pub fn event(&mut self, port: &mut Viewport, ctx: &mut EventCtx, event: &Event, env: &Env) {
        let viewport_size = port.view_size;
        let content_size = port.content_size;
        let scroll_offset = port.view_origin.to_vec2();

        let scrollbar_is_hovered = match event {
            Event::MouseMove(e) | Event::MouseUp(e) | Event::MouseDown(e) => {
                let offset_pos = e.pos + scroll_offset;
                self.point_hits_vertical_bar(port, offset_pos, env)
                    || self.point_hits_horizontal_bar(port, offset_pos, env)
            }
            _ => false,
        };

        if self.are_bars_held() {
            // if we're dragging a scrollbar
            match event {
                Event::MouseMove(event) => {
                    match self.held {
                        BarHeldState::Vertical(offset) => {
                            let scale_y = viewport_size.height / content_size.height;
                            let bounds = self
                                .calc_vertical_bar_bounds(port, env)
                                .unwrap_or(Rect::ZERO);
                            let mouse_y = event.pos.y + scroll_offset.y;
                            let delta = mouse_y - bounds.y0 - offset;
                            port.pan_by(Vec2::new(0f64, (delta / scale_y).ceil()));
                            ctx.set_handled();
                        }
                        BarHeldState::Horizontal(offset) => {
                            let scale_x = viewport_size.width / content_size.width;
                            let bounds = self
                                .calc_horizontal_bar_bounds(port, env)
                                .unwrap_or(Rect::ZERO);
                            let mouse_x = event.pos.x + scroll_offset.x;
                            let delta = mouse_x - bounds.x0 - offset;
                            port.pan_by(Vec2::new((delta / scale_x).ceil(), 0f64));
                            ctx.set_handled();
                        }
                        _ => (),
                    }
                    ctx.request_paint();
                }
                Event::MouseUp(_) => {
                    self.held = BarHeldState::None;
                    ctx.set_active(false);

                    if !scrollbar_is_hovered {
                        self.hovered = BarHoveredState::None;
                        self.reset_scrollbar_fade(|d| ctx.request_timer(d), env);
                    }

                    ctx.set_handled();
                }
                _ => (), // other events are a noop
            }
        } else if scrollbar_is_hovered {
            // if we're over a scrollbar but not dragging
            match event {
                Event::MouseMove(event) => {
                    let offset_pos = event.pos + scroll_offset;
                    if self.point_hits_vertical_bar(port, offset_pos, env) {
                        self.hovered = BarHoveredState::Vertical;
                    } else if self.point_hits_horizontal_bar(port, offset_pos, env) {
                        self.hovered = BarHoveredState::Horizontal;
                    } else {
                        unreachable!();
                    }

                    self.opacity = env.get(theme::SCROLLBAR_MAX_OPACITY);
                    self.timer_id = TimerToken::INVALID; // Cancel any fade out in progress
                    ctx.request_paint();
                    ctx.set_handled();
                }
                Event::MouseDown(event) => {
                    let pos = event.pos + scroll_offset;

                    if self.point_hits_vertical_bar(port, pos, env) {
                        ctx.set_active(true);
                        self.held = BarHeldState::Vertical(
                            // The bounds must be non-empty, because the point hits the scrollbar.
                            pos.y - self.calc_vertical_bar_bounds(port, env).unwrap().y0,
                        );
                    } else if self.point_hits_horizontal_bar(port, pos, env) {
                        ctx.set_active(true);
                        self.held = BarHeldState::Horizontal(
                            // The bounds must be non-empty, because the point hits the scrollbar.
                            pos.x - self.calc_horizontal_bar_bounds(port, env).unwrap().x0,
                        );
                    } else {
                        unreachable!();
                    }

                    ctx.set_handled();
                }
                // if the mouse was downed elsewhere, moved over a scroll bar and released: noop.
                Event::MouseUp(_) => (),
                _ => unreachable!(),
            }
        } else {
            match event {
                Event::MouseMove(_) => {
                    // if we have just stopped hovering
                    if self.hovered.is_hovered() && !scrollbar_is_hovered {
                        self.hovered = BarHoveredState::None;
                        self.reset_scrollbar_fade(|d| ctx.request_timer(d), env);
                    }
                }
                Event::Timer(id) if *id == self.timer_id => {
                    // Schedule scroll bars animation
                    ctx.request_anim_frame();
                    self.timer_id = TimerToken::INVALID;
                    ctx.set_handled();
                }
                Event::AnimFrame(interval) => {
                    // Guard by the timer id being invalid, otherwise the scroll bars would fade
                    // immediately if some other widget started animating.
                    if self.timer_id == TimerToken::INVALID {
                        // Animate scroll bars opacity
                        let diff = 2.0 * (*interval as f64) * 1e-9;
                        self.opacity -= diff;
                        if self.opacity > 0.0 {
                            ctx.request_anim_frame();
                        }

                        if let Some(bounds) = self.calc_horizontal_bar_bounds(port, env) {
                            ctx.request_paint_rect(bounds - scroll_offset);
                        }
                        if let Some(bounds) = self.calc_vertical_bar_bounds(port, env) {
                            ctx.request_paint_rect(bounds - scroll_offset);
                        }
                    }
                }

                _ => (),
            }
        }
    }
/// Checks if the event applies to the scroll behavior, uses it, and marks it handled
///
/// Make sure to call on every event
Checks if the event applies to the scroll behavior, uses it, and marks it handled
Make sure to call on every event
Checks if the event applies to the scroll behavior uses it and marks it handled Make sure to call on every event
pub fn event(&mut self, port: &mut Viewport, ctx: &mut EventCtx, event: &Event, env: &Env) {
        let viewport_size = port.view_size;
        let content_size = port.content_size;
        let scroll_offset = port.view_origin.to_vec2();
        let scrollbar_is_hovered = match event {
            Event::MouseMove(e) | Event::MouseUp(e) | Event::MouseDown(e) => {
                let offset_pos = e.pos + scroll_offset;
                self.point_hits_vertical_bar(port, offset_pos, env)
                    || self.point_hits_horizontal_bar(port, offset_pos, env)
            }
            _ => false,
        };
        if self.are_bars_held() {
            // if we're dragging a scrollbar
            match event {
                Event::MouseMove(event) => {
                    match self.held {
                        BarHeldState::Vertical(offset) => {
                            let scale_y = viewport_size.height / content_size.height;
                            let bounds = self
                                .calc_vertical_bar_bounds(port, env)
                                .unwrap_or(Rect::ZERO);
                            let mouse_y = event.pos.y + scroll_offset.y;
                            let delta = mouse_y - bounds.y0 - offset;
                            port.pan_by(Vec2::new(0f64, (delta / scale_y).ceil()));
                            ctx.set_handled();
                        }
                        BarHeldState::Horizontal(offset) => {
                            let scale_x = viewport_size.width / content_size.width;
                            let bounds = self
                                .calc_horizontal_bar_bounds(port, env)
                                .unwrap_or(Rect::ZERO);
                            let mouse_x = event.pos.x + scroll_offset.x;
                            let delta = mouse_x - bounds.x0 - offset;
                            port.pan_by(Vec2::new((delta / scale_x).ceil(), 0f64));
                            ctx.set_handled();
                        }
                        _ => (),
                    }
                    ctx.request_paint();
                }
                Event::MouseUp(_) => {
                    self.held = BarHeldState::None;
                    ctx.set_active(false);
                    if !scrollbar_is_hovered {
                        self.hovered = BarHoveredState::None;
                        self.reset_scrollbar_fade(|d| ctx.request_timer(d), env);
                    }
                    ctx.set_handled();
                }
                _ => (), // other events are a noop
            }
        } else if scrollbar_is_hovered {
            // if we're over a scrollbar but not dragging
            match event {
                Event::MouseMove(event) => {
                    let offset_pos = event.pos + scroll_offset;
                    if self.point_hits_vertical_bar(port, offset_pos, env) {
                        self.hovered = BarHoveredState::Vertical;
                    } else if self.point_hits_horizontal_bar(port, offset_pos, env) {
                        self.hovered = BarHoveredState::Horizontal;
                    } else {
                        unreachable!();
                    }
                    self.opacity = env.get(theme::SCROLLBAR_MAX_OPACITY);
                    self.timer_id = TimerToken::INVALID; // Cancel any fade out in progress
                    ctx.request_paint();
                    ctx.set_handled();
                }
                Event::MouseDown(event) => {
                    let pos = event.pos + scroll_offset;
                    if self.point_hits_vertical_bar(port, pos, env) {
                        ctx.set_active(true);
                        self.held = BarHeldState::Vertical(
                            // The bounds must be non-empty, because the point hits the scrollbar.
                            pos.y - self.calc_vertical_bar_bounds(port, env).unwrap().y0,
                        );
                    } else if self.point_hits_horizontal_bar(port, pos, env) {
                        ctx.set_active(true);
                        self.held = BarHeldState::Horizontal(
                            // The bounds must be non-empty, because the point hits the scrollbar.
                            pos.x - self.calc_horizontal_bar_bounds(port, env).unwrap().x0,
                        );
                    } else {
                        unreachable!();
                    }
                    ctx.set_handled();
                }
                // if the mouse was downed elsewhere, moved over a scroll bar and released: noop.
                Event::MouseUp(_) => (),
                _ => unreachable!(),
            }
        } else {
            match event {
                Event::MouseMove(_) => {
                    // if we have just stopped hovering
                    if self.hovered.is_hovered() && !scrollbar_is_hovered {
                        self.hovered = BarHoveredState::None;
                        self.reset_scrollbar_fade(|d| ctx.request_timer(d), env);
                    }
                }
                Event::Timer(id) if *id == self.timer_id => {
                    // Schedule scroll bars animation
                    ctx.request_anim_frame();
                    self.timer_id = TimerToken::INVALID;
                    ctx.set_handled();
                }
                Event::AnimFrame(interval) => {
                    // Guard by the timer id being invalid, otherwise the scroll bars would fade
                    // immediately if some other widget started animating.
                    if self.timer_id == TimerToken::INVALID {
                        // Animate scroll bars opacity
                        let diff = 2.0 * (*interval as f64) * 1e-9;
                        self.opacity -= diff;
                        if self.opacity > 0.0 {
                            ctx.request_anim_frame();
                        }
                        if let Some(bounds) = self.calc_horizontal_bar_bounds(port, env) {
                            ctx.request_paint_rect(bounds - scroll_offset);
                        }
                        if let Some(bounds) = self.calc_vertical_bar_bounds(port, env) {
                            ctx.request_paint_rect(bounds - scroll_offset);
                        }
                    }
                }
                _ => (),
            }
        }
    }
pub fn event ( & mut self , port : & mut Viewport , ctx : & mut EventCtx , event : & Event , env : & Env ) { let viewport_size = port . view_size ; let content_size = port . content_size ; let scroll_offset = port . view_origin . to_vec2 ( ) ; let scrollbar_is_hovered = match event { Event :: MouseMove ( e ) | Event :: MouseUp ( e ) | Event :: MouseDown ( e ) => { let offset_pos = e . pos + scroll_offset ; self . point_hits_vertical_bar ( port , offset_pos , env ) || self . point_hits_horizontal_bar ( port , offset_pos , env ) } _ => false , } ; if self . are_bars_held ( ) { // if we're dragging a scrollbar match event { Event :: MouseMove ( event ) => { match self . held { BarHeldState :: Vertical ( offset ) => { let scale_y = viewport_size . height / content_size . height ; let bounds = self . calc_vertical_bar_bounds ( port , env ) . unwrap_or ( Rect :: ZERO ) ; let mouse_y = event . pos . y + scroll_offset . y ; let delta = mouse_y - bounds . y0 - offset ; port . pan_by ( Vec2 :: new ( 0f64 , ( delta / scale_y ) . ceil ( ) ) ) ; ctx . set_handled ( ) ; } BarHeldState :: Horizontal ( offset ) => { let scale_x = viewport_size . width / content_size . width ; let bounds = self . calc_horizontal_bar_bounds ( port , env ) . unwrap_or ( Rect :: ZERO ) ; let mouse_x = event . pos . x + scroll_offset . x ; let delta = mouse_x - bounds . x0 - offset ; port . pan_by ( Vec2 :: new ( ( delta / scale_x ) . ceil ( ) , 0f64 ) ) ; ctx . set_handled ( ) ; } _ => ( ) , } ctx . request_paint ( ) ; } Event :: MouseUp ( _ ) => { self . held = BarHeldState :: None ; ctx . set_active ( false ) ; if ! scrollbar_is_hovered { self . hovered = BarHoveredState :: None ; self . reset_scrollbar_fade ( | d | ctx . request_timer ( d ) , env ) ; } ctx . set_handled ( ) ; } _ => ( ) , // other events are a noop } } else if scrollbar_is_hovered { // if we're over a scrollbar but not dragging match event { Event :: MouseMove ( event ) => { let offset_pos = event . pos + scroll_offset ; if self . point_hits_vertical_bar ( port , offset_pos , env ) { self . hovered = BarHoveredState :: Vertical ; } else if self . point_hits_horizontal_bar ( port , offset_pos , env ) { self . hovered = BarHoveredState :: Horizontal ; } else { unreachable ! ( ) ; } self . opacity = env . get ( theme :: SCROLLBAR_MAX_OPACITY ) ; self . timer_id = TimerToken :: INVALID ; // Cancel any fade out in progress ctx . request_paint ( ) ; ctx . set_handled ( ) ; } Event :: MouseDown ( event ) => { let pos = event . pos + scroll_offset ; if self . point_hits_vertical_bar ( port , pos , env ) { ctx . set_active ( true ) ; self . held = BarHeldState :: Vertical ( // The bounds must be non-empty, because the point hits the scrollbar. pos . y - self . calc_vertical_bar_bounds ( port , env ) . unwrap ( ) . y0 , ) ; } else if self . point_hits_horizontal_bar ( port , pos , env ) { ctx . set_active ( true ) ; self . held = BarHeldState :: Horizontal ( // The bounds must be non-empty, because the point hits the scrollbar. pos . x - self . calc_horizontal_bar_bounds ( port , env ) . unwrap ( ) . x0 , ) ; } else { unreachable ! ( ) ; } ctx . set_handled ( ) ; } // if the mouse was downed elsewhere, moved over a scroll bar and released: noop. Event :: MouseUp ( _ ) => ( ) , _ => unreachable ! ( ) , } } else { match event { Event :: MouseMove ( _ ) => { // if we have just stopped hovering if self . hovered . is_hovered ( ) && ! scrollbar_is_hovered { self . hovered = BarHoveredState :: None ; self . reset_scrollbar_fade ( | d | ctx . request_timer ( d ) , env ) ; } } Event :: Timer ( id ) if * id == self . timer_id => { // Schedule scroll bars animation ctx . request_anim_frame ( ) ; self . timer_id = TimerToken :: INVALID ; ctx . set_handled ( ) ; } Event :: AnimFrame ( interval ) => { // Guard by the timer id being invalid, otherwise the scroll bars would fade // immediately if some other widget started animating. if self . timer_id == TimerToken :: INVALID { // Animate scroll bars opacity let diff = 2.0 * ( * interval as f64 ) * 1e-9 ; self . opacity -= diff ; if self . opacity > 0.0 { ctx . request_anim_frame ( ) ; } if let Some ( bounds ) = self . calc_horizontal_bar_bounds ( port , env ) { ctx . request_paint_rect ( bounds - scroll_offset ) ; } if let Some ( bounds ) = self . calc_vertical_bar_bounds ( port , env ) { ctx . request_paint_rect ( bounds - scroll_offset ) ; } } } _ => ( ) , } } }
Checks if the event applies to the scroll behavior, uses it, and marks it handled
Make sure to call on every event
Checks if the event applies to the scroll behavior uses it and marks it handled Make sure to call on every event
&mut self
port
&mut Viewport
ctx
&mut EventCtx
event
&Event
env
&Env
&mut self
port
&mut Viewport
ctx
&mut EventCtx
event
&Event
env
&Env