Tips for Programming a GUI

Started by
14 comments, last by JoshuaWaring 9 years, 11 months ago

I'm about to commence my first GUI, I was wondering if anyone has any times on how I should structure the data and classes? Something that might help me with future issues.

Advertisement

You could do something like this: make your own GameButton class and have new buttons you create inherit from the GameButton class.

To think data structure is to think of object oriented composition. Each button should have some notion of representing itself (i.e: an image, position(x and y coordinate), have a mouse listener(so the buttons can listen for mouse events). Add these buttons object to the canvas so the buttons can listen the mouse events from the canvas.

When I started using GUI toolkits, I couldn't figure out why they were written for a single thread, but the keyboard and mouse events come in on other threads. Even Java uses a single threaded event thread concept and none of the GUI components are thread safe. Because the UI lives in two worlds, waiting for user input while the high level software is running, but responding to low level keyboard and mouse events, as well as operating systems messages such as focus gained/lost, it is very difficult to get right.

Long story short (too late) don't build your own GUI toolkit unless you really need to. Find an API or toolkit and use that.

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

Just a word of warning for you--unless you have something very simple in mind, this can easily snowball into taking up a massive amount of your time (especially if you've never done anything similar before). You may find yourself, 10-15 years later, working full time as some sort of UI specialist. lol (Ok, that's not such a bad thing.) I'm sure personality has much to do with this, but based on what you're asking, you could fall into that trap.

If you don't like that fate, my advice would be to either find an existing library or to define your requirements accurately and very simple. Many people seem to think that UI development doesn't seem so hard, but believe me, it gets extremely challenging fast (especially with the high expectations people have now).

Just my opinion--could turn out wrong...

Unfortunately, many (most? all?) UI libraries have their own learning curve, but you should get up and running faster if you're not too much of a picky perfectionist.

I've made a few GUIs before. It can get tricky and time consuming. Break down the GUI into the simplest components you need to accommodate your program.

-button

-list

-textbox

-dropdown

-tabmenu

These are the basic ones I use. I also have "menu groups" which are like their own window and contain the menu items listed above (as needed). Each of these items you need to be able to reference in your program so that they can "do something".

If it's at all possible, you should try to find a third party GUI. If you are set on doing it yourself, I can help you if you want.

My GUI is built on top of SDL for a map editor, but I'm writing it to also act as the game GUI. I've got the idea of a hierarchy design and positions to be stored relative its parent entity.

SDL will Handel all my keyboard and mouse events.

I seem to be on the right track.

The key to a good GUI is your event handling system.

When someone clicks on a button, how do you link that to code?

There are plenty of techniques depending on programming language, but they basically come down to two core technologies.

Callbacks and messages.

Callbacks are simple and direct, you link the button to a subroutine which does the real work.

Messages are a little more complex, you click on the button. It adds a message to the list. At some point in your code you parse any pending messages and clear the list.

I prefer callbacks. They can be called events, signals, callbacks, all sorts of things, but they all work the same way.

The only other thing I would advise is that you don't use scaling. I hate the look of scaled graphics. So to draw a button you draw the four corners, draw the sides, then fill the middle instead of just drawing a scaled version of the button.

Other than that, have fun. I love writing GUI's, I particularly like making strange effects like circular folding menus, animated buttons, animated transitions.

The implementation of a GUI system has aspects of input processing, graphical representation, and effect.

1.) Clarify whether immediate mode or retained mode GUI is what you prefer.

2.) Define how input is handled (fetched, collected, prepared) before it is provided to consumers.

3.) Define whether provided input is pushed to consumers or pulled by consumers. E.g. when running down an iteration of the game loop, the various sub-systems are called anyway and hence may investigate provided input whenever they are updated. This is an alternative to the push model which is known from application programs.

4.) GUI elements compete with other GUI elements and with game controller objects. Define how routing of input to the various possible consumers is to be done. Is the gameplay view just another widget?

5.) Define how the effects of action widgets (e.g. when pushing a button) is processed. E.g. does it invoke a callback, sends a message, or sends a command object?

6.) Define how the effects of value widgets (e.g. when dragging a slider knob) is processed. E.g. alter a local value, use a callback, send a message, send a command object, or change the target value in-place (the latter is fine for tweaking).

7.) Depending on the targeted platform: Make the graphical rendering resolution (DPI) independent by using scalable graphics / multi-resolution graphics.

8.) Even more important (IMO): Make the placement independent on the aspect ratio by using various anchors (horizontally left / center / right, vertically top / center / bottom) and a resolution independent length (e.g. normalized with the display height).

Hopefully you don't need things like table or outline views and drag & drop, because they make things really complicated.

Hello there, Gamedev forums! : )

I feel like it is appropriate for me to make my first post in this thread, as thinking about UI/GUI implementations have took up a lot of my free time in the past months, or even a year. (HTML5 indie, refusing to use CSS for "proper" buttons, since I plan on going to mobile as well, and I do not want to be dependant of DOM/CSS in any way whatsoever).

So, I have arrived at a point where my implementations was this:
a. You have a class named uiNode, which has an attached onExecute() function, and has a -initially empty- uiNodes[] array as well.
b. Upon updating your game/scene, you see if you have clicked on one of your nodes. You can do this via just getting the mouseclick and compare it to a list of your nodes (so the click has to be within the boundraries of your virtual button/menu item).
c. Each uiNode of yours can contain more uiNodes (they always automaticallly have an empty uiNodes[] array), and it is possible to have an onExecute() that does nothing else but "opens up" a set of buttons, that were otherwise invisible/inactive before.

So you have basic elements that are either visible or not, clickable or not (these things are different for a reason - you might have invisible buttons that are tied to pictures, or visible, but not yet clickable buttons that become active when something changes them), and due to the recursive nature of this.uiNodes[n].uiNodes[m].uiNodes[l]...., you can have submenus naturally. Your onExecute either leads to new menu points, or executes the code linked to clicking that particular button.

I found out that while this approach works, sometimes, for easier scenes (and even for something like an inventory screen), it was less of a hassle to just create my click logic independent of this structure. But when real menus are needed, this helped me.

A few pitfalls to avoid, regardless of what language you are aiming for:
- Have a way to dynamically change size/positions - you are not always in this with the same resolutions, after all

- Do not check each button's click state every frame, that can get demanding fast in main menus. Instead, just make a list of your active nodes and cycle through their positions whenever a click occurs. That way, you do not have scenarios where overlapping buttons/texts activate at the same time. You can even define rules like nest levels, click hierarchy, etc.

- What others posted here: define your needs, and do not go overboard with it. I spent way too much time on this, time that should have gone towards the implementations of the game rules, not arbitrary ui structure building. I do not regret it, but it might not be your favorite time spender.

You should also look at the "Immediate Mode" GUI talk on Molly rocket (https://mollyrocket.com/861). It's a slightly different way of thinking about GUI development. In my opinion it's easier to use as an end user, but not necessarily easier to build.

It's great for simple in game menus, but apparently can be used In fairly complex systems. Unity uses an IMGUI in their editor.

Cheers,

Bob

[size="3"]Halfway down the trail to Hell...

This topic is closed to new replies.

Advertisement