From 7969dfffce792b6cb096e18179a7ecff74b14111 Mon Sep 17 00:00:00 2001 From: Goran Date: Wed, 17 Apr 2024 21:45:07 +0200 Subject: [PATCH 1/6] -- Imgui Shims -- Implement FX Browser parser --- FX/sexan_Lil FX Slot Homie.lua | 140 +++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 50 deletions(-) diff --git a/FX/sexan_Lil FX Slot Homie.lua b/FX/sexan_Lil FX Slot Homie.lua index 47866268f..5e23da8b4 100644 --- a/FX/sexan_Lil FX Slot Homie.lua +++ b/FX/sexan_Lil FX Slot Homie.lua @@ -1,79 +1,98 @@ -- @description Lil FX Slot Homie -- @author Sexan --- @version 1.0 +-- @version 1.2 -- @link https://forum.cockos.com/showthread.php?p=2680992#post2680992 +-- @changelog +-- Imgui Shims +-- Implement FX Browser parser local SLOT = 1 local r = reaper +local reaper_path = r.GetResourcePath() -local ctx = r.ImGui_CreateContext('Lil FX Slot Homie', r.ImGui_ConfigFlags_NavEnableKeyboard()) +local fx_browser_script_path = reaper_path .. "/Scripts/Sexan_Scripts/FX/Sexan_FX_Browser_ParserV7.lua" -function FX_NAME(str) - local vst_name - for name_segment in str:gmatch('[^%,]+') do - if name_segment:match("(%S+) ") then - if name_segment:match('"(JS: .-)"') then - vst_name = name_segment:match('"JS: (.-)"') and "JS:" .. name_segment:match('"JS: (.-)"') or nil - else - vst_name = name_segment:match("(%S+ .-%))") and "VST:" .. name_segment:match("(%S+ .-%))") or nil - end +function ThirdPartyDeps() + local reapack_process + local repos = { + { name = "Sexan_Scripts", url = 'https://github.com/GoranKovac/ReaScripts/raw/master/index.xml' }, + } + + for i = 1, #repos do + local retinfo, url, enabled, autoInstall = r.ReaPack_GetRepositoryInfo(repos[i].name) + if not retinfo then + retval, error = r.ReaPack_AddSetRepository(repos[i].name, repos[i].url, true, 0) + reapack_process = true end end - if vst_name then return vst_name end -end -function GetFileContext(fp) - local str = "\n" - local f = io.open(fp, 'r') - if f then - str = f:read('a') - f:close() + -- ADD NEEDED REPOSITORIES + if reapack_process then + --r.ShowMessageBox("Added Third-Party ReaPack Repositories", "ADDING REPACK REPOSITORIES", 0) + r.ReaPack_ProcessQueue(true) + reapack_process = nil end - return str end --- Fill function with desired database -function Fill_fx_list() - local tbl_list = {} - local tbl = {} +local function CheckDeps() + ThirdPartyDeps() + local deps = {} - local vst_path = r.GetResourcePath() .. "/reaper-vstplugins64.ini" - local vst_str = GetFileContext(vst_path) + if not r.ImGui_GetVersion then + deps[#deps + 1] = '"Dear Imgui"' + end + if not r.file_exists(fx_browser_script_path) then + deps[#deps + 1] = '"FX Browser Parser V7"' + end + if #deps ~= 0 then + r.ShowMessageBox("Need Additional Packages.\nPlease Install it in next window", "MISSING DEPENDENCIES", 0) + r.ReaPack_BrowsePackages(table.concat(deps, " OR ")) + return true + end +end +if CheckDeps() then return end - local vst_path32 = r.GetResourcePath() .. "/reaper-vstplugins.ini" - local vst_str32 = GetFileContext(vst_path32) +dofile(r.GetResourcePath() .. '/Scripts/ReaTeam Extensions/API/imgui.lua')('0.8.7') +if r.file_exists(fx_browser_script_path) then + dofile(fx_browser_script_path) +end - local jsfx_path = r.GetResourcePath() .. "/reaper-jsfx.ini" - local jsfx_str = GetFileContext(jsfx_path) +local ctx = r.ImGui_CreateContext('Lil FX Slot Homie', r.ImGui_ConfigFlags_NavEnableKeyboard()) - local au_path = r.GetResourcePath() .. "/reaper-auplugins64-bc.ini" - local au_str = GetFileContext(au_path) +local FX_LIST = ReadFXFile() - local plugins = vst_str .. vst_str32 .. jsfx_str .. au_str +if not FX_LIST then + FX_LIST = MakeFXFiles() +end - for line in plugins:gmatch('[^\r\n]+') do tbl[#tbl + 1] = line end +local function Lead_Trim_ws(s) return s:match '^%s*(.*)' end - -- CREATE NODE LIST - for i = 1, #tbl do - local fx_name = FX_NAME(tbl[i]) - if fx_name then - tbl_list[#tbl_list + 1] = fx_name +local tsort = table.sort +function SortTable(tab, val1, val2) + tsort(tab, function(a, b) + if (a[val1] < b[val1]) then + -- primary sort on position -> a before b + return true + elseif (a[val1] > b[val1]) then + -- primary sort on position -> b before a + return false + else + -- primary sort tied, resolve w secondary sort on rank + return a[val2] < b[val2] end - end - return tbl_list + end) end -local FX_LIST = Fill_fx_list() -local function Lead_Trim_ws(s) return s:match '^%s*(.*)' end - +local old_t = {} +local old_filter = "" local function Filter_actions(filter_text) + if old_filter == filter_text then return old_t end filter_text = Lead_Trim_ws(filter_text) local t = {} - if filter_text == "" then return t end + if filter_text == "" or not filter_text then return t end for i = 1, #FX_LIST do - local action = FX_LIST[i] - local name = action:lower() + local name = FX_LIST[i]:lower() --:gsub("(%S+:)", "") local found = true for word in filter_text:gmatch("%S+") do if not name:find(word:lower(), 1, true) then @@ -81,11 +100,28 @@ local function Filter_actions(filter_text) break end end - if found then t[#t + 1] = action end + if found then t[#t + 1] = { score = FX_LIST[i]:len() - filter_text:len(), name = FX_LIST[i] } end end + if #t >= 2 then + SortTable(t, "score", "name") -- Sort by key priority + end + old_t = t + old_filter = filter_text return t end +local function SetMinMax(Input, Min, Max) + if Input >= Max then + Input = Max + elseif Input <= Min then + Input = Min + else + Input = Input + end + return Input +end + +local FILTER = '' local function AddFxToTracks(fx) if r.CountTracks(0) == 1 and r.CountSelectedTracks(0) == 0 then local track = r.GetTrack(0, 0) @@ -137,6 +173,10 @@ function FilterBox() r.ImGui_SetNextWindowSize(ctx, 0, filter_h) if r.ImGui_BeginPopup(ctx, "popup") then r.ImGui_Text(ctx, "ADD TO SLOT : " .. (SLOT < 100 and tostring(SLOT) or "LAST")) + r.ImGui_SameLine(ctx, 0, 20) + if r.ImGui_Selectable(ctx, "RESCAN FX", false, 0, 65) then + FX_LIST = MakeFXFiles() + end r.ImGui_PushItemWidth(ctx, MAX_FX_SIZE) if r.ImGui_IsWindowAppearing(ctx) then r.ImGui_SetKeyboardFocusHere(ctx) end -- IF KEYBOARD FOCUS IS ON CHILD ITEMS SET IT HERE @@ -159,8 +199,8 @@ function FilterBox() for i = 1, #filtered_fx do AllowChildFocus(i) r.ImGui_PushID(ctx, i) - if r.ImGui_Selectable(ctx, filtered_fx[i], true, nil, MAX_FX_SIZE) then - AddFxToTracks(filtered_fx[i]) + if r.ImGui_Selectable(ctx, filtered_fx[i].name, true, nil, MAX_FX_SIZE) then + AddFxToTracks(filtered_fx[i].name) end r.ImGui_PopID(ctx) end From 3e5247096ff8dc1992ff045a1ac5e42f31897aa8 Mon Sep 17 00:00:00 2001 From: Goran Kovac Date: Mon, 29 Jul 2024 16:30:59 +0200 Subject: [PATCH 2/6] -- version 1.21 -- link https://forum.cockos.com/showthread.php?p=2680992#post2680992 -- changelog -- Scroll to selected items if they are not in view -- Fix ESC Clear/close script --- FX/sexan_Lil FX Slot Homie.lua | 92 +++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 29 deletions(-) diff --git a/FX/sexan_Lil FX Slot Homie.lua b/FX/sexan_Lil FX Slot Homie.lua index 5e23da8b4..85cee8d1f 100644 --- a/FX/sexan_Lil FX Slot Homie.lua +++ b/FX/sexan_Lil FX Slot Homie.lua @@ -1,10 +1,10 @@ -- @description Lil FX Slot Homie -- @author Sexan --- @version 1.2 +-- @version 1.21 -- @link https://forum.cockos.com/showthread.php?p=2680992#post2680992 -- @changelog --- Imgui Shims --- Implement FX Browser parser +-- Scroll to selected items if they are not in view +-- Fix ESC Clear/close script local SLOT = 1 @@ -58,7 +58,7 @@ if r.file_exists(fx_browser_script_path) then dofile(fx_browser_script_path) end -local ctx = r.ImGui_CreateContext('Lil FX Slot Homie', r.ImGui_ConfigFlags_NavEnableKeyboard()) +local ctx = r.ImGui_CreateContext('Lil FX Slot Homie') local FX_LIST = ReadFXFile() @@ -121,7 +121,7 @@ local function SetMinMax(Input, Min, Max) return Input end -local FILTER = '' +FILTER = '' local function AddFxToTracks(fx) if r.CountTracks(0) == 1 and r.CountSelectedTracks(0) == 0 then local track = r.GetTrack(0, 0) @@ -166,11 +166,36 @@ local function AllowChildFocus(i) end end +function SetMinMax(Input, Min, Max) + if Input >= Max then + Input = Max + elseif Input <= Min then + Input = Min + else + Input = Input + end + return Input +end + +local function scroll(pos) + if not reaper.ImGui_IsItemVisible(ctx) then + reaper.ImGui_SetScrollHereY(ctx,pos) + end + +end + local filter_h = 60 local MAX_FX_SIZE = 300 function FilterBox() CheckKeyNumbers() r.ImGui_SetNextWindowSize(ctx, 0, filter_h) + if r.ImGui_IsKeyPressed(ctx, r.ImGui_Key_Escape()) then + if #FILTER == 0 then + CLOSE = true + else + FOCUS = true + end + end if r.ImGui_BeginPopup(ctx, "popup") then r.ImGui_Text(ctx, "ADD TO SLOT : " .. (SLOT < 100 and tostring(SLOT) or "LAST")) r.ImGui_SameLine(ctx, 0, 20) @@ -179,33 +204,42 @@ function FilterBox() end r.ImGui_PushItemWidth(ctx, MAX_FX_SIZE) if r.ImGui_IsWindowAppearing(ctx) then r.ImGui_SetKeyboardFocusHere(ctx) end - -- IF KEYBOARD FOCUS IS ON CHILD ITEMS SET IT HERE - if r.ImGui_IsKeyPressed(ctx, r.ImGui_Key_Escape()) then r.ImGui_SetKeyboardFocusHere(ctx) end - _, FILTER = r.ImGui_InputText(ctx, '##input', FILTER) - if r.ImGui_IsItemFocused(ctx) then - ALLOW_IN_LIST, PASS_FOCUS = nil, nil - -- IF FOCUS IS ALREADY HERE CLOSE POPUP - if r.ImGui_IsKeyPressed(ctx, r.ImGui_Key_Escape()) then r.ImGui_CloseCurrentPopup(ctx) end + if FOCUS then + r.ImGui_SetKeyboardFocusHere(ctx) + FOCUS = nil end + if CLOSE then + r.ImGui_CloseCurrentPopup(ctx) + end + _, FILTER = r.ImGui_InputText(ctx, '##input', FILTER) local filtered_fx = Filter_actions(FILTER) + ADDFX_Sel_Entry = SetMinMax(ADDFX_Sel_Entry or 1, 1, #filtered_fx) filter_h = #filtered_fx == 0 and 60 or (#filtered_fx > 40 and 20 * 17 or (17 * #filtered_fx) + 55) - - if r.ImGui_BeginChild(ctx, "aaaaa") then - -- DANCING AROUND SOME LIMITATIONS OF SELECTING CHILDS - if r.ImGui_IsKeyPressed(ctx, r.ImGui_Key_DownArrow()) then - if not ALLOW_IN_LIST then ALLOW_IN_LIST = true end - end - for i = 1, #filtered_fx do - AllowChildFocus(i) - r.ImGui_PushID(ctx, i) - if r.ImGui_Selectable(ctx, filtered_fx[i].name, true, nil, MAX_FX_SIZE) then - AddFxToTracks(filtered_fx[i].name) - end - r.ImGui_PopID(ctx) - end - r.ImGui_EndChild(ctx) - end + + if r.ImGui_BeginChild(ctx, "aaaaa") then + for i = 1, #filtered_fx do + r.ImGui_PushID(ctx, i) + if r.ImGui_Selectable(ctx, filtered_fx[i].name, i == ADDFX_Sel_Entry, nil, MAX_FX_SIZE) then + AddFxToTracks(filtered_fx[i].name) + end + r.ImGui_PopID(ctx) + if i == ADDFX_Sel_Entry then + scroll(scroll_pos) + end + end + if r.ImGui_IsKeyPressed(ctx, r.ImGui_Key_Enter()) then + AddFxToTracks(filtered_fx[ADDFX_Sel_Entry].name) + ADDFX_Sel_Entry = nil + elseif r.ImGui_IsKeyPressed(ctx, r.ImGui_Key_UpArrow()) then + ADDFX_Sel_Entry = ADDFX_Sel_Entry - 1 + elseif r.ImGui_IsKeyPressed(ctx, r.ImGui_Key_DownArrow()) then + ADDFX_Sel_Entry = ADDFX_Sel_Entry + 1 + end + r.ImGui_EndChild(ctx) + end + + r.ImGui_EndPopup(ctx) r.defer(FilterBox) end @@ -217,4 +251,4 @@ local function loop() FilterBox() end -r.defer(loop) +r.defer(loop) \ No newline at end of file From 1dc3a0e013efe9b4e2afaa47af2f84eca2e7a644 Mon Sep 17 00:00:00 2001 From: Christian Fillion Date: Mon, 29 Jul 2024 10:37:17 -0400 Subject: [PATCH 3/6] s/1.21/1.2.1/ --- FX/sexan_Lil FX Slot Homie.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FX/sexan_Lil FX Slot Homie.lua b/FX/sexan_Lil FX Slot Homie.lua index 85cee8d1f..1a556b1df 100644 --- a/FX/sexan_Lil FX Slot Homie.lua +++ b/FX/sexan_Lil FX Slot Homie.lua @@ -1,6 +1,6 @@ -- @description Lil FX Slot Homie -- @author Sexan --- @version 1.21 +-- @version 1.2.1 -- @link https://forum.cockos.com/showthread.php?p=2680992#post2680992 -- @changelog -- Scroll to selected items if they are not in view @@ -251,4 +251,4 @@ local function loop() FilterBox() end -r.defer(loop) \ No newline at end of file +r.defer(loop) From a3b9b32c31c0024b4f9fdfd35dcedc185fbad299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Goran=20Kova=C4=8D?= Date: Thu, 26 Sep 2024 10:56:26 +0200 Subject: [PATCH 4/6] -- version 1.01 -- changelog -- Removed IsRectVisible optiomization (not doing much but introduceds other problems) --- Tracks/reapertips_Track icon selector.lua | 42 +++++++++++------------ 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/Tracks/reapertips_Track icon selector.lua b/Tracks/reapertips_Track icon selector.lua index 7f3227105..05409f021 100644 --- a/Tracks/reapertips_Track icon selector.lua +++ b/Tracks/reapertips_Track icon selector.lua @@ -1,6 +1,8 @@ -- @description Track icon selector -- @author Reapertips & Sexan --- @version 1.0 +-- @version 1.01 +-- @changelog +-- Removed IsRectVisible optiomization (not doing much but introduceds other problems) -- @screenshot -- https://i.imgur.com/bFK2HYk.png -- https://i.imgur.com/MabMOW1.png @@ -283,33 +285,29 @@ local function PngSelector(button_size) local xx, yy = imgui.GetCursorPos(ctx) imgui.PushID(ctx, n) - imgui.Dummy(ctx, button_size, button_size) -- PLACE HOLDER - - local minx, miny = imgui.GetItemRectMin(ctx) - local maxx, maxy = imgui.GetItemRectMax(ctx) - if imgui.IsRectVisibleEx(ctx, minx, miny, maxx, maxy) then - if not imgui.ValidatePtr(FILTERED_PNG[n + 1].img_obj, 'ImGui_Image*') then - FILTERED_PNG[n + 1].img_obj = imgui.CreateImage(image) - end + if not imgui.ValidatePtr(FILTERED_PNG[n + 1].img_obj, 'ImGui_Image*') then + FILTERED_PNG[n + 1].img_obj = imgui.CreateImage(image) + end - imgui.SetCursorPos(ctx, xx, yy) + imgui.SetCursorPos(ctx, xx, yy) - if imgui.ImageButton(ctx, "##png_select", FILTERED_PNG[n + 1].img_obj, button_size, button_size, 0, 0, 1, 1) then - for i = 1, #TRACKS do - r.GetSetMediaTrackInfo_String(TRACKS[i], "P_ICON", image, true) - end - if QUIT_ON_SELECT then - WANT_CLOSE = true - end - LAST_ICON = image - CUR_ICON = image + if imgui.ImageButton(ctx, "##png_select", FILTERED_PNG[n + 1].img_obj, button_size, button_size, 0, 0, 1, 1) then + for i = 1, #TRACKS do + r.GetSetMediaTrackInfo_String(TRACKS[i], "P_ICON", image, true) end - - if imgui.IsItemHovered(ctx) and TOOLTIPS then - DrawTooltips(stripped_name) + if QUIT_ON_SELECT then + WANT_CLOSE = true end + LAST_ICON = image + CUR_ICON = image + end + + if imgui.IsItemHovered(ctx) and TOOLTIPS then + DrawTooltips(stripped_name) end + local minx, miny = imgui.GetItemRectMin(ctx) + local maxx, maxy = imgui.GetItemRectMax(ctx) if CUR_ICON == image then if LAST_ICON ~= CUR_ICON then SCROLL_TO_IMG = true From 3b298fe77f9659f58f381c3a38844c6584f52dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Goran=20Kova=C4=8D?= Date: Fri, 27 Sep 2024 19:39:16 +0200 Subject: [PATCH 5/6] -- version 1.02 -- changelog -- Fix highlighted button draw oversized width and height --- Tracks/reapertips_Track icon selector.lua | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Tracks/reapertips_Track icon selector.lua b/Tracks/reapertips_Track icon selector.lua index 05409f021..1ac76876b 100644 --- a/Tracks/reapertips_Track icon selector.lua +++ b/Tracks/reapertips_Track icon selector.lua @@ -1,8 +1,8 @@ -- @description Track icon selector -- @author Reapertips & Sexan --- @version 1.01 +-- @version 1.02 -- @changelog --- Removed IsRectVisible optiomization (not doing much but introduceds other problems) +-- Fix highlighted button draw oversized width and height -- @screenshot -- https://i.imgur.com/bFK2HYk.png -- https://i.imgur.com/MabMOW1.png @@ -282,15 +282,12 @@ local function PngSelector(button_size) for n = 0, #FILTERED_PNG - 1 do local image = FILTERED_PNG[n + 1].name local stripped_name = FILTERED_PNG[n + 1].short_name - local xx, yy = imgui.GetCursorPos(ctx) imgui.PushID(ctx, n) if not imgui.ValidatePtr(FILTERED_PNG[n + 1].img_obj, 'ImGui_Image*') then FILTERED_PNG[n + 1].img_obj = imgui.CreateImage(image) end - imgui.SetCursorPos(ctx, xx, yy) - if imgui.ImageButton(ctx, "##png_select", FILTERED_PNG[n + 1].img_obj, button_size, button_size, 0, 0, 1, 1) then for i = 1, #TRACKS do r.GetSetMediaTrackInfo_String(TRACKS[i], "P_ICON", image, true) @@ -313,7 +310,7 @@ local function PngSelector(button_size) SCROLL_TO_IMG = true LAST_ICON = CUR_ICON end - imgui.DrawList_AddRect(DRAW_LIST, minx, miny, maxx + (padding*2), maxy + padding*2, COLORS["outline_col"], 0, 0, 2) + imgui.DrawList_AddRect(DRAW_LIST, minx, miny, maxx, maxy, COLORS["outline_col"], 0, 0, 2) if SCROLL_TO_IMG then SCROLL_TO_IMG = nil imgui.SetScrollHereY(ctx) From 7b16705055e36629a75d3d41e9af3169f6e0f368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Goran=20Kova=C4=8D?= Date: Mon, 30 Sep 2024 21:10:04 +0200 Subject: [PATCH 6/6] -- version 1.03 -- changelog -- Add dir entry to table 0 index (All icons) -- Tweak Panel All Icons position a bit -- Panel size is determined by largest folder name -- Rework/Optimize size slider (cpu was hitting 10% while slider was held) -- Show all icons if no track is selected -- Focus search input on script start -- Fix path issue on linux (double slashes) -- Store current size into exstate -- Add option to close the script when ESC is released (on by default) -- Added images/icons for Panel/Menu, Reset/Remove icon from track -- Added Drag and drop support (can only be single track TCP or MCP) -- Added Undo Points on icon change/remove -- Added CTRL+Z shortcut passthrough to reaper --- Tracks/reapertips_Track icon selector.lua | 239 ++++++++++++------- Tracks/reatips_Track icon selector/Menu.png | Bin 0 -> 226 bytes Tracks/reatips_Track icon selector/Reset.png | Bin 0 -> 451 bytes 3 files changed, 154 insertions(+), 85 deletions(-) create mode 100644 Tracks/reatips_Track icon selector/Menu.png create mode 100644 Tracks/reatips_Track icon selector/Reset.png diff --git a/Tracks/reapertips_Track icon selector.lua b/Tracks/reapertips_Track icon selector.lua index 1ac76876b..e10987221 100644 --- a/Tracks/reapertips_Track icon selector.lua +++ b/Tracks/reapertips_Track icon selector.lua @@ -1,8 +1,22 @@ -- @description Track icon selector -- @author Reapertips & Sexan --- @version 1.02 +-- @version 1.03 -- @changelog --- Fix highlighted button draw oversized width and height +-- Add dir entry to table 0 index (All icons) +-- Tweak Panel All Icons position a bit +-- Panel size is determined by largest folder name +-- Rework/Optimize size slider (cpu was hitting 10% while slider was held) +-- Show all icons if no track is selected +-- Focus search input on script start +-- Fix path issue on linux (double slashes) +-- Store current size into exstate +-- Add option to close the script when ESC is released (on by default) +-- Added images/icons for Panel/Menu, Reset/Remove icon from track +-- Added Drag and drop support (can only be single track TCP or MCP) +-- Added Undo Points on icon change/remove +-- Added CTRL+Z shortcut passthrough to reaper +-- @provides +-- reatips_Track icon selector/*.png -- @screenshot -- https://i.imgur.com/bFK2HYk.png -- https://i.imgur.com/MabMOW1.png @@ -37,13 +51,15 @@ if not reaper.ImGui_GetBuiltinPath then return end -local r = reaper -package.path = r.ImGui_GetBuiltinPath() .. '/?.lua' -local os_separator = package.config:sub(1, 1) -local imgui = require "imgui" "0.9.1" -local reaper_path = r.GetResourcePath() +local r = reaper +package.path = reaper.ImGui_GetBuiltinPath() .. '/?.lua' +local getinfo = debug.getinfo(1, 'S'); +local script_path = getinfo.source:match [[^@?(.*[\/])[^\/]-$]]; +local os_separator = package.config:sub(1, 1) +local imgui = require "imgui" "0.9.3" +local reaper_path = r.GetResourcePath() -local COLORS = { +local COLORS = { ["win_bg"] = 0x282828ff, ["sidebar_col"] = 0x2c2c2cff, ["hover_col"] = 0x3c6191ff, @@ -55,7 +71,10 @@ local COLORS = { local ALWAYS_SHOW_CATEGORIES = false local QUIT_ON_SELECT = false local TOOLTIPS = true -local SIDE_WIDTH = 100 +local ESC_TO_QUIT = true +local CURRENT_ZOOM = 1 +local WANT_FOCUS = true + function StringToTable(str) local f, err = load("return " .. str) @@ -75,8 +94,9 @@ if r.HasExtState("TRACK_ICONS4", "STORED_DATA") then COLORS["outline_col"] = storedTable.outline_col ALWAYS_SHOW_CATEGORIES = storedTable.ALWAYS_SHOW_CATEGORIES QUIT_ON_SELECT = storedTable.QUIT_ON_SELECT + ESC_TO_QUIT = storedTable.ESC_TO_QUIT ~= nil and storedTable.ESC_TO_QUIT or ESC_TO_QUIT TOOLTIPS = storedTable.TOOLTIPS - SIDE_WIDTH = storedTable.SIDE_WIDTH + CURRENT_ZOOM = storedTable.CURRENT_ZOOM ~= nil and tonumber(storedTable.CURRENT_ZOOM) or CURRENT_ZOOM end end end @@ -84,7 +104,7 @@ end local OPEN_CATEGORIES = ALWAYS_SHOW_CATEGORIES local MAIN_PNG_TBL = { - [0] = {} + [0] = { dir = "All Icons" } } local FILTERED_PNG @@ -99,7 +119,14 @@ local FLT_MIN, FLT_MAX = imgui.NumericLimits_Float() local SYSTEM_FONT_FACTORY = imgui.CreateFont('sans-serif', 12, imgui.FontFlags_Bold) imgui.Attach(ctx, SYSTEM_FONT_FACTORY) -local png_path_track_icons = "/Data/track_icons/" +local menu_png_path = script_path .. "/reatips_Track icon selector/Menu.png" +local rest_png_path = script_path .. "/reatips_Track icon selector/Reset.png" +local menu_icon = imgui.CreateImage(menu_png_path) +local reset_icon = imgui.CreateImage(rest_png_path) +imgui.Attach(ctx, menu_icon) +imgui.Attach(ctx, reset_icon) + +local png_path_track_icons = "/Data/track_icons" function SerializeTable(val, name, skipnewlines, depth) skipnewlines = skipnewlines or false @@ -141,7 +168,10 @@ local function GetDirFilesRecursive(dir, tbl, filter) local path = r.EnumerateSubdirectories(dir, index) if not path then break end tbl[#tbl + 1] = { dir = path, {} } - GetDirFilesRecursive(dir .. path, tbl[#tbl], filter) + GetDirFilesRecursive(dir .. os_separator .. path, tbl[#tbl], filter) + if #tbl[#tbl] == 0 then + tbl[#tbl] = nil + end end for index = 0, math.huge do @@ -149,14 +179,23 @@ local function GetDirFilesRecursive(dir, tbl, filter) if not file then break end if file:find(filter, nil, true) then tbl[#tbl + 1] = { name = dir .. os_separator .. file, short_name = file } - table.insert(MAIN_PNG_TBL[0], { name = dir .. os_separator .. file, short_name = file}) + table.insert(MAIN_PNG_TBL[0], { name = dir .. os_separator .. file, short_name = file }) end end end GetDirFilesRecursive(reaper_path .. png_path_track_icons, MAIN_PNG_TBL, ".png") +local largest_name = 0 for i = 0, #MAIN_PNG_TBL do - table.sort(MAIN_PNG_TBL[i], function(a, b) if a.name and b.name then return a.name:lower() < b.name:lower() end end) + if MAIN_PNG_TBL[i].dir then + local cur_size = imgui.CalcTextSize(ctx, MAIN_PNG_TBL[i].dir) + largest_name = cur_size > largest_name and cur_size or largest_name + end + table.sort(MAIN_PNG_TBL[i], + function(a, b) + if a.name and b.name then return a.name:lower() < b.name:lower() end + return false + end) end local function RefreshImgObj() @@ -194,15 +233,6 @@ local function FilterActions(actions, filter_text) return t end -local function SteppedSliderDouble(label, val, v_min, v_max, step, format, flags) - local changed, value = imgui.SliderDouble(ctx, label, val, v_min, v_max, format, flags) - if changed then - value = math.floor((value / step) + 0.5) * step - NEED_REFRESH = true - end - return changed, value -end - local function DrawTooltips(str) if imgui.BeginTooltip(ctx) then imgui.Text(ctx, str) @@ -212,10 +242,8 @@ end local PNG_FILTER = '' local cur_category = 0 -local sl_val = 1 local function PngSelector(button_size) local ww = imgui.GetWindowSize(ctx) - local padding = imgui.GetStyleVar(ctx, imgui.StyleVar_FramePadding) imgui.PushStyleColor(ctx, imgui.Col_Text, COLORS["text_active"]) imgui.PushStyleColor(ctx, imgui.Col_ChildBg, COLORS["win_bg"]) @@ -223,11 +251,12 @@ local function PngSelector(button_size) imgui.PushStyleColor(ctx, imgui.Col_FrameBg, COLORS["sidebar_col"]) imgui.BeginGroup(ctx) - if imgui.Button(ctx, "||") then + if imgui.ImageButton(ctx, "menu_icon", menu_icon, 12, 12) then OPEN_CATEGORIES = not OPEN_CATEGORIES end - if imgui.IsPopupOpen(ctx,"R_CTX") then + imgui.SameLine(ctx) + if imgui.IsPopupOpen(ctx, "R_CTX") then local minx, miny = imgui.GetItemRectMin(ctx) local maxx, maxy = imgui.GetItemRectMax(ctx) imgui.DrawList_AddRect(DRAW_LIST, minx, miny, maxx, maxy, COLORS["outline_col"], 0, 0, 2) @@ -239,19 +268,39 @@ local function PngSelector(button_size) imgui.OpenPopup(ctx, "R_CTX") end end + if imgui.ImageButton(ctx, "reset_icon", reset_icon, 12, 12) then + if #TRACKS > 0 then + r.Undo_BeginBlock2(nil) + for i = 1, #TRACKS do + r.GetSetMediaTrackInfo_String(TRACKS[i], "P_ICON", "", true) + end + r.Undo_EndBlock2(nil, "Removed Track Icon", 1) + end + end + + if imgui.IsItemHovered(ctx) then + DrawTooltips("Remove Track Icon") + end imgui.SameLine(ctx) imgui.SetNextItemWidth(ctx, 50) - RV_SLD, sl_val = SteppedSliderDouble("Size ", sl_val, 1, 3, 0.25, "") - button_size = button_size * sl_val + RV_SLD, CURRENT_ZOOM = imgui.SliderInt(ctx, "Size\t", CURRENT_ZOOM, 1, 5, "") + if RV_SLD then + SaveSettings() + end + button_size = button_size * (CURRENT_ZOOM == 1 and 1 or CURRENT_ZOOM / 1.5) if imgui.IsItemHovered(ctx) and not imgui.IsItemActive(ctx) then DrawTooltips("Increase/Decrease Icon Size") end - if not OPEN_CATEGORIES and ww > 250 or (OPEN_CATEGORIES and ww > (SIDE_WIDTH+250)) then + if not OPEN_CATEGORIES and ww > largest_name or (OPEN_CATEGORIES and ww > (largest_name)) then imgui.SameLine(ctx, 0, 0) end imgui.SetNextItemWidth(ctx, -FLT_MIN - 15) + if WANT_FOCUS then + imgui.SetKeyboardFocusHere(ctx) + WANT_FOCUS = nil + end RV_F, PNG_FILTER = imgui.InputTextWithHint(ctx, "##input2", "Search Icons", PNG_FILTER) imgui.SameLine(ctx, 0, 0) @@ -289,14 +338,23 @@ local function PngSelector(button_size) end if imgui.ImageButton(ctx, "##png_select", FILTERED_PNG[n + 1].img_obj, button_size, button_size, 0, 0, 1, 1) then - for i = 1, #TRACKS do - r.GetSetMediaTrackInfo_String(TRACKS[i], "P_ICON", image, true) - end - if QUIT_ON_SELECT then - WANT_CLOSE = true + if #TRACKS > 0 then + r.Undo_BeginBlock2(nil) + for i = 1, #TRACKS do + r.GetSetMediaTrackInfo_String(TRACKS[i], "P_ICON", image, true) + end + r.Undo_EndBlock2(nil, "Changed Track Icon", 1) + if QUIT_ON_SELECT then + WANT_CLOSE = true + end + LAST_ICON = image + CUR_ICON = image end - LAST_ICON = image - CUR_ICON = image + end + if imgui.IsItemActive(ctx) and imgui.IsMouseDragging(ctx, 0) and imgui.BeginDragDropSource(ctx) then + imgui.Image(ctx, FILTERED_PNG[n + 1].img_obj, button_size, button_size) + dnd_image = image + imgui.EndDragDropSource(ctx) end if imgui.IsItemHovered(ctx) and TOOLTIPS then @@ -304,7 +362,7 @@ local function PngSelector(button_size) end local minx, miny = imgui.GetItemRectMin(ctx) - local maxx, maxy = imgui.GetItemRectMax(ctx) + local maxx, maxy = imgui.GetItemRectMax(ctx) if CUR_ICON == image then if LAST_ICON ~= CUR_ICON then SCROLL_TO_IMG = true @@ -317,6 +375,7 @@ local function PngSelector(button_size) end end + local next_button_x2 = maxx + item_spacing_x + button_size if n + 1 < buttons_count and next_button_x2 < window_visible_x2 then @@ -330,14 +389,25 @@ local function PngSelector(button_size) imgui.PopStyleVar(ctx) imgui.PopStyleColor(ctx, 5) imgui.EndGroup(ctx) + + if imgui.IsMouseReleased(ctx, 0) and dnd_image then + local rv_track, info = r.GetThingFromPoint(r.GetMousePosition()) + if rv_track and info:find("tcp") or info:find("mcp") then + r.Undo_BeginBlock2(nil) + r.GetSetMediaTrackInfo_String(rv_track, "P_ICON", dnd_image, true) + r.Undo_EndBlock2(nil, "Changed Track Icon", 1) + end + dnd_image = nil + end end local function Categories() local item_spacing_x = imgui.GetStyleVar(ctx, imgui.StyleVar_ItemSpacing) - + --local padding = imgui.GetStyleVar(ctx, imgui.StyleVar_FramePadding) imgui.PushStyleVar(ctx, imgui.StyleVar_ItemSpacing, item_spacing_x, 20) imgui.PushStyleColor(ctx, imgui.Col_ChildBg, COLORS["sidebar_col"]) - if imgui.BeginChild(ctx, "PM_INSPECTOR", SIDE_WIDTH) then + if imgui.BeginChild(ctx, "PM_INSPECTOR", largest_name) then + imgui.SetCursorPosY(ctx, imgui.GetCursorPosY(ctx) + 8) for i = 0, #MAIN_PNG_TBL do if i ~= PREV_CATEGORY then if MAIN_PNG_TBL[i].sel then @@ -348,21 +418,12 @@ local function Categories() else imgui.PushStyleColor(ctx, imgui.Col_Text, COLORS["text_active"]) end - if i == 0 then - imgui.SetCursorPosY(ctx, imgui.GetCursorPosY(ctx) + 10) - if imgui.Selectable(ctx, " All Icons", cur_category == 0, nil) then - cur_category = 0 + if MAIN_PNG_TBL[i].dir then + if imgui.Selectable(ctx, " " .. MAIN_PNG_TBL[i].dir, cur_category == i, nil) then + cur_category = i NEED_REFRESH = true old_filter = nil end - else - if MAIN_PNG_TBL[i].dir then - if imgui.Selectable(ctx, " " .. MAIN_PNG_TBL[i].dir, cur_category == i, nil) then - cur_category = i - NEED_REFRESH = true - old_filter = nil - end - end end if imgui.IsItemHovered(ctx) then MAIN_PNG_TBL[i].sel = true @@ -388,7 +449,7 @@ local function Categories() imgui.PopStyleColor(ctx) end -local function SaveSettings() +function SaveSettings() local data = TableToString({ win_col = COLORS["win_bg"], win_col_alt = COLORS["win_bg_alt"], @@ -399,8 +460,9 @@ local function SaveSettings() text_inactive = COLORS["text_inactive"], ALWAYS_SHOW_CATEGORIES = ALWAYS_SHOW_CATEGORIES, QUIT_ON_SELECT = QUIT_ON_SELECT, + ESC_TO_QUIT = ESC_TO_QUIT, TOOLTIPS = TOOLTIPS, - SIDE_WIDTH = SIDE_WIDTH, + CURRENT_ZOOM = CURRENT_ZOOM }) r.SetExtState("TRACK_ICONS4", "STORED_DATA", data, true) end @@ -409,20 +471,19 @@ local function DrawRClickCtx() if imgui.BeginPopup(ctx, "R_CTX") then if imgui.BeginMenu(ctx, "Customize") then local RV_UPDATED - RV_COL1, COLORS["win_bg"] = r.ImGui_ColorEdit4(ctx, "Primary background color", COLORS["win_bg"], - r.ImGui_ColorEditFlags_NoInputs()) - RV_COL2, COLORS["sidebar_col"] = r.ImGui_ColorEdit4(ctx, "Secondary background color", COLORS["sidebar_col"], - r.ImGui_ColorEditFlags_NoInputs()) - RV_COL3, COLORS["hover_col"] = r.ImGui_ColorEdit4(ctx, "Hover icon color", COLORS["hover_col"], - r.ImGui_ColorEditFlags_NoInputs()) - RV_COL4, COLORS["outline_col"] = r.ImGui_ColorEdit4(ctx, "Selected outline color", COLORS["outline_col"], - r.ImGui_ColorEditFlags_NoInputs()) - RV_COL5, COLORS["text_active"] = r.ImGui_ColorEdit4(ctx, "Text active color", COLORS["text_active"], - r.ImGui_ColorEditFlags_NoInputs()) - RV_COL6, COLORS["text_inactive"] = r.ImGui_ColorEdit4(ctx, "Text Inactive color", COLORS["text_inactive"], - r.ImGui_ColorEditFlags_NoInputs()) - RV_COL7, SIDE_WIDTH = imgui.SliderInt( ctx, "Side panel width", SIDE_WIDTH, 80, 200) - if RV_COL1 or RV_COL2 or RV_COL3 or RV_COL4 or RV_COL5 or RV_COL6 or RV_COL7 then + RV_COL1, COLORS["win_bg"] = imgui.ColorEdit4(ctx, "Primary background color", COLORS["win_bg"], + imgui.ColorEditFlags_NoInputs) + RV_COL2, COLORS["sidebar_col"] = imgui.ColorEdit4(ctx, "Secondary background color", COLORS["sidebar_col"], + imgui.ColorEditFlags_NoInputs) + RV_COL3, COLORS["hover_col"] = imgui.ColorEdit4(ctx, "Hover icon color", COLORS["hover_col"], + imgui.ColorEditFlags_NoInputs) + RV_COL4, COLORS["outline_col"] = imgui.ColorEdit4(ctx, "Selected outline color", COLORS["outline_col"], + imgui.ColorEditFlags_NoInputs) + RV_COL5, COLORS["text_active"] = imgui.ColorEdit4(ctx, "Text active color", COLORS["text_active"], + imgui.ColorEditFlags_NoInputs) + RV_COL6, COLORS["text_inactive"] = imgui.ColorEdit4(ctx, "Text Inactive color", COLORS["text_inactive"], + imgui.ColorEditFlags_NoInputs) + if RV_COL1 or RV_COL2 or RV_COL3 or RV_COL4 or RV_COL5 or RV_COL6 then RV_UPDATED = true end if imgui.MenuItem(ctx, "Reset to Default", nil) then @@ -432,7 +493,6 @@ local function DrawRClickCtx() COLORS["outline_col"] = 0xffcb40ff COLORS["text_active"] = 0xf1f2f2ff COLORS["text_inactive"] = 0x999B9Fff - SIDE_WIDTH = 100 SaveSettings() end if RV_UPDATED then @@ -449,6 +509,10 @@ local function DrawRClickCtx() QUIT_ON_SELECT = not QUIT_ON_SELECT SaveSettings() end + if imgui.MenuItem(ctx, "Quit after pressing ESC", nil, ESC_TO_QUIT == true) then + ESC_TO_QUIT = not ESC_TO_QUIT + SaveSettings() + end if imgui.MenuItem(ctx, "Show file name on icon hover", nil, TOOLTIPS == true) then TOOLTIPS = not TOOLTIPS SaveSettings() @@ -471,6 +535,16 @@ local function PushTheme() imgui.PushStyleColor(ctx, imgui.Col_ScrollbarBg, COLORS["win_bg"]) end +local function CheckKeys() + ESC = imgui.IsKeyReleased(ctx, imgui.Key_Escape) + CTRL = imgui.GetKeyMods(ctx) == imgui.Mod_Ctrl + Z = imgui.IsKeyPressed(ctx, imgui.Key_Z) + if ESC and ESC_TO_QUIT then WANT_CLOSE = true end + if CTRL and Z then + r.Main_OnCommand(40029, 0) + end +end + imgui.SetNextWindowSizeConstraints(ctx, WND_H, WND_W, FLT_MAX, FLT_MAX) local function main() if SET_DOCK_ID then @@ -487,26 +561,21 @@ local function main() local visible, p_open = imgui.Begin(ctx, 'Track Icons', true) imgui.PopStyleColor(ctx, 2) if visible then + CheckKeys() imgui.PushFont(ctx, SYSTEM_FONT_FACTORY) PushTheme() DRAW_LIST = imgui.GetWindowDrawList(ctx) - if #TRACKS ~= 0 then - if #TRACKS == 1 then - RV_I, CUR_ICON = r.GetSetMediaTrackInfo_String(TRACKS[1], "P_ICON", "", false) - else - CUR_ICON = nil - end - if OPEN_CATEGORIES then - Categories() - imgui.SameLine(ctx) - end - PngSelector(icon_size) - DrawRClickCtx() + if #TRACKS == 1 then + RV_I, CUR_ICON = r.GetSetMediaTrackInfo_String(TRACKS[1], "P_ICON", "", false) else - LAST_ICON = nil - NEED_REFRESH = true - imgui.Text(ctx, "SELECT TRACK") + CUR_ICON = nil + end + if OPEN_CATEGORIES then + Categories() + imgui.SameLine(ctx) end + PngSelector(icon_size) + DrawRClickCtx() imgui.PopStyleColor(ctx, 3) imgui.PopFont(ctx) imgui.End(ctx) diff --git a/Tracks/reatips_Track icon selector/Menu.png b/Tracks/reatips_Track icon selector/Menu.png new file mode 100644 index 0000000000000000000000000000000000000000..cbf5855599e0d9820a73b092ab841beab68efa1b GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-1!HlL zyA#8@b22Z19F}xPUq=Rpjs4tz5?O)#a!(h>kP61Py$3lDCRu4B|iWa!{ Q59kC2Pgg&ebxsLQ0FApxU;qFB literal 0 HcmV?d00001 diff --git a/Tracks/reatips_Track icon selector/Reset.png b/Tracks/reatips_Track icon selector/Reset.png new file mode 100644 index 0000000000000000000000000000000000000000..91e9d675b5fa26b82d43671d7be43dd618c067bd GIT binary patch literal 451 zcmV;!0X+VRP)}~L zWZC$$e-AzzgHaU4ebY40B4W$DDp6u1P18>_9J!9FMGyCV-;f!F8}Crrrd(M!1FaTA zLAApw%d*z4>sIISEX&@zu5++K+)IoxPq3`(`sok&E8r{LI272Hc)T}@IAqOe-H!_sy$sm(1Y*6&=H`Hjyuulc3f-4 tkN%g;|3}fQG_eIA