1 | /* |
2 | * Copyright © 2019 Benjamin Otte |
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: Benjamin Otte <otte@gnome.org> |
18 | */ |
19 | |
20 | #include "config.h" |
21 | |
22 | #include "gtkcustomfilter.h" |
23 | |
24 | #include "gtkintl.h" |
25 | #include "gtktypebuiltins.h" |
26 | |
27 | /** |
28 | * GtkCustomFilter: |
29 | * |
30 | * `GtkCustomFilter` determines whether to include items with a callback. |
31 | */ |
32 | struct _GtkCustomFilter |
33 | { |
34 | GtkFilter parent_instance; |
35 | |
36 | GtkCustomFilterFunc match_func; |
37 | gpointer user_data; |
38 | GDestroyNotify user_destroy; |
39 | }; |
40 | |
41 | G_DEFINE_TYPE (GtkCustomFilter, gtk_custom_filter, GTK_TYPE_FILTER) |
42 | |
43 | static gboolean |
44 | gtk_custom_filter_match (GtkFilter *filter, |
45 | gpointer item) |
46 | { |
47 | GtkCustomFilter *self = GTK_CUSTOM_FILTER (ptr: filter); |
48 | |
49 | if (!self->match_func) |
50 | return TRUE; |
51 | |
52 | return self->match_func (item, self->user_data); |
53 | } |
54 | |
55 | static GtkFilterMatch |
56 | gtk_custom_filter_get_strictness (GtkFilter *filter) |
57 | { |
58 | GtkCustomFilter *self = GTK_CUSTOM_FILTER (ptr: filter); |
59 | |
60 | if (!self->match_func) |
61 | return GTK_FILTER_MATCH_ALL; |
62 | |
63 | return GTK_FILTER_MATCH_SOME; |
64 | } |
65 | |
66 | static void |
67 | gtk_custom_filter_dispose (GObject *object) |
68 | { |
69 | GtkCustomFilter *self = GTK_CUSTOM_FILTER (ptr: object); |
70 | |
71 | if (self->user_destroy) |
72 | self->user_destroy (self->user_data); |
73 | |
74 | G_OBJECT_CLASS (gtk_custom_filter_parent_class)->dispose (object); |
75 | } |
76 | |
77 | static void |
78 | gtk_custom_filter_class_init (GtkCustomFilterClass *class) |
79 | { |
80 | GtkFilterClass *filter_class = GTK_FILTER_CLASS (ptr: class); |
81 | GObjectClass *object_class = G_OBJECT_CLASS (class); |
82 | |
83 | filter_class->match = gtk_custom_filter_match; |
84 | filter_class->get_strictness = gtk_custom_filter_get_strictness; |
85 | |
86 | object_class->dispose = gtk_custom_filter_dispose; |
87 | } |
88 | |
89 | static void |
90 | gtk_custom_filter_init (GtkCustomFilter *self) |
91 | { |
92 | } |
93 | |
94 | /** |
95 | * gtk_custom_filter_new: |
96 | * @match_func: (nullable): function to filter items |
97 | * @user_data: (nullable): user data to pass to @match_func |
98 | * @user_destroy: destroy notify for @user_data |
99 | * |
100 | * Creates a new filter using the given @match_func to filter |
101 | * items. |
102 | * |
103 | * If @match_func is %NULL, the filter matches all items. |
104 | * |
105 | * If the filter func changes its filtering behavior, |
106 | * gtk_filter_changed() needs to be called. |
107 | * |
108 | * Returns: a new `GtkCustomFilter` |
109 | **/ |
110 | GtkCustomFilter * |
111 | gtk_custom_filter_new (GtkCustomFilterFunc match_func, |
112 | gpointer user_data, |
113 | GDestroyNotify user_destroy) |
114 | { |
115 | GtkCustomFilter *result; |
116 | |
117 | result = g_object_new (GTK_TYPE_CUSTOM_FILTER, NULL); |
118 | |
119 | gtk_custom_filter_set_filter_func (self: result, match_func, user_data, user_destroy); |
120 | |
121 | return result; |
122 | } |
123 | |
124 | /** |
125 | * gtk_custom_filter_set_filter_func: |
126 | * @self: a `GtkCustomFilter` |
127 | * @match_func: (nullable): function to filter items |
128 | * @user_data: (nullable): user data to pass to @match_func |
129 | * @user_destroy: destroy notify for @user_data |
130 | * |
131 | * Sets the function used for filtering items. |
132 | * |
133 | * If @match_func is %NULL, the filter matches all items. |
134 | * |
135 | * If the filter func changes its filtering behavior, |
136 | * gtk_filter_changed() needs to be called. |
137 | * |
138 | * If a previous function was set, its @user_destroy will be |
139 | * called now. |
140 | */ |
141 | void |
142 | gtk_custom_filter_set_filter_func (GtkCustomFilter *self, |
143 | GtkCustomFilterFunc match_func, |
144 | gpointer user_data, |
145 | GDestroyNotify user_destroy) |
146 | { |
147 | g_return_if_fail (GTK_IS_CUSTOM_FILTER (self)); |
148 | g_return_if_fail (match_func || (user_data == NULL && !user_destroy)); |
149 | |
150 | if (self->user_destroy) |
151 | self->user_destroy (self->user_data); |
152 | |
153 | self->match_func = match_func; |
154 | self->user_data = user_data; |
155 | self->user_destroy = user_destroy; |
156 | |
157 | gtk_filter_changed (self: GTK_FILTER (ptr: self), change: GTK_FILTER_CHANGE_DIFFERENT); |
158 | } |
159 | |