diff --git a/forms/regionmapeditor.ui b/forms/regionmapeditor.ui index 5408a32d..8e598760 100644 --- a/forms/regionmapeditor.ui +++ b/forms/regionmapeditor.ui @@ -1091,14 +1091,16 @@ + + Edit - + @@ -1169,6 +1171,11 @@ Clear Map Entries + + + Update Config... + + diff --git a/include/ui/regionmapeditor.h b/include/ui/regionmapeditor.h index 25185619..f349f9b2 100644 --- a/include/ui/regionmapeditor.h +++ b/include/ui/regionmapeditor.h @@ -26,9 +26,6 @@ public: explicit RegionMapEditor(QWidget *parent = 0, Project *pro = nullptr); ~RegionMapEditor(); - RegionMap *region_map = nullptr; - tsl::ordered_map region_maps; - bool load(); void onRegionMapTileSelectorSelectedTileChanged(unsigned id); @@ -53,13 +50,17 @@ private: Ui::RegionMapEditor *ui; Project *project; + RegionMap *region_map = nullptr; + tsl::ordered_map region_maps; + poryjson::Json rmConfigJson; + bool configSaved = false; + QUndoGroup history; int currIndex = 0; - unsigned selectedCityTile; - unsigned selectedImageTile; + unsigned selectedImageTile = 0; QString activeEntry; bool cityMapFirstDraw = true; @@ -84,6 +85,10 @@ private: RegionMapPixmapItem *region_map_item = nullptr; CityMapPixmapItem *city_map_item = nullptr; + bool reload(); + bool setup(); + void clear(); + bool saveRegionMap(RegionMap *map); void saveConfig(); bool loadRegionMapEntries(); @@ -121,6 +126,7 @@ private slots: void on_action_RegionMap_ClearLayout_triggered(); void on_action_RegionMap_ClearEntries_triggered(); void on_action_Swap_triggered(); + void on_action_Configure_triggered(); void on_tabWidget_Region_Map_currentChanged(int); void on_pushButton_RM_Options_delete_clicked(); void on_comboBox_RM_ConnectedMap_textActivated(const QString &); diff --git a/src/ui/regionmapeditor.cpp b/src/ui/regionmapeditor.cpp index 31a1c453..3a749ebf 100644 --- a/src/ui/regionmapeditor.cpp +++ b/src/ui/regionmapeditor.cpp @@ -47,10 +47,10 @@ RegionMapEditor::~RegionMapEditor() delete mapsquare_selector_item; delete region_map_layout_item; delete scene_region_map_image; - delete city_map_selector_item; - delete city_map_item; - delete scene_city_map_tiles; - delete scene_city_map_image; + //delete city_map_selector_item; + //delete city_map_item; + //delete scene_city_map_tiles; + //delete scene_city_map_image; delete scene_region_map_layout; delete scene_region_map_tiles; delete ui; @@ -226,7 +226,7 @@ bool RegionMapEditor::buildConfigDialog() { QDialog dialog(this); dialog.setWindowTitle("Configure Region Maps"); - dialog.setWindowModality(Qt::ApplicationModal); + dialog.setWindowModality(Qt::WindowModal); QFormLayout form(&dialog); @@ -252,6 +252,19 @@ bool RegionMapEditor::buildConfigDialog() { regionMapList->addItem(newItem); } }; + updateMapList(); + + auto updateJsonFromList = [regionMapList, &rmConfigJsonUpdate]() { + poryjson::Json::object newJson; + poryjson::Json::array mapArr; + for (auto item : regionMapList->findItems("*", Qt::MatchWildcard)) { + QString err; + poryjson::Json itemJson = poryjson::Json::parse(item->data(Qt::UserRole).toString(), err); + mapArr.append(itemJson); + } + newJson["region_maps"] = mapArr; + rmConfigJsonUpdate = poryjson::Json(newJson); + }; // when double clicking a region map from the list, bring up the configuration window // and populate it with the current values @@ -299,6 +312,18 @@ bool RegionMapEditor::buildConfigDialog() { regionMapList->addItem(newItem); }); + QPushButton *delMapButton = new QPushButton("Delete Selected Region Map"); + form.addRow(delMapButton); + + connect(delMapButton, &QPushButton::clicked, [this, regionMapList, &updateJsonFromList] { + QListWidgetItem *item = regionMapList->currentItem(); + if (item) { + regionMapList->removeItemWidget(item); + delete item; + updateJsonFromList(); + } + }); + // TODO: city maps (leaving this for now) // QListWidget *cityMapList = new QListWidget(&dialog); // // TODO: double clicking can delete them? bring up the tiny menu thing like sory by maps @@ -351,6 +376,7 @@ bool RegionMapEditor::buildConfigDialog() { if (dialog.exec() == QDialog::Accepted) { // if everything looks good, we can update the master json this->rmConfigJson = rmConfigJsonUpdate; + this->configSaved = false; return true; } @@ -390,6 +416,98 @@ bool RegionMapEditor::verifyConfig(poryjson::Json cfg) { return true; } +void RegionMapEditor::clear() { + // clear everything that gets loaded in a way that will not crash the destructor + // except the config json + + auto stacks = this->history.stacks(); + for (auto *stack : stacks) { + this->history.removeStack(stack); + } + for (auto p : this->region_maps) { + delete p.second; + } + this->region_map = nullptr; + this->region_maps.clear(); + this->region_map_entries.clear(); + + this->currIndex = 0; + this->activeEntry = QString(); + this->entriesFirstDraw = true; + + delete region_map_item; + region_map_item = nullptr; + + delete mapsquare_selector_item; + mapsquare_selector_item = nullptr; + + delete region_map_layout_item; + region_map_layout_item = nullptr; + + delete scene_region_map_image; + scene_region_map_image = nullptr; + + delete scene_region_map_layout; + scene_region_map_layout = nullptr; + + delete scene_region_map_tiles; + scene_region_map_tiles = nullptr; +} + +bool RegionMapEditor::reload() { + clear(); + return setup(); +} + +bool RegionMapEditor::setup() { + // if all has gone well, this->rmConfigJson should be populated + // next, load the entries + loadRegionMapEntries(); + + // load the region maps into this->region_maps + poryjson::Json::object regionMapObjectCopy = this->rmConfigJson.object_items(); + for (auto o : regionMapObjectCopy["region_maps"].array_items()) { + QString alias = o.object_items().at("alias").string_value(); + + RegionMap *newMap = new RegionMap(this->project); + newMap->setEntries(&this->region_map_entries); + if (!newMap->loadMapData(o)) { + delete newMap; + // TODO: consider continue, just reporting error loading single map? + return false; + } + + connect(newMap, &RegionMap::mapNeedsDisplaying, [this]() { + displayRegionMap(); + }); + + region_maps[alias] = newMap; + + this->history.addStack(&(newMap->editHistory)); + } + + // add to ui + this->ui->comboBox_regionSelector->clear(); + for (auto p : region_maps) { + this->ui->comboBox_regionSelector->addItem(p.first); + } + + // display the first region map in the list + if (!region_maps.empty()) { + setRegionMap(region_maps.begin()->second); + } + + connect(&(this->history), &QUndoGroup::indexChanged, [this](int) { + on_tabWidget_Region_Map_currentChanged(this->ui->tabWidget_Region_Map->currentIndex()); + }); + + this->show(); + this->setWindowState(Qt::WindowState::WindowActive); + this->activateWindow(); + + return true; +} + bool RegionMapEditor::load() { // check for config json file QString jsonConfigFilepath = this->project->root + "/src/data/region_map/porymap_config.json"; @@ -402,6 +520,7 @@ bool RegionMapEditor::load() { OrderedJson::object obj; if (parser.tryParseOrderedJsonFile(&obj, jsonConfigFilepath)) { this->rmConfigJson = OrderedJson(obj); + this->configSaved = true; } badConfig = !verifyConfig(this->rmConfigJson); } else { @@ -411,6 +530,7 @@ bool RegionMapEditor::load() { if (badConfig) { // show popup explaining next window QMessageBox warning; + warning.setIcon(QMessageBox::Warning); warning.setText("Region map configuration not found."); warning.setInformativeText("In order to continue, you must setup porymap to use your region map."); warning.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); @@ -429,46 +549,7 @@ bool RegionMapEditor::load() { } } - // if all has gone well, this->rmConfigJson should be populated - // next, load the entries - loadRegionMapEntries(); - - // load the region maps into this->region_maps - poryjson::Json::object regionMapObjectCopy = this->rmConfigJson.object_items(); - for (auto o : regionMapObjectCopy["region_maps"].array_items()) { - QString alias = o.object_items().at("alias").string_value(); - - RegionMap *newMap = new RegionMap(this->project); - newMap->setEntries(&this->region_map_entries); - if (!newMap->loadMapData(o)) { - delete newMap; - return false; - } - - connect(newMap, &RegionMap::mapNeedsDisplaying, [this]() { - displayRegionMap(); - }); - - region_maps[alias] = newMap; - - this->history.addStack(&(newMap->editHistory)); - } - - // add to ui - for (auto p : region_maps) { - ui->comboBox_regionSelector->addItem(p.first); - } - - // display the first region map in the list - if (!region_maps.empty()) { - setRegionMap(region_maps.begin()->second); - } - - connect(&(this->history), &QUndoGroup::indexChanged, [this](int) { - on_tabWidget_Region_Map_currentChanged(this->ui->tabWidget_Region_Map->currentIndex()); - }); - - return true; + return setup(); } void RegionMapEditor::setRegionMap(RegionMap *map) { @@ -516,6 +597,8 @@ void RegionMapEditor::saveConfig() { OrderedJsonDoc jsonDoc(&newConfigJson); jsonDoc.dump(&file); file.close(); + + this->configSaved = true; } void RegionMapEditor::on_action_RegionMap_Save_triggered() { @@ -536,6 +619,28 @@ void RegionMapEditor::on_actionSave_All_triggered() { saveConfig(); } +void RegionMapEditor::on_action_Configure_triggered() { + if (this->modified()) { + QMessageBox warning; + warning.setIcon(QMessageBox::Warning); + warning.setText("Reconfiguring region maps will discard any unsaved changes."); + warning.setInformativeText("Continue?"); + warning.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + warning.setDefaultButton(QMessageBox::Ok); + + if (warning.exec() == QMessageBox::Ok) { + if (buildConfigDialog()) { + reload(); + } + } + } + else { + if (buildConfigDialog()) { + reload(); + } + } +} + void RegionMapEditor::displayRegionMap() { displayRegionMapTileSelector(); displayRegionMapImage(); @@ -1196,7 +1301,7 @@ void RegionMapEditor::on_action_RegionMap_ClearEntries_triggered() { } bool RegionMapEditor::modified() { - return !this->history.isClean(); + return !this->history.isClean() || !this->configSaved; } void RegionMapEditor::closeEvent(QCloseEvent *event)