GLUI: make ParamLabelModelString behave like the other models
[spectmorph.git] / glui / smparamlabel.hh
1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
2
3 #ifndef SPECTMORPH_PARAM_LABEL_HH
4 #define SPECTMORPH_PARAM_LABEL_HH
5
6 #include "smlineedit.hh"
7 #include "smlabel.hh"
8 #include "smwindow.hh"
9
10 namespace SpectMorph
11 {
12
13 class ParamLabelModel
14 {
15 public:
16   ParamLabelModel();
17   virtual ~ParamLabelModel();
18
19   virtual std::string value_text() = 0;
20   virtual std::string display_text() = 0;
21   virtual void        set_value_text (const std::string& t) = 0;
22 };
23
24 class ParamLabelModelDouble : public ParamLabelModel
25 {
26   double value;
27   double min_value;
28   double max_value;
29
30   std::string value_fmt;
31   std::string display_fmt;
32
33 public:
34   ParamLabelModelDouble (double start, double min_val, double max_val, const std::string& value_fmt, const std::string& display_fmt) :
35     value (start),
36     min_value (min_val),
37     max_value (max_val),
38     value_fmt (value_fmt),
39     display_fmt (display_fmt)
40   {
41   }
42
43   std::string
44   value_text()
45   {
46     return string_locale_printf (value_fmt.c_str(), value);
47   }
48   std::string
49   display_text()
50   {
51     return string_locale_printf (display_fmt.c_str(), value);
52   }
53   void
54   set_value_text (const std::string& t)
55   {
56     value = atof (t.c_str());
57
58     value = sm_bound (min_value, value, max_value);
59
60     signal_value_changed (value);
61   }
62   Signal<double> signal_value_changed;
63 };
64
65 class ParamLabelModelInt : public ParamLabelModel
66 {
67   int value;
68   int min_value;
69   int max_value;
70
71 public:
72   ParamLabelModelInt (int i, int min_value, int max_value) :
73     value (i),
74     min_value (min_value),
75     max_value (max_value)
76   {
77   }
78
79   std::string
80   value_text()
81   {
82     return string_locale_printf ("%d", value);
83   }
84   std::string
85   display_text()
86   {
87     return string_locale_printf ("%d", value);
88   }
89   void
90   set_value_text (const std::string& t)
91   {
92     value = atoi (t.c_str());
93
94     value = sm_bound (min_value, value, max_value);
95
96     signal_value_changed (value);
97   }
98   Signal<int> signal_value_changed;
99 };
100
101 class ParamLabelModelString : public ParamLabelModel
102 {
103   std::string value;
104
105 public:
106   ParamLabelModelString (const std::string& s):
107     value (s)
108   {
109   }
110   std::string
111   value_text()
112   {
113     return value;
114   }
115   std::string
116   display_text()
117   {
118     return value;
119   }
120   void
121   set_value_text (const std::string& t)
122   {
123     value = t;
124
125     signal_value_changed (value);
126   }
127   Signal<std::string> signal_value_changed;
128 };
129
130 class ParamLabel : public Label
131 {
132   bool      pressed = false;
133   LineEdit *line_edit = nullptr;
134
135   std::unique_ptr<ParamLabelModel> model;
136 public:
137   ParamLabel (Widget *parent, ParamLabelModel *model) :
138     Label (parent, ""),
139     model (model)
140   {
141     set_text (model->display_text());
142   }
143   void
144   mouse_press (double x, double y) override
145   {
146     pressed = true;
147   }
148   void
149   mouse_release (double x, double y) override
150   {
151     if (!pressed)
152       return;
153     pressed = false;
154
155     if (!line_edit)
156       {
157         line_edit = new LineEdit (this, model->value_text());
158         line_edit->height = height;
159         line_edit->width = width;
160         line_edit->x = 0;
161         line_edit->y = 0;
162
163         connect (line_edit->signal_return_pressed, this, &ParamLabel::on_return_pressed);
164         connect (line_edit->signal_focus_out, this, &ParamLabel::on_return_pressed);
165
166         window()->set_keyboard_focus (line_edit, true);
167
168         set_text ("");
169       }
170   }
171   void
172   on_return_pressed()
173   {
174     if (!line_edit->visible())
175       return;
176
177     model->set_value_text (line_edit->text());
178     set_text (model->display_text());
179     line_edit->delete_later();
180     line_edit = nullptr;
181   }
182 };
183
184 }
185
186 #endif