diff --git a/gs_libs/gs_input.h b/gs_libs/gs_input.h index 5b60de5..d4a83f0 100644 --- a/gs_libs/gs_input.h +++ b/gs_libs/gs_input.h @@ -241,6 +241,18 @@ struct input_queue input_entry* Entries; }; +enum cursor_type +{ + CursorType_Arrow, + CursorType_Pointer, + CursorType_Loading, + CursorType_HorizontalArrows, + CursorType_VerticalArrows, + CursorType_DiagonalTopLeftArrows, + CursorType_DiagonalTopRightArrows, + CursorType_Count, +}; + struct mouse_state { s32 Scroll; @@ -253,6 +265,8 @@ struct mouse_state b32 LeftButtonState; b32 MiddleButtonState; b32 RightButtonState; + + cursor_type CursorType; }; internal input_queue @@ -370,5 +384,21 @@ MouseButtonHeldDown (b32 MouseButtonState) return (WasDown && IsDown); } +inline b32 +GetMouseButtonStateAdvanced (b32 ButtonState) +{ + b32 Result = ButtonState; + if (ButtonState & KeyState_WasDown && + !((ButtonState & KeyState_IsDown) > 0)) + { + Result= 0; + } + else if (ButtonState & KeyState_IsDown) + { + Result |= KeyState_WasDown; + } + return Result; +} + #define GS_INPUT_H #endif // GS_INPUT_H \ No newline at end of file diff --git a/meta/foldhaus_meta.cpp b/meta/foldhaus_meta.cpp index 0bcb718..3206405 100644 --- a/meta/foldhaus_meta.cpp +++ b/meta/foldhaus_meta.cpp @@ -192,7 +192,7 @@ MakeReadableIdentifier(string* Identifier) } internal void -GeneratePanelMetaInfo(gs_meta_preprocessor Meta, string_builder* PanelCodeGen) +GeneratePanelMetaInfo(gs_meta_preprocessor Meta, string_builder* PanelEnumGen, string_builder* PanelCodeGen) { gs_bucket Panels = {0}; @@ -217,6 +217,7 @@ GeneratePanelMetaInfo(gs_meta_preprocessor Meta, string_builder* PanelCodeGen) } } + WriteF(PanelEnumGen, "enum panel_type {\n"); WriteF(PanelCodeGen, "global_variable s32 GlobalPanelDefsCount = %d;\n", Panels.Used); WriteF(PanelCodeGen, "global_variable panel_definition GlobalPanelDefs[] = {\n"); for (u32 i = 0; i < Panels.Used; i++) @@ -249,9 +250,12 @@ GeneratePanelMetaInfo(gs_meta_preprocessor Meta, string_builder* PanelCodeGen) WriteF(PanelCodeGen, "%S_Commands, ", PanelNameBase); WriteF(PanelCodeGen, "%S_CommandsCount ", PanelNameBase); + WriteF(PanelEnumGen, "PanelType_%S,\n", PanelNameBase); + WriteF(PanelCodeGen, "},\n"); } WriteF(PanelCodeGen, "};\n"); + WriteF(PanelEnumGen, "};\n"); } internal string @@ -295,8 +299,9 @@ int main(int ArgCount, char* Args[]) string_builder CallNodeProcGen = {0}; GenerateNodeMetaInfo(&NodeTypeGen, &NodeSpecificationGen, &CallNodeProcGen, Meta); + string_builder PanelEnumGen = {0}; string_builder PanelCodeGen = {0}; - GeneratePanelMetaInfo(Meta, &PanelCodeGen); + GeneratePanelMetaInfo(Meta, &PanelEnumGen, &PanelCodeGen); string TypeInfoHFilePath = AllocAndConcatStrings(GeneratedFilesDirectory, MakeStringLiteral("gs_meta_generated_typeinfo.h")); FILE* TypeInfoH = fopen(TypeInfoHFilePath.Memory, "w"); @@ -332,6 +337,7 @@ int main(int ArgCount, char* Args[]) FILE* PanelInfoH = fopen(PanelInfoHFilePath.Memory, "w"); if (PanelInfoH) { + WriteStringBuilderToFile(PanelEnumGen, PanelInfoH); WriteStringBuilderToFile(PanelCodeGen, PanelInfoH); fclose(PanelInfoH); } diff --git a/src/foldhaus_app.cpp b/src/foldhaus_app.cpp index a15a8a7..26198c5 100644 --- a/src/foldhaus_app.cpp +++ b/src/foldhaus_app.cpp @@ -201,7 +201,7 @@ INITIALIZE_APPLICATION(InitializeApplication) InitializePanelSystem(&State->PanelSystem); panel* Panel = TakeNewPanel(&State->PanelSystem); - SetPanelDefinition(Panel, 0, State); + SetPanelDefinition(Panel, PanelType_SculptureView, State); } internal void @@ -314,16 +314,17 @@ CreateDMXBuffers(assembly Assembly, s32 BufferHeaderSize, memory_arena* Arena) UPDATE_AND_RENDER(UpdateAndRender) { DEBUG_TRACK_FUNCTION; - app_state* State = (app_state*)Context.MemoryBase; - State->WindowBounds = Context.WindowBounds; + app_state* State = (app_state*)Context->MemoryBase; + State->WindowBounds = Context->WindowBounds; // NOTE(Peter): We do this at the beginning because all the render commands are stored in Transient, // and need to persist beyond the end of the UpdateAndRender call. In the release version, we won't // zero the Transient arena when we clear it so it wouldn't be a problem, but it is technically // incorrect to clear the arena, and then access the memory later. ClearArena(&State->Transient); + Context->Mouse.CursorType = CursorType_Arrow; - HandleInput(State, State->WindowBounds, InputQueue, Mouse); + HandleInput(State, State->WindowBounds, InputQueue, Context->Mouse); if (State->AnimationSystem.TimelineShouldAdvance) { // TODO(Peter): Revisit this. This implies that the framerate of the animation system @@ -481,10 +482,10 @@ UPDATE_AND_RENDER(UpdateAndRender) send_sacn_job_data* Job = PushStruct(&State->Transient, send_sacn_job_data); Job->SendSocket = State->SACN.SendSocket; - Job->SendTo = Context.PlatformSendTo; + Job->SendTo = Context->PlatformSendTo; Job->DMXBuffers = DMXBuffers; - Context.GeneralWorkQueue->PushWorkOnQueue(Context.GeneralWorkQueue, SACNSendDMXBufferListJob, Job, "SACN Send Data Job"); + Context->GeneralWorkQueue->PushWorkOnQueue(Context->GeneralWorkQueue, SACNSendDMXBufferListJob, Job, "SACN Send Data Job"); }break; InvalidDefaultCase; @@ -495,19 +496,19 @@ UPDATE_AND_RENDER(UpdateAndRender) PushRenderClearScreen(RenderBuffer); panel_layout PanelsToRender = GetPanelLayout(&State->PanelSystem, State->WindowBounds, &State->Transient); - DrawAllPanels(PanelsToRender, RenderBuffer, Mouse, State, Context); + DrawAllPanels(PanelsToRender, RenderBuffer, &Context->Mouse, State, *Context); for (s32 m = 0; m < State->Modes.ActiveModesCount; m++) { operation_mode OperationMode = State->Modes.ActiveModes[m]; if (OperationMode.Render != 0) { - OperationMode.Render(State, RenderBuffer, OperationMode, Mouse); + OperationMode.Render(State, RenderBuffer, OperationMode, Context->Mouse); } } - Context.GeneralWorkQueue->DoQueueWorkUntilDone(Context.GeneralWorkQueue, 0); - Context.GeneralWorkQueue->ResetWorkQueue(Context.GeneralWorkQueue); + Context->GeneralWorkQueue->DoQueueWorkUntilDone(Context->GeneralWorkQueue, 0); + Context->GeneralWorkQueue->ResetWorkQueue(Context->GeneralWorkQueue); // Checking for overflows { diff --git a/src/foldhaus_interface.cpp b/src/foldhaus_interface.cpp index e43b73c..c981358 100644 --- a/src/foldhaus_interface.cpp +++ b/src/foldhaus_interface.cpp @@ -357,12 +357,12 @@ HandleMousePanelInteraction(panel_system* PanelSystem, rect WindowBounds, mouse_ } internal void -DrawPanelBorder(panel Panel, v2 PanelMin, v2 PanelMax, v4 Color, mouse_state Mouse, render_command_buffer* RenderBuffer) +DrawPanelBorder(panel Panel, v2 PanelMin, v2 PanelMax, v4 Color, mouse_state* Mouse, render_command_buffer* RenderBuffer) { - r32 MouseLeftEdgeDistance = GSAbs(Mouse.Pos.x - PanelMin.x); - r32 MouseRightEdgeDistance = GSAbs(Mouse.Pos.x - PanelMax.x); - r32 MouseTopEdgeDistance = GSAbs(Mouse.Pos.y - PanelMax.y); - r32 MouseBottomEdgeDistance = GSAbs(Mouse.Pos.y - PanelMin.y); + r32 MouseLeftEdgeDistance = GSAbs(Mouse->Pos.x - PanelMin.x); + r32 MouseRightEdgeDistance = GSAbs(Mouse->Pos.x - PanelMax.x); + r32 MouseTopEdgeDistance = GSAbs(Mouse->Pos.y - PanelMax.y); + r32 MouseBottomEdgeDistance = GSAbs(Mouse->Pos.y - PanelMin.y); PushRenderBoundingBox2D(RenderBuffer, PanelMin, PanelMax, 1, Color); v4 HighlightColor = v4{.3f, .3f, .3f, 1.f}; @@ -372,24 +372,28 @@ DrawPanelBorder(panel Panel, v2 PanelMin, v2 PanelMax, v4 Color, mouse_state Mou v2 LeftEdgeMin = PanelMin; v2 LeftEdgeMax = v2{PanelMin.x + HighlightThickness, PanelMax.y}; PushRenderQuad2D(RenderBuffer, LeftEdgeMin, LeftEdgeMax, HighlightColor); + Mouse->CursorType = CursorType_HorizontalArrows; } else if (MouseRightEdgeDistance < PANEL_EDGE_CLICK_MAX_DISTANCE) { v2 RightEdgeMin = v2{PanelMax.x - HighlightThickness, PanelMin.y}; v2 RightEdgeMax = PanelMax; PushRenderQuad2D(RenderBuffer, RightEdgeMin, RightEdgeMax, HighlightColor); + Mouse->CursorType = CursorType_HorizontalArrows; } else if (MouseTopEdgeDistance < PANEL_EDGE_CLICK_MAX_DISTANCE) { v2 TopEdgeMin = v2{PanelMin.x, PanelMax.y - HighlightThickness}; v2 TopEdgeMax = PanelMax; PushRenderQuad2D(RenderBuffer, TopEdgeMin, TopEdgeMax, HighlightColor); + Mouse->CursorType = CursorType_VerticalArrows; } else if (MouseBottomEdgeDistance < PANEL_EDGE_CLICK_MAX_DISTANCE) { v2 BottomEdgeMin = PanelMin; v2 BottomEdgeMax = v2{PanelMax.x, PanelMin.y + HighlightThickness}; PushRenderQuad2D(RenderBuffer, BottomEdgeMin, BottomEdgeMax, HighlightColor); + Mouse->CursorType = CursorType_VerticalArrows; } } @@ -466,7 +470,7 @@ RenderPanel(panel* Panel, rect PanelBounds, rect WindowBounds, render_command_bu } internal void -DrawAllPanels(panel_layout PanelLayout, render_command_buffer* RenderBuffer, mouse_state Mouse, app_state* State, context Context) +DrawAllPanels(panel_layout PanelLayout, render_command_buffer* RenderBuffer, mouse_state* Mouse, app_state* State, context Context) { for (u32 i = 0; i < PanelLayout.PanelsCount; i++) { @@ -474,7 +478,7 @@ DrawAllPanels(panel_layout PanelLayout, render_command_buffer* RenderBuffer, mou panel* Panel = PanelWithLayout.Panel; rect PanelBounds = PanelWithLayout.Bounds; - RenderPanel(Panel, PanelBounds, State->WindowBounds, RenderBuffer, State, Context, Mouse); + RenderPanel(Panel, PanelBounds, State->WindowBounds, RenderBuffer, State, Context, *Mouse); v4 BorderColor = v4{0, 0, 0, 1}; PushRenderOrthographic(RenderBuffer, State->WindowBounds.Min.x, State->WindowBounds.Min.y, State->WindowBounds.Max.x, State->WindowBounds.Max.y); diff --git a/src/foldhaus_platform.h b/src/foldhaus_platform.h index 51dcdf0..2ee07cf 100644 --- a/src/foldhaus_platform.h +++ b/src/foldhaus_platform.h @@ -34,7 +34,7 @@ typedef struct context context; #define INITIALIZE_APPLICATION(name) void name(context Context) typedef INITIALIZE_APPLICATION(initialize_application); -#define UPDATE_AND_RENDER(name) void name(context Context, input_queue InputQueue, mouse_state Mouse, render_command_buffer* RenderBuffer) +#define UPDATE_AND_RENDER(name) void name(context* Context, input_queue InputQueue, render_command_buffer* RenderBuffer) typedef UPDATE_AND_RENDER(update_and_render); #define RELOAD_STATIC_DATA(name) void name(context Context, debug_services* DebugServices) @@ -244,6 +244,7 @@ struct context b32 WindowIsVisible; rect WindowBounds; r32 DeltaTime; + mouse_state Mouse; // Application Services initialize_application* InitializeApplication; diff --git a/src/generated/foldhaus_panels_generated.h b/src/generated/foldhaus_panels_generated.h index b4fcb6c..48610ca 100644 --- a/src/generated/foldhaus_panels_generated.h +++ b/src/generated/foldhaus_panels_generated.h @@ -1,3 +1,12 @@ +enum panel_type { +PanelType_FileView, +PanelType_SculptureView, +PanelType_AnimationTimeline, +PanelType_DMXView, +PanelType_HierarchyView, +PanelType_NodeGraph, +PanelType_ProfilerView, +}; global_variable s32 GlobalPanelDefsCount = 7; global_variable panel_definition GlobalPanelDefs[] = { { "File View", 9, FileView_Init, FileView_Cleanup, FileView_Render, FileView_Commands, FileView_CommandsCount }, diff --git a/src/win32_foldhaus.cpp b/src/win32_foldhaus.cpp index 22ad949..cf2f5c1 100644 --- a/src/win32_foldhaus.cpp +++ b/src/win32_foldhaus.cpp @@ -560,6 +560,23 @@ Win32GetThreadId() return Result; } +// NOTE(Peter): Only meant to take one of the values specified below: +// IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, IDC_HELP, IDC_IBEAM, +// IDC_ICON, IDC_NO, IDC_SIZE, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE, +// IDC_SIZEWE, IDC_UPARROW, IDC_WAIT +internal HCURSOR +Win32LoadSystemCursor(char* CursorIdentifier) +{ + u32 Error = 0; + HCURSOR Result = LoadCursorA(NULL, CursorIdentifier); + if (Result == NULL) + { + Error = GetLastError(); + InvalidCodePath; + } + return Result; +} + int WINAPI WinMain ( HINSTANCE HInstance, @@ -592,14 +609,11 @@ WinMain ( Win32GetThreadId, DebugThreadCount); - mouse_state Mouse; input_queue InputQueue; { s32 InputQueueMemorySize = sizeof(input_entry) * 32; u8* InputQueueMemory = Win32Alloc(InputQueueMemorySize); InputQueue = InitializeInputQueue(InputQueueMemory, InputQueueMemorySize); - - Mouse = {0, 0}; } // @@ -636,6 +650,16 @@ WinMain ( Context.MemorySize = InitialMemorySize; Context.MemoryBase = InitialMemory; Context.WindowBounds = rect{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}}; + Context.Mouse = {0}; + + // Cursors + HCURSOR CursorArrow = Win32LoadSystemCursor(IDC_ARROW); + HCURSOR CursorPointer = Win32LoadSystemCursor(IDC_HAND); + HCURSOR CursorLoading = Win32LoadSystemCursor(IDC_WAIT); + HCURSOR CursorHorizontalArrows = Win32LoadSystemCursor(IDC_SIZEWE); + HCURSOR CursorVerticalArrows = Win32LoadSystemCursor(IDC_SIZENS); + HCURSOR CursorDiagonalTopLeftArrows = Win32LoadSystemCursor(IDC_SIZENWSE); + HCURSOR CursorDiagonalTopRightArrows = Win32LoadSystemCursor(IDC_SIZENESW); // Platform functions Context.GeneralWorkQueue = &WorkQueue; @@ -696,17 +720,17 @@ WinMain ( GetCursorPos (&MousePos); ScreenToClient(MainWindow.Handle, &MousePos); - Mouse.Scroll = 0; - Mouse.OldPos = Mouse.Pos; - Mouse.Pos = v2{(r32)MousePos.x, (r32)MainWindow.Height - MousePos.y}; - Mouse.DeltaPos = Mouse.Pos - Mouse.OldPos; + Context.Mouse.Scroll = 0; + Context.Mouse.OldPos = Context.Mouse.Pos; + Context.Mouse.Pos = v2{(r32)MousePos.x, (r32)MainWindow.Height - MousePos.y}; + Context.Mouse.DeltaPos = Context.Mouse.Pos - Context.Mouse.OldPos; } MSG Message; while (PeekMessageA(&Message, MainWindow.Handle, 0, 0, PM_REMOVE)) { DEBUG_TRACK_SCOPE(PeekWindowsMessages); - HandleWindowMessage(Message, &MainWindow, &InputQueue, &Mouse); + HandleWindowMessage(Message, &MainWindow, &InputQueue, &Context.Mouse); } Context.WindowBounds = rect{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}}; @@ -714,40 +738,46 @@ WinMain ( RenderBuffer.ViewHeight = MainWindow.Height; Context.DeltaTime = LastFrameSecondsElapsed; - Context.UpdateAndRender(Context, InputQueue, Mouse, &RenderBuffer); + Context.UpdateAndRender(&Context, InputQueue, &RenderBuffer); RenderCommandBuffer(RenderBuffer); ClearRenderBuffer(&RenderBuffer); + Context.Mouse.LeftButtonState = GetMouseButtonStateAdvanced(Context.Mouse.LeftButtonState); + Context.Mouse.MiddleButtonState = GetMouseButtonStateAdvanced(Context.Mouse.MiddleButtonState); + Context.Mouse.RightButtonState = GetMouseButtonStateAdvanced(Context.Mouse.RightButtonState); - if (Mouse.LeftButtonState & KeyState_WasDown && - !((Mouse.LeftButtonState & KeyState_IsDown) > 0)) + switch (Context.Mouse.CursorType) { - Mouse.LeftButtonState = 0; - } - else if (Mouse.LeftButtonState & KeyState_IsDown) - { - Mouse.LeftButtonState |= KeyState_WasDown; - } - - if (Mouse.MiddleButtonState & KeyState_WasDown && - !((Mouse.MiddleButtonState & KeyState_IsDown) > 0)) - { - Mouse.MiddleButtonState = 0; - } - else if (Mouse.MiddleButtonState & KeyState_IsDown) - { - Mouse.MiddleButtonState |= KeyState_WasDown; - } - - if (Mouse.RightButtonState & KeyState_WasDown && - !((Mouse.RightButtonState & KeyState_IsDown) > 0)) - { - Mouse.RightButtonState = 0; - } - else if (Mouse.RightButtonState & KeyState_IsDown) - { - Mouse.RightButtonState |= KeyState_WasDown; + case CursorType_Arrow: + { + SetCursor(CursorArrow); + }break; + case CursorType_Pointer: + { + SetCursor(CursorPointer); + }break; + case CursorType_Loading: + { + SetCursor(CursorLoading); + }break; + case CursorType_HorizontalArrows: + { + SetCursor(CursorHorizontalArrows); + }break; + case CursorType_VerticalArrows: + { + SetCursor(CursorVerticalArrows); + }break; + case CursorType_DiagonalTopLeftArrows: + { + SetCursor(CursorDiagonalTopLeftArrows); + }break; + case CursorType_DiagonalTopRightArrows: + { + SetCursor(CursorDiagonalTopRightArrows); + }break; + InvalidDefaultCase; } HDC DeviceContext = GetDC(MainWindow.Handle);