18adf5f63f
And the planned payments tab on mobile uses it to filter on the selected wallet. Or show for all wallets.
232 lines
9.0 KiB
QML
232 lines
9.0 KiB
QML
import QtQuick
|
|
|
|
Item {
|
|
property bool hideQRScanButton: true
|
|
property bool combineWallets: allWalletsEntrySelected
|
|
onCombineWalletsChanged: {
|
|
tokens.combineWallets = combineWallets
|
|
}
|
|
|
|
Flickable {
|
|
id: canvas
|
|
anchors.fill: parent
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
property bool editable: false
|
|
|
|
property real cellWidth: parent.width / tokensLayout.screenColumnCount
|
|
property real cellHeight: parent.height / tokensLayout.screenRowCount
|
|
contentWidth: cellWidth * tokensLayout.screenColumnCount
|
|
contentHeight: cellHeight * tokensLayout.rowCount
|
|
|
|
Repeater {
|
|
model: canvas.editable ? tokensLayout.screenColumnCount + 1 : 0
|
|
delegate: Rectangle {
|
|
x: index * (parent.width / tokensLayout.screenColumnCount)
|
|
width: 1
|
|
height: parent.height
|
|
color: palette.alternateBase
|
|
}
|
|
}
|
|
Repeater {
|
|
model: canvas.editable ? tokensLayout.rowCount + 1 : 0
|
|
delegate: Rectangle {
|
|
y: index * (parent.height / tokensLayout.rowCount)
|
|
width: parent.width
|
|
height: 1
|
|
color: palette.alternateBase
|
|
}
|
|
}
|
|
|
|
// Interactive widgets
|
|
Repeater {
|
|
model: tokensLayout.widgets
|
|
|
|
delegate: Item {
|
|
id: container
|
|
z: dragArea.pressed || resizeArea.pressed ? 100 : 1
|
|
|
|
property real cellWidth: canvas.cellWidth
|
|
property real cellHeight: canvas.cellHeight
|
|
|
|
x: modelData.col * cellWidth
|
|
y: modelData.row * cellHeight
|
|
width: modelData.colSpan * cellWidth
|
|
height: modelData.rowSpan * cellHeight
|
|
|
|
// Visual border (highlight when interacting)
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: "transparent"
|
|
border.color: (dragArea.pressed || resizeArea.pressed) ? "blue" : "gray"
|
|
border.width: 2
|
|
radius: 8
|
|
visible: canvas.editable
|
|
}
|
|
|
|
Loader {
|
|
anchors.fill: parent
|
|
anchors.margins: 8
|
|
source: modelData.source
|
|
clip: true
|
|
}
|
|
|
|
// Drag the widget
|
|
MouseArea {
|
|
id: dragArea
|
|
anchors.fill: parent
|
|
enabled: canvas.editable
|
|
cursorShape: pressed ? Qt.ClosedHandCursor : Qt.OpenHandCursor
|
|
|
|
property point grabOffset: Qt.point(0, 0)
|
|
|
|
onPressed: (mouse) => {
|
|
var pressGlobal = dragArea.mapToItem(container.parent, mouse.x, mouse.y)
|
|
grabOffset = Qt.point(pressGlobal.x - container.x, pressGlobal.y - container.y)
|
|
canvas.interactive = false
|
|
}
|
|
|
|
onPositionChanged: (mouse) => {
|
|
if (pressed) {
|
|
var currentGlobal = dragArea.mapToItem(container.parent, mouse.x, mouse.y)
|
|
|
|
// Desired position if no snap (grabbed point follows cursor exactly)
|
|
var desiredX = currentGlobal.x - grabOffset.x
|
|
var desiredY = currentGlobal.y - grabOffset.y
|
|
|
|
// Live snap to grid
|
|
var candidateCol = Math.round(desiredX / cellWidth)
|
|
var candidateRow = Math.round(desiredY / cellHeight)
|
|
|
|
// Clamp to keep widget fully inside grid
|
|
candidateCol = Math.max(0, Math.min(candidateCol,
|
|
tokensLayout.screenColumnCount - modelData.colSpan))
|
|
candidateRow = Math.max(0, Math.min(candidateRow,
|
|
tokensLayout.rowCount - modelData.rowSpan))
|
|
|
|
container.x = candidateCol * cellWidth
|
|
container.y = candidateRow * cellHeight
|
|
}
|
|
}
|
|
|
|
onReleased: {
|
|
// Update backend to final snapped position
|
|
var finalCol = Math.round(container.x / cellWidth)
|
|
var finalRow = Math.round(container.y / cellHeight)
|
|
modelData.col = finalCol
|
|
modelData.row = finalRow
|
|
canvas.interactive = true
|
|
}
|
|
}
|
|
|
|
// Resize handle
|
|
Rectangle {
|
|
id: resizeHandle
|
|
width: 24
|
|
height: 24
|
|
anchors.right: parent.right
|
|
anchors.bottom: parent.bottom
|
|
anchors.margins: -8
|
|
color: "#80ffffff"
|
|
radius: 4
|
|
border.color: "#666666"
|
|
border.width: 1
|
|
visible: canvas.editable
|
|
|
|
// Grip visual
|
|
Repeater {
|
|
model: 3
|
|
Rectangle {
|
|
width: 4
|
|
height: 4
|
|
color: "#666666"
|
|
x: 4 + index * 5
|
|
y: 4 + index * 5
|
|
}
|
|
}
|
|
|
|
MouseArea {
|
|
id: resizeArea
|
|
anchors.fill: parent
|
|
cursorShape: Qt.SizeFDiagCursor
|
|
enabled: canvas.editable
|
|
|
|
property real startWidth: 0
|
|
property real startHeight: 0
|
|
property point pressMousePos: Qt.point(0, 0)
|
|
|
|
onPressed: (mouse) => {
|
|
startWidth = container.width
|
|
startHeight = container.height
|
|
pressMousePos = resizeArea.mapToItem(container.parent, mouse.x, mouse.y)
|
|
canvas.interactive = false
|
|
}
|
|
|
|
onPositionChanged: (mouse) => {
|
|
if (pressed) {
|
|
var currentMousePos = resizeArea.mapToItem(container.parent, mouse.x, mouse.y)
|
|
|
|
var deltaX = currentMousePos.x - pressMousePos.x
|
|
var deltaY = currentMousePos.y - pressMousePos.y
|
|
|
|
var newPixelWidth = startWidth + deltaX
|
|
var newPixelHeight = startHeight + deltaY
|
|
|
|
// Enforce minimum before snapping
|
|
newPixelWidth = Math.max(newPixelWidth, model.minimumWidth * cellWidth)
|
|
newPixelHeight = Math.max(newPixelHeight, model.minimumHeight * cellHeight)
|
|
|
|
// Live snap to grid units
|
|
var candColSpan = Math.round(newPixelWidth / cellWidth)
|
|
var candRowSpan = Math.round(newPixelHeight / cellHeight)
|
|
|
|
// Clamp to grid bounds
|
|
candColSpan = Math.min(candColSpan, tokensLayout.screenColumnCount - model.col)
|
|
candRowSpan = Math.min(candRowSpan, tokensLayout.rowCount - model.row)
|
|
|
|
container.width = candColSpan * cellWidth
|
|
container.height = candRowSpan * cellHeight
|
|
}
|
|
}
|
|
|
|
onReleased: {
|
|
var finalColSpan = container.width / cellWidth
|
|
var finalRowSpan = container.height / cellHeight
|
|
|
|
model.colSpan = finalColSpan
|
|
model.rowSpan = finalRowSpan
|
|
canvas.interactive = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Rectangle {
|
|
width: 50
|
|
height: 20
|
|
anchors.right: parent.right
|
|
color: "blue"
|
|
visible: false // disable configurability for now.
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: {
|
|
canvas.editable = !canvas.editable
|
|
activityTabs.interactive = !activityTabs.interactive
|
|
if (canvas.editable)
|
|
tokensLayout.rowCount += 12
|
|
else
|
|
tokensLayout.trimRows()
|
|
}
|
|
}
|
|
}
|
|
Keys.onPressed: (event)=> {
|
|
if (event.key === Qt.Key_Escape || event.key === Qt.Key_Back) {
|
|
if (canvas.editable) {
|
|
event.accepted = true
|
|
canvas.editable = false
|
|
activityTabs.interactive = true
|
|
}
|
|
}
|
|
}
|
|
}
|