Skip to content

Commit 95940a6

Browse files
committed
Simplified interface with ButtonMenu class
1 parent c4ae0b5 commit 95940a6

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,17 @@ await pages.start(ctx)
176176

177177
## Button Component Menus
178178

179-
Button implementation of a basic menu that has a stop button and two reply reactions:
179+
Here is a button implementation of a basic menu that has a stop button and two reply reactions. Note that the `ButtonMenu` class is used instead of `Menu` in order to make it a `View`.
180+
181+
`ButtonMenu` is a subclass of `Menu` and it therefore has all the same attributes and methods.
182+
183+
Also note that `ButtonMenu.stop()` is a coroutine and needs to be awaited.
180184

181185
```py
182186
import nextcord
183187
from nextcord.ext import menus
184188

185-
class MyButtonMenu(menus.Menu, nextcord.ui.View):
186-
def __init__(self):
187-
menus.Menu.__init__(self)
188-
nextcord.ui.View.__init__(self)
189-
189+
class MyButtonMenu(menus.ButtonMenu):
190190
async def send_initial_message(self, ctx, channel):
191191
return await channel.send(f'Hello {ctx.author}', view=self)
192192

@@ -200,7 +200,7 @@ class MyButtonMenu(menus.Menu, nextcord.ui.View):
200200

201201
@nextcord.ui.button(emoji="\N{BLACK SQUARE FOR STOP}\ufe0f")
202202
async def on_stop(self, button, interaction):
203-
nextcord.ui.View.stop(self)
203+
await self.stop()
204204
```
205205

206206
Instantiation is the same as above.
@@ -215,7 +215,7 @@ A `ButtonMenuPages` class is provided for pagination with button components.
215215

216216
`ButtonMenuPages` works the same way as the `MenuPages` class found above, but with button components instead of reactions.
217217

218-
`MySource` is the same as defined above, but instantiated with:
218+
`MySource` is the same as defined above, but the menu is instantiated with:
219219

220220
```py
221221
pages = menus.ButtonMenuPages(source=MySource(range(1, 100)), clear_reactions_after=True)

nextcord/ext/menus/__init__.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# consistency with the `nextcord` namespaced logging
1515
log = logging.getLogger(__name__)
1616

17+
DEFAULT_TIMEOUT = 180.0
1718

1819
class MenuError(Exception):
1920
pass
@@ -312,7 +313,7 @@ class Menu(metaclass=_MenuMeta):
312313
calling :meth:`send_initial_message`\, if for example you have a pre-existing
313314
message you want to attach a menu to.
314315
"""
315-
def __init__(self, *, timeout=180.0, delete_message_after=False,
316+
def __init__(self, *, timeout=DEFAULT_TIMEOUT, delete_message_after=False,
316317
clear_reactions_after=False, check_embeds=False, message=None):
317318

318319
self.timeout = timeout
@@ -763,6 +764,30 @@ def stop(self):
763764
self.__tasks.clear()
764765

765766

767+
class ButtonMenu(Menu, nextcord.ui.View):
768+
r"""An interface that allows handling menus by using button interaction components.
769+
770+
Buttons should be marked with the :func:`nextcord.ui.button` decorator. Please note that
771+
this expects the methods to have two parameters, the ``button`` and the ``interaction``.
772+
The ``button`` is of type :class:`nextcord.ui.Button`.
773+
The ``interaction`` is of type :class:`nextcord.Interaction`.
774+
"""
775+
def __init__(self, timeout=DEFAULT_TIMEOUT, *args, **kwargs):
776+
Menu.__init__(self, timeout=timeout, *args, **kwargs)
777+
nextcord.ui.View.__init__(self, timeout=timeout)
778+
779+
async def stop(self):
780+
"""Stops the internal loop and view interactions."""
781+
# disable the buttons
782+
for child in self.children:
783+
child.disabled = True
784+
await self.message.edit(view=self)
785+
# stop the menu loop
786+
Menu.stop(self)
787+
# stop view interactions
788+
nextcord.ui.View.stop(self)
789+
790+
766791
class PageSource:
767792
"""An interface representing a menu page's data source for the actual menu page.
768793
@@ -1082,7 +1107,7 @@ class ButtonMenuPages(MenuPagesBase, nextcord.ui.View):
10821107
The current page that we are in. Zero-indexed
10831108
between [0, :attr:`PageSource.max_pages`).
10841109
"""
1085-
def __init__(self, source, timeout = 180.0, **kwargs):
1110+
def __init__(self, source, timeout=DEFAULT_TIMEOUT, **kwargs):
10861111
MenuPagesBase.__init__(self, source, **kwargs)
10871112
nextcord.ui.View.__init__(self, timeout=timeout)
10881113
skip_double_triangle_buttons = self._skip_double_triangle_buttons()

0 commit comments

Comments
 (0)