urwid 4.0.3__tar.gz → 4.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {urwid-4.0.3 → urwid-4.0.4}/PKG-INFO +1 -1
- {urwid-4.0.3 → urwid-4.0.4}/docs/changelog.rst +22 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/bigtext.py +1 -1
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/graph.py +40 -25
- {urwid-4.0.3 → urwid-4.0.4/docs}/examples/pop_up.py +3 -3
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/real_browse.py +7 -7
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/real_edit.py +4 -4
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/tour.py +3 -3
- {urwid-4.0.3 → urwid-4.0.4}/examples/bigtext.py +1 -1
- {urwid-4.0.3 → urwid-4.0.4}/examples/browse.py +7 -7
- {urwid-4.0.3 → urwid-4.0.4}/examples/calc.py +40 -29
- {urwid-4.0.3 → urwid-4.0.4}/examples/edit.py +4 -4
- {urwid-4.0.3 → urwid-4.0.4}/examples/fib.py +2 -2
- {urwid-4.0.3 → urwid-4.0.4}/examples/graph.py +40 -25
- {urwid-4.0.3 → urwid-4.0.4}/examples/input_test.py +2 -2
- {urwid-4.0.3/docs → urwid-4.0.4}/examples/pop_up.py +3 -3
- {urwid-4.0.3 → urwid-4.0.4}/examples/terminal.py +3 -3
- {urwid-4.0.3 → urwid-4.0.4}/examples/tour.py +3 -3
- {urwid-4.0.3 → urwid-4.0.4}/examples/treesample.py +15 -8
- urwid-4.0.4/pylint-requirements.txt +1 -0
- {urwid-4.0.3 → urwid-4.0.4}/pyproject.toml +7 -1
- urwid-4.0.4/ruff-requirements.txt +1 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_tree.py +2 -2
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_vterm.py +145 -35
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/common.py +2 -3
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/web.py +1 -1
- {urwid-4.0.3 → urwid-4.0.4}/urwid/event_loop/main_loop.py +8 -4
- {urwid-4.0.3 → urwid-4.0.4}/urwid/util.py +1 -1
- {urwid-4.0.3 → urwid-4.0.4}/urwid/version.py +3 -3
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/big_text.py +0 -1
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/box_adapter.py +5 -2
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/columns.py +39 -30
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/container.py +8 -2
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/frame.py +26 -22
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/line_box.py +8 -5
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/listbox.py +8 -7
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/monitored_list.py +8 -3
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/padding.py +84 -26
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/popup.py +6 -2
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/treetools.py +32 -19
- {urwid-4.0.3 → urwid-4.0.4}/urwid.egg-info/PKG-INFO +1 -1
- urwid-4.0.4/urwid.egg-info/scm_version.json +8 -0
- urwid-4.0.3/pylint-requirements.txt +0 -1
- urwid-4.0.3/ruff-requirements.txt +0 -1
- urwid-4.0.3/urwid.egg-info/scm_version.json +0 -8
- {urwid-4.0.3 → urwid-4.0.4}/.coveralls.yml +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.devcontainer/dev.dockerfile +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.devcontainer/devcontainer.json +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.dockerignore +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.editorconfig +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/CODE_OF_CONDUCT.md +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/ISSUE_TEMPLATE/docs.md +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/dependabot.yml +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/labeler.yml +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/release.yml +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/workflows/documentation.yml +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/workflows/isolated_static_check.yml +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/workflows/labels.yml +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/workflows/pythonpackage.yml +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.github/workflows/yamllint.yml +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.gitignore +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.pre-commit-config.yaml +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/.yamllint.yml +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/COPYING +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/MANIFEST.in +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/README.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/SECURITY.md +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/classifiers.txt +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/Makefile +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/conf.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/bigtext.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/bigtext1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/bigtext2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/bigtext3.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/browse.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/browse.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/browse1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/browse2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/edit.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/edit.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/edit1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/edit2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/edit_text.txt +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/graph.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/graph1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/graph2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/index.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/palette_test.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/palette_test.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/palette_test1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/palette_test2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/pop_up.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/pop_up1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/pop_up2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/subproc.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/subproc.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/subproc1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/subproc2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/subproc2.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/tour.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/tour1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/examples/tour2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/index.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/bright_combinations.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/bright_combinations.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/bright_combinations1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/canvascache.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/displayattributes.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/displaymodules.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/encodings.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/images/display_modules.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/images/introduction.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/images/urwid_widgets.svgz +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/images/urwid_widgets_1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/images/urwid_widgets_1.xcf +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/images/urwid_widgets_2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/images/urwid_widgets_2.xcf +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/images/widget_layout.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/index.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/mainloop.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/overview.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/safe_combinations.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/safe_combinations.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/safe_combinations1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/textlayout.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/userinput.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/wanat.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/wanat_multi.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/wcur1.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/wcur2.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/widgets.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/wmod.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/manual/wsel.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/attrspec.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/canvas.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/command_map.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/constants.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/deprecated.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/display_modules.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/exceptions.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/global_settings.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/index.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/list_walkers.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/main_loop.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/meta.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/signals.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/text_layout.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/reference/widget.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tools/compile_pngs.sh +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tools/screenshots.sh +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tools/static/.placeholder +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tools/templates/indexcontent.html +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tools/templates/indexsidebar.html +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tools/templates/localtoc.html +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/adventure.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/adventure.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/adventure1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/adventure2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/adventure3.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/adventure4.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/cmenu.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/cmenu.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/cmenu1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/cmenu2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/cmenu3.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/cmenu4.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/highcolors.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/highcolors.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/highcolors1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/hmenu.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/hmenu.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/hmenu1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/hmenu2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/hmenu3.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/hmenu4.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/index.rst +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/input.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/input.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/input1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/input2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/input3.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/input4.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/input5.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/menu25.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/minimal.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/minimal.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/minimal1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/multiple.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/multiple.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/multiple1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/multiple2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/multiple3.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/multiple4.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/qa.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/qa.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/qa1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/qa2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/qa3.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/sig.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/sig.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/sig1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/sig2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/sig3.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/sig4.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/smenu.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/smenu.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/smenu1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/smenu2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/smenu3.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/urwid_attr.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/urwid_attr.py.xdotool +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/urwid_attr1.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/urwid_attr2.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/urwid_attr3.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/tutorial/urwid_attr4.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/docs/urwid-logo.png +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/examples/asyncio_socket_server.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/examples/dialog.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/examples/lcd_cf635.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/examples/palette_test.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/examples/subproc.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/examples/subproc2.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/examples/twisted_serve_ssh.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/examples/twisted_serve_ssh.tac +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/requirements.txt +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/setup.cfg +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/test_requirements.txt +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/__init__.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_canvas.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_columns.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_container.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_doctests.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_escapes.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_event_loops.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_filler.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_floatedit.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_font.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_frame.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_grapheme_clusters.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_graphics.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_grid_flow.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_line_box.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_listbox.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_main_loop.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_overlay.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_padding.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_pile.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_raw_display.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_scrollable.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_signals.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_str_util.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_text_layout.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_util.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/test_widget.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tests/util.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/tox.ini +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/__init__.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/canvas.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/command_map.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/__init__.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/_posix_raw_display.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/_raw_display_base.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/_web.css +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/_web.js +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/_win32.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/_win32_raw_display.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/curses.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/escape.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/html_fragment.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/lcd.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/display/raw.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/event_loop/__init__.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/event_loop/abstract_loop.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/event_loop/asyncio_loop.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/event_loop/glib_loop.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/event_loop/select_loop.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/event_loop/tornado_loop.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/event_loop/trio_loop.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/event_loop/twisted_loop.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/event_loop/zmq_loop.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/font.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/graphics.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/numedit.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/py.typed +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/signals.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/split_repr.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/str_util.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/text_layout.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/vterm.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/__init__.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/attr_map.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/attr_wrap.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/bar_graph.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/constants.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/divider.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/edit.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/filler.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/grid_flow.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/overlay.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/pile.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/progress_bar.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/scrollable.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/solid_fill.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/text.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/widget.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/widget_decoration.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid/widget/wimp.py +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid.egg-info/SOURCES.txt +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid.egg-info/dependency_links.txt +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid.egg-info/not-zip-safe +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid.egg-info/requires.txt +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid.egg-info/scm_file_list.json +0 -0
- {urwid-4.0.3 → urwid-4.0.4}/urwid.egg-info/top_level.txt +0 -0
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
---------
|
|
4
4
|
|
|
5
|
+
Urwid 4.0.4
|
|
6
|
+
===========
|
|
7
|
+
|
|
8
|
+
2026-07-13
|
|
9
|
+
|
|
10
|
+
New features 🗹
|
|
11
|
+
+++++++++++++++
|
|
12
|
+
* urwid.Colmns: re-calculate column_widths only if pack widgets changed by @penguinolog in https://github.com/urwid/urwid/pull/1178
|
|
13
|
+
Bug fixes 🕷
|
|
14
|
+
++++++++++++
|
|
15
|
+
* Fix IndexError in decompose_tagmarkup when a nested sublist is empty by @gaoflow in https://github.com/urwid/urwid/pull/1172
|
|
16
|
+
Documentation 🕮
|
|
17
|
+
++++++++++++++++
|
|
18
|
+
* Typing: partially annotate examples and fix annotations by @penguinolog in https://github.com/urwid/urwid/pull/1173
|
|
19
|
+
* urwid.WidgetContainerMixin: return use protocol base class by @penguinolog in https://github.com/urwid/urwid/pull/1181
|
|
20
|
+
|
|
21
|
+
New Contributors
|
|
22
|
+
++++++++++++++++
|
|
23
|
+
* @gaoflow made their first contribution in https://github.com/urwid/urwid/pull/1172
|
|
24
|
+
|
|
25
|
+
**Full Changelog**: https://github.com/urwid/urwid/compare/4.0.3...4.0.4
|
|
26
|
+
|
|
5
27
|
Urwid 4.0.3
|
|
6
28
|
===========
|
|
7
29
|
|
|
@@ -48,7 +48,7 @@ class SwitchingPadding(urwid.Padding[_Wrapped]):
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
class BigTextDisplay:
|
|
51
|
-
palette: typing.ClassVar[list[tuple[str, str, str,
|
|
51
|
+
palette: typing.ClassVar[list[tuple[str, str, str] | tuple[str, str, str, str]]] = [
|
|
52
52
|
("body", "black", "light gray", "standout"),
|
|
53
53
|
("header", "white", "dark red", "bold"),
|
|
54
54
|
("button normal", "light gray", "dark blue", "standout"),
|
|
@@ -33,6 +33,9 @@ import typing
|
|
|
33
33
|
|
|
34
34
|
import urwid
|
|
35
35
|
|
|
36
|
+
if typing.TYPE_CHECKING:
|
|
37
|
+
from collections.abc import Callable
|
|
38
|
+
|
|
36
39
|
UPDATE_INTERVAL = 0.2
|
|
37
40
|
|
|
38
41
|
|
|
@@ -52,7 +55,7 @@ class GraphModel:
|
|
|
52
55
|
|
|
53
56
|
data_max_value = 100
|
|
54
57
|
|
|
55
|
-
def __init__(self):
|
|
58
|
+
def __init__(self) -> None:
|
|
56
59
|
data = [
|
|
57
60
|
("Saw", list(range(0, 100, 2)) * 2),
|
|
58
61
|
("Square", [0] * 30 + [100] * 30),
|
|
@@ -66,13 +69,13 @@ class GraphModel:
|
|
|
66
69
|
self.modes.append(m)
|
|
67
70
|
self.data[m] = d
|
|
68
71
|
|
|
69
|
-
def get_modes(self):
|
|
72
|
+
def get_modes(self) -> list[str]:
|
|
70
73
|
return self.modes
|
|
71
74
|
|
|
72
|
-
def set_mode(self, m) -> None:
|
|
75
|
+
def set_mode(self, m: str) -> None:
|
|
73
76
|
self.current_mode = m
|
|
74
77
|
|
|
75
|
-
def get_data(self, offset, r):
|
|
78
|
+
def get_data(self, offset: int, r):
|
|
76
79
|
"""
|
|
77
80
|
Return the data in [offset:offset+r], the maximum value
|
|
78
81
|
for items returned, and the offset at which the data
|
|
@@ -95,7 +98,7 @@ class GraphView(urwid.WidgetWrap):
|
|
|
95
98
|
graph display.
|
|
96
99
|
"""
|
|
97
100
|
|
|
98
|
-
palette: typing.ClassVar[tuple[str, str, str,
|
|
101
|
+
palette: typing.ClassVar[list[tuple[str, str, str] | tuple[str, str, str, str]]] = [
|
|
99
102
|
("body", "black", "light gray", "standout"),
|
|
100
103
|
("header", "white", "dark red", "bold"),
|
|
101
104
|
("screen edge", "light blue", "dark cyan"),
|
|
@@ -118,7 +121,7 @@ class GraphView(urwid.WidgetWrap):
|
|
|
118
121
|
graph_num_bars = 5
|
|
119
122
|
graph_offset_per_second = 5
|
|
120
123
|
|
|
121
|
-
def __init__(self, controller):
|
|
124
|
+
def __init__(self, controller) -> None:
|
|
122
125
|
self.controller = controller
|
|
123
126
|
self.started = True
|
|
124
127
|
self.start_time = None
|
|
@@ -126,7 +129,7 @@ class GraphView(urwid.WidgetWrap):
|
|
|
126
129
|
self.last_offset = None
|
|
127
130
|
super().__init__(self.main_window())
|
|
128
131
|
|
|
129
|
-
def get_offset_now(self):
|
|
132
|
+
def get_offset_now(self) -> int:
|
|
130
133
|
if self.start_time is None:
|
|
131
134
|
return 0
|
|
132
135
|
if not self.started:
|
|
@@ -134,7 +137,7 @@ class GraphView(urwid.WidgetWrap):
|
|
|
134
137
|
tdelta = time.time() - self.start_time
|
|
135
138
|
return int(self.offset + (tdelta * self.graph_offset_per_second))
|
|
136
139
|
|
|
137
|
-
def update_graph(self, force_update=False):
|
|
140
|
+
def update_graph(self, force_update: bool = False) -> bool:
|
|
138
141
|
o = self.get_offset_now()
|
|
139
142
|
if o == self.last_offset and not force_update:
|
|
140
143
|
return False
|
|
@@ -164,32 +167,32 @@ class GraphView(urwid.WidgetWrap):
|
|
|
164
167
|
self.animate_progress.current = prog
|
|
165
168
|
return True
|
|
166
169
|
|
|
167
|
-
def on_animate_button(self, button):
|
|
170
|
+
def on_animate_button(self, button: urwid.AttrMap[urwid.Button]) -> None:
|
|
168
171
|
"""Toggle started state and button text."""
|
|
169
172
|
if self.started: # stop animation
|
|
170
|
-
button.
|
|
173
|
+
button.set_label("Start")
|
|
171
174
|
self.offset = self.get_offset_now()
|
|
172
175
|
self.started = False
|
|
173
176
|
self.controller.stop_animation()
|
|
174
177
|
else:
|
|
175
|
-
button.
|
|
178
|
+
button.set_label("Stop")
|
|
176
179
|
self.started = True
|
|
177
180
|
self.start_time = time.time()
|
|
178
181
|
self.controller.animate_graph()
|
|
179
182
|
|
|
180
|
-
def on_reset_button(self, w):
|
|
183
|
+
def on_reset_button(self, w: urwid.Button) -> None:
|
|
181
184
|
self.offset = 0
|
|
182
185
|
self.start_time = time.time()
|
|
183
186
|
self.update_graph(True)
|
|
184
187
|
|
|
185
|
-
def on_mode_button(self, button, state):
|
|
188
|
+
def on_mode_button(self, button: urwid.RadioButton, state: bool) -> None:
|
|
186
189
|
"""Notify the controller of a new mode setting."""
|
|
187
190
|
if state:
|
|
188
191
|
# The new mode is the label of the button
|
|
189
192
|
self.controller.set_mode(button.get_label())
|
|
190
193
|
self.last_offset = None
|
|
191
194
|
|
|
192
|
-
def on_mode_change(self, m):
|
|
195
|
+
def on_mode_change(self, m: str) -> None:
|
|
193
196
|
"""Handle external mode change by updating radio buttons."""
|
|
194
197
|
for rb in self.mode_buttons:
|
|
195
198
|
if rb.base_widget.label == m:
|
|
@@ -197,7 +200,7 @@ class GraphView(urwid.WidgetWrap):
|
|
|
197
200
|
break
|
|
198
201
|
self.last_offset = None
|
|
199
202
|
|
|
200
|
-
def on_unicode_checkbox(self, w, state):
|
|
203
|
+
def on_unicode_checkbox(self, w: urwid.CheckBox, state: bool) -> None:
|
|
201
204
|
self.graph = self.bar_graph(state)
|
|
202
205
|
self.graph_wrap._w = self.graph
|
|
203
206
|
self.animate_progress = self.progress_bar(state)
|
|
@@ -235,30 +238,42 @@ class GraphView(urwid.WidgetWrap):
|
|
|
235
238
|
)
|
|
236
239
|
return w
|
|
237
240
|
|
|
238
|
-
def bar_graph(self, smooth=False):
|
|
241
|
+
def bar_graph(self, smooth: bool = False) -> urwid.BarGraph:
|
|
239
242
|
satt = None
|
|
240
243
|
if smooth:
|
|
241
244
|
satt = {(1, 0): "bg 1 smooth", (2, 0): "bg 2 smooth"}
|
|
242
245
|
w = urwid.BarGraph(["bg background", "bg 1", "bg 2"], satt=satt)
|
|
243
246
|
return w
|
|
244
247
|
|
|
245
|
-
def button(
|
|
248
|
+
def button(
|
|
249
|
+
self,
|
|
250
|
+
t: str,
|
|
251
|
+
fn: Callable[[urwid.Button], None],
|
|
252
|
+
) -> urwid.AttrMap[urwid.Button]:
|
|
246
253
|
w = urwid.Button(t, fn)
|
|
247
254
|
w = urwid.AttrMap(w, "button normal", "button select")
|
|
248
255
|
return w
|
|
249
256
|
|
|
250
|
-
def radio_button(
|
|
257
|
+
def radio_button(
|
|
258
|
+
self,
|
|
259
|
+
g: list[urwid.RadioButton],
|
|
260
|
+
label: str,
|
|
261
|
+
fn: Callable[[urwid.RadioButton, bool], None],
|
|
262
|
+
) -> urwid.AttrMap[urwid.RadioButton]:
|
|
251
263
|
w = urwid.RadioButton(g, label, False, on_state_change=fn)
|
|
252
264
|
w = urwid.AttrMap(w, "button normal", "button select")
|
|
253
265
|
return w
|
|
254
266
|
|
|
255
|
-
def progress_bar(self, smooth=False):
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
267
|
+
def progress_bar(self, smooth: bool = False) -> urwid.ProgressBar:
|
|
268
|
+
return urwid.ProgressBar(
|
|
269
|
+
"pg normal",
|
|
270
|
+
"pg complete",
|
|
271
|
+
0,
|
|
272
|
+
1,
|
|
273
|
+
"pg smooth" if smooth else None,
|
|
274
|
+
)
|
|
260
275
|
|
|
261
|
-
def exit_program(self, w):
|
|
276
|
+
def exit_program(self, w) -> typing.NoReturn:
|
|
262
277
|
raise urwid.ExitMainLoop()
|
|
263
278
|
|
|
264
279
|
def graph_controls(self):
|
|
@@ -271,7 +286,7 @@ class GraphView(urwid.WidgetWrap):
|
|
|
271
286
|
self.mode_buttons.append(rb)
|
|
272
287
|
# setup animate button
|
|
273
288
|
self.animate_button = self.button("", self.on_animate_button)
|
|
274
|
-
self.on_animate_button(self.animate_button)
|
|
289
|
+
self.on_animate_button(self.animate_button.original_widget)
|
|
275
290
|
self.offset = 0
|
|
276
291
|
self.animate_progress = self.progress_bar()
|
|
277
292
|
animate_controls = urwid.GridFlow(
|
|
@@ -7,12 +7,12 @@ import typing
|
|
|
7
7
|
import urwid
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
class PopUpDialog(urwid.WidgetWrap):
|
|
10
|
+
class PopUpDialog(urwid.WidgetWrap[urwid.AttrMap[urwid.Filler[urwid.Pile]]]):
|
|
11
11
|
"""A dialog that appears with nothing but a close button"""
|
|
12
12
|
|
|
13
13
|
signals: typing.ClassVar[list[str]] = ["close"]
|
|
14
14
|
|
|
15
|
-
def __init__(self):
|
|
15
|
+
def __init__(self) -> None:
|
|
16
16
|
close_button = urwid.Button("that's pretty cool")
|
|
17
17
|
urwid.connect_signal(close_button, "click", lambda button: self._emit("close"))
|
|
18
18
|
pile = urwid.Pile(
|
|
@@ -24,7 +24,7 @@ class PopUpDialog(urwid.WidgetWrap):
|
|
|
24
24
|
super().__init__(urwid.AttrMap(urwid.Filler(pile), "popbg"))
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
class ThingWithAPopUp(urwid.PopUpLauncher):
|
|
27
|
+
class ThingWithAPopUp(urwid.PopUpLauncher[urwid.Button]):
|
|
28
28
|
def __init__(self) -> None:
|
|
29
29
|
super().__init__(urwid.Button("click-me"))
|
|
30
30
|
urwid.connect_signal(self.original_widget, "click", lambda button: self.open_pop_up())
|
|
@@ -178,9 +178,9 @@ class DirectoryNode(urwid.ParentNode):
|
|
|
178
178
|
parent.set_child_node(self.get_key(), self)
|
|
179
179
|
return parent
|
|
180
180
|
|
|
181
|
-
def load_child_keys(self):
|
|
182
|
-
dirs = []
|
|
183
|
-
files = []
|
|
181
|
+
def load_child_keys(self) -> list[str] | list[None]:
|
|
182
|
+
dirs: list[str] = []
|
|
183
|
+
files: list[str] = []
|
|
184
184
|
try:
|
|
185
185
|
path = self.get_value()
|
|
186
186
|
# separate dirs and files
|
|
@@ -207,7 +207,7 @@ class DirectoryNode(urwid.ParentNode):
|
|
|
207
207
|
keys = [None]
|
|
208
208
|
return keys
|
|
209
209
|
|
|
210
|
-
def load_child_node(self, key) -> EmptyNode | DirectoryNode | FileNode:
|
|
210
|
+
def load_child_node(self, key: Hashable) -> EmptyNode | DirectoryNode | FileNode:
|
|
211
211
|
"""Return either a FileNode or DirectoryNode"""
|
|
212
212
|
index = self.get_child_index(key)
|
|
213
213
|
if key is None:
|
|
@@ -225,11 +225,11 @@ class DirectoryNode(urwid.ParentNode):
|
|
|
225
225
|
|
|
226
226
|
|
|
227
227
|
class DirectoryBrowser:
|
|
228
|
-
palette: typing.ClassVar[list[tuple[str, str, str,
|
|
228
|
+
palette: typing.ClassVar[list[tuple[str, ...] | tuple[str, str, str, str]]] = [
|
|
229
229
|
("body", "black", "light gray"),
|
|
230
|
-
("flagged", "black", "dark green",
|
|
230
|
+
("flagged", "black", "dark green", "bold,underline"),
|
|
231
231
|
("focus", "light gray", "dark blue", "standout"),
|
|
232
|
-
("flagged focus", "yellow", "dark cyan",
|
|
232
|
+
("flagged focus", "yellow", "dark cyan", "bold,standout,underline"),
|
|
233
233
|
("head", "yellow", "black", "standout"),
|
|
234
234
|
("foot", "light gray", "black"),
|
|
235
235
|
("key", "light cyan", "black", "underline"),
|
|
@@ -51,10 +51,10 @@ class LineWalker(urwid.ListWalker):
|
|
|
51
51
|
if self.file is not None:
|
|
52
52
|
self.file.close()
|
|
53
53
|
|
|
54
|
-
def get_focus(self):
|
|
54
|
+
def get_focus(self) -> tuple[urwid.Edit, int] | tuple[None, None]:
|
|
55
55
|
return self._get_at_pos(self.focus)
|
|
56
56
|
|
|
57
|
-
def set_focus(self, focus) -> None:
|
|
57
|
+
def set_focus(self, focus: int) -> None:
|
|
58
58
|
self.focus = focus
|
|
59
59
|
self._modified()
|
|
60
60
|
|
|
@@ -145,7 +145,7 @@ class LineWalker(urwid.ListWalker):
|
|
|
145
145
|
|
|
146
146
|
|
|
147
147
|
class EditDisplay:
|
|
148
|
-
palette: typing.ClassVar[list[tuple[str, str, str,
|
|
148
|
+
palette: typing.ClassVar[list[tuple[str, str, str] | tuple[str, str, str, str]]] = [
|
|
149
149
|
("body", "default", "default"),
|
|
150
150
|
("foot", "dark cyan", "dark blue", "bold"),
|
|
151
151
|
("key", "light cyan", "dark blue", "underline"),
|
|
@@ -231,7 +231,7 @@ class EditDisplay:
|
|
|
231
231
|
prefix = "\n"
|
|
232
232
|
|
|
233
233
|
|
|
234
|
-
def re_tab(s) -> str:
|
|
234
|
+
def re_tab(s: str) -> str:
|
|
235
235
|
"""Return a tabbed string from an expanded one."""
|
|
236
236
|
line = []
|
|
237
237
|
p = 0
|
|
@@ -159,7 +159,7 @@ def main():
|
|
|
159
159
|
" widget is used to keep the instructions at the top of the screen.",
|
|
160
160
|
]
|
|
161
161
|
|
|
162
|
-
def button_press(button):
|
|
162
|
+
def button_press(button: urwid.Button) -> None:
|
|
163
163
|
frame.footer = urwid.AttrMap(urwid.Text(["Pressed: ", button.get_label()]), "header")
|
|
164
164
|
|
|
165
165
|
radio_button_group = []
|
|
@@ -355,11 +355,11 @@ def main():
|
|
|
355
355
|
("body", "black", "light gray", "standout"),
|
|
356
356
|
("reverse", "light gray", "black"),
|
|
357
357
|
("header", "white", "dark red", "bold"),
|
|
358
|
-
("important", "dark blue", "light gray",
|
|
358
|
+
("important", "dark blue", "light gray", "standout,underline"),
|
|
359
359
|
("editfc", "white", "dark blue", "bold"),
|
|
360
360
|
("editbx", "light gray", "dark blue"),
|
|
361
361
|
("editcp", "black", "light gray", "standout"),
|
|
362
|
-
("bright", "dark gray", "light gray",
|
|
362
|
+
("bright", "dark gray", "light gray", "bold,standout"),
|
|
363
363
|
("buttn", "black", "dark cyan"),
|
|
364
364
|
("buttnf", "white", "dark blue", "bold"),
|
|
365
365
|
]
|
|
@@ -48,7 +48,7 @@ class SwitchingPadding(urwid.Padding[_Wrapped]):
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
class BigTextDisplay:
|
|
51
|
-
palette: typing.ClassVar[list[tuple[str, str, str,
|
|
51
|
+
palette: typing.ClassVar[list[tuple[str, str, str] | tuple[str, str, str, str]]] = [
|
|
52
52
|
("body", "black", "light gray", "standout"),
|
|
53
53
|
("header", "white", "dark red", "bold"),
|
|
54
54
|
("button normal", "light gray", "dark blue", "standout"),
|
|
@@ -178,9 +178,9 @@ class DirectoryNode(urwid.ParentNode):
|
|
|
178
178
|
parent.set_child_node(self.get_key(), self)
|
|
179
179
|
return parent
|
|
180
180
|
|
|
181
|
-
def load_child_keys(self):
|
|
182
|
-
dirs = []
|
|
183
|
-
files = []
|
|
181
|
+
def load_child_keys(self) -> list[str] | list[None]:
|
|
182
|
+
dirs: list[str] = []
|
|
183
|
+
files: list[str] = []
|
|
184
184
|
try:
|
|
185
185
|
path = self.get_value()
|
|
186
186
|
# separate dirs and files
|
|
@@ -207,7 +207,7 @@ class DirectoryNode(urwid.ParentNode):
|
|
|
207
207
|
keys = [None]
|
|
208
208
|
return keys
|
|
209
209
|
|
|
210
|
-
def load_child_node(self, key) -> EmptyNode | DirectoryNode | FileNode:
|
|
210
|
+
def load_child_node(self, key: Hashable) -> EmptyNode | DirectoryNode | FileNode:
|
|
211
211
|
"""Return either a FileNode or DirectoryNode"""
|
|
212
212
|
index = self.get_child_index(key)
|
|
213
213
|
if key is None:
|
|
@@ -225,11 +225,11 @@ class DirectoryNode(urwid.ParentNode):
|
|
|
225
225
|
|
|
226
226
|
|
|
227
227
|
class DirectoryBrowser:
|
|
228
|
-
palette: typing.ClassVar[list[tuple[str, str, str,
|
|
228
|
+
palette: typing.ClassVar[list[tuple[str, ...] | tuple[str, str, str, str]]] = [
|
|
229
229
|
("body", "black", "light gray"),
|
|
230
|
-
("flagged", "black", "dark green",
|
|
230
|
+
("flagged", "black", "dark green", "bold,underline"),
|
|
231
231
|
("focus", "light gray", "dark blue", "standout"),
|
|
232
|
-
("flagged focus", "yellow", "dark cyan",
|
|
232
|
+
("flagged focus", "yellow", "dark cyan", "bold,standout,underline"),
|
|
233
233
|
("head", "yellow", "black", "standout"),
|
|
234
234
|
("foot", "light gray", "black"),
|
|
235
235
|
("key", "light cyan", "black", "underline"),
|
|
@@ -40,7 +40,7 @@ import typing
|
|
|
40
40
|
import urwid
|
|
41
41
|
|
|
42
42
|
if typing.TYPE_CHECKING:
|
|
43
|
-
from collections.abc import Hashable
|
|
43
|
+
from collections.abc import Hashable, Iterable
|
|
44
44
|
|
|
45
45
|
# use appropriate Screen class
|
|
46
46
|
if urwid.display.web.is_web_request():
|
|
@@ -99,7 +99,7 @@ class CalcEvent(Exception):
|
|
|
99
99
|
def __init__(self, message: str | tuple[Hashable, str] | list[str | tuple[Hashable, str]]) -> None:
|
|
100
100
|
self.message = message
|
|
101
101
|
|
|
102
|
-
def widget(self):
|
|
102
|
+
def widget(self) -> urwid.AttrMap[urwid.Text]:
|
|
103
103
|
"""Return a widget containing event information"""
|
|
104
104
|
text = urwid.Text(self.message, urwid.CENTER)
|
|
105
105
|
return urwid.AttrMap(text, self.attr)
|
|
@@ -110,7 +110,7 @@ class ColumnDeleteEvent(CalcEvent):
|
|
|
110
110
|
|
|
111
111
|
attr = "confirm"
|
|
112
112
|
|
|
113
|
-
def __init__(self, letter: str, from_parent=0) -> None:
|
|
113
|
+
def __init__(self, letter: str, from_parent: int = 0) -> None:
|
|
114
114
|
super().__init__(["Press ", ("key", "BACKSPACE"), " again to confirm column removal."])
|
|
115
115
|
self.letter = letter
|
|
116
116
|
|
|
@@ -120,14 +120,14 @@ class UpdateParentEvent(Exception):
|
|
|
120
120
|
|
|
121
121
|
|
|
122
122
|
class Cell:
|
|
123
|
-
def __init__(self, op) -> None:
|
|
123
|
+
def __init__(self, op: str | None) -> None:
|
|
124
124
|
self.op = op
|
|
125
125
|
self.is_top = op is None
|
|
126
126
|
self.child = None
|
|
127
127
|
self.setup_edit()
|
|
128
128
|
self.result = urwid.Text("", layout=CALC_LAYOUT)
|
|
129
129
|
|
|
130
|
-
def show_result(self, next_cell) -> bool:
|
|
130
|
+
def show_result(self, next_cell: Cell | None) -> bool:
|
|
131
131
|
"""Return whether this widget should display its result.
|
|
132
132
|
|
|
133
133
|
next_cell -- the cell following self or None"""
|
|
@@ -192,7 +192,7 @@ class Cell:
|
|
|
192
192
|
class ParentEdit(urwid.Edit):
|
|
193
193
|
"""Edit widget modified to link to a child column"""
|
|
194
194
|
|
|
195
|
-
def __init__(self, op, letter: str) -> None:
|
|
195
|
+
def __init__(self, op: str | None, letter: str) -> None:
|
|
196
196
|
"""Use the operator and letter of the child column as caption
|
|
197
197
|
|
|
198
198
|
op -- operator or None
|
|
@@ -226,20 +226,23 @@ class ParentEdit(urwid.Edit):
|
|
|
226
226
|
|
|
227
227
|
|
|
228
228
|
class CellWalker(urwid.ListWalker):
|
|
229
|
-
def __init__(self, content):
|
|
229
|
+
def __init__(self, content: Iterable[Cell]) -> None:
|
|
230
230
|
self.content = urwid.MonitoredList(content)
|
|
231
|
-
self.content.
|
|
231
|
+
self.content.set_modified_callback(self._modified)
|
|
232
232
|
self.focus = (0, 0)
|
|
233
233
|
# everyone can share the same divider widget
|
|
234
234
|
self.div = urwid.Divider("-")
|
|
235
235
|
|
|
236
|
-
def get_cell(self, i):
|
|
236
|
+
def get_cell(self, i: int) -> Cell | None:
|
|
237
237
|
if i < 0 or i >= len(self.content):
|
|
238
238
|
return None
|
|
239
239
|
|
|
240
240
|
return self.content[i]
|
|
241
241
|
|
|
242
|
-
def _get_at_pos(
|
|
242
|
+
def _get_at_pos(
|
|
243
|
+
self,
|
|
244
|
+
pos: tuple[int, int],
|
|
245
|
+
) -> tuple[urwid.Divider | urwid.AttrMap[urwid.IntEdit] | urwid.Text, tuple[int, int]] | tuple[None, None]:
|
|
243
246
|
i, sub = pos
|
|
244
247
|
assert sub in {0, 1, 2} # noqa: S101 # for examples "assert" is acceptable
|
|
245
248
|
if i < 0 or i >= len(self.content):
|
|
@@ -252,13 +255,18 @@ class CellWalker(urwid.ListWalker):
|
|
|
252
255
|
|
|
253
256
|
return self.content[i].result, pos
|
|
254
257
|
|
|
255
|
-
def get_focus(
|
|
258
|
+
def get_focus(
|
|
259
|
+
self,
|
|
260
|
+
) -> tuple[urwid.Divider | urwid.AttrMap[urwid.IntEdit] | urwid.Text, tuple[int, int]] | tuple[None, None]:
|
|
256
261
|
return self._get_at_pos(self.focus)
|
|
257
262
|
|
|
258
|
-
def set_focus(self, focus) -> None:
|
|
263
|
+
def set_focus(self, focus: tuple[int, int]) -> None:
|
|
259
264
|
self.focus = focus
|
|
260
265
|
|
|
261
|
-
def get_next(
|
|
266
|
+
def get_next(
|
|
267
|
+
self,
|
|
268
|
+
position: tuple[int, int],
|
|
269
|
+
) -> tuple[urwid.Divider | urwid.AttrMap[urwid.IntEdit] | urwid.Text, tuple[int, int]] | tuple[None, None]:
|
|
262
270
|
i, sub = position
|
|
263
271
|
assert sub in {0, 1, 2} # noqa: S101 # for examples "assert" is acceptable
|
|
264
272
|
if sub == 0:
|
|
@@ -272,7 +280,10 @@ class CellWalker(urwid.ListWalker):
|
|
|
272
280
|
|
|
273
281
|
return self._get_at_pos((i + 1, 0))
|
|
274
282
|
|
|
275
|
-
def get_prev(
|
|
283
|
+
def get_prev(
|
|
284
|
+
self,
|
|
285
|
+
position: tuple[int, int],
|
|
286
|
+
) -> tuple[urwid.Divider | urwid.AttrMap[urwid.IntEdit] | urwid.Text, tuple[int, int]] | tuple[None, None]:
|
|
276
287
|
i, sub = position
|
|
277
288
|
assert sub in {0, 1, 2} # noqa: S101 # for examples "assert" is acceptable
|
|
278
289
|
if sub == 0:
|
|
@@ -289,7 +300,7 @@ class CellWalker(urwid.ListWalker):
|
|
|
289
300
|
return self._get_at_pos((i, 1))
|
|
290
301
|
|
|
291
302
|
|
|
292
|
-
class CellColumn(urwid.WidgetWrap):
|
|
303
|
+
class CellColumn(urwid.WidgetWrap[urwid.Frame[urwid.WidgetWrap[urwid.Text], urwid.ListBox, None]]):
|
|
293
304
|
def __init__(self, letter: str) -> None:
|
|
294
305
|
self.walker = CellWalker([Cell(None)])
|
|
295
306
|
self.content = self.walker.content
|
|
@@ -304,7 +315,7 @@ class CellColumn(urwid.WidgetWrap):
|
|
|
304
315
|
header = urwid.AttrMap(urwid.Text(["Column ", ("key", letter)], layout=CALC_LAYOUT), "colhead")
|
|
305
316
|
self.frame = urwid.Frame(self.listbox, header)
|
|
306
317
|
|
|
307
|
-
def keypress(self, size, key: str) -> str | None:
|
|
318
|
+
def keypress(self, size: tuple[int, int], key: str) -> str | None:
|
|
308
319
|
key = self.frame.keypress(size, key)
|
|
309
320
|
if key is None:
|
|
310
321
|
changed = self.update_results()
|
|
@@ -387,7 +398,7 @@ class CellColumn(urwid.WidgetWrap):
|
|
|
387
398
|
return None
|
|
388
399
|
return key
|
|
389
400
|
|
|
390
|
-
def move_focus_next(self, size) -> None:
|
|
401
|
+
def move_focus_next(self, size: tuple[int, int]) -> None:
|
|
391
402
|
_f, (i, _sub) = self.walker.get_focus()
|
|
392
403
|
assert i < len(self.content) - 1 # noqa: S101 # for examples "assert" is acceptable
|
|
393
404
|
|
|
@@ -396,7 +407,7 @@ class CellColumn(urwid.WidgetWrap):
|
|
|
396
407
|
self.frame.keypress(size, "down")
|
|
397
408
|
_nf, (ni, _nsub) = self.walker.get_focus()
|
|
398
409
|
|
|
399
|
-
def move_focus_prev(self, size) -> None:
|
|
410
|
+
def move_focus_prev(self, size: tuple[int, int]) -> None:
|
|
400
411
|
_f, (i, _sub) = self.walker.get_focus()
|
|
401
412
|
assert i > 0 # noqa: S101 # for examples "assert" is acceptable
|
|
402
413
|
|
|
@@ -442,7 +453,7 @@ class CellColumn(urwid.WidgetWrap):
|
|
|
442
453
|
|
|
443
454
|
return True
|
|
444
455
|
|
|
445
|
-
def create_child(self, letter):
|
|
456
|
+
def create_child(self, letter: str) -> tuple[Cell, CellColumn] | tuple[None, None]:
|
|
446
457
|
"""Return (parent cell,child column) or None,None on failure."""
|
|
447
458
|
_f, (i, sub) = self.walker.get_focus()
|
|
448
459
|
if sub != 0:
|
|
@@ -479,7 +490,7 @@ class CellColumn(urwid.WidgetWrap):
|
|
|
479
490
|
|
|
480
491
|
return "".join(lines)
|
|
481
492
|
|
|
482
|
-
def get_result(self):
|
|
493
|
+
def get_result(self) -> int | None:
|
|
483
494
|
"""Return the result of the last cell in the column."""
|
|
484
495
|
|
|
485
496
|
return self.content[-1].get_result()
|
|
@@ -541,7 +552,7 @@ class HelpColumn(urwid.Widget):
|
|
|
541
552
|
self.body = urwid.AttrMap(self.listbox, "help")
|
|
542
553
|
self.frame = urwid.Frame(self.body, header=self.head)
|
|
543
554
|
|
|
544
|
-
def render(self, size, focus: bool = False) -> urwid.Canvas:
|
|
555
|
+
def render(self, size: tuple[int, int], focus: bool = False) -> urwid.Canvas:
|
|
545
556
|
maxcol, maxrow = size
|
|
546
557
|
head_rows = self.head.rows((maxcol,))
|
|
547
558
|
if "bottom" in self.listbox.ends_visible((maxcol, maxrow - head_rows)):
|
|
@@ -551,17 +562,17 @@ class HelpColumn(urwid.Widget):
|
|
|
551
562
|
|
|
552
563
|
return self.frame.render((maxcol, maxrow), focus)
|
|
553
564
|
|
|
554
|
-
def keypress(self, size, key: str) -> str | None:
|
|
565
|
+
def keypress(self, size: tuple[int, int], key: str) -> str | None:
|
|
555
566
|
return self.frame.keypress(size, key)
|
|
556
567
|
|
|
557
568
|
|
|
558
569
|
class CalcDisplay:
|
|
559
|
-
palette: typing.ClassVar[list[tuple[str, str, str,
|
|
570
|
+
palette: typing.ClassVar[list[tuple[str, str, str] | tuple[str, str, str, str]]] = [
|
|
560
571
|
("body", "white", "dark blue"),
|
|
561
572
|
("edit", "yellow", "dark blue"),
|
|
562
573
|
("editfocus", "yellow", "dark cyan", "bold"),
|
|
563
|
-
("key", "dark cyan", "light gray",
|
|
564
|
-
("title", "white", "light gray",
|
|
574
|
+
("key", "dark cyan", "light gray", "standout,underline"),
|
|
575
|
+
("title", "white", "light gray", "bold,standout"),
|
|
565
576
|
("help", "black", "light gray", "standout"),
|
|
566
577
|
("helpnote", "dark green", "light gray"),
|
|
567
578
|
("colhead", "black", "light gray", "standout"),
|
|
@@ -586,7 +597,7 @@ class CalcDisplay:
|
|
|
586
597
|
print(expression)
|
|
587
598
|
print("Result:", result)
|
|
588
599
|
|
|
589
|
-
def input_filter(self, data, raw_input):
|
|
600
|
+
def input_filter(self, data: list[str | tuple[str, int, int, int]], raw_input: list[int]) -> list[str]:
|
|
590
601
|
if "q" in data or "Q" in data:
|
|
591
602
|
raise urwid.ExitMainLoop()
|
|
592
603
|
|
|
@@ -604,7 +615,7 @@ class CalcDisplay:
|
|
|
604
615
|
# remove all input from further processing by MainLoop
|
|
605
616
|
return []
|
|
606
617
|
|
|
607
|
-
def wrap_keypress(self, key: str) -> None:
|
|
618
|
+
def wrap_keypress(self, key: str | tuple[str, int, int, int]) -> None:
|
|
608
619
|
"""Handle confirmation and throw event on bad input."""
|
|
609
620
|
|
|
610
621
|
try:
|
|
@@ -633,7 +644,7 @@ class CalcDisplay:
|
|
|
633
644
|
if key not in EDIT_KEYS and key not in MOVEMENT_KEYS:
|
|
634
645
|
raise CalcEvent(E_invalid_key % key.upper())
|
|
635
646
|
|
|
636
|
-
def keypress(self, key: str) -> str | None:
|
|
647
|
+
def keypress(self, key: str | tuple[str, int, int, int]) -> str | None:
|
|
637
648
|
"""Handle a keystroke."""
|
|
638
649
|
|
|
639
650
|
self.loop.process_input([key])
|
|
@@ -774,7 +785,7 @@ class CalcNumLayout(urwid.TextLayout):
|
|
|
774
785
|
the last line for the cursor.
|
|
775
786
|
"""
|
|
776
787
|
|
|
777
|
-
def layout(self, text, width: int, align, wrap):
|
|
788
|
+
def layout(self, text: str | bytes, width: int, align: typing.Any, wrap: typing.Any):
|
|
778
789
|
"""
|
|
779
790
|
Return layout structure for calculator number display.
|
|
780
791
|
"""
|
|
@@ -51,10 +51,10 @@ class LineWalker(urwid.ListWalker):
|
|
|
51
51
|
if self.file is not None:
|
|
52
52
|
self.file.close()
|
|
53
53
|
|
|
54
|
-
def get_focus(self):
|
|
54
|
+
def get_focus(self) -> tuple[urwid.Edit, int] | tuple[None, None]:
|
|
55
55
|
return self._get_at_pos(self.focus)
|
|
56
56
|
|
|
57
|
-
def set_focus(self, focus) -> None:
|
|
57
|
+
def set_focus(self, focus: int) -> None:
|
|
58
58
|
self.focus = focus
|
|
59
59
|
self._modified()
|
|
60
60
|
|
|
@@ -145,7 +145,7 @@ class LineWalker(urwid.ListWalker):
|
|
|
145
145
|
|
|
146
146
|
|
|
147
147
|
class EditDisplay:
|
|
148
|
-
palette: typing.ClassVar[list[tuple[str, str, str,
|
|
148
|
+
palette: typing.ClassVar[list[tuple[str, str, str] | tuple[str, str, str, str]]] = [
|
|
149
149
|
("body", "default", "default"),
|
|
150
150
|
("foot", "dark cyan", "dark blue", "bold"),
|
|
151
151
|
("key", "light cyan", "dark blue", "underline"),
|
|
@@ -231,7 +231,7 @@ class EditDisplay:
|
|
|
231
231
|
prefix = "\n"
|
|
232
232
|
|
|
233
233
|
|
|
234
|
-
def re_tab(s) -> str:
|
|
234
|
+
def re_tab(s: str) -> str:
|
|
235
235
|
"""Return a tabbed string from an expanded one."""
|
|
236
236
|
line = []
|
|
237
237
|
p = 0
|
|
@@ -58,12 +58,12 @@ class FibonacciWalker(urwid.ListWalker):
|
|
|
58
58
|
self.focus = focus
|
|
59
59
|
self._modified()
|
|
60
60
|
|
|
61
|
-
def get_next(self, position) -> tuple[urwid.Text, tuple[int, int]]:
|
|
61
|
+
def get_next(self, position: tuple[int, int]) -> tuple[urwid.Text, tuple[int, int]]:
|
|
62
62
|
a, b = position
|
|
63
63
|
focus = b, a + b
|
|
64
64
|
return self._get_at_pos(focus)
|
|
65
65
|
|
|
66
|
-
def get_prev(self, position) -> tuple[urwid.Text, tuple[int, int]]:
|
|
66
|
+
def get_prev(self, position: tuple[int, int]) -> tuple[urwid.Text, tuple[int, int]]:
|
|
67
67
|
a, b = position
|
|
68
68
|
focus = b - a, a
|
|
69
69
|
return self._get_at_pos(focus)
|