1/*
2 * Copyright 2008, Stephan A��mus <superstippi@gmx.de>.
3 * Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
4 * All rights reserved. Distributed under the terms of the MIT License.
5 */
6
7#include "SliderTest.h"
8
9#include <stdio.h>
10
11#include <Message.h>
12#include <Slider.h>
13
14#include "CheckBox.h"
15#include "GroupView.h"
16#include "RadioButton.h"
17#include "TestView.h"
18
19
20// messages
21enum {
22	MSG_ORIENTATION_CHANGED			= 'orch',
23	MSG_THUMB_STYLE_CHANGED			= 'tstc',
24	MSG_HASH_MARKS_CHANGED			= 'hmch',
25	MSG_BAR_THICKNESS_CHANGED		= 'btch',
26	MSG_LABEL_CHANGED				= 'lbch',
27	MSG_LIMIT_LABELS_CHANGED		= 'lmch',
28	MSG_UPDATE_TEXT_CHANGED			= 'utch'
29};
30
31
32// TestSlider
33class SliderTest::TestSlider : public BSlider {
34public:
35	TestSlider()
36		: BSlider("test slider", "Label", NULL, 1, 100, B_HORIZONTAL),
37		fExportUpdateText(false)
38	{
39	}
40
41	virtual char* UpdateText() const
42	{
43		if (!fExportUpdateText)
44			return NULL;
45		sprintf(fUpdateText, "%ld", Value());
46		return fUpdateText;
47	}
48
49	mutable char fUpdateText[32];
50	bool fExportUpdateText;
51};
52
53// OrientationRadioButton
54class SliderTest::OrientationRadioButton : public LabeledRadioButton {
55public:
56	OrientationRadioButton(const char* label, enum orientation orientation)
57		: LabeledRadioButton(label),
58		  fOrientation(orientation)
59	{
60	}
61
62	enum orientation fOrientation;
63};
64
65// ThumbStyleRadioButton
66class SliderTest::ThumbStyleRadioButton : public LabeledRadioButton {
67public:
68	ThumbStyleRadioButton(const char* label, enum thumb_style style)
69		: LabeledRadioButton(label),
70		  fStyle(style)
71	{
72	}
73
74	thumb_style fStyle;
75};
76
77// HashMarkLocationRadioButton
78class SliderTest::HashMarkLocationRadioButton : public LabeledRadioButton {
79public:
80	HashMarkLocationRadioButton(const char* label, enum hash_mark_location
81		location)
82		: LabeledRadioButton(label),
83		  fLocation(location)
84	{
85	}
86
87	hash_mark_location fLocation;
88};
89
90
91// ThicknessRadioButton
92class SliderTest::ThicknessRadioButton : public LabeledRadioButton {
93public:
94	ThicknessRadioButton(const char* label, float thickness)
95		: LabeledRadioButton(label),
96		  fThickness(thickness)
97	{
98	}
99
100	float fThickness;
101};
102
103
104// LabelRadioButton
105class SliderTest::LabelRadioButton : public LabeledRadioButton {
106public:
107	LabelRadioButton(const char* label, const char* sliderLabel)
108		: LabeledRadioButton(label),
109		  fLabel(sliderLabel)
110	{
111	}
112
113	const char*	fLabel;
114};
115
116
117// LimitLabelsRadioButton
118class SliderTest::LimitLabelsRadioButton : public LabeledRadioButton {
119public:
120	LimitLabelsRadioButton(const char* label, const char* minLabel,
121		const char* maxLabel)
122		: LabeledRadioButton(label),
123		  fMinLabel(minLabel),
124		  fMaxLabel(maxLabel)
125	{
126	}
127
128	const char*	fMinLabel;
129	const char*	fMaxLabel;
130};
131
132
133// constructor
134SliderTest::SliderTest()
135	: Test("Slider", NULL),
136	  fSlider(new TestSlider()),
137	  fOrientationRadioGroup(NULL),
138	  fThumbStyleRadioGroup(NULL),
139	  fHashMarkLocationRadioGroup(NULL),
140	  fBarThicknessRadioGroup(NULL),
141	  fLabelRadioGroup(NULL),
142	  fLimitLabelsRadioGroup(NULL),
143	  fUpdateTextCheckBox(NULL)
144{
145	SetView(fSlider);
146}
147
148
149// destructor
150SliderTest::~SliderTest()
151{
152	delete fOrientationRadioGroup;
153	delete fThumbStyleRadioGroup;
154	delete fHashMarkLocationRadioGroup;
155	delete fBarThicknessRadioGroup;
156	delete fLabelRadioGroup;
157	delete fLimitLabelsRadioGroup;
158}
159
160
161// CreateTest
162Test*
163SliderTest::CreateTest()
164{
165	return new SliderTest;
166}
167
168
169// ActivateTest
170void
171SliderTest::ActivateTest(View* controls)
172{
173	// BSlider sets its background color to that of its parent in
174	// AttachedToWindow(). Override.
175	rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
176	fSlider->SetViewColor(background);
177	fSlider->SetLowColor(background);
178	fSlider->SetHashMarkCount(10);
179
180	GroupView* group = new GroupView(B_VERTICAL);
181	group->SetFrame(controls->Bounds());
182	group->SetSpacing(0, 4);
183	controls->AddChild(group);
184
185	GroupView* hGroup = new GroupView(B_HORIZONTAL);
186	group->AddChild(hGroup);
187
188	// the radio button group for selecting the orientation
189
190	GroupView* vGroup = new GroupView(B_VERTICAL);
191	vGroup->SetSpacing(0, 4);
192	hGroup->AddChild(vGroup);
193
194	fOrientationRadioGroup = new RadioButtonGroup(
195		new BMessage(MSG_ORIENTATION_CHANGED), this);
196
197	// horizontal
198	LabeledRadioButton* button = new OrientationRadioButton("Horizontal",
199		B_HORIZONTAL);
200	vGroup->AddChild(button);
201	fOrientationRadioGroup->AddButton(button->GetRadioButton());
202
203	// vertical
204	button = new OrientationRadioButton("Vertical", B_VERTICAL);
205	vGroup->AddChild(button);
206	fOrientationRadioGroup->AddButton(button->GetRadioButton());
207
208	// default to horizontal
209	fOrientationRadioGroup->SelectButton((int32)0);
210
211	// the radio button group for selecting the thumb style
212
213	vGroup = new GroupView(B_VERTICAL);
214	vGroup->SetSpacing(0, 4);
215	hGroup->AddChild(vGroup);
216
217	fThumbStyleRadioGroup = new RadioButtonGroup(
218		new BMessage(MSG_THUMB_STYLE_CHANGED), this);
219
220	// block thumb
221	button = new ThumbStyleRadioButton("Block thumb", B_BLOCK_THUMB);
222	vGroup->AddChild(button);
223	fThumbStyleRadioGroup->AddButton(button->GetRadioButton());
224
225	// triangle thumb
226	button = new ThumbStyleRadioButton("Triangle thumb", B_TRIANGLE_THUMB);
227	vGroup->AddChild(button);
228	fThumbStyleRadioGroup->AddButton(button->GetRadioButton());
229
230	// default to block thumb
231	fThumbStyleRadioGroup->SelectButton((int32)0);
232
233	// spacing
234	group->AddChild(new VStrut(10));
235
236	// the radio button group for selecting the thumb style
237
238	fHashMarkLocationRadioGroup = new RadioButtonGroup(
239		new BMessage(MSG_HASH_MARKS_CHANGED), this);
240
241	// no hash marks
242	button = new HashMarkLocationRadioButton("No hash marks",
243		B_HASH_MARKS_NONE);
244	group->AddChild(button);
245	fHashMarkLocationRadioGroup->AddButton(button->GetRadioButton());
246
247	// left/top hash marks
248	button = new HashMarkLocationRadioButton("Left/top hash marks",
249		B_HASH_MARKS_TOP);
250	group->AddChild(button);
251	fHashMarkLocationRadioGroup->AddButton(button->GetRadioButton());
252
253	// right/bottom hash marks
254	button = new HashMarkLocationRadioButton("Right/bottom hash marks",
255		B_HASH_MARKS_BOTTOM);
256	group->AddChild(button);
257	fHashMarkLocationRadioGroup->AddButton(button->GetRadioButton());
258
259	// both side hash marks
260	button = new HashMarkLocationRadioButton("Both sides hash marks",
261		B_HASH_MARKS_BOTH);
262	group->AddChild(button);
263	fHashMarkLocationRadioGroup->AddButton(button->GetRadioButton());
264
265	// default to no hash marks
266	fHashMarkLocationRadioGroup->SelectButton((int32)0);
267
268	// spacing
269	group->AddChild(new VStrut(10));
270
271	// the radio button group for selecting the bar thickness
272
273	fBarThicknessRadioGroup = new RadioButtonGroup(
274		new BMessage(MSG_BAR_THICKNESS_CHANGED), this);
275
276	// default bar thickness
277	button = new ThicknessRadioButton("Thin bar", 1.0);
278	group->AddChild(button);
279	fBarThicknessRadioGroup->AddButton(button->GetRadioButton());
280
281	// thicker bar
282	button = new ThicknessRadioButton("Normal bar", fSlider->BarThickness());
283	group->AddChild(button);
284	fBarThicknessRadioGroup->AddButton(button->GetRadioButton());
285
286	// very thick bar
287	button = new ThicknessRadioButton("Thick bar", 25.0);
288	group->AddChild(button);
289	fBarThicknessRadioGroup->AddButton(button->GetRadioButton());
290
291	// default to default thickness
292	fBarThicknessRadioGroup->SelectButton((int32)1);
293
294	// spacing
295	group->AddChild(new VStrut(10));
296
297	// the radio button group for selecting the label
298
299	fLabelRadioGroup = new RadioButtonGroup(new BMessage(MSG_LABEL_CHANGED),
300		this);
301
302	// no label
303	button = new LabelRadioButton("No label", NULL);
304	group->AddChild(button);
305	fLabelRadioGroup->AddButton(button->GetRadioButton());
306
307	// label string
308	button = new LabelRadioButton("Label", "Label");
309	group->AddChild(button);
310	fLabelRadioGroup->AddButton(button->GetRadioButton());
311
312	// long label string
313	button = new LabelRadioButton("Long label",
314		"Quite Long Label for a BSlider");
315	group->AddChild(button);
316	fLabelRadioGroup->AddButton(button->GetRadioButton());
317
318	// default to normal label
319	fLabelRadioGroup->SelectButton((int32)1);
320
321	// spacing
322	group->AddChild(new VStrut(10));
323
324	// the radio button group for selecting the limit labels
325
326	fLimitLabelsRadioGroup = new RadioButtonGroup(
327		new BMessage(MSG_LIMIT_LABELS_CHANGED), this);
328
329	// no limit labels
330	button = new LimitLabelsRadioButton("No limit labels", NULL, NULL);
331	group->AddChild(button);
332	fLimitLabelsRadioGroup->AddButton(button->GetRadioButton());
333
334	// normal limit label strings
335	button = new LimitLabelsRadioButton("Normal limit labels", "Min", "Max");
336	group->AddChild(button);
337	fLimitLabelsRadioGroup->AddButton(button->GetRadioButton());
338
339	// long limit label strings
340	button = new LimitLabelsRadioButton("Long limit labels",
341		"Very long min label", "Very long max label");
342	group->AddChild(button);
343	fLimitLabelsRadioGroup->AddButton(button->GetRadioButton());
344
345	// default to no limit labels
346	fLimitLabelsRadioGroup->SelectButton((int32)0);
347
348	// spacing
349	group->AddChild(new VStrut(10));
350
351	// update text
352	fUpdateTextCheckBox = new LabeledCheckBox("Update text",
353		new BMessage(MSG_UPDATE_TEXT_CHANGED), this);
354	group->AddChild(fUpdateTextCheckBox);
355
356
357	// glue
358	group->AddChild(new Glue());
359}
360
361
362// DectivateTest
363void
364SliderTest::DectivateTest()
365{
366}
367
368
369// MessageReceived
370void
371SliderTest::MessageReceived(BMessage* message)
372{
373	switch (message->what) {
374		case MSG_ORIENTATION_CHANGED:
375			_UpdateOrientation();
376			break;
377		case MSG_THUMB_STYLE_CHANGED:
378			_UpdateThumbStyle();
379			break;
380		case MSG_HASH_MARKS_CHANGED:
381			_UpdateHashMarkLocation();
382			break;
383		case MSG_BAR_THICKNESS_CHANGED:
384			_UpdateBarThickness();
385			break;
386		case MSG_LABEL_CHANGED:
387			_UpdateLabel();
388			break;
389		case MSG_LIMIT_LABELS_CHANGED:
390			_UpdateLimitLabels();
391			break;
392		case MSG_UPDATE_TEXT_CHANGED:
393			_UpdateUpdateText();
394			break;
395		default:
396			Test::MessageReceived(message);
397			break;
398	}
399}
400
401
402// _UpdateOrientation
403void
404SliderTest::_UpdateOrientation()
405{
406	if (fOrientationRadioGroup) {
407		// We need to get the parent of the actually selected button, since
408		// that is the labeled radio button we've derived our
409		// BorderStyleRadioButton from.
410		AbstractButton* selectedButton
411			= fOrientationRadioGroup->SelectedButton();
412		View* parent = (selectedButton ? selectedButton->Parent() : NULL);
413		OrientationRadioButton* button = dynamic_cast<OrientationRadioButton*>(
414			parent);
415		if (button)
416			fSlider->SetOrientation(button->fOrientation);
417	}
418}
419
420// _UpdateThumbStyle
421void
422SliderTest::_UpdateThumbStyle()
423{
424	if (fThumbStyleRadioGroup) {
425		// We need to get the parent of the actually selected button, since
426		// that is the labeled radio button we've derived our
427		// BorderStyleRadioButton from.
428		AbstractButton* selectedButton
429			= fThumbStyleRadioGroup->SelectedButton();
430		View* parent = (selectedButton ? selectedButton->Parent() : NULL);
431		ThumbStyleRadioButton* button = dynamic_cast<ThumbStyleRadioButton*>(
432			parent);
433		if (button)
434			fSlider->SetStyle(button->fStyle);
435	}
436}
437
438// _UpdateHashMarkLocation
439void
440SliderTest::_UpdateHashMarkLocation()
441{
442	if (fHashMarkLocationRadioGroup) {
443		// We need to get the parent of the actually selected button, since
444		// that is the labeled radio button we've derived our
445		// BorderStyleRadioButton from.
446		AbstractButton* selectedButton
447			= fHashMarkLocationRadioGroup->SelectedButton();
448		View* parent = (selectedButton ? selectedButton->Parent() : NULL);
449		HashMarkLocationRadioButton* button
450			= dynamic_cast<HashMarkLocationRadioButton*>(parent);
451		if (button)
452			fSlider->SetHashMarks(button->fLocation);
453	}
454}
455
456// _UpdateBarThickness
457void
458SliderTest::_UpdateBarThickness()
459{
460	if (fBarThicknessRadioGroup) {
461		// We need to get the parent of the actually selected button, since
462		// that is the labeled radio button we've derived our
463		// BorderStyleRadioButton from.
464		AbstractButton* selectedButton
465			= fBarThicknessRadioGroup->SelectedButton();
466		View* parent = (selectedButton ? selectedButton->Parent() : NULL);
467		ThicknessRadioButton* button
468			= dynamic_cast<ThicknessRadioButton*>(parent);
469		if (button)
470			fSlider->SetBarThickness(button->fThickness);
471	}
472}
473
474// _UpdateLabel
475void
476SliderTest::_UpdateLabel()
477{
478	if (fLabelRadioGroup) {
479		// We need to get the parent of the actually selected button, since
480		// that is the labeled radio button we've derived our
481		// BorderStyleRadioButton from.
482		AbstractButton* selectedButton = fLabelRadioGroup->SelectedButton();
483		View* parent = (selectedButton ? selectedButton->Parent() : NULL);
484		LabelRadioButton* button = dynamic_cast<LabelRadioButton*>(parent);
485		if (button)
486			fSlider->SetLabel(button->fLabel);
487	}
488}
489
490// _UpdateLimitLabels
491void
492SliderTest::_UpdateLimitLabels()
493{
494	if (fLimitLabelsRadioGroup) {
495		// We need to get the parent of the actually selected button, since
496		// that is the labeled radio button we've derived our
497		// BorderStyleRadioButton from.
498		AbstractButton* selectedButton
499			= fLimitLabelsRadioGroup->SelectedButton();
500		View* parent = (selectedButton ? selectedButton->Parent() : NULL);
501		LimitLabelsRadioButton* button = dynamic_cast<LimitLabelsRadioButton*>(
502			parent);
503		if (button)
504			fSlider->SetLimitLabels(button->fMinLabel, button->fMaxLabel);
505	}
506}
507
508// _UpdateUpdateText
509void
510SliderTest::_UpdateUpdateText()
511{
512	if (!fUpdateTextCheckBox
513		|| fUpdateTextCheckBox->IsSelected() == fSlider->fExportUpdateText)
514		return;
515
516	fSlider->fExportUpdateText = fUpdateTextCheckBox->IsSelected();
517	fSlider->UpdateTextChanged();
518}
519
520