Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
color-page.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
/*
5 * Copyright (C) 2024 Authors
6 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
7 */
8
10
11#include <gtkmm/adjustment.h>
12#include <gtkmm/box.h>
13#include <gtkmm/grid.h>
14#include <gtkmm/label.h>
15
16#include <utility>
17
18#include "color-wheel-factory.h"
19#include "ink-color-wheel.h"
20#include "ink-spin-button.h"
21#include "colors/color.h"
22#include "colors/color-set.h"
23#include "colors/spaces/base.h"
25#include "ui/builder-utils.h"
26#include "util/signal-blocker.h"
27
28namespace Inkscape::UI::Widget {
29
30static unsigned int MAX_COMPONENTS = 6;
31
32ColorPage::ColorPage(std::shared_ptr<Space::AnySpace> space, std::shared_ptr<ColorSet> colors)
33 : Gtk::Box()
34 , _builder(create_builder("color-page.glade"))
35 , _space(std::move(space))
36 , _selected_colors(std::move(colors))
37 , _specific_colors(std::make_shared<Colors::ColorSet>(_space, true))
38 , _expander(get_widget<Gtk::Expander>(_builder, "wheel-expander"))
39{
40 set_name("ColorPage");
41 append(get_widget<Gtk::Grid>(_builder, "color-page"));
42
43 // Keep the selected colorset in-sync with the space specific colorset.
44 _specific_changed_connection = _specific_colors->signal_changed.connect([this]() {
46 for (auto &[id, color] : *_specific_colors) {
47 _selected_colors->set(id, color);
48 }
49 if (_color_wheel && _color_wheel->get_widget().is_drawable()) {
51 }
52 });
53
54 // Keep the child in-sync with the selected colorset.
55 _selected_changed_connection = _selected_colors->signal_changed.connect([this]() {
57 for (auto &[id, color] : *_selected_colors) {
58 _specific_colors->set(id, color);
59 }
60 });
61
62 // Control signals when widget isn't mapped (not visible to the user)
63 signal_map().connect([this]() {
67 });
68
69 signal_unmap().connect([this]() {
70 _specific_colors->clear();
73 });
74
75 // init ink spin button once before builder-derived instance is created to register its custom type first
76 //todo: not working after all...
77 // InkSpinButton dummy;
78
79 for (auto &component : _specific_colors->getComponents()) {
80 std::string index = std::to_string(component.index + 1);
81 _channels.emplace_back(std::make_unique<ColorPageChannel>(
83 get_widget<Gtk::Label>(_builder, ("label" + index).c_str()),
84 get_derived_widget<ColorSlider>(_builder, ("slider" + index).c_str(), _specific_colors, component),
85 get_derived_widget<InkSpinButton>(_builder, ("spin" + index).c_str())
86 ));
87 }
88
89 // Hide unncessary channel widgets
90 for (auto j = _specific_colors->getComponents().size(); j < MAX_COMPONENTS; j++) {
91 std::string index = std::to_string(j+1);
92 hide_widget(_builder, "label" + index);
93 hide_widget(_builder, "slider" + index);
94 hide_widget(_builder, "spin" + index);
95 hide_widget(_builder, "separator" + index);
96 }
97
98 // Color wheel
99 auto wheel_type = _specific_colors->getComponents().get_wheel_type();
100 // there are only a few types of color wheel supported:
101 if (can_create_color_wheel(wheel_type)) {
102 _expander.property_expanded().signal_changed().connect([this, wheel_type]() {
103 auto on = _expander.property_expanded().get_value();
104 if (on && !_color_wheel) {
105 // create color wheel now
107 _expander.set_child(_color_wheel->get_widget());
110 auto scoped = SignalBlocker{_color_wheel_changed};
111 _specific_colors->setAll(color);
112 });
113 }
114 if (_color_wheel) {
115 if (on) {
116 // update, wheel may be stale if it was hidden
118 }
119 }
120 });
121 }
122 else {
123 _expander.set_visible(false);
124 }
125}
126
128 std::shared_ptr<Colors::ColorSet> color,
129 Gtk::Label &label,
130 ColorSlider &slider,
131 InkSpinButton &spin)
132 : _label(label)
133 , _slider(slider)
134 , _spin(spin)
135 , _adj(spin.get_adjustment()), _color(std::move(color))
136{
137 auto &component = _slider._component;
138 _label.set_markup_with_mnemonic(component.name);
139 _label.set_tooltip_text(component.tip);
140
141 _slider.set_hexpand(true);
142
143 _adj->set_lower(0.0);
144 _adj->set_upper(component.scale);
145 _adj->set_page_increment(0.0);
146 _adj->set_page_size(0.0);
147
148 _spin.set_has_frame(false);
149 _spin.set_digits(0);
151
152 _color_changed = _color->signal_changed.connect([this]() {
153 if (_color->isValid(_slider._component)) {
154 _adj->set_value(_slider.getScaled());
155 }
156 });
157 _adj_changed = _adj->signal_value_changed().connect([this]() {
158 auto scoped = SignalBlocker{_slider_changed};
159 _slider.setScaled(_adj->get_value());
160 });
161 _slider_changed = _slider.signal_value_changed.connect([this]() {
162 auto scoped = SignalBlocker{_adj_changed};
163 _adj->set_value(_slider.getScaled());
164 });
165}
166
167} // namespace Inkscape::UI::Widget
168
169/*
170 Local Variables:
171 mode:c++
172 c-file-style:"stroustrup"
173 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
174 indent-tabs-mode:nil
175 fill-column:99
176 End:
177*/
178// vim:filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8: textwidth=99:
Gtk builder utilities.
std::shared_ptr< Colors::ColorSet > _color
Definition color-page.h:74
Glib::RefPtr< Gtk::Adjustment > _adj
Definition color-page.h:73
ColorPageChannel(std::shared_ptr< Colors::ColorSet > color, Gtk::Label &label, ColorSlider &slider, InkSpinButton &spin)
sigc::scoped_connection _color_changed
Definition color-page.h:77
sigc::scoped_connection _adj_changed
Definition color-page.h:75
sigc::scoped_connection _slider_changed
Definition color-page.h:76
std::shared_ptr< ColorSet > _specific_colors
Definition color-page.h:49
std::shared_ptr< ColorSet > _selected_colors
Definition color-page.h:48
ColorPage(std::shared_ptr< Space::AnySpace > space, std::shared_ptr< ColorSet > colors)
std::vector< std::unique_ptr< ColorPageChannel > > _channels
Definition color-page.h:51
sigc::scoped_connection _color_wheel_changed
Definition color-page.h:56
sigc::scoped_connection _specific_changed_connection
Definition color-page.h:53
Glib::RefPtr< Gtk::Builder > _builder
Definition color-page.h:45
sigc::scoped_connection _selected_changed_connection
Definition color-page.h:54
Colors::Space::Component _component
sigc::signal< void()> signal_value_changed
virtual sigc::connection connect_color_changed(sigc::slot< void(const Colors::Color &)>)=0
virtual Gtk::Widget & get_widget()=0
virtual void set_color(const Colors::Color &color)=0
void set_adjustment(const Glib::RefPtr< Gtk::Adjustment > &adjustment)
RAII blocker for sigc++ signals.
Build a set of color sliders for a given color space.
A set of colors which can be modified together used for color pickers.
Glib::ustring label
Definition desktop.h:50
Custom widgets.
Definition desktop.h:126
bool can_create_color_wheel(Type type)
static unsigned int MAX_COMPONENTS
ColorWheel * create_managed_color_wheel(Type type)
W & get_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id)
Glib::RefPtr< Gtk::Builder > create_builder(const char *filename)
bool hide_widget(const Glib::RefPtr< Gtk::Builder > &builder, std::string const &id)
static void append(std::vector< T > &target, std::vector< T > &&source)
STL namespace.
int index