Mostly reviewing progress so far
Prepping in the background for swapping raylib with sokol.
This commit is contained in:
		| @@ -59,3 +59,4 @@ They'll be elaborated in their own documentation | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -282,11 +282,6 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			// scope(theme_transparent) | ||||
| 			// spacer := ui_spacer("settings_menu.engine_refresh.end_spacer") | ||||
| 			// spacer.layout.flags      = {.Fixed_Height} | ||||
| 			// spacer.layout.size.min.y = 10 | ||||
|  | ||||
| 			Min_Zoom: | ||||
| 			{ | ||||
| 				scope( theme_table_row(is_even = true)) | ||||
|   | ||||
| @@ -142,7 +142,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem | ||||
|  | ||||
| 		rl.SetConfigFlags( { | ||||
| 			rl.ConfigFlag.WINDOW_RESIZABLE, | ||||
| 			// rl.ConfigFlag.WINDOW_TOPMOST, | ||||
| 			rl.ConfigFlag.WINDOW_TOPMOST, | ||||
| 		}) | ||||
|  | ||||
| 		window_width  : i32 = cast(i32) config.resolution_width | ||||
| @@ -329,7 +329,7 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32 | ||||
| 			verify( alloc_error == .None, "Failed to allocate frame slab" ) | ||||
| 		} | ||||
|  | ||||
| 		context.allocator      = frame_allocator() | ||||
| 		context.allocator      = frame_slab_allocator() | ||||
| 		context.temp_allocator = transient_allocator() | ||||
|  | ||||
| 		rl.PollInputEvents() | ||||
| @@ -338,9 +338,10 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32 | ||||
| 		debug.draw_UI_padding_bounds = false | ||||
| 		debug.draw_ui_content_bounds = false | ||||
|  | ||||
| 		config.color_theme = App_Thm_Light | ||||
| 		// config.color_theme = App_Thm_Light | ||||
| 		// config.color_theme = App_Thm_Dusk | ||||
| 		// config.color_theme = App_Thm_Dark | ||||
| 		config.color_theme = App_Thm_Dark | ||||
|  | ||||
| 		should_close = update( host_delta_time ) | ||||
| 		render() | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| The default arena allocator Odin provides does fragmented resizes even for the last most allocated block getting resized. | ||||
| This is an alternative to alleviates that. | ||||
|  | ||||
| TODO(Ed): Implement? | ||||
| TODO(Ed): Implement? Maybe we should trash this I' haven't seen a need to step away from using odin's | ||||
| */ | ||||
| package sectr | ||||
|  | ||||
| @@ -19,8 +19,6 @@ sub_arena_init :: proc( address : ^byte, size : int ) -> ( ^ Arena) { | ||||
| 	return sub_arena | ||||
| } | ||||
|  | ||||
| // TODO(Ed) : Once this is done (ArenaFixed), rename to just Arena as we're not going to use the core implementation | ||||
|  | ||||
| ArenaFixedHeader :: struct { | ||||
| 	data      : []byte, | ||||
| 	offset    : uint, | ||||
|   | ||||
| @@ -7,13 +7,6 @@ import "core:c/libc" | ||||
| import "core:mem" | ||||
| import "core:slice" | ||||
|  | ||||
| // Array :: struct ( $ Type : typeid ) { | ||||
| // 	bakcing : Allocator, | ||||
| // 	capacity  : u64, | ||||
| // 	num       : u64, | ||||
| // 	data      : [^]Type, | ||||
| // } | ||||
|  | ||||
| ArrayHeader :: struct ( $ Type : typeid ) { | ||||
| 	backing   : Allocator, | ||||
| 	dbg_name  : string, | ||||
| @@ -105,6 +98,7 @@ array_append_array :: proc( using self: ^Array( $ Type), other : Array(Type)) -> | ||||
| 	// libc.memcpy( ptr_offset(data, num), raw_data(items), len(items) * size_of(Type) ) | ||||
|  | ||||
| 	// TODO(Ed) : VERIFY VIA DEBUG THIS COPY IS FINE. | ||||
| 	ensure(false, "time to check....") | ||||
| 	target := ptr_offset( data, num ) | ||||
| 	copy( slice_ptr(target, int(capacity - num)), array_to_slice(other) ) | ||||
|  | ||||
| @@ -177,6 +171,7 @@ array_append_at_slice :: proc( using self : ^Array( $ Type ), items : []Type, id | ||||
| 	// libc.memcpy ( src, raw_data(items), len(items) * size_of(Type) ) | ||||
|  | ||||
| 	// TODO(Ed) : VERIFY VIA DEBUG THIS COPY IS FINE | ||||
| 	ensure(false, "time to check....") | ||||
| 	target := & data[id + len(items)] | ||||
| 	dst    := slice_ptr( target, num - id - len(items) ) | ||||
| 	src    := slice_ptr( & data[id], num - id ) | ||||
| @@ -189,15 +184,15 @@ array_append_at_slice :: proc( using self : ^Array( $ Type ), items : []Type, id | ||||
|  | ||||
| // array_back :: proc( ) | ||||
|  | ||||
| array_push_back :: proc( using self : Array( $ Type)) -> b32 { | ||||
| 	if num == capacity { | ||||
| 		return false | ||||
| 	} | ||||
| // array_push_back :: proc( using self : Array( $ Type)) -> b32 { | ||||
| // 	if num == capacity { | ||||
| // 		return false | ||||
| // 	} | ||||
|  | ||||
| 	data[ num ] = value | ||||
| 	num        += 1 | ||||
| 	return true | ||||
| } | ||||
| // 	data[ num ] = value | ||||
| // 	num        += 1 | ||||
| // 	return true | ||||
| // } | ||||
|  | ||||
| array_clear :: proc "contextless" ( using self : Array( $ Type ), zero_data : b32 = false ) { | ||||
| 	if zero_data { | ||||
|   | ||||
| @@ -1,12 +1,11 @@ | ||||
| // TODO(Ed) : Move this to a grime package | ||||
| package sectr | ||||
|  | ||||
| // TODO(Ed): Review these when os2 is done. | ||||
|  | ||||
| import "core:fmt" | ||||
| import "core:os" | ||||
| import "base:runtime" | ||||
|  | ||||
| // Test | ||||
|  | ||||
| file_copy_sync :: proc( path_src, path_dst: string, allocator := context.temp_allocator ) -> b32 | ||||
| { | ||||
|   file_size : i64 | ||||
|   | ||||
| @@ -2,6 +2,11 @@ | ||||
| This is an alternative to Odin's default map type. | ||||
| The only reason I may need this is due to issues with allocator callbacks or something else going on | ||||
| with hot-reloads... | ||||
| --------------------------------------------------------------------------------------------------------- | ||||
| 5-21-2024 Update: Still haven't taken the time to see why but just to add the original case for the above | ||||
| was I believe exclusively when I didn't set the base addresss of vmem | ||||
| OR when I was attempting to use Casey's brute force replay feature with memory. | ||||
| --------------------------------------------------------------------------------------------------------- | ||||
|  | ||||
| This implementation uses two ZPL-Based Arrays to hold entires and the actual hash table. | ||||
| Instead of using separate chains, it maintains linked entries within the array. | ||||
|   | ||||
| @@ -8,7 +8,7 @@ import str "core:strings" | ||||
| import "core:time" | ||||
| import core_log "core:log" | ||||
| 
 | ||||
| Max_Logger_Message_Width :: 300 | ||||
| Max_Logger_Message_Width :: 180 | ||||
| 
 | ||||
| LogLevel :: core_log.Level | ||||
| 
 | ||||
| @@ -127,5 +127,5 @@ log :: proc( msg : string, level := LogLevel.Info, loc := #caller_location ) { | ||||
| 
 | ||||
| logf :: proc( fmt : string, args : ..any,  level := LogLevel.Info, loc := #caller_location  ) { | ||||
| 	// context.allocator = transient_allocator() | ||||
| 	core_log.logf( level, fmt, args, location = loc ) | ||||
| 	core_log.logf( level, fmt, ..args, location = loc ) | ||||
| } | ||||
| @@ -39,8 +39,8 @@ str_cache_init :: proc( /*allocator : Allocator*/ ) -> ( cache : StringCache ) { | ||||
|  | ||||
| 	policy     : SlabPolicy | ||||
| 	policy_ptr := & policy | ||||
| 	// push( policy_ptr, SlabSizeClass {  64 * Kilobyte,              8, alignment }) | ||||
| 	// push( policy_ptr, SlabSizeClass {  64 * Kilobyte,             16, alignment }) | ||||
| 	push( policy_ptr, SlabSizeClass {  64 * Kilobyte,              8, alignment }) | ||||
| 	push( policy_ptr, SlabSizeClass {  64 * Kilobyte,             16, alignment }) | ||||
| 	push( policy_ptr, SlabSizeClass { 128 * Kilobyte,             32, alignment }) | ||||
| 	push( policy_ptr, SlabSizeClass { 128 * Kilobyte,             64, alignment }) | ||||
| 	push( policy_ptr, SlabSizeClass {  64 * Kilobyte,            128, alignment }) | ||||
|   | ||||
| @@ -77,10 +77,10 @@ vec3i_to_vec3 :: #force_inline proc "contextless" (v : Vec3i) -> Vec3 {return tr | ||||
|  | ||||
| Range2 :: struct #raw_union { | ||||
| 	using min_max : struct { | ||||
| 		min, max : Vec2 | ||||
| 		min, max : Vec2, | ||||
| 	}, | ||||
| 	using pts : struct { | ||||
| 		p0, p1 : Vec2 | ||||
| 		p0, p1 : Vec2, | ||||
| 	}, | ||||
| 	using xy : struct { | ||||
| 		x0, y0 : f32, | ||||
|   | ||||
| @@ -106,8 +106,8 @@ CameraZoomMode :: enum u32 { | ||||
|  | ||||
| // TODO(Ed) : I'm not sure making the size and extent types distinct has made things easier or more difficult in Odin.. | ||||
| // The lack of operator overloads is going to make any sort of nice typesystem | ||||
| // for doing lots of math or phyiscs more error prone or filled with proc wrappers | ||||
| AreaSize :: distinct Vec2 | ||||
| // for doing lots of math or phyiscs more error prone or filled with proc overload mapppings | ||||
| AreaSize :: Vec2 | ||||
|  | ||||
| Bounds2 :: struct { | ||||
| 	top_left, bottom_right: Vec2, | ||||
|   | ||||
| @@ -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 | ||||
| { | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								docs/assets/Code_2024-05-21_23-15-16.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/assets/Code_2024-05-21_23-15-16.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 338 KiB | 
		Reference in New Issue
	
	Block a user