dde-dock/frame/item/components/floatingpreview.cpp
chenjun c0f80b74ff
fix: 优化应用预览界面显示方式,使用滚动方式加载预览界面 (#705)
优化应用预览界面显示方式,使用滚动方式加载预览界面
在打开应用程序很多时,无法显示更多预览界面,不方便切换预览

Log: 修复可多开的应用打开超过20个后,任务栏预览效果不能全部展示的问题
Bug: https://pms.uniontech.com/bug-view-152143.html
Bug: https://pms.uniontech.com/bug-view-162757.html
Influence: 可多开的应用打开超过20个后,预览界面可以滚动选择未显示的界面
2022-10-14 09:01:35 +06:00

161 lines
4.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "floatingpreview.h"
#include "appsnapshot.h"
#include "previewcontainer.h"
#include <DStyle>
#include <QGraphicsEffect>
#include <QPainter>
#include <QVBoxLayout>
FloatingPreview::FloatingPreview(QWidget *parent)
: QWidget(parent)
, m_closeBtn3D(new DIconButton(this))
, m_titleBtn(new DPushButton(this))
{
m_closeBtn3D->setObjectName("closebutton-3d");
m_closeBtn3D->setFixedSize(24, 24);
m_closeBtn3D->setIconSize(QSize(24, 24));
m_closeBtn3D->setIcon(QIcon(":/icons/resources/close_round_normal.svg"));
m_closeBtn3D->setFlat(true);
m_closeBtn3D->installEventFilter(this);
m_titleBtn->setBackgroundRole(QPalette::Base);
m_titleBtn->setForegroundRole(QPalette::Text);
m_titleBtn->setFocusPolicy(Qt::NoFocus);
m_titleBtn->setAttribute(Qt::WA_TransparentForMouseEvents);
QVBoxLayout *centralLayout = new QVBoxLayout;
centralLayout->addWidget(m_closeBtn3D);
centralLayout->setAlignment(m_closeBtn3D, Qt::AlignRight | Qt::AlignTop);
centralLayout->addWidget(m_titleBtn);
centralLayout->setAlignment(m_titleBtn, Qt::AlignCenter | Qt::AlignBottom);
centralLayout->addSpacing(TITLE_MARGIN);
centralLayout->setMargin(0);
centralLayout->setSpacing(0);
setLayout(centralLayout);
setFixedSize(SNAP_WIDTH, SNAP_HEIGHT);
connect(m_closeBtn3D, &DIconButton::clicked, this, &FloatingPreview::onCloseBtnClicked);
}
WId FloatingPreview::trackedWid() const
{
Q_ASSERT(!m_tracked.isNull());
return m_tracked->wid();
}
AppSnapshot *FloatingPreview::trackedWindow()
{
return m_tracked;
}
void FloatingPreview::setFloatingTitleVisible(bool bVisible)
{
m_titleBtn->setVisible(bVisible);
}
void FloatingPreview::trackWindow(AppSnapshot *const snap)
{
if (!snap)
return;
if (!m_tracked.isNull())
m_tracked->removeEventFilter(this);
snap->installEventFilter(this);
m_tracked = snap;
m_closeBtn3D->setVisible(m_tracked->closeAble());
// 显示此标题的前提条件:配置了标题跟随鼠标显示
// 此对象是共用的鼠标移动到哪个预览图title就移动到哪里显示所以他的text统一snap获取不再重复计算显示长度
m_titleBtn->setText(snap->appTitle());
}
void FloatingPreview::paintEvent(QPaintEvent *e)
{
QWidget::paintEvent(e);
if (m_tracked.isNull())
return;
const QImage &snapshot = m_tracked->snapshot();
if (snapshot.isNull())
return;
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
const QRectF r = rect().marginsRemoved(QMargins(BORDER_MARGIN, BORDER_MARGIN, BORDER_MARGIN, BORDER_MARGIN));
DStyleHelper dstyle(style());
const int radius = dstyle.pixelMetric(DStyle::PM_FrameRadius);
// 选中外框
QPen pen;
pen.setColor(palette().highlight().color());
pen.setWidth(dstyle.pixelMetric(DStyle::PM_FocusBorderWidth));
painter.setPen(pen);
painter.setBrush(Qt::NoBrush);
painter.drawRoundedRect(r, radius, radius);
}
void FloatingPreview::mouseReleaseEvent(QMouseEvent *e)
{
QWidget::mouseReleaseEvent(e);
if (m_tracked) {
emit m_tracked->clicked(m_tracked->wid());
}
}
bool FloatingPreview::eventFilter(QObject *watched, QEvent *event)
{
if(watched == m_closeBtn3D) {
if(watched == m_closeBtn3D && (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverMove)) {
m_closeBtn3D->setIcon(QIcon(":/icons/resources/close_round_hover.svg"));
}
else if (watched == m_closeBtn3D && event->type() == QEvent::HoverLeave) {
m_closeBtn3D->setIcon(QIcon(":/icons/resources/close_round_normal.svg"));
}
else if (watched == m_closeBtn3D && event->type() == QEvent::MouseButtonPress) {
m_closeBtn3D->setIcon(QIcon(":/icons/resources/close_round_press.svg"));
}
}
if (watched == m_tracked) {
if (event->type() == QEvent::Destroy) {
// 此处需要置空否则当Destroy事件响应结束后会在FloatingPreview::hideEvent使用m_tracked野指针
m_tracked = nullptr;
hide();
}
}
return QWidget::eventFilter(watched, event);
}
void FloatingPreview::hideEvent(QHideEvent *event)
{
if (m_tracked) {
m_tracked->setContentsMargins(0, 0, 0, 0);
m_tracked->setWindowState();
}
QWidget::hideEvent(event);
}
void FloatingPreview::onCloseBtnClicked()
{
Q_ASSERT(!m_tracked.isNull());
m_tracked->closeWindow();
}