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 /*