Dragging! & basic proportional box resize frm cursor distance to box pos

Still need to add resize via 'pulling' to stretch the box out from a side or 2 sides diagonally.

Also some general clenaup of code
This commit is contained in:
Edward R. Gonzalez 2024-03-08 03:34:21 -05:00
parent 90478bec94
commit 191d5076ea
15 changed files with 278 additions and 79 deletions

12
Readme.md Normal file
View File

@ -0,0 +1,12 @@
# Sectr Prototype
This prototype aims to flesh out ideas I've wanted to explore futher when it came to code editing and tools for code in general.
The project is so far in a "codebase boostrapping" phase.
The code is organized into 2 modules sectr_host & sectr.
The host module loads the main module & its memory. Hot-reloading it's dll when it detects a change.
The main module only depends on libraries provided by odin repo's base, core, or vendor related packages, and a ini-parsing library.

View File

@ -80,6 +80,23 @@ startup :: proc( persistent_mem, frame_mem, transient_mem, files_buffer_mem : ^V
input = & input_data[1]
input_prev = & input_data[0]
// Configuration Load
{
using config
resolution_width = 1000
resolution_height = 600
refresh_rate = 0
cam_min_zoom = 0.25
cam_max_zoom = 10.0
cam_zoom_mode = .Smooth
cam_zoom_smooth_snappiness = 4.0
cam_zoom_sensitivity_digital = 0.2
cam_zoom_sensitivity_smooth = 4.0
ui_resize_border_width = 20
}
// rl.Odin_SetMalloc( RL_MALLOC )
rl.SetConfigFlags( {
@ -119,15 +136,6 @@ startup :: proc( persistent_mem, frame_mem, transient_mem, files_buffer_mem : ^V
path_firacode := strings.concatenate( { Path_Assets, "FiraCode-Regular.ttf" }, frame_allocator() )
font_firacode = font_load( path_firacode, 24.0, "FiraCode" )
// font_data, read_succeded : = os.read_entire_file( path_rec_mono_semicasual_reg )
// verify( read_succeded, fmt.tprintf("Failed to read font file for: %v", path_rec_mono_semicasual_reg) )
// cstr := strings.clone_to_cstring( path_rec_mono_semicasual_reg )
// font_rec_mono_semicasual_reg = rl.LoadFontEx( cstr, cast(i32) points_to_pixels(24.0), nil, 0 )
// delete( cstr)
// rl.GuiSetFont( font_rec_mono_semicasual_reg ) // TODO(Ed) : Does this do anything?
default_font = font_firacode
log( "Default font loaded" )
}
@ -198,8 +206,8 @@ reload :: proc( persistent_mem, frame_mem, transient_mem, files_buffer_mem : ^VA
// Thankfully persistent dynamic allocations are rare, and thus we know exactly which ones they are.
font_provider_data := & get_state().font_provider_data
// font_provide_data.font_cache.hashes.allocator = slab_allocator()
// font_provide_data.font_cache.entries.allocator = slab_allocator()
font_provider_data.font_cache.hashes.allocator = general_slab_allocator()
font_provider_data.font_cache.entries.allocator = general_slab_allocator()
ui_reload( & get_state().project.workspace.ui, cache_allocator = general_slab_allocator() )
@ -217,7 +225,9 @@ tick :: proc( delta_time : f64, delta_ns : Duration ) -> b32
context.allocator = frame_allocator()
context.temp_allocator = transient_allocator()
get_state().frametime_delta_ns = delta_ns
state := get_state()
state.frametime_delta_ns = delta_ns
state.frametime_delta_seconds = delta_time
result := update( delta_time )
render()

View File

@ -10,10 +10,10 @@ Color_White :: rl.WHITE
Color_Transparent :: Color { 0, 0, 0, 0 }
Color_BG :: Color { 41, 41, 45, 255 }
Color_BG_TextBox :: Color { 32, 32, 32, 255 }
Color_BG_TextBox :: Color { 32, 32, 32, 180 }
Color_BG_TextBox_Green :: Color { 102, 102, 110, 255 }
Color_Frame_Disabled :: Color { 22, 22, 22, 120 }
Color_Frame_Hover :: Color { 122, 122, 125, 255 }
Color_Frame_Select :: Color { 188, 188, 188, 255 }
Color_Frame_Hover :: Color { 122, 122, 125, 200 }
Color_Frame_Select :: Color { 188, 188, 188, 220 }
Color_GreyRed :: Color { 220, 100, 100, 125 }
Color_White_A125 :: Color { 255, 255, 255, 125 }

View File

@ -118,8 +118,15 @@ AppConfig :: struct {
resolution_width : uint,
resolution_height : uint,
refresh_rate : uint,
min_zoom : uint,
max_zoom : 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,
ui_resize_border_width : uint,
}
State :: struct {
@ -144,7 +151,8 @@ State :: struct {
engine_refresh_hz : i32,
engine_refresh_target : i32,
frametime_delta_ns : Duration,
frametime_delta_seconds : f64,
frametime_delta_ns : Duration,
font_firacode : FontID,
font_squidgy_slimes : FontID,
@ -190,7 +198,8 @@ Project :: struct {
Workspace :: struct {
name : string,
cam : Camera,
cam : Camera,
zoom_target : f32,
// TODO(Ed) : The workspace is mainly a 'UI' conceptually...
ui : UI_State,
@ -207,7 +216,15 @@ DebugData :: struct {
mouse_vis : b32,
last_mouse_pos : Vec2,
zoom_target : f32,
// Test First
frame_2_created : b32,
// Test Draggable
draggable_box_pos : Vec2,
draggable_box_size : Vec2,
box_original_size : Vec2,
box_resize_started : b32,
ui_drag_delta : Vec2,
ui_drag_start : Vec2,
}

View File

@ -47,7 +47,10 @@ FontGlyphsRender :: struct {
FontDef :: struct {
path_file : string,
data : [] u8,
// TODO(Ed) : you may have to store font data in the future if we render on demand
// data : []u8,
default_size : i32,
size_table : [Font_Largest_Px_Size / 2] FontGlyphsRender,
}
@ -62,8 +65,7 @@ font_provider_startup :: proc()
font_provider_data := & get_state().font_provider_data; using font_provider_data
font_cache_alloc_error : AllocatorError
font_cache, font_cache_alloc_error = zpl_hmap_init_reserve( FontDef, general_slab_allocator(), 8 )
font_cache, font_cache_alloc_error = zpl_hmap_init_reserve( FontDef, general_slab_allocator(), 2 )
verify( font_cache_alloc_error == AllocatorError.None, "Failed to allocate font_cache" )
log("font_cache created")
@ -94,7 +96,7 @@ font_load :: proc( path_file : string,
{
font_provider_data := & get_state().font_provider_data; using font_provider_data
font_data, read_succeded : = os.read_entire_file( path_file, general_slab_allocator() )
font_data, read_succeded : = os.read_entire_file( path_file, context.temp_allocator )
verify( b32(read_succeded), str_fmt_tmp("Failed to read font file for: %v", path_file) )
font_data_size := cast(i32) len(font_data)
@ -117,7 +119,7 @@ font_load :: proc( path_file : string,
verify( set_error == AllocatorError.None, "Failed to add new font entry to cache" )
def.path_file = path_file
def.data = font_data
// def.data = font_data
def.default_size = i32(points_to_pixels(default_size))
// TODO(Ed): this is slow & eats quite a bit of memory early on. Setup a more on demand load for a specific size.

View File

@ -80,6 +80,10 @@ OS_Type :: type_of(ODIN_OS)
// Proc Name Overloads Alias table
// This has to be done on a per-module basis.
add :: proc {
add_range2,
}
cm_to_pixels :: proc {
f32_cm_to_pixels,
vec2_cm_to_pixels,

View File

@ -212,7 +212,8 @@ zpl_hmap_set :: proc( using self : ^ HMapZPL( $ Type), key : u64, value : Type )
entries.data[id].value = value
if zpl_hmap_full( self ) {
return & entries.data[id].value, zpl_hmap_grow( self )
alloc_error := zpl_hmap_grow( self )
return & entries.data[id].value, alloc_error
}
return & entries.data[id].value, AllocatorError.None

View File

@ -280,6 +280,8 @@ main :: proc()
verify( sectr_api.lib_version != 0, "Failed to initially load the sectr module" )
}
free_all( context.temp_allocator )
running = true;
sectr_api = sectr_api
sectr_api.startup(

View File

@ -273,6 +273,12 @@ MouseState :: struct {
vertical_wheel, horizontal_wheel : AnalogAxis
}
mouse_world_delta :: #force_inline proc "contextless" () -> Vec2 {
using state := get_state()
cam := & state.project.workspace.cam
return { input.mouse.delta.x, -input.mouse.delta.y } * ( 1 / cam.zoom )
}
InputState :: struct {
keyboard : KeyboardState,
mouse : MouseState

View File

@ -33,6 +33,19 @@ Range2 :: struct #raw_union{
},
}
range2 :: #force_inline proc "contextless" ( a, b : Vec2 ) -> Range2 {
result := Range2 { pts = { a, b } }
return result
}
Rect :: struct {
top_left, bottom_right : Vec2
}
add_range2 :: #force_inline proc "contextless" ( a, b : Range2 ) -> Range2 {
result := Range2 { pts = {
a.p0 + b.p0,
a.p1 + b.p1,
}}
return result
}

View File

@ -95,6 +95,11 @@ range2_pixels_to_cm :: proc( range : Range2 ) -> Range2 {
Camera :: rl.Camera2D
CameraZoomMode :: enum u32 {
Digital,
Smooth,
}
// 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
@ -160,7 +165,7 @@ view_get_corners :: proc() -> BoundsCorners2 {
return { top_left, top_right, bottom_left, bottom_right }
}
screen_to_world :: proc(pos: Vec2) -> Vec2 {
screen_to_world :: #force_inline proc "contextless" (pos: Vec2) -> Vec2 {
state := get_state(); using state
cam := & project.workspace.cam
result := Vec2 { cam.target.x, -cam.target.y} + Vec2 { pos.x, -pos.y } * (1 / cam.zoom)

View File

@ -60,12 +60,20 @@ render :: proc()
}
}
debug_text("Zoom Target: %v", project.workspace.zoom_target)
if debug.mouse_vis {
debug_text( "Mouse Vertical Wheel: %v", input.mouse.vertical_wheel )
debug_text( "Mouse Position (Screen): %v", input.mouse.pos )
debug_text("Mouse Position (World): %v", screen_to_world(input.mouse.pos) )
cursor_pos := transmute(Vec2) state.app_window.extent + input.mouse.pos
rl.DrawCircleV( cursor_pos, 10, Color_White_A125 )
}
debug_text( "ui_drag_start : %v", debug.ui_drag_start )
debug_text( "ui_drag_delta : %v", debug.ui_drag_delta )
debug_text( "Draggable Box Pos: %v", debug.draggable_box_pos )
debug.draw_debug_text_y = 50
}
//endregion Render Screenspace
@ -81,6 +89,8 @@ render_mode_2d :: proc()
rl.BeginMode2D( project.workspace.cam )
debug_draw_text_world( "This is text in world space", { 0, 200 }, 16.0 )
ImguiRender:
{
ui := & state.project.workspace.ui
@ -118,7 +128,6 @@ render_mode_2d :: proc()
}
//endregion Imgui Render
debug_draw_text_world( "This is text in world space", { 0, 200 }, 16.0 )
if debug.mouse_vis {
cursor_world_pos := screen_to_world(input.mouse.pos)

View File

@ -2,6 +2,7 @@ package sectr
import "base:runtime"
import "core:math"
import "core:math/linalg"
import rl "vendor:raylib"
@ -56,10 +57,16 @@ poll_debug_actions :: proc( actions : ^ DebugActions, input : ^ InputState )
cam_mouse_pan = mouse.right.ended_down && ! pressed(mouse.right)
}
frametime_delta32 :: #force_inline proc "contextless" () -> f32 {
return cast(f32) get_state().frametime_delta_seconds
}
update :: proc( delta_time : f64 ) -> b32
{
state := get_state(); using state
replay := & Memory_App.replay
workspace := & project.workspace
cam := & workspace.cam
if rl.IsWindowResized() {
window := & state.app_window
@ -138,25 +145,30 @@ update :: proc( delta_time : f64 ) -> b32
//region Camera Manual Nav
{
cam := & project.workspace.cam
digital_move_speed : f32 = 200.0
// zoom_sensitivity : f32 = 0.2 // Digital
zoom_sensitivity : f32 = 4.0 // Smooth
if debug.zoom_target == 0.0 {
debug.zoom_target = cam.zoom
if workspace.zoom_target == 0.0 {
workspace.zoom_target = cam.zoom
}
// Adjust zoom_target based on input, not the actual zoom
zoom_delta := input.mouse.vertical_wheel * zoom_sensitivity
debug.zoom_target *= 1 + zoom_delta * f32(delta_time)
debug.zoom_target = clamp(debug.zoom_target, 0.25, 10.0)
config.cam_zoom_smooth_snappiness = 10.0
config.cam_zoom_mode = .Smooth
switch config.cam_zoom_mode
{
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)
// Linearly interpolate cam.zoom towards zoom_target
lerp_factor := cast(f32) 4.0 // Adjust this value to control the interpolation speed
cam.zoom += (debug.zoom_target - cam.zoom) * lerp_factor * f32(delta_time)
cam.zoom = clamp(cam.zoom, 0.25, 10.0) // Ensure cam.zoom stays within bounds
// 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
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)
cam.zoom = workspace.zoom_target
}
move_velocity : Vec2 = {
- cast(f32) i32(debug_actions.cam_move_left) + cast(f32) i32(debug_actions.cam_move_right),
@ -168,7 +180,7 @@ update :: proc( delta_time : f64 ) -> b32
if debug_actions.cam_mouse_pan
{
if is_within_screenspace(input.mouse.pos) {
pan_velocity := input.mouse.delta * (1/cam.zoom)
pan_velocity := input.mouse.delta * ( 1 / cam.zoom )
cam.target -= pan_velocity
}
}
@ -208,7 +220,7 @@ update :: proc( delta_time : f64 ) -> b32
}}
ui_style_theme( frame_theme )
first_layout := UI_Layout {
default_layout := UI_Layout {
anchor = {},
// alignment = { 0.0, 0.0 },
alignment = { 0.5, 0.5 },
@ -216,26 +228,71 @@ update :: proc( delta_time : f64 ) -> b32
pos = { 0, 0 },
size = { 200, 200 },
}
ui_set_layout( first_layout )
ui_set_layout( default_layout )
// First Demo
when true
Test_HoverNClick :: false
Test_Draggable :: true
when Test_HoverNClick
{
first_flags : UI_BoxFlags = { .Mouse_Clickable, .Focusable, .Click_To_Focus }
first_box := ui_box_make( first_flags, "FIRST BOX BOIS" )
first_box := ui_box_make( first_flags, "FIRST BOX!" )
signal := ui_signal_from_box( first_box )
if signal.left_clicked || debug.frame_2_created {
second_layout := first_layout
second_layout := default_layout
second_layout.pos = { 250, 0 }
ui_set_layout( second_layout )
second_box := ui_box_make( first_flags, "SECOND BOX BOIS" )
second_box := ui_box_make( first_flags, "SECOND BOX!" )
signal := ui_signal_from_box( second_box )
debug.frame_2_created = true
}
}
config.ui_resize_border_width = 50
when Test_Draggable
{
draggable_flags := UI_BoxFlags { .Mouse_Clickable, .Focusable, .Click_To_Focus }
draggable_box := ui_box_make( draggable_flags, "Draggable Box!" )
signal := ui_signal_from_box( draggable_box )
if draggable_box.first_frame {
debug.draggable_box_pos = draggable_box.style.layout.pos
debug.draggable_box_size = draggable_box.style.layout.size
}
// Dragging
if signal.dragging {
debug.draggable_box_pos += mouse_world_delta()
}
// Resize
if signal.resizing
{
if ! debug.box_resize_started {
debug.box_original_size = debug.draggable_box_size
}
center := debug.draggable_box_pos
original_distance := linalg.distance(ui_context.cursor_active_start, center)
cursor_distance := linalg.distance(signal.cursor_pos, center)
scale_factor := cursor_distance * (1 / original_distance)
debug.draggable_box_size = debug.box_original_size * scale_factor
}
debug.box_resize_started = cast(b32) signal.resizing
if workspace.ui.hot_resizable || workspace.ui.active_resizing {
draggable_box.style.bg_color = Color_Blue
}
// Note(Ed): Don't necessarily need a layout if its simple...
draggable_box.style.pos = debug.draggable_box_pos
draggable_box.style.layout.size = debug.draggable_box_size
}
}
//endregion Imgui Tick

View File

@ -162,6 +162,7 @@ UI_Signal :: struct {
pressed : b8,
released : b8,
dragging : b8,
resizing : b8,
hovering : b8,
cursor_over : b8,
commit : b8,
@ -202,7 +203,7 @@ UI_Style :: struct {
cursor : UI_Cursor,
layout : UI_Layout,
using layout : UI_Layout,
transition_time : f32,
}
@ -228,16 +229,20 @@ UI_Box :: struct {
// Regenerated per frame.
using links : DLL_NodeFull( UI_Box ), // first, last, prev, next
parent : ^ UI_Box,
parent : ^UI_Box,
num_children : i32,
flags : UI_BoxFlags,
computed : UI_Computed,
theme : UI_StyleTheme,
style : ^ UI_Style,
style : ^UI_Style,
// Persistent Data
style_delta : f32,
first_frame : b8,
hot_delta : f32,
active_delta : f32,
style_delta : f32,
// prev_computed : UI_Computed,
// prev_style : UI_Style,v
mouse : UI_InteractState,
@ -248,7 +253,7 @@ UI_Box :: struct {
UI_Layout_Stack_Size :: 512
UI_Style_Stack_Size :: 512
UI_Parent_Stack_Size :: 1024
UI_Built_Boxes_Array_Size :: 128
UI_Built_Boxes_Array_Size :: 1024
UI_State :: struct {
// TODO(Ed) : Use these
@ -258,11 +263,11 @@ UI_State :: struct {
built_box_count : i32,
caches : [2] HMapZPL( UI_Box ),
prev_cache : ^ HMapZPL( UI_Box ),
curr_cache : ^ HMapZPL( UI_Box ),
prev_cache : ^HMapZPL( UI_Box ),
curr_cache : ^HMapZPL( UI_Box ),
null_box : ^ UI_Box, // Ryan had this, I don't know why yet.
root : ^ UI_Box,
null_box : ^UI_Box, // Ryan had this, I don't know why yet.
root : ^UI_Box,
// Do we need to recompute the layout?
layout_dirty : b32,
@ -272,13 +277,17 @@ UI_State :: struct {
parent_stack : StackFixed( ^UI_Box, UI_Parent_Stack_Size ),
// flag_stack : Stack( UI_BoxFlags, UI_BoxFlags_Stack_Size ),
hot : UI_Key,
active_mouse : [MouseBtn.count] UI_Key,
active : UI_Key,
hot : UI_Key,
active_mouse : [MouseBtn.count] UI_Key,
active : UI_Key,
hot_resizable : b32,
active_resizing : b32, // Locks the user into a resizing state for the active box until they release the active key
clipboard_copy : UI_Key,
last_clicked : UI_Key,
drag_start_mouse : Vec2,
cursor_active_start : Vec2,
// cursor_resize_start : Vec2,
// drag_state_arena : ^ Arena,
// drag_state data : string,
@ -347,6 +356,8 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
verify( set_error == AllocatorError.None, "Failed to set zpl_hmap due to allocator error" )
curr_box = set_result
curr_box.first_frame = prev_box == nil
}
// TODO(Ed) : Review this when we learn layouts more...
@ -396,6 +407,21 @@ ui_box_tranverse_next :: proc( box : ^ UI_Box ) -> (^ UI_Box) {
return box.next
}
ui_cursor_pos :: #force_inline proc "contextless" () -> Vec2 {
using state := get_state()
if ui_context == & state.project.workspace.ui {
return screen_to_world( 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.cursor_active_start
}
ui_graph_build_begin :: proc( ui : ^ UI_State, bounds : Vec2 = {} )
{
get_state().ui_context = ui
@ -457,15 +483,21 @@ ui_signal_from_box :: proc ( box : ^ UI_Box ) -> UI_Signal
ui := get_state().ui_context
input := get_state().input
frame_delta := frametime_delta32()
signal := UI_Signal { box = box }
if ui == & get_state().project.workspace.ui {
signal.cursor_pos = screen_to_world( input.mouse.pos )
}
else {
signal.cursor_pos = input.mouse.pos
}
signal.cursor_over = cast(b8) pos_within_range2( signal.cursor_pos, box.computed.bounds )
// Cursor Collision
signal.cursor_pos = ui_cursor_pos()
signal.cursor_over = cast(b8) pos_within_range2( signal.cursor_pos, box.computed.bounds )
resize_border_width := cast(f32) get_state().config.ui_resize_border_width
resize_border_non_range := add(box.computed.bounds, range2(
{ resize_border_width, -resize_border_width },
{ -resize_border_width, resize_border_width }))
within_resize_range := cast(b8) ! pos_within_range2( signal.cursor_pos, resize_border_non_range )
within_resize_range &= signal.cursor_over
left_pressed := pressed( input.mouse.left )
left_released := released( input.mouse.left )
@ -478,7 +510,7 @@ ui_signal_from_box :: proc ( box : ^ UI_Box ) -> UI_Signal
ui.hot = box.key
ui.active = box.key
ui.active_mouse[MouseBtn.Left] = box.key
ui.drag_start_mouse = signal.cursor_pos
ui.cursor_active_start = signal.cursor_pos
ui.last_pressed_key = box.key
signal.pressed = true
@ -487,18 +519,24 @@ ui_signal_from_box :: proc ( box : ^ UI_Box ) -> UI_Signal
if mouse_clickable && signal.cursor_over && left_released
{
ui.active = UI_Key(0)
box.active_delta = 0
ui.active = UI_Key(0)
ui.active_mouse[MouseBtn.Left] = UI_Key(0)
signal.released = true
signal.left_clicked = true
ui.last_clicked = box.key
}
if mouse_clickable && ! signal.cursor_over && left_released {
if mouse_clickable && ! signal.cursor_over && left_released
{
box.hot_delta = 0
ui.hot = UI_Key(0)
ui.active = UI_Key(0)
ui.active_mouse[MouseBtn.Left] = UI_Key(0)
signal.released = true
signal.left_clicked = false
}
@ -523,22 +561,45 @@ ui_signal_from_box :: proc ( box : ^ UI_Box ) -> UI_Signal
}
is_hot := ui.hot == box.key
is_active := ui.active == box.key
if signal.cursor_over &&
ui.hot == UI_Key(0) || ui.hot == box.key &&
ui.active == UI_Key(0) || ui.active == box.key
ui.hot == UI_Key(0) || is_hot &&
ui.active == UI_Key(0) || is_active
{
ui.hot = box.key
is_hot = true
}
if ! is_active {
ui.hot_resizable = cast(b32) within_resize_range
}
signal.resizing = cast(b8) is_active && (within_resize_range || ui.active_resizing)
if is_hot {
box.hot_delta += frame_delta
}
if is_active {
box.active_delta += frame_delta
}
ui.active_resizing = cast(b32) is_active && signal.resizing
signal.dragging = cast(b8) is_active && ( ! within_resize_range && ! ui.active_resizing)
style_preset := UI_StylePreset.Default
// box.style = stack_peek( & ui.them_stack ).default
if box.key == ui.hot {
style_preset = UI_StylePreset.Hovered
// box.stye = stack_peek( & ui.theme_stack ).hovered
}
if box.key == ui.active {
style_preset = UI_StylePreset.Focused
// box.stye = stack_peek( & ui.theme_stack ).focused
}
if UI_BoxFlag.Disabled in box.flags {
style_preset = UI_StylePreset.Disabled
// box.style = stack_peek( & ui.theme.stack ).disabled
}
box.style = & box.theme.array[style_preset]

View File

@ -20,11 +20,11 @@
],
"odin_command": "C:/projects/SectrPrototype/thirdparty/Odin/odin.exe",
"enable_document_symbols": true,
"enable_fake_methods": true,
"enable_fake_methods": false,
"enable_format": false,
"enable_hover": true,
"enable_semantic_tokens": true,
"enable_snippets": true,
"enable_references": true,
"enable_semantic_tokens": false,
"enable_snippets": false,
"enable_references": false,
"thread_pool_count": 10
}