DVUI

processEvent

Parameters

#
self:*TextLayoutWidget
*TextLayoutWidget
e:*Event
*Event

Source

Implementation

#
pub fn processEvent(self: *TextLayoutWidget, e: *Event) void {
    switch (e.evt) {
        .mouse => |me| {
            if (me.action == .focus) {
                e.handle(@src(), self.data());
                // focus so that we can receive keyboard input
                dvui.focusWidget(self.data().id, null, e.num);
                dvui.currentWindow().scroll_to_focused = false;
            } else if (me.action == .press and (me.button.pointer() or me.button == .middle)) {
                e.handle(@src(), self.data());
                // capture and start drag
                dvui.captureMouse(self.data(), e.num);
                dvui.dragPreStart(me.button, me.p, .{ .cursor = .ibeam });

                if (me.button.touch()) {
                    self.te_focus_on_touchdown = self.focus_at_start;
                    if (self.touch_editing) {
                        self.te_show_context_menu = false;

                        // need to refresh draggables
                        dvui.refresh(null, @src(), self.data().id);
                    }
                } else if (me.button.pointer()) {
                    // a click always sets sel_move - has the highest priority
                    const p = self.data().contentRectScale().pointFromPhysical(me.p);
                    self.sel_move = .{ .mouse = .{ .down_pt = p } };
                    self.scroll_to_cursor = true;

                    if (self.click_num == 1) {
                        // select word we touched
                        self.sel_move = .{ .expand_pt = .{ .which = .word, .pt = p } };
                    } else if (self.click_num == 2) {
                        // select line we touched
                        self.sel_move = .{ .expand_pt = .{ .which = .line, .pt = p } };
                    }
                }
            } else if (me.action == .release and (me.button.pointer() or me.button == .middle)) {
                e.handle(@src(), self.data());

                if (dvui.captured(self.data().id)) {
                    if (!self.touch_editing and dvui.dragging(me.p, null) == null) {
                        // click without drag
                        self.click_pt = self.data().contentRectScale().pointFromPhysical(me.p);
                        self.click_event = e.evt;

                        if (me.button.pointer()) {
                            self.click_num += 1;
                            self.click_num_pt = me.p;
                            if (self.click_num >= 3) {
                                self.click_num = 0;
                            }
                        }
                    }

                    if (me.button.touch()) {
                        // this was a touch-release without drag, which transitions
                        // us between touch editing
                        const p = self.data().contentRectScale().pointFromPhysical(me.p);

                        if (self.te_focus_on_touchdown) {
                            self.touch_editing = !self.touch_editing;
                            // move cursor to point
                            self.sel_move = .{ .mouse = .{ .down_pt = p } };
                            if (self.touch_editing) {
                                // select word we touched
                                self.sel_move = .{ .expand_pt = .{ .which = .word, .pt = p } };
                            }
                        } else {
                            if (self.touch_edit_just_focused) {
                                self.touch_editing = true;
                            }
                            if (self.te_first) {
                                // This is the very first time we are entering
                                // touch editing from not having focus, we want to
                                // position the cursor.
                                self.te_first = false;

                                // select word we touched
                                self.sel_move = .{ .expand_pt = .{ .which = .word, .pt = p } };
                            }
                        }
                        dvui.refresh(null, @src(), self.data().id);
                    }

                    dvui.captureMouse(null, e.num);
                    dvui.dragEnd();
                }
            } else if (me.action == .motion and dvui.captured(self.data().id)) {
                if (dvui.dragging(me.p, null)) |_| {
                    self.click_num = 0;
                    if (!me.button.touch()) {
                        e.handle(@src(), self.data());
                        if (self.sel_move == .mouse) {
                            self.sel_move.mouse.drag_pt = self.data().contentRectScale().pointFromPhysical(me.p);
                        } else if (self.sel_move == .expand_pt) {
                            self.sel_move.expand_pt.pt = self.data().contentRectScale().pointFromPhysical(me.p);
                            self.sel_move.expand_pt.done = false;
                            self.sel_move.expand_pt.dragging = true;
                        }
                        dvui.scrollDrag(.{
                            .mouse_pt = me.p,
                            .screen_rect = self.data().rectScale().r,
                        });
                    } else {
                        // user intended to scroll with a finger swipe
                        // release our capture including this event so a
                        // containing scroll container can get it
                        dvui.captureMouse(null, e.num - 1); // stop possible drag and capture
                        dvui.dragEnd();
                    }
                }
            } else if (me.action == .motion) {
                if (self.click_num > 0) {
                    const dp = me.p.diff(self.click_num_pt).toNatural();
                    if (@abs(dp.x) > dvui.Dragging.threshold or @abs(dp.y) > dvui.Dragging.threshold) {
                        self.click_num = 0;
                    }
                }
            } else if (me.action == .position) {
                self.cursor_pt = self.data().contentRectScale().pointFromPhysical(me.p);
                self.cursor_event = e.evt;
            }
        },
        .key => |ke| blk: {
            if (ke.action == .down and ke.matchBind("text_start_select")) {
                e.handle(@src(), self.data());
                self.selection.moveCursor(0, true);
                self.scroll_to_cursor = true;
                break :blk;
            }

            if (ke.action == .down and ke.matchBind("text_end_select")) {
                e.handle(@src(), self.data());
                self.selection.moveCursor(std.math.maxInt(usize), true);
                self.scroll_to_cursor = true;
                break :blk;
            }

            if (ke.action == .down and ke.matchBind("line_start_select")) {
                e.handle(@src(), self.data());
                if (self.sel_move == .none) {
                    self.sel_move = .{ .expand_pt = .{ .which = .home } };
                }
                break :blk;
            }

            if (ke.action == .down and ke.matchBind("line_end_select")) {
                e.handle(@src(), self.data());
                if (self.sel_move == .none) {
                    self.sel_move = .{ .expand_pt = .{ .which = .end } };
                }
                break :blk;
            }

            if ((ke.action == .down or ke.action == .repeat) and ke.matchBind("word_left_select")) {
                e.handle(@src(), self.data());
                if (self.sel_move == .none) {
                    self.sel_move = .{ .word_left_right = .{} };
                }
                if (self.sel_move == .word_left_right) {
                    self.sel_move.word_left_right.count -= 1;
                }
                break :blk;
            }

            if ((ke.action == .down or ke.action == .repeat) and ke.matchBind("word_right_select")) {
                e.handle(@src(), self.data());
                if (self.sel_move == .none) {
                    self.sel_move = .{ .word_left_right = .{} };
                }
                if (self.sel_move == .word_left_right) {
                    self.sel_move.word_left_right.count += 1;
                }
                break :blk;
            }

            if ((ke.action == .down or ke.action == .repeat) and ke.matchBind("char_left_select")) {
                e.handle(@src(), self.data());
                if (self.sel_move == .none) {
                    self.sel_move = .{ .char_left_right = .{} };
                }
                if (self.sel_move == .char_left_right) {
                    self.sel_move.char_left_right.count -= 1;
                }
                break :blk;
            }

            if ((ke.action == .down or ke.action == .repeat) and ke.matchBind("char_right_select")) {
                e.handle(@src(), self.data());
                if (self.sel_move == .none) {
                    self.sel_move = .{ .char_left_right = .{} };
                }
                if (self.sel_move == .char_left_right) {
                    self.sel_move.char_left_right.count += 1;
                }
                break :blk;
            }

            if ((ke.action == .down or ke.action == .repeat) and ke.matchBind("char_up_select")) {
                e.handle(@src(), self.data());
                if (self.sel_move == .none) {
                    self.sel_move = .{ .cursor_updown = .{} };
                }
                if (self.sel_move == .cursor_updown) {
                    self.sel_move.cursor_updown.count -= 1;
                }
                break :blk;
            }

            if ((ke.action == .down or ke.action == .repeat) and ke.matchBind("char_down_select")) {
                e.handle(@src(), self.data());
                if (self.sel_move == .none) {
                    self.sel_move = .{ .cursor_updown = .{} };
                }
                if (self.sel_move == .cursor_updown) {
                    self.sel_move.cursor_updown.count += 1;
                }
                break :blk;
            }

            if (ke.action == .down and ke.matchBind("copy")) {
                e.handle(@src(), self.data());
                self.copy();
                break :blk;
            }

            if (ke.action == .down and ke.matchBind("select_all")) {
                e.handle(@src(), self.data());
                self.selection.selectAll();
                break :blk;
            }
        },
        .text => |te| {
            switch (te.action) {
                .selection => |sel| {
                    self.selection.moveCursor(sel.start, false);
                    self.selection.moveCursor(sel.end, true);
                    self.scroll_to_cursor = true;
                },
                else => {},
            }
        },
        else => {},
    }
}