mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-04 17:33:05 +00:00
feat(PreviewContainer):rounded corner, selected state, title style
This commit is contained in:
parent
dd7ef78dba
commit
ae14390f2e
@ -22,6 +22,8 @@
|
||||
#include "appsnapshot.h"
|
||||
#include "previewcontainer.h"
|
||||
|
||||
#include <DStyle>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xutil.h>
|
||||
@ -34,16 +36,14 @@
|
||||
#include <QSizeF>
|
||||
#include <QTimer>
|
||||
|
||||
struct SHMInfo
|
||||
{
|
||||
struct SHMInfo {
|
||||
long shmid;
|
||||
long width;
|
||||
long height;
|
||||
long bytesPerLine;
|
||||
long format;
|
||||
|
||||
struct Rect
|
||||
{
|
||||
struct Rect {
|
||||
long x;
|
||||
long y;
|
||||
long width;
|
||||
@ -142,7 +142,7 @@ void AppSnapshot::fetchSnapshot()
|
||||
if (info) {
|
||||
qDebug() << "get Image from dxcbplugin SHM...";
|
||||
//qDebug() << info->shmid << info->width << info->height << info->bytesPerLine << info->format << info->rect.x << info->rect.y << info->rect.width << info->rect.height;
|
||||
image_data = (uchar*)shmat(info->shmid, 0, 0);
|
||||
image_data = (uchar *)shmat(info->shmid, 0, 0);
|
||||
if ((qint64)image_data != -1) {
|
||||
m_snapshot = QImage(image_data, info->width, info->height, info->bytesPerLine, (QImage::Format)info->format);
|
||||
m_snapshotSrcRect = QRect(info->rect.x, info->rect.y, info->rect.width, info->rect.height);
|
||||
@ -152,19 +152,17 @@ void AppSnapshot::fetchSnapshot()
|
||||
image_data = nullptr;
|
||||
}
|
||||
|
||||
if (!image_data || qimage.isNull())
|
||||
{
|
||||
if (!image_data || qimage.isNull()) {
|
||||
// get window image from XGetImage(a little slow)
|
||||
qDebug() << "get Image from dxcbplugin SHM failed!";
|
||||
qDebug() << "get Image from Xlib...";
|
||||
ximage = getImageXlib();
|
||||
if (!ximage)
|
||||
{
|
||||
if (!ximage) {
|
||||
qDebug() << "get Image from Xlib failed! giving up...";
|
||||
emit requestCheckWindow();
|
||||
return;
|
||||
}
|
||||
qimage = QImage((const uchar*)(ximage->data), ximage->width, ximage->height, ximage->bytes_per_line, QImage::Format_RGB32);
|
||||
qimage = QImage((const uchar *)(ximage->data), ximage->width, ximage->height, ximage->bytes_per_line, QImage::Format_RGB32);
|
||||
}
|
||||
|
||||
Q_ASSERT(!qimage.isNull());
|
||||
@ -200,8 +198,7 @@ void AppSnapshot::enterEvent(QEvent *e)
|
||||
|
||||
if (!m_wmHelper->hasComposite()) {
|
||||
m_closeBtn2D->setVisible(true);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
emit entered(wid());
|
||||
}
|
||||
|
||||
@ -221,8 +218,7 @@ void AppSnapshot::paintEvent(QPaintEvent *e)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
if (!m_wmHelper->hasComposite())
|
||||
{
|
||||
if (!m_wmHelper->hasComposite()) {
|
||||
if (underMouse())
|
||||
painter.fillRect(rect(), QColor(255, 255, 255, 255 * .2));
|
||||
return;
|
||||
@ -234,8 +230,7 @@ void AppSnapshot::paintEvent(QPaintEvent *e)
|
||||
const auto ratio = devicePixelRatioF();
|
||||
|
||||
// draw attention background
|
||||
if (m_windowInfo.attention)
|
||||
{
|
||||
if (m_windowInfo.attention) {
|
||||
painter.setBrush(QColor(241, 138, 46, 255 * .8));
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.drawRoundedRect(rect(), 5, 5);
|
||||
@ -244,9 +239,18 @@ void AppSnapshot::paintEvent(QPaintEvent *e)
|
||||
// draw image
|
||||
const QImage &im = m_snapshot;
|
||||
|
||||
const qreal offset_x = width() / 2.0 - m_snapshotSrcRect.width() / ratio / 2;
|
||||
const qreal offset_y = height() / 2.0 - m_snapshotSrcRect.height() / ratio / 2;
|
||||
painter.drawImage(QPointF(offset_x, offset_y), im, m_snapshotSrcRect);
|
||||
const qreal offset_x = width() / 2.0 - m_snapshotSrcRect.width() / ratio / 2 - m_snapshotSrcRect.left();
|
||||
const qreal offset_y = height() / 2.0 - m_snapshotSrcRect.height() / ratio / 2 - m_snapshotSrcRect.top();
|
||||
|
||||
DStyleHelper dstyle(style());
|
||||
const int radius = dstyle.pixelMetric(DStyle::PM_FrameRadius);
|
||||
|
||||
QBrush brush;
|
||||
brush.setTextureImage(im);
|
||||
painter.setBrush(brush);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.translate(QPoint(offset_x, offset_y));
|
||||
painter.drawRoundedRect(m_snapshotSrcRect, radius, radius);
|
||||
}
|
||||
|
||||
void AppSnapshot::resizeEvent(QResizeEvent *e)
|
||||
@ -263,7 +267,7 @@ void AppSnapshot::mousePressEvent(QMouseEvent *e)
|
||||
emit clicked(m_wid);
|
||||
}
|
||||
|
||||
SHMInfo * AppSnapshot::getImageDSHM()
|
||||
SHMInfo *AppSnapshot::getImageDSHM()
|
||||
{
|
||||
const auto display = QX11Info::display();
|
||||
|
||||
@ -279,8 +283,8 @@ SHMInfo * AppSnapshot::getImageDSHM()
|
||||
unsigned char *prop_return_deepin_shm;
|
||||
|
||||
XGetWindowProperty(display, m_wid, atom_prop, 0, 32 * 9, false, AnyPropertyType,
|
||||
&actual_type_return_deepin_shm, &actual_format_return_deepin_shm, &nitems_return_deepin_shm,
|
||||
&bytes_after_return_deepin_shm, &prop_return_deepin_shm);
|
||||
&actual_type_return_deepin_shm, &actual_format_return_deepin_shm, &nitems_return_deepin_shm,
|
||||
&bytes_after_return_deepin_shm, &prop_return_deepin_shm);
|
||||
|
||||
//qDebug() << actual_type_return_deepin_shm << actual_format_return_deepin_shm << nitems_return_deepin_shm << bytes_after_return_deepin_shm << prop_return_deepin_shm;
|
||||
|
||||
@ -309,8 +313,7 @@ QRect AppSnapshot::rectRemovedShadow(const QImage &qimage, unsigned char *prop_t
|
||||
|
||||
const auto r = XGetWindowProperty(display, m_wid, gtk_frame_extents, 0, 4, false, XA_CARDINAL,
|
||||
&actual_type_return_gtk, &actual_format_return_gtk, &n_items_return_gtk, &bytes_after_return_gtk, &prop_to_return_gtk);
|
||||
if (!r && prop_to_return_gtk && n_items_return_gtk == 4 && actual_format_return_gtk == 32)
|
||||
{
|
||||
if (!r && prop_to_return_gtk && n_items_return_gtk == 4 && actual_format_return_gtk == 32) {
|
||||
qDebug() << "remove shadow frame...";
|
||||
const unsigned long *extents = reinterpret_cast<const unsigned long *>(prop_to_return_gtk);
|
||||
const int left = extents[0];
|
||||
|
@ -23,22 +23,36 @@
|
||||
#include "appsnapshot.h"
|
||||
#include "previewcontainer.h"
|
||||
|
||||
#include <DStyle>
|
||||
|
||||
#include <QGraphicsEffect>
|
||||
#include <QPainter>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
FloatingPreview::FloatingPreview(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
#define BORDER_MARGIN 8
|
||||
#define TITLE_MARGIN 20
|
||||
|
||||
m_closeBtn3D(new DImageButton)
|
||||
FloatingPreview::FloatingPreview(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_closeBtn3D(new DImageButton)
|
||||
, m_titleBtn(new DPushButton)
|
||||
{
|
||||
m_closeBtn3D->setFixedSize(24, 24);
|
||||
m_closeBtn3D->setNormalPic(":/icons/resources/close_round_normal.svg");
|
||||
m_closeBtn3D->setHoverPic(":/icons/resources/close_round_hover.svg");
|
||||
m_closeBtn3D->setPressPic(":/icons/resources/close_round_press.svg");
|
||||
|
||||
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);
|
||||
|
||||
@ -60,15 +74,28 @@ AppSnapshot *FloatingPreview::trackedWindow()
|
||||
return m_tracked;
|
||||
}
|
||||
|
||||
void FloatingPreview::trackWindow(AppSnapshot * const snap)
|
||||
void FloatingPreview::trackWindow(AppSnapshot *const snap)
|
||||
{
|
||||
if (!m_tracked.isNull())
|
||||
m_tracked->removeEventFilter(this);
|
||||
|
||||
snap->installEventFilter(this);
|
||||
m_tracked = snap;
|
||||
m_closeBtn3D->setVisible(m_tracked->closeAble());
|
||||
|
||||
QTimer::singleShot(0, this, [=] {
|
||||
m_closeBtn3D->setVisible(m_tracked->closeAble());
|
||||
m_titleBtn->setText(m_tracked->title());
|
||||
|
||||
QFontMetrics fm(m_titleBtn->font());
|
||||
int textWidth = fm.width(m_tracked->title()) + 10;
|
||||
int titleWidth = width() - (TITLE_MARGIN * 2 + BORDER_MARGIN);
|
||||
|
||||
if (textWidth < titleWidth) {
|
||||
m_titleBtn->setFixedWidth(textWidth);
|
||||
} else {
|
||||
m_titleBtn->setFixedWidth(titleWidth);
|
||||
}
|
||||
|
||||
QTimer::singleShot(0, this, [ = ] {
|
||||
setGeometry(snap->geometry());
|
||||
});
|
||||
}
|
||||
@ -89,37 +116,31 @@ void FloatingPreview::paintEvent(QPaintEvent *e)
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
const QRectF r = rect().marginsRemoved(QMargins(8, 8, 8, 8));
|
||||
const QRectF r = rect().marginsRemoved(QMargins(BORDER_MARGIN, BORDER_MARGIN, BORDER_MARGIN, BORDER_MARGIN));
|
||||
const auto ratio = devicePixelRatioF();
|
||||
|
||||
const qreal offset_x = width() / 2.0 - snapshot_geometry.width() / ratio / 2;
|
||||
const qreal offset_y = height() / 2.0 - snapshot_geometry.height() / ratio / 2;
|
||||
const int radius = 4;
|
||||
const qreal offset_x = width() / 2.0 - snapshot_geometry.width() / ratio / 2 - snapshot_geometry.left();
|
||||
const qreal offset_y = height() / 2.0 - snapshot_geometry.height() / ratio / 2 - snapshot_geometry.top();
|
||||
|
||||
// draw background
|
||||
DStyleHelper dstyle(style());
|
||||
const int radius = dstyle.pixelMetric(DStyle::PM_FrameRadius);
|
||||
|
||||
// 预览图
|
||||
QBrush brush;
|
||||
brush.setTextureImage(snapshot);
|
||||
painter.setBrush(brush);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(QColor(255, 255, 255, 255 * 0.3));
|
||||
painter.translate(QPoint(offset_x, offset_y));
|
||||
painter.drawRoundedRect(snapshot_geometry, radius, radius);
|
||||
painter.translate(QPoint(-offset_x, -offset_y));
|
||||
|
||||
// 选中外框
|
||||
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);
|
||||
|
||||
painter.drawImage(QPointF(offset_x, offset_y), snapshot, m_tracked->snapshotGeometry());
|
||||
|
||||
// bottom black background
|
||||
QRectF bgr = r;
|
||||
bgr.setTop(bgr.bottom() - 25);
|
||||
|
||||
QRectF bgre = bgr;
|
||||
bgre.setTop(bgr.top() - radius);
|
||||
|
||||
painter.save();
|
||||
painter.setClipRect(bgr);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(QColor(0, 0, 0, 255 * 0.3));
|
||||
painter.drawRoundedRect(bgre, radius, radius);
|
||||
painter.restore();
|
||||
|
||||
// bottom title
|
||||
painter.setPen(Qt::white);
|
||||
painter.drawText(bgr, Qt::AlignCenter, m_tracked->title());
|
||||
}
|
||||
|
||||
void FloatingPreview::mouseReleaseEvent(QMouseEvent *e)
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <QPointer>
|
||||
|
||||
#include <dimagebutton.h>
|
||||
#include <DPushButton>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
@ -41,7 +42,7 @@ public:
|
||||
AppSnapshot *trackedWindow();
|
||||
|
||||
public slots:
|
||||
void trackWindow(AppSnapshot * const snap);
|
||||
void trackWindow(AppSnapshot *const snap);
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
@ -56,6 +57,7 @@ private:
|
||||
QPointer<AppSnapshot> m_tracked;
|
||||
|
||||
DImageButton *m_closeBtn3D;
|
||||
DPushButton *m_titleBtn;
|
||||
};
|
||||
|
||||
#endif // FLOATINGPREVIEW_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user