mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-28 03:10:24 -04:00
140 lines
3.6 KiB
Go
140 lines
3.6 KiB
Go
package tracker
|
|
|
|
import (
|
|
"fmt"
|
|
"image"
|
|
"log"
|
|
|
|
"gioui.org/layout"
|
|
"gioui.org/op"
|
|
"gioui.org/op/clip"
|
|
"gioui.org/op/paint"
|
|
"gioui.org/unit"
|
|
"gioui.org/widget"
|
|
"gioui.org/widget/material"
|
|
|
|
"golang.org/x/exp/shiny/materialdesign/icons"
|
|
)
|
|
|
|
var upIcon *widget.Icon
|
|
var downIcon *widget.Icon
|
|
|
|
func init() {
|
|
var err error
|
|
upIcon, err = widget.NewIcon(icons.NavigationArrowUpward)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
downIcon, err = widget.NewIcon(icons.NavigationArrowDownward)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func (t *Tracker) Layout(gtx layout.Context) {
|
|
paint.FillShape(gtx.Ops, black, clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Op())
|
|
layout.UniformInset(unit.Dp(2)).Layout(gtx, func(gtx2 layout.Context) layout.Dimensions {
|
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx2,
|
|
layout.Rigid(t.layoutControls),
|
|
layout.Rigid(t.darkLine(true)),
|
|
layout.Flexed(1, Raised(t.layoutTracker)))
|
|
})
|
|
}
|
|
|
|
func (t *Tracker) layoutTracker(gtx layout.Context) layout.Dimensions {
|
|
flexTracks := make([]layout.FlexChild, len(t.song.Tracks))
|
|
t.playRowPatMutex.RLock()
|
|
defer t.playRowPatMutex.RUnlock()
|
|
|
|
playPat := t.PlayPattern
|
|
if !t.Playing {
|
|
playPat = -1
|
|
}
|
|
|
|
for i, trk := range t.song.Tracks {
|
|
flexTracks[i] = layout.Rigid(Lowered(t.layoutTrack(
|
|
trk.Patterns,
|
|
trk.Sequence,
|
|
t.ActiveTrack == i,
|
|
t.CursorRow,
|
|
t.DisplayPattern,
|
|
t.CursorColumn,
|
|
t.PlayRow,
|
|
playPat,
|
|
)))
|
|
}
|
|
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
|
flexTracks...,
|
|
)
|
|
}
|
|
|
|
func (t *Tracker) layoutControls(gtx layout.Context) layout.Dimensions {
|
|
gtx.Constraints.Min.Y = 200
|
|
gtx.Constraints.Max.Y = 200
|
|
|
|
playPat := t.PlayPattern
|
|
if !t.Playing {
|
|
playPat = -1
|
|
}
|
|
in := layout.UniformInset(unit.Dp(8))
|
|
|
|
for t.OctaveUpBtn.Clicked() {
|
|
t.ChangeOctave(1)
|
|
}
|
|
for t.OctaveDownBtn.Clicked() {
|
|
t.ChangeOctave(-1)
|
|
}
|
|
for t.BPMUpBtn.Clicked() {
|
|
t.ChangeBPM(1)
|
|
}
|
|
for t.BPMDownBtn.Clicked() {
|
|
t.ChangeBPM(-1)
|
|
}
|
|
|
|
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
|
layout.Rigid(Raised(t.layoutPatterns(
|
|
t.song.Tracks,
|
|
t.ActiveTrack,
|
|
t.DisplayPattern,
|
|
t.CursorColumn,
|
|
playPat,
|
|
))),
|
|
layout.Rigid(t.darkLine(false)),
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
return in.Layout(gtx, material.IconButton(t.Theme, t.OctaveUpBtn, upIcon).Layout)
|
|
}),
|
|
layout.Rigid(t.darkLine(false)),
|
|
layout.Rigid(Raised(Label(fmt.Sprintf("OCT: %v", t.CurrentOctave), white))),
|
|
layout.Rigid(t.darkLine(false)),
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
return in.Layout(gtx, material.IconButton(t.Theme, t.OctaveDownBtn, downIcon).Layout)
|
|
}),
|
|
layout.Rigid(t.darkLine(false)),
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
return in.Layout(gtx, material.IconButton(t.Theme, t.BPMUpBtn, upIcon).Layout)
|
|
}),
|
|
layout.Rigid(t.darkLine(false)),
|
|
layout.Rigid(Raised(Label(fmt.Sprintf("BPM: %3v", t.song.BPM), white))),
|
|
layout.Rigid(t.darkLine(false)),
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
return in.Layout(gtx, material.IconButton(t.Theme, t.BPMDownBtn, downIcon).Layout)
|
|
}),
|
|
)
|
|
}
|
|
|
|
func (t *Tracker) darkLine(horizontal bool) layout.Widget {
|
|
return func(gtx layout.Context) layout.Dimensions {
|
|
if horizontal {
|
|
gtx.Constraints.Min.Y = 1
|
|
gtx.Constraints.Max.Y = 1
|
|
} else {
|
|
gtx.Constraints.Min.X = 1
|
|
gtx.Constraints.Max.X = 1
|
|
}
|
|
defer op.Push(gtx.Ops).Pop()
|
|
clip.Rect{Max: gtx.Constraints.Max}.Add(gtx.Ops)
|
|
paint.FillShape(gtx.Ops, black, clip.Rect{Max: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y)}.Op())
|
|
return layout.Dimensions{Size: gtx.Constraints.Max}
|
|
}
|
|
}
|