Skip to content

Commit

Permalink
More group trigger stuff
Browse files Browse the repository at this point in the history
- Macro and MIDI1CC triggers work
- Conjunction & only
- Active, Arfs, and a pattern for controls
  • Loading branch information
baconpaul committed Oct 9, 2024
1 parent bf42876 commit 9e56883
Show file tree
Hide file tree
Showing 13 changed files with 360 additions and 38 deletions.
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
184 changes: 174 additions & 10 deletions src-ui/app/edit-screen/components/GroupTriggersCard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,37 +28,184 @@
#include "GroupTriggersCard.h"
#include "sst/jucegui/components/ToggleButton.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 +216,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 +229,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 +268,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
4 changes: 4 additions & 0 deletions src-ui/app/edit-screen/components/GroupTriggersCard.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,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

0 comments on commit 9e56883

Please sign in to comment.