|
|
@ -0,0 +1,674 @@ |
|
|
|
-- Reaper Script to add major take management functions, like: |
|
|
|
-- - Take counter with unique number ("how often REC was pressed") |
|
|
|
-- - Write takenumber to name of recorded file (by changing tracknames) |
|
|
|
-- - Group recorded items after stop (all or just horizontally) |
|
|
|
-- - Lock to active take (in lanes) after record |
|
|
|
-- - Write clean takenames after record, for easy recognition. E.g. "T042 (Violin 1)" |
|
|
|
-- Version from 19.6.2019, written by Ludwig Frühschütz |
|
|
|
-- Basic gui stuff by forum user "spk77": https://forum.cockos.com/showthread.php?t=161557 |
|
|
|
|
|
|
|
|
|
|
|
-- Some adjustable settings: |
|
|
|
-- Initial values if no settings stored in project |
|
|
|
local groupItemsAfterRecord = true |
|
|
|
local groupItemsHAfterRecord = false |
|
|
|
local fillGapsAfterRecord = true |
|
|
|
local lockToActiveTakeAfterRecord = true |
|
|
|
local writeTakeNamesAfterRecord = true |
|
|
|
|
|
|
|
-- Nothing to adjust here anymore... |
|
|
|
local script_path |
|
|
|
local mouse |
|
|
|
local Menu |
|
|
|
local gui = {} -- contains some settings for the GUI |
|
|
|
local increaseTodo = false -- used to detect transition form "REC" to "STOP" and then inc. takenumber |
|
|
|
local quit = false |
|
|
|
local sws_present = false |
|
|
|
|
|
|
|
-- Send a message to the console |
|
|
|
function msg(m) |
|
|
|
reaper.ShowConsoleMsg(tostring(m) .. "\n") |
|
|
|
end |
|
|
|
|
|
|
|
-- Write Takenumber and Trackname to selected items active takenames |
|
|
|
function writeTakeNames() |
|
|
|
local k = 0 |
|
|
|
local thisItem = reaper.GetSelectedMediaItem(0, k) |
|
|
|
local takestring |
|
|
|
local name = ' ' |
|
|
|
-- try to get takenumber from rpp. If not present, leave at "-1" |
|
|
|
retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'nexttake') |
|
|
|
if retval > 0 then |
|
|
|
takestring = 'T' .. string.format('%03d', tonumber(val)) -- format string to prepend to takename, e.g. "T042" |
|
|
|
else |
|
|
|
takestring = 'T???' |
|
|
|
end |
|
|
|
-- run through all selected items |
|
|
|
while (thisItem) |
|
|
|
do |
|
|
|
local theTake = reaper.GetActiveTake(thisItem) |
|
|
|
local track = reaper.GetMediaItem_Track(thisItem) |
|
|
|
-- get trackname without takenumber |
|
|
|
name = select( 2, reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, false) ) |
|
|
|
if name:sub(-5,-4) == '_T' then |
|
|
|
name = name:sub(1,-6) |
|
|
|
elseif name:sub(-4,-3) == '_T' then |
|
|
|
name = name:sub(1,-5) |
|
|
|
elseif name:sub(-3,-2) == '_T' then |
|
|
|
name = name:sub(1,-4) |
|
|
|
elseif name:sub(-2,-1) == '_T' then |
|
|
|
name = name:sub(1,-3) |
|
|
|
end |
|
|
|
reaper.GetSetMediaItemTakeInfo_String(theTake, 'P_NAME', takestring .. ' (' .. name .. ')', true) |
|
|
|
k = k+1 |
|
|
|
thisItem = reaper.GetSelectedMediaItem(0, k) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
-- Lock to active take in lanes (to not accidentally select one by clicking) |
|
|
|
function setLockToActiveTake() |
|
|
|
reaper.Main_OnCommand(41340, 0) -- cant get momentary state, so simply set it every time... |
|
|
|
end |
|
|
|
|
|
|
|
-- Get the highest group-ID in use |
|
|
|
function maxProjectGroupID() |
|
|
|
local floor = math.floor |
|
|
|
local all_item_count = reaper.CountMediaItems(0) |
|
|
|
local MaxGroupID = 0 |
|
|
|
for i = 0, all_item_count - 1 do |
|
|
|
local item = reaper.GetMediaItem(0, i) |
|
|
|
local item_group_id = floor(reaper.GetMediaItemInfo_Value(item, "I_GROUPID")) |
|
|
|
if item_group_id > MaxGroupID then |
|
|
|
MaxGroupID = item_group_id |
|
|
|
end |
|
|
|
end |
|
|
|
return MaxGroupID |
|
|
|
end |
|
|
|
|
|
|
|
-- Group all selected items |
|
|
|
function groupItems() |
|
|
|
local groupID = maxProjectGroupID() + 1 |
|
|
|
local k = 0 |
|
|
|
local thisItem = reaper.GetSelectedMediaItem(0, k) |
|
|
|
while (thisItem) |
|
|
|
do |
|
|
|
reaper.SetMediaItemInfo_Value(thisItem, "I_GROUPID", groupID) |
|
|
|
k = k+1 |
|
|
|
thisItem = reaper.GetSelectedMediaItem(0, k) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
-- Group selected items horizontally |
|
|
|
function groupItemsH() |
|
|
|
local init_sel_tracks = {} |
|
|
|
local groupID = maxProjectGroupID() + 1 |
|
|
|
local j = 0 |
|
|
|
local k = 0 |
|
|
|
|
|
|
|
-- store selected tracks before work... |
|
|
|
for i = 0, reaper.CountSelectedTracks(0)-1 do |
|
|
|
init_sel_tracks[i+1] = reaper.GetSelectedTrack(0, i) |
|
|
|
end |
|
|
|
|
|
|
|
local thisTrack = reaper.GetTrack(0, j) |
|
|
|
while (thisTrack) do |
|
|
|
local thisItem = reaper.GetTrackMediaItem(thisTrack, k) |
|
|
|
while (thisItem) |
|
|
|
do |
|
|
|
if reaper.IsMediaItemSelected(thisItem) then |
|
|
|
reaper.SetMediaItemInfo_Value(thisItem, "I_GROUPID", groupID) |
|
|
|
end |
|
|
|
k = k+1 |
|
|
|
thisItem = reaper.GetTrackMediaItem(thisTrack, k) |
|
|
|
end |
|
|
|
k = 0 |
|
|
|
j = j+1 |
|
|
|
thisTrack = reaper.GetTrack(0, j) |
|
|
|
groupID = maxProjectGroupID() + 1 |
|
|
|
end |
|
|
|
|
|
|
|
-- restore selected tracks after work |
|
|
|
reaper.Main_OnCommand(40297, 0) -- Unselect all tracks |
|
|
|
for _, track in ipairs(init_sel_tracks) do |
|
|
|
reaper.SetTrackSelected(track, true) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
function fillGapsBetweenItems() |
|
|
|
if not sws_present then return end |
|
|
|
local init_sel_tracks = {} |
|
|
|
local init_sel_items = {} |
|
|
|
local timesel_start |
|
|
|
local timesel_end |
|
|
|
|
|
|
|
-- store selected tracks and items before work... |
|
|
|
for i = 0, reaper.CountSelectedTracks(0)-1 do |
|
|
|
init_sel_tracks[i+1] = reaper.GetSelectedTrack(0, i) |
|
|
|
end |
|
|
|
for i = 0, reaper.CountSelectedMediaItems(0)-1 do |
|
|
|
init_sel_items[i+1] = reaper.GetSelectedMediaItem(0, i) |
|
|
|
end |
|
|
|
-- store time selection |
|
|
|
timesel_start, timesel_end = reaper.GetSet_LoopTimeRange(false, true, 0, 1, false) |
|
|
|
|
|
|
|
-- select track with selected items |
|
|
|
reaper.Main_OnCommand(40297, 0) -- Unselect all tracks |
|
|
|
local selected_items_count = reaper.CountSelectedMediaItems(0) |
|
|
|
for i = 0, selected_items_count - 1 do |
|
|
|
local item = reaper.GetSelectedMediaItem(0, i) |
|
|
|
local track = reaper.GetMediaItem_Track(item) |
|
|
|
reaper.SetTrackSelected(track, true) |
|
|
|
end |
|
|
|
-- Set time selection to selected items and extend it a little to the right and left, so it includes adjacent items |
|
|
|
reaper.Main_OnCommand( 40290, 0 ) -- set time selection to selected items |
|
|
|
reaper.Main_OnCommand( 40320, 0 ) -- nudge left edge of time selection left |
|
|
|
reaper.Main_OnCommand( 40323, 0 ) -- nudge right edge of time selection right |
|
|
|
-- Select adjacent items and fill gaps (and crossfade) |
|
|
|
reaper.Main_OnCommand( 40718, 0 ) -- select items on selected tracks and in time selection |
|
|
|
reaper.Main_OnCommand( reaper.NamedCommandLookup('_SWS_AWFILLGAPSQUICKXFADE'), 0 ) -- fill gaps between selected items and crossfade |
|
|
|
|
|
|
|
-- restore selected tracks and items after work |
|
|
|
reaper.Main_OnCommand(40297, 0) -- Unselect all tracks |
|
|
|
for _, track in ipairs(init_sel_tracks) do |
|
|
|
reaper.SetTrackSelected(track, true) |
|
|
|
end |
|
|
|
reaper.Main_OnCommand(40289, 0) -- Unselect all items |
|
|
|
for _, item in ipairs(init_sel_items) do |
|
|
|
reaper.SetMediaItemSelected(item, true) |
|
|
|
end |
|
|
|
reaper.GetSet_LoopTimeRange(true, true, timesel_start, timesel_end, false) |
|
|
|
end |
|
|
|
|
|
|
|
-- Increase the takenumber and write to tracknames |
|
|
|
function increaseTake() |
|
|
|
local i_track = 0 |
|
|
|
local track = reaper.GetTrack(0, i_track) |
|
|
|
local name = 'empty' |
|
|
|
local take = 1 |
|
|
|
local retval |
|
|
|
local val |
|
|
|
|
|
|
|
-- load takenumber from rpp |
|
|
|
retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'nexttake') |
|
|
|
if retval > 0 then take = tonumber(val) + 1 end -- variable exists? if not keep take=1 |
|
|
|
takestring = '_T' .. string.format('%03d', take) -- format string to append to tracks, e.g. "_T042" |
|
|
|
|
|
|
|
-- run through all tracks and append takenumber |
|
|
|
while(track) |
|
|
|
do |
|
|
|
name = select( 2, reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, false) ) |
|
|
|
-- check if a takenumber already exists, even if without leading zeros |
|
|
|
if name:sub(-5,-4) == '_T' then |
|
|
|
name = name:sub(1,-6) |
|
|
|
elseif name:sub(-4,-3) == '_T' then |
|
|
|
name = name:sub(1,-5) |
|
|
|
elseif name:sub(-3,-2) == '_T' then |
|
|
|
name = name:sub(1,-4) |
|
|
|
elseif name:sub(-2,-1) == '_T' then |
|
|
|
name = name:sub(1,-3) |
|
|
|
end |
|
|
|
-- set new trackname and get next track |
|
|
|
reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name .. takestring, true) |
|
|
|
i_track = i_track + 1 |
|
|
|
track = reaper.GetTrack(0, i_track) |
|
|
|
end |
|
|
|
-- write new takenumber to rpp |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', take) |
|
|
|
end |
|
|
|
|
|
|
|
-- decreases takenumber and write to tracknames |
|
|
|
function decreaseTake() |
|
|
|
local i_track = 0 |
|
|
|
local track = reaper.GetTrack(0, i_track) |
|
|
|
local name = 'empty' |
|
|
|
local take = 1 |
|
|
|
local retval |
|
|
|
local val |
|
|
|
|
|
|
|
-- load takenumber from rpp |
|
|
|
retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'nexttake') |
|
|
|
if retval > 0 then take = tonumber(val) - 1 end -- variable exists? if not keep take=1 |
|
|
|
takestring = '_T' .. string.format('%03d', take) -- format string to append to tracks, e.g. "_T042" |
|
|
|
|
|
|
|
-- run through all tracks and append takenumber |
|
|
|
while(track) |
|
|
|
do |
|
|
|
name = select( 2, reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, false) ) |
|
|
|
-- check if a takenumber already exists, even without leading zeros |
|
|
|
if name:sub(-5,-4) == '_T' then |
|
|
|
name = name:sub(1,-6) |
|
|
|
elseif name:sub(-4,-3) == '_T' then |
|
|
|
name = name:sub(1,-5) |
|
|
|
elseif name:sub(-3,-2) == '_T' then |
|
|
|
name = name:sub(1,-4) |
|
|
|
elseif name:sub(-2,-1) == '_T' then |
|
|
|
name = name:sub(1,-3) |
|
|
|
end |
|
|
|
-- set new trackname and get next track |
|
|
|
reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name .. takestring, true) |
|
|
|
i_track = i_track + 1 |
|
|
|
track = reaper.GetTrack(0, i_track) |
|
|
|
end |
|
|
|
-- write new takenumber to rpp |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', take) |
|
|
|
end |
|
|
|
|
|
|
|
-- Initialisation for takenumber and tracknames |
|
|
|
function initTracknames() |
|
|
|
local i_track = 0 |
|
|
|
local track = reaper.GetTrack(0, i_track) |
|
|
|
local name = 'empty' |
|
|
|
local take = 1 |
|
|
|
local retval |
|
|
|
local val |
|
|
|
|
|
|
|
-- try to get takenumber from rpp. If not present, set to "1" |
|
|
|
retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'nexttake') |
|
|
|
if retval > 0 then |
|
|
|
take = tonumber(val) |
|
|
|
else |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', take) |
|
|
|
end |
|
|
|
takestring = '_T' .. string.format('%03d', take) -- format string to append to tracks, e.g. "_T042" |
|
|
|
|
|
|
|
-- run through all tracks and append takenumber |
|
|
|
while(track) |
|
|
|
do |
|
|
|
name = select( 2, reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, false) ) |
|
|
|
-- check if a takenumber already exists, even without leading zeros |
|
|
|
if name:sub(-5,-4) == '_T' then |
|
|
|
name = name:sub(1,-6) |
|
|
|
elseif name:sub(-4,-3) == '_T' then |
|
|
|
name = name:sub(1,-5) |
|
|
|
elseif name:sub(-3,-2) == '_T' then |
|
|
|
name = name:sub(1,-4) |
|
|
|
elseif name:sub(-2,-1) == '_T' then |
|
|
|
name = name:sub(1,-3) |
|
|
|
end |
|
|
|
-- set new trackname and get next track |
|
|
|
reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name .. takestring, true) |
|
|
|
i_track = i_track + 1 |
|
|
|
track = reaper.GetTrack(0, i_track) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
-- Removes Takenumber from tracknames |
|
|
|
function cleanTracknames() |
|
|
|
local i_track = 0 |
|
|
|
local track = reaper.GetTrack(0, i_track) |
|
|
|
local name = 'empty' |
|
|
|
|
|
|
|
-- run through all tracks and remove takenumber |
|
|
|
while(track) |
|
|
|
do |
|
|
|
name = select( 2, reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, false) ) |
|
|
|
-- check if a takenumber exists, even without leading zeros or without numbers |
|
|
|
if name:sub(-5,-4) == '_T' then |
|
|
|
name = name:sub(1,-6) |
|
|
|
elseif name:sub(-4,-3) == '_T' then |
|
|
|
name = name:sub(1,-5) |
|
|
|
elseif name:sub(-3,-2) == '_T' then |
|
|
|
name = name:sub(1,-4) |
|
|
|
elseif name:sub(-2,-1) == '_T' then |
|
|
|
name = name:sub(1,-3) |
|
|
|
end |
|
|
|
-- set new trackname and get next track |
|
|
|
reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, true) |
|
|
|
i_track = i_track + 1 |
|
|
|
track = reaper.GetTrack(0, i_track) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
-- Read takenumber from name of first track and store it to rpp |
|
|
|
function getTakeFromTrackOne() |
|
|
|
local track = reaper.GetTrack(0, 0) |
|
|
|
local name = 'empty' |
|
|
|
|
|
|
|
name = select( 2, reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, false) ) |
|
|
|
-- reads takenumber, even without leading zeros |
|
|
|
if name:sub(-5,-4) == '_T' then |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', tonumber(name:sub(-3,-1))) |
|
|
|
elseif name:sub(-4,-3) == '_T' then |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', tonumber(name:sub(-2,-1))) |
|
|
|
elseif name:sub(-3,-2) == '_T' then |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', tonumber(name:sub(-1,-1))) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
-- Store state to project variables |
|
|
|
function storeExtState() |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'dockState', gfx.dock(-1)) |
|
|
|
|
|
|
|
if groupItemsAfterRecord then |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'groupItems', '1') |
|
|
|
else |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'groupItems', '0') |
|
|
|
end |
|
|
|
|
|
|
|
if groupItemsHAfterRecord then |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'groupItemsH', '1') |
|
|
|
else |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'groupItemsH', '0') |
|
|
|
end |
|
|
|
|
|
|
|
if lockToActiveTakeAfterRecord then |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'lockToActiveTake', '1') |
|
|
|
else |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'lockToActiveTake', '0') |
|
|
|
end |
|
|
|
|
|
|
|
if fillGapsAfterRecord then |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'fillGaps', '1') |
|
|
|
else |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'fillGaps', '0') |
|
|
|
end |
|
|
|
|
|
|
|
if writeTakeNamesAfterRecord then |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'writeTakenames', '1') |
|
|
|
else |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'writeTakenames', '0') |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
--------------------------- |
|
|
|
-- functions for graphics... |
|
|
|
--------------------------- |
|
|
|
|
|
|
|
-- Returns current script's path |
|
|
|
function get_script_path() |
|
|
|
local info = debug.getinfo(1,'S'); |
|
|
|
local script_path = info.source:match[[^@?(.*[\/])[^\/]-$]] |
|
|
|
return script_path |
|
|
|
end |
|
|
|
|
|
|
|
-- gui init stuff, including rightclick-menu |
|
|
|
function gui_init() |
|
|
|
-- Get "script path" |
|
|
|
script_path = get_script_path() |
|
|
|
--msg(script_path) |
|
|
|
|
|
|
|
-- Modify "package.path" |
|
|
|
package.path = package.path .. ";" .. script_path .. "?.lua" |
|
|
|
--msg(package.path) |
|
|
|
|
|
|
|
-- Import files ("classes", functions etc.)-- |
|
|
|
require "class" -- import "base class" |
|
|
|
mouse = require "mouse" |
|
|
|
Menu = require "menu class" |
|
|
|
|
|
|
|
-- Create "right click" menu -- |
|
|
|
-- Create a "Menu" instance |
|
|
|
rc_menu = Menu("rc_menu") |
|
|
|
|
|
|
|
-- Add menu items to "rc_menu" |
|
|
|
-- ">" at the start spawns a submenu, | at the end creates a spacer |
|
|
|
rc_menu:add_item({label = "Remove takenumber from tracknames"}) |
|
|
|
rc_menu:add_item({label = "Write takenumber to tracknames|"}) |
|
|
|
rc_menu:add_item({label = "Reset takenumber to one"}) |
|
|
|
rc_menu:add_item({label = "Get takenumber from first track"}) |
|
|
|
rc_menu:add_item({label = "Increase takenumber by one"}) |
|
|
|
rc_menu:add_item({label = "Decrease takenumber by one|"}) |
|
|
|
rc_menu:add_item({label = "Group all items of same take", |
|
|
|
toggleable = true, |
|
|
|
selected = groupItemsAfterRecord}) |
|
|
|
rc_menu:add_item({label = "Group items of same take horizontally|", |
|
|
|
toggleable = true, |
|
|
|
selected = groupItemsAfterRecordH}) |
|
|
|
rc_menu:add_item({label = "Crossfade after record (needs SWS)", |
|
|
|
toggleable = true, |
|
|
|
active = sws_present, |
|
|
|
selected = fillGapsAfterRecord and sws_present}) |
|
|
|
rc_menu:add_item({label = "Lock to active take after record", |
|
|
|
toggleable = true, |
|
|
|
selected = lockToActiveTakeAfterRecord}) |
|
|
|
rc_menu:add_item({label = "Write clean Takenames after record|", |
|
|
|
toggleable = true, |
|
|
|
selected = writeTakeNamesAfterRecord}) |
|
|
|
rc_menu:add_item({label = "Quit"}) |
|
|
|
|
|
|
|
-- Let's add a command to all created items: |
|
|
|
rc_menu.items[1].command = function() cleanTracknames() end |
|
|
|
rc_menu.items[2].command = function() initTracknames() end |
|
|
|
rc_menu.items[3].command = function() |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', '1') |
|
|
|
initTracknames() |
|
|
|
end |
|
|
|
rc_menu.items[4].command = function() |
|
|
|
getTakeFromTrackOne() |
|
|
|
initTracknames() |
|
|
|
end |
|
|
|
rc_menu.items[5].command = function() increaseTake() end |
|
|
|
rc_menu.items[6].command = function() decreaseTake() end |
|
|
|
rc_menu.items[7].command = function() |
|
|
|
if rc_menu.items[7].selected then |
|
|
|
groupItemsAfterRecord = true |
|
|
|
groupItemsHAfterRecord = false |
|
|
|
rc_menu.items[8].selected = false |
|
|
|
else |
|
|
|
groupItemsAfterRecord = false |
|
|
|
end |
|
|
|
storeExtState() |
|
|
|
end |
|
|
|
rc_menu.items[8].command = function() |
|
|
|
if rc_menu.items[8].selected then |
|
|
|
groupItemsHAfterRecord = true |
|
|
|
groupItemsAfterRecord = false |
|
|
|
rc_menu.items[7].selected = false |
|
|
|
else |
|
|
|
groupItemsHAfterRecord = false |
|
|
|
end |
|
|
|
storeExtState() |
|
|
|
end |
|
|
|
rc_menu.items[9].command = function() |
|
|
|
if rc_menu.items[9].selected then |
|
|
|
fillGapsAfterRecord = true |
|
|
|
else |
|
|
|
fillGapsAfterRecord = false |
|
|
|
end |
|
|
|
storeExtState() |
|
|
|
end |
|
|
|
rc_menu.items[10].command = function() |
|
|
|
if rc_menu.items[10].selected then |
|
|
|
lockToActiveTakeAfterRecord = true |
|
|
|
else |
|
|
|
lockToActiveTakeAfterRecord = false |
|
|
|
end |
|
|
|
storeExtState() |
|
|
|
end |
|
|
|
rc_menu.items[11].command = function() |
|
|
|
if rc_menu.items[11].selected then |
|
|
|
writeTakeNamesAfterRecord = true |
|
|
|
else |
|
|
|
writeTakeNamesAfterRecord = false |
|
|
|
end |
|
|
|
storeExtState() |
|
|
|
end |
|
|
|
rc_menu.items[12].command = function() quit = true end |
|
|
|
end |
|
|
|
|
|
|
|
-- Draw GUI -- |
|
|
|
function drawGui() |
|
|
|
local take = 1 |
|
|
|
local retval |
|
|
|
local val |
|
|
|
local thisnext = 'Next' |
|
|
|
|
|
|
|
-- try to get takenumber from rpp. If not present, set to "1" |
|
|
|
retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'nexttake') |
|
|
|
if retval > 0 then |
|
|
|
take = tonumber(val) |
|
|
|
else |
|
|
|
reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', take) |
|
|
|
end |
|
|
|
|
|
|
|
-- Are we in "record" mode? |
|
|
|
if reaper.GetAllProjectPlayStates(0) == 5 then |
|
|
|
increaseTodo = true -- after rec-stop we have to increase the takenumber |
|
|
|
thisnext = 'This' -- during record the label says "This Take: 42" |
|
|
|
gfx.clear = 255 + 20*256 + 20*65536 -- background is red |
|
|
|
else -- no, we're not |
|
|
|
if increaseTodo then -- we just stopped from record |
|
|
|
if writeTakeNamesAfterRecord then --so we do all the magic, here eventually we write nice takenames |
|
|
|
writeTakeNames() |
|
|
|
end |
|
|
|
increaseTake() -- and have to increase the takenumber |
|
|
|
if groupItemsAfterRecord then -- and do post-record-stuff |
|
|
|
groupItems() |
|
|
|
elseif groupItemsHAfterRecord then |
|
|
|
groupItemsH() |
|
|
|
end |
|
|
|
if lockToActiveTakeAfterRecord then |
|
|
|
setLockToActiveTake() |
|
|
|
end |
|
|
|
if fillGapsAfterRecord then |
|
|
|
fillGapsBetweenItems() |
|
|
|
end |
|
|
|
thisnext = 'Next' -- during "not-record" the label says "Next Take: 43" |
|
|
|
increaseTodo = false -- and we're done and reset this flag |
|
|
|
end |
|
|
|
gfx.clear = 3355443 -- background is dark grey |
|
|
|
end |
|
|
|
|
|
|
|
-- If window is docked, use different scaling |
|
|
|
if gfx.dock(-1) > 0 then |
|
|
|
-- landscape format |
|
|
|
if gfx.w > gfx.h then |
|
|
|
gfx.x = 20 |
|
|
|
gfx.y = ( gfx.h-select(2, gfx.measurestr("Take")) ) / 2 |
|
|
|
gui.settings.font_size = gfx.h / 2 |
|
|
|
gfx.setfont(1,"Arial", gui.settings.font_size) |
|
|
|
-- check if string fits into window, if not decrease fontsize a little, check again and loop |
|
|
|
while gfx.measurestr(thisnext .. " Take: " .. take) > (gfx.w - 2*gfx.x) do |
|
|
|
gui.settings.font_size = gui.settings.font_size / 1.1 |
|
|
|
gfx.setfont(1,"Arial", gui.settings.font_size) |
|
|
|
end |
|
|
|
gfx.printf(thisnext .. " Take: " .. take) |
|
|
|
-- portrait format |
|
|
|
else |
|
|
|
gfx.x = gfx.w/15 |
|
|
|
gfx.y = ( gfx.h-select(2, gfx.measurestr("Next\nTake\nT123")) ) / 2 |
|
|
|
gui.settings.font_size = gfx.w / 3 |
|
|
|
gfx.setfont(1,"Arial", gui.settings.font_size) |
|
|
|
gfx.printf(thisnext .. "\nTake:\n" .. take) |
|
|
|
end |
|
|
|
else -- window is not docked |
|
|
|
-- landscape format |
|
|
|
if gfx.w > gfx.h then |
|
|
|
gfx.x = gfx.w/20 |
|
|
|
gfx.y = ( gfx.h-select(2, gfx.measurestr("Take")) ) / 2 |
|
|
|
gui.settings.font_size = gfx.w / 6 |
|
|
|
gfx.setfont(1,"Arial", gui.settings.font_size) |
|
|
|
-- check if string fits into window, if not decrease fontsize a little, check again and loop |
|
|
|
while gfx.measurestr(thisnext .. " Take: " .. take) > (gfx.w - 2*gfx.x) do |
|
|
|
gui.settings.font_size = gui.settings.font_size / 1.1 |
|
|
|
gfx.setfont(1,"Arial", gui.settings.font_size) |
|
|
|
end |
|
|
|
gfx.printf(thisnext .. " Take: " .. take) |
|
|
|
-- portrait format |
|
|
|
else |
|
|
|
gfx.x = gfx.w/20 |
|
|
|
gfx.y = ( gfx.h-select(2, gfx.measurestr("Next\nTake\nT123")) ) / 2 |
|
|
|
gui.settings.font_size = gfx.w / 3 |
|
|
|
gfx.setfont(1,"Arial", gui.settings.font_size) |
|
|
|
gfx.printf(thisnext .. "\nTake:\n" .. take) |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
-- Called on script termination. Store stuff... |
|
|
|
function onExit() |
|
|
|
storeExtState() |
|
|
|
end |
|
|
|
|
|
|
|
-- Main init function |
|
|
|
function init() |
|
|
|
-- check for SWS extensions |
|
|
|
if reaper.NamedCommandLookup('_SWS_ABOUT') > 0 then sws_present = true end |
|
|
|
-- load settings from rpp |
|
|
|
local retval |
|
|
|
local val |
|
|
|
retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'groupItems') |
|
|
|
if retval > 0 then |
|
|
|
if tonumber(val) > 0 then |
|
|
|
groupItemsAfterRecord = true |
|
|
|
else |
|
|
|
groupItemsAfterRecord = false |
|
|
|
end |
|
|
|
end |
|
|
|
retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'groupItemsH') |
|
|
|
if retval > 0 then |
|
|
|
if tonumber(val) > 0 then |
|
|
|
groupItemsAfterRecordH = true |
|
|
|
else |
|
|
|
groupItemsAfterRecordH = false |
|
|
|
end |
|
|
|
end |
|
|
|
retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'lockToActiveTake') |
|
|
|
if retval > 0 then |
|
|
|
if tonumber(val) > 0 then |
|
|
|
lockToActiveTakeAfterRecord = true |
|
|
|
else |
|
|
|
lockToActiveTakeAfterRecord = false |
|
|
|
end |
|
|
|
end |
|
|
|
retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'fillGaps') |
|
|
|
if retval > 0 then |
|
|
|
if tonumber(val) > 0 then |
|
|
|
fillGapsAfterRecord = true |
|
|
|
else |
|
|
|
fillGapsAfterRecord = false |
|
|
|
end |
|
|
|
end |
|
|
|
retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'writeTakenames') |
|
|
|
if retval > 0 then |
|
|
|
if tonumber(val) > 0 then |
|
|
|
writeTakeNamesAfterRecord = true |
|
|
|
else |
|
|
|
writeTakeNamesAfterRecord = false |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
-- init stuff... |
|
|
|
gui_init() |
|
|
|
initTracknames() |
|
|
|
|
|
|
|
-- Add stuff to "gui" table |
|
|
|
gui.settings = {} -- Add "settings" table to "gui" table |
|
|
|
gui.settings.font_size = 50 -- font size |
|
|
|
gui.settings.docker_id = 0 -- try 0, 1, 257, 513, 1027 etc. |
|
|
|
|
|
|
|
-- Initialize gfx window -- |
|
|
|
gfx.init("Rec Take", 350, 100, gui.settings.docker_id) |
|
|
|
gfx.setfont(1,"Arial", gui.settings.font_size) |
|
|
|
gfx.clear = 3355443 -- background is dark grey |
|
|
|
|
|
|
|
-- Restore docked state |
|
|
|
retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'dockState') |
|
|
|
if retval > 0 then |
|
|
|
gfx.dock(val) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
-- Main loop -- |
|
|
|
function mainloop() |
|
|
|
-- mouseclicks? |
|
|
|
local RMB_state = mouse.cap(mouse.RB) |
|
|
|
local mx = gfx.mouse_x |
|
|
|
local my = gfx.mouse_y |
|
|
|
|
|
|
|
if not mouse.last_RMB_state and gfx.mouse_cap&2 == 2 then |
|
|
|
-- right click pressed down -> show "right click menu" at mouse cursor |
|
|
|
rc_menu:show(mx, my) |
|
|
|
end |
|
|
|
|
|
|
|
mouse.last_RMB_state = RMB_state -- store current right mouse button state |
|
|
|
|
|
|
|
drawGui() |
|
|
|
gfx.update() |
|
|
|
if gfx.getchar() >= 0 and not quit then reaper.defer(mainloop) end |
|
|
|
end |
|
|
|
|
|
|
|
-- START HERE... |
|
|
|
reaper.atexit(onExit) |
|
|
|
init() |
|
|
|
mainloop() |