Skip to content

Commit 9d2cf72

Browse files
committed
Added support of "Couple Through" mode of Virtual Couplers GrandOrgue#1657
1 parent 4c842a1 commit 9d2cf72

7 files changed

+111
-28
lines changed

src/grandorgue/GOOrganController.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ void GOOrganController::ReadOrganFile(GOConfigReader &cfg) {
254254

255255
GOOrganModel::Load(cfg);
256256

257-
m_VirtualCouplers.Init(*this, cfg);
257+
m_VirtualCouplers.Load(*this, cfg);
258258

259259
GOOrganModel::LoadCmbButtons(cfg);
260260

@@ -825,6 +825,7 @@ bool GOOrganController::Export(const wxString &cmb) {
825825

826826
GOEventDistributor::Save(cfg);
827827
GetDialogSizeSet().Save(cfg);
828+
m_VirtualCouplers.Save(cfg);
828829

829830
wxString tmp_name = cmb + wxT(".new");
830831

src/grandorgue/GOVirtualCouplerController.cpp

+59-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright 2006 Milan Digital Audio LLC
3-
* Copyright 2009-2023 GrandOrgue contributors (see AUTHORS)
3+
* Copyright 2009-2024 GrandOrgue contributors (see AUTHORS)
44
* License GPL-2.0 or later
55
* (https://www.gnu.org/licenses/old-licenses/gpl-2.0.html).
66
*/
@@ -9,6 +9,8 @@
99

1010
#include <wx/intl.h>
1111

12+
#include "config/GOConfigWriter.h"
13+
#include "control/GOCallbackButtonControl.h"
1214
#include "model/GOCoupler.h"
1315
#include "model/GOManual.h"
1416
#include "model/GOOrganModel.h"
@@ -56,8 +58,8 @@ void GOVirtualCouplerController::Init(
5658
for (unsigned int dstManualN = organModel.GetFirstManualIndex();
5759
dstManualN < organModel.GetODFManualCount();
5860
dstManualN++) {
59-
ManualCouplerSet &manualCouplers
60-
= m_CouplerPtrs[make_key(srcManualN, dstManualN)];
61+
CouplerSetKey couplerSetKey = make_key(srcManualN, dstManualN);
62+
ManualCouplerSet &manualCouplers = m_CouplerPtrs[couplerSetKey];
6163

6264
load_coupler(
6365
organModel,
@@ -123,13 +125,67 @@ void GOVirtualCouplerController::Init(
123125
wxT("SetterManual%03dCoupler%03dMEL"),
124126
wxT("S%dM%dCM"),
125127
_("MEL"));
128+
129+
GOCallbackButtonControl *pCoupleThrough
130+
= new GOCallbackButtonControl(organModel, this, false, false);
131+
132+
pCoupleThrough->Init(
133+
cfg,
134+
wxString::Format(
135+
wxT("SetterManual%03dCoupler%03dThrough"), srcManualN, dstManualN),
136+
_("Couple Through"));
137+
m_CoupleThroughPtrs[couplerSetKey] = pCoupleThrough;
126138
}
127139
}
128140
}
129141

142+
static wxString WX_COOPLE_THROUGH = wxT("CoupleThrough");
143+
144+
void GOVirtualCouplerController::Load(
145+
GOOrganModel &organModel, GOConfigReader &cfg) {
146+
Init(organModel, cfg);
147+
for (auto e : m_CoupleThroughPtrs) {
148+
GOCallbackButtonControl *pCoupleThrough = e.second;
149+
bool isCoupleThrough = cfg.ReadBoolean(
150+
CMBSetting, pCoupleThrough->GetGroup(), WX_COOPLE_THROUGH, false, false);
151+
152+
pCoupleThrough->Set(isCoupleThrough);
153+
}
154+
}
155+
156+
void GOVirtualCouplerController::Save(GOConfigWriter &cfg) {
157+
for (auto e : m_CoupleThroughPtrs) {
158+
GOCallbackButtonControl *pCoupleThrough = e.second;
159+
160+
cfg.WriteBoolean(
161+
pCoupleThrough->GetGroup(),
162+
WX_COOPLE_THROUGH,
163+
pCoupleThrough->IsEngaged());
164+
}
165+
}
166+
130167
GOCoupler *GOVirtualCouplerController::GetCoupler(
131168
unsigned fromManual, unsigned toManual, CouplerType type) const {
132169
const auto iter = m_CouplerPtrs.find(make_key(fromManual, toManual));
133170

134171
return iter != m_CouplerPtrs.end() ? iter->second[type] : nullptr;
135172
}
173+
174+
GOButtonControl *GOVirtualCouplerController::GetCouplerThrough(
175+
unsigned fromManual, unsigned toManual) const {
176+
const auto iter = m_CoupleThroughPtrs.find(make_key(fromManual, toManual));
177+
178+
return iter != m_CoupleThroughPtrs.end() ? iter->second : nullptr;
179+
}
180+
181+
void GOVirtualCouplerController::ButtonStateChanged(
182+
GOButtonControl *button, bool newState) {
183+
for (auto e : m_CoupleThroughPtrs)
184+
if (e.second == button) {
185+
const CouplerSetKey &couplerSetKey = e.first;
186+
ManualCouplerSet &manualCouplers = m_CouplerPtrs[couplerSetKey];
187+
188+
for (auto pCoupler : manualCouplers)
189+
pCoupler->SetRecursive(newState);
190+
}
191+
}

src/grandorgue/GOVirtualCouplerController.h

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright 2006 Milan Digital Audio LLC
3-
* Copyright 2009-2023 GrandOrgue contributors (see AUTHORS)
3+
* Copyright 2009-2024 GrandOrgue contributors (see AUTHORS)
44
* License GPL-2.0 or later
55
* (https://www.gnu.org/licenses/old-licenses/gpl-2.0.html).
66
*/
@@ -12,11 +12,15 @@
1212
#include <utility>
1313
#include <vector>
1414

15+
#include "control/GOButtonCallback.h"
16+
17+
class GOCallbackButtonControl;
1518
class GOConfigReader;
19+
class GOConfigWriter;
1620
class GOCoupler;
1721
class GOOrganModel;
1822

19-
class GOVirtualCouplerController {
23+
class GOVirtualCouplerController : private GOButtonCallback {
2024
/**
2125
* Represents virtual couplers that do not exist vin ODF and are added
2226
* virtually by GrandOrgue. They are exposed on the GOGUICouplerPanel
@@ -39,18 +43,26 @@ class GOVirtualCouplerController {
3943

4044
private:
4145
std::map<CouplerSetKey, ManualCouplerSet> m_CouplerPtrs;
46+
std::map<CouplerSetKey, GOCallbackButtonControl *> m_CoupleThroughPtrs;
47+
48+
void ButtonStateChanged(GOButtonControl *button, bool newState) override;
4249

4350
public:
4451
// Create virtual couplers for each manual pairs with all CouplerType and add
4552
// them to the organ model
4653
void Init(GOOrganModel &organModel, GOConfigReader &cfg);
54+
void Load(GOOrganModel &organModel, GOConfigReader &cfg);
55+
void Save(GOConfigWriter &cfg);
4756

4857
// Clears the couplers
4958
void Cleanup() { m_CouplerPtrs.clear(); }
5059

5160
// Returns the coupler pointer
5261
GOCoupler *GetCoupler(
5362
unsigned fromManual, unsigned toManual, CouplerType type) const;
63+
64+
GOButtonControl *GetCouplerThrough(
65+
unsigned fromManual, unsigned toManual) const;
5466
};
5567

5668
#endif /* GOVIRTUALCOUPLERCONTROLLER_H */

src/grandorgue/gui/GOGUICouplerPanel.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright 2006 Milan Digital Audio LLC
3-
* Copyright 2009-2023 GrandOrgue contributors (see AUTHORS)
3+
* Copyright 2009-2024 GrandOrgue contributors (see AUTHORS)
44
* License GPL-2.0 or later
55
* (https://www.gnu.org/licenses/old-licenses/gpl-2.0.html).
66
*/
@@ -53,6 +53,7 @@ GOGUIPanel *GOGUICouplerPanel::CreateCouplerPanel(
5353
int x, y;
5454
GOManual *dest_manual = m_OrganController->GetManual(i);
5555
GOCoupler *coupler;
56+
GOButtonControl *pCouplerThough;
5657
GOGUIButton *button;
5758

5859
panel->GetLayoutEngine()->GetDrawstopBlitPosition(100 + i, 1, x, y);
@@ -120,6 +121,17 @@ GOGUIPanel *GOGUICouplerPanel::CreateCouplerPanel(
120121
100 + i);
121122
panel->AddControl(button);
122123
}
124+
125+
if ((pCouplerThough = r_VirtualCouplers.GetCouplerThrough(manual_nr, i))) {
126+
button = new GOGUIButton(panel, pCouplerThough, false);
127+
button->Init(
128+
cfg,
129+
wxString::Format(
130+
wxT("SetterManual%03dCoupler%03dThrough"), manual_nr, i),
131+
7,
132+
100 + i);
133+
panel->AddControl(button);
134+
}
123135
}
124136

125137
return panel;

src/grandorgue/gui/GOGUISetterDisplayMetrics.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright 2006 Milan Digital Audio LLC
3-
* Copyright 2009-2023 GrandOrgue contributors (see AUTHORS)
3+
* Copyright 2009-2024 GrandOrgue contributors (see AUTHORS)
44
* License GPL-2.0 or later
55
* (https://www.gnu.org/licenses/old-licenses/gpl-2.0.html).
66
*/
@@ -50,11 +50,11 @@ GOGUISetterDisplayMetrics::GOGUISetterDisplayMetrics(
5050
break;
5151

5252
case GOGUI_SETTER_COUPLER:
53-
x_size = 500;
53+
x_size = 600;
5454
y_size = 20 + 80 * organController->GetODFManualCount();
5555
drawstop_rows = organController->GetODFManualCount();
56-
drawstop_cols = 6;
57-
button_cols = 10;
56+
drawstop_cols = 7;
57+
button_cols = 0;
5858
button_rows = 0;
5959
break;
6060

src/grandorgue/model/GOCoupler.cpp

+12-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright 2006 Milan Digital Audio LLC
3-
* Copyright 2009-2023 GrandOrgue contributors (see AUTHORS)
3+
* Copyright 2009-2024 GrandOrgue contributors (see AUTHORS)
44
* License GPL-2.0 or later
55
* (https://www.gnu.org/licenses/old-licenses/gpl-2.0.html).
66
*/
@@ -62,6 +62,14 @@ void GOCoupler::PreparePlayback() {
6262
src->SetUnisonOff(true);
6363
}
6464

65+
void GOCoupler::SetRecursive(bool isRecursive) {
66+
m_CoupleToSubsequentUnisonIntermanualCouplers = isRecursive;
67+
m_CoupleToSubsequentUpwardIntermanualCouplers = isRecursive;
68+
m_CoupleToSubsequentDownwardIntermanualCouplers = isRecursive;
69+
m_CoupleToSubsequentUpwardIntramanualCouplers = isRecursive;
70+
m_CoupleToSubsequentDownwardIntramanualCouplers = isRecursive;
71+
}
72+
6573
const struct IniFileEnumEntry GOCoupler::m_coupler_types[] = {
6674
{wxT("Normal"), COUPLER_NORMAL},
6775
{wxT("Bass"), COUPLER_BASS},
@@ -80,11 +88,7 @@ void GOCoupler::Init(
8088
m_UnisonOff = unison_off;
8189
m_DestinationManual = dest_manual;
8290
m_DestinationKeyshift = keyshift;
83-
m_CoupleToSubsequentUnisonIntermanualCouplers = recursive;
84-
m_CoupleToSubsequentUpwardIntermanualCouplers = recursive;
85-
m_CoupleToSubsequentDownwardIntermanualCouplers = recursive;
86-
m_CoupleToSubsequentUpwardIntramanualCouplers = recursive;
87-
m_CoupleToSubsequentDownwardIntramanualCouplers = recursive;
91+
SetRecursive(recursive);
8892
GODrawstop::Init(cfg, group, name);
8993

9094
m_CouplerType = coupler_type;
@@ -110,11 +114,7 @@ void GOCoupler::Load(GOConfigReader &cfg, wxString group) {
110114
m_DestinationKeyshift = cfg.ReadInteger(
111115
ODFSetting, group, wxT("DestinationKeyshift"), -24, 24, !m_UnisonOff, 0);
112116
if (m_UnisonOff) {
113-
m_CoupleToSubsequentUnisonIntermanualCouplers = false;
114-
m_CoupleToSubsequentUpwardIntermanualCouplers = false;
115-
m_CoupleToSubsequentDownwardIntermanualCouplers = false;
116-
m_CoupleToSubsequentUpwardIntramanualCouplers = false;
117-
m_CoupleToSubsequentDownwardIntramanualCouplers = false;
117+
SetRecursive(false);
118118
m_CouplerType = COUPLER_NORMAL;
119119
m_FirstMidiNote = 0;
120120
m_NumberOfKeys = 127;
@@ -164,11 +164,7 @@ void GOCoupler::Load(GOConfigReader &cfg, wxString group) {
164164
false,
165165
COUPLER_NORMAL);
166166
if (m_CouplerType == COUPLER_BASS || m_CouplerType == COUPLER_MELODY) {
167-
m_CoupleToSubsequentUnisonIntermanualCouplers = false;
168-
m_CoupleToSubsequentUpwardIntermanualCouplers = false;
169-
m_CoupleToSubsequentDownwardIntermanualCouplers = false;
170-
m_CoupleToSubsequentUpwardIntramanualCouplers = false;
171-
m_CoupleToSubsequentDownwardIntramanualCouplers = false;
167+
SetRecursive(false);
172168
if (!r_OrganModel.GetConfig().ODFCheck()) {
173169
cfg.ReadBoolean(
174170
ODFSetting,

src/grandorgue/model/GOCoupler.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright 2006 Milan Digital Audio LLC
3-
* Copyright 2009-2023 GrandOrgue contributors (see AUTHORS)
3+
* Copyright 2009-2024 GrandOrgue contributors (see AUTHORS)
44
* License GPL-2.0 or later
55
* (https://www.gnu.org/licenses/old-licenses/gpl-2.0.html).
66
*/
@@ -56,6 +56,12 @@ class GOCoupler : public GODrawstop {
5656

5757
public:
5858
GOCoupler(GOOrganModel &organModel, unsigned sourceManual);
59+
60+
bool IsRecursive() const {
61+
return m_CoupleToSubsequentUnisonIntermanualCouplers;
62+
}
63+
void SetRecursive(bool isRecursive);
64+
5965
void Init(
6066
GOConfigReader &cfg,
6167
wxString group,

0 commit comments

Comments
 (0)