diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rhlibrary/player_widget.go | 187 | ||||
-rw-r--r-- | src/rhlibrary/vumeter_widget.go | 220 |
2 files changed, 225 insertions, 182 deletions
diff --git a/src/rhlibrary/player_widget.go b/src/rhlibrary/player_widget.go index 8019cd9..5440582 100644 --- a/src/rhlibrary/player_widget.go +++ b/src/rhlibrary/player_widget.go @@ -25,67 +25,10 @@ package main import ( - "time" - "code.helsinki.at/rhrd-go/player" - "github.com/gotk3/gotk3/glib" "github.com/gotk3/gotk3/gtk" ) -const ( - 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 ( - meterBarCSS *gtk.CssProvider - meterFrameCSS *gtk.CssProvider -) - -func init() { - var err error - if meterBarCSS, err = gtk.CssProviderNew(); err != nil { - panic(err.Error()) - } - 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: #006600; - background-image: linear-gradient(to bottom, #36B736, #006600); -} -.level-bar.fill-block.level-orange { - border-color: #AE6600; - background-image: linear-gradient(to bottom, #FFAC36, #AE6600); -} -.level-bar.fill-block.level-red { - border-color: #AE0000; - background-image: linear-gradient(to bottom, #FF3636, #AE0000); -}`) - 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) { var btn *gtk.Button if btn, err = gtk.ButtonNewFromIconName("media-playback-start", gtk.ICON_SIZE_DIALOG); err != nil { @@ -128,132 +71,12 @@ func addStopButton(grid *gtk.Grid, p *player.PlayerChan) (err error) { return } -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) * 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 -} - -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 +func addMeter(grid *gtk.Grid, p *player.PlayerChan) error { + widget, err := getVUMeterWidget(p) + if err == nil { + grid.Add(widget) } - bar.SetMode(gtk.LEVEL_BAR_MODE_DISCRETE) - bar.RemoveOffsetValue(gtk.LEVEL_BAR_OFFSET_LOW) - bar.RemoveOffsetValue(gtk.LEVEL_BAR_OFFSET_HIGH) - - var sc *gtk.StyleContext - if sc, err = bar.GetStyleContext(); err != nil { - return - } - sc.AddProvider(meterBarCSS, 600) // TOOD: hardcoded value - return -} - -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.SetRowSpacing(3) - - var left, right *vuMeter - if left, err = newVUMeter(); err != nil { - return - } - 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 := &vuMeterLevel{0, 0, 0} - rval := &vuMeterLevel{0, 0, 0} - if ch >= 2 { - lval.setLevel(meter[0].Peak) - rval.setLevel(meter[1].Peak) - } else if ch == 1 { - lval.setLevel(meter[0].Peak) - rval = lval - } - left.SetValue(lval) - right.SetValue(rval) - }) - return true - }, nil) - - 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 - - frame.Add(mgrid) - grid.Add(frame) - return + return err } func getPlayerWidget(p *player.PlayerChan) (gtk.IWidget, error) { diff --git a/src/rhlibrary/vumeter_widget.go b/src/rhlibrary/vumeter_widget.go new file mode 100644 index 0000000..323e826 --- /dev/null +++ b/src/rhlibrary/vumeter_widget.go @@ -0,0 +1,220 @@ +// +// rhlibrary +// +// The Radio Helsinki Rivendell Library +// +// +// Copyright (C) 2016 Christian Pointner <equinox@helsinki.at> +// +// This file is part of rhlibrary. +// +// rhlibrary is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// rhlibrary is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with rhlibrary. If not, see <http://www.gnu.org/licenses/>. +// + +package main + +import ( + "time" + + "code.helsinki.at/rhrd-go/player" + "github.com/gotk3/gotk3/glib" + "github.com/gotk3/gotk3/gtk" +) + +const ( + 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 ( + meterBarCSS *gtk.CssProvider +) + +func init() { + var err error + if meterBarCSS, err = gtk.CssProviderNew(); err != nil { + panic(err.Error()) + } + 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: #006600; + background-image: linear-gradient(to bottom, #36B736, #006600); +} +.level-bar.fill-block.level-orange { + border-color: #AE6600; + background-image: linear-gradient(to bottom, #FFAC36, #AE6600); +} +.level-bar.fill-block.level-red { + border-color: #AE0000; + background-image: linear-gradient(to bottom, #FF3636, #AE0000); +}`) + if err != nil { + panic(err.Error()) + } +} + +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) * 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 +} + +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) + bar.RemoveOffsetValue(gtk.LEVEL_BAR_OFFSET_LOW) + bar.RemoveOffsetValue(gtk.LEVEL_BAR_OFFSET_HIGH) + + var sc *gtk.StyleContext + if sc, err = bar.GetStyleContext(); err != nil { + return + } + sc.AddProvider(meterBarCSS, 600) // TOOD: hardcoded value + return +} + +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 addVUMeterGrid(frame *gtk.Frame, p *player.PlayerChan) (err error) { + var grid *gtk.Grid + if grid, err = gtk.GridNew(); err != nil { + return + } + grid.SetRowSpacing(3) + + var left, right *vuMeter + if left, err = newVUMeter(); err != nil { + return + } + 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 := &vuMeterLevel{0, 0, 0} + rval := &vuMeterLevel{0, 0, 0} + if ch >= 2 { + lval.setLevel(meter[0].Peak) + rval.setLevel(meter[1].Peak) + } else if ch == 1 { + lval.setLevel(meter[0].Peak) + rval = lval + } + left.SetValue(lval) + right.SetValue(rval) + }) + return true + }, nil) + + grid.Attach(left.green, 1, 1, 1, 1) + grid.Attach(left.orange, 2, 1, 1, 1) + grid.Attach(left.red, 3, 1, 1, 1) + grid.Attach(right.green, 1, 2, 1, 1) + grid.Attach(right.orange, 2, 2, 1, 1) + grid.Attach(right.red, 3, 2, 1, 1) + + frame.Add(grid) + return +} + +func getVUMeterWidget(p *player.PlayerChan) (gtk.IWidget, error) { + frame, err := gtk.FrameNew("") + if err != nil { + return nil, err + } + + var cp *gtk.CssProvider + if cp, err = gtk.CssProviderNew(); err != nil { + return nil, err + } + if err = cp.LoadFromData(".frame { padding: 3px; }"); err != nil { + return nil, err + } + var sc *gtk.StyleContext + if sc, err = frame.GetStyleContext(); err != nil { + return nil, err + } + sc.AddProvider(cp, 600) // TOOD: hardcoded value + + if err = addVUMeterGrid(frame, p); err != nil { + return nil, err + } + return frame, nil +} |