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
BSpinner(BRect frame,const char * name,const char * label,BMessage * message,uint32 resizingMode,uint32 flags)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
BSpinner(const char * name,const char * label,BMessage * message,uint32 flags)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
BSpinner(BMessage * data)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
110
~BSpinner()111 BSpinner::~BSpinner()
112 {
113 }
114
115
116 BArchivable*
Instantiate(BMessage * data)117 BSpinner::Instantiate(BMessage* data)
118 {
119 if (validate_instantiation(data, "Spinner"))
120 return new BSpinner(data);
121
122 return NULL;
123 }
124
125
126 status_t
Archive(BMessage * data,bool deep) const127 BSpinner::Archive(BMessage* data, bool deep) const
128 {
129 status_t status = BAbstractSpinner::Archive(data, deep);
130 data->AddString("class", "Spinner");
131
132 if (status == B_OK)
133 status = data->AddInt32("_min", fMinValue);
134
135 if (status == B_OK)
136 status = data->AddInt32("_max", fMaxValue);
137
138 return status;
139 }
140
141
142 status_t
GetSupportedSuites(BMessage * message)143 BSpinner::GetSupportedSuites(BMessage* message)
144 {
145 message->AddString("suites", "suite/vnd.Haiku-intenger-spinner");
146
147 BPropertyInfo prop_info(sProperties);
148 message->AddFlat("messages", &prop_info);
149
150 return BView::GetSupportedSuites(message);
151 }
152
153
154 void
AttachedToWindow()155 BSpinner::AttachedToWindow()
156 {
157 SetValue(Value());
158
159 BAbstractSpinner::AttachedToWindow();
160 }
161
162
163 void
Decrement()164 BSpinner::Decrement()
165 {
166 SetValue(Value() - 1);
167 }
168
169
170 void
Increment()171 BSpinner::Increment()
172 {
173 SetValue(Value() + 1);
174 }
175
176
177 void
SetEnabled(bool enable)178 BSpinner::SetEnabled(bool enable)
179 {
180 if (IsEnabled() == enable)
181 return;
182
183 SetIncrementEnabled(enable && Value() < fMaxValue);
184 SetDecrementEnabled(enable && Value() > fMinValue);
185
186 BAbstractSpinner::SetEnabled(enable);
187 }
188
189
190 void
SetMinValue(int32 min)191 BSpinner::SetMinValue(int32 min)
192 {
193 fMinValue = min;
194 SetValue(Value());
195 }
196
197
198 void
SetMaxValue(int32 max)199 BSpinner::SetMaxValue(int32 max)
200 {
201 fMaxValue = max;
202 SetValue(Value());
203 }
204
205
206 void
Range(int32 * min,int32 * max)207 BSpinner::Range(int32* min, int32* max)
208 {
209 *min = fMinValue;
210 *max = fMaxValue;
211 }
212
213
214 void
SetRange(int32 min,int32 max)215 BSpinner::SetRange(int32 min, int32 max)
216 {
217 SetMinValue(min);
218 SetMaxValue(max);
219 }
220
221
222 void
SetValue(int32 value)223 BSpinner::SetValue(int32 value)
224 {
225 // clip to range
226 if (value < fMinValue)
227 value = fMinValue;
228 else if (value > fMaxValue)
229 value = fMaxValue;
230
231 // update the text view
232 BString valueString;
233 valueString << value;
234 TextView()->SetText(valueString.String());
235
236 // update the up and down arrows
237 SetIncrementEnabled(IsEnabled() && value < fMaxValue);
238 SetDecrementEnabled(IsEnabled() && value > fMinValue);
239
240 if (value == Value())
241 return;
242
243 BControl::SetValue(value);
244 ((int32*)_reserved)[0] = Value();
245
246 ValueChanged();
247
248 Invoke();
249 Invalidate();
250 }
251
252
253 void
SetValueFromText()254 BSpinner::SetValueFromText()
255 {
256 SetValue(atol(TextView()->Text()));
257 }
258
259
260 // #pragma mark - BSpinner private methods
261
262
263 void
_InitObject()264 BSpinner::_InitObject()
265 {
266 fMinValue = INT32_MIN;
267 fMaxValue = INT32_MAX;
268
269 TextView()->SetAlignment(B_ALIGN_RIGHT);
270 for (uint32 c = 0; c <= 42; c++)
271 TextView()->DisallowChar(c);
272
273 TextView()->DisallowChar(',');
274
275 for (uint32 c = 46; c <= 47; c++)
276 TextView()->DisallowChar(c);
277
278 for (uint32 c = 58; c <= 127; c++)
279 TextView()->DisallowChar(c);
280 }
281
282
283 // FBC padding
284
_ReservedSpinner20()285 void BSpinner::_ReservedSpinner20() {}
_ReservedSpinner19()286 void BSpinner::_ReservedSpinner19() {}
_ReservedSpinner18()287 void BSpinner::_ReservedSpinner18() {}
_ReservedSpinner17()288 void BSpinner::_ReservedSpinner17() {}
_ReservedSpinner16()289 void BSpinner::_ReservedSpinner16() {}
_ReservedSpinner15()290 void BSpinner::_ReservedSpinner15() {}
_ReservedSpinner14()291 void BSpinner::_ReservedSpinner14() {}
_ReservedSpinner13()292 void BSpinner::_ReservedSpinner13() {}
_ReservedSpinner12()293 void BSpinner::_ReservedSpinner12() {}
_ReservedSpinner11()294 void BSpinner::_ReservedSpinner11() {}
_ReservedSpinner10()295 void BSpinner::_ReservedSpinner10() {}
_ReservedSpinner9()296 void BSpinner::_ReservedSpinner9() {}
_ReservedSpinner8()297 void BSpinner::_ReservedSpinner8() {}
_ReservedSpinner7()298 void BSpinner::_ReservedSpinner7() {}
_ReservedSpinner6()299 void BSpinner::_ReservedSpinner6() {}
_ReservedSpinner5()300 void BSpinner::_ReservedSpinner5() {}
_ReservedSpinner4()301 void BSpinner::_ReservedSpinner4() {}
_ReservedSpinner3()302 void BSpinner::_ReservedSpinner3() {}
_ReservedSpinner2()303 void BSpinner::_ReservedSpinner2() {}
_ReservedSpinner1()304 void BSpinner::_ReservedSpinner1() {}
305