Mercurial > dwindows
comparison gtk/dw.c @ 515:c3c5d8e36aa3
Implemented MDI Window in Window code on GTK 2.x.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Tue, 16 Mar 2004 02:50:42 +0000 |
parents | 08d770271709 |
children | caa7ed17c132 |
comparison
equal
deleted
inserted
replaced
514:08d770271709 | 515:c3c5d8e36aa3 |
---|---|
3 * A GTK like implementation of the PM GUI | 3 * A GTK like implementation of the PM GUI |
4 * GTK forwarder module for portabilty. | 4 * GTK forwarder module for portabilty. |
5 * | 5 * |
6 * (C) 2000-2003 Brian Smith <dbsoft@technologist.com> | 6 * (C) 2000-2003 Brian Smith <dbsoft@technologist.com> |
7 * (C) 2003 Mark Hessling <m.hessling@qut.edu.au> | 7 * (C) 2003 Mark Hessling <m.hessling@qut.edu.au> |
8 * | 8 * (C) 2002 Shmyrev <shmyrev@yandex.ru> |
9 */ | 9 */ |
10 #include "dw.h" | 10 #include "dw.h" |
11 #include <string.h> | 11 #include <string.h> |
12 #include <stdlib.h> | 12 #include <stdlib.h> |
13 #include <sys/utsname.h> | 13 #include <sys/utsname.h> |
174 /* Alignment flags */ | 174 /* Alignment flags */ |
175 #define DW_CENTER 0.5f | 175 #define DW_CENTER 0.5f |
176 #define DW_LEFT 0.0f | 176 #define DW_LEFT 0.0f |
177 #define DW_RIGHT 1.0f | 177 #define DW_RIGHT 1.0f |
178 | 178 |
179 /* MDI Support Code */ | |
180 #if GTK_MAJOR_VERSION > 1 | |
181 #define GTK_MDI(obj) GTK_CHECK_CAST (obj, gtk_mdi_get_type (), GtkMdi) | |
182 #define GTK_MDI_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_mdi_get_type (), GtkMdiClass) | |
183 #define GTK_IS_MDI(obj) GTK_CHECK_TYPE (obj, gtk_mdi_get_type ()) | |
184 | |
185 typedef struct _GtkMdi GtkMdi; | |
186 typedef struct _GtkMdiClass GtkMdiClass; | |
187 typedef struct _GtkMdiDragInfo GtkMdiDragInfo; | |
188 typedef enum _GtkMdiChildState GtkMdiChildState; | |
189 | |
190 enum _GtkMdiChildState | |
191 { | |
192 CHILD_NORMAL, | |
193 CHILD_MAXIMIZED, | |
194 CHILD_ICONIFIED | |
195 }; | |
196 | |
197 struct _GtkMdi | |
198 { | |
199 GtkContainer container; | |
200 GList *children; | |
201 | |
202 GdkPoint drag_start; | |
203 gint drag_button; | |
204 }; | |
205 | |
206 struct _GtkMdiClass | |
207 { | |
208 GtkContainerClass parent_class; | |
209 | |
210 void (*mdi) (GtkMdi * mdi); | |
211 }; | |
212 | |
213 #include "gtk/maximize.xpm" | |
214 #include "gtk/minimize.xpm" | |
215 #include "gtk/kill.xpm" | |
216 | |
217 #define GTK_MDI_BACKGROUND "Grey70" | |
218 #define GTK_MDI_LABEL_BACKGROUND "black" | |
219 #define GTK_MDI_LABEL_FOREGROUND "white" | |
220 #define GTK_MDI_DEFAULT_WIDTH 0 | |
221 #define GTK_MDI_DEFAULT_HEIGHT 0 | |
222 #define GTK_MDI_MIN_HEIGHT 22 | |
223 #define GTK_MDI_MIN_WIDTH 55 | |
224 | |
225 typedef struct _GtkMdiChild GtkMdiChild; | |
226 | |
227 struct _GtkMdiChild | |
228 { | |
229 GtkWidget *widget; | |
230 | |
231 GtkWidget *child; | |
232 GtkMdi *mdi; | |
233 | |
234 gint x; | |
235 gint y; | |
236 gint width; | |
237 gint height; | |
238 | |
239 GtkMdiChildState state; | |
240 }; | |
241 | |
242 static void gtk_mdi_class_init(GtkMdiClass *klass); | |
243 static void gtk_mdi_init(GtkMdi *mdi); | |
244 | |
245 static void gtk_mdi_realize(GtkWidget *widget); | |
246 static void gtk_mdi_size_request(GtkWidget *widget, GtkRequisition *requisition); | |
247 static void gtk_mdi_size_allocate(GtkWidget *widget, GtkAllocation *allocation); | |
248 static gint gtk_mdi_expose(GtkWidget *widget, GdkEventExpose *event); | |
249 | |
250 /* Callbacks */ | |
251 static gboolean move_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data); | |
252 static gboolean resize_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data); | |
253 static gboolean iconify_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data); | |
254 static gboolean maximize_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data); | |
255 static gboolean kill_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data); | |
256 | |
257 static void gtk_mdi_add(GtkContainer *container, GtkWidget *widget); | |
258 static void gtk_mdi_remove_true(GtkContainer *container, GtkWidget *widget); | |
259 static void gtk_mdi_forall(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); | |
260 | |
261 static GtkMdiChild *get_child(GtkMdi *mdi, GtkWidget * widget); | |
262 | |
263 static GtkType gtk_mdi_get_type(void) | |
264 { | |
265 static GType mdi_type = 0; | |
266 | |
267 if (!mdi_type) | |
268 { | |
269 | |
270 static const GTypeInfo mdi_info = | |
271 { | |
272 sizeof (GtkMdiClass), | |
273 NULL, | |
274 NULL, | |
275 (GClassInitFunc) gtk_mdi_class_init, | |
276 NULL, | |
277 NULL, | |
278 sizeof (GtkMdi), | |
279 0, | |
280 (GInstanceInitFunc) gtk_mdi_init, | |
281 }; | |
282 | |
283 mdi_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkMdi", &mdi_info, 0); | |
284 } | |
285 | |
286 return mdi_type; | |
287 } | |
288 | |
289 /* Local data */ | |
290 static GtkWidgetClass *parent_class = NULL; | |
291 | |
292 static void gtk_mdi_class_init(GtkMdiClass *class) | |
293 { | |
294 GObjectClass *object_class; | |
295 GtkWidgetClass *widget_class; | |
296 GtkContainerClass *container_class; | |
297 | |
298 object_class = (GObjectClass *) class; | |
299 widget_class = (GtkWidgetClass *) class; | |
300 container_class = (GtkContainerClass *) class; | |
301 | |
302 parent_class = gtk_type_class (GTK_TYPE_CONTAINER); | |
303 | |
304 widget_class->realize = gtk_mdi_realize; | |
305 widget_class->expose_event = gtk_mdi_expose; | |
306 widget_class->size_request = gtk_mdi_size_request; | |
307 widget_class->size_allocate = gtk_mdi_size_allocate; | |
308 | |
309 container_class->add = gtk_mdi_add; | |
310 container_class->remove = gtk_mdi_remove_true; | |
311 container_class->forall = gtk_mdi_forall; | |
312 class->mdi = NULL; | |
313 } | |
314 | |
315 static void gtk_mdi_init(GtkMdi *mdi) | |
316 { | |
317 mdi->drag_button = -1; | |
318 mdi->children = NULL; | |
319 } | |
320 | |
321 static GtkWidget *gtk_mdi_new(void) | |
322 { | |
323 GtkWidget *mdi; | |
324 GdkColor background; | |
325 | |
326 mdi = GTK_WIDGET (g_object_new (gtk_mdi_get_type (), NULL)); | |
327 gdk_color_parse (GTK_MDI_BACKGROUND, &background); | |
328 gtk_widget_modify_bg (mdi, GTK_STATE_NORMAL, &background); | |
329 | |
330 return mdi; | |
331 } | |
332 | |
333 static void gtk_mdi_put(GtkMdi *mdi, GtkWidget *child_widget, gint x, gint y, GtkWidget *label) | |
334 { | |
335 GtkMdiChild *child; | |
336 | |
337 GtkWidget *table; | |
338 GtkWidget *button[3]; | |
339 | |
340 GtkWidget *child_box; | |
341 GtkWidget *top_event_box; | |
342 GtkWidget *bottom_event_box; | |
343 GtkWidget *child_widget_box; | |
344 | |
345 GdkColor color; | |
346 gint i, j; | |
347 GdkCursor *cursor; | |
348 GdkColormap *colormap; | |
349 GdkPixmap *pixmap; | |
350 GdkBitmap *mask; | |
351 GtkStyle *style; | |
352 | |
353 child_box = gtk_event_box_new (); | |
354 child_widget_box = gtk_event_box_new (); | |
355 top_event_box = gtk_event_box_new (); | |
356 bottom_event_box = gtk_event_box_new (); | |
357 table = gtk_table_new (4, 7, FALSE); | |
358 gtk_table_set_row_spacings (GTK_TABLE (table), 1); | |
359 gtk_table_set_col_spacings (GTK_TABLE (table), 1); | |
360 gtk_table_set_row_spacing (GTK_TABLE (table), 3, 0); | |
361 gtk_table_set_col_spacing (GTK_TABLE (table), 6, 0); | |
362 gtk_table_set_row_spacing (GTK_TABLE (table), 2, 0); | |
363 gtk_table_set_col_spacing (GTK_TABLE (table), 5, 0); | |
364 | |
365 for (i = 0; i < 3; i++) | |
366 { | |
367 button[i] = gtk_event_box_new (); | |
368 gtk_widget_set_events (button[0], GDK_BUTTON_PRESS_MASK); | |
369 } | |
370 | |
371 gdk_color_parse (GTK_MDI_LABEL_BACKGROUND, &color); | |
372 | |
373 gtk_widget_modify_bg (top_event_box, GTK_STATE_NORMAL, &color); | |
374 gtk_widget_modify_bg (bottom_event_box, GTK_STATE_NORMAL, &color); | |
375 gtk_widget_modify_bg (child_box, GTK_STATE_NORMAL, &color); | |
376 for (i = GTK_STATE_NORMAL; i < GTK_STATE_ACTIVE; i++) | |
377 { | |
378 for (j = 0; j < 3; j++) | |
379 { | |
380 gtk_widget_modify_bg (button[j], i, &color); | |
381 } | |
382 } | |
383 gdk_color_parse (GTK_MDI_LABEL_FOREGROUND, &color); | |
384 gtk_widget_modify_fg (label, GTK_STATE_NORMAL, &color); | |
385 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); | |
386 | |
387 gtk_container_add (GTK_CONTAINER (top_event_box), label); | |
388 gtk_container_add (GTK_CONTAINER (child_widget_box), child_widget); | |
389 gtk_widget_set_size_request (bottom_event_box, 2, 2); | |
390 | |
391 | |
392 style = gtk_widget_get_default_style (); | |
393 colormap = gdk_colormap_get_system (); | |
394 pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask, | |
395 &style->bg[GTK_STATE_NORMAL], | |
396 (gchar **) minimize_xpm); | |
397 gtk_container_add (GTK_CONTAINER (button[0]), gtk_image_new_from_pixmap (pixmap, mask)); | |
398 pixmap = gdk_pixmap_colormap_create_from_xpm_d (GTK_WIDGET (mdi)->window, colormap, &mask, | |
399 &style->bg[GTK_STATE_NORMAL], | |
400 (gchar **) maximize_xpm); | |
401 gtk_container_add (GTK_CONTAINER (button[1]), gtk_image_new_from_pixmap (pixmap, mask)); | |
402 pixmap = gdk_pixmap_colormap_create_from_xpm_d (GTK_WIDGET (mdi)->window, colormap, &mask, | |
403 &style->bg[GTK_STATE_NORMAL], | |
404 (gchar **) kill_xpm); | |
405 gtk_container_add (GTK_CONTAINER (button[2]), gtk_image_new_from_pixmap (pixmap, mask)); | |
406 | |
407 gtk_table_attach (GTK_TABLE (table), child_widget_box, 1, 6, 2, 3, | |
408 GTK_EXPAND | GTK_SHRINK | GTK_FILL, | |
409 GTK_EXPAND | GTK_SHRINK | GTK_FILL, | |
410 0, 0); | |
411 gtk_table_attach (GTK_TABLE (table), top_event_box, 1, 2, 1, 2, | |
412 GTK_FILL | GTK_EXPAND | GTK_SHRINK, | |
413 0, | |
414 0, 0); | |
415 gtk_table_attach (GTK_TABLE (table), bottom_event_box, 6, 7, 3, 4, | |
416 0, | |
417 0, | |
418 0, 0); | |
419 gtk_table_attach (GTK_TABLE (table), button[0], 2, 3, 1, 2, | |
420 0, | |
421 0, | |
422 0, 0); | |
423 gtk_table_attach (GTK_TABLE (table), button[1], 3, 4, 1, 2, | |
424 0, | |
425 0, | |
426 0, 0); | |
427 gtk_table_attach (GTK_TABLE (table), button[2], 4, 5, 1, 2, | |
428 0, | |
429 0, | |
430 0, 0); | |
431 | |
432 gtk_container_add (GTK_CONTAINER (child_box), table); | |
433 | |
434 child = g_new (GtkMdiChild, 1); | |
435 child->widget = child_box; | |
436 child->x = x; | |
437 child->y = y; | |
438 child->width = -1; | |
439 child->height = -1; | |
440 child->child = child_widget; | |
441 child->mdi = mdi; | |
442 child->state = CHILD_NORMAL; | |
443 | |
444 gtk_widget_set_parent (child_box, GTK_WIDGET (mdi)); | |
445 mdi->children = g_list_append (mdi->children, child); | |
446 | |
447 gtk_widget_show (child_box); | |
448 gtk_widget_show (table); | |
449 gtk_widget_show (top_event_box); | |
450 gtk_widget_show (bottom_event_box); | |
451 gtk_widget_show (child_widget_box); | |
452 for (i = 0; i < 3; i++) | |
453 { | |
454 gtk_widget_show (button[i]); | |
455 } | |
456 | |
457 cursor = gdk_cursor_new (GDK_HAND1); | |
458 gtk_widget_realize (top_event_box); | |
459 gdk_window_set_cursor (top_event_box->window, cursor); | |
460 cursor = gdk_cursor_new (GDK_BOTTOM_RIGHT_CORNER); | |
461 gtk_widget_realize (bottom_event_box); | |
462 gdk_window_set_cursor (bottom_event_box->window, cursor); | |
463 | |
464 g_signal_connect (G_OBJECT (top_event_box), "event", | |
465 G_CALLBACK (move_child_callback), | |
466 child); | |
467 g_signal_connect (G_OBJECT (bottom_event_box), "event", | |
468 G_CALLBACK (resize_child_callback), | |
469 child); | |
470 g_signal_connect (G_OBJECT (button[0]), "button_press_event", | |
471 G_CALLBACK (iconify_child_callback), | |
472 child); | |
473 g_signal_connect (G_OBJECT (button[1]), "button_press_event", | |
474 G_CALLBACK (maximize_child_callback), | |
475 child); | |
476 g_signal_connect (G_OBJECT (button[2]), "button_press_event", | |
477 G_CALLBACK (kill_child_callback), | |
478 child); | |
479 } | |
480 | |
481 static void gtk_mdi_move(GtkMdi *mdi, GtkWidget *widget, gint x, gint y) | |
482 { | |
483 GtkMdiChild *child; | |
484 | |
485 g_return_if_fail (GTK_IS_MDI (mdi)); | |
486 g_return_if_fail (GTK_IS_WIDGET (widget)); | |
487 | |
488 child = get_child (mdi, widget); | |
489 g_return_if_fail (child); | |
490 | |
491 child->x = x; | |
492 child->y = y; | |
493 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (mdi)) | |
494 gtk_widget_queue_resize (GTK_WIDGET (widget)); | |
495 } | |
496 | |
497 static void gtk_mdi_tile(GtkMdi *mdi) | |
498 { | |
499 int i, n; | |
500 int width, height; | |
501 GList *children; | |
502 GtkMdiChild *child; | |
503 | |
504 g_return_if_fail (GTK_IS_MDI (mdi)); | |
505 | |
506 children = mdi->children; | |
507 n = g_list_length (children); | |
508 width = GTK_WIDGET (mdi)->allocation.width; | |
509 height = GTK_WIDGET (mdi)->allocation.height / n; | |
510 for (i = 0; i < n; i++) | |
511 { | |
512 child = (GtkMdiChild *) children->data; | |
513 children = children->next; | |
514 child->x = 0; | |
515 child->y = i * height; | |
516 gtk_widget_set_size_request (child->widget, width, height); | |
517 child->state = CHILD_NORMAL; | |
518 child->width = -1; | |
519 child->height = -1; | |
520 } | |
521 if (GTK_WIDGET_VISIBLE (GTK_WIDGET (mdi))) | |
522 gtk_widget_queue_resize (GTK_WIDGET (mdi)); | |
523 return; | |
524 } | |
525 static void gtk_mdi_cascade(GtkMdi *mdi) | |
526 { | |
527 int i, n; | |
528 int width, height; | |
529 GList *children; | |
530 GtkMdiChild *child; | |
531 | |
532 g_return_if_fail (GTK_IS_MDI (mdi)); | |
533 if (!GTK_WIDGET_VISIBLE (GTK_WIDGET (mdi))) | |
534 return; | |
535 | |
536 children = mdi->children; | |
537 n = g_list_length (children); | |
538 width = GTK_WIDGET (mdi)->allocation.width / (2 * n - 1); | |
539 height = GTK_WIDGET (mdi)->allocation.height / (2 * n - 1); | |
540 for (i = 0; i < n; i++) | |
541 { | |
542 child = (GtkMdiChild *) children->data; | |
543 children = children->next; | |
544 child->x = i * width; | |
545 child->y = i * height; | |
546 gtk_widget_set_size_request (child->widget, width * n, height * n); | |
547 child->state = CHILD_NORMAL; | |
548 child->width = -1; | |
549 child->height = -1; | |
550 } | |
551 if (GTK_WIDGET_VISIBLE (GTK_WIDGET (mdi))) | |
552 gtk_widget_queue_resize (GTK_WIDGET (mdi)); | |
553 return; | |
554 } | |
555 | |
556 static GtkMdiChildState gtk_mdi_get_state(GtkMdi *mdi, GtkWidget *widget) | |
557 { | |
558 GtkMdiChild *child; | |
559 | |
560 g_return_val_if_fail (GTK_IS_MDI (mdi), CHILD_NORMAL); | |
561 g_return_val_if_fail (GTK_IS_WIDGET (widget), CHILD_NORMAL); | |
562 | |
563 child = get_child (mdi, widget); | |
564 g_return_val_if_fail (child, CHILD_NORMAL); | |
565 | |
566 return child->state; | |
567 } | |
568 | |
569 static void gtk_mdi_set_state(GtkMdi *mdi, GtkWidget *widget, GtkMdiChildState state) | |
570 { | |
571 GtkMdiChild *child; | |
572 | |
573 g_return_if_fail (GTK_IS_MDI (mdi)); | |
574 g_return_if_fail (GTK_IS_WIDGET (widget)); | |
575 | |
576 child = get_child (mdi, widget); | |
577 g_return_if_fail (child); | |
578 | |
579 child->state = state; | |
580 if (GTK_WIDGET_VISIBLE (child->widget) && GTK_WIDGET_VISIBLE (mdi)) | |
581 gtk_widget_queue_resize (GTK_WIDGET (child->widget)); | |
582 } | |
583 | |
584 static void gtk_mdi_remove(GtkMdi *mdi, GtkWidget *widget) | |
585 { | |
586 GtkMdiChild *child; | |
587 | |
588 g_return_if_fail (GTK_IS_MDI (mdi)); | |
589 child = get_child (mdi, widget); | |
590 g_return_if_fail (child); | |
591 g_return_if_fail (GTK_IS_WIDGET (child)); | |
592 gtk_mdi_remove_true (GTK_CONTAINER (mdi), child->widget); | |
593 } | |
594 | |
595 static void gtk_mdi_realize(GtkWidget *widget) | |
596 { | |
597 GtkMdi *mdi; | |
598 GdkWindowAttr attributes; | |
599 gint attributes_mask; | |
600 | |
601 mdi = GTK_MDI (widget); | |
602 | |
603 g_return_if_fail (widget != NULL); | |
604 g_return_if_fail (GTK_IS_MDI (mdi)); | |
605 | |
606 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); | |
607 | |
608 attributes.x = widget->allocation.x; | |
609 attributes.y = widget->allocation.y; | |
610 attributes.width = widget->allocation.width; | |
611 attributes.height = widget->allocation.height; | |
612 attributes.wclass = GDK_INPUT_OUTPUT; | |
613 attributes.window_type = GDK_WINDOW_CHILD; | |
614 attributes.event_mask = gtk_widget_get_events (widget) | | |
615 GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | | |
616 GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | | |
617 GDK_POINTER_MOTION_HINT_MASK; | |
618 attributes.visual = gtk_widget_get_visual (widget); | |
619 attributes.colormap = gtk_widget_get_colormap (widget); | |
620 | |
621 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; | |
622 widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask); | |
623 | |
624 widget->style = gtk_style_attach (widget->style, widget->window); | |
625 | |
626 gdk_window_set_user_data (widget->window, widget); | |
627 | |
628 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); | |
629 } | |
630 | |
631 static void gtk_mdi_size_request (GtkWidget *widget, GtkRequisition *requisition) | |
632 { | |
633 GtkMdi *mdi; | |
634 GtkMdiChild *child; | |
635 GList *children; | |
636 GtkRequisition child_requisition; | |
637 | |
638 mdi = GTK_MDI (widget); | |
639 requisition->width = GTK_MDI_DEFAULT_WIDTH; | |
640 requisition->height = GTK_MDI_DEFAULT_HEIGHT; | |
641 | |
642 children = mdi->children; | |
643 while (children) | |
644 { | |
645 child = children->data; | |
646 children = children->next; | |
647 | |
648 if (GTK_WIDGET_VISIBLE (child->widget)) | |
649 { | |
650 gtk_widget_size_request (child->widget, &child_requisition); | |
651 } | |
652 } | |
653 } | |
654 | |
655 static void gtk_mdi_size_allocate(GtkWidget *widget, GtkAllocation *allocation) | |
656 { | |
657 GtkMdi *mdi; | |
658 GtkMdiChild *child; | |
659 GtkAllocation child_allocation; | |
660 GtkRequisition child_requisition; | |
661 GList *children; | |
662 | |
663 mdi = GTK_MDI (widget); | |
664 | |
665 widget->allocation = *allocation; | |
666 | |
667 if (GTK_WIDGET_REALIZED (widget)) | |
668 gdk_window_move_resize (widget->window, | |
669 allocation->x, | |
670 allocation->y, | |
671 allocation->width, | |
672 allocation->height); | |
673 | |
674 | |
675 children = mdi->children; | |
676 while (children) | |
677 { | |
678 child = children->data; | |
679 children = children->next; | |
680 | |
681 if (GTK_WIDGET_VISIBLE (child->widget)) | |
682 { | |
683 gtk_widget_get_child_requisition (child->widget, &child_requisition); | |
684 child_allocation.x = 0; | |
685 child_allocation.y = 0; | |
686 switch (child->state) | |
687 { | |
688 case CHILD_NORMAL: | |
689 { | |
690 if ((child->width < 0) && (child->height < 0)) | |
691 { | |
692 child_allocation.width = child_requisition.width; | |
693 child_allocation.height = child_requisition.height; | |
694 } | |
695 else | |
696 { | |
697 child_allocation.width = child->width; | |
698 child_allocation.height = child->height; | |
699 child->width = -1; | |
700 child->height = -1; | |
701 } | |
702 child_allocation.x += child->x; | |
703 child_allocation.y += child->y; | |
704 break; | |
705 } | |
706 case CHILD_MAXIMIZED: | |
707 { | |
708 if ((child->width < 0) && (child->height < 0)) | |
709 { | |
710 child->width = child_requisition.width; | |
711 child->height = child_requisition.height; | |
712 } | |
713 child_allocation.width = allocation->width; | |
714 child_allocation.height = allocation->height; | |
715 } | |
716 break; | |
717 case CHILD_ICONIFIED: | |
718 { | |
719 if ((child->width < 0) && (child->height < 0)) | |
720 { | |
721 child->width = child_requisition.width; | |
722 child->height = child_requisition.height; | |
723 } | |
724 child_allocation.x += child->x; | |
725 child_allocation.y += child->y; | |
726 child_allocation.width = child_requisition.width; | |
727 child_allocation.height = GTK_MDI_MIN_HEIGHT; | |
728 break; | |
729 } | |
730 } | |
731 gtk_widget_size_allocate (child->widget, &child_allocation); | |
732 } | |
733 } | |
734 } | |
735 | |
736 static gint gtk_mdi_expose(GtkWidget *widget, GdkEventExpose *event) | |
737 { | |
738 GtkMdiChild *child; | |
739 GList *children; | |
740 GtkMdi *mdi; | |
741 | |
742 g_return_val_if_fail (widget != NULL, FALSE); | |
743 g_return_val_if_fail (GTK_IS_MDI (widget), FALSE); | |
744 g_return_val_if_fail (event != NULL, FALSE); | |
745 | |
746 mdi = GTK_MDI (widget); | |
747 for (children = mdi->children; children; children = children->next) | |
748 { | |
749 child = (GtkMdiChild *) children->data; | |
750 gtk_container_propagate_expose (GTK_CONTAINER (mdi), | |
751 child->widget, | |
752 event); | |
753 } | |
754 return FALSE; | |
755 } | |
756 | |
757 static void gtk_mdi_add(GtkContainer *container, GtkWidget *widget) | |
758 { | |
759 GtkWidget *label; | |
760 label = gtk_label_new (""); | |
761 gtk_mdi_put (GTK_MDI (container), widget, 0, 0, label); | |
762 } | |
763 | |
764 static void gtk_mdi_remove_true(GtkContainer *container, GtkWidget *widget) | |
765 { | |
766 GtkMdi *mdi; | |
767 GtkMdiChild *child = NULL; | |
768 GList *children; | |
769 | |
770 mdi = GTK_MDI (container); | |
771 | |
772 children = mdi->children; | |
773 while (children) | |
774 { | |
775 child = children->data; | |
776 if (child->widget == widget) | |
777 break; | |
778 | |
779 children = children->next; | |
780 } | |
781 | |
782 if(child) | |
783 { | |
784 gtk_widget_unparent (child->widget); | |
785 g_free (child); | |
786 } | |
787 mdi->children = g_list_remove_link (mdi->children, children); | |
788 g_list_free (children); | |
789 } | |
790 | |
791 static void gtk_mdi_forall(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) | |
792 { | |
793 GtkMdi *mdi; | |
794 GtkMdiChild *child; | |
795 GList *children; | |
796 | |
797 g_return_if_fail (callback != NULL); | |
798 | |
799 mdi = GTK_MDI (container); | |
800 | |
801 children = mdi->children; | |
802 while (children) | |
803 { | |
804 child = children->data; | |
805 children = children->next; | |
806 | |
807 (*callback) (child->widget, callback_data); | |
808 } | |
809 } | |
810 | |
811 static gboolean move_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data) | |
812 { | |
813 GtkMdi *mdi; | |
814 GtkMdiChild *child; | |
815 | |
816 child = (GtkMdiChild *) data; | |
817 mdi = child->mdi; | |
818 | |
819 g_return_val_if_fail (GTK_IS_MDI (mdi), FALSE); | |
820 g_return_val_if_fail (GTK_IS_EVENT_BOX (widget), FALSE); | |
821 | |
822 | |
823 switch (event->type) | |
824 { | |
825 case GDK_2BUTTON_PRESS: | |
826 { | |
827 gdk_window_raise (child->widget->window); | |
828 } | |
829 case GDK_BUTTON_PRESS: | |
830 if (child->state == CHILD_MAXIMIZED) | |
831 return FALSE; | |
832 if (mdi->drag_button < 0) | |
833 { | |
834 if (gdk_pointer_grab (event->button.window, | |
835 FALSE, | |
836 GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | | |
837 GDK_BUTTON_RELEASE_MASK, | |
838 NULL, | |
839 NULL, | |
840 event->button.time) != GDK_GRAB_SUCCESS) | |
841 return FALSE; | |
842 | |
843 mdi->drag_button = event->button.button; | |
844 | |
845 mdi->drag_start.x = event->button.x; | |
846 mdi->drag_start.y = event->button.y; | |
847 } | |
848 break; | |
849 | |
850 case GDK_BUTTON_RELEASE: | |
851 if (mdi->drag_button < 0) | |
852 return FALSE; | |
853 | |
854 if (mdi->drag_button == event->button.button) | |
855 { | |
856 int x, y; | |
857 | |
858 gdk_pointer_ungrab (event->button.time); | |
859 mdi->drag_button = -1; | |
860 | |
861 x = event->button.x + child->x - mdi->drag_start.x; | |
862 y = event->button.y + child->y - mdi->drag_start.y; | |
863 | |
864 gtk_mdi_move (mdi, child->child, x, y); | |
865 } | |
866 break; | |
867 | |
868 case GDK_MOTION_NOTIFY: | |
869 { | |
870 int x, y; | |
871 | |
872 if (mdi->drag_button < 0) | |
873 return FALSE; | |
874 | |
875 gdk_window_get_pointer (widget->window, &x, &y, NULL); | |
876 | |
877 | |
878 x = x - mdi->drag_start.x + child->x; | |
879 y = y - mdi->drag_start.y + child->y; | |
880 | |
881 | |
882 gtk_mdi_move (mdi, child->child, x, y); | |
883 } | |
884 break; | |
885 | |
886 default: | |
887 break; | |
888 } | |
889 | |
890 return FALSE; | |
891 } | |
892 | |
893 static gboolean resize_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data) | |
894 { | |
895 GtkMdi *mdi; | |
896 GtkMdiChild *child; | |
897 | |
898 child = (GtkMdiChild *) data; | |
899 mdi = child->mdi; | |
900 | |
901 g_return_val_if_fail (GTK_IS_MDI (mdi), FALSE); | |
902 g_return_val_if_fail (GTK_IS_EVENT_BOX (widget), FALSE); | |
903 | |
904 switch (event->type) | |
905 { | |
906 case GDK_BUTTON_PRESS: | |
907 if (mdi->drag_button < 0) | |
908 { | |
909 if (gdk_pointer_grab (event->button.window, | |
910 FALSE, | |
911 GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | | |
912 GDK_BUTTON_RELEASE_MASK, | |
913 NULL, | |
914 NULL, | |
915 event->button.time) != GDK_GRAB_SUCCESS) | |
916 return FALSE; | |
917 | |
918 mdi->drag_button = event->button.button; | |
919 if ((child->state == CHILD_MAXIMIZED) || (child->state == CHILD_ICONIFIED)) | |
920 { | |
921 child->state = CHILD_NORMAL; | |
922 child->x = child->widget->allocation.x; | |
923 child->y = child->widget->allocation.y; | |
924 child->width = child->widget->allocation.width; | |
925 child->height = child->widget->allocation.height; | |
926 } | |
927 | |
928 } | |
929 break; | |
930 | |
931 case GDK_BUTTON_RELEASE: | |
932 if (mdi->drag_button < 0) | |
933 return FALSE; | |
934 | |
935 if (mdi->drag_button == event->button.button) | |
936 { | |
937 int width, height; | |
938 | |
939 gdk_pointer_ungrab (event->button.time); | |
940 mdi->drag_button = -1; | |
941 | |
942 width = event->button.x + widget->allocation.x; | |
943 height = event->button.y + widget->allocation.y; | |
944 | |
945 width = MAX (width, GTK_MDI_MIN_WIDTH); | |
946 height = MAX (height, GTK_MDI_MIN_HEIGHT); | |
947 | |
948 gtk_widget_set_size_request (child->widget, width, height); | |
949 gtk_widget_queue_resize (child->widget); | |
950 } | |
951 break; | |
952 | |
953 case GDK_MOTION_NOTIFY: | |
954 { | |
955 int x, y; | |
956 int width, height; | |
957 | |
958 if (mdi->drag_button < 0) | |
959 return FALSE; | |
960 | |
961 gdk_window_get_pointer (widget->window, &x, &y, NULL); | |
962 | |
963 width = x + widget->allocation.x; | |
964 height = y + widget->allocation.y; | |
965 | |
966 width = MAX (width, GTK_MDI_MIN_WIDTH); | |
967 height = MAX (height, GTK_MDI_MIN_HEIGHT); | |
968 | |
969 gtk_widget_set_size_request (child->widget, width, height); | |
970 gtk_widget_queue_resize (child->widget); | |
971 } | |
972 break; | |
973 | |
974 default: | |
975 break; | |
976 } | |
977 | |
978 return FALSE; | |
979 } | |
980 | |
981 static gboolean iconify_child_callback (GtkWidget *widget, GdkEvent *event, gpointer data) | |
982 { | |
983 GtkMdiChild *child; | |
984 child = (GtkMdiChild *) data; | |
985 if (child->state == CHILD_ICONIFIED) | |
986 { | |
987 child->state = CHILD_NORMAL; | |
988 } | |
989 else | |
990 { | |
991 child->state = CHILD_ICONIFIED; | |
992 } | |
993 if (GTK_WIDGET_VISIBLE (child->widget)) | |
994 gtk_widget_queue_resize (GTK_WIDGET (child->widget)); | |
995 return FALSE; | |
996 } | |
997 | |
998 static gboolean maximize_child_callback (GtkWidget *widget, GdkEvent * event, gpointer data) | |
999 { | |
1000 GtkMdiChild *child; | |
1001 child = (GtkMdiChild *) data; | |
1002 if (child->state == CHILD_MAXIMIZED) | |
1003 { | |
1004 child->state = CHILD_NORMAL; | |
1005 } | |
1006 else | |
1007 { | |
1008 child->state = CHILD_MAXIMIZED; | |
1009 } | |
1010 if (GTK_WIDGET_VISIBLE (child->widget)) | |
1011 gtk_widget_queue_resize (GTK_WIDGET (child->widget)); | |
1012 return FALSE; | |
1013 } | |
1014 | |
1015 static gboolean kill_child_callback (GtkWidget *widget, GdkEvent *event, gpointer data) | |
1016 { | |
1017 GtkMdiChild *child; | |
1018 GtkMdi *mdi; | |
1019 | |
1020 child = (GtkMdiChild *) data; | |
1021 mdi = child->mdi; | |
1022 | |
1023 g_return_val_if_fail (GTK_IS_MDI (mdi), FALSE); | |
1024 | |
1025 gtk_mdi_remove_true (GTK_CONTAINER (mdi), child->widget); | |
1026 return FALSE; | |
1027 } | |
1028 | |
1029 static GtkMdiChild *get_child (GtkMdi *mdi, GtkWidget *widget) | |
1030 { | |
1031 GList *children; | |
1032 | |
1033 children = mdi->children; | |
1034 while (children) | |
1035 { | |
1036 GtkMdiChild *child; | |
1037 | |
1038 child = children->data; | |
1039 children = children->next; | |
1040 | |
1041 if (child->child == widget) | |
1042 return child; | |
1043 } | |
1044 | |
1045 return NULL; | |
1046 } | |
1047 #endif | |
1048 | |
179 static void _dw_msleep(long period) | 1049 static void _dw_msleep(long period) |
180 { | 1050 { |
181 #ifdef __sun__ | 1051 #ifdef __sun__ |
182 /* usleep() isn't threadsafe on Solaris */ | 1052 /* usleep() isn't threadsafe on Solaris */ |
183 struct timespec req; | 1053 struct timespec req; |
1849 GtkWidget *tmp; | 2719 GtkWidget *tmp; |
1850 int _locked_by_me = FALSE; | 2720 int _locked_by_me = FALSE; |
1851 int flags = 0; | 2721 int flags = 0; |
1852 | 2722 |
1853 DW_MUTEX_LOCK; | 2723 DW_MUTEX_LOCK; |
1854 last_window = tmp = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
1855 | |
1856 gtk_window_set_title(GTK_WINDOW(tmp), title); | |
1857 if(!(flStyle & DW_FCF_SIZEBORDER)) | |
1858 gtk_window_set_policy(GTK_WINDOW(tmp), FALSE, FALSE, TRUE); | |
1859 | |
1860 gtk_widget_realize(tmp); | |
1861 | |
1862 if(flStyle & DW_FCF_TITLEBAR) | |
1863 flags |= GDK_DECOR_TITLE; | |
1864 | |
1865 if(flStyle & DW_FCF_MINMAX) | |
1866 flags |= GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE; | |
1867 | |
1868 if(flStyle & DW_FCF_SIZEBORDER) | |
1869 flags |= GDK_DECOR_RESIZEH | GDK_DECOR_BORDER; | |
1870 | |
1871 if(flStyle & DW_FCF_BORDER || flStyle & DW_FCF_DLGBORDER) | |
1872 flags |= GDK_DECOR_BORDER; | |
1873 | |
1874 if(flStyle & DW_FCF_MAXIMIZE) | |
1875 { | |
1876 flags &= ~DW_FCF_MAXIMIZE; | |
1877 #if GTK_MAJOR_VERSION > 1 | 2724 #if GTK_MAJOR_VERSION > 1 |
1878 gtk_window_maximize(GTK_WINDOW(tmp)); | 2725 if(hwndOwner && GTK_IS_MDI(hwndOwner)) |
1879 #endif | 2726 { |
1880 } | 2727 GtkWidget *label; |
1881 if(flStyle & DW_FCF_MINIMIZE) | 2728 |
1882 { | 2729 tmp = dw_box_new(DW_VERT, 0); |
1883 flags &= ~DW_FCF_MINIMIZE; | 2730 |
2731 label = gtk_label_new(title); | |
2732 gtk_widget_show(label); | |
2733 gtk_object_set_data(GTK_OBJECT(tmp), "_dw_mdi_child", (gpointer)1); | |
2734 gtk_object_set_data(GTK_OBJECT(tmp), "_dw_mdi_title", (gpointer)label); | |
2735 | |
2736 gtk_mdi_put(GTK_MDI(hwndOwner), tmp, 100, 75, label); | |
2737 } | |
2738 else | |
2739 #endif | |
2740 { | |
2741 last_window = tmp = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
2742 | |
2743 gtk_window_set_title(GTK_WINDOW(tmp), title); | |
2744 if(!(flStyle & DW_FCF_SIZEBORDER)) | |
2745 gtk_window_set_policy(GTK_WINDOW(tmp), FALSE, FALSE, TRUE); | |
2746 | |
2747 gtk_widget_realize(tmp); | |
2748 | |
2749 if(flStyle & DW_FCF_TITLEBAR) | |
2750 flags |= GDK_DECOR_TITLE; | |
2751 | |
2752 if(flStyle & DW_FCF_MINMAX) | |
2753 flags |= GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE; | |
2754 | |
2755 if(flStyle & DW_FCF_SIZEBORDER) | |
2756 flags |= GDK_DECOR_RESIZEH | GDK_DECOR_BORDER; | |
2757 | |
2758 if(flStyle & DW_FCF_BORDER || flStyle & DW_FCF_DLGBORDER) | |
2759 flags |= GDK_DECOR_BORDER; | |
2760 | |
2761 if(flStyle & DW_FCF_MAXIMIZE) | |
2762 { | |
2763 flags &= ~DW_FCF_MAXIMIZE; | |
1884 #if GTK_MAJOR_VERSION > 1 | 2764 #if GTK_MAJOR_VERSION > 1 |
1885 gtk_window_iconify(GTK_WINDOW(tmp)); | 2765 gtk_window_maximize(GTK_WINDOW(tmp)); |
1886 #endif | 2766 #endif |
1887 } | 2767 } |
1888 | 2768 if(flStyle & DW_FCF_MINIMIZE) |
1889 gdk_window_set_decorations(tmp->window, flags); | 2769 { |
1890 | 2770 flags &= ~DW_FCF_MINIMIZE; |
1891 if(hwndOwner) | 2771 #if GTK_MAJOR_VERSION > 1 |
1892 gdk_window_reparent(GTK_WIDGET(tmp)->window, GTK_WIDGET(hwndOwner)->window, 0, 0); | 2772 gtk_window_iconify(GTK_WINDOW(tmp)); |
1893 | 2773 #endif |
1894 if(flStyle & DW_FCF_SIZEBORDER) | 2774 } |
1895 gtk_object_set_data(GTK_OBJECT(tmp), "_dw_size", (gpointer)1); | 2775 |
1896 | 2776 gdk_window_set_decorations(tmp->window, flags); |
2777 | |
2778 if(hwndOwner) | |
2779 gdk_window_reparent(GTK_WIDGET(tmp)->window, GTK_WIDGET(hwndOwner)->window, 0, 0); | |
2780 | |
2781 if(flStyle & DW_FCF_SIZEBORDER) | |
2782 gtk_object_set_data(GTK_OBJECT(tmp), "_dw_size", (gpointer)1); | |
2783 } | |
2784 gtk_object_set_data(GTK_OBJECT(tmp), "_dw_style", (gpointer)flStyle); | |
1897 DW_MUTEX_UNLOCK; | 2785 DW_MUTEX_UNLOCK; |
1898 return tmp; | 2786 return tmp; |
1899 } | 2787 } |
1900 | 2788 |
1901 /* | 2789 /* |
1959 { | 2847 { |
1960 GtkWidget *tmp; | 2848 GtkWidget *tmp; |
1961 int _locked_by_me = FALSE; | 2849 int _locked_by_me = FALSE; |
1962 | 2850 |
1963 DW_MUTEX_LOCK; | 2851 DW_MUTEX_LOCK; |
2852 #if GTK_MAJOR_VERSION > 1 | |
2853 tmp = gtk_mdi_new(); | |
2854 #else | |
1964 tmp = gtk_vbox_new(FALSE, 0); | 2855 tmp = gtk_vbox_new(FALSE, 0); |
2856 #endif | |
2857 gtk_widget_show(tmp); | |
1965 DW_MUTEX_UNLOCK; | 2858 DW_MUTEX_UNLOCK; |
1966 return tmp; | 2859 return tmp; |
1967 } | 2860 } |
1968 | 2861 |
1969 /* | 2862 /* |