diff --git a/electrum/gui/qml/components/WalletSummary.qml b/electrum/gui/qml/components/WalletSummary.qml index 88fba5ba9..6ee62236b 100644 --- a/electrum/gui/qml/components/WalletSummary.qml +++ b/electrum/gui/qml/components/WalletSummary.qml @@ -41,7 +41,7 @@ Item { Transition { from: 'opened' to: '' - NumberAnimation { target: root; properties: 'implicitHeight'; duration: 200 } + NumberAnimation { target: root; properties: 'implicitHeight'; duration: 100 } } ] @@ -59,75 +59,7 @@ Item { width: parent.width spacing: constants.paddingXLarge - GridLayout { - visible: Daemon.currentWallet - rowSpacing: constants.paddingSmall - Layout.preferredWidth: parent.width - Layout.topMargin: constants.paddingXLarge - - columns: 2 - - Flow { - Layout.columnSpan: 2 - Layout.alignment: Qt.AlignHCenter - Layout.preferredWidth: parent.width * 4/5 - spacing: constants.paddingMedium - - Tag { - text: Daemon.currentWallet.walletType - font.pixelSize: constants.fontSizeSmall - font.bold: true - iconSource: '../../../icons/wallet.png' - } - Tag { - text: Daemon.currentWallet.txinType - font.pixelSize: constants.fontSizeSmall - font.bold: true - } - Tag { - text: qsTr('HD') - visible: Daemon.currentWallet.isDeterministic - font.pixelSize: constants.fontSizeSmall - font.bold: true - } - Tag { - text: qsTr('Watch only') - visible: Daemon.currentWallet.isWatchOnly - font.pixelSize: constants.fontSizeSmall - font.bold: true - iconSource: '../../../icons/eye1.png' - } - Tag { - text: qsTr('Encrypted') - visible: Daemon.currentWallet.isEncrypted - font.pixelSize: constants.fontSizeSmall - font.bold: true - iconSource: '../../../icons/key.png' - } - Tag { - text: qsTr('HW') - visible: Daemon.currentWallet.isHardware - font.pixelSize: constants.fontSizeSmall - font.bold: true - iconSource: '../../../icons/seed.png' - } - Tag { - text: qsTr('Lightning') - visible: Daemon.currentWallet.isLightning - font.pixelSize: constants.fontSizeSmall - font.bold: true - iconSource: '../../../icons/lightning.png' - } - Tag { - text: qsTr('Seed') - visible: Daemon.currentWallet.hasSeed - font.pixelSize: constants.fontSizeSmall - font.bold: true - iconSource: '../../../icons/seed.png' - } - } - - } + Item { Layout.preferredWidth: 1; Layout.preferredHeight: 1 } TextHighlightPane { Layout.alignment: Qt.AlignHCenter @@ -172,37 +104,28 @@ Item { } } - Piechart { - id: piechart - visible: Daemon.currentWallet.totalBalance.satsInt > 0 - Layout.preferredWidth: parent.width - implicitHeight: 200 - innerOffset: 6 - function updateSlices() { - var totalB = Daemon.currentWallet.totalBalance.satsInt - var onchainB = Daemon.currentWallet.confirmedBalance.satsInt - var frozenB = Daemon.currentWallet.frozenBalance.satsInt - var lnB = Daemon.currentWallet.lightningBalance.satsInt - piechart.slices = [ - { v: (onchainB-frozenB)/totalB, color: constants.colorPiechartOnchain, text: 'On-chain' }, - { v: frozenB/totalB, color: constants.colorPiechartFrozen, text: 'On-chain (frozen)' }, - { v: lnB/totalB, color: constants.colorPiechartLightning, text: 'Lightning' } - ] - } - } - RowLayout { Layout.fillWidth: true FlatButton { text: qsTr('More details') Layout.fillWidth: true Layout.preferredWidth: 1 + enabled: app.stack.currentItem.objectName != 'WalletDetails' + onClicked: { + root.close() + app.stack.pushOnRoot(Qt.resolvedUrl('WalletDetails.qml')) + } } FlatButton { text: qsTr('Switch wallet') Layout.fillWidth: true icon.source: '../../icons/file.png' Layout.preferredWidth: 1 + enabled: app.stack.currentItem.objectName != 'Wallets' + onClicked: { + root.close() + app.stack.pushOnRoot(Qt.resolvedUrl('Wallets.qml')) + } } } } @@ -216,7 +139,6 @@ Item { if (Daemon.fx.enabled) { root.formattedTotalBalanceFiat = Daemon.fx.fiatValue(Daemon.currentWallet.totalBalance, false) } - piechart.updateSlices() } diff --git a/electrum/gui/qml/components/Wallets.qml b/electrum/gui/qml/components/Wallets.qml index a678f041a..a80c5d346 100644 --- a/electrum/gui/qml/components/Wallets.qml +++ b/electrum/gui/qml/components/Wallets.qml @@ -9,8 +9,11 @@ import "controls" Pane { id: rootItem + objectName: 'Wallets' - property string title: qsTr('Wallets') + padding: 0 + + // property string title: qsTr('Wallets') function createWallet() { var dialog = app.newWalletWizard.createObject(rootItem) @@ -22,230 +25,39 @@ Pane { }) } - function enableLightning() { - var dialog = app.messageDialog.createObject(rootItem, - {'text': qsTr('Enable Lightning for this wallet?'), 'yesno': true}) - dialog.yesClicked.connect(function() { - Daemon.currentWallet.enableLightning() - }) - dialog.open() - } - - function deleteWallet() { - var dialog = app.messageDialog.createObject(rootItem, - {'text': qsTr('Really delete this wallet?'), 'yesno': true}) - dialog.yesClicked.connect(function() { - Daemon.check_then_delete_wallet(Daemon.currentWallet) - }) - dialog.open() - } - - function changePassword() { - // trigger dialog via wallet (auth then signal) - Daemon.start_change_password() - } - - property QtObject menu: Menu { - id: menu - parent: Overlay.overlay - dim: true - Overlay.modeless: Rectangle { - color: "#44000000" - } - MenuItem { - icon.color: 'transparent' - action: Action { - text: qsTr('Create Wallet'); - onTriggered: rootItem.createWallet() - icon.source: '../../icons/wallet.png' - } - } - Component { - id: changePasswordComp - MenuItem { - icon.color: 'transparent' - enabled: Daemon.currentWallet - action: Action { - text: qsTr('Change Password'); - onTriggered: rootItem.changePassword() - icon.source: '../../icons/lock.png' - } - } - } - Component { - id: deleteWalletComp - MenuItem { - icon.color: 'transparent' - enabled: Daemon.currentWallet - action: Action { - text: qsTr('Delete Wallet'); - onTriggered: rootItem.deleteWallet() - icon.source: '../../icons/delete.png' - } - } - } - - Component { - id: enableLightningComp - MenuItem { - icon.color: 'transparent' - action: Action { - text: qsTr('Enable Lightning'); - onTriggered: rootItem.enableLightning() - enabled: Daemon.currentWallet && Daemon.currentWallet.canHaveLightning && !Daemon.currentWallet.isLightning - icon.source: '../../icons/lightning.png' - } - } - } - - Component { - id: sepComp - MenuSeparator {} - } - - // add items dynamically, if using visible: false property the menu item isn't removed but empty - Component.onCompleted: { - if (Daemon.currentWallet) { - menu.insertItem(0, sepComp.createObject(menu)) - if (Daemon.currentWallet.canHaveLightning && !Daemon.currentWallet.isLightning) { - menu.insertItem(0, enableLightningComp.createObject(menu)) - } - menu.insertItem(0, deleteWalletComp.createObject(menu)) - menu.insertItem(0, changePasswordComp.createObject(menu)) - } - } - } - ColumnLayout { - id: layout + id: rootLayout width: parent.width height: parent.height + spacing: 0 - GridLayout { - id: detailsLayout - visible: Daemon.currentWallet + ColumnLayout { Layout.preferredWidth: parent.width - - columns: 4 - - Label { text: 'Wallet'; Layout.columnSpan: 2; color: Material.accentColor } - Label { text: Daemon.currentWallet.name; font.bold: true /*pixelSize: constants.fontSizeLarge*/; Layout.columnSpan: 2 } - - Label { text: 'derivation prefix (BIP32)'; visible: Daemon.currentWallet.isDeterministic; color: Material.accentColor; Layout.columnSpan: 2 } - Label { text: Daemon.currentWallet.derivationPrefix; visible: Daemon.currentWallet.isDeterministic; Layout.columnSpan: 2 } - - Label { text: 'wallet type'; color: Material.accentColor } - Label { text: Daemon.currentWallet.walletType } - - Label { text: 'txin Type'; color: Material.accentColor } - Label { text: Daemon.currentWallet.txinType } - - Label { text: 'is deterministic'; color: Material.accentColor } - Label { text: Daemon.currentWallet.isDeterministic } - - Label { text: 'is watch only'; color: Material.accentColor } - Label { text: Daemon.currentWallet.isWatchOnly } - - Label { text: 'is Encrypted'; color: Material.accentColor } - Label { text: Daemon.currentWallet.isEncrypted } - - Label { text: 'is Hardware'; color: Material.accentColor } - Label { text: Daemon.currentWallet.isHardware } - - Label { text: 'is Lightning'; color: Material.accentColor } - Label { text: Daemon.currentWallet.isLightning } - - Label { text: 'has Seed'; color: Material.accentColor } - Label { text: Daemon.currentWallet.hasSeed } + Layout.margins: constants.paddingLarge Label { - visible: Daemon.currentWallet.masterPubkey - Layout.columnSpan:4; text: qsTr('Master Public Key'); color: Material.accentColor + text: qsTr('Wallets') + font.pixelSize: constants.fontSizeLarge + color: Material.accentColor } - TextHighlightPane { - visible: Daemon.currentWallet.masterPubkey - - Layout.columnSpan: 4 + Rectangle { Layout.fillWidth: true - padding: 0 - leftPadding: constants.paddingSmall - - RowLayout { - width: parent.width - Label { - text: Daemon.currentWallet.masterPubkey - wrapMode: Text.Wrap - Layout.fillWidth: true - font.family: FixedFont - font.pixelSize: constants.fontSizeMedium - } - ToolButton { - icon.source: '../../icons/share.png' - icon.color: 'transparent' - onClicked: { - var dialog = app.genericShareDialog.createObject(rootItem, { - title: qsTr('Master Public Key'), - text: Daemon.currentWallet.masterPubkey - }) - dialog.open() - } - } - } + height: 1 + color: Material.accentColor } - } - ColumnLayout { - visible: !Daemon.currentWallet - - Layout.alignment: Qt.AlignHCenter - Layout.bottomMargin: constants.paddingXXLarge - Layout.topMargin: constants.paddingXXLarge - spacing: 2*constants.paddingXLarge - - Label { - text: qsTr('No wallet loaded') - font.pixelSize: constants.fontSizeXXLarge - Layout.alignment: Qt.AlignHCenter - } - - } - - Frame { - id: detailsFrame - Layout.topMargin: constants.paddingXLarge - Layout.preferredWidth: parent.width - Layout.fillHeight: true - verticalPadding: 0 - horizontalPadding: 0 - background: PaneInsetBackground {} - - ColumnLayout { - spacing: 0 - anchors.fill: parent - - Item { - Layout.preferredHeight: hitem.height - Layout.preferredWidth: parent.width - Rectangle { - anchors.fill: parent - color: Qt.lighter(Material.background, 1.25) - } - RowLayout { - id: hitem - width: parent.width - Label { - text: qsTr('Available wallets') - font.pixelSize: constants.fontSizeLarge - color: Material.accentColor - } - } - } + Frame { + id: detailsFrame + Layout.preferredWidth: parent.width + Layout.fillHeight: true + verticalPadding: 0 + horizontalPadding: 0 + background: PaneInsetBackground {} ListView { id: listview - Layout.preferredWidth: parent.width - Layout.fillHeight: true + anchors.fill: parent clip: true model: Daemon.availableWallets @@ -305,10 +117,11 @@ Pane { ScrollIndicator.vertical: ScrollIndicator { } } } + } - Button { - Layout.alignment: Qt.AlignHCenter + FlatButton { + Layout.fillWidth: true text: 'Create Wallet' onClicked: rootItem.createWallet() } @@ -320,53 +133,6 @@ Pane { Daemon.availableWallets.reload() app.stack.pop() } - function onRequestNewPassword() { // new unified password (all wallets) - var dialog = app.passwordDialog.createObject(app, - { - 'confirmPassword': true, - 'title': qsTr('Enter new password'), - 'infotext': qsTr('If you forget your password, you\'ll need to\ - restore from seed. Please make sure you have your seed stored safely') - } ) - dialog.accepted.connect(function() { - Daemon.set_password(dialog.password) - }) - dialog.open() - } - function onWalletDeleteError(code, message) { - if (code == 'unpaid_requests') { - var dialog = app.messageDialog.createObject(app, {text: message, yesno: true }) - dialog.yesClicked.connect(function() { - Daemon.check_then_delete_wallet(Daemon.currentWallet, true) - }) - dialog.open() - } else if (code == 'balance') { - var dialog = app.messageDialog.createObject(app, {text: message, yesno: true }) - dialog.yesClicked.connect(function() { - Daemon.check_then_delete_wallet(Daemon.currentWallet, true, true) - }) - dialog.open() - } else { - var dialog = app.messageDialog.createObject(app, {text: message }) - dialog.open() - } - } } - Connections { - target: Daemon.currentWallet - function onRequestNewPassword() { // new wallet password - var dialog = app.passwordDialog.createObject(app, - { - 'confirmPassword': true, - 'title': qsTr('Enter new password'), - 'infotext': qsTr('If you forget your password, you\'ll need to\ - restore from seed. Please make sure you have your seed stored safely') - } ) - dialog.accepted.connect(function() { - Daemon.currentWallet.set_password(dialog.password) - }) - dialog.open() - } - } } diff --git a/electrum/gui/qml/components/controls/Piechart.qml b/electrum/gui/qml/components/controls/Piechart.qml index 3fee52030..8e5329849 100644 --- a/electrum/gui/qml/components/controls/Piechart.qml +++ b/electrum/gui/qml/components/controls/Piechart.qml @@ -6,6 +6,7 @@ Canvas { property var slices property int innerOffset: 10 + property int legendOffset: 8 property bool showLegend: true onSlicesChanged: piechart.requestPaint() @@ -20,7 +21,7 @@ Canvas { ctx.lineWidth = 2 var pcx = width/2 var pcy = height/2 - var radius = height/4 + var radius = height/3 var endR = startR for (const i in slices) { @@ -48,23 +49,25 @@ Canvas { continue // displace legend - var dx = Math.cos(phi) * (radius + innerOffset + constants.paddingMedium) - var dy = Math.sin(phi) * (radius + innerOffset + constants.paddingMedium) + var dx = Math.cos(phi) * (radius + innerOffset + legendOffset) + var dy = Math.sin(phi) * (radius + innerOffset + legendOffset) + var dx2 = Math.cos(phi) * (radius + innerOffset + 2 * legendOffset) + var dy2 = Math.sin(phi) * (radius + innerOffset + 2 * legendOffset) ctx.lineWidth = 1 ctx.beginPath() if (dx > 0) { var ddx = ctx.measureText(slice.text).width + 2 * constants.paddingMedium - var xtext = pcx+dx*1.2 + constants.paddingMedium + var xtext = pcx+dx2 + constants.paddingMedium } else { var ddx = -(ctx.measureText(slice.text).width + 2 * constants.paddingMedium) - var xtext = pcx+dx*1.2+ddx + constants.paddingMedium + var xtext = pcx+dx2+ddx + constants.paddingMedium } ctx.moveTo(pcx+dx, pcy+dy) - ctx.lineTo(pcx+dx*1.2, pcy+dy*1.2) - ctx.lineTo(pcx+dx*1.2+ddx, pcy+dy*1.2) - ctx.moveTo(pcx+dx*1.2, pcy+dy*1.2) + ctx.lineTo(pcx+dx2, pcy+dy2) + ctx.lineTo(pcx+dx2+ddx, pcy+dy2) + ctx.moveTo(pcx+dx2, pcy+dy2) - ctx.text(slice.text, xtext, pcy+dy*1.2 - constants.paddingXSmall) + ctx.text(slice.text, xtext, pcy+dy2 - constants.paddingXSmall) ctx.stroke() } diff --git a/electrum/gui/qml/components/main.qml b/electrum/gui/qml/components/main.qml index 07662e61c..b771b8d2b 100644 --- a/electrum/gui/qml/components/main.qml +++ b/electrum/gui/qml/components/main.qml @@ -137,6 +137,13 @@ ApplicationWindow function getRoot() { return mainStackView.get(0) } + function pushOnRoot(item) { + if (mainStackView.depth > 1) { + mainStackView.replace(mainStackView.get(1), item) + } else { + mainStackView.push(item) + } + } } Timer {