Z ordering, prep for command window

This commit is contained in:
Krzosa Karol
2024-07-23 13:34:12 +02:00
parent 0f34416726
commit 24ad9464b5
7 changed files with 329 additions and 276 deletions

View File

@@ -18,8 +18,9 @@ Vec2 GetSizeF(Rect2I r) {
return result;
}
Vec2 ToVec2(Vec2I v) { return {(float)v.x, (float)v.y}; }
Vec2I ToVec2I(Vec2 v) { return {(Int)v.x, (Int)v.y}; }
Vec2 ToVec2(Vec2I v) { return {(float)v.x, (float)v.y}; }
Vec2I ToVec2I(Vec2 v) { return {(Int)v.x, (Int)v.y}; }
Rect2I ToRect2I(Rect2 r) { return {ToVec2I(r.min), ToVec2I(r.max)}; }
// clang-format off
Rect2 operator-(Rect2 r, Rect2 value) { return { r.min.x - value.min.x, r.min.y - value.min.y, r.max.x - value.max.x, r.max.y - value.max.y }; }

View File

@@ -13,6 +13,11 @@ Rect2I GetScreenRect() {
return result;
}
Rect2 GetScreenRectF() {
Rect2 result = {0, 0, (float)GetRenderWidth(), (float)GetRenderHeight()};
return result;
}
Int GetCharSpacing(Font font, Int font_size, Int spacing) {
int index = GetGlyphIndex(font, '_');
Int textOffsetX = 0;

View File

@@ -96,9 +96,22 @@ int main(void) {
LoadLine(b);
AddView(w->id, v->id);
}
{
Window *w = CreateWindow();
w->draw_scrollbar = false;
w->draw_line_numbers = false;
w->draw_infobar = false;
Buffer *b = CreateBuffer(sys_allocator);
View *v = CreateView(b->id);
LoadLine(b);
AddView(w->id, v->id);
}
Int LastFrameIDWhenSwitchedActiveWindow = 0;
while (!WindowShouldClose()) {
ProfileScope(game_loop);
FrameID += 1;
Rect2I screen_rect = GetScreenRect();
float line_numbers_size = MeasureTextEx(MainFont, "12345", (float)FontSize, (float)FontSpacing).x;
@@ -126,13 +139,56 @@ int main(void) {
if (Windows[i].draw_infobar) Windows[i].infobar_rect = CutBottom(&Windows[i].document_rect, (Int)MenuFontSize);
if (Windows[i].draw_line_numbers) Windows[i].line_numbers_rect = CutLeft(&Windows[i].document_rect, (Int)line_numbers_size);
}
{
int i = 4;
Rect2 screen_rect = GetScreenRectF();
Vec2 size = GetSize(screen_rect);
CutTop(&screen_rect, size.y * 0.05f);
CutBottom(&screen_rect, size.y * 0.8f);
CutLeft(&screen_rect, size.x * 0.2f);
CutRight(&screen_rect, size.x * 0.2f);
Windows[i].z = 1;
Windows[i].total_rect = ToRect2I(screen_rect);
Windows[i].document_rect = Windows[i].total_rect;
}
BeginDrawing();
ClearBackground(ColorBackground);
For(Windows) {
if (!it.visible) continue;
HandleKeybindings(&it);
DrawWindow(it);
Scratch scratch;
Array<Int> order = GetWindowZOrder(scratch);
For(order) {
Window *window = &Windows[it];
if (window->visible == false) continue;
View *view = GetActiveView(window);
Vec2 _mouse = GetMousePosition();
bool mouse_in_view = CheckCollisionPointRec(_mouse, ToRectangle(window->document_rect));
bool mouse_in_scrollbar = CheckCollisionPointRec(_mouse, ToRectangle(window->scrollbar_rect));
if (mouse_in_view || mouse_in_scrollbar) {
if (IsKeyDown(KEY_F1)) {
view->scroll.x -= (Int)(GetMouseWheelMove() * 48);
} else {
view->scroll.y -= (Int)(GetMouseWheelMove() * 48);
}
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
if (LastFrameIDWhenSwitchedActiveWindow != FrameID) {
ActiveWindow = window->id;
LastFrameIDWhenSwitchedActiveWindow = FrameID;
}
}
}
}
For(IterateInReverse(&order)) {
Window &window = Windows[it];
if (window.visible == false) continue;
HandleKeybindings(&window);
DrawWindow(window);
}
SetMouseCursor();
EndDrawing();

View File

@@ -55,6 +55,7 @@ struct Window {
Rect2I document_rect;
double mouse_scroller_offset;
int z;
struct {
bool mouse_selecting_scrollbar : 1;
@@ -99,6 +100,8 @@ Int FontSpacing;
Int FontLineSpacing;
Int FontCharSpacing;
Int FrameID;
inline Window *GetWindow(WindowID id) {
For(Windows) if (it.id.id == id.id) return &it;
return &Windows[0];

View File

@@ -118,319 +118,298 @@ void HandleKeybindings(Window *window) {
Buffer *buffer = GetBuffer(view.buffer_id);
Caret main_caret_on_begin_frame = view.carets[0];
{
Vec2 _mouse = GetMousePosition();
bool mouse_in_view = CheckCollisionPointRec(_mouse, ToRectangle(window->document_rect));
bool mouse_in_scrollbar = CheckCollisionPointRec(_mouse, ToRectangle(window->scrollbar_rect));
if (IsActive(window)) {
if (mouse_in_view || mouse_in_scrollbar) {
if (IsKeyDown(KEY_F1)) {
view.scroll.x -= (Int)(GetMouseWheelMove() * 48);
} else {
view.scroll.y -= (Int)(GetMouseWheelMove() * 48);
}
if (CtrlPress(KEY_F2)) {
LoadBigLine(buffer);
} else if (Press(KEY_F2)) {
LoadBigText(buffer);
}
if (!IsActive(window)) {
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
ActiveWindow = window->id;
if (Press(KEY_ESCAPE)) {
view.carets.len = 1;
}
if (CtrlAltPress(KEY_DOWN)) {
Command_DuplicateLine(&view, DIR_DOWN);
} else if (AltShiftPress(KEY_DOWN)) {
Command_CreateCursorVertical(&view, DIR_DOWN);
} else if (CtrlShiftPress(KEY_DOWN)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_DOWN, true));
} else if (CtrlPress(KEY_DOWN)) {
For(view.carets) it = MakeCaret(MovePos(*buffer, it.range.max, DIR_DOWN, true));
} else if (ShiftPress(KEY_DOWN)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_DOWN, false));
} else if (Press(KEY_DOWN)) {
For(view.carets) {
if (GetSize(it.range) == 0) {
it = MakeCaret(MovePos(*buffer, it.range.max, DIR_DOWN, false));
} else {
it = MakeCaret(it.range.max);
}
}
}
}
if (!IsActive(window)) {
return;
}
if (CtrlPress(KEY_F2)) {
LoadBigLine(buffer);
} else if (Press(KEY_F2)) {
LoadBigText(buffer);
}
if (Press(KEY_ESCAPE)) {
view.carets.len = 1;
}
if (CtrlAltPress(KEY_DOWN)) {
Command_DuplicateLine(&view, DIR_DOWN);
} else if (AltShiftPress(KEY_DOWN)) {
Command_CreateCursorVertical(&view, DIR_DOWN);
} else if (CtrlShiftPress(KEY_DOWN)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_DOWN, true));
} else if (CtrlPress(KEY_DOWN)) {
For(view.carets) it = MakeCaret(MovePos(*buffer, it.range.max, DIR_DOWN, true));
} else if (ShiftPress(KEY_DOWN)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_DOWN, false));
} else if (Press(KEY_DOWN)) {
For(view.carets) {
if (GetSize(it.range) == 0) {
it = MakeCaret(MovePos(*buffer, it.range.max, DIR_DOWN, false));
} else {
it = MakeCaret(it.range.max);
if (CtrlAltPress(KEY_UP)) {
Command_DuplicateLine(&view, DIR_UP);
} else if (AltShiftPress(KEY_UP)) {
Command_CreateCursorVertical(&view, DIR_UP);
} else if (CtrlShiftPress(KEY_UP)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_UP, CTRL_PRESSED));
} else if (CtrlPress(KEY_UP)) {
For(view.carets) it = MakeCaret(MovePos(*buffer, it.range.min, DIR_UP, CTRL_PRESSED));
} else if (ShiftPress(KEY_UP)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_UP));
} else if (Press(KEY_UP)) {
For(view.carets) {
if (GetSize(it.range) == 0) {
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_UP));
} else {
it = MakeCaret(it.range.min);
}
}
}
}
if (CtrlAltPress(KEY_UP)) {
Command_DuplicateLine(&view, DIR_UP);
} else if (AltShiftPress(KEY_UP)) {
Command_CreateCursorVertical(&view, DIR_UP);
} else if (CtrlShiftPress(KEY_UP)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_UP, CTRL_PRESSED));
} else if (CtrlPress(KEY_UP)) {
For(view.carets) it = MakeCaret(MovePos(*buffer, it.range.min, DIR_UP, CTRL_PRESSED));
} else if (ShiftPress(KEY_UP)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_UP));
} else if (Press(KEY_UP)) {
For(view.carets) {
if (GetSize(it.range) == 0) {
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_UP));
} else {
it = MakeCaret(it.range.min);
if (CtrlShiftPress(KEY_LEFT)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_LEFT, true));
} else if (CtrlPress(KEY_LEFT)) {
For(view.carets) {
if (GetSize(it.range) != 0 && GetFront(it) != it.range.min) {
it = MakeCaret(it.range.min);
} else {
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_LEFT, true));
}
}
} else if (ShiftPress(KEY_LEFT)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_LEFT, false));
} else if (Press(KEY_LEFT)) {
For(view.carets) {
if (GetSize(it.range) == 0) {
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_LEFT, false));
} else {
it = MakeCaret(it.range.min);
}
}
}
}
if (CtrlShiftPress(KEY_LEFT)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_LEFT, true));
} else if (CtrlPress(KEY_LEFT)) {
For(view.carets) {
if (GetSize(it.range) != 0 && GetFront(it) != it.range.min) {
it = MakeCaret(it.range.min);
} else {
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_LEFT, true));
if (CtrlShiftPress(KEY_RIGHT)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_RIGHT, true));
} else if (CtrlPress(KEY_RIGHT)) {
For(view.carets) {
if (GetSize(it.range) != 0 && GetFront(it) != it.range.max) {
it = MakeCaret(it.range.max);
} else {
it = MakeCaret(MovePos(*buffer, it.range.max, DIR_RIGHT, true));
}
}
} else if (ShiftPress(KEY_RIGHT)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_RIGHT, false));
} else if (Press(KEY_RIGHT)) {
For(view.carets) {
if (GetSize(it.range) == 0) {
it = MakeCaret(MovePos(*buffer, it.range.max, DIR_RIGHT, false));
} else {
it = MakeCaret(it.range.max);
}
}
}
} else if (ShiftPress(KEY_LEFT)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_LEFT, false));
} else if (Press(KEY_LEFT)) {
For(view.carets) {
if (GetSize(it.range) == 0) {
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_LEFT, false));
} else {
it = MakeCaret(it.range.min);
}
}
}
if (CtrlShiftPress(KEY_RIGHT)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_RIGHT, true));
} else if (CtrlPress(KEY_RIGHT)) {
For(view.carets) {
if (GetSize(it.range) != 0 && GetFront(it) != it.range.max) {
it = MakeCaret(it.range.max);
} else {
it = MakeCaret(MovePos(*buffer, it.range.max, DIR_RIGHT, true));
}
}
} else if (ShiftPress(KEY_RIGHT)) {
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_RIGHT, false));
} else if (Press(KEY_RIGHT)) {
For(view.carets) {
if (GetSize(it.range) == 0) {
it = MakeCaret(MovePos(*buffer, it.range.max, DIR_RIGHT, false));
} else {
it = MakeCaret(it.range.max);
}
}
}
if (CtrlPress(KEY_D)) {
Range range = view.carets[0].range;
String16 string = GetString(*buffer, range);
String16 string_buffer = GetString(*buffer, {range.max, INT64_MAX});
Int index = 0;
if (Seek(string_buffer, string, &index)) {
Insert(&view.carets, MakeCaret(range.max + index, range.max + index + string.len), 0);
} else {
String16 string_buffer = GetString(*buffer);
if (CtrlPress(KEY_D)) {
Range range = view.carets[0].range;
String16 string = GetString(*buffer, range);
String16 string_buffer = GetString(*buffer, {range.max, INT64_MAX});
Int index = 0;
if (Seek(string_buffer, string, &index)) {
Insert(&view.carets, MakeCaret(index, index + string.len), 0);
Insert(&view.carets, MakeCaret(range.max + index, range.max + index + string.len), 0);
} else {
String16 string_buffer = GetString(*buffer);
if (Seek(string_buffer, string, &index)) {
Insert(&view.carets, MakeCaret(index, index + string.len), 0);
}
}
}
}
if (CtrlShiftPress(KEY_Z)) {
RedoEdit(buffer, &view.carets);
} else if (CtrlPress(KEY_Z)) {
UndoEdit(buffer, &view.carets);
}
if (CtrlShiftPress(KEY_Z)) {
RedoEdit(buffer, &view.carets);
} else if (CtrlPress(KEY_Z)) {
UndoEdit(buffer, &view.carets);
}
if (CtrlPress(KEY_C)) {
Command_Copy(&view);
} else if (CtrlPress(KEY_V)) {
Command_Paste(&view);
} else if (CtrlPress(KEY_X)) {
Command_Copy(&view);
Command_Replace(&view, L"");
}
if (CtrlPress(KEY_C)) {
Command_Copy(&view);
} else if (CtrlPress(KEY_V)) {
Command_Paste(&view);
} else if (CtrlPress(KEY_X)) {
Command_Copy(&view);
Command_Replace(&view, L"");
}
bool dont_update_scroll = false;
if (CtrlPress(KEY_A)) {
view.carets.len = 1;
view.carets[0] = MakeCaret(0, buffer->len);
dont_update_scroll = true;
}
bool dont_update_scroll = false;
if (CtrlPress(KEY_A)) {
view.carets.len = 1;
view.carets[0] = MakeCaret(0, buffer->len);
dont_update_scroll = true;
}
if (ShiftPress(KEY_PAGE_UP)) {
Command_MoveCursorsByPageSize(window, DIR_UP, SHIFT_PRESSED);
} else if (Press(KEY_PAGE_UP)) {
Command_MoveCursorsByPageSize(window, DIR_UP);
}
if (ShiftPress(KEY_PAGE_UP)) {
Command_MoveCursorsByPageSize(window, DIR_UP, SHIFT_PRESSED);
} else if (Press(KEY_PAGE_UP)) {
Command_MoveCursorsByPageSize(window, DIR_UP);
}
if (ShiftPress(KEY_PAGE_DOWN)) {
Command_MoveCursorsByPageSize(window, DIR_DOWN, SHIFT_PRESSED);
} else if (Press(KEY_PAGE_DOWN)) {
Command_MoveCursorsByPageSize(window, DIR_DOWN);
}
if (ShiftPress(KEY_PAGE_DOWN)) {
Command_MoveCursorsByPageSize(window, DIR_DOWN, SHIFT_PRESSED);
} else if (Press(KEY_PAGE_DOWN)) {
Command_MoveCursorsByPageSize(window, DIR_DOWN);
}
if (ShiftPress(KEY_HOME)) {
Command_MoveCursorsToSide(window, DIR_LEFT, SHIFT_PRESSED);
} else if (Press(KEY_HOME)) {
Command_MoveCursorsToSide(window, DIR_LEFT);
}
if (ShiftPress(KEY_HOME)) {
Command_MoveCursorsToSide(window, DIR_LEFT, SHIFT_PRESSED);
} else if (Press(KEY_HOME)) {
Command_MoveCursorsToSide(window, DIR_LEFT);
}
if (ShiftPress(KEY_END)) {
Command_MoveCursorsToSide(window, DIR_RIGHT, SHIFT_PRESSED);
} else if (Press(KEY_END)) {
Command_MoveCursorsToSide(window, DIR_RIGHT);
}
if (ShiftPress(KEY_END)) {
Command_MoveCursorsToSide(window, DIR_RIGHT, SHIFT_PRESSED);
} else if (Press(KEY_END)) {
Command_MoveCursorsToSide(window, DIR_RIGHT);
}
if (Press(KEY_ENTER)) {
Command_Replace(&view, L"\n");
}
if (Press(KEY_ENTER)) {
Command_Replace(&view, L"\n");
}
if (Press(KEY_TAB)) {
Command_Replace(&view, L" ");
}
if (Press(KEY_TAB)) {
Command_Replace(&view, L" ");
}
if (CtrlPress(KEY_BACKSPACE)) {
Command_Delete(&view, DIR_LEFT, CTRL_PRESSED);
} else if (Press(KEY_BACKSPACE)) {
Command_Delete(&view, DIR_LEFT);
}
if (CtrlPress(KEY_BACKSPACE)) {
Command_Delete(&view, DIR_LEFT, CTRL_PRESSED);
} else if (Press(KEY_BACKSPACE)) {
Command_Delete(&view, DIR_LEFT);
}
if (CtrlPress(KEY_DELETE)) {
Command_Delete(&view, DIR_RIGHT, CTRL_PRESSED);
} else if (Press(KEY_DELETE)) {
Command_Delete(&view, DIR_RIGHT);
}
if (CtrlPress(KEY_DELETE)) {
Command_Delete(&view, DIR_RIGHT, CTRL_PRESSED);
} else if (Press(KEY_DELETE)) {
Command_Delete(&view, DIR_RIGHT);
}
for (int c = GetCharPressed(); c; c = GetCharPressed()) {
// we interpret 2 byte sequences as 1 byte when rendering but we still
// want to read them properly.
String16 string = L"?";
UTF16Result result = UTF32ToUTF16((uint32_t)c);
if (!result.error) string = {(wchar_t *)result.out_str, result.len};
Command_Replace(&view, string);
}
for (int c = GetCharPressed(); c; c = GetCharPressed()) {
// we interpret 2 byte sequences as 1 byte when rendering but we still
// want to read them properly.
String16 string = L"?";
UTF16Result result = UTF32ToUTF16((uint32_t)c);
if (!result.error) string = {(wchar_t *)result.out_str, result.len};
Command_Replace(&view, string);
}
{
ProfileScope(mouse);
{
ProfileScope(mouse);
Vec2 _mouse = GetMousePosition();
bool mouse_in_view = CheckCollisionPointRec(_mouse, ToRectangle(window->document_rect));
bool mouse_in_scrollbar = CheckCollisionPointRec(_mouse, ToRectangle(window->scrollbar_rect));
Vec2I mouse = ToVec2I(_mouse);
Vec2 _mouse = GetMousePosition();
bool mouse_in_view = CheckCollisionPointRec(_mouse, ToRectangle(window->document_rect));
bool mouse_in_scrollbar = CheckCollisionPointRec(_mouse, ToRectangle(window->scrollbar_rect));
Vec2I mouse = ToVec2I(_mouse);
if (!(mouse_in_scrollbar || window->mouse_selecting_scrollbar) && (mouse_in_view || window->mouse_selecting)) {
Vec2I mworld = mouse - window->document_rect.min + view.scroll;
Vec2I pos = mworld / Vec2I{FontCharSpacing, FontLineSpacing};
XY xy = {(Int)(pos.x), (Int)(pos.y)};
Int p = XYToPosWithoutNL(*buffer, xy);
if (!(mouse_in_scrollbar || window->mouse_selecting_scrollbar) && (mouse_in_view || window->mouse_selecting)) {
Vec2I mworld = mouse - window->document_rect.min + view.scroll;
Vec2I pos = mworld / Vec2I{FontCharSpacing, FontLineSpacing};
XY xy = {(Int)(pos.x), (Int)(pos.y)};
Int p = XYToPosWithoutNL(*buffer, xy);
if (mouse_in_view && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
if (IsDoubleClick()) {
Caret *c = GetLast(view.carets);
if (InBounds({c->range.min - 1, c->range.max + 1}, p)) {
c->range = EncloseWord(*buffer, p);
view.selection_anchor = c->range;
if (mouse_in_view && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
if (IsDoubleClick()) {
Caret *c = GetLast(view.carets);
if (InBounds({c->range.min - 1, c->range.max + 1}, p)) {
c->range = EncloseWord(*buffer, p);
view.selection_anchor = c->range;
}
} else {
if (!IsKeyDown(KEY_LEFT_CONTROL)) {
view.carets.len = 0;
}
Add(&view.carets, MakeCaret(p, p));
view.selection_anchor = GetLast(view.carets)->range;
}
} else {
if (!IsKeyDown(KEY_LEFT_CONTROL)) {
view.carets.len = 0;
}
Add(&view.carets, MakeCaret(p, p));
view.selection_anchor = GetLast(view.carets)->range;
MergeCarets(&view.carets);
} else if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
window->mouse_selecting = true;
}
}
MergeCarets(&view.carets);
} else if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
window->mouse_selecting = true;
if (window->mouse_selecting) {
if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)) window->mouse_selecting = false;
Caret &caret = *GetLast(view.carets);
if (view.selection_anchor.min > p) {
caret = MakeCaret(p, view.selection_anchor.max);
} else if (view.selection_anchor.max < p) {
caret = MakeCaret(p, view.selection_anchor.min);
} else {
caret = MakeCaret(view.selection_anchor.max, view.selection_anchor.min);
}
MergeCarets(&view.carets, &view.selection_anchor);
}
} else if (!(mouse_in_view || window->mouse_selecting) && mouse_in_scrollbar || window->mouse_selecting_scrollbar) {
Scroller s = ComputeScrollerRect(*window);
double size_y = (double)GetSize(window->scrollbar_rect).y;
double p = _mouse.y - window->scrollbar_rect.min.y;
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
window->mouse_selecting_scrollbar = true;
} else if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
window->mouse_selecting_scrollbar = false;
}
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
if (_mouse.y < s.rect.min.y || _mouse.y > s.rect.max.y) {
view.scroll.y = (Int)(p / size_y * (double)s.line_count * (double)FontLineSpacing);
window->mouse_scroller_offset = -(double)GetSize(s.rect).y / 2.0 / size_y;
} else {
window->mouse_scroller_offset = (s.rect.min.y - p) / size_y;
}
}
if (window->mouse_selecting_scrollbar) {
double v = p / size_y;
v = v + (window->mouse_scroller_offset);
view.scroll.y = (Int)(v * (double)s.line_count * (double)FontLineSpacing);
}
}
if (window->mouse_selecting) {
if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)) window->mouse_selecting = false;
Caret &caret = *GetLast(view.carets);
if (view.selection_anchor.min > p) {
caret = MakeCaret(p, view.selection_anchor.max);
} else if (view.selection_anchor.max < p) {
caret = MakeCaret(p, view.selection_anchor.min);
} else {
caret = MakeCaret(view.selection_anchor.max, view.selection_anchor.min);
}
MergeCarets(&view.carets, &view.selection_anchor);
}
} else if (!(mouse_in_view || window->mouse_selecting) && mouse_in_scrollbar || window->mouse_selecting_scrollbar) {
Scroller s = ComputeScrollerRect(*window);
double size_y = (double)GetSize(window->scrollbar_rect).y;
double p = _mouse.y - window->scrollbar_rect.min.y;
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
window->mouse_selecting_scrollbar = true;
} else if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
window->mouse_selecting_scrollbar = false;
}
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
if (_mouse.y < s.rect.min.y || _mouse.y > s.rect.max.y) {
view.scroll.y = (Int)(p / size_y * (double)s.line_count * (double)FontLineSpacing);
window->mouse_scroller_offset = -(double)GetSize(s.rect).y / 2.0 / size_y;
} else {
window->mouse_scroller_offset = (s.rect.min.y - p) / size_y;
}
}
if (window->mouse_selecting_scrollbar) {
double v = p / size_y;
v = v + (window->mouse_scroller_offset);
view.scroll.y = (Int)(v * (double)s.line_count * (double)FontLineSpacing);
}
}
}
// Scrolling with caret
if (!AreEqual(main_caret_on_begin_frame, view.carets[0]) && !dont_update_scroll) {
Caret c = view.carets[0];
Int front = GetFront(c);
XY xy = PosToXY(*buffer, front);
Rect2I visible = GetVisibleCells(*window);
Vec2I visible_cells = GetSize(visible);
Vec2I visible_size = visible_cells * Vec2I{FontCharSpacing, FontLineSpacing};
Vec2I rect_size = GetSize(window->document_rect);
if (xy.line > visible.max.y - 2) {
Int set_view_at_line = xy.line - (visible_cells.y - 1);
Int cut_off_y = Max((Int)0, visible_size.y - rect_size.y);
view.scroll.y = (set_view_at_line * FontLineSpacing) + cut_off_y;
}
if (xy.line < visible.min.y + 1) {
view.scroll.y = xy.line * FontLineSpacing;
}
// Scrolling with caret
if (!AreEqual(main_caret_on_begin_frame, view.carets[0]) && !dont_update_scroll) {
Caret c = view.carets[0];
Int front = GetFront(c);
XY xy = PosToXY(*buffer, front);
if (xy.col >= visible.max.x - 1) {
Int set_view_at_line = xy.col - (visible_cells.x - 1);
Int cut_off_x = Max((Int)0, visible_size.x - rect_size.x);
view.scroll.x = (set_view_at_line * FontCharSpacing) + cut_off_x;
}
Rect2I visible = GetVisibleCells(*window);
Vec2I visible_cells = GetSize(visible);
Vec2I visible_size = visible_cells * Vec2I{FontCharSpacing, FontLineSpacing};
Vec2I rect_size = GetSize(window->document_rect);
if (xy.col <= visible.min.x) {
view.scroll.x = xy.col * FontCharSpacing;
if (xy.line > visible.max.y - 2) {
Int set_view_at_line = xy.line - (visible_cells.y - 1);
Int cut_off_y = Max((Int)0, visible_size.y - rect_size.y);
view.scroll.y = (set_view_at_line * FontLineSpacing) + cut_off_y;
}
if (xy.line < visible.min.y + 1) {
view.scroll.y = xy.line * FontLineSpacing;
}
if (xy.col >= visible.max.x - 1) {
Int set_view_at_line = xy.col - (visible_cells.x - 1);
Int cut_off_x = Max((Int)0, visible_size.x - rect_size.x);
view.scroll.x = (set_view_at_line * FontCharSpacing) + cut_off_x;
}
if (xy.col <= visible.min.x) {
view.scroll.x = xy.col * FontCharSpacing;
}
}
}

View File

@@ -150,6 +150,7 @@ void DrawSelection(Window &window, Caret &it) {
void DrawWindow(Window &window) {
View &view = *GetActiveView(&window);
Buffer *buffer = GetBuffer(view.buffer_id);
DrawRectangleRec(ToRectangle(window.total_rect), ColorBackground);
BeginScissorMode((int)window.document_rect.min.x, (int)window.document_rect.min.y, (int)window.document_rect.max.x - (int)window.document_rect.min.x, (int)window.document_rect.max.y - (int)window.document_rect.min.y);
For(view.carets) {

View File

@@ -39,3 +39,11 @@ void SetMouseCursor() {
SetMouseCursor(MOUSE_CURSOR_POINTING_HAND);
}
}
Array<Int> GetWindowZOrder(Allocator allocator) {
Array<Int> order = {allocator};
For(Windows) if (it.z == 2) Add(&order, GetIndex(Windows, it));
For(Windows) if (it.z == 1) Add(&order, GetIndex(Windows, it));
For(Windows) if (it.z == 0) Add(&order, GetIndex(Windows, it));
return order;
}