Skip to content

Commit 695b701

Browse files
committed
try address top menu item going off screen when there are enough mods
1 parent 39114d2 commit 695b701

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

src/willow1_mod_menu/lobby.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# ruff: noqa: D103
2+
import math
23
import re
34
import traceback
45
from typing import Any
56

67
import unrealsdk
7-
from unrealsdk.hooks import Block
8+
from unrealsdk.hooks import Block, Type
89
from unrealsdk.unreal import BoundFunction, UObject, WeakPointer, WrappedStruct
910

1011
from mods_base import (
@@ -44,8 +45,9 @@ def open_lobby_mods_menu(frontend: WillowGFxMenuFrontend) -> None:
4445
block_search_delegate.enable()
4546
init_content.enable()
4647
play_sound.enable()
47-
menu_close.enable()
4848
handle_input_key.enable()
49+
menu_scroll.enable()
50+
menu_close.enable()
4951

5052
frontend.OpenMP()
5153

@@ -131,6 +133,7 @@ def init_next_tick(*_: Any) -> None:
131133

132134
menu.SetVariableString("lobby.tab.text", "SDK Mod Manager")
133135
menu.SetVariableString("lobby.optionsHeader.text", "Mods")
136+
menu.SetVariableNumber("mMenu.mList._y", 0)
134137

135138
# Most of the mod details could be updated in the initial hook, but there's a few parts which
136139
# need to be here
@@ -270,6 +273,39 @@ def handle_input_key(
270273
return Block, True
271274

272275

276+
@hook("WillowGame.WillowGFxLobbyBase:inNext", hook_type=Type.POST)
277+
@hook("WillowGame.WillowGFxLobbyBase:inPrev", hook_type=Type.POST)
278+
def menu_scroll(
279+
obj: UObject,
280+
_args: WrappedStruct,
281+
_ret: Any,
282+
_func: BoundFunction,
283+
) -> None:
284+
# If we have more than a page of menu items (14), the scrolling slightly breaks, and the top
285+
# item gets displayed off screen. This is probably a vanilla bug.
286+
# Note this hook is not suitable for focus change, since it's not triggered on mouse movement.
287+
288+
if not math.isfinite(list_y := obj.GetVariableNumber("mMenu.mList._y")):
289+
return
290+
if list_y >= 0:
291+
# Already scrolled to the top, no need to do anything
292+
return
293+
294+
if get_focused_mod(obj) == drawn_mods[0]:
295+
# Special case: if we just scrolled to index 0 always scroll back to the top
296+
obj.SetVariableNumber("mMenu.mList._y", 0)
297+
return
298+
299+
# You can still scroll off the top, as long as you're not selecting the very top item.
300+
301+
# Unfortunately, this seems non-trivial to fix.
302+
# For one, there isn't really a good way to detect if the focused item is off screen.
303+
# Then even if we come up with a heuristic, changing Y while not at the top has some weird
304+
# effects, it'll bring the header back and leave us with some empty menu items.
305+
306+
# Leaving it for now. You can always just scroll up an extra time.
307+
308+
273309
@hook("WillowGame.WillowGFxLobbyMultiplayer:OnClose")
274310
def menu_close(
275311
_obj: UObject,
@@ -282,8 +318,9 @@ def menu_close(
282318
init_next_tick.disable()
283319
play_sound.disable()
284320
select_next_tick.disable()
285-
menu_close.disable()
286321
handle_input_key.disable()
322+
menu_scroll.disable()
323+
menu_close.disable()
287324

288325
global current_menu
289326
current_menu = WeakPointer()

0 commit comments

Comments
 (0)