From 211ebfcd01ac6e063788a5dd8bf9057b45959885 Mon Sep 17 00:00:00 2001 From: Stu Leak Date: Mon, 3 Nov 2025 11:17:44 -0500 Subject: [PATCH] =?UTF-8?q?v0.1.3=20=E2=80=94=20Centered=20Teletext=20fram?= =?UTF-8?q?e,=20added=20full=20footer=20with=20color=20band,=20and=20final?= =?UTF-8?q?ized=20header=20alignment.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 22 +++--- .../telefact_renderer.cpython-313.pyc | Bin 7611 -> 7790 bytes .../telefact_footer.cpython-313.pyc | Bin 0 -> 3644 bytes .../telefact_frame.cpython-313.pyc | Bin 3546 -> 3546 bytes .../telefact_header.cpython-313.pyc | Bin 6464 -> 6464 bytes src/core/telefact_footer.py | 30 +++---- src/core/telefact_frame.py | 2 +- src/core/telefact_header.py | 2 +- src/telefact_renderer.py | 74 ++++++++++-------- 9 files changed, 67 insertions(+), 63 deletions(-) create mode 100644 src/core/__pycache__/telefact_footer.cpython-313.pyc 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 4c62ac45ed88e16892a54c7d74fd0ce98d5f3f30..edc44021cb642a2f355545fe2e53bc1cc57f795c 100644 GIT binary patch delta 1978 zcma)6O>7%Q6y9COKZ))2f9%+avu@KQ8xl8ZBb6p4Efhqnsx69B>Wad4Yi}GkuAR?JJ&$OjPJA~<35dypD{if z5>k8pnRq6`^gyQhbTH%22w)LqOehm0;esG1O#hfx(#F-CF{+jG8qvtTBt0)=g$^6N zEsUkhu8dG_%ywsNeRhuPgIk>7N)EgWj_lqoypw(vO47s8=3t+j8M^9bDAVu5Vfw8t z%Dd^DZP*FU%1yx5qKrL=x;xv02Y}1^ZWb~-W_Sw^tM!pxE_oivE35k(M1iV~Z6Vir zl@y9)<&wE6&Cu5!hj|bE+94k_y}CNCDGzM6s57R=s2FNVDUf1bd3lRAq2p;14EmR& z>}Ur?KTFHb-Z>Z7l9>0d#p3f`%fZFku3xCN_t&ER^9`3hYtgn9z9tRSq64VHdNi?E zs+N|=uARDis@9wa*1gso{||?rS{G-lv-d5d>3MLLc!U9~cxQX9rEeuri|qnm-nAA` z(<`Z3Y&WW45KLZntOeRuy{=~(8u!4p$p8RN1;e!BY2?qW&Uh$)sPkC}S;|VeN`>T$ zW!2E6?kS?>in`V-<+QQ^-I15mvOv1f#SQ?FccFX)KowGpyS~4nAMg6#-+2=D9FyJTC^{HL*oj{JIif)#6i9=imJ20~ zg-tr?%|N;jqb7JmGKO#hK>{%OOC~>~WAkIP;DD?IgT0PdfYNW$r-K873#rA)>ST52 z^1!v(tFu@4uLoj_iE3hL^iH5-J)BrPQa!RP+zEGCPOfpsuUtc8lO@s*f?bYO^?1#{ zovsIE2L_ts>5417+8+9apL^{1lu@jd)slqWD^)IPq@>PB;}s%ZEb7z1=e4ub1$Y{T z^gT!jN0Iu_gz^ua?=QgwPaio{OLVt*S!4Iw8Xx=8wO{3%bAEZmhgeF156^SMd_TO6E zH7IRXoJE#4ZEC4Ru;EA>0CWpRKtce=WM92>jy!y9(6cXWu8=TFB0?I0-9L{K1VOVc zfdgkyi6Be>$j*9mpF@I`84GR-xru*Etvi8YF|iuoXz6gg2aJA;-f5A=`3nmji#^qz zrTn{-?@Ur}yuw)U20*+GWS#2>PpD7m;m*lI+ni3`UpH%cBZ5Lqy) zZp(|B$c3Xz;p&j(L(LD`9|4q}66h1H^4# zzCY*m*8{irD}Mw6ogAz~O<(z!=%>m9J|*t$$SHB|tqu~%1*gTFJdGBWSri%;wvGgI z@mz%IYA!k*%E>taB4W(amFp(ql3*kpb;7jF*?gfkZrVkYnB-v(T@a>(#{&IMm`F}? zmWU_g$_b!JZO(C1I<0G3Jm=Z%<+$CD9yonZoP*;Et@B}N!%J^__J;))!wSK;Np8H0 z);)&Qw#)PzkFHq$%`GL@fEyg{v2Co^AFFHe-We^0#8C8-eSATYOW`He*>d zxgr-!tXg&JTJc8tdbt_h16H{ejsM>kimWE2x(ZAMTa1O)b+@Gqe#l_~ErXVV|(P^Z1!sxnk!ny=b0Z zEa{cEO=9Jj^w|p03#Mi1d8=Hq7fic0@Q}w;(*Oof+LikqFM$G0vK3vd3#l%F!&vy;O z2S$ix%dRx(r6&_9^;s~J9SH2jWa!1jkn}w0V}?fWBqn$51@3rji)Y|sW-;#R^<{-% z4Fp?HEP6DV((oKIgrIIh4?UmMU(I^={iLXu%@x!20*C(uHS9{rd|XI#w;=1}v~E{M z=I26@E48}p22fKtE!NQL``jREDrkR(kj?SbO&ZJ9bx!bRT_3=es*Aj_Ve0JmDvg56 zfw<{m;?@uoUmRlM>l_o`Ppo6e`mpR(++@U?ZoKSrAZ`}_LP1zjSdS4P`$0HTZN6;7 zyh%T3w2?Y^bo#~M34u@l&LOhz{sF{qsW$)s 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 0000000000000000000000000000000000000000..9c6421329aab45a9abf309d3975419bb203ebd1c GIT binary patch literal 3644 zcmdT{O>7&-6`uVexgsf(k}R8|WoR8ciB_&e!Lbutjg6*?lURu*gDb*HY-F)oE~#~w zyX@=|vV;OLdMG5+g(cLks9vNViYlk7r@A*EdTK8rlv>2VD2(*vn{37CwQqL0q@pTC zbIibgJACtI=Dm5}_hz))-X2BJ{{E$4oQ@&%FZv^Be512_3OWyvjAZ6RG{#^?L@D$N zlG!wpxpS;n)@DBOS98jc)NcA}8d?O+gM1Mi4s7$^zBiVsM+Bl-ocbh5xZ&e2=9d#~YSW zxjl_=Og@C;#jw;t4mF*#ZCA(7AZ}Fo8-q}ER0pST4?6Cgsfz_~RP3L&UDqy&)2fx1 zhN72mtEIB3k3_$^fA_2VcfKe8mcZSgi$UBY;^d4j&f3__i>fQm*%d4n46CSP*C;#U z{svQF`u*=osF0Fsl!OWtcqFXZR>3H0oR2+EQdra9yMG1o08J%LPff*?XaWrUmSeM_ zpx^q+%rFWdZ*e*9KpVD2iyShWdw+{H06ka{tOL@a9Fq;G(%K#Y4L}Qa;XqkLQe>P& zMr{+)=#cPx9&8CeZB}#=o78W+*RWAi@f-=w&KR!#j7BI$Ft7<>0R-WSx=W&YfPTev zmFZ%uUnmkD+p`YgKuSE}9o;PKnHkaiT^;H*g$?;}X2ve*8ON<;u3`I@uDMR;BU@8V zF?;#iM8<8Dg^Yu>jAmoKsZo5o4VCAJpeTlAxQarK28i{88VUvu!*-4g;tr~Jr|(AV zM|$tZcEYHuXJue{p!)F!yVZGmAyQADSUbIXdVOXyyp?`yfxnvwG^Ne!Tj`5b1G5hI ztc)y=tTW4(7WiKYyRa-8C+u`lYm_#sK=hmALscqo%H6M|7c1H0mHAK%6z)8PTy#BM;?J`$-Yo6)P`N5a1!gh~ogO4%mZ) zuu7{5g&5&s*dclBFXiYTXqjV^)QC}MPAjkGW zV(;JyFn8VuaR)u^>fY|^uO43OTkTsAo^%{pa#!Y;=T|;k{_Jtb>kIGHtti(}jI zzFNF*o%zH0-<{u(H&6XJ^QX+C^N-^nz2H!1KTgyAc^5cDLaJ#LEy5Ox+TOCzgoOxT z0a$SVCoDoa{s7CpfP<}Rv%-+Ny*v79lnVzS0q8MVder+GAjfMKbE65A923m4B00Eo zN2U-`kJEy35Nr;FOoSF7nH>aQEny-9t8m^buOoCL5xDT3*Wrn8;yPT|uz&ftQ;UNzYQ^MGF6OWo*^v>5r}w+WGXhY|!&+B=fY1a7G#LKY*k6?@ZMbN9&31oi@~#dVxZ1QSaoW zkoQ*caZYa!AKR3C5;G3YUVz^CxYSNx4;DQA;Pntyl#-pVn6w{Pl%G~qvoVrTl!AdB z*EB5MvSB!)D0y2`6igFB_`IRHI7Pc0u*u_<7d!qT)paWh;NLYgMRkE|(-nwYQ9ehW zquz;NN`6n!zb%|;5Whgr*>FhMNk&7jR7*PuKAV$Y)6erXAG*p^o%PAp`Im_HpC9TD zeF&NzM86wv_}_=}qqBec#P5GGdHst|KCMlD`qDFbIUEW3=j3e)=RuCb3u}nJu!h{m zn@jPY#9oBHf0wC~^osMdD7@{T)+PKt=xBN!db~Rv!!R$Ch&l7`@Y_uE1p?vC`VTH+ Buzmml literal 0 HcmV?d00001 diff --git a/src/core/__pycache__/telefact_frame.cpython-313.pyc b/src/core/__pycache__/telefact_frame.cpython-313.pyc index 22ec12c71fde82f4c6aa7e380f73e6e24b3c0850..744aa855970b1a72d8eedaa7402d11537c6dafdf 100644 GIT binary patch delta 23 dcmca5eM_3}GcPX}0}w=C<;Z-_xsmS-F924w2RQ%$ delta 23 dcmca5eM_3}GcPX}0}!xX<+Q@f?7XVH11^xg4 diff --git a/src/core/__pycache__/telefact_header.cpython-313.pyc b/src/core/__pycache__/telefact_header.cpython-313.pyc index d2ed1c3fb342d80d1b5ace6fa7a89d90ee88b9e0..405355f9472ac354ab7d3d69ca753aca647d384b 100644 GIT binary patch delta 22 ccmX?Lbij!BGcPX}0}v!#<;YyMk=Ixf08SPLWdHyG delta 22 ccmX?Lbij!BGcPX}0}#|- 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)