1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * dialinechooser.c -- Copyright (C) 1999 James Henstridge.
5 * Copyright (C) 2004 Hubert Figuiere
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #include "dialinechooser.h"
30 static const char *button_menu_key
= "dia-button-menu";
31 static const char *menuitem_enum_key
= "dia-menuitem-value";
34 /* --------------- DiaLinePreview -------------------------------- */
36 static void dia_line_preview_set(DiaLinePreview
*line
, LineStyle lstyle
);
38 static void dia_line_preview_class_init (DiaLinePreviewClass
*klass
);
39 static void dia_line_preview_init (DiaLinePreview
*arrow
);
40 static gint
dia_line_preview_expose (GtkWidget
*widget
,
41 GdkEventExpose
*event
);
44 dia_line_preview_get_type (void)
46 static GType type
= 0;
49 static const GTypeInfo info
= {
50 sizeof (DiaLinePreviewClass
),
52 (GBaseFinalizeFunc
) NULL
,
53 (GClassInitFunc
) dia_line_preview_class_init
,
54 (GClassFinalizeFunc
) NULL
,
56 sizeof (DiaLinePreview
),
58 (GInstanceInitFunc
) dia_line_preview_init
61 type
= g_type_register_static (GTK_TYPE_MISC
, "DiaLinePreview", &info
, 0);
68 dia_line_preview_class_init (DiaLinePreviewClass
*class)
70 GtkWidgetClass
*widget_class
;
72 widget_class
= GTK_WIDGET_CLASS(class);
73 widget_class
->expose_event
= dia_line_preview_expose
;
77 dia_line_preview_init (DiaLinePreview
*line
)
79 GTK_WIDGET_SET_FLAGS (line
, GTK_NO_WINDOW
);
81 GTK_WIDGET (line
)->requisition
.width
= 30 + GTK_MISC (line
)->xpad
* 2;
82 GTK_WIDGET (line
)->requisition
.height
= 15 + GTK_MISC (line
)->ypad
* 2;
84 line
->lstyle
= LINESTYLE_SOLID
;
88 dia_line_preview_new (LineStyle lstyle
)
90 DiaLinePreview
*line
= g_object_new(DIA_TYPE_LINE_PREVIEW
, NULL
);
92 line
->lstyle
= lstyle
;
93 return GTK_WIDGET(line
);
97 dia_line_preview_set(DiaLinePreview
*line
, LineStyle lstyle
)
99 if (line
->lstyle
!= lstyle
) {
100 line
->lstyle
= lstyle
;
101 if (GTK_WIDGET_DRAWABLE(line
))
102 gtk_widget_queue_draw(GTK_WIDGET(line
));
107 dia_line_preview_expose(GtkWidget
*widget
, GdkEventExpose
*event
)
109 DiaLinePreview
*line
= DIA_LINE_PREVIEW(widget
);
110 GtkMisc
*misc
= GTK_MISC(widget
);
116 GdkGCValues gcvalues
;
120 if (GTK_WIDGET_DRAWABLE(widget
)) {
121 width
= widget
->allocation
.width
- misc
->xpad
* 2;
122 height
= widget
->allocation
.height
- misc
->ypad
* 2;
123 extent
= MIN(width
, height
);
124 x
= (widget
->allocation
.x
+ misc
->xpad
);
125 y
= (widget
->allocation
.y
+ misc
->ypad
);
127 win
= widget
->window
;
128 gc
= widget
->style
->fg_gc
[widget
->state
];
130 /* increase line width */
131 gdk_gc_get_values(gc
, &gcvalues
);
132 switch (line
->lstyle
) {
133 case LINESTYLE_SOLID
:
134 gdk_gc_set_line_attributes(gc
, line_width
, GDK_LINE_SOLID
,
135 gcvalues
.cap_style
, gcvalues
.join_style
);
137 case LINESTYLE_DASHED
:
138 gdk_gc_set_line_attributes(gc
, line_width
, GDK_LINE_ON_OFF_DASH
,
139 gcvalues
.cap_style
, gcvalues
.join_style
);
142 gdk_gc_set_dashes(gc
, 0, dash_list
, 2);
144 case LINESTYLE_DASH_DOT
:
145 gdk_gc_set_line_attributes(gc
, line_width
, GDK_LINE_ON_OFF_DASH
,
146 gcvalues
.cap_style
, gcvalues
.join_style
);
151 gdk_gc_set_dashes(gc
, 0, dash_list
, 4);
153 case LINESTYLE_DASH_DOT_DOT
:
154 gdk_gc_set_line_attributes(gc
, line_width
, GDK_LINE_ON_OFF_DASH
,
155 gcvalues
.cap_style
, gcvalues
.join_style
);
162 gdk_gc_set_dashes(gc
, 0, dash_list
, 6);
164 case LINESTYLE_DOTTED
:
165 gdk_gc_set_line_attributes(gc
, line_width
, GDK_LINE_ON_OFF_DASH
,
166 gcvalues
.cap_style
, gcvalues
.join_style
);
169 gdk_gc_set_dashes(gc
, 0, dash_list
, 2);
172 gdk_draw_line(win
, gc
, x
, y
+height
/2, x
+width
, y
+height
/2);
173 gdk_gc_set_line_attributes(gc
, gcvalues
.line_width
, gcvalues
.line_style
,
174 gcvalues
.cap_style
, gcvalues
.join_style
);
180 /* ------- Code for DiaLineChooser ---------------------- */
182 static void dia_line_chooser_class_init (DiaLineChooserClass
*klass
);
183 static void dia_line_chooser_init (DiaLineChooser
*arrow
);
186 dia_line_chooser_get_type (void)
188 static GType type
= 0;
191 static const GTypeInfo info
= {
192 sizeof (DiaLineChooserClass
),
193 (GBaseInitFunc
) NULL
,
194 (GBaseFinalizeFunc
) NULL
,
195 (GClassInitFunc
) dia_line_chooser_class_init
,
196 (GClassFinalizeFunc
) NULL
,
198 sizeof (DiaLineChooser
),
200 (GInstanceInitFunc
) dia_line_chooser_init
203 type
= g_type_register_static (GTK_TYPE_BUTTON
, "DiaLineChooser", &info
, 0);
210 dia_line_chooser_event(GtkWidget
*widget
, GdkEvent
*event
)
212 if (event
->type
== GDK_BUTTON_PRESS
&& event
->button
.button
== 1) {
213 GtkMenu
*menu
= g_object_get_data(G_OBJECT(widget
), button_menu_key
);
214 gtk_menu_popup(menu
, NULL
, NULL
, NULL
, NULL
,
215 event
->button
.button
, event
->button
.time
);
222 dia_line_chooser_class_init (DiaLineChooserClass
*class)
224 GtkWidgetClass
*widget_class
;
226 widget_class
= GTK_WIDGET_CLASS(class);
227 widget_class
->event
= dia_line_chooser_event
;
231 dia_line_chooser_dialog_response (GtkWidget
*dialog
,
233 DiaLineChooser
*lchooser
)
238 if (response_id
== GTK_RESPONSE_OK
) {
239 dia_line_style_selector_get_linestyle(lchooser
->selector
,
240 &new_style
, &new_dash
);
241 if (new_style
!= lchooser
->lstyle
|| new_dash
!= lchooser
->dash_length
) {
242 lchooser
->lstyle
= new_style
;
243 lchooser
->dash_length
= new_dash
;
244 dia_line_preview_set(lchooser
->preview
, new_style
);
245 if (lchooser
->callback
)
246 (* lchooser
->callback
)(new_style
, new_dash
, lchooser
->user_data
);
249 dia_line_style_selector_set_linestyle(lchooser
->selector
,
251 lchooser
->dash_length
);
253 gtk_widget_hide(lchooser
->dialog
);
257 dia_line_chooser_change_line_style(GtkMenuItem
*mi
, DiaLineChooser
*lchooser
)
259 LineStyle lstyle
= GPOINTER_TO_INT(g_object_get_data(G_OBJECT(mi
),
262 dia_line_chooser_set_line_style(lchooser
, lstyle
, lchooser
->dash_length
);
266 dia_line_chooser_set_line_style(DiaLineChooser
*lchooser
,
270 if (lstyle
!= lchooser
->lstyle
) {
271 dia_line_preview_set(lchooser
->preview
, lstyle
);
272 lchooser
->lstyle
= lstyle
;
273 dia_line_style_selector_set_linestyle(lchooser
->selector
, lchooser
->lstyle
,
274 lchooser
->dash_length
);
276 lchooser
->dash_length
= dashlength
;
277 if (lchooser
->callback
)
278 (* lchooser
->callback
)(lchooser
->lstyle
, lchooser
->dash_length
,
279 lchooser
->user_data
);
283 dia_line_chooser_init (DiaLineChooser
*lchooser
)
286 GtkWidget
*menu
, *mi
, *ln
;
289 lchooser
->lstyle
= LINESTYLE_SOLID
;
290 lchooser
->dash_length
= DEFAULT_LINESTYLE_DASHLEN
;
292 wid
= dia_line_preview_new(LINESTYLE_SOLID
);
293 gtk_container_add(GTK_CONTAINER(lchooser
), wid
);
294 gtk_widget_show(wid
);
295 lchooser
->preview
= DIA_LINE_PREVIEW(wid
);
297 lchooser
->dialog
= gtk_dialog_new_with_buttons(_("Line Style Properties"),
299 GTK_DIALOG_NO_SEPARATOR
,
305 gtk_dialog_set_default_response(GTK_DIALOG(lchooser
->dialog
),
307 g_signal_connect(G_OBJECT(lchooser
->dialog
), "response",
308 G_CALLBACK(dia_line_chooser_dialog_response
), lchooser
);
310 wid
= dia_line_style_selector_new();
311 gtk_container_set_border_width(GTK_CONTAINER(wid
), 5);
312 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lchooser
->dialog
)->vbox
), wid
,
314 gtk_widget_show(wid
);
315 lchooser
->selector
= DIALINESTYLESELECTOR(wid
);
317 menu
= gtk_menu_new();
318 g_object_ref(G_OBJECT(menu
));
319 gtk_object_sink(GTK_OBJECT(menu
));
320 g_object_set_data_full(G_OBJECT(lchooser
), button_menu_key
, menu
,
321 (GDestroyNotify
)gtk_widget_unref
);
322 for (i
= 0; i
<= LINESTYLE_DOTTED
; i
++) {
323 mi
= gtk_menu_item_new();
324 g_object_set_data(G_OBJECT(mi
), menuitem_enum_key
, GINT_TO_POINTER(i
));
325 ln
= dia_line_preview_new(i
);
326 gtk_container_add(GTK_CONTAINER(mi
), ln
);
328 g_signal_connect(G_OBJECT(mi
), "activate",
329 G_CALLBACK(dia_line_chooser_change_line_style
), lchooser
);
330 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), mi
);
331 gtk_widget_show (mi
);
333 mi
= gtk_menu_item_new_with_label(_("Details..."));
334 g_signal_connect_swapped(G_OBJECT(mi
), "activate",
335 G_CALLBACK(gtk_widget_show
), lchooser
->dialog
);
336 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), mi
);
337 gtk_widget_show (mi
);
341 dia_line_chooser_new(DiaChangeLineCallback callback
,
344 DiaLineChooser
*chooser
= g_object_new(DIA_TYPE_LINE_CHOOSER
, NULL
);
346 chooser
->callback
= callback
;
347 chooser
->user_data
= user_data
;
349 return GTK_WIDGET(chooser
);