adafruit-circuitpython-dang


Nameadafruit-circuitpython-dang JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryA subset of the curses framework. Used for making terminal based applications.
upload_time2025-07-23 20:49:10
maintainerNone
docs_urlNone
authorNone
requires_pythonNone
licenseMIT
keywords adafruit blinka circuitpython micropython dang curses terminal ascii ansi tui
VCS
bugtrack_url
requirements Adafruit-Blinka
Travis-CI No Travis.
coveralls test coverage No coveralls.
            Introduction
============


.. image:: https://readthedocs.org/projects/adafruit-circuitpython-dang/badge/?version=latest
    :target: https://docs.circuitpython.org/projects/dang/en/latest/
    :alt: Documentation Status


.. image:: https://raw.githubusercontent.com/adafruit/Adafruit_CircuitPython_Bundle/main/badges/adafruit_discord.svg
    :target: https://adafru.it/discord
    :alt: Discord


.. image:: https://github.com/adafruit/Adafruit_CircuitPython_Dang/workflows/Build%20CI/badge.svg
    :target: https://github.com/adafruit/Adafruit_CircuitPython_Dang/actions
    :alt: Build Status


.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
    :target: https://github.com/astral-sh/ruff
    :alt: Code Style: Ruff

A subset of the curses framework. Used for making terminal based applications.


Dependencies
=============
This driver depends on:

* `Adafruit CircuitPython <https://github.com/adafruit/circuitpython>`_

Please ensure all dependencies are available on the CircuitPython filesystem.
This is easily achieved by downloading
`the Adafruit library and driver bundle <https://circuitpython.org/libraries>`_
or individual libraries can be installed using
`circup <https://github.com/adafruit/circup>`_.


Works with any displayio based display.

Installing from PyPI
=====================

On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally `from
PyPI <https://pypi.org/project/adafruit-circuitpython-dang/>`_.
To install for current user:

.. code-block:: shell

    pip3 install adafruit-circuitpython-dang

To install system-wide (this may be required in some cases):

.. code-block:: shell

    sudo pip3 install adafruit-circuitpython-dang

To install in a virtual environment in your current project:

.. code-block:: shell

    mkdir project-name && cd project-name
    python3 -m venv .venv
    source .env/bin/activate
    pip3 install adafruit-circuitpython-dang

Installing to a Connected CircuitPython Device with Circup
==========================================================

Make sure that you have ``circup`` installed in your Python environment.
Install it with the following command if necessary:

.. code-block:: shell

    pip3 install circup

With ``circup`` installed and your CircuitPython device connected use the
following command to install:

.. code-block:: shell

    circup install adafruit_dang

Or the following command to update an existing version:

.. code-block:: shell

    circup update

Usage Example
=============

.. code-block:: python

    import time

    import supervisor
    import terminalio
    from displayio import Group, Palette, TileGrid
    from terminalio import Terminal

    import adafruit_dang as curses


    class Window:
        def __init__(self, n_rows, n_cols, row=0, col=0):
            self.n_rows = n_rows
            self.n_cols = n_cols
            self.row = row
            self.col = col

        @property
        def bottom(self):
            return self.row + self.n_rows - 1

        def up(self, cursor):  # pylint: disable=invalid-name
            if cursor.row == self.row - 1 and self.row > 0:
                self.row -= 1

        def down(self, buffer, cursor):
            if cursor.row == self.bottom + 1 and self.bottom < len(buffer) - 1:
                self.row += 1

        def horizontal_scroll(self, cursor, left_margin=5, right_margin=2):
            n_pages = cursor.col // (self.n_cols - right_margin)
            self.col = max(n_pages * self.n_cols - right_margin - left_margin, 0)

        def translate(self, cursor):
            return cursor.row - self.row, cursor.col - self.col


    def helloworld_main(stdscr, terminal_tilegrid):
        window = Window(terminal_tilegrid.height, terminal_tilegrid.width)
        stdscr.erase()
        img = [None] * window.n_rows

        user_input = ""
        user_entered_message = ""
        last_key_press = ""

        def setline(row, line):
            if img[row] == line:
                return
            img[row] = line
            line += " " * (window.n_cols - len(line) - 1)
            stdscr.addstr(row, 0, line)

        while True:
            header = "Hello World Adafruit Dang"
            margin = (window.n_cols - 1 - len(header)) // 2
            setline(1, f"{' ' * margin}{header}")

            key_press_message = f"Last key pressed: {last_key_press}"
            margin = (window.n_cols - 1 - len(key_press_message)) // 2
            setline(4, f"{' ' * margin}{key_press_message}")

            last_entered = f"Entered Message: {user_entered_message}"
            margin = (window.n_cols - 1 - len(last_entered)) // 2
            setline(6, f"{' ' * margin}{last_entered}")

            user_input_row = window.n_rows - 2
            if user_input:
                setline(user_input_row, user_input)
            else:
                setline(user_input_row, " " * (window.n_cols - 1))

            status_message_row = terminal_tilegrid.height - 1
            status_message = f" Adafruit Dang | Demo | Fruit Jam | {int(time.monotonic())}"
            status_message += " " * (window.n_cols - len(status_message) - 1)
            line = f"{status_message}"
            setline(status_message_row, line)

            k = stdscr.getkey()
            if k is not None:
                if len(k) == 1 and " " <= k <= "~":
                    user_input += k
                    last_key_press = k
                elif k == "\n":
                    user_entered_message = user_input
                    user_input = ""
                elif k in {"KEY_BACKSPACE", "\x7f", "\x08"}:
                    user_input = user_input[:-1]


    def run_helloworld_main(terminal, terminal_tilegrid):
        return curses.custom_terminal_wrapper(terminal, helloworld_main, terminal_tilegrid)


    main_group = Group()
    display = supervisor.runtime.display
    font = terminalio.FONT
    char_size = font.get_bounding_box()
    print(f"char_size: {char_size}")
    screen_size = (display.width // char_size[0], display.height // char_size[1])

    terminal_palette = Palette(2)
    terminal_palette[0] = 0x000000
    terminal_palette[1] = 0xFFFFFF

    terminal_area = TileGrid(
        bitmap=font.bitmap,
        width=screen_size[0],
        height=screen_size[1],
        tile_width=char_size[0],
        tile_height=char_size[1],
        pixel_shader=terminal_palette,
    )

    main_group.append(terminal_area)
    terminal = Terminal(terminal_area, font)

    display.root_group = main_group

    run_helloworld_main(terminal, terminal_area)


Documentation
=============
API documentation for this library can be found on `Read the Docs <https://docs.circuitpython.org/projects/dang/en/latest/>`_.

For information on building library documentation, please check out
`this guide <https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/sharing-our-docs-on-readthedocs#sphinx-5-1>`_.

Contributing
============

Contributions are welcome! Please read our `Code of Conduct
<https://github.com/adafruit/Adafruit_CircuitPython_Dang/blob/HEAD/CODE_OF_CONDUCT.md>`_
before contributing to help this project stay welcoming.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "adafruit-circuitpython-dang",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "adafruit, blinka, circuitpython, micropython, dang, curses, terminal, ascii, ansi, tui",
    "author": null,
    "author_email": "Adafruit Industries <circuitpython@adafruit.com>",
    "download_url": "https://files.pythonhosted.org/packages/ec/26/9f2041a8abf017fcffa7a12898a4e9e8c9fc96ef2309464305ed48d7c704/adafruit_circuitpython_dang-1.0.0.tar.gz",
    "platform": null,
    "description": "Introduction\n============\n\n\n.. image:: https://readthedocs.org/projects/adafruit-circuitpython-dang/badge/?version=latest\n    :target: https://docs.circuitpython.org/projects/dang/en/latest/\n    :alt: Documentation Status\n\n\n.. image:: https://raw.githubusercontent.com/adafruit/Adafruit_CircuitPython_Bundle/main/badges/adafruit_discord.svg\n    :target: https://adafru.it/discord\n    :alt: Discord\n\n\n.. image:: https://github.com/adafruit/Adafruit_CircuitPython_Dang/workflows/Build%20CI/badge.svg\n    :target: https://github.com/adafruit/Adafruit_CircuitPython_Dang/actions\n    :alt: Build Status\n\n\n.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\n    :target: https://github.com/astral-sh/ruff\n    :alt: Code Style: Ruff\n\nA subset of the curses framework. Used for making terminal based applications.\n\n\nDependencies\n=============\nThis driver depends on:\n\n* `Adafruit CircuitPython <https://github.com/adafruit/circuitpython>`_\n\nPlease ensure all dependencies are available on the CircuitPython filesystem.\nThis is easily achieved by downloading\n`the Adafruit library and driver bundle <https://circuitpython.org/libraries>`_\nor individual libraries can be installed using\n`circup <https://github.com/adafruit/circup>`_.\n\n\nWorks with any displayio based display.\n\nInstalling from PyPI\n=====================\n\nOn supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally `from\nPyPI <https://pypi.org/project/adafruit-circuitpython-dang/>`_.\nTo install for current user:\n\n.. code-block:: shell\n\n    pip3 install adafruit-circuitpython-dang\n\nTo install system-wide (this may be required in some cases):\n\n.. code-block:: shell\n\n    sudo pip3 install adafruit-circuitpython-dang\n\nTo install in a virtual environment in your current project:\n\n.. code-block:: shell\n\n    mkdir project-name && cd project-name\n    python3 -m venv .venv\n    source .env/bin/activate\n    pip3 install adafruit-circuitpython-dang\n\nInstalling to a Connected CircuitPython Device with Circup\n==========================================================\n\nMake sure that you have ``circup`` installed in your Python environment.\nInstall it with the following command if necessary:\n\n.. code-block:: shell\n\n    pip3 install circup\n\nWith ``circup`` installed and your CircuitPython device connected use the\nfollowing command to install:\n\n.. code-block:: shell\n\n    circup install adafruit_dang\n\nOr the following command to update an existing version:\n\n.. code-block:: shell\n\n    circup update\n\nUsage Example\n=============\n\n.. code-block:: python\n\n    import time\n\n    import supervisor\n    import terminalio\n    from displayio import Group, Palette, TileGrid\n    from terminalio import Terminal\n\n    import adafruit_dang as curses\n\n\n    class Window:\n        def __init__(self, n_rows, n_cols, row=0, col=0):\n            self.n_rows = n_rows\n            self.n_cols = n_cols\n            self.row = row\n            self.col = col\n\n        @property\n        def bottom(self):\n            return self.row + self.n_rows - 1\n\n        def up(self, cursor):  # pylint: disable=invalid-name\n            if cursor.row == self.row - 1 and self.row > 0:\n                self.row -= 1\n\n        def down(self, buffer, cursor):\n            if cursor.row == self.bottom + 1 and self.bottom < len(buffer) - 1:\n                self.row += 1\n\n        def horizontal_scroll(self, cursor, left_margin=5, right_margin=2):\n            n_pages = cursor.col // (self.n_cols - right_margin)\n            self.col = max(n_pages * self.n_cols - right_margin - left_margin, 0)\n\n        def translate(self, cursor):\n            return cursor.row - self.row, cursor.col - self.col\n\n\n    def helloworld_main(stdscr, terminal_tilegrid):\n        window = Window(terminal_tilegrid.height, terminal_tilegrid.width)\n        stdscr.erase()\n        img = [None] * window.n_rows\n\n        user_input = \"\"\n        user_entered_message = \"\"\n        last_key_press = \"\"\n\n        def setline(row, line):\n            if img[row] == line:\n                return\n            img[row] = line\n            line += \" \" * (window.n_cols - len(line) - 1)\n            stdscr.addstr(row, 0, line)\n\n        while True:\n            header = \"Hello World Adafruit Dang\"\n            margin = (window.n_cols - 1 - len(header)) // 2\n            setline(1, f\"{' ' * margin}{header}\")\n\n            key_press_message = f\"Last key pressed: {last_key_press}\"\n            margin = (window.n_cols - 1 - len(key_press_message)) // 2\n            setline(4, f\"{' ' * margin}{key_press_message}\")\n\n            last_entered = f\"Entered Message: {user_entered_message}\"\n            margin = (window.n_cols - 1 - len(last_entered)) // 2\n            setline(6, f\"{' ' * margin}{last_entered}\")\n\n            user_input_row = window.n_rows - 2\n            if user_input:\n                setline(user_input_row, user_input)\n            else:\n                setline(user_input_row, \" \" * (window.n_cols - 1))\n\n            status_message_row = terminal_tilegrid.height - 1\n            status_message = f\" Adafruit Dang | Demo | Fruit Jam | {int(time.monotonic())}\"\n            status_message += \" \" * (window.n_cols - len(status_message) - 1)\n            line = f\"{status_message}\"\n            setline(status_message_row, line)\n\n            k = stdscr.getkey()\n            if k is not None:\n                if len(k) == 1 and \" \" <= k <= \"~\":\n                    user_input += k\n                    last_key_press = k\n                elif k == \"\\n\":\n                    user_entered_message = user_input\n                    user_input = \"\"\n                elif k in {\"KEY_BACKSPACE\", \"\\x7f\", \"\\x08\"}:\n                    user_input = user_input[:-1]\n\n\n    def run_helloworld_main(terminal, terminal_tilegrid):\n        return curses.custom_terminal_wrapper(terminal, helloworld_main, terminal_tilegrid)\n\n\n    main_group = Group()\n    display = supervisor.runtime.display\n    font = terminalio.FONT\n    char_size = font.get_bounding_box()\n    print(f\"char_size: {char_size}\")\n    screen_size = (display.width // char_size[0], display.height // char_size[1])\n\n    terminal_palette = Palette(2)\n    terminal_palette[0] = 0x000000\n    terminal_palette[1] = 0xFFFFFF\n\n    terminal_area = TileGrid(\n        bitmap=font.bitmap,\n        width=screen_size[0],\n        height=screen_size[1],\n        tile_width=char_size[0],\n        tile_height=char_size[1],\n        pixel_shader=terminal_palette,\n    )\n\n    main_group.append(terminal_area)\n    terminal = Terminal(terminal_area, font)\n\n    display.root_group = main_group\n\n    run_helloworld_main(terminal, terminal_area)\n\n\nDocumentation\n=============\nAPI documentation for this library can be found on `Read the Docs <https://docs.circuitpython.org/projects/dang/en/latest/>`_.\n\nFor information on building library documentation, please check out\n`this guide <https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/sharing-our-docs-on-readthedocs#sphinx-5-1>`_.\n\nContributing\n============\n\nContributions are welcome! Please read our `Code of Conduct\n<https://github.com/adafruit/Adafruit_CircuitPython_Dang/blob/HEAD/CODE_OF_CONDUCT.md>`_\nbefore contributing to help this project stay welcoming.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A subset of the curses framework. Used for making terminal based applications.",
    "version": "1.0.0",
    "project_urls": {
        "Homepage": "https://github.com/adafruit/Adafruit_CircuitPython_Dang"
    },
    "split_keywords": [
        "adafruit",
        " blinka",
        " circuitpython",
        " micropython",
        " dang",
        " curses",
        " terminal",
        " ascii",
        " ansi",
        " tui"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5ffc9257f58ff494e3656eb80508ebd224f1ef2d8e20670f5ec33e87efa60722",
                "md5": "8c9affb866e532876770164cb4d3dddf",
                "sha256": "67e5414159a1751cc72103a5936b5c236565bb78b15441c72c4ae2213d37d9d3"
            },
            "downloads": -1,
            "filename": "adafruit_circuitpython_dang-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8c9affb866e532876770164cb4d3dddf",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 6814,
            "upload_time": "2025-07-23T20:49:09",
            "upload_time_iso_8601": "2025-07-23T20:49:09.111271Z",
            "url": "https://files.pythonhosted.org/packages/5f/fc/9257f58ff494e3656eb80508ebd224f1ef2d8e20670f5ec33e87efa60722/adafruit_circuitpython_dang-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ec269f2041a8abf017fcffa7a12898a4e9e8c9fc96ef2309464305ed48d7c704",
                "md5": "4971bdec20e04c6cb753a83997d20fb2",
                "sha256": "e78a0d2a92d416a093f1f4ffed55c2cac4c68d9582264dea0a6420c5d03b44de"
            },
            "downloads": -1,
            "filename": "adafruit_circuitpython_dang-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "4971bdec20e04c6cb753a83997d20fb2",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 25983,
            "upload_time": "2025-07-23T20:49:10",
            "upload_time_iso_8601": "2025-07-23T20:49:10.030442Z",
            "url": "https://files.pythonhosted.org/packages/ec/26/9f2041a8abf017fcffa7a12898a4e9e8c9fc96ef2309464305ed48d7c704/adafruit_circuitpython_dang-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-23 20:49:10",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "adafruit",
    "github_project": "Adafruit_CircuitPython_Dang",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "Adafruit-Blinka",
            "specs": []
        }
    ],
    "lcname": "adafruit-circuitpython-dang"
}
        
Elapsed time: 0.61227s