Glyphs drawn from the package's own SVG files, without Qt's SVG module.
QtSvg is not in the set of Qt modules the project uses (AGENTS.md
rule 3), and the one glyph so far, the drawer tab's chevron, is a
six-vertex outline that needs no SVG renderer. Its vertices are read
from the path and painted as a polygon, in the palette's color, at the
screen's pixel ratio. When the design changes, the file is replaced.
The parser accepts only the subset the files are drawn in: absolute M,
L and Z commands, straight edges, one path. Anything else raises
ValueError instead of being drawn wrong.
Functions:
| Name |
Description |
polygon_of |
The vertices of the single straight-edged path in an SVG, and the
|
glyph |
An icon of a packaged glyph, filled with color, turned turn
|
drawer_glyph |
The chevron on a drawer tab. It points away from edge
|
Functions:
polygon_of
polygon_of(svg: str) -> tuple[list[tuple[float, float]], float]
The vertices of the single straight-edged path in an SVG, and the
side length of its square viewBox.
Raises ValueError for anything outside that subset: curves, relative
commands, more than one path, a viewBox that is not square or not at
the origin, or fewer than three vertices.
Source code in src/visualdynamics/gui/glyphs.py
| def polygon_of(svg: str) -> tuple[list[tuple[float, float]], float]:
"""The vertices of the single straight-edged path in an SVG, and the
side length of its square viewBox.
Raises ValueError for anything outside that subset: curves, relative
commands, more than one path, a viewBox that is not square or not at
the origin, or fewer than three vertices.
"""
box = re.search(r'viewBox="0 0 (\S+) (\S+)"', svg)
if box is None or box.group(1) != box.group(2):
raise ValueError('the glyph needs a square viewBox at the origin')
paths = re.findall(r'<path\b[^>]*\bd="([^"]*)"', svg)
if len(paths) != 1:
raise ValueError(f'one path expected, {len(paths)} found')
tokens = _TOKENS.findall(paths[0])
vertices: list[tuple[float, float]] = []
command = None
while tokens:
token = tokens.pop(0)
if token.isalpha():
if token not in 'MLZ':
raise ValueError(f'path command {token!r} is not drawn: '
'straight absolute edges only')
command = token
continue
if command not in 'ML' or not tokens:
raise ValueError('malformed path data')
vertices.append((float(token), float(tokens.pop(0))))
if len(vertices) < 3:
raise ValueError('a polygon needs at least three vertices')
return vertices, float(box.group(1))
|
glyph
glyph(name: str, color: QColor, size: int = 16, turn: float = 0) -> QIcon
An icon of a packaged glyph, filled with color, turned turn
degrees clockwise about its center, size pixels on a side.
It is rendered at one and two device pixels per point so a Retina
screen gets a sharp edge, and the icon uses whichever fits the
screen.
Source code in src/visualdynamics/gui/glyphs.py
| def glyph(name: str, color: QColor, size: int = 16,
turn: float = 0) -> QIcon:
"""An icon of a packaged glyph, filled with `color`, turned `turn`
degrees clockwise about its center, `size` pixels on a side.
It is rendered at one and two device pixels per point so a Retina
screen gets a sharp edge, and the icon uses whichever fits the
screen.
"""
vertices, side = _load(name)
polygon = QPolygonF([QPointF(x, y) for x, y in vertices])
icon = QIcon()
for ratio in (1, 2):
pixmap = QPixmap(size * ratio, size * ratio)
pixmap.fill(Qt.GlobalColor.transparent)
painter = QPainter(pixmap)
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
painter.setPen(Qt.PenStyle.NoPen)
painter.setBrush(color)
painter.scale(size * ratio / side, size * ratio / side)
painter.translate(side / 2, side / 2)
painter.rotate(turn)
painter.translate(-side / 2, -side / 2)
painter.drawPolygon(polygon)
painter.end()
pixmap.setDevicePixelRatio(ratio)
icon.addPixmap(pixmap)
return icon
|
drawer_glyph
drawer_glyph(edge: str, open_: bool, color: QColor, size: int = 16) -> QIcon
The chevron on a drawer tab. It points away from edge
('bottom', 'top', 'left' or 'right') while the drawer is closed and
toward it once open, which is the way a click will move the edge.
Source code in src/visualdynamics/gui/glyphs.py
| def drawer_glyph(edge: str, open_: bool, color: QColor,
size: int = 16) -> QIcon:
"""The chevron on a drawer tab. It points away from `edge`
('bottom', 'top', 'left' or 'right') while the drawer is closed and
toward it once open, which is the way a click will move the edge."""
return glyph('drawer-tab', color, size,
_CLOSED_TURN[edge] + (180 if open_ else 0))
|