mapview.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. /*
  2. * mapview.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "mapview.h"
  12. #include "mainwindow.h"
  13. #include <QGraphicsSceneMouseEvent>
  14. #include "mapcontroller.h"
  15. #include "../lib/mapObjectConstructors/AObjectTypeHandler.h"
  16. #include "../lib/mapObjectConstructors/CObjectClassesHandler.h"
  17. #include "../lib/mapping/CMap.h"
  18. MinimapView::MinimapView(QWidget * parent):
  19. QGraphicsView(parent)
  20. {
  21. // Disable scrollbars
  22. setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  23. setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  24. }
  25. void MinimapView::dimensions()
  26. {
  27. fitInView(0, 0, controller->map()->width, controller->map()->height, Qt::KeepAspectRatio);
  28. }
  29. void MinimapView::setController(MapController * ctrl)
  30. {
  31. controller = ctrl;
  32. }
  33. void MinimapView::mouseMoveEvent(QMouseEvent *mouseEvent)
  34. {
  35. this->update();
  36. auto * sc = static_cast<MinimapScene*>(scene());
  37. if(!sc)
  38. return;
  39. auto pos = mapToScene(mouseEvent->pos());
  40. pos *= 32;
  41. emit cameraPositionChanged(pos);
  42. }
  43. void MinimapView::mousePressEvent(QMouseEvent* event)
  44. {
  45. mouseMoveEvent(event);
  46. }
  47. MapView::MapView(QWidget * parent):
  48. QGraphicsView(parent),
  49. selectionTool(MapView::SelectionTool::None)
  50. {
  51. }
  52. void MapView::cameraChanged(const QPointF & pos)
  53. {
  54. centerOn(pos);
  55. }
  56. void MapView::setController(MapController * ctrl)
  57. {
  58. controller = ctrl;
  59. }
  60. void MapView::mouseMoveEvent(QMouseEvent *mouseEvent)
  61. {
  62. this->update();
  63. auto * sc = static_cast<MapScene*>(scene());
  64. if(!sc || !controller->map())
  65. return;
  66. auto pos = mapToScene(mouseEvent->pos()); //TODO: do we need to check size?
  67. int3 tile(pos.x() / 32, pos.y() / 32, sc->level);
  68. //if scene will be scrolled without mouse movement, selection, object moving and rubber band will not be updated
  69. //to change this behavior, all this logic should be placed in viewportEvent
  70. if(rubberBand)
  71. rubberBand->setGeometry(QRect(mapFromScene(mouseStart), mouseEvent->pos()).normalized());
  72. if(tile == tilePrev) //do not redraw
  73. return;
  74. tilePrev = tile;
  75. emit currentCoordinates(tile.x, tile.y);
  76. switch(selectionTool)
  77. {
  78. case MapView::SelectionTool::Brush:
  79. if(mouseEvent->buttons() & Qt::RightButton)
  80. sc->selectionTerrainView.erase(tile);
  81. else if(mouseEvent->buttons() == Qt::LeftButton)
  82. sc->selectionTerrainView.select(tile);
  83. sc->selectionTerrainView.draw();
  84. break;
  85. case MapView::SelectionTool::Brush2:
  86. {
  87. std::array<int3, 4> extra{ int3{0, 0, 0}, int3{1, 0, 0}, int3{0, 1, 0}, int3{1, 1, 0} };
  88. for(auto & e : extra)
  89. {
  90. if(mouseEvent->buttons() & Qt::RightButton)
  91. sc->selectionTerrainView.erase(tile + e);
  92. else if(mouseEvent->buttons() == Qt::LeftButton)
  93. sc->selectionTerrainView.select(tile + e);
  94. }
  95. }
  96. sc->selectionTerrainView.draw();
  97. break;
  98. case MapView::SelectionTool::Brush4:
  99. {
  100. std::array<int3, 16> extra{
  101. int3{-1, -1, 0}, int3{0, -1, 0}, int3{1, -1, 0}, int3{2, -1, 0},
  102. int3{-1, 0, 0}, int3{0, 0, 0}, int3{1, 0, 0}, int3{2, 0, 0},
  103. int3{-1, 1, 0}, int3{0, 1, 0}, int3{1, 1, 0}, int3{2, 1, 0},
  104. int3{-1, 2, 0}, int3{0, 2, 0}, int3{1, 2, 0}, int3{2, 2, 0}
  105. };
  106. for(auto & e : extra)
  107. {
  108. if(mouseEvent->buttons() & Qt::RightButton)
  109. sc->selectionTerrainView.erase(tile + e);
  110. else if(mouseEvent->buttons() == Qt::LeftButton)
  111. sc->selectionTerrainView.select(tile + e);
  112. }
  113. }
  114. sc->selectionTerrainView.draw();
  115. break;
  116. case MapView::SelectionTool::Area:
  117. if(mouseEvent->buttons() & Qt::RightButton || !(mouseEvent->buttons() & Qt::LeftButton))
  118. break;
  119. sc->selectionTerrainView.clear();
  120. for(int j = std::min(tile.y, tileStart.y); j < std::max(tile.y, tileStart.y); ++j)
  121. {
  122. for(int i = std::min(tile.x, tileStart.x); i < std::max(tile.x, tileStart.x); ++i)
  123. {
  124. sc->selectionTerrainView.select(int3(i, j, sc->level));
  125. }
  126. }
  127. sc->selectionTerrainView.draw();
  128. break;
  129. case MapView::SelectionTool::Line:
  130. {
  131. assert(tile.z == tileStart.z);
  132. const auto diff = tile - tileStart;
  133. if(diff == int3{})
  134. break;
  135. const int edge = std::max(abs(diff.x), abs(diff.y));
  136. int distMin = std::numeric_limits<int>::max();
  137. int3 dir;
  138. for(auto & d : int3::getDirs())
  139. {
  140. if(tile.dist2d(d * edge + tileStart) < distMin)
  141. {
  142. distMin = tile.dist2d(d * edge + tileStart);
  143. dir = d;
  144. }
  145. }
  146. assert(dir != int3{});
  147. if(mouseEvent->buttons() == Qt::LeftButton)
  148. {
  149. for(auto & ts : temporaryTiles)
  150. sc->selectionTerrainView.erase(ts);
  151. for(auto ts = tileStart; ts.dist2d(tileStart) < edge; ts += dir)
  152. {
  153. if(!controller->map()->isInTheMap(ts))
  154. break;
  155. if(!sc->selectionTerrainView.selection().count(ts))
  156. temporaryTiles.insert(ts);
  157. sc->selectionTerrainView.select(ts);
  158. }
  159. }
  160. if(mouseEvent->buttons() == Qt::RightButton)
  161. {
  162. for(auto & ts : temporaryTiles)
  163. sc->selectionTerrainView.select(ts);
  164. for(auto ts = tileStart; ts.dist2d(tileStart) < edge; ts += dir)
  165. {
  166. if(!controller->map()->isInTheMap(ts))
  167. break;
  168. if(sc->selectionTerrainView.selection().count(ts))
  169. temporaryTiles.insert(ts);
  170. sc->selectionTerrainView.erase(ts);
  171. }
  172. }
  173. sc->selectionTerrainView.draw();
  174. break;
  175. }
  176. case MapView::SelectionTool::Lasso:
  177. if(mouseEvent->buttons() == Qt::LeftButton)
  178. {
  179. sc->selectionTerrainView.select(tile);
  180. sc->selectionTerrainView.draw();
  181. }
  182. break;
  183. case MapView::SelectionTool::None:
  184. if(mouseEvent->buttons() & Qt::RightButton)
  185. break;
  186. auto sh = tile - tileStart;
  187. sc->selectionObjectsView.shift = QPoint(sh.x, sh.y);
  188. if(sh.x || sh.y)
  189. {
  190. if(!sc->selectionObjectsView.newObject && (mouseEvent->buttons() & Qt::LeftButton))
  191. {
  192. if(sc->selectionObjectsView.selectionMode == SelectionObjectsLayer::SELECTION)
  193. {
  194. sc->selectionObjectsView.clear();
  195. sc->selectionObjectsView.selectObjects(tileStart.x, tileStart.y, tile.x, tile.y);
  196. }
  197. }
  198. }
  199. sc->selectionObjectsView.draw();
  200. break;
  201. }
  202. }
  203. void MapView::mousePressEvent(QMouseEvent *event)
  204. {
  205. this->update();
  206. auto * sc = static_cast<MapScene*>(scene());
  207. if(!sc || !controller->map())
  208. return;
  209. if(sc->objectPickerView.isVisible())
  210. return;
  211. mouseStart = mapToScene(event->pos());
  212. tileStart = tilePrev = int3(mouseStart.x() / 32, mouseStart.y() / 32, sc->level);
  213. if(sc->selectionTerrainView.selection().count(tileStart))
  214. pressedOnSelected = true;
  215. else
  216. pressedOnSelected = false;
  217. switch(selectionTool)
  218. {
  219. case MapView::SelectionTool::Brush:
  220. case MapView::SelectionTool::Line:
  221. sc->selectionObjectsView.clear();
  222. sc->selectionObjectsView.draw();
  223. if(event->button() == Qt::RightButton)
  224. sc->selectionTerrainView.erase(tileStart);
  225. else if(event->button() == Qt::LeftButton)
  226. sc->selectionTerrainView.select(tileStart);
  227. sc->selectionTerrainView.draw();
  228. break;
  229. case MapView::SelectionTool::Brush2:
  230. sc->selectionObjectsView.clear();
  231. sc->selectionObjectsView.draw();
  232. {
  233. std::array<int3, 4> extra{ int3{0, 0, 0}, int3{1, 0, 0}, int3{0, 1, 0}, int3{1, 1, 0} };
  234. for(auto & e : extra)
  235. {
  236. if(event->button() == Qt::RightButton)
  237. sc->selectionTerrainView.erase(tileStart + e);
  238. else if(event->button() == Qt::LeftButton)
  239. sc->selectionTerrainView.select(tileStart + e);
  240. }
  241. }
  242. sc->selectionTerrainView.draw();
  243. break;
  244. case MapView::SelectionTool::Brush4:
  245. sc->selectionObjectsView.clear();
  246. sc->selectionObjectsView.draw();
  247. {
  248. std::array<int3, 16> extra{
  249. int3{-1, -1, 0}, int3{0, -1, 0}, int3{1, -1, 0}, int3{2, -1, 0},
  250. int3{-1, 0, 0}, int3{0, 0, 0}, int3{1, 0, 0}, int3{2, 0, 0},
  251. int3{-1, 1, 0}, int3{0, 1, 0}, int3{1, 1, 0}, int3{2, 1, 0},
  252. int3{-1, 2, 0}, int3{0, 2, 0}, int3{1, 2, 0}, int3{2, 2, 0}
  253. };
  254. for(auto & e : extra)
  255. {
  256. if(event->button() == Qt::RightButton)
  257. sc->selectionTerrainView.erase(tileStart + e);
  258. else if(event->button() == Qt::LeftButton)
  259. sc->selectionTerrainView.select(tileStart + e);
  260. }
  261. }
  262. sc->selectionTerrainView.draw();
  263. break;
  264. case MapView::SelectionTool::Area:
  265. case MapView::SelectionTool::Lasso:
  266. if(event->button() == Qt::RightButton)
  267. break;
  268. sc->selectionTerrainView.clear();
  269. sc->selectionTerrainView.draw();
  270. sc->selectionObjectsView.clear();
  271. sc->selectionObjectsView.draw();
  272. break;
  273. case MapView::SelectionTool::Fill:
  274. {
  275. if(event->button() != Qt::RightButton && event->button() != Qt::LeftButton)
  276. break;
  277. std::vector<int3> queue;
  278. queue.push_back(tileStart);
  279. const std::array<int3, 4> dirs{ int3{1, 0, 0}, int3{-1, 0, 0}, int3{0, 1, 0}, int3{0, -1, 0} };
  280. while(!queue.empty())
  281. {
  282. auto tile = queue.back();
  283. queue.pop_back();
  284. if(event->button() == Qt::LeftButton)
  285. sc->selectionTerrainView.select(tile);
  286. else
  287. sc->selectionTerrainView.erase(tile);
  288. for(auto & d : dirs)
  289. {
  290. auto tilen = tile + d;
  291. if(!controller->map()->isInTheMap(tilen))
  292. continue;
  293. if(event->button() == Qt::LeftButton)
  294. {
  295. if(controller->map()->getTile(tile).roadType
  296. && controller->map()->getTile(tile).roadType != controller->map()->getTile(tilen).roadType)
  297. continue;
  298. else if(controller->map()->getTile(tile).riverType
  299. && controller->map()->getTile(tile).riverType != controller->map()->getTile(tilen).riverType)
  300. continue;
  301. else if(controller->map()->getTile(tile).terType != controller->map()->getTile(tilen).terType)
  302. continue;
  303. }
  304. if(event->button() == Qt::LeftButton && sc->selectionTerrainView.selection().count(tilen))
  305. continue;
  306. if(event->button() == Qt::RightButton && !sc->selectionTerrainView.selection().count(tilen))
  307. continue;
  308. queue.push_back(tilen);
  309. }
  310. }
  311. sc->selectionTerrainView.draw();
  312. sc->selectionObjectsView.clear();
  313. sc->selectionObjectsView.draw();
  314. break;
  315. }
  316. case MapView::SelectionTool::None:
  317. sc->selectionTerrainView.clear();
  318. sc->selectionTerrainView.draw();
  319. if(sc->selectionObjectsView.newObject && sc->selectionObjectsView.isSelected(sc->selectionObjectsView.newObject))
  320. {
  321. if(event->button() == Qt::RightButton)
  322. controller->discardObject(sc->level);
  323. }
  324. else
  325. {
  326. if(event->button() == Qt::LeftButton)
  327. {
  328. //when paste, new object could be beyond initial object so we need to test two objects in order to select new one
  329. //if object is pasted at place where is multiple objects then proper selection is not guaranteed
  330. auto * firstSelectedObject = sc->selectionObjectsView.selectObjectAt(tileStart.x, tileStart.y);
  331. auto * secondSelectedObject = sc->selectionObjectsView.selectObjectAt(tileStart.x, tileStart.y, firstSelectedObject);
  332. if(firstSelectedObject)
  333. {
  334. if(sc->selectionObjectsView.isSelected(firstSelectedObject))
  335. {
  336. if(qApp->keyboardModifiers() & Qt::ControlModifier)
  337. {
  338. sc->selectionObjectsView.deselectObject(firstSelectedObject);
  339. sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::SELECTION;
  340. }
  341. else
  342. sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::MOVEMENT;
  343. }
  344. else
  345. {
  346. if(!secondSelectedObject || !sc->selectionObjectsView.isSelected(secondSelectedObject))
  347. {
  348. if(!(qApp->keyboardModifiers() & Qt::ControlModifier))
  349. sc->selectionObjectsView.clear();
  350. sc->selectionObjectsView.selectObject(firstSelectedObject);
  351. }
  352. sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::MOVEMENT;
  353. }
  354. }
  355. else
  356. {
  357. sc->selectionObjectsView.clear();
  358. sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::SELECTION;
  359. if(!rubberBand)
  360. rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
  361. rubberBand->setGeometry(QRect(mapFromScene(mouseStart), QSize()));
  362. rubberBand->show();
  363. }
  364. }
  365. sc->selectionObjectsView.shift = QPoint(0, 0);
  366. sc->selectionObjectsView.draw();
  367. }
  368. break;
  369. }
  370. //main->setStatusMessage(QString("x: %1 y: %2").arg(QString::number(event->pos().x()), QString::number(event->pos().y())));
  371. }
  372. void MapView::mouseReleaseEvent(QMouseEvent *event)
  373. {
  374. this->update();
  375. auto * sc = static_cast<MapScene*>(scene());
  376. if(!sc || !controller->map())
  377. return;
  378. if(rubberBand)
  379. rubberBand->hide();
  380. if(sc->objectPickerView.isVisible())
  381. {
  382. if(event->button() == Qt::RightButton)
  383. sc->objectPickerView.discard();
  384. if(event->button() == Qt::LeftButton)
  385. {
  386. mouseStart = mapToScene(event->pos());
  387. tileStart = tilePrev = int3(mouseStart.x() / 32, mouseStart.y() / 32, sc->level);
  388. if(auto * pickedObject = sc->selectionObjectsView.selectObjectAt(tileStart.x, tileStart.y))
  389. sc->objectPickerView.select(pickedObject);
  390. }
  391. return;
  392. }
  393. switch(selectionTool)
  394. {
  395. case MapView::SelectionTool::Lasso: {
  396. if(event->button() == Qt::RightButton)
  397. break;
  398. //key: y position of tile
  399. //value.first: x position of left tile
  400. //value.second: x postiion of right tile
  401. std::map<int, std::pair<int, int>> selectionRangeMapX, selectionRangeMapY;
  402. for(auto & t : sc->selectionTerrainView.selection())
  403. {
  404. auto pairIter = selectionRangeMapX.find(t.y);
  405. if(pairIter == selectionRangeMapX.end())
  406. selectionRangeMapX[t.y] = std::make_pair(t.x, t.x);
  407. else
  408. {
  409. pairIter->second.first = std::min(pairIter->second.first, t.x);
  410. pairIter->second.second = std::max(pairIter->second.second, t.x);
  411. }
  412. pairIter = selectionRangeMapY.find(t.x);
  413. if(pairIter == selectionRangeMapY.end())
  414. selectionRangeMapY[t.x] = std::make_pair(t.y, t.y);
  415. else
  416. {
  417. pairIter->second.first = std::min(pairIter->second.first, t.y);
  418. pairIter->second.second = std::max(pairIter->second.second, t.y);
  419. }
  420. }
  421. std::set<int3> selectionByX, selectionByY;
  422. std::vector<int3> finalSelection;
  423. for(auto & selectionRange : selectionRangeMapX)
  424. {
  425. for(int i = selectionRange.second.first; i < selectionRange.second.second; ++i)
  426. selectionByX.insert(int3(i, selectionRange.first, sc->level));
  427. }
  428. for(auto & selectionRange : selectionRangeMapY)
  429. {
  430. for(int i = selectionRange.second.first; i < selectionRange.second.second; ++i)
  431. selectionByY.insert(int3(selectionRange.first, i, sc->level));
  432. }
  433. std::set_intersection(selectionByX.begin(), selectionByX.end(), selectionByY.begin(), selectionByY.end(), std::back_inserter(finalSelection));
  434. for(auto & lassoTile : finalSelection)
  435. sc->selectionTerrainView.select(lassoTile);
  436. sc->selectionTerrainView.draw();
  437. break;
  438. }
  439. case MapView::SelectionTool::Line:
  440. temporaryTiles.clear();
  441. break;
  442. case MapView::SelectionTool::None:
  443. if(event->button() == Qt::RightButton)
  444. break;
  445. //switch position
  446. bool tab = false;
  447. if(sc->selectionObjectsView.selectionMode == SelectionObjectsLayer::MOVEMENT)
  448. {
  449. tab = sc->selectionObjectsView.shift.isNull();
  450. controller->commitObjectShift(sc->level);
  451. }
  452. else
  453. {
  454. sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::NOTHING;
  455. sc->selectionObjectsView.shift = QPoint(0, 0);
  456. sc->selectionObjectsView.draw();
  457. tab = true;
  458. }
  459. auto selection = sc->selectionObjectsView.getSelection();
  460. if(selection.size() == 1)
  461. {
  462. emit openObjectProperties(*selection.begin(), tab);
  463. }
  464. break;
  465. }
  466. }
  467. void MapView::dragEnterEvent(QDragEnterEvent * event)
  468. {
  469. if(!controller || !controller->map())
  470. return;
  471. auto * sc = static_cast<MapScene*>(scene());
  472. if(!sc)
  473. return;
  474. if(event->mimeData()->hasImage())
  475. {
  476. logGlobal->info("Drag'n'drop: dispatching object");
  477. QVariant vdata = event->mimeData()->imageData();
  478. auto data = vdata.toJsonObject();
  479. if(!data.empty())
  480. {
  481. auto preview = data["preview"];
  482. if(preview != QJsonValue::Undefined)
  483. {
  484. auto objId = data["id"].toInt();
  485. auto objSubId = data["subid"].toInt();
  486. auto templateId = data["template"].toInt();
  487. auto factory = VLC->objtypeh->getHandlerFor(objId, objSubId);
  488. auto templ = factory->getTemplates()[templateId];
  489. controller->discardObject(sc->level);
  490. controller->createObject(sc->level, factory->create(templ));
  491. }
  492. }
  493. event->acceptProposedAction();
  494. }
  495. }
  496. void MapView::dropEvent(QDropEvent * event)
  497. {
  498. if(!controller || !controller->map())
  499. return;
  500. auto * sc = static_cast<MapScene*>(scene());
  501. if(!sc)
  502. return;
  503. if(sc->selectionObjectsView.newObject)
  504. {
  505. QString errorMsg;
  506. if(controller->canPlaceObject(sc->level, sc->selectionObjectsView.newObject, errorMsg))
  507. {
  508. auto * obj = sc->selectionObjectsView.newObject;
  509. controller->commitObjectCreate(sc->level);
  510. emit openObjectProperties(obj, false);
  511. }
  512. else
  513. {
  514. controller->discardObject(sc->level);
  515. QMessageBox::information(this, tr("Can't place object"), errorMsg);
  516. }
  517. }
  518. event->acceptProposedAction();
  519. }
  520. void MapView::dragMoveEvent(QDragMoveEvent * event)
  521. {
  522. auto * sc = static_cast<MapScene*>(scene());
  523. if(!sc)
  524. return;
  525. auto rect = event->answerRect();
  526. auto pos = mapToScene(rect.bottomRight()); //TODO: do we need to check size?
  527. int3 tile(pos.x() / 32 + 1, pos.y() / 32 + 1, sc->level);
  528. if(sc->selectionObjectsView.newObject)
  529. {
  530. sc->selectionObjectsView.shift = QPoint(tile.x, tile.y);
  531. sc->selectionObjectsView.selectObject(sc->selectionObjectsView.newObject);
  532. sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::MOVEMENT;
  533. sc->selectionObjectsView.draw();
  534. }
  535. event->acceptProposedAction();
  536. }
  537. void MapView::dragLeaveEvent(QDragLeaveEvent * event)
  538. {
  539. if(!controller || !controller->map())
  540. return;
  541. auto * sc = static_cast<MapScene*>(scene());
  542. if(!sc)
  543. return;
  544. controller->discardObject(sc->level);
  545. }
  546. bool MapView::viewportEvent(QEvent *event)
  547. {
  548. if(auto * sc = static_cast<MapScene*>(scene()))
  549. {
  550. auto rect = mapToScene(viewport()->geometry()).boundingRect();
  551. controller->miniScene(sc->level)->viewport.setViewport(rect.x() / 32, rect.y() / 32, rect.width() / 32, rect.height() / 32);
  552. }
  553. return QGraphicsView::viewportEvent(event);
  554. }
  555. MapSceneBase::MapSceneBase(int lvl):
  556. QGraphicsScene(nullptr),
  557. level(lvl)
  558. {
  559. }
  560. void MapSceneBase::initialize(MapController & controller)
  561. {
  562. for(auto * layer : getAbstractLayers())
  563. layer->initialize(controller);
  564. }
  565. void MapSceneBase::updateViews()
  566. {
  567. for(auto * layer : getAbstractLayers())
  568. layer->update();
  569. }
  570. MapScene::MapScene(int lvl):
  571. MapSceneBase(lvl),
  572. gridView(this),
  573. passabilityView(this),
  574. selectionTerrainView(this),
  575. terrainView(this),
  576. objectsView(this),
  577. selectionObjectsView(this),
  578. objectPickerView(this),
  579. isTerrainSelected(false),
  580. isObjectSelected(false)
  581. {
  582. connect(&selectionTerrainView, &SelectionTerrainLayer::selectionMade, this, &MapScene::terrainSelected);
  583. connect(&selectionObjectsView, &SelectionObjectsLayer::selectionMade, this, &MapScene::objectSelected);
  584. }
  585. std::list<AbstractLayer *> MapScene::getAbstractLayers()
  586. {
  587. //sequence is important because it defines rendering order
  588. return {
  589. &terrainView,
  590. &objectsView,
  591. &gridView,
  592. &passabilityView,
  593. &objectPickerView,
  594. &selectionTerrainView,
  595. &selectionObjectsView
  596. };
  597. }
  598. void MapScene::updateViews()
  599. {
  600. MapSceneBase::updateViews();
  601. terrainView.show(true);
  602. objectsView.show(true);
  603. selectionTerrainView.show(true);
  604. selectionObjectsView.show(true);
  605. objectPickerView.show(true);
  606. }
  607. void MapScene::terrainSelected(bool anythingSelected)
  608. {
  609. isTerrainSelected = anythingSelected;
  610. emit selected(isTerrainSelected || isObjectSelected);
  611. }
  612. void MapScene::objectSelected(bool anythingSelected)
  613. {
  614. isObjectSelected = anythingSelected;
  615. emit selected(isTerrainSelected || isObjectSelected);
  616. }
  617. MinimapScene::MinimapScene(int lvl):
  618. MapSceneBase(lvl),
  619. minimapView(this),
  620. viewport(this)
  621. {
  622. }
  623. std::list<AbstractLayer *> MinimapScene::getAbstractLayers()
  624. {
  625. //sequence is important because it defines rendering order
  626. return {
  627. &minimapView,
  628. &viewport
  629. };
  630. }
  631. void MinimapScene::updateViews()
  632. {
  633. MapSceneBase::updateViews();
  634. minimapView.show(true);
  635. viewport.show(true);
  636. }