FGQCanvas: Multi-window support (for RPi4)
To support EGLFS on the RPi4 dual outputs, enable multiple windows within a single process.
This commit is contained in:
parent
331ef3232f
commit
6e465f9dbe
13 changed files with 341 additions and 94 deletions
86
utils/fgqcanvas/WindowData.cpp
Normal file
86
utils/fgqcanvas/WindowData.cpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
#include "WindowData.h"
|
||||
|
||||
#include <QScreen>
|
||||
#include <QGuiApplication>
|
||||
#include <QDebug>
|
||||
|
||||
#include "jsonutils.h"
|
||||
|
||||
WindowData::WindowData(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QJsonObject WindowData::saveState() const
|
||||
{
|
||||
QJsonObject json;
|
||||
json["rect"] = rectToJsonArray(m_windowRect);
|
||||
if (!m_screenName.isEmpty()) {
|
||||
json["screen"] = m_screenName;
|
||||
}
|
||||
if (!m_title.isEmpty()) {
|
||||
json["title"] = m_title;
|
||||
}
|
||||
// support frameless option here?
|
||||
json["state"] = static_cast<int>(m_state);
|
||||
return json;
|
||||
}
|
||||
|
||||
bool WindowData::restoreState(QJsonObject state)
|
||||
{
|
||||
m_windowRect = jsonArrayToRect(state.value("rect").toArray());
|
||||
emit windowRectChanged(m_windowRect);
|
||||
|
||||
if (state.contains("screen")) {
|
||||
m_screenName = state.value("screen").toString();
|
||||
} else {
|
||||
m_screenName.clear();
|
||||
}
|
||||
|
||||
if (state.contains("title")) {
|
||||
m_title = state.value("title").toString();
|
||||
}
|
||||
|
||||
if (state.contains("state")) {
|
||||
m_state = static_cast<Qt::WindowState>(state.value("state").toInt());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QRect WindowData::windowRect() const
|
||||
{
|
||||
return m_windowRect;
|
||||
}
|
||||
|
||||
QScreen *WindowData::screen() const
|
||||
{
|
||||
if (m_screenName.isEmpty())
|
||||
return nullptr;
|
||||
|
||||
QStringList screenNames;
|
||||
Q_FOREACH(auto s, qApp->screens()) {
|
||||
if (s->name() == m_screenName) {
|
||||
return s;
|
||||
}
|
||||
screenNames.append(s->name());
|
||||
}
|
||||
|
||||
qWarning() << "couldn't find a screen with name:" << m_screenName;
|
||||
qWarning() << "Available screens:" << screenNames.join(", ");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void WindowData::setWindowState(Qt::WindowState ws)
|
||||
{
|
||||
m_state = ws;
|
||||
}
|
||||
|
||||
void WindowData::setWindowRect(QRect windowRect)
|
||||
{
|
||||
if (m_windowRect == windowRect)
|
||||
return;
|
||||
|
||||
m_windowRect = windowRect;
|
||||
emit windowRectChanged(m_windowRect);
|
||||
}
|
46
utils/fgqcanvas/WindowData.h
Normal file
46
utils/fgqcanvas/WindowData.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
#ifndef WINDOWDATA_H
|
||||
#define WINDOWDATA_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QJsonObject>
|
||||
#include <QRect>
|
||||
|
||||
class QScreen;
|
||||
|
||||
class WindowData : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QRect windowRect READ windowRect WRITE setWindowRect NOTIFY windowRectChanged)
|
||||
public:
|
||||
explicit WindowData(QObject *parent = nullptr);
|
||||
|
||||
QJsonObject saveState() const;
|
||||
bool restoreState(QJsonObject state);
|
||||
|
||||
QRect windowRect() const;
|
||||
QScreen* screen() const;
|
||||
|
||||
Qt::WindowState windowState() const
|
||||
{ return m_state; }
|
||||
|
||||
void setWindowState(Qt::WindowState ws);
|
||||
|
||||
QString title() const
|
||||
{ return m_title; }
|
||||
signals:
|
||||
|
||||
void windowRectChanged(QRect windowRect);
|
||||
|
||||
public slots:
|
||||
|
||||
void setWindowRect(QRect windowRect);
|
||||
|
||||
private:
|
||||
QRect m_windowRect;
|
||||
Qt::WindowState m_state = Qt::WindowNoState;
|
||||
QString m_screenName;
|
||||
QString m_title;
|
||||
};
|
||||
|
||||
#endif // WINDOWDATA_H
|
|
@ -36,9 +36,12 @@
|
|||
#include <QTimer>
|
||||
#include <QGuiApplication>
|
||||
#include <QSettings>
|
||||
#include <QQuickView>
|
||||
#include <QQmlContext>
|
||||
|
||||
#include "jsonutils.h"
|
||||
#include "canvasconnection.h"
|
||||
#include "WindowData.h"
|
||||
|
||||
ApplicationController::ApplicationController(QObject *parent)
|
||||
: QObject(parent)
|
||||
|
@ -72,18 +75,6 @@ ApplicationController::~ApplicationController()
|
|||
delete m_netAccess;
|
||||
}
|
||||
|
||||
void ApplicationController::setWindow(QWindow *window)
|
||||
{
|
||||
m_window = window;
|
||||
}
|
||||
|
||||
void ApplicationController::restoreWindowState()
|
||||
{
|
||||
if (!m_window)
|
||||
return;
|
||||
m_window->setWindowState(m_windowState);
|
||||
}
|
||||
|
||||
void ApplicationController::loadFromFile(QString path)
|
||||
{
|
||||
if (!QFile::exists(path)) {
|
||||
|
@ -104,6 +95,42 @@ void ApplicationController::setDaemonMode()
|
|||
m_daemonMode = true;
|
||||
}
|
||||
|
||||
void ApplicationController::createWindows()
|
||||
{
|
||||
if (m_windowList.empty()) {
|
||||
defineDefaultWindow();
|
||||
}
|
||||
|
||||
for (int index = 0; index < m_windowList.size(); ++index) {
|
||||
auto wd = m_windowList.at(index);
|
||||
QQuickView* qqv = new QQuickView;
|
||||
qqv->rootContext()->setContextProperty("_application", this);
|
||||
qqv->rootContext()->setContextProperty("_windowNumber", index);
|
||||
qqv->setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
qqv->setSource(QUrl{"qrc:///qml/Window.qml"});
|
||||
qqv->setTitle(wd->title());
|
||||
|
||||
if (m_daemonMode) {
|
||||
qqv->setScreen(wd->screen());
|
||||
qqv->setGeometry(wd->windowRect());
|
||||
qqv->setWindowState(wd->windowState());
|
||||
} else {
|
||||
// interactive mode, restore window size etc
|
||||
|
||||
}
|
||||
|
||||
qqv->show();
|
||||
}
|
||||
}
|
||||
|
||||
void ApplicationController::defineDefaultWindow()
|
||||
{
|
||||
auto w = new WindowData(this);
|
||||
w->setWindowRect(QRect{0, 0, 1024, 768});
|
||||
m_windowList.append(w);
|
||||
emit windowListChanged();
|
||||
}
|
||||
|
||||
void ApplicationController::save(QString configName)
|
||||
{
|
||||
QDir d(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
||||
|
@ -364,6 +391,11 @@ QQmlListProperty<CanvasConnection> ApplicationController::activeCanvases()
|
|||
return QQmlListProperty<CanvasConnection>(this, m_activeCanvases);
|
||||
}
|
||||
|
||||
QQmlListProperty<WindowData> ApplicationController::windowList()
|
||||
{
|
||||
return QQmlListProperty<WindowData>(this, m_windowList);
|
||||
}
|
||||
|
||||
QNetworkAccessManager *ApplicationController::netAccess() const
|
||||
{
|
||||
return m_netAccess;
|
||||
|
@ -371,6 +403,9 @@ QNetworkAccessManager *ApplicationController::netAccess() const
|
|||
|
||||
bool ApplicationController::showUI() const
|
||||
{
|
||||
if (m_daemonMode)
|
||||
return false;
|
||||
|
||||
if (m_blockUIIdle)
|
||||
return true;
|
||||
|
||||
|
@ -490,10 +525,12 @@ QByteArray ApplicationController::saveState(QString name) const
|
|||
}
|
||||
|
||||
json["canvases"] = canvases;
|
||||
if (m_window) {
|
||||
json["window-rect"] = rectToJsonArray(m_window->geometry());
|
||||
json["window-state"] = static_cast<int>(m_window->windowState());
|
||||
|
||||
QJsonArray windows;
|
||||
Q_FOREACH (auto w, m_windowList) {
|
||||
windows.append(w->saveState());
|
||||
}
|
||||
json["windows"] = windows;
|
||||
|
||||
// background color?
|
||||
|
||||
|
@ -509,18 +546,29 @@ void ApplicationController::restoreState(QByteArray bytes)
|
|||
QJsonDocument jsonDoc = QJsonDocument::fromJson(bytes);
|
||||
QJsonObject json = jsonDoc.object();
|
||||
|
||||
if (m_window) {
|
||||
QRect r = jsonArrayToRect(json.value("window-rect").toArray());
|
||||
if (r.isValid()) {
|
||||
m_window->setGeometry(r);
|
||||
// clear windows
|
||||
Q_FOREACH(auto w, m_windowList) {
|
||||
w->deleteLater();
|
||||
}
|
||||
m_windowList.clear();
|
||||
|
||||
for (auto w : json.value("windows").toArray()) {
|
||||
auto wd = new WindowData(this);
|
||||
m_windowList.append(wd);
|
||||
wd->restoreState(w.toObject());
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (m_windowList.isEmpty()) {
|
||||
// check for previous single-window data
|
||||
auto w = new WindowData(this);
|
||||
if (json.contains("window-rect")) {
|
||||
w->setWindowRect(jsonArrayToRect(json.value("window-rect").toArray()));
|
||||
}
|
||||
if (json.contains("window-state")) {
|
||||
w->setWindowState(static_cast<Qt::WindowState>(json.value("window-state").toInt()));
|
||||
}
|
||||
m_windowList.append(w);
|
||||
}
|
||||
// background color
|
||||
|
||||
for (auto c : json.value("canvases").toArray()) {
|
||||
auto cc = new CanvasConnection(this);
|
||||
|
@ -533,6 +581,7 @@ void ApplicationController::restoreState(QByteArray bytes)
|
|||
cc->reconnect();
|
||||
}
|
||||
|
||||
emit windowListChanged();
|
||||
emit activeCanvasesChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
class CanvasConnection;
|
||||
class QWindow;
|
||||
class QTimer;
|
||||
class WindowData;
|
||||
|
||||
class ApplicationController : public QObject
|
||||
{
|
||||
|
@ -42,6 +43,7 @@ class ApplicationController : public QObject
|
|||
|
||||
|
||||
Q_PROPERTY(QQmlListProperty<CanvasConnection> activeCanvases READ activeCanvases NOTIFY activeCanvasesChanged)
|
||||
Q_PROPERTY(QQmlListProperty<WindowData> windowList READ windowList NOTIFY windowListChanged)
|
||||
|
||||
Q_ENUMS(Status)
|
||||
|
||||
|
@ -54,15 +56,12 @@ class ApplicationController : public QObject
|
|||
Q_PROPERTY(bool showGettingStarted READ showGettingStarted WRITE setShowGettingStarted NOTIFY showGettingStartedChanged)
|
||||
public:
|
||||
explicit ApplicationController(QObject *parent = nullptr);
|
||||
~ApplicationController();
|
||||
|
||||
void setWindow(QWindow* window);
|
||||
|
||||
void restoreWindowState();
|
||||
~ApplicationController() override;
|
||||
|
||||
void loadFromFile(QString path);
|
||||
|
||||
void setDaemonMode();
|
||||
void createWindows();
|
||||
|
||||
Q_INVOKABLE void query();
|
||||
Q_INVOKABLE void cancelQuery();
|
||||
|
@ -86,6 +85,7 @@ public:
|
|||
QVariantList canvases() const;
|
||||
|
||||
QQmlListProperty<CanvasConnection> activeCanvases();
|
||||
QQmlListProperty<WindowData> windowList();
|
||||
|
||||
QNetworkAccessManager* netAccess() const;
|
||||
|
||||
|
@ -129,6 +129,7 @@ signals:
|
|||
void portChanged(unsigned int port);
|
||||
|
||||
void activeCanvasesChanged();
|
||||
void windowListChanged();
|
||||
|
||||
void canvasListChanged();
|
||||
void statusChanged(Status status);
|
||||
|
@ -179,6 +180,8 @@ private:
|
|||
|
||||
QByteArray createSnapshot(QString name) const;
|
||||
|
||||
void defineDefaultWindow();
|
||||
|
||||
QString m_host;
|
||||
unsigned int m_port;
|
||||
QVariantList m_canvases;
|
||||
|
@ -189,8 +192,7 @@ private:
|
|||
QNetworkReply* m_query = nullptr;
|
||||
QVariantList m_snapshots;
|
||||
|
||||
QWindow* m_window = nullptr;
|
||||
Qt::WindowState m_windowState = Qt::WindowNoState;
|
||||
QList<WindowData*> m_windowList;
|
||||
|
||||
bool m_daemonMode = false;
|
||||
bool m_showUI = true;
|
||||
|
|
|
@ -77,6 +77,7 @@ QJsonObject CanvasConnection::saveState() const
|
|||
json["url"] = m_webSocketUrl.toString();
|
||||
json["path"] = QString::fromUtf8(m_rootPropertyPath);
|
||||
json["rect"] = rectToJsonArray(m_destRect.toRect());
|
||||
json["window"] = m_windowIndex;
|
||||
return json;
|
||||
}
|
||||
|
||||
|
@ -86,6 +87,10 @@ bool CanvasConnection::restoreState(QJsonObject state)
|
|||
m_rootPropertyPath = state.value("path").toString().toUtf8();
|
||||
m_destRect = jsonArrayToRect(state.value("rect").toArray());
|
||||
|
||||
if (state.contains("window")) {
|
||||
m_windowIndex = state.value("window").toInt();
|
||||
}
|
||||
|
||||
emit geometryChanged();
|
||||
emit rootPathChanged();
|
||||
emit webSocketUrlChanged();
|
||||
|
@ -167,6 +172,14 @@ QSizeF CanvasConnection::size() const
|
|||
return m_destRect.size();
|
||||
}
|
||||
|
||||
void CanvasConnection::setWindowIndex(int index)
|
||||
{
|
||||
if (m_windowIndex != index) {
|
||||
m_windowIndex = index;
|
||||
emit geometryChanged();
|
||||
}
|
||||
}
|
||||
|
||||
LocalProp *CanvasConnection::propertyRoot() const
|
||||
{
|
||||
return m_localPropertyRoot.get();
|
||||
|
|
|
@ -46,6 +46,8 @@ class CanvasConnection : public QObject
|
|||
Q_PROPERTY(QPointF origin READ origin WRITE setOrigin NOTIFY geometryChanged)
|
||||
Q_PROPERTY(QSizeF size READ size WRITE setSize NOTIFY geometryChanged)
|
||||
|
||||
Q_PROPERTY(int windowIndex READ windowIndex WRITE setWindowIndex NOTIFY geometryChanged)
|
||||
|
||||
Q_PROPERTY(QUrl webSocketUrl READ webSocketUrl NOTIFY webSocketUrlChanged)
|
||||
Q_PROPERTY(QString rootPath READ rootPath NOTIFY rootPathChanged)
|
||||
public:
|
||||
|
@ -84,6 +86,13 @@ public:
|
|||
|
||||
QSizeF size() const;
|
||||
|
||||
int windowIndex() const
|
||||
{
|
||||
return m_windowIndex;
|
||||
}
|
||||
|
||||
void setWindowIndex(int index);
|
||||
|
||||
LocalProp* propertyRoot() const;
|
||||
|
||||
QUrl webSocketUrl() const
|
||||
|
@ -132,6 +141,7 @@ private:
|
|||
QUrl m_webSocketUrl;
|
||||
QByteArray m_rootPropertyPath;
|
||||
QRectF m_destRect;
|
||||
int m_windowIndex = 0;
|
||||
|
||||
QWebSocket m_webSocket;
|
||||
QNetworkAccessManager* m_netAccess = nullptr;
|
||||
|
|
|
@ -108,7 +108,6 @@ void CanvasPaintedDisplay::onConnectionStatusChanged()
|
|||
|
||||
void CanvasPaintedDisplay::buildElements()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
m_rootElement = new FGCanvasGroup(nullptr, m_connection->propertyRoot());
|
||||
// this is important to elements can discover their connection
|
||||
// by walking their parent chain
|
||||
|
|
32
utils/fgqcanvas/configs/example_config.json
Normal file
32
utils/fgqcanvas/configs/example_config.json
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"canvases": [
|
||||
{
|
||||
"path": "/canvas/by-index/texture[4]",
|
||||
"rect": [
|
||||
300,
|
||||
253,
|
||||
852,
|
||||
745
|
||||
],
|
||||
"url": "ws://localhost:8080/PropertyTreeMirror/canvas/by-index/texture[4]"
|
||||
},
|
||||
{
|
||||
"path": "/canvas/by-index/texture[7]",
|
||||
"rect": [
|
||||
1171,
|
||||
259,
|
||||
747,
|
||||
711
|
||||
],
|
||||
"url": "ws://localhost:8080/PropertyTreeMirror/canvas/by-index/texture[7]"
|
||||
}
|
||||
],
|
||||
"configName": "738_captain",
|
||||
"window-rect": [
|
||||
1001,
|
||||
2188,
|
||||
1920,
|
||||
1052
|
||||
],
|
||||
"window-state": 2
|
||||
}
|
38
utils/fgqcanvas/configs/multi_window_config.json
Normal file
38
utils/fgqcanvas/configs/multi_window_config.json
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"canvases": [
|
||||
{
|
||||
"path": "/canvas/by-index/texture[4]",
|
||||
"rect": [
|
||||
300,
|
||||
253,
|
||||
852,
|
||||
745
|
||||
],
|
||||
"url": "ws://localhost:8080/PropertyTreeMirror/canvas/by-index/texture[4]"
|
||||
},
|
||||
{
|
||||
"path": "/canvas/by-index/texture[7]",
|
||||
"rect": [
|
||||
1171,
|
||||
259,
|
||||
747,
|
||||
711
|
||||
],
|
||||
"window":1,
|
||||
"url": "ws://localhost:8080/PropertyTreeMirror/canvas/by-index/texture[7]"
|
||||
}
|
||||
],
|
||||
"configName": "738_captain",
|
||||
"windows": [
|
||||
{
|
||||
"title": "First Window",
|
||||
"rect":[100, 100, 500, 300]
|
||||
},
|
||||
|
||||
{
|
||||
"title": "Another Window",
|
||||
"rect":[150, 400, 500, 300],
|
||||
"screen":"Colour LCD"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -6,6 +6,7 @@ TARGET = fgqcanvas
|
|||
TEMPLATE = app
|
||||
|
||||
SOURCES += main.cpp\
|
||||
WindowData.cpp \
|
||||
fgcanvasgroup.cpp \
|
||||
fgcanvaselement.cpp \
|
||||
fgcanvaspaintcontext.cpp \
|
||||
|
@ -25,6 +26,7 @@ SOURCES += main.cpp\
|
|||
|
||||
|
||||
HEADERS += \
|
||||
WindowData.h \
|
||||
fgcanvasgroup.h \
|
||||
fgcanvaselement.h \
|
||||
fgcanvaspaintcontext.h \
|
||||
|
@ -48,7 +50,8 @@ RESOURCES += \
|
|||
|
||||
OTHER_FILES += \
|
||||
qml/* \
|
||||
doc/*
|
||||
doc/* \
|
||||
config/*
|
||||
|
||||
#Q_XCODE_DEVELOPMENT_TEAM.name = DEVELOPMENT_TEAM
|
||||
#Q_XCODE_DEVELOPMENT_TEAM.value = "James Turner"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>qml/mainMenu.qml</file>
|
||||
<file>qml/Window.qml</file>
|
||||
<file>qml/Button.qml</file>
|
||||
<file>qml/InputLine.qml</file>
|
||||
<file alias="images/checkerboard">qml/checkerboard.png</file>
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "canvasdisplay.h"
|
||||
#include "canvasconnection.h"
|
||||
#include "canvaspainteddisplay.h"
|
||||
#include "WindowData.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -38,12 +39,6 @@ int main(int argc, char *argv[])
|
|||
|
||||
QCommandLineParser parser;
|
||||
parser.addPositionalArgument("config", QCoreApplication::translate("main", "JSON configuration to load"));
|
||||
QCommandLineOption framelessOption(QStringList() << "frameless",
|
||||
QCoreApplication::translate("main", "Use a frameless window"));
|
||||
QCommandLineOption screenOption(QStringList() << "screen",
|
||||
QCoreApplication::translate("main", "Run full-screen on <scren>"), "screen");
|
||||
parser.addOption(framelessOption);
|
||||
parser.addOption(screenOption);
|
||||
parser.process(a);
|
||||
|
||||
ApplicationController appController;
|
||||
|
@ -52,48 +47,10 @@ int main(int argc, char *argv[])
|
|||
qmlRegisterType<CanvasDisplay>("FlightGear", 1, 0, "CanvasDisplay");
|
||||
qmlRegisterType<CanvasPaintedDisplay>("FlightGear", 1, 0, "PaintedCanvasDisplay");
|
||||
|
||||
qmlRegisterUncreatableType<WindowData>("FlightGear", 1, 0, "WindowData", "Don't create me");
|
||||
qmlRegisterUncreatableType<CanvasConnection>("FlightGear", 1, 0, "CanvasConnection", "Don't create me");
|
||||
qmlRegisterUncreatableType<ApplicationController>("FlightGear", 1, 0, "Application", "Can't create");
|
||||
|
||||
QQuickView quickView;
|
||||
appController.setWindow(&quickView);
|
||||
if (parser.isSet(framelessOption)) {
|
||||
quickView.setFlag(Qt::FramelessWindowHint, true);
|
||||
}
|
||||
|
||||
bool restoreWindowState = true;
|
||||
if (parser.isSet(screenOption)) {
|
||||
QString screenName = parser.value(screenOption);
|
||||
QStringList allScreenNames;
|
||||
|
||||
QScreen* found = nullptr;
|
||||
Q_FOREACH(QScreen* s, a.screens()) {
|
||||
allScreenNames << s->name();
|
||||
if (s->name() == screenName) {
|
||||
found = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
qFatal("Unable to find screen: %s: screens are: %s", screenName.toLatin1().data(),
|
||||
allScreenNames.join(",").toLatin1().data());
|
||||
}
|
||||
|
||||
quickView.setScreen(found);
|
||||
quickView.setGeometry(found->geometry());
|
||||
quickView.setFlag(Qt::FramelessWindowHint, true);
|
||||
restoreWindowState = false;
|
||||
|
||||
qInfo() << "Requested to run on screen:" << screenName << "with geometry" << found->geometry();
|
||||
} else {
|
||||
// windows mode, default geeometry
|
||||
quickView.setWidth(1024);
|
||||
quickView.setHeight(768);
|
||||
}
|
||||
|
||||
quickView.rootContext()->setContextProperty("_application", &appController);
|
||||
|
||||
const QStringList args = parser.positionalArguments();
|
||||
|
||||
if (!args.empty()) {
|
||||
|
@ -101,15 +58,8 @@ int main(int argc, char *argv[])
|
|||
appController.loadFromFile(args.front());
|
||||
}
|
||||
|
||||
quickView.setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
quickView.setSource(QUrl("qrc:///qml/mainMenu.qml"));
|
||||
quickView.show();
|
||||
|
||||
if (restoreWindowState) {
|
||||
appController.restoreWindowState();
|
||||
}
|
||||
appController.createWindows();
|
||||
|
||||
int result = a.exec();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import QtQuick 2.0
|
||||
import FlightGear 1.0 as FG
|
||||
import QtQuick.Window 2.4 as QQ2W
|
||||
|
||||
Rectangle {
|
||||
width: 1024
|
||||
height: 768
|
||||
color: "black"
|
||||
|
||||
property double __uiOpacity: _application.showUI ? 1.0 : 0.0
|
||||
// only show the UI on the main window
|
||||
property double __uiOpacity: (isMainWindow && _application.showUI) ? 1.0 : 0.0
|
||||
property bool __uiVisible: true
|
||||
readonly property bool isMainWindow: (_windowNumber === 0)
|
||||
|
||||
Behavior on __uiOpacity {
|
||||
SequentialAnimation {
|
||||
|
@ -27,9 +29,25 @@ Rectangle {
|
|||
|
||||
Repeater {
|
||||
model: _application.activeCanvases
|
||||
delegate: CanvasFrame {
|
||||
id: display
|
||||
canvas: modelData
|
||||
|
||||
// we use a loader to only create canvases on the correct window
|
||||
// by driving the 'active' property
|
||||
delegate: Loader {
|
||||
id: canvasLoader
|
||||
sourceComponent: canvasFrame
|
||||
active: modelData.windowIndex === _windowNumber
|
||||
|
||||
Binding {
|
||||
target: canvasLoader.item
|
||||
property: "canvas"
|
||||
value: model.modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: canvasFrame
|
||||
CanvasFrame {
|
||||
showUi: __uiVisible
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +76,7 @@ Rectangle {
|
|||
}
|
||||
|
||||
GetStarted {
|
||||
visible: isMainWindow
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
Loading…
Reference in a new issue