Initial commit.
[amiga/xmodule.git] / InstrumentsWin.c
1 /*
2 **      InstrumentsWin.c
3 **
4 **      Copyright (C) 1994,95,96 Bernardo Innocenti
5 **
6 **      Instruments editor handling functions.
7 */
8
9 #include <exec/nodes.h>
10 #include <intuition/intuition.h>
11 #include <intuition/gadgetclass.h>
12 #include <libraries/gadtools.h>
13 #include <libraries/asl.h>
14 #include <workbench/workbench.h>
15
16 #include <proto/exec.h>
17 #include <proto/dos.h>
18 #include <proto/intuition.h>
19 #include <proto/gadtools.h>
20 #include <proto/xmodule.h>
21
22 #include "XModulePriv.h"
23 #include "Gui.h"
24
25
26
27 /* Gadgets IDs */
28
29 enum
30 {
31         GD_InstrGroup0,
32                 GD_InstrGroup1,
33                         GD_InstrGroup2,
34                                 GD_InstrList,
35                                 GD_InstrName,
36                         GD_InstrGroup3,
37                                 GD_InstrNew,
38                                 GD_InstrOpen,
39                                 GD_InstrDel,
40                                 GD_InstrUp,
41                                 GD_InstrDown,
42                 GD_InstrGroup4,
43                         GD_InstrVolume,
44                         GD_InstrFineTune,
45                         GD_InstrLen,
46                         GD_InstrKind,
47                         GD_InstrEdit,
48
49         Instruments_CNT
50 };
51
52
53
54 /*****************************/
55 /* Local function prototypes */
56 /*****************************/
57
58 static void InstrumentsDropIcon         (struct AppMessage *msg);
59 static void InstrumentsPostOpen         (void);
60 static void InstrumentsPostClose        (void);
61 void UpdateInstrInfo    (void);
62 void UpdateInstrList    (void);
63
64 static void InstrNewClicked                     (void);
65 static void InstrOpenClicked            (void);
66 static void InstrDelClicked                     (void);
67 static void InstrUpClicked                      (void);
68 // TODO static void InstrSwapClicked            (void);
69 static void InstrDownClicked            (void);
70 static void InstrNameClicked            (struct WinUserData *wud);
71 static void InstrListClicked            (void);
72 static void InstrVolumeClicked          (void);
73 static void InstrFineTuneClicked        (void);
74 static void InstrEditClicked            (void);
75 static void InstrKindClicked            (void);
76
77 static void InstrumentsMiLoad           (void);
78 static void InstrumentsMiSave           (void);
79 static void InstrumentsMiSaveAs         (void);
80 static void InstrumentsMiRemap          (void);
81 static void InstrumentsMiSaveIcons      (void);
82 static void InstrumentsMiSaveCompressed (void);
83 static void InstrumentsMiSaveRaw        (void);
84
85
86 XDEF struct List        InstrList;
87 static ULONG            InstrSecs = 0, InstrMicros = 0;
88
89
90 static struct NewMenu InstrumentsNewMenu[] = {
91         NM_TITLE, (STRPTR)MSG_INSTRUMENTS_MEN, NULL, 0, NULL, NULL,
92         NM_ITEM, (STRPTR)MSG_LOAD_MEN, (STRPTR)"L", 0, 0L, (APTR)InstrumentsMiLoad,
93         NM_ITEM, (STRPTR)MSG_SAVE_MEN, (STRPTR)"S", 0, 0L, (APTR)InstrumentsMiSave,
94         NM_ITEM, (STRPTR)MSG_SAVE_AS_MEN, (STRPTR)"A", 0, 0L, (APTR)InstrumentsMiSaveAs,
95         NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
96         NM_ITEM, (STRPTR)MSG_REMAP_MEN, (STRPTR)"R", 0, 0L, (APTR)InstrumentsMiRemap,
97         NM_TITLE, (STRPTR)MSG_SETTINGS_MEN, NULL, 0, NULL, NULL,
98         NM_ITEM, (STRPTR)MSG_SAVE_ICONS_MEN, NULL, CHECKIT|MENUTOGGLE, 0L, (APTR)InstrumentsMiSaveIcons,
99         NM_ITEM, (STRPTR)MSG_SAVE_COMPRESSED_MEN, NULL, CHECKIT|MENUTOGGLE, 4L, (APTR)InstrumentsMiSaveCompressed,
100         NM_ITEM, (STRPTR)MSG_SAVE_RAW_MEN, NULL, CHECKIT|MENUTOGGLE, 2L, (APTR)InstrumentsMiSaveRaw,
101         NM_END, NULL, NULL, 0, 0L, NULL };
102
103
104
105 static STRPTR InstrKindLabels[] = {
106         (STRPTR)MSG_SAMPLE_GAD,
107         (STRPTR)MSG_SYNTH_GAD,
108         (STRPTR)MSG_HYBRID_GAD,
109         (STRPTR)0
110 };
111
112
113
114 static ULONG InstrumentsArgs[] =
115 {
116         HGROUP_KIND, BBFT_RIDGE,
117                 VGROUP_KIND, 0,
118                         LISTVIEW_KIND,  (ULONG)InstrListClicked,                0,      (ULONG)&InstrList,      TAG_DONE,
119                         STRING_KIND,    (ULONG)InstrNameClicked,                0,      64,                                     TAG_DONE,
120                         ENDGROUP_KIND,
121                 VGROUP_KIND, 0,
122                         BUTTON_KIND,    (ULONG)InstrNewClicked,         MSG_UNDERSCORE_NEW_GAD,         TAG_DONE,
123                         BUTTON_KIND,    (ULONG)InstrOpenClicked,        MSG_OPEN_GAD,                           TAG_DONE,
124                         BUTTON_KIND,    (ULONG)InstrDelClicked,         MSG_DEL_GAD,                            TAG_DONE,
125                         BUTTON_KIND,    (ULONG)InstrUpClicked,          MSG_UNDERSCORE_UP_GAD,          TAG_DONE,
126                         BUTTON_KIND,    (ULONG)InstrDownClicked,        MSG_UNDERSCORE_DOWN_GAD,        TAG_DONE,
127                         ENDGROUP_KIND,
128                 ENDGROUP_KIND,
129         VGROUP_KIND,    BBFT_RIDGE,
130                 SLIDER_KIND,    (ULONG)InstrVolumeClicked,      MSG_VOLUME_GAD,         0,      64,     (ULONG)"%lu",   3,      TAG_DONE,
131                 SLIDER_KIND,    (ULONG)InstrFineTuneClicked,MSG_FINETUNE_GAD,   -8,     +7,     (ULONG)"%ld",   3,      TAG_DONE,
132                 NUMBER_KIND,    MSG_LENGHT_GAD,                         7,                                                                                              TAG_DONE,
133                 CYCLE_KIND,             (ULONG)InstrKindClicked,        MSG_KIND_GAD,   (ULONG)InstrKindLabels,                 TAG_DONE,
134                 BUTTON_KIND,    (ULONG)InstrEditClicked,        MSG_EDIT_DOTS_GAD,                                                              TAG_DONE,
135                 ENDGROUP_KIND,
136         ENDGROUP_KIND
137 };
138
139
140
141 XDEF LONG InstrumentsWinTags[] =
142 {
143         XMWIN_NewMenu,          (LONG)InstrumentsNewMenu,
144         XMWIN_LayoutArgs,       (LONG)InstrumentsArgs,
145         XMWIN_GCount,           Instruments_CNT,
146         XMWIN_Title,            MSG_INSTRUMENTS_TITLE,
147         XMWIN_WindowFlags,      WFLG_CLOSEGADGET,
148         XMWIN_IDCMPFlags,       BUTTONIDCMP|STRINGIDCMP|LISTVIEWIDCMP|INTEGERIDCMP|NUMBERIDCMP|IDCMP_MENUPICK|IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW,
149         XMWIN_PostOpenFunc,     (LONG)InstrumentsPostOpen,
150         XMWIN_PostCloseFunc,(LONG)InstrumentsPostClose,
151         XMWIN_DropIconFunc,     (LONG)InstrumentsDropIcon,
152         XMWIN_HelpNode,         (LONG)"Instruments",
153         TAG_DONE
154 };
155
156
157
158 static void InstrumentsPostOpen (void)
159 {
160         UpdateInstrSwitches();
161         UpdateInstrList();
162 }
163
164 static void InstrumentsPostClose (void)
165 {
166         while (!IsListEmpty(&InstrList))
167                 RemListViewNode (InstrList.lh_Head);
168 }
169
170
171
172 static void InstrumentsDropIcon (struct AppMessage *msg)
173 {
174         struct SongInfo *si;
175
176         LockWindows();
177
178         if (si = xmLockActiveSong (SM_EXCLUSIVE))
179         {
180                 struct WBArg    *wba = msg->am_ArgList;
181                 BPTR olddir;
182                 UWORD i, j;
183
184                 olddir = CurrentDir (wba->wa_Lock);
185
186                 for (i = 0, j = si->CurrentInst;
187                         (i < msg->am_NumArgs) && (j < MAXINSTRUMENTS);
188                         i++, j++)
189                 {
190                         CurrentDir (msg->am_ArgList->wa_Lock);
191
192                         if (j == 0) j++;
193
194                         if (LastErr = LoadInstrument (si, j, wba->wa_Name))
195                                 break;
196
197                         wba++;
198                 }
199
200                 ReleaseSemaphore (&si->Lock);
201
202                 if (si->CurrentInst == 0)
203                         SetAttrs (si,
204                                 SNGA_CurrentInst, 1,
205                                 TAG_DONE);
206
207                 CurrentDir (olddir);
208         }
209
210         UnlockWindows();
211 }
212
213
214
215 /*************************/
216 /* Instruments Functions */
217 /*************************/
218
219 GLOBALCALL void UpdateInstrList (void)
220 {
221         struct SongInfo *si;
222         struct WinUserData *wud = WDescr[WID_INSTRUMENTS].Wud;
223         ULONG i, curr = 0;
224
225         if (wud && wud->Win)
226         {
227                 GT_SetGadgetAttrs (wud->Gadgets[GD_InstrList], wud->Win, NULL,
228                         GTLV_Labels, ~0,
229                         TAG_DONE);
230
231                 /* Empty previous list */
232                 while (!IsListEmpty (&InstrList))
233                         RemListViewNode (InstrList.lh_Head);
234
235                 if (si = xmLockActiveSong (SM_SHARED))
236                 {
237                         for (i = 1 ; i <= si->LastInstrument; i++)
238                         {
239                                 AddListViewNode (&InstrList, "%02lx %s", i,
240                                         si->Instr[i] ?
241                                                 (si->Instr[i]->Name ? si->Instr[i]->Name : STR(MSG_UNNAMED))
242                                                 : STR(MSG_EMPTY));
243                         }
244
245                         curr = si->CurrentInst - 1;
246
247                         ReleaseSemaphore (&si->Lock);
248                 }
249
250                 GT_SetGadgetAttrs (wud->Gadgets[GD_InstrList], wud->Win, NULL,
251                         GTLV_Labels, &InstrList,
252                         GTLV_MakeVisible, curr,
253                         TAG_DONE);
254
255                 UpdateInstrInfo();
256         }
257 }
258
259
260
261 GLOBALCALL void UpdateInstrInfo (void)
262 {
263         struct SongInfo *si;
264         struct WinUserData *wud;
265
266         if (!(wud = WDescr[WID_INSTRUMENTS].Wud)) return;
267         if (!(wud->Win)) return;
268
269         if (si = xmLockActiveSong (SM_SHARED))
270         {
271                 struct Instrument *instr;
272
273                 if (si->CurrentInst && (instr = si->Instr[si->CurrentInst]))
274                         SetGadgets (wud,
275                                 GD_InstrName,           instr->Name,
276                                 GD_InstrVolume,         instr->Volume,
277                                 GD_InstrFineTune,       instr->FineTune,
278                                 GD_InstrLen,            instr->Length,
279                                 GD_InstrList,           si->CurrentInst - 1,
280                                 -1);
281                 else
282                         SetGadgets (wud,
283                                 GD_InstrName,           NULL,
284                                 GD_InstrVolume,         0,
285                                 GD_InstrFineTune,       0,
286                                 GD_InstrLen,            0,
287                                 GD_InstrList,           si->CurrentInst - 1,
288                                 -1);
289
290
291                 ReleaseSemaphore (&si->Lock);
292         }
293
294         DB(kprintf("remember to uncomment updatesample!\n"));
295         //UpdateSample();
296         UpdateEditorInst();
297 }
298
299
300
301 GLOBALCALL void UpdateInstrSwitches (void)
302 {
303         struct MenuItem *item;
304         struct WinUserData *wud = WDescr[WID_INSTRUMENTS].Wud;
305
306         if (wud && wud->MenuStrip)
307         {
308                 if (wud->Win) ClearMenuStrip (wud->Win);
309
310                 item = ItemAddress (wud->MenuStrip, SHIFTMENU(1) | SHIFTITEM(0) );
311
312                 /* Save Icons? */
313                 if (GuiSwitches.InstrSaveIcons)
314                         item->Flags |= CHECKED;
315                 else
316                         item->Flags &= ~CHECKED;
317
318                 if (wud->Win) ResetMenuStrip (wud->Win, wud->MenuStrip);
319         }
320 }
321
322
323
324 static void InstrumentsLoad (STRPTR name, ULONG num, ULONG count)
325 {
326         struct SongInfo *si;
327
328         LockWindows();
329
330         if (si = xmLockActiveSong (SM_EXCLUSIVE))
331         {
332                 UWORD instnum;
333
334                 if (si->CurrentInst == 0)
335                         instnum = 1;
336                 else
337                         instnum = si->CurrentInst + num;
338
339                 if (instnum < MAXINSTRUMENTS)
340                         LoadInstrument (si, instnum, name);
341
342                 if (si->CurrentInst == 0)
343                         SetAttrs (si,
344                                 SNGA_CurrentInst, 1,
345                                 TAG_DONE);
346
347                 ReleaseSemaphore (&si->Lock);
348         }
349
350         UnlockWindows();
351 }
352
353
354
355 /***********************/
356 /* Instruments Gadgets */
357 /***********************/
358
359 static void InstrNewClicked (void)
360 {
361         struct SongInfo *si;
362
363         if (si = xmLockActiveSong (SM_EXCLUSIVE))
364         {
365                 xmAddInstrumentA (si, -1, NULL);
366
367                 SetAttrs (si,
368                         SNGA_CurrentInst,       si->LastInstrument,
369                         TAG_DONE);
370
371                 ReleaseSemaphore (&si->Lock);
372         }
373
374         UpdateSongInfo();
375 }
376
377
378
379 static void InstrOpenClicked (void)
380 {
381         StartFileRequest (FREQ_LOADINST, InstrumentsLoad);
382 }
383
384
385
386 static void InstrDelClicked (void)
387 {
388         struct SongInfo *si;
389
390         if (si = xmLockActiveSong (SM_EXCLUSIVE))
391         {
392                 xmRemInstrument (si, si->CurrentInst);
393
394                 SetAttrs (si,
395                         SNGA_CurrentInst,       si->CurrentInst + 1,
396                         TAG_DONE);
397
398                 ReleaseSemaphore (&si->Lock);
399         }
400
401         UpdateSongInfo();
402 }
403
404
405
406 static void InstrUpClicked (void)
407 {
408         struct Instrument *tmp;
409         struct SongInfo *si;
410
411         if (si = xmLockActiveSong (SM_EXCLUSIVE))
412         {
413                 /* Swap actual instrument with the previous one */
414                 if (si->CurrentInst <= 1) return;
415
416                 tmp = si->Instr[si->CurrentInst];
417                 si->Instr[si->CurrentInst] = si->Instr[si->CurrentInst-1];
418                 si->Instr[si->CurrentInst-1] = tmp;
419
420                 SetAttrs (si,
421                         SNGA_CurrentInst,       si->CurrentInst-1,
422                         TAG_DONE);
423
424                 ReleaseSemaphore (&si->Lock);
425
426                 UpdateInstrList();
427         }
428 }
429
430
431
432 static void InstrDownClicked (void)
433 {
434         struct SongInfo *si;
435         struct Instrument *tmp;
436
437         if (si = xmLockActiveSong (SM_EXCLUSIVE))
438         {
439                 /* Swap actual instrument with the next one */
440                 if (si->CurrentInst >= MAXINSTRUMENTS-1) DisplayBeep (Scr);
441                 else
442                 {
443                         /**/ /* Use some OO-legal way to do this!! :) */
444                         tmp = si->Instr[si->CurrentInst];
445                         si->Instr[si->CurrentInst] = si->Instr[si->CurrentInst+1];
446                         si->Instr[si->CurrentInst+1] = tmp;
447                         if (si->CurrentInst + 1 >= si->LastInstrument)
448                                 si->LastInstrument = si->CurrentInst + 1;
449
450                         SetAttrs (si,
451                                 SNGA_CurrentInst,       si->CurrentInst + 1,
452                                 TAG_DONE);
453                 }
454
455                 ReleaseSemaphore (&si->Lock);
456
457                 UpdateInstrList();
458         }
459 }
460
461
462
463 /*
464 static void InstrSwapClicked (void)
465 {
466         TODO
467 }
468 */
469
470
471 static void InstrNameClicked (struct WinUserData *wud)
472 {
473         struct SongInfo *si;
474
475         if (si = xmLockActiveSong (SM_EXCLUSIVE))
476         {
477                 xmSetInstrument (si, si->CurrentInst,
478                         INSTRA_Name, GetString (wud->Gadgets[GD_InstrName]),
479                         TAG_DONE);
480
481                 ReleaseSemaphore (&si->Lock);
482
483                 UpdateInstrList();
484         }
485 }
486
487
488
489 static void InstrListClicked (void)
490 {
491         struct SongInfo *si;
492
493         if (si = xmLockActiveSong (SM_SHARED))
494         {
495                 if (si->CurrentInst != IntuiMsg.Code + 1)
496                 {
497                         si->CurrentInst = IntuiMsg.Code + 1;
498                         UpdateInstrInfo();
499                 }
500                 else
501                 {
502                         /* Check Double Click */
503                         if (DoubleClick (InstrSecs, InstrMicros, IntuiMsg.Seconds, IntuiMsg.Micros))
504                                 NewWindow (WID_SAMPLE);
505                 }
506
507                 ReleaseSemaphore (&si->Lock);
508         }
509
510         InstrSecs = IntuiMsg.Seconds;
511         InstrMicros = IntuiMsg.Micros;
512 }
513
514
515
516 static void InstrVolumeClicked (void)
517 {
518         struct SongInfo *si;
519
520         if (si = xmLockActiveSong (SM_EXCLUSIVE))
521         {
522                 xmSetInstrument (si, si->CurrentInst,
523                         INSTRA_Volume, IntuiMsg.Code,
524                         TAG_DONE);
525
526                 ReleaseSemaphore (&si->Lock);
527         }
528 }
529
530
531
532 static void InstrFineTuneClicked (void)
533 {
534         struct SongInfo *si;
535
536         if (si = xmLockActiveSong (SM_EXCLUSIVE))
537         {
538                 xmSetInstrument (si, si->CurrentInst,
539                         INSTRA_FineTune, IntuiMsg.Code,
540                         TAG_DONE);
541                 ReleaseSemaphore (&si->Lock);
542         }
543 }
544
545
546
547 static void InstrKindClicked (void)
548 {
549         /**/
550 }
551
552
553
554 static void InstrEditClicked (void)
555 {
556         NewWindow (WID_SAMPLE);
557 }
558
559
560
561 /**************/
562 /* Menu Items */
563 /**************/
564
565 static void InstrumentsMiLoad (void)
566 {
567         StartFileRequest (FREQ_LOADINST, InstrumentsLoad);
568 }
569
570
571
572 static void InstrumentsMiSave (void)
573 {
574         struct SongInfo *si;
575
576         LockWindows();
577
578         if (si = xmLockActiveSong (SM_SHARED))
579         {
580                 if (si->Instr[si->CurrentInst])
581                         LastErr = SaveInstrument (si->Instr[si->CurrentInst],
582                                 si->Instr[si->CurrentInst]->Name);
583
584                 ReleaseSemaphore (&si->Lock);
585         }
586
587         UnlockWindows();
588 }
589
590
591
592 static void InstrumentsMiSaveAs (void)
593 {
594         struct SongInfo *si;
595
596         LockWindows();
597
598         if (si = xmLockActiveSong (SM_EXCLUSIVE))
599         {
600                 struct Instrument *instr;
601                 UBYTE name[PATHNAME_MAX];
602
603                 if (instr = si->Instr[si->CurrentInst])
604                 {
605                         strncpy (name, instr->Name, PATHNAME_MAX-1);
606                         name[PATHNAME_MAX-1] = '\0';
607
608                         if (FileRequest (FREQ_SAVEINST, name))
609                         {
610                                 xmSetInstrument (si, si->CurrentInst,
611                                         INSTRA_Name,    FilePart (name),
612                                         TAG_DONE);
613
614                                 LastErr = SaveInstrument (instr, name);
615                         }
616                 }
617
618                 ReleaseSemaphore (&si->Lock);
619         }
620
621         UnlockWindows();
622 }
623
624
625
626 static void InstrumentsMiRemap (void)
627 {
628         struct SongInfo *si;
629
630         if (si = xmLockActiveSong (SM_EXCLUSIVE))
631         {
632                 RemapInstruments (si);
633                 UpdateSongInfo();
634                 ReleaseSemaphore (&si->Lock);
635         }
636 }
637
638
639
640 static void InstrumentsMiSaveIcons (void)
641 {
642         GuiSwitches.InstrSaveIcons ^= 1;
643 }
644
645
646
647 static void InstrumentsMiSaveCompressed (void)
648 {
649         /**/ /* TODO */
650 }
651
652
653
654 static void InstrumentsMiSaveRaw (void)
655 {
656         /**/ /* TODO */
657 }