Python TUI framework with mouse support, modular widget system, customizable and rapid terminal markup language and more!
This version adds graceful color degradation, which (to my knowledge), makes us one of the first terminal libraries to do so, but definitely the first in our specific niche!
This is all done automatically, using the newly-rehomed Terminal
class and its instance. Essentially, every time a color is created through TIM
, the new str_to_color
method is called, which will by default localize all output colors. During this localization the xterm-standard HEX value for the given color is found, and that is then used to create a new color in the terminal's color space.
For example, lets say you have an RGB color of 000;111;222
, but your terminal only supports the xterm-256
palette. PyTermGUI will, under the hood, determine the RGB value of this color, and get the weighted difference between it and and all known palette colors. Once that is done it will find the closest match, create an IndexedColor
with the newly found index and return that back to TIM.
Now this all sounds very computationally complicated, which it is. Thus, there are a couple of simple "caches" inside the new colors
module. The first one caches all input given to str_to_color
with its corresponding output, and the second one saves all input and output of the aforementioned color matching. Because of this, my machine shows only a sub-1 ms difference of frametime parsing a true-color and 16-color representation of the same, complicated markup frame (namely, ptg -m
).
Additionally, there is now a really robust implementation of the https://no-color.org standard! Unlike pretty much all modules, we don't just completely omit colors, rather we calculate each color's brightness and then assign a value to them in the xterm-256
greyscale range, thereby retaining most of the contrast, the ability to set background colors and more. You can see some demos of this further down the page.
Color
layer (5053603026289d784dd9136c7114606e258c3e4e)terminal
(f26580732923fc71cded2347acafc1830d2e84c0)UserDict
and UserList
(35e789c978b51b37d70f89c3f455314bc8f36314)NO_COLOR
using greyscale ramps (0cdf71209ac6f46fba28dc52729fbfae1e4e2da4)colors
module with color types for all terminal colors (f26580732923fc71cded2347acafc1830d2e84c0)terminal
to its own module (5aeb397c0f9037a3338d76e554795e7c2d23be30)[
sometimes being ommitted during prettify_markup
(a2defd8f486371ee993bce689e697787a03563b2)The same HSL to RGB color palette printed by
TIM
, with onlyterminal.forced_colorspace
being changed between runs.
ptg
ran withNO_COLOR=1
as an environment variable.
This update is focused on the brand-spanking new StyleManager
API. Previously, styles were "managed" as a single dictionary, which while simple and robust, was very limited, ugly and in general not the best. This was a leftover design decision from even before TIM
was an idea, just to put its age into perspective.
The new API allows users to use JS-like dotted syntax, such as Container.styles.border = "60 bold"
to achieve what was previously Container.set_style("border", MarkupFormatter("[60 bold]{item}")
. As you could notice, the given values are also much simpler now: Anything that is not already a StyleCall
will be converted into one, and if the passed value was a string with no valid markup it will be parsed into [{{passed_value}}]{item}
. You can also set multiple styles at one time, using "__" (double underscore) character to separate them.
Getters are also the same way. Instead of a private Container._get_style("border")
call, one can now use Container.styles.border
. It also returns an already instantiated StyleCall
, unlike the previous API which created them on every new call.
Best of all, the old API remains to work! I wouldn't bet on this continuing forever, so all new code should be written using the new version. If it does ever get removed I'll be sure to make it very obvious and loud.
StyleManager
class & API (e4c0036c4546c10289c62a65fa1d6d7fe085cebb)Container.debug
to shorten itself & use type(self)
(e8ccd35d67f1bad22caf39f0c870436f87b7fa89)ptg -g
(a86e5915bf34a9d237136df77af92b05016b8d48)ESC
not being outputted in ptg -g
(661e5ce818d3a170012c6c039fb1690598280693)
There happened to be some minor issues in the previous version, but they should be fixed now.
Markapp
(524d9199a5bd026b44bb37f35f2f7cc621221c08)inspect
(418812492e298f0e5fbce2122f72561afd215d10)inspect-identifier
markup alias (319be785350a76ff1742002dc83820f5eb9d30ac)This release focuses on the brand new inspector capabilities of the module. More information about them can be found in the inspector documentation.
Items marked in bold are API breaking changes.
Inspector
widget and inspect
helper function
Container.lazy_add
method to expose _add_widget(..., run_get_lines=False)
prettify
to new submodule prettifiers
& improve its behaviour
is_interactive
under terminal
MarkupLanguage context manager in favor of a
print method
MarkupLanguage.pprint
getch
call on WindowsThis release is mostly for fixing a couple of annoying issues that came up in the last release, as well as to update the README. The biggest new "change" is the introduction of TIM
, PyTermGUI's markup language. It stands for Terminal Inline Markup, and is analogous to the previous markup
name (so much so that the latter is still provided as a reference to the same instance).
markup
→ tim
, but keeping the original name for backward-compatibility (aa79c43fee45634022dec8e47f1e9f5ed79556e9)animators
→ animations
, expose Animation
and CustomAnimation
classes (12f53ddfbddea21158e21263c61a906735729b01)TIM
macros not being colored correctly in MarkupLanguage.prettify_markup
(aa79c43fee45634022dec8e47f1e9f5ed79556e9)ptg --version
not functioning on PyPi installs (e27185779c8e28928acbd0d8352f5735414f22e1)
:moon:
:rocket:
:fire:
ptg -v
does not work on PyPi installs in this version. This was already fixed in (e27185779c8e28928acbd0d8352f5735414f22e1), but I didn't deem that one fix to be worthy of a full bugfix patch.
This version mostly focused on adding some nice utilities while improving the old ones. Before that however, I want take a second to mention how the library grew almost 300 stars in 2 days. I am immensely grateful for the exposure my project is getting, and I can't wait to see it in the wild!
Things to point out:
pretty
module: This is a very simple module that allows setting up displayhook with only one line in the REPLKeyboardButton
widget: This allows keyboard mnemonics inside PTG.!rainbow
and !gradient
macros: These are very pretty and fancy looking.parser documentation
(933729e98142039ae601bc3eecebfb60e39882db)IPython
display hook support (caa7c748f51019166b01ea163cb6d2f77fb537b5)MarkupLanguage.parse
(7f49087a747fb3d7189f09a598c29313c340e1cc)Window.is_modal
not being applied properly since a mouse handling refactor (c1d36190d20cbcefcae8c91181d2d2d4de37c269)KeyboardButton
widget (a1a0dadfb6243981c2a7bdd4f57048a87c41bef0, c495dd0d4d6a173a2ad9e031d003a17eb080123d)non_first_padding
to Label
(c630e6f9aff2dbc688197ab9866657ef04d70f8b)box
in Container
constructor (88536be5035e83ed7ad4c4b2de4980bd2c85a559)pretty
module for quick displayhook setup (48fb0dfde9742328603e26950deca657ad483299)!rainbow
and !gradient
macros (bc0e0911a14922111a429aa153e4ebc8ff4aa394)
This is a relatively minor release, mostly focused on the new pretty-printing functionality. I wanted to release this before the next major update, as that may take some time and these features are really useful in their own right.
The new MarkupLanguage.prettify
method is quite customizable: It allows you to customize all of the builtin styles it uses, as well as set indentation count, force ANSI sequences to be displayed as markup or force data-structures to be displayed flat (condensed). The default style looks really good in my opinion, and it should be a very useful tool.
Obviously, the idea was inspired by Rich's implementation of the same concept, but I tried to fix all my grievances with that version.
Terminal.pixel_size
attribute (6e350b182849a7ba062c97aa1a55628f5c9e78cd, ce27e3cde131e66a99085cc58ba7cf39f7bb14c8)prettify_ansi,
pprintand
setup_displayhook()methods to
MarkupLanguage`` (5bdf6177b28eb7fcd6475ee1b402b6b79eb671ba)Here is a quick demo of some of the prettifying functionality.
This version mostly focused on improving already built features, but there is a lot of important additions as well.
The most notable new change would probably be the PixelMatrix
classes. These allow you to display an arbitrary matrix of pixels as a widget. DensePixelMatrix
scales the entire widget down by a factor of 4 (in normal PixelMatrix
, every pixel is made up of 2 block characters. In DensePixelMatrix
all pixels make up only half a block.
This would normally not constitute for a major release, however the Slider
refactor forced our hand. Some parts of its API have changed, though mostly for the better.
Items marked in bold are API breaking changes.
Slider
widget (788a709e2a3326fb725bf8600aa3d208a12b5874, #9)Button
default chars (f370deaedd88f52c5008fcfe0a5ff1ae7efdf2c9)WindowManager.framerate
120 -> 60 (320d65c1c6988a727e724674d7dd16da0d8dcc5c)MarkupLanguage.prettify_markup
(d6733f5dc02817e8be1cadde17f2bb9ee94a4b94)WindowManager.nullify_cache
& Window.nullify_cache
(814d2055e89e40256fea1e9f9e7d7347b697c0f7)!link
markup macro (0c05080928a5e9a6e65ba3d4148e0b794b556852)StyledText
class (be2f5dec466d84458e376af5ea7e428920733247)ColorPicker
widget, CLI app (5a09f43b950414e231ac0ebf85f5db17499d3785, 45b6d02d46c3eea30b2c4cabb96cd08cff3f688a)PixelMatrix
& LargePixelMatrix
widgets (84312c16a399c9e58c070c04d23d397610895aca)Window._auto_min_width
disregarding sidelength (8b51ff0822f8e471f55bfeb1186fb8659cfd543f)Container._update_width
(363093aa3812bad4bb92250c7900a0f9d7258f80)
This version brings an implementation of animations to the library. The new Animator
class is tasked with controlling & updating a list of Animation
instances. Animations work using time-elapsed since instantiation, and animate an integer field going from one value to another.
Container._centered_axis
public (0304aca4b94517648b46bcf68e3ae4a18f1e0b68)
Overflow.HIDE
only hiding entire widgets (4289a5c6bd5df535a43053173179bc9f3ec0526f)getch
application growing in height indefinitely (ea5b721248f6c599a6c795a34bd1dae5608eb565)Here is a showcase of the already-implemented animations in WindowManager
, using the ptg
CLI environment.