bacommon.docui package¶
Declarative UI system.
A high level way to build UIs that lives as a layer on top of engine
apis such as bauiv1. UIs can easily be serialized to json data
and be provided by webservers or other local or remote sources.
- class bacommon.docui.DocUIRequest[source]¶
Bases:
IOMultiType[DocUIRequestTypeID]A request for some UI.
- classmethod get_type(type_id: DocUIRequestTypeID) type[DocUIRequest][source]¶
Return the subclass for each of our type-ids.
- classmethod get_type_id() DocUIRequestTypeID[source]¶
Return the type-id for this subclass.
- classmethod get_type_id_storage_name() str[source]¶
Return the key used to store type id in serialized data.
The default is a short obscure value so that it is unlikely to conflict with members of individual type attrs, but in some cases one might prefer to serialize it to something simpler like ‘type’ by overriding this call. One just needs to make sure that no encompassed types serialize anything to that same name themself (dataclassio will error if they do).
- classmethod get_unknown_type_fallback() DocUIRequest[source]¶
Return a fallback object in cases of unrecognized types.
This can allow newer data to remain readable in older environments. Use caution with this option, however, as it effectively modifies data.
- class bacommon.docui.DocUIRequestTypeID(*values)[source]¶
Bases:
EnumType ID for each of our subclasses.
- UNKNOWN = 'u'¶
- V1 = 'v1'¶
- V2 = 'v2'¶
- class bacommon.docui.DocUIResponse[source]¶
Bases:
IOMultiType[DocUIResponseTypeID]A UI provied in response to a
DocUIRequest.- classmethod get_type(type_id: DocUIResponseTypeID) type[DocUIResponse][source]¶
Return the subclass for each of our type-ids.
- classmethod get_type_id() DocUIResponseTypeID[source]¶
Return the type-id for this subclass.
- classmethod get_type_id_storage_name() str[source]¶
Return the key used to store type id in serialized data.
The default is a short obscure value so that it is unlikely to conflict with members of individual type attrs, but in some cases one might prefer to serialize it to something simpler like ‘type’ by overriding this call. One just needs to make sure that no encompassed types serialize anything to that same name themself (dataclassio will error if they do).
- classmethod get_unknown_type_fallback() DocUIResponse[source]¶
Return a fallback object in cases of unrecognized types.
This can allow newer data to remain readable in older environments. Use caution with this option, however, as it effectively modifies data.
- class bacommon.docui.DocUIResponseTypeID(*values)[source]¶
Bases:
EnumType ID for each of our subclasses.
- UNKNOWN = 'u'¶
- V1 = 'v1'¶
- V2 = 'v2'¶
- class bacommon.docui.DocUIWebRequest(doc_ui_request: DocUIRequest, locale: Locale, engine_build_number: int)[source]¶
Bases:
objectComplete data sent for doc-ui http requests.
- doc_ui_request: DocUIRequest¶
The wrapped doc-ui request.
- class bacommon.docui.DocUIWebResponse(error: str | None = None, doc_ui_response: DocUIResponse | None = None)[source]¶
Bases:
objectComplete data returned for doc-ui http requests.
- doc_ui_response: DocUIResponse | None = None¶
doc-ui response. Either this or error should be set; not both.
- class bacommon.docui.UnknownDocUIRequest[source]¶
Bases:
DocUIRequestFallback type for unrecognized UI types.
Will show the client a ‘cannot display this UI’ placeholder request.
- classmethod get_type_id() DocUIRequestTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.docui.UnknownDocUIResponse[source]¶
Bases:
DocUIResponseFallback type for unrecognized UI types.
Will show the client a ‘cannot display this UI’ placeholder response.
- classmethod get_type_id() DocUIResponseTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.docui.WrapParams(min_lines: int = 1, max_lines: int | None = None, max_chars_per_line: int | None = None)[source]¶
Bases:
objectConstraints for splitting a text value into lines client-side.
Mirrors the engine’s simple line splitter (
babase.split_text_into_lines()): text is broken only at valid line-break opportunities, using the fewest lines that keep every line withinmax_chars_per_line(when provided) while staying betweenmin_linesandmax_lines(Nonemeans unlimited), with line lengths balanced within that count. Somax_chars_per_linealone gives basic wrapping andmin_linesalone gives an exact line count. Constraints are best-effort. Characters are counted in Latin-width units: East Asian wide characters (CJK, kana, Hangul, full-width forms) count as two, and the engine further scales the budget per locale by how wide its script renders (Cyrillic, Greek and Tamil run wider, Arabic and Hindi narrower), so amax_chars_per_linemeans about the same width in every language.Sizing a
max_chars_per_lineto a width: allow about 9.3 text units of width per character at text scale 1.0 (measured across every locale, 2026-10-01). For example, a doc-ui row footnote (scale 0.7) in a small-layout column (534 units of text width) fills well at 534 / (9.3 * 0.7), about 82. Aim a little wide rather than narrow: text scales down to fit its max width, so a slightly long line costs less than a visibly short one.Default to pinning an exact line count: set
min_linesto the layout’s designed count and leavemax_chars_per_lineunset. Amax_chars_per_line-driven wrap yields a per-locale varying line count (translation lengths differ), which reads as broken in layouts designed around a specific count — and every legacy-converted string is such a layout, since the legacy pipeline hand-baked newlines at fixed counts (see D21 in the strings-asset-migration initiative). Reservemax_chars_per_linefor surfaces explicitly designed to tolerate a variable number of lines.Per decision D-t these are definition-time presentation hints: a string definition carries them optionally, they ride each locale blob, and evaluation applies them automatically. They are locale-invariant, and width-driven layout consumers may ignore them (they are a fallback presentation default).
Subpackages¶
Submodules¶
bacommon.docui.presets module¶
Canned doc-ui styling built from plain v2 rows and buttons.
Higher-level looks that recur across pages (a stack of grouped
section buttons, say) live here so their spacing numbers have one
owner. Everything returned is ordinary bacommon.docui.v2 data,
so callers can still adjust what they get back, and nothing here
touches the wire format.
- class bacommon.docui.presets.SectionButtonSize(*values)[source]¶
Bases:
EnumSizes of
section_button().- LARGE = 'large'¶
The standard full-width button leading to another page.
- MEDIUM = 'medium'¶
A lone button under some other content.
- bacommon.docui.presets.button_stack(groups: Sequence[Sequence[bacommon.docui.v2.Button]], *, group_spacing: float = 27.0, first_group_spacing: float | None = None) list[bacommon.docui.v2.Row][source]¶
Return rows showing buttons one per row, grouped.
Each button gets a
FILLrow of its own, so it spans the column exactly as control rows do (its own width is ignored). Buttons within a group sit tight together; groups are separated bygroup_spacing(the first byfirst_group_spacingif given, for when the stack follows something that wants a different gap). For several buttons side by side, use such a row with several buttons directly.
- bacommon.docui.presets.section_button(label: LangStrSpec, action: bacommon.docui.v2.Action, *, size: SectionButtonSize = SectionButtonSize.LARGE) bacommon.docui.v2.Button[source]¶
Return a button leading to a page section (or doing one thing).
In a
FILLrow (one or several side by side) its width only matters relative to its neighbors’; its style and height are what count.
bacommon.docui.v1 module¶
Version 1 doc-ui types.
- class bacommon.docui.v1.Action[source]¶
Bases:
IOMultiType[ActionTypeID]Top level class for our multitype.
- classmethod get_type(type_id: ActionTypeID) type[Action][source]¶
Return the subclass for each of our type-ids.
- classmethod get_type_id() ActionTypeID[source]¶
Return the type-id for this subclass.
- classmethod get_type_id_storage_name() str[source]¶
Return the key used to store type id in serialized data.
The default is a short obscure value so that it is unlikely to conflict with members of individual type attrs, but in some cases one might prefer to serialize it to something simpler like ‘type’ by overriding this call. One just needs to make sure that no encompassed types serialize anything to that same name themself (dataclassio will error if they do).
- class bacommon.docui.v1.ActionTypeID(*values)[source]¶
Bases:
EnumType ID for each of our subclasses.
- BROWSE = 'b'¶
- LOCAL = 'l'¶
- REPLACE = 'r'¶
- UNKNOWN = 'u'¶
- class bacommon.docui.v1.Browse(request: Request, default_sound: bool = True, immediate_local_action: str | None = None, immediate_local_action_args: dict | None = None)[source]¶
Bases:
ActionBrowse to a new page in a new window.
- classmethod get_type_id() ActionTypeID[source]¶
Return the type-id for this subclass.
- immediate_local_action: str | None = None¶
Local action to run immediately when the button is pressed. Will be handled by
bauiv1lib.docui.DocUIController.local_action().
- class bacommon.docui.v1.Button(label: str | None = None, action: Action | None = None, size: tuple[float, float] | None = None, color: tuple[float, float, float, float] | None = None, label_color: tuple[float, float, float, float] | None = None, label_flatness: float | None = None, label_scale: float | None = None, label_is_lstr: bool = False, label_is_langstr: bool = False, label_wrap: WrapParams | None = None, texture: str | None = None, scale: float = 1.0, padding_left: float = 0.0, padding_top: float = 0.0, padding_right: float = 0.0, padding_bottom: float = 0.0, decorations: list[Decoration] | None = None, style: ButtonStyle = ButtonStyle.SQUARE, default: bool = False, selected: bool = False, icon: str | None = None, icon_scale: float | None = None, icon_color: tuple[float, float, float, float] | None = None, depth_range: tuple[float, float] | None = None, widget_id: str | None = None, debug: bool = False)[source]¶
Bases:
objectA button in our doc-ui.
Note that size, padding, and all decorations are scaled consistently with ‘scale’.
- decorations: list[Decoration] | None = None¶
- label: str | None = None¶
Note that doc-ui accepts only raw
strvalues for text; usebabase.Lstr.evaluate()or whatnot for multi-language support.
- label_is_langstr: bool = False¶
The label field holds a language-string (canonical resource-form wire JSON) to be evaluated natively at display and re-evaluated on language changes. Set by the client-side v2 transcode; mutually exclusive with label_is_lstr.
- label_wrap: WrapParams | None = None¶
Line-wrap constraints applied to the label at widget-creation time. Set only by the client-local v2→v1 transcode; v1 producers must never send it (older clients can’t parse unknown fields — bake newlines into the label instead).
- style: ButtonStyle = 'q'¶
- class bacommon.docui.v1.ButtonRow(buttons: list[Button], header_height: float = 0.0, header_scale: float = 1.0, header_decorations_left: list[Decoration] | None = None, header_decorations_center: list[Decoration] | None = None, header_decorations_right: list[Decoration] | None = None, title: str | None = None, title_color: tuple[float, float, float, float] | None = None, title_flatness: float | None = None, title_shadow: float | None = None, title_is_lstr: bool = False, title_is_langstr: bool = False, title_wrap: WrapParams | None = None, subtitle: str | None = None, subtitle_color: tuple[float, float, float, float] | None = None, subtitle_flatness: float | None = None, subtitle_shadow: float | None = None, subtitle_is_lstr: bool = False, subtitle_is_langstr: bool = False, subtitle_wrap: WrapParams | None = None, button_spacing: float = 15.0, padding_left: float = 10.0, padding_right: float = 10.0, padding_top: float = 10.0, padding_bottom: float = 10.0, spacing_top: float = 0.0, spacing_bottom: float = 0.0, center_content: bool = False, center_title: bool = False, simple_culling_h: float = 100.0, debug: bool = False)[source]¶
Bases:
RowA row consisting of buttons.
- debug: bool = False¶
Draw bounds of the overall row and individual button columns (including padding). The UI will scroll to keep these areas visible in their entirety when changing selection via directional controls, so try to make sure all decorations for a button are within these bounds.
- header_decorations_center: list[Decoration] | None = None¶
- header_decorations_left: list[Decoration] | None = None¶
- header_decorations_right: list[Decoration] | None = None¶
- subtitle_is_langstr: bool = False¶
The subtitle field holds a language-string (canonical resource-form wire JSON) to be evaluated natively at display and re-evaluated on language changes. Set by the client-side v2 transcode; mutually exclusive with subtitle_is_lstr.
- subtitle_wrap: WrapParams | None = None¶
Line-wrap constraints applied to the subtitle at widget-creation time. Set only by the client-local v2→v1 transcode; v1 producers must never send it (older clients can’t parse unknown fields — bake newlines into the subtitle instead).
- title: str | None = None¶
Note that doc-ui accepts only raw
strvalues for text; usebabase.Lstr.evaluate()or whatnot for multi-language support.
- title_is_langstr: bool = False¶
The title field holds a language-string (canonical resource-form wire JSON) to be evaluated natively at display and re-evaluated on language changes. Set by the client-side v2 transcode; mutually exclusive with title_is_lstr.
- title_wrap: WrapParams | None = None¶
Line-wrap constraints applied to the title at widget-creation time. Set only by the client-local v2→v1 transcode; v1 producers must never send it (older clients can’t parse unknown fields — bake newlines into the title instead).
- class bacommon.docui.v1.ButtonStyle(*values)[source]¶
Bases:
EnumStyles a button can be.
- BACK = 'b'¶
- BACK_SMALL = 'bs'¶
- LARGE = 'l'¶
- LARGER = 'xl'¶
- MEDIUM = 'm'¶
- SMALL = 's'¶
- SQUARE = 'q'¶
- SQUARE_WIDE = 'w'¶
- TAB = 't'¶
- class bacommon.docui.v1.Decoration[source]¶
Bases:
IOMultiType[DecorationTypeID]Top level class for our multitype.
- classmethod get_type(type_id: DecorationTypeID) type[Decoration][source]¶
Return a specific subclass given a type-id.
Should be overridden by child classes. Generally, users of the class should call
get_type_cached()instead of this, as it is more efficient.
- classmethod get_type_id() DecorationTypeID[source]¶
Return the type-id for this subclass.
- classmethod get_type_id_storage_name() str[source]¶
Return the key used to store type id in serialized data.
The default is a short obscure value so that it is unlikely to conflict with members of individual type attrs, but in some cases one might prefer to serialize it to something simpler like ‘type’ by overriding this call. One just needs to make sure that no encompassed types serialize anything to that same name themself (dataclassio will error if they do).
- classmethod get_unknown_type_fallback() Decoration[source]¶
Return a fallback object in cases of unrecognized types.
This can allow newer data to remain readable in older environments. Use caution with this option, however, as it effectively modifies data.
- class bacommon.docui.v1.DecorationTypeID(*values)[source]¶
Bases:
EnumType ID for each of our subclasses.
- DISPLAY_ITEM = 'd'¶
- IMAGE = 'i'¶
- TEXT = 't'¶
- UNKNOWN = 'u'¶
- class bacommon.docui.v1.HAlign(*values)[source]¶
Bases:
EnumHorizontal alignment.
- CENTER = 'c'¶
- LEFT = 'l'¶
- RIGHT = 'r'¶
- class bacommon.docui.v1.Image(texture: str, position: tuple[float, float], size: tuple[float, float], color: tuple[float, float, float, float] | None = None, h_align: HAlign = HAlign.CENTER, v_align: VAlign = VAlign.CENTER, tint_texture: str | None = None, tint_color: tuple[float, float, float] | None = None, tint2_color: tuple[float, float, float] | None = None, mask_texture: str | None = None, mesh_opaque: str | None = None, mesh_transparent: str | None = None, highlight: bool = True, depth_range: tuple[float, float] | None = None)[source]¶
Bases:
DecorationImage decoration.
- classmethod get_type_id() DecorationTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.docui.v1.Local(close_window: bool = False, default_sound: bool = True, immediate_local_action: str | None = None, immediate_local_action_args: dict | None = None)[source]¶
Bases:
ActionPerform only local actions; no new requests or page changes.
- default_sound: bool = True¶
Plays a swish if closing the window or a click if triggered by a button press.
- classmethod get_type_id() ActionTypeID[source]¶
Return the type-id for this subclass.
- immediate_local_action: str | None = None¶
Local action to run immediately when the button is pressed. Will be handled by
bauiv1lib.docui.DocUIController.local_action().
- class bacommon.docui.v1.Page(title: str, rows: list[Row], center_vertically: bool = False, row_spacing: float = 10.0, simple_culling_v: float = 100.0, title_is_lstr: bool = False, title_is_langstr: bool = False, title_wrap: WrapParams | None = None, padding_bottom: float = 0.0, padding_left: float = 0.0, padding_top: float = 0.0, padding_right: float = 0.0)[source]¶
Bases:
objectDoc-UI page version 1.
- center_vertically: bool = False¶
If True, content smaller than the available height will be centered vertically. This can look natural for certain types of content such as confirmation dialogs.
- title: str¶
Note that doc-ui accepts only raw
strvalues for text; usebabase.Lstr.evaluate()or whatnot for multi-language support.
- title_is_langstr: bool = False¶
The title field holds a language-string (canonical resource-form wire JSON) to be evaluated natively at display and re-evaluated on language changes. Set by the client-side v2 transcode; mutually exclusive with title_is_lstr.
- title_is_lstr: bool = False¶
Whether the title is a json dict representing an Lstr. Generally doc-ui translation should be handled server-side, but this can allow client-side translation.
- title_wrap: WrapParams | None = None¶
Line-wrap constraints applied to the title at widget-creation time. Set only by the client-local v2→v1 transcode; v1 producers must never send it (older clients can’t parse unknown fields — bake newlines into the title instead).
- class bacommon.docui.v1.Replace(request: Request, default_sound: bool = True, immediate_local_action: str | None = None, immediate_local_action_args: dict | None = None)[source]¶
Bases:
ActionReplace current page with a new one.
Should be used to effectively ‘modify’ existing UIs by replacing them with something slightly different. Things like scroll position and selection will be carried across to the new layout when possible to make for a seamless transition.
- classmethod get_type_id() ActionTypeID[source]¶
Return the type-id for this subclass.
- immediate_local_action: str | None = None¶
Local action to run immediately when the button is pressed. Will be handled by
bauiv1lib.docui.DocUIController.local_action().
- class bacommon.docui.v1.Request(path: str, method: RequestMethod = RequestMethod.GET, args: dict = <factory>)[source]¶
Bases:
DocUIRequestFull request to doc-ui.
- classmethod get_type_id() DocUIRequestTypeID[source]¶
Return the type-id for this subclass.
- method: RequestMethod = 'g'¶
- class bacommon.docui.v1.RequestMethod(*values)[source]¶
Bases:
EnumTypeof of requests that can be made to doc-ui servers.
- GET = 'g'¶
Fetch some resource. This can be retried and its results can optionally be cached for some amount of time.
- POST = 'p'¶
Change some resource. This cannot be implicitly retried (at least without deduplication), nor can it be cached.
- UNKNOWN = 'u'¶
An unknown request method. This can appear if a newer client is requesting some method from an older server that is not known to the server.
- class bacommon.docui.v1.Response(page: Page, status: ResponseStatus = ResponseStatus.SUCCESS, local_action: str | None = None, local_action_args: dict | None = None, timed_action: Action | None = None, timed_action_delay: float = 0.0, minimum_engine_build: int | None = None, shared_state_id: str | None = None)[source]¶
Bases:
DocUIResponseFull docui response.
- classmethod get_type_id() DocUIResponseTypeID[source]¶
Return the type-id for this subclass.
- local_action: str | None = None¶
Local action to run after this response is initially received. Will be handled by
bauiv1lib.docui.DocUIController.local_action(). Note that these actions will not re-run if the page is automatically refreshed later (due to window resizing, back navigation, etc).
- minimum_engine_build: int | None = None¶
If provided, error on builds older than this (can be used to gate functionality without bumping entire docui version).
The client maintains some persistent state (such as widget selection) for all pages viewed. The default index for these states is the path of the request. If a server returns a significant variety of responses for a single path, however, (based on args, etc) then it may make sense for the server to provide explicit state ids for those different variations.
- status: ResponseStatus = 0¶
- class bacommon.docui.v1.ResponseStatus(*values)[source]¶
Bases:
EnumThe overall result of a request.
- COMMUNICATION_ERROR = 2¶
Something went wrong talking to the server. A ‘Retry’ button may be appropriate to show here (for GET requests at least).
- NOT_SIGNED_IN_ERROR = 3¶
This requires the user to be signed in, and they aint.
- SUCCESS = 0¶
- UNKNOWN_ERROR = 1¶
Something went wrong. That’s all we know.
- class bacommon.docui.v1.Row[source]¶
Bases:
IOMultiType[RowTypeID]Top level class for our multitype.
- classmethod get_type(type_id: RowTypeID) type[Row][source]¶
Return the subclass for each of our type-ids.
- classmethod get_type_id_storage_name() str[source]¶
Return the key used to store type id in serialized data.
The default is a short obscure value so that it is unlikely to conflict with members of individual type attrs, but in some cases one might prefer to serialize it to something simpler like ‘type’ by overriding this call. One just needs to make sure that no encompassed types serialize anything to that same name themself (dataclassio will error if they do).
- class bacommon.docui.v1.RowTypeID(*values)[source]¶
Bases:
EnumType ID for each of our subclasses.
- BUTTON_ROW = 'b'¶
- UNKNOWN = 'u'¶
- class bacommon.docui.v1.Text(text: str, position: tuple[float, float], size: tuple[float, float], scale: float = 1.0, h_align: HAlign = HAlign.CENTER, v_align: VAlign = VAlign.CENTER, color: tuple[float, float, float, float] | None = None, flatness: float | None = None, shadow: float | None = None, is_lstr: bool = False, is_langstr: bool = False, wrap: WrapParams | None = None, highlight: bool = True, depth_range: tuple[float, float] | None = None, debug: bool = False)[source]¶
Bases:
DecorationText decoration.
- classmethod get_type_id() DecorationTypeID[source]¶
Return the type-id for this subclass.
- is_langstr: bool = False¶
The text field holds a language-string (canonical resource-form wire JSON) to be evaluated natively at display and re-evaluated on language changes. Set by the client-side v2 transcode; mutually exclusive with is_lstr.
- text: str¶
Note that doc-ui accepts only raw
strvalues for text; usebabase.Lstr.evaluate()or whatnot for multi-language support.
- wrap: WrapParams | None = None¶
Line-wrap constraints applied to the text at widget-creation time. Set only by the client-local v2→v1 transcode; v1 producers must never send it (older clients can’t parse unknown fields — bake newlines into the string instead).
- class bacommon.docui.v1.UnknownAction[source]¶
Bases:
ActionAction type we don’t recognize.
- classmethod get_type_id() ActionTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.docui.v1.UnknownDecoration[source]¶
Bases:
DecorationAn unknown decoration.
In practice these should never show up since the master-server generates these on the fly for the client and so should not send clients one they can’t digest.
- classmethod get_type_id() DecorationTypeID[source]¶
Return the type-id for this subclass.
bacommon.docui.v2 module¶
Version 2 doc-ui types – language-agnostic (l-string) text.
Where v1 carries pre-localized raw str text (optionally a JSON-encoded
legacy babase.Lstr via *_is_lstr flags) and expects the server to
localize, v2 text is always a language-agnostic
LangStrSpec. The server ships one response to every
client regardless of language; the client resolves the referenced
asset-packages in its own locale and decodes the strings at render time.
See docs/initiatives/docui-v2-lstrings.md (ballistica-internal). This is
the milestone-1 slice: a minimal but real subset of the v1 element set, with
text typed as LangStrSpec (the name-based form – subs are flat for now).
Non-text fields mirror v1’s names/keys so client render code can stay close
to v1prep.
- class bacommon.docui.v2.Action[source]¶
Bases:
IOMultiType[ActionTypeID]Something that happens when a button is pressed.
- classmethod get_type(type_id: ActionTypeID) type[Action][source]¶
Return a specific subclass given a type-id.
Should be overridden by child classes. Generally, users of the class should call
get_type_cached()instead of this, as it is more efficient.
- classmethod get_type_id() ActionTypeID[source]¶
Return the type-id for this subclass.
- classmethod get_type_id_storage_name() str[source]¶
Return the key used to store type id in serialized data.
The default is a short obscure value so that it is unlikely to conflict with members of individual type attrs, but in some cases one might prefer to serialize it to something simpler like ‘type’ by overriding this call. One just needs to make sure that no encompassed types serialize anything to that same name themself (dataclassio will error if they do).
- class bacommon.docui.v2.ActionTypeID(*values)[source]¶
Bases:
EnumType ID for each of our subclasses.
- BROWSE = 'b'¶
- LOCAL = 'l'¶
- MENU = 'm'¶
- REPLACE = 'r'¶
- UNKNOWN = 'u'¶
- type bacommon.docui.v2.AnyControlRow = AnyInputRow | ButtonControlRow¶
Union of the control-row types: rows holding a single control, label at the left and control at the right. That is the input rows plus
ButtonControlRow, which holds no value.
- type bacommon.docui.v2.AnyInputRow = CheckboxRow | TextInputRow | ChoiceRow | ColorRow | SliderRow | NumberRow¶
Union of the input-row types: the control rows holding a value, bound to a page-state key (see
Page.state).
- class bacommon.docui.v2.Browse(request: Request, default_sound: bool = True, sets: dict | None = None, state: dict | None = None, layout: WindowLayout = WindowLayout.LARGE)[source]¶
Bases:
ActionBrowse to a new page in a new window.
- classmethod get_type_id() ActionTypeID[source]¶
Return the type-id for this subclass.
- layout: WindowLayout = 'l'¶
The new window’s layout. Note that the wire default is LARGE (an omitted value has always meant LARGE, and must keep doing so for older clients and servers), but routes’ own default is WIDE (see
bacommon.docui.routes.DocUIRoute.browse()).
- sets: dict | None = None¶
Values to assign into the page’s state before the request goes out (see
Page.state).
- class bacommon.docui.v2.Button(label: LangStrSpec | int | None = None, action: Action | None = None, size: tuple[float, float] | None = None, color: tuple[float, float, float, float] | None = None, label_color: tuple[float, float, float, float] | None = None, label_scale: float | None = None, label_flatness: float | None = None, texture: TextureSpec | int | None = None, scale: float = 1.0, padding_left: float = 0.0, padding_top: float = 0.0, padding_right: float = 0.0, padding_bottom: float = 0.0, decorations: list[Decoration] | None = None, style: ButtonStyle = ButtonStyle.SQUARE, default: bool = False, selected: bool = False, disabled: bool = False, icon: TextureSpec | int | None = None, icon_scale: float | None = None, icon_color: tuple[float, float, float, float] | None = None, depth_range: tuple[float, float] | None = None, depiction: Depiction | None = None, depiction_h_align: HAlign = HAlign.CENTER, depiction_v_align: VAlign = VAlign.CENTER, depiction_hit_area: bool = False, widget_id: str | None = None, anim_id: str | None = None, debug: bool = False)[source]¶
Bases:
objectA button in our doc-ui.
labelis a language-agnosticLangStrSpec. Size, padding, and all decorations scale consistently withscale.- anim_id: str | None = None¶
Lets client-effects animate this button (see
bacommon.clienteffect.KeyframeAnimation); give its decorations the same id to have them move with it.
- decorations: list[Decoration] | None = None¶
- depiction: Depiction | None = None¶
A depiction drawn as the button’s body, in place of its texture or style’s look, filling the button’s box (its size, at its scale). One with a shape of its own is fitted inside the box by
depiction_h_align/depiction_v_align. The label, icon and decorations still draw over it, and it brightens, pulses and greys out with the button. To show a depiction elsewhere on a button, use aDepictiondecoration. Clients predating this field show the button’s usual look.
- depiction_hit_area: bool = False¶
With a
depiction, have mouse and touch land on the button only where the depiction actually draws (an icon hugging one end of a wide button, a short name in a box sized for long ones) rather than anywhere in its box. The client grows that area to a minimum size so small depictions stay easy to tap; keyboard and controller selection are unaffected. Clients predating this field take presses anywhere in the box.
- disabled: bool = False¶
Drawn greyed out and not activatable (a press plays an error sound instead of running
action). Still selectable, so navigation around it is unaffected. Clients predating this field show it as a normal button.
- icon: TextureSpec | int | None = None¶
- label: LangStrSpec | int | None = None¶
- style: ButtonStyle = 'q'¶
- texture: TextureSpec | int | None = None¶
- class bacommon.docui.v2.ButtonControlRow(button: Button, label: LangStrSpec | int | None = None, disabled: bool = False, title: LangStrSpec | int | None = None, title_color: tuple[float, float, float, float] | None = None, title_flatness: float | None = None, title_shadow: float | None = None, subtitle: LangStrSpec | int | None = None, subtitle_color: tuple[float, float, float, float] | None = None, subtitle_flatness: float | None = None, subtitle_shadow: float | None = None, title_align: HAlign | None = None, footnote: LangStrSpec | int | None = None, padding_left: float = 0.0, padding_right: float = 0.0, padding_top: float = 4.0, padding_bottom: float = 4.0, header_height: float = 0.0, header_scale: float = 1.0, header_decorations_left: list[Decoration] | None = None, header_decorations_center: list[Decoration] | None = None, header_decorations_right: list[Decoration] | None = None, footer_height: float = 0.0, footer_scale: float = 1.0, footer_decorations_left: list[Decoration] | None = None, footer_decorations_center: list[Decoration] | None = None, footer_decorations_right: list[Decoration] | None = None, spacing_top: float = 0.0, spacing_bottom: float = 0.0, spacing_title: float = 0.0, spacing_footnote: float = 0.0, debug: bool = False)[source]¶
Bases:
RowA control row whose control is a single button.
Label at the left edge of the row;
buttonat the right, drawn as it would be in aButtonRow. Laid out like the other control rows, so it sits naturally in a column of them, but unlike them it holds no value: the button shows whatever the page draws on it (an icon or preview of a current selection, say) and does whatever its action says (browse to a page for picking a new one, say).The button can be any size; the row grows to fit it, its label stays centered beside it (squished to fit the space the button leaves), and its title and footnote keep clear of it.
- disabled: bool = False¶
The whole row shown dimmed, with its button disabled (as by
Button.disabled, which on its own leaves the label alone).
- footnote: LangStrSpec | int | None = None¶
Small explanatory text drawn below the row’s content, aligned like its title; the row grows to make room for it.
- header_decorations_center: list[Decoration] | None = None¶
- header_decorations_left: list[Decoration] | None = None¶
- header_decorations_right: list[Decoration] | None = None¶
- label: LangStrSpec | int | None = None¶
- padding_right: float = 0.0¶
Extra inset for the button, which otherwise ends where the last button of a right-aligned row does.
- subtitle: LangStrSpec | int | None = None¶
- title: LangStrSpec | int | None = None¶
Section title shown above the row (with an optional subtitle), styled and placed exactly as a
ButtonRow’s.
- class bacommon.docui.v2.ButtonRow(buttons: list[Button], layout: ButtonRowLayout = ButtonRowLayout.SCROLL, header_height: float = 0.0, header_scale: float = 1.0, header_decorations_left: list[Decoration] | None = None, header_decorations_center: list[Decoration] | None = None, header_decorations_right: list[Decoration] | None = None, footer_height: float = 0.0, footer_scale: float = 1.0, footer_decorations_left: list[Decoration] | None = None, footer_decorations_center: list[Decoration] | None = None, footer_decorations_right: list[Decoration] | None = None, title: LangStrSpec | int | None = None, title_color: tuple[float, float, float, float] | None = None, title_flatness: float | None = None, title_shadow: float | None = None, subtitle: LangStrSpec | int | None = None, subtitle_color: tuple[float, float, float, float] | None = None, subtitle_flatness: float | None = None, subtitle_shadow: float | None = None, footnote: LangStrSpec | int | None = None, button_spacing: float = 15.0, padding_left: float | None = None, padding_right: float | None = None, padding_top: float | None = None, padding_bottom: float | None = None, spacing_top: float = 0.0, spacing_bottom: float = 0.0, spacing_title: float = 0.0, spacing_footnote: float = 0.0, center_content: bool = False, center_title: bool = False, content_align: HAlign | None = None, content_offset: float = 0.0, title_align: HAlign | None = None, simple_culling_h: float = 100.0, show_scrollbar: bool = True, debug: bool = False)[source]¶
Bases:
RowA row consisting of buttons.
title/subtitleareLangStrSpec. How the buttons use the row’s width is up tolayout.- content_align: HAlign | None = None¶
Horizontal alignment of buttons when they don’t fill the row’s width (a
SCROLLrow with more than that simply scrolls; aFIXEDone shrinks to fit;FILLrows always fill it). Overridescenter_contentwhen set. Builds older than this field ignore it (and thus left-align unlesscenter_contentis also set).
- content_offset: float = 0.0¶
Shifts a
FIXEDrow’s buttons sideways as a group (positive is right). They lay out exactly as they otherwise would – same order, spacing and shrink-to-fit – and then the whole group moves this far, but never past the row’s edges (it slides back in instead). Centered content thus centers on the row’s center plus this offset: the same point header and footer decorations at that x are placed from, which is the way to line a button up with band art regardless of the layout’s width or insets. Ignored bySCROLLandFILLrows. Builds older than this field ignore it.
The header band’s mirror image – the same thing, below the row (below its footnote too). Every row type has one.
Scales the footer band’s height and everything in it.
- footnote: LangStrSpec | int | None = None¶
Small explanatory text drawn below the row’s content, aligned like its title; the row grows to make room for it.
- get_padding() tuple[float, float, float, float][source]¶
Our (left, right, top, bottom) padding, defaults applied.
A scrolling row’s bottom default leaves room for the strip its scroll bar fades in over; the others need none.
- header_decorations_center: list[Decoration] | None = None¶
- header_decorations_left: list[Decoration] | None = None¶
- header_decorations_right: list[Decoration] | None = None¶
- header_height: float = 0.0¶
Height of an optional band above the row (above its title too) holding free-form, non-interactive decorations; 0 for none. Each of the three decoration lists is positioned relative to a point on the band’s vertical midline – its left edge (inset like row titles), its center, and its right edge. Every row type has one.
- layout: ButtonRowLayout = 's'¶
How the buttons use the row’s width. Builds older than this field always scroll.
- padding_left: float | None = None¶
Space around the buttons; None for the layout’s default (see
get_padding()). Left/right are from the column’s edges (SCROLLandFIXED) or from where control rows’ contents start/end (FILL).
- show_scrollbar: bool = True¶
Whether the row’s horizontal scroll bar is drawn (and grabbable by the mouse). Off, the row still scrolls every other way (drag, wheel, keys, page buttons) and keeps the same layout; only the bar goes. Builds older than this field always show it. (
SCROLLonly.)
- simple_culling_h: float = 100.0¶
If things disappear when scrolling left/right, turn this up (
SCROLLonly).
- spacing_bottom: float = 0.0¶
Extra space below the whole row (outside its footnote and footer). Every row type has one.
- spacing_footnote: float = 0.0¶
Extra space between the row’s content and its footnote (no effect without one); the footnote’s counterpart to
spacing_title. Builds older than this field ignore it. Every row type has one.
- spacing_title: float = 0.0¶
Extra space between the title/subtitle and the row’s content (no effect without either). Titles normally hug their content; pushing one away makes it read as a heading for a group of rows rather than a label for this one. Builds older than this field ignore it. Every row type has one.
- spacing_top: float = 0.0¶
Extra space above the whole row (outside its header and title). May be negative to pull rows together. Every row type has one.
- subtitle: LangStrSpec | int | None = None¶
- title: LangStrSpec | int | None = None¶
- class bacommon.docui.v2.ButtonRowLayout(*values)[source]¶
Bases:
EnumHow a
ButtonRowhandles the row’s width.ButtonRow.layoutcarries anenum_fallback(SCROLL), so a layout added here later scrolls on builds predating it instead of failing the whole response.- FILL = 'f'¶
Buttons sharing the row’s full width, spanning exactly what a control row’s contents do (from where control rows’ labels start to where their controls end), so the row lines up with control rows around it. Each button’s width is its share of that, in proportion to its own
sizewidth (equal sizes for equal buttons); everything else about each button, height included, is its own. LikeFIXED, placed straight on the page.
- FIXED = 'x'¶
Buttons at their own sizes, placed straight on the page (so nothing about them is clipped), aligned in the row like a scrolling row’s are. If they don’t all fit, they all shrink together until they do.
- SCROLL = 's'¶
Buttons at their own sizes in a strip that scrolls sideways when they don’t all fit. The strip clips what it holds (vertically too, so a button growing as it’s pressed can lose its top and bottom edges); its scroll bar fades in over the bottom of its padding.
- class bacommon.docui.v2.ButtonStyle(*values)[source]¶
Bases:
EnumStyles a button can be.
Button.stylecarries anenum_fallback(SQUARE), so a style added here later draws as a square button on builds predating it instead of failing the whole response.- BACK = 'b'¶
- BACK_SMALL = 'bs'¶
- LARGE = 'l'¶
- LARGER = 'xl'¶
- MEDIUM = 'm'¶
- SMALL = 's'¶
- SQUARE = 'q'¶
- SQUARE_WIDE = 'w'¶
- TAB = 't'¶
- class bacommon.docui.v2.CheckboxRow(name: str, label: LangStrSpec | int | None = None, on_change: Action | None = None, disabled: bool = False, title: LangStrSpec | int | None = None, title_color: tuple[float, float, float, float] | None = None, title_flatness: float | None = None, title_shadow: float | None = None, subtitle: LangStrSpec | int | None = None, subtitle_color: tuple[float, float, float, float] | None = None, subtitle_flatness: float | None = None, subtitle_shadow: float | None = None, title_align: HAlign | None = None, footnote: LangStrSpec | int | None = None, padding_left: float = 0.0, padding_right: float = 0.0, padding_top: float = 4.0, padding_bottom: float = 4.0, header_height: float = 0.0, header_scale: float = 1.0, header_decorations_left: list[Decoration] | None = None, header_decorations_center: list[Decoration] | None = None, header_decorations_right: list[Decoration] | None = None, footer_height: float = 0.0, footer_scale: float = 1.0, footer_decorations_left: list[Decoration] | None = None, footer_decorations_center: list[Decoration] | None = None, footer_decorations_right: list[Decoration] | None = None, spacing_top: float = 0.0, spacing_bottom: float = 0.0, spacing_title: float = 0.0, spacing_footnote: float = 0.0, debug: bool = False)[source]¶
Bases:
RowA row consisting of a single checkbox.
Label at the left edge of the row; box at the right. Its value lives in the page’s state (see
Page.state) undername, which must not start with an underscore and must hold a bool.- disabled: bool = False¶
Shown dimmed and not toggleable (a press plays an error sound). Still selectable, so navigation around it is unaffected. Clients predating this field show it as a normal row.
- footnote: LangStrSpec | int | None = None¶
Small explanatory text drawn below the row’s content, aligned like its title; the row grows to make room for it.
- header_decorations_center: list[Decoration] | None = None¶
- header_decorations_left: list[Decoration] | None = None¶
- header_decorations_right: list[Decoration] | None = None¶
- label: LangStrSpec | int | None = None¶
- on_change: Action | None = None¶
Fired when the value changes, after the new value has been written to the page’s state. Without one, a changed value simply goes out with whatever request the page fires next. Actions opening new windows are not allowed here.
- padding_right: float = 0.0¶
Extra inset for the box, which otherwise ends where the last button of a right-aligned row does.
- subtitle: LangStrSpec | int | None = None¶
- title: LangStrSpec | int | None = None¶
Section title shown above the row (with an optional subtitle), styled and placed exactly as a
ButtonRow’s.
- class bacommon.docui.v2.Choice(value: str | None, label: LangStrSpec | int, disabled: bool = False)[source]¶
Bases:
objectOne option in a
ChoiceRow.- disabled: bool = False¶
Shown in the menu but greyed out and not pickable (an option this device can’t use, say). Clients predating this field show it as a normal choice.
- label: LangStrSpec | int¶
- class bacommon.docui.v2.ChoiceRow(name: str, choices: list[Choice], label: LangStrSpec | int | None = None, on_change: Action | None = None, disabled: bool = False, title: LangStrSpec | int | None = None, title_color: tuple[float, float, float, float] | None = None, title_flatness: float | None = None, title_shadow: float | None = None, subtitle: LangStrSpec | int | None = None, subtitle_color: tuple[float, float, float, float] | None = None, subtitle_flatness: float | None = None, subtitle_shadow: float | None = None, title_align: HAlign | None = None, footnote: LangStrSpec | int | None = None, padding_left: float = 0.0, padding_right: float = 0.0, padding_top: float = 4.0, padding_bottom: float = 4.0, header_height: float = 0.0, header_scale: float = 1.0, header_decorations_left: list[Decoration] | None = None, header_decorations_center: list[Decoration] | None = None, header_decorations_right: list[Decoration] | None = None, footer_height: float = 0.0, footer_scale: float = 1.0, footer_decorations_left: list[Decoration] | None = None, footer_decorations_center: list[Decoration] | None = None, footer_decorations_right: list[Decoration] | None = None, spacing_top: float = 0.0, spacing_bottom: float = 0.0, spacing_title: float = 0.0, spacing_footnote: float = 0.0, debug: bool = False)[source]¶
Bases:
RowA row consisting of a single pick-one-of-these control.
Label at the left edge of the row; a popup-menu button showing the current choice at the right. Its value lives in the page’s state (see
Page.state) undername, which must not start with an underscore and must hold thevalueof one ofchoices.- disabled: bool = False¶
The whole row shown dimmed with its menu unopenable (a press plays an error sound instead). Still selectable, so navigation around it is unaffected. Distinct from
Choice.disabled, which greys individual options in a working menu. Clients predating this field show it as a normal row.
- footnote: LangStrSpec | int | None = None¶
Small explanatory text drawn below the row’s content, aligned like its title; the row grows to make room for it.
- header_decorations_center: list[Decoration] | None = None¶
- header_decorations_left: list[Decoration] | None = None¶
- header_decorations_right: list[Decoration] | None = None¶
- label: LangStrSpec | int | None = None¶
- on_change: Action | None = None¶
Fired when a choice is picked, after the new value has been written to the page’s state. Without one, a changed value simply goes out with whatever request the page fires next. Actions opening new windows are not allowed here.
- padding_right: float = 0.0¶
Extra inset for the button, which otherwise ends where the last button of a right-aligned row does.
- subtitle: LangStrSpec | int | None = None¶
- title: LangStrSpec | int | None = None¶
Section title shown above the row (with an optional subtitle), styled and placed exactly as a
ButtonRow’s.
- class bacommon.docui.v2.ColorRow(name: str, label: LangStrSpec | int | None = None, on_change: Action | None = None, disabled: bool = False, title: LangStrSpec | int | None = None, title_color: tuple[float, float, float, float] | None = None, title_flatness: float | None = None, title_shadow: float | None = None, subtitle: LangStrSpec | int | None = None, subtitle_color: tuple[float, float, float, float] | None = None, subtitle_flatness: float | None = None, subtitle_shadow: float | None = None, title_align: HAlign | None = None, footnote: LangStrSpec | int | None = None, padding_left: float = 0.0, padding_right: float = 0.0, padding_top: float = 4.0, padding_bottom: float = 4.0, header_height: float = 0.0, header_scale: float = 1.0, header_decorations_left: list[Decoration] | None = None, header_decorations_center: list[Decoration] | None = None, header_decorations_right: list[Decoration] | None = None, footer_height: float = 0.0, footer_scale: float = 1.0, footer_decorations_left: list[Decoration] | None = None, footer_decorations_center: list[Decoration] | None = None, footer_decorations_right: list[Decoration] | None = None, spacing_top: float = 0.0, spacing_bottom: float = 0.0, spacing_title: float = 0.0, spacing_footnote: float = 0.0, debug: bool = False)[source]¶
Bases:
RowA row consisting of a single color-picking control.
Label at the left edge of the row; a swatch button showing the current color at the right, which opens a color picker. Its value lives in the page’s state (see
Page.state) undername, which must not start with an underscore and must hold an[r, g, b]list of floats in the 0-1 range.- disabled: bool = False¶
Shown dimmed (the swatch greyed like any disabled button) with its picker unopenable (a press plays an error sound). Still selectable, so navigation around it is unaffected. Clients predating this field show it as a normal row.
- footnote: LangStrSpec | int | None = None¶
Small explanatory text drawn below the row’s content, aligned like its title; the row grows to make room for it.
- header_decorations_center: list[Decoration] | None = None¶
- header_decorations_left: list[Decoration] | None = None¶
- header_decorations_right: list[Decoration] | None = None¶
- label: LangStrSpec | int | None = None¶
- on_change: Action | None = None¶
Fired when the picker closes with a changed color, after the new value has been written to the page’s state. (Not on every intermediate change; the exact-color picker streams those.) Without one, a changed value simply goes out with whatever request the page fires next. Actions opening new windows are not allowed here.
- padding_right: float = 0.0¶
Extra inset for the swatch, which otherwise ends where the last button of a right-aligned row does.
- subtitle: LangStrSpec | int | None = None¶
- title: LangStrSpec | int | None = None¶
Section title shown above the row (with an optional subtitle), styled and placed exactly as a
ButtonRow’s.
- class bacommon.docui.v2.Decoration[source]¶
Bases:
IOMultiType[DecorationTypeID]Top level class for our decoration multitype.
- classmethod get_type(type_id: DecorationTypeID) type[Decoration][source]¶
Return a specific subclass given a type-id.
Should be overridden by child classes. Generally, users of the class should call
get_type_cached()instead of this, as it is more efficient.
- classmethod get_type_id() DecorationTypeID[source]¶
Return the type-id for this subclass.
- classmethod get_type_id_storage_name() str[source]¶
Return the key used to store type id in serialized data.
The default is a short obscure value so that it is unlikely to conflict with members of individual type attrs, but in some cases one might prefer to serialize it to something simpler like ‘type’ by overriding this call. One just needs to make sure that no encompassed types serialize anything to that same name themself (dataclassio will error if they do).
- classmethod get_unknown_type_fallback() Decoration[source]¶
Return a fallback object in cases of unrecognized types.
This can allow newer data to remain readable in older environments. Use caution with this option, however, as it effectively modifies data.
- class bacommon.docui.v2.DecorationTypeID(*values)[source]¶
Bases:
EnumType ID for each of our subclasses.
- DEPICTION = 'd'¶
- IMAGE = 'i'¶
- TEXT = 't'¶
- UNKNOWN = 'u'¶
- class bacommon.docui.v2.Depiction(depiction: Depiction, position: tuple[float, float], size: tuple[float, float], h_align: HAlign = HAlign.CENTER, v_align: VAlign = VAlign.CENTER, highlight: bool = True, depth_range: tuple[float, float] | None = None, debug: bool = False, anim_id: str | None = None)[source]¶
Bases:
DecorationA
bacommon.depiction.Depiction, drawn in a box.positionis the box’s center andsizeits size. A depiction with a shape of its own (a square icon, an image’s aspect) is fitted inside the box and placed byh_align/v_align; one without (a name) fills the box.Depictions are self-sufficient: whatever packages one references contribute nothing to the page’s own
Response.packages. Art that isn’t local yet shows as a standin, never a blocked page.- anim_id: str | None = None¶
Lets client-effects animate this decoration (see
bacommon.clienteffect.KeyframeAnimation). Everything in a page sharing an id animates together.
- classmethod get_type_id() DecorationTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.docui.v2.HAlign(*values)[source]¶
Bases:
EnumHorizontal alignment.
Fields of this type carry an
enum_fallback(each field’s own default;LEFTfor the optional row alignments), so a value added here later decodes as that on builds predating it instead of failing the whole response.- CENTER = 'c'¶
- LEFT = 'l'¶
- RIGHT = 'r'¶
- class bacommon.docui.v2.Image(texture: TextureSpec | int, position: tuple[float, float], size: tuple[float, float], color: tuple[float, float, float, float] | None = None, h_align: HAlign = HAlign.CENTER, v_align: VAlign = VAlign.CENTER, tint_texture: TextureSpec | int | None = None, tint_color: tuple[float, float, float] | None = None, tint2_color: tuple[float, float, float] | None = None, mask_texture: TextureSpec | int | None = None, mesh_opaque: MeshSpec | int | None = None, mesh_transparent: MeshSpec | int | None = None, highlight: bool = True, depth_range: tuple[float, float] | None = None, tint3_color: tuple[float, float, float] | None = None, nine_patch: ImageNinePatch | None = None, debug: bool = False, anim_id: str | None = None)[source]¶
Bases:
DecorationImage decoration. Textures/meshes are language-independent refs.
Unlike text, image assets need no per-locale decode; each ref (
TextureSpec/MeshSpec) is resolved by the client and rendered directly.- anim_id: str | None = None¶
Lets client-effects animate this decoration (see
bacommon.clienteffect.KeyframeAnimation). Everything in a page sharing an id animates together.
- debug: bool = False¶
Show this image’s bounds; useful during development. Worth having separately from the art because a texture with a transparent margin gives no clue where its box really is.
- classmethod get_type_id() DecorationTypeID[source]¶
Return the type-id for this subclass.
- mask_texture: TextureSpec | int | None = None¶
- nine_patch: ImageNinePatch | None = None¶
Draw as a 9-patch (see
ImageNinePatch). Clients before this field ignore it and stretch the whole texture over the box.
- texture: TextureSpec | int¶
The image’s texture. An
intis the indexed form – a flat index into the textures domain ofResponse.packages(seebacommon.assetspec._index); the client swaps it for aTextureSpecwhile resolving, so everything downstream of resolve sees only specs. Old clients are served the spec form.
- tint3_color: tuple[float, float, float] | None = None¶
Tint through the tint texture’s blue channel (as
tint_coloris red andtint2_colorgreen). Clients before this field ignore it.
- tint_texture: TextureSpec | int | None = None¶
- class bacommon.docui.v2.ImageNinePatch(insets: tuple[float, float, float, float], borders: tuple[float, float, float, float], tile_h: bool = False, tile_v: bool = False)[source]¶
Bases:
objectDraws an
Imageas a 9-patch filling its box exactly.The texture splits into corners, edges and a middle; corners keep their drawn size, edges and middle fill what’s between. Tint and mask textures share the texture’s layout.
- borders: tuple[float, float, float, float]¶
How big those edges draw, in the image’s own units (as its
size), same order. A pair too big for the box shrinks to fit.
- insets: tuple[float, float, float, float]¶
Where the texture splits, as fractions of its width/height from the left, bottom, right and top. 0.5 on each side of an axis makes that axis’s middle a single texel line.
- class bacommon.docui.v2.Local(close_window: bool = False, default_sound: bool = True, immediate_local_action: str | None = None, immediate_local_action_args: dict | None = None, sets: dict | None = None, return_sets: dict | None = None)[source]¶
Bases:
ActionPerform only local actions; no new requests or page changes.
- classmethod get_type_id() ActionTypeID[source]¶
Return the type-id for this subclass.
- immediate_local_action: str | None = None¶
Local action to run immediately when the button is pressed. Will be handled by
bauiv1lib.docui.DocUIController.local_action().
- return_sets: dict | None = None¶
With
close_window, values to assign into the state of the page being returned to, which then refreshes with them; how a picker opened in a window of its own hands back what was picked. Carries the state’s type id (_t), and is applied only if the returned-to page’s state is of that type. Build it withbacommon.docui.routes.DocUIState.assign_on_return().
- sets: dict | None = None¶
Values to assign into the page’s state (see
Page.state).
- class bacommon.docui.v2.Menu(items: list[MenuItem], default_sound: bool = True)[source]¶
Bases:
ActionPop up a menu of items at the button; picking one runs its action.
For buttons offering several things to do (a ‘…’ button, say). Picking a value is a
ChoiceRow’s job instead. The button is drawn like any other; its label or icon is what says it opens a menu.Only buttons can open menus; one arriving anywhere else an action can go (an input row’s
on_change, a timed action, a menu item) is ignored. Clients predating this type see an unknown action.- classmethod get_type_id() ActionTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.docui.v2.MenuItem(label: LangStrSpec | int, action: Action | None = None, disabled: bool = False)[source]¶
Bases:
objectOne entry in a
Menu.- action: Action | None = None¶
What picking this item does; anything a button’s action can be except another
Menu(menus don’t nest). The menu makes its own sound when something is picked, so the action’sdefault_soundis not played.
- label: LangStrSpec | int¶
- class bacommon.docui.v2.NumberRow(name: str, min_value: float, max_value: float, increment: float, label: LangStrSpec | int | None = None, as_percent: bool = False, decimals: int = 0, on_change: Action | None = None, disabled: bool = False, title: LangStrSpec | int | None = None, title_color: tuple[float, float, float, float] | None = None, title_flatness: float | None = None, title_shadow: float | None = None, subtitle: LangStrSpec | int | None = None, subtitle_color: tuple[float, float, float, float] | None = None, subtitle_flatness: float | None = None, subtitle_shadow: float | None = None, title_align: HAlign | None = None, footnote: LangStrSpec | int | None = None, padding_left: float = 0.0, padding_right: float = 0.0, padding_top: float = 4.0, padding_bottom: float = 4.0, header_height: float = 0.0, header_scale: float = 1.0, header_decorations_left: list[Decoration] | None = None, header_decorations_center: list[Decoration] | None = None, header_decorations_right: list[Decoration] | None = None, footer_height: float = 0.0, footer_scale: float = 1.0, footer_decorations_left: list[Decoration] | None = None, footer_decorations_center: list[Decoration] | None = None, footer_decorations_right: list[Decoration] | None = None, spacing_top: float = 0.0, spacing_bottom: float = 0.0, spacing_title: float = 0.0, spacing_footnote: float = 0.0, debug: bool = False)[source]¶
Bases:
RowA row editing a number with a ‘-’ and a ‘+’ button.
Label at the left, then at the row’s right the current value as text followed by the two buttons. Each press steps the value by
incrementwithinmin_value/max_value(holding a button repeats). Its value lives in the page’s state (seePage.state) undername, which must not start with an underscore and must hold a float betweenmin_valueandmax_value.For a value with many steps,
SliderRowis usually the better fit; this suits short ranges where each step is a distinct setting.- as_percent: bool = False¶
Show the value as a whole percentage (
0.5->50%) rather than todecimalsplaces.
- disabled: bool = False¶
Shown dimmed and not adjustable (both buttons disabled). Still selectable, so navigation around it is unaffected. Clients predating this field show it as a normal adjustable row.
- footnote: LangStrSpec | int | None = None¶
Small explanatory text drawn below the row’s content, aligned like its title; the row grows to make room for it.
- header_decorations_center: list[Decoration] | None = None¶
- header_decorations_left: list[Decoration] | None = None¶
- header_decorations_right: list[Decoration] | None = None¶
- label: LangStrSpec | int | None = None¶
- on_change: Action | None = None¶
Fired on each press that changes the value, after it has been written to the page’s state. Without one, a changed value simply goes out with whatever request the page fires next. Actions opening new windows are not allowed here.
- padding_right: float = 0.0¶
Extra inset for the ‘+’ button, which otherwise ends where the last button of a right-aligned row does.
- subtitle: LangStrSpec | int | None = None¶
- title: LangStrSpec | int | None = None¶
Section title shown above the row (with an optional subtitle), styled and placed exactly as a
ButtonRow’s.
- class bacommon.docui.v2.Page(title: LangStrSpec | int, rows: list[Row], state: dict | None = None, viewer: Depiction | None = None, center_vertically: bool = False, show_scrollbar: bool = True, row_spacing: float = 10.0, simple_culling_v: float = 100.0, padding_bottom: float = 0.0, padding_left: float = 0.0, padding_top: float = 0.0, padding_right: float = 0.0)[source]¶
Bases:
objectDoc-UI page version 2.
titleis a language-agnosticLangStrSpec.- center_vertically: bool = False¶
Center content vertically when it’s smaller than the available height.
- show_scrollbar: bool = True¶
Whether the page’s vertical scroll bar is drawn (and grabbable by the mouse). Off, the page still scrolls every other way (drag, wheel, keys) and keeps the same layout; only the bar goes. Builds older than this field always show it.
- state: dict | None = None¶
Values belonging to the page as a whole – what input rows show and edit, plus anything else the page wants handed back. The client sends the current values along with every request fired from the page (see
Request.state), and whatever page comes back replaces them with its own.A flat dict of json values. Keys starting with an underscore are reserved;
_toptionally names the type of state this is so that state reaching a page expecting some other type can be recognized as such and ignored.
- title: LangStrSpec | int¶
- viewer: Depiction | None = None¶
What the window’s viewer pane shows, for windows at the
WindowLayout.VIEWERlayout (ignored elsewhere): usually abacommon.depiction.CharacterViewerDepiction. The client keeps what the pane shows running across pages, so a page re-sent with a changed depiction (an editor’s draft, say) updates the picture in place. Without one the pane is left blank.
- class bacommon.docui.v2.Replace(request: Request, default_sound: bool = True, sets: dict | None = None, state: dict | None = None)[source]¶
Bases:
ActionReplace the current page with a new one (seamless transition).
- classmethod get_type_id() ActionTypeID[source]¶
Return the type-id for this subclass.
- sets: dict | None = None¶
Values to assign into the page’s state before the request goes out (see
Page.state).
- class bacommon.docui.v2.Request(path: str, method: RequestMethod = RequestMethod.GET, args: dict = <factory>, state: dict | None = None, trigger: str | None = None)[source]¶
Bases:
DocUIRequestFull request to doc-ui (v2).
- classmethod get_type_id() DocUIRequestTypeID[source]¶
Return the type-id for this subclass.
- method: RequestMethod = 'g'¶
- state: dict | None = None¶
Current state of the page this request was fired from (see
Page.state), if it had any. Clients fill this in; page authors never set it directly.
- class bacommon.docui.v2.RequestMethod(*values)[source]¶
Bases:
EnumType of requests that can be made to doc-ui servers.
- GET = 'g'¶
Fetch some resource. Retriable; results optionally cacheable.
- POST = 'p'¶
Change some resource. Not implicitly retriable, not cacheable.
- UNKNOWN = 'u'¶
An unknown request method (newer client -> older server).
- class bacommon.docui.v2.Response(page: Page, status: ResponseStatus = ResponseStatus.SUCCESS, for_build: int | None = None, packages: list[ApverNum] = <factory>, asset_index_digest: str | None = None, langstr_index_digest: str | None = None, local_action: str | None = None, local_action_args: dict | None = None, timed_action: Action | None = None, timed_action_delay: float = 0.0, minimum_engine_build: int | None = None, shared_state_id: str | None = None)[source]¶
Bases:
DocUIResponseFull docui response (v2).
- asset_index_digest: str | None = None¶
Digest of the exact asset-index domain the producer indexed against, from
domain_digest(). The two ends build that domain from different sources, and a disagreement is invisible on its own – an index that is wrong but still in range simply names a different asset, so the page renders with the wrong art and nothing logs. A consumer whose own digest differs must refuse to de-index rather than trust it; leaving the integers in place makes the failure loud and names the packages involved. Set only when asset refs were indexed.
- for_build: int | None = None¶
The engine build this response was built for, as a sanity check: responses can be tailored per-build (client-effect forms etc.), so a consumer seeing a mismatch with its own build should treat the response as stale (e.g. toss cached data) rather than use it.
- classmethod get_type_id() DocUIResponseTypeID[source]¶
Return the type-id for this subclass.
- langstr_index_digest: str | None = None¶
The same guard for folded language-string references, from
domain_digest(). Separate from the asset digest so a mismatch says which of the two domains drifted. Set only when string refs were folded.
- local_action: str | None = None¶
Local action to run after this response is initially received (not re-run on automatic page refreshes). Will be handled by
bauiv1lib.docui.DocUIController.local_action().
- packages: list[ApverNum]¶
Asset-package-versions the response’s integer-indexed language-strings resolve against (position = package index). Present only on wire responses finalized to the indexed form by the server; its presence declares the page + contained client effects fully indexed (consumers may flag resource-form leaks), and it doubles as the client’s resolve/pre-warm manifest. Locally-authored responses never carry it (indexing is a wire compression; local pages stay in the authored resource form).
Explicit shared-state id (defaults to the request path client-side).
- status: ResponseStatus = 0¶
(A status this build doesn’t know decodes as
ResponseStatus.UNKNOWN_ERROR, so statuses can be added without older clients failing to decode the response. Builds before 23021 lack this fallback: a server must not send themResponseStatus.NEED_UPDATE_ERRORor anything newer.)
- class bacommon.docui.v2.ResponseStatus(*values)[source]¶
Bases:
EnumThe overall result of a request.
- COMMUNICATION_ERROR = 2¶
Something went wrong talking to the server. A ‘Retry’ may be apt.
- NEED_UPDATE_ERROR = 4¶
The client is too old for this; it needs an update. Set by a server declining a request on those grounds, so clients can show their standard update prompt (and composite pages can say so in their own words) without reading the page’s text.
Response.minimum_engine_buildmay name the build when the server knows it.
- NOT_SIGNED_IN_ERROR = 3¶
This requires the user to be signed in, and they aint.
- SUCCESS = 0¶
- UNKNOWN_ERROR = 1¶
Something went wrong. That’s all we know.
- class bacommon.docui.v2.Row[source]¶
Bases:
IOMultiType[RowTypeID]Top level class for our row multitype.
- classmethod get_type(type_id: RowTypeID) type[Row][source]¶
Return a specific subclass given a type-id.
Should be overridden by child classes. Generally, users of the class should call
get_type_cached()instead of this, as it is more efficient.
- classmethod get_type_id_storage_name() str[source]¶
Return the key used to store type id in serialized data.
The default is a short obscure value so that it is unlikely to conflict with members of individual type attrs, but in some cases one might prefer to serialize it to something simpler like ‘type’ by overriding this call. One just needs to make sure that no encompassed types serialize anything to that same name themself (dataclassio will error if they do).
- class bacommon.docui.v2.RowTypeID(*values)[source]¶
Bases:
EnumType ID for each of our subclasses.
- BUTTON_CONTROL_ROW = 'bc'¶
- BUTTON_ROW = 'b'¶
- CHECKBOX_ROW = 'c'¶
- CHOICE_ROW = 'h'¶
- COLOR_ROW = 'k'¶
- NUMBER_ROW = 'n'¶
- SECTION = 'sc'¶
- SLIDER_ROW = 's'¶
- TEXT_INPUT_ROW = 't'¶
- UNKNOWN = 'u'¶
- class bacommon.docui.v2.Section(rows: list[Row], backing: SectionBacking | None = None, header_height: float = 0.0, header_scale: float = 1.0, header_decorations_left: list[Decoration] | None = None, header_decorations_center: list[Decoration] | None = None, header_decorations_right: list[Decoration] | None = None, title: LangStrSpec | int | None = None, title_color: tuple[float, float, float, float] | None = None, title_flatness: float | None = None, title_shadow: float | None = None, subtitle: LangStrSpec | int | None = None, subtitle_color: tuple[float, float, float, float] | None = None, subtitle_flatness: float | None = None, subtitle_shadow: float | None = None, title_align: HAlign | None = None, footnote: LangStrSpec | int | None = None, footnote_color: tuple[float, float, float, float] | None = None, footnote_flatness: float | None = None, footnote_shadow: float | None = None, footer_height: float = 0.0, footer_scale: float = 1.0, footer_decorations_left: list[Decoration] | None = None, footer_decorations_center: list[Decoration] | None = None, footer_decorations_right: list[Decoration] | None = None, spacing_top: float = 0.0, spacing_bottom: float = 0.0, debug: bool = False)[source]¶
Bases:
RowA group of rows, with an optional heading, note and backing.
Its rows lay out exactly as they would directly in the page; the section adds around them a heading (header band, title, subtitle) above, a note (footnote, footer band) below, and optionally a backing (see
SectionBacking), which turns it into a card with a layout of its own. With none of those it just stands its rows a little apart from what comes before and after, so the grouping reads at a glance.The heading is drawn like a row’s own titles but a bit larger, so it reads as heading the group rather than labeling one row; the note likewise. Neither is selectable: selecting the section’s first selectable row scrolls its heading into view too, and its last its note.
Sections don’t nest; a section among a section’s rows is ignored (the client logs an error). Builds older than this row type skip a section entirely, rows included.
title/subtitle/footnoteareLangStrSpec.- backing: SectionBacking | None = None¶
Make the section a card (see
SectionBacking).
- debug: bool = False¶
Outline the section’s heading and note (as rows’ debug does). Its rows have their own debug flags.
- footnote: LangStrSpec | int | None = None¶
The note under the section’s rows (drawn like a subtitle).
- footnote_color: tuple[float, float, float, float] | None = None¶
The footnote’s color/flatness/shadow (drawn like a subtitle).
- header_decorations_center: list[Decoration] | None = None¶
- header_decorations_left: list[Decoration] | None = None¶
- header_decorations_right: list[Decoration] | None = None¶
- spacing_top: float = 0.0¶
Extra space above the section (outside its header band) and below it (outside its footer band), on top of the standing room it keeps from its neighbors; either may be negative. See
ButtonRow.spacing_top.
- subtitle: LangStrSpec | int | None = None¶
- title: LangStrSpec | int | None = None¶
- title_align: HAlign | None = None¶
See
ButtonRow.title_align; the footnote follows it too. Left by default.
- class bacommon.docui.v2.SectionBacking(texture: TextureSpec | int | None = None, color: tuple[float, float, float, float] = (1.0, 1.0, 1.0, 1.0), h_pin: tuple[float, float] = (0.0, 0.0), v_pin: tuple[float, float] = (0.0, 0.0), max_width: float | None = None, content_inset: float = 0.0, padding_top: float = 0.0, padding_bottom: float = 0.0)[source]¶
Bases:
objectA backing for a
Section, and the layout that goes with it.A backed section is a card: a rect of
max_widthat most (else the column’s full width), centered in the column, from the top of the section’s heading (else its first row) to the bottom of its note (else its last row) pluspadding_top/padding_bottom. Its button rows clip at the rect’s left and right edges, and its content lays out inside it as a page’s does in its column: button rows’ buttonscontent_insetin from those edges, text (heading and note text, row titles, labels) and control and fill rows a few units further in to line up with buttons’ visible edges, and centered things centered on the card. All of that holds whatever width the section gets.The rect is drawn as
texture(tinted bycolor) or, with no texture, a flatcolorfill; an alpha of 0 draws nothing, which leaves just the layout.A texture’s visible shape usually sits inside soft or shadowed margins; the pins say where.
h_pin(left, right) is how far in from each side of the image, as a fraction of its width (0 to 0.5), the shape’s edge falls: the image is stretched so those points land on the rect’s edges.v_pin(top, bottom) does the same vertically. Pins are a property of the texture alone, so one calibration holds at every width. They don’t apply to flat fills.- content_inset: float = 0.0¶
How far in from the card’s edges its button rows’ buttons sit (both sides; a page’s sit 28 in from its column’s).
- texture: TextureSpec | int | None = None¶
- class bacommon.docui.v2.SliderRow(name: str, min_value: float, max_value: float, increment: float, label: LangStrSpec | int | None = None, as_percent: bool = False, decimals: int = 2, on_change: Action | None = None, on_drag: Local | None = None, drag_interval: float = 0.25, drag_delay: float = 0.0, disabled: bool = False, title: LangStrSpec | int | None = None, title_color: tuple[float, float, float, float] | None = None, title_flatness: float | None = None, title_shadow: float | None = None, subtitle: LangStrSpec | int | None = None, subtitle_color: tuple[float, float, float, float] | None = None, subtitle_flatness: float | None = None, subtitle_shadow: float | None = None, title_align: HAlign | None = None, footnote: LangStrSpec | int | None = None, padding_left: float = 0.0, padding_right: float = 0.0, padding_top: float = 4.0, padding_bottom: float = 4.0, header_height: float = 0.0, header_scale: float = 1.0, header_decorations_left: list[Decoration] | None = None, header_decorations_center: list[Decoration] | None = None, header_decorations_right: list[Decoration] | None = None, footer_height: float = 0.0, footer_scale: float = 1.0, footer_decorations_left: list[Decoration] | None = None, footer_decorations_center: list[Decoration] | None = None, footer_decorations_right: list[Decoration] | None = None, spacing_top: float = 0.0, spacing_bottom: float = 0.0, spacing_title: float = 0.0, spacing_footnote: float = 0.0, debug: bool = False)[source]¶
Bases:
RowA row consisting of a single slider control.
Label at the left (right-aligned toward the control), the current value as text, then the slider itself at the row’s right. Its value lives in the page’s state (see
Page.state) undername, which must not start with an underscore and must hold a float betweenmin_valueandmax_value.- as_percent: bool = False¶
Show the value as a whole percentage (
0.5->50%) rather than todecimalsplaces.
- disabled: bool = False¶
Shown dimmed and not adjustable. Still selectable, so navigation around it is unaffected. Clients predating this field show it as a normal adjustable row.
- footnote: LangStrSpec | int | None = None¶
Small explanatory text drawn below the row’s content, aligned like its title; the row grows to make room for it.
- header_decorations_center: list[Decoration] | None = None¶
- header_decorations_left: list[Decoration] | None = None¶
- header_decorations_right: list[Decoration] | None = None¶
- label: LangStrSpec | int | None = None¶
- on_change: Action | None = None¶
Fired when a value is settled on – the nub released after a drag, or a run of key/controller steps going quiet (half a second after the last step, or at once on deselection) – after the value has been written to the page’s state. Without one, a changed value simply goes out with whatever request the page fires next. Actions opening new windows are not allowed here.
- on_drag: Local | None = None¶
Fired while the nub is being dragged (key/controller steps count as dragging), at most every
drag_intervalseconds and not beforedrag_delayinto the drag, with the page’s state already holding the value so far; also once for the settled value if the drag’s last apply missed it. Local only (typed so): whatever needs to track the value live – a volume being set – happens client side, with no request until the value settles.
- padding_right: float = 0.0¶
Extra inset for the slider, which otherwise ends where the last button of a right-aligned row does.
- subtitle: LangStrSpec | int | None = None¶
- title: LangStrSpec | int | None = None¶
Section title shown above the row (with an optional subtitle), styled and placed exactly as a
ButtonRow’s.
- class bacommon.docui.v2.Text(text: LangStrSpec | int, position: tuple[float, float], size: tuple[float, float], scale: float = 1.0, h_align: HAlign = HAlign.CENTER, v_align: VAlign = VAlign.CENTER, color: tuple[float, float, float, float] | None = None, flatness: float | None = None, shadow: float | None = None, highlight: bool = True, depth_range: tuple[float, float] | None = None, debug: bool = False, image_left: TextImage | None = None, image_right: TextImage | None = None, anim_id: str | None = None)[source]¶
Bases:
DecorationText decoration.
textis a language-agnosticLangStrSpec.With
image_leftorimage_rightset, the text and its images are measured, shrunk to fitsize(never grown), and aligned as a single unit.- anim_id: str | None = None¶
Lets client-effects animate this decoration (see
bacommon.clienteffect.KeyframeAnimation). Everything in a page sharing an id animates together.
- classmethod get_type_id() DecorationTypeID[source]¶
Return the type-id for this subclass.
- text: LangStrSpec | int¶
The text. An
intis the indexed form – a flat index into the string domain ofResponse.packages(seebacommon.langstr._flatindex); the client unfolds it into the two-integer form the native decoder consumes while resolving. Strings carrying substitutions never fold.
- class bacommon.docui.v2.TextImage(texture: TextureSpec | int, size: tuple[float, float], offset: tuple[float, float] = (0.0, 0.0), color: tuple[float, float, float, float] | None = None, insets: tuple[float, float, float, float] = (0.0, 0.0, 0.0, 0.0))[source]¶
Bases:
objectAn image fixed to one end of a
Textdecoration.For things like a price: a count with its currency icon beside it, measured, fitted, and aligned as one unit. The producer cannot do that itself because it cannot know the text’s rendered width; the client measures it while laying out the text.
Sizes and offsets are in text units – they are multiplied by the text’s effective scale – so the image grows and shrinks with its text. The image’s layout box (its size less its
insets) sits butted against its end of the text and vertically centered on the line; spacing from the text therefore comes from the insets, not from anything the producer adds.Meant for single-line text; on multi-line text the images center against the whole block.
- color: tuple[float, float, float, float] | None = None¶
Color and opacity. Deliberately separate from the text’s color: a coin should not turn green because its count is.
- insets: tuple[float, float, float, float] = (0.0, 0.0, 0.0, 0.0)¶
The image’s layout box, as fractions of its size trimmed from each edge, in (left, bottom, right, top) order. Layout uses only this box – for butting against the text, centering on the line, and measuring the unit – while the full image still draws. Typically trims most of the art’s transparent padding, leaving in whatever spacing the art wants beside text – the way a font glyph carries its own side bearings. A negative inset extends the box past the image instead (like a CSS margin), for art with less padding than the spacing it wants. Fractions rather than units because this is a fact of the art, true at any size.
- offset: tuple[float, float] = (0.0, 0.0)¶
A purely visual shift in text units, positive being right/up. It moves where the image draws and nothing else, like CSS relative positioning; measuring, fitting, and alignment ignore it. For small optical corrections – spacing belongs in
insets.
- texture: TextureSpec | int¶
The image’s texture. An
intis the indexed form; seeImage.texture.
- class bacommon.docui.v2.TextInputRow(name: str, label: LangStrSpec | int | None = None, description: LangStrSpec | int | None = None, max_chars: int = 64, on_change: Action | None = None, on_submit: Action | None = None, disabled: bool = False, title: LangStrSpec | int | None = None, title_color: tuple[float, float, float, float] | None = None, title_flatness: float | None = None, title_shadow: float | None = None, subtitle: LangStrSpec | int | None = None, subtitle_color: tuple[float, float, float, float] | None = None, subtitle_flatness: float | None = None, subtitle_shadow: float | None = None, title_align: HAlign | None = None, footnote: LangStrSpec | int | None = None, padding_left: float = 0.0, padding_right: float = 0.0, padding_top: float = 4.0, padding_bottom: float = 4.0, header_height: float = 0.0, header_scale: float = 1.0, header_decorations_left: list[Decoration] | None = None, header_decorations_center: list[Decoration] | None = None, header_decorations_right: list[Decoration] | None = None, footer_height: float = 0.0, footer_scale: float = 1.0, footer_decorations_left: list[Decoration] | None = None, footer_decorations_center: list[Decoration] | None = None, footer_decorations_right: list[Decoration] | None = None, spacing_top: float = 0.0, spacing_bottom: float = 0.0, spacing_title: float = 0.0, spacing_footnote: float = 0.0, debug: bool = False)[source]¶
Bases:
RowA row consisting of a single editable line of text.
Label at the left edge of the row, taking up to half of its width (and squished to fit if it wants more); the editable text gets the rest. Its value lives in the page’s state (see
Page.state) undername, which must not start with an underscore and must hold a str.- description: LangStrSpec | int | None = None¶
What is being edited, for places that ask for text by way of a separate dialog (on-screen keyboards and such). The label gets used when this is not provided.
- disabled: bool = False¶
Shown dimmed and not editable. Still selectable, so navigation around it is unaffected. Clients predating this field show it as a normal editable row.
- footnote: LangStrSpec | int | None = None¶
Small explanatory text drawn below the row’s content, aligned like its title; the row grows to make room for it.
- header_decorations_center: list[Decoration] | None = None¶
- header_decorations_left: list[Decoration] | None = None¶
- header_decorations_right: list[Decoration] | None = None¶
- label: LangStrSpec | int | None = None¶
- on_change: Action | None = None¶
Fired when an edit is applied (a text-entry dialog closing with a value, inline editing ending, the clear button; NOT per character) with a changed value, after that value has been written to the page’s state. Without one, a changed value simply goes out with whatever request the page fires next. Actions opening new windows are not allowed here.
- on_submit: Action | None = None¶
Fired when the user submits the field (return/enter while editing inline, or a text-entry dialog’s submit), after the value has been applied to the page’s state. For forms where typing and hitting return should do what the page’s main button does. Any action is allowed.
- padding_right: float = 0.0¶
Extra inset for the text box, which otherwise ends where the last button of a right-aligned row does.
- subtitle: LangStrSpec | int | None = None¶
- title: LangStrSpec | int | None = None¶
Section title shown above the row (with an optional subtitle), styled and placed exactly as a
ButtonRow’s.
- class bacommon.docui.v2.UnknownAction[source]¶
Bases:
ActionAction type we don’t recognize.
- classmethod get_type_id() ActionTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.docui.v2.UnknownDecoration[source]¶
Bases:
DecorationAn unknown decoration (should never reach a client in practice).
- classmethod get_type_id() DecorationTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.docui.v2.VAlign(*values)[source]¶
Bases:
EnumVertical alignment.
Fields of this type carry an
enum_fallback(CENTER), so a value added here later decodes as that on builds predating it instead of failing the whole response.- BOTTOM = 'b'¶
- CENTER = 'c'¶
- TOP = 't'¶
- class bacommon.docui.v2.WindowLayout(*values)[source]¶
Bases:
EnumThe overall shape of a doc-ui window.
Chosen by whatever opens the window (see
Browse.layout), since the window exists before its page arrives; pages replacing each other within a window share its layout. The client owns each layout’s actual geometry per ui-scale.- LARGE = 'l'¶
The standard full-size window.
- SMALL = 's'¶
A narrower, shorter window for simple list-style pages (settings and the like). At small ui-scale, where windows fill the screen, content is instead laid out in a centered column of limited width.
- SMALL_TALL = 'st'¶
A small layout’s width, with a height between a small and a small-taller layout’s. The same as a small layout at small ui-scale.
- SMALL_TALLER = 'str'¶
A small layout’s width, but taller; for long list-style pages (options pages and the like). The same as a small layout at small ui-scale.
- VIEWER = 'v'¶
A small layout’s column at the right of a full-size window, the rest to its left reserved for a viewer pane (a live character view, say).
- WIDE = 'w'¶
A squat window for horizontally laid out content designed to fill the screen elegantly (a row of big buttons, say). Its pages get the same width and height at every ui-scale – small ui-scale’s on the narrowest screen – so content sized to fit never scrolls and leaves little empty backing. Fills the screen at small ui-scale (full width, unlike a small layout).
- WIDER = 'wr'¶
A wide layout’s height, but wider at medium/large ui-scale; for content expected to be wider than the screen (a long row of items, say), where showing as much as possible means less scrolling. The same as a wide layout at small ui-scale.
- bacommon.docui.v2.all_rows(rows: list[Row]) Iterator[Row][source]¶
Yield rows depth-first: each row, and a section’s rows after it.
For code that visits every row wherever it sits (string and action walkers, validation). Sections don’t nest, but this simply recurses if one does.
- bacommon.docui.v2.is_control_row(row: Row) TypeIs[AnyControlRow][source]¶
Is this row one of the control-row types (
AnyControlRow)?Everything that lays control rows out alike keys off this rather than listing them; it narrows the type in both branches.
- bacommon.docui.v2.is_input_row(row: Row) TypeIs[AnyInputRow][source]¶
Is this row one of the input-row types (
AnyInputRow)?Everything concerned with the values rows hold keys off this rather than listing them; it narrows the type in both branches.
bacommon.docui.walk module¶
One traversal of a doc-ui page’s language-strings and asset refs.
Warning
This is an internal api and subject to change at any time. Do not use it in mod code.
Several things need to visit every string slot or every asset reference in a page: the client resolves the packages they name before rendering, the server rewrites them to their indexed wire forms, and so on. Each of those used to walk the page itself.
That went wrong the same way three times. Every walk matched
decorations with an isinstance chain and no final else, so a
decoration type a given walk had not been taught about contributed
nothing and the walk returned a plausible answer – silently short of
the truth. Adding a (since-retired) frame decoration missed three of
the four places that needed it.
So the traversal lives here once, and it dispatches on
DecorationTypeID with assert_never on
the end. A new decoration type is now a type error in a single file
rather than a silent omission in an unknown number of them.
Callbacks may return a replacement value (or None to leave a slot
alone), which is what lets one traversal serve both the read-only
consumers and the ones that rewrite in place.