Skip to content

Commit a673ab7

Browse files
authored
Fixed nested scrolling in the MidiObject dialog on macOs #1972 (#2112)
1 parent c7bf5c5 commit a673ab7

File tree

3 files changed

+118
-70
lines changed

3 files changed

+118
-70
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
- Fixed nested scrolling in the MidiObject dialog on macOs https://github.com/GrandOrgue/grandorgue/issues/1972
12
- Increased the maximum number of user-defined temperaments to 999 https://github.com/GrandOrgue/grandorgue/issues/1982
23
# 3.15.4 (2024-12-20)
34
- Eliminated a MacOs debug alert when opening a settings dialog https://github.com/GrandOrgue/grandorgue/issues/2003

src/grandorgue/gui/dialogs/GOMidiListDialog.cpp

+96-51
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,60 @@
88
#include "GOMidiListDialog.h"
99

1010
#include <wx/button.h>
11-
#include <wx/listctrl.h>
1211
#include <wx/sizer.h>
1312

13+
#include "gui/size/GOAdditionalSizeKeeperProxy.h"
14+
#include "gui/wxcontrols/GOGrid.h"
1415
#include "midi/objects/GOMidiObject.h"
1516

1617
#include "GOEvent.h"
1718

19+
enum {
20+
ID_LIST = 200,
21+
ID_EDIT,
22+
ID_STATUS,
23+
ID_BUTTON,
24+
ID_BUTTON_LAST = ID_BUTTON + 2,
25+
};
26+
1827
BEGIN_EVENT_TABLE(GOMidiListDialog, GOSimpleDialog)
19-
EVT_LIST_ITEM_SELECTED(ID_LIST, GOMidiListDialog::OnObjectClick)
20-
EVT_LIST_ITEM_ACTIVATED(ID_LIST, GOMidiListDialog::OnObjectDoubleClick)
28+
EVT_GRID_CMD_SELECT_CELL(ID_LIST, GOMidiListDialog::OnObjectClick)
29+
EVT_GRID_CMD_CELL_LEFT_DCLICK(ID_LIST, GOMidiListDialog::OnObjectDoubleClick)
2130
EVT_BUTTON(ID_STATUS, GOMidiListDialog::OnStatus)
2231
EVT_BUTTON(ID_EDIT, GOMidiListDialog::OnEdit)
2332
EVT_COMMAND_RANGE(
2433
ID_BUTTON, ID_BUTTON_LAST, wxEVT_BUTTON, GOMidiListDialog::OnButton)
2534
END_EVENT_TABLE()
2635

36+
enum { GRID_COL_TYPE = 0, GRID_COL_ELEMENT };
37+
2738
GOMidiListDialog::GOMidiListDialog(
2839
GODocumentBase *doc,
2940
wxWindow *parent,
3041
GODialogSizeSet &dialogSizes,
31-
const std::vector<GOMidiObject *> &midi_elements)
42+
const std::vector<GOMidiObject *> &midiObjects)
3243
: GOSimpleDialog(
3344
parent,
3445
wxT("MIDI Objects"),
3546
_("MIDI Objects"),
3647
dialogSizes,
3748
wxEmptyString,
3849
0,
39-
wxOK | wxHELP),
40-
GOView(doc, this) {
50+
wxCLOSE | wxHELP),
51+
GOView(doc, this),
52+
r_MidiObjects(midiObjects) {
4153
wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
4254
topSizer->AddSpacer(5);
4355

44-
m_Objects = new wxListView(
45-
this,
46-
ID_LIST,
47-
wxDefaultPosition,
48-
wxSize(300, 600),
49-
wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_HRULES | wxLC_VRULES);
50-
m_Objects->InsertColumn(0, _("Type"));
51-
m_Objects->InsertColumn(1, _("Element"));
56+
m_Objects = new GOGrid(this, ID_LIST, wxDefaultPosition, wxSize(250, 200));
57+
m_Objects->CreateGrid(0, 2, wxGrid::wxGridSelectRows);
58+
m_Objects->HideRowLabels();
59+
m_Objects->EnableEditing(false);
60+
m_Objects->SetColLabelValue(GRID_COL_TYPE, _("Type"));
61+
m_Objects->SetColLabelValue(GRID_COL_ELEMENT, _("Element"));
62+
m_Objects->SetColSize(GRID_COL_TYPE, 100);
63+
m_Objects->SetColSize(GRID_COL_ELEMENT, 100);
64+
5265
topSizer->Add(m_Objects, 1, wxEXPAND | wxALL, 5);
5366

5467
wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
@@ -69,61 +82,93 @@ GOMidiListDialog::GOMidiListDialog(
6982
buttons->Add(m_Status);
7083
topSizer->Add(buttons, 0, wxALIGN_RIGHT | wxALL, 1);
7184

72-
for (unsigned i = 0; i < midi_elements.size(); i++) {
73-
GOMidiObject *obj = midi_elements[i];
85+
topSizer->AddSpacer(5);
86+
LayoutWithInnerSizer(topSizer);
87+
}
7488

75-
m_Objects->InsertItem(i, obj->GetMidiTypeName());
76-
m_Objects->SetItemPtrData(i, (wxUIntPtr)obj);
77-
m_Objects->SetItem(i, 1, obj->GetName());
78-
}
89+
static const wxString WX_GRID_MIDI_OBJECTS = wxT("GridMidiObjects");
7990

80-
m_Objects->SetColumnWidth(0, wxLIST_AUTOSIZE);
81-
m_Objects->SetColumnWidth(1, wxLIST_AUTOSIZE);
91+
void GOMidiListDialog::ApplyAdditionalSizes(
92+
const GOAdditionalSizeKeeper &sizeKeeper) {
93+
GOAdditionalSizeKeeperProxy proxyMidiObjects(
94+
const_cast<GOAdditionalSizeKeeper &>(sizeKeeper), WX_GRID_MIDI_OBJECTS);
8295

83-
topSizer->AddSpacer(5);
84-
LayoutWithInnerSizer(topSizer);
96+
m_Objects->ApplyColumnSizes(proxyMidiObjects);
97+
}
98+
99+
void GOMidiListDialog::CaptureAdditionalSizes(
100+
GOAdditionalSizeKeeper &sizeKeeper) const {
101+
GOAdditionalSizeKeeperProxy proxyMidiObjects(
102+
sizeKeeper, WX_GRID_MIDI_OBJECTS);
103+
104+
m_Objects->CaptureColumnSizes(proxyMidiObjects);
105+
}
106+
107+
bool GOMidiListDialog::TransferDataToWindow() {
108+
unsigned oldRowCnt = m_Objects->GetNumberRows();
109+
unsigned newRowCnt = r_MidiObjects.size();
110+
111+
if (oldRowCnt)
112+
m_Objects->DeleteRows(0, oldRowCnt);
113+
114+
m_Objects->AppendRows(newRowCnt);
115+
for (unsigned i = 0; i < newRowCnt; i++) {
116+
GOMidiObject *obj = r_MidiObjects[i];
117+
118+
m_Objects->SetCellValue(i, GRID_COL_TYPE, obj->GetMidiTypeName());
119+
m_Objects->SetCellValue(i, GRID_COL_ELEMENT, obj->GetName());
120+
}
121+
return true;
85122
}
86123

87-
GOMidiListDialog::~GOMidiListDialog() {}
124+
GOMidiObject *GOMidiListDialog::GetSelectedObject() const {
125+
return r_MidiObjects[m_Objects->GetGridCursorRow()];
126+
}
88127

89128
void GOMidiListDialog::OnButton(wxCommandEvent &event) {
90-
GOMidiObject *obj
91-
= (GOMidiObject *)m_Objects->GetItemData(m_Objects->GetFirstSelected());
129+
GOMidiObject *obj = GetSelectedObject();
92130
obj->TriggerElementActions(event.GetId() - ID_BUTTON);
93131
}
94132

133+
void GOMidiListDialog::OnObjectClick(wxGridEvent &event) {
134+
int index = event.GetRow();
135+
bool isAnySelected = index >= 0;
136+
137+
m_Edit->Enable(isAnySelected);
138+
m_Status->Enable(isAnySelected);
139+
if (isAnySelected) {
140+
m_Objects->SelectRow(index);
141+
GOMidiObject *obj = r_MidiObjects[index];
142+
std::vector<wxString> actions = obj->GetElementActions();
143+
144+
for (unsigned i = 0; i < m_Buttons.size(); i++)
145+
if (i < actions.size()) {
146+
m_Buttons[i]->SetLabel(actions[i]);
147+
m_Buttons[i]->Show();
148+
} else
149+
m_Buttons[i]->Hide();
150+
}
151+
Layout();
152+
event.StopPropagation();
153+
}
154+
155+
void GOMidiListDialog::OnObjectDoubleClick(wxGridEvent &event) {
156+
GOMidiObject *obj = GetSelectedObject();
157+
158+
obj->ShowConfigDialog();
159+
}
160+
95161
void GOMidiListDialog::OnStatus(wxCommandEvent &event) {
96-
GOMidiObject *obj
97-
= (GOMidiObject *)m_Objects->GetItemData(m_Objects->GetFirstSelected());
162+
GOMidiObject *obj = GetSelectedObject();
98163
wxString status = obj->GetElementStatus();
164+
99165
GOMessageBox(
100166
wxString::Format(_("Status: %s"), status),
101167
obj->GetMidiTypeName() + _(" ") + obj->GetName(),
102168
wxOK);
103169
}
104170

105-
void GOMidiListDialog::OnObjectClick(wxListEvent &event) {
106-
m_Edit->Enable();
107-
m_Status->Enable();
108-
GOMidiObject *obj
109-
= (GOMidiObject *)m_Objects->GetItemData(m_Objects->GetFirstSelected());
110-
std::vector<wxString> actions = obj->GetElementActions();
111-
for (unsigned i = 0; i < m_Buttons.size(); i++)
112-
if (i < actions.size()) {
113-
m_Buttons[i]->SetLabel(actions[i]);
114-
m_Buttons[i]->Show();
115-
} else
116-
m_Buttons[i]->Hide();
117-
Layout();
118-
}
119-
120-
void GOMidiListDialog::OnObjectDoubleClick(wxListEvent &event) {
121-
GOMidiObject *obj
122-
= (GOMidiObject *)m_Objects->GetItemData(m_Objects->GetFirstSelected());
123-
obj->ShowConfigDialog();
124-
}
125-
126171
void GOMidiListDialog::OnEdit(wxCommandEvent &event) {
127-
wxListEvent listevent;
172+
wxGridEvent listevent;
128173
OnObjectDoubleClick(listevent);
129174
}

src/grandorgue/gui/dialogs/GOMidiListDialog.h

+21-19
Original file line numberDiff line numberDiff line change
@@ -14,39 +14,41 @@
1414
#include "document-base/GOView.h"
1515

1616
class wxButton;
17-
class wxListEvent;
18-
class wxListView;
17+
class wxGridEvent;
1918

19+
class GOGrid;
2020
class GOMidiObject;
2121

2222
class GOMidiListDialog : public GOSimpleDialog, public GOView {
2323
private:
24-
wxListView *m_Objects;
24+
const std::vector<GOMidiObject *> &r_MidiObjects;
25+
26+
GOGrid *m_Objects;
2527
wxButton *m_Edit;
2628
wxButton *m_Status;
2729
std::vector<wxButton *> m_Buttons;
2830

29-
enum {
30-
ID_LIST = 200,
31-
ID_EDIT,
32-
ID_STATUS,
33-
ID_BUTTON,
34-
ID_BUTTON_LAST = ID_BUTTON + 2,
35-
};
36-
37-
void OnObjectClick(wxListEvent &event);
38-
void OnObjectDoubleClick(wxListEvent &event);
39-
void OnEdit(wxCommandEvent &event);
40-
void OnStatus(wxCommandEvent &event);
41-
void OnButton(wxCommandEvent &event);
42-
4331
public:
4432
GOMidiListDialog(
4533
GODocumentBase *doc,
4634
wxWindow *parent,
4735
GODialogSizeSet &dialogSizes,
48-
const std::vector<GOMidiObject *> &midi_elements);
49-
~GOMidiListDialog();
36+
const std::vector<GOMidiObject *> &midiObjects);
37+
38+
private:
39+
void ApplyAdditionalSizes(const GOAdditionalSizeKeeper &sizeKeeper) override;
40+
void CaptureAdditionalSizes(
41+
GOAdditionalSizeKeeper &sizeKeeper) const override;
42+
43+
bool TransferDataToWindow() override;
44+
45+
GOMidiObject *GetSelectedObject() const;
46+
47+
void OnObjectClick(wxGridEvent &event);
48+
void OnObjectDoubleClick(wxGridEvent &event);
49+
void OnEdit(wxCommandEvent &event);
50+
void OnStatus(wxCommandEvent &event);
51+
void OnButton(wxCommandEvent &event);
5052

5153
DECLARE_EVENT_TABLE()
5254
};

0 commit comments

Comments
 (0)