PDA

View Full Version : Docking Dialogs


maT-Star
06-12-2008, 12:10 PM
Hi :)

I wrote a tiny test script for docking dialogs and it works quite well, sometimes I get an infinite loop but this is no big deal.

How it works:
I create several dialogs and each time the user moved them, a function checks, if it is near another dialog, if so, it snaps the dragged dialog to them.
If the user snaps to the main dialog, he can drag all docked dialogs when moving it.

This all works quite promising, but the more dialogs you dock, the slower it gets :(

Is there a way to speed this up?

Here is the code:




try
(
for i = 1 to rolloutList.count do
try destroyDialog rolloutList[i].RO catch()
)
catch()


struct ROStruct
(
parent,
docked = false,
offsetPos = [0,0],
RO
)

global ROMOVING = false


function moveDockedRO =
(
global ROMOVING = true
try
(

for i = 1 to rolloutList.count do
(
local parentRO = getParentRO rolloutList[i].RO.name
if parentRO != undefined then
(

setDialogPos rolloutList[i].RO ((getDialogPos rolloutList[rolloutList.count].RO) + rolloutList[i].offsetPos)

)
)

)catch()
global ROMOVING = false
)







function getParentRO dialogName =
(
local thisRO = ""
for i = 1 to rolloutList.count do
if rolloutList[i].RO.name == dialogName then
thisRO = rolloutList[i]

if thisRO.docked == false then
return undefined

local tempParent = thisRO.parent
while tempParent.parent != undefined do
(
enableEscape = true
tempParent = tempParent.parent
)

if tempParent.RO.name == "mainRO" then
return tempParent

return undefined
)



function dockDialog dialogName =
(
if ROMOVING == true then
return undefined

local thisRO = ""
for i = 1 to rolloutList.count do
if rolloutList[i].RO.name == dialogName then
thisRO = rolloutList[i]

thisRO.docked = false
thisRO.parent = undefined

for i = 1 to rolloutList.count do
(
local thisPos = getDialogPos thisRO.RO
local ROPos = getDialogPos rolloutList[i].RO
local thisSize = getDialogSize thisRO.RO
local ROSize = getDialogSize rolloutList[i].RO


if rolloutList[i].RO.name != thisRO.RO.name then
(
--// dock left
--// left, right pos
if ((thisPos[1] + thisSize[1]) > ROPos[1] - 10) and ((thisPos[1] + thisSize[1]) < ROPos[1]) then
(
--// up, down pos
if ((thisPos[2] > ROPos[2] - 10) and (thisPos[2] < ROPos[2] + 10)) then
(
local newPos = ROPos
newPos[1] = ROPos[1] - thisSize[1] - 5

if rolloutList[i].RO.name == "mainRO" then
newPos[2] = ROPos[2] + 3


setDialogPos thisRO.RO newPos


thisRO.parent = rolloutList[i]
thisRO.docked = true

local parentRO = (getParentRO thisRO.RO.name)

if parentRO != undefined then
thisRO.offsetPos = (getDialogPos thisRO.RO) - (getDialogPos parentRO.RO)
else
thisRO.offsetPos = [0,0]

break
)
)

--// dock right
--// left, right pos
if (thisPos[1] > (ROPos[1] + ROSize[1] )) and (thisPos[1] < (ROPos[1] + ROSize[1] + 10)) then
(
--// up, down pos
if ((thisPos[2] > ROPos[2] - 10) and (thisPos[2] < ROPos[2] + 10)) then
(
local newPos = ROPos
newPos[1] = ROPos[1] + ROSize[1] + 5

if rolloutList[i].RO.name == "mainRO" then
newPos[2] = ROPos[2] + 3

setDialogPos thisRO.RO newPos


thisRO.parent = rolloutList[i]
thisRO.docked = true

local parentRO = (getParentRO thisRO.RO.name)

if parentRO != undefined then
thisRO.offsetPos = (getDialogPos thisRO.RO) - (getDialogPos parentRO.RO)
else
thisRO.offsetPos = [0,0]

break
)
)

--// dock up
--// left, right pos
if (thisPos[1] > ROPos[1] - 10) and ((thisPos[1] + thisSize[1]) < (ROPos[1] + ROSize[1] + 10)) then
(
--// up, down pos
if ((thisPos[2] + thisSize[2] > ROPos[2] - 25) and (thisPos[2] + thisSize[2] < ROPos[2] - 15)) then
(
local newPos = ROPos
if rolloutList[i].RO.name == "mainRO" then
newPos[2] = ROPos[2] - thisSize[2] - 20
else
newPos[2] = ROPos[2] - thisSize[2] - 24



if (thisPos[1] + thisSize[1]) < (ROPos[1] + ROSize[1] + 10) and thisPos[1] + thisSize[1] > (ROPos[1] + ROSize[1] - 10) then
newPos[1] = ROPos[1] + ROSize[1] - thisSize[1]

if (thisPos[1] >= ROPos[1] + 10) and ((thisPos[1] + thisSize[1]) <= (ROPos[1] + ROSize[1] - 10)) then
newPos[1] = thisPos[1]


setDialogPos thisRO.RO newPos


thisRO.parent = rolloutList[i]
thisRO.docked = true

local parentRO = (getParentRO thisRO.RO.name)

if parentRO != undefined then
thisRO.offsetPos = (getDialogPos thisRO.RO) - (getDialogPos parentRO.RO)
else
thisRO.offsetPos = [0,0]

break
)
)

--// dock down
--// left, right pos
if (thisPos[1] > ROPos[1] - 10) and ((thisPos[1] + thisSize[1]) < (ROPos[1] + ROSize[1] + 10)) then
(
--// up, down pos
if (thisPos[2] > (ROPos[2] + ROSize[2] + 20)) and (thisPos[2] < (ROPos[2] + ROSize[2] + 30)) then
(
local newPos = ROPos
if rolloutList[i].RO.name == "mainRO" then
newPos[2] = ROPos[2] + ROSize[2] + 26
else
newPos[2] = ROPos[2] + ROSize[2] + 24




if (thisPos[1] + thisSize[1]) < (ROPos[1] + ROSize[1] + 10) and thisPos[1] + thisSize[1] > (ROPos[1] + ROSize[1] - 10) then
newPos[1] = ROPos[1] + ROSize[1] - thisSize[1]

if (thisPos[1] >= ROPos[1] + 10) and ((thisPos[1] + thisSize[1]) <= (ROPos[1] + ROSize[1] - 10)) then
newPos[1] = thisPos[1]

setDialogPos thisRO.RO newPos


thisRO.parent = rolloutList[i]
thisRO.docked = true

local parentRO = (getParentRO thisRO.RO.name)

if parentRO != undefined then
thisRO.offsetPos = (getDialogPos thisRO.RO) - (getDialogPos parentRO.RO)
else
thisRO.offsetPos = [0,0]

break
)
)
)
)
)






global rolloutList = #()





rollout test1RO "UpperLeft"
(
label labDesc "UpperLeft"

on test1RO moved value do
(
dockDialog "test1RO"
)
)


rollout test2RO "UpperMiddle"
(
label labDesc "UpperMiddle"

on test2RO moved value do
(
dockDialog "test2RO"
)
)

rollout test3RO "UpperRight"
(
label labDesc "UpperRight"

on test3RO moved value do
(
dockDialog "test3RO"
)
)






rollout mainRO "mainRO"
(
on mainRO moved value do
(
moveDockedRO()
)
)



append rolloutList (ROStruct RO:test1RO)
append rolloutList (ROStruct RO:test2RO)
append rolloutList (ROStruct RO:test3RO)
append rolloutList (ROStruct RO:mainRO)


for i = 1 to (rolloutList.count - 1) do
createDialog rolloutList[i].RO 100 100 style:#(#style_toolwindow, #style_sysmenu )




createDialog mainRO 310 0

ZeBoxx2
06-12-2008, 01:00 PM
cool :)

might have a scoping issue as it throws an error on first run:


-- Error occurred in dockDialog(); filename: ; position: 1393
-- Frame:
-- thisRO: ""
-- rolloutList: undefined
-- dialogName: "test3RO"
-- called in test3RO.moved(); filename: ; position: 6405
-- Frame:
-- value: [583,343]
>> MAXScript Rollout Handler Exception: -- Unknown property: "count" in undefined <<
-- Error occurred in dockDialog(); filename: ; position: 1393
-- Frame:
-- thisRO: ""
-- rolloutList: undefined
-- dialogName: "test3RO"
-- called in test3RO.moved(); filename: ; position: 6405
-- Frame:
-- value: [587,339]
>> MAXScript Rollout Handler Exception: -- Unknown property: "count" in undefined <<

maT-Star
06-12-2008, 01:12 PM
Yeah, I think you need to evaluate it 2 times :S
Well, it is just for testings and there is absolutely no fine-tuning there ^^

The only problem I see is that it gets quite slow :(

ZeBoxx2
06-12-2008, 06:17 PM
well, one thing that should make it faster is to not have to loop over all of your dialogs when you don't have to.

For example, when you move one dialog, you should only have to move its children. When you move those children, the 'on <roll> moved' event for them will trigger and they will take care of their own children (this could lead to an infinite loop if you dock things in a neat little circle). This does mean you have to assign a docked dialog to the parent dialog's 'children' variable (you'll have to make one), of course.

Also, I'm very confused by this little snippet of code (I admit I haven't poked much further at your code, doing some timing tests today):

[code]
local tempParent = thisRO.parent
while tempParent.parent != undefined do
(
enableEscape = true
tempParent = tempParent.parent
)
[/cide]
That appears to be a potential infinite loop; is there any reason why tempParent.parent would suddenly -not- be undefined anymore? I.e. is there a parallel script or so that sets this value? That code above will easily peg the CPU (only 1 core, of course) so it seems iffy :)

CGTalk Moderation
06-12-2008, 06:17 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.