switching to XML DocBook
[dia.git] / app / layer_dialog.c
blob309886b0a25165002fa7ad30109bef4475035dce
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 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
29 #include <assert.h>
30 #include <string.h>
31 #include <gdk/gdkkeysyms.h>
33 #include "intl.h"
35 #include "layer_dialog.h"
36 #include "persistence.h"
38 #include "pixmaps/eye.xbm"
39 #include "pixmaps/new.xpm"
40 #include "pixmaps/lower.xpm"
41 #include "pixmaps/raise.xpm"
42 #include "pixmaps/delete.xpm"
44 static struct LayerDialog *layer_dialog = NULL;
46 typedef struct _ButtonData ButtonData;
48 struct _ButtonData {
49 gchar **xpm_data;
50 gpointer callback;
51 char *tooltip;
54 enum LayerChangeType {
55 TYPE_DELETE_LAYER,
56 TYPE_ADD_LAYER,
57 TYPE_RAISE_LAYER,
58 TYPE_LOWER_LAYER
60 static Change *
61 undo_layer(Diagram *dia, Layer *layer, enum LayerChangeType, int index);
63 static void layer_dialog_new_callback(GtkWidget *widget, gpointer gdata);
64 static void layer_dialog_raise_callback(GtkWidget *widget, gpointer gdata);
65 static void layer_dialog_lower_callback(GtkWidget *widget, gpointer gdata);
66 static void layer_dialog_delete_callback(GtkWidget *widget, gpointer gdata);
67 static void layer_dialog_edit_layer(DiaLayerWidget *layer_widget);
69 static ButtonData buttons[] = {
70 { new_xpm, layer_dialog_new_callback, N_("New Layer") },
71 { raise_xpm, layer_dialog_raise_callback, N_("Raise Layer") },
72 { lower_xpm, layer_dialog_lower_callback, N_("Lower Layer") },
73 { delete_xpm, layer_dialog_delete_callback, N_("Delete Layer") },
76 enum {
77 BUTTON_NEW = 0,
78 BUTTON_RAISE,
79 BUTTON_LOWER,
80 BUTTON_DELETE
83 #define BUTTON_EVENT_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | \
84 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
86 static int num_buttons = sizeof(buttons)/sizeof(ButtonData);
88 #define NORMAL 0
89 #define SELECTED 1
90 #define INSENSITIVE 2
92 static GdkPixmap *eye_pixmap[3] = {NULL, NULL, NULL};
94 static GtkWidget *
95 create_button_box(GtkWidget *parent)
97 GtkWidget *button;
98 GtkWidget *button_box;
99 GtkWidget *pixmapwid;
100 GdkPixmap *pixmap;
101 GdkBitmap *mask;
102 GdkColormap *cmap;
103 GtkStyle *style;
104 int i;
106 GtkTooltips *tool_tips = NULL; /* ARG */
108 gtk_widget_ensure_style(parent);
109 style = gtk_widget_get_style(parent);
110 cmap = gtk_widget_get_colormap(parent);
112 button_box = gtk_hbox_new (TRUE, 1);
114 for (i=0;i<num_buttons;i++) {
115 pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, cmap,
116 &mask, &style->bg[GTK_STATE_NORMAL], buttons[i].xpm_data);
118 pixmapwid = gtk_pixmap_new (pixmap, mask);
119 gtk_widget_show(pixmapwid);
121 button = gtk_button_new ();
122 gtk_container_add (GTK_CONTAINER (button), pixmapwid);
123 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
124 (GtkSignalFunc) buttons[i].callback,
125 GTK_OBJECT (parent));
127 if (tool_tips != NULL)
128 gtk_tooltips_set_tip (tool_tips, button, gettext(buttons[i].tooltip), NULL);
130 gtk_box_pack_start (GTK_BOX(button_box), button, TRUE, TRUE, 0);
132 layer_dialog->buttons[i] = button;
134 gtk_widget_show (button);
137 return button_box;
140 static gint
141 layer_list_events (GtkWidget *widget,
142 GdkEvent *event)
144 GdkEventKey *kevent;
145 GdkEventButton *bevent;
146 GtkWidget *event_widget;
147 DiaLayerWidget *layer_widget;
149 event_widget = gtk_get_event_widget (event);
151 if (GTK_IS_LIST_ITEM (event_widget)) {
152 layer_widget = DIA_LAYER_WIDGET(event_widget);
154 switch (event->type) {
155 case GDK_BUTTON_PRESS:
156 bevent = (GdkEventButton *) event;
157 break;
159 case GDK_2BUTTON_PRESS:
160 bevent = (GdkEventButton *) event;
161 layer_dialog_edit_layer(layer_widget);
162 return TRUE;
164 case GDK_KEY_PRESS:
165 kevent = (GdkEventKey *) event;
166 switch (kevent->keyval) {
167 case GDK_Up:
168 /* printf ("up arrow\n"); */
169 break;
170 case GDK_Down:
171 /* printf ("down arrow\n"); */
172 break;
173 default:
174 return FALSE;
176 return TRUE;
178 default:
179 break;
183 return FALSE;
186 static gboolean
187 layer_dialog_delete(GtkWidget *widget, gpointer data)
189 gtk_widget_hide(widget);
190 /* We're caching, so don't destroy */
191 return TRUE;
194 void
195 create_layer_dialog(void)
197 GtkWidget *dialog;
198 GtkWidget *vbox;
199 GtkWidget *hbox;
200 GtkWidget *label;
201 GtkWidget *omenu;
202 GtkWidget *menu;
203 GtkWidget *list;
204 GtkWidget *separator;
205 GtkWidget *scrolled_win;
206 GtkWidget *button_box;
207 GtkWidget *button;
209 layer_dialog = g_new(struct LayerDialog, 1);
211 layer_dialog->diagram = NULL;
213 layer_dialog->dialog = dialog = gtk_dialog_new ();
214 gtk_window_set_title (GTK_WINDOW (dialog), _("Layers"));
215 gtk_window_set_role (GTK_WINDOW (dialog), "layer_window");
216 gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
218 gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
219 GTK_SIGNAL_FUNC(layer_dialog_delete), NULL);
220 gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
221 GTK_SIGNAL_FUNC(gtk_widget_destroyed),
222 &(layer_dialog->dialog));
224 vbox = GTK_DIALOG(dialog)->vbox;
226 hbox = gtk_hbox_new(FALSE, 1);
228 label = gtk_label_new(_("Diagrams:"));
229 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
230 gtk_widget_show (label);
232 layer_dialog->diagram_omenu = omenu = gtk_option_menu_new();
233 gtk_box_pack_start(GTK_BOX(hbox), omenu, TRUE, TRUE, 2);
234 gtk_widget_show (omenu);
236 menu = gtk_menu_new();
237 gtk_option_menu_set_menu(GTK_OPTION_MENU(omenu), menu);
239 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
240 gtk_widget_show (hbox);
242 separator = gtk_hseparator_new();
243 gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 2);
244 gtk_widget_show (separator);
246 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
247 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
248 GTK_POLICY_AUTOMATIC,
249 GTK_POLICY_AUTOMATIC);
250 gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 2);
252 layer_dialog->layer_list = list = gtk_list_new();
254 gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_BROWSE);
255 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
256 gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
257 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_win)));
258 gtk_widget_show (scrolled_win);
259 gtk_widget_show (list);
261 gtk_signal_connect (GTK_OBJECT (list), "event",
262 (GtkSignalFunc) layer_list_events,
263 NULL);
265 button_box = create_button_box(dialog);
267 gtk_box_pack_start (GTK_BOX (vbox), button_box, FALSE, FALSE, 2);
268 gtk_widget_show (button_box);
270 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
273 button = gtk_button_new_with_label (_("Close"));
274 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area),
275 button, TRUE, TRUE, 0);
276 gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
277 GTK_SIGNAL_FUNC(gtk_widget_hide),
278 GTK_OBJECT(dialog));
280 gtk_widget_show (button);
282 persistence_register_window(GTK_WINDOW(dialog));
284 layer_dialog_update_diagram_list();
287 static void
288 dia_layer_select_callback(GtkWidget *widget, gpointer data)
290 DiaLayerWidget *lw;
291 lw = DIA_LAYER_WIDGET(widget);
293 diagram_remove_all_selected(lw->dia, TRUE);
294 diagram_update_extents(lw->dia);
295 data_set_active_layer(lw->dia->data, lw->layer);
296 diagram_add_update_all(lw->dia);
297 diagram_flush(lw->dia);
300 static void
301 dia_layer_deselect_callback(GtkWidget *widget, gpointer data)
306 static void
307 layer_dialog_new_callback(GtkWidget *widget, gpointer gdata)
309 Layer *layer;
310 Diagram *dia;
311 GtkWidget *selected;
312 GList *list = NULL;
313 GtkWidget *layer_widget;
314 int pos;
316 dia = layer_dialog->diagram;
318 if (dia != NULL) {
319 layer = new_layer(g_strdup(_("New layer")),dia->data);
321 assert(GTK_LIST(layer_dialog->layer_list)->selection != NULL);
322 selected = GTK_LIST(layer_dialog->layer_list)->selection->data;
323 pos = gtk_list_child_position(GTK_LIST(layer_dialog->layer_list), selected);
325 data_add_layer_at(dia->data, layer, dia->data->layers->len - pos);
327 diagram_add_update_all(dia);
328 diagram_flush(dia);
330 layer_widget = dia_layer_widget_new(dia, layer);
331 gtk_widget_show(layer_widget);
333 list = g_list_prepend(list, layer_widget);
335 gtk_list_insert_items(GTK_LIST(layer_dialog->layer_list), list, pos);
337 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), pos);
339 undo_layer(dia, layer, TYPE_ADD_LAYER, dia->data->layers->len - pos);
340 undo_set_transactionpoint(dia->undo);
344 static void
345 layer_dialog_delete_callback(GtkWidget *widget, gpointer gdata)
347 Diagram *dia;
348 GtkWidget *selected;
349 Layer *layer;
350 int pos;
352 dia = layer_dialog->diagram;
354 if ((dia != NULL) && (dia->data->layers->len>1)) {
355 assert(GTK_LIST(layer_dialog->layer_list)->selection != NULL);
356 selected = GTK_LIST(layer_dialog->layer_list)->selection->data;
358 layer = dia->data->active_layer;
360 data_delete_layer(dia->data, layer);
361 diagram_add_update_all(dia);
362 diagram_flush(dia);
364 pos = gtk_list_child_position(GTK_LIST(layer_dialog->layer_list), selected);
365 gtk_container_remove(GTK_CONTAINER(layer_dialog->layer_list), selected);
367 undo_layer(dia, layer, TYPE_DELETE_LAYER,
368 dia->data->layers->len - pos);
369 undo_set_transactionpoint(dia->undo);
371 if (--pos<0)
372 pos = 0;
374 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), pos);
378 static void
379 layer_dialog_raise_callback(GtkWidget *widget, gpointer gdata)
381 Layer *layer;
382 Diagram *dia;
383 GtkWidget *selected;
384 GList *list = NULL;
385 int pos;
387 dia = layer_dialog->diagram;
389 if ((dia != NULL) && (dia->data->layers->len>1)) {
390 assert(GTK_LIST(layer_dialog->layer_list)->selection != NULL);
391 selected = GTK_LIST(layer_dialog->layer_list)->selection->data;
393 pos = gtk_list_child_position(GTK_LIST(layer_dialog->layer_list), selected);
395 if (pos > 0) {
396 layer = DIA_LAYER_WIDGET(selected)->layer;
397 data_raise_layer(dia->data, layer);
399 list = g_list_prepend(list, selected);
401 gtk_widget_ref(selected);
403 gtk_list_remove_items(GTK_LIST(layer_dialog->layer_list),
404 list);
406 gtk_list_insert_items(GTK_LIST(layer_dialog->layer_list),
407 list, pos - 1);
409 gtk_widget_unref(selected);
411 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), pos-1);
413 diagram_add_update_all(dia);
414 diagram_flush(dia);
416 undo_layer(dia, layer, TYPE_RAISE_LAYER, 0);
417 undo_set_transactionpoint(dia->undo);
423 static void
424 layer_dialog_lower_callback(GtkWidget *widget, gpointer gdata)
426 Layer *layer;
427 Diagram *dia;
428 GtkWidget *selected;
429 GList *list = NULL;
430 int pos;
432 dia = layer_dialog->diagram;
434 if ((dia != NULL) && (dia->data->layers->len>1)) {
435 assert(GTK_LIST(layer_dialog->layer_list)->selection != NULL);
436 selected = GTK_LIST(layer_dialog->layer_list)->selection->data;
438 pos = gtk_list_child_position(GTK_LIST(layer_dialog->layer_list), selected);
440 if (pos < dia->data->layers->len-1) {
441 layer = DIA_LAYER_WIDGET(selected)->layer;
442 data_lower_layer(dia->data, layer);
444 list = g_list_prepend(list, selected);
446 gtk_widget_ref(selected);
448 gtk_list_remove_items(GTK_LIST(layer_dialog->layer_list),
449 list);
451 gtk_list_insert_items(GTK_LIST(layer_dialog->layer_list),
452 list, pos + 1);
454 gtk_widget_unref(selected);
456 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), pos+1);
458 diagram_add_update_all(dia);
459 diagram_flush(dia);
461 undo_layer(dia, layer, TYPE_LOWER_LAYER, 0);
462 undo_set_transactionpoint(dia->undo);
469 static void
470 layer_dialog_select_diagram_callback(GtkWidget *widget, gpointer gdata)
472 Diagram *dia = (Diagram *) gdata;
474 layer_dialog_set_diagram(dia);
477 void
478 layer_dialog_update_diagram_list(void)
480 GtkWidget *new_menu;
481 GtkWidget *menu_item;
482 GList *dia_list;
483 Diagram *dia;
484 char *filename;
485 int i;
486 int current_nr;
488 new_menu = gtk_menu_new();
490 current_nr = -1;
492 i = 0;
493 dia_list = dia_open_diagrams();
494 while (dia_list != NULL) {
495 dia = (Diagram *) dia_list->data;
497 if (dia == layer_dialog->diagram) {
498 current_nr = i;
501 filename = strrchr(dia->filename, G_DIR_SEPARATOR);
502 if (filename==NULL) {
503 filename = dia->filename;
504 } else {
505 filename++;
508 menu_item = gtk_menu_item_new_with_label(filename);
510 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
511 (GtkSignalFunc) layer_dialog_select_diagram_callback,
512 (gpointer) dia);
514 gtk_menu_append( GTK_MENU(new_menu), menu_item);
515 gtk_widget_show (menu_item);
517 dia_list = g_list_next(dia_list);
518 i++;
521 if (dia_open_diagrams()==NULL) {
522 menu_item = gtk_menu_item_new_with_label (_("none"));
523 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
524 (GtkSignalFunc) layer_dialog_select_diagram_callback,
525 (gpointer) NULL);
526 gtk_menu_append( GTK_MENU(new_menu), menu_item);
527 gtk_widget_show (menu_item);
530 gtk_option_menu_remove_menu(GTK_OPTION_MENU(layer_dialog->diagram_omenu));
532 gtk_option_menu_set_menu(GTK_OPTION_MENU(layer_dialog->diagram_omenu),
533 new_menu);
535 gtk_option_menu_set_history(GTK_OPTION_MENU(layer_dialog->diagram_omenu),
536 current_nr);
537 gtk_menu_set_active(GTK_MENU(new_menu), current_nr);
539 if (current_nr == -1) {
540 dia = NULL;
541 if (dia_open_diagrams()!=NULL) {
542 dia = (Diagram *) dia_open_diagrams()->data;
544 layer_dialog_set_diagram(dia);
548 void
549 layer_dialog_show()
551 if (layer_dialog->dialog == NULL)
552 create_layer_dialog();
553 gtk_widget_show(layer_dialog->dialog);
556 void
557 layer_dialog_set_diagram(Diagram *dia)
559 DiagramData *data;
560 GtkWidget *layer_widget;
561 Layer *layer;
562 Layer *active_layer = NULL;
563 int sel_pos;
564 int i,j;
566 if (dia!=NULL)
567 active_layer = dia->data->active_layer;
569 if (layer_dialog == NULL)
570 create_layer_dialog(); /* May have been destroyed */
572 if (layer_dialog->dialog == NULL)
573 create_layer_dialog();
574 gtk_list_clear_items(GTK_LIST(layer_dialog->layer_list), 0, -1);
575 layer_dialog->diagram = dia;
576 if (dia != NULL) {
577 i = g_list_index(dia_open_diagrams(), dia);
578 if (i >= 0)
579 gtk_option_menu_set_history(GTK_OPTION_MENU(layer_dialog->diagram_omenu),
583 if (dia != NULL) {
584 data = dia->data;
586 sel_pos = 0;
587 for (i=data->layers->len-1,j=0;i>=0;i--,j++) {
588 layer = (Layer *) g_ptr_array_index(data->layers, i);
589 layer_widget = dia_layer_widget_new(dia, layer);
590 gtk_widget_show(layer_widget);
591 gtk_container_add(GTK_CONTAINER(layer_dialog->layer_list), layer_widget);
592 if (layer==active_layer)
593 sel_pos = j;
595 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), sel_pos);
601 /******* DiaLayerWidget: *****/
603 static void
604 dia_layer_widget_unrealize(GtkWidget *widget)
606 DiaLayerWidget *lw = DIA_LAYER_WIDGET(widget);
608 if (lw->edit_dialog != NULL) {
609 gtk_widget_destroy(lw->edit_dialog->dialog);
610 g_free(lw->edit_dialog);
611 lw->edit_dialog = NULL;
614 (* GTK_WIDGET_CLASS (gtk_type_class(gtk_list_item_get_type ()))->unrealize) (widget);
617 static void
618 dia_layer_widget_class_init(DiaLayerWidgetClass *klass)
620 GtkObjectClass *object_class;
621 GtkWidgetClass *widget_class;
623 object_class = (GtkObjectClass*) klass;
624 widget_class = (GtkWidgetClass*) klass;
626 widget_class->unrealize = dia_layer_widget_unrealize;
629 static void
630 dia_layer_widget_visible_redraw(DiaLayerWidget *layer_widget)
632 GdkPixmap *pixmap;
633 GdkColor *color;
634 GtkStateType state;
636 state = GTK_WIDGET(layer_widget)->state;
638 if (GTK_WIDGET_IS_SENSITIVE (layer_widget))
640 if (state == GTK_STATE_SELECTED)
641 color = &layer_widget->visible->style->bg[GTK_STATE_SELECTED];
642 else
643 color = &layer_widget->visible->style->white;
645 else
646 color = &layer_widget->visible->style->bg[GTK_STATE_INSENSITIVE];
648 gdk_window_set_background (layer_widget->visible->window, color);
650 if (layer_widget->layer->visible) {
651 if (!eye_pixmap[NORMAL]) {
652 eye_pixmap[NORMAL] =
653 gdk_pixmap_create_from_data (layer_widget->visible->window,
654 (gchar*) eye_bits, eye_width, eye_height, -1,
655 &layer_widget->visible->style->fg[GTK_STATE_NORMAL],
656 &layer_widget->visible->style->white);
657 eye_pixmap[SELECTED] =
658 gdk_pixmap_create_from_data (layer_widget->visible->window,
659 (gchar*) eye_bits, eye_width, eye_height, -1,
660 &layer_widget->visible->style->fg[GTK_STATE_SELECTED],
661 &layer_widget->visible->style->bg[GTK_STATE_SELECTED]);
662 eye_pixmap[INSENSITIVE] =
663 gdk_pixmap_create_from_data (layer_widget->visible->window,
664 (gchar*) eye_bits, eye_width, eye_height, -1,
665 &layer_widget->visible->style->fg[GTK_STATE_INSENSITIVE],
666 &layer_widget->visible->style->bg[GTK_STATE_INSENSITIVE]);
669 if (GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET(layer_widget))) {
670 if (state == GTK_STATE_SELECTED)
671 pixmap = eye_pixmap[SELECTED];
672 else
673 pixmap = eye_pixmap[NORMAL];
674 } else {
675 pixmap = eye_pixmap[INSENSITIVE];
678 gdk_draw_pixmap (layer_widget->visible->window,
679 layer_widget->visible->style->black_gc,
680 pixmap, 0, 0, 0, 0, eye_width, eye_height);
681 } else {
682 gdk_window_clear (layer_widget->visible->window);
686 static void
687 dia_layer_widget_exclusive_visible(DiaLayerWidget *layer_widget)
689 GList *list;
690 DiaLayerWidget *lw;
691 Layer *layer;
692 int visible = FALSE;
693 int i;
695 /* First determine if _any_ other layer widgets are set to visible */
696 for (i=0;i<layer_widget->dia->data->layers->len;i++) {
697 layer = g_ptr_array_index(layer_widget->dia->data->layers, i);
698 if (layer_widget->layer != layer) {
699 visible |= layer->visible;
703 /* Now, toggle the visibility for all layers except the specified one */
704 for (i=0;i<layer_widget->dia->data->layers->len;i++) {
705 layer = g_ptr_array_index(layer_widget->dia->data->layers, i);
706 if (layer_widget->layer != layer) {
707 visible |= layer->visible;
711 list = GTK_LIST(layer_dialog->layer_list)->children;
712 while (list) {
713 lw = DIA_LAYER_WIDGET(list->data);
714 if (lw != layer_widget)
715 lw->layer->visible = !visible;
716 else
717 lw->layer->visible = TRUE;
719 dia_layer_widget_visible_redraw (lw);
721 list = g_list_next(list);
725 static gint
726 dia_layer_widget_button_events(GtkWidget *widget,
727 GdkEvent *event,
728 gpointer data)
730 static GtkWidget *click_widget = NULL;
731 static int button_down = 0;
732 static int old_state;
733 static int exclusive;
734 GtkWidget *event_widget;
735 gint return_val;
736 GdkEventButton *bevent;
737 DiaLayerWidget *lw;
739 lw = DIA_LAYER_WIDGET(data);
742 return_val = FALSE;
743 switch (event->type) {
744 case GDK_EXPOSE:
745 if (widget == lw->visible)
746 dia_layer_widget_visible_redraw (lw);
747 break;
749 case GDK_BUTTON_PRESS:
750 return_val = TRUE;
752 bevent = (GdkEventButton *) event;
754 button_down = 1;
755 click_widget = widget;
756 gtk_grab_add (click_widget);
758 if (widget == lw->visible) {
759 old_state = lw->layer->visible;
761 /* If this was a shift-click, make all/none visible */
762 if (event->button.state & GDK_SHIFT_MASK) {
763 exclusive = TRUE;
764 dia_layer_widget_exclusive_visible (lw);
765 } else {
766 exclusive = FALSE;
767 lw->layer->visible = !lw->layer->visible;
768 dia_layer_widget_visible_redraw (lw);
771 break;
773 case GDK_BUTTON_RELEASE:
774 return_val = TRUE;
776 button_down = 0;
777 gtk_grab_remove (click_widget);
779 if (widget == lw->visible) {
780 if ((exclusive) || (old_state != lw->layer->visible)) {
781 diagram_add_update_all(lw->dia);
782 diagram_flush(lw->dia);
785 break;
787 case GDK_ENTER_NOTIFY:
788 case GDK_LEAVE_NOTIFY:
789 event_widget = gtk_get_event_widget (event);
791 if (button_down && (event_widget == click_widget)) {
792 if (widget == lw->visible) {
793 if (exclusive) {
794 dia_layer_widget_exclusive_visible (lw);
795 } else {
796 lw->layer->visible = !lw->layer->visible;
797 dia_layer_widget_visible_redraw (lw);
801 break;
803 default:
804 break;
807 return return_val;
810 static void
811 dia_layer_widget_init(DiaLayerWidget *lw)
813 GtkWidget *hbox;
814 GtkWidget *visible;
815 GtkWidget *label;
816 GtkWidget *alignment;
818 hbox = gtk_hbox_new(FALSE, 0);
820 lw->dia = NULL;
821 lw->layer = NULL;
822 lw->edit_dialog = NULL;
824 alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
825 lw->visible = visible = gtk_drawing_area_new ();
826 gtk_drawing_area_size (GTK_DRAWING_AREA (visible), eye_width, eye_height);
827 gtk_widget_set_events (visible, BUTTON_EVENT_MASK);
828 gtk_signal_connect (GTK_OBJECT (visible), "event",
829 (GtkSignalFunc) dia_layer_widget_button_events,
830 lw);
831 gtk_object_set_user_data (GTK_OBJECT (visible), lw);
832 gtk_widget_show(visible);
833 gtk_container_add (GTK_CONTAINER (alignment), visible);
834 gtk_box_pack_start (GTK_BOX (hbox), alignment, FALSE, TRUE, 2);
835 gtk_widget_show(alignment);
837 lw->label = label = gtk_label_new("layer_default_label");
838 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
839 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
840 gtk_widget_show(label);
842 gtk_widget_show(hbox);
844 gtk_container_add(GTK_CONTAINER(lw), hbox);
846 gtk_signal_connect (GTK_OBJECT (lw), "select",
847 (GtkSignalFunc) dia_layer_select_callback,
848 (gpointer) NULL);
849 gtk_signal_connect (GTK_OBJECT (lw), "deselect",
850 (GtkSignalFunc) dia_layer_deselect_callback,
851 (gpointer) NULL);
854 guint
855 dia_layer_widget_get_type(void)
857 static guint dlw_type = 0;
859 if (!dlw_type) {
860 GtkTypeInfo dlw_info = {
861 "DiaLayerWidget",
862 sizeof (DiaLayerWidget),
863 sizeof (DiaLayerWidgetClass),
864 (GtkClassInitFunc) dia_layer_widget_class_init,
865 (GtkObjectInitFunc) dia_layer_widget_init,
866 NULL,
867 NULL,
868 (GtkClassInitFunc) NULL,
871 dlw_type = gtk_type_unique (gtk_list_item_get_type (), &dlw_info);
874 return dlw_type;
877 GtkWidget *
878 dia_layer_widget_new(Diagram *dia, Layer *layer)
880 GtkWidget *widget;
882 widget = GTK_WIDGET ( gtk_type_new (dia_layer_widget_get_type ()));
883 dia_layer_set_layer(DIA_LAYER_WIDGET(widget), dia, layer);
885 return widget;
888 void
889 dia_layer_set_layer(DiaLayerWidget *widget, Diagram *dia, Layer *layer)
891 widget->dia = dia;
892 widget->layer = layer;
894 dia_layer_update_from_layer(widget);
897 void
898 dia_layer_update_from_layer (DiaLayerWidget *widget)
900 gtk_label_set_text (GTK_LABEL (widget->label), widget->layer->name);
905 * The edit layer attributes dialog
908 static void
909 edit_layer_ok_callback (GtkWidget *w, gpointer client_data)
911 EditLayerDialog *dialog;
912 Layer *layer;
914 dialog = (EditLayerDialog *) client_data;
915 layer = dialog->layer_widget->layer;
917 g_free (layer->name);
918 layer->name = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->name_entry)));
920 diagram_add_update_all (dialog->layer_widget->dia);
921 diagram_flush (dialog->layer_widget->dia);
923 dia_layer_update_from_layer (dialog->layer_widget);
925 dialog->layer_widget->edit_dialog = NULL;
926 gtk_widget_destroy (dialog->dialog);
927 g_free (dialog);
930 static void
931 edit_layer_cancel_callback (GtkWidget *w,
932 gpointer client_data)
934 EditLayerDialog *dialog;
936 dialog = (EditLayerDialog *) client_data;
938 dialog->layer_widget->edit_dialog = NULL;
939 if (dialog->dialog != NULL)
940 gtk_widget_destroy (dialog->dialog);
941 g_free (dialog);
944 static gint
945 edit_layer_delete_callback (GtkWidget *w,
946 GdkEvent *e,
947 gpointer client_data)
949 edit_layer_cancel_callback (w, client_data);
951 return TRUE;
954 static void
955 layer_dialog_edit_layer (DiaLayerWidget *layer_widget)
957 EditLayerDialog *dialog;
958 GtkWidget *vbox;
959 GtkWidget *hbox;
960 GtkWidget *label;
961 GtkWidget *button;
963 /* the new dialog structure */
964 dialog = (EditLayerDialog *) g_malloc (sizeof (EditLayerDialog));
965 dialog->layer_widget = layer_widget;
967 /* the dialog */
968 dialog->dialog = gtk_dialog_new ();
969 gtk_window_set_role (GTK_WINDOW (dialog->dialog), "edit_layer_attrributes");
970 gtk_window_set_title (GTK_WINDOW (dialog->dialog), _("Edit Layer Attributes"));
971 gtk_window_set_position (GTK_WINDOW (dialog->dialog), GTK_WIN_POS_MOUSE);
973 /* handle the wm close signal */
974 gtk_signal_connect (GTK_OBJECT (dialog->dialog), "delete_event",
975 GTK_SIGNAL_FUNC (edit_layer_delete_callback),
976 dialog);
977 gtk_signal_connect (GTK_OBJECT (dialog->dialog), "destroy",
978 GTK_SIGNAL_FUNC (gtk_widget_destroy),
979 &dialog->dialog);
981 /* the main vbox */
982 vbox = gtk_vbox_new (FALSE, 1);
983 gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
984 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->dialog)->vbox), vbox, TRUE, TRUE, 0);
986 /* the name entry hbox, label and entry */
987 hbox = gtk_hbox_new (FALSE, 1);
988 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
989 label = gtk_label_new (_("Layer name:"));
990 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
991 gtk_widget_show (label);
992 dialog->name_entry = gtk_entry_new ();
993 gtk_box_pack_start (GTK_BOX (hbox), dialog->name_entry, TRUE, TRUE, 0);
994 gtk_entry_set_text (GTK_ENTRY (dialog->name_entry), layer_widget->layer->name);
995 gtk_widget_show (dialog->name_entry);
996 gtk_widget_show (hbox);
998 button = gtk_button_new_with_label (_("OK"));
999 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1000 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->dialog)->action_area),
1001 button, TRUE, TRUE, 0);
1002 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1003 GTK_SIGNAL_FUNC(edit_layer_ok_callback),
1004 dialog);
1005 gtk_widget_grab_default (button);
1006 gtk_widget_show (button);
1008 button = gtk_button_new_with_label (_("Cancel"));
1009 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1010 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->dialog)->action_area),
1011 button, TRUE, TRUE, 0);
1012 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1013 GTK_SIGNAL_FUNC(edit_layer_cancel_callback),
1014 dialog);
1015 gtk_widget_show (button);
1017 gtk_widget_show (vbox);
1018 gtk_widget_show (dialog->dialog);
1020 layer_widget->edit_dialog = dialog;
1024 /******** layer changes: */
1026 struct LayerChange {
1027 Change change;
1029 enum LayerChangeType type;
1030 Layer *layer;
1031 int index;
1032 int applied;
1035 static void
1036 layer_change_apply(struct LayerChange *change, Diagram *dia)
1038 change->applied = 1;
1040 switch (change->type) {
1041 case TYPE_DELETE_LAYER:
1042 data_delete_layer(dia->data, change->layer);
1043 break;
1044 case TYPE_ADD_LAYER:
1045 data_add_layer_at(dia->data, change->layer, change->index);
1046 break;
1047 case TYPE_RAISE_LAYER:
1048 data_raise_layer(dia->data, change->layer);
1049 break;
1050 case TYPE_LOWER_LAYER:
1051 data_lower_layer(dia->data, change->layer);
1052 break;
1055 diagram_add_update_all(dia);
1057 if (layer_dialog->diagram == dia) {
1058 layer_dialog_set_diagram(dia);
1062 static void
1063 layer_change_revert(struct LayerChange *change, Diagram *dia)
1065 switch (change->type) {
1066 case TYPE_DELETE_LAYER:
1067 data_add_layer_at(dia->data, change->layer, change->index);
1068 break;
1069 case TYPE_ADD_LAYER:
1070 data_delete_layer(dia->data, change->layer);
1071 break;
1072 case TYPE_RAISE_LAYER:
1073 data_lower_layer(dia->data, change->layer);
1074 break;
1075 case TYPE_LOWER_LAYER:
1076 data_raise_layer(dia->data, change->layer);
1077 break;
1080 diagram_add_update_all(dia);
1082 if (layer_dialog->diagram == dia) {
1083 layer_dialog_set_diagram(dia);
1086 change->applied = 0;
1089 static void
1090 layer_change_free(struct LayerChange *change)
1092 switch (change->type) {
1093 case TYPE_DELETE_LAYER:
1094 if (change->applied) {
1095 layer_destroy(change->layer);
1097 break;
1098 case TYPE_ADD_LAYER:
1099 if (!change->applied) {
1100 layer_destroy(change->layer);
1102 break;
1103 case TYPE_RAISE_LAYER:
1104 break;
1105 case TYPE_LOWER_LAYER:
1106 break;
1110 static Change *
1111 undo_layer(Diagram *dia, Layer *layer, enum LayerChangeType type, int index)
1113 struct LayerChange *change;
1115 change = g_new(struct LayerChange, 1);
1117 change->change.apply = (UndoApplyFunc) layer_change_apply;
1118 change->change.revert = (UndoRevertFunc) layer_change_revert;
1119 change->change.free = (UndoFreeFunc) layer_change_free;
1121 change->type = type;
1122 change->layer = layer;
1123 change->index = index;
1124 change->applied = 1;
1126 undo_push_change(dia->undo, (Change *) change);
1127 return (Change *)change;