diff --git a/main/medium/src/flags.rs b/main/medium/src/flags.rs index a8429727..adbb2f86 100644 --- a/main/medium/src/flags.rs +++ b/main/medium/src/flags.rs @@ -110,3 +110,14 @@ pub enum SetTrackUiFlags { PreventTrackGrouping = 1, PreventSelectionGanging = 2, } + +/// Defines nudge mode in `apply_nudge` +/// +/// if not SetToValue — will nudge by value. +#[enumflags2::bitflags] +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +#[repr(u32)] +pub enum ApplyNudgeFlag { + SetToValue = 1, + Snap = 2, +} \ No newline at end of file diff --git a/main/medium/src/misc_enums.rs b/main/medium/src/misc_enums.rs index f34ad0fd..6e0edefa 100644 --- a/main/medium/src/misc_enums.rs +++ b/main/medium/src/misc_enums.rs @@ -1664,3 +1664,53 @@ impl InsertMediaMode { bits as i32 } } + +/// Defines, in which units nudge will be applied. +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +pub enum NudgeUnits { + Milliseconds, + Seconds, + Grid, + Notes256, + Notes128, + Notes64, + Notes32, + Notes16, + Notes8, + Notes4, + Notes2, + NotesWhole, + /// (1.15 = 1 measure + 1.5 beats) + MeasuresBeats, + Samples, + Frames, + Pixels, + ItemLength, + ItemSelections, +} + +impl NudgeUnits { + /// Converts this value to an integer as expected by the low-level API. + pub fn to_raw(self) -> i32 { + match self { + Self::Milliseconds => 0, + Self::Seconds => 1, + Self::Grid => 2, + Self::Notes256 => 3, + Self::Notes128 => 4, + Self::Notes64 => 5, + Self::Notes32 => 6, + Self::Notes16 => 7, + Self::Notes8 => 8, + Self::Notes4 => 9, + Self::Notes2 => 10, + Self::NotesWhole => 15, + Self::MeasuresBeats => 16, + Self::Samples => 17, + Self::Frames => 18, + Self::Pixels => 19, + Self::ItemLength => 20, + Self::ItemSelections => 21, + } + } +} diff --git a/main/medium/src/reaper.rs b/main/medium/src/reaper.rs index 95c8e1b9..7b5b139d 100644 --- a/main/medium/src/reaper.rs +++ b/main/medium/src/reaper.rs @@ -6,27 +6,28 @@ use reaper_low::{raw, register_plugin_destroy_hook}; use crate::ProjectContext::CurrentProject; use crate::{ - require_non_null_panic, Accel, ActionValueChange, AddFxBehavior, AudioDeviceAttributeKey, - AutoSeekBehavior, AutomationMode, BookmarkId, BookmarkRef, Bpm, ChunkCacheHint, CommandId, Db, - DurationInSeconds, EditMode, EnvChunkName, FxAddByNameBehavior, FxChainVisibility, FxPresetRef, - FxShowInstruction, GangBehavior, GlobalAutomationModeOverride, HelpMode, Hidden, Hwnd, - InitialAction, InputMonitoringMode, InsertMediaFlag, InsertMediaMode, KbdSectionInfo, - MasterTrackBehavior, MeasureMode, MediaItem, MediaItemTake, MediaTrack, MessageBoxResult, - MessageBoxType, MidiImportBehavior, MidiInput, MidiInputDeviceId, MidiOutput, - MidiOutputDeviceId, NativeColor, NormalizedPlayRate, NotificationBehavior, OwnedPcmSource, - OwnedReaperPitchShift, OwnedReaperResample, PanMode, ParamId, PcmSource, PitchShiftMode, - PitchShiftSubMode, PlaybackSpeedFactor, PluginContext, PositionInBeats, PositionInQuarterNotes, - PositionInSeconds, Progress, ProjectContext, ProjectRef, PromptForActionResult, ReaProject, - ReaperFunctionError, ReaperFunctionResult, ReaperNormalizedFxParamValue, ReaperPanLikeValue, - ReaperPanValue, ReaperPointer, ReaperStr, ReaperString, ReaperStringArg, ReaperVersion, - ReaperVolumeValue, ReaperWidthValue, RecordArmMode, RecordingInput, RequiredViewMode, - ResampleMode, SectionContext, SectionId, SendTarget, SetTrackUiFlags, SoloMode, - StuffMidiMessageTarget, TakeAttributeKey, TimeModeOverride, TimeRangeType, TrackArea, - TrackAttributeKey, TrackDefaultsBehavior, TrackEnvelope, TrackFxChainType, TrackFxLocation, - TrackLocation, TrackMuteOperation, TrackMuteState, TrackPolarity, TrackPolarityOperation, - TrackRecArmOperation, TrackSendAttributeKey, TrackSendCategory, TrackSendDirection, - TrackSendRef, TrackSoloOperation, TransferBehavior, UiRefreshBehavior, UndoBehavior, UndoScope, - ValueChange, VolumeSliderValue, WindowContext, + require_non_null_panic, Accel, ActionValueChange, AddFxBehavior, ApplyNudgeFlag, + AudioDeviceAttributeKey, AutoSeekBehavior, AutomationMode, BookmarkId, BookmarkRef, Bpm, + ChunkCacheHint, CommandId, Db, DurationInSeconds, EditMode, EnvChunkName, FxAddByNameBehavior, + FxChainVisibility, FxPresetRef, FxShowInstruction, GangBehavior, GlobalAutomationModeOverride, + HelpMode, Hidden, Hwnd, InitialAction, InputMonitoringMode, InsertMediaFlag, InsertMediaMode, + KbdSectionInfo, MasterTrackBehavior, MeasureMode, MediaItem, MediaItemTake, MediaTrack, + MessageBoxResult, MessageBoxType, MidiImportBehavior, MidiInput, MidiInputDeviceId, MidiOutput, + MidiOutputDeviceId, NativeColor, NormalizedPlayRate, NotificationBehavior, NudgeUnits, + OwnedPcmSource, OwnedReaperPitchShift, OwnedReaperResample, PanMode, ParamId, PcmSource, + PitchShiftMode, PitchShiftSubMode, PlaybackSpeedFactor, PluginContext, PositionInBeats, + PositionInQuarterNotes, PositionInSeconds, Progress, ProjectContext, ProjectRef, + PromptForActionResult, ReaProject, ReaperFunctionError, ReaperFunctionResult, + ReaperNormalizedFxParamValue, ReaperPanLikeValue, ReaperPanValue, ReaperPointer, ReaperStr, + ReaperString, ReaperStringArg, ReaperVersion, ReaperVolumeValue, ReaperWidthValue, + RecordArmMode, RecordingInput, RequiredViewMode, ResampleMode, SectionContext, SectionId, + SendTarget, SetTrackUiFlags, SoloMode, StuffMidiMessageTarget, TakeAttributeKey, + TimeModeOverride, TimeRangeType, TrackArea, TrackAttributeKey, TrackDefaultsBehavior, + TrackEnvelope, TrackFxChainType, TrackFxLocation, TrackLocation, TrackMuteOperation, + TrackMuteState, TrackPolarity, TrackPolarityOperation, TrackRecArmOperation, + TrackSendAttributeKey, TrackSendCategory, TrackSendDirection, TrackSendRef, TrackSoloOperation, + TransferBehavior, UiRefreshBehavior, UndoBehavior, UndoScope, ValueChange, VolumeSliderValue, + WindowContext, }; use helgoboss_midi::ShortMessage; @@ -996,6 +997,54 @@ impl Reaper { unsafe { self.any_track_solo_unchecked(project) } } + /// True if function name exists in the REAPER API + pub fn api_exists(&self, function_name: ReaperStringArg) -> bool + where + UsageScope: MainThreadOnly, + { + unsafe { self.low().APIExists(function_name.as_ptr()) } + } + + /// Displays a message window if the API was successfully called. + pub fn api_test(&self) + where + UsageScope: MainThreadOnly, + { + self.low().APITest() + } + + /// Applies nudge. + /// + /// value depends on nudge_units. + /// + /// if reverse=true: in nudge mode + /// (e.g. !ApplyNudgeFlag::SetToValue) nudges left + /// + /// copies ignored if not in nudge duplicate mode. + pub unsafe fn apply_nudge( + &self, + project: ProjectContext, + nudge_flag: BitFlags, + nudge_what: i32, + nudge_units: NudgeUnits, + value: f64, + reverse: bool, + copies: i32, + ) -> bool + where + UsageScope: MainThreadOnly, + { + self.low().ApplyNudge( + project.to_raw(), + nudge_flag.bits() as i32, + nudge_what, + nudge_units.to_raw(), + value, + reverse, + copies, + ) + } + /// Like [`any_track_solo()`] but doesn't check if project is valid. /// /// # Safety