0.5.0 — VIS Widgets, Help Button & Popup Polish#

Released — current version

Adds general-purpose widgets, a one-line Help-button hookup, standard confirmation dialogs, and a flicker-free popup centring helper. The project-upgrade-tool work originally planned for 0.5 has been deferred (see “Out of scope” below).

VIS Widgets#

General-purpose widgets that Tkinter does not provide natively. All exported from VIStk.Widgets.

  • Tooltip — hover tooltip bound to any widget. text may be a str or a zero-arg callable for state-dependent tooltips. Cleans up its after callback on widget destroy:

    from VIStk.Widgets import Tooltip
    Tooltip(my_button, text="Save the current document")
    
  • CollapsibleFrame — frame whose body is hidden under a header button. Pack children into cf.body; cf.expanded_var is a BooleanVar callers can bind for shared state:

    cf = CollapsibleFrame(parent, text="Advanced", expanded=False)
    cf.pack(fill="x")
    ttk.Entry(cf.body).pack()
    
  • AutocompleteEntryttk.Entry with a filtered dropdown Listbox. values is either an iterable or a callable (text) -> iterable. Keyboard: Up/Down move, Return accepts, Tab accepts the first match, Escape closes. match="prefix" (default) or "contains".

  • DateEntryttk.Entry + calendar-picker button. No third-party dependencies. get() returns date | None, set(date) sets programmatically, invalid manual input reverts to the last valid value on focus-out.

Confirmation Dialogs#

Drop-in helpers so screens stop reimplementing the tkinter.messagebox dance:

from VIStk.Widgets import confirm, confirm_discard

if confirm(parent, title="Delete?", message="Really delete?"):
    ...

choice = confirm_discard(parent, name="Work Order #12345")
if choice == "cancel":
    return False                # veto on_quit
if choice == "save":
    _save()
return True
  • confirm(...) -> bool — two-button Yes/No.

  • confirm_discard(...) -> "save" | "discard" | "cancel" — three- button Save / Discard / Cancel. Closing the window or pressing Escape both return "cancel".

Both dialogs are modal, transient over their parent, centred via WindowGeometry.center_on(), and never flash at the OS default position before centring.

Help Button & Per-Screen docs URL#

Wiring a top-level Help button is a one-liner from .VIS/Host.py:

from VIStk.Widgets import HostMenu
from VIStk.Objects import open_active_screen_docs

host_menu.add_project_command("Help", open_active_screen_docs)

HostMenu.add_project_command(label, command)#

New companion to set_project_items. Adds a clickable leaf entry directly on the menubar (not a cascade). Survives all tab changes; removed only by clear_project_items.

Per-screen docs field#

Each entry under Screens.<name> in project.json may carry a docs URL:

"Screens": {
  "Home":     {"...": "...", "docs": null},
  "Settings": {"...": "...", "docs": "https://example.com/docs/settings"}
},
"defaults": {
  "icon": "...",
  "docs": "https://example.com/docs"
}
  • Screen.docs: str | None — per-screen URL. None means “fall through to project default”.

  • Project.default_docs: str | None — project-level fallback.

  • Project.resolve_docs_url(screen_name=None) — runs the fallback chain (screen docs -> default_docs -> None).

  • Project.active_screen_name — property returning the active tab’s base_name (resolved from the live tab ID introduced in 0.4.7).

  • VIStk.Objects.open_active_screen_docs() — looks up the active screen’s URL via Project().resolve_docs_url() and hands it to webbrowser.open(). Returns True on dispatch, False if no URL was configured.

URLs are passed verbatim to webbrowser.open(). No path normalisation — authors write fully-qualified URLs (https://, file:///, etc.).

VIS docs CLI#

VIS docs set <screen_name> <url>      # set a per-screen URL
VIS docs set --default <url>          # set the project default
VIS docs clear <screen_name>          # clear a per-screen URL
VIS docs clear --default              # clear the project default
VIS docs list                         # show all configured URLs

The scaffolder (VIS add screen) writes "docs": null into new entries so the field is discoverable.

Out of Scope (deferred)#

  • Project Upgrade Tool (VIS upgrade) — the originally planned 0.5 epic is deferred to 0.7 (which is already titled “Defaults & Navigation, update tools” — a better fit).

  • Color palette feature — deferred; tracked separately for a later 0.5.x or 0.6.x.

  • ``is_dirty`` auto-generated ``on_quit`` — the confirm_discard helper covers the manual case; the auto-wrapper can land later without an API break.