1 // This is core/vgui/wx/wxSliderPanel.cxx
2 #include "wxSliderPanel.h"
3 //:
4 // \file
5
6 //: For compilers that support precompilation, includes "wx/wx.h".
7 #include <wx/wxprec.h>
8
9 #ifndef WX_PRECOMP
10 # include <wx/wx.h>
11 #endif
12
13 #include <cassert>
14 #ifdef _MSC_VER
15 # include "vcl_msvc_warnings.h"
16 #endif
17 #include "vgui/vgui_message.h"
18
19
20 IMPLEMENT_DYNAMIC_CLASS(wxSliderPanel, wxScrolledWindow)
21
22
23 //: Event Table
24 BEGIN_EVENT_TABLE(wxSliderPanel, wxPanel)
25 EVT_SCROLL_THUMBTRACK(wxSliderPanel::OnSliderTrack)
26 EVT_SCROLL_PAGEDOWN(wxSliderPanel::OnSliderTrack)
27 EVT_SCROLL_PAGEUP(wxSliderPanel::OnSliderTrack)
28 EVT_SCROLL_LINEDOWN(wxSliderPanel::OnSliderTrack)
29 EVT_SCROLL_LINEUP(wxSliderPanel::OnSliderTrack)
30 EVT_SCROLL_CHANGED(wxSliderPanel::OnSliderChange)
31 EVT_TEXT(wxID_ANY, wxSliderPanel::OnChangeText)
32 EVT_TEXT_ENTER(wxID_ANY, wxSliderPanel::OnEnterText)
33 END_EVENT_TABLE()
34
35
36 const char wxSliderPanel::update[] = "";
37 const char wxSliderPanel::enter[] = "";
38
39
40 //: Constructor - Default
wxSliderPanel()41 wxSliderPanel::wxSliderPanel()
42 : base_id_(10100)
43 , send_messages_(true)
44 {
45 Init();
46 }
47
48 //: Constructor
wxSliderPanel(wxWindow * parent,wxWindowID id,wxWindowID base_id,const wxPoint & pos,const wxSize & size,long style,const wxString & name)49 wxSliderPanel::wxSliderPanel(wxWindow * parent,
50 wxWindowID id,
51 wxWindowID base_id,
52 const wxPoint & pos,
53 const wxSize & size,
54 long style,
55 const wxString & name)
56 : send_messages_(true)
57 {
58 Init();
59 Create(parent, id, base_id, pos, size, style, name);
60 }
61
62
63 //: Creator
64 bool
Create(wxWindow * parent,wxWindowID id,wxWindowID base_id,const wxPoint & pos,const wxSize & size,long style,const wxString & name)65 wxSliderPanel::Create(wxWindow * parent,
66 wxWindowID id,
67 wxWindowID base_id,
68 const wxPoint & pos,
69 const wxSize & size,
70 long style,
71 const wxString & name)
72 {
73 base_id_ = base_id;
74 wxScrolledWindow::Create(parent, id, pos, size, style, name);
75 return true;
76 }
77
78
79 //: Destructor
~wxSliderPanel()80 wxSliderPanel::~wxSliderPanel() {}
81
82
83 //: Initialization
84 void
Init()85 wxSliderPanel::Init()
86 {}
87
88 //: Convert slider position to a double value
89 double
sp_to_val(unsigned int idx,int sp) const90 wxSliderPanel::sp_to_val(unsigned int idx, int sp) const
91 {
92 return (sp / 1000.0) * (max_vals_[idx] - min_vals_[idx]) + min_vals_[idx];
93 }
94
95 //: Convert a double value to a slider position
96 int
val_to_sp(unsigned int idx,double val) const97 wxSliderPanel::val_to_sp(unsigned int idx, double val) const
98 {
99 return static_cast<int>((1000.0 * (val - min_vals_[idx]) / (max_vals_[idx] - min_vals_[idx])));
100 }
101
102
103 //: Create the controls
104 void
CreateControls()105 wxSliderPanel::CreateControls()
106 {
107 wxFlexGridSizer * itemFlexGridSizer = new wxFlexGridSizer(vals_.size(), 3, 0, 0);
108 itemFlexGridSizer->AddGrowableCol(1);
109 this->SetSizer(itemFlexGridSizer);
110
111 itemFlexGridSizer->Add(0, 3, 0, wxGROW, 0);
112 itemFlexGridSizer->Add(0, 3, 0, wxGROW, 0);
113 itemFlexGridSizer->Add(0, 3, 0, wxGROW, 0);
114 for (unsigned int i = 0; i < vals_.size(); ++i)
115 {
116 wxStaticText * itemLabel =
117 new wxStaticText(this, wxID_STATIC, wxString::Format(wxT("%u"), i + 1), wxDefaultPosition, wxDefaultSize, 0);
118 itemFlexGridSizer->Add(itemLabel, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_TOP | wxLEFT, 3);
119
120 int pos = val_to_sp(i, vals_[i]);
121 wxSlider * itemSlider =
122 new wxSlider(this, base_id_ + 2 * i, pos, 0, 1000, wxDefaultPosition, wxSize(100, -1), wxSL_HORIZONTAL);
123 itemFlexGridSizer->Add(itemSlider, 1, wxGROW | wxALIGN_CENTER_VERTICAL | wxLEFT, 3);
124
125 wxTextCtrl * itemTextCtrl = new wxTextCtrl(this,
126 base_id_ + 2 * i + 1,
127 wxString::Format(wxT("%g"), vals_[i]),
128 wxDefaultPosition,
129 wxSize(70, -1),
130 wxTE_PROCESS_ENTER);
131 itemFlexGridSizer->Add(itemTextCtrl, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 3);
132 // Numeric text validator
133 itemTextCtrl->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
134 }
135 itemFlexGridSizer->Add(0, 3, 0, wxGROW, 0);
136 itemFlexGridSizer->Add(0, 3, 0, wxGROW, 0);
137 itemFlexGridSizer->Add(0, 3, 0, wxGROW, 0);
138 }
139
140 void
CreateSliders(const std::vector<double> & init_vals,const std::vector<double> & min_vals,const std::vector<double> & max_vals)141 wxSliderPanel::CreateSliders(const std::vector<double> & init_vals,
142 const std::vector<double> & min_vals,
143 const std::vector<double> & max_vals)
144 {
145 assert(init_vals.size() == min_vals.size());
146 assert(init_vals.size() == max_vals.size());
147 vals_ = init_vals;
148 min_vals_ = min_vals;
149 max_vals_ = max_vals;
150
151
152 Freeze();
153 DestroyChildren();
154 wxScrolledWindow::Create(GetParent(), GetId(), GetPosition(), GetSize(), GetWindowStyleFlag(), GetName());
155 CreateControls();
156 FitInside();
157 SetScrollRate(0, 20);
158 Thaw();
159 Refresh();
160 }
161
162
163 bool
ShowToolTips()164 wxSliderPanel::ShowToolTips()
165 {
166 return true;
167 }
168
169
170 //: Used by event handles to validate and lookup widgets
171 int
GetWidgets(const wxEvent & event,wxSlider * & slider,wxTextCtrl * & text)172 wxSliderPanel::GetWidgets(const wxEvent & event, wxSlider *& slider, wxTextCtrl *& text)
173 {
174 slider = NULL;
175 text = NULL;
176 int idx = (event.GetId() - base_id_) / 2;
177 if (idx < 0 || idx >= static_cast<int>(vals_.size()))
178 return -1;
179
180 text = dynamic_cast<wxTextCtrl *>(FindWindowById(base_id_ + 2 * idx + 1));
181 slider = dynamic_cast<wxSlider *>(FindWindowById(base_id_ + 2 * idx));
182 return idx;
183 }
184
185
186 //: Handle Slider Tracking (dragging)
187 void
OnSliderTrack(wxScrollEvent & event)188 wxSliderPanel::OnSliderTrack(wxScrollEvent & event)
189 {
190 wxSlider * slider;
191 wxTextCtrl * text;
192 int idx = GetWidgets(event, slider, text);
193 if (!slider || !text)
194 {
195 event.Skip();
196 return;
197 }
198
199 int spos = event.GetInt();
200 double val = sp_to_val(idx, spos);
201 text->SetValue(wxString::Format(wxT("%g"), val));
202 }
203
204 //: Handle Slider Release (stop dragging)
205 void
OnSliderChange(wxScrollEvent & event)206 wxSliderPanel::OnSliderChange(wxScrollEvent & event)
207 {
208 wxSlider * slider;
209 wxTextCtrl * text;
210 int idx = GetWidgets(event, slider, text);
211 if (!slider || !text)
212 {
213 event.Skip();
214 return;
215 }
216
217 if (send_messages_)
218 {
219 vgui_message m;
220 m.from = this;
221 m.user = wxSliderPanel::enter;
222 m.data = &idx;
223 notify(m);
224 }
225 }
226
227
228 //: Handle Textbox value change (typing)
229 void
OnChangeText(wxCommandEvent & event)230 wxSliderPanel::OnChangeText(wxCommandEvent & event)
231 {
232 wxSlider * slider;
233 wxTextCtrl * text;
234 int idx = GetWidgets(event, slider, text);
235 if (!slider || !text)
236 {
237 event.Skip();
238 return;
239 }
240
241 event.GetString().ToDouble(&vals_[idx]);
242 int spos = val_to_sp(idx, vals_[idx]);
243 slider->SetValue(spos);
244 event.Skip();
245
246 if (send_messages_)
247 {
248 vgui_message m;
249 m.from = this;
250 m.user = wxSliderPanel::update;
251 m.data = &idx;
252 notify(m);
253 }
254 }
255
256
257 //: Handle Textbox press of Enter key
258 void
OnEnterText(wxCommandEvent & event)259 wxSliderPanel::OnEnterText(wxCommandEvent & event)
260 {
261 wxSlider * slider;
262 wxTextCtrl * text;
263 int idx = GetWidgets(event, slider, text);
264 if (!slider || !text)
265 {
266 event.Skip();
267 return;
268 }
269
270 if (send_messages_)
271 {
272 vgui_message m;
273 m.from = this;
274 m.user = wxSliderPanel::enter;
275 m.data = &idx;
276 notify(m);
277 }
278 }
279
280
281 //: Update the data
282 void
update_data(std::vector<double> & data,bool send_messages)283 wxSliderPanel::update_data(std::vector<double> & data, bool send_messages)
284 {
285 for (unsigned int i = 0; i < data.size() && i < vals_.size(); ++i)
286 {
287 update_data(i, data[i], send_messages);
288 }
289 }
290
291 //: Update a single value
292 void
update_data(unsigned int i,double val,bool send_messages)293 wxSliderPanel::update_data(unsigned int i, double val, bool send_messages)
294 {
295 vals_[i] = val;
296 int id = base_id_ + 2 * i + 1; // id of text control
297 wxTextCtrl * text = dynamic_cast<wxTextCtrl *>(FindWindowById(id));
298
299 // optionally disable sending messages about this update
300 send_messages_ = send_messages;
301 text->SetValue(wxString::Format(wxT("%g"), val));
302 send_messages_ = true;
303 }
304