feat(tracker): make instrument name editable

This commit is contained in:
vsariola
2021-02-06 23:39:58 +02:00
parent 6c0cf6832e
commit 5588d7ca7d
4 changed files with 60 additions and 9 deletions

View File

@ -1,14 +1,16 @@
package tracker package tracker
import ( import (
"fmt"
"image" "image"
"gioui.org/io/pointer"
"gioui.org/layout" "gioui.org/layout"
"gioui.org/op" "gioui.org/op"
"gioui.org/op/clip" "gioui.org/op/clip"
"gioui.org/op/paint" "gioui.org/op/paint"
"gioui.org/text"
"gioui.org/unit" "gioui.org/unit"
"gioui.org/widget"
"gioui.org/widget/material" "gioui.org/widget/material"
"golang.org/x/exp/shiny/materialdesign/icons" "golang.org/x/exp/shiny/materialdesign/icons"
) )
@ -63,8 +65,9 @@ func (t *Tracker) layoutInstrumentHeader(gtx C) D {
} else { } else {
deleteInstrumentBtnStyle.Color = disabledTextColor deleteInstrumentBtnStyle.Color = disabledTextColor
} }
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
layout.Rigid(Label("Voices:", white)), return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx,
layout.Rigid(Label("Voices: ", white)),
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(func(gtx layout.Context) layout.Dimensions {
maxRemain := 32 - t.song.Patch.TotalVoices() + t.song.Patch.Instruments[t.CurrentInstrument].NumVoices maxRemain := 32 - t.song.Patch.TotalVoices() + t.song.Patch.Instruments[t.CurrentInstrument].NumVoices
if maxRemain < 0 { if maxRemain < 0 {
@ -90,16 +93,45 @@ func (t *Tracker) layoutInstrumentHeader(gtx C) D {
} }
func (t *Tracker) layoutInstrumentNames(gtx C) D { func (t *Tracker) layoutInstrumentNames(gtx C) D {
element := func(gtx C, i int) D { element := func(gtx C, i int) D {
gtx.Constraints.Min.Y = gtx.Px(unit.Dp(36)) gtx.Constraints.Min.Y = gtx.Px(unit.Dp(36))
text := t.song.Patch.Instruments[i].Name gtx.Constraints.Min.X = gtx.Px(unit.Dp(30))
if text == "" { grabhandle := LabelStyle{Text: "", ShadeColor: black, Color: white, FontSize: unit.Sp(10), Alignment: layout.Center}
text = fmt.Sprintf("%v", i) if i == t.CurrentInstrument {
grabhandle.Text = ":::"
} }
labelStyle := LabelStyle{Text: text, ShadeColor: black, Color: white, Font: labelDefaultFont, FontSize: unit.Sp(12)} label := func(gtx C) D {
return layout.Inset{Left: unit.Dp(10), Right: unit.Dp(10)}.Layout(gtx, func(gtx C) D { if i == t.CurrentInstrument {
for _, ev := range t.InstrumentNameEditor.Events() {
_, ok := ev.(widget.SubmitEvent)
if ok {
t.InstrumentNameEditor = &widget.Editor{SingleLine: true, Submit: true, Alignment: text.Middle} // TODO: is there any other way to defocus the editor
break
}
}
if n := t.song.Patch.Instruments[t.CurrentInstrument].Name; n != t.InstrumentNameEditor.Text() {
t.InstrumentNameEditor.SetText(n)
}
editor := material.Editor(t.Theme, t.InstrumentNameEditor, "Instr")
editor.Color = instrumentNameColor
editor.HintColor = instrumentNameHintColor
editor.TextSize = unit.Dp(12)
dims := layout.Center.Layout(gtx, editor.Layout)
t.SetInstrumentName(t.InstrumentNameEditor.Text())
return dims
}
text := t.song.Patch.Instruments[i].Name
if text == "" {
text = "Instr"
}
labelStyle := LabelStyle{Text: text, ShadeColor: black, Color: white, FontSize: unit.Sp(12)}
return layout.Center.Layout(gtx, labelStyle.Layout) return layout.Center.Layout(gtx, labelStyle.Layout)
}
return layout.Inset{Left: unit.Dp(6), Right: unit.Dp(6)}.Layout(gtx, func(gtx C) D {
return layout.Flex{Axis: layout.Vertical, Alignment: layout.Middle}.Layout(gtx,
layout.Rigid(grabhandle.Layout),
layout.Rigid(label),
)
}) })
} }
@ -109,6 +141,8 @@ func (t *Tracker) layoutInstrumentNames(gtx C) D {
instrumentList.SurfaceColor = transparent instrumentList.SurfaceColor = transparent
t.InstrumentDragList.SelectedItem = t.CurrentInstrument t.InstrumentDragList.SelectedItem = t.CurrentInstrument
defer op.Save(gtx.Ops).Load()
pointer.PassOp{Pass: true}.Add(gtx.Ops)
dims := instrumentList.Layout(gtx) dims := instrumentList.Layout(gtx)
if t.CurrentInstrument != t.InstrumentDragList.SelectedItem { if t.CurrentInstrument != t.InstrumentDragList.SelectedItem {
t.CurrentInstrument = t.InstrumentDragList.SelectedItem t.CurrentInstrument = t.InstrumentDragList.SelectedItem

View File

@ -45,6 +45,9 @@ var noteMap = map[string]int{
// KeyEvent handles incoming key events and returns true if repaint is needed. // KeyEvent handles incoming key events and returns true if repaint is needed.
func (t *Tracker) KeyEvent(e key.Event) bool { func (t *Tracker) KeyEvent(e key.Event) bool {
if e.State == key.Press { if e.State == key.Press {
if t.InstrumentNameEditor.Focused() {
return false
}
switch e.Name { switch e.Name {
case "Z": case "Z":
if e.Modifiers.Contain(key.ModCtrl) { if e.Modifiers.Contain(key.ModCtrl) {

View File

@ -87,6 +87,8 @@ var inactiveBtnColor = color.NRGBA{R: 61, G: 55, B: 55, A: 255}
var instrumentSurfaceColor = color.NRGBA{R: 45, G: 45, B: 45, A: 255} var instrumentSurfaceColor = color.NRGBA{R: 45, G: 45, B: 45, A: 255}
var instrumentHoverColor = color.NRGBA{R: 30, G: 31, B: 38, A: 255} var instrumentHoverColor = color.NRGBA{R: 30, G: 31, B: 38, A: 255}
var instrumentNameColor = color.NRGBA{R: 255, G: 255, B: 255, A: 255}
var instrumentNameHintColor = color.NRGBA{R: 200, G: 200, B: 200, A: 255}
var songSurfaceColor = color.NRGBA{R: 37, G: 37, B: 38, A: 255} var songSurfaceColor = color.NRGBA{R: 37, G: 37, B: 38, A: 255}

View File

@ -2,10 +2,12 @@ package tracker
import ( import (
"fmt" "fmt"
"strings"
"sync" "sync"
"gioui.org/font/gofont" "gioui.org/font/gofont"
"gioui.org/layout" "gioui.org/layout"
"gioui.org/text"
"gioui.org/widget" "gioui.org/widget"
"gioui.org/widget/material" "gioui.org/widget/material"
"github.com/vsariola/sointu" "github.com/vsariola/sointu"
@ -34,6 +36,7 @@ type Tracker struct {
RowsPerPattern *NumberInput RowsPerPattern *NumberInput
RowsPerBeat *NumberInput RowsPerBeat *NumberInput
InstrumentVoices *NumberInput InstrumentVoices *NumberInput
InstrumentNameEditor *widget.Editor
NewTrackBtn *widget.Clickable NewTrackBtn *widget.Clickable
NewInstrumentBtn *widget.Clickable NewInstrumentBtn *widget.Clickable
DeleteInstrumentBtn *widget.Clickable DeleteInstrumentBtn *widget.Clickable
@ -164,6 +167,14 @@ func (t *Tracker) SetInstrumentVoices(value int) bool {
return false return false
} }
func (t *Tracker) SetInstrumentName(name string) {
name = strings.TrimSpace(name)
if name != t.song.Patch.Instruments[t.CurrentInstrument].Name {
t.SaveUndo()
t.song.Patch.Instruments[t.CurrentInstrument].Name = name
}
}
func (t *Tracker) SetBPM(value int) bool { func (t *Tracker) SetBPM(value int) bool {
if value < 1 { if value < 1 {
value = 1 value = 1
@ -442,6 +453,7 @@ func New(audioContext sointu.AudioContext, synthService sointu.SynthService) *Tr
RowsPerPattern: new(NumberInput), RowsPerPattern: new(NumberInput),
RowsPerBeat: new(NumberInput), RowsPerBeat: new(NumberInput),
InstrumentVoices: new(NumberInput), InstrumentVoices: new(NumberInput),
InstrumentNameEditor: &widget.Editor{SingleLine: true, Submit: true, Alignment: text.Middle},
NewTrackBtn: new(widget.Clickable), NewTrackBtn: new(widget.Clickable),
NewInstrumentBtn: new(widget.Clickable), NewInstrumentBtn: new(widget.Clickable),
DeleteInstrumentBtn: new(widget.Clickable), DeleteInstrumentBtn: new(widget.Clickable),