Mercurial > pidgin
annotate finch/libgnt/gntwidget.c @ 18511:7ee0e0597a26
Add utility function to trigger some button when some key is pressed with
some other widget in focus. So now, pressing Insert in the accounts, status,
pounce dialog will activate the 'Add' button, pressing Delete will activate
the 'Delete' button. This can probably be used in some other places.
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Fri, 13 Jul 2007 01:42:29 +0000 |
parents | 5023ad94ebc9 |
children | 11cb1436e392 980d6e1b2d21 b25cb0775be3 |
rev | line source |
---|---|
18049
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
1 /** |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
2 * GNT - The GLib Ncurses Toolkit |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
3 * |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
4 * GNT is the legal property of its developers, whose names are too numerous |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
5 * to list here. Please refer to the COPYRIGHT file distributed with this |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
6 * source distribution. |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
7 * |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
8 * This library is free software; you can redistribute it and/or modify |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
9 * it under the terms of the GNU General Public License as published by |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
10 * the Free Software Foundation; either version 2 of the License, or |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
11 * (at your option) any later version. |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
12 * |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
13 * This program is distributed in the hope that it will be useful, |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
16 * GNU General Public License for more details. |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
17 * |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
18 * You should have received a copy of the GNU General Public License |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
19 * along with this program; if not, write to the Free Software |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
21 */ |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15945
diff
changeset
|
22 |
15817 | 23 /* Stuff brutally ripped from Gflib */ |
24 | |
25 #include "gntwidget.h" | |
26 #include "gntstyle.h" | |
27 #include "gntmarshal.h" | |
28 #include "gntutils.h" | |
29 #include "gnt.h" | |
30 | |
31 enum | |
32 { | |
33 SIG_DESTROY, | |
34 SIG_DRAW, | |
35 SIG_HIDE, | |
36 SIG_GIVE_FOCUS, | |
37 SIG_LOST_FOCUS, | |
38 SIG_KEY_PRESSED, | |
39 SIG_MAP, | |
40 SIG_ACTIVATE, | |
41 SIG_EXPOSE, | |
42 SIG_SIZE_REQUEST, | |
43 SIG_CONFIRM_SIZE, | |
44 SIG_SIZE_CHANGED, | |
45 SIG_POSITION, | |
46 SIG_CLICKED, | |
47 SIG_CONTEXT_MENU, | |
48 SIGS | |
49 }; | |
50 | |
51 static GObjectClass *parent_class = NULL; | |
52 static guint signals[SIGS] = { 0 }; | |
53 | |
54 static void init_widget(GntWidget *widget); | |
55 | |
56 static void | |
57 gnt_widget_init(GTypeInstance *instance, gpointer class) | |
58 { | |
59 GntWidget *widget = GNT_WIDGET(instance); | |
60 widget->priv.name = NULL; | |
61 GNTDEBUG; | |
62 } | |
63 | |
64 static void | |
65 gnt_widget_map(GntWidget *widget) | |
66 { | |
67 /* Get some default size for the widget */ | |
68 GNTDEBUG; | |
69 g_signal_emit(widget, signals[SIG_MAP], 0); | |
70 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_MAPPED); | |
71 } | |
72 | |
73 static void | |
74 gnt_widget_dispose(GObject *obj) | |
75 { | |
76 GntWidget *self = GNT_WIDGET(obj); | |
77 | |
78 if(!(GNT_WIDGET_FLAGS(self) & GNT_WIDGET_DESTROYING)) { | |
79 GNT_WIDGET_SET_FLAGS(self, GNT_WIDGET_DESTROYING); | |
80 | |
81 g_signal_emit(self, signals[SIG_DESTROY], 0); | |
82 | |
83 GNT_WIDGET_UNSET_FLAGS(self, GNT_WIDGET_DESTROYING); | |
84 } | |
85 | |
86 parent_class->dispose(obj); | |
87 GNTDEBUG; | |
88 } | |
89 | |
90 static void | |
91 gnt_widget_focus_change(GntWidget *widget) | |
92 { | |
93 if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED) | |
94 gnt_widget_draw(widget); | |
95 } | |
96 | |
97 static gboolean | |
98 gnt_widget_dummy_confirm_size(GntWidget *widget, int width, int height) | |
99 { | |
15945
92fa7d6e75b0
A few more fixes for resizing.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15943
diff
changeset
|
100 gboolean shadow; |
15817 | 101 if (width < widget->priv.minw || height < widget->priv.minh) |
102 return FALSE; | |
15945
92fa7d6e75b0
A few more fixes for resizing.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15943
diff
changeset
|
103 shadow = gnt_widget_has_shadow(widget); |
92fa7d6e75b0
A few more fixes for resizing.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15943
diff
changeset
|
104 if (widget->priv.width + shadow != width && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X)) |
15817 | 105 return FALSE; |
15945
92fa7d6e75b0
A few more fixes for resizing.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15943
diff
changeset
|
106 if (widget->priv.height + shadow != height && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y)) |
15817 | 107 return FALSE; |
108 return TRUE; | |
109 } | |
110 | |
111 static gboolean | |
112 context_menu(GntBindable *bind, GList *null) | |
113 { | |
114 gboolean ret = FALSE; | |
115 g_signal_emit(bind, signals[SIG_CONTEXT_MENU], 0, &ret); | |
116 return ret; | |
117 } | |
118 | |
119 static void | |
120 gnt_widget_class_init(GntWidgetClass *klass) | |
121 { | |
122 GObjectClass *obj_class = G_OBJECT_CLASS(klass); | |
123 | |
124 parent_class = g_type_class_peek_parent(klass); | |
125 | |
126 obj_class->dispose = gnt_widget_dispose; | |
127 | |
128 klass->destroy = gnt_widget_destroy; | |
129 klass->show = gnt_widget_show; | |
130 klass->draw = gnt_widget_draw; | |
131 klass->expose = gnt_widget_expose; | |
132 klass->map = gnt_widget_map; | |
133 klass->lost_focus = gnt_widget_focus_change; | |
134 klass->gained_focus = gnt_widget_focus_change; | |
135 klass->confirm_size = gnt_widget_dummy_confirm_size; | |
136 | |
137 klass->key_pressed = NULL; | |
138 klass->activate = NULL; | |
139 klass->clicked = NULL; | |
140 | |
141 signals[SIG_DESTROY] = | |
142 g_signal_new("destroy", | |
143 G_TYPE_FROM_CLASS(klass), | |
144 G_SIGNAL_RUN_LAST, | |
145 G_STRUCT_OFFSET(GntWidgetClass, destroy), | |
146 NULL, NULL, | |
147 g_cclosure_marshal_VOID__VOID, | |
148 G_TYPE_NONE, 0); | |
149 signals[SIG_GIVE_FOCUS] = | |
150 g_signal_new("gained-focus", | |
151 G_TYPE_FROM_CLASS(klass), | |
152 G_SIGNAL_RUN_LAST, | |
153 G_STRUCT_OFFSET(GntWidgetClass, gained_focus), | |
154 NULL, NULL, | |
155 g_cclosure_marshal_VOID__VOID, | |
156 G_TYPE_NONE, 0); | |
157 signals[SIG_LOST_FOCUS] = | |
158 g_signal_new("lost-focus", | |
159 G_TYPE_FROM_CLASS(klass), | |
160 G_SIGNAL_RUN_LAST, | |
161 G_STRUCT_OFFSET(GntWidgetClass, lost_focus), | |
162 NULL, NULL, | |
163 g_cclosure_marshal_VOID__VOID, | |
164 G_TYPE_NONE, 0); | |
165 signals[SIG_ACTIVATE] = | |
166 g_signal_new("activate", | |
167 G_TYPE_FROM_CLASS(klass), | |
168 G_SIGNAL_RUN_LAST, | |
169 G_STRUCT_OFFSET(GntWidgetClass, activate), | |
170 NULL, NULL, | |
171 g_cclosure_marshal_VOID__VOID, | |
172 G_TYPE_NONE, 0); | |
173 signals[SIG_MAP] = | |
174 g_signal_new("map", | |
175 G_TYPE_FROM_CLASS(klass), | |
176 G_SIGNAL_RUN_LAST, | |
177 G_STRUCT_OFFSET(GntWidgetClass, map), | |
178 NULL, NULL, | |
179 g_cclosure_marshal_VOID__VOID, | |
180 G_TYPE_NONE, 0); | |
181 signals[SIG_DRAW] = | |
182 g_signal_new("draw", | |
183 G_TYPE_FROM_CLASS(klass), | |
184 G_SIGNAL_RUN_LAST, | |
185 G_STRUCT_OFFSET(GntWidgetClass, draw), | |
186 NULL, NULL, | |
187 g_cclosure_marshal_VOID__VOID, | |
188 G_TYPE_NONE, 0); | |
189 signals[SIG_HIDE] = | |
190 g_signal_new("hide", | |
191 G_TYPE_FROM_CLASS(klass), | |
192 G_SIGNAL_RUN_LAST, | |
193 G_STRUCT_OFFSET(GntWidgetClass, hide), | |
194 NULL, NULL, | |
195 g_cclosure_marshal_VOID__VOID, | |
196 G_TYPE_NONE, 0); | |
197 signals[SIG_EXPOSE] = | |
198 g_signal_new("expose", | |
199 G_TYPE_FROM_CLASS(klass), | |
200 G_SIGNAL_RUN_LAST, | |
201 G_STRUCT_OFFSET(GntWidgetClass, expose), | |
202 NULL, NULL, | |
203 gnt_closure_marshal_VOID__INT_INT_INT_INT, | |
204 G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); | |
205 signals[SIG_POSITION] = | |
206 g_signal_new("position-set", | |
207 G_TYPE_FROM_CLASS(klass), | |
208 G_SIGNAL_RUN_LAST, | |
209 G_STRUCT_OFFSET(GntWidgetClass, set_position), | |
210 NULL, NULL, | |
211 gnt_closure_marshal_VOID__INT_INT, | |
212 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); | |
213 signals[SIG_SIZE_REQUEST] = | |
214 g_signal_new("size_request", | |
215 G_TYPE_FROM_CLASS(klass), | |
216 G_SIGNAL_RUN_LAST, | |
217 G_STRUCT_OFFSET(GntWidgetClass, size_request), | |
218 NULL, NULL, | |
219 g_cclosure_marshal_VOID__VOID, | |
220 G_TYPE_NONE, 0); | |
221 signals[SIG_SIZE_CHANGED] = | |
222 g_signal_new("size_changed", | |
223 G_TYPE_FROM_CLASS(klass), | |
224 G_SIGNAL_RUN_LAST, | |
225 G_STRUCT_OFFSET(GntWidgetClass, size_changed), | |
226 NULL, NULL, | |
227 gnt_closure_marshal_VOID__INT_INT, | |
228 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); | |
229 signals[SIG_CONFIRM_SIZE] = | |
230 g_signal_new("confirm_size", | |
231 G_TYPE_FROM_CLASS(klass), | |
232 G_SIGNAL_RUN_LAST, | |
233 G_STRUCT_OFFSET(GntWidgetClass, confirm_size), | |
234 NULL, NULL, | |
235 gnt_closure_marshal_BOOLEAN__INT_INT, | |
236 G_TYPE_BOOLEAN, 2, G_TYPE_INT, G_TYPE_INT); | |
237 signals[SIG_KEY_PRESSED] = | |
238 g_signal_new("key_pressed", | |
239 G_TYPE_FROM_CLASS(klass), | |
240 G_SIGNAL_RUN_LAST, | |
241 G_STRUCT_OFFSET(GntWidgetClass, key_pressed), | |
242 gnt_boolean_handled_accumulator, NULL, | |
243 gnt_closure_marshal_BOOLEAN__STRING, | |
244 G_TYPE_BOOLEAN, 1, G_TYPE_STRING); | |
245 | |
246 signals[SIG_CLICKED] = | |
247 g_signal_new("clicked", | |
248 G_TYPE_FROM_CLASS(klass), | |
249 G_SIGNAL_RUN_LAST, | |
250 G_STRUCT_OFFSET(GntWidgetClass, clicked), | |
251 gnt_boolean_handled_accumulator, NULL, | |
252 gnt_closure_marshal_BOOLEAN__INT_INT_INT, | |
253 G_TYPE_BOOLEAN, 3, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); | |
254 | |
255 signals[SIG_CONTEXT_MENU] = | |
256 g_signal_new("context-menu", | |
257 G_TYPE_FROM_CLASS(klass), | |
258 G_SIGNAL_RUN_LAST, | |
259 0, | |
260 gnt_boolean_handled_accumulator, NULL, | |
261 gnt_closure_marshal_BOOLEAN__VOID, | |
262 G_TYPE_BOOLEAN, 0); | |
263 | |
264 /* This is relevant for all widgets */ | |
265 gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "context-menu", context_menu, | |
266 GNT_KEY_POPUP, NULL); | |
267 gnt_bindable_register_binding(GNT_BINDABLE_CLASS(klass), "context-menu", GNT_KEY_F11, NULL); | |
268 | |
269 gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); | |
270 GNTDEBUG; | |
271 } | |
272 | |
273 /****************************************************************************** | |
274 * GntWidget API | |
275 *****************************************************************************/ | |
276 GType | |
277 gnt_widget_get_gtype(void) | |
278 { | |
279 static GType type = 0; | |
280 | |
281 if(type == 0) { | |
282 static const GTypeInfo info = { | |
283 sizeof(GntWidgetClass), | |
284 NULL, /* base_init */ | |
285 NULL, /* base_finalize */ | |
286 (GClassInitFunc)gnt_widget_class_init, | |
287 NULL, | |
288 NULL, /* class_data */ | |
289 sizeof(GntWidget), | |
290 0, /* n_preallocs */ | |
291 gnt_widget_init, /* instance_init */ | |
292 NULL /* value_table */ | |
293 }; | |
294 | |
295 type = g_type_register_static(GNT_TYPE_BINDABLE, | |
296 "GntWidget", | |
297 &info, G_TYPE_FLAG_ABSTRACT); | |
298 } | |
299 | |
300 return type; | |
301 } | |
302 | |
303 void gnt_widget_set_take_focus(GntWidget *widget, gboolean can) | |
304 { | |
305 if (can) | |
306 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); | |
307 else | |
308 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); | |
309 } | |
310 | |
311 /** | |
312 * gnt_widget_destroy: | |
313 * @obj: The #GntWidget instance. | |
314 * | |
315 * Emits the "destroy" signal notifying all reference holders that they | |
316 * should release @obj. | |
317 */ | |
318 void | |
319 gnt_widget_destroy(GntWidget *obj) | |
320 { | |
321 g_return_if_fail(GNT_IS_WIDGET(obj)); | |
322 | |
323 gnt_widget_hide(obj); | |
324 delwin(obj->window); | |
325 if(!(GNT_WIDGET_FLAGS(obj) & GNT_WIDGET_DESTROYING)) | |
326 g_object_run_dispose(G_OBJECT(obj)); | |
327 GNTDEBUG; | |
328 } | |
329 | |
330 void | |
331 gnt_widget_show(GntWidget *widget) | |
332 { | |
333 gnt_widget_draw(widget); | |
334 gnt_screen_occupy(widget); | |
335 } | |
336 | |
337 void | |
338 gnt_widget_draw(GntWidget *widget) | |
339 { | |
340 /* Draw the widget */ | |
341 if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_DRAWING)) | |
342 return; | |
343 | |
344 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_DRAWING); | |
345 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED)) { | |
346 gnt_widget_map(widget); | |
347 } | |
348 | |
349 if (widget->window == NULL) | |
350 { | |
351 #if 0 | |
352 int x, y, maxx, maxy, w, h; | |
353 int oldw, oldh; | |
354 gboolean shadow = TRUE; | |
355 | |
356 if (!gnt_widget_has_shadow(widget)) | |
357 shadow = FALSE; | |
358 | |
359 x = widget->priv.x; | |
360 y = widget->priv.y; | |
361 w = oldw = widget->priv.width + shadow; | |
362 h = oldh = widget->priv.height + shadow; | |
363 | |
364 getmaxyx(stdscr, maxy, maxx); | |
365 maxy -= 1; /* room for the taskbar */ | |
366 | |
367 x = MAX(0, x); | |
368 y = MAX(0, y); | |
369 if (x + w >= maxx) | |
370 x = MAX(0, maxx - w); | |
371 if (y + h >= maxy) | |
372 y = MAX(0, maxy - h); | |
373 | |
374 w = MIN(w, maxx); | |
375 h = MIN(h, maxy); | |
376 | |
377 widget->priv.x = x; | |
378 widget->priv.y = y; | |
379 if (w != oldw || h != oldh) { | |
380 widget->priv.width = w - shadow; | |
381 widget->priv.height = h - shadow; | |
382 g_signal_emit(widget, signals[SIG_SIZE_CHANGED], 0, oldw, oldh); | |
383 } | |
384 #else | |
385 widget->window = newpad(widget->priv.height + 20, widget->priv.width + 20); /* XXX: */ | |
386 #endif | |
387 init_widget(widget); | |
388 } | |
389 | |
390 g_signal_emit(widget, signals[SIG_DRAW], 0); | |
391 gnt_widget_queue_update(widget); | |
392 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_DRAWING); | |
393 } | |
394 | |
395 gboolean | |
396 gnt_widget_key_pressed(GntWidget *widget, const char *keys) | |
397 { | |
398 gboolean ret; | |
399 if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)) | |
400 return FALSE; | |
401 | |
402 if (gnt_bindable_perform_action_key(GNT_BINDABLE(widget), keys)) | |
403 return TRUE; | |
404 | |
405 keys = gnt_bindable_remap_keys(GNT_BINDABLE(widget), keys); | |
406 g_signal_emit(widget, signals[SIG_KEY_PRESSED], 0, keys, &ret); | |
407 return ret; | |
408 } | |
409 | |
410 gboolean | |
411 gnt_widget_clicked(GntWidget *widget, GntMouseEvent event, int x, int y) | |
412 { | |
413 gboolean ret; | |
414 g_signal_emit(widget, signals[SIG_CLICKED], 0, event, x, y, &ret); | |
415 return ret; | |
416 } | |
417 | |
418 void | |
419 gnt_widget_expose(GntWidget *widget, int x, int y, int width, int height) | |
420 { | |
421 g_signal_emit(widget, signals[SIG_EXPOSE], 0, x, y, width, height); | |
422 } | |
423 | |
424 void | |
425 gnt_widget_hide(GntWidget *widget) | |
426 { | |
427 g_signal_emit(widget, signals[SIG_HIDE], 0); | |
428 wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); | |
429 #if 0 | |
430 /* XXX: I have no clue why, but this seemed to be necessary. */ | |
431 if (gnt_widget_has_shadow(widget)) | |
432 mvwvline(widget->window, 1, widget->priv.width, ' ', widget->priv.height); | |
433 #endif | |
434 gnt_screen_release(widget); | |
435 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_INVISIBLE); | |
436 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_MAPPED); | |
437 } | |
438 | |
439 void | |
440 gnt_widget_set_position(GntWidget *wid, int x, int y) | |
441 { | |
442 g_signal_emit(wid, signals[SIG_POSITION], 0, x, y); | |
443 /* XXX: Need to install properties for these and g_object_notify */ | |
444 wid->priv.x = x; | |
445 wid->priv.y = y; | |
446 } | |
447 | |
448 void | |
449 gnt_widget_get_position(GntWidget *wid, int *x, int *y) | |
450 { | |
451 if (x) | |
452 *x = wid->priv.x; | |
453 if (y) | |
454 *y = wid->priv.y; | |
455 } | |
456 | |
457 void | |
458 gnt_widget_size_request(GntWidget *widget) | |
459 { | |
460 g_signal_emit(widget, signals[SIG_SIZE_REQUEST], 0); | |
461 } | |
462 | |
463 void | |
464 gnt_widget_get_size(GntWidget *wid, int *width, int *height) | |
465 { | |
466 gboolean shadow = TRUE; | |
467 if (!gnt_widget_has_shadow(wid)) | |
468 shadow = FALSE; | |
469 | |
470 if (width) | |
471 *width = wid->priv.width + shadow; | |
472 if (height) | |
473 *height = wid->priv.height + shadow; | |
474 | |
475 } | |
476 | |
477 static void | |
478 init_widget(GntWidget *widget) | |
479 { | |
480 gboolean shadow = TRUE; | |
481 | |
482 if (!gnt_widget_has_shadow(widget)) | |
483 shadow = FALSE; | |
484 | |
485 wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL)); | |
486 werase(widget->window); | |
487 | |
488 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER)) | |
489 { | |
490 /* - This is ugly. */ | |
491 /* - What's your point? */ | |
492 mvwvline(widget->window, 0, 0, ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL), widget->priv.height); | |
493 mvwvline(widget->window, 0, widget->priv.width - 1, | |
494 ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL), widget->priv.height); | |
495 mvwhline(widget->window, widget->priv.height - 1, 0, | |
496 ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL), widget->priv.width); | |
497 mvwhline(widget->window, 0, 0, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL), widget->priv.width); | |
498 mvwaddch(widget->window, 0, 0, ACS_ULCORNER | COLOR_PAIR(GNT_COLOR_NORMAL)); | |
499 mvwaddch(widget->window, 0, widget->priv.width - 1, | |
500 ACS_URCORNER | COLOR_PAIR(GNT_COLOR_NORMAL)); | |
501 mvwaddch(widget->window, widget->priv.height - 1, 0, | |
502 ACS_LLCORNER | COLOR_PAIR(GNT_COLOR_NORMAL)); | |
503 mvwaddch(widget->window, widget->priv.height - 1, widget->priv.width - 1, | |
504 ACS_LRCORNER | COLOR_PAIR(GNT_COLOR_NORMAL)); | |
505 } | |
506 | |
507 if (shadow) | |
508 { | |
509 wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_SHADOW)); | |
510 mvwvline(widget->window, 1, widget->priv.width, ' ', widget->priv.height); | |
511 mvwhline(widget->window, widget->priv.height, 1, ' ', widget->priv.width); | |
512 } | |
513 } | |
514 | |
515 gboolean | |
516 gnt_widget_set_size(GntWidget *widget, int width, int height) | |
517 { | |
518 gboolean ret = TRUE; | |
519 | |
520 if (gnt_widget_has_shadow(widget)) | |
521 { | |
522 width--; | |
523 height--; | |
524 } | |
525 if (width <= 0) | |
526 width = widget->priv.width; | |
527 if (height <= 0) | |
528 height = widget->priv.height; | |
529 | |
530 if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) | |
531 { | |
532 ret = gnt_widget_confirm_size(widget, width, height); | |
533 } | |
534 | |
535 if (ret) | |
536 { | |
537 gboolean shadow = TRUE; | |
538 int oldw, oldh; | |
539 | |
540 if (!gnt_widget_has_shadow(widget)) | |
541 shadow = FALSE; | |
542 | |
543 oldw = widget->priv.width; | |
544 oldh = widget->priv.height; | |
545 | |
546 widget->priv.width = width; | |
547 widget->priv.height = height; | |
15943
7db39d873d52
Do not crash when resizing with shadows turned on.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
548 if (width + shadow >= getmaxx(widget->window) || height + shadow >= getmaxy(widget->window)) { |
15817 | 549 delwin(widget->window); |
550 widget->window = newpad(height + 20, width + 20); | |
551 } | |
552 | |
553 g_signal_emit(widget, signals[SIG_SIZE_CHANGED], 0, oldw, oldh); | |
554 | |
555 if (widget->window) | |
556 { | |
557 init_widget(widget); | |
558 } | |
559 if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) | |
560 init_widget(widget); | |
561 else | |
562 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_MAPPED); | |
563 } | |
564 | |
565 return ret; | |
566 } | |
567 | |
568 gboolean | |
569 gnt_widget_set_focus(GntWidget *widget, gboolean set) | |
570 { | |
571 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_CAN_TAKE_FOCUS)) | |
572 return FALSE; | |
573 | |
574 if (set && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_HAS_FOCUS)) | |
575 { | |
576 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS); | |
577 g_signal_emit(widget, signals[SIG_GIVE_FOCUS], 0); | |
578 } | |
18223
5023ad94ebc9
Notify a window when it loses focus because another window was moved to
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
18049
diff
changeset
|
579 else if (!set && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_HAS_FOCUS)) |
15817 | 580 { |
581 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS); | |
582 g_signal_emit(widget, signals[SIG_LOST_FOCUS], 0); | |
583 } | |
584 else | |
585 return FALSE; | |
586 | |
587 return TRUE; | |
588 } | |
589 | |
590 void gnt_widget_set_name(GntWidget *widget, const char *name) | |
591 { | |
592 g_free(widget->priv.name); | |
593 widget->priv.name = g_strdup(name); | |
594 } | |
595 | |
596 const char *gnt_widget_get_name(GntWidget *widget) | |
597 { | |
598 return widget->priv.name; | |
599 } | |
600 | |
601 void gnt_widget_activate(GntWidget *widget) | |
602 { | |
603 g_signal_emit(widget, signals[SIG_ACTIVATE], 0); | |
604 } | |
605 | |
606 static gboolean | |
607 update_queue_callback(gpointer data) | |
608 { | |
609 GntWidget *widget = GNT_WIDGET(data); | |
610 | |
611 if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update")) | |
612 return FALSE; | |
613 if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) | |
614 gnt_screen_update(widget); | |
615 g_object_set_data(G_OBJECT(widget), "gnt:queue_update", NULL); | |
616 return FALSE; | |
617 } | |
618 | |
619 void gnt_widget_queue_update(GntWidget *widget) | |
620 { | |
621 if (widget->window == NULL) | |
622 return; | |
623 while (widget->parent) | |
624 widget = widget->parent; | |
625 | |
626 if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update")) | |
627 { | |
628 int id = g_timeout_add(0, update_queue_callback, widget); | |
629 g_object_set_data_full(G_OBJECT(widget), "gnt:queue_update", GINT_TO_POINTER(id), | |
630 (GDestroyNotify)g_source_remove); | |
631 } | |
632 } | |
633 | |
634 gboolean gnt_widget_confirm_size(GntWidget *widget, int width, int height) | |
635 { | |
636 gboolean ret = FALSE; | |
637 g_signal_emit(widget, signals[SIG_CONFIRM_SIZE], 0, width, height, &ret); | |
638 return ret; | |
639 } | |
640 | |
641 void gnt_widget_set_visible(GntWidget *widget, gboolean set) | |
642 { | |
643 if (set) | |
644 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_INVISIBLE); | |
645 else | |
646 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_INVISIBLE); | |
647 } | |
648 | |
649 gboolean gnt_widget_has_shadow(GntWidget *widget) | |
650 { | |
651 return (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW) && | |
652 gnt_style_get_bool(GNT_STYLE_SHADOW, FALSE)); | |
653 } | |
654 |