linewidth is now working for PS_SOLID
[dia.git] / app / color_area.c
blob9904b74f4b9017300e8c383c545010f1a149ef67
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 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
23 #include <stdio.h>
25 #include "../lib/color.h"
26 #include "intl.h"
28 #include "color_area.h"
29 #include "attributes.h"
30 #include "persistence.h"
32 #define FORE_AREA 0
33 #define BACK_AREA 1
34 #define SWAP_AREA 2
35 #define DEF_AREA 3
37 #define FOREGROUND 0
38 #define BACKGROUND 1
40 /* Global variables */
41 int active_color = 0;
43 /* Static variables */
44 GtkWidget *color_area;
45 static GdkGC *color_area_gc = NULL;
46 static GdkGC *mask_gc = NULL;
47 static GdkPixmap *color_area_pixmap = NULL;
48 static GdkBitmap *color_area_mask = NULL;
49 static GdkPixmap *default_pixmap = NULL;
50 static GdkBitmap *default_mask = NULL;
51 static GdkPixmap *swap_pixmap = NULL;
52 static GdkBitmap *swap_mask = NULL;
54 static GtkWidget *color_select = NULL;
55 static int color_select_active = 0;
56 static int edit_color;
57 static Color stored_foreground;
58 static Color stored_background;
61 static void
62 color_selection_ok (GtkWidget *w,
63 GtkColorSelectionDialog *cs);
64 static void
65 color_selection_cancel (GtkWidget *w,
66 GtkColorSelectionDialog *cs);
67 static void
68 color_selection_cancel (GtkWidget *w,
69 GtkColorSelectionDialog *cs);
70 static gint
71 color_selection_delete (GtkWidget *w,
72 GdkEvent *event,
73 GtkColorSelectionDialog *cs);
74 static gint
75 color_selection_destroy (GtkWidget *w,
76 GtkColorSelectionDialog *cs);
77 static void
78 color_selection_changed (GtkWidget *w,
79 GtkColorSelectionDialog *cs);
81 /* Local functions */
82 static int
83 color_area_target (int x,
84 int y)
86 gint rect_w, rect_h;
87 gint width, height;
89 gdk_drawable_get_size (color_area_pixmap, &width, &height);
91 rect_w = width * 0.65;
92 rect_h = height * 0.65;
94 /* foreground active */
95 if (x > 0 && x < rect_w &&
96 y > 0 && y < rect_h)
97 return FORE_AREA;
98 else if (x > (width - rect_w) && x < width &&
99 y > (height - rect_h) && y < height)
100 return BACK_AREA;
101 else if (x > 0 && x < (width - rect_w) &&
102 y > rect_h && y < height)
103 return DEF_AREA;
104 else if (x > rect_w && x < width &&
105 y > 0 && y < (height - rect_h))
106 return SWAP_AREA;
107 else
108 return -1;
111 static void
112 color_area_draw ()
114 Color col;
115 GdkColor *win_bg;
116 GdkColor fg, bg, bd;
117 gint rect_w, rect_h;
118 gint width, height;
119 gint def_width, def_height;
120 gint swap_width, swap_height;
121 GdkColor mask_pattern;
123 /* Check we haven't gotten initial expose yet,
124 * no point in drawing anything
126 if (!color_area_pixmap || !color_area_gc)
127 return;
129 gdk_drawable_get_size (color_area_pixmap, &width, &height);
131 win_bg = &(color_area->style->bg[GTK_STATE_NORMAL]);
132 col = attributes_get_foreground();
133 color_convert(&col, &fg);
134 col = attributes_get_background();
135 color_convert(&col, &bg);
136 bd = color_gdk_black;
138 rect_w = width * 0.65;
139 rect_h = height * 0.65;
141 /* initialize the mask to transparent */
142 mask_pattern.pixel = 0;
143 gdk_gc_set_foreground (mask_gc, &mask_pattern);
144 gdk_draw_rectangle (color_area_mask, mask_gc, TRUE, 0, 0, -1, -1);
146 /* set the mask's gc to opaque */
147 mask_pattern.pixel = 1;
148 gdk_gc_set_foreground (mask_gc, &mask_pattern);
150 gdk_gc_set_foreground (color_area_gc, win_bg);
151 gdk_draw_rectangle (color_area_pixmap, color_area_gc, 1,
152 0, 0, width, height);
154 gdk_gc_set_foreground (color_area_gc, &bg);
155 gdk_draw_rectangle (color_area_pixmap, color_area_gc, 1,
156 (width - rect_w), (height - rect_h), rect_w, rect_h);
157 gdk_draw_rectangle (color_area_mask, mask_gc, TRUE,
158 (width - rect_w), (height - rect_h), rect_w, rect_h);
160 if (active_color == FOREGROUND)
161 gtk_paint_shadow (color_area->style, color_area_pixmap, GTK_STATE_NORMAL,
162 GTK_SHADOW_OUT,
163 NULL, color_area, NULL,
164 (width - rect_w), (height - rect_h),
165 rect_w, rect_h);
166 else
167 gtk_paint_shadow (color_area->style, color_area_pixmap, GTK_STATE_NORMAL,
168 GTK_SHADOW_IN,
169 NULL, color_area, NULL,
170 (width - rect_w), (height - rect_h),
171 rect_w, rect_h);
173 gdk_gc_set_foreground (color_area_gc, &fg);
174 gdk_draw_rectangle (color_area_pixmap, color_area_gc, 1,
175 0, 0, rect_w, rect_h);
176 gdk_draw_rectangle (color_area_mask, mask_gc, TRUE,
177 0, 0, rect_w, rect_h);
179 if (active_color == FOREGROUND)
180 gtk_paint_shadow (color_area->style, color_area_pixmap, GTK_STATE_NORMAL,
181 GTK_SHADOW_IN,
182 NULL, color_area, NULL,
183 0, 0,
184 rect_w, rect_h);
185 else
186 gtk_paint_shadow (color_area->style, color_area_pixmap, GTK_STATE_NORMAL,
187 GTK_SHADOW_OUT,
188 NULL, color_area, NULL,
189 0, 0,
190 rect_w, rect_h);
192 /* draw the default pixmap */
193 gdk_drawable_get_size (default_pixmap, &def_width, &def_height);
194 gdk_draw_drawable (color_area_pixmap, color_area_gc, default_pixmap,
195 0, 0, 0, height - def_height, def_width, def_height);
196 gdk_draw_drawable (color_area_mask, mask_gc, default_mask,
197 0, 0, 0, height - def_height, def_width, def_height);
199 /* draw the swap pixmap */
200 gdk_drawable_get_size (swap_pixmap, &swap_width, &swap_height);
201 gdk_draw_drawable (color_area_pixmap, color_area_gc, swap_pixmap,
202 0, 0, width - swap_width, 0, swap_width, swap_height);
203 gdk_draw_drawable (color_area_mask, mask_gc, swap_mask,
204 0, 0, width - swap_width, 0, swap_width, swap_height);
206 /* draw the widget */
207 gdk_gc_set_clip_mask (color_area_gc, color_area_mask);
208 gdk_gc_set_clip_origin (color_area_gc, 0, 0);
209 gdk_draw_drawable (color_area->window, color_area_gc, color_area_pixmap,
210 0, 0, 0, 0, width, height);
212 /* reset the clip mask */
213 gdk_gc_set_clip_mask (color_area_gc, NULL);
216 static void
217 color_selection_ok (GtkWidget *w,
218 GtkColorSelectionDialog *cs)
220 GtkColorSelection *colorsel;
221 GdkColor color;
222 Color col;
224 colorsel=GTK_COLOR_SELECTION(cs->colorsel);
226 gtk_color_selection_get_current_color(colorsel,&color);
227 GDK_COLOR_TO_DIA(color, col);
229 if (edit_color == FOREGROUND) {
230 attributes_set_foreground(&col);
231 } else {
232 attributes_set_background(&col);
234 color_area_draw ();
236 /* gtk_color_selection_set_currentcolor(colorsel,&color);*/
238 gtk_widget_hide(color_select);
239 color_select_active = 0;
242 static void
243 color_selection_cancel (GtkWidget *w,
244 GtkColorSelectionDialog *cs)
246 if (color_select != NULL)
247 gtk_widget_hide(color_select);
248 color_select_active = 0;
249 attributes_set_foreground(&stored_foreground);
250 attributes_set_background(&stored_background);
252 color_area_draw ();
255 static gint
256 color_selection_delete (GtkWidget *w,
257 GdkEvent *event,
258 GtkColorSelectionDialog *cs)
260 color_selection_cancel(w,cs);
261 return TRUE;
264 static gint
265 color_selection_destroy (GtkWidget *w,
266 GtkColorSelectionDialog *cs)
268 color_select = NULL;
269 color_selection_cancel(w,cs);
270 return TRUE;
273 static void
274 color_selection_changed (GtkWidget *w,
275 GtkColorSelectionDialog *cs)
277 GtkColorSelection *colorsel;
278 GdkColor color;
279 Color col;
281 colorsel=GTK_COLOR_SELECTION(cs->colorsel);
283 gtk_color_selection_get_current_color(colorsel,&color);
284 GDK_COLOR_TO_DIA(color, col);
286 if (edit_color == FOREGROUND) {
287 attributes_set_foreground(&col);
288 } else {
289 attributes_set_background(&col);
291 color_area_draw ();
294 static void
295 color_area_edit (void)
297 Color col;
298 GtkWidget *window;
299 GdkColor color;
301 if (!color_select_active) {
302 stored_foreground = attributes_get_foreground();
303 stored_background = attributes_get_background();
306 if (active_color == FOREGROUND) {
307 col = attributes_get_foreground();
308 edit_color = FOREGROUND;
309 } else {
310 col = attributes_get_background();
311 edit_color = BACKGROUND;
314 if (! color_select) {
315 window = color_select =
316 gtk_color_selection_dialog_new(edit_color==FOREGROUND?
317 _("Select foreground color"):
318 _("Select background color"));
319 color_select_active = 1;
321 gtk_color_selection_set_has_palette (
322 GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
323 TRUE);
325 gtk_color_selection_set_update_policy(
326 GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
327 GTK_UPDATE_CONTINUOUS);
329 gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
331 g_signal_connect (G_OBJECT (window), "delete_event",
332 G_CALLBACK(color_selection_delete),
333 window);
335 g_signal_connect (GTK_OBJECT (window), "destroy",
336 G_CALLBACK(color_selection_destroy),
337 window);
339 g_signal_connect (
340 G_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
341 "color_changed",
342 G_CALLBACK(color_selection_changed),
343 window);
345 g_signal_connect (
346 G_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->ok_button),
347 "clicked",
348 G_CALLBACK(color_selection_ok),
349 window);
351 g_signal_connect (
352 G_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->cancel_button),
353 "clicked",
354 G_CALLBACK(color_selection_cancel),
355 window);
358 /* Make sure window is shown before setting its colors: */
359 gtk_widget_show_now (color_select);
361 } else {
362 gtk_window_set_title(GTK_WINDOW(color_select),
363 edit_color==FOREGROUND?
364 _("Select foreground color"):
365 _("Select background color"));
366 if (! color_select_active) {
367 gtk_widget_show (color_select);
370 DIA_COLOR_TO_GDK(col, color);
372 gtk_color_selection_set_current_color(
373 GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (color_select)->colorsel),
374 &color);
378 static gint
379 color_area_events (GtkWidget *widget,
380 GdkEvent *event)
382 GdkEventButton *bevent;
383 int target;
385 switch (event->type)
387 case GDK_CONFIGURE:
388 if (color_area_pixmap)
390 g_object_unref (color_area_pixmap);
391 g_object_unref (color_area_mask);
394 color_area_pixmap = gdk_pixmap_new (color_area->window,
395 color_area->allocation.width,
396 color_area->allocation.height, -1);
397 color_area_mask = gdk_pixmap_new (color_area->window,
398 color_area->allocation.width,
399 color_area->allocation.height, 1);
400 break;
401 case GDK_EXPOSE:
402 if (GTK_WIDGET_DRAWABLE (color_area))
404 if (!color_area_gc)
406 color_area_gc = gdk_gc_new (color_area->window);
407 mask_gc = gdk_gc_new (color_area_mask);
410 color_area_draw ();
412 break;
413 case GDK_BUTTON_PRESS:
414 bevent = (GdkEventButton *) event;
416 if (bevent->button == 1) {
417 switch ((target = color_area_target (bevent->x, bevent->y))) {
418 case FORE_AREA:
419 case BACK_AREA:
420 if (target == active_color) {
421 color_area_edit ();
422 } else {
423 active_color = target;
424 color_area_draw();
426 break;
427 case SWAP_AREA:
428 attributes_swap_fgbg();
429 color_area_draw();
430 break;
431 case DEF_AREA:
432 attributes_default_fgbg();
433 color_area_draw();
434 break;
437 break;
439 default:
440 break;
443 return FALSE;
447 GtkWidget *
448 color_area_create (int width,
449 int height,
450 GdkPixmap *default_pmap,
451 GdkBitmap *default_msk,
452 GdkPixmap *swap_pmap,
453 GdkBitmap *swap_msk)
455 GtkWidget *event_box;
457 attributes_set_foreground(persistence_register_color("fg_color", &color_black));
458 attributes_set_background(persistence_register_color("bg_color", &color_white));
460 event_box = gtk_event_box_new();
461 color_area = gtk_drawing_area_new ();
462 gtk_widget_set_size_request (color_area, width, height);
463 gtk_widget_set_events (color_area, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
464 g_signal_connect (G_OBJECT (color_area), "event",
465 G_CALLBACK(color_area_events),
466 NULL);
467 default_pixmap = default_pmap;
468 default_mask = default_msk;
469 swap_pixmap = swap_pmap;
470 swap_mask = swap_msk;
472 gtk_widget_show(color_area);
473 gtk_container_add(GTK_CONTAINER(event_box), color_area);
474 return event_box;