/****************************************************************************
Copyright (C) 2010-2012 AMVALOR, France. All rights reserved.
Contact : micha.krebs@gmail.com
Developers : Michaƫl KREBS (AMVALOR)
This file is part of AMKgl
Computree is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Computree is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Amkgl. If not, see .
*****************************************************************************/
#include "rectangleforpicking.h"
#include
#include
#include "actions/tools/math.h"
#define MIN_DISTANCE 5
namespace AMKgl {
RectangleForPicking::RectangleForPicking()
{
m_moveWhat = MoveNone;
m_pointToMoveIndex = -1;
m_authorizeMouseInteractionWithViewWhenPicking = false;
}
void RectangleForPicking::clear()
{
m_polygon.clear();
m_pointToMoveIndex = -1;
m_moveWhat = MoveNone;
emit polygonChanged();
redrawOverlay();
}
void RectangleForPicking::setRectangle(const QRect &r)
{
m_polygon = QPolygon(r);
m_pointToMoveIndex = -1;
m_moveWhat = MoveNone;
emit polygonChanged();
redrawOverlay();
}
const QPolygon& RectangleForPicking::getPolygon() const
{
return m_polygon;
}
bool RectangleForPicking::mousePressEvent(QMouseEvent *e)
{
if(e->button() == Qt::LeftButton) {
if(m_polygon.isEmpty()) {
QPoint pos = e->pos();
m_polygon.append(pos);
m_polygon.append(QPoint(pos.x()+1, pos.y()));
m_polygon.append(QPoint(pos.x()+1, pos.y()+1));
m_polygon.append(QPoint(pos.x(), pos.y()+1));
m_moveWhat = MovePointOfPolygon;
m_pointToMoveIndex = 2;
redrawOverlay();
} else {
double dist;
int index;
Math::getClosestPolygonPointToPoint(m_polygon, m_mousePos, dist, &index);
if(dist < MIN_DISTANCE) {
m_moveWhat = MovePointOfPolygon;
m_pointToMoveIndex = index;
if(isMouseInteractionWithViewAuthorizedWhenPickingIsEnabled())
return true;
} else if(isMousePosInPolygon()) {
m_moveWhat = MovePolygon;
m_originPolygon = m_polygon;
m_originPointMove = e->pos();
return true;
}
}
}
if(isMouseInteractionWithViewAuthorizedWhenPickingIsEnabled())
return false;
return true;
}
bool RectangleForPicking::mouseMoveEvent(QMouseEvent *e)
{
Q_UNUSED(e)
m_mousePos = e->pos();
if(m_moveWhat == MovePointOfPolygon) {
if((m_pointToMoveIndex == 0) || (m_pointToMoveIndex == 3)) {
if(e->pos().x() < m_polygon.at(1).x()) {
m_polygon[0].setX(e->pos().x());
m_polygon[3].setX(e->pos().x());
}
} else if(m_pointToMoveIndex != -1) {
if(e->pos().x() > m_polygon.at(0).x()) {
m_polygon[1].setX(e->pos().x());
m_polygon[2].setX(e->pos().x());
}
}
if((m_pointToMoveIndex == 0) || (m_pointToMoveIndex == 1)) {
if(e->pos().y() < m_polygon.at(3).y()) {
m_polygon[0].setY(e->pos().y());
m_polygon[1].setY(e->pos().y());
}
} else if(m_pointToMoveIndex != -1) {
if(e->pos().y() > m_polygon.at(0).y()) {
m_polygon[3].setY(e->pos().y());
m_polygon[2].setY(e->pos().y());
}
}
redrawOverlay();
if(m_pointToMoveIndex != -1)
return true;
} else if(m_moveWhat == MovePolygon) {
m_polygon = m_originPolygon;
m_polygon.translate(e->pos() - m_originPointMove);
emit polygonChanged();
redrawOverlay();
return true;
}
redrawOverlay();
if(isMouseInteractionWithViewAuthorizedWhenPickingIsEnabled())
return false;
return true;
}
bool RectangleForPicking::mouseReleaseEvent(QMouseEvent *e)
{
if(e->button() == Qt::LeftButton) {
m_moveWhat = MoveNone;
m_pointToMoveIndex = -1;
}
return false;
}
bool RectangleForPicking::mouseDoubleClickEvent(QMouseEvent *e)
{
Q_UNUSED(e)
return false;
}
bool RectangleForPicking::wheelEvent(QWheelEvent *e)
{
Q_UNUSED(e)
if(isMouseInteractionWithViewAuthorizedWhenPickingIsEnabled())
return false;
return true;
}
bool RectangleForPicking::keyPressEvent(QKeyEvent *e)
{
Q_UNUSED(e)
return false;
}
bool RectangleForPicking::keyReleaseEvent(QKeyEvent *e)
{
Q_UNUSED(e)
return false;
}
void RectangleForPicking::drawOverlay(QPainter &painter)
{
painter.save();
// draw just lines of the polygon
painter.setPen(createPenToUse(Qt::blue));
painter.setBrush(QColor(0, 0, 255, 50));
drawPolygon(m_polygon, painter);
double dist = 0;
QPoint p;
if(m_pointToMoveIndex != -1)
p = m_polygon.at(m_pointToMoveIndex);
else
p = Math::getClosestPolygonPointToPoint(m_polygon, m_mousePos, dist);
if(dist < MIN_DISTANCE) {
painter.setPen(createPenToUse(Qt::yellow));
painter.setBrush(Qt::yellow);
painter.drawEllipse(p, 5, 5);
painter.setPen(createPenToUse(Qt::red));
painter.setBrush(Qt::red);
painter.drawEllipse(p, 1, 1);
} else if(isMousePosInPolygon()) {
painter.setPen(createPenToUse(Qt::yellow));
painter.setBrush(QBrush());
drawPolygon(m_polygon, painter);
}
painter.restore();
}
bool RectangleForPicking::isMouseInteractionWithViewAuthorizedWhenPickingIsEnabled() const
{
return m_authorizeMouseInteractionWithViewWhenPicking;
}
void RectangleForPicking::drawPolygon(const QPolygon &pol, QPainter &painter)
{
painter.drawPolygon(pol);
}
bool RectangleForPicking::isMousePosInPolygon() const
{
return Math::isPointInPolygon(m_polygon, m_mousePos);
}
void RectangleForPicking::redrawOverlay()
{
emit mustBeRedraw();
}
QPen RectangleForPicking::createPenToUse(const QColor &color)
{
return QPen(QBrush(color), 1);
}
}