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 "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;
@ -152,14 +152,12 @@ 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;
@ -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)
@ -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];

View File

@ -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);
@ -64,9 +78,22 @@ 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());
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)

View File

@ -26,6 +26,7 @@
#include <QPointer>
#include <dimagebutton.h>
#include <DPushButton>
DWIDGET_USE_NAMESPACE
@ -56,6 +57,7 @@ private:
QPointer<AppSnapshot> m_tracked;
DImageButton *m_closeBtn3D;
DPushButton *m_titleBtn;
};
#endif // FLOATINGPREVIEW_H