123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576 |
- #include "controller.h"
- #include "arbeitsview.h"
- #include "mainwindow.h"
- #include "kmath.h"
- #include <QRubberBand>
- #include <QDebug>
- ArbeitsController *ArbeitsController::controller[ USERMODE_COUNT ];
- // gibt den Controller zurück, welcher in einem Bestimmten Modus verwendet
- // wird
- // m: der Modus, bei dem der gesuchte Controller benutzt wird
- ArbeitsController *ArbeitsController::getController( UserMode m )
- {
- return controller[ m ];
- }
- // Erstellt die Controller, welche bei den verschiedenen Modis benutzt
- // werden sollen
- // m: Das Modell, welches alle nötigen Daten vür die Arbeitsansicht enthält
- void ArbeitsController::initStaticController( ArbeitsModel *m )
- {
- controller[ SELECT ] = new HideController( m );
- controller[ MOVE ] = new MoveController( m );
- controller[ NEW ] = new NewController( m );
- controller[ PIPETTE_SELECT ] = new CopyController( m );
- controller[ PIPETTE_SET ] = new PasteController( m );
- controller[ DELETE ] = new DeleteController( m );
- controller[ CUT ] = new CutController( m );
- controller[ ZOOM_IN ] = new ZoomInController( m );
- }
- ArbeitsController::ArbeitsController( ArbeitsModel *m )
- {
- model = m;
- }
- // Setzt den Controller zurück
- void ArbeitsController::restartController()
- {
- model->notifyViews();
- }
- // verwaltet das drehen des Mausrades
- void ArbeitsController::wheelEvent(QWheelEvent *e)
- {
- if( !model->getFrame() )
- return;
- // Ermitteln der View Größe und der Bildgröße
- QSize s = model->getViewSize();
- QRect imgRect( QPoint( 0, 0 ), s );
- QSize imgS = model->getImage().size();
- if( imgS.width() > s.width() )
- {
- imgS.scale( s, Qt::KeepAspectRatio );
- imgRect.setSize( imgS );
- }
- QPoint bottomRight = model->inverseTranslate( imgRect.bottomRight() );
- int xOffset = model->getXOffset(); // Aktualisieren des aus dem Bild angezeigten gebietes
- int yOffset = model->getYOffset();
- xOffset += (int)( e->angleDelta().y() * (imgRect.width() / 500.0) ) / 2;
- yOffset += (int)( e->angleDelta().y() * (imgRect.height() / 500.0) ) / 2;
- QPoint nBottomRight( bottomRight.x() - (int)( e->angleDelta().y() * (imgRect.width() / 500.0) ) / 2,
- bottomRight.y() - (int)( e->angleDelta().y() * (imgRect.height() / 500.0) ) / 2 );
- if( e->angleDelta().y() > 0 )
- {
- QPoint center( model->getViewPos().x() + model->getViewSize().width() / 2, model->getViewPos().y() + model->getViewSize().height() / 2 );
- QPoint move = e->pos() - center;
- xOffset += move.x();
- yOffset += move.y();
- nBottomRight.setX( nBottomRight.x() + move.x() );
- nBottomRight.setY( nBottomRight.y() + move.y() );
- }
- if( xOffset < 0 )
- {
- nBottomRight.setX( nBottomRight.x() - xOffset );
- xOffset -= xOffset;
- }
- if( yOffset < 0 )
- {
- nBottomRight.setY( nBottomRight.y() - yOffset );
- yOffset -= yOffset;
- }
- if( nBottomRight.x() > model->getImage().width() )
- {
- xOffset -= nBottomRight.x() - model->getImage().width();
- nBottomRight.setX( model->getImage().width() );
- }
- if( nBottomRight.y() > model->getImage().height() )
- {
- yOffset -= nBottomRight.y() - model->getImage().height();
- nBottomRight.setY( model->getImage().height() );
- }
- if( xOffset >= nBottomRight.x() || yOffset >= nBottomRight.y() )
- return; // abbruch
- // Aktualisieren der Sklallierungsfaktoren
- if( xOffset < 0 || yOffset < 0 )
- {
- xOffset = 0;
- yOffset = 0;
- model->setScaleFactor(imgRect.width() / (float)model->getImage().width(), imgRect.height() / (float)model->getImage().height());
- model->notifyViews();
- return;
- }
- model->setScaleFactor( imgRect.width() / (float)(nBottomRight.x() - xOffset), imgRect.height() / (float)(nBottomRight.y() - yOffset));
- model->setOffset( xOffset, yOffset );
- model->notifyViews();
- }
- // verwaltet das Drücken einer Maustaste
- void ArbeitsController::mousePressEvent( QMouseEvent *e )
- {
- model->setMouseButtonPressed( e->button(), e->pos() );
- model->notifyViews();
- }
- // verwaltet das Bewegen der Maus
- void ArbeitsController::mouseMoveEvent( QMouseEvent *e )
- {
- if( model->isMouseButtonPressed( Qt::MidButton ) )
- { // Falls die mittlere Masutaste gedrückt ist, kann der nutzer den angezeigten Bereich des Bildes verschieben
- QPoint diff = e->pos() - model->getMousePoint();
- diff = QPoint( (int)(diff.x() / model->getXScaleFactor()) * 5, (int)(diff.y() / model->getYScaleFactor()) * 5 );
- if( diff != QPoint( 0, 0 ) )
- {
- QSize s = model->getViewSize();
- QRect imgRect( QPoint( 0, 0 ), s );
- QSize imgS = model->getImage().size();
- if( imgS.width() > s.width() )
- {
- imgS.scale( s, Qt::KeepAspectRatio );
- imgRect.setSize( imgS );
- }
- QPoint bottomRight = model->inverseTranslate( imgRect.bottomRight() );
- int xOffset = model->getXOffset(), yOffset = model->getYOffset();
- bottomRight.setX( bottomRight.x() + diff.x() );
- bottomRight.setY( bottomRight.y() + diff.y() );
- xOffset += diff.x();
- yOffset += diff.y();
- if( xOffset < 0 )
- {
- bottomRight.setX( bottomRight.x() - xOffset );
- xOffset -= xOffset;
- }
- if( yOffset < 0 )
- {
- bottomRight.setY( bottomRight.y() - yOffset );
- yOffset -= yOffset;
- }
- if( bottomRight.x() > model->getImage().width() )
- {
- xOffset -= bottomRight.x() - model->getImage().width();
- bottomRight.setX( model->getImage().width() );
- }
- if( bottomRight.y() > model->getImage().height() )
- {
- yOffset -= bottomRight.y() - model->getImage().height();
- bottomRight.setY( model->getImage().height() );
- }
- if( xOffset >= bottomRight.x() || yOffset >= bottomRight.y() )
- return;
- model->setOffset( xOffset, yOffset );
- model->notifyViews();
- }
- }
- model->setMousePoint( e->pos() );
- model->notifyViews();
- }
- // verwaltet das Loslassen einer Maustaste
- void ArbeitsController::mouseReleaseEvent( QMouseEvent *e )
- {
- model->setMousePressed( false );
- model->notifyViews();
- }
- /*
- * Controller für den SELECT Modus
- */
- HideController::HideController( ArbeitsModel *m )
- : ArbeitsController( m )
- {}
- void HideController::mouseReleaseEvent( QMouseEvent *e )
- { // Verstecken oder sichtbarmachen des Objektes, auf das geklickt wurde
- if( model->isMouseButtonPressed( Qt::LeftButton ) && e )
- {
- model->getFrame()->selectObjectAt( model->inverseTranslate( e->pos() ) );
- model->getWindow()->setFrameTreeSelection();
- }
- ArbeitsController::mouseReleaseEvent( e );
- }
- /*
- * Controller für den MOVE Modus
- */
- MoveController::MoveController( ArbeitsModel *m )
- : ArbeitsController( m )
- {}
- void MoveController::mousePressEvent( QMouseEvent *e )
- { // Auswahl des Punktes der verschoben werden soll
- if( e->button() == Qt::LeftButton && !model->getMoveObject().isNull() && model->getInsertIndex() >= 0 )
- {
- model->getMoveObject()->insertVertex( model->getInsertIndex(), model->getNewVertex(), model->getMovePolygon() );
- model->setMoveIndex( model->getInsertIndex() );
- model->setInsertIndex( -1 );
- }
- ArbeitsController::mousePressEvent( e );
- }
- void MoveController::mouseMoveEvent( QMouseEvent *e )
- { // Verschieben des ausgewählten Punktes und findes des der Maus nächstgelegenen Punktes
- if( e )
- {
- if( !model->isMousePressed() )
- { // findes des der Maus nächstgelegenen Punktes
- bool foundNp = false;
- QPoint mousePos = model->inverseTranslate(e->pos());
- double mdiff = 0;
- for( ObjectPolygon obj : model->getFrame()->getObjects() )
- {
- if( obj->isSelected() )
- {
- int pIndex = 0;
- for( QPolygon o : obj->getPolygonList() )
- {
- QPoint last = o.last();
- int index = 0;
- for( QPoint point : o )
- {
- QPoint tmp = Math::getNearestPointOnLine( mousePos, point, last );
- QPoint dir = mousePos - tmp;
- int tmpDiff = dir.x() * dir.x() + dir.y() * dir.y();
- if( !foundNp || tmpDiff < mdiff )
- {
- if( Math::diffSquare( tmp, point ) < 500 )
- {
- model->setMoveObject( obj, pIndex );
- model->setMoveIndex( index );
- model->setInsertIndex( -1 );
- }
- else if( Math::diffSquare( tmp, last ) < 500 )
- {
- model->setMoveObject( obj, pIndex );
- model->setMoveIndex( index - 1 );
- model->setInsertIndex( -1 );
- if( index - 1 < 0 )
- model->setMoveIndex( o.count() - 1 );
- }
- else
- {
- model->setMoveObject( obj, pIndex );
- model->setInsertIndex( index );
- model->setMoveIndex( -1 );
- model->setNewVertex( tmp );
- }
- foundNp = true;
- mdiff = tmpDiff;
- }
- last = point;
- index++;
- }
- pIndex++;
- }
- }
- }
- if( !foundNp || mdiff > 500 )
- {
- model->setInsertIndex( -1 );
- model->setMoveIndex( -1 );
- }
- }
- // move
- if( model->isMouseButtonPressed( Qt::LeftButton ) && model->getMoveIndex() >= 0 && !model->getMoveObject().isNull() )
- {
- model->getMoveObject()->moveVertex( model->getMoveIndex(), model->inverseTranslate( e->pos() ), model->getImage().size(), model->getMovePolygon() );
- }
- }
- ArbeitsController::mouseMoveEvent( e );
- }
- /*
- * Controller für den CUT Modus
- */
- CutController::CutController( ArbeitsModel *m )
- : ArbeitsController( m )
- {}
- void CutController::mouseReleaseEvent( QMouseEvent *e )
- {
- if( model->isMouseButtonPressed( Qt::LeftButton ) && e )
- { // Auswahl der Punkte an denen das Objekt zerschnitten werden soll
- QPoint pos = model->inverseTranslate( e->pos() );
- QList< ObjectPolygon > objects = model->getFrame()->getObjects();
- if( model->getCutObject().isNull() )
- { // Auswahl des ersten Punktes
- for( auto p = objects.begin(); p != objects.end(); p++ )
- {
- int pIndex = 0;
- for( QPolygon pol : (*p)->getPolygonList() )
- {
- int index = 0;
- for( QPoint point : pol )
- {
- if( pos.x() > point.x() - 10 && pos.x() < point.x() + 10 && pos.y() > point.y() - 10 && pos.y() < point.y() + 10 )
- {
- model->setCutObject( *p, pIndex );
- model->setCutIndex( index );
- }
- index++;
- }
- if( !model->getCutObject().isNull() )
- break;
- pIndex++;
- }
- }
- }
- else
- { // Auswahl des zweiten Punktes
- if( !model->getCutObject().isNull() && model->getFrame() )
- {
- int index = 0;
- foreach( QPoint point, model->getCutObject()->getPolygonList().at( model->getCutPolygon() ) )
- {
- if( pos.x() > point.x() - 10 && pos.x() < point.x() + 10 && pos.y() > point.y() - 10 && pos.y() < point.y() + 10 )
- break;
- index++;
- }
- if( index >= model->getCutIndex() - 1 && index <= model->getCutIndex() + 1 )
- return;
- if( ( model->getCutIndex() == 0 && index == model->getCutObject()->getPolygonList().at( model->getCutPolygon() ).size() - 1 ) ||
- ( index == 0 && model->getCutIndex() == model->getCutObject()->getPolygonList().at( model->getCutPolygon() ).size() - 1 ) ||
- index == model->getCutObject()->getPolygonList().at( model->getCutPolygon() ).size() )
- return;
- // Zerschneiden des Objektes an den zwei eckpunkten
- model->getFrame()->splitObject( model->getCutObject(), model->getCutIndex(), index, model->getCutPolygon() );
- model->setCutObject( ObjectPolygon(), 0 );
- model->setCutIndex( -1 );
- model->getWindow()->setupFrameTree();
- }
- }
- }
- ArbeitsController::mouseReleaseEvent( e );
- }
- /*
- * Controller für den PIPETTE_SELECT Modus
- */
- CopyController::CopyController( ArbeitsModel *m )
- : ArbeitsController( m )
- {}
- void CopyController::mouseReleaseEvent( QMouseEvent *e )
- { // Auswahl des Objektes, welches kopiert werden soll
- if( model->isMouseButtonPressed( Qt::LeftButton ) && e )
- {
- if( model->getFrame() )
- {
- int pIndex;
- model->setCopyedObject( model->getFrame()->getObjectAt( model->inverseTranslate( e->pos() ), pIndex ), model->inverseTranslate( e->pos() ) );
- model->setCopyedRotation( 0 );
- if( !model->getCopyedObject().isNull() )
- model->getWindow()->setMode( PIPETTE_SET );
- }
- }
- ArbeitsController::mouseReleaseEvent( e );
- }
- /*
- * Controller für den PIPETTE_SET Modus
- */
- PasteController::PasteController( ArbeitsModel *m )
- : ArbeitsController( m )
- {}
- void PasteController::mouseMoveEvent( QMouseEvent *e )
- { // Setzen der Position und der Rotierung des kopierten Objektes
- if( model->isMouseButtonPressed( Qt::RightButton ) )
- {
- if( !model->getCopyedObject().isNull() )
- model->setCopyedRotation( model->getCopyedRotation() + e->pos().x() - model->getMousePoint().x() );
- }
- ArbeitsController::mouseMoveEvent( e );
- }
- void PasteController::mouseReleaseEvent( QMouseEvent *e )
- { // Einfpgen des Objektes oder der Objekt-ID
- if( model->isMouseButtonPressed( Qt::LeftButton ) && e )
- {
- if( model->getFrame() )
- {
- model->getFrame()->setObjectAt( model->inverseTranslate( e->pos() ), model->getCopyedObject(), model->getCopyedCenter(), model->getCopyedRotation() );
- model->getWindow()->setupFrameTree();
- int pIndex;
- model->setCopyedObject( model->getFrame()->getObjectAt( model->inverseTranslate( e->pos() ), pIndex ), model->inverseTranslate( e->pos() ) );
- model->setCopyedRotation( 0 );
- }
- }
- ArbeitsController::mouseReleaseEvent( e );
- }
- /*
- * Controller für den NEW Modus
- */
- NewController::NewController( ArbeitsModel *m )
- : ArbeitsController( m )
- {}
- void NewController::mouseReleaseEvent( QMouseEvent *e )
- {
- if( model->isMouseButtonPressed( Qt::LeftButton ) && e )
- { // Hinzufügen von Punkten zum neuen Polygon
- if( !model->getNewPolygon() )
- model->setNewPolygon( new QPolygon() );
- QPoint pos = model->inverseTranslate( e->pos() );
- if( model->getNewPolygon()->size() > 3 &&
- pos.x() > model->getNewPolygon()->begin()->x() - 10 && pos.x() < model->getNewPolygon()->begin()->x() + 10 &&
- pos.y() > model->getNewPolygon()->begin()->y() - 10 && pos.y() < model->getNewPolygon()->begin()->y() + 10 )
- { // Polygon ist fertig und wird zur Sequenz hinzugefügt
- QList<QPolygon> polygons;
- polygons.append( *model->getNewPolygon() );
- if( model->getFrame() )
- model->getFrame()->addObject( "-1", 0, polygons );
- model->setNewPolygon( 0 );
- model->getWindow()->setupFrameTree();
- }
- else
- model->getNewPolygon()->append( pos );
- }
- if( model->isMouseButtonPressed( Qt::RightButton ) && e )
- { // Letzten Punkt vom Polygon entfernen
- if( model->getNewPolygon() )
- {
- if( model->getNewPolygon()->size() == 1 )
- model->setNewPolygon( 0 );
- else
- model->getNewPolygon()->pop_back();
- }
- }
- ArbeitsController::mouseReleaseEvent( e );
- }
- void NewController::restartController()
- { // Neues Polygon beenden und zur Sequenz hinzufügen
- if( model->getNewPolygon() && model->getNewPolygon()->size() >= 3 )
- {
- QList<QPolygon> polygons;
- polygons.append( *model->getNewPolygon() );
- model->getFrame()->addObject( "-1", 0, polygons );
- model->setNewPolygon( 0 );
- model->getWindow()->setupFrameTree();
- ArbeitsController::restartController();
- }
- }
- /*
- * Controller für den DELETE Modus
- */
- DeleteController::DeleteController( ArbeitsModel *m )
- : ArbeitsController( m )
- {}
- void DeleteController::mousePressEvent( QMouseEvent *e )
- { // Setzt den Beginn des auswahl feldes
- if( e && e->button() == Qt::LeftButton )
- {
- if (!model->getDeleteField() )
- model->setDeleteField( new QRect(e->pos(), QSize()) );
- }
- ArbeitsController::mousePressEvent( e );
- }
- void DeleteController::mouseMoveEvent( QMouseEvent *e )
- { // Setze das Ende des Auswahl Feldes
- if( e && model->isMouseButtonPressed( Qt::LeftButton ) && model->getDeleteField() )
- {
- *model->getDeleteField() = QRect( model->getMousePressPoint(), e->pos() ).normalized();
- }
- ArbeitsController::mouseMoveEvent( e );
- }
- void DeleteController::mouseReleaseEvent( QMouseEvent *e )
- { // Lösche alle Eckpunkte im ausgewählten Feld
- if( model->isMouseButtonPressed( Qt::LeftButton ) && e && model->getDeleteField() && model->getFrame() )
- {
- if( model->getDeleteField()->size() == QSize( 0, 0 ) )
- model->getFrame()->selectObjectAt( model->inverseTranslate( e->pos() ) );
- else
- {
- QRect field = *model->getDeleteField();
- model->getFrame()->removeSelectedVertices(QRect( model->inverseTranslate( field.topLeft() ), model->inverseTranslate( field.bottomRight() ) ));
- delete model->getDeleteField();
- model->setDeleteField( 0 );
- model->getWindow()->setupFrameTree();
- }
- }
- ArbeitsController::mouseReleaseEvent( e );
- }
- /*
- * Controller für den ZOOM_IN Modus
- */
- ZoomInController::ZoomInController( ArbeitsModel *m )
- : ArbeitsController( m )
- {}
- void ZoomInController::mousePressEvent( QMouseEvent *e )
- { // Setzte den Startpunkt des sichtbaren Gebiets
- if( e->button() == Qt::LeftButton )
- {
- if (!model->getDeleteField() )
- model->setDeleteField( new QRect(e->pos(), QSize()) );
- }
- ArbeitsController::mousePressEvent( e );
- }
- void ZoomInController::mouseMoveEvent( QMouseEvent *e )
- { // Setzte den Endpunkt des sichtbaren Gebiets
- if( model->isMouseButtonPressed( Qt::LeftButton ) && model->getDeleteField() && e )
- {
- *model->getDeleteField() = QRect( model->getMousePressPoint(), e->pos() ).normalized();
- }
- ArbeitsController::mouseMoveEvent( e );
- }
- void ZoomInController::mouseReleaseEvent( QMouseEvent *e )
- { // Aktualisiere die Ansicht auf das ausgewählte Gebiet
- if( model->isMouseButtonPressed( Qt::LeftButton ) && e && model->getFrame() && model->getDeleteField() )
- {
- if( model->getDeleteField()->size() == QSize( 0, 0 ) )
- model->getFrame()->selectObjectAt( model->inverseTranslate( e->pos() ) );
- else
- {
- QRect field = *model->getDeleteField();
- QPoint leftTop = model->inverseTranslate( field.topLeft() );
- int xOffset = leftTop.x(), yOffset = leftTop.y();
- if( xOffset < 0 )
- xOffset = 0;
- if( yOffset < 0 )
- yOffset = 0;
- QPoint bottomRight = model->inverseTranslate( field.bottomRight() );
- if( bottomRight.x() >= model->getImage().width() )
- bottomRight.setX( model->getImage().width() );
- if( bottomRight.y() >= model->getImage().height() )
- bottomRight.setY( model->getImage().height() );
- if( bottomRight.x() > xOffset && bottomRight.y() > yOffset )
- {
- QSize s = model->getViewSize();
- QRect imgRect( QPoint( 0, 0 ), s );
- QSize imgS = model->getImage().size();
- if( imgS.width() > s.width() )
- {
- imgS.scale( s, Qt::KeepAspectRatio );
- imgRect.setSize( imgS );
- }
- model->setScaleFactor( imgRect.width() / (float)(bottomRight.x() - xOffset), imgRect.height() / (float)(bottomRight.y() - yOffset));
- model->setOffset( xOffset, yOffset );
- }
- delete model->getDeleteField();
- model->setDeleteField( 0 );
- model->getWindow()->setupFrameTree();
- }
- }
- ArbeitsController::mouseReleaseEvent( e );
- }
|