Skip to main content

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>;