* lib/text.h: Added text_get_line() declaration
[dia.git] / lib / dialinechooser.c
blob3336d34df4df50baa888a430346df17be8949ba2
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.
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
26 #include "intl.h"
27 #include "widgets.h"
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);
43 GType
44 dia_line_preview_get_type (void)
46 static GType type = 0;
48 if (!type) {
49 static const GTypeInfo info = {
50 sizeof (DiaLinePreviewClass),
51 (GBaseInitFunc) NULL,
52 (GBaseFinalizeFunc) NULL,
53 (GClassInitFunc) dia_line_preview_class_init,
54 (GClassFinalizeFunc) NULL,
55 NULL,
56 sizeof (DiaLinePreview),
58 (GInstanceInitFunc) dia_line_preview_init
61 type = g_type_register_static (GTK_TYPE_MISC, "DiaLinePreview", &info, 0);
64 return type;
67 static void
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;
76 static void
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;
87 GtkWidget *
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);
96 static void
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));
106 static gint
107 dia_line_preview_expose(GtkWidget *widget, GdkEventExpose *event)
109 DiaLinePreview *line = DIA_LINE_PREVIEW(widget);
110 GtkMisc *misc = GTK_MISC(widget);
111 gint width, height;
112 gint x, y;
113 gint extent;
114 GdkWindow *win;
115 GdkGC *gc;
116 GdkGCValues gcvalues;
117 gint8 dash_list[6];
118 int line_width = 2;
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);
136 break;
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);
140 dash_list[0] = 10;
141 dash_list[1] = 10;
142 gdk_gc_set_dashes(gc, 0, dash_list, 2);
143 break;
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);
147 dash_list[0] = 10;
148 dash_list[1] = 4;
149 dash_list[2] = 2;
150 dash_list[3] = 4;
151 gdk_gc_set_dashes(gc, 0, dash_list, 4);
152 break;
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);
156 dash_list[0] = 10;
157 dash_list[1] = 2;
158 dash_list[2] = 2;
159 dash_list[3] = 2;
160 dash_list[4] = 2;
161 dash_list[5] = 2;
162 gdk_gc_set_dashes(gc, 0, dash_list, 6);
163 break;
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);
167 dash_list[0] = 2;
168 dash_list[1] = 2;
169 gdk_gc_set_dashes(gc, 0, dash_list, 2);
170 break;
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);
176 return TRUE;
180 /* ------- Code for DiaLineChooser ---------------------- */
182 static void dia_line_chooser_class_init (DiaLineChooserClass *klass);
183 static void dia_line_chooser_init (DiaLineChooser *arrow);
185 GType
186 dia_line_chooser_get_type (void)
188 static GType type = 0;
190 if (!type) {
191 static const GTypeInfo info = {
192 sizeof (DiaLineChooserClass),
193 (GBaseInitFunc) NULL,
194 (GBaseFinalizeFunc) NULL,
195 (GClassInitFunc) dia_line_chooser_class_init,
196 (GClassFinalizeFunc) NULL,
197 NULL,
198 sizeof (DiaLineChooser),
200 (GInstanceInitFunc) dia_line_chooser_init
203 type = g_type_register_static (GTK_TYPE_BUTTON, "DiaLineChooser", &info, 0);
206 return type;
209 static gint
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);
216 return TRUE;
218 return FALSE;
221 static void
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;
230 static void
231 dia_line_chooser_dialog_response (GtkWidget *dialog,
232 gint response_id,
233 DiaLineChooser *lchooser)
235 LineStyle new_style;
236 real new_dash;
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);
248 } else {
249 dia_line_style_selector_set_linestyle(lchooser->selector,
250 lchooser->lstyle,
251 lchooser->dash_length);
253 gtk_widget_hide(lchooser->dialog);
256 static void
257 dia_line_chooser_change_line_style(GtkMenuItem *mi, DiaLineChooser *lchooser)
259 LineStyle lstyle = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(mi),
260 menuitem_enum_key));
262 dia_line_chooser_set_line_style(lchooser, lstyle, lchooser->dash_length);
265 void
266 dia_line_chooser_set_line_style(DiaLineChooser *lchooser,
267 LineStyle lstyle,
268 real dashlength)
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);
282 static void
283 dia_line_chooser_init (DiaLineChooser *lchooser)
285 GtkWidget *wid;
286 GtkWidget *menu, *mi, *ln;
287 gint i;
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"),
298 NULL,
299 GTK_DIALOG_NO_SEPARATOR,
300 GTK_STOCK_CANCEL,
301 GTK_RESPONSE_CANCEL,
302 GTK_STOCK_OK,
303 GTK_RESPONSE_OK,
304 NULL);
305 gtk_dialog_set_default_response(GTK_DIALOG(lchooser->dialog),
306 GTK_RESPONSE_OK);
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,
313 TRUE, TRUE, 0);
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);
327 gtk_widget_show(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);
340 GtkWidget *
341 dia_line_chooser_new(DiaChangeLineCallback callback,
342 gpointer user_data)
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);