Z ordering, prep for command window
This commit is contained in:
@@ -18,8 +18,9 @@ Vec2 GetSizeF(Rect2I r) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2 ToVec2(Vec2I v) { return {(float)v.x, (float)v.y}; }
|
Vec2 ToVec2(Vec2I v) { return {(float)v.x, (float)v.y}; }
|
||||||
Vec2I ToVec2I(Vec2 v) { return {(Int)v.x, (Int)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
|
// 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 }; }
|
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 }; }
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ Rect2I GetScreenRect() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rect2 GetScreenRectF() {
|
||||||
|
Rect2 result = {0, 0, (float)GetRenderWidth(), (float)GetRenderHeight()};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Int GetCharSpacing(Font font, Int font_size, Int spacing) {
|
Int GetCharSpacing(Font font, Int font_size, Int spacing) {
|
||||||
int index = GetGlyphIndex(font, '_');
|
int index = GetGlyphIndex(font, '_');
|
||||||
Int textOffsetX = 0;
|
Int textOffsetX = 0;
|
||||||
|
|||||||
@@ -96,9 +96,22 @@ int main(void) {
|
|||||||
LoadLine(b);
|
LoadLine(b);
|
||||||
AddView(w->id, v->id);
|
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()) {
|
while (!WindowShouldClose()) {
|
||||||
ProfileScope(game_loop);
|
ProfileScope(game_loop);
|
||||||
|
FrameID += 1;
|
||||||
|
|
||||||
Rect2I screen_rect = GetScreenRect();
|
Rect2I screen_rect = GetScreenRect();
|
||||||
float line_numbers_size = MeasureTextEx(MainFont, "12345", (float)FontSize, (float)FontSpacing).x;
|
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_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);
|
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();
|
BeginDrawing();
|
||||||
ClearBackground(ColorBackground);
|
ClearBackground(ColorBackground);
|
||||||
For(Windows) {
|
|
||||||
if (!it.visible) continue;
|
Scratch scratch;
|
||||||
HandleKeybindings(&it);
|
Array<Int> order = GetWindowZOrder(scratch);
|
||||||
DrawWindow(it);
|
|
||||||
|
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();
|
SetMouseCursor();
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ struct Window {
|
|||||||
Rect2I document_rect;
|
Rect2I document_rect;
|
||||||
|
|
||||||
double mouse_scroller_offset;
|
double mouse_scroller_offset;
|
||||||
|
int z;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
bool mouse_selecting_scrollbar : 1;
|
bool mouse_selecting_scrollbar : 1;
|
||||||
@@ -99,6 +100,8 @@ Int FontSpacing;
|
|||||||
Int FontLineSpacing;
|
Int FontLineSpacing;
|
||||||
Int FontCharSpacing;
|
Int FontCharSpacing;
|
||||||
|
|
||||||
|
Int FrameID;
|
||||||
|
|
||||||
inline Window *GetWindow(WindowID id) {
|
inline Window *GetWindow(WindowID id) {
|
||||||
For(Windows) if (it.id.id == id.id) return ⁢
|
For(Windows) if (it.id.id == id.id) return ⁢
|
||||||
return &Windows[0];
|
return &Windows[0];
|
||||||
|
|||||||
@@ -118,319 +118,298 @@ void HandleKeybindings(Window *window) {
|
|||||||
Buffer *buffer = GetBuffer(view.buffer_id);
|
Buffer *buffer = GetBuffer(view.buffer_id);
|
||||||
Caret main_caret_on_begin_frame = view.carets[0];
|
Caret main_caret_on_begin_frame = view.carets[0];
|
||||||
|
|
||||||
{
|
if (IsActive(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 (CtrlPress(KEY_F2)) {
|
||||||
if (IsKeyDown(KEY_F1)) {
|
LoadBigLine(buffer);
|
||||||
view.scroll.x -= (Int)(GetMouseWheelMove() * 48);
|
} else if (Press(KEY_F2)) {
|
||||||
} else {
|
LoadBigText(buffer);
|
||||||
view.scroll.y -= (Int)(GetMouseWheelMove() * 48);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsActive(window)) {
|
if (Press(KEY_ESCAPE)) {
|
||||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
|
view.carets.len = 1;
|
||||||
ActiveWindow = window->id;
|
}
|
||||||
|
|
||||||
|
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)) {
|
if (CtrlAltPress(KEY_UP)) {
|
||||||
return;
|
Command_DuplicateLine(&view, DIR_UP);
|
||||||
}
|
} else if (AltShiftPress(KEY_UP)) {
|
||||||
|
Command_CreateCursorVertical(&view, DIR_UP);
|
||||||
if (CtrlPress(KEY_F2)) {
|
} else if (CtrlShiftPress(KEY_UP)) {
|
||||||
LoadBigLine(buffer);
|
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_UP, CTRL_PRESSED));
|
||||||
} else if (Press(KEY_F2)) {
|
} else if (CtrlPress(KEY_UP)) {
|
||||||
LoadBigText(buffer);
|
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));
|
||||||
if (Press(KEY_ESCAPE)) {
|
} else if (Press(KEY_UP)) {
|
||||||
view.carets.len = 1;
|
For(view.carets) {
|
||||||
}
|
if (GetSize(it.range) == 0) {
|
||||||
|
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_UP));
|
||||||
if (CtrlAltPress(KEY_DOWN)) {
|
} else {
|
||||||
Command_DuplicateLine(&view, DIR_DOWN);
|
it = MakeCaret(it.range.min);
|
||||||
} 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)) {
|
if (CtrlShiftPress(KEY_LEFT)) {
|
||||||
Command_DuplicateLine(&view, DIR_UP);
|
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_LEFT, true));
|
||||||
} else if (AltShiftPress(KEY_UP)) {
|
} else if (CtrlPress(KEY_LEFT)) {
|
||||||
Command_CreateCursorVertical(&view, DIR_UP);
|
For(view.carets) {
|
||||||
} else if (CtrlShiftPress(KEY_UP)) {
|
if (GetSize(it.range) != 0 && GetFront(it) != it.range.min) {
|
||||||
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_UP, CTRL_PRESSED));
|
it = MakeCaret(it.range.min);
|
||||||
} else if (CtrlPress(KEY_UP)) {
|
} else {
|
||||||
For(view.carets) it = MakeCaret(MovePos(*buffer, it.range.min, DIR_UP, CTRL_PRESSED));
|
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_LEFT, true));
|
||||||
} else if (ShiftPress(KEY_UP)) {
|
}
|
||||||
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_UP));
|
}
|
||||||
} else if (Press(KEY_UP)) {
|
} else if (ShiftPress(KEY_LEFT)) {
|
||||||
For(view.carets) {
|
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_LEFT, false));
|
||||||
if (GetSize(it.range) == 0) {
|
} else if (Press(KEY_LEFT)) {
|
||||||
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_UP));
|
For(view.carets) {
|
||||||
} else {
|
if (GetSize(it.range) == 0) {
|
||||||
it = MakeCaret(it.range.min);
|
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_LEFT, false));
|
||||||
|
} else {
|
||||||
|
it = MakeCaret(it.range.min);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (CtrlShiftPress(KEY_LEFT)) {
|
if (CtrlShiftPress(KEY_RIGHT)) {
|
||||||
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_LEFT, true));
|
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_RIGHT, true));
|
||||||
} else if (CtrlPress(KEY_LEFT)) {
|
} else if (CtrlPress(KEY_RIGHT)) {
|
||||||
For(view.carets) {
|
For(view.carets) {
|
||||||
if (GetSize(it.range) != 0 && GetFront(it) != it.range.min) {
|
if (GetSize(it.range) != 0 && GetFront(it) != it.range.max) {
|
||||||
it = MakeCaret(it.range.min);
|
it = MakeCaret(it.range.max);
|
||||||
} else {
|
} else {
|
||||||
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_LEFT, true));
|
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)) {
|
if (CtrlPress(KEY_D)) {
|
||||||
For(view.carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_RIGHT, true));
|
Range range = view.carets[0].range;
|
||||||
} else if (CtrlPress(KEY_RIGHT)) {
|
String16 string = GetString(*buffer, range);
|
||||||
For(view.carets) {
|
String16 string_buffer = GetString(*buffer, {range.max, INT64_MAX});
|
||||||
if (GetSize(it.range) != 0 && GetFront(it) != it.range.max) {
|
Int index = 0;
|
||||||
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 (Seek(string_buffer, string, &index)) {
|
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)) {
|
if (CtrlShiftPress(KEY_Z)) {
|
||||||
RedoEdit(buffer, &view.carets);
|
RedoEdit(buffer, &view.carets);
|
||||||
} else if (CtrlPress(KEY_Z)) {
|
} else if (CtrlPress(KEY_Z)) {
|
||||||
UndoEdit(buffer, &view.carets);
|
UndoEdit(buffer, &view.carets);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CtrlPress(KEY_C)) {
|
if (CtrlPress(KEY_C)) {
|
||||||
Command_Copy(&view);
|
Command_Copy(&view);
|
||||||
} else if (CtrlPress(KEY_V)) {
|
} else if (CtrlPress(KEY_V)) {
|
||||||
Command_Paste(&view);
|
Command_Paste(&view);
|
||||||
} else if (CtrlPress(KEY_X)) {
|
} else if (CtrlPress(KEY_X)) {
|
||||||
Command_Copy(&view);
|
Command_Copy(&view);
|
||||||
Command_Replace(&view, L"");
|
Command_Replace(&view, L"");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dont_update_scroll = false;
|
bool dont_update_scroll = false;
|
||||||
if (CtrlPress(KEY_A)) {
|
if (CtrlPress(KEY_A)) {
|
||||||
view.carets.len = 1;
|
view.carets.len = 1;
|
||||||
view.carets[0] = MakeCaret(0, buffer->len);
|
view.carets[0] = MakeCaret(0, buffer->len);
|
||||||
dont_update_scroll = true;
|
dont_update_scroll = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ShiftPress(KEY_PAGE_UP)) {
|
if (ShiftPress(KEY_PAGE_UP)) {
|
||||||
Command_MoveCursorsByPageSize(window, DIR_UP, SHIFT_PRESSED);
|
Command_MoveCursorsByPageSize(window, DIR_UP, SHIFT_PRESSED);
|
||||||
} else if (Press(KEY_PAGE_UP)) {
|
} else if (Press(KEY_PAGE_UP)) {
|
||||||
Command_MoveCursorsByPageSize(window, DIR_UP);
|
Command_MoveCursorsByPageSize(window, DIR_UP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ShiftPress(KEY_PAGE_DOWN)) {
|
if (ShiftPress(KEY_PAGE_DOWN)) {
|
||||||
Command_MoveCursorsByPageSize(window, DIR_DOWN, SHIFT_PRESSED);
|
Command_MoveCursorsByPageSize(window, DIR_DOWN, SHIFT_PRESSED);
|
||||||
} else if (Press(KEY_PAGE_DOWN)) {
|
} else if (Press(KEY_PAGE_DOWN)) {
|
||||||
Command_MoveCursorsByPageSize(window, DIR_DOWN);
|
Command_MoveCursorsByPageSize(window, DIR_DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ShiftPress(KEY_HOME)) {
|
if (ShiftPress(KEY_HOME)) {
|
||||||
Command_MoveCursorsToSide(window, DIR_LEFT, SHIFT_PRESSED);
|
Command_MoveCursorsToSide(window, DIR_LEFT, SHIFT_PRESSED);
|
||||||
} else if (Press(KEY_HOME)) {
|
} else if (Press(KEY_HOME)) {
|
||||||
Command_MoveCursorsToSide(window, DIR_LEFT);
|
Command_MoveCursorsToSide(window, DIR_LEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ShiftPress(KEY_END)) {
|
if (ShiftPress(KEY_END)) {
|
||||||
Command_MoveCursorsToSide(window, DIR_RIGHT, SHIFT_PRESSED);
|
Command_MoveCursorsToSide(window, DIR_RIGHT, SHIFT_PRESSED);
|
||||||
} else if (Press(KEY_END)) {
|
} else if (Press(KEY_END)) {
|
||||||
Command_MoveCursorsToSide(window, DIR_RIGHT);
|
Command_MoveCursorsToSide(window, DIR_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Press(KEY_ENTER)) {
|
if (Press(KEY_ENTER)) {
|
||||||
Command_Replace(&view, L"\n");
|
Command_Replace(&view, L"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Press(KEY_TAB)) {
|
if (Press(KEY_TAB)) {
|
||||||
Command_Replace(&view, L" ");
|
Command_Replace(&view, L" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CtrlPress(KEY_BACKSPACE)) {
|
if (CtrlPress(KEY_BACKSPACE)) {
|
||||||
Command_Delete(&view, DIR_LEFT, CTRL_PRESSED);
|
Command_Delete(&view, DIR_LEFT, CTRL_PRESSED);
|
||||||
} else if (Press(KEY_BACKSPACE)) {
|
} else if (Press(KEY_BACKSPACE)) {
|
||||||
Command_Delete(&view, DIR_LEFT);
|
Command_Delete(&view, DIR_LEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CtrlPress(KEY_DELETE)) {
|
if (CtrlPress(KEY_DELETE)) {
|
||||||
Command_Delete(&view, DIR_RIGHT, CTRL_PRESSED);
|
Command_Delete(&view, DIR_RIGHT, CTRL_PRESSED);
|
||||||
} else if (Press(KEY_DELETE)) {
|
} else if (Press(KEY_DELETE)) {
|
||||||
Command_Delete(&view, DIR_RIGHT);
|
Command_Delete(&view, DIR_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int c = GetCharPressed(); c; c = GetCharPressed()) {
|
for (int c = GetCharPressed(); c; c = GetCharPressed()) {
|
||||||
// we interpret 2 byte sequences as 1 byte when rendering but we still
|
// we interpret 2 byte sequences as 1 byte when rendering but we still
|
||||||
// want to read them properly.
|
// want to read them properly.
|
||||||
String16 string = L"?";
|
String16 string = L"?";
|
||||||
UTF16Result result = UTF32ToUTF16((uint32_t)c);
|
UTF16Result result = UTF32ToUTF16((uint32_t)c);
|
||||||
if (!result.error) string = {(wchar_t *)result.out_str, result.len};
|
if (!result.error) string = {(wchar_t *)result.out_str, result.len};
|
||||||
Command_Replace(&view, string);
|
Command_Replace(&view, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ProfileScope(mouse);
|
ProfileScope(mouse);
|
||||||
|
|
||||||
Vec2 _mouse = GetMousePosition();
|
Vec2 _mouse = GetMousePosition();
|
||||||
bool mouse_in_view = CheckCollisionPointRec(_mouse, ToRectangle(window->document_rect));
|
bool mouse_in_view = CheckCollisionPointRec(_mouse, ToRectangle(window->document_rect));
|
||||||
bool mouse_in_scrollbar = CheckCollisionPointRec(_mouse, ToRectangle(window->scrollbar_rect));
|
bool mouse_in_scrollbar = CheckCollisionPointRec(_mouse, ToRectangle(window->scrollbar_rect));
|
||||||
Vec2I mouse = ToVec2I(_mouse);
|
Vec2I mouse = ToVec2I(_mouse);
|
||||||
|
|
||||||
if (!(mouse_in_scrollbar || window->mouse_selecting_scrollbar) && (mouse_in_view || window->mouse_selecting)) {
|
if (!(mouse_in_scrollbar || window->mouse_selecting_scrollbar) && (mouse_in_view || window->mouse_selecting)) {
|
||||||
Vec2I mworld = mouse - window->document_rect.min + view.scroll;
|
Vec2I mworld = mouse - window->document_rect.min + view.scroll;
|
||||||
Vec2I pos = mworld / Vec2I{FontCharSpacing, FontLineSpacing};
|
Vec2I pos = mworld / Vec2I{FontCharSpacing, FontLineSpacing};
|
||||||
XY xy = {(Int)(pos.x), (Int)(pos.y)};
|
XY xy = {(Int)(pos.x), (Int)(pos.y)};
|
||||||
Int p = XYToPosWithoutNL(*buffer, xy);
|
Int p = XYToPosWithoutNL(*buffer, xy);
|
||||||
|
|
||||||
if (mouse_in_view && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
|
if (mouse_in_view && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
|
||||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
|
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
|
||||||
if (IsDoubleClick()) {
|
if (IsDoubleClick()) {
|
||||||
Caret *c = GetLast(view.carets);
|
Caret *c = GetLast(view.carets);
|
||||||
if (InBounds({c->range.min - 1, c->range.max + 1}, p)) {
|
if (InBounds({c->range.min - 1, c->range.max + 1}, p)) {
|
||||||
c->range = EncloseWord(*buffer, p);
|
c->range = EncloseWord(*buffer, p);
|
||||||
view.selection_anchor = c->range;
|
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)) {
|
MergeCarets(&view.carets);
|
||||||
view.carets.len = 0;
|
} else if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
|
||||||
}
|
window->mouse_selecting = true;
|
||||||
Add(&view.carets, MakeCaret(p, p));
|
|
||||||
view.selection_anchor = GetLast(view.carets)->range;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MergeCarets(&view.carets);
|
if (window->mouse_selecting) {
|
||||||
} else if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
|
if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)) window->mouse_selecting = false;
|
||||||
window->mouse_selecting = true;
|
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) {
|
// Scrolling with caret
|
||||||
view.scroll.y = xy.line * FontLineSpacing;
|
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) {
|
Rect2I visible = GetVisibleCells(*window);
|
||||||
Int set_view_at_line = xy.col - (visible_cells.x - 1);
|
Vec2I visible_cells = GetSize(visible);
|
||||||
Int cut_off_x = Max((Int)0, visible_size.x - rect_size.x);
|
Vec2I visible_size = visible_cells * Vec2I{FontCharSpacing, FontLineSpacing};
|
||||||
view.scroll.x = (set_view_at_line * FontCharSpacing) + cut_off_x;
|
Vec2I rect_size = GetSize(window->document_rect);
|
||||||
}
|
|
||||||
|
|
||||||
if (xy.col <= visible.min.x) {
|
if (xy.line > visible.max.y - 2) {
|
||||||
view.scroll.x = xy.col * FontCharSpacing;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ void DrawSelection(Window &window, Caret &it) {
|
|||||||
void DrawWindow(Window &window) {
|
void DrawWindow(Window &window) {
|
||||||
View &view = *GetActiveView(&window);
|
View &view = *GetActiveView(&window);
|
||||||
Buffer *buffer = GetBuffer(view.buffer_id);
|
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);
|
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) {
|
For(view.carets) {
|
||||||
|
|||||||
@@ -39,3 +39,11 @@ void SetMouseCursor() {
|
|||||||
SetMouseCursor(MOUSE_CURSOR_POINTING_HAND);
|
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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user