implemented switching to a file browser, used it in the animation window and in the assembly hierarchy, and moved everything over to a linear array of animation blocks

This commit is contained in:
PS 2020-10-18 15:31:53 -07:00
parent 8eb3044422
commit 5c183d9c5f
9 changed files with 222 additions and 218 deletions

View File

@ -19,26 +19,6 @@ enum panel_edit_mode
PanelEdit_Count, PanelEdit_Count,
}; };
internal void
SetPanelType_(panel* Panel, s32 NewPanelTypeIndex, app_state* State, context Context)
{
s32 OldPanelDefinitionIndex = Panel_GetCurrentTypeIndex(Panel);
Panel_SetCurrentTypeIndex(Panel, NewPanelTypeIndex, {0});
if(OldPanelDefinitionIndex >= 0)
{
GlobalPanelDefs[OldPanelDefinitionIndex].Cleanup(Panel, State);
}
}
internal void
SetAndInitPanelType(panel* Panel, s32 NewPanelTypeIndex, app_state* State, context Context)
{
SetPanelType_(Panel, NewPanelTypeIndex, State, Context);
GlobalPanelDefs[NewPanelTypeIndex].Init(Panel, State, Context);
}
// //
// Drag Panel Border Operation Mode // Drag Panel Border Operation Mode
@ -249,19 +229,19 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndSplitPanelOperation)
if (XDistance > YDistance) if (XDistance > YDistance)
{ {
r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / Rect2Width(PanelBounds); r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / Rect2Width(PanelBounds);
SplitPanelVertically(Panel, XPercent, &State->PanelSystem); SplitPanelVertically(Panel, XPercent, &State->PanelSystem, State, Context);
} }
else else
{ {
r32 YPercent = (Mouse.Pos.y - PanelBounds.Min.y) / Rect2Height(PanelBounds); r32 YPercent = (Mouse.Pos.y - PanelBounds.Min.y) / Rect2Height(PanelBounds);
SplitPanelHorizontally(Panel, YPercent, &State->PanelSystem); SplitPanelHorizontally(Panel, YPercent, &State->PanelSystem, State, Context);
} }
s32 PanelTypeIndex = Panel_GetCurrentTypeIndex(Panel); s32 PanelTypeIndex = Panel->TypeIndex;
gs_data PanelStateMemory = Panel_GetCurrentTypeStateMemory_(Panel); gs_data PanelStateMemory = Panel->StateMemory;
Panel_SetCurrentTypeIndex(&Panel->Left->Panel, PanelTypeIndex, PanelStateMemory); Panel_SetCurrentType(&Panel->Left->Panel, &State->PanelSystem, PanelTypeIndex, PanelStateMemory, State, Context);
SetAndInitPanelType(&Panel->Right->Panel, PanelTypeIndex, State, Context); SetAndInitPanelType(&Panel->Right->Panel, &State->PanelSystem, PanelTypeIndex, State, Context);
DeactivateCurrentOperationMode(&State->Modes); DeactivateCurrentOperationMode(&State->Modes);
} }
@ -438,7 +418,7 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect2 FooterB
gs_string DefName = MakeString(Def.PanelName, Def.PanelNameLength); gs_string DefName = MakeString(Def.PanelName, Def.PanelNameLength);
if (ui_Button(&State->Interface, DefName, ButtonBounds)) if (ui_Button(&State->Interface, DefName, ButtonBounds))
{ {
SetAndInitPanelType(Panel, i, State, Context); SetAndInitPanelType(Panel, &State->PanelSystem, i, State, Context);
Panel->PanelSelectionMenuOpen = false; Panel->PanelSelectionMenuOpen = false;
} }
@ -456,7 +436,7 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect2 FooterB
internal void internal void
RenderPanel(panel* Panel, rect2 PanelBounds, rect2 WindowBounds, render_command_buffer* RenderBuffer, app_state* State, context Context, mouse_state Mouse) RenderPanel(panel* Panel, rect2 PanelBounds, rect2 WindowBounds, render_command_buffer* RenderBuffer, app_state* State, context Context, mouse_state Mouse)
{ {
s32 PanelType = Panel_GetCurrentTypeIndex(Panel); s32 PanelType = Panel->TypeIndex;
Assert(PanelType >= 0); Assert(PanelType >= 0);
rect2 FooterBounds = rect2{ rect2 FooterBounds = rect2{

View File

@ -19,18 +19,19 @@ enum panel_split_direction
}; };
typedef struct panel_entry panel_entry; typedef struct panel_entry panel_entry;
typedef struct panel panel;
#define PANEL_MODAL_OVERRIDE_CALLBACK(name) void name(panel* ReturningFrom, app_state* State, context Context)
typedef PANEL_MODAL_OVERRIDE_CALLBACK(panel_modal_override_callback);
struct panel struct panel
{ {
s32 TypeIndex;
gs_data StateMemory;
// TODO(pjs): We want this to be a list, so that you can push sub panels on panel_entry* ModalOverride;
// and let them return to you, to perform certain tasks, like loading a file panel* IsModalOverrideFor; // TODO(pjs): I don't like that this is panel* but ModalOverride is panel_entry*
//s32 PanelDefinitionIndex; panel_modal_override_callback* ModalOverrideCB;
#define PANEL_TYPE_INDICES_COUNT_MAX 4
s32 TypeIndicesCount;
s32 TypeIndices[PANEL_TYPE_INDICES_COUNT_MAX];
gs_data ReturnDestMemory[PANEL_TYPE_INDICES_COUNT_MAX];
gs_data TypeStateMemory[PANEL_TYPE_INDICES_COUNT_MAX];
panel_split_direction SplitDirection; panel_split_direction SplitDirection;
r32 SplitPercent; r32 SplitPercent;
@ -60,9 +61,33 @@ struct panel_entry
free_panel Free; free_panel Free;
}; };
#define PANEL_INIT_PROC(name) void name(panel* Panel, app_state* State, context Context)
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);
#define PANEL_RENDER_PROC(name) void name(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
typedef PANEL_RENDER_PROC(panel_render_proc);
// NOTE(Peter): This is used by the meta system to generate panel type info
struct panel_definition
{
char* PanelName;
s32 PanelNameLength;
panel_init_proc* Init;
panel_cleanup_proc* Cleanup;
panel_render_proc* Render;
input_command* InputCommands;
s32 InputCommandsCount;
};
#define PANELS_MAX 16 #define PANELS_MAX 16
struct panel_system struct panel_system
{ {
panel_definition* PanelDefs;
u32 PanelDefsCount;
panel_entry Panels[PANELS_MAX]; panel_entry Panels[PANELS_MAX];
u32 PanelsUsed; u32 PanelsUsed;
@ -92,9 +117,11 @@ struct panel_layout
///////////////////////////////// /////////////////////////////////
internal void internal void
InitializePanelSystem(panel_system* PanelSystem) InitializePanelSystem(panel_system* PanelSystem, panel_definition* PanelDefs, u32 PanelDefsCount)
{ {
PanelSystem->FreeList.Free.Next = &PanelSystem->FreeList; PanelSystem->FreeList.Free.Next = &PanelSystem->FreeList;
PanelSystem->PanelDefs = PanelDefs;
PanelSystem->PanelDefsCount = PanelDefsCount;
} }
internal panel_entry* internal panel_entry*
@ -114,16 +141,6 @@ TakeNewPanelEntry(panel_system* PanelSystem)
return FreeEntry; return FreeEntry;
} }
internal panel*
TakeNewPanel(panel_system* PanelSystem)
{
panel* Result = 0;
panel_entry* FreeEntry = TakeNewPanelEntry(PanelSystem);
Result = &FreeEntry->Panel;
*Result = {0};
return Result;
}
internal void internal void
FreePanelEntry(panel_entry* Entry, panel_system* PanelSystem) FreePanelEntry(panel_entry* Entry, panel_system* PanelSystem)
{ {
@ -153,98 +170,111 @@ FreePanelAtIndex(s32 Index, panel_system* PanelSystem)
PanelSystem->FreeList.Free.Next = EntryToFree; PanelSystem->FreeList.Free.Next = EntryToFree;
} }
internal void internal panel_entry*
Panel_SetCurrentTypeIndex(panel* Panel, s32 NewPanelType, gs_data TypeStateMemory, gs_data ReturnDestMemory = {0}) Panel_GetModalOverride(panel_entry* PanelEntry)
{ {
u32 CurrentTypeIndex = 0; panel_entry* Result = PanelEntry;
if (Panel->TypeIndicesCount != 0) if (PanelEntry->Panel.ModalOverride != 0)
{ {
CurrentTypeIndex = Panel->TypeIndicesCount - 1; Result = Panel_GetModalOverride(PanelEntry->Panel.ModalOverride);
} }
else return Result;
}
internal panel*
Panel_GetModalOverride(panel* Panel)
{
panel* Result = Panel;
if (Panel->ModalOverride != 0)
{ {
CurrentTypeIndex = Panel->TypeIndicesCount++; Result = &Panel_GetModalOverride(Panel->ModalOverride)->Panel;
} }
return Result;
}
internal void
Panel_PushModalOverride(panel* Root, panel_entry* Override, panel_modal_override_callback* Callback)
{
Root->ModalOverride = Override;
Root->ModalOverrideCB = Callback;
Override->Panel.IsModalOverrideFor = Root;
}
internal void
Panel_PopModalOverride(panel* Parent, panel_system* System)
{
// TODO(pjs): Free the overrided panel
FreePanelEntry(Parent->ModalOverride, System);
Parent->ModalOverride = 0;
}
internal void
Panel_SetCurrentType(panel* Panel, panel_system* System, s32 NewPanelType, gs_data TypeStateMemory, app_state* State, context Context)
{
s32 OldTypeIndex = Panel->TypeIndex;
Panel->TypeIndices[CurrentTypeIndex] = NewPanelType; Panel->TypeIndex = NewPanelType;
Panel->TypeStateMemory[CurrentTypeIndex] = TypeStateMemory; Panel->StateMemory = TypeStateMemory;
Panel->ReturnDestMemory[CurrentTypeIndex] = ReturnDestMemory;
} if(OldTypeIndex >= 0)
internal s32
Panel_GetCurrentTypeIndex(panel* Panel)
{
s32 Result = -1;
if (Panel->TypeIndicesCount != 0)
{ {
Result = Panel->TypeIndices[Panel->TypeIndicesCount - 1]; System->PanelDefs[OldTypeIndex].Cleanup(Panel, State);
} }
return Result;
} }
#define Panel_GetCurrentTypeStateMemory(p, type) (type*)Panel_GetCurrentTypeStateMemory_(p).Memory internal void
SetAndInitPanelType(panel* Panel, panel_system* System, s32 NewPanelTypeIndex, app_state* State, context Context)
{
gs_data EmptyStateData = {0};
Panel_SetCurrentType(Panel, System, NewPanelTypeIndex, EmptyStateData, State, Context);
System->PanelDefs[NewPanelTypeIndex].Init(Panel, State, Context);
}
#define Panel_GetStateStruct(p, type) (type*)Panel_GetStateMemory((p), sizeof(type)).Memory
internal gs_data internal gs_data
Panel_GetCurrentTypeStateMemory_(panel* Panel) Panel_GetStateMemory(panel* Panel, u64 Size)
{ {
gs_data Result = {0}; Assert(Panel->StateMemory.Size == Size);
if (Panel->TypeIndicesCount != 0) gs_data Result = Panel->StateMemory;
{
Result = Panel->TypeStateMemory[Panel->TypeIndicesCount - 1];
}
return Result; return Result;
} }
internal void internal panel_entry*
Panel_SetCurrentTypeStateMemory(panel* Panel, gs_data StateMemory) PanelSystem_PushPanel(panel_system* PanelSystem, s32 PanelTypeIndex, app_state* State, context Context)
{ {
u32 CurrentTypeIndex = 0; panel_entry* PanelEntry = TakeNewPanelEntry(PanelSystem);
if (Panel->TypeIndicesCount != 0) SetAndInitPanelType(&PanelEntry->Panel, PanelSystem, PanelTypeIndex, State, Context);
{ return PanelEntry;
CurrentTypeIndex = Panel->TypeIndicesCount - 1;
}
else
{
CurrentTypeIndex = Panel->TypeIndicesCount++;
}
Panel->TypeStateMemory[CurrentTypeIndex] = StateMemory;
} }
internal void internal void
Panel_PushTypeWithReturn(panel* Panel, s32 NewPanelType, gs_data ReturnDestMemory) SplitPanel(panel* Parent, r32 Percent, panel_split_direction SplitDirection, panel_system* PanelSystem, app_state* State, context Context)
{
Assert(Panel->TypeIndicesCount < PANEL_TYPE_INDICES_COUNT_MAX);
u32 NewTypeIndex = Panel->TypeIndicesCount++;
Panel_SetCurrentTypeIndex(Panel, NewPanelType, ReturnDestMemory);
}
internal void
SplitPanel(panel* Parent, r32 Percent, panel_split_direction SplitDirection, panel_system* PanelSystem)
{ {
if (Percent >= 0.0f && Percent <= 1.0f) if (Percent >= 0.0f && Percent <= 1.0f)
{ {
Parent->SplitDirection = SplitDirection; Parent->SplitDirection = SplitDirection;
Parent->SplitPercent = Percent; Parent->SplitPercent = Percent;
s32 ParentTypeIndex = Panel_GetCurrentTypeIndex(Parent); s32 ParentTypeIndex = Parent->TypeIndex;
gs_data ParentStateMemory = Panel_GetCurrentTypeStateMemory_(Parent); gs_data ParentStateMemory = Parent->StateMemory;
Parent->Left = TakeNewPanelEntry(PanelSystem); Parent->Left = TakeNewPanelEntry(PanelSystem);
Panel_SetCurrentTypeIndex(&Parent->Left->Panel, ParentTypeIndex, ParentStateMemory); Panel_SetCurrentType(&Parent->Left->Panel, PanelSystem, ParentTypeIndex, ParentStateMemory, State, Context);
Parent->Right = TakeNewPanelEntry(PanelSystem); Parent->Right = TakeNewPanelEntry(PanelSystem);
Panel_SetCurrentTypeIndex(&Parent->Right->Panel, ParentTypeIndex, ParentStateMemory); Panel_SetCurrentType(&Parent->Right->Panel, PanelSystem, ParentTypeIndex, ParentStateMemory, State, Context);
} }
} }
internal void internal void
SplitPanelVertically(panel* Parent, r32 Percent, panel_system* PanelSystem) SplitPanelVertically(panel* Parent, r32 Percent, panel_system* PanelSystem, app_state* State, context Context)
{ {
SplitPanel(Parent, Percent, PanelSplit_Vertical, PanelSystem); SplitPanel(Parent, Percent, PanelSplit_Vertical, PanelSystem, State, Context);
} }
internal void internal void
SplitPanelHorizontally(panel* Parent, r32 Percent, panel_system* PanelSystem) SplitPanelHorizontally(panel* Parent, r32 Percent, panel_system* PanelSystem, app_state* State, context Context)
{ {
SplitPanel(Parent, Percent, PanelSplit_Horizontal, PanelSystem); SplitPanel(Parent, Percent, PanelSplit_Horizontal, PanelSystem, State, Context);
} }
internal void internal void
@ -321,13 +351,17 @@ LayoutPanel(panel* Panel, rect2 PanelBounds, panel_layout* Layout)
if (Panel->SplitDirection == PanelSplit_NoSplit) if (Panel->SplitDirection == PanelSplit_NoSplit)
{ {
panel_with_layout* WithLayout = Layout->Panels + Layout->PanelsCount++; panel_with_layout* WithLayout = Layout->Panels + Layout->PanelsCount++;
WithLayout->Panel = Panel; WithLayout->Panel = Panel_GetModalOverride(Panel);
WithLayout->Bounds = PanelBounds; WithLayout->Bounds = PanelBounds;
} }
else if (Panel->SplitDirection == PanelSplit_Horizontal) else if (Panel->SplitDirection == PanelSplit_Horizontal)
{ {
rect2 TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds); rect2 TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
rect2 BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds); rect2 BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
panel* TopPanel = Panel_GetModalOverride(&Panel->Top->Panel);
panel* BottomPanel = Panel_GetModalOverride(&Panel->Bottom->Panel);
LayoutPanel(&Panel->Top->Panel, TopPanelBounds, Layout); LayoutPanel(&Panel->Top->Panel, TopPanelBounds, Layout);
LayoutPanel(&Panel->Bottom->Panel, BottomPanelBounds, Layout); LayoutPanel(&Panel->Bottom->Panel, BottomPanelBounds, Layout);
} }
@ -335,6 +369,10 @@ LayoutPanel(panel* Panel, rect2 PanelBounds, panel_layout* Layout)
{ {
rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds); rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds); rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
panel* LeftPanel = Panel_GetModalOverride(&Panel->Top->Panel);
panel* RightPanel = Panel_GetModalOverride(&Panel->Bottom->Panel);
LayoutPanel(&Panel->Left->Panel, LeftPanelBounds, Layout); LayoutPanel(&Panel->Left->Panel, LeftPanelBounds, Layout);
LayoutPanel(&Panel->Right->Panel, RightPanelBounds, Layout); LayoutPanel(&Panel->Right->Panel, RightPanelBounds, Layout);
} }

View File

@ -170,11 +170,9 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
s32 NewStartFrame = OpState->ClipRange.Min + FrameOffset; s32 NewStartFrame = OpState->ClipRange.Min + FrameOffset;
if (FrameOffset < 0) if (FrameOffset < 0)
{ {
for (u32 i = 0; i < ActiveAnim->Blocks.Used; i++) for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++)
{ {
gs_list_entry<animation_block>* OtherBlockEntry = ActiveAnim->Blocks.GetEntryAtIndex(i); animation_block OtherBlock = ActiveAnim->Blocks_.Values[i];
if (EntryIsFree(OtherBlockEntry)) { continue; }
animation_block OtherBlock = OtherBlockEntry->Value;
NewStartFrame = AttemptToSnapPosition(NewStartFrame, OtherBlock.Range.Max); NewStartFrame = AttemptToSnapPosition(NewStartFrame, OtherBlock.Range.Max);
} }
} }
@ -192,11 +190,9 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
r32 NewEndFrame = OpState->ClipRange.Max + FrameOffset; r32 NewEndFrame = OpState->ClipRange.Max + FrameOffset;
if (FrameOffset > 0) if (FrameOffset > 0)
{ {
for (u32 i = 0; i < ActiveAnim->Blocks.Used; i++) for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++)
{ {
gs_list_entry<animation_block>* OtherBlockEntry = ActiveAnim->Blocks.GetEntryAtIndex(i); animation_block OtherBlock = ActiveAnim->Blocks_.Values[i];
if (EntryIsFree(OtherBlockEntry)) { continue; }
animation_block OtherBlock = OtherBlockEntry->Value;
NewEndFrame = AttemptToSnapPosition(NewEndFrame, OtherBlock.Range.Min); NewEndFrame = AttemptToSnapPosition(NewEndFrame, OtherBlock.Range.Min);
} }
} }
@ -213,11 +209,9 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
{ {
u32 NewStartFrame = OpState->ClipRange.Min + FrameOffset; u32 NewStartFrame = OpState->ClipRange.Min + FrameOffset;
u32 NewEndFrame = OpState->ClipRange.Max + FrameOffset; u32 NewEndFrame = OpState->ClipRange.Max + FrameOffset;
for (u32 i = 0; i < ActiveAnim->Blocks.Used; i++) for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++)
{ {
gs_list_entry<animation_block>* OtherBlockEntry = ActiveAnim->Blocks.GetEntryAtIndex(i); animation_block OtherBlock = ActiveAnim->Blocks_.Values[i];;
if (EntryIsFree(OtherBlockEntry)) { continue; }
animation_block OtherBlock = OtherBlockEntry->Value;
u32 SnapFramesAmount = 0; u32 SnapFramesAmount = 0;
if (FrameOffset > 0) if (FrameOffset > 0)
@ -294,7 +288,7 @@ AnimationTimeline_Init(panel* Panel, app_state* State, context Context)
animation_timeline_state* TimelineState = PushStruct(&State->Permanent, animation_timeline_state); animation_timeline_state* TimelineState = PushStruct(&State->Permanent, animation_timeline_state);
TimelineState->VisibleRange = ActiveAnim->PlayableRange; TimelineState->VisibleRange = ActiveAnim->PlayableRange;
Panel_SetCurrentTypeStateMemory(Panel, StructToData(TimelineState, animation_timeline_state)); Panel->StateMemory = StructToData(TimelineState, animation_timeline_state);
} }
GSMetaTag(panel_cleanup); GSMetaTag(panel_cleanup);
@ -580,6 +574,13 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
return Result; return Result;
} }
PANEL_MODAL_OVERRIDE_CALLBACK(LoadAnimationFileCallback)
{
Assert(ReturningFrom->TypeIndex == PanelType_FileView);
file_view_state* FileViewState = Panel_GetStateStruct(ReturningFrom, file_view_state);
gs_file_info FileInfo = FileViewState->SelectedFile;
}
internal void internal void
DrawAnimationClipsList(rect2 PanelBounds, ui_interface* Interface, u32 SelectedAnimationLayerHandle, animation_system* AnimationSystem) DrawAnimationClipsList(rect2 PanelBounds, ui_interface* Interface, u32 SelectedAnimationLayerHandle, animation_system* AnimationSystem)
{ {
@ -600,7 +601,7 @@ GSMetaTag(panel_type_animation_timeline);
internal void internal void
AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
{ {
animation_timeline_state* TimelineState = Panel_GetCurrentTypeStateMemory(Panel, animation_timeline_state); animation_timeline_state* TimelineState = Panel_GetStateStruct(Panel, animation_timeline_state);
// TODO(pjs): SelectedAnimationBlockHandle should be a property of animation_timeline_state // TODO(pjs): SelectedAnimationBlockHandle should be a property of animation_timeline_state
// unless its used elsewhere. Audit later // unless its used elsewhere. Audit later
handle SelectedBlockHandle = State->SelectedAnimationBlockHandle; handle SelectedBlockHandle = State->SelectedAnimationBlockHandle;
@ -634,11 +635,8 @@ AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer*
if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Load"))) if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Load")))
{ {
// TODO(pjs): You were working on #6 on your todo list. panel_entry* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context);
// below is a "write the interface first" example of how you'd like to be able to Panel_PushModalOverride(Panel, FileBrowser, LoadAnimationFileCallback);
// activate a file panel from within another panel.
gs_data ReturnDestination = {};
Panel_PushTypeWithReturn(Panel, PanelType_FileView, ReturnDestination);
// TODO(pjs): I think we want to be able to specify a return command that gets called when the // TODO(pjs): I think we want to be able to specify a return command that gets called when the
// pushed panel state returns to this one // pushed panel state returns to this one
// something like: AnimPanel_HandleLoadedAnimationFile // something like: AnimPanel_HandleLoadedAnimationFile

View File

@ -10,6 +10,8 @@ struct file_view_state
gs_string WorkingDirectory; gs_string WorkingDirectory;
gs_memory_arena FileNamesArena; gs_memory_arena FileNamesArena;
gs_file_info_array FileNames; gs_file_info_array FileNames;
gs_file_info SelectedFile;
}; };
input_command* FileView_Commands = 0; input_command* FileView_Commands = 0;
@ -55,7 +57,7 @@ FileView_Init(panel* Panel, app_state* State, context Context)
{ {
// TODO: :FreePanelMemory // TODO: :FreePanelMemory
file_view_state* FileViewState = PushStruct(&State->Permanent, file_view_state); file_view_state* FileViewState = PushStruct(&State->Permanent, file_view_state);
Panel_SetCurrentTypeStateMemory(Panel, StructToData(FileViewState, file_view_state)); Panel->StateMemory = StructToData(FileViewState, file_view_state);
FileViewState->FileNamesArena = CreateMemoryArena(Context.ThreadContext.Allocator); FileViewState->FileNamesArena = CreateMemoryArena(Context.ThreadContext.Allocator);
FileViewUpdateWorkingDirectory(ConstString("."), FileViewState, Context); FileViewUpdateWorkingDirectory(ConstString("."), FileViewState, Context);
} }
@ -73,7 +75,7 @@ GSMetaTag(panel_type_file_view);
internal void internal void
FileView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) FileView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
{ {
file_view_state* FileViewState = Panel_GetCurrentTypeStateMemory(Panel, file_view_state); file_view_state* FileViewState = Panel_GetStateStruct(Panel, file_view_state);
ui_layout Layout = ui_CreateLayout(State->Interface, PanelBounds); ui_layout Layout = ui_CreateLayout(State->Interface, PanelBounds);
// Header // Header
@ -96,7 +98,15 @@ FileView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBu
} }
else else
{ {
// TODO(pjs): Select the file FileViewState->SelectedFile = File;
Assert(Panel->IsModalOverrideFor != 0);
panel* ReturnTo = Panel->IsModalOverrideFor;
if (ReturnTo->ModalOverrideCB)
{
ReturnTo->ModalOverrideCB(Panel, State, Context);
}
Panel_PopModalOverride(ReturnTo, &State->PanelSystem);
} }
} }
} }

View File

@ -24,6 +24,15 @@ HierarchyView_Cleanup(panel* Panel, app_state* State)
} }
PANEL_MODAL_OVERRIDE_CALLBACK(LoadAssemblyCallback)
{
Assert(ReturningFrom->TypeIndex == PanelType_FileView);
file_view_state* FileViewState = Panel_GetStateStruct(ReturningFrom, file_view_state);
gs_file_info FileInfo = FileViewState->SelectedFile;
LoadAssembly(&State->Assemblies, &State->LedSystem, State->Transient, Context, FileInfo.Path, State->GlobalLog);
}
GSMetaTag(panel_render); GSMetaTag(panel_render);
GSMetaTag(panel_type_hierarchy); GSMetaTag(panel_type_hierarchy);
internal void internal void
@ -66,19 +75,8 @@ HierarchyView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Ren
PrintF(&TempString, "+ Add Assembly"); PrintF(&TempString, "+ Add Assembly");
if (ui_ListButton(&State->Interface, TempString, LineBounds[AssembliesToDraw], AssembliesToDraw)) if (ui_ListButton(&State->Interface, TempString, LineBounds[AssembliesToDraw], AssembliesToDraw))
{ {
gs_string FilePath = PushString(State->Transient, 256); panel_entry* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context);
Panel_PushModalOverride(Panel, FileBrowser, LoadAssemblyCallback);
// TODO(Peter): Took out file opening temporarily while I get things back up and running.
// Ideally we can just write our own file lister using the new filehandler so that
// execution doesn't suspend while we try and open a file
InvalidCodePath;
#if 0
b32 Success = GetFilePath(Context, &FilePath, "Foldhaus Files\0*.fold\0\0");
if (Success)
{
LoadAssembly(&State->Assemblies, &State->LedSystem, &State->Transient, Context, FilePath.ConstString, State->GlobalLog);
}
#endif
} }
} }
} }

View File

@ -62,7 +62,6 @@ struct animation
gs_string Name; gs_string Name;
anim_layer_array Layers; anim_layer_array Layers;
gs_list<animation_block> Blocks;
animation_block_array Blocks_; animation_block_array Blocks_;
frame_range PlayableRange; frame_range PlayableRange;
@ -199,6 +198,17 @@ AnimBlockArray_Remove(animation_block_array* Array, handle Handle)
Array->Generations[Handle.Index]++; Array->Generations[Handle.Index]++;
} }
internal void
AnimBlockArray_RemoveAt(animation_block_array* Array, u32 Index)
{
Assert(Index < Array->Count);
handle Handle = {};
Handle.Index = Index;
Handle.Generation = Array->Generations[Index];
AnimBlockArray_Remove(Array, Handle);
}
////////////////////////// //////////////////////////
// //
// Anim Layers Array // Anim Layers Array
@ -257,43 +267,6 @@ AnimationArray_Push(animation_array* Array, animation Value)
// //
// Animation // Animation
internal u32
Animation_AddLayer(animation* Animation, anim_layer Layer)
{
return AnimLayerArray_Push(&Animation->Layers, Layer);
}
internal u32
Animation_AddLayer (animation* Animation, gs_string Name, blend_mode BlendMode, animation_system* System)
{
anim_layer NewLayer = {0};
NewLayer.Name = PushStringF(System->Storage, 256, "%S", Name);
NewLayer.BlendMode = BlendMode;
return Animation_AddLayer(Animation, NewLayer);
}
internal void
Animation_RemoveLayer (animation* Animation, u32 LayerIndex)
{
AnimLayerArray_Remove(&Animation->Layers, LayerIndex);
for (u32 i = Animation->Blocks.Used -= 1; i >= 0; i--)
{
gs_list_entry<animation_block>* Entry = Animation->Blocks.GetEntryAtIndex(i);
if (EntryIsFree(Entry)) { continue; }
animation_block* Block = &Entry->Value;
if (Block->Layer > LayerIndex)
{
Block->Layer -= 1;
}
else if (Block->Layer == LayerIndex)
{
Animation->Blocks.FreeElementAtIndex(i);
}
}
}
internal handle internal handle
Animation_AddBlock(animation* Animation, u32 StartFrame, s32 EndFrame, u32 AnimationProcHandle, u32 LayerIndex) Animation_AddBlock(animation* Animation, u32 StartFrame, s32 EndFrame, u32 AnimationProcHandle, u32 LayerIndex)
{ {
@ -329,6 +302,40 @@ Animation_GetBlockFromHandle(animation* Animation, handle AnimHandle)
return Result; return Result;
} }
internal u32
Animation_AddLayer(animation* Animation, anim_layer Layer)
{
return AnimLayerArray_Push(&Animation->Layers, Layer);
}
internal u32
Animation_AddLayer (animation* Animation, gs_string Name, blend_mode BlendMode, animation_system* System)
{
anim_layer NewLayer = {0};
NewLayer.Name = PushStringF(System->Storage, 256, "%S", Name);
NewLayer.BlendMode = BlendMode;
return Animation_AddLayer(Animation, NewLayer);
}
internal void
Animation_RemoveLayer (animation* Animation, u32 LayerIndex)
{
AnimLayerArray_Remove(&Animation->Layers, LayerIndex);
for (u32 i = Animation->Blocks_.Count - 1; i >= 0; i--)
{
animation_block* Block = Animation->Blocks_.Values + i;
if (Block->Layer > LayerIndex)
{
Block->Layer -= 1;
}
else if (Block->Layer == LayerIndex)
{
AnimBlockArray_RemoveAt(&Animation->Blocks_, i);
}
}
}
////////////////////////// //////////////////////////
// //
// //
@ -408,12 +415,9 @@ AnimationSystem_CalculateAnimationFrame(animation_system* System, gs_memory_aren
Result.BlocksFilled = PushArray(Arena, b8, Result.BlocksCountMax); Result.BlocksFilled = PushArray(Arena, b8, Result.BlocksCountMax);
ZeroArray(Result.BlocksFilled, b8, Result.BlocksCountMax); ZeroArray(Result.BlocksFilled, b8, Result.BlocksCountMax);
for (u32 i = 0; i < ActiveAnim->Blocks.Used; i++) for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++)
{ {
gs_list_entry<animation_block>* BlockEntry = ActiveAnim->Blocks.GetEntryAtIndex(i); animation_block Block = ActiveAnim->Blocks_.Values[i];
if (EntryIsFree(BlockEntry)) { continue; }
animation_block Block = BlockEntry->Value;
if (FrameIsInRange(Block.Range, System->CurrentFrame)) if (FrameIsInRange(Block.Range, System->CurrentFrame))
{ {

View File

@ -16,7 +16,7 @@ AnimSerializer_Serialize(animation Anim, animation_clip* GlobalClips, gs_memory_
Serializer_WriteF(&Serializer, "%S;\n", AnimationFieldStrings[AnimField_FileIdent]); Serializer_WriteF(&Serializer, "%S;\n", AnimationFieldStrings[AnimField_FileIdent]);
Serializer_WriteStringValue(&Serializer, AnimField_AnimName, Anim.Name.ConstString); Serializer_WriteStringValue(&Serializer, AnimField_AnimName, Anim.Name.ConstString);
Serializer_WriteValue(&Serializer, AnimField_LayersCount, Anim.Layers.Count); Serializer_WriteValue(&Serializer, AnimField_LayersCount, Anim.Layers.Count);
Serializer_WriteValue(&Serializer, AnimField_BlocksCount, Anim.Blocks.Used); Serializer_WriteValue(&Serializer, AnimField_BlocksCount, Anim.Blocks_.Count);
Serializer_OpenStruct(&Serializer, AnimField_PlayableRange); Serializer_OpenStruct(&Serializer, AnimField_PlayableRange);
{ {
@ -40,12 +40,10 @@ AnimSerializer_Serialize(animation Anim, animation_clip* GlobalClips, gs_memory_
Serializer_OpenStruct(&Serializer, AnimField_BlocksArray); Serializer_OpenStruct(&Serializer, AnimField_BlocksArray);
for (u32 i = 0; i < Anim.Blocks.Used; i++) for (u32 i = 0; i < Anim.Blocks_.Count; i++)
{ {
gs_list_entry<animation_block>* AnimationBlockEntry = Anim.Blocks.GetEntryAtIndex(i); // TODO(pjs): Handle free'd animation blocks
if (EntryIsFree(AnimationBlockEntry)) { continue; } animation_block AnimationBlockAt = Anim.Blocks_.Values[i];
gs_list_handle CurrentBlockHandle = AnimationBlockEntry->Handle;
animation_block AnimationBlockAt = AnimationBlockEntry->Value;
// TODO(pjs): Systematize the AnimationProcHandle // TODO(pjs): Systematize the AnimationProcHandle
// :AnimProcHandle // :AnimProcHandle
@ -171,7 +169,7 @@ AnimParser_Parse(gs_string File, animation_clip* GlobalClips, gs_memory_arena* A
if (Parser_ReadCloseStruct(&Parser)) if (Parser_ReadCloseStruct(&Parser))
{ {
Result.Blocks.PushElementOnList(Block); AnimBlockArray_Push(&Result.Blocks_, Block);
} }
else else
{ {

View File

@ -136,7 +136,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->Modes = OperationModeSystemInit(&State->Permanent, Context.ThreadContext); State->Modes = OperationModeSystemInit(&State->Permanent, Context.ThreadContext);
{ // Animation PLAYGROUND { // Animation PLAYGROUND
State->AnimationSystem = {}; State->AnimationSystem = {};
State->AnimationSystem.Storage = &State->Permanent; State->AnimationSystem.Storage = &State->Permanent;
State->AnimationSystem.Animations = AnimationArray_Create(State->AnimationSystem.Storage, 32); State->AnimationSystem.Animations = AnimationArray_Create(State->AnimationSystem.Storage, 32);
@ -160,9 +159,8 @@ INITIALIZE_APPLICATION(InitializeApplication)
} // End Animation Playground } // End Animation Playground
InitializePanelSystem(&State->PanelSystem); InitializePanelSystem(&State->PanelSystem, GlobalPanelDefs, GlobalPanelDefsCount);
panel* Panel = TakeNewPanel(&State->PanelSystem); PanelSystem_PushPanel(&State->PanelSystem, PanelType_SculptureView, State, Context);
SetAndInitPanelType(Panel, PanelType_SculptureView, State, Context);
} }
internal void internal void
@ -184,7 +182,7 @@ HandleInput (app_state* State, rect2 WindowBounds, input_queue InputQueue, mouse
if (!PanelWithMouseOverIt.Panel) { return; } if (!PanelWithMouseOverIt.Panel) { return; }
State->HotPanel = PanelWithMouseOverIt.Panel; State->HotPanel = PanelWithMouseOverIt.Panel;
s32 PanelTypeIndex = Panel_GetCurrentTypeIndex(PanelWithMouseOverIt.Panel); s32 PanelTypeIndex = PanelWithMouseOverIt.Panel->TypeIndex;
panel_definition PanelDefinition = GlobalPanelDefs[PanelTypeIndex]; panel_definition PanelDefinition = GlobalPanelDefs[PanelTypeIndex];
if (!PanelDefinition.InputCommands) { return; } if (!PanelDefinition.InputCommands) { return; }

View File

@ -26,14 +26,14 @@
typedef struct app_state app_state; typedef struct app_state app_state;
#include "editor/foldhaus_command_dispatch.h"
#include "editor/foldhaus_operation_mode.h"
// TODO(Peter): something we can do later is to remove all reliance on app_state and context // TODO(Peter): something we can do later is to remove all reliance on app_state and context
// from foldhaus_pane.h. It should just emit lists of things that the app can iterate over and // from foldhaus_pane.h. It should just emit lists of things that the app can iterate over and
// perform operations on, like panel_draw_requests = { bounds, panel* } etc. // perform operations on, like panel_draw_requests = { bounds, panel* } etc.
#include "editor/foldhaus_panel.h" #include "editor/foldhaus_panel.h"
#include "editor/foldhaus_command_dispatch.h"
#include "editor/foldhaus_operation_mode.h"
#include "engine/animation/foldhaus_animation.h" #include "engine/animation/foldhaus_animation.h"
#include "engine/animation/foldhaus_animation_serializer.cpp" #include "engine/animation/foldhaus_animation_serializer.cpp"
@ -209,27 +209,6 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndCurrentOperationMode)
DeactivateCurrentOperationMode(&State->Modes); DeactivateCurrentOperationMode(&State->Modes);
} }
#define PANEL_INIT_PROC(name) void name(panel* Panel, app_state* State, context Context)
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);
#define PANEL_RENDER_PROC(name) void name(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
typedef PANEL_RENDER_PROC(panel_render_proc);
// NOTE(Peter): This is used by the meta system to generate panel type info
struct panel_definition
{
char* PanelName;
s32 PanelNameLength;
panel_init_proc* Init;
panel_cleanup_proc* Cleanup;
panel_render_proc* Render;
input_command* InputCommands;
s32 InputCommandsCount;
};
s32 GlobalAnimationClipsCount = 3; s32 GlobalAnimationClipsCount = 3;
animation_clip GlobalAnimationClips[] = { animation_clip GlobalAnimationClips[] = {
{ "Test Pattern One", 16, TestPatternOne }, { "Test Pattern One", 16, TestPatternOne },
@ -239,12 +218,13 @@ animation_clip GlobalAnimationClips[] = {
#include "editor/panels/foldhaus_panel_types.h" #include "editor/panels/foldhaus_panel_types.h"
#include "editor/panels/foldhaus_panel_file_view.h"
#include "editor/panels/foldhaus_panel_sculpture_view.h" #include "editor/panels/foldhaus_panel_sculpture_view.h"
#include "editor/panels/foldhaus_panel_profiler.h" #include "editor/panels/foldhaus_panel_profiler.h"
#include "editor/panels/foldhaus_panel_dmx_view.h" #include "editor/panels/foldhaus_panel_dmx_view.h"
#include "editor/panels/foldhaus_panel_animation_timeline.h" #include "editor/panels/foldhaus_panel_animation_timeline.h"
#include "editor/panels/foldhaus_panel_hierarchy.h" #include "editor/panels/foldhaus_panel_hierarchy.h"
#include "editor/panels/foldhaus_panel_file_view.h"
#include "editor/panels/foldhaus_panel_types.cpp" #include "editor/panels/foldhaus_panel_types.cpp"
//#include "generated/foldhaus_panels_generated.h" //#include "generated/foldhaus_panels_generated.h"