156 lines
4.4 KiB
C++
156 lines
4.4 KiB
C++
/*
|
|
This file is part of KDDockWidgets.
|
|
|
|
SPDX-FileCopyrightText: 2019 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
|
Author: Sérgio Martins <sergio.martins@kdab.com>
|
|
|
|
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
|
|
|
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
|
*/
|
|
|
|
#include "SideBar.h"
|
|
|
|
#include "kddockwidgets/core/DockWidget.h"
|
|
#include "kddockwidgets/core/SideBar.h"
|
|
#include "kddockwidgets/core/MainWindow.h"
|
|
#include "core/DockWidget_p.h"
|
|
|
|
#include <QVBoxLayout>
|
|
#include <QHBoxLayout>
|
|
#include <QPainter>
|
|
#include <QAbstractButton>
|
|
#include <QStyle>
|
|
#include <QStyleOptionToolButton>
|
|
|
|
using namespace KDDockWidgets;
|
|
using namespace KDDockWidgets::QtWidgets;
|
|
|
|
namespace KDDockWidgets {
|
|
class SideBarButton::Private
|
|
{
|
|
public:
|
|
Private(Core::DockWidget *dw, Core::SideBar *sideBar)
|
|
: m_sideBar(sideBar)
|
|
, m_dockWidget(dw)
|
|
{
|
|
}
|
|
|
|
Core::SideBar *const m_sideBar;
|
|
const QPointer<Core::DockWidget> m_dockWidget;
|
|
|
|
// Connections to be disconnected when button is destroyed
|
|
std::vector<KDBindings::ScopedConnection> m_connections;
|
|
};
|
|
}
|
|
|
|
SideBar::SideBar(Core::SideBar *controller, QWidget *parent)
|
|
: View(controller, Core::ViewType::SideBar, parent)
|
|
, SideBarViewInterface(controller)
|
|
{
|
|
}
|
|
|
|
void SideBar::init()
|
|
{
|
|
if (m_sideBar->isVertical())
|
|
m_layout = new QVBoxLayout(this);
|
|
else
|
|
m_layout = new QHBoxLayout(this);
|
|
|
|
m_layout->setSpacing(1);
|
|
m_layout->setContentsMargins(0, 0, 0, 0);
|
|
m_layout->addStretch();
|
|
}
|
|
|
|
void SideBar::addDockWidget_Impl(Core::DockWidget *dw)
|
|
{
|
|
auto button = createButton(dw, this);
|
|
button->setText(dw->title());
|
|
|
|
button->d->m_connections.push_back(dw->d->titleChanged.connect(&SideBarButton::setText, button));
|
|
button->d->m_connections.push_back(dw->d->isOverlayedChanged.connect([button] { button->update(); }));
|
|
button->d->m_connections.push_back(dw->d->removedFromSideBar.connect(&QObject::deleteLater, button));
|
|
|
|
connect(dw, &QObject::destroyed, button, &QObject::deleteLater);
|
|
connect(button, &SideBarButton::clicked, this, [this, dw] { m_sideBar->onButtonClicked(dw); });
|
|
|
|
const int count = m_layout->count();
|
|
m_layout->insertWidget(count - 1, button);
|
|
}
|
|
|
|
void SideBar::removeDockWidget_Impl(Core::DockWidget *)
|
|
{
|
|
// Nothing is needed. Button is removed automatically.
|
|
}
|
|
|
|
SideBarButton *SideBar::createButton(Core::DockWidget *dw,
|
|
SideBar *parent) const
|
|
{
|
|
return new SideBarButton(dw, parent);
|
|
}
|
|
|
|
SideBarButton::SideBarButton(Core::DockWidget *dw, QtWidgets::SideBar *parent)
|
|
: QToolButton(parent)
|
|
, d(new Private(dw, parent->sideBar()))
|
|
{
|
|
}
|
|
|
|
SideBarButton::~SideBarButton()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
bool SideBarButton::isVertical() const
|
|
{
|
|
return d->m_sideBar->isVertical();
|
|
}
|
|
|
|
void SideBarButton::paintEvent(QPaintEvent *)
|
|
{
|
|
if (!d->m_dockWidget) {
|
|
// Can happen during destruction
|
|
return;
|
|
}
|
|
|
|
// Draw to an horizontal button, it's easier. Rotate later.
|
|
QPixmap pixmap((isVertical() ? size().transposed() : size()) * devicePixelRatioF());
|
|
pixmap.setDevicePixelRatio(devicePixelRatioF());
|
|
|
|
{
|
|
pixmap.fill(Qt::transparent);
|
|
|
|
QStyleOptionToolButton opt;
|
|
initStyleOption(&opt);
|
|
const bool isHovered = opt.state & QStyle::State_MouseOver;
|
|
// const bool isOverlayed = m_dockWidget->isOverlayed(); // We could style different if it's
|
|
// open const bool isHoveredOrOverlayed = isHovered || isOverlayed;
|
|
|
|
QPainter p(&pixmap);
|
|
|
|
const QRect r = isVertical() ? rect().transposed() : rect();
|
|
const QRect textRect = r.adjusted(3, 0, 5, 0);
|
|
// p.drawRect(r.adjusted(0, 0, -1, -1));
|
|
p.setPen(palette().color(QPalette::Text));
|
|
p.drawText(textRect, Qt::AlignVCenter | Qt::AlignLeft, text());
|
|
|
|
QPen pen(isHovered ? palette().color(QPalette::Highlight)
|
|
: palette().color(QPalette::Highlight).darker());
|
|
pen.setWidth(isHovered ? 2 : 1);
|
|
p.setPen(pen);
|
|
p.drawLine(3, r.bottom() - 1, r.width() - 6, r.bottom() - 1);
|
|
}
|
|
|
|
QPainter p(this);
|
|
if (isVertical()) {
|
|
pixmap = pixmap.transformed(QTransform().rotate(90));
|
|
}
|
|
|
|
p.drawPixmap(rect(), pixmap);
|
|
}
|
|
|
|
QSize SideBarButton::sizeHint() const
|
|
{
|
|
const QSize hint = QToolButton::sizeHint();
|
|
return isVertical() ? (hint.transposed() + QSize(2, 0)) : (hint + QSize(0, 2));
|
|
}
|