Inkscape
Vector Graphics Editor
scalar-unit.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Authors:
4 * Bryce Harrington <bryce@bryceharrington.org>
5 * Derek P. Moore <derekm@hackunix.org>
6 * buliabyak@gmail.com
7 *
8 * Copyright (C) 2004-2005 Authors
9 *
10 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
11 */
12
13#include "scalar-unit.h"
14
15#include <utility>
16
17#include "spinbutton.h"
18#include "ui/pack.h"
19
20namespace Inkscape::UI::Widget {
21
22ScalarUnit::ScalarUnit(Glib::ustring const &label, Glib::ustring const &tooltip,
23 UnitType unit_type,
24 Glib::ustring const &icon,
25 UnitMenu *unit_menu,
26 bool mnemonic)
27 : Scalar(label, tooltip, icon, mnemonic),
28 _unit_menu(unit_menu),
29 _hundred_percent(0),
30 _absolute_is_increment(false),
31 _percentage_is_increment(false)
32{
33 if (!_unit_menu) {
34 _unit_menu = Gtk::make_managed<UnitMenu>();
35 _unit_menu->setUnitType(unit_type);
36
37 auto const widget = getWidget();
38 g_assert(widget);
39 widget->reference();
40 remove(*widget);
41 auto const widget_holder = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 6);
44 UI::pack_start(*this, *widget_holder, UI::PackOptions::shrink);
45 widget->unreference();
46 }
47
48 g_assert(_unit_menu);
49
50 _unit_menu->signal_changed()
51 .connect(sigc::mem_fun(*this, &ScalarUnit::on_unit_changed));
52
54
56}
57
58ScalarUnit::ScalarUnit(Glib::ustring const &label, Glib::ustring const &tooltip,
59 ScalarUnit &take_unitmenu,
60 Glib::ustring const &icon,
61 bool mnemonic)
62 : ScalarUnit{label, tooltip, UnitType{}, icon, take_unitmenu._unit_menu, mnemonic}
63{
64}
65
66void ScalarUnit::initScalar(double min_value, double max_value)
67{
71 Scalar::setRange(min_value, max_value);
72}
73
74bool ScalarUnit::setUnit(Glib::ustring const &unit)
75{
76 // First set the unit
77 if (!_unit_menu->setUnit(unit)) {
78 return false;
79 }
80 lastUnits = unit;
81 return true;
82}
83
85{
86 _unit_menu->setUnitType(unit_type);
88}
89
91{
92 _unit_menu->resetUnitType(unit_type);
94}
95
96Unit const * ScalarUnit::getUnit() const
97{
98 return _unit_menu->getUnit();
99}
100
102{
103 return _unit_menu->getUnitType();
104}
105
106void ScalarUnit::setValue(double number, Glib::ustring const &units)
107{
108 _unit_menu->setUnit(units);
109 Scalar::setValue(number);
110}
111
112void ScalarUnit::setValueKeepUnit(double number, Glib::ustring const &units)
113{
114 if (units.empty()) {
115 // set the value in the default units
116 Scalar::setValue(number);
117 } else {
118 double conversion = _unit_menu->getConversion(units);
119 Scalar::setValue(number / conversion);
120 }
121}
122
123void ScalarUnit::setValue(double number)
124{
125 Scalar::setValue(number);
126}
127
128double ScalarUnit::getValue(Glib::ustring const &unit_name) const
129{
130 if (unit_name.empty()) {
131 // Return the value in the default units
132 return Scalar::getValue();
133 } else {
134 double conversion = _unit_menu->getConversion(unit_name);
135 return conversion * Scalar::getValue();
136 }
137}
138
140{
141 auto &spinButton = getSpinButton();
142 spinButton.grab_focus();
143 spinButton.select_region(0, 20);
144}
145
146void ScalarUnit::setAlignment(double xalign)
147{
148 xalign = std::clamp(xalign,0.0,1.0);
149 getSpinButton().set_alignment(xalign);
150}
151
153{
154 _hundred_percent = number;
155}
156
158{
160}
161
163{
165}
166
168{
169 // convert from percent to absolute
170 double convertedVal = 0;
171 double hundred_converted = _hundred_percent / _unit_menu->getConversion("px"); // _hundred_percent is in px
173 value += 100;
174 convertedVal = 0.01 * hundred_converted * value;
176 convertedVal -= hundred_converted;
177
178 return convertedVal;
179}
180
182{
183 double convertedVal = 0;
184 // convert from absolute to percent
185 if (_hundred_percent == 0) {
187 convertedVal = 0;
188 else
189 convertedVal = 100;
190 } else {
191 double hundred_converted = _hundred_percent / _unit_menu->getConversion("px", lastUnits); // _hundred_percent is in px
193 value += hundred_converted;
194 convertedVal = 100 * value / hundred_converted;
196 convertedVal -= 100;
197 }
198
199 return convertedVal;
200}
201
203{
204 double convertedVal = AbsoluteToPercentage(Scalar::getValue());
205 return convertedVal;
206}
207
209{
210 double absolute = PercentageToAbsolute(value);
212}
213
215{
216 Glib::ustring abbr = _unit_menu->getUnitAbbr();
217 auto const &unit_table = Util::UnitTable::get();
218 Inkscape::Util::Unit const *new_unit = unit_table.getUnit(abbr);
219 Inkscape::Util::Unit const *old_unit = unit_table.getUnit(lastUnits);
220
221 double convertedVal = 0;
222 if (old_unit->type == UNIT_TYPE_DIMENSIONLESS && new_unit->type == UNIT_TYPE_LINEAR) {
223 convertedVal = PercentageToAbsolute(Scalar::getValue());
224 } else if (old_unit->type == UNIT_TYPE_LINEAR && new_unit->type == UNIT_TYPE_DIMENSIONLESS) {
225 convertedVal = AbsoluteToPercentage(Scalar::getValue());
226 } else {
227 double conversion = _unit_menu->getConversion(lastUnits);
228 convertedVal = Scalar::getValue() / conversion;
229 }
230 Scalar::setValue(convertedVal);
231
232 lastUnits = std::move(abbr);
233}
234
235} // namespace Inkscape::UI::Widget
236
237/*
238 Local Variables:
239 mode:c++
240 c-file-style:"stroustrup"
241 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
242 indent-tabs-mode:nil
243 fill-column:99
244 End:
245*/
246// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Gtk::Widget const * getWidget() const
Definition: labelled.h:48
A labelled text box, with spin buttons and optional icon, for entering the values of various unit typ...
Definition: scalar-unit.h:35
void setValue(double number, Glib::ustring const &units)
Sets the number and unit system.
double PercentageToAbsolute(double value)
Convert value from % to absolute, using _hundred_percent and *_is_increment flags.
void setUnitType(UnitType unit_type)
Adds the unit type to the ScalarUnit widget.
Definition: scalar-unit.cpp:84
double AbsoluteToPercentage(double value)
Convert value from absolute to %, using _hundred_percent and *_is_increment flags.
void grabFocusAndSelectEntry()
Grab focus, and select the text that is in the entry field.
bool setUnit(Glib::ustring const &units)
Sets the unit for the ScalarUnit widget.
Definition: scalar-unit.cpp:74
void setAlignment(double xalign)
allow align text in entry.
void resetUnitType(UnitType unit_type)
Resets the unit type for the ScalarUnit widget.
Definition: scalar-unit.cpp:90
void setValueKeepUnit(double number, Glib::ustring const &units)
Convert and sets the number only and keeps the current unit.
Unit const * getUnit() const
Gets the object for the currently selected unit.
Definition: scalar-unit.cpp:96
void setAbsoluteIsIncrement(bool value)
void initScalar(double min_value, double max_value)
Initializes the scalar based on the settings in _unit_menu.
Definition: scalar-unit.cpp:66
ScalarUnit(Glib::ustring const &label, Glib::ustring const &tooltip, UnitType unit_type=UNIT_TYPE_LINEAR, Glib::ustring const &icon={}, UnitMenu *unit_menu=nullptr, bool mnemonic=true)
Construct a ScalarUnit.
Definition: scalar-unit.cpp:22
void setPercentageIsIncrement(bool value)
void on_unit_changed()
Signal handler for updating the value when unit is changed.
UnitType getUnitType() const
Gets the UnitType ID for the unit.
void setFromPercentage(double value)
Assuming the current unit is absolute, set the value corresponding to a given %.
void setHundredPercent(double number)
double getAsPercentage()
Assuming the current unit is absolute, get the corresponding % value.
A labelled text box, with spin buttons and optional icon, for entering arbitrary number values.
Definition: scalar.h:34
void setIncrements(double step, double page)
Sets the step and page increments for the spin button.
Definition: scalar.cpp:123
void setDigits(unsigned digits)
Sets the precision to be displayed by the spin button.
Definition: scalar.cpp:94
void setRange(double min, double max)
Sets the minimum and maximum range allowed for the spin button.
Definition: scalar.cpp:128
SpinButton const & getSpinButton() const
Definition: scalar.cpp:178
void setValue(double value, bool setProg=true)
Sets the value of the spin button.
Definition: scalar.cpp:133
double getValue() const
Get the value in the spin_button.
Definition: scalar.cpp:83
void setUnitMenu(UnitMenu *unit_menu)
Definition: spinbutton.h:64
A drop down menu for choosing unit types.
Definition: unit-menu.h:31
Unit const * getUnit() const
Returns the Unit object corresponding to the current selection in the dropdown widget.
Definition: unit-menu.cpp:58
double getDefaultStep() const
Returns the recommended step size in spin buttons displaying units of this type.
Definition: unit-menu.cpp:100
UnitType getUnitType() const
Returns the UnitType of the selected unit.
Definition: unit-menu.cpp:85
int getDefaultDigits() const
Returns the recommended number of digits for displaying numbers of this unit type.
Definition: unit-menu.cpp:95
double getConversion(Glib::ustring const &new_unit_abbr, Glib::ustring const &old_unit_abbr="no_unit") const
Returns the conversion factor required to convert values of the currently selected unit into units of...
Definition: unit-menu.cpp:111
bool setUnit(Glib::ustring const &unit)
Sets the dropdown widget to the given unit abbreviation.
Definition: unit-menu.cpp:68
double getDefaultPage() const
Returns the recommended page size (when hitting pgup/pgdn) in spin buttons displaying units of this t...
Definition: unit-menu.cpp:106
Glib::ustring getUnitAbbr() const
Returns the abbreviated unit name of the selected unit.
Definition: unit-menu.cpp:77
bool resetUnitType(UnitType unit_type)
Removes all unit entries, then adds the unit type to the widget.
Definition: unit-menu.cpp:45
bool setUnitType(UnitType unit_type)
Adds the unit type to the widget.
Definition: unit-menu.cpp:30
static UnitTable & get()
Definition: units.cpp:410
UnitType type
Definition: units.h:72
auto absolute(Geom::Point const &a)
Definition: geom.h:90
int clamp(int const val)
Clamps an integer value to a value between 0 and 255.
Custom widgets.
Definition: desktop.h:127
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
@ UNIT_TYPE_DIMENSIONLESS
Definition: units.h:33
@ UNIT_TYPE_LINEAR
Definition: units.h:34
@ HORIZONTAL
The x-dimension (0).
Definition: rectangle.h:43
Helpers for using Gtk::Boxes, encapsulating large changes between GTK3 & GTK4.
void remove(std::vector< T > &vec, T const &val)
Definition: sanitize.cpp:94