summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@helsinki.at>2016-01-27 22:47:38 (GMT)
committerChristian Pointner <equinox@helsinki.at>2016-01-27 22:47:38 (GMT)
commitd05ebe8503985f65b918945b869f295a9595ca5e (patch)
tree08c1650e9efee9fbe988a92990c00a3d3be0687d
parent1c496199865c5d0a24c9d683df5a5913c2190beb (diff)
improved VU meter
-rw-r--r--src/rhlibrary/player_widget.go136
1 files changed, 103 insertions, 33 deletions
diff --git a/src/rhlibrary/player_widget.go b/src/rhlibrary/player_widget.go
index d88bbf6..8019cd9 100644
--- a/src/rhlibrary/player_widget.go
+++ b/src/rhlibrary/player_widget.go
@@ -33,31 +33,37 @@ import (
)
const (
- meterDBFloor float64 = 72 // -72 db is the lowest VU value
- meterSegments float64 = 30 // meter has 30 elements
-
- meterOffsetGreen float64 = meterSegments - 4
- meterOffsetOrange float64 = meterSegments - 2
- meterOffsetRed float64 = meterSegments - 1
+ meterDBFloor float64 = 72 // -72 db is the lowest VU value
+ meterSegmentsGreen float64 = 21
+ meterSegmentsOrange float64 = 3
+ meterSegmentsRed float64 = 1
+ meterSegmentsTotal float64 = meterSegmentsGreen + meterSegmentsOrange + meterSegmentsRed
)
var (
- levelBarCss *gtk.CssProvider
+ meterBarCSS *gtk.CssProvider
+ meterFrameCSS *gtk.CssProvider
)
func init() {
var err error
- if levelBarCss, err = gtk.CssProviderNew(); err != nil {
+ if meterBarCSS, err = gtk.CssProviderNew(); err != nil {
panic(err.Error())
}
- err = levelBarCss.LoadFromData(`
+ err = meterBarCSS.LoadFromData(`
.level-bar {
-GtkLevelBar-min-block-width: 13;
-GtkLevelBar-min-block-height: 8;
}
+.level-bar.trough {
+ border: 0;
+ padding: 0;
+ border-radius: 0;
+ background-image: unset;
+}
.level-bar.fill-block.level-green {
- border-color: #00AE00;
- background-image: linear-gradient(to bottom, #36FF36, #00AE00);
+ border-color: #006600;
+ background-image: linear-gradient(to bottom, #36B736, #006600);
}
.level-bar.fill-block.level-orange {
border-color: #AE6600;
@@ -70,6 +76,14 @@ func init() {
if err != nil {
panic(err.Error())
}
+
+ if meterFrameCSS, err = gtk.CssProviderNew(); err != nil {
+ panic(err.Error())
+ }
+ err = meterFrameCSS.LoadFromData(".frame { padding: 3px; }")
+ if err != nil {
+ panic(err.Error())
+ }
}
func addPlayButton(grid *gtk.Grid, p *player.PlayerChan) (err error) {
@@ -114,18 +128,40 @@ func addStopButton(grid *gtk.Grid, p *player.PlayerChan) (err error) {
return
}
-func calcMeterLevel(valdb float64) (val float64) {
- val = valdb + meterDBFloor
+type vuMeterLevel struct {
+ green float64
+ orange float64
+ red float64
+}
+
+func (lvl *vuMeterLevel) setLevel(valdb float64) {
+ val := valdb + meterDBFloor
if val < 0 {
val = 0
} else {
- val = (val / meterDBFloor) * meterSegments
+ val = (val / meterDBFloor) * meterSegmentsTotal
+ }
+
+ lvl.green = val
+ lvl.orange = val - meterSegmentsGreen
+ lvl.red = lvl.orange - meterSegmentsOrange
+ if lvl.orange < 0 {
+ lvl.orange = 0
+ }
+ if lvl.red < 0 {
+ lvl.red = 0
}
return
}
-func createMeterBar() (bar *gtk.LevelBar, err error) {
- if bar, err = gtk.LevelBarNewForInterval(0, meterSegments); err != nil {
+type vuMeter struct {
+ green *gtk.LevelBar
+ orange *gtk.LevelBar
+ red *gtk.LevelBar
+}
+
+func createMeterBar(segments float64) (bar *gtk.LevelBar, err error) {
+ if bar, err = gtk.LevelBarNewForInterval(0, segments); err != nil {
return
}
bar.SetMode(gtk.LEVEL_BAR_MODE_DISCRETE)
@@ -136,41 +172,60 @@ func createMeterBar() (bar *gtk.LevelBar, err error) {
if sc, err = bar.GetStyleContext(); err != nil {
return
}
- sc.AddProvider(levelBarCss, 600) // TOOD: hardcoded value
+ sc.AddProvider(meterBarCSS, 600) // TOOD: hardcoded value
+ return
+}
- bar.AddOffsetValue("green", meterOffsetGreen)
- bar.AddOffsetValue("orange", meterOffsetOrange)
- bar.AddOffsetValue("red", meterOffsetRed)
+func newVUMeter() (meter *vuMeter, err error) {
+ meter = &vuMeter{}
+ if meter.green, err = createMeterBar(meterSegmentsGreen); err != nil {
+ return
+ }
+ if meter.orange, err = createMeterBar(meterSegmentsOrange); err != nil {
+ return
+ }
+ if meter.red, err = createMeterBar(meterSegmentsRed); err != nil {
+ return
+ }
+
+ meter.green.AddOffsetValue("green", 0)
+ meter.orange.AddOffsetValue("orange", 0)
+ meter.red.AddOffsetValue("red", 0)
return
}
+func (m *vuMeter) SetValue(lvl *vuMeterLevel) {
+ m.green.SetValue(lvl.green)
+ m.orange.SetValue(lvl.orange)
+ m.red.SetValue(lvl.red)
+}
+
func addMeter(grid *gtk.Grid, p *player.PlayerChan) (err error) {
var mgrid *gtk.Grid
if mgrid, err = gtk.GridNew(); err != nil {
return
}
- mgrid.SetOrientation(gtk.ORIENTATION_VERTICAL)
- mgrid.SetColumnSpacing(3)
+ mgrid.SetRowSpacing(3)
- var left, right *gtk.LevelBar
- if left, err = createMeterBar(); err != nil {
+ var left, right *vuMeter
+ if left, err = newVUMeter(); err != nil {
return
}
- if right, err = createMeterBar(); err != nil {
+ if right, err = newVUMeter(); err != nil {
return
}
p.AddUpdateHandler(func(length time.Duration, pos time.Duration, meter player.Meter, userdata interface{}) bool {
glib.IdleAdd(func() {
ch := len(meter)
- lval := float64(0)
- rval := float64(0)
+ lval := &vuMeterLevel{0, 0, 0}
+ rval := &vuMeterLevel{0, 0, 0}
if ch >= 2 {
- lval = calcMeterLevel(meter[0].Peak)
- rval = calcMeterLevel(meter[1].Peak)
+ lval.setLevel(meter[0].Peak)
+ rval.setLevel(meter[1].Peak)
} else if ch == 1 {
- lval = calcMeterLevel(meter[0].Peak)
+ lval.setLevel(meter[0].Peak)
rval = lval
}
left.SetValue(lval)
@@ -179,10 +234,25 @@ func addMeter(grid *gtk.Grid, p *player.PlayerChan) (err error) {
return true
}, nil)
- mgrid.Add(left)
- mgrid.Add(right)
+ mgrid.Attach(left.green, 1, 1, 1, 1)
+ mgrid.Attach(left.orange, 2, 1, 1, 1)
+ mgrid.Attach(left.red, 3, 1, 1, 1)
+ mgrid.Attach(right.green, 1, 2, 1, 1)
+ mgrid.Attach(right.orange, 2, 2, 1, 1)
+ mgrid.Attach(right.red, 3, 2, 1, 1)
+
+ var frame *gtk.Frame
+ if frame, err = gtk.FrameNew(""); err != nil {
+ return
+ }
+ var sc *gtk.StyleContext
+ if sc, err = frame.GetStyleContext(); err != nil {
+ return
+ }
+ sc.AddProvider(meterFrameCSS, 600) // TOOD: hardcoded value
- grid.Add(mgrid)
+ frame.Add(mgrid)
+ grid.Add(frame)
return
}