app: show a menu path to advertize how to "Rasterize" and blink the selected layer.
This is the result of a UX session with Aryeom. Just showing a message forbidding editing of non-rasterized text/link/vector layers is problematic, because it doesn't help people understand how to unblock their situation (if they really want to just edit directly the layer). Additionally we are now blinking the layer. A possible alternative could have been to pop a dialog up, with the same message but also with a quick-action button to allow rasterize in a click (similar to how we are popping a dialog up to revert the rasterization when clicking on a text layer with the text tool or a vector layer with the path tool). The problem is that even though the need to edit directly a non-raster layer arises from time to time, most of the time, when you use such layers, you don't intend to edit these (unlike editing text/path with matching tools, you more often wanted to edit the relevant data). Therefore it is more often than not just a mistake when you try to paint directly on such a layer. I.e. that very often, you were intending to paint on another layer, or add a new layer above your non-raster layer. Therefore a dialog popping up every time you made such a mistake would be annoying and workflow-breaking. A simple error message and some blinking leave for a fluid process.
This commit is contained in:
parent
50fd97b28b
commit
0f65d3923e
5 changed files with 118 additions and 59 deletions
|
|
@ -754,23 +754,29 @@ gimp_tool_button_press (GimpTool *tool,
|
|||
! (state & gimp_get_extend_selection_mask ()));
|
||||
if (! GIMP_IS_SOURCE_TOOL (tool) || ! constrain_only)
|
||||
{
|
||||
/* TRANSLATORS: this is a menu path. Make sure you use
|
||||
* the same translations you used for the "Rasterize"
|
||||
* action under the "Layer" menu.
|
||||
*/
|
||||
gchar *menu_path = _("Layer > Rasterize");
|
||||
|
||||
if (gimp_item_is_text_layer (GIMP_ITEM (drawable)))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("Text layers must be rasterized "
|
||||
"before they can be painted on."));
|
||||
/* TRANSLATORS: the string between parentheses will be a menu path. */
|
||||
gimp_tool_message (tool, display, _("Text layers must be rasterized (%s)."), menu_path);
|
||||
gimp_tools_blink_item (display->gimp, GIMP_ITEM (drawable));
|
||||
}
|
||||
else if (gimp_item_is_link_layer (GIMP_ITEM (drawable)))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("Link layers must be rasterized "
|
||||
"before they can be painted on."));
|
||||
/* TRANSLATORS: the string between parentheses will be a menu path. */
|
||||
gimp_tool_message (tool, display, _("Link layers must be rasterized (%s)."), menu_path);
|
||||
gimp_tools_blink_item (display->gimp, GIMP_ITEM (drawable));
|
||||
}
|
||||
else if (gimp_item_is_vector_layer (GIMP_ITEM (drawable)))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("Vector layers must be rasterized "
|
||||
"before they can be painted on."));
|
||||
/* TRANSLATORS: the string between parentheses will be a menu path. */
|
||||
gimp_tool_message (tool, display, _("Vector layers must be rasterized (%s)."), menu_path);
|
||||
gimp_tools_blink_item (display->gimp, GIMP_ITEM (drawable));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@
|
|||
#include "gimptools-utils.h"
|
||||
|
||||
|
||||
static GimpItemTreeView * gimp_tools_get_tree_view_for (Gimp *gimp,
|
||||
GimpItem *item);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
|
|
@ -46,39 +49,28 @@ void
|
|||
gimp_tools_blink_lock_box (Gimp *gimp,
|
||||
GimpItem *item)
|
||||
{
|
||||
GtkWidget *dockable;
|
||||
GimpItemTreeView *view;
|
||||
GdkMonitor *monitor;
|
||||
const gchar *identifier;
|
||||
|
||||
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
||||
g_return_if_fail (GIMP_IS_ITEM (item));
|
||||
|
||||
if (GIMP_IS_LAYER (item))
|
||||
identifier = "gimp-layer-list";
|
||||
else if (GIMP_IS_CHANNEL (item))
|
||||
identifier = "gimp-channel-list";
|
||||
else if (GIMP_IS_PATH (item))
|
||||
identifier = "gimp-path-list";
|
||||
else
|
||||
return;
|
||||
|
||||
monitor = gimp_get_monitor_at_pointer ();
|
||||
|
||||
dockable = gimp_window_strategy_show_dockable_dialog (
|
||||
GIMP_WINDOW_STRATEGY (gimp_get_window_strategy (gimp)),
|
||||
gimp,
|
||||
gimp_dialog_factory_get_singleton (),
|
||||
monitor,
|
||||
identifier);
|
||||
|
||||
if (! dockable)
|
||||
return;
|
||||
|
||||
view = GIMP_ITEM_TREE_VIEW (gtk_bin_get_child (GTK_BIN (dockable)));
|
||||
view = gimp_tools_get_tree_view_for (gimp, item);
|
||||
gimp_item_tree_view_blink_lock (view, item);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_tools_blink_item (Gimp *gimp,
|
||||
GimpItem *item)
|
||||
{
|
||||
GimpItemTreeView *view;
|
||||
|
||||
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
||||
g_return_if_fail (GIMP_IS_ITEM (item));
|
||||
|
||||
view = gimp_tools_get_tree_view_for (gimp, item);
|
||||
gimp_item_tree_view_blink_item (view, item);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_tools_show_tool_options (Gimp *gimp)
|
||||
{
|
||||
|
|
@ -93,3 +85,42 @@ gimp_tools_show_tool_options (Gimp *gimp)
|
|||
gimp_dialog_factory_get_singleton (),
|
||||
monitor, "gimp-tool-options");
|
||||
}
|
||||
|
||||
|
||||
/* Private functions */
|
||||
|
||||
static GimpItemTreeView *
|
||||
gimp_tools_get_tree_view_for (Gimp *gimp,
|
||||
GimpItem *item)
|
||||
{
|
||||
GtkWidget *dockable;
|
||||
GimpItemTreeView *view;
|
||||
GdkMonitor *monitor;
|
||||
const gchar *identifier;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
|
||||
g_return_val_if_fail (GIMP_IS_ITEM (item), NULL);
|
||||
|
||||
if (GIMP_IS_LAYER (item))
|
||||
identifier = "gimp-layer-list";
|
||||
else if (GIMP_IS_CHANNEL (item))
|
||||
identifier = "gimp-channel-list";
|
||||
else if (GIMP_IS_PATH (item))
|
||||
identifier = "gimp-path-list";
|
||||
else
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
monitor = gimp_get_monitor_at_pointer ();
|
||||
dockable = gimp_window_strategy_show_dockable_dialog (GIMP_WINDOW_STRATEGY (gimp_get_window_strategy (gimp)),
|
||||
gimp,
|
||||
gimp_dialog_factory_get_singleton (),
|
||||
monitor,
|
||||
identifier);
|
||||
|
||||
if (! dockable)
|
||||
return NULL;
|
||||
|
||||
view = GIMP_ITEM_TREE_VIEW (gtk_bin_get_child (GTK_BIN (dockable)));
|
||||
|
||||
return view;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,5 +20,7 @@
|
|||
|
||||
void gimp_tools_blink_lock_box (Gimp *gimp,
|
||||
GimpItem *item);
|
||||
void gimp_tools_blink_item (Gimp *gimp,
|
||||
GimpItem *item);
|
||||
|
||||
void gimp_tools_show_tool_options (Gimp *gimp);
|
||||
|
|
|
|||
|
|
@ -262,6 +262,9 @@ static gboolean gimp_item_tree_view_search_clicked (GtkWidget
|
|||
static gboolean gimp_item_tree_view_move_cursor (GimpItemTreeView *tree_view,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers);
|
||||
static void gimp_item_tree_view_blink_item_column (GimpItemTreeView *view,
|
||||
GimpItem *item,
|
||||
gint column);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GimpItemTreeView, gimp_item_tree_view,
|
||||
|
|
@ -1014,32 +1017,14 @@ void
|
|||
gimp_item_tree_view_blink_lock (GimpItemTreeView *view,
|
||||
GimpItem *item)
|
||||
{
|
||||
GtkTreeIter *iter;
|
||||
GtkTreePath *path;
|
||||
GdkRectangle rect;
|
||||
gimp_item_tree_view_blink_item_column (view, item, 1);
|
||||
}
|
||||
|
||||
g_return_if_fail (GIMP_IS_ITEM_TREE_VIEW (view));
|
||||
g_return_if_fail (GIMP_IS_ITEM (item));
|
||||
|
||||
/* Find the item in the tree view. */
|
||||
iter = _gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view),
|
||||
GIMP_VIEWABLE (item));
|
||||
path = gtk_tree_model_get_path (GIMP_CONTAINER_TREE_VIEW (view)->model, iter);
|
||||
|
||||
/* Scroll dockable to make sure the cell is showing. */
|
||||
gtk_tree_view_scroll_to_cell (GIMP_CONTAINER_TREE_VIEW (view)->view, path,
|
||||
gtk_tree_view_get_column (GIMP_CONTAINER_TREE_VIEW (view)->view, 1),
|
||||
FALSE, 0.0, 0.0);
|
||||
|
||||
/* Now blink the lock cell of the specified item. */
|
||||
gtk_tree_view_get_cell_area (GIMP_CONTAINER_TREE_VIEW (view)->view, path,
|
||||
gtk_tree_view_get_column (GIMP_CONTAINER_TREE_VIEW (view)->view, 1),
|
||||
&rect);
|
||||
gtk_tree_view_convert_bin_window_to_widget_coords (GIMP_CONTAINER_TREE_VIEW (view)->view,
|
||||
rect.x, rect.y, &rect.x, &rect.y);
|
||||
gimp_widget_blink_rect (GTK_WIDGET (GIMP_CONTAINER_TREE_VIEW (view)->view), &rect);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
void
|
||||
gimp_item_tree_view_blink_item (GimpItemTreeView *view,
|
||||
GimpItem *item)
|
||||
{
|
||||
gimp_item_tree_view_blink_item_column (view, item, 3);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
|
|
@ -2444,3 +2429,36 @@ gimp_item_tree_view_move_cursor (GimpItemTreeView *view,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_tree_view_blink_item_column (GimpItemTreeView *view,
|
||||
GimpItem *item,
|
||||
gint column)
|
||||
{
|
||||
GtkTreeIter *iter;
|
||||
GtkTreePath *path;
|
||||
GdkRectangle rect;
|
||||
|
||||
g_return_if_fail (GIMP_IS_ITEM_TREE_VIEW (view));
|
||||
g_return_if_fail (GIMP_IS_ITEM (item));
|
||||
|
||||
/* Find the item in the tree view. */
|
||||
iter = _gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view),
|
||||
GIMP_VIEWABLE (item));
|
||||
path = gtk_tree_model_get_path (GIMP_CONTAINER_TREE_VIEW (view)->model, iter);
|
||||
|
||||
/* Scroll dockable to make sure the cell is showing. */
|
||||
gtk_tree_view_scroll_to_cell (GIMP_CONTAINER_TREE_VIEW (view)->view, path,
|
||||
gtk_tree_view_get_column (GIMP_CONTAINER_TREE_VIEW (view)->view, column),
|
||||
FALSE, 0.0, 0.0);
|
||||
|
||||
/* Now blink the specified column. */
|
||||
gtk_tree_view_get_cell_area (GIMP_CONTAINER_TREE_VIEW (view)->view, path,
|
||||
gtk_tree_view_get_column (GIMP_CONTAINER_TREE_VIEW (view)->view, column),
|
||||
&rect);
|
||||
gtk_tree_view_convert_bin_window_to_widget_coords (GIMP_CONTAINER_TREE_VIEW (view)->view,
|
||||
rect.x, rect.y, &rect.x, &rect.y);
|
||||
gimp_widget_blink_rect (GTK_WIDGET (GIMP_CONTAINER_TREE_VIEW (view)->view), &rect);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,6 +139,8 @@ void gimp_item_tree_view_add_lock (GimpItemTreeView *view,
|
|||
const gchar *help_id);
|
||||
void gimp_item_tree_view_blink_lock (GimpItemTreeView *view,
|
||||
GimpItem *item);
|
||||
void gimp_item_tree_view_blink_item (GimpItemTreeView *view,
|
||||
GimpItem *item);
|
||||
|
||||
GtkWidget * gimp_item_tree_view_get_new_button (GimpItemTreeView *view);
|
||||
GtkWidget * gimp_item_tree_view_get_delete_button (GimpItemTreeView *view);
|
||||
|
|
|
|||
Loading…
Reference in a new issue