mirror of
https://github.com/vsariola/sointu.git
synced 2025-06-03 00:58:26 -04:00
feat(tracker): add semitone & octave up/down buttons
This commit is contained in:
parent
eb36a96e29
commit
08dcbb9edb
@ -139,7 +139,40 @@ func (t *Tracker) layoutTracks(gtx layout.Context) layout.Dimensions {
|
|||||||
}.Op())
|
}.Op())
|
||||||
return layout.Dimensions{Size: gtx.Constraints.Min}
|
return layout.Dimensions{Size: gtx.Constraints.Min}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for t.AddSemitoneBtn.Clicked() {
|
||||||
|
t.AdjustSelectionPitch(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
for t.SubtractSemitoneBtn.Clicked() {
|
||||||
|
t.AdjustSelectionPitch(-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
for t.AddOctaveBtn.Clicked() {
|
||||||
|
t.AdjustSelectionPitch(12)
|
||||||
|
}
|
||||||
|
|
||||||
|
for t.SubtractOctaveBtn.Clicked() {
|
||||||
|
t.AdjustSelectionPitch(-12)
|
||||||
|
}
|
||||||
|
|
||||||
menu := func(gtx C) D {
|
menu := func(gtx C) D {
|
||||||
|
addSemitoneBtnStyle := material.Button(t.Theme, t.AddSemitoneBtn, "+1")
|
||||||
|
addSemitoneBtnStyle.Color = primaryColor
|
||||||
|
addSemitoneBtnStyle.Background = transparent
|
||||||
|
addSemitoneBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
||||||
|
subtractSemitoneBtnStyle := material.Button(t.Theme, t.SubtractSemitoneBtn, "-1")
|
||||||
|
subtractSemitoneBtnStyle.Color = primaryColor
|
||||||
|
subtractSemitoneBtnStyle.Background = transparent
|
||||||
|
subtractSemitoneBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
||||||
|
addOctaveBtnStyle := material.Button(t.Theme, t.AddOctaveBtn, "+12")
|
||||||
|
addOctaveBtnStyle.Color = primaryColor
|
||||||
|
addOctaveBtnStyle.Background = transparent
|
||||||
|
addOctaveBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
||||||
|
subtractOctaveBtnStyle := material.Button(t.Theme, t.SubtractOctaveBtn, "-12")
|
||||||
|
subtractOctaveBtnStyle.Color = primaryColor
|
||||||
|
subtractOctaveBtnStyle.Background = transparent
|
||||||
|
subtractOctaveBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
||||||
newTrackBtnStyle := material.IconButton(t.Theme, t.NewTrackBtn, addIcon)
|
newTrackBtnStyle := material.IconButton(t.Theme, t.NewTrackBtn, addIcon)
|
||||||
newTrackBtnStyle.Background = transparent
|
newTrackBtnStyle.Background = transparent
|
||||||
newTrackBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
newTrackBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
||||||
@ -158,6 +191,11 @@ func (t *Tracker) layoutTracks(gtx layout.Context) layout.Dimensions {
|
|||||||
return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx,
|
return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx,
|
||||||
layout.Rigid(Label("OCT:", white)),
|
layout.Rigid(Label("OCT:", white)),
|
||||||
layout.Rigid(octave),
|
layout.Rigid(octave),
|
||||||
|
layout.Rigid(Label(" PITCH:", white)),
|
||||||
|
layout.Rigid(addSemitoneBtnStyle.Layout),
|
||||||
|
layout.Rigid(subtractSemitoneBtnStyle.Layout),
|
||||||
|
layout.Rigid(addOctaveBtnStyle.Layout),
|
||||||
|
layout.Rigid(subtractOctaveBtnStyle.Layout),
|
||||||
layout.Flexed(1, func(gtx C) D { return layout.Dimensions{Size: gtx.Constraints.Min} }),
|
layout.Flexed(1, func(gtx C) D { return layout.Dimensions{Size: gtx.Constraints.Min} }),
|
||||||
layout.Rigid(newTrackBtnStyle.Layout))
|
layout.Rigid(newTrackBtnStyle.Layout))
|
||||||
}
|
}
|
||||||
@ -191,12 +229,6 @@ func (t *Tracker) layoutTracks(gtx layout.Context) layout.Dimensions {
|
|||||||
|
|
||||||
func (t *Tracker) layoutControls(gtx layout.Context) layout.Dimensions {
|
func (t *Tracker) layoutControls(gtx layout.Context) layout.Dimensions {
|
||||||
go func() {
|
go func() {
|
||||||
/*for t.BPMUpBtn.Clicked() {
|
|
||||||
t.ChangeBPM(1)
|
|
||||||
}
|
|
||||||
for t.BPMDownBtn.Clicked() {
|
|
||||||
t.ChangeBPM(-1)
|
|
||||||
}*/
|
|
||||||
for t.NewInstrumentBtn.Clicked() {
|
for t.NewInstrumentBtn.Clicked() {
|
||||||
t.AddInstrument()
|
t.AddInstrument()
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,10 @@ type Tracker struct {
|
|||||||
NewInstrumentBtn *widget.Clickable
|
NewInstrumentBtn *widget.Clickable
|
||||||
LoadSongFileBtn *widget.Clickable
|
LoadSongFileBtn *widget.Clickable
|
||||||
NewSongFileBtn *widget.Clickable
|
NewSongFileBtn *widget.Clickable
|
||||||
|
AddSemitoneBtn *widget.Clickable
|
||||||
|
SubtractSemitoneBtn *widget.Clickable
|
||||||
|
AddOctaveBtn *widget.Clickable
|
||||||
|
SubtractOctaveBtn *widget.Clickable
|
||||||
SongLength *NumberInput
|
SongLength *NumberInput
|
||||||
SaveSongFileBtn *widget.Clickable
|
SaveSongFileBtn *widget.Clickable
|
||||||
ParameterSliders []*widget.Float
|
ParameterSliders []*widget.Float
|
||||||
@ -256,8 +260,7 @@ func (t *Tracker) SetSongLength(value int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tracker) DeleteSelection() {
|
func (t *Tracker) getSelectionRange() (int, int, int, int) {
|
||||||
t.SaveUndo()
|
|
||||||
r1 := t.Cursor.Pattern*t.song.PatternRows() + t.Cursor.Row
|
r1 := t.Cursor.Pattern*t.song.PatternRows() + t.Cursor.Row
|
||||||
r2 := t.SelectionCorner.Pattern*t.song.PatternRows() + t.SelectionCorner.Row
|
r2 := t.SelectionCorner.Pattern*t.song.PatternRows() + t.SelectionCorner.Row
|
||||||
if r2 < r1 {
|
if r2 < r1 {
|
||||||
@ -268,10 +271,48 @@ func (t *Tracker) DeleteSelection() {
|
|||||||
if t2 < t1 {
|
if t2 < t1 {
|
||||||
t1, t2 = t2, t1
|
t1, t2 = t2, t1
|
||||||
}
|
}
|
||||||
for r := r1; r <= r2; r++ {
|
return r1, r2, t1, t2
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tracker) AdjustSelectionPitch(delta int) {
|
||||||
|
t.SaveUndo()
|
||||||
|
r1, r2, t1, t2 := t.getSelectionRange()
|
||||||
for c := t1; c <= t2; c++ {
|
for c := t1; c <= t2; c++ {
|
||||||
|
adjustedNotes := map[struct {
|
||||||
|
Pat byte
|
||||||
|
Row int
|
||||||
|
}]bool{}
|
||||||
|
for r := r1; r <= r2; r++ {
|
||||||
s := SongRow{Row: r}
|
s := SongRow{Row: r}
|
||||||
s.Wrap(t.song)
|
s.Wrap(t.song)
|
||||||
|
p := t.song.Tracks[c].Sequence[s.Pattern]
|
||||||
|
noteIndex := struct {
|
||||||
|
Pat byte
|
||||||
|
Row int
|
||||||
|
}{p, s.Row}
|
||||||
|
if !adjustedNotes[noteIndex] {
|
||||||
|
if val := t.song.Tracks[c].Patterns[p][s.Row]; val > 1 {
|
||||||
|
newVal := int(val) + delta
|
||||||
|
if newVal < 2 {
|
||||||
|
newVal = 2
|
||||||
|
} else if newVal > 255 {
|
||||||
|
newVal = 255
|
||||||
|
}
|
||||||
|
t.song.Tracks[c].Patterns[p][s.Row] = byte(newVal)
|
||||||
|
}
|
||||||
|
adjustedNotes[noteIndex] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tracker) DeleteSelection() {
|
||||||
|
t.SaveUndo()
|
||||||
|
r1, r2, t1, t2 := t.getSelectionRange()
|
||||||
|
for r := r1; r <= r2; r++ {
|
||||||
|
s := SongRow{Row: r}
|
||||||
|
s.Wrap(t.song)
|
||||||
|
for c := t1; c <= t2; c++ {
|
||||||
p := t.song.Tracks[c].Sequence[s.Pattern]
|
p := t.song.Tracks[c].Sequence[s.Pattern]
|
||||||
t.song.Tracks[c].Patterns[p][s.Row] = 1
|
t.song.Tracks[c].Patterns[p][s.Row] = 1
|
||||||
}
|
}
|
||||||
@ -291,6 +332,10 @@ func New(audioContext sointu.AudioContext) *Tracker {
|
|||||||
NewSongFileBtn: new(widget.Clickable),
|
NewSongFileBtn: new(widget.Clickable),
|
||||||
LoadSongFileBtn: new(widget.Clickable),
|
LoadSongFileBtn: new(widget.Clickable),
|
||||||
SaveSongFileBtn: new(widget.Clickable),
|
SaveSongFileBtn: new(widget.Clickable),
|
||||||
|
AddSemitoneBtn: new(widget.Clickable),
|
||||||
|
SubtractSemitoneBtn: new(widget.Clickable),
|
||||||
|
AddOctaveBtn: new(widget.Clickable),
|
||||||
|
SubtractOctaveBtn: new(widget.Clickable),
|
||||||
setPlaying: make(chan bool),
|
setPlaying: make(chan bool),
|
||||||
rowJump: make(chan int),
|
rowJump: make(chan int),
|
||||||
patternJump: make(chan int),
|
patternJump: make(chan int),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user