Use ratio layout for codec and preset row
This commit is contained in:
parent
3b6ea529de
commit
4954dc021f
|
|
@ -356,6 +356,52 @@ func TintedBar(col color.Color, body fyne.CanvasObject) fyne.CanvasObject {
|
|||
return container.NewMax(rect, padded)
|
||||
}
|
||||
|
||||
// NewRatioRow lays out two objects with a fixed width ratio for the left item.
|
||||
func NewRatioRow(left, right fyne.CanvasObject, leftRatio float32) *fyne.Container {
|
||||
return container.New(&ratioRowLayout{leftRatio: leftRatio}, left, right)
|
||||
}
|
||||
|
||||
type ratioRowLayout struct {
|
||||
leftRatio float32
|
||||
}
|
||||
|
||||
func (r *ratioRowLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) {
|
||||
if len(objects) < 2 {
|
||||
return
|
||||
}
|
||||
ratio := clampRatio(r.leftRatio)
|
||||
leftWidth := size.Width * ratio
|
||||
rightWidth := size.Width - leftWidth
|
||||
|
||||
objects[0].Move(fyne.NewPos(0, 0))
|
||||
objects[0].Resize(fyne.NewSize(leftWidth, size.Height))
|
||||
objects[1].Move(fyne.NewPos(leftWidth, 0))
|
||||
objects[1].Resize(fyne.NewSize(rightWidth, size.Height))
|
||||
}
|
||||
|
||||
func (r *ratioRowLayout) MinSize(objects []fyne.CanvasObject) fyne.Size {
|
||||
if len(objects) < 2 {
|
||||
return fyne.NewSize(0, 0)
|
||||
}
|
||||
leftMin := objects[0].MinSize()
|
||||
rightMin := objects[1].MinSize()
|
||||
height := leftMin.Height
|
||||
if rightMin.Height > height {
|
||||
height = rightMin.Height
|
||||
}
|
||||
return fyne.NewSize(leftMin.Width+rightMin.Width, height)
|
||||
}
|
||||
|
||||
func clampRatio(ratio float32) float32 {
|
||||
if ratio < 0.1 {
|
||||
return 0.1
|
||||
}
|
||||
if ratio > 0.9 {
|
||||
return 0.9
|
||||
}
|
||||
return ratio
|
||||
}
|
||||
|
||||
// Tappable wraps any canvas object and makes it tappable
|
||||
type Tappable struct {
|
||||
widget.BaseWidget
|
||||
|
|
|
|||
86
main.go
86
main.go
|
|
@ -1,52 +1,58 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"io"
|
||||
"math"
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/app"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/data/binding"
|
||||
"fyne.io/fyne/v2/dialog"
|
||||
"fyne.io/fyne/v2/driver/desktop"
|
||||
"fyne.io/fyne/v2/layout"
|
||||
"fyne.io/fyne/v2/storage"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
|
||||
"git.leaktechnologies.dev/stu/VideoTools/audio_module"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/author_module"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/filters_module"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/inspect_module"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/app"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/benchmark"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/convert"
|
||||
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/interlace"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/convert/presets"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/enhancement"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/logging"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/metadata"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/modules"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/player"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/queue"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/sysinfo"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/thumb"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/ui"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/utils"
|
||||
"github.com/hajimehoshi/oto"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/rip_module"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/settings_module"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/subtitles_module"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/thumb_module"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/upscale_module"
|
||||
|
||||
"github.com/yeqown/go-qrcode/v2"
|
||||
"github.com/yeqown/go-qrcode/writer/standard"
|
||||
)
|
||||
|
||||
// Module describes a high level tool surface that gets a tile on the menu.
|
||||
|
|
@ -500,6 +506,34 @@ func openFile(path string) error {
|
|||
return cmd.Start()
|
||||
}
|
||||
|
||||
func generatePixelatedQRCode() (fyne.CanvasObject, error) {
|
||||
docURL := "https://docs.leaktechnologies.dev/VideoTools"
|
||||
|
||||
// Create chunky QR code with large pixel blocks
|
||||
qrc, err := qrcode.New(docURL,
|
||||
qrcode.WithQRWidth(6), // Large pixel blocks for chunky look
|
||||
qrcode.WithBorderWidth(2), // Small border
|
||||
qrcode.WithErrorCorrectionLevel(qrcode.ErrorCorrectionMedium),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Generate to memory
|
||||
var buf bytes.Buffer
|
||||
w := standard.NewWithWriter(&buf, standard.WithQRWidth(6))
|
||||
if err := qrc.Save(w); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert to Fyne image with pixelated look
|
||||
img := canvas.NewImageFromReader(&buf, "qrcode.png")
|
||||
img.FillMode = canvas.ImageFillOriginal // Keep pixelated look
|
||||
img.SetMinSize(fyne.NewSize(160, 160))
|
||||
|
||||
return img, nil
|
||||
}
|
||||
|
||||
func (s *appState) showAbout() {
|
||||
version := fmt.Sprintf("VideoTools %s", appVersion)
|
||||
dev := "Leak Technologies"
|
||||
|
|
@ -557,6 +591,22 @@ func (s *appState) showAbout() {
|
|||
if ltLogo != nil {
|
||||
logoColumn.Add(ltLogo)
|
||||
}
|
||||
|
||||
// Add QR code for documentation
|
||||
qrCode, err := generatePixelatedQRCode()
|
||||
if err != nil {
|
||||
// Fallback to hyperlink if QR generation fails
|
||||
docURL, _ := url.Parse("https://docs.leaktechnologies.dev/VideoTools")
|
||||
fallbackLink := widget.NewHyperlink("View Documentation", docURL)
|
||||
logoColumn.Add(fallbackLink)
|
||||
} else {
|
||||
// Add QR code with label
|
||||
qrLabel := widget.NewLabel("Scan for docs")
|
||||
qrLabel.Alignment = fyne.TextAlignCenter
|
||||
logoColumn.Add(qrCode)
|
||||
logoColumn.Add(qrLabel)
|
||||
}
|
||||
|
||||
logoColumn.Add(layout.NewSpacer())
|
||||
logoColumn.Add(logsLink)
|
||||
|
||||
|
|
@ -8737,8 +8787,8 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
// Advanced mode options - full controls with organized sections
|
||||
videoCodecLabel := widget.NewLabelWithStyle("Video Codec", fyne.TextAlignLeading, fyne.TextStyle{Bold: true})
|
||||
presetLabel := widget.NewLabelWithStyle("Encoder Preset (speed vs quality)", fyne.TextAlignLeading, fyne.TextStyle{Bold: true})
|
||||
videoCodecRow := container.NewGridWithColumns(2, videoCodecLabel, presetLabel)
|
||||
videoCodecControls := container.NewGridWithColumns(2, videoCodecContainer, encoderPresetSelect)
|
||||
videoCodecRow := ui.NewRatioRow(videoCodecLabel, presetLabel, 0.3)
|
||||
videoCodecControls := ui.NewRatioRow(videoCodecContainer, encoderPresetSelect, 0.3)
|
||||
|
||||
advancedVideoEncodingBlock = container.NewVBox(
|
||||
widget.NewLabelWithStyle("═══ VIDEO ENCODING ═══", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}),
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user