diff --git a/src/declarativeimports/core/framesvgitem.cpp b/src/declarativeimports/core/framesvgitem.cpp index 2ac8f496c..ecd062753 100644 --- a/src/declarativeimports/core/framesvgitem.cpp +++ b/src/declarativeimports/core/framesvgitem.cpp @@ -167,7 +167,8 @@ private: FrameSvgItemMargins::FrameSvgItemMargins(Plasma::FrameSvg *frameSvg, QObject *parent) : QObject(parent), m_frameSvg(frameSvg), - m_fixed(false) + m_fixed(false), + m_shadow(false) { //qDebug() << "margins at: " << left() << top() << right() << bottom(); } @@ -176,6 +177,8 @@ qreal FrameSvgItemMargins::left() const { if (m_fixed) { return m_frameSvg->fixedMarginSize(Types::LeftMargin); + } else if(m_shadow){ + return m_frameSvg->shadowMarginSize(Types::LeftMargin); } else { return m_frameSvg->marginSize(Types::LeftMargin); } @@ -185,6 +188,8 @@ qreal FrameSvgItemMargins::top() const { if (m_fixed) { return m_frameSvg->fixedMarginSize(Types::TopMargin); + } else if(m_shadow){ + return m_frameSvg->shadowMarginSize(Types::TopMargin); } else { return m_frameSvg->marginSize(Types::TopMargin); } @@ -194,6 +199,8 @@ qreal FrameSvgItemMargins::right() const { if (m_fixed) { return m_frameSvg->fixedMarginSize(Types::RightMargin); + } else if(m_shadow){ + return m_frameSvg->shadowMarginSize(Types::RightMargin); } else { return m_frameSvg->marginSize(Types::RightMargin); } @@ -203,6 +210,8 @@ qreal FrameSvgItemMargins::bottom() const { if (m_fixed) { return m_frameSvg->fixedMarginSize(Types::BottomMargin); + } else if(m_shadow){ + return m_frameSvg->shadowMarginSize(Types::BottomMargin); } else { return m_frameSvg->marginSize(Types::BottomMargin); } @@ -245,10 +254,26 @@ bool FrameSvgItemMargins::isFixed() const return m_fixed; } +void FrameSvgItemMargins::setShadow(bool shadow) +{ + if (shadow == m_shadow) { + return; + } + + m_shadow = shadow; + emit marginsChanged(); +} + +bool FrameSvgItemMargins::isShadow() const +{ + return m_shadow; +} + FrameSvgItem::FrameSvgItem(QQuickItem *parent) : QQuickItem(parent), m_margins(nullptr), m_fixedMargins(nullptr), + m_shadowMargins(nullptr), m_textureChanged(false), m_sizeChanged(false), m_fastPath(true) @@ -295,6 +320,7 @@ void FrameSvgItem::setImagePath(const QString &path) CheckMarginsChange checkMargins(m_oldMargins, m_margins); CheckMarginsChange checkFixedMargins(m_oldFixedMargins, m_fixedMargins); + CheckMarginsChange checkShadowMargins(m_oldShadowMargins, m_shadowMargins); updateDevicePixelRatio(); m_frameSvg->setImagePath(path); @@ -339,6 +365,7 @@ void FrameSvgItem::setPrefix(const QVariant &prefixes) CheckMarginsChange checkMargins(m_oldMargins, m_margins); CheckMarginsChange checkFixedMargins(m_oldFixedMargins, m_fixedMargins); + CheckMarginsChange checkShadowMargins(m_oldShadowMargins, m_shadowMargins); m_prefixes = prefixList; applyPrefixes(); @@ -387,6 +414,15 @@ FrameSvgItemMargins *FrameSvgItem::fixedMargins() return m_fixedMargins; } +FrameSvgItemMargins *FrameSvgItem::shadowMargins() +{ + if (!m_shadowMargins) { + m_shadowMargins = new FrameSvgItemMargins(m_frameSvg, this); + m_shadowMargins->setShadow(true); + } + return m_shadowMargins; +} + void FrameSvgItem::setColorGroup(Plasma::Theme::ColorGroup group) { if (m_frameSvg->colorGroup() == group) { @@ -474,6 +510,7 @@ void FrameSvgItem::doUpdate() CheckMarginsChange checkMargins(m_oldMargins, m_margins); CheckMarginsChange checkFixedMargins(m_oldFixedMargins, m_fixedMargins); + CheckMarginsChange checkShadowMargins(m_oldShadowMargins, m_shadowMargins); //if the theme changed, the available prefix may have changed as well applyPrefixes(); @@ -618,6 +655,7 @@ void FrameSvgItem::componentComplete() { CheckMarginsChange checkMargins(m_oldMargins, m_margins); CheckMarginsChange checkFixedMargins(m_oldFixedMargins, m_fixedMargins); + CheckMarginsChange checkShadowMargins(m_oldShadowMargins, m_shadowMargins); QQuickItem::componentComplete(); m_frameSvg->resizeFrame(QSize(width(), height())); diff --git a/src/declarativeimports/core/framesvgitem.h b/src/declarativeimports/core/framesvgitem.h index e08bbf9f5..8997b6e81 100644 --- a/src/declarativeimports/core/framesvgitem.h +++ b/src/declarativeimports/core/framesvgitem.h @@ -75,6 +75,9 @@ public: void setFixed(bool fixed); bool isFixed() const; + void setShadow(bool shadow); + bool isShadow() const; + public Q_SLOTS: void update(); @@ -84,6 +87,7 @@ Q_SIGNALS: private: FrameSvg *m_frameSvg; bool m_fixed; + bool m_shadow; }; @@ -134,6 +138,14 @@ class FrameSvgItem : public QQuickItem */ Q_PROPERTY(QObject *fixedMargins READ fixedMargins CONSTANT) + /** + * The margins of the shadow + * read only + * @see FrameSvgItemMargins + * @since 5.77 + */ + Q_PROPERTY(QObject *shadowMargins READ shadowMargins CONSTANT) + /** * The borders that will be rendered, it's a flag combination of: * NoBorder @@ -200,6 +212,7 @@ public: FrameSvgItemMargins *margins(); FrameSvgItemMargins *fixedMargins(); + FrameSvgItemMargins *shadowMargins(); void setColorGroup(Plasma::Theme::ColorGroup group); Plasma::Theme::ColorGroup colorGroup() const; @@ -250,9 +263,11 @@ private: Plasma::FrameSvg *m_frameSvg; FrameSvgItemMargins *m_margins; FrameSvgItemMargins *m_fixedMargins; + FrameSvgItemMargins *m_shadowMargins; // logged margins to check for changes QVector m_oldMargins; QVector m_oldFixedMargins; + QVector m_oldShadowMargins; QStringList m_prefixes; bool m_textureChanged; bool m_sizeChanged; diff --git a/src/declarativeimports/core/iconitem.cpp b/src/declarativeimports/core/iconitem.cpp index 4d2b435b6..679f0fabf 100644 --- a/src/declarativeimports/core/iconitem.cpp +++ b/src/declarativeimports/core/iconitem.cpp @@ -252,6 +252,7 @@ IconItem::IconItem(QQuickItem *parent) m_iconItemSource(new NullSource(this)), m_status(Plasma::Svg::Normal), m_active(false), + m_selected(false), m_animated(true), m_usesPlasmaTheme(true), m_roundToIconSize(true), @@ -448,6 +449,26 @@ void IconItem::setActive(bool active) emit activeChanged(); } +bool IconItem::isSelected() const +{ + return m_selected; +} + +void IconItem::setSelected(bool selected) +{ + if (m_selected == selected) { + return; + } + + m_selected = selected; + + if (isComponentComplete()) { + m_allowNextAnimation = true; + schedulePixmapUpdate(); + } + emit selectedChanged(); +} + bool IconItem::isAnimated() const { return m_animated; @@ -726,6 +747,8 @@ void IconItem::loadPixmap() result = KIconLoader::global()->iconEffect()->apply(result, KIconLoader::Desktop, KIconLoader::DisabledState); } else if (m_active) { result = KIconLoader::global()->iconEffect()->apply(result, KIconLoader::Desktop, KIconLoader::ActiveState); + } else if (m_selected) { + result = KIconLoader::global()->iconEffect()->apply(result, KIconLoader::Desktop, KIconLoader::SelectedState); } const QSize oldPaintedSize = paintedSize(); diff --git a/src/declarativeimports/core/iconitem.h b/src/declarativeimports/core/iconitem.h index 500274a97..79e9c4cb8 100644 --- a/src/declarativeimports/core/iconitem.h +++ b/src/declarativeimports/core/iconitem.h @@ -61,6 +61,12 @@ class IconItem : public QQuickItem */ Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged) + /** + * Apply a visual indication that this icon is selected. + * @since 5.77 + */ + Q_PROPERTY(bool selected READ isSelected WRITE setSelected NOTIFY selectedChanged) + /** * Sets the image in a selected status. * Svgs can be colored with system color themes, if the status is selected, @@ -124,6 +130,9 @@ public: bool isActive() const; void setActive(bool active); + bool isSelected() const; + void setSelected(bool selected); + bool isAnimated() const; void setAnimated(bool animated); @@ -156,6 +165,7 @@ public: Q_SIGNALS: void overlaysChanged(); void activeChanged(); + void selectedChanged(); void sourceChanged(); void animatedChanged(); void usesPlasmaThemeChanged(); @@ -187,6 +197,7 @@ private: Plasma::Svg::Status m_status; bool m_active; + bool m_selected; bool m_animated; bool m_usesPlasmaTheme; bool m_roundToIconSize; diff --git a/src/declarativeimports/plasmacomponents3/TabButton.qml b/src/declarativeimports/plasmacomponents3/TabButton.qml index f4a207e4d..d8dd89fbc 100644 --- a/src/declarativeimports/plasmacomponents3/TabButton.qml +++ b/src/declarativeimports/plasmacomponents3/TabButton.qml @@ -49,6 +49,7 @@ T.TabButton { colorGroup: control.PlasmaCore.ColorScope.colorGroup visible: source.length > 0 && control.display !== T.AbstractButton.TextOnly source: control.icon ? (control.icon.name || control.icon.source) : "" + selected: control.visualFocus } Label { id: label @@ -56,7 +57,7 @@ T.TabButton { visible: text.length > 0 && control.display !== T.AbstractButton.IconOnly text: control.Kirigami.MnemonicData.richTextLabel font: control.font - color: PlasmaCore.ColorScope.textColor + color: control.visualFocus ? PlasmaCore.ColorScope.highlightColor : PlasmaCore.ColorScope.textColor opacity: enabled || control.highlighted || control.checked ? 1 : 0.4 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter diff --git a/src/plasma/framesvg.cpp b/src/plasma/framesvg.cpp index 143ba1137..8cc27b0a6 100644 --- a/src/plasma/framesvg.cpp +++ b/src/plasma/framesvg.cpp @@ -218,6 +218,45 @@ qreal FrameSvg::marginSize(const Plasma::Types::MarginEdge edge) const } } +qreal FrameSvg::shadowMarginSize(const Plasma::Types::MarginEdge edge) const +{ + switch (edge) { + case Plasma::Types::TopMargin: { + const QSize marginHint = this->elementSize(QStringLiteral("shadow-hint-top-margin")); + if (marginHint.isValid()) { + return marginHint.height(); + } else { + return .0; + } + } + case Plasma::Types::LeftMargin: { + const QSize marginHint = this->elementSize(QStringLiteral("shadow-hint-left-margin")); + if (marginHint.isValid()) { + return marginHint.width(); + } else { + return .0; + } + } + case Plasma::Types::RightMargin: { + const QSize marginHint = this->elementSize(QStringLiteral("shadow-hint-right-margin")); + if (marginHint.isValid()) { + return marginHint.width(); + } else { + return .0; + } + } + //Plasma::BottomMargin + default: { + const QSize marginHint = this->elementSize(QStringLiteral("shadow-hint-bottom-margin")); + if (marginHint.isValid()) { + return marginHint.height(); + } else { + return .0; + } + } + } +} + qreal FrameSvg::fixedMarginSize(const Plasma::Types::MarginEdge edge) const { if (!d->frame) { diff --git a/src/plasma/framesvg.h b/src/plasma/framesvg.h index 00a71872c..2c978513e 100644 --- a/src/plasma/framesvg.h +++ b/src/plasma/framesvg.h @@ -151,6 +151,14 @@ public: */ Q_INVOKABLE qreal fixedMarginSize(const Plasma::Types::MarginEdge edge) const; + /** + * Returns the shadows margin size given the margin edge we want. + * @param edge the margin edge we want, top, bottom, left or right + * @return the margin size + * @since 5.77 + */ + Q_INVOKABLE qreal shadowMarginSize(const Plasma::Types::MarginEdge edge) const; + /** * Convenience method that extracts the size of the four margins * in the four output parameters diff --git a/src/plasmaquick/dialog.cpp b/src/plasmaquick/dialog.cpp index a129173eb..c4634cb57 100644 --- a/src/plasmaquick/dialog.cpp +++ b/src/plasmaquick/dialog.cpp @@ -486,10 +486,15 @@ void DialogPrivate::updateLayoutParameters() q->resize(finalSize); } - mainItem->setPosition(QPointF(margin->left(), + if (q->backgroundHints().testFlag(Dialog::DiscardBackgroundMargins)) { + mainItem->setPosition(QPointF(margin->left(), margin->top())); - mainItem->setSize(QSizeF(q->width() - margin->left() - margin->right(), + mainItem->setSize(QSizeF(q->width() - margin->left() - margin->right(), q->height() - margin->top() - margin->bottom())); + } else { + mainItem->setPosition(QPointF(0, 0)); + mainItem->setSize(QSizeF(q->width(), q->height())); + } frameSvgItem->setSize(QSizeF(q->width(), q->height())); @@ -637,8 +642,12 @@ void DialogPrivate::syncToMainItemSize() q->resize(s); } - mainItem->setPosition(QPointF(frameSvgItem->fixedMargins()->left(), + if (q->backgroundHints().testFlag(Dialog::DiscardBackgroundMargins)) { + mainItem->setPosition(QPointF(frameSvgItem->fixedMargins()->left(), frameSvgItem->fixedMargins()->top())); + } else { + mainItem->setPosition(QPointF(0, 0)); + } updateTheme(); } @@ -656,9 +665,15 @@ void DialogPrivate::slotWindowPositionChanged() if (mainItem) { auto margin = frameSvgItem->fixedMargins(); - mainItem->setPosition(QPoint(margin->left(), margin->top())); - mainItem->setSize(QSize(q->width() - margin->left() - margin->right(), - q->height() - margin->top() - margin->bottom())); + if (q->backgroundHints().testFlag(Dialog::DiscardBackgroundMargins)) { + mainItem->setPosition(QPointF(margin->left(), + margin->top())); + mainItem->setSize(QSizeF(q->width() - margin->left() - margin->right(), + q->height() - margin->top() - margin->bottom())); + } else { + mainItem->setPosition(QPointF(0, 0)); + mainItem->setSize(QSizeF(q->width(), q->height())); + } } } @@ -1117,11 +1132,15 @@ void Dialog::resizeEvent(QResizeEvent* re) d->frameSvgItem->setSize(QSizeF(re->size().width(), re->size().height())); auto margin = d->frameSvgItem->fixedMargins(); - d->mainItem->setPosition(QPointF(margin->left(), - margin->top())); - - d->mainItem->setSize(QSize(re->size().width() - margin->left() - margin->right(), - re->size().height() - margin->top() - margin->bottom())); + if (backgroundHints().testFlag(Dialog::DiscardBackgroundMargins)) { + d->mainItem->setPosition(QPointF(margin->left(), + margin->top())); + d->mainItem->setSize(QSizeF(re->size().width() - margin->left() - margin->right(), + re->size().height() - margin->top() - margin->bottom())); + } else { + d->mainItem->setPosition(QPointF(0, 0)); + d->mainItem->setSize(QSizeF(re->size().width(), re->size().height())); + } QObject::connect(d->mainItem, SIGNAL(widthChanged()), this, SLOT(slotMainItemSizeChanged())); QObject::connect(d->mainItem, SIGNAL(heightChanged()), this, SLOT(slotMainItemSizeChanged())); diff --git a/src/plasmaquick/dialog.h b/src/plasmaquick/dialog.h index d6d50b16a..5525cb795 100644 --- a/src/plasmaquick/dialog.h +++ b/src/plasmaquick/dialog.h @@ -150,11 +150,13 @@ public: }; Q_ENUM(WindowType) - enum BackgroundHints { + enum BackgroundHint { NoBackground = 0, /**< Not drawing a background under the applet, the dialog has its own implementation */ - StandardBackground = 1 /**< The standard background from the theme is drawn */ + StandardBackground = 1, /**< The standard background from the theme is drawn */ + DiscardBackgroundMargins = 2 /**< Don't constrain dialogs main QML item within dialogs margins. */ }; - Q_ENUM(BackgroundHints) + Q_DECLARE_FLAGS(BackgroundHints, BackgroundHint) + Q_FLAG(BackgroundHints) explicit Dialog(QQuickItem *parent = nullptr); ~Dialog() override; @@ -244,6 +246,8 @@ private: Q_PRIVATE_SLOT(d, void slotMainItemSizeChanged()) }; +Q_DECLARE_OPERATORS_FOR_FLAGS(Dialog::BackgroundHints) + } #endif