2019-09-28 01:18:08 +08:00
|
|
|
#include "graphicsview.h"
|
|
|
|
|
2019-09-29 15:52:35 +08:00
|
|
|
#include "graphicsscene.h"
|
|
|
|
|
2019-09-28 01:18:08 +08:00
|
|
|
#include <QDebug>
|
|
|
|
#include <QMouseEvent>
|
|
|
|
#include <QScrollBar>
|
2019-09-29 15:52:35 +08:00
|
|
|
#include <QMimeData>
|
|
|
|
#include <QImageReader>
|
2019-09-28 01:18:08 +08:00
|
|
|
|
|
|
|
GraphicsView::GraphicsView(QWidget *parent)
|
|
|
|
: QGraphicsView (parent)
|
|
|
|
{
|
|
|
|
setDragMode(QGraphicsView::ScrollHandDrag);
|
|
|
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
2019-09-29 21:22:20 +08:00
|
|
|
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
|
2019-09-28 01:18:08 +08:00
|
|
|
setStyleSheet("background-color: rgba(0, 0, 0, 180);"
|
|
|
|
"border-radius: 3px;");
|
2019-09-29 15:52:35 +08:00
|
|
|
setAcceptDrops(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsView::showImage(const QPixmap &pixmap)
|
|
|
|
{
|
2019-09-29 21:22:20 +08:00
|
|
|
resetTransform();
|
2019-09-29 15:52:35 +08:00
|
|
|
scene()->showImage(pixmap);
|
2019-09-29 21:22:20 +08:00
|
|
|
if (!isThingSmallerThanWindowWith(transform())) {
|
|
|
|
m_enableFitInView = true;
|
|
|
|
fitInView(sceneRect(), Qt::KeepAspectRatio);
|
|
|
|
}
|
2019-09-29 15:52:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsView::showText(const QString &text)
|
|
|
|
{
|
|
|
|
scene()->showText(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
GraphicsScene *GraphicsView::scene() const
|
|
|
|
{
|
|
|
|
return qobject_cast<GraphicsScene*>(QGraphicsView::scene());
|
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsView::setScene(GraphicsScene *scene)
|
|
|
|
{
|
|
|
|
return QGraphicsView::setScene(scene);
|
2019-09-28 01:18:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsView::mousePressEvent(QMouseEvent *event)
|
|
|
|
{
|
2019-09-29 21:22:20 +08:00
|
|
|
if (shouldIgnoreMousePressMoveEvent(event)) {
|
2019-09-28 01:18:08 +08:00
|
|
|
event->ignore();
|
|
|
|
// blumia: return here, or the QMouseEvent event transparency won't
|
|
|
|
// work if we set a QGraphicsView::ScrollHandDrag drag mode.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return QGraphicsView::mousePressEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsView::mouseMoveEvent(QMouseEvent *event)
|
|
|
|
{
|
2019-09-29 21:22:20 +08:00
|
|
|
if (shouldIgnoreMousePressMoveEvent(event)) {
|
2019-09-28 01:18:08 +08:00
|
|
|
event->ignore();
|
|
|
|
}
|
|
|
|
|
|
|
|
return QGraphicsView::mouseMoveEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsView::mouseReleaseEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
QGraphicsItem *item = itemAt(event->pos());
|
|
|
|
if (!item) {
|
|
|
|
event->ignore();
|
|
|
|
}
|
|
|
|
|
|
|
|
return QGraphicsView::mouseReleaseEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsView::wheelEvent(QWheelEvent *event)
|
|
|
|
{
|
2019-09-29 21:22:20 +08:00
|
|
|
m_enableFitInView = false;
|
|
|
|
if (event->delta() > 0) {
|
2019-09-28 01:18:08 +08:00
|
|
|
scale(1.25, 1.25);
|
|
|
|
} else {
|
|
|
|
scale(0.8, 0.8);
|
|
|
|
}
|
|
|
|
}
|
2019-09-29 15:52:35 +08:00
|
|
|
|
2019-09-29 21:22:20 +08:00
|
|
|
void GraphicsView::resizeEvent(QResizeEvent *event)
|
|
|
|
{
|
|
|
|
if (m_enableFitInView) {
|
|
|
|
if (isThingSmallerThanWindowWith(QTransform()) && transform().m11() >= 1) {
|
|
|
|
// no longer need to do fitInView()
|
|
|
|
// but we leave the m_enableFitInView value unchanged in case
|
|
|
|
// user resize down the window again.
|
|
|
|
} else {
|
|
|
|
fitInView(sceneRect(), Qt::KeepAspectRatio);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return QGraphicsView::resizeEvent(event);
|
|
|
|
}
|
|
|
|
|
2019-09-29 15:52:35 +08:00
|
|
|
void GraphicsView::dragEnterEvent(QDragEnterEvent *event)
|
|
|
|
{
|
|
|
|
if (event->mimeData()->hasUrls() || event->mimeData()->hasImage() || event->mimeData()->hasText()) {
|
|
|
|
event->acceptProposedAction();
|
|
|
|
} else {
|
|
|
|
event->ignore();
|
|
|
|
}
|
|
|
|
qDebug() << event->mimeData() << "Drag Enter Event"
|
|
|
|
<< event->mimeData()->hasUrls() << event->mimeData()->hasImage()
|
|
|
|
<< event->mimeData()->formats() << event->mimeData()->hasFormat("text/uri-list");
|
|
|
|
|
|
|
|
return QGraphicsView::dragEnterEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsView::dragMoveEvent(QDragMoveEvent *event)
|
|
|
|
{
|
|
|
|
Q_UNUSED(event);
|
|
|
|
// by default, QGraphicsView/Scene will ignore the action if there are no QGraphicsItem under cursor.
|
|
|
|
// We actually doesn't care and would like to keep the drag event as-is, so just do nothing here.
|
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsView::dropEvent(QDropEvent *event)
|
|
|
|
{
|
|
|
|
event->acceptProposedAction();
|
|
|
|
|
|
|
|
const QMimeData * mimeData = event->mimeData();
|
|
|
|
|
|
|
|
if (mimeData->hasUrls()) {
|
|
|
|
QUrl url(mimeData->urls().first());
|
|
|
|
QImageReader imageReader(url.toLocalFile());
|
|
|
|
QImage::Format imageFormat = imageReader.imageFormat();
|
|
|
|
if (imageFormat == QImage::Format_Invalid) {
|
|
|
|
showText("File is not a valid image");
|
|
|
|
} else {
|
|
|
|
showImage(QPixmap::fromImageReader(&imageReader));
|
|
|
|
}
|
|
|
|
} else if (mimeData->hasImage()) {
|
|
|
|
QImage img = qvariant_cast<QImage>(mimeData->imageData());
|
|
|
|
QPixmap pixmap = QPixmap::fromImage(img);
|
|
|
|
if (pixmap.isNull()) {
|
|
|
|
showText("Image data is invalid");
|
|
|
|
} else {
|
|
|
|
showImage(pixmap);
|
|
|
|
}
|
|
|
|
} else if (mimeData->hasText()) {
|
|
|
|
showText(mimeData->text());
|
2019-09-29 21:22:20 +08:00
|
|
|
} else {
|
|
|
|
showText("Not supported mimedata: " + mimeData->formats().first());
|
2019-09-29 15:52:35 +08:00
|
|
|
}
|
|
|
|
}
|
2019-09-29 21:22:20 +08:00
|
|
|
|
|
|
|
bool GraphicsView::isThingSmallerThanWindowWith(const QTransform &transform) const
|
|
|
|
{
|
|
|
|
return rect().size().expandedTo(transform.mapRect(sceneRect()).size().toSize())
|
|
|
|
== rect().size();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GraphicsView::shouldIgnoreMousePressMoveEvent(const QMouseEvent *event) const
|
|
|
|
{
|
|
|
|
if (isThingSmallerThanWindowWith(transform())) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
QGraphicsItem *item = itemAt(event->pos());
|
|
|
|
if (!item) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|