Squashed commit of the following:

commit 60c0f65c5e3c2faf1f7b0ae10b4131dabbcf715b
Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com>
Date:   Wed Feb 15 22:34:16 2023 -0800

    mainwindow: don't close last timeline panel when removing sequence

commit bc892810d67c1dd4f9c0639767c563681f29701d
Merge: 69051a120 aef08f8cd
Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com>
Date:   Tue Feb 14 17:05:25 2023 -0800

    Merge branch 'master' into kddockwidgets

commit 69051a120b8423d0ad7b38def2f7555d323cd74d
Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com>
Date:   Tue Feb 14 15:29:24 2023 -0800

    finished kddockwidgets integration

commit 9a39dbeade871a0b9454b424c7f7a7482671d40b
Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com>
Date:   Tue Feb 14 11:54:25 2023 -0800

    switch to kddockwidgets
This commit is contained in:
itsmattkc
2023-02-16 00:44:08 -08:00
parent 9a87b197b3
commit 25b6b07a06
49 changed files with 252 additions and 331 deletions
+10
View File
@@ -150,8 +150,18 @@ if (${QT_VERSION_MAJOR} EQUAL "6")
list(APPEND OLIVE_LIBRARIES
Qt${QT_VERSION_MAJOR}::OpenGLWidgets
)
# Link KDDockWidgets
find_package(KDDockWidgets-qt6 CONFIG REQUIRED)
else()
# Link KDDockWidgets
find_package(KDDockWidgets CONFIG REQUIRED)
endif()
list(APPEND OLIVE_LIBRARIES
KDAB::kddockwidgets
)
# Link FFmpeg
find_package(FFMPEG 3.0 REQUIRED
COMPONENTS
+9
View File
@@ -752,6 +752,15 @@ void Core::StartGUI(bool full_screen)
PanelManager::instance(),
&PanelManager::FocusChanged);
// Set KDDockWidgets flags
auto &config = KDDockWidgets::Config::self();
auto flags = config.flags();
flags |= KDDockWidgets::Config::Flag_TabsHaveCloseButton;
flags |= KDDockWidgets::Config::Flag_HideTitleBarWhenTabsVisible;
flags |= KDDockWidgets::Config::Flag_AlwaysShowTabs;
flags |= KDDockWidgets::Config::Flag_AllowReorderTabs;
config.setFlags(flags);
// Create main window and open it
main_window_ = new MainWindow();
+3 -3
View File
@@ -26,10 +26,10 @@ namespace olive {
#define super PanelWidget
AudioMonitorPanel::AudioMonitorPanel(QWidget *parent) :
super(QStringLiteral("AudioMonitor"), parent)
AudioMonitorPanel::AudioMonitorPanel() :
super(QStringLiteral("AudioMonitor"))
{
audio_monitor_ = new AudioMonitor();
audio_monitor_ = new AudioMonitor(this);
SetWidgetWithPadding(audio_monitor_);
+1 -1
View File
@@ -33,7 +33,7 @@ class AudioMonitorPanel : public PanelWidget
{
Q_OBJECT
public:
AudioMonitorPanel(QWidget* parent = nullptr);
AudioMonitorPanel();
bool IsPlaying() const
{
+3 -3
View File
@@ -22,11 +22,11 @@
namespace olive {
CurvePanel::CurvePanel(QWidget *parent) :
TimeBasedPanel(QStringLiteral("CurvePanel"), parent)
CurvePanel::CurvePanel() :
TimeBasedPanel(QStringLiteral("CurvePanel"))
{
// Create main widget and set it
SetTimeBasedWidget(new CurveWidget());
SetTimeBasedWidget(new CurveWidget(this));
// Set strings
Retranslate();
+1 -1
View File
@@ -30,7 +30,7 @@ class CurvePanel : public TimeBasedPanel
{
Q_OBJECT
public:
CurvePanel(QWidget* parent);
CurvePanel();
virtual void DeleteSelected() override;
+3 -3
View File
@@ -24,11 +24,11 @@ namespace olive {
#define super ViewerPanelBase
FootageViewerPanel::FootageViewerPanel(QWidget *parent) :
super(QStringLiteral("FootageViewerPanel"), parent)
FootageViewerPanel::FootageViewerPanel() :
super(QStringLiteral("FootageViewerPanel"))
{
// Set ViewerWidget as the central widget
FootageViewerWidget* fvw = new FootageViewerWidget();
FootageViewerWidget* fvw = new FootageViewerWidget(this);
SetViewerWidget(fvw);
// Set strings
+1 -1
View File
@@ -35,7 +35,7 @@ namespace olive {
class FootageViewerPanel : public ViewerPanelBase, public FootageManagementPanel {
Q_OBJECT
public:
FootageViewerPanel(QWidget* parent);
FootageViewerPanel();
void OverrideWorkArea(const TimeRange &r);
+3 -3
View File
@@ -4,10 +4,10 @@ namespace olive {
#define super TimeBasedPanel
MulticamPanel::MulticamPanel(QWidget *parent) :
super(QStringLiteral("MultiCamPanel"), parent)
MulticamPanel::MulticamPanel() :
super(QStringLiteral("MultiCamPanel"))
{
SetTimeBasedWidget(new MulticamWidget());
SetTimeBasedWidget(new MulticamWidget(this));
Retranslate();
}
+1 -1
View File
@@ -10,7 +10,7 @@ class MulticamPanel : public TimeBasedPanel
{
Q_OBJECT
public:
MulticamPanel(QWidget* parent = nullptr);
MulticamPanel();
MulticamWidget *GetMulticamWidget() const { return static_cast<MulticamWidget *>(GetTimeBasedWidget()); }
+4 -4
View File
@@ -22,11 +22,11 @@
namespace olive {
NodePanel::NodePanel(QWidget *parent) :
PanelWidget(QStringLiteral("NodePanel"), parent)
NodePanel::NodePanel() :
PanelWidget(QStringLiteral("NodePanel"))
{
node_widget_ = new NodeWidget();
connect(this, &NodePanel::visibilityChanged, node_widget_->view(), &NodeView::CenterOnItemsBoundingRect);
node_widget_ = new NodeWidget(this);
connect(this, &NodePanel::shown, node_widget_->view(), &NodeView::CenterOnItemsBoundingRect);
connect(node_widget_->view(), &NodeView::NodesSelected, this, &NodePanel::NodesSelected);
connect(node_widget_->view(), &NodeView::NodesDeselected, this, &NodePanel::NodesDeselected);
+1 -1
View File
@@ -33,7 +33,7 @@ class NodePanel : public PanelWidget
{
Q_OBJECT
public:
NodePanel(QWidget* parent);
NodePanel();
NodeWidget *GetNodeWidget() const
{
+8 -27
View File
@@ -32,17 +32,16 @@
namespace olive {
#define super QDockWidget
#define super KDDockWidgets::DockWidget
PanelWidget::PanelWidget(const QString &object_name, QWidget *parent) :
super(parent),
PanelWidget::PanelWidget(const QString &object_name) :
super(object_name),
border_visible_(false),
signal_instead_of_close_(false)
{
setObjectName(object_name);
setFocusPolicy(Qt::ClickFocus);
connect(this, &PanelWidget::visibilityChanged, this, &PanelWidget::PanelVisibilityChanged);
connect(this, &PanelWidget::shown, this, static_cast<void(PanelWidget::*)()>(&PanelWidget::setFocus));
PanelManager::instance()->RegisterPanel(this);
}
@@ -52,17 +51,6 @@ PanelWidget::~PanelWidget()
PanelManager::instance()->UnregisterPanel(this);
}
void PanelWidget::SetMovementLocked(bool locked)
{
if (locked) {
// Disable moving on QDockWidget
setFeatures(features() & ~QDockWidget::DockWidgetMovable);
} else {
// Re-enable moving on QDockWidget
setFeatures(features() | QDockWidget::DockWidgetMovable);
}
}
void PanelWidget::SetBorderVisible(bool enabled)
{
border_visible_ = enabled;
@@ -110,16 +98,9 @@ void PanelWidget::UpdateTitle()
// If there's no subtitle, just use the title. Otherwise, we set a formatted combination of the two that can
// differ based on translation
if (subtitle_.isEmpty()) {
setWindowTitle(title_);
this->setTitle(title_);
} else {
setWindowTitle(tr("%1: %2").arg(title_, subtitle_));
}
}
void PanelWidget::PanelVisibilityChanged(bool e)
{
if (e) {
setFocus();
this->setTitle(tr("%1: %2").arg(title_, subtitle_));
}
}
@@ -134,7 +115,7 @@ void PanelWidget::closeEvent(QCloseEvent *event)
event->ignore();
emit CloseRequested();
} else {
QDockWidget::closeEvent(event);
super::closeEvent(event);
}
}
@@ -143,7 +124,7 @@ void PanelWidget::changeEvent(QEvent *e)
if (e->type() == QEvent::LanguageChange) {
Retranslate();
}
QDockWidget::changeEvent(e);
super::changeEvent(e);
}
void PanelWidget::Retranslate()
+3 -11
View File
@@ -21,7 +21,7 @@
#ifndef PANEL_WIDGET_H
#define PANEL_WIDGET_H
#include <QDockWidget>
#include <kddockwidgets/DockWidget.h>
#include <QEvent>
#include "common/define.h"
@@ -31,7 +31,7 @@ namespace olive {
/**
* @brief A widget that is always dockable within the MainWindow.
*/
class PanelWidget : public QDockWidget
class PanelWidget : public KDDockWidgets::DockWidget
{
Q_OBJECT
public:
@@ -43,15 +43,10 @@ public:
* The PanelWidget's parent, enforced to help with memory handling. Most of the time this will be an instance of
* MainWindow.
*/
PanelWidget(const QString& object_name, QWidget* parent);
PanelWidget(const QString& object_name);
virtual ~PanelWidget() override;
/**
* @brief Set whether panel movement is locked or not
*/
void SetMovementLocked(bool locked);
/**
* @brief Set visibility of panel's highlighted border, mostly used for showing panel focus
*
@@ -246,9 +241,6 @@ private:
bool signal_instead_of_close_;
private slots:
void PanelVisibilityChanged(bool e);
};
}
+28 -57
View File
@@ -28,7 +28,6 @@ PanelManager* PanelManager::instance_ = nullptr;
PanelManager::PanelManager(QObject *parent) :
QObject(parent),
locked_(false),
suppress_changed_signal_(false)
{
}
@@ -89,11 +88,6 @@ PanelWidget *PanelManager::GetPanelWithName(const QString &name) const
return nullptr;
}
bool PanelManager::ArePanelsLocked()
{
return locked_;
}
void PanelManager::CreateInstance()
{
instance_ = new PanelManager();
@@ -114,23 +108,10 @@ void PanelManager::RegisterPanel(PanelWidget *panel)
// Add panel to the bottom of the focus history
focus_history_.append(panel);
panel->SetMovementLocked(locked_);
// Get panel parent (it's assumed it has one)
QWidget *parent = panel->parentWidget();
// Sane default for panel size
panel->resize(parent->size() / 3);
// We're about to center the panel relative to the parent (usually the main window), but for some
// reason this requires the panel to be shown first.
panel->show();
// Center the panel relative to the parent
QPoint parent_center = panel->mapFromGlobal(parent->mapToGlobal(parent->rect().center()));
QPoint panel_center = panel->rect().center();
panel->move(parent_center - panel_center);
if (focus_history_.size() == 1) {
// This is the first panel, focus it
panel->SetBorderVisible(true);
@@ -151,54 +132,44 @@ void PanelManager::FocusChanged(QWidget *old, QWidget *now)
PanelWidget* panel_cast_test;
// Loop through widget's parent hierarchy
while (parent != nullptr) {
if (!focus_history_.empty()) {
while (parent != nullptr) {
// Use dynamic_cast to test if this object is a PanelWidget
panel_cast_test = dynamic_cast<PanelWidget*>(parent);
// Use dynamic_cast to test if this object is a PanelWidget
panel_cast_test = dynamic_cast<PanelWidget*>(parent);
if (panel_cast_test) {
if (panel_cast_test) {
if (focus_history_.first() != panel_cast_test) {
// If so, bump this to the top of the focus history
int panel_index = focus_history_.indexOf(panel_cast_test);
if (focus_history_.first() != panel_cast_test) {
// If so, bump this to the top of the focus history
int panel_index = focus_history_.indexOf(panel_cast_test);
// Disable highlight border on old panel
if (!focus_history_.isEmpty()) {
focus_history_.first()->SetBorderVisible(false);
// Disable highlight border on old panel
if (!focus_history_.isEmpty()) {
focus_history_.first()->SetBorderVisible(false);
}
// Enable new border's highlight
panel_cast_test->SetBorderVisible(true);
// If it's not in the focus history, prepend it, otherwise move it
if (panel_index == -1) {
focus_history_.prepend(panel_cast_test);
} else {
focus_history_.move(panel_index, 0);
}
if (!suppress_changed_signal_) {
emit FocusedPanelChanged(panel_cast_test);
}
}
// Enable new border's highlight
panel_cast_test->SetBorderVisible(true);
// If it's not in the focus history, prepend it, otherwise move it
if (panel_index == -1) {
focus_history_.prepend(panel_cast_test);
} else {
focus_history_.move(panel_index, 0);
}
if (!suppress_changed_signal_) {
emit FocusedPanelChanged(panel_cast_test);
}
break;
}
break;
}
parent = parent->parent();
}
}
void PanelManager::SetPanelsLocked(bool locked)
{
foreach (PanelWidget* panel, focus_history_) {
// Only affect panels actually in our layout
if (!panel->isFloating()) {
panel->SetMovementLocked(locked);
parent = parent->parent();
}
}
locked_ = locked;
}
}
-15
View File
@@ -86,11 +86,6 @@ public:
*/
T* MostRecentlyFocused();
/**
* @brief Get whether panels are currently prevented from moving
*/
bool ArePanelsLocked();
/**
* @brief Create PanelManager singleton instance
*/
@@ -137,11 +132,6 @@ public slots:
*/
void FocusChanged(QWidget* old, QWidget* now);
/**
* @brief Sets whether panels should be prevented from moving
*/
void SetPanelsLocked(bool locked);
signals:
/**
* @brief Signal emitted when the currently focused panel changes
@@ -154,11 +144,6 @@ private:
*/
QList<PanelWidget*> focus_history_;
/**
* @brief Internal panel movement is locked value
*/
bool locked_;
/**
* @brief PanelManager singleton instance
*/
+4 -4
View File
@@ -24,14 +24,14 @@
namespace olive {
ParamPanel::ParamPanel(QWidget* parent) :
TimeBasedPanel(QStringLiteral("ParamPanel"), parent)
ParamPanel::ParamPanel() :
TimeBasedPanel(QStringLiteral("ParamPanel"))
{
NodeParamView* view = new NodeParamView();
NodeParamView* view = new NodeParamView(this);
connect(view, &NodeParamView::FocusedNodeChanged, this, &ParamPanel::FocusedNodeChanged);
connect(view, &NodeParamView::SelectedNodesChanged, this, &ParamPanel::SelectedNodesChanged);
connect(view, &NodeParamView::RequestViewerToStartEditingText, this, &ParamPanel::RequestViewerToStartEditingText);
connect(this, &ParamPanel::visibilityChanged, view, &NodeParamView::UpdateElementY);
connect(this, &ParamPanel::shown, view, &NodeParamView::UpdateElementY);
SetTimeBasedWidget(view);
Retranslate();
+1 -1
View File
@@ -31,7 +31,7 @@ class ParamPanel : public TimeBasedPanel
{
Q_OBJECT
public:
ParamPanel(QWidget* parent);
ParamPanel();
NodeParamView *GetParamView() const
{
+5 -4
View File
@@ -24,13 +24,14 @@
namespace olive {
PixelSamplerPanel::PixelSamplerPanel(QWidget *parent) :
PanelWidget(QStringLiteral("PixelSamplerPanel"), parent)
PixelSamplerPanel::PixelSamplerPanel() :
PanelWidget(QStringLiteral("PixelSamplerPanel"))
{
sampler_widget_ = new ManagedPixelSamplerWidget();
sampler_widget_ = new ManagedPixelSamplerWidget(this);
SetWidgetWithPadding(sampler_widget_);
connect(this, &PixelSamplerPanel::visibilityChanged, Core::instance(), &Core::RequestPixelSamplingInViewers);
connect(this, &PixelSamplerPanel::shown, Core::instance(), []{Core::instance()->RequestPixelSamplingInViewers(true);});
connect(this, &PixelSamplerPanel::hidden, Core::instance(), []{Core::instance()->RequestPixelSamplingInViewers(false);});
connect(Core::instance(), &Core::ColorPickerColorEmitted, this, &PixelSamplerPanel::SetValues);
Retranslate();
+1 -1
View File
@@ -30,7 +30,7 @@ class PixelSamplerPanel : public PanelWidget
{
Q_OBJECT
public:
PixelSamplerPanel(QWidget* parent = nullptr);
PixelSamplerPanel();
public slots:
void SetValues(const Color& reference, const Color& display);
+3 -11
View File
@@ -34,8 +34,8 @@
namespace olive {
ProjectPanel::ProjectPanel(QWidget *parent) :
PanelWidget(QStringLiteral("ProjectPanel"), parent)
ProjectPanel::ProjectPanel(const QString &unique_name) :
PanelWidget(unique_name)
{
// Create main widget and its layout
QWidget* central_widget = new QWidget(this);
@@ -83,7 +83,6 @@ void ProjectPanel::set_project(Project* p)
if (project()) {
disconnect(project(), &Project::NameChanged, this, &ProjectPanel::UpdateSubtitle);
disconnect(project(), &Project::NameChanged, this, &ProjectPanel::ProjectNameChanged);
disconnect(project(), &Project::ModifiedChanged, this, &ProjectPanel::setWindowModified);
}
explorer_->set_project(p);
@@ -91,18 +90,11 @@ void ProjectPanel::set_project(Project* p)
if (project()) {
connect(project(), &Project::NameChanged, this, &ProjectPanel::UpdateSubtitle);
connect(project(), &Project::NameChanged, this, &ProjectPanel::ProjectNameChanged);
connect(project(), &Project::ModifiedChanged, this, &ProjectPanel::setWindowModified);
}
UpdateSubtitle();
emit ProjectNameChanged();
if (p) {
setWindowModified(p->is_modified());
} else {
setWindowModified(false);
}
}
Folder *ProjectPanel::get_root() const
@@ -197,7 +189,7 @@ void ProjectPanel::ShowNewMenu()
void ProjectPanel::UpdateSubtitle()
{
if (project()) {
QString project_title = QStringLiteral("[*]%1").arg(project()->name());
QString project_title = QStringLiteral("%1").arg(project()->name());
if (explorer_->get_root() != project()->root()) {
QString folder_path;
+1 -1
View File
@@ -35,7 +35,7 @@ class ProjectPanel : public PanelWidget, public FootageManagementPanel
{
Q_OBJECT
public:
ProjectPanel(QWidget* parent);
ProjectPanel(const QString &unique_name);
Project* project() const;
void set_project(Project* p);
+3 -3
View File
@@ -26,11 +26,11 @@
namespace olive {
ScopePanel::ScopePanel(QWidget* parent) :
PanelWidget(QStringLiteral("ScopePanel"), parent),
ScopePanel::ScopePanel() :
PanelWidget(QStringLiteral("ScopePanel")),
viewer_(nullptr)
{
QWidget* central = new QWidget();
QWidget* central = new QWidget(this);
setWidget(central);
QVBoxLayout* layout = new QVBoxLayout(central);
+1 -1
View File
@@ -42,7 +42,7 @@ public:
kTypeCount
};
ScopePanel(QWidget* parent = nullptr);
ScopePanel();
void SetType(Type t);
+2 -2
View File
@@ -23,8 +23,8 @@
namespace olive {
SequenceViewerPanel::SequenceViewerPanel(QWidget *parent) :
ViewerPanel(QStringLiteral("SequenceViewerPanel"), parent)
SequenceViewerPanel::SequenceViewerPanel() :
ViewerPanel(QStringLiteral("SequenceViewerPanel"))
{
// Set strings
Retranslate();
+1 -1
View File
@@ -29,7 +29,7 @@ class SequenceViewerPanel : public ViewerPanel
{
Q_OBJECT
public:
SequenceViewerPanel(QWidget* parent);
SequenceViewerPanel();
public slots:
void StartCapture(const TimeRange &time, const Track::Reference &track);
+3 -3
View File
@@ -22,10 +22,10 @@
namespace olive {
NodeTablePanel::NodeTablePanel(QWidget* parent) :
TimeBasedPanel(QStringLiteral("NodeTablePanel"), parent)
NodeTablePanel::NodeTablePanel() :
TimeBasedPanel(QStringLiteral("NodeTablePanel"))
{
SetTimeBasedWidget(new NodeTableWidget());
SetTimeBasedWidget(new NodeTableWidget(this));
Retranslate();
}
+1 -1
View File
@@ -30,7 +30,7 @@ class NodeTablePanel : public TimeBasedPanel
{
Q_OBJECT
public:
NodeTablePanel(QWidget* parent);
NodeTablePanel();
public slots:
void SelectNodes(const QVector<Node*>& nodes)
+2 -2
View File
@@ -24,8 +24,8 @@
namespace olive {
TaskManagerPanel::TaskManagerPanel(QWidget* parent) :
PanelWidget(QStringLiteral("TaskManagerPanel"), parent)
TaskManagerPanel::TaskManagerPanel() :
PanelWidget(QStringLiteral("TaskManagerPanel"))
{
// Create task view
view_ = new TaskView(this);
+1 -1
View File
@@ -33,7 +33,7 @@ class TaskManagerPanel : public PanelWidget
{
Q_OBJECT
public:
TaskManagerPanel(QWidget* parent);
TaskManagerPanel();
private:
virtual void Retranslate() override;
+2 -2
View File
@@ -22,8 +22,8 @@
namespace olive {
TimeBasedPanel::TimeBasedPanel(const QString &object_name, QWidget *parent) :
PanelWidget(object_name, parent),
TimeBasedPanel::TimeBasedPanel(const QString &object_name) :
PanelWidget(object_name),
widget_(nullptr),
show_and_raise_on_connect_(false)
{
+1 -1
View File
@@ -30,7 +30,7 @@ class TimeBasedPanel : public PanelWidget
{
Q_OBJECT
public:
TimeBasedPanel(const QString& object_name, QWidget *parent = nullptr);
TimeBasedPanel(const QString& object_name);
virtual ~TimeBasedPanel() override;
+3 -3
View File
@@ -25,10 +25,10 @@
namespace olive {
TimelinePanel::TimelinePanel(QWidget *parent) :
TimeBasedPanel(QStringLiteral("TimelinePanel"), parent)
TimelinePanel::TimelinePanel(const QString &name) :
TimeBasedPanel(name)
{
TimelineWidget* tw = new TimelineWidget();
TimelineWidget* tw = new TimelineWidget(this);
SetTimeBasedWidget(tw);
Retranslate();
+1 -1
View File
@@ -33,7 +33,7 @@ class TimelinePanel : public TimeBasedPanel
{
Q_OBJECT
public:
TimelinePanel(QWidget* parent);
TimelinePanel(const QString &name);
inline TimelineWidget *timeline_widget() const
{
+2 -2
View File
@@ -25,8 +25,8 @@
namespace olive {
ToolPanel::ToolPanel(QWidget *parent) :
PanelWidget(QStringLiteral("ToolPanel"), parent)
ToolPanel::ToolPanel() :
PanelWidget(QStringLiteral("ToolPanel"))
{
Toolbar* t = new Toolbar(this);
+1 -1
View File
@@ -32,7 +32,7 @@ class ToolPanel : public PanelWidget
{
Q_OBJECT
public:
ToolPanel(QWidget* parent);
ToolPanel();
private:
virtual void Retranslate() override;
+3 -3
View File
@@ -22,11 +22,11 @@
namespace olive {
ViewerPanel::ViewerPanel(const QString &object_name, QWidget *parent) :
ViewerPanelBase(object_name, parent)
ViewerPanel::ViewerPanel(const QString &object_name) :
ViewerPanelBase(object_name)
{
// Set ViewerWidget as the central widget
ViewerWidget* vw = new ViewerWidget();
ViewerWidget* vw = new ViewerWidget(this);
SetViewerWidget(vw);
// Set strings
+1 -5
View File
@@ -33,11 +33,7 @@ namespace olive {
class ViewerPanel : public ViewerPanelBase {
Q_OBJECT
public:
ViewerPanel(const QString& object_name, QWidget* parent);
ViewerPanel(QWidget *parent) :
ViewerPanel(QStringLiteral("ViewerPanel"), parent)
{
}
ViewerPanel(const QString& object_name);
protected:
virtual void Retranslate() override;
+2 -2
View File
@@ -26,8 +26,8 @@ namespace olive {
#define super TimeBasedPanel
ViewerPanelBase::ViewerPanelBase(const QString& object_name, QWidget *parent) :
super(object_name, parent)
ViewerPanelBase::ViewerPanelBase(const QString& object_name) :
super(object_name)
{
connect(PanelManager::instance(), &PanelManager::FocusedPanelChanged, this, &ViewerPanelBase::FocusedPanelChanged);
}
+1 -1
View File
@@ -31,7 +31,7 @@ class ViewerPanelBase : public TimeBasedPanel
{
Q_OBJECT
public:
ViewerPanelBase(const QString& object_name, QWidget* parent = nullptr);
ViewerPanelBase(const QString& object_name);
ViewerWidget *GetViewerWidget() const
{
+2 -1
View File
@@ -36,7 +36,8 @@ const int kMaximumSmoothness = 8;
QVector<AudioMonitor*> AudioMonitor::instances_;
AudioMonitor::AudioMonitor() :
AudioMonitor::AudioMonitor(QWidget *parent) :
QOpenGLWidget(parent),
waveform_(nullptr),
cached_channels_(0)
{
+1 -1
View File
@@ -35,7 +35,7 @@ class AudioMonitor : public QOpenGLWidget
{
Q_OBJECT
public:
AudioMonitor();
AudioMonitor(QWidget *parent = nullptr);
virtual ~AudioMonitor() override;
@@ -495,12 +495,12 @@ void ProjectExplorer::ReplaceSelectedFootage()
void ProjectExplorer::OpenContextMenuItemInNewTab()
{
Core::instance()->main_window()->OpenFolder(project(), static_cast<Folder*>(context_menu_items_.first()), false);
Core::instance()->main_window()->OpenFolder(static_cast<Folder*>(context_menu_items_.first()), false);
}
void ProjectExplorer::OpenContextMenuItemInNewWindow()
{
Core::instance()->main_window()->OpenFolder(project(), static_cast<Folder*>(context_menu_items_.first()), true);
Core::instance()->main_window()->OpenFolder(static_cast<Folder*>(context_menu_items_.first()), true);
}
void ProjectExplorer::ContextMenuStartProxy(QAction *a)
+1 -6
View File
@@ -188,8 +188,6 @@ MainMenu::MainMenu(MainWindow *parent) :
window_menu_ = new Menu(this, this, &MainMenu::WindowMenuAboutToShow);
window_menu_separator_ = window_menu_->addSeparator();
window_maximize_panel_item_ = window_menu_->AddItem("maximizepanel", parent, &MainWindow::ToggleMaximizedPanel, tr("`"));
window_lock_layout_item_ = window_menu_->AddItem("lockpanels", PanelManager::instance(), &PanelManager::SetPanelsLocked);
window_lock_layout_item_->setCheckable(true);
window_menu_->addSeparator();
window_reset_layout_item_ = window_menu_->AddItem("resetdefaultlayout", parent, &MainWindow::SetDefaultLayout);
@@ -403,7 +401,7 @@ void MainMenu::WindowMenuAboutToShow()
// Alphabetize actions - keeps actions in a consistent order since PanelManager::panels() is
// ordered from most recently focused to least, which may be confusing user experience.
foreach (PanelWidget* panel, PanelManager::instance()->panels()) {
QAction* panel_action = panel->toggleViewAction();
QAction* panel_action = panel->toggleAction();
bool inserted = false;
@@ -422,8 +420,6 @@ void MainMenu::WindowMenuAboutToShow()
// Add new items
window_menu_->insertActions(window_menu_separator_, panel_actions);
window_lock_layout_item_->setChecked(PanelManager::instance()->ArePanelsLocked());
}
void MainMenu::PopulateOpenRecent()
@@ -757,7 +753,6 @@ void MainMenu::Retranslate()
// Window menu
window_menu_->setTitle(tr("&Window"));
window_maximize_panel_item_->setText(tr("Maximize Panel"));
window_lock_layout_item_->setText(tr("Lock Panels"));
window_reset_layout_item_->setText(tr("Reset to Default Layout"));
// Tools menu
-1
View File
@@ -262,7 +262,6 @@ private:
Menu* window_menu_;
QAction* window_menu_separator_;
QAction* window_maximize_panel_item_;
QAction* window_lock_layout_item_;
QAction* window_reset_layout_item_;
Menu* tools_menu_;
+107 -128
View File
@@ -36,8 +36,10 @@
namespace olive {
#define super KDDockWidgets::MainWindow
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
super(QStringLiteral("OliveMain"), KDDockWidgets::MainWindowOption_None, parent),
project_(nullptr)
{
// Resizes main window to desktop geometry on startup. Fixes the following issues:
@@ -57,18 +59,6 @@ MainWindow::MainWindow(QWidget *parent) :
first_show_ = true;
// Create empty central widget - we don't actually want a central widget (so we set its maximum
// size to 0,0) but some of Qt's docking/undocking fails without it
QWidget* centralWidget = new QWidget(this);
centralWidget->setMaximumSize(QSize(0, 0));
setCentralWidget(centralWidget);
// Set tabs to be on top of panels (default behavior is bottom)
setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
// Allow panels to be tabbed within each other
setDockNestingEnabled(true);
// Create and set main menu
MainMenu* main_menu = new MainMenu(this);
setMenuBar(main_menu);
@@ -82,19 +72,19 @@ MainWindow::MainWindow(QWidget *parent) :
setStatusBar(status_bar);
// Create standard panels
node_panel_ = new NodePanel(this);
footage_viewer_panel_ = new FootageViewerPanel(this);
param_panel_ = new ParamPanel(this);
curve_panel_ = new CurvePanel(this);
sequence_viewer_panel_ = new SequenceViewerPanel(this);
multicam_panel_ = new MulticamPanel(this);
pixel_sampler_panel_ = new PixelSamplerPanel(this);
project_panel_ = new ProjectPanel(this);
tool_panel_ = new ToolPanel(this);
task_man_panel_ = new TaskManagerPanel(this);
node_panel_ = new NodePanel();
footage_viewer_panel_ = new FootageViewerPanel();
param_panel_ = new ParamPanel();
curve_panel_ = new CurvePanel();
sequence_viewer_panel_ = new SequenceViewerPanel();
multicam_panel_ = new MulticamPanel();
pixel_sampler_panel_ = new PixelSamplerPanel();
project_panel_ = new ProjectPanel(QStringLiteral("ProjectPanel"));
tool_panel_ = new ToolPanel();
task_man_panel_ = new TaskManagerPanel();
AppendTimelinePanel();
audio_monitor_panel_ = new AudioMonitorPanel(this);
scope_panel_ = new ScopePanel(this);
audio_monitor_panel_ = new AudioMonitorPanel();
scope_panel_ = new ScopePanel();
// Make node-related connections
connect(node_panel_, &NodePanel::NodeSelectionChangedWithContexts, param_panel_, &ParamPanel::SetSelectedNodes);
@@ -137,7 +127,7 @@ MainWindow::~MainWindow()
void MainWindow::LoadLayout(const MainWindowLayoutInfo &info)
{
foreach (Folder* folder, info.open_folders()) {
OpenFolder(folder->project(), folder, true);
OpenFolder(folder, true);
}
foreach (Sequence *sequence, info.open_sequences()) {
@@ -155,34 +145,52 @@ void MainWindow::LoadLayout(const MainWindowLayoutInfo &info)
}
}
restoreState(info.state());
KDDockWidgets::LayoutSaver().restoreLayout(qUncompress(info.state()));
}
QString TransformNameForSerialization(const QString &unique, int i)
{
return QStringLiteral("%1:%2").arg(unique.split(':').at(0), QString::number(i));
}
void CorrectPanelDataIfNecessary(const QString &unique_name, int index, MainWindowLayoutInfo &info, QByteArray &layout)
{
QString corrected = TransformNameForSerialization(unique_name, index);
if (corrected != unique_name) {
info.move_panel_data(unique_name, corrected);
layout.replace(unique_name.toUtf8(), corrected.toUtf8());
}
}
MainWindowLayoutInfo MainWindow::SaveLayout() const
{
MainWindowLayoutInfo info;
foreach (ProjectPanel* panel, folder_panels_) {
if (panel->project()) {
info.add_folder(panel->get_root());
}
}
foreach (TimelinePanel* panel, timeline_panels_) {
if (panel->GetConnectedViewer()) {
info.add_sequence(panel->GetSequence());
}
}
for (auto it=viewer_panels_.cbegin(); it!=viewer_panels_.cend(); it++) {
info.add_viewer((*it)->GetConnectedViewer());
}
QByteArray layout = premaximized_state_.isEmpty() ? KDDockWidgets::LayoutSaver().serializeLayout() : premaximized_state_;
foreach (PanelWidget *panel, PanelManager::instance()->panels()) {
info.set_panel_data(panel->objectName(), panel->SaveData());
info.set_panel_data(panel->uniqueName(), panel->SaveData());
}
info.set_state(premaximized_state_.isEmpty() ? this->saveState() : premaximized_state_);
for (int i = 0; i < folder_panels_.size(); i++) {
auto panel = folder_panels_.at(i);
info.add_folder(panel->get_root());
CorrectPanelDataIfNecessary(panel->uniqueName(), i, info, layout);
}
for (int i = 0; i < timeline_panels_.size(); i++) {
auto panel = timeline_panels_.at(i);
info.add_sequence(panel->GetSequence());
CorrectPanelDataIfNecessary(panel->uniqueName(), i, info, layout);
}
for (int i = 0; i < viewer_panels_.size(); i++) {
auto panel = viewer_panels_.at(i);
info.add_viewer(panel->GetConnectedViewer());
CorrectPanelDataIfNecessary(panel->uniqueName(), i, info, layout);
}
info.set_state(qCompress(layout));
return info;
}
@@ -241,17 +249,17 @@ bool MainWindow::IsSequenceOpen(Sequence *sequence) const
return false;
}
void MainWindow::OpenFolder(Project* p, Folder *i, bool floating)
void MainWindow::OpenFolder(Folder *i, bool floating)
{
ProjectPanel* panel = AppendPanelInternal(folder_panels_);
ProjectPanel* panel = AppendPanelInternal(QStringLiteral("FolderPanel"), folder_panels_);
panel->set_project(p);
panel->set_project(i->project());
panel->set_root(i);
if (floating) {
panel->setFloating(floating);
} else {
tabifyDockWidget(project_panel_, panel);
project_panel_->addDockWidgetAsTab(panel);
}
// If the panel is closed, just destroy it
@@ -275,17 +283,12 @@ void MainWindow::OpenNodeInViewer(ViewerOutput *node)
existing->raise();
} else {
// Create a viewer for this node
ViewerPanel* viewer = new ViewerPanel(this);
ViewerPanel* viewer = AppendPanelInternal(QStringLiteral("ViewerPanel"), viewer_panels_);
viewer->SetSignalInsteadOfClose(true);
viewer->setFloating(true);
viewer->setVisible(true);
viewer->ConnectViewerNode(node);
connect(viewer, &ViewerPanel::CloseRequested, this, &MainWindow::ViewerCloseRequested);
connect(node, &ViewerOutput::RemovedFromGraph, this, &MainWindow::ViewerWithPanelRemovedFromGraph);
viewer_panels_.append(viewer);
}
}
@@ -300,6 +303,8 @@ void MainWindow::SetFullscreen(bool fullscreen)
void MainWindow::ToggleMaximizedPanel()
{
KDDockWidgets::LayoutSaver saver;
if (premaximized_state_.isEmpty()) {
// Assume nothing is maximized at the moment
@@ -322,12 +327,12 @@ void MainWindow::ToggleMaximizedPanel()
}
// Save the current state so it can be restored later
premaximized_state_ = saveState();
premaximized_state_ = saver.serializeLayout();
// For every other panel that is on the main window, hide it
foreach (PanelWidget* panel, PanelManager::instance()->panels()) {
if (!panel->isFloating() && panel != currently_hovered) {
panel->setVisible(false);
panel->close();
}
}
} else {
@@ -336,7 +341,7 @@ void MainWindow::ToggleMaximizedPanel()
// Assume we are currently maximized, restore the state
PanelManager::instance()->SetSuppressChangedSignal(true);
restoreState(premaximized_state_);
saver.restoreLayout(premaximized_state_);
premaximized_state_.clear();
currently_focused_panel->raise();
@@ -593,16 +598,17 @@ void MainWindow::FolderPanelCloseRequested()
{
ProjectPanel* panel = static_cast<ProjectPanel*>(sender());
RemovePanelInternal(folder_panels_, panel);
removeDockWidget(panel);
panel->deleteLater();
}
TimelinePanel* MainWindow::AppendTimelinePanel()
{
TimelinePanel* panel = AppendPanelInternal(timeline_panels_);
TimelinePanel* panel = AppendPanelInternal(QStringLiteral("TimelinePanel"), timeline_panels_);
if (!timeline_panels_.isEmpty()) {
tabifyDockWidget(timeline_panels_.last(), panel);
if (timeline_panels_.size() > 1) {
timeline_panels_.last()->addDockWidgetAsTab(panel);
} else {
panel->SetSignalInsteadOfClose(false);
}
connect(panel, &PanelWidget::CloseRequested, this, &MainWindow::TimelineCloseRequested);
@@ -734,7 +740,6 @@ void MainWindow::SaveCustomShortcuts()
} else {
qCritical() << "Failed to save custom keyboard shortcuts";
}
}
void MainWindow::UpdateAudioMonitorParams(ViewerOutput *viewer)
@@ -804,62 +809,52 @@ void MainWindow::FocusedPanelChanged(PanelWidget *panel)
void MainWindow::SetDefaultLayout()
{
footage_viewer_panel_->show();
addDockWidget(Qt::TopDockWidgetArea, footage_viewer_panel_);
KDDockWidgets::InitialOption o;
o.preferredSize = QSize(0, centralAreaGeometry().height());
param_panel_->show();
tabifyDockWidget(footage_viewer_panel_, param_panel_);
node_panel_->show();
tabifyDockWidget(param_panel_, node_panel_);
// Top left - Tabify footage viewer, param panel, and node panel
addDockWidget(footage_viewer_panel_, KDDockWidgets::Location_OnTop, nullptr, o);
footage_viewer_panel_->addDockWidgetAsTab(param_panel_);
footage_viewer_panel_->addDockWidgetAsTab(node_panel_);
param_panel_->raise();
curve_panel_->hide();
curve_panel_->setFloating(true);
addDockWidget(Qt::TopDockWidgetArea, curve_panel_);
// Top right - sequence viewer
addDockWidget(sequence_viewer_panel_, KDDockWidgets::Location_OnRight, footage_viewer_panel_, o);
scope_panel_->hide();
scope_panel_->setFloating(true);
addDockWidget(Qt::TopDockWidgetArea, scope_panel_);
// Bottom center - timelines
addDockWidget(timeline_panels_.first(), KDDockWidgets::Location_OnBottom);
multicam_panel_->hide();
multicam_panel_->setFloating(true);
addDockWidget(Qt::TopDockWidgetArea, multicam_panel_);
// Left of timeline - tool panel
o.preferredSize = QSize(1, 0);
addDockWidget(tool_panel_, KDDockWidgets::Location_OnLeft, timeline_panels_.first(), o);
sequence_viewer_panel_->show();
addDockWidget(Qt::TopDockWidgetArea, sequence_viewer_panel_);
// Right of timeline - audio monitor
addDockWidget(audio_monitor_panel_, KDDockWidgets::Location_OnRight, timeline_panels_.first(), o);
pixel_sampler_panel_->hide();
pixel_sampler_panel_->setFloating(true);
addDockWidget(Qt::TopDockWidgetArea, pixel_sampler_panel_);
// Bottom left - project panel
addDockWidget(project_panel_, KDDockWidgets::Location_OnLeft, tool_panel_);
project_panel_->show();
addDockWidget(Qt::BottomDockWidgetArea, project_panel_);
// Hidden panels
pixel_sampler_panel_->close();
task_man_panel_->close();
curve_panel_->close();
scope_panel_->close();
multicam_panel_->close();
for (auto it = folder_panels_.cbegin(); it != folder_panels_.cend(); it++) {
(*it)->close();
}
for (auto it = viewer_panels_.cbegin(); it != viewer_panels_.cend(); it++) {
(*it)->close();
}
for (auto it = timeline_panels_.cbegin(); it != timeline_panels_.cend(); it++) {
auto p = *it;
if (p != timeline_panels_.first()) {
p->addDockWidgetAsTab(p);
}
}
tool_panel_->show();
addDockWidget(Qt::BottomDockWidgetArea, tool_panel_);
timeline_panels_.first()->show();
addDockWidget(Qt::BottomDockWidgetArea, timeline_panels_.first());
task_man_panel_->hide();
task_man_panel_->setFloating(true);
addDockWidget(Qt::BottomDockWidgetArea, task_man_panel_);
audio_monitor_panel_->show();
addDockWidget(Qt::BottomDockWidgetArea, audio_monitor_panel_);
resizeDocks({param_panel_, sequence_viewer_panel_},
{width()/2, width()/2},
Qt::Horizontal);
resizeDocks({project_panel_, tool_panel_, timeline_panels_.first(), audio_monitor_panel_},
{width()/4, 1, width(), 1},
Qt::Horizontal);
resizeDocks({node_panel_, project_panel_},
{height()/2, height()/2},
Qt::Vertical);
// Set to unmaximized panels
premaximized_state_.clear();
}
void MainWindow::showEvent(QShowEvent *e)
@@ -889,24 +884,15 @@ void MainWindow::showEvent(QShowEvent *e)
}
}
void UpdatePanelName(PanelWidget *panel, int index)
{
QString old_name = panel->objectName();
QString new_name = QStringLiteral("%1:%2").arg(old_name.split(':').at(0), QString::number(index));
qDebug() << "renaming" << old_name << "to" << new_name;
panel->setObjectName(new_name);
}
template<typename T>
T *MainWindow::AppendPanelInternal(QList<T*>& list)
T *MainWindow::AppendPanelInternal(const QString &panel_name, QList<T*>& list)
{
T* panel = new T(this);
T* panel = new T(TransformNameForSerialization(panel_name, list.size()));
// For some reason raise() on its own doesn't do anything, we need both
panel->show();
panel->raise();
UpdatePanelName(panel, list.size());
list.append(panel);
// Let us handle the panel closing rather than the panel itself
@@ -918,14 +904,7 @@ T *MainWindow::AppendPanelInternal(QList<T*>& list)
template<typename T>
void MainWindow::RemovePanelInternal(QList<T *> &list, T *panel)
{
int index = list.indexOf(panel);
if (index != -1) {
list.removeAt(index);
for (int i = index; i < list.size(); i++) {
UpdatePanelName(list.at(i), i);
}
}
list.removeOne(panel);
}
}
+5 -4
View File
@@ -21,7 +21,8 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <kddockwidgets/Config.h>
#include <kddockwidgets/MainWindow.h>
#include "mainwindowlayoutinfo.h"
#include "node/project/project.h"
@@ -50,7 +51,7 @@ namespace olive {
/**
* @brief Olive's main window responsible for docking widgets and the main menu bar.
*/
class MainWindow : public QMainWindow
class MainWindow : public KDDockWidgets::MainWindow
{
Q_OBJECT
public:
@@ -68,7 +69,7 @@ public:
bool IsSequenceOpen(Sequence* sequence) const;
void OpenFolder(Project* p, Folder *i, bool floating);
void OpenFolder(Folder *i, bool floating);
void OpenNodeInViewer(ViewerOutput* node);
@@ -117,7 +118,7 @@ private:
TimelinePanel* AppendTimelinePanel();
template <typename T>
T* AppendPanelInternal(QList<T*>& list);
T* AppendPanelInternal(const QString &panel_name, QList<T*>& list);
template <typename T>
void RemovePanelInternal(QList<T*>& list, T *panel);
@@ -176,6 +176,13 @@ void MainWindowLayoutInfo::set_panel_data(const QString &id, const PanelWidget::
panel_data_[id] = data;
}
void MainWindowLayoutInfo::move_panel_data(const QString &old, const QString &now)
{
PanelWidget::Info tmp = panel_data_.at(old);
panel_data_.erase(old);
panel_data_[now] = tmp;
}
void MainWindowLayoutInfo::set_state(const QByteArray &layout)
{
state_ = layout;
@@ -24,6 +24,8 @@ public:
void set_panel_data(const QString &id, const PanelWidget::Info &data);
void move_panel_data(const QString &old, const QString &now);
void set_state(const QByteArray& layout);
const std::vector<Folder*>& open_folders() const