comparison console/libgnt/gntbox.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 bbf0470cb348
comparison
equal deleted inserted replaced
13849:8d1c55309e3c 13850:0e1e59770cb0
1 #include "gntbox.h"
2
3 enum
4 {
5 SIGS = 1,
6 };
7
8 static GntWidgetClass *parent_class = NULL;
9 static guint signals[SIGS] = { 0 };
10
11 static void
12 gnt_box_draw(GntWidget *widget)
13 {
14 GntBox *box = GNT_BOX(widget);
15 GList *iter;
16
17 for (iter = box->list; iter; iter = iter->next)
18 {
19 gnt_widget_draw(GNT_WIDGET(iter->data));
20 }
21
22 if (box->title)
23 {
24 gchar *title = g_strdup(box->title);
25 int pos = g_utf8_strlen(title, -1);
26
27 if (pos >= widget->priv.width - 2)
28 {
29 g_utf8_strncpy(title, box->title, widget->priv.width - 2);
30 pos = 1;
31 }
32 else
33 {
34 pos = (widget->priv.width - pos - 2) / 2;
35 /*pos = 2;*/
36 }
37 wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE));
38 mvwprintw(widget->window, 0, pos, title);
39 g_free(title);
40 }
41 wrefresh(widget->window);
42
43 DEBUG;
44 }
45
46 static void
47 reposition_children(GntWidget *widget)
48 {
49 GList *iter;
50 GntBox *box = GNT_BOX(widget);
51 int w, h, curx, cury, max;
52 gboolean has_border = FALSE;
53 int x, y;
54
55 x = widget->priv.x;
56 y = widget->priv.y;
57 w = h = 0;
58 max = -1;
59 curx = widget->priv.x;
60 cury = widget->priv.y;
61 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))
62 {
63 has_border = TRUE;
64 curx += 1;
65 cury += 1;
66 if (!box->vertical)
67 curx++;
68 }
69
70 for (iter = box->list; iter; iter = iter->next)
71 {
72 gnt_widget_set_position(GNT_WIDGET(iter->data), curx, cury);
73 gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h);
74 if (box->vertical)
75 {
76 cury += h + 1;
77 if (max < w)
78 max = w;
79 }
80 else
81 {
82 curx += w + 2;
83 if (max < h)
84 max = h;
85 }
86 }
87
88 if (has_border)
89 {
90 curx += 2;
91 cury += 1;
92 max += 2;
93 }
94
95 if (box->vertical)
96 {
97 widget->priv.width = max;
98 widget->priv.height = cury - widget->priv.y;
99 }
100 else
101 {
102 widget->priv.width = curx - widget->priv.x;
103 widget->priv.height = max;
104 }
105 }
106
107 static void
108 gnt_box_set_position(GntWidget *widget, int x, int y)
109 {
110 gnt_widget_size_request(widget);
111 reposition_children(widget);
112 }
113
114 static void
115 gnt_box_size_request(GntWidget *widget)
116 {
117 GntBox *box = GNT_BOX(widget);
118 GList *iter;
119
120 g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL);
121
122 if (box->homogeneous)
123 {
124 int max = -1, w, h;
125
126 /* XXX: should probably be changed based on vertical-ness */
127 for (iter = box->list; iter; iter = iter->next)
128 {
129 gnt_widget_get_size(GNT_WIDGET(iter->data), &w, NULL);
130 if (max < w)
131 max = w;
132 }
133
134 for (iter = box->list; iter; iter = iter->next)
135 {
136 gnt_widget_get_size(GNT_WIDGET(iter->data), NULL, &h);
137 gnt_widget_set_size(GNT_WIDGET(iter->data), max, h);
138 }
139 }
140
141 reposition_children(widget);
142 }
143
144 static void
145 gnt_box_map(GntWidget *widget)
146 {
147 if (widget->priv.width == 0 || widget->priv.height == 0)
148 gnt_widget_size_request(widget);
149 DEBUG;
150 }
151
152 static gboolean
153 gnt_box_key_pressed(GntWidget *widget, const char *text)
154 {
155 GntBox *box = GNT_BOX(widget);
156
157 /*if (box->list == NULL)*/
158 /*return FALSE;*/
159
160 if (box->active == NULL)
161 box->active = box->list;
162
163 if (gnt_widget_key_pressed(box->active->data, text))
164 return TRUE;
165
166 if (text[0] == 27)
167 {
168 GList *now = NULL;
169 if (strcmp(text+1, GNT_KEY_LEFT) == 0)
170 {
171 now = box->active->prev;
172 if (now == NULL)
173 now = g_list_last(box->list);
174 }
175 else if (strcmp(text+1, GNT_KEY_RIGHT) == 0)
176 {
177 now = box->active->next;
178 if (now == NULL)
179 now = box->list;
180 }
181
182 if (now)
183 {
184 gnt_widget_set_focus(box->active->data, FALSE);
185 box->active = now;
186 gnt_widget_set_focus(box->active->data, TRUE);
187
188 return TRUE;
189 }
190 }
191
192 return FALSE;
193 }
194
195 static GntWidget *find_focused_widget(GntBox *box)
196 {
197 GList *iter;
198
199 for (iter = box->list; iter; iter = iter->next)
200 {
201 GntWidget *w = iter->data;
202
203 if (GNT_IS_BOX(w))
204 {
205 if ((w = find_focused_widget(GNT_BOX(w))) != NULL)
206 return w;
207 }
208 else
209 {
210 if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS) &&
211 GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_HAS_FOCUS))
212 return w;
213 }
214 }
215 return NULL;
216 }
217
218 static void
219 gnt_box_lost_focus(GntWidget *widget)
220 {
221 GntBox *box = GNT_BOX(widget);
222 GntWidget *p = widget;
223
224 while (p->parent)
225 p = p->parent;
226
227 p = find_focused_widget(GNT_BOX(p));
228 if (p)
229 gnt_widget_set_focus(p, FALSE);
230 }
231
232 static void
233 gnt_box_destroy(GntWidget *w)
234 {
235 GntBox *box = GNT_BOX(w);
236 GList *iter;
237
238 for (iter = box->list; iter; iter = iter->next)
239 {
240 gnt_widget_destroy(iter->data);
241 }
242
243 g_list_free(box->list);
244 }
245
246 static void
247 gnt_box_class_init(GntWidgetClass *klass)
248 {
249 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
250
251 parent_class = GNT_WIDGET_CLASS(klass);
252 parent_class->destroy = gnt_box_destroy;
253 parent_class->draw = gnt_box_draw;
254 parent_class->map = gnt_box_map;
255 parent_class->size_request = gnt_box_size_request;
256 parent_class->set_position = gnt_box_set_position;
257 parent_class->key_pressed = gnt_box_key_pressed;
258 parent_class->lost_focus = gnt_box_lost_focus;
259
260 DEBUG;
261 }
262
263 static void
264 gnt_box_init(GTypeInstance *instance, gpointer class)
265 {
266 DEBUG;
267 }
268
269 /******************************************************************************
270 * GntBox API
271 *****************************************************************************/
272 GType
273 gnt_box_get_gtype(void)
274 {
275 static GType type = 0;
276
277 if(type == 0)
278 {
279 static const GTypeInfo info = {
280 sizeof(GntBoxClass),
281 NULL, /* base_init */
282 NULL, /* base_finalize */
283 (GClassInitFunc)gnt_box_class_init,
284 NULL, /* class_finalize */
285 NULL, /* class_data */
286 sizeof(GntBox),
287 0, /* n_preallocs */
288 gnt_box_init, /* instance_init */
289 };
290
291 type = g_type_register_static(GNT_TYPE_WIDGET,
292 "GntBox",
293 &info, 0);
294 }
295
296 return type;
297 }
298
299 GntWidget *gnt_box_new(gboolean homo, gboolean vert)
300 {
301 GntWidget *widget = g_object_new(GNT_TYPE_BOX, NULL);
302 GntBox *box = GNT_BOX(widget);
303
304 box->homogeneous = homo;
305 box->vertical = vert;
306 gnt_widget_set_take_focus(widget, TRUE);
307 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
308
309 return widget;
310 }
311
312 void gnt_box_add_widget(GntBox *b, GntWidget *widget)
313 {
314 b->list = g_list_append(b->list, widget);
315 widget->parent = GNT_WIDGET(b);
316 }
317
318 void gnt_box_set_title(GntBox *b, const char *title)
319 {
320 g_free(b->title);
321 b->title = g_strdup(title);
322 }
323