Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@
- **文件树。** 升级后用 `TreeState.RowID` 让选中跟随键盘焦点:方向键移动选中,点击行把焦点放到行,“定位当前文件”把焦点移到行。
- **窗口回调只剩三件上游没给的事**:`OnKey`(Splitter 的方向键、Search Everywhere 的方向键与 Enter)、`OnShortcut`(终端和编辑器的复制、剪切、粘贴、Ctrl 系列等“chord”,`Handlers` 只收键、不收 chord)、`OnScroll`/`OnPointer`(树的横向滚轮、标签栏滚轮、纵向滑动时去掉横向分量、指针离开窗口时关悬停)。它们都只做这一件事,不再有分发层。

### 工作台背景的绘制顺序

项目渐变属于窗口边框、按钮栏和面板之间的空隙,工具面板和编辑器仍应是不透色的底色。
根容器通过 `Draw` 在子元素之前绘制渐变。不要为了让渐变铺满窗口,把它放进
绝对定位子元素:Viva 会在普通子元素后绘制绝对定位元素,即使它在声明中排在最前面,
也会让渐变盖住纯色面板。这是应用对绘制层次的使用约束,不需要修改 Viva 的绘制顺序。

`TestVisualWorkbenchGradientStaysBehindPanels` 使用 Metal 无头渲染检查面板空白区域的像素;
修复前会混入项目颜色,修复后必须保持 `#191a1c`。深浅色页面清单通过
`TestVisualWorkbench` 与旧 macOS 采集包对照,截图只作外观证据,不替代原生交互验收。

## 考虑过的备选方案

- 先在 `339e133` 上做完根 Page 再升级 Viva:该版本没有 `DragState` 和 `RowID`,拖拽会先写一遍临时状态机再删,所以直接在新版本上做。
Expand Down
2 changes: 1 addition & 1 deletion desktop/internal/i18n/i18n_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func TestWelcomeLabelsUseSharedLanguage(t *testing.T) {
empty string
}{
{English, "Projects", "Open", "No recent projects"},
{Chinese, "项目", "打开", "还没有最近项目"},
{Chinese, "项目", "打开", "没有最近项目"},
} {
welcome := For(test.language).Welcome
if welcome.Projects != test.projects || welcome.Open != test.open || welcome.EmptyTitle != test.empty {
Expand Down
22 changes: 19 additions & 3 deletions desktop/internal/i18n/shared.generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 42 additions & 0 deletions desktop/internal/logwindow/visual_capture_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//go:build vivahead && lithevisual

package logwindow

import (
"os"
"path/filepath"
"testing"

"github.com/1lck/Lithe-IDEA/desktop/internal/i18n"
"github.com/vivaui/viva/headless"
)

// TestVisualLogs renders synthetic records through the production diagnostics Page.
func TestVisualLogs(t *testing.T) {
out := os.Getenv("LITHE_VISUAL_OUTPUT_DIR")
if out == "" {
t.Skip("set LITHE_VISUAL_OUTPUT_DIR")
}
if err := os.MkdirAll(out, 0755); err != nil {
t.Fatal(err)
}
for _, dark := range []bool{true, false} {
t.Run(map[bool]string{true: "dark", false: "light"}[dark], func(t *testing.T) {
fixture := newExportFixture(t)
fixture.model.started = true
fixture.model.follows = false
ctrl := NewController(WindowOptions{Text: func() *i18n.Messages { return i18n.For(i18n.Chinese) }, Dark: func() bool { return dark }})
w := newWindow(ctrl, fixture.model)
fixture.model.opts.Wake = w.inv.Invalidate
fillRecords(fixture.model, 40)
session, err := headless.Open(w.config(), nil, headless.Options{})
if err != nil {
t.Fatal(err)
}
t.Cleanup(session.Close)
if err := session.Screenshot(filepath.Join(out, "72-logs-"+map[bool]string{true: "dark", false: "light"}[dark]+".png")); err != nil {
t.Fatal(err)
}
})
}
}
2 changes: 1 addition & 1 deletion desktop/internal/settingswindow/autosave_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"github.com/vivaui/viva/ui"
)

// autoSaveCard declares the auto-save switch of the Editor page: changed files are saved a
// autoSaveCard declares the auto-save switch of the General page: changed files are saved a
// moment after typing stops, on by default. The switch hands its change to the settings
// owner at once.
func (w *window) autoSaveCard(c ui.C) {
Expand Down
33 changes: 13 additions & 20 deletions desktop/internal/settingswindow/editor_view_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
)

// TestEditorTabPlacementAppliesAndRestores walks the choices of the editor page's tab card:
// each one reaches its setter at once, the two choices for one row are inert while several
// rows are chosen, and Restore Defaults clears both settings.
// each choice reaches its setter, multiple rows retain overflow, and Restore Defaults
// clears both settings.
func TestEditorTabPlacementAppliesAndRestores(t *testing.T) {
var rows, overflow []string
w := newWindow(NewController(Options{
Expand All @@ -20,30 +20,23 @@ func TestEditorTabPlacementAppliesAndRestores(t *testing.T) {
d := openWindow(t, w)
settings := w.text.Settings

if hit := d.hit(settings.TabsScroll); hit.Role != gfx.RoleRadio || !hit.Checked {
t.Fatalf("an unknown stored overflow does not show scrolling: %+v", hit)
if hit := d.hit(settings.TabsShowIn); hit.Role != gfx.RoleCombobox || hit.Value != settings.TabsScroll {
t.Fatalf("unknown layout did not show scrolling: %+v", hit)
}
d.click(settings.TabsShowIn)
d.click(settings.TabsSqueeze)
if !slices.Equal(overflow, []string{TabOverflowSqueeze}) || len(rows) != 0 {
t.Fatalf("squeeze: rows=%v overflow=%v", rows, overflow)
t.Fatalf("squeeze rows=%v overflow=%v", rows, overflow)
}
d.click(settings.TabsShowIn)
d.click(settings.TabsMultipleRows)
if !slices.Equal(rows, []string{TabRowsMultiple}) {
t.Fatalf("multiple rows: rows=%v", rows)
if !slices.Equal(rows, []string{TabRowsMultiple}) || !slices.Equal(overflow, []string{TabOverflowSqueeze}) {
t.Fatalf("multiple rows changed the retained overflow: rows=%v overflow=%v", rows, overflow)
}
if hit := d.hit(settings.TabsScroll); !hit.Disabled {
t.Fatalf("one-row choice is not disabled under several rows: %+v", hit)
}
d.click(settings.TabsScroll)
if !slices.Equal(overflow, []string{TabOverflowSqueeze}) {
t.Fatalf("a disabled choice applied: overflow=%v", overflow)
}
d.click(settings.TabsOneRow)
if !slices.Equal(rows, []string{TabRowsMultiple, ""}) {
t.Fatalf("one row: rows=%v", rows)
}
if hit := d.hit(settings.TabsSqueeze); hit.Disabled || !hit.Checked {
t.Fatalf("one row lost the squeeze choice: %+v", hit)
d.click(settings.TabsShowIn)
d.click(settings.TabsSqueeze)
if !slices.Equal(rows, []string{TabRowsMultiple, ""}) || d.hit(settings.TabsShowIn).Value != settings.TabsSqueeze {
t.Fatalf("returning to one row lost squeezing: rows=%v", rows)
}
d.click("Restore Defaults")
if !slices.Equal(rows, []string{TabRowsMultiple, "", ""}) || !slices.Equal(overflow, []string{TabOverflowSqueeze, ""}) {
Expand Down
8 changes: 4 additions & 4 deletions desktop/internal/settingswindow/marketplace_view_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,10 +326,10 @@ func TestMarketplaceDividerDragResizeAndRestore(t *testing.T) {
if err := d.driver.Resize(760, 680); err != nil {
t.Fatal(err)
}
// The window leaves 523 pixels beside the sidebar: less the divider and the
// room the detail keeps.
if w.marketApplied != 355 {
t.Fatalf("narrow size = %v, want 355", w.marketApplied)
// The 234-point baseline sidebar leaves 525 pixels: less the divider
// and the room the detail keeps.
if w.marketApplied != 357 {
t.Fatalf("narrow size = %v, want 357", w.marketApplied)
}
checkDetail()
// A click or outward drag at the temporary boundary must not erase the wider
Expand Down
12 changes: 6 additions & 6 deletions desktop/internal/settingswindow/palette.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ type palette struct {

func lightPalette() palette {
return palette{
window: gfx.RGB24(0xffffff), sidebar: gfx.RGB24(0xececee), titleBar: gfx.RGB24(0xe8ebef),
card: gfx.RGB24(0xf7f8fa),
line: gfx.RGB24(0xd8dae0), border: gfx.RGB24(0xc9ccd6),
window: gfx.RGB24(0xf5f5f7), sidebar: gfx.RGB24(0xececee), titleBar: gfx.RGB24(0xffffff),
card: gfx.RGB24(0xffffff),
line: gfx.RGB24(0xededf0), border: gfx.RGB24(0xc9ccd6),
hover: gfx.RGB24(0xf2f3f5),
highlight: gfx.RGB24(0xddf4ff),
selection: gfx.RGB24(0xD0DFFE), selectionIdle: gfx.RGB24(0xE9EAEE),
Expand All @@ -52,9 +52,9 @@ func lightPalette() palette {

func darkPalette() palette {
return palette{
window: gfx.RGB24(0x191a1c), sidebar: gfx.RGB24(0x232427), titleBar: gfx.RGB24(0x28292c),
window: gfx.RGB24(0x1c1d20), sidebar: gfx.RGB24(0x232427), titleBar: gfx.RGB24(0x191a1c),
card: gfx.RGB24(0x2b2d30),
line: gfx.RGB24(0x2e3036), border: gfx.RGB24(0x4e5157),
line: gfx.RGB24(0x34363a), border: gfx.RGB24(0x4e5157),
hover: gfx.RGB24(0x303136),
highlight: gfx.RGB24(0x1f2a3a),
selection: gfx.RGB24(0x2A4371), selectionIdle: gfx.RGB24(0x33353B),
Expand Down Expand Up @@ -84,7 +84,7 @@ func windowTheme(dark bool, p palette) gfx.Theme {
theme.Metrics = theme.Metrics.WithDensity(gfx.DensityCompact)
theme.Background, theme.Foreground = p.window, p.text
theme.Card, theme.CardForeground, theme.CardElevated = p.card, p.text, p.window
theme.Popover, theme.PopoverForeground = p.window, p.text
theme.Popover, theme.PopoverForeground = p.card, p.text
theme.Muted, theme.MutedForeground = p.hover, p.muted
theme.Border, theme.Input, theme.Hover = p.line, p.border, p.hover
theme.Primary, theme.PrimaryForeground = p.accent, p.white
Expand Down
Loading
Loading