mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-02 15:45:21 +00:00
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
This commit is contained in:
parent
36adcd8fc0
commit
53e68b9435
@ -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<const SoundDevicePort *>(port), itemDataRole);
|
||||
portItem->setData(port->isActive(), itemCheckRole);
|
||||
portItem->setData(AUDIOPORT, itemFlagRole);
|
||||
portItem->setData(QVariant::fromValue<const SoundDevicePort *>(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 *>();
|
||||
const SoundDevicePort *port = item->data(DeviceObjRole).value<const SoundDevicePort *>();
|
||||
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 *>();
|
||||
const SoundDevicePort *port = m_model->data(index, DeviceObjRole).value<const SoundDevicePort *>();
|
||||
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<const SoundDevicePort *>();
|
||||
item->setData((soundPort && soundPort->id() == portId && soundPort->cardId() == cardId), itemCheckRole);
|
||||
const SoundDevicePort *soundPort = item->data(DeviceObjRole).value<const SoundDevicePort *>();
|
||||
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();
|
||||
|
@ -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<SoundDevicePort *> m_ports;
|
||||
};
|
||||
|
||||
|
@ -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 <DListView>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <DGuiApplicationHelper>
|
||||
#include <QPainterPath>
|
||||
|
||||
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<QIcon>();
|
||||
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<QMouseEvent *>(event);
|
||||
if (rctIndex.contains(mouseEvent->pos()))
|
||||
Q_EMIT selectIndexChanged(index);
|
||||
}
|
||||
|
||||
return DStyledItemDelegate::editorEvent(event, model, option, index);
|
||||
}
|
@ -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 <DStyledItemDelegate>
|
||||
|
||||
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
|
Loading…
x
Reference in New Issue
Block a user