R5.1: in a table, ElyDoc's panel shows the Table group first (component 9ff403d keys folds by title); three rounds, R3 PASS
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
c3f6684a46
commit
b5bfb77ba0
12 files changed
+131
-30
No files matched your search
Generated
+12
-12
@@ -275,7 +275,7 @@ version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -286,7 +286,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1751,7 +1751,7 @@ dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users 0.5.3",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1923,7 +1923,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ely-gpui-component"
|
||||
version = "0.1.1"
|
||||
source = "git+https://git.zacharyzhang.com/ZacharyZhang-NY/Ely-GPUI-Components?rev=8fd3e431db3c57c67328869cffdcd43d5f7fd056#8fd3e431db3c57c67328869cffdcd43d5f7fd056"
|
||||
source = "git+https://git.zacharyzhang.com/ZacharyZhang-NY/Ely-GPUI-Components?rev=9ff403df31894b07904cfd197a074d1ff95e6de1#9ff403df31894b07904cfd197a074d1ff95e6de1"
|
||||
dependencies = [
|
||||
"alacritty_terminal",
|
||||
"anyhow",
|
||||
@@ -2334,7 +2334,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4501,7 +4501,7 @@ version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "536bfad37a309d62069485248eeaba1e8d9853aaf951caaeaed0585a95346f08"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4666,7 +4666,7 @@ version = "0.50.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6418,7 +6418,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7006,7 +7006,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"psm",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7346,7 +7346,7 @@ dependencies = [
|
||||
"getrandom 0.4.3",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7696,7 +7696,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
|
||||
dependencies = [
|
||||
"memoffset",
|
||||
"tempfile",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8495,7 +8495,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ jiff = "0.2"
|
||||
anyhow = "1"
|
||||
directories = "6"
|
||||
dunce = "1"
|
||||
ely-gpui-component = { git = "https://git.zacharyzhang.com/ZacharyZhang-NY/Ely-GPUI-Components", rev = "8fd3e431db3c57c67328869cffdcd43d5f7fd056" }
|
||||
ely-gpui-component = { git = "https://git.zacharyzhang.com/ZacharyZhang-NY/Ely-GPUI-Components", rev = "9ff403df31894b07904cfd197a074d1ff95e6de1" }
|
||||
env_logger = "0.11"
|
||||
gpui = { package = "gpui-pre", version = "=0.3.8", default-features = false, features = ["stacker"] }
|
||||
gpui_platform = { package = "gpui-pre-platform", version = "=0.3.8", features = ["font-kit", "wayland", "x11"] }
|
||||
|
||||
@@ -40,7 +40,7 @@ site/ 官网(Vite 8、pnpm、TypeScript,无框架;等轴 SVG 积木
|
||||
|
||||
## 组件映射
|
||||
|
||||
依赖 `ely-gpui-component`(pin 8fd3e43,gpui 为 crates.io 的 `gpui-pre` =0.3.8)。名字取自 `reference/Ely-GPUI-Components/src`。gpui 用法规则见该仓库 `AGENTS.md`。`tests/scripts/agents_md.py` 核对下表每个名字都是组件库公开项。
|
||||
依赖 `ely-gpui-component`(pin 9ff403d,gpui 为 crates.io 的 `gpui-pre` =0.3.8)。名字取自 `reference/Ely-GPUI-Components/src`。gpui 用法规则见该仓库 `AGENTS.md`。`tests/scripts/agents_md.py` 核对下表每个名字都是组件库公开项。
|
||||
|
||||
| 需要 | 用 |
|
||||
| --- | --- |
|
||||
|
||||
@@ -250,15 +250,15 @@ impl Render for Props {
|
||||
let grid = if graphic {
|
||||
grid.group(self.object_group(cx))
|
||||
} else {
|
||||
let grid = grid
|
||||
.group(self.text_group(window, cx))
|
||||
.group(self.paragraph_group(cx))
|
||||
.group(self.style_group(cx))
|
||||
.group(self.page_group(cx));
|
||||
match self.state(".uno:DeleteTable", cx).as_deref() {
|
||||
// In a table, its group leads, as in Word.
|
||||
let grid = match self.state(".uno:DeleteTable", cx).as_deref() {
|
||||
Some("enabled") => grid.group(self.table_group(cx)),
|
||||
_ => grid,
|
||||
}
|
||||
};
|
||||
grid.group(self.text_group(window, cx))
|
||||
.group(self.paragraph_group(cx))
|
||||
.group(self.style_group(cx))
|
||||
.group(self.page_group(cx))
|
||||
};
|
||||
div()
|
||||
.size_full()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use ely_gpui_component::{data_display::PropertyGroup, primitives::IconName};
|
||||
use ely_office::panel::{Panel, color_state, font_box, palette, row, size_menu, toggle};
|
||||
use gpui::{App, Context, SharedString, Window};
|
||||
use gpui::{App, Context, InteractiveElement, ParentElement, SharedString, Window, div};
|
||||
|
||||
use super::Props;
|
||||
use crate::docs::Docs;
|
||||
@@ -77,7 +77,12 @@ impl Props {
|
||||
PropertyGroup::new(tip("doc.props.text"))
|
||||
.row(tip("doc.props.font"), font)
|
||||
.row(tip("doc.props.size"), size_menu(self, "doc-props-size", cx))
|
||||
.row(tip("doc.props.effects"), effects)
|
||||
.row(
|
||||
tip("doc.props.effects"),
|
||||
div()
|
||||
.debug_selector(|| "doc-props-text".into())
|
||||
.child(effects),
|
||||
)
|
||||
.row(
|
||||
tip("doc.props.color"),
|
||||
palette(&this, "format.color", (color, AUTOMATIC), None, cx),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use ely_gpui_component::{buttons::Button, data_display::PropertyGroup, theme::ControlSize};
|
||||
use ely_office::panel::{button, color_state, palette, row, send, toggle};
|
||||
use gpui::{AnyElement, Context, IntoElement, SharedString};
|
||||
use gpui::{AnyElement, Context, InteractiveElement, IntoElement, ParentElement, SharedString, div};
|
||||
|
||||
use super::Props;
|
||||
use crate::docs::Docs;
|
||||
@@ -14,11 +14,13 @@ impl Props {
|
||||
PropertyGroup::new(tip("doc.props.table"))
|
||||
.row(
|
||||
tip("doc.props.rows"),
|
||||
row([
|
||||
button(self, "table.row_above", "doc.props.above_row", why, cx),
|
||||
button(self, "table.row_below", "doc.props.below_row", why, cx),
|
||||
button(self, "table.delete_rows", "doc.props.delete", why, cx),
|
||||
]),
|
||||
div()
|
||||
.debug_selector(|| "doc-props-table".into())
|
||||
.child(row([
|
||||
button(self, "table.row_above", "doc.props.above_row", why, cx),
|
||||
button(self, "table.row_below", "doc.props.below_row", why, cx),
|
||||
button(self, "table.delete_rows", "doc.props.delete", why, cx),
|
||||
])),
|
||||
)
|
||||
.row(
|
||||
tip("doc.props.columns"),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use ely_gpui_component::theme::Theme;
|
||||
use ely_lok::LokError;
|
||||
use ely_office::panel::Panel as _;
|
||||
use gpui::{Entity, TestAppContext};
|
||||
@@ -296,3 +297,82 @@ fn quick_spacing_edits_keep_each_other() {
|
||||
"both quick edits land"
|
||||
);
|
||||
}
|
||||
|
||||
/// A window root that shows the panel.
|
||||
struct Shown(Entity<Props>);
|
||||
|
||||
impl gpui::Render for Shown {
|
||||
fn render(
|
||||
&mut self,
|
||||
_: &mut gpui::Window,
|
||||
_: &mut gpui::Context<Self>,
|
||||
) -> impl gpui::IntoElement {
|
||||
use gpui::{ParentElement as _, Styled as _};
|
||||
gpui::div().size_full().child(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
/// The top of the element marked `selector`.
|
||||
fn top(cx: &mut gpui::VisualTestContext, selector: &'static str) -> Option<gpui::Pixels> {
|
||||
// Past reduced motion's 1ms folds.
|
||||
for _ in 0..3 {
|
||||
std::thread::sleep(std::time::Duration::from_millis(2));
|
||||
cx.update(|window, _| window.refresh());
|
||||
cx.run_until_parked();
|
||||
}
|
||||
cx.debug_bounds(selector).map(|bounds| bounds.origin.y)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn in_a_table_the_table_group_comes_first_and_folds_stay_put() {
|
||||
const DOWN: i32 = 1024;
|
||||
const UP: i32 = 1025;
|
||||
let dir = tempfile::tempdir().expect("a temp dir");
|
||||
let mut cx = TestAppContext::single();
|
||||
let Some(docs) = docs(&mut cx, dir.path()) else {
|
||||
eprintln!("SKIP: no LOK build");
|
||||
return;
|
||||
};
|
||||
cx.update(|cx| {
|
||||
ely_gpui_component::init_for_tests(cx);
|
||||
Theme::update(cx, |theme| theme.reduced_motion = true);
|
||||
});
|
||||
blank(&mut cx, &docs);
|
||||
type_into(&mut cx, &docs, "Table");
|
||||
let props = panel(&mut cx, &docs);
|
||||
let window = cx.add_window(|_, _| Shown(props.clone()));
|
||||
let mut shown = gpui::VisualTestContext::from_window(window.into(), &cx);
|
||||
assert_eq!(
|
||||
top(&mut shown, "doc-props-table"),
|
||||
None,
|
||||
"no table, no group"
|
||||
);
|
||||
let header = gpui::point(gpui::px(10.0), gpui::px(12.0));
|
||||
shown.simulate_click(header, gpui::Modifiers::none());
|
||||
assert_eq!(top(&mut shown, "doc-props-text"), None, "Text folds");
|
||||
shown.simulate_click(header, gpui::Modifiers::none());
|
||||
assert!(top(&mut shown, "doc-props-text").is_some(), "Text opens");
|
||||
with_window(&mut cx, &docs, |docs, _, cx| {
|
||||
docs.insert_table(3.0, 2.0, cx)
|
||||
});
|
||||
let in_table = |app: &gpui::App| props.read(app).state(".uno:DeleteTable", app);
|
||||
settle(&cx, |app| in_table(app).as_deref() == Some("enabled"));
|
||||
let table = top(&mut shown, "doc-props-table").expect("the table group");
|
||||
let text = top(&mut shown, "doc-props-text").expect("the text group");
|
||||
assert!(table < text, "the table group leads: {table:?} vs {text:?}");
|
||||
keys(&mut cx, &docs, &[UP]);
|
||||
settle(&cx, |app| in_table(app).as_deref() != Some("enabled"));
|
||||
shown.simulate_click(header, gpui::Modifiers::none());
|
||||
assert_eq!(top(&mut shown, "doc-props-text"), None, "Text folds again");
|
||||
keys(&mut cx, &docs, &[DOWN]);
|
||||
settle(&cx, |app| in_table(app).as_deref() == Some("enabled"));
|
||||
assert!(top(&mut shown, "doc-props-table").is_some(), "Table opens");
|
||||
assert_eq!(top(&mut shown, "doc-props-text"), None, "Text stays folded");
|
||||
keys(&mut cx, &docs, &[UP]);
|
||||
settle(&cx, |app| in_table(app).as_deref() != Some("enabled"));
|
||||
assert_eq!(
|
||||
top(&mut shown, "doc-props-text"),
|
||||
None,
|
||||
"and after the table"
|
||||
);
|
||||
}
|
||||
@@ -36,7 +36,7 @@ fetch() { # name url rev [sparse paths...]
|
||||
echo "fetch $name $rev"
|
||||
}
|
||||
|
||||
fetch Ely-GPUI-Components https://git.zacharyzhang.com/ZacharyZhang-NY/Ely-GPUI-Components.git 8fd3e431db3c57c67328869cffdcd43d5f7fd056
|
||||
fetch Ely-GPUI-Components https://git.zacharyzhang.com/ZacharyZhang-NY/Ely-GPUI-Components.git 9ff403df31894b07904cfd197a074d1ff95e6de1
|
||||
fetch zed https://github.com/zed-industries/zed.git 1a28cff4b409169bac058bca40dfbfeb7621d19b
|
||||
fetch libreoffice-core https://github.com/LibreOffice/core.git 8221e31b3ac356a1623c672912a3d2b492f7e3d1 \
|
||||
include/LibreOfficeKit libreofficekit desktop/source/lib desktop/inc \
|
||||
|
||||
@@ -243,3 +243,10 @@
|
||||
- [ ] R4.9 ElyMark:“段落”“格式”菜单与 Typora 同项同键(Ctrl+1–6、Ctrl+0、Ctrl+=/-、Ctrl+B/I/U、Ctrl+Shift+`、Alt+Shift+5、Ctrl+K、Ctrl+Shift+I、Ctrl+\、Ctrl+T、Ctrl+Shift+K/M/Q/[/]);源码模式 Ctrl+/;字号 Ctrl+Shift+=/-/0;专注 F8、打字机 F9;表格菜单加移动行列;复制为 Markdown Ctrl+Shift+C、粘贴为纯文本 Ctrl+Shift+V
|
||||
- [ ] R4.10 ElyMark:右键菜单照 Typora 按目标变化:剪贴板行(剪切、复制、粘贴、删除)、复制/粘贴为 ▸(Markdown、HTML 代码、纯文本、粘贴为纯文本)、格式行、段落 ▸ 或表格 ▸ 或代码项、插入 ▸、链接(打开、复制地址)、图片(打开所在位置、删除图片)、删除块;预览只读时只留复制类
|
||||
- [ ] R4.11 验收:同一份样本在 ElyMark 与 Typora 的真窗口截图逐项对照;帮助、PRD、`agents.md` 随之;逐条核对表
|
||||
|
||||
## R5 ElyDoc 照 Word 的右键与表格(用户 2026-10-13 报:右键没反应;表格不能加行列、不能调大小;三项方案经用户确认)
|
||||
|
||||
- [x] R5.1 属性栏:光标在表格里时表格组排在最前(同 Word 的表格布局页签),否则次序不变(DOC-07) — R3 PASS(组件 9ff403d:属性组按标题记折叠)
|
||||
- [ ] R5.2 右键菜单(DOC-02、07、08、11、12):原先只在内核菜单带拼写建议时才显示,其余右键无反应;改为照 Word 按目标出 Ely 的菜单,开在所点之处:剪切、复制、粘贴为图标行;正文为链接…、新建批注;表格单元格另有插入 ▸(左侧列、右侧列、上方行、下方行)、删除 ▸(行、列、表格)、合并单元格、拆分单元格 ▸(两列、两行)、平均分布各行与各列;图片为文字环绕 ▸、置于顶层 ▸、置于底层 ▸、插入题注…、新建批注;拼写错词时建议与“全部忽略”在最上。目标与各项可否取自内核这次给的菜单,命令只经 `COMMANDS`,文案进中英目录
|
||||
- [ ] R5.3 拖动表格边线(DOC-07):读内核的 `LOK_CALLBACK_TABLE_SELECTED`(光标所在表格的列与行边线),指针在边线上变为调整指针,拖动时画参考线,松开以 `.uno:TableChangeCurrentBorderPosition` 改列宽或行高(左、内、右列边线;内、下行边线),一步撤销,按读到边线时的修订执行;内核在 LOK 下有意不处理边线的指针与拖动(`SwEditWin::changeMousePointer`、`RulerColumnDrag` 依赖 LOK 没有的标尺);未进入的表格先单击一次
|
||||
- [ ] R5.4 验收:Windows 真窗口逐项核对(右键四种目标、加行加列、拖动列宽与行高、撤销、保存后重开);`agents.md` 随之;逐条核对表
|
||||
@@ -0,0 +1,3 @@
|
||||
FAIL
|
||||
|
||||
- apps/ely-doc/src/props.rs:254 — Prepending Table transfers collapsed states between unrelated groups. The pinned `PropertyGrid` stores each fold under its numeric position (`fold-{ix}`). Collapse Text outside a table, then insert a table: Table inherits the collapsed state, hiding its controls, while Text unexpectedly reopens. A Windows GPUI/LOK probe reproduced `table=None, text=Some(115px)` with this diff; restoring only the previous ordering made the same probe pass with `table=Some(690px), text=None`. Give groups stable state identities through the shared component and cover entering/leaving a table with previously collapsed groups. The existing 10 property-panel tests pass but miss this transition. Evidence: `.work/R5.1-r1-review/fold-regression.log` and `fold-baseline.log`.
|
||||
@@ -0,0 +1,3 @@
|
||||
FAIL
|
||||
|
||||
- reference/Ely-GPUI-Components/src/data_display/records.rs:106 — The added `PropertyGroup` documentation violates the explicit one-line, ten-word comment rule. At b3d6cc0, it extends the preceding comment to two lines and adds eleven words: “Its title keys its fold, so titles differ within a grid.” Condense the documentation into one line of at most ten words. Evidence: `.work/R5.1-r2-review/new-comment-check.log`.
|
||||
@@ -0,0 +1 @@
|
||||
PASS
|
||||
Reference in new issue
Block a user