Skip to content

Latest commit

 

History

History
182 lines (117 loc) · 13.5 KB

themebuilder.md

File metadata and controls

182 lines (117 loc) · 13.5 KB

主题编辑器

English: themebuilder.en.md

tools/themebuilder/ 是给 TyControls 写 .tycss 主题用的桌面程序。左边写主题,右边的预览马上换上它;写错的地方在问题列表里标出行号。也可以接一个大模型,用一句话说想要什么样的主题,让它起草或修改,改了什么在对比窗口里看清楚再决定要不要。

它是仓库里的一个工具,不是库的一部分,不对外承诺接口。

编译与运行

不用先在 IDE 里装包,工程直接引用 source/ 与 designtime/ 下的源码:

lazbuild -B tools/themebuilder/themebuilder.lpi

Linux 上按需要的 widgetset 加参数,例如 --ws=gtk2、--ws=qt6;macOS 加 --ws=cocoa。编出来的程序在 tools/themebuilder/lib/<CPU>-<系统>/ 下。

界面跟随系统语言,中文系统下是中文。

图标:Windows 上图标编进了程序(tools/themebuilder/themebuilder.ico,任务栏、标题栏左边都是它)。Linux / macOS 的程序文件不带图标,要的话用 tools/themebuilder/icon/themebuilder-256.png:Linux 在 .desktop 文件里写 Icon=<这张图的路径>;macOS 打成 .app 时用它做 .icns(工具没有现成的 .icns)。图标由 scripts/gen-themebuilder-icon.ps1 生成,改了图标重跑它再重编工具。

单击标题栏左边的图标,或者在标题栏上点右键,会弹出窗口菜单(还原、最小化、最大化、关闭);双击图标关闭窗口。

界面

  • 左边是侧栏,三页:种子、问题、AI。「视图」菜单里的同名项可以切到对应页,再点一次收起侧栏。
  • 中间是编辑区,带 .tycss 高亮和补全。
  • 右边是预览,按控件家族分了八页,顶上一排开关:暗色、密度(经典 / 现代)、全部禁用。「窗体外框」页里可以打开一个真窗体看标题栏和阴影。

编辑器自己的配色在「视图 → 编辑器外观」里选,和正在写的主题无关。预览挂在自己的样式控制器上,主题写坏了只会坏预览,不会把编辑器本身弄乱。

写主题

停手 0.3 秒,编辑器的内容就会被解析、检查,然后载入预览。解析不了或者预览画不出来时,预览保留上一版能用的样子,原因写在问题列表里。

新建:「文件 → 新建」可以选极简主题(只有亮、暗两套种子,其余全靠底层),也可以复制任何一个内置主题的全文。

种子页:六个种子(--accent、--surface、--on-surface、--border、--danger、--radius)是大部分颜色的来源,改它们最省事。文件有 @mode light / @mode dark 两块时分两列显示;只有一块 :root 时一列,可以一键拆成亮暗两套。点色块换颜色,改的只是文件里那一个值,别的字节都不动。值原来是表达式(var()、darken() 之类)时会先问一句。

问题页:解析错误、不认识的属性、未定义的变量、对比度太低等,带行号列出来,双击跳过去。底层主题已经定义的变量不算未定义。

Ctrl+点击预览里的控件(macOS 上是 Cmd+点击):编辑器跳到这个控件的规则;文件里还没有就在合适的位置加一条。没有变体的控件加的是底层规则的副本,而不是空规则——空规则会让底层对这个控件整个让位,控件就没了样式。

覆盖检查(「视图 → 覆盖检查」):列出主题写了、预览里却没有摆出来的控件,以及预览里有、但主题和底层都没专门写的控件。

.tycss 怎么写见 tycss-reference.md。

编辑菜单与快捷键

「编辑」菜单在「文件」与「视图」之间。撤销、剪切、复制、粘贴、删除、全选作用在有焦点的那个文字框上:编辑区,或者查找框、AI 页的描述框这类 Ty 输入框;焦点在按钮、列表上时,用快捷键什么都不做(键照常交给那个控件),从菜单里点则作用在编辑区。没有选中文字时剪切、复制、删除是灰的,没有可撤销的改动时撤销是灰的。格式化与查找总是作用在编辑区。

格式化文档 / 格式化选中部分:一行一条声明、写成 名字: 值;,每层缩进两个空格,右花括号单独一行,几个空行并成一个。选择器(TyButton:hover 的冒号)、注释(含多行的文件头注释)、引号里的字符串原样不动。「格式化选中部分」整理选中的那几行,按它们所在的层级缩进。两者都是一步撤销。

查找条:Ctrl+F 在编辑区顶上打开(选中了一段单行文字时自动填进查找框),Ctrl+H 打开时多一行替换。有区分大小写、全字匹配;上一个 / 下一个找到头会绕回另一端;找不到时右边写「找不到」。「替换」换掉选中的那一处再找下一个,「全部替换」一次换完、一步撤销,右边写换了几处。在查找框里按 Enter 找下一个、Shift+Enter 找上一个,Esc 关掉查找条、回到编辑区。

操作 快捷键
撤销 / 重做 Ctrl+Z / Ctrl+Shift+Z
剪切 / 复制 / 粘贴 Ctrl+X / Ctrl+C / Ctrl+V
删除选中的文字 Del
全选 Ctrl+A
格式化文档 Ctrl+Shift+F
格式化选中部分 (菜单)
查找 / 替换 Ctrl+F / Ctrl+H
查找下一个 / 上一个 F3 / Shift+F3
补全 Ctrl+Space

编辑区还有 SynEdit 自带的键:Ctrl+Y 删除一行、Ctrl+I / Ctrl+U 整块缩进 / 反缩进、Ctrl+Shift+数字 设书签、Ctrl+数字 跳到书签。

保存与导出

保存时换行符、BOM、文末换行都照读入时的样子写回,没改过的行一个字节都不变。打开仓库里的内置主题文件可以直接保存,状态栏会提醒重跑对应的生成脚本。

导出主题包(「文件 → 导出主题包」):导出成文件夹包(theme.tycss + theme.json + 主题引用的文件),或者在主题没有引用任何文件时导出成 zip。导出后会读回来试加载一遍,失败就不留下任何东西。

在程序里怎么用(同一菜单):给出三种加载方式的代码片段——从文件、从主题包、把文本注册成命名主题,可以直接复制。

AI

配一个服务

「视图 → AI 设置」或 AI 页右上角的齿轮。点「添加」从预置里选一个:

预置 格式 地址 模型
OpenAI OpenAI 兼容 https://api.openai.com/v1 gpt-5
DeepSeek OpenAI 兼容 https://api.deepseek.com/v1 deepseek-chat
Anthropic Anthropic https://api.anthropic.com/v1 claude-sonnet-5
本地(Ollama) OpenAI 兼容 http://localhost:11434/v1 qwen2.5-coder:7b
自定义 OpenAI 兼容 (自己填) (自己填)

预置只是帮你填好地址和模型名,填好后都能改。模型名会过时,「测试连接」报「地址或模型名不对(404)」时多半是它。

  • 密钥:本地模型不需要。Windows 上用当前用户的 DPAPI 加密后存进配置文件;Linux / macOS 上存在一个只有你能读的文件里(权限 0600)。密钥不会出现在任何提示、错误信息里。
  • 最大输出:0 表示不发送这一项,由服务自己决定。OpenAI 的新模型不接受旧的写法,所以默认是 0;DeepSeek 的 deepseek-chat 最多 8192;Anthropic 必须大于 0,默认 32000。
  • 超时:多少秒收不到任何数据算超时。生成一整份主题要一两分钟是正常的,所以没有总时长限制,随时可以点「停止」。
  • 测试连接:发一个最小的请求,一收到回答就停,然后说一句结果。

设置页底下写着:主题文本和你的描述会发给这里配置的服务。用本地模型,它们就不会离开这台电脑。

地址是 http://(不是 https://)、又不在这台电脑上时(比如内网里的服务、局域网里另一台机器上的 Ollama),设置页和 AI 页都会出一条「未加密」的警告:这个地址用 http,密钥和主题文本会明文经过网络。只是提醒,照样能用、也可以填密钥——网络可不可信只有你知道。服务把请求重定向到别的地址时,工具不跟过去(密钥会被一起带走),只告诉你它指向哪台主机,确认是对的地址就在设置里改过去。

本地模型

装好 Ollama,ollama pull qwen2.5-coder:7b(或别的 7–8B 代码模型),先设好上下文长度再启动 Ollama:

OLLAMA_CONTEXT_LENGTH=32768 ollama serve

Ollama 默认的上下文只有几千 token,请求太长时它会悄悄截掉开头——每次请求都带着一份几千 token 的语法参考,截掉的正是它,模型就会乱写。地址填本机时,设置页也会提示这一点。

生成一次

在 AI 页写一句描述(比如「暖色调,圆角大一点」),点「生成」:

  1. 回答一段段出现在下面的输出框里,可以随时「停止」。用的是带思考的模型时,先会显示「模型在思考……」。
  2. 结束后,工具从回答里取出 tycss 代码块,用和编辑器一样的标准检查:能不能解析、属性认不认识、变量有没有定义、亮暗两种模式下预览能不能画出来。有错就把问题发回去请模型改,最多两次;对比度低这类只是提示,不发回去。
  3. 对比窗口自动打开(这时若有别的对话框开着,就不弹,状态行提示用「查看对比…」):左边是编辑器现在的文本,右边是模型的版本,改动的行标了颜色,两边一起滚动。剩下的问题列在底下。勾上「在预览里试看」,预览就换成模型的版本;去掉勾或关掉窗口就换回来。
  4. 「接受」把编辑器换成模型的版本,Ctrl+Z 一次就能撤回;「放弃」什么都不变。关掉之后,AI 页的「查看对比…」可以再打开。

生成之后又在编辑器里改过,接受时会先问一句:接受会把这些改动一起替换掉。

勾上「附上问题列表」时,编辑器当前的问题会一起发过去。文件有错误时它会自动勾上,没错误时自动去掉;你自己点过之后,在这份文档里就不再自动改。

多轮对话

同一份文档里,工具会记住你之前的每句描述,以及那次的结果有没有被接受,所以「再暗一点」能接上。之前的回答不会再发,每次只发当前的文件,请求不会越来越长。新建或打开另一份文档时,对话从头开始;也可以点「新对话」。

发给模型的规则和语法参考是英文的(模型对英文规则遵守得最好);你的描述原样发送,模型写在代码块前面的那句说明会用你的语言。

出错时那句话

状态行 意思
连不上 …。服务开着吗?或者需要代理? 地址对,但没有服务在听,或者网络不通
找不到主机 … 主机名解析不了
密钥被拒绝(401) 密钥不对或者过期
地址或模型名不对(404) 地址多了或少了一段,或者模型名写错
请求太多(429) 服务限流了,等一会儿再试
… 已经 N 秒没有回应 超过了设置里的超时
回答到了最大输出长度,被截断了 把设置里的最大输出调大
回答的格式不对 地址指向的不是这种格式的服务
回答里没有 tycss 代码块 模型没照规矩回答,原文留在输出框里
回答不完整:在代码块中间就结束了 服务说完了,代码块却没写完
服务返回了重定向,指向 … 地址变了;工具不跟过去,确认后在设置里改
代理要求用户名和密码(407) 在系统的代理设置里填上

出什么错编辑器都不受影响。

Linux 与 macOS

AI 用系统的 libcurl,运行时加载。找不到时 AI 页会说试过哪些库名,生成按钮变灰,其余功能照常。Debian / Ubuntu 上装 libcurl4 包即可;库名特别的发行版可以用环境变量指定:

THEMEBUILDER_LIBCURL=/usr/lib64/libcurl.so.4 ./themebuilder

代理

Windows 上跟随系统的代理设置。Linux / macOS 上读 https_proxy、http_proxy、no_proxy 这几个环境变量。连本机地址(本地模型)时不走代理。

配置文件

工具的设置、最近文件和 AI 配置都在用户配置目录里:

系统 目录
Windows %LOCALAPPDATA%\themebuilder\
Linux / macOS ~/.config/themebuilder/

themebuilder.ini 是工具自己的设置,themebuilder-ai.ini 是 AI 服务,Linux / macOS 上另有存密钥的 themebuilder-ai.keys。想从头来,删掉它们就行。

已知限制

  • 编辑器和对比窗口用的是 SynEdit,它的边框和滚动条是系统原生的,不跟随编辑器外观。
  • AI 每次都交回整份文件,改一个颜色也一样。
  • macOS(Apple 芯片)上调用 libcurl 的方式还没在真机上验过。
  • Linux / macOS 上,正在解析主机名(DNS)时点「停止」不会立刻生效:libcurl 查名字时不回头看停止,要等查完或连接超时(15 秒)。
  • 同样的原因,Linux / macOS 上正在解析主机名时关掉工具(或关掉正在「测试连接」的 AI 设置窗口),窗口最长要等约 15 秒才关上:关闭要等那次请求结束。
  • Linux / macOS 上系统的 libcurl 太旧、不认 AI 需要的某个选项时,生成不会发出,状态行说是哪个选项,换新一点的 libcurl 即可。