From 53e68b94358674d6f46049c8a6fce78dc351a96e Mon Sep 17 00:00:00 2001 From: zsien Date: Tue, 7 Mar 2023 11:33:19 +0800 Subject: [PATCH] fix: abnormal display of sound output device list Delete custom delegates and use the native DListView state. * Fix abnormal display of checked icons * Fix abnormal display of edit box. Fixes linuxdeepin/developer-center#3793 Fixes linuxdeepin/developer-center#3741 --- plugins/sound/sounddeviceswidget.cpp | 50 ++++++++------- plugins/sound/sounddeviceswidget.h | 2 - widgets/settingdelegate.cpp | 95 ---------------------------- widgets/settingdelegate.h | 33 ---------- 4 files changed, 27 insertions(+), 153 deletions(-) delete mode 100644 widgets/settingdelegate.cpp delete mode 100644 widgets/settingdelegate.h diff --git a/plugins/sound/sounddeviceswidget.cpp b/plugins/sound/sounddeviceswidget.cpp index 81a4ce6c5..77f02a23d 100644 --- a/plugins/sound/sounddeviceswidget.cpp +++ b/plugins/sound/sounddeviceswidget.cpp @@ -4,7 +4,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "sounddeviceswidget.h" -#include "settingdelegate.h" #include "imageutil.h" #include "slidercontainer.h" #include "sounddeviceport.h" @@ -30,13 +29,16 @@ DWIDGET_USE_NAMESPACE #define ITEMSPACE 16 #define ROWSPACE 10 #define DESCRIPTIONHEIGHT 15 -#define ITEMRADIUS 12 #define SLIDERHEIGHT 36 #define AUDIOPORT 0 #define AUDIOSETTING 1 -const int sortRole = itemFlagRole + 1; +enum ItemRole { + DeviceObjRole = Dtk::UserRole + 1, + ItemTypeRole, + SortRole, +}; SoundDevicesWidget::SoundDevicesWidget(QWidget *parent) : QWidget(parent) @@ -47,7 +49,6 @@ SoundDevicesWidget::SoundDevicesWidget(QWidget *parent) , m_soundInter(new DBusAudio("org.deepin.dde.Audio1", "/org/deepin/dde/Audio1", QDBusConnection::sessionBus(), this)) , m_sinkInter(new DBusSink("org.deepin.dde.Audio1", m_soundInter->defaultSink().path(), QDBusConnection::sessionBus(), this)) , m_model(new QStandardItemModel(this)) - , m_delegate(new SettingDelegate(m_deviceList)) { initUi(); initConnection(); @@ -112,24 +113,23 @@ void SoundDevicesWidget::initUi() m_deviceList->setModel(m_model); m_deviceList->setViewMode(QListView::ListMode); m_deviceList->setMovement(QListView::Free); - m_deviceList->setItemRadius(ITEMRADIUS); m_deviceList->setWordWrap(false); m_deviceList->verticalScrollBar()->setVisible(false); m_deviceList->horizontalScrollBar()->setVisible(false); + m_deviceList->setBackgroundType(DStyledItemDelegate::BackgroundType::RoundedBackground); m_deviceList->setOrientation(QListView::Flow::TopToBottom, false); layout->addWidget(m_deviceList); m_deviceList->setSpacing(ROWSPACE); - m_deviceList->setItemDelegate(m_delegate); - m_model->setSortRole(sortRole); + m_model->setSortRole(SortRole); m_descriptionLabel->setFixedHeight(DESCRIPTIONHEIGHT); // 增加音量设置 DStandardItem *settingItem = new DStandardItem; settingItem->setText(tr("Sound settings")); settingItem->setFlags(Qt::NoItemFlags); - settingItem->setData(false, itemCheckRole); - settingItem->setData(AUDIOSETTING, itemFlagRole); + settingItem->setCheckable(Qt::Unchecked); + settingItem->setData(AUDIOSETTING, ItemTypeRole); m_model->appendRow(settingItem); m_sliderParent->installEventFilter(this); @@ -196,7 +196,7 @@ void SoundDevicesWidget::initConnection() connect(m_sinkInter, &DBusSink::VolumeChanged, this, [ = ](double value) { m_sliderContainer->updateSliderValue(value * 100); }); connect(m_sinkInter, &DBusSink::MuteChanged, this, [ = ] { m_sliderContainer->updateSliderValue(m_sinkInter->volume() * 100); }); connect(m_soundInter, &DBusAudio::DefaultSinkChanged, this, &SoundDevicesWidget::onDefaultSinkChanged); - connect(m_delegate, &SettingDelegate::selectIndexChanged, this, &SoundDevicesWidget::onSelectIndexChanged); + connect(m_deviceList->selectionModel(), &QItemSelectionModel::currentChanged, this, &SoundDevicesWidget::onSelectIndexChanged); connect(m_soundInter, &DBusAudio::PortEnabledChanged, this, &SoundDevicesWidget::onAudioDevicesChanged); connect(m_soundInter, &DBusAudio::CardsWithoutUnavailableChanged, this, &SoundDevicesWidget::onAudioDevicesChanged); connect(m_soundInter, &DBusAudio::MaxUIVolumeChanged, this, [ = ] (double maxValue) { @@ -239,9 +239,8 @@ void SoundDevicesWidget::addPort(const SoundDevicePort *port) portItem->setIcon(QIcon(soundIconFile())); portItem->setText(deviceName); portItem->setTextColorRole(QPalette::BrightText); - portItem->setData(QVariant::fromValue(port), itemDataRole); - portItem->setData(port->isActive(), itemCheckRole); - portItem->setData(AUDIOPORT, itemFlagRole); + portItem->setData(QVariant::fromValue(port), DeviceObjRole); + portItem->setData(AUDIOPORT, ItemTypeRole); connect(port, &SoundDevicePort::nameChanged, this, [ = ](const QString &str) { QString devName = str + "(" + port->cardName() + ")"; @@ -265,10 +264,10 @@ void SoundDevicesWidget::addPort(const SoundDevicePort *port) int rowCount = m_model->rowCount(); for (int i = 0; i < rowCount; i++) { QStandardItem *item = m_model->item(i); - if (item->data(itemFlagRole).toInt() == AUDIOSETTING) { - item->setData(rowCount - 1, sortRole); + if (item->data(ItemTypeRole).toInt() == AUDIOSETTING) { + item->setData(rowCount - 1, SortRole); } else { - item->setData(row, sortRole); + item->setData(row, SortRole); row++; } } @@ -285,10 +284,10 @@ void SoundDevicesWidget::removePort(const QString &portId, const uint &cardId) int removeRow = -1; for (int i = 0; i < m_model->rowCount(); i++) { QStandardItem *item = m_model->item(i); - if (item->data(itemFlagRole).toInt() != AUDIOPORT) + if (item->data(ItemTypeRole).toInt() != AUDIOPORT) continue; - const SoundDevicePort *port = item->data(itemDataRole).value(); + const SoundDevicePort *port = item->data(DeviceObjRole).value(); if (port && port->id() == portId && cardId == port->cardId()) { removeRow = i; break; @@ -419,9 +418,9 @@ SoundDevicePort *SoundDevicesWidget::findPort(const QString &portId, const uint void SoundDevicesWidget::onSelectIndexChanged(const QModelIndex &index) { - int flag = index.data(itemFlagRole).toInt(); + int flag = index.data(ItemTypeRole).toInt(); if (flag == AUDIOPORT) { - const SoundDevicePort *port = m_model->data(index, itemDataRole).value(); + const SoundDevicePort *port = m_model->data(index, DeviceObjRole).value(); if (port) { m_soundInter->SetPort(port->cardId(), port->id(), int(port->direction())); //手动勾选时启用设备 @@ -449,13 +448,18 @@ void SoundDevicesWidget::onDefaultSinkChanged(const QDBusObjectPath &value) uint cardId = m_sinkInter->card(); activePort(portId, cardId); + auto *sm = m_deviceList->selectionModel(); for (int i = 0; i < m_model->rowCount() ; i++) { QStandardItem *item = m_model->item(i); - if (item->data(itemFlagRole).toInt() != AUDIOPORT) + if (item->data(ItemTypeRole).toInt() != AUDIOPORT) continue; - const SoundDevicePort *soundPort = item->data(itemDataRole).value(); - item->setData((soundPort && soundPort->id() == portId && soundPort->cardId() == cardId), itemCheckRole); + const SoundDevicePort *soundPort = item->data(DeviceObjRole).value(); + bool checked = soundPort && soundPort->id() == portId && soundPort->cardId() == cardId; + item->setCheckState(checked ? Qt::Checked : Qt::Unchecked); + if (checked) { + sm->setCurrentIndex(item->index(), QItemSelectionModel::ClearAndSelect); + } } resetVolumeInfo(); diff --git a/plugins/sound/sounddeviceswidget.h b/plugins/sound/sounddeviceswidget.h index b022ad5b5..3a7bdf566 100644 --- a/plugins/sound/sounddeviceswidget.h +++ b/plugins/sound/sounddeviceswidget.h @@ -22,7 +22,6 @@ class QStandardItemModel; class QLabel; class VolumeModel; class AudioSink; -class SettingDelegate; class SoundDevicePort; using DBusAudio = org::deepin::dde::Audio1; @@ -81,7 +80,6 @@ private: DBusAudio *m_soundInter; DBusSink *m_sinkInter; QStandardItemModel *m_model; - SettingDelegate *m_delegate; QList m_ports; }; diff --git a/widgets/settingdelegate.cpp b/widgets/settingdelegate.cpp deleted file mode 100644 index 062265657..000000000 --- a/widgets/settingdelegate.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. -// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#include "settingdelegate.h" - -#include -#include -#include -#include -#include - -DWIDGET_USE_NAMESPACE - -SettingDelegate::SettingDelegate(QAbstractItemView *parent) - : DStyledItemDelegate(parent) -{ - parent->installEventFilter(this); -} - -SettingDelegate::~SettingDelegate() -{ -} - -void SettingDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - painter->save(); - - QRect indexRect = option.rect; - // 绘制背景色 - bool isOver = option.state & QStyle::State_MouseOver; - bool isDefault = index.data(itemCheckRole).toBool(); - if (isDefault) { - QPainterPath path, path1; - path.addRoundedRect(indexRect, 8, 8); - - DPalette palette = DGuiApplicationHelper::instance()->applicationPalette(); - painter->fillPath(path, palette.color(QPalette::ColorRole::Highlight)); - } else { - QPainterPath path; - path.addRoundedRect(indexRect, 8, 8); - painter->fillPath(path, isOver ? QColor(0, 0, 0, 100) : QColor(0, 0, 0, 64)); - } - // 绘制图标 - QRect rectIcon = indexRect; - rectIcon.setX(20); - QIcon icon = index.data(Qt::DecorationRole).value(); - QPixmap pixmap(icon.pixmap(16, 16)); - rectIcon.setY(indexRect.y() + (rectIcon.height() - pixmap.height()) / 2); - rectIcon.setWidth(pixmap.width()); - rectIcon.setHeight(pixmap.height()); - painter->drawPixmap(rectIcon, pixmap); -#define RIGHTSPACE 11 -#define SELECTICONSIZE 10 - // 绘制文本 - QRect rectText; - rectText.setX(rectIcon.left() + rectIcon.width() + 8); - rectText.setWidth(indexRect.width() - rectText.x() - RIGHTSPACE - SELECTICONSIZE - 5); - QPen pen(isDefault ? QColor(255, 255, 255) : QColor(0, 0, 0)); - pen.setWidth(2); - painter->setPen(pen); - QFont ft(DFontSizeManager::instance()->t6()); - QFontMetrics ftm(ft); - QString text = QFontMetrics(ft).elidedText(index.data(Qt::DisplayRole).toString(), Qt::TextElideMode::ElideRight, - rectText.width()); - painter->setFont(ft); - rectText.setY(indexRect.y() + (indexRect.height() - QFontMetrics(ft).height()) / 2); - rectText.setHeight(QFontMetrics(ft).height()); - painter->drawText(rectText, text); - // 如果当前是默认的输出设备,则绘制右侧的对钩 - if (isDefault) { - QPointF points[3] = { - QPointF(indexRect.width() - RIGHTSPACE - SELECTICONSIZE, indexRect.center().y()), - QPointF(indexRect.width() - RIGHTSPACE - SELECTICONSIZE / 2, rectIcon.bottom() + 2), - QPointF(indexRect.width() - RIGHTSPACE, rectIcon.top() - 2) - }; - painter->drawPolyline(points, 3); - } - - painter->restore(); -} - -bool SettingDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ - if (event->type() == QEvent::MouseButtonRelease) { - QRect rctIndex = option.rect; - rctIndex.setHeight(rctIndex.height() - spacing()); - QMouseEvent *mouseEvent = static_cast(event); - if (rctIndex.contains(mouseEvent->pos())) - Q_EMIT selectIndexChanged(index); - } - - return DStyledItemDelegate::editorEvent(event, model, option, index); -} diff --git a/widgets/settingdelegate.h b/widgets/settingdelegate.h deleted file mode 100644 index 475de8c34..000000000 --- a/widgets/settingdelegate.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. -// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#ifndef SETTINGDELEGATE_H -#define SETTINGDELEGATE_H - -#include - -DWIDGET_USE_NAMESPACE - -static const int itemCheckRole = Dtk::UserRole + 1; -static const int itemDataRole = Dtk::UserRole + 2; -static const int itemFlagRole = Dtk::UserRole + 3; - -class SettingDelegate : public DStyledItemDelegate -{ - Q_OBJECT - -public: - explicit SettingDelegate(QAbstractItemView *parent = nullptr); - ~SettingDelegate() override; - -Q_SIGNALS: - void selectIndexChanged(const QModelIndex &); - -protected: - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override; -}; - -#endif // SETTINGDELEGATE_H