Fix visual bug when scrolling
This commit is contained in:
@@ -20,6 +20,7 @@ struct Window {
|
|||||||
float font_spacing;
|
float font_spacing;
|
||||||
Rect2 rect;
|
Rect2 rect;
|
||||||
|
|
||||||
|
bool mouse_selecting;
|
||||||
Vec2 scroll; // window_world_to_window_units
|
Vec2 scroll; // window_world_to_window_units
|
||||||
Cursor main_cursor_begin_frame;
|
Cursor main_cursor_begin_frame;
|
||||||
Array<Cursor> cursors;
|
Array<Cursor> cursors;
|
||||||
@@ -132,3 +133,28 @@ Tuple<LayoutRow *, LayoutColumn *> GetRowCol(Window &window, int64_t pos) {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Range CalculateVisibleLineRange(Window &window) {
|
||||||
|
Vec2 s = GetSize(window.rect);
|
||||||
|
float line_offset = window.font_size;
|
||||||
|
float _line_min_y = (window.scroll.y) / line_offset;
|
||||||
|
float _line_max_y = (s.y + window.scroll.y) / line_offset;
|
||||||
|
int64_t line_min_y = (int64_t)floorf(_line_min_y);
|
||||||
|
int64_t line_max_y = (int64_t)ceilf(_line_max_y);
|
||||||
|
Range result = {line_min_y, line_max_y};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<LayoutColumn> CalculateVisibleColumns(Arena *arena, Window &window) {
|
||||||
|
Range visible_line_range = CalculateVisibleLineRange(window);
|
||||||
|
Array<LayoutColumn> r = {*arena};
|
||||||
|
for (int64_t line = visible_line_range.min; line < visible_line_range.max && line >= 0 && line < window.layout.rows.len; line += 1) {
|
||||||
|
LayoutRow &row = window.layout.rows[line];
|
||||||
|
For(row.columns) {
|
||||||
|
if (CheckCollisionRecs(ToRectangle(it.rect - window.scroll), ToRectangle(window.rect))) {
|
||||||
|
r.add(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
@@ -455,42 +455,59 @@ int main() {
|
|||||||
Rectangle rectangle_in_render_units = ToRectangle(window.rect);
|
Rectangle rectangle_in_render_units = ToRectangle(window.rect);
|
||||||
DrawRectangleRec(rectangle_in_render_units, WHITE);
|
DrawRectangleRec(rectangle_in_render_units, WHITE);
|
||||||
|
|
||||||
// Figure out which lines to draw
|
Array<LayoutColumn> visible_columns = CalculateVisibleColumns(&FrameArena, window);
|
||||||
Vec2 s = GetSize(window.rect);
|
// Mouse selection
|
||||||
float line_offset = font_size;
|
// @todo: multicursor
|
||||||
float _line_min_y = (window.scroll.y) / line_offset;
|
{
|
||||||
float _line_max_y = (s.y + window.scroll.y) / line_offset;
|
SetMouseCursor(MOUSE_CURSOR_DEFAULT);
|
||||||
int64_t line_min_y = (int64_t)floorf(_line_min_y);
|
Vec2 mouse = GetMousePosition();
|
||||||
int64_t line_max_y = (int64_t)ceilf(_line_max_y);
|
Vec2 mouse_lookup = Vector2Add(mouse, window.scroll);
|
||||||
int64_t visible_lines = line_max_y - line_min_y;
|
|
||||||
|
|
||||||
Array<LayoutColumn> visible_columns = {FrameArena};
|
Tuple<LayoutRow *, LayoutColumn *> rowcol = GetRowCol(window, mouse_lookup);
|
||||||
for (int64_t line = line_min_y; line < line_max_y && line >= 0 && line < window.layout.rows.len; line += 1) {
|
if (rowcol.b) {
|
||||||
LayoutRow &row = window.layout.rows[line];
|
Rect2 col_rect = rowcol.b->rect - window.scroll;
|
||||||
For(row.columns) {
|
Rectangle col_rectangle = ToRectangle(col_rect);
|
||||||
if (CheckCollisionRecs(ToRectangle(it.rect - window.scroll), ToRectangle(window.rect))) {
|
if (CheckCollisionPointRec(mouse, col_rectangle)) {
|
||||||
visible_columns.add(it);
|
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
|
||||||
|
window.cursors.clear();
|
||||||
|
window.cursors.add({rowcol.b->pos, rowcol.b->pos});
|
||||||
|
window.mouse_selecting = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!window.mouse_selecting) {
|
||||||
|
SetMouseCursor(MOUSE_CURSOR_IBEAM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.mouse_selecting) {
|
||||||
|
SetMouseCursor(MOUSE_CURSOR_RESIZE_ALL);
|
||||||
|
if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
|
||||||
|
window.mouse_selecting = false;
|
||||||
|
}
|
||||||
|
Cursor *cursor = window.cursors.last();
|
||||||
|
cursor[0] = ChangeBack(*cursor, rowcol.b->pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the scroll based on first cursor
|
// Update the scroll based on first cursor
|
||||||
// @todo: needs a rewrite
|
// @todo: needs a rewrite, make sure we also handle scrolling for mouse
|
||||||
if (!AreEqual(window.main_cursor_begin_frame, window.cursors[0])) {
|
if (!AreEqual(window.main_cursor_begin_frame, window.cursors[0])) {
|
||||||
|
Range visible_line_range = CalculateVisibleLineRange(window);
|
||||||
Vec2 rect_size = GetSize(window.rect);
|
Vec2 rect_size = GetSize(window.rect);
|
||||||
float visible_cells_in_render_units = font_size * (float)visible_lines;
|
float visible_cells_in_render_units = font_size * (float)GetRangeSize(visible_line_range);
|
||||||
float cut_off_in_render_units = visible_cells_in_render_units - rect_size.y;
|
float cut_off_in_render_units = visible_cells_in_render_units - rect_size.y;
|
||||||
|
|
||||||
Cursor cursor = window.cursors[0];
|
Cursor cursor = window.cursors[0];
|
||||||
int64_t front = GetFront(cursor);
|
int64_t front = GetBack(cursor);
|
||||||
Line line = FindLine(window.buffer, front);
|
Line line = FindLine(window.buffer, front);
|
||||||
|
|
||||||
// Scroll Y
|
// Scroll Y
|
||||||
if (line.number < (line_min_y + 1)) {
|
if (line.number < (visible_line_range.min)) {
|
||||||
window.scroll.y = line.number * font_size;
|
window.scroll.y = line.number * font_size;
|
||||||
} else if (line.number >= (line_max_y - 1)) {
|
} else if (line.number >= (visible_line_range.max)) {
|
||||||
int64_t diff = line.number - line_max_y;
|
int64_t diff = line.number - visible_line_range.max;
|
||||||
window.scroll.y = (line_min_y + diff) * font_size + cut_off_in_render_units;
|
window.scroll.y = (visible_line_range.min + diff) * font_size + cut_off_in_render_units;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scroll X
|
// Scroll X
|
||||||
@@ -513,36 +530,13 @@ int main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mouse selection @todo
|
Range visible_line_range = CalculateVisibleLineRange(window);
|
||||||
{
|
|
||||||
SetMouseCursor(MOUSE_CURSOR_DEFAULT);
|
|
||||||
Vec2 mouse = GetMousePosition();
|
|
||||||
Vec2 mouse_lookup = Vector2Add(mouse, window.scroll);
|
|
||||||
|
|
||||||
Tuple<LayoutRow *, LayoutColumn *> rowcol = GetRowCol(window, mouse_lookup);
|
|
||||||
if (rowcol.b) {
|
|
||||||
Rect2 col_rect = rowcol.b->rect - window.scroll;
|
|
||||||
Rectangle col_rectangle = ToRectangle(col_rect);
|
|
||||||
if (CheckCollisionPointRec(mouse, col_rectangle)) {
|
|
||||||
// DrawRectangleRec(col_rectangle, {0, 0, 255, 40});
|
|
||||||
SetMouseCursor(MOUSE_CURSOR_IBEAM);
|
|
||||||
|
|
||||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
|
|
||||||
window.cursors.clear();
|
|
||||||
window.cursors.add({rowcol.b->pos, rowcol.b->pos});
|
|
||||||
} else if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
|
|
||||||
Cursor *cursor = window.cursors.last();
|
|
||||||
cursor[0] = ChangeBack(*cursor, rowcol.b->pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the glyphs
|
// Draw the glyphs
|
||||||
Vec2 window_rect_size = GetSize(window.rect);
|
Vec2 window_rect_size = GetSize(window.rect);
|
||||||
BeginScissorMode((int)window.rect.min.x, (int)window.rect.min.y, (int)window_rect_size.x, (int)window_rect_size.y);
|
BeginScissorMode((int)window.rect.min.x, (int)window.rect.min.y, (int)window_rect_size.x, (int)window_rect_size.y);
|
||||||
|
|
||||||
for (int64_t line = line_min_y; line < line_max_y; line += 1) {
|
for (int64_t line = visible_line_range.min; line < visible_line_range.max; line += 1) {
|
||||||
if (line < 0 || line >= window.layout.rows.len) continue;
|
if (line < 0 || line >= window.layout.rows.len) continue;
|
||||||
LayoutRow &row = window.layout.rows[line];
|
LayoutRow &row = window.layout.rows[line];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user