DVUI

Parameters

#
self:*ScrollContainerWidget
*ScrollContainerWidget
motion:dvui.Point.Physical
dvui.Point.Physical

Source

Implementation

#
pub fn processMotionScroll(self: *ScrollContainerWidget, motion: dvui.Point.Physical) void {
    const rs = self.data().borderRectScale();

    var have_parent: bool = false;
    if (self.parentScroll) |parent| {
        if (parent.subwindowId == self.subwindowId) {
            have_parent = true;
        }
    }

    // We propagate (instead of not handling the motion event) because we have
    // capture.
    //
    // Whether to propagate out to any containing scroll
    // containers. Propagate unless we did the whole scroll
    // in the main direction of movement.
    //
    // This helps prevent spurious propogation from a text
    // entry box where you are trying to scroll vertically
    // but the motion event has a small amount of
    // horizontal.
    var propagate: bool = false;

    if (self.si.vertical != .none) {
        if (!have_parent or
            (motion.y > 0 and self.si.viewport.y > 0) or
            (motion.y < 0 and self.si.viewport.y < self.si.scrollMax(.vertical)))
        {
            // can scroll in that direction or no parent, so scroll anyway (might bump past the limit)
            self.si.viewport.y -= motion.y / rs.s;
            if (self.init_opts.user_scroll) |us| us.*.y -= motion.y / rs.s;
            self.si.velocity.y = -motion.y / rs.s;
            dvui.refresh(null, @src(), self.data().id);
        } else if (@abs(motion.y) > @abs(motion.x)) {
            propagate = true;
        }
    }

    if (self.si.horizontal != .none) {
        if (!have_parent or
            (motion.x > 0 and self.si.viewport.x > 0) or
            (motion.x < 0 and self.si.viewport.x < self.si.scrollMax(.horizontal)))
        {
            self.si.viewport.x -= motion.x / rs.s;
            if (self.init_opts.user_scroll) |us| us.*.x -= motion.x / rs.s;
            self.si.velocity.x = -motion.x / rs.s;
            dvui.refresh(null, @src(), self.data().id);
        } else if (@abs(motion.x) > @abs(motion.y)) {
            propagate = true;
        }
    }

    if (propagate) {
        if (self.parentScroll) |parent| {
            if (parent.subwindowId == self.subwindowId) {
                parent.processMotionScroll(motion);
            }
        }
    }
}