ID:154983
 
Hey, i'm not exactly great with interfaces, but i've looked through the help file and couldn't find a way to do this. Is there a way to force an aspect ratio on your interface so when you re-size it, it doesn't get contorted?
Anchors?
In response to Shaoni
I mean on the entire interface - your whole window.
Beatmewithastick wrote:
Hey, i'm not exactly great with interfaces, but i've looked through the help file and couldn't find a way to do this. Is there a way to force an aspect ratio on your interface so when you re-size it, it doesn't get contorted?

Not without writing some custom code. Here's a "smart" way to do it, which tries to guess if the user wanted to shrink or stretch their window:

//Title: forceAspectRatio
//Credit to: DarkCampainger
//Contributed by: DarkCampainger
//Special thanks to: Beatmewithastick (for posting the question)

/*
This verb resizes the passed window to the passed aspect ratio, tracking the
window's previous size so it knows if it should grow or shrink. Use this verb
by calling it from the the desired window's Resize command:
forceAspect [window] [aspectRatio]
forceAspect "default" 1.3333
*/


client
// We track the previous window size to determine if the user is trying to
// shrink or grow the window
var/tmp/lastWindowWidth = list() // Associative list of "window" = width
var/tmp/lastWindowHeight = list() // Associative list of "window" = height

// This verb should be called from the "Resize command" of the window you
// want to constrain. Pass its name and the aspect ratio.
// Example: forceAspect "default" 1.3333
verb/forceAspect(window="default" as text|null, aspect=4/3 as num|null)
var
// Get and parse the width/height of the window's size
size = winget(src, window, "size")
delimiter = findtext(size, "x")
width = text2num(copytext(size, 1, delimiter))
height = text2num(copytext(size, delimiter+1, 0))

// Calculate the counterpart to each dimension that would give the
// desired aspect ratio
heightForWidth = round(width/aspect) // Height based on width
widthForHeight = round(height*aspect) // Width based on height

// Determine if the user is stretching or shrinking the window
var
// Calculate the changes in width/height from the previous window size
changeWidth = (!lastWindowWidth[window] ? 0 \
: width - lastWindowWidth[window])
changeHeight = (!lastWindowHeight[window] ? 0 \
: height - lastWindowHeight[window])

// Take the greatest change, and see if it's an increase or decrease
// For an increase, we assume the user is growing the window
grow = ((abs(changeWidth) > abs(changeHeight)) ? changeWidth : changeHeight) >= 0

// If we're growing to fit and the height deviates the most,
// Or if we're shrinking to fit and the width deviates the most
if((grow && widthForHeight>width) || (!grow && widthForHeight<width))
// Reconstrain the width to the height
width = widthForHeight
else
// Otherwise reconstrain the height to the width
height = heightForWidth

// Store the size so we know next time if they're shrinking or stretching the window
lastWindowWidth[window] = width
lastWindowHeight[window] = height

// Update the window size
winset(src, window, "size='[width]x[height]'")


Then, in the window you want constrained, set its "Resize command" to "forceAspect [window] [aspectRatio]". For example, if your window was named "default" and you wanted a 4:3 aspect ratio, you would set the Resize command to forceAspect "default" 1.3333

I would also recommend manually calling forceAspect() when the player logs in, so the lastWindowWidth/Height is already set up when they go to resize it.
In response to DarkCampainger
Wow, thanks very much! I wasn't expecting it to be nearly as complicated as that - I figured it would be a few quick lines.

One quick last quesiton though - how do I actually call the verb for the windows resize command? (I know, it's probably super basic, but interfaces and skins have always eluded me, for some reason.)
In response to Beatmewithastick
Beatmewithastick wrote:
Wow, thanks very much! I wasn't expecting it to be nearly as complicated as that - I figured it would be a few quick lines.

Well, it was originally. Then when I started playing with it, I realized it was more annoying than useful, so I set out to make it smarter. It's still pretty short, I just put a lot of comments in there for you.

One quick last quesiton though - how do I actually call the verb for the windows resize command? (I know, it's probably super basic, but interfaces and skins have always eluded me, for some reason.)

Open up your interface, open the window you want to constrain, right-click in its canvas, select "Edit [window_name]...", and then under the General tab, set the "Resize command:" to:
forceAspect "[window_name]" [ratio].

For example, if your window was named "default" and you wanted a 4:3 ratio, you would use:
forceAspect "default" 1.3333