]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/win_gtk.c
5f6245a89111adcd4e8773b84c69d62d14b464b0
[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 myfixed->scroll_offset_x = 0;
111 myfixed->scroll_offset_y = 0;
112
113 return GTK_WIDGET (myfixed);
114 }
115
116 void
117 gtk_myfixed_set_offset (GtkMyFixed *myfixed,
118 gint16 x,
119 gint16 y)
120 {
121 GtkWidget *widget;
122
123 g_return_if_fail (myfixed != NULL);
124 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
125
126 myfixed->scroll_offset_x = x;
127 myfixed->scroll_offset_y = y;
128
129 widget = GTK_WIDGET( myfixed );
130
131 if (GTK_WIDGET_REALIZED( GTK_WIDGET(myfixed) ))
132 gdk_window_move_resize (widget->window,
133 widget->allocation.x + x,
134 widget->allocation.y + y,
135 32000,
136 32000);
137 }
138
139 void
140 gtk_myfixed_put (GtkMyFixed *myfixed,
141 GtkWidget *widget,
142 gint16 x,
143 gint16 y)
144 {
145 GtkMyFixedChild *child_info;
146
147 g_return_if_fail (myfixed != NULL);
148 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
149 g_return_if_fail (widget != NULL);
150
151 child_info = g_new (GtkMyFixedChild, 1);
152 child_info->widget = widget;
153 child_info->x = x;
154 child_info->y = y;
155
156 gtk_widget_set_parent (widget, GTK_WIDGET (myfixed));
157
158 myfixed->children = g_list_append (myfixed->children, child_info);
159
160 if (GTK_WIDGET_REALIZED (myfixed) && !GTK_WIDGET_REALIZED (widget))
161 gtk_widget_realize (widget);
162
163 if (GTK_WIDGET_MAPPED (myfixed) && !GTK_WIDGET_MAPPED (widget))
164 gtk_widget_map (widget);
165
166 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))
167 gtk_widget_queue_resize (GTK_WIDGET (myfixed));
168 }
169
170 void
171 gtk_myfixed_move (GtkMyFixed *myfixed,
172 GtkWidget *widget,
173 gint16 x,
174 gint16 y)
175 {
176 GtkMyFixedChild *child;
177 GList *children;
178
179 g_return_if_fail (myfixed != NULL);
180 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
181 g_return_if_fail (widget != NULL);
182
183 children = myfixed->children;
184 while (children)
185 {
186 child = children->data;
187 children = children->next;
188
189 if (child->widget == widget)
190 {
191 child->x = x;
192 child->y = y;
193
194 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))
195 gtk_widget_queue_resize (GTK_WIDGET (myfixed));
196
197 break;
198 }
199 }
200 }
201
202 static void
203 gtk_myfixed_map (GtkWidget *widget)
204 {
205 GtkMyFixed *myfixed;
206 GtkMyFixedChild *child;
207 GList *children;
208
209 g_return_if_fail (widget != NULL);
210 g_return_if_fail (GTK_IS_MYFIXED (widget));
211
212 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
213 myfixed = GTK_MYFIXED (widget);
214
215 gdk_window_show (widget->window);
216
217 children = myfixed->children;
218 while (children)
219 {
220 child = children->data;
221 children = children->next;
222
223 if (GTK_WIDGET_VISIBLE (child->widget) &&
224 !GTK_WIDGET_MAPPED (child->widget))
225 gtk_widget_map (child->widget);
226 }
227 }
228
229 static void
230 gtk_myfixed_unmap (GtkWidget *widget)
231 {
232 g_return_if_fail (widget != NULL);
233 g_return_if_fail (GTK_IS_MYFIXED (widget));
234
235 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
236 }
237
238 static void
239 gtk_myfixed_realize (GtkWidget *widget)
240 {
241 GdkWindowAttr attributes;
242 gint attributes_mask;
243
244 g_return_if_fail (widget != NULL);
245 g_return_if_fail (GTK_IS_MYFIXED (widget));
246
247 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
248
249 attributes.window_type = GDK_WINDOW_CHILD;
250 attributes.x = widget->allocation.x;
251 attributes.y = widget->allocation.y;
252 attributes.width = 32000;
253 attributes.height = 32000;
254 attributes.wclass = GDK_INPUT_OUTPUT;
255 attributes.visual = gtk_widget_get_visual (widget);
256 attributes.colormap = gtk_widget_get_colormap (widget);
257 attributes.event_mask = gtk_widget_get_events (widget);
258 attributes.event_mask |=
259 GDK_EXPOSURE_MASK |
260 GDK_POINTER_MOTION_MASK |
261 GDK_BUTTON_MOTION_MASK |
262 GDK_BUTTON1_MOTION_MASK |
263 GDK_BUTTON2_MOTION_MASK |
264 GDK_BUTTON3_MOTION_MASK |
265 GDK_BUTTON_PRESS_MASK |
266 GDK_BUTTON_RELEASE_MASK |
267 GDK_KEY_PRESS_MASK |
268 GDK_KEY_RELEASE_MASK |
269 GDK_ENTER_NOTIFY_MASK |
270 GDK_LEAVE_NOTIFY_MASK |
271 GDK_FOCUS_CHANGE_MASK;
272
273 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
274
275 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes,
276 attributes_mask);
277 gdk_window_set_user_data (widget->window, widget);
278
279 widget->style = gtk_style_attach (widget->style, widget->window);
280 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
281 }
282
283 static void
284 gtk_myfixed_size_request (GtkWidget *widget,
285 GtkRequisition *requisition)
286 {
287 GtkMyFixed *myfixed;
288 GtkMyFixedChild *child;
289 GList *children;
290
291 g_return_if_fail (widget != NULL);
292 g_return_if_fail (GTK_IS_MYFIXED (widget));
293 g_return_if_fail (requisition != NULL);
294
295 myfixed = GTK_MYFIXED (widget);
296
297 requisition->width = 0;
298 requisition->height = 0;
299
300 children = myfixed->children;
301 while (children)
302 {
303 child = children->data;
304 children = children->next;
305
306 if (GTK_WIDGET_VISIBLE (child->widget))
307 {
308 gtk_widget_size_request (child->widget, &child->widget->requisition);
309 }
310 }
311 }
312
313 static void
314 gtk_myfixed_size_allocate (GtkWidget *widget,
315 GtkAllocation *allocation)
316 {
317 GtkMyFixed *myfixed;
318 GtkMyFixedChild *child;
319 GtkAllocation child_allocation;
320 GList *children;
321 guint16 border_width;
322
323 g_return_if_fail (widget != NULL);
324 g_return_if_fail (GTK_IS_MYFIXED(widget));
325 g_return_if_fail (allocation != NULL);
326
327 myfixed = GTK_MYFIXED (widget);
328
329 widget->allocation = *allocation;
330 if (GTK_WIDGET_REALIZED (widget))
331 gdk_window_move_resize (widget->window,
332 allocation->x + myfixed->scroll_offset_x,
333 allocation->y + myfixed->scroll_offset_y,
334 32000,
335 32000
336 );
337
338 border_width = GTK_CONTAINER (myfixed)->border_width;
339
340 children = myfixed->children;
341 while (children)
342 {
343 child = children->data;
344 children = children->next;
345
346 if (GTK_WIDGET_VISIBLE (child->widget))
347 {
348 child_allocation.x = child->x + border_width;
349 child_allocation.y = child->y + border_width;
350 child_allocation.width = child->widget->requisition.width;
351 child_allocation.height = child->widget->requisition.height;
352 gtk_widget_size_allocate (child->widget, &child_allocation);
353 }
354 }
355 }
356
357 static void
358 gtk_myfixed_paint (GtkWidget *widget,
359 GdkRectangle *area)
360 {
361 g_return_if_fail (widget != NULL);
362 g_return_if_fail (GTK_IS_MYFIXED (widget));
363 g_return_if_fail (area != NULL);
364
365 if (GTK_WIDGET_DRAWABLE (widget))
366 gdk_window_clear_area (widget->window,
367 area->x, area->y,
368 area->width, area->height);
369 }
370
371 static void
372 gtk_myfixed_draw (GtkWidget *widget,
373 GdkRectangle *area)
374 {
375 GtkMyFixed *myfixed;
376 GtkMyFixedChild *child;
377 GdkRectangle child_area;
378 GList *children;
379
380 g_return_if_fail (widget != NULL);
381 g_return_if_fail (GTK_IS_MYFIXED (widget));
382
383 if (GTK_WIDGET_DRAWABLE (widget))
384 {
385 myfixed = GTK_MYFIXED (widget);
386 gtk_myfixed_paint (widget, area);
387
388 children = myfixed->children;
389 while (children)
390 {
391 child = children->data;
392 children = children->next;
393
394 if (gtk_widget_intersect (child->widget, area, &child_area))
395 gtk_widget_draw (child->widget, &child_area);
396 }
397 }
398 }
399
400 static gint
401 gtk_myfixed_expose (GtkWidget *widget,
402 GdkEventExpose *event)
403 {
404 GtkMyFixed *myfixed;
405 GtkMyFixedChild *child;
406 GdkEventExpose child_event;
407 GList *children;
408
409 g_return_val_if_fail (widget != NULL, FALSE);
410 g_return_val_if_fail (GTK_IS_MYFIXED (widget), FALSE);
411 g_return_val_if_fail (event != NULL, FALSE);
412
413 if (GTK_WIDGET_DRAWABLE (widget))
414 {
415 myfixed = GTK_MYFIXED (widget);
416
417 child_event = *event;
418
419 children = myfixed->children;
420 while (children)
421 {
422 child = children->data;
423 children = children->next;
424
425 if (GTK_WIDGET_NO_WINDOW (child->widget) &&
426 gtk_widget_intersect (child->widget, &event->area,
427 &child_event.area))
428 gtk_widget_event (child->widget, (GdkEvent*) &child_event);
429 }
430 }
431
432 return FALSE;
433 }
434
435 static void
436 gtk_myfixed_add (GtkContainer *container,
437 GtkWidget *widget)
438 {
439 g_return_if_fail (container != NULL);
440 g_return_if_fail (GTK_IS_MYFIXED (container));
441 g_return_if_fail (widget != NULL);
442
443 gtk_myfixed_put (GTK_MYFIXED (container), widget, 0, 0);
444 }
445
446 static void
447 gtk_myfixed_remove (GtkContainer *container,
448 GtkWidget *widget)
449 {
450 GtkMyFixed *myfixed;
451 GtkMyFixedChild *child;
452 GList *children;
453
454 g_return_if_fail (container != NULL);
455 g_return_if_fail (GTK_IS_MYFIXED (container));
456 g_return_if_fail (widget != NULL);
457
458 myfixed = GTK_MYFIXED (container);
459
460 children = myfixed->children;
461 while (children)
462 {
463 child = children->data;
464
465 if (child->widget == widget)
466 {
467 gtk_widget_unparent (widget);
468
469 myfixed->children = g_list_remove_link (myfixed->children, children);
470 g_list_free (children);
471 g_free (child);
472
473 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
474 gtk_widget_queue_resize (GTK_WIDGET (container));
475
476 break;
477 }
478
479 children = children->next;
480 }
481 }
482
483 static void
484 gtk_myfixed_foreach (GtkContainer *container,
485 GtkCallback callback,
486 gpointer callback_data)
487 {
488 GtkMyFixed *myfixed;
489 GtkMyFixedChild *child;
490 GList *children;
491
492 g_return_if_fail (container != NULL);
493 g_return_if_fail (GTK_IS_MYFIXED (container));
494 g_return_if_fail (callback != NULL);
495
496 myfixed = GTK_MYFIXED (container);
497
498 children = myfixed->children;
499 while (children)
500 {
501 child = children->data;
502 children = children->next;
503
504 (* callback) (child->widget, callback_data);
505 }
506 }
507
508
509 #ifdef __cplusplus
510 }
511 #endif /* __cplusplus */
512