178 lines
6.1 KiB
Odin
178 lines
6.1 KiB
Odin
package sectr
|
|
|
|
UI_LayoutDirectionX :: enum(i32) {
|
|
Left_To_Right,
|
|
Right_To_Left,
|
|
}
|
|
|
|
UI_LayoutDirectionY :: enum(i32) {
|
|
Top_To_Bottom,
|
|
Bottom_To_Top,
|
|
}
|
|
|
|
UI_LayoutSide :: struct {
|
|
// using _ : struct {
|
|
top, bottom : UI_Scalar,
|
|
left, right : UI_Scalar,
|
|
// }
|
|
}
|
|
|
|
// Desiered constraints on the UI_Box.
|
|
UI_Layout :: struct {
|
|
anchor : Range2,
|
|
alignment : Vec2,
|
|
text_alignment : Vec2,
|
|
|
|
font_size : f32,
|
|
|
|
margins : UI_LayoutSide,
|
|
padding : UI_LayoutSide,
|
|
|
|
// TODO(Ed): We cannot support individual corners unless we add it to raylib (or finally change the rendering backend)
|
|
corner_radii : [Corner.Count]f32,
|
|
border_width : UI_Scalar,
|
|
|
|
// Position in relative coordinate space.
|
|
// If the box's flags has Fixed_Position, then this will be its aboslute position in the relative coordinate space
|
|
pos : Vec2,
|
|
size : Range2,
|
|
|
|
// TODO(Ed) : Should thsi just always be WS_Pos for workspace UI?
|
|
// (We can union either varient and just know based on checking if its the screenspace UI)
|
|
// If the box is a child of the root parent, its automatically in world space and thus will use the tile_pos.
|
|
// tile_pos : WS_Pos,
|
|
}
|
|
|
|
// TODO(Ed): Change this to layout flags? Everything so far is just related to auto-layout
|
|
UI_StyleFlag :: enum u32 {
|
|
|
|
// Will perform scissor pass on children to their parent's bounds
|
|
// (Specified in the parent)
|
|
Clip_Children_To_Bounds,
|
|
|
|
// Enforces the box will always remain in a specific position relative to the parent.
|
|
// Overriding the anchors and margins.
|
|
Fixed_Position_X,
|
|
Fixed_Position_Y,
|
|
|
|
// Enforces box will always be within the bounds of the parent box.
|
|
Clamp_Position_X,
|
|
Clamp_Position_Y,
|
|
|
|
// Enroces the widget will maintain its size reguardless of any constraints
|
|
// Will override parent constraints (use the size.min.xy to specify the width & height)
|
|
Fixed_Width,
|
|
Fixed_Height,
|
|
|
|
// TODO(Ed): Implement this!
|
|
// Enforces the widget will have a width specified as a ratio of its height (use the size.min/max.x to specify the scalar)
|
|
// If you wish for the width to stay fixed couple with the Fixed_Width flag
|
|
Scale_Width_By_Height_Ratio,
|
|
// Enforces the widget will have a height specified as a ratio of its width (use the size.min/max.y to specify the scalar)
|
|
// If you wish for the height to stay fixed couple with the Fixed_Height flag
|
|
Scale_Height_By_Width_Ratio,
|
|
|
|
// Sets the (0, 0) position of the child box to the parents anchor's center (post-margins bounds)
|
|
// By Default, the origin is at the top left of the anchor's bounds
|
|
Origin_At_Anchor_Center,
|
|
|
|
// TODO(Ed): Implement this!
|
|
// For this to work, the children must have a minimum size set & their size overall must be greater than the parent's minimum size
|
|
Size_To_Content,
|
|
|
|
// Will size the box to its text.
|
|
Size_To_Text,
|
|
|
|
// TODO(Ed): Implement this!
|
|
Text_Wrap,
|
|
|
|
Count,
|
|
}
|
|
UI_StyleFlags :: bit_set[UI_StyleFlag; u32]
|
|
|
|
UI_StylePreset :: enum u32 {
|
|
Default,
|
|
Disabled,
|
|
Hot,
|
|
Active,
|
|
Count,
|
|
}
|
|
|
|
UI_Style :: struct {
|
|
flags : UI_StyleFlags,
|
|
|
|
bg_color : Color,
|
|
border_color : Color,
|
|
|
|
// TODO(Ed) : Add support for this eventually
|
|
blur_size : f32,
|
|
|
|
font : FontID,
|
|
// TODO(Ed): Should this get moved to the layout struct? Techncially font-size is mainly
|
|
text_color : Color,
|
|
|
|
cursor : UI_Cursor,
|
|
|
|
// TODO(Ed): Should layout be separate from style?
|
|
// It technically entirely makes up style flags
|
|
// and the only thing shared I guess is the font determining the measured text size + transition time
|
|
// Technically we can provide a separate transition time option just for layout...
|
|
using layout : UI_Layout,
|
|
|
|
// Used with style, prev_style, and style_delta to produce a simple interpolated animation
|
|
// Applied in the layout pass & the rendering pass for their associated fields.
|
|
transition_time : f32,
|
|
}
|
|
|
|
UI_StyleTheme :: struct #raw_union {
|
|
array : [UI_StylePreset.Count] UI_Style,
|
|
using styles : struct {
|
|
default, disabled, hot, active : UI_Style,
|
|
}
|
|
}
|
|
|
|
UI_TextAlign :: enum u32 {
|
|
Left,
|
|
Center,
|
|
Right,
|
|
Count
|
|
}
|
|
|
|
to_ui_layoutside :: #force_inline proc( pixels : f32 ) -> UI_LayoutSide { return { pixels, pixels, pixels, pixels } }
|
|
|
|
to_ui_styletheme :: #force_inline proc( style : UI_Style ) -> UI_StyleTheme { return { styles = {style, style, style, style} } }
|
|
|
|
ui_style_peek :: #force_inline proc( box_state : UI_StylePreset ) -> UI_Style { return stack_peek_ref( & get_state().ui_context.theme_stack ).array[box_state] }
|
|
ui_style_ref :: #force_inline proc( box_state : UI_StylePreset ) -> (^ UI_Style) { return & stack_peek_ref( & get_state().ui_context.theme_stack ).array[box_state] }
|
|
|
|
ui_style_set :: #force_inline proc ( style : UI_Style, box_state : UI_StylePreset ) { stack_peek_ref( & get_state().ui_context.theme_stack ).array[box_state] = style }
|
|
|
|
ui_style_set_layout :: #force_inline proc ( layout : UI_Layout, preset : UI_StylePreset ) { stack_peek_ref( & get_state().ui_context.theme_stack ).array[preset].layout = layout }
|
|
|
|
ui_style_theme_push :: #force_inline proc( preset : UI_StyleTheme ) { push( & get_state().ui_context.theme_stack, preset ) }
|
|
ui_style_theme_pop :: #force_inline proc() { pop( & get_state().ui_context.theme_stack ) }
|
|
|
|
@(deferred_none = ui_style_theme_pop)
|
|
ui_style_theme :: #force_inline proc( preset : UI_StyleTheme ) { ui_style_theme_push( preset ) }
|
|
|
|
ui_style_theme_peek :: #force_inline proc() -> UI_StyleTheme { return stack_peek( & get_state().ui_context.theme_stack ) }
|
|
ui_style_theme_ref :: #force_inline proc() -> (^ UI_StyleTheme) { return stack_peek_ref( & get_state().ui_context.theme_stack ) }
|
|
|
|
@(deferred_none = ui_style_theme_pop)
|
|
ui_theme_via_style :: #force_inline proc ( style : UI_Style ) { ui_style_theme_push( UI_StyleTheme { styles = { style, style, style, style } }) }
|
|
|
|
ui_style_theme_set_layout :: proc ( layout : UI_Layout ) {
|
|
for & preset in stack_peek_ref( & get_state().ui_context.theme_stack ).array {
|
|
preset.layout = layout
|
|
}
|
|
}
|
|
|
|
ui_style_theme_layout_push :: proc ( layout : UI_Layout ) {
|
|
ui := get_state().ui_context
|
|
ui_style_theme_push( stack_peek( & ui.theme_stack) )
|
|
ui_style_theme_set_layout(layout)
|
|
}
|
|
|
|
@(deferred_none = ui_style_theme_pop)
|
|
ui_style_theme_layout :: #force_inline proc( layout : UI_Layout ) { ui_style_theme_layout_push(layout) }
|