From 1051329763bd591a4aecf9eea6825cdb54badd61 Mon Sep 17 00:00:00 2001 From: Stu Leak Date: Sun, 28 Dec 2025 19:38:58 -0500 Subject: [PATCH] fix(ui): Enable word wrapping for hint labels in convert module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: - User reported hint text being cut off at window edge - Example: "CBR mode: Constant bitrate - predictable file quality. Use for strict size requirements or s" - Text truncated with "or s" visible, rest cut off - Hint labels weren't wrapping properly in narrow windows Root Cause: - Hint labels had TextWrapWord enabled BUT - Labels inside VBox containers don't wrap properly without width constraints - Fyne requires labels to be in a sized container for wrapping to work - VScroll container doesn't provide width hints to child labels Solution: - Wrap all hint labels in container.NewPadded() containers - Padded containers provide proper sizing context for text wrapping - Labels now wrap at available width instead of extending beyond bounds Affected Hint Labels: - encoderPresetHint: Encoder preset descriptions - encodingHint: Bitrate mode (CRF/CBR/VBR/Target Size) hints - frameRateHint: Frame rate change warnings - outputHint: Output file path display - targetAspectHint: Aspect ratio selection hint - hwAccelHint: Hardware acceleration guidance Implementation: - Created *Container versions of each hint label - Wrapped label in container.NewPadded(label) - Replaced direct label usage with container in VBox layouts - Maintains TextWrapWord setting on all labels Impact: - Hint text now wraps properly in narrow windows/panels - No more truncated text - Better readability across all window sizes - Consistent behavior for all hint labels Files Changed: - main.go: Wrapped 6 hint labels in padded containers Reported-by: User (screenshot showing "or s" truncation) Tested: Build successful (v0.1.0-dev20) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- main.go | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index 8908c9f..eed71fb 100644 --- a/main.go +++ b/main.go @@ -6235,6 +6235,8 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { } outputHint := widget.NewLabel(fmt.Sprintf("Output file: %s", state.convert.OutputFile())) outputHint.Wrapping = fyne.TextWrapWord + // Wrap hint in padded container to ensure proper text wrapping in narrow windows + outputHintContainer := container.NewPadded(outputHint) // DVD-specific aspect ratio selector (only shown for DVD formats) dvdAspectSelect := widget.NewSelect([]string{"4:3", "16:9"}, func(value string) { @@ -6633,6 +6635,9 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { } targetAspectSelect.SetSelected(state.convert.OutputAspect) targetAspectHint := widget.NewLabel("Pick desired output aspect (default Source).") + targetAspectHint.Wrapping = fyne.TextWrapWord + // 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) { logging.Debug(logging.CatUI, "aspect handling set to %s", value) @@ -6776,6 +6781,8 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { // Encoder Preset with hint encoderPresetHint := widget.NewLabel("") encoderPresetHint.Wrapping = fyne.TextWrapWord + // Wrap hint in padded container to ensure proper text wrapping in narrow windows + encoderPresetHintContainer := container.NewPadded(encoderPresetHint) updateEncoderPresetHint := func(preset string) { var hint string @@ -7458,6 +7465,8 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { encodingHint := widget.NewLabel("") encodingHint.Wrapping = fyne.TextWrapWord + // Wrap hint in padded container to ensure proper text wrapping in narrow windows + encodingHintContainer := container.NewPadded(encodingHint) applyBitratePreset = func(label string) { preset, ok := bitratePresetLookup[label] @@ -7612,6 +7621,8 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { // Frame Rate with hint frameRateHint := widget.NewLabel("") frameRateHint.Wrapping = fyne.TextWrapWord + // Wrap hint in padded container to ensure proper text wrapping in narrow windows + frameRateHintContainer := container.NewPadded(frameRateHint) updateFrameRateHint := func() { if src == nil { @@ -7694,6 +7705,8 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { // Hardware Acceleration with hint hwAccelHint := widget.NewLabel("Auto picks the best GPU path; if encode fails, switch to none (software).") hwAccelHint.Wrapping = fyne.TextWrapWord + // Wrap hint in padded container to ensure proper text wrapping in narrow windows + hwAccelHintContainer := container.NewPadded(hwAccelHint) hwAccelSelect := widget.NewSelect([]string{"auto", "none", "nvenc", "amf", "vaapi", "qsv", "videotoolbox"}, func(value string) { state.convert.HardwareAccel = value logging.Debug(logging.CatUI, "hardware accel set to %s", value) @@ -8002,7 +8015,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { dvdAspectBox, // DVD options appear here when DVD format selected widget.NewLabelWithStyle("Output Name", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), outputEntry, - outputHint, + outputHintContainer, widget.NewSeparator(), simpleEncodingSection, widget.NewLabelWithStyle("Target Resolution", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), @@ -8012,7 +8025,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { motionInterpCheck, widget.NewLabelWithStyle("Target Aspect Ratio", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), targetAspectSelectSimple, - targetAspectHint, + targetAspectHintContainer, layout.NewSpacer(), ) @@ -8023,25 +8036,25 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { videoCodecSelect, widget.NewLabelWithStyle("Encoder Preset (speed vs quality)", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), encoderPresetSelect, - encoderPresetHint, + encoderPresetHintContainer, qualitySectionAdv, widget.NewLabelWithStyle("Bitrate Mode", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), bitrateModeSelect, crfContainer, bitrateContainer, targetSizeContainer, - encodingHint, + encodingHintContainer, widget.NewLabelWithStyle("Target Resolution", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), resolutionSelect, widget.NewLabelWithStyle("Frame Rate", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), frameRateSelect, - frameRateHint, + frameRateHintContainer, motionInterpCheck, widget.NewLabelWithStyle("Pixel Format", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), pixelFormatSelect, widget.NewLabelWithStyle("Hardware Acceleration", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), hwAccelSelect, - hwAccelHint, + hwAccelHintContainer, twoPassCheck, ) @@ -8064,7 +8077,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { dvdAspectBox, // DVD options appear here when DVD format selected widget.NewLabelWithStyle("Output Name", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), outputEntry, - outputHint, + outputHintContainer, coverDisplay, widget.NewSeparator(), advancedVideoEncodingBlock, @@ -8073,7 +8086,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { widget.NewLabelWithStyle("═══ ASPECT RATIO ═══", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}), widget.NewLabelWithStyle("Target Aspect Ratio", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), targetAspectSelect, - targetAspectHint, + targetAspectHintContainer, aspectBox, widget.NewSeparator(),