]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/win_gtk.c
Next try at removing the dancing sliders
[wxWidgets.git] / src / gtk / win_gtk.c
1 /* ///////////////////////////////////////////////////////////////////////////
2 // Name: wx_gtk.h
3 // Purpose:
4 // Author: Robert Roebling
5 // Created: 01/02/97
6 // Id:
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////// */
10
11 #include "wx/gtk/win_gtk.h"
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif /* __cplusplus */
16
17 static void gtk_myfixed_class_init (GtkMyFixedClass *klass);
18 static void gtk_myfixed_init (GtkMyFixed *myfixed);
19 static void gtk_myfixed_map (GtkWidget *widget);
20 static void gtk_myfixed_unmap (GtkWidget *widget);
21 static void gtk_myfixed_realize (GtkWidget *widget);
22 static void gtk_myfixed_size_request (GtkWidget *widget,
23 GtkRequisition *requisition);
24 static void gtk_myfixed_size_allocate (GtkWidget *widget,
25 GtkAllocation *allocation);
26 static void gtk_myfixed_paint (GtkWidget *widget,
27 GdkRectangle *area);
28 static void gtk_myfixed_draw (GtkWidget *widget,
29 GdkRectangle *area);
30 static gint gtk_myfixed_expose (GtkWidget *widget,
31 GdkEventExpose *event);
32 static void gtk_myfixed_add (GtkContainer *container,
33 GtkWidget *widget);
34 static void gtk_myfixed_remove (GtkContainer *container,
35 GtkWidget *widget);
36 static void gtk_myfixed_foreach (GtkContainer *container,
37 GtkCallback callback,
38 gpointer callback_data);
39
40
41 static GtkContainerClass *parent_class = NULL;
42
43
44 guint
45 gtk_myfixed_get_type ()
46 {
47 static guint myfixed_type = 0;
48
49 if (!myfixed_type)
50 {
51 GtkTypeInfo myfixed_info =
52 {
53 "GtkMyFixed",
54 sizeof (GtkMyFixed),
55 sizeof (GtkMyFixedClass),
56 (GtkClassInitFunc) gtk_myfixed_class_init,
57 (GtkObjectInitFunc) gtk_myfixed_init,
58 (GtkArgSetFunc) NULL,
59 (GtkArgGetFunc) NULL,
60 };
61
62 myfixed_type = gtk_type_unique (gtk_container_get_type (), &myfixed_info);
63 }
64
65 return myfixed_type;
66 }
67
68 static void
69 gtk_myfixed_class_init (GtkMyFixedClass *klass)
70 {
71 GtkObjectClass *object_class;
72 GtkWidgetClass *widget_class;
73 GtkContainerClass *container_class;
74
75 object_class = (GtkObjectClass*) klass;
76 widget_class = (GtkWidgetClass*) klass;
77 container_class = (GtkContainerClass*) klass;
78
79 parent_class = gtk_type_class (gtk_container_get_type ());
80
81 widget_class->map = gtk_myfixed_map;
82 widget_class->unmap = gtk_myfixed_unmap;
83 widget_class->realize = gtk_myfixed_realize;
84 widget_class->size_request = gtk_myfixed_size_request;
85 widget_class->size_allocate = gtk_myfixed_size_allocate;
86 widget_class->draw = gtk_myfixed_draw;
87 widget_class->expose_event = gtk_myfixed_expose;
88
89 container_class->add = gtk_myfixed_add;
90 container_class->remove = gtk_myfixed_remove;
91 container_class->foreach = gtk_myfixed_foreach;
92 }
93
94 static void
95 gtk_myfixed_init (GtkMyFixed *myfixed)
96 {
97 GTK_WIDGET_UNSET_FLAGS (myfixed, GTK_NO_WINDOW);
98 GTK_WIDGET_SET_FLAGS (myfixed, GTK_BASIC);
99
100 myfixed->children = NULL;
101 }
102
103 GtkWidget*
104 gtk_myfixed_new ()
105 {
106 GtkMyFixed *myfixed;
107
108 myfixed = gtk_type_new (gtk_myfixed_get_type ());
109
110 return GTK_WIDGET (myfixed);
111 }
112
113 void
114 gtk_myfixed_put (GtkMyFixed *myfixed,
115 GtkWidget *widget,
116 gint16 x,
117 gint16 y)
118 {
119 GtkMyFixedChild *child_info;
120
121 g_return_if_fail (myfixed != NULL);
122 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
123 g_return_if_fail (widget != NULL);
124
125 child_info = g_new (GtkMyFixedChild, 1);
126 child_info->widget = widget;
127 child_info->x = x;
128 child_info->y = y;
129
130 gtk_widget_set_parent (widget, GTK_WIDGET (myfixed));
131
132 myfixed->children = g_list_append (myfixed->children, child_info);
133
134 if (GTK_WIDGET_REALIZED (myfixed) && !GTK_WIDGET_REALIZED (widget))
135 gtk_widget_realize (widget);
136
137 if (GTK_WIDGET_MAPPED (myfixed) && !GTK_WIDGET_MAPPED (widget))
138 gtk_widget_map (widget);
139
140 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))
141 gtk_widget_queue_resize (GTK_WIDGET (myfixed));
142 }
143
144 void
145 gtk_myfixed_move (GtkMyFixed *myfixed,
146 GtkWidget *widget,
147 gint16 x,
148 gint16 y)
149 {
150 GtkMyFixedChild *child;
151 GList *children;
152
153 g_return_if_fail (myfixed != NULL);
154 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
155 g_return_if_fail (widget != NULL);
156
157 children = myfixed->children;
158 while (children)
159 {
160 child = children->data;
161 children = children->next;
162
163 if (child->widget == widget)
164 {
165 child->x = x;
166 child->y = y;
167
168 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))
169 gtk_widget_queue_resize (GTK_WIDGET (myfixed));
170
171 break;
172 }
173 }
174 }
175
176 static void
177 gtk_myfixed_map (GtkWidget *widget)
178 {
179 GtkMyFixed *myfixed;
180 GtkMyFixedChild *child;
181 GList *children;
182
183 g_return_if_fail (widget != NULL);
184 g_return_if_fail (GTK_IS_MYFIXED (widget));
185
186 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
187 myfixed = GTK_MYFIXED (widget);
188
189 gdk_window_show (widget->window);
190
191 children = myfixed->children;
192 while (children)
193 {
194 child = children->data;
195 children = children->next;
196
197 if (GTK_WIDGET_VISIBLE (child->widget) &&
198 !GTK_WIDGET_MAPPED (child->widget))
199 gtk_widget_map (child->widget);
200 }
201 }
202
203 static void
204 gtk_myfixed_unmap (GtkWidget *widget)
205 {
206 g_return_if_fail (widget != NULL);
207 g_return_if_fail (GTK_IS_MYFIXED (widget));
208
209 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
210 }
211
212 static void
213 gtk_myfixed_realize (GtkWidget *widget)
214 {
215 GtkMyFixed *myfixed;
216 GdkWindowAttr attributes;
217 gint attributes_mask;
218
219 g_return_if_fail (widget != NULL);
220 g_return_if_fail (GTK_IS_MYFIXED (widget));
221
222 myfixed = GTK_MYFIXED (widget);
223
224 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
225
226 attributes.window_type = GDK_WINDOW_CHILD;
227 attributes.x = widget->allocation.x;
228 attributes.y = widget->allocation.y;
229 attributes.width = 32000;
230 attributes.height = 32000;
231 attributes.wclass = GDK_INPUT_OUTPUT;
232 attributes.visual = gtk_widget_get_visual (widget);
233 attributes.colormap = gtk_widget_get_colormap (widget);
234 attributes.event_mask = gtk_widget_get_events (widget);
235 attributes.event_mask |=
236 GDK_EXPOSURE_MASK |
237 GDK_POINTER_MOTION_MASK |
238 GDK_BUTTON_MOTION_MASK |
239 GDK_BUTTON1_MOTION_MASK |
240 GDK_BUTTON2_MOTION_MASK |
241 GDK_BUTTON3_MOTION_MASK |
242 GDK_BUTTON_PRESS_MASK |
243 GDK_BUTTON_RELEASE_MASK |
244 GDK_KEY_PRESS_MASK |
245 GDK_KEY_RELEASE_MASK |
246 GDK_ENTER_NOTIFY_MASK |
247 GDK_LEAVE_NOTIFY_MASK |
248 GDK_FOCUS_CHANGE_MASK;
249
250 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
251
252 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes,
253 attributes_mask);
254 gdk_window_set_user_data (widget->window, widget);
255
256 widget->style = gtk_style_attach (widget->style, widget->window);
257 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
258 }
259
260 static void
261 gtk_myfixed_size_request (GtkWidget *widget,
262 GtkRequisition *requisition)
263 {
264 GtkMyFixed *myfixed;
265 GtkMyFixedChild *child;
266 GList *children;
267
268 g_return_if_fail (widget != NULL);
269 g_return_if_fail (GTK_IS_MYFIXED (widget));
270 g_return_if_fail (requisition != NULL);
271
272 myfixed = GTK_MYFIXED (widget);
273
274 requisition->width = 0;
275 requisition->height = 0;
276
277 children = myfixed->children;
278 while (children)
279 {
280 child = children->data;
281 children = children->next;
282
283 if (GTK_WIDGET_VISIBLE (child->widget))
284 {
285 gtk_widget_size_request (child->widget, &child->widget->requisition);
286 }
287 }
288 }
289
290 static void
291 gtk_myfixed_size_allocate (GtkWidget *widget,
292 GtkAllocation *allocation)
293 {
294 GtkMyFixed *myfixed;
295 GtkMyFixedChild *child;
296 GtkAllocation child_allocation;
297 GList *children;
298 guint16 border_width;
299
300 g_return_if_fail (widget != NULL);
301 g_return_if_fail (GTK_IS_MYFIXED(widget));
302 g_return_if_fail (allocation != NULL);
303
304 myfixed = GTK_MYFIXED (widget);
305
306 widget->allocation = *allocation;
307 if (GTK_WIDGET_REALIZED (widget))
308 gdk_window_move_resize (widget->window, allocation->x, allocation->y, 32000, 32000 );
309
310 border_width = GTK_CONTAINER (myfixed)->border_width;
311
312 children = myfixed->children;
313 while (children)
314 {
315 child = children->data;
316 children = children->next;
317
318 if (GTK_WIDGET_VISIBLE (child->widget))
319 {
320 child_allocation.x = child->x + border_width;
321 child_allocation.y = child->y + border_width;
322 child_allocation.width = child->widget->requisition.width;
323 child_allocation.height = child->widget->requisition.height;
324 gtk_widget_size_allocate (child->widget, &child_allocation);
325 }
326 }
327 }
328
329 static void
330 gtk_myfixed_paint (GtkWidget *widget,
331 GdkRectangle *area)
332 {
333 g_return_if_fail (widget != NULL);
334 g_return_if_fail (GTK_IS_MYFIXED (widget));
335 g_return_if_fail (area != NULL);
336
337 if (GTK_WIDGET_DRAWABLE (widget))
338 gdk_window_clear_area (widget->window,
339 area->x, area->y,
340 area->width, area->height);
341 }
342
343 static void
344 gtk_myfixed_draw (GtkWidget *widget,
345 GdkRectangle *area)
346 {
347 GtkMyFixed *myfixed;
348 GtkMyFixedChild *child;
349 GdkRectangle child_area;
350 GList *children;
351
352 g_return_if_fail (widget != NULL);
353 g_return_if_fail (GTK_IS_MYFIXED (widget));
354
355 if (GTK_WIDGET_DRAWABLE (widget))
356 {
357 myfixed = GTK_MYFIXED (widget);
358 gtk_myfixed_paint (widget, area);
359
360 children = myfixed->children;
361 while (children)
362 {
363 child = children->data;
364 children = children->next;
365
366 if (gtk_widget_intersect (child->widget, area, &child_area))
367 gtk_widget_draw (child->widget, &child_area);
368 }
369 }
370 }
371
372 static gint
373 gtk_myfixed_expose (GtkWidget *widget,
374 GdkEventExpose *event)
375 {
376 GtkMyFixed *myfixed;
377 GtkMyFixedChild *child;
378 GdkEventExpose child_event;
379 GList *children;
380
381 g_return_val_if_fail (widget != NULL, FALSE);
382 g_return_val_if_fail (GTK_IS_MYFIXED (widget), FALSE);
383 g_return_val_if_fail (event != NULL, FALSE);
384
385 if (GTK_WIDGET_DRAWABLE (widget))
386 {
387 myfixed = GTK_MYFIXED (widget);
388
389 child_event = *event;
390
391 children = myfixed->children;
392 while (children)
393 {
394 child = children->data;
395 children = children->next;
396
397 if (GTK_WIDGET_NO_WINDOW (child->widget) &&
398 gtk_widget_intersect (child->widget, &event->area,
399 &child_event.area))
400 gtk_widget_event (child->widget, (GdkEvent*) &child_event);
401 }
402 }
403
404 return FALSE;
405 }
406
407 static void
408 gtk_myfixed_add (GtkContainer *container,
409 GtkWidget *widget)
410 {
411 g_return_if_fail (container != NULL);
412 g_return_if_fail (GTK_IS_MYFIXED (container));
413 g_return_if_fail (widget != NULL);
414
415 gtk_myfixed_put (GTK_MYFIXED (container), widget, 0, 0);
416 }
417
418 static void
419 gtk_myfixed_remove (GtkContainer *container,
420 GtkWidget *widget)
421 {
422 GtkMyFixed *myfixed;
423 GtkMyFixedChild *child;
424 GList *children;
425
426 g_return_if_fail (container != NULL);
427 g_return_if_fail (GTK_IS_MYFIXED (container));
428 g_return_if_fail (widget != NULL);
429
430 myfixed = GTK_MYFIXED (container);
431
432 children = myfixed->children;
433 while (children)
434 {
435 child = children->data;
436
437 if (child->widget == widget)
438 {
439 gtk_widget_unparent (widget);
440
441 myfixed->children = g_list_remove_link (myfixed->children, children);
442 g_list_free (children);
443 g_free (child);
444
445 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
446 gtk_widget_queue_resize (GTK_WIDGET (container));
447
448 break;
449 }
450
451 children = children->next;
452 }
453 }
454
455 static void
456 gtk_myfixed_foreach (GtkContainer *container,
457 GtkCallback callback,
458 gpointer callback_data)
459 {
460 GtkMyFixed *myfixed;
461 GtkMyFixedChild *child;
462 GList *children;
463
464 g_return_if_fail (container != NULL);
465 g_return_if_fail (GTK_IS_MYFIXED (container));
466 g_return_if_fail (callback != NULL);
467
468 myfixed = GTK_MYFIXED (container);
469
470 children = myfixed->children;
471 while (children)
472 {
473 child = children->data;
474 children = children->next;
475
476 (* callback) (child->widget, callback_data);
477 }
478 }
479
480
481 #ifdef __cplusplus
482 }
483 #endif /* __cplusplus */
484