1 /*
2 * Copyright (C) 2002 - David W. Durham
3 *
4 * This file is part of ReZound, an audio editing application.
5 *
6 * ReZound is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2 of the License,
9 * or (at your option) any later version.
10 *
11 * ReZound is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #include "FXTextParamValue.h"
22
23 #include <stdlib.h>
24 #include <math.h> // for log10
25
26 #include <istring>
27
28 #include <CNestedDataFile/CNestedDataFile.h>
29
30 #include "utils.h"
31
32 /*
33 - This is the text entry widget used over and over by ReZound on action dialogs
34 - Its purpose is to select a constant value for a parameter to an action
35 */
36
37 FXDEFMAP(FXTextParamValue) FXTextParamValueMap[]=
38 {
39 //Message_Type ID Message_Handler
40
41 FXMAPFUNC(SEL_COMMAND, FXTextParamValue::ID_VALUE_SPINNER, FXTextParamValue::onValueSpinnerChange),
42 FXMAPFUNC(SEL_COMMAND, FXTextParamValue::ID_VALUE_TEXTBOX, FXTextParamValue::onValueTextBoxChange),
43 };
44
FXIMPLEMENT(FXTextParamValue,FXHorizontalFrame,FXTextParamValueMap,ARRAYNUMBER (FXTextParamValueMap))45 FXIMPLEMENT(FXTextParamValue,FXHorizontalFrame,FXTextParamValueMap,ARRAYNUMBER(FXTextParamValueMap))
46
47 FXTextParamValue::FXTextParamValue(FXComposite *p,int opts,const char *_name,const double _initialValue,const double _minValue,const double _maxValue) :
48 FXHorizontalFrame(p,opts|FRAME_RAISED | LAYOUT_FILL_X|LAYOUT_CENTER_Y,0,0,0,0, 2,2,4,4, 0,0),
49
50 name(_name),
51
52 isNumeric(true),
53
54 initialValue(istring(_initialValue)),
55 minValue(_minValue),
56 maxValue(_maxValue),
57
58 panel(new FXHorizontalFrame(this,FRAME_NONE|LAYOUT_FILL_Y|LAYOUT_CENTER_X,0,0,0,0, 0,0,0,0, 0,0)),
59 titleLabel(new FXLabel(panel,gettext(_name),NULL,LABEL_NORMAL|LAYOUT_CENTER_Y)),
60 valueTextBox(new FXTextField(panel,8,this,ID_VALUE_TEXTBOX, TEXTFIELD_NORMAL | LAYOUT_CENTER_Y)),
61 valueSpinner(new FXSpinner(panel,0,this,ID_VALUE_SPINNER, SPIN_NORMAL|SPIN_NOTEXT | LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0)),
62 unitsLabel(new FXLabel(panel,"",NULL,LABEL_NORMAL|LAYOUT_CENTER_Y)),
63
64 textFont(getApp()->getNormalFont())
65 {
66 valueTextBox->setNumColumns((FXint)(log10(maxValue)+1));
67
68 // create a smaller font to use
69 FXFontDesc d;
70 textFont->getFontDesc(d);
71 d.size-=10;
72 textFont=new FXFont(getApp(),d);
73
74 valueSpinner->setRange(-10,10);
75 setValue(_initialValue);
76
77 //setFontOfAllChildren(this,textFont);
78 }
79
FXTextParamValue(FXComposite * p,int opts,const char * _name,const string _initialValue)80 FXTextParamValue::FXTextParamValue(FXComposite *p,int opts,const char *_name,const string _initialValue) :
81 FXHorizontalFrame(p,opts|FRAME_RAISED | LAYOUT_FILL_X|LAYOUT_CENTER_Y,0,0,0,0, 2,2,4,4, 0,0),
82
83 name(_name),
84
85 isNumeric(false),
86
87 initialValue(_initialValue),
88
89 titleLabel(new FXLabel(this,gettext(_name),NULL,LABEL_NORMAL|LAYOUT_CENTER_Y)),
90 valueTextBox(new FXTextField(this,8,this,ID_VALUE_TEXTBOX, TEXTFIELD_NORMAL | LAYOUT_CENTER_Y|LAYOUT_FILL_X)),
91 valueSpinner(NULL),
92 unitsLabel(NULL),
93
94 textFont(getApp()->getNormalFont())
95 {
96 // create a smaller font to use
97 FXFontDesc d;
98 textFont->getFontDesc(d);
99 d.size-=10;
100 textFont=new FXFont(getApp(),d);
101
102 //setFontOfAllChildren(this,textFont);
103 setText(_initialValue);
104 }
105
~FXTextParamValue()106 FXTextParamValue::~FXTextParamValue()
107 {
108 delete textFont;
109 }
110
setUnits(const FXString units,const FXString tipText)111 void FXTextParamValue::setUnits(const FXString units,const FXString tipText)
112 {
113 if(isNumeric)
114 {
115 unitsLabel->setText(units);
116 unitsLabel->setTipText(tipText);
117 }
118 }
119
onValueSpinnerChange(FXObject * sender,FXSelector sel,void * ptr)120 long FXTextParamValue::onValueSpinnerChange(FXObject *sender,FXSelector sel,void *ptr)
121 {
122 double v=atof(valueTextBox->getText().text());
123 v+=valueSpinner->getValue();
124 valueSpinner->setValue(0);
125 valueTextBox->setText(istring(v).c_str());
126
127 validateRange();
128
129 changed();
130 return 1;
131 }
132
onValueTextBoxChange(FXObject * sender,FXSelector sel,void * ptr)133 long FXTextParamValue::onValueTextBoxChange(FXObject *sender,FXSelector sel,void *ptr)
134 {
135 // just verity that a value character was typed???
136
137 validateRange();
138 changed();
139 return 1;
140 }
141
getValue()142 const double FXTextParamValue::getValue()
143 {
144 validateRange();
145 return atof(valueTextBox->getText().text());
146 }
147
setValue(const double value)148 void FXTextParamValue::setValue(const double value)
149 {
150 valueTextBox->setText(istring(value).c_str());
151 validateRange();
152 changed();
153 }
154
getText()155 const string FXTextParamValue::getText()
156 {
157 validateRange();
158 return valueTextBox->getText().text();
159 }
160
setText(const string value)161 void FXTextParamValue::setText(const string value)
162 {
163 validateRange();
164 valueTextBox->setText(value.c_str());
165 changed();
166 }
167
setRange(const double _minValue,const double _maxValue)168 void FXTextParamValue::setRange(const double _minValue,const double _maxValue)
169 {
170 minValue=_minValue;
171 maxValue=_maxValue;
172 valueTextBox->setNumColumns((FXint)(log10(maxValue)+1));
173 validateRange();
174 changed();
175 }
176
validateRange()177 void FXTextParamValue::validateRange()
178 {
179 if(!isNumeric)
180 return;
181
182 double v=atof(valueTextBox->getText().text());
183
184 if(v<minValue)
185 v=minValue;
186 else if(v>maxValue)
187 v=maxValue;
188
189 valueTextBox->setText(istring(v).c_str());
190 }
191
getName() const192 const string FXTextParamValue::getName() const
193 {
194 return name;
195 }
196
setTipText(const FXString & text)197 void FXTextParamValue::setTipText(const FXString &text)
198 {
199 titleLabel->setTipText(text);
200 valueTextBox->setTipText(text);
201 if(isNumeric)
202 valueSpinner->setTipText(text);
203 }
204
getTipText() const205 FXString FXTextParamValue::getTipText() const
206 {
207 return titleLabel->getTipText();
208 }
209
readFromFile(const string & prefix,CNestedDataFile * f)210 void FXTextParamValue::readFromFile(const string &prefix,CNestedDataFile *f)
211 {
212 const string key=prefix DOT getName() DOT "value";
213 if(f->keyExists(key))
214 {
215 if(isNumeric)
216 setValue(f->getValue<double>(key));
217 else
218 setText(f->getValue<string>(key));
219 }
220 else
221 {
222 if(isNumeric)
223 setValue(atof(initialValue.c_str())); // ??? not i18n safe (i.e. if the locale was ru and the initial value was "1.234")
224 else
225 setText(initialValue);
226 }
227 changed();
228 }
229
writeToFile(const string & prefix,CNestedDataFile * f)230 void FXTextParamValue::writeToFile(const string &prefix,CNestedDataFile *f)
231 {
232 const string key=prefix DOT getName();
233 if(isNumeric)
234 f->setValue<double>(key DOT "value",getValue());
235 else
236 f->setValue<string>(key DOT "value",getText());
237 }
238
changed()239 void FXTextParamValue::changed()
240 {
241 if(target)
242 target->handle(this,FXSEL(SEL_COMMAND,getSelector()),NULL);
243 }
244
245