using dia-manual.chm instead of dia.chm
[dia.git] / app / color_area.c
blobb29ef56e5ff439678203c6ae6b9089ebf28d479a
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"
31 #define FORE_AREA 0
32 #define BACK_AREA 1
33 #define SWAP_AREA 2
34 #define DEF_AREA 3
36 #define FOREGROUND 0
37 #define BACKGROUND 1
39 /* Global variables */
40 int active_color = 0;
42 /* Static variables */
43 GtkWidget *color_area;
44 static GdkGC *color_area_gc = NULL;
45 static GdkGC *mask_gc = NULL;
46 static GdkPixmap *color_area_pixmap = NULL;
47 static GdkBitmap *color_area_mask = NULL;
48 static GdkPixmap *default_pixmap = NULL;
49 static GdkBitmap *default_mask = NULL;
50 static GdkPixmap *swap_pixmap = NULL;
51 static GdkBitmap *swap_mask = NULL;
53 static GtkWidget *color_select = NULL;
54 static int color_select_active = 0;
55 static int edit_color;
56 static Color stored_foreground;
57 static Color stored_background;
60 static void
61 color_selection_ok (GtkWidget *w,
62 GtkColorSelectionDialog *cs);
63 static void
64 color_selection_cancel (GtkWidget *w,
65 GtkColorSelectionDialog *cs);
66 static void
67 color_selection_cancel (GtkWidget *w,
68 GtkColorSelectionDialog *cs);
69 static gint
70 color_selection_delete (GtkWidget *w,
71 GdkEvent *event,
72 GtkColorSelectionDialog *cs);
73 static gint
74 color_selection_destroy (GtkWidget *w,
75 GtkColorSelectionDialog *cs);
76 static void
77 color_selection_changed (GtkWidget *w,
78 GtkColorSelectionDialog *cs);
80 /* Local functions */
81 static int
82 color_area_target (int x,
83 int y)
85 gint rect_w, rect_h;
86 gint width, height;
88 gdk_drawable_get_size (color_area_pixmap, &width, &height);
90 rect_w = width * 0.65;
91 rect_h = height * 0.65;
93 /* foreground active */
94 if (x > 0 && x < rect_w &&
95 y > 0 && y < rect_h)
96 return FORE_AREA;
97 else if (x > (width - rect_w) && x < width &&
98 y > (height - rect_h) && y < height)
99 return BACK_AREA;
100 else if (x > 0 && x < (width - rect_w) &&
101 y > rect_h && y < height)
102 return DEF_AREA;
103 else if (x > rect_w && x < width &&
104 y > 0 && y < (height - rect_h))
105 return SWAP_AREA;
106 else
107 return -1;
110 static void
111 color_area_draw ()
113 Color col;
114 GdkColor *win_bg;
115 GdkColor fg, bg, bd;
116 gint rect_w, rect_h;
117 gint width, height;
118 gint def_width, def_height;
119 gint swap_width, swap_height;
120 GdkColor mask_pattern;
122 /* Check we haven't gotten initial expose yet,
123 * no point in drawing anything
125 if (!color_area_pixmap || !color_area_gc)
126 return;
128 gdk_drawable_get_size (color_area_pixmap, &width, &height);
130 win_bg = &(color_area->style->bg[GTK_STATE_NORMAL]);
131 col = attributes_get_foreground();
132 color_convert(&col, &fg);
133 col = attributes_get_background();
134 color_convert(&col, &bg);
135 bd = color_gdk_black;
137 rect_w = width * 0.65;
138 rect_h = height * 0.65;
140 /* initialize the mask to transparent */
141 mask_pattern.pixel = 0;
142 gdk_gc_set_foreground (mask_gc, &mask_pattern);
143 gdk_draw_rectangle (color_area_mask, mask_gc, TRUE, 0, 0, -1, -1);
145 /* set the mask's gc to opaque */
146 mask_pattern.pixel = 1;
147 gdk_gc_set_foreground (mask_gc, &mask_pattern);
149 gdk_gc_set_foreground (color_area_gc, win_bg);
150 gdk_draw_rectangle (color_area_pixmap, color_area_gc, 1,
151 0, 0, width, height);
153 gdk_gc_set_foreground (color_area_gc, &bg);
154 gdk_draw_rectangle (color_area_pixmap, color_area_gc, 1,
155 (width - rect_w), (height - rect_h), rect_w, rect_h);
156 gdk_draw_rectangle (color_area_mask, mask_gc, TRUE,
157 (width - rect_w), (height - rect_h), rect_w, rect_h);
159 if (active_color == FOREGROUND)
160 gtk_paint_shadow (color_area->style, color_area_pixmap, GTK_STATE_NORMAL,
161 GTK_SHADOW_OUT,
162 NULL, color_area, NULL,
163 (width - rect_w), (height - rect_h),
164 rect_w, rect_h);
165 else
166 gtk_paint_shadow (color_area->style, color_area_pixmap, GTK_STATE_NORMAL,
167 GTK_SHADOW_IN,
168 NULL, color_area, NULL,
169 (width - rect_w), (height - rect_h),
170 rect_w, rect_h);
172 gdk_gc_set_foreground (color_area_gc, &fg);
173 gdk_draw_rectangle (color_area_pixmap, color_area_gc, 1,
174 0, 0, rect_w, rect_h);
175 gdk_draw_rectangle (color_area_mask, mask_gc, TRUE,
176 0, 0, rect_w, rect_h);
178 if (active_color == FOREGROUND)
179 gtk_paint_shadow (color_area->style, color_area_pixmap, GTK_STATE_NORMAL,
180 GTK_SHADOW_IN,
181 NULL, color_area, NULL,
182 0, 0,
183 rect_w, rect_h);
184 else
185 gtk_paint_shadow (color_area->style, color_area_pixmap, GTK_STATE_NORMAL,
186 GTK_SHADOW_OUT,
187 NULL, color_area, NULL,
188 0, 0,
189 rect_w, rect_h);
191 /* draw the default pixmap */
192 gdk_drawable_get_size (default_pixmap, &def_width, &def_height);
193 gdk_draw_drawable (color_area_pixmap, color_area_gc, default_pixmap,
194 0, 0, 0, height - def_height, def_width, def_height);
195 gdk_draw_drawable (color_area_mask, mask_gc, default_mask,
196 0, 0, 0, height - def_height, def_width, def_height);
198 /* draw the swap pixmap */
199 gdk_drawable_get_size (swap_pixmap, &swap_width, &swap_height);
200 gdk_draw_drawable (color_area_pixmap, color_area_gc, swap_pixmap,
201 0, 0, width - swap_width, 0, swap_width, swap_height);
202 gdk_draw_drawable (color_area_mask, mask_gc, swap_mask,
203 0, 0, width - swap_width, 0, swap_width, swap_height);
205 /* draw the widget */
206 gdk_gc_set_clip_mask (color_area_gc, color_area_mask);
207 gdk_gc_set_clip_origin (color_area_gc, 0, 0);
208 gdk_draw_drawable (color_area->window, color_area_gc, color_area_pixmap,
209 0, 0, 0, 0, width, height);
211 /* reset the clip mask */
212 gdk_gc_set_clip_mask (color_area_gc, NULL);
215 static void
216 color_selection_ok (GtkWidget *w,
217 GtkColorSelectionDialog *cs)
219 GtkColorSelection *colorsel;
220 GdkColor color;
221 Color col;
223 colorsel=GTK_COLOR_SELECTION(cs->colorsel);
225 gtk_color_selection_get_current_color(colorsel,&color);
226 GDK_COLOR_TO_DIA(color, col);
228 if (edit_color == FOREGROUND) {
229 attributes_set_foreground(&col);
230 } else {
231 attributes_set_background(&col);
233 color_area_draw ();
235 /* gtk_color_selection_set_currentcolor(colorsel,&color);*/
237 gtk_widget_hide(color_select);
238 color_select_active = 0;
241 static void
242 color_selection_cancel (GtkWidget *w,
243 GtkColorSelectionDialog *cs)
245 if (color_select != NULL)
246 gtk_widget_hide(color_select);
247 color_select_active = 0;
248 attributes_set_foreground(&stored_foreground);
249 attributes_set_background(&stored_background);
251 color_area_draw ();
254 static gint
255 color_selection_delete (GtkWidget *w,
256 GdkEvent *event,
257 GtkColorSelectionDialog *cs)
259 color_selection_cancel(w,cs);
260 return TRUE;
263 static gint
264 color_selection_destroy (GtkWidget *w,
265 GtkColorSelectionDialog *cs)
267 color_select = NULL;
268 color_selection_cancel(w,cs);
269 return TRUE;
272 static void
273 color_selection_changed (GtkWidget *w,
274 GtkColorSelectionDialog *cs)
276 GtkColorSelection *colorsel;
277 GdkColor color;
278 Color col;
280 colorsel=GTK_COLOR_SELECTION(cs->colorsel);
282 gtk_color_selection_get_current_color(colorsel,&color);
283 GDK_COLOR_TO_DIA(color, col);
285 if (edit_color == FOREGROUND) {
286 attributes_set_foreground(&col);
287 } else {
288 attributes_set_background(&col);
290 color_area_draw ();
293 static void
294 color_area_edit (void)
296 Color col;
297 GtkWidget *window;
298 GdkColor color;
300 if (!color_select_active) {
301 stored_foreground = attributes_get_foreground();
302 stored_background = attributes_get_background();
305 if (active_color == FOREGROUND) {
306 col = attributes_get_foreground();
307 edit_color = FOREGROUND;
308 } else {
309 col = attributes_get_background();
310 edit_color = BACKGROUND;
313 if (! color_select) {
314 window = color_select =
315 gtk_color_selection_dialog_new(edit_color==FOREGROUND?
316 _("Select foreground color"):
317 _("Select background color"));
318 color_select_active = 1;
320 gtk_color_selection_set_has_palette (
321 GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
322 TRUE);
324 gtk_color_selection_set_update_policy(
325 GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
326 GTK_UPDATE_CONTINUOUS);
328 gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
330 g_signal_connect (G_OBJECT (window), "delete_event",
331 G_CALLBACK(color_selection_delete),
332 window);
334 gtk_signal_connect (GTK_OBJECT (window), "destroy",
335 GTK_SIGNAL_FUNC(color_selection_destroy),
336 window);
338 g_signal_connect (
339 G_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
340 "color_changed",
341 G_CALLBACK(color_selection_changed),
342 window);
344 g_signal_connect (
345 G_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->ok_button),
346 "clicked",
347 G_CALLBACK(color_selection_ok),
348 window);
350 g_signal_connect (
351 G_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->cancel_button),
352 "clicked",
353 G_CALLBACK(color_selection_cancel),
354 window);
357 /* Make sure window is shown before setting its colors: */
358 gtk_widget_show_now (color_select);
360 } else {
361 gtk_window_set_title(GTK_WINDOW(color_select),
362 edit_color==FOREGROUND?
363 _("Select foreground color"):
364 _("Select background color"));
365 if (! color_select_active) {
366 gtk_widget_show (color_select);
369 DIA_COLOR_TO_GDK(col, color);
371 gtk_color_selection_set_current_color(
372 GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (color_select)->colorsel),
373 &color);
377 static gint
378 color_area_events (GtkWidget *widget,
379 GdkEvent *event)
381 GdkEventButton *bevent;
382 int target;
384 switch (event->type)
386 case GDK_CONFIGURE:
387 if (color_area_pixmap)
389 g_object_unref (color_area_pixmap);
390 g_object_unref (color_area_mask);
393 color_area_pixmap = gdk_pixmap_new (color_area->window,
394 color_area->allocation.width,
395 color_area->allocation.height, -1);
396 color_area_mask = gdk_pixmap_new (color_area->window,
397 color_area->allocation.width,
398 color_area->allocation.height, 1);
399 break;
400 case GDK_EXPOSE:
401 if (GTK_WIDGET_DRAWABLE (color_area))
403 if (!color_area_gc)
405 color_area_gc = gdk_gc_new (color_area->window);
406 mask_gc = gdk_gc_new (color_area_mask);
409 color_area_draw ();
411 break;
412 case GDK_BUTTON_PRESS:
413 bevent = (GdkEventButton *) event;
415 if (bevent->button == 1) {
416 switch ((target = color_area_target (bevent->x, bevent->y))) {
417 case FORE_AREA:
418 case BACK_AREA:
419 if (target == active_color) {
420 color_area_edit ();
421 } else {
422 active_color = target;
423 color_area_draw();
425 break;
426 case SWAP_AREA:
427 attributes_swap_fgbg();
428 color_area_draw();
429 break;
430 case DEF_AREA:
431 attributes_default_fgbg();
432 color_area_draw();
433 break;
436 break;
438 default:
439 break;
442 return FALSE;
446 GtkWidget *
447 color_area_create (int width,
448 int height,
449 GdkPixmap *default_pmap,
450 GdkBitmap *default_msk,
451 GdkPixmap *swap_pmap,
452 GdkBitmap *swap_msk)
454 GtkWidget *event_box;
456 event_box = gtk_event_box_new();
457 color_area = gtk_drawing_area_new ();
458 gtk_widget_set_size_request (color_area, width, height);
459 gtk_widget_set_events (color_area, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
460 g_signal_connect (G_OBJECT (color_area), "event",
461 G_CALLBACK(color_area_events),
462 NULL);
463 default_pixmap = default_pmap;
464 default_mask = default_msk;
465 swap_pixmap = swap_pmap;
466 swap_mask = swap_msk;
468 gtk_widget_show(color_area);
469 gtk_container_add(GTK_CONTAINER(event_box), color_area);
470 return event_box;