diff --git a/plugins/masters-tournament/masters_renderer.py b/plugins/masters-tournament/masters_renderer.py index 6899412..365fa8e 100644 --- a/plugins/masters-tournament/masters_renderer.py +++ b/plugins/masters-tournament/masters_renderer.py @@ -825,13 +825,13 @@ def render_countdown(self, days: int, hours: int, minutes: int) -> Optional[Imag img = self._draw_gradient_bg(COLORS["masters_dark"], COLORS["masters_green"]) draw = ImageDraw.Draw(img) - # Countdown text + # Countdown text — show days + hours for context, or hours:minutes when < 1 day if days > 0: - count_text = str(days) - unit_text = "DAYS" if days > 1 else "DAY" + count_text = f"{days}d {hours}h" + unit_text = "UNTIL THE MASTERS" elif hours > 0: count_text = f"{hours}:{minutes:02d}" - unit_text = "HOURS" + unit_text = "HOURS TO GO" else: count_text = "NOW" unit_text = "" @@ -840,63 +840,67 @@ def render_countdown(self, days: int, hours: int, minutes: int) -> Optional[Imag min_right_width = 40 if self.tier == "large": logo = self.logo_loader.get_masters_logo( - max_width=int(self.width * 0.55), - max_height=self.height - 6, + max_width=int(self.width * 0.45), + max_height=self.height - 4, ) if logo and (self.width - logo.width - 12) >= min_right_width: - lx = 4 + lx = 3 ly = (self.height - logo.height) // 2 self._draw_logo_with_glow(img, logo, lx, ly) right_x = lx + logo.width + 6 right_w = self.width - right_x - 2 right_cx = right_x + right_w // 2 - until_text = "UNTIL THE MASTERS" - utw = self._text_width(draw, until_text, self.font_detail) - if utw > right_w: - until_text = "TO MASTERS" - utw = self._text_width(draw, until_text, self.font_detail) - detail_h = self._text_height(draw, "A", self.font_detail) count_h = self._text_height(draw, count_text, self.font_score) - block_h = detail_h + 2 + count_h + 2 + detail_h + # Big number on top, label underneath + block_h = count_h + 3 + detail_h block_y = max(2, (self.height - block_h) // 2) - draw.text((right_cx - utw // 2, block_y), - until_text, fill=COLORS["white"], font=self.font_detail) cw = self._text_width(draw, count_text, self.font_score) - count_y = block_y + detail_h + 2 - self._text_shadow(draw, (right_cx - cw // 2, count_y), + self._text_shadow(draw, (right_cx - cw // 2, block_y), count_text, self.font_score, COLORS["masters_yellow"]) - if unit_text: - uw = self._text_width(draw, unit_text, self.font_detail) - draw.text((right_cx - uw // 2, count_y + count_h + 2), - unit_text, fill=COLORS["light_gray"], font=self.font_detail) + + label = unit_text + lw = self._text_width(draw, label, self.font_detail) + if lw > right_w: + label = "TO MASTERS" + lw = self._text_width(draw, label, self.font_detail) + draw.text((right_cx - lw // 2, block_y + count_h + 3), + label, fill=COLORS["light_gray"], font=self.font_detail) return img - # Compact layout: logo centered at top, countdown below + # Compact layout: logo centered at top (larger), countdown below logo = self.logo_loader.get_masters_logo( - max_width=min(self.width - 10, 48), - max_height=min(self.height // 3, 20), + max_width=min(self.width - 6, 56), + max_height=min(int(self.height * 0.45), 28), ) + logo_bottom = 3 if logo: lx = (self.width - logo.width) // 2 - self._draw_logo_with_glow(img, logo, lx, 3) + self._draw_logo_with_glow(img, logo, lx, 2) + logo_bottom = 2 + logo.height + 2 + + # Position text below logo: label once, then big countdown + remaining = self.height - logo_bottom + detail_h = self._text_height(draw, "A", self.font_detail) + count_h = self._text_height(draw, count_text, self.font_score) + + if self.tier == "tiny": + label = "TO MASTERS" + else: + label = unit_text - mid_y = self.height // 2 - until_text = "TO MASTERS" if self.tier == "tiny" else "UNTIL THE MASTERS" - uw = self._text_width(draw, until_text, self.font_detail) - draw.text(((self.width - uw) // 2, mid_y - 6), - until_text, fill=COLORS["white"], font=self.font_detail) + text_block_h = count_h + 2 + detail_h + text_y = logo_bottom + max(0, (remaining - text_block_h) // 2) cw = self._text_width(draw, count_text, self.font_score) - self._text_shadow(draw, ((self.width - cw) // 2, mid_y + 4), + self._text_shadow(draw, ((self.width - cw) // 2, text_y), count_text, self.font_score, COLORS["masters_yellow"]) - if unit_text: - uw2 = self._text_width(draw, unit_text, self.font_detail) - draw.text(((self.width - uw2) // 2, mid_y + 16), - unit_text, fill=COLORS["light_gray"], font=self.font_detail) + lw = self._text_width(draw, label, self.font_detail) + draw.text(((self.width - lw) // 2, text_y + count_h + 2), + label, fill=COLORS["light_gray"], font=self.font_detail) return img diff --git a/plugins/masters-tournament/masters_renderer_enhanced.py b/plugins/masters-tournament/masters_renderer_enhanced.py index 4451899..b83f245 100644 --- a/plugins/masters-tournament/masters_renderer_enhanced.py +++ b/plugins/masters-tournament/masters_renderer_enhanced.py @@ -328,16 +328,32 @@ def render_live_alert( return img def render_course_overview(self, page: int = 0) -> Optional[Image.Image]: - """Render Augusta National overview - paginated front/back nine.""" + """Render Augusta National overview - paginated across all 18 holes.""" img = self._draw_gradient_bg(COLORS["masters_dark"], COLORS["masters_green"]) draw = ImageDraw.Draw(img) - if page % 2 == 0: - title = "FRONT NINE" - holes = range(1, 10) + font = self.font_detail + + # Calculate how many holes fit on screen + content_top = self.header_height + 3 + content_bottom = self.height - self.footer_height - 4 + usable_h = content_bottom - content_top + line_h = self._text_height(draw, "A", font) + 3 + max_holes = max(1, usable_h // line_h) + + # Paginate across all 18 holes + all_holes = list(range(1, 19)) + total_pages = max(1, (len(all_holes) + max_holes - 1) // max_holes) + page = page % total_pages + + start = page * max_holes + holes = all_holes[start : start + max_holes] + + # Title based on which nine we're showing + if holes[0] <= 9: + title = "FRONT NINE" if holes[-1] <= 9 else "FRONT/BACK" else: title = "BACK NINE" - holes = range(10, 19) self._draw_header_bar(img, draw, title, show_logo=True) @@ -347,35 +363,25 @@ def render_course_overview(self, page: int = 0) -> Optional[Image.Image]: draw.text((2, y), f"Par {par}", fill=COLORS["white"], font=self.font_body) return img - y = self.header_height + 3 - font = self.font_detail - line_h = self._text_height(draw, "A", font) + 3 - - # Show each hole with spacing + y = content_top for h in holes: info = AUGUSTA_HOLES[h] - # Hole number in yellow num_text = f"{h:2d}" draw.text((3, y), num_text, fill=COLORS["masters_yellow"], font=font) - # Hole name name = info["name"] if self.tier == "small": name = name[:10] draw.text((18, y), name, fill=COLORS["white"], font=font) - # Par and yardage right-aligned par_text = f"P{info['par']} {info['yardage']}y" pw = self._text_width(draw, par_text, font) draw.text((self.width - pw - 3, y), par_text, fill=COLORS["light_gray"], font=font) y += line_h - if y > self.height - self.footer_height - 4: - break - # Page dots (2 pages: front/back) - self._draw_page_dots(draw, page % 2, 2) + self._draw_page_dots(draw, page, total_pages) return img