[Closed] Dock/undock command panel through script?
Title say it all. Is this possible?
Would need to be able to check if command panel is docked, and if not, dock it.
Is it possible? Yes.
Is it pretty? No.
fn getCommandPanelDocked =
(
cui.saveConfig()
local pos = getIniSetting (cui.getConfigFile()) "Command Panel" "CurPos"
return pos[1] == "8"
)
fn setCommandPanelDocked state =
(
cui.saveConfig()
local f = cui.getConfigFile()
local pos = getIniSetting f "Command Panel" "CurPos"
if (pos[1] == "8" and state) or (pos[1] == "1" and not state) do return undefined
local posArr = filterString pos " "
if posArr.count == 5 do
(
local newPos = if state then "8 " else "16 "
for p = 2 to 5 do newPos+= posArr[p] + " "
setIniSetting f "Command Panel" "CurPos" newPos
)
cui.loadConfig f
)
fn doesCommandPanelFloat =
(
local act = off
for d in UIAccessor.GetPopupDialogs() while not act do act = (UIAccessor.GetWindowText d == "Command Panel")
act
)
another idea:
if (windows.getchildhwnd 0 “Command Panel”) == undefined then <command panel doesn’t float>
so using LO’s original idea we have:
fn doesCommandPanelFloat = (windows.getchildhwnd 0 "Command Panel" != undefined)
fn dockCommandPanel state:on = if doesCommandPanelFloat() == state do
(
local ini = cui.getConfigFile()
local pos = getIniSetting ini "Command Panel" "CurPos"
pos = (if state then "8" else "16") + (trimleft pos "0123456789")
setIniSetting ini "Command Panel" "CurPos" pos
cui.loadConfig ini
state
)
i try to avoid using of cui.saveConfig() because usually it takes time.
Keep in mind you are potentially discarding any other changes the user has made to the UI in the current session.
also i don’t care about Comman Panel visibility (it’s the first bit as i understood). If the user wants to dock/float the panel user expects to have it visible.
Nice optimization.
That part is actually exposed to maxscript: cui.commandPanelOpen = on
ok… what we have. the first number of Command Panel position setting:
4 – dock left
8 – dock right
16 – float
what are 1 and 2?
numbers 2…5 are: left, top, right, bottom corners… technically using getwindowpos (usr32) function we can set them.
I think the first number is a value of this enumeration (from custcont.h):
#define CUI_TOP_DOCK (1<<0) //!< Can be docked at the top.
#define CUI_BOTTOM_DOCK (1<<1) //!< Can be docked at the bottom.
#define CUI_LEFT_DOCK (1<<2) //!< Can be docked on the left.
#define CUI_RIGHT_DOCK (1<<3) //!< Can be docked at the right.
#define CUI_ALL_DOCK (CUI_TOP_DOCK|CUI_BOTTOM_DOCK|CUI_LEFT_DOCK|CUI_RIGHT_DOCK) //!< Can be docked at any of the four positions.
#define CUI_HORIZ_DOCK (CUI_TOP_DOCK|CUI_BOTTOM_DOCK) //!< Can be docked a tthe top or bottom.
#define CUI_VERT_DOCK (CUI_LEFT_DOCK|CUI_RIGHT_DOCK) //!< Can be docked at the left or right.
#define CUI_FLOATABLE (1<<4) //!< Can be floated.
#define CUI_FLOATING (1<<4) //!< Synonym for CUI_FLOATABLE.
#define CUI_CONNECTABLE (1<<5) //!< Not currently implemented.
#define CUI_SM_HANDLES (1<<6) //!< Set if frame should display size/move handles
#define CUI_SLIDING (1<<7) //!< Frame doesn't butt up against the one next to it.
#define CUI_MAX_SIZED (1<<8) //!< Frame takes up the entire row. Nothing can be docked next to it.
#define CUI_DONT_SAVE (1<<9) //!< Don't save this CUI frame in the .cui file
#define CUI_HAS_MENUBAR (1<<10) //!< CUI frames that have a menu bar need to be treated differently
just to detect if the command panel is currently floating just run through array of handles UIAccessor.GetPopupDialogs() returns, as Commandpanel reports as popup if floating, and not if docked.
so i would do the following
- check if command panel is open
cui.commandPanelOpen
- get array of popup ( window handles )
UIAccessor.GetPopupDialogs()
- find the correct window in the above array – do NOT use window title (“Command Panel”) cause it varies with the language used. Thus search for windows with resources sitting in “core.dll”, luckily the command panel reports this correctly. Now check the first subwindow handle’s windowclass, which should be “EPResizeHandle” for the command panel
function GetCommandPanel=
(
local notFound=true
for hWnd in (UIAccessor.GetPopupDialogs()) while notFound do
(
local dllName=UIAccessor.GetWindowDllFileName hWnd
if( dllName!=undefined AND filenameFromPath dllName=="core.dll" AND UIAccessor.GetWindowClassName ( UIAccessor.GetFirstChildWindow hWnd ) == "EPResizeHandle" ) then
return hWnd
)
return 0
)
- after that i would try to send a corresponding windows message to the handle using the following
UIAccessor.SendMessage <HWND>hwndDlg <integer>MessageID <integer>wParam <integer>lParam
( eg. WM_MENUSELECT uItem:61007 seems to be dock left) etc…
If that fails i would too go for the cui config route and the windows states…
UPDATE:
There is some error in my logic above, as the function GetCommandPanel would only report the handle if Command Panel is currently floating ( i already was dressed for bedtime after i found the thread yesterday )
Thus the function should be modified to do the following:
- if the panel is not found in the popupdialogs array, we know that it is currently docked and we have to search through all childwindows of the Main Max window using the same technique already in the function above
#define CUI_CONNECTABLE (1<<5) //!< Not currently implemented.
can’t wait to get it implemented. i need it badly