Skip to content

Commit fef00a2

Browse files
author
larspalo
committed
Implemented possibility to move stops by drag and drop both within manuals and to other manuals.
1 parent ae6818a commit fef00a2

File tree

5 files changed

+282
-13
lines changed

5 files changed

+282
-13
lines changed

src/GOODFFrame.cpp

Lines changed: 134 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include "Windchestgroup.h"
3131
#include "OrganFileParser.h"
3232
#include "CopyElementAttributesDialog.h"
33+
#include <vector>
34+
#include <algorithm>
3335

3436
// Event table
3537
BEGIN_EVENT_TABLE(GOODFFrame, wxFrame)
@@ -1287,12 +1289,14 @@ void GOODFFrame::OnOrganTreeRightClicked(wxTreeEvent& event) {
12871289
}
12881290

12891291
void GOODFFrame::OnOrganTreeLeftDrag(wxTreeEvent& event) {
1290-
// Only allow dragging if item is a switch, manual, windchestgroup, rank
1292+
// Only allow dragging if item is a switch, manual, windchestgroup, rank, stop
12911293
wxTreeItemId sourceItem = event.GetItem();
1292-
if ((m_organTreeCtrl->GetItemParent(sourceItem) == tree_switches && m_organTreeCtrl->GetChildrenCount(tree_switches, false) > 1) ||
1293-
(m_organTreeCtrl->GetItemParent(sourceItem) == tree_manuals && m_organTreeCtrl->GetChildrenCount(tree_manuals, false) > 1) ||
1294-
(m_organTreeCtrl->GetItemParent(sourceItem) == tree_windchestgrps && m_organTreeCtrl->GetChildrenCount(tree_windchestgrps, false) > 1) ||
1295-
(m_organTreeCtrl->GetItemParent(sourceItem) == tree_ranks && m_organTreeCtrl->GetChildrenCount(tree_ranks, false) > 1)
1294+
wxTreeItemId sourceParent = m_organTreeCtrl->GetItemParent(sourceItem);
1295+
if ((sourceParent == tree_switches && m_organTreeCtrl->GetChildrenCount(tree_switches, false) > 1) ||
1296+
(sourceParent == tree_manuals && m_organTreeCtrl->GetChildrenCount(tree_manuals, false) > 1) ||
1297+
(sourceParent == tree_windchestgrps && m_organTreeCtrl->GetChildrenCount(tree_windchestgrps, false) > 1) ||
1298+
(sourceParent == tree_ranks && m_organTreeCtrl->GetChildrenCount(tree_ranks, false) > 1) ||
1299+
(m_organTreeCtrl->GetItemText(sourceParent) == wxT("Stops") && m_organTreeCtrl->GetItemText(m_organTreeCtrl->GetNextSibling(sourceParent)) == wxT("Couplers"))
12961300
) {
12971301
m_draggedItem = sourceItem;
12981302
event.Allow();
@@ -1302,9 +1306,13 @@ void GOODFFrame::OnOrganTreeLeftDrag(wxTreeEvent& event) {
13021306
void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
13031307
wxTreeItemId srcItem = m_draggedItem;
13041308
wxTreeItemId dstItem = event.GetItem();
1309+
wxTreeItemId srcParent = m_organTreeCtrl->GetItemParent(srcItem);
1310+
wxTreeItemId dstParent = m_organTreeCtrl->GetItemParent(dstItem);
1311+
wxTreeItemId srcGrandParent = m_organTreeCtrl->GetItemParent(srcParent);
1312+
wxTreeItemId dstGrandParent = m_organTreeCtrl->GetItemParent(dstParent);
13051313
m_draggedItem = (wxTreeItemId) 0l;
13061314

1307-
if (m_organTreeCtrl->GetItemParent(dstItem) == tree_switches && m_organTreeCtrl->GetItemParent(srcItem) == tree_switches) {
1315+
if (dstParent == tree_switches && srcParent == tree_switches) {
13081316
// we drop it after target switch but first check if the move really should happen
13091317
if (m_organTreeCtrl->GetNextSibling(dstItem) == srcItem) {
13101318
return;
@@ -1334,7 +1342,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
13341342
m_organTreeCtrl->Delete(srcItem);
13351343
m_organ->moveSwitch(sourceIndex, targetIndex);
13361344
m_organTreeCtrl->SelectItem(newPos);
1337-
} else if (dstItem == tree_switches && m_organTreeCtrl->GetItemParent(srcItem) == tree_switches) {
1345+
} else if (dstItem == tree_switches && srcParent == tree_switches) {
13381346
// we make it first child
13391347
int sourceIndex = 0;
13401348
int numChildrens = m_organTreeCtrl->GetChildrenCount(tree_switches, false);
@@ -1354,7 +1362,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
13541362
m_organTreeCtrl->Delete(srcItem);
13551363
m_organ->moveSwitch(sourceIndex, 0);
13561364
m_organTreeCtrl->SelectItem(newPos);
1357-
} else if (m_organTreeCtrl->GetItemParent(dstItem) == tree_manuals && m_organTreeCtrl->GetItemParent(srcItem) == tree_manuals) {
1365+
} else if (dstParent == tree_manuals && srcParent == tree_manuals) {
13581366
// we drop it after target manual but first check if the move really should happen
13591367
if (m_organTreeCtrl->GetNextSibling(dstItem) == srcItem) {
13601368
return;
@@ -1427,7 +1435,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
14271435
m_organTreeCtrl->Delete(srcItem);
14281436
m_organ->moveManual(sourceIndex, targetIndex);
14291437
m_organTreeCtrl->SelectItem(newPos);
1430-
} else if (dstItem == tree_manuals && m_organTreeCtrl->GetItemParent(srcItem) == tree_manuals) {
1438+
} else if (dstItem == tree_manuals && srcParent == tree_manuals) {
14311439
// we make it first child
14321440
int sourceIndex = 0;
14331441
int numChildrens = m_organTreeCtrl->GetChildrenCount(tree_manuals, false);
@@ -1490,7 +1498,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
14901498
m_organTreeCtrl->Delete(srcItem);
14911499
m_organ->moveManual(sourceIndex, 0);
14921500
m_organTreeCtrl->SelectItem(newPos);
1493-
} else if (m_organTreeCtrl->GetItemParent(dstItem) == tree_windchestgrps && m_organTreeCtrl->GetItemParent(srcItem) == tree_windchestgrps) {
1501+
} else if (dstParent == tree_windchestgrps && srcParent == tree_windchestgrps) {
14941502
// we drop it after target windchestgroup but first check if the move really should happen
14951503
if (m_organTreeCtrl->GetNextSibling(dstItem) == srcItem) {
14961504
return;
@@ -1520,7 +1528,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
15201528
m_organTreeCtrl->Delete(srcItem);
15211529
m_organ->moveWindchestgroup(sourceIndex, targetIndex);
15221530
m_organTreeCtrl->SelectItem(newPos);
1523-
} else if (dstItem == tree_windchestgrps && m_organTreeCtrl->GetItemParent(srcItem) == tree_windchestgrps) {
1531+
} else if (dstItem == tree_windchestgrps && srcParent == tree_windchestgrps) {
15241532
// we make it first child
15251533
int sourceIndex = 0;
15261534
int numChildrens = m_organTreeCtrl->GetChildrenCount(tree_windchestgrps, false);
@@ -1541,7 +1549,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
15411549
m_organTreeCtrl->Delete(srcItem);
15421550
m_organ->moveWindchestgroup(sourceIndex, 0);
15431551
m_organTreeCtrl->SelectItem(newPos);
1544-
} else if (m_organTreeCtrl->GetItemParent(dstItem) == tree_ranks && m_organTreeCtrl->GetItemParent(srcItem) == tree_ranks) {
1552+
} else if (dstParent == tree_ranks && srcParent == tree_ranks) {
15451553
// we drop it after target rank but first check if the move really should happen
15461554
if (m_organTreeCtrl->GetNextSibling(dstItem) == srcItem) {
15471555
return;
@@ -1571,7 +1579,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
15711579
m_organTreeCtrl->Delete(srcItem);
15721580
m_organ->moveRank(sourceIndex, targetIndex);
15731581
m_organTreeCtrl->SelectItem(newPos);
1574-
} else if (dstItem == tree_ranks && m_organTreeCtrl->GetItemParent(srcItem) == tree_ranks) {
1582+
} else if (dstItem == tree_ranks && srcParent == tree_ranks) {
15751583
// we make it first child
15761584
int sourceIndex = 0;
15771585
int numChildrens = m_organTreeCtrl->GetChildrenCount(tree_ranks, false);
@@ -1592,6 +1600,119 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
15921600
m_organTreeCtrl->Delete(srcItem);
15931601
m_organ->moveRank(sourceIndex, 0);
15941602
m_organTreeCtrl->SelectItem(newPos);
1603+
} else if (m_organTreeCtrl->GetItemText(srcParent) == wxT("Stops") && m_organTreeCtrl->GetItemText(m_organTreeCtrl->GetNextSibling(srcParent)) == wxT("Couplers")) {
1604+
// The source item is certainly a stop, allowed drop destinations are another stop, the stop main category and a manual
1605+
std::vector<wxTreeItemId> manualsInTree;
1606+
int nbrManuals = m_organTreeCtrl->GetChildrenCount(tree_manuals, false);
1607+
wxTreeItemIdValue cookie;
1608+
for (int i = 0; i < nbrManuals; i++) {
1609+
wxTreeItemId currentMan;
1610+
if (i == 0)
1611+
currentMan = m_organTreeCtrl->GetFirstChild(tree_manuals, cookie);
1612+
else
1613+
currentMan = m_organTreeCtrl->GetNextChild(tree_manuals, cookie);
1614+
1615+
manualsInTree.push_back(currentMan);
1616+
}
1617+
1618+
// Get what index the source stop had to begin with
1619+
int srcStopIdx = -1;
1620+
int nbrSrcStops = m_organTreeCtrl->GetChildrenCount(srcParent, false);
1621+
wxTreeItemIdValue srcCookie;
1622+
for (int i = 0; i < nbrSrcStops; i++) {
1623+
wxTreeItemId currentStop;
1624+
if (i == 0)
1625+
currentStop = m_organTreeCtrl->GetFirstChild(srcParent, srcCookie);
1626+
else
1627+
currentStop = m_organTreeCtrl->GetNextChild(srcParent, srcCookie);
1628+
1629+
if (currentStop == srcItem) {
1630+
srcStopIdx = i;
1631+
break;
1632+
}
1633+
}
1634+
1635+
if (m_organTreeCtrl->GetItemText(dstParent) == wxT("Stops") && m_organTreeCtrl->GetItemText(m_organTreeCtrl->GetNextSibling(dstParent)) == wxT("Couplers")) {
1636+
// The destination item is another stop, should the move proceed?
1637+
if (m_organTreeCtrl->GetNextSibling(dstItem) == srcItem) {
1638+
return;
1639+
}
1640+
1641+
// Get what manual each of the stops belongs to
1642+
int srcManualIdx = -1;
1643+
int dstManualIdx = -1;
1644+
for (unsigned i = 0; i < manualsInTree.size(); i++) {
1645+
if (m_organTreeCtrl->GetItemText(manualsInTree[i]) == m_organTreeCtrl->GetItemText(srcGrandParent))
1646+
srcManualIdx = i;
1647+
if (m_organTreeCtrl->GetItemText(manualsInTree[i]) == m_organTreeCtrl->GetItemText(dstGrandParent))
1648+
dstManualIdx = i;
1649+
}
1650+
1651+
// Get what index the destination stop has
1652+
int dstStopIdx = -1;
1653+
int nbrDstStops = m_organTreeCtrl->GetChildrenCount(dstParent, false);
1654+
wxTreeItemIdValue dstCookie;
1655+
for (int i = 0; i < nbrDstStops; i++) {
1656+
wxTreeItemId currentStop;
1657+
if (i == 0)
1658+
currentStop = m_organTreeCtrl->GetFirstChild(dstParent, dstCookie);
1659+
else
1660+
currentStop = m_organTreeCtrl->GetNextChild(dstParent, dstCookie);
1661+
1662+
if (currentStop == dstItem) {
1663+
dstStopIdx = i;
1664+
break;
1665+
}
1666+
}
1667+
if (dstStopIdx < nbrDstStops) {
1668+
dstStopIdx += 1;
1669+
}
1670+
1671+
// Now we should know the source and destination index of respective manual and stop
1672+
if (m_organ->moveStop(srcManualIdx, srcStopIdx, dstManualIdx, dstStopIdx)) {
1673+
// The move succeeded in the organ so now it's just to take care of it in tree
1674+
wxTreeItemId newPos = m_organTreeCtrl->InsertItem(dstParent, dstItem, m_organTreeCtrl->GetItemText(srcItem));
1675+
m_organTreeCtrl->Delete(srcItem);
1676+
m_organTreeCtrl->SelectItem(newPos);
1677+
}
1678+
} else if ((std::find(manualsInTree.begin(), manualsInTree.end(), dstItem) != manualsInTree.end() && dstParent == tree_manuals) ||
1679+
(std::find(manualsInTree.begin(), manualsInTree.end(), dstParent) != manualsInTree.end() && m_organTreeCtrl->GetItemText(dstItem) == wxT("Stops"))
1680+
) {
1681+
// The destination is a manual or a stops category, should the move proceed?
1682+
if (srcGrandParent == dstItem && m_organTreeCtrl->GetChildrenCount(srcParent, false) < 2) {
1683+
return;
1684+
} else if (srcParent == dstItem && m_organTreeCtrl->GetChildrenCount(srcParent, false) < 2) {
1685+
return;
1686+
}
1687+
// Get what manual the source stop belongs to and what manual is the destination
1688+
int srcManualIdx = -1;
1689+
int dstManualIdx = -1;
1690+
for (unsigned i = 0; i < manualsInTree.size(); i++) {
1691+
if (m_organTreeCtrl->GetItemText(manualsInTree[i]) == m_organTreeCtrl->GetItemText(srcGrandParent))
1692+
srcManualIdx = i;
1693+
if ((m_organTreeCtrl->GetItemText(manualsInTree[i]) == m_organTreeCtrl->GetItemText(dstItem)) ||
1694+
(m_organTreeCtrl->GetItemText(manualsInTree[i]) == m_organTreeCtrl->GetItemText(dstParent))
1695+
)
1696+
dstManualIdx = i;
1697+
}
1698+
1699+
// Target we will be the first (0th) element
1700+
int dstStopIdx = 0;
1701+
// Now we should know the source and destination index of respective manual and stop
1702+
if (m_organ->moveStop(srcManualIdx, srcStopIdx, dstManualIdx, dstStopIdx)) {
1703+
// The move succeeded in the organ so now it's just to take care of it in tree
1704+
wxTreeItemId newPos;
1705+
if (m_organTreeCtrl->GetItemText(dstItem) == wxT("Stops")) {
1706+
newPos = m_organTreeCtrl->InsertItem(dstItem, 0, m_organTreeCtrl->GetItemText(srcItem));
1707+
} else {
1708+
wxTreeItemIdValue stopsCookie;
1709+
wxTreeItemId stopCategory = m_organTreeCtrl->GetFirstChild(dstItem, stopsCookie);
1710+
newPos = m_organTreeCtrl->InsertItem(stopCategory, 0, m_organTreeCtrl->GetItemText(srcItem));
1711+
}
1712+
m_organTreeCtrl->Delete(srcItem);
1713+
m_organTreeCtrl->SelectItem(newPos);
1714+
}
1715+
}
15951716
}
15961717

15971718
}

src/Manual.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,19 @@ int Manual::getIndexOfStop(Stop *stop) {
379379
return -1;
380380
}
381381

382+
void Manual::moveStop(int idxToMove, int destinationIdx) {
383+
auto theOneToMove = std::next(m_stops.begin(), idxToMove);
384+
std::list<Stop*>::iterator it = m_stops.begin();
385+
386+
if (destinationIdx > (int) m_stops.size() - 1) {
387+
it = m_stops.end();
388+
} else {
389+
it = std::next(m_stops.begin(), destinationIdx);
390+
}
391+
392+
m_stops.splice(it, m_stops, theOneToMove);
393+
}
394+
382395
unsigned Manual::getNumberOfCouplers() {
383396
return m_couplers.size();
384397
}

src/Manual.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class Manual {
6565
void removeStopAt(unsigned index);
6666
bool hasStopReference(Stop *stop);
6767
int getIndexOfStop(Stop *stop);
68+
void moveStop(int idxToMove, int destinationIdx);
6869
unsigned getNumberOfCouplers();
6970
Coupler* getCouplerAt(unsigned index);
7071
void addCoupler(Coupler *coupler);

0 commit comments

Comments
 (0)