summaryrefslogtreecommitdiffstats
path: root/libgimpwidgets/gimpcolorhexentry.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:30:19 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:30:19 +0000
commit5c1676dfe6d2f3c837a5e074117b45613fd29a72 (patch)
treecbffb45144febf451e54061db2b21395faf94bfe /libgimpwidgets/gimpcolorhexentry.c
parentInitial commit. (diff)
downloadgimp-5c1676dfe6d2f3c837a5e074117b45613fd29a72.tar.xz
gimp-5c1676dfe6d2f3c837a5e074117b45613fd29a72.zip
Adding upstream version 2.10.34.upstream/2.10.34upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libgimpwidgets/gimpcolorhexentry.c')
-rw-r--r--libgimpwidgets/gimpcolorhexentry.c324
1 files changed, 324 insertions, 0 deletions
diff --git a/libgimpwidgets/gimpcolorhexentry.c b/libgimpwidgets/gimpcolorhexentry.c
new file mode 100644
index 0000000..8c7474f
--- /dev/null
+++ b/libgimpwidgets/gimpcolorhexentry.c
@@ -0,0 +1,324 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpcolorhexentry.c
+ * Copyright (C) 2004 Sven Neumann <sven@gimp.org>
+ *
+ * This library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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 Lesser General Public
+ * License along with this library. If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "libgimpcolor/gimpcolor.h"
+
+#include "gimpwidgetstypes.h"
+
+#include "gimpcellrenderercolor.h"
+#include "gimpcolorhexentry.h"
+#include "gimphelpui.h"
+
+#include "libgimp/libgimp-intl.h"
+
+
+/**
+ * SECTION: gimpcolorhexentry
+ * @title: GimpColorHexEntry
+ * @short_description: Widget for entering a color's hex triplet.
+ *
+ * Widget for entering a color's hex triplet.
+ **/
+
+
+enum
+{
+ COLOR_CHANGED,
+ LAST_SIGNAL
+};
+
+enum
+{
+ COLUMN_NAME,
+ COLUMN_COLOR,
+ NUM_COLUMNS
+};
+
+
+static void gimp_color_hex_entry_constructed (GObject *object);
+
+static gboolean gimp_color_hex_entry_events (GtkWidget *widget,
+ GdkEvent *event);
+
+static gboolean gimp_color_hex_entry_matched (GtkEntryCompletion *completion,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GimpColorHexEntry *entry);
+
+
+G_DEFINE_TYPE (GimpColorHexEntry, gimp_color_hex_entry, GTK_TYPE_ENTRY)
+
+#define parent_class gimp_color_hex_entry_parent_class
+
+static guint entry_signals[LAST_SIGNAL] = { 0 };
+
+
+static void
+gimp_color_hex_entry_class_init (GimpColorHexEntryClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ entry_signals[COLOR_CHANGED] =
+ g_signal_new ("color-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpColorHexEntryClass, color_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ object_class->constructed = gimp_color_hex_entry_constructed;
+
+ klass->color_changed = NULL;
+}
+
+static void
+gimp_color_hex_entry_init (GimpColorHexEntry *entry)
+{
+ GtkEntryCompletion *completion;
+ GtkCellRenderer *cell;
+ GtkListStore *store;
+ GimpRGB *colors;
+ const gchar **names;
+ gint num_colors;
+ gint i;
+
+ /* GtkEntry's minimum size is way too large, set a reasonable one
+ * for our use case
+ */
+ gtk_entry_set_width_chars (GTK_ENTRY (entry), 8);
+
+ gimp_help_set_help_data (GTK_WIDGET (entry),
+ _("Hexadecimal color notation as used in HTML and "
+ "CSS. This entry also accepts CSS color names."),
+ NULL);
+
+ gimp_rgba_set (&entry->color, 0.0, 0.0, 0.0, 1.0);
+
+ store = gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING, GIMP_TYPE_RGB);
+
+ num_colors = gimp_rgb_list_names (&names, &colors);
+
+ for (i = 0; i < num_colors; i++)
+ {
+ GtkTreeIter iter;
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COLUMN_NAME, names[i],
+ COLUMN_COLOR, colors + i,
+ -1);
+ }
+
+ g_free (colors);
+ g_free (names);
+
+ completion = g_object_new (GTK_TYPE_ENTRY_COMPLETION,
+ "model", store,
+ NULL);
+ g_object_unref (store);
+
+ cell = gimp_cell_renderer_color_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), cell, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), cell,
+ "color", COLUMN_COLOR,
+ NULL);
+
+ gtk_entry_completion_set_text_column (completion, COLUMN_NAME);
+
+ gtk_entry_set_completion (GTK_ENTRY (entry), completion);
+ g_object_unref (completion);
+
+ g_signal_connect (entry, "focus-out-event",
+ G_CALLBACK (gimp_color_hex_entry_events),
+ NULL);
+ g_signal_connect (entry, "key-press-event",
+ G_CALLBACK (gimp_color_hex_entry_events),
+ NULL);
+
+ g_signal_connect (completion, "match-selected",
+ G_CALLBACK (gimp_color_hex_entry_matched),
+ entry);
+}
+
+static void
+gimp_color_hex_entry_constructed (GObject *object)
+{
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ gtk_entry_set_text (GTK_ENTRY (object), "000000");
+}
+
+/**
+ * gimp_color_hex_entry_new:
+ *
+ * Return value: a new #GimpColorHexEntry widget
+ *
+ * Since: 2.2
+ **/
+GtkWidget *
+gimp_color_hex_entry_new (void)
+{
+ return g_object_new (GIMP_TYPE_COLOR_HEX_ENTRY, NULL);
+}
+
+/**
+ * gimp_color_hex_entry_set_color:
+ * @entry: a #GimpColorHexEntry widget
+ * @color: pointer to a #GimpRGB
+ *
+ * Sets the color displayed by a #GimpColorHexEntry. If the new color
+ * is different to the previously set color, the "color-changed"
+ * signal is emitted.
+ *
+ * Since: 2.2
+ **/
+void
+gimp_color_hex_entry_set_color (GimpColorHexEntry *entry,
+ const GimpRGB *color)
+{
+ g_return_if_fail (GIMP_IS_COLOR_HEX_ENTRY (entry));
+ g_return_if_fail (color != NULL);
+
+ if (gimp_rgb_distance (&entry->color, color) > 0.0)
+ {
+ gchar buffer[8];
+ guchar r, g, b;
+
+ gimp_rgb_set (&entry->color, color->r, color->g, color->b);
+ gimp_rgb_clamp (&entry->color);
+
+ gimp_rgb_get_uchar (&entry->color, &r, &g, &b);
+ g_snprintf (buffer, sizeof (buffer), "%.2x%.2x%.2x", r, g, b);
+
+ gtk_entry_set_text (GTK_ENTRY (entry), buffer);
+
+ /* move cursor to the end */
+ gtk_editable_set_position (GTK_EDITABLE (entry), -1);
+
+ g_signal_emit (entry, entry_signals[COLOR_CHANGED], 0);
+ }
+}
+
+/**
+ * gimp_color_hex_entry_get_color:
+ * @entry: a #GimpColorHexEntry widget
+ * @color: pointer to a #GimpRGB
+ *
+ * Retrieves the color value displayed by a #GimpColorHexEntry.
+ *
+ * Since: 2.2
+ **/
+void
+gimp_color_hex_entry_get_color (GimpColorHexEntry *entry,
+ GimpRGB *color)
+{
+ g_return_if_fail (GIMP_IS_COLOR_HEX_ENTRY (entry));
+ g_return_if_fail (color != NULL);
+
+ *color = entry->color;
+}
+
+static gboolean
+gimp_color_hex_entry_events (GtkWidget *widget,
+ GdkEvent *event)
+{
+ GimpColorHexEntry *entry = GIMP_COLOR_HEX_ENTRY (widget);
+
+ switch (event->type)
+ {
+ case GDK_KEY_PRESS:
+ {
+ GdkEventKey *kevent = (GdkEventKey *) event;
+
+ if (kevent->keyval != GDK_KEY_Return &&
+ kevent->keyval != GDK_KEY_KP_Enter &&
+ kevent->keyval != GDK_KEY_ISO_Enter)
+ break;
+ /* else fall through */
+ }
+
+ case GDK_FOCUS_CHANGE:
+ {
+ const gchar *text;
+ gchar buffer[8];
+ guchar r, g, b;
+
+ text = gtk_entry_get_text (GTK_ENTRY (widget));
+
+ gimp_rgb_get_uchar (&entry->color, &r, &g, &b);
+ g_snprintf (buffer, sizeof (buffer), "%.2x%.2x%.2x", r, g, b);
+
+ if (g_ascii_strcasecmp (buffer, text) != 0)
+ {
+ GimpRGB color;
+ gsize len = strlen (text);
+
+ if (len > 0 &&
+ (gimp_rgb_parse_hex (&color, text, len) ||
+ gimp_rgb_parse_name (&color, text, -1)))
+ {
+ gimp_color_hex_entry_set_color (entry, &color);
+ }
+ else
+ {
+ gtk_entry_set_text (GTK_ENTRY (entry), buffer);
+ }
+ }
+ }
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+gimp_color_hex_entry_matched (GtkEntryCompletion *completion,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GimpColorHexEntry *entry)
+{
+ gchar *name;
+ GimpRGB color;
+
+ gtk_tree_model_get (model, iter,
+ COLUMN_NAME, &name,
+ -1);
+
+ if (gimp_rgb_parse_name (&color, name, -1))
+ gimp_color_hex_entry_set_color (entry, &color);
+
+ g_free (name);
+
+ return TRUE;
+}