1 /*
2  *  tracker/SectionSettings.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  *  SectionSettings.cpp
25  *  MilkyTracker
26  *
27  *  Created by Peter Barth on Sun Mar 13 2005.
28  *
29  */
30 
31 #include "SectionSettings.h"
32 #include "Tracker.h"
33 #include "TrackerConfig.h"
34 #include "ModuleEditor.h"
35 #include "PlayerMaster.h"
36 #include "ResamplerHelper.h"
37 #include "PlayerController.h"
38 #include "SystemMessage.h"
39 
40 #include "PPUIConfig.h"
41 #include "CheckBox.h"
42 #include "CheckBoxLabel.h"
43 #include "ListBox.h"
44 #include "RadioGroup.h"
45 #include "Seperator.h"
46 #include "Slider.h"
47 #include "StaticText.h"
48 #include "TransparentContainer.h"
49 #include "PatternEditorControl.h"
50 #include "DialogWithValues.h"
51 #include "DialogListBox.h"
52 #include "Graphics.h"
53 
54 #include "PatternTools.h"
55 #include "TrackerSettingsDatabase.h"
56 #include "SectionSamples.h"
57 #include "ColorPaletteContainer.h"
58 #include "ColorExportImport.h"
59 // OS Interface
60 #include "PPOpenPanel.h"
61 #include "PPSavePanel.h"
62 
63 #include "FileExtProvider.h"
64 
65 #include "ControlIDs.h"
66 
67 #ifdef __LOWRES__
68 #define SECTIONHEIGHT		148
69 #else
70 #define SECTIONHEIGHT		118
71 #endif
72 #define UPPERFRAMEHEIGHT	118
73 
74 // small custom button class which will be used to show a color preview
75 class PPColPrevButton : public PPButton
76 {
77 public:
PPColPrevButton(pp_int32 id,PPScreen * parentScreen,EventListenerInterface * eventListener,PPPoint location,PPSize size)78 	PPColPrevButton(pp_int32 id, PPScreen* parentScreen, EventListenerInterface* eventListener, PPPoint location, PPSize size) :
79 		PPButton(id, parentScreen, eventListener, location, size, false, false, false)
80 	{
81 	}
82 
paint(PPGraphicsAbstract * g)83 	virtual void paint(PPGraphicsAbstract* g)
84 	{
85 		PPButton::paint(g);
86 
87 		PPFont* font = PPFont::getFont(PPFont::FONT_TINY);
88 		g->setFont(font);
89 
90 		PPPoint p = this->getLocation();
91 		p.x+=1;
92 		p.y+=2;
93 
94 		g->setColor(255^getColor()->r, 255^getColor()->g, 255^getColor()->b);
95 
96 		char buffer[100];
97 
98 		sprintf(buffer, "R:%02X", getColor()->r);
99 		g->drawString(buffer, p.x, p.y, false);
100 		p.y+=font->getCharHeight();
101 		sprintf(buffer, "G:%02X", getColor()->g);
102 		g->drawString(buffer, p.x, p.y, false);
103 		p.y+=font->getCharHeight();
104 		sprintf(buffer, "B:%02X", getColor()->b);
105 		g->drawString(buffer, p.x, p.y, false);
106 	}
107 };
108 
109 // settings
110 enum ControlIDs
111 {
112 	PAGE_BUTTON_0						= 50,
113 	PAGE_BUTTON_1,
114 	PAGE_BUTTON_2,
115 	PAGE_BUTTON_3,
116 	PAGE_BUTTON_4,
117 	PAGE_BUTTON_5,
118 	PAGE_BUTTON_6,
119 	PAGE_BUTTON_7,
120 
121 	SUBPAGE_BUTTON_LEFT_0,
122 	SUBPAGE_BUTTON_LEFT_1,
123 	SUBPAGE_BUTTON_LEFT_2,
124 	SUBPAGE_BUTTON_LEFT_3,
125 	SUBPAGE_BUTTON_LEFT_4,
126 	SUBPAGE_BUTTON_LEFT_5,
127 	SUBPAGE_BUTTON_LEFT_6,
128 	SUBPAGE_BUTTON_LEFT_7,
129 
130 	SUBPAGE_BUTTON_RIGHT_0,
131 	SUBPAGE_BUTTON_RIGHT_1,
132 	SUBPAGE_BUTTON_RIGHT_2,
133 	SUBPAGE_BUTTON_RIGHT_3,
134 	SUBPAGE_BUTTON_RIGHT_4,
135 	SUBPAGE_BUTTON_RIGHT_5,
136 	SUBPAGE_BUTTON_RIGHT_6,
137 	SUBPAGE_BUTTON_RIGHT_7,
138 
139 	RADIOGROUP_SETTINGS_PAGE,
140 
141 	BUTTON_SETTINGS_OK,
142 	BUTTON_SETTINGS_APPLY,
143 	BUTTON_SETTINGS_CANCEL,
144 
145 	// Page I
146 	RADIOGROUP_SETTINGS_FREQTAB,
147 	STATICTEXT_SETTINGS_BUFFERSIZE,
148 	STATICTEXT_SETTINGS_MIXERVOL,
149 	SLIDER_SETTINGS_BUFFERSIZE,
150 	SLIDER_SETTINGS_MIXERVOL,
151 	STATICTEXT_SETTINGS_FORCEPOWER2BUFF,
152 	CHECKBOX_SETTINGS_FORCEPOWER2BUFF,
153 	RADIOGROUP_SETTINGS_AMPLIFY,
154 	BUTTON_SETTINGS_RESAMPLING,
155 	CHECKBOX_SETTINGS_RAMPING,
156 	RADIOGROUP_SETTINGS_MIXFREQ,
157 	BUTTON_SETTINGS_CHOOSEDRIVER,
158     RADIOGROUP_SETTINGS_XMCHANNELLIMIT,
159 
160 	// PAGE I (2)
161 	CHECKBOX_SETTINGS_VIRTUALCHANNELS,
162 	BUTTON_SETTINGS_VIRTUALCHANNELS_PLUS,
163 	BUTTON_SETTINGS_VIRTUALCHANNELS_MINUS,
164 	STATICTEXT_SETTINGS_VIRTUALCHANNELS,
165 	CHECKBOX_SETTINGS_MULTICHN_RECORD,
166 	CHECKBOX_SETTINGS_MULTICHN_KEYJAZZ,
167 	CHECKBOX_SETTINGS_MULTICHN_EDIT,
168 	CHECKBOX_SETTINGS_MULTICHN_RECORDKEYOFF,
169 	CHECKBOX_SETTINGS_MULTICHN_RECORDNOTEDELAY,
170 
171 	// Page II
172 	CHECKBOX_SETTINGS_HEXCOUNT,
173 	CHECKBOX_SETTINGS_SHOWZEROEFFECT,
174 	CHECKBOX_SETTINGS_FULLSCREEN,
175 	LISTBOX_SETTINGS_RESOLUTIONS,
176 	BUTTON_RESOLUTIONS_CUSTOM,
177 	BUTTON_RESOLUTIONS_FULL,
178 	STATICTEXT_SETTINGS_MAGNIFY,
179 	RADIOGROUP_SETTINGS_MAGNIFY,
180 	LISTBOX_COLORS,
181 	SLIDER_COLOR_RED,
182 	SLIDER_COLOR_GREEN,
183 	SLIDER_COLOR_BLUE,
184 	BUTTON_COLOR,
185 	BUTTON_COLOR_PREDEF_STORE,
186 
187 	BUTTON_COLOR_EXPORT,
188 	BUTTON_COLOR_IMPORT,
189 
190 	BUTTON_COLOR_PREVIEW,
191 	BUTTON_COLOR_COPY,
192 	BUTTON_COLOR_PASTE,
193 	BUTTON_COLOR_DARKER,
194 	BUTTON_COLOR_BRIGHTER,
195 	BUTTON_COLOR_PREDEF_0,
196 	BUTTON_COLOR_PREDEF_1,
197 	BUTTON_COLOR_PREDEF_2,
198 	BUTTON_COLOR_PREDEF_3,
199 	BUTTON_COLOR_PREDEF_4,
200 	BUTTON_COLOR_PREDEF_5,
201 	BUTTON_COLOR_RESTORE,
202 	STATICTEXT_SPACING,
203 	SLIDER_SPACING,
204 	STATICTEXT_MUTEFADE,
205 	SLIDER_MUTEFADE,
206 
207 	STATICTEXT_HIGHLIGHTMODULO1,
208 	BUTTON_HIGHLIGHTMODULO1_PLUS,
209 	BUTTON_HIGHLIGHTMODULO1_MINUS,
210 	CHECKBOX_HIGHLIGHTMODULO1_FULLROW,
211 
212 	STATICTEXT_HIGHLIGHTMODULO2,
213 	BUTTON_HIGHLIGHTMODULO2_PLUS,
214 	BUTTON_HIGHLIGHTMODULO2_MINUS,
215 	CHECKBOX_HIGHLIGHTMODULO2_FULLROW,
216 
217 	// Page III
218 	RADIOGROUP_SETTINGS_PATTERNFONT,
219 	LISTBOX_SETTINGS_FONTFAMILIES,
220 	LISTBOX_SETTINGS_FONTENTRIES,
221 
222 	// PAGE VI
223 	CHECKBOX_SETTINGS_INSTRUMENTBACKTRACE,
224 	CHECKBOX_SETTINGS_WRAPCURSOR,
225 	CHECKBOX_SETTINGS_PROSPECTIVE,
226 	//CHECKBOX_SETTINGS_FOLLOWSONG,
227 	CHECKBOX_SETTINGS_TABTONOTE,
228 	CHECKBOX_SETTINGS_AUTORESIZE,
229 	CHECKBOX_SETTINGS_CLICKTOCURSOR,
230 	RADIOGROUP_SETTINGS_EDITMODE,
231 	RADIOGROUP_SETTINGS_SCROLLMODE,
232 
233 	CHECKBOX_SETTINGS_SAMPLEEDITORUNDO,
234 	CHECKBOX_SETTINGS_AUTOMIXDOWNSAMPLES,
235 	CHECKBOX_SETTINGS_INTERNALDISKBROWSER,
236 	CHECKBOX_SETTINGS_AUTOESTPLAYTIME,
237 	CHECKBOX_SETTINGS_SHOWSPLASH,
238 	CHECKBOX_SETTINGS_SCOPES,
239 
240 	STATICTEXT_SETTINGS_SCOPESAPPEARANCE,
241 	RADIOGROUP_SETTINGS_SCOPESAPPEARANCE,
242 
243 	CHECKBOX_SETTINGS_INVERTMWHEEL,
244 	CHECKBOX_SETTINGS_INVERTMWHEELZOOM,
245 
246 	// Page V (only on desktop version)
247 	RADIOGROUP_SETTINGS_STOPBACKGROUNDBEHAVIOUR,
248 	CHECKBOX_SETTINGS_TABSWITCHRESUMEPLAY,
249 	STATICTEXT_SETTINGS_TABSWITCHRESUMEPLAY,
250 	CHECKBOX_SETTINGS_LOADMODULEINNEWTAB,
251 
252 	PAGE_IO_1,
253 	PAGE_IO_2,
254 	PAGE_IO_3,
255     PAGE_IO_4,
256 
257 	PAGE_LAYOUT_1,
258 	PAGE_LAYOUT_2,
259 	PAGE_LAYOUT_3,
260 	PAGE_LAYOUT_4,
261 
262 	PAGE_FONTS_1,
263 	PAGE_FONTS_2,
264 	PAGE_FONTS_3,
265 
266 	PAGE_MISC_1,
267 	PAGE_MISC_2,
268 	PAGE_MISC_3,
269 	PAGE_MISC_4,
270 
271 	PAGE_TABS_1,
272 	PAGE_TABS_2,
273 	PAGE_TABS_3,
274 
275 	RESPONDMESSAGEBOX_CUSTOMRESOLUTION,
276 	RESPONDMESSAGEBOX_RESTOREPALETTES,
277 	RESPONDMESSAGEBOX_SELECTAUDIODRV,
278 	RESPONDMESSAGEBOX_SELECTRESAMPLER
279 };
280 
281 struct TScreenRes
282 {
283 	pp_int32 width, height;
284 	const char* name;
285 };
286 
287 #define NUMRESOLUTIONS	13
288 #define MINWIDTH		640
289 #define MINHEIGHT		480
290 
291 static TScreenRes resolutions[NUMRESOLUTIONS] =
292 {
293 	{640, 480, "640x480"},
294 	{720, 480, "720x480"},
295 	{800, 480, "800x480"},
296 	{800, 500, "800x500"},
297 	{800, 600, "800x600"},
298 	{1024, 768, "1024x768"},
299 	{1152, 864, "1152x864"},
300 	{1280, 768, "1280x768"},
301 	{1280, 800, "1280x800"},
302 	{1280, 854, "1280x854"},
303 	{1280, 1024, "1280x1024"},
304 	{1680, 1050, "1680x1050"},
305 	{-1, -1, "<Custom>"}
306 };
307 
308 // Class which responds to message box clicks
309 class DialogResponderSettings : public DialogResponder
310 {
311 private:
312 	SectionSettings& section;
313 
314 public:
DialogResponderSettings(SectionSettings & section)315 	DialogResponderSettings(SectionSettings& section) :
316 		section(section)
317 	{
318 	}
319 
ActionOkay(PPObject * sender)320 	virtual pp_int32 ActionOkay(PPObject* sender)
321 	{
322 		switch (reinterpret_cast<PPDialogBase*>(sender)->getID())
323 		{
324 			case RESPONDMESSAGEBOX_CUSTOMRESOLUTION:
325 			{
326 				section.storeCustomResolution();
327 				break;
328 			}
329 
330 			case RESPONDMESSAGEBOX_RESTOREPALETTES:
331 				section.restorePalettes();
332 				break;
333 
334 			case RESPONDMESSAGEBOX_SELECTAUDIODRV:
335 			{
336 				PPListBox* listBox = reinterpret_cast<DialogListBox*>(sender)->getListBox();
337 				section.storeAudioDriver(listBox->getItem(listBox->getSelectedIndex()));
338 				break;
339 			}
340 
341 			case RESPONDMESSAGEBOX_SELECTRESAMPLER:
342 			{
343 				PPListBox* listBox = reinterpret_cast<DialogListBox*>(sender)->getListBox();
344 				section.storeResampler(listBox->getSelectedIndex());
345 				break;
346 			}
347 		}
348 		return 0;
349 	}
350 };
351 
352 class TabPage : public EventListenerInterface
353 {
354 protected:
355 	pp_uint32 id;
356 	SectionSettings& sectionSettings;
357 	PPTransparentContainer* container;
358 	bool visible;
359 
360 	enum
361 	{
362 		PageWidth = 160,
363 		PageHeight = UPPERFRAMEHEIGHT
364 	};
365 
366 public:
TabPage(pp_uint32 id,SectionSettings & sectionSettings)367 	TabPage(pp_uint32 id, SectionSettings& sectionSettings) :
368 		id(id),
369 		sectionSettings(sectionSettings),
370 		container(NULL),
371 		visible(false)
372 	{
373 	}
374 
~TabPage()375 	virtual ~TabPage() {}
376 
getContainer() const377 	PPTransparentContainer* getContainer() const { return container; }
378 
getWidth()379 	static pp_int32 getWidth() { return PageWidth; }
getHeight()380 	static pp_int32 getHeight() { return PageHeight; }
381 
setVisible(bool visible)382 	void setVisible(bool visible) { this->visible = visible; }
isVisible() const383 	bool isVisible() const { return visible; }
384 
385 	virtual void init(PPScreen* screen) = 0;
386 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor) = 0;
387 
handleEvent(PPObject * sender,PPEvent * event)388 	virtual pp_int32 handleEvent(PPObject* sender, PPEvent* event)
389 	{
390 		return sectionSettings.handleEvent(sender, event);
391 	}
392 
getLocation()393 	PPPoint getLocation() { return container->getLocation(); }
394 
setLocation(const PPPoint & p)395 	void setLocation(const PPPoint& p)
396 	{
397 		if (container->getLocation().x != p.x || container->getLocation().y != p.y)
398 		{
399 			pp_int32 dx = p.x - container->getLocation().x;
400 			pp_int32 dy = p.y - container->getLocation().y;
401 			container->move(PPPoint(dx, dy));
402 		}
403 	}
404 };
405 
406 class TabPageIO_1 : public TabPage
407 {
408 public:
TabPageIO_1(pp_uint32 id,SectionSettings & sectionSettings)409 	TabPageIO_1(pp_uint32 id, SectionSettings& sectionSettings) :
410 		TabPage(id, sectionSettings)
411 	{
412 	}
413 
init(PPScreen * screen)414 	virtual void init(PPScreen* screen)
415 	{
416 		pp_int32 x = 0;
417 		pp_int32 y = 0;
418 
419 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
420 
421 		pp_int32 y2 = y;
422 
423 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x + 4, y2 + 4), "Driver:", true));
424 
425 		PPButton* button = new PPButton(BUTTON_SETTINGS_CHOOSEDRIVER, screen, this, PPPoint(x + 4 + 7*8 + 4, y2 + 3), PPSize(90, 11));
426 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
427 		button->setText("Select Driver" PPSTR_PERIODS);
428 		container->addControl(button);
429 
430 		y2+=4;
431 
432 		PPStaticText* text = new PPStaticText(0, NULL, NULL, PPPoint(x + 4, y2 + 2 + 11), "Buffer:", true);
433 		//text->setFont(PPFont::getFont(PPFont::FONT_TINY));
434 		container->addControl(text);
435 		container->addControl(new PPStaticText(STATICTEXT_SETTINGS_BUFFERSIZE, NULL, NULL, PPPoint(x + 4 + 7*8, y2 + 2 + 11), "000ms(xx)", false));
436 
437 		PPSlider* slider = new PPSlider(SLIDER_SETTINGS_BUFFERSIZE, screen, this, PPPoint(x + 4, y2 + 2 + 11*2-1), 151, true);
438 		slider->setMaxValue(511);
439 		slider->setBarSize(8192);
440 		container->addControl(slider);
441 
442 		y2++;
443 
444 		PPCheckBox* checkBox = new PPCheckBox(CHECKBOX_SETTINGS_FORCEPOWER2BUFF, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 + 2 + 11 * 3 - 1));
445 		container->addControl(checkBox);
446 		container->addControl(new PPCheckBoxLabel(STATICTEXT_SETTINGS_FORCEPOWER2BUFF, NULL, this, PPPoint(x + 4, y2 + 2 + 11*3), "Force 2^n sizes:", checkBox, true));
447 
448 		y2+=12;
449 
450 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x + 4, y2 + 2 + 11*3), "Mixervol:", true));
451 		container->addControl(new PPStaticText(STATICTEXT_SETTINGS_MIXERVOL, NULL, NULL, PPPoint(x + 4 + 8*9, y2 + 2 + 11*3), "100%", false));
452 
453 		slider = new PPSlider(SLIDER_SETTINGS_MIXERVOL, screen, this, PPPoint(x + 4, y2 + 2 + 11*4-1), 151, true);
454 		slider->setMaxValue(256);
455 		slider->setBarSize(8192);
456 		container->addControl(slider);
457 
458 		y2-=1;
459 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x + 4, y2 + 2 + 11*5 + 4), "Amp:", true));
460 
461 		PPRadioGroup* radioGroup = new PPRadioGroup(RADIOGROUP_SETTINGS_AMPLIFY, screen, this, PPPoint(x + 2 + 5*8, y2 + 2 + 11*5 + 1), PPSize(120, 16));
462 		radioGroup->setColor(TrackerConfig::colorThemeMain);
463 		radioGroup->setFont(PPFont::getFont(PPFont::FONT_TINY));
464 
465 		radioGroup->setHorizontal(true);
466 		radioGroup->addItem("25%");
467 		radioGroup->addItem("50%");
468 		radioGroup->addItem("100%");
469 
470 		container->addControl(radioGroup);
471 
472 		y2 += 2 + 11*7 - 4;
473 
474 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x + 4, y2), "Resampling:", true));
475 		button = new PPButton(BUTTON_SETTINGS_RESAMPLING, screen, this, PPPoint(x + 4 + 11*8 + 4, y2-2), PPSize(6*9 + 4, 11));
476 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
477 		button->setText("Select" PPSTR_PERIODS);
478 		container->addControl(button);
479 
480 		y2+=12;
481 
482 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_RAMPING, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 - 1));
483 		container->addControl(checkBox);
484 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x + 4, y2), "Volume ramping:", checkBox, true));
485 
486 		//container->addControl(new PPSeperator(0, screen, PPPoint(x + 158, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
487 	}
488 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)489 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
490 	{
491 		PPStaticText* text = static_cast<PPStaticText*>(container->getControlByID(STATICTEXT_SETTINGS_BUFFERSIZE));
492 		PPSlider* slider = static_cast<PPSlider*>(container->getControlByID(SLIDER_SETTINGS_BUFFERSIZE));
493 
494 		char buffer[100];
495 		char buffer2[100];
496 
497 		// buffersize
498 		bool forcePowerOfTwo = settingsDatabase->restore("FORCEPOWEROFTWOBUFFERSIZE")->getBoolValue();
499 		pp_int32 v = settingsDatabase->restore("BUFFERSIZE")->getIntValue();
500 		pp_int32 v2 = v;
501 
502 		if (forcePowerOfTwo)
503 			v = PlayerMaster::roundToNearestPowerOfTwo(v);
504 
505 		float fv = PlayerMaster::convertBufferSizeToMillis(settingsDatabase->restore("MIXERFREQ")->getIntValue(),
506 														   v);
507 
508 		pp_int32 fixed = (pp_int32)fv;
509 		pp_int32 decimal = (pp_int32)(fv*10.0f) % 10;
510 		if (v >= 1000)
511 		{
512 			if (fixed >= 100)
513 			{
514 				if (fixed >= 1000)
515 					sprintf(buffer, "%i.%is(%i.%ik)", fixed / 1000, (fixed / 100) % 10, v / 1000, (v / 100) % 10);
516 				else
517 					sprintf(buffer, "%ims(%i.%ik)", fixed, v / 1000, (v / 100) % 10);
518 			}
519 			else
520 				sprintf(buffer, "%i.%ims(%i.%ik)", fixed, decimal, v / 1000, (v / 100) % 10);
521 		}
522 		else
523 		{
524 			if (fixed >= 1000)
525 				sprintf(buffer, "%i.%is(%i)", fixed / 1000, (fixed / 100) % 10, v);
526 			else
527 				sprintf(buffer, "%i.%ims(%i)", fixed, decimal, v);
528 		}
529 
530 		if (strlen(buffer) < 9)
531 		{
532 			memset(buffer2, 32, sizeof(buffer2));
533 			strcpy(buffer2 + 9-strlen(buffer), buffer);
534 			strcpy(buffer, buffer2);
535 		}
536 
537 		text->setText(buffer);
538 
539 		slider->setCurrentValue((v2 >> 5) - 1);
540 
541 		// force 2^n buffer size
542 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_FORCEPOWER2BUFF))->checkIt(forcePowerOfTwo);
543 
544 		// mixervolume
545 		text = static_cast<PPStaticText*>(container->getControlByID(STATICTEXT_SETTINGS_MIXERVOL));
546 		slider = static_cast<PPSlider*>(container->getControlByID(SLIDER_SETTINGS_MIXERVOL));
547 
548 		v = settingsDatabase->restore("MIXERVOLUME")->getIntValue();
549 
550 		sprintf(buffer, "%i%%", (v*100)/256);
551 
552 		if (strlen(buffer) < 4)
553 		{
554 			memset(buffer2, 32, sizeof(buffer2));
555 			strcpy(buffer2 + 4-strlen(buffer), buffer);
556 			strcpy(buffer, buffer2);
557 		}
558 
559 		text->setText(buffer);
560 
561 		slider->setCurrentValue(v);
562 
563 		// amplify
564 		v = settingsDatabase->restore("MIXERSHIFT")->getIntValue();
565 
566 		static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_AMPLIFY))->setChoice(v);
567 
568 		// checkboxes
569 		v = settingsDatabase->restore("RAMPING")->getIntValue();
570 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_RAMPING))->checkIt(v!=0);
571 	}
572 
573 };
574 
575 class TabPageIO_2 : public TabPage
576 {
577 public:
TabPageIO_2(pp_uint32 id,SectionSettings & sectionSettings)578 	TabPageIO_2(pp_uint32 id, SectionSettings& sectionSettings) :
579 		TabPage(id, sectionSettings)
580 	{
581 	}
582 
init(PPScreen * screen)583 	virtual void init(PPScreen* screen)
584 	{
585 		pp_int32 x = 0;
586 		pp_int32 y = 0;
587 
588 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
589 
590 		// frequency table
591 		pp_int32 x2 = x;
592 		pp_int32 y2 = y;
593 
594 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Mixer Resolution", true, true));
595 
596 		pp_int32 j;
597 		PPRadioGroup* radioGroup = new PPRadioGroup(RADIOGROUP_SETTINGS_MIXFREQ, screen, this, PPPoint(x2, y2+2+11), PPSize(160, TrackerConfig::numMixFrequencies*14));
598 		radioGroup->setColor(TrackerConfig::colorThemeMain);
599 
600 		for (j = 0; j < TrackerConfig::numMixFrequencies; j++)
601 		{
602 			char buffer[32];
603 			sprintf(buffer, "%i Hz", TrackerConfig::mixFrequencies[j]);
604 			radioGroup->addItem(buffer);
605 		}
606 
607 		container->addControl(radioGroup);
608 
609 		y2+=j*14+14;
610 
611 		container->addControl(new PPSeperator(0, screen, PPPoint(x2, y2), 158, TrackerConfig::colorThemeMain, true));
612 
613 		y2+=4;
614 
615 		// module frequencies
616 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Frequency Table", true, true));
617 
618 		radioGroup = new PPRadioGroup(RADIOGROUP_SETTINGS_FREQTAB, screen, this, PPPoint(x2, y2+2+11), PPSize(160, 30));
619 		radioGroup->setColor(TrackerConfig::colorThemeMain);
620 
621 		radioGroup->addItem("Amiga frequencies");
622 		radioGroup->addItem("Linear frequencies");
623 
624 		container->addControl(radioGroup);
625 
626 		//container->addControl(new PPSeperator(0, screen, PPPoint(x2 + 158, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
627 	}
628 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)629 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
630 	{
631 		// mixer resolution
632 		pp_int32 v = settingsDatabase->restore("MIXERFREQ")->getIntValue();
633 
634 		pp_int32 i;
635 		for (i = 0; i < TrackerConfig::numMixFrequencies; i++)
636 			if (v == TrackerConfig::mixFrequencies[i])
637 			{
638 				static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_MIXFREQ))->setChoice(i);
639 				break;
640 			}
641 
642 		// frequency table
643 		v = moduleEditor.getFrequency();
644 
645 		static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_FREQTAB))->setChoice(v);
646 	}
647 
648 };
649 
650 class TabPageIO_3 : public TabPage
651 {
652 public:
TabPageIO_3(pp_uint32 id,SectionSettings & sectionSettings)653 	TabPageIO_3(pp_uint32 id, SectionSettings& sectionSettings) :
654 		TabPage(id, sectionSettings)
655 	{
656 	}
657 
init(PPScreen * screen)658 	virtual void init(PPScreen* screen)
659 	{
660 		pp_int32 x = 0;
661 		pp_int32 y = 0;
662 
663 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
664 
665 		pp_int32 y2 = y;
666 
667 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x + 2, y2 + 2), "Instrument Playback", true, true));
668 
669 		y2+=15;
670 		PPCheckBox* checkBox = new PPCheckBox(CHECKBOX_SETTINGS_VIRTUALCHANNELS, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 - 1));
671 		container->addControl(checkBox);
672 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x + 4, y2), "Jam channels:", checkBox, true));
673 
674 		y2+=12;
675 		container->addControl(new PPStaticText(STATICTEXT_SETTINGS_VIRTUALCHANNELS, NULL, NULL, PPPoint(x + 4, y2), "Use xx channels", false));
676 
677 		PPButton* button = new PPButton(BUTTON_SETTINGS_VIRTUALCHANNELS_PLUS, screen, this, PPPoint(x + 4 + 15*8 + 4, y2), PPSize(12, 9));
678 		button->setText(TrackerConfig::stringButtonPlus);
679 		container->addControl(button);
680 
681 		button = new PPButton(BUTTON_SETTINGS_VIRTUALCHANNELS_MINUS, screen, this, PPPoint(x + 4 + 15*8 + 4 + 13, y2), PPSize(13, 9));
682 		button->setText(TrackerConfig::stringButtonMinus);
683 
684 		container->addControl(button);
685 
686 		y2+=14;
687 
688 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x + 2, y2 + 2), "Multichannel", true, true));
689 
690 		y2+=15;
691 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_MULTICHN_RECORD, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 - 1));
692 		container->addControl(checkBox);
693 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x + 4, y2), "Recording:", checkBox, true));
694 
695 		y2+=12;
696 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_MULTICHN_KEYJAZZ, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 - 1));
697 		container->addControl(checkBox);
698 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x + 4, y2), """Keyjazzing"":", checkBox, true));
699 
700 		y2+=12;
701 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_MULTICHN_EDIT, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 - 1));
702 		container->addControl(checkBox);
703 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x + 4, y2), "Editing:", checkBox, true));
704 
705 		y2+=12;
706 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_MULTICHN_RECORDKEYOFF, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 - 1));
707 		container->addControl(checkBox);
708 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x + 4, y2), "Record key off:", checkBox, true));
709 
710 		y2+=12;
711 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_MULTICHN_RECORDNOTEDELAY, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 - 1));
712 		container->addControl(checkBox);
713 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x + 4, y2), "Rec. note delays:", checkBox, true));
714 
715 		//container->addControl(new PPSeperator(0, screen, PPPoint(x + 158, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
716 	}
717 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)718 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
719 	{
720 		PPStaticText* text = static_cast<PPStaticText*>(container->getControlByID(STATICTEXT_SETTINGS_VIRTUALCHANNELS));
721 
722 		char buffer[100];
723 
724 		// buffersize
725 		pp_int32 v = settingsDatabase->restore("VIRTUALCHANNELS")->getIntValue();
726 
727 		sprintf(buffer, "Use %02i", v);
728 
729 		text->setText(buffer);
730 
731 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_VIRTUALCHANNELS))->checkIt(v>0);
732 
733 		v = settingsDatabase->restore("MULTICHN_RECORD")->getIntValue();
734 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_MULTICHN_RECORD))->checkIt(v!=0);
735 		v = settingsDatabase->restore("MULTICHN_KEYJAZZ")->getIntValue();
736 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_MULTICHN_KEYJAZZ))->checkIt(v!=0);
737 		v = settingsDatabase->restore("MULTICHN_EDIT")->getIntValue();
738 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_MULTICHN_EDIT))->checkIt(v!=0);
739 		v = settingsDatabase->restore("MULTICHN_RECORDKEYOFF")->getIntValue();
740 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_MULTICHN_RECORDKEYOFF))->checkIt(v!=0);
741 		v = settingsDatabase->restore("MULTICHN_RECORDNOTEDELAY")->getIntValue();
742 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_MULTICHN_RECORDNOTEDELAY))->checkIt(v!=0);
743 	}
744 
745 };
746 
747 class TabPageIO_4 : public TabPage
748 {
749 public:
TabPageIO_4(pp_uint32 id,SectionSettings & sectionSettings)750     TabPageIO_4(pp_uint32 id, SectionSettings& sectionSettings) :
751     TabPage(id, sectionSettings)
752     {
753     }
754 
init(PPScreen * screen)755     virtual void init(PPScreen* screen)
756     {
757         pp_int32 x = 0;
758         pp_int32 y = 0;
759 
760         container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
761 
762         pp_int32 x2 = x;
763         pp_int32 y2 = y;
764 
765         container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "XM channel limit", true, true));
766 
767         PPRadioGroup* radioGroup = new PPRadioGroup(RADIOGROUP_SETTINGS_XMCHANNELLIMIT, screen, this, PPPoint(x2, y2+2+11), PPSize(160, 3*14));
768         radioGroup->setColor(TrackerConfig::colorThemeMain);
769         radioGroup->addItem("32");
770         radioGroup->addItem("64");
771         radioGroup->addItem("128");
772 
773         container->addControl(radioGroup);
774     }
775 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)776     virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
777     {
778         // mixer resolution
779         pp_int32 v = settingsDatabase->restore("XMCHANNELLIMIT")->getIntValue();
780 
781         switch (v) {
782             case 32:
783                 static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_XMCHANNELLIMIT))->setChoice(0);
784                 break;
785             case 64:
786                 static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_XMCHANNELLIMIT))->setChoice(1);
787                 break;
788             case 128:
789                 static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_XMCHANNELLIMIT))->setChoice(2);
790                 break;
791 
792         }
793     }
794 
795 };
796 
797 class TabPageLayout_1 : public TabPage
798 {
799 public:
TabPageLayout_1(pp_uint32 id,SectionSettings & sectionSettings)800 	TabPageLayout_1(pp_uint32 id, SectionSettings& sectionSettings) :
801 		TabPage(id, sectionSettings)
802 	{
803 	}
804 
init(PPScreen * screen)805 	virtual void init(PPScreen* screen)
806 	{
807 		pp_int32 x = 0;
808 		pp_int32 y = 0;
809 
810 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
811 
812 		pp_int32 x2 = x;
813 		pp_int32 y2 = y;
814 
815 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x + 2, y2 + 2), "Pattern Editor", true, true));
816 
817 		y2+=14;
818 
819 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2), "Spacing:", true));
820 		container->addControl(new PPStaticText(STATICTEXT_SPACING, screen, this, PPPoint(x2 + 9*8, y2), "0px"));
821 
822 		PPSlider* slider = new PPSlider(SLIDER_SPACING, screen, this, PPPoint(x2 + 13*8 + 2, y2-1), 49, true);
823 		slider->setMaxValue(31);
824 		slider->setBarSize(16384);
825 		container->addControl(slider);
826 
827 		y2+=11;
828 		PPCheckBox* checkBox = new PPCheckBox(CHECKBOX_SETTINGS_HEXCOUNT, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 - 1));
829 		container->addControl(checkBox);
830 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x + 2, y2), "Hex count:", checkBox, true));
831 
832 		y2+=11;
833 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_SHOWZEROEFFECT, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 - 1));
834 		container->addControl(checkBox);
835 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x + 2, y2), "Show zero effect:", checkBox, true));
836 
837 		y2+=11;
838 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_PROSPECTIVE, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 - 1));
839 		container->addControl(checkBox);
840 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Prospective:", checkBox, true));
841 
842 		y2+=11;
843 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2), "Muting opacity:", true));
844 
845 		y2+=11;
846 		container->addControl(new PPStaticText(STATICTEXT_MUTEFADE, screen, this, PPPoint(x2 + 4, y2), "100%"));
847 
848 		slider = new PPSlider(SLIDER_MUTEFADE, screen, this, PPPoint(x2 + 4 + 8*4 + 4, y2-1), 113, true);
849 		slider->setMaxValue(100);
850 		slider->setBarSize(8192);
851 		container->addControl(slider);
852 
853 		y2+=12;
854 		PPStaticText* staticText = new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2), "Row highlight spacing:", true);
855 		staticText->setFont(PPFont::getFont(PPFont::FONT_TINY));
856 		container->addControl(staticText);
857 
858 		y2+=11;
859 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2), "1st:", true));
860 		container->addControl(new PPStaticText(STATICTEXT_HIGHLIGHTMODULO1, NULL, NULL, PPPoint(x2 + 2 + 4*8 + 2, y2), "xx"));
861 
862 		PPButton* button = new PPButton(BUTTON_HIGHLIGHTMODULO1_PLUS, screen, this, PPPoint(x + 2 + 7*8, y2-1), PPSize(12, 9));
863 		button->setText(TrackerConfig::stringButtonPlus);
864 		container->addControl(button);
865 		button = new PPButton(BUTTON_HIGHLIGHTMODULO1_MINUS, screen, this, PPPoint(x + 2 + 7*8 + 13, y2-1), PPSize(13, 9));
866 		button->setText(TrackerConfig::stringButtonMinus);
867 		container->addControl(button);
868 		checkBox = new PPCheckBox(CHECKBOX_HIGHLIGHTMODULO1_FULLROW, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 - 1));
869 		container->addControl(checkBox);
870 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x + 2 + 7*8 + 13 + 20, y2), "Full:", checkBox, true));
871 
872 		y2+=11;
873 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2), "2nd:", true));
874 		container->addControl(new PPStaticText(STATICTEXT_HIGHLIGHTMODULO2, NULL, NULL, PPPoint(x2 + 2 + 4*8 + 2, y2), "xx"));
875 		button = new PPButton(BUTTON_HIGHLIGHTMODULO2_PLUS, screen, this, PPPoint(x + 2 + 7*8, y2-1), PPSize(12, 9));
876 		button->setText(TrackerConfig::stringButtonPlus);
877 		container->addControl(button);
878 		button = new PPButton(BUTTON_HIGHLIGHTMODULO2_MINUS, screen, this, PPPoint(x + 2 + 7*8 + 13, y2-1), PPSize(13, 9));
879 		button->setText(TrackerConfig::stringButtonMinus);
880 		container->addControl(button);
881 		checkBox = new PPCheckBox(CHECKBOX_HIGHLIGHTMODULO2_FULLROW, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 - 1));
882 		container->addControl(checkBox);
883 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x + 2 + 7 * 8 + 13 + 20, y2), "Full:", checkBox, true));
884 
885 		// vertical separator
886 		//container->addControl(new PPSeperator(0, screen, PPPoint(x2 + 158, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
887 	}
888 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)889 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
890 	{
891 		// spacing slider
892 		PPStaticText* text = static_cast<PPStaticText*>(container->getControlByID(STATICTEXT_SPACING));
893 		PPSlider* slider = static_cast<PPSlider*>(container->getControlByID(SLIDER_SPACING));
894 
895 		pp_int32 v = settingsDatabase->restore("SPACING")->getIntValue();
896 		char buffer[100], buffer2[100];
897 		sprintf(buffer,"%ipx", v);
898 		text->setText(buffer);
899 		slider->setCurrentValue(v);
900 
901 		// mute fade strength slider
902 		text = static_cast<PPStaticText*>(container->getControlByID(STATICTEXT_MUTEFADE));
903 		slider = static_cast<PPSlider*>(container->getControlByID(SLIDER_MUTEFADE));
904 
905 		v = settingsDatabase->restore("MUTEFADE")->getIntValue();
906 		sprintf(buffer, "%i%%", v);
907 		// right align
908 		if (strlen(buffer) < 4)
909 		{
910 			memset(buffer2, 32, sizeof(buffer2));
911 			strcpy(buffer2 + 4-strlen(buffer), buffer);
912 			strcpy(buffer, buffer2);
913 		}
914 		text->setText(buffer);
915 		slider->setCurrentValue(v);
916 
917 		// update primary pattern row highlight
918 		text = static_cast<PPStaticText*>(container->getControlByID(STATICTEXT_HIGHLIGHTMODULO1));
919 		v = settingsDatabase->restore("HIGHLIGHTMODULO1")->getIntValue();
920 		sprintf(buffer, "%02i ", v);
921 		text->setText(buffer);
922 
923 		// update secondary pattern row highlight
924 		text = static_cast<PPStaticText*>(container->getControlByID(STATICTEXT_HIGHLIGHTMODULO2));
925 		v = settingsDatabase->restore("HIGHLIGHTMODULO2")->getIntValue();
926 		sprintf(buffer, "%02i ", v);
927 		text->setText(buffer);
928 
929 		v = settingsDatabase->restore("HIGHLIGHTROW1")->getIntValue();
930 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_HIGHLIGHTMODULO1_FULLROW))->checkIt(v!=0);
931 
932 		v = settingsDatabase->restore("HIGHLIGHTROW2")->getIntValue();
933 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_HIGHLIGHTMODULO2_FULLROW))->checkIt(v!=0);
934 
935 		v = settingsDatabase->restore("HEXCOUNT")->getIntValue();
936 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_HEXCOUNT))->checkIt(v!=0);
937 
938 		v = settingsDatabase->restore("SHOWZEROEFFECT")->getIntValue();
939 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_SHOWZEROEFFECT))->checkIt(v!=0);
940 
941 		v = settingsDatabase->restore("PROSPECTIVE")->getIntValue();
942 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_PROSPECTIVE))->checkIt(v!=0);
943 	}
944 
945 };
946 
947 class TabPageLayout_2 : public TabPage
948 {
949 public:
TabPageLayout_2(pp_uint32 id,SectionSettings & sectionSettings)950 	TabPageLayout_2(pp_uint32 id, SectionSettings& sectionSettings) :
951 		TabPage(id, sectionSettings)
952 	{
953 	}
954 
init(PPScreen * screen)955 	virtual void init(PPScreen* screen)
956 	{
957 		pp_int32 i = 0;
958 
959 		pp_int32 x = 0;
960 		pp_int32 y = 0;
961 
962 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
963 
964 		pp_int32 x2 = x;
965 
966 		// Colors
967 		pp_int32 y2 = y;
968 
969 		pp_int32 lbheight = container->getSize().height - (y2 - y) - 66;
970 
971 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Colors", true, true));
972 
973 		PPButton* button = new PPButton(BUTTON_COLOR_IMPORT, screen, this, PPPoint(x2 + 54, y2 + 2), PPSize(9, 9));
974 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
975 		button->setText("I");
976 		container->addControl(button);
977 
978 		button = new PPButton(BUTTON_COLOR_EXPORT, screen, this, PPPoint(x2 + 54 + 10, y2 + 2), PPSize(9, 9));
979 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
980 		button->setText("E");
981 		container->addControl(button);
982 
983 		button = new PPButton(BUTTON_COLOR_PREVIEW, screen, this, PPPoint(x2 + 115, y2 + 2), PPSize(39, 9));
984 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
985 		button->setText("Preview");
986 		container->addControl(button);
987 
988 		button = new PPButton(BUTTON_COLOR_RESTORE, screen, this, PPPoint(x2 + 115 - 40, y2 + 2), PPSize(39, 9));
989 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
990 		button->setText("Restore");
991 		container->addControl(button);
992 
993 		y2+=1+11;
994 
995 		sectionSettings.listBoxColors = new PPListBox(LISTBOX_COLORS, screen, this, PPPoint(x2+2, y2+2), PPSize(153,lbheight), true, false, true, true);
996 		sectionSettings.listBoxColors->setBorderColor(TrackerConfig::colorThemeMain);
997 		sectionSettings.listBoxColors->setKeepsFocus(false);
998 		sectionSettings.listBoxColors->setShowFocus(false);
999 
1000 		for (i = 0; i < GlobalColorConfig::ColorLast; i++)
1001 		{
1002 			pp_int32 j = sectionSettings.colorMapping[i];
1003 			if (sectionSettings.colorDescriptors[j].readableDecription == NULL)
1004 				break;
1005 
1006 			sectionSettings.listBoxColors->addItem(sectionSettings.colorDescriptors[j].readableDecription);
1007 		}
1008 
1009 #ifdef __LOWRES__
1010 		y2+=sectionSettings.listBoxColors->getSize().height + 2;
1011 #else
1012 		y2+=sectionSettings.listBoxColors->getSize().height + 4;
1013 #endif
1014 		container->addControl(sectionSettings.listBoxColors);
1015 
1016 		button = new PPColPrevButton(BUTTON_COLOR, screen, this, PPPoint(x2 + 88, y2 + 1), PPSize(31, 34));
1017 		button->setFlat(true);
1018 		button->setColor(sectionSettings.currentColor);
1019 		container->addControl(button);
1020 
1021 		button = new PPButton(BUTTON_COLOR_COPY, screen, this, PPPoint(x2 + 88 + 32 + 2, y2 + 2), PPSize(5*6+2, 9));
1022 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
1023 		button->setText("Copy");
1024 		container->addControl(button);
1025 
1026 		button = new PPButton(BUTTON_COLOR_PASTE, screen, this, PPPoint(x2 + 88 + 32 + 2, y2 + 2+10), PPSize(5*6+2, 9));
1027 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
1028 		button->setText("Paste");
1029 		container->addControl(button);
1030 
1031 		button = new PPButton(BUTTON_COLOR_DARKER, screen, this, PPPoint(x2 + 88 + 32 + 2, y2 + 2+23), PPSize(16, 9));
1032 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
1033 		button->setText("<<");
1034 		container->addControl(button);
1035 
1036 		button = new PPButton(BUTTON_COLOR_BRIGHTER, screen, this, PPPoint(x2 + 88 + 32 + 2 + 17, y2 + 2+23), PPSize(15, 9));
1037 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
1038 		button->setText(">>");
1039 		container->addControl(button);
1040 
1041 		// Red slider
1042 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "R", true));
1043 		PPSlider* slider = new PPSlider(SLIDER_COLOR_RED, screen, this, PPPoint(x2 + 2 + 1*8 + 2, y2 + 1), 74, true);
1044 		slider->setMaxValue(255);
1045 		slider->setBarSize(16384);
1046 		container->addControl(slider);
1047 
1048 		y2+=12;
1049 
1050 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "G", true));
1051 		slider = new PPSlider(SLIDER_COLOR_GREEN, screen, this, PPPoint(x2 + 2 + 1*8 + 2, y2 + 1), 74, true);
1052 		slider->setMaxValue(255);
1053 		slider->setBarSize(16384);
1054 		container->addControl(slider);
1055 
1056 		y2+=12;
1057 
1058 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "B", true));
1059 		slider = new PPSlider(SLIDER_COLOR_BLUE, screen, this, PPPoint(x2 + 2 + 1*8 + 2, y2 + 1), 74, true);
1060 		slider->setMaxValue(255);
1061 		slider->setBarSize(16384);
1062 		container->addControl(slider);
1063 
1064 		y2+=12;
1065 
1066 		// predefs
1067 		pp_int32 px = x2 + 2;
1068 
1069 		PPStaticText* staticText = new PPStaticText(0, NULL, NULL, PPPoint(px, y2 + 3), "Predef:", true);
1070 		container->addControl(staticText);
1071 
1072 		px+=7*8+2;
1073 
1074 		// pre-defined envelopes
1075 		for (i = 0; i < TrackerConfig::numPredefinedColorPalettes; i++)
1076 		{
1077 			button = new PPButton(BUTTON_COLOR_PREDEF_0+i, screen, this, PPPoint(px, y2 + 2), PPSize(9, 9));
1078 			button->setFont(PPFont::getFont(PPFont::FONT_TINY));
1079 			button->setText((char)('A'+i));
1080 			container->addControl(button);
1081 			px+=button->getSize().width+1;
1082 		}
1083 		px+=2;
1084 
1085 		button = new PPButton(BUTTON_COLOR_PREDEF_STORE, screen, this, PPPoint(px, y2 + 2), PPSize(5*6+2, 9), true, true, false);
1086 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
1087 		button->setText("Store");
1088 		container->addControl(button);
1089 
1090 		//container->addControl(new PPSeperator(0, screen, PPPoint(x2 + 158, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
1091 	}
1092 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)1093 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
1094 	{
1095 		// Update color from sliders
1096 		PPSlider* slider = static_cast<PPSlider*>(container->getControlByID(SLIDER_COLOR_RED));
1097 		slider->setCurrentValue(sectionSettings.currentColor.r);
1098 		slider = static_cast<PPSlider*>(container->getControlByID(SLIDER_COLOR_GREEN));
1099 		slider->setCurrentValue(sectionSettings.currentColor.g);
1100 		slider = static_cast<PPSlider*>(container->getControlByID(SLIDER_COLOR_BLUE));
1101 		slider->setCurrentValue(sectionSettings.currentColor.b);
1102 
1103 		static_cast<PPButton*>(container->getControlByID(BUTTON_COLOR_PASTE))->setClickable(sectionSettings.colorCopy != NULL);
1104 	}
1105 
1106 };
1107 
1108 class TabPageLayout_3 : public TabPage
1109 {
1110 public:
TabPageLayout_3(pp_uint32 id,SectionSettings & sectionSettings)1111 	TabPageLayout_3(pp_uint32 id, SectionSettings& sectionSettings) :
1112 		TabPage(id, sectionSettings)
1113 	{
1114 	}
1115 
init(PPScreen * screen)1116 	virtual void init(PPScreen* screen)
1117 	{
1118 		pp_int32 i;
1119 
1120 		pp_int32 x = 0;
1121 		pp_int32 y = 0;
1122 
1123 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
1124 
1125 		pp_int32 x2 = x;
1126 		pp_int32 y2 = y;
1127 
1128 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Resolutions", true, true));
1129 
1130 		PPButton* button = new PPButton(BUTTON_RESOLUTIONS_CUSTOM, screen, this, PPPoint(x2 + 92, y2 + 2), PPSize(37, 9));
1131 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
1132 		button->setText("Custom");
1133 		container->addControl(button);
1134 
1135 		button = new PPButton(BUTTON_RESOLUTIONS_FULL, screen, this, PPPoint(x2 + 92 + 37 + 2, y2 + 2), PPSize(23, 9));
1136 		button->setFont(PPFont::getFont(PPFont::FONT_TINY));
1137 		button->setText("Full");
1138 		container->addControl(button);
1139 
1140 		y2+=12;
1141 
1142 		pp_int32 lbheight = container->getSize().height - (y2 - y) - (18);
1143 		PPListBox* listBox;
1144 		listBox = new PPListBox(LISTBOX_SETTINGS_RESOLUTIONS, screen, this, PPPoint(x2+2, y2+2), PPSize(153,lbheight), true, false, true, true);
1145 		listBox->setBorderColor(TrackerConfig::colorThemeMain);
1146 		listBox->setKeepsFocus(false);
1147 		listBox->setShowFocus(false);
1148 
1149 		for (i = 0; i < NUMRESOLUTIONS; i++)
1150 			listBox->addItem(resolutions[i].name);
1151 		container->addControl(listBox);
1152 
1153 
1154 		y2+=lbheight + 6;
1155 
1156 		container->addControl(new PPStaticText(STATICTEXT_SETTINGS_MAGNIFY, NULL, NULL, PPPoint(x2 + 2, y2), "Scale:", true));
1157 
1158 		PPRadioGroup* radioGroup = new PPRadioGroup(RADIOGROUP_SETTINGS_MAGNIFY, screen, this, PPPoint(x2 + 2 + 7*8, y2 - 4), PPSize(120, 16));
1159 		radioGroup->setColor(TrackerConfig::colorThemeMain);
1160 		radioGroup->setFont(PPFont::getFont(PPFont::FONT_TINY));
1161 
1162 		radioGroup->setHorizontal(true);
1163 		radioGroup->addItem("x1");
1164 		radioGroup->addItem("x2");
1165 		radioGroup->addItem("x4");
1166 		radioGroup->addItem("x8");
1167 
1168 		container->addControl(radioGroup);
1169 	}
1170 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)1171 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
1172 	{
1173 		pp_int32 width = settingsDatabase->restore("XRESOLUTION")->getIntValue();
1174 		pp_int32 height = settingsDatabase->restore("YRESOLUTION")->getIntValue();
1175 
1176 		bool found = false;
1177 		for (pp_int32 i = 0; i < NUMRESOLUTIONS; i++)
1178 		{
1179 			if (resolutions[i].width == width && resolutions[i].height == height)
1180 			{
1181 				static_cast<PPListBox*>(container->getControlByID(LISTBOX_SETTINGS_RESOLUTIONS))->setSelectedIndex(i, false, false);
1182 				found = true;
1183 				break;
1184 			}
1185 		}
1186 
1187 		if (!found)
1188 			static_cast<PPListBox*>(container->getControlByID(LISTBOX_SETTINGS_RESOLUTIONS))->setSelectedIndex(NUMRESOLUTIONS-1, false, false);
1189 
1190 		static_cast<PPStaticText*>(container->getControlByID(STATICTEXT_SETTINGS_MAGNIFY))->enable(screen->supportsScaling());
1191 		static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_MAGNIFY))->enable(screen->supportsScaling());
1192 
1193 		pp_int32 screenScaleFactor = settingsDatabase->restore("SCREENSCALEFACTOR")->getIntValue();
1194 		pp_int32 index = 0;
1195 		switch (screenScaleFactor)
1196 		{
1197 			case 2:
1198 				index = 1;
1199 				break;
1200 			case 4:
1201 				index = 2;
1202 				break;
1203 			case 8:
1204 				index = 3;
1205 				break;
1206 		}
1207 
1208 		static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_MAGNIFY))->setChoice(index);
1209 	}
1210 
1211 };
1212 
1213 class TabPageLayout_4 : public TabPage
1214 {
1215 public:
TabPageLayout_4(pp_uint32 id,SectionSettings & sectionSettings)1216 	TabPageLayout_4(pp_uint32 id, SectionSettings& sectionSettings) :
1217 		TabPage(id, sectionSettings)
1218 	{
1219 	}
1220 
init(PPScreen * screen)1221 	virtual void init(PPScreen* screen)
1222 	{
1223 		pp_int32 x = 0;
1224 		pp_int32 y = 0;
1225 
1226 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
1227 
1228 		pp_int32 x2 = x;
1229 		pp_int32 y2 = y;
1230 
1231 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Global", true, true));
1232 
1233 		y2+=4+11;
1234 		PPCheckBox* checkBox = new PPCheckBox(CHECKBOX_SETTINGS_FULLSCREEN, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 1));
1235 		container->addControl(checkBox);
1236 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 4, y2), "Fullscreen:", checkBox, true));
1237 	}
1238 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)1239 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
1240 	{
1241 		pp_int32 v = settingsDatabase->restore("FULLSCREEN")->getIntValue();
1242 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_FULLSCREEN))->checkIt(v!=0);
1243 	}
1244 
1245 };
1246 
1247 class TabPageFonts_1 : public TabPage
1248 {
1249 public:
TabPageFonts_1(pp_uint32 id,SectionSettings & sectionSettings)1250 	TabPageFonts_1(pp_uint32 id, SectionSettings& sectionSettings) :
1251 		TabPage(id, sectionSettings)
1252 	{
1253 	}
1254 
init(PPScreen * screen)1255 	virtual void init(PPScreen* screen)
1256 	{
1257 		pp_int32 x = 0;
1258 		pp_int32 y = 0;
1259 
1260 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
1261 
1262 		pp_int32 i;
1263 		const char* name = NULL;
1264 
1265 		pp_int32 x2 = x;
1266 		pp_int32 y2 = y;
1267 
1268 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x + 2, y2 + 2), "Pattern Editor", true, true));
1269 
1270 		y2+=11;
1271 
1272 		PPRadioGroup* radioGroup = new PPRadioGroup(RADIOGROUP_SETTINGS_PATTERNFONT, screen, this, PPPoint(x2, y2), PPSize(159, 0));
1273 		radioGroup->setColor(TrackerConfig::colorThemeMain);
1274 
1275 		name = PPFont::getFirstFontFamilyName();
1276 		i = 0;
1277 		while (name)
1278 		{
1279 			radioGroup->addItem(name);
1280 			name = PPFont::getNextFontFamilyName();
1281 			i++;
1282 		}
1283 		radioGroup->setSize(PPSize(radioGroup->getSize().width, 14*i));
1284 
1285 		container->addControl(radioGroup);
1286 
1287 		y2+=radioGroup->getSize().height;
1288 
1289 		container->addControl(new PPSeperator(0, screen, PPPoint(x2, y2), 158, TrackerConfig::colorThemeMain, true));
1290 
1291 		y2+=5;
1292 
1293 		//container->addControl(new PPSeperator(0, screen, PPPoint(x2 + 158, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
1294 	}
1295 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)1296 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
1297 	{
1298 		pp_int32 v = settingsDatabase->restore("PATTERNFONT")->getIntValue();
1299 		static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_PATTERNFONT))->setChoice(v);
1300 	}
1301 
1302 };
1303 
1304 class TabPageFonts_2 : public TabPage
1305 {
1306 public:
TabPageFonts_2(pp_uint32 id,SectionSettings & sectionSettings)1307 	TabPageFonts_2(pp_uint32 id, SectionSettings& sectionSettings) :
1308 		TabPage(id, sectionSettings)
1309 	{
1310 	}
1311 
init(PPScreen * screen)1312 	virtual void init(PPScreen* screen)
1313 	{
1314 		pp_int32 x = 0;
1315 		pp_int32 y = 0;
1316 
1317 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
1318 
1319 		pp_int32 x2 = x;
1320 		pp_int32 y2 = y;
1321 
1322 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Font face config", true, true));
1323 
1324 		y2+=12;
1325 
1326 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Available sizes:", true));
1327 
1328 		y2+=8;
1329 
1330 		pp_int32 lbheight = (container->getSize().height - (y2-y+11*2+2)) / 2;
1331 		sectionSettings.listBoxFontFamilies = new PPListBox(LISTBOX_SETTINGS_FONTFAMILIES, screen, this, PPPoint(x2+2, y2+2), PPSize(153,lbheight), true, false, true, true);
1332 		sectionSettings.listBoxFontFamilies->setBorderColor(TrackerConfig::colorThemeMain);
1333 		sectionSettings.listBoxFontFamilies->setKeepsFocus(false);
1334 		sectionSettings.listBoxFontFamilies->setShowFocus(false);
1335 
1336 		const char* name = PPFont::getFirstFontFamilyName();
1337 		while (name)
1338 		{
1339 			sectionSettings.listBoxFontFamilies->addItem(name);
1340 			name = PPFont::getNextFontFamilyName();
1341 		}
1342 		container->addControl(sectionSettings.listBoxFontFamilies);
1343 
1344 		y2+=sectionSettings.listBoxFontFamilies->getSize().height+2;
1345 
1346 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Available faces:", true));
1347 
1348 		y2+=8;
1349 		lbheight+=7;
1350 
1351 		sectionSettings.listBoxFontEntries = new PPListBox(LISTBOX_SETTINGS_FONTENTRIES, screen, this, PPPoint(x2+2, y2+2), PPSize(153,lbheight), true, false, true, true);
1352 		sectionSettings.listBoxFontEntries->setBorderColor(TrackerConfig::colorThemeMain);
1353 		sectionSettings.listBoxFontEntries->setKeepsFocus(false);
1354 		sectionSettings.listBoxFontEntries->setShowFocus(false);
1355 
1356 		sectionSettings.enumerateFontFacesInListBox(sectionSettings.listBoxFontFamilies->getSelectedIndex());
1357 		container->addControl(sectionSettings.listBoxFontEntries);
1358 
1359 		//container->addControl(new PPSeperator(0, screen, PPPoint(x2 + 158, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
1360 	}
1361 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)1362 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
1363 	{
1364 		PPString str = settingsDatabase->restore(PPFont::getFamilyInternalName((PPFont::FontID)sectionSettings.listBoxFontFamilies->getSelectedIndex()))->getStringValue();
1365 		sectionSettings.listBoxFontEntries->setSelectedIndexByItem(str, false);
1366 	}
1367 
1368 };
1369 
1370 class TabPageMisc_1 : public TabPage
1371 {
1372 public:
TabPageMisc_1(pp_uint32 id,SectionSettings & sectionSettings)1373 	TabPageMisc_1(pp_uint32 id, SectionSettings& sectionSettings) :
1374 		TabPage(id, sectionSettings)
1375 	{
1376 	}
1377 
init(PPScreen * screen)1378 	virtual void init(PPScreen* screen)
1379 	{
1380 		pp_int32 x = 0;
1381 		pp_int32 y = 0;
1382 
1383 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
1384 
1385 		pp_int32 x2 = x;
1386 		pp_int32 y2 = y;
1387 
1388 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Edit mode", true, true));
1389 
1390 		PPRadioGroup* radioGroup = new PPRadioGroup(RADIOGROUP_SETTINGS_EDITMODE, screen, this, PPPoint(x2, y2+2+11), PPSize(160, 42));
1391 		radioGroup->setColor(TrackerConfig::colorThemeMain);
1392 
1393 		radioGroup->addItem("MilkyTracker");
1394 		radioGroup->addItem("Fasttracker II");
1395 		container->addControl(radioGroup);
1396 
1397 		y2+=3*12+8;
1398 
1399 		container->addControl(new PPSeperator(0, screen, PPPoint(x2, y2), 156, TrackerConfig::colorThemeMain, true));
1400 
1401 		y2+=6;
1402 
1403 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Scrolling Style", true, true));
1404 
1405 		radioGroup = new PPRadioGroup(RADIOGROUP_SETTINGS_SCROLLMODE, screen, this, PPPoint(x2, y2+2+11), PPSize(160, 42));
1406 		radioGroup->setColor(TrackerConfig::colorThemeMain);
1407 
1408 		radioGroup->addItem("Scroll to end");
1409 		radioGroup->addItem("Scroll to center");
1410 		radioGroup->addItem("Always centered");
1411 		container->addControl(radioGroup);
1412 
1413 		//container->addControl(new PPSeperator(0, screen, PPPoint(x2 + 158, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
1414 	}
1415 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)1416 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
1417 	{
1418 		pp_int32 v = settingsDatabase->restore("EDITMODE")->getIntValue();
1419 		static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_EDITMODE))->setChoice(v);
1420 
1421 		v = settingsDatabase->restore("SCROLLMODE")->getIntValue();
1422 		static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_SCROLLMODE))->setChoice(v);
1423 	}
1424 
1425 };
1426 
1427 class TabPageMisc_2 : public TabPage
1428 {
1429 public:
TabPageMisc_2(pp_uint32 id,SectionSettings & sectionSettings)1430 	TabPageMisc_2(pp_uint32 id, SectionSettings& sectionSettings) :
1431 		TabPage(id, sectionSettings)
1432 	{
1433 	}
1434 
init(PPScreen * screen)1435 	virtual void init(PPScreen* screen)
1436 	{
1437 		pp_int32 x = 0;
1438 		pp_int32 y = 0;
1439 
1440 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
1441 
1442 		pp_int32 y2 = y;
1443 		pp_int32 x2 = x;
1444 
1445 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Pattern Editor", true, true));
1446 
1447 		y2+=4+11;
1448 		PPCheckBox* checkBox = new PPCheckBox(CHECKBOX_SETTINGS_AUTORESIZE, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 1));
1449 		container->addControl(checkBox);
1450 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Paste autoresize:", checkBox, true));
1451 
1452 		y2+=12;
1453 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_INSTRUMENTBACKTRACE, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 1));
1454 		container->addControl(checkBox);
1455 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Instr. backtrace:", checkBox, true));
1456 
1457 		y2+=12;
1458 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_TABTONOTE, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 1));
1459 		container->addControl(checkBox);
1460 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "TAB to note:", checkBox, true));
1461 
1462 		y2+=12;
1463 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_CLICKTOCURSOR, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 1));
1464 		container->addControl(checkBox);
1465 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Click to cursor:", checkBox, true));
1466 
1467 		y2+=12;
1468 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_WRAPCURSOR, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 1));
1469 		container->addControl(checkBox);
1470 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Wrap cursor:", checkBox, true));
1471 
1472 		y2+=11;
1473 
1474 		//container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2), "Follow song:", true));
1475 		//container->addControl(new PPCheckBox(CHECKBOX_SETTINGS_FOLLOWSONG, screen, this, PPPoint(x2 + 4 + 17*8 + 4, y2-1)));
1476 
1477 		// ------------------ sample editor -------------------
1478 		container->addControl(new PPSeperator(0, screen, PPPoint(x2, y2), 158, TrackerConfig::colorThemeMain, true));
1479 
1480 		y2+=3;
1481 
1482 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2), "Sample Editor", true, true));
1483 		y2+=4+11;
1484 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_SAMPLEEDITORUNDO, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 1));
1485 		container->addControl(checkBox);
1486 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Enable undo buff:", checkBox, true));
1487 
1488 		y2+=14;
1489 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_AUTOMIXDOWNSAMPLES, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 3));
1490 		container->addControl(checkBox);
1491 		PPCheckBoxLabel* cbLabel = new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Auto-mixdown stereo samples:", checkBox, true);
1492 		cbLabel->setFont(PPFont::getFont(PPFont::FONT_TINY));
1493 		container->addControl(cbLabel);
1494 
1495 
1496 		y2+=10;
1497 
1498 		/*// ------------------ other -------------------
1499 			container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2), "Other", true, true));
1500 		y2+=4+11;
1501 		PPStaticText* statict = new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2), "Estimate playtime after load", true);
1502 		statict->setFont(PPFont::getFont(PPFont::FONT_TINY));
1503 		container->addControl(statict);
1504 		container->addControl(new PPCheckBox(CHECKBOX_SETTINGS_AUTOESTPLAYTIME, screen, this, PPPoint(x2 + 4 + 17*8 + 4, y2-3)));*/
1505 
1506 		//container->addControl(new PPSeperator(0, screen, PPPoint(x2 + 158, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
1507 	}
1508 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)1509 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
1510 	{
1511 		pp_int32 v = settingsDatabase->restore("PATTERNAUTORESIZE")->getIntValue();
1512 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_AUTORESIZE))->checkIt(v!=0);
1513 
1514 		v = settingsDatabase->restore("INSTRUMENTBACKTRACE")->getIntValue();
1515 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_INSTRUMENTBACKTRACE))->checkIt(v!=0);
1516 
1517 		v = settingsDatabase->restore("TABTONOTE")->getIntValue();
1518 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_TABTONOTE))->checkIt(v!=0);
1519 
1520 		v = settingsDatabase->restore("CLICKTOCURSOR")->getIntValue();
1521 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_CLICKTOCURSOR))->checkIt(v!=0);
1522 
1523 		//v = settingsDatabase->restore("WRAPAROUND")->getIntValue();
1524 		//static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_WRAPCURSOR))->checkIt(v!=0);
1525 
1526 		//v = settingsDatabase->restore("FOLLOWSONG")->getIntValue();
1527 		//static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_FOLLOWSONG))->checkIt(v!=0);
1528 
1529 		/*v = settingsDatabase->restore("AUTOESTPLAYTIME")->getIntValue();
1530 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_AUTOESTPLAYTIME))->checkIt(v!=0);*/
1531 
1532 		v = settingsDatabase->restore("SAMPLEEDITORUNDOBUFFER")->getIntValue();
1533 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_SAMPLEEDITORUNDO))->checkIt(v!=0);
1534 
1535 		v = settingsDatabase->restore("AUTOMIXDOWNSAMPLES")->getIntValue();
1536 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_AUTOMIXDOWNSAMPLES))->checkIt(v!=0);
1537 	}
1538 
1539 };
1540 
1541 class TabPageMisc_3 : public TabPage
1542 {
1543 public:
TabPageMisc_3(pp_uint32 id,SectionSettings & sectionSettings)1544 	TabPageMisc_3(pp_uint32 id, SectionSettings& sectionSettings) :
1545 		TabPage(id, sectionSettings)
1546 	{
1547 	}
1548 
init(PPScreen * screen)1549 	virtual void init(PPScreen* screen)
1550 	{
1551 		pp_int32 x = 0;
1552 		pp_int32 y = 0;
1553 
1554 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
1555 
1556 		pp_int32 x2 = x;
1557 		pp_int32 y2 = y;
1558 
1559 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2), "Other", true, true));
1560 		y2+=4+11;
1561 		PPCheckBox* checkBox = new PPCheckBox(CHECKBOX_SETTINGS_INTERNALDISKBROWSER, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 1));
1562 		container->addControl(checkBox);
1563 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Internal browser:", checkBox, true));
1564 
1565 		y2+=12;
1566 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_SHOWSPLASH, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 1));
1567 		container->addControl(checkBox);
1568 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Splash screen:", checkBox, true));
1569 
1570 		y2+=14;
1571 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_AUTOESTPLAYTIME, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 3));
1572 		container->addControl(checkBox);
1573 		PPCheckBoxLabel* cbLabel = new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Estimate playtime after load", checkBox, true);
1574 		cbLabel->setFont(PPFont::getFont(PPFont::FONT_TINY));
1575 		container->addControl(cbLabel);
1576 
1577 
1578 		y2+=10;
1579 
1580 #ifndef __LOWRES__
1581 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_SCOPES, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 1));
1582 		container->addControl(checkBox);
1583 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Show scopes:", checkBox, true));
1584 		y2+=12;
1585 #endif
1586 
1587 		container->addControl(new PPStaticText(STATICTEXT_SETTINGS_SCOPESAPPEARANCE, NULL, NULL, PPPoint(x2 + 2, y2), "Scope Style:", true));
1588 
1589 		PPRadioGroup* radioGroup = new PPRadioGroup(RADIOGROUP_SETTINGS_SCOPESAPPEARANCE, screen, this, PPPoint(x2, y2+10), PPSize(160, 42));
1590 		radioGroup->setColor(TrackerConfig::colorThemeMain);
1591 		radioGroup->setFont(PPFont::getFont(PPFont::FONT_TINY));
1592 		radioGroup->addItem("Dots");
1593 		radioGroup->addItem("Solid");
1594 		radioGroup->addItem("Smooth Lines");
1595 		container->addControl(radioGroup);
1596 
1597 		//container->addControl(new PPSeperator(0, screen, PPPoint(x2 + 158, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
1598 	}
1599 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)1600 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
1601 	{
1602 		pp_int32 v = settingsDatabase->restore("AUTOESTPLAYTIME")->getIntValue();
1603 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_AUTOESTPLAYTIME))->checkIt(v!=0);
1604 
1605 		v = settingsDatabase->restore("INTERNALDISKBROWSER")->getIntValue();
1606 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_INTERNALDISKBROWSER))->checkIt(v!=0);
1607 
1608 		v = settingsDatabase->restore("SHOWSPLASH")->getIntValue();
1609 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_SHOWSPLASH))->checkIt(v!=0);
1610 
1611 		v = settingsDatabase->restore("SCOPES")->getIntValue();
1612 #ifndef __LOWRES__
1613 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_SCOPES))->checkIt(v & 1);
1614 
1615 		static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_SCOPESAPPEARANCE))->enable((v & 1) != 0);
1616 		static_cast<PPStaticText*>(container->getControlByID(STATICTEXT_SETTINGS_SCOPESAPPEARANCE))->enable((v & 1) != 0);
1617 #endif
1618 		static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_SCOPESAPPEARANCE))->setChoice(v >> 1);
1619 	}
1620 
1621 };
1622 
1623 class TabPageMisc_4 : public TabPage
1624 {
1625 public:
TabPageMisc_4(pp_uint32 id,SectionSettings & sectionSettings)1626 	TabPageMisc_4(pp_uint32 id, SectionSettings& sectionSettings) :
1627 		TabPage(id, sectionSettings)
1628 	{
1629 	}
1630 
init(PPScreen * screen)1631 	virtual void init(PPScreen* screen)
1632 	{
1633 		pp_int32 x = 0;
1634 		pp_int32 y = 0;
1635 
1636 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
1637 
1638 		pp_int32 x2 = x;
1639 		pp_int32 y2 = y;
1640 
1641 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2), "Mouse Wheel", true, true));
1642 		y2+=4+11;
1643 		PPCheckBox* checkBox = new PPCheckBox(CHECKBOX_SETTINGS_INVERTMWHEEL, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 1));
1644 		container->addControl(checkBox);
1645 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Inv PatEd scroll:", checkBox, true));
1646 
1647 		y2+=12;
1648 
1649 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_INVERTMWHEELZOOM, screen, this, PPPoint(x2 + 4 + 17 * 8 + 4, y2 - 1));
1650 		container->addControl(checkBox);
1651 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x2 + 2, y2), "Invert zoom:", checkBox, true));
1652 
1653 		y2+=12;
1654 	}
1655 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)1656 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
1657 	{
1658 		pp_int32 v = settingsDatabase->restore("INVERTMWHEELZOOM")->getIntValue();
1659 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_INVERTMWHEELZOOM))->checkIt(v!=0);
1660 		v = settingsDatabase->restore("INVERTMWHEEL")->getIntValue();
1661 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_INVERTMWHEEL))->checkIt(v!=0);
1662 	}
1663 };
1664 
1665 class TabPageTabs_1 : public TabPage
1666 {
1667 public:
TabPageTabs_1(pp_uint32 id,SectionSettings & sectionSettings)1668 	TabPageTabs_1(pp_uint32 id, SectionSettings& sectionSettings) :
1669 		TabPage(id, sectionSettings)
1670 	{
1671 	}
1672 
init(PPScreen * screen)1673 	virtual void init(PPScreen* screen)
1674 	{
1675 		pp_int32 x = 0;
1676 		pp_int32 y = 0;
1677 
1678 		container = new PPTransparentContainer(id, screen, this, PPPoint(x, y), PPSize(PageWidth,PageHeight));
1679 
1680 		pp_int32 x2 = x;
1681 		pp_int32 y2 = y;
1682 
1683 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Load module" PPSTR_PERIODS, true, true));
1684 
1685 		y2+=12;
1686 		PPCheckBox* checkBox = new PPCheckBox(CHECKBOX_SETTINGS_LOADMODULEINNEWTAB, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 + 2 - 1));
1687 		container->addControl(checkBox);
1688 		container->addControl(new PPCheckBoxLabel(0, NULL, this, PPPoint(x + 4, y2 + 2), PPSTR_PERIODS"in new Tab", checkBox, true));
1689 
1690 		y2+=12+3;
1691 
1692 		container->addControl(new PPSeperator(0, screen, PPPoint(x2, y2), 158, TrackerConfig::colorThemeMain, true));
1693 
1694 		y2+=3;
1695 
1696 		container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 2, y2 + 2), "Stop background", true, true));
1697 
1698 		PPRadioGroup* radioGroup = new PPRadioGroup(RADIOGROUP_SETTINGS_STOPBACKGROUNDBEHAVIOUR, screen, this, PPPoint(x2, y2+2+11), PPSize(160, 42));
1699 		radioGroup->setColor(TrackerConfig::colorThemeMain);
1700 
1701 		radioGroup->addItem("Never");
1702 		radioGroup->addItem("On Tab switch");
1703 		radioGroup->addItem("On Playback");
1704 		container->addControl(radioGroup);
1705 
1706 		y2+=3*14 + 14;
1707 		checkBox = new PPCheckBox(CHECKBOX_SETTINGS_TABSWITCHRESUMEPLAY, screen, this, PPPoint(x + 4 + 17 * 8 + 4, y2 + 2 - 1));
1708 		container->addControl(checkBox);
1709 		container->addControl(new PPCheckBoxLabel(STATICTEXT_SETTINGS_TABSWITCHRESUMEPLAY, NULL, this, PPPoint(x + 4, y2 + 2), "Tab-switch resume", checkBox, true));
1710 
1711 		//container->addControl(new PPSeperator(0, screen, PPPoint(x2 + 158, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
1712 	}
1713 
update(PPScreen * screen,TrackerSettingsDatabase * settingsDatabase,ModuleEditor & moduleEditor)1714 	virtual void update(PPScreen* screen, TrackerSettingsDatabase* settingsDatabase, ModuleEditor& moduleEditor)
1715 	{
1716 		pp_int32 v = settingsDatabase->restore("TABS_STOPBACKGROUNDBEHAVIOUR")->getIntValue();
1717 		static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SETTINGS_STOPBACKGROUNDBEHAVIOUR))->setChoice(v);
1718 
1719 		static_cast<PPStaticText*>(container->getControlByID(STATICTEXT_SETTINGS_TABSWITCHRESUMEPLAY))->enable(v != 0);
1720 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_TABSWITCHRESUMEPLAY))->enable(v != 0);
1721 
1722 		v = settingsDatabase->restore("TABS_TABSWITCHRESUMEPLAY")->getIntValue();
1723 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_TABSWITCHRESUMEPLAY))->checkIt(v != 0);
1724 
1725 		v = settingsDatabase->restore("TABS_LOADMODULEINNEWTAB")->getIntValue();
1726 		static_cast<PPCheckBox*>(container->getControlByID(CHECKBOX_SETTINGS_LOADMODULEINNEWTAB))->checkIt(v != 0);
1727 	}
1728 
1729 };
1730 
SectionSettings(Tracker & theTracker)1731 SectionSettings::SectionSettings(Tracker& theTracker) :
1732 	SectionAbstract(theTracker, NULL, new DialogResponderSettings(*this)),
1733 	sectionContainer(NULL),
1734 	listBoxColors(NULL),
1735 	listBoxFontFamilies(NULL),
1736 	listBoxFontEntries(NULL),
1737 	currentActiveTabNum(0),
1738 	currentActivePageStart(0),
1739 	visible(false),
1740 	palette(NULL),
1741 	storePalette(false),
1742 	colorCopy(NULL),
1743 	lastColorFile(TrackerConfig::untitledSong)
1744 {
1745 	pp_int32 i;
1746 
1747 	for (i = 0; i < NUMSETTINGSPAGES; i++)
1748 	{
1749 		tabPages.add(new PPSimpleVector<TabPage>());
1750 		currentActiveSubPageNum[i] = 0;
1751 	}
1752 
1753 	initColorDescriptors();
1754 	currentColor.set(128, 128, 128);
1755 
1756 	palette = new TColorPalette();
1757 	mixerSettings = new TMixerSettings();
1758 
1759 	// predefined color palettes
1760 	predefinedColorPalettes = new ColorPaletteContainer(TrackerConfig::numPredefinedColorPalettes);
1761 
1762 	for (i = 0; i < getNumPredefinedColorPalettes(); i++)
1763 	{
1764 		/*TColorPalette pal;
1765 		pal.numColors = GlobalColorConfig::ColorLast;
1766 		for (j = 0; j < pal.numColors; j++)
1767 		{
1768 			pal.colors[j].set(rand()&255, rand()&255, rand()&255);
1769 		}*/
1770 		predefinedColorPalettes->store(i, ColorPaletteContainer::decodePalette(TrackerConfig::predefinedColorPalettes[i]));
1771 	}
1772 
1773 	for (i = 0; i < GlobalColorConfig::ColorLast; i++)
1774 		colorMapping[i] = GlobalColorConfig::ColorLast-1;
1775 
1776 	colorMapping[0] = GlobalColorConfig::ColorTheme;
1777 	colorMapping[1] = GlobalColorConfig::ColorForegroundText;
1778 	colorMapping[2] = GlobalColorConfig::ColorTextHighlited;
1779 	colorMapping[3] = GlobalColorConfig::ColorRowHighlitedFirst;
1780 	colorMapping[4] = GlobalColorConfig::ColorTextHighlitedSecond;
1781 	colorMapping[5] = GlobalColorConfig::ColorRowHighlitedSecond;
1782 	colorMapping[6] = GlobalColorConfig::ColorPatternNote;
1783 	colorMapping[7] = GlobalColorConfig::ColorPatternInstrument;
1784 	colorMapping[8] = GlobalColorConfig::ColorPatternVolume;
1785 	colorMapping[9] = GlobalColorConfig::ColorPatternEffect;
1786 	colorMapping[10] = GlobalColorConfig::ColorPatternOperand;
1787 	colorMapping[11] = GlobalColorConfig::ColorCursor;
1788 	colorMapping[12] = GlobalColorConfig::ColorCursorLine;
1789 	colorMapping[13] = GlobalColorConfig::ColorCursorLineHighlighted;
1790 	colorMapping[14] = GlobalColorConfig::ColorPatternSelection;
1791 	colorMapping[15] = GlobalColorConfig::ColorButtons;
1792 	colorMapping[16] = GlobalColorConfig::ColorButtonText;
1793 	colorMapping[17] = GlobalColorConfig::ColorRecordModeButtonText;
1794 	colorMapping[18] = GlobalColorConfig::ColorSelection;
1795 	colorMapping[19] = GlobalColorConfig::ColorListBoxBackground;
1796 	colorMapping[20] = GlobalColorConfig::ColorScrollBarBackground;
1797 	colorMapping[21] = GlobalColorConfig::ColorScopes;
1798 	colorMapping[22] = GlobalColorConfig::ColorScopesRecordIndicator;
1799 	colorMapping[23] = GlobalColorConfig::ColorPeakClipIndicator;
1800 	colorMapping[24] = GlobalColorConfig::ColorSampleEditorWaveform;
1801 }
1802 
~SectionSettings()1803 SectionSettings::~SectionSettings()
1804 {
1805 	delete predefinedColorPalettes;
1806 	delete palette;
1807 	delete mixerSettings;
1808 	delete colorCopy;
1809 }
1810 
getColorIndex()1811 pp_int32 SectionSettings::getColorIndex()
1812 {
1813 	return listBoxColors ? colorMapping[listBoxColors->getSelectedIndex()] : colorMapping[0];
1814 }
1815 
showRestartMessageBox()1816 void SectionSettings::showRestartMessageBox()
1817 {
1818 	if (tracker.settingsDatabase->restore("XRESOLUTION")->getIntValue() != tracker.settingsDatabaseCopy->restore("XRESOLUTION")->getIntValue() ||
1819 		tracker.settingsDatabase->restore("YRESOLUTION")->getIntValue() != tracker.settingsDatabaseCopy->restore("YRESOLUTION")->getIntValue() ||
1820 		tracker.settingsDatabase->restore("SCREENSCALEFACTOR")->getIntValue() != tracker.settingsDatabaseCopy->restore("SCREENSCALEFACTOR")->getIntValue())
1821 	{
1822 		SystemMessage message(*tracker.screen, SystemMessage::MessageResChangeRestart);
1823 		message.show();
1824 	}
1825 }
1826 
handleEvent(PPObject * sender,PPEvent * event)1827 pp_int32 SectionSettings::handleEvent(PPObject* sender, PPEvent* event)
1828 {
1829 	if (event->getID() == eCommand || event->getID() == eCommandRepeat)
1830 	{
1831 
1832 		switch (reinterpret_cast<PPControl*>(sender)->getID())
1833 		{
1834 			case PAGE_BUTTON_0:
1835 			case PAGE_BUTTON_1:
1836 			case PAGE_BUTTON_2:
1837 			case PAGE_BUTTON_3:
1838 			case PAGE_BUTTON_4:
1839 			{
1840 				pp_int32 i = reinterpret_cast<PPControl*>(sender)->getID()-PAGE_BUTTON_0;
1841 				showPage(i, currentActiveSubPageNum[i]);
1842 				update();
1843 				break;
1844 			}
1845 
1846 			case SUBPAGE_BUTTON_LEFT_0:
1847 			case SUBPAGE_BUTTON_LEFT_1:
1848 			case SUBPAGE_BUTTON_LEFT_2:
1849 			case SUBPAGE_BUTTON_LEFT_3:
1850 			case SUBPAGE_BUTTON_LEFT_4:
1851 			{
1852 				pp_int32 i = currentActiveSubPageNum[currentActiveTabNum] - 1;
1853 				if (i>=0)
1854 				{
1855 					showPage(currentActiveTabNum, i);
1856 					update();
1857 				}
1858 				break;
1859 			}
1860 
1861 			case SUBPAGE_BUTTON_RIGHT_0:
1862 			case SUBPAGE_BUTTON_RIGHT_1:
1863 			case SUBPAGE_BUTTON_RIGHT_2:
1864 			case SUBPAGE_BUTTON_RIGHT_3:
1865 			case SUBPAGE_BUTTON_RIGHT_4:
1866 			{
1867 				pp_int32 i = currentActiveSubPageNum[currentActiveTabNum] + 1;
1868 				if (i<tabPages.get(currentActiveTabNum)->size())
1869 				{
1870 					showPage(currentActiveTabNum, i);
1871 					update();
1872 				}
1873 				break;
1874 			}
1875 
1876 			case BUTTON_SETTINGS_OK:
1877 			{
1878 				if (event->getID() != eCommand)
1879 					break;
1880 
1881 				showRestartMessageBox();
1882 
1883 				// Store new palette settings
1884 				saveCurrentGlobalPalette();
1885 				storeCurrentPaletteToDatabase();
1886 				tracker.applySettings(tracker.settingsDatabase, tracker.settingsDatabaseCopy);
1887 
1888 				// Store new mixer settings
1889 				saveCurrentMixerSettings(*mixerSettings);
1890 
1891 				show(false);
1892 				tracker.sectionSamples->update(false);
1893 				tracker.screen->paint();
1894 
1895 				break;
1896 			}
1897 
1898 			case BUTTON_SETTINGS_APPLY:
1899 			{
1900 				if (event->getID() != eCommand)
1901 					break;
1902 
1903 				showRestartMessageBox();
1904 
1905 				// Store new palette settings
1906 				saveCurrentGlobalPalette();
1907 				storeCurrentPaletteToDatabase();
1908 				tracker.applySettings(tracker.settingsDatabase, tracker.settingsDatabaseCopy);
1909 
1910 				// Store new mixer settings
1911 				saveCurrentMixerSettings(*mixerSettings);
1912 
1913 				update(false);
1914 				tracker.sectionSamples->update(false);
1915 				tracker.screen->paint();
1916 
1917 				delete tracker.settingsDatabaseCopy;
1918 				tracker.settingsDatabaseCopy = new TrackerSettingsDatabase(*tracker.settingsDatabase);
1919 				break;
1920 			}
1921 
1922 			case BUTTON_SETTINGS_CANCEL:
1923 			{
1924 				if (event->getID() != eCommand)
1925 					break;
1926 
1927 				cancelSettings();
1928 				break;
1929 			}
1930 
1931 			case BUTTON_SETTINGS_CHOOSEDRIVER:
1932 			{
1933 				if (event->getID() != eCommand)
1934 					break;
1935 
1936 				showSelectDriverMessageBox();
1937 				break;
1938 			}
1939 
1940 			case CHECKBOX_SETTINGS_RAMPING:
1941 			{
1942 				if (event->getID() != eCommand)
1943 					break;
1944 
1945 				tracker.settingsDatabase->store("RAMPING", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
1946 				update();
1947 				break;
1948 			}
1949 
1950 			case BUTTON_SETTINGS_RESAMPLING:
1951 			{
1952 				if (event->getID() != eCommand)
1953 					break;
1954 
1955 				showResamplerMessageBox();
1956 				break;
1957 			}
1958 
1959 			case CHECKBOX_SETTINGS_FORCEPOWER2BUFF:
1960 			{
1961 				if (event->getID() != eCommand)
1962 					break;
1963 
1964 				tracker.settingsDatabase->store("FORCEPOWEROFTWOBUFFERSIZE", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
1965 				update();
1966 				break;
1967 			}
1968 
1969 			case CHECKBOX_SETTINGS_VIRTUALCHANNELS:
1970 			{
1971 				if (reinterpret_cast<PPCheckBox*>(sender)->isChecked())
1972 					tracker.settingsDatabase->store("VIRTUALCHANNELS", 32);
1973 				else
1974 					tracker.settingsDatabase->store("VIRTUALCHANNELS", 0);
1975 
1976 				update();
1977 				break;
1978 			}
1979 
1980 			case BUTTON_SETTINGS_VIRTUALCHANNELS_PLUS:
1981 			{
1982 				pp_int32 v = tracker.settingsDatabase->restore("VIRTUALCHANNELS")->getIntValue() + 1;
1983 				if (v > 99)
1984 					v = 99;
1985 				tracker.settingsDatabase->store("VIRTUALCHANNELS", v);
1986 				update();
1987 				break;
1988 			}
1989 
1990 			case BUTTON_SETTINGS_VIRTUALCHANNELS_MINUS:
1991 			{
1992 				pp_int32 v = tracker.settingsDatabase->restore("VIRTUALCHANNELS")->getIntValue() - 1;
1993 				if (v < 0)
1994 					v = 0;
1995 				tracker.settingsDatabase->store("VIRTUALCHANNELS", v);
1996 				update();
1997 				break;
1998 			}
1999 
2000 			case CHECKBOX_SETTINGS_MULTICHN_RECORD:
2001 			{
2002 				if (event->getID() != eCommand)
2003 					break;
2004 
2005 				tracker.settingsDatabase->store("MULTICHN_RECORD", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2006 				update();
2007 				break;
2008 			}
2009 
2010 			case CHECKBOX_SETTINGS_MULTICHN_KEYJAZZ:
2011 			{
2012 				if (event->getID() != eCommand)
2013 					break;
2014 
2015 				tracker.settingsDatabase->store("MULTICHN_KEYJAZZ", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2016 				update();
2017 				break;
2018 			}
2019 
2020 			case CHECKBOX_SETTINGS_MULTICHN_EDIT:
2021 			{
2022 				if (event->getID() != eCommand)
2023 					break;
2024 
2025 				tracker.settingsDatabase->store("MULTICHN_EDIT", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2026 				update();
2027 				break;
2028 			}
2029 
2030 			case CHECKBOX_SETTINGS_MULTICHN_RECORDKEYOFF:
2031 			{
2032 				if (event->getID() != eCommand)
2033 					break;
2034 
2035 				tracker.settingsDatabase->store("MULTICHN_RECORDKEYOFF", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2036 				update();
2037 				break;
2038 			}
2039 
2040 			case CHECKBOX_SETTINGS_MULTICHN_RECORDNOTEDELAY:
2041 			{
2042 				if (event->getID() != eCommand)
2043 					break;
2044 
2045 				tracker.settingsDatabase->store("MULTICHN_RECORDNOTEDELAY", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2046 				update();
2047 				break;
2048 			}
2049 
2050 			case CHECKBOX_SETTINGS_HEXCOUNT:
2051 			{
2052 				if (event->getID() != eCommand)
2053 					break;
2054 
2055 				tracker.settingsDatabase->store("HEXCOUNT", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2056 				update();
2057 				break;
2058 			}
2059 
2060 			case CHECKBOX_SETTINGS_SHOWZEROEFFECT:
2061 			{
2062 				if (event->getID() != eCommand)
2063 					break;
2064 
2065 				tracker.settingsDatabase->store("SHOWZEROEFFECT", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2066 				update();
2067 				break;
2068 			}
2069 
2070 			case CHECKBOX_SETTINGS_FULLSCREEN:
2071 			{
2072 				if (event->getID() != eCommand)
2073 					break;
2074 
2075 				tracker.settingsDatabase->store("FULLSCREEN", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2076 				update();
2077 				break;
2078 			}
2079 
2080 			case CHECKBOX_SETTINGS_INSTRUMENTBACKTRACE:
2081 			{
2082 				if (event->getID() != eCommand)
2083 					break;
2084 
2085 				tracker.settingsDatabase->store("INSTRUMENTBACKTRACE", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2086 				update();
2087 				break;
2088 			}
2089 
2090 			case CHECKBOX_SETTINGS_AUTORESIZE:
2091 			{
2092 				if (event->getID() != eCommand)
2093 					break;
2094 
2095 				tracker.settingsDatabase->store("PATTERNAUTORESIZE", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2096 				update();
2097 				break;
2098 			}
2099 
2100 			case CHECKBOX_SETTINGS_TABTONOTE:
2101 			{
2102 				if (event->getID() != eCommand)
2103 					break;
2104 
2105 				tracker.settingsDatabase->store("TABTONOTE", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2106 				update();
2107 				break;
2108 			}
2109 
2110 			case CHECKBOX_SETTINGS_CLICKTOCURSOR:
2111 			{
2112 				if (event->getID() != eCommand)
2113 					break;
2114 
2115 				tracker.settingsDatabase->store("CLICKTOCURSOR", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2116 				update();
2117 				break;
2118 			}
2119 
2120 			case CHECKBOX_SETTINGS_WRAPCURSOR:
2121 			{
2122 				if (event->getID() != eCommand)
2123 					break;
2124 
2125 				tracker.settingsDatabase->store("WRAPAROUND", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2126 				update();
2127 				break;
2128 			}
2129 
2130 			case CHECKBOX_SETTINGS_PROSPECTIVE:
2131 			{
2132 				if (event->getID() != eCommand)
2133 					break;
2134 
2135 				tracker.settingsDatabase->store("PROSPECTIVE", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2136 				update();
2137 				break;
2138 			}
2139 
2140 			case BUTTON_HIGHLIGHTMODULO1_PLUS:
2141 			{
2142 				pp_int32 v = tracker.settingsDatabase->restore("HIGHLIGHTMODULO1")->getIntValue() + 1;
2143 				if (v > 99)
2144 					v = 99;
2145 				tracker.settingsDatabase->store("HIGHLIGHTMODULO1", v);
2146 				update();
2147 				break;
2148 			}
2149 
2150 			case BUTTON_HIGHLIGHTMODULO1_MINUS:
2151 			{
2152 				pp_int32 v = tracker.settingsDatabase->restore("HIGHLIGHTMODULO1")->getIntValue() - 1;
2153 				if (v < 1)
2154 					v = 1;
2155 				tracker.settingsDatabase->store("HIGHLIGHTMODULO1", v);
2156 				update();
2157 				break;
2158 			}
2159 
2160 			case BUTTON_HIGHLIGHTMODULO2_PLUS:
2161 			{
2162 				pp_int32 v = tracker.settingsDatabase->restore("HIGHLIGHTMODULO2")->getIntValue() + 1;
2163 				if (v > 99)
2164 					v = 99;
2165 				tracker.settingsDatabase->store("HIGHLIGHTMODULO2", v);
2166 				update();
2167 				break;
2168 			}
2169 
2170 			case CHECKBOX_HIGHLIGHTMODULO1_FULLROW:
2171 			{
2172 				if (event->getID() != eCommand)
2173 					break;
2174 
2175 				tracker.settingsDatabase->store("HIGHLIGHTROW1", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2176 				break;
2177 			}
2178 
2179 			case BUTTON_HIGHLIGHTMODULO2_MINUS:
2180 			{
2181 				pp_int32 v = tracker.settingsDatabase->restore("HIGHLIGHTMODULO2")->getIntValue() - 1;
2182 				if (v < 1)
2183 					v = 1;
2184 				tracker.settingsDatabase->store("HIGHLIGHTMODULO2", v);
2185 				update();
2186 				break;
2187 			}
2188 
2189 			case CHECKBOX_HIGHLIGHTMODULO2_FULLROW:
2190 			{
2191 				if (event->getID() != eCommand)
2192 					break;
2193 
2194 				tracker.settingsDatabase->store("HIGHLIGHTROW2", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2195 				break;
2196 			}
2197 
2198 			case CHECKBOX_SETTINGS_SCOPES:
2199 			{
2200 				if (event->getID() != eCommand)
2201 					break;
2202 
2203 				mp_sint32 type = static_cast<PPRadioGroup*>(sectionContainer->getControlByID(RADIOGROUP_SETTINGS_SCOPESAPPEARANCE))->getChoice();
2204 				mp_sint32 value = (reinterpret_cast<PPCheckBox*>(sender)->isChecked() ? 1 : 0) | (type << 1);
2205 				tracker.settingsDatabase->store("SCOPES", value);
2206 				update();
2207 				break;
2208 			}
2209 
2210 			case CHECKBOX_SETTINGS_INVERTMWHEEL:
2211 			{
2212 				if (event->getID() != eCommand)
2213 					break;
2214 
2215 				tracker.settingsDatabase->store("INVERTMWHEEL", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2216 				break;
2217 			}
2218 
2219 			case CHECKBOX_SETTINGS_INVERTMWHEELZOOM:
2220 			{
2221 				if (event->getID() != eCommand)
2222 					break;
2223 
2224 				tracker.settingsDatabase->store("INVERTMWHEELZOOM", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2225 				break;
2226 			}
2227 
2228 			//case CHECKBOX_SETTINGS_FOLLOWSONG:
2229 			//{
2230 			//	if (event->getID() != eCommand)
2231 			//		break;
2232 
2233 			//	tracker.settingsDatabase->store("FOLLOWSONG", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2234 			//	update();
2235 			//	break;
2236 			//}
2237 
2238 			case CHECKBOX_SETTINGS_SAMPLEEDITORUNDO:
2239 			{
2240 				if (event->getID() != eCommand)
2241 					break;
2242 
2243 				tracker.settingsDatabase->store("SAMPLEEDITORUNDOBUFFER", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2244 				update();
2245 				break;
2246 			}
2247 
2248 			case CHECKBOX_SETTINGS_AUTOMIXDOWNSAMPLES:
2249 			{
2250 				if (event->getID() != eCommand)
2251 					break;
2252 
2253 				tracker.settingsDatabase->store("AUTOMIXDOWNSAMPLES", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2254 				update();
2255 				break;
2256 			}
2257 
2258 			case CHECKBOX_SETTINGS_AUTOESTPLAYTIME:
2259 			{
2260 				if (event->getID() != eCommand)
2261 					break;
2262 
2263 				tracker.settingsDatabase->store("AUTOESTPLAYTIME", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2264 				update();
2265 				break;
2266 			}
2267 
2268 			case CHECKBOX_SETTINGS_SHOWSPLASH:
2269 			{
2270 				if (event->getID() != eCommand)
2271 					break;
2272 
2273 				tracker.settingsDatabase->store("SHOWSPLASH", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2274 				update();
2275 				break;
2276 			}
2277 
2278 			case CHECKBOX_SETTINGS_INTERNALDISKBROWSER:
2279 			{
2280 				if (event->getID() != eCommand)
2281 					break;
2282 
2283 				tracker.settingsDatabase->store("INTERNALDISKBROWSER", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2284 				update();
2285 				break;
2286 			}
2287 
2288 			case CHECKBOX_SETTINGS_TABSWITCHRESUMEPLAY:
2289 			{
2290 				if (event->getID() != eCommand)
2291 					break;
2292 
2293 				tracker.settingsDatabase->store("TABS_TABSWITCHRESUMEPLAY", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2294 				update();
2295 				break;
2296 			}
2297 
2298 			case CHECKBOX_SETTINGS_LOADMODULEINNEWTAB:
2299 			{
2300 				if (event->getID() != eCommand)
2301 					break;
2302 
2303 				tracker.settingsDatabase->store("TABS_LOADMODULEINNEWTAB", (pp_int32)reinterpret_cast<PPCheckBox*>(sender)->isChecked());
2304 				update();
2305 				break;
2306 			}
2307 
2308 			case BUTTON_COLOR_EXPORT:
2309 			{
2310 				if (event->getID() != eCommand)
2311 					break;
2312 
2313 				exportCurrentColorPalette();
2314 				break;
2315 			}
2316 
2317 			case BUTTON_COLOR_IMPORT:
2318 			{
2319 				if (event->getID() != eCommand)
2320 					break;
2321 
2322 				importCurrentColorPalette();
2323 				break;
2324 			}
2325 
2326 			case BUTTON_COLOR_PREVIEW:
2327 			{
2328 				if (event->getID() != eCommand)
2329 					break;
2330 
2331 				updateCurrentColors();
2332 				break;
2333 			}
2334 
2335 			case BUTTON_COLOR_RESTORE:
2336 			{
2337 				if (event->getID() != eCommand)
2338 					break;
2339 				showRestorePaletteMessageBox();
2340 				break;
2341 			}
2342 
2343 			// predefined color handling
2344 			case BUTTON_COLOR_PREDEF_0:
2345 			case BUTTON_COLOR_PREDEF_1:
2346 			case BUTTON_COLOR_PREDEF_2:
2347 			case BUTTON_COLOR_PREDEF_3:
2348 			case BUTTON_COLOR_PREDEF_4:
2349 			case BUTTON_COLOR_PREDEF_5:
2350 			{
2351 				if (event->getID() != eCommand)
2352 					break;
2353 
2354 				pp_int32 i = reinterpret_cast<PPControl*>(sender)->getID() - BUTTON_COLOR_PREDEF_0;
2355 
2356 				if (storePalette)
2357 				{
2358 					TColorPalette pal;
2359 
2360 					colorDescriptors[getColorIndex()].colorCopy = currentColor;
2361 
2362 					pal.numColors = GlobalColorConfig::ColorLast;
2363 					for (pp_int32 j = 0; j < pal.numColors; j++)
2364 						pal.colors[j] = colorDescriptors[j].colorCopy;
2365 
2366 					predefinedColorPalettes->store(i, pal);
2367 					storePalette = !storePalette;
2368 
2369 					PPButton* button = static_cast<PPButton*>(sectionContainer->getControlByID(BUTTON_COLOR_PREDEF_STORE));
2370 					if (!button)
2371 						break;
2372 					button->setPressed(storePalette);
2373 				}
2374 				else
2375 				{
2376 					const TColorPalette* pal = predefinedColorPalettes->restore(i);
2377 
2378 					for (i = 0; i < pal->numColors; i++)
2379 					{
2380 						if (i < GlobalColorConfig::ColorLast)
2381 						{
2382 							colorDescriptors[i].colorCopy = pal->colors[i];
2383 						}
2384 					}
2385 
2386 					currentColor = colorDescriptors[getColorIndex()].colorCopy;
2387 				}
2388 
2389 				update();
2390 				break;
2391 			}
2392 
2393 			case BUTTON_COLOR_PREDEF_STORE:
2394 			{
2395 				if (event->getID() != eCommand)
2396 					break;
2397 
2398 				storePalette = !storePalette;
2399 				PPButton* button = reinterpret_cast<PPButton*>(sender);
2400 
2401 				button->setPressed(storePalette);
2402 
2403 				tracker.screen->paintControl(button);
2404 				break;
2405 			}
2406 
2407 			case BUTTON_COLOR_COPY:
2408 			{
2409 				if (event->getID() != eCommand)
2410 					break;
2411 
2412 				if (colorCopy == NULL)
2413 					colorCopy = new PPColor();
2414 
2415 				*colorCopy = currentColor;
2416 				update();
2417 				break;
2418 			}
2419 
2420 			case BUTTON_COLOR_PASTE:
2421 			{
2422 				if (event->getID() != eCommand || colorCopy == NULL)
2423 					break;
2424 
2425 				currentColor = *colorCopy;
2426 				colorDescriptors[getColorIndex()].colorCopy = currentColor;
2427 				update();
2428 				break;
2429 			}
2430 
2431 			case BUTTON_COLOR_DARKER:
2432 			{
2433 				currentColor.scale(0.5f);
2434 				colorDescriptors[getColorIndex()].colorCopy = currentColor;
2435 				update();
2436 				break;
2437 			}
2438 
2439 			case BUTTON_COLOR_BRIGHTER:
2440 			{
2441 				currentColor.scale(2.0f);
2442 				colorDescriptors[getColorIndex()].colorCopy = currentColor;
2443 				update();
2444 				break;
2445 			}
2446 
2447 			case BUTTON_RESOLUTIONS_CUSTOM:
2448 			{
2449 				if (event->getID() != eCommand)
2450 					break;
2451 				showCustomResolutionMessageBox();
2452 				break;
2453 			}
2454 
2455 			case BUTTON_RESOLUTIONS_FULL:
2456 			{
2457 				if (event->getID() != eCommand)
2458 					break;
2459 
2460 				retrieveDisplayResolution();
2461 				break;
2462 			}
2463 
2464 		}
2465 	}
2466 	else if (event->getID() == eValueChanged)
2467 	{
2468 		switch (reinterpret_cast<PPControl*>(sender)->getID())
2469 		{
2470 			case SLIDER_SETTINGS_BUFFERSIZE:
2471 			{
2472 				pp_uint32 v = (reinterpret_cast<PPSlider*>(sender)->getCurrentValue()+1) << 5;
2473 				tracker.settingsDatabase->store("BUFFERSIZE", v);
2474 				update();
2475 				break;
2476 			}
2477 			case SLIDER_SETTINGS_MIXERVOL:
2478 			{
2479 				pp_uint32 v = reinterpret_cast<PPSlider*>(sender)->getCurrentValue();
2480 				tracker.settingsDatabase->store("MIXERVOLUME", v);
2481 				update();
2482 				break;
2483 			}
2484 
2485 			case SLIDER_SPACING:
2486 			{
2487 				pp_uint32 v = reinterpret_cast<PPSlider*>(sender)->getCurrentValue();
2488 				tracker.settingsDatabase->store("SPACING", v);
2489 				update();
2490 				break;
2491 			}
2492 
2493 			case SLIDER_MUTEFADE:
2494 			{
2495 				pp_uint32 v = reinterpret_cast<PPSlider*>(sender)->getCurrentValue();
2496 				tracker.settingsDatabase->store("MUTEFADE", v);
2497 				update();
2498 				break;
2499 			}
2500 
2501 			// Color manipulation
2502 			case SLIDER_COLOR_RED:
2503 				currentColor.r = reinterpret_cast<PPSlider*>(sender)->getCurrentValue();
2504 				colorDescriptors[getColorIndex()].colorCopy = currentColor;
2505 				update();
2506 				break;
2507 			case SLIDER_COLOR_GREEN:
2508 				currentColor.g = reinterpret_cast<PPSlider*>(sender)->getCurrentValue();
2509 				colorDescriptors[getColorIndex()].colorCopy = currentColor;
2510 				update();
2511 				break;
2512 			case SLIDER_COLOR_BLUE:
2513 				currentColor.b = reinterpret_cast<PPSlider*>(sender)->getCurrentValue();
2514 				colorDescriptors[getColorIndex()].colorCopy = currentColor;
2515 				update();
2516 				break;
2517 		}
2518 	}
2519 	else if (event->getID() == eSelection)
2520 	{
2521 		switch (reinterpret_cast<PPControl*>(sender)->getID())
2522 		{
2523 			/*case RADIOGROUP_SETTINGS_PAGE:
2524 			{
2525 				showPage(reinterpret_cast<PPRadioGroup*>(sender)->getChoice());
2526 				update();
2527 				break;
2528 			}*/
2529 
2530 
2531 			case RADIOGROUP_SETTINGS_AMPLIFY:
2532 			{
2533 				pp_int32 v = reinterpret_cast<PPRadioGroup*>(sender)->getChoice();
2534 				tracker.settingsDatabase->store("MIXERSHIFT", v);
2535 				update();
2536 				break;
2537 			}
2538 
2539 			case RADIOGROUP_SETTINGS_MIXFREQ:
2540 			{
2541 				pp_int32 v = reinterpret_cast<PPRadioGroup*>(sender)->getChoice();
2542 
2543 				ASSERT(v >= 0 && v < TrackerConfig::numMixFrequencies);
2544 				tracker.settingsDatabase->store("MIXERFREQ", TrackerConfig::mixFrequencies[v]);
2545 				update();
2546 				break;
2547 			}
2548 
2549 			case RADIOGROUP_SETTINGS_FREQTAB:
2550 			{
2551 				// stop song without resetting main volume
2552 				tracker.ensureSongStopped(false, false);
2553 				pp_uint32 v = reinterpret_cast<PPRadioGroup*>(sender)->getChoice();
2554 				tracker.moduleEditor->setFrequency((ModuleEditor::Frequencies)v);
2555 				update();
2556 				tracker.ensureSongPlaying(true);
2557 				break;
2558 			}
2559 
2560             case RADIOGROUP_SETTINGS_XMCHANNELLIMIT:
2561             {
2562                 pp_int32 v = reinterpret_cast<PPRadioGroup*>(sender)->getChoice();
2563 
2564                 ASSERT(v >= 0 && v < 3);
2565                 tracker.settingsDatabase->store("XMCHANNELLIMIT", 1 << (v + 5));
2566                 update();
2567                 break;
2568             }
2569 
2570 			case RADIOGROUP_SETTINGS_PATTERNFONT:
2571 			{
2572 				pp_int32 v = reinterpret_cast<PPRadioGroup*>(sender)->getChoice();
2573 				tracker.settingsDatabase->store("PATTERNFONT", v);
2574 				update();
2575 				break;
2576 			}
2577 
2578 			case RADIOGROUP_SETTINGS_EDITMODE:
2579 			{
2580 				pp_int32 v = reinterpret_cast<PPRadioGroup*>(sender)->getChoice();
2581 #ifdef __LOWRES__
2582 				if (v != 0)
2583 				{
2584 					SystemMessage message(*tracker.screen, SystemMessage::MessageLimitedInput);
2585 					message.show();
2586 				}
2587 #endif
2588 				tracker.settingsDatabase->store("EDITMODE", v);
2589 				update();
2590 				break;
2591 			}
2592 
2593 			case RADIOGROUP_SETTINGS_SCROLLMODE:
2594 			{
2595 				pp_int32 v = reinterpret_cast<PPRadioGroup*>(sender)->getChoice();
2596 				tracker.settingsDatabase->store("SCROLLMODE", v);
2597 				update();
2598 				break;
2599 			}
2600 
2601 			case RADIOGROUP_SETTINGS_SCOPESAPPEARANCE:
2602 			{
2603 				pp_int32 v = reinterpret_cast<PPRadioGroup*>(sender)->getChoice();
2604 				pp_int32 res = (tracker.settingsDatabase->restore("SCOPES")->getIntValue() & 1) | (v << 1);
2605 				tracker.settingsDatabase->store("SCOPES", res);
2606 				update();
2607 				break;
2608 			}
2609 
2610 			case RADIOGROUP_SETTINGS_MAGNIFY:
2611 			{
2612 				pp_int32 v = reinterpret_cast<PPRadioGroup*>(sender)->getChoice();
2613 				tracker.settingsDatabase->store("SCREENSCALEFACTOR", 1 << v);
2614 				update();
2615 				break;
2616 			}
2617 
2618 			case LISTBOX_SETTINGS_RESOLUTIONS:
2619 			{
2620 				pp_int32 v = *((pp_int32*)event->getDataPtr());
2621 				if (v < NUMRESOLUTIONS-1)
2622 				{
2623 					tracker.settingsDatabase->store("XRESOLUTION", resolutions[v].width);
2624 					tracker.settingsDatabase->store("YRESOLUTION", resolutions[v].height);
2625 				}
2626 				update();
2627 			}
2628 
2629 			case LISTBOX_COLORS:
2630 			{
2631 				currentColor = colorDescriptors[getColorIndex()].colorCopy;
2632 				update();
2633 				break;
2634 			}
2635 
2636 			case LISTBOX_SETTINGS_FONTFAMILIES:
2637 			{
2638 				enumerateFontFacesInListBox(*((pp_int32*)event->getDataPtr()));
2639 				update();
2640 				break;
2641 			}
2642 
2643 			case LISTBOX_SETTINGS_FONTENTRIES:
2644 			{
2645 				pp_int32 index = *((pp_int32*)event->getDataPtr());
2646 				//PPFont::selectFontFace((PPFont::FontID)listBoxFontFamilies->getSelectedIndex(), listBoxFontEntries->getItem(index));
2647 				tracker.settingsDatabase->store(PPFont::getFamilyInternalName((PPFont::FontID)listBoxFontFamilies->getSelectedIndex()), listBoxFontEntries->getItem(index));
2648 				update();
2649 				break;
2650 			}
2651 
2652 			case RADIOGROUP_SETTINGS_STOPBACKGROUNDBEHAVIOUR:
2653 			{
2654 				pp_int32 v = reinterpret_cast<PPRadioGroup*>(sender)->getChoice();
2655 				tracker.settingsDatabase->store("TABS_STOPBACKGROUNDBEHAVIOUR", v);
2656 				update();
2657 				break;
2658 			}
2659 		}
2660 	}
2661 
2662 	return 0;
2663 }
2664 
showSection(bool bShow)2665 void SectionSettings::showSection(bool bShow)
2666 {
2667 	sectionContainer->show(bShow);
2668 }
2669 
show(bool bShow)2670 void SectionSettings::show(bool bShow)
2671 {
2672 	SectionAbstract::show(bShow);
2673 
2674 	PPScreen* screen = tracker.screen;
2675 
2676 	visible = bShow;
2677 
2678 	if (!initialised)
2679 	{
2680 		init();
2681 	}
2682 
2683 	if (initialised)
2684 	{
2685 		PatternEditorControl* control = tracker.getPatternEditorControl();
2686 		if (bShow)
2687 		{
2688 			tracker.showMainMenu(false, true);
2689 			update(false);
2690 			if (control)
2691 			{
2692 /*#ifndef
2693 				control->setLocation(PPPoint(0, SECTIONHEIGHT));
2694 				control->setSize(PPSize(screen->getWidth(),screen->getHeight()-SECTIONHEIGHT));*/
2695 #ifdef __LOWRES__
2696 				control->setLocation(PPPoint(0, 0));
2697 				control->setSize(PPSize(screen->getWidth(),tracker.MAXEDITORHEIGHT()-SECTIONHEIGHT));
2698 #endif
2699 			}
2700 			tracker.hideInputControl();
2701 
2702 			// backup current palette
2703 			saveCurrentGlobalPalette();
2704 			updateColors();
2705 			// backup current color
2706 			currentColor = colorDescriptors[getColorIndex()].colorCopy;
2707 
2708 			// backup current mixer settings
2709 			saveCurrentMixerSettings(*mixerSettings);
2710 		}
2711 		else
2712 		{
2713 			tracker.showMainMenu(true, true);
2714 			tracker.rearrangePatternEditorControl();
2715 		}
2716 
2717 		showSection(bShow);
2718 
2719 		// why should we do that? just show the last active tab
2720 		//showPage(0);
2721 
2722 		screen->paint();
2723 	}
2724 }
2725 
cancelSettings()2726 void SectionSettings::cancelSettings()
2727 {
2728 	restoreCurrentGlobalPalette();
2729 	restoreCurrentMixerSettings();
2730 
2731 	if (tracker.settingsDatabaseCopy)
2732 	{
2733 		tracker.applySettings(tracker.settingsDatabaseCopy, tracker.settingsDatabase, false);
2734 		delete tracker.settingsDatabase;
2735 		tracker.settingsDatabase = tracker.settingsDatabaseCopy;
2736 		tracker.settingsDatabaseCopy = NULL;
2737 	}
2738 	show(false);
2739 }
2740 
init()2741 void SectionSettings::init()
2742 {
2743 #ifndef __LOWRES__
2744 	init(0,0);
2745 #else
2746 	init(0,tracker.screen->getHeight()-SECTIONHEIGHT);
2747 #endif
2748 }
2749 
init(pp_int32 x,pp_int32 y)2750 void SectionSettings::init(pp_int32 x, pp_int32 y)
2751 {
2752 	pp_int32 i;
2753 
2754 	PPScreen* screen = tracker.screen;
2755 
2756 	pp_int32 y2 = y;
2757 
2758 	sectionContainer = new PPContainer(CONTAINER_SETTINGS, screen, this, PPPoint(x, y2), PPSize(screen->getWidth(),SECTIONHEIGHT), false);
2759 	static_cast<PPContainer*>(sectionContainer)->setColor(TrackerConfig::colorThemeMain);
2760 
2761 #ifdef __LOWRES__
2762 	pp_int32 x2 = 0;
2763 #else
2764 	pp_int32 x2 = 160;
2765 #endif
2766 
2767 	while (x2 < screen->getWidth())
2768 	{
2769 		sectionContainer->addControl(new PPSeperator(0, screen, PPPoint(x2 + 158, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
2770 
2771 		x2+=TabPage::getWidth();
2772 	}
2773 
2774 	tabPages.get(0)->add(new TabPageIO_1(PAGE_IO_1, *this));
2775 	tabPages.get(0)->add(new TabPageIO_2(PAGE_IO_2, *this));
2776 	tabPages.get(0)->add(new TabPageIO_3(PAGE_IO_3, *this));
2777 #ifndef __LOWRES__
2778     tabPages.get(0)->add(new TabPageIO_4(PAGE_IO_4, *this));
2779 #endif
2780 
2781 	tabPages.get(1)->add(new TabPageLayout_1(PAGE_LAYOUT_1, *this));
2782 	tabPages.get(1)->add(new TabPageLayout_2(PAGE_LAYOUT_2, *this));
2783 #ifndef __LOWRES__
2784 	tabPages.get(1)->add(new TabPageLayout_3(PAGE_LAYOUT_3, *this));
2785 	tabPages.get(1)->add(new TabPageLayout_4(PAGE_LAYOUT_4, *this));
2786 #endif
2787 
2788 	tabPages.get(2)->add(new TabPageFonts_1(PAGE_FONTS_1, *this));
2789 	tabPages.get(2)->add(new TabPageFonts_2(PAGE_FONTS_2, *this));
2790 
2791 	tabPages.get(3)->add(new TabPageMisc_1(PAGE_MISC_1, *this));
2792 	tabPages.get(3)->add(new TabPageMisc_2(PAGE_MISC_2, *this));
2793 	tabPages.get(3)->add(new TabPageMisc_3(PAGE_MISC_3, *this));
2794 	tabPages.get(3)->add(new TabPageMisc_4(PAGE_MISC_4, *this));
2795 
2796 #ifndef __LOWRES__
2797 	tabPages.get(4)->add(new TabPageTabs_1(PAGE_TABS_1, *this));
2798 #endif
2799 
2800 	for (i = 0; i < tabPages.size(); i++)
2801 		for (pp_int32 j = 0; j < tabPages.get(i)->size(); j++)
2802 		{
2803 			tabPages.get(i)->get(j)->init(screen);
2804 			sectionContainer->addControl(tabPages.get(i)->get(j)->getContainer());
2805 		}
2806 
2807 	PPButton* button;
2808 
2809 	const pp_int32 numSettingsPages = NUMSETTINGSPAGES;
2810 
2811 #ifndef __LOWRES__
2812 	const char* subSettingsTexts[] = {"I/O","Layout","Fonts","Misc.","Tabs"};
2813 
2814 	x2 = x;
2815 
2816 	static_cast<PPContainer*>(sectionContainer)->addControl(new PPSeperator(0, screen, PPPoint(x2 + 156, y+4), SECTIONHEIGHT-8, TrackerConfig::colorThemeMain, false));
2817 	static_cast<PPContainer*>(sectionContainer)->addControl(new PPSeperator(0, screen, PPPoint(x2 - 2, y+SECTIONHEIGHT-2-12-6), 157, TrackerConfig::colorThemeMain, true));
2818 
2819 	pp_int32 bWidth = 140 - 14*2;
2820 	pp_int32 bHeight = ((SECTIONHEIGHT - 2-12-6) - 8) / numSettingsPages;
2821 
2822 	pp_int32 sx = x2 + 10;
2823 	pp_int32 sy = y2 + 4;
2824 
2825 	for (i = 0; i < numSettingsPages; i++)
2826 	{
2827 		button = new PPButton(PAGE_BUTTON_0+i, screen, this, PPPoint(sx, sy), PPSize(bWidth, bHeight), false, true, false);
2828 		button->setColor(TrackerConfig::colorThemeMain);
2829 		button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
2830 		button->setText(subSettingsTexts[i]);
2831 		static_cast<PPContainer*>(sectionContainer)->addControl(button);
2832 
2833 		button = new PPButton(SUBPAGE_BUTTON_LEFT_0+i, screen, this, PPPoint(sx+140-14*2+1, sy), PPSize(14, bHeight), false);
2834 		button->setColor(TrackerConfig::colorThemeMain);
2835 		button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
2836 		button->setText("<");
2837 		static_cast<PPContainer*>(sectionContainer)->addControl(button);
2838 
2839 		button = new PPButton(SUBPAGE_BUTTON_RIGHT_0+i, screen, this, PPPoint(sx+140-14+1, sy), PPSize(14, bHeight), false);
2840 		button->setColor(TrackerConfig::colorThemeMain);
2841 		button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
2842 		button->setText(">");
2843 		static_cast<PPContainer*>(sectionContainer)->addControl(button);
2844 
2845 		sy+=bHeight;
2846 	}
2847 	x2++;
2848 
2849 #else
2850 	const char* subSettingsTexts[] = {"I/O","Layout","Fonts","Misc."};
2851 
2852 	x2 = screen->getWidth()-160 + 4;
2853 
2854 	//static_cast<PPContainer*>(sectionContainer)->addControl(new PPSeperator(0, screen, PPPoint(x2 - 4, y+4), UPPERFRAMEHEIGHT-8, TrackerConfig::colorThemeMain, false));
2855 	static_cast<PPContainer*>(sectionContainer)->addControl(new PPSeperator(0, screen, PPPoint(x + 2, y+UPPERFRAMEHEIGHT-4), screen->getWidth()-4, TrackerConfig::colorThemeMain, true));
2856 
2857 	pp_int32 bWidth = (screen->getWidth()-8-26) / numSettingsPages;
2858 	pp_int32 bHeight = 13;
2859 
2860 	pp_int32 sx = x + 4;
2861 	pp_int32 sy = y + UPPERFRAMEHEIGHT;
2862 
2863 	for (i = 0; i < numSettingsPages; i++)
2864 	{
2865 		button = new PPButton(PAGE_BUTTON_0+i, screen, this, PPPoint(sx, sy), PPSize(bWidth, bHeight), false, true, false);
2866 		button->setColor(TrackerConfig::colorThemeMain);
2867 		button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
2868 		button->setText(subSettingsTexts[i]);
2869 		static_cast<PPContainer*>(sectionContainer)->addControl(button);
2870 		sx+=bWidth;
2871 	}
2872 
2873 	sx+=1;
2874 	button = new PPButton(SUBPAGE_BUTTON_LEFT_0, screen, this, PPPoint(sx, sy), PPSize(13, bHeight), false);
2875 	button->setColor(TrackerConfig::colorThemeMain);
2876 	button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
2877 	button->setText("<");
2878 	static_cast<PPContainer*>(sectionContainer)->addControl(button);
2879 
2880 	button = new PPButton(SUBPAGE_BUTTON_RIGHT_0, screen, this, PPPoint(sx+13, sy), PPSize(13, bHeight), false);
2881 	button->setColor(TrackerConfig::colorThemeMain);
2882 	button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
2883 	button->setText(">");
2884 	static_cast<PPContainer*>(sectionContainer)->addControl(button);
2885 
2886 	//static_cast<PPContainer*>(sectionContainer)->addControl(new PPSeperator(0, screen, PPPoint(x + 2, sy + bHeight + 1), screen->getWidth()-4, TrackerConfig::colorThemeMain, true));
2887 #endif
2888 
2889 	button = new PPButton(BUTTON_SETTINGS_OK, screen, this, PPPoint(x2+3, y+SECTIONHEIGHT-2-12), PPSize(46, 11));
2890 	button->setText("Ok");
2891 
2892 	static_cast<PPContainer*>(sectionContainer)->addControl(button);
2893 
2894 	button = new PPButton(BUTTON_SETTINGS_APPLY, screen, this, PPPoint(x2+3+48, y+SECTIONHEIGHT-2-12), PPSize(48, 11));
2895 	button->setText("Apply");
2896 
2897 	static_cast<PPContainer*>(sectionContainer)->addControl(button);
2898 
2899 	button = new PPButton(BUTTON_SETTINGS_CANCEL, screen, this, PPPoint(x2+3+48+50, y+SECTIONHEIGHT-2-12), PPSize(50, 11));
2900 	button->setText("Cancel");
2901 
2902 	static_cast<PPContainer*>(sectionContainer)->addControl(button);
2903 
2904 	screen->addControl(sectionContainer);
2905 
2906 	initialised = true;
2907 
2908 	showPage(0, 0);
2909 
2910 	showSection(false);
2911 }
2912 
update(bool repaint)2913 void SectionSettings::update(bool repaint/* = true*/)
2914 {
2915 	if (!initialised || !visible)
2916 		return;
2917 
2918 	pp_int32 i, j;
2919 
2920 #ifdef __LOWRES__
2921 	pp_int32 x = 0;
2922 #else
2923 	pp_int32 x = 160;
2924 #endif
2925 	pp_int32 y = sectionContainer->getLocation().y;
2926 
2927 #ifdef __LOWRES__
2928 	static_cast<PPButton*>(sectionContainer->getControlByID(SUBPAGE_BUTTON_LEFT_0))->enable(false);
2929 	static_cast<PPButton*>(sectionContainer->getControlByID(SUBPAGE_BUTTON_RIGHT_0))->enable(false);
2930 #endif
2931 
2932 	// hide all tab pages first
2933 	for (i = 0; i < tabPages.size(); i++)
2934 	{
2935 		for (j = 0; j < tabPages.get(i)->size(); j++)
2936 		{
2937 			tabPages.get(i)->get(j)->getContainer()->show(false);
2938 			tabPages.get(i)->get(j)->setVisible(false);
2939 		}
2940 
2941 #ifndef __LOWRES__
2942 		static_cast<PPButton*>(sectionContainer->getControlByID(SUBPAGE_BUTTON_LEFT_0+i))->enable(false);
2943 		static_cast<PPButton*>(sectionContainer->getControlByID(SUBPAGE_BUTTON_RIGHT_0+i))->enable(false);
2944 #endif
2945 	}
2946 
2947 	PPPoint location(x, y);
2948 
2949 	pp_int32 lastVisiblePage = 0;
2950 
2951 	for (j = 0; j < tabPages.get(currentActiveTabNum)->size(); j++)
2952 	{
2953 		if (j + currentActivePageStart < tabPages.get(currentActiveTabNum)->size())
2954 		{
2955 			TabPage* page = tabPages.get(currentActiveTabNum)->get(j + currentActivePageStart);
2956 			page->setLocation(location);
2957 
2958 			location.x+=TabPage::getWidth();
2959 
2960 			if (location.x <= tracker.screen->getWidth())
2961 			{
2962 				page->getContainer()->show(true);
2963 				page->setVisible(true);
2964 				lastVisiblePage = j + currentActivePageStart;
2965 			}
2966 		}
2967 		else
2968 		{
2969 			location.x+=TabPage::getWidth();
2970 		}
2971 	}
2972 
2973 	i = currentActiveTabNum;
2974 #ifdef __LOWRES__
2975 	i = 0;
2976 #endif
2977 	PPButton* button = static_cast<PPButton*>(sectionContainer->getControlByID(SUBPAGE_BUTTON_RIGHT_0+i));
2978 	button->enable(lastVisiblePage < tabPages.get(currentActiveTabNum)->size() - 1);
2979 
2980 	button = static_cast<PPButton*>(sectionContainer->getControlByID(SUBPAGE_BUTTON_LEFT_0+i));
2981 	button->enable(currentActivePageStart > 0);
2982 
2983 	// update all visible pages
2984 	for (i = 0; i < tabPages.size(); i++)
2985 	{
2986 		for (j = 0; j < tabPages.get(i)->size(); j++)
2987 			if (tabPages.get(i)->get(j)-isVisible())
2988 			{
2989 				tabPages.get(i)->get(j)->update(tracker.screen, tracker.settingsDatabase, *tracker.moduleEditor);
2990 			}
2991 
2992 	}
2993 
2994 
2995 	tracker.screen->paintControl(sectionContainer, false);
2996 
2997 	if (repaint)
2998 		tracker.screen->update();
2999 }
3000 
showPage(pp_int32 page,pp_int32 subPage)3001 void SectionSettings::showPage(pp_int32 page, pp_int32 subPage/* = 0*/)
3002 {
3003 	currentActiveTabNum = page;
3004 	currentActivePageStart = subPage;
3005 
3006 	currentActiveSubPageNum[currentActiveTabNum] = subPage;
3007 
3008 	for (pp_int32 i = 0; i < NUMSETTINGSPAGES; i++)
3009 		static_cast<PPButton*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(PAGE_BUTTON_0+i))->setPressed(false);
3010 
3011 	static_cast<PPButton*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(PAGE_BUTTON_0+page))->setPressed(true);
3012 
3013 	currentActiveSubPageNum[currentActiveTabNum] = subPage;
3014 }
3015 
initColorDescriptors()3016 void SectionSettings::initColorDescriptors()
3017 {
3018 	for (pp_int32 i = 0; i < GlobalColorConfig::ColorLast; i++)
3019 		colorDescriptors[i].readableDecription = GlobalColorConfig::getInstance()->getColorReadableDescription((GlobalColorConfig::GlobalColors)i);
3020 }
3021 
updateColors()3022 void SectionSettings::updateColors()
3023 {
3024 	for (pp_int32 i = 0; i < GlobalColorConfig::ColorLast; i++)
3025 		colorDescriptors[i].colorCopy = GlobalColorConfig::getInstance()->getColor((GlobalColorConfig::GlobalColors)i);
3026 }
3027 
getNumPredefinedColorPalettes()3028 pp_int32 SectionSettings::getNumPredefinedColorPalettes()
3029 {
3030 	return TrackerConfig::numPredefinedColorPalettes;
3031 }
3032 
getEncodedPalette(pp_int32 index)3033 PPString SectionSettings::getEncodedPalette(pp_int32 index)
3034 {
3035 	return ColorPaletteContainer::encodePalette(*predefinedColorPalettes->restore(index));
3036 }
3037 
setEncodedPalette(pp_int32 index,const PPString & str)3038 void SectionSettings::setEncodedPalette(pp_int32 index, const PPString& str)
3039 {
3040 	TColorPalette p = ColorPaletteContainer::decodePalette(str);
3041 
3042 	predefinedColorPalettes->store(index, p);
3043 }
3044 
storeCurrentPaletteToDatabase()3045 void SectionSettings::storeCurrentPaletteToDatabase()
3046 {
3047 	TColorPalette pal;
3048 
3049 	pal.numColors = GlobalColorConfig::ColorLast;
3050 	for (pp_int32 j = 0; j < pal.numColors; j++)
3051 		pal.colors[j] = colorDescriptors[j].colorCopy;
3052 
3053 	tracker.settingsDatabase->store("ACTIVECOLORS", ColorPaletteContainer::encodePalette(pal));
3054 }
3055 
saveCurrentGlobalPalette()3056 void SectionSettings::saveCurrentGlobalPalette()
3057 {
3058 	palette->numColors = GlobalColorConfig::ColorLast;
3059 	for (pp_int32 i = 0; i < GlobalColorConfig::ColorLast; i++)
3060 	{
3061 		if (i < palette->numColors)
3062 			palette->colors[i] = GlobalColorConfig::getInstance()->getColor((GlobalColorConfig::GlobalColors)i);
3063 	}
3064 }
3065 
restoreCurrentGlobalPalette()3066 void SectionSettings::restoreCurrentGlobalPalette()
3067 {
3068 	for (pp_int32 i = 0; i < palette->numColors; i++)
3069 	{
3070 		if (i < GlobalColorConfig::ColorLast)
3071 			GlobalColorConfig::getInstance()->setColor((GlobalColorConfig::GlobalColors)i, palette->colors[i]);
3072 	}
3073 }
3074 
updateCurrentColors()3075 void SectionSettings::updateCurrentColors()
3076 {
3077 	for (pp_int32 i = 0; i < GlobalColorConfig::ColorLast; i++)
3078 		GlobalColorConfig::getInstance()->setColor((GlobalColorConfig::GlobalColors)i, colorDescriptors[i].colorCopy);
3079 
3080 	tracker.screen->paint();
3081 }
3082 
restorePalettes()3083 void SectionSettings::restorePalettes()
3084 {
3085 	pp_int32 i;
3086 	for (i = 0; i < getNumPredefinedColorPalettes(); i++)
3087 	{
3088 		predefinedColorPalettes->store(i, ColorPaletteContainer::decodePalette(TrackerConfig::predefinedColorPalettes[i]));
3089 	}
3090 
3091 	*palette = ColorPaletteContainer::decodePalette(TrackerConfig::predefinedColorPalettes[0]);
3092 	restoreCurrentGlobalPalette();
3093 
3094 	for (i = 0; i < palette->numColors; i++)
3095 		if (i < GlobalColorConfig::ColorLast)
3096 			colorDescriptors[i].colorCopy = palette->colors[i];
3097 
3098 	currentColor = colorDescriptors[getColorIndex()].colorCopy;
3099 
3100 	tracker.screen->paint();
3101 }
3102 
saveCurrentMixerSettings(TMixerSettings & settings)3103 void SectionSettings::saveCurrentMixerSettings(TMixerSettings& settings)
3104 {
3105 	tracker.getMixerSettingsFromDatabase(settings, *tracker.settingsDatabase);
3106 }
3107 
restoreCurrentMixerSettings()3108 void SectionSettings::restoreCurrentMixerSettings()
3109 {
3110 	TMixerSettings newMixerSettings;
3111 	tracker.getMixerSettingsFromDatabase(newMixerSettings, *tracker.settingsDatabase);
3112 
3113 	if (*mixerSettings != newMixerSettings)
3114 	{
3115 		bool res = tracker.playerMaster->applyNewMixerSettings(*mixerSettings, true);
3116 		if (!res)
3117 		{
3118 			SystemMessage message(*tracker.screen, SystemMessage::MessageSoundDriverInitFailed);
3119 			message.show();
3120 		}
3121 	}
3122 }
3123 
showCustomResolutionMessageBox()3124 void SectionSettings::showCustomResolutionMessageBox()
3125 {
3126 	if (dialog)
3127 	{
3128 		delete dialog;
3129 		dialog = NULL;
3130 	}
3131 
3132 	dialog = new DialogWithValues(tracker.screen,
3133 								  responder,
3134 								  RESPONDMESSAGEBOX_CUSTOMRESOLUTION,
3135 								  "Enter custom resolution" PPSTR_PERIODS,
3136 								  DialogWithValues::ValueStyleEnterTwoValues);
3137 
3138 	static_cast<DialogWithValues*>(dialog)->setValueOneCaption("Width in pixels:");
3139 	static_cast<DialogWithValues*>(dialog)->setValueTwoCaption("Height in pixels:");
3140 	static_cast<DialogWithValues*>(dialog)->setValueOneRange(MINWIDTH, 10000.0f, 0);
3141 	static_cast<DialogWithValues*>(dialog)->setValueTwoRange(MINHEIGHT, 10000.0f, 0);
3142 	static_cast<DialogWithValues*>(dialog)->setValueOneIncreaseStep(1.0f);
3143 	static_cast<DialogWithValues*>(dialog)->setValueTwoIncreaseStep(1.0f);
3144 
3145 	pp_int32 width = tracker.settingsDatabase->restore("XRESOLUTION")->getIntValue();
3146 	pp_int32 height = tracker.settingsDatabase->restore("YRESOLUTION")->getIntValue();
3147 
3148 	static_cast<DialogWithValues*>(dialog)->setValueOne((float)width);
3149 	static_cast<DialogWithValues*>(dialog)->setValueTwo((float)height);
3150 
3151 	dialog->show();
3152 }
3153 
showRestorePaletteMessageBox()3154 void SectionSettings::showRestorePaletteMessageBox()
3155 {
3156 	if (dialog)
3157 	{
3158 		delete dialog;
3159 		dialog = NULL;
3160 	}
3161 
3162 	dialog = new PPDialogBase(tracker.screen,
3163 							  responder,
3164 							  RESPONDMESSAGEBOX_RESTOREPALETTES,
3165 							  "Restore all default palettes?");
3166 	dialog->show();
3167 }
3168 
showSelectDriverMessageBox()3169 void SectionSettings::showSelectDriverMessageBox()
3170 {
3171 	if (dialog)
3172 	{
3173 		delete dialog;
3174 		dialog = NULL;
3175 	}
3176 
3177 	dialog = new DialogListBox(tracker.screen,
3178 							   responder,
3179 							   RESPONDMESSAGEBOX_SELECTAUDIODRV,
3180 							   "Select audio driver",
3181 							   true);
3182 	PPListBox* listBox = static_cast<DialogListBox*>(dialog)->getListBox();
3183 
3184 	mp_sint32 i = 0;
3185 	mp_sint32 selectedIndex = -1;
3186 	const char* name = tracker.playerMaster->getFirstDriverName();
3187 	//const char* curDrvName = tracker.playerController->getCurrentDriverName();
3188 
3189 	const char* curDrvName = tracker.settingsDatabase->restore("AUDIODRIVER")->getStringValue();
3190 
3191 	while (name)
3192 	{
3193 		if (strcmp(name, curDrvName) == 0)
3194 			selectedIndex = i;
3195 		listBox->addItem(name);
3196 		name = tracker.playerMaster->getNextDriverName();
3197 		i++;
3198 	}
3199 
3200 	if (selectedIndex != -1)
3201 		listBox->setSelectedIndex(selectedIndex, false);
3202 
3203 	dialog->show();
3204 }
3205 
showResamplerMessageBox()3206 void SectionSettings::showResamplerMessageBox()
3207 {
3208 	if (dialog)
3209 	{
3210 		delete dialog;
3211 		dialog = NULL;
3212 	}
3213 
3214 	dialog = new DialogListBox(tracker.screen,
3215 							   responder,
3216 							   RESPONDMESSAGEBOX_SELECTRESAMPLER,
3217 							   "Select Resampler",
3218 							   true);
3219 	PPListBox* listBox = static_cast<DialogListBox*>(dialog)->getListBox();
3220 
3221 	ResamplerHelper resamplerHelper;
3222 	for (pp_uint32 i = 0; i < resamplerHelper.getNumResamplers(); i++)
3223 		listBox->addItem(resamplerHelper.getResamplerName(i));
3224 
3225 	listBox->setSelectedIndex(tracker.settingsDatabase->restore("INTERPOLATION")->getIntValue(), false);
3226 
3227 	dialog->show();
3228 }
3229 
storeAudioDriver(const char * driverName)3230 void SectionSettings::storeAudioDriver(const char* driverName)
3231 {
3232 	const char* curDrvName = tracker.playerMaster->getCurrentDriverName();
3233 	if (strcmp(curDrvName, driverName) != 0)
3234 	{
3235 		tracker.settingsDatabase->store("AUDIODRIVER", driverName);
3236 
3237 		TMixerSettings newMixerSettings;
3238 		saveCurrentMixerSettings(newMixerSettings);
3239 		bool res = tracker.playerMaster->applyNewMixerSettings(newMixerSettings, true);
3240 		if (!res)
3241 		{
3242 			SystemMessage message(*tracker.screen, SystemMessage::MessageSoundDriverInitFailed);
3243 			message.show();
3244 		}
3245 	}
3246 	update();
3247 }
3248 
storeResampler(pp_uint32 resampler)3249 void SectionSettings::storeResampler(pp_uint32 resampler)
3250 {
3251 	tracker.settingsDatabase->store("INTERPOLATION", resampler);
3252 
3253 	TMixerSettings newMixerSettings;
3254 	newMixerSettings.resampler = resampler;
3255 	bool res = tracker.playerMaster->applyNewMixerSettings(newMixerSettings, true);
3256 	if (!res)
3257 	{
3258 		SystemMessage message(*tracker.screen, SystemMessage::MessageSoundDriverInitFailed);
3259 		message.show();
3260 	}
3261 }
3262 
enumerateFontFacesInListBox(pp_uint32 fontID)3263 void SectionSettings::enumerateFontFacesInListBox(pp_uint32 fontID)
3264 {
3265 	listBoxFontEntries->clear();
3266 	const char* name = PPFont::getFirstFontEntryName((PPFont::FontID)fontID);
3267 	while (name)
3268 	{
3269 		listBoxFontEntries->addItem(name);
3270 		name = PPFont::getNextFontEntryName((PPFont::FontID)fontID);
3271 	}
3272 }
3273 
storeCustomResolution()3274 void SectionSettings::storeCustomResolution()
3275 {
3276 	pp_int32 width = (pp_int32)static_cast<DialogWithValues*>(dialog)->getValueOne();
3277 	pp_int32 height = (pp_int32)static_cast<DialogWithValues*>(dialog)->getValueTwo();
3278 
3279 	if (width < MINWIDTH)
3280 		width = MINWIDTH;
3281 	if (height < MINHEIGHT)
3282 		height = MINHEIGHT;
3283 
3284 	tracker.settingsDatabase->store("XRESOLUTION", width);
3285 	tracker.settingsDatabase->store("YRESOLUTION", height);
3286 
3287 	update();
3288 }
3289 
importCurrentColorPalette()3290 void SectionSettings::importCurrentColorPalette()
3291 {
3292 	FileExtProvider fileExtProvider;
3293 
3294 	PPOpenPanel panel(tracker.screen, "Open colors");
3295 
3296 	panel.addExtensions(fileExtProvider.getColorExtensions());
3297 
3298 	if (panel.runModal() == PPModalDialog::ReturnCodeOK)
3299 	{
3300 		TColorPalette pal;
3301 		ColorExportImport exportImport(panel.getFileName());
3302 
3303 		if (exportImport.importColorPalette(pal))
3304 		{
3305 			for (pp_int32 j = 0; j < pal.numColors; j++)
3306 				colorDescriptors[j].colorCopy = pal.colors[j];
3307 
3308 			currentColor = colorDescriptors[getColorIndex()].colorCopy;
3309 
3310 			update();
3311 
3312 			lastColorFile = panel.getFileName();
3313 		}
3314 		else
3315 		{
3316 			tracker.showMessageBox(MESSAGEBOX_UNIVERSAL, "Unrecognized type/corrupt file", Tracker::MessageBox_OK);
3317 		}
3318 	}
3319 }
3320 
exportCurrentColorPalette()3321 void SectionSettings::exportCurrentColorPalette()
3322 {
3323 	FileExtProvider fileExtProvider;
3324 
3325 	PPSystemString fileName = lastColorFile.stripPath().stripExtension();
3326 	fileName.append(".");
3327 	fileName.append(fileExtProvider.getColorExtension(FileExtProvider::ColorExtensionMCT));
3328 
3329 	PPSavePanel panel(tracker.screen, "Save colors", fileName);
3330 
3331 	panel.addExtensions(fileExtProvider.getColorExtensions());
3332 
3333 	if (panel.runModal() == PPModalDialog::ReturnCodeOK)
3334 	{
3335 		TColorPalette pal;
3336 
3337 		pal.numColors = GlobalColorConfig::ColorLast;
3338 		for (pp_int32 j = 0; j < pal.numColors; j++)
3339 			pal.colors[j] = colorDescriptors[j].colorCopy;
3340 
3341 		ColorExportImport exportImport(panel.getFileName());
3342 
3343 		if (!exportImport.exportColorPalette(pal))
3344 		{
3345 			tracker.showMessageBox(MESSAGEBOX_UNIVERSAL, "Could not create file", Tracker::MessageBox_OK);
3346 		}
3347 	}
3348 }
3349 
retrieveDisplayResolution()3350 void SectionSettings::retrieveDisplayResolution()
3351 {
3352 	PPSize size = tracker.screen->getDisplayResolution();
3353 
3354 	if (size.width > 0 && size.height > 0)
3355 	{
3356 
3357 		if (size.width < MINWIDTH)
3358 			size.width = MINWIDTH;
3359 		if (size.height < MINHEIGHT)
3360 			size.height = MINHEIGHT;
3361 
3362 		tracker.settingsDatabase->store("XRESOLUTION", size.width);
3363 		tracker.settingsDatabase->store("YRESOLUTION", size.height);
3364 
3365 		update();
3366 	}
3367 	else
3368 	{
3369 		tracker.showMessageBox(MESSAGEBOX_UNIVERSAL, "Could not retrieve display resolution", Tracker::MessageBox_OK);
3370 	}
3371 }
3372