Non-scrolling based selection tests all pass

This commit is contained in:
Kovid Goyal 2020-02-25 08:11:46 +05:30
parent e03aabd972
commit 5bbc15583e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 50 additions and 35 deletions

View File

@ -174,14 +174,14 @@ update_drag(bool from_button, Window *w, bool is_release, int modifiers) {
global_state.active_drag_in_window = 0;
w->last_drag_scroll_at = 0;
if (screen->selection.in_progress)
screen_update_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, w->mouse_pos.in_left_half_of_cell, true);
screen_update_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, w->mouse_pos.in_left_half_of_cell, true, false);
}
else {
global_state.active_drag_in_window = w->id;
screen_start_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, w->mouse_pos.in_left_half_of_cell, modifiers == (int)OPT(rectangle_select_modifiers) || modifiers == ((int)OPT(rectangle_select_modifiers) | (int)OPT(terminal_select_modifiers)), EXTEND_CELL);
}
} else if (screen->selection.in_progress) {
screen_update_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, w->mouse_pos.in_left_half_of_cell, false);
screen_update_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, w->mouse_pos.in_left_half_of_cell, false, false);
}
}
@ -218,7 +218,7 @@ static inline void
extend_selection(Window *w) {
Screen *screen = w->render_data.screen;
if (screen_has_selection(screen)) {
screen_update_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, w->mouse_pos.in_left_half_of_cell, true);
screen_update_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, w->mouse_pos.in_left_half_of_cell, true, false);
}
}
@ -345,8 +345,8 @@ multi_click(Window *w, unsigned int count) {
break;
}
if (mode != EXTEND_CELL) {
screen_start_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, w->mouse_pos.in_left_half_of_cell, false, EXTEND_WORD);
screen_update_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, w->mouse_pos.in_left_half_of_cell, false);
screen_start_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, w->mouse_pos.in_left_half_of_cell, false, mode);
screen_update_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, w->mouse_pos.in_left_half_of_cell, false, true);
}
}

View File

@ -1709,7 +1709,7 @@ iteration_data(const Screen *self, Selection *sel, const bool rectangle) {
} else return ans; // empty selection
}
// single line selection
if (left_to_right) {
if (start->x <= end->x) {
ans.first.x = start->x + (start->in_left_half_of_cell ? 0 : 1);
ans.first.x_limit = 1 + end->x + (end->in_left_half_of_cell ? -1 : 0);
} else {
@ -2098,7 +2098,7 @@ update_selection(Screen *self, PyObject *args) {
unsigned int x, y;
int in_left_half_of_cell = 0, ended = 1;
if (!PyArg_ParseTuple(args, "II|pp", &x, &y, &in_left_half_of_cell, &ended)) return NULL;
screen_update_selection(self, x, y, in_left_half_of_cell, ended);
screen_update_selection(self, x, y, in_left_half_of_cell, ended, false);
Py_RETURN_NONE;
}
@ -2265,48 +2265,54 @@ screen_mark_url(Screen *self, index_type start_x, index_type start_y, index_type
}
void
screen_update_selection(Screen *self, index_type x, index_type y, bool in_left_half_of_cell, bool ended) {
screen_update_selection(Screen *self, index_type x, index_type y, bool in_left_half_of_cell, bool ended, bool start_extended_selection) {
if (ended) self->selection.in_progress = false;
self->selection.input_current.x = x; self->selection.input_current.y = y;
self->selection.input_current.in_left_half_of_cell = in_left_half_of_cell;
SelectionBoundary start, end, *a, *b;
a = &self->selection.end, b = &self->selection.start;
if (selection_boundary_less_than(a, b)) { a = &self->selection.start; b = &self->selection.end; }
a = &self->selection.start, b = &self->selection.end;
bool left_to_right = selection_is_left_to_right(&self->selection);
switch(self->selection.extend_mode) {
case EXTEND_WORD: {
if (selection_boundary_less_than(b, a)) { a = &self->selection.end; b = &self->selection.start; }
bool found = false;
index_type effective_x = x;
if (left_to_right && in_left_half_of_cell && x) effective_x--;
else if(!left_to_right && !in_left_half_of_cell && x < self->columns - 1) effective_x++;
if (!start_extended_selection) {
if (left_to_right && in_left_half_of_cell && x) effective_x--;
else if(!left_to_right && !in_left_half_of_cell && x < self->columns - 1) effective_x++;
}
start.y = y;
found = screen_selection_range_for_word(self, effective_x, &start.y, &end.y, &start.x, &end.x, false);
if (found) {
start.in_left_half_of_cell = true; end.in_left_half_of_cell = false;
if (selection_boundary_less_than(&start, a)) *a = start;
if (selection_boundary_less_than(b, &end)) *b = end;
}
break;
}
case EXTEND_LINE: {
bool multiline = a->y != b->y;
if (y < a->y) {
index_type top_line = y;
while (top_line > 0 && visual_line_(self, top_line)->continued) top_line--;
if (screen_selection_range_for_line(self, top_line, &start.x, &end.x)) {
a->y = top_line;
a->x = multiline ? 0 : start.x;
a->in_left_half_of_cell = start.in_left_half_of_cell;
}
index_type top_line, bottom_line;
if (start_extended_selection || y == self->selection.start.y) {
top_line = y; bottom_line = y;
} else if (y < self->selection.start.y) {
top_line = y; bottom_line = self->selection.start.y;
a = &self->selection.end; b = &self->selection.start;
} else if (y > self->selection.start.y) {
bottom_line = y; top_line = self->selection.start.y;
} else break;
while (top_line > 0 && visual_line_(self, top_line)->continued) {
if (!screen_selection_range_for_line(self, top_line - 1, &start.x, &end.x)) break;
top_line--;
}
else if (y > b->y) {
index_type bottom_line = b->y;
while(bottom_line < self->lines - 1 && visual_line_(self, bottom_line + 1)->continued) bottom_line++;
if (screen_selection_range_for_line(self, bottom_line, &start.x, &end.x))
{
b->y = bottom_line;
b->x = end.x; b->in_left_half_of_cell = end.in_left_half_of_cell;
}
while (bottom_line < self->lines - 1 && visual_line_(self, bottom_line + 1)->continued) {
if (!screen_selection_range_for_line(self, bottom_line + 1, &start.x, &end.x)) break;
bottom_line++;
}
if (screen_selection_range_for_line(self, top_line, &start.x, &start.y) && screen_selection_range_for_line(self, bottom_line, &end.x, &end.y)) {
bool multiline = top_line != bottom_line;
a->x = multiline ? 0 : start.x; a->y = top_line; a->in_left_half_of_cell = true;
b->x = end.y; b->y = bottom_line; b->in_left_half_of_cell = false;
}
break;
}

View File

@ -187,7 +187,7 @@ bool screen_is_cursor_visible(Screen *self);
bool screen_selection_range_for_line(Screen *self, index_type y, index_type *start, index_type *end);
bool screen_selection_range_for_word(Screen *self, index_type x, index_type *, index_type *, index_type *start, index_type *end, bool);
void screen_start_selection(Screen *self, index_type x, index_type y, bool, bool, SelectionExtendMode);
void screen_update_selection(Screen *self, index_type x, index_type y, bool in_left_half, bool ended);
void screen_update_selection(Screen *self, index_type x, index_type y, bool in_left_half, bool ended, bool start_extended_selection);
bool screen_history_scroll(Screen *self, int amt, bool upwards);
Line* screen_visual_line(Screen *self, index_type y);
unsigned long screen_current_char_width(Screen *self);

View File

@ -85,6 +85,8 @@ class TestMouse(BaseTest):
self.ae(sel(), '1234')
release(x=3.6)
self.ae(sel(), '1234')
press(x=4), release(x=0.6)
self.ae(sel(), '234')
# Single cell select
init()
@ -110,11 +112,11 @@ class TestMouse(BaseTest):
s.draw(' f gh')
s.draw(' stuv')
s.draw('X Y')
multi_click(x=1.6)
multi_click(x=1.4)
self.ae(sel(), 'ab')
move(3.6)
self.ae(sel(), 'ab cd')
release(3, 1)
release(3.6, 1)
self.ae(sel(), 'ab cd f gh')
multi_click(x=1, y=2)
self.ae(sel(), 'stuvX')
@ -152,14 +154,21 @@ class TestMouse(BaseTest):
# Rectangle select
init()
press(x=1, y=1, modifiers=GLFW_MOD_ALT | GLFW_MOD_CONTROL)
move(x=3, y=3)
move(x=3.6, y=3)
self.ae(sel(), '789bcdghi')
release()
release(x=3, y=3)
self.ae(sel(), '78bcgh')
press(x=3.6, y=1, modifiers=GLFW_MOD_ALT | GLFW_MOD_CONTROL)
self.ae(sel(), '')
move(x=1, y=3)
self.ae(sel(), '789bcdghi')
release(x=1.6)
self.ae(sel(), '3489')
# scrolling
init()
press(x=1)
scroll(x=1)
scroll(x=1.6)
self.ae(sel(), 'LMNO12')
scroll(x=1)
self.ae(sel(), 'GHIJKLMNO12')