Skip to content

Commit 99e31ed

Browse files
Add sequencer track solo button
1 parent 6a611fd commit 99e31ed

14 files changed

+184
-60
lines changed

src/audioCore/graph/SeqSourceProcessor.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ SeqSourceProcessor::SeqSourceProcessor(const juce::AudioChannelSet& type)
5555
}
5656

5757
SeqSourceProcessor::~SeqSourceProcessor() {
58+
this->setSolo(false);
5859
this->releaseAudio();
5960
this->releaseMIDI();
6061
}
@@ -544,7 +545,7 @@ bool SeqSourceProcessor::getMute() const {
544545
}
545546

546547
void SeqSourceProcessor::setSolo(bool solo) {
547-
bool shouldChange = (this->isSolo == solo);
548+
bool shouldChange = (this->isSolo != solo);
548549

549550
this->isSolo = solo;
550551

src/ui/component/sequencer/SeqTrackComponent.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ SeqTrackComponent::SeqTrackComponent(
4040
this->muteButton = std::make_unique<SeqTrackMuteComponent>();
4141
this->addChildComponent(this->muteButton.get());
4242

43+
/** Solo Button */
44+
this->soloButton = std::make_unique<SeqTrackSoloComponent>();
45+
this->addChildComponent(this->soloButton.get());
46+
4347
/** Input Monitoring Button */
4448
this->inputMonitoringButton = std::make_unique<SeqTrackInputMonitoringComponent>();
4549
this->addChildComponent(this->inputMonitoringButton.get());
@@ -171,6 +175,7 @@ void SeqTrackComponent::updateBlock(int blockIndex) {
171175

172176
void SeqTrackComponent::updateMuteSolo() {
173177
this->muteButton->update(this->index);
178+
this->soloButton->update(this->index);
174179
}
175180

176181
void SeqTrackComponent::updateInputMonitoring() {
@@ -327,9 +332,16 @@ void SeqTrackComponent::resized() {
327332
this->muteButton->setBounds(muteRect);
328333
this->muteButton->setVisible(isIOLineShown);
329334

335+
/** Solo Button */
336+
juce::Rectangle<int> soloRect(
337+
muteRect.getRight() + buttonSplitWidth, inputMonitoringRect.getY(),
338+
ioLineHeight, ioLineHeight);
339+
this->soloButton->setBounds(soloRect);
340+
this->soloButton->setVisible(isIOLineShown);
341+
330342
/** MIDI Output */
331343
juce::Rectangle<int> midiOutputRect(
332-
muteRect.getRight() + buttonSplitWidth, inputMonitoringRect.getY(),
344+
soloRect.getRight() + buttonSplitWidth, inputMonitoringRect.getY(),
333345
ioLineHeight, ioLineHeight);
334346
this->midiOutput->setBounds(midiOutputRect);
335347
this->midiOutput->setVisible(isIOLineShown);

src/ui/component/sequencer/SeqTrackComponent.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <JuceHeader.h>
44
#include "SeqTrackMuteComponent.h"
5+
#include "SeqTrackSoloComponent.h"
56
#include "SeqTrackInputMonitoringComponent.h"
67
#include "SeqTrackRecComponent.h"
78
#include "SeqTrackIOComponent.h"
@@ -78,6 +79,7 @@ class SeqTrackComponent final
7879

7980
std::unique_ptr<juce::TextButton> trackName = nullptr;
8081
std::unique_ptr<SeqTrackMuteComponent> muteButton = nullptr;
82+
std::unique_ptr<SeqTrackSoloComponent> soloButton = nullptr;
8183
std::unique_ptr<SeqTrackInputMonitoringComponent> inputMonitoringButton = nullptr;
8284
std::unique_ptr<SeqTrackRecComponent> recButton = nullptr;
8385

src/ui/component/sequencer/SeqTrackMuteComponent.cpp

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void SeqTrackMuteComponent::mouseUp(const juce::MouseEvent& event) {
8484
this->changeMute();
8585
}
8686
else if (event.mods.isRightButtonDown()) {
87-
this->showMenu();
87+
this->changeMute();
8888
}
8989
}
9090
}
@@ -102,39 +102,3 @@ void SeqTrackMuteComponent::update(int index) {
102102
void SeqTrackMuteComponent::changeMute() {
103103
CoreActions::setSeqMute(this->index, !(this->mute));
104104
}
105-
106-
enum MixerMuteActionType {
107-
Mute = 1, Solo, MuteAll, UnmuteAll
108-
};
109-
110-
void SeqTrackMuteComponent::showMenu() {
111-
auto menu = this->createMenu();
112-
int result = menu.show();
113-
114-
switch (result) {
115-
case MixerMuteActionType::Mute:
116-
this->changeMute();
117-
break;
118-
case MixerMuteActionType::Solo:
119-
CoreActions::setSeqSolo(this->index);
120-
break;
121-
case MixerMuteActionType::MuteAll:
122-
CoreActions::setSeqMuteAll(true);
123-
break;
124-
case MixerMuteActionType::UnmuteAll:
125-
CoreActions::setSeqMuteAll(false);
126-
break;
127-
}
128-
}
129-
130-
juce::PopupMenu SeqTrackMuteComponent::createMenu() const {
131-
juce::PopupMenu menu;
132-
133-
menu.addItem(MixerMuteActionType::Mute, TRANS("Mute"), true, this->mute);
134-
menu.addItem(MixerMuteActionType::Solo, TRANS("Solo"));
135-
menu.addSeparator();
136-
menu.addItem(MixerMuteActionType::MuteAll, TRANS("Mute All"));
137-
menu.addItem(MixerMuteActionType::UnmuteAll, TRANS("Unmute All"));
138-
139-
return menu;
140-
}

src/ui/component/sequencer/SeqTrackMuteComponent.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ class SeqTrackMuteComponent final
2222
bool equivalentMute = false;
2323

2424
void changeMute();
25-
void showMenu();
26-
27-
juce::PopupMenu createMenu() const;
2825

2926
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SeqTrackMuteComponent)
3027
};
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include "SeqTrackSoloComponent.h"
2+
#include "../../lookAndFeel/LookAndFeelFactory.h"
3+
#include "../../misc/CoreActions.h"
4+
#include "../../Utils.h"
5+
#include "../../../audioCore/AC_API.h"
6+
7+
SeqTrackSoloComponent::SeqTrackSoloComponent() {
8+
this->setLookAndFeel(
9+
LookAndFeelFactory::getInstance()->getLAFFor(LookAndFeelFactory::SoloButton));
10+
}
11+
12+
void SeqTrackSoloComponent::paint(juce::Graphics& g) {
13+
/** Size */
14+
auto screenSize = utils::getScreenSize(this);
15+
float lineThickness = screenSize.getHeight() * 0.001;
16+
17+
int buttonWidth = std::min(this->getWidth(), this->getHeight()) - lineThickness;
18+
int buttonHeight = buttonWidth;
19+
20+
float textFontHeight = buttonWidth * 0.7;
21+
22+
/** Color */
23+
auto& laf = this->getLookAndFeel();
24+
juce::Colour backgroundColor = laf.findColour(this->solo
25+
? juce::TextButton::ColourIds::buttonOnColourId
26+
: juce::TextButton::ColourIds::buttonColourId);
27+
juce::Colour textColor = laf.findColour(this->solo
28+
? juce::TextButton::ColourIds::textColourOnId
29+
: juce::TextButton::ColourIds::textColourOffId);
30+
31+
/** Font */
32+
juce::Font textFont(juce::FontOptions{ textFontHeight });
33+
34+
/** Button */
35+
juce::Rectangle<float> buttonRect(
36+
this->getWidth() / 2.f - buttonWidth / 2.f,
37+
this->getHeight() / 2.f - buttonHeight / 2.f,
38+
buttonWidth, buttonHeight);
39+
g.setColour(backgroundColor);
40+
g.fillRect(buttonRect);
41+
42+
g.setColour(textColor);
43+
g.drawRect(buttonRect, lineThickness);
44+
45+
g.setFont(textFont);
46+
g.drawFittedText("S", buttonRect.toNearestInt(),
47+
juce::Justification::centred, 1, 0.f);
48+
}
49+
50+
void SeqTrackSoloComponent::mouseDrag(const juce::MouseEvent& event) {
51+
this->mouseMove(event);
52+
}
53+
54+
void SeqTrackSoloComponent::mouseMove(const juce::MouseEvent& event) {
55+
/** Size */
56+
auto screenSize = utils::getScreenSize(this);
57+
float lineThickness = screenSize.getHeight() * 0.001;
58+
int buttonWidth = std::min(this->getWidth(), this->getHeight()) - lineThickness;
59+
int buttonHeight = buttonWidth;
60+
juce::Rectangle<float> buttonRect(
61+
this->getWidth() / 2.f - buttonWidth / 2.f,
62+
this->getHeight() / 2.f - buttonHeight / 2.f,
63+
buttonWidth, buttonHeight);
64+
65+
/** Cursor */
66+
this->setMouseCursor(buttonRect.contains(event.position)
67+
? juce::MouseCursor::PointingHandCursor
68+
: juce::MouseCursor::NormalCursor);
69+
}
70+
71+
void SeqTrackSoloComponent::mouseUp(const juce::MouseEvent& event) {
72+
/** Size */
73+
auto screenSize = utils::getScreenSize(this);
74+
float lineThickness = screenSize.getHeight() * 0.001;
75+
int buttonWidth = std::min(this->getWidth(), this->getHeight()) - lineThickness;
76+
int buttonHeight = buttonWidth;
77+
juce::Rectangle<float> buttonRect(
78+
this->getWidth() / 2.f - buttonWidth / 2.f,
79+
this->getHeight() / 2.f - buttonHeight / 2.f,
80+
buttonWidth, buttonHeight);
81+
82+
if (buttonRect.contains(event.position)) {
83+
if (event.mods.isLeftButtonDown()) {
84+
this->changeSolo();
85+
}
86+
else if (event.mods.isRightButtonDown()) {
87+
this->changeSolo();
88+
}
89+
}
90+
}
91+
92+
void SeqTrackSoloComponent::update(int index) {
93+
this->index = index;
94+
if (index > -1) {
95+
this->solo = quickAPI::getSeqTrackSolo(index);
96+
97+
this->repaint();
98+
}
99+
}
100+
101+
void SeqTrackSoloComponent::changeSolo() {
102+
CoreActions::setSeqSolo(this->index, !(this->solo));
103+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#include <JuceHeader.h>
4+
5+
class SeqTrackSoloComponent final
6+
: public juce::Component,
7+
public juce::SettableTooltipClient {
8+
public:
9+
SeqTrackSoloComponent();
10+
11+
void paint(juce::Graphics& g) override;
12+
13+
void mouseDrag(const juce::MouseEvent& event) override;
14+
void mouseMove(const juce::MouseEvent& event) override;
15+
void mouseUp(const juce::MouseEvent& event) override;
16+
17+
void update(int index);
18+
19+
private:
20+
int index = -1;
21+
bool solo = false;
22+
23+
void changeSolo();
24+
25+
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SeqTrackSoloComponent)
26+
};

src/ui/component/sequencer/SeqView.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ void SeqView::TrackList::updateBlock(int track, int index) {
5050
}
5151
}
5252

53-
void SeqView::TrackList::updateMuteSolo(int index) {
54-
if (index >= 0 && index < this->list.size()) {
55-
this->list[index]->updateMuteSolo();
53+
void SeqView::TrackList::updateMuteSolo(int /*index*/) {
54+
for (auto i : this->list) {
55+
i->updateMuteSolo();
5656
}
5757
}
5858

src/ui/lookAndFeel/LookAndFeelFactory.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "mixer/SideChainLookAndFeel.h"
1818
#include "mixer/LevelMeterLookAndFeel.h"
1919
#include "base/MuteButtonLookAndFeel.h"
20+
#include "base/SoloButtonLookAndFeel.h"
2021
#include "base/RecButtonLookAndFeel.h"
2122
#include "mixer/EffectLookAndFeel.h"
2223
#include "sequencer/SeqLookAndFeel.h"
@@ -85,6 +86,7 @@ void LookAndFeelFactory::initialise() {
8586
new SideChainLookAndFeel{},
8687
new LevelMeterLookAndFeel{},
8788
new MuteButtonLookAndFeel{},
89+
new SoloButtonLookAndFeel{},
8890
new RecButtonLookAndFeel{},
8991
new EffectLookAndFeel{},
9092
new SeqLookAndFeel{},

src/ui/lookAndFeel/LookAndFeelFactory.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class LookAndFeelFactory final : private juce::DeletedAtShutdown {
1313
ToolBar, MainMenu, SysStatus, Time, Controller, Tools,
1414
Message, MessageView, PluginView, PluginEditor, ChannelLink,
1515
Mixer, Scroller, ColorEditor, SideChain, LevelMeter,
16-
MuteButton, RecButton, Effect, Seq, TimeRuler, SeqTrack,
16+
MuteButton, SoloButton, RecButton, Effect, Seq, TimeRuler, SeqTrack,
1717
SeqTrackName, InstrName, SeqBlock, Editor, EditorSwitchBar,
1818
Piano, MidiContent, InputMonitoringButton,
1919

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include "SoloButtonLookAndFeel.h"
2+
#include "../../misc/ColorMap.h"
3+
4+
SoloButtonLookAndFeel::SoloButtonLookAndFeel()
5+
: MainLookAndFeel() {
6+
/** Button */
7+
this->setColour(juce::TextButton::ColourIds::buttonColourId,
8+
ColorMap::getInstance()->get("ThemeColorB2"));
9+
this->setColour(juce::TextButton::ColourIds::buttonOnColourId,
10+
juce::Colours::red.withAlpha(0.6f));
11+
this->setColour(juce::TextButton::ColourIds::textColourOffId,
12+
ColorMap::getInstance()->get("ThemeColorB8"));
13+
this->setColour(juce::TextButton::ColourIds::textColourOnId,
14+
ColorMap::getInstance()->get("ThemeColorB10"));
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
3+
#include <JuceHeader.h>
4+
#include "../MainLookAndFeel.h"
5+
6+
class SoloButtonLookAndFeel : public MainLookAndFeel {
7+
public:
8+
SoloButtonLookAndFeel();
9+
10+
private:
11+
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SoloButtonLookAndFeel)
12+
};

src/ui/misc/CoreActions.cpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -427,18 +427,9 @@ void CoreActions::setSeqMute(int index, bool mute) {
427427
ActionDispatcher::getInstance()->dispatch(std::move(action));
428428
}
429429

430-
void CoreActions::setSeqSolo(int index) {
431-
int trackNum = quickAPI::getSeqTrackNum();
432-
for (int i = 0; i < trackNum; i++) {
433-
CoreActions::setSeqMute(i, i != index);
434-
}
435-
}
436-
437-
void CoreActions::setSeqMuteAll(bool mute) {
438-
int trackNum = quickAPI::getSeqTrackNum();
439-
for (int i = 0; i < trackNum; i++) {
440-
CoreActions::setSeqMute(i, mute);
441-
}
430+
void CoreActions::setSeqSolo(int index, bool solo) {
431+
auto action = std::unique_ptr<ActionBase>(new ActionSetSequencerTrackSolo{ index, solo });
432+
ActionDispatcher::getInstance()->dispatch(std::move(action));
442433
}
443434

444435
void CoreActions::setSeqInputMonitoring(int index, bool inputMonitoring) {

src/ui/misc/CoreActions.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,7 @@ class CoreActions final {
9090
static void setSeqMIDIOutputToMixer(int index, int mixerIndex, bool output);
9191
static void setSeqAudioOutputToMixer(int index, int channel, int mixerIndex, int dstChannel, bool output);
9292
static void setSeqMute(int index, bool mute);
93-
static void setSeqSolo(int index);
94-
static void setSeqMuteAll(bool mute);
93+
static void setSeqSolo(int index, bool solo);
9594
static void setSeqInputMonitoring(int index, bool inputMonitoring);
9695
static void setSeqRec(int index, quickAPI::RecordState rec);
9796
static void setSeqMIDITrack(int index, int midiTrack);

0 commit comments

Comments
 (0)