From b91bae6801183f84b80f45c0306725540d2c9d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=B3=E5=8D=9A=E6=96=87?= Date: Tue, 10 Oct 2017 16:40:17 +0800 Subject: [PATCH] app preview window support hidpi Change-Id: Id08566410b5caf239a3c3e05b5203aca7fd81f8a --- frame/frame.pro | 2 - frame/item/components/appsnapshot.cpp | 10 +- frame/item/components/floatingpreview.cpp | 11 +- frame/item/components/previewwidget.cpp | 254 ---------------------- frame/item/components/previewwidget.h | 82 ------- 5 files changed, 15 insertions(+), 344 deletions(-) delete mode 100644 frame/item/components/previewwidget.cpp delete mode 100644 frame/item/components/previewwidget.h diff --git a/frame/frame.pro b/frame/frame.pro index 12c80fd7f..4f506d91b 100644 --- a/frame/frame.pro +++ b/frame/frame.pro @@ -37,7 +37,6 @@ SOURCES += main.cpp \ item/containeritem.cpp \ item/components/containerwidget.cpp \ dbus/dbusdockadaptors.cpp \ - item/components/previewwidget.cpp \ item/components/appsnapshot.cpp \ item/components/floatingpreview.cpp \ item/components/previewcontainer.cpp @@ -68,7 +67,6 @@ HEADERS += \ item/containeritem.h \ item/components/containerwidget.h \ dbus/dbusdockadaptors.h \ - item/components/previewwidget.h \ item/components/appsnapshot.h \ item/components/floatingpreview.h \ item/components/previewcontainer.h diff --git a/frame/item/components/appsnapshot.cpp b/frame/item/components/appsnapshot.cpp index dba0c5f0f..9e03e183c 100644 --- a/frame/item/components/appsnapshot.cpp +++ b/frame/item/components/appsnapshot.cpp @@ -187,12 +187,16 @@ void AppSnapshot::paintEvent(QPaintEvent *e) return; const QRect r = rect().marginsRemoved(QMargins(8, 8, 8, 8)); + const auto ratio = devicePixelRatioF(); // draw image - const QImage im = m_snapshot.scaled(r.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + QImage im = m_snapshot.scaled(r.size() * ratio, Qt::KeepAspectRatio, Qt::SmoothTransformation); + im.setDevicePixelRatio(ratio); + const QRect ir = im.rect(); - const QPoint offset = r.center() - ir.center(); - painter.drawImage(offset.x(), offset.y(), im); + const int offset_x = r.x() + r.width() / 2 - ir.width() / ratio / 2; + const int offset_y = r.y() + r.height() / 2 - ir.height() / ratio / 2; + painter.drawImage(offset_x, offset_y, im); } void AppSnapshot::mousePressEvent(QMouseEvent *e) diff --git a/frame/item/components/floatingpreview.cpp b/frame/item/components/floatingpreview.cpp index da9d50f1b..cbefc3faa 100644 --- a/frame/item/components/floatingpreview.cpp +++ b/frame/item/components/floatingpreview.cpp @@ -84,9 +84,14 @@ void FloatingPreview::paintEvent(QPaintEvent *e) painter.setRenderHint(QPainter::Antialiasing); const QRect r = rect().marginsRemoved(QMargins(8, 8, 8, 8)); - const QImage im = snapshot.scaled(r.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + const auto ratio = devicePixelRatioF(); + + QImage im = snapshot.scaled(r.size() * ratio, Qt::KeepAspectRatio, Qt::SmoothTransformation); + im.setDevicePixelRatio(ratio); + const QRect ir = im.rect(); - const QPoint offset = r.center() - ir.center(); + const int offset_x = r.x() + r.width() / 2 - ir.width() / ratio / 2; + const int offset_y = r.y() + r.height() / 2 - ir.height() / ratio / 2; const int radius = 4; // draw background @@ -95,7 +100,7 @@ void FloatingPreview::paintEvent(QPaintEvent *e) painter.drawRoundedRect(r, radius, radius); // draw preview image - painter.drawImage(offset.x(), offset.y(), im); + painter.drawImage(offset_x, offset_y, im); // bottom black background QRect bgr = r; diff --git a/frame/item/components/previewwidget.cpp b/frame/item/components/previewwidget.cpp deleted file mode 100644 index c96864865..000000000 --- a/frame/item/components/previewwidget.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) 2011 ~ 2017 Deepin Technology Co., Ltd. - * - * Author: sbw - * - * Maintainer: sbw - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "previewwidget.h" - -#include -#include -#include - -#include -#include -#include -#include - -#define PREVIEW_W 200 -#define PREVIEW_H 130 -#define PREVIEW_M 12 -#define PREVIEW_MINI_H 30 - -PreviewWidget::PreviewWidget(const WId wid, QWidget *parent) - : QWidget(parent), - - m_wid(wid), - m_mouseEnterTimer(new QTimer(this)), - - m_hovered(false), - - m_wmHelper(DWindowManagerHelper::instance()) -{ - m_closeButton = new DImageButton; - m_closeButton->setFixedSize(24, 24); - m_closeButton->setVisible(false); - m_closeButton->setNormalPic(":/icons/resources/close_round_normal.png"); - m_closeButton->setHoverPic(":/icons/resources/close_round_hover.png"); - m_closeButton->setPressPic(":/icons/resources/close_round_press.png"); - - m_droppedDelay = new QTimer(this); - m_droppedDelay->setSingleShot(true); - m_droppedDelay->setInterval(100); - - m_mouseEnterTimer->setInterval(200); - m_mouseEnterTimer->setSingleShot(true); - - m_centralLayout = new QVBoxLayout; - m_centralLayout->setSpacing(0); - m_centralLayout->setMargin(0); - m_centralLayout->addWidget(m_closeButton); - m_centralLayout->setAlignment(m_closeButton, Qt::AlignTop | Qt::AlignRight); - - setFixedSize(PREVIEW_W + PREVIEW_M * 2, PREVIEW_H + PREVIEW_M * 2); - setLayout(m_centralLayout); - setAcceptDrops(true); - - connect(m_closeButton, &DImageButton::clicked, this, &PreviewWidget::closeWindow); - connect(m_mouseEnterTimer, &QTimer::timeout, this, &PreviewWidget::showPreview, Qt::QueuedConnection); - connect(m_wmHelper, &DWindowManagerHelper::hasCompositeChanged, this, &PreviewWidget::updatePreviewSize, Qt::QueuedConnection); - - QTimer::singleShot(1, this, &PreviewWidget::refreshImage); - QTimer::singleShot(1, this, &PreviewWidget::updatePreviewSize); -} - -void PreviewWidget::setTitle(const QString &title) -{ - m_title = title; - - update(); -} - -void PreviewWidget::refreshImage() -{ - if (!m_wmHelper->hasComposite()) - return; - - const auto display = QX11Info::display(); - - XWindowAttributes attrs; - XGetWindowAttributes(display, m_wid, &attrs); - XImage *ximage = XGetImage(display, m_wid, 0, 0, attrs.width, attrs.height, AllPlanes, ZPixmap); - - const QImage qimage((const uchar*)(ximage->data), ximage->width, ximage->height, ximage->bytes_per_line, QImage::Format_RGB32); - m_image = qimage.scaled(PREVIEW_W, PREVIEW_H, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); - m_image = m_image.copy((m_image.width() - PREVIEW_W) / 2, (m_image.height() - PREVIEW_H) / 2, PREVIEW_W, PREVIEW_H); - XDestroyImage(ximage); - - update(); -} - -void PreviewWidget::closeWindow() -{ - const auto display = QX11Info::display(); - - XEvent e; - - memset(&e, 0, sizeof(e)); - e.xclient.type = ClientMessage; - e.xclient.window = m_wid; - e.xclient.message_type = XInternAtom(display, "WM_PROTOCOLS", true); - e.xclient.format = 32; - e.xclient.data.l[0] = XInternAtom(display, "WM_DELETE_WINDOW", false); - e.xclient.data.l[1] = CurrentTime; - - XSendEvent(display, m_wid, false, NoEventMask, &e); -// XDestroyWindow(display, m_wid); - XFlush(display); -} - -void PreviewWidget::showPreview() -{ - if (m_wmHelper->hasComposite()) - emit requestPreviewWindow(m_wid); -} - -void PreviewWidget::updatePreviewSize() -{ - if (m_wmHelper->hasComposite()) - { - setFixedHeight(PREVIEW_H + PREVIEW_M * 2); - m_centralLayout->setAlignment(m_closeButton, Qt::AlignTop | Qt::AlignRight); - m_centralLayout->setMargin(0); - } else { - setFixedHeight(PREVIEW_MINI_H); - m_centralLayout->setAlignment(m_closeButton, Qt::AlignVCenter | Qt::AlignRight); - m_centralLayout->setContentsMargins(0, 0, 10, 0); - } - - refreshImage(); -} - -void PreviewWidget::paintEvent(QPaintEvent *e) -{ - QPainter painter(this); - - if (m_wmHelper->hasComposite()) - { - const QRect r = rect().marginsRemoved(QMargins(PREVIEW_M, PREVIEW_M, PREVIEW_M, PREVIEW_M)); - - // draw image - const QRect ir = m_image.rect(); - const QPoint offset = r.center() - ir.center(); - - painter.fillRect(offset.x(), offset.y(), ir.width(), ir.height(), Qt::white); - painter.drawImage(offset.x(), offset.y(), m_image); - - // bottom black background - QRect bgr = r; - bgr.setTop(bgr.bottom() - 30); - painter.fillRect(bgr, QColor(0, 0, 0, 255 * 0.3)); - // bottom title - painter.drawText(bgr, Qt::AlignCenter, m_title); - - // draw border - if (m_hovered) - { - const QRect br = r.marginsAdded(QMargins(1, 1, 1, 1)); - painter.setBrush(Qt::transparent); - painter.setRenderHint(QPainter::Antialiasing); - painter.drawRoundedRect(br, 3, 3); - } - } else { - const QRect r = rect(); - - if (m_hovered) - painter.fillRect(r, QColor(255, 255, 255, .3 * 255)); - - painter.drawText(r.marginsRemoved(QMargins(10, 0, 35, 0)), Qt::AlignLeft | Qt::AlignVCenter, m_title); - } - - QWidget::paintEvent(e); -} - -void PreviewWidget::enterEvent(QEvent *e) -{ - if (m_droppedDelay->isActive()) - return e->ignore(); - - m_hovered = true; - m_closeButton->setVisible(true); - m_mouseEnterTimer->start(); - - update(); - - QWidget::enterEvent(e); -} - -void PreviewWidget::leaveEvent(QEvent *e) -{ - m_hovered = false; - m_closeButton->setVisible(false); - m_mouseEnterTimer->stop(); - - update(); - - QWidget::leaveEvent(e); -} - -void PreviewWidget::mouseReleaseEvent(QMouseEvent *e) -{ - if (m_droppedDelay->isActive()) - return e->ignore(); - - QWidget::mouseReleaseEvent(e); - - m_mouseEnterTimer->stop(); - emit requestHidePreview(); - emit requestActivateWindow(m_wid); - emit requestCancelPreview(); -} - -void PreviewWidget::dragEnterEvent(QDragEnterEvent *e) -{ - e->accept(); - - m_hovered = true; - - update(); - - emit requestActivateWindow(m_wid); -} - -void PreviewWidget::dragLeaveEvent(QDragLeaveEvent *e) -{ - QWidget::dragLeaveEvent(e); - - m_hovered = false; - - update(); -} - -void PreviewWidget::dropEvent(QDropEvent *e) -{ - m_droppedDelay->start(); - - QWidget::dropEvent(e); - - emit requestCancelPreview(); -} diff --git a/frame/item/components/previewwidget.h b/frame/item/components/previewwidget.h deleted file mode 100644 index 59267ff37..000000000 --- a/frame/item/components/previewwidget.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2011 ~ 2017 Deepin Technology Co., Ltd. - * - * Author: sbw - * - * Maintainer: sbw - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef PREVIEWWIDGET_H -#define PREVIEWWIDGET_H - -#include -#include -#include -#include -#include - -#include -#include - -DWIDGET_USE_NAMESPACE - -class PreviewWidget : public QWidget -{ - Q_OBJECT -public: - explicit PreviewWidget(const WId wid, QWidget *parent = 0); - - void setTitle(const QString &title); - -signals: - void requestActivateWindow(const WId wid) const; - void requestPreviewWindow(const WId wid) const; - void requestCancelPreview() const; - void requestHidePreview() const; - -private slots: - void refreshImage(); - void closeWindow(); - void showPreview(); - - void updatePreviewSize(); - -private: - void paintEvent(QPaintEvent *e); - void enterEvent(QEvent *e); - void leaveEvent(QEvent *e); - void mouseReleaseEvent(QMouseEvent *e); - void dragEnterEvent(QDragEnterEvent *e); - void dragLeaveEvent(QDragLeaveEvent *e); - void dropEvent(QDropEvent *e); - -private: - const WId m_wid; - QImage m_image; - QString m_title; - - DImageButton *m_closeButton; - QVBoxLayout *m_centralLayout; - - QTimer *m_droppedDelay; - QTimer *m_mouseEnterTimer; - - bool m_hovered; - - DWindowManagerHelper *m_wmHelper; -}; - -#endif // PREVIEWWIDGET_H