forked from MrBesen/soundboard
256 lines
6.8 KiB
C++
256 lines
6.8 KiB
C++
#include "mainwindow.h"
|
|
#include "ui_mainwindow.h"
|
|
|
|
#include "buttonmanager.h"
|
|
#include "editsample.h"
|
|
|
|
#include <QFileDialog>
|
|
#include <QMessageBox>
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
#include <Log.h>
|
|
|
|
MainWindow::MainWindow(const std::string& binary, QWidget* parent) : QMainWindow(parent), ui(new Ui::Soundboard), config(binary) {
|
|
ui->setupUi(this);
|
|
|
|
up = new QxtGlobalShortcut(QKeySequence("Shift+Up"));
|
|
down = new QxtGlobalShortcut(QKeySequence("Shift+Down"));
|
|
left = new QxtGlobalShortcut(QKeySequence("Shift+Left"));
|
|
right = new QxtGlobalShortcut(QKeySequence("Shift+Right"));
|
|
play = new QxtGlobalShortcut(QKeySequence("Shift+Num+Enter"));
|
|
|
|
QKeySequence seq(QString::fromStdString("Shift+Num+0"));
|
|
stopGlobal = new QxtGlobalShortcut(seq);
|
|
|
|
reloadConfig();
|
|
|
|
QObject::connect(ui->reloadButton, SIGNAL(clicked()), this, SLOT(reloadConfig()));
|
|
QObject::connect(ui->stopButton, SIGNAL( clicked() ), this, SLOT( stop() ));
|
|
QObject::connect(ui->actionSaveConfig, SIGNAL( triggered() ), this, SLOT( saveConfig() ));
|
|
QObject::connect(ui->actionButtonManager, SIGNAL( triggered() ), this, SLOT( openButtonManager() ));
|
|
QObject::connect(ui->alwaysOnTop, SIGNAL( stateChanged(int) ), this, SLOT( alwaysOnTopSettingChange(int) ));
|
|
QObject::connect(stopGlobal, SIGNAL( activated() ), this, SLOT( stop() ));
|
|
QObject::connect(this, SIGNAL(newStatusMessage(const QString&)), ui->statusbar, SLOT(showMessage(const QString&)));
|
|
|
|
QObject::connect(up, SIGNAL( activated() ), this, SLOT( moveUp() ));
|
|
QObject::connect(down, SIGNAL( activated() ), this, SLOT( moveDown() ));
|
|
QObject::connect(left, SIGNAL( activated() ), this, SLOT( moveLeft() ));
|
|
QObject::connect(right, SIGNAL( activated() ), this, SLOT( moveRight() ));
|
|
QObject::connect(play, SIGNAL( activated() ), this, SLOT( playCurrent() ));
|
|
}
|
|
|
|
MainWindow::~MainWindow() {
|
|
delete ui;
|
|
delete stopGlobal;
|
|
|
|
delete up;
|
|
delete down;
|
|
delete left;
|
|
delete right;
|
|
delete play;
|
|
|
|
Sound::deinitInstance();
|
|
}
|
|
|
|
void MainWindow::reloadConfig() {
|
|
Log::info << "realodConfig()";
|
|
|
|
QString loaded = QString::fromStdString("loading config");
|
|
emit newStatusMessage(loaded);
|
|
|
|
config.load();
|
|
|
|
loadSoundFromConfig();
|
|
|
|
removeAllButtons();
|
|
|
|
loadButtonsFromConfig();
|
|
|
|
QString done = QString::fromStdString("config loaded");
|
|
emit newStatusMessage(done);
|
|
|
|
Log::info << "realodConfig() done";
|
|
}
|
|
|
|
void MainWindow::stop() {
|
|
Sound::instance().stopAll();
|
|
}
|
|
|
|
static uint8_t wrap(uint8_t a, uint8_t max) {
|
|
if(a >= max)
|
|
return max-1;
|
|
return a;
|
|
}
|
|
|
|
static uint8_t wrap0(uint8_t a, uint8_t max) {
|
|
if(a >= max)
|
|
return 0;
|
|
return a;
|
|
}
|
|
|
|
void MainWindow::moveUp() {
|
|
reselectNext([max = ui->gridLayout->rowCount()](uint8_t&, uint8_t& y){ y = wrap(--y, max); });
|
|
}
|
|
|
|
void MainWindow::moveDown() {
|
|
reselectNext([max = ui->gridLayout->rowCount()](uint8_t&, uint8_t& y){ y = wrap0(++y, max); });
|
|
}
|
|
|
|
void MainWindow::moveLeft() {
|
|
reselectNext([max = ui->gridLayout->columnCount()](uint8_t& x, uint8_t&){ x = wrap(--x, max); });
|
|
}
|
|
|
|
void MainWindow::moveRight() {
|
|
reselectNext([max = ui->gridLayout->columnCount()](uint8_t& x, uint8_t&){ x = wrap0(++x, max); });
|
|
}
|
|
|
|
void MainWindow::playCurrent() {
|
|
QLayoutItem* item = ui->gridLayout->itemAtPosition(yCoord, xCoord);
|
|
if(item && item->widget()) {
|
|
SoundButton* button = (SoundButton*) item->widget();
|
|
button->click();
|
|
}
|
|
}
|
|
|
|
void MainWindow::reloadButtonConfig() {
|
|
removeAllButtons();
|
|
loadButtonsFromConfig();
|
|
}
|
|
|
|
void MainWindow::alwaysOnTopSettingChange(int status) {
|
|
Qt::WindowFlags eFlags = windowFlags();
|
|
Log::debug << "status: " << status;
|
|
if(status) {
|
|
setWindowFlags(eFlags | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
|
|
} else {
|
|
setWindowFlags(eFlags & ~(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint));
|
|
}
|
|
|
|
show();
|
|
}
|
|
|
|
void MainWindow::saveConfig() {
|
|
Log::info << "save Config";
|
|
config.save();
|
|
}
|
|
|
|
void MainWindow::openButtonManager() {
|
|
Log::info << "openButtonManager";
|
|
|
|
ButtonManager buttonManager(config, this);
|
|
buttonManager.exec();
|
|
|
|
// reload button config
|
|
if(buttonManager.result() == QMessageBox::ButtonRole::AcceptRole) {
|
|
removeAllButtons();
|
|
loadButtonsFromConfig();
|
|
}
|
|
}
|
|
|
|
void MainWindow::loadSoundFromConfig() {
|
|
Sound& sound = Sound::instance(); // init sound
|
|
sound.reset();
|
|
const std::vector<std::string>& devices = config.rootConfig.audio.devices;
|
|
for (const std::string& device : devices) {
|
|
Log::note << "loadAudio device: \"" << device << '"';
|
|
|
|
if (!sound.addDeviceWithName(device)) {
|
|
Log::warn << "AudioDevice could not be loaded: \"" << device << '"';
|
|
QString done = QString::fromStdString("Sound Device: " + device + " not found!");
|
|
emit newStatusMessage(done);
|
|
return;
|
|
}
|
|
}
|
|
|
|
Log::debug << "Sound devices loaded";
|
|
|
|
Sound::FOLDER = config.rootConfig.audioPath;
|
|
Log::debug << "Sound::FOLDER: " << Sound::FOLDER;
|
|
}
|
|
|
|
void MainWindow::removeAllButtons() {
|
|
//remove old buttons
|
|
for (SoundButton* sb : soundbuttons) {
|
|
ui->gridLayout->removeWidget(sb);
|
|
delete sb;
|
|
}
|
|
soundbuttons.clear();
|
|
}
|
|
|
|
void MainWindow::loadButtonsFromConfig() {
|
|
int x = 0;
|
|
int y = 0;
|
|
const std::vector<std::vector<Config::ButtonConfig>>& buttonConfigs = config.rootConfig.buttons;
|
|
for (const std::vector<Config::ButtonConfig>& line : buttonConfigs) {
|
|
if(line.empty()) continue;
|
|
|
|
for (const Config::ButtonConfig& bc : line) {
|
|
if (!bc.isValid()) continue;
|
|
|
|
SoundButton* sb = new SoundButton(bc.name, bc.key);
|
|
for(const Config::SampleConfig& sc : bc.samples) {
|
|
if(!sc.isValid()) continue;
|
|
|
|
SoundButton::Sample sample = {sc.file, sc.offset, sc.length, sc.volume};
|
|
sb->addSample(sample);
|
|
}
|
|
|
|
soundbuttons.push_back(sb);
|
|
|
|
ui->gridLayout->addWidget(sb, y, x, 1, bc.width);
|
|
sb->show();
|
|
|
|
x += bc.width;
|
|
}
|
|
//ui->gridLayout->setRowMinimumHeight(y, 60);
|
|
x = 0;
|
|
y++;
|
|
}
|
|
|
|
xCoord = 0;
|
|
yCoord = 0;
|
|
|
|
// select the first button
|
|
QLayoutItem* item = ui->gridLayout->itemAtPosition(0, 0);
|
|
if(item && item->widget()) {
|
|
((SoundButton*) item->widget())->setHighlighted(true);
|
|
}
|
|
|
|
// ui->gridLayout->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
|
|
}
|
|
|
|
void MainWindow::reselectNext(std::function<void(uint8_t&,uint8_t&)> stepf) {
|
|
QLayoutItem* item = ui->gridLayout->itemAtPosition(yCoord, xCoord);
|
|
QLayoutItem* newitem = findNextButton(stepf);
|
|
|
|
if(item != newitem) {
|
|
if(item && item->widget()) {
|
|
((SoundButton*) item->widget())->setHighlighted(false);
|
|
}
|
|
if(newitem && newitem->widget()) {
|
|
((SoundButton*) newitem->widget())->setHighlighted(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
QLayoutItem* MainWindow::findNextButton(std::function<void(uint8_t&,uint8_t&)> stepf) {
|
|
// need copy for while condition
|
|
uint8_t x = xCoord;
|
|
uint8_t y = yCoord;
|
|
|
|
QLayoutItem* currentItem = ui->gridLayout->itemAtPosition(y, x);
|
|
QLayoutItem* item = currentItem;
|
|
|
|
do {
|
|
stepf(x, y);
|
|
item = ui->gridLayout->itemAtPosition(y, x);
|
|
} while(item == currentItem && (x != xCoord || y != yCoord));
|
|
|
|
xCoord = x;
|
|
yCoord = y;
|
|
|
|
// might the same item
|
|
return item;
|
|
} |