From dc860b69b03b88ab7d57b0d659340faaae7a9f0c Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Thu, 26 Aug 2021 14:06:54 +0200 Subject: [PATCH] UI: Add clean title bars for dock widgets (transparent to avoid some ugly spaces on the right side) --- src/UI/DockWidgetTitleBar.cc | 68 ++++++++++++++++++++++++++++++++++++ src/UI/DockWidgetTitleBar.hh | 26 ++++++++++++++ src/UI/VivyDocumentView.cc | 13 +++---- 3 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 src/UI/DockWidgetTitleBar.cc create mode 100644 src/UI/DockWidgetTitleBar.hh diff --git a/src/UI/DockWidgetTitleBar.cc b/src/UI/DockWidgetTitleBar.cc new file mode 100644 index 00000000..5fdc2719 --- /dev/null +++ b/src/UI/DockWidgetTitleBar.cc @@ -0,0 +1,68 @@ +#include "DockWidgetTitleBar.hh" + +#include <QLabel> +#include <QHBoxLayout> +#include <QPushButton> + +using namespace Vivy; + +DockWidgetTitleBar::DockWidgetTitleBar(QDockWidget *parent) noexcept + : QWidget(parent) + , attachedDock(parent) +{ + if (parent == nullptr) + qFatal("Can't pass a nullptr as a parent widget pointer"); + + auto *box = new QHBoxLayout(this); + box->addWidget(new QLabel(parent->windowTitle(), this)); + qobject_cast<QHBoxLayout *>(layout())->setStretch(0, 1); +} + +void +DockWidgetTitleBar::handleFeaturesChanged(QDockWidget::DockWidgetFeatures feature) noexcept +{ + clearControls(); + + if (feature & QDockWidget::DockWidgetFloatable) { + QPushButton *const button = new QPushButton("float", this); + button->setEnabled(true); + connect(button, &QPushButton::clicked, attachedDock, + [this](bool) { attachedDock->setFloating(!attachedDock->isFloating()); }); + layout()->addWidget(button); + } + + if (feature & QDockWidget::DockWidgetClosable) { + QPushButton *const button = new QPushButton("close", this); + button->setEnabled(true); + connect(button, &QPushButton::clicked, attachedDock, [this](bool) { + QAction *const act = attachedDock->toggleViewAction(); + Q_ASSERT(act->isCheckable()); + act->trigger(); + }); + layout()->addWidget(button); + } +} + +void +DockWidgetTitleBar::clearControls() noexcept +{ + QHBoxLayout *const box = qobject_cast<QHBoxLayout *>(layout()); + QLayoutItem *item = nullptr; + + for (int i = 1; i < box->count(); ++i) { + item = box->takeAt(i); + delete item->widget(); + delete item; + } +} + +void +DockWidgetTitleBar::addToDock(QDockWidget *const dock) noexcept +{ + DockWidgetTitleBar *const titleBar = new DockWidgetTitleBar(dock); + Utils::setTransparentBackgroundForWidget(titleBar); + connect(dock, &QDockWidget::featuresChanged, titleBar, + &DockWidgetTitleBar::handleFeaturesChanged); + dock->setTitleBarWidget(titleBar); + titleBar->handleFeaturesChanged(dock->features()); +} diff --git a/src/UI/DockWidgetTitleBar.hh b/src/UI/DockWidgetTitleBar.hh new file mode 100644 index 00000000..97c2ad6d --- /dev/null +++ b/src/UI/DockWidgetTitleBar.hh @@ -0,0 +1,26 @@ +#pragma once + +#include "Utils.hh" +#include "../Lib/Utils.hh" + +class QDockWidget; + +namespace Vivy +{ +class DockWidgetTitleBar final : public QWidget { + Q_OBJECT + VIVY_UNMOVABLE_OBJECT(DockWidgetTitleBar) + + QDockWidget *attachedDock{ nullptr }; + QDockWidget::DockWidgetFeature currentFeatures{ QDockWidget::NoDockWidgetFeatures }; + + explicit DockWidgetTitleBar(QDockWidget *parent) noexcept; + void handleFeaturesChanged(QDockWidget::DockWidgetFeatures) noexcept; + void clearControls() noexcept; + void addCloseButton() noexcept; + void addFloatButton() noexcept; + +public: + static void addToDock(QDockWidget *const) noexcept; +}; +} diff --git a/src/UI/VivyDocumentView.cc b/src/UI/VivyDocumentView.cc index 0f36c52b..3bbf3a9e 100644 --- a/src/UI/VivyDocumentView.cc +++ b/src/UI/VivyDocumentView.cc @@ -1,5 +1,6 @@ #include "VivyDocumentView.hh" #include "PropertyModel.hh" +#include "DockWidgetTitleBar.hh" #include "Utils.hh" #include "DocumentViews/AudioVisualizer.hh" #include "DocumentViews/AssLinesView.hh" @@ -92,8 +93,7 @@ VivyDocumentView::loadVideoView() noexcept QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetClosable); addDockWidget(Qt::BottomDockWidgetArea, videoView, Qt::Vertical); - videoView->setTitleBarWidget(new QWidget(this)); - Utils::setTransparentBackgroundForWidget(videoView->titleBarWidget()); + DockWidgetTitleBar::addToDock(videoView); } // Kubat: because the dock is "closable", when closed the widget itself @@ -115,8 +115,7 @@ VivyDocumentView::loadAssView() noexcept assLines->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); addDockWidget(Qt::BottomDockWidgetArea, assLines, Qt::Vertical); - assLines->setTitleBarWidget(new QWidget(this)); - Utils::setTransparentBackgroundForWidget(assLines->titleBarWidget()); + DockWidgetTitleBar::addToDock(assLines); } assModel.reset(new AssLinesModel(document->getAssSubDocument()->getLines())); @@ -147,8 +146,7 @@ VivyDocumentView::loadAudioView() noexcept visualizer->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable); addDockWidget(Qt::LeftDockWidgetArea, visualizer, Qt::Horizontal); - visualizer->setTitleBarWidget(new QWidget(this)); - Utils::setTransparentBackgroundForWidget(visualizer->titleBarWidget()); + DockWidgetTitleBar::addToDock(visualizer); } // Kubat: don't check, may throw an error but don't think we can @@ -196,8 +194,7 @@ VivyDocumentView::openProperties() noexcept property = new QDockWidget("Properties", this); property->setAllowedAreas(Qt::AllDockWidgetAreas); addDockWidget(Qt::RightDockWidgetArea, property, Qt::Vertical); - property->setTitleBarWidget(new QWidget(this)); - Utils::setTransparentBackgroundForWidget(property->titleBarWidget()); + DockWidgetTitleBar::addToDock(property); } property->setWidget(view); -- GitLab