package dialogs import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" "github.com/dweymouth/supersonic/ui/layouts" myTheme "github.com/dweymouth/supersonic/ui/theme" "github.com/dweymouth/supersonic/ui/util" ) type GraphicEqualizer struct { widget.BaseWidget OnChanged func(band int, gain float64) OnPreampChanged func(gain float64) container *fyne.Container } func NewGraphicEqualizer(preamp float64, bandFreqs []string, bandGains []float64) *GraphicEqualizer { g := &GraphicEqualizer{} g.ExtendBaseWidget(g) g.buildSliders(preamp, bandFreqs, bandGains) return g } func (g *GraphicEqualizer) buildSliders(preamp float64, bands []string, bandGains []float64) { rng := container.NewVBox( newCaptionTextSizeLabel("+12", fyne.TextAlignTrailing), layout.NewSpacer(), newCaptionTextSizeLabel("0", fyne.TextAlignTrailing), layout.NewSpacer(), newCaptionTextSizeLabel("-12", fyne.TextAlignTrailing), ) bandSliders := container.New(layouts.NewGridLayoutWithColumnsAndPadding(len(bands)+2, -16)) pre := newCaptionTextSizeLabel("Pre", fyne.TextAlignCenter) preampSlider := newEQSlider() preampSlider.SetValue(preamp) preampSlider.OnChanged = func(f float64) { if g.OnPreampChanged != nil { g.OnPreampChanged(f) } } bandSliders.Add(container.NewBorder(nil, pre, nil, nil, preampSlider)) bandSliders.Add(container.NewBorder(nil, widget.NewLabel(""), nil, nil, rng)) for i, band := range bands { s := newEQSlider() if i < len(bandGains) { s.SetValue(bandGains[i]) } s.OnChanged = func(i int) func(float64) { return func(f float64) { if g.OnChanged != nil { g.OnChanged(i, f) } } }(i) l := newCaptionTextSizeLabel(band, fyne.TextAlignCenter) c := container.NewBorder(nil, l, nil, nil, s) bandSliders.Add(c) } g.container = container.NewStack( container.NewBorder(nil, widget.NewLabel(""), nil, nil, container.NewBorder(nil, nil, util.NewHSpace(5), util.NewHSpace(5), container.NewVBox( layout.NewSpacer(), myTheme.NewThemedRectangle(theme.ColorNameInputBackground), layout.NewSpacer(), ), ), ), bandSliders, ) } func newCaptionTextSizeLabel(text string, alignment fyne.TextAlign) *widget.RichText { l := widget.NewRichTextWithText(text) ts := l.Segments[0].(*widget.TextSegment) ts.Style.SizeName = theme.SizeNameCaptionText ts.Style.Alignment = alignment return l } func (g *GraphicEqualizer) CreateRenderer() fyne.WidgetRenderer { return widget.NewSimpleRenderer(g.container) } type eqSlider struct { widget.Slider tappedAt int64 } func newEQSlider() *eqSlider { s := &eqSlider{ Slider: widget.Slider{ Orientation: widget.Vertical, Min: -12, Max: 12, Step: 0.1, }, } s.ExtendBaseWidget(s) return s } // We implement our own double tapping so that the Tapped behavior // can be triggered instantly. func (s *eqSlider) DoubleTapped(e *fyne.PointEvent) { s.SetValue(0) }