svg text alignment
[dia.git] / app / layer_dialog.c
blobf1914ff91ce5ab86a3bbf49ab0e90da523cb36c6
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"
37 #include "pixmaps/eye.xbm"
38 #include "pixmaps/new.xpm"
39 #include "pixmaps/lower.xpm"
40 #include "pixmaps/raise.xpm"
41 #include "pixmaps/delete.xpm"
43 static struct LayerDialog *layer_dialog = NULL;
45 typedef struct _ButtonData ButtonData;
47 struct _ButtonData {
48 gchar **xpm_data;
49 gpointer callback;
50 char *tooltip;
53 enum LayerChangeType {
54 TYPE_DELETE_LAYER,
55 TYPE_ADD_LAYER,
56 TYPE_RAISE_LAYER,
57 TYPE_LOWER_LAYER
59 static Change *
60 undo_layer(Diagram *dia, Layer *layer, enum LayerChangeType, int index);
62 static void layer_dialog_new_callback(GtkWidget *widget, gpointer gdata);
63 static void layer_dialog_raise_callback(GtkWidget *widget, gpointer gdata);
64 static void layer_dialog_lower_callback(GtkWidget *widget, gpointer gdata);
65 static void layer_dialog_delete_callback(GtkWidget *widget, gpointer gdata);
66 static void layer_dialog_edit_layer(DiaLayerWidget *layer_widget);
68 static ButtonData buttons[] = {
69 { new_xpm, layer_dialog_new_callback, N_("New Layer") },
70 { raise_xpm, layer_dialog_raise_callback, N_("Raise Layer") },
71 { lower_xpm, layer_dialog_lower_callback, N_("Lower Layer") },
72 { delete_xpm, layer_dialog_delete_callback, N_("Delete Layer") },
75 enum {
76 BUTTON_NEW = 0,
77 BUTTON_RAISE,
78 BUTTON_LOWER,
79 BUTTON_DELETE
82 #define BUTTON_EVENT_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | \
83 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
85 static int num_buttons = sizeof(buttons)/sizeof(ButtonData);
87 #define NORMAL 0
88 #define SELECTED 1
89 #define INSENSITIVE 2
91 static GdkPixmap *eye_pixmap[3] = {NULL, NULL, NULL};
93 static GtkWidget *
94 create_button_box(GtkWidget *parent)
96 GtkWidget *button;
97 GtkWidget *button_box;
98 GtkWidget *pixmapwid;
99 GdkPixmap *pixmap;
100 GdkBitmap *mask;
101 GdkColormap *cmap;
102 GtkStyle *style;
103 int i;
105 GtkTooltips *tool_tips = NULL; /* ARG */
107 gtk_widget_ensure_style(parent);
108 style = gtk_widget_get_style(parent);
109 cmap = gtk_widget_get_colormap(parent);
111 button_box = gtk_hbox_new (TRUE, 1);
113 for (i=0;i<num_buttons;i++) {
114 pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, cmap,
115 &mask, &style->bg[GTK_STATE_NORMAL], buttons[i].xpm_data);
117 pixmapwid = gtk_pixmap_new (pixmap, mask);
118 gtk_widget_show(pixmapwid);
120 button = gtk_button_new ();
121 gtk_container_add (GTK_CONTAINER (button), pixmapwid);
122 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
123 (GtkSignalFunc) buttons[i].callback,
124 GTK_OBJECT (parent));
126 if (tool_tips != NULL)
127 gtk_tooltips_set_tip (tool_tips, button, gettext(buttons[i].tooltip), NULL);
129 gtk_box_pack_start (GTK_BOX(button_box), button, TRUE, TRUE, 0);
131 layer_dialog->buttons[i] = button;
133 gtk_widget_show (button);
136 return button_box;
139 static gint
140 layer_list_events (GtkWidget *widget,
141 GdkEvent *event)
143 GdkEventKey *kevent;
144 GdkEventButton *bevent;
145 GtkWidget *event_widget;
146 DiaLayerWidget *layer_widget;
148 event_widget = gtk_get_event_widget (event);
150 if (GTK_IS_LIST_ITEM (event_widget)) {
151 layer_widget = DIA_LAYER_WIDGET(event_widget);
153 switch (event->type) {
154 case GDK_BUTTON_PRESS:
155 bevent = (GdkEventButton *) event;
156 break;
158 case GDK_2BUTTON_PRESS:
159 bevent = (GdkEventButton *) event;
160 layer_dialog_edit_layer(layer_widget);
161 return TRUE;
163 case GDK_KEY_PRESS:
164 kevent = (GdkEventKey *) event;
165 switch (kevent->keyval) {
166 case GDK_Up:
167 /* printf ("up arrow\n"); */
168 break;
169 case GDK_Down:
170 /* printf ("down arrow\n"); */
171 break;
172 default:
173 return FALSE;
175 return TRUE;
177 default:
178 break;
182 return FALSE;
186 void
187 create_layer_dialog(void)
189 GtkWidget *dialog;
190 GtkWidget *vbox;
191 GtkWidget *hbox;
192 GtkWidget *label;
193 GtkWidget *omenu;
194 GtkWidget *menu;
195 GtkWidget *list;
196 GtkWidget *separator;
197 GtkWidget *scrolled_win;
198 GtkWidget *button_box;
199 GtkWidget *button;
201 layer_dialog = g_new(struct LayerDialog, 1);
203 layer_dialog->diagram = NULL;
205 layer_dialog->dialog = dialog = gtk_dialog_new ();
206 gtk_window_set_title (GTK_WINDOW (dialog), _("Layers"));
207 gtk_window_set_wmclass (GTK_WINDOW (dialog),
208 "layer_window", "Dia");
209 gtk_window_set_policy (GTK_WINDOW (dialog), FALSE, TRUE, TRUE);
211 gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
212 GTK_SIGNAL_FUNC(gtk_widget_hide), NULL);
215 vbox = GTK_DIALOG(dialog)->vbox;
217 hbox = gtk_hbox_new(FALSE, 1);
219 label = gtk_label_new(_("Diagrams:"));
220 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
221 gtk_widget_show (label);
223 layer_dialog->diagram_omenu = omenu = gtk_option_menu_new();
224 gtk_box_pack_start(GTK_BOX(hbox), omenu, TRUE, TRUE, 2);
225 gtk_widget_show (omenu);
227 menu = gtk_menu_new();
228 gtk_option_menu_set_menu(GTK_OPTION_MENU(omenu), menu);
230 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
231 gtk_widget_show (hbox);
233 separator = gtk_hseparator_new();
234 gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 2);
235 gtk_widget_show (separator);
237 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
238 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
239 GTK_POLICY_AUTOMATIC,
240 GTK_POLICY_AUTOMATIC);
241 gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 2);
243 layer_dialog->layer_list = list = gtk_list_new();
245 gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_BROWSE);
246 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
247 gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
248 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_win)));
249 gtk_widget_show (scrolled_win);
250 gtk_widget_show (list);
252 gtk_signal_connect (GTK_OBJECT (list), "event",
253 (GtkSignalFunc) layer_list_events,
254 NULL);
256 button_box = create_button_box(dialog);
258 gtk_box_pack_start (GTK_BOX (vbox), button_box, FALSE, FALSE, 2);
259 gtk_widget_show (button_box);
261 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
264 button = gtk_button_new_with_label (_("Close"));
265 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area),
266 button, TRUE, TRUE, 0);
267 gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
268 GTK_SIGNAL_FUNC(gtk_widget_hide),
269 GTK_OBJECT(dialog));
271 gtk_widget_show (button);
274 layer_dialog_update_diagram_list();
277 static void
278 dia_layer_select_callback(GtkWidget *widget, gpointer data)
280 DiaLayerWidget *lw;
281 lw = DIA_LAYER_WIDGET(widget);
283 diagram_remove_all_selected(lw->dia, TRUE);
284 diagram_update_extents(lw->dia);
285 data_set_active_layer(lw->dia->data, lw->layer);
286 diagram_add_update_all(lw->dia);
287 diagram_flush(lw->dia);
290 static void
291 dia_layer_deselect_callback(GtkWidget *widget, gpointer data)
296 static void
297 layer_dialog_new_callback(GtkWidget *widget, gpointer gdata)
299 Layer *layer;
300 Diagram *dia;
301 GtkWidget *selected;
302 GList *list = NULL;
303 GtkWidget *layer_widget;
304 int pos;
306 dia = layer_dialog->diagram;
308 if (dia != NULL) {
309 layer = new_layer(g_strdup(_("New layer")));
311 assert(GTK_LIST(layer_dialog->layer_list)->selection != NULL);
312 selected = GTK_LIST(layer_dialog->layer_list)->selection->data;
313 pos = gtk_list_child_position(GTK_LIST(layer_dialog->layer_list), selected);
315 data_add_layer_at(dia->data, layer, dia->data->layers->len - pos);
317 diagram_add_update_all(dia);
318 diagram_flush(dia);
320 layer_widget = dia_layer_widget_new(dia, layer);
321 gtk_widget_show(layer_widget);
323 list = g_list_prepend(list, layer_widget);
325 gtk_list_insert_items(GTK_LIST(layer_dialog->layer_list), list, pos);
327 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), pos);
329 undo_layer(dia, layer, TYPE_ADD_LAYER, dia->data->layers->len - pos);
330 undo_set_transactionpoint(dia->undo);
334 static void
335 layer_dialog_delete_callback(GtkWidget *widget, gpointer gdata)
337 Diagram *dia;
338 GtkWidget *selected;
339 Layer *layer;
340 int pos;
342 dia = layer_dialog->diagram;
344 if ((dia != NULL) && (dia->data->layers->len>1)) {
345 assert(GTK_LIST(layer_dialog->layer_list)->selection != NULL);
346 selected = GTK_LIST(layer_dialog->layer_list)->selection->data;
348 layer = dia->data->active_layer;
350 data_delete_layer(dia->data, layer);
351 diagram_add_update_all(dia);
352 diagram_flush(dia);
354 pos = gtk_list_child_position(GTK_LIST(layer_dialog->layer_list), selected);
355 gtk_container_remove(GTK_CONTAINER(layer_dialog->layer_list), selected);
357 undo_layer(dia, layer, TYPE_DELETE_LAYER,
358 dia->data->layers->len - pos);
359 undo_set_transactionpoint(dia->undo);
361 if (--pos<0)
362 pos = 0;
364 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), pos);
368 static void
369 layer_dialog_raise_callback(GtkWidget *widget, gpointer gdata)
371 Layer *layer;
372 Diagram *dia;
373 GtkWidget *selected;
374 GList *list = NULL;
375 int pos;
377 dia = layer_dialog->diagram;
379 if ((dia != NULL) && (dia->data->layers->len>1)) {
380 assert(GTK_LIST(layer_dialog->layer_list)->selection != NULL);
381 selected = GTK_LIST(layer_dialog->layer_list)->selection->data;
383 pos = gtk_list_child_position(GTK_LIST(layer_dialog->layer_list), selected);
385 if (pos > 0) {
386 layer = DIA_LAYER_WIDGET(selected)->layer;
387 data_raise_layer(dia->data, layer);
389 list = g_list_prepend(list, selected);
391 gtk_widget_ref(selected);
393 gtk_list_remove_items(GTK_LIST(layer_dialog->layer_list),
394 list);
396 gtk_list_insert_items(GTK_LIST(layer_dialog->layer_list),
397 list, pos - 1);
399 gtk_widget_unref(selected);
401 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), pos-1);
403 diagram_add_update_all(dia);
404 diagram_flush(dia);
406 undo_layer(dia, layer, TYPE_RAISE_LAYER, 0);
407 undo_set_transactionpoint(dia->undo);
413 static void
414 layer_dialog_lower_callback(GtkWidget *widget, gpointer gdata)
416 Layer *layer;
417 Diagram *dia;
418 GtkWidget *selected;
419 GList *list = NULL;
420 int pos;
422 dia = layer_dialog->diagram;
424 if ((dia != NULL) && (dia->data->layers->len>1)) {
425 assert(GTK_LIST(layer_dialog->layer_list)->selection != NULL);
426 selected = GTK_LIST(layer_dialog->layer_list)->selection->data;
428 pos = gtk_list_child_position(GTK_LIST(layer_dialog->layer_list), selected);
430 if (pos < dia->data->layers->len-1) {
431 layer = DIA_LAYER_WIDGET(selected)->layer;
432 data_lower_layer(dia->data, layer);
434 list = g_list_prepend(list, selected);
436 gtk_widget_ref(selected);
438 gtk_list_remove_items(GTK_LIST(layer_dialog->layer_list),
439 list);
441 gtk_list_insert_items(GTK_LIST(layer_dialog->layer_list),
442 list, pos + 1);
444 gtk_widget_unref(selected);
446 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), pos+1);
448 diagram_add_update_all(dia);
449 diagram_flush(dia);
451 undo_layer(dia, layer, TYPE_LOWER_LAYER, 0);
452 undo_set_transactionpoint(dia->undo);
459 static void
460 layer_dialog_select_diagram_callback(GtkWidget *widget, gpointer gdata)
462 Diagram *dia = (Diagram *) gdata;
464 layer_dialog_set_diagram(dia);
467 void
468 layer_dialog_update_diagram_list(void)
470 GtkWidget *new_menu;
471 GtkWidget *menu_item;
472 GList *dia_list;
473 Diagram *dia;
474 char *filename;
475 int i;
476 int current_nr;
478 new_menu = gtk_menu_new();
480 current_nr = -1;
482 i = 0;
483 dia_list = open_diagrams;
484 while (dia_list != NULL) {
485 dia = (Diagram *) dia_list->data;
487 if (dia == layer_dialog->diagram) {
488 current_nr = i;
491 filename = strrchr(dia->filename, G_DIR_SEPARATOR);
492 if (filename==NULL) {
493 filename = dia->filename;
494 } else {
495 filename++;
498 menu_item = gtk_menu_item_new_with_label(filename);
500 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
501 (GtkSignalFunc) layer_dialog_select_diagram_callback,
502 (gpointer) dia);
504 gtk_menu_append( GTK_MENU(new_menu), menu_item);
505 gtk_widget_show (menu_item);
507 dia_list = g_list_next(dia_list);
508 i++;
511 if (open_diagrams==NULL) {
512 menu_item = gtk_menu_item_new_with_label (_("none"));
513 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
514 (GtkSignalFunc) layer_dialog_select_diagram_callback,
515 (gpointer) NULL);
516 gtk_menu_append( GTK_MENU(new_menu), menu_item);
517 gtk_widget_show (menu_item);
520 gtk_option_menu_remove_menu(GTK_OPTION_MENU(layer_dialog->diagram_omenu));
522 gtk_option_menu_set_menu(GTK_OPTION_MENU(layer_dialog->diagram_omenu),
523 new_menu);
525 gtk_option_menu_set_history(GTK_OPTION_MENU(layer_dialog->diagram_omenu),
526 current_nr);
527 gtk_menu_set_active(GTK_MENU(new_menu), current_nr);
529 if (current_nr == -1) {
530 dia = NULL;
531 if (open_diagrams!=NULL) {
532 dia = (Diagram *) open_diagrams->data;
534 layer_dialog_set_diagram(dia);
538 void
539 layer_dialog_show()
541 gtk_widget_show(layer_dialog->dialog);
544 void
545 layer_dialog_set_diagram(Diagram *dia)
547 DiagramData *data;
548 GtkWidget *layer_widget;
549 Layer *layer;
550 Layer *active_layer = NULL;
551 int sel_pos;
552 int i,j;
555 if (dia!=NULL)
556 active_layer = dia->data->active_layer;
558 gtk_list_clear_items(GTK_LIST(layer_dialog->layer_list), 0, -1);
559 layer_dialog->diagram = dia;
560 if (dia != NULL) {
561 i = g_list_index(open_diagrams, dia);
562 if (i >= 0)
563 gtk_option_menu_set_history(GTK_OPTION_MENU(layer_dialog->diagram_omenu),
567 if (dia != NULL) {
568 data = dia->data;
570 sel_pos = 0;
571 for (i=data->layers->len-1,j=0;i>=0;i--,j++) {
572 layer = (Layer *) g_ptr_array_index(data->layers, i);
573 layer_widget = dia_layer_widget_new(dia, layer);
574 gtk_widget_show(layer_widget);
575 gtk_container_add(GTK_CONTAINER(layer_dialog->layer_list), layer_widget);
576 if (layer==active_layer)
577 sel_pos = j;
579 gtk_list_select_item(GTK_LIST(layer_dialog->layer_list), sel_pos);
585 /******* DiaLayerWidget: *****/
587 static void
588 dia_layer_widget_unrealize(GtkWidget *widget)
590 DiaLayerWidget *lw = DIA_LAYER_WIDGET(widget);
592 if (lw->edit_dialog != NULL) {
593 gtk_widget_destroy(lw->edit_dialog->dialog);
594 g_free(lw->edit_dialog);
595 lw->edit_dialog = NULL;
598 (* GTK_WIDGET_CLASS (gtk_type_class(gtk_list_item_get_type ()))->unrealize) (widget);
601 static void
602 dia_layer_widget_class_init(DiaLayerWidgetClass *klass)
604 GtkObjectClass *object_class;
605 GtkWidgetClass *widget_class;
607 object_class = (GtkObjectClass*) klass;
608 widget_class = (GtkWidgetClass*) klass;
610 widget_class->unrealize = dia_layer_widget_unrealize;
613 static void
614 dia_layer_widget_visible_redraw(DiaLayerWidget *layer_widget)
616 GdkPixmap *pixmap;
617 GdkColor *color;
618 GtkStateType state;
620 state = GTK_WIDGET(layer_widget)->state;
622 if (GTK_WIDGET_IS_SENSITIVE (layer_widget))
624 if (state == GTK_STATE_SELECTED)
625 color = &layer_widget->visible->style->bg[GTK_STATE_SELECTED];
626 else
627 color = &layer_widget->visible->style->white;
629 else
630 color = &layer_widget->visible->style->bg[GTK_STATE_INSENSITIVE];
632 gdk_window_set_background (layer_widget->visible->window, color);
634 if (layer_widget->layer->visible) {
635 if (!eye_pixmap[NORMAL]) {
636 eye_pixmap[NORMAL] =
637 gdk_pixmap_create_from_data (layer_widget->visible->window,
638 (gchar*) eye_bits, eye_width, eye_height, -1,
639 &layer_widget->visible->style->fg[GTK_STATE_NORMAL],
640 &layer_widget->visible->style->white);
641 eye_pixmap[SELECTED] =
642 gdk_pixmap_create_from_data (layer_widget->visible->window,
643 (gchar*) eye_bits, eye_width, eye_height, -1,
644 &layer_widget->visible->style->fg[GTK_STATE_SELECTED],
645 &layer_widget->visible->style->bg[GTK_STATE_SELECTED]);
646 eye_pixmap[INSENSITIVE] =
647 gdk_pixmap_create_from_data (layer_widget->visible->window,
648 (gchar*) eye_bits, eye_width, eye_height, -1,
649 &layer_widget->visible->style->fg[GTK_STATE_INSENSITIVE],
650 &layer_widget->visible->style->bg[GTK_STATE_INSENSITIVE]);
653 if (GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET(layer_widget))) {
654 if (state == GTK_STATE_SELECTED)
655 pixmap = eye_pixmap[SELECTED];
656 else
657 pixmap = eye_pixmap[NORMAL];
658 } else {
659 pixmap = eye_pixmap[INSENSITIVE];
662 gdk_draw_pixmap (layer_widget->visible->window,
663 layer_widget->visible->style->black_gc,
664 pixmap, 0, 0, 0, 0, eye_width, eye_height);
665 } else {
666 gdk_window_clear (layer_widget->visible->window);
670 static void
671 dia_layer_widget_exclusive_visible(DiaLayerWidget *layer_widget)
673 GList *list;
674 DiaLayerWidget *lw;
675 Layer *layer;
676 int visible = FALSE;
677 int i;
679 /* First determine if _any_ other layer widgets are set to visible */
680 for (i=0;i<layer_widget->dia->data->layers->len;i++) {
681 layer = g_ptr_array_index(layer_widget->dia->data->layers, i);
682 if (layer_widget->layer != layer) {
683 visible |= layer->visible;
687 /* Now, toggle the visibility for all layers except the specified one */
688 for (i=0;i<layer_widget->dia->data->layers->len;i++) {
689 layer = g_ptr_array_index(layer_widget->dia->data->layers, i);
690 if (layer_widget->layer != layer) {
691 visible |= layer->visible;
695 list = GTK_LIST(layer_dialog->layer_list)->children;
696 while (list) {
697 lw = DIA_LAYER_WIDGET(list->data);
698 if (lw != layer_widget)
699 lw->layer->visible = !visible;
700 else
701 lw->layer->visible = TRUE;
703 dia_layer_widget_visible_redraw (lw);
705 list = g_list_next(list);
709 static gint
710 dia_layer_widget_button_events(GtkWidget *widget,
711 GdkEvent *event,
712 gpointer data)
714 static GtkWidget *click_widget = NULL;
715 static int button_down = 0;
716 static int old_state;
717 static int exclusive;
718 GtkWidget *event_widget;
719 gint return_val;
720 GdkEventButton *bevent;
721 DiaLayerWidget *lw;
723 lw = DIA_LAYER_WIDGET(data);
726 return_val = FALSE;
727 switch (event->type) {
728 case GDK_EXPOSE:
729 if (widget == lw->visible)
730 dia_layer_widget_visible_redraw (lw);
731 break;
733 case GDK_BUTTON_PRESS:
734 return_val = TRUE;
736 bevent = (GdkEventButton *) event;
738 button_down = 1;
739 click_widget = widget;
740 gtk_grab_add (click_widget);
742 if (widget == lw->visible) {
743 old_state = lw->layer->visible;
745 /* If this was a shift-click, make all/none visible */
746 if (event->button.state & GDK_SHIFT_MASK) {
747 exclusive = TRUE;
748 dia_layer_widget_exclusive_visible (lw);
749 } else {
750 exclusive = FALSE;
751 lw->layer->visible = !lw->layer->visible;
752 dia_layer_widget_visible_redraw (lw);
755 break;
757 case GDK_BUTTON_RELEASE:
758 return_val = TRUE;
760 button_down = 0;
761 gtk_grab_remove (click_widget);
763 if (widget == lw->visible) {
764 if ((exclusive) || (old_state != lw->layer->visible)) {
765 diagram_add_update_all(lw->dia);
766 diagram_flush(lw->dia);
769 break;
771 case GDK_ENTER_NOTIFY:
772 case GDK_LEAVE_NOTIFY:
773 event_widget = gtk_get_event_widget (event);
775 if (button_down && (event_widget == click_widget)) {
776 if (widget == lw->visible) {
777 if (exclusive) {
778 dia_layer_widget_exclusive_visible (lw);
779 } else {
780 lw->layer->visible = !lw->layer->visible;
781 dia_layer_widget_visible_redraw (lw);
785 break;
787 default:
788 break;
791 return return_val;
794 static void
795 dia_layer_widget_init(DiaLayerWidget *lw)
797 GtkWidget *hbox;
798 GtkWidget *visible;
799 GtkWidget *label;
800 GtkWidget *alignment;
802 hbox = gtk_hbox_new(FALSE, 0);
804 lw->dia = NULL;
805 lw->layer = NULL;
806 lw->edit_dialog = NULL;
808 alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
809 lw->visible = visible = gtk_drawing_area_new ();
810 gtk_drawing_area_size (GTK_DRAWING_AREA (visible), eye_width, eye_height);
811 gtk_widget_set_events (visible, BUTTON_EVENT_MASK);
812 gtk_signal_connect (GTK_OBJECT (visible), "event",
813 (GtkSignalFunc) dia_layer_widget_button_events,
814 lw);
815 gtk_object_set_user_data (GTK_OBJECT (visible), lw);
816 gtk_widget_show(visible);
817 gtk_container_add (GTK_CONTAINER (alignment), visible);
818 gtk_box_pack_start (GTK_BOX (hbox), alignment, FALSE, TRUE, 2);
819 gtk_widget_show(alignment);
821 lw->label = label = gtk_label_new("layer_default_label");
822 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
823 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
824 gtk_widget_show(label);
826 gtk_widget_show(hbox);
828 gtk_container_add(GTK_CONTAINER(lw), hbox);
830 gtk_signal_connect (GTK_OBJECT (lw), "select",
831 (GtkSignalFunc) dia_layer_select_callback,
832 (gpointer) NULL);
833 gtk_signal_connect (GTK_OBJECT (lw), "deselect",
834 (GtkSignalFunc) dia_layer_deselect_callback,
835 (gpointer) NULL);
838 guint
839 dia_layer_widget_get_type(void)
841 static guint dlw_type = 0;
843 if (!dlw_type) {
844 GtkTypeInfo dlw_info = {
845 "DiaLayerWidget",
846 sizeof (DiaLayerWidget),
847 sizeof (DiaLayerWidgetClass),
848 (GtkClassInitFunc) dia_layer_widget_class_init,
849 (GtkObjectInitFunc) dia_layer_widget_init,
850 (GtkArgSetFunc) NULL,
851 (GtkArgGetFunc) NULL
854 dlw_type = gtk_type_unique (gtk_list_item_get_type (), &dlw_info);
857 return dlw_type;
860 GtkWidget *
861 dia_layer_widget_new(Diagram *dia, Layer *layer)
863 GtkWidget *widget;
865 widget = GTK_WIDGET ( gtk_type_new (dia_layer_widget_get_type ()));
866 dia_layer_set_layer(DIA_LAYER_WIDGET(widget), dia, layer);
868 return widget;
871 void
872 dia_layer_set_layer(DiaLayerWidget *widget, Diagram *dia, Layer *layer)
874 widget->dia = dia;
875 widget->layer = layer;
877 dia_layer_update_from_layer(widget);
880 void
881 dia_layer_update_from_layer(DiaLayerWidget *widget)
883 gtk_label_set_text(GTK_LABEL(widget->label), widget->layer->name);
888 * The edit layer attributes dialog
891 static void
892 edit_layer_ok_callback (GtkWidget *w,
893 gpointer client_data)
895 EditLayerDialog *dialog;
896 Layer *layer;
898 dialog = (EditLayerDialog *) client_data;
899 layer = dialog->layer_widget->layer;
901 g_free (layer->name);
902 layer->name = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->name_entry)));
904 diagram_add_update_all(dialog->layer_widget->dia);
905 diagram_flush(dialog->layer_widget->dia);
907 dia_layer_update_from_layer(dialog->layer_widget);
909 dialog->layer_widget->edit_dialog = NULL;
910 gtk_widget_destroy (dialog->dialog);
911 g_free (dialog);
914 static void
915 edit_layer_cancel_callback (GtkWidget *w,
916 gpointer client_data)
918 EditLayerDialog *dialog;
920 dialog = (EditLayerDialog *) client_data;
922 dialog->layer_widget->edit_dialog = NULL;
923 dialog = (EditLayerDialog *) client_data;
924 gtk_widget_destroy (dialog->dialog);
925 g_free (dialog);
928 static gint
929 edit_layer_delete_callback (GtkWidget *w,
930 GdkEvent *e,
931 gpointer client_data)
933 edit_layer_cancel_callback (w, client_data);
935 return TRUE;
938 static void
939 layer_dialog_edit_layer(DiaLayerWidget *layer_widget)
941 EditLayerDialog *dialog;
942 GtkWidget *vbox;
943 GtkWidget *hbox;
944 GtkWidget *label;
945 GtkWidget *button;
947 /* the new dialog structure */
948 dialog = (EditLayerDialog *) g_malloc (sizeof (EditLayerDialog));
949 dialog->layer_widget = layer_widget;
951 /* the dialog */
952 dialog->dialog = gtk_dialog_new ();
953 gtk_window_set_wmclass (GTK_WINDOW (dialog->dialog), "edit_layer_attrributes", "Dia");
954 gtk_window_set_title (GTK_WINDOW (dialog->dialog), _("Edit Layer Attributes"));
955 gtk_window_set_position (GTK_WINDOW (dialog->dialog), GTK_WIN_POS_MOUSE);
957 /* handle the wm close signal */
958 gtk_signal_connect (GTK_OBJECT (dialog->dialog), "delete_event",
959 GTK_SIGNAL_FUNC (edit_layer_delete_callback),
960 dialog);
962 /* the main vbox */
963 vbox = gtk_vbox_new (FALSE, 1);
964 gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
965 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->dialog)->vbox), vbox, TRUE, TRUE, 0);
967 /* the name entry hbox, label and entry */
968 hbox = gtk_hbox_new (FALSE, 1);
969 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
970 label = gtk_label_new (_("Layer name:"));
971 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
972 gtk_widget_show (label);
973 dialog->name_entry = gtk_entry_new ();
974 gtk_box_pack_start (GTK_BOX (hbox), dialog->name_entry, TRUE, TRUE, 0);
975 gtk_entry_set_text (GTK_ENTRY (dialog->name_entry), layer_widget->layer->name);
976 gtk_widget_show (dialog->name_entry);
977 gtk_widget_show (hbox);
979 button = gtk_button_new_with_label (_("OK"));
980 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
981 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->dialog)->action_area),
982 button, TRUE, TRUE, 0);
983 gtk_signal_connect (GTK_OBJECT (button), "clicked",
984 GTK_SIGNAL_FUNC(edit_layer_ok_callback),
985 dialog);
986 gtk_widget_grab_default (button);
987 gtk_widget_show (button);
989 button = gtk_button_new_with_label (_("Cancel"));
990 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
991 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->dialog)->action_area),
992 button, TRUE, TRUE, 0);
993 gtk_signal_connect (GTK_OBJECT (button), "clicked",
994 GTK_SIGNAL_FUNC(edit_layer_cancel_callback),
995 dialog);
996 gtk_widget_show (button);
998 gtk_widget_show (vbox);
999 gtk_widget_show (dialog->dialog);
1001 layer_widget->edit_dialog = dialog;
1005 /******** layer changes: */
1007 struct LayerChange {
1008 Change change;
1010 enum LayerChangeType type;
1011 Layer *layer;
1012 int index;
1013 int applied;
1016 static void
1017 layer_change_apply(struct LayerChange *change, Diagram *dia)
1019 change->applied = 1;
1021 switch (change->type) {
1022 case TYPE_DELETE_LAYER:
1023 data_delete_layer(dia->data, change->layer);
1024 break;
1025 case TYPE_ADD_LAYER:
1026 data_add_layer_at(dia->data, change->layer, change->index);
1027 break;
1028 case TYPE_RAISE_LAYER:
1029 data_raise_layer(dia->data, change->layer);
1030 break;
1031 case TYPE_LOWER_LAYER:
1032 data_lower_layer(dia->data, change->layer);
1033 break;
1036 diagram_add_update_all(dia);
1038 if (layer_dialog->diagram == dia) {
1039 layer_dialog_set_diagram(dia);
1043 static void
1044 layer_change_revert(struct LayerChange *change, Diagram *dia)
1046 switch (change->type) {
1047 case TYPE_DELETE_LAYER:
1048 data_add_layer_at(dia->data, change->layer, change->index);
1049 break;
1050 case TYPE_ADD_LAYER:
1051 data_delete_layer(dia->data, change->layer);
1052 break;
1053 case TYPE_RAISE_LAYER:
1054 data_lower_layer(dia->data, change->layer);
1055 break;
1056 case TYPE_LOWER_LAYER:
1057 data_raise_layer(dia->data, change->layer);
1058 break;
1061 diagram_add_update_all(dia);
1063 if (layer_dialog->diagram == dia) {
1064 layer_dialog_set_diagram(dia);
1067 change->applied = 0;
1070 static void
1071 layer_change_free(struct LayerChange *change)
1073 switch (change->type) {
1074 case TYPE_DELETE_LAYER:
1075 if (change->applied) {
1076 layer_destroy(change->layer);
1078 break;
1079 case TYPE_ADD_LAYER:
1080 if (!change->applied) {
1081 layer_destroy(change->layer);
1083 break;
1084 case TYPE_RAISE_LAYER:
1085 break;
1086 case TYPE_LOWER_LAYER:
1087 break;
1091 static Change *
1092 undo_layer(Diagram *dia, Layer *layer, enum LayerChangeType type, int index)
1094 struct LayerChange *change;
1096 change = g_new(struct LayerChange, 1);
1098 change->change.apply = (UndoApplyFunc) layer_change_apply;
1099 change->change.revert = (UndoRevertFunc) layer_change_revert;
1100 change->change.free = (UndoFreeFunc) layer_change_free;
1102 change->type = type;
1103 change->layer = layer;
1104 change->index = index;
1105 change->applied = 1;
1107 undo_push_change(dia->undo, (Change *) change);
1108 return (Change *)change;