Skip to main content

Theme

Struct Theme 

pub struct Theme {
Show 18 fields pub name: String, pub document: ThemeDocument, pub tokens: Tokens, pub border_standard: AlphaColor<Srgb>, pub border_focus: AlphaColor<Srgb>, pub text_primary: AlphaColor<Srgb>, pub text_dim: AlphaColor<Srgb>, pub text_tertiary: AlphaColor<Srgb>, pub status_success: AlphaColor<Srgb>, pub radius_standard: f64, pub padding_standard: f32, pub gap_standard: f32, pub reduce_motion: bool, pub reduce_transparency: bool, pub text_scale: f32, pub ui_scale: f32, pub caret_width: f64, pub forced_colors: bool,
}

Fields§

§name: String§document: ThemeDocument

The document this theme was built from, as applied: after the workspace temperature and high contrast.

§tokens: Tokens§border_standard: AlphaColor<Srgb>§border_focus: AlphaColor<Srgb>

The focus ring: the person’s own colour (crate::tokens::Intents::you).

§text_primary: AlphaColor<Srgb>§text_dim: AlphaColor<Srgb>

Second tier of the type hierarchy (captions, sub-labels).

§text_tertiary: AlphaColor<Srgb>

Quietest legible tier (timestamps, hints), below Theme::text_dim.

§status_success: AlphaColor<Srgb>§radius_standard: f64

The control radius (crate::tokens::Radii::control).

§padding_standard: f32§gap_standard: f32§reduce_motion: bool

Carried on the theme (not passed through draw) so every widget reacts without new plumbing. Default false.

§reduce_transparency: bool

Floating chrome draws its material opaque instead of over the blurred backdrop (crate::floating_surface::Material). Default false.

§text_scale: f32

1.0 = default. Baked into every Theme::text role by Theme::with_text_scale; kept here too so a widget can scale a size it computes itself.

§ui_scale: f32

The “make everything bigger” knob — spacing, radii, and type scale together, distinct from Theme::text_scale (type only). Baked in by Theme::with_ui_scale. Composes with the compositor’s per-output device scale: physical size = logical × ui_scale × device-scale, text additionally × text_scale.

§caret_width: f64

Width of an insertion caret in logical pixels. The configured theme folds in the accessibility preference once, keeping file I/O out of widget draw paths.

§forced_colors: bool

High contrast or forced colours is the active track. Content surfaces ask Theme::colors_are_forced instead of comparing Theme::name.

Implementations§

§

impl Theme

pub const ALL: [&'static str; 7]

Every theme Tilo ships, by the name Theme::named resolves.

Exists so a check can be run against all of them rather than against whichever two someone remembered.

pub fn from_document(document: &ThemeDocument) -> Option<Theme>

The theme a document describes, or None for one this build does not admit (ThemeDocument::validate). Values outside a role’s usable band are clamped, and a pairing that misses a contrast floor is repaired, so every theme that materializes is legible.

pub fn preset(preset: Preset) -> Theme

A shipped theme.

pub fn dark() -> Theme

The default: pure neutral dark.

pub fn light() -> Theme

The light theme.

pub fn high_contrast() -> Theme

Black ground under near-white ink, every text pairing at WCAG AAA. Selected when A11ySettings::high_contrast is set on a dark theme.

pub fn on_content(&self) -> OnSurface

Ink tiers on the content surface — the window ground every app paints on.

pub fn region(&self, region: Region) -> AlphaColor<Srgb>

The ground of region (HIG §9.2): surfaces.content, surfaces.sidebar or surfaces.inspector. The framework paints it (crate::surface::region); a caller reads it to measure against.

pub fn on_ground(&self, ground: AlphaColor<Srgb>) -> Theme

This theme as seen by a widget standing on ground: a region tier, a raised well, a document’s paper. surfaces.content becomes ground, the text tiers are re-measured against it (Self::on_surface) and the selection lift steps from it, so a widget that paints “ink on the window ground” or “the selected row” is right on whatever ground its container handed it. surfaces.raised stays off the ground (crate::tokens::Colors::raised_on), so a control’s face never sinks into a lighter panel. When ground has the other polarity from the palette (the near-black media.letterbox under a light theme), the inverted fill is re-derived too: primary ink on that ground as the fill and the ground as its label, so a Primary button over media still reads as the inverted control. Every other token is unchanged.

pub fn in_region(&self, region: Region) -> Theme

Self::on_ground for one of the window’s regions.

pub fn on_surface(&self, surface: AlphaColor<Srgb>) -> OnSurface

Self::on_content for any surface a widget actually paints on — a document’s paper, a tinted placeholder box, a chart panel. See crate::tokens::Colors::on_surface for why the surface is a parameter.

pub fn on_surface_at( &self, surface: AlphaColor<Srgb>, min_ratio: f64, ) -> OnSurface

Self::on_surface against a caller-chosen contrast floor.

pub fn window_edge(&self) -> AlphaColor<Srgb>

See crate::tokens::Colors::window_edge for why it’s derived from the desktop ground rather than a constant.

pub fn with_neutral_hue(self, hue: f32) -> Theme

The same theme in a workspace whose temperature is hue (OKLCH degrees). Only the neutral material’s hue moves — never its chroma, so a palette with chroma 0 (the default dark) shows no temperature at all, and the light palette, pure grey until now, takes its chroma at this hue. Presence, status, emphasis and the person’s own colour keep their hues, and every contrast promise holds at every hue. A workspace’s temperature comes from workspace_hue.

pub fn with_your_colour(self, hue: PresenceHue) -> Theme

The person’s own colour becomes their focus ring, text caret and text-selection tint, painted at this theme’s presence lightness and chroma. A colour is identity, not theme: the host that knows who sits here applies it (PresenceHue::chosen_in, PresenceHue::of_identity).

pub fn with_high_contrast(self) -> Theme

The same theme on the high-contrast palette of its polarity: shape, density, type and motion stay, the person keeps their colour, and content surfaces are asked to force their colours.

pub fn configured() -> Theme

Reads $XDG_CONFIG_HOME/tilo/settings.json (falling back to ~/.config/tilo/settings.json), the shared preference Settings and Theme Studio update through their respective domain stores. Unreadable, absent and unrecognised all mean the dark default — a machine with no preference and one whose settings file is corrupt both want a desktop that starts.

pub fn configured_from(settings: Option<&Path>) -> Theme

Theme::configured from an explicit settings file; None or an unreadable path yields the dark default.

pub fn from_settings_json(text: &str) -> Option<Theme>

The user’s theme in a settings document, if it names one this build admits. Automatic mode resolves against the local time now.

pub fn from_settings_json_at(text: &str, moment: LocalMoment) -> Option<Theme>

Self::from_settings_json at an explicit local moment: automatic mode is the light theme by day and the dark theme by night, on the schedule night light shares (settings_store::day_schedule).

pub fn automatic_schedule_from(settings: Option<&Path>) -> Option<Scheduled>

The day/night schedule an automatic appearance in settings follows, or None when the mode is fixed. Hosts keep it to notice sunrise and sunset, which change the theme without changing the file.

pub fn named(name: &str) -> Option<Theme>

A shipped theme by id or name, loosely (Preset::find), so the same lookup serves a picker, the persisted preference and the --shots theme override. None for an unknown name.

pub fn with_reduce_motion(self, on: bool) -> Theme

pub fn with_reduce_transparency(self, on: bool) -> Theme

pub fn with_text_scale(self, factor: f32) -> Theme

1.0 = unchanged. Multiplies the whole type scale and base body size together, so layout (which measures the same scaled sizes) grows to fit and nothing clips. Not assumed idempotent — call once on a fresh theme.

pub fn at_unit_text_scale(&self) -> Theme

This theme with the accessibility text scale taken back out: type at its 1× sizes (glyphs too), everything else unchanged. For content whose size is the document’s own (a slide’s text, laid out at the slide’s size and then scaled as a whole), which must not grow a second time with the reader’s text setting. Theme::with_text_scale multiplies, so it cannot undo a scale already applied.

pub fn with_ui_scale(self, factor: f32) -> Theme

1.0 = unchanged. Multiplies spacing, radii, and type together, distinct from Theme::with_text_scale which only resizes type. Not assumed idempotent — call once on a fresh theme.

pub fn text_growth(&self) -> f32

crate::tokens::Metrics::text_growth of this theme’s Theme::text_scale: how much a text-sized extent grows, never below 1.

pub fn responsive_scale(&self) -> f64

The one factor the responsive shells multiply an authored, text-sized breakpoint or pane width by: ui_scale × text_growth().

NavShell grows its metric widths by it, and a painted app’s SidebarDrawer its authored ones (breakpoint(760.0)), so at 200 % text a 760 px breakpoint pushes at 1520 px — the window that has the room a 760 px window has at 1× — without the app multiplying anything. 1.0 on a stock theme, so 1× geometry is untouched. A width sized by icons rather than text (a rail) follows Theme::ui_scale alone.

pub fn with_a11y( self, settings: &A11ySettings, text_scale: f32, ui_scale: f32, ) -> Theme

UI scale first so it grows the whole system, then text scale layers additional type growth on top. High contrast keeps the theme’s polarity, shape, density and type, and the person’s own colour.

§

impl Theme

pub fn in_window(self, appearance: &WindowAppearance) -> Theme

This theme as the window appearance describes sees it: the workspace’s temperature on the neutrals (nothing on a palette with chroma 0, nothing while there is no temperature) and the person’s colour as focus ring, caret and selection. Both are applied to the theme as configured, so a window moving to a neutral workspace loses the temperature of the one it left.

§

impl Theme

pub fn colors_are_forced(&self) -> bool

Whether accessibility is forcing colours onto content surfaces.

pub fn content_surface(&self) -> ContentSurface

Ask “am I forced?” and, when yes, paint the page from these tokens.

pub fn resolved_from_settings(text: &str) -> Theme

resolve_theme_layers for a settings document, including file scales and reduced motion. Theme::configured leaves scales and reduced motion to the host instead.

§

impl Theme

pub fn text(&self, role: TextRole) -> TextStyle

The resolved style of role in this theme: face, size, weight and leading, with the UI and text scale already applied. Measure and draw with the same value through crate::text_render::TextRenderer::measure_style and crate::text_render::TextRenderer::draw_style (or the crate::paint::PaintCtx role helpers).

Trait Implementations§

§

impl Clone for Theme

§

fn clone(&self) -> Theme

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Theme

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Theme

§

fn default() -> Theme

Returns the “default value” for a type. Read more
§

impl PartialEq for Theme

§

fn eq(&self, other: &Theme) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
§

impl StructuralPartialEq for Theme

Auto Trait Implementations§

§

impl Freeze for Theme

§

impl RefUnwindSafe for Theme

§

impl Send for Theme

§

impl Sync for Theme

§

impl Unpin for Theme

§

impl UnsafeUnpin for Theme

§

impl UnwindSafe for Theme

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> AnyEq for T
where T: Any + PartialEq,

§

fn equals(&self, other: &(dyn Any + 'static)) -> bool

§

fn as_any(&self) -> &(dyn Any + 'static)

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync> ⓘ

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> NoneValue for T
where T: Default,

§

type NoneType = T

§

fn null_value() -> T

The none-equivalent value.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

§

fn simd_from(_simd: S, value: T) -> T

§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

§

fn simd_into(self, simd: S) -> T

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>

§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> ErasedDestructor for T
where T: 'static,

§

impl<T> Fruit for T
where T: Send + Downcast,

§

impl<T> MaybeSendSync for T
where T: Send + Sync + ?Sized,

§

impl<T> WasmNotSend for T
where T: Send,

§

impl<T> WasmNotSendSync for T

§

impl<T> WasmNotSync for T
where T: Sync,