From 5c183d9c5fe6eba63ecc58d70aa070b03cd71b9a Mon Sep 17 00:00:00 2001 From: PS Date: Sun, 18 Oct 2020 15:31:53 -0700 Subject: [PATCH] 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 --- src/app/editor/foldhaus_interface.cpp | 36 +--- src/app/editor/foldhaus_panel.h | 188 +++++++++++------- .../foldhaus_panel_animation_timeline.h | 36 ++-- .../editor/panels/foldhaus_panel_file_view.h | 16 +- .../editor/panels/foldhaus_panel_hierarchy.h | 24 +-- src/app/engine/animation/foldhaus_animation.h | 90 +++++---- .../foldhaus_animation_serializer.cpp | 12 +- src/app/foldhaus_app.cpp | 8 +- src/app/foldhaus_app.h | 30 +-- 9 files changed, 222 insertions(+), 218 deletions(-) diff --git a/src/app/editor/foldhaus_interface.cpp b/src/app/editor/foldhaus_interface.cpp index 4160ab2..28a24c2 100644 --- a/src/app/editor/foldhaus_interface.cpp +++ b/src/app/editor/foldhaus_interface.cpp @@ -19,26 +19,6 @@ enum panel_edit_mode 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 @@ -249,19 +229,19 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndSplitPanelOperation) if (XDistance > YDistance) { r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / Rect2Width(PanelBounds); - SplitPanelVertically(Panel, XPercent, &State->PanelSystem); + SplitPanelVertically(Panel, XPercent, &State->PanelSystem, State, Context); } else { 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); - gs_data PanelStateMemory = Panel_GetCurrentTypeStateMemory_(Panel); - Panel_SetCurrentTypeIndex(&Panel->Left->Panel, PanelTypeIndex, PanelStateMemory); + s32 PanelTypeIndex = Panel->TypeIndex; + gs_data PanelStateMemory = Panel->StateMemory; + 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); } @@ -438,7 +418,7 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect2 FooterB gs_string DefName = MakeString(Def.PanelName, Def.PanelNameLength); if (ui_Button(&State->Interface, DefName, ButtonBounds)) { - SetAndInitPanelType(Panel, i, State, Context); + SetAndInitPanelType(Panel, &State->PanelSystem, i, State, Context); Panel->PanelSelectionMenuOpen = false; } @@ -456,7 +436,7 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect2 FooterB internal void 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); rect2 FooterBounds = rect2{ diff --git a/src/app/editor/foldhaus_panel.h b/src/app/editor/foldhaus_panel.h index 190a118..658a8a3 100644 --- a/src/app/editor/foldhaus_panel.h +++ b/src/app/editor/foldhaus_panel.h @@ -19,18 +19,19 @@ enum panel_split_direction }; 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 { + s32 TypeIndex; + gs_data StateMemory; - // TODO(pjs): We want this to be a list, so that you can push sub panels on - // and let them return to you, to perform certain tasks, like loading a file - //s32 PanelDefinitionIndex; -#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_entry* ModalOverride; + panel* IsModalOverrideFor; // TODO(pjs): I don't like that this is panel* but ModalOverride is panel_entry* + panel_modal_override_callback* ModalOverrideCB; panel_split_direction SplitDirection; r32 SplitPercent; @@ -60,9 +61,33 @@ struct panel_entry 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 struct panel_system { + panel_definition* PanelDefs; + u32 PanelDefsCount; + panel_entry Panels[PANELS_MAX]; u32 PanelsUsed; @@ -92,9 +117,11 @@ struct panel_layout ///////////////////////////////// internal void -InitializePanelSystem(panel_system* PanelSystem) +InitializePanelSystem(panel_system* PanelSystem, panel_definition* PanelDefs, u32 PanelDefsCount) { PanelSystem->FreeList.Free.Next = &PanelSystem->FreeList; + PanelSystem->PanelDefs = PanelDefs; + PanelSystem->PanelDefsCount = PanelDefsCount; } internal panel_entry* @@ -114,16 +141,6 @@ TakeNewPanelEntry(panel_system* PanelSystem) 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 FreePanelEntry(panel_entry* Entry, panel_system* PanelSystem) { @@ -153,98 +170,111 @@ FreePanelAtIndex(s32 Index, panel_system* PanelSystem) PanelSystem->FreeList.Free.Next = EntryToFree; } -internal void -Panel_SetCurrentTypeIndex(panel* Panel, s32 NewPanelType, gs_data TypeStateMemory, gs_data ReturnDestMemory = {0}) +internal panel_entry* +Panel_GetModalOverride(panel_entry* PanelEntry) { - u32 CurrentTypeIndex = 0; - if (Panel->TypeIndicesCount != 0) + panel_entry* Result = PanelEntry; + 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->TypeStateMemory[CurrentTypeIndex] = TypeStateMemory; - Panel->ReturnDestMemory[CurrentTypeIndex] = ReturnDestMemory; -} - -internal s32 -Panel_GetCurrentTypeIndex(panel* Panel) -{ - s32 Result = -1; - if (Panel->TypeIndicesCount != 0) + Panel->TypeIndex = NewPanelType; + Panel->StateMemory = TypeStateMemory; + + if(OldTypeIndex >= 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 -Panel_GetCurrentTypeStateMemory_(panel* Panel) +Panel_GetStateMemory(panel* Panel, u64 Size) { - gs_data Result = {0}; - if (Panel->TypeIndicesCount != 0) - { - Result = Panel->TypeStateMemory[Panel->TypeIndicesCount - 1]; - } + Assert(Panel->StateMemory.Size == Size); + gs_data Result = Panel->StateMemory; return Result; } -internal void -Panel_SetCurrentTypeStateMemory(panel* Panel, gs_data StateMemory) +internal panel_entry* +PanelSystem_PushPanel(panel_system* PanelSystem, s32 PanelTypeIndex, app_state* State, context Context) { - u32 CurrentTypeIndex = 0; - if (Panel->TypeIndicesCount != 0) - { - CurrentTypeIndex = Panel->TypeIndicesCount - 1; - } - else - { - CurrentTypeIndex = Panel->TypeIndicesCount++; - } - Panel->TypeStateMemory[CurrentTypeIndex] = StateMemory; + panel_entry* PanelEntry = TakeNewPanelEntry(PanelSystem); + SetAndInitPanelType(&PanelEntry->Panel, PanelSystem, PanelTypeIndex, State, Context); + return PanelEntry; } internal void -Panel_PushTypeWithReturn(panel* Panel, s32 NewPanelType, gs_data ReturnDestMemory) -{ - 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) +SplitPanel(panel* Parent, r32 Percent, panel_split_direction SplitDirection, panel_system* PanelSystem, app_state* State, context Context) { if (Percent >= 0.0f && Percent <= 1.0f) { Parent->SplitDirection = SplitDirection; Parent->SplitPercent = Percent; - s32 ParentTypeIndex = Panel_GetCurrentTypeIndex(Parent); - gs_data ParentStateMemory = Panel_GetCurrentTypeStateMemory_(Parent); + s32 ParentTypeIndex = Parent->TypeIndex; + gs_data ParentStateMemory = Parent->StateMemory; 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); - Panel_SetCurrentTypeIndex(&Parent->Right->Panel, ParentTypeIndex, ParentStateMemory); + Panel_SetCurrentType(&Parent->Right->Panel, PanelSystem, ParentTypeIndex, ParentStateMemory, State, Context); } } 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 -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 @@ -321,13 +351,17 @@ LayoutPanel(panel* Panel, rect2 PanelBounds, panel_layout* Layout) if (Panel->SplitDirection == PanelSplit_NoSplit) { panel_with_layout* WithLayout = Layout->Panels + Layout->PanelsCount++; - WithLayout->Panel = Panel; + WithLayout->Panel = Panel_GetModalOverride(Panel); WithLayout->Bounds = PanelBounds; } else if (Panel->SplitDirection == PanelSplit_Horizontal) { rect2 TopPanelBounds = GetTopPanelBounds(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->Bottom->Panel, BottomPanelBounds, Layout); } @@ -335,6 +369,10 @@ LayoutPanel(panel* Panel, rect2 PanelBounds, panel_layout* Layout) { rect2 LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds); rect2 RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds); + + panel* LeftPanel = Panel_GetModalOverride(&Panel->Top->Panel); + panel* RightPanel = Panel_GetModalOverride(&Panel->Bottom->Panel); + LayoutPanel(&Panel->Left->Panel, LeftPanelBounds, Layout); LayoutPanel(&Panel->Right->Panel, RightPanelBounds, Layout); } diff --git a/src/app/editor/panels/foldhaus_panel_animation_timeline.h b/src/app/editor/panels/foldhaus_panel_animation_timeline.h index e242a12..91f01fa 100644 --- a/src/app/editor/panels/foldhaus_panel_animation_timeline.h +++ b/src/app/editor/panels/foldhaus_panel_animation_timeline.h @@ -170,11 +170,9 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip) s32 NewStartFrame = OpState->ClipRange.Min + FrameOffset; if (FrameOffset < 0) { - for (u32 i = 0; i < ActiveAnim->Blocks.Used; i++) + for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++) { - gs_list_entry* OtherBlockEntry = ActiveAnim->Blocks.GetEntryAtIndex(i); - if (EntryIsFree(OtherBlockEntry)) { continue; } - animation_block OtherBlock = OtherBlockEntry->Value; + animation_block OtherBlock = ActiveAnim->Blocks_.Values[i]; NewStartFrame = AttemptToSnapPosition(NewStartFrame, OtherBlock.Range.Max); } } @@ -192,11 +190,9 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip) r32 NewEndFrame = OpState->ClipRange.Max + FrameOffset; if (FrameOffset > 0) { - for (u32 i = 0; i < ActiveAnim->Blocks.Used; i++) + for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++) { - gs_list_entry* OtherBlockEntry = ActiveAnim->Blocks.GetEntryAtIndex(i); - if (EntryIsFree(OtherBlockEntry)) { continue; } - animation_block OtherBlock = OtherBlockEntry->Value; + animation_block OtherBlock = ActiveAnim->Blocks_.Values[i]; NewEndFrame = AttemptToSnapPosition(NewEndFrame, OtherBlock.Range.Min); } } @@ -213,11 +209,9 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip) { u32 NewStartFrame = OpState->ClipRange.Min + 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* OtherBlockEntry = ActiveAnim->Blocks.GetEntryAtIndex(i); - if (EntryIsFree(OtherBlockEntry)) { continue; } - animation_block OtherBlock = OtherBlockEntry->Value; + animation_block OtherBlock = ActiveAnim->Blocks_.Values[i];; u32 SnapFramesAmount = 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); TimelineState->VisibleRange = ActiveAnim->PlayableRange; - Panel_SetCurrentTypeStateMemory(Panel, StructToData(TimelineState, animation_timeline_state)); + Panel->StateMemory = StructToData(TimelineState, animation_timeline_state); } GSMetaTag(panel_cleanup); @@ -580,6 +574,13 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta 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 DrawAnimationClipsList(rect2 PanelBounds, ui_interface* Interface, u32 SelectedAnimationLayerHandle, animation_system* AnimationSystem) { @@ -600,7 +601,7 @@ GSMetaTag(panel_type_animation_timeline); internal void 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 // unless its used elsewhere. Audit later handle SelectedBlockHandle = State->SelectedAnimationBlockHandle; @@ -634,11 +635,8 @@ AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* if (ui_LayoutButton(Interface, &TitleBarLayout, MakeString("Load"))) { - // TODO(pjs): You were working on #6 on your todo list. - // below is a "write the interface first" example of how you'd like to be able to - // activate a file panel from within another panel. - gs_data ReturnDestination = {}; - Panel_PushTypeWithReturn(Panel, PanelType_FileView, ReturnDestination); + panel_entry* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context); + Panel_PushModalOverride(Panel, FileBrowser, LoadAnimationFileCallback); // 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 // something like: AnimPanel_HandleLoadedAnimationFile diff --git a/src/app/editor/panels/foldhaus_panel_file_view.h b/src/app/editor/panels/foldhaus_panel_file_view.h index a1b9d98..78cbd47 100644 --- a/src/app/editor/panels/foldhaus_panel_file_view.h +++ b/src/app/editor/panels/foldhaus_panel_file_view.h @@ -10,6 +10,8 @@ struct file_view_state gs_string WorkingDirectory; gs_memory_arena FileNamesArena; gs_file_info_array FileNames; + + gs_file_info SelectedFile; }; input_command* FileView_Commands = 0; @@ -55,7 +57,7 @@ FileView_Init(panel* Panel, app_state* State, context Context) { // TODO: :FreePanelMemory 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); FileViewUpdateWorkingDirectory(ConstString("."), FileViewState, Context); } @@ -73,7 +75,7 @@ GSMetaTag(panel_type_file_view); internal void 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); // Header @@ -96,7 +98,15 @@ FileView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBu } 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); } } } diff --git a/src/app/editor/panels/foldhaus_panel_hierarchy.h b/src/app/editor/panels/foldhaus_panel_hierarchy.h index 3654cdb..fdecc36 100644 --- a/src/app/editor/panels/foldhaus_panel_hierarchy.h +++ b/src/app/editor/panels/foldhaus_panel_hierarchy.h @@ -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_type_hierarchy); internal void @@ -66,19 +75,8 @@ HierarchyView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Ren PrintF(&TempString, "+ Add Assembly"); if (ui_ListButton(&State->Interface, TempString, LineBounds[AssembliesToDraw], AssembliesToDraw)) { - gs_string FilePath = PushString(State->Transient, 256); - - // 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 + panel_entry* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context); + Panel_PushModalOverride(Panel, FileBrowser, LoadAssemblyCallback); } } } diff --git a/src/app/engine/animation/foldhaus_animation.h b/src/app/engine/animation/foldhaus_animation.h index 45037af..cb564a7 100644 --- a/src/app/engine/animation/foldhaus_animation.h +++ b/src/app/engine/animation/foldhaus_animation.h @@ -62,7 +62,6 @@ struct animation gs_string Name; anim_layer_array Layers; - gs_list Blocks; animation_block_array Blocks_; frame_range PlayableRange; @@ -199,6 +198,17 @@ AnimBlockArray_Remove(animation_block_array* Array, handle Handle) 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 @@ -257,43 +267,6 @@ AnimationArray_Push(animation_array* Array, animation Value) // // 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* 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 Animation_AddBlock(animation* Animation, u32 StartFrame, s32 EndFrame, u32 AnimationProcHandle, u32 LayerIndex) { @@ -329,6 +302,40 @@ Animation_GetBlockFromHandle(animation* Animation, handle AnimHandle) 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); 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* BlockEntry = ActiveAnim->Blocks.GetEntryAtIndex(i); - if (EntryIsFree(BlockEntry)) { continue; } - - animation_block Block = BlockEntry->Value; + animation_block Block = ActiveAnim->Blocks_.Values[i]; if (FrameIsInRange(Block.Range, System->CurrentFrame)) { diff --git a/src/app/engine/animation/foldhaus_animation_serializer.cpp b/src/app/engine/animation/foldhaus_animation_serializer.cpp index d66f3ee..57d6221 100644 --- a/src/app/engine/animation/foldhaus_animation_serializer.cpp +++ b/src/app/engine/animation/foldhaus_animation_serializer.cpp @@ -16,7 +16,7 @@ AnimSerializer_Serialize(animation Anim, animation_clip* GlobalClips, gs_memory_ Serializer_WriteF(&Serializer, "%S;\n", AnimationFieldStrings[AnimField_FileIdent]); Serializer_WriteStringValue(&Serializer, AnimField_AnimName, Anim.Name.ConstString); 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); { @@ -40,12 +40,10 @@ AnimSerializer_Serialize(animation Anim, animation_clip* GlobalClips, gs_memory_ 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* AnimationBlockEntry = Anim.Blocks.GetEntryAtIndex(i); - if (EntryIsFree(AnimationBlockEntry)) { continue; } - gs_list_handle CurrentBlockHandle = AnimationBlockEntry->Handle; - animation_block AnimationBlockAt = AnimationBlockEntry->Value; + // TODO(pjs): Handle free'd animation blocks + animation_block AnimationBlockAt = Anim.Blocks_.Values[i]; // TODO(pjs): Systematize the AnimationProcHandle // :AnimProcHandle @@ -171,7 +169,7 @@ AnimParser_Parse(gs_string File, animation_clip* GlobalClips, gs_memory_arena* A if (Parser_ReadCloseStruct(&Parser)) { - Result.Blocks.PushElementOnList(Block); + AnimBlockArray_Push(&Result.Blocks_, Block); } else { diff --git a/src/app/foldhaus_app.cpp b/src/app/foldhaus_app.cpp index 744e4f1..b578796 100644 --- a/src/app/foldhaus_app.cpp +++ b/src/app/foldhaus_app.cpp @@ -136,7 +136,6 @@ INITIALIZE_APPLICATION(InitializeApplication) State->Modes = OperationModeSystemInit(&State->Permanent, Context.ThreadContext); { // Animation PLAYGROUND - State->AnimationSystem = {}; State->AnimationSystem.Storage = &State->Permanent; State->AnimationSystem.Animations = AnimationArray_Create(State->AnimationSystem.Storage, 32); @@ -160,9 +159,8 @@ INITIALIZE_APPLICATION(InitializeApplication) } // End Animation Playground - InitializePanelSystem(&State->PanelSystem); - panel* Panel = TakeNewPanel(&State->PanelSystem); - SetAndInitPanelType(Panel, PanelType_SculptureView, State, Context); + InitializePanelSystem(&State->PanelSystem, GlobalPanelDefs, GlobalPanelDefsCount); + PanelSystem_PushPanel(&State->PanelSystem, PanelType_SculptureView, State, Context); } internal void @@ -184,7 +182,7 @@ HandleInput (app_state* State, rect2 WindowBounds, input_queue InputQueue, mouse if (!PanelWithMouseOverIt.Panel) { return; } State->HotPanel = PanelWithMouseOverIt.Panel; - s32 PanelTypeIndex = Panel_GetCurrentTypeIndex(PanelWithMouseOverIt.Panel); + s32 PanelTypeIndex = PanelWithMouseOverIt.Panel->TypeIndex; panel_definition PanelDefinition = GlobalPanelDefs[PanelTypeIndex]; if (!PanelDefinition.InputCommands) { return; } diff --git a/src/app/foldhaus_app.h b/src/app/foldhaus_app.h index 689f4d0..05bd69f 100644 --- a/src/app/foldhaus_app.h +++ b/src/app/foldhaus_app.h @@ -26,14 +26,14 @@ 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 // 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. #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_serializer.cpp" @@ -209,27 +209,6 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndCurrentOperationMode) 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; animation_clip GlobalAnimationClips[] = { { "Test Pattern One", 16, TestPatternOne }, @@ -239,12 +218,13 @@ animation_clip GlobalAnimationClips[] = { #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_profiler.h" #include "editor/panels/foldhaus_panel_dmx_view.h" #include "editor/panels/foldhaus_panel_animation_timeline.h" #include "editor/panels/foldhaus_panel_hierarchy.h" -#include "editor/panels/foldhaus_panel_file_view.h" + #include "editor/panels/foldhaus_panel_types.cpp" //#include "generated/foldhaus_panels_generated.h"