mapview.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  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;
  432. std::map<int, std::pair<int, int>> selectionRangeMapY;
  433. for(auto & t : sc->selectionTerrainView.selection())
  434. {
  435. auto pairIter = selectionRangeMapX.find(t.y);
  436. if(pairIter == selectionRangeMapX.end())
  437. selectionRangeMapX[t.y] = std::make_pair(t.x, t.x);
  438. else
  439. {
  440. pairIter->second.first = std::min(pairIter->second.first, t.x);
  441. pairIter->second.second = std::max(pairIter->second.second, t.x);
  442. }
  443. pairIter = selectionRangeMapY.find(t.x);
  444. if(pairIter == selectionRangeMapY.end())
  445. selectionRangeMapY[t.x] = std::make_pair(t.y, t.y);
  446. else
  447. {
  448. pairIter->second.first = std::min(pairIter->second.first, t.y);
  449. pairIter->second.second = std::max(pairIter->second.second, t.y);
  450. }
  451. }
  452. std::set<int3> selectionByX;
  453. std::set<int3> selectionByY;
  454. std::vector<int3> finalSelection;
  455. for(auto & selectionRange : selectionRangeMapX)
  456. {
  457. for(int i = selectionRange.second.first; i < selectionRange.second.second; ++i)
  458. selectionByX.insert(int3(i, selectionRange.first, sc->level));
  459. }
  460. for(auto & selectionRange : selectionRangeMapY)
  461. {
  462. for(int i = selectionRange.second.first; i < selectionRange.second.second; ++i)
  463. selectionByY.insert(int3(selectionRange.first, i, sc->level));
  464. }
  465. std::set_intersection(selectionByX.begin(), selectionByX.end(), selectionByY.begin(), selectionByY.end(), std::back_inserter(finalSelection));
  466. for(auto & lassoTile : finalSelection)
  467. sc->selectionTerrainView.select(lassoTile);
  468. sc->selectionTerrainView.draw();
  469. break;
  470. }
  471. case MapView::SelectionTool::Line:
  472. temporaryTiles.clear();
  473. break;
  474. case MapView::SelectionTool::None:
  475. if(event->button() == Qt::RightButton)
  476. break;
  477. //switch position
  478. bool tab = false;
  479. if(sc->selectionObjectsView.selectionMode == SelectionObjectsLayer::MOVEMENT)
  480. {
  481. tab = sc->selectionObjectsView.shift.isNull();
  482. controller->commitObjectShift(sc->level);
  483. }
  484. else
  485. {
  486. sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::NOTHING;
  487. sc->selectionObjectsView.shift = QPoint(0, 0);
  488. sc->selectionObjectsView.draw();
  489. tab = true;
  490. }
  491. auto selection = sc->selectionObjectsView.getSelection();
  492. if(selection.size() == 1)
  493. {
  494. emit openObjectProperties(*selection.begin(), tab);
  495. }
  496. break;
  497. }
  498. }
  499. void MapView::dragEnterEvent(QDragEnterEvent * event)
  500. {
  501. if(!controller || !controller->map())
  502. return;
  503. auto * sc = static_cast<MapScene*>(scene());
  504. if(!sc)
  505. return;
  506. if(event->mimeData()->hasImage())
  507. {
  508. logGlobal->info("Drag'n'drop: dispatching object");
  509. QVariant vdata = event->mimeData()->imageData();
  510. auto data = vdata.toJsonObject();
  511. if(!data.empty())
  512. {
  513. auto preview = data["preview"];
  514. if(preview != QJsonValue::Undefined)
  515. {
  516. auto objId = data["id"].toInt();
  517. auto objSubId = data["subid"].toInt();
  518. auto templateId = data["template"].toInt();
  519. auto factory = VLC->objtypeh->getHandlerFor(objId, objSubId);
  520. auto templ = factory->getTemplates()[templateId];
  521. controller->discardObject(sc->level);
  522. controller->createObject(sc->level, factory->create(nullptr, templ));
  523. }
  524. }
  525. event->acceptProposedAction();
  526. }
  527. }
  528. void MapView::dropEvent(QDropEvent * event)
  529. {
  530. if(!controller || !controller->map())
  531. return;
  532. auto * sc = static_cast<MapScene*>(scene());
  533. if(!sc)
  534. return;
  535. if(sc->selectionObjectsView.newObject)
  536. {
  537. QString errorMsg;
  538. if(controller->canPlaceObject(sc->level, sc->selectionObjectsView.newObject, errorMsg))
  539. {
  540. auto * obj = sc->selectionObjectsView.newObject;
  541. controller->commitObjectCreate(sc->level);
  542. emit openObjectProperties(obj, false);
  543. }
  544. else
  545. {
  546. controller->discardObject(sc->level);
  547. QMessageBox::information(this, tr("Can't place object"), errorMsg);
  548. }
  549. }
  550. event->acceptProposedAction();
  551. }
  552. void MapView::dragMoveEvent(QDragMoveEvent * event)
  553. {
  554. auto * sc = static_cast<MapScene*>(scene());
  555. if(!sc)
  556. return;
  557. auto rect = event->answerRect();
  558. auto pos = mapToScene(rect.bottomRight()); //TODO: do we need to check size?
  559. int3 tile(pos.x() / 32 + 1, pos.y() / 32 + 1, sc->level);
  560. if(sc->selectionObjectsView.newObject)
  561. {
  562. sc->selectionObjectsView.shift = QPoint(tile.x, tile.y);
  563. sc->selectionObjectsView.selectObject(sc->selectionObjectsView.newObject);
  564. sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::MOVEMENT;
  565. sc->selectionObjectsView.draw();
  566. }
  567. event->acceptProposedAction();
  568. }
  569. void MapView::dragLeaveEvent(QDragLeaveEvent * event)
  570. {
  571. if(!controller || !controller->map())
  572. return;
  573. auto * sc = static_cast<MapScene*>(scene());
  574. if(!sc)
  575. return;
  576. controller->discardObject(sc->level);
  577. }
  578. bool MapView::viewportEvent(QEvent *event)
  579. {
  580. if(auto * sc = static_cast<MapScene*>(scene()))
  581. {
  582. auto rect = mapToScene(viewport()->geometry()).boundingRect();
  583. controller->miniScene(sc->level)->viewport.setViewport(rect.x() / 32, rect.y() / 32, rect.width() / 32, rect.height() / 32);
  584. }
  585. return QGraphicsView::viewportEvent(event);
  586. }
  587. MapSceneBase::MapSceneBase(int lvl):
  588. QGraphicsScene(nullptr),
  589. level(lvl)
  590. {
  591. }
  592. void MapSceneBase::initialize(MapController & controller)
  593. {
  594. for(auto * layer : getAbstractLayers())
  595. layer->initialize(controller);
  596. }
  597. void MapSceneBase::updateViews()
  598. {
  599. for(auto * layer : getAbstractLayers())
  600. layer->update();
  601. }
  602. MapScene::MapScene(int lvl):
  603. MapSceneBase(lvl),
  604. gridView(this),
  605. passabilityView(this),
  606. selectionTerrainView(this),
  607. terrainView(this),
  608. objectsView(this),
  609. selectionObjectsView(this),
  610. objectPickerView(this),
  611. isTerrainSelected(false),
  612. isObjectSelected(false)
  613. {
  614. connect(&selectionTerrainView, &SelectionTerrainLayer::selectionMade, this, &MapScene::terrainSelected);
  615. connect(&selectionObjectsView, &SelectionObjectsLayer::selectionMade, this, &MapScene::objectSelected);
  616. }
  617. std::list<AbstractLayer *> MapScene::getAbstractLayers()
  618. {
  619. //sequence is important because it defines rendering order
  620. return {
  621. &terrainView,
  622. &objectsView,
  623. &gridView,
  624. &passabilityView,
  625. &objectPickerView,
  626. &selectionTerrainView,
  627. &selectionObjectsView
  628. };
  629. }
  630. void MapScene::updateViews()
  631. {
  632. MapSceneBase::updateViews();
  633. terrainView.show(true);
  634. objectsView.show(true);
  635. selectionTerrainView.show(true);
  636. selectionObjectsView.show(true);
  637. objectPickerView.show(true);
  638. }
  639. void MapScene::terrainSelected(bool anythingSelected)
  640. {
  641. isTerrainSelected = anythingSelected;
  642. emit selected(isTerrainSelected || isObjectSelected);
  643. }
  644. void MapScene::objectSelected(bool anythingSelected)
  645. {
  646. isObjectSelected = anythingSelected;
  647. emit selected(isTerrainSelected || isObjectSelected);
  648. }
  649. MinimapScene::MinimapScene(int lvl):
  650. MapSceneBase(lvl),
  651. minimapView(this),
  652. viewport(this)
  653. {
  654. }
  655. std::list<AbstractLayer *> MinimapScene::getAbstractLayers()
  656. {
  657. //sequence is important because it defines rendering order
  658. return {
  659. &minimapView,
  660. &viewport
  661. };
  662. }
  663. void MinimapScene::updateViews()
  664. {
  665. MapSceneBase::updateViews();
  666. minimapView.show(true);
  667. viewport.show(true);
  668. }