use crate::{
Hwnd, KbdSectionInfo, MediaTrack, MidiOutputDeviceId, ReaProject, ReaperStringArg,
TryFromRawError,
};
use c_str_macro::c_str;
use helgoboss_midi::{U14, U7};
use reaper_low::raw;
use std::borrow::Cow;
use std::convert::TryInto;
use std::ffi::CStr;
use std::os::raw::c_void;
use std::ptr::{null_mut, NonNull};
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum AddFxBehavior {
AddIfNotFound,
AlwaysAdd,
}
impl From<AddFxBehavior> for FxAddByNameBehavior {
fn from(b: AddFxBehavior) -> FxAddByNameBehavior {
use AddFxBehavior::*;
match b {
AddIfNotFound => FxAddByNameBehavior::AddIfNotFound,
AlwaysAdd => FxAddByNameBehavior::AlwaysAdd,
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum TrackFxChainType {
NormalFxChain,
InputFxChain,
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum MasterTrackBehavior {
ExcludeMasterTrack,
IncludeMasterTrack,
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum ChunkCacheHint {
NormalMode,
UndoMode,
}
#[derive(Clone, PartialEq, Debug)]
pub enum ValueChange<T: Copy + Into<f64>> {
Absolute(T),
Relative(f64),
}
impl<T: Copy + Into<f64>> ValueChange<T> {
pub(crate) fn value(&self) -> f64 {
use ValueChange::*;
match self {
Absolute(v) => (*v).into(),
Relative(v) => *v,
}
}
pub(crate) fn is_relative(&self) -> bool {
matches!(self, ValueChange::Relative(_))
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum UndoBehavior {
OmitUndoPoint,
AddUndoPoint,
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum TransferBehavior {
Copy,
Move,
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum TrackDefaultsBehavior {
OmitDefaultEnvAndFx,
AddDefaultEnvAndFx,
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum GangBehavior {
DenyGang,
AllowGang,
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum RecordArmMode {
Unarmed,
Armed,
}
impl RecordArmMode {
pub fn to_raw(&self) -> i32 {
use RecordArmMode::*;
match self {
Unarmed => 0,
Armed => 1,
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum FxShowInstruction {
HideChain,
ShowChain(TrackFxLocation),
HideFloatingWindow(TrackFxLocation),
ShowFloatingWindow(TrackFxLocation),
}
impl FxShowInstruction {
pub fn instruction_to_raw(&self) -> i32 {
use FxShowInstruction::*;
match self {
HideChain => 0,
ShowChain(_) => 1,
HideFloatingWindow(_) => 2,
ShowFloatingWindow(_) => 3,
}
}
pub fn location_to_raw(&self) -> i32 {
use FxShowInstruction::*;
match self {
HideChain => 0,
ShowChain(l) => l.to_raw(),
HideFloatingWindow(l) => l.to_raw(),
ShowFloatingWindow(l) => l.to_raw(),
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum TrackSendDirection {
Receive,
Send,
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum TrackSendCategory {
Receive = -1,
Send = 0,
HardwareOutput = 1,
}
impl TrackSendCategory {
pub fn to_raw(&self) -> i32 {
use TrackSendCategory::*;
match self {
Receive => -1,
Send => 0,
HardwareOutput => 1,
}
}
}
impl From<TrackSendDirection> for TrackSendCategory {
fn from(v: TrackSendDirection) -> TrackSendCategory {
use TrackSendDirection::*;
match v {
Receive => TrackSendCategory::Receive,
Send => TrackSendCategory::Send,
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum StuffMidiMessageTarget {
VirtualMidiKeyboardQueue,
MidiAsControlInputQueue,
VirtualMidiKeyboardQueueOnCurrentChannel,
MidiOutputDevice(MidiOutputDeviceId),
}
impl StuffMidiMessageTarget {
pub fn to_raw(&self) -> i32 {
use StuffMidiMessageTarget::*;
match self {
VirtualMidiKeyboardQueue => 0,
MidiAsControlInputQueue => 1,
VirtualMidiKeyboardQueueOnCurrentChannel => 2,
MidiOutputDevice(id) => 16 + id.0 as i32,
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum TrackFxLocation {
NormalFxChain(u32),
InputFxChain(u32),
}
impl TrackFxLocation {
pub fn try_from_raw(v: i32) -> Result<TrackFxLocation, TryFromRawError<i32>> {
use TrackFxLocation::*;
let v: u32 = v
.try_into()
.map_err(|_| TryFromRawError::new("FX index shouldn't be negative", v))?;
let result = if v >= 0x1000000 {
InputFxChain(v - 0x1000000)
} else {
NormalFxChain(v)
};
Ok(result)
}
pub fn to_raw(&self) -> i32 {
use TrackFxLocation::*;
let positive = match *self {
InputFxChain(idx) => 0x1000000 + idx,
NormalFxChain(idx) => idx,
};
positive as i32
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub(crate) enum FxAddByNameBehavior {
AlwaysAdd,
Query,
AddIfNotFound,
}
impl FxAddByNameBehavior {
pub fn to_raw(&self) -> i32 {
use FxAddByNameBehavior::*;
match self {
AlwaysAdd => -1,
Query => 0,
AddIfNotFound => 1,
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum ActionValueChange {
AbsoluteLowRes(U7),
AbsoluteHighRes(U14),
Relative1(U7),
Relative2(U7),
Relative3(U7),
}
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub enum RegistrationObject<'a> {
HookCommand(raw::HookCommandFn),
HookPostCommand(raw::HookPostCommandFn),
ToggleAction(raw::ToggleActionFn),
CommandId(Cow<'a, CStr>),
Gaccel(NonNull<raw::gaccel_register_t>),
CsurfInst(NonNull<raw::IReaperControlSurface>),
Custom(Cow<'a, CStr>, *mut c_void),
}
impl<'a> RegistrationObject<'a> {
pub fn custom(
key: impl Into<ReaperStringArg<'a>>,
info_struct: *mut c_void,
) -> RegistrationObject<'a> {
RegistrationObject::Custom(key.into().into_inner(), info_struct)
}
pub(crate) fn into_owned(self) -> RegistrationObject<'static> {
use RegistrationObject::*;
match self {
HookCommand(func) => HookCommand(func),
HookPostCommand(func) => HookPostCommand(func),
ToggleAction(func) => ToggleAction(func),
CommandId(command_name) => CommandId(command_name.into_owned().into()),
Gaccel(reg) => Gaccel(reg),
CsurfInst(inst) => CsurfInst(inst),
Custom(key, info_struct) => Custom(key.into_owned().into(), info_struct),
}
}
pub(crate) fn key_into_raw(self) -> Cow<'a, CStr> {
use RegistrationObject::*;
match self {
HookCommand(_) => c_str!("hookcommand").into(),
HookPostCommand(_) => c_str!("hookpostcommand").into(),
ToggleAction(_) => c_str!("toggleaction").into(),
CommandId(_) => c_str!("command_id").into(),
Gaccel(_) => c_str!("gaccel").into(),
CsurfInst(_) => c_str!("csurf_inst").into(),
Custom(key, _) => key,
}
}
pub(crate) fn ptr_to_raw(&self) -> *mut c_void {
use RegistrationObject::*;
match self {
HookCommand(func) => *func as *mut c_void,
HookPostCommand(func) => *func as *mut c_void,
ToggleAction(func) => *func as *mut c_void,
CommandId(command_name) => command_name.as_ptr() as *mut c_void,
Gaccel(reg) => reg.as_ptr() as *mut c_void,
CsurfInst(inst) => inst.as_ptr() as *mut c_void,
Custom(_, info_struct) => *info_struct,
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum TrackRef {
MasterTrack,
NormalTrack(u32),
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum InputMonitoringMode {
Off,
Normal,
NotWhenPlaying,
}
impl InputMonitoringMode {
pub fn try_from_raw(v: i32) -> Result<InputMonitoringMode, TryFromRawError<i32>> {
use InputMonitoringMode::*;
match v {
0 => Ok(Off),
1 => Ok(Normal),
2 => Ok(NotWhenPlaying),
_ => Err(TryFromRawError::new(
"couldn't convert to input monitoring mode",
v,
)),
}
}
pub fn to_raw(&self) -> i32 {
use InputMonitoringMode::*;
match self {
Off => 0,
Normal => 1,
NotWhenPlaying => 2,
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum ProjectRef {
Current,
CurrentlyRendering,
Tab(u32),
}
impl ProjectRef {
pub fn to_raw(&self) -> i32 {
use ProjectRef::*;
match *self {
Current => -1,
CurrentlyRendering => 0x40000000,
Tab(i) => i as i32,
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum FxPresetRef {
FactoryPreset,
DefaultUserPreset,
Preset(u32),
}
impl FxPresetRef {
pub fn to_raw(&self) -> i32 {
use FxPresetRef::*;
match *self {
FactoryPreset => -2,
DefaultUserPreset => -1,
Preset(idx) => idx as i32,
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum ProjectContext {
CurrentProject,
Proj(ReaProject),
}
impl ProjectContext {
pub fn to_raw(&self) -> *mut raw::ReaProject {
use ProjectContext::*;
match self {
Proj(p) => p.as_ptr(),
CurrentProject => null_mut(),
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum NotificationBehavior {
NotifyAll,
NotifyAllExcept(NonNull<raw::IReaperControlSurface>),
}
impl NotificationBehavior {
pub fn to_raw(&self) -> *mut raw::IReaperControlSurface {
use NotificationBehavior::*;
match self {
NotifyAllExcept(s) => s.as_ptr(),
NotifyAll => null_mut(),
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum SendTarget {
HardwareOutput,
OtherTrack(MediaTrack),
}
impl SendTarget {
pub fn to_raw(&self) -> *mut raw::MediaTrack {
use SendTarget::*;
match self {
HardwareOutput => null_mut(),
OtherTrack(t) => t.as_ptr(),
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum SectionContext<'a> {
MainSection,
Sec(&'a KbdSectionInfo),
}
impl<'a> SectionContext<'a> {
pub fn to_raw(&self) -> *mut raw::KbdSectionInfo {
use SectionContext::*;
match self {
MainSection => null_mut(),
Sec(i) => i.0.as_ptr(),
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum WindowContext {
NoWindow,
Win(Hwnd),
}
impl WindowContext {
pub fn to_raw(&self) -> raw::HWND {
use WindowContext::*;
match self {
Win(h) => h.as_ptr(),
NoWindow => null_mut(),
}
}
}