Mercurial > pidgin
annotate finch/libgnt/gntwidget.c @ 18193:09eb621782bc
explicit merge of 'f2eb358baf2c72cb37b6b9bcb4c036e44e0bcc2b'
and '2344c84a6e70c374b19936a127462d2f19c0139c'
author | Ka-Hing Cheung <khc@hxbc.us> |
---|---|
date | Tue, 19 Jun 2007 17:17:57 +0000 |
parents | 1cedd520cd18 |
children | 5023ad94ebc9 ac904659104f |
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 } | |
579 else if (!set) | |
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 |