Skip to content

[0627] 让tabular的边界可以修改颜色#3535

Open
JackYansongLi wants to merge 14 commits into
mainfrom
jackyansongli/200_27/0627_tabular_border_color
Open

[0627] 让tabular的边界可以修改颜色#3535
JackYansongLi wants to merge 14 commits into
mainfrom
jackyansongli/200_27/0627_tabular_border_color

Conversation

@JackYansongLi
Copy link
Copy Markdown
Contributor

@JackYansongLi JackYansongLi commented May 28, 2026

任务目标 (What)

在 Mogan 中实现表格(tabular)及单元格边框颜色的完全自定义功能:

  1. 新增 C++ 及 Scheme 层的 cell-border-colortable-border-color 属性。
  2. 在渲染层解析边框颜色,绘制边框时使用自定义颜色替换默认前景色。
  3. 在 Scheme 层提供 UI 界面和菜单选项让用户进行边框颜色修改。
  4. 相邻单元格边界合并解析:在 C++ 排版层(merge_borders)增加了基于修改顺序(cwith Precedence)的边界优先级判决。当相邻单元格有边框颜色冲突时,自动消除低优先级边框,从而渲染显示出最后选择修改的那个单元格的共享边颜色。

为什么需要这个任务 (Why)

目前 Mogan 表格(tabular)的边框颜色硬编码为当前环境的文本前景色(通常为黑色),用户无法直接修改表格的边框颜色。这限制了表格样式的丰富程度,有必要支持边框颜色的单独自定义。此外,当相邻单元格颜色不同时,重叠边界必须统一展现最后修改的颜色,绝不能因为光标切换重排版而发生混乱、闪烁或颜色覆写。

实现思路 (How)

  1. 在 C++ 的变量声明及初始化中增加 CELL_BORDER_COLORTABLE_BORDER_COLOR
    • 声明于 moebius/moebius/vars.hpp / vars.cpp
    • 并在 drd_std.cpp 注册为 TYPE_COLOR 类型,在 env_default.cpp 初始化其默认值(默认继承前景色,即 "")。
  2. cell_reptable_rep 中添加 tree bcolor 字段和 int bcolor_precedence(优先级进度):
    • table_rep::typeset_table 中从 TFORMAT 中解析出 cwith 的声明索引作为优先级存储,最后修改的优先级最高。
    • table_rep::merge_borders 中执行宽度和优先级合并。共享段优先级低于最大优先级的单元格边框被置为 0,防止重复绘制 and 冲突。
    • table_rep::finish()var_finish() 中强制重新进行合并决策,防止局部重排版引发的状态回滚。
  3. 在 Scheme 属性、焦点工具栏、菜单中加入控制逻辑:
    • environment.scm 定义对应的环境变量。
    • table-edit.scm 提供 cell-set-border-colortable-set-border-color 两个 setter。
    • table-widgets.scm 在属性面板加入颜色编辑框。
    • table-menu.scm 引入包含一键 Default、Foreground、Palette 调色盘、其他自定义颜色的完整颜色选取列表。

如何测试 (Testing)

2. 确定性测试(单元测试)

运行自动化测试套件:

xmake b edit_table_test && xmake r edit_table_test

此单元测试额外覆盖了以下关键判定场景:

  • test_adjacent_border_colors():验证当相邻单元格有边框颜色冲突(例如 Cell 1 优先级低,Cell 2 优先级高)时,C++ 能够正确判定,使低优先级单元格的右侧重合边框宽度消除(降为 0),保证高优先级单元格的颜色正确绘制在共享边界上。
  • test_adjacent_border_colors_on_cell_typeset():验证即使局部单元格发生重排版(Re-typeset)使宽度重置,执行表格 final 组装(finish())时依然能重新进行优先级合并判决,确保重排版后合并色不丢失。

3. 非确定性测试(界面及功能手动验证)

测试 3.2.1:通过“焦点工具栏”的边框弹出菜单进行修改(最直观)

  1. 构建并运行 Mogan STEM:
    xmake b stem && xmake r stem
  2. 在文档中插入一个有框表格 (Alt+t 然后 tab 几次)。
  3. 光标放入任一单元格(如 Cell 1),在上方弹出的 焦点工具栏(Focus Toolbar) 中找到 边框(Border) 图标。
  4. 点击该图标展开综合弹出菜单。在该菜单中,你会看到四大功能组:
    • Border(4x4 边框预设图标)
    • Pen width(线宽)
    • Border color新增的边框颜色选项,含有调色盘
    • Padding(边框内边距)
  5. 在该菜单中展开 Border color 子菜单,你会看到和背景色选择一致的标准多行多彩颜色调色盘
  6. 在调色盘中点击选择 红色(Red)(此时设置了当前单元格的边框颜色),然后再点击该菜单最顶部的 Border 图标组中最右侧的 全包网格(Grid) 图标(应用边框样式)。
  7. 预期结果:该单元格四周的边框成功渲染为红色。点击 Border color 中的 Default(默认)选项并重新应用全包网格,边框颜色能够一键返回默认黑色(Default)。

测试 3.2.2:相邻单元格共享边界(Border Conflict)合并测试

  1. 在一个 1行2列 的表格中,光标选中 Cell 1(左侧单元格)。
  2. 点击焦点工具栏的 边框 图标。在弹出的菜单中展开 Border color 子菜单,选择 红色(Red);然后点击顶部 Border 预设图标中的全包网格图标。此时 Cell 1 四周的边框都为红色。
  3. 随后,光标选中 Cell 2(右侧单元格)。
  4. 点击焦点工具栏的 边框 图标。在弹出的菜单中展开 Border color 子菜单,选择 蓝色(Blue);然后点击顶部 Border 预设图标中的全包网格图标。
  5. 预期结果
    • Cell 1 的左边、上边、下边框呈红色。
    • Cell 2 的右边、上边、下边框呈蓝色。
    • Cell 1 和 Cell 2 共享的中间边界线必须呈现蓝色。因为蓝色是最后一次选择并修改的颜色(在 TFORMAT 中具备更高的 cwith 优先级),C++ 应当正确将低优先级的 Cell 1 右边界消除,让 Cell 2 的蓝色左边界完美显示出来。

@JackYansongLi JackYansongLi changed the title [0627] support customizable border color for tabular [0627] 让tabular的边界可以修改颜色 May 28, 2026
JackYansongLi and others added 6 commits May 28, 2026 12:02
Copy link
Copy Markdown
Contributor

@da-liii da-liii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants