diff --git a/src-ui/app/edit-screen/components/mapping-pane/VariantDisplay.cpp b/src-ui/app/edit-screen/components/mapping-pane/VariantDisplay.cpp index 13765e8f..56d88860 100644 --- a/src-ui/app/edit-screen/components/mapping-pane/VariantDisplay.cpp +++ b/src-ui/app/edit-screen/components/mapping-pane/VariantDisplay.cpp @@ -969,9 +969,13 @@ void VariantDisplay::showVariantTabMenu(int variantIdx) { p.addSectionHeader("Variant " + std::to_string(variantIdx + 1)); p.addSeparator(); - ; + p.addItem("Copy", editor->makeComingSoon("Copy Variant")); - p.addItem("Delete", editor->makeComingSoon("Delete Variant")); + p.addItem("Delete", [variantIdx, w = juce::Component::SafePointer(this)]() { + if (!w) + return; + w->sendToSerialization(cmsg::DeleteVariant(variantIdx)); + }); } p.showMenuAsync(editor->defaultPopupMenuOptions()); } diff --git a/src/engine/zone.cpp b/src/engine/zone.cpp index 7fab8f96..417afca0 100644 --- a/src/engine/zone.cpp +++ b/src/engine/zone.cpp @@ -455,5 +455,20 @@ int16_t Zone::missingSampleCount() const return ct; } +void Zone::deleteVariant(int idx) +{ + assert(idx >= 0 && idx < maxVariantsPerZone); + for (int nv = idx + 1; nv < maxVariantsPerZone; ++nv) + { + variantData.variants[nv - 1] = variantData.variants[nv]; + samplePointers[nv - 1] = samplePointers[nv]; + } + if (idx < maxVariantsPerZone - 1) + { + variantData.variants[maxVariantsPerZone - 1] = {}; + samplePointers[maxVariantsPerZone - 1] = {}; + } +} + template struct HasGroupZoneProcessors; } // namespace scxt::engine diff --git a/src/engine/zone.h b/src/engine/zone.h index dbddddbe..7fc0ee07 100644 --- a/src/engine/zone.h +++ b/src/engine/zone.h @@ -156,6 +156,8 @@ struct Zone : MoveableOnly, HasGroupZoneProcessors, SampleRateSuppor [](const auto &s) { return s.active == false; })); } + void deleteVariant(int idx); + struct ZoneOutputInfo { float amplitude{1.f}, pan{0.f}; diff --git a/src/messaging/client/client_serial.h b/src/messaging/client/client_serial.h index 8b996a8a..7191340a 100644 --- a/src/messaging/client/client_serial.h +++ b/src/messaging/client/client_serial.h @@ -93,6 +93,8 @@ enum ClientToSerializationMessagesIds c2s_normalize_variant_amplitude, c2s_clear_variant_amplitude_normalization, + c2s_delete_variant, + c2s_update_zone_output_float_value, c2s_update_zone_output_int16_t_value, diff --git a/src/messaging/client/zone_messages.h b/src/messaging/client/zone_messages.h index 0fb9dcf4..6ffc782b 100644 --- a/src/messaging/client/zone_messages.h +++ b/src/messaging/client/zone_messages.h @@ -183,6 +183,30 @@ inline void doAddBlankZone(const addBlankZonePayload_t &payload, engine::Engine CLIENT_TO_SERIAL(AddBlankZone, c2s_add_blank_zone, addBlankZonePayload_t, doAddBlankZone(payload, engine, cont)); +using deleteVariantPayload_t = int; +inline void doDeleteVariant(const deleteVariantPayload_t &payload, engine::Engine &engine, + MessageController &cont) +{ + const auto &samples = payload; + auto sz = engine.getSelectionManager()->currentLeadZone(engine); + if (sz.has_value()) + { + auto [ps, gs, zs] = *sz; + cont.scheduleAudioThreadCallback( + [p = ps, g = gs, z = zs, var = payload](auto &eng) { + const auto &zone = eng.getPatch()->getPart(p)->getGroup(g)->getZone(z); + zone->deleteVariant(var); + eng.getSampleManager()->purgeUnreferencedSamples(); + }, + [p = ps, g = gs, z = zs](auto &e) { + SCLOG_ONCE("Delete variant could be optimized to not sending so much back"); + e.sendFullRefreshToClient(); + }); + } +} +CLIENT_TO_SERIAL(DeleteVariant, c2s_delete_variant, deleteVariantPayload_t, + doDeleteVariant(payload, engine, cont)) + } // namespace scxt::messaging::client #endif // SHORTCIRCUIT_ZONE_MESSAGES_H