rune editor with runeaspektbuttongroups

This commit is contained in:
mrbesen 2023-06-13 22:40:55 +02:00
parent 201f3665b3
commit a9fa26346f
Signed by untrusted user: MrBesen
GPG Key ID: 596B2350DCD67504
9 changed files with 168 additions and 82 deletions

View File

@ -8,6 +8,7 @@ namespace Ui {
class RuneAspektButton; class RuneAspektButton;
} }
class RuneAspektButtonGroup;
class RuneAspektButton : public QPushButton { class RuneAspektButton : public QPushButton {
Q_OBJECT Q_OBJECT
@ -15,29 +16,26 @@ public:
explicit RuneAspektButton(QWidget* parent = nullptr); explicit RuneAspektButton(QWidget* parent = nullptr);
~RuneAspektButton(); ~RuneAspektButton();
void setAspektsVector(std::vector<uint32_t>& aspekts);
void setAspketSlot(int slot);
void setAspektId(uint32_t id); void setAspektId(uint32_t id);
void setButtonGroup(RuneAspektButtonGroup* group);
bool isSelected() const; bool isSelected() const;
signals: signals:
void aspektToggled(bool newState); void aspektToggled(int aspekt);
public slots: public slots:
void buttonPressed(); void buttonPressed();
void dataChanged(); void dataChanged(); // triggers a refresh
private slots: private slots:
void setShowSelection(bool selected); // show/hide the red border void setShowSelection(bool selected); // show/hide the red border
public: public:
uint32_t aspektId = 0; uint32_t aspektId = 0;
int aspektSlot = -1;
private: private:
Ui::RuneAspektButton* ui; Ui::RuneAspektButton* ui;
RuneAspektButtonGroup* group = nullptr;
std::vector<uint32_t>* aspekts = nullptr;
}; };

View File

@ -0,0 +1,31 @@
#pragma once
#include <cstdint>
#include <QObject>
#include <QVector>
class RuneAspektButton;
class RuneAspektButtonGroup : public QObject {
Q_OBJECT
public:
RuneAspektButtonGroup(QObject* parent, uint32_t size);
virtual ~RuneAspektButtonGroup();
void addButton(RuneAspektButton* button);
void setSelectedRunes(const QVector<int>& newRunes);
constexpr const QVector<int>& getSelectedRunes() const { return selectedRune; }
constexpr uint32_t getSize() const { return size; }
signals:
void changed(); // signal that the group was changed -> all buttons should refresh
private slots:
void buttonPressed(int aspektId);
private:
QVector<int> selectedRune;
uint32_t size = 0;
};

View File

@ -3,6 +3,7 @@
#include <vector> #include <vector>
#include <QDialog> #include <QDialog>
#include <QVector>
#include "runeaspekt.h" #include "runeaspekt.h"
#include "runepage.h" #include "runepage.h"
@ -14,6 +15,7 @@ namespace Ui {
class ClientAPI; class ClientAPI;
class RuneAspektButton; class RuneAspektButton;
class RuneAspektButtonGroup;
class QGridLayout; class QGridLayout;
class RuneEditor : public QDialog { class RuneEditor : public QDialog {
@ -34,20 +36,17 @@ public:
void setName(QString text); void setName(QString text);
QString getName() const; QString getName() const;
constexpr const RunePage& getRunepage() const { return runepage; } const RunePage& getRunepage();
signals: signals:
void selectionChanged(); void selectionChanged();
private slots:
void aspectCliecked();
private: private:
const RuneStyle* getRuneStyle(uint32_t id) const; const RuneStyle* getRuneStyle(uint32_t id) const;
RuneAspektButton* createStyleButton(const RuneStyle& rs, bool selected); RuneAspektButton* createStyleButton(const RuneStyle& rs, bool selected);
RuneAspektButton* createAspektButton(const RuneAspekt& ra); RuneAspektButton* createAspektButton(uint32_t perk);
RuneAspektButton* createButtonFromResource(QString resource); RuneAspektButton* createButtonFromResource(QString resource);
void fillRuneStyle(QGridLayout* target, const RuneStyle& rs, bool subRunes = false); void fillRuneStyle(QGridLayout* target, const RuneStyle& rs);
QString fixString(QString text); QString fixString(QString text);
Ui::RuneEditor* ui; Ui::RuneEditor* ui;
@ -56,4 +55,8 @@ private:
::RunePage runepage; ::RunePage runepage;
std::vector<RuneAspekt> aspekts; std::vector<RuneAspekt> aspekts;
std::vector<RuneStyle> styles; std::vector<RuneStyle> styles;
// 0 = keystone, 1-3 = main runes, 4 = sub runes (2), 5-7 = stats
QVector<RuneAspektButtonGroup*> groups;
}; };

View File

@ -55,6 +55,7 @@ SOURCES += \
src/memoryimagecache.cpp \ src/memoryimagecache.cpp \
src/restclient.cpp \ src/restclient.cpp \
src/runeaspektbutton.cpp \ src/runeaspektbutton.cpp \
src/runeaspektbuttongroup.cpp \
src/runedisplay.cpp \ src/runedisplay.cpp \
src/runeeditor.cpp \ src/runeeditor.cpp \
src/runemanager.cpp \ src/runemanager.cpp \
@ -88,6 +89,7 @@ HEADERS += \
include/memoryimagecache.h \ include/memoryimagecache.h \
include/restclient.h \ include/restclient.h \
include/runeaspektbutton.h \ include/runeaspektbutton.h \
include/runeaspektbuttongroup.h \
include/runedisplay.h \ include/runedisplay.h \
include/runeeditor.h \ include/runeeditor.h \
include/runemanager.h \ include/runemanager.h \

View File

@ -36,6 +36,12 @@ static std::vector<QString> readProcFile(const QString& path) {
return out; return out;
} }
// test server
#if 0
std::shared_ptr<ClientAccess> ClientAccess::find() {
return std::make_shared<ClientAccess>("password", 4443);
}
#else
std::shared_ptr<ClientAccess> ClientAccess::find() { std::shared_ptr<ClientAccess> ClientAccess::find() {
DIR* procdir = opendir("/proc"); DIR* procdir = opendir("/proc");
@ -81,6 +87,7 @@ std::shared_ptr<ClientAccess> ClientAccess::find() {
return nullptr; return nullptr;
} }
#endif
std::shared_ptr<ClientAccess> findUsingLockfile(const std::vector<QString>& cmdline, pid_t pid) { std::shared_ptr<ClientAccess> findUsingLockfile(const std::vector<QString>& cmdline, pid_t pid) {
// get WINEPREFIX env // get WINEPREFIX env

View File

@ -12,7 +12,7 @@
ClientAPI::ClientAPI(const ClientAccess& ca) : RestClient(ca.getURL()), access(ca), memImageCache(40), imageCache("runes", "") { ClientAPI::ClientAPI(const ClientAccess& ca) : RestClient(ca.getURL()), access(ca), memImageCache(40), imageCache("runes", "") {
basicauth = ca.getBasicAuth(); basicauth = ca.getBasicAuth();
disableCertCheck = true; disableCertCheck = true;
// enableDebugging(); enableDebugging();
} }
ClientAPI::~ClientAPI() {} ClientAPI::~ClientAPI() {}

View File

@ -3,6 +3,8 @@
#include <QDebug> #include <QDebug>
#include "runeaspektbuttongroup.h"
RuneAspektButton::RuneAspektButton(QWidget* parent) : QPushButton(parent), ui(new Ui::RuneAspektButton) { RuneAspektButton::RuneAspektButton(QWidget* parent) : QPushButton(parent), ui(new Ui::RuneAspektButton) {
ui->setupUi(this); ui->setupUi(this);
@ -13,45 +15,25 @@ RuneAspektButton::~RuneAspektButton() {
delete this->ui; delete this->ui;
} }
void RuneAspektButton::setAspektsVector(std::vector<uint32_t>& aspekts) {
this->aspekts = &aspekts;
dataChanged();
}
void RuneAspektButton::setAspketSlot(int slot) {
aspektSlot = slot;
dataChanged();
}
void RuneAspektButton::setAspektId(uint32_t id) { void RuneAspektButton::setAspektId(uint32_t id) {
aspektId = id; aspektId = id;
dataChanged(); dataChanged();
} }
void RuneAspektButton::setButtonGroup(RuneAspektButtonGroup* group) {
this->group = group;
}
bool RuneAspektButton::isSelected() const { bool RuneAspektButton::isSelected() const {
return (aspektSlot >= 0 // aspektSlot is valid return group && group->getSelectedRunes().contains(aspektId);
&& (int) aspekts->size() > aspektSlot // aspektSlot is valid
&& aspektId != 0 // aspektId is valid
&& aspekts->at(aspektSlot) == aspektId); // aspekt is selected
} }
void RuneAspektButton::buttonPressed() { void RuneAspektButton::buttonPressed() {
if(Q_UNLIKELY(!(aspekts && aspektSlot >= 0))) return; emit aspektToggled(aspektId);
// toggle
bool oldState = isSelected();
int newValue = (oldState ? 0 : aspektId);
aspekts->at(aspektSlot) = newValue;
emit aspektToggled(!oldState);
} }
void RuneAspektButton::dataChanged() { void RuneAspektButton::dataChanged() {
if(!aspekts) return;
bool selection = isSelected(); bool selection = isSelected();
qDebug() << text() << " datachanged - isSelected: " << selection; qDebug() << text() << " datachanged - isSelected: " << selection;

View File

@ -0,0 +1,40 @@
#include "runeaspektbuttongroup.h"
#include "runeaspektbutton.h"
#include <QDebug>
RuneAspektButtonGroup::RuneAspektButtonGroup(QObject* parent, uint32_t size) : QObject(parent), selectedRune(), size(size) {
selectedRune.reserve(size*2);
}
RuneAspektButtonGroup::~RuneAspektButtonGroup() {}
void RuneAspektButtonGroup::addButton(RuneAspektButton* button) {
QObject::connect(this, &RuneAspektButtonGroup::changed, button, &RuneAspektButton::dataChanged);
QObject::connect(button, &RuneAspektButton::aspektToggled, this, &RuneAspektButtonGroup::buttonPressed);
button->setButtonGroup(this);
}
void RuneAspektButtonGroup::setSelectedRunes(const QVector<int>& newRunes) {
selectedRune = newRunes;
qDebug() << "selectedRunes changed to: " << selectedRune << " refesching buttons";
emit changed();
}
void RuneAspektButtonGroup::buttonPressed(int aspektId) {
if(selectedRune.contains(aspektId)) {
selectedRune.removeAll(aspektId);
} else {
selectedRune.push_back(aspektId);
if((uint32_t) selectedRune.size() > size) {
selectedRune.removeFirst();
}
}
emit changed();
}

View File

@ -9,8 +9,9 @@
#include "clientapi.h" #include "clientapi.h"
#include "runeaspektbutton.h" #include "runeaspektbutton.h"
#include "runeaspektbuttongroup.h"
RuneEditor::RuneEditor(QWidget* parent) : QDialog(parent), ui(new Ui::RuneEditor) { RuneEditor::RuneEditor(QWidget* parent) : QDialog(parent), ui(new Ui::RuneEditor), groups(8, nullptr) {
ui->setupUi(this); ui->setupUi(this);
QObject::connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &RuneEditor::accept); QObject::connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &RuneEditor::accept);
@ -58,6 +59,17 @@ void RuneEditor::setRunepage(const ::RunePage& rp) {
selectSubStyle(rp.secondaryStyle); selectSubStyle(rp.secondaryStyle);
runepage = rp; runepage = rp;
uint32_t offset = 0;
for(RuneAspektButtonGroup* group : groups) {
if(!group) continue;
QVector<int> selected(group->getSize(), 0);
for(uint32_t i = 0; i < group->getSize(); ++i) {
selected.replace(i, rp.selectedAspects.at(offset));
offset++;
}
group->setSelectedRunes(selected);
}
emit selectionChanged(); emit selectionChanged();
} }
@ -105,9 +117,27 @@ void RuneEditor::selectSubStyle(uint32_t id) {
runepage.secondaryStyle = id; runepage.secondaryStyle = id;
clearLayout(ui->substylePerks); clearLayout(ui->substylePerks);
delete groups.at(4);
// populate perks // populate perks
fillRuneStyle(ui->substylePerks, *substyle, true); RuneAspektButtonGroup* group = new RuneAspektButtonGroup(this, 2);
for(size_t idx = 0; idx < substyle->runeSlots.size(); ++idx) {
const RuneStyleSlot& rss = substyle->runeSlots.at(idx);
if(rss.type != "kMixedRegularSplashable") continue;
for(int perkNr = 0; perkNr < (int) rss.perks.size(); ++perkNr) {
uint32_t perk = rss.perks.at(perkNr);
RuneAspektButton* aspektBtn = createAspektButton(perk);
if(!aspektBtn) continue;
group->addButton(aspektBtn);
ui->substylePerks->addWidget(aspektBtn, idx, perkNr);
}
}
groups.replace(4, group);
} }
} }
@ -127,8 +157,20 @@ QString RuneEditor::getName() const {
return ui->runepageName->text(); return ui->runepageName->text();
} }
void RuneEditor::aspectCliecked() { const RunePage& RuneEditor::getRunepage() {
// do something? runepage.selectedAspects.clear();
runepage.selectedAspects.resize(9, 0);
for(const RuneAspektButtonGroup* group : groups) {
if(!group) continue;
const QVector<int>& selected = group->getSelectedRunes();
for(uint32_t i = 0; i < group->getSize(); ++i) {
runepage.selectedAspects.push_back(selected.at(i));
}
}
return runepage;
} }
const RuneStyle* RuneEditor::getRuneStyle(uint32_t id) const { const RuneStyle* RuneEditor::getRuneStyle(uint32_t id) const {
@ -151,19 +193,25 @@ RuneAspektButton* RuneEditor::createStyleButton(const RuneStyle& rs, bool select
styleBtn->setStyleSheet("border: 1px solid red;"); styleBtn->setStyleSheet("border: 1px solid red;");
} }
QObject::connect(this, &RuneEditor::selectionChanged, styleBtn, &RuneAspektButton::dataChanged);
return styleBtn; return styleBtn;
} }
RuneAspektButton* RuneEditor::createAspektButton(const RuneAspekt& ra) { RuneAspektButton* RuneEditor::createAspektButton(uint32_t perk) {
RuneAspektButton* aspektBtn = createButtonFromResource(ra.iconPath); auto itFound = std::find_if(aspekts.cbegin(), aspekts.cend(), [perk](const RuneAspekt& ra) {
return ra.id == perk;
});
if(!aspektBtn) return nullptr; if(itFound == aspekts.cend()) {
return nullptr;
}
RuneAspektButton* aspektBtn = createButtonFromResource(itFound->iconPath);
aspektBtn->setText(ra.name); aspektBtn->setText(itFound->name);
aspektBtn->setToolTip(ra.tooltip); aspektBtn->setToolTip(itFound->tooltip);
aspektBtn->setAspektsVector(runepage.selectedAspects); aspektBtn->setAspektId(itFound->id);
aspektBtn->setAspektId(ra.id);
return aspektBtn; return aspektBtn;
} }
@ -187,51 +235,26 @@ RuneAspektButton* RuneEditor::createButtonFromResource(QString resource) {
RuneAspektButton* rab = new RuneAspektButton(this); RuneAspektButton* rab = new RuneAspektButton(this);
rab->setIcon(icon); rab->setIcon(icon);
QObject::connect(this, &RuneEditor::selectionChanged, rab, &RuneAspektButton::dataChanged);
QObject::connect(rab, &RuneAspektButton::aspektToggled, this, &RuneEditor::aspectCliecked);
QObject::connect(rab, &RuneAspektButton::aspektToggled, this, &RuneEditor::selectionChanged);
return rab; return rab;
} }
void RuneEditor::fillRuneStyle(QGridLayout* target, const RuneStyle& rs, bool subRunes) { void RuneEditor::fillRuneStyle(QGridLayout* target, const RuneStyle& rs) {
int row = 0;
for(size_t idx = 0; idx < rs.runeSlots.size(); ++idx) { for(size_t idx = 0; idx < rs.runeSlots.size(); ++idx) {
const RuneStyleSlot& rss = rs.runeSlots.at(idx); const RuneStyleSlot& rss = rs.runeSlots.at(idx);
RuneAspektButtonGroup* group = new RuneAspektButtonGroup(this, 1);
if(subRunes && rss.type != "kMixedRegularSplashable") continue;
int rowOffset = 0;
if(subRunes) {
rowOffset = 4;
if(row > 0) {
rowOffset = 3;
}
} else {
if(row >= 4) {
rowOffset = 2;
}
}
for(int perkNr = 0; perkNr < (int) rss.perks.size(); ++perkNr) { for(int perkNr = 0; perkNr < (int) rss.perks.size(); ++perkNr) {
uint32_t perk = rss.perks.at(perkNr); uint32_t perk = rss.perks.at(perkNr);
auto itFound = std::find_if(aspekts.cbegin(), aspekts.cend(), [perk](const RuneAspekt& ra) {
return ra.id == perk;
});
if(itFound == aspekts.cend()) { RuneAspektButton* aspektBtn = createAspektButton(perk);
continue;
}
RuneAspektButton* aspektBtn = createAspektButton(*itFound);
if(!aspektBtn) continue; if(!aspektBtn) continue;
aspektBtn->setAspketSlot(row + rowOffset); group->addButton(aspektBtn);
target->addWidget(aspektBtn, row, perkNr); target->addWidget(aspektBtn, idx, perkNr);
} }
++ row; groups.replace(idx + (idx > 3), group);
} }
} }