fix: window minimum, stock spacing layout, sidebar width floor
Part A stages 1-3 of the GUI layout cleanup plan: - Stage 1 (F1-F3): delete settingsControlWidth's redundant wrapper (the Border centre slot already stretches controls), truncate the config path label, and name the default window size so it can be asserted against. Settings no longer widens the window past what it asks for. - Stage 2 (F4-F5): drop compactVBoxLayout for the stock layout.NewCustomPaddedVBoxLayout and a single derived rowOverlap() spacing, replacing three hand-tuned spacing constants. - Stage 3 (F7): delete the inert 400px sidebar width floor; the Border left slot already renders it at content MinSize. See docs/PLAN-gui-layout.md.
This commit is contained in:
+49
-12
@@ -137,21 +137,17 @@ func findFirst(root fyne.CanvasObject, match func(fyne.CanvasObject) bool) fyne.
|
||||
|
||||
// jobsSidebar narrows the search to the left pane. The details panel has a
|
||||
// widget.List of its own (the activity log), so a search from the whole view
|
||||
// would find the wrong one.
|
||||
// would find the wrong one. newJobsView assembles the panel as
|
||||
// container.NewBorder(nil, nil, sidebar, nil, ...); NewBorder keeps the centre
|
||||
// object first and appends the border slots after it, so panel.Objects[1] is
|
||||
// the left (sidebar) slot.
|
||||
func jobsSidebar(t *testing.T, content fyne.CanvasObject) fyne.CanvasObject {
|
||||
t.Helper()
|
||||
found := findFirst(content, func(o fyne.CanvasObject) bool {
|
||||
wrapper, ok := o.(*fyne.Container)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_, ok = wrapper.Layout.(minWidthLayout)
|
||||
return ok
|
||||
})
|
||||
if found == nil {
|
||||
t.Fatal("jobs view has no fixed-width sidebar")
|
||||
panel, ok := content.(*fyne.Container)
|
||||
if !ok || len(panel.Objects) < 2 {
|
||||
t.Fatal("jobs view is not the expected Border container")
|
||||
}
|
||||
return found
|
||||
return panel.Objects[1]
|
||||
}
|
||||
|
||||
func jobsList(t *testing.T, content fyne.CanvasObject) *widget.List {
|
||||
@@ -166,6 +162,24 @@ func jobsList(t *testing.T, content fyne.CanvasObject) *widget.List {
|
||||
return found.(*widget.List)
|
||||
}
|
||||
|
||||
// jobsToolbar finds the add/edit/run/pause/delete button row inside the
|
||||
// sidebar, identified by its first child being the "New job" button.
|
||||
func jobsToolbar(t *testing.T, content fyne.CanvasObject) fyne.CanvasObject {
|
||||
t.Helper()
|
||||
found := findFirst(jobsSidebar(t, content), func(o fyne.CanvasObject) bool {
|
||||
wrapper, ok := o.(*fyne.Container)
|
||||
if !ok || len(wrapper.Objects) == 0 {
|
||||
return false
|
||||
}
|
||||
button, ok := wrapper.Objects[0].(*widget.Button)
|
||||
return ok && button.Text == "New job"
|
||||
})
|
||||
if found == nil {
|
||||
t.Fatal("jobs sidebar has no toolbar row")
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
func jobsViewToggle(t *testing.T, content fyne.CanvasObject) *widget.Button {
|
||||
t.Helper()
|
||||
found := findFirst(jobsSidebar(t, content), func(o fyne.CanvasObject) bool {
|
||||
@@ -258,6 +272,29 @@ func TestJobListViewCompactConfigOpensCompact(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestJobsSidebarWidthIsItsContent is the regression guard for F7: nothing
|
||||
// but the sidebar's own content (here, the toolbar row) should impose a
|
||||
// width floor on it.
|
||||
func TestJobsSidebarWidthIsItsContent(t *testing.T) {
|
||||
testApp := test.NewApp()
|
||||
defer testApp.Quit()
|
||||
w := testApp.NewWindow("test")
|
||||
defer w.Close()
|
||||
|
||||
store := newTestStore(t)
|
||||
svc := app.NewService(store, nil)
|
||||
defer svc.Stop()
|
||||
|
||||
content, _ := newJobsView(w, svc)
|
||||
w.SetContent(content)
|
||||
|
||||
sidebarWidth := jobsSidebar(t, content).MinSize().Width
|
||||
toolbarWidth := jobsToolbar(t, content).MinSize().Width
|
||||
if sidebarWidth != toolbarWidth {
|
||||
t.Errorf("sidebar MinSize().Width = %v, want it to equal the toolbar row's %v", sidebarWidth, toolbarWidth)
|
||||
}
|
||||
}
|
||||
|
||||
func TestViewToggleTextNamesTheAction(t *testing.T) {
|
||||
cases := []struct {
|
||||
current domain.JobListView
|
||||
|
||||
Reference in New Issue
Block a user