Skip to content

Sidebar

SideBar

Bases: CTkFrame

Class for the navigation sidebar.

Source code in evaluator/frontend/components/sidebar.py
class SideBar(ctk.CTkFrame):
    """Class for the navigation sidebar."""

    def __init__(
        self,
        master: ctk.CTkFrame,
        app_state: AppState,
        run_state: RunState,
        navigate: Callable[[Literal[-1, 1], int, AppState], None],
        on_save: Callable[[AppState], None],
        on_exit: Callable[[], NoReturn],
        **kwargs,
    ):
        """Constructor."""
        super().__init__(master, **kwargs)

        self.state = app_state
        self.run = run_state
        self.navigate = navigate
        self.save = on_save
        self.exit = on_exit

        self.sidebar_frame = ctk.CTkFrame(master=master, width=140, corner_radius=0)
        self.sidebar_frame.grid(row=0, column=1, sticky="nsew")
        self.sidebar_frame.grid_rowconfigure(7, weight=1)

        padding = self.state["padding"]
        half_padding = padding // 2

        self.navigate_label = ctk.CTkLabel(
            master=self.sidebar_frame,
            text="Navigate",
            font=(self.state["font"], 16, "bold"),
        )
        self.navigate_label.grid(
            row=0, column=0, padx=padding, pady=(padding, half_padding)
        )

        self.prev_button = ctk.CTkButton(
            master=self.sidebar_frame,
            text="Previous",
            command=self._previous,
            state=("normal" if self.run["run_index"] > 0 else "disabled"),
        )
        self.prev_button.grid(row=1, column=0, padx=padding, pady=half_padding)

        self.next_button = ctk.CTkButton(
            master=self.sidebar_frame,
            text="Next",
            command=self._next,
            state=(
                "normal"
                if self.run["run_index"] < self.run["total_runs"] - 1
                else "disabled"
            ),
        )
        self.next_button.grid(row=2, column=0, padx=padding, pady=half_padding)

        self.run_counter_label = ctk.CTkLabel(
            master=self.sidebar_frame,
            text=f"Run: {self.run['run_index'] + 1} / {self.run['total_runs']}",
            font=(self.state["font"], 16, "bold"),
        )
        self.run_counter_label.grid(row=3, column=0, padx=padding, pady=half_padding)

        self.already_evaluated_label = ctk.CTkLabel(
            master=self.sidebar_frame,
            text="Already Evaluated" if self.run["already_evaluated"] else "",
            font=(self.state["font"], 16, "bold"),
            text_color="red",
        )
        self.already_evaluated_label.grid(
            row=4, column=0, padx=padding, pady=half_padding
        )

        self.save_button = ctk.CTkButton(
            master=self.sidebar_frame, text="Save", command=self._save
        )
        self.save_button.grid(row=5, column=0, padx=padding, pady=half_padding)

        self.exit_button = ctk.CTkButton(
            master=self.sidebar_frame, text="Exit", command=self._exit
        )
        self.exit_button.grid(row=6, column=0, padx=padding, pady=half_padding)

        self.appearance_label = ctk.CTkLabel(
            self.sidebar_frame,
            text="Appearance",
            font=(self.state["font"], 16, "bold"),
        )
        self.appearance_label.grid(
            row=8, column=0, padx=padding, pady=(padding, half_padding)
        )

        self.appearance_option_menu = ctk.CTkOptionMenu(
            self.sidebar_frame,
            values=["System", "Light", "Dark"],
            command=self._change_appearance_mode,
        )
        self.appearance_option_menu.grid(
            row=9, column=0, padx=padding, pady=half_padding
        )

        self.scaling_label = ctk.CTkLabel(
            master=self.sidebar_frame,
            text="UI Scaling",
            font=(self.state["font"], 16, "bold"),
        )
        self.scaling_label.grid(row=10, column=0, padx=padding, pady=half_padding)

        self.scaling_option_menu = ctk.CTkOptionMenu(
            master=self.sidebar_frame,
            values=["70%", "80%", "90%", "100%", "110%", "120%", "130%"],
            command=self._change_scaling_value,
        )
        self.scaling_option_menu.grid(
            row=11, column=0, padx=padding, pady=(half_padding, padding)
        )

    def update_state(self, run_state: RunState) -> None:
        """Updates the run state for consistency."""
        self.run = run_state
        self.run_counter_label.configure(
            text=f"Run: {self.run['run_index'] + 1} / {self.run['total_runs']}"
        )
        self.already_evaluated_label.configure(
            text="Already evaluated" if self.run["already_evaluated"] else ""
        )

    def _previous(self) -> None:
        """Callback for the previous button press."""
        new_run_index = self.run["run_index"] - 1
        if new_run_index == 0:
            self.prev_button.configure(state="disabled")
        else:
            self.prev_button.configure(state="normal")
        self.next_button.configure(state="normal")
        self.navigate(-1, new_run_index, self.state)

    def _next(self) -> None:
        """Callback for the next button press."""
        new_run_index = self.run["run_index"] + 1
        if new_run_index >= self.run["total_runs"] - 1:
            self.next_button.configure(state="disabled")
        else:
            self.next_button.configure(state="normal")
        self.prev_button.configure(state="normal")
        self.navigate(1, new_run_index, self.state)

    def _change_appearance_mode(self, new_appearance_mode: str) -> None:
        """Changes the UI color mode."""
        ctk.set_appearance_mode(new_appearance_mode)

    def _change_scaling_value(self, new_scaling: str) -> None:
        """Changes the UI scaling."""
        new_scaling_val = int(new_scaling.replace("%", "")) / 100
        ctk.set_widget_scaling(new_scaling_val)

    def _save(self) -> None:
        """Calls the save state function."""
        self.save(self.state)

    def _exit(self) -> NoReturn:
        """Calls the exit function."""
        self.save(self.state)
        self.exit()

__init__(master, app_state, run_state, navigate, on_save, on_exit, **kwargs)

Constructor.

Source code in evaluator/frontend/components/sidebar.py
def __init__(
    self,
    master: ctk.CTkFrame,
    app_state: AppState,
    run_state: RunState,
    navigate: Callable[[Literal[-1, 1], int, AppState], None],
    on_save: Callable[[AppState], None],
    on_exit: Callable[[], NoReturn],
    **kwargs,
):
    """Constructor."""
    super().__init__(master, **kwargs)

    self.state = app_state
    self.run = run_state
    self.navigate = navigate
    self.save = on_save
    self.exit = on_exit

    self.sidebar_frame = ctk.CTkFrame(master=master, width=140, corner_radius=0)
    self.sidebar_frame.grid(row=0, column=1, sticky="nsew")
    self.sidebar_frame.grid_rowconfigure(7, weight=1)

    padding = self.state["padding"]
    half_padding = padding // 2

    self.navigate_label = ctk.CTkLabel(
        master=self.sidebar_frame,
        text="Navigate",
        font=(self.state["font"], 16, "bold"),
    )
    self.navigate_label.grid(
        row=0, column=0, padx=padding, pady=(padding, half_padding)
    )

    self.prev_button = ctk.CTkButton(
        master=self.sidebar_frame,
        text="Previous",
        command=self._previous,
        state=("normal" if self.run["run_index"] > 0 else "disabled"),
    )
    self.prev_button.grid(row=1, column=0, padx=padding, pady=half_padding)

    self.next_button = ctk.CTkButton(
        master=self.sidebar_frame,
        text="Next",
        command=self._next,
        state=(
            "normal"
            if self.run["run_index"] < self.run["total_runs"] - 1
            else "disabled"
        ),
    )
    self.next_button.grid(row=2, column=0, padx=padding, pady=half_padding)

    self.run_counter_label = ctk.CTkLabel(
        master=self.sidebar_frame,
        text=f"Run: {self.run['run_index'] + 1} / {self.run['total_runs']}",
        font=(self.state["font"], 16, "bold"),
    )
    self.run_counter_label.grid(row=3, column=0, padx=padding, pady=half_padding)

    self.already_evaluated_label = ctk.CTkLabel(
        master=self.sidebar_frame,
        text="Already Evaluated" if self.run["already_evaluated"] else "",
        font=(self.state["font"], 16, "bold"),
        text_color="red",
    )
    self.already_evaluated_label.grid(
        row=4, column=0, padx=padding, pady=half_padding
    )

    self.save_button = ctk.CTkButton(
        master=self.sidebar_frame, text="Save", command=self._save
    )
    self.save_button.grid(row=5, column=0, padx=padding, pady=half_padding)

    self.exit_button = ctk.CTkButton(
        master=self.sidebar_frame, text="Exit", command=self._exit
    )
    self.exit_button.grid(row=6, column=0, padx=padding, pady=half_padding)

    self.appearance_label = ctk.CTkLabel(
        self.sidebar_frame,
        text="Appearance",
        font=(self.state["font"], 16, "bold"),
    )
    self.appearance_label.grid(
        row=8, column=0, padx=padding, pady=(padding, half_padding)
    )

    self.appearance_option_menu = ctk.CTkOptionMenu(
        self.sidebar_frame,
        values=["System", "Light", "Dark"],
        command=self._change_appearance_mode,
    )
    self.appearance_option_menu.grid(
        row=9, column=0, padx=padding, pady=half_padding
    )

    self.scaling_label = ctk.CTkLabel(
        master=self.sidebar_frame,
        text="UI Scaling",
        font=(self.state["font"], 16, "bold"),
    )
    self.scaling_label.grid(row=10, column=0, padx=padding, pady=half_padding)

    self.scaling_option_menu = ctk.CTkOptionMenu(
        master=self.sidebar_frame,
        values=["70%", "80%", "90%", "100%", "110%", "120%", "130%"],
        command=self._change_scaling_value,
    )
    self.scaling_option_menu.grid(
        row=11, column=0, padx=padding, pady=(half_padding, padding)
    )

update_state(run_state)

Updates the run state for consistency.

Source code in evaluator/frontend/components/sidebar.py
def update_state(self, run_state: RunState) -> None:
    """Updates the run state for consistency."""
    self.run = run_state
    self.run_counter_label.configure(
        text=f"Run: {self.run['run_index'] + 1} / {self.run['total_runs']}"
    )
    self.already_evaluated_label.configure(
        text="Already evaluated" if self.run["already_evaluated"] else ""
    )

_previous()

Callback for the previous button press.

Source code in evaluator/frontend/components/sidebar.py
def _previous(self) -> None:
    """Callback for the previous button press."""
    new_run_index = self.run["run_index"] - 1
    if new_run_index == 0:
        self.prev_button.configure(state="disabled")
    else:
        self.prev_button.configure(state="normal")
    self.next_button.configure(state="normal")
    self.navigate(-1, new_run_index, self.state)

_next()

Callback for the next button press.

Source code in evaluator/frontend/components/sidebar.py
def _next(self) -> None:
    """Callback for the next button press."""
    new_run_index = self.run["run_index"] + 1
    if new_run_index >= self.run["total_runs"] - 1:
        self.next_button.configure(state="disabled")
    else:
        self.next_button.configure(state="normal")
    self.prev_button.configure(state="normal")
    self.navigate(1, new_run_index, self.state)

_change_appearance_mode(new_appearance_mode)

Changes the UI color mode.

Source code in evaluator/frontend/components/sidebar.py
def _change_appearance_mode(self, new_appearance_mode: str) -> None:
    """Changes the UI color mode."""
    ctk.set_appearance_mode(new_appearance_mode)

_change_scaling_value(new_scaling)

Changes the UI scaling.

Source code in evaluator/frontend/components/sidebar.py
def _change_scaling_value(self, new_scaling: str) -> None:
    """Changes the UI scaling."""
    new_scaling_val = int(new_scaling.replace("%", "")) / 100
    ctk.set_widget_scaling(new_scaling_val)

_save()

Calls the save state function.

Source code in evaluator/frontend/components/sidebar.py
def _save(self) -> None:
    """Calls the save state function."""
    self.save(self.state)

_exit()

Calls the exit function.

Source code in evaluator/frontend/components/sidebar.py
def _exit(self) -> NoReturn:
    """Calls the exit function."""
    self.save(self.state)
    self.exit()