Collection of custom reaper scripts
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

688 lines
25 KiB

  1. -- Reaper Script to add take management functions, like:
  2. -- - Take counter with unique number ("how often REC was pressed")
  3. -- - Write takenumber to name of recorded file (by changing tracknames)
  4. -- - Group recorded items after stop (all or just horizontally)
  5. -- - Lock to active take (in lanes) after record
  6. -- - Write clean takenames after record, for easy recognition. E.g. "T042 (Violin 1)"
  7. -- - Crossfade items after record (fill gaps resulting from overlapping takes) (needs SWS)
  8. -- Author: Ludwig Frühschütz
  9. -- Source: https://www.eleton-audio.de
  10. -- Git: https://files.eleton-audio.de/gitea/Ludwig/Reaper-Scripts.git
  11. -- License: GPL v3.0
  12. -- Requires: Reaper 5 or 6
  13. -- Requires: SWS Extensions for "Fill gaps" option (http://standingwaterstudios.com/)
  14. -- Basic gui stuff by forum user "spk77": https://forum.cockos.com/showthread.php?t=161557
  15. -- Some adjustable settings:
  16. -- Initial values if no settings stored in project
  17. local groupItemsAfterRecord = true
  18. local groupItemsHAfterRecord = false
  19. local fillGapsAfterRecord = true
  20. local lockToActiveTakeAfterRecord = true
  21. local writeTakeNamesAfterRecord = true
  22. -- Nothing to adjust here anymore...
  23. local script_path
  24. local mouse
  25. local Menu
  26. local gui = {} -- contains some settings for the GUI
  27. local increaseTodo = false -- used to detect transition form "REC" to "STOP" and then inc. takenumber
  28. local quit = false
  29. local sws_present = false
  30. -- Send a message to the console
  31. function msg(m)
  32. reaper.ShowConsoleMsg(tostring(m) .. "\n")
  33. end
  34. -- Write Takenumber and Trackname to selected items active takenames
  35. function writeTakeNames()
  36. local k = 0
  37. local thisItem = reaper.GetSelectedMediaItem(0, k)
  38. local takestring
  39. local name = ' '
  40. -- try to get takenumber from rpp. If not present, leave at "-1"
  41. retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'nexttake')
  42. if retval > 0 then
  43. takestring = 'T' .. string.format('%03d', tonumber(val)) -- format string to prepend to takename, e.g. "T042"
  44. else
  45. takestring = 'T???'
  46. end
  47. -- run through all selected items
  48. while (thisItem)
  49. do
  50. local theTake = reaper.GetActiveTake(thisItem)
  51. local track = reaper.GetMediaItem_Track(thisItem)
  52. -- get trackname without takenumber
  53. name = select( 2, reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, false) )
  54. if name:sub(-5,-4) == '_T' then
  55. name = name:sub(1,-6)
  56. elseif name:sub(-4,-3) == '_T' then
  57. name = name:sub(1,-5)
  58. elseif name:sub(-3,-2) == '_T' then
  59. name = name:sub(1,-4)
  60. elseif name:sub(-2,-1) == '_T' then
  61. name = name:sub(1,-3)
  62. end
  63. reaper.GetSetMediaItemTakeInfo_String(theTake, 'P_NAME', takestring .. ' (' .. name .. ')', true)
  64. k = k+1
  65. thisItem = reaper.GetSelectedMediaItem(0, k)
  66. end
  67. end
  68. -- Lock to active take in lanes (to not accidentally select one by clicking)
  69. function setLockToActiveTake()
  70. reaper.Main_OnCommand(41340, 0) -- cant get momentary state, so simply set it every time...
  71. end
  72. -- Get the highest group-ID in use
  73. function maxProjectGroupID()
  74. local floor = math.floor
  75. local all_item_count = reaper.CountMediaItems(0)
  76. local MaxGroupID = 0
  77. for i = 0, all_item_count - 1 do
  78. local item = reaper.GetMediaItem(0, i)
  79. local item_group_id = floor(reaper.GetMediaItemInfo_Value(item, "I_GROUPID"))
  80. if item_group_id > MaxGroupID then
  81. MaxGroupID = item_group_id
  82. end
  83. end
  84. return MaxGroupID
  85. end
  86. -- Group all selected items
  87. function groupItems()
  88. local groupID = maxProjectGroupID() + 1
  89. local k = 0
  90. local thisItem = reaper.GetSelectedMediaItem(0, k)
  91. while (thisItem)
  92. do
  93. reaper.SetMediaItemInfo_Value(thisItem, "I_GROUPID", groupID)
  94. k = k+1
  95. thisItem = reaper.GetSelectedMediaItem(0, k)
  96. end
  97. end
  98. -- Group selected items horizontally
  99. function groupItemsH()
  100. local init_sel_tracks = {}
  101. local groupID = maxProjectGroupID() + 1
  102. local j = 0
  103. local k = 0
  104. -- store selected tracks before work...
  105. for i = 0, reaper.CountSelectedTracks(0)-1 do
  106. init_sel_tracks[i+1] = reaper.GetSelectedTrack(0, i)
  107. end
  108. local thisTrack = reaper.GetTrack(0, j)
  109. while (thisTrack) do
  110. local thisItem = reaper.GetTrackMediaItem(thisTrack, k)
  111. while (thisItem)
  112. do
  113. if reaper.IsMediaItemSelected(thisItem) then
  114. reaper.SetMediaItemInfo_Value(thisItem, "I_GROUPID", groupID)
  115. end
  116. k = k+1
  117. thisItem = reaper.GetTrackMediaItem(thisTrack, k)
  118. end
  119. k = 0
  120. j = j+1
  121. thisTrack = reaper.GetTrack(0, j)
  122. groupID = maxProjectGroupID() + 1
  123. end
  124. -- restore selected tracks after work
  125. reaper.Main_OnCommand(40297, 0) -- Unselect all tracks
  126. for _, track in ipairs(init_sel_tracks) do
  127. reaper.SetTrackSelected(track, true)
  128. end
  129. end
  130. function fillGapsBetweenItems()
  131. if not sws_present then return end
  132. local init_sel_tracks = {}
  133. local init_sel_items = {}
  134. local timesel_start
  135. local timesel_end
  136. -- store selected tracks and items before work...
  137. for i = 0, reaper.CountSelectedTracks(0)-1 do
  138. init_sel_tracks[i+1] = reaper.GetSelectedTrack(0, i)
  139. end
  140. for i = 0, reaper.CountSelectedMediaItems(0)-1 do
  141. init_sel_items[i+1] = reaper.GetSelectedMediaItem(0, i)
  142. end
  143. -- store time selection
  144. timesel_start, timesel_end = reaper.GetSet_LoopTimeRange(false, true, 0, 1, false)
  145. -- select track with selected items
  146. reaper.Main_OnCommand(40297, 0) -- Unselect all tracks
  147. local selected_items_count = reaper.CountSelectedMediaItems(0)
  148. for i = 0, selected_items_count - 1 do
  149. local item = reaper.GetSelectedMediaItem(0, i)
  150. local track = reaper.GetMediaItem_Track(item)
  151. reaper.SetTrackSelected(track, true)
  152. end
  153. -- Set time selection to selected items and extend it a little to the right and left, so it includes adjacent items
  154. reaper.Main_OnCommand( 40290, 0 ) -- set time selection to selected items
  155. reaper.Main_OnCommand( 40320, 0 ) -- nudge left edge of time selection left
  156. reaper.Main_OnCommand( 40323, 0 ) -- nudge right edge of time selection right
  157. -- Select adjacent items and fill gaps (and crossfade)
  158. reaper.Main_OnCommand( 40718, 0 ) -- select items on selected tracks and in time selection
  159. reaper.Main_OnCommand( reaper.NamedCommandLookup('_SWS_AWFILLGAPSQUICKXFADE'), 0 ) -- fill gaps between selected items and crossfade
  160. -- restore selected tracks and items after work
  161. reaper.Main_OnCommand(40297, 0) -- Unselect all tracks
  162. for _, track in ipairs(init_sel_tracks) do
  163. reaper.SetTrackSelected(track, true)
  164. end
  165. reaper.Main_OnCommand(40289, 0) -- Unselect all items
  166. for _, item in ipairs(init_sel_items) do
  167. reaper.SetMediaItemSelected(item, true)
  168. end
  169. reaper.GetSet_LoopTimeRange(true, true, timesel_start, timesel_end, false)
  170. end
  171. -- Increase the takenumber and write to tracknames
  172. function increaseTake()
  173. local i_track = 0
  174. local track = reaper.GetTrack(0, i_track)
  175. local name = 'empty'
  176. local take = 1
  177. local retval
  178. local val
  179. -- load takenumber from rpp
  180. retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'nexttake')
  181. if retval > 0 then take = tonumber(val) + 1 end -- variable exists? if not keep take=1
  182. takestring = '_T' .. string.format('%03d', take) -- format string to append to tracks, e.g. "_T042"
  183. -- run through all tracks and append takenumber
  184. while(track)
  185. do
  186. name = select( 2, reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, false) )
  187. -- check if a takenumber already exists, even if without leading zeros
  188. if name:sub(-5,-4) == '_T' then
  189. name = name:sub(1,-6)
  190. elseif name:sub(-4,-3) == '_T' then
  191. name = name:sub(1,-5)
  192. elseif name:sub(-3,-2) == '_T' then
  193. name = name:sub(1,-4)
  194. elseif name:sub(-2,-1) == '_T' then
  195. name = name:sub(1,-3)
  196. end
  197. -- set new trackname and get next track
  198. reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name .. takestring, true)
  199. i_track = i_track + 1
  200. track = reaper.GetTrack(0, i_track)
  201. end
  202. -- write new takenumber to rpp
  203. reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', take)
  204. end
  205. -- decreases takenumber and write to tracknames
  206. function decreaseTake()
  207. local i_track = 0
  208. local track = reaper.GetTrack(0, i_track)
  209. local name = 'empty'
  210. local take = 1
  211. local retval
  212. local val
  213. -- load takenumber from rpp
  214. retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'nexttake')
  215. if retval > 0 then take = tonumber(val) - 1 end -- variable exists? if not keep take=1
  216. takestring = '_T' .. string.format('%03d', take) -- format string to append to tracks, e.g. "_T042"
  217. -- run through all tracks and append takenumber
  218. while(track)
  219. do
  220. name = select( 2, reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, false) )
  221. -- check if a takenumber already exists, even without leading zeros
  222. if name:sub(-5,-4) == '_T' then
  223. name = name:sub(1,-6)
  224. elseif name:sub(-4,-3) == '_T' then
  225. name = name:sub(1,-5)
  226. elseif name:sub(-3,-2) == '_T' then
  227. name = name:sub(1,-4)
  228. elseif name:sub(-2,-1) == '_T' then
  229. name = name:sub(1,-3)
  230. end
  231. -- set new trackname and get next track
  232. reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name .. takestring, true)
  233. i_track = i_track + 1
  234. track = reaper.GetTrack(0, i_track)
  235. end
  236. -- write new takenumber to rpp
  237. reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', take)
  238. end
  239. -- Initialisation for takenumber and tracknames
  240. function initTracknames()
  241. local i_track = 0
  242. local track = reaper.GetTrack(0, i_track)
  243. local name = 'empty'
  244. local take = 1
  245. local retval
  246. local val
  247. -- try to get takenumber from rpp. If not present, set to "1"
  248. retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'nexttake')
  249. if retval > 0 then
  250. take = tonumber(val)
  251. else
  252. reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', take)
  253. end
  254. takestring = '_T' .. string.format('%03d', take) -- format string to append to tracks, e.g. "_T042"
  255. -- run through all tracks and append takenumber
  256. while(track)
  257. do
  258. name = select( 2, reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, false) )
  259. -- check if a takenumber already exists, even without leading zeros
  260. if name:sub(-5,-4) == '_T' then
  261. name = name:sub(1,-6)
  262. elseif name:sub(-4,-3) == '_T' then
  263. name = name:sub(1,-5)
  264. elseif name:sub(-3,-2) == '_T' then
  265. name = name:sub(1,-4)
  266. elseif name:sub(-2,-1) == '_T' then
  267. name = name:sub(1,-3)
  268. end
  269. -- set new trackname and get next track
  270. reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name .. takestring, true)
  271. i_track = i_track + 1
  272. track = reaper.GetTrack(0, i_track)
  273. end
  274. end
  275. -- Removes Takenumber from tracknames
  276. function cleanTracknames()
  277. local i_track = 0
  278. local track = reaper.GetTrack(0, i_track)
  279. local name = 'empty'
  280. -- run through all tracks and remove takenumber
  281. while(track)
  282. do
  283. name = select( 2, reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, false) )
  284. -- check if a takenumber exists, even without leading zeros or without numbers
  285. if name:sub(-5,-4) == '_T' then
  286. name = name:sub(1,-6)
  287. elseif name:sub(-4,-3) == '_T' then
  288. name = name:sub(1,-5)
  289. elseif name:sub(-3,-2) == '_T' then
  290. name = name:sub(1,-4)
  291. elseif name:sub(-2,-1) == '_T' then
  292. name = name:sub(1,-3)
  293. end
  294. -- set new trackname and get next track
  295. reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, true)
  296. i_track = i_track + 1
  297. track = reaper.GetTrack(0, i_track)
  298. end
  299. end
  300. -- Read takenumber from name of first track and store it to rpp
  301. function getTakeFromTrackOne()
  302. local track = reaper.GetTrack(0, 0)
  303. local name = 'empty'
  304. name = select( 2, reaper.GetSetMediaTrackInfo_String(track, 'P_NAME', name, false) )
  305. -- reads takenumber, even without leading zeros
  306. if name:sub(-5,-4) == '_T' then
  307. reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', tonumber(name:sub(-3,-1)))
  308. elseif name:sub(-4,-3) == '_T' then
  309. reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', tonumber(name:sub(-2,-1)))
  310. elseif name:sub(-3,-2) == '_T' then
  311. reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', tonumber(name:sub(-1,-1)))
  312. end
  313. end
  314. -- Store state to project variables
  315. function storeExtState()
  316. reaper.SetProjExtState(0, 'takenumber_window', 'dockState', gfx.dock(-1))
  317. if groupItemsAfterRecord then
  318. reaper.SetProjExtState(0, 'takenumber_window', 'groupItems', '1')
  319. else
  320. reaper.SetProjExtState(0, 'takenumber_window', 'groupItems', '0')
  321. end
  322. if groupItemsHAfterRecord then
  323. reaper.SetProjExtState(0, 'takenumber_window', 'groupItemsH', '1')
  324. else
  325. reaper.SetProjExtState(0, 'takenumber_window', 'groupItemsH', '0')
  326. end
  327. if lockToActiveTakeAfterRecord then
  328. reaper.SetProjExtState(0, 'takenumber_window', 'lockToActiveTake', '1')
  329. else
  330. reaper.SetProjExtState(0, 'takenumber_window', 'lockToActiveTake', '0')
  331. end
  332. if fillGapsAfterRecord then
  333. reaper.SetProjExtState(0, 'takenumber_window', 'fillGaps', '1')
  334. else
  335. reaper.SetProjExtState(0, 'takenumber_window', 'fillGaps', '0')
  336. end
  337. if writeTakeNamesAfterRecord then
  338. reaper.SetProjExtState(0, 'takenumber_window', 'writeTakenames', '1')
  339. else
  340. reaper.SetProjExtState(0, 'takenumber_window', 'writeTakenames', '0')
  341. end
  342. end
  343. ---------------------------
  344. -- functions for graphics...
  345. ---------------------------
  346. -- Returns current script's path
  347. function get_script_path()
  348. local info = debug.getinfo(1,'S');
  349. local script_path = info.source:match[[^@?(.*[\/])[^\/]-$]]
  350. return script_path
  351. end
  352. -- gui init stuff, including rightclick-menu
  353. function gui_init()
  354. -- Get "script path"
  355. script_path = get_script_path()
  356. --msg(script_path)
  357. -- Modify "package.path"
  358. package.path = package.path .. ";" .. script_path .. "?.lua"
  359. --msg(package.path)
  360. -- Import files ("classes", functions etc.)--
  361. require "class" -- import "base class"
  362. mouse = require "mouse"
  363. Menu = require "menu class"
  364. -- Create "right click" menu --
  365. -- Create a "Menu" instance
  366. rc_menu = Menu("rc_menu")
  367. -- Add menu items to "rc_menu"
  368. -- ">" at the start spawns a submenu, | at the end creates a spacer
  369. rc_menu:add_item({label = "Remove takenumber from tracknames"})
  370. rc_menu:add_item({label = "Write takenumber to tracknames|"})
  371. rc_menu:add_item({label = "Reset takenumber to one"})
  372. rc_menu:add_item({label = "Get takenumber from first track"})
  373. rc_menu:add_item({label = "Increase takenumber by one"})
  374. rc_menu:add_item({label = "Decrease takenumber by one|"})
  375. rc_menu:add_item({label = "Group all items of same take",
  376. toggleable = true,
  377. selected = groupItemsAfterRecord})
  378. rc_menu:add_item({label = "Group items of same take horizontally|",
  379. toggleable = true,
  380. selected = groupItemsAfterRecordH})
  381. rc_menu:add_item({label = "Crossfade after record (needs SWS)",
  382. toggleable = true,
  383. active = sws_present,
  384. selected = fillGapsAfterRecord and sws_present})
  385. rc_menu:add_item({label = "Lock to active take after record",
  386. toggleable = true,
  387. selected = lockToActiveTakeAfterRecord})
  388. rc_menu:add_item({label = "Write clean Takenames after record|",
  389. toggleable = true,
  390. selected = writeTakeNamesAfterRecord})
  391. rc_menu:add_item({label = "Quit"})
  392. -- Let's add a command to all created items:
  393. rc_menu.items[1].command = function() cleanTracknames() end
  394. rc_menu.items[2].command = function() initTracknames() end
  395. rc_menu.items[3].command = function()
  396. reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', '1')
  397. initTracknames()
  398. end
  399. rc_menu.items[4].command = function()
  400. getTakeFromTrackOne()
  401. initTracknames()
  402. end
  403. rc_menu.items[5].command = function() increaseTake() end
  404. rc_menu.items[6].command = function() decreaseTake() end
  405. rc_menu.items[7].command = function()
  406. if rc_menu.items[7].selected then
  407. groupItemsAfterRecord = true
  408. groupItemsHAfterRecord = false
  409. rc_menu.items[8].selected = false
  410. else
  411. groupItemsAfterRecord = false
  412. end
  413. storeExtState()
  414. end
  415. rc_menu.items[8].command = function()
  416. if rc_menu.items[8].selected then
  417. groupItemsHAfterRecord = true
  418. groupItemsAfterRecord = false
  419. rc_menu.items[7].selected = false
  420. else
  421. groupItemsHAfterRecord = false
  422. end
  423. storeExtState()
  424. end
  425. rc_menu.items[9].command = function()
  426. if rc_menu.items[9].selected then
  427. fillGapsAfterRecord = true
  428. else
  429. fillGapsAfterRecord = false
  430. end
  431. storeExtState()
  432. end
  433. rc_menu.items[10].command = function()
  434. if rc_menu.items[10].selected then
  435. lockToActiveTakeAfterRecord = true
  436. else
  437. lockToActiveTakeAfterRecord = false
  438. end
  439. storeExtState()
  440. end
  441. rc_menu.items[11].command = function()
  442. if rc_menu.items[11].selected then
  443. writeTakeNamesAfterRecord = true
  444. else
  445. writeTakeNamesAfterRecord = false
  446. end
  447. storeExtState()
  448. end
  449. rc_menu.items[12].command = function() quit = true end
  450. end
  451. -- Draw GUI --
  452. function drawGui()
  453. local take = 1
  454. local retval
  455. local val
  456. local thisnext = 'Next'
  457. -- try to get takenumber from rpp. If not present, set to "1"
  458. retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'nexttake')
  459. if retval > 0 then
  460. take = tonumber(val)
  461. else
  462. reaper.SetProjExtState(0, 'takenumber_window', 'nexttake', take)
  463. end
  464. -- Are we in "record" mode?
  465. if reaper.GetAllProjectPlayStates(0) == 5 then
  466. increaseTodo = true -- after rec-stop we have to increase the takenumber
  467. thisnext = 'This' -- during record the label says "This Take: 42"
  468. gfx.clear = 255 + 20*256 + 20*65536 -- background is red
  469. else -- no, we're not
  470. if increaseTodo then -- we just stopped from record
  471. if writeTakeNamesAfterRecord then --so we do all the magic, here eventually we write nice takenames
  472. writeTakeNames()
  473. end
  474. increaseTake() -- and have to increase the takenumber
  475. if groupItemsAfterRecord then -- and do post-record-stuff
  476. groupItems()
  477. elseif groupItemsHAfterRecord then
  478. groupItemsH()
  479. end
  480. if lockToActiveTakeAfterRecord then
  481. setLockToActiveTake()
  482. end
  483. if fillGapsAfterRecord then
  484. fillGapsBetweenItems()
  485. end
  486. thisnext = 'Next' -- during "not-record" the label says "Next Take: 43"
  487. increaseTodo = false -- and we're done and reset this flag
  488. end
  489. gfx.clear = 3355443 -- background is dark grey
  490. end
  491. -- If window is docked, use different scaling
  492. if gfx.dock(-1) > 0 then
  493. -- landscape format
  494. if gfx.w > gfx.h then
  495. gfx.x = 20
  496. gfx.y = ( gfx.h-select(2, gfx.measurestr("Take")) ) / 2
  497. gui.settings.font_size = gfx.h / 2
  498. gfx.setfont(1,"Arial", gui.settings.font_size)
  499. -- check if string fits into window, if not decrease fontsize a little, check again and loop
  500. while gfx.measurestr(thisnext .. " Take: " .. take) > (gfx.w - 2*gfx.x) do
  501. gui.settings.font_size = gui.settings.font_size / 1.1
  502. gfx.setfont(1,"Arial", gui.settings.font_size)
  503. end
  504. gfx.printf(thisnext .. " Take: " .. take)
  505. -- portrait format
  506. else
  507. gfx.x = gfx.w/15
  508. gfx.y = ( gfx.h-select(2, gfx.measurestr("Next\nTake\nT123")) ) / 2
  509. gui.settings.font_size = gfx.w / 3
  510. gfx.setfont(1,"Arial", gui.settings.font_size)
  511. gfx.printf(thisnext .. "\nTake:\n" .. take)
  512. end
  513. else -- window is not docked
  514. -- landscape format
  515. if gfx.w > gfx.h then
  516. gfx.x = gfx.w/20
  517. gfx.y = ( gfx.h-select(2, gfx.measurestr("Take")) ) / 2
  518. gui.settings.font_size = gfx.w / 6
  519. gfx.setfont(1,"Arial", gui.settings.font_size)
  520. -- check if string fits into window, if not decrease fontsize a little, check again and loop
  521. while gfx.measurestr(thisnext .. " Take: " .. take) > (gfx.w - 2*gfx.x) do
  522. gui.settings.font_size = gui.settings.font_size / 1.1
  523. gfx.setfont(1,"Arial", gui.settings.font_size)
  524. end
  525. gfx.printf(thisnext .. " Take: " .. take)
  526. -- portrait format
  527. else
  528. gfx.x = gfx.w/20
  529. gfx.y = ( gfx.h-select(2, gfx.measurestr("Next\nTake\nT123")) ) / 2
  530. gui.settings.font_size = gfx.w / 3
  531. gfx.setfont(1,"Arial", gui.settings.font_size)
  532. gfx.printf(thisnext .. "\nTake:\n" .. take)
  533. end
  534. end
  535. end
  536. -- Called on script termination. Store stuff...
  537. function onExit()
  538. storeExtState()
  539. end
  540. -- Main init function
  541. function init()
  542. -- check for SWS extensions
  543. if reaper.NamedCommandLookup('_SWS_ABOUT') > 0 then sws_present = true end
  544. -- load settings from rpp
  545. local retval
  546. local val
  547. retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'groupItems')
  548. if retval > 0 then
  549. if tonumber(val) > 0 then
  550. groupItemsAfterRecord = true
  551. else
  552. groupItemsAfterRecord = false
  553. end
  554. end
  555. retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'groupItemsH')
  556. if retval > 0 then
  557. if tonumber(val) > 0 then
  558. groupItemsAfterRecordH = true
  559. else
  560. groupItemsAfterRecordH = false
  561. end
  562. end
  563. retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'lockToActiveTake')
  564. if retval > 0 then
  565. if tonumber(val) > 0 then
  566. lockToActiveTakeAfterRecord = true
  567. else
  568. lockToActiveTakeAfterRecord = false
  569. end
  570. end
  571. retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'fillGaps')
  572. if retval > 0 then
  573. if tonumber(val) > 0 then
  574. fillGapsAfterRecord = true
  575. else
  576. fillGapsAfterRecord = false
  577. end
  578. end
  579. retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'writeTakenames')
  580. if retval > 0 then
  581. if tonumber(val) > 0 then
  582. writeTakeNamesAfterRecord = true
  583. else
  584. writeTakeNamesAfterRecord = false
  585. end
  586. end
  587. -- init stuff...
  588. gui_init()
  589. initTracknames()
  590. -- Add stuff to "gui" table
  591. gui.settings = {} -- Add "settings" table to "gui" table
  592. gui.settings.font_size = 50 -- font size
  593. gui.settings.docker_id = 0 -- try 0, 1, 257, 513, 1027 etc.
  594. -- Initialize gfx window --
  595. gfx.init("Rec Take", 350, 100, gui.settings.docker_id)
  596. gfx.setfont(1,"Arial", gui.settings.font_size)
  597. gfx.clear = 3355443 -- background is dark grey
  598. -- Restore docked state
  599. retval, val = reaper.GetProjExtState(0, 'takenumber_window', 'dockState')
  600. if retval > 0 then
  601. gfx.dock(val)
  602. end
  603. end
  604. -- Main loop --
  605. function mainloop()
  606. -- mouseclicks?
  607. local RMB_state = mouse.cap(mouse.RB)
  608. local LMB_state = mouse.cap(mouse.LB)
  609. local mx = gfx.mouse_x
  610. local my = gfx.mouse_y
  611. if not mouse.last_RMB_state and gfx.mouse_cap&2 == 2 then
  612. -- right click pressed down -> show "right click menu" at mouse cursor and focus arranger afterwards
  613. rc_menu:show(mx, my)
  614. reaper.Main_OnCommand( reaper.NamedCommandLookup('_BR_FOCUS_ARRANGE_WND'), 0 ) -- focus arranger
  615. end
  616. if not mouse.last_LMB_state and gfx.mouse_cap&1 == 1 then
  617. -- left click pressed down -> only focus arranger
  618. reaper.Main_OnCommand( reaper.NamedCommandLookup('_BR_FOCUS_ARRANGE_WND'), 0 ) -- focus arranger
  619. end
  620. mouse.last_RMB_state = RMB_state -- store current right mouse button state
  621. mouse.last_LMB_state = LMB_state -- store current left mouse button state
  622. drawGui()
  623. gfx.update()
  624. if gfx.getchar() >= 0 and not quit then reaper.defer(mainloop) end
  625. end
  626. -- START HERE...
  627. reaper.atexit(onExit)
  628. init()
  629. mainloop()