Inkscape
Vector Graphics Editor
layer-selector.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Inkscape::Widgets::LayerSelector - layer selector widget
4 *
5 * Authors:
6 * MenTaLguY <mental@rydia.net>
7 * Abhishek Sharma
8 *
9 * Copyright (C) 2004 MenTaLguY
10 *
11 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
12 */
13
14#include "layer-selector.h"
15
16#include <string>
17#include <glibmm/i18n.h>
18#include <glibmm/ustring.h>
19#include <gdkmm/display.h>
20#include <gtkmm/cssprovider.h>
21#include <gtkmm/image.h>
22#include <gtkmm/styleprovider.h>
23#include <sigc++/functors/mem_fun.h>
24
25#include "desktop.h"
26#include "document-undo.h"
27#include "layer-manager.h"
30#include "ui/icon-loader.h"
31#include "ui/icon-names.h"
32#include "ui/pack.h"
33#include "ui/util.h"
34
35namespace Inkscape::UI::Widget {
36
37class AlternateIcons final : public Gtk::Box {
38public:
39 AlternateIcons(Gtk::IconSize const size, Glib::ustring const &a, Glib::ustring const &b)
40 : Gtk::Box(Gtk::Orientation::HORIZONTAL)
41 {
42 set_name("AlternateIcons");
43
44 if (!a.empty()) {
45 _a = Gtk::manage(sp_get_icon_image(a, size));
46 append(*_a);
47 }
48
49 if (!b.empty()) {
50 _b = Gtk::manage(sp_get_icon_image(b, size));
51 append(*_b);
52 }
53
54 setState(false);
55 }
56
57 bool state() const { return _state; }
58 void setState(bool state) {
59 _state = state;
60
61 if (_state) {
62 if (_a) _a->set_visible(false);
63 if (_b) _b->set_visible(true);
64 } else {
65 if (_a) _a->set_visible(true);
66 if (_b) _b->set_visible(false);
67 }
68 }
69
70private:
71 Gtk::Image *_a = nullptr;
72 Gtk::Image *_b = nullptr;
73 bool _state = false ;
74};
75
76static constexpr auto cssName = "LayerSelector";
77
79 : Gtk::Box(Gtk::Orientation::HORIZONTAL)
80 , _label_style{Gtk::CssProvider::create()}
81 , _observer{std::make_unique<Inkscape::XML::SignalObserver>()}
82{
83 set_name(cssName);
84 add_css_class(getThisCssClass());
85
86 _layer_name.signal_clicked().connect(sigc::mem_fun(*this, &LayerSelector::_layerChoose));
87 _layer_name.set_has_frame(false);
88 _layer_name.set_tooltip_text(_("Current layer"));
90
91 _eye_label = Gtk::make_managed<AlternateIcons>(Gtk::IconSize::NORMAL,
92 INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden"));
93 _eye_toggle.set_child(*_eye_label);
94 _hide_layer_connection = _eye_toggle.signal_toggled().connect(sigc::mem_fun(*this, &LayerSelector::_hideLayer));
95
96 _eye_toggle.set_has_frame(false);
97 _eye_toggle.set_tooltip_text(_("Toggle current layer visibility"));
99
100 _lock_label = Gtk::make_managed<AlternateIcons>(Gtk::IconSize::NORMAL,
101 INKSCAPE_ICON("object-unlocked"), INKSCAPE_ICON("object-locked"));
102 _lock_toggle.set_child(*_lock_label);
103 _lock_layer_connection = _lock_toggle.signal_toggled().connect(sigc::mem_fun(*this, &LayerSelector::_lockLayer));
104
105 _lock_toggle.set_has_frame(false);
106 _lock_toggle.set_tooltip_text(_("Lock or unlock current layer"));
108
109 _layer_name.set_child(_layer_label);
110 _layer_label.set_max_width_chars(16);
111 _layer_label.set_ellipsize(Pango::EllipsizeMode::END);
112 _layer_label.set_markup("<i>Unset</i>");
113 _layer_label.set_valign(Gtk::Align::CENTER);
114 Gtk::StyleProvider::add_provider_for_display(_layer_label.get_display(), _label_style,
115 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
116
117 _observer->signal_changed().connect(sigc::mem_fun(*this, &LayerSelector::_layerModified));
118 setDesktop(desktop);
119}
120
122 setDesktop(nullptr);
123}
124
126 if ( desktop == _desktop )
127 return;
128
130 _desktop = desktop;
131
132 if (_desktop) {
135 }
136}
137
142{
143 _layer = layer;
144 _observer->set(layer);
146}
147
152{
154 bool active = _layer && _layer != root;
155
156 auto color_str = std::string("white");
157
158 if (active) {
159 _layer_label.set_text(_layer->defaultLabel());
160 color_str = SPColor(_layer->highlight_color()).toString();
161 } else {
162 _layer_label.set_markup(_layer ? "<i>[root]</i>" : "<i>nothing</i>");
163 }
164
165 // Other border properties are set in share/ui/style.css
166 _label_style->load_from_data(Glib::ustring::compose("#%1.%2 label { border-color: %3; }",
167 cssName, getThisCssClass(), color_str));
168
171 _eye_toggle.set_sensitive(active);
172 _lock_toggle.set_sensitive(active);
173 _eye_label->setState(active && _layer->isHidden());
174 _eye_toggle.set_active(active && _layer->isHidden());
175 _lock_label->setState(active && _layer->isLocked());
176 _lock_toggle.set_active(active && _layer->isLocked());
179}
180
182{
183 bool lock = _lock_toggle.get_active();
184 if (auto layer = _desktop->layerManager().currentLayer()) {
185 layer->setLocked(lock);
186 DocumentUndo::done(_desktop->getDocument(), lock ? _("Lock layer") : _("Unlock layer"), "");
187 }
188}
189
191{
192 bool hide = _eye_toggle.get_active();
193 if (auto layer = _desktop->layerManager().currentLayer()) {
194 layer->setHidden(hide);
195 DocumentUndo::done(_desktop->getDocument(), hide ? _("Hide layer") : _("Unhide layer"), "");
196 }
197}
198
200{
201 _desktop->getContainer()->new_dialog("Objects");
202}
203
205{
206 return "this" + std::to_string(reinterpret_cast<uintptr_t>(this));
207}
208
209} // namespace Inkscape::UI::Widget
210
211/*
212 Local Variables:
213 mode:c++
214 c-file-style:"stroustrup"
215 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
216 indent-tabs-mode:nil
217 fill-column:99
218 End:
219*/
220// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon)
SPGroup * currentLayer() const
Returns current top layer.
SPGroup * currentRoot() const
Returns current root (=bottom) layer.
sigc::connection connectCurrentLayerChanged(const sigc::slot< void(SPGroup *)> &slot)
Definition: layer-manager.h:37
void new_dialog(const Glib::ustring &dialog_type)
Add new dialog to the current container or in a floating window, based on preferences.
std::unique_ptr< Inkscape::XML::SignalObserver > _observer
void _layerModified()
If anything happens to the layer, refresh it.
Glib::RefPtr< Gtk::CssProvider > _label_style
void setDesktop(SPDesktop *desktop)
void _layerChanged(SPGroup *layer)
Selects the given layer in the widget.
LayerSelector(SPDesktop *desktop=nullptr)
bool block(bool should_block=true) noexcept
Sets or unsets the blocking state of this connection.
An RGB color with optional icc-color part.
Definition: color.h:51
std::string toString() const
Definition: color.cpp:247
To do: update description of desktop.
Definition: desktop.h:150
SPDocument * getDocument() const
Definition: desktop.h:187
Inkscape::UI::Dialog::DialogContainer * getContainer()
Definition: desktop.cpp:413
Inkscape::LayerManager & layerManager()
Definition: desktop.h:300
guint32 highlight_color() const override
Generate a highlight colour if one isn't set and return it.
bool isHidden() const
Definition: sp-item.cpp:167
bool isLocked() const
Definition: sp-item.cpp:150
char const * defaultLabel() const
Returns a default label property for this object.
Definition: sp-object.cpp:432
RootCluster root
Definition: containment.cpp:50
Editable view implementation.
A widget that manages DialogNotebook's and other widgets inside a horizontal DialogMultipaned.
TODO: insert short description here.
Gtk::Image * sp_get_icon_image(Glib::ustring const &icon_name, int size)
Definition: icon-loader.cpp:27
Icon Loader.
Macro for icon names used in Inkscape.
D2< T > compose(D2< T > const &a, T const &b)
Definition: d2.h:405
Definition: desktop.h:51
Custom widgets.
Definition: desktop.h:127
static constexpr auto cssName
void pack_start(Gtk::Box &box, Gtk::Widget &child, bool const expand, bool const fill, unsigned const padding)
Adds child to box, packed with reference to the start of box.
Definition: pack.cpp:141
CMYK to sRGB conversion routines.
static void append(std::vector< T > &target, std::vector< T > &&source)
Definition: shortcuts.cpp:515
STL namespace.
@ HORIZONTAL
The x-dimension (0).
Definition: rectangle.h:43
Helpers for using Gtk::Boxes, encapsulating large changes between GTK3 & GTK4.
std::unique_ptr< Toolbar >(* create)(SPDesktop *desktop)
Definition: toolbars.cpp:63