qml: switch to QtQuick Controls
This commit is contained in:
@@ -1,41 +0,0 @@
|
||||
import QtQuick 2.6
|
||||
|
||||
Item {
|
||||
id: rootItem
|
||||
width: visbut.width + 10
|
||||
height: visbut.height + 10
|
||||
|
||||
signal clicked
|
||||
property string text
|
||||
|
||||
Rectangle {
|
||||
id: visbut
|
||||
border {
|
||||
color: '#444444'
|
||||
width: 2
|
||||
}
|
||||
color: '#dddddd'
|
||||
radius: 4
|
||||
|
||||
anchors.centerIn: parent
|
||||
width: buttonText.width
|
||||
height: buttonText.height
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: rootItem.clicked()
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: buttonText
|
||||
leftPadding: 30
|
||||
rightPadding: 30
|
||||
topPadding: 20
|
||||
bottomPadding: 20
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: rootItem.text
|
||||
color: 'red'
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import QtQuick 2.6
|
||||
|
||||
Item {
|
||||
height: 60
|
||||
|
||||
property alias text: label.text
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: '#cccccc'
|
||||
}
|
||||
|
||||
Text {
|
||||
id: label
|
||||
x: 10
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pointSize: 11
|
||||
color: '#202020'
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
x: 10
|
||||
width: parent.width - 20
|
||||
height: 2
|
||||
anchors.topMargin: 0
|
||||
anchors.top: label.bottom
|
||||
color: '#808080'
|
||||
}
|
||||
}
|
||||
134
electrum/gui/qml/components/History.qml
Normal file
134
electrum/gui/qml/components/History.qml
Normal file
@@ -0,0 +1,134 @@
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls 2.0
|
||||
|
||||
Item {
|
||||
id: rootItem
|
||||
|
||||
property string title: 'History'
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
|
||||
ListView {
|
||||
width: parent.width
|
||||
height: 200
|
||||
|
||||
model: Daemon.currentWallet.historyModel
|
||||
delegate: Item {
|
||||
id: delegate
|
||||
width: ListView.view.width
|
||||
height: txinfo.height
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: delegate
|
||||
onClicked: extinfo.visible = !extinfo.visible
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
id: txinfo
|
||||
columns: 4
|
||||
|
||||
x: 6
|
||||
width: delegate.width - 12
|
||||
|
||||
Item {
|
||||
id: indicator
|
||||
Layout.fillHeight: true
|
||||
Layout.rowSpan: 2
|
||||
Rectangle {
|
||||
width: 3
|
||||
color: model.incoming ? 'green' : 'red'
|
||||
y: 2
|
||||
height: parent.height - 4
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
readonly property variant tx_icons : [
|
||||
"../../../gui/icons/unconfirmed.png",
|
||||
"../../../gui/icons/clock1.png",
|
||||
"../../../gui/icons/clock2.png",
|
||||
"../../../gui/icons/clock3.png",
|
||||
"../../../gui/icons/clock4.png",
|
||||
"../../../gui/icons/clock5.png",
|
||||
"../../../gui/icons/confirmed.png"
|
||||
]
|
||||
|
||||
sourceSize.width: 32
|
||||
sourceSize.height: 32
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
source: tx_icons[Math.min(6,model.confirmations)]
|
||||
}
|
||||
|
||||
Column {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
text: model.label !== '' ? model.label : '<no label>'
|
||||
color: model.label !== '' ? 'black' : 'gray'
|
||||
font.bold: model.label !== '' ? true : false
|
||||
}
|
||||
Label {
|
||||
font.pointSize: 7
|
||||
text: model.date
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: valuefee
|
||||
Label {
|
||||
text: model.bc_value
|
||||
font.bold: true
|
||||
}
|
||||
Label {
|
||||
font.pointSize: 6
|
||||
text: 'fee: ' + (model.fee !== undefined ? model.fee : '0')
|
||||
}
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
id: extinfo
|
||||
visible: false
|
||||
columns: 2
|
||||
Layout.columnSpan: 3
|
||||
|
||||
Label { text: 'txid' }
|
||||
Label {
|
||||
font.pointSize: 6
|
||||
text: model.txid
|
||||
elide: Text.ElideMiddle
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label { text: 'height' }
|
||||
Label {
|
||||
font.pointSize: 7
|
||||
text: model.height
|
||||
}
|
||||
Label { text: 'confirmations' }
|
||||
Label {
|
||||
font.pointSize: 7
|
||||
text: model.confirmations
|
||||
}
|
||||
Label { text: 'address' }
|
||||
Label {
|
||||
font.pointSize: 7
|
||||
elide: Text.ElideMiddle
|
||||
Layout.fillWidth: true
|
||||
text: {
|
||||
for (var i=0; i < Object.keys(model.outputs).length; i++) {
|
||||
if (model.outputs[i].value === model.bc_value) {
|
||||
return model.outputs[i].address
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // delegate
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
21
electrum/gui/qml/components/NetworkStats.qml
Normal file
21
electrum/gui/qml/components/NetworkStats.qml
Normal file
@@ -0,0 +1,21 @@
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Controls.Material 2.0
|
||||
|
||||
Item {
|
||||
property string title: qsTr('Network')
|
||||
|
||||
GridLayout {
|
||||
columns: 2
|
||||
|
||||
Label { text: qsTr("Server: "); color: Material.primaryHighlightedTextColor; font.bold: true }
|
||||
Label { text: Network.server }
|
||||
Label { text: qsTr("Local Height: "); color: Material.primaryHighlightedTextColor; font.bold: true }
|
||||
Label { text: Network.height }
|
||||
Label { text: qsTr("Status: "); color: Material.primaryHighlightedTextColor; font.bold: true }
|
||||
Label { text: Network.status }
|
||||
Label { text: qsTr("Wallet: "); color: Material.primaryHighlightedTextColor; font.bold: true }
|
||||
Label { text: Daemon.walletName }
|
||||
}
|
||||
}
|
||||
41
electrum/gui/qml/components/QRScan.qml
Normal file
41
electrum/gui/qml/components/QRScan.qml
Normal file
@@ -0,0 +1,41 @@
|
||||
import QtQuick 2.6
|
||||
import QtMultimedia 5.6
|
||||
|
||||
Item {
|
||||
|
||||
VideoOutput {
|
||||
id: vo
|
||||
anchors.fill: parent
|
||||
source: camera
|
||||
fillMode: VideoOutput.PreserveAspectCrop
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
vo.grabToImage(function(result) {
|
||||
console.log("grab: image=" + (result.image !== undefined) + " url=" + result.url)
|
||||
if (result.image !== undefined) {
|
||||
console.log('scanning image for QR')
|
||||
QR.scanImage(result.image)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Camera {
|
||||
id: camera
|
||||
deviceId: QtMultimedia.defaultCamera.deviceId
|
||||
viewfinder.resolution: "640x480"
|
||||
|
||||
function dumpstats() {
|
||||
console.log(camera.viewfinder.resolution)
|
||||
console.log(camera.viewfinder.minimumFrameRate)
|
||||
console.log(camera.viewfinder.maximumFrameRate)
|
||||
var resolutions = camera.supportedViewfinderResolutions()
|
||||
resolutions.forEach(function(item, i) {
|
||||
console.log('' + item.width + 'x' + item.height)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
23
electrum/gui/qml/components/Scan.qml
Normal file
23
electrum/gui/qml/components/Scan.qml
Normal file
@@ -0,0 +1,23 @@
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 2.0
|
||||
|
||||
Item {
|
||||
|
||||
property bool toolbar: false
|
||||
property string title: 'scan'
|
||||
|
||||
QRScan {
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: button.top
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
id: button
|
||||
anchors.bottom: parent.bottom
|
||||
text: 'Cancel'
|
||||
onClicked: app.stack.pop()
|
||||
}
|
||||
|
||||
}
|
||||
69
electrum/gui/qml/components/Send.qml
Normal file
69
electrum/gui/qml/components/Send.qml
Normal file
@@ -0,0 +1,69 @@
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
Item {
|
||||
id: rootItem
|
||||
|
||||
property string title: 'Send'
|
||||
|
||||
GridLayout {
|
||||
width: rootItem.width - 12
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
columns: 4
|
||||
|
||||
Label {
|
||||
Layout.columnSpan: 4
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "Current Balance: 0 mBTC"
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Recipient"
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: address
|
||||
Layout.columnSpan: 3
|
||||
placeholderText: 'Paste address or invoice'
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Amount"
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: amount
|
||||
placeholderText: 'Amount'
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Fee"
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: fee
|
||||
placeholderText: 'sat/vB'
|
||||
}
|
||||
|
||||
Column {
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 4
|
||||
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: 'Pay'
|
||||
onClicked: {
|
||||
var i_amount = parseInt(amount.text)
|
||||
if (isNaN(i_amount))
|
||||
return
|
||||
var result = Daemon.currentWallet.send_onchain(address.text, i_amount, undefined, false)
|
||||
if (result)
|
||||
app.stack.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
property bool toolbar: false
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: '#111144'
|
||||
32
electrum/gui/qml/components/Wallets.qml
Normal file
32
electrum/gui/qml/components/Wallets.qml
Normal file
@@ -0,0 +1,32 @@
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls 2.0
|
||||
|
||||
Item {
|
||||
property string title: 'Wallets'
|
||||
|
||||
ListView {
|
||||
width: parent.width
|
||||
height: 200
|
||||
model: Daemon.activeWallets
|
||||
|
||||
delegate: Item {
|
||||
width: ListView.view.width
|
||||
|
||||
RowLayout {
|
||||
x: 20
|
||||
spacing: 20
|
||||
|
||||
Image {
|
||||
source: "../../../gui/kivy/theming/light/wallet.png"
|
||||
}
|
||||
|
||||
Label {
|
||||
font.pointSize: 13
|
||||
text: model.display
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,62 +1,31 @@
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQml 2.6
|
||||
|
||||
Item {
|
||||
property string title: 'Network'
|
||||
|
||||
property QtObject menu: Menu {
|
||||
MenuItem { text: 'Wallets'; onTriggered: stack.push(Qt.resolvedUrl('Wallets.qml')) }
|
||||
MenuItem { text: 'Network'; onTriggered: stack.push(Qt.resolvedUrl('NetworkStats.qml')) }
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
|
||||
EHeader {
|
||||
text: "Network"
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
Row {
|
||||
Text { text: "Server: " }
|
||||
Text { text: Network.server }
|
||||
}
|
||||
Row {
|
||||
Text { text: "Local Height: " }
|
||||
Text { text: Network.height }
|
||||
}
|
||||
Row {
|
||||
Text { text: "Status: " }
|
||||
Text { text: Network.status }
|
||||
}
|
||||
Row {
|
||||
Text { text: "Wallet: " }
|
||||
Text { text: Daemon.walletName }
|
||||
}
|
||||
|
||||
EButton {
|
||||
Button {
|
||||
text: 'Scan QR Code'
|
||||
onClicked: app.stack.push(Qt.resolvedUrl('scan.qml'))
|
||||
onClicked: app.stack.push(Qt.resolvedUrl('Scan.qml'))
|
||||
}
|
||||
|
||||
EButton {
|
||||
text: 'Show TXen'
|
||||
onClicked: app.stack.push(Qt.resolvedUrl('tx.qml'))
|
||||
Button {
|
||||
text: 'Send'
|
||||
onClicked: app.stack.push(Qt.resolvedUrl('Send.qml'))
|
||||
}
|
||||
|
||||
ListView {
|
||||
width: parent.width
|
||||
height: 200
|
||||
model: Daemon.activeWallets
|
||||
delegate: Item {
|
||||
width: parent.width
|
||||
|
||||
Row {
|
||||
Rectangle {
|
||||
width: 10
|
||||
height: parent.height
|
||||
color: 'red'
|
||||
}
|
||||
Text {
|
||||
leftPadding: 20
|
||||
text: model.display
|
||||
}
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: 'Show TX History'
|
||||
onClicked: app.stack.push(Qt.resolvedUrl('History.qml'))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls.Material 2.0
|
||||
|
||||
import QtQml 2.6
|
||||
import QtMultimedia 5.6
|
||||
|
||||
@@ -9,22 +12,64 @@ ApplicationWindow
|
||||
visible: true
|
||||
width: 480
|
||||
height: 800
|
||||
color: '#dddddd'
|
||||
|
||||
Material.theme: Material.Dark
|
||||
Material.primary: Material.Indigo
|
||||
Material.accent: Material.LightBlue
|
||||
|
||||
property alias stack: mainStackView
|
||||
|
||||
header: ToolBar {
|
||||
id: toolbar
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
ToolButton {
|
||||
text: qsTr("‹")
|
||||
enabled: stack.currentItem.StackView.index > 0
|
||||
onClicked: stack.pop()
|
||||
}
|
||||
Label {
|
||||
text: stack.currentItem.title
|
||||
elide: Label.ElideRight
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
ToolButton {
|
||||
text: qsTr("⋮")
|
||||
onClicked: {
|
||||
stack.currentItem.menu.open()
|
||||
// position the menu to the right
|
||||
stack.currentItem.menu.x = toolbar.width - stack.currentItem.menu.width
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StackView {
|
||||
id: mainStackView
|
||||
anchors.fill: parent
|
||||
|
||||
initialItem: Qt.resolvedUrl('splash.qml')
|
||||
initialItem: Qt.resolvedUrl('landing.qml')
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: splashTimer
|
||||
interval: 400
|
||||
interval: 1000
|
||||
onTriggered: {
|
||||
mainStackView.push(Qt.resolvedUrl('landing.qml'))
|
||||
splash.opacity = 0
|
||||
}
|
||||
}
|
||||
|
||||
Splash {
|
||||
id: splash
|
||||
anchors.top: header.top
|
||||
anchors.bottom: app.contentItem.bottom
|
||||
width: app.width
|
||||
z: 1000
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 300 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
import QtQuick 2.6
|
||||
import QtMultimedia 5.6
|
||||
|
||||
|
||||
Item {
|
||||
Column {
|
||||
width: parent.width
|
||||
|
||||
EHeader {
|
||||
text: "Scan QR Code"
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
Item {
|
||||
id: voc
|
||||
width: parent.width
|
||||
height: parent.width
|
||||
|
||||
VideoOutput {
|
||||
id: vo
|
||||
anchors.fill: parent
|
||||
source: camera
|
||||
//fillMode: VideoOutput.PreserveAspectCrop
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
vo.grabToImage(function(result) {
|
||||
console.log("grab: image=" + (result.image !== undefined) + " url=" + result.url)
|
||||
if (result.image !== undefined) {
|
||||
console.log('scanning image for QR')
|
||||
QR.scanImage(result.image)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EButton {
|
||||
text: 'Exit'
|
||||
onClicked: app.stack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
Camera {
|
||||
id: camera
|
||||
deviceId: QtMultimedia.defaultCamera.deviceId
|
||||
viewfinder.resolution: "640x480"
|
||||
|
||||
function dumpstats() {
|
||||
console.log(camera.viewfinder.resolution)
|
||||
console.log(camera.viewfinder.minimumFrameRate)
|
||||
console.log(camera.viewfinder.maximumFrameRate)
|
||||
var resolutions = camera.supportedViewfinderResolutions()
|
||||
resolutions.forEach(function(item, i) {
|
||||
console.log('' + item.width + 'x' + item.height)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
import QtQuick 2.6
|
||||
|
||||
Item {
|
||||
id: rootItem
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
|
||||
EHeader {
|
||||
text: "History"
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
ListView {
|
||||
width: parent.width
|
||||
height: 200
|
||||
|
||||
model: Daemon.currentWallet.historyModel
|
||||
delegate: Item {
|
||||
id: delegate
|
||||
width: parent.width
|
||||
height: txinfo.height
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: delegate
|
||||
onClicked: extinfo.visible = !extinfo.visible
|
||||
}
|
||||
|
||||
Row {
|
||||
id: txinfo
|
||||
Rectangle {
|
||||
width: 4
|
||||
height: parent.height
|
||||
color: model.incoming ? 'green' : 'red'
|
||||
}
|
||||
|
||||
Column {
|
||||
|
||||
Row {
|
||||
id: baseinfo
|
||||
spacing: 10
|
||||
|
||||
|
||||
Image {
|
||||
readonly property variant tx_icons : [
|
||||
"../../icons/unconfirmed.png",
|
||||
"../../icons/clock1.png",
|
||||
"../../icons/clock2.png",
|
||||
"../../icons/clock3.png",
|
||||
"../../icons/clock4.png",
|
||||
"../../icons/clock5.png",
|
||||
"../../icons/confirmed.png"
|
||||
]
|
||||
|
||||
width: 32
|
||||
height: 32
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
source: tx_icons[Math.min(6,Math.floor(model.confirmations/20))]
|
||||
}
|
||||
|
||||
Column {
|
||||
id: content
|
||||
width: delegate.width - x - valuefee.width
|
||||
|
||||
Text {
|
||||
text: model.label !== '' ? model.label : '<no label>'
|
||||
color: model.label !== '' ? 'black' : 'gray'
|
||||
}
|
||||
Text {
|
||||
font.pointSize: 7
|
||||
text: model.date
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: valuefee
|
||||
width: delegate.width * 0.25
|
||||
Text {
|
||||
text: model.bc_value
|
||||
}
|
||||
Text {
|
||||
font.pointSize: 7
|
||||
text: 'fee: ' + (model.fee !== undefined ? model.fee : '0')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: extinfo
|
||||
visible: false
|
||||
|
||||
Column {
|
||||
id: extinfoinner
|
||||
Text {
|
||||
font.pointSize: 6
|
||||
text: 'txid: ' + model.txid
|
||||
}
|
||||
Text {
|
||||
font.pointSize: 7
|
||||
text: 'height: ' + model.height
|
||||
}
|
||||
Text {
|
||||
font.pointSize: 7
|
||||
text: 'confirmations: ' + model.confirmations
|
||||
}
|
||||
Text {
|
||||
font.pointSize: 7
|
||||
text: {
|
||||
for (var i=0; i < Object.keys(model.outputs).length; i++) {
|
||||
if (model.outputs[i].value === model.bc_value) {
|
||||
return 'address: ' + model.outputs[i].address
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
} // delegate
|
||||
}
|
||||
|
||||
EButton {
|
||||
text: 'Back'
|
||||
onClicked: app.stack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user