Upload DragonDisplayPicker.qml
This commit is contained in:
parent
1c9bc1e670
commit
9fcfe8c6c8
1 changed files with 203 additions and 0 deletions
203
app/gui/DragonDisplayPicker.qml
Normal file
203
app/gui/DragonDisplayPicker.qml
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
// DragonDisplayPicker.qml
|
||||
//
|
||||
// Multi-display picker component for streaming to a specific monitor on a remote host.
|
||||
// Shows a modal overlay with a list of available displays and lets the user select one.
|
||||
//
|
||||
// Usage:
|
||||
// DragonDisplayPicker {
|
||||
// visible: showDisplayPicker
|
||||
// anchors.fill: parent
|
||||
// hostIP: pickerHostIP
|
||||
// hostName: pickerHostName
|
||||
// displays: pickerDisplays
|
||||
// onDisplaySelected: function(idx) {
|
||||
// showDisplayPicker = false
|
||||
// dragonRelay.streamHostDisplay(pickerHostIP, idx)
|
||||
// }
|
||||
// onCancelled: { showDisplayPicker = false }
|
||||
// }
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string hostIP: ""
|
||||
property string hostName: ""
|
||||
property var displays: [] // array of display maps
|
||||
|
||||
signal displaySelected(int displayIndex)
|
||||
signal cancelled()
|
||||
|
||||
// ── Modal backdrop ─────────────────────────────────────────────────────
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "rgba(0, 0, 0, 0.7)"
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: root.cancelled()
|
||||
}
|
||||
}
|
||||
|
||||
// ── Dialog box ─────────────────────────────────────────────────────────
|
||||
|
||||
Rectangle {
|
||||
id: dialogBox
|
||||
anchors.centerIn: parent
|
||||
width: Math.min(parent.width - 48, 500)
|
||||
height: Math.min(parent.height - 48, 400)
|
||||
radius: 12
|
||||
color: "#0f172a" // dark blue slate
|
||||
border.color: "#374151"
|
||||
border.width: 1
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 20
|
||||
spacing: 16
|
||||
|
||||
// ── Title ──────────────────────────────────────────────────────
|
||||
|
||||
Label {
|
||||
text: qsTr("Select Display")
|
||||
font.pixelSize: 18
|
||||
font.bold: true
|
||||
color: "white"
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Host: %1 (%2)").arg(root.hostName).arg(root.hostIP)
|
||||
font.pixelSize: 12
|
||||
color: "#9ca3af"
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
// ── Divider ────────────────────────────────────────────────────
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
height: 1
|
||||
color: "#374151"
|
||||
}
|
||||
|
||||
// ── Display list ───────────────────────────────────────────────
|
||||
|
||||
ListView {
|
||||
id: displayList
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: 8
|
||||
clip: true
|
||||
|
||||
model: root.displays
|
||||
|
||||
delegate: Rectangle {
|
||||
width: displayList.width
|
||||
height: 56
|
||||
radius: 8
|
||||
color: displayMouse.containsMouse ? "#374151" : "#1f2937"
|
||||
border.color: displayMouse.containsMouse ? "#4b5563" : "transparent"
|
||||
border.width: 1
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
spacing: 12
|
||||
|
||||
Column {
|
||||
spacing: 2
|
||||
|
||||
Label {
|
||||
text: modelData.friendlyName || modelData.name
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
color: "white"
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("%1x%2").arg(modelData.width).arg(modelData.height)
|
||||
font.pixelSize: 11
|
||||
color: "#9ca3af"
|
||||
}
|
||||
}
|
||||
|
||||
Item { Layout.fillWidth: true }
|
||||
|
||||
Rectangle {
|
||||
visible: modelData.isPrimary
|
||||
width: primaryLabel.implicitWidth + 12
|
||||
height: 20
|
||||
radius: 4
|
||||
color: "#10b981" // green
|
||||
|
||||
Label {
|
||||
id: primaryLabel
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("Primary")
|
||||
font.pixelSize: 10
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: displayMouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
root.displaySelected(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Empty state message
|
||||
Label {
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("No displays available")
|
||||
color: "#9ca3af"
|
||||
font.pixelSize: 12
|
||||
visible: displayList.count === 0
|
||||
}
|
||||
}
|
||||
|
||||
// ── Divider ────────────────────────────────────────────────────
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
height: 1
|
||||
color: "#374151"
|
||||
}
|
||||
|
||||
// ── Buttons ────────────────────────────────────────────────────
|
||||
|
||||
RowLayout {
|
||||
spacing: 12
|
||||
Layout.fillWidth: true
|
||||
|
||||
Item { Layout.fillWidth: true }
|
||||
|
||||
Button {
|
||||
text: qsTr("Cancel")
|
||||
flat: true
|
||||
onClicked: root.cancelled()
|
||||
}
|
||||
|
||||
Button {
|
||||
text: qsTr("Select")
|
||||
enabled: displayList.currentIndex >= 0
|
||||
onClicked: {
|
||||
if (displayList.currentIndex >= 0) {
|
||||
root.displaySelected(displayList.currentIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue