feat(tracker): copy instrument to & paste from clipboard

Closes #25
This commit is contained in:
vsariola 2021-02-16 21:43:39 +02:00
parent 088bbc6c58
commit 09a9f072cc
3 changed files with 39 additions and 2 deletions

View File

@ -4,6 +4,7 @@ import (
"image"
"strconv"
"gioui.org/io/clipboard"
"gioui.org/io/pointer"
"gioui.org/layout"
"gioui.org/op"
@ -12,6 +13,7 @@ import (
"gioui.org/widget"
"gioui.org/widget/material"
"golang.org/x/exp/shiny/materialdesign/icons"
"gopkg.in/yaml.v3"
)
var instrumentPointerTag = false
@ -63,6 +65,11 @@ func (t *Tracker) layoutInstruments(gtx C) D {
func (t *Tracker) layoutInstrumentHeader(gtx C) D {
header := func(gtx C) D {
copyInstrumentBtnStyle := material.IconButton(t.Theme, t.CopyInstrumentBtn, widgetForIcon(icons.ContentContentCopy))
copyInstrumentBtnStyle.Background = transparent
copyInstrumentBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
copyInstrumentBtnStyle.Color = primaryColor
deleteInstrumentBtnStyle := material.IconButton(t.Theme, t.DeleteInstrumentBtn, widgetForIcon(icons.ActionDelete))
deleteInstrumentBtnStyle.Background = transparent
deleteInstrumentBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
@ -88,8 +95,15 @@ func (t *Tracker) layoutInstrumentHeader(gtx C) D {
return dims
}),
layout.Flexed(1, func(gtx C) D { return layout.Dimensions{Size: gtx.Constraints.Min} }),
layout.Rigid(copyInstrumentBtnStyle.Layout),
layout.Rigid(deleteInstrumentBtnStyle.Layout))
}
for t.CopyInstrumentBtn.Clicked() {
contents, err := yaml.Marshal(t.song.Patch.Instruments[t.CurrentInstrument])
if err == nil {
clipboard.WriteOp{Text: string(contents)}.Add(gtx.Ops)
}
}
for t.DeleteInstrumentBtn.Clicked() {
t.DeleteInstrument()
}

View File

@ -24,7 +24,7 @@ func (t *Tracker) Run(w *app.Window) error {
w.Invalidate()
}
case clipboard.Event:
err := t.UnmarshalSong([]byte(e.Text))
err := t.UnmarshalContent([]byte(e.Text))
if err == nil {
w.Invalidate()
}

View File

@ -60,6 +60,7 @@ type Tracker struct {
SubtractOctaveBtn *widget.Clickable
SongLength *NumberInput
PanicBtn *widget.Clickable
CopyInstrumentBtn *widget.Clickable
ParameterSliders []*widget.Float
ParameterList *layout.List
UnitDragList *DragList
@ -100,7 +101,18 @@ func (t *Tracker) LoadSong(song sointu.Song) error {
return nil
}
func (t *Tracker) UnmarshalSong(bytes []byte) error {
func (t *Tracker) UnmarshalContent(bytes []byte) error {
var instr sointu.Instrument
if errJSON := json.Unmarshal(bytes, &instr); errJSON == nil {
if t.SetInstrument(instr) {
return nil
}
}
if errYaml := yaml.Unmarshal(bytes, &instr); errYaml == nil {
if t.SetInstrument(instr) {
return nil
}
}
var song sointu.Song
if errJSON := json.Unmarshal(bytes, &song); errJSON != nil {
if errYaml := yaml.Unmarshal(bytes, &song); errYaml != nil {
@ -149,6 +161,16 @@ func (t *Tracker) ChangeOctave(delta int) bool {
return false
}
func (t *Tracker) SetInstrument(instrument sointu.Instrument) bool {
if len(instrument.Units) > 0 {
t.SaveUndo()
t.song.Patch.Instruments[t.CurrentInstrument] = instrument
t.sequencer.SetPatch(t.song.Patch)
return true
}
return false
}
func (t *Tracker) SetInstrumentVoices(value int) bool {
if value < 1 {
value = 1
@ -674,6 +696,7 @@ func New(audioContext sointu.AudioContext, synthService sointu.SynthService) *Tr
DeleteUnitBtn: new(widget.Clickable),
ClearUnitBtn: new(widget.Clickable),
PanicBtn: new(widget.Clickable),
CopyInstrumentBtn: new(widget.Clickable),
Menus: make([]Menu, 2),
MenuBar: make([]widget.Clickable, 2),
UnitDragList: &DragList{List: &layout.List{Axis: layout.Vertical}},