From 635ce91a9d6ef6f55316657d1d85657142b4448a Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sat, 9 Mar 2024 10:21:48 -0500 Subject: [PATCH] First text box!!! --- Readme.md | 2 + code/api.odin | 2 +- code/colors.odin | 3 + code/font_provider.odin | 2 +- code/grime.odin | 4 +- code/grime_string_interning.odin | 2 +- code/text.odin | 6 +- code/tick_render.odin | 32 ++++++++++- code/tick_update.odin | 53 +++++++++++++++++- code/ui.odin | 31 +++++----- code/{ui.layout.odin => ui_layout.odin} | 48 +++++++++++----- code/ui_widgets.odin | 5 ++ .../assets/sectr_host_2024-03-09_04-30-27.png | Bin 0 -> 31300 bytes 13 files changed, 149 insertions(+), 41 deletions(-) rename code/{ui.layout.odin => ui_layout.odin} (67%) create mode 100644 docs/assets/sectr_host_2024-03-09_04-30-27.png diff --git a/Readme.md b/Readme.md index c13e8b6..28c2ef0 100644 --- a/Readme.md +++ b/Readme.md @@ -1,5 +1,7 @@ # Sectr Prototype +![img](docs/assets/sectr_host_2024-03-09_04-30-27.png) + 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 things to explore: diff --git a/code/api.odin b/code/api.odin index 966ef90..caf159b 100644 --- a/code/api.odin +++ b/code/api.odin @@ -112,7 +112,7 @@ startup :: proc( persistent_mem, frame_mem, transient_mem, files_buffer_mem : ^V rl.SetConfigFlags( { rl.ConfigFlag.WINDOW_RESIZABLE, - // rl.ConfigFlag.WINDOW_TOPMOST, + rl.ConfigFlag.WINDOW_TOPMOST, }) // Rough setup of window with rl stuff diff --git a/code/colors.odin b/code/colors.odin index 940c2a3..26768f6 100644 --- a/code/colors.odin +++ b/code/colors.odin @@ -17,3 +17,6 @@ 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 } + +Color_Debug_UI_Padding_Bounds :: Color { 40, 195, 170, 125 } +Color_Debug_UI_Content_Bounds :: Color { 195, 40, 170, 125 } diff --git a/code/font_provider.odin b/code/font_provider.odin index 7dee121..09e4c45 100644 --- a/code/font_provider.odin +++ b/code/font_provider.odin @@ -114,7 +114,7 @@ font_load :: proc( path_file : string, default_size = Font_Default_Point_Size } - key := cast(u64) crc32( transmute([]byte) desired_id ) + key := cast(u64) xxh32( transmute([]byte) desired_id ) def, set_error := zpl_hmap_set( & font_cache, key,FontDef {} ) verify( set_error == AllocatorError.None, "Failed to add new font entry to cache" ) diff --git a/code/grime.odin b/code/grime.odin index 9f67e94..9bb8b2c 100644 --- a/code/grime.odin +++ b/code/grime.odin @@ -18,7 +18,9 @@ import "base:runtime" import c "core:c/libc" import "core:dynlib" import "core:hash" - crc32 :: hash.crc32 + // crc32 :: hash.crc32 +import "core:hash/xxhash" + xxh32 :: xxhash.XXH32 import fmt_io "core:fmt" str_fmt :: fmt_io.printf str_fmt_tmp :: fmt_io.tprintf diff --git a/code/grime_string_interning.odin b/code/grime_string_interning.odin index 77d3d93..6f9daaa 100644 --- a/code/grime_string_interning.odin +++ b/code/grime_string_interning.odin @@ -64,7 +64,7 @@ str_intern :: proc( { cache := get_state().string_cache - key := u64( crc32( transmute([]byte) content )) + key := u64( xxh32( transmute([]byte) content )) result := zpl_hmap_get( & cache.table, key ) if result != nil { return (result ^) diff --git a/code/text.odin b/code/text.odin index 4885808..40534c7 100644 --- a/code/text.odin +++ b/code/text.odin @@ -70,17 +70,15 @@ draw_text_string_cached :: proc( content : StringCached, pos : Vec2, size : f32, } font := font if font.key == Font_Default.key { - // if len(font) == 0 { font = default_font } pos := world_to_screen_pos(pos) px_size := size zoom_adjust := px_size * project.workspace.cam.zoom + rl_font := to_rl_Font(font, zoom_adjust ) + runes := content.runes - runes := content.runes - - rl_font := to_rl_Font(font, zoom_adjust ) rl.DrawTextCodepoints( rl_font, raw_data(runes), cast(i32) len(runes), position = transmute(rl.Vector2) pos, diff --git a/code/tick_render.odin b/code/tick_render.odin index 1b04112..a04d6de 100644 --- a/code/tick_render.odin +++ b/code/tick_render.odin @@ -114,16 +114,44 @@ render_mode_2d :: proc() world_to_screen_pos(computed.bounds.max), }} - rect := rl.Rectangle { + render_padding := range2( + world_to_screen_pos(computed.padding.min), + world_to_screen_pos(computed.padding.max), + ) + render_content := range2( + world_to_screen_pos(computed.content.min), + world_to_screen_pos(computed.content.max), + ) + + rect_bounds := rl.Rectangle { render_bounds.min.x, render_bounds.min.y, render_bounds.max.x - render_bounds.min.x, render_bounds.max.y - render_bounds.min.y, } - rl.DrawRectangleRec( rect, style.bg_color ) + rect_padding := rl.Rectangle { + render_padding.min.x, + render_padding.min.y, + render_padding.max.x - render_padding.min.x, + render_padding.max.y - render_padding.min.y, + } + rect_content := rl.Rectangle { + render_content.min.x, + render_content.min.y, + render_content.max.x - render_content.min.x, + render_content.max.y - render_content.min.y, + } + + rl.DrawRectangleRounded( rect_bounds, style.layout.corner_radii[0], 9, style.bg_color ) + rl.DrawRectangleRoundedLines( rect_padding, style.layout.corner_radii[0], 9, 2, Color_Debug_UI_Padding_Bounds ) + rl.DrawRectangleRoundedLines( rect_content, style.layout.corner_radii[0], 9, 2, Color_Debug_UI_Content_Bounds ) rl.DrawCircleV( render_bounds.p0, 5, Color_Red ) rl.DrawCircleV( render_bounds.p1, 5, Color_Blue ) + if len(current.text.str) > 0 { + draw_text_string_cached( current.text, world_to_screen_pos(computed.text_pos), style.font_size, style.text_color ) + } + current = ui_box_tranverse_next( current ) } } diff --git a/code/tick_update.odin b/code/tick_update.odin index 3eefc7b..24017a8 100644 --- a/code/tick_update.odin +++ b/code/tick_update.odin @@ -200,18 +200,30 @@ update :: proc( delta_time : f64 ) -> b32 frame_style_default := UI_Style { flags = frame_style_flags, bg_color = Color_BG_TextBox, + font = default_font, + font_size = 30, + text_color = Color_White, } frame_style_disabled := UI_Style { flags = frame_style_flags, bg_color = Color_Frame_Disabled, + font = default_font, + font_size = 30, + text_color = Color_White, } frame_style_hovered := UI_Style { flags = frame_style_flags, bg_color = Color_Frame_Hover, + font = default_font, + font_size = 30, + text_color = Color_White, } frame_style_select := UI_Style { flags = frame_style_flags, bg_color = Color_Frame_Select, + font = default_font, + font_size = 30, + text_color = Color_White, } frame_theme := UI_StyleTheme { styles = { frame_style_default, @@ -223,9 +235,11 @@ update :: proc( delta_time : f64 ) -> b32 default_layout := UI_Layout { anchor = {}, - // alignment = { 0.0, 0.0 }, + // alignment = { 0.0, 0.5 }, alignment = { 0.5, 0.5 }, + text_alignment = { 1.0, 1.0 }, // alignment = { 1.0, 1.0 }, + corner_radii = { 0.3, 0.3, 0.3, 0.3 }, pos = { 0, 0 }, size = { 200, 200 }, } @@ -234,7 +248,44 @@ update :: proc( delta_time : f64 ) -> b32 // test_hover_n_click() // test_draggable() + config.ui_resize_border_width = 2 + // First box with text!!!! + { + @static pos : Vec2 + text := str_intern( "Lorem ipsum dolor sit amet") + + text_size := measure_text_size( text.str, default_font, 30, 0 ) + + ui_style_theme( { styles = { + frame_style_default, + frame_style_default, + frame_style_default, + frame_style_default, + }}) + + layout := default_layout + layout.size = cast(Vec2) text_size + layout.size.y *= 4 + layout.size.x *= 1.5 + // layout.size.y *= 3.248 + // layout.size.x *= 1.348 + // layout.size.x *= 1.348 + layout.padding = ui_layout_padding( 30 ) + ui_set_layout( layout ) + + text_box := ui_widget( "TEXT BOX!", UI_BoxFlags { .Mouse_Clickable, .Focusable, .Click_To_Focus } ) + if text_box.first_frame { + pos = text_box.style.layout.pos + text_box.text = text + } + + if text_box.dragging { + pos += mouse_world_delta() + } + + text_box.style.layout.pos = pos + } } //endregion Imgui Tick diff --git a/code/ui.odin b/code/ui.odin index 15f5d15..b1f048e 100644 --- a/code/ui.odin +++ b/code/ui.odin @@ -74,16 +74,18 @@ UI_BoxFlag_Scroll :: UI_BoxFlags { .Scroll_X, .Scroll_Y } // The UI_Box's actual positioning and sizing // There is an excess of rectangles here for debug puproses. UI_Computed :: struct { - bounds : Range2, - padding : Range2, - content : Range2, + bounds : Range2, + padding : Range2, + content : Range2, + text_pos : Vec2, + text_size : Vec2, } -UI_LayoutSide :: struct #raw_union { - using _ : struct { +UI_LayoutSide :: struct { + // using _ : struct { top, bottom : UI_Scalar, left, right : UI_Scalar, - } + // } } UI_Cursor :: struct { @@ -124,8 +126,9 @@ UI_Layout :: struct { // flags : UI_LayoutFlags // TODO(Ed) : Make sure this is all we need to represent an anchor. - anchor : Range2, - alignment : Vec2, + anchor : Range2, + alignment : Vec2, + text_alignment : Vec2, border_width : UI_Scalar, @@ -197,7 +200,6 @@ UI_Style :: struct { font : FontID, font_size : f32, text_color : Color, - text_alignment : UI_TextAlign, cursor : UI_Cursor, @@ -333,11 +335,6 @@ ui_box_equal :: proc( a, b : ^ UI_Box ) -> b32 { return result } -UI_Widget :: struct { - using box : ^UI_Box, - using signal : UI_Signal, -} - ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box) { using ui := get_state().ui_context @@ -451,10 +448,14 @@ ui_graph_build :: proc( ui : ^ UI_State ) { } ui_key_from_string :: proc( value : string ) -> UI_Key { - key := cast(UI_Key) crc32( transmute([]byte) value ) + key := cast(UI_Key) xxh32( transmute([]byte) value ) return key } +ui_layout_padding :: proc( pixels : f32 ) -> UI_LayoutSide { + return { pixels, pixels, pixels, pixels } +} + ui_parent_push :: proc( ui : ^ UI_Box ) { stack := & get_state().ui_context.parent_stack stack_push( & get_state().ui_context.parent_stack, ui ) diff --git a/code/ui.layout.odin b/code/ui_layout.odin similarity index 67% rename from code/ui.layout.odin rename to code/ui_layout.odin index 0c79e4b..cd8a0a7 100644 --- a/code/ui.layout.odin +++ b/code/ui_layout.odin @@ -28,10 +28,10 @@ ui_compute_layout :: proc() style := current.style layout := & style.layout - margins := Range2 { pts = { + margins := range2( parent_content.p0 + { layout.margins.left, layout.margins.top }, parent_content.p1 - { layout.margins.right, layout.margins.bottom }, - }} + ) anchor := & layout.anchor pos : Vec2 @@ -61,35 +61,53 @@ ui_compute_layout :: proc() } half_size := size * 0.5 - size_bounds := Range2 { pts = { + size_bounds := range2( Vec2 {}, { size.x, -size.y }, - }} + ) - aligned_bounds := Range2 { pts = { + aligned_bounds := range2( size_bounds.p0 + size * { -layout.alignment.x, layout.alignment.y }, size_bounds.p1 - size * { layout.alignment.x, -layout.alignment.y }, - }} + ) bounds := & computed.bounds (bounds^) = aligned_bounds - (bounds^) = { pts = { + (bounds^) = range2( pos + aligned_bounds.p0, pos + aligned_bounds.p1, - }} + ) border_offset := Vec2 { layout.border_width, layout.border_width } padding := & computed.padding - (padding^) = { pts = { + (padding^) = range2( bounds.p0 + border_offset, - bounds.p1 - border_offset, - }} + bounds.p1 + border_offset, + ) content := & computed.content - (content^) = { pts = { - bounds.p0 + { layout.padding.left, layout.padding.top }, - bounds.p1 - { layout.padding.right, layout.padding.bottom }, - }} + (content^) = range2( + bounds.p0 + { layout.padding.left, -layout.padding.top }, + bounds.p1 + { -layout.padding.right, layout.padding.bottom }, + ) + + // Text + if len(current.text.str) > 0 + { + top_left := content.p0 + bottom_right := content.p1 + + content_size := Vec2 { top_left.x - bottom_right.x, top_left.y - bottom_right.y } + text_size := cast(Vec2) measure_text_size( current.text.str, style.font, style.font_size, 0 ) + + text_pos : Vec2 + text_pos = top_left + 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 + + computed.text_size = text_size + computed.text_pos = { text_pos.x, -text_pos.y } + } current = ui_box_tranverse_next( current ) } diff --git a/code/ui_widgets.odin b/code/ui_widgets.odin index e30ce78..87d664b 100644 --- a/code/ui_widgets.odin +++ b/code/ui_widgets.odin @@ -1,5 +1,10 @@ package sectr +UI_Widget :: struct { + using box : ^UI_Box, + using signal : UI_Signal, +} + ui_widget :: proc( label : string, flags : UI_BoxFlags ) -> (widget : UI_Widget) { widget.box = ui_box_make( flags, label ) diff --git a/docs/assets/sectr_host_2024-03-09_04-30-27.png b/docs/assets/sectr_host_2024-03-09_04-30-27.png new file mode 100644 index 0000000000000000000000000000000000000000..7db5622316cbd21f0a7a206882d4a012cbefc30c GIT binary patch literal 31300 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