Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make DockTitleBar customizable #24196

Merged
merged 1 commit into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/framework/dockwindow/docktypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
namespace muse::dock {
inline const char* CONTEXT_MENU_MODEL_PROPERTY("contextMenuModel");
inline const char* DOCK_PANEL_PROPERTY("dockPanel");
inline const char* TITLEBAR_PROPERTY("titleBar");

//! NOTE: need to be synchronized with Window shadow(see DockFloatingWindow margins)
inline constexpr int DOCK_WINDOW_SHADOW(8);
Expand Down
22 changes: 22 additions & 0 deletions src/framework/dockwindow/internal/dockframemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <QQuickItem>
#include <QApplication>

#include "private/TitleBar_p.h"
#include "thirdparty/KDDockWidgets/src/private/Frame_p.h"
#include "uicomponents/view/abstractmenumodel.h"

Expand Down Expand Up @@ -93,6 +94,11 @@ QVariantList DockFrameModel::tabs() const
return result;
}

QQmlComponent* DockFrameModel::titleBar() const
{
return m_titleBar;
}

bool DockFrameModel::titleBarVisible() const
{
return m_titleBarVisible;
Expand Down Expand Up @@ -139,6 +145,7 @@ void DockFrameModel::listenChangesInFrame()
&& (properties.location == Location::Top || properties.location == Location::Bottom);
setIsHorizontalPanel(isHorizontalPanel);

updateTitleBar();
bool visible = (allDocks.size() == 1) && (properties.type == DockType::Panel) && (properties.floatable || properties.closable);
setTitleBarVisible(visible);

Expand Down Expand Up @@ -187,6 +194,21 @@ void DockFrameModel::updateNavigationSection()
}
}

QQmlComponent* DockFrameModel::currentTitleBar() const
{
QQmlComponent* titleBar = currentDockProperty(TITLEBAR_PROPERTY).value<QQmlComponent*>();
return titleBar;
}

void DockFrameModel::updateTitleBar()
{
QQmlComponent* tb = currentTitleBar();
if (m_titleBar != tb) {
m_titleBar = tb;
emit titleBarChanged();
}
}

QObject* DockFrameModel::navigationSection() const
{
return m_navigationSection;
Expand Down
7 changes: 7 additions & 0 deletions src/framework/dockwindow/internal/dockframemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class DockFrameModel : public QObject, public muse::Injectable
Q_PROPERTY(QQuickItem * frame READ frame WRITE setFrame NOTIFY frameChanged)
Q_PROPERTY(QVariantList tabs READ tabs NOTIFY tabsChanged)

Q_PROPERTY(QQmlComponent * titleBar READ titleBar NOTIFY titleBarChanged)
Q_PROPERTY(bool titleBarVisible READ titleBarVisible NOTIFY titleBarVisibleChanged)
Q_PROPERTY(bool isHorizontalPanel READ isHorizontalPanel NOTIFY isHorizontalPanelChanged)
Q_PROPERTY(QObject * navigationSection READ navigationSection NOTIFY navigationSectionChanged)
Expand All @@ -58,6 +59,7 @@ class DockFrameModel : public QObject, public muse::Injectable
QQuickItem* frame() const;
QVariantList tabs() const;

QQmlComponent* titleBar() const;
bool titleBarVisible() const;
bool isHorizontalPanel() const;
QObject* navigationSection() const;
Expand All @@ -75,6 +77,7 @@ public slots:
signals:
void frameChanged(QQuickItem* frame);
void tabsChanged();
void titleBarChanged();
void titleBarVisibleChanged(bool visible);
void isHorizontalPanelChanged();
void navigationSectionChanged();
Expand All @@ -94,7 +97,11 @@ public slots:
QObject* currentNavigationSection() const;
void updateNavigationSection();

QQmlComponent* currentTitleBar() const;
void updateTitleBar();

KDDockWidgets::Frame* m_frame = nullptr;
QQmlComponent* m_titleBar = nullptr;
bool m_titleBarVisible = false;
bool m_isHorizontalPanel = false;
QObject* m_navigationSection = nullptr;
Expand Down
8 changes: 6 additions & 2 deletions src/framework/dockwindow/qml/Muse/Dock/DockFrame.qml
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,22 @@ Rectangle {

anchors.top: parent.top

property alias titleBar: frameModel.titleBar

titleBarCpp: root.titleBarCpp

contextMenuModel: frameModel.currentDockContextMenuModel
visible: frameModel.titleBarVisible
isHorizontalPanel: frameModel.isHorizontalPanel

navigation.panel: navPanel
navigation.order: 1
navigationPanel: navPanel
navigationOrder: 1

onHandleContextMenuItemRequested: function(itemId) {
frameModel.handleMenuItem(itemId)
}

titleBarItem: frameModel.titleBar
}

MouseArea {
Expand Down
116 changes: 74 additions & 42 deletions src/framework/dockwindow/qml/Muse/Dock/DockTitleBar.qml
Original file line number Diff line number Diff line change
Expand Up @@ -33,75 +33,107 @@ Item {

required property QtObject titleBarCpp

property alias contextMenuModel: contextMenuButton.menuModel
property alias heightWhenVisible: titleBar.heightWhenVisible
property Component titleBarItem: null
property var contextMenuModel: null
property var heightWhenVisible: null
property var navigationPanel: null
property var navigationOrder: null
property bool isHorizontalPanel: false

property alias navigation: contextMenuButton.navigation

signal handleContextMenuItemRequested(string itemId)

width: parent.width
height: visible ? heightWhenVisible : 0

visible: Boolean(titleBarCpp)

KDDW.TitleBarBase {
id: titleBar

Loader {
id: titleBarLoader
anchors.fill: parent

heightWhenVisible: titleBarContent.implicitHeight
color: ui.theme.backgroundPrimaryColor
property var titleBarCpp: root.titleBarCpp

visible: parent.visible
sourceComponent: root.titleBarItem ?? defaultTitleBarComponent

MouseArea {
id: mouseArea
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: Qt.SizeAllCursor
onLoaded: {
if (titleBarLoader.item) {
item.navigationPanel = Qt.binding(function() { return root.navigationPanel})
item.navigationOrder = Qt.binding(function() { return root.navigationOrder})
item.contextMenuModel = Qt.binding(function() { return root.contextMenuModel})
root.heightWhenVisible = Qt.binding(function() { return item.heightWhenVisible})
}
}
}

Column {
id: titleBarContent
Component {
id: defaultTitleBarComponent

KDDW.TitleBarBase {
id: titleBar

anchors.fill: parent
anchors.leftMargin: 12
anchors.rightMargin: 12

spacing: 0
implicitHeight: titleBarContent.implicitHeight
heightWhenVisible: titleBarContent.implicitHeight
color: ui.theme.backgroundPrimaryColor

RowLayout {
width: parent.width
height: 34
property var navigationPanel
property var navigationOrder
property var contextMenuModel

StyledTextLabel {
id: titleLabel
Layout.fillWidth: true
visible: parent.visible

text: titleBar.title
font: ui.theme.bodyBoldFont
horizontalAlignment: Qt.AlignLeft
}
MouseArea {
id: mouseArea
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: Qt.SizeAllCursor
}

Column {
id: titleBarContent

MenuButton {
id: contextMenuButton
anchors.fill: parent
anchors.leftMargin: 12
anchors.rightMargin: 12

width: 20
height: width
spacing: 0

onHandleMenuItem: function(itemId) {
root.handleContextMenuItemRequested(itemId)
RowLayout {
width: parent.width
height: 34

StyledTextLabel {
id: titleLabel
Layout.fillWidth: true

text: titleBar.title
font: ui.theme.bodyBoldFont
horizontalAlignment: Qt.AlignLeft
}

MenuButton {
id: contextMenuButton

width: 20
height: width

navigation.panel: root.navigationPanel
navigation.order: root.navigationOrder
menuModel: root.contextMenuModel

onHandleMenuItem: function(itemId) {
root.handleContextMenuItemRequested(itemId)
}
}
}
}

SeparatorLine {
id: bottomSeparator
orientation: Qt.Horizontal
anchors.margins: -12
visible: root.isHorizontalPanel
SeparatorLine {
id: bottomSeparator
orientation: Qt.Horizontal
anchors.margins: -12
visible: root.isHorizontalPanel
}
}
}
}
Expand Down
17 changes: 17 additions & 0 deletions src/framework/dockwindow/view/dockpanelview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ DockPanelView::~DockPanelView()

dockWidget->setProperty(DOCK_PANEL_PROPERTY, QVariant::fromValue(nullptr));
dockWidget->setProperty(CONTEXT_MENU_MODEL_PROPERTY, QVariant::fromValue(nullptr));
dockWidget->setProperty(TITLEBAR_PROPERTY, QVariant::fromValue(nullptr));
}

QString DockPanelView::groupName() const
Expand Down Expand Up @@ -194,6 +195,7 @@ void DockPanelView::componentComplete()

dockWidget->setProperty(DOCK_PANEL_PROPERTY, QVariant::fromValue(this));
dockWidget->setProperty(CONTEXT_MENU_MODEL_PROPERTY, QVariant::fromValue(m_menuModel));
dockWidget->setProperty(TITLEBAR_PROPERTY, QVariant::fromValue(m_titleBar));

connect(m_menuModel, &AbstractMenuModel::itemsChanged, [dockWidget, this]() {
if (dockWidget) {
Expand Down Expand Up @@ -222,6 +224,11 @@ AbstractMenuModel* DockPanelView::contextMenuModel() const
return m_menuModel->customMenuModel();
}

QQmlComponent* DockPanelView::titleBar() const
{
return m_titleBar;
}

void DockPanelView::setContextMenuModel(AbstractMenuModel* model)
{
if (m_menuModel->customMenuModel() == model) {
Expand All @@ -233,6 +240,16 @@ void DockPanelView::setContextMenuModel(AbstractMenuModel* model)
emit contextMenuModelChanged();
}

void DockPanelView::setTitleBar(QQmlComponent* titleBar)
{
if (m_titleBar == titleBar) {
return;
}

m_titleBar = titleBar;
emit titleBarChanged();
}

bool DockPanelView::isTabAllowed(const DockPanelView* tab) const
{
IF_ASSERT_FAILED(tab) {
Expand Down
5 changes: 5 additions & 0 deletions src/framework/dockwindow/view/dockpanelview.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class DockPanelView : public DockBase
Q_PROPERTY(
muse::uicomponents::AbstractMenuModel
* contextMenuModel READ contextMenuModel WRITE setContextMenuModel NOTIFY contextMenuModelChanged)
Q_PROPERTY(QQmlComponent * titleBar READ titleBar WRITE setTitleBar NOTIFY titleBarChanged)

public:
explicit DockPanelView(QQuickItem* parent = nullptr);
Expand All @@ -49,6 +50,7 @@ class DockPanelView : public DockBase
QString groupName() const;
QObject* navigationSection() const;
uicomponents::AbstractMenuModel* contextMenuModel() const;
QQmlComponent* titleBar() const;

bool isTabAllowed(const DockPanelView* tab) const;
void addPanelAsTab(DockPanelView* tab);
Expand All @@ -58,11 +60,13 @@ public slots:
void setGroupName(const QString& name);
void setNavigationSection(QObject* newNavigation);
void setContextMenuModel(uicomponents::AbstractMenuModel* model);
void setTitleBar(QQmlComponent* titleBar);

signals:
void groupNameChanged();
void navigationSectionChanged();
void contextMenuModelChanged();
void titleBarChanged();

private:
void componentComplete() override;
Expand All @@ -72,6 +76,7 @@ public slots:

class DockPanelMenuModel;
DockPanelMenuModel* m_menuModel = nullptr;
QQmlComponent* m_titleBar = nullptr;
};
}

Expand Down