1/*
2 * Copyright © 2019 Matthias Clasen
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Matthias Clasen <mclasen@redhat.com>
18 */
19
20#include "config.h"
21
22#include "gtkcustomsorter.h"
23
24#include "gtkintl.h"
25#include "gtktypebuiltins.h"
26
27/**
28 * GtkCustomSorter:
29 *
30 * `GtkCustomSorter` is a `GtkSorter` implementation that sorts via a callback
31 * function.
32 */
33struct _GtkCustomSorter
34{
35 GtkSorter parent_instance;
36
37 GCompareDataFunc sort_func;
38 gpointer user_data;
39 GDestroyNotify user_destroy;
40};
41
42G_DEFINE_TYPE (GtkCustomSorter, gtk_custom_sorter, GTK_TYPE_SORTER)
43
44static GtkOrdering
45gtk_custom_sorter_compare (GtkSorter *sorter,
46 gpointer item1,
47 gpointer item2)
48{
49 GtkCustomSorter *self = GTK_CUSTOM_SORTER (ptr: sorter);
50
51 if (!self->sort_func)
52 return GTK_ORDERING_EQUAL;
53
54 return gtk_ordering_from_cmpfunc (cmpfunc_result: self->sort_func (item1, item2, self->user_data));
55}
56
57static GtkSorterOrder
58gtk_custom_sorter_get_order (GtkSorter *sorter)
59{
60 GtkCustomSorter *self = GTK_CUSTOM_SORTER (ptr: sorter);
61
62 if (!self->sort_func)
63 return GTK_SORTER_ORDER_NONE;
64
65 return GTK_SORTER_ORDER_PARTIAL;
66}
67
68static void
69gtk_custom_sorter_dispose (GObject *object)
70{
71 GtkCustomSorter *self = GTK_CUSTOM_SORTER (ptr: object);
72
73 if (self->user_destroy)
74 self->user_destroy (self->user_data);
75
76 self->sort_func = NULL;
77 self->user_destroy = NULL;
78 self->user_data = NULL;
79
80 G_OBJECT_CLASS (gtk_custom_sorter_parent_class)->dispose (object);
81}
82
83static void
84gtk_custom_sorter_class_init (GtkCustomSorterClass *class)
85{
86 GtkSorterClass *sorter_class = GTK_SORTER_CLASS (ptr: class);
87 GObjectClass *object_class = G_OBJECT_CLASS (class);
88
89 sorter_class->compare = gtk_custom_sorter_compare;
90 sorter_class->get_order = gtk_custom_sorter_get_order;
91
92 object_class->dispose = gtk_custom_sorter_dispose;
93}
94
95static void
96gtk_custom_sorter_init (GtkCustomSorter *self)
97{
98}
99
100/**
101 * gtk_custom_sorter_new:
102 * @sort_func: (nullable): the `GCompareDataFunc` to use for sorting
103 * @user_data: (nullable): user data to pass to @sort_func
104 * @user_destroy: (nullable): destroy notify for @user_data
105 *
106 * Creates a new `GtkSorter` that works by calling
107 * @sort_func to compare items.
108 *
109 * If @sort_func is %NULL, all items are considered equal.
110 *
111 * Returns: a new `GtkCustomSorter`
112 */
113GtkCustomSorter *
114gtk_custom_sorter_new (GCompareDataFunc sort_func,
115 gpointer user_data,
116 GDestroyNotify user_destroy)
117{
118 GtkCustomSorter *sorter;
119
120 sorter = g_object_new (GTK_TYPE_CUSTOM_SORTER, NULL);
121
122 gtk_custom_sorter_set_sort_func (self: sorter, sort_func, user_data, user_destroy);
123
124 return sorter;
125}
126
127/**
128 * gtk_custom_sorter_set_sort_func:
129 * @self: a `GtkCustomSorter`
130 * @sort_func: (nullable): function to sort items
131 * @user_data: (nullable): user data to pass to @match_func
132 * @user_destroy: destroy notify for @user_data
133 *
134 * Sets (or unsets) the function used for sorting items.
135 *
136 * If @sort_func is %NULL, all items are considered equal.
137 *
138 * If the sort func changes its sorting behavior,
139 * gtk_sorter_changed() needs to be called.
140 *
141 * If a previous function was set, its @user_destroy will be
142 * called now.
143 */
144void
145gtk_custom_sorter_set_sort_func (GtkCustomSorter *self,
146 GCompareDataFunc sort_func,
147 gpointer user_data,
148 GDestroyNotify user_destroy)
149{
150 g_return_if_fail (GTK_IS_CUSTOM_SORTER (self));
151 g_return_if_fail (sort_func || (user_data == NULL && !user_destroy));
152
153 if (self->user_destroy)
154 self->user_destroy (self->user_data);
155
156 self->sort_func = sort_func;
157 self->user_data = user_data;
158 self->user_destroy = user_destroy;
159
160 gtk_sorter_changed (self: GTK_SORTER (ptr: self), change: GTK_SORTER_CHANGE_DIFFERENT);
161}
162

source code of gtk/gtk/gtkcustomsorter.c