1 /* 2 * Copyright 2006, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan Aßmus <superstippi@gmx.de> 7 */ 8 9 #include "NummericalTextView.h" 10 11 #include <stdio.h> 12 #include <stdlib.h> 13 14 #include <String.h> 15 16 // constructor 17 NummericalTextView::NummericalTextView(BRect frame, const char* name, 18 BRect textRect, 19 uint32 resizingMode, 20 uint32 flags) 21 : InputTextView(frame, name, textRect, resizingMode, flags) 22 { 23 for (uint32 i = 0; i < '0'; i++) { 24 DisallowChar(i); 25 } 26 for (uint32 i = '9' + 1; i < 255; i++) { 27 DisallowChar(i); 28 } 29 AllowChar('-'); 30 } 31 32 // destructor 33 NummericalTextView::~NummericalTextView() 34 { 35 } 36 37 // Invoke 38 status_t 39 NummericalTextView::Invoke(BMessage* message) 40 { 41 if (!message) 42 message = Message(); 43 44 if (message) { 45 BMessage copy(*message); 46 copy.AddInt32("be:value", IntValue()); 47 copy.AddFloat("float value", FloatValue()); 48 return InputTextView::Invoke(©); 49 } 50 return B_BAD_VALUE; 51 } 52 53 // RevertChanges 54 void 55 NummericalTextView::RevertChanges() 56 { 57 if (fFloatMode) 58 SetValue(fFloatValueCache); 59 else 60 SetValue(fIntValueCache); 61 } 62 63 // ApplyChanges 64 void 65 NummericalTextView::ApplyChanges() 66 { 67 int32 i = atoi(Text()); 68 float f = atof(Text()); 69 70 if ((fFloatMode && f != fFloatValueCache) || 71 (!fFloatMode && i != fIntValueCache)) { 72 Invoke(); 73 } 74 } 75 76 // SetFloatMode 77 void 78 NummericalTextView::SetFloatMode(bool floatingPoint) 79 { 80 fFloatMode = floatingPoint; 81 if (floatingPoint) 82 AllowChar('.'); 83 else 84 DisallowChar('.'); 85 } 86 87 // SetValue 88 void 89 NummericalTextView::SetValue(int32 value) 90 { 91 BString helper; 92 helper << value; 93 SetText(helper.String()); 94 95 // update caches 96 IntValue(); 97 FloatValue(); 98 99 if (IsFocus()) 100 SelectAll(); 101 } 102 103 // SetValue 104 void 105 NummericalTextView::SetValue(float value) 106 { 107 BString helper; 108 helper << value; 109 SetText(helper.String()); 110 111 // update caches 112 IntValue(); 113 FloatValue(); 114 115 if (IsFocus()) 116 SelectAll(); 117 } 118 119 // IntValue 120 int32 121 NummericalTextView::IntValue() const 122 { 123 fIntValueCache = atoi(Text()); 124 return fIntValueCache; 125 } 126 127 // FloatValue 128 float 129 NummericalTextView::FloatValue() const 130 { 131 fFloatValueCache = atof(Text()); 132 return fFloatValueCache; 133 } 134 135 // #pragma mark - 136 137 // Select 138 void 139 NummericalTextView::Select(int32 start, int32 finish) 140 { 141 InputTextView::Select(start, finish); 142 143 _CheckMinusAllowed(); 144 _CheckDotAllowed(); 145 } 146 147 // InsertText 148 void 149 NummericalTextView::InsertText(const char* inText, int32 inLength, int32 inOffset, 150 const text_run_array* inRuns) 151 { 152 InputTextView::InsertText(inText, inLength, inOffset, inRuns); 153 154 _CheckMinusAllowed(); 155 _CheckDotAllowed(); 156 } 157 158 // DeleteText 159 void 160 NummericalTextView::DeleteText(int32 fromOffset, int32 toOffset) 161 { 162 InputTextView::DeleteText(fromOffset, toOffset); 163 164 _CheckMinusAllowed(); 165 _CheckDotAllowed(); 166 } 167 168 // #pragma mark - 169 170 // _ToggleAllowChar 171 void 172 NummericalTextView::_ToggleAllowChar(char c) 173 { 174 const char* text = Text(); 175 if (text) { 176 bool found = false; 177 int32 selectionStart; 178 int32 selectionEnd; 179 GetSelection(&selectionStart, &selectionEnd); 180 int32 pos = 0; 181 while (text[pos]) { 182 // skip selection 183 if (selectionStart < selectionEnd 184 && pos == selectionStart) { 185 pos = selectionEnd; 186 } 187 if (text[pos] == c) { 188 found = true; 189 break; 190 } 191 pos++; 192 } 193 if (found) 194 DisallowChar(c); 195 else 196 AllowChar(c); 197 } 198 } 199 200 // _CheckMinusAllowed 201 void 202 NummericalTextView::_CheckMinusAllowed() 203 { 204 _ToggleAllowChar('-'); 205 } 206 207 // _CheckDotAllowed 208 void 209 NummericalTextView::_CheckDotAllowed() 210 { 211 if (fFloatMode) { 212 _ToggleAllowChar('.'); 213 } 214 } 215 216 217 218 219