spacr.qt.widgets.provider_marks

Draw the assistant providers as their marks rather than as their names.

“the claude gpt and gemeni buttons should be the logos for each not just

buttons”

THREE WORDS IN THREE BOXES IS A LIST WEARING BUTTONS. A mark is recognised before it is read, which is the whole reason a vendor has one – and this is the one question on the setup screen where the user already knows the answer and only has to point at it.

DRAWN, NOT SHIPPED. Each mark is a QPainterPath built here: a bitmap would be a vendor asset in the repository with its own licence, its own resolution and its own two versions for light and dark. A path scales to any button size, takes the brand colour when the provider is available and the theme’s muted ink when it is not, and adds nothing to the wheel.

The three assistant shapes are the recognisable geometry of each mark, not a facsimile: Claude’s radiating burst, OpenAI’s six-fold knot, Gemini’s four-pointed spark. They identify whose command-line tool spaCR would drive, which is what the question is asking.

GITHUB IS THE EXCEPTION, and deliberately. GitHub publishes the Octocat’s path data for use as a link mark, so that one is the real thing rather than a circle with ears – still a path, still recoloured per theme, still nothing added to the wheel.

Classes

ProviderMark

One provider, drawn as its mark with its name beneath.

Functions

claude_path(→ PySide6.QtGui.QPainterPath)

A radiating burst: petals narrow at the hub and wide at the tip.

gemini_path(→ PySide6.QtGui.QPainterPath)

A four-pointed spark: a diamond with concave sides.

github_path(→ PySide6.QtGui.QPainterPath)

GitHub's Octocat mark, scaled to fill box.

gpt_path(→ PySide6.QtGui.QPainterPath)

A six-fold knot: six lobes on a common ring, drawn as one outline.

mark_for(→ Optional[PySide6.QtGui.QPainterPath])

The path for code inside box, or None for an unknown one.

Module Contents

class spacr.qt.widgets.provider_marks.ProviderMark(code: str, label: str, available: bool = True, parent: PySide6.QtWidgets.QWidget | None = None, status: str = '')[source]

Bases: PySide6.QtWidgets.QWidget

One provider, drawn as its mark with its name beneath.

Selectable rather than clickable-once: three of these are a radio group, and set_chosen() is how the group tells this one it lost.

Parameters:
  • code – provider key – claude, gpt or gemini.

  • label – the name under the mark.

  • available – whether the vendor CLI is on PATH. This is SHOWN, not enforced: an unavailable provider is drawn in the muted ink and says what would install it, and is still choosable. The setup screen writes a PREFERENCE and launches nothing, so choosing a provider before installing its CLI is an ordinary thing to want, and the console says so at the point it would actually be used.

  • parent – parent widget; ownership only.

  • status – READY, SIGNED_OUT or NOT_INSTALLED. Empty DERIVES ONE FROM available, which is what every caller written before the third state did; that derivation can only ever produce ready-or-not-installed, so a caller that knows the CLI is present but signed out has to say so here.

Build one provider’s status mark.

Parameters:
  • code – the provider’s short code, drawn in the mark.

  • label – its display name.

  • available – whether its CLI is installed.

  • parent – parent widget, or None.

  • status – a longer status line, shown on hover.

event(event)[source]

Handle the events Qt does not give a named handler for.

Parameters:

event – the Qt event.

Returns:

True when handled here.

is_chosen() → bool[source]

Whether this provider is the selected one.

mousePressEvent(event)[source]

Open the provider’s page.

Parameters:

event – the Qt mouse event.

paintEvent(event)[source]

Draw the provider’s mark.

Parameters:

event – the Qt paint event.

set_chosen(chosen: bool) → None[source]

Select or deselect, and repaint.

Parameters:

chosen – truthy to select; the widget repaints only when the state changes.

sizeHint() → PySide6.QtCore.QSize[source]

The mark’s natural size, from the artwork it draws.

Returns:

the preferred size.

spacr.qt.widgets.provider_marks.claude_path(box: PySide6.QtCore.QRectF) → PySide6.QtGui.QPainterPath[source]

A radiating burst: petals narrow at the hub and wide at the tip.

WIDE AT THE OUTSIDE, which is both the shape of the mark and what makes it carry. Drawn as tapered points – narrow at the tip, all the area at the centre – it measured a third of the ink of the knot beside it, and the lightest of three logos in a row reads as the disabled one.

Parameters:

box – the rectangle to draw in; the mark is centred in it and sized to its shorter side.

spacr.qt.widgets.provider_marks.gemini_path(box: PySide6.QtCore.QRectF) → PySide6.QtGui.QPainterPath[source]

A four-pointed spark: a diamond with concave sides.

Parameters:

box – the rectangle to draw in; the mark is centred in it and sized to its shorter side.

spacr.qt.widgets.provider_marks.github_path(box: PySide6.QtCore.QRectF) → PySide6.QtGui.QPainterPath[source]

GitHub’s Octocat mark, scaled to fill box.

Uniform scale on the smaller of the two ratios and centred, so the cat keeps its proportions in a box of any shape.

Parameters:

box – the rectangle to fit the mark into; an empty box returns the mark unscaled.

spacr.qt.widgets.provider_marks.gpt_path(box: PySide6.QtCore.QRectF) → PySide6.QtGui.QPainterPath[source]

A six-fold knot: six lobes on a common ring, drawn as one outline.

Parameters:

box – the rectangle to draw in; the mark is centred in it and sized to its shorter side.

spacr.qt.widgets.provider_marks.mark_for(code: str, box: PySide6.QtCore.QRectF) → PySide6.QtGui.QPainterPath | None[source]

The path for code inside box, or None for an unknown one.

Parameters:
  • code – provider code: "claude", "gpt", "gemini" or "github".

  • box – the rectangle the mark is drawn in.

Nested helpers

_parse_svg_path.num()

Read the next number from the path string, advancing the cursor.

spacr/qt/widgets/provider_marks.py:178

_svg_arc.ang(ux, uy, vx, vy)

The signed angle between two vectors, as SVG’s arc maths defines it.

spacr/qt/widgets/provider_marks.py:251

_svg_arc.pt(c_, s_)

One point on the arc, from its cosine and sine.

spacr/qt/widgets/provider_marks.py:268