2 * Copyright (C) 2005 Hiroyuki Ikezoe <poincare@ikezoe.net>
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 * The original code is gimpfgbgeditor.c in GIMP-2.3.2.
20 * Copyright (C) 2004 Michael Natterer <mitch@gimp.org>
29 #include "scim_anthy_color_button.h"
30 #include "scim_anthy_intl.h"
55 #define WIDGET_WIDTH 32
56 #define WIDGET_HEIGHT 32
58 static void scim_anthy_color_button_class_init (ScimAnthyColorButtonClass *klass);
59 static void scim_anthy_color_button_init (ScimAnthyColorButton *object);
61 static void scim_anthy_color_button_destroy (GtkObject *object);
62 static gboolean scim_anthy_color_button_expose (GtkWidget *widget,
63 GdkEventExpose *eevent);
64 static gboolean scim_anthy_color_button_button_press (GtkWidget *widget,
65 GdkEventButton *bevent);
66 static gboolean scim_anthy_color_button_button_release (GtkWidget *widget,
67 GdkEventButton *bevent);
70 static guint button_signals[LAST_SIGNAL] = { 0 };
72 static GtkDrawingAreaClass *parent_class = NULL;
75 scim_anthy_color_button_get_type (void)
77 static GType type = 0;
80 static const GTypeInfo info = {
81 sizeof (ScimAnthyColorButtonClass),
83 NULL, /* base_finalize */
84 (GClassInitFunc) scim_anthy_color_button_class_init,
85 NULL, /* class_finalize */
86 NULL, /* class_data */
87 sizeof (ScimAnthyColorButton),
89 (GInstanceInitFunc) scim_anthy_color_button_init,
92 type = g_type_register_static (GTK_TYPE_DRAWING_AREA,
93 "ScimAnthyColorButton",
94 &info, (GTypeFlags) 0);
101 scim_anthy_color_button_class_init (ScimAnthyColorButtonClass *klass)
103 GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
104 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
106 parent_class = (GtkDrawingAreaClass *) g_type_class_peek_parent (klass);
108 button_signals[COLOR_CHANGED] =
109 g_signal_new ("color-changed",
110 G_TYPE_FROM_CLASS (klass),
112 G_STRUCT_OFFSET (ScimAnthyColorButtonClass, color_changed),
114 g_cclosure_marshal_VOID__VOID,
117 gtk_object_class->destroy = scim_anthy_color_button_destroy;
119 widget_class->expose_event = scim_anthy_color_button_expose;
120 widget_class->button_press_event = scim_anthy_color_button_button_press;
121 widget_class->button_release_event = scim_anthy_color_button_button_release;
125 scim_anthy_color_button_init (ScimAnthyColorButton *object)
127 /*set default color */
128 gdk_color_parse ("#000000", &object->fg_color);
129 gdk_color_parse ("#ffffff", &object->bg_color);
131 gtk_widget_add_events (GTK_WIDGET (object),
132 GDK_BUTTON_PRESS_MASK |
133 GDK_BUTTON_RELEASE_MASK);
138 scim_anthy_color_button_destroy (GtkObject *object)
140 ScimAnthyColorButton *button = SCIM_ANTHY_COLOR_BUTTON (object);
142 if (button->render_buf) {
143 g_free (button->render_buf);
144 button->render_buf = NULL;
145 button->render_buf_size = 0;
148 if (button->swap_icon) {
149 g_object_unref (button->swap_icon);
150 button->swap_icon = NULL;
153 GTK_OBJECT_CLASS (parent_class)->destroy (object);
157 scim_anthy_color_button_draw_rect (ScimAnthyColorButton *button,
158 GdkDrawable *drawable,
171 g_return_if_fail (width > 0 && height > 0);
173 r = (color->red >> 8);
174 g = (color->green >> 8);
175 b = (color->blue >> 8);
177 rowstride = 3 * ((width + 3) & -4);
179 if (! button->render_buf || button->render_buf_size < height * rowstride) {
180 button->render_buf_size = rowstride * height;
182 g_free (button->render_buf);
183 button->render_buf = (guchar *) g_malloc (button->render_buf_size);
186 bp = button->render_buf;
187 for (xx = 0; xx < width; xx++) {
193 bp = button->render_buf;
195 for (yy = 1; yy < height; yy++) {
197 memcpy (bp, button->render_buf, rowstride);
200 gdk_draw_rgb_image (drawable, gc, x, y, width, height,
207 scim_anthy_color_button_expose (GtkWidget *widget,
208 GdkEventExpose *eevent)
210 ScimAnthyColorButton *button = SCIM_ANTHY_COLOR_BUTTON (widget);
212 gint swap_w = 0, swap_h = 0;
215 if (!GTK_WIDGET_DRAWABLE (widget))
218 width = widget->allocation.width;
219 height = widget->allocation.height;
221 /* draw the swap colors pixbuf */
222 if (!button->swap_icon) {
224 = gdk_pixbuf_new_from_file (SCIM_ICONDIR"/scim-anthy-swap-colors.png",
228 if (button->swap_icon) {
229 swap_w = gdk_pixbuf_get_width (button->swap_icon);
230 swap_h = gdk_pixbuf_get_height (button->swap_icon);
233 if (swap_w < width / 2 && swap_h < height / 2) {
234 gdk_draw_pixbuf (widget->window, NULL, button->swap_icon,
235 0, 0, width - swap_w, 0, swap_w, swap_h,
236 GDK_RGB_DITHER_NORMAL, 0, 0);
241 rect_h = height - swap_h - 2;
242 rect_w = width - swap_w - 4;
244 if (rect_h > (height * 3 / 4)) {
245 rect_w = MAX (rect_w - (rect_h - ((height * 3 / 4))),
249 button->rect_width = rect_w;
250 button->rect_height = rect_h;
253 /* draw the background area */
254 scim_anthy_color_button_draw_rect (button,
256 widget->style->fg_gc[0],
262 gtk_paint_shadow (widget->style, widget->window, GTK_STATE_NORMAL,
270 /* draw the foreground area */
271 scim_anthy_color_button_draw_rect (button,
273 widget->style->fg_gc[0],
278 gtk_paint_shadow (widget->style, widget->window, GTK_STATE_NORMAL,
288 scim_anthy_color_button_target (ScimAnthyColorButton *button,
292 gint width = GTK_WIDGET (button)->allocation.width;
293 gint height = GTK_WIDGET (button)->allocation.height;
294 gint rect_w = button->rect_width;
295 gint rect_h = button->rect_height;
297 if (x > 0 && x < rect_w && y > 0 && y < rect_h)
298 return FOREGROUND_AREA;
299 else if (x > (width - rect_w) && x < width &&
300 y > (height - rect_h) && y < height)
301 return BACKGROUND_AREA;
302 else if (x > 0 && x < (width - rect_w) &&
303 y > rect_h && y < height)
305 else if (x > rect_w && x < width &&
306 y > 0 && y < (height - rect_h))
313 scim_anthy_color_button_open_color_dialog (ScimAnthyColorButton *button, gboolean fg)
320 title = fg ? _("Foreground color") : _("Background color");
321 color = fg ? &button->fg_color : &button->bg_color;
323 dialog = gtk_color_selection_dialog_new (title);
325 gtk_color_selection_set_current_color (GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (dialog)->colorsel),
327 gtk_widget_show (dialog);
329 result = gtk_dialog_run (GTK_DIALOG (dialog));
332 case GTK_RESPONSE_OK:
333 gtk_color_selection_get_current_color (GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (dialog)->colorsel),
335 g_signal_emit (button, button_signals[COLOR_CHANGED], 0);
341 gtk_widget_destroy (dialog);
342 gtk_widget_queue_draw (GTK_WIDGET (button));
346 scim_anthy_color_button_swap_color (ScimAnthyColorButton *button)
349 tmp.red = button->fg_color.red;
350 tmp.green = button->fg_color.green;
351 tmp.blue = button->fg_color.blue;
353 button->fg_color.red = button->bg_color.red;
354 button->fg_color.green = button->bg_color.green;
355 button->fg_color.blue = button->bg_color.blue;
357 button->bg_color.red = tmp.red;
358 button->bg_color.green = tmp.green;
359 button->bg_color.blue = tmp.blue;
360 g_signal_emit (button, button_signals[COLOR_CHANGED], 0);
364 scim_anthy_color_button_button_press (GtkWidget *widget,
365 GdkEventButton *bevent)
367 ScimAnthyColorButton *button = SCIM_ANTHY_COLOR_BUTTON (widget);
368 if (bevent->button == 1 && bevent->type == GDK_BUTTON_PRESS) {
369 FgBgTarget target = scim_anthy_color_button_target (button,
370 (gint) bevent->x, (gint) bevent->y);
372 button->click_target = INVALID_AREA;
375 case FOREGROUND_AREA:
376 button->click_target = FOREGROUND_AREA;
377 scim_anthy_color_button_open_color_dialog (button, TRUE);
380 case BACKGROUND_AREA:
381 button->click_target = BACKGROUND_AREA;
382 scim_anthy_color_button_open_color_dialog (button, FALSE);
386 scim_anthy_color_button_swap_color (button);
387 gtk_widget_queue_draw (GTK_WIDGET (button));
402 scim_anthy_color_button_button_release (GtkWidget *widget,
403 GdkEventButton *bevent)
405 ScimAnthyColorButton *button = SCIM_ANTHY_COLOR_BUTTON (widget);
407 if (bevent->button == 1) {
408 FgBgTarget target = scim_anthy_color_button_target (button,
409 (gint) bevent->x, (gint) bevent->y);
411 if (target == button->click_target) {
414 case FOREGROUND_AREA:
417 case BACKGROUND_AREA:
425 button->click_target = INVALID_AREA;
432 /* public functions */
435 scim_anthy_color_button_new (void)
437 return GTK_WIDGET(g_object_new (SCIM_ANTHY_TYPE_COLOR_BUTTON,
442 scim_anthy_color_button_get_colors (ScimAnthyColorButton *button,
446 gchar fg_color_str[8], bg_color_str[8];
448 g_snprintf (fg_color_str, G_N_ELEMENTS (fg_color_str),
450 ((button->fg_color.red)>>8),
451 ((button->fg_color.green)>>8),
452 ((button->fg_color.blue)>>8));
453 g_snprintf (bg_color_str, G_N_ELEMENTS (bg_color_str),
455 ((button->bg_color.red)>>8),
456 ((button->bg_color.green)>>8),
457 ((button->bg_color.blue)>>8));
458 *fg_value = String (fg_color_str);
459 *bg_value = String (bg_color_str);
465 scim_anthy_color_button_set_colors (ScimAnthyColorButton *button,
466 const String &fg_value,
467 const String &bg_value)
469 GdkColor fg_color, bg_color;
470 gdk_color_parse (fg_value.c_str (), &fg_color);
471 gdk_color_parse (bg_value.c_str (), &bg_color);
472 button->fg_color.red = fg_color.red;
473 button->fg_color.green = fg_color.green;
474 button->fg_color.blue = fg_color.blue;
476 button->bg_color.red = bg_color.red;
477 button->bg_color.green = bg_color.green;
478 button->bg_color.blue = bg_color.blue;
484 vi:ts=4:nowrap:ai:expandtab