Fix main menu sizing and add shell aliases

This commit is contained in:
Stu Leak 2026-01-15 02:58:55 -05:00
parent 1db5069b9c
commit f1cbfa66c0
7 changed files with 173 additions and 73 deletions

View File

@ -44,7 +44,7 @@ The installer will build, install, and set up everything automatically with a gu
**After installation:**
```bash
source ~/.bashrc # (or ~/.zshrc for zsh)
source ~/.bashrc # (or ~/.zshrc, or ~/.config/fish/config.fish)
VideoTools
```
@ -91,6 +91,7 @@ Output is professional quality, ready for:
- **DVD_IMPLEMENTATION_SUMMARY.md** - Technical specifications
- **INTEGRATION_GUIDE.md** - System architecture and integration
- **QUEUE_SYSTEM_GUIDE.md** - Queue system reference
- **localization-policy.md** - Localization strategy and implementation guide
## Requirements
@ -112,7 +113,9 @@ VideoTools has a modular architecture:
### Build & Run
```bash
# One-time setup
source scripts/alias.sh
source scripts/alias.sh # bash
# source scripts/alias.zsh # zsh
# source scripts/alias.fish # fish
# Run the application
VideoTools

View File

@ -6,7 +6,9 @@
```bash
cd /home/stu/Projects/VideoTools
source scripts/alias.sh
source scripts/alias.sh # bash
# source scripts/alias.zsh # zsh
# source scripts/alias.fish # fish
VideoTools
```
@ -15,7 +17,7 @@ This will:
2. Build the application (if needed)
3. Run VideoTools GUI
**Available commands after sourcing alias.sh:**
**Available commands after sourcing the alias script:**
- `VideoTools` - Run the application
- `VideoToolsRebuild` - Force a clean rebuild
- `VideoToolsClean` - Clean all build artifacts
@ -67,7 +69,7 @@ source ~/.bashrc
### For Zsh users:
Add this line to `~/.zshrc`:
```bash
source /home/stu/Projects/VideoTools/scripts/alias.sh
source /home/stu/Projects/VideoTools/scripts/alias.zsh
```
Then reload:
@ -75,6 +77,17 @@ Then reload:
source ~/.zshrc
```
### For Fish users:
Add this line to `~/.config/fish/config.fish`:
```fish
source /home/stu/Projects/VideoTools/scripts/alias.fish
```
Reload fish:
```fish
source ~/.config/fish/config.fish
```
### After setting up:
From any directory, you can simply type:
```bash
@ -133,10 +146,16 @@ bash scripts/run.sh
- No manual steps needed
- Always runs the latest code
### alias.sh
### alias.sh / alias.zsh / alias.fish
```bash
source scripts/alias.sh
```
```bash
source scripts/alias.zsh
```
```fish
source scripts/alias.fish
```
**Purpose:** Creates convenient shell commands
@ -440,4 +459,3 @@ VideoTools
```
**That's it!** The scripts handle everything else automatically.

View File

@ -24,7 +24,7 @@ This single command automates the entire setup process.
4. **Install Binary:** Copies the compiled binary to the selected location and makes it executable.
5. **Configure Shell:** Detects your shell (`bash` or `zsh`) and updates the corresponding resource file (`~/.bashrc` or `~/.zshrc`) to:
* Add the installation directory to your `PATH`.
* Source the `alias.sh` script for convenience commands.
* Source the matching alias script (`alias.sh` for bash, `alias.zsh` for zsh).
### After Installation
@ -36,6 +36,9 @@ source ~/.bashrc
# For zsh users:
source ~/.zshrc
# For fish users (manual setup required):
source ~/.config/fish/config.fish
```
You can now run the application from anywhere by simply typing `VideoTools`.
@ -80,7 +83,9 @@ If you prefer to perform the steps manually:
export PATH="$HOME/.local/bin:$PATH"
# Source VideoTools aliases
source /path/to/VideoTools/scripts/alias.sh
source /path/to/VideoTools/scripts/alias.sh # bash
# source /path/to/VideoTools/scripts/alias.zsh # zsh
# source /path/to/VideoTools/scripts/alias.fish # fish
```
4. **Reload Your Shell:**

141
main.go
View File

@ -48,11 +48,20 @@ import (
"git.leaktechnologies.dev/stu/VideoTools/internal/sysinfo"
"git.leaktechnologies.dev/stu/VideoTools/internal/ui"
"git.leaktechnologies.dev/stu/VideoTools/internal/utils"
guitutils "git.leaktechnologies.dev/stu/VideoTools/internal/utils"
"github.com/ebitengine/oto/v3"
"github.com/skip2/go-qrcode"
)
// abs returns the absolute value of an int32
func abs(x int32) int32 {
if x < 0 {
return -x
}
return x
}
// Module describes a high level tool surface that gets a tile on the menu.
type Module struct {
ID string
@ -1156,49 +1165,49 @@ type appState struct {
historyTabIdx int
// Author module state
authorFile *videoSource
authorChapters []authorChapter
authorSceneThreshold float64
authorDetecting bool
authorClips []authorClip // Multiple video clips for compilation
authorOutputType string // "dvd" or "iso"
authorRegion string // "NTSC", "PAL", "AUTO"
authorAspectRatio string // "4:3", "16:9", "AUTO"
authorCreateMenu bool // Whether to create DVD menu
authorMenuTemplate string // "Simple", "Dark", "Poster"
authorMenuBackgroundImage string // Path to a user-selected background image
authorMenuTheme string // "VideoTools"
authorMenuTitleLogoEnabled bool // Enable title logo (main logo above menu)
authorMenuTitleLogoPath string // Path to title logo image
authorMenuTitleLogoPosition string // Position for title logo
authorMenuTitleLogoScale float64 // Scale for title logo
authorMenuTitleLogoMargin int // Margin for title logo
authorMenuStudioLogoEnabled bool // Enable studio logo (corner logo)
authorMenuStudioLogoPath string // Path to studio logo image
authorMenuStudioLogoPosition string // "Top Left", "Top Right", "Bottom Left", "Bottom Right"
authorMenuStudioLogoScale float64 // Scale for studio logo
authorMenuStudioLogoMargin int // Margin for studio logo
authorMenuStructure string // Feature only, Chapters, Extras
authorMenuExtrasEnabled bool // Show extras menu
authorMenuChapterThumbSrc string // Auto, First Frame, Midpoint, Custom
authorTitle string // DVD title
authorSubtitles []string // Subtitle file paths
authorAudioTracks []string // Additional audio tracks
authorSummaryLabel *widget.Label
authorTreatAsChapters bool // Treat multiple clips as chapters
authorChapterSource string // embedded, scenes, clips, manual
authorChaptersRefresh func() // Refresh hook for chapter list UI
authorDiscSize string // "DVD5" or "DVD9"
authorLogText string
authorLogLines []string // Circular buffer for last N lines
authorLogFilePath string // Path to log file for full viewing
authorLogEntry *widget.Entry
authorLogScroll *container.Scroll
authorProgress float64
authorProgressBar *widget.ProgressBar
authorStatusLabel *widget.Label
authorCancelBtn *widget.Button
authorVideoTSPath string
authorFile *videoSource
authorChapters []authorChapter
authorSceneThreshold float64
authorDetecting bool
authorClips []authorClip // Multiple video clips for compilation
authorOutputType string // "dvd" or "iso"
authorRegion string // "NTSC", "PAL", "AUTO"
authorAspectRatio string // "4:3", "16:9", "AUTO"
authorCreateMenu bool // Whether to create DVD menu
authorMenuTemplate string // "Simple", "Dark", "Poster"
authorMenuBackgroundImage string // Path to a user-selected background image
authorMenuTheme string // "VideoTools"
authorMenuTitleLogoEnabled bool // Enable title logo (main logo above menu)
authorMenuTitleLogoPath string // Path to title logo image
authorMenuTitleLogoPosition string // Position for title logo
authorMenuTitleLogoScale float64 // Scale for title logo
authorMenuTitleLogoMargin int // Margin for title logo
authorMenuStudioLogoEnabled bool // Enable studio logo (corner logo)
authorMenuStudioLogoPath string // Path to studio logo image
authorMenuStudioLogoPosition string // "Top Left", "Top Right", "Bottom Left", "Bottom Right"
authorMenuStudioLogoScale float64 // Scale for studio logo
authorMenuStudioLogoMargin int // Margin for studio logo
authorMenuStructure string // Feature only, Chapters, Extras
authorMenuExtrasEnabled bool // Show extras menu
authorMenuChapterThumbSrc string // Auto, First Frame, Midpoint, Custom
authorTitle string // DVD title
authorSubtitles []string // Subtitle file paths
authorAudioTracks []string // Additional audio tracks
authorSummaryLabel *widget.Label
authorTreatAsChapters bool // Treat multiple clips as chapters
authorChapterSource string // embedded, scenes, clips, manual
authorChaptersRefresh func() // Refresh hook for chapter list UI
authorDiscSize string // "DVD5" or "DVD9"
authorLogText string
authorLogLines []string // Circular buffer for last N lines
authorLogFilePath string // Path to log file for full viewing
authorLogEntry *widget.Entry
authorLogScroll *container.Scroll
authorProgress float64
authorProgressBar *widget.ProgressBar
authorStatusLabel *widget.Label
authorCancelBtn *widget.Button
authorVideoTSPath string
// Rip module state
ripSourcePath string
@ -1851,25 +1860,21 @@ func (r *mouseButtonRenderer) BackgroundColor() color.Color {
func (s *appState) setContent(body fyne.CanvasObject) {
update := func() {
// Preserve current window size to prevent auto-resizing when content changes
// This ensures the window maintains the size the user set, even when content
// like progress bars or queue items change dynamically
currentSize := s.window.Canvas().Size()
bg := canvas.NewRectangle(backgroundColor)
sizeGuard := canvas.NewRectangle(color.Transparent)
sizeGuard.SetMinSize(fyne.NewSize(800, 600))
if currentSize.Width > 0 && currentSize.Height > 0 {
sizeGuard.SetMinSize(currentSize)
} else {
sizeGuard.SetMinSize(fyne.NewSize(800, 600))
}
if body == nil {
s.window.SetContent(container.NewMax(bg, sizeGuard))
// Restore window size after setting content
s.window.Resize(currentSize)
return
}
// Wrap content with mouse button handler
wrapped := newMouseButtonHandler(container.NewMax(bg, sizeGuard, body), s)
s.window.SetContent(wrapped)
// Restore window size after setting content
s.window.Resize(currentSize)
}
// Use async Do() instead of DoAndWait() to avoid deadlock when called from main goroutine
@ -1905,6 +1910,7 @@ func (s *appState) showErrorWithCopy(title string, err error) {
}
func (s *appState) showMainMenu() {
_ = guitutils.DetectGUIEnvironment() // Use GUI utilities to ensure import is used
s.stopPreview()
s.stopPlayer()
s.stopQueueAutoRefresh()
@ -6673,15 +6679,26 @@ func runGUI() {
} else {
logging.Debug(logging.CatUI, "app icon not found; continuing without custom icon")
}
// Enhanced cross-platform GUI detection and window sizing
guiEnv := guitutils.DetectGUIEnvironment()
logging.Debug(logging.CatUI, "detected GUI environment: %s", guiEnv.String())
// Adaptive window sizing for professional cross-resolution support
w.SetFixedSize(false) // Allow manual resizing and maximizing
// Use compact default size (800x600) that fits on any screen
// Window can be resized or maximized by user using window manager controls
w.Resize(fyne.NewSize(800, 600))
// Use GUI environment to determine optimal window size
optimalSize := guiEnv.GetOptimalWindowSize(800, 600)
w.Resize(optimalSize)
w.CenterOnScreen()
logging.Debug(logging.CatUI, "window initialized at 800x600 (compact default), manual resizing enabled")
// Log GPU acceleration support
if guiEnv.SupportsGPUAcceleration() {
logging.Debug(logging.CatUI, "GPU acceleration should be available on %s %s", guiEnv.GPUInfo.Vendor, guiEnv.GPUInfo.Model)
} else {
logging.Debug(logging.CatUI, "GPU acceleration may not be available - using software rendering")
}
logging.Debug(logging.CatUI, "window initialized at %v (auto-detected environment), manual resizing enabled", optimalSize)
// Initialize audio module - load persisted config or use defaults
audioDefaults, err := loadAudioConfig()
@ -11299,12 +11316,12 @@ func newPlaySession(path string, w, h int, fps, duration float64, targetW, targe
}
sess := &playSession{
path: path,
fps: fps,
width: w,
height: h,
targetW: targetW,
targetH: targetH,
path: path,
fps: fps,
width: w,
height: h,
targetW: targetW,
targetH: targetH,
volume: 100,
duration: duration,
stop: make(chan struct{}),

26
scripts/alias.fish Normal file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env fish
# VideoTools Convenience Script (fish)
# Source this file in fish to add the 'VideoTools' command
if not set -q FISH_VERSION
echo "This script is for fish. Use scripts/alias.sh or scripts/alias.zsh instead."
return 1
end
set -l script_path (status -f)
set -l project_root (dirname (dirname $script_path))
alias VideoTools="bash $project_root/scripts/run.sh"
function VideoToolsRebuild
echo "Rebuilding VideoTools..."
bash "$project_root/scripts/build.sh"
end
function VideoToolsClean
echo "Cleaning VideoTools build artifacts..."
cd "$project_root"
go clean -cache -modcache -testcache
rm -f "$project_root/VideoTools"
echo "Clean complete"
end

View File

@ -1,6 +1,11 @@
#!/bin/bash
# VideoTools Convenience Script
# Source this file in your shell to add the 'VideoTools' command
# VideoTools Convenience Script (bash)
# Source this file in bash to add the 'VideoTools' command
if [ -z "$BASH_VERSION" ]; then
echo "This script is for bash. Use scripts/alias.zsh or scripts/alias.fish instead."
return 1
fi
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

26
scripts/alias.zsh Normal file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env zsh
# VideoTools Convenience Script (zsh)
# Source this file in zsh to add the 'VideoTools' command
if [[ -z "$ZSH_VERSION" ]]; then
echo "This script is for zsh. Use scripts/alias.sh or scripts/alias.fish instead."
return 1
fi
SCRIPT_PATH="${(%):-%N}"
PROJECT_ROOT="$(cd "$(dirname "$SCRIPT_PATH")/.." && pwd)"
alias VideoTools="bash $PROJECT_ROOT/scripts/run.sh"
VideoToolsRebuild() {
echo "Rebuilding VideoTools..."
bash "$PROJECT_ROOT/scripts/build.sh"
}
VideoToolsClean() {
echo "Cleaning VideoTools build artifacts..."
cd "$PROJECT_ROOT" || return 1
go clean -cache -modcache -testcache
rm -f "$PROJECT_ROOT/VideoTools"
echo "Clean complete"
}