[gimp/gimp-2-10] app: add option to show tool-button menu on hover
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] app: add option to show tool-button menu on hover
- Date: Thu, 26 Mar 2020 11:32:55 +0000 (UTC)
commit 04d17b78294effcf8bd2cedf0de53eb99d2c09b9
Author: Ell <ell_se yahoo com>
Date: Thu Mar 26 12:19:27 2020 +0200
app: add option to show tool-button menu on hover
Add a "Menu mode" option to the toolbox preferences, which controls
the menu behavior for tool-group buttons, and can be one of "Show
on click" (current behavior), "Show on hover" (show the menu when
hovering over the button), and "Show on hover in single column"
(behaves like "Show on hover" when the toolbox has a single column,
and "Show on click" otherwise) -- the latter is the default.
Note that "Show on hover" requires the ability to remove the menu
grab, which doesn't seem to work in GTK3, so this change is
restricted to 2.10 for now.
app/config/config-enums.c | 31 ++++++
app/config/config-enums.h | 12 ++
app/config/gimpguiconfig.c | 15 +++
app/config/gimpguiconfig.h | 85 ++++++++-------
app/config/gimprc-blurbs.h | 3 +
app/dialogs/preferences-dialog.c | 31 +++++-
app/widgets/gimptoolbutton.c | 230 ++++++++++++++++++++++++++++++++++++---
app/widgets/gimptoolbutton.h | 20 ++--
app/widgets/gimptoolpalette.c | 150 +++++++++++++++++++------
9 files changed, 478 insertions(+), 99 deletions(-)
---
diff --git a/app/config/config-enums.c b/app/config/config-enums.c
index 70da0248a1..7c8c68e182 100644
--- a/app/config/config-enums.c
+++ b/app/config/config-enums.c
@@ -301,6 +301,37 @@ gimp_space_bar_action_get_type (void)
return type;
}
+GType
+gimp_tool_group_menu_mode_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_CLICK, "GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_CLICK", "click" },
+ { GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER, "GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER", "hover" },
+ { GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER_SINGLE_COLUMN,
"GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER_SINGLE_COLUMN", "hover-single-column" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_CLICK, NC_("tool-group-menu-mode", "Show on click"), NULL },
+ { GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER, NC_("tool-group-menu-mode", "Show on hover"), NULL },
+ { GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER_SINGLE_COLUMN, NC_("tool-group-menu-mode", "Show on hover in
single-column"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpToolGroupMenuMode", values);
+ gimp_type_set_translation_context (type, "tool-group-menu-mode");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
GType
gimp_window_hint_get_type (void)
{
diff --git a/app/config/config-enums.h b/app/config/config-enums.h
index 3881dbabc7..345ef75893 100644
--- a/app/config/config-enums.h
+++ b/app/config/config-enums.h
@@ -135,6 +135,18 @@ typedef enum
} GimpSpaceBarAction;
+#define GIMP_TYPE_TOOL_GROUP_MENU_MODE (gimp_tool_group_menu_mode_get_type ())
+
+GType gimp_tool_group_menu_mode_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_CLICK, /*< desc="Show on click" >*/
+ GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER, /*< desc="Show on hover" >*/
+ GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER_SINGLE_COLUMN /*< desc="Show on hover in single-column" >*/
+} GimpToolGroupMenuMode;
+
+
#define GIMP_TYPE_WINDOW_HINT (gimp_window_hint_get_type ())
GType gimp_window_hint_get_type (void) G_GNUC_CONST;
diff --git a/app/config/gimpguiconfig.c b/app/config/gimpguiconfig.c
index 81ebf52305..79ff839be2 100644
--- a/app/config/gimpguiconfig.c
+++ b/app/config/gimpguiconfig.c
@@ -77,6 +77,7 @@ enum
PROP_TOOLBOX_IMAGE_AREA,
PROP_TOOLBOX_WILBER,
PROP_TOOLBOX_GROUPS,
+ PROP_TOOLBOX_GROUP_MENU_MODE,
PROP_THEME_PATH,
PROP_THEME,
PROP_ICON_THEME_PATH,
@@ -331,6 +332,14 @@ gimp_gui_config_class_init (GimpGuiConfigClass *klass)
TRUE,
GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_TOOLBOX_GROUP_MENU_MODE,
+ "toolbox-group-menu-mode",
+ "Toolbox group menu mode",
+ TOOLBOX_GROUP_MENU_MODE_BLURB,
+ GIMP_TYPE_TOOL_GROUP_MENU_MODE,
+ GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER_SINGLE_COLUMN,
+ GIMP_PARAM_STATIC_STRINGS);
+
path = gimp_config_build_data_path ("themes");
GIMP_CONFIG_PROP_PATH (object_class, PROP_THEME_PATH,
"theme-path",
@@ -680,6 +689,9 @@ gimp_gui_config_set_property (GObject *object,
case PROP_TOOLBOX_GROUPS:
gui_config->toolbox_groups = g_value_get_boolean (value);
break;
+ case PROP_TOOLBOX_GROUP_MENU_MODE:
+ gui_config->toolbox_group_menu_mode = g_value_get_enum (value);
+ break;
case PROP_THEME_PATH:
g_free (gui_config->theme_path);
gui_config->theme_path = g_value_dup_string (value);
@@ -877,6 +889,9 @@ gimp_gui_config_get_property (GObject *object,
case PROP_TOOLBOX_GROUPS:
g_value_set_boolean (value, gui_config->toolbox_groups);
break;
+ case PROP_TOOLBOX_GROUP_MENU_MODE:
+ g_value_set_enum (value, gui_config->toolbox_group_menu_mode);
+ break;
case PROP_THEME_PATH:
g_value_set_string (value, gui_config->theme_path);
break;
diff --git a/app/config/gimpguiconfig.h b/app/config/gimpguiconfig.h
index 5f15495981..b2a25ee50a 100644
--- a/app/config/gimpguiconfig.h
+++ b/app/config/gimpguiconfig.h
@@ -39,48 +39,49 @@ typedef struct _GimpGuiConfigClass GimpGuiConfigClass;
struct _GimpGuiConfig
{
- GimpDisplayConfig parent_instance;
-
- gboolean edit_non_visible;
- gboolean move_tool_changes_active;
- gint filter_tool_max_recent;
- gboolean filter_tool_use_last_settings;
- gboolean filter_tool_show_color_options;
- gboolean trust_dirty_flag;
- gboolean save_device_status;
- gboolean devices_share_tool;
- gboolean save_session_info;
- gboolean restore_session;
- gboolean restore_monitor;
- gboolean save_tool_options;
- gboolean compact_sliders;
- gboolean show_tooltips;
- gboolean tearoff_menus;
- gboolean can_change_accels;
- gboolean save_accels;
- gboolean restore_accels;
- gint last_opened_size;
- guint64 max_new_image_size;
- gboolean toolbox_color_area;
- gboolean toolbox_foo_area;
- gboolean toolbox_image_area;
- gboolean toolbox_wilber;
- gboolean toolbox_groups;
- gchar *theme_path;
- gchar *theme;
- gchar *icon_theme_path;
- gchar *icon_theme;
- GimpIconSize icon_size;
- gboolean use_help;
- gboolean show_help_button;
- gchar *help_locales;
- GimpHelpBrowserType help_browser;
- gboolean user_manual_online;
- gchar *user_manual_online_uri;
- gboolean search_show_unavailable;
- gint action_history_size;
- GimpWindowHint dock_window_hint;
- GimpHandedness cursor_handedness;
+ GimpDisplayConfig parent_instance;
+
+ gboolean edit_non_visible;
+ gboolean move_tool_changes_active;
+ gint filter_tool_max_recent;
+ gboolean filter_tool_use_last_settings;
+ gboolean filter_tool_show_color_options;
+ gboolean trust_dirty_flag;
+ gboolean save_device_status;
+ gboolean devices_share_tool;
+ gboolean save_session_info;
+ gboolean restore_session;
+ gboolean restore_monitor;
+ gboolean save_tool_options;
+ gboolean compact_sliders;
+ gboolean show_tooltips;
+ gboolean tearoff_menus;
+ gboolean can_change_accels;
+ gboolean save_accels;
+ gboolean restore_accels;
+ gint last_opened_size;
+ guint64 max_new_image_size;
+ gboolean toolbox_color_area;
+ gboolean toolbox_foo_area;
+ gboolean toolbox_image_area;
+ gboolean toolbox_wilber;
+ gboolean toolbox_groups;
+ GimpToolGroupMenuMode toolbox_group_menu_mode;
+ gchar *theme_path;
+ gchar *theme;
+ gchar *icon_theme_path;
+ gchar *icon_theme;
+ GimpIconSize icon_size;
+ gboolean use_help;
+ gboolean show_help_button;
+ gchar *help_locales;
+ GimpHelpBrowserType help_browser;
+ gboolean user_manual_online;
+ gchar *user_manual_online_uri;
+ gboolean search_show_unavailable;
+ gint action_history_size;
+ GimpWindowHint dock_window_hint;
+ GimpHandedness cursor_handedness;
/* experimental playground */
gboolean playground_npd_tool;
diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h
index 00646d60e4..bc8c85aba8 100644
--- a/app/config/gimprc-blurbs.h
+++ b/app/config/gimprc-blurbs.h
@@ -682,6 +682,9 @@ _("Show the current foreground and background colors in the toolbox.")
#define TOOLBOX_FOO_AREA_BLURB \
_("Show the currently selected brush, pattern and gradient in the toolbox.")
+#define TOOLBOX_GROUP_MENU_MODE_BLURB \
+_("Menu mode of grouped tools.")
+
#define TOOLBOX_GROUPS_BLURB \
_("Use a single toolbox button for grouped tools.")
diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c
index 3c3fda1eba..9b8d80f706 100644
--- a/app/dialogs/preferences-dialog.c
+++ b/app/dialogs/preferences-dialog.c
@@ -2160,10 +2160,33 @@ prefs_dialog_new (Gimp *gimp,
gtk_box_pack_start (GTK_BOX (vbox2), separator, FALSE, FALSE, 0);
gtk_widget_show (separator);
- prefs_check_button_add_with_icon (object, "toolbox-groups",
- _("Use tool _groups"),
- NULL,
- GTK_BOX (vbox2), size_group);
+ button = prefs_check_button_add_with_icon (object, "toolbox-groups",
+ _("Use tool _groups"),
+ NULL,
+ GTK_BOX (vbox2), size_group);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (NULL);
+ gtk_misc_set_padding (GTK_MISC (label), 2, 2);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ gtk_size_group_add_widget (size_group, label);
+
+ vbox3 = prefs_frame_new (NULL, GTK_CONTAINER (hbox), TRUE);
+ g_object_bind_property (button, "active",
+ vbox3, "sensitive",
+ G_BINDING_SYNC_CREATE);
+
+ table = prefs_table_new (1, GTK_CONTAINER (vbox3));
+
+ prefs_enum_combo_box_add (object, "toolbox-group-menu-mode", 0, 0,
+ _("_Menu mode:"),
+ GTK_TABLE (table), 0,
+ NULL);
g_clear_object (&size_group);
diff --git a/app/widgets/gimptoolbutton.c b/app/widgets/gimptoolbutton.c
index 33e99fdc8f..1ff4a9698a 100644
--- a/app/widgets/gimptoolbutton.c
+++ b/app/widgets/gimptoolbutton.c
@@ -59,7 +59,8 @@ enum
{
PROP_0,
PROP_TOOLBOX,
- PROP_TOOL_ITEM
+ PROP_TOOL_ITEM,
+ PROP_SHOW_MENU_ON_HOVER
};
@@ -67,14 +68,17 @@ struct _GimpToolButtonPrivate
{
GimpToolbox *toolbox;
GimpToolItem *tool_item;
+ gboolean show_menu_on_hover;
GtkWidget *palette;
GtkWidget *menu;
GHashTable *menu_items;
+ gint menu_idle_id;
gint menu_timeout_id;
gint menu_timeout_button;
guint32 menu_timeout_time;
+ gint menu_select_idle_id;
};
@@ -98,6 +102,12 @@ static gboolean gimp_tool_button_expose (GtkWidget *w
static void gimp_tool_button_toggled (GtkToggleToolButton *toggle_tool_button);
+static gboolean gimp_tool_button_enter_notify (GtkWidget *widget,
+ GdkEventCrossing *event,
+ GimpToolButton *tool_button);
+static gboolean gimp_tool_button_leave_notify (GtkWidget *widget,
+ GdkEventCrossing *event,
+ GimpToolButton *tool_button);
static gboolean gimp_tool_button_button_press (GtkWidget *widget,
GdkEventButton *event,
GimpToolButton *tool_button);
@@ -130,12 +140,16 @@ static void gimp_tool_button_icon_size_notify (GtkToolPalette *p
const GParamSpec *pspec,
GimpToolButton *tool_button);
+static gboolean gimp_tool_button_menu_enter_notify (GtkMenu *menu,
+ GdkEventCrossing *event,
+ GimpToolButton *tool_button);
static gboolean gimp_tool_button_menu_leave_notify (GtkMenu *menu,
GdkEventCrossing *event,
GimpToolButton *tool_button);
static void gimp_tool_button_menu_deactivate (GtkMenu *menu,
GimpToolButton *tool_button);
+static gboolean gimp_tool_button_menu_idle (GimpToolButton *tool_button);
static gboolean gimp_tool_button_menu_timeout (GimpToolButton *tool_button);
static void gimp_tool_button_update (GimpToolButton *tool_button);
@@ -195,6 +209,12 @@ gimp_tool_button_class_init (GimpToolButtonClass *klass)
NULL, NULL,
GIMP_TYPE_TOOL_ITEM,
GIMP_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_SHOW_MENU_ON_HOVER,
+ g_param_spec_boolean ("show-menu-on-hover",
+ NULL, NULL,
+ FALSE,
+ GIMP_PARAM_READWRITE));
}
static void
@@ -222,6 +242,14 @@ gimp_tool_button_constructed (GObject *object)
gtk_widget_add_events (gtk_bin_get_child (GTK_BIN (tool_button)),
GDK_SCROLL_MASK);
+ g_signal_connect (gtk_bin_get_child (GTK_BIN (tool_button)),
+ "enter-notify-event",
+ G_CALLBACK (gimp_tool_button_enter_notify),
+ tool_button);
+ g_signal_connect (gtk_bin_get_child (GTK_BIN (tool_button)),
+ "leave-notify-event",
+ G_CALLBACK (gimp_tool_button_leave_notify),
+ tool_button);
g_signal_connect (gtk_bin_get_child (GTK_BIN (tool_button)),
"button-press-event",
G_CALLBACK (gimp_tool_button_button_press),
@@ -271,6 +299,11 @@ gimp_tool_button_set_property (GObject *object,
gimp_tool_button_set_tool_item (tool_button, g_value_get_object (value));
break;
+ case PROP_SHOW_MENU_ON_HOVER:
+ gimp_tool_button_set_show_menu_on_hover (tool_button,
+ g_value_get_boolean (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -295,6 +328,10 @@ gimp_tool_button_get_property (GObject *object,
g_value_set_object (value, tool_button->priv->tool_item);
break;
+ case PROP_SHOW_MENU_ON_HOVER:
+ g_value_set_boolean (value, tool_button->priv->show_menu_on_hover);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -423,18 +460,73 @@ gimp_tool_button_toggled (GtkToggleToolButton *toggle_tool_button)
}
}
+static gboolean
+gimp_tool_button_enter_notify (GtkWidget *widget,
+ GdkEventCrossing *event,
+ GimpToolButton *tool_button)
+{
+ if (tool_button->priv->menu &&
+ tool_button->priv->show_menu_on_hover &&
+ ! gtk_widget_get_visible (tool_button->priv->menu) &&
+ event->mode == GDK_CROSSING_NORMAL &&
+ event->state == 0)
+ {
+ if (tool_button->priv->menu_idle_id)
+ {
+ g_source_remove (tool_button->priv->menu_idle_id);
+
+ tool_button->priv->menu_idle_id = 0;
+ }
+
+ gimp_tool_button_show_menu (tool_button, 0, event->time);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+gimp_tool_button_leave_notify (GtkWidget *widget,
+ GdkEventCrossing *event,
+ GimpToolButton *tool_button)
+{
+ if (tool_button->priv->menu &&
+ tool_button->priv->show_menu_on_hover &&
+ gtk_widget_get_visible (tool_button->priv->menu))
+ {
+ if (event->mode == GDK_CROSSING_NORMAL)
+ {
+ if (! tool_button->priv->menu_idle_id)
+ {
+ tool_button->priv->menu_idle_id = g_idle_add (
+ (GSourceFunc) gimp_tool_button_menu_idle,
+ tool_button);
+ }
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
static gboolean
gimp_tool_button_button_press (GtkWidget *widget,
GdkEventButton *event,
GimpToolButton *tool_button)
{
- if (GIMP_IS_TOOL_GROUP (tool_button->priv->tool_item))
+ if (tool_button->priv->menu)
{
- if (gdk_event_triggers_context_menu ((GdkEvent *) event) &&
- gimp_tool_button_show_menu (tool_button,
- event->button, event->time))
+ if (gtk_widget_get_visible (tool_button->priv->menu))
{
- return TRUE;
+ gtk_menu_shell_deactivate (GTK_MENU_SHELL (tool_button->priv->menu));
+ }
+ else if (gdk_event_triggers_context_menu ((GdkEvent *) event) ||
+ tool_button->priv->show_menu_on_hover)
+ {
+ return gimp_tool_button_show_menu (tool_button,
+ event->button, event->time);
}
else if (event->type == GDK_BUTTON_PRESS && event->button == 1 &&
! tool_button->priv->menu_timeout_id)
@@ -602,6 +694,25 @@ gimp_tool_button_icon_size_notify (GtkToolPalette *palette,
gimp_tool_button_reconstruct_menu (tool_button);
}
+static gboolean
+gimp_tool_button_menu_enter_notify (GtkMenu *menu,
+ GdkEventCrossing *event,
+ GimpToolButton *tool_button)
+{
+ if (tool_button->priv->show_menu_on_hover &&
+ event->mode == GDK_CROSSING_NORMAL)
+ {
+ if (tool_button->priv->menu_idle_id)
+ {
+ g_source_remove (tool_button->priv->menu_idle_id);
+
+ tool_button->priv->menu_idle_id = 0;
+ }
+ }
+
+ return FALSE;
+}
+
static gboolean
gimp_tool_button_menu_leave_notify (GtkMenu *menu,
GdkEventCrossing *event,
@@ -611,6 +722,14 @@ gimp_tool_button_menu_leave_notify (GtkMenu *menu,
gtk_widget_get_visible (tool_button->priv->menu))
{
gimp_tool_button_update_menu (tool_button);
+
+ if (tool_button->priv->show_menu_on_hover &&
+ ! tool_button->priv->menu_idle_id)
+ {
+ tool_button->priv->menu_idle_id = g_idle_add (
+ (GSourceFunc) gimp_tool_button_menu_idle,
+ tool_button);
+ }
}
return FALSE;
@@ -628,9 +747,26 @@ static void
gimp_tool_button_menu_deactivate (GtkMenu *menu,
GimpToolButton *tool_button)
{
+ if (tool_button->priv->menu_select_idle_id)
+ {
+ g_source_remove (tool_button->priv->menu_select_idle_id);
+
+ tool_button->priv->menu_select_idle_id = 0;
+ }
+
g_idle_add (gimp_tool_button_menu_deactivate_idle, NULL);
}
+static gboolean
+gimp_tool_button_menu_idle (GimpToolButton *tool_button)
+{
+ tool_button->priv->menu_idle_id = 0;
+
+ gtk_menu_shell_deactivate (GTK_MENU_SHELL (tool_button->priv->menu));
+
+ return G_SOURCE_REMOVE;
+}
+
static gboolean
gimp_tool_button_menu_timeout (GimpToolButton *tool_button)
{
@@ -664,14 +800,21 @@ gimp_tool_button_update (GimpToolButton *tool_button)
tool_info ? gimp_viewable_get_icon_name (GIMP_VIEWABLE (tool_info)) :
NULL);
- if (action)
+ if (! tool_button->priv->menu || ! tool_button->priv->show_menu_on_hover)
{
- gimp_widget_set_accel_help (GTK_WIDGET (tool_button), action);
- }
- else if (tool_info)
- {
- gimp_help_set_help_data (GTK_WIDGET (tool_button),
- tool_info->tooltip, tool_info->help_id);
+ if (action)
+ {
+ gimp_widget_set_accel_help (GTK_WIDGET (tool_button), action);
+ }
+ else if (tool_info)
+ {
+ gimp_help_set_help_data (GTK_WIDGET (tool_button),
+ tool_info->tooltip, tool_info->help_id);
+ }
+ else
+ {
+ gimp_help_set_help_data (GTK_WIDGET (tool_button), NULL, NULL);
+ }
}
else
{
@@ -823,6 +966,9 @@ gimp_tool_button_reconstruct_menu (GimpToolButton *tool_button)
gtk_menu_attach_to_widget (GTK_MENU (tool_button->priv->menu),
GTK_WIDGET (tool_button), NULL);
+ g_signal_connect (tool_button->priv->menu, "enter-notify-event",
+ G_CALLBACK (gimp_tool_button_menu_enter_notify),
+ tool_button);
g_signal_connect (tool_button->priv->menu, "leave-notify-event",
G_CALLBACK (gimp_tool_button_menu_leave_notify),
tool_button);
@@ -857,12 +1003,26 @@ gimp_tool_button_destroy_menu (GimpToolButton *tool_button)
g_clear_pointer (&tool_button->priv->menu_items, g_hash_table_unref);
+ if (tool_button->priv->menu_idle_id)
+ {
+ g_source_remove (tool_button->priv->menu_idle_id);
+
+ tool_button->priv->menu_idle_id = 0;
+ }
+
if (tool_button->priv->menu_timeout_id)
{
g_source_remove (tool_button->priv->menu_timeout_id);
tool_button->priv->menu_timeout_id = 0;
}
+
+ if (tool_button->priv->menu_select_idle_id)
+ {
+ g_source_remove (tool_button->priv->menu_select_idle_id);
+
+ tool_button->priv->menu_select_idle_id = 0;
+ }
}
}
@@ -877,6 +1037,16 @@ gimp_tool_button_show_menu_position_func (GtkMenu *menu,
menu, GTK_POS_RIGHT, x, y);
}
+static gboolean
+gimp_tool_button_show_menu_select_idle (GimpToolButton *tool_button)
+{
+ tool_button->priv->menu_select_idle_id = 0;
+
+ gimp_tool_button_update_menu (tool_button);
+
+ return G_SOURCE_REMOVE;
+}
+
static gboolean
gimp_tool_button_show_menu (GimpToolButton *tool_button,
gint button,
@@ -895,7 +1065,15 @@ gimp_tool_button_show_menu (GimpToolButton *tool_button,
tool_button,
button, activate_time);
- gimp_tool_button_update_menu (tool_button);
+ if (tool_button->priv->show_menu_on_hover)
+ gtk_grab_remove (tool_button->priv->menu);
+
+ if (! tool_button->priv->menu_select_idle_id)
+ {
+ tool_button->priv->menu_select_idle_id = g_idle_add (
+ (GSourceFunc) gimp_tool_button_show_menu_select_idle,
+ tool_button);
+ }
return TRUE;
}
@@ -1050,3 +1228,27 @@ gimp_tool_button_get_tool_info (GimpToolButton *tool_button)
return NULL;
}
+
+void
+gimp_tool_button_set_show_menu_on_hover (GimpToolButton *tool_button,
+ gboolean show_menu_on_hover)
+{
+ g_return_if_fail (GIMP_IS_TOOL_BUTTON (tool_button));
+
+ if (show_menu_on_hover != tool_button->priv->show_menu_on_hover)
+ {
+ tool_button->priv->show_menu_on_hover = show_menu_on_hover;
+
+ gimp_tool_button_update (tool_button);
+
+ g_object_notify (G_OBJECT (tool_button), "show-menu-on-hover");
+ }
+}
+
+gboolean
+gimp_tool_button_get_show_menu_on_hover (GimpToolButton *tool_button)
+{
+ g_return_val_if_fail (GIMP_IS_TOOL_BUTTON (tool_button), FALSE);
+
+ return tool_button->priv->show_menu_on_hover;
+}
diff --git a/app/widgets/gimptoolbutton.h b/app/widgets/gimptoolbutton.h
index b53d48a27a..ae010e8c21 100644
--- a/app/widgets/gimptoolbutton.h
+++ b/app/widgets/gimptoolbutton.h
@@ -46,18 +46,22 @@ struct _GimpToolButtonClass
};
-GType gimp_tool_button_get_type (void) G_GNUC_CONST;
+GType gimp_tool_button_get_type (void) G_GNUC_CONST;
-GtkToolItem * gimp_tool_button_new (GimpToolbox *toolbox,
- GimpToolItem *tool_item);
+GtkToolItem * gimp_tool_button_new (GimpToolbox *toolbox,
+ GimpToolItem *tool_item);
-GimpToolbox * gimp_tool_button_get_toolbox (GimpToolButton *tool_button);
+GimpToolbox * gimp_tool_button_get_toolbox (GimpToolButton *tool_button);
-void gimp_tool_button_set_tool_item (GimpToolButton *tool_button,
- GimpToolItem *tool_item);
-GimpToolItem * gimp_tool_button_get_tool_item (GimpToolButton *tool_button);
+void gimp_tool_button_set_tool_item (GimpToolButton *tool_button,
+ GimpToolItem *tool_item);
+GimpToolItem * gimp_tool_button_get_tool_item (GimpToolButton *tool_button);
-GimpToolInfo * gimp_tool_button_get_tool_info (GimpToolButton *tool_button);
+GimpToolInfo * gimp_tool_button_get_tool_info (GimpToolButton *tool_button);
+
+void gimp_tool_button_set_show_menu_on_hover (GimpToolButton *tool_button,
+ gboolean show_menu_on_hover);
+gboolean gimp_tool_button_get_show_menu_on_hover (GimpToolButton *tool_button);
#endif /* __GIMP_TOOL_BUTTON_H__ */
diff --git a/app/widgets/gimptoolpalette.c b/app/widgets/gimptoolpalette.c
index 1f96d6d7a3..b5a27a6552 100644
--- a/app/widgets/gimptoolpalette.c
+++ b/app/widgets/gimptoolpalette.c
@@ -64,30 +64,36 @@ struct _GimpToolPalettePrivate
#define GET_PRIVATE(p) ((GimpToolPalettePrivate *) gimp_tool_palette_get_instance_private ((GimpToolPalette
*) (p)))
-static void gimp_tool_palette_finalize (GObject *object);
-
-static void gimp_tool_palette_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-static void gimp_tool_palette_style_set (GtkWidget *widget,
- GtkStyle *previous_style);
-
-static void gimp_tool_palette_tool_add (GimpContainer *container,
- GimpToolItem *tool_item,
- GimpToolPalette *palette);
-static void gimp_tool_palette_tool_remove (GimpContainer *container,
- GimpToolItem *tool_item,
- GimpToolPalette *palette);
-static void gimp_tool_palette_tool_reorder (GimpContainer *container,
- GimpToolItem *tool_item,
- gint index,
- GimpToolPalette *palette);
-
-static void gimp_tool_palette_config_size_changed (GimpGuiConfig *config,
- GimpToolPalette *palette);
-
-static void gimp_tool_palette_add_button (GimpToolPalette *palette,
- GimpToolItem *tool_item,
- gint index);
+static void gimp_tool_palette_finalize (GObject *object);
+
+static void gimp_tool_palette_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static void gimp_tool_palette_style_set (GtkWidget *widget,
+ GtkStyle *previous_style);
+
+static void gimp_tool_palette_tool_add (GimpContainer *container,
+ GimpToolItem *tool_item,
+ GimpToolPalette *palette);
+static void gimp_tool_palette_tool_remove (GimpContainer *container,
+ GimpToolItem *tool_item,
+ GimpToolPalette *palette);
+static void gimp_tool_palette_tool_reorder (GimpContainer *container,
+ GimpToolItem *tool_item,
+ gint index,
+ GimpToolPalette *palette);
+
+static void gimp_tool_palette_config_menu_mode_notify (GimpGuiConfig *config,
+ const GParamSpec *pspec,
+ GimpToolPalette *palette);
+static void gimp_tool_palette_config_size_changed (GimpGuiConfig *config,
+ GimpToolPalette *palette);
+
+static void gimp_tool_palette_add_button (GimpToolPalette *palette,
+ GimpToolItem *tool_item,
+ gint index);
+
+static gboolean gimp_tool_palette_get_show_menu_on_hover (GimpToolPalette *palette);
+static void gimp_tool_palette_update_show_menu_on_hover (GimpToolPalette *palette);
G_DEFINE_TYPE_WITH_PRIVATE (GimpToolPalette, gimp_tool_palette,
@@ -144,9 +150,16 @@ gimp_tool_palette_finalize (GObject *object)
GimpContext *context = gimp_toolbox_get_context (private->toolbox);
if (context)
- g_signal_handlers_disconnect_by_func (context->gimp->config,
- G_CALLBACK (gimp_tool_palette_config_size_changed),
- object);
+ {
+ g_signal_handlers_disconnect_by_func (
+ context->gimp->config,
+ G_CALLBACK (gimp_tool_palette_config_menu_mode_notify),
+ object);
+ g_signal_handlers_disconnect_by_func (
+ context->gimp->config,
+ G_CALLBACK (gimp_tool_palette_config_size_changed),
+ object);
+ }
}
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -156,13 +169,14 @@ static void
gimp_tool_palette_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
+ GimpToolPalette *palette = GIMP_TOOL_PALETTE (widget);
GimpToolPalettePrivate *private = GET_PRIVATE (widget);
gint button_width;
gint button_height;
GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
- if (gimp_tool_palette_get_button_size (GIMP_TOOL_PALETTE (widget),
+ if (gimp_tool_palette_get_button_size (palette,
&button_width, &button_height))
{
GimpToolItem *tool_item;
@@ -195,6 +209,8 @@ gimp_tool_palette_size_allocate (GtkWidget *widget,
gtk_widget_set_size_request (widget, -1,
tool_rows * button_height);
+
+ gimp_tool_palette_update_show_menu_on_hover (palette);
}
}
}
@@ -260,10 +276,17 @@ gimp_tool_palette_set_toolbox (GimpToolPalette *palette,
if (private->toolbox)
{
context = gimp_toolbox_get_context (private->toolbox);
- g_signal_handlers_disconnect_by_func (GIMP_GUI_CONFIG (context->gimp->config),
- G_CALLBACK (gimp_tool_palette_config_size_changed),
- palette);
+
+ g_signal_handlers_disconnect_by_func (
+ GIMP_GUI_CONFIG (context->gimp->config),
+ G_CALLBACK (gimp_tool_palette_config_menu_mode_notify),
+ palette);
+ g_signal_handlers_disconnect_by_func (
+ GIMP_GUI_CONFIG (context->gimp->config),
+ G_CALLBACK (gimp_tool_palette_config_size_changed),
+ palette);
}
+
private->toolbox = toolbox;
context = gimp_toolbox_get_context (toolbox);
@@ -293,6 +316,12 @@ gimp_tool_palette_set_toolbox (GimpToolPalette *palette,
G_CALLBACK (gimp_tool_palette_tool_reorder),
palette, 0);
+ g_signal_connect (GIMP_GUI_CONFIG (context->gimp->config),
+ "notify::toolbox-group-menu-mode",
+ G_CALLBACK (gimp_tool_palette_config_menu_mode_notify),
+ palette);
+ gimp_tool_palette_update_show_menu_on_hover (palette);
+
/* Update the toolbox icon size on config change. */
g_signal_connect (GIMP_GUI_CONFIG (context->gimp->config),
"size-changed",
@@ -385,6 +414,14 @@ gimp_tool_palette_tool_reorder (GimpContainer *container,
}
}
+static void
+gimp_tool_palette_config_menu_mode_notify (GimpGuiConfig *config,
+ const GParamSpec *pspec,
+ GimpToolPalette *palette)
+{
+ gimp_tool_palette_update_show_menu_on_hover (palette);
+}
+
static void
gimp_tool_palette_config_size_changed (GimpGuiConfig *config,
GimpToolPalette *palette)
@@ -433,6 +470,9 @@ gimp_tool_palette_add_button (GimpToolPalette *palette,
tool_button = gimp_tool_button_new (private->toolbox, tool_item);
gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (private->group),
tool_button, index);
+ gimp_tool_button_set_show_menu_on_hover (
+ GIMP_TOOL_BUTTON (tool_button),
+ gimp_tool_palette_get_show_menu_on_hover (palette));
gtk_widget_show (GTK_WIDGET (tool_button));
g_object_bind_property (tool_item, "shown",
@@ -452,3 +492,51 @@ gimp_tool_palette_add_button (GimpToolPalette *palette,
g_hash_table_insert (private->buttons, tool_item, tool_button);
}
+
+static gboolean
+gimp_tool_palette_get_show_menu_on_hover (GimpToolPalette *palette)
+{
+ GimpToolPalettePrivate *private = GET_PRIVATE (palette);
+
+ if (private->toolbox)
+ {
+ GimpContext *context = gimp_toolbox_get_context (private->toolbox);
+
+ if (context)
+ {
+ GimpGuiConfig *config = GIMP_GUI_CONFIG (context->gimp->config);
+
+ switch (config->toolbox_group_menu_mode)
+ {
+ case GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_CLICK:
+ return FALSE;
+
+ case GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER:
+ return TRUE;
+
+ case GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER_SINGLE_COLUMN:
+ return private->tool_columns == 1;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+gimp_tool_palette_update_show_menu_on_hover (GimpToolPalette *palette)
+{
+ GimpToolPalettePrivate *private = GET_PRIVATE (palette);
+ GHashTableIter iter;
+ GimpToolButton *tool_button;
+ gboolean show_menu_on_hover;
+
+ show_menu_on_hover = gimp_tool_palette_get_show_menu_on_hover (palette);
+
+ g_hash_table_iter_init (&iter, private->buttons);
+
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &tool_button))
+ {
+ gimp_tool_button_set_show_menu_on_hover (tool_button, show_menu_on_hover);
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]