Added takenumber window from private repository
This commit is contained in:
parent
c5524f75de
commit
60ce4c2249
674
TakenumberWindow/Takenumber_Window.lua
Normal file
674
TakenumberWindow/Takenumber_Window.lua
Normal file
@ -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()
|
48
TakenumberWindow/class.lua
Normal file
48
TakenumberWindow/class.lua
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
------------- "class.lua" is copied from http://lua-users.org/wiki/SimpleLuaClasses -----------
|
||||||
|
|
||||||
|
-- class.lua
|
||||||
|
-- Compatible with Lua 5.1 (not 5.0).
|
||||||
|
function class(base, init)
|
||||||
|
local c = {} -- a new class instance
|
||||||
|
if not init and type(base) == 'function' then
|
||||||
|
init = base
|
||||||
|
base = nil
|
||||||
|
elseif type(base) == 'table' then
|
||||||
|
-- our new class is a shallow copy of the base class!
|
||||||
|
for i,v in pairs(base) do
|
||||||
|
c[i] = v
|
||||||
|
end
|
||||||
|
c._base = base
|
||||||
|
end
|
||||||
|
-- the class will be the metatable for all its objects,
|
||||||
|
-- and they will look up their methods in it.
|
||||||
|
c.__index = c
|
||||||
|
|
||||||
|
-- expose a constructor which can be called by <classname>(<args>)
|
||||||
|
local mt = {}
|
||||||
|
mt.__call = function(class_tbl, ...)
|
||||||
|
local obj = {}
|
||||||
|
setmetatable(obj,c)
|
||||||
|
if init then
|
||||||
|
init(obj,...)
|
||||||
|
else
|
||||||
|
-- make sure that any stuff from the base class is initialized!
|
||||||
|
if base and base.init then
|
||||||
|
base.init(obj, ...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return obj
|
||||||
|
end
|
||||||
|
c.init = init
|
||||||
|
c.is_a = function(self, klass)
|
||||||
|
local m = getmetatable(self)
|
||||||
|
while m do
|
||||||
|
if m == klass then return true end
|
||||||
|
m = m._base
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
setmetatable(c, mt)
|
||||||
|
return c
|
||||||
|
end
|
||||||
|
----------------------------------------------------------------------------------------
|
190
TakenumberWindow/menu class.lua
Normal file
190
TakenumberWindow/menu class.lua
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
----------------
|
||||||
|
-- Menu class --
|
||||||
|
----------------
|
||||||
|
|
||||||
|
-- To create a new menu instance, call this function like this:
|
||||||
|
-- menu_name = Menu("menu_name")
|
||||||
|
local Menu =
|
||||||
|
class(
|
||||||
|
function(menu, id)
|
||||||
|
menu.id = id
|
||||||
|
menu.items = {} -- Menu items are collected to this table
|
||||||
|
menu.items_str = ""
|
||||||
|
menu.curr_item_pos = 1
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
------------------
|
||||||
|
-- Menu methods --
|
||||||
|
------------------
|
||||||
|
|
||||||
|
--[[
|
||||||
|
-- True if menu item label starts with "prefix"
|
||||||
|
function Menu:label_starts_with(label, prefix)
|
||||||
|
return string.sub(label, 1, string.len(prefix)) == prefix
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
|
||||||
|
-- Returns "menu item table" (or false if "id" not found)
|
||||||
|
function Menu:get_item_from_id(id)
|
||||||
|
for i=1, #self.items do
|
||||||
|
if self.items[i].id == id then
|
||||||
|
return self.items[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Updates "menu item type" variables (_has_submenu, _last_item_in_submenu etc.)
|
||||||
|
function Menu:update_item(item_table)
|
||||||
|
local t = item_table
|
||||||
|
t._has_submenu = false
|
||||||
|
t._last_item_in_submenu = false
|
||||||
|
t.id = self.curr_item_pos
|
||||||
|
|
||||||
|
if string.sub(t.label, 1, 1) == ">" or
|
||||||
|
string.sub(t.label, 1, 2) == "<>" or
|
||||||
|
string.sub(t.label, 1, 2) == "><" then
|
||||||
|
t._has_submenu = true
|
||||||
|
t.id = -1
|
||||||
|
self.curr_item_pos = self.curr_item_pos - 1
|
||||||
|
--end
|
||||||
|
elseif string.sub(t.label, 1, 1) == "<" then
|
||||||
|
t._has_submenu = false
|
||||||
|
t._last_item_in_submenu = true
|
||||||
|
end
|
||||||
|
--t.id = self.curr_item_pos
|
||||||
|
self.curr_item_pos = self.curr_item_pos + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Returns the created table and table index in "menu_obj.items"
|
||||||
|
function Menu:add_item(...)
|
||||||
|
local t = ... or {}
|
||||||
|
self.items[#self.items+1] = t -- add new menu item at the end of menu
|
||||||
|
|
||||||
|
-- Parse arguments
|
||||||
|
for i,v in pairs(t) do
|
||||||
|
--msg(i .. " = " .. tostring(v))
|
||||||
|
if i == "label" then
|
||||||
|
t.label = v
|
||||||
|
elseif i == "selected" then
|
||||||
|
t.selected = v
|
||||||
|
elseif i == "active" then
|
||||||
|
t.active = v
|
||||||
|
elseif i == "toggleable" then
|
||||||
|
t.toggleable = v
|
||||||
|
elseif i == "command" then
|
||||||
|
t.command = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Default values for menu items
|
||||||
|
-- (Edit these)
|
||||||
|
if t.label == nil or t.label == "" then
|
||||||
|
t.label = tostring(#self.items) -- if label is nil or "" -> label is set to "table index in menu_obj.items"
|
||||||
|
end
|
||||||
|
|
||||||
|
if t.selected == nil then
|
||||||
|
t.selected = false -- edit
|
||||||
|
end
|
||||||
|
|
||||||
|
if t.active == nil then
|
||||||
|
t.active = true -- edit
|
||||||
|
end
|
||||||
|
|
||||||
|
if t.toggleable == nil then
|
||||||
|
t.toggleable = false -- edit
|
||||||
|
end
|
||||||
|
|
||||||
|
return t, #self.items
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Get menu item table at index
|
||||||
|
function Menu:get_item(index)
|
||||||
|
if self.items[index] == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return self.items[index]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Show menu at mx, my
|
||||||
|
function Menu:show(mx, my)
|
||||||
|
gfx.x = mx
|
||||||
|
gfx.y = my
|
||||||
|
|
||||||
|
-- Check which items has a function to call when a menu is about to be shown
|
||||||
|
for i=1, #self.items do
|
||||||
|
if self.items[i].on_menu_show ~= nil then
|
||||||
|
self.items[i].on_menu_show()
|
||||||
|
end
|
||||||
|
-- Update item
|
||||||
|
self:update_item(self.items[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Convert menu item tables to string
|
||||||
|
self.items_str = self:table_to_string() or ""
|
||||||
|
self.val = gfx.showmenu(self.items_str)
|
||||||
|
if self.val > 0 then
|
||||||
|
self:update(self.val)
|
||||||
|
end
|
||||||
|
self.curr_item_pos = 1 -- set "menu item position counter" back to the initial value
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function Menu:update(menu_item_index)
|
||||||
|
-- check which "menu item id" matches with "menu_item_index"
|
||||||
|
for i=1, #self.items do
|
||||||
|
if self.items[i].id == menu_item_index then
|
||||||
|
menu_item_index = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local i = menu_item_index
|
||||||
|
-- if menu item is "toggleable" then toggle "selected" state
|
||||||
|
if self.items[i].toggleable then
|
||||||
|
self.items[i].selected = not self.items[i].selected
|
||||||
|
end
|
||||||
|
-- if menu item has a "command" (function), then call that function
|
||||||
|
if self.items[i].command ~= nil then
|
||||||
|
self.items[i].command()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Convert "Menu_obj.items" to string
|
||||||
|
function Menu:table_to_string()
|
||||||
|
if self.items == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self.items_str = ""
|
||||||
|
|
||||||
|
for i=1, #self.items do
|
||||||
|
local temp_str = ""
|
||||||
|
local menu_item = self.items[i]
|
||||||
|
if menu_item.selected then
|
||||||
|
temp_str = "!"
|
||||||
|
end
|
||||||
|
|
||||||
|
if not menu_item.active then
|
||||||
|
temp_str = temp_str .. "#"
|
||||||
|
end
|
||||||
|
|
||||||
|
if menu_item.label ~= "" then
|
||||||
|
temp_str = temp_str .. menu_item.label .. "|"
|
||||||
|
end
|
||||||
|
|
||||||
|
self.items_str = self.items_str .. temp_str
|
||||||
|
end
|
||||||
|
|
||||||
|
return self.items_str
|
||||||
|
end
|
||||||
|
|
||||||
|
--END of Menu class----------------------------------------------------
|
||||||
|
|
||||||
|
return Menu
|
||||||
|
|
34
TakenumberWindow/mouse.lua
Normal file
34
TakenumberWindow/mouse.lua
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
-----------------
|
||||||
|
-- Mouse table --
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
local mouse = {
|
||||||
|
-- Constants
|
||||||
|
LB = 1,
|
||||||
|
RB = 2,
|
||||||
|
CTRL = 4,
|
||||||
|
SHIFT = 8,
|
||||||
|
ALT = 16,
|
||||||
|
|
||||||
|
-- "cap" function
|
||||||
|
cap = function (mask)
|
||||||
|
if mask == nil then
|
||||||
|
return gfx.mouse_cap end
|
||||||
|
return gfx.mouse_cap&mask == mask
|
||||||
|
end,
|
||||||
|
|
||||||
|
uptime = 0,
|
||||||
|
|
||||||
|
last_x = -1, last_y = -1,
|
||||||
|
|
||||||
|
dx = 0,
|
||||||
|
dy = 0,
|
||||||
|
|
||||||
|
ox_l = 0, oy_l = 0, -- left click positions
|
||||||
|
ox_r = 0, oy_r = 0, -- right click positions
|
||||||
|
capcnt = 0,
|
||||||
|
last_LMB_state = false,
|
||||||
|
last_RMB_state = false
|
||||||
|
}
|
||||||
|
|
||||||
|
return mouse
|
Loading…
x
Reference in New Issue
Block a user