/*************************************************************************** BionxControl Copyright © 2025 christoph holzheuer christoph.holzheuer@gmail.com Using: mhs_can_drv.c © 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany Klaus Demlehner, klaus@mhs-elektronik.de @see www.mhs-elektronik.de Based on Bionx data type descriptions from: BigXionFlasher USB V 0.2.4 rev. 97 © 2011-2013 by Thomas Koenig @see www.bigxionflasher.org Bionx Bike Info © 2018 Thorsten Schmidt (tschmidt@ts-soft.de) @see www.ts-soft.de This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. @see https://github.com/bikemike/bionx-bikeinfo ***************************************************************************/ #ifndef BCMAINWINDOW_H #define BCMAINWINDOW_H #include #include #include class BCDeviceView; class BCMainWindow : public QMainWindow, public Ui_BCMainWindow { Q_OBJECT public: BCMainWindow(QWidget *parent = nullptr); virtual ~BCMainWindow(); void setHeaderLabel( const QString& headerText); public slots: //void onValueListReady( BCDevice::ID deviceID ); void onShowDevicePanel( BCDevice::ID deviceID ); void onConnectButtonToggled(bool active ); // Slots für Rückmeldungen vom Runner void onValueUpdated( BCDevice::ID deviceID, int index, BCValue::State state, const QString& newValue="" ); void onSyncDeviceView(); signals: // Internes Signal, um Daten an den Worker Thread zu senden void requestValueUpdate( BCValuePtrConst value); protected: void initMainWindow(); BCXmlLoader _dataManager; // Wir brauchen eine Verbindung zwischen den Views // und dem Device, das sie darstellen. using BCDeviceViews = QHash; BCDeviceViews _devicePanels; BCDeviceView* _currentPanel{}; QThread _worker; BCTransmitter _transmitter; static constexpr const char* BCKeyHeaderLabel = "BCHeaderLabel"; }; class ThemeSwitchButton : public QPushButton { Q_OBJECT public: explicit ThemeSwitchButton(QWidget *parent = nullptr) : QPushButton(parent), m_isDarkMode(true) { // 1. Visuelles Setup: Flach, keine Ränder, Hand-Cursor setFlat(true); setCursor(Qt::PointingHandCursor); setFixedSize(24, 24); // Kleiner Footprint im StatusBar // CSS: Transparent, damit es sich nahtlos in den StatusBar einfügt // Schriftgröße etwas erhöhen, damit die Emojis gut erkennbar sind setStyleSheet(R"( QPushButton { border: none; background-color: transparent; font-size: 11pt; } QPushButton:hover { background-color: rgba(128, 128, 128, 30); // Leichter Hover-Effekt border-radius: 24px; } )"); // 2. Initialer Status (Startet im Dark Mode -> zeigt Mond) updateIcon(); // 3. Klick verbinden connect(this, &QPushButton::clicked, this, &ThemeSwitchButton::toggle); } signals: void themeChanged(bool isDark); private slots: void toggle() { m_isDarkMode = !m_isDarkMode; updateIcon(); emit themeChanged(m_isDarkMode); } private: void updateIcon() { // Logik: // Ist Dark Mode an? Zeige Mond (oder Sonne, je nach Geschmack). // Hier: Zeige das Symbol des AKTUELLEN Modus. setText(m_isDarkMode ? "🌙" : "☀️"); setToolTip(m_isDarkMode ? "Switch to Light Mode" : "Switch to Dark Mode"); } bool m_isDarkMode; }; class BCConnectionWidget : public QWidget { Q_OBJECT public: // Definition der 3 Zustände enum class State { Disconnected, // Grau: Offline / Standby Connected, // Grün: Alles OK Error // Rot: Fehler / Timeout / Abbruch }; Q_ENUM(State) // Damit Qt das Enum kennt (optional, gut für Debugging) explicit BCConnectionWidget(QWidget *parent = nullptr) : QWidget(parent) { QHBoxLayout *layout = new QHBoxLayout(this); layout->setContentsMargins(10, 2, 10, 2); layout->setSpacing(8); // 1. Die LED m_led = new QLabel(this); m_led->setFixedSize(12, 12); // 2. Der Text m_label = new QLabel(this); m_label->setStyleSheet("font-weight: 500;"); // Medium weight layout->addWidget(m_led); layout->addWidget(m_label); // Startzustand setState(State::Disconnected, "Offline"); } public slots: // Hauptfunktion zum Setzen des Status // 'customMessage' ist optional. Wenn leer, wird ein Standardtext genommen. void setState(State state, const QString &customMessage = QString()) { m_state = state; // Standard-Texte, falls keine Nachricht übergeben wurde QString text = customMessage; if (text.isEmpty()) { switch (state) { case State::Connected: text = "Online"; break; case State::Disconnected: text = "Not Connected"; break; case State::Error: text = "Connection Error"; break; } } m_label->setText(text); updateStyle(); } private: void updateStyle() { QString ledStyle; QString labelColor; QString toolTipText; switch (m_state) { case State::Connected: // FLUENT GREEN (Success) ledStyle = "background-color: #107C10; border: 1px solid #0E600E;#FF5F1F; #FF8C00;<- das isses #FF6700"; labelColor = "#FFFFFF"; // Weiß (Hervorgehoben) toolTipText = "Verbindung erfolgreich hergestellt."; break; case State::Error: // FLUENT RED (Critical) ledStyle = "background-color: #C42B1C; border: 1px solid #A80000;"; labelColor = "#FF99A4"; // Ein helleres Rot für Text, damit es auf Dunkel lesbar ist toolTipText = "Kritischer Fehler bei der Verbindung!"; break; case State::Disconnected: default: // FLUENT GRAY (Neutral) // Wir machen es dunkelgrau mit hellem Rand -> "Ausgeschaltet"-Look ledStyle = "background-color: #3B3B3B; border: 1px solid #606060;"; labelColor = "#9E9E9E"; // Ausgegrauter Text toolTipText = "System ist offline."; break; } // Styles anwenden (immer rund machen) m_led->setStyleSheet(ledStyle + "border-radius: 6px;"); // Textfarbe setzen m_label->setStyleSheet(QString("color: %1; font-weight: %2;") .arg(labelColor) .arg(m_state == State::Connected ? "bold" : "normal")); setToolTip(toolTipText); } QLabel *m_led; QLabel *m_label; State m_state; }; #endif // BCMAINWINDOW_H