Bug 373060 - allow to easily switch to last used tool.

New action "Last Tool" ("context-tools-swap"), defaulted to <shift>X.
Thanks to Damien de Lemeny for the original patch and Alexander Hämmerle
for the test case in test-ui.c.
This commit is contained in:
Jehan 2013-09-07 17:13:53 +12:00
parent 5085b2c6f4
commit eeb419a363
7 changed files with 125 additions and 14 deletions

View file

@ -54,7 +54,13 @@ static const GimpActionEntry context_actions[] =
NC_("context-action", "S_wap Colors"), NULL, { "X", NULL },
NC_("context-action", "Exchange foreground and background colors"),
context_colors_swap_cmd_callback,
GIMP_HELP_TOOLBOX_SWAP_COLORS }
GIMP_HELP_TOOLBOX_SWAP_COLORS },
{ "context-tools-swap", NULL,
NC_("context-action", "_Last Tool"), NULL, { "<shift>X", NULL },
NC_("context-action", "Switch back to the last activated tool"),
context_tools_swap_cmd_callback,
GIMP_HELP_TOOLBOX_SWAP_TOOLS }
};
static GimpEnumActionEntry context_palette_foreground_actions[] =

View file

@ -104,6 +104,17 @@ context_colors_swap_cmd_callback (GimpAction *action,
gimp_context_swap_colors (context);
}
void
context_tools_swap_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpContext *context;
return_if_no_context (context, data);
gimp_context_swap_tools (context);
}
#define SELECT_COLOR_CMD_CALLBACK(name, fgbg, use_colormap, use_palette) \
void \
context_##name##_##fgbg##ground_cmd_callback (GimpAction *action, \

View file

@ -24,6 +24,9 @@ void context_colors_default_cmd_callback (GimpAction *action,
void context_colors_swap_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void context_tools_swap_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void context_palette_foreground_cmd_callback (GimpAction *action,
GVariant *value,

View file

@ -787,6 +787,7 @@ gimp_context_init (GimpContext *context)
context->tool_info = NULL;
context->tool_name = NULL;
context->last_tool_info = NULL;
context->paint_info = NULL;
context->paint_name = NULL;
@ -998,6 +999,7 @@ gimp_context_dispose (GObject *object)
g_clear_object (&context->buffer);
g_clear_object (&context->imagefile);
g_clear_object (&context->template);
g_clear_object (&context->last_tool_info);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@ -2154,6 +2156,14 @@ gimp_context_get_tool (GimpContext *context)
return context->tool_info;
}
GimpToolInfo *
gimp_context_get_last_tool (GimpContext *context)
{
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
return context->last_tool_info;
}
void
gimp_context_set_tool (GimpContext *context,
GimpToolInfo *tool_info)
@ -2208,15 +2218,19 @@ gimp_context_tool_removed (GimpContainer *container,
GimpToolInfo *tool_info,
GimpContext *context)
{
if (tool_info == context->tool_info)
if (tool_info == context->tool_info || tool_info == context->last_tool_info)
{
g_signal_handlers_disconnect_by_func (context->tool_info,
gimp_context_tool_dirty,
context);
g_clear_object (&context->tool_info);
/* If the removed tool is the current one, switch back to the last tool.
* This is more user-friendly than just setting to NULL. */
if (tool_info == context->tool_info)
{
if (context->last_tool_info != NULL)
gimp_context_swap_tools (context);
else
gimp_context_set_tool (context, NULL);
}
if (! gimp_container_frozen (container))
gimp_context_tool_list_thaw (container, context);
context->last_tool_info = NULL;
}
}
@ -2234,11 +2248,11 @@ gimp_context_real_set_tool (GimpContext *context,
}
if (context->tool_info)
g_signal_handlers_disconnect_by_func (context->tool_info,
gimp_context_tool_dirty,
context);
g_set_object (&context->tool_info, tool_info);
{
g_signal_handlers_disconnect_by_func (context->tool_info,
G_CALLBACK (gimp_context_tool_dirty),
context);
}
if (tool_info)
{
@ -2254,10 +2268,27 @@ gimp_context_real_set_tool (GimpContext *context,
gimp_context_real_set_paint_info (context, tool_info->paint_info);
}
/* Instead of unref-ing the current tool, save it as last_tool_info
* for possible use of gimp_context_swap_tools.
*/
if (context->last_tool_info)
g_object_unref (context->last_tool_info);
context->last_tool_info = context->tool_info;
/* Now we set the new tool. */
context->tool_info = tool_info ? g_object_ref (tool_info) : NULL;
g_object_notify (G_OBJECT (context), "tool");
gimp_context_tool_changed (context);
}
void
gimp_context_swap_tools (GimpContext *context)
{
if (context->last_tool_info)
gimp_context_set_tool (context, context->last_tool_info);
}
/*****************************************************************************/
/* paint info **************************************************************/

View file

@ -58,6 +58,7 @@ struct _GimpContext
GimpToolInfo *tool_info;
gchar *tool_name;
GimpToolInfo *last_tool_info;
GimpPaintInfo *paint_info;
gchar *paint_name;
@ -237,10 +238,12 @@ void gimp_context_display_changed (GimpContext *context);
/* tool */
GimpToolInfo * gimp_context_get_tool (GimpContext *context);
GimpToolInfo * gimp_context_get_last_tool (GimpContext *context);
void gimp_context_set_tool (GimpContext *context,
GimpToolInfo *tool_info);
void gimp_context_tool_changed (GimpContext *context);
void gimp_context_swap_tools (GimpContext *context);
void gimp_context_tool_changed (GimpContext *context);
/* paint info */
GimpPaintInfo * gimp_context_get_paint_info (GimpContext *context);

View file

@ -435,6 +435,61 @@ paintbrush_is_standard_tool (gconstpointer data)
"gimp-tool-paintbrush");
}
/**
* swap_tools:
* @data:
*
* Testing switchback to last used tool <shift>X. Tools are taken from gimp->tool_info_list.
* Not all possible combinations of available tools are tested though.
**/
static void
swap_tools (gconstpointer data)
{
Gimp *gimp = GIMP (data);
GimpContext *user_context = gimp_get_user_context (gimp);
GimpToolInfo *first_tool_info = NULL;
GimpToolInfo *second_tool_info = NULL;
GList *tool_info_list = NULL;
guint i, j = 0;
/* Arbitrarily testing only the first 10 available tools from gimp->tool_info_list
* because there are tools which aren't settable within the reduced framework of
* gimp_init_for_gui_testing's environment!
*/
guint tool_info_list_length = 10; /* Value should actually be g_list_length (tool_info_list) */
tool_info_list = gimp_get_tool_info_iter (gimp);
for (i = 0; i < tool_info_list_length; i++)
{
/* Getting the first reference tool */
first_tool_info = g_list_nth_data (tool_info_list, i);
for (j = 0; j < tool_info_list_length; j++)
{
/* Now get the second tool. Set both one after another and loop the second tool through
* all available tools to test switchback.
*/
second_tool_info = g_list_nth_data (tool_info_list, j);
if (first_tool_info != second_tool_info)
{
gimp_context_set_tool (user_context, first_tool_info);
g_assert (gimp_context_get_tool (user_context) == first_tool_info);
gimp_context_set_tool (user_context, second_tool_info);
g_assert (gimp_context_get_tool (user_context) == second_tool_info);
g_assert (gimp_context_get_last_tool (user_context) == first_tool_info);
gimp_context_swap_tools (user_context);
g_assert (gimp_context_get_tool (user_context) == first_tool_info);
g_assert (gimp_context_get_last_tool (user_context) == second_tool_info);
}
}
}
}
/**
* gimp_ui_synthesize_delete_event:
* @widget:
@ -553,6 +608,7 @@ int main(int argc, char **argv)
ADD_TEST (switch_back_to_multi_window_mode);
ADD_TEST (close_image);
ADD_TEST (window_roles);
ADD_TEST (swap_tools);
/* Run the tests and return status */
g_application_run (gimp->app, 0, NULL);

View file

@ -511,6 +511,7 @@
#define GIMP_HELP_TOOLBOX_INDICATOR_AREA "gimp-toolbox-indicator-area"
#define GIMP_HELP_TOOLBOX_DEFAULT_COLORS "gimp-toolbox-default-colors"
#define GIMP_HELP_TOOLBOX_SWAP_COLORS "gimp-toolbox-swap-colors"
#define GIMP_HELP_TOOLBOX_SWAP_TOOLS "gimp-toolbox-swap-tools"
#define GIMP_HELP_BRUSH_DIALOG "gimp-brush-dialog"
#define GIMP_HELP_BRUSH_EDIT "gimp-brush-edit"