A cross platform package to do curses-like operations, plus higher level APIs and widgets to create text UIs and ASCII art animations

Overview
Linux build status Windows build status Code Health Code Coverage Latest stable version Join the chat at https://gitter.im/asciimatics/Lobby

ASCIIMATICS

Asciimatics is a package to help people create full-screen text UIs (from interactive forms to ASCII animations) on any platform. It is licensed under the Apache Software Foundation License 2.0.

Why?

Why not? It brings a little joy to anyone who was programming in the 80s... Oh and it provides a single cross-platform Python class to do all the low-level console function you could ask for, including:

  • Coloured/styled text - including 256 colour terminals and unicode characters (even CJK languages)
  • Cursor positioning
  • Keyboard input (without blocking or echoing) including unicode support
  • Mouse input (terminal permitting)
  • Detecting and handling when the console resizes
  • Screen scraping

In addition, it provides some simple, high-level APIs to provide more complex features including:

  • Anti-aliased ASCII line-drawing
  • Image to ASCII conversion - including JPEG and GIF formats
  • Many animation effects - e.g. sprites, particle systems, banners, etc.
  • Various widgets for text UIs - e.g. buttons, text boxes, radio buttons, etc.

Currently this package has been proven to work on CentOS 6 & 7, Raspbian (i.e. Debian wheezy), Ubuntu 14.04, Windows 7, 8 & 10, OSX 10.11 and Android Marshmallow (courtesy of https://termux.com), though it should also work for any other platform that provides a working curses implementation.

It should be implementation agnostic and has been successfully tested on CPython and PyPy2.

(Please let me know if you successfully verified it on other platforms so that I can update this list).

Installation

Asciimatics supports Python versions 2 & 3. For the precise list of tested versions, refer to pypi.

To install asciimatics, simply install with pip as follows:

$ pip install asciimatics

This should install all your dependencies for you. If you don't use pip or it fails to install them, you can install the dependencies directly using the packages listed in requirements.txt. Additionally, Windows users (who aren't using pip) will need to install pywin32.

How to use it?

To use the low-level API, simply create a Screen and use it to print coloured text at any location, or get mouse/keyboard input. For example, here is a variant on the classic "hello world":

from random import randint
from asciimatics.screen import Screen

def demo(screen):
    while True:
        screen.print_at('Hello world!',
                        randint(0, screen.width), randint(0, screen.height),
                        colour=randint(0, screen.colours - 1),
                        bg=randint(0, screen.colours - 1))
        ev = screen.get_key()
        if ev in (ord('Q'), ord('q')):
            return
        screen.refresh()

Screen.wrapper(demo)

That same code works on Windows, OSX and Linux and paves the way for all the higher level features. These still need the Screen, but now you also create a Scene using some Effects and then get the Screen to play it. For example, this code:

from asciimatics.effects import Cycle, Stars
from asciimatics.renderers import FigletText
from asciimatics.scene import Scene
from asciimatics.screen import Screen

def demo(screen):
    effects = [
        Cycle(
            screen,
            FigletText("ASCIIMATICS", font='big'),
            int(screen.height / 2 - 8)),
        Cycle(
            screen,
            FigletText("ROCKS!", font='big'),
            int(screen.height / 2 + 3)),
        Stars(screen, 200)
    ]
    screen.play([Scene(effects, 500)])

Screen.wrapper(demo)

should produce something like this:

asciicast

Or maybe you're looking to create a TUI? In which case this simple code will give you this:

contact list sample

Documentation

Full documentation of all the above (and more!) is available at http://asciimatics.readthedocs.org/

More examples

More examples of what you can do are available in the project samples directory, hosted on GitHub. See https://github.com/peterbrittain/asciimatics/tree/v1.12/samples.

To view them, simply download these files and then simply run them directly with python. Alternatively, you can browse recordings of many of the samples in the gallery at https://github.com/peterbrittain/asciimatics/wiki.

Bugs and enhancements

If you have a problem, please check out the troubleshooting guide at http://asciimatics.readthedocs.io/en/latest/troubleshooting.html. If this doesn't solve your problem, you can report bugs (or submit enhancement requests) at https://github.com/peterbrittain/asciimatics/issues.

Alternatively, if you just have some questions, feel free to drop in at https://gitter.im/asciimatics/Lobby.

Contributing to the project

If you'd like to take part in this project (and see your name in the credits!), check out the guidance at http://asciimatics.readthedocs.org/en/latest/contributing.html

Comments
  • Vertical barcharts

    Vertical barcharts

    Describe the solution you'd like I would really like to have some barcharts, but vertically.

    Describe alternatives you've considered The only possibility to implement this with acsiimatics I can imagine is drawing it completely manually

    enhancement help wanted good first issue 
    opened by dasteihn 51
  • Add caching to labels

    Add caching to labels

    Issues fixed by this PR

    We had ~40% worst case CPU load without the fix in MPF. With this fix worst case CPU reduces to ~30%.

    What does this implement/fix?

    Cache the result of split_text for labels. This hardly changes and we invalidate the cache if it would.

    Any other comments?

    I guess it would make sense in some other widgets too. Text for example.

    PR is on top of #213 to prevent merge conflicts.

    opened by jabdoa2 25
  • Delete key in Text widget not working correctly

    Delete key in Text widget not working correctly

    I'm using Mac OS X and when I press the "delete" key (in Macs this is deleting to the left, so actually backspace) in a Text widget, its size changes and starts to behave strangely. The actual delete key (this is fn+delete in Macs) works fine. The key code of "delete" is 127 and I haven't seen this being handled in screen.py.

    bug help wanted 
    opened by ulthiel 22
  • Packaging for NixOS (test failures)

    Packaging for NixOS (test failures)

    Describe the bug

    I'm packaging this for NixOS: https://github.com/NixOS/nixpkgs/pull/54404

    However there are test failures as can be seen here: https://github.com/NixOS/nixpkgs/pull/54404#issuecomment-456238198

    To Reproduce

    Using the PR, run nix-env -f ./default.nix -iA 'python36.pkgs.asciimatics'.

    System details (please complete the following information):

    • system: "x86_64-linux"
    • host os: Linux 4.17.6, Form Bay ML, noversion
    • multi-user?: yes
    • sandbox: yes
    • version: nix-env (Nix) 2.0.4
    • nixpkgs: /nix/nixpkgs
    opened by CMCDragonkai 20
  • Add vertical separators to multicolumnlistbox

    Add vertical separators to multicolumnlistbox

    Hello, great project I was thinking, how about something like a listview ...i know that the treeview is pretty close (and great) but it would be great if we could have something like dos commander style

    enhancement good first issue 
    opened by tsgiannis 19
  • Issue on Python 3.6

    Issue on Python 3.6

    Code works perfectly on Python 2.7, but in Python 3.6 crashes the first time Screen.refresh() is called.

    Traceback (most recent call last):
      File "/Users/anthonyshaw/repo/retox-2/retox/__main__.py", line 66, in main
        screen.refresh()
      File "/Users/anthonyshaw/repo/retox-2/src/asciimatics/asciimatics/screen.py", line 2129, in refresh
        super(_CursesScreen, self).refresh()
      File "/Users/anthonyshaw/repo/retox-2/src/asciimatics/asciimatics/screen.py", line 1216, in refresh
        self._change_colours(new_cell[1], new_cell[2], new_cell[3])
      File "/Users/anthonyshaw/repo/retox-2/src/asciimatics/asciimatics/screen.py", line 2225, in _change_colours
        self._safe_write(self._a_normal)
      File "/Users/anthonyshaw/repo/retox-2/src/asciimatics/asciimatics/screen.py", line 2085, in _safe_write
        sys.stdout.write(msg)
      File "/Users/anthonyshaw/repo/retox-2/bin/../lib/python3.6/codecs.py", line 377, in write
        self.stream.write(data)
      File "/Users/anthonyshaw/repo/retox-2/bin/../lib/python3.6/codecs.py", line 376, in write
        data, consumed = self.encode(object, self.errors)
    TypeError: utf_8_encode() argument 1 must be str, not bytes
    

    Any help/tips on debugging would be appreciated.

    opened by tonybaloney 19
  • Left/Right Navigation

    Left/Right Navigation

    It would be preferable for left and right to switch focus to the nearest widget rather than the bottom of the nearest widget's column. I have an app that is a grid of equal size buttons, which this behavior makes it unusable.

    Even if this is something you are not interested in doing. Can you point me in the right direction on getting this done per app? I subclassed Layout->process_event, I see the code for KEY_LEFT and KEY_RIGHT, but I am not understanding how it works. find_next_widget looks like where the magic happens. First value is the column difference. I would think start_at would be how far down the column to check for the next widget. That doesn't seem to be it tho. Even if it is, I'd need to get the row? somewhere.

    enhancement 
    opened by peterjschroeder 18
  • Cannot display any Chinese characters on the Widgets

    Cannot display any Chinese characters on the Widgets

    Chinese characters cannot display correctly, no exceptions or errors, just display nothing for those characters. code like this

        def _quit(self):
            self._scene.add_effect(
                PopUpDialog(self._screen,
                            u"你確定嗎?",
                            [u"是", u"否"],
                            on_close=self._quit_on_yes))
    
    jietu20170322-090227 2x bug 
    opened by nilliu 18
  • text box with support for raw ansii input

    text box with support for raw ansii input

    For my app, I really needed to be able to support getting verbatim output from other terminal apps and showing it to the user. These other commands might print color text, and I wanted the color to be preserved and shown to the user as-is. I've basically been approaching my asciimatics app as if it were a web app in the terminal; if I were doing a web app, I would be able to use any HTML along with the framework widgets, and I had not considered that a similar way of working with asciimatics and raw ansii codes would be difficult.

    I dug around in the asciimatics code for a while and decided that implementing this as a widget would be... pretty difficult, at least for me. My workaround below might be useful for the library documentation.

    First we create a new exception to hold the external command to be run and scene to resume once it's finished:

    class ExternalCallException(Exception):
        def __init__(self, last_scene, command):
            self.last_scene = last_scene
            self.command = command
    

    When the external command should be run, we raise the exception like so (self is the widget object):

    raise ExternalCallException(self._scene, 'my command here')
    

    Then we add an extra except clause under the one handling screen resizes:

        except ResizeScreenError as e:
            last_scene = e.scene
        # new code below
        except ExternalCallException as e:
            last_scene = e.last_scene
            try:
                # -K means quit on ^C; -R means print ansii codes as-is
                process = Popen(e.command + " | less -K -R", shell=True)
                process.wait()
            except KeyboardInterrupt:
                # let less handle this, -K will exit cleanly
                pass
    

    With this, the external command is piped to less, which temporarily controls the whole screen and shows the command's output in color. When the user quits less, the app reappears using the same mechanism as when the screen is resized.

    enhancement 
    opened by garfieldnate 17
  • Tests fail on openSUSE Python 2 and 3

    Tests fail on openSUSE Python 2 and 3

    Describe the bug A large number of tests fail on Python 2.7 & 3.7 . I have confirmed that Python 3.7 works on Travis.

    To Reproduce The OBS project at https://build.opensuse.org/package/show/home:jayvdb:py-wheels/python-asciimatics has a .spec which makes this very reproducible.

    Build log for openSUSE tumbleweed amd64, which includes the Python 2.7 errors:

    _log.txt

    I've run the same locally on my machine with pytest and it also fails.

    Expected behavior Tess pass.

    System details (please complete the following information):

    • openSUSE (all versions)
    • Asciimatics 1.10.0
    opened by jayvdb 14
  • RegEx filtering option for FileBrowser

    RegEx filtering option for FileBrowser

    Issues fixed by this PR

    #186

    What does this implement/fix?

    Added a new RegEx option to the FileBrowser to allow filtering of files

    Any other comments?

    If you need me to change anything, please let me know.

    opened by kirtansakariya 14
  • DarkGray access on Windows/Powershell?

    DarkGray access on Windows/Powershell?

    When I run this script in my Powershell: https://stackoverflow.com/questions/20541456/list-of-all-colors-available-for-powershell I can see there is a DarkGray color in my system.

    However, asciimatics doesn't have that in the Screen class (or anywhere else according to my search). Is there any way to access DarkGray somehow?

    (Incidentally, do you know a shell that supports more colors than Powershell on Windows? Or is the limitation underlying?)

    question 
    opened by ymyke 5
  • Rain fails after 2038-01-19

    Rain fails after 2038-01-19

    Describe the bug Rain test fails after 2038-01-19

    To Reproduce

    on openSUSE, I build the package with

    osc co openSUSE:Factory/python-asciimatics
    osc build --vm-type=kvm --noservice --clean --build-opt=--vm-custom-opt="-rtc base=2038-01-20T00:00:00" --alternative-project=home:bmwiedemann:reproducible openSUSE_Tumbleweed
    

    Expected behavior

    tests should continue to pass in future

    Screenshots

     =================================== FAILURES ===================================
     ___________________________ TestParticles.test_rain ____________________________
     
     self = <tests.test_particles.TestParticles testMethod=test_rain>
     
         def test_rain(self):
             """     
             Test that Rain works as expected.
             """     
             screen = MagicMock(spec=Screen, colours=8)
             canvas = Canvas(screen, 10, 40, 0, 0)
             effect = Rain(canvas, 200)
     >       self.check_effect(canvas,
                               effect,
                               lambda value: self.assertIn(chr(value[0]), ' `\\v'))
    
     tests/test_particles.py:98:
     _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
     tests/test_particles.py:43: in check_effect
         self.assertTrue(changed, "failed at step %d %s" % (i, view))
     E   AssertionError: False is not true : failed at step 0
    
    ==== 1 failed, 149 passed, 41 skipped, 1 deselected, 966 warnings in 3.67s =====
    

    System details (please complete the following information):

    • OS and version: openSUSE-Tumbleweed-20220906
    • Python version: 3.10
    • Python distribution: cpython
    • Asciimatics version 1.14.0

    Additional context See also https://en.wikipedia.org/wiki/Year_2038_problem

    As part of my work on reproducible builds for openSUSE, I check that software still gives identical build results in the future. The usual offset is +16 years, because that is how long I expect some software will be used in some places. This showed up failing tests in our package build. See https://reproducible-builds.org/ for why this matters.

    opened by bmwiedemann 5
  • Add support for scroll wheels

    Add support for scroll wheels

    As per our conversation 2022-02-06 at https://gitter.im/asciimatics/Lobby, I am requesting scrollwheel support in Asciimatics.

    Main technical thrust: Modify Screen to recognize scrollwheel events and handle it in the Frame

    I will begin work on this soon and submit a PR when I get it working.

    =======================

    Jeff Wright @jeffwright13 Feb 06 06:35 @peterbrittain - is there a way to modify the scrolling behavior? When I use the scroll wheel on my mouse, it seems to want to scroll an entire page at a time, instead of what I have come to expect in a normal GUI: N lines at a time. The result is a very jumpy experience. I didn't see anything in the docs about configuring scroll behavior. peterbrittain @peterbrittain Feb 06 06:46 That's because asciimatics doesn't support scroll wheels (due to patchy support in Linux). I suspect what you're seeing is the terminal intercepting the event and scrolling the whole buffer. You'll be able to tell if this is the case, because asciimatics will still only draw on the original screen that was visible when you started the app. Jeff Wright @jeffwright13 Feb 06 06:55 So nothing to be done then? peterbrittain @peterbrittain Feb 06 07:08 Mouse support has improved in ncurses 6. Do you know what version your system uses? We'd also need to see if there is a setting on your terminal to force it to pass the input to the running app (instead of consuming it itself). Jeff Wright @jeffwright13 Feb 06 07:14

    I am running (currently) on a Macbook Pro (2019/Intel). Latest version of OSX. I usually run Pytest (and hence Asciimatics) out of iTerm2, although sometimes also from my IDE (VSCode, with Integrated Terminal). My shell is latest zsh.

    $ tic -V ncurses 5.7.20081102

    BUT:

    $ brew upgrade ncurses Running brew update --preinstall... ==> Auto-updated Homebrew! Updated 2 taps (homebrew/core and homebrew/cask). ==> Updated Formulae Updated 84 formulae. ==> Updated Casks Updated 36 casks.

    Warning: ncurses 6.3 already installed

    peterbrittain @peterbrittain Feb 06 08:02 Ok... with a newer version of ncurses, you then need to enable scroll wheel reporting. Looks like there's a setting in iterm2: https://iterm2.com/documentation-preferences-profiles-terminal.html Finally, we'd need to tweak asciimatics Screen to recognize the events and handle it in the Frame. All pretty self-contained changes, so I can explain them to you if you're up for submitting a PR. Jeff Wright @jeffwright13 Feb 06 09:16 Screen Shot 2022-02-06 at 9.16.13 AM.png Screen Shot 2022-02-06 at 9.16.38 AM.png Looks like I already had that setting enabled ("Enable mouse reporting") Sure, I could submit a PR. Would need some guidance on where in the code to make changes. peterbrittain @peterbrittain Feb 06 14:57 Ok... There are 2 basic changes. First is to _CursesScreen.get_event(). There's already logic to handle other buttons in there. We just need to find what events fire when you scroll the mouse wheel. You could either add some logging to the function, or use something like this: https://stackoverflow.com/questions/11893034/mouse-wheel-in-python-curses. According to the curses maintainer, it should look like mouse buttons 4 and 5. See https://stackoverflow.com/questions/42356352/mouse-scroll-up-ncurses-c Once you have those events translated into equivalent asciimatics MouseEvents, you just need to act on them in the scrollbar. That's in scrollbar.py. simply get the current position and add/subtract a percentage to the position on the relevant button. Jeff Wright @jeffwright13 Feb 06 20:54

    I made the following changes to screen.py.

                    # Some Linux modes only report clicks, so check for any
                    # button down or click events.
                    if (bstate & curses.BUTTON1_PRESSED != 0 or
                            bstate & curses.BUTTON1_CLICKED != 0):
                        buttons |= MouseEvent.LEFT_CLICK
                    if (bstate & curses.BUTTON3_PRESSED != 0 or
                            bstate & curses.BUTTON3_CLICKED != 0):
                        buttons |= MouseEvent.RIGHT_CLICK
                    if bstate & curses.BUTTON1_DOUBLE_CLICKED != 0:
                        buttons |= MouseEvent.DOUBLE_CLICK
                    if bstate & curses.BUTTON4_PRESSED != 0:
                        print("BUTTON4_PRESSED")
                    if bstate & curses.BUTTON5_PRESSED != 0:
                        print("BUTTON5_PRESSED")
                    if bstate & curses.BUTTON4_CLICKED != 0:
                        print("BUTTON4_CLICKED")
                    if bstate & curses.BUTTON5_CLICKED != 0:
                        print("BUTTON5_CLICKED")
                    return MouseEvent(x, y, buttons)
    

    This resulted in an exception when the scroll wheel was rolled:

    Traceback (most recent call last): File "/Users/jwr003/coding/pytest-fold/pytest_fold/tui.py", line 186, in main() File "/Users/jwr003/coding/pytest-fold/pytest_fold/tui.py", line 179, in main Screen.wrapper(demo, catch_interrupt=True, arguments=[last_scene]) File "/Users/jwr003/coding/pytest-fold/venv/lib/python3.9/site-packages/asciimatics/screen.py", line 1393, in wrapper return func(screen, *arguments) File "/Users/jwr003/coding/pytest-fold/pytest_fold/tui.py", line 166, in demo screen.play( File "/Users/jwr003/coding/pytest-fold/venv/lib/python3.9/site-packages/asciimatics/screen.py", line 1566, in play self.draw_next_frame(repeat=repeat) File "/Users/jwr003/coding/pytest-fold/venv/lib/python3.9/site-packages/asciimatics/screen.py", line 1649, in draw_next_frame event = self.get_event() File "/Users/jwr003/coding/pytest-fold/venv/lib/python3.9/site-packages/asciimatics/screen.py", line 2494, in get_event if bstate & curses.BUTTON5_PRESSED != 0: AttributeError: module 'curses' has no attribute 'BUTTON5_PRESSED'

    I am on a Mac. I saw the following comment in _curses.py:

    # Darwin ncurses doesn't provide BUTTON5_* constants
    

    Maybe that's the issue with the crash above. peterbrittain @peterbrittain Feb 07 00:58 Yeah - I wondered if we'd start hitting issue like this. We can create the constants ourselves if needed. For now, I suggest you just log the bstate in hex and compare it to https://github.com/mirror/ncurses/blob/d30f99439fcc8d4bb4c38e5c4afb4f6555fc6ad4/include/curses.tail Note that print doesn't work in alternate screens (like asciimatics uses). Also, if you don't like doing the bit maths, you can probably use this definition instead: https://github.com/mattn/pdcurses/blob/master/curses.h Jeff Wright @jeffwright13 Feb 07 11:14 The print was meant for initial diagnosis to see what button the system registered when I scrolled. Definitely will remove before issuing a PR! peterbrittain @peterbrittain Feb 07 11:57 :-)

    enhancement 
    opened by jeffwright13 1
  • Expanded Documentation and Examples for handling user input

    Expanded Documentation and Examples for handling user input

    Is your feature request related to a problem? Please describe. Full disclosure, I'm not a python power user, so I may well be missing something obvious with python itself.

    I'm building a video game, and have the engine mostly done in curses. I wanted to add fancy animations, so I started trying to port things over to asciimatics. However, I'm finding it hard to follow the docs in some places. For a specific example, I'm finding it hard to sort out how to use wait_for_input() in conjunction with get_event() as outlined in the docs, but there are no examples to pull from. It's not clear to me how I should even begin to get a user's input and then process it using these two methods.

    I can see the timeout of wait_for_input() is working in my script, but when I press any character the app just exits immediately. From the explanation in the docs, it made it seem as though I could just keep typing and the app would block execution until something is entered (presumably just hitting enter, but the docs aren't clear here either). I don't think this is a bug, but rather my misunderstanding of how it is supposed to function.

    The one example I've tried to follow that sort of has what I'm looking for is forms.py, but I don't see that there is any get_event() or wait_for_input() calls. None of the examples I've dug through seem to have these calls in them.


    Describe the solution you'd like Some example of using wait_for_input() and get_event(), and expand on the docs here: https://asciimatics.readthedocs.io/en/stable/io.html#input

    Would it be possible, at some point, to get an example that allows the user to input a word or short phrase in one frame, then display that entered text as FigletText in its own, separate frame?


    Additional context In my particular application, I've got several frames on-screen where one of those frames is a single-line input. Like a text adventure game, I want to have the user input a simple command then process it to change the db and then update the display with new info.

    I've been able to sort out a lot of other details from the docs, but the user input handling is one where I am a little lost. In curses, I was able to do what I needed to do with the textpad.Textbox object with relative ease. I thought that I might be able to use asciimatics's Text widget, but so far have been unsuccessful.

    EDIT:

    I'm currently running python 3.10 with asciimatics v1.13.0, and I am being careful to dig through examples in the 1.13.0 tag.

    Documentation 
    opened by sk33z3r 14
  • Display current value in chart.

    Display current value in chart.

    Is your feature request related to a problem? Please describe. I'm trying to display in a label on a bar chart for the current rendered value.

    Describe the solution you'd like A method to display the currently displayed value

    Describe alternatives you've considered I've tried to use the label but it is not updating on each re render.

    enhancement 
    opened by MrCasCode 3
Releases(1.14.0)
  • 1.14.0(Apr 23, 2022)

    • Added AnsiArtPlayer and AsciinemaPlayer
    • Added dynamically sized, animated sprites to ray caster demo.
    • Added fit parameter to DropdownList.
    • Added support for default colours to AnsiTerminalParser
    • Added VBarChart renderer.
    • BREAKING VISUAL CHANGE: Frame now supports scroll bars without borders, to have no border and no scroll bar you now need Frame(has_border=False, can_scroll=False)
    • Added TextBox.hide_cursor and TextBox.auto_scroll properties
    • Added optional diameter parameter to ShootScreen.
    • Improved DropEmitter effect - will now typically take a little longer to clear the screen.
    • Fixed bug in widget focus - eliminated duplicate events and some cases that failed to move focus
    • Fixed bug in clear_widgets() - also reset any focus in the layout.
    • Fixed bug: layout could still be a tab stop with no active widgets.
    Source code(tar.gz)
    Source code(zip)
  • 1.13.0(Apr 5, 2021)

    • Added ability to change a Button's text through a .text attribute.
    • Added ability to accept a name attribute in the Button and Label constructors.
    • Added ability to detect job pause/resume and force full screen refresh.
    • Added ability to request terminal default colours using Screen.COLOUR_DEFAULT.
    • Converted widgets to a sub-package.
    • Fixed issue with labels in a layout column preventing buttons from being pressed.
    • Fixed issue with visual overrun on Listboxes when there is a label offset.
    • Fixed issue with TextBox hitting IndexError in double buffers due to lack of clipping.
    • Fixed issue with Text/TextBox start columns on reset.
    • Added troubleshooting on terminal colour handling.
    Source code(tar.gz)
    Source code(zip)
  • 1.12.0(Nov 15, 2020)

    • Added ColouredText objects to handle embedded colour codes in text for some widgets.
    • Added parsers to handle Asciimatics and Ansi Terminal escape sequences.
    • Added ControlCodeParser to create human readable text from raw text with control codes in it.
    • Added readonly logic for Text and TextBox.
    • Added ability to enable/disable widgets by column in layouts.
    • Added left/right/up/down navigation to nearest widget.
    • Added ability to scroll screen/canvas by variable number of lines.
    • Created terminal demo
    • Fixed exception on reinstating NoneType signal handler.
    • Fixed float/int issue with recent builds of pywin32.
    • Fixed issue where setting options changed the selected value (even if it was still present).
    • Fixed erroneous trigger of on_load for all Frames at start of day.
    • Fixed bug where Frames passed on events that they already handled.
    • Fixed bug: Restore current theme on screen resize.
    • Fixed bug in scrolling the screen up.
    Source code(tar.gz)
    Source code(zip)
  • 1.11.0(May 10, 2019)

    Added allow_int parameter to Screen.play(). Added max_length parameter to Text. Added support for page up/down in TextBox. Added optional scroll bars to MultiColumnListBox. Added file_filter parameter to FileBrowser. Added wait_for_input method to Screen. Added optional theme parameter to PopupDialog. Added optional jitter parameter to Noise. Added ManagedScreen decorator. Improved performance of double-buffering.

    • NOTE: Drawing off-screen with a large scrolling buffer is no longer supported (as it wasn't needed).

    Added optional pattern parameter to Stars. Improved handling of permission errors in FileBrowser. Added formal support for defining your own colour theme. Added clear_widgets to Layout objects. Fixed height of PopUpDialog when no buttons are specified. Fixed bug where asciimatics Scenes would hang when the clock is moved back in time. Fixed off-by-one error in BarChart labels. Fixed bug where Labels ignored the custom_colour property. Added default date and time to DatePicker and TimePicker when no value specified.

    Source code(tar.gz)
    Source code(zip)
  • 1.10.0(Sep 18, 2018)

    • Added 'Frame.focussed_widget' to access current focussed widget of the frame.
    • Added PopupMenu for dynamic contextual menus.
    • Added DropdownList widget.
    • Added VerticalDivider widget.
    • Added optional scroll bar to Listboxes.
    • Added line_wrap option to TextBoxes.
    • Added line_char option to Dividers.
    • Added align option to Labels.
    • Added width property to widgets.
    • Added set_theme to Frames and provided some new colour schemes.
    • Fixed Screen.wrapper() to return result from wrapped function.
    • Fixed list box truncation when lines are too long.
    • Fixed issue with background colour when scrolling GNOME terminal.
    • Fixed Text validator to support instance methods.
    • Fixed exception raised by getdefaultlocale on some curses systems.
    • Performance tweaks for non-unicode widgets.
    • Relaxed restriction on static function callbacks for pop-up dialogs.
    • Fixed bug where Listbox.reset() overrode current selected value.
    • Fixed handling of decomposed unicode file names in FileBrowser for MacOS
    • Fixed CJK issues with Screen.paint() and SpeechBubble.
    • Fixed issue with dynamically added Frames so that they are reset before displayed for the first time.
    Source code(tar.gz)
    Source code(zip)
  • 1.9.0(Dec 6, 2017)

    • Added FileBrowser, DatePicker and TimePicker widgets.

      • Made screen a mandatory positional parameter to all Effects in the process.
      • NOTE: Any custom Effects you have created will now need to pass the screen down to the parent class.
    • Added fill_polygon() to Screen and Canvas.

    • Added the Kaleidoscope and RotatedDuplicate renderers.

    • Created Maps demo - which renders vector tiles and satellite images from Mapbox.

    • Added optional is_modal parameter to Frame constructor.

    • Added on_blur and on_focus parameters to all interactive Widgets.

    • Added colour property to Cogs Effect.

    • Added title property to Frame.

    • Added text property to Label.

    • Added hide_char parameter to Text constructor to hide any entered text - e.g. for passwords.

    • Added optional height parameter to Label constructor.

    • Allowed programs to set "default" values for Widgets - which means you need to reset each field in a Frame explicitly rather than relying on reset to blank out uninitialized fields.

    • Fixed up signal handling to re-instate old handlers on Screen.close().

    • Fixed missing on_select handler for ListBox.

    Source code(tar.gz)
    Source code(zip)
  • 1.7.2(Aug 15, 2017)

  • 1.7.1(Aug 15, 2017)

CalcuPy 📚 Create console-based calculators in a few lines of code.

CalcuPy 📚 Create console-based calculators in a few lines of code. 📌 Installation pip install calcupy 📌 Usage from calcupy import Calculator calc

Dylan Tintenfich 7 Dec 01, 2021
Terminalcmd - a Python library which can help you to make your own terminal program with high-intellegence instruments

Terminalcmd - a Python library which can help you to make your own terminal program with high-intellegence instruments, that will make your code clear and readable.

Dallas 0 Jun 19, 2022
Rich is a Python library for rich text and beautiful formatting in the terminal.

Rich 中文 readme • lengua española readme • Läs på svenska Rich is a Python library for rich text and beautiful formatting in the terminal. The Rich API

Will McGugan 41.4k Jan 02, 2023
Python composable command line interface toolkit

$ click_ Click is a Python package for creating beautiful command line interfaces in a composable way with as little code as necessary. It's the "Comm

The Pallets Projects 13.3k Dec 31, 2022
Python and tab completion, better together.

argcomplete - Bash tab completion for argparse Tab complete all the things! Argcomplete provides easy, extensible command line tab completion of argum

Andrey Kislyuk 1.1k Jan 08, 2023
A CLI tool to build beautiful command-line interfaces with type validation.

Piou A CLI tool to build beautiful command-line interfaces with type validation. It is as simple as from piou import Cli, Option cli = Cli(descriptio

Julien Brayere 310 Dec 07, 2022
prompt_toolkit is a library for building powerful interactive command line applications in Python.

Python Prompt Toolkit prompt_toolkit is a library for building powerful interactive command line applications in Python. Read the documentation on rea

prompt-toolkit 8.1k Jan 04, 2023
Python Command-line Application Tools

Clint: Python Command-line Interface Tools Clint is a module filled with a set of awesome tools for developing commandline applications. C ommand L in

Kenneth Reitz Archive 82 Dec 28, 2022
Library for building powerful interactive command line applications in Python

Python Prompt Toolkit prompt_toolkit is a library for building powerful interactive command line applications in Python. Read the documentation on rea

prompt-toolkit 8.1k Dec 30, 2022
Python library that measures the width of unicode strings rendered to a terminal

Introduction This library is mainly for CLI programs that carefully produce output for Terminals, or make pretend to be an emulator. Problem Statement

Jeff Quast 305 Dec 25, 2022
Cement is an advanced Application Framework for Python, with a primary focus on CLI

Cement Framework Cement is an advanced Application Framework for Python, with a primary focus on Command Line Interfaces (CLI). Its goal is to introdu

Data Folk Labs, LLC 1.1k Dec 31, 2022
A simple terminal Christmas tree made with Python

Python Christmas Tree A simple CLI Christmas tree made with Python Installation Just clone the repository and run $ python terminal_tree.py More opti

Francisco B. 64 Dec 27, 2022
Color text streams with a polished command line interface

colout(1) -- Color Up Arbitrary Command Output Synopsis colout [-h] [-r RESOURCE] colout [-g] [-c] [-l min,max] [-a] [-t] [-T DIR] [-P DIR] [-d COLORM

nojhan 1.1k Dec 21, 2022
Corgy allows you to create a command line interface in Python, without worrying about boilerplate code

corgy Elegant command line parsing for Python. Corgy allows you to create a command line interface in Python, without worrying about boilerplate code.

Jayanth Koushik 7 Nov 17, 2022
Clint is a module filled with a set of awesome tools for developing commandline applications.

Clint: Python Command-line Interface Tools Clint is a module filled with a set of awesome tools for developing commandline applications. C ommand L in

Kenneth Reitz Archive 82 Dec 28, 2022
Pythonic command line arguments parser, that will make you smile

docopt creates beautiful command-line interfaces Video introduction to docopt: PyCon UK 2012: Create *beautiful* command-line interfaces with Python N

7.7k Dec 30, 2022
Textual is a TUI (Text User Interface) framework for Python using Rich as a renderer.

Textual is a TUI (Text User Interface) framework for Python using Rich as a renderer. The end goal is to be able to rapidly create rich termin

Will McGugan 17k Jan 02, 2023
Cleo allows you to create beautiful and testable command-line interfaces.

Cleo Create beautiful and testable command-line interfaces. Cleo is mostly a higher level wrapper for CliKit, so a lot of the components and utilities

Sébastien Eustace 984 Jan 02, 2023
A fast, stateless http slash commands framework for scale. Built by the Crunchy bot team.

Roid 🤖 A fast, stateless http slash commands framework for scale. Built by the Crunchy bot team. 🚀 Installation You can install roid in it's default

Harrison Burt 7 Aug 09, 2022
A cross platform package to do curses-like operations, plus higher level APIs and widgets to create text UIs and ASCII art animations

ASCIIMATICS Asciimatics is a package to help people create full-screen text UIs (from interactive forms to ASCII animations) on any platform. It is li

3.2k Jan 09, 2023