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 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + 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 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + 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 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + 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 @@ +Artboard 13 \ 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 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + A + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Lapo Calamandrei + + + + + + + + record + media + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Lapo Calamandrei + + + + + Record + + + record + media + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Lapo Calamandrei + + + + + + + + record + media + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + View Refresh + + + reload + refresh + view + + + + + Ricardo 'Rick' González + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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