From a8cac05fe1490f1dd72dd44772c4f7f6046a2606 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sun, 8 Aug 2021 23:05:28 -0500 Subject: [PATCH] lots of improvements; fixed ui laying issue --- res/colors_dark.json | 4 +- res/colors_light.json | 4 +- src/app.onyx | 108 ++++++++++++++++++++---------------------- src/build.onyx | 1 - src/debug_log.onyx | 55 +++++++++++++++++---- src/ui/window.onyx | 5 +- 6 files changed, 104 insertions(+), 73 deletions(-) diff --git a/res/colors_dark.json b/res/colors_dark.json index 31095c1..439f912 100644 --- a/res/colors_dark.json +++ b/res/colors_dark.json @@ -10,10 +10,10 @@ "primary": [ 0.051, 0.278, 0.631 ], "primary_light": [ 0.329, 0.451, 0.827 ], "primary_dark": [ 0, 0.129, 0.443 ], - "primary_text": [ 1, 1, 1 ], + "primary_text": [ 1.0, 1.0, 1.0 ], "secondary": [ 0, 0.376, 0.392 ], "secondary_light": [ 0.259, 0.557, 0.573 ], "secondary_dark": [ 0, 0.212, 0.227 ], - "secondary_text": [ 1, 1, 1 ] + "secondary_text": [ 1.0, 1.0, 1.0 ] } diff --git a/res/colors_light.json b/res/colors_light.json index 7a63117..65d9c22 100644 --- a/res/colors_light.json +++ b/res/colors_light.json @@ -10,10 +10,10 @@ "primary": [ 0.051, 0.278, 0.631 ], "primary_light": [ 0.329, 0.451, 0.827 ], "primary_dark": [ 0, 0.129, 0.443 ], - "primary_text": [ 1, 1, 1 ], + "primary_text": [ 1.0, 1.0, 1.0 ], "secondary": [ 0, 0.376, 0.392 ], "secondary_light": [ 0.259, 0.557, 0.573 ], "secondary_dark": [ 0, 0.212, 0.227 ], - "secondary_text": [ 1, 1, 1 ] + "secondary_text": [ 1.0, 1.0, 1.0 ] } diff --git a/src/app.onyx b/src/app.onyx index 3f43d3d..2d18130 100644 --- a/src/app.onyx +++ b/src/app.onyx @@ -8,27 +8,35 @@ use package core #private_file ui :: package ui #private_file config :: package config #private_file wasm :: package wasm_utils +#private_file debug :: package debug use package debug { init as debug_init, debug_log, draw_debug_log } use package core.intrinsics.onyx { __initialize } @Relocate search_buffer: string.String_Buffer; -debug_log_y_offset := 0.0f; -debug_log_y_scroll := 0.0f; -debug_log_y_offset_target := 0.0f; - background_tile_texture : gfx.Texture; on_file_load_callbacks : map.Map(u32, (file_event: ^events.Event) -> void); +// The global application state. +state : Application_State; + Application_State :: struct { - _: i32; + has_active_file := false; + file := Active_File.{}; +} + +Active_File :: struct { + name := (#type [] u8).{ null, 0 }; + data := (#type [] u8).{ null, 0 }; } init :: () { debug_init(); + __initialize(^state); + gl.init("main_canvas"); events.init(); gfx.immediate_renderer_init(); @@ -51,12 +59,15 @@ init :: () { { use type_info; + // Look through all the types in the program for type: type_table { if type.kind != .Struct do continue; ts := cast(^Type_Info_Struct) type; if !string.starts_with(ts.name, "Feature_") do continue; + // Any types that are a structure and start with "Feature_" will be dynamically loaded + debug_log(.Info, "Found feature '{}'", string.advance(ts.name, 8)); for ^member: ts.members { @@ -247,7 +258,7 @@ handle_event :: (event: ^events.Event) { } if event.keyboard->get_name() == "F7" { - debug_log_y_offset_target = 1 - debug_log_y_offset_target; + debug.debug_log_toggle(); break; } @@ -276,17 +287,21 @@ handle_event :: (event: ^events.Event) { } case .FileDropped { - wasm_data := memory.make_slice(u8, event.file.size); - name := memory.make_slice(u8, event.file.name_length, context.temp_allocator); - events.get_requested_file_data(event.file.file_id, wasm_data, name); + data := memory.make_slice(u8, event.file.size); + name := memory.make_slice(u8, event.file.name_length); + events.get_requested_file_data(event.file.file_id, data, name); debug_log(.Info, "File with size {} and name {} was dropped.\n", event.file.size, name); - if !string.ends_with(name, ".wasm") { - debug_log(.Warning, "A non-WASM file was dropped. Ignoring.", null); - break; + if state.has_active_file { + memory.free_slice(^state.file.name); + memory.free_slice(^state.file.data); } + state.has_active_file = true; + state.file.name = name; + state.file.data = data; + // This transfers ownership of wasm_data to the analyzer_state // load_wasm_binary(^analyzer_state, wasm_data); } @@ -294,10 +309,11 @@ handle_event :: (event: ^events.Event) { } needs_redraw :: () -> bool { - return ui.has_active_animation() || debug_log_y_offset != debug_log_y_offset_target; + return ui.has_active_animation() || debug.debug_log_transitioning(); } update :: (dt: f32) { + debug.debug_log_update(dt); } draw :: () { @@ -314,82 +330,60 @@ draw :: () { ui.draw_rect(0, 0, 20, 20, color=.{1,0,0}); + { + #persist window_state := ui.Window_State.{ position=gfx.Vector2.{100, 100}, size=gfx.Vector2.{800, 600} }; + ui.window_start(^window_state); + defer ui.window_end(); + + if state.has_active_file { + buffer: [512] u8; + name_text := conv.str_format("File name: {}", ~~buffer, state.file.name); + ui.draw_text(.{ 0, 0, 300, 200 }, name_text); + + size_text := conv.str_format("File size: {} bytes", ~~buffer, state.file.data.count); + ui.draw_text(.{ 0, 32, 300, 200 }, size_text); + + } else { + ui.draw_text(.{ 0, 0, 300, 200 }, "No file loaded."); + } + } + ui.workspace_end(); // draw_sidebar(^analyzer_state); // Menu bar drawing { - gfx.push_matrix(); - defer gfx.pop_matrix(); + #insert gfx.save_matrix; gfx.identity(); ui.menubar(menu_bar, ^search_buffer, ~~ui.Menu_Bar_Option.[ .{ label = "File" }, .{ label = "Test" }, ]); - //draw_menu_bar(^menu_bar); } // Debug log drawing - { - ui.move_towards(^debug_log_y_offset, debug_log_y_offset_target, 0.07f); - - if debug_log_y_offset > 0.0f { - top_half, _ := ui.Flow.split_horizontal(window_rectangle, top_percent=.5); - height := ui.Rectangle.height(top_half); - top_half.y0 -= height * (1 - debug_log_y_offset); - top_half.y1 -= height * (1 - debug_log_y_offset); - draw_debug_log(top_half, ^debug_log_y_scroll); - } - } + draw_debug_log(window_rectangle); gfx.flush(); ui.end_frame(); - draw_menu_bar :: (menu_bar_: ^ui.Rectangle) { - menu_bar := *menu_bar_; - ui.draw_rect(menu_bar, color=config.Colors.background); - - menu_button_theme := ui.default_button_theme; - menu_button_theme.border_width = 2; - menu_button_theme.font_size = .9; - menu_button_theme.font = 0; - - menu_textbox_theme := ui.default_textbox_theme; - menu_textbox_theme.border_width = 2; - menu_textbox_theme.font_size = .9; - - button_rect : ui.Rectangle; - - button_rect, menu_bar = ui.Flow.split_vertical(menu_bar, left_width=100); - ui.button(button_rect, "File", theme=^menu_button_theme); - button_rect, menu_bar = ui.Flow.split_vertical(menu_bar, left_width=100); - ui.button(button_rect, "Edit", theme=^menu_button_theme); - button_rect, menu_bar = ui.Flow.split_vertical(menu_bar, left_width=100); - ui.button(button_rect, "View", theme=^menu_button_theme); - button_rect, menu_bar = ui.Flow.split_vertical(menu_bar, left_width=100); - ui.button(button_rect, "Help", theme=^menu_button_theme); - - _, search_rect := ui.Flow.split_vertical(menu_bar, right_width=300); - ui.textbox(search_rect, ^search_buffer, "Search", theme=^menu_textbox_theme); - } - draw_background_lines :: (width: f32, height: f32, line_color := gfx.Color4.{0.2, 0.2, 0.2}, line_spacing := 32.0f) { gl :: package gl + #insert gfx.save_matrix; + trans := gfx.global_renderer->get_transform(); sx := trans.scale.x * line_spacing; sy := trans.scale.y * line_spacing; tx := -trans.translation.x / sx; ty := -trans.translation.y / sy; - gfx.push_matrix(); gfx.identity(); gfx.set_texture(^background_tile_texture); gfx.textured_rect(.{ 0, 0 }, .{ width, height }, .{ tx, ty }, .{ width / sx, height / sy }, color=line_color); gfx.set_texture(); - gfx.pop_matrix(); } } diff --git a/src/build.onyx b/src/build.onyx index b39a09d..4cc582d 100644 --- a/src/build.onyx +++ b/src/build.onyx @@ -15,7 +15,6 @@ #load "src/main" #load "src/app" - // #load "src/wasm" #load "src/features/load_features" #load "src/ui/window" diff --git a/src/debug_log.onyx b/src/debug_log.onyx index 7c1978c..c014014 100644 --- a/src/debug_log.onyx +++ b/src/debug_log.onyx @@ -5,6 +5,10 @@ use package core #private_file gfx :: package immediate_mode #private_file config :: package config +#private y_scroll := 0.0f; +#private debug_log_y_offset := 0.0f; +#private debug_log_y_offset_target := 0.0f; + init :: () { log_buffer.line_arena = alloc.arena.make(context.allocator, 4096); log_buffer.lines = array.make(str); @@ -21,6 +25,25 @@ Severity :: enum { minimum_severity := Severity.Debug; +debug_log_toggle :: () { + debug_log_y_offset_target = 1 - debug_log_y_offset; +} + +debug_log_transitioning :: () -> bool { + return debug_log_y_offset != debug_log_y_offset_target; +} + +debug_log_update :: (dt: f32) { + ui.move_towards(^debug_log_y_offset, debug_log_y_offset_target, 4 * dt); +} + +debug_log_clear :: () { + array.clear(^log_buffer.lines); + alloc.arena.free(^log_buffer.line_arena); + + log_buffer.line_arena = alloc.arena.make(context.allocator, 4096); +} + debug_log :: (severity: Severity, format: str, args: ..any) { if severity < minimum_severity do return; @@ -40,22 +63,29 @@ debug_log :: (severity: Severity, format: str, args: ..any) { } } -draw_debug_log :: (r: ui.Rectangle, y_scroll: ^f32 = null, site := #callsite) { +draw_debug_log :: (window_rectangle: ui.Rectangle, site := #callsite) { + if debug_log_y_offset == 0.0f do return; + + r, _ := ui.Flow.split_horizontal(window_rectangle, top_percent=.5); + height := ui.Rectangle.height(r); + r.y0 -= height * (1 - debug_log_y_offset); + r.y1 -= height * (1 - debug_log_y_offset); + hash := ui.get_site_hash(site); mx, my := ui.get_mouse_position(); if ui.Rectangle.contains(r, mx, my) { - ui.set_hot_item(hash); + ui.set_hot_item(hash, false); } line_spacing := 28.0f; - if ui.is_hot_item(hash) && y_scroll != null { - if ui.mouse_state.dwheel > 0 do *y_scroll -= 20.0f; - if ui.mouse_state.dwheel < 0 do *y_scroll += 20.0f; + if ui.is_hot_item(hash) { + if ui.mouse_state.dwheel > 0 do y_scroll -= 20.0f; + if ui.mouse_state.dwheel < 0 do y_scroll += 20.0f; - if ui.is_key_down(38) do *y_scroll -= 20.0f; - if ui.is_key_down(40) do *y_scroll += 20.0f; + if ui.is_key_down(38) do y_scroll -= 20.0f; + if ui.is_key_down(40) do y_scroll += 20.0f; } x, y := ui.Rectangle.bottom_left(r); @@ -69,7 +99,7 @@ draw_debug_log :: (r: ui.Rectangle, y_scroll: ^f32 = null, site := #callsite) { ui.draw_rect(r, color=background_color); scale :: 0.75f; - y_offset := line_spacing * scale + *y_scroll; + y_offset := line_spacing * scale + y_scroll; while i := log_buffer.lines.count - 1; cast(i32) i >= 0 { defer i -= 1; @@ -77,6 +107,15 @@ draw_debug_log :: (r: ui.Rectangle, y_scroll: ^f32 = null, site := #callsite) { ui.draw_text_raw(log_buffer.lines[i], x, y - y_offset, color=.{ 0.2, 0.7, 0.2 }, font=1, size=scale); y_offset += line_spacing * scale; } + + clear_button_rect := ui.Rectangle.{ + x0 = r.x0, x1 = r.x0 + 200, + y0 = r.y0, y1 = r.y0 + 50, + }; + + if ui.button(clear_button_rect, "Clear log") { + debug_log_clear(); + } } #private_file log_buffer : struct { diff --git a/src/ui/window.onyx b/src/ui/window.onyx index 7e76953..db54a63 100644 --- a/src/ui/window.onyx +++ b/src/ui/window.onyx @@ -23,12 +23,11 @@ window_start :: (use state: ^Window_State, site := #callsite, increment := 0) { animation_state := map.get(^animation_states, hash); mx, my := get_mouse_position(); - contained := false; if state->get_rectangle() |> Rectangle.contains(mx, my) { - contained = true; + set_hot_item(hash); } - if contained { + if is_hot_item(hash) { move_towards(^animation_state.hover_time, 1.0f, 0.06); } else { move_towards(^animation_state.hover_time, 0.0f, 0.06); -- 2.25.1