Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
RectCut for dead simple UI layouts (halt.software)
89 points by hsn915 on June 4, 2021 | hide | past | favorite | 43 comments


It is tAlign layout from Delphi. Alignments were cutting a parent surface in order of children appearance. It allowed to solve 95% of desktop ui without complicating things.

I’m aware of four main layout models: fixed (x,y), alignment model, boxing model (gtk, qt, html), and constraints model (apple ui). Can anyone list more?


An extension of the fixed layout would be the anchor+margin layout commonly used for game UIs, where each rect is defined by two opposing corners, each of those's axes defined as a % position within its parent, plus a fixed amount of pixels margin.

In this regime, centering a 100px*50px element would be to make TopLeft=(50%-50px, 50%-25px) BottomRight=(50%+50px, 50%+25px)


Another approach I remember uses a pre-sized template and attaches sides to other sides (unlike to parent sides only). E.g. you have a form of width 1000, then you drop button A at (10,10)-(495,50), button B at (505,10)-(990,50), and then connect A.right to follow B.left instead of Form.left (which is default). B.left is then told to be proportional to Form.right, and B.right follows Form.right. When parent resizes, margins and the spacing between them (10) are naturally maintained from the fact that they were 10px apart at design time, i.e. the layout stores their initial coords for using in calculations. A minor issue is that proportional at 505 is not equidistant to proportional at 500 (a true middle of the spacing) at all times, but you just ignore that.

All the rules are of the form:

  A.side {follows|proportional} B.side
By default

  *.side follows Form.left (or top)
And few shorthands, e.g. “A expands hotizontally” means A.right follows Parent.right, etc.

It is actually a dumbed down version of a constraints model and is a subset of it, though it looks and feels more like boxing or alignment models. It was used in pre-constraints apple toolkits and few other products. The main difference is that these follow/proportional constraints are tree-like (cycles forbidden), when true constraint-based layout is a linear problem that requires a special solver optimized for ui-related [in]equality patterns to update in realtime.


I'm curious about the four that you listed. Fixed is relatively obvious, but I don't have a handle on the conceptual models of the other three. Where can I learn more about them without reading through hundreds of pages of webtech and Apple documentation?


Not sure if there is a single resource, but check these links. As you can see, some frameworks mixed layouts and extended size allocation ideas to better fit a given job. (Web has never done this, we're literally stuck with a tree of MSWords)

Constraints-based:

  https://blog.gtk.org/2019/07/02/constraint-layouts/
  https://ebassi.github.io/emeus/
  https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/AnatomyofaConstraint.html
  https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage.html
Boxing:

  https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model#examples_of_different_display_types
Alignment/anchor-based:

  $subj
  https://wiki.lazarus.freepascal.org/Autosize_/_Layout


JUCE also has this kind of layout.


It seems that it positions itself as RAD-like, so not surprising. Boxing and constraints models have one huge downside – your visual interface builder always sucks.


How does layout in say LaTeX compare? Is text/font layout different fundamentally?


Yes text layout is fundamentally different in the sense that text layout is about placing lines of text inside a rectangle, where RectCut is about placing the rectangles and doesn’t help much with text. It would be possible to use RectCut for text flow, but you probably wouldn’t want to, it’s more designed for a small number of on-screen panels in an application.

Core LaTeX is concerned with the flow of text in printed articles, and Knuth published the text layout algorithm “Breaking Paragraphs into Lines” http://www.eprg.org/G53DOC/pdfs/knuth-plass-breaking.pdf

Originally, HTML did the same thing, it was used to emulate the written page and layout text into a box. But not everyone wanted their site to look like a printed article, so CSS and new layout modes sprouted over the years. Today there are seven of them: https://developer.mozilla.org/en-US/docs/Web/CSS/Layout_mode

RectCut is fundamentally most similar in spirit to CSS flexbox, and fundamentally similar to a bunch of other box layout managers in other languages and UI toolkits, as you can see from the comments.


I would call that “flow layout”.

HTML includes a version of it, TeX and DTP apps use various versions of it.

Edit to add: I don’t know the details of TeX except that it uses a hierarchical “box model”. I suspect it’s fairly similar to HTML before flex-box. HTML flex feels like a refined version of Java AWT layout managers (a more successful evolution than Android’s painful variant).


The article and parent talk mostly about layout in terms of rectangles and subdividing those into smaller rectangles. The basics like Box and Flex layout are pretty simple.

Once you start adding constraints like min/max size and relative sizes it becomes more complex but still manageable. You’re still only reasoning about rectangles and their constraints.

Adding rendered text in the mix increases complexity immensely. Determining the size of rendered text is a very complex problem space in itself involving fonts, dpi, text flow, code points, LTR/RTL, ligatures and more. It’s not just rectangles anymore.


Text also trades width for height in random granular steps (rightmost word/char boundaries are propagated down the paragraph and depend on a previous line wrap), and that is probably the worst of its properties.


This sounds like a fascinating topic.


Trees of "dumb" rectangles don't seem very suitable for responsive or adaptive layouts in which the hierarchical structure is built before deciding rectangle sizes. For a retained mode GUI traditional container widgets and layout managers negotiating sizes with child widgets seem a more general technique; for an immediate mode GUI there is no obvious advantage over explicit and more general size computations at the same abstraction level.


From screenshots, this looks like a game console or an embedded controller screen.

For that purpose, simplicity and low footprint may trump flexibility.


Is this UI so simple that it’s meant to break on mobile?


Idiosyncratically, the website looks better on mobile if you view the page in desktop mode. That is, the content actually fits to the screen size, and the code examples aren't cut off mid-line.


That’s half of the point of giving a desktop mode switch, that it makes the browser ignore the “no really, I support mobile” <meta name="viewport" content="width=device-width"> tag.


The code examples are in C and make no mention of any webtech or mobile. I'm pretty sure that this is meant for desktop interfaces.


It’s a good illustration of the need for a simpler layout model than the three-dozen-piled-layers-of-cruft model CSS is based on.


It’s a hopelessly bad illustration of that.

The web does a singularly excellent job of supporting varying viewport sizes out of the box, but this page actively sabotaged that by claiming to support mobile:

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
While applying CSS rules that ruin it:

  .article-card, article h1, article ul, article p, article ol {
    width: 600px;
  }

  pre {
    overflow-x: hidden;
  }
These rules are obviously bad. width should be max-width, and, well, what would you expect to happen if you tell it to hide the overflow?

(It would have been OK even with these rules if the page hadn’t claimed to support mobile sizes, as the mobile browser would have rendered the page on a larger viewport and scaled it down, more or less.)


Yes, and this is exactly the type of problem you run into when your layout model is based on three-dozen-piled-layers-of-cruft.


Show me a layout system that doesn’t let you break things in this sort of way, and I’ll show you a useless layout system.


OTOH, CSS can handle a vastly wider array of styles and use cases. I agree it’s crufty, but there are many historical / legacy reasons for it that are still in use today.

If used in practice for anything substantial, RectCut will start to acquire cruft too. First thing to get added would be resizeable / dynamic layouts. Next would be something akin to the CSS grid layout, which is already the successor to flexbox (closest CSS layout mode to RectCut).


Grid is not the successor to flexbox. They’re different layout techniques that were invented at much the same time (though grid took longer to mature) for different situations. Flexbox is one-dimensional plus wrapping, while grid is two-dimensional. Now in practice, most applications of grid could be rewritten to use flexbox, but there are plenty of layouts that can be achieved with one but not with the other, both ways.


> Grid is not the successor to flexbox.

Yes, it literally is. Grid came after flexbox in W3C drafts, in W3C recommendations, in broad browser support, and in widespread use. Several years ago, flexbox was being used widely while grid support was nonexistent, and today grid is still lagging behind flexbox a little.

https://www.w3.org/TR/css-flexbox-1/

https://www.w3.org/TR/css-grid-1/

https://caniuse.com/?search=grid

https://caniuse.com/?search=flexbox


Successor indicates that it’s designed to replace it. That’s not the case and never was. They have different purposes.

(For the rest, my recollection was definitely off on the timing, and most significantly I forgot the proto-flexbox stuff that Gecko and WebKit had long before grid was proposed. Beyond that, grid certainly took longer to mature, as I remarked, being more complex and needing to interact with more features to be optimally useful. Incidentally, IE got both flexbox and grid (earlier drafts) at the same time, in IE10, Microsoft leading the way on grid by several years, five by the most common way of reckoning.)


ReactCut


This approach is also used/encouraged by JUCE: https://docs.juce.com/master/tutorial_rectangle_advanced.htm... (see "Layout by subdividing rectangles")


This is also how the Tcl/Tk pack layout works.


That was my first thought as well.

I found Tk was really great for simple layouts, but I worked on a Tk project that had some very complicated control panels. Ultimately it became unwieldy and difficult to refactor the UI as moving code around would have breaking consequences.


... and has done for at least 25 years :-)


As they say, everything old is new again.


This may be good if you know all your rect sizes in advance. But it seems like it will quickly fall apart if you have rectangles that need to change their size based on content, especially if that content is multiple levels deep.

Say you have a floating toolbar the width of two buttons, which themselves are the width of their text contents. You're back to square one — you have to measure the text of each button, then measure both buttons and finally you have the size of the toolbar.


You will generally know the rough content of the text and allocate a size that looks good enough.

A lot of people do this anyway even with css: specify the button width in pixels. Because a toolbar with buttons that have varying widths depending on their content is not always a very good looking toolbar.


This is interesting! I had implemented a similar system a while back for a mobile OS company. It was used for optimisation of the rendering of the UI scenegraph. The rectangles were cut(taking into account alpha blending) before feeding it to the renderer to improve performance. This was all post-layout though. Didn't realise that it can be used for layout as well!


I’m unsure what’s the difference between this and hierarchical layouts. And say flexbox


Mostly the ease of definition (a good part), but also there is no calculate-demands / distribute-size loop, only the distribution part. If a medium gets too small, it clips content.


Is... that good?


Depends on what’s good for you and your app/client, as usual.


Thing is, if my client had fixed size, I wouldn't need a layout engine, I'd just place everything using absolute coordinates (and this was the predominant desktop metaphor in the 90s btw).


Looks nice, but unresponsive on small screens.


>rect->minx = min(rect->max.x, rect->minx + a);

Did you mean maxx instead of max.x?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: