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 if (fValue < fMinValue) 201 SetValue(fMinValue); 202 } 203 204 205 void 206 BSpinner::SetMaxValue(int32 max) 207 { 208 fMaxValue = max; 209 if (fValue > fMaxValue) 210 SetValue(fMaxValue); 211 } 212 213 214 void 215 BSpinner::Range(int32* min, int32* max) 216 { 217 *min = fMinValue; 218 *max = fMaxValue; 219 } 220 221 222 void 223 BSpinner::SetRange(int32 min, int32 max) 224 { 225 SetMinValue(min); 226 SetMaxValue(max); 227 } 228 229 230 void 231 BSpinner::SetValue(int32 value) 232 { 233 // clip to range 234 if (value < fMinValue) 235 value = fMinValue; 236 else if (value > fMaxValue) 237 value = fMaxValue; 238 239 // update the text view 240 BString valueString; 241 valueString << value; 242 TextView()->SetText(valueString.String()); 243 244 // update the up and down arrows 245 SetIncrementEnabled(IsEnabled() && value < fMaxValue); 246 SetDecrementEnabled(IsEnabled() && value > fMinValue); 247 248 if (value == fValue) 249 return; 250 251 fValue = value; 252 ValueChanged(); 253 254 Invoke(); 255 Invalidate(); 256 } 257 258 259 void 260 BSpinner::SetValueFromText() 261 { 262 SetValue(atol(TextView()->Text())); 263 } 264 265 266 // #pragma mark - BSpinner private methods 267 268 269 void 270 BSpinner::_InitObject() 271 { 272 fMinValue = INT32_MIN; 273 fMaxValue = INT32_MAX; 274 fValue = 0; 275 276 TextView()->SetAlignment(B_ALIGN_RIGHT); 277 for (uint32 c = 0; c <= 42; c++) 278 TextView()->DisallowChar(c); 279 280 TextView()->DisallowChar(','); 281 282 for (uint32 c = 46; c <= 47; c++) 283 TextView()->DisallowChar(c); 284 285 for (uint32 c = 58; c <= 127; c++) 286 TextView()->DisallowChar(c); 287 } 288 289 290 // FBC padding 291 292 void BSpinner::_ReservedSpinner20() {} 293 void BSpinner::_ReservedSpinner19() {} 294 void BSpinner::_ReservedSpinner18() {} 295 void BSpinner::_ReservedSpinner17() {} 296 void BSpinner::_ReservedSpinner16() {} 297 void BSpinner::_ReservedSpinner15() {} 298 void BSpinner::_ReservedSpinner14() {} 299 void BSpinner::_ReservedSpinner13() {} 300 void BSpinner::_ReservedSpinner12() {} 301 void BSpinner::_ReservedSpinner11() {} 302 void BSpinner::_ReservedSpinner10() {} 303 void BSpinner::_ReservedSpinner9() {} 304 void BSpinner::_ReservedSpinner8() {} 305 void BSpinner::_ReservedSpinner7() {} 306 void BSpinner::_ReservedSpinner6() {} 307 void BSpinner::_ReservedSpinner5() {} 308 void BSpinner::_ReservedSpinner4() {} 309 void BSpinner::_ReservedSpinner3() {} 310 void BSpinner::_ReservedSpinner2() {} 311 void BSpinner::_ReservedSpinner1() {} 312