Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
flow3r firmware
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
dos
flow3r firmware
Commits
b809e893
Commit
b809e893
authored
Sep 2, 2023
by
ave
Browse files
Options
Downloads
Patches
Plain Diff
st3m/settings-settings_menu: split up settings more
parent
2b56fb28
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
python_payload/st3m/settings.py
+7
-153
7 additions, 153 deletions
python_payload/st3m/settings.py
python_payload/st3m/settings_menu.py
+140
-2
140 additions, 2 deletions
python_payload/st3m/settings_menu.py
with
147 additions
and
155 deletions
python_payload/st3m/settings.py
+
7
−
153
View file @
b809e893
...
...
@@ -10,7 +10,7 @@ request.
import
json
from
st3m
import
InputState
,
Responder
,
logging
from
st3m
import
logging
from
st3m.goose
import
(
ABCBase
,
abstractmethod
,
...
...
@@ -20,9 +20,7 @@ from st3m.goose import (
Optional
,
Callable
,
)
from
st3m.ui.view
import
ViewManager
from
st3m.utils
import
lerp
,
ease_out_cubic
,
reduce
from
ctx
import
Context
from
st3m.utils
import
reduce
log
=
logging
.
Log
(
__name__
,
level
=
logging
.
INFO
)
...
...
@@ -61,13 +59,6 @@ class Tunable(ABCBase):
"""
...
@abstractmethod
def
get_widget
(
self
)
->
"
TunableWidget
"
:
"""
Widget that will be used to render this setting in menus.
"""
...
@abstractmethod
def
save
(
self
)
->
Dict
[
str
,
Any
]:
"""
...
...
@@ -84,21 +75,6 @@ class Tunable(ABCBase):
...
class
TunableWidget
(
Responder
):
"""
A tunable
'
s widget as rendered in menus.
"""
@abstractmethod
def
press
(
self
,
vm
:
Optional
[
ViewManager
])
->
None
:
"""
Called when the menu item is
'
pressed
'
, ie. selected/activated. A widget
should react to this as the primary way to let the users manipulate the
value of the tunable from a menu.
"""
...
class
UnaryTunable
(
Tunable
):
"""
Basic implementation of a Tunable for single values. Most settings will be
...
...
@@ -165,85 +141,13 @@ class OnOffTunable(UnaryTunable):
def
__init__
(
self
,
name
:
str
,
key
:
str
,
default
:
bool
)
->
None
:
super
().
__init__
(
name
,
key
,
default
)
def
get_widget
(
self
)
->
TunableWidget
:
return
OnOffWidget
(
self
)
def
press
(
self
,
vm
:
Optional
[
ViewManager
])
->
None
:
if
self
.
value
==
True
:
def
press
(
self
,
vm
:
Optional
[
"
ViewManager
"
])
->
None
:
if
self
.
value
is
True
:
self
.
set_value
(
False
)
else
:
self
.
set_value
(
True
)
class
OnOffWidget
(
TunableWidget
):
"""
OnOffWidget is a TunableWidget for OnOffTunables. It renders a slider
switch.
"""
def
__init__
(
self
,
tunable
:
"
OnOffTunable
"
)
->
None
:
self
.
_tunable
=
tunable
# Value from 0 to animation_duration indicating animation progress
# (starts at animation_duration, ends at 0).
self
.
_animating
:
float
=
0
# Last and previous read value from tunable.
self
.
_state
=
tunable
.
value
==
True
self
.
_prev_state
=
self
.
_state
# Value from 0 to 1, representing desired animation position. Linear
# between both. 1 represents rendering _state, 0 represents render the
# opposite of _state.
self
.
_progress
=
1.0
def
think
(
self
,
ins
:
InputState
,
delta_ms
:
int
)
->
None
:
animation_duration
=
0.2
self
.
_state
=
self
.
_tunable
.
value
==
True
if
self
.
_prev_state
!=
self
.
_state
:
# State switched.
# Start new animation, making sure to take into consideration
# whatever animation is already taking place.
self
.
_animating
=
animation_duration
-
self
.
_animating
else
:
# Continue animation.
self
.
_animating
-=
delta_ms
/
1000
if
self
.
_animating
<
0
:
self
.
_animating
=
0
# Calculate progress value.
self
.
_progress
=
1.0
-
(
self
.
_animating
/
animation_duration
)
self
.
_prev_state
=
self
.
_state
def
draw
(
self
,
ctx
:
Context
)
->
None
:
value
=
self
.
_state
v
=
self
.
_progress
v
=
ease_out_cubic
(
v
)
if
not
value
:
v
=
1.0
-
v
ctx
.
rgb
(
lerp
(
0
,
0.4
,
v
),
lerp
(
0
,
0.6
,
v
),
lerp
(
0
,
0.4
,
v
))
ctx
.
round_rectangle
(
0
,
-
10
,
40
,
20
,
5
)
ctx
.
line_width
=
2
ctx
.
fill
()
ctx
.
round_rectangle
(
0
,
-
10
,
40
,
20
,
5
)
ctx
.
line_width
=
2
ctx
.
gray
(
lerp
(
0.3
,
1
,
v
))
ctx
.
stroke
()
ctx
.
gray
(
1
)
ctx
.
round_rectangle
(
lerp
(
2
,
22
,
v
),
-
8
,
16
,
16
,
5
)
ctx
.
fill
()
def
press
(
self
,
vm
:
Optional
[
ViewManager
])
->
None
:
self
.
_tunable
.
set_value
(
not
self
.
_state
)
class
StringTunable
(
UnaryTunable
):
"""
StringTunable is a UnaryTunable that has a string value
...
...
@@ -252,31 +156,7 @@ class StringTunable(UnaryTunable):
def
__init__
(
self
,
name
:
str
,
key
:
str
,
default
:
Optional
[
str
])
->
None
:
super
().
__init__
(
name
,
key
,
default
)
def
get_widget
(
self
)
->
TunableWidget
:
return
StringWidget
(
self
)
def
press
(
self
,
vm
:
Optional
[
ViewManager
])
->
None
:
# Text input not supported at the moment
pass
class
StringWidget
(
TunableWidget
):
"""
StringWidget is a TunableWidget for StringTunables. It renders a string.
"""
def
__init__
(
self
,
tunable
:
StringTunable
)
->
None
:
self
.
_tunable
=
tunable
def
think
(
self
,
ins
:
InputState
,
delta_ms
:
int
)
->
None
:
# Nothing to do here
pass
def
draw
(
self
,
ctx
:
Context
)
->
None
:
ctx
.
text_align
=
ctx
.
LEFT
ctx
.
text
(
str
(
self
.
_tunable
.
value
)
if
self
.
_tunable
.
value
else
""
)
def
press
(
self
,
vm
:
Optional
[
ViewManager
])
->
None
:
def
press
(
self
,
vm
:
Optional
[
"
ViewManager
"
])
->
None
:
# Text input not supported at the moment
pass
...
...
@@ -290,32 +170,7 @@ class ObfuscatedStringTunable(UnaryTunable):
def
__init__
(
self
,
name
:
str
,
key
:
str
,
default
:
Optional
[
str
])
->
None
:
super
().
__init__
(
name
,
key
,
default
)
def
get_widget
(
self
)
->
TunableWidget
:
return
ObfuscatedValueWidget
(
self
)
def
press
(
self
,
vm
:
Optional
[
ViewManager
])
->
None
:
# Text input not supported at the moment
pass
class
ObfuscatedValueWidget
(
TunableWidget
):
"""
ObfuscatedValueWidget is a TunableWidget for UnaryTunables. It renders three asterisks when the tunable contains a truthy value, otherwise nothing.
"""
def
__init__
(
self
,
tunable
:
UnaryTunable
)
->
None
:
self
.
_tunable
=
tunable
def
think
(
self
,
ins
:
InputState
,
delta_ms
:
int
)
->
None
:
# Nothing to do here
pass
def
draw
(
self
,
ctx
:
Context
)
->
None
:
ctx
.
text_align
=
ctx
.
LEFT
if
self
.
_tunable
.
value
:
ctx
.
text
(
"
***
"
)
def
press
(
self
,
vm
:
Optional
[
ViewManager
])
->
None
:
def
press
(
self
,
vm
:
Optional
[
"
ViewManager
"
])
->
None
:
# Text input not supported at the moment
pass
...
...
@@ -353,7 +208,6 @@ def load_all() -> None:
"""
Load all settings from flash.
"""
global
settings_loaded
data
=
{}
try
:
with
open
(
"
/flash/settings.json
"
,
"
r
"
)
as
f
:
...
...
@@ -372,7 +226,7 @@ def _update(d: Dict[str, Any], u: Dict[str, Any]) -> Dict[str, Any]:
Recursive update dictionary.
"""
for
k
,
v
in
u
.
items
():
if
type
(
v
)
==
type
({}
):
if
isinstance
(
v
,
dict
):
d
[
k
]
=
_update
(
d
.
get
(
k
,
{}),
v
)
else
:
d
[
k
]
=
v
...
...
This diff is collapsed.
Click to expand it.
python_payload/st3m/settings_menu.py
+
140
−
2
View file @
b809e893
...
...
@@ -2,7 +2,8 @@
Settings menu of flow3r badge.
"""
from
st3m
import
InputState
,
logging
from
st3m
import
InputState
,
Responder
,
logging
from
st3m.utils
import
lerp
,
ease_out_cubic
from
st3m.goose
import
(
List
,
Tuple
,
...
...
@@ -20,6 +21,143 @@ from ctx import Context
log
=
logging
.
Log
(
__name__
,
level
=
logging
.
INFO
)
class
TunableWidget
(
Responder
):
"""
A tunable
'
s widget as rendered in menus.
"""
@abstractmethod
def
press
(
self
,
vm
:
Optional
[
"
ViewManager
"
])
->
None
:
"""
Called when the menu item is
'
pressed
'
, ie. selected/activated. A widget
should react to this as the primary way to let the users manipulate the
value of the tunable from a menu.
"""
...
class
OnOffWidget
(
TunableWidget
):
"""
OnOffWidget is a TunableWidget for OnOffTunables. It renders a slider
switch.
"""
def
__init__
(
self
,
tunable
:
"
OnOffTunable
"
)
->
None
:
self
.
_tunable
=
tunable
# Value from 0 to animation_duration indicating animation progress
# (starts at animation_duration, ends at 0).
self
.
_animating
:
float
=
0
# Last and previous read value from tunable.
self
.
_state
=
tunable
.
value
is
True
self
.
_prev_state
=
self
.
_state
# Value from 0 to 1, representing desired animation position. Linear
# between both. 1 represents rendering _state, 0 represents render the
# opposite of _state.
self
.
_progress
=
1.0
def
think
(
self
,
ins
:
InputState
,
delta_ms
:
int
)
->
None
:
animation_duration
=
0.2
self
.
_state
=
self
.
_tunable
.
value
is
True
if
self
.
_prev_state
!=
self
.
_state
:
# State switched.
# Start new animation, making sure to take into consideration
# whatever animation is already taking place.
self
.
_animating
=
animation_duration
-
self
.
_animating
else
:
# Continue animation.
self
.
_animating
-=
delta_ms
/
1000
if
self
.
_animating
<
0
:
self
.
_animating
=
0
# Calculate progress value.
self
.
_progress
=
1.0
-
(
self
.
_animating
/
animation_duration
)
self
.
_prev_state
=
self
.
_state
def
draw
(
self
,
ctx
:
Context
)
->
None
:
value
=
self
.
_state
v
=
self
.
_progress
v
=
ease_out_cubic
(
v
)
if
not
value
:
v
=
1.0
-
v
ctx
.
rgb
(
lerp
(
0
,
0.4
,
v
),
lerp
(
0
,
0.6
,
v
),
lerp
(
0
,
0.4
,
v
))
ctx
.
round_rectangle
(
0
,
-
10
,
40
,
20
,
5
)
ctx
.
line_width
=
2
ctx
.
fill
()
ctx
.
round_rectangle
(
0
,
-
10
,
40
,
20
,
5
)
ctx
.
line_width
=
2
ctx
.
gray
(
lerp
(
0.3
,
1
,
v
))
ctx
.
stroke
()
ctx
.
gray
(
1
)
ctx
.
round_rectangle
(
lerp
(
2
,
22
,
v
),
-
8
,
16
,
16
,
5
)
ctx
.
fill
()
def
press
(
self
,
vm
:
Optional
[
"
ViewManager
"
])
->
None
:
self
.
_tunable
.
set_value
(
not
self
.
_state
)
class
StringWidget
(
TunableWidget
):
"""
StringWidget is a TunableWidget for StringTunables. It renders a string.
"""
def
__init__
(
self
,
tunable
:
StringTunable
)
->
None
:
self
.
_tunable
=
tunable
def
think
(
self
,
ins
:
InputState
,
delta_ms
:
int
)
->
None
:
# Nothing to do here
pass
def
draw
(
self
,
ctx
:
Context
)
->
None
:
ctx
.
text_align
=
ctx
.
LEFT
ctx
.
text
(
str
(
self
.
_tunable
.
value
)
if
self
.
_tunable
.
value
else
""
)
def
press
(
self
,
vm
:
Optional
[
"
ViewManager
"
])
->
None
:
# Text input not supported at the moment
pass
class
ObfuscatedValueWidget
(
TunableWidget
):
"""
ObfuscatedValueWidget is a TunableWidget for UnaryTunables. It renders three asterisks when the tunable contains a truthy value, otherwise nothing.
"""
def
__init__
(
self
,
tunable
:
UnaryTunable
)
->
None
:
self
.
_tunable
=
tunable
def
think
(
self
,
ins
:
InputState
,
delta_ms
:
int
)
->
None
:
# Nothing to do here
pass
def
draw
(
self
,
ctx
:
Context
)
->
None
:
ctx
.
text_align
=
ctx
.
LEFT
if
self
.
_tunable
.
value
:
ctx
.
text
(
(
"
*
"
*
len
(
str
(
self
.
_tunable
.
value
)))
if
self
.
_tunable
.
value
else
""
)
def
press
(
self
,
vm
:
Optional
[
"
ViewManager
"
])
->
None
:
# Text input not supported at the moment
pass
tunable_widget_map
=
{
Tunable
:
TunableWidget
,
OnOffTunable
:
OnOffWidget
,
StringTunable
:
StringWidget
,
ObfuscatedStringTunable
:
ObfuscatedValueWidget
,
}
class
SettingsMenuItem
(
MenuItem
):
"""
A MenuItem which draws its label offset to the left, and a Tunable
'
s widget
...
...
@@ -28,7 +166,7 @@ class SettingsMenuItem(MenuItem):
def
__init__
(
self
,
tunable
:
UnaryTunable
):
self
.
tunable
=
tunable
self
.
widget
=
tunable
.
get_widget
(
)
self
.
widget
=
tunable
_widget_map
.
get
(
type
(
tunable
),
TunableWidget
)(
tunable
)
def
press
(
self
,
vm
:
Optional
[
ViewManager
])
->
None
:
self
.
widget
.
press
(
vm
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment