diff --git a/src/interface/modeler/quickapp/MainModelerWindow.cpp b/src/interface/modeler/quickapp/MainModelerWindow.cpp
index fcf8fd1..c0ac81f 100644
--- a/src/interface/modeler/quickapp/MainModelerWindow.cpp
+++ b/src/interface/modeler/quickapp/MainModelerWindow.cpp
@@ -37,6 +37,24 @@ MainModelerWindow::MainModelerWindow()
water = new WaterModeler(this);
render_process = new RenderProcess(this, render_preview_provider);
+
+ // Bind file buttons
+ QObject *button_new = findQmlObject("tool_file_new");
+ if (button_new) {
+ connect(button_new, SIGNAL(clicked()), this, SLOT(newFile()));
+ }
+ QObject *button_save = findQmlObject("tool_file_save");
+ if (button_save) {
+ connect(button_save, SIGNAL(clicked()), this, SLOT(saveFile()));
+ }
+ QObject *button_load = findQmlObject("tool_file_load");
+ if (button_load) {
+ connect(button_load, SIGNAL(clicked()), this, SLOT(loadFile()));
+ }
+ QObject *button_exit = findQmlObject("tool_file_exit");
+ if (button_exit) {
+ connect(button_exit, SIGNAL(clicked()), this, SLOT(exit()));
+ }
}
MainModelerWindow::~MainModelerWindow()
@@ -76,6 +94,32 @@ void MainModelerWindow::setState(const QString &stateName)
rootObject()->setProperty("state", stateName);
}
+void MainModelerWindow::newFile()
+{
+ getScenery()->autoPreset();
+ renderer->reset();
+}
+
+void MainModelerWindow::saveFile()
+{
+ getScenery()->saveGlobal("saved.p3d");
+}
+
+void MainModelerWindow::loadFile()
+{
+ Scenery loaded;
+ if (loaded.loadGlobal("saved.p3d") == Scenery::FILE_OPERATION_OK)
+ {
+ loaded.copy(scenery);
+ renderer->reset();
+ }
+}
+
+void MainModelerWindow::exit()
+{
+ QGuiApplication::instance()->exit();
+}
+
void MainModelerWindow::keyReleaseEvent(QKeyEvent *event)
{
if (getState() == "Render Dialog")
@@ -113,30 +157,28 @@ void MainModelerWindow::keyReleaseEvent(QKeyEvent *event)
{
if (event->modifiers() & Qt::ControlModifier)
{
- QGuiApplication::instance()->exit();
+ exit();
}
}
else if (event->key() == Qt::Key_N)
{
if (event->modifiers() & Qt::ControlModifier)
{
- getScenery()->autoPreset();
- renderer->reset();
+ newFile();
}
}
else if (event->key() == Qt::Key_S)
{
if (event->modifiers() & Qt::ControlModifier)
{
- getScenery()->saveGlobal("saved.p3d");
+ saveFile();
}
}
else if (event->key() == Qt::Key_L or event->key() == Qt::Key_O)
{
if (event->modifiers() & Qt::ControlModifier)
{
- getScenery()->loadGlobal("saved.p3d");
- renderer->reset();
+ loadFile();
}
}
else if (event->key() == Qt::Key_Z)
diff --git a/src/interface/modeler/quickapp/MainModelerWindow.h b/src/interface/modeler/quickapp/MainModelerWindow.h
index a48cf26..6f37fcb 100644
--- a/src/interface/modeler/quickapp/MainModelerWindow.h
+++ b/src/interface/modeler/quickapp/MainModelerWindow.h
@@ -25,6 +25,12 @@ public:
inline OpenGLRenderer *getRenderer() const {return renderer;}
inline ModelerCameras *getCamera() const {return cameras;}
+public slots:
+ void newFile();
+ void saveFile();
+ void loadFile();
+ void exit();
+
protected:
virtual void keyReleaseEvent(QKeyEvent *event) override;
diff --git a/src/interface/modeler/quickapp/qml/BaseChoice.qml b/src/interface/modeler/quickapp/qml/BaseChoice.qml
index f0ec228..df650f5 100644
--- a/src/interface/modeler/quickapp/qml/BaseChoice.qml
+++ b/src/interface/modeler/quickapp/qml/BaseChoice.qml
@@ -4,9 +4,8 @@ import QtQuick.Layouts 1.1
Item {
default property alias children : inner_layout.children
+ property alias spacing : inner_layout.spacing
property int value
- width: 100
- height: 32
ExclusiveGroup {
id: choice_group
diff --git a/src/interface/modeler/quickapp/qml/BaseChoiceItem.qml b/src/interface/modeler/quickapp/qml/BaseChoiceItem.qml
index 7e87197..bafaf7b 100644
--- a/src/interface/modeler/quickapp/qml/BaseChoiceItem.qml
+++ b/src/interface/modeler/quickapp/qml/BaseChoiceItem.qml
@@ -7,18 +7,23 @@ Rectangle {
property bool checked: false
property ExclusiveGroup exclusiveGroup: null
property int value
+ property int padding: 4
color: "#333333"
+ radius: padding * 2
signal toggled(bool value)
- width: 20
- height: 20
+ width: 40
+ height: 40
Image {
- anchors.fill: parent
+ id: icon_image
source: parent.icon
- antialiasing: true
+ width: parent.width - 2 * parent.padding
+ height: parent.height - 2 * parent.padding
+ anchors.centerIn: parent
+ antialiasing: true
}
MouseArea {
@@ -35,6 +40,12 @@ Rectangle {
onCheckedChanged: choice_item.toggled(checked)
+ Behavior on color {
+ PropertyAnimation {
+ duration: 200
+ }
+ }
+
states: [
State {
name: "Checked"
@@ -42,7 +53,7 @@ Rectangle {
PropertyChanges {
target: choice_item
- color: "#999999"
+ color: "#dddddd"
}
}
diff --git a/src/interface/modeler/quickapp/qml/BasePanel.qml b/src/interface/modeler/quickapp/qml/BasePanel.qml
index 36652ae..6250d04 100644
--- a/src/interface/modeler/quickapp/qml/BasePanel.qml
+++ b/src/interface/modeler/quickapp/qml/BasePanel.qml
@@ -4,22 +4,21 @@ BaseRectangle {
property ToolbarButton tool
id: panel
- enabled: false
width: 200
- height: parent.height - 100
- color: "#a0909090"
+ height: primary_toolbar.current ? primary_toolbar.current.height : 10
+ color: "#40909090"
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
+ anchors.left: primary_toolbar.current ? primary_toolbar.current.right : parent.left
+ anchors.top: primary_toolbar.current ? primary_toolbar.current.top : parent.top
states: [
State {
- name: "Active"
- when: tool.selected
+ name: "hidden"
+ when: !tool.selected
PropertyChanges {
target: panel
- enabled: true
+ enabled: false
}
}
diff --git a/src/interface/modeler/quickapp/qml/BaseRectangle.qml b/src/interface/modeler/quickapp/qml/BaseRectangle.qml
index 956ccbb..c074bb7 100644
--- a/src/interface/modeler/quickapp/qml/BaseRectangle.qml
+++ b/src/interface/modeler/quickapp/qml/BaseRectangle.qml
@@ -10,4 +10,3 @@ Rectangle {
}
}
}
-
diff --git a/src/interface/modeler/quickapp/qml/BaseSecondaryToolbar.qml b/src/interface/modeler/quickapp/qml/BaseSecondaryToolbar.qml
new file mode 100644
index 0000000..bd4670f
--- /dev/null
+++ b/src/interface/modeler/quickapp/qml/BaseSecondaryToolbar.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+
+Toolbar {
+ enabled: false
+ height: parent.height - primary_toolbar.height
+ anchors.left: primary_toolbar.left
+ anchors.top: primary_toolbar.bottom
+
+ onEnabledChanged: primary_toolbar.current = this
+}
+
diff --git a/src/interface/modeler/quickapp/qml/CameraChoice.qml b/src/interface/modeler/quickapp/qml/CameraChoice.qml
index b8bdb57..ebbfbee 100644
--- a/src/interface/modeler/quickapp/qml/CameraChoice.qml
+++ b/src/interface/modeler/quickapp/qml/CameraChoice.qml
@@ -1,29 +1,22 @@
import QtQuick 2.0
-BaseRectangle {
+Toolbar {
id: camera_choice
- width: 200
- height: 50
+ horizontal: false
color: "#90888888"
objectName: "camera_choice"
- Row {
- id: inner_space
- anchors.centerIn: parent
- spacing: 15
+ ToolbarButton {
+ id: camera_choice_render
+ picture: "images/tab_display.png"
+ hovertext: qsTr("Final render camera")
+ selected: true
+ }
- ToolbarButton {
- id: camera_choice_render
- picture: "images/tab_display.png"
- hovertext: qsTr("Switch to the final camera")
- selected: true
- }
-
- ToolbarButton {
- id: camera_choice_topdown
- picture: "images/display_topdown.png"
- hovertext: qsTr("Switch to the top-down camera")
- }
+ ToolbarButton {
+ id: camera_choice_topdown
+ picture: "images/display_topdown.png"
+ hovertext: qsTr("Top-down camera")
}
states: [
diff --git a/src/interface/modeler/quickapp/qml/ClickableImage.qml b/src/interface/modeler/quickapp/qml/ClickableImage.qml
new file mode 100644
index 0000000..a8c9291
--- /dev/null
+++ b/src/interface/modeler/quickapp/qml/ClickableImage.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+
+Image {
+ signal clicked()
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+
+ onClicked: {
+ parent.clicked();
+ }
+ }
+}
+
diff --git a/src/interface/modeler/quickapp/qml/PanelAtmosphereDaytime.qml b/src/interface/modeler/quickapp/qml/PanelAtmosphereDaytime.qml
index 00f680b..74f188c 100644
--- a/src/interface/modeler/quickapp/qml/PanelAtmosphereDaytime.qml
+++ b/src/interface/modeler/quickapp/qml/PanelAtmosphereDaytime.qml
@@ -3,10 +3,11 @@ import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
BasePanel {
- width: 70
+ id: daytime
+ width: 100
objectName: "atmosphere_daytime"
- default property real value: day_night.value == 2 ? 1.0 : slider.value * 0.54 + 0.23;
+ default property real value: day_night.value == 2 ? 0.0 : slider.value * 0.54 + 0.23;
signal changed(real value)
onValueChanged: {
@@ -20,15 +21,19 @@ BasePanel {
ColumnLayout
{
- anchors.fill: parent
- anchors.margins: 10
+ height: parent.height
+ anchors.horizontalCenter: parent.horizontalCenter
spacing: 20
+ Item {height: 1}
+
BaseChoice {
id: day_night
- width: parent.width
- Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
+ Layout.alignment: Qt.AlignHCenter
+ spacing: 10
+ width: 90
+ height: 40
BaseChoiceItem {
icon: "images/icon_atmosphere_day.png"
@@ -47,7 +52,97 @@ BasePanel {
Layout.maximumWidth: 15
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
- visible: day_night.value == 1
}
+
+ Grid {
+ id: clock
+ property int hour: daytime.value * 86400 / 3600
+ property int minute: (daytime.value * 86400 - 3600 * hour) / 60
+ property int second: daytime.value * 86400 - 3600 * hour - 60 * minute
+ rows: 3
+ columns: 5
+ rowSpacing: 4
+
+ ClickableImage {
+ width: 20
+ height: 10
+ source: "qrc:/images/arrow_up.png"
+ onClicked: slider.value += (1.0 / 24.0) / 0.54
+ }
+ Item {width: 1; height: 1}
+ ClickableImage {
+ width: 20
+ height: 10
+ source: "qrc:/images/arrow_up.png"
+ onClicked: slider.value += (1.0 / 3600.0) / 0.54
+ }
+ Item {width: 1; height: 1}
+ ClickableImage {
+ width: 20
+ height: 10
+ source: "qrc:/images/arrow_up.png"
+ onClicked: slider.value += (1.0 / 86400.0) / 0.54
+ }
+
+ Text {
+ text: (clock.hour > 9 ? "" : "0") + clock.hour.toString()
+ font.pixelSize: 14
+ }
+ Text {
+ text: " : "
+ font.pixelSize: 14
+ }
+ Text {
+ text: (clock.minute > 9 ? "" : "0") + clock.minute.toString()
+ font.pixelSize: 14
+ }
+ Text {
+ text: " : "
+ font.pixelSize: 14
+ }
+ Text {
+ text: (clock.second > 9 ? "" : "0") + clock.second.toString()
+ font.pixelSize: 14
+ }
+
+ ClickableImage {
+ width: 20
+ height: 10
+ source: "qrc:/images/arrow_down.png"
+ onClicked: slider.value -= (1.0 / 24.0) / 0.54
+ }
+ Item {width: 1; height: 1}
+ ClickableImage {
+ width: 20
+ height: 10
+ source: "qrc:/images/arrow_down.png"
+ onClicked: slider.value -= (1.0 / 1440.0) / 0.54
+ }
+ Item {width: 1; height: 1}
+ ClickableImage {
+ width: 20
+ height: 10
+ source: "qrc:/images/arrow_down.png"
+ onClicked: slider.value -= (1.0 / 86400.0) / 0.54
+ }
+ }
+
+ Item {height: 1}
}
+
+ states: [
+ State {
+ name: "night"
+ when: day_night.value == 2
+ PropertyChanges {
+ target: slider
+ enabled: false
+ }
+ PropertyChanges {
+ target: clock
+ enabled: false
+ }
+ }
+
+ ]
}
diff --git a/src/interface/modeler/quickapp/qml/PanelWaterLevel.qml b/src/interface/modeler/quickapp/qml/PanelWaterLevel.qml
index 90d4be0..74b084a 100644
--- a/src/interface/modeler/quickapp/qml/PanelWaterLevel.qml
+++ b/src/interface/modeler/quickapp/qml/PanelWaterLevel.qml
@@ -1,7 +1,7 @@
import QtQuick 2.2
BasePanel {
- width: 20
+ width: 40
BaseSlider {
objectName: "water_height"
@@ -9,5 +9,6 @@ BasePanel {
maximumValue: 1
orientation: Qt.Vertical
anchors.fill: parent
+ anchors.margins: 10
}
}
diff --git a/src/interface/modeler/quickapp/qml/Toolbar.qml b/src/interface/modeler/quickapp/qml/Toolbar.qml
index 3e04d5e..ad5e73d 100644
--- a/src/interface/modeler/quickapp/qml/Toolbar.qml
+++ b/src/interface/modeler/quickapp/qml/Toolbar.qml
@@ -3,13 +3,16 @@ import QtQuick 2.0
BaseRectangle {
default property alias children : inner_space.children
- width: 70
- height: parent.height
+ property bool horizontal: false
+ width: horizontal ? parent.width : 60
+ height: horizontal ? 60 : parent.height
color: "#50888888"
- Column {
+ Grid {
id: inner_space
- spacing: (parent.height - children.length * tool_terrain.height) / (children.length + 1)
+ columns: parent.horizontal ? children.length : 1
+ rows: parent.horizontal ? 1 : children.length
+ spacing: (parent.horizontal ? (parent.width - children.length * tool_terrain.width) : (parent.height - children.length * tool_terrain.height)) / (children.length + 1)
anchors.centerIn: parent
}
diff --git a/src/interface/modeler/quickapp/qml/ToolbarButton.qml b/src/interface/modeler/quickapp/qml/ToolbarButton.qml
index ab7719f..cab0f34 100644
--- a/src/interface/modeler/quickapp/qml/ToolbarButton.qml
+++ b/src/interface/modeler/quickapp/qml/ToolbarButton.qml
@@ -59,6 +59,7 @@ Item {
onEntered: {
parent.hovered = true;
tooltip_widget.hovertext = hovertext;
+ tooltip_widget.hovered = this;
}
onExited: {
parent.hovered = false;
diff --git a/src/interface/modeler/quickapp/qml/Tooltip.qml b/src/interface/modeler/quickapp/qml/Tooltip.qml
index 05e1631..64b52c8 100644
--- a/src/interface/modeler/quickapp/qml/Tooltip.qml
+++ b/src/interface/modeler/quickapp/qml/Tooltip.qml
@@ -1,16 +1,31 @@
import QtQuick 2.0
BaseRectangle {
+ property var hovered
property string helptext
property string hovertext
- width: content.width
- height: content.height
+ width: content.width + 10
+ height: content.height + 10
+ enabled: content.deftext ? true : false
+ anchors.margins: 5
color: "#99000000"
Text {
id: content
color: "white"
- text: parent.helptext || parent.hovertext
+ font.bold: true
+ font.pixelSize: 12
+ property string deftext: parent.helptext || parent.hovertext
+ property string oldtext
+ text: deftext || oldtext
+ anchors.centerIn: parent
+
+ onDeftextChanged: {
+ if (deftext)
+ {
+ oldtext = deftext;
+ }
+ }
}
}
diff --git a/src/interface/modeler/quickapp/qml/app.qrc b/src/interface/modeler/quickapp/qml/app.qrc
index 3b20493..db80c69 100644
--- a/src/interface/modeler/quickapp/qml/app.qrc
+++ b/src/interface/modeler/quickapp/qml/app.qrc
@@ -28,5 +28,14 @@
RenderDialog.qml
CameraChoice.qml
BaseRectangle.qml
+ BaseSecondaryToolbar.qml
+ images/icon_exit.png
+ images/icon_file_load.png
+ images/icon_file_new.png
+ images/icon_file_save.png
+ images/tab_file.png
+ images/arrow_down.png
+ images/arrow_up.png
+ ClickableImage.qml
diff --git a/src/interface/modeler/quickapp/qml/images/arrow_down.png b/src/interface/modeler/quickapp/qml/images/arrow_down.png
new file mode 100644
index 0000000..8c1365e
Binary files /dev/null and b/src/interface/modeler/quickapp/qml/images/arrow_down.png differ
diff --git a/src/interface/modeler/quickapp/qml/images/arrow_up.png b/src/interface/modeler/quickapp/qml/images/arrow_up.png
new file mode 100644
index 0000000..2f6c816
Binary files /dev/null and b/src/interface/modeler/quickapp/qml/images/arrow_up.png differ
diff --git a/src/interface/modeler/quickapp/qml/images/icon_exit.png b/src/interface/modeler/quickapp/qml/images/icon_exit.png
new file mode 100644
index 0000000..136c54e
Binary files /dev/null and b/src/interface/modeler/quickapp/qml/images/icon_exit.png differ
diff --git a/src/interface/modeler/quickapp/qml/images/icon_file_load.png b/src/interface/modeler/quickapp/qml/images/icon_file_load.png
new file mode 100644
index 0000000..0502784
Binary files /dev/null and b/src/interface/modeler/quickapp/qml/images/icon_file_load.png differ
diff --git a/src/interface/modeler/quickapp/qml/images/icon_file_new.png b/src/interface/modeler/quickapp/qml/images/icon_file_new.png
new file mode 100644
index 0000000..661ed40
Binary files /dev/null and b/src/interface/modeler/quickapp/qml/images/icon_file_new.png differ
diff --git a/src/interface/modeler/quickapp/qml/images/icon_file_save.png b/src/interface/modeler/quickapp/qml/images/icon_file_save.png
new file mode 100644
index 0000000..1fadb03
Binary files /dev/null and b/src/interface/modeler/quickapp/qml/images/icon_file_save.png differ
diff --git a/src/interface/modeler/quickapp/qml/images/tab_file.png b/src/interface/modeler/quickapp/qml/images/tab_file.png
new file mode 100644
index 0000000..9730761
Binary files /dev/null and b/src/interface/modeler/quickapp/qml/images/tab_file.png differ
diff --git a/src/interface/modeler/quickapp/qml/main.qml b/src/interface/modeler/quickapp/qml/main.qml
index 951e286..337a7b1 100644
--- a/src/interface/modeler/quickapp/qml/main.qml
+++ b/src/interface/modeler/quickapp/qml/main.qml
@@ -11,66 +11,58 @@ OpenGLView {
Tooltip {
id: tooltip_widget
- anchors.top: parent.top
- anchors.right: parent.right
+ anchors.top: primary_toolbar.bottom
+ anchors.right: primary_toolbar.right
}
Toolbar {
id: primary_toolbar
+ horizontal: true
color: "#90888888"
+ property var current
+ anchors.top: parent.top
anchors.left: parent.left
- ToolbarButton {
- id: tool_display
- picture: "images/tab_display.png"
- hovertext: qsTr("Display options")
- }
ToolbarButton {
id: tool_terrain
picture: "images/tab_terrain.png"
+ hovertext: qsTr("Terrain edition")
}
ToolbarButton {
id: tool_textures
picture: "images/tab_textures.png"
+ hovertext: qsTr("Terrain textures")
}
ToolbarButton {
id: tool_water
picture: "images/icon_water.png"
- hovertext: "Water tools"
+ hovertext: qsTr("Water tools")
}
ToolbarButton {
id: tool_atmosphere
picture: "images/icon_atmosphere.png"
- hovertext: "Atmosphere/weather tools"
+ hovertext: qsTr("Atmosphere/weather control")
}
ToolbarButton {
id: tool_clouds
picture: "images/tab_clouds.png"
+ hovertext: qsTr("Cloud layers")
}
ToolbarButton {
id: tool_render
picture: "images/tab_render.png"
+ hovertext: qsTr("Rendering")
}
- }
-
- Toolbar {
- id: display_toolbar
- enabled: false
- anchors.left: primary_toolbar.right
-
ToolbarButton {
- id: tool_display_topdown
- picture: "images/display_topdown.png"
- hovertext: qsTr("Top-down view")
- helptext: qsTr("Drag the mouse on the map to change the viewpoint.")
+ id: tool_file
+ picture: "images/tab_file.png"
+ hovertext: qsTr("File")
}
}
- Toolbar {
+ BaseSecondaryToolbar {
id: water_toolbar
- enabled: false
- anchors.left: primary_toolbar.right
ToolbarButton {
id: tool_water_level
@@ -79,10 +71,8 @@ OpenGLView {
}
}
- Toolbar {
+ BaseSecondaryToolbar {
id: atmosphere_toolbar
- enabled: false
- anchors.left: primary_toolbar.right
ToolbarButton {
id: tool_atmosphere_daytime
@@ -91,10 +81,8 @@ OpenGLView {
}
}
- Toolbar {
+ BaseSecondaryToolbar {
id: render_toolbar
- enabled: false
- anchors.left: primary_toolbar.right
ToolbarButton {
id: tool_render_quick
@@ -104,10 +92,43 @@ OpenGLView {
}
}
+ BaseSecondaryToolbar {
+ id: file_toolbar
+
+ ToolbarButton {
+ id: tool_file_new
+ objectName: "tool_file_new"
+ picture: "images/icon_file_new.png"
+ hovertext: qsTr("Generate a new scene")
+ }
+
+ ToolbarButton {
+ id: tool_file_save
+ objectName: "tool_file_save"
+ picture: "images/icon_file_save.png"
+ hovertext: qsTr("Save the current scene to a file")
+ }
+
+ ToolbarButton {
+ id: tool_file_load
+ objectName: "tool_file_load"
+ picture: "images/icon_file_load.png"
+ hovertext: qsTr("Load a scene from a file")
+ }
+
+ ToolbarButton {
+ id: tool_file_exit
+ objectName: "tool_file_exit"
+ picture: "images/icon_exit.png"
+ hovertext: qsTr("Exit the program")
+ }
+ }
+
CameraChoice {
id: camera_choice
- anchors.bottom: main_ui.bottom
- anchors.horizontalCenter: main_ui.horizontalCenter
+ height: 150
+ anchors.right: main_ui.right
+ anchors.verticalCenter: main_ui.verticalCenter
}
RenderDialog {
@@ -126,15 +147,6 @@ OpenGLView {
}
states: [
- State {
- name: "Display Mode"
- when: tool_display.selected
-
- PropertyChanges {
- target: display_toolbar
- enabled: true
- }
- },
State {
name: "Water Mode"
when: tool_water.selected
@@ -162,6 +174,15 @@ OpenGLView {
enabled: true
}
},
+ State {
+ name: "File Mode"
+ when: tool_file.selected
+
+ PropertyChanges {
+ target: file_toolbar
+ enabled: true
+ }
+ },
State {
name: "Render Dialog"