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 RuneAspektButtonGroup;
class RuneAspektButton : public QPushButton {
Q_OBJECT
@ -15,29 +16,26 @@ public:
explicit RuneAspektButton(QWidget* parent = nullptr);
~RuneAspektButton();
void setAspektsVector(std::vector<uint32_t>& aspekts);
void setAspketSlot(int slot);
void setAspektId(uint32_t id);
void setButtonGroup(RuneAspektButtonGroup* group);
bool isSelected() const;
signals:
void aspektToggled(bool newState);
void aspektToggled(int aspekt);
public slots:
void buttonPressed();
void dataChanged();
void dataChanged(); // triggers a refresh
private slots:
void setShowSelection(bool selected); // show/hide the red border
public:
uint32_t aspektId = 0;
int aspektSlot = -1;
private:
Ui::RuneAspektButton* ui;
std::vector<uint32_t>* aspekts = nullptr;
RuneAspektButtonGroup* group = 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 <QDialog>
#include <QVector>
#include "runeaspekt.h"
#include "runepage.h"
@ -14,6 +15,7 @@ namespace Ui {
class ClientAPI;
class RuneAspektButton;
class RuneAspektButtonGroup;
class QGridLayout;
class RuneEditor : public QDialog {
@ -34,20 +36,17 @@ public:
void setName(QString text);
QString getName() const;
constexpr const RunePage& getRunepage() const { return runepage; }
const RunePage& getRunepage();
signals:
void selectionChanged();
private slots:
void aspectCliecked();
private:
const RuneStyle* getRuneStyle(uint32_t id) const;
RuneAspektButton* createStyleButton(const RuneStyle& rs, bool selected);
RuneAspektButton* createAspektButton(const RuneAspekt& ra);
RuneAspektButton* createAspektButton(uint32_t perk);
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);
Ui::RuneEditor* ui;
@ -56,4 +55,8 @@ private:
::RunePage runepage;
std::vector<RuneAspekt> aspekts;
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/restclient.cpp \
src/runeaspektbutton.cpp \
src/runeaspektbuttongroup.cpp \
src/runedisplay.cpp \
src/runeeditor.cpp \
src/runemanager.cpp \
@ -88,6 +89,7 @@ HEADERS += \
include/memoryimagecache.h \
include/restclient.h \
include/runeaspektbutton.h \
include/runeaspektbuttongroup.h \
include/runedisplay.h \
include/runeeditor.h \
include/runemanager.h \

View File

@ -36,6 +36,12 @@ static std::vector<QString> readProcFile(const QString& path) {
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() {
DIR* procdir = opendir("/proc");
@ -81,6 +87,7 @@ std::shared_ptr<ClientAccess> ClientAccess::find() {
return nullptr;
}
#endif
std::shared_ptr<ClientAccess> findUsingLockfile(const std::vector<QString>& cmdline, pid_t pid) {
// get WINEPREFIX env

View File

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

View File

@ -3,6 +3,8 @@
#include <QDebug>
#include "runeaspektbuttongroup.h"
RuneAspektButton::RuneAspektButton(QWidget* parent) : QPushButton(parent), ui(new Ui::RuneAspektButton) {
ui->setupUi(this);
@ -13,45 +15,25 @@ RuneAspektButton::~RuneAspektButton() {
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) {
aspektId = id;
dataChanged();
}
void RuneAspektButton::setButtonGroup(RuneAspektButtonGroup* group) {
this->group = group;
}
bool RuneAspektButton::isSelected() const {
return (aspektSlot >= 0 // aspektSlot is valid
&& (int) aspekts->size() > aspektSlot // aspektSlot is valid
&& aspektId != 0 // aspektId is valid
&& aspekts->at(aspektSlot) == aspektId); // aspekt is selected
return group && group->getSelectedRunes().contains(aspektId);
}
void RuneAspektButton::buttonPressed() {
if(Q_UNLIKELY(!(aspekts && aspektSlot >= 0))) return;
// toggle
bool oldState = isSelected();
int newValue = (oldState ? 0 : aspektId);
aspekts->at(aspektSlot) = newValue;
emit aspektToggled(!oldState);
emit aspektToggled(aspektId);
}
void RuneAspektButton::dataChanged() {
if(!aspekts) return;
bool selection = isSelected();
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 "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);
QObject::connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &RuneEditor::accept);
@ -58,6 +59,17 @@ void RuneEditor::setRunepage(const ::RunePage& rp) {
selectSubStyle(rp.secondaryStyle);
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();
}
@ -105,9 +117,27 @@ void RuneEditor::selectSubStyle(uint32_t id) {
runepage.secondaryStyle = id;
clearLayout(ui->substylePerks);
delete groups.at(4);
// 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();
}
void RuneEditor::aspectCliecked() {
// do something?
const RunePage& RuneEditor::getRunepage() {
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 {
@ -151,19 +193,25 @@ RuneAspektButton* RuneEditor::createStyleButton(const RuneStyle& rs, bool select
styleBtn->setStyleSheet("border: 1px solid red;");
}
QObject::connect(this, &RuneEditor::selectionChanged, styleBtn, &RuneAspektButton::dataChanged);
return styleBtn;
}
RuneAspektButton* RuneEditor::createAspektButton(const RuneAspekt& ra) {
RuneAspektButton* aspektBtn = createButtonFromResource(ra.iconPath);
RuneAspektButton* RuneEditor::createAspektButton(uint32_t perk) {
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->setToolTip(ra.tooltip);
aspektBtn->setText(itFound->name);
aspektBtn->setToolTip(itFound->tooltip);
aspektBtn->setAspektsVector(runepage.selectedAspects);
aspektBtn->setAspektId(ra.id);
aspektBtn->setAspektId(itFound->id);
return aspektBtn;
}
@ -187,51 +235,26 @@ RuneAspektButton* RuneEditor::createButtonFromResource(QString resource) {
RuneAspektButton* rab = new RuneAspektButton(this);
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;
}
void RuneEditor::fillRuneStyle(QGridLayout* target, const RuneStyle& rs, bool subRunes) {
int row = 0;
void RuneEditor::fillRuneStyle(QGridLayout* target, const RuneStyle& rs) {
for(size_t idx = 0; idx < rs.runeSlots.size(); ++idx) {
const RuneStyleSlot& rss = rs.runeSlots.at(idx);
if(subRunes && rss.type != "kMixedRegularSplashable") continue;
int rowOffset = 0;
if(subRunes) {
rowOffset = 4;
if(row > 0) {
rowOffset = 3;
}
} else {
if(row >= 4) {
rowOffset = 2;
}
}
RuneAspektButtonGroup* group = new RuneAspektButtonGroup(this, 1);
for(int perkNr = 0; perkNr < (int) rss.perks.size(); ++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()) {
continue;
}
RuneAspektButton* aspektBtn = createAspektButton(*itFound);
RuneAspektButton* aspektBtn = createAspektButton(perk);
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);
}
}