urwid 2.6.4__tar.gz → 2.6.6__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-2.6.4 → urwid-2.6.6}/.pre-commit-config.yaml +2 -2
- {urwid-2.6.4 → urwid-2.6.6}/PKG-INFO +1 -1
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/bigtext.py +21 -9
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/real_browse.py +3 -1
- {urwid-2.6.4 → urwid-2.6.6}/examples/bigtext.py +21 -9
- {urwid-2.6.4 → urwid-2.6.6}/examples/browse.py +3 -1
- urwid-2.6.6/pylint-requirements.txt +1 -0
- {urwid-2.6.4 → urwid-2.6.6}/pyproject.toml +4 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_columns.py +82 -3
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_doctests.py +1 -1
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_grid_flow.py +53 -0
- urwid-2.6.6/tests/test_tree.py +273 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/__init__.py +46 -33
- {urwid-2.6.4 → urwid-2.6.6}/urwid/canvas.py +4 -6
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/_posix_raw_display.py +3 -4
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/_raw_display_base.py +4 -5
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/_win32_raw_display.py +1 -2
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/curses.py +1 -1
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/html_fragment.py +1 -1
- {urwid-2.6.4 → urwid-2.6.6}/urwid/event_loop/__init__.py +5 -5
- {urwid-2.6.4 → urwid-2.6.6}/urwid/event_loop/main_loop.py +26 -21
- {urwid-2.6.4 → urwid-2.6.6}/urwid/event_loop/zmq_loop.py +2 -2
- {urwid-2.6.4 → urwid-2.6.6}/urwid/numedit.py +5 -1
- {urwid-2.6.4 → urwid-2.6.6}/urwid/signals.py +1 -1
- {urwid-2.6.4 → urwid-2.6.6}/urwid/str_util.py +1 -2
- {urwid-2.6.4 → urwid-2.6.6}/urwid/text_layout.py +8 -4
- {urwid-2.6.4 → urwid-2.6.6}/urwid/version.py +2 -2
- {urwid-2.6.4 → urwid-2.6.6}/urwid/vterm.py +10 -10
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/__init__.py +19 -1
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/bar_graph.py +8 -4
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/big_text.py +14 -4
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/box_adapter.py +11 -3
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/columns.py +104 -34
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/constants.py +43 -76
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/container.py +2 -2
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/divider.py +5 -1
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/edit.py +20 -14
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/filler.py +11 -4
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/frame.py +91 -28
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/grid_flow.py +66 -15
- {urwid-2.6.4/urwid → urwid-2.6.6/urwid/widget}/listbox.py +27 -23
- {urwid-2.6.4/urwid → urwid-2.6.6/urwid/widget}/monitored_list.py +2 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/overlay.py +99 -14
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/padding.py +16 -3
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/pile.py +57 -13
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/progress_bar.py +5 -1
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/scrollable.py +28 -9
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/solid_fill.py +5 -1
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/text.py +11 -3
- {urwid-2.6.4/urwid → urwid-2.6.6/urwid/widget}/treetools.py +35 -18
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/widget.py +17 -9
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/wimp.py +8 -4
- {urwid-2.6.4 → urwid-2.6.6}/urwid.egg-info/PKG-INFO +1 -1
- {urwid-2.6.4 → urwid-2.6.6}/urwid.egg-info/SOURCES.txt +3 -3
- urwid-2.6.4/pylint-requirements.txt +0 -1
- urwid-2.6.4/tests/test_tree.py +0 -102
- {urwid-2.6.4 → urwid-2.6.6}/.coveralls.yml +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.devcontainer/dev.dockerfile +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.devcontainer/devcontainer.json +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.dockerignore +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/CODE_OF_CONDUCT.md +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/ISSUE_TEMPLATE/docs.md +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/dependabot.yml +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/labeler.yml +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/release.yml +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/workflows/documentation.yml +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/workflows/isolated_static_check.yml +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/workflows/labels.yml +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/workflows/pythonpackage.yml +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.github/workflows/yamllint.yml +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.gitignore +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/.yamllint.yml +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/COPYING +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/MANIFEST.in +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/README.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/black-requirements.txt +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/classifiers.txt +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/Makefile +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/changelog.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/conf.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/bigtext.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/bigtext1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/bigtext2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/bigtext3.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/browse.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/browse.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/browse1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/browse2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/edit.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/edit.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/edit1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/edit2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/edit_text.txt +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/graph.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/graph.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/graph1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/graph2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/index.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/palette_test.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/palette_test.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/palette_test1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/palette_test2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/pop_up.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/pop_up.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/pop_up1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/pop_up2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/real_edit.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/subproc.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/subproc.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/subproc1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/subproc2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/subproc2.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/tour.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/tour.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/tour1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/examples/tour2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/index.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/bright_combinations.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/bright_combinations.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/bright_combinations1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/canvascache.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/displayattributes.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/displaymodules.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/encodings.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/images/display_modules.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/images/introduction.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/images/urwid_widgets.svgz +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/images/urwid_widgets_1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/images/urwid_widgets_1.xcf +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/images/urwid_widgets_2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/images/urwid_widgets_2.xcf +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/images/widget_layout.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/index.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/mainloop.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/overview.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/safe_combinations.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/safe_combinations.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/safe_combinations1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/textlayout.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/userinput.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/wanat.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/wanat_multi.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/wcur1.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/wcur2.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/widgets.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/wmod.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/manual/wsel.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/attrspec.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/canvas.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/command_map.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/constants.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/deprecated.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/display_modules.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/exceptions.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/global_settings.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/index.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/list_walkers.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/main_loop.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/meta.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/signals.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/text_layout.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/reference/widget.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tools/compile_pngs.sh +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tools/screenshots.sh +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tools/static/.placeholder +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tools/templates/indexcontent.html +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tools/templates/indexsidebar.html +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tools/templates/localtoc.html +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/adventure.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/adventure.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/adventure1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/adventure2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/adventure3.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/adventure4.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/cmenu.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/cmenu.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/cmenu1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/cmenu2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/cmenu3.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/cmenu4.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/highcolors.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/highcolors.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/highcolors1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/hmenu.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/hmenu.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/hmenu1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/hmenu2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/hmenu3.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/hmenu4.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/index.rst +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/input.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/input.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/input1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/input2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/input3.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/input4.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/input5.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/menu25.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/minimal.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/minimal.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/minimal1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/multiple.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/multiple.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/multiple1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/multiple2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/multiple3.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/multiple4.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/qa.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/qa.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/qa1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/qa2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/qa3.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/sig.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/sig.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/sig1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/sig2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/sig3.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/sig4.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/smenu.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/smenu.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/smenu1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/smenu2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/smenu3.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/urwid_attr.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/urwid_attr.py.xdotool +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/urwid_attr1.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/urwid_attr2.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/urwid_attr3.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/tutorial/urwid_attr4.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/docs/urwid-logo.png +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/asyncio_socket_server.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/calc.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/dialog.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/edit.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/fib.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/graph.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/input_test.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/lcd_cf635.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/palette_test.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/pop_up.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/subproc.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/subproc2.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/terminal.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/tour.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/treesample.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/twisted_serve_ssh.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/examples/twisted_serve_ssh.tac +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/isort-requirements.txt +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/requirements.txt +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/ruff-requirements.txt +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/setup.cfg +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/setup.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/test_requirements.txt +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/__init__.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_canvas.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_container.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_escapes.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_event_loops.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_filler.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_floatedit.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_font.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_frame.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_graphics.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_line_box.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_listbox.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_moved_imports.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_overlay.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_padding.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_pile.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_raw_display.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_scrollable.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_signals.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_str_util.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_text_layout.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_util.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_vterm.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/test_widget.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tests/util.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/tox.ini +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/command_map.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/container.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/decoration.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/__init__.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/_web.css +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/_web.js +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/_win32.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/common.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/escape.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/lcd.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/raw.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/display/web.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/event_loop/abstract_loop.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/event_loop/asyncio_loop.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/event_loop/glib_loop.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/event_loop/select_loop.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/event_loop/tornado_loop.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/event_loop/trio_loop.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/event_loop/twisted_loop.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/font.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/graphics.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/split_repr.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/util.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/attr_map.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/attr_wrap.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/line_box.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/popup.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/widget/widget_decoration.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid/wimp.py +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid.egg-info/dependency_links.txt +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid.egg-info/not-zip-safe +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid.egg-info/requires.txt +0 -0
- {urwid-2.6.4 → urwid-2.6.6}/urwid.egg-info/top_level.txt +0 -0
|
@@ -26,13 +26,13 @@ repos:
|
|
|
26
26
|
|
|
27
27
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
28
28
|
# Ruff version.
|
|
29
|
-
rev: v0.2.
|
|
29
|
+
rev: v0.2.2
|
|
30
30
|
hooks:
|
|
31
31
|
- id: ruff
|
|
32
32
|
args: [ --fix, --exit-non-zero-on-fix ]
|
|
33
33
|
|
|
34
34
|
- repo: https://github.com/adrienverge/yamllint.git
|
|
35
|
-
rev: v1.35.
|
|
35
|
+
rev: v1.35.1
|
|
36
36
|
hooks:
|
|
37
37
|
- id: yamllint
|
|
38
38
|
|
|
@@ -34,7 +34,10 @@ if typing.TYPE_CHECKING:
|
|
|
34
34
|
from collections.abc import Callable
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
_Wrapped = typing.TypeVar("_Wrapped")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class SwitchingPadding(urwid.Padding[_Wrapped]):
|
|
38
41
|
def padding_values(self, size, focus: bool) -> tuple[int, int]:
|
|
39
42
|
maxcol = size[0]
|
|
40
43
|
width, _height = self.original_widget.pack(size, focus=focus)
|
|
@@ -95,7 +98,10 @@ class BigTextDisplay:
|
|
|
95
98
|
def edit_change_event(self, widget, text: str) -> None:
|
|
96
99
|
self.bigtext.set_text(text)
|
|
97
100
|
|
|
98
|
-
def setup_view(self)
|
|
101
|
+
def setup_view(self) -> tuple[
|
|
102
|
+
urwid.Frame[urwid.AttrMap[urwid.ListBox], urwid.AttrMap[urwid.Text], None],
|
|
103
|
+
urwid.Overlay[urwid.BigText, urwid.Frame[urwid.AttrMap[urwid.ListBox], urwid.AttrMap[urwid.Text], None]],
|
|
104
|
+
]:
|
|
99
105
|
fonts = urwid.get_all_fonts()
|
|
100
106
|
# setup mode radio buttons
|
|
101
107
|
self.font_buttons = []
|
|
@@ -143,17 +149,23 @@ class BigTextDisplay:
|
|
|
143
149
|
col = urwid.Columns([(16, chars), fonts], 3, focus_column=1)
|
|
144
150
|
bt = urwid.Pile([bt, edit], focus_item=1)
|
|
145
151
|
lines = [bt, urwid.Divider(), col]
|
|
146
|
-
|
|
152
|
+
listbox = urwid.ListBox(urwid.SimpleListWalker(lines))
|
|
147
153
|
|
|
148
154
|
# Frame
|
|
149
|
-
w = urwid.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
155
|
+
w = urwid.Frame(
|
|
156
|
+
body=urwid.AttrMap(listbox, "body"),
|
|
157
|
+
header=urwid.AttrMap(urwid.Text("Urwid BigText example program - F8 exits."), "header"),
|
|
158
|
+
)
|
|
153
159
|
|
|
154
160
|
# Exit message
|
|
155
|
-
exit_w = urwid.
|
|
156
|
-
|
|
161
|
+
exit_w = urwid.Overlay(
|
|
162
|
+
urwid.BigText(("exit", " Quit? "), exit_font),
|
|
163
|
+
w,
|
|
164
|
+
urwid.CENTER,
|
|
165
|
+
None,
|
|
166
|
+
urwid.MIDDLE,
|
|
167
|
+
None,
|
|
168
|
+
)
|
|
157
169
|
return w, exit_w
|
|
158
170
|
|
|
159
171
|
def main(self):
|
|
@@ -274,7 +274,9 @@ class DirectoryBrowser:
|
|
|
274
274
|
self.listbox.offset_rows = 1
|
|
275
275
|
self.footer = urwid.AttrMap(urwid.Text(self.footer_text), "foot")
|
|
276
276
|
self.view = urwid.Frame(
|
|
277
|
-
urwid.AttrMap(self.listbox, "body"),
|
|
277
|
+
urwid.AttrMap(self.listbox, "body"),
|
|
278
|
+
header=urwid.AttrMap(self.header, "head"),
|
|
279
|
+
footer=self.footer,
|
|
278
280
|
)
|
|
279
281
|
|
|
280
282
|
def main(self) -> None:
|
|
@@ -34,7 +34,10 @@ if typing.TYPE_CHECKING:
|
|
|
34
34
|
from collections.abc import Callable
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
_Wrapped = typing.TypeVar("_Wrapped")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class SwitchingPadding(urwid.Padding[_Wrapped]):
|
|
38
41
|
def padding_values(self, size, focus: bool) -> tuple[int, int]:
|
|
39
42
|
maxcol = size[0]
|
|
40
43
|
width, _height = self.original_widget.pack(size, focus=focus)
|
|
@@ -95,7 +98,10 @@ class BigTextDisplay:
|
|
|
95
98
|
def edit_change_event(self, widget, text: str) -> None:
|
|
96
99
|
self.bigtext.set_text(text)
|
|
97
100
|
|
|
98
|
-
def setup_view(self)
|
|
101
|
+
def setup_view(self) -> tuple[
|
|
102
|
+
urwid.Frame[urwid.AttrMap[urwid.ListBox], urwid.AttrMap[urwid.Text], None],
|
|
103
|
+
urwid.Overlay[urwid.BigText, urwid.Frame[urwid.AttrMap[urwid.ListBox], urwid.AttrMap[urwid.Text], None]],
|
|
104
|
+
]:
|
|
99
105
|
fonts = urwid.get_all_fonts()
|
|
100
106
|
# setup mode radio buttons
|
|
101
107
|
self.font_buttons = []
|
|
@@ -143,17 +149,23 @@ class BigTextDisplay:
|
|
|
143
149
|
col = urwid.Columns([(16, chars), fonts], 3, focus_column=1)
|
|
144
150
|
bt = urwid.Pile([bt, edit], focus_item=1)
|
|
145
151
|
lines = [bt, urwid.Divider(), col]
|
|
146
|
-
|
|
152
|
+
listbox = urwid.ListBox(urwid.SimpleListWalker(lines))
|
|
147
153
|
|
|
148
154
|
# Frame
|
|
149
|
-
w = urwid.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
155
|
+
w = urwid.Frame(
|
|
156
|
+
body=urwid.AttrMap(listbox, "body"),
|
|
157
|
+
header=urwid.AttrMap(urwid.Text("Urwid BigText example program - F8 exits."), "header"),
|
|
158
|
+
)
|
|
153
159
|
|
|
154
160
|
# Exit message
|
|
155
|
-
exit_w = urwid.
|
|
156
|
-
|
|
161
|
+
exit_w = urwid.Overlay(
|
|
162
|
+
urwid.BigText(("exit", " Quit? "), exit_font),
|
|
163
|
+
w,
|
|
164
|
+
urwid.CENTER,
|
|
165
|
+
None,
|
|
166
|
+
urwid.MIDDLE,
|
|
167
|
+
None,
|
|
168
|
+
)
|
|
157
169
|
return w, exit_w
|
|
158
170
|
|
|
159
171
|
def main(self):
|
|
@@ -274,7 +274,9 @@ class DirectoryBrowser:
|
|
|
274
274
|
self.listbox.offset_rows = 1
|
|
275
275
|
self.footer = urwid.AttrMap(urwid.Text(self.footer_text), "foot")
|
|
276
276
|
self.view = urwid.Frame(
|
|
277
|
-
urwid.AttrMap(self.listbox, "body"),
|
|
277
|
+
urwid.AttrMap(self.listbox, "body"),
|
|
278
|
+
header=urwid.AttrMap(self.header, "head"),
|
|
279
|
+
footer=self.footer,
|
|
278
280
|
)
|
|
279
281
|
|
|
280
282
|
def main(self) -> None:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pylint==3.1.0
|
|
@@ -90,6 +90,10 @@ exclude_lines = [
|
|
|
90
90
|
|
|
91
91
|
# Don't complain about missing debug-only code:
|
|
92
92
|
"def __repr__",
|
|
93
|
+
"def __rich_repr__",
|
|
94
|
+
# own repr construct magic
|
|
95
|
+
"def _repr_words",
|
|
96
|
+
"def _repr_attrs",
|
|
93
97
|
|
|
94
98
|
# Don't complain if tests don't hit defensive assertion code:
|
|
95
99
|
"raise NotImplementedError",
|
|
@@ -80,13 +80,40 @@ class ColumnsTest(unittest.TestCase):
|
|
|
80
80
|
|
|
81
81
|
with self.subTest("FIXED only"):
|
|
82
82
|
widget = urwid.Columns(((urwid.PACK, fixed_only),))
|
|
83
|
-
self.assertEqual(frozenset((urwid.FIXED
|
|
83
|
+
self.assertEqual(frozenset((urwid.FLOW, urwid.FIXED)), widget.sizing())
|
|
84
84
|
cols, rows = 3, 3
|
|
85
85
|
self.assertEqual((cols, rows), widget.pack(()))
|
|
86
86
|
canvas = widget.render(())
|
|
87
87
|
self.assertEqual(cols, canvas.cols())
|
|
88
88
|
self.assertEqual(rows, canvas.rows())
|
|
89
89
|
|
|
90
|
+
with self.subTest("FIXED only use FLOW methods - drop & replace by solid"):
|
|
91
|
+
widget = urwid.Columns(((urwid.PACK, fixed_only),))
|
|
92
|
+
self.assertEqual(frozenset((urwid.FLOW, urwid.FIXED)), widget.sizing())
|
|
93
|
+
cols, rows = 2, 1
|
|
94
|
+
self.assertEqual((cols, rows), widget.pack((cols,)))
|
|
95
|
+
canvas = widget.render((cols,))
|
|
96
|
+
self.assertEqual(cols, canvas.cols())
|
|
97
|
+
self.assertEqual(rows, canvas.rows())
|
|
98
|
+
self.assertEqual(" ", str(canvas))
|
|
99
|
+
|
|
100
|
+
with self.subTest("FIXED only use FLOW methods - add empty space"):
|
|
101
|
+
widget = urwid.Columns(((urwid.PACK, fixed_only),))
|
|
102
|
+
self.assertEqual(frozenset((urwid.FLOW, urwid.FIXED)), widget.sizing())
|
|
103
|
+
cols, rows = 5, 3
|
|
104
|
+
self.assertEqual((cols, rows), widget.pack((cols,)))
|
|
105
|
+
canvas = widget.render((cols,))
|
|
106
|
+
self.assertEqual(cols, canvas.cols())
|
|
107
|
+
self.assertEqual(rows, canvas.rows())
|
|
108
|
+
self.assertEqual(
|
|
109
|
+
(
|
|
110
|
+
"┌─┐ ",
|
|
111
|
+
"│ │ ",
|
|
112
|
+
"└─┘ ",
|
|
113
|
+
),
|
|
114
|
+
canvas.decoded_text,
|
|
115
|
+
)
|
|
116
|
+
|
|
90
117
|
with self.subTest("GIVEN BOX + FLOW/FIXED, but other widgets do not support box"):
|
|
91
118
|
widget = urwid.Columns((flow_fixed, (3, box_only)), box_columns=(1,))
|
|
92
119
|
self.assertEqual(frozenset((urwid.FLOW, urwid.FIXED)), widget.sizing())
|
|
@@ -153,8 +180,7 @@ class ColumnsTest(unittest.TestCase):
|
|
|
153
180
|
)
|
|
154
181
|
|
|
155
182
|
cols, rows = 30, 1
|
|
156
|
-
|
|
157
|
-
widget.pack((cols,))
|
|
183
|
+
self.assertEqual((cols, rows), widget.pack((cols,)))
|
|
158
184
|
|
|
159
185
|
canvas = widget.render((cols,))
|
|
160
186
|
self.assertEqual(rows, canvas.rows())
|
|
@@ -241,6 +267,59 @@ class ColumnsTest(unittest.TestCase):
|
|
|
241
267
|
str(ctx.warnings[0].message),
|
|
242
268
|
)
|
|
243
269
|
|
|
270
|
+
def test_pack_render_skip_widget(self):
|
|
271
|
+
widget = urwid.Columns(((0, urwid.Text("Ignore\nme")), (urwid.Text("Count"))))
|
|
272
|
+
cols, rows = 5, 1
|
|
273
|
+
self.assertEqual((cols, rows), widget.pack(()))
|
|
274
|
+
self.assertEqual((cols, rows), widget.pack((cols,)))
|
|
275
|
+
self.assertEqual("Count", str(widget.render(())))
|
|
276
|
+
self.assertEqual("Count", str(widget.render((cols,))))
|
|
277
|
+
|
|
278
|
+
def test_pack_flow_with_fixed_item(self):
|
|
279
|
+
widget = urwid.Columns(
|
|
280
|
+
(
|
|
281
|
+
(urwid.PACK, urwid.BigText("3", urwid.Thin3x3Font())),
|
|
282
|
+
(urwid.Text("Multi\nline\ntext\n???")),
|
|
283
|
+
),
|
|
284
|
+
dividechars=1,
|
|
285
|
+
)
|
|
286
|
+
with self.subTest("Skip"):
|
|
287
|
+
self.assertEqual(3, widget.rows((3,)))
|
|
288
|
+
self.assertEqual((3, 3), widget.pack((3,)))
|
|
289
|
+
self.assertEqual(
|
|
290
|
+
(
|
|
291
|
+
"┌─┐",
|
|
292
|
+
" ─┤",
|
|
293
|
+
"└─┘",
|
|
294
|
+
),
|
|
295
|
+
widget.render((3,)).decoded_text,
|
|
296
|
+
)
|
|
297
|
+
with self.subTest("Fit all"):
|
|
298
|
+
self.assertEqual(4, widget.rows((9,)))
|
|
299
|
+
self.assertEqual((9, 4), widget.pack((9,)))
|
|
300
|
+
self.assertEqual(
|
|
301
|
+
(
|
|
302
|
+
"┌─┐ Multi",
|
|
303
|
+
" ─┤ line ",
|
|
304
|
+
"└─┘ text ",
|
|
305
|
+
" ??? ",
|
|
306
|
+
),
|
|
307
|
+
widget.render((9,)).decoded_text,
|
|
308
|
+
)
|
|
309
|
+
with self.subTest("Use SolidCanvas instead"):
|
|
310
|
+
self.assertEqual(1, widget.rows((2,)))
|
|
311
|
+
self.assertEqual((2, 1), widget.pack((2,)))
|
|
312
|
+
self.assertEqual((" ",), widget.render((2,)).decoded_text)
|
|
313
|
+
|
|
314
|
+
def test_pack_render_empty_widget(self):
|
|
315
|
+
widget = urwid.Columns(())
|
|
316
|
+
self.assertEqual(frozenset((urwid.FLOW, urwid.BOX)), widget.sizing())
|
|
317
|
+
cols, rows = 10, 1
|
|
318
|
+
self.assertEqual((cols, rows), widget.pack((cols,)))
|
|
319
|
+
canvas = widget.render((cols,))
|
|
320
|
+
self.assertEqual(rows, canvas.rows())
|
|
321
|
+
self.assertEqual((" ",), canvas.decoded_text)
|
|
322
|
+
|
|
244
323
|
def test_not_a_widget(self):
|
|
245
324
|
class NotAWidget:
|
|
246
325
|
__slots__ = ("name", "symbol")
|
|
@@ -34,11 +34,11 @@ def load_tests(loader: unittest.TestLoader, tests: unittest.BaseTestSuite, ignor
|
|
|
34
34
|
urwid.widget.widget,
|
|
35
35
|
urwid.widget.widget_decoration,
|
|
36
36
|
urwid.widget.wimp,
|
|
37
|
+
urwid.widget.monitored_list,
|
|
37
38
|
urwid.display.common,
|
|
38
39
|
urwid.display.raw,
|
|
39
40
|
urwid.event_loop.main_loop,
|
|
40
41
|
urwid.numedit,
|
|
41
|
-
urwid.monitored_list,
|
|
42
42
|
urwid.raw_display,
|
|
43
43
|
urwid.font,
|
|
44
44
|
"urwid.split_repr", # override function with same name
|
|
@@ -84,6 +84,59 @@ class GridFlowTest(unittest.TestCase):
|
|
|
84
84
|
gf = urwid.GridFlow([], 5, 0, 0, "left")
|
|
85
85
|
self.assertEqual(gf.cell_width, 5)
|
|
86
86
|
|
|
87
|
+
def test_not_fit(self):
|
|
88
|
+
"""Test scenario with maxcol < cell_width (special case, warning will be produced)."""
|
|
89
|
+
widget = urwid.GridFlow(
|
|
90
|
+
[urwid.Button("first"), urwid.Button("second")],
|
|
91
|
+
5,
|
|
92
|
+
0,
|
|
93
|
+
0,
|
|
94
|
+
"left",
|
|
95
|
+
)
|
|
96
|
+
size = (3,)
|
|
97
|
+
with self.assertWarns(urwid.widget.GridFlowWarning):
|
|
98
|
+
canvas = widget.render(size)
|
|
99
|
+
|
|
100
|
+
self.assertEqual(
|
|
101
|
+
("< f", " i", " r", " s", " t", "< s", " e", " c", " o", " n", " d"),
|
|
102
|
+
canvas.decoded_text,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def test_multiline(self):
|
|
106
|
+
"""Test widgets fit only with multiple lines"""
|
|
107
|
+
widget = urwid.GridFlow(
|
|
108
|
+
[urwid.Button("first"), urwid.Button("second")],
|
|
109
|
+
10,
|
|
110
|
+
0,
|
|
111
|
+
0,
|
|
112
|
+
"left",
|
|
113
|
+
)
|
|
114
|
+
size = (10,)
|
|
115
|
+
canvas = widget.render(size)
|
|
116
|
+
self.assertEqual(
|
|
117
|
+
("< first >", "< second >"),
|
|
118
|
+
canvas.decoded_text,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
def test_multiline_2(self):
|
|
122
|
+
"""Test widgets fit only with multiple lines"""
|
|
123
|
+
widget = urwid.GridFlow(
|
|
124
|
+
[urwid.Button("first"), urwid.Button("second"), urwid.Button("third"), urwid.Button("forth")],
|
|
125
|
+
10,
|
|
126
|
+
0,
|
|
127
|
+
0,
|
|
128
|
+
"left",
|
|
129
|
+
)
|
|
130
|
+
size = (20,)
|
|
131
|
+
canvas = widget.render(size)
|
|
132
|
+
self.assertEqual(
|
|
133
|
+
(
|
|
134
|
+
"< first >< second >",
|
|
135
|
+
"< third >< forth >",
|
|
136
|
+
),
|
|
137
|
+
canvas.decoded_text,
|
|
138
|
+
)
|
|
139
|
+
|
|
87
140
|
def test_basics(self):
|
|
88
141
|
repr(urwid.GridFlow([], 5, 0, 0, "left")) # should not fail
|
|
89
142
|
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
import unittest
|
|
5
|
+
from typing import Collection
|
|
6
|
+
|
|
7
|
+
import urwid
|
|
8
|
+
from urwid import TreeNode
|
|
9
|
+
|
|
10
|
+
if typing.TYPE_CHECKING:
|
|
11
|
+
from collections.abc import Hashable, Iterable
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SelfRegisteringParent(urwid.ParentNode):
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
value: str,
|
|
18
|
+
parent: SelfRegisteringParent | None = None,
|
|
19
|
+
key: Hashable = None,
|
|
20
|
+
depth: int | None = None,
|
|
21
|
+
children: Iterable[SelfRegisteringChild | SelfRegisteringParent] = (),
|
|
22
|
+
) -> None:
|
|
23
|
+
super().__init__(value, parent, key, depth)
|
|
24
|
+
if parent:
|
|
25
|
+
parent.set_child_node(key, self)
|
|
26
|
+
|
|
27
|
+
self._child_keys = []
|
|
28
|
+
for child in children:
|
|
29
|
+
key = child.get_key()
|
|
30
|
+
self._children[key] = child
|
|
31
|
+
self._child_keys.append(key)
|
|
32
|
+
child.set_parent(self)
|
|
33
|
+
|
|
34
|
+
def load_child_keys(self) -> Collection[Hashable]:
|
|
35
|
+
return list(self._children)
|
|
36
|
+
|
|
37
|
+
def set_child_node(self, key: Hashable, node: TreeNode) -> None:
|
|
38
|
+
super().set_child_node(key, node)
|
|
39
|
+
self._child_keys = self.load_child_keys()
|
|
40
|
+
|
|
41
|
+
def set_parent(self, parent: SelfRegisteringParent) -> None:
|
|
42
|
+
self._parent = parent
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class SelfRegisteringChild(urwid.TreeNode):
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
value: str,
|
|
49
|
+
parent: SelfRegisteringParent | None = None,
|
|
50
|
+
key: Hashable | None = None,
|
|
51
|
+
depth: int | None = None,
|
|
52
|
+
) -> None:
|
|
53
|
+
super().__init__(value, parent, key, depth)
|
|
54
|
+
if parent:
|
|
55
|
+
parent.set_child_node(key, self)
|
|
56
|
+
|
|
57
|
+
def set_parent(self, parent: SelfRegisteringParent) -> None:
|
|
58
|
+
self._parent = parent
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class TestTree(unittest.TestCase):
|
|
62
|
+
def test_basic(self):
|
|
63
|
+
root = SelfRegisteringParent(
|
|
64
|
+
"root",
|
|
65
|
+
key="/",
|
|
66
|
+
children=(SelfRegisteringChild(f"child_{idx}", key=str(idx)) for idx in range(1, 4)),
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
widget = urwid.TreeListBox(urwid.TreeWalker(root))
|
|
70
|
+
size = (15, 5)
|
|
71
|
+
expanded = (
|
|
72
|
+
"- /: root ",
|
|
73
|
+
" 1: child_1 ",
|
|
74
|
+
" 2: child_2 ",
|
|
75
|
+
" 3: child_3 ",
|
|
76
|
+
" ",
|
|
77
|
+
)
|
|
78
|
+
collapsed = (
|
|
79
|
+
"+ /: root ",
|
|
80
|
+
*(" " * size[0] for _ in range(size[1] - 1)),
|
|
81
|
+
)
|
|
82
|
+
self.assertEqual(expanded, widget.render(size).decoded_text)
|
|
83
|
+
widget.keypress(size, "-")
|
|
84
|
+
self.assertEqual(collapsed, widget.render(size).decoded_text)
|
|
85
|
+
widget.keypress(size, "+")
|
|
86
|
+
self.assertEqual(expanded, widget.render(size).decoded_text)
|
|
87
|
+
widget.keypress(size, "down")
|
|
88
|
+
self.assertIs(root, widget.focus_position)
|
|
89
|
+
widget.keypress(size, "-")
|
|
90
|
+
self.assertEqual(collapsed, widget.render(size).decoded_text)
|
|
91
|
+
widget.keypress(size, "right")
|
|
92
|
+
self.assertEqual(expanded, widget.render(size).decoded_text)
|
|
93
|
+
|
|
94
|
+
def test_nested_behavior(self):
|
|
95
|
+
root = SelfRegisteringParent(
|
|
96
|
+
"root",
|
|
97
|
+
key="/",
|
|
98
|
+
children=(
|
|
99
|
+
SelfRegisteringParent(
|
|
100
|
+
f"nested_{idx}",
|
|
101
|
+
key=f"{idx}/",
|
|
102
|
+
children=(SelfRegisteringChild(f"child_{idx}{cidx}", key=str(cidx)) for cidx in range(1, 4)),
|
|
103
|
+
)
|
|
104
|
+
for idx in range(1, 4)
|
|
105
|
+
),
|
|
106
|
+
)
|
|
107
|
+
widget = urwid.TreeListBox(urwid.TreeWalker(root))
|
|
108
|
+
size = (18, 13)
|
|
109
|
+
expanded = (
|
|
110
|
+
"- /: root ",
|
|
111
|
+
" - 1/: nested_1 ",
|
|
112
|
+
" 1: child_11 ",
|
|
113
|
+
" 2: child_12 ",
|
|
114
|
+
" 3: child_13 ",
|
|
115
|
+
" - 2/: nested_2 ",
|
|
116
|
+
" 1: child_21 ",
|
|
117
|
+
" 2: child_22 ",
|
|
118
|
+
" 3: child_23 ",
|
|
119
|
+
" - 3/: nested_3 ",
|
|
120
|
+
" 1: child_31 ",
|
|
121
|
+
" 2: child_32 ",
|
|
122
|
+
" 3: child_33 ",
|
|
123
|
+
)
|
|
124
|
+
collapsed = (
|
|
125
|
+
"+ /: root ",
|
|
126
|
+
*(" " * size[0] for _ in range(size[1] - 1)),
|
|
127
|
+
)
|
|
128
|
+
self.assertEqual(expanded, widget.render(size).decoded_text)
|
|
129
|
+
widget.keypress(size, "-")
|
|
130
|
+
self.assertEqual(collapsed, widget.render(size).decoded_text)
|
|
131
|
+
widget.keypress(size, "+")
|
|
132
|
+
self.assertEqual(expanded, widget.render(size).decoded_text)
|
|
133
|
+
widget.keypress(size, "down")
|
|
134
|
+
widget.keypress(size, "-")
|
|
135
|
+
self.assertEqual(
|
|
136
|
+
(
|
|
137
|
+
"- /: root ",
|
|
138
|
+
" + 1/: nested_1 ",
|
|
139
|
+
" - 2/: nested_2 ",
|
|
140
|
+
" 1: child_21 ",
|
|
141
|
+
" 2: child_22 ",
|
|
142
|
+
" 3: child_23 ",
|
|
143
|
+
" - 3/: nested_3 ",
|
|
144
|
+
" 1: child_31 ",
|
|
145
|
+
" 2: child_32 ",
|
|
146
|
+
" 3: child_33 ",
|
|
147
|
+
" ",
|
|
148
|
+
" ",
|
|
149
|
+
" ",
|
|
150
|
+
),
|
|
151
|
+
widget.render(size).decoded_text,
|
|
152
|
+
)
|
|
153
|
+
widget.keypress(size, "right")
|
|
154
|
+
self.assertEqual(expanded, widget.render(size).decoded_text)
|
|
155
|
+
widget.keypress(size, "left")
|
|
156
|
+
widget.keypress(size, "-")
|
|
157
|
+
self.assertEqual(collapsed, widget.render(size).decoded_text)
|
|
158
|
+
widget.keypress(size, "+")
|
|
159
|
+
widget.keypress(size, "page down")
|
|
160
|
+
widget.keypress(size, "-")
|
|
161
|
+
self.assertEqual(
|
|
162
|
+
(
|
|
163
|
+
"- /: root ",
|
|
164
|
+
" - 1/: nested_1 ",
|
|
165
|
+
" 1: child_11 ",
|
|
166
|
+
" 2: child_12 ",
|
|
167
|
+
" 3: child_13 ",
|
|
168
|
+
" - 2/: nested_2 ",
|
|
169
|
+
" 1: child_21 ",
|
|
170
|
+
" 2: child_22 ",
|
|
171
|
+
" 3: child_23 ",
|
|
172
|
+
" + 3/: nested_3 ",
|
|
173
|
+
" ",
|
|
174
|
+
" ",
|
|
175
|
+
" ",
|
|
176
|
+
),
|
|
177
|
+
widget.render(size).decoded_text,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
def test_deep_nested_collapse_expand(self):
|
|
181
|
+
root = SelfRegisteringParent(
|
|
182
|
+
"root",
|
|
183
|
+
key="/",
|
|
184
|
+
children=(
|
|
185
|
+
SelfRegisteringParent(
|
|
186
|
+
f"nested_{top_idx}",
|
|
187
|
+
key=f"{top_idx}/",
|
|
188
|
+
children=(
|
|
189
|
+
SelfRegisteringParent(
|
|
190
|
+
f"nested_{top_idx}{first_idx}",
|
|
191
|
+
key=f"{first_idx}/",
|
|
192
|
+
children=(
|
|
193
|
+
SelfRegisteringChild(f"child_{top_idx}{first_idx}{last_idx}", key=str(last_idx))
|
|
194
|
+
for last_idx in range(1, 3)
|
|
195
|
+
),
|
|
196
|
+
)
|
|
197
|
+
for first_idx in range(1, 3)
|
|
198
|
+
),
|
|
199
|
+
)
|
|
200
|
+
for top_idx in range(1, 3)
|
|
201
|
+
),
|
|
202
|
+
)
|
|
203
|
+
widget = urwid.TreeListBox(urwid.TreeWalker(root))
|
|
204
|
+
size = (21, 15)
|
|
205
|
+
expanded = (
|
|
206
|
+
"- /: root ",
|
|
207
|
+
" - 1/: nested_1 ",
|
|
208
|
+
" - 1/: nested_11",
|
|
209
|
+
" 1: child_111",
|
|
210
|
+
" 2: child_112",
|
|
211
|
+
" - 2/: nested_12",
|
|
212
|
+
" 1: child_121",
|
|
213
|
+
" 2: child_122",
|
|
214
|
+
" - 2/: nested_2 ",
|
|
215
|
+
" - 1/: nested_21",
|
|
216
|
+
" 1: child_211",
|
|
217
|
+
" 2: child_212",
|
|
218
|
+
" - 2/: nested_22",
|
|
219
|
+
" 1: child_221",
|
|
220
|
+
" 2: child_222",
|
|
221
|
+
)
|
|
222
|
+
collapsed = (
|
|
223
|
+
"+ /: root ",
|
|
224
|
+
*(" " * size[0] for _ in range(size[1] - 1)),
|
|
225
|
+
)
|
|
226
|
+
collapsed_last = (
|
|
227
|
+
"- /: root ",
|
|
228
|
+
" - 1/: nested_1 ",
|
|
229
|
+
" - 1/: nested_11",
|
|
230
|
+
" 1: child_111",
|
|
231
|
+
" 2: child_112",
|
|
232
|
+
" - 2/: nested_12",
|
|
233
|
+
" 1: child_121",
|
|
234
|
+
" 2: child_122",
|
|
235
|
+
" - 2/: nested_2 ",
|
|
236
|
+
" - 1/: nested_21",
|
|
237
|
+
" 1: child_211",
|
|
238
|
+
" 2: child_212",
|
|
239
|
+
" + 2/: nested_22",
|
|
240
|
+
" ",
|
|
241
|
+
" ",
|
|
242
|
+
)
|
|
243
|
+
self.assertEqual(expanded, widget.render(size).decoded_text)
|
|
244
|
+
widget.keypress(size, "page down")
|
|
245
|
+
widget.keypress(size, "-")
|
|
246
|
+
self.assertEqual(collapsed_last, widget.render(size).decoded_text)
|
|
247
|
+
widget.keypress(size, "left")
|
|
248
|
+
widget.keypress(size, "-")
|
|
249
|
+
self.assertEqual(
|
|
250
|
+
(
|
|
251
|
+
"- /: root ",
|
|
252
|
+
" - 1/: nested_1 ",
|
|
253
|
+
" - 1/: nested_11",
|
|
254
|
+
" 1: child_111",
|
|
255
|
+
" 2: child_112",
|
|
256
|
+
" - 2/: nested_12",
|
|
257
|
+
" 1: child_121",
|
|
258
|
+
" 2: child_122",
|
|
259
|
+
" + 2/: nested_2 ",
|
|
260
|
+
" ",
|
|
261
|
+
" ",
|
|
262
|
+
" ",
|
|
263
|
+
" ",
|
|
264
|
+
" ",
|
|
265
|
+
" ",
|
|
266
|
+
),
|
|
267
|
+
widget.render(size).decoded_text,
|
|
268
|
+
)
|
|
269
|
+
widget.keypress(size, "right")
|
|
270
|
+
self.assertEqual(collapsed_last, widget.render(size).decoded_text)
|
|
271
|
+
widget.keypress(size, "home")
|
|
272
|
+
widget.keypress(size, "-")
|
|
273
|
+
self.assertEqual(collapsed, widget.render(size).decoded_text)
|