Skip to content

Commit d6c8daa

Browse files
author
BackRaw
committed
Menus: Add register_close_callback decorator
Signed-off-by: BackRaw <backraw@gmx.de>
1 parent 95be4e0 commit d6c8daa

File tree

3 files changed

+45
-15
lines changed

3 files changed

+45
-15
lines changed

addons/source-python/packages/source-python/menus/base.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class _BaseMenu(AutoUnload, list):
4141

4242
_instances = {}
4343

44-
def __init__(self, data=None, select_callback=None, build_callback=None):
44+
def __init__(self, data=None, select_callback=None, build_callback=None, close_callback=None):
4545
"""Initialize the menu.
4646
4747
:param iterable|None data: Data that should be added to the menu.
@@ -56,6 +56,13 @@ def __init__(self, data=None, select_callback=None, build_callback=None):
5656
:param callable|None build_callback: A function that gets called
5757
before a menu is displayed.
5858
59+
The callback will receive 2 parameters:
60+
1. The instance of this menu.
61+
2. The index of the player who will receive this menu.
62+
63+
:param callable|None close_callback: A function that gets called
64+
when a menu is closed by a player.
65+
5966
The callback will receive 2 parameters:
6067
1. The instance of this menu.
6168
2. The index of the player who will receive this menu.
@@ -64,6 +71,7 @@ def __init__(self, data=None, select_callback=None, build_callback=None):
6471

6572
self.select_callback = select_callback
6673
self.build_callback = build_callback
74+
self.close_callback = close_callback
6775
self._player_pages = defaultdict(_PlayerPage)
6876
self._instances[id(self)] = self
6977

@@ -113,6 +121,15 @@ def _select(self, player_index, choice_index):
113121
if self.select_callback is not None:
114122
return self.select_callback(self, player_index, choice_index)
115123

124+
def _select_close(self, player_index):
125+
"""Handle the close menu selection.
126+
127+
:param int player_index: The index of the player who made the
128+
selection.
129+
"""
130+
if self.close_callback is not None:
131+
return self.close_callback(self, player_index)
132+
116133
def send(self, *ply_indexes, **tokens):
117134
"""Send the menu to the given player indexes.
118135
@@ -260,6 +277,21 @@ def register_build_callback(self, callback):
260277
self.build_callback = callback
261278
return callback
262279

280+
def register_close_callback(self, callback):
281+
"""Register a close callback for the menu.
282+
283+
Can and should be used as a decorator.
284+
285+
:param callable callback: A function that gets called
286+
when a menu is closed by a player.
287+
288+
The callback will receive 2 parameters:
289+
1. The instance of this menu.
290+
2. The index of the player who will receive this menu.
291+
"""
292+
self.close_callback = callback
293+
return callback
294+
263295

264296
class _MenuData(object):
265297
"""Base class for menu data.

addons/source-python/packages/source-python/menus/esc.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class SimpleESCMenu(_BaseMenu):
4949
"""This class creates basic ESC menus."""
5050

5151
def __init__(
52-
self, data=None, select_callback=None, build_callback=None,
52+
self, data=None, select_callback=None, build_callback=None, close_callback=None,
5353
description=None, title=None, title_color=WHITE):
5454
"""Initialize the object.
5555
@@ -64,7 +64,7 @@ def __init__(
6464
menu.
6565
:param Color title_color: The color of the title.
6666
"""
67-
super().__init__(data, select_callback, build_callback)
67+
super().__init__(data, select_callback, build_callback, close_callback)
6868
self.description = description
6969
self.title = title
7070
self.title_color = title_color
@@ -109,7 +109,7 @@ def _get_menu_data(self, player_index):
109109
def _select(self, player_index, choice_index):
110110
"""See :meth:`menus.base._BaseMenu._select`."""
111111
if choice_index == 0:
112-
return None
112+
return self._select_close(player_index)
113113

114114
option = self._player_pages[player_index].options[choice_index]
115115
if not option.selectable:
@@ -165,7 +165,7 @@ class PagedESCMenu(SimpleESCMenu, _PagedMenuBase):
165165
"""
166166

167167
def __init__(
168-
self, data=None, select_callback=None, build_callback=None,
168+
self, data=None, select_callback=None, build_callback=None, close_callback=None,
169169
description=None, title=None, title_color=WHITE, fill=True,
170170
parent_menu=None):
171171
"""Initialize the object.
@@ -184,7 +184,7 @@ def __init__(
184184
hitting 'Back' on the first page.
185185
"""
186186
super().__init__(
187-
data, select_callback, build_callback,
187+
data, select_callback, build_callback, close_callback,
188188
description, title, title_color)
189189
self.fill = fill
190190
self.parent_menu = parent_menu
@@ -280,10 +280,9 @@ def _get_menu_data(self, player_index):
280280

281281
def _select(self, player_index, choice_index):
282282
"""See :meth:`menus.base._BaseMenu._select`."""
283-
# Do nothing if the menu is being closed
284283
if choice_index == 0:
285284
del self._player_pages[player_index]
286-
return None
285+
return self._select_close(player_index)
287286

288287
# Get the player's current page
289288
page_index = self.get_player_page(player_index)

addons/source-python/packages/source-python/menus/radio.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def _slots_to_bin(slots):
106106
def _select(self, player_index, choice_index):
107107
"""See :meth:`menus.base._BaseMenu._select`."""
108108
if choice_index == BUTTON_CLOSE:
109-
return None
109+
return self._select_close(player_index)
110110

111111
return super()._select(
112112
player_index,
@@ -139,7 +139,7 @@ class PagedRadioMenu(SimpleRadioMenu, _PagedMenuBase):
139139

140140
def __init__(
141141
self, data=None, select_callback=None,
142-
build_callback=None, description=None,
142+
build_callback=None, close_callback=None, description=None,
143143
title=None, top_separator='-' * 30, bottom_separator='-' * 30,
144144
fill=True, parent_menu=None):
145145
"""Initialize the object.
@@ -162,7 +162,7 @@ def __init__(
162162
:param _BaseMenu parent_menu: A menu that will be displayed when
163163
hitting 'Back' on the first page.
164164
"""
165-
super().__init__(data, select_callback, build_callback)
165+
super().__init__(data, select_callback, build_callback, close_callback)
166166

167167
self.title = title
168168
self.description = description
@@ -290,10 +290,9 @@ def _get_menu_data(self, player_index):
290290

291291
def _select(self, player_index, choice_index):
292292
"""See :meth:`menus.base._BaseMenu._select`."""
293-
# Do nothing if the menu is being closed
294293
if choice_index == BUTTON_CLOSE:
295294
del self._player_pages[player_index]
296-
return None
295+
return self._select_close(player_index)
297296

298297
# Get the player's current page
299298
page = self._player_pages[player_index]
@@ -321,7 +320,7 @@ class ListRadioMenu(PagedRadioMenu):
321320
Navigation options are added automatically."""
322321

323322
def __init__(
324-
self, data=None, select_callback=None, build_callback=None,
323+
self, data=None, select_callback=None, build_callback=None, close_callback=None,
325324
description=None, title=None, top_separator='-' * 30,
326325
bottom_separator='-' * 30, fill=True, parent_menu=None,
327326
items_per_page=10):
@@ -341,7 +340,7 @@ def __init__(
341340
:param int items_per_page: Number of options that should be displayed
342341
on a single page.
343342
"""
344-
super().__init__(data, select_callback, build_callback, description,
343+
super().__init__(data, select_callback, build_callback, close_callback, description,
345344
title, top_separator, bottom_separator, fill, parent_menu)
346345
self.items_per_page = items_per_page
347346

0 commit comments

Comments
 (0)