"primary": [ 0.051, 0.278, 0.631 ],
"primary_light": [ 0.329, 0.451, 0.827 ],
"primary_dark": [ 0, 0.129, 0.443 ],
- "primary_text": [ 0, 0, 0 ],
+ "primary_text": [ 1, 1, 1 ],
"secondary": [ 0, 0.376, 0.392 ],
"secondary_light": [ 0.259, 0.557, 0.573 ],
"secondary_dark": [ 0, 0.212, 0.227 ],
- "secondary_text": [ 0, 0, 0 ]
+ "secondary_text": [ 1, 1, 1 ]
}
on_file_load_callbacks : map.Map(u32, (file_event: ^events.Event) -> void);
-analyzer_state : Wasm_Analyzer_State;
+Application_State :: struct {
+ _: i32;
+}
init :: () {
debug_init();
gl.enable(gl.BLEND);
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- __initialize(^analyzer_state);
+ {
+ use type_info;
+
+ 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;
+
+ debug_log(.Info, "Found feature '{}'", string.advance(ts.name, 8));
+
+ for ^member: ts.members {
+ Hook_Function_Type :: #type (^Application_State) -> void;
+
+ if member.name == "setup" {
+ assert(member.type == Hook_Function_Type, "setup has the wrong type.");
+ assert(member.default != null, "setup has no default function.");
+
+ (*(cast(^Hook_Function_Type) member.default))(null);
+ }
+
+ if member.name == "work" {
+ assert(member.type == Hook_Function_Type, "work has the wrong type.");
+ assert(member.default != null, "work has no default function.");
+
+ (*(cast(^Hook_Function_Type) member.default))(null);
+ }
+ }
+ }
+ }
load_background_tile_texture :: () {
background_tile_texture = gfx.load_texture(32, 32, #file_contents "res/images/background_tile.data", gl.RGB, gl.RGB);
config.Colors.secondary_dark = decode_color(colors.root["secondary_dark"]);
config.Colors.secondary_text = decode_color(colors.root["secondary_text"]);
+ update_ui_colors();
+
decode_color :: (v: ^json.Value) -> gfx.Color4 {
return .{
r = ~~v[0]->as_float(),
}
if event.keyboard->get_name() == "Tab" {
- toggle_sidebar(^analyzer_state);
+ // toggle_sidebar(^analyzer_state);
break;
}
}
// This transfers ownership of wasm_data to the analyzer_state
- load_wasm_binary(^analyzer_state, wasm_data);
+ // load_wasm_binary(^analyzer_state, wasm_data);
}
}
}
ui.workspace_end();
- draw_sidebar(^analyzer_state);
+ // draw_sidebar(^analyzer_state);
// Menu bar drawing
{
defer gfx.pop_matrix();
gfx.identity();
- draw_menu_bar(^menu_bar);
+ ui.menubar(menu_bar, ^search_buffer, ~~ui.Menu_Bar_Option.[
+ .{ label = "File" },
+ .{ label = "Test" },
+ ]);
+ //draw_menu_bar(^menu_bar);
}
// Debug log drawing
}
#private_file background_tile_texture : gfx.Texture;
+
+
+update_ui_colors :: () {
+ ui.default_text_theme.text_color = config.Colors.foreground;
+
+ ui.default_button_theme.text_color = config.Colors.primary_text;
+ ui.default_button_theme.background_color = config.Colors.primary_dark;
+ ui.default_button_theme.hover_color = config.Colors.primary;
+ ui.default_button_theme.click_color = config.Colors.primary_light;
+ ui.default_button_theme.border_color = config.Colors.primary;
+
+ ui.default_textbox_theme.text_color = config.Colors.primary_text;
+ ui.default_textbox_theme.background_color = config.Colors.primary_dark;
+ ui.default_textbox_theme.hover_color = config.Colors.primary;
+ ui.default_textbox_theme.click_color = config.Colors.primary_light;
+ ui.default_textbox_theme.border_color = config.Colors.primary;
+}
#load "src/main"
#load "src/app"
- #load "src/wasm"
+ // #load "src/wasm"
+ #load "src/features/load_features"
#load "src/ui/window"
+ #load "src/ui/menubar"
#load "src/debug_log"
}
use package immediate_mode { Color4 }
-color_scheme_file :: "/res/colors_dark.json"
+color_scheme_file :: "/res/colors_light.json"
Colors : struct {
dark_background : Color4;
use package core
#private_file ui :: package ui
#private_file gfx :: package immediate_mode
+#private_file config :: package config
init :: () {
log_buffer.line_arena = alloc.arena.make(context.allocator, 4096);
gfx.push_scissor(x, y - h, w, h);
defer gfx.pop_scissor();
- ui.draw_rect(r, color=.{0,0,0,0.8});
+ background_color := config.Colors.background;
+ background_color.a = 0.8;
+ ui.draw_rect(r, color=background_color);
- scale :: 1f;
+ scale :: 0.75f;
y_offset := line_spacing * scale + *y_scroll;
while i := log_buffer.lines.count - 1; cast(i32) i >= 0 {
defer i -= 1;
- ui.draw_text_raw(log_buffer.lines[i], x, y - y_offset, color=.{ 0.2, 1.0, 0.2 }, font=1, size=scale);
+ 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;
}
}
--- /dev/null
+
+// Add #load statements for the features
+
+#load "./wasm/feature"
\ No newline at end of file
--- /dev/null
+package feature_wasm
+
+#load "./wasm"
+
+Feature_Wasm_Loader :: struct {
+ setup := setup;
+}
\ No newline at end of file
--- /dev/null
+package feature_wasm
+
+use package app { Application_State }
+use package debug { debug_log }
+
+setup :: (use app: ^Application_State) {
+ debug_log(.Info, "Wasm Loader Loaded from {}", #file);
+}
\ No newline at end of file
--- /dev/null
+// This is not a portable file. It is heavily tied to this project.
+
+package ui
+
+#private_file iter :: package core.iter
+#private_file config :: package config
+use package core.string
+
+Menu_Bar_Option :: struct {
+ label : str;
+ action : () -> void = null_proc;
+ options : [] Menu_Bar_Option = .{ null, 0 };
+}
+
+menubar :: (r: Rectangle, @Temporary search_buffer: ^String_Buffer, options: [] Menu_Bar_Option, site := #callsite, increment := 0) {
+ menu_rect := r;
+ draw_rect(menu_rect, color=config.Colors.background);
+
+ menu_button_theme := default_button_theme;
+ menu_button_theme.border_width = 2;
+ menu_button_theme.font_size = .9;
+ menu_button_theme.font = 0;
+
+ menu_textbox_theme := default_textbox_theme;
+ menu_textbox_theme.border_width = 2;
+ menu_textbox_theme.font_size = .9;
+
+ button_rect : Rectangle;
+
+ for option: iter.enumerate(iter.from_array(options)) {
+ button_rect, menu_rect = Flow.split_vertical(menu_rect, left_width=100);
+ button(button_rect, option.value.label, theme=^menu_button_theme, increment=option.index);
+ }
+
+ _, search_rect := Flow.split_vertical(menu_rect, right_width=300);
+ textbox(search_rect, search_buffer, "Search", theme=^menu_textbox_theme);
+}
if sidebar_expansion <= 0.0f do return;
window_width, window_height := gfx.get_window_size();
- sidebar_window.position = .{ (sidebar_expansion - 1) * sidebar_window.size.x, y_offset };
+ sidebar_window.position = .{ (sidebar_expansion - 1) * sidebar_window.size.x, y_offset };
sidebar_window.size.y = ~~window_height - y_offset;
sidebar_window.active_color = config.Colors.background;
sidebar_window.background_color = config.Colors.dark_background;