9ecb8b61f8
- Allow manual "Run now" while the scheduler is paused: pause now stops only automatic scheduled runs (RunDue), not the user's explicit action. Drop the paused guard in Service.RunNow and the UI pause dialog; update tests. - Cap the details metadata caption width via a new captionValueLayout so a wider window feeds extra space to the value column instead of the short caption. - Reorganize the Settings tab into two columns (Application+Queue / Storage+About) with Save spanning the full width; move the Autostart status onto its own line. - Condense the Jobs list rows with compactVBoxLayout to fit more jobs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
153 lines
3.8 KiB
Go
153 lines
3.8 KiB
Go
package ui
|
|
|
|
import (
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/theme"
|
|
)
|
|
|
|
type minWidthLayout struct {
|
|
width float32
|
|
}
|
|
|
|
func (l minWidthLayout) MinSize(objects []fyne.CanvasObject) fyne.Size {
|
|
width := l.width
|
|
var height float32
|
|
for _, object := range objects {
|
|
if !object.Visible() {
|
|
continue
|
|
}
|
|
min := object.MinSize()
|
|
if min.Width > width {
|
|
width = min.Width
|
|
}
|
|
if min.Height > height {
|
|
height = min.Height
|
|
}
|
|
}
|
|
return fyne.NewSize(width, height)
|
|
}
|
|
|
|
func (l minWidthLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) {
|
|
for _, object := range objects {
|
|
if !object.Visible() {
|
|
continue
|
|
}
|
|
object.Move(fyne.NewPos(0, 0))
|
|
object.Resize(size)
|
|
}
|
|
}
|
|
|
|
// compactVBoxLayout stacks children vertically with a configurable gap between
|
|
// them, producing tighter rows than container.NewVBox (which inserts
|
|
// theme.Padding() between every child). A negative spacing pulls neighbouring
|
|
// rows together so they overlap the labels' built-in vertical padding, which is
|
|
// how the details metadata is condensed to fit 720p screens.
|
|
type compactVBoxLayout struct {
|
|
spacing float32
|
|
}
|
|
|
|
func (l compactVBoxLayout) MinSize(objects []fyne.CanvasObject) fyne.Size {
|
|
var w, h float32
|
|
var visible int
|
|
for _, o := range objects {
|
|
if !o.Visible() {
|
|
continue
|
|
}
|
|
min := o.MinSize()
|
|
if min.Width > w {
|
|
w = min.Width
|
|
}
|
|
h += min.Height
|
|
visible++
|
|
}
|
|
if visible > 1 {
|
|
h += l.spacing * float32(visible-1)
|
|
}
|
|
return fyne.NewSize(w, h)
|
|
}
|
|
|
|
func (l compactVBoxLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) {
|
|
var y float32
|
|
for _, o := range objects {
|
|
if !o.Visible() {
|
|
continue
|
|
}
|
|
h := o.MinSize().Height
|
|
o.Move(fyne.NewPos(0, y))
|
|
o.Resize(fyne.NewSize(size.Width, h))
|
|
y += h + l.spacing
|
|
}
|
|
}
|
|
|
|
// fixedHeightLayout forces its contents to a fixed height while leaving the
|
|
// width to the parent container. It is used to reserve a stable amount of space
|
|
// for the activity panel so a neighbouring widget can absorb the rest.
|
|
type fixedHeightLayout struct {
|
|
height float32
|
|
}
|
|
|
|
func (l fixedHeightLayout) MinSize(objects []fyne.CanvasObject) fyne.Size {
|
|
var width float32
|
|
for _, object := range objects {
|
|
if !object.Visible() {
|
|
continue
|
|
}
|
|
if min := object.MinSize(); min.Width > width {
|
|
width = min.Width
|
|
}
|
|
}
|
|
return fyne.NewSize(width, l.height)
|
|
}
|
|
|
|
func (l fixedHeightLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) {
|
|
for _, object := range objects {
|
|
if !object.Visible() {
|
|
continue
|
|
}
|
|
object.Move(fyne.NewPos(0, 0))
|
|
object.Resize(fyne.NewSize(size.Width, l.height))
|
|
}
|
|
}
|
|
|
|
// captionValueLayout places a fixed-width caption on the left and lets the value
|
|
// fill the remaining width, separated by one theme padding. Capping the caption
|
|
// stops it from growing with the window (as an even two-column grid would), so
|
|
// the extra space a wider window provides goes entirely to the value column. It
|
|
// expects exactly two children: caption first, value second.
|
|
type captionValueLayout struct {
|
|
captionWidth float32
|
|
}
|
|
|
|
func (l captionValueLayout) MinSize(objects []fyne.CanvasObject) fyne.Size {
|
|
if len(objects) != 2 {
|
|
return fyne.Size{}
|
|
}
|
|
captionMin, valueMin := objects[0].MinSize(), objects[1].MinSize()
|
|
height := captionMin.Height
|
|
if valueMin.Height > height {
|
|
height = valueMin.Height
|
|
}
|
|
return fyne.NewSize(l.captionWidth+theme.Padding()+valueMin.Width, height)
|
|
}
|
|
|
|
func (l captionValueLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) {
|
|
if len(objects) != 2 {
|
|
return
|
|
}
|
|
caption, value := objects[0], objects[1]
|
|
captionWidth := l.captionWidth
|
|
if captionWidth > size.Width {
|
|
captionWidth = size.Width
|
|
}
|
|
caption.Move(fyne.NewPos(0, 0))
|
|
caption.Resize(fyne.NewSize(captionWidth, size.Height))
|
|
|
|
valueX := captionWidth + theme.Padding()
|
|
valueWidth := size.Width - valueX
|
|
if valueWidth < 0 {
|
|
valueWidth = 0
|
|
}
|
|
value.Move(fyne.NewPos(valueX, 0))
|
|
value.Resize(fyne.NewSize(valueWidth, size.Height))
|
|
}
|