Skip to content

Commit bf76a3a

Browse files
committed
Added button functionality to Menu
1 parent 95940a6 commit bf76a3a

File tree

2 files changed

+38
-30
lines changed

2 files changed

+38
-30
lines changed

README.md

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

177177
## Button Component Menus
178178

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`.
179+
Here is a button implementation of a basic menu that has a stop button and two reply reactions.
180180

181-
`ButtonMenu` is a subclass of `Menu` and it therefore has all the same attributes and methods.
181+
Note that `view=self` is passed with the initial message and `nextcord.ui.button` is used instead of `menus.button`.
182182

183-
Also note that `ButtonMenu.stop()` is a coroutine and needs to be awaited.
183+
`Menu.disable()` can be used to disable all buttons in the menu.
184+
185+
`Menu.enable()` can be used to enable all buttons in the menu.
184186

185187
```py
186188
import nextcord
187189
from nextcord.ext import menus
188190

189-
class MyButtonMenu(menus.ButtonMenu):
191+
class MyButtonMenu(menus.Menu):
190192
async def send_initial_message(self, ctx, channel):
191193
return await channel.send(f'Hello {ctx.author}', view=self)
192194

@@ -200,7 +202,8 @@ class MyButtonMenu(menus.ButtonMenu):
200202

201203
@nextcord.ui.button(emoji="\N{BLACK SQUARE FOR STOP}\ufe0f")
202204
async def on_stop(self, button, interaction):
203-
await self.stop()
205+
await self.disable()
206+
self.stop()
204207
```
205208

206209
Instantiation is the same as above.

nextcord/ext/menus/__init__.py

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ def get_buttons(cls):
281281
return buttons
282282

283283

284-
class Menu(metaclass=_MenuMeta):
284+
class Menu(nextcord.ui.View, metaclass=_MenuMeta):
285285
r"""An interface that allows handling menus by using reactions as buttons.
286286
287287
Buttons should be marked with the :func:`button` decorator. Please note that
@@ -316,6 +316,7 @@ class Menu(metaclass=_MenuMeta):
316316
def __init__(self, *, timeout=DEFAULT_TIMEOUT, delete_message_after=False,
317317
clear_reactions_after=False, check_embeds=False, message=None):
318318

319+
super().__init__(timeout=timeout)
319320
self.timeout = timeout
320321
self.delete_message_after = delete_message_after
321322
self.clear_reactions_after = clear_reactions_after
@@ -756,6 +757,34 @@ async def send_initial_message(self, ctx, channel):
756757
"""
757758
raise NotImplementedError
758759

760+
async def _set_all_disabled(self, disable: bool):
761+
"""|coro|
762+
763+
Enables or disable all :class:`nextcord.ui.Button` components in the menu.
764+
765+
Parameters
766+
------------
767+
disable: :class:`bool`
768+
Whether to disable or enable the buttons.
769+
"""
770+
for child in self.children:
771+
child.disabled = disable
772+
await self.message.edit(view=self)
773+
774+
async def enable(self):
775+
"""|coro|
776+
777+
Enables all :class:`nextcord.ui.Button` components in the menu.
778+
"""
779+
await self._set_all_disabled(False)
780+
781+
async def disable(self):
782+
"""|coro|
783+
784+
Disables all :class:`nextcord.ui.Button` components in the menu.
785+
"""
786+
await self._set_all_disabled(True)
787+
759788
def stop(self):
760789
"""Stops the internal loop."""
761790
self._running = False
@@ -764,30 +793,6 @@ def stop(self):
764793
self.__tasks.clear()
765794

766795

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-
791796
class PageSource:
792797
"""An interface representing a menu page's data source for the actual menu page.
793798

0 commit comments

Comments
 (0)