mirror of
https://github.com/vsariola/sointu.git
synced 2025-06-04 01:28:45 -04:00
feat(tracker): only show either notes or hex for a track + checkbox to toggle
This commit is contained in:
parent
dcb0877c71
commit
5a69c14f61
@ -89,15 +89,19 @@ func (t *Tracker) KeyEvent(e key.Event) bool {
|
|||||||
t.NoteTracking = false
|
t.NoteTracking = false
|
||||||
return true
|
return true
|
||||||
case key.NameLeftArrow:
|
case key.NameLeftArrow:
|
||||||
if t.CursorColumn == 0 {
|
if t.CursorColumn == 0 || !t.TrackShowHex[t.ActiveTrack] || e.Modifiers.Contain(key.ModCtrl) {
|
||||||
t.ActiveTrack = (t.ActiveTrack + len(t.song.Tracks) - 1) % len(t.song.Tracks)
|
t.ActiveTrack = (t.ActiveTrack + len(t.song.Tracks) - 1) % len(t.song.Tracks)
|
||||||
t.CursorColumn = 2
|
if t.TrackShowHex[t.ActiveTrack] {
|
||||||
|
t.CursorColumn = 1
|
||||||
|
} else {
|
||||||
|
t.CursorColumn = 0
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
t.CursorColumn--
|
t.CursorColumn--
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
case key.NameRightArrow:
|
case key.NameRightArrow:
|
||||||
if t.CursorColumn == 2 {
|
if t.CursorColumn == 1 || !t.TrackShowHex[t.ActiveTrack] || e.Modifiers.Contain(key.ModCtrl) {
|
||||||
t.ActiveTrack = (t.ActiveTrack + 1) % len(t.song.Tracks)
|
t.ActiveTrack = (t.ActiveTrack + 1) % len(t.song.Tracks)
|
||||||
t.CursorColumn = 0
|
t.CursorColumn = 0
|
||||||
} else {
|
} else {
|
||||||
@ -119,7 +123,7 @@ func (t *Tracker) KeyEvent(e key.Event) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if t.CursorColumn == 0 {
|
if !t.TrackShowHex[t.ActiveTrack] {
|
||||||
if val, ok := noteMap[e.Name]; ok {
|
if val, ok := noteMap[e.Name]; ok {
|
||||||
t.NotePressed(val)
|
t.NotePressed(val)
|
||||||
return true
|
return true
|
||||||
@ -163,9 +167,9 @@ func (t *Tracker) NotePressed(val int) {
|
|||||||
// NumberPressed handles incoming presses while in either of the hex number columns
|
// NumberPressed handles incoming presses while in either of the hex number columns
|
||||||
func (t *Tracker) NumberPressed(iv byte) {
|
func (t *Tracker) NumberPressed(iv byte) {
|
||||||
val := t.getCurrent()
|
val := t.getCurrent()
|
||||||
if t.CursorColumn == 1 {
|
if t.CursorColumn == 0 {
|
||||||
val = ((iv & 0xF) << 4) | (val & 0xF)
|
val = ((iv & 0xF) << 4) | (val & 0xF)
|
||||||
} else if t.CursorColumn == 2 {
|
} else if t.CursorColumn == 1 {
|
||||||
val = (val & 0xF0) | (iv & 0xF)
|
val = (val & 0xF0) | (iv & 0xF)
|
||||||
}
|
}
|
||||||
t.SetCurrentNote(val)
|
t.SetCurrentNote(val)
|
||||||
|
@ -61,6 +61,15 @@ func enableButton(icStyle material.IconButtonStyle, enabled bool) material.IconB
|
|||||||
return icStyle
|
return icStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func trackButton(t *material.Theme, w *widget.Clickable, text string, enabled bool) material.ButtonStyle {
|
||||||
|
ret := material.Button(t, w, text)
|
||||||
|
if !enabled {
|
||||||
|
ret.Background = disabledContainerColor
|
||||||
|
ret.Color = disabledTextColor
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Tracker) Layout(gtx layout.Context) {
|
func (t *Tracker) Layout(gtx layout.Context) {
|
||||||
paint.FillShape(gtx.Ops, backgroundColor, clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Op())
|
paint.FillShape(gtx.Ops, backgroundColor, 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 {
|
layout.UniformInset(unit.Dp(2)).Layout(gtx, func(gtx2 layout.Context) layout.Dimensions {
|
||||||
@ -95,17 +104,34 @@ func (t *Tracker) layoutTracker(gtx layout.Context) layout.Dimensions {
|
|||||||
for i, trk := range t.song.Tracks {
|
for i, trk := range t.song.Tracks {
|
||||||
i2 := i // avoids i being updated in the closure
|
i2 := i // avoids i being updated in the closure
|
||||||
trk2 := trk // avoids trk being updated in the closure
|
trk2 := trk // avoids trk being updated in the closure
|
||||||
|
if len(t.TrackHexCheckBoxes) <= i {
|
||||||
|
t.TrackHexCheckBoxes = append(t.TrackHexCheckBoxes, new(widget.Bool))
|
||||||
|
}
|
||||||
|
if len(t.TrackShowHex) <= i {
|
||||||
|
t.TrackShowHex = append(t.TrackShowHex, false)
|
||||||
|
}
|
||||||
flexTracks[i] = layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
flexTracks[i] = layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
return leftInset.Layout(gtx, t.layoutTrack(
|
t.TrackHexCheckBoxes[i2].Value = t.TrackShowHex[i2]
|
||||||
trk2.Patterns,
|
cbStyle := material.CheckBox(t.Theme, t.TrackHexCheckBoxes[i2], "hex")
|
||||||
trk2.Sequence,
|
cbStyle.Color = white
|
||||||
t.ActiveTrack == i2,
|
ret := layout.Stack{}.Layout(gtx,
|
||||||
t.CursorRow,
|
layout.Stacked(func(gtx layout.Context) D {
|
||||||
t.DisplayPattern,
|
return leftInset.Layout(gtx, t.layoutTrack(
|
||||||
t.CursorColumn,
|
trk2.Patterns,
|
||||||
t.PlayRow,
|
trk2.Sequence,
|
||||||
playPat,
|
t.ActiveTrack == i2,
|
||||||
))
|
t.TrackShowHex[i2],
|
||||||
|
t.CursorRow,
|
||||||
|
t.DisplayPattern,
|
||||||
|
t.CursorColumn,
|
||||||
|
t.PlayRow,
|
||||||
|
playPat,
|
||||||
|
))
|
||||||
|
}),
|
||||||
|
layout.Stacked(cbStyle.Layout),
|
||||||
|
)
|
||||||
|
t.TrackShowHex[i2] = t.TrackHexCheckBoxes[i2].Value
|
||||||
|
return ret
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
in2 := layout.UniformInset(unit.Dp(8))
|
in2 := layout.UniformInset(unit.Dp(8))
|
||||||
|
@ -14,10 +14,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const trackRowHeight = 16
|
const trackRowHeight = 16
|
||||||
const trackWidth = 84
|
const trackWidth = 54
|
||||||
const patmarkWidth = 16
|
const patmarkWidth = 16
|
||||||
|
|
||||||
func (t *Tracker) layoutTrack(patterns [][]byte, sequence []byte, active bool, cursorRow, cursorPattern, cursorCol, playRow, playPattern int) layout.Widget {
|
func (t *Tracker) layoutTrack(patterns [][]byte, sequence []byte, active bool, hex bool, cursorRow, cursorPattern, cursorCol, playRow, playPattern int) layout.Widget {
|
||||||
return func(gtx layout.Context) layout.Dimensions {
|
return func(gtx layout.Context) layout.Dimensions {
|
||||||
gtx.Constraints.Min.X = trackWidth
|
gtx.Constraints.Min.X = trackWidth
|
||||||
gtx.Constraints.Max.X = trackWidth
|
gtx.Constraints.Max.X = trackWidth
|
||||||
@ -51,16 +51,27 @@ func (t *Tracker) layoutTrack(patterns [][]byte, sequence []byte, active bool, c
|
|||||||
paint.ColorOp{Color: trackerInactiveTextColor}.Add(gtx.Ops)
|
paint.ColorOp{Color: trackerInactiveTextColor}.Add(gtx.Ops)
|
||||||
}
|
}
|
||||||
op.Offset(f32.Pt(patmarkWidth, 0)).Add(gtx.Ops)
|
op.Offset(f32.Pt(patmarkWidth, 0)).Add(gtx.Ops)
|
||||||
widget.Label{}.Layout(gtx, textShaper, trackerFont, trackerFontSize, valueAsNote(c))
|
if hex {
|
||||||
if active && cursorCol == 0 && songRow == cursorSongRow {
|
var text string
|
||||||
paint.FillShape(gtx.Ops, trackerCursorColor, clip.Rect{Max: image.Pt(30, trackRowHeight)}.Op())
|
switch c {
|
||||||
|
case 0:
|
||||||
|
text = "--"
|
||||||
|
case 1:
|
||||||
|
text = ".."
|
||||||
|
default:
|
||||||
|
text = fmt.Sprintf("%02x", c)
|
||||||
|
}
|
||||||
|
widget.Label{}.Layout(gtx, textShaper, trackerFont, trackerFontSize, strings.ToUpper(text))
|
||||||
|
if active && songRow == cursorSongRow {
|
||||||
|
paint.FillShape(gtx.Ops, trackerCursorColor, clip.Rect{Min: image.Pt(cursorCol*10, 0), Max: image.Pt(cursorCol*10+10, trackRowHeight)}.Op())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
widget.Label{}.Layout(gtx, textShaper, trackerFont, trackerFontSize, valueAsNote(c))
|
||||||
|
if active && cursorCol == 0 && songRow == cursorSongRow {
|
||||||
|
paint.FillShape(gtx.Ops, trackerCursorColor, clip.Rect{Max: image.Pt(30, trackRowHeight)}.Op())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
op.Offset(f32.Pt(trackWidth/2, 0)).Add(gtx.Ops)
|
op.Offset(f32.Pt(-patmarkWidth, trackRowHeight)).Add(gtx.Ops)
|
||||||
widget.Label{}.Layout(gtx, textShaper, trackerFont, trackerFontSize, strings.ToUpper(fmt.Sprintf("%02x", c)))
|
|
||||||
if active && cursorCol > 0 && songRow == cursorSongRow {
|
|
||||||
paint.FillShape(gtx.Ops, trackerCursorColor, clip.Rect{Min: image.Pt((cursorCol-1)*10, 0), Max: image.Pt((cursorCol-1)*10+10, trackRowHeight)}.Op())
|
|
||||||
}
|
|
||||||
op.Offset(f32.Pt(-trackWidth/2-patmarkWidth, trackRowHeight)).Add(gtx.Ops)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return layout.Dimensions{Size: gtx.Constraints.Max}
|
return layout.Dimensions{Size: gtx.Constraints.Max}
|
||||||
|
@ -18,32 +18,34 @@ type Tracker struct {
|
|||||||
song sointu.Song
|
song sointu.Song
|
||||||
Playing bool
|
Playing bool
|
||||||
// protects PlayPattern and PlayRow
|
// protects PlayPattern and PlayRow
|
||||||
playRowPatMutex sync.RWMutex // protects song and playing
|
playRowPatMutex sync.RWMutex // protects song and playing
|
||||||
PlayPattern int
|
PlayPattern int
|
||||||
PlayRow int
|
PlayRow int
|
||||||
CursorRow int
|
CursorRow int
|
||||||
CursorColumn int
|
CursorColumn int
|
||||||
DisplayPattern int
|
DisplayPattern int
|
||||||
ActiveTrack int
|
ActiveTrack int
|
||||||
CurrentInstrument int
|
CurrentInstrument int
|
||||||
CurrentUnit int
|
CurrentUnit int
|
||||||
CurrentOctave byte
|
CurrentOctave byte
|
||||||
NoteTracking bool
|
NoteTracking bool
|
||||||
Theme *material.Theme
|
Theme *material.Theme
|
||||||
OctaveUpBtn *widget.Clickable
|
OctaveUpBtn *widget.Clickable
|
||||||
OctaveDownBtn *widget.Clickable
|
OctaveDownBtn *widget.Clickable
|
||||||
BPMUpBtn *widget.Clickable
|
BPMUpBtn *widget.Clickable
|
||||||
BPMDownBtn *widget.Clickable
|
BPMDownBtn *widget.Clickable
|
||||||
NewTrackBtn *widget.Clickable
|
NewTrackBtn *widget.Clickable
|
||||||
NewInstrumentBtn *widget.Clickable
|
NewInstrumentBtn *widget.Clickable
|
||||||
LoadSongFileBtn *widget.Clickable
|
LoadSongFileBtn *widget.Clickable
|
||||||
SongLengthUpBtn *widget.Clickable
|
SongLengthUpBtn *widget.Clickable
|
||||||
SongLengthDownBtn *widget.Clickable
|
SongLengthDownBtn *widget.Clickable
|
||||||
SaveSongFileBtn *widget.Clickable
|
SaveSongFileBtn *widget.Clickable
|
||||||
ParameterSliders []*widget.Float
|
ParameterSliders []*widget.Float
|
||||||
UnitBtns []*widget.Clickable
|
UnitBtns []*widget.Clickable
|
||||||
InstrumentBtns []*widget.Clickable
|
InstrumentBtns []*widget.Clickable
|
||||||
InstrumentList *layout.List
|
InstrumentList *layout.List
|
||||||
|
TrackHexCheckBoxes []*widget.Bool
|
||||||
|
TrackShowHex []bool
|
||||||
|
|
||||||
sequencer *Sequencer
|
sequencer *Sequencer
|
||||||
ticked chan struct{}
|
ticked chan struct{}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user