builtins.gdw raw

; The framework's builtin widgets, declared in the same `.gdw` grammar an
; application uses for its own Rust widgets. There is no privileged description:
; a `container` and a `markdown` are one kind of thing to the compiler, a
; `WidgetDescriptor` resolved by name, and this file is parsed into those
; descriptors exactly as an app's manifest is.
;
; The Rust implementations live in guiduck-core; the type paths below are
; carried verbatim and resolved by rustc against the generated factories, never
; by this compiler. `register_builtins!` reads these descriptors and submits one
; link-time registration per widget, the same submission `register_widget!`
; emits for an app widget.
;
; The order is the vocabulary order a "did you mean" diagnostic lists, and
; nothing else.

(widget container
  (type "::guiduck::core::Container")
  (prop background Brush)
  (prop corner-radius f64)
  (token background Brush)
  (token corner-radius Number))

(widget text
  (type "::guiduck::core::Text")
  (prop text RichText)
  (prop font-size f32)
  (prop font-family String :setter set_family)
  ; `set_brush`, not `set_color`: the value is a `Brush`, which may be a
  ; gradient, so `color` would be a narrowing lie. The token and the property
  ; are `color` because that is what a reader means.
  (prop color Brush :setter set_brush)
  (event on-link :builtin)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token link-color Brush)
  (token link-underline-width Number)
  (token selection-color Brush))

(widget text-input
  (type "::guiduck::core::TextInput")
  ; `set_content`, not `set_text`: this widget distinguishes the committed
  ; buffer from what is on screen mid-IME, and that pair is why the word is
  ; `content`.
  (prop text String :setter set_content)
  (prop font-size f32)
  (prop font-family String :setter set_family)
  (prop multiline bool)
  (event on-change :builtin)
  ; The focused border is `(text-input :focus) :border-color …`, not a token of
  ; its own: the state selector is how a theme says "while focused".
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token background Brush)
  (token border-color Brush)
  (token border-width Number)
  (token caret-color Brush)
  (token selection-color Brush)
  (token corner-radius Number))

(widget scroll-area
  (type "::guiduck::core::ScrollArea")
  ; The axis is a property, not a kind of scroll area. It was a constructor by
  ; accident.
  (prop axis ScrollAxes)
  ; The position, as app state. Controlled like every other value here: the
  ; application sets it (a handler scrolling to the top of a page it just
  ; navigated to), the reader moving the view reports through `:on-scroll`,
  ; and a programmatic set is silent so the two cannot echo.
  (prop offset-x f64 :setter set_offset_x)
  (prop offset-y f64 :setter set_offset_y)
  (event on-scroll :builtin)
  (token thumb-color Brush)
  (token thumb-corner-radius Number))

(widget button
  (type "::guiduck::core::Button")
  (prop label String)
  (prop font-size f32)
  (prop font-family String :setter set_family)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token background Brush)
  (token corner-radius Number)
  (token focus-ring-color Brush)
  (token focus-ring-width Number))

(widget checkbox
  (type "::guiduck::core::Checkbox")
  (prop checked bool)
  (prop label String)
  (prop font-size f32)
  (prop font-family String :setter set_family)
  (event on-toggle :builtin)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token box-fill Brush)
  (token box-fill-checked Brush)
  (token box-border-color Brush)
  (token box-border-color-checked Brush)
  (token box-border-width Number)
  (token box-corner-radius Number)
  (token check-mark Graphic)
  (token check-color Brush)
  (token check-width Number)
  (token focus-ring-color Brush)
  (token focus-ring-width Number))

; A radio button. Its own widget rather than a themed checkbox because two
; things a theme cannot reach differ: assistive technology is told which it is,
; and choosing the already-chosen one is not a change, so it reports nothing.
; It holds no group — mutual exclusion is a fact about the app's data, so
; `:checked` binds to a comparison and the wire carries identity.
(widget radio
  (type "::guiduck::core::Radio")
  (prop checked bool)
  (prop label String)
  (prop font-size f32)
  (prop font-family String :setter set_family)
  (event on-select :builtin)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token box-fill Brush)
  (token box-fill-checked Brush)
  (token box-border-color Brush)
  (token box-border-color-checked Brush)
  (token box-border-width Number)
  (token box-corner-radius Number)
  (token check-mark Graphic)
  (token check-color Brush)
  (token check-width Number)
  (token focus-ring-color Brush)
  (token focus-ring-width Number))

; A switch. Its own widget for the reason a radio is: assistive technology is
; told which control it is. Behaviourally a checkbox — a switch flips both
; ways — so it reports `on-toggle` like one.
(widget switch
  (type "::guiduck::core::Switch")
  (prop checked bool)
  (prop label String)
  (prop font-size f32)
  (prop font-family String :setter set_family)
  (event on-toggle :builtin)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token box-fill Brush)
  (token box-fill-checked Brush)
  (token box-border-color Brush)
  (token box-border-color-checked Brush)
  (token box-border-width Number)
  (token box-corner-radius Number)
  (token check-mark Graphic)
  (token check-color Brush)
  (token check-width Number)
  (token focus-ring-color Brush)
  (token focus-ring-width Number))

; A rule between things. Its thickness is the theme's and its length the
; layout's, so the same widget is a horizontal line in a column and a vertical
; one in a row. `menu-separator` is this idea confined to a menu.
(widget separator
  (type "::guiduck::core::Separator")
  (token color Brush)
  (token thickness Number))

; How far along something is. `:value` is a fraction from 0 to 1, clamped.
(widget progress
  (type "::guiduck::core::Progress")
  (prop value f64)
  (token track-color Brush)
  (token fill-color Brush)
  (token corner-radius Number)
  (token thickness Number))

; A slider. `:value` is a fraction from 0 to 1 and the app scales it: a slider
; carrying its own minimum, maximum and step would be doing arithmetic the app
; already does, in units this compiler cannot check.
(widget slider
  (type "::guiduck::core::Slider")
  (prop value f64)
  (event on-value-change :builtin)
  (token track-color Brush)
  (token fill-color Brush)
  (token thumb-color Brush)
  (token thumb-size Number)
  (token thickness Number)
  (token corner-radius Number)
  (token focus-ring-color Brush)
  (token focus-ring-width Number))

; A stepper: a number you nudge. Unlike a slider it carries a real range,
; because the number it shows is the number the app means — there is nothing to
; scale.
(widget stepper
  (type "::guiduck::core::Stepper")
  (prop value f64)
  (prop min f64)
  (prop max f64)
  (prop step f64)
  (prop font-size f32)
  (prop font-family String :setter set_family)
  (event on-value-change :builtin)
  (token background Brush)
  (token color Brush)
  (token border-color Brush)
  (token border-width Number)
  (token corner-radius Number)
  (token button-color Brush)
  (token focus-ring-color Brush)
  (token focus-ring-width Number))

; One tab in a strip. The same species as a radio: one of a set, chosen rather
; than toggled, with mutual exclusion a fact about the app's data.
(widget tab
  (type "::guiduck::core::Tab")
  (prop selected bool)
  (prop label String)
  (prop font-size f32)
  (prop font-family String :setter set_family)
  (event on-select :builtin)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token box-fill Brush)
  (token box-fill-checked Brush)
  (token box-border-color Brush)
  (token box-border-color-checked Brush)
  (token box-border-width Number)
  (token box-corner-radius Number)
  (token check-mark Graphic)
  (token check-color Brush)
  (token check-width Number)
  (token focus-ring-color Brush)
  (token focus-ring-width Number))

; The strip a set of tabs sits in. It holds no selection; what it adds is that
; assistive technology is told these are tabs.
(widget tab-list
  (type "::guiduck::core::TabList")
  (token background Brush)
  (token corner-radius Number))

; A list. Like a tab strip it holds nothing — selection reaches each row
; through its own `:selected` binding.
(widget list
  (type "::guiduck::core::ListBox")
  (token background Brush)
  (token corner-radius Number))

(widget list-item
  (type "::guiduck::core::ListItem")
  (parents list)
  (prop selected bool)
  (prop label String)
  (prop font-size f32)
  (prop font-family String :setter set_family)
  (event on-select :builtin)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token box-fill Brush)
  (token box-fill-checked Brush)
  (token box-border-color Brush)
  (token box-border-color-checked Brush)
  (token box-border-width Number)
  (token box-corner-radius Number)
  (token check-mark Graphic)
  (token check-color Brush)
  (token check-width Number)
  (token focus-ring-color Brush)
  (token focus-ring-width Number))

; A titled row that shows or hides what is under it. Controlled like a dialog's
; `:open`: it *asks* (`:on-toggle`) and the app's binding answers, which is what
; makes an accordion expressible without an accordion widget.
(widget expander
  (type "::guiduck::core::Expander")
  (prop open bool)
  (prop title String)
  (event on-toggle :builtin)
  (token background Brush)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token corner-radius Number)
  (token expand-mark Graphic)
  (token expand-color Brush)
  (token focus-ring-color Brush)
  (token focus-ring-width Number))

(widget image
  (type "::guiduck::core::Image")
  (prop source Graphic)
  (prop alt String)
  ; A raster source carries its own pixels, but a `(path …)` source is bare
  ; geometry, so the theme says what color to fill it with.
  (token color Brush))

(widget menu-bar
  (type "::guiduck::core::MenuBar")
  (token background Brush))

(widget menu
  (type "::guiduck::core::Menu")
  (parents menu-bar menu context-menu dropdown combo-box)
  (prop label String)
  ; A `menu` is the title row; the popup it opens is a `menu-panel`, styled
  ; separately. A row's `-highlighted` variants are token variants, not a
  ; `:highlighted` state selector, because being the current row is the
  ; widget's own state.
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token background Brush)
  (token background-highlighted Brush)
  (token color-highlighted Brush)
  (token corner-radius Number)
  (token accel-color Brush)
  (token submenu-mark Graphic))

(widget menu-item
  (type "::guiduck::core::MenuItem")
  (parents menu context-menu dropdown combo-box)
  (prop label String)
  ; `set_accel_text`, not `set_accel`: an accelerator is a rendered string
  ; *and* a keystroke the tree registers, and this method is only the first
  ; half.
  (accel :setter set_accel_text)
  (event on-select :builtin)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token background Brush)
  (token background-highlighted Brush)
  (token color-highlighted Brush)
  (token corner-radius Number)
  (token accel-color Brush)
  (token submenu-mark Graphic))

(widget menu-separator
  (type "::guiduck::core::MenuSeparator")
  (parents menu context-menu dropdown combo-box)
  (token color Brush)
  (token thickness Number))

; A context menu is never drawn: it is an attachment point, and the panel it
; opens is a `menu-panel` like any other.
(widget context-menu
  (type "::guiduck::core::ContextMenu"))

(widget dropdown
  (type "::guiduck::core::Dropdown")
  ; The chosen option's text. The app computes it from its own data: `for` is
  ; the model, so nothing here holds a list.
  (prop label String)
  (prop font-size f32)
  (prop font-family String :setter set_family)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token background Brush)
  (token border-color Brush)
  (token border-width Number)
  (token corner-radius Number)
  (token focus-ring-color Brush)
  (token focus-ring-width Number)
  (token arrow-mark Graphic)
  (token arrow-color Brush))

; A combo box: a field you can type in that also opens a list. Its rows are
; ordinary deferred content, so the candidates are a `for` over app state —
; filtering is the app's, because the text it filters on is already delivered
; by `:on-change`.
(widget combo-box
  (type "::guiduck::core::ComboBox")
  (prop text String)
  (prop font-size f32)
  (prop font-family String :setter set_family)
  (event on-change :builtin)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token background Brush)
  (token border-color Brush)
  (token border-width Number)
  (token caret-color Brush)
  (token selection-color Brush)
  (token corner-radius Number))

(widget dialog
  (type "::guiduck::core::Dialog")
  (prop open bool)
  (prop title String)
  (event on-close :builtin)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token background Brush)
  (token border-color Brush)
  (token border-width Number)
  (token corner-radius Number)
  ; The sheet dimming whatever is behind it.
  (token scrim-color Brush))

; A tooltip's panel: a parent builds it on hover, so `(internal)`.
(widget tooltip
  (type "::guiduck::core::TooltipPanel")
  (internal)
  (token color Brush)
  (token font-size Number)
  (token font-family Str)
  (token background Brush)
  (token border-color Brush)
  (token border-width Number)
  (token corner-radius Number))

; The popup a menu, context menu, or dropdown opens. A parent builds it; no
; file writes one, so it is `(internal)`.
(widget menu-panel
  (type "::guiduck::core::MenuPanel")
  (internal)
  (token background Brush)
  (token border-color Brush)
  (token border-width Number)
  (token corner-radius Number))