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