refactored panel sytstem
This commit is contained in:
parent
a88d675327
commit
57f144ea64
|
@ -0,0 +1,107 @@
|
||||||
|
//
|
||||||
|
// File: foldhaus_editor.cpp
|
||||||
|
// Author: Peter Slattery
|
||||||
|
// Creation Date: 2020-10-24
|
||||||
|
//
|
||||||
|
#ifndef FOLDHAUS_EDITOR_CPP
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Editor_HandleInput (app_state* State, rect2 WindowBounds, input_queue InputQueue, mouse_state Mouse, context Context)
|
||||||
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
|
b32 PanelSystemHandledInput = HandleMousePanelInteraction(&State->PanelSystem, State->WindowBounds, Mouse, State);
|
||||||
|
|
||||||
|
if (!PanelSystemHandledInput)
|
||||||
|
{
|
||||||
|
input_command_registry ActiveCommands = {};
|
||||||
|
if (State->Modes.ActiveModesCount > 0)
|
||||||
|
{
|
||||||
|
ActiveCommands = State->Modes.ActiveModes[State->Modes.ActiveModesCount - 1].Commands;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
panel* PanelWithMouseOverIt = GetPanelContainingPoint(Mouse.Pos, State->PanelSystem.Panels + 0);
|
||||||
|
if (!PanelWithMouseOverIt) { return; }
|
||||||
|
State->HotPanel = PanelWithMouseOverIt;
|
||||||
|
|
||||||
|
s32 PanelTypeIndex = PanelWithMouseOverIt->TypeIndex;
|
||||||
|
panel_definition PanelDefinition = GlobalPanelDefs[PanelTypeIndex];
|
||||||
|
if (!PanelDefinition.InputCommands) { return; }
|
||||||
|
|
||||||
|
ActiveCommands.Commands = PanelDefinition.InputCommands;
|
||||||
|
ActiveCommands.Size = sizeof(*PanelDefinition.InputCommands) / sizeof(PanelDefinition.InputCommands[0]);
|
||||||
|
ActiveCommands.Used = ActiveCommands.Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (s32 EventIdx = 0; EventIdx < InputQueue.QueueUsed; EventIdx++)
|
||||||
|
{
|
||||||
|
input_entry Event = InputQueue.Entries[EventIdx];
|
||||||
|
|
||||||
|
// NOTE(Peter): These are in the order Down, Up, Held because we want to privalege
|
||||||
|
// Down and Up over Held. In other words, we don't want to call a Held command on the
|
||||||
|
// frame when the button was released, even if the command is registered to both events
|
||||||
|
if (KeyTransitionedDown(Event))
|
||||||
|
{
|
||||||
|
FindAndPushExistingCommand(ActiveCommands, Event, Command_Began, &State->CommandQueue);
|
||||||
|
}
|
||||||
|
else if (KeyTransitionedUp(Event))
|
||||||
|
{
|
||||||
|
FindAndPushExistingCommand(ActiveCommands, Event, Command_Ended, &State->CommandQueue);
|
||||||
|
}
|
||||||
|
else if (KeyHeldDown(Event))
|
||||||
|
{
|
||||||
|
FindAndPushExistingCommand(ActiveCommands, Event, Command_Held, &State->CommandQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute all commands in CommandQueue
|
||||||
|
for (s32 CommandIdx = State->CommandQueue.Used - 1; CommandIdx >= 0; CommandIdx--)
|
||||||
|
{
|
||||||
|
command_queue_entry* Entry = &State->CommandQueue.Commands[CommandIdx];
|
||||||
|
Entry->Command.Proc(State, Entry->Event, Mouse, Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearCommandQueue(&State->CommandQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Editor_Update(app_state* State, context* Context, input_queue InputQueue)
|
||||||
|
{
|
||||||
|
Context->Mouse.CursorType = CursorType_Arrow;
|
||||||
|
State->WindowBounds = Context->WindowBounds;
|
||||||
|
State->Interface.Mouse = Context->Mouse;
|
||||||
|
State->Camera.AspectRatio = RectAspectRatio(Context->WindowBounds);
|
||||||
|
|
||||||
|
PanelSystem_UpdateLayout(&State->PanelSystem, State->WindowBounds);
|
||||||
|
Editor_HandleInput(State, State->WindowBounds, InputQueue, Context->Mouse, *Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Editor_Render(app_state* State, context* Context, render_command_buffer* RenderBuffer)
|
||||||
|
{
|
||||||
|
PushRenderOrthographic(RenderBuffer, State->WindowBounds);
|
||||||
|
PushRenderClearScreen(RenderBuffer);
|
||||||
|
|
||||||
|
State->Interface.RenderBuffer = RenderBuffer;
|
||||||
|
|
||||||
|
DrawAllPanels(State->PanelSystem, 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, Context->Mouse, *Context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context->GeneralWorkQueue->CompleteQueueWork(Context->GeneralWorkQueue, Context->ThreadContext);
|
||||||
|
Context->GeneralWorkQueue->ResetWorkQueue(Context->GeneralWorkQueue);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define FOLDHAUS_EDITOR_CPP
|
||||||
|
#endif // FOLDHAUS_EDITOR_CPP
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
enum panel_edit_mode
|
enum panel_edit_mode
|
||||||
{
|
{
|
||||||
|
PanelEdit_Invalid,
|
||||||
|
|
||||||
PanelEdit_Modify,
|
PanelEdit_Modify,
|
||||||
PanelEdit_Destroy,
|
PanelEdit_Destroy,
|
||||||
|
|
||||||
|
@ -111,6 +113,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Panel->SplitPercent = (NewSplitY - PanelBounds.Min.y) / Rect2Height(PanelBounds);
|
Panel->SplitPercent = (NewSplitY - PanelBounds.Min.y) / Rect2Height(PanelBounds);
|
||||||
|
Panel_UpdateLayout(Panel, PanelBounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
||||||
|
@ -127,6 +130,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndDragPanelBorderOperation)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Panel->SplitPercent = (NewSplitX - PanelBounds.Min.x) / Rect2Width(PanelBounds);
|
Panel->SplitPercent = (NewSplitX - PanelBounds.Min.x) / Rect2Width(PanelBounds);
|
||||||
|
Panel_UpdateLayout(Panel, PanelBounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,9 +243,9 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndSplitPanelOperation)
|
||||||
|
|
||||||
s32 PanelTypeIndex = Panel->TypeIndex;
|
s32 PanelTypeIndex = Panel->TypeIndex;
|
||||||
gs_data PanelStateMemory = Panel->StateMemory;
|
gs_data PanelStateMemory = Panel->StateMemory;
|
||||||
Panel_SetCurrentType(&Panel->Left->Panel, &State->PanelSystem, PanelTypeIndex, PanelStateMemory, State, Context);
|
Panel_SetCurrentType(Panel->Left, &State->PanelSystem, PanelTypeIndex, PanelStateMemory, State, Context);
|
||||||
|
|
||||||
SetAndInitPanelType(&Panel->Right->Panel, &State->PanelSystem, PanelTypeIndex, State, Context);
|
SetAndInitPanelType(Panel->Right, &State->PanelSystem, PanelTypeIndex, State, Context);
|
||||||
|
|
||||||
DeactivateCurrentOperationMode(&State->Modes);
|
DeactivateCurrentOperationMode(&State->Modes);
|
||||||
}
|
}
|
||||||
|
@ -251,12 +255,12 @@ input_command SplitPanelCommands[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
BeginSplitPanelOperation(panel* Panel, rect2 PanelBounds, mouse_state Mouse, app_state* State)
|
BeginSplitPanelOperation(panel* Panel, mouse_state Mouse, app_state* State)
|
||||||
{
|
{
|
||||||
operation_mode* SplitPanel = ActivateOperationModeWithCommands(&State->Modes, SplitPanelCommands, UpdateAndRenderSplitPanel);
|
operation_mode* SplitPanel = ActivateOperationModeWithCommands(&State->Modes, SplitPanelCommands, UpdateAndRenderSplitPanel);
|
||||||
split_panel_operation_state* OpState = CreateOperationState(SplitPanel, &State->Modes, split_panel_operation_state);
|
split_panel_operation_state* OpState = CreateOperationState(SplitPanel, &State->Modes, split_panel_operation_state);
|
||||||
OpState->Panel = Panel;
|
OpState->Panel = Panel;
|
||||||
OpState->InitialPanelBounds = PanelBounds;
|
OpState->InitialPanelBounds = Panel->Bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -265,61 +269,44 @@ BeginSplitPanelOperation(panel* Panel, rect2 PanelBounds, mouse_state Mouse, app
|
||||||
#define PANEL_EDGE_CLICK_MAX_DISTANCE 6
|
#define PANEL_EDGE_CLICK_MAX_DISTANCE 6
|
||||||
|
|
||||||
internal b32
|
internal b32
|
||||||
HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEditMode, rect2 PanelBounds, mouse_state Mouse, app_state* State)
|
HandleMouseDownPanelInteractionOrRecurse(panel* Panel, panel_edit_mode PanelEditMode, mouse_state Mouse, app_state* State)
|
||||||
{
|
{
|
||||||
b32 HandledMouseInput = false;
|
b32 HandledMouseInput = false;
|
||||||
|
|
||||||
rect2 PanelSplitButtonBounds = rect2{ PanelBounds.Min, PanelBounds.Min + v2{25, 25} };
|
// TODO(pjs): this can probably live in panel_with_layout
|
||||||
|
rect2 PanelSplitButtonBounds = rect2{ Panel->Bounds.Min, Panel->Bounds.Min + v2{25, 25} };
|
||||||
|
|
||||||
if (Panel->SplitDirection == PanelSplit_NoSplit
|
if (Panel->SplitDirection == PanelSplit_NoSplit
|
||||||
&& PointIsInRect(PanelSplitButtonBounds, Mouse.DownPos))
|
&& PointIsInRect(PanelSplitButtonBounds, Mouse.DownPos))
|
||||||
{
|
{
|
||||||
BeginSplitPanelOperation(Panel, PanelBounds, Mouse, State);
|
BeginSplitPanelOperation(Panel, Mouse, State);
|
||||||
HandledMouseInput = true;
|
HandledMouseInput = true;
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
else if (Panel->SplitDirection != PanelSplit_NoSplit)
|
||||||
{
|
{
|
||||||
r32 SplitY = LerpR32(Panel->SplitPercent, PanelBounds.Min.y, PanelBounds.Max.y);
|
u32 ElementIndex = 0;
|
||||||
r32 ClickDistanceFromSplit = Abs(Mouse.DownPos.y - SplitY);
|
switch(Panel->SplitDirection)
|
||||||
|
{
|
||||||
|
case PanelSplit_Vertical: { ElementIndex = 0; } break;
|
||||||
|
case PanelSplit_Horizontal: { ElementIndex = 1; } break;
|
||||||
|
InvalidDefaultCase;
|
||||||
|
}
|
||||||
|
|
||||||
|
r32 SplitPosition = LerpR32(Panel->SplitPercent, Panel->Bounds.Min.E[ElementIndex], Panel->Bounds.Max.E[ElementIndex]);
|
||||||
|
r32 ClickDistanceFromSplit = Abs(Mouse.DownPos.E[ElementIndex] - SplitPosition);
|
||||||
if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE)
|
if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE)
|
||||||
{
|
{
|
||||||
BeginDragPanelBorder(Panel, PanelEditMode, PanelBounds, PanelSplit_Horizontal, Mouse, State);
|
BeginDragPanelBorder(Panel, PanelEditMode, Panel->Bounds, Panel->SplitDirection, Mouse, State);
|
||||||
HandledMouseInput = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rect2 TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
if (PointIsInRect(Panel->Bottom->Bounds, Mouse.DownPos))
|
||||||
rect2 BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
|
||||||
if (PointIsInRect(BottomPanelBounds, Mouse.DownPos))
|
|
||||||
{
|
{
|
||||||
HandleMouseDownPanelInteractionOrRecurse(&Panel->Bottom->Panel, PanelEditMode, BottomPanelBounds, Mouse, State);
|
HandleMouseDownPanelInteractionOrRecurse(Panel->Bottom, PanelEditMode, Mouse, State);
|
||||||
}
|
}
|
||||||
if (PointIsInRect(TopPanelBounds, Mouse.DownPos))
|
else if (PointIsInRect(Panel->Top->Bounds, Mouse.DownPos))
|
||||||
{
|
{
|
||||||
HandleMouseDownPanelInteractionOrRecurse(&Panel->Top->Panel, PanelEditMode, TopPanelBounds, Mouse, State);
|
HandleMouseDownPanelInteractionOrRecurse(Panel->Top, PanelEditMode, Mouse, State);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
|
||||||
{
|
|
||||||
r32 SplitX = LerpR32(Panel->SplitPercent, PanelBounds.Min.x, PanelBounds.Max.x);
|
|
||||||
r32 ClickDistanceFromSplit = Abs(Mouse.DownPos.x - SplitX);
|
|
||||||
if (ClickDistanceFromSplit < PANEL_EDGE_CLICK_MAX_DISTANCE)
|
|
||||||
{
|
|
||||||
BeginDragPanelBorder(Panel, PanelEditMode, PanelBounds, PanelSplit_Vertical, Mouse, State);
|
|
||||||
HandledMouseInput = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
|
||||||
rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
|
||||||
if (PointIsInRect(LeftPanelBounds, Mouse.DownPos))
|
|
||||||
{
|
|
||||||
HandleMouseDownPanelInteractionOrRecurse(&Panel->Left->Panel, PanelEditMode, LeftPanelBounds, Mouse, State);
|
|
||||||
}
|
|
||||||
if (PointIsInRect(RightPanelBounds, Mouse.DownPos))
|
|
||||||
{
|
|
||||||
HandleMouseDownPanelInteractionOrRecurse(&Panel->Right->Panel, PanelEditMode, RightPanelBounds, Mouse, State);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,14 +319,21 @@ HandleMousePanelInteraction(panel_system* PanelSystem, rect2 WindowBounds, mouse
|
||||||
{
|
{
|
||||||
b32 HandledMouseInput = false;
|
b32 HandledMouseInput = false;
|
||||||
|
|
||||||
panel* FirstPanel = &PanelSystem->Panels[0].Panel;
|
panel* FirstPanel = PanelSystem->Panels + 0;
|
||||||
|
panel_edit_mode EditMode = PanelEdit_Invalid;
|
||||||
|
|
||||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
if (MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
||||||
{
|
{
|
||||||
HandledMouseInput = HandleMouseDownPanelInteractionOrRecurse(FirstPanel, PanelEdit_Modify, WindowBounds, Mouse, State);
|
EditMode = PanelEdit_Modify;
|
||||||
}
|
}
|
||||||
else if (MouseButtonTransitionedDown(Mouse.RightButtonState))
|
else if (MouseButtonTransitionedDown(Mouse.RightButtonState))
|
||||||
{
|
{
|
||||||
HandledMouseInput = HandleMouseDownPanelInteractionOrRecurse(FirstPanel, PanelEdit_Destroy, WindowBounds, Mouse, State);
|
EditMode = PanelEdit_Destroy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EditMode != PanelEdit_Invalid)
|
||||||
|
{
|
||||||
|
HandledMouseInput = HandleMouseDownPanelInteractionOrRecurse(FirstPanel, EditMode, Mouse, State);
|
||||||
}
|
}
|
||||||
|
|
||||||
return HandledMouseInput;
|
return HandledMouseInput;
|
||||||
|
@ -456,21 +450,36 @@ RenderPanel(panel* Panel, rect2 PanelBounds, rect2 WindowBounds, render_command_
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
DrawAllPanels(panel_layout PanelLayout, render_command_buffer* RenderBuffer, mouse_state* Mouse, app_state* State, context Context)
|
DrawPanelRecursive(panel* Panel, render_command_buffer* RenderBuffer, mouse_state* Mouse, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < PanelLayout.PanelsCount; i++)
|
switch (Panel->SplitDirection)
|
||||||
{
|
{
|
||||||
panel_with_layout PanelWithLayout = PanelLayout.Panels[i];
|
case PanelSplit_Horizontal:
|
||||||
panel* Panel = PanelWithLayout.Panel;
|
case PanelSplit_Vertical:
|
||||||
rect2 PanelBounds = PanelWithLayout.Bounds;
|
{
|
||||||
|
DrawPanelRecursive(Panel->Left, RenderBuffer, Mouse, State, Context);
|
||||||
|
DrawPanelRecursive(Panel->Right, RenderBuffer, Mouse, State, Context);
|
||||||
|
}break;
|
||||||
|
|
||||||
RenderPanel(Panel, PanelBounds, State->WindowBounds, RenderBuffer, State, Context, *Mouse);
|
case PanelSplit_NoSplit:
|
||||||
|
{
|
||||||
|
RenderPanel(Panel, Panel->Bounds, State->WindowBounds, RenderBuffer, State, Context, *Mouse);
|
||||||
v4 BorderColor = v4{0, 0, 0, 1};
|
v4 BorderColor = v4{0, 0, 0, 1};
|
||||||
|
|
||||||
PushRenderOrthographic(RenderBuffer, State->WindowBounds);
|
PushRenderOrthographic(RenderBuffer, State->WindowBounds);
|
||||||
DrawPanelBorder(*Panel, PanelBounds.Min, PanelBounds.Max, BorderColor, Mouse, RenderBuffer);
|
DrawPanelBorder(*Panel, Panel->Bounds.Min, Panel->Bounds.Max, BorderColor, Mouse, RenderBuffer);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
InvalidDefaultCase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
DrawAllPanels(panel_system System, render_command_buffer* RenderBuffer, mouse_state* Mouse, app_state* State, context Context)
|
||||||
|
{
|
||||||
|
panel* PanelAt = System.Panels + 0;
|
||||||
|
DrawPanelRecursive(PanelAt, RenderBuffer, Mouse, State, Context);
|
||||||
|
}
|
||||||
|
|
||||||
#define FOLDHAUS_INTERFACE_CPP
|
#define FOLDHAUS_INTERFACE_CPP
|
||||||
#endif // FOLDHAUS_INTERFACE_CPP
|
#endif // FOLDHAUS_INTERFACE_CPP
|
|
@ -18,7 +18,6 @@ enum panel_split_direction
|
||||||
PanelSplit_Count,
|
PanelSplit_Count,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct panel_entry panel_entry;
|
|
||||||
typedef struct panel panel;
|
typedef struct panel panel;
|
||||||
|
|
||||||
#define PANEL_MODAL_OVERRIDE_CALLBACK(name) void name(panel* ReturningFrom, app_state* State, context Context)
|
#define PANEL_MODAL_OVERRIDE_CALLBACK(name) void name(panel* ReturningFrom, app_state* State, context Context)
|
||||||
|
@ -29,10 +28,11 @@ struct panel
|
||||||
s32 TypeIndex;
|
s32 TypeIndex;
|
||||||
gs_data StateMemory;
|
gs_data StateMemory;
|
||||||
|
|
||||||
panel_entry* ModalOverride;
|
panel* ModalOverride;
|
||||||
panel* IsModalOverrideFor; // TODO(pjs): I don't like that this is panel* but ModalOverride is panel_entry*
|
panel* IsModalOverrideFor;
|
||||||
panel_modal_override_callback* ModalOverrideCB;
|
panel_modal_override_callback* ModalOverrideCB;
|
||||||
|
|
||||||
|
rect2 Bounds;
|
||||||
panel_split_direction SplitDirection;
|
panel_split_direction SplitDirection;
|
||||||
r32 SplitPercent;
|
r32 SplitPercent;
|
||||||
|
|
||||||
|
@ -40,25 +40,21 @@ struct panel
|
||||||
// Probably belongs in a more generalized PanelInterfaceState or something
|
// Probably belongs in a more generalized PanelInterfaceState or something
|
||||||
b32 PanelSelectionMenuOpen;
|
b32 PanelSelectionMenuOpen;
|
||||||
|
|
||||||
|
panel* Parent;
|
||||||
|
|
||||||
union{
|
union{
|
||||||
panel_entry* Left;
|
panel* Left;
|
||||||
panel_entry* Top;
|
panel* Top;
|
||||||
};
|
};
|
||||||
union{
|
union{
|
||||||
panel_entry* Right;
|
panel* Right;
|
||||||
panel_entry* Bottom;
|
panel* Bottom;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct free_panel
|
struct free_panel
|
||||||
{
|
{
|
||||||
panel_entry* Next;
|
free_panel* Next;
|
||||||
};
|
|
||||||
|
|
||||||
struct panel_entry
|
|
||||||
{
|
|
||||||
panel Panel;
|
|
||||||
free_panel Free;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PANEL_INIT_PROC(name) void name(panel* Panel, app_state* State, context Context)
|
#define PANEL_INIT_PROC(name) void name(panel* Panel, app_state* State, context Context)
|
||||||
|
@ -88,26 +84,10 @@ struct panel_system
|
||||||
panel_definition* PanelDefs;
|
panel_definition* PanelDefs;
|
||||||
u32 PanelDefsCount;
|
u32 PanelDefsCount;
|
||||||
|
|
||||||
panel_entry Panels[PANELS_MAX];
|
panel Panels[PANELS_MAX];
|
||||||
u32 PanelsUsed;
|
u32 PanelsUsed;
|
||||||
|
|
||||||
panel_entry FreeList;
|
free_panel* FreeList;
|
||||||
};
|
|
||||||
|
|
||||||
// NOTE(Peter): This representation is used to let external code render and interact
|
|
||||||
// with panels. It shouldn't be stored across frame boundaries as the pointers to
|
|
||||||
// Panel's are liable to change.
|
|
||||||
struct panel_with_layout
|
|
||||||
{
|
|
||||||
panel* Panel;
|
|
||||||
rect2 Bounds;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct panel_layout
|
|
||||||
{
|
|
||||||
panel_with_layout* Panels;
|
|
||||||
u32 PanelsCount;
|
|
||||||
u32 PanelsMax;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
@ -119,19 +99,20 @@ struct panel_layout
|
||||||
internal void
|
internal void
|
||||||
InitializePanelSystem(panel_system* PanelSystem, panel_definition* PanelDefs, u32 PanelDefsCount)
|
InitializePanelSystem(panel_system* PanelSystem, panel_definition* PanelDefs, u32 PanelDefsCount)
|
||||||
{
|
{
|
||||||
PanelSystem->FreeList.Free.Next = &PanelSystem->FreeList;
|
PanelSystem->FreeList = 0;
|
||||||
PanelSystem->PanelDefs = PanelDefs;
|
PanelSystem->PanelDefs = PanelDefs;
|
||||||
PanelSystem->PanelDefsCount = PanelDefsCount;
|
PanelSystem->PanelDefsCount = PanelDefsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal panel_entry*
|
internal panel*
|
||||||
TakeNewPanelEntry(panel_system* PanelSystem)
|
TakeNewPanelEntry(panel_system* PanelSystem)
|
||||||
{
|
{
|
||||||
panel_entry* FreeEntry = 0;
|
panel* FreeEntry = 0;
|
||||||
if (PanelSystem->FreeList.Free.Next != &PanelSystem->FreeList)
|
if (PanelSystem->FreeList != 0)
|
||||||
{
|
{
|
||||||
FreeEntry = PanelSystem->FreeList.Free.Next;
|
free_panel* FreePanel = PanelSystem->FreeList;
|
||||||
PanelSystem->FreeList.Free.Next = FreeEntry->Free.Next;
|
PanelSystem->FreeList = FreePanel->Next;
|
||||||
|
FreeEntry = (panel*)PanelSystem->FreeList;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -142,43 +123,24 @@ TakeNewPanelEntry(panel_system* PanelSystem)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
FreePanelEntry(panel_entry* Entry, panel_system* PanelSystem)
|
FreePanelEntry(panel* Panel, panel_system* PanelSystem)
|
||||||
{
|
{
|
||||||
Assert(Entry >= PanelSystem->Panels && Entry <= PanelSystem->Panels + PANELS_MAX);
|
Assert(Panel >= PanelSystem->Panels && Panel <= PanelSystem->Panels + PANELS_MAX);
|
||||||
Entry->Panel = {0};
|
|
||||||
Entry->Free.Next = PanelSystem->FreeList.Free.Next;
|
free_panel* FreeEntry = (free_panel*)Panel;
|
||||||
PanelSystem->FreeList.Free.Next = Entry;
|
FreeEntry->Next = PanelSystem->FreeList;
|
||||||
|
PanelSystem->FreeList = FreeEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
FreePanelEntryRecursive(panel_entry* Entry, panel_system* PanelSystem)
|
FreePanelEntryRecursive(panel* Panel, panel_system* PanelSystem)
|
||||||
{
|
{
|
||||||
if (Entry->Panel.SplitDirection != PanelSplit_NoSplit)
|
if (Panel->SplitDirection != PanelSplit_NoSplit)
|
||||||
{
|
{
|
||||||
FreePanelEntryRecursive(Entry->Panel.Left, PanelSystem);
|
FreePanelEntryRecursive(Panel->Left, PanelSystem);
|
||||||
FreePanelEntryRecursive(Entry->Panel.Right, PanelSystem);
|
FreePanelEntryRecursive(Panel->Right, PanelSystem);
|
||||||
}
|
}
|
||||||
FreePanelEntry(Entry, PanelSystem);
|
FreePanelEntry(Panel, PanelSystem);
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
FreePanelAtIndex(s32 Index, panel_system* PanelSystem)
|
|
||||||
{
|
|
||||||
Assert(Index > 0 && Index < (s32)PanelSystem->PanelsUsed);
|
|
||||||
panel_entry* EntryToFree = PanelSystem->Panels + Index;
|
|
||||||
EntryToFree->Free.Next = PanelSystem->FreeList.Free.Next;
|
|
||||||
PanelSystem->FreeList.Free.Next = EntryToFree;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal panel_entry*
|
|
||||||
Panel_GetModalOverride(panel_entry* PanelEntry)
|
|
||||||
{
|
|
||||||
panel_entry* Result = PanelEntry;
|
|
||||||
if (PanelEntry->Panel.ModalOverride != 0)
|
|
||||||
{
|
|
||||||
Result = Panel_GetModalOverride(PanelEntry->Panel.ModalOverride);
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal panel*
|
internal panel*
|
||||||
|
@ -187,17 +149,17 @@ Panel_GetModalOverride(panel* Panel)
|
||||||
panel* Result = Panel;
|
panel* Result = Panel;
|
||||||
if (Panel->ModalOverride != 0)
|
if (Panel->ModalOverride != 0)
|
||||||
{
|
{
|
||||||
Result = &Panel_GetModalOverride(Panel->ModalOverride)->Panel;
|
Result = Panel_GetModalOverride(Panel->ModalOverride);
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Panel_PushModalOverride(panel* Root, panel_entry* Override, panel_modal_override_callback* Callback)
|
Panel_PushModalOverride(panel* Root, panel* Override, panel_modal_override_callback* Callback)
|
||||||
{
|
{
|
||||||
Root->ModalOverride = Override;
|
Root->ModalOverride = Override;
|
||||||
Root->ModalOverrideCB = Callback;
|
Root->ModalOverrideCB = Callback;
|
||||||
Override->Panel.IsModalOverrideFor = Root;
|
Override->IsModalOverrideFor = Root;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -239,12 +201,12 @@ Panel_GetStateMemory(panel* Panel, u64 Size)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal panel_entry*
|
internal panel*
|
||||||
PanelSystem_PushPanel(panel_system* PanelSystem, s32 PanelTypeIndex, app_state* State, context Context)
|
PanelSystem_PushPanel(panel_system* PanelSystem, s32 PanelTypeIndex, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
panel_entry* PanelEntry = TakeNewPanelEntry(PanelSystem);
|
panel* Panel = TakeNewPanelEntry(PanelSystem);
|
||||||
SetAndInitPanelType(&PanelEntry->Panel, PanelSystem, PanelTypeIndex, State, Context);
|
SetAndInitPanelType(Panel, PanelSystem, PanelTypeIndex, State, Context);
|
||||||
return PanelEntry;
|
return Panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -257,11 +219,14 @@ SplitPanel(panel* Parent, r32 Percent, panel_split_direction SplitDirection, pan
|
||||||
|
|
||||||
s32 ParentTypeIndex = Parent->TypeIndex;
|
s32 ParentTypeIndex = Parent->TypeIndex;
|
||||||
gs_data ParentStateMemory = Parent->StateMemory;
|
gs_data ParentStateMemory = Parent->StateMemory;
|
||||||
|
|
||||||
Parent->Left = TakeNewPanelEntry(PanelSystem);
|
Parent->Left = TakeNewPanelEntry(PanelSystem);
|
||||||
Panel_SetCurrentType(&Parent->Left->Panel, PanelSystem, ParentTypeIndex, ParentStateMemory, State, Context);
|
Panel_SetCurrentType(Parent->Left, PanelSystem, ParentTypeIndex, ParentStateMemory, State, Context);
|
||||||
|
Parent->Left->Parent = Parent;
|
||||||
|
|
||||||
Parent->Right = TakeNewPanelEntry(PanelSystem);
|
Parent->Right = TakeNewPanelEntry(PanelSystem);
|
||||||
Panel_SetCurrentType(&Parent->Right->Panel, PanelSystem, ParentTypeIndex, ParentStateMemory, State, Context);
|
Panel_SetCurrentType(Parent->Right, PanelSystem, ParentTypeIndex, ParentStateMemory, State, Context);
|
||||||
|
Parent->Right->Parent = Parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,17 +243,17 @@ SplitPanelHorizontally(panel* Parent, r32 Percent, panel_system* PanelSystem, ap
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
ConsolidatePanelsKeepOne(panel* Parent, panel_entry* PanelEntryToKeep, panel_system* PanelSystem)
|
ConsolidatePanelsKeepOne(panel* Parent, panel* PanelToKeep, panel_system* PanelSystem)
|
||||||
{
|
{
|
||||||
panel_entry* LeftChild = Parent->Left;
|
panel* LeftChild = Parent->Left;
|
||||||
panel_entry* RightChild = Parent->Right;
|
panel* RightChild = Parent->Right;
|
||||||
|
|
||||||
panel_entry* PanelEntryToDestroy = PanelEntryToKeep == LeftChild ? RightChild : LeftChild;
|
panel* PanelToDestroy = PanelToKeep == LeftChild ? RightChild : LeftChild;
|
||||||
|
|
||||||
*Parent = PanelEntryToKeep->Panel;
|
*Parent = *PanelToKeep;
|
||||||
|
|
||||||
FreePanelEntry(PanelEntryToKeep, PanelSystem);
|
FreePanelEntry(PanelToKeep, PanelSystem);
|
||||||
FreePanelEntryRecursive(PanelEntryToDestroy, PanelSystem);
|
FreePanelEntryRecursive(PanelToDestroy, PanelSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
@ -297,6 +262,54 @@ ConsolidatePanelsKeepOne(panel* Parent, panel_entry* PanelEntryToKeep, panel_sys
|
||||||
//
|
//
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
|
internal rect2
|
||||||
|
GetTopPanelBounds(panel* Panel)
|
||||||
|
{
|
||||||
|
rect2 Result = {};
|
||||||
|
Result.Min = v2{
|
||||||
|
Panel->Bounds.Min.x,
|
||||||
|
LerpR32(Panel->SplitPercent, Panel->Bounds.Min.y, Panel->Bounds.Max.y)
|
||||||
|
};
|
||||||
|
Result.Max = Panel->Bounds.Max;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal rect2
|
||||||
|
GetBottomPanelBounds(panel* Panel)
|
||||||
|
{
|
||||||
|
rect2 Result = {};
|
||||||
|
Result.Min = Panel->Bounds.Min;
|
||||||
|
Result.Max = v2{
|
||||||
|
Panel->Bounds.Max.x,
|
||||||
|
LerpR32(Panel->SplitPercent, Panel->Bounds.Min.y, Panel->Bounds.Max.y)
|
||||||
|
};
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal rect2
|
||||||
|
GetRightPanelBounds(panel* Panel)
|
||||||
|
{
|
||||||
|
rect2 Result = {};
|
||||||
|
Result.Min = v2{
|
||||||
|
LerpR32(Panel->SplitPercent, Panel->Bounds.Min.x, Panel->Bounds.Max.x),
|
||||||
|
Panel->Bounds.Min.y
|
||||||
|
};
|
||||||
|
Result.Max = Panel->Bounds.Max;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal rect2
|
||||||
|
GetLeftPanelBounds(panel* Panel)
|
||||||
|
{
|
||||||
|
rect2 Result = {};
|
||||||
|
Result.Min = Panel->Bounds.Min;
|
||||||
|
Result.Max = v2{
|
||||||
|
LerpR32(Panel->SplitPercent, Panel->Bounds.Min.x, Panel->Bounds.Max.x),
|
||||||
|
Panel->Bounds.Max.y
|
||||||
|
};
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal rect2
|
internal rect2
|
||||||
GetTopPanelBounds(panel* Panel, rect2 PanelBounds)
|
GetTopPanelBounds(panel* Panel, rect2 PanelBounds)
|
||||||
{
|
{
|
||||||
|
@ -346,103 +359,77 @@ GetLeftPanelBounds(panel* Panel, rect2 PanelBounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
LayoutPanel(panel* Panel, rect2 PanelBounds, panel_layout* Layout)
|
Panel_UpdateLayout(panel* Panel, rect2 Bounds)
|
||||||
{
|
{
|
||||||
if (Panel->SplitDirection == PanelSplit_NoSplit)
|
Panel->Bounds = Bounds;
|
||||||
|
|
||||||
|
if (Panel->SplitDirection != PanelSplit_NoSplit)
|
||||||
{
|
{
|
||||||
panel_with_layout* WithLayout = Layout->Panels + Layout->PanelsCount++;
|
rect2 LeftOrTopBounds = {};
|
||||||
WithLayout->Panel = Panel_GetModalOverride(Panel);
|
rect2 RightOrBottomBounds = {};
|
||||||
WithLayout->Bounds = PanelBounds;
|
switch (Panel->SplitDirection)
|
||||||
|
{
|
||||||
|
case PanelSplit_Horizontal:
|
||||||
|
{
|
||||||
|
LeftOrTopBounds = GetTopPanelBounds(Panel);
|
||||||
|
RightOrBottomBounds = GetBottomPanelBounds(Panel);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case PanelSplit_Vertical:
|
||||||
|
{
|
||||||
|
LeftOrTopBounds = GetLeftPanelBounds(Panel);
|
||||||
|
RightOrBottomBounds = GetRightPanelBounds(Panel);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
InvalidDefaultCase;
|
||||||
}
|
}
|
||||||
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
|
||||||
{
|
|
||||||
rect2 TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
|
||||||
rect2 BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
|
||||||
|
|
||||||
panel* TopPanel = Panel_GetModalOverride(&Panel->Top->Panel);
|
Panel_UpdateLayout(Panel->Left, LeftOrTopBounds);
|
||||||
panel* BottomPanel = Panel_GetModalOverride(&Panel->Bottom->Panel);
|
Panel_UpdateLayout(Panel->Right, RightOrBottomBounds);
|
||||||
|
|
||||||
LayoutPanel(&Panel->Top->Panel, TopPanelBounds, Layout);
|
|
||||||
LayoutPanel(&Panel->Bottom->Panel, BottomPanelBounds, Layout);
|
|
||||||
}
|
|
||||||
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
|
||||||
{
|
|
||||||
rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
|
||||||
rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
|
||||||
|
|
||||||
panel* LeftPanel = Panel_GetModalOverride(&Panel->Top->Panel);
|
|
||||||
panel* RightPanel = Panel_GetModalOverride(&Panel->Bottom->Panel);
|
|
||||||
|
|
||||||
LayoutPanel(&Panel->Left->Panel, LeftPanelBounds, Layout);
|
|
||||||
LayoutPanel(&Panel->Right->Panel, RightPanelBounds, Layout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal panel_layout
|
internal void
|
||||||
GetPanelLayout(panel_system* System, rect2 WindowBounds, gs_memory_arena* Storage)
|
PanelSystem_UpdateLayout(panel_system* System, rect2 WindowBounds)
|
||||||
{
|
{
|
||||||
panel_layout Result = {};
|
panel* Root = System->Panels;
|
||||||
Result.PanelsMax = System->PanelsUsed;
|
Panel_UpdateLayout(Root, WindowBounds);
|
||||||
Result.Panels = PushArray(Storage, panel_with_layout, Result.PanelsMax);
|
|
||||||
|
|
||||||
LayoutPanel(&System->Panels[0].Panel, WindowBounds, &Result);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal panel_with_layout
|
internal panel*
|
||||||
GetPanelContainingPoint(v2 Point, panel* Panel, rect2 PanelBounds)
|
GetPanelContainingPoint(v2 Point, panel* Panel)
|
||||||
{
|
{
|
||||||
panel_with_layout Result = {0};
|
panel* Result = 0;
|
||||||
|
|
||||||
if (Panel->SplitDirection == PanelSplit_NoSplit)
|
if (PointIsInRect(Panel->Bounds, Point))
|
||||||
{
|
{
|
||||||
Result.Panel = Panel;
|
switch (Panel->SplitDirection)
|
||||||
Result.Bounds = PanelBounds;
|
|
||||||
}
|
|
||||||
else if (Panel->SplitDirection == PanelSplit_Horizontal)
|
|
||||||
{
|
{
|
||||||
rect2 TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
|
case PanelSplit_NoSplit:
|
||||||
rect2 BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
|
{
|
||||||
|
Result = Panel;
|
||||||
|
}break;
|
||||||
|
|
||||||
if (PointIsInRect(TopPanelBounds, Point))
|
case PanelSplit_Vertical:
|
||||||
|
case PanelSplit_Horizontal:
|
||||||
{
|
{
|
||||||
Result = GetPanelContainingPoint(Point, &Panel->Top->Panel, TopPanelBounds);
|
if (PointIsInRect(Panel->Left->Bounds, Point))
|
||||||
}
|
|
||||||
else if (PointIsInRect(BottomPanelBounds, Point))
|
|
||||||
{
|
{
|
||||||
Result = GetPanelContainingPoint(Point, &Panel->Bottom->Panel, BottomPanelBounds);
|
Result = GetPanelContainingPoint(Point, Panel->Left);
|
||||||
}
|
}
|
||||||
}
|
else if (PointIsInRect(Panel->Right->Bounds, Point))
|
||||||
else if (Panel->SplitDirection == PanelSplit_Vertical)
|
|
||||||
{
|
{
|
||||||
rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
|
Result = GetPanelContainingPoint(Point, Panel->Right);
|
||||||
rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
if (PointIsInRect(LeftPanelBounds, Point))
|
InvalidDefaultCase;
|
||||||
{
|
|
||||||
Result = GetPanelContainingPoint(Point, &Panel->Left->Panel, LeftPanelBounds);
|
|
||||||
}
|
|
||||||
else if (PointIsInRect(RightPanelBounds, Point))
|
|
||||||
{
|
|
||||||
Result = GetPanelContainingPoint(Point, &Panel->Right->Panel, RightPanelBounds);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal panel_with_layout
|
|
||||||
GetPanelContainingPoint(v2 Point, panel_system* PanelSystem, rect2 WindowBounds)
|
|
||||||
{
|
|
||||||
panel_with_layout Result = {0};
|
|
||||||
if (PanelSystem->PanelsUsed > 0)
|
|
||||||
{
|
|
||||||
Result = GetPanelContainingPoint(Point, &PanelSystem->Panels[0].Panel, WindowBounds);
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define FOLDHAUS_PANEL_H
|
#define FOLDHAUS_PANEL_H
|
||||||
#endif // FOLDHAUS_PANEL_H
|
#endif // FOLDHAUS_PANEL_H
|
|
@ -264,9 +264,9 @@ FOLDHAUS_INPUT_COMMAND_PROC(AddAnimationBlockCommand)
|
||||||
{
|
{
|
||||||
animation* ActiveAnim = AnimationSystem_GetActiveAnimation(&State->AnimationSystem);
|
animation* ActiveAnim = AnimationSystem_GetActiveAnimation(&State->AnimationSystem);
|
||||||
|
|
||||||
panel_with_layout ActivePanel = GetPanelContainingPoint(Mouse.Pos, &State->PanelSystem, State->WindowBounds);
|
panel* ActivePanel = GetPanelContainingPoint(Mouse.Pos, State->PanelSystem.Panels + 0);
|
||||||
frame_range Range = ActiveAnim->PlayableRange;
|
frame_range Range = ActiveAnim->PlayableRange;
|
||||||
u32 MouseDownFrame = GetFrameFromPointInAnimationPanel(Mouse.Pos, ActivePanel.Bounds, Range);
|
u32 MouseDownFrame = GetFrameFromPointInAnimationPanel(Mouse.Pos, ActivePanel->Bounds, Range);
|
||||||
|
|
||||||
handle NewBlockHandle = Animation_AddBlock(ActiveAnim, MouseDownFrame, MouseDownFrame + SecondsToFrames(3, State->AnimationSystem), 4, State->SelectedAnimationLayer);
|
handle NewBlockHandle = Animation_AddBlock(ActiveAnim, MouseDownFrame, MouseDownFrame + SecondsToFrames(3, State->AnimationSystem), 4, State->SelectedAnimationLayer);
|
||||||
SelectAnimationBlock(NewBlockHandle, State);
|
SelectAnimationBlock(NewBlockHandle, State);
|
||||||
|
@ -641,7 +641,7 @@ AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer*
|
||||||
|
|
||||||
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Load")))
|
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Load")))
|
||||||
{
|
{
|
||||||
panel_entry* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context);
|
panel* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context);
|
||||||
Panel_PushModalOverride(Panel, FileBrowser, LoadAnimationFileCallback);
|
Panel_PushModalOverride(Panel, FileBrowser, LoadAnimationFileCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ HierarchyView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Ren
|
||||||
PrintF(&TempString, "+ Add Assembly");
|
PrintF(&TempString, "+ Add Assembly");
|
||||||
if (ui_ListButton(&State->Interface, TempString, LineBounds[AssembliesToDraw], AssembliesToDraw))
|
if (ui_ListButton(&State->Interface, TempString, LineBounds[AssembliesToDraw], AssembliesToDraw))
|
||||||
{
|
{
|
||||||
panel_entry* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context);
|
panel* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context);
|
||||||
Panel_PushModalOverride(Panel, FileBrowser, LoadAssemblyCallback);
|
Panel_PushModalOverride(Panel, FileBrowser, LoadAssemblyCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,66 +162,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
PanelSystem_PushPanel(&State->PanelSystem, PanelType_SculptureView, State, Context);
|
PanelSystem_PushPanel(&State->PanelSystem, PanelType_SculptureView, State, Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
|
||||||
HandleInput (app_state* State, rect2 WindowBounds, input_queue InputQueue, mouse_state Mouse, context Context)
|
|
||||||
{
|
|
||||||
DEBUG_TRACK_FUNCTION;
|
|
||||||
|
|
||||||
b32 PanelSystemHandledInput = HandleMousePanelInteraction(&State->PanelSystem, State->WindowBounds, Mouse, State);
|
|
||||||
if (!PanelSystemHandledInput)
|
|
||||||
{
|
|
||||||
input_command_registry ActiveCommands = {};
|
|
||||||
if (State->Modes.ActiveModesCount > 0)
|
|
||||||
{
|
|
||||||
ActiveCommands = State->Modes.ActiveModes[State->Modes.ActiveModesCount - 1].Commands;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
panel_with_layout PanelWithMouseOverIt = GetPanelContainingPoint(Mouse.Pos, &State->PanelSystem, WindowBounds);
|
|
||||||
if (!PanelWithMouseOverIt.Panel) { return; }
|
|
||||||
State->HotPanel = PanelWithMouseOverIt.Panel;
|
|
||||||
|
|
||||||
s32 PanelTypeIndex = PanelWithMouseOverIt.Panel->TypeIndex;
|
|
||||||
panel_definition PanelDefinition = GlobalPanelDefs[PanelTypeIndex];
|
|
||||||
if (!PanelDefinition.InputCommands) { return; }
|
|
||||||
|
|
||||||
ActiveCommands.Commands = PanelDefinition.InputCommands;
|
|
||||||
ActiveCommands.Size = sizeof(*PanelDefinition.InputCommands) / sizeof(PanelDefinition.InputCommands[0]);
|
|
||||||
ActiveCommands.Used = ActiveCommands.Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (s32 EventIdx = 0; EventIdx < InputQueue.QueueUsed; EventIdx++)
|
|
||||||
{
|
|
||||||
input_entry Event = InputQueue.Entries[EventIdx];
|
|
||||||
|
|
||||||
// NOTE(Peter): These are in the order Down, Up, Held because we want to privalege
|
|
||||||
// Down and Up over Held. In other words, we don't want to call a Held command on the
|
|
||||||
// frame when the button was released, even if the command is registered to both events
|
|
||||||
if (KeyTransitionedDown(Event))
|
|
||||||
{
|
|
||||||
FindAndPushExistingCommand(ActiveCommands, Event, Command_Began, &State->CommandQueue);
|
|
||||||
}
|
|
||||||
else if (KeyTransitionedUp(Event))
|
|
||||||
{
|
|
||||||
FindAndPushExistingCommand(ActiveCommands, Event, Command_Ended, &State->CommandQueue);
|
|
||||||
}
|
|
||||||
else if (KeyHeldDown(Event))
|
|
||||||
{
|
|
||||||
FindAndPushExistingCommand(ActiveCommands, Event, Command_Held, &State->CommandQueue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute all commands in CommandQueue
|
|
||||||
for (s32 CommandIdx = State->CommandQueue.Used - 1; CommandIdx >= 0; CommandIdx--)
|
|
||||||
{
|
|
||||||
command_queue_entry* Entry = &State->CommandQueue.Commands[CommandIdx];
|
|
||||||
Entry->Command.Proc(State, Entry->Event, Mouse, Context);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearCommandQueue(&State->CommandQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
UPDATE_AND_RENDER(UpdateAndRender)
|
UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
@ -232,12 +172,8 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
// zero the Transient arena when we clear it so it wouldn't be a problem, but it is technically
|
// 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.
|
// incorrect to clear the arena, and then access the memory later.
|
||||||
ClearArena(State->Transient);
|
ClearArena(State->Transient);
|
||||||
Context->Mouse.CursorType = CursorType_Arrow;
|
|
||||||
|
|
||||||
PushRenderClearScreen(RenderBuffer);
|
Editor_Update(State, Context, InputQueue);
|
||||||
State->Camera.AspectRatio = RectAspectRatio(Context->WindowBounds);
|
|
||||||
|
|
||||||
HandleInput(State, State->WindowBounds, InputQueue, Context->Mouse, *Context);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
animation* ActiveAnim = AnimationSystem_GetActiveAnimation(&State->AnimationSystem);
|
animation* ActiveAnim = AnimationSystem_GetActiveAnimation(&State->AnimationSystem);
|
||||||
|
@ -348,27 +284,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
UART_BuildOutputData(OutputData, UARTAssemblies, &State->LedSystem);
|
UART_BuildOutputData(OutputData, UARTAssemblies, &State->LedSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
PushRenderOrthographic(RenderBuffer, State->WindowBounds);
|
Editor_Render(State, Context, RenderBuffer);
|
||||||
PushRenderClearScreen(RenderBuffer);
|
|
||||||
|
|
||||||
State->WindowBounds = Context->WindowBounds;
|
|
||||||
State->Interface.RenderBuffer = RenderBuffer;
|
|
||||||
State->Interface.Mouse = Context->Mouse;
|
|
||||||
|
|
||||||
panel_layout PanelsToRender = GetPanelLayout(&State->PanelSystem, State->WindowBounds, State->Transient);
|
|
||||||
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, Context->Mouse, *Context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Context->GeneralWorkQueue->CompleteQueueWork(Context->GeneralWorkQueue, Context->ThreadContext);
|
|
||||||
Context->GeneralWorkQueue->ResetWorkQueue(Context->GeneralWorkQueue);
|
|
||||||
|
|
||||||
// Checking for overflows
|
// Checking for overflows
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -233,5 +233,7 @@ animation_clip GlobalAnimationClips[] = {
|
||||||
|
|
||||||
#include "../meta/gs_meta_include.cpp"
|
#include "../meta/gs_meta_include.cpp"
|
||||||
|
|
||||||
|
#include "editor/foldhaus_editor.cpp"
|
||||||
|
|
||||||
#define FOLDHAUS_APP_H
|
#define FOLDHAUS_APP_H
|
||||||
#endif // FOLDHAUS_APP_H
|
#endif // FOLDHAUS_APP_H
|
Loading…
Reference in New Issue