4 ** Copyright (C) 1993,94,95,96 Bernardo Innocenti
6 ** Sequence editor handling functions.
9 #include <intuition/intuition.h>
10 #include <intuition/gadgetclass.h>
11 #include <libraries/gadtools.h>
13 #include <proto/exec.h>
14 #include <proto/intuition.h>
15 #include <proto/gadtools.h>
16 #include <proto/xmodule.h>
19 #include "XModulePriv.h"
51 /* Local function prototypes */
53 static void SequencePostClose (void);
55 static void SeqListClicked (struct WinUserData *wud);
56 static void PattAddClicked (struct WinUserData *wud);
57 static void PattDelClicked (struct WinUserData *wud);
58 static void PattUpClicked (struct WinUserData *wud);
59 static void PattDownClicked (struct WinUserData *wud);
60 static void PattNameClicked (struct WinUserData *wud);
61 static void PattListClicked (struct WinUserData *wud);
62 static void SeqDelClicked (struct WinUserData *wud);
63 static void SeqUpClicked (struct WinUserData *wud);
64 static void SeqDownClicked (struct WinUserData *wud);
65 static void SeqInsertClicked (struct WinUserData *wud);
68 struct Gadget *SequenceGadgets[Sequence_CNT];
69 struct List SequenceList;
70 struct List PatternsList;
71 static ULONG SequenceSecs = 0, SequenceMicros = 0;
72 static ULONG PatternSecs = 0, PatternMicros = 0;
76 static ULONG SequenceArgs[] =
78 HGROUP_KIND, BBFT_RIDGE,
80 LISTVIEW_KIND, (ULONG)PattListClicked, MSG_PATTERNS_GAD, (ULONG)&PatternsList, TAG_DONE,
81 STRING_KIND, (ULONG)PattNameClicked, MSG_UNDERSCORE_NAME_GAD, 128, TAG_DONE,
84 BUTTON_KIND, (ULONG)PattAddClicked, MSG_UNDERSCORE_ADD_GAD, TAG_DONE,
85 BUTTON_KIND, (ULONG)PattDelClicked, MSG_DEL_GAD, TAG_DONE,
86 BUTTON_KIND, (ULONG)PattUpClicked, MSG_UP_GAD, TAG_DONE,
87 BUTTON_KIND, (ULONG)PattDownClicked, MSG_DOWN_GAD, TAG_DONE,
90 HGROUP_KIND, BBFT_RIDGE,
91 LISTVIEW_KIND, (ULONG)SeqListClicked, MSG_SEQUENCE_GAD, (ULONG)&SequenceList, TAG_DONE,
93 BUTTON_KIND, (ULONG)SeqInsertClicked, MSG_UNDERSCORE_INS_GAD, TAG_DONE,
94 BUTTON_KIND, (ULONG)SeqDelClicked, MSG_DEL_GAD, TAG_DONE,
95 BUTTON_KIND, (ULONG)SeqUpClicked, MSG_UNDERSCORE_UP_GAD, TAG_DONE,
96 BUTTON_KIND, (ULONG)SeqDownClicked, MSG_UNDERSCORE_DOWN_GAD, TAG_DONE,
104 XDEF LONG SequenceWinTags[] =
106 XMWIN_LayoutArgs, (LONG)SequenceArgs,
107 XMWIN_GCount, Sequence_CNT,
108 XMWIN_Title, MSG_SEQUENCE_TITLE,
109 XMWIN_WindowFlags, WFLG_CLOSEGADGET,
110 XMWIN_IDCMPFlags, BUTTONIDCMP|LISTVIEWIDCMP|IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW,
111 XMWIN_PostOpenFunc, (LONG)UpdatePatternList,
112 XMWIN_PostCloseFunc,(LONG)SequencePostClose,
113 XMWIN_HelpNode, (LONG)"Sequence",
119 static void SequencePostClose (void)
121 while (!IsListEmpty (&SequenceList))
122 RemListViewNode (SequenceList.lh_Head);
124 while (!IsListEmpty (&PatternsList))
125 RemListViewNode (PatternsList.lh_Head);
130 /**********************/
131 /* Sequence Functions */
132 /**********************/
134 GLOBALCALL void UpdateSequenceList (void)
136 struct WinUserData *wud = WDescr[WID_SEQUENCE].Wud;
143 GT_SetGadgetAttrs (wud->Gadgets[GD_SeqList], wud->Win, NULL,
147 while (!IsListEmpty (&SequenceList))
148 RemListViewNode (SequenceList.lh_Head);
150 if (si = xmLockActiveSong (SM_SHARED))
152 for (i = 0 ; i < si->Length; i++)
154 pos = si->Sequence[i];
155 AddListViewNode (&SequenceList, "%03lu - %03ld %s", i, pos,
156 (pos >= si->NumPatterns) ? (STRPTR)"--none--" : si->Patt[pos]->Name);
159 GT_SetGadgetAttrs (wud->Gadgets[GD_SeqList], wud->Win, NULL,
160 GTLV_Labels, &SequenceList,
161 GTLV_Selected, si->CurrentPos,
162 GTLV_MakeVisible, si->CurrentPos,
165 ReleaseSemaphore (&si->Lock);
172 GLOBALCALL void UpdatePatternList (void)
174 struct WinUserData *wud = WDescr[WID_SEQUENCE].Wud;
176 struct Pattern *patt;
181 GT_SetGadgetAttrs (wud->Gadgets[GD_PattList], wud->Win, NULL,
185 while (!IsListEmpty (&PatternsList))
186 RemListViewNode (PatternsList.lh_Head);
189 if (si = xmLockActiveSong (SM_SHARED))
191 for (i = 0 ; i < si->NumPatterns; i++)
193 if (patt = si->Patt[i])
195 AddListViewNode (&PatternsList, "%03lu (%lu,%lu) %s",
196 i, patt->Tracks, patt->Lines,
197 patt->Name ? patt->Name : (STRPTR) STR(MSG_UNNAMED));
199 else AddListViewNode (&PatternsList, STR(MSG_EMPTY));
202 GT_SetGadgetAttrs (wud->Gadgets[GD_PattName], wud->Win, NULL,
203 GTST_String, si->NumPatterns ? si->Patt[si->CurrentPatt]->Name : NULL,
206 GT_SetGadgetAttrs (wud->Gadgets[GD_PattList], wud->Win, NULL,
207 GTLV_Labels, &PatternsList,
208 GTLV_Selected, si->CurrentPatt,
209 GTLV_MakeVisible, si->CurrentPatt,
212 ReleaseSemaphore (&si->Lock);
215 UpdateSequenceList();
223 /********************/
224 /* Sequence Gadgets */
225 /********************/
227 static void SeqListClicked (struct WinUserData *wud)
231 if (si = xmLockActiveSong (SM_EXCLUSIVE))
233 if (IntuiMsg.Code == si->CurrentPos)
235 /* Check Double Click */
236 if (DoubleClick (SequenceSecs, SequenceMicros, IntuiMsg.Seconds, IntuiMsg.Micros))
238 si->Sequence[si->CurrentPos] = si->CurrentPatt;
239 UpdateSequenceList();
243 si->CurrentPos = IntuiMsg.Code;
245 ReleaseSemaphore (&si->Lock);
248 SequenceSecs = IntuiMsg.Seconds;
249 SequenceMicros = IntuiMsg.Micros;
254 static void PattAddClicked (struct WinUserData *wud)
258 if (si = xmLockActiveSong (SM_EXCLUSIVE))
260 if (si->NumPatterns >= MAXPATTERNS)
264 xmAddPatternA (si, NULL);
265 UpdateSongInfo(); /* this also calls UpdatePatternList() */
268 ReleaseSemaphore (&si->Lock);
274 static void PattDelClicked (struct WinUserData *wud)
278 if (si = xmLockActiveSong (SM_EXCLUSIVE))
280 if (si->NumPatterns <= 1)
283 xmRemPattern (si, si->CurrentPatt, 0);
285 ReleaseSemaphore (&si->Lock);
293 static void PattUpClicked (struct WinUserData *wud)
297 if (si = xmLockActiveSong (SM_EXCLUSIVE))
299 if (si->CurrentPatt == 0)
303 struct Pattern *tmp_patt;
305 /* Swap pattern with its predecessor */
306 tmp_patt = si->Patt[si->CurrentPatt];
307 si->Patt[si->CurrentPatt] = si->Patt[si->CurrentPatt - 1];
308 si->Patt[si->CurrentPatt - 1] = tmp_patt;
311 SNGA_CurrentPatt, si->CurrentPatt - 1,
317 ReleaseSemaphore (&si->Lock);
323 static void PattDownClicked (struct WinUserData *wud)
327 if (si = xmLockActiveSong (SM_EXCLUSIVE))
329 if (si->CurrentPatt >= si->NumPatterns - 1)
333 struct Pattern *tmp_patt;
335 /* Swap pattern with its successor */
336 tmp_patt = si->Patt[si->CurrentPatt];
337 si->Patt[si->CurrentPatt] = si->Patt[si->CurrentPatt + 1];
338 si->Patt[si->CurrentPatt + 1] = tmp_patt;
341 SNGA_CurrentPatt, si->CurrentPatt + 1,
347 ReleaseSemaphore (&si->Lock);
353 static void PattNameClicked (struct WinUserData *wud)
357 if (si = xmLockActiveSong (SM_EXCLUSIVE))
359 xmSetPattern (si, si->CurrentPatt,
360 PATTA_Name, GetString (wud->Gadgets[GD_PattName]),
364 ReleaseSemaphore (&si->Lock);
370 static void PattListClicked (struct WinUserData *wud)
374 if (si = xmLockActiveSong (SM_SHARED))
376 if (IntuiMsg.Code == si->CurrentPatt)
378 /* Check Double Click */
379 if (DoubleClick (PatternSecs, PatternMicros, IntuiMsg.Seconds, IntuiMsg.Micros))
380 NewWindow(WID_PATTERN);
384 si->CurrentPatt = IntuiMsg.Code;
386 GT_SetGadgetAttrs (wud->Gadgets[GD_PattName], wud->Win, NULL,
387 GTST_String, si->Patt[si->CurrentPatt]->Name,
393 ReleaseSemaphore (&si->Lock);
396 PatternSecs = IntuiMsg.Seconds;
397 PatternMicros = IntuiMsg.Micros;
402 static void SeqDelClicked (struct WinUserData *wud)
406 if (si = xmLockActiveSong (SM_EXCLUSIVE))
410 /* You can't have an empty sequence */
415 /* Shift positions back */
416 for (i = si->CurrentPos ; i < si->Length; i++)
417 si->Sequence[i] = si->Sequence[i+1];
419 xmSetSongLen (si, si->Length - 1);
421 UpdateSongInfo(); /* Will call also UpdateSequenceList() */
424 ReleaseSemaphore (&si->Lock);
430 static void SeqUpClicked (struct WinUserData *wud)
434 if (si = xmLockActiveSong (SM_EXCLUSIVE))
438 if (si->CurrentPos < 1)
442 temp = si->Sequence[si->CurrentPos];
443 si->Sequence[si->CurrentPos] = si->Sequence[si->CurrentPos - 1];
444 si->Sequence[si->CurrentPos - 1] = temp;
447 UpdateSequenceList();
450 ReleaseSemaphore (&si->Lock);
456 static void SeqDownClicked (struct WinUserData *wud)
460 if (si = xmLockActiveSong (SM_EXCLUSIVE))
464 if (si->CurrentPos >= si->Length - 1)
468 temp = si->Sequence[si->CurrentPos];
469 si->Sequence[si->CurrentPos] = si->Sequence[si->CurrentPos + 1];
470 si->Sequence[si->CurrentPos + 1] = temp;
473 UpdateSequenceList();
476 ReleaseSemaphore (&si->Lock);
482 static void SeqInsertClicked (struct WinUserData *wud)
486 if (si = xmLockActiveSong (SM_EXCLUSIVE))
488 if (!(xmSetSongLen (si, si->Length + 1)))
494 for (i = si->Length - 1; i > si->CurrentPos; i--)
495 si->Sequence[i] = si->Sequence[i-1];
497 si->Sequence[si->CurrentPos] = si->CurrentPatt;
500 ReleaseSemaphore (&si->Lock);
502 UpdateSongInfo(); /* This will also update the sequence list */