Skip to content

Conversation

@AXeonV
Copy link
Contributor

@AXeonV AXeonV commented Jan 28, 2026

[201_69] 表格支持鼠标缩放

如何测试

  1. 插入标宽有框表格/普通有框表格,光标此时在表格内,应该在表格框外看到蓝色的正方形缩放手柄
  2. 标宽有框表格只有底部一个手柄,可以向下拖拽;普通有框表格有右侧、底部、右下角三个手柄,可以向右、向下、对角线拖拽
  3. 拖拽手柄时,对应的整行/列应当先均分空间再缩放大小(例如拖动右侧的手柄时,表格的各列宽度应当均分后再整体缩放)
  4. 拖拽过程应该符合预期。鼠标在手柄范围内应该变成对应的样式,且可以拖动;鼠标在手柄外则是默认样式,且不能拖动
  5. 按照正常逻辑,应当是先确定表格大小再微调具体单元格宽高。因此拖拽表格整体大小后再拖拽内部表格线进行微调,应该符合预期
  6. 表格的右侧边框和下侧边框应该可以拖拽,仅影响最后一行/列的大小,不与缩放手柄冲突
  7. 目前暂不支持大表格/小表格的缩放,理论上这两种表格的需求量不大

2026/1/28

What

  1. 实现了表格支持鼠标缩放
  2. 微调表格的交互优化的实现

How

在开发文档中详细阐述

Copilot AI review requested due to automatic review settings January 28, 2026 13:46
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

为表格新增“鼠标拖拽缩放(整体 resize handles)”能力,并配套调整表格格线拖拽(line resizing)交互所需的数据与事件处理。

Changes:

  • 在渲染层新增表格缩放手柄绘制与 bbox 缓存,并基于表格类型(wide/plain)决定手柄数量
  • 在鼠标事件层新增表格整体缩放的 hit/start/apply/stop 流程,并将原表格格线拖拽逻辑重构为 “line resizing”
  • 扩展 table-loc? 消息返回信息,补充 wide/plain 标记用于交互判断

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/Typeset/Boxes/Composite/composite_boxes.cpp table-loc? 的 cell 场景追加 wide/plain 信息,支持上层交互判断
src/Edit/Interface/edit_repaint.cpp 新增表格缩放手柄绘制逻辑与 table bbox 缓存/失效刷新
src/Edit/Interface/edit_mouse.cpp 重构表格格线拖拽并新增表格整体缩放拖拽逻辑与鼠标光标命中处理
src/Edit/Interface/edit_interface.hpp 增加表格缩放/格线拖拽所需状态字段与接口声明、以及 table bbox 缓存字段
devel/201_69.md 补充该需求的开发/测试说明文档

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +84 to +85
int table_resizing_type= 0; // 0: N/A; 1: line resizing; 2: scale resizing
bool table_line_vertical= false;
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

table_resizing_type uses magic numbers (0/1/2) to represent states. Consider replacing with named constants or an enum (e.g., enum class table_resize_mode { none, line, scale };) to make the state machine easier to read and harder to misuse.

Copilot uses AI. Check for mistakes.
Comment on lines +303 to +308
table_hit current_hit;
cursor current_cursor= get_cursor ();
if (current_cursor->valid)
table_line_hit (current_cursor->ox, current_cursor->oy, current_hit);
table_scale_wide_flag= current_hit.wide_flag;

Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

draw_table_resize_handles reads current_hit.wide_flag even when current_cursor->valid is false (or table_line_hit early-returns without initializing current_hit), which is undefined behavior and can make table_scale_wide_flag random. Initialize current_hit (or at least current_hit.wide_flag) before use and/or guard the assignment on current_cursor->valid/table_line_hit results.

Copilot uses AI. Check for mistakes.
Comment on lines +858 to +862
if (!is_zero (last_table_brec)) {
// 检测鼠标是否在表格 handles 上
if (table_scale_hit (x, y)) {
over_handles= true;
if (table_scale_handle_type == 1) handle_cursor= "size_ver";
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

In the mouse-move path, the if (!is_zero (last_table_brec)) { ... } else if (!is_zero (last_image_brec)) { ... } structure prevents image handle hit-testing and image hover/popup behavior whenever a table bbox is cached (e.g., an IMAGE inside a TABLE). Consider checking table handles first, but still falling through to image handle/hover logic when the pointer is not over a table handle.

Copilot uses AI. Check for mistakes.
Comment on lines +725 to +729
if (table_scale_handle_type == 2 || table_scale_handle_type == 3)
scale_x= max (
0.1, (double) (table_scale_initial_width + x - table_scale_start_x) /
(double) table_scale_initial_width);

Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

table_scale_apply divides by table_scale_initial_width / table_scale_initial_height when computing scale_x/scale_y. If either initial dimension is 0, this will divide by zero. Add guards (e.g., early return when initial width/height <= 0) before the division, and ensure table_scale_handle_type that needs an axis can’t trigger scaling with a zero initial size.

Copilot uses AI. Check for mistakes.
(double) table_scale_initial_height);

array<int> extents= et->table_get_extents ();
int rows= extents[0], cols= extents[1];
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

table_get_extents() can return an empty array when search_format() is nil; extents[0] / extents[1] would then be out-of-bounds. Add a check (e.g., if (N(extents) < 2 || extents[0] <= 0 || extents[1] <= 0) return;) before using rows/cols in scaling.

Suggested change
int rows= extents[0], cols= extents[1];
if (N (extents) < 2 || extents[0] <= 0 || extents[1] <= 0)
return;
int rows= extents[0], cols= extents[1];

Copilot uses AI. Check for mistakes.
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