Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
spiral-toolbar.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
5/* Authors:
6 * MenTaLguY <mental@rydia.net>
7 * Lauris Kaplinski <lauris@kaplinski.com>
8 * bulia byak <buliabyak@users.sf.net>
9 * Frank Felfe <innerspace@iname.com>
10 * John Cliff <simarilius@yahoo.com>
11 * David Turner <novalis@gnu.org>
12 * Josh Andler <scislac@scislac.com>
13 * Jon A. Cruz <jon@joncruz.org>
14 * Maximilian Albert <maximilian.albert@gmail.com>
15 * Tavmjong Bah <tavmjong@free.fr>
16 * Abhishek Sharma
17 * Kris De Gussem <Kris.DeGussem@gmail.com>
18 * Vaibhav Malik <vaibhavmalik2018@gmail.com>
19 *
20 * Copyright (C) 2004 David Turner
21 * Copyright (C) 2003 MenTaLguY
22 * Copyright (C) 1999-2011 authors
23 * Copyright (C) 2001-2002 Ximian, Inc.
24 *
25 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
26 */
27
28#include "spiral-toolbar.h"
29
30#include <glibmm/i18n.h>
31#include <gtkmm/adjustment.h>
32#include <gtkmm/box.h>
33#include <gtkmm/button.h>
34#include <gtkmm/label.h>
35
36#include "desktop.h"
37#include "document-undo.h"
38#include "preferences.h"
39
40#include "object/sp-spiral.h"
41#include "selection.h"
42#include "ui/builder-utils.h"
43#include "ui/icon-names.h"
45#include "xml/node.h"
46
48
49namespace Inkscape::UI::Toolbar {
50
54
55SpiralToolbar::SpiralToolbar(Glib::RefPtr<Gtk::Builder> const &builder)
56 : Toolbar{get_widget<Gtk::Box>(builder, "spiral-toolbar")}
57 , _mode_item{get_widget<Gtk::Label>(builder, "_mode_item")}
58 , _revolution_item{get_derived_widget<UI::Widget::SpinButton>(builder, "_revolution_item")}
59 , _expansion_item{get_derived_widget<UI::Widget::SpinButton>(builder, "_expansion_item")}
60 , _t0_item{get_derived_widget<UI::Widget::SpinButton>(builder, "_t0_item")}
61{
62 _setupDerivedSpinButton(_revolution_item, "revolution", 3.0);
65
67 {0.01, _("just a curve")},
68 {0.5, ""},
69 {1, _("one full revolution")},
70 {2, ""},
71 {3, ""},
72 {5, ""},
73 {10, ""},
74 {50, ""},
75 {100, ""}
76 });
77
79 {0, _("circle")},
80 {0.1, _("edge is much denser")},
81 {0.5, _("edge is denser")},
82 {1, _("even")},
83 {1.5, _("center is denser")},
84 {5, _("center is much denser")},
85 {20, ""}
86 });
87
89 {0, _("starts from center")},
90 {0.5, _("starts mid-way")},
91 {0.9, _("starts near edge")},
92 });
93
94 get_widget<Gtk::Button>(builder, "reset_btn")
95 .signal_clicked()
96 .connect(sigc::mem_fun(*this, &SpiralToolbar::_setDefaults));
97
99}
100
101void SpiralToolbar::_setupDerivedSpinButton(UI::Widget::SpinButton &btn, Glib::ustring const &name, double default_value)
102{
103 auto const adj = btn.get_adjustment();
104 auto const path = "/tools/shapes/spiral/" + name;
105 auto const val = Preferences::get()->getDouble(path, default_value);
106 adj->set_value(val);
107
108 adj->signal_value_changed().connect(sigc::bind(sigc::mem_fun(*this, &SpiralToolbar::_valueChanged), adj, name));
109
110 btn.setDefocusTarget(this);
111}
112
114{
115 if (_desktop) {
116 _selection_changed_conn.disconnect();
117
118 if (_repr) {
119 _detachRepr();
120 }
121 }
122
124
125 if (_desktop) {
126 auto sel = _desktop->getSelection();
128 _selectionChanged(sel); // Synthesize an emission to trigger the update
129 }
130}
131
133{
134 assert(!_repr);
135 _repr = repr;
137 _repr->addObserver(*this);
138}
139
141{
142 assert(_repr);
143 _repr->removeObserver(*this);
145 _repr = nullptr;
147}
148
149void SpiralToolbar::_valueChanged(Glib::RefPtr<Gtk::Adjustment> &adj, Glib::ustring const &value_name)
150{
152 Preferences::get()->setDouble("/tools/shapes/spiral/" + value_name, adj->get_value());
153 }
154
155 // quit if run by the attr_changed listener
156 if (_blocker.pending()) {
157 return;
158 }
159
160 // in turn, prevent listener from responding
161 auto guard = _blocker.block();
162
163 auto const namespaced_name = "sodipodi:" + value_name;
164
165 bool modified = false;
166 for (auto item : _desktop->getSelection()->items()) {
167 if (is<SPSpiral>(item)) {
168 auto repr = item->getRepr();
169 repr->setAttributeSvgDouble(namespaced_name, adj->get_value());
170 item->updateRepr();
171 modified = true;
172 }
173 }
174
175 if (modified) {
176 DocumentUndo::done(_desktop->getDocument(), _("Change spiral"), INKSCAPE_ICON("draw-spiral"));
177 }
178}
179
181{
182 // fixme: make settable
183 _revolution_item.get_adjustment()->set_value(3);
184 _expansion_item.get_adjustment()->set_value(1.0);
185 _t0_item.get_adjustment()->set_value(0.0);
186
187 onDefocus();
188}
189
191{
192 if (_repr) {
193 _detachRepr();
194 }
195
196 int n_selected = 0;
197 XML::Node *repr = nullptr;
198
199 for (auto item : selection->items()) {
200 if (is<SPSpiral>(item)) {
201 n_selected++;
202 repr = item->getRepr();
203 }
204 }
205
206 _mode_item.set_markup(n_selected == 0 ? _("<b>New:</b>") : _("<b>Change:</b>"));
207
208 if (n_selected == 1) {
209 _attachRepr(repr);
210 _repr->synthesizeEvents(*this);
211 }
212}
213
215{
216 assert(_repr);
217
218 // quit if run by the UI callbacks
219 if (_blocker.pending()) {
220 return;
221 }
222
223 _queueUpdate();
224}
225
227{
228 if (_tick_callback) {
229 return;
230 }
231
232 _tick_callback = add_tick_callback([this] (Glib::RefPtr<Gdk::FrameClock> const &) {
233 _update();
234 _tick_callback = 0;
235 return false;
236 });
237}
238
240{
241 if (!_tick_callback) {
242 return;
243 }
244
245 remove_tick_callback(_tick_callback);
246 _tick_callback = 0;
247}
248
250{
251 assert(_repr);
252
253 // prevent UI callbacks from responding
254 auto guard = _blocker.block();
255
256 _revolution_item.get_adjustment()->set_value(_repr->getAttributeDouble("sodipodi:revolution", 3.0));
257 _expansion_item.get_adjustment()->set_value(_repr->getAttributeDouble("sodipodi:expansion", 1.0));
258 _t0_item.get_adjustment()->set_value(_repr->getAttributeDouble("sodipodi:t0", 0.0));
259}
260
261} // namespace Inkscape::UI::Toolbar
262
263/*
264 Local Variables:
265 mode:c++
266 c-file-style:"stroustrup"
267 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
268 indent-tabs-mode:nil
269 fill-column:99
270 End:
271*/
272// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Gtk builder utilities.
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
static bool getUndoSensitive(SPDocument const *document)
SPItemRange items()
Returns a range of selected SPItems.
Definition object-set.h:255
double getDouble(Glib::ustring const &pref_path, double def=0.0, Glib::ustring const &unit="")
Retrieve a floating point value.
static Preferences * get()
Access the singleton Preferences object.
void setDouble(Glib::ustring const &pref_path, double value)
Set a floating point value.
The set of selected SPObjects for a given document and layer model.
Definition selection.h:80
sigc::connection connectChanged(sigc::slot< void(Selection *)> slot)
Connects a slot to be notified of selection changes.
Definition selection.h:179
UI::Widget::SpinButton & _t0_item
void setDesktop(SPDesktop *desktop) override
void _valueChanged(Glib::RefPtr< Gtk::Adjustment > &adj, Glib::ustring const &value_name)
UI::Widget::SpinButton & _expansion_item
void _setupDerivedSpinButton(UI::Widget::SpinButton &btn, Glib::ustring const &name, double default_value)
UI::Widget::SpinButton & _revolution_item
void _selectionChanged(Selection *selection)
void notifyAttributeChanged(XML::Node &node, GQuark key, Util::ptr_shared oldval, Util::ptr_shared newval) override
Attribute change callback.
Base class for all tool toolbars.
Definition toolbar.h:72
virtual void setDesktop(SPDesktop *desktop)
Definition toolbar.h:76
SpinButton widget, that allows entry of simple math expressions (also units, when linked with UnitMen...
Definition spinbutton.h:52
void setDefocusTarget(decltype(_defocus_target) target)
Definition spinbutton.h:127
void set_custom_numeric_menu_data(NumericMenuData &&custom_menu_data)
Interface for refcounted XML nodes.
Definition node.h:80
virtual void synthesizeEvents(NodeObserver &observer)=0
Generate a sequence of events corresponding to the state of this node.
double getAttributeDouble(Util::const_char_ptr key, double default_value=0.0) const
Definition node.cpp:76
virtual void addObserver(NodeObserver &observer)=0
Add an object that will be notified of the changes to this node.
virtual void removeObserver(NodeObserver &observer)=0
Remove an object from the list of observers.
bool setAttributeSvgDouble(Util::const_char_ptr key, double val)
For attributes where an exponent is allowed.
Definition node.cpp:111
scoped_block block()
To do: update description of desktop.
Definition desktop.h:149
SPDocument * getDocument() const
Definition desktop.h:189
Inkscape::Selection * getSelection() const
Definition desktop.h:188
Inkscape::XML::Node * updateRepr(unsigned int flags=SP_OBJECT_WRITE_EXT)
Updates the object's repr based on the object's state.
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
Editable view implementation.
TODO: insert short description here.
Macro for icon names used in Inkscape.
SPItem * item
Definition desktop.h:50
static R & anchor(R &r)
Increments the reference count of a anchored object.
Definition gc-anchored.h:92
static R & release(R &r)
Decrements the reference count of a anchored object.
W & get_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id)
W & get_derived_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id, Args &&... args)
Glib::RefPtr< Gtk::Builder > create_builder(const char *filename)
Singleton class to access the preferences file in a convenient way.
guint32 GQuark
SPDesktop * desktop
Glib::ustring name
Definition toolbars.cpp:55
Glib::RefPtr< Gtk::Builder > builder
Interface for XML nodes.