int GetFolderDepth(MediaTrack* tr, int* iType, MediaTrack** nextTr) // iType: 0=normal, 1=parent, < 0=last in folder { //static MediaTrack* nextTr = NULL; Let calling fcn keep track so state is reset appropriately static int iLastFolder = 0; int iFolder; if (tr == *nextTr) { *nextTr = CSurf_TrackFromID(CSurf_TrackToID(tr, false) + 1, false); if (CSurf_TrackToID(tr, false) == 0) // Special case for master { if (iType) *iType = 1; return -1; // Master is at '-1' depth } iFolder = *(int*)GetSetMediaTrackInfo(tr, "I_FOLDERDEPTH", NULL); if (iType) *iType = iFolder; if (iFolder == 0) return iLastFolder; else if (iFolder == 1) { iLastFolder++; return iLastFolder - 1; // Count parent as at the "previous" level } else if (iFolder < 0) { int iCur = iLastFolder; iLastFolder += iFolder; return iCur; } } else { // Must iterate until reaching the track passed in iLastFolder = 0; *nextTr = CSurf_TrackFromID(0, false); while (tr != *nextTr) GetFolderDepth(*nextTr, NULL, nextTr); return GetFolderDepth(tr, iType, nextTr); } return -1; }
void SWS_TrackListView::GetItemText(SWS_ListItem* item, int iCol, char* str, int iStrMax) { MediaTrack* tr = (MediaTrack*)item; if (tr) { switch (iCol) { case COL_NUM: // # _snprintf(str, iStrMax, "%d", CSurf_TrackToID(tr, false)); break; case COL_NAME: // Name lstrcpyn(str, (char*)GetSetMediaTrackInfo(tr, "P_NAME", NULL), iStrMax); break; case COL_TCP: // TCP lstrcpyn(str, GetTrackVis(tr) & 2 ? UTF8_BULLET : UTF8_CIRCLE, iStrMax); break; case COL_MCP: // MCP lstrcpyn(str, GetTrackVis(tr) & 1 ? UTF8_BULLET : UTF8_CIRCLE, iStrMax); break; case COL_ARM: lstrcpyn(str, *(int*)GetSetMediaTrackInfo(tr, "I_RECARM", NULL) ? UTF8_BULLET : UTF8_CIRCLE, iStrMax); break; case COL_MUTE: lstrcpyn(str, *(bool*)GetSetMediaTrackInfo(tr, "B_MUTE", NULL) ? UTF8_BULLET : UTF8_CIRCLE, iStrMax); break; case COL_SOLO: lstrcpyn(str, *(int*)GetSetMediaTrackInfo(tr, "I_SOLO", NULL) ? UTF8_BULLET : UTF8_CIRCLE, iStrMax); break; // case COL_INPUT: // _snprintf(str, iStrMax, "%d", *(int*)GetSetMediaTrackInfo(tr, "I_RECINPUT", NULL) + 1); // break; } } }
char* FilteredVisState::ItemString(char* str, int maxLen, bool* bDone) { static int iState = 0; static int iIndex = 0; if (!m_sFilter.Get()[0]) return NULL; *bDone = false; if (iState == 0) { sprintf(str, "<SWSTRACKFILTER %s", m_sFilter.Get()); iState = 1; iIndex = 0; } else { if (iIndex < m_filteredOut.GetSize()) { sprintf(str, "%d %d", CSurf_TrackToID(m_filteredOut.Get(iIndex)->tr, false), m_filteredOut.Get(iIndex)->iVis); iIndex++; } else { *bDone = true; iState = 0; sprintf(str, ">"); } } return str; }
void RestoreSelected() { int iSel = 1; for (int i = 0; i < g_iNumSel; i++) if (CSurf_TrackToID(g_pSelTracks[i], false) >= 0) GetSetMediaTrackInfo(g_pSelTracks[i], "I_SELECTED", &iSel); }
WDL_FastString* TrackSend::AuxRecvString(MediaTrack* srcTr, WDL_FastString* str) { int iSrc = CSurf_TrackToID(srcTr, false) - 1; str->SetFormatted(20, "AUXRECV %d ", iSrc); str->Append(m_str.Get()); return str; }
MediaItem* FindWnd::FindPrevNextItem(int _dir, MediaItem* _item) { if (!_dir) return NULL; MediaItem* previous = NULL; int startTrIdx = (_dir == -1 ? CountTracks(NULL) : 1); if (_item) if (MediaTrack* trItem = GetMediaItem_Track(_item)) startTrIdx = CSurf_TrackToID(trItem, false); if (startTrIdx>=0) { bool found = (_item == NULL); for (int i = startTrIdx; !previous && i <= CountTracks(NULL) && i >= 1; i+=_dir) { MediaTrack* tr = CSurf_TrackFromID(i, false); int nbItems = GetTrackNumMediaItems(tr); for (int j = (_dir > 0 ? 0 : (nbItems-1)); j < nbItems && j >= 0; j+=_dir) { MediaItem* item = GetTrackMediaItem(tr,j); if (found && item) { previous = item; break; } if (_item && item == _item) found = true; } } } return previous; }
bool FilteredVisState::UpdateReaper(bool bHideFiltered) { bool bChanged = false; // Remove tracks from filteredOut that aren't in the project for (int i = 0; i < m_filteredOut.GetSize(); i++) if (CSurf_TrackToID(m_filteredOut.Get(i)->tr, false) <= 0) m_filteredOut.Delete(i--, true); for (int i = 1; i <= GetNumTracks(); i++) { MediaTrack* tr = CSurf_TrackFromID(i, false); int iVis = GetTrackVis(tr); int iNewVis = iVis; bool bShow = !bHideFiltered || MatchesFilter(tr); // Is this track in the filteredOut list? int j; for (j = 0; j < m_filteredOut.GetSize(); j++) if (m_filteredOut.Get(j)->tr == tr) break; if (j < m_filteredOut.GetSize()) { if (bShow) { iNewVis = m_filteredOut.Get(j)->iVis; m_filteredOut.Delete(j, true); } else iNewVis = 0; } else if (!bShow) { iNewVis = 0; TrackVisState* tvs = m_filteredOut.Add(new TrackVisState); tvs->tr = tr; tvs->iVis = iVis; } if (iVis != iNewVis) { SetTrackVis(tr, iNewVis); bChanged = true; } } if (bChanged) { TrackList_AdjustWindows(false); UpdateTimeline(); } return bChanged; }
bool SNM_SendPatcher::AddReceive(MediaTrack* _srcTr, void* _io) { m_srcId = _srcTr ? CSurf_TrackToID(_srcTr, false) : -1; if (!_io || m_srcId <= 0) return false; m_sendType = ((SNM_SndRcv*)_io)->m_mode; m_vol = NULL; m_pan = NULL; m_sndRcv = _io; return (ParsePatch(-3, 1, "TRACK", "MIDIOUT") > 0); }
int SNM_SendPatcher::AddReceive(MediaTrack* _srcTr, int _sendType, const char* _vol, const char* _pan) { m_srcId = _srcTr ? CSurf_TrackToID(_srcTr, false) : -1; if (m_srcId <= 0) return 0; m_sendType = _sendType; m_vol = _vol; m_pan = _pan; m_sndRcv = NULL; return ParsePatch(-1, 1, "TRACK", "MIDIOUT"); }
int SNM_SendPatcher::RemoveReceivesFrom(MediaTrack* _srcTr) { m_srcId = _srcTr ? CSurf_TrackToID(_srcTr, false) : -1; if (m_srcId <= 0) return 0; /* can fail since v4.1: freeze char buf[32]; return _snprintfStrict(buf, sizeof(buf), "AUXRECV %d", srcId-1)>0 && RemoveLines(buf); */ return ParsePatch(-2, 1, "TRACK", "AUXRECV", -1, -1, NULL, NULL, "MIDIOUT"); }
int GetTrackVis(MediaTrack* tr) // &1 == mcp, &2 == tcp { int iTrack = CSurf_TrackToID(tr, false); if (iTrack == 0) return *(int*)GetConfigVar("showmaintrack") ? 3 : 1; // For now, always return master vis in MCP else if (iTrack < 0) return 0; int iVis = *(bool*)GetSetMediaTrackInfo(tr, "B_SHOWINMIXER", NULL) ? 1 : 0; iVis |= *(bool*)GetSetMediaTrackInfo(tr, "B_SHOWINTCP", NULL) ? 2 : 0; return iVis; }
void SWS_GetSelectedMediaItemsOnTrack(WDL_TypedBuf<MediaItem*>* buf, MediaTrack* tr) { buf->Resize(0); if (CSurf_TrackToID(tr, false) <= 0) return; for (int j = 0; j < GetTrackNumMediaItems(tr); j++) { MediaItem* item = GetTrackMediaItem(tr, j); if (*(bool*)GetSetMediaItemInfo(item, "B_UISEL", NULL)) { int pos = buf->GetSize(); buf->Resize(pos + 1); buf->Get()[pos] = item; } } }
void SetTrackVis(MediaTrack* tr, int vis) // &1 == mcp, &2 == tcp { int iTrack = CSurf_TrackToID(tr, false); if (iTrack == 0) { // TODO - obey master in mcp if ((vis & 2) != (*(int*)GetConfigVar("showmaintrack") ? 2 : 0)) Main_OnCommand(40075, 0); } else if (iTrack > 0) { if (vis != GetTrackVis(tr)) { GetSetMediaTrackInfo(tr, "B_SHOWINTCP", vis & 2 ? &g_bTrue : &g_bFalse); GetSetMediaTrackInfo(tr, "B_SHOWINMIXER", vis & 1 ? &g_bTrue : &g_bFalse); } } }
void TrackSends::Build(MediaTrack* tr) { // Get the HW sends from the track object string const char* trackStr = SWS_GetSetObjectState(tr, NULL); char line[4096]; int pos = 0; while (GetChunkLine(trackStr, line, 4096, &pos, false)) { if (strncmp(line, "HWOUT", 5) == 0) m_hwSends.Add(new WDL_FastString(line)); } SWS_FreeHeapPtr(trackStr); // Get the track sends from the cooresponding track object string MediaTrack* pDest; int idx = 0; char searchStr[20]; sprintf(searchStr, "AUXRECV %d ", CSurf_TrackToID(tr, false) - 1); while ((pDest = (MediaTrack*)GetSetTrackSendInfo(tr, 0, idx++, "P_DESTTRACK", NULL))) { GUID guid = *(GUID*)GetSetMediaTrackInfo(pDest, "GUID", NULL); // Have we already parsed this particular dest track string? bool bParsed = false; for (int i = 0; i < m_sends.GetSize(); i++) if (GuidsEqual(m_sends.Get(i)->GetGuid(), &guid)) { bParsed = true; break; } if (bParsed) break; // We haven't parsed yet! trackStr = SWS_GetSetObjectState(pDest, NULL); pos = 0; while (GetChunkLine(trackStr, line, 4096, &pos, false)) { if (strncmp(line, searchStr, strlen(searchStr)) == 0) m_sends.Add(new TrackSend(&guid, line)); } SWS_FreeHeapPtr(trackStr); } }
// callers must unallocate the returned value, if any WDL_PtrList<MediaTrack>* GetChildTracks(MediaTrack* _tr) { int depth = (_tr ? *(int*)GetSetMediaTrackInfo(_tr, "I_FOLDERDEPTH", NULL) : 0); if (depth == 1) { WDL_PtrList<MediaTrack>* childTracks = new WDL_PtrList<MediaTrack>; int trIdx = CSurf_TrackToID(_tr, false) + 1; while (depth > 0 && trIdx <= GetNumTracks()) { MediaTrack* tr = CSurf_TrackFromID(trIdx, false); depth += *(int*)GetSetMediaTrackInfo(tr, "I_FOLDERDEPTH", NULL); childTracks->Add(tr); trIdx++; } if (childTracks->GetSize()) return childTracks; else delete childTracks; } return NULL; }
int SWS_TrackListWnd::OnKey(MSG* msg, int iKeyState) { if (msg->message == WM_KEYDOWN) { if (!iKeyState) switch (msg->wParam) { case VK_LEFT: TogInTCP(); return 1; case VK_RIGHT: TogInMCP(); return 1; case VK_DELETE: Main_OnCommand(40005, 0); // remove selected tracks return 1; case VK_F2: OnCommand(RENAME_MSG, 0); return 1; } // For some "odd" reason, shift-up and shift-down don't work on the tracklist, // so we handle them here with this obtuse code. There's perhaps a better way, but I don't // know what it is. if (iKeyState == LVKF_SHIFT && (msg->wParam == VK_DOWN || msg->wParam == VK_UP)) { int iTouched = m_trLastTouched ? CSurf_TrackToID(m_trLastTouched, false) : -1; if (!GetNumTracks() || (msg->wParam == VK_DOWN && iTouched == GetNumTracks()) || (msg->wParam == VK_UP && iTouched == 1)) return 1; // Find the first and last selected track int iFirst = 0, iLast = 0; for (int i = 1; i <= GetNumTracks(); i++) if (*(int*)GetSetMediaTrackInfo(CSurf_TrackFromID(i, false), "I_SELECTED", NULL)) { if (!iFirst) iFirst = i; iLast = i; } if (iTouched == -1) iTouched = msg->wParam == VK_DOWN ? iLast : iFirst; else { // Find the focused track, and un-focus it for (int i = 0; i < m_pLists.Get(0)->GetListItemCount(); i++) if (m_pLists.Get(0)->GetListItem(i) == (SWS_ListItem*)m_trLastTouched) { ListView_SetItemState(m_pLists.Get(0)->GetHWND(), i, 0, LVIS_FOCUSED); break; } } m_pLists.Get(0)->DisableUpdates(true); if (!iFirst) { // Nothing selected, so select last touched, or the first/last track if (!m_trLastTouched) m_trLastTouched = CSurf_TrackFromID(msg->wParam == VK_DOWN ? 1 : GetNumTracks(), false); GetSetMediaTrackInfo(m_trLastTouched, "I_SELECTED", &g_i1); } else if (msg->wParam == VK_DOWN) { if (iTouched > iFirst || iFirst == iLast) { m_trLastTouched = CSurf_TrackFromID(iTouched+1, false); GetSetMediaTrackInfo(m_trLastTouched, "I_SELECTED", &g_i1); } else if (iTouched == iFirst) { GetSetMediaTrackInfo(m_trLastTouched, "I_SELECTED", &g_i0); m_trLastTouched = CSurf_TrackFromID(iFirst+1, false); } } else // VK_UP { if (iTouched < iLast || iFirst == iLast) { m_trLastTouched = CSurf_TrackFromID(iTouched-1, false); GetSetMediaTrackInfo(m_trLastTouched, "I_SELECTED", &g_i1); } else if (iTouched == iLast) { GetSetMediaTrackInfo(m_trLastTouched, "I_SELECTED", &g_i0); m_trLastTouched = CSurf_TrackFromID(iLast-1, false); } } m_pLists.Get(0)->DisableUpdates(false); Update(); // Update the focus for (int i = 0; i < m_pLists.Get(0)->GetListItemCount(); i++) if (m_pLists.Get(0)->GetListItem(i) == (SWS_ListItem*)m_trLastTouched) { ListView_SetItemState(m_pLists.Get(0)->GetHWND(), i, LVIS_FOCUSED, LVIS_FOCUSED); break; } return 1; } else if (iKeyState == LVKF_SHIFT && msg->wParam == VK_UP) { return 1; } } return 0; }
// param _allTakes only makes sense if jobTake() is used bool FindWnd::FindMediaItem(int _dir, bool _allTakes, bool (*jobTake)(MediaItem_Take*,const char*), bool (*jobItem)(MediaItem*,const char*)) { bool update = false, found = false, sel = true; if (g_searchStr && *g_searchStr) { PreventUIRefresh(1); MediaItem* startItem = NULL; bool clearCurrentSelection = false; if (_dir) { WDL_PtrList<MediaItem> items; SNM_GetSelectedItems(NULL, &items); if (items.GetSize()) { startItem = FindPrevNextItem(_dir, items.Get(_dir > 0 ? 0 : items.GetSize()-1)); clearCurrentSelection = (startItem != NULL); } else startItem = FindPrevNextItem(_dir, NULL); } else { startItem = FindPrevNextItem(1, NULL); clearCurrentSelection = (startItem != NULL); } if (clearCurrentSelection) { Undo_BeginBlock2(NULL); Main_OnCommand(40289,0); // unselect all items update = true; } MediaItem* item = NULL; MediaTrack* startTr = startItem ? GetMediaItem_Track(startItem) : NULL; int startTrIdx = startTr ? CSurf_TrackToID(startTr, false) : -1; if (startTr && startItem && startTrIdx>=0) { // find startItem idx int startItemIdx=-1; while (item != startItem) item = GetTrackMediaItem(startTr,++startItemIdx); bool firstItem=true, breakSelection=false; for (int i=startTrIdx; !breakSelection && i <= CountTracks(NULL) && i>=1; i += (!_dir ? 1 : _dir)) { MediaTrack* tr = CSurf_TrackFromID(i, false); int nbItems = GetTrackNumMediaItems(tr); for (int j = (firstItem ? startItemIdx : (_dir >= 0 ? 0 : (nbItems-1))); tr && !breakSelection && j < nbItems && j >= 0; j += (!_dir ? 1 : _dir)) { item = GetTrackMediaItem(tr,j); firstItem = false; // search at item level if (jobItem) { if (jobItem(item, g_searchStr)) { if (!update) Undo_BeginBlock2(NULL); update = found = true; GetSetMediaItemInfo(item, "B_UISEL", &sel); if (_dir) breakSelection = true; } } // search at take level else if (jobTake) { int nbTakes = GetMediaItemNumTakes(item); for (int k=0; item && k < nbTakes; k++) { MediaItem_Take* tk = GetMediaItemTake(item, k); if (tk && (_allTakes || (!_allTakes && tk == GetActiveTake(item)))) { if (jobTake(tk, g_searchStr)) { if (!update) Undo_BeginBlock2(NULL); update = found = true; GetSetMediaItemInfo(item, "B_UISEL", &sel); if (_dir) { breakSelection = true; break; } } } } } } } } UpdateNotFoundMsg(found); if (found && m_zoomSrollItems) { if (!_dir) ZoomToSelItems(); else if (item) ScrollToSelItem(item); } PreventUIRefresh(-1); } if (update) { UpdateTimeline(); Undo_EndBlock2(NULL, __LOCALIZE("Find: change media item selection","sws_undo"), UNDO_STATE_ALL); } return update; }
bool FindWnd::FindTrack(int _dir, bool (*job)(MediaTrack*,const char*)) { bool update = false, found = false; if (g_searchStr && *g_searchStr) { int startTrIdx = -1; bool clearCurrentSelection = false; if (_dir) { if (int selTracksCount = SNM_CountSelectedTracks(NULL, true)) { if (MediaTrack* startTr = SNM_GetSelectedTrack(NULL, _dir > 0 ? 0 : selTracksCount-1, true)) { int id = CSurf_TrackToID(startTr, false); if ((_dir > 0 && id < CountTracks(NULL)) || (_dir < 0 && id >0)) { startTrIdx = id + _dir; clearCurrentSelection = true; } } } else startTrIdx = (_dir > 0 ? 0 : CountTracks(NULL)); } else { startTrIdx = 0; clearCurrentSelection = true; } if (clearCurrentSelection) { Undo_BeginBlock2(NULL); Main_OnCommand(40297,0); // unselect all tracks update = true; } if (startTrIdx >= 0) { for (int i = startTrIdx; i <= CountTracks(NULL) && i>=0; i += (!_dir ? 1 : _dir)) { MediaTrack* tr = CSurf_TrackFromID(i, false); if (tr && job(tr, g_searchStr)) { if (!update) Undo_BeginBlock2(NULL); update = found = true; GetSetMediaTrackInfo(tr, "I_SELECTED", &g_i1); if (_dir) break; } } } UpdateNotFoundMsg(found); if (found) ScrollSelTrack(true, true); } if (update) Undo_EndBlock2(NULL, __LOCALIZE("Find: change track selection","sws_undo"), UNDO_STATE_ALL); return update; }
// Return TRUE on delete send bool ResolveMissingRecv(MediaTrack* tr, int iSend, TrackSend* ts, WDL_PtrList<TrackSendFix>* pFix) { WDL_FastString str; char* cName = (char*)GetSetMediaTrackInfo(tr, "P_NAME", NULL); if (!cName || !cName[0]) cName = (char*)__LOCALIZE("(unnamed)","sws_DLG_114"); str.SetFormatted(200, __LOCALIZE_VERFMT("Send %d on track %d \"%s\" is missing its receive track!","sws_DLG_114"), iSend+1, CSurf_TrackToID(tr, false), cName); g_cErrorStr = str.Get(); g_ts = ts; g_send = tr; g_recv = NULL; DialogBox(g_hInst, MAKEINTRESOURCE(IDD_RECVMISSING), g_hwndParent, doResolve); if (g_iResolveRet == 1) return true; else if (g_iResolveRet == 2) { GUID* newGuid = (GUID*)GetSetMediaTrackInfo(g_recv, "GUID", NULL); if (pFix) pFix->Add(new TrackSendFix(ts->GetGuid(), newGuid)); ts->SetGuid(newGuid); } return false; }
void TrackSends::UpdateReaper(MediaTrack* tr, WDL_PtrList<TrackSendFix>* pFix) { // First replace all the hw sends with the stored const char* trackStr = SWS_GetSetObjectState(tr, NULL); WDL_FastString newTrackStr; char line[4096]; int pos = 0; bool bChanged = false; while (GetChunkLine(trackStr, line, 4096, &pos, true)) { if (strncmp(line, "HWOUT", 5) != 0) newTrackStr.Append(line); else bChanged = true; } for (int i = 0; i < m_hwSends.GetSize(); i++) { bChanged = true; AppendChunkLine(&newTrackStr, m_hwSends.Get(i)->Get()); } SWS_FreeHeapPtr(trackStr); if (bChanged) SWS_GetSetObjectState(tr, &newTrackStr); // Check for destination track validity for (int i = 0; i < m_sends.GetSize(); i++) if (!GuidToTrack(m_sends.Get(i)->GetGuid())) { bool bFixed = false; if (pFix) { for (int j = 0; j < pFix->GetSize(); j++) if (GuidsEqual(&pFix->Get(j)->m_oldGuid, m_sends.Get(i)->GetGuid())) { m_sends.Get(i)->SetGuid(&pFix->Get(j)->m_newGuid); bFixed = true; break; } } if (!bFixed) { GUID newGuid = GUID_NULL; int iRet = ResolveMissingRecv(tr, i, m_sends.Get(i), pFix); if (iRet == 1) // Success! m_sends.Get(i)->SetGuid(&newGuid); else if (iRet == 2) // Delete { m_sends.Delete(i, true); i--; } } } // Now, delete any existing sends and add as necessary // Loop through each track char searchStr[20]; sprintf(searchStr, "AUXRECV %d", CSurf_TrackToID(tr, false) - 1); WDL_FastString sendStr; GUID* trGuid = (GUID*)GetSetMediaTrackInfo(tr, "GUID", NULL); for (int i = 1; i <= GetNumTracks(); i++) { MediaTrack* pDest = CSurf_TrackFromID(i, false); newTrackStr.Set(""); trackStr = NULL; MediaTrack* pSrc; int idx = 0; while ((pSrc = (MediaTrack*)GetSetTrackSendInfo(pDest, -1, idx++, "P_SRCTRACK", NULL))) if (pSrc == tr) { trackStr = SWS_GetSetObjectState(pDest, NULL); pos = 0; // Remove existing recvs from the src track while (GetChunkLine(trackStr, line, 4096, &pos, true)) { if (strncmp(line, searchStr, strlen(searchStr)) != 0) newTrackStr.Append(line); } break; } GUID guid = *(GUID*)GetSetMediaTrackInfo(pDest, "GUID", NULL); for (int i = 0; i < m_sends.GetSize(); i++) { if (GuidsEqual(&guid, m_sends.Get(i)->GetGuid()) && !GuidsEqual(&guid, trGuid)) { if (!trackStr) { trackStr = SWS_GetSetObjectState(pDest, NULL); newTrackStr.Set(trackStr); } AppendChunkLine(&newTrackStr, m_sends.Get(i)->AuxRecvString(tr, &sendStr)->Get()); } } if (trackStr) { SWS_GetSetObjectState(pDest, &newTrackStr); SWS_FreeHeapPtr(trackStr); } } }
int RprTrack::getTrackIndex() { return CSurf_TrackToID(mTrack, false); }