fixed changing orientation for toolbars

This commit is contained in:
Eism 2021-05-19 17:19:40 +02:00 committed by Roman Pudashkin
parent 79c3ed1aeb
commit 27d839e3be
17 changed files with 183 additions and 86 deletions

View file

@ -158,10 +158,8 @@ DockPage {
width: root.width
height: root.toolBarHeight
minimumWidth: orientation == Qt.Horizontal ? 720 : root.toolBarHeight
maximumWidth: orientation == Qt.Horizontal ? 100500 : 96
minimumHeight: orientation == Qt.Horizontal ? root.toolBarHeight : 400
maximumHeight: orientation == Qt.Horizontal ? root.toolBarHeight : 100500
horizontalPreferredSize: Qt.size(720, root.toolBarHeight)
verticalPreferredSize: Qt.size(root.toolBarHeight, 400)
allowedAreas: { Qt.AllDockWidgetAreas }

View file

@ -464,6 +464,17 @@ const QScreen* DockWindow::screen() const
return m_window->screen();
}
void DockWindow::requestChangeToolBarOrientation(const QString&, framework::Orientation)
{
NOT_IMPLEMENTED;
}
mu::async::Channel<std::pair<QString, mu::framework::Orientation> > DockWindow::toolBarOrientationChangeRequested() const
{
NOT_IMPLEMENTED;
return {};
}
QMenuBar* DockWindow::qMenuBar()
{
#ifdef Q_OS_MAC

View file

@ -77,6 +77,8 @@ public:
bool isFullScreen() const override;
void toggleFullScreen() override;
const QScreen* screen() const override;
void requestChangeToolBarOrientation(const QString& toolBarName, framework::Orientation orientation) override;
async::Channel<std::pair<QString, framework::Orientation> > toolBarOrientationChangeRequested() const override;
public slots:
void setTitle(QString title);

View file

@ -97,6 +97,17 @@ QList<DockStatusBar*> DockPage::statusBars() const
return m_statusBars.list();
}
DockBase* DockPage::dockByName(const QString& dockName) const
{
for (DockBase* dock : allDocks()) {
if (dock->objectName() == dockName) {
return dock;
}
}
return nullptr;
}
void DockPage::setUri(const QString& uri)
{
if (uri == m_uri) {

View file

@ -61,6 +61,7 @@ public:
DockCentral* centralDock() const;
QList<DockPanel*> panels() const;
QList<DockStatusBar*> statusBars() const;
DockBase* dockByName(const QString& dockName) const;
void close();

View file

@ -31,9 +31,12 @@
using namespace mu::dock;
static const qreal TOOLBAR_GRIP_MARGIN(4);
static const qreal TOOLBAR_GRIP_WIDTH(28);
static const qreal TOOLBAR_GRIP_HEIGHT(36);
static const qreal TOOLBAR_GRIP_MARGIN = 4;
static const qreal TOOLBAR_GRIP_WIDTH = 28;
static const qreal TOOLBAR_GRIP_HEIGHT = 36;
static constexpr int MIN_SIDE_SIZE = 48;
static constexpr int MAX_SIDE_SIZE = std::numeric_limits<int>::max();
class DockToolBar::DraggableArea : public KDDockWidgets::QWidgetAdapter, public KDDockWidgets::Draggable
{
@ -131,6 +134,16 @@ void DockToolBar::setDraggableMouseArea(QQuickItem* mouseArea)
m_draggableArea->setMouseArea(mouseArea);
}
QSize DockToolBar::horizontalPreferredSize() const
{
return m_horizontalPreferredSize;
}
QSize DockToolBar::verticalPreferredSize() const
{
return m_verticalPreferredSize;
}
void DockToolBar::setMinimumWidth(int width)
{
if (movable() && orientation() == Qt::Horizontal) {
@ -151,31 +164,25 @@ void DockToolBar::setMinimumHeight(int height)
void DockToolBar::setMaximumWidth(int width)
{
int preferedWidth = this->width();
int preferredWidth = this->width();
if (movable() && orientation() == Qt::Horizontal) {
preferedWidth = TOOLBAR_GRIP_WIDTH + TOOLBAR_GRIP_MARGIN;
}
if (preferedWidth > width) {
width = preferedWidth;
preferredWidth = TOOLBAR_GRIP_WIDTH + TOOLBAR_GRIP_MARGIN;
}
width = std::max(width, preferredWidth);
DockBase::setMaximumWidth(width);
}
void DockToolBar::setMaximumHeight(int height)
{
int preferedHeight = this->height();
int preferredHeight = this->height();
if (movable() && orientation() == Qt::Horizontal) {
preferedHeight = TOOLBAR_GRIP_HEIGHT + TOOLBAR_GRIP_MARGIN;
}
if (preferedHeight > height) {
height = preferedHeight;
preferredHeight = TOOLBAR_GRIP_HEIGHT + TOOLBAR_GRIP_MARGIN;
}
height = std::max(height, preferredHeight);
DockBase::setMaximumHeight(height);
}
@ -199,63 +206,51 @@ void DockToolBar::setOrientation(Qt::Orientation orientation)
emit orientationChanged(orientation);
}
void DockToolBar::updateOrientation()
void DockToolBar::setHorizontalPreferredSize(QSize horizontalPreferredSize)
{
if (dockWidget()->isFloating()) {
if (m_horizontalPreferredSize == horizontalPreferredSize) {
return;
}
Layouting::ItemBoxContainer* container = dockWidget()->frame()->layoutItem()->parentBoxContainer();
if (!container) {
m_horizontalPreferredSize = horizontalPreferredSize;
emit horizontalPreferredSizeChanged(m_horizontalPreferredSize);
}
void DockToolBar::setVerticalPreferredSize(QSize verticalPreferredSize)
{
if (m_verticalPreferredSize == verticalPreferredSize) {
return;
}
if (container->isVertical()) {
setOrientation(Qt::Horizontal);
return;
}
Qt::Orientation newOrientation = Qt::Horizontal;
for (const Layouting::Item* containerItem: container->childItems()) {
auto frame = static_cast<KDDockWidgets::Frame*>(containerItem->guestAsQObject());
if (!frame || frame->dockWidgets().empty()) {
continue;
}
DockType type = readPropertiesFromObject(frame->dockWidgets().first()).type;
if (type == DockType::Central) {
newOrientation = Qt::Vertical;
break;
}
}
setOrientation(newOrientation);
m_verticalPreferredSize = verticalPreferredSize;
emit verticalPreferredSizeChanged(m_verticalPreferredSize);
}
void DockToolBar::componentComplete()
{
DockBase::componentComplete();
connect(dockWidget(), &KDDockWidgets::DockWidgetQuick::parentChanged, [this]() {
if (!dockWidget()) {
return;
}
connect(this, &DockToolBar::orientationChanged, [this](Qt::Orientation orientation) {
QSize preferredSize = this->preferredSize();
KDDockWidgets::Frame* frame = dockWidget()->frame();
if (!frame) {
return;
if (orientation == Qt::Horizontal) {
setSizeConstraints(QSize(preferredSize.width(), MIN_SIDE_SIZE), QSize(MAX_SIDE_SIZE, MIN_SIDE_SIZE));
} else {
setSizeConstraints(QSize(MIN_SIDE_SIZE, preferredSize.height()), QSize(MIN_SIDE_SIZE, MAX_SIDE_SIZE));
}
connect(frame, &KDDockWidgets::Frame::isInMainWindowChanged, this, [this]() {
QTimer::singleShot(0, this, &DockToolBar::updateOrientation);
}, Qt::UniqueConnection);
});
QSize preferredSize = this->preferredSize();
setSizeConstraints(QSize(preferredSize.width(), MIN_SIDE_SIZE), QSize(MAX_SIDE_SIZE, MIN_SIDE_SIZE));
m_draggableArea->setDockWidget(dockWidget());
}
QSize DockToolBar::preferredSize() const
{
return m_orientation == Qt::Horizontal ? horizontalPreferredSize() : verticalPreferredSize();
}
DockType DockToolBar::type() const
{
return DockType::ToolBar;

View file

@ -33,6 +33,10 @@ class DockToolBar : public DockBase
Q_PROPERTY(bool movable READ movable WRITE setMovable NOTIFY movableChanged)
Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
Q_PROPERTY(
QSize horizontalPreferredSize READ horizontalPreferredSize WRITE setHorizontalPreferredSize NOTIFY horizontalPreferredSizeChanged)
Q_PROPERTY(QSize verticalPreferredSize READ verticalPreferredSize WRITE setVerticalPreferredSize NOTIFY verticalPreferredSizeChanged)
public:
explicit DockToolBar(QQuickItem* parent = nullptr);
@ -41,6 +45,9 @@ public:
Q_INVOKABLE void setDraggableMouseArea(QQuickItem* mouseArea);
QSize horizontalPreferredSize() const;
QSize verticalPreferredSize() const;
public slots:
void setMinimumWidth(int width) override;
void setMinimumHeight(int height) override;
@ -50,22 +57,30 @@ public slots:
void setMovable(bool movable);
void setOrientation(Qt::Orientation orientation);
void setHorizontalPreferredSize(QSize horizontalPreferredSize);
void setVerticalPreferredSize(QSize verticalPreferredSize);
signals:
void movableChanged(bool movable);
void orientationChanged(Qt::Orientation orientation);
private slots:
void updateOrientation();
void horizontalPreferredSizeChanged(QSize horizontalPreferredSize);
void verticalPreferredSizeChanged(QSize verticalPreferredSize);
private:
void componentComplete() override;
DockType type() const override;
QSize preferredSize() const;
class DraggableArea;
DraggableArea* m_draggableArea = nullptr;
bool m_movable = true;
Qt::Orientation m_orientation = Qt::Horizontal;
QSize m_horizontalPreferredSize;
QSize m_verticalPreferredSize;
};
}

View file

@ -57,6 +57,15 @@ void DockWindow::componentComplete()
configuration()->windowGeometryChanged().onNotify(this, [this]() {
resetWindowState();
});
mainWindow()->toolBarOrientationChangeRequested().onReceive(this, [this](std::pair<QString, mu::framework::Orientation> orientation) {
const DockPage* page = pageByUri(m_currentPageUri);
DockToolBar* toolBar = page ? dynamic_cast<DockToolBar*>(page->dockByName(orientation.first)) : nullptr;
if (toolBar) {
toolBar->setOrientation(static_cast<Qt::Orientation>(orientation.second));
}
});
}
QString DockWindow::currentPageUri() const

View file

@ -32,6 +32,7 @@
#include "modularity/ioc.h"
#include "async/asyncable.h"
#include "ui/iuiconfiguration.h"
#include "ui/imainwindow.h"
namespace KDDockWidgets {
class MainWindowBase;
@ -52,6 +53,7 @@ class DockWindow : public QQuickItem, public async::Asyncable
Q_PROPERTY(QQmlListProperty<mu::dock::DockPage> pages READ pagesProperty)
INJECT(dock, ui::IUiConfiguration, configuration)
INJECT(dock, ui::IMainWindow, mainWindow)
public:
explicit DockWindow(QQuickItem* parent = nullptr);

View file

@ -22,10 +22,13 @@
#include "dockbase.h"
#include <QRect>
#include "log.h"
#include "thirdparty/KDDockWidgets/src/DockWidgetQuick.h"
#include "thirdparty/KDDockWidgets/src/private/Frame_p.h"
#include "thirdparty/KDDockWidgets/src/private/FloatingWindow_p.h"
using namespace mu::dock;
@ -81,6 +84,22 @@ KDDockWidgets::DockWidgetQuick* DockBase::dockWidget() const
return m_dockWidget;
}
void DockBase::setSizeConstraints(const QSize& minimumSize, const QSize& maximumSize)
{
m_dockWidget->setMinimumSize(minimumSize);
m_dockWidget->setMaximumSize(maximumSize);
if (auto frame = m_dockWidget->frame()) {
frame->setMinimumSize(minimumSize);
frame->setMaximumSize(maximumSize);
}
if (auto floatingWindow = m_dockWidget->floatingWindow()) {
QRect rect(floatingWindow->dragRect().topLeft(), minimumSize);
floatingWindow->setGeometry(rect);
}
}
void DockBase::setTitle(const QString& title)
{
if (title == m_title) {
@ -154,10 +173,6 @@ void DockBase::setFloating(bool floating)
void DockBase::resize()
{
applySizeConstraints();
if (m_dockWidget) {
m_dockWidget->frame()->layoutItem()->parentBoxContainer()->layoutEqually();
}
}
void DockBase::init()
@ -210,13 +225,7 @@ void DockBase::applySizeConstraints()
QSize minimumSize(minWidth, minHeight);
QSize maximumSize(maxWidth, maxHeight);
m_dockWidget->setMinimumSize(minimumSize);
m_dockWidget->setMaximumSize(maximumSize);
if (auto frame = m_dockWidget->frame()) {
frame->setMinimumSize(minimumSize);
frame->setMaximumSize(maximumSize);
}
setSizeConstraints(minimumSize, maximumSize);
}
void DockBase::listenFloatingChanges()

View file

@ -97,6 +97,8 @@ protected:
KDDockWidgets::DockWidgetQuick* dockWidget() const;
void setSizeConstraints(const QSize& minimumSize, const QSize& maximumSize);
private slots:
void resize();

View file

@ -118,22 +118,22 @@ bool DropIndicators::centralIndicatorVisible() const
bool DropIndicators::innerLeftIndicatorVisible() const
{
return isInnerLeftIndicatorVisible(Qt::LeftDockWidgetArea);
return isInnerIndicatorVisible(Qt::LeftDockWidgetArea);
}
bool DropIndicators::innerRightIndicatorVisible() const
{
return isInnerLeftIndicatorVisible(Qt::RightDockWidgetArea);
return isInnerIndicatorVisible(Qt::RightDockWidgetArea);
}
bool DropIndicators::innerTopIndicatorVisible() const
{
return isInnerLeftIndicatorVisible(Qt::TopDockWidgetArea);
return isInnerIndicatorVisible(Qt::TopDockWidgetArea);
}
bool DropIndicators::innerBottomIndicatorVisible() const
{
return isInnerLeftIndicatorVisible(Qt::BottomDockWidgetArea);
return isInnerIndicatorVisible(Qt::BottomDockWidgetArea);
}
bool DropIndicators::hoveringOverDock(DockType type) const
@ -144,7 +144,6 @@ bool DropIndicators::hoveringOverDock(DockType type) const
for (auto dock : m_hoveredFrame->dockWidgets()) {
DockProperties properties = readPropertiesFromObject(dock);
if (properties.type == type) {
return true;
}
@ -158,16 +157,8 @@ bool DropIndicators::isAreaAllowed(Qt::DockWidgetArea area) const
return m_draggedDockProperties.allowedAreas.testFlag(area);
}
bool DropIndicators::isInnerLeftIndicatorVisible(Qt::DockWidgetArea area) const
bool DropIndicators::isInnerIndicatorVisible(Qt::DockWidgetArea area) const
{
if (isToolBar()) {
if (hoveringOverDock(DockType::ToolBar)) {
return true;
} else {
return isAreaAllowed(area);
}
}
if (hoveringOverDock(DockType::Central)) {
return isAreaAllowed(area);
}
@ -180,6 +171,16 @@ bool DropIndicators::isToolBar() const
return m_draggedDockProperties.type == DockType::ToolBar;
}
const KDDockWidgets::DockWidgetBase* DropIndicators::draggedDock() const
{
auto windowBeingDragged = KDDockWidgets::DragController::instance()->windowBeingDragged();
if (!windowBeingDragged || windowBeingDragged->dockWidgets().isEmpty()) {
return nullptr;
}
return windowBeingDragged->dockWidgets().first();
}
bool DropIndicators::onResize(QSize)
{
m_indicatorsWindow->resize(window()->size());
@ -188,7 +189,7 @@ bool DropIndicators::onResize(QSize)
void DropIndicators::updateVisibility()
{
if (isHovered()) {
if (isHovered() && m_hoveredFrame) {
m_indicatorsWindow->setVisible(true);
updateWindowPosition();
m_indicatorsWindow->raise();
@ -255,6 +256,19 @@ void DropIndicators::setDropLocation(DropLocation location)
QRect rect = m_dropArea->rectForDrop(windowBeingDragged, multisplitterLocation,
m_dropArea->itemForFrame(relativeToFrame));
auto draggedDock = this->draggedDock();
if (m_hoveredFrame && isToolBar() && draggedDock) {
QString draggedDockName = draggedDock->uniqueName();
if (hoveringOverDock(DockType::ToolBar)) {
mainWindow()->requestChangeToolBarOrientation(draggedDockName, framework::Orientation::Horizontal);
} else {
mainWindow()->requestChangeToolBarOrientation(draggedDockName, framework::Orientation::Vertical);
}
}
m_rubberBand->setGeometry(rect);
m_rubberBand->setVisible(true);
}

View file

@ -23,7 +23,9 @@
#ifndef MU_DOCK_DROPINDICATORS_H
#define MU_DOCK_DROPINDICATORS_H
#include "modularity/ioc.h"
#include "../docktypes.h"
#include "ui/imainwindow.h"
#include "thirdparty/KDDockWidgets/src/private/DropIndicatorOverlayInterface_p.h"
@ -45,6 +47,8 @@ class DropIndicators : public KDDockWidgets::DropIndicatorOverlayInterface
Q_PROPERTY(bool innerTopIndicatorVisible READ innerTopIndicatorVisible NOTIFY indicatorsVisibilityChanged)
Q_PROPERTY(bool innerBottomIndicatorVisible READ innerBottomIndicatorVisible NOTIFY indicatorsVisibilityChanged)
INJECT(dock, ui::IMainWindow, mainWindow)
public:
explicit DropIndicators(KDDockWidgets::DropArea* dropArea);
~DropIndicators() override;
@ -79,10 +83,12 @@ private:
bool hoveringOverDock(DockType type) const;
bool isAreaAllowed(Qt::DockWidgetArea area) const;
bool isInnerLeftIndicatorVisible(Qt::DockWidgetArea area) const;
bool isInnerIndicatorVisible(Qt::DockWidgetArea area) const;
bool isToolBar() const;
const KDDockWidgets::DockWidgetBase* draggedDock() const;
KDDockWidgets::QWidgetOrQuick* m_rubberBand = nullptr;
IndicatorsWindow* m_indicatorsWindow = nullptr;
DockProperties m_draggedDockProperties;

View file

@ -76,3 +76,13 @@ const QScreen* MainWindowProvider::screen() const
const QWindow* window = mainWindow();
return window ? window->screen() : nullptr;
}
void MainWindowProvider::requestChangeToolBarOrientation(const QString& toolBarName, mu::framework::Orientation orientation)
{
m_dockOrientationChanged.send({ toolBarName, orientation });
}
mu::async::Channel<std::pair<QString, mu::framework::Orientation> > MainWindowProvider::toolBarOrientationChangeRequested() const
{
return m_dockOrientationChanged;
}

View file

@ -35,6 +35,12 @@ public:
bool isFullScreen() const override;
void toggleFullScreen() override;
const QScreen* screen() const override;
void requestChangeToolBarOrientation(const QString& toolBarName, framework::Orientation orientation) override;
async::Channel<std::pair<QString, framework::Orientation> > toolBarOrientationChangeRequested() const override;
private:
async::Channel<std::pair<QString, framework::Orientation> > m_dockOrientationChanged;
};
}

View file

@ -23,10 +23,13 @@
#define MU_UI_IMAINWINDOW_H
#include "modularity/imoduleexport.h"
#include "async/channel.h"
#include "globaltypes.h"
class QMainWindow;
class QWindow;
class QScreen;
class QString;
namespace mu::ui {
class IMainWindow : MODULE_EXPORT_INTERFACE
@ -42,6 +45,9 @@ public:
virtual bool isFullScreen() const = 0;
virtual void toggleFullScreen() = 0;
virtual const QScreen* screen() const = 0;
virtual void requestChangeToolBarOrientation(const QString& toolBarName, framework::Orientation orientation) = 0;
virtual async::Channel<std::pair<QString, framework::Orientation> > toolBarOrientationChangeRequested() const = 0;
};
}

View file

@ -34,7 +34,7 @@ static const std::string module_name("userscores");
static const Settings::Key RECENT_SCORE_PATHS(module_name, "userscores/recentList");
static const Settings::Key USER_TEMPLATES_PATH(module_name, "application/paths/myTemplates");
static const Settings::Key USER_SCORES_PATH(module_name, "application/paths/myScores");
static const Settings::Key PREFERRED_SCORE_CREATION_MODE_KEY(module_name, "userscores/preferedScoreCreationMode");
static const Settings::Key PREFERRED_SCORE_CREATION_MODE_KEY(module_name, "userscores/preferredScoreCreationMode");
const QString UserScoresConfiguration::DEFAULT_FILE_SUFFIX(".mscz");