From 92b0a0193e9a5fcc3140c1e86c85c457ab750e60 Mon Sep 17 00:00:00 2001 From: Alex Spataru Date: Fri, 1 Oct 2021 04:12:04 -0500 Subject: [PATCH] Fix UI glitches in external window with HiDPI screens --- Serial-Studio.pro | 2 - assets/qml/Dashboard/WidgetDelegate.qml | 21 ++++- src/IO/DataSources/Serial.cpp | 100 ++++++++++++------------ src/Widgets/Common/ExternalWindow.cpp | 61 --------------- src/Widgets/Common/ExternalWindow.h | 54 ------------- src/Widgets/WidgetLoader.cpp | 68 ++++------------ src/Widgets/WidgetLoader.h | 18 +++-- 7 files changed, 99 insertions(+), 225 deletions(-) delete mode 100644 src/Widgets/Common/ExternalWindow.cpp delete mode 100644 src/Widgets/Common/ExternalWindow.h diff --git a/Serial-Studio.pro b/Serial-Studio.pro index b8136ea4..a2ab199c 100644 --- a/Serial-Studio.pro +++ b/Serial-Studio.pro @@ -174,7 +174,6 @@ HEADERS += \ src/Widgets/Common/AnalogGauge.h \ src/Widgets/Common/AttitudeIndicator.h \ src/Widgets/Common/BaseWidget.h \ - src/Widgets/Common/ExternalWindow.h \ src/Widgets/Compass.h \ src/Widgets/DataGroup.h \ src/Widgets/Gauge.h \ @@ -213,7 +212,6 @@ SOURCES += \ src/Widgets/Common/AnalogGauge.cpp \ src/Widgets/Common/AttitudeIndicator.cpp \ src/Widgets/Common/BaseWidget.cpp \ - src/Widgets/Common/ExternalWindow.cpp \ src/Widgets/Compass.cpp \ src/Widgets/DataGroup.cpp \ src/Widgets/Gauge.cpp \ diff --git a/assets/qml/Dashboard/WidgetDelegate.qml b/assets/qml/Dashboard/WidgetDelegate.qml index e76298a1..59c76369 100644 --- a/assets/qml/Dashboard/WidgetDelegate.qml +++ b/assets/qml/Dashboard/WidgetDelegate.qml @@ -21,6 +21,7 @@ */ import QtQuick +import QtQuick.Window import QtQuick.Layouts import QtQuick.Controls @@ -37,7 +38,7 @@ Item { anchors.fill: parent title: loader.widgetTitle icon.source: loader.widgetIcon - onHeaderDoubleClicked: loader.displayWindow() + onHeaderDoubleClicked: externalWindow.visible = true borderColor: Cpp_ThemeManager.datasetWindowBorder WidgetLoader { @@ -56,4 +57,22 @@ Item { source: window anchors.fill: window } + + Window { + id: externalWindow + minimumWidth: 640 + minimumHeight: 480 + title: externalLoader.widgetTitle + palette.base: Cpp_ThemeManager.datasetWindowBackground + palette.window: Cpp_ThemeManager.datasetWindowBackground + flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint + + WidgetLoader { + id: externalLoader + widgetIndex: index + anchors.fill: parent + isExternalWindow: true + widgetVisible: externalWindow.visible + } + } } diff --git a/src/IO/DataSources/Serial.cpp b/src/IO/DataSources/Serial.cpp index a1f2fdcc..c7cd15f4 100644 --- a/src/IO/DataSources/Serial.cpp +++ b/src/IO/DataSources/Serial.cpp @@ -384,21 +384,21 @@ void Serial::setParity(const quint8 parityIndex) // Set parity based on current index switch (parityIndex) { - case 0: - m_parity = QSerialPort::NoParity; - break; - case 1: - m_parity = QSerialPort::EvenParity; - break; - case 2: - m_parity = QSerialPort::OddParity; - break; - case 3: - m_parity = QSerialPort::SpaceParity; - break; - case 4: - m_parity = QSerialPort::MarkParity; - break; + case 0: + m_parity = QSerialPort::NoParity; + break; + case 1: + m_parity = QSerialPort::EvenParity; + break; + case 2: + m_parity = QSerialPort::OddParity; + break; + case 3: + m_parity = QSerialPort::SpaceParity; + break; + case 4: + m_parity = QSerialPort::MarkParity; + break; } // Update serial port config. @@ -420,8 +420,8 @@ void Serial::appendBaudRate(const QString &baudRate) writeSettings(); emit baudRateListChanged(); Misc::Utilities::showMessageBox( - tr("Baud rate registered successfully"), - tr("Rate \"%1\" has been added to baud rate list").arg(baudRate)); + tr("Baud rate registered successfully"), + tr("Rate \"%1\" has been added to baud rate list").arg(baudRate)); } } @@ -442,18 +442,18 @@ void Serial::setDataBits(const quint8 dataBitsIndex) // Obtain data bits value from current index switch (dataBitsIndex) { - case 0: - m_dataBits = QSerialPort::Data5; - break; - case 1: - m_dataBits = QSerialPort::Data6; - break; - case 2: - m_dataBits = QSerialPort::Data7; - break; - case 3: - m_dataBits = QSerialPort::Data8; - break; + case 0: + m_dataBits = QSerialPort::Data5; + break; + case 1: + m_dataBits = QSerialPort::Data6; + break; + case 2: + m_dataBits = QSerialPort::Data7; + break; + case 3: + m_dataBits = QSerialPort::Data8; + break; } // Update serial port configuration @@ -481,15 +481,15 @@ void Serial::setStopBits(const quint8 stopBitsIndex) // Obtain stop bits value from current index switch (stopBitsIndex) { - case 0: - m_stopBits = QSerialPort::OneStop; - break; - case 1: - m_stopBits = QSerialPort::OneAndHalfStop; - break; - case 2: - m_stopBits = QSerialPort::TwoStop; - break; + case 0: + m_stopBits = QSerialPort::OneStop; + break; + case 1: + m_stopBits = QSerialPort::OneAndHalfStop; + break; + case 2: + m_stopBits = QSerialPort::TwoStop; + break; } // Update serial port configuration @@ -526,15 +526,15 @@ void Serial::setFlowControl(const quint8 flowControlIndex) // Obtain flow control value from current index switch (flowControlIndex) { - case 0: - m_flowControl = QSerialPort::NoFlowControl; - break; - case 1: - m_flowControl = QSerialPort::HardwareControl; - break; - case 2: - m_flowControl = QSerialPort::SoftwareControl; - break; + case 0: + m_flowControl = QSerialPort::NoFlowControl; + break; + case 1: + m_flowControl = QSerialPort::HardwareControl; + break; + case 2: + m_flowControl = QSerialPort::SoftwareControl; + break; } // Update serial port configuration @@ -620,12 +620,12 @@ void Serial::readSettings() { // Register standard baud rates QStringList stdBaudRates - = { "300", "1200", "2400", "4800", "9600", "19200", "38400", "57600", - "74880", "115200", "230400", "250000", "500000", "1000000", "2000000" }; + = { "300", "1200", "2400", "4800", "9600", "19200", "38400", "57600", + "74880", "115200", "230400", "250000", "500000", "1000000", "2000000" }; // Get value from settings m_baudRateList = m_settings.value("IO_DataSource_Serial__BaudRates", stdBaudRates) - .toStringList(); + .toStringList(); // Sort baud rate list for (auto i = 0; i < m_baudRateList.count() - 1; ++i) diff --git a/src/Widgets/Common/ExternalWindow.cpp b/src/Widgets/Common/ExternalWindow.cpp deleted file mode 100644 index 100575f2..00000000 --- a/src/Widgets/Common/ExternalWindow.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2020-2021 Alex Spataru - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "ExternalWindow.h" - -#include -#include - -using namespace Widgets; - -ExternalWindow::ExternalWindow() - : m_widget(nullptr) -{ - setLayout(&m_layout); -} - -QWidget *ExternalWindow::widget() -{ - return m_widget; -} - -void ExternalWindow::setWidget(QWidget *widget) -{ - Q_ASSERT(widget); - - if (m_widget) - m_layout.removeWidget(m_widget); - - m_layout.addWidget(widget); -} - -void ExternalWindow::showEvent(QShowEvent *event) -{ - event->accept(); - emit visibleChanged(); -} - -void ExternalWindow::hideEvent(QHideEvent *event) -{ - event->accept(); - emit visibleChanged(); -} diff --git a/src/Widgets/Common/ExternalWindow.h b/src/Widgets/Common/ExternalWindow.h deleted file mode 100644 index a82bee7e..00000000 --- a/src/Widgets/Common/ExternalWindow.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2020-2021 Alex Spataru - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef WIDGETS_COMMON_EXTERNAL_WINDOW_H -#define WIDGETS_COMMON_EXTERNAL_WINDOW_H - -#include -#include - -namespace Widgets -{ -class ExternalWindow : public QDialog -{ - Q_OBJECT - -signals: - void visibleChanged(); - -public: - ExternalWindow(); - - QWidget *widget(); - void setWidget(QWidget *widget); - -protected: - void showEvent(QShowEvent *event); - void hideEvent(QHideEvent *event); - -private: - QWidget *m_widget; - QHBoxLayout m_layout; -}; -} - -#endif diff --git a/src/Widgets/WidgetLoader.cpp b/src/Widgets/WidgetLoader.cpp index 96b37cd7..5deed38a 100644 --- a/src/Widgets/WidgetLoader.cpp +++ b/src/Widgets/WidgetLoader.cpp @@ -46,6 +46,7 @@ WidgetLoader::WidgetLoader(QQuickItem *parent) , m_index(-1) , m_widget(nullptr) , m_widgetVisible(false) + , m_isExternalWindow(false) { // Set item flags setFlag(ItemHasContents, true); @@ -53,17 +54,6 @@ WidgetLoader::WidgetLoader(QQuickItem *parent) setFlag(ItemAcceptsInputMethod, true); setAcceptedMouseButtons(Qt::AllButtons); - // Configure main window - m_window.setMinimumWidth(640); - m_window.setMinimumHeight(480); - - // Set window palette - QPalette palette; - auto theme = Misc::ThemeManager::getInstance(); - palette.setColor(QPalette::Base, theme->datasetWindowBackground()); - palette.setColor(QPalette::Window, theme->datasetWindowBackground()); - m_window.setPalette(palette); - // Resize widget to fit QML item size connect(this, &QQuickPaintedItem::widthChanged, this, &WidgetLoader::updateWidgetSize); @@ -73,9 +63,6 @@ WidgetLoader::WidgetLoader(QQuickItem *parent) // Automatically update the widget's visibility connect(UI::Dashboard::getInstance(), &UI::Dashboard::widgetVisibilityChanged, this, &WidgetLoader::updateWidgetVisible); - - // Enable/disable the window widget automatically - connect(&m_window, SIGNAL(visibleChanged()), this, SLOT(updateWidgetWindow())); } /** @@ -198,6 +185,11 @@ QString WidgetLoader::widgetTitle() const return tr("Invalid"); } +bool WidgetLoader::isExternalWindow() const +{ + return m_isExternalWindow; +} + /** * Returns the type of the current widget (e.g. group, plot, bar, gauge, etc...) */ @@ -206,12 +198,10 @@ UI::Dashboard::WidgetType WidgetLoader::widgetType() const return UI::Dashboard::getInstance()->widgetType(widgetIndex()); } -/** - * Shows a window with the current widget - */ -void WidgetLoader::displayWindow() +void WidgetLoader::setVisible(const bool visible) { - m_window.showNormal(); + if (m_widget) + m_widget->setEnabled(visible); } /** @@ -231,20 +221,11 @@ void WidgetLoader::setWidgetIndex(const int index) m_widget = nullptr; } - // Delete central widget of window - if (m_window.widget()) - delete m_window.widget(); - - // Hide widget window - if (m_window.isVisible()) - m_window.hide(); - // Construct new widget switch (widgetType()) { case UI::Dashboard::WidgetType::Group: m_widget = new DataGroup(relativeIndex()); - m_window.setWidget(new DataGroup(relativeIndex())); break; case UI::Dashboard::WidgetType::MultiPlot: m_widget = new QPushButton("Multi-Plot"); @@ -254,26 +235,21 @@ void WidgetLoader::setWidgetIndex(const int index) break; case UI::Dashboard::WidgetType::Bar: m_widget = new Bar(relativeIndex()); - m_window.setWidget(new Bar(relativeIndex())); break; case UI::Dashboard::WidgetType::Gauge: m_widget = new Gauge(relativeIndex()); - m_window.setWidget(new Gauge(relativeIndex())); break; case UI::Dashboard::WidgetType::Thermometer: m_widget = new QPushButton("Thermometer"); break; case UI::Dashboard::WidgetType::Compass: m_widget = new Compass(relativeIndex()); - m_window.setWidget(new Compass(relativeIndex())); break; case UI::Dashboard::WidgetType::Gyroscope: m_widget = new Gyroscope(relativeIndex()); - m_window.setWidget(new Gyroscope(relativeIndex())); break; case UI::Dashboard::WidgetType::Accelerometer: m_widget = new Accelerometer(relativeIndex()); - m_window.setWidget(new Accelerometer(relativeIndex())); break; case UI::Dashboard::WidgetType::Map: m_widget = new QPushButton("Map"); @@ -282,11 +258,6 @@ void WidgetLoader::setWidgetIndex(const int index) break; } - // Update window title - m_window.setWindowTitle(widgetTitle()); - if (m_window.widget()) - m_window.widget()->setEnabled(false); - // Allow widget to receive events from the QML interface if (m_widget) { @@ -298,6 +269,12 @@ void WidgetLoader::setWidgetIndex(const int index) } } +void WidgetLoader::setIsExternalWindow(const bool isWindow) +{ + m_isExternalWindow = isWindow; + emit isExternalWindowChanged(); +} + /** * Resizes the widget to fit inside the QML item. */ @@ -310,16 +287,6 @@ void WidgetLoader::updateWidgetSize() } } -/** - * Enables/disables the widget updates of the external window when the window - * is shown or hidden. - */ -void WidgetLoader::updateWidgetWindow() -{ - if (m_window.widget()) - m_window.widget()->setEnabled(m_window.isVisible()); -} - /** * Updates the visibility status of the current widget (this function is called * automatically by the UI::Dashboard class via signals/slots). @@ -328,16 +295,13 @@ void WidgetLoader::updateWidgetVisible() { bool visible = UI::Dashboard::getInstance()->widgetVisible(widgetIndex()); - if (widgetVisible() != visible) + if (widgetVisible() != visible && !isExternalWindow()) { m_widgetVisible = visible; if (m_widget) m_widget->setEnabled(visible); - if (m_window.widget()) - m_window.widget()->setEnabled(visible); - emit widgetVisibleChanged(); } } diff --git a/src/Widgets/WidgetLoader.h b/src/Widgets/WidgetLoader.h index 74ca0b63..8fc02c61 100644 --- a/src/Widgets/WidgetLoader.h +++ b/src/Widgets/WidgetLoader.h @@ -30,8 +30,6 @@ #include -#include "Common/ExternalWindow.h" - namespace Widgets { class WidgetLoader : public QQuickPaintedItem @@ -55,11 +53,20 @@ class WidgetLoader : public QQuickPaintedItem Q_PROPERTY(bool widgetVisible READ widgetVisible NOTIFY widgetVisibleChanged) + Q_PROPERTY(bool isExternalWindow + READ isExternalWindow + WRITE setIsExternalWindow + NOTIFY isExternalWindowChanged) + Q_PROPERTY(bool widgetVisible + READ widgetVisible + WRITE setVisible + NOTIFY widgetVisibleChanged) // clang-format on signals: void widgetIndexChanged(); void widgetVisibleChanged(); + void isExternalWindowChanged(); public: WidgetLoader(QQuickItem *parent = 0); @@ -74,15 +81,16 @@ public: bool widgetVisible() const; QString widgetIcon() const; QString widgetTitle() const; + bool isExternalWindow() const; UI::Dashboard::WidgetType widgetType() const; public slots: - void displayWindow(); + void setVisible(const bool visible); void setWidgetIndex(const int index); + void setIsExternalWindow(const bool isWindow); private slots: void updateWidgetSize(); - void updateWidgetWindow(); void updateWidgetVisible(); protected: @@ -92,8 +100,8 @@ protected: private: int m_index; QWidget *m_widget; - ExternalWindow m_window; bool m_widgetVisible; + bool m_isExternalWindow; }; }