package gioui import ( "image" "gioui.org/layout" "gioui.org/op/clip" "gioui.org/op/paint" "gioui.org/unit" "github.com/vsariola/sointu/tracker" ) type ( SpectrumState struct { resolutionNumber *NumericUpDownState smoothingBtn *Clickable chnModeBtn *Clickable } ) func NewSpectrumState() *SpectrumState { return &SpectrumState{ resolutionNumber: NewNumericUpDownState(), smoothingBtn: new(Clickable), chnModeBtn: new(Clickable), } } func (s *SpectrumState) Layout(gtx C) D { s.Update(gtx) t := TrackerFromContext(gtx) leftSpacer := layout.Spacer{Width: unit.Dp(6), Height: unit.Dp(24)}.Layout rightSpacer := layout.Spacer{Width: unit.Dp(6)}.Layout var chnModeTxt string = "???" switch tracker.SpecChnMode(t.Model.SpecAnChannelsInt().Value()) { case tracker.SpecChnModeCombine: chnModeTxt = "Combine" case tracker.SpecChnModeSeparate: chnModeTxt = "Separate" case tracker.SpecChnModeLeft: chnModeTxt = "Left" case tracker.SpecChnModeRight: chnModeTxt = "Right" case tracker.SpecChnModeOff: chnModeTxt = "Off" } var smoothTxt string = "???" switch tracker.SpecSmoothing(t.Model.SpecAnSmoothing().Value()) { case tracker.SpecSmoothingSlow: smoothTxt = "Slow" case tracker.SpecSmoothingMedium: smoothTxt = "Medium" case tracker.SpecSmoothingFast: smoothTxt = "Fast" } resolution := NumUpDown(t.Model.SpecAnResolution(), t.Theme, s.resolutionNumber, "Resolution") chnModeBtn := Btn(t.Theme, &t.Theme.Button.Filled, s.chnModeBtn, chnModeTxt, "Channel mode") smoothBtn := Btn(t.Theme, &t.Theme.Button.Filled, s.smoothingBtn, smoothTxt, "Smoothing") return layout.Flex{Axis: layout.Vertical}.Layout(gtx, layout.Flexed(1, s.drawSpectrum), layout.Rigid(func(gtx C) D { return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx, layout.Rigid(leftSpacer), layout.Flexed(1, func(gtx C) D { return D{Size: gtx.Constraints.Min} }), layout.Rigid(chnModeBtn.Layout), layout.Rigid(smoothBtn.Layout), layout.Rigid(resolution.Layout), layout.Rigid(rightSpacer), ) }), ) } func (s *SpectrumState) Update(gtx C) { t := TrackerFromContext(gtx) for s.chnModeBtn.Clicked(gtx) { t.Model.SpecAnChannelsInt().SetValue((t.SpecAnChannelsInt().Value() + 1) % int(tracker.NumSpecChnModes)) } for s.smoothingBtn.Clicked(gtx) { r := t.Model.SpecAnSmoothing().Range() t.Model.SpecAnSmoothing().SetValue((t.SpecAnSmoothing().Value()+1)%(r.Max-r.Min+1) + r.Min) } } func (s *SpectrumState) drawSpectrum(gtx C) D { t := TrackerFromContext(gtx) for chn := range 2 { paint.ColorOp{Color: t.Theme.Oscilloscope.CurveColors[chn]}.Add(gtx.Ops) p := t.Spectrum()[chn] if len(p) <= 0 { continue } fillRect(gtx, clip.Rect{Min: image.Pt(0, 0), Max: image.Pt(gtx.Constraints.Max.X, 1)}) fillRect(gtx, clip.Rect{Min: image.Pt(0, gtx.Constraints.Min.Y-1), Max: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y)}) for px := range gtx.Constraints.Max.X { y2 := gtx.Constraints.Max.Y - 1 y1 := int(-p[px*len(p)/gtx.Constraints.Max.X] / 80 * float32(y2)) fillRect(gtx, clip.Rect{Min: image.Pt(px, y1), Max: image.Pt(px+1, y2+1)}) } } return D{Size: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y)} }