1 /**
2 * \brief Unit Menu Widget - A drop down menu for choosing unit types.
3 *
4 * Author:
5 * Bryce Harrington <bryce@bryceharrington.org>
6 *
7 * Copyright (C) 2004 Bryce Harrington
8 *
9 * Released under GNU GPL. Read the file 'COPYING' for more information.
10 */
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
16 #include <cmath>
18 #include "unit-menu.h"
20 namespace Inkscape {
21 namespace UI {
22 namespace Widget {
24 /**
25 * Construct a UnitMenu
26 *
27 */
28 UnitMenu::UnitMenu() : _type(UNIT_TYPE_NONE)
29 {
30 set_active(0);
31 }
33 UnitMenu::~UnitMenu() {
34 }
36 /** Adds the unit type to the widget. This extracts the corresponding
37 units from the unit map matching the given type, and appends them
38 to the dropdown widget. It causes the primary unit for the given
39 unit_type to be selected. */
40 bool
41 UnitMenu::setUnitType(UnitType unit_type)
42 {
43 /* Expand the unit widget with unit entries from the unit table */
44 UnitTable::UnitMap m = _unit_table.units(unit_type);
45 UnitTable::UnitMap::iterator iter = m.begin();
46 while(iter != m.end()) {
47 Glib::ustring text = (*iter).first;
48 append_text(text);
49 ++iter;
50 }
51 _type = unit_type;
52 set_active_text(_unit_table.primary(unit_type));
54 return true;
55 }
57 /** Returns the Unit object corresponding to the current selection
58 in the dropdown widget */
59 Unit
60 UnitMenu::getUnit() const {
61 if (get_active_text() == "") {
62 g_assert(_type != UNIT_TYPE_NONE);
63 return _unit_table.getUnit(_unit_table.primary(_type));
64 }
65 return _unit_table.getUnit(get_active_text());
66 }
68 /** Sets the dropdown widget to the given unit abbreviation.
69 Returns true if the unit was selectable, false if not
70 (i.e., if the unit was not present in the widget) */
71 bool
72 UnitMenu::setUnit(Glib::ustring const & unit) {
73 // TODO: Determine if 'unit' is available in the dropdown.
74 // If not, return false
76 set_active_text(unit);
77 return true;
78 }
80 /** Returns the abbreviated unit name of the selected unit */
81 Glib::ustring
82 UnitMenu::getUnitAbbr() const {
83 if (get_active_text() == "") {
84 return "";
85 }
86 return getUnit().abbr;
87 }
89 /** Returns the UnitType of the selected unit */
90 UnitType
91 UnitMenu::getUnitType() const {
92 return getUnit().type;
93 }
95 /** Returns the unit factor for the selected unit */
96 double
97 UnitMenu::getUnitFactor() const
98 {
99 return getUnit().factor;
100 }
102 /** Returns the recommended number of digits for displaying
103 * numbers of this unit type.
104 */
105 int
106 UnitMenu::getDefaultDigits() const
107 {
108 return getUnit().defaultDigits();
109 }
111 /** Returns the recommended step size in spin buttons
112 * displaying units of this type
113 */
114 double
115 UnitMenu::getDefaultStep() const
116 {
117 int factor_digits = -1*int(log10(getUnit().factor));
118 return pow(10.0, factor_digits);
119 }
121 /** Returns the recommended page size (when hitting pgup/pgdn)
122 * in spin buttons displaying units of this type
123 */
124 double
125 UnitMenu::getDefaultPage() const
126 {
127 return 10 * getDefaultStep();
128 }
130 /**
131 * Returns the conversion factor required to convert values
132 * of the currently selected unit into units of type
133 * new_unit_abbr.
134 */
135 double
136 UnitMenu::getConversion(Glib::ustring const &new_unit_abbr, Glib::ustring const &old_unit_abbr) const
137 {
138 double old_factor = getUnit().factor;
139 if (old_unit_abbr != "no_unit")
140 old_factor = _unit_table.getUnit(old_unit_abbr).factor;
141 Unit new_unit = _unit_table.getUnit(new_unit_abbr);
143 // Catch the case of zero or negative unit factors (error!)
144 if (old_factor < 0.0000001 ||
145 new_unit.factor < 0.0000001) {
146 // TODO: Should we assert here?
147 return 0.00;
148 }
150 return old_factor / new_unit.factor;
151 }
153 /** Returns true if the selected unit is not dimensionless
154 * (false for %, true for px, pt, cm, etc)
155 */
156 bool
157 UnitMenu::isAbsolute() const {
158 return getUnitType() != UNIT_TYPE_DIMENSIONLESS;
159 }
161 /** Returns true if the selected unit is radial (deg or rad)
162 */
163 bool
164 UnitMenu::isRadial() const {
165 return getUnitType() == UNIT_TYPE_RADIAL;
166 }
168 } // namespace Widget
169 } // namespace UI
170 } // namespace Inkscape
172 /*
173 Local Variables:
174 mode:c++
175 c-file-style:"stroustrup"
176 c-file-offsets:((innamespace . 0)(inline-open . 0))
177 indent-tabs-mode:nil
178 fill-column:99
179 End:
180 */
181 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :