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
NummericalTextView(BRect frame,const char * name,BRect textRect,uint32 resizingMode,uint32 flags)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
~NummericalTextView()33 NummericalTextView::~NummericalTextView()
34 {
35 }
36
37 // Invoke
38 status_t
Invoke(BMessage * message)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
RevertChanges()55 NummericalTextView::RevertChanges()
56 {
57 if (fFloatMode)
58 SetValue(fFloatValueCache);
59 else
60 SetValue(fIntValueCache);
61 }
62
63 // ApplyChanges
64 void
ApplyChanges()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
SetFloatMode(bool floatingPoint)78 NummericalTextView::SetFloatMode(bool floatingPoint)
79 {
80 fFloatMode = floatingPoint;
81 if (floatingPoint)
82 AllowChar('.');
83 else
84 DisallowChar('.');
85 }
86
87 // SetValue
88 void
SetValue(int32 value)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
SetValue(float value)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
IntValue() const121 NummericalTextView::IntValue() const
122 {
123 fIntValueCache = atoi(Text());
124 return fIntValueCache;
125 }
126
127 // FloatValue
128 float
FloatValue() const129 NummericalTextView::FloatValue() const
130 {
131 fFloatValueCache = atof(Text());
132 return fFloatValueCache;
133 }
134
135 // #pragma mark -
136
137 // Select
138 void
Select(int32 start,int32 finish)139 NummericalTextView::Select(int32 start, int32 finish)
140 {
141 InputTextView::Select(start, finish);
142
143 _CheckMinusAllowed();
144 _CheckDotAllowed();
145 }
146
147 // InsertText
148 void
InsertText(const char * inText,int32 inLength,int32 inOffset,const text_run_array * inRuns)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
DeleteText(int32 fromOffset,int32 toOffset)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
_ToggleAllowChar(char c)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
_CheckMinusAllowed()202 NummericalTextView::_CheckMinusAllowed()
203 {
204 _ToggleAllowChar('-');
205 }
206
207 // _CheckDotAllowed
208 void
_CheckDotAllowed()209 NummericalTextView::_CheckDotAllowed()
210 {
211 if (fFloatMode) {
212 _ToggleAllowChar('.');
213 }
214 }
215
216
217
218
219