Add static UI noise overlay
This commit is contained in:
parent
d30229dfae
commit
306d581c69
83
internal/ui/noise.go
Normal file
83
internal/ui/noise.go
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
)
|
||||
|
||||
const (
|
||||
noiseTileSize = 128
|
||||
noiseAlpha = uint8(8) // ~3% opacity
|
||||
noiseVariance = uint8(6) // low contrast
|
||||
noiseMeanValue = uint8(128)
|
||||
)
|
||||
|
||||
var (
|
||||
noiseOnce sync.Once
|
||||
noiseTile *image.NRGBA
|
||||
uiTextureEnabled = true
|
||||
)
|
||||
|
||||
func init() {
|
||||
switch strings.ToLower(strings.TrimSpace(os.Getenv("VT_UI_TEXTURE"))) {
|
||||
case "0", "false", "off", "no":
|
||||
uiTextureEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
// NoisyBackgroundObjects returns background layers with an optional static noise overlay.
|
||||
func NoisyBackgroundObjects(bg fyne.CanvasObject) []fyne.CanvasObject {
|
||||
if !uiTextureEnabled {
|
||||
return []fyne.CanvasObject{bg}
|
||||
}
|
||||
return []fyne.CanvasObject{bg, NewNoiseOverlay()}
|
||||
}
|
||||
|
||||
// NewNoiseOverlay creates a static, cached grayscale noise layer.
|
||||
func NewNoiseOverlay() fyne.CanvasObject {
|
||||
return canvas.NewRaster(func(w, h int) image.Image {
|
||||
if w <= 0 || h <= 0 {
|
||||
return image.NewNRGBA(image.Rect(0, 0, 1, 1))
|
||||
}
|
||||
tile := getNoiseTile()
|
||||
dst := image.NewNRGBA(image.Rect(0, 0, w, h))
|
||||
tw := tile.Bounds().Dx()
|
||||
th := tile.Bounds().Dy()
|
||||
for y := 0; y < h; y++ {
|
||||
ty := y % th
|
||||
for x := 0; x < w; x++ {
|
||||
tx := x % tw
|
||||
dst.SetNRGBA(x, y, tile.NRGBAAt(tx, ty))
|
||||
}
|
||||
}
|
||||
return dst
|
||||
})
|
||||
}
|
||||
|
||||
func getNoiseTile() *image.NRGBA {
|
||||
noiseOnce.Do(func() {
|
||||
tile := image.NewNRGBA(image.Rect(0, 0, noiseTileSize, noiseTileSize))
|
||||
rng := rand.New(rand.NewSource(1))
|
||||
for y := 0; y < noiseTileSize; y++ {
|
||||
for x := 0; x < noiseTileSize; x++ {
|
||||
delta := int(rng.Intn(int(noiseVariance)*2+1)) - int(noiseVariance)
|
||||
v := int(noiseMeanValue) + delta
|
||||
if v < 0 {
|
||||
v = 0
|
||||
} else if v > 255 {
|
||||
v = 255
|
||||
}
|
||||
tile.SetNRGBA(x, y, color.NRGBA{R: uint8(v), G: uint8(v), B: uint8(v), A: noiseAlpha})
|
||||
}
|
||||
}
|
||||
noiseTile = tile
|
||||
})
|
||||
return noiseTile
|
||||
}
|
||||
23
main.go
23
main.go
|
|
@ -6943,7 +6943,9 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
widget.NewSeparator(),
|
||||
content,
|
||||
)
|
||||
return container.NewMax(bg, container.NewPadded(body))
|
||||
layers := ui.NoisyBackgroundObjects(bg)
|
||||
layers = append(layers, container.NewPadded(body))
|
||||
return container.NewMax(layers...)
|
||||
}
|
||||
|
||||
sectionGap := func() fyne.CanvasObject {
|
||||
|
|
@ -10268,7 +10270,9 @@ func makeLabeledPanel(title, body string, min fyne.Size) *fyne.Container {
|
|||
desc.Wrapping = fyne.TextWrapWord
|
||||
|
||||
box := container.NewVBox(header, desc, layout.NewSpacer())
|
||||
return container.NewMax(rect, container.NewPadded(box))
|
||||
layers := ui.NoisyBackgroundObjects(rect)
|
||||
layers = append(layers, container.NewPadded(box))
|
||||
return container.NewMax(layers...)
|
||||
}
|
||||
|
||||
func buildMetadataPanel(state *appState, src *videoSource, min fyne.Size) (fyne.CanvasObject, func()) {
|
||||
|
|
@ -10289,7 +10293,9 @@ func buildMetadataPanel(state *appState, src *videoSource, min fyne.Size) (fyne.
|
|||
widget.NewLabel("Load a clip to inspect its technical details."),
|
||||
layout.NewSpacer(),
|
||||
)
|
||||
return container.NewMax(outer, container.NewPadded(body)), func() {}
|
||||
layers := ui.NoisyBackgroundObjects(outer)
|
||||
layers = append(layers, container.NewPadded(body))
|
||||
return container.NewMax(layers...), func() {}
|
||||
}
|
||||
|
||||
bitrate := "--"
|
||||
|
|
@ -10649,7 +10655,9 @@ Metadata: %s`,
|
|||
)
|
||||
scroll := container.NewVScroll(body)
|
||||
scroll.SetMinSize(fyne.NewSize(0, 220))
|
||||
return container.NewMax(outer, container.NewPadded(scroll)), updateCoverDisplay
|
||||
layers := ui.NoisyBackgroundObjects(outer)
|
||||
layers = append(layers, container.NewPadded(scroll))
|
||||
return container.NewMax(layers...), updateCoverDisplay
|
||||
}
|
||||
|
||||
func buildVideoPane(state *appState, min fyne.Size, src *videoSource, onCover func(string)) fyne.CanvasObject {
|
||||
|
|
@ -15313,7 +15321,9 @@ func buildUpscaleView(state *appState) fyne.CanvasObject {
|
|||
widget.NewSeparator(),
|
||||
content,
|
||||
)
|
||||
return container.NewMax(bg, container.NewPadded(body))
|
||||
layers := ui.NoisyBackgroundObjects(bg)
|
||||
layers = append(layers, container.NewPadded(body))
|
||||
return container.NewMax(layers...)
|
||||
}
|
||||
|
||||
// Scaling (method + blur)
|
||||
|
|
@ -15936,8 +15946,7 @@ func buildUpscaleView(state *appState) fyne.CanvasObject {
|
|||
mainContent := split
|
||||
|
||||
content := container.NewMax(
|
||||
canvas.NewRectangle(mediumBlue),
|
||||
container.NewPadded(mainContent),
|
||||
append(ui.NoisyBackgroundObjects(canvas.NewRectangle(mediumBlue)), container.NewPadded(mainContent))...,
|
||||
)
|
||||
|
||||
actionBar := container.NewHBox(layout.NewSpacer(), applyBtn, addQueueBtn)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user