summaryrefslogtreecommitdiffstats
path: root/app/widgets/gimpcoloreditor.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/widgets/gimpcoloreditor.c')
-rw-r--r--app/widgets/gimpcoloreditor.c695
1 files changed, 695 insertions, 0 deletions
diff --git a/app/widgets/gimpcoloreditor.c b/app/widgets/gimpcoloreditor.c
new file mode 100644
index 0000000..cfcfec0
--- /dev/null
+++ b/app/widgets/gimpcoloreditor.c
@@ -0,0 +1,695 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpcoloreditor.c
+ * Copyright (C) 2002 Michael Natterer <mitch@gimp.org>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "widgets-types.h"
+
+#include "config/gimpcoreconfig.h"
+
+#include "core/gimp.h"
+#include "core/gimpcontext.h"
+
+#include "gimpcoloreditor.h"
+#include "gimpcolorhistory.h"
+#include "gimpdocked.h"
+#include "gimpfgbgeditor.h"
+#include "gimpfgbgview.h"
+#include "gimpsessioninfo-aux.h"
+
+#include "gimp-intl.h"
+
+
+enum
+{
+ PROP_0,
+ PROP_CONTEXT
+};
+
+
+static void gimp_color_editor_docked_iface_init (GimpDockedInterface *iface);
+
+static void gimp_color_editor_constructed (GObject *object);
+static void gimp_color_editor_dispose (GObject *object);
+static void gimp_color_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_color_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_color_editor_style_set (GtkWidget *widget,
+ GtkStyle *prev_style);
+
+static void gimp_color_editor_set_aux_info (GimpDocked *docked,
+ GList *aux_info);
+static GList *gimp_color_editor_get_aux_info (GimpDocked *docked);
+static GtkWidget *gimp_color_editor_get_preview (GimpDocked *docked,
+ GimpContext *context,
+ GtkIconSize size);
+static void gimp_color_editor_set_context (GimpDocked *docked,
+ GimpContext *context);
+
+static void gimp_color_editor_fg_changed (GimpContext *context,
+ const GimpRGB *rgb,
+ GimpColorEditor *editor);
+static void gimp_color_editor_bg_changed (GimpContext *context,
+ const GimpRGB *rgb,
+ GimpColorEditor *editor);
+static void gimp_color_editor_color_changed (GimpColorSelector *selector,
+ const GimpRGB *rgb,
+ const GimpHSV *hsv,
+ GimpColorEditor *editor);
+static void gimp_color_editor_tab_toggled (GtkWidget *widget,
+ GimpColorEditor *editor);
+static void gimp_color_editor_fg_bg_notify (GtkWidget *widget,
+ GParamSpec *pspec,
+ GimpColorEditor *editor);
+static void gimp_color_editor_color_picked (GtkWidget *widget,
+ const GimpRGB *rgb,
+ GimpColorEditor *editor);
+static void gimp_color_editor_entry_changed (GimpColorHexEntry *entry,
+ GimpColorEditor *editor);
+
+static void gimp_color_editor_history_selected (GimpColorHistory *history,
+ const GimpRGB *rgb,
+ GimpColorEditor *editor);
+
+G_DEFINE_TYPE_WITH_CODE (GimpColorEditor, gimp_color_editor, GIMP_TYPE_EDITOR,
+ G_IMPLEMENT_INTERFACE (GIMP_TYPE_DOCKED,
+ gimp_color_editor_docked_iface_init))
+
+#define parent_class gimp_color_editor_parent_class
+
+static GimpDockedInterface *parent_docked_iface = NULL;
+
+
+static void
+gimp_color_editor_class_init (GimpColorEditorClass* klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->constructed = gimp_color_editor_constructed;
+ object_class->dispose = gimp_color_editor_dispose;
+ object_class->set_property = gimp_color_editor_set_property;
+ object_class->get_property = gimp_color_editor_get_property;
+
+ widget_class->style_set = gimp_color_editor_style_set;
+
+ g_object_class_install_property (object_class, PROP_CONTEXT,
+ g_param_spec_object ("context",
+ NULL, NULL,
+ GIMP_TYPE_CONTEXT,
+ G_PARAM_CONSTRUCT |
+ GIMP_PARAM_READWRITE));
+}
+
+static void
+gimp_color_editor_docked_iface_init (GimpDockedInterface *iface)
+{
+ parent_docked_iface = g_type_interface_peek_parent (iface);
+
+ if (! parent_docked_iface)
+ parent_docked_iface = g_type_default_interface_peek (GIMP_TYPE_DOCKED);
+
+ iface->get_preview = gimp_color_editor_get_preview;
+ iface->set_aux_info = gimp_color_editor_set_aux_info;
+ iface->get_aux_info = gimp_color_editor_get_aux_info;
+ iface->set_context = gimp_color_editor_set_context;
+}
+
+static void
+gimp_color_editor_init (GimpColorEditor *editor)
+{
+ GtkWidget *notebook;
+ GtkWidget *hbox;
+ GtkWidget *button;
+ gint content_spacing;
+ gint button_spacing;
+ GtkIconSize button_icon_size;
+ GimpRGB rgb;
+ GimpHSV hsv;
+ GList *list;
+ GSList *group;
+
+ editor->context = NULL;
+ editor->edit_bg = FALSE;
+
+ gimp_rgba_set (&rgb, 0.0, 0.0, 0.0, 1.0);
+ gimp_rgb_to_hsv (&rgb, &hsv);
+
+ gtk_widget_style_get (GTK_WIDGET (editor),
+ "content-spacing", &content_spacing,
+ "button-spacing", &button_spacing,
+ "button-icon-size", &button_icon_size,
+ NULL);
+
+ editor->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, button_spacing);
+ gtk_box_set_homogeneous (GTK_BOX (editor->hbox), TRUE);
+ gtk_box_pack_start (GTK_BOX (editor), editor->hbox, FALSE, FALSE, 0);
+ gtk_widget_show (editor->hbox);
+
+ editor->notebook = gimp_color_selector_new (GIMP_TYPE_COLOR_NOTEBOOK,
+ &rgb, &hsv,
+ GIMP_COLOR_SELECTOR_RED);
+ gimp_color_selector_set_show_alpha (GIMP_COLOR_SELECTOR (editor->notebook),
+ FALSE);
+ gtk_box_pack_start (GTK_BOX (editor), editor->notebook,
+ TRUE, TRUE, content_spacing);
+ gtk_widget_show (editor->notebook);
+
+ g_signal_connect (editor->notebook, "color-changed",
+ G_CALLBACK (gimp_color_editor_color_changed),
+ editor);
+
+ notebook = GIMP_COLOR_NOTEBOOK (editor->notebook)->notebook;
+
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
+
+ gimp_color_notebook_set_has_page (GIMP_COLOR_NOTEBOOK (editor->notebook),
+ GIMP_TYPE_COLOR_SCALES, TRUE);
+
+ group = NULL;
+
+ for (list = GIMP_COLOR_NOTEBOOK (editor->notebook)->selectors;
+ list;
+ list = g_list_next (list))
+ {
+ GimpColorSelector *selector;
+ GimpColorSelectorClass *selector_class;
+ GtkWidget *button;
+ GtkWidget *image;
+
+ selector = GIMP_COLOR_SELECTOR (list->data);
+ selector_class = GIMP_COLOR_SELECTOR_GET_CLASS (selector);
+
+ button = gtk_radio_button_new (group);
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
+ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
+ gtk_box_pack_start (GTK_BOX (editor->hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+
+ image = gtk_image_new_from_icon_name (selector_class->icon_name,
+ GTK_ICON_SIZE_BUTTON);
+ gtk_container_add (GTK_CONTAINER (button), image);
+ gtk_widget_show (image);
+
+ gimp_help_set_help_data (button,
+ selector_class->name, selector_class->help_id);
+
+ g_object_set_data (G_OBJECT (button), "selector", selector);
+ g_object_set_data (G_OBJECT (selector), "button", button);
+
+ g_signal_connect (button, "toggled",
+ G_CALLBACK (gimp_color_editor_tab_toggled),
+ editor);
+ }
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+ gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
+ gtk_box_pack_start (GTK_BOX (editor), hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
+
+ /* FG/BG editor */
+ editor->fg_bg = gimp_fg_bg_editor_new (NULL);
+ gtk_box_pack_start (GTK_BOX (hbox), editor->fg_bg, TRUE, TRUE, 0);
+ gtk_widget_show (editor->fg_bg);
+
+ g_signal_connect (editor->fg_bg, "notify::active-color",
+ G_CALLBACK (gimp_color_editor_fg_bg_notify),
+ editor);
+
+ /* The color picker */
+ button = gimp_pick_button_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ g_signal_connect (button, "color-picked",
+ G_CALLBACK (gimp_color_editor_color_picked),
+ editor);
+
+ /* The hex triplet entry */
+ editor->hex_entry = gimp_color_hex_entry_new ();
+ gtk_box_pack_end (GTK_BOX (hbox), editor->hex_entry, TRUE, TRUE, 0);
+ gtk_widget_show (editor->hex_entry);
+
+ g_signal_connect (editor->hex_entry, "color-changed",
+ G_CALLBACK (gimp_color_editor_entry_changed),
+ editor);
+}
+
+static void
+gimp_color_editor_constructed (GObject *object)
+{
+ GimpColorEditor *editor = GIMP_COLOR_EDITOR (object);
+ GtkWidget *history;
+
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ /* The color history */
+ history = gimp_color_history_new (editor->context, 12);
+ gtk_box_pack_end (GTK_BOX (editor), history, FALSE, FALSE, 0);
+ gtk_widget_show (history);
+
+ g_signal_connect (history, "color-selected",
+ G_CALLBACK (gimp_color_editor_history_selected),
+ editor);
+}
+
+static void
+gimp_color_editor_dispose (GObject *object)
+{
+ GimpColorEditor *editor = GIMP_COLOR_EDITOR (object);
+
+ if (editor->context)
+ gimp_docked_set_context (GIMP_DOCKED (editor), NULL);
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gimp_color_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ case PROP_CONTEXT:
+ gimp_docked_set_context (GIMP_DOCKED (object),
+ g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_color_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpColorEditor *editor = GIMP_COLOR_EDITOR (object);
+
+ switch (property_id)
+ {
+ case PROP_CONTEXT:
+ g_value_set_object (value, editor->context);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static GtkWidget *
+gimp_color_editor_get_preview (GimpDocked *docked,
+ GimpContext *context,
+ GtkIconSize size)
+{
+ GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (docked));
+ GtkWidget *preview;
+ gint width;
+ gint height;
+
+ preview = gimp_fg_bg_view_new (context);
+
+ if (gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
+ gtk_widget_set_size_request (preview, width, height);
+
+ return preview;
+}
+
+#define AUX_INFO_CURRENT_PAGE "current-page"
+
+static void
+gimp_color_editor_set_aux_info (GimpDocked *docked,
+ GList *aux_info)
+{
+ GimpColorEditor *editor = GIMP_COLOR_EDITOR (docked);
+ GtkWidget *notebook = GIMP_COLOR_NOTEBOOK (editor->notebook)->notebook;
+ GList *list;
+
+ parent_docked_iface->set_aux_info (docked, aux_info);
+
+ for (list = aux_info; list; list = g_list_next (list))
+ {
+ GimpSessionInfoAux *aux = list->data;
+
+ if (! strcmp (aux->name, AUX_INFO_CURRENT_PAGE))
+ {
+ GList *children;
+ GList *child;
+
+ children = gtk_container_get_children (GTK_CONTAINER (notebook));
+
+ for (child = children; child; child = g_list_next (child))
+ {
+ if (! strcmp (G_OBJECT_TYPE_NAME (child->data), aux->value))
+ {
+ GtkWidget *button;
+
+ button = g_object_get_data (G_OBJECT (child->data), "button");
+
+ if (button)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+ TRUE);
+
+ break;
+ }
+ }
+
+ g_list_free (children);
+ }
+ }
+}
+
+static GList *
+gimp_color_editor_get_aux_info (GimpDocked *docked)
+{
+ GimpColorEditor *editor = GIMP_COLOR_EDITOR (docked);
+ GimpColorNotebook *notebook = GIMP_COLOR_NOTEBOOK (editor->notebook);
+ GList *aux_info;
+
+ aux_info = parent_docked_iface->get_aux_info (docked);
+
+ if (notebook->cur_page)
+ {
+ GimpSessionInfoAux *aux;
+
+ aux = gimp_session_info_aux_new (AUX_INFO_CURRENT_PAGE,
+ G_OBJECT_TYPE_NAME (notebook->cur_page));
+ aux_info = g_list_append (aux_info, aux);
+ }
+
+ return aux_info;
+}
+
+static void
+gimp_color_editor_set_context (GimpDocked *docked,
+ GimpContext *context)
+{
+ GimpColorEditor *editor = GIMP_COLOR_EDITOR (docked);
+
+ if (context == editor->context)
+ return;
+
+ if (editor->context)
+ {
+ g_signal_handlers_disconnect_by_func (editor->context,
+ gimp_color_editor_fg_changed,
+ editor);
+ g_signal_handlers_disconnect_by_func (editor->context,
+ gimp_color_editor_bg_changed,
+ editor);
+
+ g_object_unref (editor->context);
+ }
+
+ editor->context = context;
+
+ if (editor->context)
+ {
+ GimpRGB rgb;
+
+ g_object_ref (editor->context);
+
+ g_signal_connect (editor->context, "foreground-changed",
+ G_CALLBACK (gimp_color_editor_fg_changed),
+ editor);
+ g_signal_connect (editor->context, "background-changed",
+ G_CALLBACK (gimp_color_editor_bg_changed),
+ editor);
+
+ if (editor->edit_bg)
+ {
+ gimp_context_get_background (editor->context, &rgb);
+ gimp_color_editor_bg_changed (editor->context, &rgb, editor);
+ }
+ else
+ {
+ gimp_context_get_foreground (editor->context, &rgb);
+ gimp_color_editor_fg_changed (editor->context, &rgb, editor);
+ }
+
+ g_object_set_data (G_OBJECT (context->gimp->config->color_management),
+ "gimp-context", editor->context);
+
+ gimp_color_selector_set_config (GIMP_COLOR_SELECTOR (editor->notebook),
+ context->gimp->config->color_management);
+
+ g_object_set_data (G_OBJECT (context->gimp->config->color_management),
+ "gimp-context", NULL);
+ }
+
+ gimp_fg_bg_editor_set_context (GIMP_FG_BG_EDITOR (editor->fg_bg), context);
+}
+
+GtkWidget *
+gimp_color_editor_new (GimpContext *context)
+{
+ return g_object_new (GIMP_TYPE_COLOR_EDITOR,
+ "context", context,
+ NULL);
+}
+
+static void
+gimp_color_editor_style_set (GtkWidget *widget,
+ GtkStyle *prev_style)
+{
+ GimpColorEditor *editor = GIMP_COLOR_EDITOR (widget);
+
+ GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style);
+
+ if (editor->hbox)
+ gimp_editor_set_box_style (GIMP_EDITOR (editor), GTK_BOX (editor->hbox));
+}
+
+
+static void
+gimp_color_editor_set_color (GimpColorEditor *editor,
+ const GimpRGB *rgb)
+{
+ GimpHSV hsv;
+
+ gimp_rgb_to_hsv (rgb, &hsv);
+
+ g_signal_handlers_block_by_func (editor->notebook,
+ gimp_color_editor_color_changed,
+ editor);
+
+ gimp_color_selector_set_color (GIMP_COLOR_SELECTOR (editor->notebook),
+ rgb, &hsv);
+
+ g_signal_handlers_unblock_by_func (editor->notebook,
+ gimp_color_editor_color_changed,
+ editor);
+
+ g_signal_handlers_block_by_func (editor->hex_entry,
+ gimp_color_editor_entry_changed,
+ editor);
+
+ gimp_color_hex_entry_set_color (GIMP_COLOR_HEX_ENTRY (editor->hex_entry),
+ rgb);
+
+ g_signal_handlers_unblock_by_func (editor->hex_entry,
+ gimp_color_editor_entry_changed,
+ editor);
+}
+
+static void
+gimp_color_editor_fg_changed (GimpContext *context,
+ const GimpRGB *rgb,
+ GimpColorEditor *editor)
+{
+ if (! editor->edit_bg)
+ gimp_color_editor_set_color (editor, rgb);
+}
+
+static void
+gimp_color_editor_bg_changed (GimpContext *context,
+ const GimpRGB *rgb,
+ GimpColorEditor *editor)
+{
+ if (editor->edit_bg)
+ gimp_color_editor_set_color (editor, rgb);
+}
+
+static void
+gimp_color_editor_color_changed (GimpColorSelector *selector,
+ const GimpRGB *rgb,
+ const GimpHSV *hsv,
+ GimpColorEditor *editor)
+{
+ if (editor->context)
+ {
+ if (editor->edit_bg)
+ {
+ g_signal_handlers_block_by_func (editor->context,
+ gimp_color_editor_bg_changed,
+ editor);
+
+ gimp_context_set_background (editor->context, rgb);
+
+ g_signal_handlers_unblock_by_func (editor->context,
+ gimp_color_editor_bg_changed,
+ editor);
+ }
+ else
+ {
+ g_signal_handlers_block_by_func (editor->context,
+ gimp_color_editor_fg_changed,
+ editor);
+
+ gimp_context_set_foreground (editor->context, rgb);
+
+ g_signal_handlers_unblock_by_func (editor->context,
+ gimp_color_editor_fg_changed,
+ editor);
+ }
+ }
+
+ g_signal_handlers_block_by_func (editor->hex_entry,
+ gimp_color_editor_entry_changed,
+ editor);
+
+ gimp_color_hex_entry_set_color (GIMP_COLOR_HEX_ENTRY (editor->hex_entry),
+ rgb);
+
+ g_signal_handlers_unblock_by_func (editor->hex_entry,
+ gimp_color_editor_entry_changed,
+ editor);
+}
+
+static void
+gimp_color_editor_tab_toggled (GtkWidget *widget,
+ GimpColorEditor *editor)
+{
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
+ {
+ GtkWidget *selector;
+
+ selector = g_object_get_data (G_OBJECT (widget), "selector");
+
+ if (selector)
+ {
+ GtkWidget *notebook;
+ gint page_num;
+
+ notebook = GIMP_COLOR_NOTEBOOK (editor->notebook)->notebook;
+
+ page_num = gtk_notebook_page_num (GTK_NOTEBOOK (notebook), selector);
+
+ if (page_num >= 0)
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), page_num);
+ }
+ }
+}
+
+static void
+gimp_color_editor_fg_bg_notify (GtkWidget *widget,
+ GParamSpec *pspec,
+ GimpColorEditor *editor)
+{
+ gboolean edit_bg;
+
+ edit_bg = (GIMP_FG_BG_EDITOR (widget)->active_color ==
+ GIMP_ACTIVE_COLOR_BACKGROUND);
+
+ if (edit_bg != editor->edit_bg)
+ {
+ editor->edit_bg = edit_bg;
+
+ if (editor->context)
+ {
+ GimpRGB rgb;
+
+ if (edit_bg)
+ {
+ gimp_context_get_background (editor->context, &rgb);
+ gimp_color_editor_bg_changed (editor->context, &rgb, editor);
+ }
+ else
+ {
+ gimp_context_get_foreground (editor->context, &rgb);
+ gimp_color_editor_fg_changed (editor->context, &rgb, editor);
+ }
+ }
+ }
+}
+
+static void
+gimp_color_editor_color_picked (GtkWidget *widget,
+ const GimpRGB *rgb,
+ GimpColorEditor *editor)
+{
+ if (editor->context)
+ {
+ if (editor->edit_bg)
+ gimp_context_set_background (editor->context, rgb);
+ else
+ gimp_context_set_foreground (editor->context, rgb);
+ }
+}
+
+static void
+gimp_color_editor_entry_changed (GimpColorHexEntry *entry,
+ GimpColorEditor *editor)
+{
+ GimpRGB rgb;
+
+ gimp_color_hex_entry_get_color (entry, &rgb);
+
+ if (editor->context)
+ {
+ if (editor->edit_bg)
+ gimp_context_set_background (editor->context, &rgb);
+ else
+ gimp_context_set_foreground (editor->context, &rgb);
+ }
+}
+
+static void
+gimp_color_editor_history_selected (GimpColorHistory *history,
+ const GimpRGB *rgb,
+ GimpColorEditor *editor)
+{
+ if (editor->context)
+ {
+ if (editor->edit_bg)
+ gimp_context_set_background (editor->context, rgb);
+ else
+ gimp_context_set_foreground (editor->context, rgb);
+ }
+}