rewrite (settings): New SettingGroup impl.
Also add `hover_desc` property to interactives.
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
from .data import ModelData
|
from .data import ModelData
|
||||||
from .base import BaseSetting
|
from .base import BaseSetting
|
||||||
from .ui import SettingWidget, InteractiveSetting
|
from .ui import SettingWidget, InteractiveSetting
|
||||||
from .groups import SettingGroup
|
|
||||||
|
|||||||
@@ -66,11 +66,11 @@ class BaseSetting(Generic[ParentID, SettingData, SettingValue]):
|
|||||||
return self._default
|
return self._default
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self) -> Optional[SettingValue]:
|
def value(self) -> SettingValue: # Actually optional *if* _default is None
|
||||||
"""
|
"""
|
||||||
Context-aware object or objects associated with the setting.
|
Context-aware object or objects associated with the setting.
|
||||||
"""
|
"""
|
||||||
return self._data_to_value(self.parent_id, self.data)
|
return self._data_to_value(self.parent_id, self.data) # type: ignore
|
||||||
|
|
||||||
@value.setter
|
@value.setter
|
||||||
def value(self, new_value: Optional[SettingValue]):
|
def value(self, new_value: Optional[SettingValue]):
|
||||||
|
|||||||
@@ -1,5 +1,79 @@
|
|||||||
from discord.ui import View
|
from typing import Generic, Type, TypeVar, Optional
|
||||||
|
from .ui import InteractiveSetting
|
||||||
|
|
||||||
|
from utils.lib import tabulate
|
||||||
|
|
||||||
|
|
||||||
class SettingGroup(View):
|
T = TypeVar('T', bound=InteractiveSetting)
|
||||||
...
|
|
||||||
|
|
||||||
|
class SettingDotDict(Generic[T], dict[str, Type[T]]):
|
||||||
|
"""
|
||||||
|
Dictionary structure allowing simple dot access to items.
|
||||||
|
"""
|
||||||
|
__getattr__ = dict.__getitem__ # type: ignore
|
||||||
|
__setattr__ = dict.__setitem__ # type: ignore
|
||||||
|
__delattr__ = dict.__delitem__ # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
class SettingGroup:
|
||||||
|
"""
|
||||||
|
A SettingGroup is a collection of settings under one name.
|
||||||
|
"""
|
||||||
|
__initial_settings__: list[Type[InteractiveSetting]] = []
|
||||||
|
|
||||||
|
_title: Optional[str] = None
|
||||||
|
_description: Optional[str] = None
|
||||||
|
|
||||||
|
def __init_subclass__(cls, title: Optional[str] = None):
|
||||||
|
cls._title = title or cls._title
|
||||||
|
cls._description = cls._description or cls.__doc__
|
||||||
|
|
||||||
|
settings: list[Type[InteractiveSetting]] = []
|
||||||
|
for item in cls.__dict__.values():
|
||||||
|
if isinstance(item, type) and issubclass(item, InteractiveSetting):
|
||||||
|
settings.append(item)
|
||||||
|
cls.__initial_settings__ = settings
|
||||||
|
|
||||||
|
def __init_settings__(self):
|
||||||
|
settings = SettingDotDict()
|
||||||
|
for setting in self.__initial_settings__:
|
||||||
|
settings[setting.__name__] = setting
|
||||||
|
return settings
|
||||||
|
|
||||||
|
def __init__(self, title=None, description=None) -> None:
|
||||||
|
self.title: str = title or self._title or self.__class__.__name__
|
||||||
|
self.description: str = description or self._description or ""
|
||||||
|
self.settings: SettingDotDict[InteractiveSetting] = self.__init_settings__()
|
||||||
|
|
||||||
|
def attach(self, cls: Type[T], name: Optional[str] = None):
|
||||||
|
name = name or cls.__name__
|
||||||
|
self.settings[name] = cls
|
||||||
|
return cls
|
||||||
|
|
||||||
|
def detach(self, cls):
|
||||||
|
return self.settings.pop(cls.__name__, None)
|
||||||
|
|
||||||
|
def update(self, smap):
|
||||||
|
self.settings.update(smap.settings)
|
||||||
|
|
||||||
|
def reduce(self, *keys):
|
||||||
|
for key in keys:
|
||||||
|
self.settings.pop(key, None)
|
||||||
|
return
|
||||||
|
|
||||||
|
async def make_setting_table(self, parent_id):
|
||||||
|
"""
|
||||||
|
Convenience method for generating a rendered setting table.
|
||||||
|
"""
|
||||||
|
rows = []
|
||||||
|
for setting in self.settings.values():
|
||||||
|
name = f"{setting.display_name}"
|
||||||
|
set = await setting.get(parent_id)
|
||||||
|
value = set.formatted
|
||||||
|
rows.append((name, value, set.hover_desc))
|
||||||
|
table_rows = tabulate(
|
||||||
|
*rows,
|
||||||
|
row_format="[`{invis}{key:<{pad}}{colon}`](https://lionbot.org \"{field[2]}\")\t{value}"
|
||||||
|
)
|
||||||
|
return '\n'.join(table_rows)
|
||||||
|
|||||||
@@ -749,7 +749,7 @@ class EnumSetting(InteractiveSetting[ParentID, ET, ET]):
|
|||||||
This should almost always include the strings from `_outputs`.
|
This should almost always include the strings from `_outputs`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_enum: ET
|
_enum: Type[ET]
|
||||||
_outputs: dict[ET, str]
|
_outputs: dict[ET, str]
|
||||||
_inputs: dict[str, ET]
|
_inputs: dict[str, ET]
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from discord.ui.button import ButtonStyle, Button, button
|
|||||||
from discord.ui.modal import Modal
|
from discord.ui.modal import Modal
|
||||||
from discord.ui.text_input import TextInput
|
from discord.ui.text_input import TextInput
|
||||||
|
|
||||||
from utils.lib import prop_tabulate, recover_context
|
from utils.lib import tabulate, recover_context
|
||||||
from utils.ui import FastModal
|
from utils.ui import FastModal
|
||||||
from meta.config import conf
|
from meta.config import conf
|
||||||
|
|
||||||
@@ -214,6 +214,15 @@ class InteractiveSetting(BaseSetting[ParentID, SettingData, SettingValue]):
|
|||||||
else:
|
else:
|
||||||
return f"Setting Updated! New value: {self.formatted}"
|
return f"Setting Updated! New value: {self.formatted}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hover_desc(self):
|
||||||
|
return '\n'.join((
|
||||||
|
self.display_name,
|
||||||
|
'=' * len(self.display_name),
|
||||||
|
self.long_desc,
|
||||||
|
f"\nAccepts: {self.accepts}"
|
||||||
|
))
|
||||||
|
|
||||||
async def update_response(self, interaction: discord.Interaction, **kwargs):
|
async def update_response(self, interaction: discord.Interaction, **kwargs):
|
||||||
"""
|
"""
|
||||||
Respond to an interaction which triggered a setting update.
|
Respond to an interaction which triggered a setting update.
|
||||||
@@ -256,10 +265,10 @@ class InteractiveSetting(BaseSetting[ParentID, SettingData, SettingValue]):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def desc_table(self):
|
def desc_table(self):
|
||||||
fields = ("Current value", "Default value")
|
return tabulate(
|
||||||
values = (self.formatted or "Not Set",
|
("Current Value", self.formatted or "Not Set"),
|
||||||
self._format_data(self.parent_id, self.default) or "None")
|
("Default Value", self._format_data(self.parent_id, self.default) or "None"),
|
||||||
return prop_tabulate(fields, values)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def input_field(self) -> TextInput:
|
def input_field(self) -> TextInput:
|
||||||
|
|||||||
Reference in New Issue
Block a user