Commit c7dd4d8d authored by Michael Natterer's avatar Michael Natterer

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".

(cherry picked from commit ae9d84dd2273a9420c1d92468aac178e508f2307)
parent 3f7ca2b2
......@@ -52,6 +52,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
......
......@@ -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,
......@@ -88,6 +80,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,
......@@ -125,6 +122,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;
......@@ -134,6 +142,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",
......@@ -428,7 +437,7 @@ gimp_fg_bg_editor_expose (GtkWidget *widget,
return TRUE;
}
static FgBgTarget
static GimpFgBgTarget
gimp_fg_bg_editor_target (GimpFgBgEditor *editor,
gint x,
gint y)
......@@ -445,18 +454,26 @@ gimp_fg_bg_editor_target (GimpFgBgEditor *editor,
height = allocation.height;
if (x > 0 && x < rect_w && y > 0 && y < rect_h)
return FOREGROUND_AREA;
{
return GIMP_FG_BG_TARGET_FOREGROUND;
}
else if (x > (width - rect_w) && x < width &&
y > (height - rect_h) && y < height)
return BACKGROUND_AREA;
{
return GIMP_FG_BG_TARGET_BACKGROUND;
}
else if (x > 0 && x < (width - rect_w) &&
y > rect_h && y < height)
return DEFAULT_AREA;
{
return GIMP_FG_BG_TARGET_DEFAULT;
}
else if (x > rect_w && x < width &&
y > 0 && y < (height - rect_h))
return SWAP_AREA;
{
return GIMP_FG_BG_TARGET_SWAP;
}
return INVALID_AREA;
return GIMP_FG_BG_TARGET_INVALID;
}
static gboolean
......@@ -467,33 +484,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;
......@@ -514,19 +531,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;
......@@ -536,7 +553,7 @@ gimp_fg_bg_editor_button_release (GtkWidget *widget,
}
}
editor->click_target = INVALID_AREA;
editor->click_target = GIMP_FG_BG_TARGET_INVALID;
}
return FALSE;
......@@ -550,9 +567,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);
......@@ -564,6 +582,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 */
......@@ -674,11 +716,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;
......
......@@ -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);
};
......
......@@ -35,6 +35,7 @@
#include "gimpsessioninfo.h"
#include "gimptoolbox.h"
#include "gimptoolbox-color-area.h"
#include "gimpuimanager.h"
#include "gimp-intl.h"
......@@ -56,6 +57,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 */
......@@ -87,16 +92,16 @@ gimp_toolbox_color_area_create (GimpToolbox *toolbox,
GDK_ENTER_NOTIFY_MASK |
GDK_LEAVE_NOTIFY_MASK);
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."), NULL);
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;
}
......@@ -282,3 +287,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);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment