diff --git a/cockatrice/src/client/network/replay_timeline_widget.cpp b/cockatrice/src/client/network/replay_timeline_widget.cpp index 8a0d1d5bc..4e5b93699 100644 --- a/cockatrice/src/client/network/replay_timeline_widget.cpp +++ b/cockatrice/src/client/network/replay_timeline_widget.cpp @@ -67,6 +67,19 @@ void ReplayTimelineWidget::mousePressEvent(QMouseEvent *event) #else int newTime = static_cast((qint64)maxTime * (qint64)event->x() / width()); #endif + skipToTime(newTime); +} + +void ReplayTimelineWidget::skipToTime(int newTime) +{ + // check boundary conditions + if (newTime < 0) { + newTime = 0; + } + if (newTime > maxTime) { + newTime = maxTime; + } + newTime -= newTime % 200; // Time should always be a multiple of 200 if (newTime < currentTime) { currentTime = 0; @@ -119,3 +132,8 @@ void ReplayTimelineWidget::stopReplay() { replayTimer->stop(); } + +void ReplayTimelineWidget::skipByAmount(int amount) +{ + skipToTime(currentTime + amount); +} \ No newline at end of file diff --git a/cockatrice/src/client/network/replay_timeline_widget.h b/cockatrice/src/client/network/replay_timeline_widget.h index 2805b89e4..5de3850ac 100644 --- a/cockatrice/src/client/network/replay_timeline_widget.h +++ b/cockatrice/src/client/network/replay_timeline_widget.h @@ -25,6 +25,8 @@ private: qreal timeScaleFactor; int currentTime; int currentEvent; + + void skipToTime(int newTime); private slots: void replayTimerTimeout(); @@ -41,6 +43,7 @@ public: public slots: void startReplay(); void stopReplay(); + void skipByAmount(int amount); // use a negative amount to skip backwards protected: void paintEvent(QPaintEvent *event) override; diff --git a/cockatrice/src/client/tabs/tab_game.cpp b/cockatrice/src/client/tabs/tab_game.cpp index 6ee2b05a0..ebcf2bcd4 100644 --- a/cockatrice/src/client/tabs/tab_game.cpp +++ b/cockatrice/src/client/tabs/tab_game.cpp @@ -257,6 +257,18 @@ void TabGame::refreshShortcuts() if (aFocusChat) { aFocusChat->setShortcuts(shortcuts.getShortcut("tab_game/aFocusChat")); } + if (aReplaySkipForward) { + aReplaySkipForward->setShortcuts(shortcuts.getShortcut("Replays/aSkipForward")); + } + if (aReplaySkipBackward) { + aReplaySkipBackward->setShortcuts(shortcuts.getShortcut("Replays/aSkipBackward")); + } + if (aReplaySkipForwardBig) { + aReplaySkipForwardBig->setShortcuts(shortcuts.getShortcut("Replays/aSkipForwardBig")); + } + if (aReplaySkipBackwardBig) { + aReplaySkipBackwardBig->setShortcuts(shortcuts.getShortcut("Replays/aSkipBackwardBig")); + } if (replayPlayButton) { replayPlayButton->setShortcut(shortcuts.getSingleShortcut("Replays/playButton")); } @@ -1699,12 +1711,35 @@ void TabGame::createPlayAreaWidget(bool bReplay) void TabGame::createReplayDock() { + // timeline widget timelineWidget = new ReplayTimelineWidget; timelineWidget->setTimeline(replayTimeline); connect(timelineWidget, SIGNAL(processNextEvent()), this, SLOT(replayNextEvent())); connect(timelineWidget, SIGNAL(replayFinished()), this, SLOT(replayFinished())); connect(timelineWidget, &ReplayTimelineWidget::rewound, messageLog, &ChatView::clearChat); + // timeline skip shortcuts + aReplaySkipForward = new QAction(timelineWidget); + timelineWidget->addAction(aReplaySkipForward); + connect(aReplaySkipForward, &QAction::triggered, this, + [=]() { timelineWidget->skipByAmount(SMALL_SKIP_AMOUNT_MS); }); + + aReplaySkipBackward = new QAction(timelineWidget); + timelineWidget->addAction(aReplaySkipBackward); + connect(aReplaySkipBackward, &QAction::triggered, this, + [=]() { timelineWidget->skipByAmount(-SMALL_SKIP_AMOUNT_MS); }); + + aReplaySkipForwardBig = new QAction(timelineWidget); + timelineWidget->addAction(aReplaySkipForwardBig); + connect(aReplaySkipForwardBig, &QAction::triggered, this, + [=]() { timelineWidget->skipByAmount(BIG_SKIP_AMOUNT_MS); }); + + aReplaySkipBackwardBig = new QAction(timelineWidget); + timelineWidget->addAction(aReplaySkipBackwardBig); + connect(aReplaySkipBackwardBig, &QAction::triggered, this, + [=]() { timelineWidget->skipByAmount(-BIG_SKIP_AMOUNT_MS); }); + + // buttons replayPlayButton = new QToolButton; replayPlayButton->setIconSize(QSize(32, 32)); QIcon playButtonIcon = QIcon(); @@ -1720,6 +1755,7 @@ void TabGame::createReplayDock() replayFastForwardButton->setCheckable(true); connect(replayFastForwardButton, SIGNAL(toggled(bool)), this, SLOT(replayFastForwardButtonToggled(bool))); + // putting everything together replayControlLayout = new QHBoxLayout; replayControlLayout->addWidget(timelineWidget, 10); replayControlLayout->addWidget(replayPlayButton); diff --git a/cockatrice/src/client/tabs/tab_game.h b/cockatrice/src/client/tabs/tab_game.h index a1d1bdc28..499a9e415 100644 --- a/cockatrice/src/client/tabs/tab_game.h +++ b/cockatrice/src/client/tabs/tab_game.h @@ -142,11 +142,14 @@ private: QStackedWidget *mainWidget; // Replay related members + static const int SMALL_SKIP_AMOUNT_MS = 1000; + static const int BIG_SKIP_AMOUNT_MS = 10000; GameReplay *replay; int currentReplayStep; QList replayTimeline; ReplayTimelineWidget *timelineWidget; QToolButton *replayPlayButton, *replayFastForwardButton; + QAction *aReplaySkipForward, *aReplaySkipBackward, *aReplaySkipForwardBig, *aReplaySkipBackwardBig; CardFrame *cardInfo; PlayerListWidget *playerListWidget; diff --git a/cockatrice/src/settings/shortcuts_settings.cpp b/cockatrice/src/settings/shortcuts_settings.cpp index 910b44d4c..0602128e9 100644 --- a/cockatrice/src/settings/shortcuts_settings.cpp +++ b/cockatrice/src/settings/shortcuts_settings.cpp @@ -151,7 +151,7 @@ void ShortcutsSettings::clearAllShortcuts() bool ShortcutsSettings::isKeyAllowed(const QString &name, const QString &Sequences) const { // if the shortcut is not to be used in deck-editor then it doesn't matter - if (name.startsWith("Player")) { + if (name.startsWith("Player") || name.startsWith("Replays")) { return true; } QString checkSequence = Sequences.split(sep).last(); diff --git a/cockatrice/src/settings/shortcuts_settings.h b/cockatrice/src/settings/shortcuts_settings.h index 98457b1c1..57e75f608 100644 --- a/cockatrice/src/settings/shortcuts_settings.h +++ b/cockatrice/src/settings/shortcuts_settings.h @@ -590,11 +590,23 @@ private: {"DlgLoadDeckFromClipboard/refreshButton", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Refresh"), parseSequenceString("F5"), ShortcutGroup::Load_deck)}, + {"Replays/aSkipForward", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Skip Forward"), + parseSequenceString("Right"), + ShortcutGroup::Replays)}, + {"Replays/aSkipBackward", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Skip Backward"), + parseSequenceString("Left"), + ShortcutGroup::Replays)}, + {"Replays/aSkipForwardBig", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Skip Forward by a lot"), + parseSequenceString("Ctrl+Right"), + ShortcutGroup::Replays)}, + {"Replays/aSkipBackwardBig", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Skip Backward by a lot"), + parseSequenceString("Ctrl+Left"), + ShortcutGroup::Replays)}, {"Replays/playButton", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Play/Pause"), parseSequenceString("Space"), ShortcutGroup::Replays)}, {"Replays/fastForwardButton", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Toggle Fast Forward"), - parseSequenceString("Ctrl+Right"), + parseSequenceString("Ctrl+P"), ShortcutGroup::Replays)}}; };