diff --git a/OSBindings/Qt/mainwindow.cpp b/OSBindings/Qt/mainwindow.cpp index 1f4d797eb..3afe5e70e 100644 --- a/OSBindings/Qt/mainwindow.cpp +++ b/OSBindings/Qt/mainwindow.cpp @@ -74,6 +74,9 @@ void MainWindow::deleteMachine() { if(controlsMenu) menuBar()->removeAction(controlsMenu->menuAction()); if(inputMenu) menuBar()->removeAction(inputMenu->menuAction()); displayMenu = enhancementsMenu = controlsMenu = inputMenu = nullptr; + + // Remove the status bar, if any. + setStatusBar(nullptr); } MainWindow::~MainWindow() { @@ -453,6 +456,9 @@ void MainWindow::launchMachine() { // Push the help menu after any that were just added. addHelpMenu(); + + // Add activity LED UI. + addActivityObserver(); } void MainWindow::addDisplayMenu(const std::string &machinePrefix, const std::string &compositeColour, const std::string &compositeMono, const std::string &svideo, const std::string &rgb) { @@ -1320,3 +1326,36 @@ void MainWindow::restoreSelections() { #undef CheckBox #undef ComboBox } + +// MARK: - Activity observation + +void MainWindow::addActivityObserver() { + auto activitySource = machine->activity_source(); + if(!activitySource) return; + + setStatusBar(new QStatusBar()); + activitySource->set_activity_observer(this); +} + +void MainWindow::register_led(const std::string &name) { + ledStatuses[name] = false; + updateStatusBarText(); +} + +void MainWindow::set_led_status(const std::string &name, bool isLit) { + ledStatuses[name] = isLit; + updateStatusBarText(); // Assumption here: Qt's attempt at automatic thread confinement will work here. +} + +void MainWindow::updateStatusBarText() { + QString fullText; + bool isFirst = true; + for(const auto &pair: ledStatuses) { + if(!isFirst) fullText += " | "; + fullText += QString::fromStdString(pair.first); + fullText += " "; + fullText += pair.second ? "■" : "□"; + isFirst = false; + } + statusBar()->showMessage(fullText); +} diff --git a/OSBindings/Qt/mainwindow.h b/OSBindings/Qt/mainwindow.h index 5d227433d..4bbe4d108 100644 --- a/OSBindings/Qt/mainwindow.h +++ b/OSBindings/Qt/mainwindow.h @@ -15,6 +15,8 @@ #include "../../Analyser/Static/StaticAnalyser.hpp" #include "../../Machines/Utility/MachineForTarget.hpp" +#include "../../Activity/Observer.hpp" + // There are machine-specific controls for the following: #include "../../Machines/ZX8081/ZX8081.hpp" #include "../../Machines/Atari/2600/Atari2600.hpp" @@ -23,7 +25,7 @@ QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE -class MainWindow : public QMainWindow, public Outputs::Speaker::Speaker::Delegate, public ScanTargetWidget::MouseDelegate { +class MainWindow : public QMainWindow, public Outputs::Speaker::Speaker::Delegate, public ScanTargetWidget::MouseDelegate, public Activity::Observer { Q_OBJECT void createActions(); @@ -139,6 +141,12 @@ class MainWindow : public QMainWindow, public Outputs::Speaker::Speaker::Delegat QMenu *inputMenu = nullptr; std::optional keyForEvent(QKeyEvent *); + + void register_led(const std::string &) override; + void set_led_status(const std::string &, bool) override; + std::map ledStatuses; + void addActivityObserver(); + void updateStatusBarText(); }; #endif // MAINWINDOW_H