You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

443 lines
11 KiB
C++

#include "DrawTool.h"
#include "RoiItem.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <QGraphicsLineItem>
#include <QtMath>
#define PI 3.14
QList<DrawTool*> DrawTool::c_tools;
QPointF DrawTool::c_down;
QPointF DrawTool::c_last;
quint32 DrawTool::c_nDownFlags;
int DrawTool::c_rgb = -1;
DrawShape DrawTool::c_drawShape = selection;
static SelectTool selectTool;
static RectTool lineTool(line);
static RectTool rectTool(rectangle);
static RectTool roundRectTool(roundrect);
static RectTool circleTool(circle);
static RectTool ellipseTool(ellipse);
static RectTool polyTool(poly);
enum SelectMode
{
none,
netSelect,
move,
size,
rotate
};
SelectMode selectMode = none;
SizeHandleRect::Direction nDragHandle = SizeHandleRect::None;
static void setCursor(QGraphicsScene * scene, const QCursor & cursor)
{
QList<QGraphicsView*> views = scene->views();
for (int i = 0; i < views.count(); i++)
{
QGraphicsView * view = views.at(i);
if (view && (int)view->userData(0) == 1)
view->setCursor(cursor);
}
}
DrawTool::DrawTool(DrawShape shape)
{
m_drawShape = shape;
c_tools.push_back(this);
}
void DrawTool::mousePressEvent(QGraphicsSceneMouseEvent *event, RoiScene *scene)
{
QList<QGraphicsItem *> items = scene->selectedItems();
c_down = event->scenePos();
//if (scene->flag)
// c_last = event->scenePos();
}
void DrawTool::mouseMoveEvent(QGraphicsSceneMouseEvent *event, RoiScene *scene)
{
if (!event || !scene)
return;
if (scene->flag)
{
QPointF centerPoint = scene->getCenterPoint();
QPointF startPoint = scene->getStartPoint();
float alpha = -cacuAngle(startPoint, event->scenePos());
float beta = -cacuAngle(centerPoint, startPoint);
float diffAngle = alpha - beta;
float disO2F = disOfPoint(startPoint, event->scenePos());
float dis = cosf(diffAngle * PI / 180)*disO2F;
float dx = cosf(beta * PI / 180) * dis;
float dy = sinf(beta * PI / 180) * dis;
QPointF newPoint(startPoint.x() + dx, startPoint.y() + dy);
QRectF newRect = scene->sceneRect();
if (!newRect.contains(newPoint)){
newPoint.setX(qMin(newRect.right(), qMax(newPoint.x(), newRect.left())));
newPoint.setY(qMin(newRect.bottom(), qMax(newPoint.y(), newRect.top())));
}
c_last = newPoint;
event->setPos(c_last);
}
else
{
c_last = event->scenePos();
}
}
float DrawTool::disOfPoint(QPointF startP, QPointF endP)
{
float dx = startP.x() - endP.x();
float dy = startP.y() - endP.y();
return (float)sqrtf(dx*dx + dy*dy);
}
void DrawTool::mouseReleaseEvent(QGraphicsSceneMouseEvent *event, RoiScene *scene)
{
if (!event || !scene)
return;
if (event->scenePos() == c_down)
c_drawShape = selection;
setCursor(scene, Qt::ArrowCursor);
if (scene->flag)
{
QPointF centerPoint = scene->getCenterPoint();
QPointF startPoint = scene->getStartPoint();
float alpha = -cacuAngle(startPoint, event->scenePos());
float beta = -cacuAngle(centerPoint, startPoint);
float diffAngle = alpha - beta;
float disO2F = disOfPoint(startPoint, event->scenePos());
float dis = cosf(diffAngle * PI / 180)*disO2F;
float dx = cosf(beta * PI / 180) * dis;
float dy = sinf(beta * PI / 180) * dis;
QPointF newPoint(startPoint.x() + dx, startPoint.y() + dy);
QRectF newRect = scene->sceneRect();
if (!newRect.contains(newPoint)){
newPoint.setX(qMin(newRect.right(), qMax(newPoint.x(), newRect.left())));
newPoint.setY(qMin(newRect.bottom(), qMax(newPoint.y(), newRect.top())));
}
c_last = newPoint;
event->setPos(c_last);
}
else
{
c_last = event->scenePos();
}
}
DrawTool *DrawTool::findTool(DrawShape drawShape)
{
QList<DrawTool*>::const_iterator iter = c_tools.constBegin();
for (; iter != c_tools.constEnd(); ++iter){
if ((*iter)->m_drawShape == drawShape)
return (*iter);
}
return 0;
}
SelectTool::SelectTool()
:DrawTool(selection)
{
m_lastSize.setHeight(0);
m_lastSize.setWidth(0);
dashRect = 0;
// dashLine = 0;
m_hoverSizer = false;
}
void SelectTool::mousePressEvent(QGraphicsSceneMouseEvent *event, RoiScene *scene)
{
if (!event || !scene)
return;
if (!m_hoverSizer)
scene->mouseEvent(event);
selectMode = none;
QList<QGraphicsItem *> items = scene->selectedItems();
GraphicsItem *item = 0;
if (items.count() == 1)
{
item = qgraphicsitem_cast<GraphicsItem*>(items.first());
}
if (item != 0){
nDragHandle = item->hitTest(event->scenePos());
if (nDragHandle != SizeHandleRect::None)
selectMode = size;
else
selectMode = move;
m_lastSize = item->boundingRect().size();
if (scene->flag)
item->setPos(c_last);
}
if (selectMode == none){
selectMode = netSelect;
QList<QGraphicsView*> views = scene->views();
if (views.count() > 0){
QGraphicsView * view = views.first();
view->setDragMode(QGraphicsView::RubberBandDrag);
}
}
if (selectMode == move && items.count() == 1){
if (dashRect){
scene->removeItem(dashRect);
delete dashRect;
dashRect = 0;
}
dashRect = new QGraphicsPathItem(item->shape());
int rgb = SystemStateInfo::rgb;
dashRect->setPen(QPen(QColor(qRed(abs(255-rgb)), qGreen(abs(255-rgb)), qBlue(abs(255-rgb))), 3, Qt::DashLine, Qt::FlatCap, Qt::MiterJoin));
dashRect->setPos(item->pos());
dashRect->setTransformOriginPoint(item->transformOriginPoint());
dashRect->setTransform(item->transform());
dashRect->setRotation(item->rotation());
scene->addItem(dashRect);
}
DrawTool::mousePressEvent(event, scene);
}
void SelectTool::mouseMoveEvent(QGraphicsSceneMouseEvent *event, RoiScene *scene)
{
if (!event || !scene)
return;
bool isGroup = false;
QList<QGraphicsItem *> items = scene->selectedItems();
GraphicsItem * item = 0;
if (items.count() == 1){
item = qgraphicsitem_cast<GraphicsItem*>(items.first());
if (item != 0)
{
if (nDragHandle != SizeHandleRect::None && selectMode == size){
QSizeF delta(c_last.x() - c_down.x(), c_last.y() - c_down.y());
item->resizeTo(nDragHandle, c_last);
}
else if (nDragHandle == SizeHandleRect::None && selectMode == selection){
SizeHandleRect::Direction handle = item->hitTest(event->scenePos());
if (handle != SizeHandleRect::None){
setCursor(scene, item->getCursor(handle));
m_hoverSizer = true;
}
else{
setCursor(scene, Qt::ArrowCursor);
m_hoverSizer = false;
}
}
}
if (scene->flag)
{
QPointF centerPoint = scene->getCenterPoint();
QPointF startPoint = scene->getStartPoint();
float alpha = -cacuAngle(startPoint, event->scenePos());
float beta = -cacuAngle(centerPoint, startPoint);
float diffAngle = alpha - beta;
float disO2F = disOfPoint(startPoint, event->scenePos());
float dis = cosf(diffAngle * PI / 180)*disO2F;
float dx = cosf(beta * PI / 180) * dis;
float dy = sinf(beta * PI / 180) * dis;
QPointF newPoint(startPoint.x() + dx, startPoint.y() + dy);
QRectF newRect = scene->sceneRect();
if (!newRect.contains(newPoint)){
newPoint.setX(qMin(newRect.right(), qMax(newPoint.x(), newRect.left())));
newPoint.setY(qMin(newRect.bottom(), qMax(newPoint.y(), newRect.top())));
}
c_last = newPoint;
item->setPos(c_last);
}
if (selectMode == move){
if (dashRect){
dashRect->setPos(item->pos());
}
}
}
if ((selectMode != size && items.count() > 0)/* || isGroup*/)
{
scene->mouseEvent(event);
}
DrawTool::mouseMoveEvent(event, scene);
}
void SelectTool::mouseReleaseEvent(QGraphicsSceneMouseEvent *event, RoiScene *scene)
{
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1){
GraphicsItem * item = qgraphicsitem_cast<GraphicsItem*>(items.first());
if (item != 0 && selectMode == move/* && c_last != c_down*/){
item->pos();
if (scene->flag)
{
item->setPos(c_last);
}
}
}
if (selectMode == netSelect){
QList<QGraphicsView*> views = scene->views();
if (views.count() > 0){
QGraphicsView * view = views.first();
view->setDragMode(QGraphicsView::NoDrag);
}
}
if (dashRect){
scene->removeItem(dashRect);
delete dashRect;
dashRect = 0;
}
selectMode = none;
nDragHandle = SizeHandleRect::None;
m_hoverSizer = false;
scene->mouseEvent(event);
DrawTool::mouseReleaseEvent(event, scene);
}
RectTool::RectTool(DrawShape drawShape)
:DrawTool(drawShape)
{
}
void RectTool::mousePressEvent(QGraphicsSceneMouseEvent *event, RoiScene *scene)
{
scene->clearSelection();
switch (c_drawShape){
case rectangle:
item = new GraphicsRectItem(QRect(0, 0, 0, 0), NULL);
item->SetColor(SystemStateInfo::rgb);
item->SetType(GraphicsRect);
item->setPen(Qt::NoPen);
item->setZValue(1);
item->setData(0, LP_DETECTOR_INVALID_ID);
item->setData(1, LP_DETECTOR_INVALID_ID);
break;
case ellipse:
item = new GraphicsEllipseItem(QRect(0, 0, 0, 0), NULL);
item->SetColor(SystemStateInfo::rgb);
item->SetType(GraphicsEllipse);
item->setPen(Qt::NoPen);
item->setZValue(1);
item->setData(0, LP_DETECTOR_INVALID_ID);
item->setData(1, LP_DETECTOR_INVALID_ID);
break;
case circle:
item = new GraphicsEllipseItem(QRect(0, 0, 0, 0), NULL);
item->SetColor(SystemStateInfo::rgb);
item->SetType(GraphicsCircle);
item->setPen(Qt::NoPen);
item->setZValue(1);
item->setData(0, LP_DETECTOR_INVALID_ID);
item->setData(1, LP_DETECTOR_INVALID_ID);
break;
}
if (item == 0)
return;
item->setPos(event->scenePos());
scene->addItem(item);
item->setSelected(true);
selectMode = size;
nDragHandle = SizeHandleRect::RightBottom;
DrawTool::mousePressEvent(event, scene);
}
void RectTool::mouseMoveEvent(QGraphicsSceneMouseEvent *event, RoiScene *scene)
{
setCursor(scene, Qt::CrossCursor);
selectTool.mouseMoveEvent(event, scene);
}
void RectTool::mouseReleaseEvent(QGraphicsSceneMouseEvent *event, RoiScene *scene)
{
if (event->scenePos() == c_down){
if (item != 0)
scene->removeItem(item);
//selectTool.mousePressEvent(event, scene);
}
c_drawShape = selection;
selectTool.mouseReleaseEvent(event, scene);
}
float DrawTool::cacuAngle(QPointF pCenter, QPointF pTarget)
{
float fAngle;
float dTempAngle;
if (abs(pCenter.x() - pTarget.x()) < 0.01)
{
if (pCenter.y() > pTarget.y())
{
fAngle = 90.0;
}
else
fAngle = 270.0;
}
else
{
// |
// 二 | 一
// ----------
// 三 | 四
// |
//图像 Y上 小于 Y下
// X左 小于 X右
//-pi/2~~~~~pi/2
dTempAngle = atan((double)(pCenter.y() - pTarget.y()) / (pTarget.x() - pCenter.x()));
if (pCenter.x() > pTarget.x())//二三
{
if (pCenter.y() > pTarget.y())
{
//第二象限
//temp_angle += CV_PI;
dTempAngle = CV_PI + dTempAngle;
}
else
{
//第三
dTempAngle = CV_PI + dTempAngle;
}
}
else//一si
{
if (pCenter.y() >= pTarget.y())
{
//yi
//temp_angle = 2 * CV_PI - temp_angle;
}
else
{
//si
dTempAngle = 2 * CV_PI + dTempAngle;
}
}
fAngle = dTempAngle * 180.0 / CV_PI;
}
return fAngle;
}