Skip to content

xpuz.base ¤

Page addon classes such as routing and fonts, as well as the base app instance.

Addons ¤

Convenience and utility methods for all page classes.

_confirm_route ¤

_confirm_route(
    *,
    action: Callable = None,
    condition: bool = None,
    confirmation: Dict[str, bool] = {"close": True}
) -> bool

Allow the user to confirm if they wish to route through a messagebox.

Parameters:

Name Type Description Default
action Callable

A function to call if the user confirms to route.

None
condition bool

Only perform the confirmation if True.

None
confirmation Dict[str, bool]

Passed in **kwargs syntax to the messagebox helper

{'close': True}

Returns:

Type Description
bool

The status of the route confirmation; whether it was accepted or not.

Source code in src/xpuz/base.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
def _confirm_route(
    self,
    *,
    action: Callable = None,
    condition: bool = None,
    confirmation: Dict[str, bool] = {"close": True},
) -> bool:
    """Allow the user to confirm if they wish to route through a messagebox.

    Args:
        action: A function to call if the user confirms to route.
        condition: Only perform the confirmation if `True`.
        confirmation: Passed in `**kwargs` syntax to the 
            [messagebox helper](
                utils.md#xpuz.utils.GUIHelper.confirm_with_messagebox
            )

    Returns:
        The status of the route confirmation; whether it was accepted or not.
    """

    if (
        condition
    ):  # A condition is required for this confirmation to happen
        if GUIHelper.confirm_with_messagebox(**confirmation):
            if action:
                action()
            return True  # User agreed to the route
        else:
            return False  # User didn't agree to the route

    return True  # No condition, so just return True

_route ¤

_route(
    page_ref: Literal,
    base: CTk,
    title: str,
    **kwargs: Dict[str, bool]
) -> bool

Method for all page-related classes to simplify navigation.

All class instances that use _route must have their content packed and contain 4 content generation methods, as seen in the source code.

Parameters:

Name Type Description Default
page_ref Literal

The new page's name, used to retrieve the corresponding class from locals().

required
base CTk

The main app instance.

required
title str

The new page's title.

required
**kwargs Dict[str, bool]

Confirmation dictionary routed to _confirm_route.

{}

Returns:

Type Description
bool

Status of the route; whether it was performed or not.

Source code in src/xpuz/base.py
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
def _route(
    self,
    page_ref: Literal,
    base: CTk,
    title: str,
    **kwargs: Dict[str, bool],
) -> bool:
    """Method for all page-related classes to simplify navigation.

    All class instances that use ``_route`` must have their content packed
    and contain 4 content generation methods, as seen in the source code.

    Args:
        page_ref: The new page's name, used to retrieve the corresponding 
                  class from `locals()`.
        base: The main app instance.
        title: The new page's title.
        **kwargs: Confirmation dictionary routed to 
            [_confirm_route](base.md#xpuz.base.Addons._confirm_route).

    Returns:
        Status of the route; whether it was performed or not.
    """
    if (
        kwargs
    ):  # The caller of this route has added arguments for confirmation
        if not self._confirm_route(**kwargs):
            return False  # User didn't want to route

    try:
        page_inst = locals()[page_ref](base)
    except KeyError:
        from xpuz.pages import BrowserPage, EditorPage, HomePage

        page_inst = locals()[page_ref](base)

    for widget in Base.base_container.winfo_children():  # Remove content
        widget.pack_forget()

    base.title(f"{title} ({__version__})")
    _update_cfg(Base.cfg, "m", "page", page_inst.__class__.__name__)
    try:  # Attempt to unbind existing widgets
        Base.page_inst.unbind_()
    except AttributeError:
        pass
    Base.page_inst = page_inst

    page_inst.pack(expand=True, fill="both")
    page_inst._make_containers()
    page_inst._place_containers()
    page_inst._make_content()
    page_inst._place_content()

    return True  # Route was successful

_set_fonts ¤

_set_fonts() -> None

Initialise this instance with all the required CTkFont objects.

Source code in src/xpuz/base.py
32
33
34
35
36
37
38
39
40
41
42
43
def _set_fonts(self) -> None:
    """Initialise this instance with all the required CTkFont objects."""
    self.TITLE_FONT = CTkFont(size=31, weight="bold", slant="roman")
    self.SUBHEADING_FONT = CTkFont(size=24, weight="normal", slant="roman")
    self.TEXT_FONT = CTkFont(size=15, weight="normal", slant="roman")
    self.ITALIC_TEXT_FONT = CTkFont(size=15, weight="bold", slant="roman")
    self.BOLD_TEXT_FONT = CTkFont(size=15, weight="bold", slant="roman")
    self.CATEGORY_FONT = CTkFont(size=23, weight="bold", slant="roman")
    self.BLOCK_FONT = CTkFont(size=18, weight="normal", slant="roman")
    self.HYPERLINK_FONT = CTkFont(
        size=15, weight="normal", family="Courier", underline=True
    )

Base ¤

Base(
    **kwargs: Dict[
        str,
        Union[
            Tuple[Dict[str, str], List[str]],
            Locale,
            ConfigParser,
        ],
    ]
)

Bases: CTk, Addons

The main app instance. Contains methods used by all pages.

Parameters:

Name Type Description Default
**kwargs Dict[str, Union[Tuple[Dict[str, str], List[str]], Locale, ConfigParser]]

lang_info, cfg, and locale objects passed from main.

{}
Source code in src/xpuz/base.py
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
def __init__(
    self,
    **kwargs: Dict[
        str, Union[Tuple[Dict[str, str], List[str]], Locale, ConfigParser]
    ],
) -> None:
    """Initialise the base instance and container and apply widget scaling,
    theme and appearance.

    Args:
        **kwargs: `lang_info`, `cfg`, and `locale` objects passed from 
            [main](__main__.md#xpuz.__main__.main).
    """
    super().__init__()

    base_container = CTkFrame(self)
    base_container.pack(fill="both", expand=True)
    Base.base_container = base_container

    for kwarg in kwargs:
        setattr(Base, kwarg, kwargs[kwarg])

    self.protocol("WM_DELETE_WINDOW", self._exit_handler)  # Detect exit
    if system() in ["Windows", "Linux"]:
        self.iconbitmap(
            WIN_LOGO_PATH if system() == "Windows" else LINUX_LOGO_PATH
        )
    set_appearance_mode(Base.cfg.get("m", "appearance"))
    set_default_color_theme(Base.cfg.get("m", "theme"))
    set_widget_scaling(float(Base.cfg.get("m", "scale")))
    self._set_dim()

    self._increment_launches()

    # Bring the user to the Home Page or their most recently opened page
    # since last viewing the GUI.
    page = Base.cfg.get("m", "page")
    self._route(page, self, _(PAGE_MAP[page]))

_exit_handler ¤

_exit_handler(
    restart: bool = False, webapp_on: bool = False
) -> None

Called when the event WM_DELETE_WINDOW occurs or when the the program must be restarted, in which case the restart default parameter is overridden.

Parameters:

Name Type Description Default
restart bool

Whether to perform a restart or not.

False
webapp_on bool

Whether the Flask web app is running or not.

False
Source code in src/xpuz/base.py
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
def _exit_handler(
    self, restart: bool = False, webapp_on: bool = False
) -> None:
    """Called when the event `WM_DELETE_WINDOW` occurs or when the the
    program must be restarted, in which case the ``restart`` default
    parameter is overridden.

    Args:
        restart: Whether to perform a restart or not.
        webapp_on: Whether the `Flask` web app is running or not.
    """
    # If user wants to exit/restart
    if GUIHelper.confirm_with_messagebox(exit_=True, restart=restart):
        _terminate_app()
        self.quit()

    if restart:  # Additionally perform a restart
        from xpuz.main import main

        main()

_increment_launches ¤

_increment_launches() -> None

Increment launches in the program config by 1.

Source code in src/xpuz/base.py
208
209
210
211
212
213
214
215
def _increment_launches(self) -> None:
    """Increment ``launches`` in the program config by 1."""
    return _update_cfg(
        Base.cfg,
        "misc",
        "launches",
        str(int(Base.cfg.get("misc", "launches")) + 1),
    )

_set_dim ¤

_set_dim(dim: Tuple[int, int] = DIM) -> None

Set the dimensions of the program during runtime.

Parameters:

Name Type Description Default
dim Tuple[int, int]

The dimensions.

DIM
Source code in src/xpuz/base.py
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
def _set_dim(self, dim: Tuple[int, int] = DIM) -> None:
    """Set the dimensions of the program during runtime.

    Args:
        dim: The dimensions.
    """
    scale = float(Base.cfg.get("m", "scale"))
    new_width = dim[0] * scale
    new_height = dim[1] * scale

    self.minsize(new_width, new_height)
    self.maxsize(new_width, new_height)
    self.geometry(f"{new_width}x{new_height}")

    self.update()

_toggle_fullscreen ¤

_toggle_fullscreen() -> None

Enable or disabled fullscreen mode.

Source code in src/xpuz/base.py
199
200
201
202
203
204
205
206
def _toggle_fullscreen(self) -> None:
    """Enable or disabled fullscreen mode."""
    Base.fullscreen = not Base.fullscreen
    if self.fullscreen:
        self.maxsize(self.winfo_screenwidth(), self.winfo_screenheight())
    else:
        self._set_dim()
    self.attributes("-fullscreen", Base.fullscreen)