/* dtkComposerCompass.cpp --- * * Author: Julien Wintz * Copyright (C) 2008-2011 - Julien Wintz, Inria. * Created: Wed Apr 18 09:37:07 2012 (+0200) * Version: $Id: 9b06b0d1dec0c190545fc0bb4836e2facc5dd62e $ * Last-Updated: Thu Apr 19 13:16:55 2012 (+0200) * By: tkloczko * Update #: 344 */ /* Commentary: * */ /* Change log: * */ #include "dtkComposerCompass.h" #include "dtkComposerView.h" // ///////////////////////////////////////////////////////////////// // Helper functions // ///////////////////////////////////////////////////////////////// QRect toRect(QPolygon polygon) { if (polygon.size() != 4) return QRect(); return QRect(polygon.first(), polygon.at(2)); } QRect toRect(QPolygonF polygon) { return toRect(polygon.toPolygon()); } // ///////////////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////////////// class dtkComposerCompassPrivate { public: dtkComposerView *view; public: QRect c_rect; // crop QRect s_rect; // source QRect t_rect; // target public: QPoint pos; public: bool moving; }; // ///////////////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////////////// dtkComposerCompass::dtkComposerCompass(QWidget *parent) : QGraphicsView(parent), d(new dtkComposerCompassPrivate) { d->view = NULL; this->setAttribute(Qt::WA_MacShowFocusRect, false); this->setBackgroundBrush(QColor(0xc5, 0xc5, 0xc5)); this->setFrameStyle(QFrame::NoFrame); this->setInteractive(false); this->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); this->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); d->moving = false; } dtkComposerCompass::~dtkComposerCompass(void) { delete d; d = NULL; } void dtkComposerCompass::setView(dtkComposerView *view) { d->view = view; connect(d->view, SIGNAL(scrolled()), this, SLOT(update())); } void dtkComposerCompass::update(void) { this->scene()->update(); QGraphicsView::update(); } #define CROP_BORDER_LINE 10 #define CROP_GRID_SIZE 3 void dtkComposerCompass::paintEvent(QPaintEvent *event) { if (!d->view) return; if (event->rect().width() < 20 || event->rect().height() < 20) return; bool fit = false; if (d->s_rect != d->view->sceneRect().toRect()) { d->s_rect = d->view->sceneRect().toRect(); fit = true; } if (d->t_rect != event->rect()) { d->t_rect = event->rect(); fit = true; } if (fit && (d->s_rect.width() > d->t_rect.width() || d->s_rect.height() > d->t_rect.height())) this->fitInView(this->scene()->sceneRect(), Qt::KeepAspectRatio); // -- QGraphicsView::paintEvent(event); // -- Map source view to target view through scene d->c_rect = toRect(d->view->mapToScene(d->view->rect())); d->c_rect = toRect(this->mapFromScene(d->c_rect)); // -- if (d->c_rect.contains(d->t_rect)) return; // -- QPainterPath cropPath; cropPath.addRect(d->c_rect); QPainterPath windowPath; windowPath.addRect(d->t_rect); windowPath -= cropPath; QPainter painter(this->viewport()); painter.setRenderHints(QPainter::Antialiasing); // Draw Alpha-Black Background. painter.fillPath(windowPath, QColor(0x83, 0x83, 0x83, 0x77)); // Draw Crop Rect painter.setPen(QPen(QColor(0xdd, 0xdd, 0xdd), 1)); painter.drawPath(cropPath); // -- int topRightX = d->c_rect.x() + d->c_rect.width(); int bottomY = d->c_rect.y() + d->c_rect.height(); qreal f = 1.0f / CROP_GRID_SIZE; qreal hsize = d->c_rect.height() * f; qreal wsize = d->c_rect.width() * f; QPainterPath gridPath; for (uint i = 1; i < CROP_GRID_SIZE; ++i) { qreal y = d->c_rect.y() + i * hsize; gridPath.moveTo(d->c_rect.x(), y); gridPath.lineTo(topRightX, y); for (uint j = 1; j < CROP_GRID_SIZE; ++j) { qreal x = d->c_rect.x() + j * wsize; gridPath.moveTo(x, d->c_rect.y()); gridPath.lineTo(x, bottomY); } } // Draw Grid Path painter.setPen(QPen(QColor(0x99, 0x99, 0x99, 0x80), 1)); painter.drawPath(gridPath); // -- QPainterPath borderPath; // Top-Left Corner borderPath.moveTo(d->c_rect.x(), d->c_rect.y()); borderPath.lineTo(d->c_rect.x() + CROP_BORDER_LINE, d->c_rect.y()); borderPath.moveTo(d->c_rect.x(), d->c_rect.y()); borderPath.lineTo(d->c_rect.x(), d->c_rect.y() + CROP_BORDER_LINE); // Top-Right Corner borderPath.moveTo(topRightX - CROP_BORDER_LINE, d->c_rect.y()); borderPath.lineTo(topRightX, d->c_rect.y()); borderPath.moveTo(topRightX, d->c_rect.y()); borderPath.lineTo(topRightX, d->c_rect.y() + CROP_BORDER_LINE); // Bottom-Left Corner borderPath.moveTo(d->c_rect.x(), bottomY); borderPath.lineTo(d->c_rect.x() + CROP_BORDER_LINE, bottomY); borderPath.moveTo(d->c_rect.x(), bottomY - CROP_BORDER_LINE); borderPath.lineTo(d->c_rect.x(), bottomY); // Bottom-Left Corner borderPath.moveTo(topRightX, bottomY); borderPath.lineTo(topRightX - CROP_BORDER_LINE, bottomY); borderPath.moveTo(topRightX, bottomY - CROP_BORDER_LINE); borderPath.lineTo(topRightX, bottomY); // Draw Border Path painter.setPen(QPen(QColor(0xee, 0xee, 0xee), 3)); painter.drawPath(borderPath); } void dtkComposerCompass::mousePressEvent(QMouseEvent *event) { if (d->c_rect.contains(event->pos())) d->moving = true; } void dtkComposerCompass::mouseMoveEvent(QMouseEvent *event) { if (d->moving) { QPoint c = this->mapToScene(event->pos()).toPoint(); QPoint p = this->mapToScene(d->pos).toPoint(); QPoint delta = c - p; d->view->scroll(delta.x(), delta.y()); } d->pos = event->pos(); } void dtkComposerCompass::mouseReleaseEvent(QMouseEvent *event) { Q_UNUSED(event); d->moving = false; }