[egg-list-box/flow-box-enhancements: 3/3] Add sorting to EggFlowBox
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [egg-list-box/flow-box-enhancements: 3/3] Add sorting to EggFlowBox
- Date: Sun, 22 Sep 2013 17:31:45 +0000 (UTC)
commit 79f142ed577a5262e90a56f984e5ee8ac96e8fbb
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Sep 22 13:27:36 2013 -0400
Add sorting to EggFlowBox
This is pretty much a 1-1 copy of the sorting functionality
in GtkListBox.
egg-flow-box.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++---------
egg-flow-box.h | 17 ++++++--
test-flow-box.c | 37 ++++++++++++++++++-
3 files changed, 143 insertions(+), 23 deletions(-)
---
diff --git a/egg-flow-box.c b/egg-flow-box.c
index 14036cb..8c7abef 100644
--- a/egg-flow-box.c
+++ b/egg-flow-box.c
@@ -142,6 +142,10 @@ struct _EggFlowBoxPrivate {
EggFlowBoxFilterFunc filter_func;
gpointer filter_data;
GDestroyNotify filter_destroy;
+
+ EggFlowBoxSortFunc sort_func;
+ gpointer sort_data;
+ GDestroyNotify sort_destroy;
};
typedef struct _EggFlowBoxChildPrivate EggFlowBoxChildPrivate;
@@ -181,6 +185,9 @@ static void egg_flow_box_update_selection (EggFlowBox *box,
gboolean extend);
static void egg_flow_box_apply_filter (EggFlowBox *box,
EggFlowBoxChild *child);
+static gint egg_flow_box_sort (EggFlowBoxChild *a,
+ EggFlowBoxChild *b,
+ EggFlowBox *box);
static void
@@ -497,19 +504,6 @@ egg_flow_box_child_get_index (EggFlowBoxChild *child)
}
void
-egg_flow_box_child_changed (EggFlowBoxChild *child)
-{
- EggFlowBox *box;
-
- box = egg_flow_box_child_get_box (child);
-
- if (box != NULL)
- {
- egg_flow_box_apply_filter (box, child);
- }
-}
-
-void
egg_flow_box_set_adjustment (EggFlowBox *box,
GtkAdjustment *adjustment)
{
@@ -1306,7 +1300,11 @@ egg_flow_box_add (GtkContainer *container,
gtk_container_add (GTK_CONTAINER (info), child);
}
- iter = g_sequence_append (priv->children, info);
+ if (priv->sort_func != NULL)
+ iter = g_sequence_insert_sorted (priv->children, info,
+ (GCompareDataFunc)egg_flow_box_sort, box);
+ else
+ iter = g_sequence_append (priv->children, info);
child_priv = egg_flow_box_child_get_instance_private (info);
child_priv->iter = iter;
@@ -3482,8 +3480,13 @@ egg_flow_box_realize (GtkWidget *widget)
static void
egg_flow_box_finalize (GObject *obj)
{
- EggFlowBox *flow_box = EGG_FLOW_BOX (obj);
- EggFlowBoxPrivate *priv = flow_box->priv;
+ EggFlowBox *box = EGG_FLOW_BOX (obj);
+ EggFlowBoxPrivate *priv = box->priv;
+
+ if (priv->filter_destroy != NULL)
+ priv->filter_destroy (priv->filter_data);
+ if (priv->sort_destroy != NULL)
+ priv->sort_destroy (priv->sort_data);
g_sequence_free (priv->children);
g_clear_object (&priv->adjustment);
@@ -3981,8 +3984,7 @@ egg_flow_box_set_filter_func (EggFlowBox *box,
priv->filter_data = user_data;
priv->filter_destroy = destroy;
- egg_flow_box_apply_filter_all (box);
- gtk_widget_queue_resize (GTK_WIDGET (box));
+ egg_flow_box_invalidate_filter (box);
}
void
@@ -3993,3 +3995,77 @@ egg_flow_box_invalidate_filter (EggFlowBox *box)
egg_flow_box_apply_filter_all (box);
gtk_widget_queue_resize (GTK_WIDGET (box));
}
+
+void
+egg_flow_box_set_sort_func (EggFlowBox *box,
+ EggFlowBoxSortFunc sort_func,
+ gpointer user_data,
+ GDestroyNotify destroy)
+{
+ EggFlowBoxPrivate *priv;
+
+ g_return_if_fail (EGG_IS_FLOW_BOX (box));
+
+ priv = box->priv;
+
+ if (priv->sort_destroy != NULL)
+ priv->sort_destroy (priv->sort_data);
+
+ priv->sort_func = sort_func;
+ priv->sort_data = user_data;
+ priv->sort_destroy = destroy;
+
+ egg_flow_box_invalidate_sort (box);
+}
+
+static gint
+egg_flow_box_sort (EggFlowBoxChild *a,
+ EggFlowBoxChild *b,
+ EggFlowBox *box)
+{
+ EggFlowBoxPrivate *priv = box->priv;
+
+ return priv->sort_func (a, b, priv->sort_data);
+}
+
+void
+egg_flow_box_invalidate_sort (EggFlowBox *box)
+{
+ EggFlowBoxPrivate *priv;
+
+ g_return_if_fail (EGG_IS_FLOW_BOX (box));
+
+ priv = box->priv;
+
+ if (priv->sort_func != NULL)
+ {
+ g_sequence_sort (priv->children,
+ (GCompareDataFunc)egg_flow_box_sort, box);
+ gtk_widget_queue_resize (GTK_WIDGET (box));
+ }
+}
+
+void
+egg_flow_box_child_changed (EggFlowBoxChild *child)
+{
+ EggFlowBox *box;
+ EggFlowBoxPrivate *priv;
+ EggFlowBoxChildPrivate *child_priv;
+
+ child_priv = egg_flow_box_child_get_instance_private (child);
+ box = egg_flow_box_child_get_box (child);
+ priv = box->priv;
+
+ if (box == NULL)
+ return;
+
+ if (priv->sort_func != NULL)
+ {
+ g_sequence_sort_changed (child_priv->iter,
+ (GCompareDataFunc)egg_flow_box_sort, box);
+ gtk_widget_queue_resize (GTK_WIDGET (box));
+ }
+
+ egg_flow_box_apply_filter (box, child);
+}
+
diff --git a/egg-flow-box.h b/egg-flow-box.h
index 68af5c7..56b03d8 100644
--- a/egg-flow-box.h
+++ b/egg-flow-box.h
@@ -114,10 +114,6 @@ struct _EggFlowBoxChildClass
void (*_gtk_reserved2) (void);
};
-typedef gboolean (*EggFlowBoxFilterFunc) (EggFlowBoxChild *child,
- gpointer user_data);
-
-
GType egg_flow_box_child_get_type (void) G_GNUC_CONST;
GtkWidget* egg_flow_box_child_new (void);
gint egg_flow_box_child_get_index (EggFlowBoxChild *child);
@@ -175,12 +171,25 @@ void egg_flow_box_set_selection_mode (EggFlowBox
void egg_flow_box_set_adjustment (EggFlowBox *box,
GtkAdjustment *adjustment);
+typedef gboolean (*EggFlowBoxFilterFunc) (EggFlowBoxChild *child,
+ gpointer user_data);
+
void egg_flow_box_set_filter_func (EggFlowBox *box,
EggFlowBoxFilterFunc filter_func,
gpointer user_data,
GDestroyNotify destroy);
void egg_flow_box_invalidate_filter (EggFlowBox *box);
+typedef gint (*EggFlowBoxSortFunc) (EggFlowBoxChild *child1,
+ EggFlowBoxChild *child2,
+ gpointer user_data);
+
+void egg_flow_box_set_sort_func (EggFlowBox *box,
+ EggFlowBoxSortFunc sort_func,
+ gpointer user_data,
+ GDestroyNotify destroy);
+void egg_flow_box_invalidate_sort (EggFlowBox *box);
+
G_END_DECLS
diff --git a/test-flow-box.c b/test-flow-box.c
index 9061892..cbe5b5b 100644
--- a/test-flow-box.c
+++ b/test-flow-box.c
@@ -328,6 +328,29 @@ filter_toggled (GtkToggleButton *button,
egg_flow_box_set_filter_func (flowbox, NULL, NULL, NULL);
}
+static gint
+sort_func (EggFlowBoxChild *a,
+ EggFlowBoxChild *b,
+ gpointer data)
+{
+ gchar *ida, *idb;
+
+ ida = (gchar *)g_object_get_data (G_OBJECT (gtk_bin_get_child (GTK_BIN (a))), "id");
+ idb = (gchar *)g_object_get_data (G_OBJECT (gtk_bin_get_child (GTK_BIN (b))), "id");
+ return g_strcmp0 (ida, idb);
+}
+
+static void
+sort_toggled (GtkToggleButton *button,
+ EggFlowBox *flowbox)
+{
+ gboolean state = gtk_toggle_button_get_active (button);
+
+ if (state)
+ egg_flow_box_set_sort_func (flowbox, sort_func, NULL, NULL);
+ else
+ egg_flow_box_set_sort_func (flowbox, NULL, NULL, NULL);
+}
static GtkWidget *
create_window (void)
@@ -521,6 +544,10 @@ create_window (void)
g_signal_connect (G_OBJECT (widget), "value-changed",
G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_VERTICAL));
+ gtk_box_pack_start (GTK_BOX (flowbox_cntl), hbox, FALSE, FALSE, 0);
+
+ /* filtering and sorting */
+
widget = gtk_check_button_new_with_label ("Filter");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
gtk_widget_show (widget);
@@ -531,7 +558,15 @@ create_window (void)
g_signal_connect (G_OBJECT (widget), "toggled",
G_CALLBACK (filter_toggled), flowbox);
- gtk_box_pack_start (GTK_BOX (flowbox_cntl), hbox, FALSE, FALSE, 0);
+ widget = gtk_check_button_new_with_label ("Sort");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
+ gtk_widget_show (widget);
+
+ gtk_widget_set_tooltip_text (widget, "Set whether items should be sorted");
+ gtk_box_pack_start (GTK_BOX (flowbox_cntl), widget, FALSE, FALSE, 0);
+
+ g_signal_connect (G_OBJECT (widget), "toggled",
+ G_CALLBACK (sort_toggled), flowbox);
/* Add test items control frame */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]