[gimp] Issue #2235 - Color reset/swap keyboard shortcuts not discoverable...
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Issue #2235 - Color reset/swap keyboard shortcuts not discoverable...
- Date: Thu, 25 Oct 2018 12:49:23 +0000 (UTC)
commit ae9d84dd2273a9420c1d92468aac178e508f2307
Author: Michael Natterer <mitch gimp org>
Date: Thu Oct 25 14:45:55 2018 +0200
Issue #2235 - Color reset/swap keyboard shortcuts not discoverable...
...via hover tooltips
Use the GtkWidget::query_tooltip() signal on GimpFgBgEditor to emit an
own signal "tooltip" that has the hovered widget area as parameter.
Connect to GimpFgBgEditor::tooltip() in gimptoolbox-color-area.c and
set separate tooltips on the widget's areas, including the shortcuts
for "Swap colors" and "Default colors".
app/core/gimpmarshal.list | 1 +
app/widgets/gimpfgbgeditor.c | 100 +++++++++++++++++++++-----------
app/widgets/gimpfgbgeditor.h | 14 +++++
app/widgets/gimptoolbox-color-area.c | 109 ++++++++++++++++++++++++++++++++---
4 files changed, 184 insertions(+), 40 deletions(-)
---
diff --git a/app/core/gimpmarshal.list b/app/core/gimpmarshal.list
index 4232c475d2..b08acf9391 100644
--- a/app/core/gimpmarshal.list
+++ b/app/core/gimpmarshal.list
@@ -53,6 +53,7 @@ VOID: INT, BOOLEAN
VOID: INT, INT
VOID: INT, INT, INT, INT
VOID: INT, INT, BOOLEAN, BOOLEAN
+VOID: INT, OBJECT
VOID: OBJECT
VOID: OBJECT, BOOLEAN
VOID: OBJECT, INT
diff --git a/app/widgets/gimpfgbgeditor.c b/app/widgets/gimpfgbgeditor.c
index 565a100a53..200be0ba39 100644
--- a/app/widgets/gimpfgbgeditor.c
+++ b/app/widgets/gimpfgbgeditor.c
@@ -52,18 +52,10 @@ enum
enum
{
COLOR_CLICKED,
+ TOOLTIP,
LAST_SIGNAL
};
-typedef enum
-{
- INVALID_AREA,
- FOREGROUND_AREA,
- BACKGROUND_AREA,
- SWAP_AREA,
- DEFAULT_AREA
-} FgBgTarget;
-
static void gimp_fg_bg_editor_dispose (GObject *object);
static void gimp_fg_bg_editor_set_property (GObject *object,
@@ -87,6 +79,11 @@ static gboolean gimp_fg_bg_editor_drag_motion (GtkWidget *widget,
gint x,
gint y,
guint time);
+static gboolean gimp_fg_bg_editor_query_tooltip (GtkWidget *widget,
+ gint x,
+ gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip);
static void gimp_fg_bg_editor_drag_color (GtkWidget *widget,
GimpRGB *color,
@@ -124,6 +121,17 @@ gimp_fg_bg_editor_class_init (GimpFgBgEditorClass *klass)
G_TYPE_NONE, 1,
GIMP_TYPE_ACTIVE_COLOR);
+ editor_signals[TOOLTIP] =
+ g_signal_new ("tooltip",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpFgBgEditorClass, tooltip),
+ NULL, NULL,
+ gimp_marshal_VOID__INT_OBJECT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT,
+ GTK_TYPE_TOOLTIP);
+
object_class->dispose = gimp_fg_bg_editor_dispose;
object_class->set_property = gimp_fg_bg_editor_set_property;
object_class->get_property = gimp_fg_bg_editor_get_property;
@@ -133,6 +141,7 @@ gimp_fg_bg_editor_class_init (GimpFgBgEditorClass *klass)
widget_class->button_press_event = gimp_fg_bg_editor_button_press;
widget_class->button_release_event = gimp_fg_bg_editor_button_release;
widget_class->drag_motion = gimp_fg_bg_editor_drag_motion;
+ widget_class->query_tooltip = gimp_fg_bg_editor_query_tooltip;
g_object_class_install_property (object_class, PROP_CONTEXT,
g_param_spec_object ("context",
@@ -439,7 +448,7 @@ gimp_fg_bg_editor_draw (GtkWidget *widget,
return TRUE;
}
-static FgBgTarget
+static GimpFgBgTarget
gimp_fg_bg_editor_target (GimpFgBgEditor *editor,
gint x,
gint y)
@@ -476,31 +485,31 @@ gimp_fg_bg_editor_target (GimpFgBgEditor *editor,
y > border.top &&
y < border.top + rect_h)
{
- return FOREGROUND_AREA;
+ return GIMP_FG_BG_TARGET_FOREGROUND;
}
else if (x > width - border.right - rect_w &&
x < width - border.right &&
y > height - border.bottom - rect_h &&
y < height - border.bottom)
{
- return BACKGROUND_AREA;
+ return GIMP_FG_BG_TARGET_BACKGROUND;
}
else if (x > border.left &&
x < border.left + button_width &&
y > border.top + rect_h &&
y < height - border.bottom)
{
- return DEFAULT_AREA;
+ return GIMP_FG_BG_TARGET_DEFAULT;
}
else if (x > border.left + rect_w &&
x < width - border.right &&
y > border.top &&
y < border.top + button_height)
{
- return SWAP_AREA;
+ return GIMP_FG_BG_TARGET_SWAP;
}
- return INVALID_AREA;
+ return GIMP_FG_BG_TARGET_INVALID;
}
static gboolean
@@ -511,33 +520,33 @@ gimp_fg_bg_editor_button_press (GtkWidget *widget,
if (bevent->button == 1 && bevent->type == GDK_BUTTON_PRESS)
{
- FgBgTarget target = gimp_fg_bg_editor_target (editor,
- bevent->x, bevent->y);
+ GimpFgBgTarget target = gimp_fg_bg_editor_target (editor,
+ bevent->x, bevent->y);
- editor->click_target = INVALID_AREA;
+ editor->click_target = GIMP_FG_BG_TARGET_INVALID;
switch (target)
{
- case FOREGROUND_AREA:
+ case GIMP_FG_BG_TARGET_FOREGROUND:
if (editor->active_color != GIMP_ACTIVE_COLOR_FOREGROUND)
gimp_fg_bg_editor_set_active (editor,
GIMP_ACTIVE_COLOR_FOREGROUND);
- editor->click_target = FOREGROUND_AREA;
+ editor->click_target = GIMP_FG_BG_TARGET_FOREGROUND;
break;
- case BACKGROUND_AREA:
+ case GIMP_FG_BG_TARGET_BACKGROUND:
if (editor->active_color != GIMP_ACTIVE_COLOR_BACKGROUND)
gimp_fg_bg_editor_set_active (editor,
GIMP_ACTIVE_COLOR_BACKGROUND);
- editor->click_target = BACKGROUND_AREA;
+ editor->click_target = GIMP_FG_BG_TARGET_BACKGROUND;
break;
- case SWAP_AREA:
+ case GIMP_FG_BG_TARGET_SWAP:
if (editor->context)
gimp_context_swap_colors (editor->context);
break;
- case DEFAULT_AREA:
+ case GIMP_FG_BG_TARGET_DEFAULT:
if (editor->context)
gimp_context_set_default_colors (editor->context);
break;
@@ -558,19 +567,19 @@ gimp_fg_bg_editor_button_release (GtkWidget *widget,
if (bevent->button == 1)
{
- FgBgTarget target = gimp_fg_bg_editor_target (editor,
- bevent->x, bevent->y);
+ GimpFgBgTarget target = gimp_fg_bg_editor_target (editor,
+ bevent->x, bevent->y);
if (target == editor->click_target)
{
switch (target)
{
- case FOREGROUND_AREA:
+ case GIMP_FG_BG_TARGET_FOREGROUND:
g_signal_emit (editor, editor_signals[COLOR_CLICKED], 0,
GIMP_ACTIVE_COLOR_FOREGROUND);
break;
- case BACKGROUND_AREA:
+ case GIMP_FG_BG_TARGET_BACKGROUND:
g_signal_emit (editor, editor_signals[COLOR_CLICKED], 0,
GIMP_ACTIVE_COLOR_BACKGROUND);
break;
@@ -580,7 +589,7 @@ gimp_fg_bg_editor_button_release (GtkWidget *widget,
}
}
- editor->click_target = INVALID_AREA;
+ editor->click_target = GIMP_FG_BG_TARGET_INVALID;
}
return FALSE;
@@ -594,9 +603,10 @@ gimp_fg_bg_editor_drag_motion (GtkWidget *widget,
guint time)
{
GimpFgBgEditor *editor = GIMP_FG_BG_EDITOR (widget);
- FgBgTarget target = gimp_fg_bg_editor_target (editor, x, y);
+ GimpFgBgTarget target = gimp_fg_bg_editor_target (editor, x, y);
- if (target == FOREGROUND_AREA || target == BACKGROUND_AREA)
+ if (target == GIMP_FG_BG_TARGET_FOREGROUND ||
+ target == GIMP_FG_BG_TARGET_BACKGROUND)
{
gdk_drag_status (context, GDK_ACTION_COPY, time);
@@ -608,6 +618,30 @@ gimp_fg_bg_editor_drag_motion (GtkWidget *widget,
return FALSE;
}
+static gboolean
+gimp_fg_bg_editor_query_tooltip (GtkWidget *widget,
+ gint x,
+ gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip)
+{
+ if (! keyboard_mode)
+ {
+ GimpFgBgEditor *editor = GIMP_FG_BG_EDITOR (widget);
+ GimpFgBgTarget target = gimp_fg_bg_editor_target (editor, x, y);
+
+ if (target != GIMP_FG_BG_TARGET_INVALID)
+ {
+ g_signal_emit (widget, editor_signals[TOOLTIP], 0,
+ target, tooltip);
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
/* public functions */
@@ -718,11 +752,11 @@ gimp_fg_bg_editor_drop_color (GtkWidget *widget,
{
switch (gimp_fg_bg_editor_target (editor, x, y))
{
- case FOREGROUND_AREA:
+ case GIMP_FG_BG_TARGET_FOREGROUND:
gimp_context_set_foreground (editor->context, color);
break;
- case BACKGROUND_AREA:
+ case GIMP_FG_BG_TARGET_BACKGROUND:
gimp_context_set_background (editor->context, color);
break;
diff --git a/app/widgets/gimpfgbgeditor.h b/app/widgets/gimpfgbgeditor.h
index a3d4bb3846..7c425afc7d 100644
--- a/app/widgets/gimpfgbgeditor.h
+++ b/app/widgets/gimpfgbgeditor.h
@@ -22,6 +22,16 @@
#define __GIMP_FG_BG_EDITOR_H__
+typedef enum
+{
+ GIMP_FG_BG_TARGET_INVALID,
+ GIMP_FG_BG_TARGET_FOREGROUND,
+ GIMP_FG_BG_TARGET_BACKGROUND,
+ GIMP_FG_BG_TARGET_SWAP,
+ GIMP_FG_BG_TARGET_DEFAULT
+} GimpFgBgTarget;
+
+
#define GIMP_TYPE_FG_BG_EDITOR (gimp_fg_bg_editor_get_type ())
#define GIMP_FG_BG_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_FG_BG_EDITOR,
GimpFgBgEditor))
#define GIMP_FG_BG_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_FG_BG_EDITOR,
GimpFgBgEditorClass))
@@ -58,6 +68,10 @@ struct _GimpFgBgEditorClass
void (* color_clicked) (GimpFgBgEditor *editor,
GimpActiveColor color);
+
+ void (* tooltip) (GimpFgBgEditor *editor,
+ GimpFgBgTarget target,
+ GtkTooltip tooltip);
};
diff --git a/app/widgets/gimptoolbox-color-area.c b/app/widgets/gimptoolbox-color-area.c
index 57854e4bd2..feea1b5f77 100644
--- a/app/widgets/gimptoolbox-color-area.c
+++ b/app/widgets/gimptoolbox-color-area.c
@@ -36,6 +36,7 @@
#include "gimpsessioninfo.h"
#include "gimptoolbox.h"
#include "gimptoolbox-color-area.h"
+#include "gimpuimanager.h"
#include "gimp-intl.h"
@@ -57,6 +58,10 @@ static void color_area_dialog_update (GimpColorDialog *dialog,
static void color_area_color_clicked (GimpFgBgEditor *editor,
GimpActiveColor active_color,
GimpContext *context);
+static void color_area_tooltip (GimpFgBgEditor *editor,
+ GimpFgBgTarget target,
+ GtkTooltip *tooltip,
+ GimpToolbox *toolbox);
/* local variables */
@@ -85,18 +90,18 @@ gimp_toolbox_color_area_create (GimpToolbox *toolbox,
color_area = gimp_fg_bg_editor_new (context);
gtk_widget_set_size_request (color_area, width, height);
- gimp_help_set_help_data
- (color_area,
- _("Foreground & background colors.\n"
- "The black and white squares reset colors.\n"
- "The arrows swap colors.\n"
- "Click to open the color selection dialog."),
- GIMP_HELP_TOOLBOX_COLOR_AREA);
+ gimp_help_set_help_data (color_area, NULL,
+ GIMP_HELP_TOOLBOX_COLOR_AREA);
+ g_object_set (color_area, "has-tooltip", TRUE, NULL);
g_signal_connect (color_area, "color-clicked",
G_CALLBACK (color_area_color_clicked),
context);
+ g_signal_connect (color_area, "tooltip",
+ G_CALLBACK (color_area_tooltip),
+ toolbox);
+
return color_area;
}
@@ -281,3 +286,93 @@ color_area_color_clicked (GimpFgBgEditor *editor,
gtk_window_present (GTK_WINDOW (color_dialog));
color_dialog_active = TRUE;
}
+
+static gboolean
+accel_find_func (GtkAccelKey *key,
+ GClosure *closure,
+ gpointer data)
+{
+ return (GClosure *) data == closure;
+}
+
+static void
+color_area_tooltip (GimpFgBgEditor *editor,
+ GimpFgBgTarget target,
+ GtkTooltip *tooltip,
+ GimpToolbox *toolbox)
+{
+ GimpUIManager *manager = gimp_dock_get_ui_manager (GIMP_DOCK (toolbox));
+ GtkAction *action = NULL;
+ const gchar *text = NULL;
+
+ switch (target)
+ {
+ case GIMP_FG_BG_TARGET_FOREGROUND:
+ text = _("The active foreground color.\n"
+ "Click to open the color selection dialog.");
+ break;
+
+ case GIMP_FG_BG_TARGET_BACKGROUND:
+ text = _("The active background color.\n"
+ "Click to open the color selection dialog.");
+ break;
+
+ case GIMP_FG_BG_TARGET_SWAP:
+ action = gimp_ui_manager_find_action (manager, "context",
+ "context-colors-swap");
+ text = gtk_action_get_tooltip (action);
+ break;
+
+ case GIMP_FG_BG_TARGET_DEFAULT:
+ action = gimp_ui_manager_find_action (manager, "context",
+ "context-colors-default");
+ text = gtk_action_get_tooltip (action);
+ break;
+
+ default:
+ break;
+ }
+
+ if (text)
+ {
+ gchar *markup = NULL;
+
+ if (action)
+ {
+ GtkAccelGroup *accel_group;
+ GClosure *accel_closure;
+ GtkAccelKey *accel_key;
+
+ accel_closure = gtk_action_get_accel_closure (action);
+ accel_group = gtk_accel_group_from_accel_closure (accel_closure);
+
+ accel_key = gtk_accel_group_find (accel_group,
+ accel_find_func,
+ accel_closure);
+
+ if (accel_key &&
+ accel_key->accel_key &&
+ (accel_key->accel_flags & GTK_ACCEL_VISIBLE))
+ {
+ gchar *escaped = g_markup_escape_text (text, -1);
+ gchar *accel = gtk_accelerator_get_label (accel_key->accel_key,
+ accel_key->accel_mods);
+
+ markup = g_strdup_printf ("%s <b>%s</b>", escaped, accel);
+
+ g_free (accel);
+ g_free (escaped);
+ }
+ }
+
+ if (markup)
+ {
+ gtk_tooltip_set_markup (tooltip, markup);
+ g_free (markup);
+ }
+ else
+ {
+ gtk_tooltip_set_text (tooltip, text);
+ }
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]