Restructured the codebase yet again but this time with compiler support for monlithic packages
So no need to stage generate symbolic links in a flat directory for the compiler
This commit is contained in:
		
							
								
								
									
										41
									
								
								code/sectr/app/scratch.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								code/sectr/app/scratch.odin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| package sectr | ||||
|  | ||||
| // Scratch space | ||||
|  | ||||
| import rl "vendor:raylib" | ||||
|  | ||||
| DebugData :: struct { | ||||
| 	square_size : i32, | ||||
| 	square_pos  : rl.Vector2, | ||||
|  | ||||
| 	draw_debug_text_y : f32, | ||||
|  | ||||
| 	cursor_locked     : b32, | ||||
| 	cursor_unlock_pos : Vec2, // Raylib changes the mose position on lock, we want restore the position the user would be in on screen | ||||
| 	mouse_vis         : b32, | ||||
| 	last_mouse_pos    : Vec2, | ||||
|  | ||||
| 	// UI Vis | ||||
| 	draw_ui_box_bounds_points : bool, | ||||
| 	draw_UI_padding_bounds    : bool, | ||||
| 	draw_ui_content_bounds    : bool, | ||||
|  | ||||
| 	// Test First | ||||
| 	frame_2_created : b32, | ||||
|  | ||||
| 	// Test Draggable | ||||
| 	draggable_box_pos  : Vec2, | ||||
| 	draggable_box_size : Vec2, | ||||
| 	box_original_size  : Vec2, | ||||
|  | ||||
| 	// Test parsing | ||||
| 	path_lorem    : string, | ||||
| 	lorem_content : []byte, | ||||
| 	lorem_parse   : PWS_ParseResult, | ||||
|  | ||||
| 	// Test 3d Viewport | ||||
| 	cam_vp      : rl.Camera3D, | ||||
| 	viewport_rt : rl.RenderTexture, | ||||
|  | ||||
| 	proto_text_shader : rl.Shader | ||||
| } | ||||
							
								
								
									
										320
									
								
								code/sectr/app/screen.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										320
									
								
								code/sectr/app/screen.odin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,320 @@ | ||||
| package sectr | ||||
|  | ||||
| UI_ScreenState :: struct | ||||
| { | ||||
| 	using base : UI_State, | ||||
|  | ||||
| 	floating : UI_FloatingManager, | ||||
|  | ||||
| 	// TODO(Ed): The docked should be the base, floating is should be nested within as a 'veiwport' to a 'desktop' or 'canvas' | ||||
| 	// docked : UI_Docking, | ||||
|  | ||||
| 	menu_bar : struct | ||||
| 	{ | ||||
| 		pos, size    : Vec2, | ||||
| 		container    : UI_HBox, | ||||
| 		settings_btn : struct | ||||
| 		{ | ||||
| 			using widget : UI_Widget, | ||||
| 		} | ||||
| 	}, | ||||
| 	settings_menu : struct | ||||
| 	{ | ||||
| 		pos, size, min_size : Vec2, | ||||
| 		container           : UI_Widget, | ||||
| 		is_open             : b32, | ||||
| 		is_maximized        : b32, | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| ui_screen_tick :: proc() { | ||||
| 	profile("Screenspace Imgui") | ||||
|  | ||||
| 	using state := get_state() | ||||
| 	ui_graph_build( & screen_ui ) | ||||
| 	ui := ui_context | ||||
|  | ||||
| 	ui_floating_manager_begin( & screen_ui.floating ) | ||||
| 	{ | ||||
| 		ui_floating("Menu Bar",      ui_screen_menu_bar) | ||||
| 		ui_floating("Settings Menu", ui_screen_settings_menu) | ||||
| 	} | ||||
| 	ui_floating_manager_end() | ||||
| } | ||||
|  | ||||
| ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 = false ) | ||||
| { | ||||
| 	profile("App Menu Bar") | ||||
| 	fmt :: str_fmt_alloc | ||||
|  | ||||
| 	@(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) | ||||
| 	} | ||||
|  | ||||
| 	using state := get_state() | ||||
| 	using screen_ui | ||||
| 	{ | ||||
| 		using screen_ui.menu_bar | ||||
| 		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_theme_btn_default() | ||||
| 		move_box := ui_button("Move Box"); | ||||
| 		{ | ||||
| 			using move_box | ||||
| 			if active { | ||||
| 				pos += input.mouse.delta | ||||
| 				should_raise = true | ||||
| 			} | ||||
| 			layout.anchor.ratio.x = 0.4 | ||||
| 		} | ||||
|  | ||||
| 		spacer := ui_spacer("Menu Bar: Move Spacer") | ||||
| 		spacer.layout.flags |= {.Fixed_Width} | ||||
| 		spacer.layout.size.min.x = 30 | ||||
|  | ||||
| 		// TODO(Ed): Implement an external composition for theme interpolation using the settings btn | ||||
| 		settings_btn.widget = ui_button("Menu Bar: Settings Btn") | ||||
| 		{ | ||||
| 			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") | ||||
| 		spacer.layout.anchor.ratio.x = 1.0 | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| 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 | ||||
|  | ||||
| 	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 | ||||
|  | ||||
| 	ui_theme_transparent() | ||||
| 	container = ui_widget("Settings Menu", {}) | ||||
| 	{ | ||||
| 		using container | ||||
| 		layout.flags        = { .Fixed_Width, .Fixed_Height, .Fixed_Position_X, .Fixed_Position_Y, .Origin_At_Anchor_Center } | ||||
| 		style.bg_color      = Color_ThmDark_Translucent_Panel | ||||
| 		style.border_color  = { 0, 0, 0, 200 } | ||||
| 		layout.alignment    = {0.0, 0.0} | ||||
| 		layout.border_width = 1.0 | ||||
| 		layout.pos          = pos | ||||
| 		layout.size         = range2( size, {}) | ||||
| 	} | ||||
| 	ui_parent(container) | ||||
| 	if settings_menu.is_maximized { | ||||
| 		using container | ||||
| 		layout.flags = {.Origin_At_Anchor_Center } | ||||
| 		layout.pos   = {} | ||||
| 	} | ||||
| 	should_raise |= ui_resizable_handles( & container, & pos, & size/*, compute_layout = true*/) | ||||
| 	// ui_box_compute_layout(container) | ||||
|  | ||||
| 	vbox := ui_vbox_begin( .Top_To_Bottom, "Settings Menu: VBox", {.Mouse_Clickable}, compute_layout = true) | ||||
| 	{ | ||||
| 		should_raise |= b32(vbox.active) | ||||
| 		ui_parent(vbox) | ||||
|  | ||||
| 		ui_layout( UI_Layout { | ||||
| 		// 	font_size = 16, | ||||
| 			// alignment = {0, 1}, | ||||
| 		}) | ||||
| 		ui_style( UI_Style { | ||||
| 			// bg_color   = Color_Transparent, | ||||
| 			font       = default_font, | ||||
| 			text_color = Color_White, | ||||
| 		}) | ||||
| 		ui_style_ref().hot.bg_color = Color_Blue | ||||
| 		frame_bar := ui_hbox_begin(.Left_To_Right, "Settings Menu: Frame Bar", { .Mouse_Clickable, .Focusable, .Click_To_Focus }) | ||||
| 		{ | ||||
| 			frame_bar.layout.flags      = {.Fixed_Height} | ||||
| 			frame_bar.layout.size.min.y = 50 | ||||
| 			ui_parent(frame_bar) | ||||
|  | ||||
| 			ui_layout( UI_Layout { | ||||
| 				font_size = 18, | ||||
| 			}) | ||||
| 			title := ui_text("Settings Menu: Title", str_intern("Settings Menu"), {.Disabled}) | ||||
| 			{ | ||||
| 				using title | ||||
| 				layout.margins        = { 0, 0, 15, 0} | ||||
| 				layout.text_alignment = {0 , 0.5} | ||||
| 				layout.anchor.ratio.x = 1.0 | ||||
| 			} | ||||
|  | ||||
| 			ui_layout( UI_Layout { | ||||
| 				font_size = 16, | ||||
| 			}) | ||||
|  | ||||
| 			ui_style(ui_style_peek()) | ||||
| 			style := ui_style_ref() | ||||
| 			maximize_btn := ui_button("Settings Menu: Maximize Btn") | ||||
| 			{ | ||||
| 				using maximize_btn | ||||
| 				layout.flags          = {.Fixed_Width} | ||||
| 				layout.size.min       = {50, 50} | ||||
| 				layout.text_alignment = {0.5, 0.5} | ||||
| 				layout.anchor.ratio.x = 1.0 | ||||
| 				if maximize_btn.pressed { | ||||
| 					settings_menu.is_maximized = ~settings_menu.is_maximized | ||||
| 					should_raise = true | ||||
| 				} | ||||
| 				if settings_menu.is_maximized do text = str_intern("min") | ||||
| 				else do text = str_intern("max") | ||||
| 			} | ||||
| 			close_btn := ui_button("Settings Menu: Close Btn") | ||||
| 			{ | ||||
| 				using close_btn | ||||
| 				text = str_intern("close") | ||||
| 				layout.flags          = {.Fixed_Width} | ||||
| 				layout.size.min       = {50, 0} | ||||
| 				layout.text_alignment = {0.5, 0.5} | ||||
| 				layout.anchor.ratio.x = 1.0 | ||||
| 				if close_btn.pressed { | ||||
| 					settings_menu.is_open = false | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			ui_hbox_end(frame_bar, compute_layout = true) | ||||
| 		} | ||||
| 		if frame_bar.active { | ||||
| 			pos += input.mouse.delta | ||||
| 			should_raise = true | ||||
| 		} | ||||
|  | ||||
| 		// 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}) | ||||
| 		btn : UI_Widget | ||||
| 		{ | ||||
| 			drop_down_bar.layout.anchor.ratio.y = 0.1 | ||||
| 			{ | ||||
| 				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) | ||||
|  | ||||
| 			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.0, 0.0} | ||||
| 				layout.anchor.ratio.x = 1.0 | ||||
| 				layout.font_size      = 12 | ||||
| 				layout.margins        = {0,0, 15, 0} | ||||
| 				layout.size.min.y     = 35 | ||||
| 			} | ||||
| 			um := ui_spacer("um...") | ||||
| 			um.layout.anchor.ratio.x = 1.0 | ||||
| 			ui_hbox_end(drop_down_bar, compute_layout = true) | ||||
| 		} | ||||
|  | ||||
| 		// 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) | ||||
|  | ||||
| 		spacer := ui_spacer("Settings Menu: Spacer") | ||||
| 		spacer.layout.anchor.ratio.y = 1.0 | ||||
|  | ||||
| 		ui_vbox_end(vbox, compute_layout = false ) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										2
									
								
								code/sectr/app/serialize.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								code/sectr/app/serialize.odin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| package sectr | ||||
|  | ||||
							
								
								
									
										260
									
								
								code/sectr/app/state.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								code/sectr/app/state.odin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,260 @@ | ||||
| package sectr | ||||
|  | ||||
| import "base:runtime" | ||||
| import "core:fmt" | ||||
| import "core:mem" | ||||
| import "core:mem/virtual" | ||||
| import "core:os" | ||||
|  | ||||
| import rl "vendor:raylib" | ||||
|  | ||||
| Str_App_State := "App State" | ||||
|  | ||||
| #region("Memory") | ||||
|  | ||||
| Memory_App : Memory | ||||
|  | ||||
| Memory_Base_Address_Persistent   :: Terabyte * 1 | ||||
| Memory_Base_Address_Frame        :: Memory_Base_Address_Persistent + Memory_Reserve_Persistent * 2 | ||||
| Memory_Base_Address_Transient    :: Memory_Base_Address_Frame      + Memory_Reserve_Frame * 2 | ||||
| Memory_Base_Address_Files_Buffer :: Memory_Base_Address_Transient  + Memory_Reserve_Transient * 2 | ||||
|  | ||||
| // This reserve goes beyond the typical amount of ram the user has, | ||||
| // TODO(Ed): Setup warnings when the amount is heading toward half the ram size | ||||
| Memory_Reserve_Persistent  :: 32 * Gigabyte | ||||
| Memory_Reserve_Frame       :: 16 * Gigabyte | ||||
| Memory_Reserve_Transient   :: 16 * Gigabyte | ||||
| Memory_Reserve_FilesBuffer :: 64 * Gigabyte | ||||
|  | ||||
| Memory_Commit_Initial_Persistent :: 4 * Kilobyte | ||||
| Memory_Commit_Initial_Frame      :: 4 * Kilobyte | ||||
| Memory_Commit_Initial_Transient  :: 4 * Kilobyte | ||||
| Memory_Commit_Initial_Filebuffer :: 4 * Kilobyte | ||||
|  | ||||
| MemorySnapshot :: struct { | ||||
| 	persistent   : []u8, | ||||
| 	frame        : []u8, | ||||
| 	transient    : []u8, | ||||
| 	// files_buffer cannot be restored from snapshot | ||||
| } | ||||
|  | ||||
| Memory :: struct { | ||||
| 	persistent   : ^VArena, | ||||
| 	frame        : ^VArena, | ||||
| 	transient    : ^VArena, | ||||
| 	files_buffer : ^VArena, | ||||
|  | ||||
| 	state   : ^State, | ||||
|  | ||||
| 	// Should only be used for small memory allocation iterations | ||||
| 	// Not for large memory env states | ||||
| 	snapshot : MemorySnapshot, | ||||
|  | ||||
| 	replay   : ReplayState, | ||||
| 	logger   : Logger, | ||||
| 	profiler : ^SpallProfiler | ||||
| } | ||||
|  | ||||
| persistent_allocator :: proc() -> Allocator { | ||||
| 	result := varena_allocator( Memory_App.persistent ) | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| frame_allocator :: proc() -> Allocator { | ||||
| 	result := varena_allocator( Memory_App.frame ) | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| transient_allocator :: proc() -> Allocator { | ||||
| 	result := varena_allocator( Memory_App.transient ) | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| files_buffer_allocator :: proc() -> Allocator { | ||||
| 	result := varena_allocator( Memory_App.files_buffer ) | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| persistent_slab_allocator :: proc() -> Allocator { | ||||
| 	state := get_state() | ||||
| 	result := slab_allocator( state.persistent_slab ) | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| frame_slab_allocator :: proc() -> Allocator { | ||||
| 	result := slab_allocator( get_state().frame_slab ) | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| transient_slab_allocator :: proc() -> Allocator { | ||||
| 	result := slab_allocator( get_state().transient_slab ) | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| // TODO(Ed) : Implment host memory mapping api | ||||
| save_snapshot :: proc( snapshot : ^MemorySnapshot ) | ||||
| { | ||||
| 	// Make sure the snapshot size is able to hold the current size of the arenas | ||||
| 	// Grow the files & mapping otherwise | ||||
| 	{ | ||||
| 		// TODO(Ed) : Implement eventually | ||||
| 	} | ||||
|  | ||||
| 	persistent := Memory_App.persistent | ||||
| 	mem.copy_non_overlapping( & snapshot.persistent[0], persistent.reserve_start, int(persistent.commit_used) ) | ||||
|  | ||||
| 	frame := Memory_App.frame | ||||
| 	mem.copy_non_overlapping( & snapshot.frame[0], frame.reserve_start, int(frame.commit_used) ) | ||||
|  | ||||
| 	transient := Memory_App.transient | ||||
| 	mem.copy_non_overlapping( & snapshot.transient[0], transient.reserve_start, int(transient.commit_used) ) | ||||
| } | ||||
|  | ||||
| // TODO(Ed) : Implment host memory mapping api | ||||
| load_snapshot :: proc( snapshot : ^MemorySnapshot ) { | ||||
| 	persistent := Memory_App.persistent | ||||
| 	mem.copy_non_overlapping( persistent.reserve_start, & snapshot.persistent[0], int(persistent.commit_used) ) | ||||
|  | ||||
| 	frame := Memory_App.frame | ||||
| 	mem.copy_non_overlapping( frame.reserve_start, & snapshot.frame[0], int(frame.commit_used) ) | ||||
|  | ||||
| 	transient := Memory_App.transient | ||||
| 	mem.copy_non_overlapping( transient.reserve_start, & snapshot.transient[0], int(transient.commit_used) ) | ||||
| } | ||||
|  | ||||
| // TODO(Ed) : Implement usage of this | ||||
| MemoryConfig :: struct { | ||||
| 	reserve_persistent : uint, | ||||
| 	reserve_frame      : uint, | ||||
| 	reserve_transient  : uint, | ||||
| 	reserve_filebuffer : uint, | ||||
|  | ||||
| 	commit_initial_persistent : uint, | ||||
| 	commit_initial_frame      : uint, | ||||
| 	commit_initial_transient  : uint, | ||||
| 	commit_initial_filebuffer : uint, | ||||
| } | ||||
|  | ||||
| #endregion("Memory") | ||||
|  | ||||
| #region("State") | ||||
|  | ||||
| // ALl nobs available for this application | ||||
| AppConfig :: struct { | ||||
| 	using memory : MemoryConfig, | ||||
|  | ||||
| 	resolution_width  : uint, | ||||
| 	resolution_height : uint, | ||||
| 	refresh_rate      : uint, | ||||
|  | ||||
| 	cam_min_zoom                 : f32, | ||||
| 	cam_max_zoom                 : f32, | ||||
| 	cam_zoom_mode                : CameraZoomMode, | ||||
| 	cam_zoom_smooth_snappiness   : f32, | ||||
| 	cam_zoom_sensitivity_smooth  : f32, | ||||
| 	cam_zoom_sensitivity_digital : f32, | ||||
|  | ||||
| 	engine_refresh_hz : uint, | ||||
|  | ||||
| 	timing_fps_moving_avg_alpha : f32, | ||||
|  | ||||
| 	ui_resize_border_width : f32, | ||||
| } | ||||
|  | ||||
| AppWindow :: struct { | ||||
| 	extent    : Extents2, // Window half-size | ||||
| 	dpi_scale : f32,      // Dots per inch scale (provided by raylib via glfw) | ||||
| 	ppcm      : f32,      // Dots per centimetre | ||||
| } | ||||
|  | ||||
| FontData :: struct { | ||||
| 	provider : FontProviderData, | ||||
|  | ||||
| 	// TODO(Ed): We can have font constants here I guess but eventually | ||||
| 	// I rather have fonts configurable for a 'theme' combo | ||||
| 	// So that way which IDs are picked depends on runtime | ||||
| 	firacode                : FontID, | ||||
| 	squidgy_slimes          : FontID, | ||||
| 	rec_mono_semicasual_reg : FontID, | ||||
|  | ||||
| 	default_font            : FontID, | ||||
| } | ||||
|  | ||||
| FrameTime :: struct { | ||||
| 	sleep_is_granular : b32, | ||||
|  | ||||
| 	delta_seconds : f64, | ||||
| 	delta_ms      : f64, | ||||
| 	delta_ns      : Duration, | ||||
| 	target_ms     : f64, | ||||
| 	elapsed_ms    : f64, | ||||
| 	avg_ms        : f64, | ||||
| 	fps_avg       : f64, | ||||
| } | ||||
|  | ||||
| // Global Singleton stored in the persistent virtual arena, the first allocated data. | ||||
| // Use get_state() to conviently retrieve at any point for the program's lifetime | ||||
| State :: struct { | ||||
| 	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 | ||||
|  | ||||
| 	string_cache : StringCache, | ||||
|  | ||||
| 	input_data : [2]InputState, | ||||
| 	input_prev : ^InputState, | ||||
| 	input      : ^InputState, | ||||
|  | ||||
| 	debug  : DebugData, | ||||
|  | ||||
| 	project : Project, | ||||
|  | ||||
| 	config     : AppConfig, | ||||
| 	app_window : AppWindow, | ||||
| 	screen_ui  : UI_ScreenState, | ||||
|  | ||||
| 	monitor_id         : i32, | ||||
| 	monitor_refresh_hz : i32, | ||||
|  | ||||
| 	// using frametime : FrameTime, | ||||
| 	sleep_is_granular : b32, | ||||
|  | ||||
| 	frametime_delta_seconds : f64, | ||||
| 	frametime_delta_ms      : f64, | ||||
| 	frametime_delta_ns      : Duration, | ||||
| 	frametime_target_ms     : f64, | ||||
| 	frametime_elapsed_ms    : f64, | ||||
| 	frametime_avg_ms        : f64, | ||||
| 	fps_avg                 : f64, | ||||
|  | ||||
| 	// fonts : FontData, | ||||
| 	font_provider_data : FontProviderData, | ||||
|  | ||||
| 	font_firacode                : FontID, | ||||
| 	font_squidgy_slimes          : FontID, | ||||
| 	font_rec_mono_semicasual_reg : FontID, | ||||
| 	default_font                 : FontID, | ||||
|  | ||||
| 	// 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_floating_context : ^UI_FloatingManager, | ||||
|  | ||||
| 	// The camera is considered the "context" for coodrinate space operations in rendering | ||||
| 	cam_context : Camera, | ||||
| } | ||||
|  | ||||
| get_state :: #force_inline proc "contextless" () -> ^ State { | ||||
| 	return cast( ^ State ) Memory_App.persistent.reserve_start | ||||
| } | ||||
|  | ||||
| // get_frametime :: #force_inline proc "contextless" () -> FrameTime { | ||||
| // 	return get_state().frametime | ||||
| // } | ||||
|  | ||||
| #endregion("State") | ||||
							
								
								
									
										114
									
								
								code/sectr/app/ui_theme_default.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								code/sectr/app/ui_theme_default.odin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| package sectr | ||||
|  | ||||
| /* | ||||
| 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 | ||||
|  | ||||
| @(deferred_none = ui_theme_pop) | ||||
| ui_theme_btn_default :: proc() | ||||
| { | ||||
| 	@static theme : UI_Theme | ||||
| 	@static loaded : b32 = false | ||||
| 	if ! 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       = {}, | ||||
| 		} | ||||
| 		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 | ||||
| 		} | ||||
| 		loaded = true | ||||
| 	} | ||||
| 	ui_layout_push(theme.layout) | ||||
| 	ui_style_push(theme.style) | ||||
| } | ||||
|  | ||||
| @(deferred_none = ui_theme_pop) | ||||
| ui_theme_transparent :: proc() | ||||
| { | ||||
| 	@static theme : UI_Theme | ||||
| 	@static loaded : b32 = false | ||||
| 	if ! loaded || true | ||||
| 	{ | ||||
| 		layout := UI_Layout { | ||||
| 			flags          = {}, | ||||
| 			anchor         = range2({},{}), | ||||
| 			alignment      = {0, 0}, | ||||
| 			text_alignment = {0.0, 0.0}, | ||||
| 			font_size      = 16, | ||||
| 			margins        = {0, 0, 0, 0}, | ||||
| 			padding        = {0, 0, 0, 0}, | ||||
| 			border_width   = 0, | ||||
| 			pos            = {0, 0}, | ||||
| 			size           = range2({},{}) | ||||
| 		} | ||||
| 		style := UI_Style { | ||||
| 			bg_color     = Color_Transparent, | ||||
| 			border_color = Color_Transparent, | ||||
| 			corner_radii = {}, | ||||
| 			blur_size    = 0, | ||||
| 			font         = get_state().default_font, | ||||
| 			text_color   = Color_ThmDark_Text_Default, | ||||
| 			cursor       = {}, | ||||
| 		} | ||||
|  | ||||
| 		layout_combo := to_ui_layout_combo(layout) | ||||
| 		style_combo  := to_ui_style_combo(style) | ||||
| 		{ | ||||
| 			using layout_combo.disabled | ||||
| 			using style_combo.disabled | ||||
| 		} | ||||
| 		{ | ||||
| 			using layout_combo.hot | ||||
| 			using style_combo.hot | ||||
| 		} | ||||
| 		{ | ||||
| 			using layout_combo.active | ||||
| 			using style_combo.active | ||||
| 		} | ||||
|  | ||||
| 		theme = UI_Theme { | ||||
| 			layout_combo, style_combo | ||||
| 		} | ||||
| 		loaded = true | ||||
| 	} | ||||
| 	ui_layout_push(theme.layout) | ||||
| 	ui_style_push(theme.style) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user