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