]> git.saurik.com Git - wxWidgets.git/blob - include/wx/generic/spinctlg.h
Don't send wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED when nothing changed.
[wxWidgets.git] / include / wx / generic / spinctlg.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/generic/spinctlg.h
3 // Purpose: generic wxSpinCtrl class
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 28.10.99
7 // RCS-ID: $Id$
8 // Copyright: (c) Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_GENERIC_SPINCTRL_H_
13 #define _WX_GENERIC_SPINCTRL_H_
14
15 // ----------------------------------------------------------------------------
16 // wxSpinCtrl is a combination of wxSpinButton and wxTextCtrl, so if
17 // wxSpinButton is available, this is what we do - but if it isn't, we still
18 // define wxSpinCtrl class which then has the same appearance as wxTextCtrl but
19 // the different interface. This allows to write programs using wxSpinCtrl
20 // without tons of #ifdefs.
21 // ----------------------------------------------------------------------------
22
23 #if wxUSE_SPINBTN
24
25 class WXDLLIMPEXP_FWD_CORE wxSpinButton;
26 class WXDLLIMPEXP_FWD_CORE wxTextCtrl;
27
28 class wxSpinCtrlTextGeneric; // wxTextCtrl used for the wxSpinCtrlGenericBase
29
30 // The !wxUSE_SPINBTN version's GetValue() function conflicts with the
31 // wxTextCtrl's GetValue() and so you have to input a dummy int value.
32 #define wxSPINCTRL_GETVALUE_FIX
33
34 // ----------------------------------------------------------------------------
35 // wxSpinCtrlGeneric is a combination of wxTextCtrl and wxSpinButton
36 //
37 // This class manages a double valued generic spinctrl through the DoGet/SetXXX
38 // functions that are made public as Get/SetXXX functions for int or double
39 // for the wxSpinCtrl and wxSpinCtrlDouble classes respectively to avoid
40 // function ambiguity.
41 // ----------------------------------------------------------------------------
42
43 class WXDLLIMPEXP_CORE wxSpinCtrlGenericBase : public wxSpinCtrlBase
44 {
45 public:
46 wxSpinCtrlGenericBase() { Init(); }
47
48 bool Create(wxWindow *parent,
49 wxWindowID id = wxID_ANY,
50 const wxString& value = wxEmptyString,
51 const wxPoint& pos = wxDefaultPosition,
52 const wxSize& size = wxDefaultSize,
53 long style = wxSP_ARROW_KEYS | wxALIGN_RIGHT,
54 double min = 0, double max = 100, double initial = 0,
55 double inc = 1,
56 const wxString& name = wxT("wxSpinCtrl"));
57
58 virtual ~wxSpinCtrlGenericBase();
59
60 // accessors
61 // T GetValue() const
62 // T GetMin() const
63 // T GetMax() const
64 // T GetIncrement() const
65 virtual bool GetSnapToTicks() const { return m_snap_to_ticks; }
66 // unsigned GetDigits() const - wxSpinCtrlDouble only
67
68 // operations
69 virtual void SetValue(const wxString& text);
70 // void SetValue(T val)
71 // void SetRange(T minVal, T maxVal)
72 // void SetIncrement(T inc)
73 virtual void SetSnapToTicks(bool snap_to_ticks);
74 // void SetDigits(unsigned digits) - wxSpinCtrlDouble only
75
76 // Select text in the textctrl
77 void SetSelection(long from, long to);
78
79 // implementation from now on
80
81 // forward these functions to all subcontrols
82 virtual bool Enable(bool enable = true);
83 virtual bool Show(bool show = true);
84 virtual bool Reparent(wxWindowBase *newParent);
85
86 // get the subcontrols
87 wxTextCtrl *GetText() const { return m_textCtrl; }
88 wxSpinButton *GetSpinButton() const { return m_spinButton; }
89
90 // forwarded events from children windows
91 void OnSpinButton(wxSpinEvent& event);
92 void OnTextEnter(wxCommandEvent& event);
93 void OnTextChar(wxKeyEvent& event);
94
95 friend class wxSpinCtrlTextGeneric;
96
97 protected:
98 // override the base class virtuals involved into geometry calculations
99 virtual wxSize DoGetBestSize() const;
100 virtual void DoMoveWindow(int x, int y, int width, int height);
101
102 // generic double valued functions
103 double DoGetValue() const { return m_value; }
104 bool DoSetValue(double val);
105 void DoSetRange(double min_val, double max_val);
106 void DoSetIncrement(double inc);
107
108 // update our value to reflect the text control contents (if it has been
109 // modified by user, do nothing otherwise)
110 //
111 // can also change the text control if its value is invalid
112 //
113 // return true if our value has changed
114 bool SyncSpinToText();
115
116 // Send the correct event type
117 virtual void DoSendEvent() = 0;
118
119 // check if the value is in range
120 bool InRange(double n) const { return (n >= m_min) && (n <= m_max); }
121
122 // ensure that the value is in range wrapping it round if necessary
123 double AdjustToFitInRange(double value) const;
124
125
126 double m_value;
127 double m_min;
128 double m_max;
129 double m_increment;
130 bool m_snap_to_ticks;
131 wxString m_format;
132
133 int m_spin_value;
134
135 // the subcontrols
136 wxTextCtrl *m_textCtrl;
137 wxSpinButton *m_spinButton;
138
139 private:
140 // common part of all ctors
141 void Init();
142 };
143
144 #else // !wxUSE_SPINBTN
145
146 #define wxSPINCTRL_GETVALUE_FIX int = 1
147
148 // ----------------------------------------------------------------------------
149 // wxSpinCtrl is just a text control
150 // ----------------------------------------------------------------------------
151
152 #include "wx/textctrl.h"
153
154 class WXDLLIMPEXP_CORE wxSpinCtrlGenericBase : public wxTextCtrl
155 {
156 public:
157 wxSpinCtrlGenericBase() : m_value(0), m_min(0), m_max(100),
158 m_increment(1), m_snap_to_ticks(false),
159 m_format(wxT("%g")) { }
160
161 bool Create(wxWindow *parent,
162 wxWindowID id = wxID_ANY,
163 const wxString& value = wxEmptyString,
164 const wxPoint& pos = wxDefaultPosition,
165 const wxSize& size = wxDefaultSize,
166 long style = wxSP_ARROW_KEYS | wxALIGN_RIGHT,
167 double min = 0, double max = 100, double initial = 0,
168 double inc = 1,
169 const wxString& name = wxT("wxSpinCtrl"))
170 {
171 m_min = min;
172 m_max = max;
173 m_value = initial;
174 m_increment = inc;
175
176 bool ok = wxTextCtrl::Create(parent, id, value, pos, size, style,
177 wxDefaultValidator, name);
178 DoSetValue(initial);
179
180 return ok;
181 }
182
183 // accessors
184 // T GetValue() const
185 // T GetMin() const
186 // T GetMax() const
187 // T GetIncrement() const
188 virtual bool GetSnapToTicks() const { return m_snap_to_ticks; }
189 // unsigned GetDigits() const - wxSpinCtrlDouble only
190
191 // operations
192 virtual void SetValue(const wxString& text) { wxTextCtrl::SetValue(text); }
193 // void SetValue(T val)
194 // void SetRange(T minVal, T maxVal)
195 // void SetIncrement(T inc)
196 virtual void SetSnapToTicks(bool snap_to_ticks)
197 { m_snap_to_ticks = snap_to_ticks; }
198 // void SetDigits(unsigned digits) - wxSpinCtrlDouble only
199
200 // Select text in the textctrl
201 //void SetSelection(long from, long to);
202
203 protected:
204 // generic double valued
205 double DoGetValue() const
206 {
207 double n;
208 if ( (wxSscanf(wxTextCtrl::GetValue(), wxT("%lf"), &n) != 1) )
209 n = INT_MIN;
210
211 return n;
212 }
213
214 bool DoSetValue(double val)
215 {
216 wxTextCtrl::SetValue(wxString::Format(m_format.c_str(), val));
217 return true;
218 }
219 void DoSetRange(double min_val, double max_val)
220 {
221 m_min = min_val;
222 m_max = max_val;
223 }
224 void DoSetIncrement(double inc) { m_increment = inc; } // Note: unused
225
226 double m_value;
227 double m_min;
228 double m_max;
229 double m_increment;
230 bool m_snap_to_ticks;
231 wxString m_format;
232 };
233
234 #endif // wxUSE_SPINBTN/!wxUSE_SPINBTN
235
236 #if !defined(wxHAS_NATIVE_SPINCTRL)
237
238 //-----------------------------------------------------------------------------
239 // wxSpinCtrl
240 //-----------------------------------------------------------------------------
241
242 class WXDLLIMPEXP_CORE wxSpinCtrl : public wxSpinCtrlGenericBase
243 {
244 public:
245 wxSpinCtrl() {}
246 wxSpinCtrl(wxWindow *parent,
247 wxWindowID id = wxID_ANY,
248 const wxString& value = wxEmptyString,
249 const wxPoint& pos = wxDefaultPosition,
250 const wxSize& size = wxDefaultSize,
251 long style = wxSP_ARROW_KEYS | wxALIGN_RIGHT,
252 int min = 0, int max = 100, int initial = 0,
253 const wxString& name = wxT("wxSpinCtrl"))
254 {
255 Create(parent, id, value, pos, size, style, min, max, initial, name);
256 }
257
258 bool Create(wxWindow *parent,
259 wxWindowID id = wxID_ANY,
260 const wxString& value = wxEmptyString,
261 const wxPoint& pos = wxDefaultPosition,
262 const wxSize& size = wxDefaultSize,
263 long style = wxSP_ARROW_KEYS | wxALIGN_RIGHT,
264 int min = 0, int max = 100, int initial = 0,
265 const wxString& name = wxT("wxSpinCtrl"))
266 {
267 return wxSpinCtrlGenericBase::Create(parent, id, value, pos, size,
268 style, min, max, initial, 1, name);
269 }
270
271 // accessors
272 int GetValue(wxSPINCTRL_GETVALUE_FIX) const { return int(DoGetValue()); }
273 int GetMin() const { return int(m_min); }
274 int GetMax() const { return int(m_max); }
275 int GetIncrement() const { return int(m_increment); }
276
277 // operations
278 void SetValue(const wxString& value)
279 { wxSpinCtrlGenericBase::SetValue(value); }
280 void SetValue( int value ) { DoSetValue(value); }
281 void SetRange( int minVal, int maxVal ) { DoSetRange(minVal, maxVal); }
282 void SetIncrement(int inc) { DoSetIncrement(inc); }
283
284 protected:
285 virtual void DoSendEvent();
286
287 DECLARE_DYNAMIC_CLASS(wxSpinCtrl)
288 };
289
290 #endif // wxHAS_NATIVE_SPINCTRL
291
292 //-----------------------------------------------------------------------------
293 // wxSpinCtrlDouble
294 //-----------------------------------------------------------------------------
295
296 class WXDLLIMPEXP_CORE wxSpinCtrlDouble : public wxSpinCtrlGenericBase
297 {
298 public:
299 wxSpinCtrlDouble() : m_digits(0) { }
300 wxSpinCtrlDouble(wxWindow *parent,
301 wxWindowID id = wxID_ANY,
302 const wxString& value = wxEmptyString,
303 const wxPoint& pos = wxDefaultPosition,
304 const wxSize& size = wxDefaultSize,
305 long style = wxSP_ARROW_KEYS | wxALIGN_RIGHT,
306 double min = 0, double max = 100, double initial = 0,
307 double inc = 1,
308 const wxString& name = wxT("wxSpinCtrlDouble"))
309 {
310 m_digits = 0;
311 Create(parent, id, value, pos, size, style,
312 min, max, initial, inc, name);
313 }
314
315 bool Create(wxWindow *parent,
316 wxWindowID id = wxID_ANY,
317 const wxString& value = wxEmptyString,
318 const wxPoint& pos = wxDefaultPosition,
319 const wxSize& size = wxDefaultSize,
320 long style = wxSP_ARROW_KEYS | wxALIGN_RIGHT,
321 double min = 0, double max = 100, double initial = 0,
322 double inc = 1,
323 const wxString& name = wxT("wxSpinCtrlDouble"))
324 {
325 return wxSpinCtrlGenericBase::Create(parent, id, value, pos, size,
326 style, min, max, initial,
327 inc, name);
328 }
329
330 // accessors
331 double GetValue(wxSPINCTRL_GETVALUE_FIX) const { return DoGetValue(); }
332 double GetMin() const { return m_min; }
333 double GetMax() const { return m_max; }
334 double GetIncrement() const { return m_increment; }
335 unsigned GetDigits() const { return m_digits; }
336
337 // operations
338 void SetValue(const wxString& value)
339 { wxSpinCtrlGenericBase::SetValue(value); }
340 void SetValue(double value) { DoSetValue(value); }
341 void SetRange(double minVal, double maxVal) { DoSetRange(minVal, maxVal); }
342 void SetIncrement(double inc) { DoSetIncrement(inc); }
343 void SetDigits(unsigned digits);
344
345 protected:
346 virtual void DoSendEvent();
347
348 unsigned m_digits;
349
350 DECLARE_DYNAMIC_CLASS(wxSpinCtrlDouble)
351 };
352
353 #endif // _WX_GENERIC_SPINCTRL_H_