1 /*
2 * tracker/DialogWithValues.cpp
3 *
4 * Copyright 2009 Peter Barth
5 *
6 * This file is part of Milkytracker.
7 *
8 * Milkytracker is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * Milkytracker is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with Milkytracker. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 /*
24 * DialogWithValues.cpp
25 * MilkyTracker
26 *
27 * Created by Peter Barth on 25.10.05.
28 *
29 */
30
31 #include "DialogWithValues.h"
32 #include "Screen.h"
33 #include "StaticText.h"
34 #include "MessageBoxContainer.h"
35 #include "Font.h"
36 #include "ListBox.h"
37 #include "Seperator.h"
38
DialogWithValues(PPScreen * screen,DialogResponder * responder,pp_int32 id,const PPString & caption,ValueStyles style)39 DialogWithValues::DialogWithValues(PPScreen* screen,
40 DialogResponder* responder,
41 pp_int32 id,
42 const PPString& caption,
43 ValueStyles style) :
44 PPDialogBase()
45 {
46 valueOne = 0;
47 valueTwo = 0;
48 valueOneRangeStart = (float)-0x7FFFFFFF;
49 valueOneRangeEnd = (float)0x7FFFFFFE;
50 valueTwoRangeStart = (float)-0x7FFFFFFF;
51 valueTwoRangeEnd = (float)0x7FFFFFFE;
52 valueOneIncreaseStep = 1.0f;
53 valueTwoIncreaseStep = 1.0f;
54 numValueOneDecimals = 0;
55 numValueTwoDecimals = 0;
56
57 switch (style)
58 {
59 case ValueStyleEnterOneValue:
60 #ifdef __LOWRES__
61 initDialog(screen, responder, id, caption, 290, 110+15, 26+15, "Ok", "Cancel");
62 #else
63 initDialog(screen, responder, id, caption, 290, 110, 26, "Ok", "Cancel");
64 #endif
65 break;
66
67 case ValueStyleEnterTwoValues:
68 #ifdef __LOWRES__
69 initDialog(screen, responder, id, caption, 290, 142+15, 26+15, "Ok", "Cancel");
70 #else
71 initDialog(screen, responder, id, caption, 290, 142, 26, "Ok", "Cancel");
72 #endif
73 break;
74 }
75
76 pp_int32 x = getMessageBoxContainer()->getLocation().x;
77
78 pp_int32 width = getMessageBoxContainer()->getSize().width;
79
80 pp_int32 x2 = x;
81 pp_int32 y2 = getMessageBoxContainer()->getControlByID(MESSAGEBOX_STATICTEXT_MAIN_CAPTION)->getLocation().y;
82
83 PPButton* button;
84
85 if (style == ValueStyleEnterOneValue ||
86 style == ValueStyleEnterTwoValues)
87 {
88 //setValueOneCaption("Enter new volume in percent");
89 y2 +=20+12;
90
91 // enter edit field 1
92 x2 = x + width / 2 - (100+35)/2;
93
94 PPListBox* listBox = new PPListBox(MESSAGEBOX_LISTBOX_VALUE_ONE, screen, this, PPPoint(x2, y2), PPSize(100,12), true, true, false);
95 listBox->showSelection(false);
96 listBox->setBorderColor(messageBoxContainerGeneric->getColor());
97 listBox->setMaxEditSize(8);
98 messageBoxContainerGeneric->addControl(listBox);
99
100 button = new PPButton(MESSAGEBOX_BUTTON_INCREASE_VALUEONE, screen, this, PPPoint(x2 + listBox->getSize().width + 2, y2), PPSize(16, 11));
101 button->setText("+");
102 messageBoxContainerGeneric->addControl(button);
103
104 button = new PPButton(MESSAGEBOX_BUTTON_DECREASE_VALUEONE, screen, this, PPPoint(x2 + listBox->getSize().width + 2 + button->getSize().width + 1, y2), PPSize(16, 11));
105 button->setText("-");
106 messageBoxContainerGeneric->addControl(button);
107
108 #ifdef __LOWRES__
109 pp_int32 height = getMessageBoxContainer()->getSize().height;
110 pp_int32 y = getMessageBoxContainer()->getLocation().y;
111
112 const char buttonTexts[] = {'1','2','3','4','5','6','7','8','9','0','+','-','.','<','>'};
113
114 pp_int32 bWidth = (width - 22*2 - 2*3) / sizeof(buttonTexts);
115 pp_int32 x2_2 = x+4;
116
117 pp_int32 y2_2 = y+height - 4 - 13;
118
119 messageBoxContainerGeneric->addControl(new PPSeperator(0, screen, PPPoint(x2_2-1, y2_2-3), width-2*3, messageBoxContainerGeneric->getColor(), true));
120
121 pp_uint32 i = 0;
122 for (i = 0; i < sizeof(buttonTexts); i++)
123 {
124 button = new PPButton(MESSAGEBOX_BUTTON_KEYS_BASE+i, screen, this, PPPoint(x2_2, y2_2), PPSize(bWidth+1, 13));
125 button->setText(buttonTexts[i]);
126 messageBoxContainerGeneric->addControl(button);
127 x2_2+=bWidth;
128 }
129
130 bWidth = 22;
131
132 button = new PPButton(MESSAGEBOX_BUTTON_KEYS_BASE+i, screen, this, PPPoint(x2_2, y2_2), PPSize(bWidth+1-3, 13));
133 button->setFont(PPFont::getFont(PPFont::FONT_TINY));
134 button->setText("Del");
135 messageBoxContainerGeneric->addControl(button);
136 x2_2+=bWidth-3;
137 i++;
138 button = new PPButton(MESSAGEBOX_BUTTON_KEYS_BASE+i, screen, this, PPPoint(x2_2, y2_2), PPSize(bWidth+1, 13));
139 button->setFont(PPFont::getFont(PPFont::FONT_TINY));
140 button->setText("Back");
141 messageBoxContainerGeneric->addControl(button);
142 #endif
143 }
144
145 if (style == ValueStyleEnterTwoValues)
146 {
147 //setValueTwoCaption("Enter new volume in percent");
148 y2 += 32;
149
150 // enter edit field 2
151 x2 = x + width / 2 - (100+35)/2;
152
153 PPListBox* listBox = new PPListBox(MESSAGEBOX_LISTBOX_VALUE_TWO, screen, this, PPPoint(x2, y2), PPSize(100,12), true, true, false);
154 listBox->showSelection(false);
155 listBox->setBorderColor(messageBoxContainerGeneric->getColor());
156 listBox->setMaxEditSize(8);
157 messageBoxContainerGeneric->addControl(listBox);
158
159 button = new PPButton(MESSAGEBOX_BUTTON_INCREASE_VALUETWO, screen, this, PPPoint(x2 + listBox->getSize().width + 2, y2), PPSize(16, 11));
160 button->setText("+");
161 messageBoxContainerGeneric->addControl(button);
162
163 button = new PPButton(MESSAGEBOX_BUTTON_DECREASE_VALUETWO, screen, this, PPPoint(x2 + listBox->getSize().width + 2 + button->getSize().width + 1, y2), PPSize(16, 11));
164 button->setText("-");
165 messageBoxContainerGeneric->addControl(button);
166 }
167
168 fitListBoxes();
169 updateListBoxes();
170 }
171
setValueOneCaption(const PPString & caption)172 void DialogWithValues::setValueOneCaption(const PPString& caption)
173 {
174 PPControl* ctrl = messageBoxContainerGeneric->getControlByID(MESSAGEBOX_STATICTEXT_VALUE_ONE_CAPTION);
175 if (ctrl)
176 messageBoxContainerGeneric->removeControl(ctrl);
177
178 pp_int32 width = messageBoxContainerGeneric->getSize().width;
179
180 pp_int32 x = messageBoxContainerGeneric->getLocation().x;
181 pp_int32 y = messageBoxContainerGeneric->getControlByID(MESSAGEBOX_STATICTEXT_MAIN_CAPTION)->getLocation().y;
182
183 y+=20;
184
185 x += width / 2 - (PPFont::getFont(PPFont::FONT_SYSTEM)->getStrWidth(caption) / 2);
186
187 messageBoxContainerGeneric->addControl(new PPStaticText(MESSAGEBOX_STATICTEXT_VALUE_ONE_CAPTION, parentScreen, this, PPPoint(x, y), caption, true));
188 }
189
setValueTwoCaption(const PPString & caption)190 void DialogWithValues::setValueTwoCaption(const PPString& caption)
191 {
192 PPControl* ctrl = messageBoxContainerGeneric->getControlByID(MESSAGEBOX_STATICTEXT_VALUE_TWO_CAPTION);
193 if (ctrl)
194 messageBoxContainerGeneric->removeControl(ctrl);
195
196 pp_int32 width = messageBoxContainerGeneric->getSize().width;
197
198 pp_int32 x = messageBoxContainerGeneric->getLocation().x;
199 pp_int32 y = messageBoxContainerGeneric->getControlByID(MESSAGEBOX_STATICTEXT_MAIN_CAPTION)->getLocation().y;
200
201 y+=20+32;
202
203 x += width / 2 - (PPFont::getFont(PPFont::FONT_SYSTEM)->getStrWidth(caption) / 2);
204
205 messageBoxContainerGeneric->addControl(new PPStaticText(MESSAGEBOX_STATICTEXT_VALUE_TWO_CAPTION, parentScreen, this, PPPoint(x, y), caption, true));
206 }
207
show(bool b)208 void DialogWithValues::show(bool b/* = true*/)
209 {
210 if (b)
211 listBoxEnterEditState(MESSAGEBOX_LISTBOX_VALUE_ONE);
212 PPDialogBase::show(b);
213 }
214
handleEvent(PPObject * sender,PPEvent * event)215 pp_int32 DialogWithValues::handleEvent(PPObject* sender, PPEvent* event)
216 {
217 if (event->getID() == eKeyDown)
218 {
219 pp_uint16 keyCode = *((pp_uint16*)event->getDataPtr());
220 if (keyCode == VK_TAB)
221 {
222 switchListBox();
223 event->cancel();
224 }
225 }
226 else if (event->getID() == eCommand || event->getID() == eCommandRepeat)
227 {
228 switch (reinterpret_cast<PPControl*>(sender)->getID())
229 {
230 case PP_MESSAGEBOX_BUTTON_YES:
231 {
232 commitChanges();
233 break;
234 }
235
236 case MESSAGEBOX_BUTTON_INCREASE_VALUEONE:
237 {
238 setValueOne(valueOne+valueOneIncreaseStep);
239 parentScreen->paintControl(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_ONE));
240 break;
241 }
242
243 case MESSAGEBOX_BUTTON_DECREASE_VALUEONE:
244 {
245 setValueOne(valueOne-valueOneIncreaseStep);
246 parentScreen->paintControl(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_ONE));
247 break;
248 }
249
250 case MESSAGEBOX_BUTTON_INCREASE_VALUETWO:
251 {
252 setValueTwo(valueTwo+valueOneIncreaseStep);
253 parentScreen->paintControl(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_TWO));
254 break;
255 }
256
257 case MESSAGEBOX_BUTTON_DECREASE_VALUETWO:
258 {
259 setValueTwo(valueTwo-valueOneIncreaseStep);
260 parentScreen->paintControl(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_TWO));
261 break;
262 }
263
264 }
265 }
266 else if (event->getID() == eValueChanged)
267 {
268 switch (reinterpret_cast<PPControl*>(sender)->getID())
269 {
270 // song title
271 case MESSAGEBOX_LISTBOX_VALUE_ONE:
272 {
273 const PPString* str = *(reinterpret_cast<PPString* const*>(event->getDataPtr()));
274 setValueOne((float)atof(*str));
275 break;
276 }
277
278 case MESSAGEBOX_LISTBOX_VALUE_TWO:
279 {
280 const PPString* str = *(reinterpret_cast<PPString* const*>(event->getDataPtr()));
281 setValueTwo((float)atof(*str));
282 break;
283 }
284 }
285 }
286
287 return PPDialogBase::handleEvent(sender, event);
288 }
289
setValueOneRange(float start,float end,pp_int32 numDecimals)290 void DialogWithValues::setValueOneRange(float start, float end, pp_int32 numDecimals)
291 {
292 valueOneRangeStart = start; valueOneRangeEnd = end; numValueOneDecimals = numDecimals;
293 fitListBoxes();
294 setValueOne(valueOne);
295 }
setValueTwoRange(float start,float end,pp_int32 numDecimals)296 void DialogWithValues::setValueTwoRange(float start, float end, pp_int32 numDecimals)
297 {
298 valueTwoRangeStart = start; valueTwoRangeEnd = end; numValueTwoDecimals = numDecimals;
299 fitListBoxes();
300 setValueTwo(valueTwo);
301 }
302
fitListBoxes()303 void DialogWithValues::fitListBoxes()
304 {
305 fitListBox(MESSAGEBOX_LISTBOX_VALUE_ONE, valueOneRangeStart, valueOneRangeEnd, numValueOneDecimals);
306 fitListBox(MESSAGEBOX_LISTBOX_VALUE_TWO, valueTwoRangeStart, valueTwoRangeEnd, numValueTwoDecimals);
307 }
308
fitListBox(pp_int32 id,float valueOneRangeStart,float valueOneRangeEnd,pp_int32 numDecimals)309 void DialogWithValues::fitListBox(pp_int32 id, float valueOneRangeStart, float valueOneRangeEnd, pp_int32 numDecimals)
310 {
311 pp_int32 width = messageBoxContainerGeneric->getSize().width;
312 pp_int32 x = messageBoxContainerGeneric->getLocation().x;
313
314 char buffer1[100];
315 char buffer2[100];
316
317 sprintf(buffer1, "%%.%if", numDecimals);
318
319 PPListBox* listBox = static_cast<PPListBox*>(messageBoxContainerGeneric->getControlByID(id));
320 if (listBox)
321 {
322 sprintf(buffer2, buffer1, valueOneRangeStart);
323 pp_int32 len = (pp_int32)strlen(buffer2);
324 sprintf(buffer2, buffer1, valueOneRangeEnd);
325 if ((pp_int32)strlen(buffer2) > len) len = (pp_int32)strlen(buffer2);
326
327 pp_int32 y2 = listBox->getLocation().y;
328
329 pp_int32 x2 = x + width / 2 - ((len*8)+10+35)/2;
330
331 listBox->setLocation(PPPoint(x2, y2));
332 listBox->setSize(PPSize(len*8+10, listBox->getSize().height));
333
334 x2+=listBox->getSize().width + 2;
335
336 PPButton* button = static_cast<PPButton*>(messageBoxContainerGeneric->getControlByID(id+1));
337 y2 = button->getLocation().y;
338 button->setLocation(PPPoint(x2, y2));
339
340 x2+=button->getSize().width+1;
341 button = static_cast<PPButton*>(messageBoxContainerGeneric->getControlByID(id+2));
342 y2 = button->getLocation().y;
343 button->setLocation(PPPoint(x2, y2));
344 }
345 }
346
updateListBoxes()347 void DialogWithValues::updateListBoxes()
348 {
349 updateListBox(MESSAGEBOX_LISTBOX_VALUE_ONE, valueOne, numValueOneDecimals);
350 updateListBox(MESSAGEBOX_LISTBOX_VALUE_TWO, valueTwo, numValueTwoDecimals);
351 }
352
updateListBox(pp_int32 id,float val,pp_int32 numDecimals)353 void DialogWithValues::updateListBox(pp_int32 id, float val, pp_int32 numDecimals)
354 {
355 char buffer1[100];
356 char buffer2[100];
357
358 sprintf(buffer1, "%%.%if", numDecimals);
359
360 PPListBox* listBox = static_cast<PPListBox*>(messageBoxContainerGeneric->getControlByID(id));
361 if (listBox)
362 {
363 sprintf(buffer2, buffer1, val);
364 listBox->clear();
365 listBox->addItem(buffer2);
366 }
367 }
368
commitChanges()369 void DialogWithValues::commitChanges()
370 {
371 PPListBox* listBox = static_cast<PPListBox*>(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_ONE));
372 if (listBox)
373 listBox->commitChanges();
374
375 listBox = static_cast<PPListBox*>(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_TWO));
376 if (listBox)
377 listBox->commitChanges();
378 }
379
listBoxEnterEditState(pp_int32 id)380 void DialogWithValues::listBoxEnterEditState(pp_int32 id)
381 {
382 PPListBox* listBox = static_cast<PPListBox*>(messageBoxContainerGeneric->getControlByID(id));
383 if (listBox)
384 listBox->placeCursorAtEnd();
385 }
386
switchListBox()387 void DialogWithValues::switchListBox()
388 {
389 if (messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_TWO) == NULL)
390 return;
391
392 PPListBox* listBox = static_cast<PPListBox*>(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_ONE));
393 if (listBox->isEditing())
394 {
395 listBox->commitChanges();
396 listBoxEnterEditState(MESSAGEBOX_LISTBOX_VALUE_TWO);
397 messageBoxContainerGeneric->setFocus(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_TWO));
398 parentScreen->paintControl(messageBoxContainerGeneric);
399 return;
400 }
401
402 listBox = static_cast<PPListBox*>(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_TWO));
403 if (listBox->isEditing())
404 {
405 listBox->commitChanges();
406 listBoxEnterEditState(MESSAGEBOX_LISTBOX_VALUE_ONE);
407 messageBoxContainerGeneric->setFocus(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_ONE));
408 parentScreen->paintControl(messageBoxContainerGeneric);
409 return;
410 }
411
412 listBoxEnterEditState(MESSAGEBOX_LISTBOX_VALUE_ONE);
413 messageBoxContainerGeneric->setFocus(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_ONE));
414 parentScreen->paintControl(messageBoxContainerGeneric);
415 }
416