working horizontal panel drag

This commit is contained in:
jacob 2025-12-19 20:11:32 -06:00
parent 0ce031e324
commit 0075263e2f
6 changed files with 104 additions and 43 deletions

View File

@ -1,28 +1,3 @@
////////////////////////////////////////////////////////////
//~ Win32 libs
#pragma warning(push, 0)
#include <WinSock2.h>
#include <TlHelp32.h>
#include <WS2tcpip.h>
#include <windowsx.h>
#include <ShlObj_core.h>
#include <fileapi.h>
#include <dwmapi.h>
#include <avrt.h>
#include <shellapi.h>
#pragma warning(pop)
#pragma comment(lib, "kernel32")
#pragma comment(lib, "user32")
#pragma comment(lib, "shell32")
#pragma comment(lib, "ole32")
#pragma comment(lib, "winmm")
#pragma comment(lib, "dwmapi")
#pragma comment(lib, "synchronization")
#pragma comment(lib, "avrt")
#pragma comment(lib, "ws2_32.lib")
////////////////////////////////////////////////////////////
//~ Watch types

View File

@ -501,6 +501,7 @@ void V_TickForever(WaveLaneCtx *lane)
ui_frame_flags |= UI_FrameFlag_Vsync * !!VSYNC;
UI_Frame *ui_frame = UI_BeginFrame(ui_frame_flags, swapchain_color);
WND_Frame window_frame = ui_frame->window_frame;
WND_PushCmd(window_frame, .kind = WND_CmdKind_SetCursor, .cursor = WND_CursorKind_Default);
/* Restore window */
{
@ -896,23 +897,44 @@ void V_TickForever(WaveLaneCtx *lane)
panel_dfs->visited = 1;
/* Push children to dfs stack */
f32 ratio_accum = 0;
V_Panel *ratio_diff_panel = 0;
for (V_Panel *child = panel->last; child; child = child->prev)
{
PanelDfsNode *n = PushStruct(frame->arena, PanelDfsNode);
ratio_accum += child->pref_ratio;
n->panel = child;
SllStackPush(first_panel_dfs, n);
if (child->pref_ratio_diff != 0)
{
ratio_diff_panel = child;
}
}
/* Apply ratio diff */
if (ratio_diff_panel)
{
f32 min_ratio = 0.05;
f32 ratio_diff = ratio_diff_panel->pref_ratio_diff;
{
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);
}
ratio_diff_panel->next->pref_ratio -= ratio_diff;
ratio_diff_panel->pref_ratio += ratio_diff;
ratio_diff_panel->pref_ratio_diff = 0;
}
/* Constrain child raitos */
f32 ratio_accum = 0;
for (V_Panel *child = panel->last; child; child = child->prev)
{
child->pref_ratio = MaxF32(child->pref_ratio, 0.01);
ratio_accum += child->pref_ratio;
}
for (V_Panel *child = panel->last; child; child = child->prev)
{
child->pref_ratio += (1.0 - ratio_accum) / panel->count;
// child->pref_ratio = MaxF32(child->pref_ratio, 0.01);
}
UI_SetNext(AxisSize, UI_GROW(panel->pref_ratio, 0), .axis = !panel->axis);
UI_SetNext(AxisSize, UI_GROW(1, 0), .axis = panel->axis);
if (panel->axis == Axis_X)
@ -1053,9 +1075,13 @@ void V_TickForever(WaveLaneCtx *lane)
// UI_SetNext(Border, 2);
UI_SetNext(AxisSize, UI_GROW(1, 1), .axis = panel->axis);
UI_SetNext(AxisSize, UI_PIX(3, 1), .axis = !panel->axis);
/* FIXME: Non-transient key */
UI_BuildBoxEx(divider_key);
if (rep.is_hovered)
{
WND_PushCmd(window_frame, .kind = WND_CmdKind_SetCursor, WND_CursorKind_HorizontalResize);
}
if (rep.is_m1_held)
{
UI_Report panel_rep = UI_ReportFromKey(panel->key);
@ -1065,20 +1091,9 @@ void V_TickForever(WaveLaneCtx *lane)
f32 parent_width = DimsFromRng2(parent_rep.screen_rect).x;
f32 old_ratio = panel->pref_ratio;
// f32 new_ratio = MaxF32((frame->ui_cursor.x - panel_rep.screen_rect.p0.x) / parent_width, 0.01);
f32 new_ratio = MaxF32(frame->ui_cursor.x - panel_rep.screen_rect.p0.x, 20) / parent_width;
f32 new_ratio = (frame->ui_cursor.x - panel_rep.screen_rect.p0.x) / parent_width;
f32 ratio_diff = new_ratio - old_ratio;
panel->pref_ratio = new_ratio;
if (ratio_diff > 0.1)
{
DEBUGBREAKABLE;
}
if (panel->next)
{
panel->next->pref_ratio -= ratio_diff;
}
panel->pref_ratio_diff = ratio_diff;
}
}

View File

@ -161,6 +161,8 @@ Struct(V_Panel)
UI_Key key;
f32 pref_ratio;
f32 pref_ratio_diff;
Axis axis;
b32 is_organizing_panel;

View File

@ -6,6 +6,24 @@ Struct(WND_Handle)
u64 v;
};
////////////////////////////////////////////////////////////
//~ Cursor types
Enum(WND_CursorKind)
{
WND_CursorKind_Default,
WND_CursorKind_Text,
WND_CursorKind_No,
WND_CursorKind_Hand,
WND_CursorKind_Move,
WND_CursorKind_HorizontalResize,
WND_CursorKind_VerticalResize,
WND_CursorKind_TlBrResize,
WND_CursorKind_TrBlResize,
WND_CursorKind_Count
};
////////////////////////////////////////////////////////////
//~ Cmd types
@ -16,12 +34,14 @@ Enum(WND_CmdKind)
WND_CmdKind_SetMaximized,
WND_CmdKind_SetFullscreen,
WND_CmdKind_SetForcedTop,
WND_CmdKind_SetCursor,
WND_CmdKind_Restore,
};
Struct(WND_Cmd)
{
WND_CmdKind kind;
WND_CursorKind cursor;
String restore;
b32 v;
};

View File

@ -52,6 +52,23 @@ void WND_Bootstrap(void)
g->vk_to_button[VK_OEM_1] = Button_Semicolon;
}
//- Initialize cursors
{
HCURSOR arrow = LoadCursor(0, IDC_ARROW);
for (u64 cursor_idx = 0; cursor_idx < countof(g->cursors); ++cursor_idx)
{
g->cursors[cursor_idx] = arrow;
}
g->cursors[WND_CursorKind_Text] = LoadCursor(0, IDC_IBEAM);
g->cursors[WND_CursorKind_No] = LoadCursor(0, IDC_NO);
g->cursors[WND_CursorKind_Hand] = LoadCursor(0, IDC_HAND);
g->cursors[WND_CursorKind_Move] = LoadCursor(0, IDC_SIZEALL);
g->cursors[WND_CursorKind_HorizontalResize] = LoadCursor(0, IDC_SIZEWE);
g->cursors[WND_CursorKind_VerticalResize] = LoadCursor(0, IDC_SIZENS);
g->cursors[WND_CursorKind_TlBrResize] = LoadCursor(0, IDC_SIZENWSE);
g->cursors[WND_CursorKind_TrBlResize] = LoadCursor(0, IDC_SIZENESW);
}
//- Create window class
{
HMODULE instance = GetModuleHandle(0);
@ -200,6 +217,20 @@ LRESULT CALLBACK WND_W32_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
WND_W32_PushEvent(window, (ControllerEvent) { .kind = ControllerEventKind_Quit });
} break;
//- Cursor kind
case WM_SETCURSOR:
{
/* FIXME */
HCURSOR new_cursor = (HCURSOR)Atomic64Fetch(&window->new_cursor);
if (new_cursor != window->active_cursor)
{
SetCursor(new_cursor);
window->active_cursor = new_cursor;
result = 1;
}
} break;
//- Keyboard button
case WM_SYSKEYUP:
case WM_SYSKEYDOWN:
@ -535,6 +566,7 @@ void WND_EndFrame(WND_Frame frame, i32 vsync)
/* Process cmds */
b32 was_restored = 0;
WND_CursorKind new_cursor = (WND_CursorKind)Atomic64Fetch(&window->new_cursor);
for (WND_W32_CmdNode *n = window->first_cmd; n; n = n->next)
{
WND_Cmd cmd = n->cmd;
@ -604,6 +636,12 @@ void WND_EndFrame(WND_Frame frame, i32 vsync)
SetWindowPos(hwnd, window->is_forced_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
} break;
//- Cursor
case WND_CmdKind_SetCursor:
{
new_cursor = cmd.cursor;
} break;
//- Restore
case WND_CmdKind_Restore:
{
@ -664,6 +702,9 @@ void WND_EndFrame(WND_Frame frame, i32 vsync)
BringWindowToTop(hwnd);
}
/* Set cursor */
Atomic64Set(&window->new_cursor, (u64)g->cursors[new_cursor]);
/* Commit backbuffer */
G_CommitBackbuffer(frame.backbuffer, vsync);

View File

@ -10,6 +10,7 @@ Struct(WND_W32_Window)
/* Window proc state */
u16 previous_utf16_high_surrogate;
HCURSOR active_cursor;
/* User state */
Arena *frame_arena;
@ -23,6 +24,9 @@ Struct(WND_W32_Window)
/* Window proc -> User */
TicketMutex w2u_tm;
Arena *w2u_events_arena;
/* User -> Window proc */
Atomic64 new_cursor;
};
////////////////////////////////////////////////////////////
@ -66,7 +70,11 @@ Struct(WND_W32_CmdNode)
Struct(WND_W32_SharedState)
{
Button vk_to_button[256];
HCURSOR cursors[WND_CursorKind_Count];
WNDCLASSEXW window_class;
WND_W32_Window window; /* Single-window for now */
} extern WND_W32_shared_state;