#include "main_window.h" #include #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->SetValue(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->SetValue(volume); if (!pitch_slider->IsPressed()) pitch_slider->SetValue(pitch); if (!speed_slider->IsPressed()) speed_slider->SetValue(speed); if (!tempo_slider->IsPressed()) tempo_slider->SetValue(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(); 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); pause_resume_btn = new QPushButton("Pause"); QObject::connect(pause_resume_btn, &QPushButton::pressed, [=,this]() { playback->Pause(); }); restart_btn = new QPushButton("Restart"); 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); 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); 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(); top_row_widget->setLayout(top_row); root_layout->addWidget(top_row_widget); QBoxLayout *bottom_row = new QBoxLayout(QBoxLayout::LeftToRight); 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(); 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); } } }