looper/backends/ui/qt/main_window.cpp

175 lines
7.8 KiB
C++

#include "main_window.h"
#include <QMenuBar>
#include "preferences.h"
void LooperWindow::Pulse() {
auto len = playback->GetLength();
auto pos = playback->GetPosition();
this->slider->SetLimits(0.0, len);
if (!this->slider->IsPressed()) this->slider->SetValueNoSignal(pos);
auto component_count = TimeToComponentCount(len);
bool enable_ui = !playback->IsStopped();
if (enable_ui) {
slider->SetLabel(fmt::format("Position: {}", TimeToString(pos, component_count)).c_str());
slider->SetLimitLabels(TimeToString(0, component_count).c_str(), TimeToString(len).c_str());
} else {
slider->SetLabel("Position");
slider->SetLimitLabels("N/A", "N/A");
}
update_label_setting(labels_visible, icons_visible);
slider->setEnabled(enable_ui && len >= 0.0001);
pause_resume_btn->setEnabled(enable_ui);
stop_btn->setEnabled(enable_ui);
restart_btn->setEnabled(enable_ui);
auto volume = playback->GetVolume();
auto pitch = playback->GetPitch();
auto speed = playback->GetSpeed();
auto tempo = playback->GetTempo();
if (!volume_slider->IsPressed()) volume_slider->SetValueNoSignal(volume);
if (!pitch_slider->IsPressed()) pitch_slider->SetValueNoSignal(pitch);
if (!speed_slider->IsPressed()) speed_slider->SetValueNoSignal(speed);
if (!tempo_slider->IsPressed()) tempo_slider->SetValueNoSignal(tempo);
volume_slider->SetLabel(fmt::format("Volume: {}%", (int)volume).c_str());
pitch_slider->SetLabel(fmt::format("Pitch {:.02f}x", pitch).c_str());
speed_slider->SetLabel(fmt::format("Speed: {:.02f}x", speed).c_str());
tempo_slider->SetLabel(fmt::format("Tempo: {:.02f}x", tempo).c_str());
if (playback->handle_signals(PlaybackSignalFileChanged|PlaybackSignalStarted|PlaybackSignalStopped)) {
if (playback->IsStopped()) {
setWindowTitle("Looper");
} else {
setWindowTitle(fmt::format("{} - Looper", playback->get_current_title().value_or(fs::path(playback->get_current_file().value_or("")).stem().string())).c_str());
}
}
}
LooperWindow::LooperWindow(Playback *playback) : QMainWindow() {
labels_visible = false;
icons_visible = true;
this->layout()->setContentsMargins(QMargins(0, 0, 0, 0));
this->playback = playback;
this->root_layout = new QBoxLayout(QBoxLayout::TopToBottom);
QWidget *central_widget = new QWidget(this);
central_widget->setLayout(this->root_layout);
this->setCentralWidget(central_widget);
prefs_window = new PrefsWindow();
about_window = new AboutWindow();
QMenuBar *bar = this->menuBar();
file_menu = new QMenu("File");
open_item = new QAction("Open...");
file_dialog = new QFileDialog(this);
QObject::connect(file_dialog, &QFileDialog::fileSelected, [=,this](const QString &file) {
playback->Start(file.toUtf8().constData());
});
QObject::connect(open_item, &QAction::triggered, [=,this]() {
file_dialog->show();
});
prefs_item = new QAction("Preferences...");
QObject::connect(prefs_item, &QAction::triggered, [=,this]() {
prefs_window->show();
});
quit_item = new QAction("Quit");
QObject::connect(quit_item, &QAction::triggered, [=,this]() {
qApp->quit();
});
file_menu->addAction(open_item);
file_menu->addAction(prefs_item);
file_menu->addAction(quit_item);
help_menu = new QMenu("Help");
about_item = new QAction("About...");
QObject::connect(about_item, &QAction::triggered, [=,this]() {
about_window->show();
});
help_menu->addAction(about_item);
bar->addMenu(file_menu);
bar->addMenu(help_menu);
root_layout->addWidget(bar);
QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);
root_layout->addSpacerItem(spacer);
QBoxLayout *top_row = new QBoxLayout(QBoxLayout::LeftToRight, this);
pause_resume_btn = new QPushButton("Pause", this);
QObject::connect(pause_resume_btn, &QPushButton::pressed, [=,this]() {
playback->Pause();
});
restart_btn = new QPushButton("Restart", this);
QObject::connect(restart_btn, &QPushButton::pressed, [=,this]() {
playback->Seek(0.0);
});
top_row->addWidget(pause_resume_btn);
top_row->addWidget(restart_btn);
slider = new LooperSlider("seek", "Position", 0.0, 1.0, 0.00000000001, false, this);
slider->DisableModeButton();
slider->UseSlider();
QObject::connect(slider, &LooperSlider::changed, [=,this](double value) {
playback->Seek(value);
});
top_row->addWidget(slider);
stop_btn = new QPushButton("Stop");
QObject::connect(stop_btn, &QPushButton::pressed, [=,this]() {
playback->Stop();
});
top_row->addWidget(stop_btn);
volume_slider = new LooperSlider("volume", "Volume", 0.0, 100.0, 1.0, false, this);
volume_slider->SetLimitLabels("Muted", "Full Volume");
QObject::connect(volume_slider, &LooperSlider::changed, [=,this](double value) {
playback->SetVolume(value);
});
top_row->addWidget(volume_slider);
QWidget *top_row_widget = new QWidget(this);
top_row_widget->setLayout(top_row);
root_layout->addWidget(top_row_widget);
QBoxLayout *bottom_row = new QBoxLayout(QBoxLayout::LeftToRight, this);
speed_slider = new LooperSlider("speed", "Speed", 0.25, 4.0, 0.01, true);
pitch_slider = new LooperSlider("pitch", "Pitch", 0.25, 4.0, 0.01, true);
tempo_slider = new LooperSlider("tempo", "Tempo", 0.25, 4.0, 0.01, true);
speed_slider->SetLimitLabels("0.25x", "4.00x");
pitch_slider->SetLimitLabels("0.25x", "4.00x");
tempo_slider->SetLimitLabels("0.25x", "4.00x");
QObject::connect(speed_slider, &LooperSlider::changed, [=,this](double value) {
playback->SetSpeed(value);
});
QObject::connect(pitch_slider, &LooperSlider::changed, [=,this](double value) {
playback->SetPitch(value);
});
QObject::connect(tempo_slider, &LooperSlider::changed, [=,this](double value) {
playback->SetTempo(value);
});
bottom_row->addWidget(speed_slider);
bottom_row->addWidget(pitch_slider);
bottom_row->addWidget(tempo_slider);
QWidget *bottom_row_widget = new QWidget(this);
bottom_row_widget->setLayout(bottom_row);
root_layout->addWidget(bottom_row_widget);
QTimer *timer = new QTimer(this);
QObject::connect(timer, &QTimer::timeout, [=,this]() {
Pulse();
});
timer->setTimerType(Qt::TimerType::PreciseTimer);
timer->setSingleShot(false);
timer->setInterval(1);
timer->start();
QObject::connect(prefs_window, &PrefsWindow::settings_changed, this, &LooperWindow::update_label_setting);
//setLayout(layout);
}
void LooperWindow::update_label_setting(bool labels_visible, bool icons_visible) {
this->labels_visible = labels_visible;
this->icons_visible = icons_visible;
for (auto *slider : {volume_slider, speed_slider, tempo_slider, pitch_slider, slider}) {
slider->SetShowButtonIcon(icons_visible);
slider->SetShowButtonText(labels_visible);
}
QString strings[] = {"Restart", "Stop", (playback->IsPaused() && !playback->IsStopped()) ? "Resume" : "Pause"};
QIcon icons[] = {QIcon::fromTheme("view-refresh"), QIcon::fromTheme("media-playback-stop"), QIcon::fromTheme((playback->IsPaused() && !playback->IsStopped()) ? "media-playback-start" : "media-playback-pause")};
QPushButton *buttons[] = {restart_btn, stop_btn, pause_resume_btn};
for (int i = 0; i < 3; i++) {
QIcon icon = icons[i];
if (icon.isNull() || labels_visible) {
buttons[i]->setText(strings[i]);
} else {
buttons[i]->setText("");
}
if (icons_visible && !icon.isNull()) {
buttons[i]->setIcon(icons[i]);
} else {
QIcon emptyIcon;
buttons[i]->setIcon(emptyIcon);
}
}
}