// 图标:18×18 viewbox 的矢量绘制(Metro 要求线性几何图标,不用 emoji/位图)。 // 只用 M/L/Q/Z 命令 + 直线,避免依赖字体字形;描边图标 stroke,实心图标 fill。 import { Theme } from "../theme/tokens.slint"; export enum IconKind { instances, download, logs, settings, ai, play, stop, search, plus, close, minimize, maximize, chevronLeft, chevronRight, chevronDown, expand, send, check, warn, error, more, sidebar, restore, } export component AppIcon inherits Rectangle { in property kind: IconKind.instances; in property tint: Theme.fg-secondary; in property icon-size: 18px; width: icon-size; height: icon-size; background: transparent; if kind == IconKind.instances : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 2 2 L 8 2 L 8 8 L 2 8 Z M 10 2 L 16 2 L 16 8 L 10 8 Z M 2 10 L 8 10 L 8 16 L 2 16 Z M 10 10 L 16 10 L 16 16 L 10 16 Z"; fill: transparent; stroke: root.tint; stroke-width: 1.4px; } if kind == IconKind.download : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 9 2 L 9 11 M 4 7 L 9 12 L 14 7 M 3 15 L 15 15"; fill: transparent; stroke: root.tint; stroke-width: 1.6px; } if kind == IconKind.logs : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 3 4 L 15 4 M 3 9 L 15 9 M 3 14 L 11 14"; fill: transparent; stroke: root.tint; stroke-width: 1.6px; } if kind == IconKind.settings : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 3 5 L 15 5 M 3 9 L 15 9 M 3 13 L 15 13"; fill: transparent; stroke: root.tint; stroke-width: 1.4px; } if kind == IconKind.settings : Rectangle { x: 5px; width: 5px; height: 5px; y: 3px; border-radius: 2.5px; background: root.tint; } if kind == IconKind.settings : Rectangle { x: 10px; y: 7px; width: 5px; height: 5px; border-radius: 2.5px; background: root.tint; } if kind == IconKind.settings : Rectangle { x: 3px; y: 11px; width: 5px; height: 5px; border-radius: 2.5px; background: root.tint; } if kind == IconKind.ai : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 9 1.5 L 10.7 7.3 L 16.5 9 L 10.7 10.7 L 9 16.5 L 7.3 10.7 L 1.5 9 L 7.3 7.3 Z"; fill: root.tint; stroke: transparent; stroke-width: 1px; } if kind == IconKind.play : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 5 3 L 15 9 L 5 15 Z"; fill: root.tint; stroke: transparent; stroke-width: 1px; } if kind == IconKind.stop : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 5 5 L 13 5 L 13 13 L 5 13 Z"; fill: root.tint; stroke: transparent; stroke-width: 1px; } if kind == IconKind.search : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 8 3 Q 13 3 13 8 Q 13 13 8 13 Q 3 13 3 8 Q 3 3 8 3 Z M 11.5 11.5 L 16 16"; fill: transparent; stroke: root.tint; stroke-width: 1.5px; } if kind == IconKind.plus : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 9 3 L 9 15 M 3 9 L 15 9"; fill: transparent; stroke: root.tint; stroke-width: 1.8px; } if kind == IconKind.close : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 4 4 L 14 14 M 14 4 L 4 14"; fill: transparent; stroke: root.tint; stroke-width: 1.4px; } if kind == IconKind.minimize : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 4 9 L 14 9"; fill: transparent; stroke: root.tint; stroke-width: 1.4px; } if kind == IconKind.maximize : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 4.5 4.5 L 13.5 4.5 L 13.5 13.5 L 4.5 13.5 Z"; fill: transparent; stroke: root.tint; stroke-width: 1.2px; } if kind == IconKind.chevronLeft : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 11 3 L 6 9 L 11 15"; fill: transparent; stroke: root.tint; stroke-width: 1.6px; } if kind == IconKind.chevronRight : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 7 3 L 12 9 L 7 15"; fill: transparent; stroke: root.tint; stroke-width: 1.6px; } if kind == IconKind.chevronDown : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 3 7 L 9 13 L 15 7"; fill: transparent; stroke: root.tint; stroke-width: 1.6px; } if kind == IconKind.expand : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 3 7 L 3 3 L 7 3 M 11 3 L 15 3 L 15 7 M 15 11 L 15 15 L 11 15 M 7 15 L 3 15 L 3 11"; fill: transparent; stroke: root.tint; stroke-width: 1.4px; } if kind == IconKind.send : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 2 9 L 16 9 M 11 4 L 16 9 L 11 14"; fill: transparent; stroke: root.tint; stroke-width: 1.6px; } if kind == IconKind.check : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 3 9 L 7 13 L 15 4"; fill: transparent; stroke: root.tint; stroke-width: 1.8px; } if kind == IconKind.warn : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 9 2 L 16 15 L 2 15 Z M 9 6.5 L 9 10.5"; fill: transparent; stroke: root.tint; stroke-width: 1.4px; } if kind == IconKind.error : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 9 2 Q 16 2 16 9 Q 16 16 9 16 Q 2 16 2 9 Q 2 2 9 2 Z M 9 5 L 9 10"; fill: transparent; stroke: root.tint; stroke-width: 1.5px; } if kind == IconKind.more : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 4 7 L 6 7 L 6 9 L 4 9 Z M 8 7 L 10 7 L 10 9 L 8 9 Z M 12 7 L 14 7 L 14 9 L 12 9 Z"; fill: root.tint; stroke: transparent; stroke-width: 1px; } if kind == IconKind.sidebar : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 3 4 L 15 4 L 15 14 L 3 14 Z M 7 4 L 7 14"; fill: transparent; stroke: root.tint; stroke-width: 1.4px; } // 还原(已最大化时的标题栏按钮):两层叠放方框 if kind == IconKind.restore : Path { width: root.width; height: root.height; viewbox-width: 18; viewbox-height: 18; commands: "M 6 3 L 15 3 L 15 12 M 3 6 L 12 6 L 12 15 L 3 15 Z"; fill: transparent; stroke: root.tint; stroke-width: 1.2px; } }