/* LIBPIKA - The PIKA Library * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball * * pikacolornotebook.c * Copyright (C) 2002 Michael Natterer * * based on color_notebook module * Copyright (C) 1998 Austin Donnelly * * 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 * . */ #include "config.h" #include #include #include "libpikacolor/pikacolor.h" #include "pikawidgetstypes.h" #include "pikacolornotebook.h" #include "pikacolorscales.h" #include "pikahelpui.h" #include "libpika/libpika-intl.h" /** * SECTION: pikacolornotebook * @title: PikaColorNotebook * @short_description: A #PikaColorSelector implementation. * * The #PikaColorNotebook widget is an implementation of a * #PikaColorSelector. It serves as a container for * #PikaColorSelectors. **/ #define DEFAULT_TAB_ICON_SIZE GTK_ICON_SIZE_BUTTON struct _PikaColorNotebookPrivate { GtkWidget *notebook; GList *selectors; PikaColorSelector *cur_page; }; #define GET_PRIVATE(obj) (((PikaColorNotebook *) obj)->priv) static void pika_color_notebook_style_updated (GtkWidget *widget); static void pika_color_notebook_togg_visible (PikaColorSelector *selector, gboolean visible); static void pika_color_notebook_togg_sensitive (PikaColorSelector *selector, gboolean sensitive); static void pika_color_notebook_set_show_alpha (PikaColorSelector *selector, gboolean show_alpha); static void pika_color_notebook_set_color (PikaColorSelector *selector, const PikaRGB *rgb, const PikaHSV *hsv); static void pika_color_notebook_set_channel (PikaColorSelector *selector, PikaColorSelectorChannel channel); static void pika_color_notebook_set_model_visible (PikaColorSelector *selector, PikaColorSelectorModel model, gboolean gboolean); static void pika_color_notebook_set_config (PikaColorSelector *selector, PikaColorConfig *config); static void pika_color_notebook_switch_page (GtkNotebook *gtk_notebook, gpointer page, guint page_num, PikaColorNotebook *notebook); static void pika_color_notebook_color_changed (PikaColorSelector *page, const PikaRGB *rgb, const PikaHSV *hsv, PikaColorNotebook *notebook); static void pika_color_notebook_channel_changed (PikaColorSelector *page, PikaColorSelectorChannel channel, PikaColorNotebook *notebook); static void pika_color_notebook_model_visible_changed (PikaColorSelector *page, PikaColorSelectorModel model, gboolean visible, PikaColorNotebook *notebook); static GtkWidget * pika_color_notebook_add_page (PikaColorNotebook *notebook, GType page_type); static void pika_color_notebook_remove_selector (GtkContainer *container, GtkWidget *widget, PikaColorNotebook *notebook); G_DEFINE_TYPE_WITH_PRIVATE (PikaColorNotebook, pika_color_notebook, PIKA_TYPE_COLOR_SELECTOR) #define parent_class pika_color_notebook_parent_class static void pika_color_notebook_class_init (PikaColorNotebookClass *klass) { GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); PikaColorSelectorClass *selector_class = PIKA_COLOR_SELECTOR_CLASS (klass); widget_class->style_updated = pika_color_notebook_style_updated; selector_class->name = "Notebook"; selector_class->help_id = "pika-colorselector-notebook"; selector_class->set_toggles_visible = pika_color_notebook_togg_visible; selector_class->set_toggles_sensitive = pika_color_notebook_togg_sensitive; selector_class->set_show_alpha = pika_color_notebook_set_show_alpha; selector_class->set_color = pika_color_notebook_set_color; selector_class->set_channel = pika_color_notebook_set_channel; selector_class->set_model_visible = pika_color_notebook_set_model_visible; selector_class->set_config = pika_color_notebook_set_config; gtk_widget_class_install_style_property (widget_class, g_param_spec_enum ("tab-icon-size", NULL, "Size for icons displayed in the tab", GTK_TYPE_ICON_SIZE, DEFAULT_TAB_ICON_SIZE, G_PARAM_READABLE)); gtk_widget_class_set_css_name (widget_class, "PikaColorNotebook"); } static void pika_color_notebook_init (PikaColorNotebook *notebook) { PikaColorNotebookPrivate *private = GET_PRIVATE (notebook); GType *selector_types; guint n_selector_types; guint i; notebook->priv = pika_color_notebook_get_instance_private (notebook); private = notebook->priv; private->notebook = gtk_notebook_new (); gtk_notebook_popup_enable (GTK_NOTEBOOK (private->notebook)); gtk_box_pack_start (GTK_BOX (notebook), private->notebook, TRUE, TRUE, 0); gtk_widget_show (private->notebook); g_signal_connect (private->notebook, "switch-page", G_CALLBACK (pika_color_notebook_switch_page), notebook); g_signal_connect (private->notebook, "remove", G_CALLBACK (pika_color_notebook_remove_selector), notebook); selector_types = g_type_children (PIKA_TYPE_COLOR_SELECTOR, &n_selector_types); if (n_selector_types == 2) { gtk_notebook_set_show_tabs (GTK_NOTEBOOK (private->notebook), FALSE); gtk_notebook_set_show_border (GTK_NOTEBOOK (private->notebook), FALSE); } for (i = 0; i < n_selector_types; i++) { /* skip ourselves */ if (g_type_is_a (selector_types[i], PIKA_TYPE_COLOR_NOTEBOOK)) continue; /* skip the "Scales" color selector */ if (g_type_is_a (selector_types[i], PIKA_TYPE_COLOR_SCALES)) continue; pika_color_notebook_add_page (notebook, selector_types[i]); } g_free (selector_types); } static void pika_color_notebook_style_updated (GtkWidget *widget) { PikaColorNotebookPrivate *private = GET_PRIVATE (widget); GList *list; GtkIconSize icon_size; GTK_WIDGET_CLASS (parent_class)->style_updated (widget); gtk_widget_style_get (widget, "tab-icon-size", &icon_size, NULL); for (list = private->selectors; list; list = g_list_next (list)) { PikaColorSelectorClass *selector_class; GtkWidget *image; selector_class = PIKA_COLOR_SELECTOR_GET_CLASS (list->data); image = gtk_image_new_from_icon_name (selector_class->icon_name, icon_size); pika_help_set_help_data (image, gettext (selector_class->name), NULL); gtk_notebook_set_tab_label (GTK_NOTEBOOK (private->notebook), GTK_WIDGET (list->data), image); } } static void pika_color_notebook_togg_visible (PikaColorSelector *selector, gboolean visible) { PikaColorNotebookPrivate *private = GET_PRIVATE (selector); GList *list; for (list = private->selectors; list; list = g_list_next (list)) { PikaColorSelector *child = list->data; pika_color_selector_set_toggles_visible (child, visible); } } static void pika_color_notebook_togg_sensitive (PikaColorSelector *selector, gboolean sensitive) { PikaColorNotebookPrivate *private = GET_PRIVATE (selector); GList *list; for (list = private->selectors; list; list = g_list_next (list)) { PikaColorSelector *child = list->data; pika_color_selector_set_toggles_sensitive (child, sensitive); } } static void pika_color_notebook_set_show_alpha (PikaColorSelector *selector, gboolean show_alpha) { PikaColorNotebookPrivate *private = GET_PRIVATE (selector); GList *list; for (list = private->selectors; list; list = g_list_next (list)) { PikaColorSelector *child = list->data; pika_color_selector_set_show_alpha (child, show_alpha); } } static void pika_color_notebook_set_color (PikaColorSelector *selector, const PikaRGB *rgb, const PikaHSV *hsv) { PikaColorNotebookPrivate *private = GET_PRIVATE (selector); g_signal_handlers_block_by_func (private->cur_page, pika_color_notebook_color_changed, selector); pika_color_selector_set_color (private->cur_page, rgb, hsv); g_signal_handlers_unblock_by_func (private->cur_page, pika_color_notebook_color_changed, selector); } static void pika_color_notebook_set_channel (PikaColorSelector *selector, PikaColorSelectorChannel channel) { PikaColorNotebookPrivate *private = GET_PRIVATE (selector); g_signal_handlers_block_by_func (private->cur_page, pika_color_notebook_channel_changed, selector); pika_color_selector_set_channel (private->cur_page, channel); g_signal_handlers_unblock_by_func (private->cur_page, pika_color_notebook_channel_changed, selector); } static void pika_color_notebook_set_model_visible (PikaColorSelector *selector, PikaColorSelectorModel model, gboolean visible) { PikaColorNotebookPrivate *private = GET_PRIVATE (selector); g_signal_handlers_block_by_func (private->cur_page, pika_color_notebook_model_visible_changed, selector); pika_color_selector_set_model_visible (private->cur_page, model, visible); g_signal_handlers_unblock_by_func (private->cur_page, pika_color_notebook_model_visible_changed, selector); } static void pika_color_notebook_set_config (PikaColorSelector *selector, PikaColorConfig *config) { PikaColorNotebookPrivate *private = GET_PRIVATE (selector); GList *list; for (list = private->selectors; list; list = g_list_next (list)) { PikaColorSelector *child = list->data; pika_color_selector_set_config (child, config); } } static void pika_color_notebook_switch_page (GtkNotebook *gtk_notebook, gpointer page, guint page_num, PikaColorNotebook *notebook) { PikaColorNotebookPrivate *private = GET_PRIVATE (notebook); PikaColorSelector *selector = PIKA_COLOR_SELECTOR (notebook); GtkWidget *page_widget; PikaColorSelectorModel model; page_widget = gtk_notebook_get_nth_page (gtk_notebook, page_num); private->cur_page = PIKA_COLOR_SELECTOR (page_widget); g_signal_handlers_block_by_func (private->cur_page, pika_color_notebook_color_changed, notebook); g_signal_handlers_block_by_func (private->cur_page, pika_color_notebook_channel_changed, notebook); g_signal_handlers_block_by_func (private->cur_page, pika_color_notebook_model_visible_changed, notebook); pika_color_selector_set_color (private->cur_page, &selector->rgb, &selector->hsv); pika_color_selector_set_channel (private->cur_page, pika_color_selector_get_channel (selector)); for (model = PIKA_COLOR_SELECTOR_MODEL_RGB; model <= PIKA_COLOR_SELECTOR_MODEL_HSV; model++) { gboolean visible = pika_color_selector_get_model_visible (selector, model); pika_color_selector_set_model_visible (private->cur_page, model, visible); } g_signal_handlers_unblock_by_func (private->cur_page, pika_color_notebook_color_changed, notebook); g_signal_handlers_unblock_by_func (private->cur_page, pika_color_notebook_channel_changed, notebook); g_signal_handlers_unblock_by_func (private->cur_page, pika_color_notebook_model_visible_changed, notebook); } static void pika_color_notebook_color_changed (PikaColorSelector *page, const PikaRGB *rgb, const PikaHSV *hsv, PikaColorNotebook *notebook) { PikaColorSelector *selector = PIKA_COLOR_SELECTOR (notebook); selector->rgb = *rgb; selector->hsv = *hsv; pika_color_selector_emit_color_changed (selector); } static void pika_color_notebook_channel_changed (PikaColorSelector *page, PikaColorSelectorChannel channel, PikaColorNotebook *notebook) { PikaColorSelector *selector = PIKA_COLOR_SELECTOR (notebook); pika_color_selector_set_channel (selector, channel); } static void pika_color_notebook_model_visible_changed (PikaColorSelector *page, PikaColorSelectorModel model, gboolean visible, PikaColorNotebook *notebook) { PikaColorSelector *selector = PIKA_COLOR_SELECTOR (notebook); pika_color_selector_set_model_visible (selector, model, visible); } static GtkWidget * pika_color_notebook_add_page (PikaColorNotebook *notebook, GType page_type) { PikaColorNotebookPrivate *private = GET_PRIVATE (notebook); PikaColorSelector *selector = PIKA_COLOR_SELECTOR (notebook); PikaColorSelectorClass *selector_class; GtkWidget *page; GtkWidget *menu_widget; GtkWidget *image; GtkWidget *label; gboolean show_alpha; page = pika_color_selector_new (page_type, &selector->rgb, &selector->hsv, pika_color_selector_get_channel (selector)); if (! page) return NULL; selector_class = PIKA_COLOR_SELECTOR_GET_CLASS (page); show_alpha = pika_color_selector_get_show_alpha (PIKA_COLOR_SELECTOR (notebook)); pika_color_selector_set_show_alpha (PIKA_COLOR_SELECTOR (page), show_alpha); menu_widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); image = gtk_image_new_from_icon_name (selector_class->icon_name, GTK_ICON_SIZE_MENU); gtk_box_pack_start (GTK_BOX (menu_widget), image, FALSE, FALSE, 0); gtk_widget_show (image); label = gtk_label_new (gettext (selector_class->name)); gtk_box_pack_start (GTK_BOX (menu_widget), label, FALSE, FALSE, 0); gtk_widget_show (label); image = gtk_image_new_from_icon_name (selector_class->icon_name, DEFAULT_TAB_ICON_SIZE); pika_help_set_help_data (image, gettext (selector_class->name), NULL); gtk_notebook_append_page_menu (GTK_NOTEBOOK (private->notebook), page, image, menu_widget); if (! private->cur_page) private->cur_page = PIKA_COLOR_SELECTOR (page); private->selectors = g_list_append (private->selectors, page); gtk_widget_show (page); g_signal_connect (page, "color-changed", G_CALLBACK (pika_color_notebook_color_changed), notebook); g_signal_connect (page, "channel-changed", G_CALLBACK (pika_color_notebook_channel_changed), notebook); g_signal_connect (page, "model-visible-changed", G_CALLBACK (pika_color_notebook_model_visible_changed), notebook); return page; } static void pika_color_notebook_remove_selector (GtkContainer *container, GtkWidget *widget, PikaColorNotebook *notebook) { notebook->priv->selectors = g_list_remove (notebook->priv->selectors, widget); if (! notebook->priv->selectors) notebook->priv->cur_page = NULL; } /** * pika_color_notebook_set_has_page: * @notebook: A #PikaColorNotebook widget. * @page_type: The #GType of the notebook page to add or remove. * @has_page: Whether the page should be added or removed. * * This function adds and removed pages to / from a #PikaColorNotebook. * The @page_type passed must be a #PikaColorSelector subtype. * * Returns: (transfer none): The new page widget, if @has_page was * %TRUE, or %NULL if @has_page was %FALSE. **/ GtkWidget * pika_color_notebook_set_has_page (PikaColorNotebook *notebook, GType page_type, gboolean has_page) { GList *list; g_return_val_if_fail (PIKA_IS_COLOR_NOTEBOOK (notebook), NULL); g_return_val_if_fail (g_type_is_a (page_type, PIKA_TYPE_COLOR_SELECTOR), NULL); g_return_val_if_fail (! g_type_is_a (page_type, PIKA_TYPE_COLOR_NOTEBOOK), NULL); for (list = notebook->priv->selectors; list; list = g_list_next (list)) { PikaColorSelector *page = list->data; if (G_TYPE_FROM_INSTANCE (page) == page_type) { if (has_page) return GTK_WIDGET (page); gtk_container_remove (GTK_CONTAINER (notebook->priv->notebook), GTK_WIDGET (page)); return NULL; } } if (! has_page) return NULL; return pika_color_notebook_add_page (notebook, page_type); } /** * pika_color_notebook_get_notebook: * @notebook: A #PikaColorNotebook widget. * * Returns: (transfer none) (type GtkNotebook): The #GtkNotebook inside. * * Since: 3.0 **/ GtkWidget * pika_color_notebook_get_notebook (PikaColorNotebook *notebook) { g_return_val_if_fail (PIKA_IS_COLOR_NOTEBOOK (notebook), NULL); return notebook->priv->notebook; } /** * pika_color_notebook_get_selectors: * @notebook: A #PikaColorNotebook widget. * * Returns: (element-type PikaColorSelector) (transfer none): The * notebook's list of #PikaColorSelector's. * * Since: 3.0 **/ GList * pika_color_notebook_get_selectors (PikaColorNotebook *notebook) { g_return_val_if_fail (PIKA_IS_COLOR_NOTEBOOK (notebook), NULL); return notebook->priv->selectors; } /** * pika_color_notebook_get_current_selector: * @notebook: A #PikaColorNotebook widget. * * Returns: (transfer none): The active page's #PikaColorSelector. * * Since: 3.0 **/ PikaColorSelector * pika_color_notebook_get_current_selector (PikaColorNotebook *notebook) { g_return_val_if_fail (PIKA_IS_COLOR_NOTEBOOK (notebook), NULL); return notebook->priv->cur_page; } /** * pika_color_notebook_set_simulation: * @notebook: A #PikaColorNotebook widget. * @profile: A #PikaColorProfile object. * @intent: A #PikaColorRenderingIntent enum. * @bpc: A gboolean. * * Updates all selectors with the current simulation settings. * * Since: 3.0 **/ void pika_color_notebook_set_simulation (PikaColorNotebook *notebook, PikaColorProfile *profile, PikaColorRenderingIntent intent, gboolean bpc) { GList *list; g_return_if_fail (PIKA_IS_COLOR_NOTEBOOK (notebook)); g_return_if_fail (profile == NULL || PIKA_IS_COLOR_PROFILE (profile)); for (list = notebook->priv->selectors; list; list = g_list_next (list)) { PikaColorSelector *selector = list->data; if (selector) pika_color_selector_set_simulation (selector, profile, intent, bpc); } }