From ae14390f2e6faddcd8c340bad7080d70abfa4a55 Mon Sep 17 00:00:00 2001 From: shaojun Date: Tue, 27 Aug 2019 15:03:40 +0800 Subject: [PATCH] feat(PreviewContainer):rounded corner, selected state, title style --- frame/item/components/appsnapshot.cpp | 51 +++++++------- frame/item/components/floatingpreview.cpp | 85 ++++++++++++++--------- frame/item/components/floatingpreview.h | 4 +- 3 files changed, 83 insertions(+), 57 deletions(-) diff --git a/frame/item/components/appsnapshot.cpp b/frame/item/components/appsnapshot.cpp index 851aadd82..4c854e0b5 100644 --- a/frame/item/components/appsnapshot.cpp +++ b/frame/item/components/appsnapshot.cpp @@ -22,6 +22,8 @@ #include "appsnapshot.h" #include "previewcontainer.h" +#include + #include #include #include @@ -34,16 +36,14 @@ #include #include -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(prop_to_return_gtk); const int left = extents[0]; diff --git a/frame/item/components/floatingpreview.cpp b/frame/item/components/floatingpreview.cpp index aa9d40759..1052acad2 100644 --- a/frame/item/components/floatingpreview.cpp +++ b/frame/item/components/floatingpreview.cpp @@ -23,22 +23,36 @@ #include "appsnapshot.h" #include "previewcontainer.h" +#include + +#include #include #include -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) diff --git a/frame/item/components/floatingpreview.h b/frame/item/components/floatingpreview.h index 6c13588c9..54dada978 100644 --- a/frame/item/components/floatingpreview.h +++ b/frame/item/components/floatingpreview.h @@ -26,6 +26,7 @@ #include #include +#include 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 m_tracked; DImageButton *m_closeBtn3D; + DPushButton *m_titleBtn; }; #endif // FLOATINGPREVIEW_H