[gegl] bin: add operation specific canvas ui's written in lua



commit fbb8e4fba6e62f1001b02a4c0edf1af68a5a7fed
Author: Øyvind Kolås <pippin gimp org>
Date:   Sat Feb 16 13:06:07 2019 +0100

    bin: add operation specific canvas ui's written in lua
    
    For now for crop, linear-gradient and radial-gradient, lua files are live
    searched at runtime each time the ui is redrawn, this permits live editing of a
    copy of gegl_crop.lua or any new introduced per-op ui in /tmp or
    /home/user/.local/share/gegl-0.4/lua/gegl_crop.lua to override the system wide
    on installed in /prefix/share/gegl-0.4/lua/gegl_opname.lua and when running the
    gegl binary out of the build, the in-build lua files take precedence.
    
    The following are available as globals for the lua scripts:
    
    loaded lua modules: ffi Mrg lgi
    lgi namespaces: GLib Gegl GObject
    
    mrg    mrg context for registering interaction callbacks and rendering xhtml/css
    cr     cairo context, transformed to the local coordinatesystem of the op
    active active GeglNode
    sink   the sink GeglNode
    dim    a dimension suitable for a touch interaction area (for now 10% of mrg:height())
    o      (the global application state struct)

 bin/Makefile.am                  |   2 +
 bin/lua/Makefile.am              |   5 ++
 bin/lua/gegl_crop.lua            |  40 +++++++++++++
 bin/lua/gegl_linear-gradient.lua |  39 +++++++++++++
 bin/lua/gegl_radial-gradient.lua |  39 +++++++++++++
 bin/lua/init.lua                 | 118 +++++++++++++++++++++++++++++++++++++++
 bin/ui.c                         |   4 ++
 configure.ac                     |   6 ++
 8 files changed, 253 insertions(+)
---
diff --git a/bin/Makefile.am b/bin/Makefile.am
index 2a8bb91f8..917e55451 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -2,6 +2,8 @@ if OS_WIN32
 no_undefined = -no-undefined
 endif
 
+SUBDIRS=lua
+
 AM_CPPFLAGS = \
        -I$(top_srcdir) \
        -I$(top_srcdir)/bin \
diff --git a/bin/lua/Makefile.am b/bin/lua/Makefile.am
new file mode 100644
index 000000000..ce4fe2d8d
--- /dev/null
+++ b/bin/lua/Makefile.am
@@ -0,0 +1,5 @@
+
+luadatadir = $(gegldatadir)/lua
+
+luadata_DATA = $(wildcard *.lua)
+
diff --git a/bin/lua/gegl_crop.lua b/bin/lua/gegl_crop.lua
new file mode 100644
index 000000000..c428f9d0d
--- /dev/null
+++ b/bin/lua/gegl_crop.lua
@@ -0,0 +1,40 @@
+local x = active:get_property("x").value
+local y = active:get_property("y").value
+
+cr:new_path()
+cr:arc(x, y, dim/2, 0, 3.1415 * 2)
+
+mrg:listen(Mrg.DRAG, function(ev)
+  if ev.type == Mrg.DRAG_MOTION then
+    local x = active:get_property("x").value
+    local y = active:get_property("y").value
+    x = x + ev.delta_x
+    y = y + ev.delta_y
+    active:set_property("y", GObject.Value(GObject.Type.DOUBLE, y))
+    active:set_property("x", GObject.Value(GObject.Type.DOUBLE, x))
+    ev:stop_propagate();
+  end
+end)
+
+cr:set_source_rgba(1,0,0,0.5)
+cr:fill()
+
+local w = active:get_property("width").value
+local h = active:get_property("height").value
+
+cr:new_path()
+cr:arc(x + w, y + h, dim/2, 0, 3.1415 * 2)
+mrg:listen(Mrg.DRAG, function(ev)
+  if ev.type == Mrg.DRAG_MOTION then
+    local w = active:get_property("width").value
+    local h = active:get_property("height").value
+    w = w + ev.delta_x
+    h = h + ev.delta_y
+    active:set_property("width", GObject.Value(GObject.Type.DOUBLE, w))
+    active:set_property("height", GObject.Value(GObject.Type.DOUBLE, h))
+    ev:stop_propagate();
+  end
+end)
+cr:set_source_rgba(1,0,0,0.5)
+cr:fill()
+
diff --git a/bin/lua/gegl_linear-gradient.lua b/bin/lua/gegl_linear-gradient.lua
new file mode 100644
index 000000000..32239ee22
--- /dev/null
+++ b/bin/lua/gegl_linear-gradient.lua
@@ -0,0 +1,39 @@
+
+local start_x = active:get_property("start-x").value
+local start_y = active:get_property("start-y").value
+
+cr:new_path()
+cr:arc(start_x, start_y, dim/2, 0, 3.1415 * 2)
+
+mrg:listen(Mrg.DRAG, function(ev)
+  if ev.type == Mrg.DRAG_MOTION then
+    local start_x = active:get_property("start-x").value
+    local start_y = active:get_property("start-y").value
+    start_x = start_x + ev.delta_x
+    start_y = start_y + ev.delta_y
+    active:set_property("start-y", GObject.Value(GObject.Type.DOUBLE, start_y))
+    active:set_property("start-x", GObject.Value(GObject.Type.DOUBLE, start_x))
+    ev:stop_propagate();
+  end
+end)
+cr:set_source_rgba(1,0,0,0.5)
+cr:fill()
+
+local end_x = active:get_property("end-x").value
+local end_y = active:get_property("end-y").value
+
+cr:arc(end_x, end_y, dim/2, 0, 3.1415 * 2)
+mrg:listen(Mrg.DRAG, function(ev)
+  if ev.type == Mrg.DRAG_MOTION then
+    local end_x = active:get_property("end-x").value
+    local end_y = active:get_property("end-y").value
+    end_x = end_x + ev.delta_x
+    end_y = end_y + ev.delta_y
+    active:set_property("end-y", GObject.Value(GObject.Type.DOUBLE, end_y))
+    active:set_property("end-x", GObject.Value(GObject.Type.DOUBLE, end_x))
+    ev:stop_propagate();
+  end
+end)
+cr:set_source_rgba(1,0,0,0.5)
+cr:fill()
+
diff --git a/bin/lua/gegl_radial-gradient.lua b/bin/lua/gegl_radial-gradient.lua
new file mode 100644
index 000000000..32239ee22
--- /dev/null
+++ b/bin/lua/gegl_radial-gradient.lua
@@ -0,0 +1,39 @@
+
+local start_x = active:get_property("start-x").value
+local start_y = active:get_property("start-y").value
+
+cr:new_path()
+cr:arc(start_x, start_y, dim/2, 0, 3.1415 * 2)
+
+mrg:listen(Mrg.DRAG, function(ev)
+  if ev.type == Mrg.DRAG_MOTION then
+    local start_x = active:get_property("start-x").value
+    local start_y = active:get_property("start-y").value
+    start_x = start_x + ev.delta_x
+    start_y = start_y + ev.delta_y
+    active:set_property("start-y", GObject.Value(GObject.Type.DOUBLE, start_y))
+    active:set_property("start-x", GObject.Value(GObject.Type.DOUBLE, start_x))
+    ev:stop_propagate();
+  end
+end)
+cr:set_source_rgba(1,0,0,0.5)
+cr:fill()
+
+local end_x = active:get_property("end-x").value
+local end_y = active:get_property("end-y").value
+
+cr:arc(end_x, end_y, dim/2, 0, 3.1415 * 2)
+mrg:listen(Mrg.DRAG, function(ev)
+  if ev.type == Mrg.DRAG_MOTION then
+    local end_x = active:get_property("end-x").value
+    local end_y = active:get_property("end-y").value
+    end_x = end_x + ev.delta_x
+    end_y = end_y + ev.delta_y
+    active:set_property("end-y", GObject.Value(GObject.Type.DOUBLE, end_y))
+    active:set_property("end-x", GObject.Value(GObject.Type.DOUBLE, end_x))
+    ev:stop_propagate();
+  end
+end)
+cr:set_source_rgba(1,0,0,0.5)
+cr:fill()
+
diff --git a/bin/lua/init.lua b/bin/lua/init.lua
new file mode 100644
index 000000000..2a297233c
--- /dev/null
+++ b/bin/lua/init.lua
@@ -0,0 +1,118 @@
+
+ffi = require('ffi')
+lgi = require 'lgi'
+
+GLib    = lgi.GLib
+GObject = lgi.GObject
+Mrg     = require('mrg')
+Gegl    = lgi.Gegl
+
+ffi.cdef[[
+
+typedef void* GList;
+typedef void* GeglNode;
+typedef void* GeglBuffer;
+typedef void* GeglProcessor;
+typedef void* GThread;
+typedef void* GHashTable;
+
+struct State {
+  int64_t   pad_for_gobject[3];
+
+  void      (*ui) (Mrg *mrg, void *state);
+  Mrg        *mrg;
+  char       *path;      /* path of edited file or open folder  */
+
+  char       *src_path; /* path to (immutable) source image. */
+
+  char       *save_path; /* the exported .gegl file, or .png with embedded .gegl file,
+                            the file that is written to on save. This differs depending
+                            on type of input file.
+                          */
+  GList       *paths;  /* list of full paths to entries in collection/path/containing path,
+                          XXX: could be replaced with URIs, and each
+                          element should perhaps contain more internal info
+                          like stars, tags etc.  */
+  GeglBuffer  *buffer;
+  GeglNode    *gegl;
+  GeglNode    *source;  /* a file-loader or another swapped in buffer provider that is the
+                             image data source for the loaded image.  */
+  GeglNode    *save;    /* node rigged up for saving file XXX: might be bitrotted */
+
+  GeglNode    *sink;    /* the sink which we're rendering content and graph from */
+  GeglNode    *active;  /* the node being actively inspected  */
+
+  int          pad_active; /* 0=input 1=aux 2=output (default)*/
+
+  GThread     *renderer_thread; /* only used when GEGL_RENDERER=thread is set in environment */
+  int          entry_no; /* used in collection-view, and set by "parent" */
+
+  int          is_dir;  // is current in dir mode
+
+  int          show_bindings;
+
+  GeglNode    *reference_node;
+
+  GeglNode    *processor_node; /* the node we have a processor for */
+  GeglProcessor *processor;
+  GeglBuffer  *processor_buffer;
+  int          renderer_state;
+  int          editing_op_name;
+  char         editing_buf[1024];
+  int          rev;
+
+  const char  *property_focus; // interned string of property name, or "operation" or "id"
+  int          editing_property;
+
+
+  float        u, v;
+  float        scale;
+
+  int          is_fit;
+  int          show_bounding_box;
+  float        dir_scale;
+  float        render_quality; /* default (and in code swapped for preview_quality during preview rendering, 
this is the canonical read location for the value)  */
+  float        preview_quality;
+
+  float        graph_pan_x;
+  float        graph_pan_y;
+  int          show_graph;
+  float        graph_scale;
+
+  float        thumbbar_pan_x;
+  float        thumbbar_pan_y;
+  int          show_thumbbar;
+  float        thumbbar_scale;
+  float        thumbbar_opacity;
+  int          thumbbar_timeout;
+
+  int          show_controls;
+  int          controls_timeout;
+  int          frame_no;
+
+
+  char       **ops; // the operations part of the commandline, if any
+  float        slide_pause;
+  int          slide_enabled;
+  int          slide_timeout;
+  char        *paint_color;    // XXX : should be a GeglColor
+
+  GeglNode    *gegl_decode;
+  GeglNode    *decode_load;
+  GeglNode    *decode_store;
+  int          playing;
+  int          color_managed_display;
+
+  int          is_video;
+  int          prev_frame_played;
+  double       prev_ms;
+
+  GHashTable  *ui_consumer;
+};
+
+struct State *app_state(void);
+int argvs_eval (const char *str);
+]]
+
+o = ffi.C.app_state()
+mrg = o.mrg
diff --git a/bin/ui.c b/bin/ui.c
index 66d1381aa..f11ee0a8f 100644
--- a/bin/ui.c
+++ b/bin/ui.c
@@ -5421,6 +5421,10 @@ static gboolean run_lua_file (const char *basename)
 "local foo = GObject.Object(STATE)\n"
 "active = foo.active\n"
 "sink = foo.sink\n"
+"cr = mrg:cr()\n"
+"dim = mrg:height() * 0.1;\n"
+"dim, dimy = cr:device_to_user_distance(dim, dim)\n"
+
 "source = foo.source\n");
   result = lua_pcall(L, 0, LUA_MULTRET, 0);
 
diff --git a/configure.ac b/configure.ac
index 77a5fc9b9..359cb0f9d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -551,6 +551,11 @@ PKG_CHECK_MODULES(DEP,
 DEP_CFLAGS=`$PKG_CONFIG --cflags $GLIB_PACKAGES gthread-2.0`
 DEP_LIBS=`$PKG_CONFIG --libs $GLIB_PACKAGES gthread-2.0`
 
+
+gegldatadir="$datadir/$PACKAGE-$GEGL_API_VERSION"
+
+AC_SUBST(gegldatadir)
+
 ######################
 # gettext i18n support
 ######################
@@ -1313,6 +1318,7 @@ dnl bin/node-editors/Makefile
 AC_CONFIG_FILES([
 Makefile
 bin/Makefile
+bin/lua/Makefile
 gcut/Makefile
 gegl/Makefile
 gegl/gegl-version.h


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]