-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: preferences.yml for window size #185
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package gioui | ||
|
||
import ( | ||
_ "embed" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
"gopkg.in/yaml.v2" | ||
|
||
"gioui.org/unit" | ||
) | ||
|
||
type ( | ||
Preferences struct { | ||
Window WindowPreferences | ||
YmlError error | ||
} | ||
|
||
WindowPreferences struct { | ||
Width int | ||
Height int | ||
Maximized bool `yaml:",omitempty"` | ||
} | ||
) | ||
|
||
//go:embed preferences.yml | ||
var defaultPreferencesYaml []byte | ||
|
||
func loadDefaultPreferences() Preferences { | ||
var preferences Preferences | ||
err := yaml.Unmarshal(defaultPreferencesYaml, &preferences) | ||
if err != nil { | ||
panic(fmt.Errorf("failed to unmarshal preferences: %w", err)) | ||
} | ||
return preferences | ||
} | ||
|
||
// ReadCustomConfigYml modifies the target argument, i.e. needs a pointer | ||
func ReadCustomConfigYml(filename string, target interface{}) (exists bool, err error) { | ||
configDir, err := os.UserConfigDir() | ||
if err != nil { | ||
return false, err | ||
} | ||
path := filepath.Join(configDir, "sointu", filename) | ||
bytes, err2 := os.ReadFile(path) | ||
if err2 != nil { | ||
return false, err2 | ||
} | ||
err = yaml.Unmarshal(bytes, target) | ||
return true, err | ||
} | ||
|
||
func MakePreferences() Preferences { | ||
preferences := loadDefaultPreferences() | ||
exists, err := ReadCustomConfigYml("preferences.yml", &preferences) | ||
if exists { | ||
preferences.YmlError = err | ||
} | ||
return preferences | ||
} | ||
|
||
func (p Preferences) WindowSize() (unit.Dp, unit.Dp) { | ||
return unit.Dp(p.Window.Width), unit.Dp(p.Window.Height) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
window: | ||
width: 800 | ||
height: 600 | ||
maximized: false |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,6 @@ import ( | |
"gioui.org/op/clip" | ||
"gioui.org/op/paint" | ||
"gioui.org/text" | ||
"gioui.org/unit" | ||
"gioui.org/widget/material" | ||
"gioui.org/x/explorer" | ||
"github.com/vsariola/sointu/tracker" | ||
|
@@ -51,8 +50,9 @@ type ( | |
|
||
filePathString tracker.String | ||
|
||
quitWG sync.WaitGroup | ||
execChan chan func() | ||
quitWG sync.WaitGroup | ||
execChan chan func() | ||
preferences Preferences | ||
|
||
*tracker.Model | ||
} | ||
|
@@ -89,9 +89,16 @@ func NewTracker(model *tracker.Model) *Tracker { | |
Model: model, | ||
|
||
filePathString: model.FilePath().String(), | ||
preferences: MakePreferences(), | ||
} | ||
t.Theme.Shaper = text.NewShaper(text.WithCollection(fontCollection)) | ||
t.PopupAlert = NewPopupAlert(model.Alerts(), t.Theme.Shaper) | ||
if t.preferences.YmlError != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is fine for now. In future, and even for the keybindings, I'm thinking of loading them every time a new tracker is created instead of init(). Because: In the VST, init is called only once, when the DLL is loaded. But the DLL stays loaded even if you close the plugin. So, to make new config take effect, you have to close the entire DAW. |
||
model.Alerts().Add( | ||
fmt.Sprintf("Preferences YML Error: %s", t.preferences.YmlError), | ||
tracker.Warning, | ||
) | ||
} | ||
t.Theme.Palette.Fg = primaryColor | ||
t.Theme.Palette.ContrastFg = black | ||
t.TrackEditor.scrollTable.Focus() | ||
|
@@ -101,9 +108,7 @@ func NewTracker(model *tracker.Model) *Tracker { | |
|
||
func (t *Tracker) Main() { | ||
titleFooter := "" | ||
w := new(app.Window) | ||
w.Option(app.Title("Sointu Tracker")) | ||
w.Option(app.Size(unit.Dp(800), unit.Dp(600))) | ||
w := t.newWindow() | ||
t.InstrumentEditor.Focus() | ||
recoveryTicker := time.NewTicker(time.Second * 30) | ||
t.Explorer = explorer.NewExplorer(w) | ||
|
@@ -127,9 +132,7 @@ func (t *Tracker) Main() { | |
} | ||
if !t.Quitted() { | ||
// TODO: uh oh, there's no way of canceling the destroyevent in gioui? so we create a new window just to show the dialog | ||
w = new(app.Window) | ||
w.Option(app.Title("Sointu Tracker")) | ||
w.Option(app.Size(unit.Dp(800), unit.Dp(600))) | ||
w = t.newWindow() | ||
t.Explorer = explorer.NewExplorer(w) | ||
go eventLoop(w, events, acks) | ||
} | ||
|
@@ -165,6 +168,16 @@ func (t *Tracker) Main() { | |
t.quitWG.Done() | ||
} | ||
|
||
func (t *Tracker) newWindow() *app.Window { | ||
w := new(app.Window) | ||
w.Option(app.Title("Sointu Tracker")) | ||
w.Option(app.Size(t.preferences.WindowSize())) | ||
if t.preferences.Window.Maximized { | ||
w.Option(app.Maximized.Option()) | ||
} | ||
return w | ||
} | ||
|
||
func eventLoop(w *app.Window, events chan<- event.Event, acks <-chan struct{}) { | ||
// Iterate window events, sending each to the old event loop and waiting for | ||
// a signal that processing is complete before iterating again. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: To me, "maximized" means a different concept from fullscreen. Maximized means the window takes maximal amount of space, but keeping the decoration. Fullscreen means the bottom bars and window decorations are gone. So please change this to either "fullscreen" or consider implementing both "fullscreen" and "maximized"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gioui seems to agree: maximized, minimized, windowed and fullscreen are different options: https://github.com/gioui/gio/blob/8daff13af6cdbe4cb689e324f6ba343062dad050/app/window.go#L853
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, yeah, this confuses me. All I ever meant was "Maximized" (and I also see no use for actual Fullscreen), but when I try the gioui options, the app.Fullscreen.Option() that I used and the app.Maximized.Option() give the same effect (i.e. Maximized).
as the app.Fullscreen.Option() gave me what I wanted, I didn't get the idea of looking further; but as no other people really asked for Fullscreen, I would then just use the different Option, even if they look the same for me.