mapview.cpp 20 KB

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