* make the shape export work again
[dia.git] / app / layer_dialog.c
blob27b1a1d64670690f099e21b888a1084733698a44
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 /* Parts of this file are derived from the file layers_dialog.c in the Gimp:
21 * The GIMP -- an image manipulation program
22 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
25 #include <assert.h>
26 #include <string.h>
27 #include <gdk/gdkkeysyms.h>
29 #include "config.h"
30 #include "intl.h"
32 #include "layer_dialog.h"
34 #include "pixmaps/eye.xbm"
35 #include "pixmaps/new.xpm"
36 #include "pixmaps/lower.xpm"
37 #include "pixmaps/raise.xpm"
38 #include "pixmaps/delete.xpm"
40 static struct LayerDialog *layer_dialog = NULL;
42 typedef struct _ButtonData ButtonData;
44 struct _ButtonData {
45 gchar **xpm_data;
46 gpointer callback;
47 char *tooltip;
50 enum LayerChangeType {
51 TYPE_DELETE_LAYER,
52 TYPE_ADD_LAYER,
53 TYPE_RAISE_LAYER,
54 TYPE_LOWER_LAYER
56 static Change *
57 undo_layer(Diagram *dia, Layer *layer, enum LayerChangeType, int index);
59 static void layer_dialog_new_callback(GtkWidget *widget, gpointer gdata);
60 static void layer_dialog_raise_callback(GtkWidget *widget, gpointer gdata);
61 static void layer_dialog_lower_callback(GtkWidget *widget, gpointer gdata);
62 static void layer_dialog_delete_callback(GtkWidget *widget, gpointer gdata);
63 static void layer_dialog_edit_layer(DiaLayerWidget *layer_widget);
65 static ButtonData buttons[] = {
66 { new_xpm, layer_dialog_new_callback, N_("New Layer") },
67 { raise_xpm, layer_dialog_raise_callback, N_("Raise Layer") },
68 { lower_xpm, layer_dialog_lower_callback, N_("Lower Layer") },
69 { delete_xpm, layer_dialog_delete_callback, N_("Delete Layer") },
72 enum {
73 BUTTON_NEW = 0,
74 BUTTON_RAISE,
75 BUTTON_LOWER,
76 BUTTON_DELETE
79 #define BUTTON_EVENT_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | \
80 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
82 static int num_buttons = sizeof(buttons)/sizeof(ButtonData);
84 #define NORMAL 0
85 #define SELECTED 1
86 #define INSENSITIVE 2
88 static GdkPixmap *eye_pixmap[3] = {NULL, NULL, NULL};
90 static GtkWidget *
91 create_button_box(GtkWidget *parent)
93 GtkWidget *button;
94 GtkWidget *button_box;
95 GtkWidget *pixmapwid;
96 GdkPixmap *pixmap;
97 GdkBitmap *mask;
98 GdkColormap *cmap;
99 GtkStyle *style;
100 int i;
102 GtkTooltips *tool_tips = NULL; /* ARG */
104 gtk_widget_ensure_style(parent);
105 style = gtk_widget_get_style(parent);
106 cmap = gtk_widget_get_colormap(parent);
108 button_box = gtk_hbox_new (TRUE, 1);
110 for (i=0;i<num_buttons;i++) {
111 pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, cmap,
112 &mask, &style->bg[GTK_STATE_NORMAL], buttons[i].xpm_data);
114 pixmapwid = gtk_pixmap_new (pixmap, mask);
115 gtk_widget_show(pixmapwid);
117 button = gtk_button_new ();
118 gtk_container_add (GTK_CONTAINER (button), pixmapwid);
119 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
120 (GtkSignalFunc) buttons[i].callback,
121 GTK_OBJECT (parent));
123 if (tool_tips != NULL)
124 gtk_tooltips_set_tip (tool_tips, button, gettext(buttons[i].tooltip), NULL);
126 gtk_box_pack_start (GTK_BOX(button_box), button, TRUE, TRUE, 0);
128 layer_dialog->buttons[i] = button;
130 gtk_widget_show (button);
133 return button_box;
136 static gint
137 layer_list_events (GtkWidget *widget,
138 GdkEvent *event)
140 GdkEventKey *kevent;
141 GdkEventButton *bevent;
142 GtkWidget *event_widget;
143 DiaLayerWidget *layer_widget;
145 event_widget = gtk_get_event_widget (event);
147 if (GTK_IS_LIST_ITEM (event_widget)) {
148 layer_widget = DIA_LAYER_WIDGET(event_widget);
150 switch (event->type) {
151 case GDK_BUTTON_PRESS:
152 bevent = (GdkEventButton *) event;
153 break;
155 case GDK_2BUTTON_PRESS:
156 bevent = (GdkEventButton *) event;
157 layer_dialog_edit_layer(layer_widget);
158 return TRUE;
160 case GDK_KEY_PRESS:
161 kevent = (GdkEventKey *) event;
162 switch (kevent->keyval) {
163 case GDK_Up:
164 /* printf ("up arrow\n"); */
165 break;
166 case GDK_Down:
167 /* printf ("down arrow\n"); */
168 break;
169 default:
170 return FALSE;
172 return TRUE;
174 default:
175 break;
179 return FALSE;
183 void
184 create_layer_dialog(void)
186 GtkWidget *dialog;
187 GtkWidget *vbox;
188 GtkWidget *hbox;
189 GtkWidget *label;
190 GtkWidget *omenu;
191 GtkWidget *menu;
192 GtkWidget *list;
193 GtkWidget *separator;
194 GtkWidget *scrolled_win;
195 GtkWidget *button_box;
196 GtkWidget *button;
198 layer_dialog = g_new(struct LayerDialog, 1);
200 layer_dialog->diagram = NULL;
202 layer_dialog->dialog = dialog = gtk_dialog_new ();
203 gtk_window_set_title (GTK_WINDOW (dialog), _("Layers"));
204 gtk_window_set_wmclass (GTK_WINDOW (dialog),
205 "layer_window", "Dia");
206 gtk_window_set_policy (GTK_WINDOW (dialog), FALSE, TRUE, TRUE);
208 gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
209 GTK_SIGNAL_FUNC(gtk_widget_hide), NULL);
212 vbox = GTK_DIALOG(dialog)->vbox;
214 hbox = gtk_hbox_new(FALSE, 1);
216 label = gtk_label_new(_("Diagrams:"));
217 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
218 gtk_widget_show (label);
220 layer_dialog->diagram_omenu = omenu = gtk_option_menu_new();
221 gtk_box_pack_start(GTK_BOX(hbox), omenu, TRUE, TRUE, 2);
222 gtk_widget_show (omenu);
224 menu = gtk_menu_new();
225 gtk_option_menu_set_menu(GTK_OPTION_MENU(omenu), menu);
227 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
228 gtk_widget_show (hbox);
230 separator = gtk_hseparator_new();
231 gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 2);
232 gtk_widget_show (separator);
234 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
235 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
236 GTK_POLICY_AUTOMATIC,
237 GTK_POLICY_AUTOMATIC);
238 gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 2);
240 layer_dialog->layer_list = list = gtk_list_new();
242 gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_BROWSE);
243 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
244 gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
245 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_win)));
246 gtk_widget_show (scrolled_win);
247 gtk_widget_show (list);
249 gtk_signal_connect (GTK_OBJECT (list), "event",
250 (GtkSignalFunc) layer_list_events,
251 NULL);
253 button_box = create_button_box(dialog);
255 gtk_box_pack_start (GTK_BOX (vbox), button_box, FALSE, FALSE, 2);
256 gtk_widget_show (button_box);
258 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
261 button = gtk_button_new_with_label (_("Close"));
262 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area),
263 button, TRUE, TRUE, 0);
264 gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
265 GTK_SIGNAL_FUNC(gtk_widget_hide),
266 GTK_OBJECT(dialog));
268 gtk_widget_show (button);
271 layer_dialog_update_diagram_list();
274 static void
275 dia_layer_select_callback(GtkWidget *widget, gpointer data)
277 DiaLayerWidget *lw;
278 lw = DIA_LAYER_WIDGET(widget);
280 diagram_remove_all_selected(lw->dia, TRUE);
281 diagram_update_extents(lw->dia);
282 data_set_active_layer(lw->dia->data, lw->layer);
283 diagram_add_update_all(lw->dia);
284 diagram_flush(lw->dia);
287 static void
288 dia_layer_deselect_callback(GtkWidget *widget, gpointer data)
293 static void
294 layer_dialog_new_callback(GtkWidget *widget, gpointer gdata)
296 Layer *layer;
297 Diagram *dia;
298 GtkWidget *selected;
299 GList *list = NULL;
300 GtkWidget *layer_widget;
301 int pos;
303 dia = layer_dialog->diagram;
305 if (dia != NULL) {
306 layer = new_layer(g_strdup(_("New layer")));
308 assert(GTK_LIST(layer_dialog->layer_list)->selection != NULL);
309 selected = GTK_LIST(layer_dialog->layer_list)->selection->data;
310 pos = gtk_list_child_position(GTK_LIST(layer_dialog->layer_list), selected);
312 data_add_layer_at(dia->data, layer, dia->data->layers->len - pos);
314 diagram_add_update_all(dia);
315 diagram_flush(dia);
317 layer_widget = dia_layer_widget_new(dia, layer);
318 gtk_widget_show(layer_widget);
320 list = g_list_prepend(list, layer_widget);
322 gtk_list_insert_items(GTK_LIST(layer_dialog->layer_list), list, pos);
324 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), pos);
326 undo_layer(dia, layer, TYPE_ADD_LAYER, dia->data->layers->len - pos);
327 undo_set_transactionpoint(dia->undo);
331 static void
332 layer_dialog_delete_callback(GtkWidget *widget, gpointer gdata)
334 Diagram *dia;
335 GtkWidget *selected;
336 Layer *layer;
337 int pos;
339 dia = layer_dialog->diagram;
341 if ((dia != NULL) && (dia->data->layers->len>1)) {
342 assert(GTK_LIST(layer_dialog->layer_list)->selection != NULL);
343 selected = GTK_LIST(layer_dialog->layer_list)->selection->data;
345 layer = dia->data->active_layer;
347 data_delete_layer(dia->data, layer);
348 diagram_add_update_all(dia);
349 diagram_flush(dia);
351 pos = gtk_list_child_position(GTK_LIST(layer_dialog->layer_list), selected);
352 gtk_container_remove(GTK_CONTAINER(layer_dialog->layer_list), selected);
354 undo_layer(dia, layer, TYPE_DELETE_LAYER,
355 dia->data->layers->len - pos);
356 undo_set_transactionpoint(dia->undo);
358 if (--pos<0)
359 pos = 0;
361 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), pos);
365 static void
366 layer_dialog_raise_callback(GtkWidget *widget, gpointer gdata)
368 Layer *layer;
369 Diagram *dia;
370 GtkWidget *selected;
371 GList *list = NULL;
372 int pos;
374 dia = layer_dialog->diagram;
376 if ((dia != NULL) && (dia->data->layers->len>1)) {
377 assert(GTK_LIST(layer_dialog->layer_list)->selection != NULL);
378 selected = GTK_LIST(layer_dialog->layer_list)->selection->data;
380 pos = gtk_list_child_position(GTK_LIST(layer_dialog->layer_list), selected);
382 if (pos > 0) {
383 layer = DIA_LAYER_WIDGET(selected)->layer;
384 data_raise_layer(dia->data, layer);
386 list = g_list_prepend(list, selected);
388 gtk_widget_ref(selected);
390 gtk_list_remove_items(GTK_LIST(layer_dialog->layer_list),
391 list);
393 gtk_list_insert_items(GTK_LIST(layer_dialog->layer_list),
394 list, pos - 1);
396 gtk_widget_unref(selected);
398 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), pos-1);
400 diagram_add_update_all(dia);
401 diagram_flush(dia);
403 undo_layer(dia, layer, TYPE_RAISE_LAYER, 0);
404 undo_set_transactionpoint(dia->undo);
410 static void
411 layer_dialog_lower_callback(GtkWidget *widget, gpointer gdata)
413 Layer *layer;
414 Diagram *dia;
415 GtkWidget *selected;
416 GList *list = NULL;
417 int pos;
419 dia = layer_dialog->diagram;
421 if ((dia != NULL) && (dia->data->layers->len>1)) {
422 assert(GTK_LIST(layer_dialog->layer_list)->selection != NULL);
423 selected = GTK_LIST(layer_dialog->layer_list)->selection->data;
425 pos = gtk_list_child_position(GTK_LIST(layer_dialog->layer_list), selected);
427 if (pos < dia->data->layers->len-1) {
428 layer = DIA_LAYER_WIDGET(selected)->layer;
429 data_lower_layer(dia->data, layer);
431 list = g_list_prepend(list, selected);
433 gtk_widget_ref(selected);
435 gtk_list_remove_items(GTK_LIST(layer_dialog->layer_list),
436 list);
438 gtk_list_insert_items(GTK_LIST(layer_dialog->layer_list),
439 list, pos + 1);
441 gtk_widget_unref(selected);
443 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), pos+1);
445 diagram_add_update_all(dia);
446 diagram_flush(dia);
448 undo_layer(dia, layer, TYPE_LOWER_LAYER, 0);
449 undo_set_transactionpoint(dia->undo);
456 static void
457 layer_dialog_select_diagram_callback(GtkWidget *widget, gpointer gdata)
459 Diagram *dia = (Diagram *) gdata;
461 layer_dialog_set_diagram(dia);
464 void
465 layer_dialog_update_diagram_list(void)
467 GtkWidget *new_menu;
468 GtkWidget *menu_item;
469 GList *dia_list;
470 Diagram *dia;
471 char *filename;
472 int i;
473 int current_nr;
475 new_menu = gtk_menu_new();
477 current_nr = -1;
479 i = 0;
480 dia_list = open_diagrams;
481 while (dia_list != NULL) {
482 dia = (Diagram *) dia_list->data;
484 if (dia == layer_dialog->diagram) {
485 current_nr = i;
488 filename = strrchr(dia->filename, G_DIR_SEPARATOR);
489 if (filename==NULL) {
490 filename = dia->filename;
491 } else {
492 filename++;
495 menu_item = gtk_menu_item_new_with_label(filename);
497 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
498 (GtkSignalFunc) layer_dialog_select_diagram_callback,
499 (gpointer) dia);
501 gtk_menu_append( GTK_MENU(new_menu), menu_item);
502 gtk_widget_show (menu_item);
504 dia_list = g_list_next(dia_list);
505 i++;
508 if (open_diagrams==NULL) {
509 menu_item = gtk_menu_item_new_with_label (_("none"));
510 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
511 (GtkSignalFunc) layer_dialog_select_diagram_callback,
512 (gpointer) NULL);
513 gtk_menu_append( GTK_MENU(new_menu), menu_item);
514 gtk_widget_show (menu_item);
517 gtk_option_menu_remove_menu(GTK_OPTION_MENU(layer_dialog->diagram_omenu));
519 gtk_option_menu_set_menu(GTK_OPTION_MENU(layer_dialog->diagram_omenu),
520 new_menu);
522 gtk_option_menu_set_history(GTK_OPTION_MENU(layer_dialog->diagram_omenu),
523 current_nr);
524 gtk_menu_set_active(GTK_MENU(new_menu), current_nr);
526 if (current_nr == -1) {
527 dia = NULL;
528 if (open_diagrams!=NULL) {
529 dia = (Diagram *) open_diagrams->data;
531 layer_dialog_set_diagram(dia);
535 void
536 layer_dialog_show()
538 gtk_widget_show(layer_dialog->dialog);
541 void
542 layer_dialog_set_diagram(Diagram *dia)
544 DiagramData *data;
545 GtkWidget *layer_widget;
546 Layer *layer;
547 Layer *active_layer = NULL;
548 int sel_pos;
549 int i,j;
552 if (dia!=NULL)
553 active_layer = dia->data->active_layer;
555 gtk_list_clear_items(GTK_LIST(layer_dialog->layer_list), 0, -1);
556 layer_dialog->diagram = dia;
557 if (dia != NULL) {
558 i = g_list_index(open_diagrams, dia);
559 if (i >= 0)
560 gtk_option_menu_set_history(GTK_OPTION_MENU(layer_dialog->diagram_omenu),
564 if (dia != NULL) {
565 data = dia->data;
567 sel_pos = 0;
568 for (i=data->layers->len-1,j=0;i>=0;i--,j++) {
569 layer = (Layer *) g_ptr_array_index(data->layers, i);
570 layer_widget = dia_layer_widget_new(dia, layer);
571 gtk_widget_show(layer_widget);
572 gtk_container_add(GTK_CONTAINER(layer_dialog->layer_list), layer_widget);
573 if (layer==active_layer)
574 sel_pos = j;
576 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), sel_pos);
582 /******* DiaLayerWidget: *****/
584 static void
585 dia_layer_widget_unrealize(GtkWidget *widget)
587 DiaLayerWidget *lw = DIA_LAYER_WIDGET(widget);
589 if (lw->edit_dialog != NULL) {
590 gtk_widget_destroy(lw->edit_dialog->dialog);
591 g_free(lw->edit_dialog);
592 lw->edit_dialog = NULL;
595 (* GTK_WIDGET_CLASS (gtk_type_class(gtk_list_item_get_type ()))->unrealize) (widget);
598 static void
599 dia_layer_widget_class_init(DiaLayerWidgetClass *klass)
601 GtkObjectClass *object_class;
602 GtkWidgetClass *widget_class;
604 object_class = (GtkObjectClass*) klass;
605 widget_class = (GtkWidgetClass*) klass;
607 widget_class->unrealize = dia_layer_widget_unrealize;
610 static void
611 dia_layer_widget_visible_redraw(DiaLayerWidget *layer_widget)
613 GdkPixmap *pixmap;
614 GdkColor *color;
615 GtkStateType state;
617 state = GTK_WIDGET(layer_widget)->state;
619 if (GTK_WIDGET_IS_SENSITIVE (layer_widget))
621 if (state == GTK_STATE_SELECTED)
622 color = &layer_widget->visible->style->bg[GTK_STATE_SELECTED];
623 else
624 color = &layer_widget->visible->style->white;
626 else
627 color = &layer_widget->visible->style->bg[GTK_STATE_INSENSITIVE];
629 gdk_window_set_background (layer_widget->visible->window, color);
631 if (layer_widget->layer->visible) {
632 if (!eye_pixmap[NORMAL]) {
633 eye_pixmap[NORMAL] =
634 gdk_pixmap_create_from_data (layer_widget->visible->window,
635 (gchar*) eye_bits, eye_width, eye_height, -1,
636 &layer_widget->visible->style->fg[GTK_STATE_NORMAL],
637 &layer_widget->visible->style->white);
638 eye_pixmap[SELECTED] =
639 gdk_pixmap_create_from_data (layer_widget->visible->window,
640 (gchar*) eye_bits, eye_width, eye_height, -1,
641 &layer_widget->visible->style->fg[GTK_STATE_SELECTED],
642 &layer_widget->visible->style->bg[GTK_STATE_SELECTED]);
643 eye_pixmap[INSENSITIVE] =
644 gdk_pixmap_create_from_data (layer_widget->visible->window,
645 (gchar*) eye_bits, eye_width, eye_height, -1,
646 &layer_widget->visible->style->fg[GTK_STATE_INSENSITIVE],
647 &layer_widget->visible->style->bg[GTK_STATE_INSENSITIVE]);
650 if (GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET(layer_widget))) {
651 if (state == GTK_STATE_SELECTED)
652 pixmap = eye_pixmap[SELECTED];
653 else
654 pixmap = eye_pixmap[NORMAL];
655 } else {
656 pixmap = eye_pixmap[INSENSITIVE];
659 gdk_draw_pixmap (layer_widget->visible->window,
660 layer_widget->visible->style->black_gc,
661 pixmap, 0, 0, 0, 0, eye_width, eye_height);
662 } else {
663 gdk_window_clear (layer_widget->visible->window);
667 static void
668 dia_layer_widget_exclusive_visible(DiaLayerWidget *layer_widget)
670 GList *list;
671 DiaLayerWidget *lw;
672 Layer *layer;
673 int visible = FALSE;
674 int i;
676 /* First determine if _any_ other layer widgets are set to visible */
677 for (i=0;i<layer_widget->dia->data->layers->len;i++) {
678 layer = g_ptr_array_index(layer_widget->dia->data->layers, i);
679 if (layer_widget->layer != layer) {
680 visible |= layer->visible;
684 /* Now, toggle the visibility for all layers except the specified one */
685 for (i=0;i<layer_widget->dia->data->layers->len;i++) {
686 layer = g_ptr_array_index(layer_widget->dia->data->layers, i);
687 if (layer_widget->layer != layer) {
688 visible |= layer->visible;
692 list = GTK_LIST(layer_dialog->layer_list)->children;
693 while (list) {
694 lw = DIA_LAYER_WIDGET(list->data);
695 if (lw != layer_widget)
696 lw->layer->visible = !visible;
697 else
698 lw->layer->visible = TRUE;
700 dia_layer_widget_visible_redraw (lw);
702 list = g_list_next(list);
706 static gint
707 dia_layer_widget_button_events(GtkWidget *widget,
708 GdkEvent *event,
709 gpointer data)
711 static GtkWidget *click_widget = NULL;
712 static int button_down = 0;
713 static int old_state;
714 static int exclusive;
715 GtkWidget *event_widget;
716 gint return_val;
717 GdkEventButton *bevent;
718 DiaLayerWidget *lw;
720 lw = DIA_LAYER_WIDGET(data);
723 return_val = FALSE;
724 switch (event->type) {
725 case GDK_EXPOSE:
726 if (widget == lw->visible)
727 dia_layer_widget_visible_redraw (lw);
728 break;
730 case GDK_BUTTON_PRESS:
731 return_val = TRUE;
733 bevent = (GdkEventButton *) event;
735 button_down = 1;
736 click_widget = widget;
737 gtk_grab_add (click_widget);
739 if (widget == lw->visible) {
740 old_state = lw->layer->visible;
742 /* If this was a shift-click, make all/none visible */
743 if (event->button.state & GDK_SHIFT_MASK) {
744 exclusive = TRUE;
745 dia_layer_widget_exclusive_visible (lw);
746 } else {
747 exclusive = FALSE;
748 lw->layer->visible = !lw->layer->visible;
749 dia_layer_widget_visible_redraw (lw);
752 break;
754 case GDK_BUTTON_RELEASE:
755 return_val = TRUE;
757 button_down = 0;
758 gtk_grab_remove (click_widget);
760 if (widget == lw->visible) {
761 if ((exclusive) || (old_state != lw->layer->visible)) {
762 diagram_add_update_all(lw->dia);
763 diagram_flush(lw->dia);
766 break;
768 case GDK_ENTER_NOTIFY:
769 case GDK_LEAVE_NOTIFY:
770 event_widget = gtk_get_event_widget (event);
772 if (button_down && (event_widget == click_widget)) {
773 if (widget == lw->visible) {
774 if (exclusive) {
775 dia_layer_widget_exclusive_visible (lw);
776 } else {
777 lw->layer->visible = !lw->layer->visible;
778 dia_layer_widget_visible_redraw (lw);
782 break;
784 default:
785 break;
788 return return_val;
791 static void
792 dia_layer_widget_init(DiaLayerWidget *lw)
794 GtkWidget *hbox;
795 GtkWidget *visible;
796 GtkWidget *label;
797 GtkWidget *alignment;
799 hbox = gtk_hbox_new(FALSE, 0);
801 lw->dia = NULL;
802 lw->layer = NULL;
803 lw->edit_dialog = NULL;
805 alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
806 lw->visible = visible = gtk_drawing_area_new ();
807 gtk_drawing_area_size (GTK_DRAWING_AREA (visible), eye_width, eye_height);
808 gtk_widget_set_events (visible, BUTTON_EVENT_MASK);
809 gtk_signal_connect (GTK_OBJECT (visible), "event",
810 (GtkSignalFunc) dia_layer_widget_button_events,
811 lw);
812 gtk_object_set_user_data (GTK_OBJECT (visible), lw);
813 gtk_widget_show(visible);
814 gtk_container_add (GTK_CONTAINER (alignment), visible);
815 gtk_box_pack_start (GTK_BOX (hbox), alignment, FALSE, TRUE, 2);
816 gtk_widget_show(alignment);
818 lw->label = label = gtk_label_new("layer_default_label");
819 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
820 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
821 gtk_widget_show(label);
823 gtk_widget_show(hbox);
825 gtk_container_add(GTK_CONTAINER(lw), hbox);
827 gtk_signal_connect (GTK_OBJECT (lw), "select",
828 (GtkSignalFunc) dia_layer_select_callback,
829 (gpointer) NULL);
830 gtk_signal_connect (GTK_OBJECT (lw), "deselect",
831 (GtkSignalFunc) dia_layer_deselect_callback,
832 (gpointer) NULL);
835 guint
836 dia_layer_widget_get_type(void)
838 static guint dlw_type = 0;
840 if (!dlw_type) {
841 GtkTypeInfo dlw_info = {
842 "DiaLayerWidget",
843 sizeof (DiaLayerWidget),
844 sizeof (DiaLayerWidgetClass),
845 (GtkClassInitFunc) dia_layer_widget_class_init,
846 (GtkObjectInitFunc) dia_layer_widget_init,
847 (GtkArgSetFunc) NULL,
848 (GtkArgGetFunc) NULL
851 dlw_type = gtk_type_unique (gtk_list_item_get_type (), &dlw_info);
854 return dlw_type;
857 GtkWidget *
858 dia_layer_widget_new(Diagram *dia, Layer *layer)
860 GtkWidget *widget;
862 widget = GTK_WIDGET ( gtk_type_new (dia_layer_widget_get_type ()));
863 dia_layer_set_layer(DIA_LAYER_WIDGET(widget), dia, layer);
865 return widget;
868 void
869 dia_layer_set_layer(DiaLayerWidget *widget, Diagram *dia, Layer *layer)
871 widget->dia = dia;
872 widget->layer = layer;
874 dia_layer_update_from_layer(widget);
877 void
878 dia_layer_update_from_layer(DiaLayerWidget *widget)
880 gtk_label_set_text(GTK_LABEL(widget->label), widget->layer->name);
885 * The edit layer attributes dialog
888 static void
889 edit_layer_ok_callback (GtkWidget *w,
890 gpointer client_data)
892 EditLayerDialog *dialog;
893 Layer *layer;
895 dialog = (EditLayerDialog *) client_data;
896 layer = dialog->layer_widget->layer;
898 g_free (layer->name);
899 layer->name = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->name_entry)));
901 diagram_add_update_all(dialog->layer_widget->dia);
902 diagram_flush(dialog->layer_widget->dia);
904 dia_layer_update_from_layer(dialog->layer_widget);
906 dialog->layer_widget->edit_dialog = NULL;
907 gtk_widget_destroy (dialog->dialog);
908 g_free (dialog);
911 static void
912 edit_layer_cancel_callback (GtkWidget *w,
913 gpointer client_data)
915 EditLayerDialog *dialog;
917 dialog = (EditLayerDialog *) client_data;
919 dialog->layer_widget->edit_dialog = NULL;
920 dialog = (EditLayerDialog *) client_data;
921 gtk_widget_destroy (dialog->dialog);
922 g_free (dialog);
925 static gint
926 edit_layer_delete_callback (GtkWidget *w,
927 GdkEvent *e,
928 gpointer client_data)
930 edit_layer_cancel_callback (w, client_data);
932 return TRUE;
935 static void
936 layer_dialog_edit_layer(DiaLayerWidget *layer_widget)
938 EditLayerDialog *dialog;
939 GtkWidget *vbox;
940 GtkWidget *hbox;
941 GtkWidget *label;
942 GtkWidget *button;
944 /* the new dialog structure */
945 dialog = (EditLayerDialog *) g_malloc (sizeof (EditLayerDialog));
946 dialog->layer_widget = layer_widget;
948 /* the dialog */
949 dialog->dialog = gtk_dialog_new ();
950 gtk_window_set_wmclass (GTK_WINDOW (dialog->dialog), "edit_layer_attrributes", "Dia");
951 gtk_window_set_title (GTK_WINDOW (dialog->dialog), _("Edit Layer Attributes"));
952 gtk_window_set_position (GTK_WINDOW (dialog->dialog), GTK_WIN_POS_MOUSE);
954 /* handle the wm close signal */
955 gtk_signal_connect (GTK_OBJECT (dialog->dialog), "delete_event",
956 GTK_SIGNAL_FUNC (edit_layer_delete_callback),
957 dialog);
959 /* the main vbox */
960 vbox = gtk_vbox_new (FALSE, 1);
961 gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
962 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->dialog)->vbox), vbox, TRUE, TRUE, 0);
964 /* the name entry hbox, label and entry */
965 hbox = gtk_hbox_new (FALSE, 1);
966 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
967 label = gtk_label_new (_("Layer name:"));
968 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
969 gtk_widget_show (label);
970 dialog->name_entry = gtk_entry_new ();
971 gtk_box_pack_start (GTK_BOX (hbox), dialog->name_entry, TRUE, TRUE, 0);
972 gtk_entry_set_text (GTK_ENTRY (dialog->name_entry), layer_widget->layer->name);
973 gtk_widget_show (dialog->name_entry);
974 gtk_widget_show (hbox);
976 button = gtk_button_new_with_label (_("OK"));
977 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
978 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->dialog)->action_area),
979 button, TRUE, TRUE, 0);
980 gtk_signal_connect (GTK_OBJECT (button), "clicked",
981 GTK_SIGNAL_FUNC(edit_layer_ok_callback),
982 dialog);
983 gtk_widget_grab_default (button);
984 gtk_widget_show (button);
986 button = gtk_button_new_with_label (_("Cancel"));
987 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
988 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->dialog)->action_area),
989 button, TRUE, TRUE, 0);
990 gtk_signal_connect (GTK_OBJECT (button), "clicked",
991 GTK_SIGNAL_FUNC(edit_layer_cancel_callback),
992 dialog);
993 gtk_widget_show (button);
995 gtk_widget_show (vbox);
996 gtk_widget_show (dialog->dialog);
998 layer_widget->edit_dialog = dialog;
1002 /******** layer changes: */
1004 struct LayerChange {
1005 Change change;
1007 enum LayerChangeType type;
1008 Layer *layer;
1009 int index;
1010 int applied;
1013 static void
1014 layer_change_apply(struct LayerChange *change, Diagram *dia)
1016 change->applied = 1;
1018 switch (change->type) {
1019 case TYPE_DELETE_LAYER:
1020 data_delete_layer(dia->data, change->layer);
1021 break;
1022 case TYPE_ADD_LAYER:
1023 data_add_layer_at(dia->data, change->layer, change->index);
1024 break;
1025 case TYPE_RAISE_LAYER:
1026 data_raise_layer(dia->data, change->layer);
1027 break;
1028 case TYPE_LOWER_LAYER:
1029 data_lower_layer(dia->data, change->layer);
1030 break;
1033 diagram_add_update_all(dia);
1035 if (layer_dialog->diagram == dia) {
1036 layer_dialog_set_diagram(dia);
1040 static void
1041 layer_change_revert(struct LayerChange *change, Diagram *dia)
1043 switch (change->type) {
1044 case TYPE_DELETE_LAYER:
1045 data_add_layer_at(dia->data, change->layer, change->index);
1046 break;
1047 case TYPE_ADD_LAYER:
1048 data_delete_layer(dia->data, change->layer);
1049 break;
1050 case TYPE_RAISE_LAYER:
1051 data_lower_layer(dia->data, change->layer);
1052 break;
1053 case TYPE_LOWER_LAYER:
1054 data_raise_layer(dia->data, change->layer);
1055 break;
1058 diagram_add_update_all(dia);
1060 if (layer_dialog->diagram == dia) {
1061 layer_dialog_set_diagram(dia);
1064 change->applied = 0;
1067 static void
1068 layer_change_free(struct LayerChange *change)
1070 switch (change->type) {
1071 case TYPE_DELETE_LAYER:
1072 if (change->applied) {
1073 layer_destroy(change->layer);
1075 break;
1076 case TYPE_ADD_LAYER:
1077 if (!change->applied) {
1078 layer_destroy(change->layer);
1080 break;
1081 case TYPE_RAISE_LAYER:
1082 break;
1083 case TYPE_LOWER_LAYER:
1084 break;
1088 static Change *
1089 undo_layer(Diagram *dia, Layer *layer, enum LayerChangeType type, int index)
1091 struct LayerChange *change;
1093 change = g_new(struct LayerChange, 1);
1095 change->change.apply = (UndoApplyFunc) layer_change_apply;
1096 change->change.revert = (UndoRevertFunc) layer_change_revert;
1097 change->change.free = (UndoFreeFunc) layer_change_free;
1099 change->type = type;
1100 change->layer = layer;
1101 change->index = index;
1102 change->applied = 1;
1104 undo_push_change(dia->undo, (Change *) change);
1105 return (Change *)change;