HaikuDepot: notify work status from main window
[haiku.git] / src / kits / interface / DecimalSpinner.cpp
blobd1ef04e2179e13e67d968667070e5b6781d6fcfb
1 /*
2 * Copyright 2015 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT license.
5 * Authors:
6 * John Scipione, jscipione@gmail.com
7 */
10 #include <DecimalSpinner.h>
12 #include <stdio.h>
13 #include <stdlib.h>
15 #include <PropertyInfo.h>
16 #include <TextView.h>
19 static double
20 roundTo(double value, uint32 n)
22 return floor(value * pow(10.0, n) + 0.5) / pow(10.0, n);
26 static property_info sProperties[] = {
28 "MaxValue",
29 { B_GET_PROPERTY, 0 },
30 { B_DIRECT_SPECIFIER, 0 },
31 "Returns the maximum value of the spinner.",
33 { B_DOUBLE_TYPE }
36 "MaxValue",
37 { B_SET_PROPERTY, 0 },
38 { B_DIRECT_SPECIFIER, 0},
39 "Sets the maximum value of the spinner.",
41 { B_DOUBLE_TYPE }
45 "MinValue",
46 { B_GET_PROPERTY, 0 },
47 { B_DIRECT_SPECIFIER, 0 },
48 "Returns the minimum value of the spinner.",
50 { B_DOUBLE_TYPE }
53 "MinValue",
54 { B_SET_PROPERTY, 0 },
55 { B_DIRECT_SPECIFIER, 0},
56 "Sets the minimum value of the spinner.",
58 { B_DOUBLE_TYPE }
62 "Precision",
63 { B_SET_PROPERTY, 0 },
64 { B_DIRECT_SPECIFIER, 0},
65 "Sets the number of decimal places of precision of the spinner.",
67 { B_UINT32_TYPE }
70 "Precision",
71 { B_GET_PROPERTY, 0 },
72 { B_DIRECT_SPECIFIER, 0 },
73 "Returns the number of decimal places of precision of the spinner.",
75 { B_UINT32_TYPE }
79 "Step",
80 { B_GET_PROPERTY, 0 },
81 { B_DIRECT_SPECIFIER, 0 },
82 "Returns the step size of the spinner.",
84 { B_DOUBLE_TYPE }
87 "Step",
88 { B_SET_PROPERTY, 0 },
89 { B_DIRECT_SPECIFIER, 0},
90 "Sets the step size of the spinner.",
92 { B_DOUBLE_TYPE }
96 "Value",
97 { B_GET_PROPERTY, 0 },
98 { B_DIRECT_SPECIFIER, 0 },
99 "Returns the value of the spinner.",
101 { B_DOUBLE_TYPE }
104 "Value",
105 { B_SET_PROPERTY, 0 },
106 { B_DIRECT_SPECIFIER, 0},
107 "Sets the value of the spinner.",
109 { B_DOUBLE_TYPE }
112 { 0 }
116 // #pragma mark - BDecimalSpinner
119 BDecimalSpinner::BDecimalSpinner(BRect frame, const char* name,
120 const char* label, BMessage* message, uint32 resizingMode, uint32 flags)
122 BAbstractSpinner(frame, name, label, message, resizingMode, flags)
124 _InitObject();
128 BDecimalSpinner::BDecimalSpinner(const char* name, const char* label,
129 BMessage* message, uint32 flags)
131 BAbstractSpinner(name, label, message, flags)
133 _InitObject();
137 BDecimalSpinner::BDecimalSpinner(BMessage* data)
139 BAbstractSpinner(data)
141 _InitObject();
143 if (data->FindDouble("_min", &fMinValue) != B_OK)
144 fMinValue = 0.0;
146 if (data->FindDouble("_max", &fMaxValue) != B_OK)
147 fMinValue = 100.0;
149 if (data->FindUInt32("_precision", &fPrecision) != B_OK)
150 fPrecision = 2;
152 if (data->FindDouble("_step", &fStep) != B_OK)
153 fStep = 1.0;
155 if (data->FindDouble("_val", &fValue) != B_OK)
156 fValue = 0.0;
160 BDecimalSpinner::~BDecimalSpinner()
165 BArchivable*
166 BDecimalSpinner::Instantiate(BMessage* data)
168 if (validate_instantiation(data, "DecimalSpinner"))
169 return new BDecimalSpinner(data);
171 return NULL;
175 status_t
176 BDecimalSpinner::Archive(BMessage* data, bool deep) const
178 status_t status = BAbstractSpinner::Archive(data, deep);
179 data->AddString("class", "DecimalSpinner");
181 if (status == B_OK)
182 status = data->AddDouble("_min", fMinValue);
184 if (status == B_OK)
185 status = data->AddDouble("_max", fMaxValue);
187 if (status == B_OK)
188 status = data->AddUInt32("_precision", fPrecision);
190 if (status == B_OK)
191 status = data->AddDouble("_step", fStep);
193 if (status == B_OK)
194 status = data->AddDouble("_val", fValue);
196 return status;
200 status_t
201 BDecimalSpinner::GetSupportedSuites(BMessage* message)
203 message->AddString("suites", "suite/vnd.Haiku-decimal-spinner");
205 BPropertyInfo prop_info(sProperties);
206 message->AddFlat("messages", &prop_info);
208 return BView::GetSupportedSuites(message);
212 void
213 BDecimalSpinner::AttachedToWindow()
215 SetValue(fValue);
217 BAbstractSpinner::AttachedToWindow();
221 void
222 BDecimalSpinner::Decrement()
224 SetValue(Value() - Step());
228 void
229 BDecimalSpinner::Increment()
231 SetValue(Value() + Step());
235 void
236 BDecimalSpinner::SetEnabled(bool enable)
238 if (IsEnabled() == enable)
239 return;
241 SetIncrementEnabled(enable && Value() < fMaxValue);
242 SetDecrementEnabled(enable && Value() > fMinValue);
244 BAbstractSpinner::SetEnabled(enable);
248 void
249 BDecimalSpinner::SetMinValue(double min)
251 fMinValue = min;
252 if (fValue < fMinValue)
253 SetValue(fMinValue);
257 void
258 BDecimalSpinner::SetMaxValue(double max)
260 fMaxValue = max;
261 if (fValue > fMaxValue)
262 SetValue(fMaxValue);
266 void
267 BDecimalSpinner::Range(double* min, double* max)
269 *min = fMinValue;
270 *max = fMaxValue;
274 void
275 BDecimalSpinner::SetRange(double min, double max)
277 SetMinValue(min);
278 SetMaxValue(max);
282 void
283 BDecimalSpinner::SetValue(int32 value)
285 SetValue((double)value);
289 void
290 BDecimalSpinner::SetValue(double value)
292 // clip to range
293 if (value < fMinValue)
294 value = fMinValue;
295 else if (value > fMaxValue)
296 value = fMaxValue;
298 // update the text view
299 char* format;
300 asprintf(&format, "%%.%" B_PRId32 "f", fPrecision);
301 char* valueString;
302 asprintf(&valueString, format, value);
303 TextView()->SetText(valueString);
304 free(format);
305 free(valueString);
307 // update the up and down arrows
308 SetIncrementEnabled(IsEnabled() && value < fMaxValue);
309 SetDecrementEnabled(IsEnabled() && value > fMinValue);
311 if (value == fValue)
312 return;
314 fValue = value;
315 ValueChanged();
317 Invoke();
318 Invalidate();
322 void
323 BDecimalSpinner::SetValueFromText()
325 SetValue(roundTo(atof(TextView()->Text()), Precision()));
329 // #pragma mark - BDecimalSpinner private methods
332 void
333 BDecimalSpinner::_InitObject()
335 fMinValue = 0.0;
336 fMaxValue = 100.0;
337 fPrecision = 2;
338 fStep = 1.0;
339 fValue = 0.0;
341 TextView()->SetAlignment(B_ALIGN_RIGHT);
342 for (uint32 c = 0; c <= 42; c++)
343 TextView()->DisallowChar(c);
345 TextView()->DisallowChar('/');
346 for (uint32 c = 58; c <= 127; c++)
347 TextView()->DisallowChar(c);
351 // FBC padding
353 void BDecimalSpinner::_ReservedDecimalSpinner20() {}
354 void BDecimalSpinner::_ReservedDecimalSpinner19() {}
355 void BDecimalSpinner::_ReservedDecimalSpinner18() {}
356 void BDecimalSpinner::_ReservedDecimalSpinner17() {}
357 void BDecimalSpinner::_ReservedDecimalSpinner16() {}
358 void BDecimalSpinner::_ReservedDecimalSpinner15() {}
359 void BDecimalSpinner::_ReservedDecimalSpinner14() {}
360 void BDecimalSpinner::_ReservedDecimalSpinner13() {}
361 void BDecimalSpinner::_ReservedDecimalSpinner12() {}
362 void BDecimalSpinner::_ReservedDecimalSpinner11() {}
363 void BDecimalSpinner::_ReservedDecimalSpinner10() {}
364 void BDecimalSpinner::_ReservedDecimalSpinner9() {}
365 void BDecimalSpinner::_ReservedDecimalSpinner8() {}
366 void BDecimalSpinner::_ReservedDecimalSpinner7() {}
367 void BDecimalSpinner::_ReservedDecimalSpinner6() {}
368 void BDecimalSpinner::_ReservedDecimalSpinner5() {}
369 void BDecimalSpinner::_ReservedDecimalSpinner4() {}
370 void BDecimalSpinner::_ReservedDecimalSpinner3() {}
371 void BDecimalSpinner::_ReservedDecimalSpinner2() {}
372 void BDecimalSpinner::_ReservedDecimalSpinner1() {}