[gegl] A port of gegl-paint to vala
- From: Étienne Bersac <bersace src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] A port of gegl-paint to vala
- Date: Fri, 21 May 2010 16:28:19 +0000 (UTC)
commit 625ef9a939004e4f0a4271b719a9a7e77fddac69
Author: Kao <angekao gmail com>
Date: Fri May 21 18:27:48 2010 +0200
A port of gegl-paint to vala
bindings/vala/samples/Makefile.am | 26 +++++-
bindings/vala/samples/paint.vala | 143 ++++++++++++++++++++++++++
bindings/vala/samples/view.vala | 202 +++++++++++++++++++++++++++++++++++++
3 files changed, 369 insertions(+), 2 deletions(-)
---
diff --git a/bindings/vala/samples/Makefile.am b/bindings/vala/samples/Makefile.am
index 9ca7e1e..018c57c 100644
--- a/bindings/vala/samples/Makefile.am
+++ b/bindings/vala/samples/Makefile.am
@@ -1,5 +1,5 @@
-noinst_PROGRAMS = format pipeline buffer
+noinst_PROGRAMS = format pipeline buffer paint
BUILT_SOURCES = \
$(noinst_PROGRAMS:=.vala.stamp)
@@ -63,7 +63,29 @@ buffer.vala.stamp: $(buffer_VALASOURCES)
touch $@
+# PAINT
+paint_VALASOURCES = paint.vala view.vala
+paint_VALAPKGS = \
+ --pkg=gtk+-2.0 \
+ --vapidir=$(top_srcdir) --pkg=babl-0.0 --pkg=gegl-0.0
+
+paint_SOURCES = \
+ paint.vala.stamp \
+ $(paint_VALASOURCES:.vala=.c)
+
+paint_CFLAGS = \
+ $(VALA_TEST_CFLAGS)
+paint_LDFLAGS = \
+ $(VALA_TEST_LIBS) \
+ -lbabl-0.0 -lgegl-0.0
+
+paint.vala.stamp: $(paint_VALASOURCES)
+ valac -C $(paint_VALAPKGS) $^
+ touch $@
+
+
EXTRA_DIST = \
$(format_VALASOURCES) \
$(pipeline_VALASOURCES) \
- $(buffer_VALASOURCES)
+ $(buffer_VALASOURCES) \
+ $(paint_VALASOURCES)
diff --git a/bindings/vala/samples/paint.vala b/bindings/vala/samples/paint.vala
new file mode 100644
index 0000000..1b20a4b
--- /dev/null
+++ b/bindings/vala/samples/paint.vala
@@ -0,0 +1,143 @@
+const double LINEWIDTH = 60.0;
+const double HARDNESS = 0.2;
+const string COLOR = "rgba(0.0,0.0,0.0,0.4)";
+
+
+Gegl.Node n_gegl;
+weak Gegl.Node n_out;
+weak Gegl.Node n_top;
+weak Gegl.Node n_over;
+weak Gegl.Node n_stroke;
+
+bool pen_down = false;
+Gegl.Path vector;
+
+Gegl.Buffer buffer;
+
+
+public bool press (Gdk.EventButton event)
+{
+ if (event.button == 1)
+ {
+ vector = new Gegl.Path();
+
+ n_over = n_gegl.new_child("operation","gegl:over");
+
+ n_stroke = n_gegl.new_child("operation","gegl:path",
+ "d", vector,
+ "fill-opacity", 0.0,
+ "stroke", new Gegl.Color(COLOR),
+ "stroke-width", LINEWIDTH,
+ "stroke-hardness", HARDNESS);
+
+ n_top.link_many(n_over, n_out);
+ n_stroke.connect_to("output", n_over, "aux");
+
+ vector.append('M', event.x, event.y);
+
+ pen_down = true;
+
+ return true;
+ }
+ return false;
+}
+public bool motion (Gdk.EventMotion event)
+{
+ if ((event.state & Gdk.ModifierType.BUTTON1_MASK) !=0)
+ {
+ if (!pen_down)
+ {
+ return true;
+ }
+ vector.append('L',event.x,event.y);
+ return true;
+ }
+ return false;
+}
+public bool release (Gdk.EventButton event)
+{
+ if (event.button == 1)
+ {
+ double x0,x1,y0,y1;
+ Gegl.Processor processor;
+ Gegl.Node writebuf;
+ Gegl.Rectangle roi = Gegl.Rectangle();
+
+ vector.get_bounds (out x0, out x1, out y0, out y1);
+
+ roi.x = (int)(x0 - LINEWIDTH);
+ roi.y = (int)(y0 - LINEWIDTH);
+ roi.width = (int)(x1 -x0 + LINEWIDTH * 2);
+ roi.height = (int)(y1 -y0 + LINEWIDTH * 2);
+
+ writebuf = n_gegl.new_child("operation", "gegl:write-buffer",
+ "buffer", buffer);
+ n_over.link_many(writebuf);
+
+ processor = new Gegl.Processor(writebuf, roi);
+
+ while (processor.work(null));
+
+ n_top.link_many(n_out);
+
+ n_over = null;
+ n_stroke = null;
+ pen_down = false;
+
+ return true;
+ }
+ return false;
+}
+
+
+static int main (string[] args)
+{
+ Gtk.init (ref args);
+ Gegl.init (ref args);
+
+ Log.set_always_fatal (GLib.LogLevelFlags.LEVEL_CRITICAL);
+
+ // Setting up main window
+ Gtk.Window window = new Gtk.Window (Gtk.WindowType.TOPLEVEL);
+ window.title = "GPaint";
+ window.destroy.connect (Gtk.main_quit);
+
+
+ Gegl.Rectangle rect = {0,0,512,512};
+ void* buf;
+
+ buffer = new Gegl.Buffer(rect, Babl.format ("RGBA float"));
+ buf = buffer.linear_open (null, null, Babl.format("Y' u8"));
+ Memory.set (buf, 255, 512*512);
+ buffer.linear_close (buf);
+
+ n_gegl = new Gegl.Node ();
+ Gegl.Node loadbuf = n_gegl.new_child ("operation","gegl:buffer-source",
+ "buffer",buffer);
+
+ n_out = n_gegl.new_child ("operation", "gegl:nop");
+ loadbuf.link_many (n_out);
+ n_top = loadbuf;
+
+ var view = new View (n_out);
+
+ view.button_press_event.connect (press);
+ view.motion_notify_event.connect (motion);
+ view.button_release_event.connect (release);
+ view.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK);
+
+ window.add (view);
+
+ window.show_all ();
+
+ Gtk.main ();
+
+ n_gegl = null;
+ buffer = null;
+ loadbuf = null;
+ view = null;
+
+ Gegl.exit ();
+ return 0;
+}
+
diff --git a/bindings/vala/samples/view.vala b/bindings/vala/samples/view.vala
new file mode 100644
index 0000000..142a9c7
--- /dev/null
+++ b/bindings/vala/samples/view.vala
@@ -0,0 +1,202 @@
+
+public class View : Gtk.DrawingArea
+{
+ private weak Gegl.Node _node;
+ public weak Gegl.Node node
+ {
+ get{ return _node;}
+ set
+ {
+ _node = (Gegl.Node)value;
+ _node.computed.connect((rect)=>
+ {
+ int x = (int)(this.scale * rect.x - this.x);
+ int y = (int)(this.scale * rect.y - this.y);
+ int w = (int)Math.ceil(this.scale * rect.width + 1);
+ int h = (int)Math.ceil(this.scale * rect.height + 1);
+ this.queue_draw_area (x,y,w,h);
+ }
+ );
+ this._node.invalidated.connect((rect)=>this.repaint());
+ this.repaint();
+ }
+ }
+ private uint monitor_id;
+ private Gegl.Processor processor;
+
+
+ /* Fields */
+ public int x {get; set; default = 0;}
+ public int y {get; set; default = 0;}
+ private int screen_x;
+ private int screen_y;
+ private int orig_x;
+ private int orig_y;
+ private int start_buf_x;
+ private int start_buf_y;
+ private int prev_x;
+ private int prev_y;
+
+
+ private double _scale=1.0;
+ public double scale
+ {
+ get{return _scale;}
+ construct set
+ {
+ if (value > 100) {_scale = double.MAX+1;}
+ if (value < 0) {_scale = double.MIN -1;}
+ }
+ }
+ private double prev_scale;
+
+ private bool drag_started;
+ public bool block {get; set; default = false;}
+
+
+
+ public View(Gegl.Node node)
+ {
+ this.node = node;
+ this.set_size_request (300, 200);
+ this.add_events (Gdk.EventMask.BUTTON_PRESS_MASK
+ | Gdk.EventMask.BUTTON_RELEASE_MASK
+ | Gdk.EventMask.POINTER_MOTION_MASK);
+ }
+ public override bool button_press_event(Gdk.EventButton event)
+ {
+ int x = (int)event.x;
+ int y = (int)event.y;
+
+ this.screen_x = x;
+ this.screen_y = y;
+
+ this.orig_x = this.x;
+ this.orig_y = this.y;
+
+ this.start_buf_x = (int)((this.x + x)/this.scale);
+ this.start_buf_y = (int)((this.y + y)/this.scale);
+
+ this.prev_x = x;
+ this.prev_y = y;
+
+ x = (int)(x / this.scale + this.x);
+ y = (int)(y / this.scale + this.y);
+
+ Gegl.Node detected = this.node.detect ((int)((this.x + event.x)/this.scale),
+ (int)((this.y + event.y)/this.scale));
+ if (detected != null)
+ {
+ this.detected(detected);
+ }
+ this.drag_started = true;
+ return false;
+ }
+ public override bool button_release_event(Gdk.EventButton event)
+ {
+ this.drag_started = false;
+ return false;
+ }
+ public override bool motion_notify_event(Gdk.EventMotion event)
+ {
+ int x = (int)event.x;
+ int y = (int)event.y;
+
+ if (!this.drag_started) {return false;}
+ if ((event.state & Gdk.ModifierType.BUTTON2_MASK) != 0)
+ {
+ int diff_x = x - this.prev_x;
+ int diff_y = y - this.prev_y;
+
+ this.x -= diff_x;
+ this.y -= diff_y;
+
+ this.get_window().scroll(diff_x, diff_y);
+ }
+
+ this.prev_x = x;
+ this.prev_y = y;
+
+ return true;
+ }
+ public override bool expose_event (Gdk.EventExpose event)
+ {
+ if (this.node == null) {return false;}
+
+ Gdk.Rectangle[] rectangles;
+ event.region.get_rectangles(out rectangles);
+
+ foreach (var rectangle in rectangles)
+ {
+ Gegl.Rectangle roi = Gegl.Rectangle();
+
+ roi.x = this.x + rectangle.x;
+ roi.y = this.y + rectangle.y;
+ roi.width = rectangle.width;
+ roi.height = rectangle.height;
+
+ uchar[] buf = new uchar[roi.width*roi.height*3];
+
+ //uchar *buf = (uchar*)malloc (roi.width * roi.height * 3);
+
+ this.node.blit(this.scale,
+ roi,
+ Babl.format ("R'G'B' u8"),
+ (void*)buf,
+ Gegl.AUTO_ROWSTRIDE,
+ Gegl.BlitFlags.CACHE|
+ (this.block?0:Gegl.BlitFlags.DIRTY));
+
+ Gdk.draw_rgb_image(this.get_window(),
+ this.get_style().black_gc,
+ rectangle.x, rectangle.y,
+ rectangle.width, rectangle.height,
+ Gdk.RgbDither.NONE,
+ buf, roi.width*3);
+ }
+ return false;
+ }
+ public void repaint()
+ {
+ Gegl.Rectangle roi = Gegl.Rectangle();
+
+ roi.x = (int)(this.x / this.scale);
+ roi.y = (int)(this.y / this.scale);
+ roi.width = (int)Math.ceil(this.allocation.width / this.scale+1);
+ roi.height = (int)Math.ceil(this.allocation.height / this.scale+1);
+
+ if (this.monitor_id == 0)
+ {
+ this.monitor_id = Idle.add_full(Priority.LOW,task_monitor);
+
+ if (this.processor == null)
+ {
+ if (this.node != null)
+ {
+ this.processor = new Gegl.Processor(node, roi);
+ }
+ }
+ }
+
+ if (this.processor != null)
+ {
+ processor.set_rectangle(roi);
+ }
+ }
+
+ private bool task_monitor ()
+ {
+ if (this.processor == null)
+ {
+ return false;
+ }
+ if (this.processor.work(null))
+ {
+ return true;
+ }
+
+ this.monitor_id = 0;
+ return false;
+ }
+ public signal void detected(Gegl.Node node);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]