Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a layout engine that can adapt to various screen sizes and orientations #39

Open
jserv opened this issue Aug 28, 2024 · 3 comments
Assignees

Comments

@jserv
Copy link
Contributor

jserv commented Aug 28, 2024

Creating responsive and flexible interfaces in embedded systems involves implementing a layout engine that can adapt to various screen sizes and orientations, similar to modern web design principles. This approach offers several benefits: it allows for a single UI design to work across multiple devices with different resolutions, improves user experience by ensuring content is always appropriately sized and positioned, and simplifies development by reducing the need for device-specific layouts. Mado can significantly benefit from incorporating CSS Flexbox-like layouts, enhancing its capabilities for creating dynamic and adaptable user interfaces in embedded systems.

Flexible Layout Management
By adopting Flexbox-inspired layouts, Mado can offer a more intuitive and powerful way to arrange UI elements. This allows developers to create complex layouts with less code, reducing development time and potential for errors. Elements can automatically adjust their size and position based on available space, making it easier to design interfaces that work well across different screen sizes and orientations.

Responsive Design
Flexbox-like layouts enable truly responsive designs in embedded systems. UI elements can grow, shrink, or reflow automatically as the available space changes, whether due to screen rotation, resizing of windows, or adapting to different device form factors. This responsiveness improves user experience and reduces the need for multiple layout designs for different scenarios.

Clay (short for C Layout) is a high-performance 2D UI layout library. It implements a React-like nested declarative syntax, outputting a sorted list of rendering primitives that can be easily composited in any 2D/3D engine. It serves as an excellent reference for flexible layout management.

Layout is a simple, fast stacking box layout library. It's useful for calculating layouts for applications such as 2D user interfaces.

@jserv
Copy link
Contributor Author

jserv commented Jan 3, 2025

@ndsl7109256
Copy link
Collaborator

ndsl7109256 commented Jan 3, 2025

Clay offers rendering capabilities through Cairo (clay_renderer_cairo.c), and the path function used by Mado is also aligned with Cairo. This provides an excellent opportunity to integrate Clay into Mado. However, since Clay utilizes floating-point arithmetic, should we need to convert it to fixed-point calculations?

@a1091150
Copy link
Contributor

a1091150 commented Jan 5, 2025

For someone who is interested in this Clay projects and wants to build the examples in the example directory.
There are six examples:

  1. cpp-project-example
  2. raylib-sidebar-scrolling-container
  3. cairo-pdf-rendering
  4. clay-official-website
  5. introducing-clay-video-demo
  6. SDL2-video-demo

To build examples:

  1. mkdir build
  2. cd build
  3. cmake ..
  4. make
  5. Run the proram under example directory.

cmake process will clone raylib and cairo repo to compile. If you fail to compile, you may install some dependencies.
raylib's dependencies: https://github.com/raysan5/raylib/wiki/Working-on-GNU-Linux
cairo's dependencies: https://www.cairographics.org/download/

cpp-project-example provides you a simple example. As video demonstrated, you can just compile the code by g++ main.cpp to get a program.

Below example modified from cpp-project-example. After crafting ui layout, use Clay_EndLayout() to get each x, y, height and width.

#include <iostream>
#define CLAY_IMPLEMENTATION
#include "../../clay.h"
using std::cout;
using std::endl;
Clay_LayoutConfig layoutElement = Clay_LayoutConfig{.padding = {5}};

void HandleClayErrors(Clay_ErrorData errorData) {
  printf("%s", errorData.errorText.chars);
}

int main(void) {
  uint64_t totalMemorySize = Clay_MinMemorySize();
  Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(
      totalMemorySize, (char *)malloc(totalMemorySize));
  Clay_Initialize(clayMemory, Clay_Dimensions{1024, 768},
                  Clay_ErrorHandler{HandleClayErrors});
  Clay_BeginLayout();
  CLAY(CLAY_RECTANGLE({.color = {255, 255, 255, 0}}),
       CLAY_LAYOUT(layoutElement)) {}
  Clay_RenderCommandArray renender = Clay_EndLayout();
  for (int i = 0; i < renender.length; i++) {
    float height = renender.internalArray[i].boundingBox.height;
    float width = renender.internalArray[i].boundingBox.width;
    float x = renender.internalArray[i].boundingBox.x;
    float y = renender.internalArray[i].boundingBox.y;
    cout << height << " " << width << " " << x << " " << y << endl;
  }
  return 0;
}

@jouae jouae self-assigned this Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants