Began working on a new ui layout system. Deprecated a lot of old ui code, in favor of new ui_ code
This commit is contained in:
parent
803f5c82ae
commit
cb98100a94
|
@ -669,6 +669,15 @@ PointToPercentRange (v2 P, v2 Min, v2 Max)
|
|||
// which makes refactoring easier as you only have to change the identifier in one place
|
||||
#define RectExpand(r) (r).Min, (r).Max
|
||||
|
||||
static rect
|
||||
MakeRectMinWidth(v2 Min, v2 Width)
|
||||
{
|
||||
rect Rect = {0};
|
||||
Rect.Min = Min;
|
||||
Rect.Max = Min + Width;
|
||||
return Rect;
|
||||
}
|
||||
|
||||
inline float
|
||||
Width (rect Rect)
|
||||
{
|
||||
|
@ -744,6 +753,104 @@ RectOffsetByVector(rect R, v2 V)
|
|||
return Result;
|
||||
}
|
||||
|
||||
static void
|
||||
HSplitRectAtValue(rect Bounds, r32 YValue, rect* Top, rect* Bottom)
|
||||
{
|
||||
if (YValue <= Bounds.Min.y)
|
||||
{
|
||||
*Top = Bounds;
|
||||
*Bottom = {0};
|
||||
}
|
||||
else if (YValue >= Bounds.Max.y)
|
||||
{
|
||||
*Top = {0};
|
||||
*Bottom = Bounds;
|
||||
}
|
||||
else
|
||||
{
|
||||
Top->Max = Bounds.Max;
|
||||
Top->Min = { Bounds.Min.x, YValue };
|
||||
Bottom->Max = { Bounds.Max.x, YValue };
|
||||
Bottom->Min = Bounds.Min;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HSplitRectAtDistanceFromTop(rect Bounds, r32 YDist, rect* Top, rect* Bottom)
|
||||
{
|
||||
r32 YValue = Bounds.Max.y - YDist;
|
||||
HSplitRectAtValue(Bounds, YValue, Top, Bottom);
|
||||
}
|
||||
|
||||
static void
|
||||
HSplitRectAtDistanceFromBottom(rect Bounds, r32 YDist, rect* Top, rect* Bottom)
|
||||
{
|
||||
r32 YValue = Bounds.Min.y + YDist;
|
||||
HSplitRectAtValue(Bounds, YValue, Top, Bottom);
|
||||
}
|
||||
|
||||
static void
|
||||
HSplitRectAtPercent(rect Bounds, r32 YPercent, rect* Top, rect* Bottom)
|
||||
{
|
||||
r32 YValue = GSLerp(Bounds.Min.y, Bounds.Max.y, YPercent);
|
||||
HSplitRectAtValue(Bounds, YValue, Top, Bottom);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
VSplitRectAtValue(rect Bounds, r32 XValue, rect* Left, rect* Right)
|
||||
{
|
||||
if (XValue <= Bounds.Min.x)
|
||||
{
|
||||
*Left = {0};
|
||||
*Right = Bounds;
|
||||
}
|
||||
else if (XValue >= Bounds.Max.x)
|
||||
{
|
||||
*Left = Bounds;
|
||||
*Right = {0};
|
||||
}
|
||||
else
|
||||
{
|
||||
Left->Max = { XValue, Bounds.Max.y};
|
||||
Left->Min = Bounds.Min;
|
||||
Right->Max = Bounds.Max;
|
||||
Right->Min = { XValue, Bounds.Min.y };
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
VSplitRectAtDistanceFromRight(rect Bounds, r32 XDist, rect* Left, rect* Right)
|
||||
{
|
||||
r32 XValue = Bounds.Max.x - XDist;
|
||||
VSplitRectAtValue(Bounds, XValue, Left, Right);
|
||||
}
|
||||
|
||||
static void
|
||||
VSplitRectAtDistanceFromLeft(rect Bounds, r32 XDist, rect* Left, rect* Right)
|
||||
{
|
||||
r32 XValue = Bounds.Min.x + XDist;
|
||||
VSplitRectAtValue(Bounds, XValue, Left, Right);
|
||||
}
|
||||
|
||||
static void
|
||||
VSplitRectAtPercent(rect Bounds, r32 XPercent, rect* Left, rect* Right)
|
||||
{
|
||||
r32 XValue = GSLerp(Bounds.Min.x, Bounds.Max.x, XPercent);
|
||||
VSplitRectAtValue(Bounds, XValue, Left, Right);
|
||||
}
|
||||
|
||||
#define TranslateRectX(r, d) TranslateRect((r), v2{(d), 0})
|
||||
#define TranslateRectY(r, d) TranslateRect((r), v2{0, (d)})
|
||||
static rect
|
||||
TranslateRect(rect R, v2 Delta)
|
||||
{
|
||||
rect Result = R;
|
||||
Result.Min += Delta;
|
||||
Result.Max += Delta;
|
||||
return Result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// MATRIX
|
||||
//////////////////////////////////////
|
||||
|
|
|
@ -156,7 +156,14 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
|||
State->Interface.ButtonColor_Active = v4{.1f, .1f, .1f, 1};
|
||||
State->Interface.ButtonColor_Selected = v4{.1f, .1f, .3f, 1};
|
||||
State->Interface.TextColor = WhiteV4;
|
||||
State->Interface.ListBGColors[0] = v4{ .16f, .16f, .16f, 1.f };
|
||||
State->Interface.ListBGColors[1] = v4{ .18f, .18f, .18f, 1.f };
|
||||
State->Interface.ListBGHover = v4{ .22f, .22f, .22f, 1.f };
|
||||
State->Interface.ListBGSelected = v4{.44f, .44f, .44f, 1.f };
|
||||
State->Interface.Margin = v2{5, 5};
|
||||
State->Interface.RowHeight = State->Interface.Font->PixelHeight + 2 * State->Interface.Margin.y;
|
||||
|
||||
State->Interface_.Style = State->Interface;
|
||||
|
||||
State->SACN = InitializeSACN(Context);
|
||||
State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE;
|
||||
|
@ -315,7 +322,6 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
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
|
||||
|
@ -495,6 +501,10 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
PushRenderOrthographic(RenderBuffer, 0, 0, Width(State->WindowBounds), Height(State->WindowBounds));
|
||||
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);
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ struct app_state
|
|||
input_command_queue CommandQueue;
|
||||
text_entry ActiveTextEntry;
|
||||
|
||||
ui_interface Interface_;
|
||||
interface_config Interface;
|
||||
|
||||
animation_system AnimationSystem;
|
||||
|
@ -230,6 +231,7 @@ typedef PANEL_INIT_PROC(panel_init_proc);
|
|||
#define PANEL_CLEANUP_PROC(name) void name(panel* Panel, app_state* State)
|
||||
typedef PANEL_CLEANUP_PROC(panel_cleanup_proc);
|
||||
|
||||
// TODO(Peter): Should be able to take the mouse out of this
|
||||
#define PANEL_RENDER_PROC(name) void name(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context, mouse_state Mouse)
|
||||
typedef PANEL_RENDER_PROC(panel_render_proc);
|
||||
|
||||
|
|
|
@ -403,16 +403,14 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect FooterBo
|
|||
PushRenderQuad2D(RenderBuffer, FooterBounds.Min, v2{FooterBounds.Max.x, FooterBounds.Min.y + 25}, v4{.5f, .5f, .5f, 1.f});
|
||||
PushRenderQuad2D(RenderBuffer, FooterBounds.Min, FooterBounds.Min + v2{25, 25}, WhiteV4);
|
||||
|
||||
v2 PanelSelectButtonMin = FooterBounds.Min + v2{30, 1};
|
||||
v2 PanelSelectButtonMax = PanelSelectButtonMin + v2{100, 23};
|
||||
rect PanelSelectBtnBounds = MakeRectMinWidth(FooterBounds.Min + v2{30, 1}, v2{100, 23});
|
||||
|
||||
if (Panel->PanelSelectionMenuOpen)
|
||||
{
|
||||
v2 ButtonDimension = v2{100, 25};
|
||||
v2 ButtonMin = v2{PanelSelectButtonMin.x, FooterBounds.Max.y};
|
||||
rect ButtonBounds = MakeRectMinWidth(v2{ PanelSelectBtnBounds.Min.x, FooterBounds.Max.y }, v2{ 100, 25 });
|
||||
|
||||
v2 MenuMin = ButtonMin;
|
||||
v2 MenuMax = v2{ButtonMin.x + ButtonDimension.x, ButtonMin.y + (ButtonDimension.y * GlobalPanelDefsCount)};
|
||||
v2 MenuMin = ButtonBounds.Min;
|
||||
v2 MenuMax = v2{ButtonBounds.Min.x + Width(ButtonBounds), ButtonBounds.Min.y + (Height(ButtonBounds) * GlobalPanelDefsCount)};
|
||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
|
||||
&& !PointIsInRange(Mouse.DownPos, MenuMin, MenuMax))
|
||||
{
|
||||
|
@ -424,24 +422,17 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect FooterBo
|
|||
{
|
||||
panel_definition Def = GlobalPanelDefs[i];
|
||||
string DefName = MakeString(Def.PanelName, Def.PanelNameLength);
|
||||
button_result DefinitionButton = EvaluateButton(RenderBuffer,
|
||||
ButtonMin, ButtonMin + ButtonDimension,
|
||||
DefName, State->Interface, Mouse);
|
||||
if (DefinitionButton.Pressed)
|
||||
if (ui_Button(&State->Interface_, DefName, ButtonBounds))
|
||||
{
|
||||
SetPanelDefinition(Panel, i, State);
|
||||
Panel->PanelSelectionMenuOpen = false;
|
||||
}
|
||||
|
||||
ButtonMin.y += ButtonDimension.y;
|
||||
ButtonBounds = TranslateRectY(ButtonBounds, Height(ButtonBounds));
|
||||
}
|
||||
}
|
||||
|
||||
button_result ButtonResult = EvaluateButton(RenderBuffer,
|
||||
PanelSelectButtonMin,
|
||||
PanelSelectButtonMax,
|
||||
MakeStringLiteral("Select"), State->Interface, Mouse);
|
||||
if (ButtonResult.Pressed)
|
||||
if (ui_Button(&State->Interface_, MakeStringLiteral("Select"), PanelSelectBtnBounds))
|
||||
{
|
||||
Panel->PanelSelectionMenuOpen = !Panel->PanelSelectionMenuOpen;
|
||||
}
|
||||
|
|
388
src/interface.h
388
src/interface.h
|
@ -60,7 +60,7 @@ DrawCharacterRightAligned (render_quad_batch_constructor* BatchConstructor, char
|
|||
}
|
||||
|
||||
internal v2
|
||||
DrawStringLeftAligned (render_quad_batch_constructor* BatchConstructor, char* String, s32 Length, v2 InitialRegisterPosition, bitmap_font* Font, v4 Color)
|
||||
DrawStringLeftAligned (render_quad_batch_constructor* BatchConstructor, s32 Length, char* String, v2 InitialRegisterPosition, bitmap_font* Font, v4 Color)
|
||||
{
|
||||
v2 RegisterPosition = InitialRegisterPosition;
|
||||
char* C = String;
|
||||
|
@ -74,7 +74,7 @@ DrawStringLeftAligned (render_quad_batch_constructor* BatchConstructor, char* St
|
|||
}
|
||||
|
||||
internal v2
|
||||
DrawStringRightAligned (render_quad_batch_constructor* BatchConstructor, char* String, s32 Length, v2 InitialRegisterPosition, bitmap_font* Font, v4 Color)
|
||||
DrawStringRightAligned (render_quad_batch_constructor* BatchConstructor, s32 Length, char* String, v2 InitialRegisterPosition, bitmap_font* Font, v4 Color)
|
||||
{
|
||||
v2 RegisterPosition = InitialRegisterPosition;
|
||||
char* C = String + Length - 1;
|
||||
|
@ -104,15 +104,11 @@ DrawString (render_command_buffer* RenderBuffer, string String, bitmap_font* Fon
|
|||
v2 RegisterPosition = Position;
|
||||
if (Alignment == Align_Left)
|
||||
{
|
||||
RegisterPosition = DrawStringLeftAligned(&BatchConstructor,
|
||||
String.Memory, String.Length,
|
||||
RegisterPosition, Font, Color);
|
||||
RegisterPosition = DrawStringLeftAligned(&BatchConstructor, StringExpand(String), RegisterPosition, Font, Color);
|
||||
}
|
||||
else if (Alignment == Align_Right)
|
||||
{
|
||||
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
|
||||
String.Memory, String.Length,
|
||||
RegisterPosition, Font, Color);
|
||||
RegisterPosition = DrawStringRightAligned(&BatchConstructor, StringExpand(String), RegisterPosition, Font, Color);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -151,29 +147,27 @@ DrawStringWithCursor (render_command_buffer* RenderBuffer, string String, s32 Cu
|
|||
v2 RegisterPosition = Position;
|
||||
if (Alignment == Align_Left)
|
||||
{
|
||||
RegisterPosition = DrawStringLeftAligned(&BatchConstructor,
|
||||
String.Memory, CursorPosition,
|
||||
RegisterPosition, Font, Color);
|
||||
RegisterPosition = DrawStringLeftAligned(&BatchConstructor, StringExpand(String), RegisterPosition, Font, Color);
|
||||
DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font);
|
||||
if (String.Length - CursorPosition > 0)
|
||||
{
|
||||
RegisterPosition = DrawStringLeftAligned(&BatchConstructor,
|
||||
String.Memory + CursorPosition,
|
||||
String.Length - CursorPosition,
|
||||
String.Memory + CursorPosition,
|
||||
RegisterPosition, Font, Color);
|
||||
}
|
||||
}
|
||||
else if (Alignment == Align_Right)
|
||||
{
|
||||
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
|
||||
String.Memory, CursorPosition,
|
||||
CursorPosition, String.Memory,
|
||||
RegisterPosition, Font, Color);
|
||||
DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font);
|
||||
if (String.Length - CursorPosition > 0)
|
||||
{
|
||||
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
|
||||
String.Memory + CursorPosition,
|
||||
String.Length - CursorPosition,
|
||||
String.Memory + CursorPosition,
|
||||
RegisterPosition, Font, Color);
|
||||
}
|
||||
}
|
||||
|
@ -189,154 +183,229 @@ DrawStringWithCursor (render_command_buffer* RenderBuffer, string String, s32 Cu
|
|||
struct interface_config
|
||||
{
|
||||
v4 PanelBGColors[4];
|
||||
|
||||
v4 ButtonColor_Inactive, ButtonColor_Active, ButtonColor_Selected;
|
||||
|
||||
v4 TextColor;
|
||||
|
||||
#define LIST_BG_COLORS_COUNT 2
|
||||
v4 ListBGColors[LIST_BG_COLORS_COUNT];
|
||||
v4 ListBGHover;
|
||||
v4 ListBGSelected;
|
||||
|
||||
bitmap_font* Font;
|
||||
r32 FontSize;
|
||||
v2 Margin;
|
||||
r32 RowHeight;
|
||||
};
|
||||
|
||||
struct button_result
|
||||
struct ui_layout
|
||||
{
|
||||
b32 Pressed;
|
||||
r32 Advance;
|
||||
rect Bounds;
|
||||
v2 Margin;
|
||||
r32 RowHeight;
|
||||
r32 RowYAt;
|
||||
|
||||
b32 DrawHorizontal;
|
||||
u32 RowDivisions;
|
||||
u32 RowElementsCount;
|
||||
};
|
||||
|
||||
internal button_result
|
||||
EvaluateButton (render_command_buffer* RenderBuffer,
|
||||
v2 Min, v2 Max, v2 Margin, string Label,
|
||||
v4 IdleBGColor, v4 HotBGColor, v4 IdleTextColor, v4 HotTextColor,
|
||||
bitmap_font* Font, mouse_state Mouse)
|
||||
struct ui_interface
|
||||
{
|
||||
button_result Result = {};
|
||||
Result.Pressed = false;
|
||||
interface_config Style;
|
||||
mouse_state Mouse;
|
||||
render_command_buffer* RenderBuffer;
|
||||
};
|
||||
|
||||
v4 BGColor = IdleBGColor;
|
||||
v4 TextColor = IdleTextColor;
|
||||
static ui_layout
|
||||
ui_CreateLayout(ui_interface Interface, rect Bounds)
|
||||
{
|
||||
ui_layout Result = {0};
|
||||
Result.Bounds = Bounds;
|
||||
Result.Margin = Interface.Style.Margin;
|
||||
Result.RowHeight = Interface.Style.RowHeight;
|
||||
Result.RowYAt = Bounds.Max.y - Result.RowHeight;
|
||||
return Result;
|
||||
}
|
||||
|
||||
if (PointIsInRange(Mouse.Pos, Min, Max))
|
||||
static void
|
||||
ui_StartRow(ui_layout* Layout, u32 RowDivisions)
|
||||
{
|
||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
||||
Layout->DrawHorizontal = true;
|
||||
Layout->RowDivisions = RowDivisions;
|
||||
Layout->RowElementsCount = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ui_StartRow(ui_layout* Layout)
|
||||
{
|
||||
Result.Pressed = true;
|
||||
ui_StartRow(Layout, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
ui_EndRow(ui_layout* Layout)
|
||||
{
|
||||
Layout->DrawHorizontal = false;
|
||||
}
|
||||
|
||||
static b32
|
||||
ui_TryReserveElementBounds(ui_layout* Layout, rect* Bounds)
|
||||
{
|
||||
b32 Result = true;
|
||||
if (!Layout->DrawHorizontal)
|
||||
{
|
||||
Bounds->Min = { Layout->Bounds.Min.x, Layout->RowYAt };
|
||||
Bounds->Max = { Layout->Bounds.Max.x, Bounds->Min.y + Layout->RowHeight };
|
||||
Layout->RowYAt -= Layout->RowHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
BGColor = HotBGColor;
|
||||
TextColor = HotTextColor;
|
||||
}
|
||||
}
|
||||
|
||||
PushRenderQuad2D(RenderBuffer, Min, Max, BGColor);
|
||||
DrawString(RenderBuffer, Label, Font, Min + Margin, TextColor);
|
||||
|
||||
Result.Advance = (Max.y - Min.y) + Margin.y;
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal button_result
|
||||
EvaluateButton (render_command_buffer* RenderBuffer, v2 Min, v2 Max, string Label, interface_config Config, mouse_state Mouse)
|
||||
if (Layout->RowDivisions > 0)
|
||||
{
|
||||
button_result Result = EvaluateButton(RenderBuffer,
|
||||
Min, Max, Config.Margin, Label,
|
||||
Config.ButtonColor_Inactive, Config.ButtonColor_Active,
|
||||
Config.TextColor, Config.TextColor,
|
||||
Config.Font, Mouse);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal button_result
|
||||
EvaluateSelectableButton (render_command_buffer* RenderBuffer, v2 Min, v2 Max, string Label, interface_config Config, mouse_state Mouse, b32 Selected)
|
||||
{
|
||||
v4 BGColor = Config.ButtonColor_Inactive;
|
||||
if (Selected)
|
||||
{
|
||||
BGColor = Config.ButtonColor_Selected;
|
||||
}
|
||||
|
||||
button_result Result = EvaluateButton(RenderBuffer,
|
||||
Min, Max, Config.Margin, Label,
|
||||
Config.ButtonColor_Inactive, Config.ButtonColor_Active,
|
||||
Config.TextColor, Config.TextColor,
|
||||
Config.Font, Mouse);
|
||||
return Result;
|
||||
}
|
||||
|
||||
struct multi_option_label_result
|
||||
{
|
||||
b32 Pressed;
|
||||
s32 IndexPressed;
|
||||
r32 Advance;
|
||||
Assert(Layout->RowElementsCount < Layout->RowDivisions);
|
||||
r32 ElementWidth = Width(Layout->Bounds) / Layout->RowDivisions;
|
||||
Bounds->Min = {
|
||||
Layout->Bounds.Min.x + (ElementWidth * Layout->RowElementsCount) + Layout->Margin.x,
|
||||
Layout->RowYAt
|
||||
};
|
||||
|
||||
internal multi_option_label_result
|
||||
EvaluateMultiOptionLabel (render_command_buffer* RenderBuffer,
|
||||
v2 Min, v2 Max, string Label, string Options[], s32 OptionsCount,
|
||||
interface_config Config, mouse_state Mouse)
|
||||
Bounds->Max = {
|
||||
Bounds->Min.x + ElementWidth - Layout->Margin.x,
|
||||
Bounds->Min.y + Layout->RowHeight
|
||||
};
|
||||
Layout->RowElementsCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
multi_option_label_result Result = {};
|
||||
Result.Pressed = false;
|
||||
|
||||
DrawString(RenderBuffer, Label, Config.Font, Min + Config.Margin, Config.TextColor);
|
||||
|
||||
r32 ButtonSide = (Max.y - Min.y) - (2 * Config.Margin.y);
|
||||
v2 ButtonDim = v2{ButtonSide, ButtonSide};
|
||||
v2 ButtonPos = Max - (ButtonDim + Config.Margin);
|
||||
|
||||
for (s32 b = 0; b < OptionsCount; b++)
|
||||
{
|
||||
button_result Button = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
||||
Options[b], Config, Mouse);
|
||||
if (Button.Pressed)
|
||||
{
|
||||
Result.Pressed = true;
|
||||
Result.IndexPressed = b;
|
||||
Result = false;
|
||||
}
|
||||
}
|
||||
|
||||
Result.Advance = (Max.y - Min.y) + Config.Margin.y;
|
||||
return Result;
|
||||
}
|
||||
|
||||
// NOTE(Peter): returns IndexPressed = -1 if the button itself is pressed, as opposed
|
||||
// to one of its options
|
||||
internal multi_option_label_result
|
||||
EvaluateMultiOptionButton (render_command_buffer* RenderBuffer, v2 Min, v2 Max, string Text, string Options[], s32 OptionsCount, b32 Selected,
|
||||
interface_config Config, mouse_state Mouse)
|
||||
static rect
|
||||
ui_ReserveTextLineBounds(ui_interface Interface, string Text, ui_layout* Layout)
|
||||
{
|
||||
multi_option_label_result Result = {};
|
||||
Result.Pressed = false;
|
||||
rect Bounds = {0};
|
||||
|
||||
r32 ButtonSide = (Max.y - Min.y) - (2 * Config.Margin.y);
|
||||
v2 ButtonDim = v2{ButtonSide, ButtonSide};
|
||||
|
||||
v2 FirstButtonPos = Max - ((ButtonDim + Config.Margin) * OptionsCount);
|
||||
v2 NewMax = v2{FirstButtonPos.x - Config.Margin.x, Max.y};
|
||||
|
||||
button_result MainButton = EvaluateSelectableButton(RenderBuffer, Min, NewMax, Text, Config, Mouse, Selected);
|
||||
if (MainButton.Pressed)
|
||||
{
|
||||
Result.Pressed = true;
|
||||
Result.IndexPressed = -1;
|
||||
return Bounds;
|
||||
}
|
||||
|
||||
v2 ButtonPos = Max - (ButtonDim + Config.Margin);
|
||||
//
|
||||
// Drawing Functions
|
||||
//
|
||||
|
||||
for (s32 b = 0; b < OptionsCount; b++)
|
||||
static void
|
||||
ui_FillRect(ui_interface* Interface, rect Bounds, v4 Color)
|
||||
{
|
||||
button_result Button = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
||||
Options[b], Config, Mouse);
|
||||
if (Button.Pressed)
|
||||
PushRenderQuad2D(Interface->RenderBuffer, RectExpand(Bounds), Color);
|
||||
}
|
||||
|
||||
static void
|
||||
ui_OutlineRect(ui_interface* Interface, rect Bounds, r32 Thickness, v4 Color)
|
||||
{
|
||||
Result.Pressed = true;
|
||||
Result.IndexPressed = b;
|
||||
PushRenderBoundingBox2D(Interface->RenderBuffer, Bounds.Min, Bounds.Max, Thickness, Color);
|
||||
}
|
||||
|
||||
internal void
|
||||
ui_DrawString(ui_interface* Interface, string String, rect Bounds, v4 Color, string_alignment Alignment = Align_Left)
|
||||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
render_quad_batch_constructor BatchConstructor = PushRenderTexture2DBatch(Interface->RenderBuffer,
|
||||
String.Length,
|
||||
Interface->Style.Font->BitmapMemory,
|
||||
Interface->Style.Font->BitmapTextureHandle,
|
||||
Interface->Style.Font->BitmapWidth,
|
||||
Interface->Style.Font->BitmapHeight,
|
||||
Interface->Style.Font->BitmapBytesPerPixel,
|
||||
Interface->Style.Font->BitmapStride);
|
||||
|
||||
v2 RegisterPosition = Bounds.Min + Interface->Style.Margin;
|
||||
if (Alignment == Align_Left)
|
||||
{
|
||||
RegisterPosition = DrawStringLeftAligned(&BatchConstructor, StringExpand(String), RegisterPosition, Interface->Style.Font, Color);
|
||||
}
|
||||
else if (Alignment == Align_Right)
|
||||
{
|
||||
RegisterPosition = DrawStringRightAligned(&BatchConstructor, StringExpand(String), RegisterPosition, Interface->Style.Font, Color);
|
||||
}
|
||||
else
|
||||
{
|
||||
InvalidCodePath;
|
||||
}
|
||||
}
|
||||
|
||||
Result.Advance = (Max.y - Min.y) + Config.Margin.y;
|
||||
return Result;
|
||||
static void
|
||||
ui_TextBox(ui_interface* Interface, rect Bounds, string Text, v4 BGColor, v4 TextColor)
|
||||
{
|
||||
ui_FillRect(Interface, Bounds, BGColor);
|
||||
ui_DrawString(Interface, Text, Bounds, TextColor);
|
||||
}
|
||||
|
||||
static b32
|
||||
ui_Button(ui_interface* Interface, string Text, rect Bounds, v4 InactiveColor, v4 HoverColor, v4 ClickedColor)
|
||||
{
|
||||
b32 Pressed = false;
|
||||
v4 ButtonBG = InactiveColor;
|
||||
if (PointIsInRect(Interface->Mouse.Pos, Bounds))
|
||||
{
|
||||
ButtonBG = HoverColor;
|
||||
if (MouseButtonTransitionedDown(Interface->Mouse.LeftButtonState))
|
||||
{
|
||||
ButtonBG = ClickedColor;
|
||||
Pressed = true;
|
||||
}
|
||||
}
|
||||
ui_TextBox(Interface, Bounds, Text, ButtonBG, Interface->Style.TextColor);
|
||||
return Pressed;
|
||||
}
|
||||
|
||||
static b32
|
||||
ui_Button(ui_interface* Interface, string Text, rect Bounds)
|
||||
{
|
||||
v4 BGColor = Interface->Style.ButtonColor_Inactive;
|
||||
v4 HoverColor = Interface->Style.ButtonColor_Active;
|
||||
v4 SelectedColor = Interface->Style.ButtonColor_Selected;
|
||||
return ui_Button(Interface, Text, Bounds, BGColor, HoverColor, SelectedColor);
|
||||
}
|
||||
|
||||
static b32
|
||||
ui_LayoutButton(ui_interface* Interface, string Text, ui_layout* Layout)
|
||||
{
|
||||
rect ButtonBounds = {0};
|
||||
if (!ui_TryReserveElementBounds(Layout, &ButtonBounds))
|
||||
{
|
||||
ButtonBounds = ui_ReserveTextLineBounds(*Interface, Text, Layout);
|
||||
}
|
||||
|
||||
v4 BGColor = Interface->Style.ButtonColor_Inactive;
|
||||
v4 HoverColor = Interface->Style.ButtonColor_Active;
|
||||
v4 SelectedColor = Interface->Style.ButtonColor_Selected;
|
||||
return ui_Button(Interface, Text, ButtonBounds, BGColor, HoverColor, SelectedColor);
|
||||
}
|
||||
|
||||
static b32
|
||||
ui_LayoutListEntry(ui_interface* Interface, ui_layout* Layout, string Text, u32 Index)
|
||||
{
|
||||
rect Bounds = {0};
|
||||
if (!ui_TryReserveElementBounds(Layout, &Bounds))
|
||||
{
|
||||
// TODO(Peter): this isn't really invalid, but I don't have a concrete use case
|
||||
// for it yet. This should only fire if the Layout component is drawing a row,
|
||||
// but if you're in row mode during a list, what should happen?
|
||||
// Punting this till I have a use case
|
||||
InvalidCodePath;
|
||||
}
|
||||
v4 BGColor = Interface->Style.ListBGColors[Index % LIST_BG_COLORS_COUNT];
|
||||
v4 HoverColor = Interface->Style.ListBGHover;
|
||||
v4 SelectedColor = Interface->Style.ListBGSelected;
|
||||
return ui_Button(Interface, Text, Bounds, BGColor, HoverColor, SelectedColor);
|
||||
}
|
||||
|
||||
//
|
||||
// OLD
|
||||
//
|
||||
|
||||
struct slider_result
|
||||
{
|
||||
r32 Percent;
|
||||
|
@ -383,54 +452,6 @@ EvaluateSlider (render_command_buffer* RenderBuffer, v2 Min, v2 Max, string Labe
|
|||
return Result;
|
||||
}
|
||||
|
||||
struct panel_result
|
||||
{
|
||||
v2 NextPanelMin;
|
||||
v2 ChildMin, ChildMax;
|
||||
};
|
||||
|
||||
internal panel_result
|
||||
EvaluatePanel (render_command_buffer* RenderBuffer, v2 Min, v2 Max, interface_config Config)
|
||||
{
|
||||
panel_result Result = {};
|
||||
|
||||
Result.ChildMin = Min + Config.Margin;
|
||||
Result.ChildMax = Max - Config.Margin;
|
||||
Result.NextPanelMin = v2{Max.x, Min.y};
|
||||
|
||||
v4 BG = Config.PanelBGColors[0];
|
||||
PushRenderQuad2D(RenderBuffer, Min, Max, BG);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal panel_result
|
||||
EvaluatePanel (render_command_buffer* RenderBuffer, v2 Min, v2 Max, string Label, interface_config Config)
|
||||
{
|
||||
panel_result Result = EvaluatePanel(RenderBuffer, Min, Max, Config);
|
||||
|
||||
v2 TextPos = v2{
|
||||
Min.x + Config.Margin.x,
|
||||
Max.y - ((r32)NewLineYOffset(*Config.Font) + Config.Margin.y)
|
||||
};
|
||||
DrawString(RenderBuffer, Label, Config.Font, TextPos, Config.TextColor);
|
||||
Result.ChildMax = v2{Max.x, TextPos.y} - Config.Margin;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal panel_result
|
||||
EvaluatePanel(render_command_buffer* RenderBuffer, panel_result* ParentPanel, r32 Height, string Title, interface_config Config)
|
||||
{
|
||||
v2 Min = v2{ParentPanel->ChildMin.x, ParentPanel->ChildMax.y - Height};
|
||||
v2 Max = ParentPanel->ChildMax;
|
||||
panel_result Result = EvaluatePanel(RenderBuffer, Min, Max, Title, Config);
|
||||
|
||||
ParentPanel->ChildMax.y = Min.y - Config.Margin.y;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
enum selection_state
|
||||
{
|
||||
Selection_None,
|
||||
|
@ -566,24 +587,27 @@ struct search_lister_result
|
|||
typedef string search_lister_get_list_item_at_offset(u8* ListMemory, s32 ListLength, string SearchString, s32 Offset);
|
||||
|
||||
internal search_lister_result
|
||||
EvaluateSearchLister (render_command_buffer* RenderBuffer, v2 TopLeft, v2 Dimension, string Title,
|
||||
EvaluateSearchLister (ui_interface* Interface, v2 TopLeft, v2 Dimension, string Title,
|
||||
string* ItemList, s32* ListLUT, s32 ListLength,
|
||||
s32 HotItem,
|
||||
string* SearchString, s32 SearchStringCursorPosition,
|
||||
bitmap_font* Font, interface_config Config, mouse_state Mouse)
|
||||
string* SearchString, s32 SearchStringCursorPosition)
|
||||
{
|
||||
search_lister_result Result = {};
|
||||
Result.ShouldRemainOpen = true;
|
||||
Result.HotItem = HotItem;
|
||||
|
||||
// TODO(Peter): Was tired. Nothing wrong with the code below
|
||||
InvalidCodePath;
|
||||
#if 0
|
||||
// Title Bar
|
||||
PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f});
|
||||
DrawString(RenderBuffer, Title, Font, v2{TopLeft.x, TopLeft.y - 25}, WhiteV4);
|
||||
rect TitleBarBounds = rect{v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}};
|
||||
ui_FillRect(Interface, TitleBarBounds, v4{.3f, .3f, .3f, 1.f});
|
||||
ui_DrawString(Interface, Title, TitleBarBounds, Interface->Style.TextColor);
|
||||
|
||||
MakeStringBuffer(DebugString, 256);
|
||||
PrintF(&DebugString, "Hot Item: %d | Filtered Items: %d", HotItem, ListLength);
|
||||
DrawString(RenderBuffer, DebugString, Font, v2{TopLeft.x + 256, TopLeft.y - 25}, WhiteV4);
|
||||
TopLeft.y -= 30;
|
||||
rect DebugBounds = MakeRectMinWidth(v2{ TopLeft.x + 256, TopLeft.y - 25}, v2{256, Interface->Style.LineHeight});
|
||||
ui_DrawString(Interface, DebugString, DebugBounds, Interface->Style.TextColor);
|
||||
|
||||
// Search Bar
|
||||
PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f});
|
||||
|
@ -604,16 +628,14 @@ EvaluateSearchLister (render_command_buffer* RenderBuffer, v2 TopLeft, v2 Dimens
|
|||
ButtonColor = Config.ButtonColor_Active;
|
||||
}
|
||||
|
||||
button_result Button = EvaluateButton(RenderBuffer, Min, Max, Config.Margin, ListItemString,
|
||||
ButtonColor, ButtonColor, Config.TextColor, Config.TextColor,
|
||||
Config.Font, Mouse);
|
||||
if (Button.Pressed)
|
||||
if (ui_Button(Interface, ListItemString, rect{Min, Max}))
|
||||
{
|
||||
Result.SelectedItem = i;
|
||||
}
|
||||
|
||||
TopLeft.y -= 30;
|
||||
}
|
||||
#endif
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
|
|
@ -30,15 +30,14 @@ RenderNodeLister(panel Panel, rect PanelBounds, render_command_buffer* RenderBuf
|
|||
FilterSearchLister(&OpState->SearchLister);
|
||||
|
||||
// Display Search Lister
|
||||
search_lister_result NodeListerResult = EvaluateSearchLister (RenderBuffer, TopLeft, Dimension,
|
||||
search_lister_result NodeListerResult = EvaluateSearchLister (&State->Interface_, TopLeft, Dimension,
|
||||
MakeStringLiteral("Nodes List"),
|
||||
OpState->SearchLister.SourceList,
|
||||
OpState->SearchLister.FilteredIndexLUT,
|
||||
OpState->SearchLister.FilteredListCount,
|
||||
OpState->SearchLister.HotItem,
|
||||
&State->ActiveTextEntry.Buffer,
|
||||
State->ActiveTextEntry.CursorPosition,
|
||||
State->Font, State->Interface, Mouse);
|
||||
State->ActiveTextEntry.CursorPosition);
|
||||
}
|
||||
|
||||
FOLDHAUS_INPUT_COMMAND_PROC(NodeListerNextItem)
|
||||
|
|
|
@ -448,43 +448,34 @@ DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range V
|
|||
}
|
||||
|
||||
internal gs_list_handle
|
||||
DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_state* TimelineState, rect PanelBounds, gs_list_handle SelectedBlockHandle, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse)
|
||||
DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_state* TimelineState, rect PanelBounds, gs_list_handle SelectedBlockHandle, ui_interface* Interface, app_state* State)
|
||||
{
|
||||
string TempString = MakeString(PushArray(&State->Transient, char, 256), 256);
|
||||
gs_list_handle Result = SelectedBlockHandle;
|
||||
|
||||
r32 AnimationPanelHeight = PanelBounds.Max.y - PanelBounds.Min.y;
|
||||
r32 AnimationPanelWidth = PanelBounds.Max.x - PanelBounds.Min.x;
|
||||
rect LayerMenuBounds, TimelineBounds;
|
||||
VSplitRectAtDistanceFromLeft(PanelBounds, 256, &LayerMenuBounds, &TimelineBounds);
|
||||
|
||||
rect LayerMenuBounds = {0};
|
||||
LayerMenuBounds.Min = PanelBounds.Min;
|
||||
LayerMenuBounds.Max = { PanelBounds.Min.x + 256, PanelBounds.Max.y };
|
||||
// In Top To Bottom Order
|
||||
rect TimelineFrameBarBounds, TimelineBlockDisplayBounds, TimelineRangeBarBounds;
|
||||
HSplitRectAtDistanceFromTop(TimelineBounds, 32, &TimelineFrameBarBounds, &TimelineBounds);
|
||||
HSplitRectAtDistanceFromBottom(TimelineBounds, 24, &TimelineBlockDisplayBounds, &TimelineRangeBarBounds);
|
||||
|
||||
rect TimeRangeBarBounds = {0};
|
||||
TimeRangeBarBounds.Min = BottomRight(LayerMenuBounds);
|
||||
TimeRangeBarBounds.Max = { PanelBounds.Max.x, PanelBounds.Min.y + 24 };
|
||||
|
||||
rect FrameBarBounds = {0};
|
||||
FrameBarBounds.Min = { LayerMenuBounds.Max.x, PanelBounds.Max.y - 32 };
|
||||
FrameBarBounds.Max = PanelBounds.Max;
|
||||
|
||||
rect TimelineBounds = {0};
|
||||
TimelineBounds.Min = TopLeft(TimeRangeBarBounds);
|
||||
TimelineBounds.Max = BottomRight(FrameBarBounds);
|
||||
|
||||
DrawLayerMenu(AnimationSystem, LayerMenuBounds, RenderBuffer, State, Mouse);
|
||||
// TODO(Peter): Clean Up
|
||||
DrawLayerMenu(AnimationSystem, LayerMenuBounds, Interface->RenderBuffer, State, Interface->Mouse);
|
||||
|
||||
frame_range AdjustedViewRange = {0};
|
||||
AdjustedViewRange = DrawTimelineRangeBar(AnimationSystem, TimelineState, RenderBuffer, TimeRangeBarBounds, Mouse);
|
||||
// TODO(Peter): Clean Up
|
||||
AdjustedViewRange = DrawTimelineRangeBar(AnimationSystem, TimelineState, Interface->RenderBuffer, TimelineRangeBarBounds, Interface->Mouse);
|
||||
s32 VisibleFrameCount = AdjustedViewRange.Max - AdjustedViewRange.Min;
|
||||
|
||||
DrawFrameBar(AnimationSystem, RenderBuffer, AdjustedViewRange, FrameBarBounds, Mouse, State);
|
||||
// TODO(Peter): Clean Up
|
||||
DrawFrameBar(AnimationSystem, Interface->RenderBuffer, AdjustedViewRange, TimelineFrameBarBounds, Interface->Mouse, State);
|
||||
|
||||
// Timeline
|
||||
PushRenderQuad2D(RenderBuffer, RectExpand(TimelineBounds), v4{.25f, .25f, .25f, 1.f});
|
||||
ui_FillRect(Interface, TimelineBlockDisplayBounds, v4{.25f, .25f, .25f, 1.0f});
|
||||
|
||||
// Animation Blocks
|
||||
b32 MouseDownAndNotHandled = MouseButtonTransitionedDown(Mouse.LeftButtonState);
|
||||
b32 MouseDownAndNotHandled = MouseButtonTransitionedDown(Interface->Mouse.LeftButtonState);
|
||||
gs_list_handle DragBlockHandle = {0};
|
||||
for (u32 i = 0; i < AnimationSystem->Blocks.Used; i++)
|
||||
{
|
||||
|
@ -508,8 +499,9 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
|
|||
{
|
||||
BlockColor = PinkV4;
|
||||
}
|
||||
rect BlockBounds = DrawAnimationBlock(AnimationBlockAt, BlockColor, AdjustedViewRange, TimelineBounds, RenderBuffer);
|
||||
if (PointIsInRange(Mouse.Pos, BlockBounds.Min, BlockBounds.Max))
|
||||
// TODO(Peter): Clean Up
|
||||
rect BlockBounds = DrawAnimationBlock(AnimationBlockAt, BlockColor, AdjustedViewRange, TimelineBounds, Interface->RenderBuffer);
|
||||
if (PointIsInRect(Interface->Mouse.Pos, BlockBounds))
|
||||
{
|
||||
DragBlockHandle = CurrentBlockHandle;
|
||||
}
|
||||
|
@ -519,6 +511,7 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
|
|||
if (MouseDownAndNotHandled && ListHandleIsValid(DragBlockHandle))
|
||||
{
|
||||
MouseDownAndNotHandled = false;
|
||||
// TODO(Peter): Why are we passing state around?
|
||||
SelectAndBeginDragAnimationBlock(DragBlockHandle, AdjustedViewRange, TimelineBounds, State);
|
||||
}
|
||||
|
||||
|
@ -527,16 +520,18 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
|
|||
{
|
||||
r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, AdjustedViewRange);
|
||||
r32 SliderX = GSLerp(TimelineBounds.Min.x, TimelineBounds.Max.x, FrameAtPercentVisibleRange);
|
||||
v2 SliderMin = v2{SliderX, TimelineBounds.Min.y};
|
||||
v2 SliderMax = v2{SliderX + 1, TimelineBounds.Max.y};
|
||||
PushRenderQuad2D(RenderBuffer, SliderMin, SliderMax, TimeSliderColor);
|
||||
rect SliderBounds = {
|
||||
v2{ SliderX, TimelineBounds.Min.y },
|
||||
v2{ SliderX + 1, TimelineBounds.Max.y }
|
||||
};
|
||||
ui_FillRect(Interface, SliderBounds, TimeSliderColor);
|
||||
}
|
||||
|
||||
PushRenderBoundingBox2D(RenderBuffer, RectExpand(TimeRangeBarBounds), 1.f, RedV4);
|
||||
PushRenderBoundingBox2D(RenderBuffer, RectExpand(FrameBarBounds), 1.f, TealV4);
|
||||
PushRenderBoundingBox2D(RenderBuffer, RectExpand(TimelineBounds), 1.f, PinkV4);
|
||||
ui_OutlineRect(Interface, TimelineRangeBarBounds, 1.f, RedV4);
|
||||
ui_OutlineRect(Interface, TimelineFrameBarBounds, 1.f, RedV4);
|
||||
ui_OutlineRect(Interface, TimelineBlockDisplayBounds, 1.f, RedV4);
|
||||
|
||||
if (MouseDownAndNotHandled && PointIsInRect(Mouse.Pos, TimelineBounds))
|
||||
if (MouseDownAndNotHandled && PointIsInRect(Interface->Mouse.Pos, TimelineBounds))
|
||||
{
|
||||
DeselectCurrentAnimationBlock(State);
|
||||
}
|
||||
|
@ -559,42 +554,19 @@ animation_clip GlobalAnimationClips[] = {
|
|||
};
|
||||
|
||||
internal void
|
||||
DrawAnimationClipsList(rect PanelBounds, mouse_state Mouse, render_command_buffer* RenderBuffer, app_state* State)
|
||||
DrawAnimationClipsList(rect PanelBounds, ui_interface* Interface, u32 SelectedAnimationLayer, animation_system* AnimationSystem)
|
||||
{
|
||||
v4 LineBGColors[] = {
|
||||
{ .16f, .16f, .16f, 1.f },
|
||||
{ .18f, .18f, .18f, 1.f },
|
||||
};
|
||||
|
||||
interface_list List = {};
|
||||
|
||||
List.LineBGColors = LineBGColors;
|
||||
List.LineBGColorsCount = sizeof(LineBGColors) / sizeof(LineBGColors[0]);
|
||||
List.LineBGHoverColor = v4{ .22f, .22f, .22f, 1.f };
|
||||
List.TextColor = WhiteV4;
|
||||
List.ListBounds = PanelBounds;
|
||||
List.ListElementDimensions = v2{
|
||||
Width(PanelBounds),
|
||||
(r32)(State->Interface.Font->PixelHeight + 8),
|
||||
};
|
||||
List.ElementLabelIndent = v2{10, 4};
|
||||
|
||||
string TitleString = MakeStringLiteral("Animation Clips");
|
||||
DrawListElement(TitleString, &List, Mouse, RenderBuffer, State->Interface);
|
||||
|
||||
ui_layout Layout = ui_CreateLayout(*Interface, PanelBounds);
|
||||
for (s32 i = 0; i < GlobalAnimationClipsCount; i++)
|
||||
{
|
||||
animation_clip Clip = GlobalAnimationClips[i];
|
||||
string ClipName = MakeString(Clip.Name, Clip.NameLength);
|
||||
rect ElementBounds = DrawListElement(ClipName, &List, Mouse, RenderBuffer, State->Interface);
|
||||
|
||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
|
||||
&& PointIsInRect(Mouse.DownPos, ElementBounds))
|
||||
if (ui_LayoutListEntry(Interface, &Layout, ClipName, i))
|
||||
{
|
||||
AddAnimationBlockAtCurrentTime(i + 1, State->SelectedAnimationLayer, &State->AnimationSystem);
|
||||
AddAnimationBlockAtCurrentTime(i + 1, SelectedAnimationLayer, AnimationSystem);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(Peter): Fill up the rest of the area with empty list entries
|
||||
}
|
||||
|
||||
GSMetaTag(panel_render);
|
||||
|
@ -603,69 +575,42 @@ internal void
|
|||
AnimationTimeline_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context, mouse_state Mouse)
|
||||
{
|
||||
animation_timeline_state* TimelineState = (animation_timeline_state*)Panel.PanelStateMemory;
|
||||
|
||||
gs_list_handle SelectedBlockHandle = State->SelectedAnimationBlockHandle;
|
||||
|
||||
r32 OptionsRowHeight = 25;
|
||||
rect AnimationClipListBounds = rect{
|
||||
PanelBounds.Min,
|
||||
v2{PanelBounds.Min.x + 300, PanelBounds.Max.y - OptionsRowHeight},
|
||||
};
|
||||
rect TimelineBounds = rect{
|
||||
v2{AnimationClipListBounds.Max.x, PanelBounds.Min.y},
|
||||
v2{PanelBounds.Max.x, PanelBounds.Max.y - OptionsRowHeight},
|
||||
};
|
||||
ui_interface* Interface = &State->Interface_;
|
||||
animation_system* AnimationSystem = &State->AnimationSystem;
|
||||
|
||||
if (Height(TimelineBounds) > 0)
|
||||
rect TitleBarBounds, PanelContentsBounds;
|
||||
HSplitRectAtDistanceFromTop(PanelBounds, Interface->Style.RowHeight, &TitleBarBounds, &PanelContentsBounds);
|
||||
rect AnimationListBounds, TimelineBounds;
|
||||
VSplitRectAtDistanceFromLeft(PanelContentsBounds, 300, &AnimationListBounds, &TimelineBounds);
|
||||
|
||||
ui_FillRect(Interface, TitleBarBounds, Interface->Style.PanelBGColors[0]);
|
||||
ui_layout TitleBarLayout = ui_CreateLayout(*Interface, TitleBarBounds);
|
||||
ui_StartRow(&TitleBarLayout, 3);
|
||||
{
|
||||
SelectedBlockHandle = DrawAnimationTimeline(&State->AnimationSystem,
|
||||
TimelineState,
|
||||
TimelineBounds,
|
||||
SelectedBlockHandle,
|
||||
RenderBuffer, State, Mouse);
|
||||
DrawAnimationClipsList(AnimationClipListBounds, Mouse, RenderBuffer, State);
|
||||
}
|
||||
|
||||
v2 OptionsRowMin = v2{ PanelBounds.Min.x, TimelineBounds.Max.y };
|
||||
v2 OptionsRowMax = PanelBounds.Max;
|
||||
panel_result AnimationPanel = EvaluatePanel(RenderBuffer, OptionsRowMin, OptionsRowMax, State->Interface);
|
||||
|
||||
r32 ButtonWidth = 35;
|
||||
v2 ButtonMin = v2{0, 0};
|
||||
v2 ButtonMax = v2{35, OptionsRowHeight - 2};
|
||||
v2 ButtonAt = v2{OptionsRowMin.x + 1, OptionsRowMin.y + 1};
|
||||
|
||||
button_result PauseResult = EvaluateButton(RenderBuffer,
|
||||
ButtonAt + ButtonMin, ButtonAt + ButtonMax,
|
||||
MakeStringLiteral("Pause"),
|
||||
State->Interface, Mouse);
|
||||
ButtonAt.x += ButtonWidth + 2;
|
||||
button_result PlayResult = EvaluateButton(RenderBuffer,
|
||||
ButtonAt + ButtonMin, ButtonAt + ButtonMax,
|
||||
MakeStringLiteral("Play"),
|
||||
State->Interface, Mouse);
|
||||
ButtonAt.x += ButtonWidth + 2;
|
||||
button_result StopResult = EvaluateButton(RenderBuffer,
|
||||
ButtonAt + ButtonMin, ButtonAt + ButtonMax,
|
||||
MakeStringLiteral("Stop"),
|
||||
State->Interface, Mouse);
|
||||
|
||||
if (PauseResult.Pressed)
|
||||
{
|
||||
State->AnimationSystem.TimelineShouldAdvance = false;
|
||||
}
|
||||
|
||||
if (PlayResult.Pressed)
|
||||
if (ui_LayoutButton(Interface, MakeStringLiteral("Pause"), &TitleBarLayout))
|
||||
{
|
||||
State->AnimationSystem.TimelineShouldAdvance = true;
|
||||
}
|
||||
|
||||
if (StopResult.Pressed)
|
||||
if (ui_LayoutButton(Interface, MakeStringLiteral("Play"), &TitleBarLayout))
|
||||
{
|
||||
State->AnimationSystem.TimelineShouldAdvance = false;
|
||||
}
|
||||
if (ui_LayoutButton(Interface, MakeStringLiteral("Stop"), &TitleBarLayout))
|
||||
{
|
||||
State->AnimationSystem.TimelineShouldAdvance = false;
|
||||
State->AnimationSystem.CurrentFrame = 0;
|
||||
}
|
||||
}
|
||||
ui_EndRow(&TitleBarLayout);
|
||||
|
||||
if (Height(TimelineBounds) > 0)
|
||||
{
|
||||
SelectedBlockHandle = DrawAnimationTimeline(AnimationSystem, TimelineState, TimelineBounds, SelectedBlockHandle, Interface, State);
|
||||
DrawAnimationClipsList(AnimationListBounds, Interface, State->SelectedAnimationLayer, &State->AnimationSystem);
|
||||
}
|
||||
}
|
||||
|
||||
#define FOLDHAUS_PANEL_ANIMATION_TIMELINE_H
|
||||
#endif // FOLDHAUS_PANEL_ANIMATION_TIMELINE_H
|
|
@ -37,6 +37,7 @@ HierarchyView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
|
|||
{ .18f, .18f, .18f, 1.f },
|
||||
};
|
||||
|
||||
// TODO(Peter): use the new ui system
|
||||
interface_list List = {};
|
||||
List.LineBGColors = LineBGColors;
|
||||
List.LineBGColorsCount = sizeof(LineBGColors) / sizeof(LineBGColors[0]);
|
||||
|
|
|
@ -178,41 +178,39 @@ ProfilerView_Render(panel Panel, rect PanelBounds, render_command_buffer* Render
|
|||
FrameTotalCycles);
|
||||
DrawString(RenderBuffer, String, State->Interface.Font, FrameListMin - v2{0, 32}, WhiteV4);
|
||||
|
||||
v2 ButtonMin = v2{FrameListMax.x - 128, FrameListMin.y - 32};
|
||||
v2 ButtonMax = ButtonMin + v2{128, 28};
|
||||
button_result ShouldResumeRecording = EvaluateButton(RenderBuffer, ButtonMin, ButtonMax,
|
||||
MakeString("Resume Recording"), State->Interface, Mouse);
|
||||
if (ShouldResumeRecording.Pressed)
|
||||
rect ResumeRecordingBtnBounds = MakeRectMinWidth(v2{ FrameListMax.x - 128, FrameListMin.y - 32 }, v2{ 128, 28 });
|
||||
if (ui_Button(&State->Interface_, MakeString("Resume Recording"), ResumeRecordingBtnBounds))
|
||||
{
|
||||
GlobalDebugServices->RecordFrames = true;
|
||||
}
|
||||
|
||||
ButtonMin = v2{FrameListMin.x, FrameListMin.y - 60};
|
||||
ButtonMax = v2{FrameListMin.x + 128, FrameListMin.y - 42};
|
||||
button_result ActivateScopeView = EvaluateButton(RenderBuffer, ButtonMin, ButtonMax,
|
||||
MakeString("Scope View"), State->Interface, Mouse);
|
||||
rect ScopeViewBtnBounds = {
|
||||
v2{ FrameListMin.x, FrameListMin.y - 60 },
|
||||
v2{ FrameListMin.x + 128, FrameListMin.y - 42 }
|
||||
};
|
||||
if (ui_Button(&State->Interface_, MakeString("Scope View"), ScopeViewBtnBounds))
|
||||
{
|
||||
GlobalDebugServices->Interface.FrameView = FRAME_VIEW_PROFILER;
|
||||
}
|
||||
|
||||
ButtonMin.x += 152;
|
||||
ButtonMax.x += 152;
|
||||
button_result ActivateListView = EvaluateButton(RenderBuffer, ButtonMin, ButtonMax,
|
||||
MakeString("List View"), State->Interface, Mouse);
|
||||
|
||||
if (ActivateScopeView.Pressed) { GlobalDebugServices->Interface.FrameView = FRAME_VIEW_PROFILER; }
|
||||
if (ActivateListView.Pressed) { GlobalDebugServices->Interface.FrameView = FRAME_VIEW_SCOPE_LIST; }
|
||||
|
||||
v2 ViewModeMin = v2{FrameListMin.x, PanelBounds.Min.y};
|
||||
v2 ViewModeMax = v2{FrameListMax.x, FrameListMin.y - 96};
|
||||
rect ListViewBtnBounds = TranslateRectX(ScopeViewBtnBounds, 152);
|
||||
if (ui_Button(&State->Interface_, MakeString("List View"), ListViewBtnBounds))
|
||||
{
|
||||
GlobalDebugServices->Interface.FrameView = FRAME_VIEW_SCOPE_LIST;
|
||||
}
|
||||
|
||||
rect ViewModeBounds = {
|
||||
v2{ FrameListMin.x, PanelBounds.Min.y },
|
||||
v2{ FrameListMax.x, FrameListMin.y - 96 }
|
||||
};
|
||||
if (GlobalDebugServices->Interface.FrameView == FRAME_VIEW_PROFILER)
|
||||
{
|
||||
RenderProfiler_ScopeVisualization(RenderBuffer, State->Interface, Mouse,
|
||||
ViewModeMin, ViewModeMax,
|
||||
RenderProfiler_ScopeVisualization(RenderBuffer, State->Interface, Mouse, RectExpand(ViewModeBounds),
|
||||
VisibleFrame, Memory);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderProfiler_ListVisualization(RenderBuffer, State->Interface, Mouse,
|
||||
ViewModeMin, ViewModeMax,
|
||||
RenderProfiler_ListVisualization(RenderBuffer, State->Interface, Mouse, RectExpand(ViewModeBounds),
|
||||
VisibleFrame, Memory);
|
||||
}
|
||||
}
|
||||
|
|
7
todo.txt
7
todo.txt
|
@ -4,7 +4,7 @@ TODO FOLDHAUS
|
|||
- fix memory layout (remeber to profile before and after)
|
||||
|
||||
- Make the DLL truly platform agnostic
|
||||
- math.h: present for trig functions
|
||||
- math.h: present for trig functions (though this is part of the c-std lib, so it should be everywhere)
|
||||
- windows.h: only thing left is InterlockedIncrement and InterlockedAdd
|
||||
|
||||
- Win32 Platform Layer
|
||||
|
@ -20,10 +20,9 @@ TODO FOLDHAUS
|
|||
- Make sure it works without building in Debug Mode
|
||||
|
||||
- Buckets & Lists
|
||||
- Allow them to use memory arenas
|
||||
- Zero is initialization
|
||||
- On second thought, I just really don't like these. Lets get rid of them, and put custom structures in place
|
||||
|
||||
- Rendering
|
||||
- Rendering (Working on this elsewhere)
|
||||
- OpenGL 3
|
||||
- Vertex Buffers
|
||||
- Layers
|
||||
|
|
Loading…
Reference in New Issue