Files

232 lines
9.0 KiB
QML
Raw Permalink Normal View History

2026-02-15 22:16:51 +01:00
import QtQuick
Item {
2026-03-08 22:40:30 +01:00
property bool hideQRScanButton: true
property bool combineWallets: allWalletsEntrySelected
onCombineWalletsChanged: {
tokens.combineWallets = combineWallets
}
2026-02-15 22:16:51 +01:00
Flickable {
id: canvas
anchors.fill: parent
boundsBehavior: Flickable.StopAtBounds
2026-02-15 22:16:51 +01:00
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
2026-03-07 15:40:13 +01:00
color: palette.alternateBase
2026-02-15 22:16:51 +01:00
}
}
Repeater {
model: canvas.editable ? tokensLayout.rowCount + 1 : 0
delegate: Rectangle {
y: index * (parent.height / tokensLayout.rowCount)
width: parent.width
height: 1
2026-03-07 15:40:13 +01:00
color: palette.alternateBase
2026-02-15 22:16:51 +01:00
}
}
// 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
2026-02-15 22:16:51 +01:00
// 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
2026-03-07 23:55:20 +01:00
source: modelData.source
2026-02-17 21:00:12 +01:00
clip: true
2026-02-15 22:16:51 +01:00
}
2026-03-07 15:40:13 +01:00
// Drag the widget
2026-02-15 22:16:51 +01:00
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))
2026-02-15 22:16:51 +01:00
candidateRow = Math.max(0, Math.min(candidateRow,
tokensLayout.rowCount - modelData.rowSpan))
2026-02-15 22:16:51 +01:00
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
2026-02-15 22:16:51 +01:00
canvas.interactive = true
}
}
2026-03-07 15:40:13 +01:00
// Resize handle
2026-02-15 22:16:51 +01:00
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"
2026-03-07 15:40:13 +01:00
visible: false // disable configurability for now.
2026-02-15 22:16:51 +01:00
MouseArea {
anchors.fill: parent
onClicked: {
canvas.editable = !canvas.editable
activityTabs.interactive = !activityTabs.interactive
if (canvas.editable)
tokensLayout.rowCount += 12
else
tokensLayout.trimRows()
}
}
}
2026-03-07 15:40:13 +01:00
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
}
}
}
2026-02-15 22:16:51 +01:00
}