arenaview.cpp
Go to the documentation of this file.
1 #include "arenaview.h"
2 #include "arenascene.h"
3 #include "arenasceneelement.h"
4 #include "../model/arena.h"
5 #include "../model/arenaelement.h"
6 #include "../model/arenaelementtype.h"
7 
8 #include <QDebug>
9 #include <QScrollBar>
10 #include <QMouseEvent>
11 #include <QMessageBox>
12 #include <QMimeData>
13 #include <QTimer>
14 
15 ArenaView::ArenaView(ArenaController *controller, QWidget *parent)
16  : QGraphicsView(parent)
17  , m_controller(controller)
18 {
19  setDragMode(QGraphicsView::RubberBandDrag);
20  setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
21 
22  m_rubberBandActive = false;
23 }
24 
25 void drawCross(QPainter *painter, QPoint p, int lineLength)
26 {
27  painter->drawLine(p.x() - lineLength, p.y(), p.x() + lineLength, p.y());
28  painter->drawLine(p.x(), p.y() - lineLength, p.x(), p.y() + lineLength);
29 }
30 
32 {
33  QMessageBox::warning(parentWidget(), "Grid Painting Monkey",
34  "Aaargh. This is just too many grid points. Sorry. Falling back to white background.");
35 }
36 
37 void ArenaView::drawBackground(QPainter *painter, const QRectF& rect)
38 {
39  // When the grid becomes too small, don't draw anything because it won't
40  // help and only consume (a lot of) CPU cycles
41  qreal scale = qMin(transform().m11(), transform().m22());
42  if (scale < 0.2001)
43  return;
44 
45  // It is important to know that we effectively draw in *scene* coordinates,
46  // not view coordinates! Before drawBackground() is called, the painter is
47  // transformed accordingly by Qt.
48 
49  painter->setPen(0xE0E0E0);
50 
51  QPointF p0 = ArenaScene::nearestGridPoint(rect.topLeft());
52  QRectF scRect = scene()->sceneRect();
53  p0.rx() = qMax(p0.x(), scRect.left());
54  p0.ry() = qMax(p0.y(), scRect.top());
55  int visibleSceneWidth = qMin(rect.width(), scRect.width()) + CELL_SIZE;
56  int visibleSceneHeight = qMin(rect.height(), scRect.height()) + CELL_SIZE;
57 
58 
59  /*int numCells = (visibleSceneWidth / CELL_SIZE) * (visibleSceneHeight / CELL_SIZE);
60  // Paintint a grid for > 1000 cells is just too much for the average CPU
61  if (numCells > 1000)
62  {
63  static bool warned = false;
64  if (!warned)
65  {
66  QTimer::singleShot(0, this, SLOT(slotGridPaintingDisabled()));
67  warned = true;
68  }
69  return;
70  }*/
71 
72  // One cell has a grid line to its left *and* to its right, therefore
73  // we always have (number of cells + 1) grid lines
74  for (int x = 0; x <= visibleSceneWidth; x += CELL_SIZE)
75  {
76  for (int y = 0; y <= visibleSceneHeight; y += CELL_SIZE)
77  {
78  int lineLength = 2;
79  QPoint p = p0.toPoint() + QPoint(x, y)
80  - QPoint(ITEM_SIZE, ITEM_SIZE) / 2 - QPoint(SPACING, SPACING);
81 
82  p.rx() -= 1;
83  p.ry() -= 1;
84  drawCross(painter, p, lineLength);
85  p.rx() += SPACING + 1;
86  drawCross(painter, p, lineLength);
87  p.rx() -= SPACING + 1;
88  p.ry() += SPACING + 1;
89  drawCross(painter, p, lineLength);
90  p.rx() += SPACING + 1;
91  drawCross(painter, p, lineLength);
92 
93  }
94  }
95 }
96 
97 void ArenaView::drawForeground(QPainter *painter, const QRectF &rect)
98 {
99  m_controller->draw(painter, rect);
100 }
101 
102 void ArenaView::mousePressEvent(QMouseEvent *event)
103 {
104  bool forwardEvent = true;
105 
106  // Shortcut to inserting elements
107  if (event->modifiers() & Qt::ShiftModifier && arenaScene()->selectedElements().count() == 1)
108  {
109  dragStarted();
110  ArenaSceneElement *selection = arenaScene()->selectedElements().first();
111  QString elementType = selection->element()->type()->name();
112  m_controller->startInsertion(elementType, mapToScene(event->pos()));
113  m_rubberBandActive = false;
114  // Do not mess with item selection (set by ArenaController)
115  forwardEvent = false;
116  }
117  else
118  {
119  m_rubberBandActive = itemAt(event->pos()) == 0;
120  }
121 
122  if (m_rubberBandActive)
123  setDragMode(QGraphicsView::RubberBandDrag);
124  else
125  setDragMode(QGraphicsView::NoDrag);
126 
127  m_lastMousePos = event->pos();
128  m_lastMousePosScene = mapToScene(event->pos());
129 
130  if (forwardEvent)
131  QGraphicsView::mousePressEvent(event);
132 }
133 
134 void ArenaView::mouseMoveEvent(QMouseEvent *event)
135 {
136  if (!arenaScene())
137  return;
138 
139  bool forwardEvent = true;
140 
141  if (event->buttons() & Qt::LeftButton && !m_rubberBandActive)
142  {
143  QPointF mousePos = mapToScene(event->pos());
144  QList<ArenaSceneElement*> selectedElements = arenaScene()->selectedElements();
145 
147  {
148  dragStarted();
149  m_controller->startDrag(selectedElements);
150  }
151 
152  // In this case, we will move the selected element directly to the
153  // position of the mouse cursor
154  if (selectedElements.count() == 1 &&
155  !selectedElements.first()->element()->isItem())
156  {
157  m_controller->dragTo(mousePos);
158  }
159  else
160  {
161  // Offset the mouse has been moved by
162  QPointF offset = mousePos - m_lastMousePosScene;
163  m_controller->dragBy(offset);
164  }
165 
166  forwardEvent = false;
167  }
168  else if (event->buttons() & Qt::RightButton)
169  {
170  QPoint diff = event->pos() - m_lastMousePos;
171 
172  int oldX = horizontalScrollBar()->value();
173  int oldY = verticalScrollBar()->value();
174  horizontalScrollBar()->setValue(oldX - diff.x());
175  verticalScrollBar()->setValue(oldY - diff.y());
176  }
177 
178  m_lastMousePos = event->pos();
179  m_lastMousePosScene = mapToScene(event->pos());
180 
181  if (forwardEvent)
182  QGraphicsView::mouseMoveEvent(event);
183 }
184 
185 void ArenaView::mouseReleaseEvent(QMouseEvent *event)
186 {
187  QGraphicsView::mouseReleaseEvent(event);
188  m_rubberBandActive = false;
190  {
192  // Update to make controller handles disappear
193  update();
194  }
195 
196  dragEnded();
197 }
198 
200 {
201  return dynamic_cast<ArenaScene*>(scene());
202 }
203 
204 void ArenaView::wheelEvent(QWheelEvent *event)
205 {
206  if (event->delta() > 0)
207  slotZoomIn();
208  else
209  slotZoomOut();
210 }
211 
212 #define MIN_SCALE 0.1
213 #define MAX_SCALE 5.0
214 
216 {
217  QTransform trans = transform().scale(2.0, 2.0);
218  if (trans.m11() <= MAX_SCALE || trans.m22() <= MAX_SCALE)
219  setTransform(trans);
220 }
221 
223 {
224  QTransform trans = transform().scale(0.5, 0.5);
225  if (trans.m11() >= MIN_SCALE || trans.m22() >= MIN_SCALE)
226  setTransform(trans);
227 }
228 
230 {
231  // Do not change visible scene rect while an element is being inserted
232  if (scene())
233  setSceneRect(scene()->sceneRect());
234 }
235 
237 {
238  // Change scene rect with scene again
239  setSceneRect(QRectF());
240 }
241 
242 
243 void ArenaView::dragEnterEvent(QDragEnterEvent *event)
244 {
245  dragStarted();
246 
247  QString elementTypeName = event->mimeData()->data("type");
248  m_controller->startInsertion(elementTypeName, mapToScene(event->pos()));
249 
250  event->accept();
251 }
252 
253 void ArenaView::dragLeaveEvent(QDragLeaveEvent *event)
254 {
256  event->accept();
257 
258  dragEnded();
259 }
260 
261 void ArenaView::dragMoveEvent(QDragMoveEvent *event)
262 {
263  m_controller->dragTo(mapToScene(event->pos()));
264  event->accept();
265 }
266 
267 void ArenaView::dropEvent(QDropEvent *event)
268 {
269  event->accept();
271  // Make controller handles disappear
272  update();
273  dragEnded();
274  //QGraphicsScene::dropEvent(event);
275 }
bool m_rubberBandActive
Definition: arenaview.h:51
void mouseReleaseEvent(QMouseEvent *event)
Definition: arenaview.cpp:185
#define MAX_SCALE
Definition: arenaview.cpp:213
void dragEnded()
Definition: arenaview.cpp:236
ArenaController * m_controller
Definition: arenaview.h:54
ArenaElementType const * type() const
Definition: arenaelement.h:43
void dropEvent(QDropEvent *event)
Definition: arenaview.cpp:267
QList< ArenaSceneElement * > selectedElements()
Definition: arenascene.cpp:61
bool operationInProgress() const
void drawCross(QPainter *painter, QPoint p, int lineLength)
Definition: arenaview.cpp:25
void draw(QPainter *painter, const QRectF &rect)
const int ITEM_SIZE
Definition: arenascene.h:13
void mouseMoveEvent(QMouseEvent *event)
Definition: arenaview.cpp:134
void dragTo(const QPointF &to)
void slotGridPaintingDisabled()
Definition: arenaview.cpp:31
void wheelEvent(QWheelEvent *event)
Definition: arenaview.cpp:204
#define MIN_SCALE
Definition: arenaview.cpp:212
ArenaElement * element() const
const int SPACING
Definition: arenascene.h:14
void dragBy(const QPointF &by)
const int CELL_SIZE
Definition: arenascene.h:15
ArenaView(ArenaController *controller, QWidget *parent=0)
Definition: arenaview.cpp:15
void drawBackground(QPainter *painter, const QRectF &rect)
Definition: arenaview.cpp:37
void dragStarted()
Definition: arenaview.cpp:229
void slotZoomOut()
Definition: arenaview.cpp:222
QPointF m_lastMousePosScene
Definition: arenaview.h:53
static QPointF nearestGridPoint(QPointF scenePos)
Definition: arenascene.cpp:56
void dragLeaveEvent(QDragLeaveEvent *event)
Definition: arenaview.cpp:253
void drawForeground(QPainter *painter, const QRectF &rect)
Definition: arenaview.cpp:97
ArenaScene * arenaScene()
Definition: arenaview.cpp:199
void mousePressEvent(QMouseEvent *event)
Definition: arenaview.cpp:102
void startInsertion(const QString &elementType, const QPointF &pos)
void slotZoomIn()
Definition: arenaview.cpp:215
void dragMoveEvent(QDragMoveEvent *event)
Definition: arenaview.cpp:261
void dragEnterEvent(QDragEnterEvent *event)
Definition: arenaview.cpp:243
QString name() const
void startDrag(ArenaSceneElement *sceneElement)
QPoint m_lastMousePos
Definition: arenaview.h:52


hector_nist_arena_designer
Author(s): Stefan Kohlbrecher , Johannes Simon
autogenerated on Fri Aug 21 2020 10:45:27