]>
Commit | Line | Data |
---|---|---|
c67daf87 | 1 | /* /////////////////////////////////////////////////////////////////////////// |
0ba6a836 | 2 | // Name: src/gtk/win_gtk.c |
77ffb593 | 3 | // Purpose: Native GTK+ widget for wxWidgets, based on GtkLayout and |
ed673c6a RR |
4 | // GtkFixed. It makes use of the gravity window property and |
5 | // therefore does not work with GTK 1.0. | |
c801d85f | 6 | // Author: Robert Roebling |
c67d8618 | 7 | // Id: $Id$ |
01111366 | 8 | // Copyright: (c) 1998 Robert Roebling |
77ffb593 | 9 | // Licence: wxWidgets licence |
c67daf87 | 10 | /////////////////////////////////////////////////////////////////////////// */ |
c801d85f | 11 | |
d02af7bb JJ |
12 | #ifdef VMS |
13 | #define XCheckIfEvent XCHECKIFEVENT | |
3fa056ab | 14 | #endif |
27df579a | 15 | |
79918119 | 16 | #include "wx/platform.h" |
27df579a | 17 | #include "wx/gtk/win_gtk.h" |
034be888 | 18 | #include "gtk/gtksignal.h" |
ed673c6a RR |
19 | #include "gtk/gtkprivate.h" |
20 | #include "gdk/gdkx.h" | |
38c7b3d3 | 21 | |
c801d85f KB |
22 | #ifdef __cplusplus |
23 | extern "C" { | |
24 | #endif /* __cplusplus */ | |
25 | ||
da048e3d | 26 | typedef struct _GtkPizzaAdjData GtkPizzaAdjData; |
ed673c6a | 27 | |
bf3dab48 | 28 | struct _GtkPizzaAdjData |
ed673c6a RR |
29 | { |
30 | gint dx; | |
31 | gint dy; | |
32 | }; | |
33 | ||
b6fa52db RR |
34 | static void gtk_pizza_class_init (GtkPizzaClass *klass); |
35 | static void gtk_pizza_init (GtkPizza *pizza); | |
ed673c6a | 36 | |
b6fa52db RR |
37 | static void gtk_pizza_realize (GtkWidget *widget); |
38 | static void gtk_pizza_unrealize (GtkWidget *widget); | |
ed673c6a | 39 | |
b6fa52db | 40 | static void gtk_pizza_map (GtkWidget *widget); |
ed673c6a | 41 | |
da048e3d | 42 | static void gtk_pizza_size_request (GtkWidget *widget, |
bf3dab48 | 43 | GtkRequisition *requisition); |
da048e3d | 44 | static void gtk_pizza_size_allocate (GtkWidget *widget, |
bf3dab48 | 45 | GtkAllocation *allocation); |
da048e3d | 46 | static gint gtk_pizza_expose (GtkWidget *widget, |
bf3dab48 | 47 | GdkEventExpose *event); |
22aff579 VS |
48 | static void gtk_pizza_style_set (GtkWidget *widget, |
49 | GtkStyle *previous_style); | |
da048e3d | 50 | static void gtk_pizza_add (GtkContainer *container, |
bf3dab48 | 51 | GtkWidget *widget); |
da048e3d | 52 | static void gtk_pizza_remove (GtkContainer *container, |
bf3dab48 | 53 | GtkWidget *widget); |
b6fa52db RR |
54 | static void gtk_pizza_forall (GtkContainer *container, |
55 | gboolean include_internals, | |
56 | GtkCallback callback, | |
57 | gpointer callback_data); | |
17a1ebd1 | 58 | |
67d78217 RR |
59 | static void gtk_pizza_allocate_child (GtkPizza *pizza, |
60 | GtkPizzaChild *child); | |
3fc6e5fa RR |
61 | static void gtk_pizza_adjust_allocations_recurse (GtkWidget *widget, |
62 | gpointer cb_data); | |
ed673c6a | 63 | |
da048e3d | 64 | static GtkType gtk_pizza_child_type (GtkContainer *container); |
c801d85f | 65 | |
b6fa52db | 66 | static void gtk_pizza_scroll_set_adjustments (GtkPizza *pizza, |
bf3dab48 VZ |
67 | GtkAdjustment *hadj, |
68 | GtkAdjustment *vadj); | |
c801d85f | 69 | |
68567a96 MR |
70 | /* static */ |
71 | GtkContainerClass *pizza_parent_class = NULL; | |
034be888 | 72 | |
e1ff9329 | 73 | GtkType |
da048e3d | 74 | gtk_pizza_get_type () |
c801d85f | 75 | { |
e1ff9329 | 76 | static GtkType pizza_type = 0; |
c801d85f | 77 | |
da048e3d | 78 | if (!pizza_type) |
c801d85f | 79 | { |
67d78217 RR |
80 | static const GTypeInfo pizza_info = |
81 | { | |
82 | sizeof (GtkPizzaClass), | |
83 | NULL, /* base_init */ | |
84 | NULL, /* base_finalize */ | |
85 | (GClassInitFunc) gtk_pizza_class_init, | |
86 | NULL, /* class_finalize */ | |
87 | NULL, /* class_data */ | |
88 | sizeof (GtkPizza), | |
89 | 16, /* n_preallocs */ | |
90 | (GInstanceInitFunc) gtk_pizza_init, | |
91 | }; | |
17a1ebd1 | 92 | pizza_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkPizza", &pizza_info, (GTypeFlags)0); |
c801d85f | 93 | } |
bf3dab48 | 94 | |
da048e3d | 95 | return pizza_type; |
c801d85f KB |
96 | } |
97 | ||
02a525b3 VZ |
98 | /* Marshaller needed for set_scroll_adjustments signal, |
99 | generated with GLib-2.4.6 glib-genmarshal */ | |
143318dd RR |
100 | #define g_marshal_value_peek_object(v) g_value_get_object (v) |
101 | static void | |
102 | g_cclosure_user_marshal_VOID__OBJECT_OBJECT (GClosure *closure, | |
103 | GValue *return_value, | |
104 | guint n_param_values, | |
105 | const GValue *param_values, | |
106 | gpointer invocation_hint, | |
107 | gpointer marshal_data) | |
108 | { | |
109 | typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1, | |
110 | gpointer arg_1, | |
111 | gpointer arg_2, | |
112 | gpointer data2); | |
113 | register GMarshalFunc_VOID__OBJECT_OBJECT callback; | |
114 | register GCClosure *cc = (GCClosure*) closure; | |
115 | register gpointer data1, data2; | |
116 | ||
117 | g_return_if_fail (n_param_values == 3); | |
118 | ||
119 | if (G_CCLOSURE_SWAP_DATA (closure)) | |
120 | { | |
121 | data1 = closure->data; | |
122 | data2 = g_value_peek_pointer (param_values + 0); | |
123 | } | |
124 | else | |
125 | { | |
126 | data1 = g_value_peek_pointer (param_values + 0); | |
127 | data2 = closure->data; | |
128 | } | |
129 | callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback); | |
130 | ||
131 | callback (data1, | |
132 | g_marshal_value_peek_object (param_values + 1), | |
133 | g_marshal_value_peek_object (param_values + 2), | |
134 | data2); | |
135 | } | |
143318dd | 136 | |
c801d85f | 137 | static void |
da048e3d | 138 | gtk_pizza_class_init (GtkPizzaClass *klass) |
c801d85f | 139 | { |
053f9cc1 RR |
140 | GtkObjectClass *object_class; |
141 | GtkWidgetClass *widget_class; | |
142 | GtkContainerClass *container_class; | |
c801d85f | 143 | |
053f9cc1 RR |
144 | object_class = (GtkObjectClass*) klass; |
145 | widget_class = (GtkWidgetClass*) klass; | |
146 | container_class = (GtkContainerClass*) klass; | |
67d78217 | 147 | pizza_parent_class = gtk_type_class (GTK_TYPE_CONTAINER); |
c801d85f | 148 | |
da048e3d RR |
149 | widget_class->map = gtk_pizza_map; |
150 | widget_class->realize = gtk_pizza_realize; | |
151 | widget_class->unrealize = gtk_pizza_unrealize; | |
152 | widget_class->size_request = gtk_pizza_size_request; | |
153 | widget_class->size_allocate = gtk_pizza_size_allocate; | |
da048e3d | 154 | widget_class->expose_event = gtk_pizza_expose; |
22aff579 | 155 | widget_class->style_set = gtk_pizza_style_set; |
053f9cc1 | 156 | |
da048e3d RR |
157 | container_class->add = gtk_pizza_add; |
158 | container_class->remove = gtk_pizza_remove; | |
159 | container_class->forall = gtk_pizza_forall; | |
38c7b3d3 | 160 | |
da048e3d | 161 | container_class->child_type = gtk_pizza_child_type; |
034be888 | 162 | |
da048e3d | 163 | klass->set_scroll_adjustments = gtk_pizza_scroll_set_adjustments; |
034be888 | 164 | |
053f9cc1 | 165 | widget_class->set_scroll_adjustments_signal = |
143318dd RR |
166 | g_signal_new( |
167 | "set_scroll_adjustments", | |
168 | G_TYPE_FROM_CLASS(object_class), | |
169 | G_SIGNAL_RUN_LAST, | |
170 | G_STRUCT_OFFSET(GtkPizzaClass, set_scroll_adjustments), | |
171 | NULL, | |
172 | NULL, | |
173 | g_cclosure_user_marshal_VOID__OBJECT_OBJECT, | |
174 | G_TYPE_NONE, | |
175 | 2, | |
176 | GTK_TYPE_ADJUSTMENT, | |
177 | GTK_TYPE_ADJUSTMENT); | |
38c7b3d3 RR |
178 | } |
179 | ||
38c7b3d3 | 180 | static GtkType |
da048e3d | 181 | gtk_pizza_child_type (GtkContainer *container) |
38c7b3d3 | 182 | { |
053f9cc1 | 183 | return GTK_TYPE_WIDGET; |
c801d85f KB |
184 | } |
185 | ||
186 | static void | |
da048e3d | 187 | gtk_pizza_init (GtkPizza *pizza) |
c801d85f | 188 | { |
da048e3d | 189 | GTK_WIDGET_UNSET_FLAGS (pizza, GTK_NO_WINDOW); |
bf3dab48 | 190 | |
da048e3d | 191 | pizza->shadow_type = GTK_MYSHADOW_NONE; |
034be888 | 192 | |
da048e3d | 193 | pizza->children = NULL; |
bf3dab48 | 194 | |
da048e3d RR |
195 | pizza->width = 20; |
196 | pizza->height = 20; | |
ed673c6a | 197 | |
da048e3d | 198 | pizza->bin_window = NULL; |
3dd9b88a | 199 | |
8e217128 RR |
200 | pizza->xoffset = 0; |
201 | pizza->yoffset = 0; | |
ed673c6a | 202 | |
da048e3d RR |
203 | pizza->configure_serial = 0; |
204 | pizza->scroll_x = 0; | |
205 | pizza->scroll_y = 0; | |
206 | pizza->visibility = GDK_VISIBILITY_PARTIAL; | |
bf3dab48 | 207 | |
da048e3d | 208 | pizza->clear_on_draw = TRUE; |
b6fa52db | 209 | pizza->use_filter = TRUE; |
b420fb6a | 210 | pizza->external_expose = FALSE; |
c801d85f KB |
211 | } |
212 | ||
213 | GtkWidget* | |
da048e3d | 214 | gtk_pizza_new () |
c801d85f | 215 | { |
da048e3d | 216 | GtkPizza *pizza; |
c801d85f | 217 | |
da048e3d | 218 | pizza = gtk_type_new (gtk_pizza_get_type ()); |
bf3dab48 | 219 | |
da048e3d | 220 | return GTK_WIDGET (pizza); |
c801d85f KB |
221 | } |
222 | ||
bf3dab48 | 223 | static void |
da048e3d | 224 | gtk_pizza_scroll_set_adjustments (GtkPizza *pizza, |
bf3dab48 VZ |
225 | GtkAdjustment *hadj, |
226 | GtkAdjustment *vadj) | |
034be888 | 227 | { |
ed673c6a | 228 | /* We handle scrolling in the wxScrolledWindow, not here. */ |
034be888 RR |
229 | } |
230 | ||
bf3dab48 | 231 | void |
b6fa52db | 232 | gtk_pizza_set_shadow_type (GtkPizza *pizza, |
0e09f76e | 233 | GtkMyShadowType type) |
034be888 | 234 | { |
da048e3d RR |
235 | g_return_if_fail (pizza != NULL); |
236 | g_return_if_fail (GTK_IS_PIZZA (pizza)); | |
034be888 | 237 | |
da048e3d | 238 | if ((GtkMyShadowType) pizza->shadow_type != type) |
034be888 | 239 | { |
da048e3d | 240 | pizza->shadow_type = type; |
034be888 | 241 | |
da048e3d | 242 | if (GTK_WIDGET_VISIBLE (pizza)) |
bf3dab48 VZ |
243 | { |
244 | gtk_widget_size_allocate (GTK_WIDGET (pizza), &(GTK_WIDGET (pizza)->allocation)); | |
245 | gtk_widget_queue_draw (GTK_WIDGET (pizza)); | |
246 | } | |
034be888 RR |
247 | } |
248 | } | |
034be888 | 249 | |
bf3dab48 | 250 | void |
b6fa52db RR |
251 | gtk_pizza_set_clear (GtkPizza *pizza, |
252 | gboolean clear) | |
147bc491 | 253 | { |
da048e3d RR |
254 | g_return_if_fail (pizza != NULL); |
255 | g_return_if_fail (GTK_IS_PIZZA (pizza)); | |
bf3dab48 | 256 | |
da048e3d | 257 | pizza->clear_on_draw = clear; |
bf3dab48 VZ |
258 | } |
259 | ||
3dd9b88a | 260 | void |
b6fa52db RR |
261 | gtk_pizza_set_filter (GtkPizza *pizza, |
262 | gboolean use) | |
0e09f76e RR |
263 | { |
264 | g_return_if_fail (pizza != NULL); | |
265 | g_return_if_fail (GTK_IS_PIZZA (pizza)); | |
266 | ||
267 | pizza->use_filter = use; | |
3dd9b88a VZ |
268 | } |
269 | ||
270 | void | |
b420fb6a RR |
271 | gtk_pizza_set_external (GtkPizza *pizza, |
272 | gboolean expose) | |
273 | { | |
274 | g_return_if_fail (pizza != NULL); | |
275 | g_return_if_fail (GTK_IS_PIZZA (pizza)); | |
276 | ||
277 | pizza->external_expose = expose; | |
278 | } | |
279 | ||
c801d85f | 280 | void |
b6fa52db RR |
281 | gtk_pizza_put (GtkPizza *pizza, |
282 | GtkWidget *widget, | |
283 | gint x, | |
284 | gint y, | |
285 | gint width, | |
286 | gint height) | |
c801d85f | 287 | { |
da048e3d | 288 | GtkPizzaChild *child_info; |
053f9cc1 | 289 | |
da048e3d RR |
290 | g_return_if_fail (pizza != NULL); |
291 | g_return_if_fail (GTK_IS_PIZZA (pizza)); | |
053f9cc1 RR |
292 | g_return_if_fail (widget != NULL); |
293 | ||
da048e3d | 294 | child_info = g_new (GtkPizzaChild, 1); |
bf3dab48 | 295 | |
053f9cc1 RR |
296 | child_info->widget = widget; |
297 | child_info->x = x; | |
298 | child_info->y = y; | |
299 | child_info->width = width; | |
300 | child_info->height = height; | |
bf3dab48 VZ |
301 | |
302 | pizza->children = g_list_append (pizza->children, child_info); | |
ed673c6a | 303 | |
da048e3d RR |
304 | if (GTK_WIDGET_REALIZED (pizza)) |
305 | gtk_widget_set_parent_window (widget, pizza->bin_window); | |
bf3dab48 | 306 | |
2b5f62a0 VZ |
307 | gtk_widget_set_parent (widget, GTK_WIDGET (pizza)); |
308 | ||
370dc79c | 309 | gtk_widget_set_size_request (widget, width, height); |
c801d85f KB |
310 | } |
311 | ||
312 | void | |
b6fa52db RR |
313 | gtk_pizza_move (GtkPizza *pizza, |
314 | GtkWidget *widget, | |
315 | gint x, | |
316 | gint y) | |
c801d85f | 317 | { |
da048e3d | 318 | GtkPizzaChild *child; |
053f9cc1 | 319 | GList *children; |
c801d85f | 320 | |
da048e3d RR |
321 | g_return_if_fail (pizza != NULL); |
322 | g_return_if_fail (GTK_IS_PIZZA (pizza)); | |
053f9cc1 | 323 | g_return_if_fail (widget != NULL); |
c801d85f | 324 | |
da048e3d | 325 | children = pizza->children; |
053f9cc1 | 326 | while (children) |
fdd3ed7a | 327 | { |
053f9cc1 RR |
328 | child = children->data; |
329 | children = children->next; | |
bf3dab48 | 330 | |
053f9cc1 | 331 | if (child->widget == widget) |
fdd3ed7a | 332 | { |
bf3dab48 VZ |
333 | if ((child->x == x) && (child->y == y)) |
334 | break; | |
335 | ||
ed673c6a RR |
336 | child->x = x; |
337 | child->y = y; | |
17a1ebd1 | 338 | |
bf3dab48 VZ |
339 | if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (pizza)) |
340 | gtk_widget_queue_resize (widget); | |
341 | break; | |
342 | } | |
fdd3ed7a RR |
343 | } |
344 | } | |
345 | ||
346 | void | |
b6fa52db RR |
347 | gtk_pizza_resize (GtkPizza *pizza, |
348 | GtkWidget *widget, | |
349 | gint width, | |
350 | gint height) | |
fdd3ed7a | 351 | { |
da048e3d | 352 | GtkPizzaChild *child; |
053f9cc1 | 353 | GList *children; |
fdd3ed7a | 354 | |
da048e3d RR |
355 | g_return_if_fail (pizza != NULL); |
356 | g_return_if_fail (GTK_IS_PIZZA (pizza)); | |
053f9cc1 | 357 | g_return_if_fail (widget != NULL); |
fdd3ed7a | 358 | |
da048e3d | 359 | children = pizza->children; |
053f9cc1 | 360 | while (children) |
fdd3ed7a | 361 | { |
053f9cc1 RR |
362 | child = children->data; |
363 | children = children->next; | |
bf3dab48 | 364 | |
053f9cc1 | 365 | if (child->widget == widget) |
fdd3ed7a | 366 | { |
bf3dab48 VZ |
367 | if ((child->width == width) && (child->height == height)) |
368 | break; | |
369 | ||
ed673c6a RR |
370 | child->width = width; |
371 | child->height = height; | |
bf3dab48 | 372 | |
370dc79c | 373 | gtk_widget_set_size_request (widget, width, height); |
bf3dab48 | 374 | |
da048e3d | 375 | if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (pizza)) |
bf3dab48 VZ |
376 | gtk_widget_queue_resize (widget); |
377 | break; | |
378 | } | |
fdd3ed7a RR |
379 | } |
380 | } | |
381 | ||
382 | void | |
b6fa52db RR |
383 | gtk_pizza_set_size (GtkPizza *pizza, |
384 | GtkWidget *widget, | |
385 | gint x, | |
386 | gint y, | |
387 | gint width, | |
388 | gint height) | |
fdd3ed7a | 389 | { |
da048e3d | 390 | GtkPizzaChild *child; |
053f9cc1 | 391 | GList *children; |
fdd3ed7a | 392 | |
da048e3d RR |
393 | g_return_if_fail (pizza != NULL); |
394 | g_return_if_fail (GTK_IS_PIZZA (pizza)); | |
053f9cc1 | 395 | g_return_if_fail (widget != NULL); |
fdd3ed7a | 396 | |
da048e3d | 397 | children = pizza->children; |
053f9cc1 | 398 | while (children) |
c801d85f | 399 | { |
053f9cc1 RR |
400 | child = children->data; |
401 | children = children->next; | |
c801d85f | 402 | |
053f9cc1 | 403 | if (child->widget == widget) |
c801d85f | 404 | { |
bf3dab48 VZ |
405 | if ((child->x == x) && |
406 | (child->y == y) && | |
407 | (child->width == width) && | |
408 | (child->height == height)) return; | |
409 | ||
053f9cc1 RR |
410 | child->x = x; |
411 | child->y = y; | |
412 | child->width = width; | |
413 | child->height = height; | |
bf3dab48 | 414 | |
370dc79c | 415 | gtk_widget_set_size_request (widget, width, height); |
bf3dab48 | 416 | |
da048e3d | 417 | if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (pizza)) |
bf3dab48 VZ |
418 | gtk_widget_queue_resize (widget); |
419 | ||
6d693bb4 | 420 | return; |
c801d85f KB |
421 | } |
422 | } | |
423 | } | |
424 | ||
3dd9b88a | 425 | gint |
8cb9f0d0 RR |
426 | gtk_pizza_child_resized (GtkPizza *pizza, |
427 | GtkWidget *widget) | |
428 | { | |
429 | GtkPizzaChild *child; | |
430 | GList *children; | |
431 | ||
432 | g_return_val_if_fail (pizza != NULL, FALSE); | |
433 | g_return_val_if_fail (GTK_IS_PIZZA (pizza), FALSE); | |
434 | g_return_val_if_fail (widget != NULL, FALSE); | |
435 | ||
436 | children = pizza->children; | |
437 | while (children) | |
438 | { | |
439 | child = children->data; | |
440 | children = children->next; | |
441 | ||
442 | if (child->widget == widget) | |
443 | { | |
444 | return ((child->width == widget->allocation.width) && | |
445 | (child->height == widget->allocation.height)); | |
446 | } | |
447 | } | |
3dd9b88a | 448 | |
8cb9f0d0 RR |
449 | return FALSE; |
450 | } | |
3dd9b88a | 451 | |
c801d85f | 452 | static void |
da048e3d | 453 | gtk_pizza_map (GtkWidget *widget) |
c801d85f | 454 | { |
da048e3d RR |
455 | GtkPizza *pizza; |
456 | GtkPizzaChild *child; | |
053f9cc1 | 457 | GList *children; |
c801d85f | 458 | |
053f9cc1 | 459 | g_return_if_fail (widget != NULL); |
da048e3d | 460 | g_return_if_fail (GTK_IS_PIZZA (widget)); |
c801d85f | 461 | |
053f9cc1 | 462 | GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); |
da048e3d | 463 | pizza = GTK_PIZZA (widget); |
c801d85f | 464 | |
da048e3d | 465 | children = pizza->children; |
053f9cc1 | 466 | while (children) |
c801d85f | 467 | { |
053f9cc1 RR |
468 | child = children->data; |
469 | children = children->next; | |
c801d85f | 470 | |
bf3dab48 VZ |
471 | if ( GTK_WIDGET_VISIBLE (child->widget) && |
472 | !GTK_WIDGET_MAPPED (child->widget) && | |
a2d8ce85 | 473 | TRUE) |
bf3dab48 VZ |
474 | { |
475 | gtk_widget_map (child->widget); | |
476 | } | |
c801d85f | 477 | } |
bf3dab48 | 478 | |
053f9cc1 | 479 | gdk_window_show (widget->window); |
da048e3d | 480 | gdk_window_show (pizza->bin_window); |
c801d85f KB |
481 | } |
482 | ||
c801d85f | 483 | static void |
da048e3d | 484 | gtk_pizza_realize (GtkWidget *widget) |
c801d85f | 485 | { |
da048e3d | 486 | GtkPizza *pizza; |
053f9cc1 RR |
487 | GdkWindowAttr attributes; |
488 | gint attributes_mask; | |
da048e3d | 489 | GtkPizzaChild *child; |
ed673c6a | 490 | GList *children; |
c801d85f | 491 | |
053f9cc1 | 492 | g_return_if_fail (widget != NULL); |
da048e3d | 493 | g_return_if_fail (GTK_IS_PIZZA (widget)); |
c801d85f | 494 | |
da048e3d | 495 | pizza = GTK_PIZZA (widget); |
053f9cc1 | 496 | GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); |
c801d85f | 497 | |
053f9cc1 | 498 | attributes.window_type = GDK_WINDOW_CHILD; |
bf3dab48 | 499 | |
053f9cc1 RR |
500 | attributes.x = widget->allocation.x; |
501 | attributes.y = widget->allocation.y; | |
502 | attributes.width = widget->allocation.width; | |
503 | attributes.height = widget->allocation.height; | |
504 | ||
1e6feb95 | 505 | #ifndef __WXUNIVERSAL__ |
da048e3d | 506 | if (pizza->shadow_type == GTK_MYSHADOW_NONE) |
053f9cc1 | 507 | { |
5e014a0c | 508 | /* no border, no changes to sizes */ |
1e6feb95 VZ |
509 | } |
510 | else if (pizza->shadow_type == GTK_MYSHADOW_THIN) | |
5e014a0c RR |
511 | { |
512 | /* GTK_MYSHADOW_THIN == wxSIMPLE_BORDER */ | |
513 | attributes.x += 1; | |
514 | attributes.y += 1; | |
515 | attributes.width -= 2; | |
516 | attributes.height -= 2; | |
1e6feb95 VZ |
517 | } |
518 | else | |
5e014a0c RR |
519 | { |
520 | /* GTK_MYSHADOW_IN == wxSUNKEN_BORDER */ | |
521 | /* GTK_MYSHADOW_OUT == wxRAISED_BORDER */ | |
053f9cc1 RR |
522 | attributes.x += 2; |
523 | attributes.y += 2; | |
524 | attributes.width -= 4; | |
525 | attributes.height -= 4; | |
526 | } | |
1e6feb95 | 527 | #endif /* __WXUNIVERSAL__ */ |
bf3dab48 | 528 | |
ed673c6a | 529 | /* minimal size */ |
053f9cc1 RR |
530 | if (attributes.width < 2) attributes.width = 2; |
531 | if (attributes.height < 2) attributes.height = 2; | |
bf3dab48 | 532 | |
053f9cc1 RR |
533 | attributes.wclass = GDK_INPUT_OUTPUT; |
534 | attributes.visual = gtk_widget_get_visual (widget); | |
535 | attributes.colormap = gtk_widget_get_colormap (widget); | |
3dd9b88a | 536 | attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK; |
ed673c6a | 537 | attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; |
bf3dab48 | 538 | |
c916e13b | 539 | widget->window = gdk_window_new(gtk_widget_get_parent_window (widget), |
bf3dab48 | 540 | &attributes, attributes_mask); |
ed673c6a RR |
541 | gdk_window_set_user_data (widget->window, widget); |
542 | ||
543 | attributes.x = 0; | |
544 | attributes.y = 0; | |
bf3dab48 | 545 | |
053f9cc1 | 546 | attributes.event_mask = gtk_widget_get_events (widget); |
3dd9b88a | 547 | attributes.event_mask |= GDK_EXPOSURE_MASK | |
67d78217 | 548 | GDK_SCROLL_MASK | |
3dd9b88a VZ |
549 | GDK_POINTER_MOTION_MASK | |
550 | GDK_POINTER_MOTION_HINT_MASK | | |
551 | GDK_BUTTON_MOTION_MASK | | |
552 | GDK_BUTTON1_MOTION_MASK | | |
553 | GDK_BUTTON2_MOTION_MASK | | |
554 | GDK_BUTTON3_MOTION_MASK | | |
555 | GDK_BUTTON_PRESS_MASK | | |
556 | GDK_BUTTON_RELEASE_MASK | | |
557 | GDK_KEY_PRESS_MASK | | |
558 | GDK_KEY_RELEASE_MASK | | |
559 | GDK_ENTER_NOTIFY_MASK | | |
560 | GDK_LEAVE_NOTIFY_MASK | | |
561 | GDK_FOCUS_CHANGE_MASK; | |
053f9cc1 | 562 | |
c916e13b | 563 | pizza->bin_window = gdk_window_new(widget->window, |
bf3dab48 | 564 | &attributes, attributes_mask); |
da048e3d | 565 | gdk_window_set_user_data (pizza->bin_window, widget); |
bf3dab48 | 566 | |
053f9cc1 RR |
567 | widget->style = gtk_style_attach (widget->style, widget->window); |
568 | gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); | |
b6fa52db | 569 | gtk_style_set_background (widget->style, pizza->bin_window, GTK_STATE_NORMAL ); |
17a1ebd1 | 570 | |
33611ebb RR |
571 | /* |
572 | gdk_window_set_back_pixmap( widget->window, NULL, FALSE ); | |
573 | gdk_window_set_back_pixmap( pizza->bin_window, NULL, FALSE ); | |
574 | */ | |
bf3dab48 | 575 | |
ed673c6a | 576 | /* cannot be done before realisation */ |
da048e3d | 577 | children = pizza->children; |
ed673c6a RR |
578 | while (children) |
579 | { | |
580 | child = children->data; | |
581 | children = children->next; | |
582 | ||
da048e3d | 583 | gtk_widget_set_parent_window (child->widget, pizza->bin_window); |
ed673c6a RR |
584 | } |
585 | } | |
586 | ||
bf3dab48 | 587 | static void |
da048e3d | 588 | gtk_pizza_unrealize (GtkWidget *widget) |
ed673c6a | 589 | { |
d5ab387d | 590 | GtkPizza *pizza; |
ed673c6a | 591 | |
d5ab387d RR |
592 | g_return_if_fail (widget != NULL); |
593 | g_return_if_fail (GTK_IS_PIZZA (widget)); | |
ed673c6a | 594 | |
d5ab387d | 595 | pizza = GTK_PIZZA (widget); |
ed673c6a | 596 | |
d5ab387d RR |
597 | gdk_window_set_user_data (pizza->bin_window, NULL); |
598 | gdk_window_destroy (pizza->bin_window); | |
599 | pizza->bin_window = NULL; | |
ed673c6a | 600 | |
67d78217 RR |
601 | if (GTK_WIDGET_CLASS (pizza_parent_class)->unrealize) |
602 | (* GTK_WIDGET_CLASS (pizza_parent_class)->unrealize) (widget); | |
c801d85f KB |
603 | } |
604 | ||
605 | static void | |
da048e3d | 606 | gtk_pizza_size_request (GtkWidget *widget, |
b6fa52db | 607 | GtkRequisition *requisition) |
c801d85f | 608 | { |
da048e3d RR |
609 | GtkPizza *pizza; |
610 | GtkPizzaChild *child; | |
053f9cc1 RR |
611 | GList *children; |
612 | GtkRequisition child_requisition; | |
bf3dab48 | 613 | |
053f9cc1 | 614 | g_return_if_fail (widget != NULL); |
da048e3d | 615 | g_return_if_fail (GTK_IS_PIZZA (widget)); |
053f9cc1 | 616 | g_return_if_fail (requisition != NULL); |
c801d85f | 617 | |
da048e3d | 618 | pizza = GTK_PIZZA (widget); |
bf3dab48 | 619 | |
da048e3d | 620 | children = pizza->children; |
053f9cc1 | 621 | while (children) |
c801d85f | 622 | { |
053f9cc1 RR |
623 | child = children->data; |
624 | children = children->next; | |
c801d85f | 625 | |
053f9cc1 | 626 | if (GTK_WIDGET_VISIBLE (child->widget)) |
bf3dab48 | 627 | { |
053f9cc1 | 628 | gtk_widget_size_request (child->widget, &child_requisition); |
bf3dab48 | 629 | } |
c801d85f | 630 | } |
bf3dab48 | 631 | |
053f9cc1 RR |
632 | /* request very little, I'm not sure if requesting nothing |
633 | will always have positive effects on stability... */ | |
634 | requisition->width = 2; | |
635 | requisition->height = 2; | |
c801d85f KB |
636 | } |
637 | ||
638 | static void | |
da048e3d | 639 | gtk_pizza_size_allocate (GtkWidget *widget, |
b6fa52db | 640 | GtkAllocation *allocation) |
c801d85f | 641 | { |
da048e3d | 642 | GtkPizza *pizza; |
053f9cc1 | 643 | gint border; |
ed673c6a | 644 | gint x,y,w,h; |
da048e3d | 645 | GtkPizzaChild *child; |
ed673c6a | 646 | GList *children; |
c801d85f | 647 | |
053f9cc1 | 648 | g_return_if_fail (widget != NULL); |
da048e3d | 649 | g_return_if_fail (GTK_IS_PIZZA(widget)); |
053f9cc1 | 650 | g_return_if_fail (allocation != NULL); |
c801d85f | 651 | |
da048e3d | 652 | pizza = GTK_PIZZA (widget); |
bf3dab48 | 653 | |
227e5e99 | 654 | widget->allocation = *allocation; |
bf3dab48 | 655 | |
da048e3d | 656 | if (pizza->shadow_type == GTK_MYSHADOW_NONE) |
053f9cc1 | 657 | border = 0; |
5e014a0c | 658 | else |
da048e3d | 659 | if (pizza->shadow_type == GTK_MYSHADOW_THIN) |
5e014a0c | 660 | border = 1; |
053f9cc1 RR |
661 | else |
662 | border = 2; | |
bf3dab48 | 663 | |
ed673c6a RR |
664 | x = allocation->x + border; |
665 | y = allocation->y + border; | |
666 | w = allocation->width - border*2; | |
667 | h = allocation->height - border*2; | |
034be888 | 668 | |
053f9cc1 RR |
669 | if (GTK_WIDGET_REALIZED (widget)) |
670 | { | |
ed673c6a | 671 | gdk_window_move_resize( widget->window, x, y, w, h ); |
da048e3d | 672 | gdk_window_move_resize( pizza->bin_window, 0, 0, w, h ); |
053f9cc1 | 673 | } |
bf3dab48 | 674 | |
da048e3d | 675 | children = pizza->children; |
6d693bb4 RR |
676 | while (children) |
677 | { | |
678 | child = children->data; | |
679 | children = children->next; | |
bf3dab48 | 680 | |
da048e3d | 681 | gtk_pizza_allocate_child (pizza, child); |
6d693bb4 | 682 | } |
c801d85f KB |
683 | } |
684 | ||
c801d85f | 685 | static gint |
da048e3d | 686 | gtk_pizza_expose (GtkWidget *widget, |
b6fa52db | 687 | GdkEventExpose *event) |
c801d85f | 688 | { |
b420fb6a | 689 | GtkPizza *pizza; |
b420fb6a RR |
690 | |
691 | g_return_val_if_fail (widget != NULL, FALSE); | |
692 | g_return_val_if_fail (GTK_IS_PIZZA (widget), FALSE); | |
693 | g_return_val_if_fail (event != NULL, FALSE); | |
694 | ||
695 | pizza = GTK_PIZZA (widget); | |
696 | ||
67d78217 RR |
697 | if (event->window != pizza->bin_window) |
698 | return FALSE; | |
4e5a4c69 | 699 | |
67d78217 | 700 | /* We handle all expose events in window.cpp now. */ |
b420fb6a | 701 | if (pizza->external_expose) |
d5ab387d | 702 | return FALSE; |
b420fb6a | 703 | |
67d78217 | 704 | (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, event); |
17a1ebd1 | 705 | |
67d78217 | 706 | return FALSE; |
c801d85f KB |
707 | } |
708 | ||
22aff579 VS |
709 | static void |
710 | gtk_pizza_style_set(GtkWidget *widget, GtkStyle *previous_style) | |
711 | { | |
712 | if (GTK_WIDGET_REALIZED(widget)) | |
713 | { | |
714 | gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL); | |
715 | gtk_style_set_background(widget->style, GTK_PIZZA(widget)->bin_window, GTK_STATE_NORMAL ); | |
716 | } | |
717 | ||
718 | (* GTK_WIDGET_CLASS (pizza_parent_class)->style_set) (widget, previous_style); | |
719 | } | |
720 | ||
c801d85f | 721 | static void |
da048e3d | 722 | gtk_pizza_add (GtkContainer *container, |
bf3dab48 | 723 | GtkWidget *widget) |
c801d85f | 724 | { |
ed673c6a | 725 | g_return_if_fail (container != NULL); |
da048e3d | 726 | g_return_if_fail (GTK_IS_PIZZA (container)); |
ed673c6a | 727 | g_return_if_fail (widget != NULL); |
c801d85f | 728 | |
da048e3d | 729 | gtk_pizza_put (GTK_PIZZA (container), widget, 0, 0, 20, 20 ); |
c801d85f KB |
730 | } |
731 | ||
732 | static void | |
da048e3d | 733 | gtk_pizza_remove (GtkContainer *container, |
b6fa52db | 734 | GtkWidget *widget) |
c801d85f | 735 | { |
da048e3d RR |
736 | GtkPizza *pizza; |
737 | GtkPizzaChild *child; | |
ed673c6a | 738 | GList *children; |
c801d85f | 739 | |
ed673c6a | 740 | g_return_if_fail (container != NULL); |
da048e3d | 741 | g_return_if_fail (GTK_IS_PIZZA (container)); |
ed673c6a | 742 | g_return_if_fail (widget != NULL); |
c801d85f | 743 | |
da048e3d | 744 | pizza = GTK_PIZZA (container); |
c801d85f | 745 | |
da048e3d | 746 | children = pizza->children; |
ed673c6a | 747 | while (children) |
c801d85f | 748 | { |
ed673c6a | 749 | child = children->data; |
c801d85f | 750 | |
ed673c6a | 751 | if (child->widget == widget) |
bf3dab48 VZ |
752 | { |
753 | gtk_widget_unparent (widget); | |
c801d85f | 754 | |
ed673c6a RR |
755 | /* security checks */ |
756 | g_return_if_fail (GTK_IS_WIDGET (widget)); | |
bf3dab48 VZ |
757 | |
758 | pizza->children = g_list_remove_link (pizza->children, children); | |
759 | g_list_free (children); | |
760 | g_free (child); | |
c801d85f | 761 | |
ed673c6a | 762 | /* security checks */ |
bf3dab48 VZ |
763 | g_return_if_fail (GTK_IS_WIDGET (widget)); |
764 | ||
bf3dab48 VZ |
765 | break; |
766 | } | |
c801d85f | 767 | |
ed673c6a | 768 | children = children->next; |
c801d85f KB |
769 | } |
770 | } | |
771 | ||
772 | static void | |
da048e3d | 773 | gtk_pizza_forall (GtkContainer *container, |
b6fa52db RR |
774 | gboolean include_internals, |
775 | GtkCallback callback, | |
776 | gpointer callback_data) | |
c801d85f | 777 | { |
da048e3d RR |
778 | GtkPizza *pizza; |
779 | GtkPizzaChild *child; | |
6d693bb4 | 780 | GList *children; |
c801d85f | 781 | |
6d693bb4 | 782 | g_return_if_fail (container != NULL); |
da048e3d | 783 | g_return_if_fail (GTK_IS_PIZZA (container)); |
90350682 | 784 | g_return_if_fail (callback != (GtkCallback)NULL); |
c801d85f | 785 | |
da048e3d | 786 | pizza = GTK_PIZZA (container); |
c801d85f | 787 | |
da048e3d | 788 | children = pizza->children; |
6d693bb4 | 789 | while (children) |
c801d85f | 790 | { |
6d693bb4 RR |
791 | child = children->data; |
792 | children = children->next; | |
c801d85f | 793 | |
6d693bb4 | 794 | (* callback) (child->widget, callback_data); |
c801d85f KB |
795 | } |
796 | } | |
797 | ||
67d78217 RR |
798 | static void |
799 | gtk_pizza_allocate_child (GtkPizza *pizza, | |
800 | GtkPizzaChild *child) | |
801 | { | |
802 | GtkAllocation allocation; | |
803 | GtkRequisition requisition; | |
c801d85f | 804 | |
67d78217 RR |
805 | allocation.x = child->x - pizza->xoffset; |
806 | allocation.y = child->y - pizza->yoffset; | |
807 | gtk_widget_get_child_requisition (child->widget, &requisition); | |
808 | allocation.width = requisition.width; | |
809 | allocation.height = requisition.height; | |
810 | ||
811 | gtk_widget_size_allocate (child->widget, &allocation); | |
812 | } | |
ed673c6a | 813 | |
ed673c6a | 814 | static void |
da048e3d | 815 | gtk_pizza_adjust_allocations_recurse (GtkWidget *widget, |
bf3dab48 | 816 | gpointer cb_data) |
ed673c6a | 817 | { |
da048e3d | 818 | GtkPizzaAdjData *data = cb_data; |
ed673c6a | 819 | |
6d693bb4 RR |
820 | widget->allocation.x += data->dx; |
821 | widget->allocation.y += data->dy; | |
ed673c6a | 822 | |
6d693bb4 RR |
823 | if (GTK_WIDGET_NO_WINDOW (widget) && GTK_IS_CONTAINER (widget)) |
824 | { | |
bf3dab48 VZ |
825 | gtk_container_forall (GTK_CONTAINER (widget), |
826 | gtk_pizza_adjust_allocations_recurse, | |
827 | cb_data); | |
6d693bb4 | 828 | } |
ed673c6a RR |
829 | } |
830 | ||
831 | static void | |
da048e3d | 832 | gtk_pizza_adjust_allocations (GtkPizza *pizza, |
bf3dab48 VZ |
833 | gint dx, |
834 | gint dy) | |
ed673c6a | 835 | { |
0e09f76e RR |
836 | GList *tmp_list; |
837 | GtkPizzaAdjData data; | |
ed673c6a | 838 | |
0e09f76e RR |
839 | data.dx = dx; |
840 | data.dy = dy; | |
ed673c6a | 841 | |
0e09f76e RR |
842 | tmp_list = pizza->children; |
843 | while (tmp_list) | |
ed673c6a | 844 | { |
0e09f76e RR |
845 | GtkPizzaChild *child = tmp_list->data; |
846 | tmp_list = tmp_list->next; | |
bf3dab48 | 847 | |
0e09f76e RR |
848 | child->widget->allocation.x += dx; |
849 | child->widget->allocation.y += dy; | |
ed673c6a | 850 | |
0e09f76e RR |
851 | if (GTK_WIDGET_NO_WINDOW (child->widget) && |
852 | GTK_IS_CONTAINER (child->widget)) | |
853 | { | |
854 | gtk_container_forall (GTK_CONTAINER (child->widget), | |
855 | gtk_pizza_adjust_allocations_recurse, | |
856 | &data); | |
857 | } | |
ed673c6a RR |
858 | } |
859 | } | |
bf3dab48 | 860 | |
ed673c6a RR |
861 | |
862 | /* This is the main routine to do the scrolling. Scrolling is | |
863 | * done by "Guffaw" scrolling, as in the Mozilla XFE, with | |
864 | * a few modifications. | |
bf3dab48 | 865 | * |
ed673c6a RR |
866 | * The main improvement is that we keep track of whether we |
867 | * are obscured or not. If not, we ignore the generated expose | |
868 | * events and instead do the exposes ourself, without having | |
869 | * to wait for a roundtrip to the server. This also provides | |
870 | * a limited form of expose-event compression, since we do | |
871 | * the affected area as one big chunk. | |
872 | */ | |
873 | ||
874 | void | |
da048e3d | 875 | gtk_pizza_scroll (GtkPizza *pizza, gint dx, gint dy) |
ed673c6a | 876 | { |
3fc6e5fa RR |
877 | pizza->xoffset += dx; |
878 | pizza->yoffset += dy; | |
879 | ||
880 | gtk_pizza_adjust_allocations (pizza, -dx, -dy); | |
881 | ||
882 | if (pizza->bin_window) | |
883 | gdk_window_scroll( pizza->bin_window, -dx, -dy ); | |
ed673c6a RR |
884 | } |
885 | ||
c801d85f KB |
886 | #ifdef __cplusplus |
887 | } | |
888 | #endif /* __cplusplus */ |