For speech rate in settings up/down move by 10, left/right move by 1. Easier to get settings right without having to hold doown the arrow keys lol.
This commit is contained in:
1 parent
ea5d26f56d
commit
088f706cb4
13 files changed
+81
-10
No files matched your search
@@ -144,6 +144,7 @@ Space toggles checkboxes; arrows change selections and numeric values. Activate
|
||||
|
||||
The menu includes speech, sound, reading, keyboard, clipboard, and other
|
||||
settings. Speech rate, pitch, and volume use a scale from -100 to 100.
|
||||
For speech rate, Up and Down change the value by 10; Left and Right change it by 1.
|
||||
Backend, device, keyboard layout, sound theme, and other launch-only changes
|
||||
take effect the next time Fenrir starts.
|
||||
|
||||
|
||||
@@ -239,6 +239,7 @@ Activate \f[B]OK\f[R] to save, or \f[B]Cancel\f[R] or Escape to discard
|
||||
the form\(cqs changes.
|
||||
.PP
|
||||
Speech rate, pitch, and volume use a scale from \-100 to 100.
|
||||
For speech rate, Up and Down change the value by 10; Left and Right change it by 1.
|
||||
Sound volume is between 0.0 and 1.0.
|
||||
Backend, device, keyboard layout, sound theme, and other launch\-only
|
||||
settings take effect on the next start.
|
||||
|
||||
+2
-1
@@ -164,7 +164,8 @@ options. The form captures its navigation keys until it closes.
|
||||
* Activate *OK* to save, or *Cancel* or Escape to discard the form’s
|
||||
changes.
|
||||
|
||||
Speech rate, pitch, and volume use a scale from -100 to 100. Sound
|
||||
Speech rate, pitch, and volume use a scale from -100 to 100. For speech
|
||||
rate, Up and Down change the value by 10; Left and Right change it by 1. Sound
|
||||
volume is between 0.0 and 1.0. Backend, device, keyboard layout, sound
|
||||
theme, and other launch-only settings take effect on the next start.
|
||||
|
||||
|
||||
+2
-1
@@ -233,7 +233,8 @@ The form captures its navigation keys until it closes.
|
||||
- Arrows change list selections and numeric values.
|
||||
- Activate **OK** to save, or **Cancel** or Escape to discard the form's changes.
|
||||
|
||||
Speech rate, pitch, and volume use a scale from -100 to 100. Sound volume is
|
||||
Speech rate, pitch, and volume use a scale from -100 to 100. For speech rate,
|
||||
Up and Down change the value by 10; Left and Right change it by 1. Sound volume is
|
||||
between 0.0 and 1.0. Backend, device, keyboard layout, sound theme, and other
|
||||
launch-only settings take effect on the next start.
|
||||
|
||||
|
||||
+2
-1
@@ -156,7 +156,8 @@ options. The form captures its navigation keys until it closes.
|
||||
- Activate OK to save, or Cancel or Escape to discard the form’s
|
||||
changes.
|
||||
|
||||
Speech rate, pitch, and volume use a scale from -100 to 100. Sound
|
||||
Speech rate, pitch, and volume use a scale from -100 to 100. For speech
|
||||
rate, Up and Down change the value by 10; Left and Right change it by 1. Sound
|
||||
volume is between 0.0 and 1.0. Backend, device, keyboard layout, sound
|
||||
theme, and other launch-only settings take effect on the next start.
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ func TestSettingsMenuCancelSaveAndReopen(t *testing.T) {
|
||||
settings, _, err := config.Load(path, nil)
|
||||
want := 40
|
||||
if action == "save" {
|
||||
want = 41
|
||||
want = 50
|
||||
}
|
||||
if err != nil || settings.Presentation.Speech.Rate != want {
|
||||
t.Fatal("wrong persistence", settings, err)
|
||||
|
||||
@@ -20,7 +20,7 @@ func admit_menu_save(t *testing.T, a *application) {
|
||||
receive_ui(t, a.ui)
|
||||
a.ui.handle(interaction.Key{Name: "tab"})
|
||||
a.ui.handle(interaction.Key{Name: "tab"})
|
||||
a.ui.handle(interaction.Key{Name: "up"}) // Rate 24 -> 25.
|
||||
a.ui.handle(interaction.Key{Name: "right"}) // Rate 24 -> 25.
|
||||
a.ui.action("save", a.ui.session)
|
||||
if !a.saver.busy || a.ui.session != nil {
|
||||
t.Fatal("menu save was not admitted")
|
||||
|
||||
@@ -37,6 +37,7 @@ type Control struct {
|
||||
Checked bool
|
||||
Number float64
|
||||
Min, Max, Step float64
|
||||
UpDownStep float64 // Zero uses the default step of 1 for Up and Down.
|
||||
Text string
|
||||
Items []string
|
||||
Selected int
|
||||
|
||||
@@ -54,6 +54,14 @@ func New_session(form Form) (*Session, error) {
|
||||
return nil, fmt.Errorf("invalid control %q", control.ID)
|
||||
}
|
||||
controlIDs[control.ID] = true
|
||||
if control.Kind == Number {
|
||||
if control.UpDownStep == 0 {
|
||||
control.UpDownStep = 1
|
||||
}
|
||||
if math.IsNaN(control.UpDownStep) || math.IsInf(control.UpDownStep, 0) || control.UpDownStep < 0 {
|
||||
return nil, fmt.Errorf("invalid vertical step %q", control.ID)
|
||||
}
|
||||
}
|
||||
if control.Kind == Number && (math.IsNaN(control.Number) || math.IsInf(control.Number, 0) || math.IsNaN(control.Min) || math.IsInf(control.Min, 0) || math.IsNaN(control.Max) || math.IsInf(control.Max, 0) || math.IsNaN(control.Step) || math.IsInf(control.Step, 0) || control.Min > control.Max || control.Step <= 0 || control.Number < control.Min || control.Number > control.Max) {
|
||||
return nil, fmt.Errorf("invalid range %q", control.ID)
|
||||
}
|
||||
@@ -244,9 +252,9 @@ func (s *Session) Handle(key Key) Result {
|
||||
delta := 0.0
|
||||
switch key.Name {
|
||||
case "up":
|
||||
delta = 1
|
||||
delta = control.UpDownStep
|
||||
case "down":
|
||||
delta = -1
|
||||
delta = -control.UpDownStep
|
||||
case "right":
|
||||
delta = control.Step
|
||||
case "left":
|
||||
|
||||
@@ -17,7 +17,20 @@
|
||||
|
||||
package interaction
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInvalidNumberUpDownStepRejected(t *testing.T) {
|
||||
for _, step := range []float64{-1, math.NaN(), math.Inf(1), math.Inf(-1)} {
|
||||
form := test_form()
|
||||
form.Tabs[0].Controls[1].UpDownStep = step
|
||||
if _, err := New_session(form); err == nil {
|
||||
t.Fatalf("invalid Up/Down step %v accepted", step)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func test_form() Form {
|
||||
return Form{Type: TabForm, Title: "Settings", Tabs: []Tab{
|
||||
|
||||
@@ -28,7 +28,7 @@ func TestApplicationSettingsOnlyExposeRestorableControls(t *testing.T) {
|
||||
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 {
|
||||
if err != nil || saved.Presentation.Speech.Rate != base.Presentation.Speech.Rate+10 || saved.Keyboard.Layout != base.Keyboard.Layout {
|
||||
t.Fatal(saved, err)
|
||||
}
|
||||
}
|
||||
@@ -132,6 +132,9 @@ func make_control(definition config.Definition, settings config.Settings, discov
|
||||
control.Number = value.(float64)
|
||||
}
|
||||
control.Min, control.Max, control.Step = definition.Min, definition.Max, definition.Step
|
||||
if definition.Path == "presentation.speech.rate" {
|
||||
control.UpDownStep = 10
|
||||
}
|
||||
case reflect.String:
|
||||
control.Kind, control.Text = interaction.Entry, value.(string)
|
||||
case reflect.Slice:
|
||||
|
||||
@@ -19,6 +19,7 @@ package preferences
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -52,11 +53,51 @@ func TestSettingsFormCoversSchemaAndReturnsIsolatedDraft(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if draft.Presentation.Speech.Enabled || draft.Presentation.Speech.Rate != 1 || !base.Presentation.Speech.Enabled || base.Presentation.Speech.Rate != 0 {
|
||||
if draft.Presentation.Speech.Enabled || draft.Presentation.Speech.Rate != 10 || !base.Presentation.Speech.Enabled || base.Presentation.Speech.Rate != 0 {
|
||||
t.Fatal("draft isolation", draft, base)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpeechRateArrowSteps(t *testing.T) {
|
||||
for _, application := range []bool{false, true} {
|
||||
for _, trial := range []struct {
|
||||
start int
|
||||
key string
|
||||
want int
|
||||
}{
|
||||
{-3, "up", 7}, {-3, "down", -13},
|
||||
{-3, "right", -2}, {-3, "left", -4},
|
||||
{96, "up", 100}, {-96, "down", -100},
|
||||
{100, "up", 100}, {-100, "down", -100},
|
||||
{100, "right", 100}, {-100, "left", -100},
|
||||
{100, "down", 90}, {-100, "up", -90},
|
||||
{100, "left", 99}, {-100, "right", -99},
|
||||
} {
|
||||
base := config.Defaults()
|
||||
base.Presentation.Speech.Rate = trial.start
|
||||
session, err := new_session(base, []string{"presentation"}, MenuTitle, application)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
session.Handle(interaction.Key{Name: "tab"}) // Speech enabled.
|
||||
session.Handle(interaction.Key{Name: "tab"}) // Rate.
|
||||
result := session.Handle(interaction.Key{Name: trial.key})
|
||||
if want := "Rate " + strconv.Itoa(trial.want); result.Speech != want {
|
||||
t.Fatalf("application=%v, rate=%d, key=%s: speech=%q, want %q", application, trial.start, trial.key, result.Speech, want)
|
||||
}
|
||||
var draft config.Settings
|
||||
if application {
|
||||
draft, err = Application_settings(session, base)
|
||||
} else {
|
||||
draft, err = Settings(session, base)
|
||||
}
|
||||
if err != nil || draft.Presentation.Speech.Rate != trial.want || base.Presentation.Speech.Rate != trial.start {
|
||||
t.Fatalf("application=%v, trial=%+v: draft rate=%d, base rate=%d, err=%v", application, trial, draft.Presentation.Speech.Rate, base.Presentation.Speech.Rate, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadingModeIsConstrainedAndSavedInDraft(t *testing.T) {
|
||||
base := config.Defaults()
|
||||
session, err := New_session(base, []string{"reading"})
|
||||
|
||||
Reference in new issue
Block a user