mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-03 00:15:21 +00:00
fix: 修复快捷设置面板的图标在高缩放率下显示模糊
带背景的圆底图标不再通过自动创建,因为无法控制周边的锯齿,统一在paintEvent函数中进行绘制。修改滑动条统一通过代理来进行绘制 Log: Influence: 屏幕设置高缩放率,任务栏特效模式下,查看快捷面板图标是否正常显示 Bug: https://pms.uniontech.com/task-view-149623.html Change-Id: I825e38a9ae8c5a4252be840193e44393ac129201
This commit is contained in:
parent
fc181973ce
commit
3824e9d9bb
@ -24,6 +24,7 @@
|
||||
|
||||
#include <DGuiApplicationHelper>
|
||||
#include <DFontSizeManager>
|
||||
#include <DPaletteHelper>
|
||||
|
||||
#include <QIcon>
|
||||
#include <QPainterPath>
|
||||
@ -106,7 +107,8 @@ void QuickSettingItem::paintEvent(QPaintEvent *e)
|
||||
painter.setClipPath(path);
|
||||
|
||||
// 绘制背景色
|
||||
painter.fillRect(rect(), backgroundColor());
|
||||
DPalette dpa = DPaletteHelper::instance()->palette(this);
|
||||
painter.fillRect(rect(), dpa.brush(DPalette::ColorRole::Mid));
|
||||
// 让图标填上前景色
|
||||
int pixmapWidth = static_cast<int>(ICONWIDTH * qApp->devicePixelRatio());
|
||||
int pixmapHeight = static_cast<int>(ICONHEIGHT * qApp->devicePixelRatio());
|
||||
@ -129,7 +131,7 @@ void QuickSettingItem::paintEvent(QPaintEvent *e)
|
||||
QRect iconBg(MARGINLEFTSPACE, marginYSpace, BGSIZE, BGSIZE);
|
||||
painter.save();
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(shadowColor());
|
||||
painter.setBrush(dpa.brush(DPalette::ColorRole::Midlight));
|
||||
painter.drawEllipse(iconBg);
|
||||
painter.restore();
|
||||
QRect rctIcon(iconBg.x() + (iconBg.width() - pixmapWidth) / 2,
|
||||
@ -185,32 +187,15 @@ QRect QuickSettingItem::iconRect()
|
||||
|
||||
QColor QuickSettingItem::foregroundColor() const
|
||||
{
|
||||
DPalette dpa = DPaletteHelper::instance()->palette(this);
|
||||
// 此处的颜色是临时获取的,后期需要和设计师确认,改成正规的颜色
|
||||
if (m_pluginInter->status() == PluginsItemInterface::PluginStatus::Active)
|
||||
return QColor(0, 129, 255);
|
||||
return dpa.color(DPalette::ColorGroup::Active, DPalette::ColorRole::Text);
|
||||
|
||||
if (m_pluginInter->status() == PluginsItemInterface::PluginStatus::Deactive)
|
||||
return QColor(51, 51, 51);
|
||||
return dpa.color(DPalette::ColorGroup::Disabled, DPalette::ColorRole::Text);
|
||||
|
||||
return QColor(181, 181, 181);
|
||||
}
|
||||
|
||||
QColor QuickSettingItem::backgroundColor() const
|
||||
{
|
||||
// 此处的颜色是临时获取的,后期需要和设计师确认,改成正规的颜色
|
||||
if (m_pluginInter->status() == PluginsItemInterface::PluginStatus::Active)
|
||||
return QColor(250, 250, 252);
|
||||
|
||||
return QColor(241, 241, 246);
|
||||
}
|
||||
|
||||
QColor QuickSettingItem::shadowColor() const
|
||||
{
|
||||
// 此处的颜色是临时获取的,后期需要和设计师确认,改成正规的颜色
|
||||
if (m_pluginInter->status() == PluginsItemInterface::PluginStatus::Active)
|
||||
return QColor(217, 219, 226);
|
||||
|
||||
return QColor(199, 203, 222);
|
||||
return dpa.color(DPalette::ColorGroup::Normal, DPalette::ColorRole::Text);
|
||||
}
|
||||
|
||||
void QuickSettingItem::mouseReleaseEvent(QMouseEvent *event)
|
||||
|
@ -47,8 +47,6 @@ protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
QRect iconRect();
|
||||
QColor foregroundColor() const;
|
||||
QColor backgroundColor() const;
|
||||
QColor shadowColor() const;
|
||||
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
|
@ -84,36 +84,3 @@ QCursor* ImageUtil::loadQCursorFromX11Cursor(const char* theme, const char* curs
|
||||
XcursorImagesDestroy(images);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
const QPixmap ImageUtil::getShadowPixmap(const QPixmap &pixmap, const QColor &shadowColor, const QSize &backSize)
|
||||
{
|
||||
// 新建一个bitmap作为遮罩,尺寸为外部指定(backSize)
|
||||
QBitmap bitmap(backSize);
|
||||
QPainter painter(&bitmap);
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
painter.setPen(Qt::NoPen);
|
||||
// 往bitmap上绘制圆形区域
|
||||
QRect rectBackground(0, 0, backSize.width(), backSize.height());
|
||||
painter.fillRect(rectBackground, Qt::white);
|
||||
painter.setBrush(Qt::black);
|
||||
painter.drawEllipse(0, 0, backSize.width(), backSize.height());
|
||||
|
||||
// 新建QPixmap,将上述新建的Bitmap作为它的遮罩
|
||||
QPixmap newPixmap(backSize);
|
||||
newPixmap.setMask(bitmap);
|
||||
QPainter pixPainter(&newPixmap);
|
||||
pixPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
const QSize iconSize = pixmap.size();
|
||||
int startX = (backSize.width() - iconSize.width()) / 2;
|
||||
int startY = (backSize.height() - iconSize.height()) / 2;
|
||||
// 将传入参数的背景尺寸(backSize)作为背景,通过画笔路径在上面绘制圆形区域
|
||||
QRect rectPixmap(startX, startY, iconSize.width(), iconSize.height());
|
||||
QPainterPath path;
|
||||
path.addEllipse(rectBackground);
|
||||
pixPainter.fillPath(path, shadowColor);
|
||||
// 将图像绘制到新建的QPixmap的背景区域,并返回新的QPixmap
|
||||
pixPainter.drawPixmap(rectPixmap, pixmap);
|
||||
pixPainter.setPen(shadowColor);
|
||||
pixPainter.drawEllipse(rectBackground);
|
||||
return newPixmap;
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ public:
|
||||
static const QPixmap loadSvg(const QString &iconName, const QString &localPath, const int size, const qreal ratio);
|
||||
static const QPixmap loadSvg(const QString &iconName, const QSize size, const qreal ratio = qApp->devicePixelRatio());
|
||||
static QCursor* loadQCursorFromX11Cursor(const char* theme, const char* cursorName, int cursorSize);
|
||||
static const QPixmap getShadowPixmap(const QPixmap &pixmap, const QColor &shadowColor, const QSize &backSize);
|
||||
};
|
||||
|
||||
#endif // IMAGEUTIL_H
|
||||
|
@ -20,8 +20,9 @@
|
||||
*/
|
||||
#include "brightnessmonitorwidget.h"
|
||||
#include "brightnessmodel.h"
|
||||
#include "customslider.h"
|
||||
#include "slidercontainer.h"
|
||||
#include "settingdelegate.h"
|
||||
#include "imageutil.h"
|
||||
|
||||
#include <DListView>
|
||||
#include <DDBusSender>
|
||||
@ -72,14 +73,20 @@ void BrightnessMonitorWidget::initUi()
|
||||
|
||||
QList<BrightMonitor *> monitors = m_brightModel->monitors();
|
||||
for (BrightMonitor *monitor : monitors) {
|
||||
SliderContainer *container = new SliderContainer(CustomSlider::Normal, m_sliderWidget);
|
||||
SliderContainer *container = new SliderContainer(m_sliderWidget);
|
||||
container->setTitle(monitor->name());
|
||||
container->slider()->setIconSize(QSize(20, 20));
|
||||
container->slider()->setLeftIcon(QIcon(":/icons/resources/brightnesslow"));
|
||||
container->slider()->setRightIcon(QIcon(":/icons/resources/brightnesshigh"));
|
||||
QPixmap leftPixmap = ImageUtil::loadSvg(":/icons/resources/brightnesslow", QSize(20, 20));
|
||||
QPixmap rightPixmap = ImageUtil::loadSvg(":/icons/resources/brightnesshigh", QSize(20, 20));
|
||||
container->updateSlider(SliderContainer::IconPosition::LeftIcon, { leftPixmap.size(), QSize(), leftPixmap, 12 });
|
||||
container->updateSlider(SliderContainer::IconPosition::RightIcon, { rightPixmap.size(), QSize(), rightPixmap, 12 });
|
||||
|
||||
container->setFixedHeight(50);
|
||||
m_sliderLayout->addWidget(container);
|
||||
|
||||
SliderProxyStyle *proxy = new SliderProxyStyle(SliderProxyStyle::Normal);
|
||||
proxy->setParent(container->slider());
|
||||
container->slider()->setStyle(proxy);
|
||||
|
||||
m_sliderContainers << qMakePair(monitor, container);
|
||||
}
|
||||
|
||||
@ -122,9 +129,9 @@ void BrightnessMonitorWidget::initConnection()
|
||||
});
|
||||
|
||||
for (QPair<BrightMonitor *, SliderContainer *> container : m_sliderContainers) {
|
||||
SliderContainer *slider = container.second;
|
||||
slider->slider()->setValue(container.first->brihtness());
|
||||
connect(slider->slider(), &CustomSlider::valueChanged, this, [ = ](int value) {
|
||||
SliderContainer *sliderContainer = container.second;
|
||||
sliderContainer->slider()->setValue(container.first->brihtness());
|
||||
connect(sliderContainer->slider(), &QSlider::valueChanged, this, [ this, container ](int value) {
|
||||
m_brightModel->setBrightness(container.first, value);
|
||||
});
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <QWidget>
|
||||
|
||||
class QLabel;
|
||||
class CustomSlider;
|
||||
class SliderContainer;
|
||||
class BrightnessModel;
|
||||
class QStandardItemModel;
|
||||
class QVBoxLayout;
|
||||
|
@ -19,33 +19,33 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "brightnesswidget.h"
|
||||
#include "customslider.h"
|
||||
#include "brightnessmodel.h"
|
||||
#include "brightnessmonitorwidget.h"
|
||||
#include "imageutil.h"
|
||||
#include "slidercontainer.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QDebug>
|
||||
|
||||
#define BACKSIZE 36
|
||||
#define IMAGESIZE 24
|
||||
#define IMAGESIZE 18
|
||||
|
||||
BrightnessWidget::BrightnessWidget(QWidget *parent)
|
||||
BrightnessWidget::BrightnessWidget(BrightnessModel *model, QWidget *parent)
|
||||
: DBlurEffectWidget(parent)
|
||||
, m_slider(new CustomSlider(CustomSlider::SliderType::Normal, this))
|
||||
, m_model(new BrightnessModel(this))
|
||||
, m_sliderContainer(new SliderContainer(this))
|
||||
, m_model(model)
|
||||
{
|
||||
initUi();
|
||||
initConenction();
|
||||
initConnection();
|
||||
}
|
||||
|
||||
BrightnessWidget::~BrightnessWidget()
|
||||
{
|
||||
}
|
||||
|
||||
BrightnessModel *BrightnessWidget::model()
|
||||
SliderContainer *BrightnessWidget::sliderContainer()
|
||||
{
|
||||
return m_model;
|
||||
return m_sliderContainer;
|
||||
}
|
||||
|
||||
void BrightnessWidget::showEvent(QShowEvent *event)
|
||||
@ -63,30 +63,22 @@ void BrightnessWidget::hideEvent(QHideEvent *event)
|
||||
void BrightnessWidget::initUi()
|
||||
{
|
||||
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(20, 0, 20, 0);
|
||||
layout->addWidget(m_slider);
|
||||
layout->setContentsMargins(15, 0, 12, 0);
|
||||
layout->addWidget(m_sliderContainer);
|
||||
|
||||
m_slider->setPageStep(1);
|
||||
m_slider->setIconSize(QSize(BACKSIZE, BACKSIZE));
|
||||
QPixmap leftPixmap = ImageUtil::loadSvg(":/icons/resources/brightness.svg", QSize(IMAGESIZE, IMAGESIZE));
|
||||
QPixmap rightPixmap = ImageUtil::loadSvg(":/icons/resources/ICON_Device_Laptop.svg", QSize(IMAGESIZE, IMAGESIZE));
|
||||
m_sliderContainer->updateSlider(SliderContainer::IconPosition::LeftIcon, { leftPixmap.size(), QSize(), leftPixmap, 10 });
|
||||
m_sliderContainer->updateSlider(SliderContainer::IconPosition::RightIcon, { rightPixmap.size(), QSize(BACKSIZE, BACKSIZE), rightPixmap, 12});
|
||||
|
||||
QIcon leftIcon(QPixmap(":/icons/resources/brightness.svg").scaled(IMAGESIZE, IMAGESIZE));
|
||||
m_slider->setLeftIcon(leftIcon);
|
||||
QPixmap rightPixmap = ImageUtil::getShadowPixmap(QPixmap(QString(":/icons/resources/ICON_Device_Laptop.svg")).scaled(24, 24), Qt::lightGray, QSize(36, 36));
|
||||
m_slider->setRightIcon(rightPixmap);
|
||||
|
||||
SliderProxy *style = new SliderProxy;
|
||||
style->setParent(m_slider->qtSlider());
|
||||
m_slider->qtSlider()->setStyle(style);
|
||||
SliderProxyStyle *style = new SliderProxyStyle;
|
||||
style->setParent(m_sliderContainer->slider());
|
||||
m_sliderContainer->slider()->setStyle(style);
|
||||
}
|
||||
|
||||
void BrightnessWidget::initConenction()
|
||||
void BrightnessWidget::initConnection()
|
||||
{
|
||||
connect(m_slider, &CustomSlider::iconClicked, this, [ this ](DSlider::SliderIcons icon, bool) {
|
||||
if (icon == DSlider::SliderIcons::RightIcon)
|
||||
Q_EMIT rightIconClicked();
|
||||
});
|
||||
|
||||
connect(m_slider, &CustomSlider::valueChanged, this, [ this ](int value) {
|
||||
connect(m_sliderContainer->slider(), &QSlider::valueChanged, this, [ this ](int value) {
|
||||
BrightMonitor *monitor = m_model->primaryMonitor();
|
||||
if (monitor)
|
||||
m_model->setBrightness(monitor, value);
|
||||
@ -104,5 +96,5 @@ void BrightnessWidget::onUpdateBright(BrightMonitor *monitor)
|
||||
if (!monitor->isPrimary())
|
||||
return;
|
||||
// 此处只显示主屏的亮度
|
||||
m_slider->setValue(monitor->brihtness());
|
||||
m_sliderContainer->slider()->setValue(monitor->brihtness());
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
class CustomSlider;
|
||||
class SliderContainer;
|
||||
class BrightnessModel;
|
||||
class BrightMonitor;
|
||||
|
||||
@ -34,13 +34,12 @@ class BrightnessWidget : public DBlurEffectWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BrightnessWidget(QWidget *parent = nullptr);
|
||||
explicit BrightnessWidget(BrightnessModel *model, QWidget *parent = nullptr);
|
||||
~BrightnessWidget() override;
|
||||
BrightnessModel *model();
|
||||
SliderContainer *sliderContainer();
|
||||
|
||||
Q_SIGNALS:
|
||||
void visibleChanged(bool);
|
||||
void rightIconClicked();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
@ -51,10 +50,10 @@ private Q_SLOTS:
|
||||
|
||||
private:
|
||||
void initUi();
|
||||
void initConenction();
|
||||
void initConnection();
|
||||
|
||||
private:
|
||||
CustomSlider *m_slider;
|
||||
SliderContainer *m_sliderContainer;
|
||||
BrightnessModel *m_model;
|
||||
};
|
||||
|
||||
|
@ -1,192 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: sbw <sbw@sbw.so>
|
||||
*
|
||||
* Maintainer: sbw <sbw@sbw.so>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "customslider.h"
|
||||
#include <QPainterPath>
|
||||
|
||||
#include <DStyle>
|
||||
#include <DApplicationHelper>
|
||||
#include <DGuiApplicationHelper>
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
CustomSlider::CustomSlider(CustomSlider::SliderType type, QWidget *parent)
|
||||
: DSlider(Qt::Horizontal, parent)
|
||||
{
|
||||
setType(type);
|
||||
DSlider::slider()->setTracking(false);
|
||||
}
|
||||
|
||||
CustomSlider::CustomSlider(Qt::Orientation orientation, QWidget *parent)
|
||||
: DSlider(orientation, parent)
|
||||
{
|
||||
DSlider::slider()->setTracking(false);
|
||||
}
|
||||
|
||||
void CustomSlider::setType(CustomSlider::SliderType type)
|
||||
{
|
||||
switch (type) {
|
||||
case Vernier: setProperty("handleType", "Vernier"); break;
|
||||
case Progress: setProperty("handleType", "None"); break;
|
||||
default: setProperty("handleType", "Normal"); break;
|
||||
}
|
||||
}
|
||||
|
||||
QSlider *CustomSlider::qtSlider()
|
||||
{
|
||||
return DSlider::slider();
|
||||
}
|
||||
|
||||
void CustomSlider::setRange(int min, int max)
|
||||
{
|
||||
setMinimum(min);
|
||||
setMaximum(max);
|
||||
}
|
||||
|
||||
void CustomSlider::setTickPosition(QSlider::TickPosition tick)
|
||||
{
|
||||
m_tickPosition = tick;
|
||||
}
|
||||
|
||||
void CustomSlider::setTickInterval(int ti)
|
||||
{
|
||||
DSlider::slider()->setTickInterval(ti);
|
||||
}
|
||||
|
||||
void CustomSlider::setSliderPosition(int Position)
|
||||
{
|
||||
DSlider::slider()->setSliderPosition(Position);
|
||||
}
|
||||
|
||||
void CustomSlider::setAnnotations(const QStringList &annotations)
|
||||
{
|
||||
switch (m_tickPosition) {
|
||||
case QSlider::TicksLeft:
|
||||
setLeftTicks(annotations);
|
||||
break;
|
||||
case QSlider::TicksRight:
|
||||
setRightTicks(annotations);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CustomSlider::setOrientation(Qt::Orientation orientation)
|
||||
{
|
||||
Q_UNUSED(orientation)
|
||||
}
|
||||
|
||||
void CustomSlider::wheelEvent(QWheelEvent *e)
|
||||
{
|
||||
e->ignore();
|
||||
}
|
||||
|
||||
SliderContainer::SliderContainer(CustomSlider::SliderType type, QWidget *parent)
|
||||
: QWidget (parent)
|
||||
, m_slider(new CustomSlider(type, this))
|
||||
, m_titleLabel(new QLabel(this))
|
||||
{
|
||||
QVBoxLayout *mainlayout = new QVBoxLayout(this);
|
||||
mainlayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainlayout->setSpacing(5);
|
||||
mainlayout->addWidget(m_titleLabel);
|
||||
mainlayout->addWidget(m_slider);
|
||||
}
|
||||
|
||||
SliderContainer::SliderContainer(Qt::Orientation orientation, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_slider(new CustomSlider(orientation, this))
|
||||
, m_titleLabel(new QLabel(this))
|
||||
{
|
||||
QVBoxLayout *mainlayout = new QVBoxLayout(this);
|
||||
mainlayout->setContentsMargins(0, 1, 0, 0);
|
||||
mainlayout->setSpacing(1);
|
||||
|
||||
m_titleLabel->setFixedHeight(8);
|
||||
mainlayout->addWidget(m_titleLabel);
|
||||
mainlayout->addWidget(m_slider);
|
||||
}
|
||||
|
||||
SliderContainer::~SliderContainer()
|
||||
{
|
||||
}
|
||||
|
||||
void SliderContainer::setTitle(const QString &title)
|
||||
{
|
||||
m_titleLabel->setText(title);
|
||||
}
|
||||
|
||||
CustomSlider *SliderContainer::slider()
|
||||
{
|
||||
return m_slider;
|
||||
}
|
||||
|
||||
SliderProxy::SliderProxy(QStyle *style)
|
||||
: QProxyStyle(style)
|
||||
{
|
||||
}
|
||||
|
||||
SliderProxy::~SliderProxy()
|
||||
{
|
||||
}
|
||||
|
||||
void SliderProxy::drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
if (control != ComplexControl::CC_Slider)
|
||||
return;
|
||||
|
||||
// 绘制之前先保存之前的画笔
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::RenderHint::Antialiasing);
|
||||
// 获取滑动条和滑块的区域
|
||||
const QStyleOptionSlider *sliderOption = static_cast<const QStyleOptionSlider *>(option);
|
||||
QRect rectGroove = subControlRect(CC_Slider, sliderOption, SC_SliderGroove, widget);
|
||||
QRect rectHandle = subControlRect(CC_Slider, sliderOption, SC_SliderHandle, widget);
|
||||
// 深色背景下,滑块和滑动条白色,浅色背景下,滑块和滑动条黑色
|
||||
QBrush brush(DGuiApplicationHelper::DarkType == DGuiApplicationHelper::instance()->themeType() ? Qt::white : Qt::black);
|
||||
// 此处中绘制圆形滑动条,需要绘制圆角,圆角大小为其高度的一半
|
||||
QPainterPath pathGroove;
|
||||
int radius = rectGroove.height() / 2;
|
||||
pathGroove.addRoundedRect(rectGroove, radius, radius);
|
||||
painter->fillPath(pathGroove, brush);
|
||||
|
||||
// 绘制滑块,因为滑块是正圆形,而它本来的区域是一个长方形区域,因此,需要计算当前
|
||||
// 区域的正中心区域,将其作为一个正方形区域来绘制圆形滑块
|
||||
int handleSize = qMin(rectHandle.width(), rectHandle.height());
|
||||
int x = rectHandle.x() + (rectHandle.width() - handleSize) / 2;
|
||||
int y = rectHandle.y() + (rectHandle.height() - handleSize) / 2;
|
||||
rectHandle.setX(x);
|
||||
rectHandle.setY(y);
|
||||
rectHandle.setWidth(handleSize);
|
||||
rectHandle.setHeight(handleSize);
|
||||
|
||||
QPainterPath pathHandle;
|
||||
pathHandle.addEllipse(rectHandle);
|
||||
painter->fillPath(pathHandle, brush);
|
||||
painter->restore();
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: sbw <sbw@sbw.so>
|
||||
*
|
||||
* Maintainer: sbw <sbw@sbw.so>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CUSTOMCTRL_H
|
||||
#define CUSTOMCTRL_H
|
||||
|
||||
#include <DSlider>
|
||||
#include <QProxyStyle>
|
||||
#include <QTimer>
|
||||
|
||||
class QLabel;
|
||||
|
||||
class CustomSlider : public DTK_WIDGET_NAMESPACE::DSlider
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum SliderType {
|
||||
Normal,
|
||||
Vernier,
|
||||
Progress
|
||||
};
|
||||
|
||||
public:
|
||||
explicit CustomSlider(SliderType type = Normal, QWidget *parent = nullptr);
|
||||
explicit CustomSlider(Qt::Orientation orientation, QWidget *parent = nullptr);
|
||||
|
||||
inline CustomSlider *slider() const { return const_cast<CustomSlider *>(this); }
|
||||
QSlider *qtSlider();
|
||||
|
||||
void setType(SliderType type);
|
||||
void setRange(int min, int max);
|
||||
void setTickPosition(QSlider::TickPosition tick);
|
||||
void setTickInterval(int ti);
|
||||
void setSliderPosition(int Position);
|
||||
void setAnnotations(const QStringList &annotations);
|
||||
void setOrientation(Qt::Orientation orientation);
|
||||
|
||||
protected:
|
||||
void wheelEvent(QWheelEvent *e);
|
||||
|
||||
private:
|
||||
QSlider::TickPosition m_tickPosition = QSlider::TicksBelow;
|
||||
};
|
||||
|
||||
class SliderContainer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SliderContainer(CustomSlider::SliderType type = CustomSlider::Normal, QWidget *parent = nullptr);
|
||||
explicit SliderContainer(Qt::Orientation orientation, QWidget *parent);
|
||||
~SliderContainer();
|
||||
void setTitle(const QString &title);
|
||||
CustomSlider *slider();
|
||||
|
||||
private:
|
||||
CustomSlider *m_slider;
|
||||
QLabel *m_titleLabel;
|
||||
};
|
||||
|
||||
class SliderProxy : public QProxyStyle
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SliderProxy(QStyle *style = nullptr);
|
||||
~SliderProxy() override;
|
||||
|
||||
protected:
|
||||
void drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const override;
|
||||
};
|
||||
|
||||
#endif // VOLUMESLIDER_H
|
@ -18,7 +18,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "customslider.h"
|
||||
#include "brightnessmodel.h"
|
||||
#include "mediawidget.h"
|
||||
|
||||
#include <DFontSizeManager>
|
||||
|
273
frame/window/components/slidercontainer.cpp
Normal file
273
frame/window/components/slidercontainer.cpp
Normal file
@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "brightnessmodel.h"
|
||||
#include "slidercontainer.h"
|
||||
|
||||
#include <DStyle>
|
||||
#include <DApplicationHelper>
|
||||
#include <DGuiApplicationHelper>
|
||||
#include <DPaletteHelper>
|
||||
|
||||
#include <QPainterPath>
|
||||
#include <QMouseEvent>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
// 用于绘制图标的窗体,此窗体不想让其在外部调用,因此,将其作为一个私有类
|
||||
class SliderIconWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
explicit SliderIconWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_iconSize(QSize(24, 24))
|
||||
, m_shadowSize(QSize())
|
||||
{}
|
||||
|
||||
void updateData(const QIcon &icon, const QSize &iconSize, const QSize &shadowSize)
|
||||
{
|
||||
m_icon = icon;
|
||||
m_iconSize = iconSize;
|
||||
m_shadowSize = shadowSize;
|
||||
update();
|
||||
}
|
||||
|
||||
void updateIcon(const QIcon &icon)
|
||||
{
|
||||
m_icon = icon;
|
||||
update();
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
private:
|
||||
QIcon m_icon;
|
||||
QSize m_iconSize;
|
||||
QSize m_shadowSize;
|
||||
};
|
||||
|
||||
void SliderIconWidget::paintEvent(QPaintEvent *e)
|
||||
{
|
||||
if (m_iconSize.isNull() || m_icon.isNull())
|
||||
return QWidget::paintEvent(e);
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
if (m_shadowSize.isValid() && !m_shadowSize.isNull() && !m_shadowSize.isEmpty()) {
|
||||
// 绘制圆形背景
|
||||
painter.setPen(Qt::NoPen);
|
||||
// 获取阴影部分背景颜色
|
||||
DPalette dpa = DPaletteHelper::instance()->palette(this);
|
||||
painter.setBrush(dpa.brush(DPalette::ColorRole::Midlight));
|
||||
int x = (rect().width() - m_shadowSize.width() ) / 2;
|
||||
int y = (rect().height() - m_shadowSize.height() ) / 2;
|
||||
painter.drawEllipse(QRect(x, y, m_shadowSize.width(), m_shadowSize.height()));
|
||||
}
|
||||
// 绘制图标
|
||||
QPixmap pixmap = m_icon.pixmap(m_iconSize);
|
||||
int iconWidth = static_cast<int>(m_iconSize.width() / qApp->devicePixelRatio());
|
||||
int iconHeight = static_cast<int>(m_iconSize.height() / qApp->devicePixelRatio());
|
||||
int x = (rect().width() - iconWidth) / 2;
|
||||
int y = (rect().height() - iconHeight) / 2;
|
||||
painter.drawPixmap(x, y, iconWidth, iconHeight, pixmap);
|
||||
}
|
||||
|
||||
SliderContainer::SliderContainer(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_leftIconWidget(new SliderIconWidget(this))
|
||||
, m_slider(new QSlider(Qt::Orientation::Horizontal, this))
|
||||
, m_titleLabel(new QLabel(this))
|
||||
, m_rightIconWidget(new SliderIconWidget(this))
|
||||
, m_spaceLeftWidget(new QWidget(this))
|
||||
, m_spaceRightWidget(new QWidget(this))
|
||||
{
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->setSpacing(0);
|
||||
|
||||
QHBoxLayout *sliderLayout = new QHBoxLayout(this);
|
||||
sliderLayout->setContentsMargins(0, 0, 0, 0);
|
||||
sliderLayout->setSpacing(0);
|
||||
sliderLayout->addWidget(m_leftIconWidget);
|
||||
sliderLayout->addWidget(m_spaceLeftWidget);
|
||||
sliderLayout->addWidget(m_slider);
|
||||
sliderLayout->addWidget(m_spaceRightWidget);
|
||||
sliderLayout->addWidget(m_rightIconWidget);
|
||||
|
||||
mainLayout->addWidget(m_titleLabel);
|
||||
mainLayout->addLayout(sliderLayout);
|
||||
|
||||
m_titleLabel->setVisible(false);
|
||||
|
||||
m_leftIconWidget->installEventFilter(this);
|
||||
m_slider->installEventFilter(this);
|
||||
m_rightIconWidget->installEventFilter(this);
|
||||
}
|
||||
|
||||
SliderContainer::~SliderContainer()
|
||||
{
|
||||
}
|
||||
|
||||
void SliderContainer::setTitle(const QString &text)
|
||||
{
|
||||
m_titleLabel->setText(text);
|
||||
m_titleLabel->setVisible(!text.isEmpty());
|
||||
}
|
||||
|
||||
QSize SliderContainer::getSuitableSize(const QSize &iconSize, const QSize &bgSize)
|
||||
{
|
||||
if (bgSize.isValid() && !bgSize.isNull() && !bgSize.isEmpty())
|
||||
return bgSize;
|
||||
|
||||
return iconSize;
|
||||
}
|
||||
|
||||
void SliderContainer::updateSlider(const SliderContainer::IconPosition &iconPosition, const SliderContainer::SliderData &sliderData)
|
||||
{
|
||||
switch (iconPosition) {
|
||||
case IconPosition::LeftIcon: {
|
||||
m_leftIconWidget->setFixedSize(getSuitableSize(sliderData.iconSize, sliderData.shadowSize));
|
||||
m_leftIconWidget->updateData(sliderData.icon, sliderData.iconSize, sliderData.shadowSize);
|
||||
m_spaceLeftWidget->setFixedWidth(sliderData.space);
|
||||
break;
|
||||
}
|
||||
case IconPosition::RightIcon: {
|
||||
m_rightIconWidget->setFixedSize(getSuitableSize(sliderData.iconSize, sliderData.shadowSize));
|
||||
m_rightIconWidget->updateData(sliderData.icon, sliderData.iconSize, sliderData.shadowSize);
|
||||
m_spaceRightWidget->setFixedWidth(sliderData.space);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SliderContainer::setIcon(const SliderContainer::IconPosition &iconPosition, const QIcon &icon)
|
||||
{
|
||||
switch (iconPosition) {
|
||||
case IconPosition::LeftIcon: {
|
||||
m_leftIconWidget->updateIcon(icon);
|
||||
break;
|
||||
}
|
||||
case IconPosition::RightIcon: {
|
||||
m_rightIconWidget->updateIcon(icon);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSlider *SliderContainer::slider()
|
||||
{
|
||||
return m_slider;
|
||||
}
|
||||
|
||||
bool SliderContainer::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonRelease) {
|
||||
if (watched == m_leftIconWidget)
|
||||
Q_EMIT iconClicked(IconPosition::LeftIcon);
|
||||
else if (watched == m_rightIconWidget)
|
||||
Q_EMIT iconClicked(IconPosition::RightIcon);
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
SliderProxyStyle::SliderProxyStyle(StyleType drawSpecial, QStyle *style)
|
||||
: QProxyStyle(style)
|
||||
, m_drawSpecial(drawSpecial)
|
||||
{
|
||||
}
|
||||
|
||||
SliderProxyStyle::~SliderProxyStyle()
|
||||
{
|
||||
}
|
||||
|
||||
void SliderProxyStyle::drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
if (control != ComplexControl::CC_Slider)
|
||||
return;
|
||||
|
||||
// 绘制之前先保存之前的画笔
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::RenderHint::Antialiasing);
|
||||
// 获取滑动条和滑块的区域
|
||||
const QStyleOptionSlider *sliderOption = static_cast<const QStyleOptionSlider *>(option);
|
||||
QRect rectGroove = subControlRect(CC_Slider, sliderOption, SC_SliderGroove, widget);
|
||||
QRect rectHandle = subControlRect(CC_Slider, sliderOption, SC_SliderHandle, widget);
|
||||
if (m_drawSpecial == RoundHandler)
|
||||
drawRoundSlider(painter, rectGroove, rectHandle);
|
||||
else
|
||||
drawNormalSlider(painter, rectGroove, rectHandle, const_cast<QWidget *>(widget));
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
// 绘制通用的滑动条
|
||||
void SliderProxyStyle::drawNormalSlider(QPainter *painter, QRect rectGroove, QRect rectHandle, QWidget *wigdet) const
|
||||
{
|
||||
DPalette dpa = DPaletteHelper::instance()->palette(wigdet);
|
||||
QPen penLine = QPen(dpa.color(DPalette::Highlight), 2);
|
||||
// 绘制上下的竖线,一根竖线的宽度是2,+4个像素刚好保证中间也是间隔2个像素
|
||||
for (int i = rectGroove.x(); i < rectGroove.x() + rectGroove.width(); i = i + 4) {
|
||||
if (i < rectHandle.x())
|
||||
painter->setPen(penLine);
|
||||
else
|
||||
painter->setPen(QPen(Qt::gray, 2));
|
||||
|
||||
painter->drawLine(i, rectGroove.y() + 2, i, rectGroove.y() + rectGroove.height() - 2);
|
||||
}
|
||||
// 绘制滚动区域
|
||||
painter->setBrush(dpa.color(DPalette::Highlight));
|
||||
painter->setPen(Qt::NoPen);
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(rectHandle, 6, 6);
|
||||
painter->drawPath(path);
|
||||
}
|
||||
|
||||
// 绘制设计师定义的那种圆形滑块,黑色的滑条
|
||||
void SliderProxyStyle::drawRoundSlider(QPainter *painter, QRect rectGroove, QRect rectHandle) const
|
||||
{
|
||||
// 深色背景下,滑块和滑动条白色,浅色背景下,滑块和滑动条黑色
|
||||
QBrush brush(DGuiApplicationHelper::DarkType == DGuiApplicationHelper::instance()->themeType() ? Qt::white : Qt::black);
|
||||
// 此处中绘制圆形滑动条,需要绘制圆角,圆角大小为其高度的一半
|
||||
QPainterPath pathGroove;
|
||||
int radius = rectGroove.height() / 2;
|
||||
pathGroove.addRoundedRect(rectGroove, radius, radius);
|
||||
painter->fillPath(pathGroove, brush);
|
||||
|
||||
// 绘制滑块,因为滑块是正圆形,而它本来的区域是一个长方形区域,因此,需要计算当前
|
||||
// 区域的正中心区域,将其作为一个正方形区域来绘制圆形滑块
|
||||
int handleSize = qMin(rectHandle.width(), rectHandle.height());
|
||||
int x = rectHandle.x() + (rectHandle.width() - handleSize) / 2;
|
||||
int y = rectHandle.y() + (rectHandle.height() - handleSize) / 2;
|
||||
rectHandle.setX(x);
|
||||
rectHandle.setY(y);
|
||||
rectHandle.setWidth(handleSize);
|
||||
rectHandle.setHeight(handleSize);
|
||||
|
||||
QPainterPath pathHandle;
|
||||
pathHandle.addEllipse(rectHandle);
|
||||
painter->fillPath(pathHandle, brush);
|
||||
}
|
110
frame/window/components/slidercontainer.h
Normal file
110
frame/window/components/slidercontainer.h
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SLIDERCONTAINER_H
|
||||
#define SLIDERCONTAINER_H
|
||||
|
||||
#include <DSlider>
|
||||
|
||||
#include <QProxyStyle>
|
||||
#include <QTimer>
|
||||
|
||||
class QLabel;
|
||||
class SliderProxyStyle;
|
||||
class SliderIconWidget;
|
||||
|
||||
/**
|
||||
* @brief 滚动条的类的封装,封装这个类的原因,是为了方便设置左右图标,dtk中的对应的DSlider类也有这个功能,
|
||||
* 但是只能简单的设置左右图标,对于右边图标有阴影的,需要外部提供一个带阴影图标,但是如果由外部来提供,
|
||||
* 通过QPixmap绘制的带阴影的图标无法消除锯齿(即使通过反走样也不行),因此在此处封装这个类
|
||||
*/
|
||||
class SliderContainer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum IconPosition {
|
||||
LeftIcon = 0,
|
||||
RightIcon
|
||||
};
|
||||
|
||||
struct SliderData {
|
||||
QSize iconSize; // 图标尺寸
|
||||
QSize shadowSize; // 阴影尺寸
|
||||
QIcon icon; // 图标
|
||||
int space; // 间距
|
||||
};
|
||||
|
||||
public:
|
||||
explicit SliderContainer(QWidget *parent);
|
||||
~SliderContainer() override;
|
||||
|
||||
void setTitle(const QString &text);
|
||||
void updateSlider(const IconPosition &iconPosition, const SliderData &sliderData);
|
||||
void setIcon(const IconPosition &iconPosition, const QIcon &icon);
|
||||
QSlider *slider();
|
||||
|
||||
Q_SIGNALS:
|
||||
void iconClicked(const IconPosition &);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
QSize getSuitableSize(const QSize &iconSize, const QSize &bgSize);
|
||||
|
||||
private:
|
||||
SliderIconWidget *m_leftIconWidget;
|
||||
QSlider *m_slider;
|
||||
QLabel *m_titleLabel;
|
||||
SliderIconWidget *m_rightIconWidget;
|
||||
QWidget *m_spaceLeftWidget;
|
||||
QWidget *m_spaceRightWidget;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 用来设置滚动条的样式
|
||||
* @param drawSpecial: true
|
||||
*/
|
||||
class SliderProxyStyle : public QProxyStyle
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum StyleType {
|
||||
RoundHandler = 0, // 绘制那种黑色圆底滑动条
|
||||
Normal // 绘制那种通用的滑动条
|
||||
};
|
||||
|
||||
public:
|
||||
explicit SliderProxyStyle(StyleType drawSpecial = RoundHandler, QStyle *style = nullptr);
|
||||
~SliderProxyStyle() override;
|
||||
|
||||
protected:
|
||||
void drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const override;
|
||||
|
||||
private:
|
||||
void drawNormalSlider(QPainter *painter, QRect rectGroove, QRect rectHandle, QWidget *wigdet) const;
|
||||
void drawRoundSlider(QPainter *painter, QRect rectGroove, QRect rectHandle) const;
|
||||
|
||||
private:
|
||||
StyleType m_drawSpecial;
|
||||
};
|
||||
|
||||
#endif // VOLUMESLIDER_H
|
@ -19,15 +19,19 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "volumedeviceswidget.h"
|
||||
#include "customslider.h"
|
||||
#include "brightnessmodel.h"
|
||||
#include "volumemodel.h"
|
||||
#include "settingdelegate.h"
|
||||
#include "imageutil.h"
|
||||
#include "slidercontainer.h"
|
||||
|
||||
#include <DListView>
|
||||
#include <DPushButton>
|
||||
#include <DLabel>
|
||||
#include <DGuiApplicationHelper>
|
||||
#include <DDBusSender>
|
||||
#include <DBlurEffectWidget>
|
||||
#include <DPaletteHelper>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QScrollBar>
|
||||
@ -43,7 +47,8 @@ DWIDGET_USE_NAMESPACE
|
||||
|
||||
VolumeDevicesWidget::VolumeDevicesWidget(VolumeModel *model, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_volumeSlider(new CustomSlider(CustomSlider::Normal, this))
|
||||
, m_sliderParent(new QWidget(this))
|
||||
, m_sliderContainer(new SliderContainer(m_sliderParent))
|
||||
, m_descriptionLabel(new QLabel(tr("Output Device"), this))
|
||||
, m_deviceList(new DListView(this))
|
||||
, m_volumeModel(model)
|
||||
@ -54,6 +59,7 @@ VolumeDevicesWidget::VolumeDevicesWidget(VolumeModel *model, QWidget *parent)
|
||||
initUi();
|
||||
initConnection();
|
||||
reloadAudioDevices();
|
||||
m_sliderParent->installEventFilter(this);
|
||||
|
||||
QMetaObject::invokeMethod(this, [ this ] {
|
||||
resetVolumeInfo();
|
||||
@ -65,17 +71,49 @@ VolumeDevicesWidget::~VolumeDevicesWidget()
|
||||
{
|
||||
}
|
||||
|
||||
bool VolumeDevicesWidget::eventFilter(QObject *watcher, QEvent *event)
|
||||
{
|
||||
if ((watcher == m_sliderParent) && (event->type() == QEvent::Paint)) {
|
||||
QPainter painter(m_sliderParent);
|
||||
painter.setRenderHint(QPainter::Antialiasing); // 抗锯齿
|
||||
painter.setPen(Qt::NoPen);
|
||||
|
||||
DPalette dpa = DPaletteHelper::instance()->palette(m_sliderParent);
|
||||
painter.setBrush(dpa.brush(DPalette::ColorRole::Midlight));
|
||||
painter.drawRoundedRect(m_sliderParent->rect(), 10, 10);
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(watcher, event);
|
||||
}
|
||||
|
||||
void VolumeDevicesWidget::initUi()
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(6);
|
||||
|
||||
m_volumeSlider->setIconSize(QSize(36, 36));
|
||||
m_volumeSlider->setLeftIcon(QIcon(leftIcon()));
|
||||
m_volumeSlider->setRightIcon(QIcon(rightIcon()));
|
||||
m_sliderParent->setFixedHeight(36);
|
||||
|
||||
layout->addWidget(m_volumeSlider);
|
||||
QHBoxLayout *sliderLayout = new QHBoxLayout(m_sliderParent);
|
||||
sliderLayout->setContentsMargins(11, 0, 11, 0);
|
||||
sliderLayout->setSpacing(0);
|
||||
|
||||
QPixmap leftPixmap = ImageUtil::loadSvg(leftIcon(), QSize(24, 24));
|
||||
m_sliderContainer->updateSlider(SliderContainer::IconPosition::LeftIcon, { leftPixmap.size(), QSize(), leftPixmap, 5 });
|
||||
QPixmap rightPixmap = ImageUtil::loadSvg(rightIcon(), QSize(24, 24));
|
||||
m_sliderContainer->updateSlider(SliderContainer::IconPosition::RightIcon, { rightPixmap.size(), QSize(), rightPixmap, 7 });
|
||||
|
||||
SliderProxyStyle *proxy = new SliderProxyStyle(SliderProxyStyle::Normal);
|
||||
proxy->setParent(m_sliderContainer->slider());
|
||||
m_sliderContainer->slider()->setStyle(proxy);
|
||||
sliderLayout->addWidget(m_sliderContainer);
|
||||
|
||||
QHBoxLayout *topLayout = new QHBoxLayout(this);
|
||||
topLayout->setContentsMargins(10, 0, 10, 0);
|
||||
topLayout->setSpacing(0);
|
||||
topLayout->addWidget(m_sliderParent);
|
||||
|
||||
layout->addLayout(topLayout);
|
||||
layout->addSpacing(4);
|
||||
layout->addWidget(m_descriptionLabel);
|
||||
|
||||
@ -119,9 +157,9 @@ void VolumeDevicesWidget::initConnection()
|
||||
{
|
||||
m_audioSink = m_volumeModel->defaultSink();
|
||||
auto adjustVolumeSlider = [ this ](int volume) {
|
||||
m_volumeSlider->blockSignals(true);
|
||||
m_volumeSlider->setValue(volume);
|
||||
m_volumeSlider->blockSignals(false);
|
||||
m_sliderContainer->slider()->blockSignals(true);
|
||||
m_sliderContainer->slider()->setValue(volume);
|
||||
m_sliderContainer->slider()->blockSignals(false);
|
||||
};
|
||||
if (m_audioSink)
|
||||
connect(m_audioSink, &AudioSink::volumeChanged, this, adjustVolumeSlider);
|
||||
@ -137,7 +175,7 @@ void VolumeDevicesWidget::initConnection()
|
||||
m_deviceList->update();
|
||||
});
|
||||
|
||||
connect(m_volumeSlider, &CustomSlider::valueChanged, this, [ this ](int value) {
|
||||
connect(m_sliderContainer->slider(), &QSlider::valueChanged, this, [ this ](int value) {
|
||||
AudioSink *defSink = m_volumeModel->defaultSink();
|
||||
if (!defSink)
|
||||
return;
|
||||
@ -210,7 +248,7 @@ void VolumeDevicesWidget::resizeHeight()
|
||||
{
|
||||
m_deviceList->adjustSize();
|
||||
QMargins m = layout()->contentsMargins();
|
||||
int height = m.top() + m.bottom() + HEADERHEIGHT + m_volumeSlider->height() + ITEMSPACE
|
||||
int height = m.top() + m.bottom() + HEADERHEIGHT + m_sliderContainer->height() + ITEMSPACE
|
||||
+ m_descriptionLabel->height() + m_deviceList->height();
|
||||
|
||||
setFixedHeight(height);
|
||||
@ -222,7 +260,7 @@ void VolumeDevicesWidget::resetVolumeInfo()
|
||||
if (!defaultSink)
|
||||
return;
|
||||
|
||||
m_volumeSlider->blockSignals(true);
|
||||
m_volumeSlider->setValue(defaultSink->volume());
|
||||
m_volumeSlider->blockSignals(false);
|
||||
m_sliderContainer->slider()->blockSignals(true);
|
||||
m_sliderContainer->slider()->setValue(defaultSink->volume());
|
||||
m_sliderContainer->slider()->blockSignals(false);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace Dtk { namespace Widget { class DListView; } }
|
||||
|
||||
using namespace Dtk::Widget;
|
||||
|
||||
class CustomSlider;
|
||||
class SliderContainer;
|
||||
class QStandardItemModel;
|
||||
class QLabel;
|
||||
class VolumeModel;
|
||||
@ -45,6 +45,9 @@ public:
|
||||
explicit VolumeDevicesWidget(VolumeModel *model, QWidget *parent = nullptr);
|
||||
~VolumeDevicesWidget() override;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watcher, QEvent *event) override;
|
||||
|
||||
private:
|
||||
void initUi();
|
||||
void reloadAudioDevices();
|
||||
@ -58,7 +61,8 @@ private:
|
||||
void resetVolumeInfo();
|
||||
|
||||
private:
|
||||
CustomSlider *m_volumeSlider;
|
||||
QWidget *m_sliderParent;
|
||||
SliderContainer *m_sliderContainer;
|
||||
QLabel *m_descriptionLabel;
|
||||
DListView *m_deviceList;
|
||||
VolumeModel *m_volumeModel;
|
||||
|
@ -19,10 +19,11 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "volumewidget.h"
|
||||
#include "customslider.h"
|
||||
#include "brightnessmodel.h"
|
||||
#include "imageutil.h"
|
||||
#include "volumemodel.h"
|
||||
#include "imageutil.h"
|
||||
#include "slidercontainer.h"
|
||||
|
||||
#include <DGuiApplicationHelper>
|
||||
|
||||
@ -44,11 +45,11 @@ DGUI_USE_NAMESPACE
|
||||
#define ICON_SIZE 24
|
||||
#define BACKSIZE 36
|
||||
|
||||
VolumeWidget::VolumeWidget(QWidget *parent)
|
||||
VolumeWidget::VolumeWidget(VolumeModel *model, QWidget *parent)
|
||||
: DBlurEffectWidget(parent)
|
||||
, m_volumeController(new VolumeModel(this))
|
||||
, m_volumnCtrl(new CustomSlider(Qt::Horizontal, this))
|
||||
, m_defaultSink(m_volumeController->defaultSink())
|
||||
, m_model(model)
|
||||
, m_sliderContainer(new SliderContainer(this))
|
||||
, m_defaultSink(m_model->defaultSink())
|
||||
{
|
||||
initUi();
|
||||
initConnection();
|
||||
@ -61,38 +62,36 @@ VolumeWidget::~VolumeWidget()
|
||||
void VolumeWidget::initUi()
|
||||
{
|
||||
if (m_defaultSink)
|
||||
m_volumnCtrl->setValue(m_defaultSink->volume());
|
||||
m_sliderContainer->slider()->setValue(m_defaultSink->volume());
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||
mainLayout->setContentsMargins(20, 0, 20, 0);
|
||||
mainLayout->addWidget(m_volumnCtrl);
|
||||
mainLayout->setContentsMargins(17, 0, 12, 0);
|
||||
mainLayout->addWidget(m_sliderContainer);
|
||||
|
||||
const QString rightIconFile = rightIcon();
|
||||
QIcon rIcon = ImageUtil::getShadowPixmap(QPixmap(rightIconFile), Qt::lightGray, QSize(BACKSIZE, BACKSIZE));
|
||||
QPixmap leftPixmap = ImageUtil::loadSvg(leftIcon(), QSize(ICON_SIZE, ICON_SIZE));
|
||||
QPixmap rightPixmap = ImageUtil::loadSvg(rightIcon(), QSize(ICON_SIZE, ICON_SIZE));
|
||||
m_sliderContainer->updateSlider(SliderContainer::IconPosition::LeftIcon, { leftPixmap.size(), QSize(), leftPixmap, 12});
|
||||
m_sliderContainer->updateSlider(SliderContainer::IconPosition::RightIcon, { rightPixmap.size(), QSize(BACKSIZE, BACKSIZE), rightPixmap, 12});
|
||||
|
||||
m_volumnCtrl->setIconSize(QSize(BACKSIZE, BACKSIZE));
|
||||
m_volumnCtrl->setLeftIcon(QIcon(QPixmap(leftIcon())));
|
||||
m_volumnCtrl->setRightIcon(rIcon);
|
||||
SliderProxyStyle *proxy = new SliderProxyStyle;
|
||||
proxy->setParent(m_sliderContainer->slider());
|
||||
m_sliderContainer->slider()->setStyle(proxy);
|
||||
|
||||
SliderProxy *proxy = new SliderProxy;
|
||||
proxy->setParent(m_volumnCtrl->qtSlider());
|
||||
m_volumnCtrl->qtSlider()->setStyle(proxy);
|
||||
|
||||
bool existActiveOutputDevice = m_volumeController->existActiveOutputDevice();
|
||||
bool existActiveOutputDevice = m_model->existActiveOutputDevice();
|
||||
setEnabled(existActiveOutputDevice);
|
||||
}
|
||||
|
||||
void VolumeWidget::initConnection()
|
||||
{
|
||||
auto setCtrlVolumeValue = [this](int volume) {
|
||||
m_volumnCtrl->blockSignals(true);
|
||||
m_volumnCtrl->setValue(volume);
|
||||
m_volumnCtrl->blockSignals(false);
|
||||
m_sliderContainer->blockSignals(true);
|
||||
m_sliderContainer->slider()->setValue(volume);
|
||||
m_sliderContainer->blockSignals(false);
|
||||
};
|
||||
if (m_defaultSink)
|
||||
connect(m_defaultSink, &AudioSink::volumeChanged, this, setCtrlVolumeValue);
|
||||
|
||||
connect(m_volumeController, &VolumeModel::defaultSinkChanged, this, [ this, setCtrlVolumeValue ](AudioSink *sink) {
|
||||
connect(m_model, &VolumeModel::defaultSinkChanged, this, [ this, setCtrlVolumeValue ](AudioSink *sink) {
|
||||
if (m_defaultSink)
|
||||
disconnect(m_defaultSink);
|
||||
|
||||
@ -103,24 +102,24 @@ void VolumeWidget::initConnection()
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_volumnCtrl, &DTK_WIDGET_NAMESPACE::DSlider::valueChanged, this, [ this ](int value) {
|
||||
AudioSink *sink = m_volumeController->defaultSink();
|
||||
connect(m_sliderContainer->slider(), &QSlider::valueChanged, this, [ this ](int value) {
|
||||
AudioSink *sink = m_model->defaultSink();
|
||||
if (sink)
|
||||
sink->setVolume(value, true);
|
||||
});
|
||||
|
||||
connect(m_volumeController, &VolumeModel::muteChanged, this, [ this ] {
|
||||
m_volumnCtrl->setLeftIcon(QIcon(leftIcon()));
|
||||
connect(m_model, &VolumeModel::muteChanged, this, [ this ] {
|
||||
m_sliderContainer->setIcon(SliderContainer::IconPosition::LeftIcon, QIcon(leftIcon()));
|
||||
});
|
||||
|
||||
connect(m_volumnCtrl, &CustomSlider::iconClicked, this, [ this ](DSlider::SliderIcons icon, bool) {
|
||||
connect(m_sliderContainer, &SliderContainer::iconClicked, this, [ this ](const SliderContainer::IconPosition icon) {
|
||||
switch (icon) {
|
||||
case DSlider::SliderIcons::LeftIcon: {
|
||||
if (m_volumeController->existActiveOutputDevice())
|
||||
m_volumeController->setMute(!m_volumeController->isMute());
|
||||
case SliderContainer::IconPosition::LeftIcon: {
|
||||
if (m_model->existActiveOutputDevice())
|
||||
m_model->setMute(!m_model->isMute());
|
||||
break;
|
||||
}
|
||||
case DSlider::SliderIcons::RightIcon: {
|
||||
case SliderContainer::IconPosition::RightIcon: {
|
||||
// 弹出音量选择对话框
|
||||
Q_EMIT rightIconClick();
|
||||
break;
|
||||
@ -129,12 +128,6 @@ void VolumeWidget::initConnection()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
VolumeModel *VolumeWidget::model()
|
||||
{
|
||||
return m_volumeController;
|
||||
}
|
||||
|
||||
void VolumeWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
DBlurEffectWidget::showEvent(event);
|
||||
@ -149,8 +142,8 @@ void VolumeWidget::hideEvent(QHideEvent *event)
|
||||
|
||||
const QString VolumeWidget::leftIcon()
|
||||
{
|
||||
bool existActiveOutputDevice = m_volumeController->existActiveOutputDevice();
|
||||
const bool mute = existActiveOutputDevice ? m_volumeController->isMute() : true;
|
||||
bool existActiveOutputDevice = m_model->existActiveOutputDevice();
|
||||
const bool mute = existActiveOutputDevice ? m_model->isMute() : true;
|
||||
if (mute)
|
||||
return QString(":/icons/resources/audio-volume-muted-dark");
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
class VolumeModel;
|
||||
class QDBusMessage;
|
||||
class CustomSlider;
|
||||
class SliderContainer;
|
||||
class QLabel;
|
||||
class AudioSink;
|
||||
|
||||
@ -37,9 +37,8 @@ class VolumeWidget : public DBlurEffectWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VolumeWidget(QWidget *parent = nullptr);
|
||||
explicit VolumeWidget(VolumeModel *model, QWidget *parent = nullptr);
|
||||
~VolumeWidget() override;
|
||||
VolumeModel *model();
|
||||
|
||||
Q_SIGNALS:
|
||||
void visibleChanged(bool);
|
||||
@ -57,8 +56,8 @@ private:
|
||||
const QString rightIcon();
|
||||
|
||||
private:
|
||||
VolumeModel *m_volumeController;
|
||||
CustomSlider *m_volumnCtrl;
|
||||
VolumeModel *m_model;
|
||||
SliderContainer *m_sliderContainer;
|
||||
AudioSink *m_defaultSink;
|
||||
};
|
||||
|
||||
|
@ -19,16 +19,19 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "quicksettingcontainer.h"
|
||||
#include "brightnessmodel.h"
|
||||
#include "quicksettingcontroller.h"
|
||||
#include "pluginsiteminterface.h"
|
||||
#include "quicksettingitem.h"
|
||||
#include "mediawidget.h"
|
||||
#include "dockpopupwindow.h"
|
||||
#include "brightnesswidget.h"
|
||||
#include "slidercontainer.h"
|
||||
#include "volumewidget.h"
|
||||
#include "volumedeviceswidget.h"
|
||||
#include "brightnessmonitorwidget.h"
|
||||
#include "pluginchildpage.h"
|
||||
#include "volumemodel.h"
|
||||
|
||||
#include <DListView>
|
||||
#include <DStyle>
|
||||
@ -60,10 +63,12 @@ QuickSettingContainer::QuickSettingContainer(QWidget *parent)
|
||||
, m_mainlayout(new QVBoxLayout(m_mainWidget))
|
||||
, m_pluginLoader(QuickSettingController::instance())
|
||||
, m_playerWidget(new MediaWidget(m_componentWidget))
|
||||
, m_volumnWidget(new VolumeWidget(m_componentWidget))
|
||||
, m_brihtnessWidget(new BrightnessWidget(m_componentWidget))
|
||||
, m_volumeSettingWidget(new VolumeDevicesWidget(m_volumnWidget->model(), this))
|
||||
, m_brightSettingWidget(new BrightnessMonitorWidget(m_brihtnessWidget->model(), this))
|
||||
, m_volumeModel(new VolumeModel(this))
|
||||
, m_brightnessModel(new BrightnessModel(this))
|
||||
, m_volumnWidget(new VolumeWidget(m_volumeModel, m_componentWidget))
|
||||
, m_brihtnessWidget(new BrightnessWidget(m_brightnessModel, m_componentWidget))
|
||||
, m_volumeSettingWidget(new VolumeDevicesWidget(m_volumeModel, this))
|
||||
, m_brightSettingWidget(new BrightnessMonitorWidget(m_brightnessModel, this))
|
||||
, m_childPage(new PluginChildPage(this))
|
||||
, m_dragPluginPosition(QPoint(0, 0))
|
||||
{
|
||||
@ -333,9 +338,12 @@ void QuickSettingContainer::initConnection()
|
||||
resizeView();
|
||||
});
|
||||
connect(m_brihtnessWidget, &BrightnessWidget::visibleChanged, this, [ this ] { resizeView(); });
|
||||
connect(m_brihtnessWidget, &BrightnessWidget::rightIconClicked, this, [ this ] {
|
||||
showWidget(m_brightSettingWidget, tr("brightness"));
|
||||
resizeView();
|
||||
connect(m_brihtnessWidget->sliderContainer(), &SliderContainer::iconClicked, this, [ this ](const SliderContainer::IconPosition &iconPosition) {
|
||||
if (iconPosition == SliderContainer::RightIcon) {
|
||||
// 点击右侧的按钮,弹出具体的调节的界面
|
||||
showWidget(m_brightSettingWidget, tr("brightness"));
|
||||
resizeView();
|
||||
}
|
||||
});
|
||||
connect(m_childPage, &PluginChildPage::back, this, [ this ] {
|
||||
m_switchLayout->setCurrentWidget(m_mainWidget);
|
||||
|
@ -33,6 +33,8 @@ class DockItem;
|
||||
class QVBoxLayout;
|
||||
class QuickSettingController;
|
||||
class MediaWidget;
|
||||
class VolumeModel;
|
||||
class BrightnessModel;
|
||||
class VolumeWidget;
|
||||
class BrightnessWidget;
|
||||
class QuickSettingItem;
|
||||
@ -96,6 +98,8 @@ private:
|
||||
QVBoxLayout *m_mainlayout;
|
||||
QuickSettingController *m_pluginLoader;
|
||||
MediaWidget *m_playerWidget;
|
||||
VolumeModel *m_volumeModel;
|
||||
BrightnessModel *m_brightnessModel;
|
||||
VolumeWidget *m_volumnWidget;
|
||||
BrightnessWidget *m_brihtnessWidget;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user