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.
23 #include "linewidth_area.h"
24 #include "attributes.h"
25 #include "persistence.h"
26 #include "interface.h"
31 # define rint(x) floor ((x) + 0.5)
34 #define BASE_WIDTH 0.05
35 #define PIXELS_BETWEEN_LINES 6
38 #define X_OFFSET(i) (PIXELS_BETWEEN_LINES*(i)+((i)-1)*(i)/2)
40 #define AREA_WIDTH X_OFFSET(NUMLINES+1)
41 #define AREA_HEIGHT 42
43 static void linewidth_create_dialog(void);
45 static int active_linewidth
= 2;
46 static GdkGC
*linewidth_area_gc
= NULL
;
47 static GdkPixmap
*linewidth_area_pixmap
= NULL
;
49 static GtkWidget
*linewidth_area_widget
= NULL
;
50 static GtkWidget
*linewidth_dialog
= NULL
;
51 static GtkWidget
*linewidth_button
= NULL
;
54 linewidth_area_target (int x
, int y
)
58 for (i
=1;i
<=NUMLINES
;i
++) {
60 if ((x
>=x_offs
-PIXELS_BETWEEN_LINES
/2) &&
61 (x
<x_offs
+i
+PIXELS_BETWEEN_LINES
/2))
68 linewidth_area_draw (GtkWidget
*linewidth_area
)
76 if (!linewidth_area_pixmap
) /* we haven't gotten initial expose yet,
77 * no point in drawing anything */
81 if (!linewidth_area_gc
) {
82 linewidth_area_gc
= gdk_gc_new (linewidth_area_pixmap
);
83 gdk_gc_set_line_attributes(linewidth_area_gc
, 1,
89 gdk_window_get_size (linewidth_area_pixmap
, &width
, &height
);
91 win_bg
= &(linewidth_area
->style
->bg
[GTK_STATE_NORMAL
]);
92 line
= color_gdk_black
;
94 gdk_gc_set_foreground (linewidth_area_gc
, win_bg
);
95 gdk_draw_rectangle (linewidth_area_pixmap
, linewidth_area_gc
, 1,
98 gdk_gc_set_foreground (linewidth_area_gc
, &line
);
100 for (i
=0;i
<=NUMLINES
;i
++) {
101 x_offs
= X_OFFSET(i
);
103 gdk_draw_rectangle (linewidth_area_pixmap
, linewidth_area_gc
, 1,
104 x_offs
, 2, i
, height
-4);
108 if (active_linewidth
!= 0) {
109 gdk_draw_rectangle (linewidth_area_pixmap
, linewidth_area_gc
, 0,
110 X_OFFSET(active_linewidth
)-2, 0,
111 active_linewidth
+4, height
-1);
114 gdk_draw_pixmap (linewidth_area
->window
, linewidth_area_gc
, linewidth_area_pixmap
,
115 0, 0, 0, 0, width
, height
);
119 linewidth_area_events (GtkWidget
*widget
,
122 GdkEventButton
*bevent
;
123 GdkEventConfigure
*cevent
;
129 cevent
= (GdkEventConfigure
*) event
;
130 if (cevent
->width
> 1) {
131 linewidth_area_pixmap
= gdk_pixmap_new (widget
->window
,
137 linewidth_area_draw (linewidth_area_widget
);
140 case GDK_BUTTON_PRESS
:
141 bevent
= (GdkEventButton
*) event
;
142 if (bevent
->button
== 1) {
143 target
= linewidth_area_target (bevent
->x
, bevent
->y
);
146 active_linewidth
= target
;
147 linewidth_area_draw(linewidth_area_widget
);
148 attributes_set_default_linewidth(BASE_WIDTH
*(target
-1));
153 case GDK_2BUTTON_PRESS
:
154 if (linewidth_dialog
== NULL
)
155 linewidth_create_dialog();
157 gtk_widget_grab_focus(linewidth_button
);
158 gtk_spin_button_set_value(GTK_SPIN_BUTTON(linewidth_button
), attributes_get_default_linewidth());
160 gtk_widget_show(linewidth_dialog
);
172 linewidth_number_from_width(real width
)
174 if (fabs(width
/BASE_WIDTH
-rint(width
/BASE_WIDTH
)) > 0.0005 ||
175 (width
/BASE_WIDTH
> NUMLINES
)) {
178 return width
/BASE_WIDTH
+1.0005;
183 linewidth_area_create (void)
185 GtkWidget
*linewidth_area
;
186 GtkWidget
*event_box
;
188 attributes_set_default_linewidth(persistence_register_real("linewidth", 0.1));
189 active_linewidth
= linewidth_number_from_width(attributes_get_default_linewidth());
191 event_box
= gtk_event_box_new();
192 linewidth_area
= gtk_drawing_area_new ();
193 gtk_drawing_area_size (GTK_DRAWING_AREA (linewidth_area
),
194 AREA_WIDTH
, AREA_HEIGHT
);
195 gtk_widget_set_events (linewidth_area
, GDK_EXPOSURE_MASK
| GDK_BUTTON_PRESS_MASK
);
196 g_signal_connect (GTK_OBJECT (linewidth_area
), "event",
197 G_CALLBACK(linewidth_area_events
),
200 linewidth_area_widget
= linewidth_area
;
202 gtk_container_add(GTK_CONTAINER(event_box
), linewidth_area
);
203 gtk_widget_show(linewidth_area
);
208 get_current_line_width() {
209 float newvalue
= gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(linewidth_button
));
210 active_linewidth
= linewidth_number_from_width(newvalue
);
211 linewidth_area_draw(GTK_WIDGET(linewidth_area_widget
));
212 attributes_set_default_linewidth(newvalue
);
216 linewidth_dialog_respond(GtkWidget
*widget
, gint response_id
, gpointer data
)
218 if (response_id
== GTK_RESPONSE_OK
) {
219 get_current_line_width();
221 gtk_widget_hide(linewidth_dialog
);
225 linewidth_dialog_ok(GtkWidget
*widget
, gpointer data
)
227 gtk_dialog_response(GTK_DIALOG(linewidth_dialog
), GTK_RESPONSE_OK
);
230 /* Crashes with gtk_widget_destroyed, so use this instead */
232 dialog_destroyed(GtkWidget
*widget
, gpointer data
)
234 GtkWidget
**wid
= (GtkWidget
**)data
;
235 if (wid
) *wid
= NULL
;
239 linewidth_create_dialog()
245 linewidth_dialog
= gtk_dialog_new_with_buttons(
246 _("Line width"), GTK_WINDOW(interface_get_toolbox_shell()),
248 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
249 GTK_STOCK_OK
, GTK_RESPONSE_OK
,
252 gtk_dialog_set_default_response (GTK_DIALOG(linewidth_dialog
), GTK_RESPONSE_OK
);
253 gtk_window_set_role (GTK_WINDOW (linewidth_dialog
), "linewidth_window");
254 gtk_window_set_resizable (GTK_WINDOW (linewidth_dialog
), TRUE
);
255 gtk_container_set_border_width (GTK_CONTAINER (linewidth_dialog
), 2);
257 hbox
= gtk_hbox_new(FALSE
, 5);
258 label
= gtk_label_new(_("Line width:"));
259 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, TRUE
, 0);
260 gtk_widget_show (label
);
261 adj
= (GtkAdjustment
*) gtk_adjustment_new(0.1, 0.00, 10.0, 0.01, 0.05, 0.0);
262 linewidth_button
= gtk_spin_button_new(adj
, attributes_get_default_linewidth(), 2);
263 gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(linewidth_button
), TRUE
);
264 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(linewidth_button
), TRUE
);
265 gtk_box_pack_start(GTK_BOX (hbox
), linewidth_button
, TRUE
, TRUE
, 0);
266 gtk_widget_show (linewidth_button
);
267 gtk_widget_show(hbox
);
268 gtk_box_pack_start (GTK_BOX(GTK_DIALOG (linewidth_dialog
)->vbox
), hbox
, TRUE
, TRUE
, 0);
270 gtk_widget_show (linewidth_button
);
272 g_signal_connect(G_OBJECT (linewidth_dialog
), "response",
273 G_CALLBACK (linewidth_dialog_respond
), NULL
);
274 g_signal_connect_after(G_OBJECT (linewidth_button
), "activate",
275 G_CALLBACK (linewidth_dialog_ok
), NULL
);
277 g_signal_connect (GTK_OBJECT (linewidth_dialog
), "delete_event",
278 G_CALLBACK(gtk_widget_hide
), NULL
);
279 g_signal_connect (GTK_OBJECT (linewidth_dialog
), "destroy",
280 G_CALLBACK(dialog_destroyed
), &linewidth_dialog
);
282 persistence_register_window (GTK_WINDOW (linewidth_dialog
));