aboutsummaryrefslogtreecommitdiff
path: root/gui/internal/ui
diff options
context:
space:
mode:
Diffstat (limited to 'gui/internal/ui')
-rw-r--r--gui/internal/ui/plan.go85
1 files changed, 65 insertions, 20 deletions
diff --git a/gui/internal/ui/plan.go b/gui/internal/ui/plan.go
index f4ecb91..87afdff 100644
--- a/gui/internal/ui/plan.go
+++ b/gui/internal/ui/plan.go
@@ -40,12 +40,13 @@ type planView struct {
previewNote *gtk.Label
picture *gtk.Picture
- pictureFrame *gtk.ScrolledWindow
previewText *gtk.TextView
previewScroll *gtk.ScrolledWindow
previewTmp string
previewFor string
+ detailPane *gtk.Paned
renderedDir string
+ previewHeight int
previewOff bool
startSelected bool
menu *gtk.Popover
@@ -128,15 +129,15 @@ func newPlanView(w *Window) *planView {
p.previewNote.SetEllipsize(pango.EllipsizeEnd)
p.previewNote.SetMaxWidthChars(20)
p.previewNote.AddCSSClass("dim-label")
+ // The picture fills whatever the divider leaves it. Inside a scrolled
+ // window it would be given its smallest size instead, which is what
+ // made the page a stamp (his report, 2026-09-17).
p.picture = gtk.NewPicture()
p.picture.SetCanShrink(true)
p.picture.SetContentFit(gtk.ContentFitContain)
p.picture.SetVisible(false)
- pictureFrame := gtk.NewScrolledWindow()
- pictureFrame.SetChild(p.picture)
- pictureFrame.SetSizeRequest(-1, 280)
- pictureFrame.SetVisible(false)
- p.pictureFrame = pictureFrame
+ p.picture.SetVExpand(true)
+ p.picture.SetHExpand(true)
p.previewText = gtk.NewTextView()
p.previewText.SetEditable(false)
p.previewText.SetMonospace(true)
@@ -145,17 +146,28 @@ func newPlanView(w *Window) *planView {
p.previewText.SetTopMargin(6)
previewScroll := gtk.NewScrolledWindow()
previewScroll.SetChild(p.previewText)
- previewScroll.SetSizeRequest(-1, 260)
previewScroll.SetVisible(false)
+ previewScroll.SetVExpand(true)
p.previewScroll = previewScroll
- detailBox := gtk.NewBox(gtk.OrientationVertical, 0)
- detailBox.Append(detailScroll)
- detailBox.Append(gtk.NewSeparator(gtk.OrientationHorizontal))
- detailBox.Append(p.previewNote)
- detailBox.Append(pictureFrame)
- detailBox.Append(previewScroll)
- detailBox.SetSizeRequest(340, -1)
+ previewBox := gtk.NewBox(gtk.OrientationVertical, 0)
+ previewBox.Append(p.previewNote)
+ previewBox.Append(p.picture)
+ previewBox.Append(previewScroll)
+
+ // The divider between the explanation and the preview is the size
+ // control: drag it, and the preview stays that tall (his request,
+ // 2026-09-17).
+ p.detailPane = gtk.NewPaned(gtk.OrientationVertical)
+ p.detailPane.SetStartChild(detailScroll)
+ p.detailPane.SetEndChild(previewBox)
+ p.detailPane.SetResizeStartChild(true)
+ p.detailPane.SetResizeEndChild(false)
+ p.detailPane.SetShrinkEndChild(false)
+ p.detailPane.SetVExpand(true)
+ p.detailPane.SetSizeRequest(340, -1)
+ p.detailPane.Connect("notify::position", p.rememberPreviewHeight)
+ detailBox := p.detailPane
// A pane the user can drag: on a narrow window the list needs the room,
// on a wide one the explanation does.
@@ -549,7 +561,7 @@ func (p *planView) showPreview(rel string) {
return
}
p.previewFor = path
- p.pictureFrame.SetVisible(false)
+ p.picture.SetVisible(false)
p.previewScroll.SetVisible(false)
p.previewNote.SetText("looking at " + escape(rel) + "...")
if p.previewTmp == "" {
@@ -562,7 +574,7 @@ func (p *planView) showPreview(rel string) {
}
var pv model.Preview
runInBackground(func(ctx context.Context) error {
- pv = model.MakePreview(ctx, path, p.previewTmp)
+ pv = model.MakePreview(ctx, path, p.previewTmp, p.previewHeight)
return nil
}, func(error) {
if p.previewFor != path {
@@ -573,7 +585,6 @@ func (p *planView) showPreview(rel string) {
case model.PreviewImage:
p.picture.SetFilename(pv.Image)
p.picture.SetVisible(true)
- p.pictureFrame.SetVisible(true)
// The picture is loaded, so the page rendered for the row
// before it can go.
p.dropRendered()
@@ -588,14 +599,48 @@ func (p *planView) showPreview(rel string) {
})
}
-// applyPrefs turns the file preview on or off, and says how a fresh plan
-// starts.
+// rememberPreviewHeight keeps what a drag of the divider chose, so the next
+// window opens the same way.
+func (p *planView) rememberPreviewHeight() {
+ height := p.detailPane.Height() - p.detailPane.Position()
+ if height < 80 || height == p.previewHeight {
+ return
+ }
+ p.previewHeight = height
+ prefs := p.w.prefs
+ prefs.PreviewHeight = height
+ p.w.prefs = prefs
+ if err := prefs.Save(); err != nil {
+ p.w.setStatus("settings: %v", err)
+ }
+}
+
+// setPreviewHeight puts the divider where a height asks for.
+func (p *planView) setPreviewHeight(height int) {
+ if height < 80 {
+ height = model.DefaultPreviewHeight
+ }
+ p.previewHeight = height
+ if total := p.detailPane.Height(); total > height+80 {
+ p.detailPane.SetPosition(total - height)
+ return
+ }
+ // Before the window is drawn there is no height to subtract from, so
+ // the end child's own request puts the divider in the right place.
+ if child := p.detailPane.EndChild(); child != nil {
+ gtk.BaseWidget(child).SetSizeRequest(-1, height)
+ }
+}
+
+// applyPrefs turns the file preview on or off, sets how tall it is, and
+// says how a fresh plan starts.
func (p *planView) applyPrefs(prefs model.Prefs) {
p.previewOff = !prefs.Preview
p.startSelected = prefs.SelectAll
+ p.setPreviewHeight(prefs.PreviewHeight)
if p.previewOff {
p.previewFor = ""
- p.pictureFrame.SetVisible(false)
+ p.picture.SetVisible(false)
p.previewScroll.SetVisible(false)
p.previewNote.SetText("")
}