arenaview.cpp
Go to the documentation of this file.
00001 #include "arenaview.h"
00002 #include "arenascene.h"
00003 #include "arenasceneelement.h"
00004 #include "../model/arena.h"
00005 #include "../model/arenaelement.h"
00006 #include "../model/arenaelementtype.h"
00007 
00008 #include <QDebug>
00009 #include <QScrollBar>
00010 #include <QMouseEvent>
00011 #include <QMessageBox>
00012 #include <QTimer>
00013 
00014 ArenaView::ArenaView(ArenaController *controller, QWidget *parent)
00015     : QGraphicsView(parent)
00016     , m_controller(controller)
00017 {
00018     setDragMode(QGraphicsView::RubberBandDrag);
00019     setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
00020 
00021     m_rubberBandActive = false;
00022 }
00023 
00024 void drawCross(QPainter *painter, QPoint p, int lineLength)
00025 {
00026     painter->drawLine(p.x() - lineLength, p.y(), p.x() + lineLength, p.y());
00027     painter->drawLine(p.x(), p.y() - lineLength, p.x(), p.y() + lineLength);
00028 }
00029 
00030 void ArenaView::slotGridPaintingDisabled()
00031 {
00032     QMessageBox::warning(parentWidget(), "Grid Painting Monkey",
00033         "Aaargh. This is just too many grid points. Sorry. Falling back to white background.");
00034 }
00035 
00036 void ArenaView::drawBackground(QPainter *painter, const QRectF& rect)
00037 {
00038     // When the grid becomes too small, don't draw anything because it won't
00039     // help and only consume (a lot of) CPU cycles
00040     qreal scale = qMin(transform().m11(), transform().m22());
00041     if (scale < 0.2001)
00042         return;
00043 
00044     // It is important to know that we effectively draw in *scene* coordinates,
00045     // not view coordinates! Before drawBackground() is called, the painter is
00046     // transformed accordingly by Qt.
00047 
00048     painter->setPen(0xE0E0E0);
00049 
00050     QPointF p0 = ArenaScene::nearestGridPoint(rect.topLeft());
00051     QRectF scRect = scene()->sceneRect();
00052     p0.rx() = qMax(p0.x(), scRect.left());
00053     p0.ry() = qMax(p0.y(), scRect.top());
00054     int visibleSceneWidth = qMin(rect.width(), scRect.width()) + CELL_SIZE;
00055     int visibleSceneHeight = qMin(rect.height(), scRect.height()) + CELL_SIZE;
00056 
00057 
00058     /*int numCells = (visibleSceneWidth / CELL_SIZE) * (visibleSceneHeight / CELL_SIZE);
00059     // Paintint a grid for > 1000 cells is just too much for the average CPU
00060     if (numCells > 1000)
00061     {
00062         static bool warned = false;
00063         if (!warned)
00064         {
00065             QTimer::singleShot(0, this, SLOT(slotGridPaintingDisabled()));
00066             warned = true;
00067         }
00068         return;
00069     }*/
00070 
00071     // One cell has a grid line to its left *and* to its right, therefore
00072     // we always have (number of cells + 1) grid lines
00073     for (int x = 0; x <= visibleSceneWidth; x += CELL_SIZE)
00074     {
00075         for (int y = 0; y <= visibleSceneHeight; y += CELL_SIZE)
00076         {
00077             int lineLength = 2;
00078             QPoint p = p0.toPoint() + QPoint(x, y)
00079                        - QPoint(ITEM_SIZE, ITEM_SIZE) / 2 - QPoint(SPACING, SPACING);
00080 
00081             p.rx() -= 1;
00082             p.ry() -= 1;
00083             drawCross(painter, p, lineLength);
00084             p.rx() += SPACING + 1;
00085             drawCross(painter, p, lineLength);
00086             p.rx() -= SPACING + 1;
00087             p.ry() += SPACING + 1;
00088             drawCross(painter, p, lineLength);
00089             p.rx() += SPACING + 1;
00090             drawCross(painter, p, lineLength);
00091 
00092         }
00093     }
00094 }
00095 
00096 void ArenaView::drawForeground(QPainter *painter, const QRectF &rect)
00097 {
00098     m_controller->draw(painter, rect);
00099 }
00100 
00101 void ArenaView::mousePressEvent(QMouseEvent *event)
00102 {
00103     bool forwardEvent = true;
00104 
00105     // Shortcut to inserting elements
00106     if (event->modifiers() & Qt::ShiftModifier && arenaScene()->selectedElements().count() == 1)
00107     {
00108         dragStarted();
00109         ArenaSceneElement *selection = arenaScene()->selectedElements().first();
00110         QString elementType = selection->element()->type()->name();
00111         m_controller->startInsertion(elementType, mapToScene(event->pos()));
00112         m_rubberBandActive = false;
00113         // Do not mess with item selection (set by ArenaController)
00114         forwardEvent = false;
00115     }
00116     else
00117     {
00118         m_rubberBandActive = itemAt(event->pos()) == 0;
00119     }
00120 
00121     if (m_rubberBandActive)
00122         setDragMode(QGraphicsView::RubberBandDrag);
00123     else
00124         setDragMode(QGraphicsView::NoDrag);
00125 
00126     m_lastMousePos = event->pos();
00127     m_lastMousePosScene = mapToScene(event->pos());
00128 
00129     if (forwardEvent)
00130         QGraphicsView::mousePressEvent(event);
00131 }
00132 
00133 void ArenaView::mouseMoveEvent(QMouseEvent *event)
00134 {
00135     if (!arenaScene())
00136         return;
00137 
00138     bool forwardEvent = true;
00139 
00140     if (event->buttons() & Qt::LeftButton && !m_rubberBandActive)
00141     {
00142         QPointF mousePos = mapToScene(event->pos());
00143         QList<ArenaSceneElement*> selectedElements = arenaScene()->selectedElements();
00144 
00145         if (!m_controller->operationInProgress())
00146         {
00147             dragStarted();
00148             m_controller->startDrag(selectedElements);
00149         }
00150 
00151         // In this case, we will move the selected element directly to the
00152         // position of the mouse cursor
00153         if (selectedElements.count() == 1 &&
00154             !selectedElements.first()->element()->isItem())
00155         {
00156             m_controller->dragTo(mousePos);
00157         }
00158         else
00159         {
00160             // Offset the mouse has been moved by
00161             QPointF offset = mousePos - m_lastMousePosScene;
00162             m_controller->dragBy(offset);
00163         }
00164 
00165         forwardEvent = false;
00166     }
00167     else if (event->buttons() & Qt::RightButton)
00168     {
00169         QPoint diff = event->pos() - m_lastMousePos;
00170 
00171         int oldX = horizontalScrollBar()->value();
00172         int oldY = verticalScrollBar()->value();
00173         horizontalScrollBar()->setValue(oldX - diff.x());
00174         verticalScrollBar()->setValue(oldY - diff.y());
00175     }
00176 
00177     m_lastMousePos = event->pos();
00178     m_lastMousePosScene = mapToScene(event->pos());
00179 
00180     if (forwardEvent)
00181         QGraphicsView::mouseMoveEvent(event);
00182 }
00183 
00184 void ArenaView::mouseReleaseEvent(QMouseEvent *event)
00185 {
00186     QGraphicsView::mouseReleaseEvent(event);
00187     m_rubberBandActive = false;
00188     if (m_controller->operationInProgress())
00189     {
00190         m_controller->endOperation();
00191         // Update to make controller handles disappear
00192         update();
00193     }
00194 
00195     dragEnded();
00196 }
00197 
00198 ArenaScene *ArenaView::arenaScene()
00199 {
00200     return dynamic_cast<ArenaScene*>(scene());
00201 }
00202 
00203 void ArenaView::wheelEvent(QWheelEvent *event)
00204 {
00205     if (event->delta() > 0)
00206         slotZoomIn();
00207     else
00208         slotZoomOut();
00209 }
00210 
00211 #define MIN_SCALE 0.1
00212 #define MAX_SCALE 5.0
00213 
00214 void ArenaView::slotZoomIn()
00215 {
00216     QTransform trans = transform().scale(2.0, 2.0);
00217     if (trans.m11() <= MAX_SCALE || trans.m22() <= MAX_SCALE)
00218         setTransform(trans);
00219 }
00220 
00221 void ArenaView::slotZoomOut()
00222 {
00223     QTransform trans = transform().scale(0.5, 0.5);
00224     if (trans.m11() >= MIN_SCALE || trans.m22() >= MIN_SCALE)
00225         setTransform(trans);
00226 }
00227 
00228 void ArenaView::dragStarted()
00229 {
00230     // Do not change visible scene rect while an element is being inserted
00231     if (scene())
00232         setSceneRect(scene()->sceneRect());
00233 }
00234 
00235 void ArenaView::dragEnded()
00236 {
00237     // Change scene rect with scene again
00238     setSceneRect(QRectF());
00239 }
00240 
00241 
00242 void ArenaView::dragEnterEvent(QDragEnterEvent *event)
00243 {
00244     dragStarted();
00245 
00246     QString elementTypeName = event->mimeData()->data("type");
00247     m_controller->startInsertion(elementTypeName, mapToScene(event->pos()));
00248 
00249     event->accept();
00250 }
00251 
00252 void ArenaView::dragLeaveEvent(QDragLeaveEvent *event)
00253 {
00254     m_controller->cancelInsertion();
00255     event->accept();
00256 
00257     dragEnded();
00258 }
00259 
00260 void ArenaView::dragMoveEvent(QDragMoveEvent *event)
00261 {
00262     m_controller->dragTo(mapToScene(event->pos()));
00263     event->accept();
00264 }
00265 
00266 void ArenaView::dropEvent(QDropEvent *event)
00267 {
00268     event->accept();
00269     m_controller->endOperation();
00270     // Make controller handles disappear
00271     update();
00272     dragEnded();
00273     //QGraphicsScene::dropEvent(event);
00274 }


hector_nist_arena_designer
Author(s): Johannes Simon, Stefan Kohlbrecher
autogenerated on Mon Oct 6 2014 00:26:31