1 module gui_root; 2 3 import re; 4 import re.gfx; 5 import re.math; 6 import re.ecs; 7 import re.ng.diag; 8 import re.util.interop; 9 10 import raylib; 11 import raylib_nuklear; 12 import nuklear_ext; 13 import style; 14 15 import std.array; 16 import std.conv; 17 import std.string; 18 19 // font size 20 enum UI_FS = 16; 21 enum UI_UI_PAD = 4; 22 23 class GuiRoot : Component, Renderable2D, Updatable { 24 mixin Reflect; 25 26 @property public Rectangle bounds() { 27 return Rectangle(transform.position2.x, transform.position2.y, 28 entity.scene.resolution.x, entity.scene.resolution.y); 29 } 30 31 nk_context* ctx; 32 nk_colorf bg; 33 34 override void setup() { 35 bg = ColorToNuklearF(Colors.SKYBLUE); 36 auto ui_font = raylib.LoadFontEx("./res/SourceSansPro-Regular.ttf", UI_FS, null, 0); 37 ctx = InitNuklearEx(ui_font, UI_FS); 38 ctx.backend_render_scale = cast(int)(Core.window.scale_dpi); 39 apply_style(ctx); 40 41 status("ready."); 42 } 43 44 @property string status(string val) { 45 // log status 46 Core.log.info(format("status: %s", val)); 47 return status_text = val; 48 } 49 50 private string status_text = ""; 51 int active_tab = 0; 52 bool tab_picker_open = false; 53 54 void update() { 55 // keyboard shortcuts 56 if (Input.is_key_down(Keys.KEY_LEFT_CONTROL) && Input.is_key_pressed(Keys.KEY_TAB)) { 57 // advance tab 58 // active_tab = cast(int)((active_tab + 1) % tab_mds.length); 59 } 60 } 61 62 void render() { 63 auto ui_bounds = bounds; 64 65 UpdateNuklear(ctx); 66 67 // GUI 68 // auto window_bounds = nk_rect(0, 0, GetRenderWidth(), GetRenderHeight()); 69 auto window_bounds = Rectangle(0, 0, GetRenderWidth(), GetRenderHeight()); 70 if (nk_begin(ctx, "Demo", RectangleToNuklearScaled(ctx, window_bounds), 71 nk_panel_flags.NK_WINDOW_BORDER | nk_panel_flags.NK_WINDOW_TITLE)) { 72 enum EASY = 0; 73 enum HARD = 1; 74 75 nk_style_push_vec2(ctx, &ctx.style.window.spacing, nk_vec2(0, 0)); 76 nk_style_push_float(ctx, &ctx.style.button.rounding, 0); 77 nk_layout_row_begin(ctx, nk_layout_format.NK_STATIC, 30, 2); 78 enum TAB1 = 0; 79 enum TAB2 = 1; 80 static int tab_state = TAB1; 81 if (nk_tab(ctx, "TAB1", tab_state == TAB1)) { 82 tab_state = TAB1; 83 } 84 if (nk_tab(ctx, "TAB2", tab_state == TAB2)) { 85 tab_state = TAB2; 86 } 87 88 if (tab_state == TAB1) { 89 static int op = EASY; 90 91 nk_layout_row_dynamic(ctx, UI_PAD, 1); 92 93 nk_layout_row_static(ctx, 30, 80, 1); 94 if (nk_button_label(ctx, "button")) 95 TraceLog(TraceLogLevel.LOG_INFO, "button pressed"); 96 97 nk_layout_row_dynamic(ctx, 30, 2); 98 if (nk_option_label(ctx, "easy", op == EASY)) 99 op = EASY; 100 if (nk_option_label(ctx, "hard", op == HARD)) 101 op = HARD; 102 } else if (tab_state == TAB2) { 103 static int property = 20; 104 105 nk_layout_row_dynamic(ctx, UI_PAD, 1); 106 107 nk_layout_row_dynamic(ctx, 25, 1); 108 nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); 109 110 nk_layout_row_dynamic(ctx, 20, 1); 111 nk_label(ctx, "background:", nk_text_alignment.NK_TEXT_LEFT); 112 nk_layout_row_dynamic(ctx, 25, 1); 113 if (nk_combo_begin_color(ctx, nk_rgb_cf(bg), nk_vec2(nk_widget_width(ctx), 400))) { 114 nk_layout_row_dynamic(ctx, 120, 1); 115 bg = nk_color_picker(ctx, bg, nk_color_format.NK_RGBA); 116 nk_layout_row_dynamic(ctx, 25, 1); 117 bg.r = nk_propertyf(ctx, "#R:", 0, bg.r, 1.0f, 0.01f, 0.005f); 118 bg.g = nk_propertyf(ctx, "#G:", 0, bg.g, 1.0f, 0.01f, 0.005f); 119 bg.b = nk_propertyf(ctx, "#B:", 0, bg.b, 1.0f, 0.01f, 0.005f); 120 bg.a = nk_propertyf(ctx, "#A:", 0, bg.a, 1.0f, 0.01f, 0.005f); 121 nk_combo_end(ctx); 122 } 123 } 124 125 nk_style_pop_float(ctx); 126 nk_style_pop_vec2(ctx); 127 } 128 129 nk_end(ctx); 130 131 DrawNuklear(ctx); 132 } 133 134 void debug_render() { 135 raylib.DrawRectangleLinesEx(bounds, 1, Colors.RED); 136 } 137 }