LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!
Hello: i have two stacks A and B.
B is smaller than A, and always within the rect of A.
when user resizes A, B shall resize proportionally. This code works:
-- this handler is inside stack A
on resizeStack pNewWidth, pNewHeight, pOldWidth, pOldHeight
if within(me, the loc of stack "B") then
set the height of stack "B" to round((the height of stack "B")*pNewHeight/pOldHeight)
set the width of stack "B to round((the width of stack "B")*pNewWidth/pOldWidth)
end if
end resizeStack
However, when A is resized and B follows suit as per script above, the relative positions of the two stacks change as well -- but I want to preserve their original relative positions to each other, such that the resizing of A and B will result in B keeping its relative position within A.
I cannot get my head around how to do this. Any tips?
First, I cannot replicate the error that you post. Could that be specific to windows (I code on macOS Sierra)?
I attached an image to illustrate my problem a bit better.
As can be seen on image, stack B resizes correctly, but ends up not at the same position relative to the resized Stack A.
Sorry for not having done that from the beginning.
-- this handler is inside stack A
on resizeStack pNewWidth, pNewHeight, pOldWidth, pOldHeight
if within(me, the loc of stack "B") then
set the height of stack "B" to round((the height of stack "B")*pNewHeight/pOldHeight)
set the width of stack "B" to round((the width of stack "B")*pNewWidth/pOldWidth)
set the loc of stack "B" to the loc of stack "A" -- new
end if
end resizeStack
Jean-Marc, thank you for the suggestion. This would always center stack B over A, but the stacks will not always be positioned as on the screenshots -- e.g., B could be somewhere close to a corner of A etc. I thought that I might need to know the locations for both stacks prior to the resizeStack message being sent. Then I might be able to calculate the relative loc changes with this information and update accordingly. Probably the best way to do this would add a custom property to the stacks that stores the loc, such that this custom property is modified/updated each time the stack position changes, and when the stack is opens and closes. I have not tried that one out yet.
Olli.
OK, I thougt that was more complex. I hope Bernd and Hermann will come soon.
Thanks for explanation of your goal, That is very interesting.
Best regards and good luck
Jean-Marc
Take the values of the old margins, and scale them to the new rect of the large stack. So if the old margins were, say, 1",2",3" and 4", and the new stack was 50% larger, well, then.
on resizeStack pNewWidth, pNewHeight, pOldWidth, pOldHeight
local tHeightR, tWidthR // aspect ratio for height and width, just for readability
put pNewWidth/pOldWidth into tWidthR
put pNewHeight/pOldHeight into tHeightR
set the rect of stack "B" to round (tWidthR*(item 1 of the rect of stack "B")), round(tHeightR*(item 2 of the rect of stack "B")), round(tWidthR*(item 3 of the rect of stack "B")), round (tHeightR*(item 4 of the rect of stack "B"))
end resizeStack
Sorry for being dense here. Craig -- you seem to know what to do here, could you be so kind and sketch out your solution in more detail for me?
Hello: after some thinking, i realised that i need to take into consideration the relative location of the smaller stack within the larger stack. This code resulted, and it works very well, but it is not precise -- there is some odd imprecision, and the only way i could get around this is by introducing small correcting factors into the equations. this is of course not very satisfying, and it does only work well so far for the horizontal scaling, but not so well for the vertical scaling.
-- Please note that "me" refers to the enclosing stack "A"
on resizeStack pNewWidth, pNewHeight, pOldWidth, pOldHeight
put (the left of me)+round(1.0001*pNewWidth*(((the left of stack "B")-(the left of me))/pOldWidth)) into tNewLeftOfBStack
put (the top of me)+round(1.001*pNewHeight*(((the top of stack "B")-(the top of me))/pOldHeight)) into tNewTopOfBStack
set the height of stack "B" to round(1.0006*(the height of stack "B")*pNewHeight/pOldHeight)
set the width of stack "B" to round((the width of stack "B")*pNewWidth/pOldWidth)
set the left of stack "module_B" to tNewLeftOfBStack
set the top of stack "module_B" to tNewTopOfBStack
end resizeStack
Anybody with an idea why this is not working well?
on resizeStack newWidth,newHeight
set the width of stack "s2" to round(newWidth / 2)
set the height of stack "s2" to round(newHeight / 2)
set the loc of stack "s2" to the loc of stack "s1"
end resizeStack
Now this locks the loc of "s2" at the loc of "s1, in other words, centers the two stacks, but the parameters attached to the reSizeStack message scale properly. So that part is done. Do you need help with getting the starting loc relationships and maintaining those as well?
It occurs to me that if you do not keep the locs centered, which contains symmetries that make lots of issues go away, the management of off-center resizing may be a bit more complicated.
Hi Craig,
you are right -- if the original relationships between the stacks are to be maintained, and their relationship is not symmetrical around their loc, then it becomes more complex.
The code I posted before, where subtle correcting factors are introduced, may have failed to produce precise outcomes because of incrementing rounding errors. As another forum member suggested in a private message, resizeStack is sent very often, and the rounding either by me or the engine leads to a progressive loss of precision. One way around this would be to determine the fixed factors, i.e., the relative position-based scaling factors prior to the resizing, and not calculate them for each resizeStack message. I am in the process of implementing this method given the constraints of my framework, and will report back with code once that is done.
Best,
Olli.