soundboard/src/buttonmanager.cpp

333 lines
8.8 KiB
C++

#include "buttonmanager.h"
#include "ui_buttonmanager.h"
#include "addnewwhat.h"
#include "editsample.h"
#include "sound.h"
#include <QFileDialog>
#include <QShortcut>
#include <Log.h>
ButtonManager::ButtonManager(Config& conf, MainWindow* parent) : ConfigDialog(conf, parent), ui(new Ui::ButtonManager), mainW(parent) {
ui->setupUi(this);
loadConfig();
QStringList labels;
labels.push_back("Name");
labels.push_back("Samples");
labels.push_back("Shortcut");
ui->buttonTreeWidget->setHeaderLabels(labels);
ui->buttonTreeWidget->setColumnWidth(0, 420);
ui->buttonTreeWidget->header()->setStretchLastSection(false);
ui->buttonTreeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
QShortcut* sc = new QShortcut(QKeySequence(QKeySequence::Save), this);
QObject::connect(sc, SIGNAL( activated() ), this, SLOT( saveChanges() ));
}
ButtonManager::~ButtonManager() {
delete ui;
}
void ButtonManager::addButton() {
AddNewWhat whatshouldbeadded(this);
whatshouldbeadded.exec();
AddNewWhat::ReturnCode type = whatshouldbeadded.returnCode;
if(type == AddNewWhat::ReturnCode::Row) {
// create new row
RowItem* row = addNewRow();
//select the new row
select(row);
return;
}
if(type == AddNewWhat::ReturnCode::Button) {
//get row to create button in
RowItem* row = getCurrentRow();
if(row) {
//create new button in config
row->getConfig().push_back({});
// create new button GUI
ButtonItem* newButton = new ButtonItem(row, row->getConfig().size()-1, workingConfig);
//select the new button
select(newButton);
// start editing
ui->buttonTreeWidget->editItem(newButton, 0);
} else {
Log::error << "no row selected";
}
return;
}
if(type == AddNewWhat::ReturnCode::Sample) {
// create new sample
ButtonItem* btn = getCurrentButton();
if(btn) {
// button to add sample to exists -> start sample editor
QFileDialog fileselector(this);
fileselector.setFileMode(QFileDialog::ExistingFile);
fileselector.setDirectory(QString::fromStdString(Sound::FOLDER));
fileselector.exec();
QStringList filelist = fileselector.selectedFiles();
if(filelist.size() != 1) {
Log::error << "no file selected";
return;
} else {
QString qfile = filelist.at(0);
std::string file = qfile.toStdString();
if(file.find(Sound::FOLDER) != 0) {
Log::error << "file outside of " << Sound::FOLDER << " was selected, that is not allowed";
return;
}
file = file.substr(file.rfind('/')+1); // remove path; only keep filename
Log::info << "selected file: " << file;
//spawn edit dialog
EditSample esample(file, this);
esample.exec();
if(esample.result() == 0) {
Log::info << "Dialog failed";
return;
}
// create sample
Config::SampleConfig sample;
sample.file = file;
sample.offset = esample.getStartTime();
sample.length = esample.getLength();
sample.volume = 1.0f;
btn->getConfig().samples.push_back(sample);
// create SampleItem in GUI
SampleItem* item = new SampleItem(btn, btn->getConfig().samples.size()-1, workingConfig);
btn->setExpanded(true);
select(item);
}
} else {
Log::error << "no button selected";
}
return;
}
}
void ButtonManager::editButton() {
perform<&ButtonManagerItem::edit>();
}
void ButtonManager::deleteButton() {
QTreeWidgetItem* currentSelectedItem = getSelectedItem();
perform<&ButtonManagerItem::remove>();
delete currentSelectedItem;
}
void ButtonManager::upButton() {
QTreeWidgetItem* currentSelectedItem = getSelectedItem();
perform<&ButtonManagerItem::moveUp>();
select(currentSelectedItem);
}
void ButtonManager::downButton() {
QTreeWidgetItem* currentSelectedItem = getSelectedItem();
perform<&ButtonManagerItem::moveDown>();
select(currentSelectedItem);
}
void ButtonManager::itemSelected() {
Log::debug << "item selected";
ButtonManagerItem* item = getSelectedItem<ButtonManagerItem>();
if(item) {
// set buttons
ui->editButton->setEnabled(item->hasEdit());
ui->deleteButton->setEnabled(item->hasRemove());
ui->moveUpButton->setEnabled(item->hasMoveUp());
ui->moveDownButton->setEnabled(item->hasMoveDown());
} else {
Log::info << "no valid item selected";
ui->editButton->setEnabled(false);
ui->deleteButton->setEnabled(false);
ui->moveUpButton->setEnabled(false);
ui->moveDownButton->setEnabled(false);
}
}
void ButtonManager::itemChanged(QTreeWidgetItem* item, int column) {
// only handle own items (should never trigger anyways)
if(!dynamic_cast<ButtonManagerItem*>(item)) return;
if(ButtonItem* button = dynamic_cast<ButtonItem*>(item)) {
if(column == 0) {
// name
button->nameWasChanged();
} else if(column == 2) {
//shortcut
button->keyWasChanged();
}
}
}
void ButtonManager::itemDoubleClicked(QTreeWidgetItem* item) {
if(SampleItem* sample = dynamic_cast<SampleItem*>(item)) {
const Config::SampleConfig& sampleconf = sample->getConfig();
Sound::instance().addPlayback(sampleconf.file, sampleconf.volume, sampleconf.offset, sampleconf.length);
}
}
void ButtonManager::saveChanges() {
// store working config to main config and save
ConfigDialog::saveChanges();
mainW->reloadButtonConfig();
}
void ButtonManager::loadConfig() {
ConfigDialog::loadConfig();
while(ui->buttonTreeWidget->invisibleRootItem()->childCount()) {
auto kid = ui->buttonTreeWidget->invisibleRootItem()->takeChild(0);
delete kid;
}
QTreeWidgetItem* root = ui->buttonTreeWidget->invisibleRootItem();
for(uint8_t rownr = 0; rownr < workingConfig.buttons.size(); ++rownr) {
RowItem* row = new RowItem(root, rownr, workingConfig);
(void) row;
}
}
QDialogButtonBox* ButtonManager::getButtonBox() {
return ui->buttonBox;
}
void ButtonManager::select(QTreeWidgetItem* item) {
QList<QTreeWidgetItem*> selected = ui->buttonTreeWidget->selectedItems();
for(QTreeWidgetItem* selectedItem : selected) {
ui->buttonTreeWidget->setItemSelected(selectedItem, false);
}
ui->buttonTreeWidget->setItemSelected(item, true);
}
QTreeWidgetItem* ButtonManager::getSelectedItem() const {
QList items = ui->buttonTreeWidget->selectedItems();
if(items.size() != 1) {
return nullptr; // not exectly one selected
}
return items.at(0);
}
template<typename T>
T* ButtonManager::getSelectedItem() const {
return dynamic_cast<T*>(getSelectedItem());
}
RowItem* ButtonManager::getCurrentRow(bool create, bool onlyIfSelected) {
QTreeWidgetItem* selectedItem = getSelectedItem();
// no item selected and its allowed to use alternative messures
if(!selectedItem && !onlyIfSelected) {
// no item selected
// search for a empty row
for(uint8_t rownr = 0; rownr < workingConfig.buttons.size(); ++rownr) {
if(workingConfig.buttons.at(rownr).empty()) {
//first empty row
RowItem* row = dynamic_cast<RowItem*>(ui->buttonTreeWidget->invisibleRootItem()->child(rownr));
if(row)
return row;
}
}
// no empty row -> create new row
if(create) {
return addNewRow();
}
return nullptr;
}
// is current selected item a row?
if(RowItem* row = dynamic_cast<RowItem*>(selectedItem)) {
return row;
}
// selected item is button -> take parent
if(ButtonItem* button = dynamic_cast<ButtonItem*>(selectedItem)) {
return button->getParent<RowItem>();
}
// selected item is sample -> take grand parent
if(SampleItem* sample = dynamic_cast<SampleItem*>(selectedItem)) {
if(ButtonItem* button = sample->getParent<ButtonItem>())
return button->getParent<RowItem>();
}
return nullptr;
}
ButtonItem* ButtonManager::getCurrentButton(bool create) const {
// currently unused
(void) create;
QTreeWidgetItem* selectedItem = getSelectedItem();
if(!selectedItem) {
// no item selected
//TODO: search for first empty button, create a new button
return nullptr;
}
// is current selected item a button?
if(ButtonItem* btn = dynamic_cast<ButtonItem*>(selectedItem)) {
return btn;
}
// a sample is selected -> use its parent
if(SampleItem* sample = dynamic_cast<SampleItem*>(selectedItem)) {
return sample->getParent<ButtonItem>();
}
// a row is selected use the first empty button
if(RowItem* row = dynamic_cast<RowItem*>(selectedItem)) {
// search for empty button in current row
auto& rowConf = row->getConfig();
for(uint8_t buttonnr = 0; buttonnr < rowConf.size(); ++buttonnr) {
if(rowConf.at(buttonnr).samples.empty()) {
return row->getChild<ButtonItem>(buttonnr);
}
}
}
return nullptr;
}
RowItem* ButtonManager::addNewRow() {
//TODO: when a row is selected: add after the selected row
workingConfig.buttons.push_back({}); // create a empty vector
RowItem* row = new RowItem(ui->buttonTreeWidget->invisibleRootItem(), workingConfig.buttons.size()-1, workingConfig);
return row;
}
template<void (ButtonManagerItem::*T)()>
void ButtonManager::perform() {
ButtonManagerItem* item = getSelectedItem<ButtonManagerItem>();
if(item) {
(item->*T)();
} else {
Log::info << "no valid item selected";
}
}