# How can I implement dynamic button size?

I'm on the process of planing a sort of a 2D/2.5D, pixel-art multilingual game, while I learn about game development. I have a pretty solid background at programming, but when it comes to game design, I don't know too much. My particular question is about how is the proper/better way of creating and implementing a game text button, but I suppose it can be applied to other GUI elements. What I have found so far, while "googleing"/looking for this specific question, is how to deal with engines or frameworks which have their own way of doing it, but I would like to do it by my own. So to make things clearer, let me expose my vision of potential approaches.

1. Fixed text in a fixed-size texture

• This is an easy way of implementing a text button, as all I have to do is loading and positioning a texture. However, it could be painful to change my .psd files all the time, as I'm working with a multilingual game.
2. Variable text and fixed-size texture

• I could use a texture as a button model and overlap it with all kinds of text of different languages, reading the texts from .xml files. The problem is that a word in a language can exceed its equivalent of another language. A workaround for this could be switching between different font sizes, i.e., a text in a language would be smaller or larger than in another, but this would look ugly.
3. Variable text and splitted texture

• This approach would divide a button texture into 3 different parts: left, middle and right. Then, I would read a text from a .xml file, measure its length in pixels and increase ("multiply") the "middle" part of the texture so that the text could fit on it. This looks fine when working with a pixel-art game GUI, but sounds not fine when working with vectorized images.
4. Dynamically-generated GUI

• I could use OpenGL to render rectangles and use them as buttons, but this would produce quite basic shapes. At most, I would have shaded rectangles with a basic border and some text rendered on it; it would look like a HTML/CSS GUI, which is a way far from a game GUI.

These approaches are just my guesses, as I've never worked in the game industry; I assume that someone experienced can correct me if I deduced something wrong. Another thing is that I think these approaches can work diffently depending of the texture type (e.g. pixel-art and vectorized textures), so you'll be welcome for answering why an approach is better for a texture type or another. There's also a possibility of me being a bad thinker and all of this being a "bullshit", and if it is the case, I hope you share your technique with me.

Moreover, as I said before, this question is specific for a text button, but I think with some adjustments it could cover more GUI elements which have related properties (such as window, text input and the like), so if you include it as part of your answer, it'll be helpful.

I'm no expert in GUI, but I think I could help you get in the right direction. I'm assuming that you want to avoid manually setting button sizes for each language, so this will discuss how to procedurally generate a GUI.

Depending on how you are rendering your fonts, there should be a way to get the width and height of a string. For instance, if you are using the Java swing library, this is how you could get the pixel dimensions of your text. Obviously, if you are using a different API, you will have to find this method on your own, or if you are writing your font rendering from scratch, you will have to implement this on your own. This shouldn't be too difficult so I won't get into the details of it. If you are concerned about a language's translation being really long and taking up too much screen space, here is where you could write some code that will check "Is this string length excessively long?" If so, shrink the font size.

The next step is to write a "procedural design" system. This basically takes the dimensions of the string from the previous step and then creates a button object based on that. Depending on how complex your game's GUI is, this could be either really easy or really difficult. Assuming you are using OpenGL, you can create a button of custom size by procedurally generating a VBO like this:

    /* Top Left */
// Pos
vertices[0] = -dimensions.x;
vertices[1] = dimensions.y;
// TexCoord
vertices[2] = 0;
vertices[3] = 0;

/* Top Right */
// Pos
vertices[4] = dimensions.x;
vertices[5] = dimensions.y;
// TexCoord
vertices[6] = 1;
vertices[7] = 0;

/* Bottom Right */
// Pos
vertices[8] = dimensions.x;
vertices[9] = -dimensions.y;
// TexCoord
vertices[10] = 1;
vertices[11] = 1;

/* Bottom Left */
// Pos
vertices[12] = -dimensions.x;
vertices[13] = -dimensions.y;
// TexCoord
vertices[14] = 0;
vertices[15] = 1;

elements[] = { 0, 1, 2, 2, 3, 0 };


Note: This assumes you are using glDrawElements(GL_TRIANGLES).

If you are concerned about getting the button to look interesting, remember that because of how texture coordinates work in OpenGL, the image will stretch to the size of the button. This usually works for when the buttons don't end up stretching too much, so the visual artifacts aren't very visible. However, if this produces too obvious of an effect, you can implement a more complicated texturing system so that you repeat the texture rather than stretching it. Or even make it so that you repeat the middle of the texture (the body of the button) but don't tile the ends of the button. This would probably produce the most natural effect, however it may not be necessary depending on the requirements of your GUI.

You can probably use similar code/techniques in applying this to other parts of your GUI system, but you will probably have to change how you calculate the dimensions if you are not making a button with text on it. Additionally, if you want a GUI element that changes size dynamically (eg a text box that expands as the player types), keep in mind you will have to dynamically rewrite the gui's vbo. Make sure you use GL_DYNAMIC_DRAW for dynamic elements.

Good Luck! Have fun coding and learning!

• I was wondering if there is some magical technique for dealing with a dynamic GUI system, but according to your answer, there's no easy or right way. Anyway, thanks for the feedback. – HugoB Aug 28 '17 at 21:16