Some general refactors and compaction

Made a distinction from the "core" ui vs the rest of the ui that composes from there.
This commit is contained in:
Edward R. Gonzalez 2024-05-16 11:21:07 -04:00
parent 7250456db5
commit 5ceef39410
25 changed files with 258 additions and 321 deletions

View 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)
}

View File

@ -1,17 +0,0 @@
package sectr
import rl "vendor:raylib"
range2_to_rl_rect :: #force_inline proc "contextless"( range : Range2 ) -> rl.Rectangle
{
rect := rl.Rectangle {
range.min.x,
range.max.y,
abs(range.max.x - range.min.x),
abs(range.max.y - range.min.y),
}
return rect
}

View File

@ -0,0 +1,2 @@
package sectr

View File

@ -4,6 +4,17 @@ import "core:fmt"
import rl "vendor:raylib"
range2_to_rl_rect :: #force_inline proc "contextless"( range : Range2 ) -> rl.Rectangle
{
rect := rl.Rectangle {
range.min.x,
range.max.y,
abs(range.max.x - range.min.x),
abs(range.max.y - range.min.y),
}
return rect
}
draw_rectangle :: #force_inline proc "contextless" ( rect : rl.Rectangle, box : ^UI_RenderBoxInfo ) {
using box
if style.corner_radii[0] > 0 {
@ -211,9 +222,9 @@ render_mode_screenspace :: proc ()
render_screen_ui()
fps_msg := str_fmt_tmp( "FPS: %f", fps_avg)
fps_msg_width := measure_text_size( fps_msg, default_font, 16.0, 0.0 ).x
fps_msg_width := measure_text_size( fps_msg, default_font, 12.0, 0.0 ).x
fps_msg_pos := screen_get_corners().top_right - { fps_msg_width, 0 } - { 5, 5 }
debug_draw_text( fps_msg, fps_msg_pos, 16.0, color = rl.GREEN )
debug_draw_text( fps_msg, fps_msg_pos, 12.0, color = rl.GREEN )
debug_text :: proc( format : string, args : ..any )
{
@ -232,7 +243,7 @@ render_mode_screenspace :: proc ()
position.y -= debug.draw_debug_text_y
content := str_fmt_buffer( draw_text_scratch[:], format, ..args )
debug_draw_text( content, position, 14.0 )
debug_draw_text( content, position, 12.0 )
debug.draw_debug_text_y += 14
}
@ -293,7 +304,6 @@ render_mode_screenspace :: proc ()
}
view := view_get_bounds()
// debug_text("View Bounds (World): %v", view.pts )
debug.draw_debug_text_y = 14
@ -304,10 +314,6 @@ render_mode_screenspace :: proc ()
0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, // Vertex 2: Green
0.0, 0.5, 0.0, 0.0, 0.0, 1.0, 1.0 // Vertex 3: Blue
}
// Begin using the shader to draw
// rl.BeginShaderMode(debug.proto_text_shader)
// rl.EndShaderMode()
}
// A non-zoomable static-view for ui
@ -366,7 +372,6 @@ render_screen_ui :: proc()
line_thickness : f32 = 1
// profile_begin("rl.DrawRectangleRoundedLines: padding & content")
if debug.draw_UI_padding_bounds && equal_range2(computed.content, computed.padding) {
draw_rectangle_lines( rect_padding, & current, Color_Debug_UI_Padding_Bounds, line_thickness )
}
@ -376,16 +381,17 @@ render_screen_ui :: proc()
point_radius : f32 = 3
// profile_begin("circles")
if debug.draw_ui_box_bounds_points
{
computed_size := computed.bounds.p1 - computed.bounds.p0
// center := Vec2 {
// render_bounds.p0.x + computed_size.x * 0.5,
// render_bounds.p0.y - computed_size.y * 0.5,
// }
// rl.DrawCircleV( center, point_radius, Color_White )
if false
{
center := Vec2 {
render_bounds.p0.x + computed_size.x * 0.5,
render_bounds.p0.y - computed_size.y * 0.5,
}
rl.DrawCircleV( center, point_radius, Color_White )
}
rl.DrawCircleV( render_bounds.p0, point_radius, Color_Red )
rl.DrawCircleV( render_bounds.p1, point_radius, Color_Blue )
}

View File

@ -150,7 +150,7 @@ else
// Raylib's equivalent doesn't take a length for the string (making it a pain in the ass)
// So this is a 1:1 copy except it takes Odin strings
measure_text_size :: proc( text : string, font : FontID, font_size := Font_Use_Default_Size, spacing : f32 ) -> Vec2
measure_text_size_raylib :: proc( text : string, font : FontID, font_size := Font_Use_Default_Size, spacing : f32 ) -> Vec2
{
// profile(#procedure)
px_size := math.round( points_to_pixels( font_size ) )

View File

@ -0,0 +1 @@
package genodin

View File

@ -1,11 +1,5 @@
package sectr
// GrimeContextExt :: struct {
// dbg_name : string
// }
// Global_Transient_Context : GrimeContextExt
context_ext :: proc( $ Type : typeid ) -> (^Type) {
return cast(^Type) context.user_ptr
}

View File

@ -99,13 +99,6 @@ import "thirdparty:backtrace"
#endregion("Import Aliases")
OS_Type :: type_of(ODIN_OS)
swap :: proc( a, b : ^ $Type ) -> ( ^ Type, ^ Type ) {
return b, a
}
#region("Proc overload mappings")
// This has to be done on a per-module basis.
@ -163,6 +156,10 @@ is_power_of_two :: proc {
is_power_of_two_uintptr,
}
measure_text_size :: proc {
measure_text_size_raylib,
}
mov_avg_exp :: proc {
mov_avg_exp_f32,
mov_avg_exp_f64,
@ -279,6 +276,11 @@ to_ui_layout_side :: proc {
to_ui_layout_side_vec2,
}
ui_compute_layout :: proc {
ui_core_compute_layout,
ui_box_compute_layout,
}
ui_floating :: proc {
ui_floating_just_builder,
ui_floating_with_capture,
@ -316,3 +318,7 @@ wedge :: proc {
}
#endregion("Proc overload mappings")
OS_Type :: type_of(ODIN_OS)
swap :: #force_inline proc( a, b : ^ $Type ) -> ( ^ Type, ^ Type ) { return b, a }

View File

@ -32,25 +32,25 @@ Side :: enum i32 {
// Count,
// }
UI_AnchorPresets :: enum u32 {
Top_Left,
Top_Right,
Bottom_Right,
Bottom_Left,
Center_Left,
Center_Top,
Center_Right,
Center_Bottom,
Center,
Left_Wide,
Top_Wide,
Right_Wide,
Bottom_Wide,
VCenter_Wide,
HCenter_Wide,
Full,
Count,
}
// UI_AnchorPresets :: enum u32 {
// Top_Left,
// Top_Right,
// Bottom_Right,
// Bottom_Left,
// Center_Left,
// Center_Top,
// Center_Right,
// Center_Bottom,
// Center,
// Left_Wide,
// Top_Wide,
// Right_Wide,
// Bottom_Wide,
// VCenter_Wide,
// HCenter_Wide,
// Full,
// Count,
// }
UI_Cursor :: struct {
placeholder : int,
@ -136,8 +136,7 @@ ui_startup :: proc( ui : ^ UI_State, cache_allocator : Allocator /* , cache_rese
ui := ui
ui^ = {}
// cache.ref in ui.caches.ref
for & cache in (& ui.caches) {
for & cache in ui.caches {
box_cache, allocation_error := zpl_hmap_init_reserve( UI_Box, cache_allocator, UI_Built_Boxes_Array_Size )
verify( allocation_error == AllocatorError.None, "Failed to allocate box cache" )
cache = box_cache
@ -155,7 +154,7 @@ ui_startup :: proc( ui : ^ UI_State, cache_allocator : Allocator /* , cache_rese
ui_reload :: proc( ui : ^ UI_State, cache_allocator : Allocator )
{
// We need to repopulate Allocator references
for & cache in & ui.caches {
for & cache in ui.caches {
zpl_hmap_reload( & cache, cache_allocator)
}
ui.render_queue.backing = cache_allocator
@ -180,11 +179,6 @@ ui_drag_delta :: #force_inline proc "contextless" () -> Vec2 {
return ui_cursor_pos() - state.ui_context.active_start_signal.cursor_pos
}
ui_ws_drag_delta :: #force_inline proc "contextless" () -> Vec2 {
using state := get_state()
return screen_to_ws_view_pos(input.mouse.pos) - state.ui_context.active_start_signal.cursor_pos
}
ui_graph_build_begin :: proc( ui : ^ UI_State, bounds : Vec2 = {} )
{
profile(#procedure)
@ -197,10 +191,7 @@ ui_graph_build_begin :: proc( ui : ^ UI_State, bounds : Vec2 = {} )
stack_clear( & style_combo_stack )
array_clear( render_queue )
temp := prev_cache
prev_cache = curr_cache
curr_cache = temp
// curr_cache, prev_cache = swap( curr_cache, prev_cache )
curr_cache, prev_cache = swap( curr_cache, prev_cache )
if ui.active == UI_Key(0) {
//ui.hot = UI_Key(0)
@ -228,9 +219,7 @@ ui_graph_build_end :: proc( ui : ^UI_State )
}
@(deferred_in = ui_graph_build_end)
ui_graph_build :: proc( ui : ^ UI_State ) {
ui_graph_build_begin( ui )
}
ui_graph_build :: #force_inline proc( ui : ^ UI_State ) { ui_graph_build_begin( ui ) }
ui_key_from_string :: #force_inline proc "contextless" ( value : string ) -> UI_Key
{
@ -254,26 +243,13 @@ ui_key_from_string :: #force_inline proc "contextless" ( value : string ) -> UI_
return key
}
ui_parent_push :: proc( ui : ^ UI_Box ) {
stack := & get_state().ui_context.parent_stack
stack_push( & get_state().ui_context.parent_stack, ui )
}
ui_parent_pop :: proc() {
// If size_to_content is set, we need to compute the layout now.
// Check to make sure that the parent's children are the same for this frame,
// if its not we need to mark the layout as dirty.
stack_pop( & get_state().ui_context.parent_stack )
}
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 ) }
@(deferred_none = ui_parent_pop)
ui_parent :: #force_inline proc( ui : ^UI_Box) { ui_parent_push( ui ) }
ui_prev_cached_box :: #force_inline proc( box : ^UI_Box ) -> ^UI_Box {
return zpl_hmap_get( ui_context().prev_cache, cast(u64) box.key )
}
ui_prev_cached_box :: #force_inline proc( box : ^UI_Box ) -> ^UI_Box { return zpl_hmap_get( ui_context().prev_cache, cast(u64) box.key ) }
// Topmost ancestor that is not the root
ui_top_ancestor :: #force_inline proc "contextless" ( box : ^UI_Box ) -> (^UI_Box) {

View File

@ -1,6 +1,7 @@
package sectr
UI_BoxFlag :: enum u64 {
UI_BoxFlag :: enum u64
{
Disabled,
Focusable,
@ -9,13 +10,6 @@ UI_BoxFlag :: enum u64 {
Mouse_Clickable,
Keyboard_Clickable,
// Pan_X,
// Pan_Y,
// Scroll_X,
// Scroll_Y,
// Screenspace,
Count,
}
UI_BoxFlags :: bit_set[UI_BoxFlag; u64]
@ -24,9 +18,9 @@ UI_BoxFlags :: bit_set[UI_BoxFlag; u64]
UI_RenderBoxInfo :: struct {
using computed : UI_Computed,
using style : UI_Style,
text : StrRunesPair,
font_size : UI_Scalar,
border_width : UI_Scalar,
text : StrRunesPair,
font_size : UI_Scalar,
border_width : UI_Scalar,
}
UI_Box :: struct {
@ -60,8 +54,6 @@ UI_Box :: struct {
first_frame : b8,
// root_order_id : i16,
// prev_computed : UI_Computed,
// prev_style : UI_Style,v
// mouse : UI_InteractState,
// keyboard : UI_InteractState,
}
@ -82,16 +74,13 @@ ui_box_from_key :: #force_inline proc ( cache : ^HMapZPL(UI_Box), key : UI_Key )
ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
{
// profile(#procedure)
using ui := get_state().ui_context
key := ui_key_from_string( label )
curr_box : (^ UI_Box)
prev_box := zpl_hmap_get( prev_cache, cast(u64) key )
{
// profile("Assigning current box")
set_result : ^ UI_Box
set_error : AllocatorError
if prev_box != nil
@ -103,18 +92,15 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
box : UI_Box
box.key = key
box.label = str_intern( label )
// set_result, set_error = zpl_hmap_set( prev_cache, cast(u64) key, box )
set_result, set_error = zpl_hmap_set( curr_cache, cast(u64) key, box )
}
verify( set_error == AllocatorError.None, "Failed to set zpl_hmap due to allocator error" )
curr_box = set_result
curr_box = set_result
curr_box.first_frame = prev_box == nil
curr_box.flags = flags
}
curr_box.flags = flags
// Clear non-persistent data
curr_box.computed.fresh = false
curr_box.links = {}
@ -124,30 +110,7 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
parent := stack_peek( & parent_stack )
if parent != nil
{
when true {
dll_full_push_back( parent, curr_box, nil )
}
else
{
// |
// v
// parent.first <nil>
if parent.first == nil {
parent.first = curr_box
parent.last = curr_box
curr_box.next = nil
curr_box.prev = nil
}
else {
// Positin is set to last, insert at end
// <parent.last.prev> <parent.last> curr_box
parent.last.next = curr_box
curr_box.prev = parent.last
parent.last = curr_box
curr_box.next = nil
}
}
dll_full_push_back( parent, curr_box, nil )
curr_box.parent_index = parent.num_children
parent.num_children += 1
curr_box.parent = parent
@ -160,37 +123,31 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box)
ui_box_tranverse_next :: proc "contextless" ( box : ^ UI_Box ) -> (^ UI_Box)
{
// Check to make sure parent is present on the screen, if its not don't bother.
// If current has children, do them first
using state := get_state()
// If current has children, do them first
if box.first != nil
{
// Check to make sure parent is present on the screen, if its not don't bother.
is_app_ui := ui_context == & screen_ui
if is_app_ui || intersects_range2( view_get_bounds(), box.computed.bounds)
if intersects_range2( view_get_bounds(), box.computed.bounds)
{
return box.first
}
}
if box.next == nil
{
// There is no more adjacent nodes
if box.parent != nil
{
parent := box.parent
// Attempt to find a parent with a next, otherwise we just return a parent with nil
for ; parent.parent != nil;
{
if parent.next != nil {
break
}
parent = parent.parent
}
if box.next != nil do return box.next
// There is no more adjacent nodes
// Lift back up to parent, and set it to its next.
return parent.next
parent := box.parent
// Attempt to find a parent with a next, otherwise we just return a parent with nil
for ; parent.parent != nil;
{
if parent.next != nil {
break
}
parent = parent.parent
}
return box.next
// Lift back up to parent, and set it to its next.
return parent.next
}

View File

@ -76,7 +76,6 @@ UI_LayoutFlag :: enum u32 {
Fixed_Width,
Fixed_Height,
// TODO(Ed): Implement this!
// Enforces the widget will have a width specified as a ratio of its height (use the size.min/max.x to specify the scalar)
// If you wish for the width to stay fixed couple with the Fixed_Width flag
Scale_Width_By_Height_Ratio,
@ -96,6 +95,9 @@ UI_LayoutFlag :: enum u32 {
Size_To_Text,
// TODO(Ed): Implement this!
// ?Note(Ed): This can get pretty complicated... Maybe its better to leave this to composition of boxes.
// ?A text wrapping panel can organize text and wrap it via procedrually generated lines in a hbox/vbox.
// ?It would be a non-issue so long as the text rendering bottleneck is resolved.
// Wrap text around the box, text_alignment specifies the justification for its compostion when wrapping.
Text_Wrap,

View File

@ -8,26 +8,10 @@ ui_box_compute_layout :: proc( box : ^UI_Box,
// profile("Layout Box")
state := get_state()
ui := state.ui_context
parent := box.parent
style := box.style
layout := & box.layout
// These are used to choose via multiplication weather to apply
// position & size constraints of the parent.
// The parent's unadjusted content bounds however are enforced for position,
// they cannot be ignored. The user may bypass them by doing the
// relative offset math vs world/screen space if they desire.
// fixed_pos_x : f32 = cast(f32) int(.Fixed_Position_X in layout.flags)
// fixed_pos_y : f32 = cast(f32) int(.Fixed_Position_Y in layout.flags)
// fixed_width : f32 = cast(f32) int(.Fixed_Width in layout.flags)
// fixed_height : f32 = cast(f32) int(.Fixed_Height in layout.flags)
using box
size_to_text : bool = .Size_To_Text in layout.flags
computed := & box.computed
parent_content := parent.computed.content
parent_content_size := parent_content.max - parent_content.min
parent_center := parent_content.min + parent_content_size * 0.5
@ -98,6 +82,13 @@ ui_box_compute_layout :: proc( box : ^UI_Box,
adjusted_size = text_size
}
if .Scale_Width_By_Height_Ratio in layout.flags {
adjusted_size.x = adjusted_size.y * layout.size.min.x
}
if .Scale_Height_By_Width_Ratio in layout.flags {
adjusted_size.y = adjusted_size.x * layout.size.min.y
}
if .Size_To_Content in layout.flags {
// Preemtively traverse the children of this parent and have them compute their layout.
// This parent will just set its size to the max bounding area of those children.
@ -135,8 +126,7 @@ ui_box_compute_layout :: proc( box : ^UI_Box,
// 6. Determine the box bounds
// Adjust Alignment of pivot position
alignment := layout.alignment
bounds : Range2
bounds : Range2
if ! (.Origin_At_Anchor_Center in layout.flags) {
// The convention offset adjust the box so that the top-left point is at the top left of the anchor's bounds
tl_convention_offset := adjusted_size * {0, -1}
@ -153,6 +143,7 @@ ui_box_compute_layout :: proc( box : ^UI_Box,
)
}
// 7. Padding & Content
// Determine Padding's outer bounds
border_offset := Vec2 { layout.border_width, layout.border_width }
@ -167,21 +158,20 @@ ui_box_compute_layout :: proc( box : ^UI_Box,
bounds.max - { layout.padding.right, layout.padding.top } - border_offset,
)
computed.bounds = bounds
computed.bounds = bounds
computed.padding = padding_bounds
computed.content = content_bounds
// 8. Text position & size
if len(box.text.str) > 0
{
content_size := content_bounds.max - content_bounds.min
text_pos : Vec2
text_pos = content_bounds.min + { 0, text_size.y }
// text_pos.x += ( content_size.x - text_size.x ) * layout.text_alignment.x
// text_pos.y += ( content_size.y - text_size.y ) * layout.text_alignment.y
text_pos += (content_size - text_size) * layout.text_alignment
computed.text_size = text_size
computed.text_pos = { text_pos.x, text_pos.y }
computed.text_pos = text_pos
}
computed.fresh = true && !dont_mark_fresh
}
@ -196,7 +186,7 @@ ui_box_compute_layout_children :: proc( box : ^UI_Box )
}
}
ui_compute_layout :: proc( ui : ^UI_State )
ui_core_compute_layout :: proc( ui : ^UI_State )
{
profile(#procedure)
state := get_state()

View File

@ -116,20 +116,21 @@ ui_floating_build :: proc()
lookup.builder = to_enqueue.builder
}
lookup.queued = true
if first == nil {
first = lookup
last = lookup
continue
}
if first == last {
last = lookup
last.prev = first
first.next = last
continue
}
last.next = lookup
lookup.prev = last
last = lookup
dll_full_push_back(floating, lookup, nil )
// if first == nil {
// first = lookup
// last = lookup
// continue
// }
// if first == last {
// last = lookup
// last.prev = first
// first.next = last
// continue
// }
// last.next = lookup
// lookup.prev = last
// last = lookup
}
array_clear(build_queue)

View File

@ -35,116 +35,3 @@ ui_theme_via_theme :: #force_inline proc( theme : UI_Theme ) {
ui_layout_push( theme.layout )
ui_style_push( theme.style )
}
/*
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)
}

View File

@ -425,6 +425,18 @@ ui_spacer :: proc( label : string ) -> (widget : UI_Widget) {
return
}
// UI_ScrollBox {
// using widget : UI_Widget,
// scroll_bar : UI_Widget,
// content : UI_Widget,
// }
// ui_scroll_box :: proc( label : string ) -> (scroll_box : UI_ScrollBox) {
// }
// ui_scrollable_view( )
#region("Text")
ui_text :: proc( label : string, content : StrRunesPair, flags : UI_BoxFlags = {} ) -> UI_Widget
@ -468,6 +480,8 @@ ui_text_tabs :: proc( label : string, flags : UI_BoxFlags = {} ) -> UI_Widget
box.text = tab_str
return { box, signal }
}
ui_text_wrap_panel :: proc( label : string, flags : UI_BoxFlags = {} )
#endregion("Text")
#region("Vertical Box")

View File

@ -38,12 +38,16 @@ foreach ($file in $files)
}
else
{
# For files without a namespace, create a symbolic link in the root of the original code's path in virtual view
$linkPath = Join-Path $path_virtual_view $fileName
if (-not (Test-Path $linkPath)) {
New-Item -ItemType SymbolicLink -Path $linkPath -Value $file.FullName
}
}
# For files without a namespace, maintain the directory structure in the virtual view
$relativePath = $file.FullName.Substring($path_code.Length + 1)
$linkPath = Join-Path $path_virtual_view $relativePath
$linkDir = Split-Path -Parent $linkPath
if (-not (Test-Path $linkDir)) {
New-Item -ItemType Directory -Path $linkDir -Force
}
New-Item -ItemType SymbolicLink -Path $linkPath -Value $file.FullName
}
}
Write-Host "Virtual view created successfully."

@ -1 +1 @@
Subproject commit 0d4069d2ea7aaf155b8c5d979fbbc590360314d0
Subproject commit 67ae530d22c116f86d476743b5dfc978255391d4