-
This commit is contained in:
@@ -1,336 +1,272 @@
|
||||
import { Theme, SpacingSystem, Typography } from "../theme/theme.slint";
|
||||
import { Card } from "../components/card.slint";
|
||||
// Settings Page - App and Clash settings
|
||||
import { Theme, Typography, SpacingSystem } from "../theme/theme.slint";
|
||||
import { Container } from "../layouts/container.slint";
|
||||
import { Switch } from "../components/switch.slint";
|
||||
import { Button } from "../components/button.slint";
|
||||
import { Select, SelectOption } from "../components/select.slint";
|
||||
import { Separator, Orientation } from "../components/separator.slint";
|
||||
import { SettingItem } from "../types.slint";
|
||||
|
||||
export component SettingsPage inherits Rectangle {
|
||||
in property <[SettingItem]> app-settings;
|
||||
in property <[SettingItem]> clash-settings;
|
||||
|
||||
callback toggle-setting(string /* key */, bool /* value */);
|
||||
callback load-settings();
|
||||
|
||||
background: Theme.colors.background;
|
||||
|
||||
export component SettingsPage {
|
||||
// App Settings
|
||||
in property <bool> auto-start: false;
|
||||
in property <bool> silent-start: false;
|
||||
in property <bool> clash-core: false;
|
||||
|
||||
// Clash Settings
|
||||
in property <bool> tun-mode: false;
|
||||
in property <bool> allow-lan: false;
|
||||
in property <bool> ipv6: false;
|
||||
in property <bool> unified-delay: false;
|
||||
in property <int> log-level-index: 1;
|
||||
in property <int> proxy-port: 7890;
|
||||
|
||||
// Misc
|
||||
in property <string> app-dir: "C:/Program Files/Clash";
|
||||
in property <string> config-dir: "C:/Users/User/.config/clash";
|
||||
in property <string> core-dir: "C:/Program Files/Clash/core";
|
||||
in property <string> app-version: "1.0.0";
|
||||
|
||||
callback toggle-auto-start(bool);
|
||||
callback toggle-silent-start(bool);
|
||||
callback toggle-clash-core(bool);
|
||||
callback toggle-tun-mode(bool);
|
||||
callback toggle-allow-lan(bool);
|
||||
callback toggle-ipv6(bool);
|
||||
callback toggle-unified-delay(bool);
|
||||
callback log-level-changed(int);
|
||||
callback open-port-settings();
|
||||
callback open-tun-config();
|
||||
callback open-directory(string);
|
||||
|
||||
VerticalLayout {
|
||||
padding: SpacingSystem.spacing.s4;
|
||||
spacing: SpacingSystem.spacing.s4;
|
||||
|
||||
// Header
|
||||
Text {
|
||||
text: "Settings";
|
||||
color: Theme.colors.foreground;
|
||||
font-size: Typography.sizes.xl;
|
||||
font-weight: Typography.weights.bold;
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
VerticalLayout {
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
|
||||
// App Settings Section
|
||||
Card {
|
||||
VerticalLayout {
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
|
||||
Text {
|
||||
text: "App Settings";
|
||||
color: Theme.colors.foreground;
|
||||
font-size: Typography.sizes.base;
|
||||
font-weight: Typography.weights.semibold;
|
||||
}
|
||||
|
||||
SettingRow {
|
||||
icon: "🚀";
|
||||
label: "Auto Start";
|
||||
|
||||
Switch {
|
||||
checked: root.auto-start;
|
||||
toggled(checked) => {
|
||||
root.toggle-auto-start(checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator { orientation: Orientation.horizontal; }
|
||||
|
||||
SettingRow {
|
||||
icon: "🔇";
|
||||
label: "Silent Start";
|
||||
|
||||
Switch {
|
||||
checked: root.silent-start;
|
||||
toggled(checked) => {
|
||||
root.toggle-silent-start(checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator { orientation: Orientation.horizontal; }
|
||||
|
||||
SettingRow {
|
||||
icon: "⚙";
|
||||
label: "Clash Core";
|
||||
|
||||
Switch {
|
||||
checked: root.clash-core;
|
||||
toggled(checked) => {
|
||||
root.toggle-clash-core(checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clash Settings Section
|
||||
Card {
|
||||
VerticalLayout {
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
|
||||
Text {
|
||||
text: "Clash Settings";
|
||||
color: Theme.colors.foreground;
|
||||
font-size: Typography.sizes.base;
|
||||
font-weight: Typography.weights.semibold;
|
||||
}
|
||||
|
||||
SettingRow {
|
||||
icon: "🌐";
|
||||
label: "TUN Mode";
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: SpacingSystem.spacing.s2;
|
||||
|
||||
Switch
|
||||
checked: root.tun-mode;
|
||||
toggled(checked) => {
|
||||
root.toggle-tun-mode(checked);
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
text: "⚙";
|
||||
variant: "ghost";
|
||||
|
||||
clicked => {
|
||||
root.open-tun-config();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator { orientation: Orientation.horizontal; }
|
||||
|
||||
SettingRow {
|
||||
icon: "📡";
|
||||
label: "Allow LAN";
|
||||
|
||||
Switch {
|
||||
checked: root.allow-lan;
|
||||
toggled(checked) => {
|
||||
root.toggle-allow-lan(checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator { orientation: Orientation.horizontal; }
|
||||
|
||||
SettingRow {
|
||||
icon: "🌍";
|
||||
label: "IPv6";
|
||||
|
||||
Switch {
|
||||
checked: root.ipv6;
|
||||
toggled(checked) => {
|
||||
root.toggle-ipv6(checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator { orientation: Orientation.horizontal; }
|
||||
|
||||
SettingRow {
|
||||
icon: "⏱";
|
||||
label: "Unified Delay";
|
||||
|
||||
Switch {
|
||||
checked: root.unified-delay;
|
||||
toggled(checked) => {
|
||||
root.toggle-unified-delay(checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator { orientation: Orientation.horizontal; }
|
||||
|
||||
SettingRow {
|
||||
icon: "📝";
|
||||
label: "Log Level";
|
||||
|
||||
Select {
|
||||
options: [
|
||||
{ label: "Debug", valueg" },
|
||||
{ label: "Info", value: "info" },
|
||||
{ label: "Warn", value: "warn" },
|
||||
{ label: "Error", value: "error" },
|
||||
];
|
||||
selected-index: root.log-level-index;
|
||||
|
||||
selected(index, value) => {
|
||||
root.log-level-changed(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator { orientation: Orientation.horizontal; }
|
||||
|
||||
SettingRow {
|
||||
icon: "🔌";
|
||||
label: "Proxy Port";
|
||||
|
||||
Button {
|
||||
text: root.proxy-port;
|
||||
variant: "link";
|
||||
|
||||
clicked => {
|
||||
root.open-port-settings();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Miscellaneous Section
|
||||
Card {
|
||||
VerticalLayout {
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
|
||||
Text {
|
||||
text: "Miscellaneous";
|
||||
color: Theme.colors.foreground;
|
||||
font-size: Typography.sizes.base;
|
||||
font-weight: Typography.weights.semibold;
|
||||
}
|
||||
|
||||
SettingRow {
|
||||
icon: "📁";
|
||||
l: "App Directory";
|
||||
|
||||
Button {
|
||||
text: "Open";
|
||||
variant: "link";
|
||||
|
||||
clicked => {
|
||||
root.open-directory(root.app-dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator { orientation: Orientation.horizontal; }
|
||||
|
||||
SettingRow {
|
||||
icon: "📁";
|
||||
label: "Config Directory";
|
||||
|
||||
Button {
|
||||
text: "Open";
|
||||
variant: "link";
|
||||
|
||||
clicked => {
|
||||
root.open-directory(root.config-dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator { orientation: Orientation.horizontal; }
|
||||
|
||||
SettingRow {
|
||||
icon: "📁";
|
||||
label: "Core Directory";
|
||||
|
||||
Button {
|
||||
text: "Open";
|
||||
variant: "link";
|
||||
|
||||
clicked => {
|
||||
root.open-directory(root.core-dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator { orientation: Orientation.horizontal; }
|
||||
|
||||
SettingRow {
|
||||
icon: "ℹ";
|
||||
label: "App Version";
|
||||
|
||||
Text {
|
||||
text: root.app-version;
|
||||
color: Theme.colors.muted-foreground;
|
||||
font-size: Typography.sizes.sm;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fixed header
|
||||
Rectangle {
|
||||
height: 48px;
|
||||
background: Theme.colors.background;
|
||||
|
||||
component SettingRow {
|
||||
in property <string> icon: "";
|
||||
in property <string> label: "";
|
||||
|
||||
height: 40px;
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
alignment: space-between;
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: SpacingSystem.spacing.s2;
|
||||
|
||||
Text {
|
||||
text: root.icon;
|
||||
font-size: Typography.sizes.base;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: root.label;
|
||||
color: Theme.colors.foreground;
|
||||
font-size: Typography.sizes.sm;
|
||||
vertical-alignment: center;
|
||||
HorizontalLayout {
|
||||
padding: SpacingSystem.spacing.s4;
|
||||
|
||||
Text {
|
||||
text: "Settings";
|
||||
font-size: Typography.sizes.xl;
|
||||
font-weight: Typography.weights.bold;
|
||||
color: Theme.colors.foreground;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scrollable content
|
||||
Flickable {
|
||||
viewport-height: content-layout.preferred-height + SpacingSystem.spacing.s4 * 2;
|
||||
|
||||
content-layout := VerticalLayout {
|
||||
padding: SpacingSystem.spacing.s4;
|
||||
spacing: SpacingSystem.spacing.s4;
|
||||
|
||||
// App Settings Section
|
||||
Container {
|
||||
VerticalLayout {
|
||||
padding: SpacingSystem.spacing.s4;
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
|
||||
// Section title
|
||||
Text {
|
||||
text: "App 设置";
|
||||
font-size: Typography.sizes.base;
|
||||
font-weight: Typography.weights.semibold;
|
||||
color: Theme.colors.foreground;
|
||||
}
|
||||
|
||||
// App settings list
|
||||
for setting in app-settings: Rectangle {
|
||||
height: 48px;
|
||||
|
||||
HorizontalLayout {
|
||||
padding-top: SpacingSystem.spacing.s2;
|
||||
padding-bottom: SpacingSystem.spacing.s2;
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
alignment: space-between;
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
|
||||
// Icon
|
||||
Text {
|
||||
text: "✓";
|
||||
font-size: Typography.sizes.base;
|
||||
color: Theme.colors.primary;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
// Label
|
||||
Text {
|
||||
text: setting.label;
|
||||
font-size: Typography.sizes.sm;
|
||||
color: Theme.colors.foreground;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
// Control based on type
|
||||
if setting.type == "switch": Switch {
|
||||
checked: setting.enabled;
|
||||
|
||||
toggled => {
|
||||
root.toggle-setting(setting.key, self.checked);
|
||||
}
|
||||
}
|
||||
|
||||
if setting.type == "button": Button {
|
||||
text: setting.value;
|
||||
variant: "link";
|
||||
size: "sm";
|
||||
}
|
||||
|
||||
if setting.type == "text": Text {
|
||||
text: setting.value;
|
||||
font-size: Typography.sizes.sm;
|
||||
color: Theme.colors.muted-foreground;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clash Settings Section
|
||||
Container {
|
||||
VerticalLayout {
|
||||
padding: SpacingSystem.spacing.s4;
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
|
||||
// Section title
|
||||
Text {
|
||||
text: "Clash 设置";
|
||||
font-size: Typography.sizes.base;
|
||||
font-weight: Typography.weights.semibold;
|
||||
color: Theme.colors.foreground;
|
||||
}
|
||||
|
||||
// Clash settings list
|
||||
for setting in clash-settings: Rectangle {
|
||||
height: 48px;
|
||||
|
||||
HorizontalLayout {
|
||||
padding-top: SpacingSystem.spacing.s2;
|
||||
padding-bottom: SpacingSystem.spacing.s2;
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
alignment: space-between;
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
|
||||
// Icon
|
||||
Text {
|
||||
text: "⚙";
|
||||
font-size: Typography.sizes.base;
|
||||
color: Theme.colors.primary;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
// Label
|
||||
Text {
|
||||
text: setting.label;
|
||||
font-size: Typography.sizes.sm;
|
||||
color: Theme.colors.foreground;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
// Control based on type
|
||||
if setting.type == "switch": Switch {
|
||||
checked: setting.enabled;
|
||||
|
||||
toggled => {
|
||||
root.toggle-setting(setting.key, self.checked);
|
||||
}
|
||||
}
|
||||
|
||||
if setting.type == "button": Button {
|
||||
text: setting.value;
|
||||
variant: "link";
|
||||
size: "sm";
|
||||
}
|
||||
|
||||
if setting.type == "text": Text {
|
||||
text: setting.value;
|
||||
font-size: Typography.sizes.sm;
|
||||
color: Theme.colors.muted-foreground;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Miscellaneous Section
|
||||
Container {
|
||||
VerticalLayout {
|
||||
padding: SpacingSystem.spacing.s4;
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
|
||||
// Section title
|
||||
Text {
|
||||
text: "杂项";
|
||||
font-size: Typography.sizes.base;
|
||||
font-weight: Typography.weights.semibold;
|
||||
color: Theme.colors.foreground;
|
||||
}
|
||||
|
||||
// Misc items
|
||||
Rectangle {
|
||||
height: 48px;
|
||||
|
||||
HorizontalLayout {
|
||||
padding-top: SpacingSystem.spacing.s2;
|
||||
padding-bottom: SpacingSystem.spacing.s2;
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
alignment: space-between;
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
|
||||
Text {
|
||||
text: "📁";
|
||||
font-size: Typography.sizes.base;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "App 目录";
|
||||
font-size: Typography.sizes.sm;
|
||||
color: Theme.colors.foreground;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "打开";
|
||||
variant: "link";
|
||||
size: "sm";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 48px;
|
||||
|
||||
HorizontalLayout {
|
||||
padding-top: SpacingSystem.spacing.s2;
|
||||
padding-bottom: SpacingSystem.spacing.s2;
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
alignment: space-between;
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
|
||||
Text {
|
||||
text: "📋";
|
||||
font-size: Typography.sizes.base;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "App 版本";
|
||||
font-size: Typography.sizes.sm;
|
||||
color: Theme.colors.foreground;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "v1.0.0";
|
||||
font-size: Typography.sizes.sm;
|
||||
color: Theme.colors.muted-foreground;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@children
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user