diff options
author | TheJackiMonster <thejackimonster@gmail.com> | 2021-11-25 22:45:04 +0100 |
---|---|---|
committer | TheJackiMonster <thejackimonster@gmail.com> | 2021-11-25 22:45:04 +0100 |
commit | 9b67d565baf5ce0f555cb38abdda22696cbfe778 (patch) | |
tree | b0da8719278f02b15c5360329e8488130d9cbfb5 | |
parent | 5df934d452aaedf319028740987de0e0dcac52d5 (diff) | |
download | messenger-gtk-9b67d565baf5ce0f555cb38abdda22696cbfe778.tar.gz messenger-gtk-9b67d565baf5ce0f555cb38abdda22696cbfe778.zip |
Added emoji picker
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | resources/css/style.css | 8 | ||||
-rw-r--r-- | resources/ui/chat.ui | 19 | ||||
-rw-r--r-- | resources/ui/picker.ui | 508 | ||||
-rw-r--r-- | src/application.c | 2 | ||||
-rw-r--r-- | src/ui/chat.c | 35 | ||||
-rw-r--r-- | src/ui/chat.h | 5 | ||||
-rw-r--r-- | src/ui/messenger.c | 2 | ||||
-rw-r--r-- | src/ui/picker.c | 251 | ||||
-rw-r--r-- | src/ui/picker.h | 65 | ||||
m--------- | submodules/gnome-characters | 0 |
12 files changed, 897 insertions, 6 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..65ecbeb --- /dev/null +++ b/.gitmodules | |||
@@ -0,0 +1,3 @@ | |||
1 | [submodule "submodules/gnome-characters"] | ||
2 | path = submodules/gnome-characters | ||
3 | url = https://gitlab.gnome.org/GNOME/gnome-characters.git | ||
@@ -15,6 +15,7 @@ SOURCES = messenger_gtk.c\ | |||
15 | ui/messenger.c\ | 15 | ui/messenger.c\ |
16 | ui/new_contact.c\ | 16 | ui/new_contact.c\ |
17 | ui/new_platform.c\ | 17 | ui/new_platform.c\ |
18 | ui/picker.c\ | ||
18 | ui/profile_entry.c\ | 19 | ui/profile_entry.c\ |
19 | ui/settings.c | 20 | ui/settings.c |
20 | 21 | ||
@@ -22,6 +23,7 @@ HEADERS = | |||
22 | 23 | ||
23 | LIBRARIES = gnunetchat | 24 | LIBRARIES = gnunetchat |
24 | PACKAGES = gnunetutil libhandy-1 gtk+-3.0 libnotify zbar libqrencode | 25 | PACKAGES = gnunetutil libhandy-1 gtk+-3.0 libnotify zbar libqrencode |
26 | INCLUDES = submodules/gnome-characters/lib | ||
25 | 27 | ||
26 | GNU_CC ?= gcc | 28 | GNU_CC ?= gcc |
27 | GNU_LD ?= gcc | 29 | GNU_LD ?= gcc |
@@ -38,6 +40,7 @@ OBJECT_FILES = $(SOURCE_FILES:%.c=%.o) | |||
38 | HEADER_FILES = $(addprefix $(SOURCE_DIR), $(HEADERS)) | 40 | HEADER_FILES = $(addprefix $(SOURCE_DIR), $(HEADERS)) |
39 | LIBRARY_FLAGS = $(addprefix -l, $(LIBRARIES)) | 41 | LIBRARY_FLAGS = $(addprefix -l, $(LIBRARIES)) |
40 | PACKAGE_FLAGS = $(shell pkg-config --cflags --libs $(PACKAGES)) | 42 | PACKAGE_FLAGS = $(shell pkg-config --cflags --libs $(PACKAGES)) |
43 | INCLUDE_FLAGS = $(addprefix -I, $(INCLUDES)) | ||
41 | 44 | ||
42 | all: $(BINARY) | 45 | all: $(BINARY) |
43 | 46 | ||
@@ -48,7 +51,7 @@ release: CFLAGS += $(RELEASEFLAGS) | |||
48 | release: $(BINARY) | 51 | release: $(BINARY) |
49 | 52 | ||
50 | %.o: %.c | 53 | %.o: %.c |
51 | $(GNU_CC) $(CFLAGS) -c $< -o $@ $(LIBRARY_FLAGS) $(PACKAGE_FLAGS) | 54 | $(GNU_CC) $(CFLAGS) -c $< -o $@ $(LIBRARY_FLAGS) $(PACKAGE_FLAGS) $(INCLUDE_FLAGS) |
52 | 55 | ||
53 | $(BINARY): $(OBJECT_FILES) | 56 | $(BINARY): $(OBJECT_FILES) |
54 | $(GNU_LD) $(LDFLAGS) $^ -o $@ $(LIBRARY_FLAGS) $(PACKAGE_FLAGS) | 57 | $(GNU_LD) $(LDFLAGS) $^ -o $@ $(LIBRARY_FLAGS) $(PACKAGE_FLAGS) |
diff --git a/resources/css/style.css b/resources/css/style.css index a75a5e2..1f923d6 100644 --- a/resources/css/style.css +++ b/resources/css/style.css | |||
@@ -61,6 +61,14 @@ | |||
61 | padding: 2px 4px; | 61 | padding: 2px 4px; |
62 | } | 62 | } |
63 | 63 | ||
64 | .picker-switcher-box { | ||
65 | padding: 0px 8px; | ||
66 | } | ||
67 | |||
68 | .emoji-flow-box { | ||
69 | font-size: large; | ||
70 | } | ||
71 | |||
64 | .settings-entry { | 72 | .settings-entry { |
65 | margin: 8px; | 73 | margin: 8px; |
66 | } | 74 | } |
diff --git a/resources/ui/chat.ui b/resources/ui/chat.ui index c653b3e..f6e8cc8 100644 --- a/resources/ui/chat.ui +++ b/resources/ui/chat.ui | |||
@@ -169,6 +169,22 @@ Author: Tobias Frisch | |||
169 | </packing> | 169 | </packing> |
170 | </child> | 170 | </child> |
171 | <child> | 171 | <child> |
172 | <object class="GtkRevealer" id="picker_revealer"> | ||
173 | <property name="visible">True</property> | ||
174 | <property name="can-focus">False</property> | ||
175 | <property name="transition-type">slide-up</property> | ||
176 | <child> | ||
177 | <placeholder/> | ||
178 | </child> | ||
179 | </object> | ||
180 | <packing> | ||
181 | <property name="expand">False</property> | ||
182 | <property name="fill">True</property> | ||
183 | <property name="pack-type">end</property> | ||
184 | <property name="position">2</property> | ||
185 | </packing> | ||
186 | </child> | ||
187 | <child> | ||
172 | <object class="GtkBox"> | 188 | <object class="GtkBox"> |
173 | <property name="visible">True</property> | 189 | <property name="visible">True</property> |
174 | <property name="can-focus">False</property> | 190 | <property name="can-focus">False</property> |
@@ -263,7 +279,8 @@ Author: Tobias Frisch | |||
263 | <packing> | 279 | <packing> |
264 | <property name="expand">False</property> | 280 | <property name="expand">False</property> |
265 | <property name="fill">True</property> | 281 | <property name="fill">True</property> |
266 | <property name="position">2</property> | 282 | <property name="pack-type">end</property> |
283 | <property name="position">3</property> | ||
267 | </packing> | 284 | </packing> |
268 | </child> | 285 | </child> |
269 | </object> | 286 | </object> |
diff --git a/resources/ui/picker.ui b/resources/ui/picker.ui new file mode 100644 index 0000000..fec48e5 --- /dev/null +++ b/resources/ui/picker.ui | |||
@@ -0,0 +1,508 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | <!-- Generated with glade 3.38.2 | ||
3 | |||
4 | Copyright (C) 2021 GNUnet e.V. | ||
5 | |||
6 | GNUnet is free software: you can redistribute it and/or modify it | ||
7 | under the terms of the GNU Affero General Public License as published | ||
8 | by the Free Software Foundation, either version 3 of the License, | ||
9 | or (at your option) any later version. | ||
10 | |||
11 | GNUnet is distributed in the hope that it will be useful, but | ||
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | Affero General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU Affero General Public License | ||
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | |||
19 | SPDX-License-Identifier: AGPL3.0-or-later | ||
20 | Author: Tobias Frisch | ||
21 | |||
22 | --> | ||
23 | <interface> | ||
24 | <requires lib="gtk+" version="3.24"/> | ||
25 | <requires lib="libhandy" version="1.2"/> | ||
26 | <object class="GtkBox" id="picker_box"> | ||
27 | <property name="height-request">250</property> | ||
28 | <property name="visible">True</property> | ||
29 | <property name="can-focus">False</property> | ||
30 | <property name="orientation">vertical</property> | ||
31 | <child> | ||
32 | <object class="GtkStack" id="picker_stack"> | ||
33 | <property name="visible">True</property> | ||
34 | <property name="can-focus">False</property> | ||
35 | <child> | ||
36 | <object class="GtkBox"> | ||
37 | <property name="visible">True</property> | ||
38 | <property name="can-focus">False</property> | ||
39 | <property name="orientation">vertical</property> | ||
40 | <child> | ||
41 | <object class="GtkScrolledWindow"> | ||
42 | <property name="visible">True</property> | ||
43 | <property name="can-focus">True</property> | ||
44 | <property name="vscrollbar-policy">never</property> | ||
45 | <property name="shadow-type">in</property> | ||
46 | <child> | ||
47 | <object class="GtkViewport"> | ||
48 | <property name="visible">True</property> | ||
49 | <property name="can-focus">False</property> | ||
50 | <child> | ||
51 | <object class="HdyViewSwitcherBar" id="emoji_switcher_bar"> | ||
52 | <property name="visible">True</property> | ||
53 | <property name="can-focus">False</property> | ||
54 | <property name="stack">emoji_stack</property> | ||
55 | <property name="reveal">True</property> | ||
56 | </object> | ||
57 | </child> | ||
58 | </object> | ||
59 | </child> | ||
60 | </object> | ||
61 | <packing> | ||
62 | <property name="expand">False</property> | ||
63 | <property name="fill">True</property> | ||
64 | <property name="position">0</property> | ||
65 | </packing> | ||
66 | </child> | ||
67 | <child> | ||
68 | <object class="GtkStack" id="emoji_stack"> | ||
69 | <property name="visible">True</property> | ||
70 | <property name="can-focus">False</property> | ||
71 | <child> | ||
72 | <object class="GtkScrolledWindow"> | ||
73 | <property name="visible">True</property> | ||
74 | <property name="can-focus">True</property> | ||
75 | <property name="shadow-type">in</property> | ||
76 | <child> | ||
77 | <object class="GtkViewport"> | ||
78 | <property name="visible">True</property> | ||
79 | <property name="can-focus">False</property> | ||
80 | <child> | ||
81 | <object class="GtkFlowBox" id="recent_flow_box"> | ||
82 | <property name="visible">True</property> | ||
83 | <property name="can-focus">False</property> | ||
84 | <property name="border-width">8</property> | ||
85 | <property name="homogeneous">True</property> | ||
86 | <property name="max-children-per-line">8</property> | ||
87 | <property name="selection-mode">none</property> | ||
88 | <style> | ||
89 | <class name="emoji-flow-box"/> | ||
90 | </style> | ||
91 | </object> | ||
92 | </child> | ||
93 | </object> | ||
94 | </child> | ||
95 | </object> | ||
96 | <packing> | ||
97 | <property name="name">recent</property> | ||
98 | <property name="icon-name">emoji-recent-symbolic</property> | ||
99 | </packing> | ||
100 | </child> | ||
101 | <child> | ||
102 | <object class="GtkScrolledWindow"> | ||
103 | <property name="visible">True</property> | ||
104 | <property name="can-focus">True</property> | ||
105 | <property name="shadow-type">in</property> | ||
106 | <child> | ||
107 | <object class="GtkViewport"> | ||
108 | <property name="visible">True</property> | ||
109 | <property name="can-focus">False</property> | ||
110 | <child> | ||
111 | <object class="GtkFlowBox" id="people_flow_box"> | ||
112 | <property name="visible">True</property> | ||
113 | <property name="can-focus">False</property> | ||
114 | <property name="border-width">8</property> | ||
115 | <property name="homogeneous">True</property> | ||
116 | <property name="max-children-per-line">8</property> | ||
117 | <property name="selection-mode">none</property> | ||
118 | <style> | ||
119 | <class name="emoji-flow-box"/> | ||
120 | </style> | ||
121 | </object> | ||
122 | </child> | ||
123 | </object> | ||
124 | </child> | ||
125 | </object> | ||
126 | <packing> | ||
127 | <property name="name">people</property> | ||
128 | <property name="icon-name">emoji-people-symbolic</property> | ||
129 | <property name="position">1</property> | ||
130 | </packing> | ||
131 | </child> | ||
132 | <child> | ||
133 | <object class="GtkScrolledWindow"> | ||
134 | <property name="visible">True</property> | ||
135 | <property name="can-focus">True</property> | ||
136 | <property name="shadow-type">in</property> | ||
137 | <child> | ||
138 | <object class="GtkViewport"> | ||
139 | <property name="visible">True</property> | ||
140 | <property name="can-focus">False</property> | ||
141 | <child> | ||
142 | <object class="GtkFlowBox" id="nature_flow_box"> | ||
143 | <property name="visible">True</property> | ||
144 | <property name="can-focus">False</property> | ||
145 | <property name="border-width">8</property> | ||
146 | <property name="homogeneous">True</property> | ||
147 | <property name="max-children-per-line">8</property> | ||
148 | <property name="selection-mode">none</property> | ||
149 | <style> | ||
150 | <class name="emoji-flow-box"/> | ||
151 | </style> | ||
152 | </object> | ||
153 | </child> | ||
154 | </object> | ||
155 | </child> | ||
156 | </object> | ||
157 | <packing> | ||
158 | <property name="name">nature</property> | ||
159 | <property name="icon-name">emoji-nature-symbolic</property> | ||
160 | <property name="position">2</property> | ||
161 | </packing> | ||
162 | </child> | ||
163 | <child> | ||
164 | <object class="GtkScrolledWindow"> | ||
165 | <property name="visible">True</property> | ||
166 | <property name="can-focus">True</property> | ||
167 | <property name="shadow-type">in</property> | ||
168 | <child> | ||
169 | <object class="GtkViewport"> | ||
170 | <property name="visible">True</property> | ||
171 | <property name="can-focus">False</property> | ||
172 | <child> | ||
173 | <object class="GtkFlowBox" id="food_flow_box"> | ||
174 | <property name="visible">True</property> | ||
175 | <property name="can-focus">False</property> | ||
176 | <property name="border-width">8</property> | ||
177 | <property name="homogeneous">True</property> | ||
178 | <property name="max-children-per-line">8</property> | ||
179 | <property name="selection-mode">none</property> | ||
180 | <style> | ||
181 | <class name="emoji-flow-box"/> | ||
182 | </style> | ||
183 | </object> | ||
184 | </child> | ||
185 | </object> | ||
186 | </child> | ||
187 | </object> | ||
188 | <packing> | ||
189 | <property name="name">food</property> | ||
190 | <property name="icon-name">emoji-food-symbolic</property> | ||
191 | <property name="position">3</property> | ||
192 | </packing> | ||
193 | </child> | ||
194 | <child> | ||
195 | <object class="GtkScrolledWindow"> | ||
196 | <property name="visible">True</property> | ||
197 | <property name="can-focus">True</property> | ||
198 | <property name="shadow-type">in</property> | ||
199 | <child> | ||
200 | <object class="GtkViewport"> | ||
201 | <property name="visible">True</property> | ||
202 | <property name="can-focus">False</property> | ||
203 | <child> | ||
204 | <object class="GtkFlowBox" id="activities_flow_box"> | ||
205 | <property name="visible">True</property> | ||
206 | <property name="can-focus">False</property> | ||
207 | <property name="border-width">8</property> | ||
208 | <property name="homogeneous">True</property> | ||
209 | <property name="max-children-per-line">8</property> | ||
210 | <property name="selection-mode">none</property> | ||
211 | <style> | ||
212 | <class name="emoji-flow-box"/> | ||
213 | </style> | ||
214 | </object> | ||
215 | </child> | ||
216 | </object> | ||
217 | </child> | ||
218 | </object> | ||
219 | <packing> | ||
220 | <property name="name">activities</property> | ||
221 | <property name="icon-name">emoji-activities-symbolic</property> | ||
222 | <property name="position">4</property> | ||
223 | </packing> | ||
224 | </child> | ||
225 | <child> | ||
226 | <object class="GtkScrolledWindow"> | ||
227 | <property name="visible">True</property> | ||
228 | <property name="can-focus">True</property> | ||
229 | <property name="shadow-type">in</property> | ||
230 | <child> | ||
231 | <object class="GtkViewport"> | ||
232 | <property name="visible">True</property> | ||
233 | <property name="can-focus">False</property> | ||
234 | <child> | ||
235 | <object class="GtkFlowBox" id="travel_flow_box"> | ||
236 | <property name="visible">True</property> | ||
237 | <property name="can-focus">False</property> | ||
238 | <property name="border-width">8</property> | ||
239 | <property name="homogeneous">True</property> | ||
240 | <property name="max-children-per-line">8</property> | ||
241 | <property name="selection-mode">none</property> | ||
242 | <style> | ||
243 | <class name="emoji-flow-box"/> | ||
244 | </style> | ||
245 | </object> | ||
246 | </child> | ||
247 | </object> | ||
248 | </child> | ||
249 | </object> | ||
250 | <packing> | ||
251 | <property name="name">travel</property> | ||
252 | <property name="icon-name">emoji-travel-symbolic</property> | ||
253 | <property name="position">5</property> | ||
254 | </packing> | ||
255 | </child> | ||
256 | <child> | ||
257 | <object class="GtkScrolledWindow"> | ||
258 | <property name="visible">True</property> | ||
259 | <property name="can-focus">True</property> | ||
260 | <property name="shadow-type">in</property> | ||
261 | <child> | ||
262 | <object class="GtkViewport"> | ||
263 | <property name="visible">True</property> | ||
264 | <property name="can-focus">False</property> | ||
265 | <child> | ||
266 | <object class="GtkFlowBox" id="objects_flow_box"> | ||
267 | <property name="visible">True</property> | ||
268 | <property name="can-focus">False</property> | ||
269 | <property name="border-width">8</property> | ||
270 | <property name="homogeneous">True</property> | ||
271 | <property name="max-children-per-line">8</property> | ||
272 | <property name="selection-mode">none</property> | ||
273 | <style> | ||
274 | <class name="emoji-flow-box"/> | ||
275 | </style> | ||
276 | </object> | ||
277 | </child> | ||
278 | </object> | ||
279 | </child> | ||
280 | </object> | ||
281 | <packing> | ||
282 | <property name="name">objects</property> | ||
283 | <property name="icon-name">emoji-objects-symbolic</property> | ||
284 | <property name="position">6</property> | ||
285 | </packing> | ||
286 | </child> | ||
287 | <child> | ||
288 | <object class="GtkScrolledWindow"> | ||
289 | <property name="visible">True</property> | ||
290 | <property name="can-focus">True</property> | ||
291 | <property name="shadow-type">in</property> | ||
292 | <child> | ||
293 | <object class="GtkViewport"> | ||
294 | <property name="visible">True</property> | ||
295 | <property name="can-focus">False</property> | ||
296 | <child> | ||
297 | <object class="GtkFlowBox" id="symbols_flow_box"> | ||
298 | <property name="visible">True</property> | ||
299 | <property name="can-focus">False</property> | ||
300 | <property name="border-width">8</property> | ||
301 | <property name="homogeneous">True</property> | ||
302 | <property name="max-children-per-line">8</property> | ||
303 | <property name="selection-mode">none</property> | ||
304 | <style> | ||
305 | <class name="emoji-flow-box"/> | ||
306 | </style> | ||
307 | </object> | ||
308 | </child> | ||
309 | </object> | ||
310 | </child> | ||
311 | </object> | ||
312 | <packing> | ||
313 | <property name="name">symbols</property> | ||
314 | <property name="icon-name">emoji-symbols-symbolic</property> | ||
315 | <property name="position">7</property> | ||
316 | </packing> | ||
317 | </child> | ||
318 | <child> | ||
319 | <object class="GtkScrolledWindow"> | ||
320 | <property name="visible">True</property> | ||
321 | <property name="can-focus">True</property> | ||
322 | <property name="shadow-type">in</property> | ||
323 | <child> | ||
324 | <object class="GtkViewport"> | ||
325 | <property name="visible">True</property> | ||
326 | <property name="can-focus">False</property> | ||
327 | <child> | ||
328 | <object class="GtkFlowBox" id="flags_flow_box"> | ||
329 | <property name="visible">True</property> | ||
330 | <property name="can-focus">False</property> | ||
331 | <property name="border-width">8</property> | ||
332 | <property name="homogeneous">True</property> | ||
333 | <property name="max-children-per-line">8</property> | ||
334 | <property name="selection-mode">none</property> | ||
335 | <style> | ||
336 | <class name="emoji-flow-box"/> | ||
337 | </style> | ||
338 | </object> | ||
339 | </child> | ||
340 | </object> | ||
341 | </child> | ||
342 | </object> | ||
343 | <packing> | ||
344 | <property name="name">flags</property> | ||
345 | <property name="icon-name">emoji-flags-symbolic</property> | ||
346 | <property name="position">8</property> | ||
347 | </packing> | ||
348 | </child> | ||
349 | </object> | ||
350 | <packing> | ||
351 | <property name="expand">True</property> | ||
352 | <property name="fill">True</property> | ||
353 | <property name="pack-type">end</property> | ||
354 | <property name="position">1</property> | ||
355 | </packing> | ||
356 | </child> | ||
357 | <child> | ||
358 | <object class="HdySearchBar" id="emoji_search_bar"> | ||
359 | <property name="visible">True</property> | ||
360 | <property name="can-focus">False</property> | ||
361 | <property name="show-close-button">True</property> | ||
362 | <child> | ||
363 | <object class="GtkSearchEntry" id="emoji_search_entry"> | ||
364 | <property name="visible">True</property> | ||
365 | <property name="can-focus">True</property> | ||
366 | <property name="primary-icon-name">edit-find-symbolic</property> | ||
367 | <property name="primary-icon-activatable">False</property> | ||
368 | <property name="primary-icon-sensitive">False</property> | ||
369 | </object> | ||
370 | </child> | ||
371 | </object> | ||
372 | <packing> | ||
373 | <property name="expand">False</property> | ||
374 | <property name="fill">True</property> | ||
375 | <property name="position">2</property> | ||
376 | </packing> | ||
377 | </child> | ||
378 | </object> | ||
379 | <packing> | ||
380 | <property name="name">emoji</property> | ||
381 | <property name="title" translatable="yes">Emoji</property> | ||
382 | <property name="icon-name">face-smile-symbolic</property> | ||
383 | </packing> | ||
384 | </child> | ||
385 | <child> | ||
386 | <object class="GtkBox"> | ||
387 | <property name="visible">True</property> | ||
388 | <property name="can-focus">False</property> | ||
389 | <property name="orientation">vertical</property> | ||
390 | <child> | ||
391 | <placeholder/> | ||
392 | </child> | ||
393 | <child> | ||
394 | <placeholder/> | ||
395 | </child> | ||
396 | <child> | ||
397 | <placeholder/> | ||
398 | </child> | ||
399 | </object> | ||
400 | <packing> | ||
401 | <property name="name">gif</property> | ||
402 | <property name="title" translatable="yes">GIF</property> | ||
403 | <property name="icon-name">video-x-generic-symbolic</property> | ||
404 | <property name="position">1</property> | ||
405 | </packing> | ||
406 | </child> | ||
407 | <child> | ||
408 | <object class="GtkBox"> | ||
409 | <property name="visible">True</property> | ||
410 | <property name="can-focus">False</property> | ||
411 | <property name="orientation">vertical</property> | ||
412 | <child> | ||
413 | <placeholder/> | ||
414 | </child> | ||
415 | <child> | ||
416 | <placeholder/> | ||
417 | </child> | ||
418 | <child> | ||
419 | <placeholder/> | ||
420 | </child> | ||
421 | </object> | ||
422 | <packing> | ||
423 | <property name="name">stickers</property> | ||
424 | <property name="title" translatable="yes">Stickers</property> | ||
425 | <property name="icon-name">image-x-generic-symbolic</property> | ||
426 | <property name="position">2</property> | ||
427 | </packing> | ||
428 | </child> | ||
429 | </object> | ||
430 | <packing> | ||
431 | <property name="expand">True</property> | ||
432 | <property name="fill">True</property> | ||
433 | <property name="position">1</property> | ||
434 | </packing> | ||
435 | </child> | ||
436 | <child> | ||
437 | <object class="GtkBox"> | ||
438 | <property name="visible">True</property> | ||
439 | <property name="can-focus">False</property> | ||
440 | <child> | ||
441 | <object class="GtkButton" id="search_button"> | ||
442 | <property name="visible">True</property> | ||
443 | <property name="can-focus">True</property> | ||
444 | <property name="receives-default">True</property> | ||
445 | <property name="valign">center</property> | ||
446 | <property name="relief">none</property> | ||
447 | <child> | ||
448 | <object class="GtkImage"> | ||
449 | <property name="visible">True</property> | ||
450 | <property name="can-focus">False</property> | ||
451 | <property name="icon-name">system-search-symbolic</property> | ||
452 | </object> | ||
453 | </child> | ||
454 | </object> | ||
455 | <packing> | ||
456 | <property name="expand">False</property> | ||
457 | <property name="fill">True</property> | ||
458 | <property name="position">0</property> | ||
459 | </packing> | ||
460 | </child> | ||
461 | <child> | ||
462 | <object class="HdyViewSwitcherBar" id="picker_switcher_bar"> | ||
463 | <property name="visible">True</property> | ||
464 | <property name="can-focus">False</property> | ||
465 | <property name="policy">auto</property> | ||
466 | <property name="stack">picker_stack</property> | ||
467 | <property name="reveal">True</property> | ||
468 | </object> | ||
469 | <packing> | ||
470 | <property name="expand">True</property> | ||
471 | <property name="fill">True</property> | ||
472 | <property name="position">1</property> | ||
473 | </packing> | ||
474 | </child> | ||
475 | <child> | ||
476 | <object class="GtkButton" id="settings_button"> | ||
477 | <property name="visible">True</property> | ||
478 | <property name="can-focus">True</property> | ||
479 | <property name="receives-default">True</property> | ||
480 | <property name="valign">center</property> | ||
481 | <property name="relief">none</property> | ||
482 | <child> | ||
483 | <object class="GtkImage"> | ||
484 | <property name="visible">True</property> | ||
485 | <property name="can-focus">False</property> | ||
486 | <property name="icon-name">preferences-other-symbolic</property> | ||
487 | </object> | ||
488 | </child> | ||
489 | </object> | ||
490 | <packing> | ||
491 | <property name="expand">False</property> | ||
492 | <property name="fill">True</property> | ||
493 | <property name="pack-type">end</property> | ||
494 | <property name="position">2</property> | ||
495 | </packing> | ||
496 | </child> | ||
497 | <style> | ||
498 | <class name="picker-switcher-box"/> | ||
499 | </style> | ||
500 | </object> | ||
501 | <packing> | ||
502 | <property name="expand">False</property> | ||
503 | <property name="fill">True</property> | ||
504 | <property name="position">3</property> | ||
505 | </packing> | ||
506 | </child> | ||
507 | </object> | ||
508 | </interface> | ||
diff --git a/src/application.c b/src/application.c index dfb214a..2062b82 100644 --- a/src/application.c +++ b/src/application.c | |||
@@ -157,8 +157,6 @@ application_run(MESSENGER_Application *app) | |||
157 | 157 | ||
158 | pthread_join(app->chat.tid, NULL); | 158 | pthread_join(app->chat.tid, NULL); |
159 | 159 | ||
160 | ui_messenger_cleanup(&(app->ui.messenger)); | ||
161 | |||
162 | g_hash_table_destroy(app->ui.bindings); | 160 | g_hash_table_destroy(app->ui.bindings); |
163 | 161 | ||
164 | notify_uninit(); | 162 | notify_uninit(); |
diff --git a/src/ui/chat.c b/src/ui/chat.c index b4dcca9..42943c3 100644 --- a/src/ui/chat.c +++ b/src/ui/chat.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "chat.h" | 25 | #include "chat.h" |
26 | 26 | ||
27 | #include "messenger.h" | 27 | #include "messenger.h" |
28 | #include "picker.h" | ||
28 | #include "../application.h" | 29 | #include "../application.h" |
29 | 30 | ||
30 | static void | 31 | static void |
@@ -67,7 +68,7 @@ handle_send_text_buffer_changed(GtkTextBuffer *buffer, | |||
67 | 68 | ||
68 | gtk_image_set_from_icon_name( | 69 | gtk_image_set_from_icon_name( |
69 | symbol, | 70 | symbol, |
70 | 0 < g_utf8_strlen(text, 1)? | 71 | 0 < strlen(text)? |
71 | "mail-send-symbolic" : | 72 | "mail-send-symbolic" : |
72 | "audio-input-microphone-symbolic", | 73 | "audio-input-microphone-symbolic", |
73 | GTK_ICON_SIZE_BUTTON | 74 | GTK_ICON_SIZE_BUTTON |
@@ -86,7 +87,7 @@ _send_text_from_view(MESSENGER_Application *app, | |||
86 | 87 | ||
87 | const gchar *text = gtk_text_buffer_get_text(buffer, &start, &end, TRUE); | 88 | const gchar *text = gtk_text_buffer_get_text(buffer, &start, &end, TRUE); |
88 | 89 | ||
89 | if (0 == g_utf8_strlen(text, 1)) | 90 | if (0 == strlen(text)) |
90 | return FALSE; | 91 | return FALSE; |
91 | 92 | ||
92 | struct GNUNET_CHAT_Context *context = g_hash_table_lookup( | 93 | struct GNUNET_CHAT_Context *context = g_hash_table_lookup( |
@@ -132,6 +133,16 @@ handle_send_text_key_press (GtkWidget *widget, | |||
132 | return _send_text_from_view(app, GTK_TEXT_VIEW(widget)); | 133 | return _send_text_from_view(app, GTK_TEXT_VIEW(widget)); |
133 | } | 134 | } |
134 | 135 | ||
136 | static void | ||
137 | handle_picker_button_click(UNUSED GtkButton *button, | ||
138 | gpointer user_data) | ||
139 | { | ||
140 | GtkRevealer *revealer = GTK_REVEALER(user_data); | ||
141 | gboolean reveal = !gtk_revealer_get_child_revealed(revealer); | ||
142 | |||
143 | gtk_revealer_set_reveal_child(revealer, reveal); | ||
144 | } | ||
145 | |||
135 | UI_CHAT_Handle* | 146 | UI_CHAT_Handle* |
136 | ui_chat_new(MESSENGER_Application *app) | 147 | ui_chat_new(MESSENGER_Application *app) |
137 | { | 148 | { |
@@ -239,12 +250,32 @@ ui_chat_new(MESSENGER_Application *app) | |||
239 | handle->send_text_view | 250 | handle->send_text_view |
240 | ); | 251 | ); |
241 | 252 | ||
253 | handle->picker_revealer = GTK_REVEALER( | ||
254 | gtk_builder_get_object(handle->builder, "picker_revealer") | ||
255 | ); | ||
256 | |||
257 | handle->picker = ui_picker_new(app, handle); | ||
258 | |||
259 | gtk_container_add( | ||
260 | GTK_CONTAINER(handle->picker_revealer), | ||
261 | handle->picker->picker_box | ||
262 | ); | ||
263 | |||
264 | g_signal_connect( | ||
265 | handle->emoji_button, | ||
266 | "clicked", | ||
267 | G_CALLBACK(handle_picker_button_click), | ||
268 | handle->picker_revealer | ||
269 | ); | ||
270 | |||
242 | return handle; | 271 | return handle; |
243 | } | 272 | } |
244 | 273 | ||
245 | void | 274 | void |
246 | ui_chat_delete(UI_CHAT_Handle *handle) | 275 | ui_chat_delete(UI_CHAT_Handle *handle) |
247 | { | 276 | { |
277 | ui_picker_delete(handle->picker); | ||
278 | |||
248 | g_object_unref(handle->builder); | 279 | g_object_unref(handle->builder); |
249 | 280 | ||
250 | g_free(handle); | 281 | g_free(handle); |
diff --git a/src/ui/chat.h b/src/ui/chat.h index 250ac08..77e4553 100644 --- a/src/ui/chat.h +++ b/src/ui/chat.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <libnotify/notify.h> | 30 | #include <libnotify/notify.h> |
31 | 31 | ||
32 | typedef struct MESSENGER_Application MESSENGER_Application; | 32 | typedef struct MESSENGER_Application MESSENGER_Application; |
33 | typedef struct UI_PICKER_Handle UI_PICKER_Handle; | ||
33 | 34 | ||
34 | typedef struct UI_CHAT_Handle | 35 | typedef struct UI_CHAT_Handle |
35 | { | 36 | { |
@@ -49,6 +50,10 @@ typedef struct UI_CHAT_Handle | |||
49 | GtkButton *emoji_button; | 50 | GtkButton *emoji_button; |
50 | GtkButton *send_record_button; | 51 | GtkButton *send_record_button; |
51 | GtkImage *send_record_symbol; | 52 | GtkImage *send_record_symbol; |
53 | |||
54 | GtkRevealer *picker_revealer; | ||
55 | |||
56 | UI_PICKER_Handle *picker; | ||
52 | } UI_CHAT_Handle; | 57 | } UI_CHAT_Handle; |
53 | 58 | ||
54 | UI_CHAT_Handle* | 59 | UI_CHAT_Handle* |
diff --git a/src/ui/messenger.c b/src/ui/messenger.c index 669ef19..8f463ca 100644 --- a/src/ui/messenger.c +++ b/src/ui/messenger.c | |||
@@ -150,6 +150,8 @@ handle_main_window_destroy(UNUSED GtkWidget *window, | |||
150 | { | 150 | { |
151 | MESSENGER_Application *app = (MESSENGER_Application*) user_data; | 151 | MESSENGER_Application *app = (MESSENGER_Application*) user_data; |
152 | 152 | ||
153 | ui_messenger_cleanup(&(app->ui.messenger)); | ||
154 | |||
153 | application_exit(app, MESSENGER_QUIT); | 155 | application_exit(app, MESSENGER_QUIT); |
154 | } | 156 | } |
155 | 157 | ||
diff --git a/src/ui/picker.c b/src/ui/picker.c new file mode 100644 index 0000000..f6c89a6 --- /dev/null +++ b/src/ui/picker.c | |||
@@ -0,0 +1,251 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @author Tobias Frisch | ||
22 | * @file ui/picker.c | ||
23 | */ | ||
24 | |||
25 | #include "picker.h" | ||
26 | |||
27 | #include "../application.h" | ||
28 | |||
29 | #include <emoji.h> | ||
30 | |||
31 | static void | ||
32 | handle_emoji_button_click(GtkButton *button, | ||
33 | gpointer user_data) | ||
34 | { | ||
35 | GtkTextView *text_view = GTK_TEXT_VIEW(user_data); | ||
36 | GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(text_view); | ||
37 | |||
38 | const gchar *label = gtk_button_get_label(button); | ||
39 | |||
40 | if (label) | ||
41 | gtk_text_buffer_insert_at_cursor(text_buffer, label, strlen(label)); | ||
42 | } | ||
43 | |||
44 | static void | ||
45 | _add_emoji_buttons(GtkFlowBox *flow_box, | ||
46 | GtkTextView *text_view, | ||
47 | size_t characters_count, | ||
48 | const uint32_t *characters) | ||
49 | { | ||
50 | for (size_t i = 0; i < characters_count; i++) { | ||
51 | GString *string = g_string_new(""); | ||
52 | g_string_append_unichar(string, (gunichar) characters[i]); | ||
53 | |||
54 | GtkButton *emoji_button = GTK_BUTTON( | ||
55 | gtk_button_new_with_label(string->str) | ||
56 | ); | ||
57 | |||
58 | gtk_button_set_relief(emoji_button, GTK_RELIEF_NONE); | ||
59 | |||
60 | g_signal_connect( | ||
61 | emoji_button, | ||
62 | "clicked", | ||
63 | G_CALLBACK(handle_emoji_button_click), | ||
64 | text_view | ||
65 | ); | ||
66 | |||
67 | gtk_flow_box_insert(flow_box, GTK_WIDGET(emoji_button), -1); | ||
68 | gtk_widget_show(GTK_WIDGET(emoji_button)); | ||
69 | |||
70 | g_string_free(string, TRUE); | ||
71 | } | ||
72 | } | ||
73 | |||
74 | static void | ||
75 | handle_search_button_click(UNUSED GtkButton *button, | ||
76 | gpointer user_data) | ||
77 | { | ||
78 | UI_PICKER_Handle *handle = (UI_PICKER_Handle*) user_data; | ||
79 | |||
80 | const gchar* picked = gtk_stack_get_visible_child_name(handle->picker_stack); | ||
81 | |||
82 | HdySearchBar *search_bar = NULL; | ||
83 | |||
84 | if (0 == g_strcmp0(picked, "emoji")) | ||
85 | search_bar = handle->emoji_search_bar; | ||
86 | |||
87 | if (search_bar) | ||
88 | hdy_search_bar_set_search_mode( | ||
89 | search_bar, | ||
90 | !hdy_search_bar_get_search_mode(search_bar) | ||
91 | ); | ||
92 | } | ||
93 | |||
94 | UI_PICKER_Handle* | ||
95 | ui_picker_new(UNUSED MESSENGER_Application *app, | ||
96 | UI_CHAT_Handle *chat) | ||
97 | { | ||
98 | UI_PICKER_Handle *handle = g_malloc(sizeof(UI_PICKER_Handle)); | ||
99 | |||
100 | handle->builder = gtk_builder_new_from_file( | ||
101 | "resources/ui/picker.ui" | ||
102 | ); | ||
103 | |||
104 | handle->picker_box = GTK_WIDGET( | ||
105 | gtk_builder_get_object(handle->builder, "picker_box") | ||
106 | ); | ||
107 | |||
108 | handle->picker_stack = GTK_STACK( | ||
109 | gtk_builder_get_object(handle->builder, "picker_stack") | ||
110 | ); | ||
111 | |||
112 | handle->emoji_stack = GTK_STACK( | ||
113 | gtk_builder_get_object(handle->builder, "emoji_stack") | ||
114 | ); | ||
115 | |||
116 | handle->picker_switcher_bar = HDY_VIEW_SWITCHER_BAR( | ||
117 | gtk_builder_get_object(handle->builder, "picker_switcher_bar") | ||
118 | ); | ||
119 | |||
120 | handle->emoji_switcher_bar = HDY_VIEW_SWITCHER_BAR( | ||
121 | gtk_builder_get_object(handle->builder, "emoji_switcher_bar") | ||
122 | ); | ||
123 | |||
124 | handle->recent_flow_box = GTK_FLOW_BOX( | ||
125 | gtk_builder_get_object(handle->builder, "recent_flow_box") | ||
126 | ); | ||
127 | |||
128 | handle->people_flow_box = GTK_FLOW_BOX( | ||
129 | gtk_builder_get_object(handle->builder, "people_flow_box") | ||
130 | ); | ||
131 | |||
132 | _add_emoji_buttons( | ||
133 | handle->people_flow_box, | ||
134 | chat->send_text_view, | ||
135 | EMOJI_SMILEYS_CHARACTER_COUNT, | ||
136 | emoji_smileys_characters | ||
137 | ); | ||
138 | |||
139 | handle->nature_flow_box = GTK_FLOW_BOX( | ||
140 | gtk_builder_get_object(handle->builder, "nature_flow_box") | ||
141 | ); | ||
142 | |||
143 | _add_emoji_buttons( | ||
144 | handle->nature_flow_box, | ||
145 | chat->send_text_view, | ||
146 | EMOJI_ANIMALS_CHARACTER_COUNT, | ||
147 | emoji_animals_characters | ||
148 | ); | ||
149 | |||
150 | handle->food_flow_box = GTK_FLOW_BOX( | ||
151 | gtk_builder_get_object(handle->builder, "food_flow_box") | ||
152 | ); | ||
153 | |||
154 | _add_emoji_buttons( | ||
155 | handle->food_flow_box, | ||
156 | chat->send_text_view, | ||
157 | EMOJI_FOOD_CHARACTER_COUNT, | ||
158 | emoji_food_characters | ||
159 | ); | ||
160 | |||
161 | handle->activities_flow_box = GTK_FLOW_BOX( | ||
162 | gtk_builder_get_object(handle->builder, "activities_flow_box") | ||
163 | ); | ||
164 | |||
165 | _add_emoji_buttons( | ||
166 | handle->activities_flow_box, | ||
167 | chat->send_text_view, | ||
168 | EMOJI_ACTIVITIES_CHARACTER_COUNT, | ||
169 | emoji_activities_characters | ||
170 | ); | ||
171 | |||
172 | handle->travel_flow_box = GTK_FLOW_BOX( | ||
173 | gtk_builder_get_object(handle->builder, "travel_flow_box") | ||
174 | ); | ||
175 | |||
176 | _add_emoji_buttons( | ||
177 | handle->travel_flow_box, | ||
178 | chat->send_text_view, | ||
179 | EMOJI_TRAVEL_CHARACTER_COUNT, | ||
180 | emoji_travel_characters | ||
181 | ); | ||
182 | |||
183 | handle->objects_flow_box = GTK_FLOW_BOX( | ||
184 | gtk_builder_get_object(handle->builder, "objects_flow_box") | ||
185 | ); | ||
186 | |||
187 | _add_emoji_buttons( | ||
188 | handle->objects_flow_box, | ||
189 | chat->send_text_view, | ||
190 | EMOJI_OBJECTS_CHARACTER_COUNT, | ||
191 | emoji_objects_characters | ||
192 | ); | ||
193 | |||
194 | handle->symbols_flow_box = GTK_FLOW_BOX( | ||
195 | gtk_builder_get_object(handle->builder, "symbols_flow_box") | ||
196 | ); | ||
197 | |||
198 | _add_emoji_buttons( | ||
199 | handle->symbols_flow_box, | ||
200 | chat->send_text_view, | ||
201 | EMOJI_SYMBOLS_CHARACTER_COUNT, | ||
202 | emoji_symbols_characters | ||
203 | ); | ||
204 | |||
205 | handle->flags_flow_box = GTK_FLOW_BOX( | ||
206 | gtk_builder_get_object(handle->builder, "flags_flow_box") | ||
207 | ); | ||
208 | |||
209 | _add_emoji_buttons( | ||
210 | handle->flags_flow_box, | ||
211 | chat->send_text_view, | ||
212 | EMOJI_FLAGS_CHARACTER_COUNT, | ||
213 | emoji_flags_characters | ||
214 | ); | ||
215 | |||
216 | handle->emoji_search_bar = HDY_SEARCH_BAR( | ||
217 | gtk_builder_get_object(handle->builder, "emoji_search_bar") | ||
218 | ); | ||
219 | |||
220 | handle->emoji_search_entry = GTK_SEARCH_ENTRY( | ||
221 | gtk_builder_get_object(handle->builder, "emoji_search_entry") | ||
222 | ); | ||
223 | |||
224 | handle->search_button = GTK_BUTTON( | ||
225 | gtk_builder_get_object(handle->builder, "search_button") | ||
226 | ); | ||
227 | |||
228 | g_signal_connect( | ||
229 | handle->search_button, | ||
230 | "clicked", | ||
231 | G_CALLBACK(handle_search_button_click), | ||
232 | handle | ||
233 | ); | ||
234 | |||
235 | handle->settings_button = GTK_BUTTON( | ||
236 | gtk_builder_get_object(handle->builder, "settings_button") | ||
237 | ); | ||
238 | |||
239 | return handle; | ||
240 | } | ||
241 | |||
242 | void | ||
243 | ui_picker_delete(UI_PICKER_Handle *handle) | ||
244 | { | ||
245 | hdy_view_switcher_bar_set_stack(handle->picker_switcher_bar, NULL); | ||
246 | hdy_view_switcher_bar_set_stack(handle->emoji_switcher_bar, NULL); | ||
247 | |||
248 | g_object_unref(handle->builder); | ||
249 | |||
250 | g_free(handle); | ||
251 | } | ||
diff --git a/src/ui/picker.h b/src/ui/picker.h new file mode 100644 index 0000000..99c7fa2 --- /dev/null +++ b/src/ui/picker.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @author Tobias Frisch | ||
22 | * @file ui/picker.h | ||
23 | */ | ||
24 | |||
25 | #ifndef UI_PICKER_H_ | ||
26 | #define UI_PICKER_H_ | ||
27 | |||
28 | #include "chat.h" | ||
29 | |||
30 | typedef struct UI_PICKER_Handle | ||
31 | { | ||
32 | GtkBuilder *builder; | ||
33 | GtkWidget *picker_box; | ||
34 | |||
35 | GtkStack *picker_stack; | ||
36 | GtkStack *emoji_stack; | ||
37 | |||
38 | HdyViewSwitcherBar *picker_switcher_bar; | ||
39 | HdyViewSwitcherBar *emoji_switcher_bar; | ||
40 | |||
41 | GtkFlowBox *recent_flow_box; | ||
42 | GtkFlowBox *people_flow_box; | ||
43 | GtkFlowBox *nature_flow_box; | ||
44 | GtkFlowBox *food_flow_box; | ||
45 | GtkFlowBox *activities_flow_box; | ||
46 | GtkFlowBox *travel_flow_box; | ||
47 | GtkFlowBox *objects_flow_box; | ||
48 | GtkFlowBox *symbols_flow_box; | ||
49 | GtkFlowBox *flags_flow_box; | ||
50 | |||
51 | HdySearchBar *emoji_search_bar; | ||
52 | GtkSearchEntry *emoji_search_entry; | ||
53 | |||
54 | GtkButton *search_button; | ||
55 | GtkButton *settings_button; | ||
56 | } UI_PICKER_Handle; | ||
57 | |||
58 | UI_PICKER_Handle* | ||
59 | ui_picker_new(MESSENGER_Application *app, | ||
60 | UI_CHAT_Handle *chat); | ||
61 | |||
62 | void | ||
63 | ui_picker_delete(UI_PICKER_Handle *handle); | ||
64 | |||
65 | #endif /* UI_PICKER_H_ */ | ||
diff --git a/submodules/gnome-characters b/submodules/gnome-characters new file mode 160000 | |||
Subproject f732b513cd5b8882d4176ed6ada1a78aba61a63 | |||