xref: /haiku/src/kits/interface/Spinner.cpp (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
1 /*
2  * Copyright 2015 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT license.
4  *
5  * Authors:
6  *		John Scipione, jscipione@gmail.com
7  */
8 
9 
10 #include <Spinner.h>
11 
12 #include <stdint.h>
13 #include <stdlib.h>
14 
15 #include <PropertyInfo.h>
16 #include <String.h>
17 #include <TextView.h>
18 
19 
20 static property_info sProperties[] = {
21 	{
22 		"MaxValue",
23 		{ B_GET_PROPERTY, 0 },
24 		{ B_DIRECT_SPECIFIER, 0 },
25 		"Returns the maximum value of the spinner.",
26 		0,
27 		{ B_INT32_TYPE }
28 	},
29 	{
30 		"MaxValue",
31 		{ B_SET_PROPERTY, 0 },
32 		{ B_DIRECT_SPECIFIER, 0},
33 		"Sets the maximum value of the spinner.",
34 		0,
35 		{ B_INT32_TYPE }
36 	},
37 
38 	{
39 		"MinValue",
40 		{ B_GET_PROPERTY, 0 },
41 		{ B_DIRECT_SPECIFIER, 0 },
42 		"Returns the minimum value of the spinner.",
43 		0,
44 		{ B_INT32_TYPE }
45 	},
46 	{
47 		"MinValue",
48 		{ B_SET_PROPERTY, 0 },
49 		{ B_DIRECT_SPECIFIER, 0},
50 		"Sets the minimum value of the spinner.",
51 		0,
52 		{ B_INT32_TYPE }
53 	},
54 
55 	{
56 		"Value",
57 		{ B_GET_PROPERTY, 0 },
58 		{ B_DIRECT_SPECIFIER, 0 },
59 		"Returns the value of the spinner.",
60 		0,
61 		{ B_INT32_TYPE }
62 	},
63 	{
64 		"Value",
65 		{ B_SET_PROPERTY, 0 },
66 		{ B_DIRECT_SPECIFIER, 0},
67 		"Sets the value of the spinner.",
68 		0,
69 		{ B_INT32_TYPE }
70 	},
71 
72 	{ 0 }
73 };
74 
75 
76 //	#pragma mark - BSpinner
77 
78 
79 BSpinner::BSpinner(BRect frame, const char* name, const char* label,
80 	BMessage* message, uint32 resizingMode, uint32 flags)
81 	:
82 	BAbstractSpinner(frame, name, label, message, resizingMode, flags)
83 {
84 	_InitObject();
85 }
86 
87 
88 BSpinner::BSpinner(const char* name, const char* label,
89 	BMessage* message, uint32 flags)
90 	:
91 	BAbstractSpinner(name, label, message, flags)
92 {
93 	_InitObject();
94 }
95 
96 
97 BSpinner::BSpinner(BMessage* data)
98 	:
99 	BAbstractSpinner(data)
100 {
101 	_InitObject();
102 
103 	if (data->FindInt32("_min", &fMinValue) != B_OK)
104 		fMinValue = INT32_MIN;
105 
106 	if (data->FindInt32("_max", &fMaxValue) != B_OK)
107 		fMaxValue = INT32_MAX;
108 
109 	if (data->FindInt32("_val", &fValue) != B_OK)
110 		fValue = 0;
111 }
112 
113 
114 BSpinner::~BSpinner()
115 {
116 }
117 
118 
119 BArchivable*
120 BSpinner::Instantiate(BMessage* data)
121 {
122 	if (validate_instantiation(data, "Spinner"))
123 		return new BSpinner(data);
124 
125 	return NULL;
126 }
127 
128 
129 status_t
130 BSpinner::Archive(BMessage* data, bool deep) const
131 {
132 	status_t status = BAbstractSpinner::Archive(data, deep);
133 	data->AddString("class", "Spinner");
134 
135 	if (status == B_OK)
136 		status = data->AddInt32("_min", fMinValue);
137 
138 	if (status == B_OK)
139 		status = data->AddInt32("_max", fMaxValue);
140 
141 	if (status == B_OK)
142 		status = data->AddInt32("_val", fValue);
143 
144 	return status;
145 }
146 
147 
148 status_t
149 BSpinner::GetSupportedSuites(BMessage* message)
150 {
151 	message->AddString("suites", "suite/vnd.Haiku-intenger-spinner");
152 
153 	BPropertyInfo prop_info(sProperties);
154 	message->AddFlat("messages", &prop_info);
155 
156 	return BView::GetSupportedSuites(message);
157 }
158 
159 
160 void
161 BSpinner::AttachedToWindow()
162 {
163 	SetValue(fValue);
164 
165 	BAbstractSpinner::AttachedToWindow();
166 }
167 
168 
169 void
170 BSpinner::Decrement()
171 {
172 	SetValue(Value() - 1);
173 }
174 
175 
176 void
177 BSpinner::Increment()
178 {
179 	SetValue(Value() + 1);
180 }
181 
182 
183 void
184 BSpinner::SetEnabled(bool enable)
185 {
186 	if (IsEnabled() == enable)
187 		return;
188 
189 	SetIncrementEnabled(enable && Value() < fMaxValue);
190 	SetDecrementEnabled(enable && Value() > fMinValue);
191 
192 	BAbstractSpinner::SetEnabled(enable);
193 }
194 
195 
196 void
197 BSpinner::SetMinValue(int32 min)
198 {
199 	fMinValue = min;
200 	SetValue(Value());
201 }
202 
203 
204 void
205 BSpinner::SetMaxValue(int32 max)
206 {
207 	fMaxValue = max;
208 	SetValue(Value());
209 }
210 
211 
212 void
213 BSpinner::Range(int32* min, int32* max)
214 {
215 	*min = fMinValue;
216 	*max = fMaxValue;
217 }
218 
219 
220 void
221 BSpinner::SetRange(int32 min, int32 max)
222 {
223 	SetMinValue(min);
224 	SetMaxValue(max);
225 }
226 
227 
228 void
229 BSpinner::SetValue(int32 value)
230 {
231 	// clip to range
232 	if (value < fMinValue)
233 		value = fMinValue;
234 	else if (value > fMaxValue)
235 		value = fMaxValue;
236 
237 	// update the text view
238 	BString valueString;
239 	valueString << value;
240 	TextView()->SetText(valueString.String());
241 
242 	// update the up and down arrows
243 	SetIncrementEnabled(IsEnabled() && value < fMaxValue);
244 	SetDecrementEnabled(IsEnabled() && value > fMinValue);
245 
246 	if (value == fValue)
247 		return;
248 
249 	fValue = value;
250 	ValueChanged();
251 
252 	Invoke();
253 	Invalidate();
254 }
255 
256 
257 void
258 BSpinner::SetValueFromText()
259 {
260 	SetValue(atol(TextView()->Text()));
261 }
262 
263 
264 //	#pragma mark - BSpinner private methods
265 
266 
267 void
268 BSpinner::_InitObject()
269 {
270 	fMinValue = INT32_MIN;
271 	fMaxValue = INT32_MAX;
272 	fValue = 0;
273 
274 	TextView()->SetAlignment(B_ALIGN_RIGHT);
275 	for (uint32 c = 0; c <= 42; c++)
276 		TextView()->DisallowChar(c);
277 
278 	TextView()->DisallowChar(',');
279 
280 	for (uint32 c = 46; c <= 47; c++)
281 		TextView()->DisallowChar(c);
282 
283 	for (uint32 c = 58; c <= 127; c++)
284 		TextView()->DisallowChar(c);
285 }
286 
287 
288 // FBC padding
289 
290 void BSpinner::_ReservedSpinner20() {}
291 void BSpinner::_ReservedSpinner19() {}
292 void BSpinner::_ReservedSpinner18() {}
293 void BSpinner::_ReservedSpinner17() {}
294 void BSpinner::_ReservedSpinner16() {}
295 void BSpinner::_ReservedSpinner15() {}
296 void BSpinner::_ReservedSpinner14() {}
297 void BSpinner::_ReservedSpinner13() {}
298 void BSpinner::_ReservedSpinner12() {}
299 void BSpinner::_ReservedSpinner11() {}
300 void BSpinner::_ReservedSpinner10() {}
301 void BSpinner::_ReservedSpinner9() {}
302 void BSpinner::_ReservedSpinner8() {}
303 void BSpinner::_ReservedSpinner7() {}
304 void BSpinner::_ReservedSpinner6() {}
305 void BSpinner::_ReservedSpinner5() {}
306 void BSpinner::_ReservedSpinner4() {}
307 void BSpinner::_ReservedSpinner3() {}
308 void BSpinner::_ReservedSpinner2() {}
309 void BSpinner::_ReservedSpinner1() {}
310