Skip to content

Commit 39114d2

Browse files
committed
fix spinner changes
the previous change to fix spinners broke this one :/ `.Value` is some sort of common getter, but it's invalid when trying to get on the next tick. it forwards to `.mValue` or `.mChoice` - so we now check each
1 parent c727aff commit 39114d2

File tree

2 files changed

+68
-35
lines changed

2 files changed

+68
-35
lines changed

src/willow1_mod_menu/options.py

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ def get_selected_idx(menu: WillowGFxMenu) -> int | None:
191191
return None
192192

193193

194-
slider_spinner_next_tick_info: tuple[WeakPointer, str, Populator, int] | None = None
194+
slider_next_tick_info: tuple[WeakPointer, str, Populator, int] | None = None
195195

196196

197197
# Similarly to the lobby menu, we need to use sounds to detect when you click an option/adjust a
@@ -217,42 +217,52 @@ def play_sound(
217217
populator.on_activate(obj, idx)
218218
return
219219

220+
# The same sound is used for both sliders and spinners.
221+
# This variable is only defined on spinners, so should be NaN if we've selected a slider.
222+
choice: float = obj.GetVariableNumber((focused := find_focused_item(obj)) + ".mChoice")
223+
if math.isfinite(choice):
224+
# It's a spinner
225+
populator.on_spinner_change(obj, idx, int(choice))
226+
return
227+
228+
# It's a slider.
220229
# Sliders have the same problem as in the lobby movie, for kb input they plays the sound after
221230
# updating the value, and we could run our callbacks here, but for mouse input they play the
222-
# sound before. Wait for next tick before updating.
231+
# sound before.
232+
# Save a bunch of data we already have, then wait for next tick.
223233

224-
# Save a bunch of data we already have
225-
global slider_spinner_next_tick_info
226-
slider_spinner_next_tick_info = (
234+
global slider_next_tick_info
235+
slider_next_tick_info = (
227236
WeakPointer(obj),
228-
find_focused_item(obj) + ".mValue",
237+
focused + ".mValue",
229238
populator,
230239
idx,
231240
)
232241

233-
slider_spinner_next_tick.enable()
242+
slider_next_tick.enable()
234243

235244

236245
@hook("WillowGame.WillowUIInteraction:TickImp")
237-
def slider_spinner_next_tick(*_: Any) -> None:
238-
slider_spinner_next_tick.disable()
246+
def slider_next_tick(*_: Any) -> None:
247+
slider_next_tick.disable()
239248

240-
global slider_spinner_next_tick_info
241-
if slider_spinner_next_tick_info is None:
249+
global slider_next_tick_info
250+
if slider_next_tick_info is None:
242251
return
243-
weak_menu, path, populator, idx = slider_spinner_next_tick_info
244-
slider_spinner_next_tick_info = None
252+
weak_menu, path, populator, idx = slider_next_tick_info
253+
slider_next_tick_info = None
245254

246255
if (menu := weak_menu()) is None:
247256
return
248257
value = menu.GetVariableNumber(path)
249258

250-
if math.isnan(value):
251-
# We really don't want to set an option's value to NaN since it becomes essentially
252-
# unrecoverable without manually editing settings
253-
logging.error("Got NaN after changing spinner/slide!")
259+
if not math.isfinite(value):
260+
# If something's become invalid, we'll have gotten a NaN back. We really don't want to set
261+
# an option's value to NaN or inf, since it becomes essentially unrecoverable without
262+
# manually editing settings
263+
logging.error(f"Got {value} after changing spinner/slider!")
254264
else:
255-
populator.on_slider_spinner_change(menu, idx, value)
265+
populator.on_slider_change(menu, idx, value)
256266

257267

258268
@hook("WillowGame.WillowGFxMenuScreenGeneric:Screen_Deactivate", immediately_enable=True)

src/willow1_mod_menu/populators/__init__.py

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,14 @@ def on_activate(self, menu: WillowGFxMenu, idx: int) -> None:
182182

183183
self.handle_activate(menu, option)
184184

185-
def on_slider_spinner_change(self, menu: WillowGFxMenu, idx: int, value: float) -> None:
185+
def on_spinner_change(self, menu: WillowGFxMenu, idx: int, choice_idx: int) -> None:
186186
"""
187-
Handles a raw slider or spinner change event.
187+
Handles a raw spinner change.
188188
189189
Args:
190190
menu: The currently open menu.
191191
idx: The index of the item which was activated.
192-
value: The option's new value.
192+
choice_idx: The newly selected choice's index.
193193
"""
194194
_ = menu
195195
try:
@@ -200,25 +200,48 @@ def on_slider_spinner_change(self, menu: WillowGFxMenu, idx: int, value: float)
200200

201201
match option:
202202
case BoolOption():
203-
option.value = bool(value)
203+
option.value = bool(choice_idx)
204204
case DropdownOption() | SpinnerOption():
205-
option.value = option.choices[int(value)]
206-
case SliderOption():
207-
if option.is_integer:
208-
value = round(value)
209-
option.value = value
210-
211-
menu.SetVariableString(
212-
find_focused_item(menu) + ".mLabel.text",
213-
self.format_slider_label(option),
214-
)
215-
205+
option.value = option.choices[choice_idx]
216206
case _:
217207
logging.error(
218-
f"Option '{option.identifier}' of unknown type {type(option)} unexpectedly got"
219-
f" a slider/spinner change event",
208+
f"Option '{option.identifier}' got a spinner change event despite not being a"
209+
" spinner",
220210
)
221211

212+
def on_slider_change(self, menu: WillowGFxMenu, idx: int, value: float) -> None:
213+
"""
214+
Handles a raw slider change.
215+
216+
Args:
217+
menu: The currently open menu.
218+
idx: The index of the item which was activated.
219+
value: The new value of the slider.
220+
"""
221+
_ = menu
222+
try:
223+
option = self.drawn_options[idx]
224+
except IndexError:
225+
logging.error(f"Can't find option which was changed at index {idx}")
226+
return
227+
228+
if not isinstance(option, SliderOption):
229+
logging.error(
230+
f"Option '{option.identifier}' got a spinner change event despite not being a"
231+
" spinner",
232+
)
233+
return
234+
235+
if option.is_integer:
236+
value = round(value)
237+
238+
option.value = value
239+
240+
menu.SetVariableString(
241+
find_focused_item(menu) + ".mLabel.text",
242+
self.format_slider_label(option),
243+
)
244+
222245
def draw_keybind(
223246
self,
224247
kb_frame: WillowGFxMenuScreenFrameKeyBinds,

0 commit comments

Comments
 (0)