mirror of https://github.com/GNOME/gimp.git
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".
This commit is contained in:
parent
231b82a7fe
commit
ae9d84dd22
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue