• Forum
  • Lounge
  • UI layout is certainly the most difficul

 
UI layout is certainly the most difficult area of UI design

As some of you might already know I'm writing a UI library, for personal esteem of course, nothing official or public yet.

It will be Windows only library and not cross platform primarily because it takes much less work.

All my work so far was not too hard, it all boils down to finding the right API's and design patterns to achieve some goal, there are of course gray areas which are more difficult than others but everything is achievable with enough effort.

But eventually I've hit a wall, and that wall is called UI layout.

When I started I thought it would be as simple as declaring few enums which would specify alignment, orientation, sizing etc., for ex.
Alignment: Left
Orientation: Horizontal
Sizing: Optimal
etc..

And then simply a for loop that would reposition controls according to those options.

But no man, it's far more difficult that few enums!

What if there is no horizontal space left?
What if not all controls are same size?
If you resize for excess space this might make some controls look ugly.
What if a portion of controls should be vertically positioned and another portion horizontally?
What if alignment for a group of controls should be left, for other group right and yet another centered?
What if an element is a picture control which requires aspect ratio to not be violated?
What if a control can not be resized beyond some limit due to MINMAX specification?
What if there is not enough client area space to layout all the controls, what to do with the surplus controls then?

What if, what if, what if, you continue this madness to make it worse.

This madness made me googling out about UI layout and I've learned that there is a whole research branch going around UI layout, there is a thing called linear programming and a bunch or complex math and algorithms which one should understand to get anywhere.

Here is one such research paper useful to get a grasp of theory:
https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.127.7519

It become obvious to me that I've opened up a can of worms lol.
Sadly all those research papers are difficult in theory which one should transform into a code somehow to make use of them.

I've also learned that every UI library or framework provides the so called "layout engine" and there are many ways to implement a layout engine.
I started to write my layout manager class like 5 days ago but I'm still struggling because one algorithm can not solve every possible desired layout result.

My only invention so far is splitting window client area into virtual regions, where each region is managed by a separate layout manager instance assigned with a portion of controls.
This way it's possible to move, resize and scale regions and reposition controls within region independently of other virtual regions or controls.
Each region thus can run it's own layout style and algorithm.

I would like to hear your experience with UI layout, and if you have any useful research papers, algorithms, or anything useful about UI layout to please share here.

If you have any hints about UI layout that would be great because every bit of information can be useful.

edit:
Also if you know of any good tutorials it would be great, I've found this one to be useful although not really advanced:
https://www.codeproject.com/Articles/11316/Control-Positioning-and-Sizing-using-a-C-Helper-Cl

This MS resource for XAML is also useful to convert into C++ and to get some basic understanding of what should layout engine do:
https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/alignment-margins-and-padding-overview?view=netframeworkdesktop-4.8
Last edited on
yea this stuff is so very simple yet takes you down so many annoying edge cases that you have to handle somehow. I wish I had the experience here to help you, but all my UI experience was either toy scale (putting a simple interface on a simple program, one was just fat buttons for a touch screen way back when those were kinda new) or trying to slice new stuff into an existing large program where I ran into problems similar to what you describe and failed miserably at estimation of the difficulty.
thank you for comment, yeah it should be simple but complexity grows with count and shapes of elements.

It seems the only way around is many separate algorithms and many options which a users can chose from, which in turn means a lot of code that looks the same but works differently.

When and if I finish this, I think I'm going to make a video and post it here to pick up some criticisms for improvements :)
You should look into how previous frameworks have solved this problem.
Also, another thing you missed: what if the UI must work at different DPIs? Which elements should be resized and which shouldn't? How do you deal with the varying geometry?
I would suggest the following process:

Calculate the horizontal size of the layouts then vertical.
After that you calculate the positions according to the sizes and again horizontal and vertical one after another.

You may also consider a tree like layout. Then it would be possible to group elements and even have different orientations within a parent layout.
Sorry guys for late response, I was away from computer for a few days...

@helios,
That's a good question, I didn't test my algorithm for DPI but I think layout logic should be independent of DPI.

I'm handling this by storing DIP dimensions for each window which the layout manager can simply access by calling a getter function for each child window and then do layout in DIP's.
Since all window dimensions are in DIP's there can't be any issue because prior resize all DIP dimensions are scaled.

what so you mean by "varying geometry", perhaps non rectangular child windows?
You can always measure non rectangular elements by computing a bounding box of their client area, if they are round or something.

You should look into how previous frameworks have solved this problem

Yes, maybe but existing frameworks are too complex to learn anything out of them.
It easier to interpret abstract papers and turn the idea into a code.

coder777,
Calculate the horizontal size of the layouts then vertical.
After that you calculate the positions according to the sizes and again horizontal and vertical one after another.

This is what I'm doing, it's called tabular layout and each child window is optionally resized to fit the table, rows and columns.

You may also consider a tree like layout. Then it would be possible to group elements and even have different orientations within a parent layout

I'm not sure how would that work or be implemented, what do you mean?
Last edited on
I'm not sure how would that work or be implemented, what do you mean?
For instance:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
struct layout_type
{
  int PosX = 0;
  int PosY = 0;
  int SizeX = 0;
  int SizeY = 0;

  layout_type() = default;
  virtual ~layout_type() = default;

  virtual update_x() = 0;
  virtual update_y() = 0;
};

struct layout_button_type : layout_type
{
  std::shared_ptr<button_type> Button;

  virtual update_x()
  {
    SizeX = Button->size().x;
    SizeY = Button->size().y;
  }
  virtual update_y()
  {
    ....
  }
};

struct layout_container_type : layout_type
{
  std::vector<std::unique_ptr<layout_type>> SubLayout;

  virtual update_x()
  {
    SizeX = 0;
    pos_x = PosX;
    for(const std::unique_ptr<layout_type>& l : SubLayout)
    {
      l->PosX = pos_x;
      l->update_x();
      pos_x += l->SizeX;
      SizeX += l->SizeX;
    }
  }
  virtual update_y()
  {
    ....
  }
};
In the simplest possible form
Last edited on
Yes, maybe but existing frameworks are too complex to learn anything out of them.
It easier to interpret abstract papers and turn the idea into a code.
I don't mean you should look at the code. Look at how it's supposed to work from the library user's point of view.
coder777,
Thank you for pseudo code, looks interesting and it took me some time to get what you mean.

helios,
ah this yes, I've already "copied" half of interface from MFC heh and made my implementation:
https://learn.microsoft.com/en-us/cpp/mfc/reference/cmfcdynamiclayout-class?view=msvc-170

But this class does not implement any algorithms, it expects exact input from the user.
Topic archived. No new replies allowed.