diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 03:13:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 03:13:10 +0000 |
commit | 3c57dd931145d43f2b0aef96c4d178135956bf91 (patch) | |
tree | 3de698981e9f0cc2c4f9569b19a5f3595e741f6b /app/widgets/gimppaletteeditor.c | |
parent | Initial commit. (diff) | |
download | gimp-3c57dd931145d43f2b0aef96c4d178135956bf91.tar.xz gimp-3c57dd931145d43f2b0aef96c4d178135956bf91.zip |
Adding upstream version 2.10.36.upstream/2.10.36
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'app/widgets/gimppaletteeditor.c')
-rw-r--r-- | app/widgets/gimppaletteeditor.c | 967 |
1 files changed, 967 insertions, 0 deletions
diff --git a/app/widgets/gimppaletteeditor.c b/app/widgets/gimppaletteeditor.c new file mode 100644 index 0000000..b5f6285 --- /dev/null +++ b/app/widgets/gimppaletteeditor.c @@ -0,0 +1,967 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * 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 "libgimpbase/gimpbase.h" +#include "libgimpmath/gimpmath.h" +#include "libgimpcolor/gimpcolor.h" +#include "libgimpwidgets/gimpwidgets.h" + +#include "widgets-types.h" + +#include "core/gimp.h" +#include "core/gimpcontainer.h" +#include "core/gimpcontext.h" +#include "core/gimpdatafactory.h" +#include "core/gimppalette.h" + +#include "gimpcolordialog.h" +#include "gimpdnd.h" +#include "gimpdocked.h" +#include "gimpdialogfactory.h" +#include "gimphelp-ids.h" +#include "gimppaletteeditor.h" +#include "gimppaletteview.h" +#include "gimpsessioninfo-aux.h" +#include "gimpuimanager.h" +#include "gimpviewrendererpalette.h" +#include "gimpwidgets-utils.h" + +#include "gimp-intl.h" + + +#define ENTRY_WIDTH 12 +#define ENTRY_HEIGHT 10 +#define SPACING 1 +#define COLUMNS 16 +#define ROWS 11 + +#define PREVIEW_WIDTH ((ENTRY_WIDTH + SPACING) * COLUMNS + 1) +#define PREVIEW_HEIGHT ((ENTRY_HEIGHT + SPACING) * ROWS + 1) + + +/* local function prototypes */ + +static void gimp_palette_editor_docked_iface_init (GimpDockedInterface *face); + +static void gimp_palette_editor_constructed (GObject *object); +static void gimp_palette_editor_dispose (GObject *object); + +static void gimp_palette_editor_unmap (GtkWidget *widget); + +static void gimp_palette_editor_set_data (GimpDataEditor *editor, + GimpData *data); + +static void gimp_palette_editor_set_context (GimpDocked *docked, + GimpContext *context); +static void gimp_palette_editor_set_aux_info (GimpDocked *docked, + GList *aux_info); +static GList *gimp_palette_editor_get_aux_info (GimpDocked *docked); + +static void palette_editor_invalidate_preview (GimpPalette *palette, + GimpPaletteEditor *editor); + +static void palette_editor_viewport_size_allocate(GtkWidget *widget, + GtkAllocation *allocation, + GimpPaletteEditor *editor); + +static void palette_editor_drop_palette (GtkWidget *widget, + gint x, + gint y, + GimpViewable *viewable, + gpointer data); +static void palette_editor_drop_color (GtkWidget *widget, + gint x, + gint y, + const GimpRGB *color, + gpointer data); + +static void palette_editor_entry_clicked (GimpPaletteView *view, + GimpPaletteEntry *entry, + GdkModifierType state, + GimpPaletteEditor *editor); +static void palette_editor_entry_selected (GimpPaletteView *view, + GimpPaletteEntry *entry, + GimpPaletteEditor *editor); +static void palette_editor_entry_activated (GimpPaletteView *view, + GimpPaletteEntry *entry, + GimpPaletteEditor *editor); +static void palette_editor_entry_context (GimpPaletteView *view, + GimpPaletteEntry *entry, + GimpPaletteEditor *editor); +static void palette_editor_color_dropped (GimpPaletteView *view, + GimpPaletteEntry *entry, + const GimpRGB *color, + GimpPaletteEditor *editor); + +static void palette_editor_color_name_changed (GtkWidget *widget, + GimpPaletteEditor *editor); +static void palette_editor_columns_changed (GtkAdjustment *adj, + GimpPaletteEditor *editor); + +static void palette_editor_resize (GimpPaletteEditor *editor, + gint width, + gdouble zoom_factor); +static void palette_editor_scroll_top_left (GimpPaletteEditor *editor); +static void palette_editor_edit_color_update (GimpColorDialog *dialog, + const GimpRGB *color, + GimpColorDialogState state, + GimpPaletteEditor *editor); + + +G_DEFINE_TYPE_WITH_CODE (GimpPaletteEditor, gimp_palette_editor, + GIMP_TYPE_DATA_EDITOR, + G_IMPLEMENT_INTERFACE (GIMP_TYPE_DOCKED, + gimp_palette_editor_docked_iface_init)) + +#define parent_class gimp_palette_editor_parent_class + +static GimpDockedInterface *parent_docked_iface = NULL; + + +static void +gimp_palette_editor_class_init (GimpPaletteEditorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GimpDataEditorClass *editor_class = GIMP_DATA_EDITOR_CLASS (klass); + + object_class->constructed = gimp_palette_editor_constructed; + object_class->dispose = gimp_palette_editor_dispose; + + widget_class->unmap = gimp_palette_editor_unmap; + + editor_class->set_data = gimp_palette_editor_set_data; + editor_class->title = _("Palette Editor"); +} + +static void +gimp_palette_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->set_context = gimp_palette_editor_set_context; + iface->set_aux_info = gimp_palette_editor_set_aux_info; + iface->get_aux_info = gimp_palette_editor_get_aux_info; +} + +static void +gimp_palette_editor_init (GimpPaletteEditor *editor) +{ + GimpDataEditor *data_editor = GIMP_DATA_EDITOR (editor); + GtkWidget *viewport; + GtkWidget *hbox; + GtkWidget *icon; + GtkWidget *spinbutton; + + editor->zoom_factor = 1.0; + editor->col_width = 0; + editor->last_width = 0; + editor->columns = COLUMNS; + + data_editor->view = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_set_size_request (data_editor->view, -1, PREVIEW_HEIGHT); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (data_editor->view), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (editor), data_editor->view, TRUE, TRUE, 0); + gtk_widget_show (data_editor->view); + + viewport = gtk_viewport_new (NULL, NULL); + gtk_container_add (GTK_CONTAINER (data_editor->view), viewport); + gtk_widget_show (viewport); + + editor->view = gimp_view_new_full_by_types (NULL, + GIMP_TYPE_PALETTE_VIEW, + GIMP_TYPE_PALETTE, + PREVIEW_WIDTH, PREVIEW_HEIGHT, 0, + FALSE, TRUE, FALSE); + gimp_view_renderer_palette_set_cell_size + (GIMP_VIEW_RENDERER_PALETTE (GIMP_VIEW (editor->view)->renderer), -1); + gimp_view_renderer_palette_set_draw_grid + (GIMP_VIEW_RENDERER_PALETTE (GIMP_VIEW (editor->view)->renderer), TRUE); + gtk_container_add (GTK_CONTAINER (viewport), editor->view); + gtk_widget_show (editor->view); + + g_signal_connect (gtk_widget_get_parent (editor->view), "size-allocate", + G_CALLBACK (palette_editor_viewport_size_allocate), + editor); + + g_signal_connect (editor->view, "entry-clicked", + G_CALLBACK (palette_editor_entry_clicked), + editor); + g_signal_connect (editor->view, "entry-selected", + G_CALLBACK (palette_editor_entry_selected), + editor); + g_signal_connect (editor->view, "entry-activated", + G_CALLBACK (palette_editor_entry_activated), + editor); + g_signal_connect (editor->view, "entry-context", + G_CALLBACK (palette_editor_entry_context), + editor); + g_signal_connect (editor->view, "color-dropped", + G_CALLBACK (palette_editor_color_dropped), + editor); + + gimp_dnd_viewable_dest_add (editor->view, + GIMP_TYPE_PALETTE, + palette_editor_drop_palette, + editor); + gimp_dnd_viewable_dest_add (gtk_widget_get_parent (editor->view), + GIMP_TYPE_PALETTE, + palette_editor_drop_palette, + editor); + + gimp_dnd_color_dest_add (gtk_widget_get_parent (editor->view), + palette_editor_drop_color, + editor); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2); + gtk_box_pack_start (GTK_BOX (editor), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + /* The color index number */ + editor->index_label = gtk_label_new ("####"); + gtk_box_pack_start (GTK_BOX (hbox), editor->index_label, FALSE, FALSE, 0); + gimp_label_set_attributes (GTK_LABEL (editor->index_label), + PANGO_ATTR_FAMILY, "Monospace", -1); + gtk_widget_show (editor->index_label); + + /* The color name entry */ + editor->color_name = gtk_entry_new (); + gtk_box_pack_start (GTK_BOX (hbox), editor->color_name, TRUE, TRUE, 0); + gtk_entry_set_width_chars (GTK_ENTRY (editor->color_name), 1); + gtk_entry_set_text (GTK_ENTRY (editor->color_name), _("Undefined")); + gtk_editable_set_editable (GTK_EDITABLE (editor->color_name), FALSE); + gtk_widget_show (editor->color_name); + + g_signal_connect (editor->color_name, "changed", + G_CALLBACK (palette_editor_color_name_changed), + editor); + + icon = gtk_image_new_from_icon_name (GIMP_ICON_GRID, GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0); + gtk_widget_show (icon); + + editor->columns_adj = (GtkAdjustment *) + gtk_adjustment_new (0, 0, 64, 1, 4, 0); + spinbutton = gimp_spin_button_new (editor->columns_adj, 1.0, 0); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE); + gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0); + gtk_widget_show (spinbutton); + + gimp_help_set_help_data (spinbutton, _("Set the number of columns"), NULL); + + g_signal_connect (editor->columns_adj, "value-changed", + G_CALLBACK (palette_editor_columns_changed), + editor); +} + +static void +gimp_palette_editor_constructed (GObject *object) +{ + GimpPaletteEditor *editor = GIMP_PALETTE_EDITOR (object); + + G_OBJECT_CLASS (parent_class)->constructed (object); + + gimp_editor_add_action_button (GIMP_EDITOR (editor), "palette-editor", + "palette-editor-edit-color", NULL); + + gimp_editor_add_action_button (GIMP_EDITOR (editor), "palette-editor", + "palette-editor-new-color-fg", + "palette-editor-new-color-bg", + gimp_get_toggle_behavior_mask (), + NULL); + + gimp_editor_add_action_button (GIMP_EDITOR (editor), "palette-editor", + "palette-editor-delete-color", NULL); + + gimp_editor_add_action_button (GIMP_EDITOR (editor), "palette-editor", + "palette-editor-zoom-out", NULL); + + gimp_editor_add_action_button (GIMP_EDITOR (editor), "palette-editor", + "palette-editor-zoom-in", NULL); + + gimp_editor_add_action_button (GIMP_EDITOR (editor), "palette-editor", + "palette-editor-zoom-all", NULL); +} + +static void +gimp_palette_editor_dispose (GObject *object) +{ + GimpPaletteEditor *editor = GIMP_PALETTE_EDITOR (object); + + g_clear_pointer (&editor->color_dialog, gtk_widget_destroy); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gimp_palette_editor_unmap (GtkWidget *widget) +{ + GimpPaletteEditor *editor = GIMP_PALETTE_EDITOR (widget); + + if (editor->color_dialog) + gtk_widget_hide (editor->color_dialog); + + GTK_WIDGET_CLASS (parent_class)->unmap (widget); +} + +static void +gimp_palette_editor_set_data (GimpDataEditor *editor, + GimpData *data) +{ + GimpPaletteEditor *palette_editor = GIMP_PALETTE_EDITOR (editor); + + g_signal_handlers_block_by_func (palette_editor->columns_adj, + palette_editor_columns_changed, + editor); + + if (editor->data) + { + if (palette_editor->color_dialog) + { + gtk_widget_destroy (palette_editor->color_dialog); + palette_editor->color_dialog = NULL; + } + + g_signal_handlers_disconnect_by_func (editor->data, + palette_editor_invalidate_preview, + editor); + + gtk_adjustment_set_value (palette_editor->columns_adj, 0); + } + + GIMP_DATA_EDITOR_CLASS (parent_class)->set_data (editor, data); + + gimp_view_set_viewable (GIMP_VIEW (palette_editor->view), + GIMP_VIEWABLE (data)); + + if (editor->data) + { + GimpPalette *palette = GIMP_PALETTE (editor->data); + + g_signal_connect (editor->data, "invalidate-preview", + G_CALLBACK (palette_editor_invalidate_preview), + editor); + + gtk_adjustment_set_value (palette_editor->columns_adj, + gimp_palette_get_columns (palette)); + + palette_editor_scroll_top_left (palette_editor); + + palette_editor_invalidate_preview (GIMP_PALETTE (editor->data), + palette_editor); + } + + g_signal_handlers_unblock_by_func (palette_editor->columns_adj, + palette_editor_columns_changed, + editor); +} + +static void +gimp_palette_editor_set_context (GimpDocked *docked, + GimpContext *context) +{ + GimpPaletteEditor *editor = GIMP_PALETTE_EDITOR (docked); + + parent_docked_iface->set_context (docked, context); + + gimp_view_renderer_set_context (GIMP_VIEW (editor->view)->renderer, + context); +} + +#define AUX_INFO_ZOOM_FACTOR "zoom-factor" + +static void +gimp_palette_editor_set_aux_info (GimpDocked *docked, + GList *aux_info) +{ + GimpPaletteEditor *editor = GIMP_PALETTE_EDITOR (docked); + 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_ZOOM_FACTOR)) + { + gdouble zoom_factor; + + zoom_factor = g_ascii_strtod (aux->value, NULL); + + editor->zoom_factor = CLAMP (zoom_factor, 0.1, 4.0); + } + } +} + +static GList * +gimp_palette_editor_get_aux_info (GimpDocked *docked) +{ + GimpPaletteEditor *editor = GIMP_PALETTE_EDITOR (docked); + GList *aux_info; + + aux_info = parent_docked_iface->get_aux_info (docked); + + if (editor->zoom_factor != 1.0) + { + GimpSessionInfoAux *aux; + gchar value[G_ASCII_DTOSTR_BUF_SIZE]; + + g_ascii_formatd (value, sizeof (value), "%.2f", editor->zoom_factor); + + aux = gimp_session_info_aux_new (AUX_INFO_ZOOM_FACTOR, value); + aux_info = g_list_append (aux_info, aux); + } + + return aux_info; +} + + +/* public functions */ + +GtkWidget * +gimp_palette_editor_new (GimpContext *context, + GimpMenuFactory *menu_factory) +{ + g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); + + return g_object_new (GIMP_TYPE_PALETTE_EDITOR, + "menu-factory", menu_factory, + "menu-identifier", "<PaletteEditor>", + "ui-path", "/palette-editor-popup", + "data-factory", context->gimp->palette_factory, + "context", context, + "data", gimp_context_get_palette (context), + NULL); +} + +void +gimp_palette_editor_edit_color (GimpPaletteEditor *editor) +{ + GimpDataEditor *data_editor; + GimpPalette *palette; + + g_return_if_fail (GIMP_IS_PALETTE_EDITOR (editor)); + + data_editor = GIMP_DATA_EDITOR (editor); + + if (! (data_editor->data_editable && editor->color)) + return; + + palette = GIMP_PALETTE (gimp_data_editor_get_data (data_editor)); + + if (! editor->color_dialog) + { + editor->color_dialog = + gimp_color_dialog_new (GIMP_VIEWABLE (palette), + data_editor->context, + _("Edit Palette Color"), + GIMP_ICON_PALETTE, + _("Edit Color Palette Entry"), + GTK_WIDGET (editor), + gimp_dialog_factory_get_singleton (), + "gimp-palette-editor-color-dialog", + &editor->color->color, + FALSE, FALSE); + + g_signal_connect (editor->color_dialog, "destroy", + G_CALLBACK (gtk_widget_destroyed), + &editor->color_dialog); + + g_signal_connect (editor->color_dialog, "update", + G_CALLBACK (palette_editor_edit_color_update), + editor); + } + else + { + gimp_viewable_dialog_set_viewable (GIMP_VIEWABLE_DIALOG (editor->color_dialog), + GIMP_VIEWABLE (palette), + data_editor->context); + gimp_color_dialog_set_color (GIMP_COLOR_DIALOG (editor->color_dialog), + &editor->color->color); + + if (! gtk_widget_get_visible (editor->color_dialog)) + gimp_dialog_factory_position_dialog (gimp_dialog_factory_get_singleton (), + "gimp-palette-editor-color-dialog", + editor->color_dialog, + gtk_widget_get_screen (GTK_WIDGET (editor)), + gimp_widget_get_monitor (GTK_WIDGET (editor))); + } + + gtk_window_present (GTK_WINDOW (editor->color_dialog)); +} + +void +gimp_palette_editor_pick_color (GimpPaletteEditor *editor, + const GimpRGB *color, + GimpColorPickState pick_state) +{ + g_return_if_fail (GIMP_IS_PALETTE_EDITOR (editor)); + g_return_if_fail (color != NULL); + + if (GIMP_DATA_EDITOR (editor)->data_editable) + { + GimpPaletteEntry *entry; + GimpData *data; + gint index = -1; + + data = gimp_data_editor_get_data (GIMP_DATA_EDITOR (editor)); + + switch (pick_state) + { + case GIMP_COLOR_PICK_STATE_START: + if (editor->color) + index = editor->color->position + 1; + + entry = gimp_palette_add_entry (GIMP_PALETTE (data), index, + NULL, color); + gimp_palette_view_select_entry (GIMP_PALETTE_VIEW (editor->view), + entry); + break; + + case GIMP_COLOR_PICK_STATE_UPDATE: + case GIMP_COLOR_PICK_STATE_END: + gimp_palette_set_entry_color (GIMP_PALETTE (data), + editor->color->position, + color); + break; + } + } +} + +void +gimp_palette_editor_zoom (GimpPaletteEditor *editor, + GimpZoomType zoom_type) +{ + GimpPalette *palette; + gdouble zoom_factor; + + g_return_if_fail (GIMP_IS_PALETTE_EDITOR (editor)); + + palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); + + if (! palette) + return; + + zoom_factor = editor->zoom_factor; + + switch (zoom_type) + { + case GIMP_ZOOM_IN_MAX: + case GIMP_ZOOM_IN_MORE: + case GIMP_ZOOM_IN: + zoom_factor += 0.1; + break; + + case GIMP_ZOOM_OUT_MORE: + case GIMP_ZOOM_OUT: + zoom_factor -= 0.1; + break; + + case GIMP_ZOOM_OUT_MAX: + case GIMP_ZOOM_TO: /* abused as ZOOM_ALL */ + { + GtkWidget *scrolled_win = GIMP_DATA_EDITOR (editor)->view; + GtkWidget *viewport = gtk_bin_get_child (GTK_BIN (scrolled_win)); + GtkAllocation allocation; + gint columns; + gint rows; + + gtk_widget_get_allocation (viewport, &allocation); + + columns = gimp_palette_get_columns (palette); + if (columns == 0) + columns = COLUMNS; + + rows = gimp_palette_get_n_colors (palette) / columns; + if (gimp_palette_get_n_colors (palette) % columns) + rows += 1; + + rows = MAX (1, rows); + + zoom_factor = (((gdouble) allocation.height - 2 * SPACING) / + (gdouble) rows - SPACING) / ENTRY_HEIGHT; + } + break; + } + + zoom_factor = CLAMP (zoom_factor, 0.1, 4.0); + + editor->columns = gimp_palette_get_columns (palette); + if (editor->columns == 0) + editor->columns = COLUMNS; + + palette_editor_resize (editor, editor->last_width, zoom_factor); + + palette_editor_scroll_top_left (editor); +} + +gint +gimp_palette_editor_get_index (GimpPaletteEditor *editor, + const GimpRGB *search) +{ + GimpPalette *palette; + + g_return_val_if_fail (GIMP_IS_PALETTE_EDITOR (editor), -1); + g_return_val_if_fail (search != NULL, -1); + + palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); + + if (palette && gimp_palette_get_n_colors (palette) > 0) + { + GimpPaletteEntry *entry; + + entry = gimp_palette_find_entry (palette, search, editor->color); + + if (entry) + return entry->position; + } + + return -1; +} + +gboolean +gimp_palette_editor_set_index (GimpPaletteEditor *editor, + gint index, + GimpRGB *color) +{ + GimpPalette *palette; + + g_return_val_if_fail (GIMP_IS_PALETTE_EDITOR (editor), FALSE); + + palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); + + if (palette && gimp_palette_get_n_colors (palette) > 0) + { + GimpPaletteEntry *entry; + + index = CLAMP (index, 0, gimp_palette_get_n_colors (palette) - 1); + + entry = gimp_palette_get_entry (palette, index); + + gimp_palette_view_select_entry (GIMP_PALETTE_VIEW (editor->view), + entry); + + if (color) + *color = editor->color->color; + + return TRUE; + } + + return FALSE; +} + +gint +gimp_palette_editor_max_index (GimpPaletteEditor *editor) +{ + GimpPalette *palette; + + g_return_val_if_fail (GIMP_IS_PALETTE_EDITOR (editor), -1); + + palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); + + if (palette && gimp_palette_get_n_colors (palette) > 0) + { + return gimp_palette_get_n_colors (palette) - 1; + } + + return -1; +} + + +/* private functions */ + +static void +palette_editor_invalidate_preview (GimpPalette *palette, + GimpPaletteEditor *editor) +{ + editor->columns = gimp_palette_get_columns (palette); + if (editor->columns == 0) + editor->columns = COLUMNS; + + palette_editor_resize (editor, editor->last_width, editor->zoom_factor); +} + +static void +palette_editor_viewport_size_allocate (GtkWidget *widget, + GtkAllocation *allocation, + GimpPaletteEditor *editor) +{ + if (allocation->width != editor->last_width) + { + palette_editor_resize (editor, allocation->width, + editor->zoom_factor); + } +} + +static void +palette_editor_drop_palette (GtkWidget *widget, + gint x, + gint y, + GimpViewable *viewable, + gpointer data) +{ + gimp_data_editor_set_data (GIMP_DATA_EDITOR (data), GIMP_DATA (viewable)); +} + +static void +palette_editor_drop_color (GtkWidget *widget, + gint x, + gint y, + const GimpRGB *color, + gpointer data) +{ + GimpPaletteEditor *editor = data; + + if (GIMP_DATA_EDITOR (editor)->data_editable) + { + GimpPalette *palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); + GimpPaletteEntry *entry; + + entry = gimp_palette_add_entry (palette, -1, NULL, color); + gimp_palette_view_select_entry (GIMP_PALETTE_VIEW (editor->view), entry); + } +} + + +/* palette view callbacks */ + +static void +palette_editor_entry_clicked (GimpPaletteView *view, + GimpPaletteEntry *entry, + GdkModifierType state, + GimpPaletteEditor *editor) +{ + if (entry) + { + GimpDataEditor *data_editor = GIMP_DATA_EDITOR (editor); + + if (state & gimp_get_toggle_behavior_mask ()) + gimp_context_set_background (data_editor->context, &entry->color); + else + gimp_context_set_foreground (data_editor->context, &entry->color); + } +} + +static void +palette_editor_entry_selected (GimpPaletteView *view, + GimpPaletteEntry *entry, + GimpPaletteEditor *editor) +{ + GimpDataEditor *data_editor = GIMP_DATA_EDITOR (editor); + + if (editor->color != entry) + { + gchar index[8]; + + editor->color = entry; + + if (entry) + g_snprintf (index, sizeof (index), "%04i", entry->position); + else + g_snprintf (index, sizeof (index), "####"); + + gtk_label_set_text (GTK_LABEL (editor->index_label), index); + + g_signal_handlers_block_by_func (editor->color_name, + palette_editor_color_name_changed, + editor); + + gtk_entry_set_text (GTK_ENTRY (editor->color_name), + entry ? entry->name : _("Undefined")); + + g_signal_handlers_unblock_by_func (editor->color_name, + palette_editor_color_name_changed, + editor); + + gtk_editable_set_editable (GTK_EDITABLE (editor->color_name), + entry && data_editor->data_editable); + + gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)), + gimp_editor_get_popup_data (GIMP_EDITOR (editor))); + } +} + +static void +palette_editor_entry_activated (GimpPaletteView *view, + GimpPaletteEntry *entry, + GimpPaletteEditor *editor) +{ + if (GIMP_DATA_EDITOR (editor)->data_editable && entry == editor->color) + { + gimp_ui_manager_activate_action (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)), + "palette-editor", + "palette-editor-edit-color"); + } +} + +static void +palette_editor_entry_context (GimpPaletteView *view, + GimpPaletteEntry *entry, + GimpPaletteEditor *editor) +{ + gimp_editor_popup_menu (GIMP_EDITOR (editor), NULL, NULL); +} + +static void +palette_editor_color_dropped (GimpPaletteView *view, + GimpPaletteEntry *entry, + const GimpRGB *color, + GimpPaletteEditor *editor) +{ + if (GIMP_DATA_EDITOR (editor)->data_editable) + { + GimpPalette *palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); + gint pos = -1; + + if (entry) + pos = entry->position; + + entry = gimp_palette_add_entry (palette, pos, NULL, color); + gimp_palette_view_select_entry (GIMP_PALETTE_VIEW (editor->view), entry); + } +} + + +/* color name and columns callbacks */ + +static void +palette_editor_color_name_changed (GtkWidget *widget, + GimpPaletteEditor *editor) +{ + if (GIMP_DATA_EDITOR (editor)->data) + { + GimpPalette *palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); + const gchar *name; + + name = gtk_entry_get_text (GTK_ENTRY (editor->color_name)); + + gimp_palette_set_entry_name (palette, editor->color->position, name); + } +} + +static void +palette_editor_columns_changed (GtkAdjustment *adj, + GimpPaletteEditor *editor) +{ + if (GIMP_DATA_EDITOR (editor)->data) + { + GimpPalette *palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); + + gimp_palette_set_columns (palette, + ROUND (gtk_adjustment_get_value (adj))); + } +} + + +/* misc utils */ + +static void +palette_editor_resize (GimpPaletteEditor *editor, + gint width, + gdouble zoom_factor) +{ + GimpPalette *palette; + gint rows; + gint preview_width; + gint preview_height; + + palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); + + if (! palette) + return; + + editor->zoom_factor = zoom_factor; + editor->last_width = width; + editor->col_width = width / (editor->columns + 1) - SPACING; + + if (editor->col_width < 0) + editor->col_width = 0; + + rows = gimp_palette_get_n_colors (palette) / editor->columns; + if (gimp_palette_get_n_colors (palette) % editor->columns) + rows += 1; + + preview_width = (editor->col_width + SPACING) * editor->columns; + preview_height = (rows * + (SPACING + (gint) (ENTRY_HEIGHT * editor->zoom_factor))); + + if (preview_height > GIMP_VIEWABLE_MAX_PREVIEW_SIZE) + preview_height = ((GIMP_VIEWABLE_MAX_PREVIEW_SIZE - SPACING) / rows) * rows; + + gimp_view_renderer_set_size_full (GIMP_VIEW (editor->view)->renderer, + preview_width + SPACING, + preview_height + SPACING, 0); +} + +static void +palette_editor_scroll_top_left (GimpPaletteEditor *palette_editor) +{ + GimpDataEditor *data_editor = GIMP_DATA_EDITOR (palette_editor); + GtkAdjustment *hadj; + GtkAdjustment *vadj; + + if (! data_editor->view) + return; + + hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (data_editor->view)); + vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (data_editor->view)); + + if (hadj) + gtk_adjustment_set_value (hadj, 0.0); + if (vadj) + gtk_adjustment_set_value (vadj, 0.0); +} + +static void +palette_editor_edit_color_update (GimpColorDialog *dialog, + const GimpRGB *color, + GimpColorDialogState state, + GimpPaletteEditor *editor) +{ + GimpPalette *palette = GIMP_PALETTE (GIMP_DATA_EDITOR (editor)->data); + + switch (state) + { + case GIMP_COLOR_DIALOG_UPDATE: + break; + + case GIMP_COLOR_DIALOG_OK: + if (editor->color) + { + editor->color->color = *color; + gimp_data_dirty (GIMP_DATA (palette)); + } + /* Fallthrough */ + + case GIMP_COLOR_DIALOG_CANCEL: + gtk_widget_hide (editor->color_dialog); + break; + } +} |