teksilo_core/styles/grid_view_style.rs
1// SPDX-License-Identifier: MPL-2.0
2// SPDX-FileCopyrightText: 2026 FernTech
3
4//! Tier-3 style protocol for `GridView`. See `docs/styling-system.md`.
5//!
6//! `GridView` renders its tiles through the app-supplied delegate, so the
7//! only widget-owned chrome is the paint-time decoration: the keyboard focus
8//! ring, the rubber-band marquee rectangle, the drag-reorder insertion bar,
9//! and the sticky pinned-header background. This trait exposes that chrome as
10//! plain recipe data (roles + dimensions) resolved against the active theme
11//! each frame — the same data-returning pattern as
12//! [`ListContainerStyle`](super::list_container_style::ListContainerStyle).
13
14use std::rc::Rc;
15
16use teksilo_tokens::{BorderRole, SurfaceRole};
17
18/// Focus-ring chrome: border role, stroke thickness, and inset from the tile
19/// edge (all in logical pixels).
20#[derive(Debug, Clone, Copy, PartialEq)]
21pub struct GridFocusRingRecipe {
22 pub role: BorderRole,
23 pub thickness: f32,
24 pub inset: f32,
25}
26
27impl Default for GridFocusRingRecipe {
28 fn default() -> Self {
29 Self {
30 role: BorderRole::Focused,
31 thickness: 1.5,
32 inset: 1.0,
33 }
34 }
35}
36
37/// Rubber-band marquee chrome: the accent role (used for both the
38/// translucent fill and the stroke), the fill alpha, and the stroke width.
39#[derive(Debug, Clone, Copy, PartialEq)]
40pub struct GridMarqueeRecipe {
41 pub role: BorderRole,
42 pub fill_alpha: f32,
43 pub stroke_width: f32,
44}
45
46impl Default for GridMarqueeRecipe {
47 fn default() -> Self {
48 Self {
49 role: BorderRole::Focused,
50 fill_alpha: 0.18,
51 stroke_width: 1.0,
52 }
53 }
54}
55
56/// Drag-reorder insertion-bar chrome: border role and bar thickness.
57#[derive(Debug, Clone, Copy, PartialEq)]
58pub struct GridInsertionRecipe {
59 pub role: BorderRole,
60 pub thickness: f32,
61}
62
63impl Default for GridInsertionRecipe {
64 fn default() -> Self {
65 Self {
66 role: BorderRole::Accent,
67 thickness: 2.0,
68 }
69 }
70}
71
72/// Tier-3 style protocol for [`GridView`](../../teksilo_widgets/grid_view).
73/// Every method has a default returning the stock recipe, so a custom style
74/// only overrides the decoration it cares about.
75pub trait GridViewStyle: 'static {
76 /// Focus-ring chrome painted around the keyboard-focused tile.
77 fn focus_ring(&self) -> GridFocusRingRecipe {
78 GridFocusRingRecipe::default()
79 }
80 /// Rubber-band marquee rectangle chrome.
81 fn marquee(&self) -> GridMarqueeRecipe {
82 GridMarqueeRecipe::default()
83 }
84 /// Drag-reorder insertion-bar chrome.
85 fn insertion(&self) -> GridInsertionRecipe {
86 GridInsertionRecipe::default()
87 }
88 /// Opaque background surface role for the sticky pinned section header.
89 fn pinned_header_surface(&self) -> SurfaceRole {
90 SurfaceRole::Raised
91 }
92}
93
94pub type SharedGridViewStyle = Rc<dyn GridViewStyle>;