Zig UI demo
This commit is contained in:
		
							parent
							
								
									47cba86c03
								
							
						
					
					
						commit
						fd308f9a3a
					
				| 
						 | 
					@ -73,6 +73,12 @@ ORCA_EXPORT void oc_on_raw_event(oc_event* event)
 | 
				
			||||||
    oc_ui_process_event(event);
 | 
					    oc_ui_process_event(event);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ORCA_EXPORT void oc_on_resize(u32 width, u32 height)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    frameSize.x = width;
 | 
				
			||||||
 | 
					    frameSize.y = height;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void log_push(const char* line)
 | 
					void log_push(const char* line)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_str8_list_push(&logArena, &logLines, (oc_str8)OC_STR8(line));
 | 
					    oc_str8_list_push(&logArena, &logLines, (oc_str8)OC_STR8(line));
 | 
				
			||||||
| 
						 | 
					@ -158,12 +164,6 @@ void labeled_slider(const char* label, f32* value)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ORCA_EXPORT void oc_on_resize(u32 width, u32 height)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    frameSize.x = width;
 | 
					 | 
				
			||||||
    frameSize.y = height;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void reset_next_radio_group_to_dark_theme(oc_arena* arena);
 | 
					void reset_next_radio_group_to_dark_theme(oc_arena* arena);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ORCA_EXPORT void oc_on_frame_refresh(void)
 | 
					ORCA_EXPORT void oc_on_frame_refresh(void)
 | 
				
			||||||
| 
						 | 
					@ -330,7 +330,7 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
 | 
				
			||||||
                            radioSelected = result.selectedIndex;
 | 
					                            radioSelected = result.selectedIndex;
 | 
				
			||||||
                            if(result.changed)
 | 
					                            if(result.changed)
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                log_pushf("Selected Radio %i", result.selectedIndex + 1);
 | 
					                                log_pushf("Selected %s", options[result.selectedIndex].ptr);
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            //-----------------------------------------------------------------------------
 | 
					                            //-----------------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					@ -359,13 +359,13 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
 | 
				
			||||||
                                                     .size.height = { OC_UI_SIZE_TEXT } },
 | 
					                                                     .size.height = { OC_UI_SIZE_TEXT } },
 | 
				
			||||||
                                     OC_UI_STYLE_SIZE);
 | 
					                                     OC_UI_STYLE_SIZE);
 | 
				
			||||||
                    static oc_str8 text = OC_STR8_LIT("Text box");
 | 
					                    static oc_str8 text = OC_STR8_LIT("Text box");
 | 
				
			||||||
                    oc_ui_text_box_result res = oc_ui_text_box("text", scratch.arena, text);
 | 
					                    oc_ui_text_box_result result = oc_ui_text_box("text", scratch.arena, text);
 | 
				
			||||||
                    if(res.changed)
 | 
					                    if(result.changed)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        oc_arena_clear(&textArena);
 | 
					                        oc_arena_clear(&textArena);
 | 
				
			||||||
                        text = oc_str8_push_copy(&textArena, res.text);
 | 
					                        text = oc_str8_push_copy(&textArena, result.text);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if(res.accepted)
 | 
					                    if(result.accepted)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        log_pushf("Entered text \"%s\"", text.ptr);
 | 
					                        log_pushf("Entered text \"%s\"", text.ptr);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
| 
						 | 
					@ -465,7 +465,7 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
 | 
					                    oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
 | 
				
			||||||
                                                     .size.height = { OC_UI_SIZE_PIXELS, 152 },
 | 
					                                                     .size.height = { OC_UI_SIZE_PIXELS, 152 },
 | 
				
			||||||
                                                     .layout.margin.x = 320,
 | 
					                                                     .layout.margin.x = 310,
 | 
				
			||||||
                                                     .layout.margin.y = 16,
 | 
					                                                     .layout.margin.y = 16,
 | 
				
			||||||
                                                     .bgColor = OC_UI_DARK_THEME.bg0,
 | 
					                                                     .bgColor = OC_UI_DARK_THEME.bg0,
 | 
				
			||||||
                                                     .roundness = OC_UI_DARK_THEME.roundnessSmall },
 | 
					                                                     .roundness = OC_UI_DARK_THEME.roundnessSmall },
 | 
				
			||||||
| 
						 | 
					@ -527,8 +527,8 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
 | 
				
			||||||
                                                    | OC_UI_STYLE_BG_COLOR
 | 
					                                                    | OC_UI_STYLE_BG_COLOR
 | 
				
			||||||
                                                    | OC_UI_STYLE_ROUNDNESS);
 | 
					                                                    | OC_UI_STYLE_ROUNDNESS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        oc_ui_pattern labelPattern = { 0 };
 | 
					 | 
				
			||||||
                        oc_ui_tag labelTag = oc_ui_tag_make("label");
 | 
					                        oc_ui_tag labelTag = oc_ui_tag_make("label");
 | 
				
			||||||
 | 
					                        oc_ui_pattern labelPattern = { 0 };
 | 
				
			||||||
                        oc_ui_pattern_push(scratch.arena, &labelPattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = labelTag });
 | 
					                        oc_ui_pattern_push(scratch.arena, &labelPattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = labelTag });
 | 
				
			||||||
                        oc_ui_style_match_after(labelPattern,
 | 
					                        oc_ui_style_match_after(labelPattern,
 | 
				
			||||||
                                                &(oc_ui_style){ .color = labelFontColor,
 | 
					                                                &(oc_ui_style){ .color = labelFontColor,
 | 
				
			||||||
| 
						 | 
					@ -818,32 +818,32 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
 | 
				
			||||||
// You won't need it in a real program as long as your colors come from ui.theme or ui.theme->palette
 | 
					// You won't need it in a real program as long as your colors come from ui.theme or ui.theme->palette
 | 
				
			||||||
void reset_next_radio_group_to_dark_theme(oc_arena* arena)
 | 
					void reset_next_radio_group_to_dark_theme(oc_arena* arena)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_tag defaultTag = oc_ui_tag_make("radio");
 | 
					    oc_ui_tag unselectedTag = oc_ui_tag_make("radio");
 | 
				
			||||||
    oc_ui_pattern defaultPattern = { 0 };
 | 
					    oc_ui_pattern unselectedPattern = { 0 };
 | 
				
			||||||
    oc_ui_pattern_push(arena, &defaultPattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = defaultTag });
 | 
					    oc_ui_pattern_push(arena, &unselectedPattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = unselectedTag });
 | 
				
			||||||
    oc_ui_style defaultStyle = { .borderColor = OC_UI_DARK_THEME.text3,
 | 
					    oc_ui_style unselectedStyle = { .borderColor = OC_UI_DARK_THEME.text3,
 | 
				
			||||||
                                    .borderSize = 1 };
 | 
					                                    .borderSize = 1 };
 | 
				
			||||||
    oc_ui_style_mask defaultMask = OC_UI_STYLE_BORDER_COLOR
 | 
					    oc_ui_style_mask unselectedMask = OC_UI_STYLE_BORDER_COLOR
 | 
				
			||||||
                                    | OC_UI_STYLE_BORDER_SIZE;
 | 
					                                    | OC_UI_STYLE_BORDER_SIZE;
 | 
				
			||||||
    oc_ui_style_match_after(defaultPattern, &defaultStyle, defaultMask);
 | 
					    oc_ui_style_match_after(unselectedPattern, &unselectedStyle, unselectedMask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oc_ui_pattern hoverPattern = { 0 };
 | 
					    oc_ui_pattern unselectedHoverPattern = { 0 };
 | 
				
			||||||
    oc_ui_pattern_push(arena, &hoverPattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = defaultTag });
 | 
					    oc_ui_pattern_push(arena, &unselectedHoverPattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = unselectedTag });
 | 
				
			||||||
    oc_ui_pattern_push(arena, &hoverPattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER });
 | 
					    oc_ui_pattern_push(arena, &unselectedHoverPattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER });
 | 
				
			||||||
    oc_ui_style hoverStyle = { .bgColor = OC_UI_DARK_THEME.fill0,
 | 
					    oc_ui_style hoverStyle = { .bgColor = OC_UI_DARK_THEME.fill0,
 | 
				
			||||||
                               .borderColor = OC_UI_DARK_THEME.primary };
 | 
					                               .borderColor = OC_UI_DARK_THEME.primary };
 | 
				
			||||||
    oc_ui_style_mask hoverMask = OC_UI_STYLE_BG_COLOR
 | 
					    oc_ui_style_mask hoverMask = OC_UI_STYLE_BG_COLOR
 | 
				
			||||||
                               | OC_UI_STYLE_BORDER_COLOR;
 | 
					                               | OC_UI_STYLE_BORDER_COLOR;
 | 
				
			||||||
    oc_ui_style_match_after(hoverPattern, &hoverStyle, hoverMask);
 | 
					    oc_ui_style_match_after(unselectedHoverPattern, &hoverStyle, hoverMask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oc_ui_pattern activePattern = { 0 };
 | 
					    oc_ui_pattern unselectedActivePattern = { 0 };
 | 
				
			||||||
    oc_ui_pattern_push(arena, &activePattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = defaultTag });
 | 
					    oc_ui_pattern_push(arena, &unselectedActivePattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = unselectedTag });
 | 
				
			||||||
    oc_ui_pattern_push(arena, &activePattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE });
 | 
					    oc_ui_pattern_push(arena, &unselectedActivePattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE });
 | 
				
			||||||
    oc_ui_style activeStyle = { .bgColor = OC_UI_DARK_THEME.fill1,
 | 
					    oc_ui_style activeStyle = { .bgColor = OC_UI_DARK_THEME.fill1,
 | 
				
			||||||
                                .borderColor = OC_UI_DARK_THEME.primary };
 | 
					                                .borderColor = OC_UI_DARK_THEME.primary };
 | 
				
			||||||
    oc_ui_style_mask activeMask = OC_UI_STYLE_BG_COLOR
 | 
					    oc_ui_style_mask activeMask = OC_UI_STYLE_BG_COLOR
 | 
				
			||||||
                                | OC_UI_STYLE_BORDER_COLOR;
 | 
					                                | OC_UI_STYLE_BORDER_COLOR;
 | 
				
			||||||
    oc_ui_style_match_after(activePattern, &activeStyle, activeMask);
 | 
					    oc_ui_style_match_after(unselectedActivePattern, &activeStyle, activeMask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oc_ui_tag selectedTag = oc_ui_tag_make("radio_selected");
 | 
					    oc_ui_tag selectedTag = oc_ui_tag_make("radio_selected");
 | 
				
			||||||
    oc_ui_pattern selectedPattern = { 0 };
 | 
					    oc_ui_pattern selectedPattern = { 0 };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,5 @@ These two commands build the runtime - the native host executable - and the samp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Warning
 | 
					### Warning
 | 
				
			||||||
Zig bindings for Orca are in-progress and experimental. You may encounter bugs since not all the bound APIs have been tested extensively - this sample is currently the only code doing so! Additionally, not all APIs have zig coverage yet, notably:
 | 
					Zig bindings for Orca are in-progress and experimental. You may encounter bugs since not all the bound APIs have been tested extensively - this sample is currently the only code doing so! Additionally, not all APIs have zig coverage yet, notably:
 | 
				
			||||||
* `oc_ui`
 | 
					 | 
				
			||||||
* `gles`
 | 
					* `gles`
 | 
				
			||||||
As more APIs get tested, there is a possibility of breaking changes. Please report any bugs you find on the Handmade discord in the #orca channel.
 | 
					As more APIs get tested, there is a possibility of breaking changes. Please report any bugs you find on the Handmade discord in the #orca channel.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -205,7 +205,7 @@ export fn oc_on_frame_refresh() void {
 | 
				
			||||||
        const text_rect = text_metrics.ink;
 | 
					        const text_rect = text_metrics.ink;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const center_x = frame_size.x / 2;
 | 
					        const center_x = frame_size.x / 2;
 | 
				
			||||||
        const text_begin_x = center_x - text_rect.Flat.w / 2;
 | 
					        const text_begin_x = center_x - text_rect.w / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Mat2x3.push(Mat2x3.translate(text_begin_x, 100));
 | 
					        Mat2x3.push(Mat2x3.translate(text_begin_x, 100));
 | 
				
			||||||
        defer Mat2x3.pop();
 | 
					        defer Mat2x3.pop();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					UI
 | 
				
			||||||
 | 
					zig-out
 | 
				
			||||||
 | 
					zig-cache
 | 
				
			||||||
 | 
					liborca.a
 | 
				
			||||||
 | 
					profile.dtrace
 | 
				
			||||||
 | 
					profile.spall
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					### Build and run
 | 
				
			||||||
 | 
					Zig version `0.11.0` or greater is required for this sample. To build and run:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					orca dev build-runtime
 | 
				
			||||||
 | 
					zig build run
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					These two commands build the runtime - the native host executable - and the sample as a loadable wasm library, then runs it. To only build the sample without running it, use `zig build bundle`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Warning
 | 
				
			||||||
 | 
					Zig bindings for Orca are in-progress and experimental. You may encounter bugs since not all the bound APIs have been tested extensively - this sample is currently the only code doing so! Additionally, not all APIs have zig coverage yet, notably:
 | 
				
			||||||
 | 
					* `gles`
 | 
				
			||||||
 | 
					As more APIs get tested, there is a possibility of breaking changes. Please report any bugs you find on the Handmade discord in the #orca channel.
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,107 @@
 | 
				
			||||||
 | 
					const std = @import("std");
 | 
				
			||||||
 | 
					const builtin = @import("builtin");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn addSourceString(str: []const u8, strings: *std.ArrayList(u8), sources: *std.ArrayList([]const u8)) !void {
 | 
				
			||||||
 | 
					    var begin = strings.items.len;
 | 
				
			||||||
 | 
					    try strings.appendSlice(str);
 | 
				
			||||||
 | 
					    var realstring = strings.items[begin..];
 | 
				
			||||||
 | 
					    try sources.append(realstring);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn build(b: *std.Build) !void {
 | 
				
			||||||
 | 
					    const optimize = b.standardOptimizeOption(.{});
 | 
				
			||||||
 | 
					    var wasm_target = std.zig.CrossTarget{
 | 
				
			||||||
 | 
					        .cpu_arch = .wasm32,
 | 
				
			||||||
 | 
					        .os_tag = .freestanding,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    wasm_target.cpu_features_add.addFeature(@intFromEnum(std.Target.wasm.Feature.bulk_memory));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var orca_source_strings = try std.ArrayList(u8).initCapacity(b.allocator, 1024 * 4);
 | 
				
			||||||
 | 
					    var orca_sources = try std.ArrayList([]const u8).initCapacity(b.allocator, 128);
 | 
				
			||||||
 | 
					    defer orca_source_strings.deinit();
 | 
				
			||||||
 | 
					    defer orca_sources.deinit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try addSourceString("../../src/orca.c", &orca_source_strings, &orca_sources);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var libc_shim_dir = try std.fs.cwd().openIterableDir("../../src/libc-shim/src", .{});
 | 
				
			||||||
 | 
					        var walker = try libc_shim_dir.walk(b.allocator);
 | 
				
			||||||
 | 
					        defer walker.deinit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while (try walker.next()) |entry| {
 | 
				
			||||||
 | 
					            const extension = std.fs.path.extension(entry.path);
 | 
				
			||||||
 | 
					            if (std.mem.eql(u8, extension, ".c")) {
 | 
				
			||||||
 | 
					                var path_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
 | 
				
			||||||
 | 
					                var abs_path = try libc_shim_dir.dir.realpath(entry.path, &path_buffer);
 | 
				
			||||||
 | 
					                try addSourceString(abs_path, &orca_source_strings, &orca_sources);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const orca_compile_opts = [_][]const u8{
 | 
				
			||||||
 | 
					        "-D__ORCA__",
 | 
				
			||||||
 | 
					        "--no-standard-libraries",
 | 
				
			||||||
 | 
					        "-fno-builtin",
 | 
				
			||||||
 | 
					        "-g",
 | 
				
			||||||
 | 
					        "-O2",
 | 
				
			||||||
 | 
					        "-mexec-model=reactor",
 | 
				
			||||||
 | 
					        "-fno-sanitize=undefined",
 | 
				
			||||||
 | 
					        "-isystem ../../src/libc-shim/include",
 | 
				
			||||||
 | 
					        "-I../../src",
 | 
				
			||||||
 | 
					        "-I../../src/ext",
 | 
				
			||||||
 | 
					        "-Wl,--export-dynamic",
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var orca_lib = b.addStaticLibrary(.{
 | 
				
			||||||
 | 
					        .name = "orca",
 | 
				
			||||||
 | 
					        .target = wasm_target,
 | 
				
			||||||
 | 
					        .optimize = optimize,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    orca_lib.rdynamic = true;
 | 
				
			||||||
 | 
					    orca_lib.addIncludePath(.{ .path = "../../src" });
 | 
				
			||||||
 | 
					    orca_lib.addIncludePath(.{ .path = "../../src/libc-shim/include" });
 | 
				
			||||||
 | 
					    orca_lib.addIncludePath(.{ .path = "../../src/ext" });
 | 
				
			||||||
 | 
					    orca_lib.addCSourceFiles(orca_sources.items, &orca_compile_opts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // builds the wasm module out of the orca C sources and main.zig
 | 
				
			||||||
 | 
					    const orca_module: *std.Build.Module = b.createModule(.{
 | 
				
			||||||
 | 
					        .source_file = .{ .path = "../../src/orca.zig" },
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    const wasm_lib = b.addSharedLibrary(.{
 | 
				
			||||||
 | 
					        .name = "module",
 | 
				
			||||||
 | 
					        .root_source_file = .{ .path = "src/main.zig" },
 | 
				
			||||||
 | 
					        .target = wasm_target,
 | 
				
			||||||
 | 
					        .optimize = optimize,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    wasm_lib.rdynamic = true;
 | 
				
			||||||
 | 
					    wasm_lib.addIncludePath(.{ .path = "../../src" });
 | 
				
			||||||
 | 
					    wasm_lib.addIncludePath(.{ .path = "../../src/libc-shim/include" });
 | 
				
			||||||
 | 
					    wasm_lib.addIncludePath(.{ .path = "../../ext" });
 | 
				
			||||||
 | 
					    wasm_lib.addModule("orca", orca_module);
 | 
				
			||||||
 | 
					    wasm_lib.linkLibrary(orca_lib);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // copies the wasm module into zig-out/wasm_lib
 | 
				
			||||||
 | 
					    b.installArtifact(wasm_lib);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Runs the orca build command
 | 
				
			||||||
 | 
					    const bundle_cmd_str = [_][]const u8{ "orca", "bundle", "--orca-dir", "../..", "--name", "UI", "--resource-dir", "data", "zig-out/lib/module.wasm" };
 | 
				
			||||||
 | 
					    var bundle_cmd = b.addSystemCommand(&bundle_cmd_str);
 | 
				
			||||||
 | 
					    bundle_cmd.step.dependOn(b.getInstallStep());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const bundle_step = b.step("bundle", "Runs the orca toolchain to bundle the wasm module into an orca app.");
 | 
				
			||||||
 | 
					    bundle_step.dependOn(&bundle_cmd.step);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Runs the app
 | 
				
			||||||
 | 
					    const run_cmd_windows = [_][]const u8{"UI/bin/UI.exe"};
 | 
				
			||||||
 | 
					    const run_cmd_macos = [_][]const u8{ "open", "UI.app" };
 | 
				
			||||||
 | 
					    const run_cmd_str: []const []const u8 = switch (builtin.os.tag) {
 | 
				
			||||||
 | 
					        .windows => &run_cmd_windows,
 | 
				
			||||||
 | 
					        .macos => &run_cmd_macos,
 | 
				
			||||||
 | 
					        else => @compileError("unsupported platform"),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    var run_cmd = b.addSystemCommand(run_cmd_str);
 | 
				
			||||||
 | 
					    run_cmd.step.dependOn(&bundle_cmd.step);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const run_step = b.step("run", "Runs the bundled app using the Orca runtime.");
 | 
				
			||||||
 | 
					    run_step.dependOn(&run_cmd.step);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -0,0 +1,870 @@
 | 
				
			||||||
 | 
					const std = @import("std");
 | 
				
			||||||
 | 
					const oc = @import("orca");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var frame_size: oc.Vec2 = .{ .x = 1200, .y = 838 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var surface: oc.Surface = undefined;
 | 
				
			||||||
 | 
					var canvas: oc.Canvas = undefined;
 | 
				
			||||||
 | 
					var font_regular: oc.Font = undefined;
 | 
				
			||||||
 | 
					var font_bold: oc.Font = undefined;
 | 
				
			||||||
 | 
					var ui: oc.UiContext = undefined;
 | 
				
			||||||
 | 
					var text_arena: oc.Arena = undefined;
 | 
				
			||||||
 | 
					var log_arena: oc.Arena = undefined;
 | 
				
			||||||
 | 
					var log_lines: oc.Str8List = undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Cmd = enum {
 | 
				
			||||||
 | 
					    None,
 | 
				
			||||||
 | 
					    SetDarkTheme,
 | 
				
			||||||
 | 
					    SetLightTheme,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					var cmd: Cmd = .None;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export fn oc_on_init() void {
 | 
				
			||||||
 | 
					    oc.windowSetTitle("Orca Zig UI Demo");
 | 
				
			||||||
 | 
					    oc.windowSetSize(frame_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    surface = oc.Surface.canvas();
 | 
				
			||||||
 | 
					    canvas = oc.Canvas.create();
 | 
				
			||||||
 | 
					    ui.init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var fonts = [_]*oc.Font{ &font_regular, &font_bold };
 | 
				
			||||||
 | 
					    var font_names = [_][]const u8{ "/OpenSans-Regular.ttf", "/OpenSans-Bold.ttf" };
 | 
				
			||||||
 | 
					    for (fonts, font_names) |font, name| {
 | 
				
			||||||
 | 
					        var scratch = oc.Arena.scratchBegin();
 | 
				
			||||||
 | 
					        defer scratch.end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var file = oc.File.open(oc.Str8.fromSlice(name), .{ .read = true }, .{});
 | 
				
			||||||
 | 
					        if (file.lastError() != oc.io.Error.Ok) {
 | 
				
			||||||
 | 
					            oc.log.err("Couldn't open file {s}", .{name}, @src());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var size = file.getSize();
 | 
				
			||||||
 | 
					        var buffer = scratch.arena.push(size) catch {
 | 
				
			||||||
 | 
					            oc.log.err("Out of memory", .{}, @src());
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        _ = file.read(size, buffer);
 | 
				
			||||||
 | 
					        file.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var ranges = oc.UnicodeRange.range(&[_]oc.UnicodeRange.Enum{
 | 
				
			||||||
 | 
					            .BasicLatin,
 | 
				
			||||||
 | 
					            .C1ControlsAndLatin1Supplement,
 | 
				
			||||||
 | 
					            .LatinExtendedA,
 | 
				
			||||||
 | 
					            .LatinExtendedB,
 | 
				
			||||||
 | 
					            .Specials,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        font.* = oc.Font.createFromMemory(buffer[0..size], &ranges);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    text_arena = oc.Arena.init();
 | 
				
			||||||
 | 
					    log_arena = oc.Arena.init();
 | 
				
			||||||
 | 
					    log_lines = oc.Str8List.init();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export fn oc_on_raw_event(event: *oc.CEvent) void {
 | 
				
			||||||
 | 
					    oc.uiProcessCEvent(event);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export fn oc_on_resize(width: u32, height: u32) void {
 | 
				
			||||||
 | 
					    frame_size.x = @floatFromInt(width);
 | 
				
			||||||
 | 
					    frame_size.y = @floatFromInt(height);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export fn oc_on_frame_refresh() void {
 | 
				
			||||||
 | 
					    var scratch = oc.Arena.scratchBegin();
 | 
				
			||||||
 | 
					    defer scratch.end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (cmd) {
 | 
				
			||||||
 | 
					        .SetDarkTheme => oc.uiSetTheme(oc.ui_dark_theme),
 | 
				
			||||||
 | 
					        .SetLightTheme => oc.uiSetTheme(oc.ui_light_theme),
 | 
				
			||||||
 | 
					        .None => {},
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    cmd = .None;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var default_style = oc.UiStyle{ .font = font_regular };
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        oc.uiBeginFrame(frame_size, &default_style);
 | 
				
			||||||
 | 
					        defer oc.uiEndFrame();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //--------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					        // Menu bar
 | 
				
			||||||
 | 
					        //--------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            oc.uiMenuBarBegin("menu_bar");
 | 
				
			||||||
 | 
					            defer oc.uiMenuBarEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiMenuBegin("File");
 | 
				
			||||||
 | 
					                defer oc.uiMenuEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (oc.uiMenuButton("Quit").pressed) {
 | 
				
			||||||
 | 
					                    oc.requestQuit();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiMenuBegin("Theme");
 | 
				
			||||||
 | 
					                defer oc.uiMenuEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (oc.uiMenuButton("Dark theme").pressed) {
 | 
				
			||||||
 | 
					                    cmd = .SetDarkTheme;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (oc.uiMenuButton("Light theme").pressed) {
 | 
				
			||||||
 | 
					                    cmd = .SetLightTheme;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            oc.uiPanelBegin("main panel", .{});
 | 
				
			||||||
 | 
					            defer oc.uiPanelEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					                    .size = .{
 | 
				
			||||||
 | 
					                        .width = .fill_parent,
 | 
				
			||||||
 | 
					                        .height = .{ .custom = .{ .kind = .Parent, .value = 1, .relax = 1 } },
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    .layout = .{
 | 
				
			||||||
 | 
					                        .axis = .X,
 | 
				
			||||||
 | 
					                        .margin = .{ .x = 16, .y = 16 },
 | 
				
			||||||
 | 
					                        .spacing = 16,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin("Background", .{ .draw_background = true });
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                widgets(scratch.arena);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                styling(scratch.arena);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _ = canvas.select();
 | 
				
			||||||
 | 
					    surface.select();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    oc.Canvas.setColor(ui.theme.bg0);
 | 
				
			||||||
 | 
					    oc.Canvas.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    oc.uiDraw();
 | 
				
			||||||
 | 
					    canvas.render();
 | 
				
			||||||
 | 
					    surface.present();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var checkbox_checked: bool = false;
 | 
				
			||||||
 | 
					var v_slider_value: f32 = 0;
 | 
				
			||||||
 | 
					var v_slider_logged_value: f32 = 0;
 | 
				
			||||||
 | 
					var v_slider_log_time: f64 = 0;
 | 
				
			||||||
 | 
					var radio_selected: usize = 0;
 | 
				
			||||||
 | 
					var h_slider_value: f32 = 0;
 | 
				
			||||||
 | 
					var h_slider_logged_value: f32 = 0;
 | 
				
			||||||
 | 
					var h_slider_log_time: f64 = 0;
 | 
				
			||||||
 | 
					var text: []const u8 = "Text box";
 | 
				
			||||||
 | 
					var selected: ?usize = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn widgets(arena: *oc.Arena) void {
 | 
				
			||||||
 | 
					    columnBegin("Widgets", 1.0 / 3.0);
 | 
				
			||||||
 | 
					    defer columnEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					            .size = .{
 | 
				
			||||||
 | 
					                .width = .fill_parent,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            .layout = .{
 | 
				
			||||||
 | 
					                .axis = .X,
 | 
				
			||||||
 | 
					                .spacing = 32,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        _ = oc.uiBoxBegin("top", .{});
 | 
				
			||||||
 | 
					        defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					                .layout = .{
 | 
				
			||||||
 | 
					                    .axis = .Y,
 | 
				
			||||||
 | 
					                    .spacing = 24,
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            _ = oc.uiBoxBegin("top_left", .{});
 | 
				
			||||||
 | 
					            defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					            // Label
 | 
				
			||||||
 | 
					            //-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					            _ = oc.uiLabel("Label");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					            // Button
 | 
				
			||||||
 | 
					            //-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					            if (oc.uiButton("Button").clicked) {
 | 
				
			||||||
 | 
					                logPush("Button clicked");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					                    .layout = .{
 | 
				
			||||||
 | 
					                        .axis = .X,
 | 
				
			||||||
 | 
					                        .alignment = .{ .y = .Center },
 | 
				
			||||||
 | 
					                        .spacing = 8,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin("checkbox", .{});
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //-------------------------------------------------------------------------
 | 
				
			||||||
 | 
					                // Checkbox
 | 
				
			||||||
 | 
					                //-------------------------------------------------------------------------
 | 
				
			||||||
 | 
					                if (oc.uiCheckbox("checkbox", &checkbox_checked).clicked) {
 | 
				
			||||||
 | 
					                    if (checkbox_checked) {
 | 
				
			||||||
 | 
					                        logPush("Checkbox checked");
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        logPush("Checkbox unhecked");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _ = oc.uiLabel("Checkbox");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //---------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					        // Vertical slider
 | 
				
			||||||
 | 
					        //---------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					        oc.uiStyleNext(.{ .size = .{ .height = .{ .pixels = 130 } } });
 | 
				
			||||||
 | 
					        _ = oc.uiSlider("v_slider", &v_slider_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var now = oc.clock.time(.Monotonic);
 | 
				
			||||||
 | 
					        if ((now - v_slider_log_time) >= 0.2 and v_slider_value != v_slider_logged_value) {
 | 
				
			||||||
 | 
					            logPushf("Vertical slider moved to {d:.3}", .{v_slider_value});
 | 
				
			||||||
 | 
					            v_slider_logged_value = v_slider_value;
 | 
				
			||||||
 | 
					            v_slider_log_time = now;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					                .layout = .{
 | 
				
			||||||
 | 
					                    .axis = .Y,
 | 
				
			||||||
 | 
					                    .spacing = 24,
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            _ = oc.uiBoxBegin("top right", .{});
 | 
				
			||||||
 | 
					            defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					            // Tooltip
 | 
				
			||||||
 | 
					            //-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					            if (oc.uiLabel("Tooltip").hovering) {
 | 
				
			||||||
 | 
					                oc.uiTooltip("Hi");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					            // Radio group
 | 
				
			||||||
 | 
					            //-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					            var options = [_][]const u8{
 | 
				
			||||||
 | 
					                "Radio 1",
 | 
				
			||||||
 | 
					                "Radio 2",
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            var radio_group_info = oc.UiRadioGroupInfo{
 | 
				
			||||||
 | 
					                .selected_index = radio_selected,
 | 
				
			||||||
 | 
					                .options = &options,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            var result = oc.uiRadioGroup("radio_group", &radio_group_info);
 | 
				
			||||||
 | 
					            radio_selected = result.selected_index.?;
 | 
				
			||||||
 | 
					            if (result.changed) {
 | 
				
			||||||
 | 
					                logPushf("Selected {s}", .{options[radio_selected]});
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					            // Horizontal slider
 | 
				
			||||||
 | 
					            //-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					            oc.uiStyleNext(.{ .size = .{ .width = .{ .pixels = 130 } } });
 | 
				
			||||||
 | 
					            _ = oc.uiSlider("h_slider", &h_slider_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ((now - h_slider_log_time) >= 0.2 and h_slider_value != h_slider_logged_value) {
 | 
				
			||||||
 | 
					                logPushf("Slider moved to {d:.3}", .{h_slider_value});
 | 
				
			||||||
 | 
					                h_slider_logged_value = h_slider_value;
 | 
				
			||||||
 | 
					                h_slider_log_time = now;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //-------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					    // Text box
 | 
				
			||||||
 | 
					    //-------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					    oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					        .size = .{
 | 
				
			||||||
 | 
					            .width = .{ .pixels = 305 },
 | 
				
			||||||
 | 
					            .height = .text,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    var textResult = oc.uiTextBox("text", arena.*, text);
 | 
				
			||||||
 | 
					    if (textResult.changed) {
 | 
				
			||||||
 | 
					        text_arena.clear();
 | 
				
			||||||
 | 
					        text = text_arena.pushStr(textResult.text) catch {
 | 
				
			||||||
 | 
					            oc.log.err("Out of memory", .{}, @src());
 | 
				
			||||||
 | 
					            oc.requestQuit();
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (textResult.accepted) {
 | 
				
			||||||
 | 
					        logPushf("Entered text {s}", .{text});
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //-------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					    // Select
 | 
				
			||||||
 | 
					    //-------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					    var options = [_][]const u8{
 | 
				
			||||||
 | 
					        "Option 1",
 | 
				
			||||||
 | 
					        "Option 2",
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    var select_popup_info = oc.UiSelectPopupInfo{
 | 
				
			||||||
 | 
					        .selected_index = selected,
 | 
				
			||||||
 | 
					        .options = &options,
 | 
				
			||||||
 | 
					        .placeholder = "Select",
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    var selectResult = oc.uiSelectPopup("select", &select_popup_info);
 | 
				
			||||||
 | 
					    if (selectResult.selected_index != selected) {
 | 
				
			||||||
 | 
					        logPushf("Selected {s}", .{options[selectResult.selected_index.?]});
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    selected = selectResult.selected_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //-------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					    // Scrollable panel
 | 
				
			||||||
 | 
					    //-------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					            .size = .{
 | 
				
			||||||
 | 
					                .width = .fill_parent,
 | 
				
			||||||
 | 
					                .height = .{
 | 
				
			||||||
 | 
					                    .custom = .{ .kind = .Parent, .value = 1, .relax = 1, .min_size = 200 },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            .bg_color = ui.theme.bg2,
 | 
				
			||||||
 | 
					            .border_color = ui.theme.border,
 | 
				
			||||||
 | 
					            .border_size = 1,
 | 
				
			||||||
 | 
					            .roundness = ui.theme.roundness_small,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        _ = oc.uiPanelBegin("log", .{ .draw_background = true, .draw_border = true });
 | 
				
			||||||
 | 
					        defer oc.uiPanelEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					                .layout = .{
 | 
				
			||||||
 | 
					                    .margin = .{ .x = 16, .y = 16 },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            _ = oc.uiBoxBegin("contents", .{});
 | 
				
			||||||
 | 
					            defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (log_lines.list.empty()) {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{ .color = ui.theme.text2 });
 | 
				
			||||||
 | 
					                _ = oc.uiLabel("Log");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var i: i32 = 0;
 | 
				
			||||||
 | 
					            var log_lines_iter = log_lines.iter();
 | 
				
			||||||
 | 
					            while (log_lines_iter.next()) |log_line| {
 | 
				
			||||||
 | 
					                var buf: [15]u8 = undefined;
 | 
				
			||||||
 | 
					                var id = std.fmt.bufPrint(&buf, "{d}", .{i}) catch unreachable;
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin(id, .{});
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _ = oc.uiLabel(log_line.string.slice());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                i += 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var styling_selected_radio: ?usize = 0;
 | 
				
			||||||
 | 
					var unselected_width: f32 = 16;
 | 
				
			||||||
 | 
					var unselected_height: f32 = 16;
 | 
				
			||||||
 | 
					var unselected_roundness: f32 = 8;
 | 
				
			||||||
 | 
					var unselected_bg_color: oc.Color = oc.Color.rgba(0.086, 0.086, 0.102, 1);
 | 
				
			||||||
 | 
					var unselected_border_color: oc.Color = oc.Color.rgba(0.976, 0.976, 0.976, 0.35);
 | 
				
			||||||
 | 
					var unselected_border_size: f32 = 1;
 | 
				
			||||||
 | 
					var unselected_when_status: oc.UiStatus = .{};
 | 
				
			||||||
 | 
					var unselected_status_index: ?usize = 0;
 | 
				
			||||||
 | 
					var selected_width: f32 = 16;
 | 
				
			||||||
 | 
					var selected_height: f32 = 16;
 | 
				
			||||||
 | 
					var selected_roundness: f32 = 8;
 | 
				
			||||||
 | 
					var selected_center_color: oc.Color = oc.Color.rgba(1, 1, 1, 1);
 | 
				
			||||||
 | 
					var selected_bg_color: oc.Color = oc.Color.rgba(0.33, 0.66, 1, 1);
 | 
				
			||||||
 | 
					var selected_when_status: oc.UiStatus = .{};
 | 
				
			||||||
 | 
					var selected_status_index: ?usize = 0;
 | 
				
			||||||
 | 
					var label_font_color: oc.Color = oc.Color.rgba(0.976, 0.976, 0.976, 1);
 | 
				
			||||||
 | 
					var label_font_color_selected: ?usize = 0;
 | 
				
			||||||
 | 
					var label_font: *oc.Font = &font_regular;
 | 
				
			||||||
 | 
					var label_font_selected: ?usize = 0;
 | 
				
			||||||
 | 
					var label_font_size: f32 = 14;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn styling(arena: *oc.Arena) void {
 | 
				
			||||||
 | 
					    //-----------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					    // Styling
 | 
				
			||||||
 | 
					    //-----------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					    // Initial values here are hardcoded from the dark theme and everything is overridden all
 | 
				
			||||||
 | 
					    // the time. In a real program you'd only override what you need and supply the values from
 | 
				
			||||||
 | 
					    // ui.theme or ui.theme.palette.
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // Rule-based styling is described at
 | 
				
			||||||
 | 
					    // https://www.forkingpaths.dev/posts/23-03-10/rule_based_styling_imgui.html
 | 
				
			||||||
 | 
					    columnBegin("Styling", 2.0 / 3.0);
 | 
				
			||||||
 | 
					    defer columnEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					            .size = .{
 | 
				
			||||||
 | 
					                .width = .fill_parent,
 | 
				
			||||||
 | 
					                .height = .{ .pixels = 152 },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            .layout = .{
 | 
				
			||||||
 | 
					                .margin = .{ .x = 310, .y = 16 },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            .bg_color = oc.ui_dark_theme.bg0,
 | 
				
			||||||
 | 
					            .roundness = oc.ui_dark_theme.roundness_small,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        _ = oc.uiBoxBegin("styled_radios", .{ .draw_background = true, .draw_border = true });
 | 
				
			||||||
 | 
					        defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        resetNextRadioGroupToDarkTheme(arena);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var unselected_tag = oc.uiTagMake("radio");
 | 
				
			||||||
 | 
					        var unselected_pattern = oc.UiPattern.init();
 | 
				
			||||||
 | 
					        unselected_pattern.push(arena, .{ .sel = .{ .tag = unselected_tag } });
 | 
				
			||||||
 | 
					        if (!unselected_when_status.empty()) {
 | 
				
			||||||
 | 
					            unselected_pattern.push(arena, .{ .op = .And, .sel = .{ .status = unselected_when_status } });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        oc.uiStyleMatchAfter(unselected_pattern, .{
 | 
				
			||||||
 | 
					            .size = .{
 | 
				
			||||||
 | 
					                .width = .{ .pixels = unselected_width },
 | 
				
			||||||
 | 
					                .height = .{ .pixels = unselected_height },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            .bg_color = unselected_bg_color,
 | 
				
			||||||
 | 
					            .border_color = unselected_border_color,
 | 
				
			||||||
 | 
					            .border_size = unselected_border_size,
 | 
				
			||||||
 | 
					            .roundness = unselected_roundness,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var selected_tag = oc.uiTagMake("radio_selected");
 | 
				
			||||||
 | 
					        var selected_pattern = oc.UiPattern.init();
 | 
				
			||||||
 | 
					        selected_pattern.push(arena, .{ .sel = .{ .tag = selected_tag } });
 | 
				
			||||||
 | 
					        if (!selected_when_status.empty()) {
 | 
				
			||||||
 | 
					            selected_pattern.push(arena, .{ .op = .And, .sel = .{ .status = selected_when_status } });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        oc.uiStyleMatchAfter(selected_pattern, .{
 | 
				
			||||||
 | 
					            .size = .{
 | 
				
			||||||
 | 
					                .width = .{ .pixels = selected_width },
 | 
				
			||||||
 | 
					                .height = .{ .pixels = selected_height },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            .color = selected_center_color,
 | 
				
			||||||
 | 
					            .bg_color = selected_bg_color,
 | 
				
			||||||
 | 
					            .roundness = selected_roundness,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var label_tag = oc.uiTagMake("label");
 | 
				
			||||||
 | 
					        var label_pattern = oc.UiPattern.init();
 | 
				
			||||||
 | 
					        label_pattern.push(arena, .{ .sel = .{ .tag = label_tag } });
 | 
				
			||||||
 | 
					        oc.uiStyleMatchAfter(label_pattern, .{
 | 
				
			||||||
 | 
					            .color = label_font_color,
 | 
				
			||||||
 | 
					            .font = label_font.*,
 | 
				
			||||||
 | 
					            .font_size = label_font_size,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var options = [_][]const u8{
 | 
				
			||||||
 | 
					            "I",
 | 
				
			||||||
 | 
					            "Am",
 | 
				
			||||||
 | 
					            "Stylish",
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        var radio_group_info = oc.UiRadioGroupInfo{
 | 
				
			||||||
 | 
					            .selected_index = styling_selected_radio,
 | 
				
			||||||
 | 
					            .options = &options,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        var result = oc.uiRadioGroup("radio_group", &radio_group_info);
 | 
				
			||||||
 | 
					        styling_selected_radio = result.selected_index;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        oc.uiStyleNext(.{ .layout = .{ .axis = .X, .spacing = 32 } });
 | 
				
			||||||
 | 
					        _ = oc.uiBoxBegin("controls", .{});
 | 
				
			||||||
 | 
					        defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            oc.uiStyleNext(.{ .layout = .{ .axis = .Y, .spacing = 16 } });
 | 
				
			||||||
 | 
					            _ = oc.uiBoxBegin("unselected", .{});
 | 
				
			||||||
 | 
					            defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            oc.uiStyleNext(.{ .font_size = 16 });
 | 
				
			||||||
 | 
					            _ = oc.uiLabel("Radio style");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{ .layout = .{ .spacing = 4 } });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin("size", .{});
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var width_slider = (unselected_width - 8) / 16;
 | 
				
			||||||
 | 
					                labeledSlider("Width", &width_slider);
 | 
				
			||||||
 | 
					                unselected_width = 8 + width_slider * 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var height_slider = (unselected_height - 8) / 16;
 | 
				
			||||||
 | 
					                labeledSlider("Height", &height_slider);
 | 
				
			||||||
 | 
					                unselected_height = 8 + height_slider * 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var roundness_slider = (unselected_roundness - 4) / 8;
 | 
				
			||||||
 | 
					                labeledSlider("Roundness", &roundness_slider);
 | 
				
			||||||
 | 
					                unselected_roundness = 4 + roundness_slider * 8;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{ .layout = .{ .spacing = 4 } });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin("background", .{});
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                labeledSlider("Background R", &unselected_bg_color.r);
 | 
				
			||||||
 | 
					                labeledSlider("Background G", &unselected_bg_color.g);
 | 
				
			||||||
 | 
					                labeledSlider("Background B", &unselected_bg_color.b);
 | 
				
			||||||
 | 
					                labeledSlider("Background A", &unselected_bg_color.a);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{ .layout = .{ .spacing = 4 } });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin("border", .{});
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                labeledSlider("Border R", &unselected_border_color.r);
 | 
				
			||||||
 | 
					                labeledSlider("Border G", &unselected_border_color.g);
 | 
				
			||||||
 | 
					                labeledSlider("Border B", &unselected_border_color.b);
 | 
				
			||||||
 | 
					                labeledSlider("Border A", &unselected_border_color.a);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var border_size_slider = unselected_border_size / 5;
 | 
				
			||||||
 | 
					            labeledSlider("Border size", &border_size_slider);
 | 
				
			||||||
 | 
					            unselected_border_size = border_size_slider * 5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{ .layout = .{ .spacing = 10 } });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin("status_override", .{});
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _ = oc.uiLabel("Override");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var status_options = [_][]const u8{
 | 
				
			||||||
 | 
					                    "Always",
 | 
				
			||||||
 | 
					                    "When hovering",
 | 
				
			||||||
 | 
					                    "When active",
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                var status_info = oc.UiRadioGroupInfo{
 | 
				
			||||||
 | 
					                    .selected_index = unselected_status_index,
 | 
				
			||||||
 | 
					                    .options = &status_options,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                var status_result = oc.uiRadioGroup("status", &status_info);
 | 
				
			||||||
 | 
					                unselected_status_index = status_result.selected_index;
 | 
				
			||||||
 | 
					                unselected_when_status = switch (unselected_status_index.?) {
 | 
				
			||||||
 | 
					                    0 => .{},
 | 
				
			||||||
 | 
					                    1 => .{ .hover = true },
 | 
				
			||||||
 | 
					                    2 => .{ .active = true },
 | 
				
			||||||
 | 
					                    else => unreachable,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            oc.uiStyleNext(.{ .layout = .{ .axis = .Y, .spacing = 16 } });
 | 
				
			||||||
 | 
					            _ = oc.uiBoxBegin("selected", .{});
 | 
				
			||||||
 | 
					            defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            oc.uiStyleNext(.{ .font_size = 16 });
 | 
				
			||||||
 | 
					            _ = oc.uiLabel("Radio selected style");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{ .layout = .{ .spacing = 4 } });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin("size", .{});
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var width_slider = (selected_width - 8) / 16;
 | 
				
			||||||
 | 
					                labeledSlider("Width", &width_slider);
 | 
				
			||||||
 | 
					                selected_width = 8 + width_slider * 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var height_slider = (selected_height - 8) / 16;
 | 
				
			||||||
 | 
					                labeledSlider("Height", &height_slider);
 | 
				
			||||||
 | 
					                selected_height = 8 + height_slider * 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var roundness_slider = (selected_roundness - 4) / 8;
 | 
				
			||||||
 | 
					                labeledSlider("Roundness", &roundness_slider);
 | 
				
			||||||
 | 
					                selected_roundness = 4 + roundness_slider * 8;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{ .layout = .{ .spacing = 4 } });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin("color", .{});
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                labeledSlider("Center R", &selected_center_color.r);
 | 
				
			||||||
 | 
					                labeledSlider("Center G", &selected_center_color.g);
 | 
				
			||||||
 | 
					                labeledSlider("Center B", &selected_center_color.b);
 | 
				
			||||||
 | 
					                labeledSlider("Center A", &selected_center_color.a);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{ .layout = .{ .spacing = 4 } });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin("background", .{});
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                labeledSlider("Background R", &selected_bg_color.r);
 | 
				
			||||||
 | 
					                labeledSlider("Background G", &selected_bg_color.g);
 | 
				
			||||||
 | 
					                labeledSlider("Background B", &selected_bg_color.b);
 | 
				
			||||||
 | 
					                labeledSlider("Background A", &selected_bg_color.a);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{ .layout = .{ .spacing = 10 } });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin("status_override", .{});
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{ .size = .{ .height = .{ .pixels = 30 } } });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxMake("spacer", .{});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _ = oc.uiLabel("Override");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var status_options = [_][]const u8{
 | 
				
			||||||
 | 
					                    "Always",
 | 
				
			||||||
 | 
					                    "When hovering",
 | 
				
			||||||
 | 
					                    "When active",
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                var status_info = oc.UiRadioGroupInfo{
 | 
				
			||||||
 | 
					                    .selected_index = selected_status_index,
 | 
				
			||||||
 | 
					                    .options = &status_options,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                var status_result = oc.uiRadioGroup("status", &status_info);
 | 
				
			||||||
 | 
					                selected_status_index = status_result.selected_index;
 | 
				
			||||||
 | 
					                selected_when_status = switch (selected_status_index.?) {
 | 
				
			||||||
 | 
					                    0 => .{},
 | 
				
			||||||
 | 
					                    1 => .{ .hover = true },
 | 
				
			||||||
 | 
					                    2 => .{ .active = true },
 | 
				
			||||||
 | 
					                    else => unreachable,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            oc.uiStyleNext(.{ .layout = .{ .axis = .Y, .spacing = 10 } });
 | 
				
			||||||
 | 
					            _ = oc.uiBoxBegin("label", .{});
 | 
				
			||||||
 | 
					            defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            oc.uiStyleNext(.{ .font_size = 16 });
 | 
				
			||||||
 | 
					            _ = oc.uiLabel("Label style");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{ .layout = .{ .axis = .X, .spacing = 8 } });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin("font_color", .{});
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                oc.uiStyleMatchAfter(oc.UiPattern.owner(), .{
 | 
				
			||||||
 | 
					                    .size = .{ .width = .{ .pixels = 100 } },
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                _ = oc.uiLabel("Font color");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var color_names = [_][]const u8{
 | 
				
			||||||
 | 
					                    "Default",
 | 
				
			||||||
 | 
					                    "Red",
 | 
				
			||||||
 | 
					                    "Orange",
 | 
				
			||||||
 | 
					                    "Amber",
 | 
				
			||||||
 | 
					                    "Yellow",
 | 
				
			||||||
 | 
					                    "Lime",
 | 
				
			||||||
 | 
					                    "Light green",
 | 
				
			||||||
 | 
					                    "Green",
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                var colors = [_]oc.Color{
 | 
				
			||||||
 | 
					                    oc.ui_dark_theme.text0,
 | 
				
			||||||
 | 
					                    oc.ui_dark_theme.palette.red5,
 | 
				
			||||||
 | 
					                    oc.ui_dark_theme.palette.orange5,
 | 
				
			||||||
 | 
					                    oc.ui_dark_theme.palette.amber5,
 | 
				
			||||||
 | 
					                    oc.ui_dark_theme.palette.yellow5,
 | 
				
			||||||
 | 
					                    oc.ui_dark_theme.palette.lime5,
 | 
				
			||||||
 | 
					                    oc.ui_dark_theme.palette.light_green5,
 | 
				
			||||||
 | 
					                    oc.ui_dark_theme.palette.green5,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                var color_info = oc.UiSelectPopupInfo{
 | 
				
			||||||
 | 
					                    .selected_index = label_font_color_selected,
 | 
				
			||||||
 | 
					                    .options = &color_names,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                var color_result = oc.uiSelectPopup("color", &color_info);
 | 
				
			||||||
 | 
					                label_font_color_selected = color_result.selected_index;
 | 
				
			||||||
 | 
					                label_font_color = colors[label_font_color_selected.?];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oc.uiStyleNext(.{ .layout = .{ .axis = .X, .spacing = 8 } });
 | 
				
			||||||
 | 
					                _ = oc.uiBoxBegin("font", .{});
 | 
				
			||||||
 | 
					                defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                oc.uiStyleMatchAfter(oc.UiPattern.owner(), .{
 | 
				
			||||||
 | 
					                    .size = .{ .width = .{ .pixels = 100 } },
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                _ = oc.uiLabel("Font");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var font_names = [_][]const u8{
 | 
				
			||||||
 | 
					                    "Regular",
 | 
				
			||||||
 | 
					                    "Bold",
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                var fonts = [_]*oc.Font{
 | 
				
			||||||
 | 
					                    &font_regular,
 | 
				
			||||||
 | 
					                    &font_bold,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                var font_info = oc.UiSelectPopupInfo{
 | 
				
			||||||
 | 
					                    .selected_index = label_font_selected,
 | 
				
			||||||
 | 
					                    .options = &font_names,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                var font_result = oc.uiSelectPopup("font_style", &font_info);
 | 
				
			||||||
 | 
					                label_font_selected = font_result.selected_index;
 | 
				
			||||||
 | 
					                label_font = fonts[label_font_selected.?];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var font_size_slider = (label_font_size - 8) / 16;
 | 
				
			||||||
 | 
					            labeledSlider("Font size", &font_size_slider);
 | 
				
			||||||
 | 
					            label_font_size = 8 + font_size_slider * 16;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn columnBegin(header: []const u8, widthFraction: f32) void {
 | 
				
			||||||
 | 
					    oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					        .size = .{
 | 
				
			||||||
 | 
					            .width = .{
 | 
				
			||||||
 | 
					                .custom = .{ .kind = .Parent, .value = widthFraction, .relax = 1 },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            .height = .fill_parent,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        .layout = .{
 | 
				
			||||||
 | 
					            .axis = .Y,
 | 
				
			||||||
 | 
					            .margin = .{ .y = 8 },
 | 
				
			||||||
 | 
					            .spacing = 24,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        .bg_color = ui.theme.bg1,
 | 
				
			||||||
 | 
					        .border_color = ui.theme.border,
 | 
				
			||||||
 | 
					        .border_size = 1,
 | 
				
			||||||
 | 
					        .roundness = ui.theme.roundness_small,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    _ = oc.uiBoxBegin(header, .{ .draw_background = true, .draw_border = true });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					            .size = .{ .width = .fill_parent },
 | 
				
			||||||
 | 
					            .layout = .{ .alignment = .{ .x = .Center } },
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        _ = oc.uiBoxBegin("header", .{});
 | 
				
			||||||
 | 
					        defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        oc.uiStyleNext(.{ .font_size = 18 });
 | 
				
			||||||
 | 
					        _ = oc.uiLabel(header);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					        .size = .{
 | 
				
			||||||
 | 
					            .width = .fill_parent,
 | 
				
			||||||
 | 
					            .height = .{
 | 
				
			||||||
 | 
					                .custom = .{ .kind = .Parent, .value = 1, .relax = 1 },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        .layout = .{
 | 
				
			||||||
 | 
					            .alignment = .{ .x = .Start },
 | 
				
			||||||
 | 
					            .margin = .{ .x = 16 },
 | 
				
			||||||
 | 
					            .spacing = 24,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    _ = oc.uiBoxBegin("contents", .{});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn columnEnd() void {
 | 
				
			||||||
 | 
					    _ = oc.uiBoxEnd(); // contents
 | 
				
			||||||
 | 
					    _ = oc.uiBoxEnd(); // column
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn labeledSlider(label: []const u8, value: *f32) void {
 | 
				
			||||||
 | 
					    oc.uiStyleNext(.{ .layout = .{ .axis = .X, .spacing = 8 } });
 | 
				
			||||||
 | 
					    _ = oc.uiBoxBegin(label, .{});
 | 
				
			||||||
 | 
					    defer _ = oc.uiBoxEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    oc.uiStyleMatchAfter(oc.UiPattern.owner(), .{
 | 
				
			||||||
 | 
					        .size = .{ .width = .{ .pixels = 100 } },
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    _ = oc.uiLabel(label);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    oc.uiStyleNext(.{
 | 
				
			||||||
 | 
					        .size = .{ .width = .{ .pixels = 100 } },
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    _ = oc.uiSlider("slider", value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn logPush(line: []const u8) void {
 | 
				
			||||||
 | 
					    log_lines.push(&log_arena, oc.Str8.fromSlice(line)) catch {
 | 
				
			||||||
 | 
					        oc.log.err("Out of memory", .{}, @src());
 | 
				
			||||||
 | 
					        oc.requestQuit();
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn logPushf(comptime fmt: []const u8, args: anytype) void {
 | 
				
			||||||
 | 
					    var str = oc.Str8.pushf(&log_arena, fmt, args) catch {
 | 
				
			||||||
 | 
					        oc.log.err("Out of memory", .{}, @src());
 | 
				
			||||||
 | 
					        oc.requestQuit();
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    log_lines.push(&log_arena, str) catch {
 | 
				
			||||||
 | 
					        oc.log.err("Out of memory", .{}, @src());
 | 
				
			||||||
 | 
					        oc.requestQuit();
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// This makes sure the light theme doesn't break the styling overrides
 | 
				
			||||||
 | 
					/// You won't need it in a real program as long as your colors come from ui.theme or ui.theme.palette
 | 
				
			||||||
 | 
					fn resetNextRadioGroupToDarkTheme(arena: *oc.Arena) void {
 | 
				
			||||||
 | 
					    var unselected_tag = oc.uiTagMake("radio");
 | 
				
			||||||
 | 
					    var unselected_pattern = oc.UiPattern.init();
 | 
				
			||||||
 | 
					    unselected_pattern.push(arena, .{ .sel = .{ .tag = unselected_tag } });
 | 
				
			||||||
 | 
					    oc.uiStyleMatchAfter(unselected_pattern, .{
 | 
				
			||||||
 | 
					        .border_color = oc.ui_dark_theme.text3,
 | 
				
			||||||
 | 
					        .border_size = 1,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var unselected_hover_pattern = oc.UiPattern.init();
 | 
				
			||||||
 | 
					    unselected_hover_pattern.push(arena, .{ .sel = .{ .tag = unselected_tag } });
 | 
				
			||||||
 | 
					    unselected_hover_pattern.push(arena, .{ .op = .And, .sel = .{ .status = .{ .hover = true } } });
 | 
				
			||||||
 | 
					    oc.uiStyleMatchAfter(unselected_hover_pattern, .{
 | 
				
			||||||
 | 
					        .bg_color = oc.ui_dark_theme.fill0,
 | 
				
			||||||
 | 
					        .border_color = oc.ui_dark_theme.primary,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var unselected_active_pattern = oc.UiPattern.init();
 | 
				
			||||||
 | 
					    unselected_active_pattern.push(arena, .{ .sel = .{ .tag = unselected_tag } });
 | 
				
			||||||
 | 
					    unselected_active_pattern.push(arena, .{ .op = .And, .sel = .{ .status = .{ .active = true } } });
 | 
				
			||||||
 | 
					    oc.uiStyleMatchAfter(unselected_active_pattern, .{
 | 
				
			||||||
 | 
					        .bg_color = oc.ui_dark_theme.fill1,
 | 
				
			||||||
 | 
					        .border_color = oc.ui_dark_theme.primary,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var selected_tag = oc.uiTagMake("radio_selected");
 | 
				
			||||||
 | 
					    var selected_pattern = oc.UiPattern.init();
 | 
				
			||||||
 | 
					    selected_pattern.push(arena, .{ .sel = .{ .tag = selected_tag } });
 | 
				
			||||||
 | 
					    oc.uiStyleMatchAfter(selected_pattern, .{
 | 
				
			||||||
 | 
					        .color = oc.ui_dark_theme.palette.white,
 | 
				
			||||||
 | 
					        .bg_color = oc.ui_dark_theme.primary,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var selected_hover_pattern = oc.UiPattern.init();
 | 
				
			||||||
 | 
					    selected_hover_pattern.push(arena, .{ .sel = .{ .tag = selected_tag } });
 | 
				
			||||||
 | 
					    selected_hover_pattern.push(arena, .{ .op = .And, .sel = .{ .status = .{ .hover = true } } });
 | 
				
			||||||
 | 
					    oc.uiStyleMatchAfter(selected_hover_pattern, .{
 | 
				
			||||||
 | 
					        .bg_color = oc.ui_dark_theme.primary_hover,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var selected_active_pattern = oc.UiPattern.init();
 | 
				
			||||||
 | 
					    selected_active_pattern.push(arena, .{ .sel = .{ .tag = selected_tag } });
 | 
				
			||||||
 | 
					    selected_active_pattern.push(arena, .{ .op = .And, .sel = .{ .status = .{ .active = true } } });
 | 
				
			||||||
 | 
					    oc.uiStyleMatchAfter(selected_active_pattern, .{
 | 
				
			||||||
 | 
					        .bg_color = oc.ui_dark_theme.primary_active,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1555
									
								
								src/orca.zig
								
								
								
								
							
							
						
						
									
										1555
									
								
								src/orca.zig
								
								
								
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										107
									
								
								src/ui/ui.c
								
								
								
								
							
							
						
						
									
										107
									
								
								src/ui/ui.c
								
								
								
								
							| 
						 | 
					@ -1778,7 +1778,7 @@ oc_ui_sig oc_ui_button_behavior(oc_ui_box* box)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        oc_ui_box_set_hot(box, false);
 | 
					        oc_ui_box_set_hot(box, false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(!sig.hovering && !sig.dragging)
 | 
					    if(!sig.hovering || !sig.dragging)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        oc_ui_box_deactivate(box);
 | 
					        oc_ui_box_deactivate(box);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1873,7 +1873,7 @@ void oc_ui_checkbox_draw(oc_ui_box* box, void* data)
 | 
				
			||||||
    oc_matrix_pop();
 | 
					    oc_matrix_pop();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oc_ui_sig oc_ui_checkbox(const char* name, bool* checked)
 | 
					oc_ui_sig oc_ui_checkbox_str8(oc_str8 name, bool* checked)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_context* ui = oc_ui_get_context();
 | 
					    oc_ui_context* ui = oc_ui_get_context();
 | 
				
			||||||
    oc_ui_theme* theme = ui->theme;
 | 
					    oc_ui_theme* theme = ui->theme;
 | 
				
			||||||
| 
						 | 
					@ -1918,7 +1918,7 @@ oc_ui_sig oc_ui_checkbox(const char* name, bool* checked)
 | 
				
			||||||
                          | OC_UI_FLAG_HOT_ANIMATION
 | 
					                          | OC_UI_FLAG_HOT_ANIMATION
 | 
				
			||||||
                          | OC_UI_FLAG_ACTIVE_ANIMATION;
 | 
					                          | OC_UI_FLAG_ACTIVE_ANIMATION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        box = oc_ui_box_make(name, flags);
 | 
					        box = oc_ui_box_make_str8(name, flags);
 | 
				
			||||||
        oc_ui_tag_box(box, "checkbox");
 | 
					        oc_ui_tag_box(box, "checkbox");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        oc_ui_box_set_draw_proc(box, oc_ui_checkbox_draw, 0);
 | 
					        oc_ui_box_set_draw_proc(box, oc_ui_checkbox_draw, 0);
 | 
				
			||||||
| 
						 | 
					@ -1968,7 +1968,7 @@ oc_ui_sig oc_ui_checkbox(const char* name, bool* checked)
 | 
				
			||||||
                          | OC_UI_FLAG_HOT_ANIMATION
 | 
					                          | OC_UI_FLAG_HOT_ANIMATION
 | 
				
			||||||
                          | OC_UI_FLAG_ACTIVE_ANIMATION;
 | 
					                          | OC_UI_FLAG_ACTIVE_ANIMATION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        box = oc_ui_box_make(name, flags);
 | 
					        box = oc_ui_box_make_str8(name, flags);
 | 
				
			||||||
        oc_ui_tag_box(box, "checkbox");
 | 
					        oc_ui_tag_box(box, "checkbox");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1981,16 +1981,21 @@ oc_ui_sig oc_ui_checkbox(const char* name, bool* checked)
 | 
				
			||||||
    return (sig);
 | 
					    return (sig);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					oc_ui_sig oc_ui_checkbox(const char* name, bool* checked)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return oc_ui_checkbox_str8(OC_STR8(name), checked);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
// slider / scrollbar
 | 
					// slider / scrollbar
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
oc_ui_box* oc_ui_slider(const char* label, f32* value)
 | 
					oc_ui_box* oc_ui_slider_str8(oc_str8 label, f32* value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_context* ui = oc_ui_get_context();
 | 
					    oc_ui_context* ui = oc_ui_get_context();
 | 
				
			||||||
    oc_ui_theme* theme = ui->theme;
 | 
					    oc_ui_theme* theme = ui->theme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oc_ui_style_match_before(oc_ui_pattern_all(), &(oc_ui_style){ 0 }, OC_UI_STYLE_LAYOUT);
 | 
					    oc_ui_style_match_before(oc_ui_pattern_all(), &(oc_ui_style){ 0 }, OC_UI_STYLE_LAYOUT);
 | 
				
			||||||
    oc_ui_box* frame = oc_ui_box_begin(label, 0);
 | 
					    oc_ui_box* frame = oc_ui_box_begin_str8(label, 0);
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        oc_ui_axis trackAxis = (frame->rect.w > frame->rect.h) ? OC_UI_AXIS_X : OC_UI_AXIS_Y;
 | 
					        oc_ui_axis trackAxis = (frame->rect.w > frame->rect.h) ? OC_UI_AXIS_X : OC_UI_AXIS_Y;
 | 
				
			||||||
        oc_ui_axis secondAxis = (trackAxis == OC_UI_AXIS_Y) ? OC_UI_AXIS_X : OC_UI_AXIS_Y;
 | 
					        oc_ui_axis secondAxis = (trackAxis == OC_UI_AXIS_Y) ? OC_UI_AXIS_X : OC_UI_AXIS_Y;
 | 
				
			||||||
| 
						 | 
					@ -2161,12 +2166,17 @@ oc_ui_box* oc_ui_slider(const char* label, f32* value)
 | 
				
			||||||
    return (frame);
 | 
					    return (frame);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oc_ui_box* oc_ui_scrollbar(const char* label, f32 thumbRatio, f32* scrollValue)
 | 
					oc_ui_box* oc_ui_slider(const char* label, f32* value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return oc_ui_slider_str8(OC_STR8(label), value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					oc_ui_box* oc_ui_scrollbar_str8(oc_str8 label, f32 thumbRatio, f32* scrollValue)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_context* ui = oc_ui_get_context();
 | 
					    oc_ui_context* ui = oc_ui_get_context();
 | 
				
			||||||
    oc_ui_theme* theme = ui->theme;
 | 
					    oc_ui_theme* theme = ui->theme;
 | 
				
			||||||
    oc_ui_style_match_before(oc_ui_pattern_all(), &(oc_ui_style){ 0 }, OC_UI_STYLE_LAYOUT);
 | 
					    oc_ui_style_match_before(oc_ui_pattern_all(), &(oc_ui_style){ 0 }, OC_UI_STYLE_LAYOUT);
 | 
				
			||||||
    oc_ui_box* frame = oc_ui_box_begin(label, 0);
 | 
					    oc_ui_box* frame = oc_ui_box_begin_str8(label, 0);
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        f32 minThumbRatio = 17. / oc_max(frame->rect.w, frame->rect.h);
 | 
					        f32 minThumbRatio = 17. / oc_max(frame->rect.w, frame->rect.h);
 | 
				
			||||||
        thumbRatio = oc_min(oc_max(thumbRatio, minThumbRatio), 1.);
 | 
					        thumbRatio = oc_min(oc_max(thumbRatio, minThumbRatio), 1.);
 | 
				
			||||||
| 
						 | 
					@ -2292,10 +2302,15 @@ oc_ui_box* oc_ui_scrollbar(const char* label, f32 thumbRatio, f32* scrollValue)
 | 
				
			||||||
    return (frame);
 | 
					    return (frame);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					oc_ui_box* oc_ui_scrollbar(const char* label, f32 thumbRatio, f32* scrollValue)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return oc_ui_scrollbar_str8(OC_STR8(label), thumbRatio, scrollValue);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
// panels
 | 
					// panels
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
void oc_ui_panel_begin(const char* str, oc_ui_flags flags)
 | 
					void oc_ui_panel_begin_str8(oc_str8 str, oc_ui_flags flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    flags = flags
 | 
					    flags = flags
 | 
				
			||||||
          | OC_UI_FLAG_CLIP
 | 
					          | OC_UI_FLAG_CLIP
 | 
				
			||||||
| 
						 | 
					@ -2311,7 +2326,7 @@ void oc_ui_panel_begin(const char* str, oc_ui_flags flags)
 | 
				
			||||||
                                     .layout.margin.y = 0 },
 | 
					                                     .layout.margin.y = 0 },
 | 
				
			||||||
                     OC_UI_STYLE_SIZE
 | 
					                     OC_UI_STYLE_SIZE
 | 
				
			||||||
                         | OC_UI_STYLE_LAYOUT_MARGINS);
 | 
					                         | OC_UI_STYLE_LAYOUT_MARGINS);
 | 
				
			||||||
    oc_ui_box_begin(str, flags);
 | 
					    oc_ui_box_begin_str8(str, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
 | 
					    oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
 | 
				
			||||||
                                     .size.height = { OC_UI_SIZE_PARENT, 1 } },
 | 
					                                     .size.height = { OC_UI_SIZE_PARENT, 1 } },
 | 
				
			||||||
| 
						 | 
					@ -2320,6 +2335,11 @@ void oc_ui_panel_begin(const char* str, oc_ui_flags flags)
 | 
				
			||||||
    oc_ui_box_begin("contents", 0);
 | 
					    oc_ui_box_begin("contents", 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void oc_ui_panel_begin(const char* str, oc_ui_flags flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    oc_ui_panel_begin_str8(OC_STR8(str), flags);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void oc_ui_panel_end(void)
 | 
					void oc_ui_panel_end(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_box_end(); // contents
 | 
					    oc_ui_box_end(); // contents
 | 
				
			||||||
| 
						 | 
					@ -2413,7 +2433,7 @@ void oc_ui_tooltip_arrow_draw(oc_ui_box* box, void* data)
 | 
				
			||||||
    oc_matrix_pop();
 | 
					    oc_matrix_pop();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void oc_ui_tooltip(const char* label)
 | 
					void oc_ui_tooltip_str8(oc_str8 label)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_context* ui = oc_ui_get_context();
 | 
					    oc_ui_context* ui = oc_ui_get_context();
 | 
				
			||||||
    oc_ui_theme* theme = ui->theme;
 | 
					    oc_ui_theme* theme = ui->theme;
 | 
				
			||||||
| 
						 | 
					@ -2424,7 +2444,7 @@ void oc_ui_tooltip(const char* label)
 | 
				
			||||||
                                   .floatTarget.x = p.x,
 | 
					                                   .floatTarget.x = p.x,
 | 
				
			||||||
                                   .floatTarget.y = p.y };
 | 
					                                   .floatTarget.y = p.y };
 | 
				
			||||||
    oc_ui_style_next(&containerStyle, OC_UI_STYLE_FLOAT);
 | 
					    oc_ui_style_next(&containerStyle, OC_UI_STYLE_FLOAT);
 | 
				
			||||||
    oc_ui_container(label, OC_UI_FLAG_OVERLAY)
 | 
					    oc_ui_container_str8(label, OC_UI_FLAG_OVERLAY)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        oc_ui_style arrowStyle = { .size.width = { OC_UI_SIZE_PIXELS, 24 },
 | 
					        oc_ui_style arrowStyle = { .size.width = { OC_UI_SIZE_PIXELS, 24 },
 | 
				
			||||||
                                   .size.height = { OC_UI_SIZE_PIXELS, 24 },
 | 
					                                   .size.height = { OC_UI_SIZE_PIXELS, 24 },
 | 
				
			||||||
| 
						 | 
					@ -2460,17 +2480,22 @@ void oc_ui_tooltip(const char* label)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        oc_ui_box* contents = oc_ui_box_begin("contents", OC_UI_FLAG_DRAW_BACKGROUND);
 | 
					        oc_ui_box* contents = oc_ui_box_begin("contents", OC_UI_FLAG_DRAW_BACKGROUND);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        oc_ui_label(label);
 | 
					        oc_ui_label_str8(label);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        oc_ui_box_end();
 | 
					        oc_ui_box_end();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void oc_ui_tooltip(const char* label)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    oc_ui_tooltip_str8(OC_STR8(label));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
// Menus
 | 
					// Menus
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void oc_ui_menu_bar_begin(const char* name)
 | 
					void oc_ui_menu_bar_begin_str8(oc_str8 name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_style style = {
 | 
					    oc_ui_style style = {
 | 
				
			||||||
        .size.width = { OC_UI_SIZE_PARENT, 1, 0 },
 | 
					        .size.width = { OC_UI_SIZE_PARENT, 1, 0 },
 | 
				
			||||||
| 
						 | 
					@ -2481,7 +2506,7 @@ void oc_ui_menu_bar_begin(const char* name)
 | 
				
			||||||
                          | OC_UI_STYLE_LAYOUT_AXIS;
 | 
					                          | OC_UI_STYLE_LAYOUT_AXIS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oc_ui_style_next(&style, mask);
 | 
					    oc_ui_style_next(&style, mask);
 | 
				
			||||||
    oc_ui_box* bar = oc_ui_box_begin(name, OC_UI_FLAG_DRAW_BACKGROUND);
 | 
					    oc_ui_box* bar = oc_ui_box_begin_str8(name, OC_UI_FLAG_DRAW_BACKGROUND);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oc_ui_sig sig = oc_ui_box_sig(bar);
 | 
					    oc_ui_sig sig = oc_ui_box_sig(bar);
 | 
				
			||||||
    oc_ui_context* ui = oc_ui_get_context();
 | 
					    oc_ui_context* ui = oc_ui_get_context();
 | 
				
			||||||
| 
						 | 
					@ -2491,16 +2516,21 @@ void oc_ui_menu_bar_begin(const char* name)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void oc_ui_menu_bar_begin(const char* name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    oc_ui_menu_bar_begin_str8(OC_STR8(name));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void oc_ui_menu_bar_end(void)
 | 
					void oc_ui_menu_bar_end(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_box_end(); // menu bar
 | 
					    oc_ui_box_end(); // menu bar
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void oc_ui_menu_begin(const char* label)
 | 
					void oc_ui_menu_begin_str8(oc_str8 label)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_context* ui = oc_ui_get_context();
 | 
					    oc_ui_context* ui = oc_ui_get_context();
 | 
				
			||||||
    oc_ui_theme* theme = ui->theme;
 | 
					    oc_ui_theme* theme = ui->theme;
 | 
				
			||||||
    oc_ui_box* container = oc_ui_box_make(label, 0);
 | 
					    oc_ui_box* container = oc_ui_box_make_str8(label, 0);
 | 
				
			||||||
    oc_ui_box_push(container);
 | 
					    oc_ui_box_push(container);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_CHILDREN },
 | 
					    oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_CHILDREN },
 | 
				
			||||||
| 
						 | 
					@ -2525,7 +2555,7 @@ void oc_ui_menu_begin(const char* label)
 | 
				
			||||||
    oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_TEXT },
 | 
					    oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_TEXT },
 | 
				
			||||||
                                     .size.height = { OC_UI_SIZE_TEXT } },
 | 
					                                     .size.height = { OC_UI_SIZE_TEXT } },
 | 
				
			||||||
                     OC_UI_STYLE_SIZE);
 | 
					                     OC_UI_STYLE_SIZE);
 | 
				
			||||||
    oc_ui_box* buttonLabel = oc_ui_box_make(label, OC_UI_FLAG_DRAW_TEXT);
 | 
					    oc_ui_box* buttonLabel = oc_ui_box_make_str8(label, OC_UI_FLAG_DRAW_TEXT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oc_ui_box_end(); // button
 | 
					    oc_ui_box_end(); // button
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2592,13 +2622,18 @@ void oc_ui_menu_begin(const char* label)
 | 
				
			||||||
    oc_ui_box_push(menu);
 | 
					    oc_ui_box_push(menu);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void oc_ui_menu_begin(const char* label)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    oc_ui_menu_begin_str8(OC_STR8(label));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void oc_ui_menu_end(void)
 | 
					void oc_ui_menu_end(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_box_pop(); // menu
 | 
					    oc_ui_box_pop(); // menu
 | 
				
			||||||
    oc_ui_box_pop(); // container
 | 
					    oc_ui_box_pop(); // container
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oc_ui_sig oc_ui_menu_button(const char* name)
 | 
					oc_ui_sig oc_ui_menu_button_str8(oc_str8 name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_context* ui = oc_ui_get_context();
 | 
					    oc_ui_context* ui = oc_ui_get_context();
 | 
				
			||||||
    oc_ui_theme* theme = ui->theme;
 | 
					    oc_ui_theme* theme = ui->theme;
 | 
				
			||||||
| 
						 | 
					@ -2627,11 +2662,16 @@ oc_ui_sig oc_ui_menu_button(const char* name)
 | 
				
			||||||
                      | OC_UI_FLAG_DRAW_TEXT
 | 
					                      | OC_UI_FLAG_DRAW_TEXT
 | 
				
			||||||
                      | OC_UI_FLAG_DRAW_BACKGROUND;
 | 
					                      | OC_UI_FLAG_DRAW_BACKGROUND;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oc_ui_box* box = oc_ui_box_make(name, flags);
 | 
					    oc_ui_box* box = oc_ui_box_make_str8(name, flags);
 | 
				
			||||||
    oc_ui_sig sig = oc_ui_box_sig(box);
 | 
					    oc_ui_sig sig = oc_ui_box_sig(box);
 | 
				
			||||||
    return (sig);
 | 
					    return (sig);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					oc_ui_sig oc_ui_menu_button(const char* name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return oc_ui_menu_button_str8(OC_STR8(name));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
// Select
 | 
					// Select
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					@ -2689,14 +2729,14 @@ void oc_ui_select_popup_draw_checkmark(oc_ui_box* box, void* data)
 | 
				
			||||||
    oc_matrix_pop();
 | 
					    oc_matrix_pop();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oc_ui_select_popup_info oc_ui_select_popup(const char* name, oc_ui_select_popup_info* info)
 | 
					oc_ui_select_popup_info oc_ui_select_popup_str8(oc_str8 name, oc_ui_select_popup_info* info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_select_popup_info result = *info;
 | 
					    oc_ui_select_popup_info result = *info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oc_ui_context* ui = oc_ui_get_context();
 | 
					    oc_ui_context* ui = oc_ui_get_context();
 | 
				
			||||||
    oc_ui_theme* theme = ui->theme;
 | 
					    oc_ui_theme* theme = ui->theme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oc_ui_container(name, 0)
 | 
					    oc_ui_container_str8(name, 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        oc_ui_pattern hoverPattern = { 0 };
 | 
					        oc_ui_pattern hoverPattern = { 0 };
 | 
				
			||||||
        oc_ui_pattern_push(&ui->frameArena, &hoverPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER });
 | 
					        oc_ui_pattern_push(&ui->frameArena, &hoverPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER });
 | 
				
			||||||
| 
						 | 
					@ -2908,6 +2948,11 @@ oc_ui_select_popup_info oc_ui_select_popup(const char* name, oc_ui_select_popup_
 | 
				
			||||||
    return (result);
 | 
					    return (result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					oc_ui_select_popup_info oc_ui_select_popup(const char* name, oc_ui_select_popup_info* info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return oc_ui_select_popup_str8(OC_STR8(name), info);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
// Radio group
 | 
					// Radio group
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					@ -2926,7 +2971,7 @@ void oc_ui_radio_indicator_draw(oc_ui_box* box, void* data)
 | 
				
			||||||
    oc_matrix_pop();
 | 
					    oc_matrix_pop();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oc_ui_radio_group_info oc_ui_radio_group(const char* name, oc_ui_radio_group_info* info)
 | 
					oc_ui_radio_group_info oc_ui_radio_group_str8(oc_str8 name, oc_ui_radio_group_info* info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_radio_group_info result = *info;
 | 
					    oc_ui_radio_group_info result = *info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2937,7 +2982,7 @@ oc_ui_radio_group_info oc_ui_radio_group(const char* name, oc_ui_radio_group_inf
 | 
				
			||||||
                                     .layout.spacing = 12 },
 | 
					                                     .layout.spacing = 12 },
 | 
				
			||||||
                     OC_UI_STYLE_LAYOUT_AXIS
 | 
					                     OC_UI_STYLE_LAYOUT_AXIS
 | 
				
			||||||
                         | OC_UI_STYLE_LAYOUT_SPACING);
 | 
					                         | OC_UI_STYLE_LAYOUT_SPACING);
 | 
				
			||||||
    oc_ui_container(name, 0)
 | 
					    oc_ui_container_str8(name, 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        for(int i = 0; i < info->optionCount; i++)
 | 
					        for(int i = 0; i < info->optionCount; i++)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -3036,6 +3081,11 @@ oc_ui_radio_group_info oc_ui_radio_group(const char* name, oc_ui_radio_group_inf
 | 
				
			||||||
    return (result);
 | 
					    return (result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					oc_ui_radio_group_info oc_ui_radio_group(const char* name, oc_ui_radio_group_info* info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return oc_ui_radio_group_str8(OC_STR8(name), info);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
// text box
 | 
					// text box
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					@ -3817,7 +3867,7 @@ void oc_ui_text_box_render(oc_ui_box* box, void* data)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oc_ui_text_box_result oc_ui_text_box(const char* name, oc_arena* arena, oc_str8 text)
 | 
					oc_ui_text_box_result oc_ui_text_box_str8(oc_str8 name, oc_arena* arena, oc_str8 text)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    oc_ui_context* ui = oc_ui_get_context();
 | 
					    oc_ui_context* ui = oc_ui_get_context();
 | 
				
			||||||
    oc_ui_theme* theme = ui->theme;
 | 
					    oc_ui_theme* theme = ui->theme;
 | 
				
			||||||
| 
						 | 
					@ -3853,7 +3903,7 @@ oc_ui_text_box_result oc_ui_text_box(const char* name, oc_arena* arena, oc_str8
 | 
				
			||||||
    oc_ui_flags frameFlags = OC_UI_FLAG_CLICKABLE
 | 
					    oc_ui_flags frameFlags = OC_UI_FLAG_CLICKABLE
 | 
				
			||||||
                           | OC_UI_FLAG_DRAW_BACKGROUND
 | 
					                           | OC_UI_FLAG_DRAW_BACKGROUND
 | 
				
			||||||
                           | OC_UI_FLAG_DRAW_BORDER;
 | 
					                           | OC_UI_FLAG_DRAW_BORDER;
 | 
				
			||||||
    oc_ui_box* frame = oc_ui_box_begin(name, frameFlags);
 | 
					    oc_ui_box* frame = oc_ui_box_begin_str8(name, frameFlags);
 | 
				
			||||||
    oc_ui_tag_box(frame, "frame");
 | 
					    oc_ui_tag_box(frame, "frame");
 | 
				
			||||||
    oc_font font = frame->style.font;
 | 
					    oc_font font = frame->style.font;
 | 
				
			||||||
    f32 fontSize = frame->style.fontSize;
 | 
					    f32 fontSize = frame->style.fontSize;
 | 
				
			||||||
| 
						 | 
					@ -4136,6 +4186,11 @@ oc_ui_text_box_result oc_ui_text_box(const char* name, oc_arena* arena, oc_str8
 | 
				
			||||||
    return (result);
 | 
					    return (result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					oc_ui_text_box_result oc_ui_text_box(const char* name, oc_arena* arena, oc_str8 text)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return oc_ui_text_box_str8(OC_STR8(name), arena, text);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//------------------------------------------------------------------------------
 | 
					//------------------------------------------------------------------------------
 | 
				
			||||||
// Themes
 | 
					// Themes
 | 
				
			||||||
// doc/UIColors.md has them visualized
 | 
					// doc/UIColors.md has them visualized
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/ui/ui.h
								
								
								
								
							
							
						
						
									
										14
									
								
								src/ui/ui.h
								
								
								
								
							| 
						 | 
					@ -518,7 +518,6 @@ struct oc_ui_box
 | 
				
			||||||
    oc_list beforeRules;
 | 
					    oc_list beforeRules;
 | 
				
			||||||
    oc_list afterRules;
 | 
					    oc_list afterRules;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //oc_ui_style_tag tag;
 | 
					 | 
				
			||||||
    oc_ui_style* targetStyle;
 | 
					    oc_ui_style* targetStyle;
 | 
				
			||||||
    oc_ui_style style;
 | 
					    oc_ui_style style;
 | 
				
			||||||
    u32 z;
 | 
					    u32 z;
 | 
				
			||||||
| 
						 | 
					@ -632,8 +631,6 @@ typedef struct oc_ui_context
 | 
				
			||||||
    i32 editWordSelectionInitialCursor;
 | 
					    i32 editWordSelectionInitialCursor;
 | 
				
			||||||
    i32 editWordSelectionInitialMark;
 | 
					    i32 editWordSelectionInitialMark;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool clipboardRegistered;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    oc_ui_theme* theme;
 | 
					    oc_ui_theme* theme;
 | 
				
			||||||
} oc_ui_context;
 | 
					} oc_ui_context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -731,17 +728,6 @@ ORCA_API void oc_ui_style_match_after(oc_ui_pattern pattern, oc_ui_style* style,
 | 
				
			||||||
//-------------------------------------------------------------------------
 | 
					//-------------------------------------------------------------------------
 | 
				
			||||||
// Basic widget helpers
 | 
					// Basic widget helpers
 | 
				
			||||||
//-------------------------------------------------------------------------
 | 
					//-------------------------------------------------------------------------
 | 
				
			||||||
enum
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    OC_UI_STYLE_TAG_USER_MAX = 1 << 16,
 | 
					 | 
				
			||||||
    OC_UI_STYLE_TAG_LABEL,
 | 
					 | 
				
			||||||
    OC_UI_STYLE_TAG_BUTTON,
 | 
					 | 
				
			||||||
    OC_UI_STYLE_TAG_SCROLLBAR,
 | 
					 | 
				
			||||||
    OC_UI_STYLE_TAG_PANEL,
 | 
					 | 
				
			||||||
    OC_UI_STYLE_TAG_TOOLTIP,
 | 
					 | 
				
			||||||
    OC_UI_STYLE_TAG_MENU
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ORCA_API oc_ui_sig oc_ui_label(const char* label);
 | 
					ORCA_API oc_ui_sig oc_ui_label(const char* label);
 | 
				
			||||||
ORCA_API oc_ui_sig oc_ui_label_str8(oc_str8 label);
 | 
					ORCA_API oc_ui_sig oc_ui_label_str8(oc_str8 label);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue