/*************************************************************************** * Copyright (C) 2008 by Peter Dahlberg * * pdahlberg@gmail.com * * * * This program 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 2 of the License, or * * (at your option) any later version. * * * * This program 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 this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "constants.h" #include "simulscene.h" #include #include #include #include #include "graphicsellipseitem.h" #include "homoefielditem.h" #include "homobfielditem.h" #include "stopperitem.h" #include #include #include #include #include #include #include #include #include #include #include SimulScene::SimulScene ( QObject* parent ) : QGraphicsScene ( parent ) { fieldListWidget = new QListWidget(); currHomoEfieldInsertItem = 0; currHomoEfieldEditItem = 0; currHomoBfieldInsertItem = 0; currHomoBfieldEditItem = 0; currStopperInsertItem = 0; currStopperEditItem = 0; ChargePlacementInProgress = false; createResizeRects(); //path Item Erstellen pathItem1 = addPath(QPainterPath(), QPen(QColor(255,137,11), 1, Qt::SolidLine)); pathItem1->setZValue(100); //pathItem1->setCacheMode(QGraphicsItem::DeviceCoordinateCache); setFlightPathVisible(); /*addLine(0,-298,0,298,QPen(Qt::green, 1, Qt::SolidLine) )->setCacheMode(QGraphicsItem::DeviceCoordinateCache); addLine(-398,0,398,0,QPen(Qt::green, 1, Qt::SolidLine) )->setCacheMode(QGraphicsItem::DeviceCoordinateCache); for (int i = -39; i< 39; ++i) { if(i!=0) { QGraphicsLineItem *line = addLine(i*10,-298,i*10,298,QPen(Qt::lightGray, 1, Qt::DotLine) ); line->setCacheMode(QGraphicsItem::DeviceCoordinateCache); line->setZValue(-1); } } for (int i = -29; i< 29; ++i) { if(i!=0) { QGraphicsLineItem *line = addLine(-398,i*10,398,i*10,QPen(Qt::lightGray, 1, Qt::DotLine) ); line ->setCacheMode(QGraphicsItem::DeviceCoordinateCache); line->setZValue(-1); } }*/ ellipse1 = new GraphicsEllipseItem(); ellipse1->setRect(-2,-2,5,5); ellipse1->setPen(Qt::NoPen); ellipse1->setBrush(Qt::red); ellipse1->setZValue(200); //ellipse1->scale(0.25,0.25); connect(this,SIGNAL(changed(QList)),ellipse1,SLOT(handleSceneChange(QList))); addItem(ellipse1); timer = new QTimeLine(1); timer->setCurveShape(QTimeLine::LinearCurve); //timer->toggleDirection(); ani = new QGraphicsItemAnimation(); ani->setItem(ellipse1); ani->setTimeLine(timer); connect( timer, SIGNAL(finished()), this, SIGNAL(timeLineInRunningState()) ); setupVars(); } void SimulScene::drawBackground ( QPainter * painter, const QRectF & rect ) { QGraphicsScene::drawBackground(painter,rect); } void SimulScene::setupVars() { //variablen initialisieren setTimePerStep(1e-10); setSteps(300000); //setMeterPerPx(1/1000.0); setMeterPerPx(0.01); setPxPerSec(90.0); timer->setFrameRange(0,100); //timer->setUpdateInterval(30); timer->setCurveShape(QTimeLine::LinearCurve); setTimeLineDuration(30000); setFlightPathVisible(true); } void SimulScene::startTimer() { timer->setCurrentTime(0); timer->start(); } void SimulScene::stopTimer() { timer->setCurrentTime(0); timer->stop(); emit timeLineInRunningState(false); } void SimulScene::pauseTimer(bool yesno) { if (yesno) timer->stop(); else timer->start(); } void SimulScene::startPauseTimer(bool yesno) { pauseTimer(!yesno); } void SimulScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { switch(myMode) { case HomoEFieldItemInsert: if (mouseEvent->button() != Qt::LeftButton) break; //benutze nur linke maustaste currHomoEfieldInsertItem = new HomoEFieldItem(QRectF(mouseEvent->scenePos(),mouseEvent->scenePos())); currHomoEfieldInsertItem->setZValue(getHighestZIndexFieldItems() + FieldZStep); //zValue setzen addItem(currHomoEfieldInsertItem); QApplication::setOverrideCursor(QCursor(Qt::SizeFDiagCursor)); break; case StopperItemInsert: if (mouseEvent->button() != Qt::LeftButton) break; //benutze nur linke maustaste currStopperInsertItem = new StopperItem(mouseEvent->scenePos() ,mouseEvent->scenePos()); currStopperInsertItem->setZValue(getHighestZIndexFieldItems() + FieldZStep); //zValue setzen addItem(currStopperInsertItem); QApplication::setOverrideCursor(QCursor(Qt::SizeHorCursor)); break; case HomoBFieldItemInsert: if (mouseEvent->button() != Qt::LeftButton) break; //benutze nur linke maustaste currHomoBfieldInsertItem = new HomoBFieldItem(QRectF(mouseEvent->scenePos(),mouseEvent->scenePos())); currHomoBfieldInsertItem->setZValue(getHighestZIndexFieldItems()+FieldZStep); //zValue setzen addItem(currHomoBfieldInsertItem); QApplication::setOverrideCursor(QCursor(Qt::SizeFDiagCursor)); break; case ProbeChargeItemPlace: if (mouseEvent->button() != Qt::LeftButton) break; //benutze nur linke maustaste clearSelection(); ChargePlacementInProgress = true; ellipse1->setPos(mouseEvent->scenePos()); break; default: if (itemAt(mouseEvent->scenePos())->data(0) == ResizeRectItem && mouseEvent->button()==Qt::LeftButton) { pressedResizeItem = itemAt(mouseEvent->scenePos()); if (selectedItems().first()->type() == HomoEFieldItem::Type) { currHomoEfieldEditItem = qgraphicsitem_cast(selectedItems().first()); QApplication::setOverrideCursor(pressedResizeItem->cursor()); } else if (selectedItems().first()->type() == HomoBFieldItem::Type) { currHomoBfieldEditItem = qgraphicsitem_cast(selectedItems().first()); QApplication::setOverrideCursor(pressedResizeItem->cursor()); } else if (selectedItems().first()->type() == StopperItem::Type) { currStopperEditItem = qgraphicsitem_cast(selectedItems().first()); QApplication::setOverrideCursor(pressedResizeItem->cursor()); } } else { QGraphicsScene::mousePressEvent(mouseEvent); } } } void SimulScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (currHomoEfieldInsertItem != 0) { if (myMode == HomoEFieldItemInsert) { QPointF point(currHomoEfieldInsertItem->getRectF().x(), currHomoEfieldInsertItem->getRectF().y()); update(currHomoEfieldInsertItem->getRectF()); if(point.x() <= mouseEvent->scenePos().x() && point.y() <= mouseEvent->scenePos().y()) { QRectF rect(point,mouseEvent->scenePos()); currHomoEfieldInsertItem->setRectF(rect); //update(QRectF(point,mouseEvent->lastScenePos())); } } } if (currStopperInsertItem != 0) { if (myMode == StopperItemInsert) { QPointF point(currStopperInsertItem->getRectF().x(), currStopperInsertItem->getRectF().y()); update(currStopperInsertItem->getRectF()); if(point.x() <= mouseEvent->scenePos().x() && point.y() <= mouseEvent->scenePos().y()) { currStopperInsertItem->setLine(QLineF(point, QPointF(mouseEvent->scenePos().x(),point.y() ))); } } } else if (currHomoBfieldInsertItem != 0) { if (myMode == HomoBFieldItemInsert) { QPointF point(currHomoBfieldInsertItem->getRectF().x(), currHomoBfieldInsertItem->getRectF().y()); update(currHomoBfieldInsertItem->getRectF()); if(point.x() <= mouseEvent->scenePos().x() && point.y() <= mouseEvent->scenePos().y()) { QRectF rect(point,mouseEvent->scenePos()); currHomoBfieldInsertItem->setRectF(rect); //update(QRectF(point,mouseEvent->lastScenePos())); } } } else if (currHomoEfieldEditItem != 0 ) { QGraphicsRectItem *pressedRectItem = qgraphicsitem_cast(pressedResizeItem); QRectF currRect = currHomoEfieldEditItem->getRectF(); QPointF newPos = currHomoEfieldEditItem->pos(); calculateItemResize(mouseEvent,pressedRectItem,currRect,newPos,HomoEFieldItem::MinimumWidth,HomoEFieldItem::MinimumHeight); //aenderungen uebernehmen currHomoEfieldEditItem->setPos(newPos); if (currRect != currHomoEfieldEditItem->getRectF()) { currHomoEfieldEditItem->setRectF(currRect); } //resize rechtecke mitverschieben --> macht jetzt schon das Widget //if(mouseEvent->scenePos() != mouseEvent->lastScenePos()) displayResizeRects(true); } else if (currHomoBfieldEditItem != 0 ) { QGraphicsRectItem *pressedRectItem = qgraphicsitem_cast(pressedResizeItem); QRectF currRect = currHomoBfieldEditItem->getRectF(); QPointF newPos = currHomoBfieldEditItem->pos(); calculateItemResize(mouseEvent,pressedRectItem,currRect,newPos,HomoBFieldItem::MinimumWidth,HomoBFieldItem::MinimumHeight); //aenderungen uebernehmen currHomoBfieldEditItem->setPos(newPos); if (currRect != currHomoBfieldEditItem->getRectF()) { currHomoBfieldEditItem->setRectF(currRect); } //resize rechtecke mitverschieben --> macht jetzt schon das Widget //if(mouseEvent->scenePos() != mouseEvent->lastScenePos()) displayResizeRects(true); } else if (currStopperEditItem != 0 ) { QGraphicsRectItem *pressedRectItem = qgraphicsitem_cast(pressedResizeItem); QRectF currRect = currStopperEditItem->getRectF(); QPointF pos = currStopperEditItem->pos(); //calculateItemResize(mouseEvent,pressedRectItem,currRect,newPos,StopperItem::MinimumWidth,StopperItem::Height); qreal mouseDistanceX = mouseEvent->scenePos().x() - mouseEvent->lastScenePos().x(); //aenderungen uebernehmen if ( pressedResizeItem == reRects.rightRezizeItem || pressedResizeItem == reRects.rightTopResizeItem || pressedResizeItem == reRects.rightBottomResizeItem ) { QPointF newPos = QPointF(pos.x()+currRect.width()+mouseDistanceX , pos.y()); if (newPos.x() - pos.x() >= StopperItem::MinimumWidth) { currRect.adjust(0,0, (mouseDistanceX),0); currStopperEditItem->setRectF(currRect); //currStopperEditItem->setLine(QLineF(pos, newPos )); } } else if ( pressedResizeItem == reRects.leftResizeItem || pressedResizeItem == reRects.leftTopResizeItem || pressedResizeItem == reRects.leftBottomResizeItem ) { if ( pos.x() - pos.x()+currRect.width()-mouseDistanceX >= StopperItem::MinimumWidth) { currRect.adjust(0,0,-mouseDistanceX,0); currStopperEditItem->setPos(pos.x()+mouseDistanceX,pos.y()); currStopperEditItem->setRectF(currRect); //currStopperEditItem->setLine(QLineF(pos, newPos )); } } //resize rechtecke mitverschieben --> macht jetzt schon das Widget //if(mouseEvent->scenePos() != mouseEvent->lastScenePos()) displayResizeRects(true); } else if (ChargePlacementInProgress) { if (myMode == ProbeChargeItemPlace) { ellipse1->setPos(mouseEvent->scenePos()); } } else { QGraphicsScene::mouseMoveEvent(mouseEvent); if (mouseEvent->buttons() == Qt::LeftButton) if(mouseEvent->scenePos() != mouseEvent->lastScenePos()) displayResizeRects(true); } } void SimulScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (currHomoEfieldInsertItem != 0 && myMode == HomoEFieldItemInsert) { if (currHomoEfieldInsertItem->getRectF().width() < HomoEFieldItem::MinimumWidth || currHomoEfieldInsertItem->getRectF().height() setVisible(false); //ausblenden, damit sich nix verschiebt QRectF rect (currHomoEfieldInsertItem->getRectF()); QPointF posPoint(rect.x(),rect.y()); rect.setWidth(rect.width() - rect.x()); rect.setHeight(rect.height() - rect.y()); rect.setX(0); rect.setY(0); currHomoEfieldInsertItem->setRectF(rect); currHomoEfieldInsertItem->setPos(posPoint); currHomoEfieldInsertItem->setVisible(true); //und wieder einblenden setSceneMode(FieldItemEdit); //das neue item auswaehlen clearSelection(); currHomoEfieldInsertItem->setSelected(true); //die resize items aus und einblenden bei rotation connect( currHomoEfieldInsertItem, SIGNAL(rotationChanged()), this, SLOT(displayResizeRects())); //bei groesenanderung und verschieben resizerects mitverschieben connect( currHomoEfieldInsertItem, SIGNAL(heightChanged(double)), this, SLOT(moveResizeRects())); connect( currHomoEfieldInsertItem, SIGNAL(widthChanged(double)), this, SLOT(moveResizeRects())); connect( currHomoEfieldInsertItem, SIGNAL(ScenePosChanged(QPointF)), this, SLOT(moveResizeRects())); //item ueber sceneChange informieren connect(this,SIGNAL(changed(QList)),currHomoEfieldInsertItem,SLOT(handleSceneChange(QList))); } update(); //moegliche darstellungsprobleme beseitigen QApplication::restoreOverrideCursor(); } else if (currHomoBfieldInsertItem != 0 && myMode == HomoBFieldItemInsert) { if (currHomoBfieldInsertItem->getRectF().width() < HomoBFieldItem::MinimumWidth || currHomoBfieldInsertItem->getRectF().height() setVisible(false); //ausblenden, damit sich nix verschiebt QRectF rect (currHomoBfieldInsertItem->getRectF()); QPointF posPoint(rect.x(),rect.y()); rect.setWidth(rect.width() - rect.x()); rect.setHeight(rect.height() - rect.y()); rect.setX(0); rect.setY(0); currHomoBfieldInsertItem->setRectF(rect); currHomoBfieldInsertItem->setPos(posPoint); currHomoBfieldInsertItem->setVisible(true); //und wieder einblenden setSceneMode(FieldItemEdit); //das neue item auswaehlen clearSelection(); currHomoBfieldInsertItem->setSelected(true); //die resize items aus und einblenden bei rotation connect( currHomoBfieldInsertItem, SIGNAL(rotationChanged()), this, SLOT(displayResizeRects())); //bei groesenanderung und verschieben resizerects mitverschieben connect( currHomoBfieldInsertItem, SIGNAL(heightChanged(double)), this, SLOT(moveResizeRects())); connect( currHomoBfieldInsertItem, SIGNAL(widthChanged(double)), this, SLOT(moveResizeRects())); connect( currHomoBfieldInsertItem, SIGNAL(ScenePosChanged(QPointF)), this, SLOT(moveResizeRects())); //item ueber sceneChange informieren connect(this,SIGNAL(changed(QList)),currHomoBfieldInsertItem,SLOT(handleSceneChange(QList))); } update(); //moegliche darstellungsprobleme beseitigen QApplication::restoreOverrideCursor(); } else if (currStopperInsertItem != 0 && myMode == StopperItemInsert) { if (currStopperInsertItem->getRectF().width() < StopperItem::MinimumWidth) { //removeItem(currHomoEfieldInsertItem); //segmention fault in kombination mit delete? delete currStopperInsertItem; //zu kleines feld loeschen } else { //setze Startpunkt des rechtecks auf 0,0, damit pos() richtig funktioniert currStopperInsertItem->setVisible(false); //ausblenden, damit sich nix verschiebt QRectF rect (currStopperInsertItem->getRectF()); QPointF posPoint(rect.x(),rect.y()); rect.setWidth(rect.width() - rect.x()); rect.setHeight(rect.height() - rect.y()); rect.setX(0); rect.setY(0); currStopperInsertItem->setRectF(rect); currStopperInsertItem->setPos(posPoint); currStopperInsertItem->setVisible(true); //und wieder einblenden setSceneMode(FieldItemEdit); //das neue item auswaehlen clearSelection(); currStopperInsertItem->setSelected(true); //die resize items aus und einblenden bei rotation connect( currStopperInsertItem, SIGNAL(rotationChanged()), this, SLOT(displayResizeRects())); //bei groesenanderung und verschieben resizerects mitverschieben connect( currStopperInsertItem, SIGNAL(heightChanged(double)), this, SLOT(moveResizeRects())); connect( currStopperInsertItem, SIGNAL(widthChanged(double)), this, SLOT(moveResizeRects())); connect( currStopperInsertItem, SIGNAL(ScenePosChanged(QPointF)), this, SLOT(moveResizeRects())); //item ueber sceneChange informieren connect(this,SIGNAL(changed(QList)),currStopperInsertItem,SLOT(handleSceneChange(QList))); } update(); //moegliche darstellungsprobleme beseitigen QApplication::restoreOverrideCursor(); } else if (currHomoEfieldEditItem != 0) { update(); QApplication::restoreOverrideCursor(); } else if (currHomoBfieldEditItem != 0) { update(); QApplication::restoreOverrideCursor(); } else if (currStopperEditItem != 0) { update(); QApplication::restoreOverrideCursor(); } else if (ChargePlacementInProgress) { ChargePlacementInProgress = false; setSceneMode(FieldItemEdit); } pressedResizeItem = 0; currHomoEfieldInsertItem = 0; currHomoBfieldInsertItem = 0; currHomoEfieldEditItem = 0; currHomoBfieldEditItem = 0; currStopperInsertItem = 0; currStopperEditItem = 0; QGraphicsScene::mouseReleaseEvent(mouseEvent); } void SimulScene::keyPressEvent (QKeyEvent *keyevent) { if(keyevent->matches(QKeySequence::Delete)) { deleteSelectedFieldItems(); } } void SimulScene::setSceneMode(SceneMode mode) { if(myMode==mode) return; myMode = mode; emit sceneModeChanged(mode); } void SimulScene::createResizeRects() { const QRectF resizeRectSize(0,0,7,7); reRects.leftTopResizeItem = new QGraphicsRectItem(resizeRectSize); reRects.leftTopResizeItem->setCursor(Qt::SizeFDiagCursor); reRects.leftTopResizeItem->setBrush(Qt::black); reRects.leftTopResizeItem->setVisible(false); reRects.leftTopResizeItem->setData(0, QVariant(ResizeRectItem)); //typ des items setzen reRects.leftResizeItem = new QGraphicsRectItem(resizeRectSize); reRects.leftResizeItem->setCursor(Qt::SizeHorCursor); reRects.leftResizeItem->setBrush(Qt::black); reRects.leftResizeItem->setVisible(false); reRects.leftResizeItem->setData(0, QVariant(ResizeRectItem)); reRects.leftBottomResizeItem = new QGraphicsRectItem(resizeRectSize); reRects.leftBottomResizeItem->setCursor(Qt::SizeBDiagCursor); reRects.leftBottomResizeItem->setBrush(Qt::black); reRects.leftBottomResizeItem->setVisible(false); reRects.leftBottomResizeItem->setData(0, QVariant(ResizeRectItem)); reRects.bottomResizeItem = new QGraphicsRectItem(resizeRectSize); reRects.bottomResizeItem->setCursor(Qt::SizeVerCursor); reRects.bottomResizeItem->setBrush(Qt::black); reRects.bottomResizeItem->setVisible(false); reRects.bottomResizeItem->setData(0, QVariant(ResizeRectItem)); reRects.rightBottomResizeItem = new QGraphicsRectItem(resizeRectSize); reRects.rightBottomResizeItem->setCursor(Qt::SizeFDiagCursor); reRects.rightBottomResizeItem->setBrush(Qt::black); reRects.rightBottomResizeItem->setVisible(false); reRects.rightBottomResizeItem->setData(0, QVariant(ResizeRectItem)); reRects.rightRezizeItem = new QGraphicsRectItem(resizeRectSize); reRects.rightRezizeItem->setCursor(Qt::SizeHorCursor); reRects.rightRezizeItem->setBrush(Qt::black); reRects.rightRezizeItem->setVisible(false); reRects.rightRezizeItem->setData(0, QVariant(ResizeRectItem)); reRects.rightTopResizeItem = new QGraphicsRectItem(resizeRectSize); reRects.rightTopResizeItem->setCursor(Qt::SizeBDiagCursor); reRects.rightTopResizeItem->setBrush(Qt::black); reRects.rightTopResizeItem->setVisible(false); reRects.rightTopResizeItem->setData(0, QVariant(ResizeRectItem)); reRects.topResizeItem = new QGraphicsRectItem(resizeRectSize); reRects.topResizeItem->setCursor(Qt::SizeVerCursor); reRects.topResizeItem->setBrush(Qt::black); reRects.topResizeItem->setVisible(false); reRects.topResizeItem->setData(0, QVariant(ResizeRectItem)); addItem(reRects.leftTopResizeItem); addItem(reRects.leftResizeItem); addItem(reRects.leftBottomResizeItem); addItem(reRects.bottomResizeItem); addItem(reRects.rightBottomResizeItem); addItem(reRects.rightRezizeItem); addItem(reRects.rightTopResizeItem); addItem(reRects.topResizeItem); connect( this, SIGNAL(selectionChanged()), this, SLOT(displayResizeRects()) ); } void SimulScene::displayResizeRects(bool move) { if ( selectedItems().count() == 1 && FieldItem::isFieldItem(selectedItems().first()) && !selectedItems().first()->transform().isTranslating() //bei rotation nicht anzeigen ) { const qreal oSPACE = 3; //Aussenabstand //position des ausgewaehlten items QPointF seletedPos = selectedItems().first()->pos(); qreal selPosX = seletedPos.x(); qreal selPosY = seletedPos.y(); //an die richtige stelle schieben reRects.leftTopResizeItem->setPos(selPosX - reRects.leftTopResizeItem->rect().width()- oSPACE, selPosY - reRects.leftTopResizeItem->rect().height() - oSPACE); reRects.leftResizeItem->setPos(selPosX - reRects.leftResizeItem->rect().width()- oSPACE, selPosY + selectedItems().first()->boundingRect().height() / 2.0 - reRects.leftResizeItem->rect().height() /2.0); reRects.leftBottomResizeItem->setPos(selPosX - reRects.leftBottomResizeItem->rect().width()- oSPACE, selPosY + selectedItems().first()->boundingRect().height() + oSPACE); reRects.bottomResizeItem->setPos(selPosX + selectedItems().first()->boundingRect().width() / 2.0 - reRects.bottomResizeItem->rect().width() /2.0, selPosY + selectedItems().first()->boundingRect().height() + oSPACE); reRects.rightBottomResizeItem->setPos(selPosX + selectedItems().first()->boundingRect().width() + oSPACE, selPosY + selectedItems().first()->boundingRect().height() + oSPACE); reRects.rightRezizeItem->setPos(selPosX + selectedItems().first()->boundingRect().width() + oSPACE, selPosY + selectedItems().first()->boundingRect().height() / 2.0 - reRects.rightRezizeItem->rect().height() /2.0); reRects.rightTopResizeItem->setPos(selPosX + selectedItems().first()->boundingRect().width() + oSPACE, selPosY - reRects.rightTopResizeItem->rect().height() - oSPACE); reRects.topResizeItem->setPos(selPosX + selectedItems().first()->boundingRect().width() / 2.0 - reRects.topResizeItem->rect().width() /2.0, selPosY - reRects.leftTopResizeItem->rect().height() - oSPACE); if (!move) { //im verschiebemodus kann man von diesen dingen ausgehen //nach oben bringen qreal newZValue = getHighestZIndexVisible() + 0.000001; reRects.leftTopResizeItem->setZValue(newZValue); reRects.leftResizeItem->setZValue(newZValue); reRects.leftBottomResizeItem->setZValue(newZValue); reRects.bottomResizeItem->setZValue(newZValue); reRects.rightBottomResizeItem->setZValue(newZValue); reRects.rightRezizeItem->setZValue(newZValue); reRects.rightTopResizeItem->setZValue(newZValue); reRects.topResizeItem->setZValue(newZValue); //sichtbar machen reRects.leftTopResizeItem->setVisible(true); reRects.leftResizeItem->setVisible(true); reRects.leftBottomResizeItem->setVisible(true); reRects.bottomResizeItem->setVisible(true); reRects.rightBottomResizeItem->setVisible(true); reRects.rightRezizeItem->setVisible(true); reRects.rightTopResizeItem->setVisible(true); reRects.topResizeItem->setVisible(true); } } else if(!move && reRects.leftTopResizeItem->isVisible()) { //unsichtbar machen reRects.leftTopResizeItem->setVisible(false); reRects.leftResizeItem->setVisible(false); reRects.leftBottomResizeItem->setVisible(false); reRects.bottomResizeItem->setVisible(false); reRects.rightBottomResizeItem->setVisible(false); reRects.rightRezizeItem->setVisible(false); reRects.rightTopResizeItem->setVisible(false); reRects.topResizeItem->setVisible(false); } } void SimulScene::moveResizeRects() { displayResizeRects(true); } qreal SimulScene::getHighestZIndexVisible() { bool highestZValueSet = false; qreal highestZValue = 0; for (int i = 0; i < items().count() ; ++i ) { if (items().at(i)->isVisible()) { if (!highestZValueSet) { highestZValue = items().at(i)->zValue(); highestZValueSet = true; } else if (highestZValue < items().at(i)->zValue()) { highestZValue = items().at(i)->zValue(); } } } return highestZValue; } qreal SimulScene::getHighestZIndexFieldItems() { bool highestZValueSet = false; qreal highestZValue = FieldDefaultZValue; //default value for (int i = 0; i < items().count() ; ++i ) { if (FieldItem::isFieldItem(items().at(i))) { if (!highestZValueSet) { highestZValue = items().at(i)->zValue(); highestZValueSet = true; } else if (highestZValue < items().at(i)->zValue()) { highestZValue = items().at(i)->zValue(); } } } return highestZValue; } qreal SimulScene::getLowestZIndexFieldItems() { bool lowestZValueSet = false; qreal lowestZValue = FieldDefaultZValue; //default value for (int i = 0; i < items().count() ; ++i ) { if (FieldItem::isFieldItem(items().at(i))) { if (!lowestZValueSet) { lowestZValue = items().at(i)->zValue(); lowestZValueSet = true; } else if (lowestZValue > items().at(i)->zValue()) { lowestZValue = items().at(i)->zValue(); } } } return lowestZValue; } void SimulScene::deleteSelectedFieldItems() { QList currSelectedItems = selectedItems(); for (int i = 0; i < currSelectedItems.count() ; ++i ) { if (FieldItem::isFieldItem(currSelectedItems.at(i))) { delete currSelectedItems.at(i); } } } void SimulScene::calculateItemResize( QGraphicsSceneMouseEvent *mouseEvent, QGraphicsRectItem *pressedRectItem, QRectF &currRect, QPointF &newPos, qreal minWidth, qreal minHeight ) { qreal mouseDistanceX = mouseEvent->scenePos().x() - mouseEvent->lastScenePos().x(); qreal mouseDistanceY = mouseEvent->scenePos().y() - mouseEvent->lastScenePos().y(); if (reRects.rightRezizeItem == pressedRectItem) { currRect.adjust(0,0,mouseDistanceX , 0); } else if (reRects.leftResizeItem == pressedRectItem) { newPos = QPointF(newPos.x()+mouseDistanceX,newPos.y()); currRect.adjust(0,0,-mouseDistanceX , 0); } else if (reRects.topResizeItem == pressedRectItem) { newPos = QPointF(newPos.x(),newPos.y()+mouseDistanceY); currRect.adjust(0,0,0, -mouseDistanceY ); } else if (reRects.bottomResizeItem == pressedRectItem) { currRect.adjust(0,0,0, mouseDistanceY ); } else if (reRects.rightBottomResizeItem == pressedRectItem) { currRect.adjust(0,0,0, mouseDistanceY ); currRect.adjust(0,0,mouseDistanceX , 0); } else if (reRects.leftBottomResizeItem == pressedRectItem) { currRect.adjust(0,0,0, mouseDistanceY ); newPos = QPointF(newPos.x()+mouseDistanceX,newPos.y()); currRect.adjust(0,0,-mouseDistanceX , 0); } else if (reRects.leftTopResizeItem == pressedRectItem) { newPos = QPointF(newPos.x(),newPos.y()+mouseDistanceY); currRect.adjust(0,0,0, -mouseDistanceY ); newPos = QPointF(newPos.x()+mouseDistanceX,newPos.y()); currRect.adjust(0,0,-mouseDistanceX , 0); } else if (reRects.rightTopResizeItem == pressedRectItem) { newPos = QPointF(newPos.x(),newPos.y()+mouseDistanceY); currRect.adjust(0,0,0, -mouseDistanceY ); currRect.adjust(0,0,mouseDistanceX , 0); } //gegen zu klein werden if (currRect.width() <= minWidth) { if (mouseEvent->lastScenePos().x() < mouseEvent->scenePos().x()) { //gegen rumspringen newPos = QPointF(newPos.x() + (currRect.width() - minWidth) ,newPos.y()); } currRect.setWidth(minWidth); } if (currRect.height() <= minHeight) { if (mouseEvent->lastScenePos().y() < mouseEvent->scenePos().y()) { //gegen rumspringen newPos = QPointF(newPos.x(), newPos.y() + (currRect.height() - minHeight)); } currRect.setHeight(minHeight); } } SimulScene::~SimulScene() { } /*! \fn SimulScene::getTimePerStep() */ double SimulScene::getTimePerStep() { return timePerStep; } /*! \fn SimulScene::setTimePerStep(int time) */ void SimulScene::setTimePerStep(double time) { if (time == timePerStep) return; timePerStep = time; emit timePerStepChanged(time); } /*! \fn SimulScene::startCalculation() */ void SimulScene::startCalculation() { //evtl laufenden timer stoppen stopTimer(); //leeren Pfad setezen clearFlightPath(); //Feld Item Listen erzeugen (viel schneller, als jedes mal items(point) durchlaufen) calcEFieldList.clear(); calcBFieldList.clear(); calcStopperList.clear(); for(int i = 0; i < items().size(); ++i) { //HomoEFieldItems Abarbeiten if (qgraphicsitem_cast (items().at(i)) != 0) { calcEFieldList << qgraphicsitem_cast (items().at(i)); } //HomoBFieldItems Abarbeiten if (qgraphicsitem_cast (items().at(i)) != 0) { calcBFieldList << qgraphicsitem_cast(items().at(i)); } //StopperItems Abarbeiten if (qgraphicsitem_cast (items().at(i)) != 0) { calcStopperList << qgraphicsitem_cast(items().at(i)); } } //berechnung starten ellipse1->calculateProbePath(ellipse1->pos()); pathItem1->setPath(ellipse1->getFlightPath()); //animationspfad berechnen ani->clear(); int currSteps = ellipse1->getCurrProbePath()->count(); int entry_step = ceil(currSteps/2500.0); //jeder entry_step(te) step wird eingetragen for (int i=0; isetPosAt(i/(double)currSteps, ellipse1->getCurrProbePath()->at(i) ); } } //aenderungen bestimmter Werte bekanntgeben QString realSimulTimeString(QLocale().toString(ellipse1->getRealSimulTime(),'g')); realSimulTimeString.append(" s"); emit realSimulTimeChanged(realSimulTimeString); //brauchbare Animationsdauer bestimmen setTimeLineDuration(ellipse1->getFlightPath().length()/getPxPerSec() * 1000.0); } /*! \fn SimulScene::getSteps() */ int SimulScene::getSteps() { return steps; } /*! \fn SimulScene::setSteps() */ void SimulScene::setSteps(int steps) { if (this->steps == steps) return; this->steps = steps; emit stepsChanged(steps); } double SimulScene::getPowerAt(QPointF point, double charge, double speedX, double speedY, char xy) { double dPower = 0; for (int i=0; icontains(myHomoEFieldItem->mapFromScene(point))) { double power = (myHomoEFieldItem->getFieldPower() * charge); double degAngle = myHomoEFieldItem->getRotation(); double radAngle = degAngle/180.0*PI; if(xy == 'x') { if (degAngle != 180.0) dPower += power * -sin(radAngle); } if(xy == 'y') { if (degAngle != 90.0 && degAngle != 270.0) dPower += power * cos(radAngle); } } } for (int i=0; icontains(myHomoBFieldItem->mapFromScene(point))) { double absSpeed = sqrt(speedX * speedX + speedY * speedY); // Geschwindigkeit im Betrag |v|=sqrt(vx^2+vy^2) double absLorentzPower = (charge * absSpeed * myHomoBFieldItem->getFluxDensity() ); //Kraft im Betrag: |F| = q*v*B double speedRadAngle = atan2(speedY,speedX); //Winkel des Geschwindigkeitsvekors zur x-Achse im Bogenmass double PowerRadAngle; //Winkel des Lorentzkraftvektors zur x-Achse im Bogenmass if (myHomoBFieldItem->getIsDirectionIntoPlane()) { PowerRadAngle = speedRadAngle - PI/2.0; } else { PowerRadAngle = speedRadAngle + PI/2.0; } //qDebug()<< PowerRadAngle; if (xy == 'x') { dPower += absLorentzPower * cos(PowerRadAngle); } if (xy == 'y') { dPower += absLorentzPower * sin(PowerRadAngle); } } } return dPower; } bool SimulScene::stopsHere(const QPointF &p1, const QPointF &p2) { QPainterPath myPath(p1); myPath.lineTo(p2); for (int i = 0; i< calcStopperList.count(); ++i) { QPainterPath itemPath = calcStopperList.at(i)->mapFromScene(myPath); if (calcStopperList.at(i)->collidesWithPath(itemPath/*,Qt::IntersectsItemShape*/)) return true; } return false; } double SimulScene::getMeterPerPx() const { return meterPerPx; } double SimulScene::getPxPerSec() const { return pxPerSec; } void SimulScene::setMeterPerPx ( double theValue ) { if (theValue == meterPerPx) return; meterPerPx = theValue; emit meterPerPxChanged(theValue); } void SimulScene::setPxPerSec ( double theValue ) { if (theValue == pxPerSec) return; pxPerSec = theValue; emit pxPerSecChanged(theValue); } /*! \fn SimulScene::getProbeDockWidget() const */ QWidget* SimulScene::getProbeDockWidget() const { return ellipse1->getDockWidget(); } void SimulScene::setFlightPathVisible(bool visible) { if(pathItem1->isVisible() == visible) return; pathItem1->setVisible(visible); emit flightPathVisibilityChanged(visible); } bool SimulScene::isFlightPathVisible() { return pathItem1->isVisible(); } void SimulScene::setTimeLineDuration(int duration) { if(timer->duration() == duration) return; timer->setDuration(duration); emit timeLineDurationChanged(duration); } int SimulScene::getTimeLineDuration() { return timer->duration(); } QListWidget* SimulScene::getFieldListWidget() { return fieldListWidget; } QList SimulScene::getItemsInZOrder() { QList currItems = items(); bool swapNeeded; for (int i=0;i< currItems.count();++i) { swapNeeded=false; for (int j=0; j< currItems.count() -i -1; ++j){ if(currItems[j]->zValue() > currItems[j+1]->zValue()) { QGraphicsItem* swapper = currItems[j]; currItems[j]= currItems[j+1]; currItems[j+1] = swapper; swapNeeded = true; } } if(!swapNeeded) break; } return currItems; } QList SimulScene::getFieldItemsInZOrder() { QList currItems; for (int i = 0; i< items().size();++i) { if(FieldItem::isFieldItem(items().at(i))) currItems.append(items().at(i)); } bool swapNeeded; for (int i=0;i< currItems.count();++i) { swapNeeded=false; for (int j=0; j< currItems.count() -i -1; ++j){ if(currItems[j]->zValue() > currItems[j+1]->zValue()) { QGraphicsItem* swapper = currItems[j]; currItems[j]= currItems[j+1]; currItems[j+1] = swapper; swapNeeded = true; } } if(!swapNeeded) break; } //for (int i=0;i< currItems.count();++i) { // qDebug()<< "sort: " <zValue(); //} return currItems; } void SimulScene::moveFieldItemDown(QGraphicsItem* fieldItem) { if (!FieldItem::isFieldItem(fieldItem)) return; qreal currFieldItemZValue = fieldItem->zValue(); QList FieldItemsInZOrder = getFieldItemsInZOrder(); for (int i = 1; i< FieldItemsInZOrder.count();++i) { if (FieldItemsInZOrder.at(i) == fieldItem) { fieldItem->setZValue(FieldItemsInZOrder.at(i-1)->zValue()); FieldItemsInZOrder.at(i-1)->setZValue(currFieldItemZValue); return; } } } void SimulScene::moveFieldItemUp(QGraphicsItem* fieldItem) { if (!FieldItem::isFieldItem(fieldItem)) return; qreal currFieldItemZValue = fieldItem->zValue(); QList FieldItemsInZOrder = getFieldItemsInZOrder(); for (int i = 0; i< FieldItemsInZOrder.count()-1;++i) { if (FieldItemsInZOrder.at(i) == fieldItem) { fieldItem->setZValue(FieldItemsInZOrder.at(i+1)->zValue()); FieldItemsInZOrder.at(i+1)->setZValue(currFieldItemZValue); return; } } } void SimulScene::moveFieldItemOnTop(QGraphicsItem* fieldItem) { if (!FieldItem::isFieldItem(fieldItem)) return; qreal currFieldItemZValue = fieldItem->zValue(); QList FieldItemsInZOrder = getFieldItemsInZOrder(); bool fieldItemHit = false; for (int i = 0; i< FieldItemsInZOrder.count()-1;++i) {//currItem rauf wandern lassen if (FieldItemsInZOrder.at(i) == fieldItem) { fieldItemHit = true; } if (fieldItemHit) { QGraphicsItem* swapper = FieldItemsInZOrder.at(i); FieldItemsInZOrder[i] = FieldItemsInZOrder.at(i+1); FieldItemsInZOrder[i+1] = swapper; } } for (int i = 0;isetZValue( (FieldDefaultZValue + i*FieldZStep)); } } void SimulScene::moveFieldItemOnBottom(QGraphicsItem* fieldItem) { if (!FieldItem::isFieldItem(fieldItem)) return; qreal currFieldItemZValue = fieldItem->zValue(); QList FieldItemsInZOrder = getFieldItemsInZOrder(); bool fieldItemHit = false; for (int i = FieldItemsInZOrder.count()-1; i>0 ;--i) { //currItem runter wandern lassen if (FieldItemsInZOrder.at(i) == fieldItem) { fieldItemHit = true; } if (fieldItemHit) { QGraphicsItem* swapper = FieldItemsInZOrder.at(i); FieldItemsInZOrder[i] = FieldItemsInZOrder.at(i-1); FieldItemsInZOrder[i-1] = swapper; } } for (int i = 0;isetZValue( (FieldDefaultZValue + i*FieldZStep)); } } void SimulScene::moveSelectedFieldItemDown() { if (selectedItems().isEmpty()) return; moveFieldItemDown(selectedItems().first()); } void SimulScene::moveSelectedFieldItemUp() { if (selectedItems().isEmpty()) return; moveFieldItemUp(selectedItems().first()); } void SimulScene::moveSelectedFieldItemOnTop() { if (selectedItems().isEmpty()) return; moveFieldItemOnTop(selectedItems().first()); } void SimulScene::moveSelectedFieldItemOnBottom() { if (selectedItems().isEmpty()) return; moveFieldItemOnBottom(selectedItems().first()); } GraphicsEllipseItem* SimulScene::getProbeChargeItem() { return ellipse1; } void SimulScene::clearFlightPath() { pathItem1->setPath(QPainterPath()); } void SimulScene::resetScene() { //Alle felder Entfernen QList currItems = items(); for (int i = 0; iresetProbe(); }