Skip to content

Commit c8c228d

Browse files
committed
Improve tempo editing
1 parent 2acc8ba commit c8c228d

File tree

4 files changed

+71
-18
lines changed

4 files changed

+71
-18
lines changed

src/libs/application/uishell/src/qml/TempoTimeSignatureIndicator.qml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ Item {
3636
font.pixelSize: 16
3737
implicitWidth: Math.max(control.backgroundVisible ? 54 : 0, implicitContentWidth + 16)
3838
implicitHeight: 24
39-
leftPadding: 12
40-
rightPadding: 12
39+
leftPadding: 8
40+
rightPadding: 8
4141
}
4242
IndicatorToolButton {
4343
text: control.tempoText

src/plugins/visualeditor/core/TempoViewModelContextData.cpp

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,27 @@
55

66
#include <QLocale>
77
#include <QLoggingCategory>
8-
#include <QStateMachine>
8+
#include <QQuickItem>
9+
#include <QQuickWindow>
910
#include <QSignalTransition>
11+
#include <QStateMachine>
1012

13+
#include <ScopicFlowCore/LabelSequenceInteractionController.h>
1114
#include <ScopicFlowCore/LabelViewModel.h>
1215
#include <ScopicFlowCore/PointSequenceViewModel.h>
13-
#include <ScopicFlowCore/LabelSequenceInteractionController.h>
16+
#include <ScopicFlowCore/TimeManipulator.h>
17+
#include <ScopicFlowCore/TimeViewModel.h>
18+
#include <ScopicFlowCore/TimeLayoutViewModel.h>
1419

1520
#include <dspxmodel/Model.h>
21+
#include <dspxmodel/SelectionModel.h>
1622
#include <dspxmodel/Tempo.h>
23+
#include <dspxmodel/TempoSelectionModel.h>
1724
#include <dspxmodel/TempoSequence.h>
1825
#include <dspxmodel/Timeline.h>
19-
#include <dspxmodel/SelectionModel.h>
20-
#include <dspxmodel/TempoSelectionModel.h>
2126

2227
#include <coreplugin/DspxDocument.h>
28+
#include <coreplugin/EditTempoTimeSignatureScenario.h>
2329
#include <coreplugin/ProjectDocumentContext.h>
2430
#include <coreplugin/ProjectWindowInterface.h>
2531

@@ -52,10 +58,16 @@ namespace VisualEditor {
5258
auto endDocumentItem = endItem ? q->getTempoDocumentItemFromViewItem(qobject_cast<sflow::LabelViewModel *>(endItem)) : tempoSequence->lastItem();
5359
Q_ASSERT(startDocumentItem && endDocumentItem);
5460
QObjectList viewItems;
55-
for (auto item = startDocumentItem; item && item != endDocumentItem; item = tempoSequence->nextItem(item)) {
61+
if (startDocumentItem->pos() > endDocumentItem->pos()) {
62+
std::swap(startDocumentItem, endDocumentItem);
63+
}
64+
for (auto item = startDocumentItem; item; item = tempoSequence->nextItem(item)) {
5665
auto viewItem = q->getTempoViewItemFromDocumentItem(item);
5766
Q_ASSERT(viewItem);
5867
viewItems.append(viewItem);
68+
if (item == endDocumentItem) {
69+
break;
70+
}
5971
}
6072
return viewItems;
6173
}
@@ -79,7 +91,7 @@ namespace VisualEditor {
7991
selectionModel->select(documentItem, documentSelectionCommand, dspx::SelectionModel::ST_Tempo);
8092
}
8193
QObject *TempoSelectionController::currentItem() const {
82-
return tempoSelectionModel->currentItem();
94+
return q->getTempoViewItemFromDocumentItem(tempoSelectionModel->currentItem());
8395
}
8496

8597
void TempoViewModelContextData::init() {
@@ -106,32 +118,38 @@ namespace VisualEditor {
106118
movePendingState->addTransition(this, &TempoViewModelContextData::transactionStarted, movingState);
107119
movePendingState->addTransition(this, &TempoViewModelContextData::transactionNotStarted, idleState);
108120

109-
connect(idleState, &QState::entered, q, [=, this] {
121+
connect(idleState, &QState::entered, this, [=, this] {
110122
qCInfo(lcTempoViewModelContextData) << "Idle state entered";
111123
});
112-
connect(idleState, &QState::exited, q, [=, this] {
124+
connect(idleState, &QState::exited, this, [=, this] {
113125
qCInfo(lcTempoViewModelContextData) << "Idle state exited";
114126
});
115-
connect(movePendingState, &QState::entered, q, [=, this] {
127+
connect(movePendingState, &QState::entered, this, [=, this] {
116128
qCInfo(lcTempoViewModelContextData) << "Move pending state entered";
117129
handleMovePendingStateEntered();
118130
});
119-
connect(movePendingState, &QState::exited, q, [=, this] {
131+
connect(movePendingState, &QState::exited, this, [=, this] {
120132
qCInfo(lcTempoViewModelContextData) << "Move pending state exited";
121133
});
122-
connect(movingState, &QState::entered, q, [=, this] {
134+
connect(movingState, &QState::entered, this, [=, this] {
123135
qCInfo(lcTempoViewModelContextData) << "Moving state entered";
124136
});
125-
connect(movingState, &QState::exited, q, [=, this] {
137+
connect(movingState, &QState::exited, this, [=, this] {
126138
qCInfo(lcTempoViewModelContextData) << "Moving state exited";
127139
handleMovingStateExited();
128140
});
129-
connect(rubberBandDraggingState, &QState::entered, q, [=, this] {
141+
connect(rubberBandDraggingState, &QState::entered, this, [=, this] {
130142
qCInfo(lcTempoViewModelContextData) << "Rubber band dragging state entered";
131143
});
132-
connect(rubberBandDraggingState, &QState::exited, q, [=, this] {
144+
connect(rubberBandDraggingState, &QState::exited, this, [=, this] {
133145
qCInfo(lcTempoViewModelContextData) << "Rubber band dragging state exited";
134146
});
147+
148+
scenario = new Core::EditTempoTimeSignatureScenario(this);
149+
scenario->setWindow(static_cast<QQuickWindow *>(q->windowHandle()->window()));
150+
scenario->setProjectTimeline(q->windowHandle()->projectTimeline());
151+
scenario->setDocument(q->windowHandle()->projectDocumentContext()->document());
152+
scenario->setShouldDialogPopupAtCursor(true);
135153
}
136154

137155
void TempoViewModelContextData::bindTempoSequenceViewModel() {
@@ -146,7 +164,7 @@ namespace VisualEditor {
146164
for (auto item : tempoSequence->asRange()) {
147165
bindTempoDocumentItem(item);
148166
}
149-
connect(tempoSelectionModel, &dspx::TempoSelectionModel::itemSelected, q, [=, this](dspx::Tempo *item, bool selected) {
167+
connect(tempoSelectionModel, &dspx::TempoSelectionModel::itemSelected, this, [=, this](dspx::Tempo *item, bool selected) {
150168
qCDebug(lcTempoViewModelContextData) << "Tempo item selected" << item << selected;
151169
auto viewItem = tempoViewItemMap.value(item);
152170
Q_ASSERT(viewItem);
@@ -273,6 +291,14 @@ namespace VisualEditor {
273291
movingState->removeTransition(moveFinishTransition);
274292
rubberBandDraggingState->removeTransition(rubberBandDragFinishTransition);
275293
});
294+
connect(controller, &sflow::LabelSequenceInteractionController::doubleClicked, this, [=](QQuickItem *labelSequenceItem, int position) {
295+
qCDebug(lcTempoViewModelContextData) << "Tempo sequence double clicked" << position;
296+
handleDoubleClicked(labelSequenceItem, position);
297+
});
298+
connect(controller, &sflow::LabelSequenceInteractionController::itemDoubleClicked, this, [=](QQuickItem *, sflow::LabelViewModel *viewItem) {
299+
qCDebug(lcTempoViewModelContextData) << "Tempo sequence view item double clicked" << viewItem;
300+
handleItemDoubleClicked(viewItem);
301+
});
276302
return controller;
277303
}
278304

@@ -314,5 +340,23 @@ namespace VisualEditor {
314340
}
315341
q->windowHandle()->projectDocumentContext()->document()->transactionController()->commitTransaction(moveTransactionId, tr("Moving tempo"));
316342
}
343+
void TempoViewModelContextData::handleDoubleClicked(QQuickItem *labelSequenceItem, int position) {
344+
Q_Q(ProjectViewModelContext);
345+
sflow::TimeManipulator timeManipulator;
346+
timeManipulator.setTarget(labelSequenceItem);
347+
timeManipulator.setTimeViewModel(labelSequenceItem->property("timeViewModel").value<sflow::TimeViewModel *>());
348+
timeManipulator.setTimeLayoutViewModel(labelSequenceItem->property("timeLayoutViewModel").value<sflow::TimeLayoutViewModel *>());
349+
position = timeManipulator.alignPosition(position, sflow::ScopicFlow::AO_Visible);
350+
scenario->insertTempoAt(position);
351+
auto items = tempoSequence->slice(position, 1);
352+
if (items.isEmpty()) {
353+
return;
354+
}
355+
q->windowHandle()->projectDocumentContext()->document()->selectionModel()->select(items.first(), dspx::SelectionModel::Select | dspx::SelectionModel::SetCurrentItem | dspx::SelectionModel::ClearPreviousSelection);
356+
}
357+
void TempoViewModelContextData::handleItemDoubleClicked(sflow::LabelViewModel *viewItem) {
358+
Q_Q(ProjectViewModelContext);
359+
scenario->modifyExistingTempoAt(viewItem->position());
360+
}
317361

318362
}

src/plugins/visualeditor/core/TempoViewModelContextData_p.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@
1212

1313
class QStateMachine;
1414
class QState;
15+
class QQuickItem;
1516

1617
namespace dspx {
1718
class TempoSequence;
1819
class TempoSelectionModel;
1920
class SelectionModel;
2021
}
2122

23+
namespace Core {
24+
class EditTempoTimeSignatureScenario;
25+
}
26+
2227
namespace VisualEditor {
2328

2429
class TempoSelectionController : public sflow::SelectionController {
@@ -62,6 +67,8 @@ namespace VisualEditor {
6267
QState *movingState;
6368
QState *rubberBandDraggingState;
6469

70+
Core::EditTempoTimeSignatureScenario *scenario;
71+
6572
Core::TransactionController::TransactionId moveTransactionId{};
6673

6774
void init();
@@ -72,6 +79,8 @@ namespace VisualEditor {
7279

7380
void handleMovePendingStateEntered();
7481
void handleMovingStateExited();
82+
void handleDoubleClicked(QQuickItem *labelSequenceItem, int position);
83+
void handleItemDoubleClicked(sflow::LabelViewModel *viewItem);
7584

7685
Q_SIGNALS:
7786
void transactionStarted();

0 commit comments

Comments
 (0)