Package: tanmatsu
:~^:.:YJ?!.Y&J?^%@@P!:GG&!~@@&:.PGP?B@&~.!@@%:&@J^@@?.#@B.G@#^!.!@@%!^:&@?^@@?#@G:%~~~~~~~~~~~~~~^B@#~^~~~~~~~~~Y@@#Y^~?!!!J@@Y~Y&&P^.&@&~!!!?&@&!!!!!&@B:!!~~~~~~~~~~~~~~B@&~~~~~~~~~~~~~~~!^:~^:^::::%Y?%~.:@@J::::::::::::^PBYG@#:&&@@?:.:%%:......^PG?:G@#.?~PGB@&JJ%%%%%%?B#G?%%%%%J&&&J:^?!!~~~~~~~~~~B@&!~~~~~~~%B@@B%.~@P:@&:%@B^.!~^^^^^^^^^P@@@&G!^^^^^^^^^^^~..#@??@J:&?^:::^#&:.:..::::JP?^:G@G#@#~P%P@GG#..&@P!!%#@Y!!Y&#%!!%@@&%.Y@&?G@#:PB!Y@!^&~::.#@J.&@%!@&.#@%.J&&J.G@#.%##J:..YB%??!..#@J.#@%%@&..#@%^Y#B%.G@#..?#@G?^..^!?&GGJ!:.#@J.#@%%@&..#@%.%PBY^B@#..%G@@#PJ!~^..P&&#&%^.&@J.&@%%@&:#@%.~J&J~B@#.^JB@@@#J^~#!:&@J.&@??@@^~!%&@%^?!^.#@&.:!J^:#&??J^^J?..:P#P!B@#:^GGGGGG^%P~..%P!?P^?Y~.Y&:?P^?GGGGGG:.^YPPJ^.&Y%P~.~!@@%~:.&@GB@@~P@!G@L:Y@@~:@@P^~&G&~^!@B~!&@^:B&.&B%#&.J@%@~B@@#.&@!G@@A/@@@~Y@@%.Y@%!@G^.^/:B#.&B%.#&:.&!^&GB@Y&.P@!G@#B@&PG@~:@<^G%Y@%\&BBG%:B#.&B%.#&:J@!#@~B@!!@@@!G@^\J@^G@~Y@!&@:Y@%.:.B@~:B#&B%.&@:.&&%%?@GB@%J@@!G@~^/G@~:@#%^J@%Y@%%@P~~J@^.#B%~B@~.PP.!B?&G:?B~&G~YG^YG^%B%&P.!B?%PBG&~:YGBP!AboutDeclarative TUI (Terminal User Interface) library, with layout features modelled after modern web components.Widget objects can be created by defining a class that inherits from the desired widget class.For example, a CSS flexbox-style widget that contains a text box and a button can be created declaratively, like so:classNiceFlexBox(widgets.FlexBox):text_box=widgets.TextBox(text="Hello World!")button=widgets.Button(label="Button 2",callback=None)classMeta:border_label="Nice FlexBox"nice_flex_box=NiceFlexBox()or imperatively, like so:children={'text_box':widgets.TextBox(text="Hello World!"),'button':widgets.Button(label="Button 2",callback=None)}nice_flex_box=widgets.FlexBox(children=children,border_label="Nice FlexBox")Tanmatsu supports either style. The declarative syntax should be familiar with anyone who's used Django models before.Examplewhich is given by the code:fromtanmatsuimportTanmatsu,widgetsclassButtonList(widgets.List):classMeta:border_label="List"children=[widgets.Button(label="Button 1",callback=None),widgets.Button(label="Button 2",callback=None),widgets.Button(label="Button 3",callback=None),]item_height=5classVertSplit(widgets.FlexBox):text_box=widgets.TextBox(border_label="Text Box",text="Hello World!")text_log=widgets.TextLog(border_label="Text Log")button_list=ButtonList()classMeta:flex_direction=widgets.FlexBox.HORIZONTALwithTanmatsu(title="Tanmatsu!")ast:rw=VertSplit()t.set_root_widget(rw)for(i,v)inenumerate(rw.button_list.children):v.callback=lambdai=i:rw.text_log.append_line(f"Button{i+1}pressed")t.loop()Installationpip install tanmatsuDocumentationhttps://tanmatsu.readthedocs.io/en/latest/RequirementsPython >=3.11GNU/LinuxFull-featured terminal emulator (e.g., Gnome VTE)A font with unicode symbols (e.g.,Noto)Dependenciestri.declarativeparsywcwidthDevelopment dependancies:sphinxDevelopmentInstallingIf not running python 3.11, installpyenv.Installpoetry.Runpoetry installfrom the repository directory to set up a virtual environment with the necessary python version and packagesRunningpoetry run python3 main.pyTestingpoetry run python3 -m unittestChangelogSeeCHANGELOG.md.LicenseMIT. For more information, seeLICENSE.md.