Skip to Content
UI

UI

ZwyLib bundles a handful of ready-made native UI helpers — popup menus, alert dialogs, text/selection input dialogs, progress bottom sheets, and pickers for chats/users — so plugins don’t have to build these from scratch on top of raw Java APIs. Dialog helpers that need a result are coroutines, built on top of zwylib.async_manager.

zwylib.UI

class UI

Namespace class grouping together simple, native UI widgets.

UI.PopupMenuBuilder

UI.PopupMenuBuilder(view: View)

Builds and shows a context (popup) menu anchored to a given Android View.

Constructor Arguments

  • view (View): The view the popup menu should be anchored to.

Methods

add_item
PopupMenuBuilder.add_item(item: UI.PopupMenuItem) -> None

Adds an item to the menu. Order of calls determines display order.

Parameters

  • item (UI.PopupMenuItem): The item to add.

Example

builder = zwylib.UI.PopupMenuBuilder(some_view) builder.add_item(zwylib.UI.PopupMenuItem( text="Delete", on_click=lambda: print("deleted"), icon="msg_delete", is_red=True, )) builder.show()

show
PopupMenuBuilder.show() -> None

Displays the built popup menu anchored to the constructor’s view.


UI.PopupMenuItem

UI.PopupMenuItem(text: str, on_click: () -> None, icon: str, is_red: bool = False)

Dataclass describing a single entry in a PopupMenuBuilder.

Arguments

  • text (str): Item label.
  • on_click (() -> None): Called when the item is tapped.
  • icon (str): Drawable resource name shown next to the item.
  • is_red (bool, default False): Whether to render the item in the destructive/red style.

UI.AlertDialog

UI.AlertDialog(title: str, text: str, buttons: List[UI.AlertButton])

A simple title + message alert dialog with up to three buttons (positive/negative/neutral).

Constructor Arguments

  • title (str): Dialog title.
  • text (str): Dialog message body.
  • buttons (List[UI.AlertButton]): Buttons to show. None entries are ignored, letting you conditionally omit a button.

Methods

show
AlertDialog.show() -> None

Displays the dialog. Does nothing (and logs a warning) if this instance is already showing.

Example

dialog = zwylib.UI.AlertDialog( title="Delete plugin?", text="This cannot be undone.", buttons=[ zwylib.UI.AlertButton("Cancel", type=AlertDialogBuilder.BUTTON_NEGATIVE), zwylib.UI.AlertButton("Delete", red=True, on_click=lambda b, w: do_delete()), ], ) dialog.show()

dismiss
AlertDialog.dismiss() -> None

Dismisses the dialog if it’s currently showing.


UI.AlertButton

UI.AlertButton( text: str, on_click: Optional[(AlertDialogBuilder, int) -> None] = None, type: int = AlertDialogBuilder.BUTTON_POSITIVE, red: bool = False )

Dataclass describing a single button in an AlertDialog.

Arguments

  • text (str): Button label.
  • on_click (Optional[(AlertDialogBuilder, int) -> None], default None): Called with the dialog builder and the clicked button’s index/id.
  • type (int, default AlertDialogBuilder.BUTTON_POSITIVE): One of AlertDialogBuilder.BUTTON_POSITIVE, BUTTON_NEGATIVE, or BUTTON_NEUTRAL, determining the button’s position.
  • red (bool, default False): Whether to render the button text in the destructive/red style.

UI.StringInputDialog

class StringInputDialog

A single-line/multi-line text input dialog.

Methods

show
StringInputDialog.show(title: str, initial_text="", hint="") -> Optional[str]

Coroutine — shows a text input dialog and returns the entered text, or None if the dialog was dismissed without confirming.

Parameters

  • title (str): Dialog title.
  • initial_text (str, default ""): Text pre-filled into the input field.
  • hint (str, default ""): Placeholder text shown when the field is empty.

Example

async def ask_name(): name = await zwylib.UI.StringInputDialog.show("Your name", hint="John Doe") if name is not None: print(f"Got: {name}")

UI.SelectorDialog

class SelectorDialog

A single-choice selection dialog rendered as a list of radio buttons.

Methods

show
SelectorDialog.show(title: str, items: List[str], current_index: int = -1) -> Optional[int]

Coroutine — shows a selection dialog and returns the index of the chosen item, or None if the dialog was dismissed without a selection.

Parameters

  • title (str): Dialog title.
  • items (List[str]): Labels to show, in order.
  • current_index (int, default -1): Index pre-selected when the dialog opens. -1 means no item is pre-selected.

Example

async def ask_theme(): index = await zwylib.UI.SelectorDialog.show("Theme", ["Light", "Dark", "System"], current_index=2) if index is not None: print(f"Chosen: {index}")

UI.BottomSheet

UI.BottomSheet( title: str, description: Optional[str], sticker: str, worker: (UI.BottomSheet) -> None, on_finish: Optional[(UI.BottomSheet) -> None] = None, on_dismiss: Optional[(UI.BottomSheet) -> None] = None )

A non-dismissible bottom sheet with a sticker, title, description, and progress bar — meant for showing progress of a longer-running background task (e.g. downloading/installing something).

Constructor Arguments

  • title (str): Sheet title.
  • description (Optional[str]): Initial description text shown under the progress bar.
  • sticker (str): Sticker reference in "pack_name/index" form, shown at the top of the sheet.
  • worker ((UI.BottomSheet) -> None): Function that performs the actual work. Called (via safe_func_call) when start_worker is invoked, receiving the sheet instance itself so it can call update_status / finish. May be a coroutine function.
  • on_finish (Optional[(UI.BottomSheet) -> None], default None): Called after the sheet is dismissed via finish.
  • on_dismiss (Optional[(UI.BottomSheet) -> None], default None): Called whenever the sheet is dismissed, by any means.

Methods

show
BottomSheet.show() -> None

Displays the sheet.


start_worker
BottomSheet.start_worker() -> None

Invokes the worker function passed to the constructor, passing this sheet instance as its only argument.

Example

def do_work(sheet: "zwylib.UI.BottomSheet"): sheet.update_status(0.5, "Halfway there...") ... sheet.finish() sheet = zwylib.UI.BottomSheet("Installing", "Starting...", "MyPack/1", do_work) sheet.show() sheet.start_worker()

update_status
BottomSheet.update_status(progress: float, text: str) -> None

Updates the progress bar and description text.

Parameters

  • progress (float): Progress fraction from 0.0 to 1.0 (values above 1.0 are clamped).
  • text (str): New description text.

finish
BottomSheet.finish() -> None

Dismisses the sheet and calls on_finish, if provided.

zwylib.DialogPicker

class DialogPicker

Presents native chat/user picker screens and awaits the user’s selection.

Methods

pick_dialogs

DialogPicker.pick_dialogs( pre_picked: Optional[List[int]] = None, chats_only=False ) -> PickedDialogs

Coroutine — opens the multi-select “share with” screen and returns what the user picked.

Parameters

  • pre_picked (Optional[List[int]], default None): Peer IDs to pre-select when the screen opens.
  • chats_only (bool, default False): If True, filters the list down to chats/channels only, hiding individual users.

Example

async def choose(): picked = await zwylib.DialogPicker.pick_dialogs(chats_only=True) print(picked.chats)

pick_chat

DialogPicker.pick_chat(groups=True, channels=True, topics=False) -> TopicKey

Coroutine — opens the single-select dialogs screen and returns the chosen chat (and topic, if applicable). Raises an exception if the picker is cancelled.

Parameters

  • groups (bool, default True): Whether groups/megagroups are selectable.
  • channels (bool, default True): Whether channels are selectable.
  • topics (bool, default False): Whether forum topics can be selected in addition to the chat itself.

Example

async def choose(): result = await zwylib.DialogPicker.pick_chat(topics=True) print(result.dialog_id, result.topic_id)

zwylib.PickedDialogs

@dataclass class PickedDialogs: users: List[int] chats: List[int]

Result of DialogPicker.pick_dialogs — the peer IDs the user selected, split into users and chats.

zwylib.TopicKey

@dataclass class TopicKey: dialog_id: int topic_id: int

Result of DialogPicker.pick_chat — the picked chat’s ID and, if applicable, the picked topic’s ID (0 when no topic was selected).

Last updated on