diff --git a/src/vr/assets/img/alarm/alarm_activated.png b/src/vr/assets/img/alarm/alarm_activated.png
new file mode 100755
index 0000000..58bcc95
Binary files /dev/null and b/src/vr/assets/img/alarm/alarm_activated.png differ
diff --git a/src/vr/assets/img/audio/media_keys/outline_play_pause_white_24dp.svg b/src/vr/assets/img/audio/media_keys/outline_play_pause_white_24dp.svg
new file mode 100755
index 0000000..03a3ca1
--- /dev/null
+++ b/src/vr/assets/img/audio/media_keys/outline_play_pause_white_24dp.svg
@@ -0,0 +1,12 @@
+
+
+
diff --git a/src/vr/assets/img/audio/media_keys/outline_skip_next_white_24dp.svg b/src/vr/assets/img/audio/media_keys/outline_skip_next_white_24dp.svg
new file mode 100755
index 0000000..23fa6ea
--- /dev/null
+++ b/src/vr/assets/img/audio/media_keys/outline_skip_next_white_24dp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/vr/assets/img/audio/media_keys/outline_skip_previous_white_24dp.svg b/src/vr/assets/img/audio/media_keys/outline_skip_previous_white_24dp.svg
new file mode 100755
index 0000000..1d08e59
--- /dev/null
+++ b/src/vr/assets/img/audio/media_keys/outline_skip_previous_white_24dp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/vr/assets/img/audio/media_keys/outline_stop_white_24dp.svg b/src/vr/assets/img/audio/media_keys/outline_stop_white_24dp.svg
new file mode 100755
index 0000000..2123cee
--- /dev/null
+++ b/src/vr/assets/img/audio/media_keys/outline_stop_white_24dp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/vr/assets/img/audio/microphone/mic_off.svg b/src/vr/assets/img/audio/microphone/mic_off.svg
new file mode 100755
index 0000000..a03af97
--- /dev/null
+++ b/src/vr/assets/img/audio/microphone/mic_off.svg
@@ -0,0 +1,75 @@
+
+
diff --git a/src/vr/assets/img/audio/microphone/mic_on.svg b/src/vr/assets/img/audio/microphone/mic_on.svg
new file mode 100755
index 0000000..7c32e56
--- /dev/null
+++ b/src/vr/assets/img/audio/microphone/mic_on.svg
@@ -0,0 +1,70 @@
+
+
diff --git a/src/vr/assets/img/audio/microphone/ptm_notification.png b/src/vr/assets/img/audio/microphone/ptm_notification.png
new file mode 100755
index 0000000..3bfa181
Binary files /dev/null and b/src/vr/assets/img/audio/microphone/ptm_notification.png differ
diff --git a/src/vr/assets/img/audio/microphone/ptt_notification.png b/src/vr/assets/img/audio/microphone/ptt_notification.png
new file mode 100755
index 0000000..cf8d3f9
Binary files /dev/null and b/src/vr/assets/img/audio/microphone/ptt_notification.png differ
diff --git a/src/vr/assets/img/audio/microphone/ptt_notification.svg b/src/vr/assets/img/audio/microphone/ptt_notification.svg
new file mode 100755
index 0000000..a3a96d3
--- /dev/null
+++ b/src/vr/assets/img/audio/microphone/ptt_notification.svg
@@ -0,0 +1,85 @@
+
+
diff --git a/src/vr/assets/img/audio/speaker/speaker_off.svg b/src/vr/assets/img/audio/speaker/speaker_off.svg
new file mode 100755
index 0000000..585c36d
--- /dev/null
+++ b/src/vr/assets/img/audio/speaker/speaker_off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/vr/assets/img/audio/speaker/speaker_on.svg b/src/vr/assets/img/audio/speaker/speaker_on.svg
new file mode 100755
index 0000000..f0353d8
--- /dev/null
+++ b/src/vr/assets/img/audio/speaker/speaker_on.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/vr/assets/img/battery/battery_0.png b/src/vr/assets/img/battery/battery_0.png
new file mode 100755
index 0000000..1b97fea
Binary files /dev/null and b/src/vr/assets/img/battery/battery_0.png differ
diff --git a/src/vr/assets/img/battery/battery_1.png b/src/vr/assets/img/battery/battery_1.png
new file mode 100755
index 0000000..190004a
Binary files /dev/null and b/src/vr/assets/img/battery/battery_1.png differ
diff --git a/src/vr/assets/img/battery/battery_2.png b/src/vr/assets/img/battery/battery_2.png
new file mode 100755
index 0000000..abf2625
Binary files /dev/null and b/src/vr/assets/img/battery/battery_2.png differ
diff --git a/src/vr/assets/img/battery/battery_3.png b/src/vr/assets/img/battery/battery_3.png
new file mode 100755
index 0000000..9e0a8c6
Binary files /dev/null and b/src/vr/assets/img/battery/battery_3.png differ
diff --git a/src/vr/assets/img/battery/battery_4.png b/src/vr/assets/img/battery/battery_4.png
new file mode 100755
index 0000000..2fd59c3
Binary files /dev/null and b/src/vr/assets/img/battery/battery_4.png differ
diff --git a/src/vr/assets/img/battery/battery_5.png b/src/vr/assets/img/battery/battery_5.png
new file mode 100755
index 0000000..916fa2d
Binary files /dev/null and b/src/vr/assets/img/battery/battery_5.png differ
diff --git a/src/vr/assets/img/chaperone/centermark.png b/src/vr/assets/img/chaperone/centermark.png
new file mode 100755
index 0000000..44ddeab
Binary files /dev/null and b/src/vr/assets/img/chaperone/centermark.png differ
diff --git a/src/vr/assets/img/chaperone/centermarkl1.png b/src/vr/assets/img/chaperone/centermarkl1.png
new file mode 100755
index 0000000..88d99f0
Binary files /dev/null and b/src/vr/assets/img/chaperone/centermarkl1.png differ
diff --git a/src/vr/assets/img/chaperone/centermarkl2.png b/src/vr/assets/img/chaperone/centermarkl2.png
new file mode 100755
index 0000000..0b6e4df
Binary files /dev/null and b/src/vr/assets/img/chaperone/centermarkl2.png differ
diff --git a/src/vr/assets/img/chaperone/centermarkl3.png b/src/vr/assets/img/chaperone/centermarkl3.png
new file mode 100755
index 0000000..f554af6
Binary files /dev/null and b/src/vr/assets/img/chaperone/centermarkl3.png differ
diff --git a/src/vr/assets/img/chaperone/centermarkr1.png b/src/vr/assets/img/chaperone/centermarkr1.png
new file mode 100755
index 0000000..4ab9f37
Binary files /dev/null and b/src/vr/assets/img/chaperone/centermarkr1.png differ
diff --git a/src/vr/assets/img/chaperone/centermarkr2.png b/src/vr/assets/img/chaperone/centermarkr2.png
new file mode 100755
index 0000000..5a2849c
Binary files /dev/null and b/src/vr/assets/img/chaperone/centermarkr2.png differ
diff --git a/src/vr/assets/img/chaperone/centermarkr3.png b/src/vr/assets/img/chaperone/centermarkr3.png
new file mode 100755
index 0000000..1d6865c
Binary files /dev/null and b/src/vr/assets/img/chaperone/centermarkr3.png differ
diff --git a/src/vr/assets/img/chest.png b/src/vr/assets/img/chest.png
new file mode 100644
index 0000000..675161b
Binary files /dev/null and b/src/vr/assets/img/chest.png differ
diff --git a/src/vr/assets/img/common/backarrow.svg b/src/vr/assets/img/common/backarrow.svg
new file mode 100755
index 0000000..6e08dbe
--- /dev/null
+++ b/src/vr/assets/img/common/backarrow.svg
@@ -0,0 +1,76 @@
+
+
diff --git a/src/vr/assets/img/common/check.svg b/src/vr/assets/img/common/check.svg
new file mode 100755
index 0000000..6a6f37f
--- /dev/null
+++ b/src/vr/assets/img/common/check.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/vr/assets/img/confirmed.png b/src/vr/assets/img/confirmed.png
new file mode 100755
index 0000000..2023abd
Binary files /dev/null and b/src/vr/assets/img/confirmed.png differ
diff --git a/src/vr/assets/img/cpus.png b/src/vr/assets/img/cpus.png
new file mode 100644
index 0000000..a3aa53e
Binary files /dev/null and b/src/vr/assets/img/cpus.png differ
diff --git a/src/vr/assets/img/cpus.svg b/src/vr/assets/img/cpus.svg
new file mode 100644
index 0000000..4157fe0
--- /dev/null
+++ b/src/vr/assets/img/cpus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/vr/assets/img/dog.gif b/src/vr/assets/img/dog.gif
new file mode 100644
index 0000000..433ee58
Binary files /dev/null and b/src/vr/assets/img/dog.gif differ
diff --git a/src/vr/assets/img/dog2.gif b/src/vr/assets/img/dog2.gif
new file mode 100644
index 0000000..f773aee
Binary files /dev/null and b/src/vr/assets/img/dog2.gif differ
diff --git a/src/vr/assets/img/expired.png b/src/vr/assets/img/expired.png
new file mode 100755
index 0000000..6400b8b
Binary files /dev/null and b/src/vr/assets/img/expired.png differ
diff --git a/src/vr/assets/img/grass.png b/src/vr/assets/img/grass.png
new file mode 100644
index 0000000..d3f74dd
Binary files /dev/null and b/src/vr/assets/img/grass.png differ
diff --git a/src/vr/assets/img/hypnotoad.png b/src/vr/assets/img/hypnotoad.png
new file mode 100644
index 0000000..fcf0257
Binary files /dev/null and b/src/vr/assets/img/hypnotoad.png differ
diff --git a/src/vr/assets/img/icons/advicon256px.ico b/src/vr/assets/img/icons/advicon256px.ico
new file mode 100755
index 0000000..dae4b8d
Binary files /dev/null and b/src/vr/assets/img/icons/advicon256px.ico differ
diff --git a/src/vr/assets/img/icons/thumbicon.png b/src/vr/assets/img/icons/thumbicon.png
new file mode 100755
index 0000000..3805af1
Binary files /dev/null and b/src/vr/assets/img/icons/thumbicon.png differ
diff --git a/src/vr/assets/img/illuminati.png b/src/vr/assets/img/illuminati.png
new file mode 100644
index 0000000..459f83e
Binary files /dev/null and b/src/vr/assets/img/illuminati.png differ
diff --git a/src/vr/assets/img/info.png b/src/vr/assets/img/info.png
new file mode 100755
index 0000000..a1bb2a9
Binary files /dev/null and b/src/vr/assets/img/info.png differ
diff --git a/src/vr/assets/img/main_menu_icons/audio_tab_icon.svg b/src/vr/assets/img/main_menu_icons/audio_tab_icon.svg
new file mode 100755
index 0000000..110df6f
--- /dev/null
+++ b/src/vr/assets/img/main_menu_icons/audio_tab_icon.svg
@@ -0,0 +1,12 @@
+
+
+
diff --git a/src/vr/assets/img/main_menu_icons/bindings_tab_icon.svg b/src/vr/assets/img/main_menu_icons/bindings_tab_icon.svg
new file mode 100755
index 0000000..4526825
--- /dev/null
+++ b/src/vr/assets/img/main_menu_icons/bindings_tab_icon.svg
@@ -0,0 +1,14 @@
+
+
+
diff --git a/src/vr/assets/img/main_menu_icons/chaperone_tab_icon.svg b/src/vr/assets/img/main_menu_icons/chaperone_tab_icon.svg
new file mode 100755
index 0000000..54c94c7
--- /dev/null
+++ b/src/vr/assets/img/main_menu_icons/chaperone_tab_icon.svg
@@ -0,0 +1,12 @@
+
+
+
diff --git a/src/vr/assets/img/main_menu_icons/motion_tab_icon.svg b/src/vr/assets/img/main_menu_icons/motion_tab_icon.svg
new file mode 100755
index 0000000..a5b2ca8
--- /dev/null
+++ b/src/vr/assets/img/main_menu_icons/motion_tab_icon.svg
@@ -0,0 +1,14 @@
+
+
+
diff --git a/src/vr/assets/img/main_menu_icons/offsets_tab_icon.svg b/src/vr/assets/img/main_menu_icons/offsets_tab_icon.svg
new file mode 100755
index 0000000..5c7d0d9
--- /dev/null
+++ b/src/vr/assets/img/main_menu_icons/offsets_tab_icon.svg
@@ -0,0 +1,13 @@
+
+
+
diff --git a/src/vr/assets/img/main_menu_icons/rotation_tab_icon.svg b/src/vr/assets/img/main_menu_icons/rotation_tab_icon.svg
new file mode 100755
index 0000000..0735790
--- /dev/null
+++ b/src/vr/assets/img/main_menu_icons/rotation_tab_icon.svg
@@ -0,0 +1,13 @@
+
+
+
diff --git a/src/vr/assets/img/main_menu_icons/settings_tab_icon.svg b/src/vr/assets/img/main_menu_icons/settings_tab_icon.svg
new file mode 100755
index 0000000..7079354
--- /dev/null
+++ b/src/vr/assets/img/main_menu_icons/settings_tab_icon.svg
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/vr/assets/img/main_menu_icons/space_fix_tab_icon.svg b/src/vr/assets/img/main_menu_icons/space_fix_tab_icon.svg
new file mode 100755
index 0000000..f9d375e
--- /dev/null
+++ b/src/vr/assets/img/main_menu_icons/space_fix_tab_icon.svg
@@ -0,0 +1,12 @@
+
+
+
diff --git a/src/vr/assets/img/main_menu_icons/statistics_tab_icon.svg b/src/vr/assets/img/main_menu_icons/statistics_tab_icon.svg
new file mode 100755
index 0000000..d92e219
--- /dev/null
+++ b/src/vr/assets/img/main_menu_icons/statistics_tab_icon.svg
@@ -0,0 +1,13 @@
+
+
+
diff --git a/src/vr/assets/img/main_menu_icons/steamvr_tab_icon.svg b/src/vr/assets/img/main_menu_icons/steamvr_tab_icon.svg
new file mode 100755
index 0000000..11f8ead
--- /dev/null
+++ b/src/vr/assets/img/main_menu_icons/steamvr_tab_icon.svg
@@ -0,0 +1,12 @@
+
+
+
diff --git a/src/vr/assets/img/main_menu_icons/utilities_tab_icon.svg b/src/vr/assets/img/main_menu_icons/utilities_tab_icon.svg
new file mode 100755
index 0000000..59e5480
--- /dev/null
+++ b/src/vr/assets/img/main_menu_icons/utilities_tab_icon.svg
@@ -0,0 +1,12 @@
+
+
+
diff --git a/src/vr/assets/img/main_menu_icons/video_tab_icon.svg b/src/vr/assets/img/main_menu_icons/video_tab_icon.svg
new file mode 100755
index 0000000..fcdccb5
--- /dev/null
+++ b/src/vr/assets/img/main_menu_icons/video_tab_icon.svg
@@ -0,0 +1,12 @@
+
+
+
diff --git a/src/vr/assets/img/receive.svg b/src/vr/assets/img/receive.svg
new file mode 100755
index 0000000..f5de763
--- /dev/null
+++ b/src/vr/assets/img/receive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/vr/assets/img/rotation/autoturn.png b/src/vr/assets/img/rotation/autoturn.png
new file mode 100755
index 0000000..37bd883
Binary files /dev/null and b/src/vr/assets/img/rotation/autoturn.png differ
diff --git a/src/vr/assets/img/rotation/noautoturn.png b/src/vr/assets/img/rotation/noautoturn.png
new file mode 100755
index 0000000..b3a14ef
Binary files /dev/null and b/src/vr/assets/img/rotation/noautoturn.png differ
diff --git a/src/vr/assets/img/rotation/noautoturn.svg b/src/vr/assets/img/rotation/noautoturn.svg
new file mode 100755
index 0000000..755074c
--- /dev/null
+++ b/src/vr/assets/img/rotation/noautoturn.svg
@@ -0,0 +1,120 @@
+
+
diff --git a/src/vr/assets/img/send.png b/src/vr/assets/img/send.png
new file mode 100755
index 0000000..482dae9
Binary files /dev/null and b/src/vr/assets/img/send.png differ
diff --git a/src/vr/assets/img/status_connected.svg b/src/vr/assets/img/status_connected.svg
new file mode 100644
index 0000000..e077999
--- /dev/null
+++ b/src/vr/assets/img/status_connected.svg
@@ -0,0 +1,173 @@
+
+
diff --git a/src/vr/assets/img/status_disconnected.svg b/src/vr/assets/img/status_disconnected.svg
new file mode 100644
index 0000000..46d1a1d
--- /dev/null
+++ b/src/vr/assets/img/status_disconnected.svg
@@ -0,0 +1,293 @@
+
+
+
diff --git a/src/vr/assets/img/status_lagging.svg b/src/vr/assets/img/status_lagging.svg
new file mode 100644
index 0000000..1fd4879
--- /dev/null
+++ b/src/vr/assets/img/status_lagging.svg
@@ -0,0 +1,173 @@
+
+
diff --git a/src/vr/assets/img/status_waiting.svg b/src/vr/assets/img/status_waiting.svg
new file mode 100644
index 0000000..069a4d3
--- /dev/null
+++ b/src/vr/assets/img/status_waiting.svg
@@ -0,0 +1,398 @@
+
+
+
diff --git a/src/vr/assets/img/tutorial.png b/src/vr/assets/img/tutorial.png
new file mode 100644
index 0000000..4cab6f9
Binary files /dev/null and b/src/vr/assets/img/tutorial.png differ
diff --git a/src/vr/assets/img/video/color.png b/src/vr/assets/img/video/color.png
new file mode 100755
index 0000000..be8926f
Binary files /dev/null and b/src/vr/assets/img/video/color.png differ
diff --git a/src/vr/assets/img/video/dimmer.png b/src/vr/assets/img/video/dimmer.png
new file mode 100755
index 0000000..7c2f6a1
Binary files /dev/null and b/src/vr/assets/img/video/dimmer.png differ
diff --git a/src/vr/assets/img/wizard.png b/src/vr/assets/img/wizard.png
new file mode 100644
index 0000000..31426b5
Binary files /dev/null and b/src/vr/assets/img/wizard.png differ
diff --git a/src/vr/main.qml b/src/vr/main.qml
new file mode 100644
index 0000000..2660c12
--- /dev/null
+++ b/src/vr/main.qml
@@ -0,0 +1,353 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.2
+import QtGraphicalEffects 1.0
+import QtQuick.Window 2.0
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Dialogs 1.2
+
+import "."
+import "mock/Windows.js" as Windows
+import "mock/Version.js" as Version
+import "mock/NetworkType.js" as NetworkType
+import "mock/Settings.js" as Settings
+import "mock"
+
+import "qml/common"
+import "qml/."
+
+import wowlet.Wallet 1.0
+import wowlet.WalletManager 1.0
+
+Rectangle {
+ id: appWindow
+ width: 1600
+ height: 800
+ color: "#1b2939"
+
+ property var currentWallet;
+ property bool disconnected: currentWallet ? currentWallet.disconnected : false
+ property string walletTitle: "lol123"
+ property string walletPath: ""
+ property string statusText: "Idle"
+ property string balanceFormatted: "Balance: 25928.9543 WOW (+3902.32 WOW unconfirmed)"
+ property bool wsConnected: false
+ property int connectionStatus: Wallet.ConnectionStatus_Disconnected;
+
+ property var balance: 0.0
+ property var spendable: 0.0
+
+ property DashboardPage dashboardPage: DashboardPage {
+ visible: false
+ }
+
+ property AboutPage aboutPage: AboutPage {
+ visible: false
+ }
+
+ property WalletPage walletPage: WalletPage {
+ visible: false
+ }
+
+ MyDialogOkPopup {
+ id: messagePopup
+ function showMessage(title, text) {
+ dialogTitle = title
+ dialogText = text
+ open()
+ }
+ }
+
+ MyDialogOkCancelPopup {
+ id: enterPasswordDialog
+ dialogTitle: "Enter Password"
+ dialogWidth: 700
+ dialogHeight: 400
+
+ dialogContentItem: ColumnLayout {
+ RowLayout {
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ MyText {
+ text: "Password: "
+ }
+
+ MyTextField {
+ id: walletOpenPassword
+ keyBoardUID: 590
+ color: "#cccccc"
+ text: ""
+ Layout.fillWidth: true
+ font.pointSize: 20
+ function onInputEvent(input) {
+ walletOpenPassword.text = input
+ }
+ }
+ }
+ }
+
+ onClosed: {
+ if (okClicked) {
+ if(walletOpenPassword.text === "")
+ return messagePopup.showMessage("Password empty", "Please fill in a password.");
+
+ ctx.onOpenWallet(appWindow.walletPath, walletOpenPassword.text);
+ }
+ }
+ function openPopup() {
+ open()
+ }
+ }
+
+ MyDialogOkCancelPopup {
+ id: createWalletDialog
+ dialogTitle: "Create New Wallet"
+ dialogWidth: 700
+ dialogHeight: 400
+
+ dialogContentItem: ColumnLayout {
+ RowLayout {
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ MyText {
+ text: "Name: "
+ }
+
+ MyTextField {
+ id: newWalletName
+ keyBoardUID: 590
+ color: "#cccccc"
+ text: ""
+ Layout.fillWidth: true
+ font.pointSize: 20
+ function onInputEvent(input) {
+ newWalletName.text = input
+ }
+ }
+ }
+
+ RowLayout {
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ MyText {
+ text: "Password: "
+ }
+
+ MyTextField {
+ id: newWalletPassword
+ keyBoardUID: 591
+ color: "#cccccc"
+ text: ""
+ Layout.fillWidth: true
+ font.pointSize: 20
+ function onInputEvent(input) {
+ newWalletPassword.text = input
+ }
+ }
+ }
+
+ MyText {
+ fontSize: 16
+ text: "The password field is optional."
+ }
+
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ }
+ onClosed: {
+ if (okClicked) {
+ if(newWalletName.text === "")
+ return messagePopup.showMessage("Invalid name", "Please name the wallet.");
+
+ ctx.createWalletWithoutSpecifyingSeed(newWalletName.text, newWalletPassword.text);
+ }
+ }
+ function openPopup() {
+ open()
+ }
+ }
+
+ StackView {
+ id: mainView
+ anchors.fill: parent
+
+ pushEnter: Transition {
+ PropertyAnimation {
+ property: "x"
+ from: mainView.width
+ to: 0
+ duration: 300
+ easing.type: Easing.OutCubic
+ }
+ }
+ pushExit: Transition {
+ PropertyAnimation {
+ property: "x"
+ from: 0
+ to: -mainView.width
+ duration: 300
+ easing.type: Easing.OutCubic
+ }
+ }
+ popEnter: Transition {
+ PropertyAnimation {
+ property: "x"
+ from: -mainView.width
+ to: 0
+ duration: 300
+ easing.type: Easing.OutCubic
+ }
+ }
+ popExit: Transition {
+ PropertyAnimation {
+ property: "x"
+ from: 0
+ to: mainView.width
+ duration: 300
+ easing.type: Easing.OutCubic
+ }
+ }
+
+ initialItem: dashboardPage
+ }
+
+ Component.onCompleted: {
+ dashboardPage.onPageCompleted();
+
+ if(typeof ctx !== 'undefined') {
+ ctx.initTor();
+ ctx.initWS();
+ }
+ }
+
+ Connections {
+ target: ctx
+
+ function onWsConnected() {
+ console.log("onWsConnected")
+ appWindow.wsConnected = true;
+ }
+
+ function onWsDisconnected() {
+ console.log("onWsDisconnected")
+ appWindow.wsConnected = false;
+ }
+
+ function onWalletOpened(wallet) {
+ console.log("onWalletOpened()");
+
+ appWindow.currentWallet = wallet;
+ appWindow.walletTitle = ctx.walletName;
+ mainView.push(appWindow.walletPage);
+ appWindow.walletPage.onPageCompleted();
+
+ appWindow.currentWallet.connectionStatusChanged.connect(onConnectionStatusChanged);
+ }
+
+ // function onWalletOpened(Wallet *wallet) {
+
+ // currentWallet.heightRefreshed.connect(onHeightRefreshed);
+ // currentWallet.refreshed.connect(onWalletRefresh)
+ // currentWallet.updated.connect(onWalletUpdate)
+ // currentWallet.newBlock.connect(onWalletNewBlock)
+ // currentWallet.moneySpent.connect(onWalletMoneySent)
+ // currentWallet.moneyReceived.connect(onWalletMoneyReceived)
+ // currentWallet.unconfirmedMoneyReceived.connect(onWalletUnconfirmedMoneyReceived)
+ // currentWallet.transactionCreated.connect(onTransactionCreated)
+ // currentWallet.connectionStatusChanged.connect(onWalletConnectionStatusChanged)
+ // currentWallet.deviceButtonRequest.connect(onDeviceButtonRequest);
+ // currentWallet.deviceButtonPressed.connect(onDeviceButtonPressed);
+ // currentWallet.walletPassphraseNeeded.connect(onWalletPassphraseNeededWallet);
+ // currentWallet.transactionCommitted.connect(onTransactionCommitted);
+
+ // middlePanel.paymentClicked.connect(handlePayment);
+ // }
+
+ function onBlockchainSync(height, target) {
+ let blocks = (target > height) ? (target - height) : "?";
+ let heightText = "Blockchain sync: " + blocks + " blocks remaining";
+ appWindow.statusText = heightText;
+ }
+
+ function onRefreshSync(height, target) {
+ let blocks = (target >= height) ? (target - height) : "?";
+ let heightText = "Wallet sync: " + blocks + " blocks remaining";
+ appWindow.statusText = heightText;
+ }
+
+ function onWalletClosed() {
+ console.log("onWalletClosed");
+
+ appWindow.currentWallet.connectionStatusChanged.disconnect(onConnectionStatusChanged);
+
+ appWindow.walletTitle = "";
+ appWindow.balanceFormatted = "";
+ appWindow.balance = 0.0;
+ appWindow.spendable = 0.0;
+ appWindow.connectionStatus = Wallet.ConnectionStatus_Disconnected;
+ }
+
+ function onBalanceUpdatedFormatted(fmt) {
+ appWindow.balanceFormatted = fmt;
+ }
+
+ function onBalanceUpdated(balance, spendable) {
+ appWindow.balance = balance;
+ appWindow.spendable = spendable;
+ }
+
+ function onWalletOpenedError(err) {
+ messagePopup.showMessage("Error", err);
+ }
+
+ function onWalletCreatedError(err) {
+ messagePopup.showMessage("Error", err);
+ }
+
+ function onWalletCreated(wallet) {
+ console.log("walletCreated");
+ }
+
+ function onSynchronized() {
+ appWindow.statusText = "Synchronized";
+
+ appWindow.onConnectionStatusChanged(Wallet.ConnectionStatus_Connected);
+ console.log("onSynchronized");
+ }
+
+ function onWalletOpenPasswordNeeded(invalidPassword, path) { // bool, str
+ enterPasswordDialog.openPopup();
+ }
+
+ function onInitiateTransaction() {
+ console.log("transactionStarted");
+ }
+
+ function onCreateTransactionError(message) { // str
+ console.log("transactionError", message);
+ }
+
+ function onCreateTransactionSuccess(tx, address) { // PendingTransaction
+ // auto-commit all tx's
+ //m_ctx->currentWallet->commitTransactionAsync(tx);
+ console.log("onCreateTransactionSuccess", address)
+ }
+
+ function onTransactionCommitted(status, tx, txid) { // bool,PendingTransaction,stringlist
+ console.log("onTransactionCommitted", status)
+ }
+ }
+
+ function onConnectionStatusChanged(status) {
+ console.log("onConnectionStatusChanged", status)
+ appWindow.connectionStatus = status;
+ }
+}
diff --git a/src/vr/qml.qrc b/src/vr/qml.qrc
new file mode 100644
index 0000000..3b5d696
--- /dev/null
+++ b/src/vr/qml.qrc
@@ -0,0 +1,87 @@
+
+
+ assets/img/common/backarrow.svg
+ assets/img/common/check.svg
+ assets/img/audio/speaker/speaker_on.svg
+ assets/img/audio/speaker/speaker_off.svg
+ assets/img/audio/media_keys/outline_play_pause_white_24dp.svg
+ assets/img/audio/media_keys/outline_skip_next_white_24dp.svg
+ assets/img/audio/media_keys/outline_skip_previous_white_24dp.svg
+ assets/img/audio/media_keys/outline_stop_white_24dp.svg
+ assets/img/main_menu_icons/audio_tab_icon.svg
+ assets/img/main_menu_icons/bindings_tab_icon.svg
+ assets/img/main_menu_icons/chaperone_tab_icon.svg
+ assets/img/main_menu_icons/motion_tab_icon.svg
+ assets/img/main_menu_icons/offsets_tab_icon.svg
+ assets/img/main_menu_icons/settings_tab_icon.svg
+ assets/img/main_menu_icons/space_fix_tab_icon.svg
+ assets/img/main_menu_icons/statistics_tab_icon.svg
+ assets/img/main_menu_icons/steamvr_tab_icon.svg
+ assets/img/main_menu_icons/utilities_tab_icon.svg
+ assets/img/main_menu_icons/video_tab_icon.svg
+ assets/img/main_menu_icons/rotation_tab_icon.svg
+ assets/img/send.png
+ assets/img/receive.svg
+ assets/img/info.png
+ assets/img/confirmed.png
+ assets/img/expired.png
+ assets/img/illuminati.png
+ assets/img/chest.png
+ assets/img/tutorial.png
+ assets/img/wizard.png
+ assets/img/hypnotoad.png
+ assets/img/grass.png
+ assets/img/dog.gif
+ assets/img/dog2.gif
+ assets/img/cpus.png
+
+ assets/img/status_disconnected.svg
+ assets/img/status_connected.svg
+ assets/img/status_waiting.svg
+ assets/img/status_lagging.svg
+
+ mock/NetworkType.js
+ mock/OverlayController.js
+ mock/Settings.js
+ mock/Translation.js
+ mock/Version.js
+ mock/Windows.js
+
+ main.qml
+ qml/common/HourComboBox.qml
+ qml/common/MinuteSecondComboBox.qml
+ qml/common/MyDialogOkCancelPopup.qml
+ qml/common/MyResources.qml
+ qml/common/MyTextField.qml
+ qml/common/MyRadioButton.qml
+ qml/common/MyDialogOkPopup.qml
+ qml/common/MyPushButton2.qml
+ qml/common/MyComboBox.qml
+ qml/common/TimeAssembly.qml
+ qml/common/LineSeparator.qml
+ qml/common/FullWidthSliderBox.qml
+ qml/common/MyText.qml
+ qml/common/MyToggleButton.qml
+ qml/common/MyPushButton.qml
+ qml/common/MySlider.qml
+ qml/common/mainwidget.qml
+ qml/common/MyNumPad.qml
+ qml/common/MyNumPadButton.qml
+ qml/common/MyNumPadSendAmount.qml
+ qml/common/MyStackViewPage.qml
+ qml/wallet/ReceivePage.qml
+ qml/wallet/HistoryTable.qml
+ qml/wallet/WalletDashBoardPage.qml
+
+ qml/DashboardPage.qml
+ qml/WalletPage.qml
+ qml/AboutPage.qml
+
+ qml/wallet/send/SendPage.qml
+ qml/wallet/send/SendPageDashboard.qml
+ qml/wallet/send/SendPageNavBack.qml
+ qml/wallet/send/SendPagePIN.qml
+ qml/wallet/send/SendPageQR.qml
+ qml/wallet/send/SendPageTransfer.qml
+
+
\ No newline at end of file
diff --git a/src/vr/qml/AboutPage.qml b/src/vr/qml/AboutPage.qml
new file mode 100644
index 0000000..4a4cc2c
--- /dev/null
+++ b/src/vr/qml/AboutPage.qml
@@ -0,0 +1,78 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.2
+
+import "."
+import "common"
+
+ColumnLayout {
+ id: root
+ spacing: 30
+ width: 1600
+ height: 800
+
+ RowLayout {
+ Layout.topMargin: 40
+ Layout.leftMargin: 40
+ Layout.rightMargin: 40
+ Layout.fillWidth: true
+ Layout.preferredHeight: 200
+
+ ColumnLayout {
+ Layout.preferredWidth: 256
+ Layout.maximumWidth: 256
+
+ Image {
+ Layout.preferredHeight: 256
+ Layout.preferredWidth: 256
+
+ source: "qrc:/illuminati"
+ }
+
+
+ }
+
+ ColumnLayout {
+ Layout.preferredWidth: 256
+
+ MyText {
+ Layout.leftMargin: 40
+ Layout.rightMargin: 40
+ Layout.fillWidth: true
+ text: "Wowlet VR is an alternative QML interface for wowlet and was made over a 4 week period by eating lots of pizzas. It is the world's first cryptocurrency wallet with support for VR. Wowlet is Free and open-source (BSD-3) software and the source code can be studied on git.wownero.com/wowlet/wowlet"
+ wrap: true
+ }
+
+
+ }
+ }
+
+ MyText {
+ Layout.leftMargin: 40
+ Layout.rightMargin: 40
+ Layout.fillWidth: true
+ text: "By \"dsc\" - April 2021. Shoutouts: OpenVR-AdvancedSettings, qvqc, Gatto, cisme, wowario, lza_menace, jwinterm, nioc, asymptotically, azy, selsta, kico, laura, thrmo, rottensox, solar, bl4sty, scoobybejesus (sorry if I forgot anyone!)"
+ wrap: true
+ }
+
+ MyPushButton {
+ text: "Back"
+ Layout.leftMargin: 40
+ Layout.preferredWidth: 220
+
+ onClicked: {
+ mainView.pop();
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+
+ function onPageCompleted(previousView){
+
+ }
+}
+
+// OverlayController.exitApp();
diff --git a/src/vr/qml/CreateWalletDialog.qml b/src/vr/qml/CreateWalletDialog.qml
new file mode 100644
index 0000000..9f15dba
--- /dev/null
+++ b/src/vr/qml/CreateWalletDialog.qml
@@ -0,0 +1,12 @@
+// import QtQuick 2.7
+// import QtQuick.Controls 2.0
+// import QtQuick.Layouts 1.2
+// import QtGraphicalEffects 1.0
+// import QtQuick.Window 2.0
+// import QtQuick.Controls.Styles 1.4
+// import QtQuick.Dialogs 1.2
+
+// //import ovrwow.wowletvr 1.0
+
+// import "common"
+
diff --git a/src/vr/qml/DashboardPage.qml b/src/vr/qml/DashboardPage.qml
new file mode 100644
index 0000000..dc93a14
--- /dev/null
+++ b/src/vr/qml/DashboardPage.qml
@@ -0,0 +1,183 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.2
+
+import wowlet.NetworkType 1.0
+import wowlet.WalletKeysFiles 1.0
+
+import "."
+import "common"
+
+ColumnLayout {
+ id: root
+ width: 1600
+ height: 800
+
+ property var walletList: [];
+ property string enteredColor: "#365473"
+ property string exitedColor: "#2c435d"
+ property string pressedColor: "#406288"
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ ColumnLayout {
+ Layout.fillWidth: true
+ Layout.preferredHeight: 128
+ Layout.leftMargin: 40
+ Layout.rightMargin: 40
+
+ RowLayout {
+ MyText {
+ text: "Welcome to Wowlet VR"
+ font.pointSize: 24
+ Layout.leftMargin: 0
+ }
+
+ Item {
+ Layout.fillWidth: true
+ Layout.preferredHeight: 50
+ }
+
+ Rectangle {
+ Layout.preferredWidth: 720
+ Layout.preferredHeight: 50
+ color: "transparent"
+
+ MyText{
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ fontSize: 14
+ text: "Version 0.1 (Qt " + qtRuntimeVersion + ")"
+ }
+ }
+ }
+
+ Rectangle {
+ color: "#cccccc"
+ height: 1
+ Layout.topMargin: 10
+ Layout.fillWidth: true
+ }
+ }
+
+ Flow {
+ id: flow
+ spacing: 20
+ clip: true
+
+ property int itemHeight: 192
+ property int maxRows: 6
+
+ Layout.topMargin: 30
+ Layout.fillWidth: true
+ Layout.leftMargin: 40
+
+
+ Repeater {
+ id: recentList
+ clip: true
+ model: walletList
+
+ delegate: Rectangle {
+ // inherited roles from walletKeysFilesModel:
+ // index, fileName, modified, accessed, path, networktype, address
+ // @TODO: maybe enforce networktype === 0 (mainnet)
+
+ id: item
+ property var currentItem: walletList[index]
+ property bool about: currentItem.hasOwnProperty("about")
+ property bool create: currentItem.hasOwnProperty("create")
+ color: root.enteredColor
+ height: 256
+ width: 256
+
+ Image {
+ width: 182
+ height: 182
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 10
+ source: {
+ if(about) {
+ return "qrc:/hypnotoad";
+ } else if(create) {
+ return "qrc:/wizard";
+ } else {
+ return "qrc:/chest";
+ }
+ }
+ }
+
+ Text {
+ color: "white"
+ text: {
+ if(about) {
+ return "About";
+ } else if(create) {
+ return "Create wallet";
+ } else {
+ return currentItem['fileName'].replace(".keys", "");
+ }
+ }
+ font.pointSize: 14
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ anchors.topMargin: 14
+ anchors.leftMargin: 14
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+
+ onEntered: {
+ parent.color = root.pressedColor
+ }
+ onExited: {
+ parent.color = root.enteredColor;
+ }
+ onClicked: {
+ if(about) {
+ mainView.push(aboutPage);
+ } else if(create) {
+ createWalletDialog.openPopup();
+ } else {
+ appWindow.walletPath = currentItem['path'];
+ ctx.onOpenWallet(currentItem['path'], "");
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+
+ function onPageCompleted(previousView){
+ console.log("list wallets");
+
+ let wallets = [];
+ if(typeof ctx !== 'undefined')
+ wallets = ctx.listWallets();
+
+ let _walletList = [];
+
+ for(var i = 0; i != wallets.length; i++) {
+ if(i == 8) // draw 10 items at any time
+ break;
+ _walletList.push(wallets[i]);
+ }
+
+ _walletList.push({"create": true});
+ _walletList.push({"about": true});
+
+ root.walletList = _walletList;
+ }
+}
+
+// OverlayController.exitApp();
diff --git a/src/vr/qml/WalletPage.qml b/src/vr/qml/WalletPage.qml
new file mode 100755
index 0000000..2ad9604
--- /dev/null
+++ b/src/vr/qml/WalletPage.qml
@@ -0,0 +1,82 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.2
+import QtGraphicalEffects 1.0
+import QtQuick.Window 2.0
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Dialogs 1.2
+
+import "."
+import "common"
+import "wallet"
+import "wallet/send"
+
+
+Rectangle {
+ width: 1600
+ height: 800
+ color: "transparent"
+
+ property WalletDashBoardPage walletDashboardPage: WalletDashBoardPage {
+ stackView: walletView
+ visible: false
+ }
+
+ property SendPage sendPage: SendPage {
+ stackView: walletView
+ visible: false
+ }
+
+ property ReceivePage receivePage: ReceivePage {
+ stackView: walletView
+ visible: false
+ }
+
+ StackView {
+ id: walletView
+ anchors.fill: parent
+
+ pushEnter: Transition {
+ PropertyAnimation {
+ property: "x"
+ from: walletView.width
+ to: 0
+ duration: 300
+ easing.type: Easing.OutCubic
+ }
+ }
+ pushExit: Transition {
+ PropertyAnimation {
+ property: "x"
+ from: 0
+ to: -walletView.width
+ duration: 300
+ easing.type: Easing.OutCubic
+ }
+ }
+ popEnter: Transition {
+ PropertyAnimation {
+ property: "x"
+ from: -walletView.width
+ to: 0
+ duration: 300
+ easing.type: Easing.OutCubic
+ }
+ }
+ popExit: Transition {
+ PropertyAnimation {
+ property: "x"
+ from: 0
+ to: walletView.width
+ duration: 300
+ easing.type: Easing.OutCubic
+ }
+ }
+
+ initialItem: walletDashboardPage
+ }
+
+ function onPageCompleted() {
+ walletDashboardPage.onPageCompleted();
+ }
+}
diff --git a/src/vr/qml/common/FullWidthSliderBox.qml b/src/vr/qml/common/FullWidthSliderBox.qml
new file mode 100755
index 0000000..c8df999
--- /dev/null
+++ b/src/vr/qml/common/FullWidthSliderBox.qml
@@ -0,0 +1,93 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+
+GroupBox {
+ // Public properties
+ // Overload
+ property alias headerMessage: headerText.text
+ property alias sliderText: steamDesktopForwardText.text
+ property alias sliderValue: steamDesktopForwardSlider.value
+ property alias lowerLimit: steamDesktopForwardSlider.from
+ property alias upperLimit: steamDesktopForwardSlider.to
+ property alias kbUID: steamDesktopForwardText.keyBoardUID
+
+
+ function onValueChanged(value) {
+
+ }
+
+ function onComponentComplete() {
+
+ }
+
+
+ // Private properties
+ id: sliderBox
+ Layout.fillWidth: true
+ label: MyText {
+ id: headerText
+ leftPadding: 10
+ text: "MISSING HEADER TEXT"
+ bottomPadding: -10
+ }
+ background: Rectangle {
+ color: "transparent"
+ border.color: "#ffffff"
+ radius: 8
+ }
+
+ property real sliderStepSize: 0.10
+ readonly property real rightLeftLimit: 4.0
+
+ ColumnLayout {
+ anchors.fill: parent
+
+ LineSeparator {
+ }
+
+ ColumnLayout {
+ RowLayout {
+ MyPushButton2 {
+ Layout.preferredWidth: 40
+ text: "-"
+ onClicked: {
+ steamDesktopForwardSlider.value -= sliderStepSize
+ }
+ }
+
+ MySlider {
+ id: steamDesktopForwardSlider
+ from: -rightLeftLimit
+ to: rightLeftLimit
+ stepSize: sliderStepSize
+ Layout.fillWidth: true
+ onValueChanged: {
+ sliderBox.onValueChanged(this.value)
+ }
+ }
+
+ MyPushButton2 {
+ Layout.preferredWidth: 40
+ text: "+"
+ onClicked: {
+ steamDesktopForwardSlider.value += sliderStepSize
+ }
+ }
+
+ MyTextField {
+ id: steamDesktopForwardText
+ text: "0.0"
+ keyBoardUID: 611
+ Layout.preferredWidth: 100
+ Layout.leftMargin: 10
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+ }
+ }
+ Component.onCompleted: {
+ sliderBox.onComponentComplete()
+ }
+}
diff --git a/src/vr/qml/common/HourComboBox.qml b/src/vr/qml/common/HourComboBox.qml
new file mode 100755
index 0000000..8d7655b
--- /dev/null
+++ b/src/vr/qml/common/HourComboBox.qml
@@ -0,0 +1,49 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+
+MyComboBox {
+
+ model: [
+ { value: 0, text: "00" },
+ { value: 1, text: "01" },
+ { value: 2, text: "02" },
+ { value: 3, text: "03" },
+ { value: 4, text: "04" },
+ { value: 5, text: "05" },
+ { value: 6, text: "06" },
+ { value: 7, text: "07" },
+ { value: 8, text: "08" },
+ { value: 9, text: "09" },
+ { value: 10, text: "10" },
+ { value: 11, text: "11" },
+ { value: 12, text: "12" },
+ { value: 13, text: "13" },
+ { value: 14, text: "14" },
+ { value: 15, text: "15" },
+ { value: 16, text: "16" },
+ { value: 17, text: "17" },
+ { value: 18, text: "18" },
+ { value: 19, text: "19" },
+ { value: 20, text: "20" },
+ { value: 21, text: "21" },
+ { value: 22, text: "22" },
+ { value: 23, text: "23" },
+ ]
+
+ delegate: ItemDelegate {
+ width: parent.width
+ text: modelData.text
+ hoverEnabled: true
+ contentItem: MyText {
+ horizontalAlignment: Text.AlignLeft
+ verticalAlignment: Text.AlignVCenter
+ text: parent.text
+ color: parent.enabled ? "#ffffff" : "#909090"
+ }
+ background: Rectangle {
+ color: parent.pressed ? "#406288" : (parent.hovered ? "#365473" : "#2c435d")
+ }
+ }
+}
diff --git a/src/vr/qml/common/LineSeparator.qml b/src/vr/qml/common/LineSeparator.qml
new file mode 100755
index 0000000..13656cf
--- /dev/null
+++ b/src/vr/qml/common/LineSeparator.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+// Necessary for the project specific Components.
+import ".."
+
+// Insert inside a ColumnLayout containing this and a RowLayout
+// to neatly separate header and buttons.
+Rectangle {
+ color: "#ffffff"
+ height: 1
+ Layout.fillWidth: true
+ Layout.bottomMargin: 5
+}
diff --git a/src/vr/qml/common/MinuteSecondComboBox.qml b/src/vr/qml/common/MinuteSecondComboBox.qml
new file mode 100755
index 0000000..786282f
--- /dev/null
+++ b/src/vr/qml/common/MinuteSecondComboBox.qml
@@ -0,0 +1,85 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+
+MyComboBox {
+
+ model: [
+ { value: 0, text: "00" },
+ { value: 1, text: "01" },
+ { value: 2, text: "02" },
+ { value: 3, text: "03" },
+ { value: 4, text: "04" },
+ { value: 5, text: "05" },
+ { value: 6, text: "06" },
+ { value: 7, text: "07" },
+ { value: 8, text: "08" },
+ { value: 9, text: "09" },
+ { value: 10, text: "10" },
+ { value: 11, text: "11" },
+ { value: 12, text: "12" },
+ { value: 13, text: "13" },
+ { value: 14, text: "14" },
+ { value: 15, text: "15" },
+ { value: 16, text: "16" },
+ { value: 17, text: "17" },
+ { value: 18, text: "18" },
+ { value: 19, text: "19" },
+ { value: 20, text: "20" },
+ { value: 21, text: "21" },
+ { value: 22, text: "22" },
+ { value: 23, text: "23" },
+ { value: 24, text: "24" },
+ { value: 25, text: "25" },
+ { value: 26, text: "26" },
+ { value: 27, text: "27" },
+ { value: 28, text: "28" },
+ { value: 29, text: "29" },
+ { value: 30, text: "30" },
+ { value: 31, text: "31" },
+ { value: 32, text: "32" },
+ { value: 33, text: "33" },
+ { value: 34, text: "34" },
+ { value: 35, text: "35" },
+ { value: 36, text: "36" },
+ { value: 37, text: "37" },
+ { value: 38, text: "38" },
+ { value: 39, text: "39" },
+ { value: 40, text: "40" },
+ { value: 41, text: "41" },
+ { value: 42, text: "42" },
+ { value: 43, text: "43" },
+ { value: 44, text: "44" },
+ { value: 45, text: "45" },
+ { value: 46, text: "46" },
+ { value: 47, text: "47" },
+ { value: 48, text: "48" },
+ { value: 49, text: "49" },
+ { value: 50, text: "50" },
+ { value: 51, text: "51" },
+ { value: 52, text: "52" },
+ { value: 53, text: "53" },
+ { value: 54, text: "54" },
+ { value: 55, text: "55" },
+ { value: 56, text: "56" },
+ { value: 57, text: "57" },
+ { value: 58, text: "58" },
+ { value: 59, text: "59" }
+ ]
+
+ delegate: ItemDelegate {
+ width: parent.width
+ text: modelData.text
+ hoverEnabled: true
+ contentItem: MyText {
+ horizontalAlignment: Text.AlignLeft
+ verticalAlignment: Text.AlignVCenter
+ text: parent.text
+ color: parent.enabled ? "#ffffff" : "#909090"
+ }
+ background: Rectangle {
+ color: parent.pressed ? "#406288" : (parent.hovered ? "#365473" : "#2c435d")
+ }
+ }
+}
diff --git a/src/vr/qml/common/MyComboBox.qml b/src/vr/qml/common/MyComboBox.qml
new file mode 100755
index 0000000..d9b915e
--- /dev/null
+++ b/src/vr/qml/common/MyComboBox.qml
@@ -0,0 +1,73 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import "." // QTBUG-34418, singletons require explicit import to load qmldir file
+
+
+ComboBox {
+ id: myComboBox
+ hoverEnabled: true
+ background: Rectangle {
+ color: parent.pressed ? "#406288" : (parent.activeFocus ? "#365473" : "#2c435d")
+ }
+
+ contentItem: MyText {
+ leftPadding: 0
+ rightPadding: parent.indicator.width + parent.spacing
+ text: parent.displayText
+ horizontalAlignment: Text.AlignLeft
+ verticalAlignment: Text.AlignVCenter
+ elide: Text.ElideRight
+ }
+
+ delegate: ItemDelegate {
+ width: myComboBox.width
+ text: modelData
+ hoverEnabled: true
+ contentItem: MyText {
+ horizontalAlignment: Text.AlignLeft
+ verticalAlignment: Text.AlignVCenter
+ text: parent.text
+ color: parent.enabled ? "#ffffff" : "#909090"
+ }
+ background: Rectangle {
+ color: parent.pressed ? "#406288" : (parent.hovered ? "#365473" : "#2c435d")
+ }
+ }
+
+ indicator: Canvas {
+ x: parent.width - width - parent.rightPadding
+ y: parent.topPadding + (parent.availableHeight - height) / 2
+ width: 13
+ height: 7
+ contextType: "2d"
+
+ onPaint: {
+ if (!context) {
+ getContext("2d")
+ }
+ context.reset();
+ context.lineWidth = 2
+ context.moveTo(1, 1);
+ context.lineTo(Math.ceil(width / 2), height - 1);
+ context.lineTo(width - 1, 1);
+ context.strokeStyle = "#ffffff"
+ context.stroke()
+ }
+ }
+
+ onHoveredChanged: {
+ if (hovered) {
+ forceActiveFocus()
+ }
+ }
+
+ onActivated: {
+ if (activeFocus) {
+ MyResources.playActivationSound()
+ }
+ }
+
+ Component.onCompleted: {
+ popup.background.color = "#2c435d"
+ }
+}
diff --git a/src/vr/qml/common/MyDialogOkCancelPopup.qml b/src/vr/qml/common/MyDialogOkCancelPopup.qml
new file mode 100755
index 0000000..6540e79
--- /dev/null
+++ b/src/vr/qml/common/MyDialogOkCancelPopup.qml
@@ -0,0 +1,99 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+Popup {
+ id: myDialogPopup
+
+ implicitHeight: parent.height
+ implicitWidth: parent.width
+
+ property string dialogTitle: ""
+ property string dialogText: ""
+ property int dialogWidth: 600
+ property int dialogHeight: 300
+
+ property Item dialogContentItem: MyText {
+ text: dialogText
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ Layout.fillWidth: true
+ }
+
+ property bool okClicked: false
+
+ closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
+
+ background: Rectangle {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ color: "black"
+ opacity: 0.8
+ }
+
+ contentItem: Item {
+ Rectangle {
+ implicitWidth: dialogWidth
+ implicitHeight: dialogHeight
+ anchors.centerIn: parent
+ radius: 24
+ color: "#1b2939"
+ border.color: "#cccccc"
+ border.width: 2
+ ColumnLayout {
+ anchors.fill: parent
+ anchors.margins: 12
+ MyText {
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ text: dialogTitle
+ }
+ Rectangle {
+ color: "#cccccc"
+ height: 1
+ Layout.fillWidth: true
+ }
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ ColumnLayout {
+ id: dialogContent
+ }
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.leftMargin: 24
+ Layout.rightMargin: 24
+ Layout.bottomMargin: 12
+ MyPushButton {
+ implicitWidth: 200
+ text: "Ok"
+ onClicked: {
+ okClicked = true
+ myDialogPopup.close()
+ }
+ }
+ Item {
+ Layout.fillWidth: true
+ }
+ MyPushButton {
+ implicitWidth: 200
+ text: "Cancel"
+ onClicked: {
+ okClicked = false
+ myDialogPopup.close()
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ dialogContentItem.parent = dialogContent
+ }
+}
diff --git a/src/vr/qml/common/MyDialogOkPopup.qml b/src/vr/qml/common/MyDialogOkPopup.qml
new file mode 100755
index 0000000..3865952
--- /dev/null
+++ b/src/vr/qml/common/MyDialogOkPopup.qml
@@ -0,0 +1,93 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+Popup {
+ id: myDialogPopup
+
+ implicitHeight: parent.height
+ implicitWidth: parent.width
+
+ property string dialogTitle: ""
+ property string dialogText: ""
+ property int dialogWidth: 800
+ property int dialogHeight: 300
+
+ property Item dialogContentItem: MyText {
+ fontSize:16
+ text: dialogText
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ Layout.fillWidth: true
+ }
+
+ property bool okClicked: false
+
+ closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
+
+ background: Rectangle {
+ color: "black"
+ opacity: 0.8
+ }
+
+ contentItem: Item {
+ Rectangle {
+ implicitWidth: dialogWidth
+ implicitHeight: dialogHeight
+ anchors.centerIn: parent
+ radius: 24
+ color: "#1b2939"
+ border.color: "#cccccc"
+ border.width: 2
+ ColumnLayout {
+ anchors.fill: parent
+ anchors.margins: 12
+ MyText {
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ text: dialogTitle
+ }
+ Rectangle {
+ color: "#cccccc"
+ height: 1
+ Layout.fillWidth: true
+ }
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ ColumnLayout {
+ id: dialogContent
+ }
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.leftMargin: 24
+ Layout.rightMargin: 24
+ Layout.bottomMargin: 12
+ Item {
+ Layout.fillWidth: true
+ }
+ MyPushButton {
+ implicitWidth: 200
+ text: "Ok"
+ onClicked: {
+ okClicked = true
+ myDialogPopup.close()
+ }
+ }
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ dialogContentItem.parent = dialogContent
+ }
+}
diff --git a/src/vr/qml/common/MyNumPad.qml b/src/vr/qml/common/MyNumPad.qml
new file mode 100644
index 0000000..84af802
--- /dev/null
+++ b/src/vr/qml/common/MyNumPad.qml
@@ -0,0 +1,136 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+import "."
+
+ColumnLayout {
+ id: root
+ enabled: true
+
+ property double disabledOpacity: 0.4
+ property var code: [];
+
+ signal resolvePressed();
+ signal codeUpdated(var pin_code);
+
+ function onButtonPress(val) {
+ code.push(val);
+
+ if(code.length === 5)
+ code = [val];
+
+ codeUpdated(code);
+ }
+
+ function reset() {
+ root.code = [];
+ }
+
+ RowLayout {
+ spacing: 20
+
+ MyNumPadButton {
+ opacity: root.enabled ? 1 : disabledOpacity
+ text: "1"
+ onClicked: {
+ onButtonPress("1");
+ }
+ }
+
+ MyNumPadButton {
+ opacity: root.enabled ? 1 : disabledOpacity
+ text: "2"
+ onClicked: {
+ onButtonPress("2");
+ }
+ }
+
+ MyNumPadButton {
+ opacity: root.enabled ? 1 : disabledOpacity
+ text: "3"
+ onClicked: {
+ onButtonPress("3");
+ }
+ }
+ }
+
+ RowLayout {
+ spacing: 20
+
+ MyNumPadButton {
+ opacity: root.enabled ? 1 : disabledOpacity
+ text: "4"
+ onClicked: {
+ onButtonPress("4");
+ }
+ }
+
+ MyNumPadButton {
+ opacity: root.enabled ? 1 : disabledOpacity
+ text: "5"
+ onClicked: {
+ onButtonPress("5");
+ }
+ }
+
+ MyNumPadButton {
+ opacity: root.enabled ? 1 : disabledOpacity
+ text: "6"
+ onClicked: {
+ onButtonPress("6");
+ }
+ }
+ }
+
+ RowLayout {
+ spacing: 20
+
+ MyNumPadButton {
+ opacity: root.enabled ? 1 : disabledOpacity
+ text: "7"
+ onClicked: {
+ onButtonPress("7");
+ }
+ }
+
+ MyNumPadButton {
+ opacity: root.enabled ? 1 : disabledOpacity
+ text: "8"
+ onClicked: {
+ onButtonPress("8");
+ }
+ }
+
+ MyNumPadButton {
+ opacity: root.enabled ? 1 : disabledOpacity
+ text: "9"
+ onClicked: {
+ onButtonPress("9");
+ }
+ }
+ }
+
+ RowLayout {
+ spacing: 20
+
+ MyNumPadButton {
+ opacity: root.enabled ? 1 : disabledOpacity
+ text: "0"
+ onClicked: {
+ onButtonPress("0");
+ }
+ }
+
+ MyNumPadButton {
+ opacity: root.enabled ? 1 : disabledOpacity
+
+ Layout.preferredWidth: 204
+ fontSize: 16
+ text: "Clear"
+ onClicked: {
+ root.code = [0,0,0,0];
+ root.codeUpdated(root.code);
+ }
+ }
+ }
+}
diff --git a/src/vr/qml/common/MyNumPadButton.qml b/src/vr/qml/common/MyNumPadButton.qml
new file mode 100644
index 0000000..8a7fac2
--- /dev/null
+++ b/src/vr/qml/common/MyNumPadButton.qml
@@ -0,0 +1,40 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+Rectangle {
+ id: root
+ property string text: ""
+ property int fontSize: 22
+ property string enteredColor: "#365473"
+ property string exitedColor: "#2c435d"
+ property string pressedColor: "#406288"
+ property alias mouseArea: mouseArea
+
+ signal clicked;
+
+ Layout.preferredWidth: 92
+ Layout.preferredHeight: 92
+ color: root.exitedColor
+
+ MyText {
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ color: "white"
+ text: root.text
+ fontSize: root.fontSize
+ fontBold: true
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onEntered: parent.color = root.enteredColor
+ onExited: parent.color = root.exitedColor
+ onPressed: parent.color = root.pressedColor
+ onClicked: {
+ root.clicked();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/vr/qml/common/MyNumPadSendAmount.qml b/src/vr/qml/common/MyNumPadSendAmount.qml
new file mode 100644
index 0000000..ede542b
--- /dev/null
+++ b/src/vr/qml/common/MyNumPadSendAmount.qml
@@ -0,0 +1,172 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+import "."
+
+RowLayout {
+ id: root
+ property double amount: 0.0;
+ property bool add: true;
+
+ property string enteredColor: "#365473"
+ property string exitedColor: "#2c435d"
+ property string pressedColor: "#406288"
+
+ signal amountUpdated(double amount);
+
+ spacing: 24
+
+ function reset() {
+ root.amount = 0.0;
+ }
+
+ MyNumPadButton {
+ id: minButton
+ mouseArea.enabled: false
+ fontSize: 18
+
+ Layout.preferredWidth: 128
+ Layout.preferredHeight: 112
+
+ color: root.add ? root.exitedColor : root.enteredColor
+
+ text: "-"
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ onEntered: {
+ if(!root.add) return;
+ parent.color = root.enteredColor
+ }
+ onExited: {
+ if(!root.add) return;
+ parent.color = root.exitedColor
+ }
+ onClicked: {
+ root.add = false;
+ plusButton.color = root.exitedColor
+ }
+ }
+ }
+
+ MyNumPadButton {
+ id: plusButton
+ mouseArea.enabled: false
+ fontSize: 18
+
+ Layout.preferredWidth: 128
+ Layout.preferredHeight: 112
+
+ color: root.add ? root.enteredColor : root.exitedColor
+
+ text: "+"
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ onEntered: {
+ if(root.add) return;
+ parent.color = root.enteredColor
+ }
+ onExited: {
+ if(root.add) return;
+ parent.color = root.exitedColor
+ }
+ onClicked: {
+ root.add = true;
+ minButton.color = root.exitedColor
+ }
+ }
+ }
+
+ Rectangle {
+ color: "#cccccc"
+ width: 1
+ Layout.fillHeight: true
+ }
+
+ MyNumPadButton {
+ fontSize: 18
+ Layout.preferredWidth: 180
+ Layout.preferredHeight: 112
+ text: "0.001"
+ onClicked: {
+ root.add ? root.amount += 0.001 : root.amount -= 0.001;
+ if(root.amount <= 0.0) root.amount = 0.0;
+ amountUpdated(root.amount);
+ }
+ }
+
+ MyNumPadButton {
+ fontSize: 18
+ Layout.preferredWidth: 148
+ Layout.preferredHeight: 112
+ text: "0.01"
+ onClicked: {
+ root.add ? root.amount += 0.01 : root.amount -= 0.01;
+ if(root.amount <= 0.0) root.amount = 0.0;
+ amountUpdated(root.amount);
+ }
+ }
+
+ MyNumPadButton {
+ fontSize: 18
+ Layout.preferredWidth: 128
+ Layout.preferredHeight: 112
+ text: "0.1"
+ onClicked: {
+ root.add ? root.amount += 0.1 : root.amount -= 0.1;
+ if(root.amount <= 0.0) root.amount = 0.0;
+ amountUpdated(root.amount);
+ }
+ }
+
+ MyNumPadButton {
+ fontSize: 18
+ Layout.preferredWidth: 128
+ Layout.preferredHeight: 112
+ text: "1"
+ onClicked: {
+ root.add ? root.amount += 1.0 : root.amount -= 1.0;
+ if(root.amount <= 0.0) root.amount = 0.0;
+ amountUpdated(root.amount);
+ }
+ }
+
+ MyNumPadButton {
+ fontSize: 18
+ Layout.preferredWidth: 168
+ Layout.preferredHeight: 112
+ text: "10"
+ onClicked: {
+ root.add ? root.amount += 10.0 : root.amount -= 10.0;
+ if(root.amount <= 0.0) root.amount = 0.0;
+ amountUpdated(root.amount);
+ }
+ }
+
+ MyNumPadButton {
+ fontSize: 18
+ Layout.preferredWidth: 128
+ Layout.preferredHeight: 112
+ text: "100"
+ onClicked: {
+ root.add ? root.amount += 100.0 : root.amount -= 100.0;
+ if(root.amount <= 0.0) root.amount = 0.0;
+ amountUpdated(root.amount);
+ }
+ }
+
+ MyNumPadButton {
+ fontSize: 18
+ Layout.preferredWidth: 168
+ Layout.preferredHeight: 112
+ text: "1000"
+ onClicked: {
+ root.add ? root.amount += 1000.0 : root.amount -= 1000.0;
+ if(root.amount <= 0.0) root.amount = 0.0;
+ amountUpdated(root.amount);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/vr/qml/common/MyPushButton.qml b/src/vr/qml/common/MyPushButton.qml
new file mode 100755
index 0000000..be9d4b7
--- /dev/null
+++ b/src/vr/qml/common/MyPushButton.qml
@@ -0,0 +1,62 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.2
+import "." // QTBUG-34418, singletons require explicit import to load qmldir file
+
+Item {
+ id: root
+ property string text: "testy"
+ property string iconPath: ""
+ property bool hasIcon: iconPath !== ""
+ property bool hoverEnabled: true
+ property bool activationSoundEnabled: true
+ property string enteredColor: "#365473"
+ property string exitedColor: "#2c435d"
+ property string pressedColor: "#406288"
+ signal clicked;
+
+ Layout.preferredHeight: 70
+
+ RowLayout {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ Layout.minimumHeight: 54
+
+ Image {
+ visible: hasIcon
+ source: iconPath
+ Layout.leftMargin: 20
+ Layout.rightMargin: 20
+ Layout.preferredWidth: 32
+ Layout.preferredHeight: 32
+ }
+
+ MyText {
+ Layout.leftMargin: root.hasIcon ? 0 : 20
+ Layout.rightMargin: root.hasIcon ? 0 : 20
+ Layout.fillWidth: root.hasIcon ? true : false
+ Layout.alignment: root.hasIcon ? Qt.AlignLeft : Qt.AlignHCenter
+ text: root.text
+ fontSize: 16
+ }
+ }
+
+ Rectangle {
+ z: root.z - 1
+ anchors.fill: root
+ Layout.fillWidth: root.Layout.fillWidth
+ color: root.down ? root.pressedColor : (root.activeFocus ? root.enteredColor : root.exitedColor)
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ onEntered: parent.color = root.enteredColor
+ onExited: parent.color = root.exitedColor
+ onPressed: parent.color = root.pressedColor
+ onClicked: {
+ root.clicked();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/vr/qml/common/MyPushButton2.qml b/src/vr/qml/common/MyPushButton2.qml
new file mode 100755
index 0000000..31da025
--- /dev/null
+++ b/src/vr/qml/common/MyPushButton2.qml
@@ -0,0 +1,29 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import "." // QTBUG-34418, singletons require explicit import to load qmldir file
+
+Button {
+ hoverEnabled: true
+ contentItem: MyText {
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ text: parent.text
+ color: parent.enabled ? "#ffffff" : "#909090"
+ }
+ background: Rectangle {
+ color: parent.down ? "#406288" : (parent.activeFocus ? "#365473" : "transparent")
+ border.color: parent.enabled ? "#ffffff" : "#909090"
+ radius: 8
+ }
+ onHoveredChanged: {
+ if (hovered) {
+ forceActiveFocus()
+ } else {
+ focus = false
+ }
+ }
+
+ onClicked: {
+ MyResources.playActivationSound()
+ }
+}
diff --git a/src/vr/qml/common/MyRadioButton.qml b/src/vr/qml/common/MyRadioButton.qml
new file mode 100755
index 0000000..8ffa650
--- /dev/null
+++ b/src/vr/qml/common/MyRadioButton.qml
@@ -0,0 +1,24 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import "." // QTBUG-34418, singletons require explicit import to load qmldir file
+
+RadioButton {
+ hoverEnabled: true
+ contentItem: MyText {
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ text: parent.text
+ color: parent.enabled ? "#ffffff" : "#909090"
+ }
+ onHoveredChanged: {
+ if (hovered) {
+ forceActiveFocus()
+ } else {
+ focus = false
+ }
+ }
+
+ onClicked: {
+ MyResources.playActivationSound()
+ }
+}
diff --git a/src/vr/qml/common/MyResources.qml b/src/vr/qml/common/MyResources.qml
new file mode 100755
index 0000000..31cf903
--- /dev/null
+++ b/src/vr/qml/common/MyResources.qml
@@ -0,0 +1,12 @@
+pragma Singleton
+import QtQuick 2.7
+
+
+QtObject {
+ function playActivationSound() {
+ OverlayController.playActivationSound()
+ }
+ function playFocusChangedSound() {
+ OverlayController.playFocusChangedSound()
+ }
+}
diff --git a/src/vr/qml/common/MySlider.qml b/src/vr/qml/common/MySlider.qml
new file mode 100755
index 0000000..797de79
--- /dev/null
+++ b/src/vr/qml/common/MySlider.qml
@@ -0,0 +1,54 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import "." // QTBUG-34418, singletons require explicit import to load qmldir file
+
+
+
+Slider {
+ snapMode: Slider.SnapAlways
+ wheelEnabled: true
+ hoverEnabled: true
+ to: 1.0
+ from: 0.0
+
+ background: Rectangle {
+ x: parent.leftPadding
+ y: parent.topPadding + parent.availableHeight / 2 - height / 2
+ width: parent.availableWidth
+ height: parent.availableHeight
+ radius: 2
+ color: parent.activeFocus ? "#2c435d" : "#1b2939"
+ Rectangle {
+ y: parent.height / 2 - height / 2
+ implicitHeight: 4
+ width: parent.width
+ height: implicitHeight
+ radius: 2
+ color: "#bdbebf"
+ }
+ }
+
+ handle: Rectangle {
+ x: parent.leftPadding + parent.visualPosition * (parent.availableWidth - width)
+ y: parent.topPadding + parent.availableHeight / 2 - height / 2
+ implicitWidth: 20
+ implicitHeight: 40
+ radius: 4
+ color: parent.pressed ? "#ffffff" : "#eeeeee"
+ border.color: "#bdbebf"
+ }
+
+ onHoveredChanged: {
+ if (hovered) {
+ forceActiveFocus()
+ } else {
+ focus = false
+ }
+ }
+
+ onValueChanged: {
+ if (activeFocus) {
+ //MyResources.playActivationSound()
+ }
+ }
+}
diff --git a/src/vr/qml/common/MyStackViewPage.qml b/src/vr/qml/common/MyStackViewPage.qml
new file mode 100755
index 0000000..fad7c5c
--- /dev/null
+++ b/src/vr/qml/common/MyStackViewPage.qml
@@ -0,0 +1,275 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.2
+
+import "."
+import ".."
+
+import wowlet.Wallet 1.0
+
+
+Rectangle {
+ color: "#1b2939"
+ width: 1600
+ height: 800
+
+ property StackView stackView
+ property string headerText: "Header Title"
+ property bool headerShowBackButton: true
+
+ signal backClicked();
+
+ property Item header: ColumnLayout {
+ RowLayout {
+ Button {
+ id: headerBackButton
+ Layout.preferredHeight: 50
+ Layout.preferredWidth: 50
+ hoverEnabled: true
+ enabled: headerShowBackButton
+ visible: headerShowBackButton
+ contentItem: Image {
+ source: "qrc:/backarrow"
+ sourceSize.width: 50
+ sourceSize.height: 50
+ anchors.fill: parent
+ }
+ background: Rectangle {
+ opacity: parent.down ? 1.0 : (parent.activeFocus ? 0.5 : 0.0)
+ color: "#406288"
+ radius: 4
+ anchors.fill: parent
+ }
+ onHoveredChanged: {
+ if (hovered) {
+ forceActiveFocus()
+ } else {
+ focus = false
+ }
+ }
+ onClicked: {
+ backClicked();
+ stackView.pop();
+ }
+ }
+ MyText {
+ id: headerTitle
+ text: headerText
+ font.pointSize: 30
+ Layout.leftMargin: headerShowBackButton ? 32 : 0
+ }
+
+ Item {
+ Layout.fillWidth: true
+ Layout.preferredHeight: 50
+ }
+
+ Rectangle {
+ Layout.preferredWidth: 720
+ Layout.preferredHeight: 50
+ color: "transparent"
+
+ MyText{
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ fontSize: 14
+ fontBold: true
+ text: appWindow.balanceFormatted
+ }
+ }
+ }
+
+ Rectangle {
+ color: "#cccccc"
+ height: 1
+ Layout.topMargin: 10
+ Layout.fillWidth: true
+ }
+ }
+
+ property Item content: Frame {
+ MyText {
+ text: "Content"
+ }
+ }
+
+ ColumnLayout {
+ id: mainLayout
+ spacing: 12
+ anchors.fill: parent
+ }
+
+ Rectangle {
+ id: testy66
+ color: "transparent"
+
+ Layout.fillWidth: true
+ Layout.preferredHeight: 64
+
+ Rectangle {
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ anchors.leftMargin: 40
+ anchors.rightMargin: 40
+
+ color: "#cccccc"
+ height: 1
+ }
+
+ RowLayout {
+ spacing: 30
+ anchors.verticalCenter: parent.verticalCenter
+
+ Layout.preferredHeight: 64
+ Layout.fillWidth: true
+
+ MyText {
+ Layout.leftMargin: 40
+
+ fontSize: 14
+ text: appWindow.statusText
+ color: "#cccccc"
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.preferredWidth: 1
+ color: "#cccccc"
+ }
+
+ RowLayout {
+ Layout.fillHeight: true
+ spacing: 0
+
+ MyText {
+ fontSize: 14
+ text: "Daemon: "
+ color: "#cccccc"
+ }
+
+ Image {
+ opacity: 0.8
+ Layout.preferredWidth: 32
+ Layout.preferredHeight: 32
+ source: {
+ if(typeof Wallet == 'undefined')
+ return "qrc:/status_disconnected";
+
+ if(appWindow.connectionStatus == Wallet.ConnectionStatus_Connected){
+ return "qrc:/status_connected";
+ } else if(appWindow.connectionStatus == Wallet.ConnectionStatus_Connecting) {
+ return "qrc:/status_lagging";
+ } else {
+ return "qrc:/status_disconnected";
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.preferredWidth: 1
+ color: "#cccccc"
+ }
+
+ RowLayout {
+ Layout.fillHeight: true
+ spacing: 0
+
+ MyText {
+ fontSize: 14
+ text: "WS: "
+ color: "#cccccc"
+ }
+
+ Image {
+ opacity: 0.8
+ Layout.preferredWidth: 32
+ Layout.preferredHeight: 32
+ source: appWindow.wsConnected ? "qrc:/status_connected" : "qrc:/status_disconnected"
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.preferredWidth: 1
+ color: "#cccccc"
+ }
+
+ MyText {
+ fontSize: 14
+ text: "Fiat: $0.05 USD"
+ color: "#cccccc"
+ }
+ }
+ }
+
+ // Rectangle {
+ // z: 100
+ // color: "black"
+ // height: 64
+
+ // // anchors.bottom: parent.bottom
+ // // anchors.left: parent.left
+ // // anchors.right: parent.right
+
+ // Rectangle {
+ // anchors.top: parent.top
+ // anchors.left: parent.left
+ // anchors.right: parent.right
+
+ // anchors.leftMargin: 40
+ // anchors.rightMargin: 40
+
+ // color: "#cccccc"
+ // height: 1
+ // }
+
+ // RowLayout {
+ // spacing: 30
+ // anchors.left: parent.left
+ // anchors.leftMargin: 40
+ // anchors.rightMargin: 40
+ // anchors.verticalCenter: parent.verticalCenter
+
+ // MyText {
+ // fontSize: 14
+ // text: "Status: idle"
+ // }
+
+ // MyText {
+ // fontSize: 14
+ // text: "WS: OK"
+ // }
+
+ // MyText {
+ // fontSize: 14
+ // text: "Tor: OK"
+ // }
+
+ // MyText {
+ // fontSize: 14
+ // text: "Height: OK"
+ // }
+ // }
+ // }
+
+ Component.onCompleted: {
+ header.parent = mainLayout
+ header.Layout.leftMargin = 40
+ header.Layout.topMargin = 30
+ header.Layout.rightMargin = 40
+ content.parent = mainLayout
+ content.Layout.fillHeight = true
+ content.Layout.fillWidth = true
+
+ content.Layout.topMargin = 10
+ content.Layout.leftMargin = 40
+ content.Layout.rightMargin = 40
+ content.Layout.bottomMargin = 40
+
+ testy66.parent = mainLayout
+ }
+}
diff --git a/src/vr/qml/common/MyText.qml b/src/vr/qml/common/MyText.qml
new file mode 100755
index 0000000..4dc92a7
--- /dev/null
+++ b/src/vr/qml/common/MyText.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+
+
+Text {
+ property bool wrap: false
+ property int fontSize: 16
+ property bool fontBold: false
+ property string fontColor: "#ffffff"
+
+ color: fontColor
+ font.bold: fontBold
+ font.pointSize: fontSize
+ wrapMode: wrap ? Text.WordWrap : Text.NoWrap
+}
diff --git a/src/vr/qml/common/MyTextField.qml b/src/vr/qml/common/MyTextField.qml
new file mode 100755
index 0000000..fd1bb5a
--- /dev/null
+++ b/src/vr/qml/common/MyTextField.qml
@@ -0,0 +1,42 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+
+TextField {
+ property int keyBoardUID: 0
+ property string savedText: ""
+ property bool passwordField: false
+
+ id: myTextField
+ echoMode: passwordField ? TextInput.Password : TextInput.Normal
+ color: "#cccccc"
+ text: ""
+ font.pointSize: 20
+ background: Button {
+ hoverEnabled: true
+ background: Rectangle {
+ color: parent.hovered ? "#2c435d" : "#1b2939"
+ border.color: "#cccccc"
+ border.width: 2
+ }
+ onClicked: {
+ myTextField.forceActiveFocus()
+ }
+ }
+ onActiveFocusChanged: {
+ if (activeFocus) {
+ if (!OverlayController.desktopMode) {
+ OverlayController.showKeyboard(text, keyBoardUID)
+ } else {
+ savedText = text
+ }
+ }
+ }
+ onEditingFinished: {
+ if (OverlayController.desktopMode && savedText !== text) {
+ myTextField.onInputEvent(text)
+ }
+ }
+ function onInputEvent(input) {
+ text = input
+ }
+}
diff --git a/src/vr/qml/common/MyToggleButton.qml b/src/vr/qml/common/MyToggleButton.qml
new file mode 100755
index 0000000..3f50afb
--- /dev/null
+++ b/src/vr/qml/common/MyToggleButton.qml
@@ -0,0 +1,65 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import "." // QTBUG-34418, singletons require explicit import to load qmldir file
+// Needed for MyResources in the default folder.
+import ".."
+
+CheckBox {
+ checkState: Qt.Checked
+ tristate: false
+ hoverEnabled: true
+ spacing: 12
+
+ indicator: Rectangle {
+ implicitWidth: 28
+ implicitHeight: 28
+ x: parent.leftPadding
+ y: parent.height / 2 - height / 2
+ color: parent.enabled ? (parent.down ? "#e0e0e0" : "#ffffff") : "#a0a0a0"
+ border.width: 0
+ Path {
+ startX: 0
+ startY: 0
+ PathLine {
+ x: 40
+ y: 40
+ }
+ }
+
+ Image {
+ width: 28
+ height: 28
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+ source: "qrc:/box_checkmark"
+ sourceSize.width: width
+ sourceSize.height: height
+ visible: parent.parent.checked
+ }
+ }
+
+ contentItem: MyText {
+ text: parent.text
+ horizontalAlignment: Text.AlignLeft
+ verticalAlignment: Text.AlignVCenter
+ leftPadding: parent.indicator.width + parent.spacing
+ color: parent.enabled ? "#ffffff" : "#909090"
+ }
+
+ background: Rectangle {
+ color: "#2c435d"
+ opacity: parent.activeFocus ? 1.0 : 0
+ }
+
+ onHoveredChanged: {
+ if (hovered) {
+ forceActiveFocus()
+ } else {
+ focus = false
+ }
+ }
+
+ onClicked: {
+ MyResources.playActivationSound()
+ }
+}
diff --git a/src/vr/qml/common/TimeAssembly.qml b/src/vr/qml/common/TimeAssembly.qml
new file mode 100755
index 0000000..087955b
--- /dev/null
+++ b/src/vr/qml/common/TimeAssembly.qml
@@ -0,0 +1,55 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+
+RowLayout {
+ signal timeChanged(int hour, int minute, int second)
+
+ HourComboBox {
+ id: hourBox
+ Layout.preferredWidth: 60
+ onActivated: {
+ parent.timeChanged(hourBox.currentIndex,
+ minuteBox.currentIndex,
+ secondBox.currentIndex)
+ }
+ }
+ MyText {
+ text: "h"
+ }
+
+ MinuteSecondComboBox {
+ id: minuteBox
+ Layout.preferredWidth: 60
+ onActivated: {
+ parent.timeChanged(hourBox.currentIndex,
+ minuteBox.currentIndex,
+ secondBox.currentIndex)
+ }
+ }
+ MyText {
+ text: "m"
+ }
+
+ MinuteSecondComboBox {
+ id: secondBox
+ Layout.preferredWidth: 60
+ onActivated: {
+ parent.timeChanged(hourBox.currentIndex,
+ minuteBox.currentIndex,
+ secondBox.currentIndex)
+ }
+ }
+ MyText {
+ text: "s"
+ }
+ function changeTimer(hour, minute, second) {
+ hourBox.currentIndex = hour
+ minuteBox.currentIndex = minute
+ secondBox.currentIndex = second
+ hourBox.displayText = hour
+ minuteBox.displayText = minute
+ secondBox.displayText = second
+ }
+}
diff --git a/src/vr/qml/common/mainwidget.qml b/src/vr/qml/common/mainwidget.qml
new file mode 100755
index 0000000..868931e
--- /dev/null
+++ b/src/vr/qml/common/mainwidget.qml
@@ -0,0 +1,128 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.0
+import ".."
+import "../utilities_page"
+import "../audio_page"
+import "../motion_page"
+import "../video_page"
+import "../chaperone_page"
+import "../steamvr_page"
+import "../rotation_page"
+import "../chaperone_page/chaperone_additional"
+
+Rectangle {
+ id: root
+ color: "#1b2939"
+ width: 1200
+ height: 800
+
+ property WalletDashboard WalletDashboard: WalletDashboard {
+ stackView: walletView
+ }
+
+ property SteamVRPage steamVRPage: SteamVRPage {
+ stackView: walletView
+ visible: false
+ }
+
+ property ChaperonePage chaperonePage: ChaperonePage {
+ stackView: walletView
+ visible: false
+ }
+
+ property ChaperoneWarningsPage chaperoneWarningsPage: ChaperoneWarningsPage {
+ stackView: walletView
+ visible: false
+ }
+
+ property ChaperoneAdditionalPage chaperoneAdditionalPage: ChaperoneAdditionalPage{
+ stackView: walletView
+ visible: false
+ }
+
+ property PlayspacePage playspacePage: PlayspacePage {
+ stackView: walletView
+ visible: false
+ }
+
+ property MotionPage motionPage: MotionPage {
+ stackView: walletView
+ visible: false
+ }
+
+ property RotationPage rotationPage: RotationPage {
+ stackView: walletView
+ visible: false
+ }
+
+ property FixFloorPage fixFloorPage: FixFloorPage {
+ stackView: walletView
+ visible: false
+ }
+
+ property StatisticsPage statisticsPage: StatisticsPage {
+ stackView: walletView
+ visible: false
+ }
+
+ property SettingsPage settingsPage: SettingsPage {
+ stackView: walletView
+ visible: false
+ }
+
+ property AudioPage audioPage: AudioPage {
+ stackView: walletView
+ visible: false
+ }
+
+ property UtilitiesPage utilitiesPage: UtilitiesPage {
+ stackView: walletView
+ visible: false
+ }
+
+ property VideoPage videoPage: VideoPage {
+ stackView: walletView
+ visible:false
+ }
+
+ StackView {
+ id: walletView
+ anchors.fill: parent
+
+ pushEnter: Transition {
+ PropertyAnimation {
+ property: "x"
+ from: walletView.width
+ to: 0
+ duration: 200
+ }
+ }
+ pushExit: Transition {
+ PropertyAnimation {
+ property: "x"
+ from: 0
+ to: -walletView.width
+ duration: 200
+ }
+ }
+ popEnter: Transition {
+ PropertyAnimation {
+ property: "x"
+ from: -walletView.width
+ to: 0
+ duration: 200
+ }
+ }
+ popExit: Transition {
+ PropertyAnimation {
+ property: "x"
+ from: 0
+ to: walletView.width
+ duration: 200
+ }
+ }
+
+ initialItem: WalletDashboard
+ }
+}
diff --git a/src/vr/qml/dashboard/CreateWallet.qml b/src/vr/qml/dashboard/CreateWallet.qml
new file mode 100644
index 0000000..e69de29
diff --git a/src/vr/qml/dashboard/HelpPage.qml b/src/vr/qml/dashboard/HelpPage.qml
new file mode 100644
index 0000000..e69de29
diff --git a/src/vr/qml/wallet/HistoryTable.qml b/src/vr/qml/wallet/HistoryTable.qml
new file mode 100755
index 0000000..14a84c6
--- /dev/null
+++ b/src/vr/qml/wallet/HistoryTable.qml
@@ -0,0 +1,189 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.2
+
+import wowlet.Wallet 1.0
+import wowlet.WalletManager 1.0
+import wowlet.TransactionHistory 1.0
+import wowlet.TransactionInfo 1.0
+import wowlet.TransactionHistoryModel 1.0
+import wowlet.TransactionHistoryProxyModel 1.0
+
+import "../common"
+
+Item {
+ id: root
+ property var modelx
+
+ property var txModelData: []
+ property int sideMargin: 20
+
+ ListModel { id: txListViewModel }
+
+ ColumnLayout {
+ anchors.fill: parent
+ spacing: 0
+
+ ListView {
+ id: listView
+ visible: true
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ spacing: 10
+ model: modelx
+ interactive: false
+
+ delegate: Rectangle {
+ id: delegate
+ anchors.left: parent ? parent.left : undefined
+ anchors.right: parent ? parent.right : undefined
+ height: 54
+ color: "#2c435d"
+
+ property bool isout: false;
+ property string amount: "0";
+ property string description: "";
+ property string date: "2021-13-37";
+
+ property bool confirmed: false
+ property bool failed: false
+ property bool pending: false
+ property int confirmations: 0
+ property int confirmationsRequired: 0
+
+ Component.onCompleted: {
+ isout = getTxData(index, TransactionHistoryModel.TransactionIsOutRole);
+ amount = getTxData(index, TransactionHistoryModel.Amount);
+ description = getTxData(index, TransactionHistoryModel.Description);
+ date = getTxData(index, TransactionHistoryModel.Date);
+
+ failed = getTxData(index, TransactionHistoryModel.TransactionFailedRole);
+ pending = getTxData(index, TransactionHistoryModel.TransactionPendingRole);
+ confirmations = getTxData(index, TransactionHistoryModel.TransactionConfirmationsRole);
+ confirmationsRequired = getTxData(index, TransactionHistoryModel.TransactionConfirmationsRequiredRole);
+
+ confirmed = confirmations >= confirmationsRequired;
+ }
+
+ RowLayout {
+ spacing: 0
+ clip: true
+ height: parent.height
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Rectangle {
+ Layout.preferredWidth: 56
+ Layout.fillHeight: true
+ color: "#406288"
+
+ Image {
+ width: 32
+ height: 32
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ source: {
+ if(failed) return "qrc:/assets/images/warning.png"
+ else if(pending) return "qrc:/assets/images/unconfirmed.png"
+ else if(!confirmed) return "qrc:/assets/images/clock1.png"
+
+ else return "qrc:/assets/images/confirmed.png"
+ //confirmed ? "qrc:/checkmark_icon" : "qrc:/expired_icon"
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.preferredWidth: 300
+ Layout.leftMargin: 10
+ Layout.rightMargin: 10
+ Layout.fillHeight: true
+ color: "transparent"
+
+ MyText {
+ // date
+ anchors.verticalCenter: parent.verticalCenter
+ fontSize: 12
+ fontColor: "white"
+ text: date
+
+ Component.onCompleted: {
+ parent.Layout.preferredWidth = width;
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.leftMargin: 10
+ color: "transparent"
+
+ MyText {
+ anchors.verticalCenter: parent.verticalCenter
+ fontSize: 14
+ text: description !== "" ? description : "..."
+ fontColor: description !== "" ? "white" : "#cccccc"
+ Component.onCompleted: {
+ parent.Layout.preferredWidth = width;
+ }
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ Rectangle {
+ Layout.preferredWidth: 420
+ Layout.fillHeight: true
+ color: "#406288"
+
+ MyText {
+ anchors.right: parent.right
+ anchors.rightMargin: 10
+
+ anchors.verticalCenter: parent.verticalCenter
+ fontSize: 14
+ fontBold: true
+ text: amount
+ fontColor: !isout ? "#00d304" : "red"
+ }
+ }
+ }
+ }
+ }
+
+ Item {
+ Layout.fillHeight: true
+ }
+ }
+
+ Rectangle {
+ z: parent.z - 1
+ color: "transparent"
+ anchors.fill: parent
+ }
+
+ function getTxData(x, y) {
+ var idx = modelx.index(x, y);
+ return modelx.data(idx, 0);
+ }
+
+ function updateTransactionsFromModel() {
+ // This function copies the items of `appWindow.currentWallet.historyModel` to `root.txModelData`, as a list of javascript objects
+ if(appWindow.currentWallet == null || typeof appWindow.currentWallet.history === "undefined" ) return;
+
+ var _model = root.model;
+ var total = 0
+ var count = _model.rowCount()
+ root.txModelData = [];
+ }
+
+ function onPageCompleted() {
+ if(currentWallet == null || typeof currentWallet.history === "undefined" ) return;
+ root.modelx = appWindow.currentWallet.historyModel;
+ //root.model.sortRole = TransactionHistoryModel.TransactionBlockHeightRole;
+ //root.model.sort(0, Qt.DescendingOrder);
+ }
+}
\ No newline at end of file
diff --git a/src/vr/qml/wallet/ReceivePage.qml b/src/vr/qml/wallet/ReceivePage.qml
new file mode 100755
index 0000000..82ebdf6
--- /dev/null
+++ b/src/vr/qml/wallet/ReceivePage.qml
@@ -0,0 +1,266 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+import QtQuick.Dialogs 1.2
+import "."
+import "../common"
+
+MyStackViewPage {
+ headerText: "Receive"
+
+ MyDialogOkPopup {
+ id: chaperoneMessageDialog
+ function showMessage(title, text) {
+ dialogTitle = title
+ dialogText = text
+ open()
+ }
+ }
+
+ MyDialogOkCancelPopup {
+ id: chaperoneDeleteProfileDialog
+ property int profileIndex: -1
+ dialogTitle: "Delete Profile"
+ dialogText: "Do you really want to delete this profile?"
+ onClosed: {
+ if (okClicked) {
+ ChaperoneTabController.deleteChaperoneProfile(profileIndex)
+ }
+ }
+ }
+
+ MyDialogOkCancelPopup {
+ id: chaperoneNewProfileDialog
+ dialogTitle: "Create New Profile"
+ dialogWidth: 800
+ dialogHeight: 780
+ dialogContentItem: ColumnLayout {
+ RowLayout {
+ Layout.topMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+ MyText {
+ text: "Name: "
+ }
+ MyTextField {
+ id: chaperoneNewProfileName
+ keyBoardUID: 390
+ color: "#cccccc"
+ text: ""
+ Layout.fillWidth: true
+ font.pointSize: 20
+ function onInputEvent(input) {
+ chaperoneNewProfileName.text = input
+ }
+ }
+ }
+ MyText {
+ Layout.topMargin: 24
+ text: "What to include:"
+ }
+ MyToggleButton {
+ id: chaperoneNewProfileIncludeGeometry
+ Layout.leftMargin: 32
+ text: "Chaperone Geometry"
+ }
+ MyToggleButton {
+ id: chaperoneNewProfileIncludeStyle
+ Layout.leftMargin: 32
+ text: "Chaperone Style"
+ }
+ MyToggleButton {
+ id: chaperoneNewProfileIncludeBoundsColor
+ Layout.leftMargin: 32
+ text: "Chaperone Color"
+ }
+ MyToggleButton {
+ id: chaperoneNewProfileIncludeVisibility
+ Layout.leftMargin: 32
+ text: "Visibility Setting"
+ }
+ MyToggleButton {
+ id: chaperoneNewProfileIncludeFadeDistance
+ Layout.leftMargin: 32
+ text: "Fade Distance Setting"
+ }
+ MyToggleButton {
+ id: chaperoneNewProfileIncludeCenterMarker
+ Layout.leftMargin: 32
+ text: "Center Marker Setting"
+ }
+ MyToggleButton {
+ id: chaperoneNewProfileIncludePlaySpaceMarker
+ Layout.leftMargin: 32
+ text: "Play Space Marker Setting"
+ }
+ MyToggleButton {
+ id: chaperoneNewProfileIncludeFloorBoundsMarker
+ Layout.leftMargin: 32
+ text: "Floor Bounds Always On Setting"
+ }
+ MyToggleButton {
+ id: chaperoneNewProfileIncludeForceBounds
+ Layout.leftMargin: 32
+ text: "Force Bounds Setting"
+ }
+ MyToggleButton {
+ id: chaperoneNewProfileIncludeProximityWarnings
+ Layout.leftMargin: 32
+ text: "Proximity Warning Settings"
+ }
+ }
+ onClosed: {
+ if (okClicked) {
+ if (chaperoneNewProfileName.text == "") {
+ chaperoneMessageDialog.showMessage("Create New Profile", "ERROR: Empty profile name.")
+ } else if (!chaperoneNewProfileIncludeGeometry.checked
+ && !chaperoneNewProfileIncludeVisibility.checked
+ && !chaperoneNewProfileIncludeFadeDistance.checked
+ && !chaperoneNewProfileIncludeCenterMarker.checked
+ && !chaperoneNewProfileIncludePlaySpaceMarker.checked
+ && !chaperoneNewProfileIncludeFloorBoundsMarker.checked
+ && !chaperoneNewProfileIncludeBoundsColor.checked
+ && !chaperoneNewProfileIncludeStyle.checked
+ && !chaperoneNewProfileIncludeForceBounds.checked
+ && !chaperoneNewProfileIncludeProximityWarnings.checked) {
+ chaperoneMessageDialog.showMessage("Create New Profile", "ERROR: Nothing included.")
+ } else if ( Math.abs(MoveCenterTabController.offsetX) > 0.00000000001
+ || Math.abs(MoveCenterTabController.offsetY) > 0.00000000001
+ || Math.abs(MoveCenterTabController.offsetZ) > 0.00000000001
+ || MoveCenterTabController.rotation !== 0) {
+ chaperoneMessageDialog.showMessage("Create New Profile", "ERROR: Offsets not reset.")
+ } else {
+ ChaperoneTabController.addChaperoneProfile(chaperoneNewProfileName.text,
+ chaperoneNewProfileIncludeGeometry.checked,
+ chaperoneNewProfileIncludeVisibility.checked,
+ chaperoneNewProfileIncludeFadeDistance.checked,
+ chaperoneNewProfileIncludeCenterMarker.checked,
+ chaperoneNewProfileIncludePlaySpaceMarker.checked,
+ chaperoneNewProfileIncludeFloorBoundsMarker.checked,
+ chaperoneNewProfileIncludeBoundsColor.checked,
+ chaperoneNewProfileIncludeStyle.checked,
+ chaperoneNewProfileIncludeForceBounds.checked,
+ chaperoneNewProfileIncludeProximityWarnings.checked)
+ }
+
+ }
+ }
+ function openPopup() {
+ chaperoneNewProfileName.text = ""
+ chaperoneNewProfileIncludeGeometry.checked = false
+ chaperoneNewProfileIncludeVisibility.checked = false
+ chaperoneNewProfileIncludeFadeDistance.checked = false
+ chaperoneNewProfileIncludeCenterMarker.checked = false
+ chaperoneNewProfileIncludePlaySpaceMarker.checked = false
+ chaperoneNewProfileIncludeFloorBoundsMarker.checked = false
+ chaperoneNewProfileIncludeBoundsColor.checked = false
+ chaperoneNewProfileIncludeStyle.checked = false
+ chaperoneNewProfileIncludeForceBounds.checked = false
+ chaperoneNewProfileIncludeProximityWarnings.checked = false
+ open()
+ }
+ }
+
+
+ content: ColumnLayout {
+ spacing: 30
+
+ MyText {
+ Layout.fillWidth: true
+ wrap: true
+ text: "Give the following 4 digit PIN to the person that is sending you Wownero. PIN's are valid for 5 minutes and automatically renew."
+ }
+
+ ColumnLayout {
+ MyText {
+ visible: false
+ fontSize: 14
+ text: "Currently generating PIN."
+ }
+
+ Text {
+ visible: true
+ text: "0 0 0 0"
+ color: "#ffffff"
+ font.bold: true
+ font.pointSize: 40
+ leftPadding: 20
+ rightPadding: 20
+
+ Rectangle {
+ z: parent.z - 1
+ anchors.fill: parent
+ color: "black"
+ }
+ }
+
+ MyText {
+ id: expireText
+ visible: true
+ fontSize: 14
+ text: "Expires in 40 seconds."
+ }
+
+
+ }
+
+ Rectangle {
+ color: "#cccccc"
+ height: 1
+ Layout.topMargin: 10
+ Layout.fillWidth: true
+ }
+
+ MyText {
+ Layout.fillWidth: true
+ wrap: true
+ text: "Alternatively, you may use one of the following methods."
+ }
+
+ RowLayout {
+ Layout.topMargin: 10
+
+ MyPushButton {
+ id: viewAddress
+ text: "View address"
+ Layout.preferredWidth: 360
+
+ onClicked: {
+ MyResources.playFocusChangedSound()
+ walletView.push(chaperoneAdditionalPage)
+ }
+ }
+
+ MyPushButton {
+ id: copyToClipboard
+ text: "Copy address to clipboard"
+ Layout.preferredWidth: 540
+
+ onClicked: {
+ MyResources.playFocusChangedSound()
+ walletView.push(chaperoneAdditionalPage)
+ }
+ }
+
+ MyPushButton {
+ id: writeQRcode
+ text: "QR image"
+ Layout.preferredWidth: 340
+
+ onClicked: {
+ chaperoneNewProfileDialog.open();
+ }
+ }
+ }
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ }
+
+ function onPageCompleted() {
+ console.log("onPageCompleted() ReceivePage")
+ }
+}
diff --git a/src/vr/qml/wallet/WalletDashBoardPage.qml b/src/vr/qml/wallet/WalletDashBoardPage.qml
new file mode 100644
index 0000000..35b4730
--- /dev/null
+++ b/src/vr/qml/wallet/WalletDashBoardPage.qml
@@ -0,0 +1,101 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.2
+import QtGraphicalEffects 1.0
+import QtQuick.Window 2.0
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Dialogs 1.2
+
+// import ovrwow.wowletvr 1.0
+
+import "../common"
+import "."
+
+MyStackViewPage {
+ id: walletDashboard
+ width: 1600
+ height: 800
+ headerText: appWindow.walletTitle
+ headerShowBackButton: false
+ stackView: walletView
+
+ content: Item {
+ ColumnLayout {
+ anchors.fill: parent
+ RowLayout {
+ spacing: 32
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ ColumnLayout {
+ Layout.preferredWidth: 250
+ Layout.maximumWidth: 250
+ Layout.fillHeight: true
+ spacing: 10
+
+ MyPushButton {
+ id: steamVRButton
+ iconPath: "qrc:/send_icon"
+ activationSoundEnabled: false
+ text: "Send"
+ Layout.fillWidth: true
+ onClicked: {
+ //MyResources.playFocusChangedSound()
+ if(!appWindow.wsConnected) {
+ return messagePopup.showMessage("Please wait", "No connection to websocket server (yet).");
+ }
+
+ walletView.push(sendPage)
+ sendPage.onPageCompleted();
+ }
+ }
+
+ MyPushButton {
+ id: chaperoneButton
+ iconPath: "qrc:/receive_icon"
+ activationSoundEnabled: false
+ text: "Receive"
+ Layout.fillWidth: true
+ onClicked: {
+ //MyResources.playFocusChangedSound()
+ if(!appWindow.wsConnected) {
+ return messagePopup.showMessage("Please wait", "No connection to websocket server (yet).");
+ }
+
+ walletView.push(receivePage)
+ }
+ }
+
+ MyPushButton {
+ id: rotationButton
+ iconPath: "qrc:/backarrow"
+ activationSoundEnabled: false
+ text: "Close"
+ Layout.fillWidth: true
+ onClicked: {
+ //MyResources.playFocusChangedSound()
+ ctx.closeWallet(true, true);
+ mainView.pop();
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ color: "transparent"
+ }
+ }
+
+ HistoryTable {
+ id: historyView
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ }
+ }
+ }
+
+ function onPageCompleted() {
+ historyView.onPageCompleted();
+ }
+}
\ No newline at end of file
diff --git a/src/vr/qml/wallet/send/SendPage.qml b/src/vr/qml/wallet/send/SendPage.qml
new file mode 100755
index 0000000..06679a0
--- /dev/null
+++ b/src/vr/qml/wallet/send/SendPage.qml
@@ -0,0 +1,123 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 1.4
+
+import "../../common"
+import "."
+
+MyStackViewPage {
+ id: sendStateController
+ width: 1600
+ headerText: "Send"
+
+ property string destinationAddress: "cool_addy_here"
+
+ property string enteredColor: "#365473"
+ property string exitedColor: "#2c435d"
+ property string pressedColor: "#406288"
+
+ content: ColumnLayout {
+ id: sendStateView
+ property Item currentView
+ property Item previousView
+
+ property SendPagePIN pinPage: SendPagePIN {}
+ property SendPageDashboard dashPage: SendPageDashboard {}
+ property SendPageTransfer transferPage: SendPageTransfer {}
+ property SendPageQR qrPage: SendPageQR {}
+
+ state: ''
+
+ onCurrentViewChanged: {
+ if (previousView) {
+ if (typeof previousView.onPageClosed === "function") {
+ previousView.onPageClosed();
+ }
+ }
+
+ // if(previousView !== null && currentView.viewName === "wizardHome")
+ // wizardController.restart();
+
+ if (currentView) {
+ sendStack.replace(currentView)
+ // Calls when view is opened
+ if (typeof currentView.onPageCompleted === "function") {
+ currentView.onPageCompleted(previousView);
+ }
+ }
+
+ previousView = currentView;
+
+ // reset push direction
+ // if(wizardController.wizardState == "wizardHome")
+ // wizardController.wizardStackView.backTransition = false;
+ }
+
+ states: [
+ State {
+ name: "pinPage"
+ PropertyChanges { target: sendStateView; currentView: sendStateView.pinPage }
+ }, State {
+ name: "dashPage"
+ PropertyChanges { target: sendStateView; currentView: sendStateView.dashPage }
+ }, State {
+ name: "transferPage"
+ PropertyChanges { target: sendStateView; currentView: sendStateView.transferPage }
+ }, State {
+ name: "qrPage"
+ PropertyChanges { target: sendStateView; currentView: sendStateView.qrPage }
+ }
+ ]
+
+ StackView {
+ id: sendStack
+ clip: true
+ initialItem: sendStateView.dashPage
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ delegate: StackViewDelegate {
+ pushTransition: StackViewTransition {
+ PropertyAnimation {
+ target: enterItem
+ property: "x"
+ from: sendStack.backTransition ? -target.width : target.width
+ to: 0
+ duration: 300
+ easing.type: Easing.OutCubic
+ }
+
+ PropertyAnimation {
+ target: exitItem
+ property: "x"
+ from: 0
+ to: sendStack.backTransition ? target.width : -target.width
+ duration: 300
+ easing.type: Easing.OutCubic
+ }
+ }
+ }
+ }
+ }
+
+ // Connections {
+ // target: sendStateView.dashPage
+ // function onTest() {
+ // sendStack.push(pinPage)
+ // pinPage.onPageCompleted();
+ // }
+ // }
+
+ function onPageCompleted(previousView){
+ sendStateView.state = "dashPage"
+ }
+
+ onBackClicked: {
+ // top back button to send/receive menu, reset default states for sendViews
+ sendStateView.pinPage.onPageCompleted();
+ sendStateView.dashPage.onPageCompleted();
+ sendStateView.transferPage.onPageCompleted();
+ }
+}
diff --git a/src/vr/qml/wallet/send/SendPageDashboard.qml b/src/vr/qml/wallet/send/SendPageDashboard.qml
new file mode 100644
index 0000000..40e3bf0
--- /dev/null
+++ b/src/vr/qml/wallet/send/SendPageDashboard.qml
@@ -0,0 +1,65 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+import "../../common"
+
+ColumnLayout {
+ id: root
+
+ Layout.fillWidth: true
+
+ MyText {
+ Layout.fillWidth: true
+ wrap: true
+ text: "How to transfer Wownero?"
+ }
+
+ RowLayout {
+ Layout.topMargin: 30
+ Layout.fillWidth: true
+ spacing: 30
+
+ Rectangle {
+ color: sendStateController.exitedColor
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ onEntered: parent.color = sendStateController.enteredColor
+ onExited: parent.color = sendStateController.exitedColor
+ onPressed: parent.color = sendStateController.pressedColor
+ onClicked: {
+ sendStateView.state = "pinPage";
+ }
+ }
+ }
+
+ Rectangle {
+ color: sendStateController.exitedColor
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ onEntered: parent.color = sendStateController.enteredColor
+ onExited: parent.color = sendStateController.exitedColor
+ onPressed: parent.color = sendStateController.pressedColor
+ onClicked: {
+ sendStateView.state = "qrPage";
+ }
+ }
+ }
+ }
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ function onPageCompleted(previousView){
+
+ }
+}
\ No newline at end of file
diff --git a/src/vr/qml/wallet/send/SendPageNavBack.qml b/src/vr/qml/wallet/send/SendPageNavBack.qml
new file mode 100644
index 0000000..994486c
--- /dev/null
+++ b/src/vr/qml/wallet/send/SendPageNavBack.qml
@@ -0,0 +1,56 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 1.4
+
+import "../../common"
+
+
+RowLayout {
+ id: root
+ Layout.fillWidth: true
+ Layout.preferredHeight: 82
+ Layout.maximumHeight: 82
+
+ signal backClicked();
+
+ Rectangle {
+ color: sendStateController.exitedColor
+ Layout.preferredHeight: 82
+ Layout.preferredWidth: 220
+
+ RowLayout {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ Layout.minimumHeight: 54
+
+ Image {
+ source: "qrc:/backarrow"
+ Layout.leftMargin: 20
+ Layout.rightMargin: 20
+ Layout.preferredWidth: 32
+ Layout.preferredHeight: 32
+ }
+
+ MyText {
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignLeft
+ fontBold: true
+ text: "back"
+ fontSize: 16
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ onEntered: parent.color = sendStateController.enteredColor
+ onExited: parent.color = sendStateController.exitedColor
+ onPressed: parent.color = sendStateController.pressedColor
+ onClicked: {
+ root.backClicked();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/vr/qml/wallet/send/SendPagePIN.qml b/src/vr/qml/wallet/send/SendPagePIN.qml
new file mode 100644
index 0000000..04dd83c
--- /dev/null
+++ b/src/vr/qml/wallet/send/SendPagePIN.qml
@@ -0,0 +1,269 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+import "../../common"
+
+
+ColumnLayout {
+ id: root
+
+ Layout.fillWidth: true
+ property string _PINLookup: ""
+ property int lookupTimeoutSecs: 5;
+ property int lookupTimeoutCounter: 2;
+
+ Timer {
+ id: lookupTimer
+ interval: 1000;
+ running: false;
+ repeat: true;
+
+ onTriggered: {
+ lookupTimeoutCounter -= 1;
+
+ if(lookupTimeoutCounter === 0) {
+ stop();
+ root.onLookupTimeout();
+ }
+ }
+ }
+
+ MyText {
+ Layout.fillWidth: true
+ wrap: true
+ text: "Enter a 4 digit PIN and wait for it to resolve."
+ }
+
+ RowLayout {
+ Layout.topMargin: 30
+ Layout.fillWidth: true
+ spacing: 40
+
+ ColumnLayout {
+ Layout.preferredWidth: 320
+ Layout.preferredHeight: 400
+
+ MyNumPad {
+ id: numPad
+ onCodeUpdated: {
+ let codeFmt = "";
+
+ for(var i = 0; i != 4; i++) {
+ if(pin_code[i] !== undefined) {
+ codeFmt += pin_code[i] + " ";
+ } else {
+ codeFmt += ". ";
+ }
+ }
+
+ // update display thingy
+ codeDisplay.text = codeFmt;
+
+ // lol Qt
+ codeFmt = codeFmt.replace(" ", "").replace(" ", "").replace(" ", "").replace(" ", "").replace(" ", "").trim();
+
+ if(pin_code.length === 4 && codeFmt != "0000")
+ addressLookup(codeFmt);
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.Layout.preferredWidth
+ color: "transparent"
+ }
+ }
+
+ ColumnLayout {
+ Layout.preferredHeight: 400
+ Layout.preferredWidth: 390
+
+ Text {
+ id: codeDisplay
+ Layout.preferredWidth: 390
+ visible: true
+ text: "0 0 0 0"
+ color: "#ffffff"
+ font.bold: true
+ font.pointSize: 40
+ leftPadding: 20
+ rightPadding: 20
+
+ Rectangle {
+ z: parent.z - 1
+ anchors.fill: parent
+ color: "black"
+ }
+ }
+
+ Rectangle {
+ color: "transparent"
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.Layout.preferredWidth
+ }
+ }
+
+ Rectangle {
+ color: "#cccccc"
+ width: 1
+ Layout.fillHeight: true
+ }
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ // Idle container
+ ColumnLayout {
+ id: idleContainer
+ visible: true
+ spacing: 30
+ Layout.fillWidth: true
+
+ MyText {
+ fontSize: 18
+ text: "Waiting on input..."
+ }
+ }
+
+ // Loading container
+ ColumnLayout {
+ id: loadingContainer
+ visible: false
+ spacing: 10
+ Layout.fillWidth: true
+
+ MyText {
+ fontSize: 18
+ text: "Looking up address..."
+ }
+
+ RowLayout {
+ spacing: 30
+ Layout.topMargin: 20
+ Layout.fillWidth: true
+
+ MyText {
+ fontBold: true
+ text: "Code:"
+ }
+
+ MyText {
+ text: _PINLookup
+ }
+ }
+
+ RowLayout {
+ spacing: 30
+ Layout.fillWidth: true
+
+ MyText {
+ fontBold: true
+ text: "Timeout:"
+ }
+
+ MyText {
+ text: lookupTimeoutCounter + " seconds"
+ }
+ }
+ }
+
+ // Image {
+ // visible: false
+ // id: loadingImage
+ // source: "qrc:/illuminati"
+ // sourceSize.width: 400
+ // sourceSize.height: 400
+ // }
+
+ ColumnLayout {
+ id: foundContainer
+ visible: false
+ spacing: 30
+ Layout.fillWidth: true
+
+ RowLayout {
+ spacing: 20
+ Layout.fillWidth: true
+
+ MyText {
+ fontBold: true
+ text: "Address found:"
+ }
+
+ MyText {
+ text: "WW2xG...gKgrcC7"
+ }
+ }
+
+ MyPushButton {
+ id: continueButton
+ text: "Continue"
+ Layout.preferredWidth: 220
+
+ onClicked: {
+ //
+ }
+ }
+ }
+ }
+ }
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ function addressLookup(code) {
+ if(_PINLookup !== "")
+ return;
+
+ _PINLookup = code;
+
+ idleContainer.visible = false;
+ foundContainer.visible = false;
+ loadingContainer.visible = true;
+
+ numPad.enabled = false;
+
+ lookupTimer.start();
+ }
+
+ function onLookupTimeout() {
+ reset();
+ messagePopup.showMessage("Lookup failed", "Error getting address.")
+ sendStateView.state = "transferPage";
+ }
+
+ function onPageCompleted(previousView) {
+ reset();
+ }
+
+ function onWSPINAdressReceived(pin_code, address) {
+ // address received from websockets
+ if(pin_code === _PINLookup) {
+ sendStateController.destinationAddress = address;
+ sendStateView.state = "transferPage";
+ } else {
+ console.log("PIN lookup received but we timed out already, disregard.")
+ }
+ }
+
+ function reset() {
+ // reset state
+ _PINLookup = "";
+
+ lookupTimer.stop();
+ lookupTimeoutCounter = lookupTimeoutSecs;
+ idleContainer.visible = true;
+ foundContainer.visible = false;
+ loadingContainer.visible = false;
+ sendStateController.destinationAddress = "";
+
+ numPad.enabled = true;
+ numPad.reset();
+
+ codeDisplay.text = "0 0 0 0";
+ }
+}
\ No newline at end of file
diff --git a/src/vr/qml/wallet/send/SendPageQR.qml b/src/vr/qml/wallet/send/SendPageQR.qml
new file mode 100644
index 0000000..e1c810b
--- /dev/null
+++ b/src/vr/qml/wallet/send/SendPageQR.qml
@@ -0,0 +1,46 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+import "../../common"
+
+
+ColumnLayout {
+ id: root
+ spacing: 20
+
+ Layout.fillWidth: true
+
+ MyText {
+ Layout.fillWidth: true
+ wrap: true
+ text: "Look at a QR code in VR and take a screenshot."
+ }
+
+ MyPushButton {
+ id: continueButton
+ text: "Take in-game screenshot"
+ Layout.preferredWidth: 490
+
+ onClicked: {
+ // QR thingy
+ }
+ }
+
+ MyText {
+ id: statusMessage
+ visible: false
+ Layout.fillWidth: true
+ wrap: true
+ text: "Status message."
+ }
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ function onPageCompleted(previousView){
+
+ }
+}
\ No newline at end of file
diff --git a/src/vr/qml/wallet/send/SendPageTransfer.qml b/src/vr/qml/wallet/send/SendPageTransfer.qml
new file mode 100644
index 0000000..ede8a69
--- /dev/null
+++ b/src/vr/qml/wallet/send/SendPageTransfer.qml
@@ -0,0 +1,207 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+import "../../common"
+
+ColumnLayout {
+ id: root
+ spacing: 30
+
+ property double amount: 0.0
+ property bool canSend: false
+ property bool isSending: false
+
+ Layout.fillWidth: true
+
+ MyText {
+ Layout.fillWidth: true
+ wrap: true
+ text: "How much would you like to send?"
+ }
+
+ MyNumPadSendAmount {
+ id: myNumPadSendAmount
+ Layout.fillWidth: true
+ Layout.preferredHeight: 112
+ Layout.maximumHeight: 112
+
+ onAmountUpdated: {
+ root.amount = amount;
+
+ // @TODO: create tx validation here
+ if(root.amount <= 0) {
+ root.canSend = false;
+ } else {
+ root.canSend = true;
+ }
+ }
+ }
+
+ RowLayout {
+ spacing: 30
+ Layout.topMargin: 20
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ ColumnLayout {
+ spacing: 10
+ Layout.fillHeight: true
+ Layout.maximumWidth: parent.width / 2
+
+ RowLayout {
+ spacing: 30
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Rectangle {
+ color: "transparent"
+ Layout.preferredWidth: 192
+ Layout.preferredHeight: 48
+
+ MyText {
+ fontBold: true
+ text: "Amount:"
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Rectangle {
+ color: "transparent"
+ Layout.fillWidth: true
+ Layout.preferredHeight: 48
+
+ MyText {
+ fontSize: 18
+ text: root.amount + " WOW"
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ }
+ }
+ }
+
+ RowLayout {
+ spacing: 30
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Rectangle {
+ color: "transparent"
+ Layout.preferredWidth: 192
+ Layout.preferredHeight: 48
+
+ MyText {
+ fontBold: true
+ text: "Fiat:"
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Rectangle {
+ color: "transparent"
+ Layout.fillWidth: true
+ Layout.preferredHeight: 48
+
+ MyText {
+ fontSize: 18
+ text: "$853.20 USD"
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ }
+ }
+ }
+
+ RowLayout {
+ spacing: 30
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Rectangle {
+ color: "transparent"
+ Layout.preferredWidth: 192
+ Layout.preferredHeight: 48
+
+ MyText {
+ fontBold: true
+ text: "Destination:"
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Rectangle {
+ color: "transparent"
+ Layout.fillWidth: true
+ Layout.preferredHeight: 48
+
+ MyText {
+ text: "Wo3ige...YegEia2"
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ }
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ }
+
+ Rectangle {
+ color: "transparent"
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+
+ RowLayout {
+ Layout.preferredWidth: parent.width
+ Layout.preferredHeight: 128
+
+ MyPushButton {
+ id: keyboardButton
+ enabled: !isSending
+ opacity: isSending ? 0.5 : 1.0
+ Layout.preferredWidth: 700
+
+ text: "Enter amount via virtual keyboard"
+
+ onClicked: {
+ OverlayController.showKeyboard(text, "1337")
+ }
+ }
+
+ MyPushButton {
+ id: sendButton
+ opacity: root.canSend ? 1.0 : 0.5
+ enabled: root.canSend
+
+ Layout.preferredWidth: 420
+ Layout.alignment: Qt.AlignRight
+
+ text: "Create transaction"
+
+ onClicked: {
+ currentWallet.createTransactionAsync(addresses, paymentId, amountsxmr, mixinCount, priority);
+ }
+ }
+ }
+
+ Connections {
+ target: OverlayController
+ function onKeyBoardInputSignal(input, userValue) {
+ if (userValue == "1337") {
+ let val = parseFloat(input);
+ myNumPadSendAmount.onAmountUpdated(val);
+ }
+ }
+ }
+
+ function onPageCompleted(previousView){
+
+ }
+}
\ No newline at end of file