It's neat to see boxes resizing themselves using an algorithm you implemented. Wonder if I could expose a C interface?
The reason I like CSS Grid is that I could imitate the formatting like this:
test "compute others":
var gt: GridTemplate
parseGridTemplateColumns gt, ["first"] 40'ux \
["second", "line2"] 50'ux \
["line3"] auto \
["col4-start"] 50'ux \
["five"] 40'ux ["end"]
1: https://github.com/elcritch/cssgridOne thing we have that you may be particularly interested is a reasonably substantial test suite. The tests are defined as HTML snippets that we run through Chrome using webdriver in order the scrape (hopefully) correct assertions, and then format into pure-code unit tests. If you wanted to you could write your own test generator and reuse our snippets. (this test infrastructure is also partially shared with Yoga [2], the C++ Flexbox implementation that powers React Native)
> Looks like the licenses are both MIT (although you may want to add a LICENSE file to make that easier to find) so feel free to steal bits if you want.
Good call, I'll add the license file.
Otherwise solving that system is far from being trivial, you will need simplex solver or the like, for example https://constraints.cs.washington.edu/solvers/cassowary-toch...
But with iOS Safari + Dark Reader, at least on my side, the HTML page is turned into dark mode with Dark Reader, while the canvas page is not. So, it basically ruins the wow factor, haha.
But it still looks nice.
> There's even an HTML renderer - you're looking at it right now!
Jokes on them, I already switched to Canvas renderer when I read it.
This library makes use of modern composable components, is declarative driven and not imperative; and doesn't do immediate rendering in all cases.
It can target incredibly different backends, e.g. DOM/canvas/raylib.
All of this in modern C as a `.h` library alone.
These are great features and not just a 'youngster discovers' project.
The developer has clearly put a lot of thought into this content. Worth taking a second or two to see what’s available before criticising it.
what's also interesting is how much worse Firefox is at rendering this page; example =>
Also, doing layout in WASM and rendering to HTML is a great idea that I can't believe I never thought of before.
But 2000 lines of C, and no dependencies is pretty cool!
void LandingPageDesktop() { CLAY(CLAY_ID("LandingPage1Desktop"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT({ .min = windowHeight - 70 }) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = { .x = 50 } })) { CLAY(CLAY_ID("LandingPage1"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = { 32, 32 }, .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) { CLAY(CLAY_ID("LeftText"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_PERCENT(0.55f) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) { CLAY_TEXT(CLAY_STRING("Clay is a flex-box style UI auto layout library in C, with declarative syntax and microsecond performance."), CLAY_TEXT_CONFIG({ .fontSize = 56, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED })); CLAY(CLAY_ID("LandingPageSpacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(32) } })) {} CLAY_TEXT(CLAY_STRING("Clay is laying out this webpage right now!"), CLAY_TEXT_CONFIG({ .fontSize = 36, .fontId = FONT_ID_TITLE_36, .textColor = COLOR_ORANGE })); } CLAY(CLAY_ID("HeroImageOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_PERCENT(0.45f) }, .childAlignment = { CLAY_ALIGN_X_CENTER }, .childGap = 16 })) { LandingPageBlob(1, 32, COLOR_BLOB_BORDER_5, CLAY_STRING("High performance"), CLAY_STRING("/clay/images/check_5.png")); LandingPageBlob(2, 32, COLOR_BLOB_BORDER_4, CLAY_STRING("Flexbox-style responsive layout"), CLAY_STRING("/clay/images/check_4.png")); LandingPageBlob(3, 32, COLOR_BLOB_BORDER_3, CLAY_STRING("Declarative syntax"), CLAY_STRING("/clay/images/check_3.png")); LandingPageBlob(4, 32, COLOR_BLOB_BORDER_2, CLAY_STRING("Single .h file for C/C++"), CLAY_STRING("/clay/images/check_2.png")); LandingPageBlob(5, 32, COLOR_BLOB_BORDER_1, CLAY_STRING("Compile to 15kb .wasm"), CLAY_STRING("/clay/images/check_1.png")); } } } }
Source: https://github.com/nicbarker/clay/blob/35d72e5fba6872be48d15...
[1] https://docs.oracle.com/javase/7/docs/api/java/awt/GridLayou...
[2] https://github.com/eclipse-platform/eclipse.platform.swt/blo...
[3] https://stackoverflow.com/a/12867862/243613
[4] https://stackoverflow.com/questions/37304684/qwidgetsetlayou...
† Qt actually has a (XML-based, I think) layouting system, but you can also just do stuff in code, which is generally discouraged.
[5] https://gist.github.com/ledongthuc/9686787fe51bbe763fa1e5038...
I wish there would be an elegant c++ class/function based ui framework again.
First, this isn't really true. You might typically have a window, a container, a layout object and then your gui components.
Second you don't need nested calls, you just add one component to another.
or you're going to scatter the fragments across a number of files
Why would that be true?
they need to be reassembled in the reader's head in order to understand what's going on.
This is a bizarre way to make a GUI let alone thinking it's necessary. Where is this idea coming from?
FLTK, JUCE, Tk, ImGUI, Swing and Qt are not like this at all.
LandingPageDesktop(landingPageDesktopId, landingPageDesktopProperties) {
LandingPage(landingPageId, landingPageProperties) {
LeftText() {
etc...
}
}
}
The real issue is trying to represent graphical objects, and the relationship between those objects, with text. Graphical builders/RAD tools seem like such an obvious solution, but that approach has largely been abandoned.I'm a stuck record on this, but I really feel like the regressions in clipboard universality are one of most understated losses of UI shifts in the last few years (along with linkability and embedding)
- Mapping components or structured document data with something like MDX or slate on to Clay components to render in different contexts outside the browser reasonably closely to what shows up in a browser preview, for example content for HUDs, in-world display panels or documents in games, or batch rendering printed documents
- Layout for UI where something like Electron or React Native would be overkill, or isn't supported
Put another way, this library is a step into writing an agnostic UI layer for your application which it just invokes from its business logic. If you can decouple your UI from your application code ala MVC or MVP architecture, as a developer you can find the right tool for the components that compose the sum of your project.
Okay, from the examples there's something like this:
if (isMouseDown && !scrollbarData.mouseDown && Clay_PointerOver(Clay_GetElementId(CLAY_STRING("ScrollBar")))) {
The examples use Raylib as a renderer behind the layout engine. I suppose it would be possible to use Dear Imgui as a renderer, but you might have to write some glue code.
Yes, the repo offers a couple of example renderers.
The idea is that you already have a rendering pipeline (e.g. in your game engine), but want to lay out more complex UIs in it. Then you can use this library to make nice settings / chat / stats / whatever screens, or even render realistic content onto screens of in-game computers, pages of books, etc.
The API approach could be implemented extremely cleanly in Clojure and Java, and then the whole thing would be runtime-dynamic, since Clojure generates new Java functions on the fly, and the JVM's JIT makes them fast.
If anyone wants a fun project over the holidays…
Wouldn’t you try Zig instead?