feat(tracker): implement saving and loading a song file

This commit is contained in:
vsariola 2021-01-10 17:20:42 +02:00
parent 5e76fabf21
commit 8b666064b2
3 changed files with 81 additions and 0 deletions

51
tracker/files.go Normal file
View File

@ -0,0 +1,51 @@
package tracker
import (
"encoding/json"
"io/ioutil"
"path/filepath"
"gopkg.in/yaml.v3"
"github.com/sqweek/dialog"
"github.com/vsariola/sointu"
)
func (t *Tracker) LoadSongFile() {
filename, err := dialog.File().Filter("Sointu YAML song", "yml").Filter("Sointu JSON song", "json").Title("Load song").Load()
if err != nil {
return
}
bytes, err := ioutil.ReadFile(filename)
if err != nil {
return
}
var song sointu.Song
if errJSON := json.Unmarshal(bytes, &song); errJSON != nil {
if errYaml := yaml.Unmarshal(bytes, &song); errYaml != nil {
return
}
}
t.LoadSong(song)
}
func (t *Tracker) SaveSongFile() {
filename, err := dialog.File().Filter("Sointu YAML song", "yml").Filter("Sointu JSON song", "json").Title("Save song").Save()
if err != nil {
return
}
var extension = filepath.Ext(filename)
var contents []byte
if extension == "json" {
contents, err = json.Marshal(t.song)
} else {
contents, err = yaml.Marshal(t.song)
}
if err != nil {
return
}
if extension == "" {
filename = filename + ".yml"
}
ioutil.WriteFile(filename, contents, 0644)
}

View File

@ -20,6 +20,8 @@ import (
var upIcon *widget.Icon
var downIcon *widget.Icon
var addIcon *widget.Icon
var loadIcon *widget.Icon
var saveIcon *widget.Icon
func init() {
var err error
@ -35,6 +37,14 @@ func init() {
if err != nil {
log.Fatal(err)
}
loadIcon, err = widget.NewIcon(icons.FileFolder)
if err != nil {
log.Fatal(err)
}
saveIcon, err = widget.NewIcon(icons.ContentSave)
if err != nil {
log.Fatal(err)
}
}
func smallButton(icStyle material.IconButtonStyle) material.IconButtonStyle {
@ -170,6 +180,14 @@ func (t *Tracker) layoutControls(gtx layout.Context) layout.Dimensions {
}
}()
for t.LoadSongFileBtn.Clicked() {
t.LoadSongFile()
}
for t.SaveSongFileBtn.Clicked() {
t.SaveSongFile()
}
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
layout.Rigid(t.layoutPatterns(
t.song.Tracks,
@ -190,6 +208,14 @@ func (t *Tracker) layoutControls(gtx layout.Context) layout.Dimensions {
iconBtn := enableButton(material.IconButton(t.Theme, t.NewInstrumentBtn, addIcon), t.song.Patch.TotalVoices() < 32)
return in.Layout(gtx, iconBtn.Layout)
}),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
iconBtn := material.IconButton(t.Theme, t.LoadSongFileBtn, loadIcon)
return in.Layout(gtx, iconBtn.Layout)
}),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
iconBtn := material.IconButton(t.Theme, t.SaveSongFileBtn, saveIcon)
return in.Layout(gtx, iconBtn.Layout)
}),
)
}

View File

@ -36,6 +36,8 @@ type Tracker struct {
BPMDownBtn *widget.Clickable
NewTrackBtn *widget.Clickable
NewInstrumentBtn *widget.Clickable
LoadSongFileBtn *widget.Clickable
SaveSongFileBtn *widget.Clickable
ParameterSliders []*widget.Float
UnitBtns []*widget.Clickable
InstrumentBtns []*widget.Clickable
@ -263,6 +265,8 @@ func New(audioContext sointu.AudioContext) *Tracker {
BPMDownBtn: new(widget.Clickable),
NewTrackBtn: new(widget.Clickable),
NewInstrumentBtn: new(widget.Clickable),
LoadSongFileBtn: new(widget.Clickable),
SaveSongFileBtn: new(widget.Clickable),
setPlaying: make(chan bool),
rowJump: make(chan int),
patternJump: make(chan int),