Improved the visuals of the hierarchy panel and the timeline panel
This commit is contained in:
parent
d9af0c6a36
commit
2c6adaeda2
|
@ -39,8 +39,12 @@ struct animation_system
|
||||||
free_list FreeList;
|
free_list FreeList;
|
||||||
u32 BlocksCount;
|
u32 BlocksCount;
|
||||||
|
|
||||||
r32 Time;
|
r32 Time;
|
||||||
b32 TimelineShouldAdvance;
|
s32 LastUpdatedFrame;
|
||||||
|
r32 SecondsPerFrame;
|
||||||
|
|
||||||
|
b32 TimelineShouldAdvance;
|
||||||
|
|
||||||
// :Temporary
|
// :Temporary
|
||||||
r32 AnimationEnd;
|
r32 AnimationEnd;
|
||||||
};
|
};
|
||||||
|
|
|
@ -275,6 +275,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
|
|
||||||
{ // MODES PLAYGROUND
|
{ // MODES PLAYGROUND
|
||||||
InitializeAnimationSystem(&State->AnimationSystem);
|
InitializeAnimationSystem(&State->AnimationSystem);
|
||||||
|
State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
|
||||||
|
|
||||||
animation_block BlockZero = {0};
|
animation_block BlockZero = {0};
|
||||||
BlockZero.StartTime = 0;
|
BlockZero.StartTime = 0;
|
||||||
|
@ -415,6 +416,13 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
{
|
{
|
||||||
State->AnimationSystem.Time -= State->AnimationSystem.AnimationEnd;
|
State->AnimationSystem.Time -= State->AnimationSystem.AnimationEnd;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 CurrentFrame = (s32)(State->AnimationSystem.Time / State->AnimationSystem.SecondsPerFrame);
|
||||||
|
if (CurrentFrame != State->AnimationSystem.LastUpdatedFrame)
|
||||||
|
{
|
||||||
|
State->AnimationSystem.LastUpdatedFrame = CurrentFrame;
|
||||||
|
r32 FrameTime = CurrentFrame * State->AnimationSystem.SecondsPerFrame;
|
||||||
|
|
||||||
for (u32 i = 0; i < State->AnimationSystem.BlocksCount; i++)
|
for (u32 i = 0; i < State->AnimationSystem.BlocksCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -425,11 +433,11 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
if (State->AnimationSystem.Time >= Block.StartTime
|
if (State->AnimationSystem.Time >= Block.StartTime
|
||||||
&& State->AnimationSystem.Time <= Block.EndTime)
|
&& State->AnimationSystem.Time <= Block.EndTime)
|
||||||
{
|
{
|
||||||
Block.Proc(State, State->AnimationSystem.Time - Block.StartTime);
|
Block.Proc(State, FrameTime - Block.StartTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
s32 HeaderSize = State->NetworkProtocolHeaderSize;
|
s32 HeaderSize = State->NetworkProtocolHeaderSize;
|
||||||
dmx_buffer_list* DMXBuffers = 0;
|
dmx_buffer_list* DMXBuffers = 0;
|
||||||
|
|
|
@ -105,5 +105,7 @@ MouseButtonTransitionedUp (b32 MouseButtonState)
|
||||||
internal b32
|
internal b32
|
||||||
MouseButtonHeldDown (b32 MouseButtonState)
|
MouseButtonHeldDown (b32 MouseButtonState)
|
||||||
{
|
{
|
||||||
return (KeyWasDown(MouseButtonState) && KeyIsDown(MouseButtonState));
|
b32 WasDown = KeyWasDown(MouseButtonState);
|
||||||
|
b32 IsDown = KeyIsDown(MouseButtonState);
|
||||||
|
return (WasDown && IsDown);
|
||||||
}
|
}
|
|
@ -8,12 +8,14 @@ enum string_alignment
|
||||||
internal void
|
internal void
|
||||||
DrawCharacter_ (render_quad_batch_constructor* BatchConstructor, r32 MinX, r32 MinY, codepoint_bitmap CodepointInfo, v4 Color)
|
DrawCharacter_ (render_quad_batch_constructor* BatchConstructor, r32 MinX, r32 MinY, codepoint_bitmap CodepointInfo, v4 Color)
|
||||||
{
|
{
|
||||||
r32 MaxX = MinX + (CodepointInfo.Width);
|
s32 AlignedMinX = (s32)(MinX);
|
||||||
r32 MaxY = MinY + (CodepointInfo.Height);
|
s32 AlignedMinY = (s32)(MinY);
|
||||||
|
s32 AlignedMaxX = AlignedMinX + (CodepointInfo.Width);
|
||||||
|
s32 AlignedMaxY = AlignedMinY + (CodepointInfo.Height);
|
||||||
|
|
||||||
PushQuad2DOnBatch(BatchConstructor,
|
PushQuad2DOnBatch(BatchConstructor,
|
||||||
v2{MinX, MinY}, v2{MaxX, MinY},
|
v2{(r32)AlignedMinX, (r32)AlignedMinY}, v2{(r32)AlignedMaxX, (r32)AlignedMinY},
|
||||||
v2{MaxX, MaxY}, v2{MinX, MaxY},
|
v2{(r32)AlignedMaxX, (r32)AlignedMaxY}, v2{(r32)AlignedMinX, (r32)AlignedMaxY},
|
||||||
CodepointInfo.UVMin, CodepointInfo.UVMax,
|
CodepointInfo.UVMin, CodepointInfo.UVMax,
|
||||||
Color);
|
Color);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,36 +18,75 @@ PANEL_CLEANUP_PROC(AnimationTimeline_Cleanup)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal animation_block_handle
|
internal animation_block_handle
|
||||||
DrawAnimationTimeline (animation_system* AnimationSystem, v2 PanelMin, v2 PanelMax, animation_block_handle SelectedBlockHandle, render_command_buffer* RenderBuffer, interface_config Interface, mouse_state Mouse)
|
DrawAnimationTimeline (animation_system* AnimationSystem, s32 StartFrame, s32 EndFrame, v2 PanelMin, v2 PanelMax, animation_block_handle SelectedBlockHandle, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse)
|
||||||
{
|
{
|
||||||
|
string TempString = MakeString(PushArray(&State->Transient, char, 256), 256);
|
||||||
|
s32 FrameCount = EndFrame - StartFrame;
|
||||||
|
|
||||||
animation_block_handle Result = SelectedBlockHandle;
|
animation_block_handle Result = SelectedBlockHandle;
|
||||||
|
|
||||||
r32 AnimationPanelHeight = PanelMax.y - PanelMin.y;
|
r32 AnimationPanelHeight = PanelMax.y - PanelMin.y;
|
||||||
r32 AnimationPanelWidth = PanelMax.x - PanelMin.x;
|
r32 AnimationPanelWidth = PanelMax.x - PanelMin.x;
|
||||||
panel_result AnimationPanel = EvaluatePanel(RenderBuffer, PanelMin, PanelMax,
|
PushRenderQuad2D(RenderBuffer, PanelMin, PanelMax, v4{.22f, .22f, .22f, 1.f});
|
||||||
0, Interface);
|
|
||||||
|
|
||||||
|
// Frame Bar
|
||||||
|
r32 FrameBarHeight = 24;
|
||||||
|
v2 FrameBarMin = v2{PanelMin.x, PanelMax.y - FrameBarHeight};
|
||||||
|
v2 FrameBarMax = PanelMax;
|
||||||
|
PushRenderQuad2D(RenderBuffer, FrameBarMin, FrameBarMax, v4{.16f, .16f, .16f, 1.f});
|
||||||
|
|
||||||
|
// Mouse clicked inside frame nubmer bar -> change current frame on timeline
|
||||||
|
if (MouseButtonHeldDown(Mouse.LeftButtonState)
|
||||||
|
&& PointIsInRange(Mouse.DownPos, FrameBarMin, FrameBarMax))
|
||||||
|
{
|
||||||
|
r32 MouseX = Mouse.DownPos.x;
|
||||||
|
r32 MousePercentX = (MouseX - FrameBarMin.x) / (FrameBarMax.x - FrameBarMin.y);
|
||||||
|
s32 MouseFrame = (s32)((MousePercentX * FrameCount) + StartFrame);
|
||||||
|
r32 MouseFrameTime = (r32)MouseFrame * AnimationSystem->SecondsPerFrame;
|
||||||
|
AnimationSystem->Time = MouseFrameTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (s32 f = 0; f < FrameCount; f += 10)
|
||||||
|
{
|
||||||
|
s32 Frame = StartFrame + f;
|
||||||
|
PrintF(&TempString, "%d", Frame);
|
||||||
|
|
||||||
|
r32 FramePercent = (r32)f / (r32)FrameCount;
|
||||||
|
r32 FrameX = GSLerp(PanelMin.x, PanelMax.x, FramePercent);
|
||||||
|
v2 FrameTextPos = v2{FrameX, FrameBarMin.y + 2};
|
||||||
|
DrawString(RenderBuffer, TempString, State->Interface.Font, FrameTextPos, WhiteV4);
|
||||||
|
|
||||||
|
// Frame Vertical Slices
|
||||||
|
v2 LineTop = v2{FrameX, FrameBarMin.y};
|
||||||
|
v2 LineBottom = v2{FrameX + 1, PanelMin.y};
|
||||||
|
PushRenderQuad2D(RenderBuffer, LineTop, LineBottom, v4{.16f, .16f, .16f, 1.f});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animation Blocks
|
||||||
|
v2 TimelineMin = PanelMin;
|
||||||
|
v2 TimelineMax = v2{PanelMax.x, FrameBarMin.y};
|
||||||
b32 MouseDownAndNotHandled = MouseButtonTransitionedDown(Mouse.LeftButtonState);
|
b32 MouseDownAndNotHandled = MouseButtonTransitionedDown(Mouse.LeftButtonState);
|
||||||
|
for (u32 i = 0; i < AnimationSystem->BlocksCount; i++)
|
||||||
for (u32 i = 0; i < AnimationSystem->BlocksCount; i++)
|
{
|
||||||
{
|
animation_block_entry AnimationBlockEntry = AnimationSystem->Blocks[i];
|
||||||
animation_block_entry AnimationBlockEntry = AnimationSystem->Blocks[i];
|
if (AnimationBlockIsFree(AnimationBlockEntry)) { continue; }
|
||||||
if (AnimationBlockIsFree(AnimationBlockEntry)) { continue; }
|
|
||||||
|
|
||||||
animation_block_handle CurrentBlockHandle = {};
|
animation_block_handle CurrentBlockHandle = {};
|
||||||
CurrentBlockHandle.Index = i;
|
CurrentBlockHandle.Index = i;
|
||||||
CurrentBlockHandle.Generation = AnimationBlockEntry.Generation;
|
CurrentBlockHandle.Generation = AnimationBlockEntry.Generation;
|
||||||
|
|
||||||
animation_block AnimationBlockAt = AnimationBlockEntry.Block;
|
animation_block AnimationBlockAt = AnimationBlockEntry.Block;
|
||||||
|
|
||||||
r32 StartTimePercent = AnimationBlockAt.StartTime / AnimationSystem->AnimationEnd;
|
s32 BlockStartFrame = AnimationBlockAt.StartTime / AnimationSystem->SecondsPerFrame;
|
||||||
r32 StartPosition = AnimationPanelWidth * StartTimePercent;
|
r32 StartFramePercent = (r32)(BlockStartFrame - StartFrame) / (r32)FrameCount;
|
||||||
|
r32 StartPosition = AnimationPanelWidth * StartFramePercent;
|
||||||
|
|
||||||
r32 EndTimePercent = AnimationBlockAt.EndTime / AnimationSystem->AnimationEnd;
|
s32 BlockEndFrame = AnimationBlockAt.EndTime / AnimationSystem->SecondsPerFrame;
|
||||||
r32 EndPosition = AnimationPanelWidth * EndTimePercent;
|
r32 EndFramePercent = (r32)(BlockEndFrame - StartFrame) / (r32)FrameCount;
|
||||||
|
r32 EndPosition = AnimationPanelWidth * EndFramePercent;
|
||||||
|
|
||||||
v2 Min = PanelMin + v2{StartPosition, 25};
|
v2 Min = TimelineMin + v2{StartPosition, 25};
|
||||||
v2 Max = PanelMin + v2{EndPosition, 75};
|
v2 Max = TimelineMin + v2{EndPosition, 75};
|
||||||
|
|
||||||
v4 BlockColor = BlackV4;
|
v4 BlockColor = BlackV4;
|
||||||
if (AnimationBlockHandlesAreEqual(SelectedBlockHandle, CurrentBlockHandle))
|
if (AnimationBlockHandlesAreEqual(SelectedBlockHandle, CurrentBlockHandle))
|
||||||
|
@ -55,32 +94,44 @@ r32 EndTimePercent = AnimationBlockAt.EndTime / AnimationSystem->AnimationEnd;
|
||||||
BlockColor = PinkV4;
|
BlockColor = PinkV4;
|
||||||
}
|
}
|
||||||
|
|
||||||
PushRenderQuad2D(RenderBuffer, Min, Max, BlockColor);
|
PushRenderQuad2D(RenderBuffer, Min, Max, BlockColor);
|
||||||
PushRenderBoundingBox2D(RenderBuffer, Min, Max, 1, WhiteV4);
|
PushRenderBoundingBox2D(RenderBuffer, Min, Max, 1, WhiteV4);
|
||||||
|
|
||||||
if (PointIsInRange(Mouse.Pos, Min, Max)
|
if (PointIsInRange(Mouse.Pos, Min, Max)
|
||||||
&& MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
&& MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
||||||
{
|
{
|
||||||
MouseDownAndNotHandled = false;
|
MouseDownAndNotHandled = false;
|
||||||
if (AnimationBlockHandlesAreEqual(SelectedBlockHandle, CurrentBlockHandle))
|
if (AnimationBlockHandlesAreEqual(SelectedBlockHandle, CurrentBlockHandle))
|
||||||
{
|
{
|
||||||
// If the block is already selected, deselect it.
|
// If the block is already selected, deselect it.
|
||||||
Result = {0};
|
Result = {0};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Result = CurrentBlockHandle;
|
Result = CurrentBlockHandle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r32 TimePercent = AnimationSystem->Time / AnimationSystem->AnimationEnd;
|
// Time Slider
|
||||||
|
s32 SliderFrame = AnimationSystem->Time / AnimationSystem->SecondsPerFrame;
|
||||||
|
r32 TimePercent = (r32)SliderFrame / (r32)EndFrame;
|
||||||
r32 SliderX = PanelMin.x + (AnimationPanelWidth * TimePercent);
|
r32 SliderX = PanelMin.x + (AnimationPanelWidth * TimePercent);
|
||||||
v2 SliderMin = v2{SliderX, PanelMin.y};
|
v2 SliderMin = v2{SliderX, PanelMin.y};
|
||||||
v2 SliderMax = v2{SliderX + 1, PanelMax.y - 25};
|
v2 SliderMax = v2{SliderX + 1, PanelMax.y - 25};
|
||||||
PushRenderQuad2D(RenderBuffer, SliderMin, SliderMax, WhiteV4);
|
v4 TimeSliderColor = v4{.36f, .52f, .78f, 1.f};
|
||||||
|
|
||||||
if (MouseDownAndNotHandled && PointIsInRange(Mouse.Pos, PanelMin, PanelMax))
|
PushRenderQuad2D(RenderBuffer, SliderMin, SliderMax, TimeSliderColor);
|
||||||
|
|
||||||
|
r32 SliderHalfWidth = 10;
|
||||||
|
v2 HeadMin = v2{SliderX - SliderHalfWidth, SliderMax.y};
|
||||||
|
v2 HeadMax = v2{SliderX + SliderHalfWidth, SliderMax.y + FrameBarHeight};
|
||||||
|
PushRenderQuad2D(RenderBuffer, HeadMin, HeadMax, TimeSliderColor);
|
||||||
|
|
||||||
|
PrintF(&TempString, "%d", SliderFrame);
|
||||||
|
DrawString(RenderBuffer, TempString, State->Interface.Font, HeadMin + v2{4, 4}, WhiteV4);
|
||||||
|
|
||||||
|
if (MouseDownAndNotHandled && PointIsInRange(Mouse.Pos, TimelineMin, TimelineMax))
|
||||||
{
|
{
|
||||||
r32 MouseDownPositionPercent = (Mouse.Pos.x - PanelMin.x) / AnimationPanelWidth;
|
r32 MouseDownPositionPercent = (Mouse.Pos.x - PanelMin.x) / AnimationPanelWidth;
|
||||||
r32 NewBlockTimeStart = MouseDownPositionPercent * AnimationSystem->AnimationEnd;
|
r32 NewBlockTimeStart = MouseDownPositionPercent * AnimationSystem->AnimationEnd;
|
||||||
|
@ -96,21 +147,23 @@ Result = CurrentBlockHandle;
|
||||||
Result = NewBlockHandle;
|
Result = NewBlockHandle;
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PANEL_RENDER_PROC(AnimationTimeline_Render)
|
PANEL_RENDER_PROC(AnimationTimeline_Render)
|
||||||
{
|
{
|
||||||
animation_block_handle SelectedBlockHandle = State->SelectedAnimationBlockHandle;
|
animation_block_handle SelectedBlockHandle = State->SelectedAnimationBlockHandle;
|
||||||
|
|
||||||
r32 OptionsRowHeight = 25;
|
r32 OptionsRowHeight = 25;
|
||||||
v2 TimelineMin = PanelMin;
|
v2 TimelineMin = PanelMin;
|
||||||
v2 TimelineMax = v2{PanelMax.x, PanelMax.y - OptionsRowHeight};
|
v2 TimelineMax = v2{PanelMax.x, PanelMax.y - OptionsRowHeight};
|
||||||
if (TimelineMax.y - TimelineMin.y > 0)
|
if (TimelineMax.y - TimelineMin.y > 0)
|
||||||
{
|
{
|
||||||
|
s32 FrameEnd = (s32)(State->AnimationSystem.AnimationEnd / State->AnimationSystem.SecondsPerFrame);
|
||||||
SelectedBlockHandle = DrawAnimationTimeline(&State->AnimationSystem,
|
SelectedBlockHandle = DrawAnimationTimeline(&State->AnimationSystem,
|
||||||
TimelineMin, TimelineMax,
|
0, FrameEnd,
|
||||||
SelectedBlockHandle,
|
TimelineMin, TimelineMax,
|
||||||
RenderBuffer, State->Interface, Mouse);
|
SelectedBlockHandle,
|
||||||
|
RenderBuffer, State, Mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
v2 OptionsRowMin = v2{ PanelMin.x, TimelineMax.y };
|
v2 OptionsRowMin = v2{ PanelMin.x, TimelineMax.y };
|
||||||
|
@ -128,14 +181,14 @@ TimelineMin, TimelineMax,
|
||||||
MakeStringLiteral("Pause"),
|
MakeStringLiteral("Pause"),
|
||||||
State->Interface, Mouse);
|
State->Interface, Mouse);
|
||||||
ButtonAt.x += ButtonWidth + 2;
|
ButtonAt.x += ButtonWidth + 2;
|
||||||
button_result PlayResult = EvaluateButton(RenderBuffer,
|
button_result PlayResult = EvaluateButton(RenderBuffer,
|
||||||
ButtonAt + ButtonMin, ButtonAt + ButtonMax,
|
ButtonAt + ButtonMin, ButtonAt + ButtonMax,
|
||||||
MakeStringLiteral("Play"),
|
MakeStringLiteral("Play"),
|
||||||
State->Interface, Mouse);
|
State->Interface, Mouse);
|
||||||
ButtonAt.x += ButtonWidth + 2;
|
ButtonAt.x += ButtonWidth + 2;
|
||||||
button_result StopResult = EvaluateButton(RenderBuffer,
|
button_result StopResult = EvaluateButton(RenderBuffer,
|
||||||
ButtonAt + ButtonMin, ButtonAt + ButtonMax,
|
ButtonAt + ButtonMin, ButtonAt + ButtonMax,
|
||||||
MakeStringLiteral("Stop"),
|
MakeStringLiteral("Stop"),
|
||||||
State->Interface, Mouse);
|
State->Interface, Mouse);
|
||||||
|
|
||||||
if (PauseResult.Pressed)
|
if (PauseResult.Pressed)
|
||||||
|
@ -154,5 +207,5 @@ button_result StopResult = EvaluateButton(RenderBuffer,
|
||||||
State->AnimationSystem.Time = 0;
|
State->AnimationSystem.Time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
State->SelectedAnimationBlockHandle = SelectedBlockHandle;
|
State->SelectedAnimationBlockHandle = SelectedBlockHandle;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ v4 LineBGColors[] = {
|
||||||
v4 LineBGHoverColor = { .22f, .22f, .22f, 1.f };
|
v4 LineBGHoverColor = { .22f, .22f, .22f, 1.f };
|
||||||
|
|
||||||
r32 LineHeight = State->Interface.Font->PixelHeight + 8;
|
r32 LineHeight = State->Interface.Font->PixelHeight + 8;
|
||||||
v2 LineMin = v2{PanelMin.x + State->Interface.Margin.x, PanelMax.y - LineHeight};
|
v2 LineMin = v2{PanelMin.x, PanelMax.y - LineHeight};
|
||||||
v2 LineMax = LineMin + v2{PanelWidth, LineHeight};
|
v2 LineMax = LineMin + v2{PanelWidth, LineHeight};
|
||||||
v2 TextOffset = v2{10, 4};
|
v2 TextOffset = v2{10, 4};
|
||||||
string TempString = MakeString(PushArray(&State->Transient, char, 256), 256);
|
string TempString = MakeString(PushArray(&State->Transient, char, 256), 256);
|
||||||
|
|
Loading…
Reference in New Issue