6#include "decorationbuttongroup.h"
8#include "decorationbuttongroup_p.h"
9#include "decorationsettings.h"
12#include <QGuiApplication>
16DecorationButtonGroup::Private::Private(Decoration *decoration, DecorationButtonGroup *parent)
17 : decoration(decoration)
23DecorationButtonGroup::Private::~Private() =
default;
25void DecorationButtonGroup::Private::setGeometry(
const QRectF &geo)
27 if (geometry == geo) {
31 Q_EMIT q->geometryChanged(geometry);
36static bool s_layoutRecursion =
false;
39void DecorationButtonGroup::Private::updateLayout()
41 if (s_layoutRecursion) {
44 s_layoutRecursion =
true;
45 const QPointF &pos = geometry.topLeft();
49 for (
auto it = buttons.constBegin(); it != buttons.constEnd(); ++it) {
50 if (!(*it)->isVisible()) {
53 height = qMax(height, qreal((*it)->size().height()));
54 width += (*it)->size().width();
55 if (it + 1 != buttons.constEnd()) {
64 qreal leftPosition = pos.
x();
65 qreal rightPosition = pos.
x() + width;
68 for (
auto button : std::as_const(buttons)) {
69 if (!button->isVisible()) {
72 const auto size = button->size();
73 const auto buttonPos =
QPointF(leftPosition, pos.
y());
74 button->setGeometry(
QRectF(buttonPos, size));
75 leftPosition += size.width() + spacing;
78 for (
auto button : std::as_const(buttons)) {
79 if (!button->isVisible()) {
82 const auto size = button->size();
83 const auto buttonPos =
QPointF(rightPosition - size.width(), pos.
y());
84 button->setGeometry(
QRectF(buttonPos, size));
85 rightPosition -= size.width() + spacing;
88 qCritical() <<
"There's an unhandled layout direction! This is likely an issue of KDecoration3 not being updated to handle it\n"
89 <<
"or the application having an invalid layout direction set. Either way, this is a critical bug.";
92 s_layoutRecursion =
false;
95DecorationButtonGroup::DecorationButtonGroup(Decoration *parent)
97 , d(new Private(parent, this))
101DecorationButtonGroup::DecorationButtonGroup(DecorationButtonGroup::Position type,
103 std::function<DecorationButton *(DecorationButtonType, Decoration *,
QObject *)> buttonCreator)
105 , d(new Private(parent, this))
107 auto createButtons = [
this, buttonCreator,
type] {
109 const DecorationSettings *settings = d->decoration->settings().get();
110 const auto &buttons =
111 (
type == Position::Left) ?
112 (layoutDirection ==
Qt::LeftToRight ? settings->decorationButtonsLeft() : settings->decorationButtonsRight()) :
113 (layoutDirection ==
Qt::LeftToRight ? settings->decorationButtonsRight() : settings->decorationButtonsLeft());
114 for (DecorationButtonType type : buttons) {
115 if (DecorationButton *b = buttonCreator(type, d->decoration,
this)) {
121 auto changed =
type == Position::Left ? &DecorationSettings::decorationButtonsLeftChanged : &DecorationSettings::decorationButtonsRightChanged;
122 connect(parent->settings().get(), changed,
this, [
this, createButtons] {
123 qDeleteAll(d->buttons);
129DecorationButtonGroup::~DecorationButtonGroup() =
default;
131Decoration *DecorationButtonGroup::decoration()
const
133 return d->decoration;
136QRectF DecorationButtonGroup::geometry()
const
144 auto it = std::find_if(d->buttons.begin(), d->buttons.end(), [type](
DecorationButton *button) {
145 return button->type() == type;
147 return it != d->buttons.end();
150qreal DecorationButtonGroup::spacing()
const
155QPointF DecorationButtonGroup::pos()
const
157 return d->geometry.topLeft();
160void DecorationButtonGroup::setPos(
const QPointF &pos)
162 if (d->geometry.topLeft() == pos) {
165 d->setGeometry(
QRectF(pos, d->geometry.size()));
169void DecorationButtonGroup::setSpacing(qreal spacing)
171 if (d->spacing == spacing) {
174 d->spacing = spacing;
175 Q_EMIT spacingChanged(d->spacing);
182 connect(button, &DecorationButton::visibilityChanged,
this, [
this]() {
185 connect(button, &DecorationButton::geometryChanged,
this, [
this]() {
188 d->buttons.append(button);
199 bool needUpdate =
false;
200 auto it = d->buttons.
begin();
201 while (it != d->buttons.end()) {
202 if ((*it)->type() == type) {
203 it = d->buttons.erase(it);
216 bool needUpdate =
false;
217 auto it = d->buttons.begin();
218 while (it != d->buttons.end()) {
220 it = d->buttons.erase(it);
231void DecorationButtonGroup::paint(
QPainter *painter,
const QRect &repaintArea)
233 const auto &buttons = d->buttons;
234 for (
auto button : buttons) {
235 if (!button->isVisible()) {
238 button->paint(painter, repaintArea);
244#include "moc_decorationbuttongroup.cpp"
Framework for creating window decorations.
DecorationButtonType
The DecorationButtonType is a helper type for the DecorationButton.
GeoCoordinates geo(const QVariant &location)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
QCoreApplication * instance()
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)