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 {
|
func (r *moduleTileRenderer) MinSize() fyne.Size {
|
||||||
return fyne.NewSize(160, 80)
|
return fyne.NewSize(150, 65)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *moduleTileRenderer) Refresh() {
|
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 {
|
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 := canvas.NewText("VIDEOTOOLS", titleColor)
|
||||||
title.TextStyle = fyne.TextStyle{Monospace: true, Bold: true}
|
title.TextStyle = fyne.TextStyle{Monospace: true, Bold: true}
|
||||||
title.TextSize = 20
|
title.TextSize = 18
|
||||||
|
|
||||||
queueTile := buildQueueTile(queueCompleted, queueTotal, queueColor, textColor, onQueueClick)
|
queueTile := buildQueueTile(queueCompleted, queueTotal, queueColor, textColor, onQueueClick)
|
||||||
|
|
||||||
|
|
@ -103,24 +103,23 @@ func BuildMainMenu(modules []ModuleInfo, onModuleClick func(string), onModuleDro
|
||||||
|
|
||||||
var sections []fyne.CanvasObject
|
var sections []fyne.CanvasObject
|
||||||
for _, cat := range sortedKeys(categorized) {
|
for _, cat := range sortedKeys(categorized) {
|
||||||
|
catLabel := canvas.NewText(cat, textColor)
|
||||||
|
catLabel.TextSize = 12
|
||||||
|
catLabel.TextStyle = fyne.TextStyle{Bold: true}
|
||||||
sections = append(sections,
|
sections = append(sections,
|
||||||
canvas.NewText(cat, textColor),
|
catLabel,
|
||||||
container.NewGridWithColumns(3, categorized[cat]...),
|
container.NewGridWithColumns(3, categorized[cat]...),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
padding := canvas.NewRectangle(color.Transparent)
|
padding := canvas.NewRectangle(color.Transparent)
|
||||||
padding.SetMinSize(fyne.NewSize(0, 8))
|
padding.SetMinSize(fyne.NewSize(0, 4))
|
||||||
|
|
||||||
// Make the sections scrollable
|
// Compact body without scrolling
|
||||||
sectionsContent := container.NewVBox(sections...)
|
body := container.NewVBox(
|
||||||
scroll := container.NewVScroll(sectionsContent)
|
header,
|
||||||
|
padding,
|
||||||
// Use border layout with fixed header and scrollable content
|
container.NewVBox(sections...),
|
||||||
body := container.NewBorder(
|
|
||||||
container.NewVBox(header, padding),
|
|
||||||
nil, nil, nil,
|
|
||||||
scroll,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Wrap with HSplit if sidebar is visible
|
// 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
|
// buildQueueTile creates the queue status tile
|
||||||
func buildQueueTile(completed, total int, queueColor, textColor color.Color, onClick func()) fyne.CanvasObject {
|
func buildQueueTile(completed, total int, queueColor, textColor color.Color, onClick func()) fyne.CanvasObject {
|
||||||
rect := canvas.NewRectangle(queueColor)
|
rect := canvas.NewRectangle(queueColor)
|
||||||
rect.CornerRadius = 8
|
rect.CornerRadius = 6
|
||||||
rect.SetMinSize(fyne.NewSize(140, 50))
|
rect.SetMinSize(fyne.NewSize(120, 40))
|
||||||
|
|
||||||
text := canvas.NewText(fmt.Sprintf("QUEUE: %d/%d", completed, total), textColor)
|
text := canvas.NewText(fmt.Sprintf("QUEUE: %d/%d", completed, total), textColor)
|
||||||
text.Alignment = fyne.TextAlignCenter
|
text.Alignment = fyne.TextAlignCenter
|
||||||
text.TextStyle = fyne.TextStyle{Monospace: true, Bold: true}
|
text.TextStyle = fyne.TextStyle{Monospace: true, Bold: true}
|
||||||
text.TextSize = 16
|
text.TextSize = 14
|
||||||
|
|
||||||
tile := container.NewMax(rect, container.NewCenter(text))
|
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)
|
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.
|
// defaultConvertConfigPath returns the path to the persisted convert config.
|
||||||
func defaultConvertConfigPath() string {
|
func defaultConvertConfigPath() string {
|
||||||
configDir, err := os.UserConfigDir()
|
configDir, err := os.UserConfigDir()
|
||||||
|
|
@ -4865,47 +4915,8 @@ func runGUI() {
|
||||||
logging.Debug(logging.CatUI, "window initialized at 800x600 (compact default), manual resizing enabled")
|
logging.Debug(logging.CatUI, "window initialized at 800x600 (compact default), manual resizing enabled")
|
||||||
|
|
||||||
state := &appState{
|
state := &appState{
|
||||||
window: w,
|
window: w,
|
||||||
convert: convertConfig{
|
convert: defaultConvertConfig(),
|
||||||
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,
|
|
||||||
},
|
|
||||||
mergeChapters: true,
|
mergeChapters: true,
|
||||||
player: player.New(),
|
player: player.New(),
|
||||||
playerVolume: 100,
|
playerVolume: 100,
|
||||||
|
|
@ -5271,6 +5282,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
||||||
crfContainer *fyne.Container
|
crfContainer *fyne.Container
|
||||||
bitrateContainer *fyne.Container
|
bitrateContainer *fyne.Container
|
||||||
targetSizeContainer *fyne.Container
|
targetSizeContainer *fyne.Container
|
||||||
|
resetConvertDefaults func()
|
||||||
)
|
)
|
||||||
var (
|
var (
|
||||||
updateEncodingControls func()
|
updateEncodingControls func()
|
||||||
|
|
@ -5767,7 +5779,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
||||||
encoderPresetHint.SetText(hint)
|
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
|
state.convert.EncoderPreset = value
|
||||||
logging.Debug(logging.CatUI, "encoder preset set to %s", value)
|
logging.Debug(logging.CatUI, "encoder preset set to %s", value)
|
||||||
updateEncoderPresetHint(value)
|
updateEncoderPresetHint(value)
|
||||||
|
|
@ -5779,7 +5791,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
||||||
updateEncoderPresetHint(state.convert.EncoderPreset)
|
updateEncoderPresetHint(state.convert.EncoderPreset)
|
||||||
|
|
||||||
// Simple mode preset dropdown
|
// 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
|
state.convert.EncoderPreset = value
|
||||||
logging.Debug(logging.CatUI, "simple preset set to %s", value)
|
logging.Debug(logging.CatUI, "simple preset set to %s", value)
|
||||||
updateEncoderPresetHint(value)
|
updateEncoderPresetHint(value)
|
||||||
|
|
@ -6063,7 +6075,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if state.convert.BitratePreset == "" || bitratePresetLookup[state.convert.BitratePreset].Label == "" {
|
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)
|
bitratePresetSelect.SetSelected(state.convert.BitratePreset)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user