diff options
author | Christian Pointner <equinox@helsinki.at> | 2016-01-27 22:47:38 (GMT) |
---|---|---|
committer | Christian Pointner <equinox@helsinki.at> | 2016-01-27 22:47:38 (GMT) |
commit | d05ebe8503985f65b918945b869f295a9595ca5e (patch) | |
tree | 08c1650e9efee9fbe988a92990c00a3d3be0687d /src | |
parent | 1c496199865c5d0a24c9d683df5a5913c2190beb (diff) |
improved VU meter
Diffstat (limited to 'src')
-rw-r--r-- | src/rhlibrary/player_widget.go | 136 |
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 } |