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"