gimp/app/widgets/gimpcolordialog.c
Alx Sa 60fb3baa1a widgets: Update index in color-map selection when...
...color-picking on the image.

In GIMP 3.0, we now show a GimpColormapSelection when
users open a color dialogue. However, unlike the RGB color
selector it does not respond to color-picking, instead always
defaulting to index 0.
This patch adds code to get the index of the currently selected
color from the palette, and set the ColormapSelection's selected
index to that.
2025-05-09 23:07:11 +00:00

881 lines
32 KiB
C

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* color_dialog module (C) 1998 Austin Donnelly <austin@greenend.org.uk>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
#include "config/gimpcoreconfig.h"
#include "core/gimp.h"
#include "core/gimp-palettes.h"
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
#include "core/gimpimage-color-profile.h"
#include "core/gimpimage-colormap.h"
#include "core/gimpmarshal.h"
#include "core/gimppalettemru.h"
#include "core/gimpprojection.h"
#include "gimpactiongroup.h"
#include "gimpcolordialog.h"
#include "gimpcolorhistory.h"
#include "gimpcolormapselection.h"
#include "gimpdialogfactory.h"
#include "gimphelp-ids.h"
#include "gimpwidgets-constructors.h"
#include "gimpwidgets-utils.h"
#include "gimp-intl.h"
#define RESPONSE_RESET 1
#define COLOR_AREA_SIZE 20
enum
{
UPDATE,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_USER_CONTEXT_AWARE
};
static void gimp_color_dialog_constructed (GObject *object);
static void gimp_color_dialog_finalize (GObject *object);
static void gimp_color_dialog_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_color_dialog_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_color_dialog_style_updated (GtkWidget *widget);
static void gimp_color_dialog_response (GtkDialog *dialog,
gint response_id);
static void gimp_color_dialog_help_func (const gchar *help_id,
gpointer help_data);
static void gimp_color_dialog_colormap_clicked (GimpColorDialog *dialog,
GimpPaletteEntry *entry,
GdkModifierType state);
static void
gimp_color_dialog_colormap_edit_activate (GimpColorDialog *dialog);
static void
gimp_color_dialog_colormap_add_activate (GimpColorDialog *dialog);
static void gimp_color_dialog_color_changed (GimpColorSelection *selection,
GimpColorDialog *dialog);
static void gimp_color_history_add_clicked (GtkWidget *widget,
GimpColorDialog *dialog);
static void gimp_color_dialog_image_changed (GimpContext *context,
GimpImage *image,
GimpColorDialog *dialog);
static void gimp_color_dialog_update_format (GimpImage *image,
GimpColorDialog *dialog);
static void gimp_color_dialog_update_simulation(GimpImage *image,
GimpColorDialog *dialog);
static void gimp_color_dialog_update_base_type (GimpColorDialog *dialog);
static void gimp_color_dialog_show (GimpColorDialog *dialog);
static void gimp_color_dialog_hide (GimpColorDialog *dialog);
G_DEFINE_TYPE (GimpColorDialog, gimp_color_dialog, GIMP_TYPE_VIEWABLE_DIALOG)
#define parent_class gimp_color_dialog_parent_class
static guint color_dialog_signals[LAST_SIGNAL] = { 0, };
static void
gimp_color_dialog_class_init (GimpColorDialogClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->constructed = gimp_color_dialog_constructed;
object_class->finalize = gimp_color_dialog_finalize;
object_class->set_property = gimp_color_dialog_set_property;
object_class->get_property = gimp_color_dialog_get_property;
dialog_class->response = gimp_color_dialog_response;
widget_class->style_updated = gimp_color_dialog_style_updated;
color_dialog_signals[UPDATE] =
g_signal_new ("update",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GimpColorDialogClass, update),
NULL, NULL,
gimp_marshal_VOID__BOXED_ENUM,
G_TYPE_NONE, 2,
GEGL_TYPE_COLOR,
GIMP_TYPE_COLOR_DIALOG_STATE);
g_object_class_install_property (object_class, PROP_USER_CONTEXT_AWARE,
g_param_spec_boolean ("user-context-aware",
NULL, NULL, FALSE,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_color_dialog_init (GimpColorDialog *dialog)
{
dialog->stack = gtk_stack_new ();
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
dialog->stack, TRUE, TRUE, 0);
gtk_widget_show (dialog->stack);
}
static void
gimp_color_dialog_constructed (GObject *object)
{
GimpColorDialog *dialog = GIMP_COLOR_DIALOG (object);
GimpViewableDialog *viewable_dialog = GIMP_VIEWABLE_DIALOG (object);
GtkWidget *hbox;
GtkWidget *history;
GtkWidget *button;
GtkWidget *image;
G_OBJECT_CLASS (parent_class)->constructed (object);
/** Tab: colormap selection. **/
dialog->colormap_selection = gimp_colormap_selection_new (viewable_dialog->context->gimp->user_context);
gtk_stack_add_named (GTK_STACK (dialog->stack),
dialog->colormap_selection, "colormap");
g_signal_connect_swapped (dialog->colormap_selection, "color-clicked",
G_CALLBACK (gimp_color_dialog_colormap_clicked),
dialog);
g_signal_connect_swapped (dialog->colormap_selection, "color-activated",
G_CALLBACK (gimp_color_dialog_colormap_edit_activate),
dialog);
gtk_widget_show (dialog->colormap_selection);
/* Edit color button */
button = gimp_button_new ();
gtk_button_set_relief (GTK_BUTTON (button), FALSE);
image = gtk_image_new_from_icon_name (GIMP_ICON_EDIT, GTK_ICON_SIZE_LARGE_TOOLBAR);
gtk_container_add (GTK_CONTAINER (button), image);
gtk_widget_show (image);
/* XXX: I use the same icon, tooltip and help id as in
* colormap-actions.c. I wanted to just load these strings from
* the action, but the group is only registered when the Colormap
* dockable is opened.
*/
gimp_help_set_help_data_with_markup (button,
C_("colormap-action", "Edit this color"),
GIMP_HELP_INDEXED_PALETTE_EDIT);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gimp_color_dialog_colormap_edit_activate),
dialog);
gtk_widget_show (button);
gtk_box_pack_start (GTK_BOX (GIMP_COLORMAP_SELECTION (dialog->colormap_selection)->right_vbox), button,
FALSE, FALSE, 0);
/* Add Color button */
button = gimp_button_new ();
gtk_button_set_relief (GTK_BUTTON (button), FALSE);
image = gtk_image_new_from_icon_name (GIMP_ICON_LIST_ADD, GTK_ICON_SIZE_LARGE_TOOLBAR);
gtk_container_add (GTK_CONTAINER (button), image);
gtk_widget_show (image);
gimp_help_set_help_data_with_markup (button,
C_("colormap-action", "Add current foreground color"),
GIMP_HELP_INDEXED_PALETTE_ADD);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gimp_color_dialog_colormap_add_activate),
dialog);
gtk_widget_show (button);
gtk_box_pack_start (GTK_BOX (GIMP_COLORMAP_SELECTION (dialog->colormap_selection)->right_vbox), button,
FALSE, FALSE, 0);
/** Tab: color selection. **/
dialog->selection = gimp_color_selection_new ();
gtk_container_set_border_width (GTK_CONTAINER (dialog->selection), 12);
gtk_stack_add_named (GTK_STACK (dialog->stack), dialog->selection, "color");
gtk_widget_show (dialog->selection);
g_signal_connect (dialog->selection, "color-changed",
G_CALLBACK (gimp_color_dialog_color_changed),
dialog);
/* Color history box. */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_pack_end (GTK_BOX (gimp_color_selection_get_right_vbox (GIMP_COLOR_SELECTION (dialog->selection))),
hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
/* Button for adding to color history. */
button = gimp_icon_button_new (GIMP_ICON_LIST_ADD, NULL);
gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (button), FALSE, FALSE, 0);
gimp_help_set_help_data (button,
_("Add the current color to the color history"),
NULL);
gtk_widget_show (button);
g_signal_connect (button, "clicked",
G_CALLBACK (gimp_color_history_add_clicked),
dialog);
/* Color history table. */
history = gimp_color_history_new (viewable_dialog->context, 12);
gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (history), TRUE, TRUE, 0);
gtk_widget_show (GTK_WIDGET (history));
g_signal_connect_swapped (history, "color-selected",
G_CALLBACK (gimp_color_selection_set_color),
dialog->selection);
g_signal_connect (dialog, "show",
G_CALLBACK (gimp_color_dialog_show),
NULL);
g_signal_connect (dialog, "hide",
G_CALLBACK (gimp_color_dialog_hide),
NULL);
gimp_color_dialog_show (dialog);
}
static void
gimp_color_dialog_finalize (GObject *object)
{
GimpColorDialog *dialog = GIMP_COLOR_DIALOG (object);
GimpViewableDialog *viewable_dialog = GIMP_VIEWABLE_DIALOG (dialog);
g_clear_weak_pointer (&dialog->active_image);
if (dialog->user_context_aware && viewable_dialog->context)
{
GimpContext *user_context = viewable_dialog->context->gimp->user_context;
g_signal_handlers_disconnect_by_func (user_context,
G_CALLBACK (gimp_color_dialog_image_changed),
dialog);
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_color_dialog_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpColorDialog *dialog = GIMP_COLOR_DIALOG (object);
switch (property_id)
{
case PROP_USER_CONTEXT_AWARE:
dialog->user_context_aware = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_color_dialog_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpColorDialog *dialog = GIMP_COLOR_DIALOG (object);
switch (property_id)
{
case PROP_USER_CONTEXT_AWARE:
g_value_set_boolean (value, dialog->user_context_aware);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_color_dialog_style_updated (GtkWidget *widget)
{
GimpColorDialog *dialog = GIMP_COLOR_DIALOG (widget);
GimpColorNotebook *notebook;
GTK_WIDGET_CLASS (parent_class)->style_updated (widget);
notebook =
GIMP_COLOR_NOTEBOOK (gimp_color_selection_get_notebook (GIMP_COLOR_SELECTION (dialog->selection)));
GTK_WIDGET_GET_CLASS (notebook)->style_updated (GTK_WIDGET (notebook));
}
static void
gimp_color_dialog_response (GtkDialog *gtk_dialog,
gint response_id)
{
GimpColorDialog *dialog = GIMP_COLOR_DIALOG (gtk_dialog);
GimpViewableDialog *viewable_dialog = GIMP_VIEWABLE_DIALOG (dialog);
GimpImage *image = NULL;
GimpColormapSelection *colormap_selection;
gint col_index;
GeglColor *color = NULL;
colormap_selection = GIMP_COLORMAP_SELECTION (dialog->colormap_selection);
col_index = gimp_colormap_selection_get_index (colormap_selection, NULL);
if (dialog->colormap_editing && viewable_dialog->context)
{
GimpContext *user_context = viewable_dialog->context->gimp->user_context;
image = gimp_context_get_image (user_context);
}
switch (response_id)
{
case RESPONSE_RESET:
gimp_color_selection_reset (GIMP_COLOR_SELECTION (dialog->selection));
break;
case GTK_RESPONSE_OK:
color = gimp_color_selection_get_color (GIMP_COLOR_SELECTION (dialog->selection));
if (dialog->colormap_editing && image)
{
GeglColor *old_color;
dialog->colormap_editing = FALSE;
/* Restore old color for undo */
old_color = gimp_color_selection_get_old_color (GIMP_COLOR_SELECTION (dialog->selection));
gimp_image_set_colormap_entry (image, col_index, old_color, FALSE);
gimp_image_set_colormap_entry (image, col_index, color, TRUE);
gimp_image_flush (image);
gtk_stack_set_visible_child_name (GTK_STACK (dialog->stack), "colormap");
g_signal_emit (dialog, color_dialog_signals[UPDATE], 0,
color, GIMP_COLOR_DIALOG_UPDATE);
g_object_unref (old_color);
}
else
{
g_signal_emit (dialog, color_dialog_signals[UPDATE], 0,
color, GIMP_COLOR_DIALOG_OK);
}
g_object_unref (color);
break;
default:
color = gimp_color_selection_get_old_color (GIMP_COLOR_SELECTION (dialog->selection));
if (dialog->colormap_editing && image)
{
dialog->colormap_editing = FALSE;
gimp_image_set_colormap_entry (image, col_index, color, FALSE);
gimp_projection_flush (gimp_image_get_projection (image));
gtk_stack_set_visible_child_name (GTK_STACK (dialog->stack), "colormap");
g_signal_emit (dialog, color_dialog_signals[UPDATE], 0,
color, GIMP_COLOR_DIALOG_UPDATE);
}
else
{
g_signal_emit (dialog, color_dialog_signals[UPDATE], 0,
color, GIMP_COLOR_DIALOG_CANCEL);
}
g_object_unref (color);
break;
}
}
/* public functions */
GtkWidget *
gimp_color_dialog_new (GimpViewable *viewable,
GimpContext *context,
gboolean user_context_aware,
const gchar *title,
const gchar *icon_name,
const gchar *desc,
GtkWidget *parent,
GimpDialogFactory *dialog_factory,
const gchar *dialog_identifier,
GeglColor *color,
gboolean wants_updates,
gboolean show_alpha)
{
GimpColorDialog *dialog;
const gchar *role;
gboolean use_header_bar;
g_return_val_if_fail (viewable == NULL || GIMP_IS_VIEWABLE (viewable), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
g_return_val_if_fail (GTK_IS_WIDGET (parent), NULL);
g_return_val_if_fail (dialog_factory == NULL ||
GIMP_IS_DIALOG_FACTORY (dialog_factory), NULL);
g_return_val_if_fail (dialog_factory == NULL || dialog_identifier != NULL,
NULL);
g_return_val_if_fail (GEGL_IS_COLOR (color), NULL);
role = dialog_identifier ? dialog_identifier : "gimp-color-selector";
g_object_get (gtk_settings_get_default (),
"gtk-dialogs-use-header", &use_header_bar,
NULL);
dialog = g_object_new (GIMP_TYPE_COLOR_DIALOG,
"title", title,
"role", role,
"help-func", gimp_color_dialog_help_func,
"help-id", GIMP_HELP_COLOR_DIALOG,
"icon-name", icon_name,
"description", desc,
"context", context,
"user-context-aware", user_context_aware,
"parent", gtk_widget_get_toplevel (parent),
"use-header-bar", use_header_bar,
NULL);
gimp_dialog_add_buttons (GIMP_DIALOG (dialog),
_("_Reset"), RESPONSE_RESET,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_OK"), GTK_RESPONSE_OK,
NULL);
gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
RESPONSE_RESET,
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
if (viewable)
{
gimp_viewable_dialog_set_viewables (GIMP_VIEWABLE_DIALOG (dialog),
g_list_prepend (NULL, viewable), context);
}
else
{
GtkWidget *parent;
parent = gtk_widget_get_parent (GIMP_VIEWABLE_DIALOG (dialog)->icon);
parent = gtk_widget_get_parent (parent);
gtk_widget_hide (parent);
}
dialog->wants_updates = wants_updates;
if (dialog_factory)
{
gimp_dialog_factory_add_foreign (dialog_factory, dialog_identifier,
GTK_WIDGET (dialog),
gimp_widget_get_monitor (parent));
}
gimp_color_selection_set_show_alpha (GIMP_COLOR_SELECTION (dialog->selection),
show_alpha);
g_object_set_data (G_OBJECT (context->gimp->config->color_management),
"gimp-context", context);
gimp_color_selection_set_config (GIMP_COLOR_SELECTION (dialog->selection),
context->gimp->config->color_management);
g_object_set_data (G_OBJECT (context->gimp->config->color_management),
"gimp-context", NULL);
gimp_color_selection_set_color (GIMP_COLOR_SELECTION (dialog->selection),
color);
gimp_color_selection_set_old_color (GIMP_COLOR_SELECTION (dialog->selection),
color);
return GTK_WIDGET (dialog);
}
void
gimp_color_dialog_set_color (GimpColorDialog *dialog,
GeglColor *color)
{
g_return_if_fail (GIMP_IS_COLOR_DIALOG (dialog));
g_return_if_fail (GEGL_IS_COLOR (color));
g_signal_handlers_block_by_func (dialog->selection,
gimp_color_dialog_color_changed,
dialog);
gimp_color_selection_set_color (GIMP_COLOR_SELECTION (dialog->selection),
color);
gimp_color_selection_set_old_color (GIMP_COLOR_SELECTION (dialog->selection),
color);
if (! dialog->user_context_aware)
gimp_color_selection_set_format (GIMP_COLOR_SELECTION (dialog->selection),
gegl_color_get_format (color));
if (dialog->active_image &&
gimp_image_get_base_type (dialog->active_image) == GIMP_INDEXED)
{
GimpColormapSelection *colormap_selection;
gint col_index;
colormap_selection = GIMP_COLORMAP_SELECTION (dialog->colormap_selection);
col_index = gimp_colormap_selection_get_index (colormap_selection, color);
gimp_colormap_selection_set_index (colormap_selection, col_index, NULL);
}
g_signal_handlers_unblock_by_func (dialog->selection,
gimp_color_dialog_color_changed,
dialog);
}
GeglColor *
gimp_color_dialog_get_color (GimpColorDialog *dialog)
{
g_return_val_if_fail (GIMP_IS_COLOR_DIALOG (dialog), NULL);
return gimp_color_selection_get_color (GIMP_COLOR_SELECTION (dialog->selection));
}
/* private functions */
static void
gimp_color_dialog_help_func (const gchar *help_id,
gpointer help_data)
{
GimpColorDialog *dialog = GIMP_COLOR_DIALOG (help_data);
GimpColorNotebook *notebook;
GimpColorSelector *current;
notebook =
GIMP_COLOR_NOTEBOOK (gimp_color_selection_get_notebook (GIMP_COLOR_SELECTION (dialog->selection)));
current = gimp_color_notebook_get_current_selector (notebook);
help_id = GIMP_COLOR_SELECTOR_GET_CLASS (current)->help_id;
gimp_standard_help_func (help_id, NULL);
}
static void
gimp_color_dialog_colormap_clicked (GimpColorDialog *dialog,
GimpPaletteEntry *entry,
GdkModifierType state)
{
gimp_color_dialog_set_color (dialog, entry->color);
if (dialog->wants_updates)
g_signal_emit (dialog, color_dialog_signals[UPDATE], 0,
entry->color, GIMP_COLOR_DIALOG_UPDATE);
}
static void
gimp_color_dialog_colormap_edit_activate (GimpColorDialog *dialog)
{
GimpColormapSelection *colormap_selection;
GeglColor *color;
gint col_index;
dialog->colormap_editing = TRUE;
colormap_selection = GIMP_COLORMAP_SELECTION (dialog->colormap_selection);
col_index = gimp_colormap_selection_get_index (colormap_selection, NULL);
color = gimp_image_get_colormap_entry (dialog->active_image, col_index);
gimp_color_dialog_set_color (dialog, color);
gtk_stack_set_visible_child_name (GTK_STACK (dialog->stack), "color");
}
static void
gimp_color_dialog_colormap_add_activate (GimpColorDialog *dialog)
{
GimpViewableDialog *viewable_dialog = GIMP_VIEWABLE_DIALOG (dialog);
if (dialog->active_image &&
gimp_palette_get_n_colors (gimp_image_get_colormap_palette (dialog->active_image)) < 256 &&
viewable_dialog->context)
{
GimpContext *user_context = viewable_dialog->context->gimp->user_context;
GeglColor *color = gimp_context_get_foreground (user_context);
gimp_image_add_colormap_entry (dialog->active_image, color);
gimp_image_flush (dialog->active_image);
}
}
static void
gimp_color_dialog_color_changed (GimpColorSelection *selection,
GimpColorDialog *dialog)
{
GimpViewableDialog *viewable_dialog = GIMP_VIEWABLE_DIALOG (dialog);
GeglColor *color;
color = gimp_color_selection_get_color (selection);
if (dialog->colormap_editing && viewable_dialog->context)
{
GimpContext *user_context = viewable_dialog->context->gimp->user_context;
GimpImage *image;
image = gimp_context_get_image (user_context);
if (image)
{
GimpColormapSelection *colormap_selection;
gboolean push_undo = FALSE;
gint col_index;
colormap_selection = GIMP_COLORMAP_SELECTION (dialog->colormap_selection);
col_index = gimp_colormap_selection_get_index (colormap_selection, NULL);
if (push_undo)
{
GeglColor *old_color;
old_color = gimp_color_selection_get_old_color (GIMP_COLOR_SELECTION (dialog->selection));
/* Restore old color for undo */
gimp_image_set_colormap_entry (image, col_index, old_color, FALSE);
g_object_unref (old_color);
}
gimp_image_set_colormap_entry (image, col_index, color, push_undo);
if (push_undo)
gimp_image_flush (image);
else
gimp_projection_flush (gimp_image_get_projection (image));
}
}
if (dialog->wants_updates)
g_signal_emit (dialog, color_dialog_signals[UPDATE], 0,
color, GIMP_COLOR_DIALOG_UPDATE);
g_object_unref (color);
}
/* History-adding button callback */
static void
gimp_color_history_add_clicked (GtkWidget *widget,
GimpColorDialog *dialog)
{
GimpViewableDialog *viewable_dialog = GIMP_VIEWABLE_DIALOG (dialog);
GimpPalette *history;
GeglColor *color;
history = gimp_palettes_get_color_history (viewable_dialog->context->gimp);
color = gimp_color_selection_get_color (GIMP_COLOR_SELECTION (dialog->selection));
gimp_palette_mru_add (GIMP_PALETTE_MRU (history), color);
}
/* Context-related callbacks */
static void
gimp_color_dialog_image_changed (GimpContext *context,
GimpImage *image,
GimpColorDialog *dialog)
{
if (dialog->active_image != image)
{
if (dialog->active_image)
{
g_signal_handlers_disconnect_by_func (dialog->active_image,
G_CALLBACK (gimp_color_dialog_update_base_type),
dialog);
g_signal_handlers_disconnect_by_func (dialog->active_image,
gimp_color_dialog_update_simulation,
dialog);
}
g_set_weak_pointer (&dialog->active_image, image);
if (image)
{
g_signal_connect_object (image, "notify::base-type",
G_CALLBACK (gimp_color_dialog_update_base_type),
dialog, G_CONNECT_SWAPPED);
g_signal_connect_object (image, "profile-changed",
G_CALLBACK (gimp_color_dialog_update_format),
dialog, 0);
g_signal_connect_object (image, "simulation-profile-changed",
G_CALLBACK (gimp_color_dialog_update_simulation),
dialog, 0);
g_signal_connect_object (image, "simulation-intent-changed",
G_CALLBACK (gimp_color_dialog_update_simulation),
dialog, 0);
g_signal_connect_object (image, "simulation-bpc-changed",
G_CALLBACK (gimp_color_dialog_update_simulation),
dialog, 0);
gimp_color_dialog_update_simulation (image, dialog);
}
gimp_color_dialog_update_base_type (dialog);
gimp_color_dialog_update_format (image, dialog);
}
}
static void
gimp_color_dialog_update_format (GimpImage *image,
GimpColorDialog *dialog)
{
const Babl *format = NULL;
g_return_if_fail (GIMP_IS_COLOR_DIALOG (dialog));
if (image)
format = gimp_image_get_layer_format (image, FALSE);
gimp_color_selection_set_format (GIMP_COLOR_SELECTION (dialog->selection), format);
}
static void
gimp_color_dialog_update_simulation (GimpImage *image,
GimpColorDialog *dialog)
{
GimpColorProfile *profile = NULL;
GimpColorRenderingIntent intent = GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC;
gboolean bpc = FALSE;
g_return_if_fail (GIMP_IS_COLOR_DIALOG (dialog));
if (image)
{
profile = gimp_image_get_simulation_profile (image);
intent = gimp_image_get_simulation_intent (image);
bpc = gimp_image_get_simulation_bpc (image);
}
gimp_color_selection_set_simulation (GIMP_COLOR_SELECTION (dialog->selection),
profile, intent, bpc);
}
static void
gimp_color_dialog_update_base_type (GimpColorDialog *dialog)
{
if (dialog->active_image &&
gimp_image_get_base_type (dialog->active_image) == GIMP_INDEXED)
{
GimpColormapSelection *colormap_selection;
GeglColor *color;
gint col_index;
gtk_stack_set_visible_child_name (GTK_STACK (dialog->stack), "colormap");
/* Update selected color in palette */
colormap_selection = GIMP_COLORMAP_SELECTION (dialog->colormap_selection);
color = gimp_color_dialog_get_color (dialog);
col_index = gimp_colormap_selection_get_index (colormap_selection, color);
g_object_unref (color);
gimp_colormap_selection_set_index (colormap_selection, col_index, NULL);
}
else
{
gtk_stack_set_visible_child_name (GTK_STACK (dialog->stack), "color");
}
}
static void
gimp_color_dialog_show (GimpColorDialog *dialog)
{
GimpViewableDialog *viewable_dialog = GIMP_VIEWABLE_DIALOG (dialog);
dialog->colormap_editing = FALSE;
if (dialog->user_context_aware && viewable_dialog->context)
{
GimpContext *user_context = viewable_dialog->context->gimp->user_context;
GimpImage *image = gimp_context_get_image (user_context);
g_signal_connect_object (user_context, "image-changed",
G_CALLBACK (gimp_color_dialog_image_changed),
dialog, 0);
g_signal_connect_object (viewable_dialog->context->gimp->config,
"notify::theme",
G_CALLBACK (gimp_color_dialog_style_updated),
dialog, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
g_signal_connect_object (viewable_dialog->context->gimp->config,
"notify::override-theme-icon-size",
G_CALLBACK (gimp_color_dialog_style_updated),
dialog, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
g_signal_connect_object (viewable_dialog->context->gimp->config,
"notify::custom-icon-size",
G_CALLBACK (gimp_color_dialog_style_updated),
dialog, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
gimp_color_dialog_image_changed (viewable_dialog->context,
image, dialog);
gimp_color_dialog_update_base_type (dialog);
gimp_color_dialog_style_updated (GTK_WIDGET (dialog));
}
else
{
gtk_stack_set_visible_child_name (GTK_STACK (dialog->stack), "color");
}
}
static void
gimp_color_dialog_hide (GimpColorDialog *dialog)
{
GimpViewableDialog *viewable_dialog = GIMP_VIEWABLE_DIALOG (dialog);
if (dialog->user_context_aware && viewable_dialog->context)
{
GimpContext *user_context = viewable_dialog->context->gimp->user_context;
g_signal_handlers_disconnect_by_func (user_context,
G_CALLBACK (gimp_color_dialog_image_changed),
dialog);
g_signal_handlers_disconnect_by_func (viewable_dialog->context->gimp->config,
G_CALLBACK (gimp_color_dialog_style_updated),
dialog);
}
}