FGCanvas tweaks
Enable daemon mode for hands-off operation. Add auto-reconnect feature for daemon mode, will keep trying to connect to the configured FGFS instance.
This commit is contained in:
parent
2f12c0b0bd
commit
2403e95559
10 changed files with 80 additions and 15 deletions
|
@ -64,6 +64,13 @@ void ApplicationController::setWindow(QWindow *window)
|
||||||
m_window = window;
|
m_window = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApplicationController::restoreWindowState()
|
||||||
|
{
|
||||||
|
if (!m_window)
|
||||||
|
return;
|
||||||
|
m_window->setWindowState(m_windowState);
|
||||||
|
}
|
||||||
|
|
||||||
void ApplicationController::loadFromFile(QString path)
|
void ApplicationController::loadFromFile(QString path)
|
||||||
{
|
{
|
||||||
if (!QFile::exists(path)) {
|
if (!QFile::exists(path)) {
|
||||||
|
@ -79,6 +86,11 @@ void ApplicationController::loadFromFile(QString path)
|
||||||
restoreState(f.readAll());
|
restoreState(f.readAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApplicationController::setDaemonMode()
|
||||||
|
{
|
||||||
|
m_daemonMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
void ApplicationController::save(QString configName)
|
void ApplicationController::save(QString configName)
|
||||||
{
|
{
|
||||||
QDir d(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
QDir d(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
||||||
|
@ -440,12 +452,18 @@ void ApplicationController::restoreState(QByteArray bytes)
|
||||||
m_window->setGeometry(r);
|
m_window->setGeometry(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_window->setWindowState(static_cast<Qt::WindowState>(json.value("window-state").toInt()));
|
// we have to cache the state becuase it seems to be ignored
|
||||||
|
// before show is called();
|
||||||
|
m_windowState = static_cast<Qt::WindowState>(json.value("window-state").toInt());
|
||||||
|
m_window->setWindowState(m_windowState);
|
||||||
}
|
}
|
||||||
// background color
|
// background color
|
||||||
|
|
||||||
for (auto c : json.value("canvases").toArray()) {
|
for (auto c : json.value("canvases").toArray()) {
|
||||||
auto cc = new CanvasConnection(this);
|
auto cc = new CanvasConnection(this);
|
||||||
|
if (m_daemonMode)
|
||||||
|
cc->setAutoReconnect();
|
||||||
|
|
||||||
cc->setNetworkAccess(m_netAccess);
|
cc->setNetworkAccess(m_netAccess);
|
||||||
m_activeCanvases.append(cc);
|
m_activeCanvases.append(cc);
|
||||||
cc->restoreState(c.toObject());
|
cc->restoreState(c.toObject());
|
||||||
|
|
|
@ -52,8 +52,12 @@ public:
|
||||||
|
|
||||||
void setWindow(QWindow* window);
|
void setWindow(QWindow* window);
|
||||||
|
|
||||||
|
void restoreWindowState();
|
||||||
|
|
||||||
void loadFromFile(QString path);
|
void loadFromFile(QString path);
|
||||||
|
|
||||||
|
void setDaemonMode();
|
||||||
|
|
||||||
Q_INVOKABLE void query();
|
Q_INVOKABLE void query();
|
||||||
Q_INVOKABLE void cancelQuery();
|
Q_INVOKABLE void cancelQuery();
|
||||||
Q_INVOKABLE void clearQuery();
|
Q_INVOKABLE void clearQuery();
|
||||||
|
@ -146,7 +150,11 @@ private:
|
||||||
QVariantList m_configs;
|
QVariantList m_configs;
|
||||||
QNetworkReply* m_query = nullptr;
|
QNetworkReply* m_query = nullptr;
|
||||||
QVariantList m_snapshots;
|
QVariantList m_snapshots;
|
||||||
|
|
||||||
QWindow* m_window = nullptr;
|
QWindow* m_window = nullptr;
|
||||||
|
Qt::WindowState m_windowState = Qt::WindowNoState;
|
||||||
|
|
||||||
|
bool m_daemonMode = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // APPLICATIONCONTROLLER_H
|
#endif // APPLICATIONCONTROLLER_H
|
||||||
|
|
|
@ -41,6 +41,11 @@ CanvasConnection::CanvasConnection(QObject *parent) : QObject(parent)
|
||||||
this, &CanvasConnection::onTextMessageReceived);
|
this, &CanvasConnection::onTextMessageReceived);
|
||||||
|
|
||||||
m_destRect = QRectF(50, 50, 400, 400);
|
m_destRect = QRectF(50, 50, 400, 400);
|
||||||
|
m_reconnectTimer = new QTimer(this);
|
||||||
|
m_reconnectTimer->setInterval(1000 * 10);
|
||||||
|
m_reconnectTimer->setSingleShot(true);
|
||||||
|
connect(m_reconnectTimer, &QTimer::timeout,
|
||||||
|
this, &CanvasConnection::reconnect);
|
||||||
}
|
}
|
||||||
|
|
||||||
CanvasConnection::~CanvasConnection()
|
CanvasConnection::~CanvasConnection()
|
||||||
|
@ -61,6 +66,11 @@ void CanvasConnection::setRootPropertyPath(QByteArray path)
|
||||||
emit rootPathChanged();
|
emit rootPathChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanvasConnection::setAutoReconnect()
|
||||||
|
{
|
||||||
|
m_autoReconnect = true;
|
||||||
|
}
|
||||||
|
|
||||||
QJsonObject CanvasConnection::saveState() const
|
QJsonObject CanvasConnection::saveState() const
|
||||||
{
|
{
|
||||||
QJsonObject json;
|
QJsonObject json;
|
||||||
|
@ -104,6 +114,7 @@ void CanvasConnection::restoreSnapshot(QDataStream &ds)
|
||||||
|
|
||||||
void CanvasConnection::reconnect()
|
void CanvasConnection::reconnect()
|
||||||
{
|
{
|
||||||
|
qDebug() << "starting connection attempt to:" << m_webSocketUrl;
|
||||||
m_webSocket.open(m_webSocketUrl);
|
m_webSocket.open(m_webSocketUrl);
|
||||||
setStatus(Connecting);
|
setStatus(Connecting);
|
||||||
}
|
}
|
||||||
|
@ -185,6 +196,7 @@ FGQCanvasFontCache *CanvasConnection::fontCache() const
|
||||||
|
|
||||||
void CanvasConnection::onWebSocketConnected()
|
void CanvasConnection::onWebSocketConnected()
|
||||||
{
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << m_webSocketUrl;
|
||||||
m_localPropertyRoot.reset(new LocalProp{nullptr, NameIndexTuple("")});
|
m_localPropertyRoot.reset(new LocalProp{nullptr, NameIndexTuple("")});
|
||||||
setStatus(Connected);
|
setStatus(Connected);
|
||||||
}
|
}
|
||||||
|
@ -272,10 +284,9 @@ void CanvasConnection::onWebSocketClosed()
|
||||||
|
|
||||||
setStatus(Closed);
|
setStatus(Closed);
|
||||||
|
|
||||||
// if we're in automatic mode, start reconnection timer
|
if (m_autoReconnect) {
|
||||||
// update state
|
m_reconnectTimer->start();
|
||||||
|
}
|
||||||
// ui->stack->setCurrentIndex(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasConnection::setStatus(CanvasConnection::Status newStatus)
|
void CanvasConnection::setStatus(CanvasConnection::Status newStatus)
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QRectF>
|
#include <QRectF>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
class LocalProp;
|
class LocalProp;
|
||||||
class QNetworkAccessManager;
|
class QNetworkAccessManager;
|
||||||
|
@ -54,6 +55,8 @@ public:
|
||||||
void setNetworkAccess(QNetworkAccessManager *dl);
|
void setNetworkAccess(QNetworkAccessManager *dl);
|
||||||
void setRootPropertyPath(QByteArray path);
|
void setRootPropertyPath(QByteArray path);
|
||||||
|
|
||||||
|
void setAutoReconnect();
|
||||||
|
|
||||||
enum Status
|
enum Status
|
||||||
{
|
{
|
||||||
NotConnected,
|
NotConnected,
|
||||||
|
@ -132,6 +135,9 @@ private:
|
||||||
|
|
||||||
QWebSocket m_webSocket;
|
QWebSocket m_webSocket;
|
||||||
QNetworkAccessManager* m_netAccess = nullptr;
|
QNetworkAccessManager* m_netAccess = nullptr;
|
||||||
|
QTimer* m_reconnectTimer = nullptr;
|
||||||
|
bool m_autoReconnect = false;
|
||||||
|
|
||||||
std::unique_ptr<LocalProp> m_localPropertyRoot;
|
std::unique_ptr<LocalProp> m_localPropertyRoot;
|
||||||
QHash<int, QPointer<LocalProp>> idPropertyDict;
|
QHash<int, QPointer<LocalProp>> idPropertyDict;
|
||||||
Status m_status = NotConnected;
|
Status m_status = NotConnected;
|
||||||
|
|
|
@ -33,7 +33,6 @@ CanvasPaintedDisplay::CanvasPaintedDisplay(QQuickItem* parent) :
|
||||||
|
|
||||||
CanvasPaintedDisplay::~CanvasPaintedDisplay()
|
CanvasPaintedDisplay::~CanvasPaintedDisplay()
|
||||||
{
|
{
|
||||||
qDebug() << "did destory canvas painted";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasPaintedDisplay::paint(QPainter *painter)
|
void CanvasPaintedDisplay::paint(QPainter *painter)
|
||||||
|
@ -64,7 +63,7 @@ void CanvasPaintedDisplay::setCanvas(CanvasConnection *canvas)
|
||||||
|
|
||||||
if (m_connection) {
|
if (m_connection) {
|
||||||
disconnect(m_connection, nullptr, this, nullptr);
|
disconnect(m_connection, nullptr, this, nullptr);
|
||||||
m_rootElement.reset();
|
delete m_rootElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_connection = canvas;
|
m_connection = canvas;
|
||||||
|
@ -84,29 +83,35 @@ void CanvasPaintedDisplay::setCanvas(CanvasConnection *canvas)
|
||||||
|
|
||||||
void CanvasPaintedDisplay::onConnectionDestroyed()
|
void CanvasPaintedDisplay::onConnectionDestroyed()
|
||||||
{
|
{
|
||||||
|
qDebug() << "saw connection destroyed";
|
||||||
m_connection = nullptr;
|
m_connection = nullptr;
|
||||||
emit canvasChanged(m_connection);
|
delete m_rootElement;
|
||||||
|
|
||||||
m_rootElement.reset();
|
emit canvasChanged(m_connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasPaintedDisplay::onConnectionStatusChanged()
|
void CanvasPaintedDisplay::onConnectionStatusChanged()
|
||||||
{
|
{
|
||||||
if ((m_connection->status() == CanvasConnection::Connected) ||
|
if ((m_connection->status() == CanvasConnection::Connected) ||
|
||||||
(m_connection->status() == CanvasConnection::Snapshot))
|
(m_connection->status() == CanvasConnection::Snapshot))
|
||||||
{
|
{
|
||||||
buildElements();
|
buildElements();
|
||||||
|
} else {
|
||||||
|
qDebug() << Q_FUNC_INFO << "clearing root element";
|
||||||
|
delete m_rootElement;
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasPaintedDisplay::buildElements()
|
void CanvasPaintedDisplay::buildElements()
|
||||||
{
|
{
|
||||||
m_rootElement.reset(new FGCanvasGroup(nullptr, m_connection->propertyRoot()));
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
m_rootElement = new FGCanvasGroup(nullptr, m_connection->propertyRoot());
|
||||||
// this is important to elements can discover their connection
|
// this is important to elements can discover their connection
|
||||||
// by walking their parent chain
|
// by walking their parent chain
|
||||||
m_rootElement->setParent(m_connection);
|
m_rootElement->setParent(m_connection);
|
||||||
|
|
||||||
connect(m_rootElement.get(), &FGCanvasGroup::canvasSizeChanged,
|
connect(m_rootElement, &FGCanvasGroup::canvasSizeChanged,
|
||||||
this, &CanvasPaintedDisplay::onCanvasSizeChanged);
|
this, &CanvasPaintedDisplay::onCanvasSizeChanged);
|
||||||
|
|
||||||
onCanvasSizeChanged();
|
onCanvasSizeChanged();
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <QQuickPaintedItem>
|
#include <QQuickPaintedItem>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
class CanvasConnection;
|
class CanvasConnection;
|
||||||
class FGCanvasGroup;
|
class FGCanvasGroup;
|
||||||
|
@ -67,7 +68,7 @@ private:
|
||||||
void buildElements();
|
void buildElements();
|
||||||
|
|
||||||
CanvasConnection* m_connection = nullptr;
|
CanvasConnection* m_connection = nullptr;
|
||||||
std::unique_ptr<FGCanvasGroup> m_rootElement;
|
QPointer<FGCanvasGroup> m_rootElement;
|
||||||
// QQuickItem* m_rootItem = nullptr;
|
// QQuickItem* m_rootItem = nullptr;
|
||||||
QSizeF m_sourceSize;
|
QSizeF m_sourceSize;
|
||||||
};
|
};
|
||||||
|
|
|
@ -102,7 +102,9 @@ FGCanvasElement::FGCanvasElement(FGCanvasGroup* pr, LocalProp* prop) :
|
||||||
void FGCanvasElement::onPropDestroyed()
|
void FGCanvasElement::onPropDestroyed()
|
||||||
{
|
{
|
||||||
doDestroy();
|
doDestroy();
|
||||||
const_cast<FGCanvasGroup*>(_parent)->removeChild(this);
|
if (_parent) {
|
||||||
|
const_cast<FGCanvasGroup*>(_parent)->removeChild(this);
|
||||||
|
}
|
||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -253,7 +253,6 @@ void FGCanvasText::markStyleDirty()
|
||||||
|
|
||||||
void FGCanvasText::doDestroy()
|
void FGCanvasText::doDestroy()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
delete _quickItem;
|
delete _quickItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ int main(int argc, char *argv[])
|
||||||
quickView.rootContext()->setContextProperty("_application", &appController);
|
quickView.rootContext()->setContextProperty("_application", &appController);
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
appController.setDaemonMode();
|
||||||
appController.loadFromFile(QString::fromLocal8Bit(argv[1]));
|
appController.loadFromFile(QString::fromLocal8Bit(argv[1]));
|
||||||
} else {
|
} else {
|
||||||
quickView.setWidth(1024);
|
quickView.setWidth(1024);
|
||||||
|
@ -59,6 +60,8 @@ int main(int argc, char *argv[])
|
||||||
quickView.setResizeMode(QQuickView::SizeRootObjectToView);
|
quickView.setResizeMode(QQuickView::SizeRootObjectToView);
|
||||||
quickView.show();
|
quickView.show();
|
||||||
|
|
||||||
|
appController.restoreWindowState();
|
||||||
|
|
||||||
int result = a.exec();
|
int result = a.exec();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -31,6 +31,16 @@ Rectangle {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
uiVisible = !uiVisible;
|
uiVisible = !uiVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hoverEnabled: uiVisible
|
||||||
|
onMouseXChanged: idleTimer.restart()
|
||||||
|
onMouseYChanged: idleTimer.restart()
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: idleTimer
|
||||||
|
interval: 1000 * 10
|
||||||
|
onTriggered: { uiVisible = false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
@ -65,4 +75,6 @@ Rectangle {
|
||||||
SnapshotsPanel { }
|
SnapshotsPanel { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue