Mostly reviewing progress so far
Prepping in the background for swapping raylib with sokol.
This commit is contained in:
@ -3,8 +3,13 @@
|
||||
Eventually want to generalize this core UI as its own library.
|
||||
This will keep track of here whats needed for it to work wihtout the rest of this codebase.
|
||||
|
||||
* Provide UI input state or "events" in its own data stucture at the beginning of `ui_build_graph`:
|
||||
*
|
||||
* Provide UI input "events" in its own data stucture at the beginning of `ui_build_graph`:
|
||||
* Needed so that the UI can consume events in ui_signal_from_box.
|
||||
* Make a global context state separate from UI_State for storing info persistent to all UI_States
|
||||
* This is needed since UI_State can contextually exist for different viewports, etc.
|
||||
* The ui state's major functions all assume a context
|
||||
* ...
|
||||
|
||||
--
|
||||
|
||||
TODO(Ed): I'm not sure what to make the default coordinate space for this widget
|
||||
It would eventually be nice to make this multi-threaded but its that isn't a major concern anytime soon.
|
@ -34,11 +34,9 @@ UI_Box :: struct {
|
||||
text : StrRunesPair,
|
||||
|
||||
// Regenerated per frame.
|
||||
|
||||
nav : UI_NavLinks,
|
||||
// signal_callback : #type proc(),
|
||||
|
||||
|
||||
// first, last : The first and last child of this box
|
||||
// prev, next : The adjacent neighboring boxes who are children of to the same parent
|
||||
using links : DLL_NodeFull( UI_Box ),
|
||||
@ -60,9 +58,6 @@ UI_Box :: struct {
|
||||
style_delta : f32,
|
||||
first_frame : b8,
|
||||
// root_order_id : i16,
|
||||
|
||||
// mouse : UI_InteractState,
|
||||
// keyboard : UI_InteractState,
|
||||
}
|
||||
|
||||
ui_box_equal :: #force_inline proc "contextless" ( a, b : ^ UI_Box ) -> b32 {
|
||||
|
@ -174,6 +174,11 @@ ui_box_compute_layout :: proc( box : ^UI_Box,
|
||||
computed.fresh = true && !dont_mark_fresh
|
||||
}
|
||||
|
||||
ui_compute_children_bounding_area :: proc ( box : ^UI_Box )
|
||||
{
|
||||
// TODO(Ed): Implement this so we can have the .Size_To_Content flag supported.
|
||||
}
|
||||
|
||||
ui_box_compute_layout_children :: proc( box : ^UI_Box )
|
||||
{
|
||||
for current := box.first; current != nil && current.prev != box; current = ui_box_tranverse_next( current )
|
||||
|
@ -100,14 +100,7 @@ UI_State :: struct {
|
||||
render_queue : Array(UI_RenderBoxInfo),
|
||||
|
||||
null_box : ^UI_Box, // This was used with the Linked list interface...
|
||||
// TODO(Ed): Should we change our convention for null boxes to use the above and nil as an invalid state?
|
||||
root : ^UI_Box,
|
||||
// Children of the root node are unique in that they have their order preserved per frame
|
||||
// This is to support overlapping frames
|
||||
// So long as their parent-index is non-negative they'll be rendered
|
||||
|
||||
// Do we need to recompute the layout?
|
||||
// layout_dirty : b32,
|
||||
|
||||
// TODO(Ed) : Look into using a build arena like Ryan does for these possibly (and thus have a linked-list stack)
|
||||
layout_combo_stack : StackFixed( UI_LayoutCombo, UI_Style_Stack_Size ),
|
||||
@ -131,6 +124,8 @@ UI_State :: struct {
|
||||
last_pressed_key_us : [MouseBtn.count] f32,
|
||||
}
|
||||
|
||||
#region("Lifetime")
|
||||
|
||||
ui_startup :: proc( ui : ^ UI_State, cache_allocator : Allocator /* , cache_reserve_size : u64 */ )
|
||||
{
|
||||
ui := ui
|
||||
@ -164,20 +159,6 @@ ui_reload :: proc( ui : ^ UI_State, cache_allocator : Allocator )
|
||||
ui_shutdown :: proc() {
|
||||
}
|
||||
|
||||
ui_cursor_pos :: #force_inline proc "contextless" () -> Vec2 {
|
||||
using state := get_state()
|
||||
if ui_context == & state.project.workspace.ui {
|
||||
return screen_to_ws_view_pos( input.mouse.pos )
|
||||
}
|
||||
else {
|
||||
return input.mouse.pos
|
||||
}
|
||||
}
|
||||
|
||||
ui_drag_delta :: #force_inline proc "contextless" () -> Vec2 {
|
||||
using state := get_state()
|
||||
return ui_cursor_pos() - state.ui_context.active_start_signal.cursor_pos
|
||||
}
|
||||
|
||||
ui_graph_build_begin :: proc( ui : ^ UI_State, bounds : Vec2 = {} )
|
||||
{
|
||||
@ -249,6 +230,22 @@ ui_graph_build_end :: proc( ui : ^UI_State )
|
||||
@(deferred_in = ui_graph_build_end)
|
||||
ui_graph_build :: #force_inline proc( ui : ^ UI_State ) { ui_graph_build_begin( ui ) }
|
||||
|
||||
#endregion("Lifetime")
|
||||
|
||||
#region("Caching")
|
||||
// Mainly referenced from RAD Debugger
|
||||
|
||||
// TODO(Ed): Need to setup the proper hashing convention for strings the other reference imguis use.
|
||||
ui_hash_from_string :: proc ( value : string ) -> u64 {
|
||||
fatal("NOT IMPLEMENTED")
|
||||
return 0
|
||||
}
|
||||
|
||||
ui_hash_part_from_key_string :: proc ( content : string ) -> string {
|
||||
fatal("NOT IMPLEMENTED")
|
||||
return ""
|
||||
}
|
||||
|
||||
ui_key_from_string :: #force_inline proc "contextless" ( value : string ) -> UI_Key
|
||||
{
|
||||
// profile(#procedure)
|
||||
@ -270,6 +267,22 @@ ui_key_from_string :: #force_inline proc "contextless" ( value : string ) -> UI_
|
||||
|
||||
return key
|
||||
}
|
||||
#endregion("Caching")
|
||||
|
||||
ui_cursor_pos :: #force_inline proc "contextless" () -> Vec2 {
|
||||
using state := get_state()
|
||||
if ui_context == & state.project.workspace.ui {
|
||||
return screen_to_ws_view_pos( input.mouse.pos )
|
||||
}
|
||||
else {
|
||||
return input.mouse.pos
|
||||
}
|
||||
}
|
||||
|
||||
ui_drag_delta :: #force_inline proc "contextless" () -> Vec2 {
|
||||
using state := get_state()
|
||||
return ui_cursor_pos() - state.ui_context.active_start_signal.cursor_pos
|
||||
}
|
||||
|
||||
ui_parent_push :: #force_inline proc( ui : ^ UI_Box ) { stack_push( & ui_context().parent_stack, ui ) }
|
||||
ui_parent_pop :: #force_inline proc() { stack_pop( & get_state().ui_context.parent_stack ) }
|
||||
|
@ -1,5 +1,12 @@
|
||||
package sectr
|
||||
|
||||
/*
|
||||
Themes: While technically in UI_State we only store the layout and style combo pairs in separate stacks, most of the time
|
||||
widgets will want to push or pop a (layout_combo, style_combo) pair during construction.
|
||||
|
||||
Themes provide that ease of use.
|
||||
*/
|
||||
|
||||
UI_ThemePtr :: struct {
|
||||
layout : ^UI_LayoutCombo,
|
||||
style : ^UI_StyleCombo,
|
||||
|
@ -65,22 +65,24 @@ ui_layout_children_horizontally :: proc( container : ^UI_Box, direction : UI_Lay
|
||||
|
||||
space_used : f32 = 0.0
|
||||
switch direction{
|
||||
case .Right_To_Left:
|
||||
for child := container.last; child != nil; child = child.prev {
|
||||
using child.layout
|
||||
child_width := allocate_space(child, total_stretch_ratio, avail_flex_space, container_height)
|
||||
anchor = range2({0, 0}, {0, 0})
|
||||
pos.x = space_used
|
||||
space_used += child_width + child.layout.margins.left + child.layout.margins.right
|
||||
}
|
||||
case .Left_To_Right:
|
||||
for child := container.first; child != nil; child = child.next {
|
||||
using child.layout
|
||||
child_width := allocate_space(child, total_stretch_ratio, avail_flex_space, container_height)
|
||||
anchor = range2({0, 0}, {0, 0})
|
||||
alignment = {0, 0}
|
||||
pos.x = space_used
|
||||
space_used += child_width + child.layout.margins.left + child.layout.margins.right
|
||||
}
|
||||
case .Right_To_Left:
|
||||
for child := container.first; child != nil; child = child.next {
|
||||
using child.layout
|
||||
child_width := allocate_space(child, total_stretch_ratio, avail_flex_space, container_height)
|
||||
anchor = range2({1, 0}, {0, 0})
|
||||
alignment = {1, 0}
|
||||
pos.x = space_used
|
||||
space_used -= child_width + child.layout.margins.left + child.layout.margins.right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,10 +141,10 @@ ui_layout_children_vertically :: proc( container : ^UI_Box, direction : UI_Layou
|
||||
return
|
||||
}
|
||||
|
||||
space_used : f32 = 0
|
||||
switch direction
|
||||
{
|
||||
case .Top_To_Bottom:
|
||||
space_used : f32 = 0
|
||||
for child := container.first; child != nil; child = child.next {
|
||||
using child.layout
|
||||
child_height := allocate_space(child, total_stretch_ratio, avail_flex_space, container_width)
|
||||
@ -152,7 +154,6 @@ ui_layout_children_vertically :: proc( container : ^UI_Box, direction : UI_Layou
|
||||
space_used -= child_height - child.layout.margins.top - child.layout.margins.bottom
|
||||
}
|
||||
case .Bottom_To_Top:
|
||||
space_used : f32 = 0
|
||||
for child := container.first; child != nil; child = child.next {
|
||||
using child.layout
|
||||
child_height := allocate_space(child, total_stretch_ratio, avail_flex_space, container_width)
|
||||
|
@ -27,8 +27,6 @@ ui_button :: proc( label : string, flags : UI_BoxFlags = {} ) -> (btn : UI_Widge
|
||||
}
|
||||
|
||||
#region("Drop Down")
|
||||
/* TODO(Ed): Don't feel very good about the abstraction...
|
||||
*/
|
||||
UI_DropDown :: struct {
|
||||
btn : UI_Widget,
|
||||
title : UI_Widget,
|
||||
@ -215,14 +213,6 @@ ui_resizable_end :: proc( resizable : ^UI_Resizable, pos, size : ^Vec2 ) {
|
||||
compute_layout)
|
||||
}
|
||||
|
||||
ui_resizable_begin_auto :: proc() {
|
||||
|
||||
}
|
||||
|
||||
ui_resizable_end_auto :: proc() {
|
||||
|
||||
}
|
||||
|
||||
// Adds resizable handles to a widget
|
||||
ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2,
|
||||
handle_width : f32 = 15,
|
||||
@ -505,13 +495,12 @@ UI_ScrollBox :: struct {
|
||||
content : UI_Widget,
|
||||
}
|
||||
|
||||
// TODO(Ed): Implement
|
||||
ui_scroll_box :: proc( label : string, flags : UI_BoxFlags ) -> (scroll_box : UI_ScrollBox) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ui_scrollable_view( )
|
||||
|
||||
#region("Text")
|
||||
ui_text :: proc( label : string, content : StrRunesPair, flags : UI_BoxFlags = {} ) -> UI_Widget
|
||||
{
|
||||
|
Reference in New Issue
Block a user