Began working on a proper default theme

Going with dark mode at first,
I'll also be making a lightmode, but I want to have a post-processing shader for tonemapping the app screen's tone by the user before doing so.
This commit is contained in:
Edward R. Gonzalez 2024-05-15 03:34:52 -04:00
parent fd2552a82f
commit af757cfdaa
17 changed files with 380 additions and 222 deletions

View File

@ -59,3 +59,4 @@ They'll be elaborated in their own documentation
![img](docs/assets/sectr_host_2024-05-04_12-29-39.png)
![img](docs/assets/Code_2024-05-04_12-55-53.png)
![img](docs/assets/sectr_host_2024-05-11_22-34-15.png)
![img](docs/assets/sectr_host_2024-05-15_03-32-36.png)

View File

@ -21,7 +21,7 @@ UI_ScreenState :: struct
settings_menu : struct
{
pos, size, min_size : Vec2,
vb_container : UI_VBox,
container : UI_Widget,
is_open : b32,
is_maximized : b32,
},
@ -42,7 +42,7 @@ ui_screen_tick :: proc() {
ui_floating_manager_end()
}
ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 )
ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 = false )
{
profile("App Menu Bar")
fmt :: str_fmt_alloc
@ -52,41 +52,17 @@ ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 )
{
using state := get_state();
using screen_ui.menu_bar
ui_layout( UI_Layout {
flags = {.Fixed_Position_X, .Fixed_Position_Y, .Fixed_Width, .Fixed_Height, .Origin_At_Anchor_Center},
// anchor = range2({0.5, 0.5}, {0.5, 0.5} ),
alignment = { 0.5, 0.5 },
border_width = 1.0,
font_size = 12,
// pos = {},
pos = pos,
size = range2( size, {}),
})
ui_style( UI_Style {
bg_color = { 0, 0, 0, 30 },
border_color = { 0, 0, 0, 200 },
font = default_font,
text_color = Color_White,
})
ui_theme_app_menu_bar_default()
container = ui_hbox( .Left_To_Right, "Menu Bar" )
{
using container
layout.flags = {.Fixed_Position_X, .Fixed_Position_Y, .Fixed_Width, .Fixed_Height, .Origin_At_Anchor_Center}
layout.pos = pos
layout.size = range2( size, {})
text = str_intern("menu_bar")
}
ui_layout( UI_Layout {
flags = {},
anchor = {},
alignment = { 0.0, 0.0 },
text_alignment = {0.5, 0.5},
border_width = 1.0,
font_size = 12,
})
style_theme := to_ui_style_combo({
bg_color = Color_Frame_Disabled,
font = default_font,
text_color = Color_White,
})
style_theme.hot.bg_color = Color_Blue
style_theme.active.bg_color = Color_Frame_Select
ui_style(style_theme)
ui_theme_btn_default()
move_box := ui_button("Move Box");
{
using move_box
@ -94,22 +70,26 @@ ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 )
pos += input.mouse.delta
should_raise = true
}
layout.anchor.ratio.x = 0.2
layout.anchor.ratio.x = 0.4
}
spacer := ui_spacer("Menu Bar: Move Spacer")
spacer.layout.flags |= {.Fixed_Width}
spacer.layout.size.min.x = 50
spacer.layout.size.min.x = 30
// TODO(Ed): Implement an external composition for theme interpolation using the settings btn
settings_btn.widget = ui_button("Settings Btn")
settings_btn.text = str_intern("Settings")
settings_btn.layout.flags = {
// .Scale_Width_By_Height_Ratio,
.Fixed_Width
}
settings_btn.layout.size.min.x = 100
if settings_btn.pressed {
screen_ui.settings_menu.is_open = true
{
using settings_btn
text = str_intern("Settings")
layout.flags = {
// .Scale_Width_By_Height_Ratio,
.Fixed_Width
}
layout.size.min.x = 100
if pressed {
screen_ui.settings_menu.is_open = true
}
}
spacer = ui_spacer("Menu Bar: End Spacer")
@ -118,46 +98,44 @@ ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 )
return
}
ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b32)
ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b32 = false)
{
profile("Settings Menu")
using state := get_state()
using state.screen_ui
if ! settings_menu.is_open do return false
if ! settings_menu.is_open do return
using settings_menu
if size.x < min_size.x do size.x = min_size.x
if size.y < min_size.y do size.y = min_size.y
resize_box_base := ui_widget("Settings Menu Wrapper", {})
container = ui_widget("Settings Menu", {})
{
using resize_box_base
layout.flags = { .Fixed_Width, .Fixed_Height, .Origin_At_Anchor_Center, .Fixed_Position_X, .Fixed_Position_Y }
layout.pos = pos
layout.alignment = { 0.5, 0.5 }
layout.size = range2( size, {})
style.bg_color = Color_3D_BG
using container
layout.flags = { .Fixed_Width, .Fixed_Height, .Origin_At_Anchor_Center, .Fixed_Position_X, .Fixed_Position_Y }
layout.alignment = { 0.5, 0.5 }
// style.bg_color = Color_3D_BG
style.border_color = { 0, 0, 0, 200 }
layout.border_width = 1.0
layout.pos = pos
layout.size = range2( size, {})
}
ui_parent(resize_box_base)
ui_parent(container)
if settings_menu.is_maximized {
using resize_box_base
using container
layout.flags = {.Origin_At_Anchor_Center }
layout.pos = {}
}
ui_resizable_handles( & resize_box_base, & pos, & size)
should_raise |= ui_resizable_handles( & container, & pos, & size)
vb_container = ui_vbox_begin( .Top_To_Bottom, "Settings Menu", {.Mouse_Clickable}, compute_layout = true)
vbox := ui_vbox_begin( .Top_To_Bottom, "Settings Menu: VBox", {.Mouse_Clickable}, compute_layout = true)
{
{
using vb_container
flags = {}
style.bg_color = Color_BG_Panel_Translucent
}
ui_parent(vb_container)
vbox.style.bg_color = Color_BG_Panel_Translucent
ui_parent(vbox)
ui_layout( UI_Layout {
font_size = 16,
alignment = {0, 0},
// font_size = 16,
// alignment = {0, 1},
})
ui_style( UI_Style {
bg_color = Color_Transparent,
@ -165,19 +143,16 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b
text_color = Color_White,
})
ui_style_ref().hot.bg_color = Color_Blue
frame_bar : UI_HBox
frame_bar = ui_hbox_begin(.Left_To_Right, "Settings Menu: Frame Bar", { .Mouse_Clickable, .Focusable, .Click_To_Focus })
frame_bar := ui_hbox_begin(.Left_To_Right, "Settings Menu: Frame Bar", { .Mouse_Clickable, .Focusable, .Click_To_Focus })
{
frame_bar.style.bg_color = Color_BG_Panel
frame_bar.layout.flags = {.Fixed_Height}
frame_bar.layout.size.min.y = 50
frame_bar.layout.anchor.ratio.y = 0.25
// frame_bar.layout.anchor.ratio.y = 0.8
ui_parent(frame_bar)
ui_layout( UI_Layout {
font_size = 16,
// alignment = {1, 0},
// anchor = range2({}, {})
font_size = 18,
})
title := ui_text("Settings Menu: Title", str_intern("Settings Menu"), {.Disabled})
{
@ -187,6 +162,10 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b
layout.anchor.ratio.x = 1.0
}
ui_layout( UI_Layout {
font_size = 16,
})
ui_style(ui_style_peek())
style := ui_style_ref()
style.default.bg_color = Color_Black
@ -228,65 +207,70 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b
should_raise = true
}
ui_style( UI_Style {
bg_color = Color_Red,
font = default_font,
text_color = Color_White,
})
// Populate settings with values from config (hardcoded for now)
ui_layout(UI_Layout {
flags = {
// .Origin_At_Anchor_Center,
// .Fixed_Height,
},
// pos = {0, 50},
// size = range2({100, 100},{}),
// alignment = {0,0},
})
ui_style( UI_Style {
// bg_color = Color_GreyRed
})
drop_down_bar := ui_hbox_begin(.Left_To_Right, "settings_menu.vbox: config drop_down_bar", {.Mouse_Clickable})
{
ui_layout(UI_Layout {
flags = {
// .Origin_At_Anchor_Center,
// .Fixed_Height,
},
// pos = {0, 50},
// size = range2({100, 100},{}),
// alignment = {0,0},
})
ui_style( UI_Style {
bg_color = Color_GreyRed
})
drop_down_bar.layout.anchor.ratio.y = 0.1
{
drop_down_bar := ui_hbox_begin(.Left_To_Right, "settings_menu.vbox: config drop_down_bar", {.Mouse_Clickable})
drop_down_bar.layout.anchor.ratio.y = 1.0
// drop_down_bar.style.bg_color = Color_Red
ui_parent(drop_down_bar)
btn := ui_button("pls")
btn.text = str_intern("Config")
btn.style.font = default_font
btn.layout.font_size = 32
btn.layout.size.min.y = 50
btn.layout.text_alignment = { 0.5, 0.5 }
btn.layout.flags = {.Fixed_Width, .Size_To_Text}
// btn.layout.size.min = {50, 0}
btn.style.bg_color = Color_Green
ui_hbox_end(drop_down_bar, compute_layout = false)
using drop_down_bar
text = str_intern("drop_down_bar")
style.bg_color = { 55, 55, 55, 100 }
style.font = default_font
style.text_color = Color_White
layout.flags = {.Fixed_Height}
layout.font_size = 12
layout.text_alignment = {1, 0}
layout.size.min.y = 35
}
ui_parent(drop_down_bar)
// ui_layout(UI_Layout {
// })
// ui_style( UI_Style {
// })
// res_width_hbox := ui_hbox_begin(.Left_To_Right, "settings_menu.vbox: config.resolution_width: hbox", {})
// ui_parent(res_width_hbox)
btn := ui_text("pls", str_intern("Lets figure this out..."))
{
using btn
text = str_intern("Config")
style.font = default_font
style.text_color = Color_White
layout.flags = {.Origin_At_Anchor_Center}
layout.alignment = {0.5, 0.25} // ??? (Wtf is this alignment)
layout.anchor.ratio.x = 1.0
layout.font_size = 12
layout.margins = {0,0, 15, 0}
layout.size.min.y = 35
}
ui_hbox_end(drop_down_bar, compute_layout = false)
ui_box_compute_layout(btn)
}
// ui_layout(UI_Layout {
// })
// ui_style( UI_Style {
// })
// res_width_hbox := ui_hbox_begin(.Left_To_Right, "settings_menu.vbox: config.resolution_width: hbox", {})
// ui_parent(res_width_hbox)
// ui_layout_ref().default.flags = {.Fixed_Width, .Fixed_Height, .Fixed_Position_Y}
// ui_layout_ref().default.size.min = {50, 50}
spacer := ui_spacer("Settings Menu: Spacer")
// spacer.style.bg_color = Color_Red
spacer.layout.anchor.ratio.y = 1.0
// spacer.layout.flags = {.Origin_At_Anchor_Center}
// spacer.layout.alignment = {0.5, 0.5}
// spacer.style.bg_color = Color_Red
// ui_box_compute_layout(spacer)
ui_vbox_end(vb_container, compute_layout = false )
// ui_box_compute_layout(spacer)
ui_vbox_end(vbox, compute_layout = true )
}
return
}

View File

@ -27,3 +27,30 @@ Color_3D_BG :: Color { 188, 182 , 170, 255 }
Color_Debug_UI_Padding_Bounds :: Color { 40, 195, 170, 160 }
Color_Debug_UI_Content_Bounds :: Color { 170, 120, 240, 160 }
// TODO(Ed): The entire rendering pass should be post-processed by a tone curve configurable for the user
// This is how you properly support any tonality of light or dark themes and not have it be base don the monitors raw output.
// Dark Theme
// Brightest value limited to (text is the only exception):
Color_ThmDark_BrightLimit :: Color {230, 230, 230, 255}
// Darkness value limited to (text is the only exception):
Color_ThmDark_DarkLimit :: Color {10, 10, 10, 255}
Color_ThmDark_BG :: Color {33, 33, 33, 255}
Color_ThmDark_Border_Default :: Color { 64, 64, 64, 255}
Color_ThmDark_Btn_BG_Default :: Color { 40, 40, 40, 255}
Color_ThmDark_Btn_BG_Hot :: Color { 60, 60, 70, 255}
Color_ThmDark_Btn_BG_Active :: Color { 90, 100, 130, 255}
Color_ThmDark_Text_Default :: Color {120, 117, 115, 255}
Color_ThmDark_Text_Hot :: Color {180, 180, 180, 255}
Color_ThmDark_Text_Active :: Color {240, 240, 240, 255}
// Light Theme
// LightTheme_BG :: Color { 120, 120, 120, 255 }

View File

@ -171,7 +171,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
// Setup the screen ui state
{
ui_startup( & screen_ui.base, cache_allocator = persistent_slab_allocator() )
ui_floating_startup( & screen_ui.floating, persistent_slab_allocator(), 16 * Kilobyte, 16 * Kilobyte, "screen ui floating manager" )
ui_floating_startup( & screen_ui.floating, persistent_slab_allocator(), 1 * Kilobyte, 1 * Kilobyte, "screen ui floating manager" )
using screen_ui
menu_bar.pos = { -60, 0 }
@ -277,7 +277,7 @@ reload :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem,
slab_reload( persistent_slab, persistent_allocator() )
hmap_chained_reload( font_provider_data.font_cache, persistent_slab_allocator())
hmap_chained_reload( font_provider_data.font_cache, persistent_allocator())
slab_reload( string_cache.slab, persistent_allocator() )
zpl_hmap_reload( & string_cache.table, persistent_slab_allocator())
@ -318,9 +318,9 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32
rl.PollInputEvents()
debug.draw_ui_box_bounds_points = true
debug.draw_UI_padding_bounds = true
debug.draw_ui_content_bounds = true
debug.draw_ui_box_bounds_points = false
debug.draw_UI_padding_bounds = false
debug.draw_ui_content_bounds = false
should_close = update( host_delta_time )
render()
@ -331,8 +331,8 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32
// Timing
{
// profile("Client tick timing processing")
// config.engine_refresh_hz = uint(monitor_refresh_hz)
config.engine_refresh_hz = 6
config.engine_refresh_hz = uint(monitor_refresh_hz)
// config.engine_refresh_hz = 6
frametime_target_ms = 1.0 / f64(config.engine_refresh_hz) * S_To_MS
sub_ms_granularity_required := frametime_target_ms <= Frametime_High_Perf_Threshold_MS

View File

@ -128,7 +128,7 @@ dll_pop_back :: #force_inline proc "contextless" ( current_ptr : ^(^ ($ Type)) )
}
}
dll_full_insert_raw :: proc "contextless" ( null : ^($ Type), parent, pos, node : ^Type )
dll_full_insert_raw :: proc "contextless" ( null : ^($ Type), parent : ^$ParentType, pos, node : ^Type )
{
if parent.first == null {
parent.first = node
@ -161,7 +161,7 @@ dll_full_insert_raw :: proc "contextless" ( null : ^($ Type), parent, pos, node
}
}
dll_full_pop :: proc "contextless" ( node, parent : ^$Type ) {
dll_full_pop :: proc "contextless" ( node : ^$NodeType, parent : ^$ParentType ) {
if node == nil {
return
}
@ -171,20 +171,19 @@ dll_full_pop :: proc "contextless" ( node, parent : ^$Type ) {
if parent.last == node {
parent.last = node.prev
}
if parent.first == parent.last {
parent.last = nil
}
if node.prev != nil {
node.prev.next = nil
prev := node.prev
next := node.next
if prev != nil {
prev.next = next
node.prev = nil
}
if node.next != nil {
node.next.prev = nil
if next != nil {
next.prev = prev
node.next = nil
}
}
dll_full_push_back :: proc "contextless" ( parent, node : ^ $Type, null : ^Type ) {
dll_full_push_back :: proc "contextless" ( parent : ^$ParentType, node : ^$Type, null : ^Type ) {
dll_full_insert_raw( null, parent, parent.last, node )
}

View File

@ -185,7 +185,7 @@ stack_allocator_proc :: proc(
alignment : int,
old_memory : rawptr,
old_size : int,
location : SourceCodeLocation = #caller_location
// location : SourceCodeLocation = #caller_location
) -> ([]byte, AllocatorError)
{
stack := StackAllocator { cast( ^StackAllocatorBase) allocator_data }

View File

@ -196,7 +196,7 @@ varena_allocator_proc :: proc(
alignment : int,
old_memory : rawptr,
old_size : int,
location : SourceCodeLocation = #caller_location
// location : SourceCodeLocation = #caller_location
) -> ( data : []byte, alloc_error : AllocatorError)
{
arena := cast( ^VArena) allocator_data

View File

@ -32,7 +32,7 @@ render :: proc()
render_mode_3d()
rl.BeginDrawing()
rl.ClearBackground( Color_BG )
rl.ClearBackground( Color_ThmDark_BG )
render_mode_2d_workspace()
render_mode_screenspace()

View File

@ -240,7 +240,7 @@ update :: proc( delta_time : f64 ) -> b32
// test_draggable()
// test_text_box()
// test_parenting( & default_layout, & frame_style_default )
test_whitespace_ast( & default_layout, & frame_style_default )
// test_whitespace_ast( & default_layout, & frame_style_default )
}
//endregion Workspace Imgui Tick

View File

@ -87,8 +87,6 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
key := ui_key_from_string( label )
links_perserved : DLL_NodeFull( UI_Box )
curr_box : (^ UI_Box)
prev_box := zpl_hmap_get( prev_cache, cast(u64) key )
{
@ -119,15 +117,17 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
// Clear non-persistent data
curr_box.computed.fresh = false
curr_box.links = links_perserved
curr_box.links = {}
curr_box.num_children = 0
// If there is a parent, setup the relevant references
parent := stack_peek( & parent_stack )
if parent != nil
{
dll_full_push_back( parent, curr_box, nil )
when false
when false {
dll_full_push_back( parent, curr_box, nil )
}
else
{
// |
// v
@ -160,8 +160,6 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
ui_box_tranverse_next :: proc "contextless" ( box : ^ UI_Box ) -> (^ UI_Box)
{
parent := box.parent
// Check to make sure parent is present on the screen, if its not don't bother.
// If current has children, do them first
using state := get_state()
@ -179,6 +177,16 @@ ui_box_tranverse_next :: proc "contextless" ( box : ^ UI_Box ) -> (^ UI_Box)
// There is no more adjacent nodes
if box.parent != nil
{
parent := box.parent
// Attempt to find a parent with a next, otherwise we just return a parent with nil
for ; parent.parent != nil;
{
if parent.next != nil {
break
}
parent = parent.parent
}
// Lift back up to parent, and set it to its next.
return parent.next
}

View File

@ -100,7 +100,7 @@ ui_floating_build :: proc()
lookup := hmap_chained_get( tracked, transmute(u64) key )
// Check if entry is already present
if lookup != nil && lookup.prev != nil && lookup.next != nil {
if lookup != nil && (lookup.next != nil || lookup == last) {
lookup.captures = to_enqueue.captures
lookup.builder = to_enqueue.builder
lookup.queued = true
@ -115,30 +115,36 @@ ui_floating_build :: proc()
ensure(false, "Failed to allocate entry to hashtable")
continue
}
lookup.queued = true
}
else {
lookup.captures = to_enqueue.captures
lookup.builder = to_enqueue.builder
lookup.queued = true
continue
}
lookup.queued = true
if first == nil {
first = lookup
last = lookup
continue
}
last.next = lookup
last = lookup
if first == last {
last = lookup
last.prev = first
first.next = last
continue
}
last.next = lookup
lookup.prev = last
last = lookup
}
array_clear(build_queue)
to_raise : ^UI_Floating
for entry := first; entry != nil; entry = entry.next
{
using entry
if ! queued
if ! entry.queued
{
ensure(false, "There should be no queue failures yet")
if entry == first
{
first = entry.next
@ -162,39 +168,45 @@ ui_floating_build :: proc()
entry.next = nil
}
if builder( captures ) && entry != last
if entry.builder( entry.captures ) && entry != last && to_raise == nil
{
PopEntry:
{
if first == nil {
first = entry
last = entry
break PopEntry
}
if entry == first
{
first = entry.next
entry.next = nil
break PopEntry
}
if entry == last
{
last = last.prev
last.prev = nil
entry.prev = nil
break PopEntry
}
left := entry.prev
right := entry.next
left.next = right
right.prev = left
}
last.next = entry
last = entry
to_raise = entry
}
queued = false
entry.queued = false
}
if to_raise != nil
{
dll_full_pop( to_raise, floating )
dll_full_push_back( floating, to_raise, nil )
// PopEntry:
// {
// if first == nil {
// first = to_raise
// last = to_raise
// break PopEntry
// }
// if to_raise == first
// {
// first = to_raise.next
// to_raise.next.prev = nil
// break PopEntry
// }
// if to_raise == last
// {
// // Do nothing no need to modify order
// return
// }
// left := to_raise.prev
// right := to_raise.next
// left.next = right
// right.prev = left
// }
// last.next = to_raise
// to_raise.prev = last
// last.next = nil
// last = to_raise
}
}

View File

@ -170,8 +170,8 @@ ui_box_compute_layout_children :: proc( box : ^UI_Box )
{
for current := box.first; current != nil; current = ui_box_tranverse_next( current )
{
// if current == box do return
// if current.computed.fresh do continue
if current == box do return
if current.computed.fresh do continue
ui_box_compute_layout( current )
}
}

View File

@ -44,9 +44,9 @@ ui_layout_children_horizontally :: proc( container : ^UI_Box, direction : UI_Lay
{
using child.layout
if ! (.Fixed_Width in flags) {
size.min.x = anchor.ratio.x * (1 / total_stretch_ratio) * avail_flex_space
size.min.x = anchor.ratio.x * (1 / total_stretch_ratio) * avail_flex_space - child.layout.margins.left - child.layout.margins.right
}
flags |= {.Fixed_Width}
flags |= {.Fixed_Width}
}
space_used : f32 = 0.0
@ -56,20 +56,16 @@ ui_layout_children_horizontally :: proc( container : ^UI_Box, direction : UI_Lay
allocate_space(child, total_stretch_ratio, avail_flex_space)
using child.layout
anchor = range2({0, 0}, {0, 0})
// alignment = { 0, 0 }// - hbox.layout.alignment
pos.x = space_used
space_used += size.min.x
// size.min.y = container.computed.content.max.y - container.computed.content.min.y
space_used += size.min.x + child.layout.margins.left + child.layout.margins.right
}
case .Left_To_Right:
for child := container.first; child != nil; child = child.next {
allocate_space(child, total_stretch_ratio, avail_flex_space)
using child.layout
anchor = range2({0, 0}, {0, 0})
// alignment = { 0, 0 }
pos.x = space_used
space_used += size.min.x
// size.min.y = container.computed.content.max.y - container.computed.content.min.y
space_used += size.min.x + child.layout.margins.left + child.layout.margins.right
}
}
}
@ -114,18 +110,19 @@ ui_layout_children_vertically :: proc( container : ^UI_Box, direction : UI_Layou
{
using child.layout
if ! (.Fixed_Height in flags) {
size.min.y = anchor.ratio.y * (1 / total_stretch_ratio) * avail_flex_space
size.min.y = (anchor.ratio.y * (1 / total_stretch_ratio) * avail_flex_space)
}
flags |= {.Fixed_Height}
}
space_used : f32 = 0.0
switch direction {
switch direction
{
case .Bottom_To_Top:
for child := container.last; child != nil; child = child.prev {
allocate_space(child, total_stretch_ratio, avail_flex_space)
using child.layout
anchor = range2({0, 0}, {0, 0})
anchor = range2({0,0}, {0, 0})
// alignment = {0, 0}
pos.y = -space_used
space_used += size.min.y

View File

@ -42,13 +42,141 @@ UI Themes: Comprise of UI_Box's layout & style
Provides presets for themes and their interface for manipulating the combo stacks in UI_State in pairs
*/
// TODO(Ed): Eventually this will have a configuration wizard, and we'll save the presets
UI_Theme_Btn_Default :: UI_Theme {
/*
UI_Theme_Template :: UI_Theme {
UI_Layout {
flags = {},
anchor = Range2{{},{}},
alignment = {},
text_alignment = {},
font_size = {},
margins = {},
padding = {},
border_width = {},
pos = {},
size = Range2{{},{}}
},
UI_Style {
bg_color = {},
corner_radii = {},
blur_size = 0,
font = {},
text_color = {},
cursor = 0,
}
}
*/
@(deferred_none = ui_theme_pop)
ui_theme_app_menu_bar_default :: proc()
{
@static theme : UI_Theme
// @static loaded : b32 = false
// if true && ! loaded
// {
layout := UI_Layout {
flags = {},
anchor = range2({},{}),
alignment = {0.5, 0.5},
text_alignment = {0.0, 1.5},
font_size = 12,
margins = {0, 0, 0, 0},
padding = {0, 0, 0, 0},
border_width = 0.6,
pos = {0, 0},
size = range2({},{})
}
style := UI_Style {
bg_color = Color_ThmDark_BG,
border_color = Color_ThmDark_Border_Default,
corner_radii = {},
blur_size = 0,
font = get_state().default_font,
text_color = Color_ThmDark_Text_Default,
cursor = {},
}
// loaded = true
layout_combo := to_ui_layout_combo(layout)
style_combo := to_ui_style_combo(style)
{
using layout_combo.hot
using style_combo.hot
bg_color = Color_ThmDark_Btn_BG_Hot
text_color = Color_ThmDark_Text_Hot
}
{
using layout_combo.active
using style_combo.active
bg_color = Color_ThmDark_Btn_BG_Active
text_color = Color_ThmDark_Text_Active
}
theme = UI_Theme {
layout_combo, style_combo
}
// }
ui_layout_push(theme.layout)
ui_style_push(theme.style)
}
@(deferred_none = ui_layout_pop)
ui_theme_btn_default :: #force_inline proc() {
ui_layout_push(UI_Theme_Btn_Default.layout)
ui_style_push(UI_Theme_Btn_Default.style)
@(deferred_none = ui_theme_pop)
ui_theme_btn_default :: proc()
{
@static theme : UI_Theme
// @static loaded : b32 = false
// if true && ! loaded
// {
layout := UI_Layout {
flags = {},
anchor = range2({},{}),
alignment = {0, 0},
text_alignment = {0.5, 0.5},
font_size = 16,
margins = {0, 0, 0, 0},
padding = {0, 0, 0, 0},
border_width = 1,
pos = {0, 0},
size = range2({},{})
}
style := UI_Style {
bg_color = Color_ThmDark_Btn_BG_Default,
border_color = Color_ThmDark_Border_Default,
corner_radii = {},
blur_size = 0,
font = get_state().default_font,
text_color = Color_ThmDark_Text_Default,
cursor = {},
}
// loaded = true
layout_combo := to_ui_layout_combo(layout)
style_combo := to_ui_style_combo(style)
{
using layout_combo.hot
using style_combo.hot
bg_color = Color_ThmDark_Btn_BG_Hot
text_color = Color_ThmDark_Text_Hot
margins = {2, 2, 2, 2}
}
{
using layout_combo.active
using style_combo.active
bg_color = Color_ThmDark_Btn_BG_Active
text_color = Color_ThmDark_Text_Active
margins = {2, 2, 2, 2}
}
theme = UI_Theme {
layout_combo, style_combo
}
// }
ui_layout_push(theme.layout)
ui_style_push(theme.style)
}

View File

@ -165,7 +165,7 @@ ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2,
corner_tl := true,
corner_br := true,
corner_bl := true,
compute_layout := true)
compute_layout := true) -> (drag_signal : b32)
{
profile(#procedure)
handle_left : UI_Widget
@ -259,15 +259,15 @@ ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2,
target_alignment : Vec2,
pos : ^Vec2,
size : ^Vec2,
alignment : ^Vec2, )
alignment : ^Vec2, ) -> b32
{
ui := get_state().ui_context
if ui.last_pressed_key != handle.key { return }
if ui.last_pressed_key != handle.key { return false }
size_delta := size_delta
pos_adjust := size^ * (alignment^ - target_alignment)
@static was_dragging := false
@static was_dragging : b32 = false
using handle
if active
@ -287,21 +287,23 @@ ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2,
alignment^ = target_alignment
was_dragging = false
}
return was_dragging
}
delta := get_state().input.mouse.delta
alignment := & parent.layout.alignment
if right do process_handle_drag( & handle_right, { 1, 0 }, delta, {0, 0}, pos, size, alignment )
if left do process_handle_drag( & handle_left, { -1, 0 }, delta, {1, 0}, pos, size, alignment )
if top do process_handle_drag( & handle_top, { 0, 1 }, delta, {0, 0}, pos, size, alignment )
if bottom do process_handle_drag( & handle_bottom, { 0, -1 }, delta, {0, 1}, pos, size, alignment )
if corner_tr do process_handle_drag( & handle_corner_tr, { 1, 1 }, delta, {0, 0}, pos, size, alignment )
if corner_tl do process_handle_drag( & handle_corner_tl, { -1, 1 }, delta, {1, 0}, pos, size, alignment )
if corner_br do process_handle_drag( & handle_corner_br, { 1, -1 }, delta, {0, 1}, pos, size, alignment )
if corner_bl do process_handle_drag( & handle_corner_bl, { -1, -1 }, delta, {1, 1}, pos, size, alignment )
if right do drag_signal |= process_handle_drag( & handle_right, { 1, 0 }, delta, {0, 0}, pos, size, alignment )
if left do drag_signal |= process_handle_drag( & handle_left, { -1, 0 }, delta, {1, 0}, pos, size, alignment )
if top do drag_signal |= process_handle_drag( & handle_top, { 0, 1 }, delta, {0, 0}, pos, size, alignment )
if bottom do drag_signal |= process_handle_drag( & handle_bottom, { 0, -1 }, delta, {0, 1}, pos, size, alignment )
if corner_tr do drag_signal |= process_handle_drag( & handle_corner_tr, { 1, 1 }, delta, {0, 0}, pos, size, alignment )
if corner_tl do drag_signal |= process_handle_drag( & handle_corner_tl, { -1, 1 }, delta, {1, 0}, pos, size, alignment )
if corner_br do drag_signal |= process_handle_drag( & handle_corner_br, { 1, -1 }, delta, {0, 1}, pos, size, alignment )
if corner_bl do drag_signal |= process_handle_drag( & handle_corner_bl, { -1, -1 }, delta, {1, 1}, pos, size, alignment )
ui_box_compute_layout(parent)
return
}
#endregion("Resizable")

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -167,10 +167,10 @@ push-location $path_root
$build_args += $flag_output_path + $module_dll
$build_args += ($flag_collection + $pkg_collection_thirdparty)
# $build_args += $flag_micro_architecture_native
$build_args += $flag_use_separate_modules
$build_args += $flag_thread_count + $CoreCount_Physical
$build_args += $flag_optimize_none
# $build_args += $flag_optimize_minimal
# $build_args += $flag_use_separate_modules
# $build_args += $flag_thread_count + $CoreCount_Physical
# $build_args += $flag_optimize_none
$build_args += $flag_optimize_minimal
# $build_args += $flag_optimize_speed
# $build_args += $falg_optimize_aggressive
$build_args += $flag_debug
@ -249,8 +249,8 @@ push-location $path_root
$build_args += $flag_output_path + $executable
$build_args += ($flag_collection + $pkg_collection_thirdparty)
# $build_args += $flag_micro_architecture_native
$build_args += $flag_use_separate_modules
$build_args += $flag_thread_count + $CoreCount_Physical
# $build_args += $flag_use_separate_modules
# $build_args += $flag_thread_count + $CoreCount_Physical
$build_args += $flag_optimize_none
# $build_args += $flag_optimize_minimal
# $build_args += $flag_optimize_speed