feat(PreviewContainer):rounded corner, selected state, title style

This commit is contained in:
shaojun 2019-08-27 15:03:40 +08:00
parent dd7ef78dba
commit ae14390f2e
3 changed files with 83 additions and 57 deletions

View File

@ -22,6 +22,8 @@
#include "appsnapshot.h" #include "appsnapshot.h"
#include "previewcontainer.h" #include "previewcontainer.h"
#include <DStyle>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
@ -34,16 +36,14 @@
#include <QSizeF> #include <QSizeF>
#include <QTimer> #include <QTimer>
struct SHMInfo struct SHMInfo {
{
long shmid; long shmid;
long width; long width;
long height; long height;
long bytesPerLine; long bytesPerLine;
long format; long format;
struct Rect struct Rect {
{
long x; long x;
long y; long y;
long width; long width;
@ -142,7 +142,7 @@ void AppSnapshot::fetchSnapshot()
if (info) { if (info) {
qDebug() << "get Image from dxcbplugin SHM..."; 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; //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) { if ((qint64)image_data != -1) {
m_snapshot = QImage(image_data, info->width, info->height, info->bytesPerLine, (QImage::Format)info->format); 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); 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; image_data = nullptr;
} }
if (!image_data || qimage.isNull()) if (!image_data || qimage.isNull()) {
{
// get window image from XGetImage(a little slow) // get window image from XGetImage(a little slow)
qDebug() << "get Image from dxcbplugin SHM failed!"; qDebug() << "get Image from dxcbplugin SHM failed!";
qDebug() << "get Image from Xlib..."; qDebug() << "get Image from Xlib...";
ximage = getImageXlib(); ximage = getImageXlib();
if (!ximage) if (!ximage) {
{
qDebug() << "get Image from Xlib failed! giving up..."; qDebug() << "get Image from Xlib failed! giving up...";
emit requestCheckWindow(); emit requestCheckWindow();
return; 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()); Q_ASSERT(!qimage.isNull());
@ -200,8 +198,7 @@ void AppSnapshot::enterEvent(QEvent *e)
if (!m_wmHelper->hasComposite()) { if (!m_wmHelper->hasComposite()) {
m_closeBtn2D->setVisible(true); m_closeBtn2D->setVisible(true);
} } else {
else {
emit entered(wid()); emit entered(wid());
} }
@ -221,8 +218,7 @@ void AppSnapshot::paintEvent(QPaintEvent *e)
{ {
QPainter painter(this); QPainter painter(this);
if (!m_wmHelper->hasComposite()) if (!m_wmHelper->hasComposite()) {
{
if (underMouse()) if (underMouse())
painter.fillRect(rect(), QColor(255, 255, 255, 255 * .2)); painter.fillRect(rect(), QColor(255, 255, 255, 255 * .2));
return; return;
@ -234,8 +230,7 @@ void AppSnapshot::paintEvent(QPaintEvent *e)
const auto ratio = devicePixelRatioF(); const auto ratio = devicePixelRatioF();
// draw attention background // draw attention background
if (m_windowInfo.attention) if (m_windowInfo.attention) {
{
painter.setBrush(QColor(241, 138, 46, 255 * .8)); painter.setBrush(QColor(241, 138, 46, 255 * .8));
painter.setPen(Qt::NoPen); painter.setPen(Qt::NoPen);
painter.drawRoundedRect(rect(), 5, 5); painter.drawRoundedRect(rect(), 5, 5);
@ -244,9 +239,18 @@ void AppSnapshot::paintEvent(QPaintEvent *e)
// draw image // draw image
const QImage &im = m_snapshot; const QImage &im = m_snapshot;
const qreal offset_x = width() / 2.0 - m_snapshotSrcRect.width() / ratio / 2; 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; const qreal offset_y = height() / 2.0 - m_snapshotSrcRect.height() / ratio / 2 - m_snapshotSrcRect.top();
painter.drawImage(QPointF(offset_x, offset_y), im, m_snapshotSrcRect);
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) void AppSnapshot::resizeEvent(QResizeEvent *e)
@ -263,7 +267,7 @@ void AppSnapshot::mousePressEvent(QMouseEvent *e)
emit clicked(m_wid); emit clicked(m_wid);
} }
SHMInfo * AppSnapshot::getImageDSHM() SHMInfo *AppSnapshot::getImageDSHM()
{ {
const auto display = QX11Info::display(); const auto display = QX11Info::display();
@ -279,8 +283,8 @@ SHMInfo * AppSnapshot::getImageDSHM()
unsigned char *prop_return_deepin_shm; unsigned char *prop_return_deepin_shm;
XGetWindowProperty(display, m_wid, atom_prop, 0, 32 * 9, false, AnyPropertyType, 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, &actual_type_return_deepin_shm, &actual_format_return_deepin_shm, &nitems_return_deepin_shm,
&bytes_after_return_deepin_shm, &prop_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; //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, 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); &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..."; qDebug() << "remove shadow frame...";
const unsigned long *extents = reinterpret_cast<const unsigned long *>(prop_to_return_gtk); const unsigned long *extents = reinterpret_cast<const unsigned long *>(prop_to_return_gtk);
const int left = extents[0]; const int left = extents[0];

View File

@ -23,22 +23,36 @@
#include "appsnapshot.h" #include "appsnapshot.h"
#include "previewcontainer.h" #include "previewcontainer.h"
#include <DStyle>
#include <QGraphicsEffect>
#include <QPainter> #include <QPainter>
#include <QVBoxLayout> #include <QVBoxLayout>
FloatingPreview::FloatingPreview(QWidget *parent) #define BORDER_MARGIN 8
: QWidget(parent), #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->setFixedSize(24, 24);
m_closeBtn3D->setNormalPic(":/icons/resources/close_round_normal.svg"); m_closeBtn3D->setNormalPic(":/icons/resources/close_round_normal.svg");
m_closeBtn3D->setHoverPic(":/icons/resources/close_round_hover.svg"); m_closeBtn3D->setHoverPic(":/icons/resources/close_round_hover.svg");
m_closeBtn3D->setPressPic(":/icons/resources/close_round_press.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; QVBoxLayout *centralLayout = new QVBoxLayout;
centralLayout->addWidget(m_closeBtn3D); centralLayout->addWidget(m_closeBtn3D);
centralLayout->setAlignment(m_closeBtn3D, Qt::AlignRight | Qt::AlignTop); 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->setMargin(0);
centralLayout->setSpacing(0); centralLayout->setSpacing(0);
@ -60,15 +74,28 @@ AppSnapshot *FloatingPreview::trackedWindow()
return m_tracked; return m_tracked;
} }
void FloatingPreview::trackWindow(AppSnapshot * const snap) void FloatingPreview::trackWindow(AppSnapshot *const snap)
{ {
if (!m_tracked.isNull()) if (!m_tracked.isNull())
m_tracked->removeEventFilter(this); m_tracked->removeEventFilter(this);
snap->installEventFilter(this); snap->installEventFilter(this);
m_tracked = snap; 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()); setGeometry(snap->geometry());
}); });
} }
@ -89,37 +116,31 @@ void FloatingPreview::paintEvent(QPaintEvent *e)
QPainter painter(this); QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); 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 auto ratio = devicePixelRatioF();
const qreal offset_x = width() / 2.0 - snapshot_geometry.width() / ratio / 2; 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; const qreal offset_y = height() / 2.0 - snapshot_geometry.height() / ratio / 2 - snapshot_geometry.top();
const int radius = 4;
// 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.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.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) void FloatingPreview::mouseReleaseEvent(QMouseEvent *e)

View File

@ -26,6 +26,7 @@
#include <QPointer> #include <QPointer>
#include <dimagebutton.h> #include <dimagebutton.h>
#include <DPushButton>
DWIDGET_USE_NAMESPACE DWIDGET_USE_NAMESPACE
@ -41,7 +42,7 @@ public:
AppSnapshot *trackedWindow(); AppSnapshot *trackedWindow();
public slots: public slots:
void trackWindow(AppSnapshot * const snap); void trackWindow(AppSnapshot *const snap);
private: private:
void paintEvent(QPaintEvent *e) override; void paintEvent(QPaintEvent *e) override;
@ -56,6 +57,7 @@ private:
QPointer<AppSnapshot> m_tracked; QPointer<AppSnapshot> m_tracked;
DImageButton *m_closeBtn3D; DImageButton *m_closeBtn3D;
DPushButton *m_titleBtn;
}; };
#endif // FLOATINGPREVIEW_H #endif // FLOATINGPREVIEW_H