]> git.saurik.com Git - wxWidgets.git/blob - samples/widgets/gauge.cpp
Make storing non-trivial data in wxThreadSpecificInfo possible.
[wxWidgets.git] / samples / widgets / gauge.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Program: wxWidgets Widgets Sample
3 // Name: gauge.cpp
4 // Purpose: Part of the widgets sample showing wxGauge
5 // Author: Vadim Zeitlin
6 // Created: 27.03.01
7 // Copyright: (c) 2001 Vadim Zeitlin
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // for compilers that support precompilation, includes "wx/wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 // for all others, include the necessary headers
27 #ifndef WX_PRECOMP
28 #include "wx/log.h"
29 #include "wx/timer.h"
30
31 #include "wx/bitmap.h"
32 #include "wx/button.h"
33 #include "wx/checkbox.h"
34 #include "wx/combobox.h"
35 #include "wx/gauge.h"
36 #include "wx/radiobox.h"
37 #include "wx/statbox.h"
38 #include "wx/textctrl.h"
39 #endif
40
41 #include "wx/sizer.h"
42
43 #include "widgets.h"
44 #if wxUSE_GAUGE
45 #include "icons/gauge.xpm"
46
47 // ----------------------------------------------------------------------------
48 // constants
49 // ----------------------------------------------------------------------------
50
51 // control ids
52 enum
53 {
54 GaugePage_Reset = wxID_HIGHEST,
55 GaugePage_Progress,
56 GaugePage_IndeterminateProgress,
57 GaugePage_Clear,
58 GaugePage_SetValue,
59 GaugePage_SetRange,
60 GaugePage_CurValueText,
61 GaugePage_ValueText,
62 GaugePage_RangeText,
63 GaugePage_Timer,
64 GaugePage_IndeterminateTimer,
65 GaugePage_Gauge
66 };
67
68 // ----------------------------------------------------------------------------
69 // GaugeWidgetsPage
70 // ----------------------------------------------------------------------------
71
72 class GaugeWidgetsPage : public WidgetsPage
73 {
74 public:
75 GaugeWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
76 virtual ~GaugeWidgetsPage();
77
78 virtual wxControl *GetWidget() const { return m_gauge; }
79 virtual void RecreateWidget() { CreateGauge(); }
80
81 // lazy creation of the content
82 virtual void CreateContent();
83
84 protected:
85 // event handlers
86 void OnButtonReset(wxCommandEvent& event);
87 void OnButtonProgress(wxCommandEvent& event);
88 void OnButtonIndeterminateProgress(wxCommandEvent& event);
89 void OnButtonClear(wxCommandEvent& event);
90 void OnButtonSetValue(wxCommandEvent& event);
91 void OnButtonSetRange(wxCommandEvent& event);
92
93 void OnCheckOrRadioBox(wxCommandEvent& event);
94
95 void OnUpdateUIValueButton(wxUpdateUIEvent& event);
96 void OnUpdateUIRangeButton(wxUpdateUIEvent& event);
97 void OnUpdateUIResetButton(wxUpdateUIEvent& event);
98
99 void OnUpdateUICurValueText(wxUpdateUIEvent& event);
100
101 void OnProgressTimer(wxTimerEvent& event);
102 void OnIndeterminateProgressTimer(wxTimerEvent& event);
103
104 // reset the gauge parameters
105 void Reset();
106
107 // (re)create the gauge
108 void CreateGauge();
109
110 // start progress timer
111 void StartTimer(wxButton*);
112
113 // stop the progress timer
114 void StopTimer(wxButton*);
115
116 // the gauge range
117 unsigned long m_range;
118
119 // the controls
120 // ------------
121
122 // the checkboxes for styles
123 wxCheckBox *m_chkVert,
124 *m_chkSmooth;
125
126 // the gauge itself and the sizer it is in
127 wxGauge *m_gauge;
128 wxSizer *m_sizerGauge;
129
130 // the text entries for set value/range
131 wxTextCtrl *m_textValue,
132 *m_textRange;
133
134 // the timer for simulating gauge progress
135 wxTimer *m_timer;
136
137 private:
138 DECLARE_EVENT_TABLE()
139 DECLARE_WIDGETS_PAGE(GaugeWidgetsPage)
140 };
141
142 // ----------------------------------------------------------------------------
143 // event tables
144 // ----------------------------------------------------------------------------
145
146 BEGIN_EVENT_TABLE(GaugeWidgetsPage, WidgetsPage)
147 EVT_BUTTON(GaugePage_Reset, GaugeWidgetsPage::OnButtonReset)
148 EVT_BUTTON(GaugePage_Progress, GaugeWidgetsPage::OnButtonProgress)
149 EVT_BUTTON(GaugePage_IndeterminateProgress, GaugeWidgetsPage::OnButtonIndeterminateProgress)
150 EVT_BUTTON(GaugePage_Clear, GaugeWidgetsPage::OnButtonClear)
151 EVT_BUTTON(GaugePage_SetValue, GaugeWidgetsPage::OnButtonSetValue)
152 EVT_BUTTON(GaugePage_SetRange, GaugeWidgetsPage::OnButtonSetRange)
153
154 EVT_UPDATE_UI(GaugePage_SetValue, GaugeWidgetsPage::OnUpdateUIValueButton)
155 EVT_UPDATE_UI(GaugePage_SetRange, GaugeWidgetsPage::OnUpdateUIRangeButton)
156 EVT_UPDATE_UI(GaugePage_Reset, GaugeWidgetsPage::OnUpdateUIResetButton)
157
158 EVT_UPDATE_UI(GaugePage_CurValueText, GaugeWidgetsPage::OnUpdateUICurValueText)
159
160 EVT_CHECKBOX(wxID_ANY, GaugeWidgetsPage::OnCheckOrRadioBox)
161 EVT_RADIOBOX(wxID_ANY, GaugeWidgetsPage::OnCheckOrRadioBox)
162
163 EVT_TIMER(GaugePage_Timer, GaugeWidgetsPage::OnProgressTimer)
164 EVT_TIMER(GaugePage_IndeterminateTimer, GaugeWidgetsPage::OnIndeterminateProgressTimer)
165 END_EVENT_TABLE()
166
167 // ============================================================================
168 // implementation
169 // ============================================================================
170
171 #if defined(__WXUNIVERSAL__)
172 #define FAMILY_CTRLS UNIVERSAL_CTRLS
173 #else
174 #define FAMILY_CTRLS NATIVE_CTRLS
175 #endif
176
177 IMPLEMENT_WIDGETS_PAGE(GaugeWidgetsPage, wxT("Gauge"), FAMILY_CTRLS );
178
179 GaugeWidgetsPage::GaugeWidgetsPage(WidgetsBookCtrl *book,
180 wxImageList *imaglist)
181 :WidgetsPage(book, imaglist, gauge_xpm)
182 {
183 // init everything
184 m_range = 100;
185
186 m_timer = (wxTimer *)NULL;
187
188 m_chkVert =
189 m_chkSmooth = (wxCheckBox *)NULL;
190
191 m_gauge = (wxGauge *)NULL;
192 m_sizerGauge = (wxSizer *)NULL;
193 }
194
195 void GaugeWidgetsPage::CreateContent()
196 {
197 wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
198
199 // left pane
200 wxStaticBox *box = new wxStaticBox(this, wxID_ANY, wxT("&Set style"));
201
202 wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
203
204 m_chkVert = CreateCheckBoxAndAddToSizer(sizerLeft, wxT("&Vertical"));
205 m_chkSmooth = CreateCheckBoxAndAddToSizer(sizerLeft, wxT("&Smooth"));
206
207 sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
208
209 wxButton *btn = new wxButton(this, GaugePage_Reset, wxT("&Reset"));
210 sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
211
212 // middle pane
213 wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY, wxT("&Change gauge value"));
214 wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
215
216 wxTextCtrl *text;
217 wxSizer *sizerRow = CreateSizerWithTextAndLabel(wxT("Current value"),
218 GaugePage_CurValueText,
219 &text);
220 text->SetEditable(false);
221
222 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
223
224 sizerRow = CreateSizerWithTextAndButton(GaugePage_SetValue,
225 wxT("Set &value"),
226 GaugePage_ValueText,
227 &m_textValue);
228 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
229
230 sizerRow = CreateSizerWithTextAndButton(GaugePage_SetRange,
231 wxT("Set &range"),
232 GaugePage_RangeText,
233 &m_textRange);
234 m_textRange->SetValue( wxString::Format(wxT("%lu"), m_range) );
235 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
236
237 btn = new wxButton(this, GaugePage_Progress, wxT("Simulate &progress"));
238 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
239
240 btn = new wxButton(this, GaugePage_IndeterminateProgress,
241 wxT("Simulate &indeterminate job"));
242 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
243
244 btn = new wxButton(this, GaugePage_Clear, wxT("&Clear"));
245 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
246
247 // right pane
248 wxSizer *sizerRight = new wxBoxSizer(wxHORIZONTAL);
249 m_gauge = new wxGauge(this, GaugePage_Gauge, m_range);
250 sizerRight->Add(m_gauge, 1, wxCENTRE | wxALL, 5);
251 sizerRight->SetMinSize(150, 0);
252 m_sizerGauge = sizerRight; // save it to modify it later
253
254 // the 3 panes panes compose the window
255 sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
256 sizerTop->Add(sizerMiddle, 1, wxGROW | wxALL, 10);
257 sizerTop->Add(sizerRight, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
258
259 // final initializations
260 Reset();
261
262 SetSizer(sizerTop);
263 }
264
265 GaugeWidgetsPage::~GaugeWidgetsPage()
266 {
267 delete m_timer;
268 }
269
270 // ----------------------------------------------------------------------------
271 // operations
272 // ----------------------------------------------------------------------------
273
274 void GaugeWidgetsPage::Reset()
275 {
276 m_chkVert->SetValue(false);
277 m_chkSmooth->SetValue(false);
278 }
279
280 void GaugeWidgetsPage::CreateGauge()
281 {
282 int flags = ms_defaultFlags;
283
284 if ( m_chkVert->GetValue() )
285 flags |= wxGA_VERTICAL;
286 else
287 flags |= wxGA_HORIZONTAL;
288
289 if ( m_chkSmooth->GetValue() )
290 flags |= wxGA_SMOOTH;
291
292 int val = 0;
293 if ( m_gauge )
294 {
295 val = m_gauge->GetValue();
296
297 m_sizerGauge->Detach( m_gauge );
298 delete m_gauge;
299 }
300
301 m_gauge = new wxGauge(this, GaugePage_Gauge, m_range,
302 wxDefaultPosition, wxDefaultSize,
303 flags);
304 m_gauge->SetValue(val);
305
306 if ( flags & wxGA_VERTICAL )
307 m_sizerGauge->Add(m_gauge, 0, wxGROW | wxALL, 5);
308 else
309 m_sizerGauge->Add(m_gauge, 1, wxCENTRE | wxALL, 5);
310
311 m_sizerGauge->Layout();
312 }
313
314 void GaugeWidgetsPage::StartTimer(wxButton *clicked)
315 {
316 static const int INTERVAL = 300;
317
318 wxLogMessage(wxT("Launched progress timer (interval = %d ms)"), INTERVAL);
319
320 m_timer = new wxTimer(this,
321 clicked->GetId() == GaugePage_Progress ? GaugePage_Timer : GaugePage_IndeterminateTimer);
322 m_timer->Start(INTERVAL);
323
324 clicked->SetLabel(wxT("&Stop timer"));
325
326 if (clicked->GetId() == GaugePage_Progress)
327 FindWindow(GaugePage_IndeterminateProgress)->Disable();
328 else
329 FindWindow(GaugePage_Progress)->Disable();
330 }
331
332 void GaugeWidgetsPage::StopTimer(wxButton *clicked)
333 {
334 wxCHECK_RET( m_timer, wxT("shouldn't be called") );
335
336 m_timer->Stop();
337 wxDELETE(m_timer);
338
339 if (clicked->GetId() == GaugePage_Progress)
340 {
341 clicked->SetLabel(wxT("Simulate &progress"));
342 FindWindow(GaugePage_IndeterminateProgress)->Enable();
343 }
344 else
345 {
346 clicked->SetLabel(wxT("Simulate indeterminate job"));
347 FindWindow(GaugePage_Progress)->Enable();
348 }
349
350 wxLogMessage(wxT("Progress finished."));
351 }
352
353 // ----------------------------------------------------------------------------
354 // event handlers
355 // ----------------------------------------------------------------------------
356
357 void GaugeWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
358 {
359 Reset();
360
361 CreateGauge();
362 }
363
364 void GaugeWidgetsPage::OnButtonProgress(wxCommandEvent& event)
365 {
366 wxButton *b = (wxButton *)event.GetEventObject();
367 if ( !m_timer )
368 {
369 StartTimer(b);
370 }
371 else // stop the running timer
372 {
373 StopTimer(b);
374
375 wxLogMessage(wxT("Stopped the timer."));
376 }
377 }
378
379 void GaugeWidgetsPage::OnButtonIndeterminateProgress(wxCommandEvent& event)
380 {
381 wxButton *b = (wxButton *)event.GetEventObject();
382 if ( !m_timer )
383 {
384 StartTimer(b);
385 }
386 else // stop the running timer
387 {
388 StopTimer(b);
389
390 m_gauge->SetValue(0);
391
392 wxLogMessage(wxT("Stopped the timer."));
393 }
394 }
395
396 void GaugeWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
397 {
398 m_gauge->SetValue(0);
399 }
400
401 void GaugeWidgetsPage::OnButtonSetRange(wxCommandEvent& WXUNUSED(event))
402 {
403 unsigned long val;
404 if ( !m_textRange->GetValue().ToULong(&val) )
405 return;
406
407 m_range = val;
408 m_gauge->SetRange(val);
409 }
410
411 void GaugeWidgetsPage::OnButtonSetValue(wxCommandEvent& WXUNUSED(event))
412 {
413 unsigned long val;
414 if ( !m_textValue->GetValue().ToULong(&val) )
415 return;
416
417 m_gauge->SetValue(val);
418 }
419
420 void GaugeWidgetsPage::OnUpdateUIValueButton(wxUpdateUIEvent& event)
421 {
422 unsigned long val;
423 event.Enable( m_textValue->GetValue().ToULong(&val) && (val <= m_range) );
424 }
425
426 void GaugeWidgetsPage::OnUpdateUIRangeButton(wxUpdateUIEvent& event)
427 {
428 unsigned long val;
429 event.Enable( m_textRange->GetValue().ToULong(&val) );
430 }
431
432 void GaugeWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
433 {
434 event.Enable( m_chkVert->GetValue() || m_chkSmooth->GetValue() );
435 }
436
437 void GaugeWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
438 {
439 CreateGauge();
440 }
441
442 void GaugeWidgetsPage::OnProgressTimer(wxTimerEvent& WXUNUSED(event))
443 {
444 int val = m_gauge->GetValue();
445 if ( (unsigned)val < m_range )
446 {
447 m_gauge->SetValue(val + 1);
448 }
449 else // reached the end
450 {
451 wxButton *btn = (wxButton *)FindWindow(GaugePage_Progress);
452 wxCHECK_RET( btn, wxT("no progress button?") );
453
454 StopTimer(btn);
455 }
456 }
457
458 void GaugeWidgetsPage::OnIndeterminateProgressTimer(wxTimerEvent& WXUNUSED(event))
459 {
460 m_gauge->Pulse();
461 }
462
463 void GaugeWidgetsPage::OnUpdateUICurValueText(wxUpdateUIEvent& event)
464 {
465 event.SetText( wxString::Format(wxT("%d"), m_gauge->GetValue()));
466 }
467
468 #endif
469 // wxUSE_GAUGE