/// PersefoneDesktop - a GUI to the Persefone model of agriculture and ecosystems /// /// This file defines the layout of the main window. /// import org.julialang import QtQuick import QtQuick.Controls import QtQuick.Dialogs import QtQuick.Layouts ApplicationWindow { id: mainWindow title: "Persefone.jl Desktop" width: 1024 height: 768 visibility: "Maximized" visible: true menuBar: MenuBar { Menu { title: "&Simulation" Action { text: "&New Simulation" onTriggered: { vars.launching = true } //TODO select config file } /* Action { */ /* text: "&Configure Simulation" */ /* onTriggered: { Julia.configwindow() } */ /* } */ Action { text: "&Load Saved State" onTriggered: { loadFileChooser.open() } } Action { text: "&Save Current State" onTriggered: { saveFileChooser.open() } } MenuSeparator { } Action { text: "&Quit" onTriggered: { mainWindow.close() } } } Menu { title: "&Data" Action { text: "Show &Population Graph" onTriggered: { populationGraph.visible = true } } Action { text: "Save &Simulation Output" onTriggered: { Julia.saveoutput() } } } Menu { title: "&Help" Action { text: "&Documentation" onTriggered: { Qt.openUrlExternally("https://persefone-model.eu/documentation") } } Action { text: "&Website" onTriggered: { Qt.openUrlExternally("https://persefone-model.eu/") } } Action { text: "&About" onTriggered: { aboutDialog.open() } } } } // visualise the model map and the locations of animals MakieViewport { id: mapviewport anchors.fill: parent renderFunction: render_map_callback } // the main control bar, with pause/step/run buttons, the progress // bar and a speed slider footer: ToolBar { RowLayout { //TODO change button texts to icons // (https://doc.qt.io/qt-6/qtquickcontrols-icons.html) id: controlBar anchors.fill: parent Layout.alignment: Qt.AlignVCenter Layout.fillWidth: true // anchors.topMargin: 5 //FIXME // anchors.bottomMargin: 5 Button { id: backButton text: "<" ToolTip.text: "Back" ToolTip.visible: hovered onClicked: { Julia.previousstep() } } Button { id: stepButton text: ">" ToolTip.text: "Step" ToolTip.visible: hovered onClicked: { Julia.nextstep() } } Button { id: runButton text: vars.runbuttontext ToolTip.text: vars.runbuttontip ToolTip.visible: hovered onClicked: { vars.running = !vars.running } } ProgressBar { id: progressBar value: vars.progress Layout.fillWidth: true ToolTip.text: "Simulation progress" ToolTip.visible: hovered } Slider { id: speedSlider from: 0.0 to: 2.0 value: vars.delay stepSize: 0.1 snapMode: Slider.SnapAlways ToolTip.text: "Time delay between updates" ToolTip.visible: hovered onValueChanged: vars.delay = value } Text { id: dateText text: Julia.datestring() //width: //TODO } } } // extra windows MessageDialog { id: aboutDialog text: "Persefone.jl Desktop" informativeText: "A mechanistic model of agricultural landscapes \ and ecosystems in Europe.\n\n\ © 2023 Daniel Vedder, Lea Kolb, Guy Pe'er\n\ Distributed under the MIT license." } FileDialog { id: loadFileChooser defaultSuffix: "dat" nameFilters: ["Save files (*.dat)"] onAccepted: { Julia.loadsimulation(selectedFile.toString()) } } FileDialog { id: saveFileChooser defaultSuffix: "dat" fileMode: FileDialog.SaveFile nameFilters: ["Save files (*.dat)"] onAccepted: { Julia.savesimulation(selectedFile.toString()) } } Window { id: populationGraph title: "Population Graph" width: 512 height: 512 visible: false MakieViewport { id: plotviewport anchors.fill: parent renderFunction: render_plot_callback } } Popup { id: splashPopup parent: Overlay.overlay closePolicy: Popup.NoAutoClose modal: true padding: 0 width: 600 height: 250 x: Math.round((parent.width - width) / 2) y: Math.round((parent.height - height) / 2) Image { anchors.fill: parent source: "persefonejl_logo_v3_splash.png" } } // set up connections and signals to update the simulation and the display Connections { target: timer function onTimeout() { vars.ticks += 1 } } JuliaSignals { signal updateMakie() onUpdateMakie: { dateText.text = Julia.datestring(); mapviewport.update(); plotviewport.update(); } signal showSplash() onShowSplash: { splashPopup.open() } signal closeSplash() onCloseSplash: { splashPopup.close() } } }