From 168aab1ec8e7b33f74e7af0215292589ef41954d Mon Sep 17 00:00:00 2001 From: Stu Leak Date: Thu, 1 Jan 2026 19:51:24 -0500 Subject: [PATCH] feat(ui): Combine Letterbox/Pillarbox into single smart option + bump to dev21 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aspect Ratio Handling Improvements: - Combine "Letterbox" and "Pillarbox" into single "Letterbox/Pillarbox" option - System auto-detects direction based on aspect ratio change - 4:3 → 16:9 = adds pillarbox (vertical bars) - 16:9 → 4:3 = adds letterbox (horizontal bars) - Update hint text for clarity: "Crop removes edges, Letterbox/Pillarbox adds black bars to fit" - Backwards compatibility: legacy "Letterbox"/"Pillarbox" options still work in aspectFilters() Inspired by Topaz's clear UX for aspect ratio handling. Version Updates: - Bump version to v0.1.0-dev21 - Increment build number to 20 - Updates both main.go and FyneApp.toml Options now available: - Auto (crops to fit) - Crop (explicitly crop to target aspect) - Letterbox/Pillarbox (adds black bars, auto-detects direction) - Blur Fill (blurred background with original centered) - Stretch (distorts to fit) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- FyneApp.toml | 4 ++-- main.go | 22 ++++++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/FyneApp.toml b/FyneApp.toml index 3a6abf7..a47ece0 100644 --- a/FyneApp.toml +++ b/FyneApp.toml @@ -2,5 +2,5 @@ Icon = "assets/logo/VT_Icon.png" Name = "VideoTools" ID = "com.leaktechnologies.videotools" -Version = "0.1.0-dev20" -Build = 19 +Version = "0.1.0-dev21" +Build = 20 diff --git a/main.go b/main.go index e1b6bf2..fd2dfbd 100644 --- a/main.go +++ b/main.go @@ -71,7 +71,7 @@ var ( logsDirOnce sync.Once logsDirPath string feedbackBundler = utils.NewFeedbackBundler() - appVersion = "v0.1.0-dev20" + appVersion = "v0.1.0-dev21" hwAccelProbeOnce sync.Once hwAccelSupported atomic.Value // map[string]bool @@ -6932,17 +6932,20 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { // Wrap hint in padded container to ensure proper text wrapping in narrow windows targetAspectHintContainer := container.NewPadded(targetAspectHint) - aspectOptions := widget.NewRadioGroup([]string{"Auto", "Crop", "Letterbox", "Pillarbox", "Blur Fill", "Stretch"}, func(value string) { + aspectOptions := widget.NewRadioGroup([]string{"Auto", "Crop", "Letterbox/Pillarbox", "Blur Fill", "Stretch"}, func(value string) { logging.Debug(logging.CatUI, "aspect handling set to %s", value) state.convert.AspectHandling = value }) aspectOptions.Horizontal = false aspectOptions.Required = true + + // Map old separate options to new combined option for backwards compatibility + if state.convert.AspectHandling == "Letterbox" || state.convert.AspectHandling == "Pillarbox" { + state.convert.AspectHandling = "Letterbox/Pillarbox" + } aspectOptions.SetSelected(state.convert.AspectHandling) - aspectOptions.SetSelected(state.convert.AspectHandling) - - backgroundHint := widget.NewLabel("Shown when aspect differs; choose padding/fill style.") + backgroundHint := widget.NewLabel("Crop removes edges, Letterbox/Pillarbox adds black bars to fit.") aspectBox := container.NewVBox( widget.NewLabelWithStyle("Aspect Handling", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), aspectOptions, @@ -12430,7 +12433,14 @@ func aspectFilters(target float64, mode string) []string { return []string{filterStr, "setsar=1"} } - // Letterbox/Pillarbox: keep source resolution, just pad to target aspect with black bars + // Letterbox/Pillarbox: pad with black bars (auto-detects direction based on aspect ratio change) + // Also handles legacy "Letterbox" and "Pillarbox" options for backwards compatibility + if strings.EqualFold(mode, "Letterbox/Pillarbox") || strings.EqualFold(mode, "Letterbox") || strings.EqualFold(mode, "Pillarbox") { + pad := fmt.Sprintf("pad=w='trunc(max(iw,ih*%[1]s)/2)*2':h='trunc(max(ih,iw/%[1]s)/2)*2':x='(ow-iw)/2':y='(oh-ih)/2':color=black", ar) + return []string{pad, "setsar=1"} + } + + // Default fallback: same as Letterbox/Pillarbox pad := fmt.Sprintf("pad=w='trunc(max(iw,ih*%[1]s)/2)*2':h='trunc(max(ih,iw/%[1]s)/2)*2':x='(ow-iw)/2':y='(oh-ih)/2':color=black", ar) return []string{pad, "setsar=1"} }