|
|
@@ -15,6 +15,17 @@ Rectangle {
|
|
|
signal modeButtonClicked()
|
|
|
signal sendButtonClicked(string text)
|
|
|
signal settingsButtonClicked()
|
|
|
+ signal exhibitionButtonClicked()
|
|
|
+ signal setExhibitionVolume(int volume)
|
|
|
+ signal toggleExhibitionLight(string deviceKey, bool on)
|
|
|
+ signal controlAllTvs(string action)
|
|
|
+ signal setWelcomeMode(bool on)
|
|
|
+ signal setDoorMode(int mode)
|
|
|
+ signal setCeilingLightLevel(int level)
|
|
|
+ signal restartAllDevices()
|
|
|
+ signal videoButtonClicked()
|
|
|
+ signal playVideo(int videoId)
|
|
|
+
|
|
|
// 标题栏相关信号
|
|
|
signal titleMinimize()
|
|
|
signal titleClose()
|
|
|
@@ -30,8 +41,8 @@ Rectangle {
|
|
|
parent: root
|
|
|
x: (root.width - width) / 2
|
|
|
y: (root.height - height) / 2
|
|
|
- modal: true
|
|
|
- focus: true
|
|
|
+ modal: false // 改为非模态,允许同时输入
|
|
|
+ focus: false // 不自动获取焦点,防止打断输入
|
|
|
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
|
|
|
|
|
background: Rectangle {
|
|
|
@@ -112,6 +123,649 @@ Rectangle {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 重启确认弹窗
|
|
|
+ Popup {
|
|
|
+ id: restartConfirmPopup
|
|
|
+ width: 400
|
|
|
+ height: 240
|
|
|
+ parent: root
|
|
|
+ x: (root.width - width) / 2
|
|
|
+ y: (root.height - height) / 2
|
|
|
+ modal: true
|
|
|
+ focus: true
|
|
|
+ closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
|
|
+
|
|
|
+ background: Rectangle {
|
|
|
+ color: "white"
|
|
|
+ radius: 12
|
|
|
+ border.color: "#ffccc7"
|
|
|
+ border.width: 1
|
|
|
+ layer.enabled: true
|
|
|
+ layer.effect: DropShadow {
|
|
|
+ transparentBorder: true
|
|
|
+ horizontalOffset: 0
|
|
|
+ verticalOffset: 4
|
|
|
+ radius: 16
|
|
|
+ samples: 25
|
|
|
+ color: "#40000000"
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ColumnLayout {
|
|
|
+ anchors.fill: parent
|
|
|
+ anchors.margins: 24
|
|
|
+ spacing: 20
|
|
|
+
|
|
|
+ Text {
|
|
|
+ text: "⚠️ 警告"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 22
|
|
|
+ color: "#cf1322"
|
|
|
+ Layout.alignment: Qt.AlignHCenter
|
|
|
+ }
|
|
|
+
|
|
|
+ Text {
|
|
|
+ text: "检测到设备可能出现异常,建议重启展厅所有设备进行恢复,是否现在执行重启?\n(全程约需 1 分钟,请耐心等待)"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.pixelSize: 15
|
|
|
+ color: "#333"
|
|
|
+ wrapMode: Text.WordWrap
|
|
|
+ Layout.fillWidth: true
|
|
|
+ horizontalAlignment: Text.AlignHCenter
|
|
|
+ }
|
|
|
+
|
|
|
+ RowLayout {
|
|
|
+ Layout.alignment: Qt.AlignHCenter
|
|
|
+ spacing: 20
|
|
|
+
|
|
|
+ Button {
|
|
|
+ text: "取消"
|
|
|
+ Layout.preferredWidth: 100
|
|
|
+ Layout.preferredHeight: 40
|
|
|
+ background: Rectangle { color: parent.pressed ? "#e5e6eb" : "#f2f3f5"; radius: 6 }
|
|
|
+ contentItem: Text { text: parent.text; font.family: "PingFang SC"; font.pixelSize: 14; color: "#4e5969"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: restartConfirmPopup.close()
|
|
|
+ }
|
|
|
+
|
|
|
+ Button {
|
|
|
+ text: "确认重启"
|
|
|
+ Layout.preferredWidth: 100
|
|
|
+ Layout.preferredHeight: 40
|
|
|
+ background: Rectangle { color: parent.pressed ? "#ffccc7" : "#cf1322"; radius: 6 }
|
|
|
+ contentItem: Text { text: parent.text; font.family: "PingFang SC"; font.weight: Font.Bold; font.pixelSize: 14; color: "white"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: {
|
|
|
+ root.restartAllDevices()
|
|
|
+ restartConfirmPopup.close()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 视频列表弹窗
|
|
|
+ Popup {
|
|
|
+ id: videoPopup
|
|
|
+ width: root.width * 0.9
|
|
|
+ height: root.height * 0.8 // 高度也适应主界面
|
|
|
+ parent: root
|
|
|
+ x: (root.width - width) / 2
|
|
|
+ y: (root.height - height) / 2
|
|
|
+ modal: true
|
|
|
+ focus: true
|
|
|
+ closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
|
|
+
|
|
|
+ onOpened: root.videoButtonClicked()
|
|
|
+
|
|
|
+ background: Rectangle {
|
|
|
+ color: "white"
|
|
|
+ radius: 16
|
|
|
+ border.color: "#e5e6eb"
|
|
|
+ border.width: 1
|
|
|
+ layer.enabled: true
|
|
|
+ layer.effect: DropShadow {
|
|
|
+ transparentBorder: true
|
|
|
+ horizontalOffset: 0
|
|
|
+ verticalOffset: 4
|
|
|
+ radius: 20
|
|
|
+ samples: 25
|
|
|
+ color: "#40000000"
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ColumnLayout {
|
|
|
+ anchors.fill: parent
|
|
|
+ anchors.margins: 24
|
|
|
+ spacing: 20
|
|
|
+
|
|
|
+ Text {
|
|
|
+ text: "视频播放列表"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 28
|
|
|
+ color: "#faad14"
|
|
|
+ Layout.alignment: Qt.AlignHCenter
|
|
|
+ }
|
|
|
+
|
|
|
+ // 动态计算卡片尺寸(单行铺满,强制不滑动)
|
|
|
+ property int totalItems: displayModel && displayModel.videoList && displayModel.videoList.length > 0 ? displayModel.videoList.length : 1
|
|
|
+ property real cardSpacing: 16
|
|
|
+ property real availableWidth: videoPopup.contentItem.width - 48 // 减去弹窗左右 margin
|
|
|
+
|
|
|
+ // 宽度:平分剩余空间
|
|
|
+ property real cardWidth: (availableWidth - (totalItems - 1) * cardSpacing) / totalItems
|
|
|
+
|
|
|
+ // 高度:设置为竖向长方形(类似扑克牌),或者根据宽度自适应,但受限于弹窗高度
|
|
|
+ // 预留顶部标题和底部关闭按钮的高度 (约 120px)
|
|
|
+ property real maxCardHeight: videoPopup.contentItem.height - 120
|
|
|
+ property real cardHeight: Math.min(cardWidth * 1.5, maxCardHeight)
|
|
|
+
|
|
|
+ ListView {
|
|
|
+ id: videoListView
|
|
|
+ Layout.fillWidth: true
|
|
|
+ Layout.fillHeight: true
|
|
|
+ orientation: ListView.Horizontal
|
|
|
+ spacing: parent.cardSpacing
|
|
|
+ clip: true
|
|
|
+ interactive: false // 禁止滑动
|
|
|
+
|
|
|
+ model: displayModel ? displayModel.videoList : []
|
|
|
+
|
|
|
+ // 垂直居中
|
|
|
+ Layout.alignment: Qt.AlignVCenter
|
|
|
+
|
|
|
+ delegate: Rectangle {
|
|
|
+ width: videoListView.parent.cardWidth
|
|
|
+ height: videoListView.parent.cardHeight
|
|
|
+ // 垂直居中于 ListView
|
|
|
+ y: (videoListView.height - height) / 2
|
|
|
+
|
|
|
+ radius: 12
|
|
|
+ color: {
|
|
|
+ var colors = ["#fff1b8", "#e6f7ff", "#d9f7be", "#efdbff", "#ffccc7", "#fff0f6"];
|
|
|
+ return colors[index % colors.length];
|
|
|
+ }
|
|
|
+ border.width: 1
|
|
|
+ border.color: "#f0f0f0"
|
|
|
+
|
|
|
+ // 视频标题
|
|
|
+ Text {
|
|
|
+ anchors.centerIn: parent
|
|
|
+ width: parent.width - 16
|
|
|
+ height: parent.height - 16
|
|
|
+ text: modelData.name || "未知视频"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ // 字体大小自适应:根据卡片尺寸动态计算,确保尽量大
|
|
|
+ font.pixelSize: Math.max(14, Math.min(parent.width, parent.height / 2) * 0.25)
|
|
|
+ color: "#1d2129"
|
|
|
+ wrapMode: Text.Wrap
|
|
|
+ horizontalAlignment: Text.AlignHCenter
|
|
|
+ verticalAlignment: Text.AlignVCenter
|
|
|
+ maximumLineCount: 5
|
|
|
+ elide: Text.ElideRight
|
|
|
+ }
|
|
|
+
|
|
|
+ MouseArea {
|
|
|
+ anchors.fill: parent
|
|
|
+ hoverEnabled: true
|
|
|
+ cursorShape: Qt.PointingHandCursor
|
|
|
+ onClicked: {
|
|
|
+ root.playVideo(modelData.id)
|
|
|
+ videoPopup.close()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 悬停动画
|
|
|
+ scale: MouseArea.containsMouse ? 1.05 : 1.0
|
|
|
+ Behavior on scale { NumberAnimation { duration: 150 } }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Button {
|
|
|
+ text: "关闭"
|
|
|
+ Layout.alignment: Qt.AlignHCenter
|
|
|
+ Layout.preferredWidth: 120
|
|
|
+ Layout.preferredHeight: 48
|
|
|
+ background: Rectangle { color: parent.pressed ? "#e5e6eb" : "#f2f3f5"; radius: 8 }
|
|
|
+ contentItem: Text { text: parent.text; font.pixelSize: 16; color: "#1d2129"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: videoPopup.close()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 展厅控制弹窗
|
|
|
+ Popup {
|
|
|
+ id: exhibitionControlPopup
|
|
|
+ width: root.width * 0.8
|
|
|
+ height: root.height * 0.8
|
|
|
+ parent: root
|
|
|
+ x: (root.width - width) / 2
|
|
|
+ y: (root.height - height) / 2
|
|
|
+ modal: true
|
|
|
+ focus: true
|
|
|
+ closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
|
|
+
|
|
|
+ onOpened: root.exhibitionButtonClicked()
|
|
|
+
|
|
|
+ background: Rectangle {
|
|
|
+ color: "white"
|
|
|
+ radius: 16
|
|
|
+ border.color: "#e5e6eb"
|
|
|
+ border.width: 1
|
|
|
+ layer.enabled: true
|
|
|
+ layer.effect: DropShadow {
|
|
|
+ transparentBorder: true
|
|
|
+ horizontalOffset: 0
|
|
|
+ verticalOffset: 4
|
|
|
+ radius: 20
|
|
|
+ samples: 25
|
|
|
+ color: "#40000000"
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ColumnLayout {
|
|
|
+ anchors.fill: parent
|
|
|
+ anchors.margins: 24
|
|
|
+ spacing: 20
|
|
|
+
|
|
|
+ Text {
|
|
|
+ text: "展厅控制中心"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 24
|
|
|
+ color: "#1d2129"
|
|
|
+ Layout.alignment: Qt.AlignHCenter
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分割线
|
|
|
+ Rectangle { Layout.fillWidth: true; height: 1; color: "#f2f3f5" }
|
|
|
+
|
|
|
+ // 第一栏:全局音量
|
|
|
+ RowLayout {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ spacing: 20
|
|
|
+
|
|
|
+ Text {
|
|
|
+ text: "全局音量"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 20
|
|
|
+ color: "#333"
|
|
|
+ Layout.preferredWidth: 80
|
|
|
+ }
|
|
|
+
|
|
|
+ Slider {
|
|
|
+ id: volumeSlider
|
|
|
+ Layout.fillWidth: true
|
|
|
+ from: 0
|
|
|
+ to: 100
|
|
|
+ stepSize: 1
|
|
|
+ value: displayModel ? displayModel.exhibitionVolume : 50
|
|
|
+ onMoved: root.setExhibitionVolume(value)
|
|
|
+
|
|
|
+ background: Rectangle {
|
|
|
+ x: volumeSlider.leftPadding
|
|
|
+ y: volumeSlider.topPadding + volumeSlider.availableHeight / 2 - height / 2
|
|
|
+ implicitWidth: 200
|
|
|
+ implicitHeight: 12
|
|
|
+ width: volumeSlider.availableWidth
|
|
|
+ height: implicitHeight
|
|
|
+ radius: 6
|
|
|
+ color: "#e5e6eb"
|
|
|
+
|
|
|
+ Rectangle {
|
|
|
+ width: volumeSlider.visualPosition * parent.width
|
|
|
+ height: parent.height
|
|
|
+ color: "#165dff"
|
|
|
+ radius: 6
|
|
|
+ }
|
|
|
+ }
|
|
|
+ handle: Rectangle {
|
|
|
+ x: volumeSlider.leftPadding + volumeSlider.visualPosition * (volumeSlider.availableWidth - width)
|
|
|
+ y: volumeSlider.topPadding + volumeSlider.availableHeight / 2 - height / 2
|
|
|
+ implicitWidth: 32
|
|
|
+ implicitHeight: 32
|
|
|
+ radius: 16
|
|
|
+ color: volumeSlider.pressed ? "#f0f0f0" : "#ffffff"
|
|
|
+ border.color: "#165dff"
|
|
|
+ border.width: 2
|
|
|
+ layer.enabled: true
|
|
|
+ layer.effect: DropShadow {
|
|
|
+ transparentBorder: true
|
|
|
+ horizontalOffset: 0
|
|
|
+ verticalOffset: 2
|
|
|
+ radius: 4
|
|
|
+ color: "#20000000"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Text {
|
|
|
+ text: volumeSlider.value.toFixed(0) + "%"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 20
|
|
|
+ color: "#165dff"
|
|
|
+ Layout.preferredWidth: 50
|
|
|
+ horizontalAlignment: Text.AlignRight
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 第二栏:电视控制
|
|
|
+ RowLayout {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ spacing: 20
|
|
|
+
|
|
|
+ Text {
|
|
|
+ text: "电视控制"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 20
|
|
|
+ color: "#333"
|
|
|
+ Layout.preferredWidth: 80
|
|
|
+ }
|
|
|
+
|
|
|
+ Flow {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ spacing: 15
|
|
|
+
|
|
|
+ Button {
|
|
|
+ text: "开所有电视"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.pixelSize: 14
|
|
|
+ font.weight: Font.Bold
|
|
|
+ padding: 12
|
|
|
+ background: Rectangle { color: parent.pressed ? "#b7eb8f" : "#f6ffed"; radius: 8; border.color: "#b7eb8f" }
|
|
|
+ contentItem: Text { text: parent.text; font: parent.font; color: "#389e0d"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: root.controlAllTvs("turn_on_all")
|
|
|
+ }
|
|
|
+ Button {
|
|
|
+ text: "关所有电视"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.pixelSize: 14
|
|
|
+ font.weight: Font.Bold
|
|
|
+ padding: 12
|
|
|
+ background: Rectangle { color: parent.pressed ? "#ffccc7" : "#fff1f0"; radius: 8; border.color: "#ffccc7" }
|
|
|
+ contentItem: Text { text: parent.text; font: parent.font; color: "#cf1322"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: root.controlAllTvs("turn_off_all")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 第三栏:迎宾模式
|
|
|
+ RowLayout {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ spacing: 20
|
|
|
+
|
|
|
+ Text {
|
|
|
+ text: "迎宾模式"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 20
|
|
|
+ color: "#333"
|
|
|
+ Layout.preferredWidth: 80
|
|
|
+ }
|
|
|
+
|
|
|
+ Flow {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ spacing: 15
|
|
|
+
|
|
|
+ Button {
|
|
|
+ text: "启动迎宾"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.pixelSize: 14
|
|
|
+ font.weight: Font.Bold
|
|
|
+ padding: 12
|
|
|
+ background: Rectangle { color: parent.pressed ? "#d3adf7" : "#f9f0ff"; radius: 8; border.color: "#d3adf7" }
|
|
|
+ contentItem: Text { text: parent.text; font: parent.font; color: "#722ed1"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: root.setWelcomeMode(true)
|
|
|
+ }
|
|
|
+ Button {
|
|
|
+ text: "关闭迎宾"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.pixelSize: 14
|
|
|
+ font.weight: Font.Bold
|
|
|
+ padding: 12
|
|
|
+ background: Rectangle { color: parent.pressed ? "#ffccc7" : "#fff1f0"; radius: 8; border.color: "#ffccc7" }
|
|
|
+ contentItem: Text { text: parent.text; font: parent.font; color: "#cf1322"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: root.setWelcomeMode(false)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 第四栏:大门控制
|
|
|
+ RowLayout {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ spacing: 20
|
|
|
+
|
|
|
+ Text {
|
|
|
+ text: "大门控制"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 20
|
|
|
+ color: "#333"
|
|
|
+ Layout.preferredWidth: 80
|
|
|
+ }
|
|
|
+
|
|
|
+ Flow {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ spacing: 15
|
|
|
+
|
|
|
+ Button {
|
|
|
+ text: "正常模式"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.pixelSize: 14
|
|
|
+ font.weight: Font.Bold
|
|
|
+ padding: 12
|
|
|
+ background: Rectangle { color: parent.pressed ? "#bae7ff" : "#e6f7ff"; radius: 8; border.color: "#bae7ff" }
|
|
|
+ contentItem: Text { text: parent.text; font: parent.font; color: "#096dd9"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: root.setDoorMode(0)
|
|
|
+ }
|
|
|
+ Button {
|
|
|
+ text: "常开模式"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.pixelSize: 14
|
|
|
+ font.weight: Font.Bold
|
|
|
+ padding: 12
|
|
|
+ background: Rectangle { color: parent.pressed ? "#b7eb8f" : "#f6ffed"; radius: 8; border.color: "#b7eb8f" }
|
|
|
+ contentItem: Text { text: parent.text; font: parent.font; color: "#389e0d"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: root.setDoorMode(1)
|
|
|
+ }
|
|
|
+ Button {
|
|
|
+ text: "常闭模式"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.pixelSize: 14
|
|
|
+ font.weight: Font.Bold
|
|
|
+ padding: 12
|
|
|
+ background: Rectangle { color: parent.pressed ? "#ffccc7" : "#fff1f0"; radius: 8; border.color: "#ffccc7" }
|
|
|
+ contentItem: Text { text: parent.text; font: parent.font; color: "#cf1322"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: root.setDoorMode(2)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 第五栏:展厅顶灯等级控制
|
|
|
+ RowLayout {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ spacing: 20
|
|
|
+
|
|
|
+ Text {
|
|
|
+ text: "顶灯等级"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 20
|
|
|
+ color: "#333"
|
|
|
+ Layout.preferredWidth: 80
|
|
|
+ }
|
|
|
+
|
|
|
+ Flow {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ spacing: 15
|
|
|
+
|
|
|
+ Button {
|
|
|
+ text: "全关"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.pixelSize: 14
|
|
|
+ font.weight: Font.Bold
|
|
|
+ padding: 12
|
|
|
+ background: Rectangle { color: parent.pressed ? "#ffccc7" : "#fff1f0"; radius: 8; border.color: "#ffccc7" }
|
|
|
+ contentItem: Text { text: parent.text; font: parent.font; color: "#cf1322"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: root.setCeilingLightLevel(0)
|
|
|
+ }
|
|
|
+ Button {
|
|
|
+ text: "单灯"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.pixelSize: 14
|
|
|
+ font.weight: Font.Bold
|
|
|
+ padding: 12
|
|
|
+ background: Rectangle { color: parent.pressed ? "#bae7ff" : "#e6f7ff"; radius: 8; border.color: "#bae7ff" }
|
|
|
+ contentItem: Text { text: parent.text; font: parent.font; color: "#096dd9"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: root.setCeilingLightLevel(1)
|
|
|
+ }
|
|
|
+ Button {
|
|
|
+ text: "双灯"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.pixelSize: 14
|
|
|
+ font.weight: Font.Bold
|
|
|
+ padding: 12
|
|
|
+ background: Rectangle { color: parent.pressed ? "#b7eb8f" : "#f6ffed"; radius: 8; border.color: "#b7eb8f" }
|
|
|
+ contentItem: Text { text: parent.text; font: parent.font; color: "#389e0d"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: root.setCeilingLightLevel(2)
|
|
|
+ }
|
|
|
+ Button {
|
|
|
+ text: "全开"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.pixelSize: 14
|
|
|
+ font.weight: Font.Bold
|
|
|
+ padding: 12
|
|
|
+ background: Rectangle { color: parent.pressed ? "#d3adf7" : "#f9f0ff"; radius: 8; border.color: "#d3adf7" }
|
|
|
+ contentItem: Text { text: parent.text; font: parent.font; color: "#722ed1"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter }
|
|
|
+ onClicked: root.setCeilingLightLevel(3)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 第六栏:展厅灯光与设备
|
|
|
+ ColumnLayout {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ spacing: 15
|
|
|
+
|
|
|
+ Text {
|
|
|
+ text: "展厅控制"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 20
|
|
|
+ color: "#333"
|
|
|
+ }
|
|
|
+
|
|
|
+ Flow {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ spacing: 12
|
|
|
+
|
|
|
+ Repeater {
|
|
|
+ model: [
|
|
|
+ { name: "玄关顶灯", key: "entrance_lights" },
|
|
|
+ { name: "玄关射灯", key: "exhibition_spotlight" },
|
|
|
+ { name: "桌面总开关", key: "exhibition_desktop_switch" },
|
|
|
+ { name: "3D风扇", key: "exhibition_3d_fan" },
|
|
|
+ { name: "展台灯带", key: "exhibition_stand_light_strip" }
|
|
|
+ ]
|
|
|
+
|
|
|
+ delegate: Button {
|
|
|
+ text: modelData.name
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 14
|
|
|
+ padding: 12
|
|
|
+
|
|
|
+ property bool isOn: false
|
|
|
+
|
|
|
+ background: Rectangle {
|
|
|
+ color: parent.isOn ? "#ffb400" : "#f2f3f5"
|
|
|
+ radius: 8
|
|
|
+ border.color: parent.isOn ? "#ffb400" : "#e5e6eb"
|
|
|
+ }
|
|
|
+ contentItem: Text {
|
|
|
+ text: parent.text
|
|
|
+ font: parent.font
|
|
|
+ color: parent.isOn ? "white" : "#4e5969"
|
|
|
+ horizontalAlignment: Text.AlignHCenter
|
|
|
+ verticalAlignment: Text.AlignVCenter
|
|
|
+ }
|
|
|
+
|
|
|
+ onClicked: {
|
|
|
+ isOn = !isOn
|
|
|
+ root.toggleExhibitionLight(modelData.key, isOn)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 第五栏:重启与维护
|
|
|
+ RowLayout {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ spacing: 20
|
|
|
+
|
|
|
+ Text {
|
|
|
+ text: "系统维护"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 20
|
|
|
+ color: "#333"
|
|
|
+ Layout.preferredWidth: 80
|
|
|
+ }
|
|
|
+
|
|
|
+ Button {
|
|
|
+ text: "重启展厅所有设备"
|
|
|
+ Layout.fillWidth: true
|
|
|
+ Layout.preferredHeight: 44
|
|
|
+ background: Rectangle {
|
|
|
+ color: parent.pressed ? "#ffccc7" : "#fff1f0"
|
|
|
+ radius: 8
|
|
|
+ border.color: "#ffccc7"
|
|
|
+ }
|
|
|
+ contentItem: Text {
|
|
|
+ text: parent.text
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 16
|
|
|
+ color: "#cf1322"
|
|
|
+ horizontalAlignment: Text.AlignHCenter
|
|
|
+ verticalAlignment: Text.AlignVCenter
|
|
|
+ }
|
|
|
+ onClicked: restartConfirmPopup.open()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Item { Layout.fillHeight: true } // Spacer
|
|
|
+
|
|
|
+ Button {
|
|
|
+ text: "关闭"
|
|
|
+ Layout.alignment: Qt.AlignHCenter
|
|
|
+ Layout.preferredWidth: 120
|
|
|
+ Layout.preferredHeight: 48
|
|
|
+
|
|
|
+ background: Rectangle {
|
|
|
+ color: parent.pressed ? "#e5e6eb" : "#f2f3f5"
|
|
|
+ radius: 8
|
|
|
+ }
|
|
|
+ contentItem: Text {
|
|
|
+ text: parent.text
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 16
|
|
|
+ color: "#1d2129"
|
|
|
+ horizontalAlignment: Text.AlignHCenter
|
|
|
+ verticalAlignment: Text.AlignVCenter
|
|
|
+ }
|
|
|
+ onClicked: exhibitionControlPopup.close()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// 主布局
|
|
|
ColumnLayout {
|
|
|
anchors.fill: parent
|
|
|
@@ -222,71 +876,167 @@ Rectangle {
|
|
|
Layout.fillHeight: true
|
|
|
Layout.minimumHeight: 80
|
|
|
|
|
|
- // 动态加载表情:AnimatedImage 用于 GIF,Image 用于静态图,Text 用于 emoji
|
|
|
- Loader {
|
|
|
- id: emotionLoader
|
|
|
- anchors.centerIn: parent
|
|
|
- // 保持正方形,取宽高中较小值的 70%,最小60px
|
|
|
- property real maxSize: Math.max(Math.min(parent.width, parent.height) * 0.7, 60)
|
|
|
- width: maxSize
|
|
|
- height: maxSize
|
|
|
-
|
|
|
- sourceComponent: {
|
|
|
- var path = displayModel ? displayModel.emotionPath : ""
|
|
|
- if (!path || path.length === 0) {
|
|
|
- return emojiComponent
|
|
|
- }
|
|
|
- if (path.indexOf(".gif") !== -1) {
|
|
|
- return gifComponent
|
|
|
- }
|
|
|
- if (path.indexOf(".") !== -1) {
|
|
|
- return imageComponent
|
|
|
+ // 使用 RowLayout 来放置 左侧按钮 - 表情 - 右侧按钮
|
|
|
+ RowLayout {
|
|
|
+ anchors.fill: parent
|
|
|
+ spacing: 20
|
|
|
+
|
|
|
+ // 左侧:视频播放悬浮球
|
|
|
+ Item {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ Layout.fillHeight: true
|
|
|
+
|
|
|
+ // 视频播放悬浮球
|
|
|
+ Rectangle {
|
|
|
+ anchors.centerIn: parent
|
|
|
+ width: 240
|
|
|
+ height: 240
|
|
|
+ radius: 120
|
|
|
+ color: videoMouse.pressed ? "#fff7e6" : (videoMouse.containsMouse ? "#fff1b8" : "#ffffff")
|
|
|
+ border.color: "#faad14"
|
|
|
+ border.width: 4
|
|
|
+ visible: true
|
|
|
+
|
|
|
+ layer.enabled: true
|
|
|
+ layer.effect: DropShadow {
|
|
|
+ transparentBorder: true
|
|
|
+ horizontalOffset: 0
|
|
|
+ verticalOffset: 4
|
|
|
+ radius: 16
|
|
|
+ color: "#20faad14"
|
|
|
+ }
|
|
|
+
|
|
|
+ Text {
|
|
|
+ anchors.centerIn: parent
|
|
|
+ text: "视频播放"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 36
|
|
|
+ color: "#faad14"
|
|
|
+ }
|
|
|
+
|
|
|
+ MouseArea {
|
|
|
+ id: videoMouse
|
|
|
+ anchors.fill: parent
|
|
|
+ hoverEnabled: true
|
|
|
+ cursorShape: Qt.PointingHandCursor
|
|
|
+ onClicked: videoPopup.open()
|
|
|
+ }
|
|
|
+
|
|
|
+ // 鼠标悬停动画
|
|
|
+ scale: videoMouse.containsMouse ? 1.05 : 1.0
|
|
|
+ Behavior on scale { NumberAnimation { duration: 150; easing.type: Easing.OutQuad } }
|
|
|
}
|
|
|
- return emojiComponent
|
|
|
}
|
|
|
|
|
|
- // GIF 动图组件
|
|
|
- Component {
|
|
|
- id: gifComponent
|
|
|
- AnimatedImage {
|
|
|
- fillMode: Image.PreserveAspectCrop
|
|
|
- source: displayModel ? displayModel.emotionPath : ""
|
|
|
- playing: true
|
|
|
- speed: 1.05
|
|
|
- cache: true
|
|
|
- clip: true
|
|
|
- onStatusChanged: {
|
|
|
- if (status === Image.Error) {
|
|
|
- console.error("AnimatedImage error:", errorString, "src=", source)
|
|
|
+ // 中间:动态加载表情
|
|
|
+ Item {
|
|
|
+ Layout.preferredWidth: Math.min(parent.width * 0.3, parent.height)
|
|
|
+ Layout.fillHeight: true
|
|
|
+
|
|
|
+ Loader {
|
|
|
+ id: emotionLoader
|
|
|
+ anchors.centerIn: parent
|
|
|
+ // 保持正方形
|
|
|
+ property real maxSize: Math.min(parent.width, parent.height)
|
|
|
+ width: maxSize
|
|
|
+ height: maxSize
|
|
|
+
|
|
|
+ sourceComponent: {
|
|
|
+ var path = displayModel ? displayModel.emotionPath : ""
|
|
|
+ if (!path || path.length === 0) {
|
|
|
+ return emojiComponent
|
|
|
+ }
|
|
|
+ if (path.indexOf(".gif") !== -1) {
|
|
|
+ return gifComponent
|
|
|
+ }
|
|
|
+ if (path.indexOf(".") !== -1) {
|
|
|
+ return imageComponent
|
|
|
+ }
|
|
|
+ return emojiComponent
|
|
|
+ }
|
|
|
+
|
|
|
+ // GIF 动图组件
|
|
|
+ Component {
|
|
|
+ id: gifComponent
|
|
|
+ AnimatedImage {
|
|
|
+ fillMode: Image.PreserveAspectCrop
|
|
|
+ source: displayModel ? displayModel.emotionPath : ""
|
|
|
+ playing: true
|
|
|
+ speed: 1.05
|
|
|
+ cache: true
|
|
|
+ clip: true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 静态图片组件
|
|
|
+ Component {
|
|
|
+ id: imageComponent
|
|
|
+ Image {
|
|
|
+ fillMode: Image.PreserveAspectCrop
|
|
|
+ source: displayModel ? displayModel.emotionPath : ""
|
|
|
+ cache: true
|
|
|
+ clip: true
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- // 静态图片组件
|
|
|
- Component {
|
|
|
- id: imageComponent
|
|
|
- Image {
|
|
|
- fillMode: Image.PreserveAspectCrop
|
|
|
- source: displayModel ? displayModel.emotionPath : ""
|
|
|
- cache: true
|
|
|
- clip: true
|
|
|
- onStatusChanged: {
|
|
|
- if (status === Image.Error) {
|
|
|
- console.error("Image error:", errorString, "src=", source)
|
|
|
+ // Emoji 文本组件
|
|
|
+ Component {
|
|
|
+ id: emojiComponent
|
|
|
+ Text {
|
|
|
+ text: displayModel ? displayModel.emotionPath : "😊"
|
|
|
+ font.pixelSize: 80
|
|
|
+ horizontalAlignment: Text.AlignHCenter
|
|
|
+ verticalAlignment: Text.AlignVCenter
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Emoji 文本组件
|
|
|
- Component {
|
|
|
- id: emojiComponent
|
|
|
- Text {
|
|
|
- text: displayModel ? displayModel.emotionPath : "😊"
|
|
|
- font.pixelSize: 80
|
|
|
- horizontalAlignment: Text.AlignHCenter
|
|
|
- verticalAlignment: Text.AlignVCenter
|
|
|
+ // 右侧:展厅控制悬浮球
|
|
|
+ Item {
|
|
|
+ Layout.fillWidth: true
|
|
|
+ Layout.fillHeight: true
|
|
|
+
|
|
|
+ Rectangle {
|
|
|
+ anchors.centerIn: parent
|
|
|
+ width: 240
|
|
|
+ height: 240
|
|
|
+ radius: 120
|
|
|
+ color: exhibitionMouse.pressed ? "#cce4ff" : (exhibitionMouse.containsMouse ? "#e6f4ff" : "#ffffff")
|
|
|
+ border.color: "#165dff"
|
|
|
+ border.width: 4
|
|
|
+
|
|
|
+ layer.enabled: true
|
|
|
+ layer.effect: DropShadow {
|
|
|
+ transparentBorder: true
|
|
|
+ horizontalOffset: 0
|
|
|
+ verticalOffset: 4
|
|
|
+ radius: 16
|
|
|
+ color: "#20165dff"
|
|
|
+ }
|
|
|
+
|
|
|
+ Text {
|
|
|
+ anchors.centerIn: parent
|
|
|
+ text: "展厅控制"
|
|
|
+ font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
+ font.weight: Font.Bold
|
|
|
+ font.pixelSize: 36
|
|
|
+ color: "#165dff"
|
|
|
+ Layout.alignment: Qt.AlignHCenter
|
|
|
+ }
|
|
|
+
|
|
|
+ MouseArea {
|
|
|
+ id: exhibitionMouse
|
|
|
+ anchors.fill: parent
|
|
|
+ hoverEnabled: true
|
|
|
+ cursorShape: Qt.PointingHandCursor
|
|
|
+ onClicked: exhibitionControlPopup.open()
|
|
|
+ }
|
|
|
+
|
|
|
+ // 鼠标悬停动画
|
|
|
+ scale: exhibitionMouse.containsMouse ? 1.05 : 1.0
|
|
|
+ Behavior on scale { NumberAnimation { duration: 150; easing.type: Easing.OutQuad } }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -410,7 +1160,7 @@ Rectangle {
|
|
|
// 输入 + 发送
|
|
|
RowLayout {
|
|
|
Layout.fillWidth: false
|
|
|
- Layout.preferredWidth: 160
|
|
|
+ Layout.preferredWidth: 480
|
|
|
Layout.preferredHeight: 38
|
|
|
spacing: 6
|
|
|
|
|
|
@@ -438,6 +1188,26 @@ Rectangle {
|
|
|
Text { anchors.fill: parent; text: "输入文字..."; font: textInput.font; color: "#c9cdd4"; verticalAlignment: Text.AlignVCenter; visible: !textInput.text && !textInput.activeFocus }
|
|
|
|
|
|
Keys.onReturnPressed: { if (textInput.text.trim().length > 0) { root.sendButtonClicked(textInput.text); textInput.text = "" } }
|
|
|
+
|
|
|
+ // 获得焦点时触发快捷指令弹窗
|
|
|
+ onActiveFocusChanged: {
|
|
|
+ if (activeFocus && !quickCmdPopup.visible) {
|
|
|
+ quickCmdPopup.open()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 点击时也能触发(如果已经有焦点但弹窗关了的情况)
|
|
|
+ MouseArea {
|
|
|
+ anchors.fill: parent
|
|
|
+ propagateComposedEvents: true
|
|
|
+ cursorShape: Qt.IBeamCursor
|
|
|
+ onClicked: {
|
|
|
+ if (!quickCmdPopup.visible) {
|
|
|
+ quickCmdPopup.open()
|
|
|
+ }
|
|
|
+ mouse.accepted = false
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -481,33 +1251,6 @@ Rectangle {
|
|
|
onClicked: root.modeButtonClicked()
|
|
|
}
|
|
|
|
|
|
- // 快捷指令(次要)
|
|
|
- Button {
|
|
|
- id: quickCmdBtn
|
|
|
- Layout.preferredWidth: 200
|
|
|
- Layout.fillWidth: true
|
|
|
- Layout.maximumWidth: 300
|
|
|
- Layout.preferredHeight: 38
|
|
|
- text: "快捷指令"
|
|
|
- background: Rectangle {
|
|
|
- color: quickCmdBtn.pressed ? "#b7eb8f" : (quickCmdBtn.hovered ? "#d9f7be" : "#f6ffed")
|
|
|
- radius: 8
|
|
|
- border.color: "#b7eb8f"
|
|
|
- border.width: 1
|
|
|
- }
|
|
|
- contentItem: Text {
|
|
|
- text: quickCmdBtn.text
|
|
|
- font.family: "PingFang SC, Microsoft YaHei UI"
|
|
|
- font.pixelSize: 16
|
|
|
- font.weight: Font.Bold
|
|
|
- color: "#389e0d"
|
|
|
- horizontalAlignment: Text.AlignHCenter
|
|
|
- verticalAlignment: Text.AlignVCenter
|
|
|
- elide: Text.ElideRight
|
|
|
- }
|
|
|
- onClicked: quickCmdPopup.open()
|
|
|
- }
|
|
|
-
|
|
|
// 设置(次要)
|
|
|
Button {
|
|
|
id: settingsBtn
|