asciimatics

repository·master·Indexed 26 days ago

https://github.com/peterbrittain/asciimatics

A cross-platform Python package for creating full-screen text UIs and ASCII animations. It provides low-level console functions for styled text, cursor positioning, and input handling, alongside high-level APIs for anti-aliased line-drawing, image-to-ASCII conversion, particle systems, sprites, and a comprehensive suite of UI widgets including buttons, text boxes, and listboxes.

Tokens
13.9K
Snippets
29
Records
70
Agent score
88%

What's inside asciimatics

  1. Overview of asciimatics features

    master

    Asciimatics provides a cross-platform Python interface for terminal-based animations and text UIs.

    Low-level console functions:

    • Coloured/styled text (including 256 colour terminals)
    • Cursor positioning
    • Non-blocking/non-echoing keyboard input
    • Mouse input (terminal permitting)
    • Console resize detection and handling
    • Screen scraping

    High-level APIs:

    • Anti-aliased ASCII line-drawing
    • Image to ASCII conversion (JPEG and GIF)
    • Animation effects (sprites, particle systems, banners, etc.)
    • Text UI widgets (buttons, text boxes, radio buttons, etc.)
  2. Overview of asciimatics.widgets submodules

    master

    The asciimatics.widgets package provides a comprehensive suite of UI components for building terminal-based interfaces. Available submodules include:

    • Selection & Lists: baselistbox, basepicker, dropdownlist, listbox, multicolumnlistbox, popupmenu, radiobuttons.
    • Input & Controls: button, checkbox, datepicker, timepicker, textbox.
    • Display & Layout: divider, verticaldivider, frame, label, scrollbar, text, layout.
    • Navigation & Dialogs: filebrowser, popupdialog, temppopup.
    • Core & Utilities: widget, utilities.
  3. Build interactive text UIs with the widgets sub-package

    master

    Asciimatics provides a widgets sub-package for creating interactive text user interfaces. The architecture relies on three main components:

    1. Widget: The basic building block (e.g., buttons, checkboxes).
    2. Layout: Manages the arrangement and resizing of Widgets on the Screen.
    3. Frame: An Effect that contains one or more Layouts. It acts like a window in a GUI framework, drawing the visible parts of its layouts within its boundaries.

    You can trigger application logic by setting callbacks for key events, such as button clicks or value changes.

  4. Explore the asciimatics package structure

    master

    The asciimatics package is organized into several modules and subpackages for handling different aspects of ASCII animation and terminal manipulation. Key components include:

    • Subpackages:
      • asciimatics.renderers: For rendering content to the terminal.
      • asciimatics.widgets: For UI components and interactive elements.
    • Core Modules:
      • asciimatics.scene: For managing scenes and animation sequences.
      • asciimatics.screen: For terminal screen management.
      • asciimatics.effects: For visual effects.
      • asciimatics.particles: For particle systems.
      • asciimatics.sprites: For managing animated objects.
      • asciimatics.event: For handling user input and events.
      • asciimatics.paths: For movement and trajectory logic.
      • asciimatics.parsers: For parsing input data.
      • asciimatics.constants, asciimatics.exceptions, asciimatics.strings, and asciimatics.utilities: For supporting functionality.
  5. Explore the asciimatics.renderers package submodules

    master

    The asciimatics.renderers package provides various visual rendering modules for creating animations and terminal effects. Available submodules include:

    • asciimatics.renderers.base: Base classes for renderers.
    • asciimatics.renderers.box: Box rendering.
    • asciimatics.renderers.charts: Chart and graph rendering.
    • asciimatics.renderers.figlettext: FIGlet text rendering.
    • asciimatics.renderers.fire: Fire effects.
    • asciimatics.renderers.images: Image rendering.
    • asciimatics.renderers.kaleidoscope: Kaleidoscope effects.
    • asciimatics.renderers.plasma: Plasma effects.
    • asciimatics.renderers.players: Player/character rendering.
    • asciimatics.renderers.rainbow: Rainbow effects.
    • asciimatics.renderers.rotatedduplicate: Rotated duplicate effects.
    • asciimatics.renderers.scales: Scales effects.
    • asciimatics.renderers.speechbubble: Speech bubble rendering.
  6. Re-apply color themes on terminal resize

    master

    While asciimatics maintains its own themes on resize, it will not automatically re-invoke external applications that use terminal control sequences to set colors (like pywal). If you use such tools, you must manually re-apply the sequences when screen.has_resized() is true.

    from pathlib import Path
    from asciimatics.screen import ManagedScreen
    import sys
    
    with ManagedScreen() as screen:
        # do stuff
        if screen.has_resized():
            wal_sequences = Path.home() / ".cache" / "wal" / "sequences"
            try:
                with wal_sequences.open("rb") as fd:
                    contents = fd.read()
                    sys.stdout.buffer.write(contents)
            except Exception:
                pass
  7. Quick start guide for asciimatics animations

    master

    To create an animation, follow these steps:

    1. Create a Screen object.
    2. Define a Scene containing one or more Effect objects.
    3. Use a Renderer (like FigletText) to provide pre-formatted text for the effects.
    4. Use Screen.wrapper() to run your animation function, which handles the low-level console setup and teardown.
    from asciimatics.screen import Screen
    from asciimatics.scene import Scene
    from asciimatics.effects import Cycle, Stars
    from asciimatics.renderers import FigletText
    
    def demo(screen):
        effects = [
            Cycle(
                screen,
                FigletText("ASCIIMATICS", font='big'),
                screen.height // 2 - 8),
            Cycle(
                screen,
                FigletText("ROCKS!", font='big'),
                screen.height // 2 + 3),
            Stars(screen, (screen.width + screen.height) // 2)
        ]
        screen.play([Scene(effects, 500)])
    
    Screen.wrapper(demo)
  8. Combine Effects and Frames in a Scene

    master

    You can layer different effects in a single Scene. To layer content, add multiple effects to the list passed to the Scene constructor.

    Important: Z-order The order of the effects in the list determines their Z-order. Effects at the end of the list are drawn on top of effects earlier in the list. For example, to place an input form over an animated background, place the InputFormFrame after the background effect in the list.

    scenes = []
    effects = [
        Julia(screen),
        InputFormFrame(screen)
    ]
    scenes.append(Scene(effects, -1))
    screen.play(scenes)
  9. Create and Arrange UI with Frame and Layout

    master

    To build a UI, you define a Frame and associate it with one or more Layout objects. Layouts stack vertically within a Frame. Each Layout defines horizontal columns as proportions of the Frame width. You then add widgets to specific columns within a layout.

    To create a 4-column layout in an 80x20 frame:

    frame = Frame(screen, 80, 20, has_border=False)
    layout = Layout([1, 1, 1, 1])
    frame.add_layout(layout)
    
    # Add widgets to specific columns (0-indexed)
    layout.add_widget(Button("OK", self._ok), 0)
    layout.add_widget(Button("Cancel", self._cancel), 3)

    If you add multiple widgets with labels to the same column, Asciimatics automatically aligns and indents them for a consistent look.

  10. Fill Remaining Space in Frame

    master

    To create layouts like a fixed header/footer with a variable middle section, you can use the following methods to fill remaining space:

    1. Layout level: Set fill_frame=True when constructing a Layout.
    2. Widget level: Set the height of a widget to Widget.FILL_FRAME during construction.

    Warning: You can only have one Layout or one Widget that fills the frame. Attempting to set more than one will be rejected.

  11. Manage input focus and Modal Frames

    master

    Input Focus

    Focus determines which widget receives keyboard input. Users can navigate focus using cursor keys, Tab/Backtab, or the mouse. If you set hover_focus=True on a Frame and your terminal supports mouse move events, simply hovering over a widget will move the focus to it.

    When creating a Frame, you can set is_modal=True. A modal frame prevents input from filtering through to other Effects in the Scene, ensuring only the modal frame processes user input. This is ideal for PopUpDialog notifications.