Aucune description

mainwindow.cpp 31KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include "project.h"
  4. #include "editor.h"
  5. #include "objectpropertiesframe.h"
  6. #include "ui_objectpropertiesframe.h"
  7. #include <QDebug>
  8. #include <QFileDialog>
  9. #include <QStandardItemModel>
  10. #include <QShortcut>
  11. #include <QSettings>
  12. #include <QSpinBox>
  13. #include <QTextEdit>
  14. #include <QSpacerItem>
  15. #include <QFont>
  16. #include <QScrollBar>
  17. #include <QMessageBox>
  18. #include <QDialogButtonBox>
  19. MainWindow::MainWindow(QWidget *parent) :
  20. QMainWindow(parent),
  21. ui(new Ui::MainWindow)
  22. {
  23. QCoreApplication::setOrganizationName("pret");
  24. QCoreApplication::setApplicationName("pretmap");
  25. ui->setupUi(this);
  26. ui->newEventToolButton->initButton();
  27. connect(ui->newEventToolButton, SIGNAL(newEventAdded(QString)), this, SLOT(addNewEvent(QString)));
  28. new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z), this, SLOT(redo()));
  29. editor = new Editor(ui);
  30. connect(editor, SIGNAL(objectsChanged()), this, SLOT(updateSelectedObjects()));
  31. connect(editor, SIGNAL(selectedObjectsChanged()), this, SLOT(updateSelectedObjects()));
  32. connect(editor, SIGNAL(loadMapRequested(QString, QString)), this, SLOT(onLoadMapRequested(QString, QString)));
  33. connect(editor, SIGNAL(tilesetChanged(QString)), this, SLOT(onTilesetChanged(QString)));
  34. on_toolButton_Paint_clicked();
  35. QSettings settings;
  36. QString key = "recent_projects";
  37. if (settings.contains(key)) {
  38. QString default_dir = settings.value(key).toStringList().last();
  39. if (!default_dir.isNull()) {
  40. qDebug() << QString("default_dir: '%1'").arg(default_dir);
  41. openProject(default_dir);
  42. }
  43. }
  44. }
  45. MainWindow::~MainWindow()
  46. {
  47. delete ui;
  48. }
  49. void MainWindow::setStatusBarMessage(QString message, int timeout/* = 0*/) {
  50. statusBar()->showMessage(message, timeout);
  51. }
  52. void MainWindow::openProject(QString dir) {
  53. if (dir.isNull()) {
  54. return;
  55. }
  56. setStatusBarMessage(QString("Opening project %1").arg(dir));
  57. bool already_open = (
  58. (editor != NULL && editor != nullptr)
  59. && (editor->project != NULL && editor->project != nullptr)
  60. && (editor->project->root == dir)
  61. );
  62. if (!already_open) {
  63. editor->project = new Project;
  64. editor->project->root = dir;
  65. setWindowTitle(editor->project->getProjectTitle() + " - pretmap");
  66. loadDataStructures();
  67. populateMapList();
  68. setMap(getDefaultMap());
  69. } else {
  70. setWindowTitle(editor->project->getProjectTitle() + " - pretmap");
  71. loadDataStructures();
  72. populateMapList();
  73. }
  74. setStatusBarMessage(QString("Opened project %1").arg(dir));
  75. }
  76. QString MainWindow::getDefaultMap() {
  77. if (editor && editor->project) {
  78. QList<QStringList> names = editor->project->groupedMapNames;
  79. if (!names.isEmpty()) {
  80. QSettings settings;
  81. QString key = "project:" + editor->project->root;
  82. if (settings.contains(key)) {
  83. QMap<QString, QVariant> qmap = settings.value(key).toMap();
  84. if (qmap.contains("recent_map")) {
  85. QString map_name = qmap.value("recent_map").toString();
  86. for (int i = 0; i < names.length(); i++) {
  87. if (names.value(i).contains(map_name)) {
  88. return map_name;
  89. }
  90. }
  91. }
  92. }
  93. // Failing that, just get the first map in the list.
  94. for (int i = 0; i < names.length(); i++) {
  95. QStringList list = names.value(i);
  96. if (list.length()) {
  97. return list.value(0);
  98. }
  99. }
  100. }
  101. }
  102. return QString();
  103. }
  104. QString MainWindow::getExistingDirectory(QString dir) {
  105. return QFileDialog::getExistingDirectory(this, "Open Directory", dir, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
  106. }
  107. void MainWindow::on_action_Open_Project_triggered()
  108. {
  109. QSettings settings;
  110. QString key = "recent_projects";
  111. QString recent = ".";
  112. if (settings.contains(key)) {
  113. recent = settings.value(key).toStringList().last();
  114. }
  115. QString dir = getExistingDirectory(recent);
  116. if (!dir.isEmpty()) {
  117. QStringList recents;
  118. if (settings.contains(key)) {
  119. recents = settings.value(key).toStringList();
  120. }
  121. recents.removeAll(dir);
  122. recents.append(dir);
  123. settings.setValue(key, recents);
  124. openProject(dir);
  125. }
  126. }
  127. void MainWindow::setMap(QString map_name) {
  128. qDebug() << QString("setMap(%1)").arg(map_name);
  129. if (map_name.isNull()) {
  130. return;
  131. }
  132. editor->setMap(map_name);
  133. on_tabWidget_currentChanged(ui->tabWidget->currentIndex());
  134. ui->graphicsView_Map->setScene(editor->scene);
  135. ui->graphicsView_Map->setSceneRect(editor->scene->sceneRect());
  136. ui->graphicsView_Map->setFixedSize(editor->scene->width() + 2, editor->scene->height() + 2);
  137. ui->graphicsView_Objects_Map->setScene(editor->scene);
  138. ui->graphicsView_Objects_Map->setSceneRect(editor->scene->sceneRect());
  139. ui->graphicsView_Objects_Map->setFixedSize(editor->scene->width() + 2, editor->scene->height() + 2);
  140. ui->graphicsView_Objects_Map->editor = editor;
  141. ui->graphicsView_Connections->setScene(editor->scene);
  142. ui->graphicsView_Connections->setSceneRect(editor->scene->sceneRect());
  143. ui->graphicsView_Connections->setFixedSize(editor->scene->width() + 2, editor->scene->height() + 2);
  144. ui->graphicsView_Metatiles->setScene(editor->scene_metatiles);
  145. //ui->graphicsView_Metatiles->setSceneRect(editor->scene_metatiles->sceneRect());
  146. ui->graphicsView_Metatiles->setFixedSize(editor->metatiles_item->pixmap().width() + 2, editor->metatiles_item->pixmap().height() + 2);
  147. ui->graphicsView_BorderMetatile->setScene(editor->scene_selected_border_metatiles);
  148. ui->graphicsView_BorderMetatile->setFixedSize(editor->selected_border_metatiles_item->pixmap().width() + 2, editor->selected_border_metatiles_item->pixmap().height() + 2);
  149. ui->graphicsView_Collision->setScene(editor->scene_collision_metatiles);
  150. //ui->graphicsView_Collision->setSceneRect(editor->scene_collision_metatiles->sceneRect());
  151. ui->graphicsView_Collision->setFixedSize(editor->collision_metatiles_item->pixmap().width() + 2, editor->collision_metatiles_item->pixmap().height() + 2);
  152. ui->graphicsView_Elevation->setScene(editor->scene_elevation_metatiles);
  153. //ui->graphicsView_Elevation->setSceneRect(editor->scene_elevation_metatiles->sceneRect());
  154. ui->graphicsView_Elevation->setFixedSize(editor->elevation_metatiles_item->pixmap().width() + 2, editor->elevation_metatiles_item->pixmap().height() + 2);
  155. displayMapProperties();
  156. setWindowTitle(map_name + " - " + editor->project->getProjectTitle() + " - pretmap");
  157. connect(editor->map, SIGNAL(mapChanged(Map*)), this, SLOT(onMapChanged(Map *)));
  158. connect(editor->map, SIGNAL(statusBarMessage(QString)), this, SLOT(setStatusBarMessage(QString)));
  159. setRecentMap(map_name);
  160. updateMapList();
  161. }
  162. void MainWindow::setRecentMap(QString map_name) {
  163. QSettings settings;
  164. QString key = "project:" + editor->project->root;
  165. QMap<QString, QVariant> qmap;
  166. if (settings.contains(key)) {
  167. qmap = settings.value(key).toMap();
  168. }
  169. qmap.insert("recent_map", map_name);
  170. settings.setValue(key, qmap);
  171. }
  172. void MainWindow::displayMapProperties() {
  173. ui->comboBox_Song->clear();
  174. ui->comboBox_Location->clear();
  175. ui->comboBox_Visibility->clear();
  176. ui->comboBox_Weather->clear();
  177. ui->comboBox_Type->clear();
  178. ui->comboBox_BattleScene->clear();
  179. ui->comboBox_PrimaryTileset->clear();
  180. ui->comboBox_SecondaryTileset->clear();
  181. ui->checkBox_ShowLocation->setChecked(false);
  182. if (!editor || !editor->map || !editor->project) {
  183. ui->frame_3->setEnabled(false);
  184. return;
  185. }
  186. ui->frame_3->setEnabled(true);
  187. Map *map = editor->map;
  188. Project *project = editor->project;
  189. QStringList songs = project->getSongNames();
  190. ui->comboBox_Song->addItems(songs);
  191. ui->comboBox_Song->setCurrentText(map->song);
  192. ui->comboBox_Location->addItems(project->getLocations());
  193. ui->comboBox_Location->setCurrentText(map->location);
  194. QMap<QString, QStringList> tilesets = project->getTilesets();
  195. ui->comboBox_PrimaryTileset->addItems(tilesets.value("primary"));
  196. ui->comboBox_PrimaryTileset->setCurrentText(map->layout->tileset_primary_label);
  197. ui->comboBox_SecondaryTileset->addItems(tilesets.value("secondary"));
  198. ui->comboBox_SecondaryTileset->setCurrentText(map->layout->tileset_secondary_label);
  199. ui->comboBox_Visibility->addItems(project->getVisibilities());
  200. ui->comboBox_Visibility->setCurrentText(map->visibility);
  201. ui->comboBox_Weather->addItems(project->getWeathers());
  202. ui->comboBox_Weather->setCurrentText(map->weather);
  203. ui->comboBox_Type->addItems(project->getMapTypes());
  204. ui->comboBox_Type->setCurrentText(map->type);
  205. ui->comboBox_BattleScene->addItems(project->getBattleScenes());
  206. ui->comboBox_BattleScene->setCurrentText(map->battle_scene);
  207. ui->checkBox_ShowLocation->setChecked(map->show_location.toInt() > 0 || map->show_location == "TRUE");
  208. }
  209. void MainWindow::on_comboBox_Song_activated(const QString &song)
  210. {
  211. if (editor && editor->map) {
  212. editor->map->song = song;
  213. }
  214. }
  215. void MainWindow::on_comboBox_Location_activated(const QString &location)
  216. {
  217. if (editor && editor->map) {
  218. editor->map->location = location;
  219. }
  220. }
  221. void MainWindow::on_comboBox_Visibility_activated(const QString &visibility)
  222. {
  223. if (editor && editor->map) {
  224. editor->map->visibility = visibility;
  225. }
  226. }
  227. void MainWindow::on_comboBox_Weather_activated(const QString &weather)
  228. {
  229. if (editor && editor->map) {
  230. editor->map->weather = weather;
  231. }
  232. }
  233. void MainWindow::on_comboBox_Type_activated(const QString &type)
  234. {
  235. if (editor && editor->map) {
  236. editor->map->type = type;
  237. }
  238. }
  239. void MainWindow::on_comboBox_BattleScene_activated(const QString &battle_scene)
  240. {
  241. if (editor && editor->map) {
  242. editor->map->battle_scene = battle_scene;
  243. }
  244. }
  245. void MainWindow::on_checkBox_ShowLocation_clicked(bool checked)
  246. {
  247. if (editor && editor->map) {
  248. if (checked) {
  249. editor->map->show_location = "TRUE";
  250. } else {
  251. editor->map->show_location = "FALSE";
  252. }
  253. }
  254. }
  255. void MainWindow::loadDataStructures() {
  256. Project *project = editor->project;
  257. project->readMapLayoutsTable();
  258. project->readAllMapLayouts();
  259. project->readItemNames();
  260. project->readFlagNames();
  261. project->readVarNames();
  262. project->readMapsWithConnections();
  263. }
  264. void MainWindow::populateMapList() {
  265. Project *project = editor->project;
  266. QIcon mapFolderIcon;
  267. mapFolderIcon.addFile(QStringLiteral(":/icons/folder_closed_map.ico"), QSize(), QIcon::Normal, QIcon::Off);
  268. mapFolderIcon.addFile(QStringLiteral(":/icons/folder_map.ico"), QSize(), QIcon::Normal, QIcon::On);
  269. QIcon folderIcon;
  270. folderIcon.addFile(QStringLiteral(":/icons/folder_closed.ico"), QSize(), QIcon::Normal, QIcon::Off);
  271. mapIcon = new QIcon;
  272. mapIcon->addFile(QStringLiteral(":/icons/map.ico"), QSize(), QIcon::Normal, QIcon::Off);
  273. mapIcon->addFile(QStringLiteral(":/icons/image.ico"), QSize(), QIcon::Normal, QIcon::On);
  274. mapListModel = new QStandardItemModel;
  275. mapGroupsModel = new QList<QStandardItem*>;
  276. QStandardItem *entry = new QStandardItem;
  277. entry->setText(project->getProjectTitle());
  278. entry->setIcon(folderIcon);
  279. entry->setEditable(false);
  280. mapListModel->appendRow(entry);
  281. QStandardItem *maps = new QStandardItem;
  282. maps->setText("maps");
  283. maps->setIcon(folderIcon);
  284. maps->setEditable(false);
  285. entry->appendRow(maps);
  286. project->readMapGroups();
  287. for (int i = 0; i < project->groupNames->length(); i++) {
  288. QString group_name = project->groupNames->value(i);
  289. QStandardItem *group = new QStandardItem;
  290. group->setText(group_name);
  291. group->setIcon(mapFolderIcon);
  292. group->setEditable(false);
  293. group->setData(group_name, Qt::UserRole);
  294. group->setData("map_group", MapListUserRoles::TypeRole);
  295. group->setData(i, MapListUserRoles::GroupRole);
  296. maps->appendRow(group);
  297. mapGroupsModel->append(group);
  298. QStringList names = project->groupedMapNames.value(i);
  299. for (int j = 0; j < names.length(); j++) {
  300. QString map_name = names.value(j);
  301. QStandardItem *map = createMapItem(map_name, i, j);
  302. group->appendRow(map);
  303. }
  304. }
  305. // Right-clicking on items in the map list tree view brings up a context menu.
  306. ui->mapList->setContextMenuPolicy(Qt::CustomContextMenu);
  307. connect(ui->mapList, SIGNAL(customContextMenuRequested(const QPoint &)),
  308. this, SLOT(onOpenMapListContextMenu(const QPoint &)));
  309. ui->mapList->setModel(mapListModel);
  310. ui->mapList->setUpdatesEnabled(true);
  311. ui->mapList->expandToDepth(2);
  312. ui->mapList->repaint();
  313. }
  314. QStandardItem* MainWindow::createMapItem(QString mapName, int groupNum, int inGroupNum) {
  315. QStandardItem *map = new QStandardItem;
  316. map->setText(QString("[%1.%2] ").arg(groupNum).arg(inGroupNum, 2, 10, QLatin1Char('0')) + mapName);
  317. map->setIcon(*mapIcon);
  318. map->setEditable(false);
  319. map->setData(mapName, Qt::UserRole);
  320. map->setData("map_name", MapListUserRoles::TypeRole);
  321. return map;
  322. }
  323. void MainWindow::onOpenMapListContextMenu(const QPoint &point)
  324. {
  325. QModelIndex index = ui->mapList->indexAt(point);
  326. if (!index.isValid()) {
  327. return;
  328. }
  329. QStandardItem *selectedItem = mapListModel->itemFromIndex(index);
  330. QVariant itemType = selectedItem->data(MapListUserRoles::TypeRole);
  331. if (!itemType.isValid()) {
  332. return;
  333. }
  334. // Build custom context menu depending on which type of item was selected (map group, map name, etc.)
  335. if (itemType == "map_group") {
  336. QString groupName = selectedItem->data(Qt::UserRole).toString();
  337. int groupNum = selectedItem->data(MapListUserRoles::GroupRole).toInt();
  338. QMenu* menu = new QMenu();
  339. QActionGroup* actions = new QActionGroup(menu);
  340. actions->addAction(menu->addAction("Add New Map to Group"))->setData(groupNum);
  341. connect(actions, SIGNAL(triggered(QAction*)), this, SLOT(onAddNewMapToGroupClick(QAction*)));
  342. menu->exec(QCursor::pos());
  343. }
  344. }
  345. void MainWindow::onAddNewMapToGroupClick(QAction* triggeredAction)
  346. {
  347. int groupNum = triggeredAction->data().toInt();
  348. QStandardItem* groupItem = mapGroupsModel->at(groupNum);
  349. QString newMapName = editor->project->getNewMapName();
  350. Map* newMap = editor->project->addNewMapToGroup(newMapName, groupNum);
  351. editor->project->saveMap(newMap);
  352. editor->project->saveAllDataStructures();
  353. int numMapsInGroup = groupItem->rowCount();
  354. QStandardItem *newMapItem = createMapItem(newMapName, groupNum, numMapsInGroup);
  355. groupItem->appendRow(newMapItem);
  356. setMap(newMapName);
  357. }
  358. void MainWindow::onTilesetChanged(QString mapName)
  359. {
  360. setMap(mapName);
  361. }
  362. void MainWindow::on_mapList_activated(const QModelIndex &index)
  363. {
  364. QVariant data = index.data(Qt::UserRole);
  365. if (!data.isNull()) {
  366. setMap(data.toString());
  367. }
  368. //updateMapList();
  369. }
  370. void MainWindow::markAllEdited(QAbstractItemModel *model) {
  371. QList<QModelIndex> list;
  372. list.append(QModelIndex());
  373. while (list.length()) {
  374. QModelIndex parent = list.takeFirst();
  375. for (int i = 0; i < model->rowCount(parent); i++) {
  376. QModelIndex index = model->index(i, 0, parent);
  377. if (model->hasChildren(index)) {
  378. list.append(index);
  379. }
  380. markEdited(index);
  381. }
  382. }
  383. }
  384. void MainWindow::markEdited(QModelIndex index) {
  385. QVariant data = index.data(Qt::UserRole);
  386. if (!data.isNull()) {
  387. QString map_name = data.toString();
  388. if (editor->project) {
  389. if (editor->project->map_cache->contains(map_name)) {
  390. // Just mark anything that's been opened for now.
  391. // TODO if (project->getMap()->saved)
  392. //ui->mapList->setExpanded(index, true);
  393. ui->mapList->setExpanded(index, editor->project->map_cache->value(map_name)->hasUnsavedChanges());
  394. }
  395. }
  396. }
  397. }
  398. void MainWindow::updateMapList() {
  399. QAbstractItemModel *model = ui->mapList->model();
  400. markAllEdited(model);
  401. }
  402. void MainWindow::on_action_Save_Project_triggered()
  403. {
  404. editor->saveProject();
  405. updateMapList();
  406. }
  407. void MainWindow::undo() {
  408. editor->undo();
  409. }
  410. void MainWindow::redo() {
  411. editor->redo();
  412. }
  413. void MainWindow::on_action_Save_triggered() {
  414. editor->save();
  415. updateMapList();
  416. }
  417. void MainWindow::on_tabWidget_2_currentChanged(int index)
  418. {
  419. if (index == 0) {
  420. editor->setEditingMap();
  421. } else if (index == 1) {
  422. editor->setEditingCollision();
  423. }
  424. }
  425. void MainWindow::on_action_Exit_triggered()
  426. {
  427. QApplication::quit();
  428. }
  429. void MainWindow::on_tabWidget_currentChanged(int index)
  430. {
  431. if (index == 0) {
  432. on_tabWidget_2_currentChanged(ui->tabWidget_2->currentIndex());
  433. } else if (index == 1) {
  434. editor->setEditingObjects();
  435. } else if (index == 3) {
  436. editor->setEditingConnections();
  437. }
  438. }
  439. void MainWindow::on_actionUndo_triggered()
  440. {
  441. undo();
  442. }
  443. void MainWindow::on_actionRedo_triggered()
  444. {
  445. redo();
  446. }
  447. void MainWindow::addNewEvent(QString event_type)
  448. {
  449. if (editor) {
  450. DraggablePixmapItem *object = editor->addNewEvent(event_type);
  451. if (object) {
  452. editor->selectMapEvent(object, false);
  453. }
  454. updateSelectedObjects();
  455. }
  456. }
  457. // Should probably just pass layout and let the editor work it out
  458. void MainWindow::updateSelectedObjects() {
  459. QList<DraggablePixmapItem *> *all_events = editor->getObjects();
  460. QList<DraggablePixmapItem *> *events = all_events;
  461. if (editor->selected_events && editor->selected_events->length()) {
  462. events = editor->selected_events;
  463. }
  464. QMap<QString, int> event_obj_gfx_constants = editor->project->getEventObjGfxConstants();
  465. QList<ObjectPropertiesFrame *> frames;
  466. for (DraggablePixmapItem *item : *events) {
  467. ObjectPropertiesFrame *frame = new ObjectPropertiesFrame;
  468. // frame->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
  469. QSpinBox *x = frame->ui->spinBox_x;
  470. QSpinBox *y = frame->ui->spinBox_y;
  471. QSpinBox *z = frame->ui->spinBox_z;
  472. x->setValue(item->event->x());
  473. connect(x, SIGNAL(valueChanged(QString)), item, SLOT(set_x(QString)));
  474. connect(item, SIGNAL(xChanged(int)), x, SLOT(setValue(int)));
  475. y->setValue(item->event->y());
  476. connect(y, SIGNAL(valueChanged(QString)), item, SLOT(set_y(QString)));
  477. connect(item, SIGNAL(yChanged(int)), y, SLOT(setValue(int)));
  478. z->setValue(item->event->elevation());
  479. connect(z, SIGNAL(valueChanged(QString)), item, SLOT(set_elevation(QString)));
  480. connect(item, SIGNAL(elevationChanged(int)), z, SLOT(setValue(int)));
  481. QFont font;
  482. font.setCapitalization(QFont::Capitalize);
  483. frame->ui->label_name->setFont(font);
  484. QString event_type = item->event->get("event_type");
  485. QString event_group_type = item->event->get("event_group_type");
  486. QString map_name = item->event->get("map_name");
  487. frame->ui->label_name->setText(
  488. QString("%1: %2 %3")
  489. .arg(editor->project->getMap(map_name)->events.value(event_group_type).indexOf(item->event) + 1)
  490. .arg(map_name)
  491. .arg(event_type)
  492. );
  493. frame->ui->label_spritePixmap->setPixmap(item->event->pixmap);
  494. connect(item, SIGNAL(spriteChanged(QPixmap)), frame->ui->label_spritePixmap, SLOT(setPixmap(QPixmap)));
  495. frame->ui->sprite->setVisible(false);
  496. QMap<QString, QString> field_labels;
  497. field_labels["script_label"] = "Script";
  498. field_labels["event_flag"] = "Event Flag";
  499. field_labels["replacement"] = "Replacement";
  500. field_labels["behavior"] = "Behavior";
  501. field_labels["radius_x"] = "Movement Radius X";
  502. field_labels["radius_y"] = "Movement Radius Y";
  503. field_labels["trainer_see_type"] = "Trainer See Type";
  504. field_labels["sight_radius_tree_id"] = "Sight Radius / Berry Tree ID";
  505. field_labels["destination_warp"] = "Destination Warp";
  506. field_labels["destination_map_name"] = "Destination Map";
  507. field_labels["script_var"] = "Var";
  508. field_labels["script_var_value"] = "Var Value";
  509. field_labels["player_facing_direction"] = "Player Facing Direction";
  510. field_labels["item"] = "Item";
  511. field_labels["item_unknown5"] = "Unknown 5";
  512. field_labels["item_unknown6"] = "Unknown 6";
  513. field_labels["weather"] = "Weather";
  514. field_labels["flag"] = "Flag";
  515. field_labels["secret_base_map"] = "Secret Base Map";
  516. QStringList fields;
  517. if (event_type == EventType::Object) {
  518. frame->ui->sprite->setVisible(true);
  519. frame->ui->comboBox_sprite->addItems(event_obj_gfx_constants.keys());
  520. frame->ui->comboBox_sprite->setCurrentText(item->event->get("sprite"));
  521. connect(frame->ui->comboBox_sprite, SIGNAL(activated(QString)), item, SLOT(set_sprite(QString)));
  522. /*
  523. frame->ui->script->setVisible(true);
  524. frame->ui->comboBox_script->addItem(item->event->get("script_label"));
  525. frame->ui->comboBox_script->setCurrentText(item->event->get("script_label"));
  526. //item->bind(frame->ui->comboBox_script, "script_label");
  527. connect(frame->ui->comboBox_script, SIGNAL(activated(QString)), item, SLOT(set_script(QString)));
  528. //connect(frame->ui->comboBox_script, static_cast<void (QComboBox::*)(const QString&)>(&QComboBox::activated), item, [item](QString script_label){ item->event->put("script_label", script_label); });
  529. //connect(item, SIGNAL(scriptChanged(QString)), frame->ui->comboBox_script, SLOT(setValue(QString)));
  530. */
  531. fields << "behavior";
  532. fields << "radius_x";
  533. fields << "radius_y";
  534. fields << "script_label";
  535. fields << "event_flag";
  536. fields << "replacement";
  537. fields << "trainer_see_type";
  538. fields << "sight_radius_tree_id";
  539. }
  540. else if (event_type == EventType::Warp) {
  541. fields << "destination_warp";
  542. fields << "destination_map_name";
  543. }
  544. else if (event_type == EventType::CoordScript) {
  545. fields << "script_label";
  546. fields << "script_var";
  547. fields << "script_var_value";
  548. }
  549. else if (event_type == EventType::CoordWeather) {
  550. fields << "weather";
  551. }
  552. else if (event_type == EventType::Sign) {
  553. fields << "player_facing_direction";
  554. fields << "script_label";
  555. }
  556. else if (event_type == EventType::HiddenItem) {
  557. fields << "item";
  558. fields << "flag";
  559. }
  560. else if (event_type == EventType::SecretBase) {
  561. fields << "secret_base_map";
  562. }
  563. for (QString key : fields) {
  564. QWidget *widget = new QWidget(frame);
  565. QFormLayout *fl = new QFormLayout(widget);
  566. fl->setContentsMargins(9, 0, 9, 0);
  567. QComboBox *combo = new QComboBox(widget);
  568. combo->setEditable(true);
  569. QString value = item->event->get(key);
  570. if (key == "destination_map_name") {
  571. if (!editor->project->mapNames->contains(value)) {
  572. combo->addItem(value);
  573. }
  574. combo->addItems(*editor->project->mapNames);
  575. } else if (key == "item") {
  576. if (!editor->project->itemNames->contains(value)) {
  577. combo->addItem(value);
  578. }
  579. combo->addItems(*editor->project->itemNames);
  580. } else if (key == "flag") {
  581. if (!editor->project->flagNames->contains(value)) {
  582. combo->addItem(value);
  583. }
  584. combo->addItems(*editor->project->flagNames);
  585. } else if (key == "script_var") {
  586. if (!editor->project->varNames->contains(value)) {
  587. combo->addItem(value);
  588. }
  589. combo->addItems(*editor->project->varNames);
  590. } else {
  591. combo->addItem(value);
  592. }
  593. combo->setCurrentText(value);
  594. fl->addRow(new QLabel(field_labels[key], widget), combo);
  595. widget->setLayout(fl);
  596. frame->layout()->addWidget(widget);
  597. item->bind(combo, key);
  598. }
  599. frames.append(frame);
  600. }
  601. //int scroll = ui->scrollArea_4->verticalScrollBar()->value();
  602. QWidget *target = ui->scrollAreaWidgetContents;
  603. if (target->children().length()) {
  604. qDeleteAll(target->children());
  605. }
  606. QVBoxLayout *layout = new QVBoxLayout(target);
  607. target->setLayout(layout);
  608. ui->scrollArea_4->setWidgetResizable(true);
  609. ui->scrollArea_4->setWidget(target);
  610. for (ObjectPropertiesFrame *frame : frames) {
  611. layout->addWidget(frame);
  612. }
  613. layout->addStretch(1);
  614. // doesn't work
  615. //QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
  616. //ui->scrollArea_4->ensureVisible(0, scroll);
  617. }
  618. void MainWindow::on_toolButton_deleteObject_clicked()
  619. {
  620. if (editor && editor->selected_events) {
  621. if (editor->selected_events->length()) {
  622. for (DraggablePixmapItem *item : *editor->selected_events) {
  623. editor->deleteEvent(item->event);
  624. if (editor->scene->items().contains(item)) {
  625. editor->scene->removeItem(item);
  626. }
  627. editor->selected_events->removeOne(item);
  628. }
  629. updateSelectedObjects();
  630. }
  631. }
  632. }
  633. void MainWindow::on_toolButton_Paint_clicked()
  634. {
  635. editor->map_edit_mode = "paint";
  636. checkToolButtons();
  637. }
  638. void MainWindow::on_toolButton_Select_clicked()
  639. {
  640. editor->map_edit_mode = "select";
  641. checkToolButtons();
  642. }
  643. void MainWindow::on_toolButton_Fill_clicked()
  644. {
  645. editor->map_edit_mode = "fill";
  646. checkToolButtons();
  647. }
  648. void MainWindow::on_toolButton_Dropper_clicked()
  649. {
  650. editor->map_edit_mode = "pick";
  651. checkToolButtons();
  652. }
  653. void MainWindow::checkToolButtons() {
  654. ui->toolButton_Paint->setChecked(editor->map_edit_mode == "paint");
  655. ui->toolButton_Select->setChecked(editor->map_edit_mode == "select");
  656. ui->toolButton_Fill->setChecked(editor->map_edit_mode == "fill");
  657. ui->toolButton_Dropper->setChecked(editor->map_edit_mode == "pick");
  658. }
  659. void MainWindow::onLoadMapRequested(QString mapName, QString fromMapName) {
  660. setMap(mapName);
  661. editor->setSelectedConnectionFromMap(fromMapName);
  662. }
  663. void MainWindow::onMapChanged(Map *map) {
  664. map->layout->has_unsaved_changes = true;
  665. updateMapList();
  666. }
  667. void MainWindow::on_action_Export_Map_Image_triggered()
  668. {
  669. QString defaultFilepath = QString("%1/%2.png").arg(editor->project->root).arg(editor->map->name);
  670. QString filepath = QFileDialog::getSaveFileName(this, "Export Map Image", defaultFilepath, "Image Files (*.png *.jpg *.bmp)");
  671. if (!filepath.isEmpty()) {
  672. editor->map_item->pixmap().save(filepath);
  673. }
  674. }
  675. void MainWindow::on_comboBox_ConnectionDirection_currentIndexChanged(const QString &direction)
  676. {
  677. editor->updateCurrentConnectionDirection(direction);
  678. }
  679. void MainWindow::on_spinBox_ConnectionOffset_valueChanged(int offset)
  680. {
  681. editor->updateConnectionOffset(offset);
  682. }
  683. void MainWindow::on_comboBox_ConnectedMap_currentTextChanged(const QString &mapName)
  684. {
  685. editor->setConnectionMap(mapName);
  686. }
  687. void MainWindow::on_pushButton_AddConnection_clicked()
  688. {
  689. editor->addNewConnection();
  690. }
  691. void MainWindow::on_pushButton_RemoveConnection_clicked()
  692. {
  693. editor->removeCurrentConnection();
  694. }
  695. void MainWindow::on_comboBox_DiveMap_currentTextChanged(const QString &mapName)
  696. {
  697. editor->updateDiveMap(mapName);
  698. }
  699. void MainWindow::on_comboBox_EmergeMap_currentTextChanged(const QString &mapName)
  700. {
  701. editor->updateEmergeMap(mapName);
  702. }
  703. void MainWindow::on_comboBox_PrimaryTileset_activated(const QString &tilesetLabel)
  704. {
  705. editor->updatePrimaryTileset(tilesetLabel);
  706. }
  707. void MainWindow::on_comboBox_SecondaryTileset_activated(const QString &tilesetLabel)
  708. {
  709. editor->updateSecondaryTileset(tilesetLabel);
  710. }
  711. void MainWindow::on_pushButton_clicked()
  712. {
  713. QDialog dialog(this, Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
  714. dialog.setWindowTitle("Change Map Dimensions");
  715. dialog.setWindowModality(Qt::NonModal);
  716. QFormLayout form(&dialog);
  717. QSpinBox *widthSpinBox = new QSpinBox();
  718. QSpinBox *heightSpinBox = new QSpinBox();
  719. widthSpinBox->setMinimum(1);
  720. heightSpinBox->setMinimum(1);
  721. // See below for explanation of maximum map dimensions
  722. widthSpinBox->setMaximum(0x1E7);
  723. heightSpinBox->setMaximum(0x1D1);
  724. widthSpinBox->setValue(editor->map->getWidth());
  725. heightSpinBox->setValue(editor->map->getHeight());
  726. form.addRow(new QLabel("Width"), widthSpinBox);
  727. form.addRow(new QLabel("Height"), heightSpinBox);
  728. QLabel *errorLabel = new QLabel();
  729. QPalette errorPalette;
  730. errorPalette.setColor(QPalette::WindowText, Qt::red);
  731. errorLabel->setPalette(errorPalette);
  732. errorLabel->setVisible(false);
  733. QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
  734. form.addRow(&buttonBox);
  735. connect(&buttonBox, &QDialogButtonBox::accepted, [&dialog, &widthSpinBox, &heightSpinBox, &errorLabel](){
  736. // Ensure width and height are an acceptable size.
  737. // The maximum number of metatiles in a map is the following:
  738. // max = (width + 15) * (height + 14)
  739. // This limit can be found in fieldmap.c in pokeruby/pokeemerald.
  740. int realWidth = widthSpinBox->value() + 15;
  741. int realHeight = heightSpinBox->value() + 14;
  742. int numMetatiles = realWidth * realHeight;
  743. if (numMetatiles <= 0x2800) {
  744. dialog.accept();
  745. } else {
  746. QString errorText = QString("Error: The specified width and height are too large.\n"
  747. "The maximum width and height is the following: (width + 15) * (height + 14) <= 10240\n"
  748. "The specified width and height was: (%1 + 15) * (%2 + 14) = %3")
  749. .arg(widthSpinBox->value())
  750. .arg(heightSpinBox->value())
  751. .arg(numMetatiles);
  752. errorLabel->setText(errorText);
  753. errorLabel->setVisible(true);
  754. }
  755. });
  756. connect(&buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
  757. form.addRow(errorLabel);
  758. if (dialog.exec() == QDialog::Accepted) {
  759. editor->map->setDimensions(widthSpinBox->value(), heightSpinBox->value());
  760. setMap(editor->map->name);
  761. }
  762. }