White Shining Rock Logo
White Shining Rock Logo

UI Redo: Part 2

October 19, 2021 | Dukus | 4 Comments

With a change to the C++ side of my user interface complete, I decided it was time to fix up the data and creation side of it.

Fixing Complex Layout Data.

Previously my data for interface layout was setup in a JSON-like file. It's how most all the game data is specified. It works great for general data creation. But not so much for user interface. For every control, every attribute was specified. (like text, image, width, height, padding, size, color, children, etc, etc.) Once a complicated user interface was built, changing it was really hard, and it was hard to think about how things were laid out and related to each other.

Since I'd recently setup a new data format for writing scripts for game play earlier in the year, I used a really similar data format for user interface layout. They even use the same parser! Yay code sharing!

The old version looked something like this - where every element was its own section, and child/parent relationships where explicitly written out...

VerticalLayoutElement layout
{
	Element _children
	[
		"nameControl",
		"toolTipControl"
	]
}
TextElement nameControl
{
	Text _text = "Name@String.rsc:objects";
}
TextElement toolTipControl
{
	Text _text = "Name@String.rsc:objectToolTips";
}

I didn't include everything for a whole dialog because it's huge. And interface layout used to be even worse than what you see above, as colors, fonts, spacing, and general look of each element could be specified per control.

And then in C++, I'd have to do something like this, to fill in the name field.

TextElement* nameElement = FindElement("nameControl");
nameElement->SetText(_entity->_metaData->_name);
TextElement* toolTipElement = FindElement("toolTipControl");
toolTipElement->SetText(_entity->_metaData->_toolTipText);

With the new version, the layout is now reduced to just a few lines. It really amplifies the change and reduction in complexity that I'm getting. The example below is a whole dialog, restructuring what is seen above, and with no C++ involved.

Dialog toolTip(_style = "UI/Style/ToolTipStyle.rsc")
{
	Border()
	{
		VertialLayout() // this is what was shown above...
		{
			Text(_binding = "Control: _entity._metaData._name")
			Text(_binding = "Control: _entity._metaData._toolTipText")
		}
	}
}

Here I can see where controls are parented, what data each control connects to, and how it's arranged on the dialog. This makes it easy to move things around. None of the drawing or layout information like padding and offsets are here either. That data has been moved to a separate resource, so I can restyle any interface easily.

The binding field you see, such as '_binding = "Control: _object._metaData._name"' are the connections to internal data I mentioned in the last post which removes the need for C++. Which is awesome.

You may be wondering or noticed I don't have a graphical tool for building data like this. It could be useful. But! For me as a single developer, when I need to change things en-mass, find and replace in text is pretty fast. And things tend to change a lot. Plus I don't have a team of people using it, and I don't have to take the time to write and maintain tools. Maybe one day I'll write graphical dev tools, but I'm not missing them.

With that layout rework out of the way, I worked on fixing some issues with fonts, which I'll talk about next time.

Leave a Reply

Your email address will not be published.

4 comments on “UI Redo: Part 2”

  1. Thank you for your updates.
    Whether we understand them or not, it is great to hear that you are forging ahead.

  2. Good stuff Luke, I wonder how much easier it is for you this time around compared to your time creating Banished. It must be a great help to have a past project that you learned from and can take parts of.

More Posts

Code Rot

April 17, 2022
1 2 3 47
Back to devlog
Back to devlog
© Copyright 2021 Shining Rock Software
Website Design & Branding by Carrboro Creative
menu-circlecross-circle linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram