diff --git a/main.py b/main.py index 8f24d67..3292e13 100644 --- a/main.py +++ b/main.py @@ -1,13 +1,12 @@ # ============================================================ -# File: /home/stu/Projects/Local REPO/telefact/main.py +# File: /telefact/main.py # Description: # Entry point for the Telefact Broadcaster mode. # Initializes the Tkinter window, loads configuration, -# and renders the Teletext grid with dynamic header. +# and renders the Teletext grid with dynamic header/footer. # ============================================================ import tkinter as tk - from src.config_manager import ConfigManager from src.telefact_renderer import TelefactRenderer from src.core.telefact_frame import TelefactFrame @@ -31,34 +30,33 @@ def main(): height=config["ScreenHeight"], show_grid=config.get("ShowGrid", False), font_path=config["Font"]["Path"], + font_size=config["Font"]["Size"], ) # --- Prepare frame --- frame = TelefactFrame() - # --- Initialize header --- + # --- Header --- header = TelefactHeader(frame, config) header.render() header.update_time(root, renderer) - # --- Initialize footer --- - footer = TelefactFooter(frame, config) - footer.render_test_footer() - - # --- Body & footer test content --- + # --- Body content --- formatter = TelefactFormatter(frame) formatter.add_body_line(1, "Welcome to the Telefact Broadcaster base.", align="center", color="white") formatter.add_body_line(3, "Press Q or ESC to exit.", align="center", color="cyan") - formatter.set_footer("PAGE 100 TELEFACT", align="center", color="green") - # --- Render frame --- + # --- Footer (replaces old PAGE 100 TELEFACT) --- + footer = TelefactFooter(frame, config) + footer.set_footer("Telefact: The world at your fingertips", align="left", fg="yellow", bg="blue") + + # --- Render everything --- renderer.render(frame) # --- Bind exit keys --- root.bind("", lambda e: root.quit()) root.bind("q", lambda e: root.quit()) - # --- Start loop --- root.mainloop() diff --git a/src/__pycache__/telefact_renderer.cpython-313.pyc b/src/__pycache__/telefact_renderer.cpython-313.pyc index 4c62ac4..edc4402 100644 Binary files a/src/__pycache__/telefact_renderer.cpython-313.pyc and b/src/__pycache__/telefact_renderer.cpython-313.pyc differ diff --git a/src/core/__pycache__/telefact_footer.cpython-313.pyc b/src/core/__pycache__/telefact_footer.cpython-313.pyc new file mode 100644 index 0000000..9c64213 Binary files /dev/null and b/src/core/__pycache__/telefact_footer.cpython-313.pyc differ diff --git a/src/core/__pycache__/telefact_frame.cpython-313.pyc b/src/core/__pycache__/telefact_frame.cpython-313.pyc index 22ec12c..744aa85 100644 Binary files a/src/core/__pycache__/telefact_frame.cpython-313.pyc and b/src/core/__pycache__/telefact_frame.cpython-313.pyc differ diff --git a/src/core/__pycache__/telefact_header.cpython-313.pyc b/src/core/__pycache__/telefact_header.cpython-313.pyc index d2ed1c3..405355f 100644 Binary files a/src/core/__pycache__/telefact_header.cpython-313.pyc and b/src/core/__pycache__/telefact_header.cpython-313.pyc differ diff --git a/src/core/telefact_footer.py b/src/core/telefact_footer.py index 1374e97..5f94147 100644 --- a/src/core/telefact_footer.py +++ b/src/core/telefact_footer.py @@ -2,8 +2,7 @@ # File: /home/stu/Projects/Local REPO/telefact/src/core/telefact_footer.py # Description: # Dynamic Telefact footer renderer for broadcaster mode. -# Draws a single bottom-row text band with background color -# and per-page contextual support. +# Draws a single bottom-row text band with full background fill. # ============================================================ from src.core.telefact_frame import TelefactFrame @@ -22,24 +21,24 @@ class TelefactFooter: self.frame = frame self.config = config - # default colors from global config + # Default colors colours = config.get("Colours", {}) self.default_bg = colours.get("Footer", "blue") self.default_fg = colours.get("TextPrimary", "white") - # reserved footer row (last visible line) + # Reserved row (bottom row = line 24) self.row = frame.rows - 1 # -------------------------------------------------------- def clear_footer(self, bg: str | None = None): - """Clears the footer line with background fill.""" + """Clears the footer row with solid background color.""" bg_color = bg or self.default_bg for c in range(self.frame.cols): self.frame.set_cell(c, self.row, " ", self.default_fg, bg_color) # -------------------------------------------------------- def set_footer(self, text: str, align: str = "left", fg: str | None = None, bg: str | None = None): - """Draw a footer message with color and alignment control.""" + """Draw footer message with proper background fill.""" fg_color = fg or self.default_fg bg_color = bg or self.default_bg self.clear_footer(bg_color) @@ -47,25 +46,26 @@ class TelefactFooter: text = text.strip() text_len = len(text) - # --- Alignment handling --- + # Alignment if align == "center": start_col = (self.frame.cols - text_len) // 2 elif align == "right": start_col = max(self.frame.cols - text_len - 1, 0) else: - start_col = 1 + start_col = 1 # left padding - # --- Background fill --- - for c in range(self.frame.cols): - self.frame.set_cell(c, self.row, " ", fg_color, bg_color) - - # --- Text overlay --- + # Draw each character with full background for i, ch in enumerate(text): pos = start_col + i if 0 <= pos < self.frame.cols: - self.frame.set_cell(pos, self.row, ch, fg_color) + self.frame.set_cell(pos, self.row, ch, fg_color, bg_color) # -------------------------------------------------------- def render_test_footer(self): """Temporary demo for testing footer display.""" - self.set_footer("Telefact: The world at your fingertips", align="left", fg="yellow", bg="blue") + self.set_footer( + "Telefact: The world at your fingertips", + align="left", + fg="yellow", + bg="blue", + ) diff --git a/src/core/telefact_frame.py b/src/core/telefact_frame.py index 9674e28..3e5d161 100644 --- a/src/core/telefact_frame.py +++ b/src/core/telefact_frame.py @@ -1,5 +1,5 @@ # ============================================================ -# File: /home/stu/Projects/Local REPO/telefact/src/core/telefact_frame.py +# File: /telefact/src/core/telefact_frame.py # Description: # Telefact Frame (model) # Defines a 40×24 grid and logical regions for Teletext layout. diff --git a/src/core/telefact_header.py b/src/core/telefact_header.py index 3b1fa22..2a6a48c 100644 --- a/src/core/telefact_header.py +++ b/src/core/telefact_header.py @@ -1,5 +1,5 @@ # ============================================================ -# File: /home/stu/Projects/Local REPO/telefact/src/core/telefact_header.py +# File: /telefact/src/core/telefact_header.py # Description: # Dynamic Telefact header renderer for broadcaster mode. # Displays page numbers, centered service name block with diff --git a/src/telefact_renderer.py b/src/telefact_renderer.py index 5188667..194d3ca 100644 --- a/src/telefact_renderer.py +++ b/src/telefact_renderer.py @@ -1,10 +1,9 @@ # ============================================================ -# File: /home/stu/Projects/Local REPO/telefact/src/telefact_renderer.py +# File: /telefact/src/telefact_renderer.py # Description: # Telefact Renderer (Tkinter) # Renders a 40×24 Telefact grid with full foreground/background -# colour support, aligned inside a CRT-style safe area margin. -# No header/footer bars — layout calibration only. +# colour support, perfectly centered inside the window. # ============================================================ import os @@ -44,20 +43,33 @@ class TelefactRenderer: self.height = height self.show_grid = show_grid - # Teletext dimensions + # Teletext logical dimensions self.cols, self.rows = 40, 24 - # Safe area margins (simulate CRT overscan) - self.margin_x = 24 - self.margin_y = 24 - self.inner_w = width - self.margin_x * 2 - self.inner_h = height - self.margin_y * 2 + # --- Dynamic centered layout --- + # Define safe area target margins + safe_margin_x = 24 + safe_margin_y = 24 - # Per-cell dimensions - self.cell_w = self.inner_w // self.cols - self.cell_h = self.inner_h // self.rows - self.w = self.inner_w - self.h = self.inner_h + # Compute total drawable region + self.inner_w = width - safe_margin_x * 2 + self.inner_h = height - safe_margin_y * 2 + + # Compute exact per-cell dimensions (float precision) + self.cell_w = self.inner_w / self.cols + self.cell_h = self.inner_h / self.rows + + # Compute corrected total grid size (may differ slightly due to float math) + total_grid_w = self.cell_w * self.cols + total_grid_h = self.cell_h * self.rows + + # --- Center grid on screen --- + self.margin_x = (width - total_grid_w) / 2 + self.margin_y = (height - total_grid_h) / 2 + + # Cache total grid extents + self.w = total_grid_w + self.h = total_grid_h # Base colours self.colors = { @@ -101,12 +113,12 @@ class TelefactRenderer: return ("Courier New", font_size, "bold") # ------------------------------------------------------------------ - def _gx(self, col: int) -> int: - """Grid X coordinate.""" + def _gx(self, col: int) -> float: + """Grid X coordinate (precise, centered).""" return self.margin_x + col * self.cell_w - def _gy(self, row: int) -> int: - """Grid Y coordinate.""" + def _gy(self, row: int) -> float: + """Grid Y coordinate (precise, centered).""" return self.margin_y + row * self.cell_h # ------------------------------------------------------------------ @@ -115,21 +127,18 @@ class TelefactRenderer: x = self._gx(col) y = self._gy(row) - # Draw background block + # Background rectangle self.canvas.create_rectangle( - x, - y, - x + self.cell_w, - y + self.cell_h, + x, y, x + self.cell_w, y + self.cell_h, fill=PALETTE.get(bg, bg), - outline=PALETTE.get(bg, bg), + outline=PALETTE.get(bg, bg) ) - # Draw text glyph + # Foreground glyph if char.strip(): self.canvas.create_text( x + 2, - y + self.cell_h // 2, + y + self.cell_h / 2, anchor="w", text=char, font=self.font, @@ -138,7 +147,7 @@ class TelefactRenderer: # ------------------------------------------------------------------ def _draw_grid(self) -> None: - """Optional debug overlay for cell alignment.""" + """Optional grid overlay for visual debugging.""" for c in range(self.cols + 1): x = self._gx(c) self.canvas.create_line( @@ -152,20 +161,17 @@ class TelefactRenderer: # ------------------------------------------------------------------ def render(self, frame: TelefactFrame) -> None: - """Renders the full Telefact grid (foreground + background).""" + """Renders the entire 40×24 Telefact grid.""" self.canvas.delete("all") - # Fill background + # Fill full canvas background self.canvas.create_rectangle( - 0, - 0, - self.width, - self.height, + 0, 0, self.width, self.height, fill=PALETTE.get(self.colors["Background"], self.colors["Background"]), width=0, ) - # Draw all cells (bg first, then text) + # Draw text grid (each cell: bg + fg) for row in range(frame.rows): for col in range(frame.cols): ch, fg, bg = frame.get_cell(col, row)