libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GtkCRNConfigElement.cpp
Go to the documentation of this file.
1 /* Copyright 2011-2016 CoReNum, ENS-Lyon
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * libcrn is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: GtkCRNConfigElement.cpp
19  * \author Yann LEYDIER
20  */
21 
22 #include <GtkCRNConfigElement.h>
23 #include <GtkCRNProp3.h>
24 #include <CRNi18n.h>
25 #include <limits>
26 
27 using namespace GtkCRN;
28 
34  value(el.GetValue()),
35  tmpvalue(el.GetValue())
36 {
37  if (!value)
38  throw crn::ExceptionUninitialized(_("The element was not initialized."));
39  if (differ)
40  tmpvalue = crn::Clone(*value);
41 
42  if (std::dynamic_pointer_cast<crn::Int>(tmpvalue))
43  typ = U"Int";
44  else if (std::dynamic_pointer_cast<crn::Real>(tmpvalue))
45  typ = U"Real";
46  else if (std::dynamic_pointer_cast<crn::Prop3>(tmpvalue))
47  typ = U"Prop3";
48  else if (std::dynamic_pointer_cast<crn::String>(tmpvalue))
49  typ = U"String";
50  else if (std::dynamic_pointer_cast<crn::StringUTF8>(tmpvalue))
51  typ = U"StringUTF8";
52  else if (std::dynamic_pointer_cast<crn::Path>(tmpvalue))
53  typ = U"Path";
54 
55  Gtk::Label *lab = Gtk::manage(new Gtk::Label(el.GetName().CStr()));
56  lab->show();
57  pack_start(*lab, false, true, 2);
58 
59  if (typ == U"Prop3")
60  {
61  Prop3 *p = Gtk::manage(new Prop3(Gtk::ICON_SIZE_BUTTON, el.GetValue<crn::Prop3>()));
62  p->signal_value_changed().connect(sigc::mem_fun(this, &ConfigElement::on_p3_changed));
63  p->show();
64  pack_start(*p, true, true, 2);
65  }
66  else if (!el.GetAllowedValues().IsEmpty())
67  { // any Int, Real, String, StringUTF8 or Path
68  Gtk::ComboBoxText *cb = Gtk::manage(new Gtk::ComboBoxText);
69  const std::vector<crn::StringUTF8> values(el.GetAllowedValues<crn::StringUTF8>());
70  for (const crn::StringUTF8 &val : values)
71 #ifdef CRN_USING_GTKMM3
72  cb->append(val.CStr());
73 #else /* CRN_USING_GTKMM3 */
74  cb->append_text(val.CStr());
75 #endif /* CRN_USING_GTKMM3 */
76  cb->set_active_text(el.GetValue<crn::StringUTF8>().CStr());
77  cb->signal_changed().connect(sigc::bind(sigc::mem_fun(this, &ConfigElement::on_combo_changed), cb));
78  cb->show();
79  pack_start(*cb, true, true, 2);
80  }
81  else if (typ == U"Int")
82  {
83  if (el.HasMinValue() && el.HasMaxValue())
84  { // has finite range, use a slider
85 #ifdef CRN_USING_GTKMM3
86  auto *s = Gtk::manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL));
87  s->set_range(el.GetMinValue<int>(), el.GetMaxValue<int>() + 1);
88  s->set_increments(1, 1);
89 #else
90  Gtk::HScale *s = Gtk::manage(new Gtk::HScale(el.GetMinValue<int>(), el.GetMaxValue<int>() + 1, 1));
91 #endif
92  s->set_value(el.GetValue<int>());
93  s->signal_value_changed().connect(sigc::bind(sigc::mem_fun(this, &ConfigElement::on_range_changed), s));
94  s->show();
95  pack_start(*s, true, true, 2);
96  }
97  else
98  { // has at least one infinite (maxed) bound, use a spin button
99  Gtk::SpinButton *s = Gtk::manage(new Gtk::SpinButton);
100  int m = std::numeric_limits<int>::min(), M = std::numeric_limits<int>::max();
101  if (el.HasMinValue())
102  m = el.GetMinValue<int>();
103  if (el.HasMaxValue())
104  M = el.GetMaxValue<int>();
105  s->set_range(m, M);
106  s->set_increments(1, 10);
107  s->set_value(el.GetValue<int>());
108  s->signal_value_changed().connect(sigc::bind(sigc::mem_fun(this, &ConfigElement::on_spin_changed), s));
109  s->show();
110  pack_start(*s, true, true, 2);
111  }
112  }
113  else if (typ == U"Real")
114  {
115  if (el.HasMinValue() && el.HasMaxValue())
116  { // has finite range, use a slider
117 #ifdef CRN_USING_GTKMM3
118  auto *s = Gtk::manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL));
119  s->set_range(el.GetMinValue<double>(), el.GetMaxValue<double>() + 0.01);
120  s->set_increments(0.01, 0.01);
121 #else
122  Gtk::HScale *s = Gtk::manage(new Gtk::HScale(el.GetMinValue<double>(), el.GetMaxValue<double>() + 0.01, 0.01));
123 #endif
124  s->set_digits(2);
125  s->set_value(el.GetValue<double>());
126  s->signal_value_changed().connect(sigc::bind(sigc::mem_fun(this, &ConfigElement::on_range_changed), s));
127  s->show();
128  pack_start(*s, true, true, 2);
129  }
130  else
131  { // has at least one infinite (maxed) bound, use a spin button
132  Gtk::SpinButton *s = Gtk::manage(new Gtk::SpinButton(0, 2));
133  double m = -std::numeric_limits<double>::max(), M = std::numeric_limits<double>::max();
134  if (el.HasMinValue())
135  m = el.GetMinValue<double>();
136  if (el.HasMaxValue())
137  M = el.GetMaxValue<double>();
138  s->set_range(m, M);
139  s->set_increments(0.01, 1);
140  s->set_value(el.GetValue<double>());
141  s->signal_value_changed().connect(sigc::bind(sigc::mem_fun(this, &ConfigElement::on_spin_changed), s));
142  s->show();
143  pack_start(*s, true, true, 2);
144  }
145  }
146  else // string types
147  {
148  Gtk::Entry *e = Gtk::manage(new Gtk::Entry);
149  e->set_text(el.GetValue<crn::StringUTF8>().CStr());
150  e->signal_changed().connect(sigc::bind(sigc::mem_fun(this, &ConfigElement::on_entry_changed), e));
151  e->show();
152  pack_start(*e, true, true, 2);
153  }
154  lab = Gtk::manage(new Gtk::Label("?"));
155  lab->show();
156  lab->set_tooltip_text(el.GetDescription().CStr());
157  pack_start(*lab, false, true, 2);
158 }
159 
162 {
163  if (typ == U"Int")
164  {
165  *std::static_pointer_cast<crn::Int>(value) = *std::static_pointer_cast<crn::Int>(tmpvalue);
166  }
167  else if (typ == U"Real")
168  {
169  *std::static_pointer_cast<crn::Real>(value) = *std::static_pointer_cast<crn::Real>(tmpvalue);
170  }
171  else if (typ == U"Prop3")
172  {
173  *std::static_pointer_cast<crn::Prop3>(value) = *std::static_pointer_cast<crn::Prop3>(tmpvalue);
174  }
175  else if (typ == U"String")
176  {
177  *std::static_pointer_cast<crn::String>(value) = *std::static_pointer_cast<crn::String>(tmpvalue);
178  }
179  else if (typ == U"StringUTF8")
180  {
181  *std::static_pointer_cast<crn::StringUTF8>(value) = *std::static_pointer_cast<crn::StringUTF8>(tmpvalue);
182  }
183  else if (typ == U"Path")
184  {
185  *std::static_pointer_cast<crn::Path>(value) = *std::static_pointer_cast<crn::Path>(tmpvalue);
186  }
187 }
188 
189 void ConfigElement::on_p3_changed(crn::Prop3 p3)
190 {
191  *std::static_pointer_cast<crn::Prop3>(tmpvalue) = p3;
192 }
193 
194 void ConfigElement::on_combo_changed(Gtk::ComboBoxText *combo)
195 {
196  const crn::StringUTF8 val(combo->get_active_text().c_str());
197  if (typ == U"Int")
198  {
199  *std::static_pointer_cast<crn::Int>(tmpvalue) = val.ToInt();
200  }
201  else if (typ == U"Real")
202  {
203  *std::static_pointer_cast<crn::Real>(tmpvalue) = val.ToDouble();
204  }
205  else if (typ == U"String")
206  {
207  *std::static_pointer_cast<crn::String>(tmpvalue) = val;
208  }
209  else if (typ == U"StringUTF8")
210  {
211  *std::static_pointer_cast<crn::StringUTF8>(tmpvalue) = val;
212  }
213  else if (typ == U"Path")
214  {
215  *std::static_pointer_cast<crn::Path>(tmpvalue) = val;
216  }
217 }
218 
219 void ConfigElement::on_range_changed(Gtk::Range *range)
220 {
221  if (typ == U"Int")
222  {
223  *std::static_pointer_cast<crn::Int>(tmpvalue) = int(range->get_value());
224  }
225  else if (typ == U"Real")
226  {
227  *std::static_pointer_cast<crn::Real>(tmpvalue) = range->get_value();
228  }
229 }
230 
231 void ConfigElement::on_spin_changed(Gtk::SpinButton *spin)
232 {
233  if (typ == U"Int")
234  {
235  *std::static_pointer_cast<crn::Int>(tmpvalue) = spin->get_value_as_int();
236  }
237  else if (typ == U"Real")
238  {
239  *std::static_pointer_cast<crn::Real>(tmpvalue) = spin->get_value();
240  }
241 }
242 
243 void ConfigElement::on_entry_changed(Gtk::Entry *entry)
244 {
245  if (typ == U"String")
246  {
247  *std::static_pointer_cast<crn::String>(tmpvalue) = entry->get_text().c_str();
248  }
249  else if (typ == U"StringUTF8")
250  {
251  *std::static_pointer_cast<crn::StringUTF8>(tmpvalue) = entry->get_text().c_str();
252  }
253  else if (typ == U"Path")
254  {
255  *std::static_pointer_cast<crn::Path>(tmpvalue) = entry->get_text().c_str();
256  }
257 }
258 
ConfigElement(crn::ConfigElement &el, bool differ=false)
Constructor.
ScalarRange< T > Range(T b, T e)
Creates a range [[b, e[[.
Definition: CRNType.h:257
const SObject & GetMinValue() noexcept
Gets the inner representation of the element's min value.
const crn::Vector & GetAllowedValues() const
Returns the list of allowed values.
#define _(String)
Definition: CRNi18n.h:51
const char * CStr() const
Conversion to UTF8 cstring.
Definition: CRNString.cpp:167
Unintialized object error.
Definition: CRNException.h:155
bool HasMaxValue() const noexcept
Tells if the element has max value.
A UTF32 character string class.
Definition: CRNString.h:61
void apply_changes()
In differ mode, validates the changes to the value.
void Scale(ITER it_begin, ITER it_end, const double s)
Scale a collection of numbers.
Definition: CRNMath.h:103
Interface class for the metric real number class.
Definition: CRNReal.h:38
const SObject & GetMaxValue() noexcept
Gets the inner representation of the element's max value.
const char * CStr() const noexcept
Conversion to UTF8 cstring.
A convenience class for file paths.
Definition: CRNPath.h:39
const String & GetName() const noexcept
Gets the translated name of the element.
A element of configuration.
const String & GetDescription() const noexcept
Gets the description of the element.
const SObject & GetValue() noexcept
Gets the inner representation of the element's value.
Interface class for the metric real number class.
Definition: CRNInt.h:40
A widget for ternary values representation.
Definition: GtkCRNProp3.h:40
A character string class.
Definition: CRNStringUTF8.h:49
UObject Clone(const Object &obj)
Clones an object if possible.
Definition: CRNObject.cpp:35
A ternary proposition.
Definition: CRNProp3.h:40
sigc::signal< void, crn::Prop3 > signal_value_changed()
Signals when the value was changed. Connect to void on_value_changed(crn::Prop3). ...
Definition: GtkCRNProp3.h:61
bool HasMinValue() const noexcept
Tells if the element has min value.
bool IsEmpty() const noexcept
Tests if the vector is empty.
Definition: CRNVector.h:58