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 20static 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 79BSpinner::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 88BSpinner::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 97BSpinner::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 111BSpinner::~BSpinner() 112{ 113} 114 115 116BArchivable* 117BSpinner::Instantiate(BMessage* data) 118{ 119 if (validate_instantiation(data, "Spinner")) 120 return new BSpinner(data); 121 122 return NULL; 123} 124 125 126status_t 127BSpinner::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 142status_t 143BSpinner::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 154void 155BSpinner::AttachedToWindow() 156{ 157 SetValue(Value()); 158 159 BAbstractSpinner::AttachedToWindow(); 160} 161 162 163void 164BSpinner::Decrement() 165{ 166 SetValue(Value() - 1); 167} 168 169 170void 171BSpinner::Increment() 172{ 173 SetValue(Value() + 1); 174} 175 176 177void 178BSpinner::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 190void 191BSpinner::SetMinValue(int32 min) 192{ 193 fMinValue = min; 194 SetValue(Value()); 195} 196 197 198void 199BSpinner::SetMaxValue(int32 max) 200{ 201 fMaxValue = max; 202 SetValue(Value()); 203} 204 205 206void 207BSpinner::Range(int32* min, int32* max) 208{ 209 *min = fMinValue; 210 *max = fMaxValue; 211} 212 213 214void 215BSpinner::SetRange(int32 min, int32 max) 216{ 217 SetMinValue(min); 218 SetMaxValue(max); 219} 220 221 222void 223BSpinner::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 ValueChanged(); 245 246 Invoke(); 247 Invalidate(); 248} 249 250 251void 252BSpinner::SetValueFromText() 253{ 254 SetValue(atol(TextView()->Text())); 255} 256 257 258// #pragma mark - BSpinner private methods 259 260 261void 262BSpinner::_InitObject() 263{ 264 fMinValue = INT32_MIN; 265 fMaxValue = INT32_MAX; 266 267 TextView()->SetAlignment(B_ALIGN_RIGHT); 268 for (uint32 c = 0; c <= 42; c++) 269 TextView()->DisallowChar(c); 270 271 TextView()->DisallowChar(','); 272 273 for (uint32 c = 46; c <= 47; c++) 274 TextView()->DisallowChar(c); 275 276 for (uint32 c = 58; c <= 127; c++) 277 TextView()->DisallowChar(c); 278} 279 280 281// FBC padding 282 283void BSpinner::_ReservedSpinner20() {} 284void BSpinner::_ReservedSpinner19() {} 285void BSpinner::_ReservedSpinner18() {} 286void BSpinner::_ReservedSpinner17() {} 287void BSpinner::_ReservedSpinner16() {} 288void BSpinner::_ReservedSpinner15() {} 289void BSpinner::_ReservedSpinner14() {} 290void BSpinner::_ReservedSpinner13() {} 291void BSpinner::_ReservedSpinner12() {} 292void BSpinner::_ReservedSpinner11() {} 293void BSpinner::_ReservedSpinner10() {} 294void BSpinner::_ReservedSpinner9() {} 295void BSpinner::_ReservedSpinner8() {} 296void BSpinner::_ReservedSpinner7() {} 297void BSpinner::_ReservedSpinner6() {} 298void BSpinner::_ReservedSpinner5() {} 299void BSpinner::_ReservedSpinner4() {} 300void BSpinner::_ReservedSpinner3() {} 301void BSpinner::_ReservedSpinner2() {} 302void BSpinner::_ReservedSpinner1() {} 303