void MarkerNudge(bool bRight) { // Find the marker underneath the edit cursor int x = 0; int iIndex, iColor; double dPos, dEnd; bool bReg; double dCurPos = GetCursorPosition(); while (x = EnumProjectMarkers3(NULL, x, &bReg, &dPos, &dEnd, NULL, &iIndex, &iColor)) { if (dPos == dCurPos) { dCurPos += (bRight ? 1.0 : -1.0) / GetHZoomLevel(); if (dCurPos >= 0) { SetProjectMarkerByIndex(NULL, x-1, bReg, dCurPos, dEnd, iIndex, NULL, iColor); SetEditCurPos(dCurPos, true, false); return; } } } }
void MoveTempo (COMMAND_T* ct) { BR_Envelope tempoMap(GetTempoEnv()); if (!tempoMap.Count()) return; double cursor = GetCursorPositionEx(NULL); double tDiff = 0; int targetId = -1; // Find tempo marker closest to the edit cursor if ((int)ct->user == 3) { targetId = tempoMap.FindClosest(cursor); if (targetId == 0) ++targetId; if (!tempoMap.ValidateId(targetId)) return; double cTime; tempoMap.GetPoint(targetId, &cTime, NULL, NULL, NULL); tDiff = cursor - cTime; } // Just get time difference for selected points else { if ((int)ct->user == 2 || (int)ct->user == -2) tDiff = 1 / GetHZoomLevel() * (double)ct->user / 2; else tDiff = (double)ct->user/10000; } if (tDiff == 0) return; // Loop through selected points int skipped = 0; int count = (targetId != -1) ? (1) : (tempoMap.CountSelected()); for (int i = 0; i < count; ++i) { if (int id = ((int)ct->user == 3) ? (targetId) : (tempoMap.GetSelected(i))) // skip first point skipped += (MoveTempo(tempoMap, id, tDiff)) ? (0) : (1); } // Commit changes PreventUIRefresh(1); // prevent jumpy cursor if (tempoMap.Commit()) { if ((int)ct->user == 3) SetEditCurPos2(NULL, cursor, false, false); // always keep cursor position when moving to closest tempo marker Undo_OnStateChangeEx2(NULL, SWS_CMD_SHORTNAME(ct), UNDO_STATE_ALL, -1); } PreventUIRefresh(-1); // Warn user if some points weren't processed static bool s_warnUser = true; if (s_warnUser && skipped != 0) { char buffer[512]; _snprintfSafe(buffer, sizeof(buffer), __LOCALIZE_VERFMT("%d of the selected points didn't get processed because some points would end up with illegal BPM or position. Would you like to be warned if it happens again?", "sws_mbox"), skipped); int userAnswer = ShowMessageBox(buffer, __LOCALIZE("SWS - Warning", "sws_mbox"), 4); if (userAnswer == 7) s_warnUser = false; } }
bool BR_MidiEditor::Build () { m_take = (m_midiEditor) ? SWS_MIDIEditor_GetTake(m_midiEditor) : m_take; if (m_take) { MediaItem* item = GetMediaItemTake_Item(m_take); int takeId = GetTakeId(m_take, item); if (takeId >= 0) { SNM_TakeParserPatcher p(item, CountTakes(item)); WDL_FastString takeChunk; if (p.GetTakeChunk(takeId, &takeChunk)) { SNM_ChunkParserPatcher ptk(&takeChunk, false); LineParser lp(false); int laneId = 0; WDL_FastString lineLane; while (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "VELLANE", laneId++, -1, &lineLane)) { lp.parse(lineLane.Get()); m_ccLanes.push_back(lp.gettoken_int(1)); m_ccLanesHeight.push_back(lp.gettoken_int(((m_midiEditor) ? 2 : 3))); if (!m_midiEditor && m_ccLanesHeight.back() == 0) m_ccLanesHeight.back() = INLINE_MIDI_LANE_DIVIDER_H; // sometimes REAPER will return 0 when lane is completely hidden, but divider will still be visible lineLane.DeleteSub(0, lineLane.GetLength()); } WDL_FastString dataLine; if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "HASDATA", 0, -1, &dataLine)) { lp.parse(dataLine.Get()); m_ppq = lp.gettoken_int(2); } else if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "FILE", 0, -1, &dataLine)) { lp.parse(dataLine.Get()); m_ppq = GetMIDIFilePPQ (lp.gettoken_str(1)); if (!m_ppq) return false; } else return false; WDL_FastString lineView; if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "CFGEDITVIEW", 0, -1, &lineView)) { lp.parse(lineView.Get()); m_startPos = (m_midiEditor) ? lp.gettoken_float(1) : GetMediaItemInfo_Value(GetMediaItemTake_Item(m_take), "D_POSITION"); m_hZoom = (m_midiEditor) ? lp.gettoken_float(2) : GetHZoomLevel(); m_vPos = (m_midiEditor) ? lp.gettoken_int(3) : lp.gettoken_int(7); m_vZoom = (m_midiEditor) ? lp.gettoken_int(4) : lp.gettoken_int(6); } else return false; WDL_FastString lineFilter; if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "EVTFILTER", 0, -1, &lineFilter)) { lp.parse(lineFilter.Get()); m_filterEnabled = !!GetBit(lp.gettoken_int(7), 0); m_filterInverted = !!GetBit(lp.gettoken_int(7), 2); m_filterChannel = lp.gettoken_int(1); m_filterEventType = lp.gettoken_int(2); m_filterEventParam = !!lp.gettoken_int(16); m_filterEventVal = !!lp.gettoken_int(8); m_filterEventPos = !!lp.gettoken_int(14); m_filterEventLen = !!lp.gettoken_int(9); m_filterEventParamLo = lp.gettoken_int(17); m_filterEventParamHi = lp.gettoken_int(18); m_filterEventValLo = lp.gettoken_int(4); m_filterEventValHi = lp.gettoken_int(5); m_filterEventPosRepeat = lp.gettoken_float(15); m_filterEventPosLo = lp.gettoken_float(12); m_filterEventPosHi = lp.gettoken_float(13); m_filterEventLenLo = lp.gettoken_float(10); m_filterEventLenHi = lp.gettoken_float(11); } else return false; WDL_FastString lineProp; if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "CFGEDIT", 0, -1, &lineProp)) { lp.parse(lineProp.Get()); m_pianoroll = (m_midiEditor) ? lp.gettoken_int(6) : 0; // inline midi editor doesn't have piano roll modes m_drawChannel = lp.gettoken_int(9) - 1; m_noteshow = lp.gettoken_int(18); m_timebase = (m_midiEditor) ? lp.gettoken_int(19) : PROJECT_SYNC; } else return false; // A few "corrections" for easier manipulation afterwards if (m_filterChannel == 0) m_filterChannel = ~m_filterChannel; if (m_filterEventParamLo < 0) m_filterEventParamLo = 0; if (m_filterEventParamHi < 0) m_filterEventParamHi = INT_MAX; if (m_filterEventValLo < 0) m_filterEventValLo = 0; if (m_filterEventValHi < 0) m_filterEventValHi = INT_MAX; if (m_filterEventPosLo < 0) m_filterEventPosLo = 0; if (m_filterEventPosHi < 0) m_filterEventPosHi = INT_MAX; m_filterEventLenLo = (m_filterEventLenLo < 0) ? (0) : (m_ppq * 4 * m_filterEventLenLo); m_filterEventLenHi = (m_filterEventLenHi < 0) ? (INT_MAX) : (m_ppq * 4 * m_filterEventLenHi); m_filterEventPosLo = (m_filterEventPosLo < 0) ? (0) : (m_ppq * 4 * m_filterEventPosLo); m_filterEventPosHi = (m_filterEventPosHi < 0) ? (INT_MAX) : (m_ppq * 4 * m_filterEventPosHi); m_filterEventPosRepeat = (m_filterEventPosRepeat < 0) ? (0) : (m_ppq * 4 * m_filterEventPosRepeat); return true; } } } return false; }