commit 64fb78ad16eea59797af383730436091ba86618d Author: Paul Provost Date: Sun Feb 23 16:00:29 2020 -0500 Initial commit diff --git a/Realive_ProjectTabsList.lua b/Realive_ProjectTabsList.lua new file mode 100644 index 0000000..3698cd6 --- /dev/null +++ b/Realive_ProjectTabsList.lua @@ -0,0 +1,809 @@ +-- @version 1.01 +-- @author MPL +-- @changelog +-- + Menu/Show shortcuts +-- + Menu/Dock: show dockstate check +-- @description ProjectPlaylist +-- @website http://forum.cockos.com/member.php?u=70694 + + -- requested here https://forum.cockos.com/showpost.php?p=1854775&postcount=1 + + + --[[ full changelog + 0.02 init alpha 01.07.2017 + basic GUI + load current opened project on start + save/load playlist + selecting tabs + objects init/update improvements + dragndrop project in list + 0.25 02.07.2017 + progress bar + active state + clickable play buttons + dragndrop + redraw background/static buttons fix + small menu button + limit playing progress to end of every project + redraw and update playlist if project closed manually + 0.30 03.07.2017 + tab selection: fill white rectangle, bold and bigger font + color current playing tab green + green progress line under the tab name + scroll with mouse wheel + shortcuts + space to Play/Stop active tab + space+shift: stop all tabs + arrow up: upper tab + arrow down: lower tab + dockable window + store dock state + left aligned tab names + order numbers + refresh playlist + 0.4 + take out play state buttons + take out gradient + take out menu + right click run menu + item separators + item state: the play cursor while playing and the Edit cursor while Stopped + cycle arrows + user input on save + reload list after save optionally + save/load playlists with .rpl extension + 0.50 + Prefix - Weekday MM DD HH-MM-SS YYYY.RPL + shortcuts : esc for exit + shortcuts : Shift+Alt+K for exit + shortcuts : tab to focus arrange + shift blit if active tab out of window + keep ID order + 0.60 + Menu: toggle dock + take gradient back + 0.61 + force reload after SWS save test + 1.01 12/07/2017 + Menu/Show shortcuts + Menu dock: show dockstate check + ]] + + + + --------------------------------------------------- + --------------------------------------------------- + -- Start Of Code + --------------------------------------------------- + --------------------------------------------------- + + + + + + + --------------------------------------------------- + -- Variables + --------------------------------------------------- + + for key in pairs(reaper) do _G[key]=reaper[key] end + local item_height = 20 + local global_font_size = 16 + local global_font_name = 'Arial' + local max_proj_cnt = 200 + local playlists_path = '/Volumes/DropboxDrive/Dropbox/ReaperSetlists/' + local TrackToArm = "Drumpad" + + + --------------------------------------------------- + -- INIT & SETUP + --------------------------------------------------- + + local vrs = 1.01 + debug = 0 + local mouse = {} + local gui -- see GUI_define() + local obj = {blit_offs = 0} + conf = {} + local cycle = 0 + local redraw = 1 + local SCC, lastSCC, SCC_trig,drag_mode,last_drag_mode + local ProjState + local playlist = {} + --------------------------------------------------- + local function lim(val, min,max) --local min,max + if not min or not max then min, max = 0,1 end + return math.max(min, math.min(val, max) ) + end + --------------------------------------------------- + local function ExtState_Save() + conf.dock, conf.wind_x, conf.wind_y, conf.wind_w, conf.wind_h = gfx.dock(-1, 0,0,0,0) + for key in pairs(conf) do SetExtState(conf.ES_key, key, conf[key], true) end + end + --------------------------------------------------- + local function Msg(s) + --ShowConsoleMsg(s..'\n') + end +-- if debug == 1 then function Msg(s) ShowConsoleMsg(s..'\n') end end + + --------------------------------------------------- + -- GUI Stuff + --------------------------------------------------- + + local function col(col_s, a) gfx.set( table.unpack(gui.col[col_s])) if a then gfx.a = a end end + --------------------------------------------------- + local function GUI_DrawObj(o) + if not o then return end + local x,y,w,h, txt = o.x, o.y, o.w, o.h, o.txt + + -- gradient back + gfx.a = o.a or 0.3 + gfx.blit( 2, 1, math.rad(o.grad_blit_rot), + 0,0, obj.grad_sz,math.ceil(obj.grad_sz*o.grad_blit_h_coeff), + x,y,w,h, 0,0) + + -- separator + col('white', 0.3) + gfx.line(x,y+h,x+w,y+h) + + + local flag = '' + local fontsz_add = 0 + + -- selection active tab + if o.active then + col('white', 0.45) + gfx.rect(x,y+1,w,h-1,1) + flag = string.byte("b",1) + fontsz_add = 2 + end + + -- progress + if o.progress then + col('green', 0.43) + gfx.rect(x,y+h-2,w*o.progress,2,0) + end + + -- font on play + col('white', 0.8) + if o.playstate then col('green', 0.7) end + + -- text + gfx.setfont(1, gui.fontname, gui.fontsz + fontsz_add, flag ) + local x_offs = 5 + gfx.x = x + (w-gfx.measurestr(txt))/2 + if o.leftaligned then gfx.x = x + x_offs end + gfx.y = y+ (h-gfx.texth)/2 + gfx.drawstr(o.txt) + end + --------------------------------------------------- + local function GUI_Playlist() + gfx.dest = 4 + gfx.setimgdim(4, -1, -1) + gfx.setimgdim(4, gfx.w, obj.it_h * #playlist) + for key in pairs(obj) do if type(obj[key]) == 'table' and key:find('PLitem') then GUI_DrawObj(obj[key]) end end + + if drag_id_dest and drag_id_src and drag_id_dest ~= drag_id_src then + local add + if drag_id_dest > drag_id_src then add = 0 else add =1 end + gfx.a = 1 + gfx.line(0,obj.it_h*(drag_id_dest-add), + gfx.w, obj.it_h*(drag_id_dest-add) + ) + end + + end + --------------------------------------------------- + local function GUI_draw() + gfx.mode = 0 + -- redraw: -1 init, 1 maj changes, 2 minor changes + -- 1 back + -- 2 gradient + --// 3 dynamic stuff + -- 4 playlist + + -- init + if math.abs(redraw )== 1 then + gfx.dest = 2 + gfx.setimgdim(2, -1, -1) + gfx.setimgdim(2, obj.grad_sz,obj.grad_sz) + local r,g,b,a = 0.61,0.61,0.61,0.67 + gfx.x, gfx.y = 0,0 + local c = 0.5 + local drdx = c*0.00001 + local drdy = c*0.00001 + local dgdx = c*0.00008 + local dgdy = c*0.0001 + local dbdx = c*0.00008 + local dbdy = c*0.00001 + local dadx = c*0.00003 + local dady = c*0.0004 + gfx.gradrect(0,0, obj.grad_sz,obj.grad_sz, + r,g,b,a, + drdx, dgdx, dbdx, dadx, + drdy, dgdy, dbdy, dady) + -- refresh backgroung + gfx.dest = 1 + gfx.setimgdim(1, -1, -1) + gfx.setimgdim(1, gfx.w, gfx.h) + gfx.blit( 2, 1, 0, -- grad back + 0,0, obj.grad_sz,obj.grad_sz, + 0,0, gfx.w,gfx.h, 0,0) + gfx.a = 1 + + end + -- dynamic list + GUI_Playlist() + + + -- render + gfx.dest = -1 + gfx.a = 1 + gfx.x,gfx.y = 0,0 + -- back + gfx.blit(1, 1, 0, -- backgr + 0,0,gfx.w, gfx.h, + 0,0,gfx.w, gfx.h, 0,0) + -- PL + local y_sh = lim(obj.it_h * #playlist - gfx.h, 0, gfx.h) * obj.blit_offs + local h = lim(obj.it_h * #playlist, 0, y_sh+gfx.h) + gfx.blit(4, 1, 0, -- PL + 0,0, gfx.w,h , + 0,-y_sh, gfx.w, h, 0,0) + + GUI_DrawObj(obj.scrollbar) + GUI_DrawObj(obj.menu) + --[[ line fix + col('white', 0.3) + gfx.line(0,gfx.h-obj.it_h, gfx.w,gfx.h-obj.it_h)]] + + redraw = 0 + gfx.update() + end + --------------------------------------------------- + function HasWindXYWHChanged() + local dock, wx,wy,ww,wh = gfx.dock(-1, 0,0,0,0) + local retval=0 + if wx ~= obj.last_gfxx or wy ~= obj.last_gfxy then retval= 2 end --- minor + if ww ~= obj.last_gfxw + or wh ~= obj.last_gfxh + or wdock ~= obj.last_gfxdock + then retval= 1 end --- major + if not obj.last_gfxx then retval = -1 end + obj.last_gfxx, obj.last_gfxy, obj.last_gfxw, obj.last_gfxh, obj.last_gfxdock = wx,wy,ww,wh, dock + return retval + end + + --------------------------------------------------- + -- EXT States + --------------------------------------------------- + + local function ExtState_Def() + return {ES_key = 'MPL_ProjectPlaylist', + wind_x = 50, + wind_y = 50, + wind_w = 200, + wind_h = 500, + dock = 0} + end + --------------------------------------------------- + local function ExtState_Load() + local def = ExtState_Def() + for key in pairs(def) do + local es_str = GetExtState(def.ES_key, key) + if es_str == '' then conf[key] = def[key] else conf[key] = tonumber(es_str) or es_str end + end + end + + --------------------------------------------------- + -- PLAYLIST Generate + --------------------------------------------------- + + local function Actions_AddOpenedProjectsToPlaylist() + for i = 1, max_proj_cnt do + local retval, projfn= EnumProjects( i-1, '' ) +-- if projfn == '' then break end + playlist[#playlist+1] = {ptr = retval, path = projfn, ID = i} + end + end + --------------------------------------------------- + local function Actions_ReloadPlaylist(fp) + if not fp and not playlist.fn then return end + if not fp then fp = playlist.fn end + if not tp then return end + playlist = {} + local f = io.open(fp, 'r') + if not f then return end + local context = f:read('a') + f:close() + local t = {} + Main_OnCommand(40886,0) -- File: Close all projects + playlist = {fn = fp} + for line in context:gmatch('[^\r\n]+') do + Main_OnCommand(41929, 0 ) -- New project tab (ignore default template) + Main_openProject( line ) + local retval= EnumProjects( -1, '' ) + playlist[#playlist+1] = {path = line, + ptr = retval} + end + SelectProjectInstance( EnumProjects( 0, '') ) + Main_OnCommand(40860,0) -- Close current project tab + redraw = 1 + OBJ_define() + end + + + + --------------------------------------------------- + -- Right Click MENU + --------------------------------------------------- + + function Menu() + gfx.x, gfx.y = mouse.mx, mouse.my + local is_dirty = '#' if playlist.fn then is_dirty = '' end + local is_docked + if conf.dock==1 then is_docked = '!' else is_docked = '' end + local str_t = { + { txt = 'Add current saved project to playlist', + func = function() + local retval, projfn= EnumProjects( -1, '' ) + playlist[#playlist+1] = {ptr = retval, path = projfn } + redraw = 1 + OBJ_define() + end + }, + { txt = '|Add all opened saved projects to playlist (ignore projects without saved RPP)', + func = function() + Actions_AddOpenedProjectsToPlaylist() + redraw = 1 + OBJ_define() + end + }, + { txt = '||Load projects from playlist', + func = function() + local ret = MB( 'Are you sure you want to close ALL project tabs?', 'MPL ProjectPlaylist', 4 ) + if ret == 6 then + local r, fn = GetUserFileNameForRead('', 'Open ProjectPlaylist', 'rpl' ) + if not r then return end + local f = io.open(fn, 'r') + if not f then return end + local context = f:read('a') + f:close() + local t = {} + Main_OnCommand(40886,0) -- File: Close all projects + playlist = {fn = fn} + for line in context:gmatch('[^\r\n]+') do + Main_OnCommand(41929, 0 ) -- New project tab (ignore default template) + Main_openProject( line ) + local retval= EnumProjects( -1, '' ) + playlist[#playlist+1] = {path = line, + ptr = retval} + end + SelectProjectInstance( EnumProjects( 0, '') ) + Main_OnCommand(40860,0) -- Close current project tab + redraw = 1 + OBJ_define() + end + end + }, + -- { txt = '|'..is_dirty..'Save playlist', + -- func = function() + -- local out_str = '' + -- for i = 1, #playlist do out_str = out_str..playlist[i].path..'\n' end + -- local f = io.open(playlist.fn, 'w') + -- f:write(out_str) + -- f:close() + -- end + -- }, + { txt = '|Save playlist to ~/Dropbox/REAPER Setlists/(timestamp)', + func = function() + local out_str = '' + RecursiveCreateDirectory( playlists_path, 0 ) + r, UI = GetUserInputs('Save playlist', 1, 'new name', 'playlist') + if r then + local timest = os.date():gsub('%:', '-') + timest = os.date('%Y-%m-%d - %H-%M-%S') + local fp = playlists_path..UI..' - '..timest..'.rpl' + for i = 1, #playlist do out_str = out_str..playlist[i].path..'\n' end + local f = io.open(fp, 'w') + f:write(out_str) + f:close() + playlist.fn = fp + -- r2 = MB( 'Reload playlist?', '', 4 ) + -- if r2 == 5 then + -- Actions_ReloadPlaylist(fp) + -- end + end + end + }, + { txt = '|Open ProjectPlaylist path', + func = function() + local OS, cmd = GetOS() + if OS:find("OSX") then cmd = 'open' else cmd = 'start' end + os.execute(cmd..' "" "' .. playlists_path .. '"') + end + }, + { txt = '||Refresh Playlist', + func = function() + playlist = {} + Actions_AddOpenedProjectsToPlaylist() + redraw = 1 + OBJ_define() + end + } , + { txt = '|'..is_docked..'Dock Project Playlist Manager in docker', + func = function() + dock_state = gfx.dock(-1) + gfx.dock(math.abs(1-dock_state)) + end + } , + { txt = '|Show shortcuts', + func = function() + MB( +[[ +SPACE - Transport: Play/stop active tab +Shift SPACE - Stop All Tabs +UP arrow - Previous tab +DOWN arrow - Next tab +TAB - SWS/S&M: Focus main window (close others) +CMD+OPT+K - Open/Close window +]] + + ,'Keyboard shortcuts',0) + end + } + + } + local str = "" + for i = 1, #str_t do str = str..str_t[i].txt end + local ret = gfx.showmenu(str) + if ret > 0 then str_t[ret].func() end + end + + --------------------------------------------------- + -- OBJ Define + --------------------------------------------------- + + function OBJ_define() + obj.offs = 2 + obj.menu_b_h = 15 + obj.it_h = item_height + obj.grad_sz = 300 -- gradient rect + obj.proj_playb_w = 20 + obj.scrollbar_w = 10 + + obj.scrollbar = {x = gfx.w-obj.scrollbar_w, + y = 0,--obj.menu_b_h, + w= obj.scrollbar_w, + h =gfx.h,---obj.menu_b_h, + a = 0.8, + grad_blit_h_coeff = 1, + grad_blit_rot = 0, + txt = '', + draw_dyn = true} + + + --[[obj.menu = {x = gfx.w-obj.scrollbar_w, + y = 0, + w= obj.scrollbar_w, + h = obj.menu_b_h, + a = 0.2, + grad_blit_h_coeff = 1, + grad_blit_rot = 0, + txt = 'M', + func = function() Menu() end}]] + + for i = 1, #playlist do + if ValidatePtr2( nil, playlist[i].ptr, 'ReaProject*' ) then + --[[obj['PLitem_play_'..i] = {x = 0, + y = obj.it_h*(i-1), + w = obj.proj_playb_w, + h = obj.it_h, + txt = '', + a = 1, + grad_blit_h_coeff = 0.3, + grad_blit_rot = 180, + func = function() + local state = GetPlayStateEx( playlist[i].ptr ) == 1 + if state then OnStopButtonEx( playlist[i].ptr ) + else OnPlayButtonEx( playlist[i].ptr ) end + end} ]] + if not playlist[i].ID then playlist[i].ID = 0 end + obj['PLitem_'..i] = {x = -1,--obj.proj_playb_w, + y = obj.it_h*(i-1), + w = gfx.w-obj.scrollbar_w,---obj.proj_playb_w, + h = obj.it_h, + txt = i..'. '..GetProjectName( playlist[i].ptr, '' ):sub(0,-5), + a = 1, + leftaligned = true, + grad_blit_h_coeff = 0.3, + grad_blit_rot = 180,func = function() + Msg('1073 [i]: '..i) + + Msg('1073 Ptr: '..tostring(playlist[i].ptr)) + + SelectProjectInstance( playlist[i].ptr ) + redraw = 1 + OBJ_Update() + end} + end + end + end + --------------------------------------------------- + function OBJ_Update() + for i = 1, max_proj_cnt do + local retval, projfn= EnumProjects( i-1, '' ) + if projfn == '' then break end + for j = 1, #playlist do + if playlist[j].ptr == retval then playlist[j].ID = i end + end + end + + obj.blit_h = obj.it_h * #playlist + + obj.scrollbar.x = gfx.w-obj.scrollbar_w + obj.scrollbar.h = gfx.h * lim( gfx.h/obj.blit_h , 0, 1) + --(gfx.h-obj.menu_b_h ) * lim( gfx.h/obj.blit_h , 0, 1) + obj.scrollbar.y = obj.blit_offs * (gfx.h - obj.scrollbar.h) + --obj.menu.x = gfx.w-obj.scrollbar_w + + for i = #playlist , 1, -1 do + if not ValidatePtr2( nil, playlist[i].ptr, 'ReaProject*' ) then + obj['PLitem_'..i] = nil + table.remove(playlist, i) + redraw =1 + end + end + + for i = 1, #playlist do + if ValidatePtr2( nil, playlist[i].ptr, 'ReaProject*' ) and obj['PLitem_'..i] then + obj['PLitem_'..i].w = gfx.w-obj.scrollbar_w--obj.proj_playb_w + obj['PLitem_'..i].active = EnumProjects( -1, '' ) == playlist[i].ptr + if obj['PLitem_'..i].active then + obj.active_item = i + + end + obj['PLitem_'..i].playstate = GetPlayStateEx( playlist[i].ptr ) == 1 + obj['PLitem_'..i].mouse_offs_y = -lim(obj.it_h * #playlist - gfx.h, 0, gfx.h) * obj.blit_offs + --[[obj['PLitem_play_'..i].mouse_offs_y = obj['PLitem_'..i].mouse_offs_y + if GetPlayStateEx( playlist[i].ptr ) == 1 then obj['PLitem_play_'..i].txt = '>' + else obj['PLitem_play_'..i].txt = '|' end]] + if GetProjectLength( playlist[i].ptr ) > 0 then + if GetPlayStateEx( playlist[i].ptr ) == 1 then + obj['PLitem_'..i].progress = lim(GetPlayPositionEx( playlist[i].ptr ) / GetProjectLength( playlist[i].ptr ),0,1) + else + obj['PLitem_'..i].progress = lim( GetCursorPositionEx( playlist[i].ptr ) / GetProjectLength( playlist[i].ptr ),0,1) + end + end + end + end + + if obj.last_active_item and obj.active_item and obj.active_item ~= obj.last_active_item then + shift_to_tab = true + end + + if shift_to_tab then + if obj['PLitem_'..obj.active_item].y+obj['PLitem_'..obj.active_item].mouse_offs_y > gfx.h - obj.it_h then + obj.blit_offs = lim(obj.blit_offs + 0.08, 0, 1) + redraw = 1 + elseif obj['PLitem_'..obj.active_item].y+obj['PLitem_'..obj.active_item].mouse_offs_y < 0 then + obj.blit_offs = lim(obj.blit_offs - 0.08, 0, 1) + redraw = 1 + else + shift_to_tab = false + end + end + + obj.last_active_item = obj.active_item + + end + + --------------------------------------------------- + -- Mouse Stuff + --------------------------------------------------- + + local function MOUSE_Match(b) + if not b.mouse_offs_y then b.mouse_offs_y = 0 end + if not b.ignore_mouse then + return mouse.mx > b.x + and mouse.mx < b.x+b.w + and mouse.my > b.y+b.mouse_offs_y + and mouse.my < b.y+b.mouse_offs_y+b.h + end + end + --------------------------------------------------- + local function MOUSE_Click(b) return MOUSE_Match(b) and mouse.LMB_state and not mouse.last_LMB_state end + --------------------------------------------------- + local function MOUSE() + mouse.mx = gfx.mouse_x + mouse.my = gfx.mouse_y + mouse.LMB_state = gfx.mouse_cap&1 == 1 + mouse.RMB_state = gfx.mouse_cap&2 == 2 + mouse.MMB_state = gfx.mouse_cap&64 == 64 + mouse.LMB_state_doubleclick = false + mouse.Ctrl_LMB_state = gfx.mouse_cap&5 == 5 + mouse.Ctrl_state = gfx.mouse_cap&4 == 4 + mouse.Shift_state = gfx.mouse_cap&8 == 8 + mouse.Alt_state = gfx.mouse_cap&17 == 17 -- alt + LB + mouse.wheel = gfx.mouse_wheel + if mouse.last_wheel then mouse.wheel_trig = (mouse.wheel - mouse.last_wheel) end + if mouse.LMB_state and not mouse.last_LMB_state then mouse.last_mx_onclick = mouse.mx mouse.last_my_onclick = mouse.my end + if mouse.last_mx_onclick and mouse.last_my_onclick then mouse.dx = mouse.mx - mouse.last_mx_onclick mouse.dy = mouse.my - mouse.last_my_onclick else mouse.dx, mouse.dy = 0,0 end + + -- butts + for key in pairs(obj) do + if type(obj[key]) == 'table'then + if MOUSE_Match(obj[key]) then mouse.context = key end + if MOUSE_Click(obj[key]) then + Msg('') + Msg('MouseButton_ID: '..key) + Msg('MouseButton_ptr: '..tostring(obj[key])) + + mouse.context_latch = key + if obj[key].func then + obj[key].func() + Msg('') + for key in pairs(playlist) do + Msg('') + Msg('ID: '..tostring(playlist[key].ID)) + Msg('ptr: '..tostring(playlist[key].ptr)) + Msg('path: '..tostring(playlist[key].path)) + Msg('') + end + reaper.SetCursorContext(1) --Focus Arrange Window + break + end + end + end + end + + -- drag + drag_mode = mouse.LMB_state and mouse.context and mouse.context_latch and mouse.context_latch ~= '' + if drag_mode then + drag_id_src = mouse.context_latch:match('[%d]+') if drag_id_src then drag_id_src = tonumber(drag_id_src) end + drag_id_dest = mouse.context:match('[%d]+') if drag_id_dest then drag_id_dest = tonumber(drag_id_dest) end + if mouse.my < 0 then + obj.blit_offs = lim(obj.blit_offs - 0.05, 0,1) + elseif mouse.my > gfx.h then + obj.blit_offs = lim(obj.blit_offs + 0.05, 0,1) + end + end + if last_drag_mode and not drag_mode and drag_id_dest and drag_id_src then + local entry = playlist[drag_id_src] + table.remove(playlist, drag_id_src) + table.insert(playlist, drag_id_dest, entry) + drag_id_src, drag_id_dest = nil, nil + OBJ_define() + OBJ_Update() + redraw = 1 + end + + -- scrollbar + if obj.it_h * #playlist > gfx.h - obj.menu_b_h then + if MOUSE_Click(obj.scrollbar) then + blit_offs_latch = obj.blit_offs + reaper.SetCursorContext(1) --Focus Arrange Window + end + if mouse.context_latch and mouse.context_latch == 'scrollbar' then + obj.blit_offs = lim(blit_offs_latch + mouse.dy/100) + end + end + + if mouse.wheel_trig then obj.blit_offs = lim(obj.blit_offs - mouse.wheel_trig/1200, 0,1) end + if mouse.LMB_state and MOUSE_Match({x=0,y=0,w=gfx.w,h=gfx.h}) then OBJ_Update() redraw = 1 end + + if not mouse.last_RMB_state and mouse.RMB_state then Menu() end + + -- Empty Space +-- if MOUSE_Click(obj.grad_sz) then +-- reaper.SetCursorContext(1) --Focus Arrange Window +-- end + + + -- mouse release + last_drag_mode = drag_mode + if mouse.last_LMB_state and not mouse.LMB_state then mouse.context_latch = '' end + mouse.last_LMB_state = mouse.LMB_state + mouse.last_RMB_state = mouse.RMB_state + mouse.last_MMB_state = mouse.MMB_state + mouse.last_Ctrl_LMB_state = mouse.Ctrl_LMB_state + mouse.last_Ctrl_state = mouse.Ctrl_state + mouse.last_Alt_state = mouse.Alt_state + mouse.last_wheel = mouse.wheel + end + + --------------------------------------------------- + -- Tabs + --------------------------------------------------- + + local function Actions_Shift_Tab(add) + if not obj.active_item then return end + local id = obj.active_item + add , 1, #playlist + if id < 1 then id = #playlist elseif id > #playlist then id = 1 end + if playlist[id] then SelectProjectInstance( playlist[id].ptr ) end + end + --------------------------------------------------- + local function Actions_StopAllTabs() + for i = 1, #playlist do if playlist[i].ptr then reaper.OnStopButtonEx( playlist[i].ptr ) end end + end + --------------------------------------------------- + local function SHORTCUTS(chr) +--[[ if chr == 32 and not mouse.Shift_state then Main_OnCommand(40044, 0) -- Transport: Play/stop active tab // Space + elseif chr == 30064 then Actions_Shift_Tab(-1) + elseif chr == 1685026670 then Actions_Shift_Tab(1) + elseif chr == 32 and mouse.Shift_state then Actions_StopAllTabs() + elseif chr == 9 then Main_OnCommand(NamedCommandLookup('_BR_FOCUS_ARRANGE_WND'), 0)-- SWS/S&M: Focus main window (close others) + elseif chr == 019 then + reaper.Main_OnCommand(reaper.NamedCommandLookup('_SWS_PROJLISTSAVE'),0)-- SWS/S&M: Save List of Open Project + Actions_ReloadPlaylist() + elseif chr == 015 then reaper.Main_OnCommand(reaper.NamedCommandLookup('_SWS_PROJLISTSOPEN'),0)-- SWS/S&M: Open Projects from List + end]] + end + + --------------------------------------------------- + --------------------------------------------------- + -- RUN + --------------------------------------------------- + --------------------------------------------------- + + local function run() + SCC = GetProjectStateChangeCount( 0 ) if not lastSCC or lastSCC ~= SCC then SCC_trig = true else SCC_trig = false end lastSCC = SCC + clock = os.clock() + cycle = cycle+1 + local st_wind = HasWindXYWHChanged() + if st_wind == -1 then + redraw = -1 + elseif st_wind == 1 then + redraw = 1 + --OBJ_define() + ExtState_Save() + elseif st_wind == 2 then + ExtState_Save() + end + + + OBJ_Update() + GUI_draw() + MOUSE() + chr = gfx.getchar() + chr_ms = gfx.mouse_cap + SHORTCUTS(chr) + if chr>= 0 + and chr ~= 27 + and not (chr == 331 and chr_ms == 24) then defer(run) else atexit(gfx.quit) end + end + --------------------------------------------------- + local function GUI_define() + gui = { + aa = 1, + mode = 3, + fontname = global_font_name, + fontsz = global_font_size, + col = { grey = {0.5, 0.5, 0.5 }, + white = {1, 1, 1 }, + red = {1, 0, 0 }, + green = {0, 1, 0.3 }, + blue = {0, 0, 1} + } + + } + + if OS == "OSX32" or OS == "OSX64" then gui.fontsz = gui.fontsz - 3 end + end + + + + + --------------------------------------------------- + --------------------------------------------------- + -- Main Loop + --------------------------------------------------- + --------------------------------------------------- + ExtState_Load() + gfx.init('MPL ProjectPlaylist '..vrs,conf.wind_w, conf.wind_h, conf.dock, conf.wind_x, conf.wind_y) + Actions_AddOpenedProjectsToPlaylist() + OBJ_define() + GUI_define() + run() + +