# chopsui design notes ## questions Should containers be generalized, i.e. there's not necessarily even going to be a tree unless the top-level node is a container? Or should nodes intrinsically have children? How does this choice play into the DSL, is the DSL aware of the (specialized) container types? Inclination is that the DSL can be conservatively specialized in cases like this and generalizing the internals is wise. how to express the complex constraints of grid children? **answer**: with dedicated cell nodes, not by adding properties/interfaces to children as originally planned. ## dsl yes, but optional - can also just use code ## namespaces yes ## types & interfaces - types can be instantiated, interfaces cannot. Both can provide methods. - methods on types are C functions straight-up - methods in interfaces are abstracted through function pointers **host interface** - wraps another node and adds stuff to it - re-"implements" the interfaces of its child - must always have a single child, zero children is invalid **container interface** - may have zero or more children - allows enumeration of its children **window type** interfaces: - focus_manager - input_source (can be multiple) - presentation_manager - sized - host - wayland\_window | x11\_window | etc properties: - title - app_id - etc **grid type** - has restrictions on their children (how to express that?): ``` grid: children supports grid::layout | grid::cells grid::layout: children are grid::row | grid::column grid::row, grid::column has size constraints (similar to css grids) grid::cells[container] grid::cell(host) has row, col, rowspan, colspan ``` interfaces: - container - presentation_manager **fixed_size interface** has an immutable size signals: - size_changed **contstrained_resizable interface** - is assigned a size by external forces, but may impose constraints on that size properties: - min_size - max_size - preserve_aspect_ratio **resizable interface** is assigned a size by external forces methods: - set_size **presentation_manager type** methods: - submit_frame (with optional damage) signals: - frame_ready ## first-class tree proposal - Three first-class types make up the tree: leaf, host, container - leaves cannot have any children. - hosts can have exactly one child and re-export the interfaces of their child. - containers can have zero or more children. - All of these are nodes. A tree has one root node. Except for the root node, all nodes have exactly one parent. Nodes may have an ID and classes. - Having a first-class tree allows each node to traverse the tree looking for interfaces. - To find an interface, you can climb up the tree until you find one. Nodes can shadow the interfaces of their parents, such as a grid shadowing the presentation manager of the window to offer slightly different functionality. - Can query the tree with ## DSL example ``` namespace my_app import layout::{grid,row,column} os::window widgets::* @root window title="My example" stylesheet name=window.css grid #root-grid grid::layout row #navbar row #body row column #left column #right grow grid::cells cell row=#navbar colspan=2 { navbar } cell row=2 statusbar cell row=#left text content=< This is my example application. I hope you like it. > cell row=#right text content="Your foobars will appear here." # Defines a new type @host(navbar) menu [ flow=horizontal ] item name="File" item name="Open" %select=on_select @host(statusbar) : constrained_size( min_size: 100, 100 ), stacked flow=vertical bordered top=1 color=$black text content="Ready." ``` - # at the start of a line is a comment - # following a node name assigns it an ID - { inline children } - [ multi-line props ] - bare props (e.g. column grow) are booleans set to true - Should the DSL have %signals at all? Where does it get the symbols from? - Should this be compiled or interpreted at runtime? Pros compile: - Faster in some cases - Signals are easy to support, since the C compiler would deal with the function pointer linkage Pros interpreted: - Can use sui syntax to create nodes at runtime, e.g. `list_add(tree_get(app, "#items"), sui_parse("text content='my text'")))` - Compile may be harder to do with bindings to other programming langs Maybe do both? - Stacking up a bunch of meta stuff like stylesheets might get annoyingly deep. Should we extend the DSL to support nesting without indentation? ``` window ... +stylesheet +foobar +foobaz foobad foomad ``` equivalent to: ``` window stylesheet foobar foobaz foobad foomad ```