File indexing completed on 2024-11-10 04:56:51

0001 /*
0002     SPDX-FileCopyrightText: 2009 Marco Martin <notmart@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "screenpreviewwidget.h"
0008 
0009 #include <QPaintEvent>
0010 #include <QPainter>
0011 #include <QResizeEvent>
0012 
0013 #include <QDebug>
0014 #include <QMimeData>
0015 
0016 #include <KSvg/FrameSvg>
0017 #include <KSvg/ImageSet>
0018 
0019 #include <memory>
0020 
0021 class ScreenPreviewWidgetPrivate
0022 {
0023 public:
0024     ScreenPreviewWidgetPrivate(ScreenPreviewWidget *screen)
0025         : q(screen)
0026         , ratio(1)
0027         , minimumContentWidth(0)
0028     {
0029     }
0030 
0031     ~ScreenPreviewWidgetPrivate()
0032     {
0033     }
0034 
0035     void updateRect(const QRectF &rect)
0036     {
0037         q->update(rect.toRect());
0038     }
0039 
0040     void updateScreenGraphics()
0041     {
0042         int bottomElements = screenGraphics->elementSize("base").height() + screenGraphics->marginSize(KSvg::FrameSvg::BottomMargin);
0043         QRect bounds(QPoint(0, 0), QSize(q->width(), q->height() - bottomElements));
0044 
0045         QSizeF monitorSize(1.0, 1.0 / ratio);
0046         monitorSize.scale(bounds.size(), Qt::KeepAspectRatio);
0047 
0048         if (monitorSize.isEmpty()) {
0049             return;
0050         }
0051 
0052         const auto minFrameWidth = minimumContentWidth + screenGraphics->marginSize(KSvg::FrameSvg::LeftMargin) + screenGraphics->marginSize(KSvg::FrameSvg::RightMargin);
0053         if (monitorSize.width() < minFrameWidth) {
0054             monitorSize.setWidth(minFrameWidth);
0055         }
0056 
0057         monitorRect = QRect(QPoint(0, 0), monitorSize.toSize());
0058         monitorRect.moveCenter(bounds.center());
0059 
0060         screenGraphics->resizeFrame(monitorRect.size());
0061 
0062         previewRect = screenGraphics->contentsRect().toRect();
0063         previewRect.moveCenter(bounds.center());
0064     }
0065 
0066     ScreenPreviewWidget *q;
0067     std::unique_ptr<KSvg::ImageSet> svgImageSet;
0068     KSvg::FrameSvg *screenGraphics;
0069     QPixmap preview;
0070     QRect monitorRect;
0071     qreal ratio;
0072     qreal minimumContentWidth;
0073     QRect previewRect;
0074 };
0075 
0076 ScreenPreviewWidget::ScreenPreviewWidget(QWidget *parent)
0077     : QWidget(parent)
0078     , d(std::make_unique<ScreenPreviewWidgetPrivate>(this))
0079 {
0080     d->svgImageSet = std::make_unique<KSvg::ImageSet>();
0081     d->svgImageSet->setBasePath("plasma/desktoptheme");
0082     d->screenGraphics = new KSvg::FrameSvg(this);
0083     d->screenGraphics->setImageSet(d->svgImageSet.get());
0084     d->screenGraphics->setImagePath("widgets/monitor");
0085     d->updateScreenGraphics();
0086 }
0087 
0088 ScreenPreviewWidget::~ScreenPreviewWidget() = default;
0089 
0090 void ScreenPreviewWidget::setPreview(const QPixmap &preview)
0091 {
0092     d->preview = preview;
0093 
0094     update();
0095 }
0096 
0097 const QPixmap ScreenPreviewWidget::preview() const
0098 {
0099     return d->preview;
0100 }
0101 
0102 void ScreenPreviewWidget::setRatio(const qreal ratio)
0103 {
0104     d->ratio = ratio;
0105     d->updateScreenGraphics();
0106 }
0107 
0108 qreal ScreenPreviewWidget::ratio() const
0109 {
0110     return d->ratio;
0111 }
0112 
0113 void ScreenPreviewWidget::setMinimumContentWidth(const qreal minw)
0114 {
0115     d->minimumContentWidth = minw;
0116     d->updateScreenGraphics();
0117 }
0118 
0119 qreal ScreenPreviewWidget::minimumContentWidth() const
0120 {
0121     return d->minimumContentWidth;
0122 }
0123 
0124 QRect ScreenPreviewWidget::previewRect() const
0125 {
0126     return d->previewRect;
0127 }
0128 
0129 KSvg::ImageSet *ScreenPreviewWidget::svgImageSet() const
0130 {
0131     return d->svgImageSet.get();
0132 }
0133 
0134 void ScreenPreviewWidget::resizeEvent(QResizeEvent *e)
0135 {
0136     d->updateScreenGraphics();
0137 }
0138 
0139 void ScreenPreviewWidget::paintEvent(QPaintEvent *event)
0140 {
0141     if (d->monitorRect.size().isEmpty()) {
0142         return;
0143     }
0144 
0145     QPainter painter(this);
0146     QPoint standPosition(d->monitorRect.center().x() - d->screenGraphics->elementSize("base").width() / 2, d->previewRect.bottom());
0147 
0148     d->screenGraphics->paint(&painter, QRect(standPosition, d->screenGraphics->elementSize("base").toSize()), "base");
0149     d->screenGraphics->paintFrame(&painter, d->monitorRect.topLeft());
0150 
0151     painter.save();
0152     if (!d->preview.isNull()) {
0153         painter.setRenderHint(QPainter::SmoothPixmapTransform);
0154         painter.drawPixmap(d->previewRect, d->preview, d->preview.rect());
0155     }
0156     painter.restore();
0157 
0158     d->screenGraphics->paint(&painter, d->previewRect, "glass");
0159 }
0160 
0161 #include "moc_screenpreviewwidget.cpp"