diff --git a/src/base/base_shader.gh b/src/base/base_shader.gh index 443a3dbb..5730680e 100644 --- a/src/base/base_shader.gh +++ b/src/base/base_shader.gh @@ -76,6 +76,11 @@ u32 countof(T arr[N]) #define ClampI64(...) clamp(__VA_ARGS__) #define ClampF64(...) clamp(__VA_ARGS__) +//////////////////////////////////////////////////////////// +//~ Derivative helpers + +#define fwidth_fine(v) (abs(ddx_fine((v))) + abs(ddx_fine((v)))) + //////////////////////////////////////////////////////////// //~ Color helpers @@ -165,195 +170,100 @@ Vec2 NdcFromUv(Vec2 uv) template u32 U32FromChar(in T c) { - if(c == ' ') - return 32; - if(c == '!') - return 33; - if(c == '\"' || c == '\"') - return 34; - if(c == '#') - return 35; - if(c == '$') - return 36; - if(c == '%') - return 37; - if(c == '&') - return 38; - if(c == '\'') - return 39; - if(c == '(') - return 40; - if(c == ')') - return 41; - if(c == '*') - return 42; - if(c == '+') - return 43; - if(c == ',') - return 44; - if(c == '-') - return 45; - if(c == '.') - return 46; - if(c == '/') - return 47; - if(c == '0') - return 48; - if(c == '1') - return 49; - if(c == '2') - return 50; - if(c == '3') - return 51; - if(c == '4') - return 52; - if(c == '5') - return 53; - if(c == '6') - return 54; - if(c == '7') - return 55; - if(c == '8') - return 56; - if(c == '9') - return 57; - if(c == ':') - return 58; - if(c == ';') - return 59; - if(c == '<') - return 60; - if(c == '=') - return 61; - if(c == '>') - return 62; - if(c == '?') - return 63; - if(c == '@') - return 64; - if(c == 'A') - return 65; - if(c == 'B') - return 66; - if(c == 'C') - return 67; - if(c == 'D') - return 68; - if(c == 'E') - return 69; - if(c == 'F') - return 70; - if(c == 'G') - return 71; - if(c == 'H') - return 72; - if(c == 'I') - return 73; - if(c == 'J') - return 74; - if(c == 'K') - return 75; - if(c == 'L') - return 76; - if(c == 'M') - return 77; - if(c == 'N') - return 78; - if(c == 'O') - return 79; - if(c == 'P') - return 80; - if(c == 'Q') - return 81; - if(c == 'R') - return 82; - if(c == 'S') - return 83; - if(c == 'T') - return 84; - if(c == 'U') - return 85; - if(c == 'V') - return 86; - if(c == 'W') - return 87; - if(c == 'X') - return 88; - if(c == 'Y') - return 89; - if(c == 'Z') - return 90; - if(c == '[') - return 91; - if(c == '\\') - return 92; - if(c == ']') - return 93; - if(c == '^') - return 94; - if(c == '_') - return 95; - if(c == '`') - return 96; - if(c == 'a') - return 97; - if(c == 'b') - return 98; - if(c == 'c') - return 99; - if(c == 'd') - return 100; - if(c == 'e') - return 101; - if(c == 'f') - return 102; - if(c == 'g') - return 103; - if(c == 'h') - return 104; - if(c == 'i') - return 105; - if(c == 'j') - return 106; - if(c == 'k') - return 107; - if(c == 'l') - return 108; - if(c == 'm') - return 109; - if(c == 'n') - return 110; - if(c == 'o') - return 111; - if(c == 'p') - return 112; - if(c == 'q') - return 113; - if(c == 'r') - return 114; - if(c == 's') - return 115; - if(c == 't') - return 116; - if(c == 'u') - return 117; - if(c == 'v') - return 118; - if(c == 'w') - return 119; - if(c == 'x') - return 120; - if(c == 'y') - return 121; - if(c == 'z') - return 122; - if(c == '{') - return 123; - if(c == '|') - return 124; - if(c == '}') - return 125; - if(c == '~') - return 126; + if(c == ' ') return 32; + if(c == '!') return 33; + if(c == '\"' || c == '\"') return 34; + if(c == '#') return 35; + if(c == '$') return 36; + if(c == '%') return 37; + if(c == '&') return 38; + if(c == '\'') return 39; + if(c == '(') return 40; + if(c == ')') return 41; + if(c == '*') return 42; + if(c == '+') return 43; + if(c == ',') return 44; + if(c == '-') return 45; + if(c == '.') return 46; + if(c == '/') return 47; + if(c == '0') return 48; + if(c == '1') return 49; + if(c == '2') return 50; + if(c == '3') return 51; + if(c == '4') return 52; + if(c == '5') return 53; + if(c == '6') return 54; + if(c == '7') return 55; + if(c == '8') return 56; + if(c == '9') return 57; + if(c == ':') return 58; + if(c == ';') return 59; + if(c == '<') return 60; + if(c == '=') return 61; + if(c == '>') return 62; + if(c == '?') return 63; + if(c == '@') return 64; + if(c == 'A') return 65; + if(c == 'B') return 66; + if(c == 'C') return 67; + if(c == 'D') return 68; + if(c == 'E') return 69; + if(c == 'F') return 70; + if(c == 'G') return 71; + if(c == 'H') return 72; + if(c == 'I') return 73; + if(c == 'J') return 74; + if(c == 'K') return 75; + if(c == 'L') return 76; + if(c == 'M') return 77; + if(c == 'N') return 78; + if(c == 'O') return 79; + if(c == 'P') return 80; + if(c == 'Q') return 81; + if(c == 'R') return 82; + if(c == 'S') return 83; + if(c == 'T') return 84; + if(c == 'U') return 85; + if(c == 'V') return 86; + if(c == 'W') return 87; + if(c == 'X') return 88; + if(c == 'Y') return 89; + if(c == 'Z') return 90; + if(c == '[') return 91; + if(c == '\\') return 92; + if(c == ']') return 93; + if(c == '^') return 94; + if(c == '_') return 95; + if(c == '`') return 96; + if(c == 'a') return 97; + if(c == 'b') return 98; + if(c == 'c') return 99; + if(c == 'd') return 100; + if(c == 'e') return 101; + if(c == 'f') return 102; + if(c == 'g') return 103; + if(c == 'h') return 104; + if(c == 'i') return 105; + if(c == 'j') return 106; + if(c == 'k') return 107; + if(c == 'l') return 108; + if(c == 'm') return 109; + if(c == 'n') return 110; + if(c == 'o') return 111; + if(c == 'p') return 112; + if(c == 'q') return 113; + if(c == 'r') return 114; + if(c == 's') return 115; + if(c == 't') return 116; + if(c == 'u') return 117; + if(c == 'v') return 118; + if(c == 'w') return 119; + if(c == 'x') return 120; + if(c == 'y') return 121; + if(c == 'z') return 122; + if(c == '{') return 123; + if(c == '|') return 124; + if(c == '}') return 125; + if(c == '~') return 126; return 0; } diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index a10b5a5e..aa7fcebe 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -882,6 +882,7 @@ void V_TickForever(WaveLaneCtx *lane) panel->parent = V.root_panel; panel->key = UI_TransKey(); // TODO: Don't use transient keys panel->axis = !panel->parent->axis; + panel->pref_ratio = 0.25; DllQueuePush(panel->parent->first, panel->parent->last, panel); ++panel->parent->count; @@ -912,7 +913,7 @@ void V_TickForever(WaveLaneCtx *lane) DllQueuePush(panel->parent->first, panel->parent->last, panel); ++panel->parent->count; - panel->pref_ratio = 0.5; + panel->pref_ratio = 0.75; panel->is_viewport_panel = 1; // { @@ -925,32 +926,32 @@ void V_TickForever(WaveLaneCtx *lane) // } } - { - V_Panel *panel = PushStruct(perm, V_Panel); - panel->parent = V.root_panel; - panel->key = UI_TransKey(); // TODO: Don't use transient keys - panel->axis = !panel->parent->axis; - DllQueuePush(panel->parent->first, panel->parent->last, panel); - ++panel->parent->count; + // { + // V_Panel *panel = PushStruct(perm, V_Panel); + // panel->parent = V.root_panel; + // panel->key = UI_TransKey(); // TODO: Don't use transient keys + // panel->axis = !panel->parent->axis; + // DllQueuePush(panel->parent->first, panel->parent->last, panel); + // ++panel->parent->count; - { - V_Window *window = PushStruct(perm, V_Window); - window->panel = panel; - window->key = UI_TransKey(); // TODO: Don't use transient keys - // window->is_tile_window = 1; - DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel); - ++panel->windows_count; - } - { - V_Window *window = PushStruct(perm, V_Window); - window->panel = panel; - window->key = UI_TransKey(); // TODO: Don't use transient keys - window->is_tile_window = 1; - DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel); - ++panel->windows_count; - } - panel->active_window_idx = 1; - } + // { + // V_Window *window = PushStruct(perm, V_Window); + // window->panel = panel; + // window->key = UI_TransKey(); // TODO: Don't use transient keys + // // window->is_tile_window = 1; + // DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel); + // ++panel->windows_count; + // } + // { + // V_Window *window = PushStruct(perm, V_Window); + // window->panel = panel; + // window->key = UI_TransKey(); // TODO: Don't use transient keys + // window->is_tile_window = 1; + // DllQueuePushNP(panel->first_window, panel->last_window, window, next_in_panel, prev_in_panel); + // ++panel->windows_count; + // } + // panel->active_window_idx = 1; + // } } if (frame->is_editing) @@ -958,6 +959,7 @@ void V_TickForever(WaveLaneCtx *lane) Struct(PanelDfsNode) { PanelDfsNode *next; b32 visited; V_Panel *panel; UI_Checkpoint cp; }; PanelDfsNode *first_panel_dfs = PushStruct(frame->arena, PanelDfsNode); first_panel_dfs->panel = V.root_panel; + f32 divider_size = 10; //- Iterate panels while (first_panel_dfs) @@ -968,35 +970,64 @@ void V_TickForever(WaveLaneCtx *lane) { panel_dfs->visited = 1; + UI_Report panel_rep = UI_ReportFromKey(panel->key); + f32 panel_size = 0; + if (panel->axis == Axis_X) + { + panel_size = DimsFromRng2(panel_rep.screen_rect).x; + } + else + { + panel_size = DimsFromRng2(panel_rep.screen_rect).y; + } + // Push children to dfs stack - V_Panel *ratio_diff_panel = 0; + V_Panel *resize_panel = 0; for (V_Panel *child = panel->last; child; child = child->prev) { PanelDfsNode *n = PushStruct(frame->arena, PanelDfsNode); n->panel = child; SllStackPush(first_panel_dfs, n); - if (child->pref_ratio_diff != 0) + if (child->resizing) { - ratio_diff_panel = child; + resize_panel = child; } } - // Apply ratio diff - if (ratio_diff_panel) + // Apply resize + if (resize_panel) { - f32 min_ratio = 0.05; - f32 ratio_diff = ratio_diff_panel->pref_ratio_diff; + UI_Report child_rep = UI_ReportFromKey(resize_panel->key); + UI_Report divider_rep = UI_ReportFromKey(resize_panel->divider_key); + + f32 child_pref_size = 0; + if (panel->axis == Axis_X) { - ratio_diff += MaxF32(min_ratio - (ratio_diff_panel->pref_ratio + ratio_diff), 0); - ratio_diff -= MaxF32(min_ratio - (ratio_diff_panel->next->pref_ratio - ratio_diff), 0); + child_pref_size = frame->ui_cursor.x - child_rep.screen_rect.p0.x - divider_rep.last_down_mouse_offset.x; } - ratio_diff_panel->next->pref_ratio -= ratio_diff; - ratio_diff_panel->pref_ratio += ratio_diff; - ratio_diff_panel->pref_ratio_diff = 0; + else + { + child_pref_size = frame->ui_cursor.y - child_rep.screen_rect.p0.y - divider_rep.last_down_mouse_offset.y; + } + + f32 ratio_diff = (child_pref_size / panel_size) - resize_panel->pref_ratio; + f32 min_ratio = 0.05; + { + ratio_diff += MaxF32(min_ratio - (resize_panel->pref_ratio + ratio_diff), 0); + ratio_diff -= MaxF32(min_ratio - (resize_panel->next->pref_ratio - ratio_diff), 0); + } + + resize_panel->next->pref_ratio -= ratio_diff; + resize_panel->pref_ratio += ratio_diff; + resize_panel->resizing = 0; } // Constrain child raitos f32 ratio_accum = 0; + if (panel_size != 0) + { + ratio_accum += (MaxF32(panel->count - 1, 0) * divider_size) / panel_size; + } for (V_Panel *child = panel->last; child; child = child->prev) { child->pref_ratio = MaxF32(child->pref_ratio, 0.01); @@ -1025,7 +1056,7 @@ void V_TickForever(WaveLaneCtx *lane) i64 new_active_window_idx = panel->active_window_idx; UI_PushCP(UI_BuildColumn()); { - UI_Push(Tint, VEC4(1, 1, 1, 0.95)); + UI_Push(Tint, VEC4(1, 1, 1, 0.90)); i64 active_window_idx = ClampI64(panel->active_window_idx, 0, MaxI64(panel->windows_count - 1, 0)); //- Build tab row @@ -1183,21 +1214,12 @@ void V_TickForever(WaveLaneCtx *lane) bg_color = BlendSrgb(bg_color, theme.button_hot_color, rep.hot); bg_color = BlendSrgb(bg_color, theme.button_active_color, rep.active); - // Vec4 border_color = Zi; - // if (tile_kind == frame->equipped_tile) - // { - // border_color = theme.button_active_color; - // border_color.w *= 0.5; - // } - // border_color = BlendSrgb(border_color, theme.button_active_color, rep.hot); - b32 is_selected = tile_kind == frame->equipped_tile; Vec4 border_color = Zi; border_color = BlendSrgb(border_color, theme.button_selected_color, rep.selected); border_color = BlendSrgb(border_color, theme.button_active_color, rep.hot); - UI_SetNext(Rounding, UI_RPIX(5)); UI_SetNext(BackgroundColor, bg_color); UI_SetNext(BorderColor, border_color); UI_SetNext(Border, 1); @@ -1232,25 +1254,26 @@ void V_TickForever(WaveLaneCtx *lane) //- Build divider if (panel->next != 0) { - UI_Key divider_key = UI_KeyF("Divider"); - UI_Report rep = UI_ReportFromKey(divider_key); + panel->divider_key = UI_KeyF("Divider"); + UI_Report rep = UI_ReportFromKey(panel->divider_key); - // Vec4 hovered_color = Rgb32(0x103c4c); - Vec4 hovered_color = VEC4(0.5, 0.5, 0.5, 1); - Vec4 pressed_color = hovered_color; - pressed_color.w = 0.2; + Vec4 active_color = theme.button_active_color; + Vec4 hot_color = BlendSrgb(theme.button_hot_color, theme.button_active_color, 0.25); - Vec4 bg_color = theme.window_background_color; - bg_color.x = 0.4; - bg_color = BlendSrgb(bg_color, hovered_color, rep.hot); - bg_color = BlendSrgb(bg_color, pressed_color, rep.active * rep.hovered); + Vec4 bg_color = Zi; + bg_color = BlendSrgb(bg_color, hot_color, rep.hot); + bg_color = BlendSrgb(bg_color, active_color, rep.active); + Vec4 border_color = Zi; + f32 visible_size = 2.0; + + UI_SetNext(BackgroundColor, bg_color); + UI_SetNext(BorderColor, border_color); + UI_SetNext(Border, MaxF32((divider_size / 2.0) - (visible_size / 2.0), 0)); UI_SetNext(Flags, UI_BoxFlag_Interactable); - // UI_SetNext(BackgroundColor, bg_color); - // UI_SetNext(Border, 2); UI_SetNext(AxisSize, UI_GROW(1, 1), .axis = panel->axis); - UI_SetNext(AxisSize, UI_PIX(10, 1), .axis = !panel->axis); - UI_BuildBoxEx(divider_key); + UI_SetNext(AxisSize, UI_PIX(divider_size, 1), .axis = !panel->axis); + UI_BuildBoxEx(panel->divider_key); if (rep.is_hot || rep.m1.held) { @@ -1266,27 +1289,7 @@ void V_TickForever(WaveLaneCtx *lane) if (rep.m1.held) { - UI_Report panel_rep = UI_ReportFromKey(panel->key); - UI_Report parent_rep = UI_ReportFromKey(panel->parent->key); - - // FIXME: Height - f32 parent_size = 0; - f32 new_size = 0; - if (panel->axis == Axis_X) - { - parent_size = DimsFromRng2(parent_rep.screen_rect).y; - new_size = frame->ui_cursor.y - panel_rep.screen_rect.p0.y; - } - else - { - parent_size = DimsFromRng2(parent_rep.screen_rect).x; - new_size = frame->ui_cursor.x - panel_rep.screen_rect.p0.x; - } - - f32 old_ratio = panel->pref_ratio; - f32 new_ratio = new_size / parent_size; - f32 ratio_diff = new_ratio - old_ratio; - panel->pref_ratio_diff = ratio_diff; + panel->resizing = 1; } } diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index 87b72914..640a47c6 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -164,9 +164,10 @@ Struct(V_Panel) i64 count; UI_Key key; + UI_Key divider_key; f32 pref_ratio; - f32 pref_ratio_diff; + b32 resizing; Axis axis; diff --git a/src/ui/ui_shaders.g b/src/ui/ui_shaders.g index 05dd9663..befa58ad 100644 --- a/src/ui/ui_shaders.g +++ b/src/ui/ui_shaders.g @@ -98,7 +98,7 @@ PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input) // Border color { - f32 half_border_dist_fwidth = fwidth(border_dist) * 0.5; + f32 half_border_dist_fwidth = fwidth_fine(border_dist) * 0.5; f32 border_alpha = smoothstep(half_border_dist_fwidth, -half_border_dist_fwidth, border_dist); final_color = lerp(final_color, border_color, border_alpha); }