aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickdialogs/quickdialogsquickimpl
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2025-06-10 16:31:16 +0200
committerIvan Solovev <ivan.solovev@qt.io>2025-06-13 12:15:41 +0200
commit7322e051c9c3d8dc715c20a3d42d9be83ea2295c (patch)
tree4b13c016a33e3793ef51e3e77d1db940596a5249 /src/quickdialogs/quickdialogsquickimpl
parent2d4bebdb51bbf720fe719f5e6ea54b04bde36510 (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')
-rw-r--r--src/quickdialogs/quickdialogsquickimpl/qml/SideBar.qml10
-rw-r--r--src/quickdialogs/quickdialogsquickimpl/qquickfiledialogdelegate.cpp29
-rw-r--r--src/quickdialogs/quickdialogsquickimpl/qquicksidebar.cpp80
-rw-r--r--src/quickdialogs/quickdialogsquickimpl/qquicksidebar_p_p.h7
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);