mirror of
https://github.com/vsariola/sointu.git
synced 2025-06-04 01:28:45 -04:00
feat(tracker): implement saving and loading a song file
This commit is contained in:
parent
5e76fabf21
commit
8b666064b2
51
tracker/files.go
Normal file
51
tracker/files.go
Normal 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)
|
||||||
|
}
|
@ -20,6 +20,8 @@ import (
|
|||||||
var upIcon *widget.Icon
|
var upIcon *widget.Icon
|
||||||
var downIcon *widget.Icon
|
var downIcon *widget.Icon
|
||||||
var addIcon *widget.Icon
|
var addIcon *widget.Icon
|
||||||
|
var loadIcon *widget.Icon
|
||||||
|
var saveIcon *widget.Icon
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var err error
|
var err error
|
||||||
@ -35,6 +37,14 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
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 {
|
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,
|
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
||||||
layout.Rigid(t.layoutPatterns(
|
layout.Rigid(t.layoutPatterns(
|
||||||
t.song.Tracks,
|
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)
|
iconBtn := enableButton(material.IconButton(t.Theme, t.NewInstrumentBtn, addIcon), t.song.Patch.TotalVoices() < 32)
|
||||||
return in.Layout(gtx, iconBtn.Layout)
|
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)
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ type Tracker struct {
|
|||||||
BPMDownBtn *widget.Clickable
|
BPMDownBtn *widget.Clickable
|
||||||
NewTrackBtn *widget.Clickable
|
NewTrackBtn *widget.Clickable
|
||||||
NewInstrumentBtn *widget.Clickable
|
NewInstrumentBtn *widget.Clickable
|
||||||
|
LoadSongFileBtn *widget.Clickable
|
||||||
|
SaveSongFileBtn *widget.Clickable
|
||||||
ParameterSliders []*widget.Float
|
ParameterSliders []*widget.Float
|
||||||
UnitBtns []*widget.Clickable
|
UnitBtns []*widget.Clickable
|
||||||
InstrumentBtns []*widget.Clickable
|
InstrumentBtns []*widget.Clickable
|
||||||
@ -263,6 +265,8 @@ func New(audioContext sointu.AudioContext) *Tracker {
|
|||||||
BPMDownBtn: new(widget.Clickable),
|
BPMDownBtn: new(widget.Clickable),
|
||||||
NewTrackBtn: new(widget.Clickable),
|
NewTrackBtn: new(widget.Clickable),
|
||||||
NewInstrumentBtn: new(widget.Clickable),
|
NewInstrumentBtn: new(widget.Clickable),
|
||||||
|
LoadSongFileBtn: new(widget.Clickable),
|
||||||
|
SaveSongFileBtn: 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