Skip to content

Positioning and Anchors

In this tutorial you will learn about widget positioning and anchor points in gooey.

Let's talk about anchor points first.

Anchor Points

The gooey system renders widgets on a position based on anchor points. There are nine anchor points available for any parent (including the GUI layer, which is the parent of panels). These points determine the "starting point" for a widget and also in what direction is the width and height rendered.

When using GameMaker x,y coordinates, we are used to the top left of the window / room / surface is our (0,0), and we know that positive x values will mean further right from that point, and positive y values will mean further down from that point.

This is depicted in the following diagram:

Here, again, the depicted "box" can be any parent - the GUI layer (if you are adding a panel) or another widget (for example, if you are adding a widget such as a text to a panel, then the "box" represents the panel). The labels on each of the nine anchor points are the enum values you can use to refer to that anchor point. These are packed in the UI_RELATIVE_TO enum, so if you want to refer to the TOP_RIGHT anchor point for example, you can write UI_RELATIVE_TO.TOP_RIGHT.

Tip

By default, if you do not specify it, gooey will assign a default anchor point. You can configure this default in the gooey configuration script, see the Configuration section for more info.

Offsets

Once you've chosen (either implicitly or explicitly) an anchor point, when you position a widget, you can further specify offsets. These offsets specify where the widget is placed relative to the chosen anchor point (where negative values move the final x position to the left or the final y position upwards, and positive values move the final x position to the right or the final y position downwards).

For example, setting the offset of a widget to (10, -5) and choosing an anchor point of UI_RELATIVE_TO.BOTTOM_CENTER, means that the widget placement point will be the spot that is 10 pixels to the right and 5 pixels upwards from the bottom center anchor point of the parent. We can now see our placement point in the diagram below:

Rendering relative to the placement point

The last step is how gooey uses the anchor and the placement point to render a widget: the idea is that it aligns the selected (from the parent) to the corresponding anchor point of the actual widget being placed. So, in our example above, we selected the BOTTOM_CENTER anchor point and determined the placement point. If the widget we were placing was, for example, a button, the bottom center of the button would be aligned with the placement point, like so:

Why does gooey work like this?

The benefits of how gooey positions and renders widgets should become clearer as you start using the library. If, for example, you need to place a widget somewhere in a panel, it is many times much easier to think in terms of the spacing of the widget to the corner (i.e. "10px from the top and 20px from the right") and having the widget "grow" in the expected direction. The anchor points allow you to do exactly that. If you were to always use TOP_LEFT, and say you needed to place a widget close to the top right corner, you would need to account not only for that position (i.e. subtract or add - depending on the corner - the spacing from the corner coordinates) but also account for width and/or height - again, depending on the corner - in order to have it render correctly. gooey abstracts this process and easily lets you place items by just determining the placement point as above.

Also, note that if the anchor point is TOP_LEFT, the rendering functions as you regularly draw and position things in GameMaker. This is why TOP_LEFT is the value that is configured as default anchor point when you first import gooey, although you can always change this (for example, I find myself aligning things a lot to MIDDLE_CENTER, so I sometimes use that as default and only modify the anchor point when I don't need that placement point).

Interactive example

An embedded example is worth a thousand words! In the following example we will creating a panel, and then add a button to the panel. The core code to do that is as follows:

1
2
3
4
5
6
7
8
// Not specifying anchor point - i.e. using the default (configured as `TOP_LEFT`), relative to the GUI layer
var _panel = new UIPanel("HelloWorld_Panel", 100, 100, 500, 350, green_panel);
_panel.setTitle("Hello world!");

// Not specifying anchor point - i.e. using the default (configured as `TOP_LEFT`), relative to the parent
var _button = new UIButton("HelloWorld_Button", 0, 0, 150, 80, "Hi", green_button00);
// Set the parent of the button to the panel (i.e. "add it")
_panel.add(_button);

In the code above, the anchor point for both is the default - TOP_LEFT Now, for the actual example, I store the button's x and y offsets and the button's anchor point into instance variables, for easy modification. The resulting example is here, you can interact with it as follows:

  • Use the Tab key to cycle through the parent anchor point for the button
  • Use the A and D keys to change the x offset of the button
  • Use the W and S keys to change the y offset of the button
  • Use the Space key to reset the parameters

Remember you can also drag and resize the panel by using the mouse. Notice how the positioning and rendering of the button follows the panel change in position or size!

Not working?

If interaction is not working, click on the black bar just above the game canvas, to activate the iframe element - otherwise keys are processed by the site itself.

Wrapping up

As you can see, gooey has a robust, flexible positioning system that can help you more easily layout UI elements. Let's now find out how to access and check existance of widgets by using some convenience functions.