Skip to content

Commit 237ed63

Browse files
authored
[0824] 修复圆形拖控制点调成圆心位置 (#3917)
1 parent 0120261 commit 237ed63

2 files changed

Lines changed: 45 additions & 2 deletions

File tree

TeXmacs/progs/graphics/graphics-env.scm

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,9 @@
292292
(set-car! e2 #f)
293293
) ;begin
294294
) ;if
295-
(if (and o (not (in? (tree-label o) gr-tags-all)))
296-
;; Custom markup
295+
(if (and o (or (not (in? (tree-label o) gr-tags-all)) (tree-in? o '(circle))))
296+
;; circle(源 2 点 vs 渲染展开 carc 3 点,索引错位)
297+
;; 也需要按源对象重算控制点序号,才能与椭圆操作逻辑对齐
297298
(set-car! e2
298299
(rcons p (if x (object-closest-point-pos (tree->stree o) (f2s x) (f2s y)) 0))
299300
) ;set-car!

devel/0824.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# [0824] 修复圆形拖控制点调成圆心位置
2+
3+
## 1 相关文档
4+
- [0817.md](0817.md) - 绘图后自动切换到移动模式
5+
- [0818.md](0818.md) - 重构绘图区鼠标处理 & 工具切换逻辑
6+
- [0820.md](0820.md) - edit-props 模式吸收 move 的移动能力
7+
8+
## 2 任务相关的代码文件
9+
- `TeXmacs/progs/graphics/graphics-env.scm``filter-sel` 的控制点序号重算分支,对 `circle` 特判进入
10+
11+
## 3 如何测试
12+
13+
### 3.1 确定性测试(单元测试)
14+
```bash
15+
xmake b stem
16+
xmake r stem
17+
```
18+
19+
### 3.2 非确定性测试(交互验证)
20+
1. 画一个圆后进入选中状态
21+
2. 拖动**半径点**(圆周上的控制点)后,圆心不动,半径变化
22+
3. 对照椭圆,行为逻辑应完全一致
23+
24+
## 4 What
25+
调整已画好的图形大小时,椭圆拖控制点正常,但圆拖控制点不是调半径,而是错调成圆心位置。
26+
27+
## 5 Why
28+
圆与椭圆在实现层级上不同:
29+
30+
- 椭圆 `ellipse` 是 C++ 原生 tag,源对象 3 个点 = 渲染 3 个点,索引一一对应。
31+
-`circle` 是 Scheme 宏(`<extern|circle>``graphics-markup.scm``(define-graphics (circle C P) ...)`),源对象只有 2 个点(圆心 C、半径点 P),渲染时展开成 `(carc p q1 q2)` 共 3 个点。
32+
33+
`current-point-no` 取自 box 层 `graphical_select` 命中的展开后 carc 子节点序号(0/1/2),与源 `(circle C P)` 子节点(0/1)错位,于是拖半径点时改到了圆心。
34+
35+
`filter-sel` 本有"按源对象重算控制点序号"的分支(`object-closest-point-pos`),但触发条件是 `(not (in? (tree-label o) gr-tags-all))`。circle 在 `gr-tags-all` 里,被跳过。
36+
37+
## 6 How
38+
`filter-sel` 重算分支的触发条件加上 `(tree-in? o '(circle))` 特判,让圆也走 `object-closest-point-pos`,直接在源对象的 C、P 两点上找离鼠标最近的点,返回正确的 0 或 1。
39+
40+
之后 `set-point-sub` 拿到正确序号改源 `(circle C P)`,宏重新展开渲染:拖 P 改半径、拖 C 移圆心。
41+
42+
只特判 `circle` 一个 tag,椭圆等原生图形(源点数 = 渲染点数)行为不变;不改文档格式,旧 `(circle C P)` 文档原样修复。

0 commit comments

Comments
 (0)