feat(tracker): show * next to the file path to indicate unsaved changes

Related to #224.
This commit is contained in:
5684185+vsariola@users.noreply.github.com
2026-03-06 15:01:30 +02:00
parent 4cb9308af3
commit c52c074aa1
2 changed files with 19 additions and 7 deletions

View File

@ -7,6 +7,7 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings"
"time" "time"
"gioui.org/app" "gioui.org/app"
@ -122,11 +123,12 @@ func (t *Tracker) Main() {
recoveryTicker := time.NewTicker(time.Second * 30) recoveryTicker := time.NewTicker(time.Second * 30)
var ops op.Ops var ops op.Ops
titlePath := "" titlePath := ""
changedSinceSave := false
globals := make(map[string]any, 1) globals := make(map[string]any, 1)
globals["Tracker"] = t globals["Tracker"] = t
for !t.Quitted() { for !t.Quitted() {
w := t.newWindow() w := t.newWindow()
w.Option(app.Title(titleFromPath(titlePath))) w.Option(app.Title(titleFromPath(titlePath, changedSinceSave)))
t.Explorer = explorer.NewExplorer(w) t.Explorer = explorer.NewExplorer(w)
acks := make(chan struct{}) acks := make(chan struct{})
events := make(chan event.Event) events := make(chan event.Event)
@ -171,9 +173,10 @@ func (t *Tracker) Main() {
acks <- struct{}{} acks <- struct{}{}
break F // this window is done, we need to create a new one break F // this window is done, we need to create a new one
case app.FrameEvent: case app.FrameEvent:
if titlePath != t.filePathString.Value() { if titlePath != t.filePathString.Value() || changedSinceSave != t.Song().ChangedSinceSave() {
titlePath = t.filePathString.Value() titlePath = t.filePathString.Value()
w.Option(app.Title(titleFromPath(titlePath))) changedSinceSave = t.Song().ChangedSinceSave()
w.Option(app.Title(titleFromPath(titlePath, changedSinceSave)))
} }
gtx := app.NewContext(&ops, e) gtx := app.NewContext(&ops, e)
gtx.Values = globals gtx.Values = globals
@ -211,11 +214,17 @@ func (t *Tracker) newWindow() *app.Window {
return w return w
} }
func titleFromPath(path string) string { func titleFromPath(path string, unsaved bool) string {
if path == "" { var sb strings.Builder
return "Sointu Tracker" sb.WriteString("Sointu Tracker")
if path != "" {
sb.WriteString(" - ")
sb.WriteString(path)
} }
return fmt.Sprintf("Sointu Tracker - %s", path) if unsaved {
sb.WriteString(" *")
}
return sb.String()
} }
func (t *Tracker) Layout(gtx layout.Context) { func (t *Tracker) Layout(gtx layout.Context) {

View File

@ -19,6 +19,9 @@ func (m *Model) Song() *SongModel { return (*SongModel)(m) }
type SongModel Model type SongModel Model
// ChangesSinceSave returns a Bool representing whether the current song has unsaved
func (m *SongModel) ChangedSinceSave() bool { return m.d.ChangedSinceSave }
// FilePath returns a String representing the file path of the current song. // FilePath returns a String representing the file path of the current song.
func (m *SongModel) FilePath() String { return MakeString((*songFilePath)(m)) } func (m *SongModel) FilePath() String { return MakeString((*songFilePath)(m)) }