mirror of https://github.com/Gnucash/gnucash
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
729 lines
22 KiB
729 lines
22 KiB
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
|
/*
|
|
* color-palette.c - A color selector palette
|
|
* Copyright 2000, 2001, Ximian, Inc.
|
|
*
|
|
* Authors:
|
|
* This code was extracted from widget-color-combo.c
|
|
* written by Miguel de Icaza (miguel@kernel.org) and
|
|
* Dom Lachowicz (dominicl@seas.upenn.edu). The extracted
|
|
* code was re-packaged into a separate object by
|
|
* Michael Levy (mlevy@genoscope.cns.fr)
|
|
* And later revised and polished by
|
|
* Almer S. Tigelaar (almer@gnome.org)
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License, version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This library is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
* 02111-1307, USA.
|
|
*/
|
|
|
|
#include <goffice/goffice-config.h>
|
|
#include "go-color-palette.h"
|
|
#include "go-marshalers.h"
|
|
|
|
#include <goffice/utils/go-color.h>
|
|
#include <gui-util.h>
|
|
#include <style-color.h>
|
|
#include <gtk/gtklabel.h>
|
|
#include <gtk/gtkvbox.h>
|
|
#include <gtk/gtktable.h>
|
|
#include <gtk/gtkdrawingarea.h>
|
|
#include <gtk/gtkimagemenuitem.h>
|
|
#include <gtk/gtkimage.h>
|
|
#include <gtk/gtkstock.h>
|
|
#include <gtk/gtkbutton.h>
|
|
#include <gtk/gtkcolorseldialog.h>
|
|
#include <gdk/gdkkeysyms.h>
|
|
#include <gdk/gdkcolor.h>
|
|
#include <glib/gi18n.h>
|
|
#include <gsf/gsf-impl-utils.h>
|
|
|
|
|
|
#include <string.h>
|
|
|
|
typedef struct _ColorNamePair ColorNamePair;
|
|
struct _GOColorPalette {
|
|
GtkVBox base;
|
|
|
|
GOColorGroup *group;
|
|
GOColor selection, default_color;
|
|
gboolean current_is_custom;
|
|
gboolean current_is_default;
|
|
gboolean allow_alpha;
|
|
|
|
/* only for custom colours */
|
|
GtkWidget *swatches [GO_COLOR_GROUP_HISTORY_SIZE];
|
|
GtkTooltips *tip;
|
|
|
|
/* The table with our default color names */
|
|
ColorNamePair const *default_set;
|
|
};
|
|
|
|
typedef struct {
|
|
GtkVBoxClass base;
|
|
|
|
/* Signals emited by this widget */
|
|
void (*color_changed) (GOColorPalette *pal, GOColor color,
|
|
gboolean is_custom, gboolean by_user, gboolean is_default);
|
|
void (*display_custom_dialog) (GOColorPalette *pal, GtkWidget *dialog);
|
|
} GOColorPaletteClass;
|
|
|
|
#define COLOR_PREVIEW_WIDTH 12
|
|
#define COLOR_PREVIEW_HEIGHT 12
|
|
|
|
enum {
|
|
COLOR_CHANGED,
|
|
DISPLAY_CUSTOM_DIALOG,
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
struct _ColorNamePair {
|
|
GOColor color;
|
|
char const *name; /* english name - eg. "white" */
|
|
};
|
|
|
|
static ColorNamePair const default_color_set [] = {
|
|
{ RGBA_TO_UINT (0x00, 0x00, 0x00, 0xff), N_("black")},
|
|
{ RGBA_TO_UINT (0x99, 0x33, 0x00, 0xff), N_("light brown")},
|
|
{ RGBA_TO_UINT (0x33, 0x33, 0x00, 0xff), N_("brown gold")},
|
|
{ RGBA_TO_UINT (0x00, 0x33, 0x00, 0xff), N_("dark green #2")},
|
|
{ RGBA_TO_UINT (0x00, 0x33, 0x66, 0xff), N_("navy")},
|
|
{ RGBA_TO_UINT (0x00, 0x00, 0x80, 0xff), N_("dark blue")},
|
|
{ RGBA_TO_UINT (0x33, 0x33, 0x99, 0xff), N_("purple #2")},
|
|
{ RGBA_TO_UINT (0x33, 0x33, 0x33, 0xff), N_("very dark gray")},
|
|
|
|
{ RGBA_TO_UINT (0x80, 0x00, 0x00, 0xff), N_("dark red")},
|
|
{ RGBA_TO_UINT (0xFF, 0x66, 0x00, 0xff), N_("red-orange")},
|
|
{ RGBA_TO_UINT (0x80, 0x80, 0x00, 0xff), N_("gold")},
|
|
{ RGBA_TO_UINT (0x00, 0x80, 0x00, 0xff), N_("dark green")},
|
|
{ RGBA_TO_UINT (0x00, 0x80, 0x80, 0xff), N_("dull blue")},
|
|
{ RGBA_TO_UINT (0x00, 0x00, 0xFF, 0xff), N_("blue")},
|
|
{ RGBA_TO_UINT (0x66, 0x66, 0x99, 0xff), N_("dull purple")},
|
|
{ RGBA_TO_UINT (0x80, 0x80, 0x80, 0xff), N_("dark gray")},
|
|
|
|
{ RGBA_TO_UINT (0xFF, 0x00, 0x00, 0xff), N_("red")},
|
|
{ RGBA_TO_UINT (0xFF, 0x99, 0x00, 0xff), N_("orange")},
|
|
{ RGBA_TO_UINT (0x99, 0xCC, 0x00, 0xff), N_("lime")},
|
|
{ RGBA_TO_UINT (0x33, 0x99, 0x66, 0xff), N_("dull green")},
|
|
{ RGBA_TO_UINT (0x33, 0xCC, 0xCC, 0xff), N_("dull blue #2")},
|
|
{ RGBA_TO_UINT (0x33, 0x66, 0xFF, 0xff), N_("sky blue #2")},
|
|
{ RGBA_TO_UINT (0x80, 0x00, 0x80, 0xff), N_("purple")},
|
|
{ RGBA_TO_UINT (0x96, 0x96, 0x96, 0xff), N_("gray")},
|
|
|
|
{ RGBA_TO_UINT (0xFF, 0x00, 0xFF, 0xff), N_("magenta")},
|
|
{ RGBA_TO_UINT (0xFF, 0xCC, 0x00, 0xff), N_("bright orange")},
|
|
{ RGBA_TO_UINT (0xFF, 0xFF, 0x00, 0xff), N_("yellow")},
|
|
{ RGBA_TO_UINT (0x00, 0xFF, 0x00, 0xff), N_("green")},
|
|
{ RGBA_TO_UINT (0x00, 0xFF, 0xFF, 0xff), N_("cyan")},
|
|
{ RGBA_TO_UINT (0x00, 0xCC, 0xFF, 0xff), N_("bright blue")},
|
|
{ RGBA_TO_UINT (0x99, 0x33, 0x66, 0xff), N_("red purple")},
|
|
{ RGBA_TO_UINT (0xC0, 0xC0, 0xC0, 0xff), N_("light gray")},
|
|
|
|
{ RGBA_TO_UINT (0xFF, 0x99, 0xCC, 0xff), N_("pink")},
|
|
{ RGBA_TO_UINT (0xFF, 0xCC, 0x99, 0xff), N_("light orange")},
|
|
{ RGBA_TO_UINT (0xFF, 0xFF, 0x99, 0xff), N_("light yellow")},
|
|
{ RGBA_TO_UINT (0xCC, 0xFF, 0xCC, 0xff), N_("light green")},
|
|
{ RGBA_TO_UINT (0xCC, 0xFF, 0xFF, 0xff), N_("light cyan")},
|
|
{ RGBA_TO_UINT (0x99, 0xCC, 0xFF, 0xff), N_("light blue")},
|
|
{ RGBA_TO_UINT (0xCC, 0x99, 0xFF, 0xff), N_("light purple")},
|
|
{ RGBA_TO_UINT (0xFF, 0xFF, 0xFF, 0xff), N_("white")},
|
|
|
|
{ 0, NULL},
|
|
|
|
/* Disable these for now, they are mostly repeats */
|
|
{ RGBA_TO_UINT (0x99, 0x99, 0xFF, 0xff), N_("purplish blue")},
|
|
{ RGBA_TO_UINT (0x99, 0x33, 0x66, 0xff), N_("red purple")},
|
|
{ RGBA_TO_UINT (0xFF, 0xFF, 0xCC, 0xff), N_("light yellow")},
|
|
{ RGBA_TO_UINT (0xCC, 0xFF, 0xFF, 0xff), N_("light blue")},
|
|
{ RGBA_TO_UINT (0x66, 0x00, 0x66, 0xff), N_("dark purple")},
|
|
{ RGBA_TO_UINT (0xFF, 0x80, 0x80, 0xff), N_("pink")},
|
|
{ RGBA_TO_UINT (0x00, 0x66, 0xCC, 0xff), N_("sky blue")},
|
|
{ RGBA_TO_UINT (0xCC, 0xCC, 0xFF, 0xff), N_("light purple")},
|
|
|
|
{ RGBA_TO_UINT (0x00, 0x00, 0x80, 0xff), N_("dark blue")},
|
|
{ RGBA_TO_UINT (0xFF, 0x00, 0xFF, 0xff), N_("magenta")},
|
|
{ RGBA_TO_UINT (0xFF, 0xFF, 0x00, 0xff), N_("yellow")},
|
|
{ RGBA_TO_UINT (0x00, 0xFF, 0xFF, 0xff), N_("cyan")},
|
|
{ RGBA_TO_UINT (0x80, 0x00, 0x80, 0xff), N_("purple")},
|
|
{ RGBA_TO_UINT (0x80, 0x00, 0x00, 0xff), N_("dark red")},
|
|
{ RGBA_TO_UINT (0x00, 0x80, 0x80, 0xff), N_("dull blue")},
|
|
{ RGBA_TO_UINT (0x00, 0x00, 0xFF, 0xff), N_("blue")},
|
|
|
|
{ 0, NULL},
|
|
};
|
|
|
|
static guint go_color_palette_signals [LAST_SIGNAL] = { 0, };
|
|
|
|
static GObjectClass *go_color_palette_parent_class;
|
|
|
|
static GtkWidget *
|
|
create_color_sel (GObject *action_proxy, GOColor c, GCallback handler, gboolean allow_alpha)
|
|
{
|
|
char *title = g_object_get_data (G_OBJECT (action_proxy), "title");
|
|
GtkWidget *w = gtk_color_selection_dialog_new (title);
|
|
GtkColorSelectionDialog *dialog = GTK_COLOR_SELECTION_DIALOG (w);
|
|
GtkColorSelection *colorsel = GTK_COLOR_SELECTION (dialog->colorsel);
|
|
GdkColor gdk;
|
|
|
|
gtk_widget_hide (dialog->help_button);
|
|
gtk_color_selection_set_current_color (colorsel,
|
|
go_color_to_gdk (c, &gdk));
|
|
gtk_color_selection_set_has_opacity_control (colorsel, allow_alpha);
|
|
|
|
g_signal_connect_object (dialog,
|
|
"response", handler, action_proxy, 0);
|
|
|
|
/* require an explicit show _after_ the custom-dialog signal fires */
|
|
return w;
|
|
}
|
|
|
|
static gboolean
|
|
handle_color_sel (GtkColorSelectionDialog *dialog,
|
|
gint response_id, GOColor *res)
|
|
{
|
|
if (response_id == GTK_RESPONSE_OK) {
|
|
GdkColor gdk;
|
|
GtkColorSelection *colorsel = GTK_COLOR_SELECTION (dialog->colorsel);
|
|
guint16 alpha = gtk_color_selection_get_current_alpha (colorsel);
|
|
|
|
gtk_color_selection_get_current_color (colorsel, &gdk);
|
|
*res = GDK_TO_UINT (gdk);
|
|
alpha >>= 8;
|
|
*res = UINT_RGBA_CHANGE_A (*res, alpha);
|
|
}
|
|
/* destroy _before_ we emit */
|
|
gtk_object_destroy (GTK_OBJECT (dialog));
|
|
return response_id == GTK_RESPONSE_OK;
|
|
}
|
|
|
|
static void
|
|
go_color_palette_finalize (GObject *object)
|
|
{
|
|
GOColorPalette *pal = GO_COLOR_PALETTE (object);
|
|
|
|
if (pal->tip) {
|
|
g_object_unref (pal->tip);
|
|
pal->tip = NULL;
|
|
}
|
|
|
|
go_color_palette_set_group (pal, NULL);
|
|
|
|
(*go_color_palette_parent_class->finalize) (object);
|
|
}
|
|
|
|
static void
|
|
go_color_palette_class_init (GObjectClass *gobject_class)
|
|
{
|
|
gobject_class->finalize = go_color_palette_finalize;
|
|
|
|
go_color_palette_parent_class = g_type_class_peek_parent (gobject_class);
|
|
|
|
go_color_palette_signals [COLOR_CHANGED] =
|
|
g_signal_new ("color_changed",
|
|
G_OBJECT_CLASS_TYPE (gobject_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET (GOColorPaletteClass, color_changed),
|
|
NULL, NULL,
|
|
go__VOID__INT_BOOLEAN_BOOLEAN_BOOLEAN,
|
|
G_TYPE_NONE, 4, G_TYPE_INT,
|
|
G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
|
|
go_color_palette_signals [DISPLAY_CUSTOM_DIALOG] =
|
|
g_signal_new ("display-custom-dialog",
|
|
G_OBJECT_CLASS_TYPE (gobject_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET (GOColorPaletteClass, display_custom_dialog),
|
|
NULL, NULL,
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
|
}
|
|
|
|
GSF_CLASS (GOColorPalette, go_color_palette,
|
|
go_color_palette_class_init, NULL,
|
|
GTK_TYPE_VBOX)
|
|
|
|
/*
|
|
* Find out if a color is in the default palette (not in the custom colors!)
|
|
*
|
|
* Utility function
|
|
*/
|
|
static gboolean
|
|
color_in_palette (ColorNamePair const *set, GOColor color)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; set[i].name != NULL; i++)
|
|
if (color == set[i].color)
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
set_color (GOColorPalette *pal, GOColor color, gboolean is_custom,
|
|
gboolean by_user, gboolean is_default)
|
|
{
|
|
if (is_default)
|
|
color = pal->default_color;
|
|
if (!color_in_palette (pal->default_set, color))
|
|
go_color_group_add_color (pal->group, color);
|
|
pal->selection = color;
|
|
pal->current_is_custom = is_custom;
|
|
pal->current_is_default = is_default;
|
|
g_signal_emit (pal, go_color_palette_signals [COLOR_CHANGED], 0,
|
|
color, is_custom, by_user, is_default);
|
|
}
|
|
|
|
static void
|
|
cb_history_changed (GOColorPalette *pal)
|
|
{
|
|
int i;
|
|
GdkColor gdk;
|
|
GOColorGroup *group = pal->group;
|
|
|
|
for (i = 0 ; i < GO_COLOR_GROUP_HISTORY_SIZE ; i++)
|
|
gtk_widget_modify_bg (pal->swatches [i], GTK_STATE_NORMAL,
|
|
go_color_to_gdk (group->history[i], &gdk));
|
|
#if 0
|
|
if (next_swatch != NULL) {
|
|
next_swatch->style->bg[GTK_STATE_NORMAL] = *new_color;
|
|
gnome_color_picker_set_i16 (GNOME_COLOR_PICKER (pal->picker),
|
|
new_color->red, new_color->green, new_color->blue, 0);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static gboolean
|
|
cb_default_release_event (GtkWidget *button, GdkEventButton *event, GOColorPalette *pal)
|
|
{
|
|
set_color (pal, pal->default_color, FALSE, TRUE, TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
swatch_activated (GOColorPalette *pal, GtkBin *button)
|
|
{
|
|
GList *tmp = gtk_container_get_children (GTK_CONTAINER (gtk_bin_get_child (button)));
|
|
GtkWidget *swatch = (tmp != NULL) ? tmp->data : NULL;
|
|
|
|
g_list_free (tmp);
|
|
|
|
g_return_if_fail (swatch != NULL);
|
|
|
|
set_color (pal, GDK_TO_UINT (swatch->style->bg[GTK_STATE_NORMAL]),
|
|
FALSE, TRUE, FALSE);
|
|
}
|
|
|
|
static gboolean
|
|
cb_swatch_release_event (GtkBin *button, GdkEventButton *event, GOColorPalette *pal)
|
|
{
|
|
#ifdef GOG_WARN_TODO
|
|
#warning TODO do I want to check for which button ?
|
|
#endif
|
|
swatch_activated (pal, button);
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
cb_swatch_key_press (GtkBin *button, GdkEventKey *event, GOColorPalette *pal)
|
|
{
|
|
if (event->keyval == GDK_Return ||
|
|
event->keyval == GDK_KP_Enter ||
|
|
event->keyval == GDK_space) {
|
|
swatch_activated (pal, button);
|
|
return TRUE;
|
|
} else
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* Create the individual color buttons
|
|
*
|
|
* Utility function
|
|
*/
|
|
static GtkWidget *
|
|
go_color_palette_button_new (GOColorPalette *pal, GtkTable* table, GtkTooltips *tip,
|
|
ColorNamePair const * color_name, gint col, gint row)
|
|
{
|
|
GtkWidget *button, *swatch, *box;
|
|
GdkColor gdk;
|
|
|
|
swatch = gtk_drawing_area_new ();
|
|
gtk_widget_modify_bg (swatch, GTK_STATE_NORMAL,
|
|
go_color_to_gdk (color_name->color, &gdk));
|
|
gtk_widget_set_size_request (swatch, COLOR_PREVIEW_WIDTH, COLOR_PREVIEW_HEIGHT);
|
|
|
|
/* Wrap inside a vbox with a border so that we can see the focus indicator */
|
|
box = gtk_vbox_new (FALSE, 0);
|
|
gtk_container_set_border_width (GTK_CONTAINER (box), 2);
|
|
gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (swatch), TRUE, TRUE, 0);
|
|
|
|
button = gtk_button_new ();
|
|
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
|
|
gtk_container_add (GTK_CONTAINER (button), box);
|
|
gtk_tooltips_set_tip (tip, button, _(color_name->name), "");
|
|
|
|
gtk_table_attach (table, button, col, col+1, row, row+1,
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
g_object_connect (button,
|
|
"signal::button_release_event", G_CALLBACK (cb_swatch_release_event), pal,
|
|
"signal::key_press_event", G_CALLBACK (cb_swatch_key_press), pal,
|
|
NULL);
|
|
return swatch;
|
|
}
|
|
|
|
static void
|
|
cb_combo_custom_response (GtkColorSelectionDialog *dialog,
|
|
gint response_id, GOColorPalette *pal)
|
|
{
|
|
GOColor c;
|
|
if (handle_color_sel (dialog, response_id, &c))
|
|
set_color (pal, c, TRUE, TRUE, FALSE);
|
|
}
|
|
|
|
static void
|
|
cb_combo_custom_clicked (GtkWidget *button, GOColorPalette *pal)
|
|
{
|
|
GtkWidget *dialog = create_color_sel (G_OBJECT (pal), pal->selection,
|
|
G_CALLBACK (cb_combo_custom_response), pal->allow_alpha);
|
|
g_signal_emit (pal, go_color_palette_signals [DISPLAY_CUSTOM_DIALOG], 0,
|
|
dialog);
|
|
gtk_widget_show (dialog);
|
|
}
|
|
|
|
void
|
|
go_color_palette_set_title (GOColorPalette *pal, char const *title)
|
|
{
|
|
g_object_set_data_full (G_OBJECT (pal), "title",
|
|
g_strdup (title), g_free);
|
|
}
|
|
|
|
/**
|
|
* go_color_palette_set_group :
|
|
* @cg : #GOColorGroup
|
|
*
|
|
* Absorb the reference to the group
|
|
*/
|
|
void
|
|
go_color_palette_set_group (GOColorPalette *pal, GOColorGroup *cg)
|
|
{
|
|
if (pal->group == cg)
|
|
return;
|
|
|
|
if (pal->group) {
|
|
g_signal_handlers_disconnect_by_func (
|
|
G_OBJECT (pal->group),
|
|
G_CALLBACK (cb_history_changed), pal);
|
|
g_object_unref (G_OBJECT (pal->group));
|
|
pal->group = NULL;
|
|
}
|
|
if (cg != NULL) {
|
|
pal->group = cg;
|
|
g_signal_connect_swapped (G_OBJECT (cg),
|
|
"history-changed",
|
|
G_CALLBACK (cb_history_changed), pal);
|
|
}
|
|
}
|
|
static GtkWidget *
|
|
go_color_palette_setup (GOColorPalette *pal,
|
|
char const *no_color_label,
|
|
int cols, int rows,
|
|
ColorNamePair const *color_names)
|
|
{
|
|
GtkWidget *w, *table;
|
|
GtkTooltips *tip;
|
|
int pos, row, col = 0;
|
|
|
|
table = gtk_table_new (cols, rows, FALSE);
|
|
|
|
if (no_color_label != NULL) {
|
|
w = gtk_button_new_with_label (no_color_label);
|
|
gtk_table_attach (GTK_TABLE (table), w,
|
|
0, cols, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
|
|
g_signal_connect (w,
|
|
"button_release_event",
|
|
G_CALLBACK (cb_default_release_event), pal);
|
|
}
|
|
|
|
pal->tip = tip = gtk_tooltips_new ();
|
|
g_object_ref (pal->tip);
|
|
gtk_object_sink (GTK_OBJECT (pal->tip));
|
|
|
|
for (row = 0; row < rows; row++)
|
|
for (col = 0; col < cols; col++) {
|
|
pos = row * cols + col;
|
|
if (color_names [pos].name == NULL)
|
|
goto custom_colors;
|
|
go_color_palette_button_new ( pal,
|
|
GTK_TABLE (table), GTK_TOOLTIPS (tip),
|
|
&(color_names [pos]), col, row + 1);
|
|
}
|
|
|
|
custom_colors :
|
|
if (col > 0)
|
|
row++;
|
|
for (col = 0; col < cols && col < GO_COLOR_GROUP_HISTORY_SIZE; col++) {
|
|
ColorNamePair color_name = { 0, N_("custom") };
|
|
color_name.color = pal->group->history [col];
|
|
pal->swatches [col] = go_color_palette_button_new (pal,
|
|
GTK_TABLE (table), GTK_TOOLTIPS (tip),
|
|
&color_name, col, row + 1);
|
|
}
|
|
|
|
w = gnumeric_button_new_with_stock_image (_("Custom Color..."),
|
|
GTK_STOCK_SELECT_COLOR);
|
|
gtk_button_set_alignment (GTK_BUTTON (w), 0., .5);
|
|
gtk_table_attach (GTK_TABLE (table), w, 0, cols,
|
|
row + 2, row + 3, GTK_FILL | GTK_EXPAND, 0, 0, 0);
|
|
g_signal_connect (G_OBJECT (w),
|
|
"clicked",
|
|
G_CALLBACK (cb_combo_custom_clicked), pal);
|
|
|
|
return table;
|
|
}
|
|
|
|
void
|
|
go_color_palette_set_color_to_default (GOColorPalette *pal)
|
|
{
|
|
set_color (pal, pal->default_color, FALSE, TRUE, TRUE);
|
|
}
|
|
|
|
void
|
|
go_color_palette_set_current_color (GOColorPalette *pal, GOColor color)
|
|
{
|
|
set_color (pal, color,
|
|
color_in_palette (pal->default_set, color),
|
|
FALSE, FALSE);
|
|
}
|
|
|
|
GOColor
|
|
go_color_palette_get_current_color (GOColorPalette *pal,
|
|
gboolean *is_default, gboolean *is_custom)
|
|
{
|
|
if (is_default != NULL)
|
|
*is_default = pal->current_is_default;
|
|
if (is_custom != NULL)
|
|
*is_custom = pal->current_is_custom;
|
|
return pal->selection;
|
|
}
|
|
|
|
void
|
|
go_color_palette_set_allow_alpha (GOColorPalette *pal, gboolean allow_alpha)
|
|
{
|
|
pal->allow_alpha = allow_alpha;
|
|
}
|
|
|
|
GtkWidget *
|
|
go_color_palette_new (char const *no_color_label,
|
|
GOColor default_color,
|
|
GOColorGroup *cg)
|
|
{
|
|
GOColorPalette *pal;
|
|
int const cols = 8;
|
|
int const rows = 6;
|
|
ColorNamePair const *color_names = default_color_set;
|
|
|
|
pal = g_object_new (GO_COLOR_PALETTE_TYPE, NULL);
|
|
|
|
pal->default_set = color_names;
|
|
pal->default_color = default_color;
|
|
pal->selection = default_color;
|
|
pal->current_is_custom = FALSE;
|
|
pal->current_is_default = TRUE;
|
|
go_color_palette_set_group (pal, cg);
|
|
|
|
gtk_container_add (GTK_CONTAINER (pal),
|
|
go_color_palette_setup (pal, no_color_label, cols, rows,
|
|
pal->default_set));
|
|
return GTK_WIDGET (pal);
|
|
}
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
typedef struct {
|
|
GtkMenu base;
|
|
gboolean allow_alpha;
|
|
GOColor selection, default_color;
|
|
} GOMenuColor;
|
|
|
|
typedef struct {
|
|
GtkMenuClass base;
|
|
void (* color_changed) (GOMenuColor *menu, GOColor color,
|
|
gboolean custom, gboolean by_user, gboolean is_default);
|
|
void (*display_custom_dialog) (GOColorPalette *pal, GtkWidget *dialog);
|
|
} GOMenuColorClass;
|
|
|
|
static guint go_menu_color_signals [LAST_SIGNAL] = { 0, };
|
|
|
|
static void
|
|
go_menu_color_class_init (GObjectClass *gobject_class)
|
|
{
|
|
go_menu_color_signals [COLOR_CHANGED] =
|
|
g_signal_new ("color_changed",
|
|
G_OBJECT_CLASS_TYPE (gobject_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET (GOMenuColorClass, color_changed),
|
|
NULL, NULL,
|
|
go__VOID__INT_BOOLEAN_BOOLEAN_BOOLEAN,
|
|
G_TYPE_NONE, 4, G_TYPE_INT,
|
|
G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
|
|
go_menu_color_signals [DISPLAY_CUSTOM_DIALOG] =
|
|
g_signal_new ("display-custom-dialog",
|
|
G_OBJECT_CLASS_TYPE (gobject_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET (GOColorPaletteClass, display_custom_dialog),
|
|
NULL, NULL,
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
|
}
|
|
|
|
static GSF_CLASS (GOMenuColor, go_menu_color,
|
|
go_menu_color_class_init, NULL,
|
|
GTK_TYPE_MENU)
|
|
|
|
static GtkWidget *
|
|
make_colored_menu_item (char const *label, GOColor c)
|
|
{
|
|
GtkWidget *button;
|
|
GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
|
|
COLOR_PREVIEW_WIDTH, COLOR_PREVIEW_HEIGHT);
|
|
gdk_pixbuf_fill (pixbuf, c);
|
|
|
|
button = gtk_image_menu_item_new_with_label (label);
|
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (button),
|
|
gtk_image_new_from_pixbuf (pixbuf));
|
|
g_object_unref (pixbuf);
|
|
gtk_widget_show_all (button);
|
|
|
|
g_object_set_data (G_OBJECT (button), "go_color", GINT_TO_POINTER (c));
|
|
return button;
|
|
}
|
|
|
|
static void
|
|
cb_menu_default_activate (GtkWidget *button, GOMenuColor *menu)
|
|
{
|
|
menu->selection = menu->default_color;
|
|
g_signal_emit (menu, go_menu_color_signals [COLOR_CHANGED], 0,
|
|
menu->selection, FALSE, TRUE, TRUE);
|
|
}
|
|
|
|
static void
|
|
cb_menu_color_activate (GtkWidget *button, GOMenuColor *menu)
|
|
{
|
|
GOColor color = GPOINTER_TO_INT (
|
|
g_object_get_data (G_OBJECT (button), "go_color"));
|
|
menu->selection = color;
|
|
g_signal_emit (menu, go_menu_color_signals [COLOR_CHANGED], 0,
|
|
color, FALSE, TRUE, FALSE);
|
|
}
|
|
static void
|
|
cb_menu_custom_response (GtkColorSelectionDialog *dialog,
|
|
gint response_id, GOMenuColor *menu)
|
|
{
|
|
GOColor c;
|
|
if (handle_color_sel (dialog, response_id, &c)) {
|
|
menu->selection = c;
|
|
g_signal_emit (menu, go_menu_color_signals [COLOR_CHANGED], 0,
|
|
c, TRUE, TRUE, FALSE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cb_menu_custom_activate (GtkWidget *button, GOMenuColor *menu)
|
|
{
|
|
GtkWidget *dialog = create_color_sel (G_OBJECT (menu), menu->selection,
|
|
G_CALLBACK (cb_menu_custom_response), menu->allow_alpha);
|
|
g_signal_emit (menu, go_menu_color_signals [DISPLAY_CUSTOM_DIALOG], 0,
|
|
dialog);
|
|
gtk_widget_show (dialog);
|
|
}
|
|
|
|
/**
|
|
* go_color_palette_make_menu:
|
|
* @no_color_labe :
|
|
* default_color: #GOColor
|
|
* @cg : #GOColorGroup
|
|
* @custom_dialog_title :
|
|
* @current_color : #GOColor
|
|
*
|
|
* Create a submenu with a palette of colours. Caller is responsible for
|
|
* creating an item to point to the submenu.
|
|
**/
|
|
GtkWidget *
|
|
go_color_palette_make_menu (char const *no_color_label,
|
|
GOColor default_color,
|
|
GOColorGroup *cg,
|
|
char const *custom_dialog_title,
|
|
GOColor current_color)
|
|
{
|
|
int cols = 8;
|
|
int rows = 6;
|
|
int col, row, pos, table_row = 0;
|
|
ColorNamePair const *color_names = default_color_set;
|
|
GtkWidget *w, *submenu;
|
|
|
|
submenu = g_object_new (go_menu_color_get_type (), NULL);
|
|
|
|
if (no_color_label != NULL) {
|
|
w = make_colored_menu_item (no_color_label, default_color);
|
|
gtk_menu_attach (GTK_MENU (submenu), w, 0, cols, 0, 1);
|
|
g_signal_connect (G_OBJECT (w),
|
|
"activate",
|
|
G_CALLBACK (cb_menu_default_activate), submenu);
|
|
table_row++;
|
|
}
|
|
for (row = 0; row < rows; row++, table_row++) {
|
|
for (col = 0; col < cols; col++) {
|
|
pos = row * cols + col;
|
|
if (color_names [pos].name == NULL)
|
|
goto custom_colors;
|
|
w = make_colored_menu_item (" ",
|
|
color_names [pos].color);
|
|
gtk_menu_attach (GTK_MENU (submenu), w,
|
|
col, col+1, table_row, table_row+1);
|
|
g_signal_connect (G_OBJECT (w),
|
|
"activate",
|
|
G_CALLBACK (cb_menu_color_activate), submenu);
|
|
}
|
|
}
|
|
|
|
custom_colors :
|
|
if (col > 0)
|
|
row++;
|
|
for (col = 0; col < cols && col < GO_COLOR_GROUP_HISTORY_SIZE; col++) {
|
|
w = make_colored_menu_item (" ", cg->history[col]);
|
|
gtk_menu_attach (GTK_MENU (submenu), w,
|
|
col, col+1, table_row, table_row+1);
|
|
g_signal_connect (G_OBJECT (w),
|
|
"activate",
|
|
G_CALLBACK (cb_menu_color_activate), submenu);
|
|
}
|
|
w = gtk_image_menu_item_new_with_label (_("Custom Color..."));
|
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (w),
|
|
gtk_image_new_from_stock (GTK_STOCK_SELECT_COLOR, GTK_ICON_SIZE_MENU));
|
|
gtk_widget_show_all (w);
|
|
gtk_menu_attach (GTK_MENU (submenu), w, 0, cols, row + 2, row + 3);
|
|
g_signal_connect (G_OBJECT (w),
|
|
"activate",
|
|
G_CALLBACK (cb_menu_custom_activate), submenu);
|
|
|
|
((GOMenuColor *)submenu)->selection = current_color;
|
|
((GOMenuColor *)submenu)->default_color = default_color;
|
|
g_object_set_data_full (G_OBJECT (submenu), "title",
|
|
g_strdup (custom_dialog_title), g_free);
|
|
|
|
gtk_widget_show (submenu);
|
|
|
|
return submenu;
|
|
}
|