File indexing completed on 2024-04-28 04:32:07
0001 /* 0002 * Copyright (C) 2015 by Stephen Allewell 0003 * steve.allewell@gmail.com 0004 * 0005 * This program is free software; you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation; either version 2 of the License, or 0008 * (at your option) any later version. 0009 */ 0010 0011 /** @file 0012 * This file defines an extension to a QLabel that scales the associated QPixmap 0013 * to maintain the aspect ratio when scaling to fill the extents of the QLabel 0014 * area. 0015 */ 0016 0017 // Class include 0018 #include "ScaledPixmapLabel.h" 0019 0020 // Qt includes 0021 #include <QMouseEvent> 0022 #include <QPainter> 0023 #include <QStyleOptionRubberBand> 0024 0025 ScaledPixmapLabel::ScaledPixmapLabel(QWidget *parent) 0026 : QLabel(parent) 0027 , m_cropping(false) 0028 { 0029 setMinimumSize(1, 1); 0030 setAlignment(Qt::AlignCenter); 0031 setMouseTracking(true); 0032 } 0033 0034 void ScaledPixmapLabel::setPixmap(const QPixmap &pixmap) 0035 { 0036 m_pixmap = pixmap; 0037 m_crop = QRect(); 0038 QLabel::setPixmap(m_pixmap.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); 0039 } 0040 0041 void ScaledPixmapLabel::setCropping(bool checked) 0042 { 0043 m_cropping = checked; 0044 m_crop = QRect(); 0045 update(); 0046 } 0047 0048 int ScaledPixmapLabel::heightForWidth(int width) const 0049 { 0050 return ((qreal)m_pixmap.height() * width) / m_pixmap.width(); 0051 } 0052 0053 QSize ScaledPixmapLabel::sizeHint() const 0054 { 0055 int w = width(); 0056 return QSize(w, heightForWidth(w)); 0057 } 0058 0059 QRect ScaledPixmapLabel::pixmapRect() const 0060 { 0061 QSize previewSize = size(); 0062 QSize pixmapSize = pixmap()->size(); 0063 0064 int dx = (previewSize.width() - pixmapSize.width()) / 2; 0065 int dy = (previewSize.height() - pixmapSize.height()) / 2; 0066 0067 return QRect(dx, dy, pixmapSize.width(), pixmapSize.height()); 0068 } 0069 0070 void ScaledPixmapLabel::resizeEvent(QResizeEvent *event) 0071 { 0072 Q_UNUSED(event); 0073 0074 QLabel::setPixmap(m_pixmap.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); 0075 } 0076 0077 void ScaledPixmapLabel::paintEvent(QPaintEvent *event) 0078 { 0079 QLabel::paintEvent(event); 0080 0081 QPainter painter(this); 0082 painter.setRenderHint(QPainter::Qt4CompatiblePainting, true); 0083 0084 if (m_crop.isValid()) { 0085 QStyleOptionRubberBand opt; 0086 opt.initFrom(this); 0087 opt.shape = QRubberBand::Rectangle; 0088 opt.opaque = false; 0089 opt.rect = m_crop.adjusted(0, 0, 1, 1); 0090 0091 style()->drawControl(QStyle::CE_RubberBand, &opt, &painter); 0092 } else { 0093 if (m_cropping && underMouse() && (children().count() == 0)) { 0094 // draw guides 0095 QPoint cursor = mapFromGlobal(QCursor::pos()); 0096 painter.drawLine(cursor.x(), 0, cursor.x(), size().height()); 0097 painter.drawLine(0, cursor.y(), size().width(), cursor.y()); 0098 } 0099 } 0100 } 0101 0102 void ScaledPixmapLabel::mousePressEvent(QMouseEvent *event) 0103 { 0104 if (m_cropping) { 0105 m_start = event->pos(); 0106 m_crop = QRect(); 0107 update(); 0108 } 0109 } 0110 0111 void ScaledPixmapLabel::mouseMoveEvent(QMouseEvent *event) 0112 { 0113 if (m_cropping && (event->buttons() & Qt::LeftButton)) { 0114 m_end = event->pos(); 0115 m_crop = pixmapRect().intersected(QRect(m_start, m_end).normalized()); 0116 } 0117 0118 update(); 0119 } 0120 0121 void ScaledPixmapLabel::mouseReleaseEvent(QMouseEvent *event) 0122 { 0123 if (m_cropping) { 0124 m_end = event->pos(); 0125 m_crop = pixmapRect().intersected(QRect(m_start, m_end).normalized()); 0126 update(); 0127 0128 double scale = (double)m_pixmap.size().width() / (double)pixmap()->size().width(); 0129 m_crop.translate(-pixmapRect().topLeft()); 0130 QRectF cropF(scale * m_crop.x(), scale * m_crop.y(), scale * m_crop.width(), scale * m_crop.height()); 0131 0132 emit imageCropped(cropF); 0133 0134 m_crop = QRect(); 0135 } 0136 } 0137 0138 void ScaledPixmapLabel::leaveEvent(QEvent *event) 0139 { 0140 update(); 0141 QLabel::leaveEvent(event); 0142 } 0143 0144 #include "moc_ScaledPixmapLabel.cpp"