summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOyvind Kolas <pippin@gimp.org>2015-07-27 00:57:11 +0200
committerOyvind Kolas <pippin@gimp.org>2015-07-27 01:14:00 +0200
commitc2aba45298c74228c9667cc3f3112c63c7482146 (patch)
tree1e41d5cd07639c3278814e012cf3a16d18173493
parent16dea04ed66150aa06cc3693ec2e04b3f171a091 (diff)
code reorg
-rw-r--r--bin/mrg-ui.c1316
1 files changed, 664 insertions, 652 deletions
diff --git a/bin/mrg-ui.c b/bin/mrg-ui.c
index b56ca5fd..d3c36b22 100644
--- a/bin/mrg-ui.c
+++ b/bin/mrg-ui.c
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
- * Copyright (C) 2015 Øyvind Kolås
+ * Copyright (C) 2015 Øyvind Kolås pippin@gimp.org
*/
#define _BSD_SOURCE
@@ -83,6 +83,545 @@ struct _State {
void gegl_meta_set (const char *path, const char *meta_data);
char * gegl_meta_get (const char *path);
+static char *suffix_path (const char *path);
+static char *unsuffix_path (const char *path);
+static int is_giev_path (const char *path);
+
+static void contrasty_stroke (cairo_t *cr);
+
+static void mrg_gegl_blit (Mrg *mrg,
+ float x0, float y0,
+ float width, float height,
+ GeglNode *node,
+ float u, float v,
+ float scale,
+ float preview_multiplier);
+
+static void load_path (State *o);
+
+static void go_next (State *o);
+static void go_prev (State *o);
+
+
+static void go_next_cb (MrgEvent *event, void *data1, void *data2);
+static void go_prev_cb (MrgEvent *event, void *data1, void *data2);
+
+static void leave_editor (State *o);
+
+static void drag_preview (MrgEvent *e);
+static void load_into_buffer (State *o, const char *path);
+
+static GeglNode *locate_node (State *o, const char *op_name);
+
+static void zoom_to_fit (State *o);
+
+static void zoom_to_fit_buffer (State *o);
+
+static void zoom_fit_cb (MrgEvent *e, void *data1, void *data2);
+static int deferred_zoom_to_fit (Mrg *mrg, void *data);
+
+static void pan_left_cb (MrgEvent *event, void *data1, void *data2);
+
+static void pan_right_cb (MrgEvent *event, void *data1, void *data2);
+
+static void pan_down_cb (MrgEvent *event, void *data1, void *data2);
+
+static void pan_up_cb (MrgEvent *event, void *data1, void *data2);
+
+static void get_coords (State *o, float screen_x, float screen_y, float *gegl_x, float *gegl_y);
+
+static void preview_more_cb (MrgEvent *event, void *data1, void *data2);
+
+static void preview_less_cb (MrgEvent *event, void *data1, void *data2);
+
+static void zoom_1_cb (MrgEvent *event, void *data1, void *data2);
+
+static void zoom_in_cb (MrgEvent *event, void *data1, void *data2);
+
+static void zoom_out_cb (MrgEvent *event, void *data1, void *data2);
+
+static void toggle_actions_cb (MrgEvent *event, void *data1, void *data2);
+
+static void toggle_fullscreen_cb (MrgEvent *event, void *data1, void *data2);
+
+
+static void activate_op_cb (MrgEvent *event, void *data1, void *data2);
+
+
+static void disable_filter_cb (MrgEvent *event, void *data1, void *data2);
+
+static void apply_filter_cb (MrgEvent *event, void *data1, void *data2);
+static void discard_cb (MrgEvent *event, void *data1, void *data2);
+static void save_cb (MrgEvent *event, void *data1, void *data2);
+
+
+
+
+static void toggle_show_controls_cb (MrgEvent *event, void *data1, void *data2);
+
+static void gegl_ui (Mrg *mrg, void *data);
+int mrg_ui_main (int argc, char **argv);
+
+void gegl_meta_set (const char *path, const char *meta_data);
+char * gegl_meta_get (const char *path);
+
+static State *hack_state = NULL; // XXX: this shoudl be factored away
+
+int mrg_ui_main (int argc, char **argv)
+{
+ Mrg *mrg = mrg_new (1024, 768, NULL);
+ State o = {NULL,};
+#ifdef USE_MIPMAPS
+ g_setenv ("GEGL_MIPMAP_RENDERING", "1", TRUE);
+#endif
+ g_setenv ("BABL_TOLERANCE", "0.1", TRUE);
+
+ gegl_init (&argc, &argv);
+ o.gegl = gegl_node_new ();
+ o.mrg = mrg;
+ o.scale = 1.0;
+ o.render_quality = 1.0;
+ o.preview_quality = 4.0;
+
+ if (access (argv[1], F_OK) != -1)
+ o.path = strdup (argv[1]);
+ else
+ {
+ printf ("usage: %s <full-path-to-image>\n", argv[0]);
+ return -1;
+ }
+
+ load_path (&o);
+ mrg_set_ui (mrg, gegl_ui, &o);
+ hack_state = &o;
+ mrg_main (mrg);
+
+ g_object_unref (o.gegl);
+ if (o.buffer)
+ {
+ g_object_unref (o.buffer);
+ o.buffer = NULL;
+ }
+ gegl_exit ();
+ return 0;
+}
+
+static void on_pan_drag (MrgEvent *e, void *data1, void *data2)
+{
+ State *o = data1;
+ if (e->type == MRG_DRAG_MOTION)
+ {
+ o->u -= (e->delta_x );
+ o->v -= (e->delta_y );
+ mrg_queue_draw (e->mrg, NULL);
+ }
+ drag_preview (e);
+}
+
+static void prop_double_drag_cb (MrgEvent *e, void *data1, void *data2)
+{
+ GeglNode *node = data1;
+ GParamSpec *pspec = data2;
+ GeglParamSpecDouble *gspec = data2;
+ gdouble value = 0.0;
+ float range = gspec->ui_maximum - gspec->ui_minimum;
+
+ value = e->x / mrg_width (e->mrg);
+ value = value * range + gspec->ui_minimum;
+ gegl_node_set (node, pspec->name, value, NULL);
+
+ drag_preview (e);
+
+ mrg_queue_draw (e->mrg, NULL);
+}
+
+static void draw_gegl_generic (State *state, Mrg *mrg, cairo_t *cr, GeglNode *node)
+{
+ const gchar* op_name = gegl_node_get_operation (node);
+ mrg_set_edge_left (mrg, mrg_width (mrg) * 0.1);
+ mrg_set_edge_top (mrg, mrg_height (mrg) * 0.1);
+ mrg_set_font_size (mrg, mrg_height (mrg) * 0.07);
+ mrg_set_style (mrg, "color:white; background-color: transparent");
+
+ cairo_save (cr);
+ mrg_printf (mrg, "%s\n", op_name);
+ {
+ guint n_props;
+ GParamSpec **pspecs = gegl_operation_list_properties (op_name, &n_props);
+
+ if (pspecs)
+ {
+ int tot_pos = 0;
+ int pos_no = 0;
+
+ for (gint i = 0; i < n_props; i++)
+ {
+ if (g_type_is_a (pspecs[i]->value_type, G_TYPE_DOUBLE) ||
+ g_type_is_a (pspecs[i]->value_type, G_TYPE_INT) ||
+ g_type_is_a (pspecs[i]->value_type, G_TYPE_STRING) ||
+ g_type_is_a (pspecs[i]->value_type, G_TYPE_BOOLEAN))
+ tot_pos ++;
+ }
+
+ for (gint i = 0; i < n_props; i++)
+ {
+ mrg_set_xy (mrg, mrg_em(mrg), mrg_height (mrg) - mrg_em (mrg) * ((tot_pos-pos_no)));
+
+ if (g_type_is_a (pspecs[i]->value_type, G_TYPE_DOUBLE))
+ {
+ float xpos;
+ GeglParamSpecDouble *geglspec = (void*)pspecs[i];
+ gdouble value;
+ gegl_node_get (node, pspecs[i]->name, &value, NULL);
+
+ cairo_rectangle (cr, 0,
+ mrg_height (mrg) - mrg_em (mrg) * ((tot_pos-pos_no+1)),
+ mrg_width (mrg), mrg_em(mrg));
+ cairo_set_source_rgba (cr, 0,0,0, 0.5);
+
+ mrg_listen (mrg, MRG_DRAG, prop_double_drag_cb, node,(void*)pspecs[i]);
+
+ cairo_fill (cr);
+ xpos = (value - geglspec->ui_minimum) / (geglspec->ui_maximum - geglspec->ui_minimum);
+ cairo_rectangle (cr, xpos * mrg_width(mrg) - mrg_em(mrg)/4,
+ mrg_height (mrg) - mrg_em (mrg) * ((tot_pos-pos_no+1)),
+ mrg_em(mrg)/2, mrg_em(mrg));
+ cairo_set_source_rgba (cr, 1,1,1, 0.5);
+ cairo_fill (cr);
+
+ mrg_printf (mrg, "%s:%f\n", pspecs[i]->name, value);
+ pos_no ++;
+ }
+ else if (g_type_is_a (pspecs[i]->value_type, G_TYPE_INT))
+ {
+ gint value;
+ gegl_node_get (node, pspecs[i]->name, &value, NULL);
+ mrg_printf (mrg, "%s:%i\n", pspecs[i]->name, value);
+ pos_no ++;
+ }
+ else if (g_type_is_a (pspecs[i]->value_type, G_TYPE_STRING))
+ {
+ char *value = NULL;
+ gegl_node_get (node, pspecs[i]->name, &value, NULL);
+ pos_no ++;
+ mrg_printf (mrg, "%s:%s\n", pspecs[i]->name, value);
+ if (value) g_free (value);
+ }
+ else if (g_type_is_a (pspecs[i]->value_type, G_TYPE_BOOLEAN))
+ {
+ gboolean value = FALSE;
+ gegl_node_get (node, pspecs[i]->name, &value, NULL);
+ pos_no ++;
+ mrg_printf (mrg, "%s:%i\n", pspecs[i]->name, value);
+ }
+
+ }
+ g_free (pspecs);
+ }
+ }
+
+ cairo_restore (cr);
+ mrg_set_style (mrg, "color:yellow; background-color: transparent");
+}
+
+static void crop_drag_ul (MrgEvent *e, void *data1, void *data2)
+{
+ GeglNode *node = data1;
+ double x,y,width,height;
+ double x0, y0, x1, y1;
+ gegl_node_get (node, "x", &x, "y", &y, "width", &width, "height", &height, NULL);
+ x0 = x; y0 = y; x1 = x0 + width; y1 = y + height;
+
+ if (e->type == MRG_DRAG_MOTION)
+ {
+ x0 += e->delta_x;
+ y0 += e->delta_y;
+
+ x=x0;
+ y=y0;
+ width = x1 - x0;
+ height = y1 - y0;
+ gegl_node_set (node, "x", x, "y", y, "width", width, "height", height, NULL);
+
+ mrg_queue_draw (e->mrg, NULL);
+ }
+
+ drag_preview (e);
+}
+
+static void crop_drag_lr (MrgEvent *e, void *data1, void *data2)
+{
+ GeglNode *node = data1;
+ double x,y,width,height;
+ double x0, y0, x1, y1;
+ gegl_node_get (node, "x", &x, "y", &y, "width", &width, "height", &height, NULL);
+ x0 = x; y0 = y; x1 = x0 + width; y1 = y + height;
+
+ if (e->type == MRG_DRAG_MOTION)
+ {
+ x1 += e->delta_x;
+ y1 += e->delta_y;
+
+ x=x0;
+ y=y0;
+ width = x1 - x0;
+ height = y1 - y0;
+ gegl_node_set (node, "x", x, "y", y, "width", width, "height", height, NULL);
+
+ mrg_queue_draw (e->mrg, NULL);
+ }
+
+ drag_preview (e);
+}
+
+static void crop_drag_rotate (MrgEvent *e, void *data1, void *data2)
+{
+ State *o = hack_state;
+ double degrees;
+ gegl_node_get (o->rotate, "degrees", &degrees, NULL);
+
+ if (e->type == MRG_DRAG_MOTION)
+ {
+ degrees += e->delta_x / 100.0;
+
+ gegl_node_set (o->rotate, "degrees", degrees, NULL);
+
+ mrg_queue_draw (e->mrg, NULL);
+ }
+
+ drag_preview (e);
+}
+
+static void draw_gegl_crop (State *o, Mrg *mrg, cairo_t *cr, GeglNode *node)
+{
+ const gchar* op_name = gegl_node_get_operation (node);
+ float dim = mrg_height (mrg) * 0.1 / o->scale;
+ double x,y,width,height;
+ double x0, y0, x1, y1;
+
+ mrg_set_edge_left (mrg, mrg_width (mrg) * 0.1);
+ mrg_set_edge_top (mrg, mrg_height (mrg) * 0.1);
+ mrg_set_font_size (mrg, mrg_height (mrg) * 0.07);
+ mrg_set_style (mrg, "color:white; background-color: transparent");
+
+ cairo_save (cr);
+ mrg_printf (mrg, "%s\n", op_name);
+
+ cairo_translate (cr, -o->u, -o->v);
+ cairo_scale (cr, o->scale, o->scale);
+
+ gegl_node_get (node, "x", &x, "y", &y, "width", &width, "height", &height, NULL);
+ x0 = x; y0 = y; x1 = x0 + width; y1 = y + height;
+
+ cairo_rectangle (cr, x0, y0, dim, dim);
+ mrg_listen (mrg, MRG_DRAG, crop_drag_ul, node, NULL);
+ contrasty_stroke (cr);
+
+ cairo_rectangle (cr, x1-dim, y1-dim, dim, dim);
+ mrg_listen (mrg, MRG_DRAG, crop_drag_lr, node, NULL);
+ contrasty_stroke (cr);
+
+ cairo_rectangle (cr, x0+dim, y0+dim, width-dim-dim, height-dim-dim);
+ mrg_listen (mrg, MRG_DRAG, crop_drag_rotate, node, NULL);
+ cairo_new_path (cr);
+
+ cairo_restore (cr);
+ mrg_set_style (mrg, "color:yellow; background-color: transparent");
+}
+
+static void ui_op_draw_apply_disable (State *o)
+{
+ Mrg *mrg = o->mrg;
+ mrg_set_font_size (mrg, mrg_height (mrg) * 0.1);
+ mrg_set_xy (mrg, 0, mrg_em(mrg));
+ mrg_text_listen (mrg, MRG_PRESS, disable_filter_cb, o, NULL);
+ mrg_printf (mrg, "X");
+ mrg_text_listen_done (mrg);
+ mrg_set_xy (mrg, mrg_width(mrg) - mrg_em (mrg), mrg_em(mrg));
+ mrg_text_listen (mrg, MRG_PRESS, apply_filter_cb, o, NULL);
+ mrg_printf (mrg, "O");
+ mrg_text_listen_done (mrg);
+}
+
+static void ui_active_op (State *o)
+{
+ Mrg *mrg = o->mrg;
+ cairo_t *cr = mrg_cr (mrg);
+ char *opname = NULL;
+ g_object_get (o->active, "operation", &opname, NULL);
+
+ if (!strcmp (opname, "gegl:crop")) {
+ zoom_to_fit_buffer (o);
+ draw_gegl_crop (o, mrg, cr, o->active);
+ ui_op_draw_apply_disable (o);
+ }
+ else
+ {
+ draw_gegl_generic (o, mrg, cr, o->active);
+ ui_op_draw_apply_disable (o);
+ }
+}
+
+static void ui_debug_op_chain (State *o)
+{
+ Mrg *mrg = o->mrg;
+ GeglNode *iter;
+ mrg_set_edge_top (mrg, mrg_height (mrg) * 0.2);
+ iter = o->sink;
+ while (iter)
+ {
+ char *opname = NULL;
+ g_object_get (iter, "operation", &opname, NULL);
+ if (iter == o->active)
+ mrg_printf (mrg, "[%s]", opname);
+ else
+ mrg_printf (mrg, "%s", opname);
+ mrg_printf (mrg, "\n");
+
+ g_free (opname);
+ iter = gegl_node_get_producer (iter, "input", NULL);
+ }
+}
+
+static void ui_actions (State *o)
+{
+ Mrg *mrg = o->mrg;
+ int i;
+ cairo_t *cr = mrg_cr (mrg);
+ mrg_set_edge_left (mrg, mrg_width (mrg) * 0.25);
+ mrg_set_edge_top (mrg, mrg_height (mrg) * 0.1);
+ mrg_set_font_size (mrg, mrg_height (mrg) * 0.08);
+
+ for (i = 0; actions[i].label; i ++)
+ {
+ mrg_text_listen (mrg, MRG_PRESS, activate_op_cb, o, &actions[i]);
+ if (locate_node (o, actions[i].op_name))
+ mrg_printf (mrg, "-");
+ mrg_printf (mrg, "%s\n", actions[i].label);
+ mrg_text_listen_done (mrg);
+ }
+
+ mrg_print (mrg, "\n");
+ mrg_printf (mrg, "existing\n");
+ mrg_text_listen (mrg, MRG_PRESS, discard_cb, o, NULL);
+ mrg_printf (mrg, "discard\n");
+ mrg_text_listen_done (mrg);
+ cairo_scale (cr, mrg_width(mrg), mrg_height(mrg));
+ cairo_new_path (cr);
+ cairo_arc (cr, 0.9, 0.1, 0.1, 0.0, G_PI * 2);
+ mrg_listen (mrg, MRG_PRESS, toggle_actions_cb, o, NULL);
+ contrasty_stroke (cr);
+}
+
+static void ui_viewer (State *o)
+{
+ Mrg *mrg = o->mrg;
+ cairo_t *cr = mrg_cr (mrg);
+ cairo_rectangle (cr, 0,0, mrg_width(mrg), mrg_height(mrg));
+ mrg_listen (mrg, MRG_DRAG, on_pan_drag, o, NULL);
+ cairo_new_path (cr);
+ cairo_scale (cr, mrg_width(mrg), mrg_height(mrg));
+ cairo_move_to (cr, 0.2, 0.8);
+ cairo_line_to (cr, 0.2, 1.0);
+ cairo_line_to (cr, 0.0, 0.9);
+ cairo_close_path (cr);
+ mrg_listen (mrg, MRG_PRESS, go_prev_cb, o, NULL);
+ if (o->show_controls)
+ contrasty_stroke (cr);
+ else
+ cairo_new_path (cr);
+
+ cairo_move_to (cr, 0.8, 0.8);
+ cairo_line_to (cr, 0.8, 1.0);
+ cairo_line_to (cr, 1.0, 0.9);
+ cairo_close_path (cr);
+
+ mrg_listen (mrg, MRG_PRESS, go_next_cb, o, NULL);
+ if (o->show_controls)
+ contrasty_stroke (cr);
+ else
+ cairo_new_path (cr);
+
+ cairo_arc (cr, 0.9, 0.1, 0.1, 0.0, G_PI * 2);
+ mrg_listen (mrg, MRG_PRESS, toggle_actions_cb, o, NULL);
+
+ if (o->show_controls)
+ contrasty_stroke (cr);
+ else
+ cairo_new_path (cr);
+}
+
+static void toggle_show_controls_cb (MrgEvent *event, void *data1, void *data2)
+{
+ State *o = data1;
+ o->show_controls = !o->show_controls;
+ mrg_queue_draw (o->mrg, NULL);
+}
+
+static void gegl_ui (Mrg *mrg, void *data)
+{
+ State *o = data;
+ mrg_gegl_blit (mrg,
+ 0, 0,
+ mrg_width (mrg), mrg_height (mrg),
+ o->sink,
+ o->u, o->v,
+ o->scale,
+ o->render_quality);
+
+ if (o->show_controls)
+ {
+ mrg_printf (mrg, "%s\n", o->path);
+#if DEBUG_OP_LIST
+ ui_debug_op_chain (o);
+#endif
+ }
+
+ if (o->show_actions)
+ {
+ ui_actions (o);
+ mrg_add_binding (mrg, "return", NULL, NULL, toggle_actions_cb, o);
+ }
+ else if (o->active)
+ {
+ ui_active_op (o);
+ mrg_add_binding (mrg, "return", NULL, NULL, apply_filter_cb, o);
+ mrg_add_binding (mrg, "escape", NULL, NULL, disable_filter_cb, o);
+ }
+ else
+ {
+ ui_viewer (o);
+ mrg_add_binding (mrg, "return", NULL, NULL, toggle_actions_cb, o);
+ }
+
+ mrg_add_binding (mrg, "left", NULL, NULL, pan_left_cb, o);
+ mrg_add_binding (mrg, "right", NULL, NULL, pan_right_cb, o);
+ mrg_add_binding (mrg, "up", NULL, NULL, pan_up_cb, o);
+ mrg_add_binding (mrg, "down", NULL, NULL, pan_down_cb, o);
+ mrg_add_binding (mrg, "+", NULL, NULL, zoom_in_cb, o);
+ mrg_add_binding (mrg, "=", NULL, NULL, zoom_in_cb, o);
+ mrg_add_binding (mrg, "-", NULL, NULL, zoom_out_cb, o);
+ mrg_add_binding (mrg, "1", NULL, NULL, zoom_1_cb, o);
+ mrg_add_binding (mrg, "m", NULL, NULL, zoom_fit_cb, o);
+
+ mrg_add_binding (mrg, "control-q", NULL, NULL, mrg_quit_cb, o);
+ mrg_add_binding (mrg, "m", NULL, NULL, zoom_fit_cb, o);
+ mrg_add_binding (mrg, "q", NULL, NULL, mrg_quit_cb, o);
+ mrg_add_binding (mrg, "x", NULL, NULL, discard_cb, o);
+ mrg_add_binding (mrg, "f", NULL, NULL, toggle_fullscreen_cb, o);
+ mrg_add_binding (mrg, "F11", NULL, NULL, toggle_fullscreen_cb, o);
+ mrg_add_binding (mrg, "tab", NULL, NULL, toggle_show_controls_cb, o);
+ mrg_add_binding (mrg, "space", NULL, NULL, go_next_cb , o);
+ mrg_add_binding (mrg, "n", NULL, NULL, go_next_cb, o);
+ mrg_add_binding (mrg, "p", NULL, NULL, go_prev_cb, o);
+ mrg_add_binding (mrg, "backspace", NULL, NULL, go_prev_cb, o);
+
+ mrg_add_binding (mrg, ",", NULL, NULL, preview_less_cb, o);
+ mrg_add_binding (mrg, ".", NULL, NULL, preview_more_cb, o);
+}
+
+/***********************************************/
+
static char *suffix_path (const char *path)
{
char *ret, *last_dot;
@@ -105,21 +644,6 @@ static char *suffix_path (const char *path)
return ret;
}
-static void contrasty_stroke (cairo_t *cr)
-{
- double x0 = 6.0, y0 = 6.0;
- double x1 = 4.0, y1 = 4.0;
-
- cairo_device_to_user_distance (cr, &x0, &y0);
- cairo_device_to_user_distance (cr, &x1, &y1);
- cairo_set_source_rgba (cr, 0,0,0,0.5);
- cairo_set_line_width (cr, y0);
- cairo_stroke_preserve (cr);
- cairo_set_source_rgba (cr, 1,1,1,0.5);
- cairo_set_line_width (cr, y1);
- cairo_stroke (cr);
-}
-
static char *unsuffix_path (const char *path)
{
char *ret = NULL, *last_dot, *extension;
@@ -144,6 +668,21 @@ static int is_giev_path (const char *path)
return 0;
}
+static void contrasty_stroke (cairo_t *cr)
+{
+ double x0 = 6.0, y0 = 6.0;
+ double x1 = 4.0, y1 = 4.0;
+
+ cairo_device_to_user_distance (cr, &x0, &y0);
+ cairo_device_to_user_distance (cr, &x1, &y1);
+ cairo_set_source_rgba (cr, 0,0,0,0.5);
+ cairo_set_line_width (cr, y0);
+ cairo_stroke_preserve (cr);
+ cairo_set_source_rgba (cr, 1,1,1,0.5);
+ cairo_set_line_width (cr, y1);
+ cairo_stroke (cr);
+}
+
static unsigned char *copy_buf = NULL;
static int copy_buf_len = 0;
@@ -223,7 +762,89 @@ foo++;
cairo_restore (cr);
}
-static void load_path (State *o);
+static void load_path (State *o)
+{
+ char *path;
+ char *meta;
+ if (is_giev_path (o->path))
+ {
+ if (o->giev_path)
+ free (o->giev_path);
+ o->giev_path = o->path;
+ o->path = unsuffix_path (o->giev_path);
+ }
+ else
+ {
+ if (o->giev_path)
+ free (o->giev_path);
+ o->giev_path = suffix_path (o->path);
+ }
+ path = o->path;
+
+ if (access (o->giev_path, F_OK) != -1)
+ path = o->giev_path;
+
+ g_object_unref (o->gegl);
+ o->gegl = NULL;
+
+ meta = gegl_meta_get (path);
+ if (meta)
+ {
+ GSList *nodes, *n;
+ o->gegl = gegl_node_new_from_xml (meta, NULL);
+ o->sink = gegl_node_new_child (o->gegl,
+ "operation", "gegl:nop", NULL);
+ o->source = NULL;
+ gegl_node_link_many (
+ gegl_node_get_producer (o->gegl, "input", NULL), o->sink, NULL);
+ nodes = gegl_node_get_children (o->gegl);
+ for (n = nodes; n; n=n->next)
+ {
+ const char *op_name = gegl_node_get_operation (n->data);
+ if (!strcmp (op_name, "gegl:load"))
+ {
+ GeglNode *load;
+ gchar *path;
+ gegl_node_get (n->data, "path", &path, NULL);
+ load_into_buffer (o, path);
+ gegl_node_set (n->data, "operation", "gegl:nop", NULL);
+ o->source = n->data;
+ load = gegl_node_new_child (o->gegl, "operation", "gegl:buffer-source",
+ "buffer", o->buffer, NULL);
+ gegl_node_link_many (load, o->source, NULL);
+ g_free (path);
+ break;
+ }
+ }
+ o->save = gegl_node_new_child (o->gegl,
+ "operation", "gegl:save",
+ "path", path,
+ NULL);
+ }
+ else
+ {
+ o->gegl = gegl_node_new ();
+ o->sink = gegl_node_new_child (o->gegl,
+ "operation", "gegl:nop", NULL);
+ o->source = gegl_node_new_child (o->gegl,
+ "operation", "gegl:nop", NULL);
+ load_into_buffer (o, path);
+ o->load = gegl_node_new_child (o->gegl,
+ "operation", "gegl:buffer-source",
+ NULL);
+ o->save = gegl_node_new_child (o->gegl,
+ "operation", "gegl:save",
+ "path", o->giev_path,
+ NULL);
+ gegl_node_link_many (o->load, o->source, o->sink, NULL);
+ gegl_node_set (o->load, "buffer", o->buffer, NULL);
+ }
+ zoom_to_fit (o);
+
+ mrg_queue_draw (o->mrg, NULL);
+ o->rev = 0;
+}
+
static void go_next (State *o)
{
@@ -315,8 +936,6 @@ static void go_prev (State *o)
}
}
-static void save_cb (MrgEvent *event, void *data1, void *data2);
-
static void go_next_cb (MrgEvent *event, void *data1, void *data2)
{
State *o = data1;
@@ -337,12 +956,20 @@ static void go_prev_cb (MrgEvent *event, void *data1, void *data2)
mrg_event_stop_propagate (event);
}
-static void on_pan_drag (MrgEvent *e, void *data1, void *data2)
+static void leave_editor (State *o)
{
- State *o = data1;
+ char *opname = NULL;
+ g_object_get (o->active, "operation", &opname, NULL);
+ if (!strcmp (opname, "gegl:crop"))
+ {
+ zoom_to_fit (o);
+ }
+}
+static void drag_preview (MrgEvent *e)
+{
+ State *o = hack_state;
static float old_factor = 1;
-
switch (e->type)
{
case MRG_DRAG_PRESS:
@@ -354,11 +981,6 @@ static void on_pan_drag (MrgEvent *e, void *data1, void *data2)
o->render_quality = old_factor;
mrg_queue_draw (e->mrg, NULL);
break;
- case MRG_DRAG_MOTION:
- o->u -= (e->delta_x );
- o->v -= (e->delta_y );
- mrg_queue_draw (e->mrg, NULL);
- break;
default:
break;
}
@@ -394,6 +1016,20 @@ static void load_into_buffer (State *o, const char *path)
o->buffer = tempbuf;
}
+static GeglNode *locate_node (State *o, const char *op_name)
+{
+ GeglNode *iter = o->sink;
+ while (iter)
+ {
+ char *opname = NULL;
+ g_object_get (iter, "operation", &opname, NULL);
+ if (!strcmp (opname, op_name))
+ return iter;
+ g_free (opname);
+ iter = gegl_node_get_producer (iter, "input", NULL);
+ }
+ return NULL;
+}
static void zoom_to_fit (State *o)
{
Mrg *mrg = o->mrg;
@@ -428,13 +1064,10 @@ static void zoom_to_fit_buffer (State *o)
if (scale2 < scale) scale = scale2;
o->scale = scale;
-
o->u = -(mrg_width (mrg) - rect.width * scale) / 2;
o->v = -(mrg_height (mrg) - rect.height * scale) / 2;
-
o->u += rect.x * scale;
o->v += rect.y * scale;
-
mrg_queue_draw (mrg, NULL);
}
@@ -461,7 +1094,6 @@ static void pan_right_cb (MrgEvent *event, void *data1, void *data2)
{
State *o = data1;
float amount = mrg_width (event->mrg) * 0.1;
-
o->u = o->u + amount;
mrg_queue_draw (o->mrg, NULL);
}
@@ -470,7 +1102,6 @@ static void pan_down_cb (MrgEvent *event, void *data1, void *data2)
{
State *o = data1;
float amount = mrg_width (event->mrg) * 0.1;
-
o->v = o->v + amount;
mrg_queue_draw (o->mrg, NULL);
}
@@ -479,9 +1110,7 @@ static void pan_up_cb (MrgEvent *event, void *data1, void *data2)
{
State *o = data1;
float amount = mrg_width (event->mrg) * 0.1;
-
o->v = o->v - amount;
-
mrg_queue_draw (o->mrg, NULL);
}
@@ -505,7 +1134,6 @@ static void preview_less_cb (MrgEvent *event, void *data1, void *data2)
o->render_quality /= 2;
if (o->render_quality <= 1.0)
o->render_quality = 1.0;
-
mrg_queue_draw (o->mrg, NULL);
}
@@ -557,30 +1185,14 @@ static void toggle_fullscreen_cb (MrgEvent *event, void *data1, void *data2)
mrg_add_timeout (event->mrg, 250, deferred_zoom_to_fit, o);
}
-static GeglNode *locate_node (State *o, const char *op_name)
-{
- GeglNode *iter = o->sink;
- while (iter)
- {
- char *opname = NULL;
- g_object_get (iter, "operation", &opname, NULL);
- if (!strcmp (opname, op_name))
- return iter;
- g_free (opname);
- iter = gegl_node_get_producer (iter, "input", NULL);
- }
- return NULL;
-}
static void activate_op_cb (MrgEvent *event, void *data1, void *data2)
{
State *o = data1;
GeglNode *found;
ActionData *ad = data2;
-
o->show_actions = 0;
o->rev ++;
-
found = locate_node (o, ad->op_name);
if (found)
{
@@ -634,16 +1246,6 @@ static void activate_op_cb (MrgEvent *event, void *data1, void *data2)
mrg_queue_draw (o->mrg, NULL);
}
-static void leave_editor (State *o)
-{
- char *opname = NULL;
- g_object_get (o->active, "operation", &opname, NULL);
- if (!strcmp (opname, "gegl:crop"))
- {
- zoom_to_fit (o);
- }
-}
-
static void disable_filter_cb (MrgEvent *event, void *data1, void *data2)
{
State *o = data1;
@@ -666,6 +1268,7 @@ static void disable_filter_cb (MrgEvent *event, void *data1, void *data2)
o->active = NULL;
mrg_queue_draw (o->mrg, NULL);
}
+
static void apply_filter_cb (MrgEvent *event, void *data1, void *data2)
{
State *o = data1;
@@ -704,316 +1307,6 @@ static void discard_cb (MrgEvent *event, void *data1, void *data2)
free (old_path);
}
-static State *hack_state = NULL;
-static void prop_double_drag_cb (MrgEvent *e, void *data1, void *data2)
-{
- GeglNode *node = data1;
- GParamSpec *pspec = data2;
- State *o = hack_state;
- static float old_factor = 1;
- GeglParamSpecDouble *gspec = data2;
- gdouble value = 0.0;
- float range = gspec->ui_maximum - gspec->ui_minimum;
-
- value = e->x / mrg_width (e->mrg);
- value = value * range + gspec->ui_minimum;
- gegl_node_set (node, pspec->name, value, NULL);
-
- switch (e->type)
- {
- case MRG_DRAG_PRESS:
- old_factor = o->render_quality;
- if (o->render_quality < o->preview_quality)
- o->render_quality = o->preview_quality;
- break;
- case MRG_DRAG_RELEASE:
- o->render_quality = old_factor;
- mrg_queue_draw (e->mrg, NULL);
- break;
- default:
- break;
- }
-
- mrg_queue_draw (e->mrg, NULL);
-}
-
-static void draw_gegl_generic (State *state, Mrg *mrg, cairo_t *cr, GeglNode *node)
-{
- const gchar* op_name = gegl_node_get_operation (node);
- mrg_set_edge_left (mrg, mrg_width (mrg) * 0.1);
- mrg_set_edge_top (mrg, mrg_height (mrg) * 0.1);
- mrg_set_font_size (mrg, mrg_height (mrg) * 0.07);
- mrg_set_style (mrg, "color:white; background-color: transparent");
-
- cairo_save (cr);
- mrg_printf (mrg, "%s\n", op_name);
- {
- guint n_props;
- GParamSpec **pspecs = gegl_operation_list_properties (op_name, &n_props);
-
- if (pspecs)
- {
- int tot_pos = 0;
- int pos_no = 0;
-
- for (gint i = 0; i < n_props; i++)
- {
- if (g_type_is_a (pspecs[i]->value_type, G_TYPE_DOUBLE) ||
- g_type_is_a (pspecs[i]->value_type, G_TYPE_INT) ||
- g_type_is_a (pspecs[i]->value_type, G_TYPE_STRING) ||
- g_type_is_a (pspecs[i]->value_type, G_TYPE_BOOLEAN))
- tot_pos ++;
- }
-
- for (gint i = 0; i < n_props; i++)
- {
- mrg_set_xy (mrg, mrg_em(mrg), mrg_height (mrg) - mrg_em (mrg) * ((tot_pos-pos_no)));
-
-
- if (g_type_is_a (pspecs[i]->value_type, G_TYPE_DOUBLE))
- {
- float xpos;
- GeglParamSpecDouble *geglspec = (void*)pspecs[i];
- gdouble value;
- gegl_node_get (node, pspecs[i]->name, &value, NULL);
-
- cairo_rectangle (cr, 0,
- mrg_height (mrg) - mrg_em (mrg) * ((tot_pos-pos_no+1)),
- mrg_width (mrg), mrg_em(mrg));
- cairo_set_source_rgba (cr, 0,0,0, 0.5);
-
- mrg_listen (mrg, MRG_DRAG, prop_double_drag_cb, node,(void*)pspecs[i]);
-
- cairo_fill (cr);
- xpos = (value - geglspec->ui_minimum) / (geglspec->ui_maximum - geglspec->ui_minimum);
- cairo_rectangle (cr, xpos * mrg_width(mrg) - mrg_em(mrg)/4,
- mrg_height (mrg) - mrg_em (mrg) * ((tot_pos-pos_no+1)),
- mrg_em(mrg)/2, mrg_em(mrg));
- cairo_set_source_rgba (cr, 1,1,1, 0.5);
- cairo_fill (cr);
-
- mrg_printf (mrg, "%s:%f\n", pspecs[i]->name, value);
- pos_no ++;
- }
- else if (g_type_is_a (pspecs[i]->value_type, G_TYPE_INT))
- {
- gint value;
- gegl_node_get (node, pspecs[i]->name, &value, NULL);
- mrg_printf (mrg, "%s:%i\n", pspecs[i]->name, value);
- pos_no ++;
- }
- else if (g_type_is_a (pspecs[i]->value_type, G_TYPE_STRING))
- {
- char *value = NULL;
- gegl_node_get (node, pspecs[i]->name, &value, NULL);
- pos_no ++;
- mrg_printf (mrg, "%s:%s\n", pspecs[i]->name, value);
- if (value) g_free (value);
- }
- else if (g_type_is_a (pspecs[i]->value_type, G_TYPE_BOOLEAN))
- {
- gboolean value = FALSE;
- gegl_node_get (node, pspecs[i]->name, &value, NULL);
- pos_no ++;
- mrg_printf (mrg, "%s:%i\n", pspecs[i]->name, value);
- }
-
- }
- g_free (pspecs);
- }
- }
-
- cairo_restore (cr);
- mrg_set_style (mrg, "color:yellow; background-color: transparent");
-}
-
-static void crop_drag_ul (MrgEvent *e, void *data1, void *data2)
-{
- GeglNode *node = data1;
- State *o = hack_state;
- static float old_factor = 1;
-
- double x,y,width,height;
- double x0, y0, x1, y1;
- gegl_node_get (node, "x", &x, "y", &y, "width", &width, "height", &height, NULL);
- x0 = x; y0 = y; x1 = x0 + width; y1 = y + height;
-
- if (e->type == MRG_DRAG_MOTION)
- {
- x0 += e->delta_x;
- y0 += e->delta_y;
-
- x=x0;
- y=y0;
- width = x1 - x0;
- height = y1 - y0;
- gegl_node_set (node, "x", x, "y", y, "width", width, "height", height, NULL);
-
- mrg_queue_draw (e->mrg, NULL);
- }
-
- switch (e->type)
- {
- case MRG_DRAG_PRESS:
- old_factor = o->render_quality;
- if (o->render_quality < o->preview_quality)
- o->render_quality = o->preview_quality;
- break;
- case MRG_DRAG_RELEASE:
- o->render_quality = old_factor;
- mrg_queue_draw (e->mrg, NULL);
- break;
- default:
- break;
- }
-}
-
-static void crop_drag_lr (MrgEvent *e, void *data1, void *data2)
-{
- GeglNode *node = data1;
- State *o = hack_state;
- static float old_factor = 1;
-
- double x,y,width,height;
- double x0, y0, x1, y1;
- gegl_node_get (node, "x", &x, "y", &y, "width", &width, "height", &height, NULL);
- x0 = x; y0 = y; x1 = x0 + width; y1 = y + height;
-
- if (e->type == MRG_DRAG_MOTION)
- {
- x1 += e->delta_x;
- y1 += e->delta_y;
-
- x=x0;
- y=y0;
- width = x1 - x0;
- height = y1 - y0;
- gegl_node_set (node, "x", x, "y", y, "width", width, "height", height, NULL);
-
- mrg_queue_draw (e->mrg, NULL);
- }
-
-
- switch (e->type)
- {
- case MRG_DRAG_PRESS:
- old_factor = o->render_quality;
- if (o->render_quality < o->preview_quality)
- o->render_quality = o->preview_quality;
- break;
- case MRG_DRAG_RELEASE:
- o->render_quality = old_factor;
- mrg_queue_draw (e->mrg, NULL);
- break;
- default:
- break;
- }
-}
-
-
-static void crop_drag_rotate (MrgEvent *e, void *data1, void *data2)
-{
- State *o = hack_state;
- static float old_factor = 1;
-
- double degrees;
- gegl_node_get (o->rotate, "degrees", &degrees, NULL);
-
- if (e->type == MRG_DRAG_MOTION)
- {
- degrees += e->delta_x / 100.0;
-
- gegl_node_set (o->rotate, "degrees", degrees, NULL);
-
- mrg_queue_draw (e->mrg, NULL);
- }
-
- switch (e->type)
- {
- case MRG_DRAG_PRESS:
- old_factor = o->render_quality;
- if (o->render_quality < o->preview_quality)
- o->render_quality = o->preview_quality;
- break;
- case MRG_DRAG_RELEASE:
- o->render_quality = old_factor;
- mrg_queue_draw (e->mrg, NULL);
- break;
- default:
- break;
- }
-}
-
-static void draw_gegl_crop (State *o, Mrg *mrg, cairo_t *cr, GeglNode *node)
-{
- const gchar* op_name = gegl_node_get_operation (node);
- float dim = mrg_height (mrg) * 0.1 / o->scale;
- double x,y,width,height;
- double x0, y0, x1, y1;
-
- mrg_set_edge_left (mrg, mrg_width (mrg) * 0.1);
- mrg_set_edge_top (mrg, mrg_height (mrg) * 0.1);
- mrg_set_font_size (mrg, mrg_height (mrg) * 0.07);
- mrg_set_style (mrg, "color:white; background-color: transparent");
-
- cairo_save (cr);
- mrg_printf (mrg, "%s\n", op_name);
-
- cairo_translate (cr, -o->u, -o->v);
- cairo_scale (cr, o->scale, o->scale);
-
- gegl_node_get (node, "x", &x, "y", &y, "width", &width, "height", &height, NULL);
- x0 = x; y0 = y; x1 = x0 + width; y1 = y + height;
-
- cairo_rectangle (cr, x0, y0, dim, dim);
- mrg_listen (mrg, MRG_DRAG, crop_drag_ul, node, NULL);
- contrasty_stroke (cr);
-
- cairo_rectangle (cr, x1-dim, y1-dim, dim, dim);
- mrg_listen (mrg, MRG_DRAG, crop_drag_lr, node, NULL);
- contrasty_stroke (cr);
-
- cairo_rectangle (cr, x0+dim, y0+dim, width-dim-dim, height-dim-dim);
- mrg_listen (mrg, MRG_DRAG, crop_drag_rotate, node, NULL);
- cairo_new_path (cr);
-
- cairo_restore (cr);
- mrg_set_style (mrg, "color:yellow; background-color: transparent");
-}
-
-static void ui_op_draw_apply_disable (State *o)
-{
- Mrg *mrg = o->mrg;
- mrg_set_font_size (mrg, mrg_height (mrg) * 0.1);
- mrg_set_xy (mrg, 0, mrg_em(mrg));
- mrg_text_listen (mrg, MRG_PRESS, disable_filter_cb, o, NULL);
- mrg_printf (mrg, "X");
- mrg_text_listen_done (mrg);
- mrg_set_xy (mrg, mrg_width(mrg) - mrg_em (mrg), mrg_em(mrg));
- mrg_text_listen (mrg, MRG_PRESS, apply_filter_cb, o, NULL);
- mrg_printf (mrg, "O");
- mrg_text_listen_done (mrg);
-}
-
-static void ui_active_op (State *o)
-{
- Mrg *mrg = o->mrg;
- cairo_t *cr = mrg_cr (mrg);
- char *opname = NULL;
- g_object_get (o->active, "operation", &opname, NULL);
-
- if (!strcmp (opname, "gegl:crop")) {
- zoom_to_fit_buffer (o);
- draw_gegl_crop (o, mrg, cr, o->active);
- ui_op_draw_apply_disable (o);
- }
- else
- {
- draw_gegl_generic (o, mrg, cr, o->active);
- ui_op_draw_apply_disable (o);
- }
-}
-
static void save_cb (MrgEvent *event, void *data1, void *data2)
{
GeglNode *load;
@@ -1038,164 +1331,6 @@ static void save_cb (MrgEvent *event, void *data1, void *data2)
o->rev = 0;
}
-static void ui_debug_op_chain (State *o)
-{
- Mrg *mrg = o->mrg;
- GeglNode *iter;
- mrg_set_edge_top (mrg, mrg_height (mrg) * 0.2);
- iter = o->sink;
- while (iter)
- {
- char *opname = NULL;
- g_object_get (iter, "operation", &opname, NULL);
- if (iter == o->active)
- mrg_printf (mrg, "[%s]", opname);
- else
- mrg_printf (mrg, "%s", opname);
- mrg_printf (mrg, "\n");
-
- g_free (opname);
- iter = gegl_node_get_producer (iter, "input", NULL);
- }
-}
-
-static void ui_actions (State *o)
-{
- Mrg *mrg = o->mrg;
- int i;
- cairo_t *cr = mrg_cr (mrg);
- mrg_set_edge_left (mrg, mrg_width (mrg) * 0.25);
- mrg_set_edge_top (mrg, mrg_height (mrg) * 0.1);
- mrg_set_font_size (mrg, mrg_height (mrg) * 0.08);
-
- for (i = 0; actions[i].label; i ++)
- {
- mrg_text_listen (mrg, MRG_PRESS, activate_op_cb, o, &actions[i]);
- if (locate_node (o, actions[i].op_name))
- mrg_printf (mrg, "-");
- mrg_printf (mrg, "%s\n", actions[i].label);
- mrg_text_listen_done (mrg);
- }
-
- mrg_print (mrg, "\n");
- mrg_printf (mrg, "existing\n");
- mrg_text_listen (mrg, MRG_PRESS, discard_cb, o, NULL);
- mrg_printf (mrg, "discard\n");
- mrg_text_listen_done (mrg);
- cairo_scale (cr, mrg_width(mrg), mrg_height(mrg));
- cairo_new_path (cr);
- cairo_arc (cr, 0.9, 0.1, 0.1, 0.0, G_PI * 2);
- mrg_listen (mrg, MRG_PRESS, toggle_actions_cb, o, NULL);
- contrasty_stroke (cr);
-}
-
-static void ui_viewer (State *o)
-{
- Mrg *mrg = o->mrg;
- cairo_t *cr = mrg_cr (mrg);
- cairo_rectangle (cr, 0,0, mrg_width(mrg), mrg_height(mrg));
- mrg_listen (mrg, MRG_DRAG, on_pan_drag, o, NULL);
- cairo_new_path (cr);
- cairo_scale (cr, mrg_width(mrg), mrg_height(mrg));
- cairo_move_to (cr, 0.2, 0.8);
- cairo_line_to (cr, 0.2, 1.0);
- cairo_line_to (cr, 0.0, 0.9);
- cairo_close_path (cr);
- mrg_listen (mrg, MRG_PRESS, go_prev_cb, o, NULL);
- if (o->show_controls)
- contrasty_stroke (cr);
- else
- cairo_new_path (cr);
-
- cairo_move_to (cr, 0.8, 0.8);
- cairo_line_to (cr, 0.8, 1.0);
- cairo_line_to (cr, 1.0, 0.9);
- cairo_close_path (cr);
-
- mrg_listen (mrg, MRG_PRESS, go_next_cb, o, NULL);
- if (o->show_controls)
- contrasty_stroke (cr);
- else
- cairo_new_path (cr);
-
- cairo_arc (cr, 0.9, 0.1, 0.1, 0.0, G_PI * 2);
- mrg_listen (mrg, MRG_PRESS, toggle_actions_cb, o, NULL);
-
- if (o->show_controls)
- contrasty_stroke (cr);
- else
- cairo_new_path (cr);
-}
-
-static void toggle_show_controls_cb (MrgEvent *event, void *data1, void *data2)
-{
- State *o = data1;
- o->show_controls = !o->show_controls;
- mrg_queue_draw (o->mrg, NULL);
-}
-
-static void ui (Mrg *mrg, void *data)
-{
- State *o = data;
- mrg_gegl_blit (mrg,
- 0, 0,
- mrg_width (mrg), mrg_height (mrg),
- o->sink,
- o->u, o->v,
- o->scale,
- o->render_quality);
-
- if (o->show_controls)
- {
- mrg_printf (mrg, "%s\n", o->path);
-#if DEBUG_OP_LIST
- ui_debug_op_chain (o);
-#endif
- }
-
- if (o->show_actions)
- {
- ui_actions (o);
- mrg_add_binding (mrg, "return", NULL, NULL, toggle_actions_cb, o);
- }
- else if (o->active)
- {
- ui_active_op (o);
- mrg_add_binding (mrg, "return", NULL, NULL, apply_filter_cb, o);
- mrg_add_binding (mrg, "escape", NULL, NULL, disable_filter_cb, o);
- }
- else
- {
- ui_viewer (o);
- mrg_add_binding (mrg, "return", NULL, NULL, toggle_actions_cb, o);
- }
-
- mrg_add_binding (mrg, "left", NULL, NULL, pan_left_cb, o);
- mrg_add_binding (mrg, "right", NULL, NULL, pan_right_cb, o);
- mrg_add_binding (mrg, "up", NULL, NULL, pan_up_cb, o);
- mrg_add_binding (mrg, "down", NULL, NULL, pan_down_cb, o);
- mrg_add_binding (mrg, "+", NULL, NULL, zoom_in_cb, o);
- mrg_add_binding (mrg, "=", NULL, NULL, zoom_in_cb, o);
- mrg_add_binding (mrg, "-", NULL, NULL, zoom_out_cb, o);
- mrg_add_binding (mrg, "1", NULL, NULL, zoom_1_cb, o);
- mrg_add_binding (mrg, "m", NULL, NULL, zoom_fit_cb, o);
-
- mrg_add_binding (mrg, "control-q", NULL, NULL, mrg_quit_cb, o);
- mrg_add_binding (mrg, "m", NULL, NULL, zoom_fit_cb, o);
- mrg_add_binding (mrg, "q", NULL, NULL, mrg_quit_cb, o);
- mrg_add_binding (mrg, "x", NULL, NULL, discard_cb, o);
- mrg_add_binding (mrg, "f", NULL, NULL, toggle_fullscreen_cb, o);
- mrg_add_binding (mrg, "F11", NULL, NULL, toggle_fullscreen_cb, o);
- mrg_add_binding (mrg, "tab", NULL, NULL, toggle_show_controls_cb, o);
- mrg_add_binding (mrg, "space", NULL, NULL, go_next_cb , o);
- mrg_add_binding (mrg, "n", NULL, NULL, go_next_cb, o);
- mrg_add_binding (mrg, "p", NULL, NULL, go_prev_cb, o);
- mrg_add_binding (mrg, "backspace", NULL, NULL, go_prev_cb, o);
-
- mrg_add_binding (mrg, ",", NULL, NULL, preview_less_cb, o);
- mrg_add_binding (mrg, ".", NULL, NULL, preview_more_cb, o);
-}
-
#if 0
void gegl_node_defaults (GeglNode *node)
{
@@ -1233,129 +1368,6 @@ void gegl_node_defaults (GeglNode *node)
* creates live gegl pipeline, or nops.. rigs up o->giev_path to be
* the location where default saves ends up.
*/
-static void load_path (State *o)
-{
- char *path;
- char *meta;
- if (is_giev_path (o->path))
- {
- if (o->giev_path)
- free (o->giev_path);
- o->giev_path = o->path;
- o->path = unsuffix_path (o->giev_path);
- }
- else
- {
- if (o->giev_path)
- free (o->giev_path);
- o->giev_path = suffix_path (o->path);
- }
- path = o->path;
-
- if (access (o->giev_path, F_OK) != -1)
- path = o->giev_path;
-
- g_object_unref (o->gegl);
- o->gegl = NULL;
-
- meta = gegl_meta_get (path);
- if (meta)
- {
- GSList *nodes, *n;
- o->gegl = gegl_node_new_from_xml (meta, NULL);
- o->sink = gegl_node_new_child (o->gegl,
- "operation", "gegl:nop", NULL);
- o->source = NULL;
- gegl_node_link_many (
- gegl_node_get_producer (o->gegl, "input", NULL), o->sink, NULL);
- nodes = gegl_node_get_children (o->gegl);
- for (n = nodes; n; n=n->next)
- {
- const char *op_name = gegl_node_get_operation (n->data);
- if (!strcmp (op_name, "gegl:load"))
- {
- GeglNode *load;
- gchar *path;
- gegl_node_get (n->data, "path", &path, NULL);
- load_into_buffer (o, path);
- gegl_node_set (n->data, "operation", "gegl:nop", NULL);
- o->source = n->data;
- load = gegl_node_new_child (o->gegl, "operation", "gegl:buffer-source",
- "buffer", o->buffer, NULL);
- gegl_node_link_many (load, o->source, NULL);
- g_free (path);
- break;
- }
- }
- o->save = gegl_node_new_child (o->gegl,
- "operation", "gegl:save",
- "path", path,
- NULL);
- }
- else
- {
- o->gegl = gegl_node_new ();
- o->sink = gegl_node_new_child (o->gegl,
- "operation", "gegl:nop", NULL);
- o->source = gegl_node_new_child (o->gegl,
- "operation", "gegl:nop", NULL);
- load_into_buffer (o, path);
- o->load = gegl_node_new_child (o->gegl,
- "operation", "gegl:buffer-source",
- NULL);
- o->save = gegl_node_new_child (o->gegl,
- "operation", "gegl:save",
- "path", o->giev_path,
- NULL);
- gegl_node_link_many (o->load, o->source, o->sink, NULL);
- gegl_node_set (o->load, "buffer", o->buffer, NULL);
- }
- zoom_to_fit (o);
-
- mrg_queue_draw (o->mrg, NULL);
- o->rev = 0;
-}
-
-int mrg_ui_main (int argc, char **argv);
-int mrg_ui_main (int argc, char **argv)
-{
- Mrg *mrg = mrg_new (1024, 768, NULL);
- State o = {NULL,};
-#ifdef USE_MIPMAPS
- g_setenv ("GEGL_MIPMAP_RENDERING", "1", TRUE);
-#endif
- g_setenv ("BABL_TOLERANCE", "0.1", TRUE);
-
- gegl_init (&argc, &argv);
- o.gegl = gegl_node_new ();
- o.mrg = mrg;
- o.scale = 1.0;
- o.render_quality = 1.0;
- o.preview_quality = 4.0;
-
- if (access (argv[1], F_OK) != -1)
- o.path = strdup (argv[1]);
- else
- {
- printf ("usage: %s <full-path-to-image>\n", argv[0]);
- return -1;
- }
-
- load_path (&o);
- mrg_set_ui (mrg, ui, &o);
- hack_state = &o;
- mrg_main (mrg);
-
- g_object_unref (o.gegl);
- if (o.buffer)
- {
- g_object_unref (o.buffer);
- o.buffer = NULL;
- }
- gegl_exit ();
- return 0;
-}
-
void
gegl_meta_set (const char *path,
const char *meta_data)