Application specific preferences saving now enabled.
This commit is contained in:
1 parent
f88e5b81a2
commit
60abcc37d9
23 files changed
+1004
-248
No files matched your search
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package preferences
|
||||
|
||||
import (
|
||||
"git.stormux.org/storm/fenrir/internal/config"
|
||||
"git.stormux.org/storm/fenrir/internal/interaction"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestApplicationSettingsOnlyExposeRestorableControls(t *testing.T) {
|
||||
base := config.Defaults()
|
||||
session, err := New_application_session(base, nil, "Ninjam application settings")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
values := session.Values()
|
||||
for _, path := range []string{"presentation.speech.driver", "presentation.sound.theme", "keyboard.layout", "keyboard.devices", "reading.punctuation_profile", "clipboard.persistent"} {
|
||||
if _, exists := values[path]; exists {
|
||||
t.Fatal("startup/global control exposed", path)
|
||||
}
|
||||
}
|
||||
if _, exists := values["presentation.speech.voice"]; !exists {
|
||||
t.Fatal("voice control missing")
|
||||
}
|
||||
session.Handle(interaction.Key{Name: "tab"})
|
||||
session.Handle(interaction.Key{Name: "tab"})
|
||||
session.Handle(interaction.Key{Name: "up"})
|
||||
saved, err := Application_settings(session, base)
|
||||
if err != nil || saved.Presentation.Speech.Rate != base.Presentation.Speech.Rate+1 || saved.Keyboard.Layout != base.Keyboard.Layout {
|
||||
t.Fatal(saved, err)
|
||||
}
|
||||
}
|
||||
@@ -119,6 +119,9 @@ func (d Discovery) Refresh_speech(session *interaction.Session, previous *config
|
||||
"presentation.speech.voice": &next.Presentation.Speech.Voice,
|
||||
} {
|
||||
control, ok := values[path]
|
||||
if !ok && path == "presentation.speech.driver" {
|
||||
continue
|
||||
}
|
||||
if !ok || control.Selected < 0 || control.Selected >= len(control.Choices) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -38,10 +38,18 @@ type Choices map[string][]config.Choice
|
||||
const MenuTitle = "Fenrir Menu"
|
||||
|
||||
func New_session(settings config.Settings, order []string, discovered ...Choices) (*interaction.Session, error) {
|
||||
return new_session(settings, order, MenuTitle, false, discovered...)
|
||||
}
|
||||
|
||||
func New_application_session(settings config.Settings, order []string, title string, discovered ...Choices) (*interaction.Session, error) {
|
||||
return new_session(settings, order, title, true, discovered...)
|
||||
}
|
||||
|
||||
func new_session(settings config.Settings, order []string, title string, application bool, discovered ...Choices) (*interaction.Session, error) {
|
||||
if err := settings.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
form := interaction.Form{Type: interaction.TabForm, Title: MenuTitle}
|
||||
form := interaction.Form{Type: interaction.TabForm, Title: title}
|
||||
for _, section := range config.Ordered_sections(config.Sections(), order) {
|
||||
if section.Label == "" {
|
||||
continue
|
||||
@@ -50,6 +58,9 @@ func New_session(settings config.Settings, order []string, discovered ...Choices
|
||||
var append_section func(config.Section, string) error
|
||||
append_section = func(section config.Section, group string) error {
|
||||
for _, definition := range section.Settings {
|
||||
if application && !config.Application_setting(definition.Path) {
|
||||
continue
|
||||
}
|
||||
control, err := make_control(definition, settings, discovered)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -76,6 +87,9 @@ func New_session(settings config.Settings, order []string, discovered ...Choices
|
||||
if err := append_section(section, ""); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(tab.Controls) == 0 {
|
||||
continue
|
||||
}
|
||||
tab.Controls = append(tab.Controls, interaction.Control{ID: "ok", Label: "OK", Kind: interaction.Button, Action: "save"}, interaction.Control{ID: "cancel", Label: "Cancel", Kind: interaction.Button, Action: "cancel"})
|
||||
form.Tabs = append(form.Tabs, tab)
|
||||
}
|
||||
@@ -137,15 +151,25 @@ func make_control(definition config.Definition, settings config.Settings, discov
|
||||
}
|
||||
|
||||
func Settings(session *interaction.Session, base config.Settings) (config.Settings, error) {
|
||||
return settings_values(session, base, false)
|
||||
}
|
||||
|
||||
func Application_settings(session *interaction.Session, base config.Settings) (config.Settings, error) {
|
||||
return settings_values(session, base, true)
|
||||
}
|
||||
|
||||
func settings_values(session *interaction.Session, base config.Settings, application bool) (config.Settings, error) {
|
||||
values := session.Values()
|
||||
// Visibility follows the form's selected driver, including unsaved switches.
|
||||
driver := values["presentation.speech.driver"]
|
||||
if driver.Selected < 0 || driver.Selected >= len(driver.Choices) {
|
||||
driver, hasDriver := values["presentation.speech.driver"]
|
||||
if (!application && !hasDriver) || (hasDriver && (driver.Selected < 0 || driver.Selected >= len(driver.Choices))) {
|
||||
return config.Settings{}, fmt.Errorf("invalid speech driver selection")
|
||||
}
|
||||
base.Presentation.Speech.Driver = driver.Choices[driver.Selected].ID
|
||||
if hasDriver {
|
||||
base.Presentation.Speech.Driver = driver.Choices[driver.Selected].ID
|
||||
}
|
||||
for _, definition := range config.Definitions() {
|
||||
if !definition.Available(base) {
|
||||
if !definition.Available(base) || (application && !config.Application_setting(definition.Path)) {
|
||||
continue
|
||||
}
|
||||
control, ok := values[definition.Path]
|
||||
|
||||
Reference in new issue
Block a user