Generic renderer for settings screens. Font sizes match pager_menu.py's tuned values for 480x222: labels/values: 16px (TTF_MEDIUM — proven readable on this screen) bottom hint: 13px (TTF_SMALL) Row height 28px gives 6 visible rows in the content area.
(self, screen_id, title)
| 954 | return self.CYAN |
| 955 | |
| 956 | def _draw_settings_screen(self, screen_id, title): |
| 957 | """Generic renderer for settings screens. |
| 958 | |
| 959 | Font sizes match pager_menu.py's tuned values for 480x222: |
| 960 | labels/values: 16px (TTF_MEDIUM — proven readable on this screen) |
| 961 | bottom hint: 13px (TTF_SMALL) |
| 962 | Row height 28px gives 6 visible rows in the content area. |
| 963 | """ |
| 964 | self.pager.clear(self.DARK_BG) |
| 965 | self._draw_screen_header(title) |
| 966 | |
| 967 | settings = self._get_settings_for_screen(screen_id) |
| 968 | if not settings: |
| 969 | self.pager.draw_ttf_centered(100, "No settings available", self.GRAY, self.font_arial, 20) |
| 970 | return |
| 971 | |
| 972 | # Layout constants — tuned for 480x222 with 24px header + 18px hint bar |
| 973 | ROW_H = 28 # 28px per row → 6 rows in 168px content area |
| 974 | HINT_H = 18 # bottom hint bar height |
| 975 | y_start = 26 # immediately after 24px header + 2px gap |
| 976 | content_h = self.height - y_start - HINT_H |
| 977 | visible = content_h // ROW_H # = 168 // 28 = 6 |
| 978 | |
| 979 | # Column positions |
| 980 | SEL_X = 4 # ">" selection arrow |
| 981 | LABEL_X = 20 # setting label start |
| 982 | VALUE_X = 330 # current value (right side) |
| 983 | DOT_X = self.width - 10 # type-indicator dot |
| 984 | |
| 985 | scroll = self._settings_scroll.get(screen_id, 0) |
| 986 | selected = self._settings_selected.get(screen_id, 0) |
| 987 | |
| 988 | for i in range(scroll, min(scroll + visible, len(settings))): |
| 989 | s = settings[i] |
| 990 | row_y = y_start + (i - scroll) * ROW_H |
| 991 | is_selected = (i == selected) |
| 992 | |
| 993 | # Row background |
| 994 | if is_selected: |
| 995 | self.pager.fill_rect(2, row_y, self.width - 4, ROW_H - 2, self.BLUE) |
| 996 | elif (i - scroll) % 2 == 0: |
| 997 | self.pager.fill_rect(2, row_y, self.width - 4, ROW_H - 2, self.CARD_BG) |
| 998 | |
| 999 | # Selection arrow |
| 1000 | if is_selected: |
| 1001 | self.pager.draw_ttf(SEL_X, row_y + 6, ">", self.CYAN, self.font_arial, 14) |
| 1002 | |
| 1003 | # Label — 16px, same as pager_menu TTF_MEDIUM |
| 1004 | label_color = self.WHITE if is_selected else self.LIGHT_GRAY |
| 1005 | self.pager.draw_ttf(LABEL_X, row_y + 6, s['label'][:26], label_color, self.font_arial, 16) |
| 1006 | |
| 1007 | # Value — 16px, color-coded by meaning |
| 1008 | val_str = self._get_setting_value_str(s) |
| 1009 | val_color = self._get_setting_value_color(s) if not is_selected else self.WHITE |
| 1010 | self.pager.draw_ttf(VALUE_X, row_y + 6, val_str[:10], val_color, self.font_arial, 16) |
| 1011 | |
| 1012 | # Small type-indicator dot (green=bool, cyan=int, yellow=choice) |
| 1013 | type_colors = {'bool': self.GREEN, 'int': self.CYAN, 'choice': self.YELLOW} |
no test coverage detected