It works but there is a memory issue... (parsing in tick update)
This commit is contained in:
@ -75,7 +75,12 @@ startup :: proc( persistent_mem, frame_mem, transient_mem, files_buffer_mem : ^V
|
||||
|
||||
alloc_error : AllocatorError
|
||||
persistent_slab, alloc_error = slab_init( policy_ptr, allocator = persistent_allocator() )
|
||||
verify( alloc_error == .None, "Failed to allocate the general slab allocator" )
|
||||
verify( alloc_error == .None, "Failed to allocate the persistent slab" )
|
||||
|
||||
transient_slab, alloc_error = slab_init( & default_slab_policy, allocator = transient_allocator() )
|
||||
verify( alloc_error == .None, "Failed to allocate transient slab" )
|
||||
|
||||
transient_clear_time = 120 // Seconds, 2 Minutes
|
||||
}
|
||||
|
||||
string_cache = str_cache_init()
|
||||
@ -176,6 +181,13 @@ startup :: proc( persistent_mem, frame_mem, transient_mem, files_buffer_mem : ^V
|
||||
ui_startup( & workspace.ui, cache_allocator = persistent_slab_allocator() )
|
||||
}
|
||||
|
||||
debug.path_lorem = str_fmt_alloc("C:/projects/SectrPrototype/examples/Lorem Ipsum.txt", allocator = persistent_allocator())
|
||||
|
||||
alloc_error : AllocatorError; success : bool
|
||||
debug.lorem_content, success = os.read_entire_file( debug.path_lorem, persistent_slab_allocator() )
|
||||
|
||||
debug.lorem_parse, alloc_error = pws_parser_parse( transmute(string) debug.lorem_content, persistent_slab_allocator() )
|
||||
verify( alloc_error == .None, "Faield to parse due to allocation failure" )
|
||||
}
|
||||
|
||||
startup_ms := duration_ms( time.tick_lap_time( & startup_tick))
|
||||
@ -191,6 +203,8 @@ startup :: proc( persistent_mem, frame_mem, transient_mem, files_buffer_mem : ^V
|
||||
@export
|
||||
sectr_shutdown :: proc()
|
||||
{
|
||||
context.logger = to_odin_logger( & Memory_App.logger )
|
||||
|
||||
if Memory_App.persistent == nil {
|
||||
return
|
||||
}
|
||||
@ -209,6 +223,7 @@ sectr_shutdown :: proc()
|
||||
@export
|
||||
reload :: proc( persistent_mem, frame_mem, transient_mem, files_buffer_mem : ^VArena, host_logger : ^ Logger )
|
||||
{
|
||||
context.logger = to_odin_logger( & Memory_App.logger )
|
||||
using Memory_App;
|
||||
|
||||
persistent = persistent_mem
|
||||
@ -219,6 +234,7 @@ reload :: proc( persistent_mem, frame_mem, transient_mem, files_buffer_mem : ^VA
|
||||
context.allocator = persistent_allocator()
|
||||
context.temp_allocator = transient_allocator()
|
||||
|
||||
|
||||
// Procedure Addresses are not preserved on hot-reload. They must be restored for persistent data.
|
||||
// The only way to alleviate this is to either do custom handles to allocators
|
||||
// Or as done below, correct containers using allocators on reload.
|
||||
@ -241,14 +257,15 @@ swap :: proc( a, b : ^ $Type ) -> ( ^ Type, ^ Type ) {
|
||||
@export
|
||||
tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32
|
||||
{
|
||||
client_tick := time.tick_now()
|
||||
|
||||
context.logger = to_odin_logger( & Memory_App.logger )
|
||||
state := get_state(); using state
|
||||
|
||||
client_tick := time.tick_now()
|
||||
|
||||
// Setup Frame Slab
|
||||
{
|
||||
alloc_error : AllocatorError
|
||||
frame_slab, alloc_error = slab_init( & default_slab_policy, allocator = frame_allocator() )
|
||||
frame_slab, alloc_error = slab_init( & default_slab_policy, bucket_reserve_num = 0, allocator = frame_allocator() )
|
||||
verify( alloc_error == .None, "Failed to allocate frame slab" )
|
||||
}
|
||||
|
||||
@ -305,6 +322,21 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32
|
||||
}
|
||||
|
||||
@export
|
||||
clean_frame :: proc() {
|
||||
clean_frame :: proc()
|
||||
{
|
||||
state := get_state(); using state
|
||||
context.logger = to_odin_logger( & Memory_App.logger )
|
||||
|
||||
free_all( frame_allocator() )
|
||||
|
||||
transient_clear_elapsed += frametime_delta32()
|
||||
if transient_clear_elapsed >= transient_clear_time && ! transinet_clear_lock
|
||||
{
|
||||
transient_clear_elapsed = 0
|
||||
free_all( transient_allocator() )
|
||||
|
||||
alloc_error : AllocatorError
|
||||
transient_slab, alloc_error = slab_init( & default_slab_policy, allocator = transient_allocator() )
|
||||
verify( alloc_error == .None, "Failed to allocate transient slab" )
|
||||
}
|
||||
}
|
||||
|
@ -140,11 +140,14 @@ AppConfig :: struct {
|
||||
}
|
||||
|
||||
State :: struct {
|
||||
default_slab_policy : SlabPolicy,
|
||||
default_slab_policy : SlabPolicy,
|
||||
persistent_slab : Slab,
|
||||
frame_slab : Slab,
|
||||
transient_slab : Slab, // TODO(Ed): This needs to be recreated per transient wipe
|
||||
transinet_clear_lock : b32, // Pravents auto-free of transient at designated intervals
|
||||
transient_clear_time : f32, // Time in seconds for the usual period to clear transient
|
||||
transient_clear_elapsed : f32, // Time since last clear
|
||||
|
||||
persistent_slab : Slab,
|
||||
frame_slab : Slab,
|
||||
transient_slab : Slab, // TODO(Ed): This needs to be recreated per transient wipe
|
||||
string_cache : StringCache,
|
||||
|
||||
font_provider_data : FontProviderData,
|
||||
@ -180,7 +183,7 @@ State :: struct {
|
||||
// There are two potential UI contextes for this prototype so far,
|
||||
// the screen-space UI and the current workspace UI.
|
||||
// This is used so that the ui api doesn't need to have the user pass the context every single time.
|
||||
ui_context : ^ UI_State,
|
||||
ui_context : ^UI_State,
|
||||
}
|
||||
|
||||
get_state :: proc "contextless" () -> ^ State {
|
||||
@ -254,5 +257,8 @@ DebugData :: struct {
|
||||
draggable_box_size : Vec2,
|
||||
box_original_size : Vec2,
|
||||
|
||||
lorem_parse : PWS_ParseResult,
|
||||
// Test parsing
|
||||
path_lorem : string,
|
||||
lorem_content : []byte,
|
||||
lorem_parse : PWS_ParseResult,
|
||||
}
|
||||
|
@ -273,12 +273,9 @@ array_set_capacity :: proc( self : ^Array( $ Type ), new_capacity : u64 ) -> All
|
||||
return result_code
|
||||
}
|
||||
|
||||
using new_self : Array(Type)
|
||||
header = cast( ^ArrayHeader(Type)) new_mem;
|
||||
data = cast( [^]Type ) (cast( [^]ArrayHeader(Type)) header)[ 1:]
|
||||
capacity = new_capacity
|
||||
num = self.num
|
||||
|
||||
(self ^) = new_self
|
||||
self.header = cast( ^ArrayHeader(Type)) new_mem;
|
||||
self.data = cast( [^]Type ) (cast( [^]ArrayHeader(Type)) self.header)[ 1:]
|
||||
self.capacity = new_capacity
|
||||
self.num = self.num
|
||||
return result_code
|
||||
}
|
||||
|
@ -34,7 +34,8 @@ DLL_Node :: struct ( $ Type : typeid ) #raw_union {
|
||||
}
|
||||
|
||||
DLL_NodeFull :: struct ( $ Type : typeid ) {
|
||||
using _ : DLL_NodeFL(Type),
|
||||
// using _ : DLL_NodeFL(Type),
|
||||
first, last : ^Type,
|
||||
prev, next : ^Type,
|
||||
}
|
||||
|
||||
|
@ -187,22 +187,25 @@ pool_grab :: proc( using pool : Pool ) -> ( block : []byte, alloc_error : Alloca
|
||||
return
|
||||
}
|
||||
|
||||
pool_release :: proc( using self : Pool, block : []byte, loc := #caller_location )
|
||||
pool_release :: proc( self : Pool, block : []byte, loc := #caller_location )
|
||||
{
|
||||
when Pool_Check_Release_Object_Validity
|
||||
{
|
||||
if Pool_Check_Release_Object_Validity {
|
||||
within_bucket := pool_validate_ownership( self, block )
|
||||
verify( within_bucket, "Attempted to release data that is not within a bucket of this pool", location = loc )
|
||||
return
|
||||
}
|
||||
|
||||
// Compiler bug
|
||||
// ll_push( & self.free_list_head, cast(^Pool_FreeBlock) raw_data(block) )
|
||||
|
||||
pool_watch := self
|
||||
head_watch := & self.free_list_head
|
||||
|
||||
// ll_push:
|
||||
new_free_block := cast(^Pool_FreeBlock) raw_data(block)
|
||||
new_free_block.next = self.free_list_head
|
||||
self.free_list_head = new_free_block
|
||||
|
||||
new_free_block = new_free_block
|
||||
}
|
||||
|
||||
pool_reset :: proc( using pool : Pool )
|
||||
|
@ -69,7 +69,7 @@ slab_init :: proc( policy : ^SlabPolicy, bucket_reserve_num : uint = 0, allocato
|
||||
slab.header = cast( ^SlabHeader) raw_mem
|
||||
slab.backing = allocator
|
||||
slab.policy = (policy^)
|
||||
alloc_error = slab_init_pools( slab )
|
||||
alloc_error = slab_init_pools( slab, bucket_reserve_num )
|
||||
return
|
||||
}
|
||||
|
||||
@ -186,14 +186,16 @@ slab_resize :: proc( using self : Slab,
|
||||
new_block : []byte
|
||||
new_block, alloc_error = pool_grab( pool_resize )
|
||||
if alloc_error != .None do return
|
||||
if zero_memory {
|
||||
slice.zero( new_block )
|
||||
}
|
||||
|
||||
copy_non_overlapping( raw_data(new_block), raw_data(data), int(old_size) )
|
||||
pool_release( pool_old, data )
|
||||
if raw_data(data) != raw_data(new_block) {
|
||||
copy_non_overlapping( raw_data(new_block), raw_data(data), int(old_size) )
|
||||
pool_release( pool_old, data )
|
||||
}
|
||||
|
||||
new_data = byte_slice( raw_data(new_block), int(old_size) )
|
||||
if zero_memory {
|
||||
slice.zero( new_data )
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -71,15 +71,19 @@ str_intern :: proc(
|
||||
}
|
||||
|
||||
length := len(content)
|
||||
// str_mem, alloc_error := alloc( length, mem.DEFAULT_ALIGNMENT )
|
||||
str_mem, alloc_error := slab_alloc( cache.slab, uint(length), uint(mem.DEFAULT_ALIGNMENT) )
|
||||
verify( alloc_error == .None, "String cache had a backing allocator error" )
|
||||
|
||||
// copy_non_overlapping( str_mem, raw_data(content), length )
|
||||
copy_non_overlapping( raw_data(str_mem), raw_data(content), length )
|
||||
|
||||
runes : []rune
|
||||
// runes, alloc_error = to_runes( content, persistent_allocator() )
|
||||
runes, alloc_error = to_runes( content, slab_allocator(cache.slab) )
|
||||
verify( alloc_error == .None, "String cache had a backing allocator error" )
|
||||
|
||||
// result, alloc_error = zpl_hmap_set( & cache.table, key, StringCached { transmute(string) byte_slice(str_mem, length), runes } )
|
||||
result, alloc_error = zpl_hmap_set( & cache.table, key, StringCached { transmute(string) str_mem, runes } )
|
||||
verify( alloc_error == .None, "String cache had a backing allocator error" )
|
||||
|
||||
|
@ -210,7 +210,8 @@ varena_allocator_proc :: proc(
|
||||
|
||||
old_memory_offset := uintptr(old_memory) + uintptr(old_size)
|
||||
current_offset := uintptr(arena.reserve_start) + uintptr(arena.commit_used)
|
||||
verify( old_memory_offset == current_offset || arena.allow_any_reize, "Cannot resize existing allocation in vitual arena to a larger size unless it was the last allocated" )
|
||||
verify( old_memory_offset == current_offset || arena.allow_any_reize,
|
||||
"Cannot resize existing allocation in vitual arena to a larger size unless it was the last allocated" )
|
||||
|
||||
if old_memory_offset == current_offset && arena.allow_any_reize
|
||||
{
|
||||
|
@ -107,6 +107,7 @@ PWS_LexerData :: struct {
|
||||
|
||||
content : string,
|
||||
previous_rune : rune,
|
||||
current_rune : rune,
|
||||
previous : PWS_TokenType,
|
||||
line : u32,
|
||||
column : u32,
|
||||
@ -159,7 +160,7 @@ pws_parser_lex :: proc ( text : string, allocator : Allocator ) -> ( PWS_LexResu
|
||||
}
|
||||
|
||||
alloc_error : AllocatorError
|
||||
tokens, alloc_error = array_init_reserve( PWS_Token, allocator, u64( len(text)) )
|
||||
tokens, alloc_error = array_init_reserve( PWS_Token, allocator, 8 )
|
||||
if alloc_error != AllocatorError.None {
|
||||
ensure(false, "Failed to allocate token's array")
|
||||
return result, alloc_error
|
||||
@ -168,11 +169,11 @@ pws_parser_lex :: proc ( text : string, allocator : Allocator ) -> ( PWS_LexResu
|
||||
line = 0
|
||||
column = 0
|
||||
|
||||
make_token :: proc ( codepoint : rune, byte_offset : int ) -> AllocatorError
|
||||
make_token :: proc ( byte_offset : int ) -> AllocatorError
|
||||
{
|
||||
self := context_ext( PWS_LexerData); using self
|
||||
|
||||
if previous_rune == Rune_Carriage_Return && codepoint != Rune_Line_Feed {
|
||||
if previous_rune == Rune_Carriage_Return && current_rune != Rune_Line_Feed {
|
||||
ensure(false, "Rouge Carriage Return")
|
||||
}
|
||||
|
||||
@ -194,10 +195,12 @@ pws_parser_lex :: proc ( text : string, allocator : Allocator ) -> ( PWS_LexResu
|
||||
for codepoint, byte_offset in text
|
||||
{
|
||||
type := rune_type( codepoint )
|
||||
current_rune = codepoint
|
||||
|
||||
if (current.type != type && previous != .Invalid) || current.type == .New_Line
|
||||
if (current.type != type && previous != .Invalid) ||
|
||||
( previous_rune != Rune_Carriage_Return && current.type == .New_Line )
|
||||
{
|
||||
alloc_error = make_token( previous_rune, byte_offset )
|
||||
alloc_error = make_token( byte_offset )
|
||||
if alloc_error != AllocatorError.None {
|
||||
ensure(false, "Failed to append token to token array")
|
||||
return lexer, alloc_error
|
||||
@ -215,7 +218,7 @@ pws_parser_lex :: proc ( text : string, allocator : Allocator ) -> ( PWS_LexResu
|
||||
last_byte_offset = byte_offset
|
||||
}
|
||||
|
||||
make_token( previous_rune, last_byte_offset )
|
||||
make_token( last_byte_offset )
|
||||
|
||||
return result, alloc_error
|
||||
}
|
||||
@ -244,23 +247,22 @@ pws_parser_parse :: proc( text : string, allocator : Allocator ) -> ( PWS_ParseR
|
||||
|
||||
tokens = lex.tokens
|
||||
|
||||
nodes, alloc_error = array_init_reserve( PWS_AST, allocator, PWS_NodeArray_ReserveSize )
|
||||
nodes, alloc_error = array_init_reserve( PWS_AST, allocator, 8 )
|
||||
verify( alloc_error == nil, "Allocation failure creating nodes array")
|
||||
|
||||
lines, alloc_error = array_init_reserve( ^PWS_AST, allocator, PWS_LineArray_RserveSize )
|
||||
lines, alloc_error = array_init_reserve( ^PWS_AST, allocator, 8 )
|
||||
verify( alloc_error == nil, "Allocation failure creating line array")
|
||||
|
||||
//region Helper procs
|
||||
eat_line :: proc()
|
||||
eat_line :: #force_inline proc()
|
||||
{
|
||||
self := context_ext( PWS_ParseData); using self
|
||||
tok := cast( ^PWS_Token) head
|
||||
|
||||
ast : PWS_AST
|
||||
ast.type = .Line
|
||||
ast.line = tok.line
|
||||
ast.column = tok.column
|
||||
ast.content = tok.content
|
||||
line.type = .Line
|
||||
line.line = tok.line
|
||||
line.column = tok.column
|
||||
line.content = tok.content
|
||||
|
||||
alloc_error := array_append( & nodes, line )
|
||||
verify( alloc_error == nil, "Allocation failure appending node")
|
||||
|
@ -75,8 +75,10 @@ render :: proc()
|
||||
|
||||
ui := project.workspace.ui
|
||||
|
||||
hot_box := zpl_hmap_get( ui.curr_cache, u64(ui.hot) )
|
||||
active_box := zpl_hmap_get( ui.curr_cache, u64(ui.active) )
|
||||
debug_text("Box Count: %v", ui.built_box_count )
|
||||
|
||||
hot_box := ui_box_from_key( ui.curr_cache, ui.hot )
|
||||
active_box := ui_box_from_key( ui.curr_cache, ui.active )
|
||||
if hot_box != nil {
|
||||
debug_text("Hot Box: %v", hot_box.label.str )
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package sectr
|
||||
import "base:runtime"
|
||||
import "core:math"
|
||||
import "core:math/linalg"
|
||||
import "core:os"
|
||||
|
||||
import rl "vendor:raylib"
|
||||
|
||||
@ -158,15 +159,15 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
case .Smooth:
|
||||
zoom_delta := input.mouse.vertical_wheel * config.cam_zoom_sensitivity_smooth
|
||||
workspace.zoom_target *= 1 + zoom_delta * f32(delta_time)
|
||||
workspace.zoom_target = clamp(workspace.zoom_target, 0.25, 10.0)
|
||||
workspace.zoom_target = clamp(workspace.zoom_target, 0.05, 10.0)
|
||||
|
||||
// Linearly interpolate cam.zoom towards zoom_target
|
||||
lerp_factor := config.cam_zoom_smooth_snappiness // Adjust this value to control the interpolation speed
|
||||
cam.zoom += (workspace.zoom_target - cam.zoom) * lerp_factor * f32(delta_time)
|
||||
cam.zoom = clamp(cam.zoom, 0.25, 10.0) // Ensure cam.zoom stays within bounds
|
||||
cam.zoom = clamp(cam.zoom, 0.05, 10.0) // Ensure cam.zoom stays within bounds
|
||||
case .Digital:
|
||||
zoom_delta := input.mouse.vertical_wheel * config.cam_zoom_sensitivity_digital
|
||||
workspace.zoom_target = clamp(workspace.zoom_target + zoom_delta, 0.25, 10.0)
|
||||
workspace.zoom_target = clamp(workspace.zoom_target + zoom_delta, 0.05, 10.0)
|
||||
cam.zoom = workspace.zoom_target
|
||||
}
|
||||
|
||||
@ -235,20 +236,32 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
// Whitespace AST test
|
||||
when true
|
||||
{
|
||||
alloc_error : AllocatorError
|
||||
text := str_intern( "Lorem ipsum dolor sit amet")
|
||||
debug.lorem_parse, alloc_error = pws_parser_parse( text.str, frame_allocator() )
|
||||
verify( alloc_error == .None, "Faield to parse due to allocation failure" )
|
||||
text_theme := UI_StyleTheme { styles = {
|
||||
frame_style_default,
|
||||
frame_style_default,
|
||||
frame_style_default,
|
||||
frame_style_default,
|
||||
}}
|
||||
text_theme.default.bg_color = Color_Transparent
|
||||
text_theme.disabled.bg_color = Color_Frame_Disabled
|
||||
text_theme.hovered.bg_color = Color_Frame_Hover
|
||||
text_theme.focused.bg_color = Color_Frame_Select
|
||||
layout_text := default_layout
|
||||
ui_style_theme( text_theme )
|
||||
|
||||
alloc_error : AllocatorError; success : bool
|
||||
// debug.lorem_content, success = os.read_entire_file( debug.path_lorem, frame_allocator() )
|
||||
|
||||
// debug.lorem_parse, alloc_error = pws_parser_parse( transmute(string) debug.lorem_content, frame_allocator() )
|
||||
// verify( alloc_error == .None, "Faield to parse due to allocation failure" )
|
||||
|
||||
text_space := str_intern( " " )
|
||||
text_tab := str_intern( "\t")
|
||||
|
||||
layout_text := default_layout
|
||||
|
||||
// index := 0
|
||||
widgets : Array(UI_Widget)
|
||||
widgets, alloc_error = array_init( UI_Widget, frame_allocator() )
|
||||
widget_ptr := & widgets
|
||||
widgets_ptr := & widgets
|
||||
|
||||
label_id := 0
|
||||
|
||||
@ -265,42 +278,47 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
#partial switch head.type
|
||||
{
|
||||
case .Visible:
|
||||
label := str_intern( str_fmt_alloc( "%v %v", head.content.str, label_id, label_id ))
|
||||
widget = ui_text( head.content.str, head.content )
|
||||
label := str_intern( str_fmt_alloc( "%v %v", head.content.str, label_id ))
|
||||
widget = ui_text( label.str, head.content )
|
||||
label_id += 1
|
||||
|
||||
layout_text.pos.x += widget.style.layout.size.x
|
||||
|
||||
case .Spaces:
|
||||
label := str_intern( str_fmt_alloc( "%v %v%v", "space", label_id, label_id ))
|
||||
widget := ui_text( label.str, text_space, {} )
|
||||
widget.style.layout.size = Vec2 { 20, 30 }
|
||||
label := str_intern( str_fmt_alloc( "%v %v", "space", label_id ))
|
||||
// widget = ui_text( label.str, text_space, {} )
|
||||
// widget.style.layout.size = Vec2 { 1, 16 }
|
||||
widget = ui_space( label.str )
|
||||
label_id += 1
|
||||
|
||||
for idx in 0 ..< len( head.content.runes )
|
||||
for idx in 1 ..< len( head.content.runes )
|
||||
{
|
||||
widget.style.layout.size.x += widget.style.layout.size.x
|
||||
}
|
||||
layout_text.pos.x += widget.style.layout.size.x
|
||||
|
||||
case .Tabs:
|
||||
label := str_intern( str_fmt_alloc( "%v %v%v", "tab", label_id, label_id ))
|
||||
widget := ui_text( label.str, text_tab, {} )
|
||||
label := str_intern( str_fmt_alloc( "%v %v", "tab", label_id ))
|
||||
// widget = ui_text( label.str, text_tab, {} )
|
||||
widget = ui_tab( label.str )
|
||||
label_id += 1
|
||||
|
||||
for idx in 0 ..< len( head.content.runes )
|
||||
for idx in 1 ..< len( head.content.runes )
|
||||
{
|
||||
widget.style.layout.size.x += widget.style.layout.size.x
|
||||
}
|
||||
layout_text.pos.x += widget.style.layout.size.x
|
||||
}
|
||||
|
||||
array_append( widget_ptr, widget )
|
||||
array_append( widgets_ptr, widget )
|
||||
head = head.next
|
||||
}
|
||||
|
||||
layout_text.pos.x = default_layout.pos.x
|
||||
layout_text.pos.y -= 30
|
||||
}
|
||||
|
||||
// runtime.trap()
|
||||
label_id += 1
|
||||
}
|
||||
}
|
||||
//endregion Imgui Tick
|
||||
|
10
code/ui.odin
10
code/ui.odin
@ -256,8 +256,8 @@ UI_Box :: struct {
|
||||
// UI_BoxFlags_Stack_Size :: 512
|
||||
UI_Layout_Stack_Size :: 512
|
||||
UI_Style_Stack_Size :: 512
|
||||
UI_Parent_Stack_Size :: 1024
|
||||
UI_Built_Boxes_Array_Size :: 1024
|
||||
UI_Parent_Stack_Size :: 1024 * 10
|
||||
UI_Built_Boxes_Array_Size :: 1024 * 10
|
||||
|
||||
UI_State :: struct {
|
||||
// TODO(Ed) : Use these
|
||||
@ -335,6 +335,10 @@ ui_box_equal :: proc( a, b : ^ UI_Box ) -> b32 {
|
||||
return result
|
||||
}
|
||||
|
||||
ui_box_from_key :: proc( cache : ^HMapZPL(UI_Box), key : UI_Key ) -> (^UI_Box) {
|
||||
return zpl_hmap_get( cache, cast(u64) key )
|
||||
}
|
||||
|
||||
ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
|
||||
{
|
||||
using ui := get_state().ui_context
|
||||
@ -380,6 +384,7 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
|
||||
curr_box.parent = parent
|
||||
}
|
||||
|
||||
ui.built_box_count += 1
|
||||
return curr_box
|
||||
}
|
||||
|
||||
@ -431,6 +436,7 @@ ui_graph_build_begin :: proc( ui : ^ UI_State, bounds : Vec2 = {} )
|
||||
ui.hot_resizable = false
|
||||
}
|
||||
|
||||
ui.built_box_count = 0
|
||||
root = ui_box_make( {}, "root#001" )
|
||||
ui_parent_push(root)
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ test_text_box :: proc()
|
||||
text := str_intern( "Lorem ipsum dolor sit amet")
|
||||
font_size := 30
|
||||
|
||||
text_box := ui_text("TEXT BOX!", text, 30, flags = { .Mouse_Clickable })
|
||||
text_box := ui_text("TEXT BOX!", text, flags = { .Mouse_Clickable })
|
||||
if text_box.first_frame {
|
||||
pos = text_box.style.layout.pos
|
||||
}
|
||||
|
@ -20,20 +20,46 @@ ui_button :: proc( label : string, flags : UI_BoxFlags = {} ) -> (btn : UI_Widge
|
||||
return
|
||||
}
|
||||
|
||||
ui_text :: proc( label : string, content : StringCached, font_size : f32 = 30, font := Font_Default, flags : UI_BoxFlags = {} ) -> UI_Widget
|
||||
ui_text :: proc( label : string, content : StringCached, flags : UI_BoxFlags = {} ) -> UI_Widget
|
||||
{
|
||||
state := get_state(); using state
|
||||
|
||||
font := font
|
||||
if font == Font_Default {
|
||||
font = default_font
|
||||
}
|
||||
text_size := measure_text_size( content.str, font, font_size, 0 )
|
||||
|
||||
box := ui_box_make( flags, label )
|
||||
signal := ui_signal_from_box( box )
|
||||
|
||||
text_size := measure_text_size( content.str, box.style.font, box.style.font_size, 0 )
|
||||
|
||||
box.text = content
|
||||
box.style.layout.size = text_size
|
||||
return { box, signal }
|
||||
}
|
||||
|
||||
ui_space :: proc( label : string, flags : UI_BoxFlags = {} ) -> UI_Widget
|
||||
{
|
||||
space_str := str_intern( " " )
|
||||
|
||||
state := get_state(); using state
|
||||
|
||||
box := ui_box_make( flags, label )
|
||||
signal := ui_signal_from_box( box )
|
||||
|
||||
text_size := measure_text_size( space_str.str, box.style.font, box.style.font_size, 0 )
|
||||
box.text = space_str
|
||||
box.style.layout.size = text_size
|
||||
return { box, signal }
|
||||
}
|
||||
|
||||
ui_tab :: proc( label : string, flags : UI_BoxFlags = {} ) -> UI_Widget
|
||||
{
|
||||
tab_str := str_intern( "\t" )
|
||||
|
||||
state := get_state(); using state
|
||||
|
||||
box := ui_box_make( flags, label )
|
||||
signal := ui_signal_from_box( box )
|
||||
|
||||
text_size := measure_text_size( tab_str.str, box.style.font, box.style.font_size, 0 )
|
||||
box.text = tab_str
|
||||
box.style.layout.size = text_size
|
||||
return { box, signal }
|
||||
}
|
||||
|
Reference in New Issue
Block a user