From 08904c484a8caf65a27812342ac362d0b147c79a Mon Sep 17 00:00:00 2001 From: Martyn Date: Sat, 11 Dec 2021 11:31:38 +0100 Subject: [PATCH] Adds vertical mode for VUMeter --- examples/vumeter/main.go | 6 ++- pkg/vumeter/vumeter.go | 96 +++++++++++++++++++++++++++------------- 2 files changed, 71 insertions(+), 31 deletions(-) diff --git a/examples/vumeter/main.go b/examples/vumeter/main.go index 436857f..b18cc04 100644 --- a/examples/vumeter/main.go +++ b/examples/vumeter/main.go @@ -24,6 +24,10 @@ func main() { level.Set(data / 100) } - w.SetContent(container.New(layout.NewVBoxLayout(), levelPB, progress, slider)) + vLevelPB := vumeter.NewVUMeterWithData(level) + vLevelPB.VUMeterDirection = vumeter.VUMeterVertical + vLevelPB.TextFormatter = func() string { return " " } + contain := container.New(layout.NewVBoxLayout(), levelPB, progress, slider) + w.SetContent(container.New(layout.NewHBoxLayout(), contain, vLevelPB)) w.ShowAndRun() } diff --git a/pkg/vumeter/vumeter.go b/pkg/vumeter/vumeter.go index 6dae69d..5de4c45 100644 --- a/pkg/vumeter/vumeter.go +++ b/pkg/vumeter/vumeter.go @@ -54,47 +54,74 @@ func (v *vuRenderer) updateBars() { } size := v.meter.Size() - greenWidth := 0.0 - amberWidth := 0.0 - redWidth := 0.0 + var ratioSize float64 + if v.meter.VUMeterDirection == VUMeterHorizontal { + ratioSize = float64(size.Width) + } else { + ratioSize = float64(size.Height) + } + + greenSize := 0.0 + amberSize := 0.0 + redSize := 0.0 if ratio > (v.meter.OptimumValueMin / 100) { if ratio > (v.meter.OptimumValueMax / 100) { - greenWidth = float64(size.Width) * v.meter.OptimumValueMin / 100 - amberWidth = float64(size.Width) * v.meter.OptimumValueMax / 100 - redWidth = float64(size.Width) * ratio + greenSize = ratioSize * v.meter.OptimumValueMin / 100 + amberSize = ratioSize * v.meter.OptimumValueMax / 100 + redSize = ratioSize * ratio } else { - greenWidth = float64(size.Width) * v.meter.OptimumValueMin / 100 - amberWidth = float64(size.Width) * ratio + greenSize = ratioSize * v.meter.OptimumValueMin / 100 + amberSize = ratioSize * ratio } } else { - greenWidth = float64(size.Width) * ratio + greenSize = ratioSize * ratio } - redWidth = redWidth - amberWidth - if redWidth < 0 { - redWidth = 0 + redSize = redSize - amberSize + if redSize < 0 { + redSize = 0 } - amberWidth = amberWidth - greenWidth - if amberWidth < 0 { - amberWidth = 0 + amberSize = amberSize - greenSize + if amberSize < 0 { + amberSize = 0 } - lowalphaGreenWidth := float64(size.Width) * v.meter.OptimumValueMin / 100 - lowalphaAmberWidth := float64(size.Width) * v.meter.OptimumValueMax / 100 - lowalphaRedWidth := float64(size.Width) - lowalphaRedWidth = lowalphaRedWidth - lowalphaAmberWidth - lowalphaAmberWidth = lowalphaAmberWidth - lowalphaGreenWidth + lowalphaGreenSize := ratioSize * v.meter.OptimumValueMin / 100 + lowalphaAmberSize := ratioSize * v.meter.OptimumValueMax / 100 + lowalphaRedSize := ratioSize + lowalphaRedSize = lowalphaRedSize - lowalphaAmberSize + lowalphaAmberSize = lowalphaAmberSize - lowalphaGreenSize - v.lowalphaGreen.Resize(fyne.NewSize(float32(lowalphaGreenWidth), size.Height)) - v.lowalphaAmber.Resize(fyne.NewSize(float32(lowalphaAmberWidth), size.Height)) - v.lowalphaAmber.Move(fyne.NewPos(float32(lowalphaGreenWidth), 0)) - v.lowalphaRed.Resize(fyne.NewSize(float32(lowalphaRedWidth), size.Height)) - v.lowalphaRed.Move(fyne.NewPos(float32(lowalphaAmberWidth+lowalphaGreenWidth), 0)) + if v.meter.VUMeterDirection == VUMeterHorizontal { + v.lowalphaGreen.Move(fyne.NewPos(0, 0)) + v.lowalphaGreen.Resize(fyne.NewSize(float32(lowalphaGreenSize), size.Height)) + v.lowalphaAmber.Resize(fyne.NewSize(float32(lowalphaAmberSize), size.Height)) + v.lowalphaAmber.Move(fyne.NewPos(float32(lowalphaGreenSize), 0)) + v.lowalphaRed.Resize(fyne.NewSize(float32(lowalphaRedSize), size.Height)) + v.lowalphaRed.Move(fyne.NewPos(float32(lowalphaAmberSize+lowalphaGreenSize), 0)) + } else { + v.lowalphaGreen.Move(fyne.NewPos(0, size.Height-float32(lowalphaGreenSize))) + v.lowalphaGreen.Resize(fyne.NewSize(size.Width, float32(lowalphaGreenSize))) + v.lowalphaAmber.Resize(fyne.NewSize(size.Width, float32(lowalphaAmberSize))) + v.lowalphaAmber.Move(fyne.NewPos(0, size.Height-float32(lowalphaGreenSize+lowalphaAmberSize))) + v.lowalphaRed.Resize(fyne.NewSize(size.Width, float32(lowalphaRedSize))) + v.lowalphaRed.Move(fyne.NewPos(0, size.Height-float32(lowalphaGreenSize+lowalphaAmberSize+lowalphaRedSize))) + } - v.bar.Resize(fyne.NewSize(float32(greenWidth), size.Height)) - v.optimumBar.Resize(fyne.NewSize(float32(amberWidth), size.Height)) - v.optimumBar.Move(fyne.NewPos(float32(greenWidth), 0)) - v.peakBar.Resize(fyne.NewSize(float32(redWidth), size.Height)) - v.peakBar.Move(fyne.NewPos(float32(greenWidth+amberWidth), 0)) + if v.meter.VUMeterDirection == VUMeterHorizontal { + v.bar.Move(fyne.NewPos(0, 0)) + v.bar.Resize(fyne.NewSize(float32(greenSize), size.Height)) + v.optimumBar.Resize(fyne.NewSize(float32(amberSize), size.Height)) + v.optimumBar.Move(fyne.NewPos(float32(greenSize), 0)) + v.peakBar.Resize(fyne.NewSize(float32(redSize), size.Height)) + v.peakBar.Move(fyne.NewPos(float32(greenSize+amberSize), 0)) + } else { + v.bar.Resize(fyne.NewSize(size.Width, float32(greenSize))) + v.bar.Move(fyne.NewPos(0, size.Height-float32(greenSize))) + v.optimumBar.Resize(fyne.NewSize(size.Width, float32(amberSize))) + v.optimumBar.Move(fyne.NewPos(0, size.Height-float32(greenSize+amberSize))) + v.peakBar.Resize(fyne.NewSize(size.Width, float32(redSize))) + v.peakBar.Move(fyne.NewPos(0, size.Height-float32(greenSize+amberSize+redSize))) + } } // Layout the components of the widget @@ -128,12 +155,20 @@ func (v *vuRenderer) Objects() []fyne.CanvasObject { func (v *vuRenderer) Destroy() { } +type VUMeterDirectionEnum uint32 + +const ( + VUMeterVertical = iota + VUMeterHorizontal +) + // vuMeter widget is a kind of custom progressbar but has "zones" of different color for peaking. type vuMeter struct { widget.BaseWidget TextFormatter func() string Value, Min, Max, OptimumValueMin, OptimumValueMax float64 + VUMeterDirection VUMeterDirectionEnum binder basicBinder } @@ -214,6 +249,7 @@ func NewVUMeter(value float64) *vuMeter { meter.OptimumValueMin = 75 meter.OptimumValueMax = 85 meter.ExtendBaseWidget(meter) + meter.VUMeterDirection = VUMeterHorizontal return meter }