BufferView: add scroll_view_{up,down}()
This commit is contained in:
parent
84759d0a36
commit
70aba6e2d4
@ -192,6 +192,46 @@ bool BufferView::cursor_move(CursorMovement which, bool allow_eol)
|
|||||||
return moved;
|
return moved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BufferView::scroll_view_up(int n_lines, bool allow_eol)
|
||||||
|
{
|
||||||
|
int so = effective_scroll_offset();
|
||||||
|
int rows_to_move_cursor = (so + n_lines) - (m_height - m_cursor_screen_row - 1);
|
||||||
|
rows_to_move_cursor = std::min(calculate_rows_above_screen(rows_to_move_cursor), rows_to_move_cursor);
|
||||||
|
int actual_lines_moved = 0;
|
||||||
|
while (rows_to_move_cursor-- > 0)
|
||||||
|
{
|
||||||
|
if (move_cursor_screen_row_up(allow_eol))
|
||||||
|
{
|
||||||
|
actual_lines_moved++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_cursor_screen_row += (n_lines - actual_lines_moved);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferView::scroll_view_down(int n_lines, bool allow_eol)
|
||||||
|
{
|
||||||
|
int so = effective_scroll_offset();
|
||||||
|
int rows_to_move_cursor = (so + n_lines) - m_cursor_screen_row;
|
||||||
|
rows_to_move_cursor = std::min(calculate_rows_below_screen(rows_to_move_cursor), rows_to_move_cursor);
|
||||||
|
int actual_lines_moved = 0;
|
||||||
|
while (rows_to_move_cursor-- > 0)
|
||||||
|
{
|
||||||
|
if (move_cursor_screen_row_down(allow_eol))
|
||||||
|
{
|
||||||
|
actual_lines_moved++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_cursor_screen_row -= (n_lines - actual_lines_moved);
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Internal functions
|
* Internal functions
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
@ -374,3 +414,35 @@ void BufferView::move_forward_to_screen_position(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int BufferView::calculate_rows_above_screen(int stop_at)
|
||||||
|
{
|
||||||
|
if (m_lines.empty())
|
||||||
|
return 0;
|
||||||
|
const LineDescriptor & first_line = *m_lines.begin();
|
||||||
|
auto iterator = std::make_shared<Buffer::Iterator>(*first_line.line);
|
||||||
|
int lines = std::max(0, -first_line.row_offset);
|
||||||
|
while (lines < stop_at)
|
||||||
|
{
|
||||||
|
if (!iterator->go_previous_line())
|
||||||
|
break;
|
||||||
|
lines += calculate_rows_in_line(iterator);
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BufferView::calculate_rows_below_screen(int stop_at)
|
||||||
|
{
|
||||||
|
if (m_lines.empty())
|
||||||
|
return 0;
|
||||||
|
const LineDescriptor & last_line = *m_lines.rbegin();
|
||||||
|
auto iterator = std::make_shared<Buffer::Iterator>(*last_line.line);
|
||||||
|
int lines = std::max(0, last_line.row_offset + last_line.n_rows - m_height);
|
||||||
|
while (lines < stop_at)
|
||||||
|
{
|
||||||
|
if (!iterator->go_next_line())
|
||||||
|
break;
|
||||||
|
lines += calculate_rows_in_line(iterator);
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
@ -84,6 +84,8 @@ public:
|
|||||||
{
|
{
|
||||||
m_cursor_screen_row = cursor_screen_row;
|
m_cursor_screen_row = cursor_screen_row;
|
||||||
}
|
}
|
||||||
|
void scroll_view_up(int n_lines, bool allow_eol);
|
||||||
|
void scroll_view_down(int n_lines, bool allow_eol);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct LineDescriptor
|
struct LineDescriptor
|
||||||
@ -126,6 +128,8 @@ protected:
|
|||||||
void move_forward_to_screen_position(
|
void move_forward_to_screen_position(
|
||||||
std::shared_ptr<Buffer::Iterator> line, int target_row_offset,
|
std::shared_ptr<Buffer::Iterator> line, int target_row_offset,
|
||||||
bool allow_eol);
|
bool allow_eol);
|
||||||
|
int calculate_rows_above_screen(int stop_at);
|
||||||
|
int calculate_rows_below_screen(int stop_at);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -520,3 +520,116 @@ TEST(BufferViewTest, cursor_move_screen_row_up_and_down_returns_false_at_top_and
|
|||||||
}
|
}
|
||||||
EXPECT_FALSE(bv.cursor_move(BufferView::CursorMovement::SCREEN_ROW_DOWN, false));
|
EXPECT_FALSE(bv.cursor_move(BufferView::CursorMovement::SCREEN_ROW_DOWN, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(BufferViewTest, scrolls_the_view_up_and_down)
|
||||||
|
{
|
||||||
|
auto b = buffer1();
|
||||||
|
auto iterator = b->add_iterator();
|
||||||
|
BufferView bv(b, iterator, Cwd);
|
||||||
|
bv.resize(40, 6);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(0, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(0, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_down(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(1, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(0, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_down(5, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(6, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(0, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_down(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(7, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(0, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_down(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(7, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(0, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_down(3, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(7, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(0, bv.cursor_screen_row());
|
||||||
|
|
||||||
|
bv.scroll_view_up(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(7, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(1, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_up(4, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(7, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(5, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_up(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(6, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(5, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_up(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(5, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(5, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_up(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(5, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(5, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_up(3, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(5, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(5, bv.cursor_screen_row());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BufferViewTest, scrolls_the_view_up_and_down_with_nonzero_scroll_offset)
|
||||||
|
{
|
||||||
|
auto b = buffer1();
|
||||||
|
auto iterator = b->add_iterator();
|
||||||
|
BufferView bv(b, iterator, Cwd);
|
||||||
|
bv.resize(40, 6);
|
||||||
|
bv.set_scroll_offset(2);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(0, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(0, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_down(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(3, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(2, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_down(5, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(8, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(2, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_down(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(9, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(2, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_down(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(9, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(2, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_down(3, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(9, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(2, bv.cursor_screen_row());
|
||||||
|
|
||||||
|
bv.scroll_view_up(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(9, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(3, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_up(4, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(5, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(3, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_up(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(4, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(3, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_up(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(3, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(3, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_up(1, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(3, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(3, bv.cursor_screen_row());
|
||||||
|
bv.scroll_view_up(3, false);
|
||||||
|
bv.update();
|
||||||
|
EXPECT_EQ(3, LineNumber(iterator));
|
||||||
|
EXPECT_EQ(3, bv.cursor_screen_row());
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user