2006-12-09 21:33:38 +00:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
2001-03-11 17:24:47 +00:00
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
2003-03-16 11:14:29 +00:00
|
|
|
* gimplayertreeview.c
|
2009-08-03 19:21:51 +02:00
|
|
|
* Copyright (C) 2001-2009 Michael Natterer <mitch@gimp.org>
|
2001-04-22 00:38:56 +00:00
|
|
|
*
|
2009-01-17 22:28:01 +00:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
2001-03-11 17:24:47 +00:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
2009-01-17 22:28:01 +00:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2001-03-11 17:24:47 +00:00
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2018-07-11 23:27:07 +02:00
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2001-03-11 17:24:47 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2004-12-24 19:11:30 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
2008-10-09 20:24:04 +00:00
|
|
|
#include <gegl.h>
|
2001-03-11 17:24:47 +00:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
2005-01-15 17:57:32 +00:00
|
|
|
#include "libgimpbase/gimpbase.h"
|
2001-03-11 17:24:47 +00:00
|
|
|
#include "libgimpmath/gimpmath.h"
|
|
|
|
#include "libgimpwidgets/gimpwidgets.h"
|
|
|
|
|
2001-05-08 03:48:54 +00:00
|
|
|
#include "widgets-types.h"
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2020-12-14 12:10:21 +01:00
|
|
|
#if 0
|
|
|
|
/* For mask features in gimp_layer_tree_view_layer_clicked() */
|
|
|
|
#include "config/gimpdialogconfig.h"
|
|
|
|
#endif
|
|
|
|
|
2006-10-16 13:46:28 +00:00
|
|
|
#include "core/gimp.h"
|
2018-03-07 09:31:02 -05:00
|
|
|
#include "core/gimpchannel.h"
|
2001-05-09 02:32:03 +00:00
|
|
|
#include "core/gimpcontainer.h"
|
Issue #7023: icon size selection on GIMP 2.99.
This kinda reverts commit 6aebd30de142286c41e6cd90abedc4082a13fcea ("app: remove
icon sizing preferences"), except that the code base is different enough since
this old commit was mainly for GIMP 2.10.x.
In any case, after initially thinking that GTK+3 handling for high density
display would be enough, we finally decide that adding back a Preferences-wide
setting for overriding the theme-set icon size is a good idea (additionally to
GTK+3 automatic support).
The base idea for removing the feature was that GTK+3 has high density display
support, through the "scale factor". Typically a high density display will
normally be set as using a ×2 scale factor so all icons will be double size.
Unfortunately it turns out it's not enough.
For instance, on very small screen estate, even with a scale factor of 1, if the
theme sets 24px toolbox icons, it may still take too much space.
Oppositely on huge screens, even with ×2 factor scale detected by the OS, the
icons may still feel too small (this is possibly what happens with #7023).
Furthermore there is also a matter of taste. Some people like small icons even
when they have the space. Others may want bigger icons, easy to click on.
Finally you can like a theme for its color scheme for instance, but it may not
have the icon size you want. Right now, we'd need to duplicate every theme in
small or bigger size. Instead of doing so, let's just have this global setting
overriding the theme rules.
Comparison with the 2.10 implementation:
- We still provide 4 sizes: small, medium, large and huge.
- We don't have the "Guess ideal size" setting anymore. Instead this is now a
mix of the GTK+3 scale factor logic and the theme-set or custom size. I.e.
that on a high density display with ×2 scale factor, we could have toolbox
icons up to 96 pixels (48×2)!
- We now try to have less custom code in widgets as we append the CSS rules to
the theme (similar to what we were already doing for dark theme or icon
variants). What happens in widget code is mostly to connect to changes in
themes and redraw the widgets which need to be.
- The custom size will now affect: toolbox icons, the FG/BG editor widget (in
both the toolbox and the color dockable), dockable tab icons, the main
dockable buttons, eye and lock header icons in item tree views, eye and lock
cell icons in the item lists.
There are still a bunch of areas where it is not taken into account, such as
plug-ins, and various dialogs, but even in custom-made interface in dockables.
Ultimately it might be interesting to have a way to sync more buttons and
widgets to a global size settings.
Lastly, I fixed a bunch of existing bugs where we were updating icon sizes with
gtk_image_set_from_icon_name() using the const icon name taken from
gtk_image_get_icon_name(). As this was reusing the same string pointer, we were
ending with freeing the icon name.
2022-09-26 22:56:08 +02:00
|
|
|
#include "core/gimpcontext.h"
|
2004-08-04 10:15:49 +00:00
|
|
|
#include "core/gimpimage-undo.h"
|
2021-02-11 16:17:36 +01:00
|
|
|
#include "core/gimpimage-undo-push.h"
|
2010-06-27 10:29:49 +02:00
|
|
|
#include "core/gimpimage.h"
|
2021-02-07 00:21:27 +01:00
|
|
|
#include "core/gimpitemlist.h"
|
Made drawable/layer properties (visibility, opacity etc.) undoable (fixes
2003-03-17 Michael Natterer <mitch@gimp.org>
Made drawable/layer properties (visibility, opacity etc.)
undoable (fixes bug #73893).
* app/core/core-enums.[ch]: added undo types/groups for
visibility, mode, opacity, linked and preserve_trans.
* app/core/Makefile.am
* app/core/core-types.h
* app/core/gimpitemundo.[ch]: new GimpUndo subclass which holds a
ref'ed GimpItem pointer so (1) this doesn't need to be done by all
undo steps related to an item and (2) the item the undo step is
for can be determined from outside the undo system.
* app/core/gimpimage-undo.[ch]: added gimp_image_undo_push_item()
which returns a new GimpItemUndo.
* app/core/gimpimage-undo-push.[ch]: use it for all item related
undo steps. Removed lots of GimpItem, GimpLayer, GimpDrawable
and GimpVectors pointers from the private undo structs. Added
undo push functions for the new undo types added above.
* app/core/gimpdrawable.[ch] (gimp_drawable_set_visible): added
"gboolean push_undo" parameter.
* app/core/gimplayer.[ch] (gimp_layer_set_opacity, _mode,
_preserve_trans, _linked): added "gboolean push_undo" parameters.
* app/core/gimpimage-mask.c
* app/core/gimpimage-merge.c
* app/core/gimplayer-floating-sel.c
* app/tools/gimpmovetool.c
* app/xcf/xcf-load.c
* app/widgets/gimpdrawablelistitem.c
* app/widgets/gimplayerlistitem.c
* app/widgets/gimplayerlistview.c: changed accordingly.
* tools/pdbgen/pdb/channel.pdb
* tools/pdbgen/pdb/layer.pdb: ditto. Added '$undo' paramaters to
the foo_accessors() functions. Removed $func from foo_accesors()
because we don't manipulate items without using getters/setters
any longer.
* app/pdb/channel_cmds.c
* app/pdb/layer_cmds.c: regenerated.
* app/widgets/gimpcellrenderertoggle.[ch]: added "clicked" signal
which carries an additional "GdkModifierType state" parameter as
in GimpCellRendererViewable .
* app/widgets/gimpcontainertreeview.c: emit "clicked" from
the toggle renderer, not "toggled" so the callbacks get the
modifier state.
* app/widgets/gimpdrawabletreeview.c: resurrected the "exclusive
visible by <shift>+click" feature as in 1.2.
* app/widgets/gimplayertreeview.c: compress layer opacity undos by
looking at the top of the undo stack and not pushing an undo if
there already is a GIMP_UNDO_DRAWABLE_OPACITY for the active
layer.
2003-03-17 18:02:41 +00:00
|
|
|
#include "core/gimpitemundo.h"
|
2010-06-27 10:29:49 +02:00
|
|
|
#include "core/gimplayer.h"
|
2018-03-07 09:31:02 -05:00
|
|
|
#include "core/gimplayer-floating-selection.h"
|
2015-06-17 13:21:01 +02:00
|
|
|
#include "core/gimplayer-new.h"
|
2010-06-27 10:29:49 +02:00
|
|
|
#include "core/gimplayermask.h"
|
2009-08-04 22:41:49 +02:00
|
|
|
#include "core/gimptreehandler.h"
|
2001-09-25 23:23:09 +00:00
|
|
|
|
2004-06-28 22:07:12 +00:00
|
|
|
#include "text/gimptextlayer.h"
|
|
|
|
|
|
|
|
#include "file/file-open.h"
|
|
|
|
|
2004-08-20 22:32:14 +00:00
|
|
|
#include "gimpactiongroup.h"
|
2003-03-16 11:14:29 +00:00
|
|
|
#include "gimpcellrendererviewable.h"
|
2010-05-17 21:22:36 +02:00
|
|
|
#include "gimpcontainertreestore.h"
|
2004-05-10 23:22:39 +00:00
|
|
|
#include "gimpcontainerview.h"
|
2001-05-08 03:48:54 +00:00
|
|
|
#include "gimpdnd.h"
|
2003-08-24 13:52:51 +00:00
|
|
|
#include "gimphelp-ids.h"
|
2017-01-30 13:24:35 +01:00
|
|
|
#include "gimplayermodebox.h"
|
2003-03-16 11:14:29 +00:00
|
|
|
#include "gimplayertreeview.h"
|
2023-01-31 20:37:19 +01:00
|
|
|
#include "gimptoggleaction.h"
|
2004-05-12 18:36:33 +00:00
|
|
|
#include "gimpuimanager.h"
|
2011-04-18 20:41:02 +02:00
|
|
|
#include "gimpviewrenderer.h"
|
2011-10-07 00:51:17 +02:00
|
|
|
#include "gimpwidgets-utils.h"
|
2001-05-08 03:48:54 +00:00
|
|
|
|
2003-03-25 16:38:19 +00:00
|
|
|
#include "gimp-intl.h"
|
2001-03-11 17:24:47 +00:00
|
|
|
|
|
|
|
|
app, libgimp*, modules: don't use g_type_class_add_private() ...
... and G_TYPE_INSTANCE_GET_PRIVATE()
g_type_class_add_private() and G_TYPE_INSTANCE_GET_PRIVATE() were
deprecated in GLib 2.58. Instead, use
G_DEFINE_[ABSTRACT_]TYPE_WITH_PRIVATE(), and
G_ADD_PRIVATE[_DYNAMIC](), and the implictly-defined
foo_get_instance_private() functions, all of which are available in
the GLib versions we depend on.
This commit only covers types registered using one of the
G_DEFINE_FOO() macros (i.e., most types), but not types with a
custom registration function, of which we still have a few -- GLib
currently only provides a (non-deprecated) public API for adding a
private struct using the G_DEFINE_FOO() macros.
Note that this commit was 99% auto-generated (because I'm not
*that* crazy :), so if there are any style mismatches... we'll have
to live with them for now.
2018-09-18 12:09:39 -04:00
|
|
|
struct _GimpLayerTreeViewPrivate
|
2008-12-25 12:12:33 +00:00
|
|
|
{
|
2017-01-30 13:24:35 +01:00
|
|
|
GtkWidget *layer_mode_box;
|
2008-12-25 12:12:33 +00:00
|
|
|
GtkAdjustment *opacity_adjustment;
|
2018-03-07 05:42:26 -05:00
|
|
|
GtkWidget *anchor_button;
|
2008-12-25 12:12:33 +00:00
|
|
|
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
GtkWidget *link_button;
|
2021-02-07 00:21:27 +01:00
|
|
|
GtkWidget *link_popover;
|
Issue #7023: icon size selection on GIMP 2.99.
This kinda reverts commit 6aebd30de142286c41e6cd90abedc4082a13fcea ("app: remove
icon sizing preferences"), except that the code base is different enough since
this old commit was mainly for GIMP 2.10.x.
In any case, after initially thinking that GTK+3 handling for high density
display would be enough, we finally decide that adding back a Preferences-wide
setting for overriding the theme-set icon size is a good idea (additionally to
GTK+3 automatic support).
The base idea for removing the feature was that GTK+3 has high density display
support, through the "scale factor". Typically a high density display will
normally be set as using a ×2 scale factor so all icons will be double size.
Unfortunately it turns out it's not enough.
For instance, on very small screen estate, even with a scale factor of 1, if the
theme sets 24px toolbox icons, it may still take too much space.
Oppositely on huge screens, even with ×2 factor scale detected by the OS, the
icons may still feel too small (this is possibly what happens with #7023).
Furthermore there is also a matter of taste. Some people like small icons even
when they have the space. Others may want bigger icons, easy to click on.
Finally you can like a theme for its color scheme for instance, but it may not
have the icon size you want. Right now, we'd need to duplicate every theme in
small or bigger size. Instead of doing so, let's just have this global setting
overriding the theme rules.
Comparison with the 2.10 implementation:
- We still provide 4 sizes: small, medium, large and huge.
- We don't have the "Guess ideal size" setting anymore. Instead this is now a
mix of the GTK+3 scale factor logic and the theme-set or custom size. I.e.
that on a high density display with ×2 scale factor, we could have toolbox
icons up to 96 pixels (48×2)!
- We now try to have less custom code in widgets as we append the CSS rules to
the theme (similar to what we were already doing for dark theme or icon
variants). What happens in widget code is mostly to connect to changes in
themes and redraw the widgets which need to be.
- The custom size will now affect: toolbox icons, the FG/BG editor widget (in
both the toolbox and the color dockable), dockable tab icons, the main
dockable buttons, eye and lock header icons in item tree views, eye and lock
cell icons in the item lists.
There are still a bunch of areas where it is not taken into account, such as
plug-ins, and various dialogs, but even in custom-made interface in dockables.
Ultimately it might be interesting to have a way to sync more buttons and
widgets to a global size settings.
Lastly, I fixed a bunch of existing bugs where we were updating icon sizes with
gtk_image_set_from_icon_name() using the const icon name taken from
gtk_image_get_icon_name(). As this was reusing the same string pointer, we were
ending with freeing the icon name.
2022-09-26 22:56:08 +02:00
|
|
|
GtkWidget *new_link_button;
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
GtkWidget *link_list;
|
|
|
|
GtkWidget *link_entry;
|
2021-12-23 01:55:20 +01:00
|
|
|
GtkWidget *link_search_entry;
|
|
|
|
GimpItemList *link_pattern_set;
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
|
2008-12-25 12:12:33 +00:00
|
|
|
gint model_column_mask;
|
|
|
|
gint model_column_mask_visible;
|
|
|
|
|
|
|
|
GtkCellRenderer *mask_cell;
|
|
|
|
|
|
|
|
PangoAttrList *italic_attrs;
|
|
|
|
PangoAttrList *bold_attrs;
|
|
|
|
|
2009-08-04 22:41:49 +02:00
|
|
|
GimpTreeHandler *mode_changed_handler;
|
|
|
|
GimpTreeHandler *opacity_changed_handler;
|
|
|
|
GimpTreeHandler *mask_changed_handler;
|
|
|
|
GimpTreeHandler *alpha_changed_handler;
|
2008-12-25 12:12:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-06-26 21:59:17 +02:00
|
|
|
static void gimp_layer_tree_view_view_iface_init (GimpContainerViewInterface *iface);
|
2011-01-14 09:38:11 +01:00
|
|
|
|
|
|
|
static void gimp_layer_tree_view_constructed (GObject *object);
|
2010-06-26 21:59:17 +02:00
|
|
|
static void gimp_layer_tree_view_finalize (GObject *object);
|
2011-01-14 09:38:11 +01:00
|
|
|
|
Issue #7023: icon size selection on GIMP 2.99.
This kinda reverts commit 6aebd30de142286c41e6cd90abedc4082a13fcea ("app: remove
icon sizing preferences"), except that the code base is different enough since
this old commit was mainly for GIMP 2.10.x.
In any case, after initially thinking that GTK+3 handling for high density
display would be enough, we finally decide that adding back a Preferences-wide
setting for overriding the theme-set icon size is a good idea (additionally to
GTK+3 automatic support).
The base idea for removing the feature was that GTK+3 has high density display
support, through the "scale factor". Typically a high density display will
normally be set as using a ×2 scale factor so all icons will be double size.
Unfortunately it turns out it's not enough.
For instance, on very small screen estate, even with a scale factor of 1, if the
theme sets 24px toolbox icons, it may still take too much space.
Oppositely on huge screens, even with ×2 factor scale detected by the OS, the
icons may still feel too small (this is possibly what happens with #7023).
Furthermore there is also a matter of taste. Some people like small icons even
when they have the space. Others may want bigger icons, easy to click on.
Finally you can like a theme for its color scheme for instance, but it may not
have the icon size you want. Right now, we'd need to duplicate every theme in
small or bigger size. Instead of doing so, let's just have this global setting
overriding the theme rules.
Comparison with the 2.10 implementation:
- We still provide 4 sizes: small, medium, large and huge.
- We don't have the "Guess ideal size" setting anymore. Instead this is now a
mix of the GTK+3 scale factor logic and the theme-set or custom size. I.e.
that on a high density display with ×2 scale factor, we could have toolbox
icons up to 96 pixels (48×2)!
- We now try to have less custom code in widgets as we append the CSS rules to
the theme (similar to what we were already doing for dark theme or icon
variants). What happens in widget code is mostly to connect to changes in
themes and redraw the widgets which need to be.
- The custom size will now affect: toolbox icons, the FG/BG editor widget (in
both the toolbox and the color dockable), dockable tab icons, the main
dockable buttons, eye and lock header icons in item tree views, eye and lock
cell icons in the item lists.
There are still a bunch of areas where it is not taken into account, such as
plug-ins, and various dialogs, but even in custom-made interface in dockables.
Ultimately it might be interesting to have a way to sync more buttons and
widgets to a global size settings.
Lastly, I fixed a bunch of existing bugs where we were updating icon sizes with
gtk_image_set_from_icon_name() using the const icon name taken from
gtk_image_get_icon_name(). As this was reusing the same string pointer, we were
ending with freeing the icon name.
2022-09-26 22:56:08 +02:00
|
|
|
static void gimp_layer_tree_view_style_updated (GtkWidget *widget);
|
|
|
|
|
2010-06-26 21:59:17 +02:00
|
|
|
static void gimp_layer_tree_view_set_container (GimpContainerView *view,
|
|
|
|
GimpContainer *container);
|
|
|
|
static void gimp_layer_tree_view_set_context (GimpContainerView *view,
|
|
|
|
GimpContext *context);
|
|
|
|
static gpointer gimp_layer_tree_view_insert_item (GimpContainerView *view,
|
|
|
|
GimpViewable *viewable,
|
|
|
|
gpointer parent_insert_data,
|
|
|
|
gint index);
|
2020-03-21 19:03:07 +01:00
|
|
|
static gboolean gimp_layer_tree_view_select_items (GimpContainerView *view,
|
|
|
|
GList *items,
|
|
|
|
GList *paths);
|
2010-06-26 21:59:17 +02:00
|
|
|
static void gimp_layer_tree_view_set_view_size (GimpContainerView *view);
|
|
|
|
static gboolean gimp_layer_tree_view_drop_possible (GimpContainerTreeView *view,
|
|
|
|
GimpDndType src_type,
|
2020-03-24 22:06:28 +01:00
|
|
|
GList *src_viewables,
|
2010-06-26 21:59:17 +02:00
|
|
|
GimpViewable *dest_viewable,
|
|
|
|
GtkTreePath *drop_path,
|
|
|
|
GtkTreeViewDropPosition drop_pos,
|
|
|
|
GtkTreeViewDropPosition *return_drop_pos,
|
|
|
|
GdkDragAction *return_drag_action);
|
|
|
|
static void gimp_layer_tree_view_drop_color (GimpContainerTreeView *view,
|
|
|
|
const GimpRGB *color,
|
|
|
|
GimpViewable *dest_viewable,
|
|
|
|
GtkTreeViewDropPosition drop_pos);
|
|
|
|
static void gimp_layer_tree_view_drop_uri_list (GimpContainerTreeView *view,
|
|
|
|
GList *uri_list,
|
|
|
|
GimpViewable *dest_viewable,
|
|
|
|
GtkTreeViewDropPosition drop_pos);
|
|
|
|
static void gimp_layer_tree_view_drop_component (GimpContainerTreeView *tree_view,
|
|
|
|
GimpImage *image,
|
|
|
|
GimpChannelType component,
|
|
|
|
GimpViewable *dest_viewable,
|
|
|
|
GtkTreeViewDropPosition drop_pos);
|
|
|
|
static void gimp_layer_tree_view_drop_pixbuf (GimpContainerTreeView *tree_view,
|
|
|
|
GdkPixbuf *pixbuf,
|
|
|
|
GimpViewable *dest_viewable,
|
|
|
|
GtkTreeViewDropPosition drop_pos);
|
|
|
|
static void gimp_layer_tree_view_set_image (GimpItemTreeView *view,
|
|
|
|
GimpImage *image);
|
|
|
|
static GimpItem * gimp_layer_tree_view_item_new (GimpImage *image);
|
|
|
|
static void gimp_layer_tree_view_floating_selection_changed (GimpImage *image,
|
|
|
|
GimpLayerTreeView *view);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
|
|
|
|
static void gimp_layer_tree_view_layer_links_changed (GimpImage *image,
|
|
|
|
GimpLayerTreeView *view);
|
2021-02-04 21:26:34 +01:00
|
|
|
static gboolean gimp_layer_tree_view_link_clicked (GtkWidget *box,
|
|
|
|
GdkEvent *event,
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
GimpLayerTreeView *view);
|
2021-10-05 01:56:51 +02:00
|
|
|
static void gimp_layer_tree_view_link_popover_shown (GtkPopover *popover,
|
|
|
|
GimpLayerTreeView *view);
|
2021-12-23 01:55:20 +01:00
|
|
|
|
|
|
|
static gboolean gimp_layer_tree_view_search_key_release (GtkWidget *widget,
|
|
|
|
GdkEventKey *event,
|
2021-02-06 16:10:22 +01:00
|
|
|
GimpLayerTreeView *view);
|
2022-11-28 21:48:53 +01:00
|
|
|
static gboolean gimp_layer_tree_view_start_interactive_search (GtkTreeView *tree_view,
|
|
|
|
GimpLayerTreeView *layer_view);
|
2021-12-23 01:55:20 +01:00
|
|
|
|
2021-02-07 00:21:27 +01:00
|
|
|
static void gimp_layer_tree_view_new_link_exit (GimpLayerTreeView *view);
|
|
|
|
static gboolean gimp_layer_tree_view_new_link_clicked (GimpLayerTreeView *view);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
static gboolean gimp_layer_tree_view_unlink_clicked (GtkWidget *widget,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpLayerTreeView *view);
|
|
|
|
|
2017-01-30 13:24:35 +01:00
|
|
|
static void gimp_layer_tree_view_layer_mode_box_callback (GtkWidget *widget,
|
|
|
|
const GParamSpec *pspec,
|
2010-06-26 21:59:17 +02:00
|
|
|
GimpLayerTreeView *view);
|
|
|
|
static void gimp_layer_tree_view_opacity_scale_changed (GtkAdjustment *adj,
|
|
|
|
GimpLayerTreeView *view);
|
|
|
|
static void gimp_layer_tree_view_layer_signal_handler (GimpLayer *layer,
|
|
|
|
GimpLayerTreeView *view);
|
|
|
|
static void gimp_layer_tree_view_update_options (GimpLayerTreeView *view,
|
2020-04-29 02:12:00 +02:00
|
|
|
GList *layers);
|
2010-06-26 21:59:17 +02:00
|
|
|
static void gimp_layer_tree_view_update_menu (GimpLayerTreeView *view,
|
2020-04-28 17:04:47 +02:00
|
|
|
GList *layers);
|
2018-03-07 10:42:00 -05:00
|
|
|
static void gimp_layer_tree_view_update_highlight (GimpLayerTreeView *view);
|
2010-06-26 21:59:17 +02:00
|
|
|
static void gimp_layer_tree_view_mask_update (GimpLayerTreeView *view,
|
|
|
|
GtkTreeIter *iter,
|
|
|
|
GimpLayer *layer);
|
|
|
|
static void gimp_layer_tree_view_mask_changed (GimpLayer *layer,
|
|
|
|
GimpLayerTreeView *view);
|
|
|
|
static void gimp_layer_tree_view_renderer_update (GimpViewRenderer *renderer,
|
|
|
|
GimpLayerTreeView *view);
|
|
|
|
static void gimp_layer_tree_view_update_borders (GimpLayerTreeView *view,
|
|
|
|
GtkTreeIter *iter);
|
2012-03-17 18:30:13 +01:00
|
|
|
static void gimp_layer_tree_view_mask_callback (GimpLayer *mask,
|
2010-06-26 21:59:17 +02:00
|
|
|
GimpLayerTreeView *view);
|
|
|
|
static void gimp_layer_tree_view_layer_clicked (GimpCellRendererViewable *cell,
|
|
|
|
const gchar *path,
|
|
|
|
GdkModifierType state,
|
|
|
|
GimpLayerTreeView *view);
|
|
|
|
static void gimp_layer_tree_view_mask_clicked (GimpCellRendererViewable *cell,
|
|
|
|
const gchar *path,
|
|
|
|
GdkModifierType state,
|
|
|
|
GimpLayerTreeView *view);
|
|
|
|
static void gimp_layer_tree_view_alpha_update (GimpLayerTreeView *view,
|
|
|
|
GtkTreeIter *iter,
|
|
|
|
GimpLayer *layer);
|
|
|
|
static void gimp_layer_tree_view_alpha_changed (GimpLayer *layer,
|
|
|
|
GimpLayerTreeView *view);
|
2003-05-21 11:34:00 +00:00
|
|
|
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2005-12-19 22:37:49 +00:00
|
|
|
G_DEFINE_TYPE_WITH_CODE (GimpLayerTreeView, gimp_layer_tree_view,
|
|
|
|
GIMP_TYPE_DRAWABLE_TREE_VIEW,
|
app, libgimp*, modules: don't use g_type_class_add_private() ...
... and G_TYPE_INSTANCE_GET_PRIVATE()
g_type_class_add_private() and G_TYPE_INSTANCE_GET_PRIVATE() were
deprecated in GLib 2.58. Instead, use
G_DEFINE_[ABSTRACT_]TYPE_WITH_PRIVATE(), and
G_ADD_PRIVATE[_DYNAMIC](), and the implictly-defined
foo_get_instance_private() functions, all of which are available in
the GLib versions we depend on.
This commit only covers types registered using one of the
G_DEFINE_FOO() macros (i.e., most types), but not types with a
custom registration function, of which we still have a few -- GLib
currently only provides a (non-deprecated) public API for adding a
private struct using the G_DEFINE_FOO() macros.
Note that this commit was 99% auto-generated (because I'm not
*that* crazy :), so if there are any style mismatches... we'll have
to live with them for now.
2018-09-18 12:09:39 -04:00
|
|
|
G_ADD_PRIVATE (GimpLayerTreeView)
|
2005-12-19 22:37:49 +00:00
|
|
|
G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONTAINER_VIEW,
|
2006-08-31 21:40:16 +00:00
|
|
|
gimp_layer_tree_view_view_iface_init))
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2005-12-19 22:37:49 +00:00
|
|
|
#define parent_class gimp_layer_tree_view_parent_class
|
|
|
|
|
2006-08-31 21:40:16 +00:00
|
|
|
static GimpContainerViewInterface *parent_view_iface = NULL;
|
2001-03-11 17:24:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
2003-03-16 11:14:29 +00:00
|
|
|
gimp_layer_tree_view_class_init (GimpLayerTreeViewClass *klass)
|
2001-03-11 17:24:47 +00:00
|
|
|
{
|
2007-11-01 23:37:00 +00:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
2003-03-19 15:17:13 +00:00
|
|
|
GimpContainerTreeViewClass *tree_view_class;
|
|
|
|
GimpItemTreeViewClass *item_view_class;
|
Issue #7023: icon size selection on GIMP 2.99.
This kinda reverts commit 6aebd30de142286c41e6cd90abedc4082a13fcea ("app: remove
icon sizing preferences"), except that the code base is different enough since
this old commit was mainly for GIMP 2.10.x.
In any case, after initially thinking that GTK+3 handling for high density
display would be enough, we finally decide that adding back a Preferences-wide
setting for overriding the theme-set icon size is a good idea (additionally to
GTK+3 automatic support).
The base idea for removing the feature was that GTK+3 has high density display
support, through the "scale factor". Typically a high density display will
normally be set as using a ×2 scale factor so all icons will be double size.
Unfortunately it turns out it's not enough.
For instance, on very small screen estate, even with a scale factor of 1, if the
theme sets 24px toolbox icons, it may still take too much space.
Oppositely on huge screens, even with ×2 factor scale detected by the OS, the
icons may still feel too small (this is possibly what happens with #7023).
Furthermore there is also a matter of taste. Some people like small icons even
when they have the space. Others may want bigger icons, easy to click on.
Finally you can like a theme for its color scheme for instance, but it may not
have the icon size you want. Right now, we'd need to duplicate every theme in
small or bigger size. Instead of doing so, let's just have this global setting
overriding the theme rules.
Comparison with the 2.10 implementation:
- We still provide 4 sizes: small, medium, large and huge.
- We don't have the "Guess ideal size" setting anymore. Instead this is now a
mix of the GTK+3 scale factor logic and the theme-set or custom size. I.e.
that on a high density display with ×2 scale factor, we could have toolbox
icons up to 96 pixels (48×2)!
- We now try to have less custom code in widgets as we append the CSS rules to
the theme (similar to what we were already doing for dark theme or icon
variants). What happens in widget code is mostly to connect to changes in
themes and redraw the widgets which need to be.
- The custom size will now affect: toolbox icons, the FG/BG editor widget (in
both the toolbox and the color dockable), dockable tab icons, the main
dockable buttons, eye and lock header icons in item tree views, eye and lock
cell icons in the item lists.
There are still a bunch of areas where it is not taken into account, such as
plug-ins, and various dialogs, but even in custom-made interface in dockables.
Ultimately it might be interesting to have a way to sync more buttons and
widgets to a global size settings.
Lastly, I fixed a bunch of existing bugs where we were updating icon sizes with
gtk_image_set_from_icon_name() using the const icon name taken from
gtk_image_get_icon_name(). As this was reusing the same string pointer, we were
ending with freeing the icon name.
2022-09-26 22:56:08 +02:00
|
|
|
GtkWidgetClass *widget_class;
|
2001-03-11 17:24:47 +00:00
|
|
|
|
Issue #7023: icon size selection on GIMP 2.99.
This kinda reverts commit 6aebd30de142286c41e6cd90abedc4082a13fcea ("app: remove
icon sizing preferences"), except that the code base is different enough since
this old commit was mainly for GIMP 2.10.x.
In any case, after initially thinking that GTK+3 handling for high density
display would be enough, we finally decide that adding back a Preferences-wide
setting for overriding the theme-set icon size is a good idea (additionally to
GTK+3 automatic support).
The base idea for removing the feature was that GTK+3 has high density display
support, through the "scale factor". Typically a high density display will
normally be set as using a ×2 scale factor so all icons will be double size.
Unfortunately it turns out it's not enough.
For instance, on very small screen estate, even with a scale factor of 1, if the
theme sets 24px toolbox icons, it may still take too much space.
Oppositely on huge screens, even with ×2 factor scale detected by the OS, the
icons may still feel too small (this is possibly what happens with #7023).
Furthermore there is also a matter of taste. Some people like small icons even
when they have the space. Others may want bigger icons, easy to click on.
Finally you can like a theme for its color scheme for instance, but it may not
have the icon size you want. Right now, we'd need to duplicate every theme in
small or bigger size. Instead of doing so, let's just have this global setting
overriding the theme rules.
Comparison with the 2.10 implementation:
- We still provide 4 sizes: small, medium, large and huge.
- We don't have the "Guess ideal size" setting anymore. Instead this is now a
mix of the GTK+3 scale factor logic and the theme-set or custom size. I.e.
that on a high density display with ×2 scale factor, we could have toolbox
icons up to 96 pixels (48×2)!
- We now try to have less custom code in widgets as we append the CSS rules to
the theme (similar to what we were already doing for dark theme or icon
variants). What happens in widget code is mostly to connect to changes in
themes and redraw the widgets which need to be.
- The custom size will now affect: toolbox icons, the FG/BG editor widget (in
both the toolbox and the color dockable), dockable tab icons, the main
dockable buttons, eye and lock header icons in item tree views, eye and lock
cell icons in the item lists.
There are still a bunch of areas where it is not taken into account, such as
plug-ins, and various dialogs, but even in custom-made interface in dockables.
Ultimately it might be interesting to have a way to sync more buttons and
widgets to a global size settings.
Lastly, I fixed a bunch of existing bugs where we were updating icon sizes with
gtk_image_set_from_icon_name() using the const icon name taken from
gtk_image_get_icon_name(). As this was reusing the same string pointer, we were
ending with freeing the icon name.
2022-09-26 22:56:08 +02:00
|
|
|
widget_class = GTK_WIDGET_CLASS (klass);
|
2004-05-10 23:22:39 +00:00
|
|
|
tree_view_class = GIMP_CONTAINER_TREE_VIEW_CLASS (klass);
|
|
|
|
item_view_class = GIMP_ITEM_TREE_VIEW_CLASS (klass);
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2011-01-14 09:38:11 +01:00
|
|
|
object_class->constructed = gimp_layer_tree_view_constructed;
|
2003-09-06 21:17:16 +00:00
|
|
|
object_class->finalize = gimp_layer_tree_view_finalize;
|
2003-03-16 11:14:29 +00:00
|
|
|
|
Issue #7023: icon size selection on GIMP 2.99.
This kinda reverts commit 6aebd30de142286c41e6cd90abedc4082a13fcea ("app: remove
icon sizing preferences"), except that the code base is different enough since
this old commit was mainly for GIMP 2.10.x.
In any case, after initially thinking that GTK+3 handling for high density
display would be enough, we finally decide that adding back a Preferences-wide
setting for overriding the theme-set icon size is a good idea (additionally to
GTK+3 automatic support).
The base idea for removing the feature was that GTK+3 has high density display
support, through the "scale factor". Typically a high density display will
normally be set as using a ×2 scale factor so all icons will be double size.
Unfortunately it turns out it's not enough.
For instance, on very small screen estate, even with a scale factor of 1, if the
theme sets 24px toolbox icons, it may still take too much space.
Oppositely on huge screens, even with ×2 factor scale detected by the OS, the
icons may still feel too small (this is possibly what happens with #7023).
Furthermore there is also a matter of taste. Some people like small icons even
when they have the space. Others may want bigger icons, easy to click on.
Finally you can like a theme for its color scheme for instance, but it may not
have the icon size you want. Right now, we'd need to duplicate every theme in
small or bigger size. Instead of doing so, let's just have this global setting
overriding the theme rules.
Comparison with the 2.10 implementation:
- We still provide 4 sizes: small, medium, large and huge.
- We don't have the "Guess ideal size" setting anymore. Instead this is now a
mix of the GTK+3 scale factor logic and the theme-set or custom size. I.e.
that on a high density display with ×2 scale factor, we could have toolbox
icons up to 96 pixels (48×2)!
- We now try to have less custom code in widgets as we append the CSS rules to
the theme (similar to what we were already doing for dark theme or icon
variants). What happens in widget code is mostly to connect to changes in
themes and redraw the widgets which need to be.
- The custom size will now affect: toolbox icons, the FG/BG editor widget (in
both the toolbox and the color dockable), dockable tab icons, the main
dockable buttons, eye and lock header icons in item tree views, eye and lock
cell icons in the item lists.
There are still a bunch of areas where it is not taken into account, such as
plug-ins, and various dialogs, but even in custom-made interface in dockables.
Ultimately it might be interesting to have a way to sync more buttons and
widgets to a global size settings.
Lastly, I fixed a bunch of existing bugs where we were updating icon sizes with
gtk_image_set_from_icon_name() using the const icon name taken from
gtk_image_get_icon_name(). As this was reusing the same string pointer, we were
ending with freeing the icon name.
2022-09-26 22:56:08 +02:00
|
|
|
widget_class->style_updated = gimp_layer_tree_view_style_updated;
|
|
|
|
|
2003-03-19 15:17:13 +00:00
|
|
|
tree_view_class->drop_possible = gimp_layer_tree_view_drop_possible;
|
2004-06-28 22:07:12 +00:00
|
|
|
tree_view_class->drop_color = gimp_layer_tree_view_drop_color;
|
2004-06-30 14:47:23 +00:00
|
|
|
tree_view_class->drop_uri_list = gimp_layer_tree_view_drop_uri_list;
|
2005-01-15 17:57:32 +00:00
|
|
|
tree_view_class->drop_component = gimp_layer_tree_view_drop_component;
|
2005-04-09 17:56:04 +00:00
|
|
|
tree_view_class->drop_pixbuf = gimp_layer_tree_view_drop_pixbuf;
|
2003-03-19 15:17:13 +00:00
|
|
|
|
2004-10-16 20:17:30 +00:00
|
|
|
item_view_class->item_type = GIMP_TYPE_LAYER;
|
2020-03-26 00:33:11 +01:00
|
|
|
item_view_class->signal_name = "selected-layers-changed";
|
2004-10-16 20:17:30 +00:00
|
|
|
|
2003-09-06 21:17:16 +00:00
|
|
|
item_view_class->set_image = gimp_layer_tree_view_set_image;
|
2003-02-17 13:33:29 +00:00
|
|
|
item_view_class->get_container = gimp_image_get_layers;
|
2020-03-26 00:33:11 +01:00
|
|
|
item_view_class->get_selected_items = (GimpGetItemsFunc) gimp_image_get_selected_layers;
|
2020-03-21 19:03:07 +01:00
|
|
|
item_view_class->set_selected_items = (GimpSetItemsFunc) gimp_image_set_selected_layers;
|
2003-02-17 13:33:29 +00:00
|
|
|
item_view_class->add_item = (GimpAddItemFunc) gimp_image_add_layer;
|
2004-10-16 15:48:23 +00:00
|
|
|
item_view_class->remove_item = (GimpRemoveItemFunc) gimp_image_remove_layer;
|
|
|
|
item_view_class->new_item = gimp_layer_tree_view_item_new;
|
|
|
|
|
2012-11-09 11:17:25 +01:00
|
|
|
item_view_class->action_group = "layers";
|
2017-05-13 00:15:05 +02:00
|
|
|
item_view_class->activate_action = "layers-edit";
|
2012-11-09 11:17:25 +01:00
|
|
|
item_view_class->new_action = "layers-new";
|
|
|
|
item_view_class->new_default_action = "layers-new-last-values";
|
|
|
|
item_view_class->raise_action = "layers-raise";
|
|
|
|
item_view_class->raise_top_action = "layers-raise-to-top";
|
|
|
|
item_view_class->lower_action = "layers-lower";
|
|
|
|
item_view_class->lower_bottom_action = "layers-lower-to-bottom";
|
|
|
|
item_view_class->duplicate_action = "layers-duplicate";
|
|
|
|
item_view_class->delete_action = "layers-delete";
|
|
|
|
item_view_class->lock_content_help_id = GIMP_HELP_LAYER_LOCK_PIXELS;
|
|
|
|
item_view_class->lock_position_help_id = GIMP_HELP_LAYER_LOCK_POSITION;
|
2001-03-11 17:24:47 +00:00
|
|
|
}
|
|
|
|
|
2006-08-29 21:44:51 +00:00
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_view_iface_init (GimpContainerViewInterface *iface)
|
|
|
|
{
|
|
|
|
parent_view_iface = g_type_interface_peek_parent (iface);
|
|
|
|
|
|
|
|
iface->set_container = gimp_layer_tree_view_set_container;
|
2006-08-31 21:40:16 +00:00
|
|
|
iface->set_context = gimp_layer_tree_view_set_context;
|
2006-08-29 21:44:51 +00:00
|
|
|
iface->insert_item = gimp_layer_tree_view_insert_item;
|
2020-03-21 19:03:07 +01:00
|
|
|
iface->select_items = gimp_layer_tree_view_select_items;
|
2006-08-29 21:44:51 +00:00
|
|
|
iface->set_view_size = gimp_layer_tree_view_set_view_size;
|
2009-08-23 20:27:47 +02:00
|
|
|
|
|
|
|
iface->model_is_tree = TRUE;
|
2006-08-29 21:44:51 +00:00
|
|
|
}
|
|
|
|
|
2001-03-11 17:24:47 +00:00
|
|
|
static void
|
2003-03-16 11:14:29 +00:00
|
|
|
gimp_layer_tree_view_init (GimpLayerTreeView *view)
|
2001-03-11 17:24:47 +00:00
|
|
|
{
|
2004-05-11 10:01:25 +00:00
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
|
2011-04-18 20:41:02 +02:00
|
|
|
GtkWidget *scale;
|
2003-09-06 21:17:16 +00:00
|
|
|
PangoAttribute *attr;
|
2003-03-16 11:14:29 +00:00
|
|
|
|
app, libgimp*, modules: don't use g_type_class_add_private() ...
... and G_TYPE_INSTANCE_GET_PRIVATE()
g_type_class_add_private() and G_TYPE_INSTANCE_GET_PRIVATE() were
deprecated in GLib 2.58. Instead, use
G_DEFINE_[ABSTRACT_]TYPE_WITH_PRIVATE(), and
G_ADD_PRIVATE[_DYNAMIC](), and the implictly-defined
foo_get_instance_private() functions, all of which are available in
the GLib versions we depend on.
This commit only covers types registered using one of the
G_DEFINE_FOO() macros (i.e., most types), but not types with a
custom registration function, of which we still have a few -- GLib
currently only provides a (non-deprecated) public API for adding a
private struct using the G_DEFINE_FOO() macros.
Note that this commit was 99% auto-generated (because I'm not
*that* crazy :), so if there are any style mismatches... we'll have
to live with them for now.
2018-09-18 12:09:39 -04:00
|
|
|
view->priv = gimp_layer_tree_view_get_instance_private (view);
|
2008-12-25 12:12:33 +00:00
|
|
|
|
2021-12-23 01:55:20 +01:00
|
|
|
view->priv->link_pattern_set = NULL;
|
2021-02-07 00:21:27 +01:00
|
|
|
|
2010-05-17 21:22:36 +02:00
|
|
|
view->priv->model_column_mask =
|
|
|
|
gimp_container_tree_store_columns_add (tree_view->model_columns,
|
|
|
|
&tree_view->n_model_columns,
|
|
|
|
GIMP_TYPE_VIEW_RENDERER);
|
|
|
|
|
|
|
|
view->priv->model_column_mask_visible =
|
|
|
|
gimp_container_tree_store_columns_add (tree_view->model_columns,
|
|
|
|
&tree_view->n_model_columns,
|
|
|
|
G_TYPE_BOOLEAN);
|
2001-03-11 17:24:47 +00:00
|
|
|
|
|
|
|
/* Paint mode menu */
|
|
|
|
|
2017-02-17 05:20:53 -05:00
|
|
|
view->priv->layer_mode_box = gimp_layer_mode_box_new (GIMP_LAYER_MODE_CONTEXT_LAYER);
|
2017-01-30 13:24:35 +01:00
|
|
|
gimp_layer_mode_box_set_label (GIMP_LAYER_MODE_BOX (view->priv->layer_mode_box),
|
|
|
|
_("Mode"));
|
|
|
|
gimp_item_tree_view_add_options (GIMP_ITEM_TREE_VIEW (view), NULL,
|
|
|
|
view->priv->layer_mode_box);
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2017-01-30 13:24:35 +01:00
|
|
|
g_signal_connect (view->priv->layer_mode_box, "notify::layer-mode",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_layer_mode_box_callback),
|
|
|
|
view);
|
2005-02-08 20:07:08 +00:00
|
|
|
|
2017-01-30 13:24:35 +01:00
|
|
|
gimp_help_set_help_data (view->priv->layer_mode_box, NULL,
|
2003-11-12 13:35:06 +00:00
|
|
|
GIMP_HELP_LAYER_DIALOG_PAINT_MODE_MENU);
|
2001-03-12 04:40:17 +00:00
|
|
|
|
2005-07-10 21:17:22 +00:00
|
|
|
/* Opacity scale */
|
|
|
|
|
2018-06-24 18:15:16 +02:00
|
|
|
view->priv->opacity_adjustment = gtk_adjustment_new (100.0, 0.0, 100.0,
|
|
|
|
1.0, 10.0, 0.0);
|
2011-04-18 20:41:02 +02:00
|
|
|
scale = gimp_spin_scale_new (view->priv->opacity_adjustment, _("Opacity"), 1);
|
2019-01-28 17:43:43 +01:00
|
|
|
gimp_spin_scale_set_constrain_drag (GIMP_SPIN_SCALE (scale), TRUE);
|
2011-04-18 20:41:02 +02:00
|
|
|
gimp_help_set_help_data (scale, NULL,
|
|
|
|
GIMP_HELP_LAYER_DIALOG_OPACITY_SCALE);
|
2009-08-19 10:48:32 +02:00
|
|
|
gimp_item_tree_view_add_options (GIMP_ITEM_TREE_VIEW (view),
|
2011-04-18 20:41:02 +02:00
|
|
|
NULL, scale);
|
2005-07-10 21:17:22 +00:00
|
|
|
|
2008-12-25 12:12:33 +00:00
|
|
|
g_signal_connect (view->priv->opacity_adjustment, "value-changed",
|
2005-07-10 21:17:22 +00:00
|
|
|
G_CALLBACK (gimp_layer_tree_view_opacity_scale_changed),
|
|
|
|
view);
|
|
|
|
|
2008-12-25 12:12:33 +00:00
|
|
|
view->priv->italic_attrs = pango_attr_list_new ();
|
2003-09-06 21:17:16 +00:00
|
|
|
attr = pango_attr_style_new (PANGO_STYLE_ITALIC);
|
|
|
|
attr->start_index = 0;
|
|
|
|
attr->end_index = -1;
|
2008-12-25 12:12:33 +00:00
|
|
|
pango_attr_list_insert (view->priv->italic_attrs, attr);
|
2003-09-06 21:17:16 +00:00
|
|
|
|
2008-12-25 12:12:33 +00:00
|
|
|
view->priv->bold_attrs = pango_attr_list_new ();
|
2003-09-06 21:17:16 +00:00
|
|
|
attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
|
|
|
|
attr->start_index = 0;
|
|
|
|
attr->end_index = -1;
|
2008-12-25 12:12:33 +00:00
|
|
|
pango_attr_list_insert (view->priv->bold_attrs, attr);
|
2003-03-16 11:14:29 +00:00
|
|
|
}
|
|
|
|
|
2011-01-14 09:38:11 +01:00
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_constructed (GObject *object)
|
2003-03-16 11:14:29 +00:00
|
|
|
{
|
2011-01-14 09:38:11 +01:00
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (object);
|
|
|
|
GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (object);
|
2005-06-15 14:52:01 +00:00
|
|
|
GtkWidget *button;
|
2021-02-06 16:21:33 +01:00
|
|
|
GtkWidget *placeholder;
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
GtkWidget *grid;
|
2021-02-06 16:21:33 +01:00
|
|
|
PangoAttrList *attrs;
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
GtkIconSize button_size;
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2012-11-12 21:51:22 +01:00
|
|
|
G_OBJECT_CLASS (parent_class)->constructed (object);
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2008-12-25 12:12:33 +00:00
|
|
|
layer_view->priv->mask_cell = gimp_cell_renderer_viewable_new ();
|
2003-03-16 11:14:29 +00:00
|
|
|
gtk_tree_view_column_pack_start (tree_view->main_column,
|
2008-12-25 12:12:33 +00:00
|
|
|
layer_view->priv->mask_cell,
|
2003-03-16 11:14:29 +00:00
|
|
|
FALSE);
|
|
|
|
gtk_tree_view_column_set_attributes (tree_view->main_column,
|
2008-12-25 12:12:33 +00:00
|
|
|
layer_view->priv->mask_cell,
|
2003-03-16 11:14:29 +00:00
|
|
|
"renderer",
|
2008-12-25 12:12:33 +00:00
|
|
|
layer_view->priv->model_column_mask,
|
2003-03-16 11:14:29 +00:00
|
|
|
"visible",
|
2008-12-25 12:12:33 +00:00
|
|
|
layer_view->priv->model_column_mask_visible,
|
2003-03-16 11:14:29 +00:00
|
|
|
NULL);
|
|
|
|
|
2009-08-28 10:59:27 +02:00
|
|
|
gimp_container_tree_view_add_renderer_cell (tree_view,
|
2022-11-02 01:25:43 +01:00
|
|
|
layer_view->priv->mask_cell,
|
|
|
|
layer_view->priv->model_column_mask);
|
2003-03-16 11:14:29 +00:00
|
|
|
|
|
|
|
g_signal_connect (tree_view->renderer_cell, "clicked",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_layer_clicked),
|
|
|
|
layer_view);
|
2008-12-25 12:12:33 +00:00
|
|
|
g_signal_connect (layer_view->priv->mask_cell, "clicked",
|
2003-03-16 11:14:29 +00:00
|
|
|
G_CALLBACK (gimp_layer_tree_view_mask_clicked),
|
|
|
|
layer_view);
|
|
|
|
|
2005-01-15 17:57:32 +00:00
|
|
|
gimp_dnd_component_dest_add (GTK_WIDGET (tree_view->view),
|
|
|
|
NULL, tree_view);
|
|
|
|
gimp_dnd_viewable_dest_add (GTK_WIDGET (tree_view->view), GIMP_TYPE_CHANNEL,
|
|
|
|
NULL, tree_view);
|
|
|
|
gimp_dnd_viewable_dest_add (GTK_WIDGET (tree_view->view), GIMP_TYPE_LAYER_MASK,
|
|
|
|
NULL, tree_view);
|
2010-11-29 22:04:56 +01:00
|
|
|
gimp_dnd_uri_list_dest_add (GTK_WIDGET (tree_view->view),
|
|
|
|
NULL, tree_view);
|
2013-01-09 00:28:30 +01:00
|
|
|
gimp_dnd_pixbuf_dest_add (GTK_WIDGET (tree_view->view),
|
|
|
|
NULL, tree_view);
|
2004-06-28 22:07:12 +00:00
|
|
|
|
2009-08-23 20:27:47 +02:00
|
|
|
button = gimp_editor_add_action_button (GIMP_EDITOR (layer_view), "layers",
|
|
|
|
"layers-new-group", NULL);
|
2011-04-09 19:51:51 +02:00
|
|
|
gtk_box_reorder_child (gimp_editor_get_button_box (GIMP_EDITOR (layer_view)),
|
2016-10-30 17:36:32 +01:00
|
|
|
button, 1);
|
2009-08-23 20:27:47 +02:00
|
|
|
|
2005-06-15 14:52:01 +00:00
|
|
|
button = gimp_editor_add_action_button (GIMP_EDITOR (layer_view), "layers",
|
|
|
|
"layers-anchor", NULL);
|
2018-03-07 05:42:26 -05:00
|
|
|
layer_view->priv->anchor_button = button;
|
2004-05-12 18:36:33 +00:00
|
|
|
gimp_container_view_enable_dnd (GIMP_CONTAINER_VIEW (layer_view),
|
2005-06-15 14:52:01 +00:00
|
|
|
GTK_BUTTON (button),
|
2004-08-25 22:31:44 +00:00
|
|
|
GIMP_TYPE_LAYER);
|
2011-04-09 19:51:51 +02:00
|
|
|
gtk_box_reorder_child (gimp_editor_get_button_box (GIMP_EDITOR (layer_view)),
|
2016-10-30 17:36:32 +01:00
|
|
|
button, 5);
|
2016-08-23 19:18:20 +02:00
|
|
|
|
2019-12-19 16:08:01 -05:00
|
|
|
button = gimp_editor_add_action_button (GIMP_EDITOR (layer_view), "layers",
|
2019-12-19 22:58:31 -05:00
|
|
|
"layers-merge-down-button",
|
|
|
|
"layers-merge-group",
|
|
|
|
GDK_SHIFT_MASK,
|
|
|
|
"layers-merge-layers",
|
|
|
|
GDK_CONTROL_MASK,
|
|
|
|
"layers-merge-layers-last-values",
|
|
|
|
GDK_CONTROL_MASK |
|
|
|
|
GDK_SHIFT_MASK,
|
|
|
|
NULL);
|
2019-12-19 16:08:01 -05:00
|
|
|
gimp_container_view_enable_dnd (GIMP_CONTAINER_VIEW (layer_view),
|
|
|
|
GTK_BUTTON (button),
|
|
|
|
GIMP_TYPE_LAYER);
|
|
|
|
gtk_box_reorder_child (gimp_editor_get_button_box (GIMP_EDITOR (layer_view)),
|
|
|
|
button, 6);
|
|
|
|
|
2016-08-23 19:18:20 +02:00
|
|
|
button = gimp_editor_add_action_button (GIMP_EDITOR (layer_view), "layers",
|
|
|
|
"layers-mask-add-button",
|
|
|
|
"layers-mask-add-last-values",
|
|
|
|
gimp_get_extend_selection_mask (),
|
|
|
|
"layers-mask-delete",
|
|
|
|
gimp_get_modify_selection_mask (),
|
|
|
|
"layers-mask-apply",
|
|
|
|
gimp_get_extend_selection_mask () |
|
|
|
|
gimp_get_modify_selection_mask (),
|
|
|
|
NULL);
|
|
|
|
gimp_container_view_enable_dnd (GIMP_CONTAINER_VIEW (layer_view),
|
|
|
|
GTK_BUTTON (button),
|
|
|
|
GIMP_TYPE_LAYER);
|
|
|
|
gtk_box_reorder_child (gimp_editor_get_button_box (GIMP_EDITOR (layer_view)),
|
2019-12-19 16:08:01 -05:00
|
|
|
button, 7);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
|
|
|
|
/* Link popover menu. */
|
|
|
|
|
|
|
|
layer_view->priv->link_button = gtk_menu_button_new ();
|
2021-10-05 01:56:51 +02:00
|
|
|
gtk_widget_set_tooltip_text (layer_view->priv->link_button,
|
|
|
|
_("Select layers by patterns and store layer sets"));
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
gtk_widget_style_get (GTK_WIDGET (layer_view),
|
|
|
|
"button-icon-size", &button_size,
|
|
|
|
NULL);
|
|
|
|
gtk_button_set_image (GTK_BUTTON (layer_view->priv->link_button),
|
|
|
|
gtk_image_new_from_icon_name (GIMP_ICON_LINKED,
|
|
|
|
button_size));
|
|
|
|
gtk_box_pack_start (gimp_editor_get_button_box (GIMP_EDITOR (layer_view)),
|
|
|
|
layer_view->priv->link_button, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (layer_view->priv->link_button);
|
|
|
|
gimp_container_view_enable_dnd (GIMP_CONTAINER_VIEW (layer_view),
|
|
|
|
GTK_BUTTON (layer_view->priv->link_button),
|
|
|
|
GIMP_TYPE_LAYER);
|
|
|
|
gtk_box_reorder_child (gimp_editor_get_button_box (GIMP_EDITOR (layer_view)),
|
|
|
|
layer_view->priv->link_button, 8);
|
|
|
|
|
2021-02-07 00:21:27 +01:00
|
|
|
layer_view->priv->link_popover = gtk_popover_new (layer_view->priv->link_button);
|
|
|
|
gtk_popover_set_modal (GTK_POPOVER (layer_view->priv->link_popover), TRUE);
|
|
|
|
gtk_menu_button_set_popover (GTK_MENU_BUTTON (layer_view->priv->link_button),
|
|
|
|
layer_view->priv->link_popover);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
|
2021-10-05 01:56:51 +02:00
|
|
|
g_signal_connect (layer_view->priv->link_popover,
|
|
|
|
"show",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_link_popover_shown),
|
|
|
|
layer_view);
|
|
|
|
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
grid = gtk_grid_new ();
|
|
|
|
|
2021-02-06 16:10:22 +01:00
|
|
|
/* Link popover: regexp search. */
|
2021-12-23 01:55:20 +01:00
|
|
|
layer_view->priv->link_search_entry = gtk_entry_new ();
|
|
|
|
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (layer_view->priv->link_search_entry),
|
2021-02-06 16:10:22 +01:00
|
|
|
GTK_ENTRY_ICON_SECONDARY,
|
|
|
|
"system-search");
|
|
|
|
gtk_grid_attach (GTK_GRID (grid),
|
2021-12-23 01:55:20 +01:00
|
|
|
layer_view->priv->link_search_entry,
|
2021-02-06 16:10:22 +01:00
|
|
|
0, 0, 2, 1);
|
2021-12-23 01:55:20 +01:00
|
|
|
gtk_widget_show (layer_view->priv->link_search_entry);
|
|
|
|
g_signal_connect (layer_view->priv->link_search_entry,
|
|
|
|
"key-release-event",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_search_key_release),
|
2021-02-06 16:10:22 +01:00
|
|
|
layer_view);
|
|
|
|
|
2022-11-28 21:48:53 +01:00
|
|
|
g_signal_connect (GIMP_CONTAINER_TREE_VIEW (layer_view)->view,
|
|
|
|
"start-interactive-search",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_start_interactive_search),
|
|
|
|
layer_view);
|
|
|
|
gtk_tree_view_set_search_entry (GIMP_CONTAINER_TREE_VIEW (layer_view)->view,
|
|
|
|
GTK_ENTRY (layer_view->priv->link_search_entry));
|
|
|
|
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
/* Link popover: existing links. */
|
|
|
|
layer_view->priv->link_list = gtk_list_box_new ();
|
2021-02-06 16:21:33 +01:00
|
|
|
placeholder = gtk_label_new (_("No layer set stored"));
|
|
|
|
attrs = pango_attr_list_new ();
|
|
|
|
gtk_label_set_attributes (GTK_LABEL (placeholder),
|
|
|
|
attrs);
|
|
|
|
pango_attr_list_insert (attrs, pango_attr_style_new (PANGO_STYLE_ITALIC));
|
|
|
|
pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_ULTRALIGHT));
|
|
|
|
pango_attr_list_unref (attrs);
|
|
|
|
gtk_list_box_set_placeholder (GTK_LIST_BOX (layer_view->priv->link_list),
|
|
|
|
placeholder);
|
|
|
|
gtk_widget_show (placeholder);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
gtk_grid_attach (GTK_GRID (grid),
|
|
|
|
layer_view->priv->link_list,
|
2021-02-06 16:10:22 +01:00
|
|
|
0, 1, 2, 1);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
gtk_widget_show (layer_view->priv->link_list);
|
|
|
|
|
|
|
|
gtk_list_box_set_activate_on_single_click (GTK_LIST_BOX (layer_view->priv->link_list),
|
|
|
|
TRUE);
|
|
|
|
|
|
|
|
/* Link popover: new links. */
|
|
|
|
|
|
|
|
layer_view->priv->link_entry = gtk_entry_new ();
|
|
|
|
gtk_entry_set_placeholder_text (GTK_ENTRY (layer_view->priv->link_entry),
|
2022-02-02 16:15:25 +01:00
|
|
|
_("New layer set's name"));
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
gtk_grid_attach (GTK_GRID (grid),
|
|
|
|
layer_view->priv->link_entry,
|
2021-02-06 16:10:22 +01:00
|
|
|
0, 2, 1, 1);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
gtk_widget_show (layer_view->priv->link_entry);
|
|
|
|
|
2022-02-02 16:15:25 +01:00
|
|
|
button = gtk_button_new_from_icon_name (GIMP_ICON_LIST_ADD, button_size);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
gtk_grid_attach (GTK_GRID (grid),
|
|
|
|
button,
|
2021-02-06 16:10:22 +01:00
|
|
|
1, 2, 1, 1);
|
2021-02-07 00:21:27 +01:00
|
|
|
g_signal_connect_swapped (button,
|
|
|
|
"clicked",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_new_link_clicked),
|
|
|
|
layer_view);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
gtk_widget_show (button);
|
Issue #7023: icon size selection on GIMP 2.99.
This kinda reverts commit 6aebd30de142286c41e6cd90abedc4082a13fcea ("app: remove
icon sizing preferences"), except that the code base is different enough since
this old commit was mainly for GIMP 2.10.x.
In any case, after initially thinking that GTK+3 handling for high density
display would be enough, we finally decide that adding back a Preferences-wide
setting for overriding the theme-set icon size is a good idea (additionally to
GTK+3 automatic support).
The base idea for removing the feature was that GTK+3 has high density display
support, through the "scale factor". Typically a high density display will
normally be set as using a ×2 scale factor so all icons will be double size.
Unfortunately it turns out it's not enough.
For instance, on very small screen estate, even with a scale factor of 1, if the
theme sets 24px toolbox icons, it may still take too much space.
Oppositely on huge screens, even with ×2 factor scale detected by the OS, the
icons may still feel too small (this is possibly what happens with #7023).
Furthermore there is also a matter of taste. Some people like small icons even
when they have the space. Others may want bigger icons, easy to click on.
Finally you can like a theme for its color scheme for instance, but it may not
have the icon size you want. Right now, we'd need to duplicate every theme in
small or bigger size. Instead of doing so, let's just have this global setting
overriding the theme rules.
Comparison with the 2.10 implementation:
- We still provide 4 sizes: small, medium, large and huge.
- We don't have the "Guess ideal size" setting anymore. Instead this is now a
mix of the GTK+3 scale factor logic and the theme-set or custom size. I.e.
that on a high density display with ×2 scale factor, we could have toolbox
icons up to 96 pixels (48×2)!
- We now try to have less custom code in widgets as we append the CSS rules to
the theme (similar to what we were already doing for dark theme or icon
variants). What happens in widget code is mostly to connect to changes in
themes and redraw the widgets which need to be.
- The custom size will now affect: toolbox icons, the FG/BG editor widget (in
both the toolbox and the color dockable), dockable tab icons, the main
dockable buttons, eye and lock header icons in item tree views, eye and lock
cell icons in the item lists.
There are still a bunch of areas where it is not taken into account, such as
plug-ins, and various dialogs, but even in custom-made interface in dockables.
Ultimately it might be interesting to have a way to sync more buttons and
widgets to a global size settings.
Lastly, I fixed a bunch of existing bugs where we were updating icon sizes with
gtk_image_set_from_icon_name() using the const icon name taken from
gtk_image_get_icon_name(). As this was reusing the same string pointer, we were
ending with freeing the icon name.
2022-09-26 22:56:08 +02:00
|
|
|
layer_view->priv->new_link_button = button;
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
|
2021-02-07 00:21:27 +01:00
|
|
|
/* Enter on any entry activates the link creation then exits in case
|
|
|
|
* of success.
|
|
|
|
*/
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
g_signal_connect_swapped (layer_view->priv->link_entry,
|
|
|
|
"activate",
|
2021-02-07 00:21:27 +01:00
|
|
|
G_CALLBACK (gimp_layer_tree_view_new_link_exit),
|
|
|
|
layer_view);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
|
2021-02-07 00:21:27 +01:00
|
|
|
gtk_container_add (GTK_CONTAINER (layer_view->priv->link_popover), grid);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
gtk_widget_show (grid);
|
2021-02-09 02:39:37 +01:00
|
|
|
|
|
|
|
/* Lock alpha toggle */
|
|
|
|
|
|
|
|
gimp_item_tree_view_add_lock (GIMP_ITEM_TREE_VIEW (tree_view),
|
2021-03-09 11:08:00 +01:00
|
|
|
GIMP_ICON_LOCK_ALPHA,
|
2021-02-09 02:39:37 +01:00
|
|
|
(GimpIsLockedFunc) gimp_layer_get_lock_alpha,
|
2021-02-11 16:17:36 +01:00
|
|
|
(GimpCanLockFunc) gimp_layer_can_lock_alpha,
|
|
|
|
(GimpSetLockFunc) gimp_layer_set_lock_alpha,
|
|
|
|
(GimpUndoLockPush) gimp_image_undo_push_layer_lock_alpha,
|
2021-02-09 02:39:37 +01:00
|
|
|
"lock-alpha-changed",
|
|
|
|
GIMP_UNDO_LAYER_LOCK_ALPHA,
|
|
|
|
GIMP_UNDO_GROUP_LAYER_LOCK_ALPHA,
|
|
|
|
_("Lock alpha channel"),
|
|
|
|
_("Unlock alpha channel"),
|
2021-02-11 16:17:36 +01:00
|
|
|
_("Set Item Exclusive Alpha Channel lock"),
|
2021-02-09 02:39:37 +01:00
|
|
|
_("Lock alpha channel"),
|
|
|
|
GIMP_HELP_LAYER_LOCK_ALPHA);
|
2001-03-11 17:24:47 +00:00
|
|
|
}
|
|
|
|
|
2003-09-06 21:17:16 +00:00
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (object);
|
|
|
|
|
2008-12-25 12:12:33 +00:00
|
|
|
if (layer_view->priv->italic_attrs)
|
2003-09-06 21:17:16 +00:00
|
|
|
{
|
2008-12-25 12:12:33 +00:00
|
|
|
pango_attr_list_unref (layer_view->priv->italic_attrs);
|
|
|
|
layer_view->priv->italic_attrs = NULL;
|
2003-09-06 21:17:16 +00:00
|
|
|
}
|
|
|
|
|
2008-12-25 12:12:33 +00:00
|
|
|
if (layer_view->priv->bold_attrs)
|
2003-09-06 21:17:16 +00:00
|
|
|
{
|
2008-12-25 12:12:33 +00:00
|
|
|
pango_attr_list_unref (layer_view->priv->bold_attrs);
|
|
|
|
layer_view->priv->bold_attrs = NULL;
|
2003-09-06 21:17:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
2001-03-11 17:24:47 +00:00
|
|
|
|
Issue #7023: icon size selection on GIMP 2.99.
This kinda reverts commit 6aebd30de142286c41e6cd90abedc4082a13fcea ("app: remove
icon sizing preferences"), except that the code base is different enough since
this old commit was mainly for GIMP 2.10.x.
In any case, after initially thinking that GTK+3 handling for high density
display would be enough, we finally decide that adding back a Preferences-wide
setting for overriding the theme-set icon size is a good idea (additionally to
GTK+3 automatic support).
The base idea for removing the feature was that GTK+3 has high density display
support, through the "scale factor". Typically a high density display will
normally be set as using a ×2 scale factor so all icons will be double size.
Unfortunately it turns out it's not enough.
For instance, on very small screen estate, even with a scale factor of 1, if the
theme sets 24px toolbox icons, it may still take too much space.
Oppositely on huge screens, even with ×2 factor scale detected by the OS, the
icons may still feel too small (this is possibly what happens with #7023).
Furthermore there is also a matter of taste. Some people like small icons even
when they have the space. Others may want bigger icons, easy to click on.
Finally you can like a theme for its color scheme for instance, but it may not
have the icon size you want. Right now, we'd need to duplicate every theme in
small or bigger size. Instead of doing so, let's just have this global setting
overriding the theme rules.
Comparison with the 2.10 implementation:
- We still provide 4 sizes: small, medium, large and huge.
- We don't have the "Guess ideal size" setting anymore. Instead this is now a
mix of the GTK+3 scale factor logic and the theme-set or custom size. I.e.
that on a high density display with ×2 scale factor, we could have toolbox
icons up to 96 pixels (48×2)!
- We now try to have less custom code in widgets as we append the CSS rules to
the theme (similar to what we were already doing for dark theme or icon
variants). What happens in widget code is mostly to connect to changes in
themes and redraw the widgets which need to be.
- The custom size will now affect: toolbox icons, the FG/BG editor widget (in
both the toolbox and the color dockable), dockable tab icons, the main
dockable buttons, eye and lock header icons in item tree views, eye and lock
cell icons in the item lists.
There are still a bunch of areas where it is not taken into account, such as
plug-ins, and various dialogs, but even in custom-made interface in dockables.
Ultimately it might be interesting to have a way to sync more buttons and
widgets to a global size settings.
Lastly, I fixed a bunch of existing bugs where we were updating icon sizes with
gtk_image_set_from_icon_name() using the const icon name taken from
gtk_image_get_icon_name(). As this was reusing the same string pointer, we were
ending with freeing the icon name.
2022-09-26 22:56:08 +02:00
|
|
|
/* GimpWidget methods */
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_style_updated (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
GimpLayerTreeView *view = GIMP_LAYER_TREE_VIEW (widget);
|
|
|
|
GtkWidget *image;
|
|
|
|
const gchar *old_icon_name;
|
|
|
|
GtkReliefStyle button_relief;
|
|
|
|
GtkIconSize old_size;
|
|
|
|
GtkIconSize button_size;
|
|
|
|
|
|
|
|
gtk_widget_style_get (widget,
|
|
|
|
"button-relief", &button_relief,
|
|
|
|
"button-icon-size", &button_size,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
gtk_button_set_relief (GTK_BUTTON (view->priv->link_button),
|
|
|
|
button_relief);
|
|
|
|
|
|
|
|
image = gtk_button_get_image (GTK_BUTTON (view->priv->link_button));
|
|
|
|
|
|
|
|
gtk_image_get_icon_name (GTK_IMAGE (image), &old_icon_name, &old_size);
|
|
|
|
|
|
|
|
if (button_size != old_size)
|
|
|
|
{
|
|
|
|
gchar *icon_name;
|
|
|
|
|
|
|
|
/* Changing the link button in dockable button box. */
|
|
|
|
icon_name = g_strdup (old_icon_name);
|
|
|
|
gtk_image_set_from_icon_name (GTK_IMAGE (image),
|
|
|
|
icon_name, button_size);
|
|
|
|
g_free (icon_name);
|
|
|
|
|
|
|
|
/* Changing the new link button inside the popover. */
|
|
|
|
image = gtk_button_get_image (GTK_BUTTON (view->priv->new_link_button));
|
|
|
|
gtk_image_get_icon_name (GTK_IMAGE (image), &old_icon_name, &old_size);
|
|
|
|
icon_name = g_strdup (old_icon_name);
|
|
|
|
gtk_image_set_from_icon_name (GTK_IMAGE (image),
|
|
|
|
icon_name, button_size);
|
|
|
|
g_free (icon_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-11 17:24:47 +00:00
|
|
|
/* GimpContainerView methods */
|
|
|
|
|
|
|
|
static void
|
2003-03-16 11:14:29 +00:00
|
|
|
gimp_layer_tree_view_set_container (GimpContainerView *view,
|
2004-08-25 22:31:44 +00:00
|
|
|
GimpContainer *container)
|
2001-03-11 17:24:47 +00:00
|
|
|
{
|
2004-05-10 17:16:50 +00:00
|
|
|
GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view);
|
|
|
|
GimpContainer *old_container;
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2004-05-10 17:16:50 +00:00
|
|
|
old_container = gimp_container_view_get_container (view);
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2004-05-10 17:16:50 +00:00
|
|
|
if (old_container)
|
2001-03-11 17:24:47 +00:00
|
|
|
{
|
2009-08-04 22:41:49 +02:00
|
|
|
gimp_tree_handler_disconnect (layer_view->priv->mode_changed_handler);
|
|
|
|
layer_view->priv->mode_changed_handler = NULL;
|
|
|
|
|
|
|
|
gimp_tree_handler_disconnect (layer_view->priv->opacity_changed_handler);
|
|
|
|
layer_view->priv->opacity_changed_handler = NULL;
|
|
|
|
|
|
|
|
gimp_tree_handler_disconnect (layer_view->priv->mask_changed_handler);
|
|
|
|
layer_view->priv->mask_changed_handler = NULL;
|
|
|
|
|
|
|
|
gimp_tree_handler_disconnect (layer_view->priv->alpha_changed_handler);
|
|
|
|
layer_view->priv->alpha_changed_handler = NULL;
|
2001-03-11 17:24:47 +00:00
|
|
|
}
|
|
|
|
|
2004-05-10 23:22:39 +00:00
|
|
|
parent_view_iface->set_container (view, container);
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2004-05-10 17:16:50 +00:00
|
|
|
if (container)
|
2001-03-11 17:24:47 +00:00
|
|
|
{
|
2009-08-04 22:41:49 +02:00
|
|
|
layer_view->priv->mode_changed_handler =
|
|
|
|
gimp_tree_handler_connect (container, "mode-changed",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_layer_signal_handler),
|
|
|
|
view);
|
|
|
|
|
|
|
|
layer_view->priv->opacity_changed_handler =
|
|
|
|
gimp_tree_handler_connect (container, "opacity-changed",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_layer_signal_handler),
|
|
|
|
view);
|
|
|
|
|
|
|
|
layer_view->priv->mask_changed_handler =
|
|
|
|
gimp_tree_handler_connect (container, "mask-changed",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_mask_changed),
|
|
|
|
view);
|
|
|
|
|
|
|
|
layer_view->priv->alpha_changed_handler =
|
|
|
|
gimp_tree_handler_connect (container, "alpha-changed",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_alpha_changed),
|
|
|
|
view);
|
2001-03-11 17:24:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-28 10:15:38 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
gint mask_column;
|
|
|
|
GimpContext *context;
|
|
|
|
} SetContextForeachData;
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_layer_tree_view_set_context_foreach (GtkTreeModel *model,
|
|
|
|
GtkTreePath *path,
|
|
|
|
GtkTreeIter *iter,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
SetContextForeachData *context_data = data;
|
|
|
|
GimpViewRenderer *renderer;
|
|
|
|
|
|
|
|
gtk_tree_model_get (model, iter,
|
|
|
|
context_data->mask_column, &renderer,
|
|
|
|
-1);
|
|
|
|
|
|
|
|
if (renderer)
|
|
|
|
{
|
|
|
|
gimp_view_renderer_set_context (renderer, context_data->context);
|
|
|
|
|
|
|
|
g_object_unref (renderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2006-08-31 21:40:16 +00:00
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_set_context (GimpContainerView *view,
|
|
|
|
GimpContext *context)
|
|
|
|
{
|
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
|
|
|
|
GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view);
|
Issue #7023: icon size selection on GIMP 2.99.
This kinda reverts commit 6aebd30de142286c41e6cd90abedc4082a13fcea ("app: remove
icon sizing preferences"), except that the code base is different enough since
this old commit was mainly for GIMP 2.10.x.
In any case, after initially thinking that GTK+3 handling for high density
display would be enough, we finally decide that adding back a Preferences-wide
setting for overriding the theme-set icon size is a good idea (additionally to
GTK+3 automatic support).
The base idea for removing the feature was that GTK+3 has high density display
support, through the "scale factor". Typically a high density display will
normally be set as using a ×2 scale factor so all icons will be double size.
Unfortunately it turns out it's not enough.
For instance, on very small screen estate, even with a scale factor of 1, if the
theme sets 24px toolbox icons, it may still take too much space.
Oppositely on huge screens, even with ×2 factor scale detected by the OS, the
icons may still feel too small (this is possibly what happens with #7023).
Furthermore there is also a matter of taste. Some people like small icons even
when they have the space. Others may want bigger icons, easy to click on.
Finally you can like a theme for its color scheme for instance, but it may not
have the icon size you want. Right now, we'd need to duplicate every theme in
small or bigger size. Instead of doing so, let's just have this global setting
overriding the theme rules.
Comparison with the 2.10 implementation:
- We still provide 4 sizes: small, medium, large and huge.
- We don't have the "Guess ideal size" setting anymore. Instead this is now a
mix of the GTK+3 scale factor logic and the theme-set or custom size. I.e.
that on a high density display with ×2 scale factor, we could have toolbox
icons up to 96 pixels (48×2)!
- We now try to have less custom code in widgets as we append the CSS rules to
the theme (similar to what we were already doing for dark theme or icon
variants). What happens in widget code is mostly to connect to changes in
themes and redraw the widgets which need to be.
- The custom size will now affect: toolbox icons, the FG/BG editor widget (in
both the toolbox and the color dockable), dockable tab icons, the main
dockable buttons, eye and lock header icons in item tree views, eye and lock
cell icons in the item lists.
There are still a bunch of areas where it is not taken into account, such as
plug-ins, and various dialogs, but even in custom-made interface in dockables.
Ultimately it might be interesting to have a way to sync more buttons and
widgets to a global size settings.
Lastly, I fixed a bunch of existing bugs where we were updating icon sizes with
gtk_image_set_from_icon_name() using the const icon name taken from
gtk_image_get_icon_name(). As this was reusing the same string pointer, we were
ending with freeing the icon name.
2022-09-26 22:56:08 +02:00
|
|
|
GimpContext *old_context;
|
|
|
|
|
|
|
|
old_context = gimp_container_view_get_context (view);
|
|
|
|
|
|
|
|
if (old_context)
|
|
|
|
{
|
|
|
|
g_signal_handlers_disconnect_by_func (old_context->gimp->config,
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_style_updated),
|
|
|
|
view);
|
|
|
|
}
|
2006-08-31 21:40:16 +00:00
|
|
|
|
|
|
|
parent_view_iface->set_context (view, context);
|
|
|
|
|
Issue #7023: icon size selection on GIMP 2.99.
This kinda reverts commit 6aebd30de142286c41e6cd90abedc4082a13fcea ("app: remove
icon sizing preferences"), except that the code base is different enough since
this old commit was mainly for GIMP 2.10.x.
In any case, after initially thinking that GTK+3 handling for high density
display would be enough, we finally decide that adding back a Preferences-wide
setting for overriding the theme-set icon size is a good idea (additionally to
GTK+3 automatic support).
The base idea for removing the feature was that GTK+3 has high density display
support, through the "scale factor". Typically a high density display will
normally be set as using a ×2 scale factor so all icons will be double size.
Unfortunately it turns out it's not enough.
For instance, on very small screen estate, even with a scale factor of 1, if the
theme sets 24px toolbox icons, it may still take too much space.
Oppositely on huge screens, even with ×2 factor scale detected by the OS, the
icons may still feel too small (this is possibly what happens with #7023).
Furthermore there is also a matter of taste. Some people like small icons even
when they have the space. Others may want bigger icons, easy to click on.
Finally you can like a theme for its color scheme for instance, but it may not
have the icon size you want. Right now, we'd need to duplicate every theme in
small or bigger size. Instead of doing so, let's just have this global setting
overriding the theme rules.
Comparison with the 2.10 implementation:
- We still provide 4 sizes: small, medium, large and huge.
- We don't have the "Guess ideal size" setting anymore. Instead this is now a
mix of the GTK+3 scale factor logic and the theme-set or custom size. I.e.
that on a high density display with ×2 scale factor, we could have toolbox
icons up to 96 pixels (48×2)!
- We now try to have less custom code in widgets as we append the CSS rules to
the theme (similar to what we were already doing for dark theme or icon
variants). What happens in widget code is mostly to connect to changes in
themes and redraw the widgets which need to be.
- The custom size will now affect: toolbox icons, the FG/BG editor widget (in
both the toolbox and the color dockable), dockable tab icons, the main
dockable buttons, eye and lock header icons in item tree views, eye and lock
cell icons in the item lists.
There are still a bunch of areas where it is not taken into account, such as
plug-ins, and various dialogs, but even in custom-made interface in dockables.
Ultimately it might be interesting to have a way to sync more buttons and
widgets to a global size settings.
Lastly, I fixed a bunch of existing bugs where we were updating icon sizes with
gtk_image_set_from_icon_name() using the const icon name taken from
gtk_image_get_icon_name(). As this was reusing the same string pointer, we were
ending with freeing the icon name.
2022-09-26 22:56:08 +02:00
|
|
|
if (context)
|
|
|
|
{
|
|
|
|
g_signal_connect_object (context->gimp->config,
|
|
|
|
"notify::theme",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_style_updated),
|
|
|
|
view, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
|
|
|
|
g_signal_connect_object (context->gimp->config,
|
|
|
|
"notify::override-theme-icon-size",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_style_updated),
|
|
|
|
view, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
|
|
|
|
g_signal_connect_object (context->gimp->config,
|
|
|
|
"notify::custom-icon-size",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_style_updated),
|
|
|
|
view, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
|
|
|
|
}
|
|
|
|
|
2006-08-31 21:40:16 +00:00
|
|
|
if (tree_view->model)
|
|
|
|
{
|
2009-08-28 10:15:38 +02:00
|
|
|
SetContextForeachData context_data = { layer_view->priv->model_column_mask,
|
|
|
|
context };
|
|
|
|
|
|
|
|
gtk_tree_model_foreach (tree_view->model,
|
|
|
|
gimp_layer_tree_view_set_context_foreach,
|
|
|
|
&context_data);
|
2006-08-31 21:40:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-16 11:14:29 +00:00
|
|
|
static gpointer
|
|
|
|
gimp_layer_tree_view_insert_item (GimpContainerView *view,
|
|
|
|
GimpViewable *viewable,
|
2009-08-01 19:13:35 +02:00
|
|
|
gpointer parent_insert_data,
|
2003-03-16 11:14:29 +00:00
|
|
|
gint index)
|
|
|
|
{
|
2004-05-10 23:22:39 +00:00
|
|
|
GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view);
|
|
|
|
GimpLayer *layer;
|
|
|
|
GtkTreeIter *iter;
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2009-08-01 19:13:35 +02:00
|
|
|
iter = parent_view_iface->insert_item (view, viewable,
|
|
|
|
parent_insert_data, index);
|
2003-03-16 11:14:29 +00:00
|
|
|
|
|
|
|
layer = GIMP_LAYER (viewable);
|
|
|
|
|
2003-05-21 11:34:00 +00:00
|
|
|
if (! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
|
|
|
|
gimp_layer_tree_view_alpha_update (layer_view, iter, layer);
|
|
|
|
|
2003-03-16 13:19:43 +00:00
|
|
|
gimp_layer_tree_view_mask_update (layer_view, iter, layer);
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2022-11-02 01:25:43 +01:00
|
|
|
if (GIMP_IS_LAYER (viewable) && gimp_layer_is_floating_sel (GIMP_LAYER (viewable)))
|
|
|
|
{
|
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
|
|
|
|
GimpLayer *floating = GIMP_LAYER (viewable);
|
|
|
|
GimpDrawable *drawable = gimp_layer_get_floating_sel_drawable (floating);
|
|
|
|
|
|
|
|
if (GIMP_IS_LAYER_MASK (drawable))
|
|
|
|
{
|
|
|
|
/* Display floating mask in the mask column. */
|
|
|
|
GimpViewRenderer *renderer = NULL;
|
|
|
|
|
|
|
|
gtk_tree_model_get (GTK_TREE_MODEL (tree_view->model), iter,
|
|
|
|
GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
|
|
|
|
-1);
|
|
|
|
if (renderer)
|
|
|
|
{
|
|
|
|
gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter,
|
|
|
|
layer_view->priv->model_column_mask, renderer,
|
|
|
|
layer_view->priv->model_column_mask_visible, TRUE,
|
|
|
|
GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, NULL,
|
|
|
|
-1);
|
|
|
|
g_object_unref (renderer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-16 11:14:29 +00:00
|
|
|
return iter;
|
|
|
|
}
|
|
|
|
|
2020-03-21 19:03:07 +01:00
|
|
|
static gboolean
|
|
|
|
gimp_layer_tree_view_select_items (GimpContainerView *view,
|
|
|
|
GList *items,
|
|
|
|
GList *paths)
|
|
|
|
{
|
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
|
|
|
|
GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view);
|
|
|
|
GList *layers = items;
|
|
|
|
GList *path = paths;
|
|
|
|
gboolean success;
|
|
|
|
|
|
|
|
success = parent_view_iface->select_items (view, items, paths);
|
|
|
|
|
|
|
|
if (layers)
|
|
|
|
{
|
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
for (layers = items, path = paths; layers && path; layers = layers->next, path = path->next)
|
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
gtk_tree_model_get_iter (tree_view->model, &iter, path->data);
|
|
|
|
gimp_layer_tree_view_update_borders (layer_view, &iter);
|
|
|
|
}
|
2020-04-29 02:12:00 +02:00
|
|
|
gimp_layer_tree_view_update_options (layer_view, items);
|
2020-04-28 17:04:47 +02:00
|
|
|
gimp_layer_tree_view_update_menu (layer_view, items);
|
2020-03-21 19:03:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! success)
|
|
|
|
{
|
|
|
|
GimpEditor *editor = GIMP_EDITOR (view);
|
|
|
|
|
2021-06-19 23:31:37 +02:00
|
|
|
/* currently, select_items() only ever fails when there is a floating
|
2020-03-21 19:03:07 +01:00
|
|
|
* selection, which can be committed/canceled through the editor buttons.
|
|
|
|
*/
|
|
|
|
gimp_widget_blink (GTK_WIDGET (gimp_editor_get_button_box (editor)));
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
2009-08-28 10:07:15 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
gint mask_column;
|
|
|
|
gint view_size;
|
|
|
|
gint border_width;
|
|
|
|
} SetSizeForeachData;
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_layer_tree_view_set_view_size_foreach (GtkTreeModel *model,
|
|
|
|
GtkTreePath *path,
|
|
|
|
GtkTreeIter *iter,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
SetSizeForeachData *size_data = data;
|
|
|
|
GimpViewRenderer *renderer;
|
|
|
|
|
|
|
|
gtk_tree_model_get (model, iter,
|
|
|
|
size_data->mask_column, &renderer,
|
|
|
|
-1);
|
|
|
|
|
|
|
|
if (renderer)
|
|
|
|
{
|
|
|
|
gimp_view_renderer_set_size (renderer,
|
|
|
|
size_data->view_size,
|
|
|
|
size_data->border_width);
|
|
|
|
|
|
|
|
g_object_unref (renderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2003-03-16 11:14:29 +00:00
|
|
|
static void
|
2006-01-17 10:08:50 +00:00
|
|
|
gimp_layer_tree_view_set_view_size (GimpContainerView *view)
|
2003-03-16 11:14:29 +00:00
|
|
|
{
|
2004-05-10 17:16:50 +00:00
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2005-03-18 00:31:29 +00:00
|
|
|
if (tree_view->model)
|
2003-03-16 11:14:29 +00:00
|
|
|
{
|
2005-03-18 00:31:29 +00:00
|
|
|
GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view);
|
2009-08-28 10:07:15 +02:00
|
|
|
SetSizeForeachData size_data;
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2009-08-28 10:07:15 +02:00
|
|
|
size_data.mask_column = layer_view->priv->model_column_mask;
|
2005-03-18 00:31:29 +00:00
|
|
|
|
2009-08-28 10:07:15 +02:00
|
|
|
size_data.view_size =
|
|
|
|
gimp_container_view_get_view_size (view, &size_data.border_width);
|
2005-03-18 00:31:29 +00:00
|
|
|
|
2009-08-28 10:07:15 +02:00
|
|
|
gtk_tree_model_foreach (tree_view->model,
|
|
|
|
gimp_layer_tree_view_set_view_size_foreach,
|
|
|
|
&size_data);
|
2003-03-16 11:14:29 +00:00
|
|
|
}
|
|
|
|
|
2006-01-17 10:08:50 +00:00
|
|
|
parent_view_iface->set_view_size (view);
|
2003-03-16 11:14:29 +00:00
|
|
|
}
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2003-03-16 13:19:43 +00:00
|
|
|
|
2003-03-19 15:17:13 +00:00
|
|
|
/* GimpContainerTreeView methods */
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_layer_tree_view_drop_possible (GimpContainerTreeView *tree_view,
|
2004-06-28 22:07:12 +00:00
|
|
|
GimpDndType src_type,
|
2020-03-24 22:06:28 +01:00
|
|
|
GList *src_viewables,
|
2003-03-19 15:17:13 +00:00
|
|
|
GimpViewable *dest_viewable,
|
2009-12-28 21:10:04 +01:00
|
|
|
GtkTreePath *drop_path,
|
2003-03-19 15:17:13 +00:00
|
|
|
GtkTreeViewDropPosition drop_pos,
|
2004-06-28 22:07:12 +00:00
|
|
|
GtkTreeViewDropPosition *return_drop_pos,
|
|
|
|
GdkDragAction *return_drag_action)
|
|
|
|
{
|
2018-04-25 14:31:11 -04:00
|
|
|
/* If we are dropping a new layer, check if the destination image
|
2005-05-06 20:45:21 +00:00
|
|
|
* has a floating selection.
|
|
|
|
*/
|
2004-06-28 22:07:12 +00:00
|
|
|
if (src_type == GIMP_DND_TYPE_URI_LIST ||
|
|
|
|
src_type == GIMP_DND_TYPE_TEXT_PLAIN ||
|
|
|
|
src_type == GIMP_DND_TYPE_NETSCAPE_URL ||
|
2005-01-15 17:57:32 +00:00
|
|
|
src_type == GIMP_DND_TYPE_COMPONENT ||
|
2005-04-09 17:56:04 +00:00
|
|
|
src_type == GIMP_DND_TYPE_PIXBUF ||
|
2020-03-24 22:06:28 +01:00
|
|
|
g_list_length (src_viewables) > 0)
|
2004-06-28 22:07:12 +00:00
|
|
|
{
|
2008-12-25 11:31:51 +00:00
|
|
|
GimpImage *dest_image = gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (tree_view));
|
2004-06-28 22:07:12 +00:00
|
|
|
|
2008-11-14 15:01:44 +00:00
|
|
|
if (gimp_image_get_floating_selection (dest_image))
|
2004-06-28 22:07:12 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-01-17 15:28:08 +00:00
|
|
|
return GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_possible (tree_view,
|
|
|
|
src_type,
|
2020-03-24 22:06:28 +01:00
|
|
|
src_viewables,
|
2005-01-17 15:28:08 +00:00
|
|
|
dest_viewable,
|
2009-12-28 21:10:04 +01:00
|
|
|
drop_path,
|
2005-01-17 15:28:08 +00:00
|
|
|
drop_pos,
|
|
|
|
return_drop_pos,
|
|
|
|
return_drag_action);
|
2004-06-28 22:07:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_drop_color (GimpContainerTreeView *view,
|
|
|
|
const GimpRGB *color,
|
|
|
|
GimpViewable *dest_viewable,
|
|
|
|
GtkTreeViewDropPosition drop_pos)
|
|
|
|
{
|
2010-10-05 07:39:00 +02:00
|
|
|
if (gimp_item_is_text_layer (GIMP_ITEM (dest_viewable)))
|
2004-06-28 22:07:12 +00:00
|
|
|
{
|
|
|
|
gimp_text_layer_set (GIMP_TEXT_LAYER (dest_viewable), NULL,
|
|
|
|
"color", color,
|
|
|
|
NULL);
|
2008-12-25 11:31:51 +00:00
|
|
|
gimp_image_flush (gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (view)));
|
2005-01-17 15:28:08 +00:00
|
|
|
return;
|
2004-06-28 22:07:12 +00:00
|
|
|
}
|
|
|
|
|
2005-01-17 15:28:08 +00:00
|
|
|
GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_color (view, color,
|
|
|
|
dest_viewable,
|
|
|
|
drop_pos);
|
2004-06-28 22:07:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-06-30 14:47:23 +00:00
|
|
|
gimp_layer_tree_view_drop_uri_list (GimpContainerTreeView *view,
|
|
|
|
GList *uri_list,
|
|
|
|
GimpViewable *dest_viewable,
|
|
|
|
GtkTreeViewDropPosition drop_pos)
|
2003-03-19 15:17:13 +00:00
|
|
|
{
|
2006-08-31 21:40:16 +00:00
|
|
|
GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (view);
|
|
|
|
GimpContainerView *cont_view = GIMP_CONTAINER_VIEW (view);
|
2008-12-25 11:31:51 +00:00
|
|
|
GimpImage *image = gimp_item_tree_view_get_image (item_view);
|
2009-08-03 19:21:51 +02:00
|
|
|
GimpLayer *parent;
|
|
|
|
gint index;
|
2006-08-31 21:40:16 +00:00
|
|
|
GList *list;
|
2004-06-28 22:07:12 +00:00
|
|
|
|
2009-08-03 19:21:51 +02:00
|
|
|
index = gimp_item_tree_view_get_drop_index (item_view, dest_viewable,
|
|
|
|
drop_pos,
|
|
|
|
(GimpViewable **) &parent);
|
2004-06-28 22:07:12 +00:00
|
|
|
|
2019-01-03 16:46:00 +01:00
|
|
|
g_object_ref (image);
|
|
|
|
|
2004-06-30 14:47:23 +00:00
|
|
|
for (list = uri_list; list; list = g_list_next (list))
|
2004-06-28 22:07:12 +00:00
|
|
|
{
|
|
|
|
const gchar *uri = list->data;
|
2014-07-07 00:46:25 +02:00
|
|
|
GFile *file = g_file_new_for_uri (uri);
|
2006-11-03 17:12:27 +00:00
|
|
|
GList *new_layers;
|
2004-06-28 22:07:12 +00:00
|
|
|
GimpPDBStatusType status;
|
|
|
|
GError *error = NULL;
|
|
|
|
|
2006-11-03 17:12:27 +00:00
|
|
|
new_layers = file_open_layers (image->gimp,
|
|
|
|
gimp_container_view_get_context (cont_view),
|
|
|
|
NULL,
|
|
|
|
image, FALSE,
|
2014-07-07 00:46:25 +02:00
|
|
|
file, GIMP_RUN_INTERACTIVE, NULL,
|
2006-11-03 17:12:27 +00:00
|
|
|
&status, &error);
|
2004-06-28 22:07:12 +00:00
|
|
|
|
2006-11-03 17:12:27 +00:00
|
|
|
if (new_layers)
|
2004-06-28 22:07:12 +00:00
|
|
|
{
|
2009-08-03 19:21:51 +02:00
|
|
|
gimp_image_add_layers (image, new_layers, parent, index,
|
2006-11-03 19:59:30 +00:00
|
|
|
0, 0,
|
|
|
|
gimp_image_get_width (image),
|
|
|
|
gimp_image_get_height (image),
|
|
|
|
_("Drop layers"));
|
2004-06-28 22:07:12 +00:00
|
|
|
|
2006-11-03 19:59:30 +00:00
|
|
|
index += g_list_length (new_layers);
|
2004-06-28 22:07:12 +00:00
|
|
|
|
2006-11-03 17:12:27 +00:00
|
|
|
g_list_free (new_layers);
|
2004-06-28 22:07:12 +00:00
|
|
|
}
|
|
|
|
else if (status != GIMP_PDB_CANCEL)
|
|
|
|
{
|
2007-05-21 16:32:52 +00:00
|
|
|
gimp_message (image->gimp, G_OBJECT (view), GIMP_MESSAGE_ERROR,
|
2006-10-09 18:49:15 +00:00
|
|
|
_("Opening '%s' failed:\n\n%s"),
|
2014-07-07 00:46:25 +02:00
|
|
|
gimp_file_get_utf8_name (file), error->message);
|
2004-06-28 22:07:12 +00:00
|
|
|
g_clear_error (&error);
|
|
|
|
}
|
2014-07-07 00:46:25 +02:00
|
|
|
|
|
|
|
g_object_unref (file);
|
2004-06-28 22:07:12 +00:00
|
|
|
}
|
|
|
|
|
2006-03-28 17:08:36 +00:00
|
|
|
gimp_image_flush (image);
|
2019-01-03 16:46:00 +01:00
|
|
|
|
|
|
|
g_object_unref (image);
|
2003-03-19 15:17:13 +00:00
|
|
|
}
|
|
|
|
|
2005-01-15 17:57:32 +00:00
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_drop_component (GimpContainerTreeView *tree_view,
|
|
|
|
GimpImage *src_image,
|
|
|
|
GimpChannelType component,
|
|
|
|
GimpViewable *dest_viewable,
|
|
|
|
GtkTreeViewDropPosition drop_pos)
|
|
|
|
{
|
2005-01-17 15:28:08 +00:00
|
|
|
GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (tree_view);
|
2009-08-03 19:21:51 +02:00
|
|
|
GimpImage *image = gimp_item_tree_view_get_image (item_view);
|
2005-01-15 17:57:32 +00:00
|
|
|
GimpChannel *channel;
|
2005-01-17 15:28:08 +00:00
|
|
|
GimpItem *new_item;
|
2009-08-03 19:21:51 +02:00
|
|
|
GimpLayer *parent;
|
|
|
|
gint index;
|
2005-01-15 17:57:32 +00:00
|
|
|
const gchar *desc;
|
|
|
|
|
2009-08-03 19:21:51 +02:00
|
|
|
index = gimp_item_tree_view_get_drop_index (item_view, dest_viewable,
|
|
|
|
drop_pos,
|
|
|
|
(GimpViewable **) &parent);
|
2005-01-15 17:57:32 +00:00
|
|
|
|
|
|
|
channel = gimp_channel_new_from_component (src_image, component, NULL, NULL);
|
|
|
|
|
2009-08-03 19:21:51 +02:00
|
|
|
new_item = gimp_item_convert (GIMP_ITEM (channel), image,
|
2008-01-08 11:46:15 +00:00
|
|
|
GIMP_TYPE_LAYER);
|
2005-01-15 17:57:32 +00:00
|
|
|
|
|
|
|
g_object_unref (channel);
|
|
|
|
|
|
|
|
gimp_enum_get_value (GIMP_TYPE_CHANNEL_TYPE, component,
|
|
|
|
NULL, NULL, &desc, NULL);
|
2006-04-07 10:51:22 +00:00
|
|
|
gimp_object_take_name (GIMP_OBJECT (new_item),
|
|
|
|
g_strdup_printf (_("%s Channel Copy"), desc));
|
2005-01-15 17:57:32 +00:00
|
|
|
|
2009-08-03 19:21:51 +02:00
|
|
|
gimp_image_add_layer (image, GIMP_LAYER (new_item), parent, index, TRUE);
|
|
|
|
|
|
|
|
gimp_image_flush (image);
|
2005-01-15 17:57:32 +00:00
|
|
|
}
|
|
|
|
|
2005-04-09 17:56:04 +00:00
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_drop_pixbuf (GimpContainerTreeView *tree_view,
|
|
|
|
GdkPixbuf *pixbuf,
|
|
|
|
GimpViewable *dest_viewable,
|
|
|
|
GtkTreeViewDropPosition drop_pos)
|
|
|
|
{
|
|
|
|
GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (tree_view);
|
2008-12-25 11:31:51 +00:00
|
|
|
GimpImage *image = gimp_item_tree_view_get_image (item_view);
|
2005-04-09 17:56:04 +00:00
|
|
|
GimpLayer *new_layer;
|
2009-08-03 19:21:51 +02:00
|
|
|
GimpLayer *parent;
|
|
|
|
gint index;
|
2005-04-09 17:56:04 +00:00
|
|
|
|
2009-08-03 19:21:51 +02:00
|
|
|
index = gimp_item_tree_view_get_drop_index (item_view, dest_viewable,
|
|
|
|
drop_pos,
|
|
|
|
(GimpViewable **) &parent);
|
2005-04-09 17:56:04 +00:00
|
|
|
|
|
|
|
new_layer =
|
|
|
|
gimp_layer_new_from_pixbuf (pixbuf, image,
|
2012-04-07 00:46:59 +02:00
|
|
|
gimp_image_get_layer_format (image, TRUE),
|
2005-04-09 17:56:04 +00:00
|
|
|
_("Dropped Buffer"),
|
2017-01-08 23:00:19 +01:00
|
|
|
GIMP_OPACITY_OPAQUE,
|
2017-08-21 20:04:25 +02:00
|
|
|
gimp_image_get_default_new_layer_mode (image));
|
2005-04-09 17:56:04 +00:00
|
|
|
|
2009-08-03 19:21:51 +02:00
|
|
|
gimp_image_add_layer (image, new_layer, parent, index, TRUE);
|
|
|
|
|
2005-04-09 17:56:04 +00:00
|
|
|
gimp_image_flush (image);
|
|
|
|
}
|
|
|
|
|
2003-03-19 15:17:13 +00:00
|
|
|
|
2003-03-16 13:19:43 +00:00
|
|
|
/* GimpItemTreeView methods */
|
|
|
|
|
2003-09-06 21:17:16 +00:00
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_set_image (GimpItemTreeView *view,
|
2006-03-28 17:08:36 +00:00
|
|
|
GimpImage *image)
|
2003-09-06 21:17:16 +00:00
|
|
|
{
|
2018-03-07 10:42:00 -05:00
|
|
|
GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view);
|
|
|
|
|
2008-12-25 11:31:51 +00:00
|
|
|
if (gimp_item_tree_view_get_image (view))
|
2018-03-07 10:42:00 -05:00
|
|
|
{
|
|
|
|
g_signal_handlers_disconnect_by_func (gimp_item_tree_view_get_image (view),
|
|
|
|
gimp_layer_tree_view_floating_selection_changed,
|
|
|
|
view);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
g_signal_handlers_disconnect_by_func (gimp_item_tree_view_get_image (view),
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_layer_links_changed),
|
|
|
|
view);
|
2018-03-07 10:42:00 -05:00
|
|
|
}
|
2003-09-06 21:17:16 +00:00
|
|
|
|
2006-03-28 17:08:36 +00:00
|
|
|
GIMP_ITEM_TREE_VIEW_CLASS (parent_class)->set_image (view, image);
|
2003-09-06 21:17:16 +00:00
|
|
|
|
2008-12-25 11:31:51 +00:00
|
|
|
if (gimp_item_tree_view_get_image (view))
|
2018-03-07 10:42:00 -05:00
|
|
|
{
|
|
|
|
g_signal_connect (gimp_item_tree_view_get_image (view),
|
|
|
|
"floating-selection-changed",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_floating_selection_changed),
|
|
|
|
view);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
g_signal_connect (gimp_item_tree_view_get_image (view),
|
2021-12-16 00:35:20 +01:00
|
|
|
"layer-sets-changed",
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
G_CALLBACK (gimp_layer_tree_view_layer_links_changed),
|
|
|
|
view);
|
2018-03-07 10:42:00 -05:00
|
|
|
|
|
|
|
/* call gimp_layer_tree_view_floating_selection_changed() now, to update
|
|
|
|
* the floating selection's row attributes.
|
|
|
|
*/
|
|
|
|
gimp_layer_tree_view_floating_selection_changed (
|
|
|
|
gimp_item_tree_view_get_image (view),
|
|
|
|
layer_view);
|
|
|
|
}
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
/* Call this even with no image, allowing to empty the link list. */
|
|
|
|
gimp_layer_tree_view_layer_links_changed (gimp_item_tree_view_get_image (view),
|
|
|
|
layer_view);
|
2018-03-07 10:42:00 -05:00
|
|
|
|
|
|
|
gimp_layer_tree_view_update_highlight (layer_view);
|
2003-09-06 21:17:16 +00:00
|
|
|
}
|
|
|
|
|
2004-10-16 15:48:23 +00:00
|
|
|
static GimpItem *
|
|
|
|
gimp_layer_tree_view_item_new (GimpImage *image)
|
2003-03-16 13:19:43 +00:00
|
|
|
{
|
2012-04-07 00:46:59 +02:00
|
|
|
GimpLayer *new_layer;
|
2004-10-16 15:48:23 +00:00
|
|
|
|
|
|
|
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
|
|
|
|
_("New Layer"));
|
|
|
|
|
|
|
|
new_layer = gimp_layer_new (image,
|
|
|
|
gimp_image_get_width (image),
|
|
|
|
gimp_image_get_height (image),
|
2012-04-07 00:46:59 +02:00
|
|
|
gimp_image_get_layer_format (image, TRUE),
|
2017-01-08 23:00:19 +01:00
|
|
|
NULL,
|
|
|
|
GIMP_OPACITY_OPAQUE,
|
2017-08-21 20:04:25 +02:00
|
|
|
gimp_image_get_default_new_layer_mode (image));
|
2004-10-16 15:48:23 +00:00
|
|
|
|
2009-08-03 22:30:36 +02:00
|
|
|
gimp_image_add_layer (image, new_layer,
|
|
|
|
GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
|
2004-10-16 15:48:23 +00:00
|
|
|
|
|
|
|
gimp_image_undo_group_end (image);
|
|
|
|
|
|
|
|
return GIMP_ITEM (new_layer);
|
2003-03-16 13:19:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-09-06 21:17:16 +00:00
|
|
|
/* callbacks */
|
|
|
|
|
|
|
|
static void
|
2006-03-28 17:08:36 +00:00
|
|
|
gimp_layer_tree_view_floating_selection_changed (GimpImage *image,
|
2003-09-06 21:17:16 +00:00
|
|
|
GimpLayerTreeView *layer_view)
|
|
|
|
{
|
2004-05-10 23:22:39 +00:00
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (layer_view);
|
|
|
|
GimpContainerView *view = GIMP_CONTAINER_VIEW (layer_view);
|
|
|
|
GimpLayer *floating_sel;
|
|
|
|
GtkTreeIter *iter;
|
2004-05-10 17:16:50 +00:00
|
|
|
|
2008-11-14 15:01:44 +00:00
|
|
|
floating_sel = gimp_image_get_floating_selection (image);
|
2003-09-06 21:17:16 +00:00
|
|
|
|
|
|
|
if (floating_sel)
|
|
|
|
{
|
2004-05-10 23:22:39 +00:00
|
|
|
iter = gimp_container_view_lookup (view, (GimpViewable *) floating_sel);
|
2003-09-06 21:17:16 +00:00
|
|
|
|
|
|
|
if (iter)
|
2009-07-25 17:38:03 +02:00
|
|
|
gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter,
|
2010-05-17 21:28:17 +02:00
|
|
|
GIMP_CONTAINER_TREE_STORE_COLUMN_NAME_ATTRIBUTES,
|
2008-12-25 12:12:33 +00:00
|
|
|
layer_view->priv->italic_attrs,
|
2003-09-06 21:17:16 +00:00
|
|
|
-1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-08-01 23:07:07 +02:00
|
|
|
GList *all_layers;
|
2003-09-06 21:17:16 +00:00
|
|
|
GList *list;
|
|
|
|
|
2009-08-01 23:07:07 +02:00
|
|
|
all_layers = gimp_image_get_layer_list (image);
|
|
|
|
|
|
|
|
for (list = all_layers; list; list = g_list_next (list))
|
2003-09-06 21:17:16 +00:00
|
|
|
{
|
|
|
|
GimpDrawable *drawable = list->data;
|
|
|
|
|
2005-09-08 19:38:58 +00:00
|
|
|
iter = gimp_container_view_lookup (view, (GimpViewable *) drawable);
|
|
|
|
|
|
|
|
if (iter)
|
2009-07-25 17:38:03 +02:00
|
|
|
gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter,
|
2010-05-17 21:28:17 +02:00
|
|
|
GIMP_CONTAINER_TREE_STORE_COLUMN_NAME_ATTRIBUTES,
|
2005-09-08 19:38:58 +00:00
|
|
|
gimp_drawable_has_alpha (drawable) ?
|
2008-12-25 12:12:33 +00:00
|
|
|
NULL : layer_view->priv->bold_attrs,
|
2005-09-08 19:38:58 +00:00
|
|
|
-1);
|
2003-09-06 21:17:16 +00:00
|
|
|
}
|
2009-08-01 23:07:07 +02:00
|
|
|
|
|
|
|
g_list_free (all_layers);
|
2003-09-06 21:17:16 +00:00
|
|
|
}
|
2018-03-07 05:42:26 -05:00
|
|
|
|
2018-03-07 10:42:00 -05:00
|
|
|
gimp_layer_tree_view_update_highlight (layer_view);
|
2003-09-06 21:17:16 +00:00
|
|
|
}
|
2001-03-11 17:24:47 +00:00
|
|
|
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_layer_links_changed (GimpImage *image,
|
|
|
|
GimpLayerTreeView *view)
|
|
|
|
{
|
|
|
|
GtkWidget *grid;
|
|
|
|
GtkWidget *label;
|
|
|
|
GtkWidget *event_box;
|
|
|
|
GtkWidget *icon;
|
|
|
|
GtkSizeGroup *label_size;
|
|
|
|
GList *links;
|
|
|
|
GList *iter;
|
|
|
|
|
|
|
|
gtk_container_foreach (GTK_CONTAINER (view->priv->link_list),
|
|
|
|
(GtkCallback) gtk_widget_destroy, NULL);
|
|
|
|
gtk_widget_set_sensitive (view->priv->link_button, image != NULL);
|
|
|
|
|
|
|
|
if (! image)
|
|
|
|
return;
|
|
|
|
|
2021-12-16 00:35:20 +01:00
|
|
|
links = gimp_image_get_stored_item_sets (image, GIMP_TYPE_LAYER);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
|
|
|
|
label_size = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
|
|
|
|
for (iter = links; iter; iter = iter->next)
|
|
|
|
{
|
2021-12-23 02:27:39 +01:00
|
|
|
GimpSelectMethod method;
|
|
|
|
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
grid = gtk_grid_new ();
|
|
|
|
|
2021-02-07 00:21:27 +01:00
|
|
|
label = gtk_label_new (gimp_object_get_name (iter->data));
|
|
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
2021-12-23 02:27:39 +01:00
|
|
|
if (gimp_item_list_is_pattern (iter->data, &method))
|
2021-02-07 00:21:27 +01:00
|
|
|
{
|
2021-12-23 02:27:39 +01:00
|
|
|
gchar *display_name;
|
|
|
|
PangoAttrList *attrs;
|
|
|
|
|
|
|
|
display_name = g_strdup_printf ("<small>[%s]</small> %s",
|
|
|
|
method == GIMP_SELECT_PLAIN_TEXT ? _("search") :
|
|
|
|
(method == GIMP_SELECT_GLOB_PATTERN ? _("glob") : _("regexp")),
|
|
|
|
gimp_object_get_name (iter->data));
|
|
|
|
gtk_label_set_markup (GTK_LABEL (label), display_name);
|
|
|
|
g_free (display_name);
|
2021-02-07 00:21:27 +01:00
|
|
|
|
2021-12-23 02:27:39 +01:00
|
|
|
attrs = pango_attr_list_new ();
|
2021-02-07 00:21:27 +01:00
|
|
|
pango_attr_list_insert (attrs, pango_attr_style_new (PANGO_STYLE_OBLIQUE));
|
|
|
|
gtk_label_set_attributes (GTK_LABEL (label), attrs);
|
|
|
|
pango_attr_list_unref (attrs);
|
|
|
|
}
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
gtk_widget_set_hexpand (GTK_WIDGET (label), TRUE);
|
|
|
|
gtk_widget_set_halign (GTK_WIDGET (label), GTK_ALIGN_START);
|
|
|
|
gtk_size_group_add_widget (label_size, label);
|
|
|
|
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
/* I don't use a GtkButton because the minimum size is 16 which is
|
|
|
|
* weird and ugly here. And somehow if I force smaller GtkImage
|
|
|
|
* size then add it to the GtkButton, I still get a giant button
|
|
|
|
* with a small image in it, which is even worse. XXX
|
|
|
|
*/
|
|
|
|
event_box = gtk_event_box_new ();
|
|
|
|
gtk_event_box_set_above_child (GTK_EVENT_BOX (event_box), TRUE);
|
|
|
|
gtk_widget_add_events (event_box, GDK_BUTTON_RELEASE_MASK);
|
2021-02-07 00:21:27 +01:00
|
|
|
g_object_set_data (G_OBJECT (event_box), "link-set", iter->data);
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
g_signal_connect (event_box, "button-release-event",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_unlink_clicked),
|
|
|
|
view);
|
|
|
|
gtk_grid_attach (GTK_GRID (grid), event_box, 2, 0, 1, 1);
|
|
|
|
gtk_widget_show (event_box);
|
|
|
|
|
|
|
|
icon = gtk_image_new_from_icon_name (GIMP_ICON_EDIT_DELETE, GTK_ICON_SIZE_MENU);
|
|
|
|
gtk_image_set_pixel_size (GTK_IMAGE (icon), 10);
|
|
|
|
gtk_container_add (GTK_CONTAINER (event_box), icon);
|
|
|
|
gtk_widget_show (icon);
|
|
|
|
|
2021-02-04 21:26:34 +01:00
|
|
|
/* Now using again an event box on the whole grid, but behind its
|
|
|
|
* child (so that the delete button is processed first. I do it
|
|
|
|
* this way instead of using the "row-activated" of GtkListBox
|
|
|
|
* because this signal does not give us event info, and in
|
|
|
|
* particular modifier state. Yet I want to be able to process
|
|
|
|
* Shift/Ctrl state for logical operations on layer sets.
|
|
|
|
*/
|
|
|
|
event_box = gtk_event_box_new ();
|
|
|
|
gtk_event_box_set_above_child (GTK_EVENT_BOX (event_box), FALSE);
|
|
|
|
gtk_widget_add_events (event_box, GDK_BUTTON_RELEASE_MASK);
|
2021-02-07 00:21:27 +01:00
|
|
|
g_object_set_data (G_OBJECT (event_box), "link-set", iter->data);
|
2021-02-04 21:26:34 +01:00
|
|
|
gtk_container_add (GTK_CONTAINER (event_box), grid);
|
|
|
|
gtk_list_box_prepend (GTK_LIST_BOX (view->priv->link_list), event_box);
|
|
|
|
gtk_widget_show (event_box);
|
|
|
|
|
|
|
|
g_signal_connect (event_box,
|
|
|
|
"button-release-event",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_link_clicked),
|
|
|
|
view);
|
|
|
|
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
gtk_widget_show (grid);
|
|
|
|
}
|
|
|
|
g_object_unref (label_size);
|
|
|
|
gtk_list_box_unselect_all (GTK_LIST_BOX (view->priv->link_list));
|
|
|
|
}
|
|
|
|
|
2021-02-04 21:26:34 +01:00
|
|
|
static gboolean
|
|
|
|
gimp_layer_tree_view_link_clicked (GtkWidget *box,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpLayerTreeView *view)
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
{
|
2021-02-04 21:26:34 +01:00
|
|
|
GimpImage *image;
|
|
|
|
GdkEventButton *bevent = (GdkEventButton *) event;
|
|
|
|
GdkModifierType modifiers;
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
|
|
|
|
image = gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (view));
|
|
|
|
|
2021-02-04 21:26:34 +01:00
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
|
|
|
|
g_return_val_if_fail (GTK_IS_EVENT_BOX (box), FALSE);
|
|
|
|
|
|
|
|
modifiers = bevent->state & gimp_get_all_modifiers_mask ();
|
|
|
|
if (modifiers == GDK_SHIFT_MASK)
|
2021-02-07 00:21:27 +01:00
|
|
|
gimp_image_add_item_set (image, g_object_get_data (G_OBJECT (box), "link-set"));
|
2021-02-04 21:26:34 +01:00
|
|
|
else if (modifiers == GDK_CONTROL_MASK)
|
2021-02-07 00:21:27 +01:00
|
|
|
gimp_image_remove_item_set (image, g_object_get_data (G_OBJECT (box), "link-set"));
|
2021-02-04 21:26:34 +01:00
|
|
|
else if (modifiers == (GDK_CONTROL_MASK | GDK_SHIFT_MASK))
|
2021-02-07 00:21:27 +01:00
|
|
|
gimp_image_intersect_item_set (image, g_object_get_data (G_OBJECT (box), "link-set"));
|
2021-02-04 21:26:34 +01:00
|
|
|
else
|
2021-02-07 00:21:27 +01:00
|
|
|
gimp_image_select_item_set (image, g_object_get_data (G_OBJECT (box), "link-set"));
|
|
|
|
|
2021-12-23 01:55:20 +01:00
|
|
|
gtk_entry_set_text (GTK_ENTRY (view->priv->link_search_entry), "");
|
2021-02-07 00:21:27 +01:00
|
|
|
/* TODO: if clicking on pattern link, fill in the pattern field? */
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
|
2021-02-04 21:26:34 +01:00
|
|
|
return FALSE;
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
}
|
|
|
|
|
2021-10-05 01:56:51 +02:00
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_link_popover_shown (GtkPopover *popover,
|
|
|
|
GimpLayerTreeView *view)
|
|
|
|
{
|
|
|
|
GimpImage *image;
|
|
|
|
GimpSelectMethod pattern_syntax;
|
|
|
|
|
|
|
|
image = gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (view));
|
|
|
|
|
|
|
|
if (! image)
|
|
|
|
{
|
2021-12-23 01:55:20 +01:00
|
|
|
gtk_widget_set_tooltip_text (view->priv->link_search_entry,
|
2021-10-05 01:56:51 +02:00
|
|
|
_("Select layers by text search"));
|
2021-12-23 01:55:20 +01:00
|
|
|
gtk_entry_set_placeholder_text (GTK_ENTRY (view->priv->link_search_entry),
|
2021-10-05 01:56:51 +02:00
|
|
|
_("Text search"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_object_get (image->gimp->config,
|
|
|
|
"items-select-method", &pattern_syntax,
|
|
|
|
NULL);
|
|
|
|
switch (pattern_syntax)
|
|
|
|
{
|
|
|
|
case GIMP_SELECT_PLAIN_TEXT:
|
2021-12-23 01:55:20 +01:00
|
|
|
gtk_widget_set_tooltip_text (view->priv->link_search_entry,
|
2021-10-05 01:56:51 +02:00
|
|
|
_("Select layers by text search"));
|
2021-12-23 01:55:20 +01:00
|
|
|
gtk_entry_set_placeholder_text (GTK_ENTRY (view->priv->link_search_entry),
|
2021-10-05 01:56:51 +02:00
|
|
|
_("Text search"));
|
|
|
|
break;
|
|
|
|
case GIMP_SELECT_GLOB_PATTERN:
|
2021-12-23 01:55:20 +01:00
|
|
|
gtk_widget_set_tooltip_text (view->priv->link_search_entry,
|
2021-10-05 01:56:51 +02:00
|
|
|
_("Select layers by glob patterns"));
|
2021-12-23 01:55:20 +01:00
|
|
|
gtk_entry_set_placeholder_text (GTK_ENTRY (view->priv->link_search_entry),
|
2021-10-05 01:56:51 +02:00
|
|
|
_("Glob pattern search"));
|
|
|
|
break;
|
|
|
|
case GIMP_SELECT_REGEX_PATTERN:
|
2021-12-23 01:55:20 +01:00
|
|
|
gtk_widget_set_tooltip_text (view->priv->link_search_entry,
|
2021-10-05 01:56:51 +02:00
|
|
|
_("Select layers by regular expressions"));
|
2021-12-23 01:55:20 +01:00
|
|
|
gtk_entry_set_placeholder_text (GTK_ENTRY (view->priv->link_search_entry),
|
2021-10-05 01:56:51 +02:00
|
|
|
_("Regular Expression search"));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-23 01:55:20 +01:00
|
|
|
static gboolean
|
|
|
|
gimp_layer_tree_view_search_key_release (GtkWidget *widget,
|
|
|
|
GdkEventKey *event,
|
|
|
|
GimpLayerTreeView *view)
|
2021-02-06 16:10:22 +01:00
|
|
|
{
|
2021-10-05 01:56:51 +02:00
|
|
|
GimpImage *image;
|
|
|
|
const gchar *pattern;
|
|
|
|
GimpSelectMethod pattern_syntax;
|
2021-02-06 16:10:22 +01:00
|
|
|
|
2021-12-23 01:55:20 +01:00
|
|
|
if (event->keyval == GDK_KEY_Escape ||
|
|
|
|
event->keyval == GDK_KEY_Return ||
|
|
|
|
event->keyval == GDK_KEY_KP_Enter ||
|
|
|
|
event->keyval == GDK_KEY_ISO_Enter)
|
|
|
|
{
|
|
|
|
if (event->state & GDK_SHIFT_MASK)
|
|
|
|
{
|
|
|
|
if (gimp_layer_tree_view_new_link_clicked (view))
|
|
|
|
gtk_widget_hide (view->priv->link_popover);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_widget_hide (view->priv->link_popover);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_entry_set_attributes (GTK_ENTRY (view->priv->link_search_entry),
|
2021-02-06 16:10:22 +01:00
|
|
|
NULL);
|
2021-10-05 01:56:51 +02:00
|
|
|
|
2021-02-06 16:10:22 +01:00
|
|
|
image = gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (view));
|
2021-12-23 01:55:20 +01:00
|
|
|
g_clear_object (&view->priv->link_pattern_set);
|
2021-02-06 16:10:22 +01:00
|
|
|
|
|
|
|
if (! image)
|
2021-12-23 01:55:20 +01:00
|
|
|
return TRUE;
|
2021-02-06 16:10:22 +01:00
|
|
|
|
2021-10-05 01:56:51 +02:00
|
|
|
g_object_get (image->gimp->config,
|
|
|
|
"items-select-method", &pattern_syntax,
|
|
|
|
NULL);
|
2021-12-23 01:55:20 +01:00
|
|
|
pattern = gtk_entry_get_text (GTK_ENTRY (view->priv->link_search_entry));
|
2021-02-06 16:10:22 +01:00
|
|
|
if (pattern && strlen (pattern) > 0)
|
|
|
|
{
|
2021-10-05 01:56:51 +02:00
|
|
|
GList *items;
|
|
|
|
GError *error = NULL;
|
2021-02-06 16:10:22 +01:00
|
|
|
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (view->priv->link_entry), "");
|
|
|
|
gtk_widget_set_sensitive (view->priv->link_entry, FALSE);
|
2021-02-07 00:21:27 +01:00
|
|
|
|
2021-12-23 01:55:20 +01:00
|
|
|
view->priv->link_pattern_set = gimp_item_list_pattern_new (image,
|
|
|
|
GIMP_TYPE_LAYER,
|
|
|
|
pattern_syntax,
|
|
|
|
pattern);
|
|
|
|
items = gimp_item_list_get_items (view->priv->link_pattern_set, &error);
|
2021-02-07 00:21:27 +01:00
|
|
|
if (error)
|
2021-02-06 16:10:22 +01:00
|
|
|
{
|
2021-02-07 00:21:27 +01:00
|
|
|
/* Invalid regular expression. */
|
|
|
|
PangoAttrList *attrs = pango_attr_list_new ();
|
|
|
|
gchar *tooltip;
|
|
|
|
|
|
|
|
pango_attr_list_insert (attrs, pango_attr_strikethrough_new (TRUE));
|
|
|
|
tooltip = g_strdup_printf (_("Invalid regular expression: %s\n"),
|
|
|
|
error->message);
|
2021-12-23 01:55:20 +01:00
|
|
|
gtk_widget_set_tooltip_text (view->priv->link_search_entry,
|
2021-02-07 00:21:27 +01:00
|
|
|
tooltip);
|
2021-12-23 02:06:06 +01:00
|
|
|
gimp_image_set_selected_layers (image, NULL);
|
2021-12-23 01:55:20 +01:00
|
|
|
gtk_entry_set_attributes (GTK_ENTRY (view->priv->link_search_entry),
|
2021-02-07 00:21:27 +01:00
|
|
|
attrs);
|
|
|
|
g_free (tooltip);
|
|
|
|
g_error_free (error);
|
|
|
|
pango_attr_list_unref (attrs);
|
|
|
|
|
2021-12-23 01:55:20 +01:00
|
|
|
g_clear_object (&view->priv->link_pattern_set);
|
2021-02-07 00:21:27 +01:00
|
|
|
}
|
|
|
|
else if (items == NULL)
|
|
|
|
{
|
|
|
|
/* Pattern does not match any results. */
|
2021-12-23 02:06:06 +01:00
|
|
|
gimp_image_set_selected_layers (image, NULL);
|
2021-12-23 01:55:20 +01:00
|
|
|
gimp_widget_blink (view->priv->link_search_entry);
|
2021-02-07 00:21:27 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gimp_image_set_selected_layers (image, items);
|
|
|
|
g_list_free (items);
|
2021-02-06 16:10:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_widget_set_sensitive (view->priv->link_entry, TRUE);
|
|
|
|
}
|
2021-12-23 01:55:20 +01:00
|
|
|
|
|
|
|
return TRUE;
|
2021-02-06 16:10:22 +01:00
|
|
|
}
|
|
|
|
|
2022-11-28 21:48:53 +01:00
|
|
|
static gboolean
|
|
|
|
gimp_layer_tree_view_start_interactive_search (GtkTreeView *tree_view,
|
|
|
|
GimpLayerTreeView *layer_view)
|
|
|
|
{
|
|
|
|
gtk_widget_show (layer_view->priv->link_popover);
|
|
|
|
gtk_widget_grab_focus (layer_view->priv->link_search_entry);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
static void
|
2021-02-07 00:21:27 +01:00
|
|
|
gimp_layer_tree_view_new_link_exit (GimpLayerTreeView *view)
|
|
|
|
{
|
|
|
|
if (gimp_layer_tree_view_new_link_clicked (view))
|
2022-02-02 16:20:28 +01:00
|
|
|
gtk_widget_hide (view->priv->link_popover);
|
2021-02-07 00:21:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_layer_tree_view_new_link_clicked (GimpLayerTreeView *view)
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
{
|
|
|
|
GimpImage *image;
|
|
|
|
const gchar *name;
|
|
|
|
|
|
|
|
image = gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (view));
|
|
|
|
|
|
|
|
if (! image)
|
2021-02-07 00:21:27 +01:00
|
|
|
return TRUE;
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
|
|
|
|
name = gtk_entry_get_text (GTK_ENTRY (view->priv->link_entry));
|
|
|
|
if (name && strlen (name) > 0)
|
|
|
|
{
|
2021-02-07 00:21:27 +01:00
|
|
|
GimpItemList *set;
|
|
|
|
|
|
|
|
set = gimp_item_list_named_new (image, GIMP_TYPE_LAYER, name, NULL);
|
|
|
|
if (set)
|
|
|
|
{
|
|
|
|
gimp_image_store_item_set (image, set);
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (view->priv->link_entry), "");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No existing selection. */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2021-12-23 01:55:20 +01:00
|
|
|
else if (view->priv->link_pattern_set != NULL)
|
2021-02-07 00:21:27 +01:00
|
|
|
{
|
2021-12-23 01:55:20 +01:00
|
|
|
gimp_image_store_item_set (image, view->priv->link_pattern_set);
|
|
|
|
view->priv->link_pattern_set = NULL;
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (view->priv->link_search_entry), "");
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gimp_widget_blink (view->priv->link_entry);
|
2021-12-23 01:55:20 +01:00
|
|
|
gimp_widget_blink (view->priv->link_search_entry);
|
2021-02-07 00:21:27 +01:00
|
|
|
|
|
|
|
return FALSE;
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
}
|
2021-02-07 00:21:27 +01:00
|
|
|
|
|
|
|
return TRUE;
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_layer_tree_view_unlink_clicked (GtkWidget *widget,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpLayerTreeView *view)
|
|
|
|
{
|
|
|
|
GimpImage *image;
|
|
|
|
|
|
|
|
image = gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (view));
|
|
|
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
|
|
|
|
|
2021-02-07 00:21:27 +01:00
|
|
|
gimp_image_unlink_item_set (image,
|
|
|
|
g_object_get_data (G_OBJECT (widget),
|
|
|
|
"link-set"));
|
app: new concept of sets of layers stored in GimpImage.
The eventual goal is to replace the "linked layers" concept, which is
why I am using similar vocabulary. The point is that linked layers are
mostly useless/redundant now with multiplie layer selection, except for
one thing: they kind of serve like a way to "save" a selection of layers
(to be moved/transformed together mostly). Apart from this, multiple
selection is more powerful on any way. You can do much more than
transforming the layers together (you can reorganize them together,
delete them, crop them and so on).
Therefore this new feature is the way to fill the only weakness of layer
selection: its ephemerality. Now we can save a given set of layers, not
even only one, but as many as we want, and under a meaningful name, for
later reuse.
Moreover it will make layer-handling core code much simpler as we
currently have 2 concepts of layer set: multiple selection and links.
The new stored links are only a way to recreate multiple selections.
More is to come, for instance right now, these are not stored in the XCF
format. Also it would be awesome to add logical operators (Shift for
union of layer sets, Ctrl for subtraction and Shift-Ctrl for
intersection). And finally I was thinking about a way to select by
pattern (regular expression? Shell-style glob patterns?) and even store
these patterns. So if you save a "Marmot .*" selection pattern, then
when you select it later, new layers matching this pattern will be
included too (instead of fixed-in-time list of layers).
2021-02-04 18:54:22 +01:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2005-07-10 21:17:22 +00:00
|
|
|
/* Paint Mode, Opacity and Lock alpha callbacks */
|
2001-03-11 17:24:47 +00:00
|
|
|
|
|
|
|
#define BLOCK() \
|
2003-01-05 22:07:10 +00:00
|
|
|
g_signal_handlers_block_by_func (layer, \
|
2004-08-25 22:31:44 +00:00
|
|
|
gimp_layer_tree_view_layer_signal_handler, view)
|
2001-03-11 17:24:47 +00:00
|
|
|
|
|
|
|
#define UNBLOCK() \
|
2003-01-05 22:07:10 +00:00
|
|
|
g_signal_handlers_unblock_by_func (layer, \
|
2004-08-25 22:31:44 +00:00
|
|
|
gimp_layer_tree_view_layer_signal_handler, view)
|
2001-03-11 17:24:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
2017-01-30 13:24:35 +01:00
|
|
|
gimp_layer_tree_view_layer_mode_box_callback (GtkWidget *widget,
|
|
|
|
const GParamSpec *pspec,
|
|
|
|
GimpLayerTreeView *view)
|
2001-03-11 17:24:47 +00:00
|
|
|
{
|
2020-04-29 02:12:00 +02:00
|
|
|
GimpImage *image;
|
|
|
|
GList *layers = NULL;
|
|
|
|
GList *iter;
|
|
|
|
GimpUndo *undo;
|
|
|
|
gboolean push_undo = TRUE;
|
|
|
|
gint n_layers = 0;
|
|
|
|
GimpLayerMode mode;
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2008-12-25 11:31:51 +00:00
|
|
|
image = gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (view));
|
2020-04-29 02:12:00 +02:00
|
|
|
mode = gimp_layer_mode_box_get_mode (GIMP_LAYER_MODE_BOX (widget));
|
|
|
|
undo = gimp_image_undo_can_compress (image, GIMP_TYPE_ITEM_UNDO,
|
|
|
|
GIMP_UNDO_LAYER_MODE);
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2006-03-28 17:08:36 +00:00
|
|
|
if (image)
|
2020-04-29 02:12:00 +02:00
|
|
|
layers = GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->get_selected_items (image);
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2020-04-29 02:12:00 +02:00
|
|
|
for (iter = layers; iter; iter = iter->next)
|
2001-03-11 17:24:47 +00:00
|
|
|
{
|
2020-04-29 02:12:00 +02:00
|
|
|
if (gimp_layer_get_mode (iter->data) != mode)
|
2004-08-25 22:31:44 +00:00
|
|
|
{
|
2020-04-29 02:12:00 +02:00
|
|
|
n_layers++;
|
2004-08-03 14:09:49 +00:00
|
|
|
|
2020-04-29 02:12:00 +02:00
|
|
|
if (undo && GIMP_ITEM_UNDO (undo)->item == GIMP_ITEM (iter->data))
|
2003-11-19 17:03:20 +00:00
|
|
|
push_undo = FALSE;
|
2020-04-29 02:12:00 +02:00
|
|
|
}
|
|
|
|
}
|
2003-11-19 17:03:20 +00:00
|
|
|
|
2020-04-29 02:12:00 +02:00
|
|
|
if (n_layers > 1)
|
|
|
|
{
|
|
|
|
/* Don't compress mode undos with more than 1 layer changed. */
|
|
|
|
push_undo = TRUE;
|
|
|
|
|
|
|
|
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_LAYER_OPACITY,
|
|
|
|
_("Set layers mode"));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (iter = layers; iter; iter = iter->next)
|
|
|
|
{
|
|
|
|
GimpLayer *layer = iter->data;
|
|
|
|
|
|
|
|
if (gimp_layer_get_mode (layer) != mode)
|
|
|
|
{
|
2004-08-25 22:31:44 +00:00
|
|
|
BLOCK();
|
2017-01-08 23:00:19 +01:00
|
|
|
gimp_layer_set_mode (layer, (GimpLayerMode) mode, push_undo);
|
2004-08-25 22:31:44 +00:00
|
|
|
UNBLOCK();
|
|
|
|
}
|
2001-03-11 17:24:47 +00:00
|
|
|
}
|
2020-04-29 02:12:00 +02:00
|
|
|
gimp_image_flush (image);
|
|
|
|
|
|
|
|
if (! push_undo)
|
|
|
|
gimp_undo_refresh_preview (undo, gimp_container_view_get_context (GIMP_CONTAINER_VIEW (view)));
|
|
|
|
|
|
|
|
if (n_layers > 1)
|
|
|
|
gimp_image_undo_group_end (image);
|
2001-03-11 17:24:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2003-03-16 11:14:29 +00:00
|
|
|
gimp_layer_tree_view_opacity_scale_changed (GtkAdjustment *adjustment,
|
2004-08-25 22:31:44 +00:00
|
|
|
GimpLayerTreeView *view)
|
2001-03-11 17:24:47 +00:00
|
|
|
{
|
2006-03-28 17:08:36 +00:00
|
|
|
GimpImage *image;
|
2020-04-29 02:12:00 +02:00
|
|
|
GList *layers;
|
|
|
|
GList *iter;
|
|
|
|
GimpUndo *undo;
|
|
|
|
gboolean push_undo = TRUE;
|
|
|
|
gint n_layers = 0;
|
|
|
|
gdouble opacity;
|
|
|
|
|
|
|
|
image = gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (view));
|
|
|
|
layers = GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->get_selected_items (image);
|
|
|
|
undo = gimp_image_undo_can_compress (image, GIMP_TYPE_ITEM_UNDO,
|
|
|
|
GIMP_UNDO_LAYER_OPACITY);
|
|
|
|
opacity = gtk_adjustment_get_value (adjustment) / 100.0;
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2020-04-29 02:12:00 +02:00
|
|
|
for (iter = layers; iter; iter = iter->next)
|
|
|
|
{
|
|
|
|
if (gimp_layer_get_opacity (iter->data) != opacity)
|
|
|
|
{
|
|
|
|
n_layers++;
|
|
|
|
|
|
|
|
if (undo && GIMP_ITEM_UNDO (undo)->item == GIMP_ITEM (iter->data))
|
|
|
|
push_undo = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (n_layers > 1)
|
|
|
|
{
|
|
|
|
/* Don't compress opacity undos with more than 1 layer changed. */
|
|
|
|
push_undo = TRUE;
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2020-04-29 02:12:00 +02:00
|
|
|
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_LAYER_OPACITY,
|
|
|
|
_("Set layers opacity"));
|
|
|
|
}
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2020-04-29 02:12:00 +02:00
|
|
|
for (iter = layers; iter; iter = iter->next)
|
2001-03-11 17:24:47 +00:00
|
|
|
{
|
2020-04-29 02:12:00 +02:00
|
|
|
GimpLayer *layer = iter->data;
|
2001-03-11 17:24:47 +00:00
|
|
|
|
|
|
|
if (gimp_layer_get_opacity (layer) != opacity)
|
2004-08-25 22:31:44 +00:00
|
|
|
{
|
|
|
|
BLOCK();
|
|
|
|
gimp_layer_set_opacity (layer, opacity, push_undo);
|
|
|
|
UNBLOCK();
|
|
|
|
}
|
2001-03-11 17:24:47 +00:00
|
|
|
}
|
2020-04-29 02:12:00 +02:00
|
|
|
gimp_image_flush (image);
|
|
|
|
|
|
|
|
if (! push_undo)
|
|
|
|
gimp_undo_refresh_preview (undo, gimp_container_view_get_context (GIMP_CONTAINER_VIEW (view)));
|
|
|
|
|
|
|
|
if (n_layers > 1)
|
|
|
|
gimp_image_undo_group_end (image);
|
2001-03-11 17:24:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#undef BLOCK
|
|
|
|
#undef UNBLOCK
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2003-03-16 11:14:29 +00:00
|
|
|
gimp_layer_tree_view_layer_signal_handler (GimpLayer *layer,
|
2004-08-25 22:31:44 +00:00
|
|
|
GimpLayerTreeView *view)
|
2001-03-11 17:24:47 +00:00
|
|
|
{
|
2004-05-11 10:01:25 +00:00
|
|
|
GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (view);
|
2020-04-29 02:12:00 +02:00
|
|
|
GList *selected_layers;
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2020-04-29 02:12:00 +02:00
|
|
|
selected_layers =
|
|
|
|
GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->get_selected_items (gimp_item_tree_view_get_image (item_view));
|
2003-02-17 13:33:29 +00:00
|
|
|
|
2020-04-29 02:12:00 +02:00
|
|
|
if (g_list_find (selected_layers, layer))
|
|
|
|
gimp_layer_tree_view_update_options (view, selected_layers);
|
2001-03-11 17:24:47 +00:00
|
|
|
}
|
|
|
|
|
2001-03-11 20:01:14 +00:00
|
|
|
|
|
|
|
#define BLOCK(object,function) \
|
2003-01-05 22:07:10 +00:00
|
|
|
g_signal_handlers_block_by_func ((object), (function), view)
|
2001-03-11 20:01:14 +00:00
|
|
|
|
|
|
|
#define UNBLOCK(object,function) \
|
2003-01-05 22:07:10 +00:00
|
|
|
g_signal_handlers_unblock_by_func ((object), (function), view)
|
2001-03-11 20:01:14 +00:00
|
|
|
|
2001-03-11 17:24:47 +00:00
|
|
|
static void
|
2003-03-16 11:14:29 +00:00
|
|
|
gimp_layer_tree_view_update_options (GimpLayerTreeView *view,
|
2020-04-29 02:12:00 +02:00
|
|
|
GList *layers)
|
2001-03-11 17:24:47 +00:00
|
|
|
{
|
2020-04-29 02:12:00 +02:00
|
|
|
GList *iter;
|
|
|
|
GimpLayerMode mode = GIMP_LAYER_MODE_SEPARATOR;
|
|
|
|
GimpLayerModeContext context = 0;
|
|
|
|
/*gboolean inconsistent_opacity = FALSE;*/
|
|
|
|
gboolean inconsistent_mode = FALSE;
|
|
|
|
gdouble opacity = -1.0;
|
2005-02-08 20:07:08 +00:00
|
|
|
|
2020-04-29 02:12:00 +02:00
|
|
|
for (iter = layers; iter; iter = iter->next)
|
2017-02-17 05:20:53 -05:00
|
|
|
{
|
2020-04-29 02:12:00 +02:00
|
|
|
#if 0
|
|
|
|
if (opacity != -1.0 &&
|
|
|
|
opacity != gimp_layer_get_opacity (iter->data))
|
|
|
|
/* We don't really have a way to show an inconsistent
|
|
|
|
* GimpSpinScale. This is currently unused.
|
|
|
|
*/
|
|
|
|
inconsistent_opacity = TRUE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
opacity = gimp_layer_get_opacity (iter->data);
|
|
|
|
|
|
|
|
if (gimp_viewable_get_children (iter->data))
|
|
|
|
context |= GIMP_LAYER_MODE_CONTEXT_GROUP;
|
|
|
|
else
|
|
|
|
context |= GIMP_LAYER_MODE_CONTEXT_LAYER;
|
|
|
|
|
|
|
|
if (mode != GIMP_LAYER_MODE_SEPARATOR &&
|
|
|
|
mode != gimp_layer_get_mode (iter->data))
|
|
|
|
inconsistent_mode = TRUE;
|
|
|
|
|
|
|
|
mode = gimp_layer_get_mode (iter->data);
|
2017-02-17 05:20:53 -05:00
|
|
|
}
|
2020-04-29 02:12:00 +02:00
|
|
|
if (opacity == -1.0)
|
|
|
|
opacity = 1.0;
|
|
|
|
|
|
|
|
if (inconsistent_mode)
|
|
|
|
mode = GIMP_LAYER_MODE_SEPARATOR;
|
|
|
|
|
|
|
|
if (! context)
|
|
|
|
context = GIMP_LAYER_MODE_CONTEXT_LAYER;
|
|
|
|
|
|
|
|
BLOCK (view->priv->layer_mode_box,
|
|
|
|
gimp_layer_tree_view_layer_mode_box_callback);
|
2017-02-17 05:20:53 -05:00
|
|
|
|
2020-04-29 02:12:00 +02:00
|
|
|
gimp_layer_mode_box_set_context (GIMP_LAYER_MODE_BOX (view->priv->layer_mode_box),
|
|
|
|
context);
|
2017-01-30 13:24:35 +01:00
|
|
|
gimp_layer_mode_box_set_mode (GIMP_LAYER_MODE_BOX (view->priv->layer_mode_box),
|
2020-04-29 02:12:00 +02:00
|
|
|
mode);
|
2005-02-08 20:07:08 +00:00
|
|
|
|
2017-01-30 13:24:35 +01:00
|
|
|
UNBLOCK (view->priv->layer_mode_box,
|
|
|
|
gimp_layer_tree_view_layer_mode_box_callback);
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2020-04-29 02:12:00 +02:00
|
|
|
if (opacity * 100.0 !=
|
2008-12-25 12:12:33 +00:00
|
|
|
gtk_adjustment_get_value (view->priv->opacity_adjustment))
|
2001-03-11 17:24:47 +00:00
|
|
|
{
|
2008-12-25 12:12:33 +00:00
|
|
|
BLOCK (view->priv->opacity_adjustment,
|
2004-08-25 22:31:44 +00:00
|
|
|
gimp_layer_tree_view_opacity_scale_changed);
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2008-12-25 12:12:33 +00:00
|
|
|
gtk_adjustment_set_value (view->priv->opacity_adjustment,
|
2020-04-29 02:12:00 +02:00
|
|
|
opacity * 100.0);
|
2001-03-11 17:24:47 +00:00
|
|
|
|
2008-12-25 12:12:33 +00:00
|
|
|
UNBLOCK (view->priv->opacity_adjustment,
|
2004-08-25 22:31:44 +00:00
|
|
|
gimp_layer_tree_view_opacity_scale_changed);
|
2001-03-11 17:24:47 +00:00
|
|
|
}
|
|
|
|
}
|
2001-03-11 20:01:14 +00:00
|
|
|
|
|
|
|
#undef BLOCK
|
|
|
|
#undef UNBLOCK
|
2003-02-17 13:33:29 +00:00
|
|
|
|
2003-03-16 13:19:43 +00:00
|
|
|
|
2004-08-20 22:32:14 +00:00
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_update_menu (GimpLayerTreeView *layer_view,
|
2020-04-28 17:04:47 +02:00
|
|
|
GList *layers)
|
2004-08-20 22:32:14 +00:00
|
|
|
{
|
2023-01-31 20:37:19 +01:00
|
|
|
GimpContext *context;
|
|
|
|
Gimp *gimp;
|
|
|
|
GAction *action;
|
|
|
|
GList *iter;
|
|
|
|
gboolean have_masks = FALSE;
|
|
|
|
gboolean all_masks_shown = TRUE;
|
|
|
|
gboolean all_masks_disabled = TRUE;
|
2004-08-20 22:32:14 +00:00
|
|
|
|
2023-01-31 20:37:19 +01:00
|
|
|
context = gimp_container_view_get_context (GIMP_CONTAINER_VIEW (layer_view));
|
|
|
|
gimp = context->gimp;
|
2004-08-20 22:32:14 +00:00
|
|
|
|
2020-04-28 17:04:47 +02:00
|
|
|
for (iter = layers; iter; iter = iter->next)
|
|
|
|
{
|
|
|
|
if (gimp_layer_get_mask (iter->data))
|
|
|
|
{
|
|
|
|
have_masks = TRUE;
|
|
|
|
if (! gimp_layer_get_show_mask (iter->data))
|
|
|
|
all_masks_shown = FALSE;
|
|
|
|
if (gimp_layer_get_apply_mask (iter->data))
|
|
|
|
all_masks_disabled = FALSE;
|
|
|
|
}
|
|
|
|
}
|
2004-08-20 22:32:14 +00:00
|
|
|
|
2023-01-31 20:37:19 +01:00
|
|
|
action = g_action_map_lookup_action (G_ACTION_MAP (gimp->app),
|
|
|
|
"layers-mask-show");
|
|
|
|
g_return_if_fail (GIMP_IS_TOGGLE_ACTION (action));
|
|
|
|
gimp_toggle_action_set_active (GIMP_TOGGLE_ACTION (action),
|
|
|
|
have_masks && all_masks_shown);
|
|
|
|
|
|
|
|
action = g_action_map_lookup_action (G_ACTION_MAP (gimp->app),
|
|
|
|
"layers-mask-disable");
|
|
|
|
g_return_if_fail (GIMP_IS_TOGGLE_ACTION (action));
|
|
|
|
gimp_toggle_action_set_active (GIMP_TOGGLE_ACTION (action),
|
|
|
|
have_masks && all_masks_disabled);
|
2020-04-28 17:04:47 +02:00
|
|
|
|
|
|
|
/* Only one layer mask at a time can be edited. */
|
2023-01-31 20:37:19 +01:00
|
|
|
action = g_action_map_lookup_action (G_ACTION_MAP (gimp->app),
|
|
|
|
"layers-mask-edit");
|
|
|
|
g_return_if_fail (GIMP_IS_TOGGLE_ACTION (action));
|
|
|
|
gimp_toggle_action_set_active (GIMP_TOGGLE_ACTION (action),
|
|
|
|
g_list_length (layers) == 1 &&
|
|
|
|
gimp_layer_get_mask (layers->data) &&
|
|
|
|
gimp_layer_get_edit_mask (layers->data));
|
2004-08-20 22:32:14 +00:00
|
|
|
}
|
|
|
|
|
2018-03-07 10:42:00 -05:00
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_update_highlight (GimpLayerTreeView *layer_view)
|
|
|
|
{
|
|
|
|
GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (layer_view);
|
|
|
|
GimpImage *image = gimp_item_tree_view_get_image (item_view);
|
|
|
|
GimpLayer *floating_sel = NULL;
|
2018-05-17 12:56:29 +02:00
|
|
|
GtkReliefStyle default_relief;
|
2018-03-07 10:42:00 -05:00
|
|
|
|
|
|
|
if (image)
|
|
|
|
floating_sel = gimp_image_get_floating_selection (image);
|
|
|
|
|
2018-05-17 12:56:29 +02:00
|
|
|
gtk_widget_style_get (GTK_WIDGET (layer_view),
|
|
|
|
"button-relief", &default_relief,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
gimp_button_set_suggested (gimp_item_tree_view_get_new_button (item_view),
|
|
|
|
floating_sel &&
|
|
|
|
! GIMP_IS_CHANNEL (gimp_layer_get_floating_sel_drawable (floating_sel)),
|
|
|
|
default_relief);
|
2018-03-07 10:42:00 -05:00
|
|
|
|
2018-05-17 12:56:29 +02:00
|
|
|
gimp_button_set_destructive (gimp_item_tree_view_get_delete_button (item_view),
|
|
|
|
floating_sel != NULL,
|
|
|
|
default_relief);
|
2018-03-07 10:42:00 -05:00
|
|
|
|
2018-05-17 12:56:29 +02:00
|
|
|
gimp_button_set_suggested (layer_view->priv->anchor_button,
|
|
|
|
floating_sel != NULL,
|
|
|
|
default_relief);
|
2022-11-28 20:43:56 +01:00
|
|
|
if (floating_sel != NULL)
|
|
|
|
{
|
|
|
|
if (GIMP_IS_LAYER_MASK (gimp_layer_get_floating_sel_drawable (floating_sel)))
|
|
|
|
gtk_widget_set_tooltip_text (layer_view->priv->anchor_button,
|
|
|
|
C_("layers-action", "Anchor the floating mask"));
|
|
|
|
else
|
|
|
|
gtk_widget_set_tooltip_text (layer_view->priv->anchor_button,
|
|
|
|
C_("layers-action", "Anchor the floating layer"));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_widget_set_tooltip_text (layer_view->priv->anchor_button,
|
|
|
|
C_("layers-action", "Anchor the floating layer or mask"));
|
|
|
|
}
|
2018-03-07 10:42:00 -05:00
|
|
|
}
|
|
|
|
|
2004-08-20 22:32:14 +00:00
|
|
|
|
2003-03-16 13:19:43 +00:00
|
|
|
/* Layer Mask callbacks */
|
|
|
|
|
2003-03-16 11:14:29 +00:00
|
|
|
static void
|
2003-03-16 13:19:43 +00:00
|
|
|
gimp_layer_tree_view_mask_update (GimpLayerTreeView *layer_view,
|
|
|
|
GtkTreeIter *iter,
|
|
|
|
GimpLayer *layer)
|
2003-03-16 11:14:29 +00:00
|
|
|
{
|
2004-05-10 17:16:50 +00:00
|
|
|
GimpContainerView *view = GIMP_CONTAINER_VIEW (layer_view);
|
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (layer_view);
|
2003-03-16 13:19:43 +00:00
|
|
|
GimpLayerMask *mask;
|
2004-08-25 22:31:44 +00:00
|
|
|
GimpViewRenderer *renderer = NULL;
|
2003-03-16 13:19:43 +00:00
|
|
|
gboolean mask_visible = FALSE;
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2003-03-16 13:19:43 +00:00
|
|
|
mask = gimp_layer_get_mask (layer);
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2003-03-16 13:19:43 +00:00
|
|
|
if (mask)
|
2003-03-16 11:14:29 +00:00
|
|
|
{
|
2003-03-16 13:19:43 +00:00
|
|
|
GClosure *closure;
|
2006-01-17 10:08:50 +00:00
|
|
|
gint view_size;
|
2004-05-10 17:16:50 +00:00
|
|
|
gint border_width;
|
|
|
|
|
2006-01-17 10:08:50 +00:00
|
|
|
view_size = gimp_container_view_get_view_size (view, &border_width);
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2003-03-16 13:19:43 +00:00
|
|
|
mask_visible = TRUE;
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2006-08-31 21:40:16 +00:00
|
|
|
renderer = gimp_view_renderer_new (gimp_container_view_get_context (view),
|
2006-08-29 21:44:51 +00:00
|
|
|
G_TYPE_FROM_INSTANCE (mask),
|
2006-01-17 10:08:50 +00:00
|
|
|
view_size, border_width,
|
2004-08-25 22:31:44 +00:00
|
|
|
FALSE);
|
|
|
|
gimp_view_renderer_set_viewable (renderer, GIMP_VIEWABLE (mask));
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2003-03-16 13:19:43 +00:00
|
|
|
g_signal_connect (renderer, "update",
|
|
|
|
G_CALLBACK (gimp_layer_tree_view_renderer_update),
|
|
|
|
layer_view);
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2003-03-16 13:19:43 +00:00
|
|
|
closure = g_cclosure_new (G_CALLBACK (gimp_layer_tree_view_mask_callback),
|
|
|
|
layer_view, NULL);
|
|
|
|
g_object_watch_closure (G_OBJECT (renderer), closure);
|
2012-03-17 18:30:13 +01:00
|
|
|
g_signal_connect_closure (layer, "apply-mask-changed", closure, FALSE);
|
|
|
|
g_signal_connect_closure (layer, "edit-mask-changed", closure, FALSE);
|
|
|
|
g_signal_connect_closure (layer, "show-mask-changed", closure, FALSE);
|
2003-03-16 13:19:43 +00:00
|
|
|
}
|
|
|
|
|
2009-07-25 17:38:03 +02:00
|
|
|
gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter,
|
2008-12-25 12:12:33 +00:00
|
|
|
layer_view->priv->model_column_mask, renderer,
|
|
|
|
layer_view->priv->model_column_mask_visible, mask_visible,
|
2003-03-16 13:19:43 +00:00
|
|
|
-1);
|
|
|
|
|
2009-09-21 10:43:26 +02:00
|
|
|
gimp_layer_tree_view_update_borders (layer_view, iter);
|
|
|
|
|
2003-03-16 13:19:43 +00:00
|
|
|
if (renderer)
|
|
|
|
{
|
2004-08-25 22:31:44 +00:00
|
|
|
gimp_view_renderer_remove_idle (renderer);
|
2003-03-16 13:19:43 +00:00
|
|
|
g_object_unref (renderer);
|
2003-03-16 11:14:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-16 13:19:43 +00:00
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_mask_changed (GimpLayer *layer,
|
|
|
|
GimpLayerTreeView *layer_view)
|
|
|
|
{
|
2004-05-10 23:22:39 +00:00
|
|
|
GimpContainerView *view = GIMP_CONTAINER_VIEW (layer_view);
|
|
|
|
GtkTreeIter *iter;
|
2003-03-16 13:19:43 +00:00
|
|
|
|
2004-05-10 23:22:39 +00:00
|
|
|
iter = gimp_container_view_lookup (view, GIMP_VIEWABLE (layer));
|
2003-03-16 13:19:43 +00:00
|
|
|
|
|
|
|
if (iter)
|
|
|
|
gimp_layer_tree_view_mask_update (layer_view, iter, layer);
|
|
|
|
}
|
|
|
|
|
2003-03-16 11:14:29 +00:00
|
|
|
static void
|
2004-08-25 22:31:44 +00:00
|
|
|
gimp_layer_tree_view_renderer_update (GimpViewRenderer *renderer,
|
|
|
|
GimpLayerTreeView *layer_view)
|
2003-03-16 11:14:29 +00:00
|
|
|
{
|
2004-05-10 23:22:39 +00:00
|
|
|
GimpContainerView *view = GIMP_CONTAINER_VIEW (layer_view);
|
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (layer_view);
|
|
|
|
GimpLayerMask *mask;
|
|
|
|
GtkTreeIter *iter;
|
2003-03-16 11:14:29 +00:00
|
|
|
|
|
|
|
mask = GIMP_LAYER_MASK (renderer->viewable);
|
|
|
|
|
2004-05-10 23:22:39 +00:00
|
|
|
iter = gimp_container_view_lookup (view, (GimpViewable *)
|
|
|
|
gimp_layer_mask_get_layer (mask));
|
2003-03-16 11:14:29 +00:00
|
|
|
|
|
|
|
if (iter)
|
|
|
|
{
|
|
|
|
GtkTreePath *path;
|
|
|
|
|
|
|
|
path = gtk_tree_model_get_path (tree_view->model, iter);
|
|
|
|
|
|
|
|
gtk_tree_model_row_changed (tree_view->model, path, iter);
|
|
|
|
|
|
|
|
gtk_tree_path_free (path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_update_borders (GimpLayerTreeView *layer_view,
|
|
|
|
GtkTreeIter *iter)
|
|
|
|
{
|
2004-05-11 10:01:25 +00:00
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (layer_view);
|
2004-08-25 22:31:44 +00:00
|
|
|
GimpViewRenderer *layer_renderer;
|
|
|
|
GimpViewRenderer *mask_renderer;
|
2022-11-02 01:25:43 +01:00
|
|
|
GimpLayer *layer = NULL;
|
2004-05-11 10:01:25 +00:00
|
|
|
GimpLayerMask *mask = NULL;
|
2004-08-25 22:31:44 +00:00
|
|
|
GimpViewBorderType layer_type = GIMP_VIEW_BORDER_BLACK;
|
2003-03-16 11:14:29 +00:00
|
|
|
|
|
|
|
gtk_tree_model_get (tree_view->model, iter,
|
2010-05-17 21:28:17 +02:00
|
|
|
GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &layer_renderer,
|
2012-03-17 18:30:13 +01:00
|
|
|
layer_view->priv->model_column_mask, &mask_renderer,
|
2003-03-16 11:14:29 +00:00
|
|
|
-1);
|
|
|
|
|
2022-11-02 01:25:43 +01:00
|
|
|
if (layer_renderer)
|
|
|
|
layer = GIMP_LAYER (layer_renderer->viewable);
|
|
|
|
else if (mask_renderer && GIMP_IS_LAYER (mask_renderer->viewable))
|
|
|
|
/* This happens when floating masks are displayed (in the mask column).
|
|
|
|
* In such a case, the mask_renderer will actually be a layer renderer
|
|
|
|
* showing the floating mask.
|
|
|
|
*/
|
|
|
|
layer = GIMP_LAYER (mask_renderer->viewable);
|
|
|
|
|
|
|
|
g_return_if_fail (layer != NULL);
|
2012-03-17 18:30:13 +01:00
|
|
|
|
2022-11-02 01:25:43 +01:00
|
|
|
if (mask_renderer && GIMP_IS_LAYER_MASK (mask_renderer->viewable))
|
2003-03-16 11:14:29 +00:00
|
|
|
mask = GIMP_LAYER_MASK (mask_renderer->viewable);
|
|
|
|
|
2012-03-17 18:30:13 +01:00
|
|
|
if (! mask || (mask && ! gimp_layer_get_edit_mask (layer)))
|
2004-08-25 22:31:44 +00:00
|
|
|
layer_type = GIMP_VIEW_BORDER_WHITE;
|
2004-03-13 16:54:35 +00:00
|
|
|
|
2022-11-02 01:25:43 +01:00
|
|
|
if (layer_renderer)
|
|
|
|
gimp_view_renderer_set_border_type (layer_renderer, layer_type);
|
2003-03-16 11:14:29 +00:00
|
|
|
|
|
|
|
if (mask)
|
|
|
|
{
|
2004-08-25 22:31:44 +00:00
|
|
|
GimpViewBorderType mask_color = GIMP_VIEW_BORDER_BLACK;
|
2004-03-13 16:54:35 +00:00
|
|
|
|
2012-03-17 18:30:13 +01:00
|
|
|
if (gimp_layer_get_show_mask (layer))
|
2004-08-25 22:31:44 +00:00
|
|
|
{
|
|
|
|
mask_color = GIMP_VIEW_BORDER_GREEN;
|
|
|
|
}
|
2012-03-17 18:30:13 +01:00
|
|
|
else if (! gimp_layer_get_apply_mask (layer))
|
2004-08-25 22:31:44 +00:00
|
|
|
{
|
|
|
|
mask_color = GIMP_VIEW_BORDER_RED;
|
|
|
|
}
|
2012-03-17 18:30:13 +01:00
|
|
|
else if (gimp_layer_get_edit_mask (layer))
|
2004-08-25 22:31:44 +00:00
|
|
|
{
|
|
|
|
mask_color = GIMP_VIEW_BORDER_WHITE;
|
|
|
|
}
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2004-08-25 22:31:44 +00:00
|
|
|
gimp_view_renderer_set_border_type (mask_renderer, mask_color);
|
2004-03-13 16:54:35 +00:00
|
|
|
}
|
2022-11-02 01:25:43 +01:00
|
|
|
else if (mask_renderer)
|
|
|
|
{
|
|
|
|
/* Floating mask. */
|
|
|
|
gimp_view_renderer_set_border_type (mask_renderer, GIMP_VIEW_BORDER_WHITE);
|
|
|
|
}
|
2003-03-16 11:14:29 +00:00
|
|
|
|
|
|
|
if (layer_renderer)
|
|
|
|
g_object_unref (layer_renderer);
|
|
|
|
|
|
|
|
if (mask_renderer)
|
|
|
|
g_object_unref (mask_renderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-03-17 18:30:13 +01:00
|
|
|
gimp_layer_tree_view_mask_callback (GimpLayer *layer,
|
2003-03-16 13:19:43 +00:00
|
|
|
GimpLayerTreeView *layer_view)
|
2003-03-16 11:14:29 +00:00
|
|
|
{
|
2004-05-10 23:22:39 +00:00
|
|
|
GimpContainerView *view = GIMP_CONTAINER_VIEW (layer_view);
|
|
|
|
GtkTreeIter *iter;
|
2004-05-10 17:16:50 +00:00
|
|
|
|
2012-03-17 18:30:13 +01:00
|
|
|
iter = gimp_container_view_lookup (view, (GimpViewable *) layer);
|
2003-03-16 11:14:29 +00:00
|
|
|
|
|
|
|
gimp_layer_tree_view_update_borders (layer_view, iter);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_layer_clicked (GimpCellRendererViewable *cell,
|
|
|
|
const gchar *path_str,
|
|
|
|
GdkModifierType state,
|
|
|
|
GimpLayerTreeView *layer_view)
|
|
|
|
{
|
2004-05-11 10:01:25 +00:00
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (layer_view);
|
2016-08-23 19:18:20 +02:00
|
|
|
GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
|
2003-03-16 11:14:29 +00:00
|
|
|
GtkTreeIter iter;
|
|
|
|
|
2020-12-14 12:10:21 +01:00
|
|
|
if (gtk_tree_model_get_iter (tree_view->model, &iter, path))
|
2003-03-16 11:14:29 +00:00
|
|
|
{
|
2010-06-27 21:44:29 +02:00
|
|
|
GimpViewRenderer *renderer;
|
2004-08-20 22:32:14 +00:00
|
|
|
|
2010-06-27 21:44:29 +02:00
|
|
|
gtk_tree_model_get (tree_view->model, &iter,
|
2012-03-17 18:30:13 +01:00
|
|
|
GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
|
2010-06-27 21:44:29 +02:00
|
|
|
-1);
|
2010-06-27 10:29:49 +02:00
|
|
|
|
2010-06-27 21:44:29 +02:00
|
|
|
if (renderer)
|
2003-03-16 11:14:29 +00:00
|
|
|
{
|
2020-12-14 12:10:21 +01:00
|
|
|
GimpLayer *layer = GIMP_LAYER (renderer->viewable);
|
|
|
|
GimpLayerMask *mask = gimp_layer_get_mask (layer);
|
|
|
|
GdkModifierType modifiers = (state & gimp_get_all_modifiers_mask ());
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* This feature has been removed because it clashes with the
|
|
|
|
* multi-selection (Shift/Ctrl are reserved), and we can't move it to
|
|
|
|
* Alt+ because then it would clash with the alpha-to-selection features
|
|
|
|
* (cf. gimp_item_tree_view_item_pre_clicked()).
|
|
|
|
* Just macro-ing them out for now, just in case, but I don't think
|
|
|
|
* there is a chance to revive them as there is no infinite modifiers.
|
|
|
|
*/
|
|
|
|
GimpImage *image;
|
|
|
|
|
|
|
|
image = gimp_item_get_image (GIMP_ITEM (layer));
|
2009-07-18 16:59:43 +02:00
|
|
|
|
2020-12-14 12:10:21 +01:00
|
|
|
if ((modifiers & GDK_MOD1_MASK))
|
2012-03-17 22:49:50 +01:00
|
|
|
{
|
2020-12-14 12:10:21 +01:00
|
|
|
/* Alternative functions (Alt key or equivalent) when
|
|
|
|
* clicking on a layer preview. The actions happen only on
|
|
|
|
* the clicked layer, not on selected layers.
|
|
|
|
*
|
|
|
|
* Note: Alt-click is already reserved for Alpha to
|
|
|
|
* selection in GimpItemTreeView.
|
|
|
|
*/
|
|
|
|
if (modifiers == (GDK_MOD1_MASK | GDK_SHIFT_MASK))
|
2016-08-23 19:18:20 +02:00
|
|
|
{
|
2020-12-14 12:10:21 +01:00
|
|
|
/* Alt-Shift-click adds a layer mask with last values */
|
|
|
|
GimpDialogConfig *config;
|
|
|
|
GimpChannel *channel = NULL;
|
2016-08-23 19:18:20 +02:00
|
|
|
|
2020-12-14 12:10:21 +01:00
|
|
|
if (! mask)
|
|
|
|
{
|
|
|
|
config = GIMP_DIALOG_CONFIG (image->gimp->config);
|
|
|
|
|
|
|
|
if (config->layer_add_mask_type == GIMP_ADD_MASK_CHANNEL)
|
|
|
|
{
|
|
|
|
channel = gimp_image_get_active_channel (image);
|
|
|
|
|
|
|
|
if (! channel)
|
|
|
|
{
|
|
|
|
GimpContainer *channels = gimp_image_get_channels (image);
|
|
|
|
|
|
|
|
channel = GIMP_CHANNEL (gimp_container_get_first_child (channels));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! channel)
|
|
|
|
{
|
|
|
|
/* No channel. We cannot perform the add
|
|
|
|
* mask action. */
|
|
|
|
g_message (_("No channels to create a layer mask from."));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config->layer_add_mask_type != GIMP_ADD_MASK_CHANNEL || channel)
|
|
|
|
{
|
|
|
|
mask = gimp_layer_create_mask (layer,
|
|
|
|
config->layer_add_mask_type,
|
|
|
|
channel);
|
|
|
|
|
|
|
|
if (config->layer_add_mask_invert)
|
|
|
|
gimp_channel_invert (GIMP_CHANNEL (mask), FALSE);
|
|
|
|
|
|
|
|
gimp_layer_add_mask (layer, mask, TRUE, NULL);
|
|
|
|
gimp_image_flush (image);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (modifiers == (GDK_MOD1_MASK | GDK_CONTROL_MASK))
|
|
|
|
{
|
|
|
|
/* Alt-Control-click removes a layer mask */
|
2016-08-23 19:18:20 +02:00
|
|
|
if (mask)
|
2020-12-14 12:10:21 +01:00
|
|
|
{
|
|
|
|
gimp_layer_apply_mask (layer, GIMP_MASK_DISCARD, TRUE);
|
|
|
|
gimp_image_flush (image);
|
|
|
|
}
|
2016-08-23 19:18:20 +02:00
|
|
|
}
|
2020-12-14 12:10:21 +01:00
|
|
|
else if (modifiers == (GDK_MOD1_MASK | GDK_CONTROL_MASK | GDK_SHIFT_MASK))
|
2016-08-23 19:18:20 +02:00
|
|
|
{
|
2020-12-14 12:10:21 +01:00
|
|
|
/* Alt-Shift-Control-click applies a layer mask */
|
|
|
|
if (mask)
|
|
|
|
{
|
|
|
|
gimp_layer_apply_mask (layer, GIMP_MASK_APPLY, TRUE);
|
|
|
|
gimp_image_flush (image);
|
|
|
|
}
|
2016-08-23 19:18:20 +02:00
|
|
|
}
|
|
|
|
}
|
2020-12-14 12:10:21 +01:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
if (! modifiers && mask && gimp_layer_get_edit_mask (layer))
|
2016-08-23 19:18:20 +02:00
|
|
|
{
|
2020-12-14 12:10:21 +01:00
|
|
|
/* Simple clicks (without modifiers) activate the layer */
|
2016-08-23 19:18:20 +02:00
|
|
|
|
|
|
|
if (mask)
|
2023-01-31 20:37:19 +01:00
|
|
|
{
|
|
|
|
GimpContext *context;
|
|
|
|
Gimp *gimp;
|
|
|
|
GAction *action;
|
|
|
|
|
|
|
|
context = gimp_container_view_get_context (GIMP_CONTAINER_VIEW (layer_view));
|
|
|
|
gimp = context->gimp;
|
|
|
|
action = g_action_map_lookup_action (G_ACTION_MAP (gimp->app),
|
|
|
|
"layers-mask-edit");
|
|
|
|
g_return_if_fail (GIMP_IS_TOGGLE_ACTION (action));
|
|
|
|
gimp_toggle_action_set_active (GIMP_TOGGLE_ACTION (action),
|
|
|
|
FALSE);
|
|
|
|
}
|
2012-03-17 22:49:50 +01:00
|
|
|
}
|
2009-07-18 16:59:43 +02:00
|
|
|
|
2010-06-27 21:44:29 +02:00
|
|
|
g_object_unref (renderer);
|
2003-03-16 11:14:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_tree_path_free (path);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_mask_clicked (GimpCellRendererViewable *cell,
|
|
|
|
const gchar *path_str,
|
|
|
|
GdkModifierType state,
|
|
|
|
GimpLayerTreeView *layer_view)
|
|
|
|
{
|
2004-05-11 10:01:25 +00:00
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (layer_view);
|
2003-03-16 11:14:29 +00:00
|
|
|
GtkTreePath *path;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
path = gtk_tree_path_new_from_string (path_str);
|
|
|
|
|
|
|
|
if (gtk_tree_model_get_iter (tree_view->model, &iter, path))
|
|
|
|
{
|
2004-08-25 22:31:44 +00:00
|
|
|
GimpViewRenderer *renderer;
|
2003-03-16 11:14:29 +00:00
|
|
|
|
|
|
|
gtk_tree_model_get (tree_view->model, &iter,
|
2012-03-17 18:30:13 +01:00
|
|
|
GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
|
2003-03-16 11:14:29 +00:00
|
|
|
-1);
|
|
|
|
|
2004-08-20 22:32:14 +00:00
|
|
|
if (renderer)
|
2003-03-16 11:14:29 +00:00
|
|
|
{
|
2020-12-14 01:37:19 +01:00
|
|
|
GimpLayer *layer = GIMP_LAYER (renderer->viewable);
|
|
|
|
GdkModifierType modifiers = gimp_get_all_modifiers_mask ();
|
|
|
|
|
|
|
|
if ((state & GDK_MOD1_MASK))
|
|
|
|
{
|
|
|
|
GimpImage *image;
|
|
|
|
|
|
|
|
image = gimp_item_get_image (GIMP_ITEM (layer));
|
|
|
|
|
|
|
|
if ((state & modifiers) == GDK_MOD1_MASK)
|
|
|
|
{
|
|
|
|
/* Alt-click shows/hides a layer mask */
|
|
|
|
gimp_layer_set_show_mask (layer, ! gimp_layer_get_show_mask (layer), TRUE);
|
|
|
|
gimp_image_flush (image);
|
|
|
|
}
|
|
|
|
if ((state & modifiers) == (GDK_MOD1_MASK | GDK_CONTROL_MASK))
|
|
|
|
{
|
|
|
|
/* Alt-Control-click enables/disables a layer mask */
|
|
|
|
gimp_layer_set_apply_mask (layer, ! gimp_layer_get_apply_mask (layer), TRUE);
|
|
|
|
gimp_image_flush (image);
|
|
|
|
}
|
|
|
|
}
|
2012-03-17 18:30:13 +01:00
|
|
|
else if (! gimp_layer_get_edit_mask (layer))
|
2020-12-14 01:37:19 +01:00
|
|
|
{
|
2023-01-31 20:37:19 +01:00
|
|
|
GimpContext *context;
|
|
|
|
Gimp *gimp;
|
|
|
|
GAction *action;
|
|
|
|
|
|
|
|
context = gimp_container_view_get_context (GIMP_CONTAINER_VIEW (layer_view));
|
|
|
|
gimp = context->gimp;
|
|
|
|
action = g_action_map_lookup_action (G_ACTION_MAP (gimp->app),
|
|
|
|
"layers-mask-edit");
|
|
|
|
g_return_if_fail (GIMP_IS_TOGGLE_ACTION (action));
|
|
|
|
|
2020-12-14 01:37:19 +01:00
|
|
|
/* Simple click selects the mask for edition. */
|
2023-01-31 20:37:19 +01:00
|
|
|
gimp_toggle_action_set_active (GIMP_TOGGLE_ACTION (action),
|
|
|
|
TRUE);
|
2020-12-14 01:37:19 +01:00
|
|
|
}
|
2003-03-16 11:14:29 +00:00
|
|
|
|
2004-08-20 22:32:14 +00:00
|
|
|
g_object_unref (renderer);
|
|
|
|
}
|
2003-03-16 11:14:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gtk_tree_path_free (path);
|
|
|
|
}
|
2003-05-21 11:34:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* GimpDrawable alpha callbacks */
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_alpha_update (GimpLayerTreeView *view,
|
|
|
|
GtkTreeIter *iter,
|
|
|
|
GimpLayer *layer)
|
|
|
|
{
|
2003-09-06 21:17:16 +00:00
|
|
|
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
|
2003-05-21 11:34:00 +00:00
|
|
|
|
2009-07-25 17:38:03 +02:00
|
|
|
gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter,
|
2010-05-17 21:28:17 +02:00
|
|
|
GIMP_CONTAINER_TREE_STORE_COLUMN_NAME_ATTRIBUTES,
|
2003-05-21 11:34:00 +00:00
|
|
|
gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)) ?
|
2008-12-25 12:12:33 +00:00
|
|
|
NULL : view->priv->bold_attrs,
|
2003-05-21 11:34:00 +00:00
|
|
|
-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_layer_tree_view_alpha_changed (GimpLayer *layer,
|
|
|
|
GimpLayerTreeView *layer_view)
|
|
|
|
{
|
2004-05-10 23:22:39 +00:00
|
|
|
GimpContainerView *view = GIMP_CONTAINER_VIEW (layer_view);
|
|
|
|
GtkTreeIter *iter;
|
2003-05-21 11:34:00 +00:00
|
|
|
|
2004-05-10 23:22:39 +00:00
|
|
|
iter = gimp_container_view_lookup (view, (GimpViewable *) layer);
|
2003-05-21 11:34:00 +00:00
|
|
|
|
|
|
|
if (iter)
|
2003-08-27 19:50:08 +00:00
|
|
|
{
|
2003-09-06 21:17:16 +00:00
|
|
|
GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (view);
|
2003-08-27 19:50:08 +00:00
|
|
|
|
|
|
|
gimp_layer_tree_view_alpha_update (layer_view, iter, layer);
|
|
|
|
|
|
|
|
/* update button states */
|
2020-04-29 02:12:00 +02:00
|
|
|
if (g_list_find (gimp_image_get_selected_layers (gimp_item_tree_view_get_image (item_view)),
|
|
|
|
layer))
|
|
|
|
gimp_container_view_select_items (GIMP_CONTAINER_VIEW (view),
|
|
|
|
gimp_image_get_selected_layers (gimp_item_tree_view_get_image (item_view)));
|
2003-08-27 19:50:08 +00:00
|
|
|
}
|
2003-05-21 11:34:00 +00:00
|
|
|
}
|