feat: implement flashing support (0x08/0x09) with 1Hz timer
This commit is contained in:
@@ -63,6 +63,12 @@ class TeletextCanvas(QWidget):
|
||||
self.service = None # Reference to TeletextService for DRCS/Shared data
|
||||
self.subset_idx = 0 # Default English
|
||||
|
||||
# Flashing state
|
||||
self.flash_on = True
|
||||
self.flash_timer = QTimer(self)
|
||||
self.flash_timer.timeout.connect(self.toggle_flash)
|
||||
self.flash_timer.start(500) # 500ms toggle (1Hz flash rate)
|
||||
|
||||
# Teletext is 40 columns x 25 rows
|
||||
# We will render to a fixed size QImage and scale it
|
||||
self.cols = 40
|
||||
@@ -87,6 +93,12 @@ class TeletextCanvas(QWidget):
|
||||
self.cursor_is_graphics = False # Tracked during draw
|
||||
# Blinking cursor timer could be added, for now static inverted is fine or toggle on timer elsewhere
|
||||
|
||||
def toggle_flash(self):
|
||||
self.flash_on = not self.flash_on
|
||||
if self.page:
|
||||
self.redraw()
|
||||
self.update()
|
||||
|
||||
def get_byte_at(self, x, y):
|
||||
if not self.page: return 0
|
||||
|
||||
@@ -274,6 +286,7 @@ class TeletextCanvas(QWidget):
|
||||
hold_graphics = False
|
||||
held_char = 0x20 # Space
|
||||
double_height = False
|
||||
flashing = False
|
||||
|
||||
last_visible_idx = -1
|
||||
bg_segments = [(0, bg)] # Track BG changes: (index, color)
|
||||
@@ -364,6 +377,10 @@ class TeletextCanvas(QWidget):
|
||||
break
|
||||
painter.fillRect(k * self.cell_w, y, self.cell_w, self.cell_h * 2, cell_bg)
|
||||
|
||||
elif byte_val == 0x08: # Start Flashing
|
||||
flashing = True
|
||||
elif byte_val == 0x09: # Steady
|
||||
flashing = False
|
||||
elif byte_val == 0x19: # Contiguous Graphics
|
||||
contiguous = True
|
||||
elif byte_val == 0x1A: # Separated Graphics
|
||||
@@ -410,45 +427,60 @@ class TeletextCanvas(QWidget):
|
||||
|
||||
# Draw Foreground
|
||||
if draw_fg:
|
||||
# Calculate height
|
||||
# For Mosaics, we use the height param.
|
||||
# For Alphanumerics, we scale the painter.
|
||||
# If flashing is active and flash is in 'off' state, skip drawing FG
|
||||
if not (flashing and not self.flash_on):
|
||||
# Calculate height
|
||||
# For Mosaics, we use the height param.
|
||||
# For Alphanumerics, we scale the painter.
|
||||
|
||||
if is_control:
|
||||
# "Set-at" spacing attribute? Teletext control codes occupy a space
|
||||
# unless "Hold Graphics" replaces it with previous graphic char.
|
||||
if hold_graphics and graphics_mode:
|
||||
if double_height:
|
||||
self.draw_mosaic(painter, x, y, held_char, fg, contiguous, height=self.cell_h * 2)
|
||||
if is_control:
|
||||
# "Set-at" spacing attribute? Teletext control codes occupy a space
|
||||
# unless "Hold Graphics" replaces it with previous graphic char.
|
||||
if hold_graphics and graphics_mode:
|
||||
if double_height:
|
||||
self.draw_mosaic(painter, x, y, held_char, fg, contiguous, height=self.cell_h * 2)
|
||||
else:
|
||||
self.draw_mosaic(painter, x, y, held_char, fg, contiguous)
|
||||
else:
|
||||
self.draw_mosaic(painter, x, y, held_char, fg, contiguous)
|
||||
# Draw space (nothing, since we filled BG)
|
||||
pass
|
||||
else:
|
||||
# Draw space (nothing, since we filled BG)
|
||||
pass
|
||||
else:
|
||||
# Check for DRCS
|
||||
drcs_char = None
|
||||
if self.page and hasattr(self, 'parent') and hasattr(self.parent(), 'service'):
|
||||
# Try to find drcs in service
|
||||
service = self.parent().service
|
||||
# For now, assume Set 0 if we have drcs_data for this code
|
||||
drcs_char = service.drcs_data.get((0, byte_val))
|
||||
# Check for DRCS
|
||||
drcs_char = None
|
||||
if self.page and hasattr(self, 'parent') and hasattr(self.parent(), 'service'):
|
||||
# Try to find drcs in service
|
||||
service = self.parent().service
|
||||
# For now, assume Set 0 if we have drcs_data for this code
|
||||
drcs_char = service.drcs_data.get((0, byte_val))
|
||||
|
||||
# Alternatively, if we just want it to work in the test where we might not have parent()
|
||||
# We can store a reference to the service in the canvas
|
||||
if not drcs_char and hasattr(self, 'service') and self.service:
|
||||
drcs_char = self.service.drcs_data.get((0, byte_val))
|
||||
# Alternatively, if we just want it to work in the test where we might not have parent()
|
||||
# We can store a reference to the service in the canvas
|
||||
if not drcs_char and hasattr(self, 'service') and self.service:
|
||||
drcs_char = self.service.drcs_data.get((0, byte_val))
|
||||
|
||||
if drcs_char:
|
||||
self.draw_drcs(painter, x, y, drcs_char, fg, double_height)
|
||||
elif graphics_mode:
|
||||
# Mosaic Graphics
|
||||
h_mos = self.cell_h * 2 if double_height else self.cell_h
|
||||
if (0x20 <= byte_val <= 0x3F) or (0x60 <= byte_val <= 0x7F):
|
||||
self.draw_mosaic(painter, x, y, byte_val, fg, contiguous, height=h_mos)
|
||||
held_char = byte_val
|
||||
if drcs_char:
|
||||
self.draw_drcs(painter, x, y, drcs_char, fg, double_height)
|
||||
elif graphics_mode:
|
||||
# Mosaic Graphics
|
||||
h_mos = self.cell_h * 2 if double_height else self.cell_h
|
||||
if (0x20 <= byte_val <= 0x3F) or (0x60 <= byte_val <= 0x7F):
|
||||
self.draw_mosaic(painter, x, y, byte_val, fg, contiguous, height=h_mos)
|
||||
held_char = byte_val
|
||||
else:
|
||||
# Capital letter in graphics mode? Usually shows char?
|
||||
char = get_char(byte_val, self.subset_idx)
|
||||
painter.setPen(fg)
|
||||
if double_height:
|
||||
painter.save()
|
||||
painter.translate(x, y)
|
||||
painter.scale(1, 2)
|
||||
painter.drawText(QRect(0, 0, self.cell_w, self.cell_h), Qt.AlignmentFlag.AlignCenter, char)
|
||||
painter.restore()
|
||||
else:
|
||||
painter.drawText(QRect(x, y, self.cell_w, self.cell_h), Qt.AlignmentFlag.AlignCenter, char)
|
||||
held_char = 0x20
|
||||
else:
|
||||
# Capital letter in graphics mode? Usually shows char?
|
||||
# Alphanumeric
|
||||
char = get_char(byte_val, self.subset_idx)
|
||||
painter.setPen(fg)
|
||||
if double_height:
|
||||
@@ -459,19 +491,6 @@ class TeletextCanvas(QWidget):
|
||||
painter.restore()
|
||||
else:
|
||||
painter.drawText(QRect(x, y, self.cell_w, self.cell_h), Qt.AlignmentFlag.AlignCenter, char)
|
||||
held_char = 0x20
|
||||
else:
|
||||
# Alphanumeric
|
||||
char = get_char(byte_val, self.subset_idx)
|
||||
painter.setPen(fg)
|
||||
if double_height:
|
||||
painter.save()
|
||||
painter.translate(x, y)
|
||||
painter.scale(1, 2)
|
||||
painter.drawText(QRect(0, 0, self.cell_w, self.cell_h), Qt.AlignmentFlag.AlignCenter, char)
|
||||
painter.restore()
|
||||
else:
|
||||
painter.drawText(QRect(x, y, self.cell_w, self.cell_h), Qt.AlignmentFlag.AlignCenter, char)
|
||||
# Draw Cursor
|
||||
# Invert the cell at cursor position
|
||||
if draw_fg and self.cursor_visible and c == self.cursor_x and row == self.cursor_y:
|
||||
|
||||
Reference in New Issue
Block a user