timeline/viewer: reimplemented "play in to out" and "loop"
This commit is contained in:
@@ -81,6 +81,7 @@ void Config::SetDefaults()
|
||||
config_map_["SetNameWithMarker"] = false;
|
||||
config_map_["RectifiedWaveforms"] = false;
|
||||
config_map_["DropWithoutSequenceBehavior"] = TimelineWidget::kDWSAsk;
|
||||
config_map_["Loop"] = false;
|
||||
|
||||
config_map_["DiskCachePath"] = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
|
||||
config_map_["DiskCacheSize"] = 20.0;
|
||||
|
||||
@@ -88,6 +88,11 @@ void TimeBasedPanel::PlayPause()
|
||||
emit PlayPauseRequested();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::PlayInToOut()
|
||||
{
|
||||
emit PlayInToOutRequested();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::ShuttleLeft()
|
||||
{
|
||||
emit ShuttleLeftRequested();
|
||||
|
||||
@@ -60,6 +60,8 @@ public:
|
||||
|
||||
virtual void PlayPause() override;
|
||||
|
||||
virtual void PlayInToOut() override;
|
||||
|
||||
virtual void ShuttleLeft() override;
|
||||
|
||||
virtual void ShuttleStop() override;
|
||||
@@ -96,6 +98,8 @@ signals:
|
||||
|
||||
void PlayPauseRequested();
|
||||
|
||||
void PlayInToOutRequested();
|
||||
|
||||
void ShuttleLeftRequested();
|
||||
|
||||
void ShuttleStopRequested();
|
||||
|
||||
@@ -32,6 +32,11 @@ void ViewerPanelBase::PlayPause()
|
||||
static_cast<ViewerWidget*>(GetTimeBasedWidget())->TogglePlayPause();
|
||||
}
|
||||
|
||||
void ViewerPanelBase::PlayInToOut()
|
||||
{
|
||||
static_cast<ViewerWidget*>(GetTimeBasedWidget())->Play(true);
|
||||
}
|
||||
|
||||
void ViewerPanelBase::ShuttleLeft()
|
||||
{
|
||||
static_cast<ViewerWidget*>(GetTimeBasedWidget())->ShuttleLeft();
|
||||
@@ -50,6 +55,7 @@ void ViewerPanelBase::ShuttleRight()
|
||||
void ViewerPanelBase::ConnectTimeBasedPanel(TimeBasedPanel *panel)
|
||||
{
|
||||
connect(panel, &TimeBasedPanel::PlayPauseRequested, this, &ViewerPanelBase::PlayPause);
|
||||
connect(panel, &TimeBasedPanel::PlayInToOutRequested, this, &ViewerPanelBase::PlayInToOut);
|
||||
connect(panel, &TimeBasedPanel::ShuttleLeftRequested, this, &ViewerPanelBase::ShuttleLeft);
|
||||
connect(panel, &TimeBasedPanel::ShuttleStopRequested, this, &ViewerPanelBase::ShuttleStop);
|
||||
connect(panel, &TimeBasedPanel::ShuttleRightRequested, this, &ViewerPanelBase::ShuttleRight);
|
||||
@@ -58,6 +64,7 @@ void ViewerPanelBase::ConnectTimeBasedPanel(TimeBasedPanel *panel)
|
||||
void ViewerPanelBase::DisconnectTimeBasedPanel(TimeBasedPanel *panel)
|
||||
{
|
||||
disconnect(panel, &TimeBasedPanel::PlayPauseRequested, this, &ViewerPanelBase::PlayPause);
|
||||
disconnect(panel, &TimeBasedPanel::PlayInToOutRequested, this, &ViewerPanelBase::PlayInToOut);
|
||||
disconnect(panel, &TimeBasedPanel::ShuttleLeftRequested, this, &ViewerPanelBase::ShuttleLeft);
|
||||
disconnect(panel, &TimeBasedPanel::ShuttleStopRequested, this, &ViewerPanelBase::ShuttleStop);
|
||||
disconnect(panel, &TimeBasedPanel::ShuttleRightRequested, this, &ViewerPanelBase::ShuttleRight);
|
||||
|
||||
@@ -35,6 +35,8 @@ public:
|
||||
|
||||
virtual void PlayPause() override;
|
||||
|
||||
virtual void PlayInToOut() override;
|
||||
|
||||
virtual void ShuttleLeft() override;
|
||||
|
||||
virtual void ShuttleStop() override;
|
||||
|
||||
@@ -91,6 +91,8 @@ public:
|
||||
*/
|
||||
virtual void PlayPause(){}
|
||||
|
||||
virtual void PlayInToOut(){}
|
||||
|
||||
virtual void NextFrame(){}
|
||||
|
||||
virtual void GoToEnd(){}
|
||||
|
||||
@@ -84,7 +84,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
controls_ = new PlaybackControls();
|
||||
controls_->SetTimecodeEnabled(true);
|
||||
controls_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
|
||||
connect(controls_, &PlaybackControls::PlayClicked, this, &ViewerWidget::Play);
|
||||
connect(controls_, &PlaybackControls::PlayClicked, this, static_cast<void(ViewerWidget::*)()>(&ViewerWidget::Play));
|
||||
connect(controls_, &PlaybackControls::PauseClicked, this, &ViewerWidget::Pause);
|
||||
connect(controls_, &PlaybackControls::PrevFrameClicked, this, &ViewerWidget::PrevFrame);
|
||||
connect(controls_, &PlaybackControls::NextFrameClicked, this, &ViewerWidget::NextFrame);
|
||||
@@ -332,7 +332,7 @@ void ViewerWidget::UpdateTextureFromNode(const rational& time)
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::PlayInternal(int speed)
|
||||
void ViewerWidget::PlayInternal(int speed, bool in_to_out_only)
|
||||
{
|
||||
Q_ASSERT(speed != 0);
|
||||
|
||||
@@ -342,6 +342,7 @@ void ViewerWidget::PlayInternal(int speed)
|
||||
}
|
||||
|
||||
playback_speed_ = speed;
|
||||
play_in_to_out_only_ = in_to_out_only;
|
||||
|
||||
QIODevice* audio_src = audio_renderer_->GetAudioPullDevice();
|
||||
if (audio_src != nullptr && audio_src->open(QIODevice::ReadOnly)) {
|
||||
@@ -649,9 +650,21 @@ void ViewerWidget::ShowContextMenu(const QPoint &pos)
|
||||
menu.exec(static_cast<QWidget*>(sender())->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void ViewerWidget::Play(bool in_to_out_only)
|
||||
{
|
||||
if (in_to_out_only
|
||||
&& GetConnectedTimelinePoints()
|
||||
&& GetConnectedTimelinePoints()->workarea()->enabled()) {
|
||||
// Jump to in point
|
||||
SetTimeAndSignal(Timecode::time_to_timestamp(GetConnectedTimelinePoints()->workarea()->in(), timebase()));
|
||||
}
|
||||
|
||||
PlayInternal(1, in_to_out_only);
|
||||
}
|
||||
|
||||
void ViewerWidget::Play()
|
||||
{
|
||||
PlayInternal(1);
|
||||
Play(false);
|
||||
}
|
||||
|
||||
void ViewerWidget::Pause()
|
||||
@@ -683,7 +696,7 @@ void ViewerWidget::ShuttleLeft()
|
||||
current_speed--;
|
||||
}
|
||||
|
||||
PlayInternal(current_speed);
|
||||
PlayInternal(current_speed, false);
|
||||
}
|
||||
|
||||
void ViewerWidget::ShuttleStop()
|
||||
@@ -705,7 +718,7 @@ void ViewerWidget::ShuttleRight()
|
||||
current_speed++;
|
||||
}
|
||||
|
||||
PlayInternal(current_speed);
|
||||
PlayInternal(current_speed, false);
|
||||
}
|
||||
|
||||
void ViewerWidget::SetOCIOParameters(const QString &display, const QString &view, const QString &look)
|
||||
@@ -773,12 +786,64 @@ void ViewerWidget::PlaybackTimerUpdate()
|
||||
|
||||
int64_t current_time = start_timestamp_ + frames_since_start * playback_speed_;
|
||||
|
||||
if (current_time < 0) {
|
||||
SetTimeAndSignal(0);
|
||||
int64_t min_time, max_time;
|
||||
|
||||
{
|
||||
if ((play_in_to_out_only_ || Config::Current()["Loop"].toBool())
|
||||
&& GetConnectedTimelinePoints()
|
||||
&& GetConnectedTimelinePoints()->workarea()->enabled()) {
|
||||
|
||||
// If "play in to out" is enabled or we're looping AND we have a workarea, only play the workarea
|
||||
min_time = Timecode::time_to_timestamp(GetConnectedTimelinePoints()->workarea()->in(), timebase());
|
||||
max_time = Timecode::time_to_timestamp(GetConnectedTimelinePoints()->workarea()->out(), timebase());
|
||||
|
||||
} else {
|
||||
|
||||
// Otherwise set the bounds to the range of the sequence
|
||||
min_time = 0;
|
||||
max_time = Timecode::time_to_timestamp(GetConnectedNode()->Length(), timebase());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((playback_speed_ < 0 && current_time <= min_time)
|
||||
|| (playback_speed_ > 0 && current_time >= max_time)) {
|
||||
|
||||
// Determine which timestamp we tripped
|
||||
int64_t tripped_time;
|
||||
|
||||
if (current_time <= min_time) {
|
||||
tripped_time = min_time;
|
||||
} else {
|
||||
tripped_time = max_time;
|
||||
}
|
||||
|
||||
if (Config::Current()["Loop"].toBool()) {
|
||||
|
||||
// If we're looping, jump to the other side of the workarea and continue
|
||||
int64_t opposing_time = (tripped_time == min_time) ? max_time : min_time;
|
||||
|
||||
// Cache the current speed
|
||||
int current_speed = playback_speed_;
|
||||
|
||||
// Jump to the other side and keep playing at the same speed
|
||||
SetTimeAndSignal(opposing_time);
|
||||
PlayInternal(current_speed, play_in_to_out_only_);
|
||||
|
||||
} else {
|
||||
|
||||
// Pause at the boundary
|
||||
SetTimeAndSignal(tripped_time);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Sets time, wrapping in this bool ensures we don't pause from setting the time
|
||||
time_changed_from_timer_ = true;
|
||||
SetTimeAndSignal(current_time);
|
||||
time_changed_from_timer_ = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,8 @@ public:
|
||||
VideoRenderBackend* video_renderer() const;
|
||||
|
||||
public slots:
|
||||
void Play(bool in_to_out_only);
|
||||
|
||||
void Play();
|
||||
|
||||
void Pause();
|
||||
@@ -152,7 +154,7 @@ private:
|
||||
|
||||
void UpdateTextureFromNode(const rational &time);
|
||||
|
||||
void PlayInternal(int speed);
|
||||
void PlayInternal(int speed, bool in_to_out_only);
|
||||
|
||||
void PushScrubbedAudio();
|
||||
|
||||
@@ -186,6 +188,8 @@ private:
|
||||
|
||||
bool time_changed_from_timer_;
|
||||
|
||||
bool play_in_to_out_only_;
|
||||
|
||||
AudioWaveformView* waveform_view_;
|
||||
|
||||
QList<ViewerWindow*> windows_;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <QStyleFactory>
|
||||
|
||||
#include "common/timecodefunctions.h"
|
||||
#include "config/config.h"
|
||||
#include "core.h"
|
||||
#include "dialog/actionsearch/actionsearch.h"
|
||||
#include "panel/panelmanager.h"
|
||||
@@ -152,7 +153,7 @@ MainMenu::MainMenu(MainWindow *parent) :
|
||||
//
|
||||
// PLAYBACK MENU
|
||||
//
|
||||
playback_menu_ = new Menu(this);
|
||||
playback_menu_ = new Menu(this, this, &MainMenu::PlaybackMenuAboutToShow);
|
||||
playback_gotostart_item_ = playback_menu_->AddItem("gotostart", this, &MainMenu::GoToStartTriggered, "Home");
|
||||
playback_prevframe_item_ = playback_menu_->AddItem("prevframe", this, &MainMenu::PrevFrameTriggered, "Left");
|
||||
playback_playpause_item_ = playback_menu_->AddItem("playpause", this, &MainMenu::PlayPauseTriggered, "Space");
|
||||
@@ -179,7 +180,7 @@ MainMenu::MainMenu(MainWindow *parent) :
|
||||
playback_menu_->addSeparator();
|
||||
|
||||
playback_loop_item_ = playback_menu_->AddItem("loop", this, &MainMenu::LoopTriggered);
|
||||
//Menu::SetBooleanAction(playback_loop_item_, &olive::config.loop);
|
||||
playback_loop_item_->setCheckable(true);
|
||||
|
||||
//
|
||||
// WINDOW MENU
|
||||
@@ -359,6 +360,11 @@ void MainMenu::ToolsMenuAboutToShow()
|
||||
tools_snapping_item_->setChecked(Core::instance()->snapping());
|
||||
}
|
||||
|
||||
void MainMenu::PlaybackMenuAboutToShow()
|
||||
{
|
||||
playback_loop_item_->setChecked(Config::Current()["Loop"].toBool());
|
||||
}
|
||||
|
||||
void MainMenu::WindowMenuAboutToShow()
|
||||
{
|
||||
// QMainWindow generates a perfectly usable menu for this purpose, we just need to copy it to the window menu
|
||||
@@ -450,12 +456,12 @@ void MainMenu::PlayPauseTriggered()
|
||||
|
||||
void MainMenu::PlayInToOutTriggered()
|
||||
{
|
||||
qDebug() << "FIXME: Stub";
|
||||
PanelManager::instance()->CurrentlyFocused()->PlayInToOut();
|
||||
}
|
||||
|
||||
void MainMenu::LoopTriggered()
|
||||
void MainMenu::LoopTriggered(bool enabled)
|
||||
{
|
||||
qDebug() << "FIXME: Stub";
|
||||
Config::Current()["Loop"] = enabled;
|
||||
}
|
||||
|
||||
void MainMenu::NextFrameTriggered()
|
||||
|
||||
@@ -84,6 +84,11 @@ private slots:
|
||||
*/
|
||||
void ToolsMenuAboutToShow();
|
||||
|
||||
/**
|
||||
* @brief PlaybackMenuAboutToShow
|
||||
*/
|
||||
void PlaybackMenuAboutToShow();
|
||||
|
||||
/**
|
||||
* @brief Slot triggered just before the Window menu shows
|
||||
*/
|
||||
@@ -133,7 +138,7 @@ private slots:
|
||||
|
||||
void PlayInToOutTriggered();
|
||||
|
||||
void LoopTriggered();
|
||||
void LoopTriggered(bool enabled);
|
||||
|
||||
void NextFrameTriggered();
|
||||
void GoToEndTriggered();
|
||||
|
||||
Reference in New Issue
Block a user