From 09a9f072cc2c250350ffc18519060ae741044b8e Mon Sep 17 00:00:00 2001 From: vsariola <5684185+vsariola@users.noreply.github.com> Date: Tue, 16 Feb 2021 21:43:39 +0200 Subject: [PATCH] feat(tracker): copy instrument to & paste from clipboard Closes #25 --- tracker/instruments.go | 14 ++++++++++++++ tracker/run.go | 2 +- tracker/tracker.go | 25 ++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/tracker/instruments.go b/tracker/instruments.go index 8838c61..53197e0 100644 --- a/tracker/instruments.go +++ b/tracker/instruments.go @@ -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() } diff --git a/tracker/run.go b/tracker/run.go index eb895fe..c12ea39 100644 --- a/tracker/run.go +++ b/tracker/run.go @@ -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() } diff --git a/tracker/tracker.go b/tracker/tracker.go index ec2bdf5..22e1345 100644 --- a/tracker/tracker.go +++ b/tracker/tracker.go @@ -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}},