Handler API

本页用于查询 flor::view::handlerflor::view::builder::EventBuilder 的主要公开 API。使用教程见 外置事件

导入

use flor::view::builder::EventBuilder;
use flor::view::handler::*;
use flor::view::ViewId;

use flor::base::platform::{
    HandleResult, KeyCode, KeyState, MousePosition, ScrollAxis,
};

启用拖放或主题 feature 后,还会用到这些类型:

use flor::base::platform::{DragData, DragFormat, DropEffect};
use flor::base::platform::ThemeMode;

EventBuilder

EventBuilder 对所有 V: ViewIdentity 实现。所有方法都会保存 handler 并返回 Self,用于链式调用。普通控件、ViewBox、以及函数返回的 impl IntoView 都可以继续使用这些方法。

pub trait EventBuilder {
    fn on_mouse_move<Args>(self, handler: impl IntoEventHandler<OnMouseMoveHandler, Args>) -> Self;
    fn on_double_click<Args>(self, handler: impl IntoEventHandler<OnDoubleClickHandler, Args>) -> Self;
    fn on_click<Args>(self, handler: impl IntoEventHandler<OnClickHandler, Args>) -> Self;
    fn on_button_down<Args>(self, handler: impl IntoEventHandler<OnButtonDownHandler, Args>) -> Self;
    fn on_button_up<Args>(self, handler: impl IntoEventHandler<OnButtonUpHandler, Args>) -> Self;

    fn on_right_button_double_click<Args>(
        self,
        handler: impl IntoEventHandler<OnRightButtonDoubleClickHandler, Args>,
    ) -> Self;
    fn on_right_button_click<Args>(self, handler: impl IntoEventHandler<OnRightButtonClickHandler, Args>) -> Self;
    fn on_right_button_down<Args>(self, handler: impl IntoEventHandler<OnRightButtonDownHandler, Args>) -> Self;
    fn on_right_button_up<Args>(self, handler: impl IntoEventHandler<OnRightButtonUpHandler, Args>) -> Self;

    fn on_middle_button_double_click<Args>(
        self,
        handler: impl IntoEventHandler<OnMiddleButtonDoubleClickHandler, Args>,
    ) -> Self;
    fn on_middle_button_down<Args>(self, handler: impl IntoEventHandler<OnMiddleButtonDownHandler, Args>) -> Self;
    fn on_middle_button_up<Args>(self, handler: impl IntoEventHandler<OnMiddleButtonUpHandler, Args>) -> Self;

    fn on_context_menu<Args>(self, handler: impl IntoEventHandler<OnContextMenuHandler, Args>) -> Self;

    fn on_key_down<Args>(self, handler: impl IntoEventHandler<OnKeyDownHandler, Args>) -> Self;
    fn on_key_up<Args>(self, handler: impl IntoEventHandler<OnKeyUpHandler, Args>) -> Self;

    fn on_mouse_enter<Args>(self, handler: impl IntoEventHandler<OnMouseEnterHandler, Args>) -> Self;
    fn on_mouse_leave<Args>(self, handler: impl IntoEventHandler<OnMouseLeaveHandler, Args>) -> Self;
    fn on_focus<Args>(self, handler: impl IntoEventHandler<OnFocusHandler, Args>) -> Self;
    fn on_blur<Args>(self, handler: impl IntoEventHandler<OnBlurHandler, Args>) -> Self;
    fn on_create<Args>(self, handler: impl IntoEventHandler<OnCreateHandler, Args>) -> Self;
    fn on_destroy<Args>(self, handler: impl IntoEventHandler<OnDestroyHandler, Args>) -> Self;

    fn on_resize<Args>(self, handler: impl IntoEventHandler<OnResizeHandler, Args>) -> Self;
    fn on_close_requested<Args>(self, handler: impl IntoEventHandler<OnCloseRequestedHandler, Args>) -> Self;
    fn on_work_area_changed<Args>(self, handler: impl IntoEventHandler<OnWorkAreaChangedHandler, Args>) -> Self;
    fn on_wheel_settings_changed<Args>(
        self,
        handler: impl IntoEventHandler<OnWheelSettingsChangedHandler, Args>,
    ) -> Self;
    fn on_dpi_change<Args>(self, handler: impl IntoEventHandler<OnDpiChangeHandler, Args>) -> Self;

    #[cfg(feature = "theme-change")]
    fn on_theme_changed<Args>(self, handler: impl IntoEventHandler<OnThemeChangedHandler, Args>) -> Self;

    #[cfg(feature = "drag-drop")]
    fn on_drag_enter<Args>(self, handler: impl IntoEventHandler<OnDragEnterHandler, Args>) -> Self;
    #[cfg(feature = "drag-drop")]
    fn on_drag_over<Args>(self, handler: impl IntoEventHandler<OnDragOverHandler, Args>) -> Self;
    #[cfg(feature = "drag-drop")]
    fn on_drag_leave<Args>(self, handler: impl IntoEventHandler<OnDragLeaveHandler, Args>) -> Self;
    #[cfg(feature = "drag-drop")]
    fn on_drop<Args>(self, handler: impl IntoEventHandler<DropHandler, Args>) -> Self;
}

IntoEventHandler

IntoEventHandler<T, Args> 是事件 builder 接收 handler 的转换入口。它把闭包、普通函数、关联函数、方法项或已经确定泛型参数的泛型函数,转换成目标 handler 包装类型。

pub trait IntoEventHandler<T, Args> {
    fn into_event_handler(self) -> T;
}

转换分两层:

层级机制
完整参数handler 包装类型实现 From<F>IntoEventHandler<T, FullArgs> 再通过 F: Into<T> 调用这个 From 转换
简化参数IntoEventHandler<T, Args> 针对无参数、只接收 ViewId、省略 ViewId 等形态补齐被省略的参数

所以完整参数形态是 From 驱动的转换,事件 Builder 再用 IntoEventHandler<T, Args> 把不同参数形态统一到同一个入口。Args 是编译期标记,用来区分参数形态;调用 .on_click(...).on_key_down(...) 时通常由 Rust 自动推导,不需要手写。

例如 on_click 的底层类型是 MouseHandler,以下四种写法都可以转换成 OnClickHandler

view.on_click(|view_id, key_state, mouse_position| { /* 完整参数 */ });
view.on_click(|| { /* 不关心事件参数 */ });
view.on_click(|view_id| { /* 只关心控件 */ });
view.on_click(|key_state, mouse_position| { /* 省略 ViewId */ });

只有 ViewId 一个完整参数的 Handler 别名事件,例如 on_mouse_enteron_mouse_leaveon_createon_destroyon_resize,没有“省略 ViewId 后继续接收事件数据”的形态,因此只支持完整参数和无参数。

函数和方法项只要最终满足对应的 Fn(...) + Send + Sync + 'static 签名,也会参与同一套转换:

fn clicked(view_id: ViewId) {
    println!("{view_id}");
}

struct Actions;

impl Actions {
    fn open<const SLOT: usize>(view_id: ViewId) {
        println!("open {SLOT}: {view_id}");
    }
}

view.on_click(clicked);
view.on_click(Actions::open::<1>);

如果你要在自己的控件封装里继续接收并转发 handler,不要退回到 impl Into<OnClickHandler>。应保留 Args 泛型,这样调用方仍然可以使用完整参数、无参数、只接收 ViewId、省略 ViewId 这几种形态:

fn accept_click<Args>(handler: impl IntoEventHandler<OnClickHandler, Args>) -> OnClickHandler {
    handler.into_event_handler()
}

当前派发状态

API当前状态
on_mouse_move已派发。目标是捕获鼠标的控件或当前 hover 控件
on_mouse_enter / on_mouse_leave已派发。hover 目标变化时触发
on_button_down / on_button_up已派发。左键 down/up
on_click已派发。左键 down/up 命中同一控件时合成
on_double_click已派发。左键双击
on_right_button_down / on_right_button_up已派发。右键 down/up
on_right_button_click已派发。右键 down/up 命中同一控件时合成
on_right_button_double_click已派发。右键双击
on_middle_button_down / on_middle_button_up已派发。中键 down/up
on_middle_button_double_click已派发。中键双击
on_key_down / on_key_up已派发。目标是当前焦点控件
on_focus / on_blur已派发。由焦点管理器触发
on_create已派发。窗口创建控件树后触发
on_wheel_settings_changed已派发。当前鼠标滚轮消息会走这个 handler
on_drag_enter / on_drag_over / on_drag_leave / on_drop已派发,需要 drag-drop feature
on_context_menu有绑定槽位,当前源码没有外置派发入口
on_destroy有绑定槽位,当前源码没有外置派发入口
on_resize有绑定槽位,当前 Resize 只更新布局和渲染尺寸,没有调用外置 handler
on_close_requested有绑定槽位,当前关闭请求没有调用外置 handler
on_work_area_changed有绑定槽位,当前窗口总线实现为空
on_dpi_change有绑定槽位,当前 DPI 消息只更新渲染器、单位和布局,没有调用外置 handler
on_theme_changed有绑定槽位,需要 theme-change feature,当前窗口总线实现为空

ViewHandler

ViewHandler 是每个 ViewId 对应的一组 handler 槽位。应用代码通常通过 EventBuilder 写入这些槽位,不需要直接操作 ViewHandler

#[derive(Default)]
pub struct ViewHandler {
    pub on_mouse_move_handler: Option<OnMouseMoveHandler>,
    pub on_double_click_handler: Option<OnDoubleClickHandler>,
    pub on_click_handler: Option<OnClickHandler>,
    pub on_button_down_handler: Option<OnButtonDownHandler>,
    pub on_button_up_handler: Option<OnButtonUpHandler>,

    pub on_right_button_double_click_handler: Option<OnRightButtonDoubleClickHandler>,
    pub on_right_button_click_handler: Option<OnRightButtonClickHandler>,
    pub on_right_button_down_handler: Option<OnRightButtonDownHandler>,
    pub on_right_button_up_handler: Option<OnRightButtonUpHandler>,

    pub on_middle_button_double_click_handler: Option<OnMiddleButtonDoubleClickHandler>,
    pub on_middle_button_down_handler: Option<OnMiddleButtonDownHandler>,
    pub on_middle_button_up_handler: Option<OnMiddleButtonUpHandler>,

    pub on_context_menu_handler: Option<OnContextMenuHandler>,

    pub on_key_down_handler: Option<OnKeyDownHandler>,
    pub on_key_up_handler: Option<OnKeyUpHandler>,

    pub on_mouse_enter_handler: Option<OnMouseEnterHandler>,
    pub on_mouse_leave_handler: Option<OnMouseLeaveHandler>,
    pub on_focus_handler: Option<OnFocusHandler>,
    pub on_blur_handler: Option<OnBlurHandler>,
    pub on_create_handler: Option<OnCreateHandler>,
    pub on_destroy_handler: Option<OnDestroyHandler>,

    pub on_tooltip_show_handler: Option<OnTooltipShowHandler>,
    pub on_tooltip_hide_handler: Option<OnTooltipHideHandler>,

    pub on_resize_handler: Option<OnResizeHandler>,
    pub on_close_requested_handler: Option<OnCloseRequestedHandler>,
    pub on_work_area_changed_handler: Option<OnWorkAreaChangedHandler>,
    pub on_wheel_settings_changed_handler: Option<OnWheelSettingsChangedHandler>,
    pub on_dpi_change_handler: Option<OnDpiChangeHandler>,

    #[cfg(feature = "theme-change")]
    pub on_theme_changed_handler: Option<OnThemeChangedHandler>,

    #[cfg(feature = "drag-drop")]
    pub on_drag_enter_handler: Option<OnDragEnterHandler>,
    #[cfg(feature = "drag-drop")]
    pub on_drag_over_handler: Option<OnDragOverHandler>,
    #[cfg(feature = "drag-drop")]
    pub on_drag_leave_handler: Option<OnDragLeaveHandler>,
    #[cfg(feature = "drag-drop")]
    pub on_drop_handler: Option<DropHandler>,
}

Handler 包装类型

所有 handler 包装类型都实现了完整参数签名的 From<F>,其中 F 是对应签名的闭包或函数,并满足 Send + Sync + 'static。事件 builder 还通过 IntoEventHandler 支持若干简化参数形态,因此用户侧通常直接传闭包,不需要手动构造包装类型。

Handler

pub struct Handler(pub Arc<dyn Fn(ViewId) + Send + Sync + 'static>);

用于只需要 ViewId 的事件。

可接收:

形态示例
完整参数|view_id| { ... }
无参数|| { ... }

MouseHandler

pub struct MouseHandler(
    pub Arc<dyn Fn(ViewId, KeyState, MousePosition) + Send + Sync + 'static>,
);

用于鼠标移动、点击、按下、松开、双击等事件。

可接收:

形态示例
完整参数|view_id, key_state, mouse_position| { ... }
无参数|| { ... }
只接收 ViewId|view_id| { ... }
省略 ViewId|key_state, mouse_position| { ... }

KeyHandler

pub struct KeyHandler(
    pub Arc<
        dyn Fn(ViewId, KeyCode, bool, bool, bool) -> HandleResult
            + Send
            + Sync
            + 'static,
    >,
);

参数依次是 ViewIdKeyCodeis_altis_ctrlis_shift

可接收:

形态示例
完整参数|view_id, code, is_alt, is_ctrl, is_shift| -> HandleResult { ... }
无参数|| -> HandleResult { ... }
只接收 ViewId|view_id| -> HandleResult { ... }
省略 ViewId|code, is_alt, is_ctrl, is_shift| -> HandleResult { ... }

FocusHandler

pub struct FocusHandler(
    pub Arc<dyn Fn(ViewId, u16) + Send + Sync + 'static>,
);

第二个参数是虚拟焦点序号。

可接收:

形态示例
完整参数|view_id, focus_index| { ... }
无参数|| { ... }
只接收 ViewId|view_id| { ... }
省略 ViewId|focus_index| { ... }

OnWheelSettingsChangedHandler

pub struct OnWheelSettingsChangedHandler(
    pub Arc<
        dyn Fn(ViewId, ScrollAxis, f32, KeyState, MousePosition)
            + Send
            + Sync
            + 'static,
    >,
);

参数依次是 ViewId、滚动方向、滚动量、按键状态、鼠标位置。

可接收:

形态示例
完整参数|view_id, axis, delta, key_state, mouse_position| { ... }
无参数|| { ... }
只接收 ViewId|view_id| { ... }
省略 ViewId|axis, delta, key_state, mouse_position| { ... }

OnDpiChangeHandler

pub struct OnDpiChangeHandler(
    pub Arc<dyn Fn(ViewId, f32, f32) + Send + Sync + 'static>,
);

第二、第三个参数分别是 dpi_xdpi_y

可接收:

形态示例
完整参数|view_id, dpi_x, dpi_y| { ... }
无参数|| { ... }
只接收 ViewId|view_id| { ... }
省略 ViewId|dpi_x, dpi_y| { ... }

OnThemeChangedHandler

需要 theme-change feature。

pub struct OnThemeChangedHandler(
    pub Arc<dyn Fn(ViewId, ThemeMode) + Send + Sync + 'static>,
);

可接收:

形态示例
完整参数|view_id, theme_mode| { ... }
无参数|| { ... }
只接收 ViewId|view_id| { ... }
省略 ViewId|theme_mode| { ... }

DragEnterOverHandler

需要 drag-drop feature。

pub struct DragEnterOverHandler(
    pub Arc<
        dyn Fn(ViewId, KeyState, MousePosition, &[DragFormat], &mut DropEffect)
            + Send
            + Sync
            + 'static,
    >,
);

用于 on_drag_enteron_drag_over

可接收:

形态示例
完整参数|view_id, key_state, mouse_position, formats, effect| { ... }
无参数|| { ... }
只接收 ViewId|view_id| { ... }
省略 ViewId|key_state, mouse_position, formats, effect| { ... }

DropHandler

需要 drag-drop feature。

pub struct DropHandler(
    pub Arc<
        dyn Fn(ViewId, KeyState, MousePosition, &DragData, &mut DropEffect)
            + Send
            + Sync
            + 'static,
    >,
);

用于 on_drop

可接收:

形态示例
完整参数|view_id, key_state, mouse_position, data, effect| { ... }
无参数|| { ... }
只接收 ViewId|view_id| { ... }
省略 ViewId|key_state, mouse_position, data, effect| { ... }

类型别名

鼠标事件

别名底层类型
OnMouseMoveHandlerMouseHandler
OnDoubleClickHandlerMouseHandler
OnClickHandlerMouseHandler
OnButtonDownHandlerMouseHandler
OnButtonUpHandlerMouseHandler
OnRightButtonDoubleClickHandlerMouseHandler
OnRightButtonClickHandlerMouseHandler
OnRightButtonDownHandlerMouseHandler
OnRightButtonUpHandlerMouseHandler
OnMiddleButtonDoubleClickHandlerMouseHandler
OnMiddleButtonDownHandlerMouseHandler
OnMiddleButtonUpHandlerMouseHandler
OnContextMenuHandlerMouseHandler

当前没有 OnMiddleButtonClickHandler

键盘事件

别名底层类型
OnKeyDownHandlerKeyHandler
OnKeyUpHandlerKeyHandler

View 与生命周期事件

别名底层类型
OnMouseEnterHandlerHandler
OnMouseLeaveHandlerHandler
OnFocusHandlerFocusHandler
OnBlurHandlerFocusHandler
OnCreateHandlerHandler
OnDestroyHandlerHandler

Tooltip 事件

别名底层类型
OnTooltipShowHandlerMouseHandler
OnTooltipHideHandlerHandler

当前 EventBuilder 没有公开 tooltip 对应的链式绑定方法。

窗口相关事件

别名底层类型
OnResizeHandlerHandler
OnCloseRequestedHandlerHandler
OnWorkAreaChangedHandlerHandler
OnWheelSettingsChangedHandler独立包装类型
OnDpiChangeHandler独立包装类型
OnThemeChangedHandler独立包装类型,需要 theme-change feature

拖放事件

需要 drag-drop feature。

别名底层类型
OnDragEnterHandlerDragEnterOverHandler
OnDragOverHandlerDragEnterOverHandler
OnDragLeaveHandlerHandler
DropHandler独立包装类型

参数说明

类型说明
ViewId触发事件的目标控件 ID
KeyState鼠标按钮和修饰键状态
MousePosition鼠标坐标。常规鼠标命中事件是目标控件局部坐标;滚轮和拖放当前是窗口客户区坐标
KeyCode按键枚举。常见按键有字母、数字、方向键、功能键、EnterEscapeTabBackspaceSpaceDelete
HandleResult键盘事件处理结果,Handled 表示已处理,Default 表示走默认处理
ScrollAxisVerticalHorizontal
DropEffect拖放反馈效果,常用 NoneCopyMoveLink
DragFormat拖放进入/悬停阶段可用的数据格式
DragDatadrop 阶段真正传入的数据