… and use gimp_container_view_select_items() when the context changes.
Even though some types of containers still expect only a single
selected content, we should slowly move to multiple item code. The
reason is to avoid 2 code paths which makes the code more complicated
and bug-prone. When all child classes of GimpContainerView will have a
valid select_items() implementation, we can work on getting rid of the
select_item() in favor of the multi-item one.
Rather than trying to fix up our own heuristics using a
`GtkMenuPositionFunc`, use whatever GTK provides to position given a
specific rectangle, which also has the benefit of nicely integrating
with GDK backends such as Wayland. Another advantage is that we can use
GdkGravity to center the popup.
Since GTK 3, GtkWidget also gained a "popup-menu" signal, which we
can/should use instead of rolling our own context signals.
This was already implemented for the new button which had its own drag'n
drop handler, and now also for other buttons (in particular the delete
button which is multi-item aware).
In the middle of multi-item insertion, you don't want to run
gimp_container_view_select_items() as was being done in
gimp_item_tree_view_insert_item_after(). As it turns out, this is the
only implementation for this virtual function, and it doesn't need to be
run on the specific inserted viewable, just make it a call to run when
all insertions are done.
Though it's not finished yet, I am changing "active layer" into
"selected layers" logics. Probably the "active layer" concept will be
back eventually (i.e. even in a multi-selection a specific layer could
be said "active", highlighted in the list a bit differently, hence one
could edit this specific layer only). But for simplicity, for now, it's
better to first get rid of it, otherwise it's just messy.
Basically the single click selection must happen on mouse button
release, not initial press, otherwise it would cancel your multiple
selection when you were actually about to drag the items.
As for contextual menu, it should trigger a selection only when the
clicked item is not in the current multiple selection.
Properly pass the multi-selection information through the container
classes. Previous implementation was incomplete (most code paths with
multiple item selected were just ignored) and data was passed through
the "select-item" signal with the GimpViewable to NULL and the data to a
list of items (instead of being a GtkTreeIter otherwise). Having a
pointer data which changes meaning in the same function/class is not the
best idea. So instead "select-items" will have 2 list as parameters: a
list of items and a list of GtkTreePath to be used similarly and with
less ambiguity.
which means that it's now included normally via gimpbase.h
and not any longer via gimpbasetypes.h which we only did out
of lazyness. A *lot* of files in libgimp* and app/ now need to
... while the container is frozen
In GimpContainerView, do nothing in response to a
gimp_container_view_{select,activate,context}_item() call while the
view's container is frozen. While the container is frozen the view
is empty, and these functions can segfault.
The bug is very hard to reproduce, probably because it requires specific
timing conditions but this looks like this commit would prevent it.
Apparently the signal handler gimp_container_view_name_changed() may
have been run while the container view (set as user data) was most
likely already finalized, hence leaving an invalid dangling pointer.
Let's just make sure we disconnect this handler (and another) when we
finalize the container view and its private data.
Add an "expanded-changed" signal to GimpViewable, which should be
emitted by subclasses when the viewable's expanded state changes.
Emit this signal when the expanded state of group layers changes.
Respond to this signal in GimpContainerView, by calling a new
expand_item() virtual function. Implement expand_item() in
GimpContainerTreeView, expanding or collapsing the item as
necessary.
Don't special case on view_iface->model_is_tree and always run
gimp_container_view_remove_foreach(), also on the view's toplevel
container. Run gimp_container_view_clear_items() anyway on the
toplevel as an optimization, but with a big comment. This makes all
views (on list *and* tree models) behave the same way, and makes
view_iface->model_is_tree practically obsolete, will remove it later.
When removing the container of a GimpContainerView,
gimp_container_view_remove_container() must be the last call. It was
causing a `GIMP_IS_CONTAINER (container)' failure in subsequent
gimp_container_get_children_type().
For good practice, unsetting a container works now the exact reversed
order as the setting of a container.
Wrong order of destruction functions were causing critical warnings on
g_signal_handlers_disconnect_by_func() calls.
Also g_object_ref/unref() the container because the tree handler might
hold the last ref to the container, once it's disconnected the container
could be gone.
Implemented infrastructure for multiple selection support.
GimpContainerTreeView actually provides such functionality.
All other GimpContainerViews should work as before.
In the drop callbacks, don't check if the GimpContainerView's container
contains the dropped item, it might be in a sub-container. Instead,
simply checking if the GimpContainerView knows the item is sufficient
(and also much simpler than a recursive container serach).
The new function is called after the item is inserted. This is a much
smaller change than turning all vfuncs into signals just to be able
connect_after to one of them.
* app/widgets/gimpcontainerview.h: add "gboolean model_is_tree"
to GimpContainerViewInterface.
* app/widgets/gimpcontainerview.c: default to FALSE and enable the
commented-out optimization in remove_container() for list-only
container views.
* app/widgets/gimpcontainerview.[ch]: add and remove container trees
recursively. Change virtual function ::add_item() to pass the
insert_data of the parent viewable.
* app/widgets/gimpcontainercombobox.c
* app/widgets/gimpcontainerentry.c
* app/widgets/gimpcontainergridview.c: changed accordingly.
* app/widgets/gimpcontainertreeview.c
* app/widgets/gimpitemtreeview.c
* app/widgets/gimplayertreeview.c: dito, but actually use the passed
parent_insert_data to insert the item at the right place in the
GtkTreeView.
Factor out large portions of identical code into new utility functions
gimp_container_view_connect_context() and
gimp_container_view_disconnect_context().
Keep around the handler IDs for the "name-changed" signals of the
container's children in a hash table that maps containers to handler
IDs and move adding/removing of the handler to
add_container()/remove_container(). This way the name-changed code is
prepared for handling multiple containers.
In preparation of having a tree of containers, added
gimp_container_view_add_container(),
gimp_container_view_remove_container() and
gimp_container_view_remove_foreach()
which do all the job of inserting/removing items and
connecting/disconnecting the "add", "remove" and "reorder" signals.
Also refactored things so when the toplevel container freezes/thaws,
it simply gets removed from the view instead of ignoring its signals.
gimp_container_view_real_set_container()
gimp_container_view_freeze()
gimp_container_view_thaw(): use the new add_container() and
remove_container() APIs and fix the code for the unlikely case
that a frozen container gets added/removed.
GHashTable has g_hash_table_remove_all() since GLib 2.12, so there is
no need any longer to clear the hash table by destroyung it. Instead,
keep the hash around during the view's entire lifetime and remove all
re-creation code and all checks for its existence.
2009-01-17 Michael Natterer <mitch@gimp.org>
* all files with a GPL header and all COPYING files:
Change licence to GPLv3 (and to LGPLv3 for libgimp).
Cleaned up some copyright headers and regenerated the parsers in
the ImageMap plugin.
svn path=/trunk/; revision=27913
2008-02-01 Michael Natterer <mitch@gimp.org>
* app/widgets/gimpcontainerview.c
(gimp_container_view_set_container): refuse containers if their
children are not GimpViewables instead of crashing later.
svn path=/trunk/; revision=24769
2006-08-31 Michael Natterer <mitch@gimp.org>
* app/widgets/gimpcontainerview.c
(gimp_container_view_real_set_container)
(gimp_container_view_real_set_context)
(gimp_container_view_item_selected)
(gimp_container_view_thaw): support setting a context even if
the viewed container's children_type is *not* a property of
GimpContext. This removes a major restriction of container
views and allows to get rid of some hacks:
* app/widgets/gimpitemtreeview.[ch]: removed GimpContext member
and implement GimpContainerView::set_context() instead of
GimpDocked::set_context().
* app/widgets/gimpchanneltreeview.c
* app/widgets/gimpcontainergridview.c
* app/widgets/gimpcontainertreeview.c
* app/widgets/gimpdrawabletreeview.c
* app/widgets/gimplayertreeview.c: use GimpContainerView's context
instead of GimpItemTreeView's and implement GimpContainerView's
set_context() instead of GimpDocked's.
* app/actions/actions.c (action_data_get_gimp)
(action_data_get_context): don't special-case GimpItemTreeView any
more, it's just like a normal GimpContainerView now.
* app/widgets/gimpcontrollerlist.c
(gimp_controller_list_constructor): set a context on the
GimpContainerView so its renderers have a context to use.
2006-08-28 Michael Natterer <mitch@gimp.org>
* app/widgets/gimpcontainerview.[ch]: made set_container() a
virtual function of the GimpContainerView interface.
2006-01-18 Michael Natterer <mitch@gimp.org>
* app/config/config-types.c: define GIMP_PARAM_STATIC_STRINGS
which is G_PARAM_STATIC_NAME|NICK|BLURB. Also define
GIMP_PARAM_READABLE, _WRITABLE and _READWRITE which include
GIMP_PARAM_STATIC_STRINGS.
* app/*/*.c: use them for all object properties so their
strings are not copied.