From e347e4e75a78dac49bad71d28379f32740954287 Mon Sep 17 00:00:00 2001 From: BenTalagan Date: Wed, 18 Dec 2024 11:07:36 +0100 Subject: [PATCH] Update Docking Tools v0.1 > v0.2 --- View/talagan_Docking tools.lua | 100 +++- ...=> talagan_Generic dock resize action.lua} | 3 +- ...ize dock containing active MIDI Editor.lua | 16 - .../talagan_Minimize bottommost dock.lua | 16 - ...ize dock containing active MIDI Editor.lua | 16 - ...lagan_Set bottommost dock height (500).lua | 19 - ...aining active MIDI Editor height (500).lua | 19 - View/talagan_Docking tools/docking_lib.lua | 484 +++++++++++++----- 8 files changed, 443 insertions(+), 230 deletions(-) rename View/talagan_Docking tools/actions/{talagan_Maximize bottommost dock.lua => talagan_Generic dock resize action.lua} (87%) delete mode 100644 View/talagan_Docking tools/actions/talagan_Maximize dock containing active MIDI Editor.lua delete mode 100644 View/talagan_Docking tools/actions/talagan_Minimize bottommost dock.lua delete mode 100644 View/talagan_Docking tools/actions/talagan_Minimize dock containing active MIDI Editor.lua delete mode 100644 View/talagan_Docking tools/actions/talagan_Set bottommost dock height (500).lua delete mode 100644 View/talagan_Docking tools/actions/talagan_Set dock containing active MIDI Editor height (500).lua diff --git a/View/talagan_Docking tools.lua b/View/talagan_Docking tools.lua index fd60b915f..96a0f0643 100644 --- a/View/talagan_Docking tools.lua +++ b/View/talagan_Docking tools.lua @@ -1,26 +1,102 @@ --[[ @description Docking tools : actions to resize docks -@version 0.1 +@version 0.2 @author Ben 'Talagan' Babut @donation https://www.paypal.com/donate/?business=3YEZMY9D6U8NC&no_recurring=1¤cy_code=EUR @license MIT +@links + Forum Thread https://forum.cockos.com/showthread.php?t=296531 @metapackage +@changelog + - Added support for all dock positions (left/top/bottom/right) + - New syntax for duplicated action names allow to define conditional heights depending on the dock position + - New syntax for duplicated action names allow to target other widgets than the active MIDI Editor @provides - [main=main] talagan_Docking tools/actions/talagan_Maximize bottommost dock.lua > talagan_Maximize bottommost dock.lua - [main=main] talagan_Docking tools/actions/talagan_Minimize bottommost dock.lua > talagan_Minimize bottommost dock.lua - [main=main] talagan_Docking tools/actions/talagan_Set bottommost dock height (500).lua > talagan_Set bottommost dock height (500).lua - [main=main,midi_editor] talagan_Docking tools/actions/talagan_Maximize dock containing active MIDI Editor.lua > talagan_Maximize dock containing active MIDI Editor.lua - [main=main,midi_editor] talagan_Docking tools/actions/talagan_Minimize dock containing active MIDI Editor.lua > talagan_Minimize dock containing active MIDI Editor.lua - [main=main,midi_editor] talagan_Docking tools/actions/talagan_Set dock containing active MIDI Editor height (500).lua > talagan_Set dock containing active MIDI Editor height (500).lua + + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Set bottommost dock height (500).lua + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Set dock containing active MIDI Editor height (500).lua + + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Maximize dock containing project bay.lua + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Minimize dock containing project bay.lua + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Set dock containing project bay size (500,700,500,700).lua + + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Maximize bottommost dock.lua + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Minimize bottommost dock.lua + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Set bottommost dock size (500).lua + + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Maximize topmost dock.lua + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Minimize topmost dock.lua + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Set topmost dock size (500).lua + + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Maximize rightmost dock.lua + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Minimize rightmost dock.lua + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Set rightmost dock size (500).lua + + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Maximize leftmost dock.lua + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Minimize leftmost dock.lua + [main=main] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Set leftmost dock size (500).lua + + [main=main,midi_editor] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Maximize dock containing active MIDI Editor.lua + [main=main,midi_editor] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Minimize dock containing active MIDI Editor.lua + [main=main,midi_editor] talagan_Docking tools/actions/talagan_Generic dock resize action.lua > talagan_Set dock containing active MIDI Editor size (500).lua + [nomain] talagan_Docking tools/docking_lib.lua -@changelog - - Initial Release @about - This package provide actions to quickly resize the MIDI dock and the bottommost dock (maximize, minimize, or set to custom height). + This package provide actions to quickly resize the docks in REAPER. These actions are meant to be small bricks of bigger custom actions where you perform a reorganisation of the UI (e.g. use FTC's scrolling scripts for the MIDI editor). - You can copy / paste the "... (500).lua" action files and modify their name to put a custom height instead of 500. + All actions in this package are duplicates of the same one, with a different name that will decide of it's behaviour. The syntax of the name should be one of the following : + + - Maximize A_DOCK.lua + - Minimize A_DOCK.lua + - Set A_DOCK size (SIZES).lua + + A_DOCK can be either : + + - DIRMOST dock + - dock containing A_WIDGET + + DIRMOST can be one of the following : + + - leftmost + - rightmost + - bottommost + - topmost + + A_WIDGET can be one of the following : + + - active MIDI Editor + - Mixer + - Project Bay + - Media Explorer + - Track Manager + - Track Group Manager + - Take Properties + - Undo History + - Envelope Manager + - Routing Matrix + - Track Grouping Matrix + - Track Wiring Diagram + - Region Render Matrix + - FX Browser + - Navigator + - Big Clock + - Performance Meter + + Finally SIZES syntax is one of the following + + - T,R,B,L + - DIM + + T,R,B,L and DIM are either pixel sizes, or "min" or "max" + + If using the first syntax, each value T,R,B or L applies conditionally to the dock depending on its position (top, right, bottom or left). That way you may write, for example, your own "set to big" function that will use custom sizes for you desired "biggest" dock config, wherever the dock is. + + Various actions using this syntax are installed with this package and may be used as an example. + + If you want to add your own custom behaviours, just duplicate one (copy-paste the corresponding file **in the same directory**) and rename it to your will. + - Thanks to @edgemeal for the technical advice / windows support and @X-raym for the code review! + Thanks to @Edgemeal for the technical advice / windows support and @X-raym for the code review! --]] diff --git a/View/talagan_Docking tools/actions/talagan_Maximize bottommost dock.lua b/View/talagan_Docking tools/actions/talagan_Generic dock resize action.lua similarity index 87% rename from View/talagan_Docking tools/actions/talagan_Maximize bottommost dock.lua rename to View/talagan_Docking tools/actions/talagan_Generic dock resize action.lua index 0e7707a59..3874104be 100644 --- a/View/talagan_Docking tools/actions/talagan_Maximize bottommost dock.lua +++ b/View/talagan_Docking tools/actions/talagan_Generic dock resize action.lua @@ -13,4 +13,5 @@ end if not docking_lib.CheckDependencies() then return end -docking_lib.maximizeBottommostDock() +docking_lib.resizeDockFromActionName(debug.getinfo(1,"S").source) + diff --git a/View/talagan_Docking tools/actions/talagan_Maximize dock containing active MIDI Editor.lua b/View/talagan_Docking tools/actions/talagan_Maximize dock containing active MIDI Editor.lua deleted file mode 100644 index 155bd12fe..000000000 --- a/View/talagan_Docking tools/actions/talagan_Maximize dock containing active MIDI Editor.lua +++ /dev/null @@ -1,16 +0,0 @@ --- @noindex --- @author Ben 'Talagan' Babut --- @license MIT --- @description This is part of Talagan Docking Tools - -package.path = debug.getinfo(1,"S").source:match[[^@?(.*[\/])[^\/]-$]] .."?.lua;".. package.path - -local ok, docking_lib = pcall(require, "talagan_Docking tools/docking_lib") -if not ok then - reaper.MB("This script is not well installed. Please install 'Docking tools' with Reapack.","Ouch!",0) - return -end - -if not docking_lib.CheckDependencies() then return end - -docking_lib.maximizeMidiDock() diff --git a/View/talagan_Docking tools/actions/talagan_Minimize bottommost dock.lua b/View/talagan_Docking tools/actions/talagan_Minimize bottommost dock.lua deleted file mode 100644 index 4b496f0e7..000000000 --- a/View/talagan_Docking tools/actions/talagan_Minimize bottommost dock.lua +++ /dev/null @@ -1,16 +0,0 @@ --- @noindex --- @author Ben 'Talagan' Babut --- @license MIT --- @description This is part of Talagan Docking Tools - -package.path = debug.getinfo(1,"S").source:match[[^@?(.*[\/])[^\/]-$]] .."?.lua;".. package.path - -local ok, docking_lib = pcall(require, "talagan_Docking tools/docking_lib") -if not ok then - reaper.MB("This script is not well installed. Please install 'Docking tools' with Reapack.","Ouch!",0) - return -end - -if not docking_lib.CheckDependencies() then return end - -docking_lib.minimizeBottommostDock() diff --git a/View/talagan_Docking tools/actions/talagan_Minimize dock containing active MIDI Editor.lua b/View/talagan_Docking tools/actions/talagan_Minimize dock containing active MIDI Editor.lua deleted file mode 100644 index bb5a66182..000000000 --- a/View/talagan_Docking tools/actions/talagan_Minimize dock containing active MIDI Editor.lua +++ /dev/null @@ -1,16 +0,0 @@ --- @noindex --- @author Ben 'Talagan' Babut --- @license MIT --- @description This is part of Talagan Docking Tools - -package.path = debug.getinfo(1,"S").source:match[[^@?(.*[\/])[^\/]-$]] .."?.lua;".. package.path - -local ok, docking_lib = pcall(require, "talagan_Docking tools/docking_lib") -if not ok then - reaper.MB("This script is not well installed. Please install 'Docking tools' with Reapack.","Ouch!",0) - return -end - -if not docking_lib.CheckDependencies() then return end - -docking_lib.minimizeMidiDock() diff --git a/View/talagan_Docking tools/actions/talagan_Set bottommost dock height (500).lua b/View/talagan_Docking tools/actions/talagan_Set bottommost dock height (500).lua deleted file mode 100644 index 4a93dc1a0..000000000 --- a/View/talagan_Docking tools/actions/talagan_Set bottommost dock height (500).lua +++ /dev/null @@ -1,19 +0,0 @@ --- @noindex --- @author Ben 'Talagan' Babut --- @license MIT --- @description This is part of Talagan Docking Tools - -package.path = debug.getinfo(1,"S").source:match[[^@?(.*[\/])[^\/]-$]] .."?.lua;".. package.path - -local ok, docking_lib = pcall(require, "talagan_Docking tools/docking_lib") -if not ok then - reaper.MB("This script is not well installed. Please install 'Docking tools' with Reapack.","Ouch!",0) - return -end - -if not docking_lib.CheckDependencies() then return end - -local _, sfname = reaper.get_action_context() -local param = tonumber(sfname.match(sfname,"%((.*)%).lua")) - -docking_lib.resizeBottommostDock(param) diff --git a/View/talagan_Docking tools/actions/talagan_Set dock containing active MIDI Editor height (500).lua b/View/talagan_Docking tools/actions/talagan_Set dock containing active MIDI Editor height (500).lua deleted file mode 100644 index b6ec72e00..000000000 --- a/View/talagan_Docking tools/actions/talagan_Set dock containing active MIDI Editor height (500).lua +++ /dev/null @@ -1,19 +0,0 @@ --- @noindex --- @author Ben 'Talagan' Babut --- @license MIT --- @description This is part of Talagan Docking Tools - -package.path = debug.getinfo(1,"S").source:match[[^@?(.*[\/])[^\/]-$]] .."?.lua;".. package.path - -local ok, docking_lib = pcall(require, "talagan_Docking tools/docking_lib") -if not ok then - reaper.MB("This script is not well installed. Please install 'Docking tools' with Reapack.","Ouch!",0) - return -end - -if not docking_lib.CheckDependencies() then return end - -local _, sfname = reaper.get_action_context() -local param = tonumber(sfname.match(sfname,"%((.*)%).lua")) - -docking_lib.resizeMidiDock(param) diff --git a/View/talagan_Docking tools/docking_lib.lua b/View/talagan_Docking tools/docking_lib.lua index f06ec9bd4..e5970f756 100644 --- a/View/talagan_Docking tools/docking_lib.lua +++ b/View/talagan_Docking tools/docking_lib.lua @@ -20,49 +20,46 @@ local function CheckDependencies() return true end - ------------------------ -DOCK_BOTTOM = 0 -DOCK_FLOATING = 4 - -local function setTimeout(callback, timeout) - local wur = timeout - local wut = reaper.time_precise() - function _wait_ready() - - if reaper.time_precise() - wut < wur then - reaper.defer(_wait_ready) - return - end +local DockableComponents = { + "Mixer", + "Project Bay", + "Media Explorer", + "Track Manager", + "Track Group Manager", + "Take Properties", + "Undo History", + "Envelope Manager", + "Routing Matrix", + "Track Grouping Matrix", + "Track Wiring Diagram", + "Region Render Matrix", + "FX Browser", + "Navigator", + "Big Clock", + "Performance Meter" +} - callback() - end +local DOCK_BOTTOM = 0 +local DOCK_LEFT = 1 +local DOCK_TOP = 2 +local DOCK_RIGHT = 3 - reaper.defer(_wait_ready) -end +local DOCK_FLOATING = 4 --- Thanks to @edgemeal for this technique ! +-- Thanks to @Edgemeal for this technique ! local function JS_LDrag(hwnd, x_start,x_end, y_start,y_end) reaper.JS_WindowMessage_Send(hwnd, "WM_LBUTTONDOWN", 1, 0, x_start, y_start) reaper.JS_WindowMessage_Send(hwnd, "WM_LBUTTONUP", 0, 0, x_end, y_end) end -local function JS_Window_GetTopParent(hwnd) - local p = hwnd; local p2 = hwnd; - while p2 do - p = p2; - p2 = reaper.JS_Window_GetParent(p) - end - return p -end - local function JS_Window_GetBounds(hwnd) local _, left, top, right, bottom = reaper.JS_Window_GetClientRect( hwnd ) - local os = reaper.GetOS() - h = top - bottom + local os = reaper.GetOS() + local h = top - bottom -- Under windows, vertical coordinates are flipped ! if os == "Win32" or os == "Win64" then @@ -72,161 +69,370 @@ local function JS_Window_GetBounds(hwnd) return {hwnd = hwnd, l = left, t = top, r = right, b = bottom, w = (right-left), h = h } end -local function JS_Window_Debug(hwnd) - local bounds = JS_Window_GetBounds(hwnd); - reaper.ShowConsoleMsg("Title : " .. reaper.JS_Window_GetTitle(hwnd) .. "\n"); - reaper.ShowConsoleMsg("Width : " .. bounds.w .. "\n"); - reaper.ShowConsoleMsg("Height : " .. bounds.h .. "\n"); - reaper.ShowConsoleMsg("T,R,B,L : " .. bounds.t .. ", " .. bounds.r .. ", " .. bounds.b .. ", " .. bounds.l .. "\n"); +local function getHwndDock(hwnd) + local p = nil + local dock = nil + + p = reaper.JS_Window_GetParent(hwnd) + while p do + if reaper.JS_Window_GetTitle(p) == "REAPER_dock" then + dock = p + p = nil + else + p = reaper.JS_Window_GetParent(p); + end + end + return dock end -local function findDockerThatContainsWindow(hwnd_to_find) - local c, l = reaper.JS_Window_ListFind("REAPER_dock",true); - for token in string.gmatch(l, "[^,]+") do - local hwnd = reaper.JS_Window_HandleFromAddress(token); - if reaper.JS_Window_IsChild(hwnd, hwnd_to_find) then - return JS_Window_GetBounds(hwnd); +local function dockInfo(dockhwnd) + local did, floating = reaper.DockIsChildOfDock(dockhwnd) + local pos = reaper.DockGetPosition(did) + local bounds = JS_Window_GetBounds(dockhwnd) + + return { + hwnd=dockhwnd, + id=did, + floating=floating, + pos=pos, + bounds=bounds + } +end + +local function findDockThatContainsWindow(hwnd) + local dockhwnd = getHwndDock(hwnd) + if not dockhwnd then return nil end + + return dockInfo(dockhwnd) +end + +local function findDockThatContainsWindowWithTitle(title) + local hwnd = reaper.JS_Window_Find(title,true) + if not hwnd then return nil end + + return findDockThatContainsWindow(hwnd) +end + +local function findDockThatContainsActiveMidiEditor() + local me = reaper.MIDIEditor_GetActive() -- Exists because we found the parent docket + if not me then return end + + return findDockThatContainsWindow(me) +end + +local function findDirmostDock(wanted_dir) + local extrema_dock = nil + local extrema_val = nil + + local comparator = function(cur, ext) + if wanted_dir == DOCK_BOTTOM then return cur < ext end + if wanted_dir == DOCK_RIGHT then return cur < ext end + if wanted_dir == DOCK_TOP then return cur > ext end + if wanted_dir == DOCK_LEFT then return cur > ext end + end + + local ext_coord = function(bnd) + local coord = nil + + if wanted_dir == DOCK_BOTTOM then coord = bnd.b end + if wanted_dir == DOCK_RIGHT then coord = bnd.r end + if wanted_dir == DOCK_TOP then coord = bnd.t end + if wanted_dir == DOCK_LEFT then coord = bnd.l end + + if (os == "Win32" or os == "Win64") and (wanted_dir == DOCK_TOP or wanted_dir == DOCK_BOTTOM ) then + -- Under windows we reverse the bottom bound to have the same ordering logic as on MacOS/Linux + -- (This will be negative but we don't care, we just want to know what's the bottommost dock) + coord = - coord end + + return coord end - return nil; -end -local function findBottommostDock() - local lowest = nil - local blowest = nil + -- Enumerate all docks local c, l = reaper.JS_Window_ListFind("REAPER_dock",true); for token in string.gmatch(l, "[^,]+") do - local hwnd = reaper.JS_Window_HandleFromAddress(token); - local idx,_ = reaper.DockIsChildOfDock(hwnd) - local pos = reaper.DockGetPosition(idx) + local addr = tonumber(token) or 0 + local hwnd = reaper.JS_Window_HandleFromAddress(addr); + local dock = dockInfo(hwnd) -- Don't try to do something on docks that are not docked at the bottom - if pos == DOCK_BOTTOM then - local bounds = JS_Window_GetBounds(hwnd) - - local bot = bounds.b - if os == "Win32" or os == "Win64" then - -- Under windows we reverse the bottom bound to have the same ordering logic as on MacOS/Linux - -- (This will be negative but we don't care, we just want to know what's the bottommost dock) - bot = - bot - end + if dock.pos == wanted_dir and reaper.JS_Window_IsVisible(dock.hwnd) then + local coord = ext_coord(dock.bounds) - if not lowest or bot < blowest then - lowest = bounds - blowest = bot + if not extrema_dock or comparator(coord, extrema_val) then + extrema_dock = dock + extrema_val = coord end end end - if lowest then - return lowest - end + -- May be nil + return extrema_dock +end +local function baseSize(dock) + if dock.pos == DOCK_BOTTOM or dock.pos == DOCK_TOP then + return dock.bounds.h + elseif dock.pos == DOCK_LEFT or dock.pos == DOCK_RIGHT then + return dock.bounds.w + end return nil end -local function findTopWindowThatContainsWindow(hwnd_to_find) - local c, l = reaper.JS_Window_ListAllTop(); - for token in string.gmatch(l, "[^,]+") do - local hwnd = reaper.JS_Window_HandleFromAddress(token); - if reaper.JS_Window_IsChild(hwnd, hwnd_to_find) then - return JS_Window_GetBounds(hwnd); - end +local function resolveWantedSize(dock, sizes) + local size = nil + if dock.pos == DOCK_BOTTOM then + size = sizes.b + elseif dock.pos == DOCK_TOP then + size = sizes.t + elseif dock.pos == DOCK_LEFT then + size = sizes.l + elseif dock.pos == DOCK_RIGHT then + size = sizes.r end - return nil; -end -local function deferredDebugPostCheck() - setTimeout(function() - local redock = JS_Window_GetBounds(dock.hwnd); - if redock.h ~= height then - reaper.ShowConsoleMsg("Requested height : " .. height .. " , but got height " .. redock.h .. "\n") - end - end, 1.0); + if size == 'min' then return 0 end + if size == 'max' then return 10000 end + + return tonumber(size) end -local function safeHeight(dock, height) - -- We need to clamp the requested height so that what we ask - -- will match what's REAPER will be able to do - -- else, at the end of our action subsequent actions will not work on a valid height - -- (they will run on what we have set, but a few cycles later, REAPER - -- will repack the UI, making those adjusments wrong) +local function resizeDock(dock, sizes) - local sheight = height + aaa_sizes = sizes + if not dock then return end - local topw = JS_Window_GetTopParent(dock.hwnd); - local topwbounds = JS_Window_GetBounds(topw); + if type(sizes) == "table" then + -- Ok + elseif type(sizes) == "number" then + local size = sizes + sizes = {b=size,t=size,r=size,l=size} + elseif type(sizes) == "string" then + local size = sizes + sizes = {b=size,t=size,r=size,l=size} + else + error("Type mismatch for argument 'sizes'. Should be a table, a number or a keyword.") + end - -- JS_Window_Debug(topw); + -- Dock should be docked + if not (dock.pos == DOCK_BOTTOM or dock.pos == DOCK_TOP or dock.pos == DOCK_LEFT or dock.pos == DOCK_RIGHT) then return nil end - local maxheight = topwbounds.h - 191; - local minheight = math.min(320, topwbounds.h - 174); + local base_size = baseSize(dock) + local wanted_size = resolveWantedSize(dock, sizes) - -- reaper.ShowConsoleMsg(height .. "\n"); - -- reaper.ShowConsoleMsg(maxheight .. "\n"); - -- reaper.ShowConsoleMsg(minheight .. "\n"); + if not base_size or not wanted_size then return nil end - if sheight > maxheight then - sheight = maxheight; + -- Remember current focus + local focused = reaper.JS_Window_GetFocus(); + + local delta_size = base_size - wanted_size + + -- Drag the resize grip... thanks @Edgemeal for the technique ! + if dock.pos == DOCK_BOTTOM then + JS_LDrag(dock.hwnd, 0, 0, 0, delta_size) + elseif dock.pos == DOCK_TOP then + JS_LDrag(dock.hwnd, 0, 0, base_size, base_size - delta_size) + elseif dock.pos == DOCK_LEFT then + JS_LDrag(dock.hwnd, base_size, base_size - delta_size, 0, 0) + elseif dock.pos == DOCK_RIGHT then + JS_LDrag(dock.hwnd, 0, delta_size, 0, 0) end - if sheight < minheight then - sheight = minheight; - end + -- Restore focus + reaper.JS_Window_SetFocus(focused) +end - -- reaper.ShowConsoleMsg("Safe height : " .. sheight) +local function resizeMidiDock(sizes) + local dock = findDockThatContainsActiveMidiEditor() - return sheight + resizeDock(dock, sizes); end -local function resizeDock(dock, height) +local function resizeDirmostDock(findfunc, sizes) + local dock = findfunc() - -- height = safeHeight(dock, height) - -- reaper.ShowConsoleMsg(height .. "\n"); + resizeDock(dock, sizes) +end - -- Remember current focus - local focused = reaper.JS_Window_GetFocus(); - -- Drag the resize grip... thanks @edgemeal for the technique ! - JS_LDrag(dock.hwnd, 0, 0, 0, dock.h - height) +local function maximizeMidiDock() resizeMidiDock('max') end +local function minimizeMidiDock() resizeMidiDock('min') end - -- Restore focus - reaper.JS_Window_SetFocus(focused); +local function findBottommostDock() return findDirmostDock(DOCK_BOTTOM) end +local function findLeftmostDock() return findDirmostDock(DOCK_LEFT) end +local function findRightmostDock() return findDirmostDock(DOCK_RIGHT) end +local function findTopmostDock() return findDirmostDock(DOCK_TOP) end - -- The next call helps to check if what we requested is what we got - -- use it in debug mode only - -- deferredDebugPostCheck(); -end +local function resizeBottommostDock(sizes) resizeDirmostDock(findBottommostDock, sizes) end +local function maximizeBottommostDock() resizeBottommostDock('max') end +local function minimizeBottommostDock() resizeBottommostDock('min') end --- Exports +local function resizeLeftmostDock(sizes) resizeDirmostDock(findLeftmostDock, sizes) end +local function maximizeLeftmostDock() resizeLeftmostDock('max') end +local function minimizeLeftmmostDock() resizeLeftmostDock('min') end -local function resizeMidiDock(height) - local me = reaper.MIDIEditor_GetActive(); -- Exists because we found the parent docket - if not me then return end +local function resizeRightmostDock(sizes) resizeDirmostDock(findRightmostDock, sizes) end +local function maximizeRightmostDock() resizeRightmostDock('max') end +local function minimizeRightmmostDock() resizeRightmostDock('min') end - local dock = findDockerThatContainsWindow(me); - if not dock then return end +local function resizeTopmostDock(sizes) resizeDirmostDock(findTopmostDock, sizes) end +local function maximizeTopmostDock() resizeTopmostDock('max') end +local function minimizeTopmmostDock() resizeTopmostDock('min') end + +-- All resize functions accept the following values for 'sizes' : + +-- * a table : {t=tsize, l=lsize, r=rsize, b=bsize}, the size will be applied conditionally. +-- * a number : (will be applied to all docking positions) +-- * a string : (will be applied to all docking positions) + +-- Each individual size can be a number or a keyword (only 'min', 'max' are supported) - resizeDock(dock, height); +local function splitString(str, sep) + local result = {} + + for v in string.gmatch(str..sep, '([^'.. sep ..']*)' .. sep) do + table.insert(result, v) + end + + return result end -local function resizeBottommostDock(height) - local dock = findBottommostDock() - if not dock then return end - resizeDock(dock, height) +local function extractSizesFromAction(size_str) + local tokens = splitString(size_str, ',') + + if #tokens == 1 then + return {t=tokens[1], r=tokens[1], b=tokens[1], l=tokens[1] } + elseif #tokens == 4 then + return {t=tokens[1], r=tokens[2], b=tokens[3], l=tokens[4] } + else + error("In action name size string : '" .. size_str .. "'. should pass exactly 1 or 4 parameters separated by comas" ) + end end -local function maximizeMidiDock() resizeMidiDock(10000) end -local function minimizeMidiDock() resizeMidiDock(0) end +local function findDirmostDockFromString(dir) + if dir == 'left' then + return findLeftmostDock() + elseif dir == 'right' then + return findRightmostDock() + elseif dir == 'top' then + return findTopmostDock() + elseif dir == 'bottom' then + return findBottommostDock() + else + error("In action name, dirmost dock '" .. dir .. "' does not exist.") + end +end + +local function findContainerDockFromString(dstr) + if dstr == 'active midi editor' then + return findDockThatContainsActiveMidiEditor() + elseif dstr then + for _, s in ipairs(DockableComponents) do + if string.lower(s) == dstr then + return findDockThatContainsWindowWithTitle(s) + end + end + return nil + end +end + +local function resizeDockFromActionName(filename) + + local s, e, dir, cnt, sizes + + local rxdir = "talagan_Set (%a+)most dock size %((.+)%)%.lua" + s, e, dir, sizes = string.find(filename, rxdir) + if s then + local dock = findDirmostDockFromString(string.lower(dir)) + sizes = extractSizesFromAction(sizes) + resizeDock(dock, sizes) + return + end + + -- Backward compatibility with the first version + local rxdirh = "talagan_Set (%a+)most dock height %((.+)%)%.lua" + s, e, dir, sizes = string.find(filename, rxdirh) + if s then + local dock = findDirmostDockFromString(string.lower(dir)) + sizes = extractSizesFromAction(sizes) + resizeDock(dock, {b=sizes.b}) + return + end + + local rxdirmin = "talagan_Minimize (%a+)most dock.lua" + s, e, dir = string.find(filename, rxdirmin) + if s then + local dock = findDirmostDockFromString(string.lower(dir)) + resizeDock(dock, 'min') + return + end -local function maximizeBottommostDock() resizeBottommostDock(10000) end -local function minimizeBottommostDock() resizeBottommostDock(0) end + local rxdirmax = "talagan_Maximize (%a+)most dock.lua" + s, e, dir = string.find(filename, rxdirmax) + if s then + local dock = findDirmostDockFromString(string.lower(dir)) + resizeDock(dock, 'max') + return + end + + ----------- + + local rx = "talagan_Set dock containing (.+) size %((.+)%)%.lua" + s, e, cnt, sizes = string.find(filename, rx) + if s then + local dock = findContainerDockFromString(string.lower(cnt)) + sizes = extractSizesFromAction(sizes) + resizeDock(dock, sizes) + return + end + + -- Backward compatibility with the first version + local rxh = "talagan_Set dock containing (.+) height %((.+)%)%.lua" + s, e, cnt, sizes = string.find(filename, rxh) + if s then + local dock = findContainerDockFromString(string.lower(cnt)) + sizes = extractSizesFromAction(sizes) + resizeDock(dock, {b=sizes.b}) + return + end + + local rxmin = "talagan_Minimize dock containing (.*).lua" + s, e, cnt = string.find(filename, rxmin) + if s then + local dock = findContainerDockFromString(string.lower(cnt)) + resizeDock(dock, 'min') + return + end + + local rxmax = "talagan_Maximize dock containing (.*).lua" + s, e, cnt = string.find(filename, rxmax) + if s then + local dock = findContainerDockFromString(string.lower(cnt)) + resizeDock(dock, 'max') + return + end + +end return { CheckDependencies=CheckDependencies, - setTimeout=setTimeout, + + -- LIB : Finders + + findDockThatContainsWindowWithTitle=findDockThatContainsWindowWithTitle, + findDockThatContainsWindow=findDockThatContainsWindow, + findDockThatContainsActiveMidiEditor=findDockThatContainsActiveMidiEditor, + + findBottommostDock=findBottommostDock, + findLeftmostDock=findLeftmostDock, + findRightmostDock=findRightmostDock, + findTopmostDock=findTopmostDock, + + -- LIB : Resizers + + resizeDock=resizeDock, resizeMidiDock=resizeMidiDock, maximizeMidiDock=maximizeMidiDock, @@ -235,5 +441,21 @@ return { resizeBottommostDock=resizeBottommostDock, maximizeBottommostDock=maximizeBottommostDock, minimizeBottommostDock=minimizeBottommostDock, + + resizeLeftmostDock=resizeLeftmostDock, + maximizeLeftmostDock=maximizeLeftmostDock, + minimizeLeftmmostDock=minimizeLeftmmostDock, + + resizeTopmostDock=resizeTopmostDock, + maximizeTopmostDock=maximizeTopmostDock, + minimizeTopmmostDock=minimizeTopmmostDock, + + resizeRightmostDock=resizeRightmostDock, + maximizeRightmostDock=maximizeRightmostDock, + minimizeRightmmostDock=minimizeRightmmostDock, + + -- To use with action names + + resizeDockFromActionName=resizeDockFromActionName, }