1 /*
2  *  tracker/SectionSamples.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  *  SectionSamples.cpp
25  *  MilkyTracker
26  *
27  *  Created by Peter Barth on 15.04.05.
28  *
29  */
30 
31 #include "SectionSamples.h"
32 
33 #include "PPUI.h"
34 #include "TransparentContainer.h"
35 #include "Tracker.h"
36 #include "TrackerConfig.h"
37 #include "ModuleEditor.h"
38 #include "SamplePlayer.h"
39 #include "PatternEditorControl.h"
40 #include "SampleEditorControl.h"
41 #include "SectionInstruments.h"
42 #include "DialogBase.h"
43 
44 // OS Interface
45 #include "PPOpenPanel.h"
46 #include "PPSavePanel.h"
47 
48 #include "ControlIDs.h"
49 
50 enum ControlIDs
51 {
52 	STATICTEXT_DISPLAY = 0xF000,
53 	STATICTEXT_LENGTH,
54 	STATICTEXT_REPSTART,
55 	STATICTEXT_REPLEN,
56 	BUTTON_SHOWRANGE,
57 	BUTTON_FLIPNUMBERFORMAT,
58 	// Only low-res
59 	CONTAINER_SHOWCONTEXTMENU,
60 	BUTTON_SHOWCONTEXTMENU
61 };
62 
63 // Class which responds to message box clicks
64 class DialogResponderSamples : public DialogResponder
65 {
66 private:
67 	SectionSamples& section;
68 
69 public:
DialogResponderSamples(SectionSamples & section)70 	DialogResponderSamples(SectionSamples& section) :
71 		section(section)
72 	{
73 	}
74 
ActionOkay(PPObject * sender)75 	virtual pp_int32 ActionOkay(PPObject* sender)
76 	{
77 		switch (reinterpret_cast<PPDialogBase*>(sender)->getID())
78 		{
79 			case MESSAGEBOX_CLEARSAMPLE:
80 				section.getSampleEditorControl()->getSampleEditor()->clearSample();
81 				break;
82 
83 			case MESSAGEBOX_CROPSAMPLE:
84 				section.getSampleEditorControl()->getSampleEditor()->cropSample();
85 				break;
86 
87 			case MESSAGEBOX_MINIMIZESAMPLE:
88 				section.getSampleEditorControl()->getSampleEditor()->minimizeSample();
89 				break;
90 
91 			case MESSAGEBOX_CONVERTSAMPLE:
92 				section.getSampleEditorControl()->getSampleEditor()->convertSampleResolution(true);
93 				section.getSampleEditorControl()->showAll();
94 				break;
95 		}
96 		return 0;
97 	}
98 
ActionNo(PPObject * sender)99 	virtual pp_int32 ActionNo(PPObject* sender)
100 	{
101 		switch (reinterpret_cast<PPDialogBase*>(sender)->getID())
102 		{
103 			case MESSAGEBOX_CONVERTSAMPLE:
104 				section.getSampleEditorControl()->getSampleEditor()->convertSampleResolution(false);
105 				section.getSampleEditorControl()->showAll();
106 				break;
107 		}
108 		return 0;
109 	}
110 };
111 
SectionSamples(Tracker & theTracker)112 SectionSamples::SectionSamples(Tracker& theTracker) :
113 	SectionAbstract(theTracker, NULL, new DialogResponderSamples(*this)),
114 	containerEntire(NULL),
115 	visible(false),
116 	sampleEditorControl(NULL),
117 	currentSamplePlayNote(ModuleEditor::MAX_NOTE/2),
118 	showRangeOffsets(false),
119 	offsetFormat(0)
120 {
121 }
122 
~SectionSamples()123 SectionSamples::~SectionSamples()
124 {
125 }
126 
handleEvent(PPObject * sender,PPEvent * event)127 pp_int32 SectionSamples::handleEvent(PPObject* sender, PPEvent* event)
128 {
129 	PPScreen* screen = tracker.screen;
130 	ModuleEditor* moduleEditor = tracker.moduleEditor;
131 	SampleEditor* sampleEditor = sampleEditorControl->getSampleEditor();
132 
133 	if (event->getID() == eUpdateChanged)
134 	{
135 		tracker.updateWindowTitle();
136 	}
137 	else if (event->getID() == eCommand || event->getID() == eCommandRepeat)
138 	{
139 		switch (reinterpret_cast<PPControl*>(sender)->getID())
140 		{
141 			// load sample
142 			case BUTTON_SAMPLE_LOAD:
143 			{
144 				if (event->getID() != eCommand)
145 					break;
146 
147 				tracker.loadType(FileTypes::FileTypeSongAllSamples);
148 				break;
149 			}
150 
151 			// save sample
152 			case BUTTON_SAMPLE_SAVE:
153 			{
154 				if (event->getID() != eCommand)
155 					break;
156 
157 				if (isEmptySample())
158 					tracker.showMessageBox(MESSAGEBOX_UNIVERSAL, "Sample is empty.", Tracker::MessageBox_OK);
159 				else
160 					tracker.saveType(tracker.getCurrentSelectedSampleSaveType());
161 				break;
162 			}
163 
164 			case BUTTON_SAMPLE_PLAY_UP:
165 				if (currentSamplePlayNote < 95)
166 					currentSamplePlayNote++;
167 				refresh();
168 				break;
169 
170 			case BUTTON_SAMPLE_PLAY_DOWN:
171 				if (currentSamplePlayNote > 0)
172 					currentSamplePlayNote--;
173 				refresh();
174 				break;
175 
176 			case BUTTON_SAMPLE_PLAY_WAVE:
177 			{
178 				SamplePlayer samplePlayer(*moduleEditor, *tracker.playerController);
179 				samplePlayer.playCurrentSample(currentSamplePlayNote);
180 				break;
181 			}
182 
183 			case BUTTON_SAMPLE_PLAY_RANGE:
184 			{
185 				SamplePlayer samplePlayer(*moduleEditor, *tracker.playerController);
186 				samplePlayer.playCurrentSampleSelectionRange(currentSamplePlayNote);
187 				break;
188 			}
189 
190 			case BUTTON_SAMPLE_PLAY_DISPLAY:
191 			{
192 				SamplePlayer samplePlayer(*moduleEditor, *tracker.playerController);
193 				samplePlayer.playSample(*sampleEditor->getSample(),
194 										currentSamplePlayNote,
195 										sampleEditorControl->getCurrentPosition(),
196 										sampleEditorControl->getCurrentPosition() + sampleEditorControl->getCurrentDisplayRange());
197 				break;
198 			}
199 
200 			case BUTTON_SAMPLE_PLAY_STOP:
201 			{
202 				SamplePlayer samplePlayer(*moduleEditor, *tracker.playerController);
203 				samplePlayer.stopSamplePlayback();
204 				break;
205 			}
206 
207 			case BUTTON_SAMPLE_RANGE_SHOW:
208 				if (event->getID() != eCommand)
209 					break;
210 
211 				sampleEditorControl->showRange();
212 				refresh();
213 				break;
214 
215 			case BUTTON_SAMPLE_RANGE_ALL:
216 				if (event->getID() != eCommand)
217 					break;
218 
219 				sampleEditorControl->rangeAll(true);
220 				break;
221 
222 			case BUTTON_SAMPLE_RANGE_CLEAR:
223 				sampleEditorControl->rangeClear(true);
224 				break;
225 
226 			case BUTTON_SAMPLE_RANGE_ZOOMOUT:
227 				if (event->getID() != eCommand)
228 					break;
229 
230 				sampleEditorControl->zoomOut();
231 				refresh();
232 				break;
233 
234 			case BUTTON_SAMPLE_RANGE_SHOWALL:
235 				if (event->getID() != eCommand)
236 					break;
237 
238 				sampleEditorControl->showAll();
239 				refresh();
240 				break;
241 
242 			case BUTTON_SAMPLE_APPLY_LASTFILTER:
243 				if (event->getID() != eCommand)
244 					break;
245 
246 				sampleEditor->tool_applyLastFilter();
247 				break;
248 
249 			case BUTTON_SAMPLE_UNDO:
250 				if (event->getID() != eCommand)
251 					break;
252 
253 				sampleEditor->undo();
254 				break;
255 
256 			case BUTTON_SAMPLE_REDO:
257 				if (event->getID() != eCommand)
258 					break;
259 
260 				sampleEditor->redo();
261 				break;
262 
263 			case BUTTON_SAMPLE_EDIT_CUT:
264 				if (event->getID() != eCommand)
265 					break;
266 
267 				sampleEditor->cut();
268 				break;
269 
270 			case BUTTON_SAMPLE_EDIT_COPY:
271 				if (event->getID() != eCommand)
272 					break;
273 
274 				sampleEditor->copy();
275 				break;
276 
277 			case BUTTON_SAMPLE_EDIT_PASTE:
278 				if (event->getID() != eCommand)
279 					break;
280 
281 				sampleEditor->paste();
282 				break;
283 
284 			case BUTTON_SAMPLE_EDIT_REPSTARTPLUS:
285 				if (showRangeOffsets)
286 				{
287 					sampleEditorControl->increaseRangeStart();
288 					refresh();
289 				}
290 				else
291 					sampleEditor->increaseRepeatStart();
292 				break;
293 
294 			case BUTTON_SAMPLE_EDIT_REPSTARTMINUS:
295 				if (showRangeOffsets)
296 				{
297 					sampleEditorControl->decreaseRangeStart();
298 					refresh();
299 				}
300 				else
301 					sampleEditor->decreaseRepeatStart();
302 				break;
303 
304 			case BUTTON_SAMPLE_EDIT_REPLENPLUS:
305 				if (showRangeOffsets)
306 				{
307 					sampleEditorControl->increaseRangeEnd();
308 					refresh();
309 				}
310 				else
311 					sampleEditor->increaseRepeatLength();
312 				break;
313 
314 			case BUTTON_SAMPLE_EDIT_REPLENMINUS:
315 				if (showRangeOffsets)
316 				{
317 					sampleEditorControl->decreaseRangeEnd();
318 					refresh();
319 				}
320 				else
321 					sampleEditor->decreaseRepeatLength();
322 				break;
323 
324 			case BUTTON_SAMPLE_EDIT_CLEAR:
325 			{
326 				if (event->getID() != eCommand)
327 					break;
328 
329 				handleClearSample();
330 				break;
331 			}
332 
333 			case BUTTON_SAMPLE_EDIT_MINIMIZE:
334 			{
335 				if (event->getID() != eCommand)
336 					break;
337 
338 				handleMinimizeSample();
339 				break;
340 			}
341 
342 			case BUTTON_SAMPLE_EDIT_CROP:
343 			{
344 				if (event->getID() != eCommand)
345 					break;
346 
347 				handleCropSample();
348 				break;
349 			}
350 
351 			case BUTTON_SAMPLE_EDIT_VOL:
352 			{
353 				if (event->getID() != eCommand)
354 					break;
355 
356 				getSampleEditorControl()->invokeSetSampleVolume();
357 				break;
358 			}
359 
360 			case BUTTON_SAMPLE_EDIT_DRAW:
361 			{
362 				if (event->getID() != eCommand)
363 					break;
364 
365 				getSampleEditorControl()->setDrawMode(!getSampleEditorControl()->getDrawMode());
366 				PPButton* button = reinterpret_cast<PPButton*>(sender);
367 				button->setPressed(getSampleEditorControl()->getDrawMode());
368 				screen->paintControl(button);
369 				break;
370 			}
371 
372 			case BUTTON_SAMPLE_ZOOM_PLUS:
373 				getSampleEditorControl()->scrollWheelZoomIn();
374 				break;
375 
376 			case BUTTON_SAMPLE_ZOOM_MINUS:
377 				getSampleEditorControl()->scrollWheelZoomOut();
378 				break;
379 
380 
381 			case STATICTEXT_REPSTART:
382 			case STATICTEXT_REPLEN:
383 			case STATICTEXT_SAMPLE_REPSTART:
384 			case STATICTEXT_SAMPLE_REPLENGTH:
385 			case BUTTON_SHOWRANGE:
386 				if (event->getID() != eCommand)
387 					break;
388 
389 				showRangeOffsets = !showRangeOffsets;
390 				refresh();
391 				break;
392 
393 			case BUTTON_FLIPNUMBERFORMAT:
394 				if (event->getID() != eCommand)
395 					break;
396 
397 				toggleOffsetFormat();
398 				refresh();
399 				break;
400 
401 			case BUTTON_SHOWCONTEXTMENU:
402 				if (event->getID() != eCommand)
403 					break;
404 
405 				getSampleEditorControl()->invokeContextMenu(reinterpret_cast<PPControl*>(sender)->getLocation(), false);
406 				break;
407 
408 		}
409 	}
410 	else if (event->getID() == eSelection)
411 	{
412 
413 		switch (reinterpret_cast<PPControl*>(sender)->getID())
414 		{
415 			case RADIOGROUP_SAMPLE_RESTYPE:
416 			{
417 				handleConvertSampleResolution();
418 				break;
419 			}
420 
421 			case RADIOGROUP_SAMPLE_LOOPTYPE:
422 			{
423 				sampleEditor->setLoopType((mp_ubyte)((reinterpret_cast<PPRadioGroup*>(sender)->getChoice())&3));
424 				refresh();
425 				break;
426 			}
427 		}
428 
429 	}
430 	else if (event->getID() == eUpdated)
431 	{
432 		switch (reinterpret_cast<PPControl*>(sender)->getID())
433 		{
434 			case SAMPLE_EDITOR:
435 			{
436 				// redraw sample editor
437 				realUpdate(true, true, false);
438 				break;
439 			}
440 		}
441 	}
442 	else if (event->getID() == eLMouseDown)
443 	{
444 		switch (reinterpret_cast<PPControl*>(sender)->getID())
445 		{
446 			// Play sample preview from offset position
447 			case SAMPLE_EDITOR:
448 			{
449 				SamplePlayer samplePlayer(*moduleEditor, *tracker.playerController);
450 				samplePlayer.playCurrentSampleFromOffset(event->getMetaData(), currentSamplePlayNote);
451 				break;
452 			}
453 		}
454 	}
455 	else if (event->getID() == eLMouseUp)
456 	{
457 		switch (reinterpret_cast<PPControl*>(sender)->getID())
458 		{
459 			// Stop sample preview
460 			case SAMPLE_EDITOR:
461 			{
462 				SamplePlayer samplePlayer(*moduleEditor, *tracker.playerController);
463 				samplePlayer.stopSamplePlayback();
464 				break;
465 			}
466 		}
467 	}
468 
469 	return 0;
470 }
471 
init()472 void SectionSamples::init()
473 {
474 	init(0, tracker.MAXEDITORHEIGHT()-tracker.SAMPLESECTIONDEFAULTHEIGHT());
475 }
476 
init(pp_int32 x,pp_int32 y)477 void SectionSamples::init(pp_int32 x, pp_int32 y)
478 {
479 	PPScreen* screen = tracker.screen;
480 
481 	containerEntire = new PPTransparentContainer(CONTAINER_ENTIRESMPSECTION, screen, this,
482 												 PPPoint(0, 0), PPSize(screen->getWidth(), screen->getHeight()));
483 
484 #ifndef __LOWRES__
485 	pp_int32 conSize1 = (pp_int32)(screen->getWidth()*0.1359375f);
486 	pp_int32 conSize2 = (pp_int32)(screen->getWidth()*0.215625f);
487 	pp_int32 conSize3 = (pp_int32)(screen->getWidth()*0.0734375f);
488 	pp_int32 conSize4 = (pp_int32)(screen->getWidth()*0.075f);
489 	pp_int32 conSize5 = (pp_int32)(screen->getWidth()*0.128125f);
490 	pp_int32 conSize6 = (pp_int32)(screen->getWidth()*0.103125f);
491 	pp_int32 conSize7 = (pp_int32)(screen->getWidth()*0.2525f);
492 
493 	pp_int32 dHeight = 12*4+8;
494 	pp_int32 bHeight = (dHeight-4)/3;
495 	pp_int32 bHeightm = bHeight-1;
496 
497 	pp_int32 cHeight = tracker.SAMPLESECTIONDEFAULTHEIGHT() - dHeight - 1;
498 
499 	// sample editor
500 	PPContainer* sampleEditorContainer = new PPContainer(CONTAINER_SAMPLEEDITOR, screen, this, PPPoint(x, y), PPSize(screen->getWidth(), cHeight), false);
501 	sampleEditorContainer->setColor(TrackerConfig::colorThemeMain);
502 
503 	sampleEditorControl = new SampleEditorControl(SAMPLE_EDITOR, screen, this, PPPoint(x+2, y+2), PPSize(sampleEditorContainer->getSize().width-4, sampleEditorContainer->getSize().height-4));
504 	sampleEditorControl->attachSampleEditor(tracker.moduleEditor->getSampleEditor());
505 	sampleEditorControl->setBorderColor(TrackerConfig::colorThemeMain);
506 
507 	sampleEditorContainer->addControl(sampleEditorControl);
508 
509 	containerEntire->addControl(sampleEditorContainer);
510 
511 	pp_int32 x2 = x;
512 	pp_int32 y2 = sampleEditorContainer->getSize().height + y;
513 
514 	PPContainer* container = new PPContainer(CONTAINER_SAMPLE_PLAY, screen, this, PPPoint(x2, y2), PPSize(conSize1,dHeight), false);
515 	container->setColor(TrackerConfig::colorThemeMain);
516 
517 	container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 4, y2 + 2), "Play:", true));
518 	container->addControl(new PPStaticText(STATICTEXT_SAMPLE_PLAYNOTE, screen, this, PPPoint(x2 + 8, y2 + 2 + bHeight+2), "C-5", false));
519 
520 	pp_int32 size = (pp_int32)(conSize1*0.2183908045977f);
521 	pp_int32 size2 = (pp_int32)(conSize1*0.4367816091954f);
522 	pp_int32 size3 = (pp_int32)(conSize1/*0.2988505747126f*/*0.3218390804598f);
523 
524 	PPButton* button = new PPButton(BUTTON_SAMPLE_PLAY_UP, screen, this, PPPoint(x2+size2, y2+2+bHeight), PPSize(size, bHeightm));
525 	button->setText("Up");
526 	container->addControl(button);
527 
528 	button = new PPButton(BUTTON_SAMPLE_PLAY_DOWN, screen, this, PPPoint(x2+size2, y2+2+bHeight*2), PPSize(size, bHeightm+1));
529 	button->setText("Dn");
530 	container->addControl(button);
531 
532 	button = new PPButton(BUTTON_SAMPLE_PLAY_STOP, screen, this, PPPoint(x2+2, y2+2+bHeight*2), PPSize(size2-3, bHeightm+1));
533 	button->setText("Stop");
534 	container->addControl(button);
535 
536 	button = new PPButton(BUTTON_SAMPLE_PLAY_WAVE, screen, this, PPPoint(x2+2 + size+size2-1, y2+2), PPSize(size3, bHeightm));
537 	button->setText("Wav");
538 	container->addControl(button);
539 
540 	button = new PPButton(BUTTON_SAMPLE_PLAY_RANGE, screen, this, PPPoint(x2+2 + size+size2-1, y2+2+bHeight), PPSize(size3, bHeightm));
541 	button->setText("Rng");
542 	container->addControl(button);
543 
544 	button = new PPButton(BUTTON_SAMPLE_PLAY_DISPLAY, screen, this, PPPoint(x2+2 + size+size2-1, y2+2+bHeight*2), PPSize(size3, bHeightm+1));
545 	button->setText("Dsp");
546 	container->addControl(button);
547 
548 	containerEntire->addControl(container);
549 
550 	size = (conSize2-4)/2-1;
551 
552 	x2+=container->getSize().width;
553 	container = new PPContainer(CONTAINER_SAMPLE_RANGE, screen, this, PPPoint(x2, y2), PPSize(conSize2,dHeight), false);
554 	container->setColor(TrackerConfig::colorThemeMain);
555 
556 	button = new PPButton(BUTTON_SAMPLE_RANGE_SHOW, screen, this, PPPoint(x2+2, y2+2), PPSize(size, bHeightm));
557 	button->setText("Show rng");
558 	container->addControl(button);
559 
560 	button = new PPButton(BUTTON_SAMPLE_RANGE_ALL, screen, this, PPPoint(x2+2, y2+2+bHeight), PPSize(size, bHeightm));
561 	button->setText("Rng all");
562 	container->addControl(button);
563 
564 	pp_int32 h = button->getSize().width;
565 
566 	button = new PPButton(BUTTON_SAMPLE_UNDO, screen, this, PPPoint(x2+2, y2+2+bHeight*2), PPSize((size>>1), bHeightm+1));
567 	button->setText("Undo");
568 	container->addControl(button);
569 
570 	button = new PPButton(BUTTON_SAMPLE_REDO, screen, this, PPPoint(x2+2 + (size>>1)+1, y2+2+bHeight*2), PPSize(h-(size>>1)-1, bHeightm+1));
571 	button->setText("Redo");
572 	container->addControl(button);
573 
574 	button = new PPButton(BUTTON_SAMPLE_RANGE_ZOOMOUT, screen, this, PPPoint(x2+2 + size+1, y2+2), PPSize(size, bHeightm));
575 	button->setText("Zoom out");
576 	container->addControl(button);
577 
578 	button = new PPButton(BUTTON_SAMPLE_RANGE_SHOWALL, screen, this, PPPoint(x2+2 + size+1, y2+2+bHeight), PPSize(size, bHeightm));
579 	button->setText("Show all");
580 	container->addControl(button);
581 
582 	button = new PPButton(BUTTON_SAMPLE_APPLY_LASTFILTER, screen, this, PPPoint(x2+2 + size+1, y2+2+bHeight*2), PPSize(size, bHeightm+1));
583 	button->setText("Redo filter");
584 	container->addControl(button);
585 
586 	containerEntire->addControl(container);
587 
588 	x2 += container->getSize().width;
589 
590 	size = (conSize3-5);
591 
592 	container = new PPContainer(CONTAINER_SAMPLE_EDIT1, screen, this, PPPoint(x2, y2), PPSize(conSize3,dHeight), false);
593 	container->setColor(TrackerConfig::colorThemeMain);
594 
595 	button = new PPButton(BUTTON_SAMPLE_EDIT_CUT, screen, this, PPPoint(x2+2, y2+2), PPSize(size, bHeightm));
596 	button->setText("Cut");
597 	container->addControl(button);
598 
599 	button = new PPButton(BUTTON_SAMPLE_EDIT_COPY, screen, this, PPPoint(x2+2, y2+2+bHeight), PPSize(size, bHeightm));
600 	button->setText("Copy");
601 	container->addControl(button);
602 
603 	button = new PPButton(BUTTON_SAMPLE_EDIT_PASTE, screen, this, PPPoint(x2+2, y2+2+bHeight*2), PPSize(size, bHeightm+1));
604 	button->setText("Paste");
605 	container->addControl(button);
606 
607 	containerEntire->addControl(container);
608 
609 	x2 += container->getSize().width;
610 
611 	size = (conSize4-5);
612 
613 	container = new PPContainer(CONTAINER_SAMPLE_EDIT2, screen, this, PPPoint(x2, y2), PPSize(conSize4,dHeight), false);
614 	container->setColor(TrackerConfig::colorThemeMain);
615 
616 	button = new PPButton(BUTTON_SAMPLE_EDIT_CROP, screen, this, PPPoint(x2+2, y2+2), PPSize(size, bHeightm));
617 	button->setText("Crop");
618 	container->addControl(button);
619 
620 	button = new PPButton(BUTTON_SAMPLE_EDIT_VOL, screen, this, PPPoint(x2+2, y2+2+bHeight), PPSize(size, bHeightm));
621 	button->setText("Vol");
622 	container->addControl(button);
623 
624 	button = new PPButton(BUTTON_SAMPLE_EDIT_DRAW, screen, this, PPPoint(x2+2, y2+2+bHeight*2), PPSize(size, bHeightm+1), true, true, false);
625 	button->setText("Draw");
626 	container->addControl(button);
627 
628 	containerEntire->addControl(container);
629 
630 	x2+=container->getSize().width;
631 
632 	//y2+=container->getSize().height;
633 
634 	container = new PPContainer(CONTAINER_SAMPLE_EDIT3, screen, this, PPPoint(x2, y2), PPSize(conSize5, 56), false);
635 	container->setColor(TrackerConfig::colorThemeMain);
636 
637 	PPRadioGroup* radioGroup = new PPRadioGroup(RADIOGROUP_SAMPLE_LOOPTYPE, screen, this, PPPoint(x2+1, y2-2), PPSize(conSize5-1, 4*14));
638 	radioGroup->setColor(TrackerConfig::colorThemeMain);
639 
640 	radioGroup->addItem("No loop");
641 	radioGroup->addItem("Forward");
642 	if (screen->getWidth() < 800)
643 		radioGroup->addItem("Bi-dir");
644 	else
645 		radioGroup->addItem("Ping-pong");
646 	radioGroup->addItem("One shot");
647 
648 	container->addControl(radioGroup);
649 
650 	containerEntire->addControl(container);
651 
652 	// load container
653 	pp_int32 ty = y2;
654 
655 	x2+=container->getSize().width;
656 
657 	container = new PPContainer(CONTAINER_SAMPLE_EDIT4, screen, this, PPPoint(x2, ty), PPSize(conSize6,27), false);
658 	container->setColor(TrackerConfig::colorThemeMain);
659 
660 	radioGroup = new PPRadioGroup(RADIOGROUP_SAMPLE_RESTYPE, screen, this, PPPoint(x2+1, ty-2), PPSize(conSize6-1, 28));
661 	radioGroup->setColor(TrackerConfig::colorThemeMain);
662 
663 	radioGroup->addItem("8-bit");
664 	radioGroup->addItem("16-bit");
665 
666 	container->addControl(radioGroup);
667 
668 	containerEntire->addControl(container);
669 
670 	ty+=container->getSize().height;
671 
672 	// ----------- load/save
673 	size = (conSize6-4)/2-1;
674 
675 	container = new PPContainer(CONTAINER_SAMPLE_LOADSAVE, screen, this, PPPoint(x2, ty), PPSize(conSize6,29), false);
676 	container->setColor(TrackerConfig::colorThemeMain);
677 
678 	button = new PPButton(BUTTON_SAMPLE_LOAD, screen, this, PPPoint(x2+2, ty+2), PPSize(size, 12));
679 	button->setText("Load");
680 	container->addControl(button);
681 
682 	size2 = (container->getLocation().x + container->getSize().width) - (x2+2+size+1) - 3;
683 
684 	button = new PPButton(BUTTON_SAMPLE_SAVE, screen, this, PPPoint(x2+2+size+1, ty+2), PPSize(size2, 12));
685 	button->setText("Save");
686 	container->addControl(button);
687 
688 	// ----------- exit
689 	pp_int32 y3 = ty + 13;
690 
691 	button = new PPButton(BUTTON_SAMPLEEDITOR_EXIT, screen, &tracker, PPPoint(x2+2, y3+2), PPSize(conSize6-5, 12));
692 	button->setText("Exit");
693 	container->addControl(button);
694 
695 	containerEntire->addControl(container);
696 
697 	x2+=container->getSize().width;
698 
699 	conSize7 = screen->getWidth()-x2;
700 
701 	container = new PPContainer(CONTAINER_SAMPLE_EDIT5, screen, this, PPPoint(x2, y2), PPSize(conSize7,56), false);
702 	container->setColor(TrackerConfig::colorThemeMain);
703 
704 	container->addControl(new PPStaticText(STATICTEXT_DISPLAY, NULL, NULL, PPPoint(x2 + 2 + 2, y2 + 4), screen->getWidth() < 800 ? "Displ." : "Display", true));
705 	container->addControl(new PPStaticText(STATICTEXT_LENGTH, NULL, NULL, PPPoint(x2 + 2 + 2, y2 + 4+13), "Length", true));
706 	container->addControl(new PPStaticText(STATICTEXT_REPSTART, screen, this, PPPoint(x2 + 2 + 2, y2 + 4+13*2), "Repeat", true));
707 	container->addControl(new PPStaticText(STATICTEXT_REPLEN, screen, this, PPPoint(x2 + 2 + 2, y2 + 4+13*3), "Replen.", true));
708 
709 	x2 = screen->getWidth()-43-3 - 4 - 8*8;
710 
711 	container->addControl(new PPStaticText(STATICTEXT_SAMPLE_DISPLAY, screen, this, PPPoint(x2, y2 + 4), "12345678", false));
712 	container->addControl(new PPStaticText(STATICTEXT_SAMPLE_LENGTH, screen, this, PPPoint(x2, y2 + 4+13), "12345678", false));
713 	container->addControl(new PPStaticText(STATICTEXT_SAMPLE_REPSTART, screen, this, PPPoint(x2, y2 + 4+13*2), "12345678", false));
714 	container->addControl(new PPStaticText(STATICTEXT_SAMPLE_REPLENGTH, screen, this, PPPoint(x2, y2 + 4+13*3), "12345678", false));
715 
716 	x2 = screen->getWidth()-43-3;
717 
718 	button = new PPButton(BUTTON_SAMPLE_EDIT_CLEAR, screen, this, PPPoint(x2, y2+2), PPSize(43, 12));
719 	button->setText("Clear");
720 	container->addControl(button);
721 
722 	button = new PPButton(BUTTON_SAMPLE_EDIT_MINIMIZE, screen, this, PPPoint(x2, y2+2+13), PPSize(29, 12));
723 	button->setText("Min");
724 	container->addControl(button);
725 
726 	button = new PPButton(BUTTON_FLIPNUMBERFORMAT, screen, this, PPPoint(x2+30, y2+2+13), PPSize(13, 12));
727 	button->setColor(TrackerConfig::colorThemeMain);
728 	button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
729 	button->setText("H");
730 	container->addControl(button);
731 
732 	button = new PPButton(BUTTON_SAMPLE_EDIT_REPSTARTPLUS, screen, this, PPPoint(x2, y2+2+13*2), PPSize(14, 12));
733 	button->setText(TrackerConfig::stringButtonPlus);
734 	container->addControl(button);
735 
736 	button = new PPButton(BUTTON_SAMPLE_EDIT_REPSTARTMINUS, screen, this, PPPoint(x2+15, y2+2+13*2), PPSize(14, 12));
737 	button->setText(TrackerConfig::stringButtonMinus);
738 	container->addControl(button);
739 
740 	button = new PPButton(BUTTON_SAMPLE_EDIT_REPLENPLUS, screen, this, PPPoint(x2, y2+2+13*3), PPSize(14, 12));
741 	button->setText(TrackerConfig::stringButtonPlus);
742 	container->addControl(button);
743 
744 	button = new PPButton(BUTTON_SAMPLE_EDIT_REPLENMINUS, screen, this, PPPoint(x2+15, y2+2+13*3), PPSize(14, 12));
745 	button->setText(TrackerConfig::stringButtonMinus);
746 	container->addControl(button);
747 
748 	button = new PPButton(BUTTON_SHOWRANGE, screen, this, PPPoint(x2+15+15, y2+2+13*2), PPSize(13, 12*2+1));
749 	button->setColor(TrackerConfig::colorThemeMain);
750 	button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
751 	button->setFont(PPFont::getFont(PPFont::FONT_TINY));
752 	button->setText("Rng");
753 	button->setVerticalText(true);
754 	container->addControl(button);
755 
756 	containerEntire->addControl(container);
757 #else
758 	// sample editor
759 	PPContainer* sampleEditorContainer = new PPContainer(CONTAINER_SAMPLEEDITOR, screen, this, PPPoint(x, y), PPSize(320, 92), false);
760 	sampleEditorContainer->setColor(TrackerConfig::colorThemeMain);
761 
762 	sampleEditorControl = new SampleEditorControl(SAMPLE_EDITOR, screen, this, PPPoint(x+2, y+2), PPSize(316, 92-4));
763 	sampleEditorControl->attachSampleEditor(tracker.moduleEditor->getSampleEditor());
764 	sampleEditorControl->setBorderColor(TrackerConfig::colorThemeMain);
765 
766 	sampleEditorContainer->addControl(sampleEditorControl);
767 	containerEntire->addControl(sampleEditorContainer);
768 
769 	pp_int32 x2 = x;
770 	pp_int32 y2 = sampleEditorContainer->getSize().height + y;
771 
772 	PPContainer* container = new PPContainer(CONTAINER_SAMPLE_PLAY, screen, this, PPPoint(x2, y2), PPSize(87,12*3+4), false);
773 	container->setColor(TrackerConfig::colorThemeMain);
774 
775 	container->addControl(new PPStaticText(0, NULL, NULL, PPPoint(x2 + 4, y2 + 2), "Play:", true));
776 	container->addControl(new PPStaticText(STATICTEXT_SAMPLE_PLAYNOTE, screen, this, PPPoint(x2 + 8, y2 + 2 + 14), "C-5", false));
777 
778 	PPButton* button = new PPButton(BUTTON_SAMPLE_PLAY_UP, screen, this, PPPoint(x2+38, y2+2+12), PPSize(18, 11));
779 	button->setText("Up");
780 	container->addControl(button);
781 
782 	button = new PPButton(BUTTON_SAMPLE_PLAY_DOWN, screen, this, PPPoint(x2+38, y2+2+24), PPSize(18, 11));
783 	button->setText("Dn");
784 	container->addControl(button);
785 
786 	button = new PPButton(BUTTON_SAMPLE_PLAY_STOP, screen, this, PPPoint(x2+2, y2+2+24), PPSize(34, 11));
787 	button->setText("Stop");
788 	container->addControl(button);
789 
790 	button = new PPButton(BUTTON_SAMPLE_PLAY_WAVE, screen, this, PPPoint(x2+2 + 56, y2+2), PPSize(26, 11));
791 	button->setText("Wav");
792 	container->addControl(button);
793 
794 	button = new PPButton(BUTTON_SAMPLE_PLAY_RANGE, screen, this, PPPoint(x2+2 + 56, y2+2+12), PPSize(26, 11));
795 	button->setText("Rng");
796 	container->addControl(button);
797 
798 	button = new PPButton(BUTTON_SAMPLE_PLAY_DISPLAY, screen, this, PPPoint(x2+2 + 56, y2+2+12*2), PPSize(26, 11));
799 	button->setText("Dsp");
800 	container->addControl(button);
801 
802 	containerEntire->addControl(container);
803 
804 	x2+=container->getSize().width;
805 	container = new PPContainer(CONTAINER_SAMPLE_RANGE, screen, this, PPPoint(x2, y2), PPSize(66*2+6,12*3+4), false);
806 	container->setColor(TrackerConfig::colorThemeMain);
807 
808 	button = new PPButton(BUTTON_SAMPLE_RANGE_SHOW, screen, this, PPPoint(x2+2, y2+2), PPSize(66, 11));
809 	button->setText("Show rng");
810 	container->addControl(button);
811 
812 	button = new PPButton(BUTTON_SAMPLE_RANGE_ALL, screen, this, PPPoint(x2+2, y2+2+12), PPSize(66, 11));
813 	button->setText("Rng all");
814 	container->addControl(button);
815 
816 	button = new PPButton(BUTTON_SAMPLE_UNDO, screen, this, PPPoint(x2+2, y2+2+12*2), PPSize(32, 11));
817 	button->setText("Undo");
818 	button->setFont(PPFont::getFont(PPFont::FONT_TINY));
819 	container->addControl(button);
820 
821 	button = new PPButton(BUTTON_SAMPLE_REDO, screen, this, PPPoint(x2 + 2 + 33, y2+2+12*2), PPSize(33, 11));
822 	button->setText("Redo");
823 	button->setFont(PPFont::getFont(PPFont::FONT_TINY));
824 	container->addControl(button);
825 
826 	button = new PPButton(BUTTON_SAMPLE_RANGE_ZOOMOUT, screen, this, PPPoint(x2+2 + 67, y2+2), PPSize(66, 11));
827 	button->setText("Zoom out");
828 	container->addControl(button);
829 
830 	button = new PPButton(BUTTON_SAMPLE_RANGE_SHOWALL, screen, this, PPPoint(x2+2 + 67, y2+2+12), PPSize(66, 11));
831 	button->setText("Show all");
832 	container->addControl(button);
833 
834 	button = new PPButton(BUTTON_SAMPLE_APPLY_LASTFILTER, screen, this, PPPoint(x2+2 + 67, y2+2+12*2), PPSize(66, 11));
835 	button->setFont(PPFont::getFont(PPFont::FONT_TINY));
836 	button->setText("Redo filter");
837 	container->addControl(button);
838 
839 	containerEntire->addControl(container);
840 
841 	x2 += container->getSize().width;
842 
843 	container = new PPContainer(CONTAINER_SAMPLE_EDIT1, screen, this, PPPoint(x2, y2), PPSize(47,12*3+4), false);
844 	container->setColor(TrackerConfig::colorThemeMain);
845 
846 	button = new PPButton(BUTTON_SAMPLE_EDIT_CUT, screen, this, PPPoint(x2+2, y2+2), PPSize(42, 11));
847 	button->setText("Cut");
848 	container->addControl(button);
849 
850 	button = new PPButton(BUTTON_SAMPLE_EDIT_COPY, screen, this, PPPoint(x2+2, y2+2+12), PPSize(42, 11));
851 	button->setText("Copy");
852 	container->addControl(button);
853 
854 	button = new PPButton(BUTTON_SAMPLE_EDIT_PASTE, screen, this, PPPoint(x2+2, y2+2+12*2), PPSize(42, 11));
855 	button->setText("Paste");
856 	container->addControl(button);
857 
858 	containerEntire->addControl(container);
859 
860 	x2 += container->getSize().width;
861 
862 	container = new PPContainer(CONTAINER_SAMPLE_EDIT2, screen, this, PPPoint(x2, y2), PPSize(48,12*3+4), false);
863 	container->setColor(TrackerConfig::colorThemeMain);
864 
865 	button = new PPButton(BUTTON_SAMPLE_EDIT_CROP, screen, this, PPPoint(x2+2, y2+2), PPSize(43, 11));
866 	button->setText("Crop");
867 	container->addControl(button);
868 
869 	button = new PPButton(BUTTON_SAMPLE_EDIT_VOL, screen, this, PPPoint(x2+2, y2+2+12), PPSize(43, 11));
870 	button->setText("Vol");
871 	container->addControl(button);
872 
873 	button = new PPButton(BUTTON_SAMPLE_EDIT_DRAW, screen, this, PPPoint(x2+2, y2+2+12*2), PPSize(43, 11), true, true, false);
874 	button->setText("Draw");
875 	container->addControl(button);
876 
877 	containerEntire->addControl(container);
878 
879 	x2 = x;
880 
881 	y2+=container->getSize().height;
882 
883 	container = new PPContainer(CONTAINER_SHOWCONTEXTMENU, screen, this, PPPoint(x2, y2), PPSize(17,52), false);
884 	container->setColor(TrackerConfig::colorThemeMain);
885 
886 	button = new PPButton(BUTTON_SHOWCONTEXTMENU, screen, this, PPPoint(x2+2, y2+2), PPSize(12, container->getSize().height - 5));
887 	button->setVerticalText(true);
888 	button->setText("Menu");
889 	container->addControl(button);
890 
891 	containerEntire->addControl(container);
892 
893 	x2+=container->getSize().width;
894 
895 	container = new PPContainer(CONTAINER_SAMPLE_EDIT3, screen, this, PPPoint(x2, y2), PPSize(65,52), false);
896 	container->setColor(TrackerConfig::colorThemeMain);
897 
898 	PPRadioGroup* radioGroup = new PPRadioGroup(RADIOGROUP_SAMPLE_LOOPTYPE, screen, this, PPPoint(x2+3, y2+1), PPSize(65, 50));
899 	radioGroup->setColor(TrackerConfig::colorThemeMain);
900 	radioGroup->setFont(PPFont::getFont(PPFont::FONT_TINY));
901 
902 	radioGroup->addItem("No loop");
903 	radioGroup->addItem("Forward");
904 	radioGroup->addItem("Ping-pong");
905 	radioGroup->addItem("One shot");
906 
907 	container->addControl(radioGroup);
908 
909 	containerEntire->addControl(container);
910 
911 	x2+=container->getSize().width;
912 
913 	container = new PPContainer(CONTAINER_SAMPLE_EDIT4, screen, this, PPPoint(x2, y2), PPSize(66-16,25), false);
914 	container->setColor(TrackerConfig::colorThemeMain);
915 
916 	radioGroup = new PPRadioGroup(RADIOGROUP_SAMPLE_RESTYPE, screen, this, PPPoint(x2+1, y2-1), PPSize(65-16, 25));
917 	radioGroup->setColor(TrackerConfig::colorThemeMain);
918 	radioGroup->setFont(PPFont::getFont(PPFont::FONT_TINY));
919 
920 	radioGroup->addItem("8-bit");
921 	radioGroup->addItem("16-bit");
922 
923 	container->addControl(radioGroup);
924 
925 	containerEntire->addControl(container);
926 
927 	// Zoom container
928 	container = new PPContainer(CONTAINER_SAMPLE_ZOOMIN, screen, this, PPPoint(x2 + container->getSize().width, y2), PPSize(16,25), false);
929 	container->setColor(TrackerConfig::colorThemeMain);
930 
931 	button = new PPButton(BUTTON_SAMPLE_ZOOM_PLUS, screen, this, PPPoint(container->getLocation().x+2, y2+2), PPSize(11, 10));
932 	button->setText("+");
933 	container->addControl(button);
934 
935 	button = new PPButton(BUTTON_SAMPLE_ZOOM_MINUS, screen, this, PPPoint(button->getLocation().x, y2+2+button->getSize().height+1), PPSize(11, 9));
936 	button->setText("-");
937 	container->addControl(button);
938 
939 	containerEntire->addControl(container);
940 
941 	pp_int32 y3 = y2 + container->getSize().height;
942 
943 	container = new PPContainer(CONTAINER_SAMPLE_LOADSAVE, screen, this, PPPoint(x2, y3), PPSize(66,27), false);
944 	container->setColor(TrackerConfig::colorThemeMain);
945 
946 	button = new PPButton(MAINMENU_INSEDIT, screen, &tracker, PPPoint(x2+2, y3+2+12), PPSize(34, 10));
947 	button->setFont(PPFont::getFont(PPFont::FONT_TINY));
948 	button->setText("Ins.Ed.");
949 	container->addControl(button);
950 
951 	button = new PPButton(BUTTON_SAMPLEEDITOR_EXIT, screen, &tracker, PPPoint(x2+2+35, y3+2+12), PPSize(26, 10));
952 	button->setFont(PPFont::getFont(PPFont::FONT_TINY));
953 	button->setText("Exit");
954 	container->addControl(button);
955 
956 	button = new PPButton(BUTTON_SAMPLE_LOAD, screen, this, PPPoint(x2+2, y3+2), PPSize(30, 11));
957 	button->setFont(PPFont::getFont(PPFont::FONT_TINY));
958 	button->setText("Load");
959 	container->addControl(button);
960 
961 	button = new PPButton(BUTTON_SAMPLE_SAVE, screen, this, PPPoint(x2+2+31, y3+2), PPSize(30, 11));
962 	button->setFont(PPFont::getFont(PPFont::FONT_TINY));
963 	button->setText("Save");
964 	container->addControl(button);
965 
966 	containerEntire->addControl(container);
967 
968 	x2+=container->getSize().width;
969 
970 	container = new PPContainer(CONTAINER_SAMPLE_EDIT5, screen, this, PPPoint(x2, y2), PPSize(172,52), false);
971 	container->setColor(TrackerConfig::colorThemeMain);
972 
973 	container->addControl(new PPStaticText(STATICTEXT_DISPLAY, NULL, NULL, PPPoint(x2 + 2, y2 + 4), "Display", true));
974 	container->addControl(new PPStaticText(STATICTEXT_LENGTH, NULL, NULL, PPPoint(x2 + 2, y2 + 4+12), "Length", true));
975 	container->addControl(new PPStaticText(STATICTEXT_REPSTART, screen, this, PPPoint(x2 + 2, y2 + 4+12*2), "Repeat", true));
976 	container->addControl(new PPStaticText(STATICTEXT_REPLEN, screen, this, PPPoint(x2 + 2, y2 + 4+12*3), "Replen.", true));
977 
978 	container->addControl(new PPStaticText(STATICTEXT_SAMPLE_DISPLAY, screen, this, PPPoint(x2 + 2 + 58, y2 + 4), "12345678", false));
979 	container->addControl(new PPStaticText(STATICTEXT_SAMPLE_LENGTH, screen, this, PPPoint(x2 + 2 + 58, y2 + 4+12), "12345678", false));
980 	container->addControl(new PPStaticText(STATICTEXT_SAMPLE_REPSTART, screen, this, PPPoint(x2 + 2 + 58, y2 + 4+12*2), "12345678", false));
981 	container->addControl(new PPStaticText(STATICTEXT_SAMPLE_REPLENGTH, screen, this, PPPoint(x2 + 2 + 58, y2 + 4+12*3), "12345678", false));
982 
983 	button = new PPButton(BUTTON_SAMPLE_EDIT_CLEAR, screen, this, PPPoint(x2+126, y2+2), PPSize(43, 11));
984 	button->setText("Clear");
985 	container->addControl(button);
986 
987 	button = new PPButton(BUTTON_SAMPLE_EDIT_MINIMIZE, screen, this, PPPoint(x2+126, y2+2+12), PPSize(27, 11));
988 	button->setText("Min");
989 	container->addControl(button);
990 
991 	button = new PPButton(BUTTON_FLIPNUMBERFORMAT, screen, this, PPPoint(x2+126+28, y2+2+12), PPSize(15, 11));
992 	button->setColor(TrackerConfig::colorThemeMain);
993 	button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
994 	button->setText("H");
995 	container->addControl(button);
996 
997 	button = new PPButton(BUTTON_SAMPLE_EDIT_REPSTARTPLUS, screen, this, PPPoint(x2+126, y2+2+12*2), PPSize(13, 11));
998 	button->setText(TrackerConfig::stringButtonPlus);
999 	container->addControl(button);
1000 
1001 	button = new PPButton(BUTTON_SAMPLE_EDIT_REPSTARTMINUS, screen, this, PPPoint(x2+126+14, y2+2+12*2), PPSize(13, 11));
1002 	button->setText(TrackerConfig::stringButtonMinus);
1003 	container->addControl(button);
1004 
1005 	button = new PPButton(BUTTON_SAMPLE_EDIT_REPLENPLUS, screen, this, PPPoint(x2+126, y2+2+12*3), PPSize(13, 11));
1006 	button->setText(TrackerConfig::stringButtonPlus);
1007 	container->addControl(button);
1008 
1009 	button = new PPButton(BUTTON_SAMPLE_EDIT_REPLENMINUS, screen, this, PPPoint(x2+126+14, y2+2+12*3), PPSize(13, 11));
1010 	button->setText(TrackerConfig::stringButtonMinus);
1011 	container->addControl(button);
1012 
1013 	button = new PPButton(BUTTON_SHOWRANGE, screen, this, PPPoint(x2+126+14*2, y2+2+12*2), PPSize(15, 11*2+1));
1014 	button->setColor(TrackerConfig::colorThemeMain);
1015 	button->setTextColor(PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText));
1016 	button->setFont(PPFont::getFont(PPFont::FONT_TINY));
1017 	button->setText("Rng");
1018 	button->setVerticalText(true);
1019 	container->addControl(button);
1020 
1021 	containerEntire->addControl(container);
1022 #endif
1023 	containerEntire->adjustContainerSize();
1024 	screen->addControl(containerEntire);
1025 
1026 	initialised = true;
1027 
1028 	showSection(false);
1029 }
1030 
showSection(bool bShow)1031 void SectionSamples::showSection(bool bShow)
1032 {
1033 	containerEntire->show(bShow);
1034 }
1035 
realign()1036 void SectionSamples::realign()
1037 {
1038 	pp_uint32 maxShould = tracker.MAXEDITORHEIGHT();
1039 	pp_uint32 maxIs = containerEntire->getLocation().y + containerEntire->getSize().height;
1040 
1041 	if (maxIs != maxShould)
1042 	{
1043 		pp_int32 offset = maxShould - maxIs;
1044 		containerEntire->move(PPPoint(0, offset));
1045 	}
1046 
1047 	PatternEditorControl* control = tracker.getPatternEditorControl();
1048 	PPScreen* screen = tracker.screen;
1049 
1050 	if (visible)
1051 	{
1052 		control->setSize(PPSize(screen->getWidth(),
1053 								tracker.MAXEDITORHEIGHT()-tracker.SAMPLESECTIONDEFAULTHEIGHT()-tracker.UPPERSECTIONDEFAULTHEIGHT()+1));
1054 	}
1055 	else
1056 	{
1057 		control->setSize(PPSize(screen->getWidth(),tracker.MAXEDITORHEIGHT()-tracker.UPPERSECTIONDEFAULTHEIGHT()));
1058 	}
1059 }
1060 
show(bool bShow)1061 void SectionSamples::show(bool bShow)
1062 {
1063 #ifdef __LOWRES__
1064 	PPScreen* screen = tracker.screen;
1065 	screen->pauseUpdate(true);
1066 #endif
1067 	SectionAbstract::show(bShow);
1068 
1069 	visible = bShow;
1070 
1071 	if (!initialised)
1072 	{
1073 		init();
1074 	}
1075 
1076 	if (initialised)
1077 	{
1078 		PatternEditorControl* control = tracker.getPatternEditorControl();
1079 
1080 #ifndef __LOWRES__
1081 		realign();
1082 #endif
1083 
1084 		if (bShow)
1085 		{
1086 			if (control)
1087 			{
1088 #ifdef __LOWRES__
1089 				control->show(false);
1090 				replaceInstrumentListBoxes(true, 56);
1091 #endif
1092 			}
1093 			tracker.hideInputControl();
1094 		}
1095 		else if (control)
1096 		{
1097 #ifdef __LOWRES__
1098 			control->show(true);
1099 			replaceInstrumentListBoxes(false);
1100 #endif
1101 		}
1102 
1103 		update();
1104 		showSection(bShow);
1105 	}
1106 
1107 #ifdef __LOWRES__
1108 	// If instrument section is shown (bShow = true)
1109 	// set focus to the Instrumentlist container (instrument listbox)
1110 	// but before disable screen updates to prevent flickering
1111 	if (bShow)
1112 	{
1113 		screen->setFocus(screen->getControlByID(CONTAINER_INSTRUMENTLIST));
1114 	}
1115 	screen->pauseUpdate(false);
1116 	if (!bShow)
1117 	{
1118 		screen->update();
1119 	}
1120 #endif
1121 }
1122 
update(bool repaint)1123 void SectionSamples::update(bool repaint/* = true*/)
1124 {
1125 	realUpdate(repaint, false, true);
1126 }
1127 
notifyTabSwitch()1128 void SectionSamples::notifyTabSwitch()
1129 {
1130 	if (isVisible())
1131 		realign();
1132 }
1133 
1134 // No need to reattach sample again, because reattaching also clears out selection
refresh(bool repaint)1135 void SectionSamples::refresh(bool repaint/* = true*/)
1136 {
1137 	realUpdate(repaint, false, false);
1138 }
1139 
realUpdate(bool repaint,bool force,bool reAttach)1140 void SectionSamples::realUpdate(bool repaint, bool force, bool reAttach)
1141 {
1142 	if (!initialised)
1143 		return;
1144 
1145 	PPScreen* screen = tracker.screen;
1146 	SampleEditor* sampleEditor = sampleEditorControl->getSampleEditor();
1147 
1148 	if (!force && screen->getModalControl() && screen->getModalControl() == tracker.messageBoxContainerGeneric)
1149 		return;
1150 
1151 	if (reAttach)
1152 		tracker.moduleEditor->reloadSample(tracker.listBoxInstruments->getSelectedIndex(), tracker.listBoxSamples->getSelectedIndex());
1153 
1154 	if (!visible)
1155 		return;
1156 
1157 	PPContainer* container = static_cast<PPContainer*>(screen->getControlByID(CONTAINER_SAMPLE_EDIT3));
1158 
1159 	sampleEditorControl->setRelativeNote(currentSamplePlayNote - ModuleEditor::MAX_NOTE/2);
1160 
1161 	static_cast<PPRadioGroup*>(container->getControlByID(RADIOGROUP_SAMPLE_LOOPTYPE))->setChoice(sampleEditor->getLoopType() & 3);
1162 
1163 	PPContainer* container2 = static_cast<PPContainer*>(screen->getControlByID(CONTAINER_SAMPLE_EDIT4));
1164 	static_cast<PPRadioGroup*>(container2->getControlByID(RADIOGROUP_SAMPLE_RESTYPE))->setChoice(sampleEditor->is16Bit() ? 1 : 0);
1165 
1166 	PPContainer* container3 = static_cast<PPContainer*>(screen->getControlByID(CONTAINER_SAMPLE_EDIT5));
1167 
1168 	setOffsetText(STATICTEXT_SAMPLE_LENGTH, sampleEditor->getSampleLen());
1169 	setOffsetText(STATICTEXT_SAMPLE_DISPLAY, sampleEditorControl->getCurrentDisplayRange());
1170 
1171 	static const char offsetTypes[3] = {'H', 'D', 'T'};
1172 
1173 	static_cast<PPButton*>(container3->getControlByID(BUTTON_FLIPNUMBERFORMAT))->setText(offsetTypes[offsetFormat]);
1174 
1175 	if (showRangeOffsets)
1176 	{
1177 		static_cast<PPButton*>(container3->getControlByID(BUTTON_SHOWRANGE))->setText("Rng");
1178 		static_cast<PPStaticText*>(container3->getControlByID(STATICTEXT_REPSTART))->setText("RStart");
1179 		static_cast<PPStaticText*>(container3->getControlByID(STATICTEXT_REPLEN))->setText("REnd");
1180 		pp_int32 sStart = sampleEditorControl->getSelectionStart();
1181 		pp_int32 sEnd = sampleEditorControl->getSelectionEnd();
1182 		if (sStart >= 0 && sEnd >= 0)
1183 		{
1184 			setOffsetText(STATICTEXT_SAMPLE_REPSTART, sStart);
1185 			setOffsetText(STATICTEXT_SAMPLE_REPLENGTH, sEnd);
1186 		}
1187 		else
1188 		{
1189 			static_cast<PPStaticText*>(container3->getControlByID(STATICTEXT_SAMPLE_REPSTART))->setText("--------");
1190 			static_cast<PPStaticText*>(container3->getControlByID(STATICTEXT_SAMPLE_REPLENGTH))->setText("--------");
1191 		}
1192 	}
1193 	else
1194 	{
1195 		static_cast<PPButton*>(container3->getControlByID(BUTTON_SHOWRANGE))->setText("Rep");
1196 		static_cast<PPStaticText*>(container3->getControlByID(STATICTEXT_REPSTART))->setText("Repeat");
1197 		static_cast<PPStaticText*>(container3->getControlByID(STATICTEXT_REPLEN))->setText("Replen.");
1198 
1199 		setOffsetText(STATICTEXT_SAMPLE_REPSTART, sampleEditorControl->getRepeatStart());
1200 		setOffsetText(STATICTEXT_SAMPLE_REPLENGTH, sampleEditorControl->getRepeatLength());
1201 	}
1202 
1203 	PPContainer* container4 = static_cast<PPContainer*>(screen->getControlByID(CONTAINER_SAMPLE_PLAY));
1204 	char noteName[4];
1205 	PatternTools::getNoteName(noteName, currentSamplePlayNote+1);
1206 	static_cast<PPStaticText*>(container4->getControlByID(STATICTEXT_SAMPLE_PLAYNOTE))->setText(noteName);
1207 
1208 	PPContainer* container5 = static_cast<PPContainer*>(screen->getControlByID(CONTAINER_SAMPLE_RANGE));
1209 	static_cast<PPButton*>(container5->getControlByID(BUTTON_SAMPLE_RANGE_ALL))->setClickable(!sampleEditor->isEmptySample());
1210 	static_cast<PPButton*>(container5->getControlByID(BUTTON_SAMPLE_RANGE_SHOWALL))->setClickable(!sampleEditor->isEmptySample());
1211 	static_cast<PPButton*>(container5->getControlByID(BUTTON_SAMPLE_RANGE_ZOOMOUT))->setClickable(sampleEditorControl->canZoomOut());
1212 	static_cast<PPButton*>(container5->getControlByID(BUTTON_SAMPLE_RANGE_SHOW))->setClickable(sampleEditorControl->hasValidSelection());
1213 	static_cast<PPButton*>(container5->getControlByID(BUTTON_SAMPLE_APPLY_LASTFILTER))->setClickable(sampleEditor->tool_canApplyLastFilter());
1214 	static_cast<PPButton*>(container5->getControlByID(BUTTON_SAMPLE_UNDO))->setClickable(sampleEditor->canUndo());
1215 	static_cast<PPButton*>(container5->getControlByID(BUTTON_SAMPLE_REDO))->setClickable(sampleEditor->canRedo());
1216 
1217 	PPContainer* container6 = static_cast<PPContainer*>(screen->getControlByID(CONTAINER_SAMPLE_EDIT2));
1218 	static_cast<PPButton*>(container6->getControlByID(BUTTON_SAMPLE_EDIT_CROP))->setClickable(sampleEditorControl->hasValidSelection());
1219 	static_cast<PPButton*>(container6->getControlByID(BUTTON_SAMPLE_EDIT_VOL))->setClickable(!sampleEditor->isEmptySample());
1220 	static_cast<PPButton*>(container6->getControlByID(BUTTON_SAMPLE_EDIT_DRAW))->setClickable(!sampleEditor->isEmptySample());
1221 
1222 	PPContainer* container7 = static_cast<PPContainer*>(screen->getControlByID(CONTAINER_SAMPLE_PLAY));
1223 	static_cast<PPButton*>(container7->getControlByID(BUTTON_SAMPLE_PLAY_RANGE))->setClickable(sampleEditorControl->hasValidSelection());
1224 	static_cast<PPButton*>(container7->getControlByID(BUTTON_SAMPLE_PLAY_WAVE))->setClickable(!sampleEditor->isEmptySample());
1225 	static_cast<PPButton*>(container7->getControlByID(BUTTON_SAMPLE_PLAY_DISPLAY))->setClickable(!sampleEditor->isEmptySample());
1226 
1227 	PPContainer* container9 = static_cast<PPContainer*>(screen->getControlByID(CONTAINER_SAMPLE_EDIT1));
1228 	bool b = (sampleEditorControl->getCurrentRangeLength()) > 0 && sampleEditorControl->hasValidSelection();
1229 	static_cast<PPButton*>(container9->getControlByID(BUTTON_SAMPLE_EDIT_CUT))->setClickable(b);
1230 	static_cast<PPButton*>(container9->getControlByID(BUTTON_SAMPLE_EDIT_COPY))->setClickable(b);
1231 	static_cast<PPButton*>(container9->getControlByID(BUTTON_SAMPLE_EDIT_PASTE))->setClickable(sampleEditor->canPaste());
1232 
1233 	PPContainer* container10 = static_cast<PPContainer*>(screen->getControlByID(CONTAINER_SAMPLE_LOADSAVE));
1234 	static_cast<PPButton*>(container10->getControlByID(BUTTON_SAMPLE_SAVE))->setClickable(!sampleEditor->isEmptySample());
1235 
1236 	screen->paintControl(container10, false);
1237 	screen->paintControl(container9, false);
1238 	screen->paintControl(container6, false);
1239 	screen->paintControl(container5, false);
1240 	screen->paintControl(container4, false);
1241 	screen->paintControl(container, false);
1242 	screen->paintControl(container2, false);
1243 	screen->paintControl(container3, false);
1244 	screen->paintControl(sampleEditorControl, false);
1245 	if (repaint)
1246 		screen->update();
1247 }
1248 
updateSampleWindow(bool repaint)1249 void SectionSamples::updateSampleWindow(bool repaint/* = true*/)
1250 {
1251 	PPScreen* screen = tracker.screen;
1252 	screen->paintControl(sampleEditorControl, false);
1253 	if (repaint)
1254 		screen->update();
1255 }
1256 
updateAfterLoad()1257 void SectionSamples::updateAfterLoad()
1258 {
1259 	tracker.updateInstrumentsListBox(false);
1260 	tracker.updateSamplesListBox(false);
1261 	tracker.sectionInstruments->update(false);
1262 	update(false);
1263 }
1264 
getSampleEditorControl(bool forceAttach)1265 SampleEditorControl* SectionSamples::getSampleEditorControl(bool forceAttach/* = true*/)
1266 {
1267 	if (forceAttach &&
1268 		sampleEditorControl &&
1269 		sampleEditorControl->getSampleEditor()->getSample() == NULL)
1270 	{
1271 		tracker.moduleEditor->reloadSample(tracker.listBoxInstruments->getSelectedIndex(), tracker.listBoxSamples->getSelectedIndex());
1272 	}
1273 
1274 	return sampleEditorControl;
1275 }
1276 
resetSampleEditor()1277 void SectionSamples::resetSampleEditor()
1278 {
1279 	if (sampleEditorControl)
1280 		sampleEditorControl->reset();
1281 }
1282 
isEmptySample()1283 bool SectionSamples::isEmptySample()
1284 {
1285 	return !tracker.getSampleEditor()->isEditableSample();
1286 }
1287 
setOffsetFormat(pp_uint32 offsetFormat)1288 void SectionSamples::setOffsetFormat(pp_uint32 offsetFormat)
1289 {
1290 	this->offsetFormat = offsetFormat;
1291 
1292 	sampleEditorControl->setOffsetFormat((SampleEditorControl::OffsetFormats)offsetFormat);
1293 }
1294 
toggleOffsetFormat()1295 void SectionSamples::toggleOffsetFormat()
1296 {
1297 	offsetFormat = (offsetFormat + 1) % (SampleEditorControl::OffsetFormatMillis+1);
1298 
1299 	sampleEditorControl->setOffsetFormat((SampleEditorControl::OffsetFormats)offsetFormat);
1300 }
1301 
setOffsetText(pp_uint32 ID,pp_uint32 offset)1302 void SectionSamples::setOffsetText(pp_uint32 ID, pp_uint32 offset)
1303 {
1304 	switch (offsetFormat)
1305 	{
1306 		case SampleEditorControl::OffsetFormatDec:
1307 			static_cast<PPStaticText*>(containerEntire->getControlByID(ID))->setValue(offset, false, 8);
1308 			break;
1309 
1310 		case SampleEditorControl::OffsetFormatHex:
1311 			static_cast<PPStaticText*>(containerEntire->getControlByID(ID))->setValue(offset, true, 8);
1312 			break;
1313 
1314 		case SampleEditorControl::OffsetFormatMillis:
1315 		{
1316 			pp_uint32 millis = sampleEditorControl->getSampleEditor()->convertSmpPosToMillis(offset, currentSamplePlayNote - ModuleEditor::MAX_NOTE/2);
1317 			char buffer[32], buffer2[32];
1318 			memset(buffer2, 32, sizeof(buffer2));
1319 			// we only have 7 digits, one period character is contained too
1320 			SampleEditorControl::formatMillis(buffer, sizeof(buffer), millis % 10000000);
1321 			// string too large
1322 			if (strlen(buffer) > 8)
1323 			{
1324 				// try to cut off msecs (from period)
1325 				char* ptr = buffer+strlen(buffer);
1326 				while (*ptr != '.' && ptr > buffer)
1327 					ptr--;
1328 				if (*ptr == '.')
1329 				{
1330 					*ptr++ = 's';
1331 					*ptr = '\0';
1332 				}
1333 				// string still too large?
1334 				if (strlen(buffer) > 8)
1335 				{
1336 					// cut off minutes part (from m)
1337 					char* ptr = buffer+strlen(buffer);
1338 					while (*ptr != 'm' && ptr > buffer)
1339 						ptr--;
1340 					if (*ptr == 'm')
1341 						*(++ptr) = '\0';
1342 				}
1343 				if (strlen(buffer) > 8)
1344 					strcpy(buffer, "toolarge");
1345 			}
1346 			strcpy(buffer2 + (8-strlen(buffer)), buffer);
1347 			static_cast<PPStaticText*>(containerEntire->getControlByID(ID))->setText(buffer2);
1348 			break;
1349 		}
1350 	}
1351 }
1352 
handleClearSample()1353 void SectionSamples::handleClearSample()
1354 {
1355 	SampleEditor* sampleEditor = sampleEditorControl->getSampleEditor();
1356 	if (sampleEditor->isEditableSample())
1357 	{
1358 		if (sampleEditor->isUndoStackEnabled())
1359 		{
1360 			sampleEditor->clearSample();
1361 		}
1362 		else
1363 		{
1364 			showMessageBox(MESSAGEBOX_CLEARSAMPLE, "Clear sample?");
1365 		}
1366 	}
1367 	else
1368 	{
1369 		update();
1370 	}
1371 }
1372 
handleCropSample()1373 void SectionSamples::handleCropSample()
1374 {
1375 	SampleEditor* sampleEditor = sampleEditorControl->getSampleEditor();
1376 	if (sampleEditor->isEditableSample() && sampleEditorControl->hasValidSelection())
1377 	{
1378 		if (sampleEditor->isUndoStackEnabled())
1379 		{
1380 			sampleEditor->cropSample();
1381 		}
1382 		else
1383 		{
1384 			showMessageBox(MESSAGEBOX_CROPSAMPLE, "Crop sample?");
1385 		}
1386 	}
1387 	else
1388 	{
1389 		update();
1390 	}
1391 }
1392 
handleMinimizeSample()1393 void SectionSamples::handleMinimizeSample()
1394 {
1395 	SampleEditor* sampleEditor = sampleEditorControl->getSampleEditor();
1396 	if (sampleEditor->canMinimize())
1397 	{
1398 		if (sampleEditor->isUndoStackEnabled())
1399 		{
1400 			sampleEditor->minimizeSample();
1401 		}
1402 		else
1403 		{
1404 			showMessageBox(MESSAGEBOX_MINIMIZESAMPLE, "Minimize sample?");
1405 		}
1406 	}
1407 	else
1408 	{
1409 		update();
1410 	}
1411 }
1412 
handleConvertSampleResolution()1413 void SectionSamples::handleConvertSampleResolution()
1414 {
1415 	SampleEditor* sampleEditor = sampleEditorControl->getSampleEditor();
1416 	if (sampleEditor->isEditableSample())
1417 	{
1418 		showMessageBox(MESSAGEBOX_CONVERTSAMPLE, "Convert sample data?", true);
1419 	}
1420 	else
1421 	{
1422 		sampleEditor->convertSampleResolution(false);
1423 		update();
1424 	}
1425 }
1426