Metaprocessor now generates an enum of panel types, app now passes a cursor type out to the platform layer, which handles setting the cursor style.

This commit is contained in:
Peter Slattery 2020-03-12 22:42:59 -07:00
parent 27c0c5e16f
commit f461ee2044
7 changed files with 137 additions and 56 deletions

View File

@ -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

View File

@ -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<panel_elements> 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);
}

View File

@ -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
{

View File

@ -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);

View File

@ -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;

View File

@ -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 },

View File

@ -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)
case CursorType_Arrow:
{
Mouse.LeftButtonState |= KeyState_WasDown;
}
if (Mouse.MiddleButtonState & KeyState_WasDown &&
!((Mouse.MiddleButtonState & KeyState_IsDown) > 0))
SetCursor(CursorArrow);
}break;
case CursorType_Pointer:
{
Mouse.MiddleButtonState = 0;
}
else if (Mouse.MiddleButtonState & KeyState_IsDown)
SetCursor(CursorPointer);
}break;
case CursorType_Loading:
{
Mouse.MiddleButtonState |= KeyState_WasDown;
}
if (Mouse.RightButtonState & KeyState_WasDown &&
!((Mouse.RightButtonState & KeyState_IsDown) > 0))
SetCursor(CursorLoading);
}break;
case CursorType_HorizontalArrows:
{
Mouse.RightButtonState = 0;
}
else if (Mouse.RightButtonState & KeyState_IsDown)
SetCursor(CursorHorizontalArrows);
}break;
case CursorType_VerticalArrows:
{
Mouse.RightButtonState |= KeyState_WasDown;
SetCursor(CursorVerticalArrows);
}break;
case CursorType_DiagonalTopLeftArrows:
{
SetCursor(CursorDiagonalTopLeftArrows);
}break;
case CursorType_DiagonalTopRightArrows:
{
SetCursor(CursorDiagonalTopRightArrows);
}break;
InvalidDefaultCase;
}
HDC DeviceContext = GetDC(MainWindow.Handle);