summaryrefslogtreecommitdiffstats
path: root/src/ui/widget/color-notebook.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/widget/color-notebook.cpp')
-rw-r--r--src/ui/widget/color-notebook.cpp347
1 files changed, 347 insertions, 0 deletions
diff --git a/src/ui/widget/color-notebook.cpp b/src/ui/widget/color-notebook.cpp
new file mode 100644
index 0000000..e0dcd16
--- /dev/null
+++ b/src/ui/widget/color-notebook.cpp
@@ -0,0 +1,347 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/** @file
+ * A notebook with RGB, CMYK, CMS, HSL, and Wheel pages
+ *//*
+ * Authors:
+ * Lauris Kaplinski <lauris@kaplinski.com>
+ * bulia byak <buliabyak@users.sf.net>
+ * Tomasz Boczkowski <penginsbacon@gmail.com> (c++-sification)
+ *
+ * Copyright (C) 2001-2014 Authors
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h" // only include where actually required!
+#endif
+
+#undef SPCS_PREVIEW
+#define noDUMP_CHANGE_INFO
+
+#include <glibmm/i18n.h>
+#include <gtkmm/label.h>
+#include <gtkmm/notebook.h>
+#include <gtkmm/radiobutton.h>
+
+#include "cms-system.h"
+#include "document.h"
+#include "inkscape.h"
+#include "preferences.h"
+#include "profile-manager.h"
+
+#include "object/color-profile.h"
+#include "ui/icon-loader.h"
+
+#include "svg/svg-icc-color.h"
+
+#include "ui/dialog-events.h"
+#include "ui/tools/dropper-tool.h"
+#include "ui/widget/color-entry.h"
+#include "ui/widget/color-icc-selector.h"
+#include "ui/widget/color-notebook.h"
+#include "ui/widget/color-scales.h"
+//#include "ui/widget/color-wheel-selector.h"
+//#include "ui/widget/color-wheel-hsluv-selector.h"
+
+#include "widgets/spw-utilities.h"
+
+using Inkscape::CMSSystem;
+
+#define XPAD 2
+#define YPAD 1
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+
+ColorNotebook::ColorNotebook(SelectedColor &color)
+ : Gtk::Grid()
+ , _selected_color(color)
+{
+ set_name("ColorNotebook");
+
+ _available_pages.push_back(new Page(new ColorScalesFactory<SPColorScalesMode::HSL>, "color-selector-hsx"));
+ _available_pages.push_back(new Page(new ColorScalesFactory<SPColorScalesMode::HSV>, "color-selector-hsx"));
+ _available_pages.push_back(new Page(new ColorScalesFactory<SPColorScalesMode::RGB>, "color-selector-rgb"));
+ _available_pages.push_back(new Page(new ColorScalesFactory<SPColorScalesMode::CMYK>, "color-selector-cmyk"));
+ _available_pages.push_back(new Page(new ColorScalesFactory<SPColorScalesMode::HSLUV>, "color-selector-hsluv"));
+ //_available_pages.push_back(new Page(new ColorWheelSelectorFactory, "color-selector-wheel"));
+ _available_pages.push_back(new Page(new ColorICCSelectorFactory, "color-selector-cms"));
+
+ _initUI();
+
+ _selected_color.signal_changed.connect(sigc::mem_fun(this, &ColorNotebook::_onSelectedColorChanged));
+ _selected_color.signal_dragged.connect(sigc::mem_fun(this, &ColorNotebook::_onSelectedColorChanged));
+}
+
+ColorNotebook::~ColorNotebook()
+{
+ if (_onetimepick)
+ _onetimepick.disconnect();
+}
+
+ColorNotebook::Page::Page(Inkscape::UI::ColorSelectorFactory *selector_factory, const char* icon)
+ : selector_factory(selector_factory), icon_name(icon)
+{
+}
+
+void ColorNotebook::set_label(const Glib::ustring& label) {
+ _label->set_markup(label);
+}
+
+void ColorNotebook::_initUI()
+{
+ guint row = 0;
+
+ _book = Gtk::make_managed<Gtk::Stack>();
+ _book->show();
+ _book->set_transition_type(Gtk::STACK_TRANSITION_TYPE_CROSSFADE);
+ _book->set_transition_duration(130);
+
+ // mode selection switcher widget shows all buttons for color mode selection, side by side
+ _switcher = Gtk::make_managed<Gtk::StackSwitcher>();
+ _switcher->set_stack(*_book);
+ // cannot leave it homogeneous - in some themes switcher gets very wide
+ _switcher->set_homogeneous(false);
+ _switcher->set_halign(Gtk::ALIGN_CENTER);
+ _switcher->show();
+ attach(*_switcher, 0, row++, 2);
+
+ _buttonbox = Gtk::make_managed<Gtk::Box>();
+ _buttonbox->show();
+
+ // combo mode selection is compact and only shows one entry (active)
+ _combo = Gtk::manage(new IconComboBox());
+ _combo->set_can_focus(false);
+ _combo->set_visible();
+ _combo->set_tooltip_text(_("Choose style of color selection"));
+
+ for (auto&& page : _available_pages) {
+ _addPage(page);
+ }
+
+ _label = Gtk::make_managed<Gtk::Label>();
+ _label->set_visible();
+ _buttonbox->pack_start(*_label, false, true);
+ _buttonbox->pack_end(*_combo, false, false);
+ _combo->signal_changed().connect([=](){ _setCurrentPage(_combo->get_active_row_id(), false); });
+
+ _buttonbox->set_margin_start(XPAD);
+ _buttonbox->set_margin_end(XPAD);
+ _buttonbox->set_margin_top(YPAD);
+ _buttonbox->set_margin_bottom(YPAD);
+ _buttonbox->set_hexpand();
+ _buttonbox->set_valign(Gtk::ALIGN_START);
+ attach(*_buttonbox, 0, row, 2);
+
+ row++;
+
+ _book->set_margin_start(XPAD);
+ _book->set_margin_end(XPAD);
+ _book->set_margin_top(YPAD);
+ _book->set_margin_bottom(YPAD);
+ _book->set_hexpand();
+ _book->set_vexpand();
+ attach(*_book, 0, row, 2, 1);
+
+ // restore the last active page
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ _setCurrentPage(prefs->getInt("/colorselector/page", 0), true);
+ row++;
+
+ auto switcher_path = Glib::ustring("/colorselector/switcher");
+ auto choose_switch = [=](bool compact) {
+ if (compact) {
+ _switcher->hide();
+ _buttonbox->show();
+ }
+ else {
+ _buttonbox->hide();
+ _switcher->show();
+ }
+ };
+
+ _observer = prefs->createObserver(switcher_path, [=](const Preferences::Entry& new_value) {
+ choose_switch(new_value.getBool());
+ });
+
+ choose_switch(prefs->getBool(switcher_path));
+
+ GtkWidget *rgbabox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+
+ /* Create color management icons */
+ _box_colormanaged = gtk_event_box_new();
+ GtkWidget *colormanaged = sp_get_icon_image("color-management", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_container_add(GTK_CONTAINER(_box_colormanaged), colormanaged);
+ gtk_widget_set_tooltip_text(_box_colormanaged, _("Color Managed"));
+ gtk_widget_set_sensitive(_box_colormanaged, false);
+ gtk_box_pack_start(GTK_BOX(rgbabox), _box_colormanaged, FALSE, FALSE, 2);
+
+ _box_outofgamut = gtk_event_box_new();
+ GtkWidget *outofgamut = sp_get_icon_image("out-of-gamut-icon", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_container_add(GTK_CONTAINER(_box_outofgamut), outofgamut);
+ gtk_widget_set_tooltip_text(_box_outofgamut, _("Out of gamut!"));
+ gtk_widget_set_sensitive(_box_outofgamut, false);
+ gtk_box_pack_start(GTK_BOX(rgbabox), _box_outofgamut, FALSE, FALSE, 2);
+
+ _box_toomuchink = gtk_event_box_new();
+ GtkWidget *toomuchink = sp_get_icon_image("too-much-ink-icon", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_container_add(GTK_CONTAINER(_box_toomuchink), toomuchink);
+ gtk_widget_set_tooltip_text(_box_toomuchink, _("Too much ink!"));
+ gtk_widget_set_sensitive(_box_toomuchink, false);
+ gtk_box_pack_start(GTK_BOX(rgbabox), _box_toomuchink, FALSE, FALSE, 2);
+
+
+ /* Color picker */
+ GtkWidget *picker = sp_get_icon_image("color-picker", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ _btn_picker = gtk_button_new();
+ gtk_button_set_relief(GTK_BUTTON(_btn_picker), GTK_RELIEF_NONE);
+ gtk_container_add(GTK_CONTAINER(_btn_picker), picker);
+ gtk_widget_set_tooltip_text(_btn_picker, _("Pick colors from image"));
+ gtk_box_pack_start(GTK_BOX(rgbabox), _btn_picker, FALSE, FALSE, 2);
+ g_signal_connect(G_OBJECT(_btn_picker), "clicked", G_CALLBACK(ColorNotebook::_onPickerClicked), this);
+
+ /* Create RGBA entry and color preview */
+ _rgbal = gtk_label_new_with_mnemonic(_("RGBA_:"));
+ gtk_widget_set_halign(_rgbal, GTK_ALIGN_END);
+ gtk_box_pack_start(GTK_BOX(rgbabox), _rgbal, TRUE, TRUE, 2);
+
+ ColorEntry *rgba_entry = Gtk::manage(new ColorEntry(_selected_color));
+ sp_dialog_defocus_on_enter(GTK_WIDGET(rgba_entry->gobj()));
+ gtk_box_pack_start(GTK_BOX(rgbabox), GTK_WIDGET(rgba_entry->gobj()), FALSE, FALSE, 0);
+ gtk_label_set_mnemonic_widget(GTK_LABEL(_rgbal), GTK_WIDGET(rgba_entry->gobj()));
+
+ gtk_widget_show_all(rgbabox);
+
+ // the "too much ink" icon is initially hidden
+ gtk_widget_hide(GTK_WIDGET(_box_toomuchink));
+
+ gtk_widget_set_margin_start(rgbabox, XPAD);
+ gtk_widget_set_margin_end(rgbabox, XPAD);
+ gtk_widget_set_margin_top(rgbabox, YPAD);
+ gtk_widget_set_margin_bottom(rgbabox, YPAD);
+ attach(*Glib::wrap(rgbabox), 0, row, 2, 1);
+
+#ifdef SPCS_PREVIEW
+ _p = sp_color_preview_new(0xffffffff);
+ gtk_widget_show(_p);
+ attach(*Glib::wrap(_p), 2, 3, row, row + 1, Gtk::FILL, Gtk::FILL, XPAD, YPAD);
+#endif
+}
+
+void ColorNotebook::_onPickerClicked(GtkWidget * /*widget*/, ColorNotebook *colorbook)
+{
+ // Set the dropper into a "one click" mode, so it reverts to the previous tool after a click
+ if (colorbook->_onetimepick) {
+ colorbook->_onetimepick.disconnect();
+ }
+ else {
+ Inkscape::UI::Tools::sp_toggle_dropper(SP_ACTIVE_DESKTOP);
+ auto tool = dynamic_cast<Inkscape::UI::Tools::DropperTool *>(SP_ACTIVE_DESKTOP->event_context);
+ if (tool) {
+ colorbook->_onetimepick = tool->onetimepick_signal.connect(sigc::mem_fun(*colorbook, &ColorNotebook::_pickColor));
+ }
+ }
+}
+
+void ColorNotebook::_pickColor(ColorRGBA *color) {
+ // Set color to color notebook here.
+ _selected_color.setValue(color->getIntValue());
+ _onSelectedColorChanged();
+}
+
+void ColorNotebook::_onSelectedColorChanged() { _updateICCButtons(); }
+
+void ColorNotebook::_onPageSwitched(int page_num)
+{
+ if (get_visible()) {
+ // remember the page we switched to
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setInt("/colorselector/page", page_num);
+ }
+}
+
+
+// TODO pass in param so as to avoid the need for SP_ACTIVE_DOCUMENT
+void ColorNotebook::_updateICCButtons()
+{
+ SPColor color = _selected_color.color();
+ gfloat alpha = _selected_color.alpha();
+
+ g_return_if_fail((0.0 <= alpha) && (alpha <= 1.0));
+
+ /* update color management icon*/
+ gtk_widget_set_sensitive(_box_colormanaged, color.icc != nullptr);
+
+ /* update out-of-gamut icon */
+ gtk_widget_set_sensitive(_box_outofgamut, false);
+ if (color.icc) {
+ Inkscape::ColorProfile *target_profile =
+ SP_ACTIVE_DOCUMENT->getProfileManager()->find(color.icc->colorProfile.c_str());
+ if (target_profile)
+ gtk_widget_set_sensitive(_box_outofgamut, target_profile->GamutCheck(color));
+ }
+
+ /* update too-much-ink icon */
+ gtk_widget_set_sensitive(_box_toomuchink, false);
+ if (color.icc) {
+ Inkscape::ColorProfile *prof = SP_ACTIVE_DOCUMENT->getProfileManager()->find(color.icc->colorProfile.c_str());
+ if (prof && CMSSystem::isPrintColorSpace(prof)) {
+ gtk_widget_show(GTK_WIDGET(_box_toomuchink));
+ double ink_sum = 0;
+ for (double i : color.icc->colors) {
+ ink_sum += i;
+ }
+
+ /* Some literature states that when the sum of paint values exceed 320%, it is considered to be a satured color,
+ which means the paper can get too wet due to an excessive amount of ink. This may lead to several issues
+ such as misalignment and poor quality of printing in general.*/
+ if (ink_sum > 3.2)
+ gtk_widget_set_sensitive(_box_toomuchink, true);
+ }
+ else {
+ gtk_widget_hide(GTK_WIDGET(_box_toomuchink));
+ }
+ }
+}
+
+void ColorNotebook::_setCurrentPage(int i, bool sync_combo)
+{
+ const auto pages = _book->get_children();
+ if (i >= 0 && i < pages.size()) {
+ _book->set_visible_child(*pages[i]);
+ if (sync_combo) {
+ _combo->set_active_by_id(i);
+ }
+ _onPageSwitched(i);
+ }
+}
+
+void ColorNotebook::_addPage(Page &page)
+{
+ if (auto selector_widget = page.selector_factory->createWidget(_selected_color)) {
+ selector_widget->show();
+
+ Glib::ustring mode_name = page.selector_factory->modeName();
+ _book->add(*selector_widget, mode_name, mode_name);
+ int page_num = _book->get_children().size() - 1;
+
+ _combo->add_row(page.icon_name, mode_name, page_num);
+ }
+}
+
+}
+}
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :