--- /dev/null
+/*
+ * color-combo-menu.c
+ * Copyright (C) 2008 Jim Evins <evins@snaught.com>.
+ *
+ * This file is part of gLabels.
+ *
+ * gLabels is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gLabels 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "color-combo-menu.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "color-combo-color-menu-item.h"
+#include "color-history-model.h"
+#include "color.h"
+#include "marshal.h"
+
+
+/*===========================================*/
+/* Private macros and constants. */
+/*===========================================*/
+
+#define PALETTE_COLS 7
+#define PALETTE_ROWS (G_N_ELEMENTS(color_table)/PALETTE_COLS + (G_N_ELEMENTS(color_table)%PALETTE_COLS ? 1 : 0))
+
+#define ROW_DEFAULT (0)
+#define ROW_SEP_1 (ROW_DEFAULT + 1)
+#define ROW_PALETTE (ROW_SEP_1 + 1)
+#define ROW_SEP_2 (ROW_PALETTE + PALETTE_ROWS)
+#define ROW_HISTORY (ROW_SEP_2 + 1)
+#define ROW_SEP_3 (ROW_HISTORY + 1)
+#define ROW_CUSTOM (ROW_SEP_3 + 1)
+
+/*===========================================*/
+/* Private types */
+/*===========================================*/
+
+struct _glColorComboMenuPrivate {
+
+ GtkWidget *default_menu_item;
+ GtkWidget *custom_menu_item;
+
+ GtkWidget *history_menu_item[PALETTE_COLS];
+
+ guint color;
+};
+
+enum {
+ COLOR_CHANGED,
+ LAST_SIGNAL
+};
+
+typedef struct {
+ guint color;
+ gchar *name;
+} ColorTableEntry;
+
+
+/*===========================================*/
+/* Private globals */
+/*===========================================*/
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static ColorTableEntry color_table[] =
+{
+
+ { GL_COLOR (139, 0, 0), N_("Dark Red") },
+ { GL_COLOR (165, 42, 42), N_("Brown") },
+ { GL_COLOR (205, 149, 12), N_("Dark Goldenrod") },
+ { GL_COLOR ( 0, 100, 0), N_("Dark Green") },
+ { GL_COLOR ( 0, 139, 139), N_("Dark Cyan") },
+ { GL_COLOR ( 0, 0, 128), N_("Navy Blue") },
+ { GL_COLOR (148, 0, 211), N_("Dark Violet") },
+
+ { GL_COLOR (255, 0, 0), N_("Red") },
+ { GL_COLOR (255, 165, 0), N_("Orange") },
+ { GL_COLOR (205, 205, 0), N_("Dark Yellow") },
+ { GL_COLOR ( 0, 205, 0), N_("Medium green") },
+ { GL_COLOR ( 64, 224, 208), N_("Turquoise") },
+ { GL_COLOR ( 0, 0, 255), N_("Blue") },
+ { GL_COLOR (160, 32, 240), N_("Purple") },
+
+ { GL_COLOR (250, 128, 114), N_("Salmon") },
+ { GL_COLOR (255, 215, 0), N_("Gold") },
+ { GL_COLOR (255, 255, 0), N_("Yellow") },
+ { GL_COLOR ( 0, 255, 0), N_("Green") },
+ { GL_COLOR ( 0, 255, 255), N_("Cyan") },
+ { GL_COLOR (135, 206, 235), N_("SkyBlue") },
+ { GL_COLOR (238, 130, 238), N_("Violet") },
+
+ { GL_COLOR (255, 192, 203), N_("Pink") },
+ { GL_COLOR (255, 246, 143), N_("Khaki") },
+ { GL_COLOR (255, 255, 224), N_("Light Yellow") },
+ { GL_COLOR (144, 238, 144), N_("Light Green") },
+ { GL_COLOR (224, 255, 255), N_("Light Cyan") },
+ { GL_COLOR (198, 226, 255), N_("Slate Gray") },
+ { GL_COLOR (216, 191, 216), N_("Thistle") },
+
+ { GL_COLOR (255, 255, 255), N_("White") },
+ /* xgettext: no-c-format */
+ { GL_COLOR (230, 230, 230), N_("10% Gray") },
+ /* xgettext: no-c-format */
+ { GL_COLOR (192, 192, 192), N_("25% Gray") },
+ /* xgettext: no-c-format */
+ { GL_COLOR (153, 153, 153), N_("40% Gray") },
+ /* xgettext: no-c-format */
+ { GL_COLOR (128, 128, 128), N_("50% Gray") },
+ /* xgettext: no-c-format */
+ { GL_COLOR (102, 102, 102), N_("60% Gray") },
+ { GL_COLOR ( 0, 0, 0), N_("Black") },
+
+};
+
+static glColorHistoryModel *custom_color_history = NULL;
+
+
+/*===========================================*/
+/* Local function prototypes */
+/*===========================================*/
+
+static void gl_color_combo_menu_finalize (GObject *object);
+
+static void load_custom_color_history (glColorComboMenu *this);
+
+static gboolean map_event_cb (GtkWidget *widget,
+ GdkEventAny *event);
+
+static void default_menu_item_activate_cb (glColorComboMenu *this);
+static void custom_menu_item_activate_cb (glColorComboMenu *this);
+
+static void palette_menu_item_activate_cb (GtkMenuItem *item,
+ glColorComboMenu *this);
+
+static void history_menu_item_activate_cb (GtkMenuItem *item,
+ glColorComboMenu *this);
+
+
+/****************************************************************************/
+/* Boilerplate Object stuff. */
+/****************************************************************************/
+G_DEFINE_TYPE (glColorComboMenu, gl_color_combo_menu, GTK_TYPE_MENU)
+
+
+/*****************************************************************************/
+/* Class Init Function. */
+/*****************************************************************************/
+static void
+gl_color_combo_menu_class_init (glColorComboMenuClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+ gl_color_combo_menu_parent_class = g_type_class_peek_parent (class);
+
+ gobject_class->finalize = gl_color_combo_menu_finalize;
+
+ widget_class->map_event = map_event_cb;
+
+ signals[COLOR_CHANGED] =
+ g_signal_new ("color_changed",
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (glColorComboMenuClass, color_changed),
+ NULL, NULL,
+ gl_marshal_VOID__UINT_BOOLEAN,
+ G_TYPE_NONE,
+ 2, G_TYPE_POINTER, G_TYPE_BOOLEAN);
+}
+
+
+/*****************************************************************************/
+/* Object Instance Init Function. */
+/*****************************************************************************/
+static void
+gl_color_combo_menu_init (glColorComboMenu *this)
+{
+ GtkWidget *separator_menu_item;
+ gint i, i_row, i_col;
+ GtkWidget *palette_menu_item;
+
+
+ /*
+ * Initialize history, if needed.
+ */
+ if ( !custom_color_history )
+ {
+ custom_color_history = gl_color_history_model_new (PALETTE_COLS);
+ }
+
+
+ this->priv = g_new0 (glColorComboMenuPrivate, 1);
+
+ this->priv->default_menu_item = gtk_menu_item_new_with_label ("");
+ gtk_menu_attach (GTK_MENU (this), this->priv->default_menu_item,
+ 0, PALETTE_COLS, ROW_DEFAULT, ROW_DEFAULT+1);
+
+ separator_menu_item = gtk_separator_menu_item_new ();
+ gtk_menu_attach (GTK_MENU (this), separator_menu_item,
+ 0, PALETTE_COLS, ROW_SEP_1, ROW_SEP_1+1);
+
+ for ( i=0; i < G_N_ELEMENTS(color_table); i++ )
+ {
+
+ i_row = i / PALETTE_COLS;
+ i_col = i % PALETTE_COLS;
+
+ palette_menu_item = gl_color_combo_color_menu_item_new (i,
+ color_table[i].color,
+ gettext (color_table[i].name));
+ g_signal_connect (palette_menu_item, "activate",
+ G_CALLBACK (palette_menu_item_activate_cb), this);
+
+ gtk_menu_attach (GTK_MENU (this), palette_menu_item,
+ i_col, i_col+1,
+ ROW_PALETTE+i_row, ROW_PALETTE+i_row+1);
+ }
+
+ separator_menu_item = gtk_separator_menu_item_new ();
+ gtk_menu_attach (GTK_MENU (this), separator_menu_item,
+ 0, PALETTE_COLS, ROW_SEP_2, ROW_SEP_2+1);
+
+ for ( i=0; i < PALETTE_COLS; i++ )
+ {
+ this->priv->history_menu_item[i] =
+ gl_color_combo_color_menu_item_new (i, 0, NULL);
+ gtk_widget_set_sensitive (this->priv->history_menu_item[i], FALSE);
+ g_signal_connect (this->priv->history_menu_item[i], "activate",
+ G_CALLBACK (history_menu_item_activate_cb), this);
+ gtk_menu_attach (GTK_MENU (this), this->priv->history_menu_item[i],
+ i, i+1,
+ ROW_HISTORY, ROW_HISTORY+1);
+ }
+
+ separator_menu_item = gtk_separator_menu_item_new ();
+ gtk_menu_attach (GTK_MENU (this), separator_menu_item,
+ 0, PALETTE_COLS, ROW_SEP_3, ROW_SEP_3+1);
+
+ this->priv->custom_menu_item = gtk_menu_item_new_with_label (_("Custom Color"));
+ gtk_menu_attach (GTK_MENU (this), this->priv->custom_menu_item,
+ 0, PALETTE_COLS, ROW_CUSTOM, ROW_CUSTOM+1);
+
+ g_signal_connect_swapped (this->priv->default_menu_item, "activate",
+ G_CALLBACK (default_menu_item_activate_cb), this);
+ g_signal_connect_swapped (this->priv->custom_menu_item, "activate",
+ G_CALLBACK (custom_menu_item_activate_cb), this);
+
+}
+
+
+/*****************************************************************************/
+/* Finalize Method. */
+/*****************************************************************************/
+static void
+gl_color_combo_menu_finalize (GObject *object)
+{
+ glColorComboMenu *this = GL_COLOR_COMBO_MENU (object);
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GL_IS_COLOR_COMBO_MENU (object));
+
+ g_free (this->priv);
+
+ G_OBJECT_CLASS (gl_color_combo_menu_parent_class)->finalize (object);
+}
+
+
+/*****************************************************************************/
+/** New Object Generator. */
+/*****************************************************************************/
+GtkWidget *
+gl_color_combo_menu_new (const gchar *default_label,
+ guint color)
+{
+ glColorComboMenu *this;
+
+ this = g_object_new (gl_color_combo_menu_get_type (), NULL);
+
+ gtk_label_set_text ( GTK_LABEL (gtk_bin_get_child (GTK_BIN (this->priv->default_menu_item))),
+ default_label);
+
+ this->priv->color = color;
+
+ return GTK_WIDGET (this);
+}
+
+
+/*****************************************************************************/
+/* Load menu with custom color history. */
+/*****************************************************************************/
+static void
+load_custom_color_history (glColorComboMenu *this)
+{
+ guint i;
+ guint color;
+ gchar *tip;
+
+ for ( i=0; i < PALETTE_COLS; i++ )
+ {
+ color = gl_color_history_model_get_color (custom_color_history, i);
+
+ if (color)
+ {
+ tip = g_strdup_printf (_("Custom Color #%u"), i+1);
+
+ gl_color_combo_color_menu_item_set_color (GL_COLOR_COMBO_COLOR_MENU_ITEM (this->priv->history_menu_item[i]),
+ i,
+ color,
+ tip);
+ g_free (tip);
+ gtk_widget_set_sensitive (this->priv->history_menu_item[i], TRUE);
+ }
+ }
+}
+
+
+/*****************************************************************************/
+/* Map event callback. */
+/*****************************************************************************/
+static gboolean
+map_event_cb (GtkWidget *widget,
+ GdkEventAny *event)
+{
+ glColorComboMenu *this = GL_COLOR_COMBO_MENU (widget);
+
+ load_custom_color_history (this);
+
+ return FALSE;
+}
+
+
+/*****************************************************************************/
+/* "Default" menu_item activate callback. */
+/*****************************************************************************/
+static void
+default_menu_item_activate_cb (glColorComboMenu *this)
+{
+ g_signal_emit (this, signals[COLOR_CHANGED], 0,
+ NULL, TRUE);
+
+ gtk_widget_hide (GTK_WIDGET (this));
+}
+
+
+/*****************************************************************************/
+/* "Custom color" menu_item activate callback. */
+/*****************************************************************************/
+static void
+custom_menu_item_activate_cb (glColorComboMenu *this)
+{
+ GtkWidget *custom_dialog;
+ GtkWidget *colorsel;
+ gint response;
+ GdkColor color;
+
+ gtk_widget_hide (GTK_WIDGET (this));
+
+ custom_dialog = gtk_color_selection_dialog_new (_("Custom Color"));
+
+ colorsel = gtk_color_selection_dialog_get_color_selection (GTK_COLOR_SELECTION_DIALOG (custom_dialog));
+ color.red = GL_COLOR_F_RED (this->priv->color) * 65535;
+ color.green = GL_COLOR_F_GREEN (this->priv->color) * 65535;
+ color.blue = GL_COLOR_F_BLUE (this->priv->color) * 65535;
+
+ gtk_color_selection_set_current_color (GTK_COLOR_SELECTION (colorsel),
+ &color);
+
+ response = gtk_dialog_run (GTK_DIALOG (custom_dialog));
+
+ switch (response) {
+
+ case GTK_RESPONSE_OK:
+ gtk_color_selection_get_current_color (GTK_COLOR_SELECTION (colorsel),
+ &color);
+ this->priv->color = GL_COLOR ((color.red >>8),
+ (color.green >>8),
+ (color.blue >>8));
+
+ gl_color_history_model_add_color (custom_color_history,
+ this->priv->color);
+
+ g_signal_emit (this, signals[COLOR_CHANGED], 0,
+ this->priv->color, FALSE);
+
+ gtk_widget_destroy (custom_dialog);
+ break;
+ default:
+ gtk_widget_destroy (custom_dialog);
+ break;
+ }
+}
+
+
+/*****************************************************************************/
+/* Palette color changed callback. */
+/*****************************************************************************/
+static void
+palette_menu_item_activate_cb (GtkMenuItem *item,
+ glColorComboMenu *this)
+{
+ gint i;
+
+ i = gl_color_combo_color_menu_item_get_id (GL_COLOR_COMBO_COLOR_MENU_ITEM (item));
+
+ this->priv->color = color_table[i].color;
+
+ g_signal_emit (this, signals[COLOR_CHANGED], 0,
+ this->priv->color, FALSE);
+
+ gtk_widget_hide (GTK_WIDGET (this));
+}
+
+/*****************************************************************************/
+/* History color menu item callback. */
+/*****************************************************************************/
+static void
+history_menu_item_activate_cb (GtkMenuItem *item,
+ glColorComboMenu *this)
+{
+ gint i;
+
+ i = gl_color_combo_color_menu_item_get_id (GL_COLOR_COMBO_COLOR_MENU_ITEM (item));
+
+ this->priv->color = gl_color_history_model_get_color (custom_color_history, i);
+
+ g_signal_emit (this, signals[COLOR_CHANGED], 0,
+ this->priv->color, FALSE);
+
+ gtk_widget_hide (GTK_WIDGET (this));
+}
+
+
+
+/*
+ * Local Variables: -- emacs
+ * mode: C -- emacs
+ * c-basic-offset: 8 -- emacs
+ * tab-width: 8 -- emacs
+ * indent-tabs-mode: nil -- emacs
+ * End: -- emacs
+ */