diff --git a/include/core/wildmoninfo.h b/include/core/wildmoninfo.h index 48d9e997..414e0f35 100644 --- a/include/core/wildmoninfo.h +++ b/include/core/wildmoninfo.h @@ -19,19 +19,20 @@ struct WildMonInfo { // for extensibility, make a QVector // or QMap struct WildPokemonHeader { - WildMonInfo landMons; - WildMonInfo waterMons; - WildMonInfo rockSmashMons; - WildMonInfo fishingMons; - QMap wildMons; }; -class Project; -QWidget *newSpeciesTableEntry(Project *project, WildPokemon mon, int index); -void createSpeciesTableRow(Project *, QTableWidget *, WildPokemon, int, QString); +typedef QVector>> Fields; +typedef QPair> Field; + +//class Project; +//class MonTabWidget; +//QWidget *newSpeciesTableEntry(Project *project, WildPokemon mon, int index); +//void createSpeciesTableRow(Project *, QTableWidget *, WildPokemon, int, QString); void clearTabWidget(QLayout *tab); -void clearTable(QTableWidget *table); -void populateWildMonTabWidget(QTabWidget *tabWidget, QVector>> fields); +//void clearTable(QTableWidget *table); +//void populateWildMonTabWidget(MonTabWidget *tabWidget, Fields /* QVector>> */ fields); + +WildMonInfo getDefaultMonInfo(Field field); #endif // GUARD_WILDMONINFO_H diff --git a/include/ui/montabwidget.h b/include/ui/montabwidget.h new file mode 100644 index 00000000..7aa7a82d --- /dev/null +++ b/include/ui/montabwidget.h @@ -0,0 +1,51 @@ +// montablewidget.h + +#ifndef MONTABWIDGET_H +#define MONTABWIDGET_H + +#include "wildmoninfo.h" + +#include +#include + +// +class Project; + +class MonTabWidget : public QTabWidget { + + Q_OBJECT + +public: + explicit MonTabWidget(Project *project = nullptr, QWidget *parent = nullptr); + ~MonTabWidget(){}; + + void populate(); + void populateTab(int tabIndex, WildMonInfo monInfo, QString fieldName); + void clear(); + + void createSpeciesTableRow(QTableWidget *table, WildPokemon mon, int index, QString fieldName); + + void clearTableAt(int index); + + QTableWidget *tableAt(int tabIndex); + //void setupTableAt(int tabIndex); + +public slots: + void setTabActive(int index, bool active = true); + +private: + bool eventFilter(QObject *object, QEvent *event); + void askActivateTab(int tabIndex, QPoint menuPos); + + QVector activeTabs; + + Project *project; + +private slots: + // + +signals: + // right click +}; + +#endif // MONTABWIDGET_H diff --git a/porymap.pro b/porymap.pro index 25401d79..4ab7305c 100644 --- a/porymap.pro +++ b/porymap.pro @@ -54,6 +54,7 @@ SOURCES += src/core/block.cpp \ src/ui/neweventtoolbutton.cpp \ src/ui/noscrollcombobox.cpp \ src/ui/noscrollspinbox.cpp \ + src/ui/montabwidget.cpp \ src/ui/paletteeditor.cpp \ src/ui/selectablepixmapitem.cpp \ src/ui/tileseteditor.cpp \ @@ -114,6 +115,7 @@ HEADERS += include/core/block.h \ include/ui/neweventtoolbutton.h \ include/ui/noscrollcombobox.h \ include/ui/noscrollspinbox.h \ + include/ui/montabwidget.h \ include/ui/paletteeditor.h \ include/ui/selectablepixmapitem.h \ include/ui/tileseteditor.h \ diff --git a/src/core/wildmoninfo.cpp b/src/core/wildmoninfo.cpp index 768df609..a6dcb953 100644 --- a/src/core/wildmoninfo.cpp +++ b/src/core/wildmoninfo.cpp @@ -1,6 +1,7 @@ // #include "wildmoninfo.h" +#include "montabwidget.h" #include "project.h" @@ -19,94 +20,15 @@ void clearTabWidget(QLayout *tab) { if (item) tab->removeItem(item); } -void clearTable(QTableWidget *table) { - if (table) { - table->clear(); - table->horizontalHeader()->hide(); - } +WildMonInfo getDefaultMonInfo(Field field) { + WildMonInfo newInfo; + newInfo.active = true; + newInfo.encounterRate = 0; + + for (int row : field.second) + newInfo.wildPokemon.append({5, 5, "SPECIES_NONE"}); + + return newInfo; } -void createSpeciesTableRow(Project *project, QTableWidget *table, WildPokemon mon, int index, QString fieldName) { - // - QPixmap monIcon = QPixmap(project->speciesToIconPath.value(mon.species)).copy(0, 0, 32, 32); - QLabel *monNum = new QLabel(QString("%1.").arg(QString::number(index))); - - QLabel *monLabel = new QLabel(); - monLabel->setPixmap(monIcon); - - QComboBox *monSelector = new QComboBox; - monSelector->setMinimumContentsLength(20); - monSelector->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength); - monSelector->addItems(project->speciesToIconPath.keys()); - monSelector->setCurrentText(mon.species); - monSelector->setEditable(true); - - QObject::connect(monSelector, &QComboBox::currentTextChanged, [=](QString newSpecies){ - QPixmap monIcon = QPixmap(project->speciesToIconPath.value(newSpecies)).copy(0, 0, 32, 32); - monLabel->setPixmap(monIcon); - }); - - QSpinBox *minLevel = new QSpinBox; - QSpinBox *maxLevel = new QSpinBox; - minLevel->setMinimum(1); - minLevel->setMaximum(100); - maxLevel->setMinimum(1); - maxLevel->setMaximum(100); - minLevel->setValue(mon.minLevel); - maxLevel->setValue(mon.maxLevel); - - int fieldIndex = 0; - for (auto field : project->wildMonFields) { - if (field.first == fieldName) break; - fieldIndex++; - } - QLabel *percentLabel = new QLabel(QString("%1%").arg( - QString::number(project->wildMonFields[fieldIndex].second[index - 1] - ))); - - QFrame *speciesSelector = new QFrame; - QHBoxLayout *speciesSelectorLayout = new QHBoxLayout; - speciesSelectorLayout->addWidget(monLabel); - speciesSelectorLayout->addWidget(monSelector); - speciesSelector->setLayout(speciesSelectorLayout); - - // prevent the spinboxes from being stupidly tall - QFrame *minLevelFrame = new QFrame; - QVBoxLayout *minLevelSpinboxLayout = new QVBoxLayout; - minLevelSpinboxLayout->addWidget(minLevel); - minLevelFrame->setLayout(minLevelSpinboxLayout); - QFrame *maxLevelFrame = new QFrame; - QVBoxLayout *maxLevelSpinboxLayout = new QVBoxLayout; - maxLevelSpinboxLayout->addWidget(maxLevel); - maxLevelFrame->setLayout(maxLevelSpinboxLayout); - - // add widgets to the table - table->setCellWidget(index - 1, 0, monNum); - table->setCellWidget(index - 1, 1, speciesSelector); - table->setCellWidget(index - 1, 2, minLevelFrame); - table->setCellWidget(index - 1, 3, maxLevelFrame); - table->setCellWidget(index - 1, 4, percentLabel); - - // TODO: lock max spinbox to min spinbox -} - -void populateWildMonTabWidget(QTabWidget *tabWidget, QVector>> fields) { - //QPushButton *newTabButton = new QPushButton("Configure JSON..."); - //QObject::connect(newTabButton, &QPushButton::clicked, [=](){ - // // TODO - // qDebug() << "configure json pressed"; - //}); - //tabWidget->setCornerWidget(newTabButton); - - // delete everything in the tab widget here? no - - for (QPair> field : fields) { - QTableWidget *table = new QTableWidget; - table->setEditTriggers(QAbstractItemView::NoEditTriggers); - table->setFocusPolicy(Qt::NoFocus); - table->setSelectionMode(QAbstractItemView::NoSelection); - table->clearFocus(); - tabWidget->addTab(table, field.first); - } -} diff --git a/src/editor.cpp b/src/editor.cpp index b061310a..ffe3bc43 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -5,6 +5,7 @@ #include "mapconnection.h" #include "currentselectedmetatilespixmapitem.h" #include "mapsceneeventfilter.h" +#include "montabwidget.h" #include #include #include @@ -196,71 +197,43 @@ void Editor::displayWildMonTables() { WildPokemonHeader header = project->wildMonData.value(map->constantName).value(label); - //QTableWidget *speciesTable = new QTableWidget; - //clearTable(speciesTable); - QTabWidget *tabWidget = new QTabWidget; + //QTabWidget *tabWidget = new QTabWidget; + MonTabWidget *tabWidget = new MonTabWidget(project); stack->insertWidget(labelIndex, tabWidget); - populateWildMonTabWidget(tabWidget, project->wildMonFields); + //populateWildMonTabWidget(tabWidget, project->wildMonFields); //stack->setCurrentWidget(tabWidget); + //QVector unusedIndices; + int tabIndex = 0; for (QPair> monField : project->wildMonFields) { - QString field = monField.first; + QString fieldName = monField.first; // tabWidget_WildMons - QTableWidget *speciesTable = static_cast(tabWidget->widget(tabIndex++));//static_cast(ui->tabWidget_WildMons->widget(tabIndex++)); - clearTable(speciesTable); + //QTableWidget *speciesTable = tabWidget->tableAt(tabIndex); + //clearTable(speciesTable); + tabWidget->clearTableAt(tabIndex); //speciesTable->horizontalHeader()->hide(); - if (project->wildMonData.contains(map->constantName) && header.wildMons[field].active) { - int i = 1; - - //ui->stackedWidget_WildMons->insertWidget(0, speciesTable); - //return; - - speciesTable->setRowCount(header.wildMons[field].wildPokemon.size()); - speciesTable->setColumnCount(6);// TODO: stretch last column? - - QStringList landMonTableHeaders; - landMonTableHeaders << "Index" << "Species" << "Min Level" << "Max Level" << "Index Percentage" << "Encounter Rate"; - speciesTable->setHorizontalHeaderLabels(landMonTableHeaders); - speciesTable->horizontalHeader()->show(); - speciesTable->verticalHeader()->hide(); - speciesTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - speciesTable->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - - speciesTable->setShowGrid(false); - - // set encounter rate slider - // don't forget to add number label next to it - QFrame *encounterFrame = new QFrame; - QHBoxLayout *encounterLayout = new QHBoxLayout; - - QSlider *encounterRate = new QSlider(Qt::Horizontal); - encounterRate->setMinimum(1); - encounterRate->setMaximum(100); - - QLabel *encounterLabel = new QLabel; - connect(encounterRate, &QSlider::valueChanged, [=](int value){ - encounterLabel->setText(QString::number(value)); - }); - encounterRate->setValue(header.wildMons[field].encounterRate); - - encounterLayout->addWidget(encounterLabel); - encounterLayout->addWidget(encounterRate); - - encounterFrame->setLayout(encounterLayout); - - speciesTable->setCellWidget(0, 5, encounterFrame); - - for (WildPokemon mon : header.wildMons[field].wildPokemon) { - createSpeciesTableRow(project, speciesTable, mon, i, field); - i++; - } + if (project->wildMonData.contains(map->constantName) && header.wildMons[fieldName].active) { + tabWidget->populateTab(tabIndex, header.wildMons[fieldName], fieldName); } else { - // create button to add this field to this map + //unusedIndices.append + tabWidget->setTabActive(tabIndex, false); + //tabWidget } + tabIndex++; } + //connect(tabWidget, &QTabWidget::tabBarDoubleClicked, [=](int clickedTab) { + // if (!unusedIndices.contains(clickedTab)) return; + + // project->wildMonData.value(map->constantName).value(label).active = true + // header.wildMons[field].wildPokemon = QVector... + + // qDebug() << "double clicked tab" << clickedTab; + + //displayWildMonTables(); + //}); } stack->setCurrentIndex(0); } @@ -291,7 +264,7 @@ void Editor::saveEncounterTabData() { for (int groupIndex = 0; groupIndex < encounterMap.keys().size(); groupIndex++) { // - QTabWidget *tabWidget = static_cast(stack->widget(groupIndex)); + MonTabWidget *tabWidget = static_cast(stack->widget(groupIndex)); // TODO: verify this exists before so no segfault WildPokemonHeader &encounterHeader = encounterMap[labelCombo->itemText(groupIndex)]; @@ -304,12 +277,13 @@ void Editor::saveEncounterTabData() { int fieldIndex = 0; for (QPair> monField : project->wildMonFields) { QString fieldName = monField.first; - if (!encounterHeader.wildMons.contains(fieldName) - || encounterHeader.wildMons[fieldName].wildPokemon.empty() - || !encounterHeader.wildMons[fieldName].active) continue; + //if (!encounterHeader.wildMons.contains(fieldName) + // || encounterHeader.wildMons[fieldName].wildPokemon.empty() + // || !encounterHeader.wildMons[fieldName].active) continue; + if (!tabWidget->isTabEnabled(fieldIndex++)) continue; // project->wildMonData //qDebug() << monField.first << "mons"; - QTableWidget *monTable = static_cast(tabWidget->widget(fieldIndex++)); + QTableWidget *monTable = static_cast(tabWidget->widget(fieldIndex - 1)); QVector newWildMons; @@ -323,6 +297,7 @@ void Editor::saveEncounterTabData() { newWildMons.append(newWildMon);//(speciesCombo->currentText()); } // Brackets because need a reference to this object. A safety check is done at the top. + encounterHeader.wildMons[fieldName].active = true; encounterHeader.wildMons[fieldName].wildPokemon = newWildMons; encounterHeader.wildMons[fieldName].encounterRate = monTable->findChild()->value(); //fieldIndex++; diff --git a/src/ui/montabwidget.cpp b/src/ui/montabwidget.cpp new file mode 100644 index 00000000..8a6cbb6c --- /dev/null +++ b/src/ui/montabwidget.cpp @@ -0,0 +1,209 @@ +// montablewidget.cpp + +#include "montabwidget.h" +#include "project.h" + +MonTabWidget::MonTabWidget(Project *project, QWidget *parent) : QTabWidget(parent) { + // + this->project = project; + populate(); + installEventFilter(this); +} + +bool MonTabWidget::eventFilter(QObject *object, QEvent *event) { + // + // press right mouse button + if (event->type() == QEvent::MouseButtonPress + && static_cast(event)->button() == Qt::RightButton) { + // + QPoint eventPos = static_cast(event)->pos(); + int tabIndex = tabBar()->tabAt(eventPos); + if (tabIndex > -1) { + askActivateTab(tabIndex, eventPos); + } + // + } else { + // + } +} + +void MonTabWidget::populate() { + //QPushButton *newTabButton = new QPushButton("Configure JSON..."); + //QObject::connect(newTabButton, &QPushButton::clicked, [=](){ + // // TODO + // qDebug() << "configure json pressed"; + //}); + //tabWidget->setCornerWidget(newTabButton); + + // delete everything in the tab widget here? no + + Fields fields = project->wildMonFields; + activeTabs = QVector(fields.size(), false); + + for (QPair> field : fields) { + QTableWidget *table = new QTableWidget; + table->setEditTriggers(QAbstractItemView::NoEditTriggers); + table->setFocusPolicy(Qt::NoFocus); + table->setSelectionMode(QAbstractItemView::NoSelection); + table->clearFocus(); + addTab(table, field.first); + } +} + +void MonTabWidget::askActivateTab(int tabIndex, QPoint menuPos) { + if (activeTabs[tabIndex]) return; + + QMenu contextMenu(this); + + QString tabText = tabBar()->tabText(tabIndex); + QAction actionActivateTab(QString("Add %1 data for this map...").arg(tabText), this); + connect(&actionActivateTab, &QAction::triggered, [=](){ + // + //qDebug() << "activate tab" << tabIndex; + clearTableAt(tabIndex); + populateTab(tabIndex, getDefaultMonInfo(project->wildMonFields.at(tabIndex)), tabText); + setCurrentIndex(tabIndex); + });//SIGNAL(triggered()), this, SLOT(removeDataPoint())); + contextMenu.addAction(&actionActivateTab); + + contextMenu.exec(mapToGlobal(menuPos)); +} + +void MonTabWidget::clearTableAt(int tabIndex) { + QTableWidget *table = tableAt(tabIndex); + if (table) { + table->clear(); + table->horizontalHeader()->hide(); + } +} + +void MonTabWidget::populateTab(int tabIndex, WildMonInfo monInfo, QString fieldName) { + // + int i = 1; + + //ui->stackedWidget_WildMons->insertWidget(0, speciesTable); + //return; + + QTableWidget *speciesTable = tableAt(tabIndex); + + speciesTable->setRowCount(monInfo.wildPokemon.size()); + speciesTable->setColumnCount(6);// TODO: stretch last column? + + QStringList landMonTableHeaders; + landMonTableHeaders << "Index" << "Species" << "Min Level" << "Max Level" << "Index Percentage" << "Encounter Rate"; + speciesTable->setHorizontalHeaderLabels(landMonTableHeaders); + speciesTable->horizontalHeader()->show(); + speciesTable->verticalHeader()->hide(); + speciesTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + speciesTable->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + + speciesTable->setShowGrid(false); + + // set encounter rate slider + // don't forget to add number label next to it + QFrame *encounterFrame = new QFrame; + QHBoxLayout *encounterLayout = new QHBoxLayout; + + QSlider *encounterRate = new QSlider(Qt::Horizontal); + encounterRate->setMinimum(1); + encounterRate->setMaximum(100); + + QLabel *encounterLabel = new QLabel; + connect(encounterRate, &QSlider::valueChanged, [=](int value){ + encounterLabel->setText(QString::number(value)); + }); + encounterRate->setValue(monInfo.encounterRate); + + encounterLayout->addWidget(encounterLabel); + encounterLayout->addWidget(encounterRate); + + encounterFrame->setLayout(encounterLayout); + + speciesTable->setCellWidget(0, 5, encounterFrame); + + for (WildPokemon mon : monInfo.wildPokemon) { + createSpeciesTableRow(speciesTable, mon, i, fieldName); + i++; + } + this->setTabActive(tabIndex, true); +} + +// TODO: just move these funcs to editor.cpp +void MonTabWidget::createSpeciesTableRow(QTableWidget *table, WildPokemon mon, int index, QString fieldName) { + // + QPixmap monIcon = QPixmap(project->speciesToIconPath.value(mon.species)).copy(0, 0, 32, 32); + + QLabel *monNum = new QLabel(QString("%1.").arg(QString::number(index))); + + QLabel *monLabel = new QLabel(); + monLabel->setPixmap(monIcon); + + QComboBox *monSelector = new QComboBox; + monSelector->setMinimumContentsLength(20); + monSelector->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength); + monSelector->addItems(project->speciesToIconPath.keys()); + monSelector->setCurrentText(mon.species); + monSelector->setEditable(true); + + QObject::connect(monSelector, &QComboBox::currentTextChanged, [=](QString newSpecies){ + QPixmap monIcon = QPixmap(project->speciesToIconPath.value(newSpecies)).copy(0, 0, 32, 32); + monLabel->setPixmap(monIcon); + }); + + QSpinBox *minLevel = new QSpinBox; + QSpinBox *maxLevel = new QSpinBox; + minLevel->setMinimum(1); + minLevel->setMaximum(100); + maxLevel->setMinimum(1); + maxLevel->setMaximum(100); + minLevel->setValue(mon.minLevel); + maxLevel->setValue(mon.maxLevel); + + int fieldIndex = 0; + for (auto field : project->wildMonFields) { + if (field.first == fieldName) break; + fieldIndex++; + } + QLabel *percentLabel = new QLabel(QString("%1%").arg( + QString::number(project->wildMonFields[fieldIndex].second[index - 1] + ))); + + QFrame *speciesSelector = new QFrame; + QHBoxLayout *speciesSelectorLayout = new QHBoxLayout; + speciesSelectorLayout->addWidget(monLabel); + speciesSelectorLayout->addWidget(monSelector); + speciesSelector->setLayout(speciesSelectorLayout); + + // prevent the spinboxes from being stupidly tall + QFrame *minLevelFrame = new QFrame; + QVBoxLayout *minLevelSpinboxLayout = new QVBoxLayout; + minLevelSpinboxLayout->addWidget(minLevel); + minLevelFrame->setLayout(minLevelSpinboxLayout); + QFrame *maxLevelFrame = new QFrame; + QVBoxLayout *maxLevelSpinboxLayout = new QVBoxLayout; + maxLevelSpinboxLayout->addWidget(maxLevel); + maxLevelFrame->setLayout(maxLevelSpinboxLayout); + + // add widgets to the table + table->setCellWidget(index - 1, 0, monNum); + table->setCellWidget(index - 1, 1, speciesSelector); + table->setCellWidget(index - 1, 2, minLevelFrame); + table->setCellWidget(index - 1, 3, maxLevelFrame); + table->setCellWidget(index - 1, 4, percentLabel); + + // TODO: lock max spinbox to min spinbox +} + +QTableWidget *MonTabWidget::tableAt(int tabIndex) { + return static_cast(this->widget(tabIndex)); +} + + + + + +// +void MonTabWidget::setTabActive(int index, bool active) { + activeTabs[index] = active; + setTabEnabled(index, active); +}