# Decks

> Deck::new(theme, slides) makes one fframes Scene per slide, named by the slide's key, so frame agenda@end on the command line finds it.

Page: https://fframes-kit.pages.dev/docs/slides/decks/

`Deck::new(theme, slides)` makes one fframes `Scene` per slide, named by the slide's key, so
`frame agenda@end` on the command line finds it. Give the video `Duration::Auto`, return
`deck.scenes()` from `define_scenes` and draw them with `ctx.render_scenes(&frame)`.

Between two slides the deck plays a `Fade` of the theme's `motion.duration.base` (0.4 s).
`.transition(presentation, timing)` takes any presentation of the transitions (`Slide`,
`Wipe`, `Iris`, ...), `.no_transition()` cuts. With a transition each slide starts that
long before the previous one ends (`Overlap::Previous`): its own time starts with the
transition, so it builds in while it comes in, and the slide before it holds under it.
`transition_seconds()` gives the length.

`deck.slides()` gives the slides in play order, for their keys, `seconds()`,
`reveal_times()` and `notes()`.

```rust
use fframes_kit::prelude::*;

#[derive(Debug)]
struct Talk {
    deck: Deck<'static>,
}

impl Talk {
    fn new() -> Self {
        let deck = Deck::new(
            Theme::default(),
            vec![
                slides::Slide::new(
                    "intro",
                    SlideLayout::Title { title: "Decks in fframes", subtitle: Some("A short talk") },
                ),
                slides::Slide::new("why", SlideLayout::bullets("Why", vec!["One file", "Real video"])),
                slides::Slide::new(
                    "end",
                    SlideLayout::Quote { text: "Thank you", author: None },
                ),
            ],
        )
        .transition(Wipe::default(), Timing::default());
        Self { deck }
    }
}

impl Video for Talk {
    const FPS: usize = 30;
    const WIDTH: usize = 1920;
    const HEIGHT: usize = 1080;

    fn duration(&self) -> Duration<'_> {
        Duration::Auto
    }

    fn audio(&self) -> AudioMap<'_> {
        AudioMap::none()
    }

    fn define_scenes(&self) -> Scenes<'_> {
        self.deck.scenes()
    }

    fn render_frame<'a>(&'a self, frame: Frame, ctx: &FFramesContext<'a, '_>) -> Svgr<'a> {
        svgr!(
            <svg viewBox="0 0 1920 1080" width={Self::WIDTH} height={Self::HEIGHT}>
                {ctx.render_scenes(&frame)}
            </svg>
        )
    }
}

let talk = Talk::new();
let keys: Vec<&str> = talk.deck.slides().map(|s| s.key).collect();
assert_eq!(keys, ["intro", "why", "end"]);
assert_eq!(talk.deck.transition_seconds(), 0.8);
```

### Editable slide text

With the kit's `studio` feature the text of the slides is editable in fframes Studio's
Props panel: `deck.with_props(state, view)` gives every slide's `Ui` the props source
`view` makes of `state` for the slide's scene. The editable objects are `SlideText`s keyed
`title`, `subtitle`, `item-1`, `item-2`, ..., `left`, `right`, `step-1`, `step-2`, ...,
`caption`, `quote`,
`author`, `bar-1`, `bar-2`, ..., `stat-1-value`, `stat-1-label`, ..., `event-1-date`, `event-1-text`, ..., each
with its `text` and `fill`. A figure edited in Studio no longer counts up. Edited text fits the same box as the code's.
The example uses fframes Studio's `PropsStore`, which is not a dependency of the kit:

```rust title="Not compiled"
let store = Arc::new(PropsStore::default());
let deck = Deck::new(theme, slides)
    .with_props(store.clone(), |store, scene| Box::new(store.scene_view(scene)));
```
