Commit d027a059 authored by Ell's avatar Ell

app: respond to viewable expanded state changes in container views

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.
parent 06ef7949
......@@ -438,9 +438,14 @@ static void
gimp_group_layer_set_expanded (GimpViewable *viewable,
gboolean expanded)
{
GimpGroupLayer *group = GIMP_GROUP_LAYER (viewable);
GimpGroupLayerPrivate *private = GET_PRIVATE (viewable);
GET_PRIVATE (group)->expanded = expanded;
if (private->expanded != expanded)
{
private->expanded = expanded;
gimp_viewable_expanded_changed (viewable);
}
}
static gboolean
......
......@@ -54,6 +54,7 @@ enum
{
INVALIDATE_PREVIEW,
SIZE_CHANGED,
EXPANDED_CHANGED,
LAST_SIGNAL
};
......@@ -160,6 +161,15 @@ gimp_viewable_class_init (GimpViewableClass *klass)
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
viewable_signals[EXPANDED_CHANGED] =
g_signal_new ("expanded-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpViewableClass, expanded_changed),
NULL, NULL,
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
object_class->finalize = gimp_viewable_finalize;
object_class->get_property = gimp_viewable_get_property;
object_class->set_property = gimp_viewable_set_property;
......@@ -172,6 +182,7 @@ gimp_viewable_class_init (GimpViewableClass *klass)
klass->invalidate_preview = gimp_viewable_real_invalidate_preview;
klass->size_changed = NULL;
klass->expanded_changed = NULL;
klass->get_size = NULL;
klass->get_preview_size = gimp_viewable_real_get_preview_size;
......@@ -556,6 +567,22 @@ gimp_viewable_size_changed (GimpViewable *viewable)
g_signal_emit (viewable, viewable_signals[SIZE_CHANGED], 0);
}
/**
* gimp_viewable_expanded_changed:
* @viewable: a viewable object
*
* This function sends a signal that is handled at a lower level in the
* object hierarchy, and provides a mechanism by which objects derived
* from #GimpViewable can respond to expanded state changes.
**/
void
gimp_viewable_expanded_changed (GimpViewable *viewable)
{
g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
g_signal_emit (viewable, viewable_signals[EXPANDED_CHANGED], 0);
}
/**
* gimp_viewable_calc_preview_size:
* @aspect_width: unscaled width of the preview for an item.
......
......@@ -57,6 +57,7 @@ struct _GimpViewableClass
/* signals */
void (* invalidate_preview) (GimpViewable *viewable);
void (* size_changed) (GimpViewable *viewable);
void (* expanded_changed) (GimpViewable *viewable);
/* virtual functions */
gboolean (* get_size) (GimpViewable *viewable,
......@@ -107,6 +108,7 @@ GType gimp_viewable_get_type (void) G_GNUC_CONST;
void gimp_viewable_invalidate_preview (GimpViewable *viewable);
void gimp_viewable_size_changed (GimpViewable *viewable);
void gimp_viewable_expanded_changed (GimpViewable *viewable);
void gimp_viewable_calc_preview_size (gint aspect_width,
gint aspect_height,
......
......@@ -86,6 +86,9 @@ static void gimp_container_tree_view_reorder_item (GimpContainerVi
static void gimp_container_tree_view_rename_item (GimpContainerView *view,
GimpViewable *viewable,
gpointer insert_data);
static void gimp_container_tree_view_expand_item (GimpContainerView *view,
GimpViewable *viewable,
gpointer insert_data);
static gboolean gimp_container_tree_view_select_item (GimpContainerView *view,
GimpViewable *viewable,
gpointer insert_data);
......@@ -203,6 +206,7 @@ gimp_container_tree_view_view_iface_init (GimpContainerViewInterface *iface)
iface->remove_item = gimp_container_tree_view_remove_item;
iface->reorder_item = gimp_container_tree_view_reorder_item;
iface->rename_item = gimp_container_tree_view_rename_item;
iface->expand_item = gimp_container_tree_view_expand_item;
iface->select_item = gimp_container_tree_view_select_item;
iface->clear_items = gimp_container_tree_view_clear_items;
iface->set_view_size = gimp_container_tree_view_set_view_size;
......@@ -767,6 +771,41 @@ gimp_container_tree_view_rename_item (GimpContainerView *view,
}
}
static void
gimp_container_tree_view_expand_item (GimpContainerView *view,
GimpViewable *viewable,
gpointer insert_data)
{
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
GtkTreeIter *iter = (GtkTreeIter *) insert_data;
GimpViewRenderer *renderer;
gtk_tree_model_get (tree_view->model, iter,
GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
-1);
if (renderer)
{
GtkTreePath *path = gtk_tree_model_get_path (tree_view->model, iter);
g_signal_handlers_block_by_func (tree_view,
gimp_container_tree_view_row_expanded,
view);
if (gimp_viewable_get_expanded (renderer->viewable))
gtk_tree_view_expand_row (tree_view->view, path, FALSE);
else
gtk_tree_view_collapse_row (tree_view->view, path);
g_signal_handlers_unblock_by_func (tree_view,
gimp_container_tree_view_row_expanded,
view);
gtk_tree_path_free (path);
g_object_unref (renderer);
}
}
static gboolean
gimp_container_tree_view_select_item (GimpContainerView *view,
GimpViewable *viewable,
......
......@@ -72,6 +72,7 @@ struct _GimpContainerViewPrivate
GtkWidget *dnd_widget;
GimpTreeHandler *name_changed_handler;
GimpTreeHandler *expanded_changed_handler;
};
......@@ -117,6 +118,8 @@ static void gimp_container_view_thaw (GimpContainerView *view,
GimpContainer *container);
static void gimp_container_view_name_changed (GimpViewable *viewable,
GimpContainerView *view);
static void gimp_container_view_expanded_changed (GimpViewable *viewable,
GimpContainerView *view);
static void gimp_container_view_connect_context (GimpContainerView *view);
static void gimp_container_view_disconnect_context (GimpContainerView *view);
......@@ -217,6 +220,7 @@ gimp_container_view_iface_base_init (GimpContainerViewInterface *view_iface)
view_iface->remove_item = NULL;
view_iface->reorder_item = NULL;
view_iface->rename_item = NULL;
view_iface->expand_item = NULL;
view_iface->clear_items = gimp_container_view_real_clear_items;
view_iface->set_view_size = NULL;
view_iface->get_selected = gimp_container_view_real_get_selected;
......@@ -980,6 +984,15 @@ gimp_container_view_add_container (GimpContainerView *view,
G_CALLBACK (gimp_container_view_name_changed),
view);
if (GIMP_CONTAINER_VIEW_GET_INTERFACE (view)->expand_item)
{
private->expanded_changed_handler =
gimp_tree_handler_connect (container,
"expanded-changed",
G_CALLBACK (gimp_container_view_expanded_changed),
view);
}
g_type_class_unref (viewable_class);
}
......@@ -1088,8 +1101,10 @@ gimp_container_view_remove_container (GimpContainerView *view,
if (container == private->container)
{
gimp_tree_handler_disconnect (private->name_changed_handler);
private->name_changed_handler = NULL;
g_clear_pointer (&private->name_changed_handler,
gimp_tree_handler_disconnect);
g_clear_pointer (&private->expanded_changed_handler,
gimp_tree_handler_disconnect);
/* optimization: when the toplevel container gets removed, call
* clear_items() which will get rid of all view widget stuff
......@@ -1212,6 +1227,23 @@ gimp_container_view_name_changed (GimpViewable *viewable,
}
}
static void
gimp_container_view_expanded_changed (GimpViewable *viewable,
GimpContainerView *view)
{
GimpContainerViewPrivate *private = GIMP_CONTAINER_VIEW_GET_PRIVATE (view);
gpointer insert_data;
insert_data = g_hash_table_lookup (private->item_hash, viewable);
if (insert_data)
{
GIMP_CONTAINER_VIEW_GET_INTERFACE (view)->expand_item (view,
viewable,
insert_data);
}
}
static void
gimp_container_view_connect_context (GimpContainerView *view)
{
......
......@@ -83,6 +83,9 @@ struct _GimpContainerViewInterface
void (* rename_item) (GimpContainerView *view,
GimpViewable *object,
gpointer insert_data);
void (* expand_item) (GimpContainerView *view,
GimpViewable *object,
gpointer insert_data);
void (* clear_items) (GimpContainerView *view);
void (* set_view_size) (GimpContainerView *view);
gint (* get_selected) (GimpContainerView *view,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment