diff options
| author | Ivan Solovev <ivan.solovev@qt.io> | 2025-06-10 16:31:16 +0200 |
|---|---|---|
| committer | Ivan Solovev <ivan.solovev@qt.io> | 2025-06-13 12:15:41 +0200 |
| commit | 7322e051c9c3d8dc715c20a3d42d9be83ea2295c (patch) | |
| tree | 4b13c016a33e3793ef51e3e77d1db940596a5249 /src/quickdialogs/quickdialogsquickimpl | |
| parent | 2d4bebdb51bbf720fe719f5e6ea54b04bde36510 (diff) | |
QQuickDialogs: fix dark mode in SideBar
The patch explicitly sets the colors from the palette for some of the
elements of the SideBar.
It also removes the usage of Basic.darkShade color, which is not
available in general case, replacing it with the palette.dark color.
A more complicated problem was related to the icons in buttonDelegate
and addFavoriteDelegate, that were not updating their colors.
The reason for that was that the unrelying C++ code was constructing
the delegates using QQmlComponent::createWithInitialProperties(), and
passed a QQuickIcon object as one of the properties. As a result, the
original binding on icon.color was removed.
To keep the binding, construct the components with a default icon,
then manually set the source and the size. This approach is slower,
but it allows to preserve the original binding from the QtQuick Button
component.
Last affected element was the drag pixmap, which was always using
the original color. Use the buttonText() palette color to update
all the non-transparent pixels of the icon before using it in the
drag.
Fixes: QTBUG-122738
Pick-to: 6.10 6.9
Change-Id: Ibf4182b1c5a631fe7043e8d76ed98629c69ab4d6
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/quickdialogs/quickdialogsquickimpl')
4 files changed, 78 insertions, 48 deletions
diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/SideBar.qml b/src/quickdialogs/quickdialogsquickimpl/qml/SideBar.qml index ce96cf55b9..8c49991509 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/SideBar.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/SideBar.qml @@ -15,7 +15,7 @@ DialogsQuickImpl.SideBar { implicitContentHeight + topPadding + bottomPadding) background: Rectangle { - border.color: control.palette.button + color: control.palette.window } contentItem: ListView { @@ -39,12 +39,13 @@ DialogsQuickImpl.SideBar { icon: buttonDelegateRoot.icon text: buttonDelegateRoot.folderName font: buttonDelegateRoot.font + // same as the icon color + color: buttonDelegateRoot.icon.color alignment: Qt.AlignLeft } required property int index required property string folderName - required icon } separatorDelegate: Item { @@ -52,7 +53,7 @@ DialogsQuickImpl.SideBar { height: 9 Rectangle { id: separatorDelegate - color: Qt.lighter(Basic.darkShade, 1.06) + color: Qt.lighter(control.palette.dark, 1.06) anchors.centerIn: parent radius: 1 height: 1 @@ -72,12 +73,13 @@ DialogsQuickImpl.SideBar { icon: addFavoriteDelegateRoot.icon text: addFavoriteDelegateRoot.labelText font: addFavoriteDelegateRoot.font + // same as the icon color + color: addFavoriteDelegateRoot.icon.color alignment: Qt.AlignLeft opacity: addFavoriteDelegateRoot.dragHovering ? 0.2 : 1.0 } required property string labelText required property bool dragHovering - required icon } } diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickfiledialogdelegate.cpp b/src/quickdialogs/quickdialogsquickimpl/qquickfiledialogdelegate.cpp index 88f1370135..b034cdd7e8 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qquickfiledialogdelegate.cpp +++ b/src/quickdialogs/quickdialogsquickimpl/qquickfiledialogdelegate.cpp @@ -204,7 +204,34 @@ void QQuickFileDialogTapHandler::grabFolder() if (m_drag.isNull()) return; - QPixmap pixmap(":/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/sidebar-folder.png"_L1); + QQuickPalette *palette = [this]() -> QQuickPalette* { + auto *delegate = qobject_cast<QQuickFileDialogDelegate*>(parent()); + if (delegate) { + QQuickDialog *dlg = delegate->dialog(); + if (dlg) { + QQuickDialogPrivate *priv = QQuickDialogPrivate::get(dlg); + if (priv) + return priv->palette(); + } + } + return nullptr; + }(); + + // TODO: use proper @Nx scaling + const auto src = ":/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/sidebar-folder.png"_L1; + QImage img = QImage(src).convertToFormat(QImage::Format_ARGB32); + + if (!img.isNull() && palette) { + const QColor iconColor = palette->buttonText(); + if (iconColor.alpha() > 0) { + // similar to what QQuickIconImage does + QPainter painter(&img); + painter.setCompositionMode(QPainter::CompositionMode_SourceIn); + painter.fillRect(img.rect(), iconColor); + } + } + + QPixmap pixmap = QPixmap::fromImage(std::move(img)); auto *mimeData = new QMimeData(); mimeData->setImageData(pixmap); m_drag->setMimeData(mimeData); diff --git a/src/quickdialogs/quickdialogsquickimpl/qquicksidebar.cpp b/src/quickdialogs/quickdialogsquickimpl/qquicksidebar.cpp index 38b3067d66..6232beba53 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qquicksidebar.cpp +++ b/src/quickdialogs/quickdialogsquickimpl/qquicksidebar.cpp @@ -233,18 +233,31 @@ void QQuickSideBarPrivate::repopulate() QScopedValueRollback repopulateGuard(repopulating, true); - auto createButtonDelegate = [this, q](int index, const QString &folderPath, const QQuickIcon& icon) { + auto updateIconSourceAndSize = [this](QQuickAbstractButton *button, const QUrl &iconUrl) { + // we need to preserve the default binding on icon.color, so + // we just take the default-created icon, and update its source + // and size + QQuickIcon icon = button->icon(); + icon.setSource(iconUrl); + const QSize iconSize = dialogIconSize(); + icon.setWidth(iconSize.width()); + icon.setHeight(iconSize.height()); + button->setIcon(icon); + }; + + auto createButtonDelegate = [this, q, &updateIconSourceAndSize](int index, const QString &folderPath, const QUrl &iconUrl) { const QString displayName = displayNameFromFolderPath(folderPath); QVariantMap initialProperties = { { "index"_L1, QVariant::fromValue(index) }, { "folderName"_L1, QVariant::fromValue(displayName) }, - { "icon"_L1, QVariant::fromValue(icon) }, }; if (QQuickItem *buttonItem = createDelegateItem(buttonDelegate, initialProperties)) { - if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(buttonItem)) + if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(buttonItem)) { QObjectPrivate::connect(button, &QQuickAbstractButton::clicked, this, &QQuickSideBarPrivate::buttonClicked); + updateIconSourceAndSize(button, iconUrl); + } insertItem(q->count(), buttonItem); } }; @@ -260,7 +273,7 @@ void QQuickSideBarPrivate::repopulate() int insertIndex = 0; for (auto &folder : folders) - createButtonDelegate(insertIndex++, QStandardPaths::displayName(folder), folderIcon(folder)); + createButtonDelegate(insertIndex++, QStandardPaths::displayName(folder), folderIconSource(folder)); if (showSeparator) if (QQuickItem *separatorItem = createDelegateItem(separatorDelegate, {})) @@ -270,17 +283,19 @@ void QQuickSideBarPrivate::repopulate() // the variant needs to be QString, not a QLatin1StringView const QString labelText = QCoreApplication::translate("FileDialog", "Add Favorite"); QVariantMap initialProperties = { - { "icon"_L1, QVariant::fromValue(addFavoriteIcon()) }, { "labelText"_L1, QVariant::fromValue(labelText) }, { "dragHovering"_L1, QVariant::fromValue(addFavoriteDelegateHovered()) }, }; - if (auto *addFavoriteDelegateItem = createDelegateItem(addFavoriteDelegate, initialProperties)) + if (auto *addFavoriteDelegateItem = createDelegateItem(addFavoriteDelegate, initialProperties)) { + if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(addFavoriteDelegateItem)) + updateIconSourceAndSize(button, addFavoriteIconUrl()); insertItem(insertIndex++, addFavoriteDelegateItem); + } } // calculate the starting index for the favorites for (auto &favorite : favorites) - createButtonDelegate(insertIndex++, favorite.toLocalFile(), folderIcon()); + createButtonDelegate(insertIndex++, favorite.toLocalFile(), folderIconSource()); q->setCurrentIndex(-1); } @@ -340,47 +355,36 @@ void QQuickSideBar::componentComplete() d->initContextMenu(); } -QQuickIcon QQuickSideBarPrivate::folderIcon() const +QUrl QQuickSideBarPrivate::folderIconSource() const { - QQuickIcon icon; - icon.setSource(QUrl("../images/sidebar-folder.png"_L1)); - icon.setWidth(16); - icon.setHeight(16); - return icon; + return QUrl("../images/sidebar-folder.png"_L1); } -QQuickIcon QQuickSideBarPrivate::folderIcon(QStandardPaths::StandardLocation stdLocation) const +QUrl QQuickSideBarPrivate::folderIconSource(QStandardPaths::StandardLocation stdLocation) const { - QQuickIcon icon; switch (stdLocation) { case QStandardPaths::DesktopLocation: - icon.setSource(QUrl("../images/sidebar-desktop.png"_L1)); - break; + return QUrl("../images/sidebar-desktop.png"_L1); case QStandardPaths::DocumentsLocation: - icon.setSource(QUrl("../images/sidebar-documents.png"_L1)); - break; + return QUrl("../images/sidebar-documents.png"_L1); case QStandardPaths::MusicLocation: - icon.setSource(QUrl("../images/sidebar-music.png"_L1)); - break; + return QUrl("../images/sidebar-music.png"_L1); case QStandardPaths::MoviesLocation: - icon.setSource(QUrl("../images/sidebar-video.png"_L1)); - break; + return QUrl("../images/sidebar-video.png"_L1); case QStandardPaths::PicturesLocation: - icon.setSource(QUrl("../images/sidebar-photo.png"_L1)); - break; + return QUrl("../images/sidebar-photo.png"_L1); case QStandardPaths::HomeLocation: - icon.setSource(QUrl("../images/sidebar-home.png"_L1)); - break; + return QUrl("../images/sidebar-home.png"_L1); case QStandardPaths::DownloadLocation: - icon.setSource(QUrl("../images/sidebar-downloads.png"_L1)); - break; + return QUrl("../images/sidebar-downloads.png"_L1); default: - icon.setSource(QUrl("../images/sidebar-folder.png"_L1)); - break; + return QUrl("../images/sidebar-folder.png"_L1); } - icon.setWidth(16); - icon.setHeight(16); - return icon; +} + +QSize QQuickSideBarPrivate::dialogIconSize() const +{ + return QSize(16, 16); } #if QT_CONFIG(settings) @@ -473,13 +477,9 @@ void QQuickSideBarPrivate::setAddFavoriteDelegateHovered(bool hovered) repopulate(); } -QQuickIcon QQuickSideBarPrivate::addFavoriteIcon() const +QUrl QQuickSideBarPrivate::addFavoriteIconUrl() const { - QQuickIcon icon; - icon.setSource(QUrl("../images/sidebar-plus.png"_L1)); - icon.setWidth(16); - icon.setHeight(16); - return icon; + return QUrl("../images/sidebar-plus.png"_L1); } void QQuickSideBarPrivate::initContextMenu() diff --git a/src/quickdialogs/quickdialogsquickimpl/qquicksidebar_p_p.h b/src/quickdialogs/quickdialogsquickimpl/qquicksidebar_p_p.h index 42dcfdf2c6..047425a988 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qquicksidebar_p_p.h +++ b/src/quickdialogs/quickdialogsquickimpl/qquicksidebar_p_p.h @@ -40,8 +40,9 @@ public: QUrl dialogFolder() const; void setDialogFolder(const QUrl &folder); QString displayNameFromFolderPath(const QString &filePath); - QQuickIcon folderIcon() const; - QQuickIcon folderIcon(QStandardPaths::StandardLocation stdLocation) const; + QUrl folderIconSource() const; + QUrl folderIconSource(QStandardPaths::StandardLocation stdLocation) const; + QSize dialogIconSize() const; void folderChanged(); void readSettings(); @@ -53,7 +54,7 @@ public: void setShowAddFavoriteDelegate(bool show); bool addFavoriteDelegateHovered() const; void setAddFavoriteDelegateHovered(bool hovered); - QQuickIcon addFavoriteIcon() const; + QUrl addFavoriteIconUrl() const; void initContextMenu(); void handleContextMenuRequested(QPointF pos); |
