525 lines
12 KiB
C++
525 lines
12 KiB
C++
#include "buttonmanageritems.h"
|
|
|
|
#include <algorithm>
|
|
#include <Log.h>
|
|
|
|
#include "editbutton.h"
|
|
#include "editsample.h"
|
|
|
|
ButtonManagerItem::ButtonManagerItem(QTreeWidgetItem* parent, int type, uint8_t pos) : QTreeWidgetItem(parent, type), mparent(parent), pos(pos) {
|
|
}
|
|
|
|
ButtonManagerItem::~ButtonManagerItem() {}
|
|
|
|
bool ButtonManagerItem::hasEdit() const {
|
|
return false;
|
|
}
|
|
|
|
bool ButtonManagerItem::hasRemove() const {
|
|
return false;
|
|
}
|
|
|
|
bool ButtonManagerItem::hasMoveUp() const {
|
|
return false;
|
|
}
|
|
|
|
bool ButtonManagerItem::hasMoveDown() const {
|
|
return false;
|
|
}
|
|
|
|
void ButtonManagerItem::edit() {}
|
|
|
|
void ButtonManagerItem::remove() {}
|
|
|
|
void ButtonManagerItem::moveUp() {}
|
|
|
|
void ButtonManagerItem::moveDown() {}
|
|
|
|
template<typename T>
|
|
T* ButtonManagerItem::getParent() const {
|
|
return dynamic_cast<T*>(mparent);
|
|
}
|
|
|
|
template<typename T>
|
|
T* ButtonManagerItem::getChild(int index) const {
|
|
if(childCount() <= index)
|
|
return nullptr;
|
|
return dynamic_cast<T*>(child(index));
|
|
}
|
|
|
|
template<typename T>
|
|
T* ButtonManagerItem::getLastChild() const {
|
|
return getChild<T>(childCount()-1);
|
|
}
|
|
|
|
template<typename T>
|
|
T* ButtonManagerItem::getSibling(int index) const {
|
|
if(mparent->childCount() <= index || index < 0)
|
|
return nullptr;
|
|
return dynamic_cast<T*>(mparent->child(index));
|
|
}
|
|
|
|
template<typename T>
|
|
T* ButtonManagerItem::getItemAbove() const {
|
|
return getSibling<T>(pos-1);
|
|
}
|
|
|
|
template<typename T>
|
|
T* ButtonManagerItem::getItemBelow() const {
|
|
return getSibling<T>(pos+1);
|
|
}
|
|
|
|
// enforce existence of required templates
|
|
template RowItem* ButtonManagerItem::getParent() const;
|
|
template ButtonItem* ButtonManagerItem::getParent() const;
|
|
template SampleItem* ButtonManagerItem::getParent() const;
|
|
|
|
template RowItem* ButtonManagerItem::getChild(int) const;
|
|
template ButtonItem* ButtonManagerItem::getChild(int) const;
|
|
template SampleItem* ButtonManagerItem::getChild(int) const;
|
|
|
|
template RowItem* ButtonManagerItem::getSibling(int) const;
|
|
template ButtonItem* ButtonManagerItem::getSibling(int) const;
|
|
template SampleItem* ButtonManagerItem::getSibling(int) const;
|
|
|
|
void ButtonManagerItem::reenumerateAllSiblings() {
|
|
for(uint8_t i = 0; i < mparent->childCount(); ++i) {
|
|
ButtonManagerItem* item = getSibling<ButtonManagerItem>(i);
|
|
if(item) {
|
|
item->pos = i;
|
|
item->updatePosition();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ButtonManagerItem::expandTree() {
|
|
ButtonManagerItem* c = this;
|
|
while(c) {
|
|
c->setExpanded(true);
|
|
c = c->getParent<ButtonManagerItem>();
|
|
}
|
|
}
|
|
|
|
void ButtonManagerItem::updateAllPosBellow(int8_t diff, uint8_t size) {
|
|
for(uint8_t i = pos+1; i < size; ++i) {
|
|
ButtonManagerItem* item = getSibling<ButtonManagerItem>(i);
|
|
if(item) {
|
|
item->pos += diff;
|
|
item->updatePosition();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ButtonManagerItem::updatePosition() {}
|
|
|
|
|
|
RowItem::RowItem(QTreeWidgetItem* parent, uint8_t rownr, Config::RootConfig& conf) : ButtonManagerItem(parent, TYPE, rownr), conf(conf) {
|
|
const std::vector<Config::ButtonConfig>& btnrow = conf.buttons.at(rownr);
|
|
|
|
updatePosition();
|
|
setExpanded(true);
|
|
|
|
// iterate buttons in a row
|
|
for(uint8_t btnnr = 0; btnnr < btnrow.size(); btnnr++) {
|
|
ButtonItem* btnItem = new ButtonItem(this, btnnr, conf);
|
|
// no need to use this var, they add themself to their parent (this)
|
|
(void) btnItem;
|
|
}
|
|
}
|
|
|
|
bool RowItem::hasRemove() const {
|
|
return true;
|
|
}
|
|
|
|
bool RowItem::hasMoveUp() const {
|
|
return pos > 0;
|
|
}
|
|
|
|
bool RowItem::hasMoveDown() const {
|
|
return pos < conf.buttons.size()-1;
|
|
}
|
|
|
|
void RowItem::remove() {
|
|
conf.buttons.erase(conf.buttons.begin() + pos);
|
|
|
|
updateAllPosBellow(-1, conf.buttons.size()+1);
|
|
}
|
|
|
|
void RowItem::moveUp() {
|
|
//apply change to config
|
|
conf.buttons.at(pos-1).swap(conf.buttons.at(pos));
|
|
|
|
// apply change in GUI
|
|
|
|
//get Child above
|
|
RowItem* rowaboveItem = getSibling<RowItem>(pos-1);
|
|
if(rowaboveItem) {
|
|
rowaboveItem->pos++;
|
|
rowaboveItem->updatePosition();
|
|
} else {
|
|
Log::error << "row above could not be updated";
|
|
}
|
|
|
|
mparent->removeChild(this);
|
|
|
|
mparent->insertChild(pos-1, this);
|
|
expandTree();
|
|
|
|
pos--;
|
|
updatePosition();
|
|
}
|
|
|
|
void RowItem::moveDown() {
|
|
// moving down is the same as moving the item below up
|
|
RowItem* rowbelow = getSibling<RowItem>(pos+1);
|
|
if(rowbelow) {
|
|
rowbelow->moveUp();
|
|
} else {
|
|
Log::error << "no item below";
|
|
}
|
|
}
|
|
|
|
uint8_t RowItem::getRow() const {
|
|
return pos;
|
|
}
|
|
|
|
void RowItem::updatePosition() {
|
|
setData(0, Qt::ItemDataRole::DisplayRole, QVariant((int) pos+1));
|
|
}
|
|
|
|
std::vector<Config::ButtonConfig>& RowItem::getConfig() {
|
|
return conf.buttons.at(pos);
|
|
}
|
|
|
|
|
|
|
|
|
|
ButtonItem::ButtonItem(RowItem* parent, uint8_t buttonnr, Config::RootConfig& conf) : ButtonManagerItem(parent, TYPE, buttonnr), conf(conf) {
|
|
Config::ButtonConfig& btn = getConfig();
|
|
setData(1, Qt::ItemDataRole::DisplayRole, QVariant(QString::fromStdString(btn.name)));
|
|
setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); // | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled
|
|
|
|
// iterate samples in a button
|
|
for(uint8_t samplenr = 0; samplenr < btn.samples.size(); ++samplenr) {
|
|
SampleItem* sample = new SampleItem(this, samplenr, conf);
|
|
// no need to use this var, they add themself to their parent (this)
|
|
(void) sample;
|
|
}
|
|
}
|
|
|
|
bool ButtonItem::hasEdit() const {
|
|
return true;
|
|
}
|
|
|
|
bool ButtonItem::hasRemove() const {
|
|
return true;
|
|
}
|
|
|
|
bool ButtonItem::hasMoveUp() const {
|
|
return pos > 0 || getParent<RowItem>()->hasMoveUp();
|
|
}
|
|
|
|
bool ButtonItem::hasMoveDown() const {
|
|
return pos < getParent<RowItem>()->getConfig().size()-1 || getParent<RowItem>()->hasMoveDown();
|
|
}
|
|
|
|
void ButtonItem::edit() {
|
|
Config::ButtonConfig& buttonConf = getConfig();
|
|
|
|
EditButton editor;
|
|
editor.setName(buttonConf.name);
|
|
editor.setKey(buttonConf.key);
|
|
editor.exec();
|
|
|
|
if(editor.result() == 0) {
|
|
Log::info << "Dialog failed";
|
|
return;
|
|
}
|
|
|
|
buttonConf.name = editor.getName();
|
|
buttonConf.key = editor.getKey();
|
|
}
|
|
|
|
void ButtonItem::remove() {
|
|
auto& rowconf = getParent<RowItem>()->getConfig();
|
|
rowconf.erase(rowconf.begin() + pos);
|
|
|
|
updateAllPosBellow(-1, rowconf.size()+1);
|
|
}
|
|
|
|
void ButtonItem::moveUp() {
|
|
if(pos == 0) {
|
|
moveToRowAbove();
|
|
return;
|
|
}
|
|
//apply change to config
|
|
auto& rowconf = getParent<RowItem>()->getConfig();
|
|
std::swap(rowconf.at(pos-1), rowconf.at(pos));
|
|
|
|
// apply change in GUI
|
|
|
|
//get Child above
|
|
ButtonItem* buttonaboveItem = getSibling<ButtonItem>(pos-1);
|
|
if(buttonaboveItem) {
|
|
buttonaboveItem->pos++;
|
|
} else {
|
|
Log::error << "button above could not be updated";
|
|
}
|
|
|
|
mparent->removeChild(this);
|
|
|
|
mparent->insertChild(pos-1, this);
|
|
expandTree();
|
|
|
|
pos--;
|
|
}
|
|
|
|
void ButtonItem::moveDown() {
|
|
if(pos == getParent<RowItem>()->getConfig().size()-1) {
|
|
moveToRowBelow();
|
|
return;
|
|
}
|
|
|
|
// moving down is the same as moving the item below up
|
|
ButtonItem* buttonbelow = getSibling<ButtonItem>(pos+1);
|
|
if(buttonbelow) {
|
|
buttonbelow->moveUp();
|
|
} else {
|
|
Log::error << "no item below";
|
|
}
|
|
}
|
|
|
|
void ButtonItem::nameWasChanged() {
|
|
std::string newName = data(1, Qt::ItemDataRole::DisplayRole).toString().toStdString();
|
|
getConfig().name = newName;
|
|
}
|
|
|
|
Config::ButtonConfig& ButtonItem::getConfig() {
|
|
return getParent<RowItem>()->getConfig().at(pos);
|
|
}
|
|
|
|
void ButtonItem::moveToRowAbove() {
|
|
// get row above
|
|
RowItem* rowabove = getParent<RowItem>()->getItemAbove<RowItem>();
|
|
if(!rowabove) {
|
|
Log::error << "no row above!";
|
|
return;
|
|
}
|
|
|
|
// apply change in config
|
|
auto& rowconf = getParent<RowItem>()->getConfig();
|
|
auto& newrowconf = rowabove->getConfig();
|
|
|
|
newrowconf.push_back(rowconf.front());
|
|
rowconf.erase(rowconf.begin());
|
|
|
|
// update buttons in old row
|
|
// updateAllPosBellow(-1, rowconf.size()+1);
|
|
|
|
// remove button from this row and attach to other
|
|
getParent<RowItem>()->removeChild(this);
|
|
|
|
reenumerateAllSiblings(); // depends on mparent beeing set to the old row
|
|
|
|
rowabove->addChild(this);
|
|
//update local parent
|
|
mparent = rowabove;
|
|
|
|
//update local pos
|
|
pos = newrowconf.size()-1;
|
|
|
|
expandTree();
|
|
}
|
|
|
|
void ButtonItem::moveToRowBelow() {
|
|
// get row below
|
|
RowItem* rowbelow = getParent<RowItem>()->getItemBelow<RowItem>();
|
|
if(!rowbelow) {
|
|
Log::error << "no row below!";
|
|
return;
|
|
}
|
|
|
|
// apply change in config
|
|
auto& rowconf = getParent<RowItem>()->getConfig();
|
|
auto& newrowconf = rowbelow->getConfig();
|
|
|
|
newrowconf.insert(newrowconf.begin(), rowconf.back());
|
|
rowconf.erase(rowconf.end());
|
|
|
|
// remove button from this row and attach to other
|
|
getParent<RowItem>()->removeChild(this);
|
|
|
|
rowbelow->insertChild(0, this);
|
|
//update local parent
|
|
mparent = rowbelow;
|
|
|
|
//update local pos
|
|
pos = 0;
|
|
|
|
//update new buttons below
|
|
updateAllPosBellow(1, newrowconf.size());
|
|
|
|
expandTree();
|
|
}
|
|
|
|
|
|
|
|
|
|
SampleItem::SampleItem(ButtonItem* parent, uint8_t samplenr, Config::RootConfig& conf) : ButtonManagerItem(parent, TYPE, samplenr), conf(conf) {
|
|
const Config::SampleConfig& sample = getConfig();
|
|
updatePosition();
|
|
setText(3, QString::fromStdString(sample.file));
|
|
setToolTip(2, "Doubleclick to play");
|
|
}
|
|
|
|
bool SampleItem::hasEdit() const {
|
|
return true;
|
|
}
|
|
|
|
bool SampleItem::hasRemove() const {
|
|
return true;
|
|
}
|
|
|
|
bool SampleItem::hasMoveUp() const {
|
|
return pos > 0 || getParent<ButtonItem>()->hasMoveUp();
|
|
}
|
|
|
|
bool SampleItem::hasMoveDown() const {
|
|
return pos < getParent<ButtonItem>()->getConfig().samples.size()-1 || getParent<ButtonItem>()->hasMoveDown();
|
|
}
|
|
|
|
void SampleItem::edit() {
|
|
Config::SampleConfig& sammpleConf = getConfig();
|
|
EditSample editor(sammpleConf.file);
|
|
editor.setStartTime(sammpleConf.offset);
|
|
editor.setLength(sammpleConf.length);
|
|
editor.exec();
|
|
|
|
if(editor.result() == 0) {
|
|
Log::info << "Dialog failed";
|
|
return;
|
|
}
|
|
|
|
sammpleConf.offset = editor.getStartTime();
|
|
sammpleConf.length = editor.getLength();
|
|
}
|
|
|
|
void SampleItem::remove() {
|
|
auto& btnconf = getParent<ButtonItem>()->getConfig().samples;
|
|
btnconf.erase(btnconf.begin() + pos);
|
|
|
|
updateAllPosBellow(-1, btnconf.size());
|
|
}
|
|
|
|
void SampleItem::moveUp() {
|
|
if(pos == 0) {
|
|
moveToButtonAbove();
|
|
return;
|
|
}
|
|
//apply change to config
|
|
auto& rowconf = getParent<ButtonItem>()->getConfig().samples;
|
|
std::swap(rowconf.at(pos-1), rowconf.at(pos));
|
|
|
|
// apply change in GUI
|
|
|
|
//get Child above
|
|
SampleItem* sampleAboveItem = getSibling<SampleItem>(pos-1);
|
|
if(sampleAboveItem) {
|
|
sampleAboveItem->pos++;
|
|
} else {
|
|
Log::error << "button above could not be updated";
|
|
}
|
|
|
|
mparent->removeChild(this);
|
|
|
|
mparent->insertChild(pos-1, this);
|
|
expandTree();
|
|
|
|
pos--;
|
|
updatePosition();
|
|
}
|
|
|
|
void SampleItem::moveDown() {
|
|
if(pos == getParent<ButtonItem>()->getConfig().samples.size()-1) {
|
|
moveToButtonBelow();
|
|
return;
|
|
}
|
|
|
|
// moving down is the same as moving the item below up
|
|
SampleItem* samplebelow = getSibling<SampleItem>(pos+1);
|
|
if(samplebelow) {
|
|
samplebelow->moveUp();
|
|
} else {
|
|
Log::error << "no item below";
|
|
}
|
|
}
|
|
|
|
Config::SampleConfig& SampleItem::getConfig() {
|
|
return getParent<ButtonItem>()->getConfig().samples.at(pos);
|
|
}
|
|
|
|
void SampleItem::updatePosition() {
|
|
setData(2, Qt::ItemDataRole::DisplayRole, QVariant((int) pos+1));
|
|
}
|
|
|
|
void SampleItem::moveToButtonAbove() {
|
|
ButtonItem* buttonabove = getParent<ButtonItem>()->getItemAbove<ButtonItem>();
|
|
if(!buttonabove) {
|
|
buttonabove = getParent<ButtonItem>()->getParent<RowItem>()->getItemAbove<RowItem>()->getLastChild<ButtonItem>();
|
|
}
|
|
|
|
// apply change in config
|
|
auto& buttonconf = getParent<ButtonItem>()->getConfig().samples;
|
|
auto& newbuttonconf = buttonabove->getConfig().samples;
|
|
|
|
newbuttonconf.push_back(buttonconf.front());
|
|
buttonconf.erase(buttonconf.begin());
|
|
|
|
// update buttons in old row
|
|
// updateAllPosBellow(-1, rowconf.size()+1);
|
|
|
|
// remove button from this row and attach to other
|
|
getParent<ButtonItem>()->removeChild(this);
|
|
|
|
reenumerateAllSiblings(); // depends on mparent beeing set to the old row
|
|
|
|
buttonabove->addChild(this);
|
|
//update local parent
|
|
mparent = buttonabove;
|
|
|
|
//update local pos
|
|
pos = newbuttonconf.size()-1;
|
|
|
|
expandTree();
|
|
|
|
updatePosition();
|
|
}
|
|
|
|
void SampleItem::moveToButtonBelow() {
|
|
ButtonItem* buttonbelow = getParent<ButtonItem>()->getItemBelow<ButtonItem>();
|
|
if(!buttonbelow) {
|
|
buttonbelow = getParent<ButtonItem>()->getParent<RowItem>()->getItemBelow<RowItem>()->getChild<ButtonItem>(0);
|
|
}
|
|
|
|
// apply change in config
|
|
auto& buttonConf = getParent<ButtonItem>()->getConfig().samples;
|
|
auto& newButtonconf = buttonbelow->getConfig().samples;
|
|
|
|
newButtonconf.insert(newButtonconf.begin(), buttonConf.back());
|
|
buttonConf.erase(buttonConf.end());
|
|
|
|
// remove button from this row and attach to other
|
|
getParent<ButtonItem>()->removeChild(this);
|
|
|
|
buttonbelow->insertChild(0, this);
|
|
//update local parent
|
|
mparent = buttonbelow;
|
|
|
|
//update local pos
|
|
pos = 0;
|
|
|
|
//update new buttons below
|
|
reenumerateAllSiblings();
|
|
|
|
expandTree();
|
|
} |