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 "FXLFOParamValue.h"
22 
23 #include <CNestedDataFile/CNestedDataFile.h>
24 
25 #include "FXConstantParamValue.h"
26 #include "CFOXIcons.h"
27 
28 #include "utils.h"
29 
30 #include "../backend/ActionParamMappers.h"
31 
32 /*
33 	- This is the LFO selection widget used over and over by ReZound on action dialogs
34 
35 	- NOTE: I am using FXListBox's itemData point to store indexes into the LFO
36 	  registry rather than just in the index of the item in the FXListBox because
37 	  sometimes I exclude bipolar LFOs, which makes the index off.
38 */
39 
40 FXDEFMAP(FXLFOParamValue) FXLFOParamValueMap[]=
41 {
42 	//Message_Type		ID					Message_Handler
43 	FXMAPFUNC(SEL_COMMAND,	FXLFOParamValue::ID_LFO_TYPE_COMBOBOX,	FXLFOParamValue::onLFOTypeChange),
44 };
45 
FXIMPLEMENT(FXLFOParamValue,FXVerticalFrame,FXLFOParamValueMap,ARRAYNUMBER (FXLFOParamValueMap))46 FXIMPLEMENT(FXLFOParamValue,FXVerticalFrame,FXLFOParamValueMap,ARRAYNUMBER(FXLFOParamValueMap))
47 
48 FXLFOParamValue::FXLFOParamValue(FXComposite *p,int opts,const char *_name,const string ampUnits,const string ampTitle,const double maxAmp,const string freqUnits,const double maxFreq,const bool hideBipolarLFOs) :
49 	FXVerticalFrame(p,opts|FRAME_RAISED |LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 2,2,2,2, 0,2),
50 
51 	name(_name),
52 
53 	titleLabel(new FXLabel(this,gettext(_name),NULL,LABEL_NORMAL|LAYOUT_CENTER_X)),
54 	sliders(new FXHorizontalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0, 0,0)),
55 
56 		amplitudeSlider(new FXConstantParamValue(
57 			new CActionParamMapper_linear(1.0,min((int)maxAmp,1),min((int)maxAmp,1),(int)maxAmp),
58 			false,
59 			sliders,
60 			LAYOUT_CENTER_X,
61 			gettext(ampTitle.c_str())
62 		)),
63 
64 		frequencySlider(new FXConstantParamValue(
65 			new CActionParamMapper_linear(1.0,min((int)maxFreq,1),min((int)maxFreq,1),(int)maxFreq),
66 			false,
67 			sliders,
68 			LAYOUT_CENTER_X,
69 			N_("Frequency")
70 		)),
71 
72 		phaseSlider(new FXConstantParamValue(
73 			new CActionParamMapper_linear(90.0,360,0,0),
74 			true,
75 			sliders,
76 			LAYOUT_CENTER_X,
77 			N_("Phase")
78 		)),
79 
80 	LFOTypeComboBox(new FXListBox(this,this,ID_LFO_TYPE_COMBOBOX,FRAME_SUNKEN|FRAME_THICK|LISTBOX_NORMAL|LAYOUT_CENTER_X|LAYOUT_FIX_WIDTH)),
81 
82 	textFont(getApp()->getNormalFont()),
83 
84 	minWidth(0),
85 	minHeight(236)
86 {
87 	LFOTypeComboBox->position(0,0,180,0);
88 
89 	amplitudeSlider->setMinSize(0,0);
90 	frequencySlider->setMinSize(0,0);
91 	phaseSlider->setMinSize(0,0);
92 
93 	// create a smaller font to use
94         FXFontDesc d;
95         textFont->getFontDesc(d);
96         d.size-=10;
97         textFont=new FXFont(getApp(),d);
98 
99 	// allow this to be hidden (cause varied repeat doesn't need it)
100 	if(ampTitle=="")
101 		amplitudeSlider->hide();
102 
103 	amplitudeSlider->setUnits(ampUnits.c_str());
104 	frequencySlider->setUnits(freqUnits.c_str());
105 	phaseSlider->setUnits("deg");
106 
107 
108 	LFOTypeComboBox->setWidth(280); // ??? I really would like call something that sets it to the width of the widest item added
109 	LFOTypeComboBox->setNumVisible(16);
110 	for(size_t t=0;t<gLFORegistry.getCount();t++)
111 	{
112 		if(!hideBipolarLFOs || !gLFORegistry.isBipolar(t))
113 		{
114 			LFOTypeComboBox->appendItem(gettext(gLFORegistry.getName(t).c_str()),FOXIcons->getByName(gLFORegistry.getName(t).c_str()),(void *)t);
115 		}
116 	}
117 	LFOTypeComboBox->setCurrentItem(0);
118 
119 	onLFOTypeChange(NULL,0,NULL);
120 
121 	setFontOfAllChildren(this,textFont);
122 }
123 
~FXLFOParamValue()124 FXLFOParamValue::~FXLFOParamValue()
125 {
126 	delete textFont;
127 }
128 
getDefaultWidth()129 FXint FXLFOParamValue::getDefaultWidth()
130 {
131 	return max(FXVerticalFrame::getDefaultWidth(),minWidth);
132 }
133 
getDefaultHeight()134 FXint FXLFOParamValue::getDefaultHeight()
135 {
136 	return max(FXVerticalFrame::getDefaultHeight(),minHeight);
137 }
138 
setMinSize(FXint _minWidth,FXint _minHeight)139 void FXLFOParamValue::setMinSize(FXint _minWidth,FXint _minHeight)
140 {
141 	minWidth=_minWidth;
142 	minHeight=_minHeight;
143 }
144 
onLFOTypeChange(FXObject * sender,FXSelector sel,void * ptr)145 long FXLFOParamValue::onLFOTypeChange(FXObject *sender,FXSelector sel,void *ptr)
146 {
147 	if((size_t)(LFOTypeComboBox->getItemData(LFOTypeComboBox->getCurrentItem()))==3)
148 	{ // constant needs only to have an amplitude setting
149 		amplitudeSlider->enable();
150 		frequencySlider->disable();
151 		phaseSlider->disable();
152 	}
153 	else
154 	{
155 		amplitudeSlider->enable();
156 		frequencySlider->enable();
157 		phaseSlider->enable();
158 	}
159 	return 1;
160 }
161 
getValue()162 const CLFODescription FXLFOParamValue::getValue()
163 {
164 	//validateRange();
165 	return CLFODescription(
166 		amplitudeSlider->getValue(),
167 		frequencySlider->getValue(),
168 		phaseSlider->getValue(),
169 		((size_t)LFOTypeComboBox->getItemData(LFOTypeComboBox->getCurrentItem()))
170 	);
171 }
172 
getName() const173 const string FXLFOParamValue::getName() const
174 {
175 	return name;
176 }
177 
enable()178 void FXLFOParamValue::enable()
179 {
180 	FXVerticalFrame::enable();
181 	enableAllChildren(this);
182 
183 	onLFOTypeChange(NULL,0,NULL);
184 }
185 
disable()186 void FXLFOParamValue::disable()
187 {
188 	FXVerticalFrame::disable();
189 	disableAllChildren(this);
190 }
191 
192 
193 /*
194 void FXLFOParamValue::setTipText(const FXString &text)
195 {
196 	titleLabel->setTipText(text);
197 	valueTextBox->setTipText(text);
198 	valueSpinner->setTipText(text);
199 }
200 
201 FXString FXLFOParamValue::getTipText() const
202 {
203 	return titleLabel->getTipText();
204 }
205 */
206 
readFromFile(const string & prefix,CNestedDataFile * f)207 void FXLFOParamValue::readFromFile(const string &prefix,CNestedDataFile *f)
208 {
209 	const string key=prefix DOT getName();
210 	const string LFOName=f->keyExists(key DOT "name") ? f->getValue<string>(key DOT "name") : "Constant";
211 	try
212 	{
213 		const size_t LFOIndex=gLFORegistry.getIndexByName(LFOName);
214 		for(int t=0;t<LFOTypeComboBox->getNumItems();t++)
215 		{
216 			if(((size_t)LFOTypeComboBox->getItemData(t))==LFOIndex)
217 			{
218 				LFOTypeComboBox->setCurrentItem(t);
219 				break;
220 			}
221 		}
222 	}
223 	catch(...)
224 	{
225 		LFOTypeComboBox->setCurrentItem(0); // default to the first position which should be sine
226 	}
227 	if(isEnabled())
228 		onLFOTypeChange(NULL,0,NULL);
229 
230 	if(amplitudeSlider->getName()!="")
231 		amplitudeSlider->readFromFile(key,f);
232 	frequencySlider->readFromFile(key,f);
233 	phaseSlider->readFromFile(key,f);
234 }
235 
writeToFile(const string & prefix,CNestedDataFile * f)236 void FXLFOParamValue::writeToFile(const string &prefix,CNestedDataFile *f)
237 {
238 	const string key=prefix DOT getName();
239 	f->setValue<string>(key DOT "name", gLFORegistry.getName((size_t)LFOTypeComboBox->getItemData(LFOTypeComboBox->getCurrentItem())) );
240 
241 	if(amplitudeSlider->getName()!="")
242 		amplitudeSlider->writeToFile(key,f);
243 	frequencySlider->writeToFile(key,f);
244 	phaseSlider->writeToFile(key,f);
245 }
246 
247 
248