197 lines
6.7 KiB
C++
197 lines
6.7 KiB
C++
#include "desktop_list_page.h"
|
||
|
||
#include <QFont>
|
||
#include <QFrame>
|
||
#include <QHBoxLayout>
|
||
#include <QLabel>
|
||
#include <QPushButton>
|
||
#include <QScrollArea>
|
||
#include <QVBoxLayout>
|
||
|
||
namespace vdi {
|
||
namespace {
|
||
|
||
// 在信息行里加一个拉伸占位(独立函数避免在类外重复声明)
|
||
void addStretchToRow(QHBoxLayout* row) {
|
||
row->addStretch(1);
|
||
}
|
||
|
||
} // namespace
|
||
|
||
DesktopListPage::DesktopListPage(QWidget* parent) : QWidget(parent) {
|
||
auto* root = new QVBoxLayout(this);
|
||
root->setContentsMargins(80, 50, 80, 40);
|
||
root->setSpacing(16);
|
||
|
||
// ---- 标题区 ----
|
||
auto* title = new QLabel(QStringLiteral("选择云桌面"), this);
|
||
QFont titleFont = title->font();
|
||
titleFont.setPointSize(26);
|
||
titleFont.setBold(true);
|
||
title->setFont(titleFont);
|
||
title->setAlignment(Qt::AlignCenter);
|
||
root->addWidget(title);
|
||
|
||
auto* infoRow = new QHBoxLayout();
|
||
labelUser_ = new QLabel(this);
|
||
labelUser_->setStyleSheet(QStringLiteral("color: #8a94a6;"));
|
||
// 无登录页演示模式下不设"退出登录"(用户身份由设备/平台承担,
|
||
// 正式认证接入后由 DesktopService 驱动恢复登录流程)
|
||
infoRow->addWidget(labelUser_);
|
||
addStretchToRow(infoRow);
|
||
root->addLayout(infoRow);
|
||
|
||
// ---- 卡片区 ----
|
||
auto* scroll = new QScrollArea(this);
|
||
scroll->setWidgetResizable(true);
|
||
scroll->setFrameShape(QFrame::NoFrame);
|
||
scroll->setStyleSheet(QStringLiteral(
|
||
"QScrollArea { background: transparent; }"
|
||
"QWidget { background: transparent; }"));
|
||
|
||
auto* cardsHost = new QWidget(scroll);
|
||
cardsLayout_ = new QVBoxLayout(cardsHost);
|
||
cardsLayout_->setSpacing(14);
|
||
cardsLayout_->addStretch(1);
|
||
scroll->setWidget(cardsHost);
|
||
root->addWidget(scroll, 1);
|
||
|
||
// ---- 状态条 ----
|
||
labelStatus_ = new QLabel(this);
|
||
labelStatus_->setAlignment(Qt::AlignCenter);
|
||
labelStatus_->setStyleSheet(QStringLiteral("color: #8a94a6;"));
|
||
root->addWidget(labelStatus_);
|
||
}
|
||
|
||
void DesktopListPage::setDesktops(const std::vector<DesktopInfo>& desktops) {
|
||
desktops_ = desktops;
|
||
rebuildCards();
|
||
}
|
||
|
||
void DesktopListPage::rebuildCards() {
|
||
actionButtons_.clear();
|
||
|
||
// 清空旧卡片(最后一项是 stretch)
|
||
while (cardsLayout_->count() > 1) {
|
||
QLayoutItem* item = cardsLayout_->takeAt(0);
|
||
if (item->widget()) {
|
||
item->widget()->deleteLater();
|
||
}
|
||
delete item;
|
||
}
|
||
|
||
for (const DesktopInfo& d : desktops_) {
|
||
auto* card = new QFrame(this);
|
||
card->setMinimumHeight(96);
|
||
card->setStyleSheet(QStringLiteral(
|
||
"QFrame { background: #1a2233; border: 1px solid #2b3654; border-radius: 10px; }"
|
||
"QFrame:hover { border: 1px solid #2f6feb; }"
|
||
"QLabel { border: none; background: transparent; }"));
|
||
|
||
auto* row = new QHBoxLayout(card);
|
||
row->setContentsMargins(24, 16, 24, 16);
|
||
row->setSpacing(18);
|
||
|
||
auto* textCol = new QVBoxLayout();
|
||
textCol->setSpacing(4);
|
||
auto* name = new QLabel(d.name, card);
|
||
QFont nameFont = name->font();
|
||
nameFont.setPointSize(15);
|
||
nameFont.setBold(true);
|
||
name->setFont(nameFont);
|
||
auto* osLine = new QLabel(d.os, card);
|
||
osLine->setStyleSheet(QStringLiteral("color: #8a94a6;"));
|
||
textCol->addWidget(name);
|
||
textCol->addWidget(osLine);
|
||
row->addLayout(textCol, 1);
|
||
|
||
// 状态标签(会话通道统一 Moonlight,无需按桌面标注协议)
|
||
QString stateText;
|
||
QString stateColor;
|
||
switch (d.state) {
|
||
case DesktopState::kAvailable:
|
||
stateText = QStringLiteral("可连接");
|
||
stateColor = QStringLiteral("#3fb950");
|
||
break;
|
||
case DesktopState::kPending:
|
||
stateText = QStringLiteral("任务进行中");
|
||
stateColor = QStringLiteral("#d29922");
|
||
break;
|
||
case DesktopState::kUnassigned:
|
||
stateText = QStringLiteral("待分配");
|
||
stateColor = QStringLiteral("#8a94a6");
|
||
break;
|
||
}
|
||
auto* state = new QLabel(stateText, card);
|
||
state->setStyleSheet(QStringLiteral("color: %1; font-weight: bold;").arg(stateColor));
|
||
row->addWidget(state);
|
||
|
||
// “设置”:每张卡都可编辑连接参数(协议/地址/应用名/分辨率/帧率)
|
||
auto* editBtn = new QPushButton(QStringLiteral("设置"), card);
|
||
editBtn->setMinimumSize(88, 42);
|
||
editBtn->setEnabled(!busy_);
|
||
actionButtons_.push_back(editBtn);
|
||
connect(editBtn, &QPushButton::clicked, this, [this, id = d.id]() {
|
||
if (!busy_) {
|
||
emit editRequested(id);
|
||
}
|
||
});
|
||
row->addWidget(editBtn);
|
||
|
||
if (d.state == DesktopState::kAvailable) {
|
||
auto* connectBtn = new QPushButton(QStringLiteral("连接"), card);
|
||
connectBtn->setMinimumSize(110, 42);
|
||
connectBtn->setStyleSheet(QStringLiteral(
|
||
"QPushButton { background: #2f6feb; color: white; border: none; "
|
||
"border-radius: 6px; font-weight: bold; }"
|
||
"QPushButton:disabled { background: #3a4a63; }"));
|
||
connectBtn->setEnabled(!busy_);
|
||
actionButtons_.push_back(connectBtn);
|
||
connect(connectBtn, &QPushButton::clicked, this, [this, id = d.id]() {
|
||
if (!busy_) {
|
||
setBusy(true);
|
||
setStatus(QStringLiteral("正在连接,请稍候…"));
|
||
emit desktopSelected(id);
|
||
}
|
||
});
|
||
row->addWidget(connectBtn);
|
||
} else {
|
||
auto* btn = new QPushButton(QStringLiteral("连接"), card);
|
||
btn->setMinimumSize(110, 42);
|
||
btn->setEnabled(false);
|
||
row->addWidget(btn);
|
||
}
|
||
|
||
cardsLayout_->insertWidget(cardsLayout_->count() - 1, card);
|
||
}
|
||
}
|
||
|
||
void DesktopListPage::setStatus(const QString& text, bool error) {
|
||
labelStatus_->setText(text);
|
||
labelStatus_->setStyleSheet(
|
||
QStringLiteral("color: %1;").arg(error ? QStringLiteral("#e05561")
|
||
: QStringLiteral("#8a94a6")));
|
||
}
|
||
|
||
void DesktopListPage::setBusy(bool busy) {
|
||
busy_ = busy;
|
||
for (QPushButton* button : actionButtons_) {
|
||
if (button) {
|
||
button->setEnabled(!busy_);
|
||
}
|
||
}
|
||
}
|
||
|
||
QString DesktopListPage::currentUser() const {
|
||
return currentUser_;
|
||
}
|
||
|
||
void DesktopListPage::setCurrentUser(const QString& user) {
|
||
currentUser_ = user;
|
||
labelUser_->setText(user.isEmpty()
|
||
? QStringLiteral("当前用户:未登录")
|
||
: QStringLiteral("当前用户:%1").arg(user));
|
||
}
|
||
|
||
} // namespace vdi
|