77 lines
3 KiB
Python
77 lines
3 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import toga
|
||
|
|
|
||
|
|
|
||
|
|
class MainWindow(toga.MainWindow):
|
||
|
|
"""Main application window with content-switching layout.
|
||
|
|
|
||
|
|
Provides:
|
||
|
|
- Header buttons: Recipes, Inventory, New Recipe
|
||
|
|
- Menus: File/New Recipe, File/Exit, Help/About
|
||
|
|
- Placeholder content views swapped into the main content area
|
||
|
|
"""
|
||
|
|
|
||
|
|
def __init__(self, app: toga.App):
|
||
|
|
super().__init__(title="FunkyJuice Recipes")
|
||
|
|
# Keep a reference to the App without binding the Window to it yet.
|
||
|
|
# The actual association is done when the app assigns `app.main_window = ...`.
|
||
|
|
self._app_ref = app
|
||
|
|
|
||
|
|
# Lazy imports to avoid import cycles
|
||
|
|
from .views.recipe_list import RecipeListView
|
||
|
|
from .views.inventory import InventoryView
|
||
|
|
from .views.edit_recipe import EditRecipeView
|
||
|
|
|
||
|
|
self._RecipeListView = RecipeListView
|
||
|
|
self._InventoryView = InventoryView
|
||
|
|
self._EditRecipeView = EditRecipeView
|
||
|
|
|
||
|
|
# Container where we swap views
|
||
|
|
self.content_container = toga.Box(style=toga.style.Pack(direction="column", margin=8))
|
||
|
|
|
||
|
|
# Header nav using button wrapper classes
|
||
|
|
from .buttons.recipes_nav import RecipesNavButton
|
||
|
|
from .buttons.inventory_nav import InventoryNavButton
|
||
|
|
from .buttons.new_recipe_nav import NewRecipeNavButton
|
||
|
|
|
||
|
|
header = toga.Box(style=toga.style.Pack(direction="row", margin=(0, 0, 8, 0)))
|
||
|
|
header.add(RecipesNavButton(self._app_ref, self.content_container))
|
||
|
|
header.add(InventoryNavButton(self._app_ref, self.content_container))
|
||
|
|
header.add(NewRecipeNavButton(self._app_ref, self.content_container))
|
||
|
|
|
||
|
|
# Compose the window content
|
||
|
|
root = toga.Box(style=toga.style.Pack(direction="column", margin=12))
|
||
|
|
root.add(header)
|
||
|
|
root.add(self.content_container)
|
||
|
|
self.content = root
|
||
|
|
|
||
|
|
# Menus
|
||
|
|
async def do_about(widget=None): # pragma: no cover - trivial UI wiring
|
||
|
|
await self.dialog(toga.InfoDialog("About", "FunkyJuice Recipes\nVersion 0.1.0"))
|
||
|
|
|
||
|
|
# Commands for menu bar
|
||
|
|
from .commands.recipes import RecipesCommand
|
||
|
|
from .commands.new_recipe import NewRecipeCommand
|
||
|
|
from .commands.exit import ExitCommand
|
||
|
|
from .commands.about import AboutCommand
|
||
|
|
|
||
|
|
recipes_cmd = RecipesCommand(self._app_ref, self.content_container)
|
||
|
|
new_recipe_cmd = NewRecipeCommand(self._app_ref, self.content_container)
|
||
|
|
exit_cmd = ExitCommand(self._app_ref, self.content_container)
|
||
|
|
about_cmd = AboutCommand(self._app_ref, self.content_container)
|
||
|
|
|
||
|
|
self._app_ref.commands.add(recipes_cmd, new_recipe_cmd, exit_cmd, about_cmd)
|
||
|
|
|
||
|
|
# Initial content
|
||
|
|
# self.show_recipes()
|
||
|
|
self.content_container.add(self._RecipeListView(self._app_ref))
|
||
|
|
|
||
|
|
|
||
|
|
def build_main_window(app: toga.App) -> toga.MainWindow:
|
||
|
|
"""Backward-compatible factory to build the main window instance."""
|
||
|
|
return MainWindow(app)
|
||
|
|
|
||
|
|
|
||
|
|
__all__ = ["MainWindow", "build_main_window"]
|