Feature: Enhanced Editing, Hex Inspector, Color Shortcuts

- Enhanced Editing: Auto-create packets, Enter key support.
- Cursor: Fixed visibility (composition mode), click-to-move, immediate redraw.
- Hex Inspector: Added Hex Value display and input panel.
- Shortcuts: Added Color Insert buttons.
- Fixes: Resolved Hamming encoding for save, fixed duplicate spaces bug, fixed IndentationError.
This commit is contained in:
2025-12-28 21:57:44 +01:00
parent e2ed4dd1e2
commit 088ad1a320
6 changed files with 265 additions and 20 deletions

View File

@@ -62,24 +62,74 @@ def load_t42(file_path: str) -> TeletextService:
return service
def encode_hamming_8_4(value):
# Value is 4 bits (0-15)
d1 = (value >> 0) & 1
d2 = (value >> 1) & 1
d3 = (value >> 2) & 1
d4 = (value >> 3) & 1
# Parity bits (Odd parity default? Or standard Hamming?)
# Teletext spec:
# P1 = 1 + D1 + D2 + D4 (mod 2) -> Inverse of even parity check?
# Actually, simpler to look up or calculate.
# Let's match typical implementation:
# P1 (b0) covers 1,3,7 (D1, D2, D4)
# P2 (b2) covers 1,5,7 (D1, D3, D4)
# P3 (b4) covers 3,5,7 (D2, D3, D4)
# P4 (b6) covers all.
# Teletext uses ODD parity for the hamming bits usually?
# "Hamming 8/4 with odd parity"
p1 = 1 ^ d1 ^ d2 ^ d4
p2 = 1 ^ d1 ^ d3 ^ d4
p3 = 1 ^ d2 ^ d3 ^ d4
res = (p1 << 0) | (d1 << 1) | \
(p2 << 2) | (d2 << 3) | \
(p3 << 4) | (d3 << 5) | \
(d4 << 7)
# P4 (bit 6) makes total bits odd
# Count set bits so far
set_bits = bin(res).count('1')
p4 = 1 if (set_bits % 2 == 0) else 0
res |= (p4 << 6)
return res
def save_t42(file_path: str, service: TeletextService):
with open(file_path, 'wb') as f:
# User requirement: "without rearranging the order of the packets"
# Implies we should iterate the original list.
# However, if we edit data, we modify the Packet objects in place.
# If we Add/Delete packets, we need to handle that.
for packet in service.all_packets:
# Reconstruct the 42 bytes from the packet fields
# The packet.data (bytearray) should be mutable and edited by the UI.
# packet.original_data (first 2 bytes) + packet.data
# Reconstruct header bytes from packet.magazine and packet.row
# Byte 1: M1 M2 M3 R1
# Byte 2: R2 R3 R4 R5
# Note: If we changed Magazine or Row, we'd need to re-encode the first 2 bytes.
# For now, assume we primarily edit content (bytes 2-41).
mag = packet.magazine
if mag == 8: mag = 0 # 0 encoded as 8
header = packet.original_data[:2] # Keep original address for now
# TODO: regenerating header if Mag/Row changed
# Bits:
# B1 data: M1(0) M2(1) M3(2) R1(3)
m1 = (mag >> 0) & 1
m2 = (mag >> 1) & 1
m3 = (mag >> 2) & 1
r1 = (packet.row >> 0) & 1
b1_val = m1 | (m2 << 1) | (m3 << 2) | (r1 << 3)
b1_enc = encode_hamming_8_4(b1_val)
# B2 data: R2(0) R3(1) R4(2) R5(3)
r2 = (packet.row >> 1) & 1
r3 = (packet.row >> 2) & 1
r4 = (packet.row >> 3) & 1
r5 = (packet.row >> 4) & 1
b2_val = r2 | (r3 << 1) | (r4 << 2) | (r5 << 3)
b2_enc = encode_hamming_8_4(b2_val)
header = bytes([b1_enc, b2_enc])
f.write(header + packet.data)
def decode_hamming_8_4(byte_val):