1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2011 Werner Schweer
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License version 2
9 //  as published by the Free Software Foundation and appearing in
10 //  the file LICENCE.GPL
11 //=============================================================================
12 
13 #include "log.h"
14 
15 #include "scoreview.h"
16 #include "libmscore/score.h"
17 #include "musescore.h"
18 #include "libmscore/staff.h"
19 #include "libmscore/utils.h"
20 #include "libmscore/undo.h"
21 #include "libmscore/part.h"
22 #include "tourhandler.h"
23 
24 namespace Ms {
25 
26 //---------------------------------------------------------
27 //   startDrag
28 //---------------------------------------------------------
29 
startDrag()30 void ScoreView::startDrag()
31       {
32       editData.grips = 0;
33       editData.clearData();
34       editData.normalizedStartMove = editData.startMove - editData.element->offset();
35 
36       const Selection& sel = _score->selection();
37       const bool filterType = sel.isRange();
38       const ElementType type = editData.element->type();
39 
40       const auto isDragged = [filterType, type](const Element* e) {
41             return e && e->selected() && (!filterType || type == e->type());
42             };
43 
44       for (Element* e : sel.elements()) {
45             if (!isDragged(e))
46                   continue;
47 
48             std::unique_ptr<ElementGroup> g = e->getDragGroup(isDragged);
49             if (g && g->enabled())
50                   dragGroups.push_back(std::move(g));
51             }
52 
53       _score->startCmd();
54 
55       for (auto& g : dragGroups)
56             g->startDrag(editData);
57 
58       _score->selection().lock("drag");
59       }
60 
61 //---------------------------------------------------------
62 //   doDragElement
63 //---------------------------------------------------------
64 
doDragElement(QMouseEvent * ev)65 void ScoreView::doDragElement(QMouseEvent* ev)
66       {
67       const QPointF logicalPos = toLogical(ev->pos());
68       QPointF delta = logicalPos - editData.normalizedStartMove;
69       QPointF evtDelta = logicalPos - editData.pos;
70 
71       TourHandler::startTour("autoplace-tour");
72 
73       QPointF pt(delta);
74       if (qApp->keyboardModifiers() == Qt::ShiftModifier) {
75             pt.setX(editData.element->offset().x());
76             evtDelta.setX(0.0);
77             }
78       else if (qApp->keyboardModifiers() == Qt::ControlModifier) {
79             pt.setY(editData.element->offset().y());
80             evtDelta.setY(0.0);
81             }
82 
83       editData.lastPos = editData.pos;
84       editData.hRaster = mscore->hRaster();
85       editData.vRaster = mscore->vRaster();
86       editData.delta   = pt;
87       editData.moveDelta = pt + (editData.normalizedStartMove - editData.startMove); // TODO: restructure
88       editData.evtDelta = evtDelta;
89       editData.pos     = logicalPos;
90 
91       const Selection& sel = _score->selection();
92 
93       for (auto& g : dragGroups)
94             _score->addRefresh(g->drag(editData));
95 
96       _score->update();
97       QVector<QLineF> anchorLines;
98 
99       for (Element* e : sel.elements()) {
100             QVector<QLineF> elAnchorLines = e->dragAnchorLines();
101 
102             if (!elAnchorLines.isEmpty()) {
103                   anchorLines.append(elAnchorLines);
104                   }
105             }
106 
107       if (anchorLines.isEmpty())
108             setDropTarget(0); // this also resets dropAnchor
109       else
110             setDropAnchorLines(anchorLines);
111 
112       Element* e = _score->getSelectedElement();
113       if (e) {
114             if (_score->playNote()) {
115                   mscore->play(e);
116                   _score->setPlayNote(false);
117                   }
118             }
119       updateGrips();
120       _score->update();
121       }
122 
123 //---------------------------------------------------------
124 //   endDrag
125 //---------------------------------------------------------
126 
endDrag()127 void ScoreView::endDrag()
128       {
129       for (auto& g : dragGroups)
130             g->endDrag(editData);
131 
132       dragGroups.clear();
133       _score->selection().unlock("drag");
134       setDropTarget(0); // this also resets dropAnchor
135       _score->endCmd();
136       updateGrips();
137       if (editData.element->normalModeEditBehavior() == Element::EditBehavior::Edit && _score->selection().element() == editData.element)
138             startEdit(/* editMode */ false);
139       }
140 }
141 
142