Mercurial > pidgin
comparison console/libgnt/gntwidget.c @ 13850:0e1e59770cb0
[gaim-migrate @ 16308]
This is my first commit here. So don't yell at me if things get borked.
Also, I haven't looked at the auto-thingies yet. So don't puke at the
Makefiles.
Files in console/libgnt/ are for the 'Gaim/GObjectified Ncurses Toolkit'
library. Files in console/ uses libgaim and libgnt. Currently, only the
buddylist-ui is 'functional', ie. the buddy-list updates when someone
logs on or logs off. It still needs a lot of work.
committer: Tailor Script <tailor@pidgin.im>
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Thu, 22 Jun 2006 08:33:54 +0000 |
parents | |
children | 5b288502a382 |
comparison
equal
deleted
inserted
replaced
13849:8d1c55309e3c | 13850:0e1e59770cb0 |
---|---|
1 /* Stuff brutally ripped from Gflib */ | |
2 | |
3 #include "gntwidget.h" | |
4 #include "gntutils.h" | |
5 #include "gnt.h" | |
6 | |
7 enum | |
8 { | |
9 SIG_DESTROY, | |
10 SIG_DRAW, | |
11 SIG_GIVE_FOCUS, | |
12 SIG_LOST_FOCUS, | |
13 SIG_KEY_PRESSED, | |
14 SIG_MAP, | |
15 SIG_ACTIVATE, | |
16 SIG_EXPOSE, | |
17 SIG_SIZE_REQUEST, | |
18 SIG_POSITION, | |
19 SIGS | |
20 }; | |
21 | |
22 static GObjectClass *parent_class = NULL; | |
23 static guint signals[SIGS] = { 0 }; | |
24 | |
25 static void | |
26 gnt_widget_init(GTypeInstance *instance, gpointer class) | |
27 { | |
28 GntWidget *widget = GNT_WIDGET(instance); | |
29 widget->priv.name = NULL; | |
30 DEBUG; | |
31 } | |
32 | |
33 static void | |
34 gnt_widget_map(GntWidget *widget) | |
35 { | |
36 /* Get some default size for the widget */ | |
37 DEBUG; | |
38 g_signal_emit(widget, signals[SIG_MAP], 0); | |
39 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_MAPPED); | |
40 } | |
41 | |
42 static void | |
43 gnt_widget_dispose(GObject *obj) | |
44 { | |
45 GntWidget *self = GNT_WIDGET(obj); | |
46 | |
47 if(!(GNT_WIDGET_FLAGS(self) & GNT_WIDGET_DESTROYING)) { | |
48 GNT_WIDGET_SET_FLAGS(self, GNT_WIDGET_DESTROYING); | |
49 | |
50 g_signal_emit(self, signals[SIG_DESTROY], 0); | |
51 | |
52 GNT_WIDGET_UNSET_FLAGS(self, GNT_WIDGET_DESTROYING); | |
53 } | |
54 | |
55 parent_class->dispose(obj); | |
56 DEBUG; | |
57 } | |
58 | |
59 static void | |
60 gnt_widget_focus_change(GntWidget *widget) | |
61 { | |
62 if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED) | |
63 gnt_widget_draw(widget); | |
64 } | |
65 | |
66 static void | |
67 gnt_widget_class_init(GntWidgetClass *klass) | |
68 { | |
69 GObjectClass *obj_class = G_OBJECT_CLASS(klass); | |
70 | |
71 parent_class = g_type_class_peek_parent(klass); | |
72 | |
73 obj_class->dispose = gnt_widget_dispose; | |
74 | |
75 klass->destroy = gnt_widget_destroy; | |
76 klass->show = gnt_widget_show; | |
77 klass->draw = gnt_widget_draw; | |
78 klass->expose = gnt_widget_expose; | |
79 klass->map = gnt_widget_map; | |
80 klass->lost_focus = gnt_widget_focus_change; | |
81 klass->gained_focus = gnt_widget_focus_change; | |
82 | |
83 klass->key_pressed = NULL; | |
84 klass->activate = NULL; | |
85 | |
86 signals[SIG_DESTROY] = | |
87 g_signal_new("destroy", | |
88 G_TYPE_FROM_CLASS(klass), | |
89 G_SIGNAL_RUN_LAST, | |
90 G_STRUCT_OFFSET(GntWidgetClass, destroy), | |
91 NULL, NULL, | |
92 g_cclosure_marshal_VOID__VOID, | |
93 G_TYPE_NONE, 0); | |
94 signals[SIG_GIVE_FOCUS] = | |
95 g_signal_new("gained-focus", | |
96 G_TYPE_FROM_CLASS(klass), | |
97 G_SIGNAL_RUN_LAST, | |
98 G_STRUCT_OFFSET(GntWidgetClass, gained_focus), | |
99 NULL, NULL, | |
100 g_cclosure_marshal_VOID__VOID, | |
101 G_TYPE_NONE, 0); | |
102 signals[SIG_LOST_FOCUS] = | |
103 g_signal_new("lost-focus", | |
104 G_TYPE_FROM_CLASS(klass), | |
105 G_SIGNAL_RUN_LAST, | |
106 G_STRUCT_OFFSET(GntWidgetClass, lost_focus), | |
107 NULL, NULL, | |
108 g_cclosure_marshal_VOID__VOID, | |
109 G_TYPE_NONE, 0); | |
110 signals[SIG_ACTIVATE] = | |
111 g_signal_new("activate", | |
112 G_TYPE_FROM_CLASS(klass), | |
113 G_SIGNAL_RUN_LAST, | |
114 G_STRUCT_OFFSET(GntWidgetClass, activate), | |
115 NULL, NULL, | |
116 g_cclosure_marshal_VOID__VOID, | |
117 G_TYPE_NONE, 0); | |
118 signals[SIG_MAP] = | |
119 g_signal_new("map", | |
120 G_TYPE_FROM_CLASS(klass), | |
121 G_SIGNAL_RUN_LAST, | |
122 G_STRUCT_OFFSET(GntWidgetClass, map), | |
123 NULL, NULL, | |
124 g_cclosure_marshal_VOID__VOID, | |
125 G_TYPE_NONE, 0); | |
126 signals[SIG_DRAW] = | |
127 g_signal_new("draw", | |
128 G_TYPE_FROM_CLASS(klass), | |
129 G_SIGNAL_RUN_LAST, | |
130 G_STRUCT_OFFSET(GntWidgetClass, draw), | |
131 NULL, NULL, | |
132 g_cclosure_marshal_VOID__VOID, | |
133 G_TYPE_NONE, 0); | |
134 signals[SIG_EXPOSE] = | |
135 g_signal_new("expose", | |
136 G_TYPE_FROM_CLASS(klass), | |
137 G_SIGNAL_RUN_LAST, | |
138 G_STRUCT_OFFSET(GntWidgetClass, expose), | |
139 NULL, NULL, | |
140 gnt_closure_marshal_VOID__INT_INT_INT_INT, | |
141 G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); | |
142 signals[SIG_POSITION] = | |
143 g_signal_new("position-set", | |
144 G_TYPE_FROM_CLASS(klass), | |
145 G_SIGNAL_RUN_LAST, | |
146 G_STRUCT_OFFSET(GntWidgetClass, set_position), | |
147 NULL, NULL, | |
148 gnt_closure_marshal_VOID__INT_INT, | |
149 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); | |
150 signals[SIG_SIZE_REQUEST] = | |
151 g_signal_new("size_request", | |
152 G_TYPE_FROM_CLASS(klass), | |
153 G_SIGNAL_RUN_LAST, | |
154 G_STRUCT_OFFSET(GntWidgetClass, size_request), | |
155 NULL, NULL, | |
156 g_cclosure_marshal_VOID__VOID, | |
157 G_TYPE_NONE, 0); | |
158 signals[SIG_KEY_PRESSED] = | |
159 g_signal_new("key_pressed", | |
160 G_TYPE_FROM_CLASS(klass), | |
161 G_SIGNAL_RUN_LAST, | |
162 G_STRUCT_OFFSET(GntWidgetClass, key_pressed), | |
163 NULL, NULL, | |
164 gnt_closure_marshal_BOOLEAN__STRING, | |
165 G_TYPE_BOOLEAN, 1, G_TYPE_STRING); | |
166 DEBUG; | |
167 } | |
168 | |
169 /****************************************************************************** | |
170 * GntWidget API | |
171 *****************************************************************************/ | |
172 GType | |
173 gnt_widget_get_gtype(void) | |
174 { | |
175 static GType type = 0; | |
176 | |
177 if(type == 0) { | |
178 static const GTypeInfo info = { | |
179 sizeof(GntWidgetClass), | |
180 NULL, /* base_init */ | |
181 NULL, /* base_finalize */ | |
182 (GClassInitFunc)gnt_widget_class_init, | |
183 NULL, /* class_finalize */ | |
184 NULL, /* class_data */ | |
185 sizeof(GntWidget), | |
186 0, /* n_preallocs */ | |
187 gnt_widget_init, /* instance_init */ | |
188 }; | |
189 | |
190 type = g_type_register_static(G_TYPE_OBJECT, | |
191 "GntWidget", | |
192 &info, G_TYPE_FLAG_ABSTRACT); | |
193 } | |
194 | |
195 return type; | |
196 } | |
197 | |
198 static void | |
199 gnt_widget_take_focus(GntWidget *widget) | |
200 { | |
201 gnt_screen_take_focus(widget); | |
202 } | |
203 | |
204 void gnt_widget_set_take_focus(GntWidget *widget, gboolean can) | |
205 { | |
206 if (can) | |
207 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); | |
208 else | |
209 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); | |
210 } | |
211 | |
212 /** | |
213 * gnt_widget_destroy: | |
214 * @obj: The #GntWidget instance. | |
215 * | |
216 * Emits the "destroy" signal notifying all reference holders that they | |
217 * should release @obj. | |
218 */ | |
219 void | |
220 gnt_widget_destroy(GntWidget *obj) | |
221 { | |
222 g_return_if_fail(GNT_IS_WIDGET(obj)); | |
223 | |
224 delwin(obj->window); | |
225 if(!(GNT_WIDGET_FLAGS(obj) & GNT_WIDGET_DESTROYING)) | |
226 g_object_run_dispose(G_OBJECT(obj)); | |
227 gnt_screen_remove_widget(obj); | |
228 DEBUG; | |
229 } | |
230 | |
231 void | |
232 gnt_widget_show(GntWidget *widget) | |
233 { | |
234 /* Draw the widget and take focus */ | |
235 gnt_widget_draw(widget); | |
236 if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_CAN_TAKE_FOCUS) | |
237 { | |
238 gnt_widget_take_focus(widget); | |
239 } | |
240 } | |
241 | |
242 void | |
243 gnt_widget_draw(GntWidget *widget) | |
244 { | |
245 /* Draw the widget */ | |
246 DEBUG; | |
247 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED)) | |
248 gnt_widget_map(widget); | |
249 | |
250 if (widget->window) | |
251 { | |
252 delwin(widget->window); | |
253 } | |
254 | |
255 widget->window = newwin(widget->priv.height, widget->priv.width, | |
256 widget->priv.y, widget->priv.x); | |
257 wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL)); | |
258 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER)) | |
259 { | |
260 box(widget->window, 0, 0); | |
261 } | |
262 else | |
263 werase(widget->window); | |
264 | |
265 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_SHADOW)) | |
266 { | |
267 /* XXX: Find out the actual windows beneath this window, and | |
268 * draw the shadow on them */ | |
269 /* XXX: Or perhaps do all these from a psedo-WM! */ | |
270 widget->back = newwin(widget->priv.height, widget->priv.width, | |
271 widget->priv.y + 1, widget->priv.x + 1); | |
272 wbkgd(widget->back, COLOR_PAIR(GNT_COLOR_SHADOW)); | |
273 werase(widget->back); | |
274 | |
275 mvwchgat(widget->back, 0, 0, widget->priv.height, | |
276 A_REVERSE | A_BLINK, 0, 0); | |
277 touchline(widget->back, 0, widget->priv.height); | |
278 wrefresh(widget->back); | |
279 } | |
280 | |
281 wrefresh(widget->window); | |
282 g_signal_emit(widget, signals[SIG_DRAW], 0); | |
283 } | |
284 | |
285 gboolean | |
286 gnt_widget_key_pressed(GntWidget *widget, const char *keys) | |
287 { | |
288 gboolean ret; | |
289 g_signal_emit(widget, signals[SIG_KEY_PRESSED], 0, keys, &ret); | |
290 return ret; | |
291 } | |
292 | |
293 void | |
294 gnt_widget_expose(GntWidget *widget, int x, int y, int width, int height) | |
295 { | |
296 g_signal_emit(widget, signals[SIG_EXPOSE], 0, x, y, width, height); | |
297 } | |
298 | |
299 void | |
300 gnt_widget_hide(GntWidget *widget) | |
301 { | |
302 int i; | |
303 | |
304 /* XXX: Currently it simply empties the window. Ideally, it will | |
305 * detect what windows are immediately beneath this one, and cause | |
306 * those windows to redraw themselves by emitting the approrpiate | |
307 * expose signal. */ | |
308 | |
309 werase(widget->window); | |
310 wrefresh(widget->window); | |
311 } | |
312 | |
313 void | |
314 gnt_widget_set_position(GntWidget *wid, int x, int y) | |
315 { | |
316 /* XXX: Need to install properties for these and g_object_notify */ | |
317 wid->priv.x = x; | |
318 wid->priv.y = y; | |
319 g_signal_emit(wid, signals[SIG_POSITION], 0, x, y); | |
320 } | |
321 | |
322 void | |
323 gnt_widget_get_position(GntWidget *wid, int *x, int *y) | |
324 { | |
325 if (x) | |
326 *x = wid->priv.x; | |
327 if (y) | |
328 *y = wid->priv.y; | |
329 } | |
330 | |
331 void | |
332 gnt_widget_size_request(GntWidget *widget) | |
333 { | |
334 g_signal_emit(widget, signals[SIG_SIZE_REQUEST], 0); | |
335 } | |
336 | |
337 void | |
338 gnt_widget_get_size(GntWidget *wid, int *width, int *height) | |
339 { | |
340 if (width) | |
341 *width = wid->priv.width; | |
342 if (height) | |
343 *height = wid->priv.height; | |
344 } | |
345 | |
346 void | |
347 gnt_widget_set_size(GntWidget *widget, int width, int height) | |
348 { | |
349 widget->priv.width = width; | |
350 widget->priv.height = height; | |
351 } | |
352 | |
353 gboolean | |
354 gnt_widget_set_focus(GntWidget *widget, gboolean set) | |
355 { | |
356 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_CAN_TAKE_FOCUS)) | |
357 return FALSE; | |
358 | |
359 if (set && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_HAS_FOCUS)) | |
360 { | |
361 g_signal_emit(widget->parent, signals[SIG_LOST_FOCUS], 0); | |
362 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS); | |
363 g_signal_emit(widget, signals[SIG_GIVE_FOCUS], 0); | |
364 } | |
365 else if (!set) | |
366 { | |
367 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS); | |
368 g_signal_emit(widget, signals[SIG_LOST_FOCUS], 0); | |
369 } | |
370 else | |
371 return FALSE; | |
372 | |
373 return TRUE; | |
374 } | |
375 | |
376 void gnt_widget_set_name(GntWidget *widget, const char *name) | |
377 { | |
378 g_free(widget->priv.name); | |
379 widget->priv.name = g_strdup(name); | |
380 } | |
381 | |
382 void gnt_widget_activate(GntWidget *widget) | |
383 { | |
384 g_signal_emit(widget, signals[SIG_ACTIVATE], 0); | |
385 } | |
386 |