2个版本 (1个稳定版)
1.0.0 | 2023年3月22日 |
---|---|
0.2.0 | 2022年9月29日 |
#1097 in 音频
255KB
2K SLoC
audio-processor-iced-storybook
这是一个为Iced编写的“storybook”风格库的非常简单的草案。
它与"React的Storybook"在精神上相似。
目前它只是
- 显示带有故事名称的侧边栏
- 点击时在内容视图中显示故事
用法
故事使用builder
函数配置。它们可以通过两种方式之一进行注册。
第一种方式是将故事声明为story_fn
,它仅用于渲染无状态元素
use iced::{Text, Length, Container};
use audio_processor_iced_storybook as storybook;
type Message = ();
fn main() {
storybook::builder::<Message>()
.story_fn("Hello world", || {
Container::new(Text::new("Hey!"))
.padding(50)
.center_x()
.center_y()
.height(Length::Fill)
.width(Length::Fill)
.into()
})
.run()
.unwrap();
}
storybook::builder
将子消息类型作为类型参数。要求此类型符合'static + Clone + Debug
。
故事可以有不同类型的Message
,只要它们可以通过From
转换为根类型。
注册故事的第二种方式如下
您有一个my_view
模块,它声明了一个按钮视图
mod my_view {
use iced::*;
// This view has the state of the button
pub struct MyView {
button_state: iced::button::State,
}
// This view fires a `Message::ButtonClicked` message
#[derive(Clone, Debug)]
pub enum Message {
ButtonClicked,
}
impl MyView {
pub fn new() -> Self {
Self {
button_state: iced::button::State::default(),
}
}
pub fn view(&mut self) -> Element<Message> {
Button::new(&mut self.button_state, Text::new("Hello world"))
.on_press(Message::ButtonClicked)
.into()
}
}
// You will declare a `story` module, which may be conditionally compiled on your set-up
pub mod story {
use audio_processor_iced_storybook::StoryView;
use super::*;
// You will declare some helper types
struct Story(MyView);
pub fn default() -> Story {
Story::default()
}
// You will implement the `StoryView` trait for your story. This will be parameterized over the `Message` type,
// however it doesn't have to be a global type, as long as the root type is convertible to/from this.
impl StoryView<Message> for Story {
// You may implement an update function for your story
fn update(&mut self, _message: Message) -> Command<Message> { Command::none() }
// You will implement the view function
fn view(&mut self) -> Element<Message> {
self.0.view()
}
}
}
}
// In order to have different message types, you'll implement a "super-type" for Message, which derives `From` and
// `TryInto`
use derive_more::{From, TryInto}; // <- You need this to derive `From`/`TryInto` automatically for the child message
#[derive(Debug, From, Clone, TryInto)]
enum Message {
MyView(my_view::Message),
None(()) // <- Adding a `None(())` will let you continue using stateless stories as well.
}
// examples/stories.rs
fn main() {
audio_processor_iced_storybook::builder::<Message>()
// You will register the story with `story` rather than `story_fn`.
.story("MyView - default", my_view::story::default())
.run()
.unwrap();
}
更详细的示例,请参见crates/plugin-host-gui2
。
许可证:MIT
依赖关系
~18–35MB
~624K SLoC