From bea9caa0780b0109ab6e5851daf946b8281afd01 Mon Sep 17 00:00:00 2001 From: Kieran Kihn <114803508+kierankihn@users.noreply.github.com> Date: Tue, 9 Dec 2025 20:07:12 +0800 Subject: [PATCH] feat(ui): add `ConnectPage`, `StartPage`, and `MainWindow` components - Implemented `ConnectPage` to handle server connection input and initiation. - Added `StartPage` to manage player readiness before starting the game. - Created `MainWindow` to manage page transitions and callbacks. --- src/ui/ConnectPage.slint | 96 ++++++++++++++++++++++++++++++++++++++++ src/ui/MainWindow.slint | 33 ++++++++++++++ src/ui/StartPage.slint | 75 +++++++++++++++++++++++++++++++ 3 files changed, 204 insertions(+) create mode 100644 src/ui/ConnectPage.slint create mode 100644 src/ui/MainWindow.slint create mode 100644 src/ui/StartPage.slint diff --git a/src/ui/ConnectPage.slint b/src/ui/ConnectPage.slint new file mode 100644 index 0000000..d08c1f4 --- /dev/null +++ b/src/ui/ConnectPage.slint @@ -0,0 +1,96 @@ +import { + VerticalBox, + HorizontalBox, +} from "std-widgets.slint"; +import { Button, LabeledInput } from "Components.slint"; + +export component ConnectPage inherits Window { + width: 1920px; + height: 1080px; + title: "UNO!"; + + in property is-connecting; + + callback request-connect(string, string, string); + + // 背景渐变 (从左上角的米色到右下角的淡粉色) + Rectangle { + background: @linear-gradient(135deg, #fdfbf7 0%, #f3e7e9 100%); + } + + // 中心卡片 + Rectangle { + width: 600px; + height: 600px; // 根据内容高度调整 + background: #FDFBF8; // 略微区别于背景的米白色 + border-radius: 20px; + + // 简单的阴影模拟 + drop-shadow-blur: 20px; + drop-shadow-color: #00000015; + drop-shadow-offset-y: 4px; + + VerticalLayout { + padding: 40px; + spacing: 20px; + alignment: center; + + // 标题区域 + VerticalLayout { + spacing: 8px; + alignment: center; + + Text { + text: "UNO"; + font-size: 96px; + font-weight: 700; + color: #222222; + horizontal-alignment: center; + } + + Text { + text: "连接至服务器以开始游戏"; + font-size: 14px; + color: #666666; + horizontal-alignment: center; + } + } + + // 占位间隔 + Rectangle { + height: 10px; + } + + // 表单区域 + address-input := LabeledInput { + label-text: "服务器地址"; + value: "localhost"; + } + + port-input := LabeledInput { + label-text: "服务器端口"; + value: "10001"; + input-type: InputType.number; + } + + name-input := LabeledInput { + label-text: "玩家昵称"; + value: "Player"; + } + + // 底部按钮区域 (增加一点顶部间距) + HorizontalLayout { + padding-top: 10px; + alignment: center; + + Button { + text: is-connecting ? "正在连接..." : "连接"; + enabled: !is-connecting; + clicked => { + root.request-connect(address-input.value, port-input.value, name-input.value); + } + } + } + } + } +} diff --git a/src/ui/MainWindow.slint b/src/ui/MainWindow.slint new file mode 100644 index 0000000..259ef8b --- /dev/null +++ b/src/ui/MainWindow.slint @@ -0,0 +1,33 @@ +import { ConnectPage } from "ConnectPage.slint"; +import { StartPage } from "StartPage.slint"; + +enum PageType { + ConnectPage, + StartPage, + GamePage +} + +export component MainWindow inherits Window { + in property active-page: PageType.ConnectPage; + in property is-connecting; + in property is-ready; + + callback request-connect(string, string, string); + callback request-start; + + width: 1920px; + height: 1080px; + + if root.active-page == PageType.ConnectPage: connect-page := ConnectPage { + is-connecting: root.is-connecting; + request-connect(server-address, server-port, player-name) => { + root.request-connect(server-address, server-port, player-name); + } + } + if root.active-page == PageType.StartPage: start-page := StartPage { + is-ready: root.is-ready; + request-start => { + root.request-start(); + } + } +} diff --git a/src/ui/StartPage.slint b/src/ui/StartPage.slint new file mode 100644 index 0000000..7f4a445 --- /dev/null +++ b/src/ui/StartPage.slint @@ -0,0 +1,75 @@ +import {Button} from "Components.slint"; + +export component StartPage inherits Window { + width: 1920px; + height: 1080px; + title: "UNO!"; + + in property is-ready; + + callback request-start; + + // 背景渐变 (从左上角的米色到右下角的淡粉色) + Rectangle { + background: @linear-gradient(135deg, #fdfbf7 0%, #f3e7e9 100%); + } + + // 中心卡片 + Rectangle { + width: 600px; + height: 600px; // 根据内容高度调整 + background: #FDFBF8; // 略微区别于背景的米白色 + border-radius: 20px; + + // 简单的阴影模拟 + drop-shadow-blur: 20px; + drop-shadow-color: #00000015; + drop-shadow-offset-y: 4px; + + VerticalLayout { + padding: 40px; + spacing: 20px; + alignment: center; + + // 标题区域 + VerticalLayout { + spacing: 8px; + alignment: center; + + Text { + text: "UNO"; + font-size: 96px; + font-weight: 700; + color: #222222; + horizontal-alignment: center; + } + + Text { + text: "连接成功,所有玩家准备后开始游戏"; + font-size: 14px; + color: #666666; + horizontal-alignment: center; + } + } + + // 占位间隔 + Rectangle { + height: 10px; + } + + // 底部按钮区域 (增加一点顶部间距) + HorizontalLayout { + padding-top: 10px; + alignment: center; + + Button { + enabled: !is-ready; + text: is-ready ? "已准备" : "准备"; + clicked => { + root.request-start(); + } + } + } + } + } +}