Skip to main content

rustmotion_components/codeblock/
mod.rs

1mod chrome;
2mod diff;
3pub(crate) mod dimensions;
4pub(crate) mod highlight;
5mod render;
6mod reveal;
7
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use skia_safe::Canvas;
11
12use rustmotion_core::css::CssStyle;
13use rustmotion_core::engine::animator::AnimatedProperties;
14use rustmotion_core::engine::layout_pass::BoxLayout;
15use rustmotion_core::schema::{
16    CodeblockChrome, CodeblockHighlight, CodeblockReveal, CodeblockState, TimelineStep,
17};
18use rustmotion_core::traits::{PaintCtx, Painter, TimingConfig};
19
20#[derive(Debug, Serialize, Deserialize, JsonSchema)]
21pub struct Codeblock {
22    pub code: String,
23    #[serde(default = "default_language")]
24    pub language: String,
25    #[serde(default = "default_theme")]
26    pub theme: String,
27    #[serde(default)]
28    pub show_line_numbers: bool,
29    #[serde(default)]
30    pub chrome: Option<CodeblockChrome>,
31    #[serde(default)]
32    pub highlights: Vec<CodeblockHighlight>,
33    #[serde(default)]
34    pub reveal: Option<CodeblockReveal>,
35    #[serde(default)]
36    pub states: Vec<CodeblockState>,
37    /// Enable diff mode: lines starting with `+` get green background, `-` get red background.
38    #[serde(default)]
39    pub diff: bool,
40    /// When the rendered content overflows the box vertically, scroll up so the
41    /// last revealed line stays visible. Default: `true`. Set to `false` to
42    /// require that all content fits — the geometry validator will fail
43    /// otherwise. Font size is never reduced.
44    #[serde(default = "default_auto_scroll")]
45    pub auto_scroll: bool,
46    #[serde(flatten)]
47    pub timing: TimingConfig,
48    #[serde(default)]
49    pub style: CssStyle,
50    #[serde(default)]
51    pub timeline: Vec<TimelineStep>,
52    #[serde(default)]
53    pub stagger: Option<f32>,
54}
55
56fn default_auto_scroll() -> bool {
57    true
58}
59
60rustmotion_core::impl_traits!(Codeblock {
61    Animatable => animation,
62    Timed => timing,
63    Styled => style,
64});
65
66impl Painter for Codeblock {
67    fn paint_content(
68        &self,
69        canvas: &Canvas,
70        layout: &BoxLayout,
71        props: &AnimatedProperties,
72        ctx: &PaintCtx,
73    ) {
74        render::render_codeblock(canvas, self, layout, props, ctx);
75    }
76}
77
78fn default_language() -> String {
79    "plain".to_string()
80}
81fn default_theme() -> String {
82    "base16-ocean.dark".to_string()
83}