[gegl] bin: implement keybindings for integer/double prop-editors
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] bin: implement keybindings for integer/double prop-editors
- Date: Fri, 25 Jan 2019 01:58:19 +0000 (UTC)
commit fd97041a500adb5a2a23dadef270f4ea3dd79f9d
Author: Øyvind Kolås <pippin gimp org>
Date: Fri Jan 25 02:57:47 2019 +0100
bin: implement keybindings for integer/double prop-editors
bin/ui.c | 429 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 356 insertions(+), 73 deletions(-)
---
diff --git a/bin/ui.c b/bin/ui.c
index 368085b75..e051f062c 100644
--- a/bin/ui.c
+++ b/bin/ui.c
@@ -270,6 +270,8 @@ struct _State {
int controls_timeout;
int frame_no;
+ const char *property_focus; // interned string of property name, or "operation" or "id"
+
char **ops; // the operations part of the commandline, if any
float slide_pause;
int slide_enabled;
@@ -2371,9 +2373,30 @@ draw_property_string (State *o, Mrg *mrg, GeglNode *node, const GParamSpec *pspe
mrg_end (mrg);
}
+static void
+draw_property_focus_box (State *o, Mrg *mrg)
+{
+ cairo_t *cr = mrg_cr (mrg);
+ cairo_save (cr);
+ cairo_new_path (cr);
+ cairo_move_to (cr, mrg_x (mrg), mrg_y (mrg));
+ cairo_rel_line_to (cr, mrg_style (mrg)->width, 0);
+ cairo_rel_line_to (cr, -mrg_style (mrg)->width - mrg_em(mrg) * .25, 0);
+ cairo_rel_line_to (cr, 0, mrg_em (mrg));
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+
static void
draw_property (State *o, Mrg *mrg, GeglNode *node, const GParamSpec *pspec)
{
+ gboolean focused_property = g_intern_string (pspec->name) == o->property_focus;
+
+ if (focused_property)
+ {
+ draw_property_focus_box (o, mrg);
+ }
if (g_type_is_a (pspec->value_type, G_TYPE_DOUBLE))
{
@@ -2429,6 +2452,9 @@ static void list_node_props (State *o, GeglNode *node, int indent)
mrg_start (mrg, "div.properties", NULL);
+ if (o->property_focus == g_intern_string ("operation"))
+ draw_property_focus_box (o, mrg);
+
mrg_text_listen (mrg, MRG_CLICK, set_int, &operation_selector, GINT_TO_POINTER(1));
draw_key_value (o, mrg, "operation", op_name);
mrg_text_listen_done (mrg);
@@ -2437,6 +2463,8 @@ static void list_node_props (State *o, GeglNode *node, int indent)
const char *id = g_object_get_data (G_OBJECT (node), "refname");
if (id)
{
+ if (o->property_focus == g_intern_string ("id"))
+ draw_property_focus_box (o, mrg);
draw_key_value (o, mrg, "id", id);
}
}
@@ -2830,8 +2858,10 @@ int cmd_graph_cursor (COMMAND_ARGS) /* "graph-cursor", 1, "<left|right|up|down|s
ref = o->source;
o->pad_active = PAD_OUTPUT;
}
- else
+ else {
+ printf ("unkown graph cursor sub command %s\n", argv[1]);
ref = NULL;
+ }
if (ref)
o->active = ref;
@@ -3797,10 +3827,14 @@ static void
run_command (MrgEvent *event, void *data1, void *data_2)
{
State *o = global_state;
- const char *commandline = data1;
+ char *commandline = data1;
gchar **argv = NULL;
gint argc = 0;
+
+ while (commandline && commandline[strlen(commandline)-1]==' ')
+ commandline[strlen(commandline)-1]='\0';
+
g_shell_parse_argv (commandline, &argc, &argv, NULL);
/* the commandline has two modes, operation/property mode and argvs command running mode
@@ -4525,86 +4559,96 @@ static GList *commandline_get_completions (GeglNode *node,
g_free (operations);
}
-
- if (key) /* an = is already part of last bit.. this changes our behavior */
+ if (prev && !strcmp (prev, "set"))
+ {
+ for (int i = 0; i < sizeof(settings)/sizeof(settings[0]); i++)
+ {
+ if (g_str_has_prefix (settings[i].name, last))
+ {
+ char *result = g_strdup_printf ("%s ", settings[i].name + strlen (last));
+ completions = g_list_prepend (completions, result);
+ count ++;
+ }
+ }
+ }
+ else
{
- guint n_props;
- gint i;
- GParamSpec **pspecs = gegl_operation_list_properties (op_name, &n_props);
- GParamSpec *pspec = NULL;
- for (i = 0; i < n_props; i++)
- {
- if (!strcmp (pspecs[i]->name, key))
- pspec = pspecs[i];
- }
- g_free (pspecs);
- if (pspec && g_type_is_a (pspec->value_type, G_TYPE_ENUM))
+ if (key) /* an = is already part of last bit.. this changes our behavior */
+ {
+ guint n_props;
+ gint i;
+ GParamSpec **pspecs = gegl_operation_list_properties (op_name, &n_props);
+ GParamSpec *pspec = NULL;
+ for (i = 0; i < n_props; i++)
+ {
+ if (!strcmp (pspecs[i]->name, key))
+ pspec = pspecs[i];
+ }
+ g_free (pspecs);
+
+ if (pspec && g_type_is_a (pspec->value_type, G_TYPE_ENUM))
+ {
+ GEnumClass *eclass = g_type_class_peek (pspec->value_type);
+ for (i = eclass->minimum; i<= eclass->maximum; i++)
+ {
+ GEnumValue *evalue = &eclass->values[i];
+ if (g_str_has_prefix (evalue->value_nick, value))
+ {
+ char *result = g_strdup_printf ("%s", evalue->value_nick + strlen (value));
+ completions = g_list_prepend (completions, result);
+ count ++;
+ }
+ }
+ }
+ }
+ else
+ {
{
- GEnumClass *eclass = g_type_class_peek (pspec->value_type);
- for (i = eclass->minimum; i<= eclass->maximum; i++)
+ guint n_props;
+ gint i;
+ GParamSpec **pspecs = gegl_operation_list_properties (op_name, &n_props);
+ for (i = 0; i < n_props && count < bail; i++)
{
- GEnumValue *evalue = &eclass->values[i];
- if (g_str_has_prefix (evalue->value_nick, value))
+ if (g_str_has_prefix (pspecs[i]->name, last))
{
- char *result = g_strdup_printf ("%s", evalue->value_nick + strlen (value));
+ char *result = g_strdup_printf ("%s=", pspecs[i]->name + strlen (last));
completions = g_list_prepend (completions, result);
count ++;
}
}
+ g_free (pspecs);
}
- }
- else
- {
- {
- guint n_props;
+
+ {
+ char prefixed_by_gegl[512];
+ char ** operations = operations;
gint i;
- GParamSpec **pspecs = gegl_operation_list_properties (op_name, &n_props);
- for (i = 0; i < n_props && count < bail; i++)
+ guint n_operations;
+ /* the last fragment is what we're completing */
+ operations = gegl_list_operations (&n_operations);
+ for (i = 0; i < n_operations && count < bail; i++)
{
- if (g_str_has_prefix (pspecs[i]->name, last))
+ if (g_str_has_prefix (operations[i], last))
{
- char *result = g_strdup_printf ("%s=", pspecs[i]->name + strlen (last));
- completions = g_list_prepend (completions, result);
+ completions = g_list_prepend (completions, g_strdup (operations[i] + strlen (last)));
count ++;
}
}
+ sprintf (prefixed_by_gegl, "gegl:%s", last);
- g_free (pspecs);
- }
-
- {
- char prefixed_by_gegl[512];
- char ** operations = operations;
- gint i;
- guint n_operations;
- /* the last fragment is what we're completing */
- operations = gegl_list_operations (&n_operations);
- for (i = 0; i < n_operations && count < bail; i++)
- {
- if (g_str_has_prefix (operations[i], last))
+ for (i = 0; i < n_operations && count < bail; i++)
{
- completions = g_list_prepend (completions, g_strdup (operations[i] + strlen (last)));
- count ++;
+ if (g_str_has_prefix (operations[i], prefixed_by_gegl))
+ {
+ completions = g_list_prepend (completions, g_strdup (operations[i] + strlen (prefixed_by_gegl)));
+ count ++;
+ }
}
- }
- sprintf (prefixed_by_gegl, "gegl:%s", last);
- for (i = 0; i < n_operations && count < bail; i++)
- {
- if (g_str_has_prefix (operations[i], prefixed_by_gegl))
- {
- completions = g_list_prepend (completions, g_strdup (operations[i] + strlen (prefixed_by_gegl)));
- count ++;
- }
+ g_free (operations);
+ }
}
-
-
- g_free (operations);
- }
-
-
-
}
if (key)
@@ -4797,6 +4841,58 @@ static void ui_commandline (Mrg *mrg, void *data)
cairo_restore (cr);
}
+static void vector_op_ui (State *o, GeglNode *node)
+{
+ Mrg *mrg = o->mrg;
+ GeglPath *path;
+ cairo_t *cr = mrg_cr (mrg);
+ double linewidth = 2.0f;
+ double linewidth_shadow = 2.5f;
+ double foo ;
+
+ cairo_device_to_user_distance (cr, &linewidth, &foo);
+ cairo_device_to_user_distance (cr, &linewidth_shadow, &foo);
+
+ return;
+
+ gegl_node_get (node, "d", &path, NULL);
+
+
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 1100,1100);
+
+ cairo_set_source_rgba (cr, 0,0,0, .5);
+ cairo_set_line_width (cr, linewidth_shadow);
+ cairo_set_source_rgba (cr, 1,0,0, 1.0);
+ cairo_stroke (cr);
+}
+
+
+
+
+static int per_op_canvas_ui (State *o)
+{
+ Mrg *mrg = o->mrg;
+ cairo_t *cr = mrg_cr (mrg);
+
+ const char *opname;
+ if (!o->active)
+ return -1;
+
+ cairo_save (cr);
+ cairo_translate (cr, -o->u, -o->v);
+ cairo_scale (cr, o->scale, o->scale);
+
+ opname = gegl_node_get_operation (o->active);
+ if (!strcmp (opname, "gegl:vector-stroke"))
+ {
+ vector_op_ui (o, o->active);
+ }
+
+ cairo_restore (cr);
+
+ return 0;
+}
static void gegl_ui (Mrg *mrg, void *data)
{
@@ -4878,6 +4974,9 @@ static void gegl_ui (Mrg *mrg, void *data)
{
if (o->show_graph)
{
+ per_op_canvas_ui (o);
+
+
ui_debug_op_chain (o);
mrg_add_binding (mrg, "escape", NULL, NULL, run_command, "toggle editing");
}
@@ -4909,7 +5008,7 @@ static void gegl_ui (Mrg *mrg, void *data)
mrg_add_binding (mrg, "control-q", NULL, NULL, run_command, "quit");
mrg_add_binding (mrg, "F11", NULL, NULL, run_command, "toggle fullscreen");
- if (!edited_prop && !o->editing_op_name && ! o->is_dir)
+ if (!edited_prop && !o->editing_op_name && ! o->is_dir && o->property_focus == NULL)
{
#if 0
if (o->active && gegl_node_has_pad (o->active, "output"))
@@ -4972,14 +5071,29 @@ static void gegl_ui (Mrg *mrg, void *data)
}
else
{
- mrg_add_binding (mrg, "home", NULL, NULL, run_command, "graph-cursor append");
- mrg_add_binding (mrg, "end", NULL, NULL, run_command, "graph-cursor source");
+ mrg_add_binding (mrg, "tab", NULL, NULL, run_command, "prop-editor focus");
- if (o->active && gegl_node_has_pad (o->active, "output"))
- mrg_add_binding (mrg, "left", NULL, NULL, run_command, "graph-cursor left");
- if (o->active) // && gegl_node_has_pad (o->active, "aux"))
- mrg_add_binding (mrg, "right", NULL, NULL, run_command, "graph-cursor right");
- mrg_add_binding (mrg, "space", NULL, NULL, run_command, "next");
+ if (o->property_focus)
+ {
+ //mrg_add_binding (mrg, "return", NULL, NULL, run_command, "prop-editor return");
+ mrg_add_binding (mrg, "left", NULL, NULL, run_command, "prop-editor space");
+ mrg_add_binding (mrg, "left", NULL, NULL, run_command, "prop-editor left");
+ mrg_add_binding (mrg, "right", NULL, NULL, run_command, "prop-editor right");
+ mrg_add_binding (mrg, "shift-left", NULL, NULL, run_command, "prop-editor shift-left");
+ mrg_add_binding (mrg, "shift-right", NULL, NULL,run_command, "prop-editor shift-right");
+
+ }
+ else
+ {
+ mrg_add_binding (mrg, "home", NULL, NULL, run_command, "graph-cursor append");
+ mrg_add_binding (mrg, "end", NULL, NULL, run_command, "graph-cursor source");
+
+ if (o->active && gegl_node_has_pad (o->active, "output"))
+ mrg_add_binding (mrg, "left", NULL, NULL, run_command, "graph-cursor left");
+ if (o->active) // && gegl_node_has_pad (o->active, "aux"))
+ mrg_add_binding (mrg, "right", NULL, NULL, run_command, "graph-cursor right");
+ mrg_add_binding (mrg, "space", NULL, NULL, run_command, "next");
+ }
//mrg_add_binding (mrg, "backspace", NULL, NULL, run_command, "prev");
}
#if 0
@@ -5000,11 +5114,19 @@ static void gegl_ui (Mrg *mrg, void *data)
mrg_add_binding (mrg, "control-m", NULL, NULL, run_command, "toggle mipmap");
mrg_add_binding (mrg, "control-y", NULL, NULL, run_command, "toggle colormanage-display");
+ if (o->property_focus)
+ {
+ mrg_add_binding (mrg, "up", NULL, NULL, run_command, "prop-editor up");
+ mrg_add_binding (mrg, "down", NULL, NULL, run_command, "prop-editor down");
- if (o->active && gegl_node_has_pad (o->active, "output"))
- mrg_add_binding (mrg, "up", NULL, NULL, run_command, "graph-cursor up");
- if (o->active && gegl_node_has_pad (o->active, "input"))
- mrg_add_binding (mrg, "down", NULL, NULL, run_command, "graph-cursor down");
+ }
+ else
+ {
+ if (o->active && gegl_node_has_pad (o->active, "output"))
+ mrg_add_binding (mrg, "up", NULL, NULL, run_command, "graph-cursor up");
+ if (o->active && gegl_node_has_pad (o->active, "input"))
+ mrg_add_binding (mrg, "down", NULL, NULL, run_command, "graph-cursor down");
+ }
if (o->active && gegl_node_has_pad (o->active, "input") &&
gegl_node_has_pad (o->active, "output"))
@@ -5372,6 +5494,166 @@ static void go_prev (State *o)
}
}
+int cmd_propeditor (COMMAND_ARGS); /* "prop-editor", 1, "<subcommand>", "used for property editing
keybindings"*/
+int
+cmd_propeditor (COMMAND_ARGS)
+{
+ State *o = global_state;
+ GParamSpec *pspec = o->property_focus?gegl_node_find_property (o->active, o->property_focus):NULL;
+
+
+ if (!strcmp (argv[1], "left") ||
+ !strcmp (argv[1], "shift-left"))
+ {
+ if (!pspec)
+ return 0;
+ if (g_type_is_a (pspec->value_type, G_TYPE_DOUBLE))
+ {
+ double value;
+ double step = 1.0;
+ if (GEGL_IS_PARAM_SPEC_DOUBLE (pspec))
+ {
+ if (!strcmp (argv[1], "shift-left"))
+ step = GEGL_PARAM_SPEC_DOUBLE (pspec)->ui_step_big;
+ else
+ step = GEGL_PARAM_SPEC_DOUBLE (pspec)->ui_step_small;
+ }
+
+ gegl_node_get (o->active, o->property_focus, &value, NULL);
+ value -= step;
+ gegl_node_set (o->active, o->property_focus, value, NULL);
+ }
+ else if (g_type_is_a (pspec->value_type, G_TYPE_INT) ||
+ g_type_is_a (pspec->value_type, G_TYPE_ENUM))
+ {
+ int value;
+ gegl_node_get (o->active, o->property_focus, &value, NULL);
+ value -= 1;
+ gegl_node_set (o->active, o->property_focus, value, NULL);
+ }
+ else if (g_type_is_a (pspec->value_type, G_TYPE_STRING) ||
+ g_type_is_a (pspec->value_type, GEGL_TYPE_PARAM_FILE_PATH))
+ {
+ }
+ else if (g_type_is_a (pspec->value_type, GEGL_TYPE_COLOR))
+ {
+ }
+ else if (g_type_is_a (pspec->value_type, G_TYPE_BOOLEAN))
+ {
+ gboolean value;
+ gegl_node_get (o->active, o->property_focus, &value, NULL);
+ value = !value;
+ gegl_node_set (o->active, o->property_focus, value, NULL);
+ }
+ else
+ {
+ }
+
+ o->rev++;
+ renderer_dirty++;
+ }
+ else if (!strcmp (argv[1], "right")||
+ !strcmp (argv[1], "shift-right"))
+ {
+ if (!pspec)
+ return 0;
+ if (g_type_is_a (pspec->value_type, G_TYPE_DOUBLE))
+ {
+ double value;
+ double step = 1.0;
+ if (GEGL_IS_PARAM_SPEC_DOUBLE (pspec))
+ {
+ if (!strcmp (argv[1], "shift-right"))
+ step = GEGL_PARAM_SPEC_DOUBLE (pspec)->ui_step_big;
+ else
+ step = GEGL_PARAM_SPEC_DOUBLE (pspec)->ui_step_small;
+ }
+ gegl_node_get (o->active, o->property_focus, &value, NULL);
+ value += step;
+ gegl_node_set (o->active, o->property_focus, value, NULL);
+ }
+ else if (g_type_is_a (pspec->value_type, G_TYPE_INT) ||
+ g_type_is_a (pspec->value_type, G_TYPE_ENUM))
+ {
+ int value;
+ gegl_node_get (o->active, o->property_focus, &value, NULL);
+ value += 1;
+ gegl_node_set (o->active, o->property_focus, value, NULL);
+ }
+ else if (g_type_is_a (pspec->value_type, G_TYPE_STRING) ||
+ g_type_is_a (pspec->value_type, GEGL_TYPE_PARAM_FILE_PATH))
+ {
+ }
+ else if (g_type_is_a (pspec->value_type, GEGL_TYPE_COLOR))
+ {
+ }
+ else if (g_type_is_a (pspec->value_type, G_TYPE_BOOLEAN))
+ {
+ gboolean value;
+ gegl_node_get (o->active, o->property_focus, &value, NULL);
+ value = !value;
+ gegl_node_set (o->active, o->property_focus, value, NULL);
+ }
+ else
+ {
+ }
+
+ o->rev++;
+ renderer_dirty++;
+ }
+ else if (!strcmp (argv[1], "focus"))
+ {
+ if (o->property_focus)
+ {
+ o->property_focus = NULL;
+ }
+ else
+ {
+ o->property_focus = g_intern_string ("operation");
+ }
+ }
+ else if (!strcmp (argv[1], "down"))
+ {
+ GParamSpec **pspecs = NULL;
+ unsigned int n_props = 0;
+ int i, next = -1;
+ pspecs = gegl_operation_list_properties (gegl_node_get_operation (o->active), &n_props);
+ for (i = 0; i < n_props; i++)
+ if (g_intern_string (pspecs[i]->name) == o->property_focus)
+ {
+ next = i; break;
+ }
+ next++;
+ if (next < n_props)
+ o->property_focus = g_intern_string (pspecs[next]->name);
+
+ g_free (pspecs);
+ }
+ else if (!strcmp (argv[1], "up"))
+ {
+ GParamSpec **pspecs = NULL;
+ unsigned int n_props = 0;
+ int i, next = -1;
+ pspecs = gegl_operation_list_properties (gegl_node_get_operation (o->active), &n_props);
+ for (i = 0; i < n_props; i++)
+ if (g_intern_string (pspecs[i]->name) == o->property_focus)
+ {
+ next = i; break;
+ }
+ next--;
+ if (next >= 0)
+ o->property_focus = g_intern_string (pspecs[next]->name);
+ else
+ o->property_focus = g_intern_string ("operation");
+
+ g_free (pspecs);
+ }
+
+ mrg_queue_draw (o->mrg, NULL);
+ return 0;
+}
+
+
int cmd_clear (COMMAND_ARGS); /* "clear", 0, "", "clears the scrollback and triggers as rerender"*/
int
cmd_clear (COMMAND_ARGS)
@@ -5987,6 +6269,7 @@ cmd_toggle (COMMAND_ARGS)
renderer = GEGL_RENDERER_IDLE;
printf ("disabled mipmap rendering\n");
}
+ renderer_dirty++;
}
else if (!strcmp(argv[1], "controls"))
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]