diff --git a/src/app/editor/interface.h b/src/app/editor/interface.h index f06c16a..4b4d13e 100644 --- a/src/app/editor/interface.h +++ b/src/app/editor/interface.h @@ -753,13 +753,13 @@ ui_PushOverlayLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction } static gs_string -ui_PushLayoutCategoryName(ui_interface* Interface, gs_string Category, gs_string Identifier) +ui_PushLayoutCategoryName(ui_interface* Interface, gs_string Category, u32 Value) { gs_string Result = PushStringF(Interface->PerFrameMemory, - Category.Length + Identifier.Length, - "%S%S", + Category.Length + 25, + "%S%d", Category.ConstString, - Identifier.ConstString); + Value); return Result; } @@ -782,9 +782,9 @@ ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir return Result; } static ui_widget* -ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Category, gs_string Identifier) +ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Category, u32 Value) { - gs_string Name = ui_PushLayoutCategoryName(Interface, Category, Identifier); + gs_string Name = ui_PushLayoutCategoryName(Interface, Category, Value); return ui_PushLayout(Interface, Bounds, FillDir, Name); } @@ -854,7 +854,16 @@ ui_PopLayout(ui_interface* Interface, gs_string LayoutName) // NOTE(pjs): If this isn't true then a layout was opened without being closed // Go check for ui_PushLayout, ui_BeginDropdown, ui_BeginRow, etc that don't have // a corresponding ui_Pop/ui_End* - Assert(StringsEqual(Layout->String, LayoutName)); + // + // We use StringsEqualUpToLength here becuase its possible that + // the current layout used the Category + Identifier method + // for generating Layout->String. And if Identifier was a string + // that was edited within the scope of this layout, then + // Layout->String and LayoutName will no longer match. + // + // This is a compromise that will at least let us know if + // we aren't popping all our layouts correctly. + Assert(StringsEqualUpToLength(Layout->String, LayoutName, LayoutName.Length)); ui_ExpandToFitChildren(Layout); @@ -869,9 +878,9 @@ ui_PopLayout(ui_interface* Interface, gs_string LayoutName) } } static void -ui_PopLayout(ui_interface* Interface, gs_string Category, gs_string Identifier) +ui_PopLayout(ui_interface* Interface, gs_string Category, u32 Value) { - gs_string Name = ui_PushLayoutCategoryName(Interface, Category, Identifier); + gs_string Name = ui_PushLayoutCategoryName(Interface, Category, Value); ui_PopLayout(Interface, Name); } @@ -1073,6 +1082,7 @@ ui_EvaluateWidget(ui_interface* Interface, ui_widget* Widget, rect2 Bounds) else { OutChar(&State->EditString, Interface->TempInputString.Str[i]); + Interface->CursorPosition += 1; } } } diff --git a/src/app/editor/panels/foldhaus_panel_animation_timeline.h b/src/app/editor/panels/foldhaus_panel_animation_timeline.h index b0b7dcc..d319a0e 100644 --- a/src/app/editor/panels/foldhaus_panel_animation_timeline.h +++ b/src/app/editor/panels/foldhaus_panel_animation_timeline.h @@ -14,7 +14,7 @@ struct animation_timeline_state frame_range VisibleRange; handle SelectedBlockHandle; animation_handle EditingAnimationHandle; - u32 SelectedAnimationLayer; + s32 SelectedAnimationLayer; animation_handle NextActiveAnim; }; @@ -265,7 +265,8 @@ AnimationTimeline_AddAnimationBlockCommand(animation_timeline_state* TimelineSta if ((EndFrame - StartFrame) > 0) { animation_pattern_handle PatternHandle = Patterns_IndexToHandle(0); - u32 Layer = TimelineState->SelectedAnimationLayer; + s32 Layer = TimelineState->SelectedAnimationLayer; + Assert(Layer >= 0); handle NewBlockHandle = Animation_AddBlock(ActiveAnim, StartFrame, EndFrame, PatternHandle, Layer); @@ -638,7 +639,7 @@ LayerList_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, if (ActiveAnim) { v2 LayerTextPos = {}; - for (u32 i = 0; i < ActiveAnim->Layers.Count; i++) + for (s32 i = 0; i < (s32)ActiveAnim->Layers.Count; i++) { anim_layer* Layer = ActiveAnim->Layers.Values + i; @@ -771,8 +772,9 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, animation* ActiveAn { animation_system* AnimSystem = &State->AnimationSystem; + animation_handle ActiveAnimHandle = State->AnimationSystem.ActiveFadeGroup.From; ui_interface* Interface = &State->Interface; - ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("AnimInfo Layout"), ActiveAnim->Name); + ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("AnimInfo Layout"), ActiveAnimHandle.Index); ui_FillRect(&State->Interface, Bounds, Interface->Style.PanelBG); @@ -803,18 +805,22 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, animation* ActiveAn { if (ui_Button(Interface, MakeString("New"))) { - animation NewAnim = {}; - NewAnim.Name = PushString(State->AnimationSystem.Storage, 256); + animation_desc Desc = {}; + Desc.NameSize = 256; + Desc.LayersCount = 8; + Desc.BlocksCount = 8; + Desc.MinFrames = 0; + Desc.MaxFrames = SecondsToFrames(15, State->AnimationSystem); + animation NewAnim = Animation_Create(Desc, &State->AnimationSystem); animation_handle NewAnimHandle = AnimationArray_Push(&State->AnimationSystem.Animations, NewAnim); - State->AnimationSystem.ActiveFadeGroup.From = NewAnimHandle; + AnimationTimeline_SetActiveAnimation(NewAnimHandle, TimelineState); } if (ActiveAnim && ui_Button(Interface, MakeString("Save"))) { // Save Animation File // TODO(pjs): If you created the animation via the "new" button, there won't be a file attached. // need to use the file browser to create a file - animation_handle ActiveAnimHandle = State->AnimationSystem.ActiveFadeGroup.From; animation ActiveAnimation = *AnimationArray_GetSafe(State->AnimationSystem.Animations, ActiveAnimHandle); if (!ActiveAnimation.FileInfo.Path.Str) @@ -850,22 +856,26 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, animation* ActiveAn ui_Label(Interface, MakeString("Layer")); - u32 LayerIndex = TimelineState->SelectedAnimationLayer; - anim_layer* SelectedLayer = ActiveAnim->Layers.Values + LayerIndex; - - ui_TextEntry(Interface, MakeString("Layer Name"), &SelectedLayer->Name); - gs_string BlendStr = BlendModeStrings[SelectedLayer->BlendMode]; - if (ui_BeginLabeledDropdown(Interface, MakeString("Blend Mode"), BlendStr)) + s32 LayerIndex = TimelineState->SelectedAnimationLayer; + anim_layer* SelectedLayer = 0; + if (LayerIndex >= 0) { - for (u32 i = 0; i < BlendMode_Count; i++) + SelectedLayer = ActiveAnim->Layers.Values + LayerIndex; + + ui_TextEntry(Interface, MakeString("Layer Name"), &SelectedLayer->Name); + gs_string BlendStr = BlendModeStrings[SelectedLayer->BlendMode]; + if (ui_BeginLabeledDropdown(Interface, MakeString("Blend Mode"), BlendStr)) { - if (ui_Button(Interface, BlendModeStrings[i])) + for (u32 i = 0; i < BlendMode_Count; i++) { - SelectedLayer->BlendMode = (blend_mode)i; + if (ui_Button(Interface, BlendModeStrings[i])) + { + SelectedLayer->BlendMode = (blend_mode)i; + } } } + ui_EndLabeledDropdown(Interface); } - ui_EndLabeledDropdown(Interface); ui_Label(Interface, MakeString("Pattern")); @@ -896,7 +906,7 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, animation* ActiveAn AnimationTimeline_AddAnimationBlockCommand(TimelineState, State, Context); } } - ui_PopLayout(Interface, MakeString("AnimInfo Layout"), ActiveAnim->Name); + ui_PopLayout(Interface, MakeString("AnimInfo Layout")); } internal void @@ -948,6 +958,7 @@ AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* { State->AnimationSystem.ActiveFadeGroup.From = TimelineState->NextActiveAnim; TimelineState->EditingAnimationHandle = TimelineState->NextActiveAnim; + TimelineState->SelectedAnimationLayer = -1; } } diff --git a/src/app/engine/animation/foldhaus_animation.h b/src/app/engine/animation/foldhaus_animation.h index 12281fe..91204c7 100644 --- a/src/app/engine/animation/foldhaus_animation.h +++ b/src/app/engine/animation/foldhaus_animation.h @@ -419,6 +419,38 @@ AnimationArray_GetSafe(animation_array Array, animation_handle Handle) // // Animation +typedef struct animation_desc +{ + u32 NameSize; + char* Name; + + u32 LayersCount; + u32 BlocksCount; + + u32 MinFrames; + u32 MaxFrames; +} animation_desc; + +internal animation +Animation_Create(animation_desc Desc, animation_system* System) +{ + animation Result = {}; + u32 NameLen = Desc.NameSize; + if (Desc.Name) + { + NameLen = Max(CStringLength(Desc.Name), NameLen); + Result.Name = PushStringF(System->Storage, NameLen, "%s", Desc.Name); + } else { + Result.Name = PushStringF(System->Storage, NameLen, "[New Animation]"); + } + + Result.Layers = AnimLayerArray_Create(System->Storage, Desc.LayersCount); + Result.Blocks_ = AnimBlockArray_Create(System->Storage, Desc.BlocksCount); + Result.PlayableRange.Min = Desc.MinFrames; + Result.PlayableRange.Max = Desc.MaxFrames; + return Result; +} + internal handle Animation_AddBlock(animation* Animation, u32 StartFrame, s32 EndFrame, animation_pattern_handle AnimationProcHandle, u32 LayerIndex) { diff --git a/src/app/ss_blumen_lumen/blumen_lumen.cpp b/src/app/ss_blumen_lumen/blumen_lumen.cpp index 29bf6a1..7361fd4 100644 --- a/src/app/ss_blumen_lumen/blumen_lumen.cpp +++ b/src/app/ss_blumen_lumen/blumen_lumen.cpp @@ -188,40 +188,32 @@ BlumenLumen_CustomInit(app_state* State, context Context) #if 0 { // Animation PLAYGROUND - animation Anim0 = {0}; - Anim0.Name = PushStringF(&State->Permanent, 256, "test_anim_zero"); - Anim0.Layers = AnimLayerArray_Create(State->AnimationSystem.Storage, 8); - Anim0.Blocks_ = AnimBlockArray_Create(State->AnimationSystem.Storage, 8); - Anim0.PlayableRange.Min = 0; - Anim0.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem); + animation_desc Desc = {}; + Desc.NameSize = 256; + Desc.LayersCount = 8; + Desc.BlocksCount = 8; + Desc.MinFrames = 0; + Desc.MaxFrames = SecondsToFrames(15, State->AnimationSystem); + + animation_desc Desc0 = Desc; + Desc.Name = "test_anim_zero"; + animation Anim0 = Animation_Create(Desc0, &State->AnimationSystem); Animation_AddLayer(&Anim0, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem); - Animation_AddBlock(&Anim0, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(15), 0); - BLState->AnimHandles[0] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim0); - animation Anim1 = {0}; - Anim1.Name = PushStringF(&State->Permanent, 256, "test_anim_one"); - Anim1.Layers = AnimLayerArray_Create(State->AnimationSystem.Storage, 8); - Anim1.Blocks_ = AnimBlockArray_Create(State->AnimationSystem.Storage, 8); - Anim1.PlayableRange.Min = 0; - Anim1.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem); + animation_desc Desc1 = Desc; + Desc1.Name = "test_anim_one"; + animation Anim1 = Animation_Create(Desc1, &State->AnimationSystem); Animation_AddLayer(&Anim1, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem); - Animation_AddBlock(&Anim1, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(12), 0); - BLState->AnimHandles[1] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim1); - animation Anim2 = {0}; - Anim2.Name = PushStringF(&State->Permanent, 256, "i_love_you"); - Anim2.Layers = AnimLayerArray_Create(State->AnimationSystem.Storage, 8); - Anim2.Blocks_ = AnimBlockArray_Create(State->AnimationSystem.Storage, 8); - Anim2.PlayableRange.Min = 0; - Anim2.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem); + animation_desc Desc2 = Desc; + Desc2.Name = "i_love_you"; + animation Anim2 = Animation_Create(Desc2, &State->AnimationSystem);; Animation_AddLayer(&Anim2, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem); - Animation_AddBlock(&Anim2, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(20), 0); - BLState->AnimHandles[2] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim2); State->AnimationSystem.ActiveFadeGroup.From = BLState->AnimHandles[2]; @@ -417,6 +409,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) } } // Dim the leds based on temp data +#define DIM_LED_BRIGHTNESS 1 #if DIM_LED_BRIGHTNESS for (u32 i = 0; i < State->LedSystem.BuffersCount; i++) { @@ -430,7 +423,25 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) } } - // TODO(pjs): dim stem to 50% + // TODO(PS): This should really only happen if we think the + // flower _might_ be open + for (u32 a = 0; a < State->Assemblies.Count; a++) + { + assembly Assembly = State->Assemblies.Values[a]; + led_buffer Buffer = State->LedSystem.Buffers[Assembly.LedBufferIndex]; + + led_strip_list TopStrips = AssemblyStripsGetWithTagValue(Assembly, ConstString("section"), ConstString("inner_bloom"), State->Transient); + for (u32 s = 0; s < TopStrips.Count; s++) + { + u32 SIndex = TopStrips.StripIndices[s]; + v2_strip Strip = Assembly.Strips[SIndex]; + for (u32 l = 0; l < Strip.LedCount; l++) + { + u32 LIndex = Strip.LedLUT[l]; + Buffer.Colors[LIndex] = {0}; + } + } + } #endif // Send Status Packet