1 /*
2  *  tracker/SectionDiskMenu.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  *  SectionDiskMenu.cpp
25  *  MilkyTracker
26  *
27  *  Created by Peter Barth on 08.07.05.
28  *
29  */
30 
31 #include "SectionDiskMenu.h"
32 #include "Tracker.h"
33 #include "TrackerConfig.h"
34 #include "TrackerSettingsDatabase.h"
35 #include "ModuleEditor.h"
36 #include "GlobalColorConfig.h"
37 
38 #include "Container.h"
39 #include "MessageBoxContainer.h"
40 #include "RadioGroup.h"
41 #include "Seperator.h"
42 #include "Slider.h"
43 #include "StaticText.h"
44 #include "ListBox.h"
45 #include "ListBoxFileBrowser.h"
46 #include "CheckBox.h"
47 #include "CheckBoxLabel.h"
48 #include "PPUIConfig.h"
49 #include "PatternEditorControl.h"
50 
51 #include "SectionSwitcher.h"
52 #include "SectionHDRecorder.h"
53 
54 #include "DialogBase.h"
55 
56 #include "PatternTools.h"
57 #include "Tools.h"
58 #include "PPPath.h"
59 #include "XMFile.h"
60 #include "PPSavePanel.h"
61 
62 #include "FileExtProvider.h"
63 
64 #include "ControlIDs.h"
65 
66 enum ControlIDs
67 {
68 	DISKMENU_BUTTON_FLIP = 7000,
69 	DISKMENU_BUTTON_EXIT,
70 
71 	DISKMENU_NORMAL_STATICTEXT_HEADING,
72 	DISKMENU_NORMAL_BUTTON_LOAD_SONG,
73 	DISKMENU_NORMAL_BUTTON_SAVE_SONG,
74 	DISKMENU_NORMAL_BUTTON_LOAD_PATTERN,
75 	DISKMENU_NORMAL_BUTTON_SAVE_PATTERN,
76 	DISKMENU_NORMAL_BUTTON_LOAD_TRACK,
77 	DISKMENU_NORMAL_BUTTON_SAVE_TRACK,
78 	DISKMENU_NORMAL_BUTTON_LOAD_INSTRUMENT,
79 	DISKMENU_NORMAL_BUTTON_SAVE_INSTRUMENT,
80 	DISKMENU_NORMAL_BUTTON_LOAD_SAMPLE,
81 	DISKMENU_NORMAL_BUTTON_SAVE_SAMPLE,
82 
83 	DISKMENU_NORMAL_RADIOGROUP_SONGTYPE,
84 	DISKMENU_NORMAL_RADIOGROUP_PATTERNTYPE,
85 	DISKMENU_NORMAL_RADIOGROUP_TRACKTYPE,
86 	DISKMENU_NORMAL_RADIOGROUP_INSTRUMENTTYPE,
87 	DISKMENU_NORMAL_RADIOGROUP_SAMPLETYPE,
88 
89 	DISKMENU_CLASSIC_STATICTEXT_HEADING,
90 	DISKMENU_CLASSIC_BUTTON_TYPE_TYPE,
91 	DISKMENU_CLASSIC_BUTTON_TYPE_MODULE,
92 	DISKMENU_CLASSIC_BUTTON_TYPE_INSTRUMENT,
93 	DISKMENU_CLASSIC_BUTTON_TYPE_SAMPLE,
94 	DISKMENU_CLASSIC_BUTTON_TYPE_PATTERN,
95 	DISKMENU_CLASSIC_BUTTON_TYPE_TRACK,
96 	DISKMENU_CLASSIC_BUTTON_SAVE,
97 	DISKMENU_CLASSIC_LISTBOX_NAME,
98 	DISKMENU_CLASSIC_LISTBOX_BROWSER,
99 
100 	DISKMENU_CLASSIC_BUTTON_PREV,
101 	DISKMENU_CLASSIC_BUTTON_NEXT,
102 	DISKMENU_CLASSIC_BUTTON_PARENT,
103 	DISKMENU_CLASSIC_BUTTON_ROOT,
104 	DISKMENU_CLASSIC_BUTTON_HOME,
105 	DISKMENU_CLASSIC_BUTTON_REFRESH,
106 	DISKMENU_CLASSIC_BUTTON_LOAD,
107 	DISKMENU_CLASSIC_BUTTON_DELETE,
108 	DISKMENU_CLASSIC_BUTTON_MAKEDIR,
109 
110 	DISKMENU_CLASSIC_STATICTEXT_FILTEREXTENSIONS,
111 	DISKMENU_CLASSIC_CHECKBOX_FILTEREXTENSIONS,
112 
113 	DISKMENU_CLASSIC_STATICTEXT_SORTBY,
114 	DISKMENU_CLASSIC_BUTTON_SORTBY,
115 	DISKMENU_CLASSIC_BUTTON_SORTORDER,
116 
117 	DISKMENU_CLASSIC_BUTTON_VEXTEND,
118 	DISKMENU_CLASSIC_BUTTON_HEXTEND,
119 
120 	DISKMENU_CLASSIC_BUTTON_DIR0,
121 	DISKMENU_CLASSIC_BUTTON_DIR1,
122 	DISKMENU_CLASSIC_BUTTON_DIR2,
123 	DISKMENU_CLASSIC_BUTTON_DIR3,
124 	DISKMENU_CLASSIC_BUTTON_DIR4,
125 	DISKMENU_CLASSIC_BUTTON_STOREDIR, // this needs to be DISKMENU_CLASSIC_BUTTON_DIR5+1
126 
127 	DISKMENU_CLASSIC_BUTTON_TYPE,
128 
129 	RESPONDMESSAGEBOX_OVERWRITE,
130 	RESPONDMESSAGEBOX_DELETE
131 };
132 
133 #define RADIOGROUPTOINDEX(ID) ((ID) - DISKMENU_NORMAL_RADIOGROUP_SONGTYPE)
134 #define INDEXTORADIOGROUP(INDEX) ((INDEX) + DISKMENU_NORMAL_RADIOGROUP_SONGTYPE)
135 
136 // Class which responds to the above message box clicks
137 class DialogResponderDisk : public DialogResponder
138 {
139 private:
140 	SectionDiskMenu& section;
141 
142 public:
DialogResponderDisk(SectionDiskMenu & section)143 	DialogResponderDisk(SectionDiskMenu& section) :
144 		section(section)
145 	{
146 	}
147 
ActionOkay(PPObject * sender)148 	virtual pp_int32 ActionOkay(PPObject* sender)
149 	{
150 		if (reinterpret_cast<PPDialogBase*>(sender)->getID() == RESPONDMESSAGEBOX_OVERWRITE)
151 		{
152 			section.saveCurrent();
153 			return 1;
154 		}
155 		else if (reinterpret_cast<PPDialogBase*>(sender)->getID() == RESPONDMESSAGEBOX_DELETE)
156 		{
157 			section.deleteCurrent();
158 		}
159 		return 0;
160 	}
161 
ActionCancel(PPObject * sender)162 	virtual pp_int32 ActionCancel(PPObject* sender)
163 	{
164 		return 0;
165 	}
166 };
167 
168 class PPDummySavePanel : public PPSavePanel
169 {
170 public:
PPDummySavePanel(const PPSystemString & defaultFileName)171 	PPDummySavePanel(const PPSystemString& defaultFileName) :
172 		PPSavePanel(NULL, "", defaultFileName)
173 	{
174 		this->defaultFileName = defaultFileName;
175 	}
176 
runModal()177 	virtual ReturnCodes runModal()
178 	{
179 		return ReturnCodeOK;
180 	}
181 
getFileName()182 	virtual const PPSystemString& getFileName()
183 	{
184 		return defaultFileName;
185 	}
186 };
187 
188 class ColorQueryListener : public PPListBox::ColorQueryListener
189 {
190 private:
191 	SectionDiskMenu& sectionDiskMenu;
192 
193 public:
ColorQueryListener(SectionDiskMenu & theSectionDiskMenu)194 	ColorQueryListener(SectionDiskMenu& theSectionDiskMenu) :
195 		sectionDiskMenu(theSectionDiskMenu)
196 	{
197 	}
198 
getColor(pp_uint32 index,PPListBox & sender)199 	virtual PPColor getColor(pp_uint32 index, PPListBox& sender)
200 	{
201 		PPListBoxFileBrowser& listBoxFiles = static_cast<PPListBoxFileBrowser&>(sender);
202 
203 		const PPColor& fileColor = GlobalColorConfig::getInstance()->getColor(GlobalColorConfig::ColorTextHighlited);
204 		const PPColor& dirColor = GlobalColorConfig::getInstance()->getColor(GlobalColorConfig::ColorForegroundText);
205 
206 		return listBoxFiles.getPathEntry(index)->isFile() ? fileColor : dirColor;
207 	}
208 };
209 
SectionDiskMenu(Tracker & theTracker)210 SectionDiskMenu::SectionDiskMenu(Tracker& theTracker) :
211 	SectionUpperLeft(theTracker, NULL, new DialogResponderDisk(*this)),
212 	diskMenuVisible(false),
213 	classicViewState(BrowseModules),
214 	forceClassicBrowser(false),
215 	moduleTypeAdjust(true),
216 	sortAscending(true),
217 	storePath(false),
218 	listBoxFiles(NULL),
219 	editFieldCurrentFile(NULL),
220 	currentActiveRadioGroup(NULL)
221 {
222 	normalViewControls = new PPSimpleVector<PPControl>(0, false);
223 	classicViewControls = new PPSimpleVector<PPControl>(0, false);
224 
225 	fileFullPath = new PPSystemString();
226 	file = new PPSystemString();
227 
228 	lastFocusedControl = NULL;
229 
230 #ifdef __LOWRES__
231 	lastSIPOffsetMove = 0;
232 #endif
233 
234 	colorQueryListener = new ColorQueryListener(*this);
235 }
236 
~SectionDiskMenu()237 SectionDiskMenu::~SectionDiskMenu()
238 {
239 	delete colorQueryListener;
240 
241 	delete fileFullPath;
242 	delete file;
243 
244 	delete normalViewControls;
245 	delete classicViewControls;
246 }
247 
getCurrentSelectedSampleSaveType()248 pp_int32 SectionDiskMenu::getCurrentSelectedSampleSaveType()
249 {
250 	if (sectionContainer == NULL)
251 		return -1;
252 
253 	switch (static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_SAMPLETYPE))->getChoice())
254 	{
255 		case 0:
256 			return FileTypes::FileTypeSampleWAV;
257 		case 1:
258 			return FileTypes::FileTypeSampleIFF;
259 	}
260 
261 	return -1;
262 }
263 
handleEvent(PPObject * sender,PPEvent * event)264 pp_int32 SectionDiskMenu::handleEvent(PPObject* sender, PPEvent* event)
265 {
266 	PPScreen* screen = tracker.screen;
267 
268 	if (event->getID() == eCommand)
269 	{
270 
271 		switch (reinterpret_cast<PPControl*>(sender)->getID())
272 		{
273 			case DISKMENU_NORMAL_BUTTON_LOAD_SONG:
274 			{
275 				if (screen->getModalControl())
276 					break;
277 
278 				tracker.loadTypeWithDialog(FileTypes::FileTypeSongAllModules);
279 				break;
280 			}
281 
282 
283 			case DISKMENU_NORMAL_BUTTON_SAVE_SONG:
284 			{
285 				switch (static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_SONGTYPE))->getChoice())
286 				{
287 					case 0:
288 						tracker.saveTypeWithDialog(FileTypes::FileTypeSongXM);
289 						break;
290 
291 					case 1:
292 						tracker.saveTypeWithDialog(FileTypes::FileTypeSongMOD);
293 						break;
294 
295 					case 2:
296 						tracker.sectionSwitcher->showUpperSection(tracker.sectionHDRecorder);
297 						break;
298 				}
299 
300 				break;
301 			}
302 
303 			case DISKMENU_NORMAL_BUTTON_LOAD_PATTERN:
304 			{
305 				tracker.loadTypeWithDialog(FileTypes::FileTypePatternXP);
306 				break;
307 			}
308 
309 			case DISKMENU_NORMAL_BUTTON_SAVE_PATTERN:
310 			{
311 				tracker.saveTypeWithDialog(FileTypes::FileTypePatternXP);
312 				break;
313 			}
314 
315 			case DISKMENU_NORMAL_BUTTON_LOAD_TRACK:
316 			{
317 				tracker.loadTypeWithDialog(FileTypes::FileTypeTrackXT);
318 				break;
319 			}
320 
321 			case DISKMENU_NORMAL_BUTTON_SAVE_TRACK:
322 			{
323 				tracker.saveTypeWithDialog(FileTypes::FileTypeTrackXT);
324 				break;
325 			}
326 
327 			case DISKMENU_NORMAL_BUTTON_LOAD_INSTRUMENT:
328 			{
329 				tracker.loadTypeWithDialog(FileTypes::FileTypeSongAllInstruments);
330 				break;
331 			}
332 
333 			case DISKMENU_NORMAL_BUTTON_SAVE_INSTRUMENT:
334 			{
335 				tracker.saveTypeWithDialog(FileTypes::FileTypeInstrumentXI);
336 				break;
337 			}
338 
339 			case DISKMENU_NORMAL_BUTTON_LOAD_SAMPLE:
340 			{
341 				tracker.loadTypeWithDialog(FileTypes::FileTypeSongAllSamples);
342 				break;
343 			}
344 
345 			case DISKMENU_NORMAL_BUTTON_SAVE_SAMPLE:
346 			{
347 				tracker.saveTypeWithDialog(getCurrentSelectedSampleSaveType());
348 				break;
349 			}
350 
351 			case DISKMENU_BUTTON_FLIP:
352 			{
353 				flip();
354 				break;
355 			}
356 
357 			case DISKMENU_CLASSIC_BUTTON_TYPE_TYPE:
358 			{
359 				switchState(BrowseAll);
360 				break;
361 			}
362 
363 			case DISKMENU_CLASSIC_BUTTON_TYPE_MODULE:
364 			{
365 				switchState(BrowseModules);
366 				break;
367 			}
368 
369 			case DISKMENU_CLASSIC_BUTTON_TYPE_INSTRUMENT:
370 			{
371 				switchState(BrowseInstruments);
372 				break;
373 			}
374 
375 			case DISKMENU_CLASSIC_BUTTON_TYPE_SAMPLE:
376 			{
377 				switchState(BrowseSamples);
378 				break;
379 			}
380 
381 			case DISKMENU_CLASSIC_BUTTON_TYPE_PATTERN:
382 			{
383 				switchState(BrowsePatterns);
384 				break;
385 			}
386 
387 			case DISKMENU_CLASSIC_BUTTON_TYPE_TRACK:
388 			{
389 				switchState(BrowseTracks);
390 				break;
391 			}
392 
393 			case DISKMENU_CLASSIC_BUTTON_SAVE:
394 			{
395 				prepareSave();
396 				break;
397 			}
398 
399 			case DISKMENU_CLASSIC_BUTTON_PREV:
400 				prev();
401 				break;
402 
403 			case DISKMENU_CLASSIC_BUTTON_NEXT:
404 				next();
405 				break;
406 
407 			case DISKMENU_CLASSIC_BUTTON_PARENT:
408 				parent();
409 				break;
410 
411 			case DISKMENU_CLASSIC_BUTTON_ROOT:
412 				root();
413 				break;
414 
415 			case DISKMENU_CLASSIC_BUTTON_HOME:
416 				home();
417 				break;
418 
419 			case DISKMENU_CLASSIC_BUTTON_REFRESH:
420 				reload();
421 				break;
422 
423 			case DISKMENU_CLASSIC_BUTTON_DELETE:
424 				showDeleteMessageBox();
425 				break;
426 
427 			case DISKMENU_CLASSIC_BUTTON_LOAD:
428 				handleLoadOrStep();
429 				break;
430 
431 			case DISKMENU_CLASSIC_BUTTON_SORTBY:
432 				listBoxFiles->cycleSorting();
433 				reload();
434 				updateButtonStates();
435 				break;
436 
437 			case DISKMENU_CLASSIC_BUTTON_SORTORDER:
438 				sortAscending = !sortAscending;
439 				listBoxFiles->setSortAscending(sortAscending);
440 				reload();
441 				updateButtonStates();
442 				break;
443 
444 			case DISKMENU_CLASSIC_CHECKBOX_FILTEREXTENSIONS:
445 				updateFilter();
446 				break;
447 
448 			case DISKMENU_CLASSIC_BUTTON_VEXTEND:
449 				resizeBrowserVertically();
450 				break;
451 
452 			case DISKMENU_CLASSIC_BUTTON_HEXTEND:
453 				resizeBrowserHorizontally();
454 				break;
455 
456 			case DISKMENU_CLASSIC_BUTTON_STOREDIR:
457 			{
458 				storePath = !storePath;
459 				PPButton* button = reinterpret_cast<PPButton*>(sender);
460 				button->setPressed(storePath);
461 				screen->paintControl(button);
462 				break;
463 			}
464 
465 			case DISKMENU_CLASSIC_BUTTON_DIR0:
466 			case DISKMENU_CLASSIC_BUTTON_DIR1:
467 			case DISKMENU_CLASSIC_BUTTON_DIR2:
468 			case DISKMENU_CLASSIC_BUTTON_DIR3:
469 			case DISKMENU_CLASSIC_BUTTON_DIR4:
470 			{
471 				PPButton* button = reinterpret_cast<PPButton*>(sender);
472 
473 				PPString strKey = getKeyFromPredefPathButton(button);
474 
475 				if (storePath)
476 				{
477 					PPString path = listBoxFiles->getCurrentPathAsASCIIString();
478 					tracker.settingsDatabase->store(strKey, path);
479 
480 					storePath = !storePath;
481 					PPButton* button = static_cast<PPButton*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_STOREDIR));
482 					button->setPressed(storePath);
483 					screen->paintControl(button);
484 				}
485 				else
486 				{
487 					PPDictionaryKey* key = tracker.settingsDatabase->restore(strKey);
488 					if (key)
489 					{
490 						PPSystemString str(key->getStringValue());
491 						bool res = listBoxFiles->gotoPath(str);
492 
493 						if (!res)
494 							tracker.showMessageBox(MESSAGEBOX_UNIVERSAL, "Couldn't change directory.", Tracker::MessageBox_OK);
495 
496 						screen->paintControl(listBoxFiles);
497 					}
498 					else
499 						tracker.showMessageBox(MESSAGEBOX_UNIVERSAL, "No directory defined.", Tracker::MessageBox_OK);
500 				}
501 
502 				break;
503 			}
504 
505 			case DISKMENU_BUTTON_EXIT:
506 				show(false);
507 				break;
508 
509 		}
510 
511 	}
512 	else if (reinterpret_cast<PPControl*>(sender) == listBoxFiles && event->getID() == eConfirmed)
513 	{
514 		handleLoadOrStep();
515 	}
516 	else if (event->getID() == eSelection)
517 	{
518 		switch (reinterpret_cast<PPControl*>(sender)->getID())
519 		{
520 			case DISKMENU_CLASSIC_LISTBOX_BROWSER:
521 			{
522 				updateFilenameEditFieldFromBrowser();
523 				break;
524 			}
525 
526 			case DISKMENU_NORMAL_RADIOGROUP_SONGTYPE:
527 			case DISKMENU_NORMAL_RADIOGROUP_PATTERNTYPE:
528 			case DISKMENU_NORMAL_RADIOGROUP_TRACKTYPE:
529 			case DISKMENU_NORMAL_RADIOGROUP_INSTRUMENTTYPE:
530 			case DISKMENU_NORMAL_RADIOGROUP_SAMPLETYPE:
531 				currentActiveRadioGroup = reinterpret_cast<PPRadioGroup*>(sender);
532 				updateFilenameEditFieldExtension(classicViewState);
533 				break;
534 		}
535 
536 	}
537 	else if (event->getID() == eFileSystemChanged)
538 	{
539 		reload();
540 	}
541 	else if (event->getID() == eValueChanged)
542 	{
543 		switch (reinterpret_cast<PPControl*>(sender)->getID())
544 		{
545 			case DISKMENU_CLASSIC_LISTBOX_NAME:
546 			{
547 				const PPString* str = *(reinterpret_cast<const PPString* const*>(event->getDataPtr()));
548 				*fileFullPath = listBoxFiles->getCurrentPathAsString();
549 				PPSystemString temp(*str);
550 				*file = temp;
551 				fileFullPath->append(*file);
552 				assureExtension();
553 				break;
554 			}
555 		}
556 	}
557 
558 	return 0;
559 }
560 
init(pp_int32 px,pp_int32 py)561 void SectionDiskMenu::init(pp_int32 px, pp_int32 py)
562 {
563 	pp_int32 i;
564 
565 	PPScreen* screen = tracker.screen;
566 
567 	PPContainer* container = new PPContainer(CONTAINER_ADVEDIT, tracker.screen, this, PPPoint(px, py), PPSize(320,UPPERLEFTSECTIONHEIGHT), false);
568 	container->setColor(TrackerConfig::colorThemeMain);
569 
570 	container->addControl(new PPStaticText(DISKMENU_NORMAL_STATICTEXT_HEADING, NULL, NULL, PPPoint(px + 2, py + 2), "Disk operations", true, true));
571 
572 	pp_int32 buttonWidth = 8*4+4;
573 	pp_int32 buttonHeight = 11;
574 
575 	pp_int32 x = px+container->getSize().width-(buttonWidth+4);
576 	pp_int32 y = py+container->getSize().height-(buttonHeight+4);
577 
578 	container->addControl(new PPSeperator(0, screen, PPPoint(px + 2, y - 4), container->getSize().width - 4, TrackerConfig::colorThemeMain, true));
579 
580 	PPButton* button = new PPButton(DISKMENU_BUTTON_EXIT, screen, this, PPPoint(x, y), PPSize(buttonWidth,buttonHeight+1));
581 	button->setText("Exit");
582 	container->addControl(button);
583 
584 	pp_int32 dx = 6;
585 	pp_int32 dy = 16;
586 	// ---- Song ----------
587 	x = px + 2;
588 	y = py + dy;
589 	container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x,y), "Song:", true));
590 
591 	y+=12;
592 	buttonWidth = 8*7+2;
593 	button = new PPButton(DISKMENU_NORMAL_BUTTON_LOAD_SONG, screen, this, PPPoint(x, y), PPSize(buttonWidth,buttonHeight));
594 	button->setText("Load");
595 	container->addControl(button);
596 	y+=buttonHeight+1;
597 	button = new PPButton(DISKMENU_NORMAL_BUTTON_SAVE_SONG, screen, this, PPPoint(x, y), PPSize(buttonWidth,buttonHeight));
598 	button->setText("Save As");
599 	container->addControl(button);
600 	y+=buttonHeight;
601 
602 	PPRadioGroup* radioGroup = new PPRadioGroup(DISKMENU_NORMAL_RADIOGROUP_SONGTYPE, screen, this, PPPoint(x, y), PPSize(buttonWidth, 3*14));
603 	radioGroupLocations[RADIOGROUPTOINDEX(DISKMENU_NORMAL_RADIOGROUP_SONGTYPE)] = radioGroup->getLocation();
604 	radioGroup->setColor(TrackerConfig::colorThemeMain);
605 
606 	radioGroup->addItem(".xm");
607 	radioGroup->addItem(".mod");
608 	radioGroup->addItem(".wav");
609 	container->addControl(radioGroup);
610 
611 	// ---- Pattern ----------
612 	x += buttonWidth+dx;
613 	y = py + dy;
614 	container->addControl(new PPSeperator(0, screen, PPPoint(x - 4, y - 2), container->getLocation().y + container->getSize().height - y - 17, TrackerConfig::colorThemeMain, false));
615 
616 	container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x,y), "Patt:", true));
617 
618 	y+=12;
619 	button = new PPButton(DISKMENU_NORMAL_BUTTON_LOAD_PATTERN, screen, this, PPPoint(x, y), PPSize(buttonWidth,buttonHeight));
620 	button->setText("Load");
621 	container->addControl(button);
622 	y+=buttonHeight+1;
623 	button = new PPButton(DISKMENU_NORMAL_BUTTON_SAVE_PATTERN, screen, this, PPPoint(x, y), PPSize(buttonWidth,buttonHeight));
624 	button->setText("Save As");
625 	container->addControl(button);
626 	y+=buttonHeight;
627 
628 	radioGroup = new PPRadioGroup(DISKMENU_NORMAL_RADIOGROUP_PATTERNTYPE, screen, this, PPPoint(x, y), PPSize(buttonWidth, 30));
629 	radioGroupLocations[RADIOGROUPTOINDEX(DISKMENU_NORMAL_RADIOGROUP_PATTERNTYPE)] = radioGroup->getLocation();
630 	radioGroup->setColor(TrackerConfig::colorThemeMain);
631 
632 	radioGroup->addItem(".xp");
633 	container->addControl(radioGroup);
634 
635 	// ---- Track ----------
636 	x += buttonWidth+dx;
637 	y = py + dy;
638 	container->addControl(new PPSeperator(0, screen, PPPoint(x - 4, y - 2), container->getLocation().y + container->getSize().height - y - 17, TrackerConfig::colorThemeMain, false));
639 
640 	container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x,y), "Track:", true));
641 
642 	y+=12;
643 	button = new PPButton(DISKMENU_NORMAL_BUTTON_LOAD_TRACK, screen, this, PPPoint(x, y), PPSize(buttonWidth,buttonHeight));
644 	button->setText("Load");
645 	container->addControl(button);
646 	y+=buttonHeight+1;
647 	button = new PPButton(DISKMENU_NORMAL_BUTTON_SAVE_TRACK, screen, this, PPPoint(x, y), PPSize(buttonWidth,buttonHeight));
648 	button->setText("Save As");
649 	container->addControl(button);
650 	y+=buttonHeight;
651 
652 	radioGroup = new PPRadioGroup(DISKMENU_NORMAL_RADIOGROUP_TRACKTYPE, screen, this, PPPoint(x, y), PPSize(buttonWidth, 30));
653 	radioGroupLocations[RADIOGROUPTOINDEX(DISKMENU_NORMAL_RADIOGROUP_TRACKTYPE)] = radioGroup->getLocation();
654 	radioGroup->setColor(TrackerConfig::colorThemeMain);
655 
656 	radioGroup->addItem(".xt");
657 	container->addControl(radioGroup);
658 
659 	// ---- Instrument ----------
660 	x += buttonWidth+dx;
661 	y = py + dy;
662 	container->addControl(new PPSeperator(0, screen, PPPoint(x - 4, y - 2), container->getLocation().y + container->getSize().height - y - 17, TrackerConfig::colorThemeMain, false));
663 
664 	container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x,y), "Instr:", true));
665 
666 	y+=12;
667 	button = new PPButton(DISKMENU_NORMAL_BUTTON_LOAD_INSTRUMENT, screen, this, PPPoint(x, y), PPSize(buttonWidth,buttonHeight));
668 	button->setText("Load");
669 	container->addControl(button);
670 	y+=buttonHeight+1;
671 	button = new PPButton(DISKMENU_NORMAL_BUTTON_SAVE_INSTRUMENT, screen, this, PPPoint(x, y), PPSize(buttonWidth,buttonHeight));
672 	button->setText("Save As");
673 	container->addControl(button);
674 	y+=buttonHeight;
675 
676 	radioGroup = new PPRadioGroup(DISKMENU_NORMAL_RADIOGROUP_INSTRUMENTTYPE, screen, this, PPPoint(x, y), PPSize(buttonWidth, 30));
677 	radioGroupLocations[RADIOGROUPTOINDEX(DISKMENU_NORMAL_RADIOGROUP_INSTRUMENTTYPE)] = radioGroup->getLocation();
678 	radioGroup->setColor(TrackerConfig::colorThemeMain);
679 
680 	radioGroup->addItem(".xi");
681 	container->addControl(radioGroup);
682 
683 	// ---- Sample ----------
684 	x += buttonWidth+dx;
685 	y = py + dy;
686 	container->addControl(new PPSeperator(0, screen, PPPoint(x - 4, y - 2), container->getLocation().y + container->getSize().height - y - 17, TrackerConfig::colorThemeMain, false));
687 
688 	container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x,y), "Sample:", true));
689 
690 	y+=12;
691 	button = new PPButton(DISKMENU_NORMAL_BUTTON_LOAD_SAMPLE, screen, this, PPPoint(x, y), PPSize(buttonWidth,buttonHeight));
692 	button->setText("Load");
693 	container->addControl(button);
694 	y+=buttonHeight+1;
695 	button = new PPButton(DISKMENU_NORMAL_BUTTON_SAVE_SAMPLE, screen, this, PPPoint(x, y), PPSize(buttonWidth,buttonHeight));
696 	button->setText("Save As");
697 	container->addControl(button);
698 	y+=buttonHeight;
699 
700 	radioGroup = new PPRadioGroup(DISKMENU_NORMAL_RADIOGROUP_SAMPLETYPE, screen, this, PPPoint(x, y), PPSize(buttonWidth, 2*14));
701 	radioGroupLocations[RADIOGROUPTOINDEX(DISKMENU_NORMAL_RADIOGROUP_SAMPLETYPE)] = radioGroup->getLocation();
702 	radioGroup->setColor(TrackerConfig::colorThemeMain);
703 
704 	radioGroup->addItem(".wav");
705 	radioGroup->addItem(".iff");
706 	container->addControl(radioGroup);
707 
708 	// Now get all controls built for the "normal" view (not the FT2 retro view) and save them,
709 	// so we can hide them later easily, without referring to the IDs or whatever
710 	// (except for the section heading and the exit button)
711 	PPSimpleVector<PPControl>& controls = container->getControls();
712 	for (i = 0; i < controls.size(); i++)
713 	{
714 		if (controls.get(i)->getID() != DISKMENU_BUTTON_EXIT)
715 		{
716 			normalViewControls->add(controls.get(i));
717 		}
718 	}
719 
720 	// remember that, this is where we start gathering the controls for the "classic" view
721 	pp_int32 firstClassicControlIndex = i + 1;
722 
723 	// go on with some more stuff
724 	x = container->getLocation().x + container->getSize().width - 28;
725 	pp_int32 x4 = x;
726 	y = py + 2;
727 	button = new PPButton(DISKMENU_BUTTON_FLIP, screen, this, PPPoint(x, y), PPSize(24, 11), false);
728 	button->setText("Flip");
729 	button->setColor(TrackerConfig::colorThemeMain);
730 	button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
731 	container->addControl(button);
732 
733 	x = px + 2;
734 	y = py + 2;
735 	container->addControl(new PPStaticText(DISKMENU_CLASSIC_STATICTEXT_HEADING, NULL, NULL, PPPoint(x, y), "Disk op", true, true));
736 	y+=13;
737 
738 	// add type buttons
739 	static const char* buttonTexts[6] = {"Type", "Module", "Instr.", "Sample", "Patt.", "Track"};
740 	pp_int32 numButtons = (DISKMENU_CLASSIC_BUTTON_TYPE_TRACK-DISKMENU_CLASSIC_BUTTON_TYPE_TYPE+1);
741 	ASSERT((sizeof(buttonTexts)/sizeof(const char*)) == numButtons);
742 
743 	pp_int32 bWidth = 7*8;
744 	pp_int32 bHeight = 14;
745 
746 	y--;
747 	pp_int32 y3 = y;
748 
749 	for (i = 0; i < numButtons; i++)
750 	{
751 		/*if (i == 0)
752 			button = new PPButton(i + DISKMENU_CLASSIC_BUTTON_TYPE_TYPE, screen, this, PPPoint(x, y), PPSize(bWidth, bHeight), false, true, false);
753 		else*/
754 
755 		button = new PPButton(i + DISKMENU_CLASSIC_BUTTON_TYPE_TYPE, screen, this, PPPoint(x, y), PPSize(bWidth, bHeight), false);
756 
757 		button->setColor(TrackerConfig::colorThemeMain);
758 		button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
759 		button->setText(buttonTexts[i]);
760 		container->addControl(button);
761 		y+=bHeight;
762 	}
763 
764 	pp_int32 x3 = x + bWidth + 3;
765 
766 	y+=5;
767 
768 	// add save button
769 	button = new PPButton(DISKMENU_CLASSIC_BUTTON_SAVE, screen, this, PPPoint(x, y), PPSize(bWidth, buttonHeight+1));
770 	button->setText("Save");
771 	container->addControl(button);
772 
773 	// file browser
774 	pp_int32 lbWidth = (px + container->getSize().width) - x3 - 4;
775 	pp_int32 lbHeight = (py+container->getSize().height-(buttonHeight+4)) - y3 - 5;
776 	listBoxFiles = new PPListBoxFileBrowser(DISKMENU_CLASSIC_LISTBOX_BROWSER, screen, this, PPPoint(x3, y3), PPSize(lbWidth, lbHeight));
777 	listBoxFiles->setBorderColor(TrackerConfig::colorThemeMain);
778 	listBoxFiles->setFilePrefix("");
779 	listBoxFiles->setDirectoryPrefix("");
780 	listBoxFiles->setDirectorySuffixPathSeperator();
781 	listBoxFiles->setSortAscending(sortAscending);
782 	listBoxFiles->setColorQueryListener(colorQueryListener);
783 	container->addControl(listBoxFiles);
784 	fileBrowserExtent = listBoxFiles->getSize();
785 
786 	y3+=2;
787 	x3+=2;
788 
789 	PPControl* ctrl;
790 
791 	ctrl = new PPStaticText(DISKMENU_CLASSIC_STATICTEXT_SORTBY, NULL, NULL, PPPoint(x3, y3), "Sort by:", true);
792 	container->addControl(ctrl);
793 	x3+=8*8;
794 
795 	button = new PPButton(DISKMENU_CLASSIC_BUTTON_SORTBY, screen, this, PPPoint(x3, y3-1), PPSize(51, 11), false);
796 	button->setFont(PPFont::getFont(PPFont::FONT_TINY));
797 	button->setText("Extension");
798 	button->setColor(TrackerConfig::colorThemeMain);
799 	button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
800 	container->addControl(button);
801 
802 	button = new PPButton(DISKMENU_CLASSIC_BUTTON_SORTORDER, screen, this, PPPoint(x3+button->getSize().width, y3-1), PPSize(13, 11), false);
803 	button->setText(sortAscending ? "\xfd" : "\xfe");
804 	button->setColor(TrackerConfig::colorThemeMain);
805 	button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
806 	container->addControl(button);
807 
808 	x3+=80;
809 	PPCheckBox* checkBox = new PPCheckBox(DISKMENU_CLASSIC_CHECKBOX_FILTEREXTENSIONS, screen, this, PPPoint(x3 + 12 * 8 + 2, y3 - 1));
810 	container->addControl(checkBox);
811 	container->addControl(new PPCheckBoxLabel(DISKMENU_CLASSIC_STATICTEXT_FILTEREXTENSIONS, NULL, this, PPPoint(x3, y3), "Type filter:", checkBox, true));
812 
813 	buttonWidth = 27;
814 	pp_int32 y5 = y3 + 12;
815 	pp_int32 x5 = container->getLocation().x + container->getSize().width - buttonWidth - 5;
816 	numButtons = 5;
817 	for (i = 0; i < numButtons; i++)
818 	{
819 		pp_int32 buttonHeight = 11;
820 		char temp[80];
821 		sprintf(temp, "DIR%d", i+1);
822 		PPFont* font = PPFont::getFont(PPFont::FONT_TINY);
823 		button = new PPButton(DISKMENU_CLASSIC_BUTTON_DIR0+i, screen, this, PPPoint(x5, y5), PPSize(buttonWidth, buttonHeight));
824 		button->setFont(font);
825 		button->setText(temp);
826 		container->addControl(button);
827 		y5+=buttonHeight+1;
828 	}
829 	button = new PPButton(DISKMENU_CLASSIC_BUTTON_STOREDIR, screen, this, PPPoint(x5, y5), PPSize(buttonWidth, 9), true, true, false);
830 	button->setFont(PPFont::getFont(PPFont::FONT_TINY));
831 	button->setText("Store");
832 	container->addControl(button);
833 
834 	// save edit list box
835 	buttonWidth = container->getControlByID(DISKMENU_BUTTON_EXIT)->getLocation().x - (x + bWidth + 4) - 4;
836 
837 	editFieldCurrentFile = new PPListBox(DISKMENU_CLASSIC_LISTBOX_NAME, screen, this, PPPoint(x + bWidth + 4, y), PPSize(buttonWidth, buttonHeight+1), true, true, false);
838 	editFieldCurrentFile->showSelection(false);
839 	editFieldCurrentFile->setSingleButtonClickEdit(true);
840 	editFieldCurrentFile->setBorderColor(TrackerConfig::colorThemeMain);
841 
842 	char str[MP_MAXTEXT+1];
843 	memset(str, 0, sizeof(str));
844 
845 	editFieldCurrentFile->addItem(str);
846 	editFieldCurrentFile->setMaxEditSize(255);
847 
848 	container->addControl(editFieldCurrentFile);
849 
850 	y = py + 2;
851 	x = px + 2 + 8*7 + 5;
852 
853 	static const char* buttonTexts2[] = {"<-", "->", "Up", "Root", "Home", "Reload", "Load", "Del", "MkDir"};
854 	static const pp_int32 buttonSpacing[] = {0,0,0,0,0,3,0,0,0};
855 	numButtons = sizeof(buttonTexts2)/sizeof(const char*);
856 
857 	bHeight = 10;
858 	for (i = 0; i < numButtons; i++)
859 	{
860 		PPFont* font = PPFont::getFont(PPFont::FONT_TINY);
861 		bWidth = font->getStrWidth(buttonTexts2[i]) + 3;
862 		button = new PPButton(DISKMENU_CLASSIC_BUTTON_PREV+i, screen, this, PPPoint(x, y), PPSize(bWidth, bHeight));
863 		button->setFont(font);
864 		button->setText(buttonTexts2[i]);
865 		container->addControl(button);
866 		x+=bWidth+1+buttonSpacing[i];
867 	}
868 
869 	x=x4-13*2;
870 	button = new PPButton(DISKMENU_CLASSIC_BUTTON_VEXTEND, screen, this, PPPoint(x, y), PPSize(13, bHeight+1), false);
871 	button->setText(TrackerConfig::stringButtonCollapsed);
872 	button->setColor(TrackerConfig::colorThemeMain);
873 	button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
874 	container->addControl(button);
875 	x+=13;
876 	button = new PPButton(DISKMENU_CLASSIC_BUTTON_HEXTEND, screen, this, PPPoint(x, y), PPSize(13, bHeight+1), false);
877 	button->setFont(PPFont::getFont(PPFont::FONT_TINY));
878 	button->setText(">");
879 	button->setColor(TrackerConfig::colorThemeMain);
880 	button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
881 	container->addControl(button);
882 
883 	y = py+container->getSize().height-(buttonHeight+4);
884 	container->addControl(new PPSeperator(0, screen, PPPoint(px + 2, y - 4), container->getSize().width - 4, TrackerConfig::colorThemeMain, true));
885 
886 	// gather controls for the classic view, we simply start counting from the last control we found
887 	// the last time
888 	for (i = firstClassicControlIndex; i < controls.size(); i++)
889 	{
890 		classicViewControls->add(controls.get(i));
891 		controls.get(i)->hide(true);
892 	}
893 
894 	tracker.screen->addControl(container);
895 
896 	sectionContainer = container;
897 
898 	// fit dir buttons to browser listbox size
899 	fitDirButtons();
900 
901 	initialised = true;
902 
903 	showSection(false);
904 }
905 
show(bool bShow)906 void SectionDiskMenu::show(bool bShow)
907 {
908 	// sanity check
909 	if (bShow == diskMenuVisible)
910 		return;
911 
912 #ifdef __LOWRES__
913 	tracker.screen->pauseUpdate(true);
914 #endif
915 
916 	PPRadioGroup* radioGroup = static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_SONGTYPE));
917 
918 	if (bShow)
919 	{
920 		if (moduleTypeAdjust)
921 		{
922 			switch (tracker.moduleEditor->getSaveType())
923 			{
924 				case ModuleEditor::ModSaveTypeXM:
925 					radioGroup->setChoice(0);
926 					break;
927 
928 				case ModuleEditor::ModSaveTypeMOD:
929 					radioGroup->setChoice(1);
930 					break;
931 
932 				default:
933 					ASSERT(false);
934 			}
935 		}
936 
937 		// restore CWD in case it has been changed
938 		// through the native file requester (e.g. on Windows)
939 		if (currentPath.length() != 0)
940 		{
941 			setCurrentPath(currentPath, false);
942 		}
943 	}
944 	else
945 	{
946 		// store CWD
947 		currentPath = getCurrentPath();
948 	}
949 
950 	diskMenuVisible = bShow;
951 
952 	SectionUpperLeft::show(bShow);
953 
954 	if (bShow)
955 	{
956 #ifdef __LOWRES__
957 		pp_int32 y = tracker.screen->getControlByID(CONTAINER_INPUTDEFAULT)->getLocation().y;
958 		replaceInstrumentListBoxes(true, y);
959 		tracker.getPatternEditorControl()->show(false);
960 #endif
961 		prepareSection();
962 		lastFocusedControl = tracker.screen->getFocusedControl();
963 		tracker.screen->setFocus(listBoxFiles);
964 
965 		if (forceClassicBrowser)
966 		{
967 			showNormalView(false);
968 			showClassicView(true);
969 			updateClassicView();
970 			updateFilenameEditField(classicViewState);
971 			forceClassicBrowser = false;
972 		}
973 	}
974 	else
975 	{
976 #ifdef __LOWRES__
977 		replaceInstrumentListBoxes(false);
978 		tracker.getPatternEditorControl()->show(true);
979 #endif
980 		tracker.screen->setFocus(lastFocusedControl);
981 	}
982 
983 #ifdef __LOWRES__
984 	pp_int32 deltay = sectionContainer->getSize().height - tracker.UPPERSECTIONDEFAULTHEIGHT();
985 
986 	pp_int32 newSIPOffsetMove = bShow ? -deltay : deltay;
987 
988 	// Only move SIP panel up/down on show/hide when it's exactly the complementary
989 	// to the previous move, otherwise we'll be moving it out of range
990 	if ((lastSIPOffsetMove != 0 && lastSIPOffsetMove == -newSIPOffsetMove) ||
991 		lastSIPOffsetMove == 0)
992 	{
993 		tracker.moveInputControls(newSIPOffsetMove);
994 		lastSIPOffsetMove = newSIPOffsetMove;
995 	}
996 
997 	tracker.screen->paint();
998 	tracker.screen->pauseUpdate(false);
999 	if (!bShow)
1000 	{
1001 		tracker.screen->update();
1002 	}
1003 #endif
1004 }
1005 
update(bool repaint)1006 void SectionDiskMenu::update(bool repaint/* = true*/)
1007 {
1008 }
1009 
isActiveEditing()1010 bool SectionDiskMenu::isActiveEditing()
1011 {
1012 	PPListBox* listBox = static_cast<PPListBox*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_LISTBOX_NAME));
1013 
1014 	ASSERT(listBox);
1015 
1016 	if (tracker.screen->hasFocus(sectionContainer) && listBox->isEditing())
1017 		return true;
1018 
1019 	return false;
1020 }
1021 
isFileBrowserVisible()1022 bool SectionDiskMenu::isFileBrowserVisible()
1023 {
1024 	return listBoxFiles->isVisible();
1025 }
1026 
fileBrowserHasFocus()1027 bool SectionDiskMenu::fileBrowserHasFocus()
1028 {
1029 	return tracker.screen->hasFocus(sectionContainer) && listBoxFiles->gotFocus();
1030 }
1031 
setFileBrowserShowFocus(bool showFocus)1032 void SectionDiskMenu::setFileBrowserShowFocus(bool showFocus)
1033 {
1034 	listBoxFiles->setShowFocus(showFocus);
1035 }
1036 
selectSaveType(pp_uint32 type)1037 void SectionDiskMenu::selectSaveType(pp_uint32 type)
1038 {
1039 	switch (type)
1040 	{
1041 		case FileTypes::FileTypeSongMOD:
1042 			static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_SONGTYPE))->setChoice(1);
1043 			classicViewState = BrowseModules;
1044 			break;
1045 		case FileTypes::FileTypeSongAllModules:
1046 		case FileTypes::FileTypeSongXM:
1047 			static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_SONGTYPE))->setChoice(0);
1048 			classicViewState = BrowseModules;
1049 			break;
1050 		case FileTypes::FileTypeSongWAV:
1051 			static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_SONGTYPE))->setChoice(2);
1052 			classicViewState = BrowseModules;
1053 			break;
1054 
1055 		case FileTypes::FileTypePatternXP:
1056 			static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_PATTERNTYPE))->setChoice(0);
1057 			classicViewState = BrowsePatterns;
1058 			break;
1059 
1060 		case FileTypes::FileTypeTrackXT:
1061 			static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_TRACKTYPE))->setChoice(0);
1062 			classicViewState = BrowseTracks;
1063 			break;
1064 
1065 		case FileTypes::FileTypeInstrumentXI:
1066 		case FileTypes::FileTypeSongAllInstruments:
1067 			static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_INSTRUMENTTYPE))->setChoice(0);
1068 			classicViewState = BrowseInstruments;
1069 			break;
1070 
1071 		case FileTypes::FileTypeSampleWAV:
1072 		case FileTypes::FileTypeSongAllSamples:
1073 			static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_SAMPLETYPE))->setChoice(0);
1074 			classicViewState = BrowseSamples;
1075 			break;
1076 		case FileTypes::FileTypeSampleIFF:
1077 			static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_SAMPLETYPE))->setChoice(1);
1078 			classicViewState = BrowseSamples;
1079 			break;
1080 
1081 		default:
1082 			ASSERT(false);
1083 	}
1084 
1085 	forceClassicBrowser = true;
1086 }
1087 
getDefaultConfigUInt32()1088 pp_uint32 SectionDiskMenu::getDefaultConfigUInt32()
1089 {
1090 	// default is:
1091 	// classic view is NOT visible = 0
1092 	// list box is v-extended = 2
1093 	// list box is h-extended = 4
1094 	// sort order is ascending = 8
1095 	// filtering by file extension is ON = 16
1096 	return 0 + 2 + 4 + 8 + 16;
1097 }
1098 
getConfigUInt32()1099 pp_uint32 SectionDiskMenu::getConfigUInt32()
1100 {
1101 	pp_uint32 result = 0;
1102 
1103 	// Classic view visible
1104 	result |= classicViewVisible ? 1 : 0;
1105 	// Extended list box = Bit 1
1106 	result |= (listBoxFiles->getSize().height == fileBrowserExtent.height) ? 2 : 0;
1107 	// Extended list box = Bit 2
1108 	result |= (listBoxFiles->getSize().width == fileBrowserExtent.width) ? 4 : 0;
1109 	// Sort order = Bit 3
1110 	result |= sortAscending ? 8 : 0;
1111 	// filter types = Bit 4
1112 	result |= static_cast<PPCheckBox*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_CHECKBOX_FILTEREXTENSIONS))->isChecked() ? 16 : 0;
1113 
1114 	// filter types = Bit 24 and above
1115 	result |= (pp_uint32)listBoxFiles->getSortType() << 24;
1116 
1117 	return result;
1118 }
1119 
setConfigUInt32(pp_uint32 config)1120 void SectionDiskMenu::setConfigUInt32(pp_uint32 config)
1121 {
1122 	if (config & 1)
1123 	{
1124 		showNormalView(false);
1125 		showClassicView(true);
1126 	}
1127 	else if (!(config & 1))
1128 	{
1129 		showNormalView(true);
1130 		showClassicView(false);
1131 	}
1132 
1133 	if ((config & 2) && listBoxFiles->getSize().height != fileBrowserExtent.height)
1134 	{
1135 		resizeBrowserVertically();
1136 	}
1137 	else if (!(config & 2) && listBoxFiles->getSize().height == fileBrowserExtent.height)
1138 	{
1139 		resizeBrowserVertically();
1140 	}
1141 	if ((config & 4) && listBoxFiles->getSize().width != fileBrowserExtent.width)
1142 	{
1143 		resizeBrowserHorizontally();
1144 	}
1145 	else if (!(config & 4) && listBoxFiles->getSize().width == fileBrowserExtent.width)
1146 	{
1147 		resizeBrowserHorizontally();
1148 	}
1149 	sortAscending = (config & 8) != 0;
1150 	listBoxFiles->setSortAscending(sortAscending);
1151 
1152 	PPCheckBox* checkBox = static_cast<PPCheckBox*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_CHECKBOX_FILTEREXTENSIONS));
1153 	ASSERT(checkBox);
1154 	checkBox->checkIt((config & 16) != 0);
1155 
1156 	listBoxFiles->setSortType((PPListBoxFileBrowser::SortTypes)(config >> 24));
1157 	updateButtonStates(false);
1158 }
1159 
getCurrentPath()1160 PPSystemString SectionDiskMenu::getCurrentPath()
1161 {
1162 	return listBoxFiles->getCurrentPathAsString();
1163 }
1164 
setCurrentPath(const PPSystemString & path,bool reload)1165 void SectionDiskMenu::setCurrentPath(const PPSystemString& path, bool reload/* = true*/)
1166 {
1167 	listBoxFiles->gotoPath(path, reload);
1168 }
1169 
getCurrentPathASCII()1170 PPString SectionDiskMenu::getCurrentPathASCII()
1171 {
1172 	char* nameASCIIZ = listBoxFiles->getCurrentPathAsString().toASCIIZ();
1173 	PPString result(nameASCIIZ);
1174 	delete[] nameASCIIZ;
1175 	return result;
1176 }
1177 
resizeInstrumentContainer()1178 void SectionDiskMenu::resizeInstrumentContainer()
1179 {
1180 #ifdef __LOWRES__
1181 	PPControl* ctrl1 = tracker.screen->getControlByID(CONTAINER_INPUTDEFAULT);
1182 	PPControl* ctrl2 = tracker.screen->getControlByID(CONTAINER_INPUTEXTENDED);
1183 
1184 	pp_int32 y = ctrl1->isVisible() ? ctrl1->getLocation().y : ctrl2->getLocation().y;
1185 
1186 	replaceAndResizeInstrumentListContainer(y);
1187 
1188 	tracker.screen->paint(false);
1189 #endif
1190 }
1191 
setCycleFilenames(bool cycleFilenames)1192 void SectionDiskMenu::setCycleFilenames(bool cycleFilenames)
1193 {
1194 	listBoxFiles->setCycleFilenames(cycleFilenames);
1195 }
1196 
prepareSection()1197 void SectionDiskMenu::prepareSection()
1198 {
1199 	updateFilter();
1200 
1201 	updateFilenameEditField(classicViewState);
1202 }
1203 
showNormalView(bool bShow)1204 void SectionDiskMenu::showNormalView(bool bShow)
1205 {
1206 	pp_uint32 i;
1207 
1208 	for (i = 0; i < (unsigned)normalViewControls->size(); i++)
1209 		normalViewControls->get(i)->hide(!bShow);
1210 
1211 	for (i = 0; i < sizeof(radioGroupLocations) / sizeof(PPPoint); i++)
1212 		static_cast<PPContainer*>(sectionContainer)->getControlByID(INDEXTORADIOGROUP(i))->setLocation(radioGroupLocations[i]);
1213 
1214 	if (bShow && isActiveEditing())
1215 		tracker.screen->setFocus(lastFocusedControl);
1216 }
1217 
updateClassicView(bool repaint)1218 void SectionDiskMenu::updateClassicView(bool repaint/* = true*/)
1219 {
1220 	pp_uint32 i;
1221 
1222 	if (!classicViewVisible)
1223 		return;
1224 
1225 	updateButtonStates(false);
1226 
1227 	bool cond = classicViewState != BrowseAll;
1228 
1229 	static_cast<PPButton*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_TYPE_TYPE))->setClickable(cond);
1230 	static_cast<PPButton*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_SAVE))->setClickable(cond);
1231 	static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_TYPE_MODULE)->hide(cond);
1232 	static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_TYPE_INSTRUMENT)->hide(cond);
1233 	static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_TYPE_SAMPLE)->hide(cond);
1234 	static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_TYPE_PATTERN)->hide(cond);
1235 	static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_TYPE_TRACK)->hide(cond);
1236 
1237 	if (classicViewState == BrowseAll)
1238 	{
1239 		currentActiveRadioGroup = NULL;
1240 	}
1241 
1242 	PPPoint pos = static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_TYPE_MODULE)->getLocation();
1243 
1244 	for (i = 0; i < sizeof(radioGroupLocations) / sizeof(PPPoint); i++)
1245 	{
1246 		static_cast<PPContainer*>(sectionContainer)->getControlByID(INDEXTORADIOGROUP(i))->setLocation(pos);
1247 		static_cast<PPContainer*>(sectionContainer)->getControlByID(INDEXTORADIOGROUP(i))->hide(true);
1248 	}
1249 
1250 	switch (classicViewState)
1251 	{
1252 		case BrowseModules:
1253 			currentActiveRadioGroup = static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_SONGTYPE));
1254 			break;
1255 		case BrowseInstruments:
1256 			currentActiveRadioGroup = static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_INSTRUMENTTYPE));
1257 			break;
1258 		case BrowseSamples:
1259 			currentActiveRadioGroup = static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_SAMPLETYPE));
1260 			break;
1261 		case BrowsePatterns:
1262 			currentActiveRadioGroup = static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_PATTERNTYPE));
1263 			break;
1264 		case BrowseTracks:
1265 			currentActiveRadioGroup = static_cast<PPRadioGroup*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_NORMAL_RADIOGROUP_TRACKTYPE));
1266 			break;
1267 		case BrowseAll:
1268 		case BrowseLAST:
1269 			break;
1270 	}
1271 
1272 	cond = listBoxFiles->getSize().height == fileBrowserExtent.height;
1273 	static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_STATICTEXT_FILTEREXTENSIONS)->hide(cond);
1274 	static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_CHECKBOX_FILTEREXTENSIONS)->hide(cond);
1275 	static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_STATICTEXT_SORTBY)->hide(cond);
1276 	static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_SORTBY)->hide(cond);
1277 	static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_SORTORDER)->hide(cond);
1278 
1279 	for (i = DISKMENU_CLASSIC_BUTTON_DIR0; i <= DISKMENU_CLASSIC_BUTTON_STOREDIR; i++)
1280 		static_cast<PPContainer*>(sectionContainer)->getControlByID(i)->hide(listBoxFiles->getSize().width == fileBrowserExtent.width);
1281 
1282 	if (currentActiveRadioGroup)
1283 		currentActiveRadioGroup->hide(false);
1284 
1285 	if (repaint)
1286 		tracker.screen->paintControl(sectionContainer);
1287 }
1288 
showClassicView(bool bShow)1289 void SectionDiskMenu::showClassicView(bool bShow)
1290 {
1291 	for (pp_int32 i = 0; i < classicViewControls->size(); i++)
1292 		classicViewControls->get(i)->hide(!bShow);
1293 
1294 	classicViewVisible = bShow;
1295 
1296 	if (bShow)
1297 	{
1298 		updateClassicView();
1299 	}
1300 }
1301 
isNormalViewVisible()1302 bool SectionDiskMenu::isNormalViewVisible()
1303 {
1304 	bool res = true;
1305 
1306 	for (pp_int32 i = 0; i < normalViewControls->size(); i++)
1307 		if (!normalViewControls->get(i)->isVisible())
1308 			res = false;
1309 
1310 	return res;
1311 }
1312 
isClassicViewVisible()1313 bool SectionDiskMenu::isClassicViewVisible()
1314 {
1315 	bool res = true;
1316 
1317 	for (pp_int32 i = 0; i < classicViewControls->size(); i++)
1318 		if (!classicViewControls->get(i)->isVisible())
1319 			res = false;
1320 
1321 	return res;
1322 }
1323 
flip()1324 void SectionDiskMenu::flip()
1325 {
1326 	if (isNormalViewVisible())
1327 	{
1328 		showNormalView(false);
1329 		showClassicView(true);
1330 		updateFilenameEditField(classicViewState);
1331 	}
1332 	else
1333 	{
1334 		showNormalView(true);
1335 		showClassicView(false);
1336 	}
1337 
1338 	PPScreen* screen = tracker.screen;
1339 
1340 	screen->paintControl(sectionContainer);
1341 }
1342 
updateFilenameEditFieldExtension(ClassicViewStates viewState)1343 void SectionDiskMenu::updateFilenameEditFieldExtension(ClassicViewStates viewState)
1344 {
1345 	if (currentActiveRadioGroup)
1346 	{
1347 		PPSystemString file = this->file->stripExtension();
1348 		if (file.length())
1349 		{
1350 			PPSystemString ext(currentActiveRadioGroup->getItem(currentActiveRadioGroup->getChoice()));
1351 			file.append(ext);
1352 			updateFilenameEditField(file);
1353 		}
1354 	}
1355 }
1356 
updateFilenameEditField(ClassicViewStates viewState)1357 void SectionDiskMenu::updateFilenameEditField(ClassicViewStates viewState)
1358 {
1359 	PPSystemString ext;
1360 
1361 	if (currentActiveRadioGroup)
1362 		ext = PPSystemString(currentActiveRadioGroup->getItem(currentActiveRadioGroup->getChoice()));
1363 
1364 	switch (viewState)
1365 	{
1366 		case BrowseAll:
1367 			*file = tracker.moduleEditor->getModuleFileName();
1368 			break;
1369 
1370 		case BrowseModules:
1371 			if (moduleTypeAdjust)
1372 				*file = tracker.moduleEditor->getModuleFileName();
1373 			else
1374 			{
1375 				*file = tracker.moduleEditor->getModuleFileName().stripExtension();
1376 				file->append(ext);
1377 			}
1378 			break;
1379 		case BrowseInstruments:
1380 		{
1381 			*file = tracker.moduleEditor->getInstrumentFileName(tracker.listBoxInstruments->getSelectedIndex());
1382 			file->append(ext);
1383 			break;
1384 		}
1385 		case BrowseSamples:
1386 		{
1387 			*file = tracker.moduleEditor->getSampleFileName(tracker.listBoxInstruments->getSelectedIndex(), tracker.listBoxSamples->getSelectedIndex());
1388 			file->append(ext);
1389 			break;
1390 		}
1391 		case BrowsePatterns:
1392 		{
1393 			*file = tracker.moduleEditor->getModuleFileName().stripExtension();
1394 			file->append(ext);
1395 			break;
1396 		}
1397 		case BrowseTracks:
1398 		{
1399 			*file = tracker.moduleEditor->getModuleFileName().stripExtension();
1400 			file->append(ext);
1401 			break;
1402 		}
1403 		case BrowseLAST:
1404 			break;
1405 
1406 	}
1407 
1408 	updateFilenameEditField(*file);
1409 }
1410 
updateFilenameEditField(const PPSystemString & fileName)1411 void SectionDiskMenu::updateFilenameEditField(const PPSystemString& fileName)
1412 {
1413 	editFieldCurrentFile->clear();
1414 
1415 	char* nameASCIIZ = fileName.toASCIIZ();
1416 	PPString str(nameASCIIZ);
1417 	editFieldCurrentFile->addItem(str);
1418 	delete[] nameASCIIZ;
1419 
1420 	*file = fileName;
1421 
1422 	tracker.screen->paintControl(editFieldCurrentFile);
1423 }
1424 
updateFilenameEditFieldFromBrowser()1425 void SectionDiskMenu::updateFilenameEditFieldFromBrowser()
1426 {
1427 	updateButtonStates();
1428 
1429 	if (listBoxFiles->currentSelectionIsFile())
1430 	{
1431 		updateFilenameEditField(listBoxFiles->getCurrentSelectedPathEntry()->getName());
1432 	}
1433 }
1434 
handleLoadOrStep()1435 void SectionDiskMenu::handleLoadOrStep()
1436 {
1437 	if (listBoxFiles->stepIntoCurrentSelection())
1438 	{
1439 		listBoxFiles->refreshFiles();
1440 		updateButtonStates();
1441 		tracker.screen->paintControl(listBoxFiles);
1442 	}
1443 	else
1444 	{
1445 		loadCurrentSelectedFile();
1446 	}
1447 }
1448 
loadCurrentSelectedFile()1449 void SectionDiskMenu::loadCurrentSelectedFile()
1450 {
1451 	PPSystemString fileFullPath = listBoxFiles->getCurrentPathAsString();
1452 	fileFullPath.append(listBoxFiles->getCurrentSelectedPathEntry()->getName());
1453 
1454 	switch (classicViewState)
1455 	{
1456 		case BrowseAll:
1457 			tracker.loadGenericFileType(fileFullPath);
1458 			break;
1459 		case BrowseModules:
1460 			tracker.loadTypeFromFile(FileTypes::FileTypeSongAllModules, fileFullPath);
1461 			break;
1462 		case BrowseInstruments:
1463 			tracker.loadTypeFromFile(FileTypes::FileTypeSongAllInstruments, fileFullPath);
1464 			break;
1465 		case BrowseSamples:
1466 			tracker.loadTypeFromFile(FileTypes::FileTypeSongAllSamples, fileFullPath);
1467 			break;
1468 		case BrowsePatterns:
1469 			tracker.loadTypeFromFile(FileTypes::FileTypePatternXP, fileFullPath);
1470 			break;
1471 		case BrowseTracks:
1472 			tracker.loadTypeFromFile(FileTypes::FileTypeTrackXT, fileFullPath);
1473 			break;
1474 		case BrowseLAST:
1475 			break;
1476 
1477 	}
1478 
1479 	updateFilenameEditFieldExtension(classicViewState);
1480 }
1481 
showOverwriteMessageBox()1482 void SectionDiskMenu::showOverwriteMessageBox()
1483 {
1484 	if (dialog)
1485 	{
1486 		delete dialog;
1487 		dialog = NULL;
1488 	}
1489 
1490 	dialog = new PPDialogBase(tracker.screen,
1491 							  responder,
1492 							  RESPONDMESSAGEBOX_OVERWRITE,
1493 							  "Overwrite existing file?");
1494 	dialog->show();
1495 }
1496 
prepareSave()1497 void SectionDiskMenu::prepareSave()
1498 {
1499 	if (editFieldCurrentFile->isEditing())
1500 		editFieldCurrentFile->commitChanges();
1501 
1502 	assureExtension();
1503 
1504 	PPSystemString fileFullPath = listBoxFiles->getCurrentPathAsString();
1505 
1506 	PPSystemString file = this->file->stripExtension();
1507 
1508 	if (file.length())
1509 	{
1510 		fileFullPath.append(*this->file);
1511 
1512 		if (XMFile::exists(fileFullPath))
1513 		{
1514 			showOverwriteMessageBox();
1515 		}
1516 		else
1517 		{
1518 			saveCurrent();
1519 		}
1520 	}
1521 }
1522 
saveCurrent()1523 void SectionDiskMenu::saveCurrent()
1524 {
1525 	PPSystemString fileFullPath = listBoxFiles->getCurrentPathAsString();
1526 
1527 	fileFullPath.append(*this->file);
1528 
1529 	bool res = true;
1530 
1531 	FileTypes saveType;
1532 
1533 	switch (classicViewState)
1534 	{
1535 		case BrowseAll:
1536 			ASSERT(false);
1537 			break;
1538 		case BrowseModules:
1539 		{
1540 			switch (currentActiveRadioGroup->getChoice())
1541 			{
1542 				case 0:
1543 					saveType = FileTypes::FileTypeSongXM;
1544 					break;
1545 
1546 				case 1:
1547 					saveType = FileTypes::FileTypeSongMOD;
1548 					break;
1549 
1550 				case 2:
1551 				{
1552 					tracker.sectionHDRecorder->setCurrentFileName(fileFullPath);
1553 					tracker.sectionSwitcher->showUpperSection(tracker.sectionHDRecorder);
1554 					if (dialog &&
1555 						tracker.screen->getModalControl() == dialog->getMessageBoxContainer())
1556 					{
1557 						tracker.screen->setModalControl(NULL);
1558 					}
1559 					return;
1560 				}
1561 			}
1562 
1563 			break;
1564 		}
1565 
1566 		case BrowseInstruments:
1567 			saveType = FileTypes::FileTypeInstrumentXI;
1568 			break;
1569 		case BrowseSamples:
1570 		{
1571 			switch (currentActiveRadioGroup->getChoice())
1572 			{
1573 				case 0:
1574 					saveType = FileTypes::FileTypeSampleWAV;
1575 					break;
1576 
1577 				case 1:
1578 					saveType = FileTypes::FileTypeSampleIFF;
1579 					break;
1580 			}
1581 
1582 			break;
1583 		}
1584 		case BrowsePatterns:
1585 			saveType = FileTypes::FileTypePatternXP;
1586 			break;
1587 		case BrowseTracks:
1588 			saveType = FileTypes::FileTypeTrackXT;
1589 			break;
1590 		case BrowseLAST:
1591 			break;
1592 
1593 	}
1594 
1595 	res = tracker.prepareSavingWithDialog(saveType);
1596 
1597 	if (tracker.savePanel)
1598 	{
1599 		delete tracker.savePanel;
1600 		tracker.savePanel = new PPDummySavePanel(fileFullPath);
1601 	}
1602 
1603 	if (res)
1604 	{
1605 		tracker.saveTypeWithDialog(saveType, this);
1606 	}
1607 	else
1608 	{
1609 		tracker.fileSystemChangedListener = this;
1610 	}
1611 
1612 	if (dialog &&
1613 		tracker.screen->getModalControl() == dialog->getMessageBoxContainer())
1614 	{
1615 		tracker.screen->setModalControl(NULL);
1616 	}
1617 
1618 }
1619 
showDeleteMessageBox()1620 void SectionDiskMenu::showDeleteMessageBox()
1621 {
1622 	if (!listBoxFiles->currentSelectionIsFile())
1623 		return;
1624 
1625 	showMessageBox(RESPONDMESSAGEBOX_DELETE, "Delete selected file?");
1626 }
1627 
deleteCurrent()1628 void SectionDiskMenu::deleteCurrent()
1629 {
1630 	PPSystemString fileFullPath = listBoxFiles->getCurrentPathAsString();
1631 
1632 	fileFullPath.append(listBoxFiles->getCurrentSelectedPathEntry()->getName());
1633 
1634 	XMFile::remove(fileFullPath);
1635 
1636 	reload();
1637 }
1638 
updateButtonStates(bool repaint)1639 void SectionDiskMenu::updateButtonStates(bool repaint/* = true*/)
1640 {
1641 	static const pp_uint32 IDs[] =
1642 	{
1643 		DISKMENU_CLASSIC_BUTTON_PREV,
1644 		DISKMENU_CLASSIC_BUTTON_NEXT,
1645 		DISKMENU_CLASSIC_BUTTON_PARENT,
1646 		DISKMENU_CLASSIC_BUTTON_ROOT,
1647 		DISKMENU_CLASSIC_BUTTON_HOME,
1648 		DISKMENU_CLASSIC_BUTTON_LOAD,
1649 		DISKMENU_CLASSIC_BUTTON_DELETE,
1650 		DISKMENU_CLASSIC_BUTTON_MAKEDIR
1651 	};
1652 
1653 	const bool states[] =
1654 	{
1655 		listBoxFiles->canPrev(),
1656 		listBoxFiles->canNext(),
1657 		listBoxFiles->canGotoParent(),
1658 		listBoxFiles->canGotoRoot(),
1659 		listBoxFiles->canGotoHome(),
1660 		true,
1661 		listBoxFiles->currentSelectionIsFile(),
1662 		false
1663 	};
1664 
1665 	ASSERT(sizeof(states)/sizeof(bool) == sizeof(IDs)/sizeof(pp_uint32));
1666 
1667 	pp_uint32 i;
1668 	for (i = 0; i < sizeof(IDs)/sizeof(pp_uint32); i++)
1669 	{
1670 		bool b = states[i];
1671 		PPButton* button = static_cast<PPButton*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(IDs[i]));
1672 		if (button->isClickable() != b)
1673 		{
1674 			button->setClickable(b);
1675 			if (repaint)
1676 				tracker.screen->paintControl(button);
1677 		}
1678 	}
1679 
1680 	const char* stateText = listBoxFiles->currentSelectionIsFile() ? "Load" : "Step";
1681 	PPButton* button = static_cast<PPButton*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_LOAD));
1682 	if (button->getText().compareTo(stateText) != 0)
1683 	{
1684 		button->setText(stateText);
1685 		if (repaint)
1686 			tracker.screen->paintControl(button);
1687 	}
1688 
1689 	stateText = sortAscending ? "\xfd" : "\xfe";
1690 	button = static_cast<PPButton*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_SORTORDER));
1691 	if (button->getText().compareTo(stateText) != 0)
1692 	{
1693 		button->setText(stateText);
1694 		if (repaint)
1695 			tracker.screen->paintControl(button);
1696 	}
1697 
1698 	static const char* sortTypes[PPListBoxFileBrowser::NumSortRules] = {"Name", "Size", "Extension"};
1699 	stateText = sortTypes[listBoxFiles->getSortType()];
1700 	button = static_cast<PPButton*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_SORTBY));
1701 	if (button->getText().compareTo(stateText) != 0)
1702 	{
1703 		button->setText(stateText);
1704 		if (repaint)
1705 			tracker.screen->paintControl(button);
1706 	}
1707 
1708 	PPString stateText2 = (listBoxFiles->getSize().height == fileBrowserExtent.height) ? TrackerConfig::stringButtonExtended : TrackerConfig::stringButtonCollapsed;
1709 	button = static_cast<PPButton*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_VEXTEND));
1710 	if (button->getText().compareTo(stateText2) != 0)
1711 	{
1712 		button->setText(stateText2);
1713 		if (repaint)
1714 			tracker.screen->paintControl(button);
1715 	}
1716 
1717 	stateText2 = (listBoxFiles->getSize().width == fileBrowserExtent.width) ? ">" : "<";
1718 	button = static_cast<PPButton*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_BUTTON_HEXTEND));
1719 	if (button->getText().compareTo(stateText2) != 0)
1720 	{
1721 		button->setText(stateText2);
1722 		if (repaint)
1723 			tracker.screen->paintControl(button);
1724 	}
1725 
1726 	// update directory buttons
1727 #if 0
1728 	for (i = DISKMENU_CLASSIC_BUTTON_DIR0; i <= DISKMENU_CLASSIC_BUTTON_DIR4; i++)
1729 	{
1730 		PPButton* button = static_cast<PPButton*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(i));
1731 		PPString strKey = getKeyFromPredefPathButton(button);
1732 		PPDictionaryKey* key = tracker.settingsDatabase->restore(strKey);
1733 		button->enable(key != NULL);
1734 	}
1735 #endif
1736 }
1737 
next(bool repaint)1738 void SectionDiskMenu::next(bool repaint/* = true*/)
1739 {
1740 	listBoxFiles->next();
1741 	tracker.screen->paintControl(listBoxFiles);
1742 	updateButtonStates();
1743 }
1744 
prev(bool repaint)1745 void SectionDiskMenu::prev(bool repaint/* = true*/)
1746 {
1747 	listBoxFiles->prev();
1748 	tracker.screen->paintControl(listBoxFiles);
1749 	updateButtonStates();
1750 }
1751 
parent(bool repaint)1752 void SectionDiskMenu::parent(bool repaint/* = true*/)
1753 {
1754 	listBoxFiles->gotoParent();
1755 	tracker.screen->paintControl(listBoxFiles);
1756 	updateButtonStates();
1757 }
1758 
root(bool repaint)1759 void SectionDiskMenu::root(bool repaint/* = true*/)
1760 {
1761 	listBoxFiles->gotoRoot();
1762 	tracker.screen->paintControl(listBoxFiles);
1763 	updateButtonStates();
1764 }
1765 
home(bool repaint)1766 void SectionDiskMenu::home(bool repaint/* = true*/)
1767 {
1768 	listBoxFiles->gotoHome();
1769 	tracker.screen->paintControl(listBoxFiles);
1770 	updateButtonStates();
1771 }
1772 
reload(bool repaint)1773 void SectionDiskMenu::reload(bool repaint/* = true*/)
1774 {
1775 	PPPathEntry* pathEntry = NULL;
1776 	const PPPathEntry* src = listBoxFiles->getCurrentSelectedPathEntry();
1777 
1778 	if (src)
1779 		pathEntry = src->clone();
1780 
1781 	listBoxFiles->saveState();
1782 	listBoxFiles->refreshFiles();
1783 	listBoxFiles->restoreState(false);
1784 
1785 	if (pathEntry)
1786 	{
1787 		for (pp_int32 i = 0; i < listBoxFiles->getNumItems(); i++)
1788 		{
1789 			if (pathEntry->compareTo(*listBoxFiles->getPathEntry(i)))
1790 			{
1791 				listBoxFiles->setSelectedIndex(i, false);
1792 				break;
1793 			}
1794 		}
1795 		delete pathEntry;
1796 	}
1797 
1798 	if (repaint)
1799 		tracker.screen->paintControl(listBoxFiles);
1800 
1801 }
1802 
updateFilter(bool repaint)1803 void SectionDiskMenu::updateFilter(bool repaint/* = true*/)
1804 {
1805 	FileExtProvider fileExtProvider;
1806 
1807 	listBoxFiles->clearExtensions();
1808 
1809 	const char* const* extensions = NULL;
1810 
1811 	if (static_cast<PPCheckBox*>(static_cast<PPContainer*>(sectionContainer)->getControlByID(DISKMENU_CLASSIC_CHECKBOX_FILTEREXTENSIONS))->isChecked())
1812 	{
1813 		switch (classicViewState)
1814 		{
1815 			case BrowseModules:
1816 				extensions = fileExtProvider.getModuleExtensions();
1817 				break;
1818 			case BrowseInstruments:
1819 				extensions = fileExtProvider.getInstrumentExtensions();
1820 				break;
1821 			case BrowseSamples:
1822 				extensions = fileExtProvider.getSampleExtensions();
1823 				break;
1824 			case BrowsePatterns:
1825 				extensions = fileExtProvider.getPatternExtensions();
1826 				break;
1827 			case BrowseTracks:
1828 				extensions = fileExtProvider.getTrackExtensions();
1829 				break;
1830 			case BrowseAll:
1831 			case BrowseLAST:
1832 				break;
1833 		}
1834 	}
1835 
1836 	if (extensions)
1837 		listBoxFiles->addExtensions(extensions);
1838 
1839 	reload(repaint);
1840 }
1841 
switchState(ClassicViewStates viewState)1842 void SectionDiskMenu::switchState(ClassicViewStates viewState)
1843 {
1844 	classicViewState = viewState;
1845 	updateFilter(false);
1846 	updateClassicView();
1847 	updateFilenameEditField(classicViewState);
1848 }
1849 
resizeBrowserVertically()1850 void SectionDiskMenu::resizeBrowserVertically()
1851 {
1852 	PPSize size = listBoxFiles->getSize();
1853 	PPPoint location = listBoxFiles->getLocation();
1854 	if (size.height == fileBrowserExtent.height)
1855 	{
1856 		size.height-=13;
1857 		listBoxFiles->setSize(size);
1858 		location.y+=13;
1859 		listBoxFiles->setLocation(location);
1860 	}
1861 	else
1862 	{
1863 		size.height+=13;
1864 		listBoxFiles->setSize(size);
1865 		location.y-=13;
1866 		listBoxFiles->setLocation(location);
1867 	}
1868 
1869 	fitDirButtons();
1870 
1871 	updateClassicView();
1872 }
1873 
resizeBrowserHorizontally()1874 void SectionDiskMenu::resizeBrowserHorizontally()
1875 {
1876 	PPSize size = listBoxFiles->getSize();
1877 	if (size.width == fileBrowserExtent.width)
1878 	{
1879 		size.width-=32;
1880 		listBoxFiles->setSize(size);
1881 	}
1882 	else
1883 	{
1884 		size.width+=32;
1885 		listBoxFiles->setSize(size);
1886 	}
1887 
1888 	updateClassicView();
1889 }
1890 
fitDirButtons()1891 void SectionDiskMenu::fitDirButtons()
1892 {
1893 	pp_int32 height = (listBoxFiles->getSize().height-2) / 6;
1894 
1895 	pp_int32 cy = ((listBoxFiles->getSize().height-2) - (height * 6));
1896 
1897 	pp_int32 y = listBoxFiles->getLocation().y + cy;
1898 
1899 	for (pp_int32 i = DISKMENU_CLASSIC_BUTTON_DIR0; i <= DISKMENU_CLASSIC_BUTTON_STOREDIR; i++)
1900 	{
1901 		PPControl* ctrl = static_cast<PPContainer*>(sectionContainer)->getControlByID(i);
1902 		PPPoint p = ctrl->getLocation();
1903 		p.y = y;
1904 		ctrl->setLocation(p);
1905 		PPSize s = ctrl->getSize();
1906 		s.height = height-1;
1907 		ctrl->setSize(s);
1908 		y+=height;
1909 	}
1910 }
1911 
getKeyFromPredefPathButton(PPControl * button)1912 PPString SectionDiskMenu::getKeyFromPredefPathButton(PPControl* button)
1913 {
1914 	pp_int32 id = button->getID();
1915 
1916 	id -= DISKMENU_CLASSIC_BUTTON_DIR0;
1917 
1918 	if (id >= 0 && id < 5)
1919 	{
1920 		static const char* keys[BrowseLAST] =
1921 		{
1922 			"PREDEF_PATH_ALL",
1923 			"PREDEF_PATH_MODULES",
1924 			"PREDEF_PATH_INSTRUMENTS",
1925 			"PREDEF_PATH_SAMPLES",
1926 			"PREDEF_PATH_PATTERNS",
1927 			"PREDEF_PATH_TRACKS",
1928 		};
1929 
1930 		char result[1024];
1931 
1932 		sprintf(result, "%s_%d", keys[classicViewState], id);
1933 
1934 		return PPString(result);
1935 	}
1936 	else return "";
1937 }
1938 
assureExtension()1939 void SectionDiskMenu::assureExtension()
1940 {
1941 	updateFilenameEditFieldExtension(classicViewState);
1942 }
1943 
1944 
1945 
1946 
1947