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
|
// which makes refactoring easier as you only have to change the identifier in one place
|
||||||
#define RectExpand(r) (r).Min, (r).Max
|
#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
|
inline float
|
||||||
Width (rect Rect)
|
Width (rect Rect)
|
||||||
{
|
{
|
||||||
|
@ -744,6 +753,104 @@ RectOffsetByVector(rect R, v2 V)
|
||||||
return Result;
|
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
|
// MATRIX
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
|
|
@ -156,7 +156,14 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
State->Interface.ButtonColor_Active = v4{.1f, .1f, .1f, 1};
|
State->Interface.ButtonColor_Active = v4{.1f, .1f, .1f, 1};
|
||||||
State->Interface.ButtonColor_Selected = v4{.1f, .1f, .3f, 1};
|
State->Interface.ButtonColor_Selected = v4{.1f, .1f, .3f, 1};
|
||||||
State->Interface.TextColor = WhiteV4;
|
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.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->SACN = InitializeSACN(Context);
|
||||||
State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE;
|
State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE;
|
||||||
|
@ -315,7 +322,6 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
app_state* State = (app_state*)Context->MemoryBase;
|
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,
|
// 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
|
// 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));
|
PushRenderOrthographic(RenderBuffer, 0, 0, Width(State->WindowBounds), Height(State->WindowBounds));
|
||||||
PushRenderClearScreen(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);
|
panel_layout PanelsToRender = GetPanelLayout(&State->PanelSystem, State->WindowBounds, &State->Transient);
|
||||||
DrawAllPanels(PanelsToRender, RenderBuffer, &Context->Mouse, State, *Context);
|
DrawAllPanels(PanelsToRender, RenderBuffer, &Context->Mouse, State, *Context);
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ struct app_state
|
||||||
input_command_queue CommandQueue;
|
input_command_queue CommandQueue;
|
||||||
text_entry ActiveTextEntry;
|
text_entry ActiveTextEntry;
|
||||||
|
|
||||||
|
ui_interface Interface_;
|
||||||
interface_config Interface;
|
interface_config Interface;
|
||||||
|
|
||||||
animation_system AnimationSystem;
|
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)
|
#define PANEL_CLEANUP_PROC(name) void name(panel* Panel, app_state* State)
|
||||||
typedef PANEL_CLEANUP_PROC(panel_cleanup_proc);
|
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)
|
#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);
|
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, v2{FooterBounds.Max.x, FooterBounds.Min.y + 25}, v4{.5f, .5f, .5f, 1.f});
|
||||||
PushRenderQuad2D(RenderBuffer, FooterBounds.Min, FooterBounds.Min + v2{25, 25}, WhiteV4);
|
PushRenderQuad2D(RenderBuffer, FooterBounds.Min, FooterBounds.Min + v2{25, 25}, WhiteV4);
|
||||||
|
|
||||||
v2 PanelSelectButtonMin = FooterBounds.Min + v2{30, 1};
|
rect PanelSelectBtnBounds = MakeRectMinWidth(FooterBounds.Min + v2{30, 1}, v2{100, 23});
|
||||||
v2 PanelSelectButtonMax = PanelSelectButtonMin + v2{100, 23};
|
|
||||||
|
|
||||||
if (Panel->PanelSelectionMenuOpen)
|
if (Panel->PanelSelectionMenuOpen)
|
||||||
{
|
{
|
||||||
v2 ButtonDimension = v2{100, 25};
|
rect ButtonBounds = MakeRectMinWidth(v2{ PanelSelectBtnBounds.Min.x, FooterBounds.Max.y }, v2{ 100, 25 });
|
||||||
v2 ButtonMin = v2{PanelSelectButtonMin.x, FooterBounds.Max.y};
|
|
||||||
|
|
||||||
v2 MenuMin = ButtonMin;
|
v2 MenuMin = ButtonBounds.Min;
|
||||||
v2 MenuMax = v2{ButtonMin.x + ButtonDimension.x, ButtonMin.y + (ButtonDimension.y * GlobalPanelDefsCount)};
|
v2 MenuMax = v2{ButtonBounds.Min.x + Width(ButtonBounds), ButtonBounds.Min.y + (Height(ButtonBounds) * GlobalPanelDefsCount)};
|
||||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
|
if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
|
||||||
&& !PointIsInRange(Mouse.DownPos, MenuMin, MenuMax))
|
&& !PointIsInRange(Mouse.DownPos, MenuMin, MenuMax))
|
||||||
{
|
{
|
||||||
|
@ -424,24 +422,17 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect FooterBo
|
||||||
{
|
{
|
||||||
panel_definition Def = GlobalPanelDefs[i];
|
panel_definition Def = GlobalPanelDefs[i];
|
||||||
string DefName = MakeString(Def.PanelName, Def.PanelNameLength);
|
string DefName = MakeString(Def.PanelName, Def.PanelNameLength);
|
||||||
button_result DefinitionButton = EvaluateButton(RenderBuffer,
|
if (ui_Button(&State->Interface_, DefName, ButtonBounds))
|
||||||
ButtonMin, ButtonMin + ButtonDimension,
|
|
||||||
DefName, State->Interface, Mouse);
|
|
||||||
if (DefinitionButton.Pressed)
|
|
||||||
{
|
{
|
||||||
SetPanelDefinition(Panel, i, State);
|
SetPanelDefinition(Panel, i, State);
|
||||||
Panel->PanelSelectionMenuOpen = false;
|
Panel->PanelSelectionMenuOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ButtonMin.y += ButtonDimension.y;
|
ButtonBounds = TranslateRectY(ButtonBounds, Height(ButtonBounds));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button_result ButtonResult = EvaluateButton(RenderBuffer,
|
if (ui_Button(&State->Interface_, MakeStringLiteral("Select"), PanelSelectBtnBounds))
|
||||||
PanelSelectButtonMin,
|
|
||||||
PanelSelectButtonMax,
|
|
||||||
MakeStringLiteral("Select"), State->Interface, Mouse);
|
|
||||||
if (ButtonResult.Pressed)
|
|
||||||
{
|
{
|
||||||
Panel->PanelSelectionMenuOpen = !Panel->PanelSelectionMenuOpen;
|
Panel->PanelSelectionMenuOpen = !Panel->PanelSelectionMenuOpen;
|
||||||
}
|
}
|
||||||
|
|
384
src/interface.h
384
src/interface.h
|
@ -60,7 +60,7 @@ DrawCharacterRightAligned (render_quad_batch_constructor* BatchConstructor, char
|
||||||
}
|
}
|
||||||
|
|
||||||
internal v2
|
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;
|
v2 RegisterPosition = InitialRegisterPosition;
|
||||||
char* C = String;
|
char* C = String;
|
||||||
|
@ -74,7 +74,7 @@ DrawStringLeftAligned (render_quad_batch_constructor* BatchConstructor, char* St
|
||||||
}
|
}
|
||||||
|
|
||||||
internal v2
|
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;
|
v2 RegisterPosition = InitialRegisterPosition;
|
||||||
char* C = String + Length - 1;
|
char* C = String + Length - 1;
|
||||||
|
@ -104,15 +104,11 @@ DrawString (render_command_buffer* RenderBuffer, string String, bitmap_font* Fon
|
||||||
v2 RegisterPosition = Position;
|
v2 RegisterPosition = Position;
|
||||||
if (Alignment == Align_Left)
|
if (Alignment == Align_Left)
|
||||||
{
|
{
|
||||||
RegisterPosition = DrawStringLeftAligned(&BatchConstructor,
|
RegisterPosition = DrawStringLeftAligned(&BatchConstructor, StringExpand(String), RegisterPosition, Font, Color);
|
||||||
String.Memory, String.Length,
|
|
||||||
RegisterPosition, Font, Color);
|
|
||||||
}
|
}
|
||||||
else if (Alignment == Align_Right)
|
else if (Alignment == Align_Right)
|
||||||
{
|
{
|
||||||
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
|
RegisterPosition = DrawStringRightAligned(&BatchConstructor, StringExpand(String), RegisterPosition, Font, Color);
|
||||||
String.Memory, String.Length,
|
|
||||||
RegisterPosition, Font, Color);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -151,29 +147,27 @@ DrawStringWithCursor (render_command_buffer* RenderBuffer, string String, s32 Cu
|
||||||
v2 RegisterPosition = Position;
|
v2 RegisterPosition = Position;
|
||||||
if (Alignment == Align_Left)
|
if (Alignment == Align_Left)
|
||||||
{
|
{
|
||||||
RegisterPosition = DrawStringLeftAligned(&BatchConstructor,
|
RegisterPosition = DrawStringLeftAligned(&BatchConstructor, StringExpand(String), RegisterPosition, Font, Color);
|
||||||
String.Memory, CursorPosition,
|
|
||||||
RegisterPosition, Font, Color);
|
|
||||||
DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font);
|
DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font);
|
||||||
if (String.Length - CursorPosition > 0)
|
if (String.Length - CursorPosition > 0)
|
||||||
{
|
{
|
||||||
RegisterPosition = DrawStringLeftAligned(&BatchConstructor,
|
RegisterPosition = DrawStringLeftAligned(&BatchConstructor,
|
||||||
String.Memory + CursorPosition,
|
|
||||||
String.Length - CursorPosition,
|
String.Length - CursorPosition,
|
||||||
|
String.Memory + CursorPosition,
|
||||||
RegisterPosition, Font, Color);
|
RegisterPosition, Font, Color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Alignment == Align_Right)
|
else if (Alignment == Align_Right)
|
||||||
{
|
{
|
||||||
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
|
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
|
||||||
String.Memory, CursorPosition,
|
CursorPosition, String.Memory,
|
||||||
RegisterPosition, Font, Color);
|
RegisterPosition, Font, Color);
|
||||||
DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font);
|
DrawCursor(&CursorBatch, RegisterPosition, GreenV4, *Font);
|
||||||
if (String.Length - CursorPosition > 0)
|
if (String.Length - CursorPosition > 0)
|
||||||
{
|
{
|
||||||
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
|
RegisterPosition = DrawStringRightAligned(&BatchConstructor,
|
||||||
String.Memory + CursorPosition,
|
|
||||||
String.Length - CursorPosition,
|
String.Length - CursorPosition,
|
||||||
|
String.Memory + CursorPosition,
|
||||||
RegisterPosition, Font, Color);
|
RegisterPosition, Font, Color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,154 +183,229 @@ DrawStringWithCursor (render_command_buffer* RenderBuffer, string String, s32 Cu
|
||||||
struct interface_config
|
struct interface_config
|
||||||
{
|
{
|
||||||
v4 PanelBGColors[4];
|
v4 PanelBGColors[4];
|
||||||
|
|
||||||
v4 ButtonColor_Inactive, ButtonColor_Active, ButtonColor_Selected;
|
v4 ButtonColor_Inactive, ButtonColor_Active, ButtonColor_Selected;
|
||||||
|
|
||||||
v4 TextColor;
|
v4 TextColor;
|
||||||
|
|
||||||
|
#define LIST_BG_COLORS_COUNT 2
|
||||||
|
v4 ListBGColors[LIST_BG_COLORS_COUNT];
|
||||||
|
v4 ListBGHover;
|
||||||
|
v4 ListBGSelected;
|
||||||
|
|
||||||
bitmap_font* Font;
|
bitmap_font* Font;
|
||||||
r32 FontSize;
|
r32 FontSize;
|
||||||
v2 Margin;
|
v2 Margin;
|
||||||
|
r32 RowHeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct button_result
|
struct ui_layout
|
||||||
{
|
{
|
||||||
b32 Pressed;
|
rect Bounds;
|
||||||
r32 Advance;
|
v2 Margin;
|
||||||
|
r32 RowHeight;
|
||||||
|
r32 RowYAt;
|
||||||
|
|
||||||
|
b32 DrawHorizontal;
|
||||||
|
u32 RowDivisions;
|
||||||
|
u32 RowElementsCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal button_result
|
struct ui_interface
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
button_result Result = {};
|
interface_config Style;
|
||||||
Result.Pressed = false;
|
mouse_state Mouse;
|
||||||
|
render_command_buffer* RenderBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
v4 BGColor = IdleBGColor;
|
static ui_layout
|
||||||
v4 TextColor = IdleTextColor;
|
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)
|
||||||
|
{
|
||||||
|
Layout->DrawHorizontal = true;
|
||||||
|
Layout->RowDivisions = RowDivisions;
|
||||||
|
Layout->RowElementsCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ui_StartRow(ui_layout* Layout)
|
||||||
|
{
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
Bounds->Min = { Layout->Bounds.Min.x, Layout->RowYAt };
|
||||||
{
|
Bounds->Max = { Layout->Bounds.Max.x, Bounds->Min.y + Layout->RowHeight };
|
||||||
Result.Pressed = true;
|
Layout->RowYAt -= Layout->RowHeight;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BGColor = HotBGColor;
|
if (Layout->RowDivisions > 0)
|
||||||
TextColor = HotTextColor;
|
{
|
||||||
|
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
|
||||||
|
};
|
||||||
|
Bounds->Max = {
|
||||||
|
Bounds->Min.x + ElementWidth - Layout->Margin.x,
|
||||||
|
Bounds->Min.y + Layout->RowHeight
|
||||||
|
};
|
||||||
|
Layout->RowElementsCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PushRenderQuad2D(RenderBuffer, Min, Max, BGColor);
|
|
||||||
DrawString(RenderBuffer, Label, Font, Min + Margin, TextColor);
|
|
||||||
|
|
||||||
Result.Advance = (Max.y - Min.y) + Margin.y;
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal button_result
|
static rect
|
||||||
EvaluateButton (render_command_buffer* RenderBuffer, v2 Min, v2 Max, string Label, interface_config Config, mouse_state Mouse)
|
ui_ReserveTextLineBounds(ui_interface Interface, string Text, ui_layout* Layout)
|
||||||
{
|
{
|
||||||
button_result Result = EvaluateButton(RenderBuffer,
|
rect Bounds = {0};
|
||||||
Min, Max, Config.Margin, Label,
|
|
||||||
Config.ButtonColor_Inactive, Config.ButtonColor_Active,
|
return Bounds;
|
||||||
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)
|
// Drawing Functions
|
||||||
{
|
//
|
||||||
v4 BGColor = Config.ButtonColor_Inactive;
|
|
||||||
if (Selected)
|
|
||||||
{
|
|
||||||
BGColor = Config.ButtonColor_Selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
button_result Result = EvaluateButton(RenderBuffer,
|
static void
|
||||||
Min, Max, Config.Margin, Label,
|
ui_FillRect(ui_interface* Interface, rect Bounds, v4 Color)
|
||||||
Config.ButtonColor_Inactive, Config.ButtonColor_Active,
|
{
|
||||||
Config.TextColor, Config.TextColor,
|
PushRenderQuad2D(Interface->RenderBuffer, RectExpand(Bounds), Color);
|
||||||
Config.Font, Mouse);
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct multi_option_label_result
|
static void
|
||||||
|
ui_OutlineRect(ui_interface* Interface, rect Bounds, r32 Thickness, v4 Color)
|
||||||
{
|
{
|
||||||
b32 Pressed;
|
PushRenderBoundingBox2D(Interface->RenderBuffer, Bounds.Min, Bounds.Max, Thickness, Color);
|
||||||
s32 IndexPressed;
|
|
||||||
r32 Advance;
|
|
||||||
};
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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.Advance = (Max.y - Min.y) + Config.Margin.y;
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(Peter): returns IndexPressed = -1 if the button itself is pressed, as opposed
|
internal void
|
||||||
// to one of its options
|
ui_DrawString(ui_interface* Interface, string String, rect Bounds, v4 Color, string_alignment Alignment = Align_Left)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
multi_option_label_result Result = {};
|
DEBUG_TRACK_FUNCTION;
|
||||||
Result.Pressed = false;
|
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);
|
||||||
|
|
||||||
r32 ButtonSide = (Max.y - Min.y) - (2 * Config.Margin.y);
|
v2 RegisterPosition = Bounds.Min + Interface->Style.Margin;
|
||||||
v2 ButtonDim = v2{ButtonSide, ButtonSide};
|
if (Alignment == Align_Left)
|
||||||
|
|
||||||
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;
|
RegisterPosition = DrawStringLeftAligned(&BatchConstructor, StringExpand(String), RegisterPosition, Interface->Style.Font, Color);
|
||||||
Result.IndexPressed = -1;
|
|
||||||
}
|
}
|
||||||
|
else if (Alignment == Align_Right)
|
||||||
v2 ButtonPos = Max - (ButtonDim + Config.Margin);
|
|
||||||
|
|
||||||
for (s32 b = 0; b < OptionsCount; b++)
|
|
||||||
{
|
{
|
||||||
button_result Button = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
RegisterPosition = DrawStringRightAligned(&BatchConstructor, StringExpand(String), RegisterPosition, Interface->Style.Font, Color);
|
||||||
Options[b], Config, Mouse);
|
}
|
||||||
if (Button.Pressed)
|
else
|
||||||
{
|
{
|
||||||
Result.Pressed = true;
|
InvalidCodePath;
|
||||||
Result.IndexPressed = b;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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
|
struct slider_result
|
||||||
{
|
{
|
||||||
r32 Percent;
|
r32 Percent;
|
||||||
|
@ -383,54 +452,6 @@ EvaluateSlider (render_command_buffer* RenderBuffer, v2 Min, v2 Max, string Labe
|
||||||
return Result;
|
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
|
enum selection_state
|
||||||
{
|
{
|
||||||
Selection_None,
|
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);
|
typedef string search_lister_get_list_item_at_offset(u8* ListMemory, s32 ListLength, string SearchString, s32 Offset);
|
||||||
|
|
||||||
internal search_lister_result
|
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,
|
string* ItemList, s32* ListLUT, s32 ListLength,
|
||||||
s32 HotItem,
|
s32 HotItem,
|
||||||
string* SearchString, s32 SearchStringCursorPosition,
|
string* SearchString, s32 SearchStringCursorPosition)
|
||||||
bitmap_font* Font, interface_config Config, mouse_state Mouse)
|
|
||||||
{
|
{
|
||||||
search_lister_result Result = {};
|
search_lister_result Result = {};
|
||||||
Result.ShouldRemainOpen = true;
|
Result.ShouldRemainOpen = true;
|
||||||
Result.HotItem = HotItem;
|
Result.HotItem = HotItem;
|
||||||
|
|
||||||
|
// TODO(Peter): Was tired. Nothing wrong with the code below
|
||||||
|
InvalidCodePath;
|
||||||
|
#if 0
|
||||||
// Title Bar
|
// Title Bar
|
||||||
PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f});
|
rect TitleBarBounds = rect{v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}};
|
||||||
DrawString(RenderBuffer, Title, Font, v2{TopLeft.x, TopLeft.y - 25}, WhiteV4);
|
ui_FillRect(Interface, TitleBarBounds, v4{.3f, .3f, .3f, 1.f});
|
||||||
|
ui_DrawString(Interface, Title, TitleBarBounds, Interface->Style.TextColor);
|
||||||
|
|
||||||
MakeStringBuffer(DebugString, 256);
|
MakeStringBuffer(DebugString, 256);
|
||||||
PrintF(&DebugString, "Hot Item: %d | Filtered Items: %d", HotItem, ListLength);
|
PrintF(&DebugString, "Hot Item: %d | Filtered Items: %d", HotItem, ListLength);
|
||||||
DrawString(RenderBuffer, DebugString, Font, v2{TopLeft.x + 256, TopLeft.y - 25}, WhiteV4);
|
rect DebugBounds = MakeRectMinWidth(v2{ TopLeft.x + 256, TopLeft.y - 25}, v2{256, Interface->Style.LineHeight});
|
||||||
TopLeft.y -= 30;
|
ui_DrawString(Interface, DebugString, DebugBounds, Interface->Style.TextColor);
|
||||||
|
|
||||||
// Search Bar
|
// Search Bar
|
||||||
PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f});
|
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;
|
ButtonColor = Config.ButtonColor_Active;
|
||||||
}
|
}
|
||||||
|
|
||||||
button_result Button = EvaluateButton(RenderBuffer, Min, Max, Config.Margin, ListItemString,
|
if (ui_Button(Interface, ListItemString, rect{Min, Max}))
|
||||||
ButtonColor, ButtonColor, Config.TextColor, Config.TextColor,
|
|
||||||
Config.Font, Mouse);
|
|
||||||
if (Button.Pressed)
|
|
||||||
{
|
{
|
||||||
Result.SelectedItem = i;
|
Result.SelectedItem = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
TopLeft.y -= 30;
|
TopLeft.y -= 30;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,15 +30,14 @@ RenderNodeLister(panel Panel, rect PanelBounds, render_command_buffer* RenderBuf
|
||||||
FilterSearchLister(&OpState->SearchLister);
|
FilterSearchLister(&OpState->SearchLister);
|
||||||
|
|
||||||
// Display Search Lister
|
// Display Search Lister
|
||||||
search_lister_result NodeListerResult = EvaluateSearchLister (RenderBuffer, TopLeft, Dimension,
|
search_lister_result NodeListerResult = EvaluateSearchLister (&State->Interface_, TopLeft, Dimension,
|
||||||
MakeStringLiteral("Nodes List"),
|
MakeStringLiteral("Nodes List"),
|
||||||
OpState->SearchLister.SourceList,
|
OpState->SearchLister.SourceList,
|
||||||
OpState->SearchLister.FilteredIndexLUT,
|
OpState->SearchLister.FilteredIndexLUT,
|
||||||
OpState->SearchLister.FilteredListCount,
|
OpState->SearchLister.FilteredListCount,
|
||||||
OpState->SearchLister.HotItem,
|
OpState->SearchLister.HotItem,
|
||||||
&State->ActiveTextEntry.Buffer,
|
&State->ActiveTextEntry.Buffer,
|
||||||
State->ActiveTextEntry.CursorPosition,
|
State->ActiveTextEntry.CursorPosition);
|
||||||
State->Font, State->Interface, Mouse);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(NodeListerNextItem)
|
FOLDHAUS_INPUT_COMMAND_PROC(NodeListerNextItem)
|
||||||
|
|
|
@ -448,43 +448,34 @@ DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range V
|
||||||
}
|
}
|
||||||
|
|
||||||
internal gs_list_handle
|
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);
|
string TempString = MakeString(PushArray(&State->Transient, char, 256), 256);
|
||||||
gs_list_handle Result = SelectedBlockHandle;
|
gs_list_handle Result = SelectedBlockHandle;
|
||||||
|
|
||||||
r32 AnimationPanelHeight = PanelBounds.Max.y - PanelBounds.Min.y;
|
rect LayerMenuBounds, TimelineBounds;
|
||||||
r32 AnimationPanelWidth = PanelBounds.Max.x - PanelBounds.Min.x;
|
VSplitRectAtDistanceFromLeft(PanelBounds, 256, &LayerMenuBounds, &TimelineBounds);
|
||||||
|
|
||||||
rect LayerMenuBounds = {0};
|
// In Top To Bottom Order
|
||||||
LayerMenuBounds.Min = PanelBounds.Min;
|
rect TimelineFrameBarBounds, TimelineBlockDisplayBounds, TimelineRangeBarBounds;
|
||||||
LayerMenuBounds.Max = { PanelBounds.Min.x + 256, PanelBounds.Max.y };
|
HSplitRectAtDistanceFromTop(TimelineBounds, 32, &TimelineFrameBarBounds, &TimelineBounds);
|
||||||
|
HSplitRectAtDistanceFromBottom(TimelineBounds, 24, &TimelineBlockDisplayBounds, &TimelineRangeBarBounds);
|
||||||
|
|
||||||
rect TimeRangeBarBounds = {0};
|
// TODO(Peter): Clean Up
|
||||||
TimeRangeBarBounds.Min = BottomRight(LayerMenuBounds);
|
DrawLayerMenu(AnimationSystem, LayerMenuBounds, Interface->RenderBuffer, State, Interface->Mouse);
|
||||||
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);
|
|
||||||
|
|
||||||
frame_range AdjustedViewRange = {0};
|
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;
|
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
|
ui_FillRect(Interface, TimelineBlockDisplayBounds, v4{.25f, .25f, .25f, 1.0f});
|
||||||
PushRenderQuad2D(RenderBuffer, RectExpand(TimelineBounds), v4{.25f, .25f, .25f, 1.f});
|
|
||||||
|
|
||||||
// Animation Blocks
|
// Animation Blocks
|
||||||
b32 MouseDownAndNotHandled = MouseButtonTransitionedDown(Mouse.LeftButtonState);
|
b32 MouseDownAndNotHandled = MouseButtonTransitionedDown(Interface->Mouse.LeftButtonState);
|
||||||
gs_list_handle DragBlockHandle = {0};
|
gs_list_handle DragBlockHandle = {0};
|
||||||
for (u32 i = 0; i < AnimationSystem->Blocks.Used; i++)
|
for (u32 i = 0; i < AnimationSystem->Blocks.Used; i++)
|
||||||
{
|
{
|
||||||
|
@ -508,8 +499,9 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
|
||||||
{
|
{
|
||||||
BlockColor = PinkV4;
|
BlockColor = PinkV4;
|
||||||
}
|
}
|
||||||
rect BlockBounds = DrawAnimationBlock(AnimationBlockAt, BlockColor, AdjustedViewRange, TimelineBounds, RenderBuffer);
|
// TODO(Peter): Clean Up
|
||||||
if (PointIsInRange(Mouse.Pos, BlockBounds.Min, BlockBounds.Max))
|
rect BlockBounds = DrawAnimationBlock(AnimationBlockAt, BlockColor, AdjustedViewRange, TimelineBounds, Interface->RenderBuffer);
|
||||||
|
if (PointIsInRect(Interface->Mouse.Pos, BlockBounds))
|
||||||
{
|
{
|
||||||
DragBlockHandle = CurrentBlockHandle;
|
DragBlockHandle = CurrentBlockHandle;
|
||||||
}
|
}
|
||||||
|
@ -519,6 +511,7 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
|
||||||
if (MouseDownAndNotHandled && ListHandleIsValid(DragBlockHandle))
|
if (MouseDownAndNotHandled && ListHandleIsValid(DragBlockHandle))
|
||||||
{
|
{
|
||||||
MouseDownAndNotHandled = false;
|
MouseDownAndNotHandled = false;
|
||||||
|
// TODO(Peter): Why are we passing state around?
|
||||||
SelectAndBeginDragAnimationBlock(DragBlockHandle, AdjustedViewRange, TimelineBounds, State);
|
SelectAndBeginDragAnimationBlock(DragBlockHandle, AdjustedViewRange, TimelineBounds, State);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,16 +520,18 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
|
||||||
{
|
{
|
||||||
r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, AdjustedViewRange);
|
r32 FrameAtPercentVisibleRange = FrameToPercentRange(AnimationSystem->CurrentFrame, AdjustedViewRange);
|
||||||
r32 SliderX = GSLerp(TimelineBounds.Min.x, TimelineBounds.Max.x, FrameAtPercentVisibleRange);
|
r32 SliderX = GSLerp(TimelineBounds.Min.x, TimelineBounds.Max.x, FrameAtPercentVisibleRange);
|
||||||
v2 SliderMin = v2{SliderX, TimelineBounds.Min.y};
|
rect SliderBounds = {
|
||||||
v2 SliderMax = v2{SliderX + 1, TimelineBounds.Max.y};
|
v2{ SliderX, TimelineBounds.Min.y },
|
||||||
PushRenderQuad2D(RenderBuffer, SliderMin, SliderMax, TimeSliderColor);
|
v2{ SliderX + 1, TimelineBounds.Max.y }
|
||||||
|
};
|
||||||
|
ui_FillRect(Interface, SliderBounds, TimeSliderColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
PushRenderBoundingBox2D(RenderBuffer, RectExpand(TimeRangeBarBounds), 1.f, RedV4);
|
ui_OutlineRect(Interface, TimelineRangeBarBounds, 1.f, RedV4);
|
||||||
PushRenderBoundingBox2D(RenderBuffer, RectExpand(FrameBarBounds), 1.f, TealV4);
|
ui_OutlineRect(Interface, TimelineFrameBarBounds, 1.f, RedV4);
|
||||||
PushRenderBoundingBox2D(RenderBuffer, RectExpand(TimelineBounds), 1.f, PinkV4);
|
ui_OutlineRect(Interface, TimelineBlockDisplayBounds, 1.f, RedV4);
|
||||||
|
|
||||||
if (MouseDownAndNotHandled && PointIsInRect(Mouse.Pos, TimelineBounds))
|
if (MouseDownAndNotHandled && PointIsInRect(Interface->Mouse.Pos, TimelineBounds))
|
||||||
{
|
{
|
||||||
DeselectCurrentAnimationBlock(State);
|
DeselectCurrentAnimationBlock(State);
|
||||||
}
|
}
|
||||||
|
@ -559,42 +554,19 @@ animation_clip GlobalAnimationClips[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
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[] = {
|
ui_layout Layout = ui_CreateLayout(*Interface, PanelBounds);
|
||||||
{ .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);
|
|
||||||
|
|
||||||
for (s32 i = 0; i < GlobalAnimationClipsCount; i++)
|
for (s32 i = 0; i < GlobalAnimationClipsCount; i++)
|
||||||
{
|
{
|
||||||
animation_clip Clip = GlobalAnimationClips[i];
|
animation_clip Clip = GlobalAnimationClips[i];
|
||||||
string ClipName = MakeString(Clip.Name, Clip.NameLength);
|
string ClipName = MakeString(Clip.Name, Clip.NameLength);
|
||||||
rect ElementBounds = DrawListElement(ClipName, &List, Mouse, RenderBuffer, State->Interface);
|
if (ui_LayoutListEntry(Interface, &Layout, ClipName, i))
|
||||||
|
|
||||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
|
|
||||||
&& PointIsInRect(Mouse.DownPos, ElementBounds))
|
|
||||||
{
|
{
|
||||||
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);
|
GSMetaTag(panel_render);
|
||||||
|
@ -603,68 +575,41 @@ internal void
|
||||||
AnimationTimeline_Render(panel Panel, rect PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context, mouse_state Mouse)
|
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;
|
animation_timeline_state* TimelineState = (animation_timeline_state*)Panel.PanelStateMemory;
|
||||||
|
|
||||||
gs_list_handle SelectedBlockHandle = State->SelectedAnimationBlockHandle;
|
gs_list_handle SelectedBlockHandle = State->SelectedAnimationBlockHandle;
|
||||||
|
|
||||||
r32 OptionsRowHeight = 25;
|
ui_interface* Interface = &State->Interface_;
|
||||||
rect AnimationClipListBounds = rect{
|
animation_system* AnimationSystem = &State->AnimationSystem;
|
||||||
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},
|
|
||||||
};
|
|
||||||
|
|
||||||
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,
|
if (ui_LayoutButton(Interface, MakeStringLiteral("Pause"), &TitleBarLayout))
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
State->AnimationSystem.TimelineShouldAdvance = true;
|
State->AnimationSystem.TimelineShouldAdvance = true;
|
||||||
}
|
}
|
||||||
|
if (ui_LayoutButton(Interface, MakeStringLiteral("Play"), &TitleBarLayout))
|
||||||
if (StopResult.Pressed)
|
{
|
||||||
|
State->AnimationSystem.TimelineShouldAdvance = false;
|
||||||
|
}
|
||||||
|
if (ui_LayoutButton(Interface, MakeStringLiteral("Stop"), &TitleBarLayout))
|
||||||
{
|
{
|
||||||
State->AnimationSystem.TimelineShouldAdvance = false;
|
State->AnimationSystem.TimelineShouldAdvance = false;
|
||||||
State->AnimationSystem.CurrentFrame = 0;
|
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
|
#define FOLDHAUS_PANEL_ANIMATION_TIMELINE_H
|
||||||
|
|
|
@ -37,6 +37,7 @@ HierarchyView_Render(panel Panel, rect PanelBounds, render_command_buffer* Rende
|
||||||
{ .18f, .18f, .18f, 1.f },
|
{ .18f, .18f, .18f, 1.f },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO(Peter): use the new ui system
|
||||||
interface_list List = {};
|
interface_list List = {};
|
||||||
List.LineBGColors = LineBGColors;
|
List.LineBGColors = LineBGColors;
|
||||||
List.LineBGColorsCount = sizeof(LineBGColors) / sizeof(LineBGColors[0]);
|
List.LineBGColorsCount = sizeof(LineBGColors) / sizeof(LineBGColors[0]);
|
||||||
|
|
|
@ -178,41 +178,39 @@ ProfilerView_Render(panel Panel, rect PanelBounds, render_command_buffer* Render
|
||||||
FrameTotalCycles);
|
FrameTotalCycles);
|
||||||
DrawString(RenderBuffer, String, State->Interface.Font, FrameListMin - v2{0, 32}, WhiteV4);
|
DrawString(RenderBuffer, String, State->Interface.Font, FrameListMin - v2{0, 32}, WhiteV4);
|
||||||
|
|
||||||
v2 ButtonMin = v2{FrameListMax.x - 128, FrameListMin.y - 32};
|
rect ResumeRecordingBtnBounds = MakeRectMinWidth(v2{ FrameListMax.x - 128, FrameListMin.y - 32 }, v2{ 128, 28 });
|
||||||
v2 ButtonMax = ButtonMin + v2{128, 28};
|
if (ui_Button(&State->Interface_, MakeString("Resume Recording"), ResumeRecordingBtnBounds))
|
||||||
button_result ShouldResumeRecording = EvaluateButton(RenderBuffer, ButtonMin, ButtonMax,
|
|
||||||
MakeString("Resume Recording"), State->Interface, Mouse);
|
|
||||||
if (ShouldResumeRecording.Pressed)
|
|
||||||
{
|
{
|
||||||
GlobalDebugServices->RecordFrames = true;
|
GlobalDebugServices->RecordFrames = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ButtonMin = v2{FrameListMin.x, FrameListMin.y - 60};
|
rect ScopeViewBtnBounds = {
|
||||||
ButtonMax = v2{FrameListMin.x + 128, FrameListMin.y - 42};
|
v2{ FrameListMin.x, FrameListMin.y - 60 },
|
||||||
button_result ActivateScopeView = EvaluateButton(RenderBuffer, ButtonMin, ButtonMax,
|
v2{ FrameListMin.x + 128, FrameListMin.y - 42 }
|
||||||
MakeString("Scope View"), State->Interface, Mouse);
|
};
|
||||||
|
if (ui_Button(&State->Interface_, MakeString("Scope View"), ScopeViewBtnBounds))
|
||||||
|
{
|
||||||
|
GlobalDebugServices->Interface.FrameView = FRAME_VIEW_PROFILER;
|
||||||
|
}
|
||||||
|
|
||||||
ButtonMin.x += 152;
|
rect ListViewBtnBounds = TranslateRectX(ScopeViewBtnBounds, 152);
|
||||||
ButtonMax.x += 152;
|
if (ui_Button(&State->Interface_, MakeString("List View"), ListViewBtnBounds))
|
||||||
button_result ActivateListView = EvaluateButton(RenderBuffer, ButtonMin, ButtonMax,
|
{
|
||||||
MakeString("List View"), State->Interface, Mouse);
|
GlobalDebugServices->Interface.FrameView = FRAME_VIEW_SCOPE_LIST;
|
||||||
|
}
|
||||||
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 ViewModeBounds = {
|
||||||
|
v2{ FrameListMin.x, PanelBounds.Min.y },
|
||||||
|
v2{ FrameListMax.x, FrameListMin.y - 96 }
|
||||||
|
};
|
||||||
if (GlobalDebugServices->Interface.FrameView == FRAME_VIEW_PROFILER)
|
if (GlobalDebugServices->Interface.FrameView == FRAME_VIEW_PROFILER)
|
||||||
{
|
{
|
||||||
RenderProfiler_ScopeVisualization(RenderBuffer, State->Interface, Mouse,
|
RenderProfiler_ScopeVisualization(RenderBuffer, State->Interface, Mouse, RectExpand(ViewModeBounds),
|
||||||
ViewModeMin, ViewModeMax,
|
|
||||||
VisibleFrame, Memory);
|
VisibleFrame, Memory);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RenderProfiler_ListVisualization(RenderBuffer, State->Interface, Mouse,
|
RenderProfiler_ListVisualization(RenderBuffer, State->Interface, Mouse, RectExpand(ViewModeBounds),
|
||||||
ViewModeMin, ViewModeMax,
|
|
||||||
VisibleFrame, Memory);
|
VisibleFrame, Memory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
7
todo.txt
7
todo.txt
|
@ -4,7 +4,7 @@ TODO FOLDHAUS
|
||||||
- fix memory layout (remeber to profile before and after)
|
- fix memory layout (remeber to profile before and after)
|
||||||
|
|
||||||
- Make the DLL truly platform agnostic
|
- 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
|
- windows.h: only thing left is InterlockedIncrement and InterlockedAdd
|
||||||
|
|
||||||
- Win32 Platform Layer
|
- Win32 Platform Layer
|
||||||
|
@ -20,10 +20,9 @@ TODO FOLDHAUS
|
||||||
- Make sure it works without building in Debug Mode
|
- Make sure it works without building in Debug Mode
|
||||||
|
|
||||||
- Buckets & Lists
|
- Buckets & Lists
|
||||||
- Allow them to use memory arenas
|
- On second thought, I just really don't like these. Lets get rid of them, and put custom structures in place
|
||||||
- Zero is initialization
|
|
||||||
|
|
||||||
- Rendering
|
- Rendering (Working on this elsewhere)
|
||||||
- OpenGL 3
|
- OpenGL 3
|
||||||
- Vertex Buffers
|
- Vertex Buffers
|
||||||
- Layers
|
- Layers
|
||||||
|
|
Loading…
Reference in New Issue