Druid Controller (2)

2022-10-26 20:15:12 浏览数 (3)

Controller 是一种管理子部件、重写或自定义其事件处理或更新行为的类型。Controller控制器只能处理事件和更新,不能影响布局和绘制。控制器是一种方便; 它可以做的任何事情也可以通过创建一个拥有子控件的自定义 Widget 来完成。但是,这有点麻烦,特别是当您只想拦截或修改一个或两个事件时。Controller 上的方法与 Widget 上的方法相同,只是它们也被传递给控制器的子方法。控制器负责根据需要显式地将调用转发到子级。Controller 与 ControllerHost 一起使用,后者管理它与其子节点之间的关系; 尽管通常您会使用 WidgetExt: : Controller 方法,而不是直接实例化主机。

Controller有3个需要实现的方法

代码语言:javascript复制
pub fn event(
    &mut self,
    child: &mut W,
    ctx: &mut EventCtx<'_, '_>,
    event: &Event,
    data: &mut T,
    env: &Env
)

pub fn lifecycle(
    &mut self,
    child: &mut W,
    ctx: &mut LifeCycleCtx<'_, '_>,
    event: &LifeCycle,
    data: &T,
    env: &Env
)
// 更新
pub fn update(
    &mut self,
    child: &mut W,
    ctx: &mut UpdateCtx<'_, '_>,
    old_data: &T,
    data: &T,
    env: &Env
)

1、我们先编写controller控制器 来看看

代码语言:javascript复制
struct TakeFocus;

impl <T, W: Widget<T>> Controller<T, W> for TakeFocus {
    //处理事件
    /*
    child:小部件
    EventCtx:事件etc
    Event:事件
    data:数据
    */
    fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
        //当窗口第一次实例化的时候接收到WindowConnectioned
        if let Event::WindowConnected = event {
            //让小部件获得焦点
            ctx.request_focus();
        }
        child.event(ctx, event, data, env)
    }
}

2、编写我们的ui,创建textBox并且让textBox使用controller控制器

代码语言:rust复制
#[derive(Data,Lens,Clone)]
struct AppState{
    text:String
}

fn builder_ui() -> impl Widget<AppState>{
    Flex::row()
        //给输入框添加controller控制器
        .with_child(TextBox::multiline().controller(TakeFocus).lens(AppState::text))
}
// 运行起来; 
fn main() {
    let win = WindowDesc::new(builder_ui()).window_size((200.,200.));

    let _app = AppLauncher::with_window(win).launch(AppState{text:"".to_string()});
}

0 人点赞