Code

Super duper mega (fun!) commit: replaced encoding=utf-8 with fileencoding=utf-8 in...
[inkscape.git] / src / ui / widget / scalar-unit.cpp
1 /**
2  * \brief Scalar Unit Widget - A labelled text box, with spin buttons and
3  *        optional icon or suffix, for entering the values of various unit
4  *        types.
5  *
6  * A ScalarUnit is a control for entering, viewing, or manipulating
7  * numbers with units.  This differs from ordinary numbers like 2 or
8  * 3.14 because the number portion of a scalar *only* has meaning
9  * when considered with its unit type.  For instance, 12 m and 12 in
10  * have very different actual values, but 1 m and 100 cm have the same
11  * value.  The ScalarUnit allows us to abstract the presentation of
12  * the scalar to the user from the internal representations used by
13  * the program.
14  *
15  * Authors:
16  *   Bryce Harrington <bryce@bryceharrington.org>
17  *   Derek P. Moore <derekm@hackunix.org>
18  *   buliabyak@gmail.com
19  *
20  * Copyright (C) 2004-2005 Authors
21  *
22  * Released under GNU GPL.  Read the file 'COPYING' for more information.
23  */
25 #ifdef HAVE_CONFIG_H
26 # include <config.h>
27 #endif
29 #include "scalar-unit.h"
31 namespace Inkscape {
32 namespace UI {
33 namespace Widget {
35 /**
36  * Construct a ScalarUnit
37  *
38  * \param label      Label.
39  * \param unit_type  Unit type (defaults to UNIT_TYPE_LINEAR).
40  * \param suffix     Suffix, placed after the widget (defaults to "").
41  * \param icon       Icon filename, placed before the label (defaults to "").
42  * \param unit_menu  UnitMenu drop down; if not specified, one will be created
43  *                   and displayed after the widget (defaults to NULL).
44  * \param mnemonic   Mnemonic toggle; if true, an underscore (_) in the label
45  *                   indicates the next character should be used for the
46  *                   mnemonic accelerator key (defaults to true).
47  */
48 ScalarUnit::ScalarUnit(Glib::ustring const &label, Glib::ustring const &tooltip,
49                        UnitType unit_type,
50                        Glib::ustring const &suffix,
51                        Glib::ustring const &icon,
52                        UnitMenu *unit_menu,
53                        bool mnemonic)
54     : Scalar(label, tooltip, suffix, icon, mnemonic),
55       _unit_menu(unit_menu),
56       _hundred_percent(0),
57       _absolute_is_increment(false),
58       _percentage_is_increment(false)
59 {
60     if (_unit_menu == NULL) {
61         _unit_menu = new UnitMenu();
62         g_assert(_unit_menu);
63         _unit_menu->setUnitType(unit_type);
64         pack_start(*Gtk::manage(_unit_menu), false, false, 4);
65     }
66     _unit_menu->signal_changed()
67             .connect_notify(sigc::mem_fun(*this, &ScalarUnit::on_unit_changed));
68 }
70 /**
71  * Initializes the scalar based on the settings in _unit_menu.
72  * Requires that _unit_menu has already been initialized.
73  */
74 void
75 ScalarUnit::initScalar(double min_value, double max_value)
76 {
77     g_assert(_unit_menu != NULL);
78     Scalar::setDigits(_unit_menu->getDefaultDigits());
79     Scalar::setIncrements(_unit_menu->getDefaultStep(),
80                           _unit_menu->getDefaultPage());
81     Scalar::setRange(min_value, max_value);
82 }
84 /** Sets the unit for the ScalarUnit widget */
85 bool
86 ScalarUnit::setUnit(Glib::ustring const &unit) {
87     g_assert(_unit_menu != NULL);
88     // First set the unit
89     if (!_unit_menu->setUnit(unit)) {
90         return false;
91     }
92     lastUnits = unit;
93     return true;
94 }
96 /** Gets the object for the currently selected unit */
97 Unit
98 ScalarUnit::getUnit() const {
99     g_assert(_unit_menu != NULL);
100     return _unit_menu->getUnit();
103 /** Gets the UnitType ID for the unit */
104 UnitType
105 ScalarUnit::getUnitType() const {
106     g_assert(_unit_menu);
107     return _unit_menu->getUnitType();
110 /** Sets the number and unit system */
111 void
112 ScalarUnit::setValue(double number, Glib::ustring const &units) {
113     g_assert(_unit_menu != NULL);
114     _unit_menu->setUnit(units);
115     Scalar::setValue(number);
118 /** Sets the number only */
119 void
120 ScalarUnit::setValue(double number) {
121     Scalar::setValue(number);
124 /** Returns the value in the given unit system */
125 double
126 ScalarUnit::getValue(Glib::ustring const &unit_name) const {
127     g_assert(_unit_menu != NULL);
128     if (unit_name == "") {
129         // Return the value in the default units
130         return Scalar::getValue();
131     } else {
132         double conversion = _unit_menu->getConversion(unit_name);
133         return conversion * Scalar::getValue();
134     }
137 void
138 ScalarUnit::setHundredPercent(double number)
140     _hundred_percent = number;
143 void
144 ScalarUnit::setAbsoluteIsIncrement(bool value)
146     _absolute_is_increment = value;
149 void
150 ScalarUnit::setPercentageIsIncrement(bool value)
152     _percentage_is_increment = value;
155 /** Convert value from % to absolute, using _hundred_percent and *_is_increment flags */
156 double
157 ScalarUnit::PercentageToAbsolute(double value)
159     // convert from percent to absolute
160     double convertedVal = 0;
161     double hundred_converted = _hundred_percent / _unit_menu->getConversion("px"); // _hundred_percent is in px
162     if (_percentage_is_increment) 
163         value += 100;
164     convertedVal = 0.01 * hundred_converted * value;
165     if (_absolute_is_increment) 
166         convertedVal -= hundred_converted;
168     return convertedVal;
171 /** Convert value from absolute to %, using _hundred_percent and *_is_increment flags */
172 double
173 ScalarUnit::AbsoluteToPercentage(double value)
175     double convertedVal = 0;
176     // convert from absolute to percent
177     if (_hundred_percent == 0) {
178         if (_percentage_is_increment)
179             convertedVal = 0;
180         else 
181             convertedVal = 100;
182     } else {
183         double hundred_converted = _hundred_percent / _unit_menu->getConversion("px", lastUnits); // _hundred_percent is in px
184         if (_absolute_is_increment) 
185             value += hundred_converted;
186         convertedVal = 100 * value / hundred_converted;
187         if (_percentage_is_increment) 
188             convertedVal -= 100;
189     }
191     return convertedVal;
194 /** Assuming the current unit is absolute, get the corresponding % value */
195 double
196 ScalarUnit::getAsPercentage()
198     double convertedVal = AbsoluteToPercentage(Scalar::getValue());
199     return convertedVal;
203 /** Assuming the current unit is absolute, set the value corresponding to a given % */
204 void 
205 ScalarUnit::setFromPercentage(double value)
207     double absolute = PercentageToAbsolute(value);
208     Scalar::setValue(absolute);
212 /** Signal handler for updating the value and suffix label when unit is changed */
213 void
214 ScalarUnit::on_unit_changed()
216     g_assert(_unit_menu != NULL);
218     Glib::ustring abbr = _unit_menu->getUnitAbbr();
219     _suffix->set_label(abbr);
221     Inkscape::Util::UnitTable &table = _unit_menu->getUnitTable();
222     Inkscape::Util::Unit new_unit = (table.getUnit(abbr));
223     Inkscape::Util::Unit old_unit = (table.getUnit(lastUnits));
225     double convertedVal = 0;
226     if (old_unit.type == UNIT_TYPE_DIMENSIONLESS && new_unit.type == UNIT_TYPE_LINEAR) {
227         convertedVal = PercentageToAbsolute(Scalar::getValue());
228     } else if (old_unit.type == UNIT_TYPE_LINEAR && new_unit.type == UNIT_TYPE_DIMENSIONLESS) {
229         convertedVal = AbsoluteToPercentage(Scalar::getValue());
230     } else {
231         double conversion = _unit_menu->getConversion(lastUnits);
232         convertedVal = Scalar::getValue() / conversion;
233     }
234     Scalar::setValue(convertedVal);
236     lastUnits = abbr;
239 } // namespace Widget
240 } // namespace UI
241 } // namespace Inkscape
243 /*
244   Local Variables:
245   mode:c++
246   c-file-style:"stroustrup"
247   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
248   indent-tabs-mode:nil
249   fill-column:99
250   End:
251 */
252 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :