Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More group trigger stuff #1413

Merged
merged 2 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src-ui/app/HasEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct HasEditor
{
SCXTEditor *editor{nullptr};
HasEditor(SCXTEditor *e);
HasEditor(HasEditor *e);
virtual ~HasEditor() = default;

template <typename T> void sendToSerialization(const T &msg);
Expand Down
185 changes: 175 additions & 10 deletions src-ui/app/edit-screen/components/GroupTriggersCard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,38 +27,186 @@

#include "GroupTriggersCard.h"
#include "sst/jucegui/components/ToggleButton.h"
#include "sst/jucegui/components/TextPushButton.h"
#include "sst/jucegui/components/MenuButton.h"
#include "sst/jucegui/components/DraggableTextEditableValue.h"

#include "app/SCXTEditor.h"
#include "messaging/client/client_messages.h"
#include "connectors/PayloadDataAttachment.h"

namespace scxt::ui::app::edit_screen
{
namespace jcmp = sst::jucegui::components;

struct GroupTriggersCard::ConditionRow : juce::Component, HasEditor
{
using booleanAttachment_t =
connectors::BooleanPayloadDataAttachment<scxt::engine::GroupTriggerConditions>;

using floatAttachment_t =
connectors::PayloadDataAttachment<scxt::engine::GroupTriggerConditions>;

GroupTriggersCard *parent{nullptr};
engine::GroupTriggerID lastID{engine::GroupTriggerID::NONE};

int index{-1};
bool withCondition{false};
ConditionRow(int index, bool withCond, SCXTEditor *ed)
: index(index), withCondition(withCond), HasEditor(ed)
ConditionRow(GroupTriggersCard *p, int index, bool withCond)
: parent(p), index(index), withCondition(withCond), HasEditor(p)
{
activeA = std::make_unique<booleanAttachment_t>(
"Active",
[this](const auto &a) {
setupValuesFromData();
parent->pushUpdate();
},
parent->cond.active[index]);
activeB = std::make_unique<jcmp::ToggleButton>();
activeB->setLabel(std::to_string(index + 1));
activeB->setSource(activeA.get());
addAndMakeVisible(*activeB);

auto mkm = [this](auto tx, auto cs) {
auto res = std::make_unique<jcmp::MenuButton>();
auto res = std::make_unique<jcmp::TextPushButton>();
res->setLabel(tx);
res->setOnCallback(
editor->makeComingSoon(std::string() + "Trigger Condition Pane " + cs));
addAndMakeVisible(*res);
return res;
};
typeM = mkm("TYPE", "Trigger Mode");
a1M = mkm("A1", "Argument One");
a2M = mkm("A2", "Argument Two");
typeM->setOnCallback([w = juce::Component::SafePointer(this)]() {
if (!w)
return;
w->showTypeMenu();
});
if (withCond)
cM = mkm("&", "Conjunction");

setupValuesFromData();
}

void setupValuesFromData()
{
auto &sr = parent->cond.storage[index];

if (sr.id != lastID)
{
lastID = sr.id;

auto onArgChanged = [this](const auto &a) { parent->pushUpdate(); };

if (sr.id == engine::GroupTriggerID::NONE)
{
SCLOG("NONE");
a1A.reset();
a2A.reset();
a1M.reset();
a2M.reset();
}
else if ((int)sr.id >= (int)engine::GroupTriggerID::MACRO &&
(int)sr.id <= (int)engine::GroupTriggerID::MACRO + scxt::macrosPerPart)
{
auto dm = datamodel::pmd()
.asFloat()
.withRange(0, 1)
.withLinearScaleFormatting("")
.withDecimalPlaces(2)
.withDefault(0.5);
a1A = std::make_unique<floatAttachment_t>(dm, onArgChanged, sr.args[0]);
a2A = std::make_unique<floatAttachment_t>(dm, onArgChanged, sr.args[1]);

a1M = std::make_unique<jcmp::DraggableTextEditableValue>();
a1M->setSource(a1A.get());
addAndMakeVisible(*a1M);

a2M = std::make_unique<jcmp::DraggableTextEditableValue>();
a2M->setSource(a2A.get());
addAndMakeVisible(*a2M);
}
else if ((int)sr.id >= (int)engine::GroupTriggerID::MIDICC &&
(int)sr.id <= (int)engine::GroupTriggerID::LAST_MIDICC)
{
auto dm = datamodel::pmd()
.asFloat()
.withRange(0, 127)
.withLinearScaleFormatting("")
.withDecimalPlaces(0)
.withDefault(64);
a1A = std::make_unique<floatAttachment_t>(dm, onArgChanged, sr.args[0]);
a2A = std::make_unique<floatAttachment_t>(dm, onArgChanged, sr.args[1]);

a1M = std::make_unique<jcmp::DraggableTextEditableValue>();
a1M->setSource(a1A.get());
addAndMakeVisible(*a1M);

a2M = std::make_unique<jcmp::DraggableTextEditableValue>();
a2M->setSource(a2A.get());
addAndMakeVisible(*a2M);
}
else
{
SCLOG_UNIMPL("No midi CC for type " << (int)sr.id);
}
resized();
}

typeM->setLabel(engine::getGroupTriggerDisplayName(sr.id));
auto showRest = (sr.id != engine::GroupTriggerID::NONE);
if (a1M)
a1M->setVisible(showRest);
if (a2M)
a2M->setVisible(showRest);
if (cM)
cM->setVisible(showRest);

auto ac = parent->cond.active[index];
typeM->setEnabled(ac);
if (a1M)
a1M->setEnabled(ac);
if (a2M)
a2M->setEnabled(ac);
if (cM)
cM->setEnabled(ac);

repaint();
}

void showTypeMenu()
{
auto p = juce::PopupMenu();
p.addSectionHeader("Trigger Mode");
p.addSeparator();

auto mkv = [this](auto v) {
return [w = juce::Component::SafePointer(this), v]() {
if (!w)
return;
w->parent->cond.storage[w->index].id = (engine::GroupTriggerID)v;
w->parent->pushUpdate();
w->setupValuesFromData();
};
};

p.addItem("NONE", mkv((int)engine::GroupTriggerID::NONE));

auto mcc = juce::PopupMenu();
for (int i = 0; i < 128; ++i)
{
mcc.addItem(fmt::format("CC {:3d}", i), mkv((int)engine::GroupTriggerID::MIDICC + i));
}

p.addSubMenu("MIDI CC", mcc);
auto msm = juce::PopupMenu();
for (int i = 0; i < scxt::macrosPerPart; ++i)
{
msm.addItem("Macro " + std::to_string(i + 1),
mkv((int)engine::GroupTriggerID::MACRO + i));
}

p.addSubMenu("Macros", msm);
p.showMenuAsync(editor->defaultPopupMenuOptions());
}

void resized() override
Expand All @@ -69,9 +217,11 @@ struct GroupTriggersCard::ConditionRow : juce::Component, HasEditor
tb = tb.translated(tb.getWidth() + 2, 0).withWidth(72);
typeM->setBounds(tb);
tb = tb.translated(tb.getWidth() + 2, 0).withWidth(32);
a1M->setBounds(tb);
if (a1M)
a1M->setBounds(tb);
tb = tb.translated(tb.getWidth() + 2, 0).withWidth(32);
a2M->setBounds(tb);
if (a2M)
a2M->setBounds(tb);

if (cM)
{
Expand All @@ -80,15 +230,17 @@ struct GroupTriggersCard::ConditionRow : juce::Component, HasEditor
}
}

std::unique_ptr<booleanAttachment_t> activeA;
std::unique_ptr<floatAttachment_t> a1A, a2A;
std::unique_ptr<jcmp::ToggleButton> activeB;
std::unique_ptr<jcmp::MenuButton> typeM, a1M, a2M, cM;
std::unique_ptr<jcmp::TextPushButton> typeM, cM;
std::unique_ptr<jcmp::DraggableTextEditableValue> a1M, a2M;
};
GroupTriggersCard::GroupTriggersCard(SCXTEditor *e) : HasEditor(e)
{
for (int i = 0; i < scxt::triggerConditionsPerGroup; ++i)
{
rows[i] =
std::make_unique<ConditionRow>(i, i != scxt::triggerConditionsPerGroup - 1, editor);
rows[i] = std::make_unique<ConditionRow>(this, i, i != scxt::triggerConditionsPerGroup - 1);
addAndMakeVisible(*rows[i]);
}
}
Expand Down Expand Up @@ -117,4 +269,17 @@ void GroupTriggersCard::paint(juce::Graphics &g)
g.drawText("TRIGGER CONDITIONS", getLocalBounds(), juce::Justification::topLeft);
}

void GroupTriggersCard::setGroupTriggerConditions(const scxt::engine::GroupTriggerConditions &c)
{
cond = c;
for (auto &r : rows)
r->setupValuesFromData();
repaint();
}

void GroupTriggersCard::pushUpdate()
{
sendToSerialization(scxt::messaging::client::UpdateGroupTriggerConditions(cond));
}

} // namespace scxt::ui::app::edit_screen
6 changes: 6 additions & 0 deletions src-ui/app/edit-screen/components/GroupTriggersCard.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

#include <juce_gui_basics/juce_gui_basics.h>

#include "engine/group_triggers.h"

#include "configuration.h"
#include "app/HasEditor.h"

Expand All @@ -46,6 +48,10 @@ struct GroupTriggersCard : juce::Component, HasEditor
~GroupTriggersCard();
void paint(juce::Graphics &g) override;
void resized() override;

void setGroupTriggerConditions(const scxt::engine::GroupTriggerConditions &);
void pushUpdate();
scxt::engine::GroupTriggerConditions cond;
};
} // namespace scxt::ui::app::edit_screen
#endif // GROUPTRIGGERSCARD_H
14 changes: 13 additions & 1 deletion src-ui/app/edit-screen/components/PartGroupSidebar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,13 @@ struct GroupSidebar : GroupZoneSidebarBase<GroupSidebar, false>
}
~GroupSidebar() = default;

void updateSelection() { updateSelectionFrom(partGroupSidebar->editor->allGroupSelections); }
void updateSelection()
{
bool anySel = !partGroupSidebar->editor->allGroupSelections.empty();
updateSelectionFrom(partGroupSidebar->editor->allGroupSelections);
groupSettings->setVisible(anySel);
groupTriggers->setVisible(anySel);
}

void resized() override
{
Expand Down Expand Up @@ -522,4 +528,10 @@ void PartGroupSidebar::partConfigurationChanged(int i)
partSidebar->parts[i]->resetFromEditorCache();
partSidebar->restackForActive();
}

void PartGroupSidebar::groupTriggerConditionChanged(const scxt::engine::GroupTriggerConditions &c)
{
groupSidebar->groupTriggers->setGroupTriggerConditions(c);
}

} // namespace scxt::ui::app::edit_screen
1 change: 1 addition & 0 deletions src-ui/app/edit-screen/components/PartGroupSidebar.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct PartGroupSidebar : sst::jucegui::components::NamedPanel, HasEditor
std::unique_ptr<PartSidebar> partSidebar;

void partConfigurationChanged(int i);
void groupTriggerConditionChanged(const scxt::engine::GroupTriggerConditions &);

void resized() override;
};
Expand Down
1 change: 1 addition & 0 deletions src-ui/app/editor-impl/HasEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@
namespace scxt::ui::app
{
HasEditor::HasEditor(SCXTEditor *e) : editor(e) {}
HasEditor::HasEditor(HasEditor *e) : editor(e->editor) {}
} // namespace scxt::ui::app
2 changes: 1 addition & 1 deletion src-ui/app/editor-impl/SCXTEditorResponseHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,6 @@ void SCXTEditor::onMissingResolutionWorkItemList(

void SCXTEditor::onGroupTriggerConditions(scxt::engine::GroupTriggerConditions const &g)
{
SCLOG_ONCE("Implement: On Group Trigger Conditions");
editScreen->partSidebar->groupTriggerConditionChanged(g);
}
} // namespace scxt::ui::app
3 changes: 3 additions & 0 deletions src/engine/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ struct Engine : MoveableOnly<Engine>, SampleRateSupport
{
for (const auto &[gidx, group] : sst::cpputils::enumerate(*part))
{
if (!group->triggerConditions.value(*this, *group))
continue;

for (const auto &[zidx, zone] : sst::cpputils::enumerate(*group))
{
if (zone->mapping.keyboardRange.includes(key) &&
Expand Down
Loading
Loading