Skip to content

Instantly share code, notes, and snippets.

@dennorske
Created December 4, 2023 15:10
Show Gist options
  • Save dennorske/911ff6ef05c7c67d1645ea198d8db3ce to your computer and use it in GitHub Desktop.
Save dennorske/911ff6ef05c7c67d1645ea198d8db3ce to your computer and use it in GitHub Desktop.
DialogList concept for PySAMP
from python.core.color import DialogColor # Colors that has double curly brackets, basically.
class ListItem:
"""A list item is a string that is colored,
formatted and split into tabs. Each field is split with \\t.
To format an item, access the field directly.
"""
def __init__(
self,
*,
fields: list[str],
color: str | None = None,
):
"""
Args:
fields(list[str]): The fields of the list item
color(str, optional): The color of the list item
(Overrides the color of the first field, if any)
"""
self.fields = fields
self.color = color
self.tabs = len(self.fields)
def __str__(self) -> str:
"""The list item as a string.
Use when showing dialog.
"""
list_item_string = (
self.color if self.color else "" + "\t".join(self.fields)
)
return list_item_string
def __getitem__(self, index: int) -> str:
if index < 0 or index >= len(self.fields):
raise IndexError(
"ListItem only has " + str(len(self.fields)) + " fields",
" and index " + str(index),
" is out of range",
)
else:
return self.fields[index]
class DialogList:
"""DialogList is the complete list of items (including headers) for view.
Supports Rainbow colors 🦊
"""
def __init__(
self,
headers: list[str],
items: list[ListItem],
rainbow: bool = False,
non_rainbow_color: str = DialogColor.white,
color_palette: list[str] | None = None,
):
"""Header and the ListItems needs to have the same amount of fields.
Args:
headers(list[str]): The headers of the list
items(list[ListItem]): The list of ListItems
rainbow(bool, optional): Add rainbow colors to first field,
it overrides the color_palette argument.
color_palette(list[str], optional): Add colors to fields,
will be used equally for all list items.
The first index will be for the first field and so on.
If the amount of colors exceeds the amount of fields, they will
be ignored. If rainbow is True, this argument is ignored.
`PS: It will not override the color of what the ListItem
defines`
"""
self.headers = headers
self.items = items
self.rainbow = rainbow
self.non_rainbow_color = non_rainbow_color
self.color_palette = color_palette
if rainbow: # override color_palette if rainbow is True
self.color_palette = None
self.color_palette = [
DialogColor.purple,
DialogColor.cyan,
DialogColor.green,
DialogColor.blue,
DialogColor.orange,
DialogColor.admin_orange,
DialogColor.red,
DialogColor.white,
DialogColor.yellow,
] * 10
def __len__(self) -> int:
"""return the number of items, excluding headers"""
return len(self.items)
def __getitem__(self, index: int) -> ListItem:
if index < 0 or index >= len(self.items):
raise IndexError(
"DialogList only has " + str(len(self.items)) + " items",
" and index " + str(index),
" is out of range",
)
else:
return self.items[index]
def __str__(self) -> str:
"""return the list of items as a string"""
if self.rainbow and self.color_palette is not None:
# Set rainbow color to the first listitem field, set next field to
# non-rainbow color
for idx, item in enumerate(self.items):
# prefix the color to the first field
# example:
# item.fields[0] = "color 1" + item.fields[0]
# next iteration becomes:
# item.fields[0] = "color 2" + item.fields[0]
item.fields[0] = self.color_palette[idx] + item.fields[0]
item.fields[1] = self.non_rainbow_color + item.fields[1]
if not self.rainbow and self.color_palette is not None:
# Set color to each field as the order suggests. Color 1 = field 1
for item in self.items:
for idx, field in enumerate(item.fields):
item.fields[idx] = self.color_palette[idx] + field
headers = "\t".join(self.headers) + "\n"
items = "\n".join([str(item) for item in self.items])
return headers + items
def __repr__(self) -> str:
return str(self)
def as_string(self) -> str:
"""Alias for `.str()`"""
return str(self)
def as_content(self) -> str:
"""Alias for `.as_string()`"""
return str(self)
@property
def content(self) -> str:
return str(self)
@property
def string(self) -> str:
"""Return the list of items (including the header) as a string.
This string can be used to set content in a dialog."""
return str(self)
@property
def length(self) -> int:
return len(self)
@property
def count(self) -> int:
return len(self)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment