summaryrefslogtreecommitdiff
path: root/src/rhlibrary
diff options
context:
space:
mode:
Diffstat (limited to 'src/rhlibrary')
-rw-r--r--src/rhlibrary/player_widget.go187
-rw-r--r--src/rhlibrary/vumeter_widget.go220
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
+}