Improve preset UX and finalize 800x600 UI scaling
UI Scaling Improvements: - Reduce module tiles from 160x80 to 150x65 - Reduce title from 20 to 18 - Reduce queue tile from 140x50 to 120x40 - Reduce category labels to 12px - Reduce padding from 8 to 4px - Remove scrolling, everything fits in 800x600 Preset UX Improvements: - Move "Manual" to bottom of all preset dropdowns - Default bitrate preset: "2.5 Mbps - Medium Quality" - Default target size: "100MB" - Manual input fields hidden by default - Show manual fields only when "Manual" selected Encoding Preset Order: - Reverse order: veryslow first, ultrafast last - Better quality options now appear first - Applied to both simple and advanced mode 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
c62b7867fd
commit
c1ccb38062
|
|
@ -173,7 +173,7 @@ func (r *moduleTileRenderer) Layout(size fyne.Size) {
|
|||
}
|
||||
|
||||
func (r *moduleTileRenderer) MinSize() fyne.Size {
|
||||
return fyne.NewSize(160, 80)
|
||||
return fyne.NewSize(150, 65)
|
||||
}
|
||||
|
||||
func (r *moduleTileRenderer) Refresh() {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ type HistoryEntry struct {
|
|||
func BuildMainMenu(modules []ModuleInfo, onModuleClick func(string), onModuleDrop func(string, []fyne.URI), onQueueClick func(), onLogsClick func(), onBenchmarkClick func(), onBenchmarkHistoryClick func(), onToggleSidebar func(), sidebarVisible bool, sidebar fyne.CanvasObject, titleColor, queueColor, textColor color.Color, queueCompleted, queueTotal int, hasBenchmark bool) fyne.CanvasObject {
|
||||
title := canvas.NewText("VIDEOTOOLS", titleColor)
|
||||
title.TextStyle = fyne.TextStyle{Monospace: true, Bold: true}
|
||||
title.TextSize = 20
|
||||
title.TextSize = 18
|
||||
|
||||
queueTile := buildQueueTile(queueCompleted, queueTotal, queueColor, textColor, onQueueClick)
|
||||
|
||||
|
|
@ -103,24 +103,23 @@ func BuildMainMenu(modules []ModuleInfo, onModuleClick func(string), onModuleDro
|
|||
|
||||
var sections []fyne.CanvasObject
|
||||
for _, cat := range sortedKeys(categorized) {
|
||||
catLabel := canvas.NewText(cat, textColor)
|
||||
catLabel.TextSize = 12
|
||||
catLabel.TextStyle = fyne.TextStyle{Bold: true}
|
||||
sections = append(sections,
|
||||
canvas.NewText(cat, textColor),
|
||||
catLabel,
|
||||
container.NewGridWithColumns(3, categorized[cat]...),
|
||||
)
|
||||
}
|
||||
|
||||
padding := canvas.NewRectangle(color.Transparent)
|
||||
padding.SetMinSize(fyne.NewSize(0, 8))
|
||||
padding.SetMinSize(fyne.NewSize(0, 4))
|
||||
|
||||
// Make the sections scrollable
|
||||
sectionsContent := container.NewVBox(sections...)
|
||||
scroll := container.NewVScroll(sectionsContent)
|
||||
|
||||
// Use border layout with fixed header and scrollable content
|
||||
body := container.NewBorder(
|
||||
container.NewVBox(header, padding),
|
||||
nil, nil, nil,
|
||||
scroll,
|
||||
// Compact body without scrolling
|
||||
body := container.NewVBox(
|
||||
header,
|
||||
padding,
|
||||
container.NewVBox(sections...),
|
||||
)
|
||||
|
||||
// Wrap with HSplit if sidebar is visible
|
||||
|
|
@ -142,13 +141,13 @@ func buildModuleTile(mod ModuleInfo, tapped func(), dropped func([]fyne.URI)) fy
|
|||
// buildQueueTile creates the queue status tile
|
||||
func buildQueueTile(completed, total int, queueColor, textColor color.Color, onClick func()) fyne.CanvasObject {
|
||||
rect := canvas.NewRectangle(queueColor)
|
||||
rect.CornerRadius = 8
|
||||
rect.SetMinSize(fyne.NewSize(140, 50))
|
||||
rect.CornerRadius = 6
|
||||
rect.SetMinSize(fyne.NewSize(120, 40))
|
||||
|
||||
text := canvas.NewText(fmt.Sprintf("QUEUE: %d/%d", completed, total), textColor)
|
||||
text.Alignment = fyne.TextAlignCenter
|
||||
text.TextStyle = fyne.TextStyle{Monospace: true, Bold: true}
|
||||
text.TextSize = 16
|
||||
text.TextSize = 14
|
||||
|
||||
tile := container.NewMax(rect, container.NewCenter(text))
|
||||
|
||||
|
|
|
|||
100
main.go
100
main.go
|
|
@ -505,6 +505,56 @@ func (c convertConfig) CoverLabel() string {
|
|||
return filepath.Base(c.CoverArtPath)
|
||||
}
|
||||
|
||||
func defaultConvertConfig() convertConfig {
|
||||
return convertConfig{
|
||||
SelectedFormat: formatOptions[0],
|
||||
OutputBase: "converted",
|
||||
Quality: "Standard (CRF 23)",
|
||||
Mode: "Simple",
|
||||
UseAutoNaming: false,
|
||||
AutoNameTemplate: "<actress> - <studio> - <scene>",
|
||||
|
||||
VideoCodec: "H.264",
|
||||
EncoderPreset: "medium",
|
||||
CRF: "",
|
||||
BitrateMode: "CRF",
|
||||
BitratePreset: "Manual",
|
||||
VideoBitrate: "5000k",
|
||||
TargetFileSize: "",
|
||||
TargetResolution: "Source",
|
||||
FrameRate: "Source",
|
||||
UseMotionInterpolation: false,
|
||||
PixelFormat: "yuv420p",
|
||||
HardwareAccel: "auto",
|
||||
TwoPass: false,
|
||||
H264Profile: "main",
|
||||
H264Level: "4.0",
|
||||
Deinterlace: "Auto",
|
||||
DeinterlaceMethod: "bwdif",
|
||||
AutoCrop: false,
|
||||
CropWidth: "",
|
||||
CropHeight: "",
|
||||
CropX: "",
|
||||
CropY: "",
|
||||
FlipHorizontal: false,
|
||||
FlipVertical: false,
|
||||
Rotation: "0",
|
||||
|
||||
AudioCodec: "AAC",
|
||||
AudioBitrate: "192k",
|
||||
AudioChannels: "Source",
|
||||
AudioSampleRate: "Source",
|
||||
NormalizeAudio: false,
|
||||
|
||||
InverseTelecine: true,
|
||||
InverseAutoNotes: "Default smoothing for interlaced footage.",
|
||||
CoverArtPath: "",
|
||||
AspectHandling: "Auto",
|
||||
OutputAspect: "Source",
|
||||
AspectUserSet: false,
|
||||
}
|
||||
}
|
||||
|
||||
// defaultConvertConfigPath returns the path to the persisted convert config.
|
||||
func defaultConvertConfigPath() string {
|
||||
configDir, err := os.UserConfigDir()
|
||||
|
|
@ -4865,47 +4915,8 @@ func runGUI() {
|
|||
logging.Debug(logging.CatUI, "window initialized at 800x600 (compact default), manual resizing enabled")
|
||||
|
||||
state := &appState{
|
||||
window: w,
|
||||
convert: convertConfig{
|
||||
OutputBase: "converted",
|
||||
SelectedFormat: formatOptions[0],
|
||||
Quality: "Standard (CRF 23)",
|
||||
Mode: "Simple",
|
||||
UseAutoNaming: false,
|
||||
AutoNameTemplate: "<actress> - <studio> - <scene>",
|
||||
|
||||
// Video encoding defaults
|
||||
VideoCodec: "H.264",
|
||||
EncoderPreset: "medium",
|
||||
CRF: "", // Empty means use Quality preset
|
||||
BitrateMode: "CRF",
|
||||
BitratePreset: "Manual",
|
||||
VideoBitrate: "5000k",
|
||||
TargetResolution: "Source",
|
||||
FrameRate: "Source",
|
||||
PixelFormat: "yuv420p",
|
||||
HardwareAccel: "auto",
|
||||
TwoPass: false,
|
||||
H264Profile: "main",
|
||||
H264Level: "4.0",
|
||||
Deinterlace: "Auto",
|
||||
DeinterlaceMethod: "bwdif",
|
||||
AutoCrop: false,
|
||||
|
||||
// Audio encoding defaults
|
||||
AudioCodec: "AAC",
|
||||
AudioBitrate: "192k",
|
||||
AudioChannels: "Source",
|
||||
AudioSampleRate: "Source",
|
||||
NormalizeAudio: false,
|
||||
|
||||
// Other defaults
|
||||
InverseTelecine: true,
|
||||
InverseAutoNotes: "Default smoothing for interlaced footage.",
|
||||
OutputAspect: "Source",
|
||||
AspectHandling: "Auto",
|
||||
AspectUserSet: false,
|
||||
},
|
||||
window: w,
|
||||
convert: defaultConvertConfig(),
|
||||
mergeChapters: true,
|
||||
player: player.New(),
|
||||
playerVolume: 100,
|
||||
|
|
@ -5271,6 +5282,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
crfContainer *fyne.Container
|
||||
bitrateContainer *fyne.Container
|
||||
targetSizeContainer *fyne.Container
|
||||
resetConvertDefaults func()
|
||||
)
|
||||
var (
|
||||
updateEncodingControls func()
|
||||
|
|
@ -5767,7 +5779,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
encoderPresetHint.SetText(hint)
|
||||
}
|
||||
|
||||
encoderPresetSelect := widget.NewSelect([]string{"ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow"}, func(value string) {
|
||||
encoderPresetSelect := widget.NewSelect([]string{"veryslow", "slower", "slow", "medium", "fast", "faster", "veryfast", "superfast", "ultrafast"}, func(value string) {
|
||||
state.convert.EncoderPreset = value
|
||||
logging.Debug(logging.CatUI, "encoder preset set to %s", value)
|
||||
updateEncoderPresetHint(value)
|
||||
|
|
@ -5779,7 +5791,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
updateEncoderPresetHint(state.convert.EncoderPreset)
|
||||
|
||||
// Simple mode preset dropdown
|
||||
simplePresetSelect := widget.NewSelect([]string{"ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow"}, func(value string) {
|
||||
simplePresetSelect := widget.NewSelect([]string{"veryslow", "slower", "slow", "medium", "fast", "faster", "veryfast", "superfast", "ultrafast"}, func(value string) {
|
||||
state.convert.EncoderPreset = value
|
||||
logging.Debug(logging.CatUI, "simple preset set to %s", value)
|
||||
updateEncoderPresetHint(value)
|
||||
|
|
@ -6063,7 +6075,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
}
|
||||
})
|
||||
if state.convert.BitratePreset == "" || bitratePresetLookup[state.convert.BitratePreset].Label == "" {
|
||||
state.convert.BitratePreset = "4.0 Mbps - Good Quality"
|
||||
state.convert.BitratePreset = "2.5 Mbps - Medium Quality"
|
||||
}
|
||||
bitratePresetSelect.SetSelected(state.convert.BitratePreset)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user