187 lines
6.4 KiB
Python
187 lines
6.4 KiB
Python
"""Editable status-bar layout playground.
|
|
|
|
Run from this directory with ``python3 playground.py``. Everything below is
|
|
intended to be edited freely; the model and renderer live in separate files.
|
|
|
|
Coordinates use the same convention as the module's layout solver:
|
|
horizontal zero is the status bar's left edge and vertical zero is its bottom.
|
|
"""
|
|
|
|
from statusbar_lab import StatusBarLab, containers_overlap, vertically_overlaps
|
|
from statusbar_renderer import render
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Virtual status-bar settings
|
|
# ---------------------------------------------------------------------------
|
|
|
|
STATUSBAR_WIDTH = 1200
|
|
STATUSBAR_HEIGHT = 100
|
|
|
|
# These are inputs for the algorithm you will write. The playground itself
|
|
# does not apply them automatically.
|
|
EDGE_PADDING = 0
|
|
CONTAINER_PADDING = 8
|
|
CAMERA_PADDING = 0
|
|
TEXT_HORIZONTAL_PADDING = 6
|
|
ICON_DOT_GAP = 0
|
|
DOT_WIDTH_FACTOR = 0.75
|
|
|
|
# Keep these in the same terms as the module settings. They are intentionally
|
|
# passive until the positioning/truncation algorithm below uses them.
|
|
CONTAINER_ORDER = ["clock", "chip", "carrier", "notification", "status"]
|
|
SHRINK_ORDER = ["notification", "status", "chip", "carrier"]
|
|
|
|
# Rendering scale only affects the visualizer, never the simulated geometry.
|
|
RENDER_SCALE = 1.0
|
|
VERTICAL_RENDER_SCALE = 2.0
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Scenario API
|
|
# ---------------------------------------------------------------------------
|
|
|
|
LAB = StatusBarLab()
|
|
|
|
# These lists remain valid when items are added. Clock text lines belong to
|
|
# one CLOCK group because the group moves them by their relative x offsets.
|
|
CLOCK = LAB.clock
|
|
CLOCK_LINES = CLOCK.lines
|
|
NOTIFICATIONS = LAB.notifications
|
|
STATUSES = LAB.statuses
|
|
CHIPS = LAB.chips
|
|
CARRIERS = LAB.carriers
|
|
CAMERAS = LAB.cameras
|
|
|
|
|
|
def _sync_settings() -> None:
|
|
LAB.text_horizontal_padding = TEXT_HORIZONTAL_PADDING
|
|
LAB.icon_dot_gap = ICON_DOT_GAP
|
|
LAB.dot_width_factor = DOT_WIDTH_FACTOR
|
|
|
|
|
|
def AddClock(
|
|
text: str,
|
|
height: float,
|
|
vertical_offset: float = 0,
|
|
horizontal_offset: float = 0,
|
|
position: str = "left",
|
|
cutout_side: str = "left",
|
|
):
|
|
"""Add one text line to the single movable CLOCK group.
|
|
|
|
Horizontal offsets are normalized relative to all clock lines. Therefore
|
|
offsets ``5, 10, -20`` produce the same clock geometry as ``105, 110, 80``.
|
|
``position`` is ``left``, ``middle`` or ``right``; ``cutout_side`` is the
|
|
fallback side for a middle clock when a camera splits the status bar.
|
|
"""
|
|
_sync_settings()
|
|
return CLOCK.add_line(text, height, vertical_offset, horizontal_offset, position, cutout_side)
|
|
|
|
|
|
def AddNotification(
|
|
height: float,
|
|
vertical_offset: float = 0,
|
|
position: str = "left",
|
|
cutout_side: str = "left",
|
|
direction: str = "right",
|
|
):
|
|
_sync_settings()
|
|
return LAB.add_notification(height, vertical_offset, position, cutout_side, direction)
|
|
|
|
|
|
def SetNotificationIcons(number_of_notifications: int) -> None:
|
|
"""Replace the notification-icon pool and empty every notification container."""
|
|
LAB.configure_notification_icons(number_of_notifications)
|
|
|
|
|
|
def AddStatus(
|
|
height: float,
|
|
vertical_offset: float = 0,
|
|
position: str = "right",
|
|
cutout_side: str = "right",
|
|
direction: str = "left",
|
|
):
|
|
_sync_settings()
|
|
return LAB.add_status(height, vertical_offset, position, cutout_side, direction)
|
|
|
|
|
|
def SetStatusIcons(number_of_icons: int, widths: list[float] | None = None) -> None:
|
|
"""Replace the status-icon pool and empty every status container.
|
|
|
|
Missing widths are padded using the first status container's height. Add
|
|
status containers before calling this function when relying on that default.
|
|
"""
|
|
LAB.configure_status_icons(number_of_icons, widths or [])
|
|
|
|
|
|
def AddChip(
|
|
text: str,
|
|
height: float,
|
|
vertical_offset: float = 0,
|
|
position: str = "left",
|
|
cutout_side: str = "left",
|
|
):
|
|
_sync_settings()
|
|
return LAB.add_chip(text, height, vertical_offset, position, cutout_side)
|
|
|
|
|
|
def AddCarrier(
|
|
text: str,
|
|
height: float,
|
|
vertical_offset: float = 0,
|
|
position: str = "left",
|
|
cutout_side: str = "left",
|
|
):
|
|
_sync_settings()
|
|
return LAB.add_carrier(text, height, vertical_offset, position, cutout_side)
|
|
|
|
|
|
def AddCamera(width: float, height: float, horizontal_position: float, vertical_position: float):
|
|
return LAB.add_camera(width, height, horizontal_position, vertical_position)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Simulated app settings: add or remove as many containers as you need.
|
|
# ---------------------------------------------------------------------------
|
|
|
|
AddClock("12:34:56", height=40, vertical_offset=0, horizontal_offset=0)
|
|
AddClock("Mon, 1 Jan", height=24, vertical_offset=42, horizontal_offset=10)
|
|
|
|
AddNotification(height=32, vertical_offset=0)
|
|
AddNotification(height=32, vertical_offset=40)
|
|
SetNotificationIcons(8)
|
|
|
|
AddStatus(height=30, vertical_offset=0)
|
|
AddStatus(height=30, vertical_offset=38)
|
|
SetStatusIcons(6, [20, 30, 30, 45])
|
|
|
|
AddChip("Navigation 12:34", height=38, vertical_offset=0)
|
|
AddCarrier("Example carrier", height=30, vertical_offset=45)
|
|
|
|
AddCamera(width=90, height=100, horizontal_position=555, vertical_position=0)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Positioning and truncation algorithm
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# All containers currently start at horizontal position zero. Add your layout
|
|
# algorithm here. Useful operations include:
|
|
#
|
|
# CLOCK.set_left(EDGE_PADDING)
|
|
# NOTIFICATIONS[0].set_right(STATUSBAR_WIDTH - EDGE_PADDING)
|
|
# CHIPS[0].set_width(120) # clock widths cannot be overridden
|
|
# NOTIFICATIONS[0].add_icons(3) # takes IDs from the shared pool
|
|
# NOTIFICATIONS[0].return_icons(1) # returns the newest assigned ID
|
|
# NOTIFICATIONS[0].set_dot(True)
|
|
# CLOCK.right_edge_between(10, 50) # ignores clock lines outside this band
|
|
# containers_overlap(CLOCK, CHIPS[0])
|
|
# vertically_overlaps(NOTIFICATIONS[0].bounds, CHIPS[0].bounds)
|
|
|
|
|
|
# Keep the renderer call at the end so the editable scenario and algorithm stay
|
|
# together above it.
|
|
_sync_settings()
|
|
render(LAB, STATUSBAR_WIDTH, STATUSBAR_HEIGHT, RENDER_SCALE, VERTICAL_RENDER_SCALE)
|