Scrolling clip and global commands

This commit is contained in:
Krzosa Karol
2024-07-27 07:41:15 +02:00
parent 8117d043aa
commit 71494984de
4 changed files with 156 additions and 52 deletions

View File

@@ -184,12 +184,7 @@ Array<Range> FindAllInBuffer(Allocator allocator, Buffer *buffer, String16 needl
// void HandleGlobalCommands() {
// if (CtrlPress(KEY_P)) {
// Window *command_window = GetWindow(CommandWindowID);
// if (command_window->visible) {
// SetActiveWindow(GetLastActiveWindow());
// } else {
// SetActiveWindow(command_window->id);
// }
// }
// if (CtrlPress(KEY_F)) {
@@ -210,11 +205,4 @@ Array<Range> FindAllInBuffer(Allocator allocator, Buffer *buffer, String16 needl
// ReloadFont(font_size);
// }
// if (CtrlPress(KEY_ONE)) {
// SetActiveWindow({0});
// } else if (CtrlPress(KEY_TWO)) {
// SetActiveWindow({1});
// } else if (CtrlPress(KEY_THREE)) {
// SetActiveWindow({2});
// }
// }

View File

@@ -181,13 +181,13 @@ void Command_EvalLuaLine(View *view) {
Command_EvalLua(view, string);
}
void PrintDebugCarets(View *view, const char *msg) {
Buffer *null_buffer = GetBuffer(NullBufferID);
Appendf(null_buffer, "%s id: %d sel_anchor(%d, %d)\n", msg, view->caret_change_id, view->selection_anchor.min, view->selection_anchor.max);
For(view->carets) {
Appendf(null_buffer, " min: %lld max: %lld front: %d\n", (long long)it.range.min, (long long)it.range.max, it.ifront);
}
}
// void PrintDebugCarets(View *view, const char *msg) {
// Buffer *null_buffer = GetBuffer(NullBufferID);
// Appendf(null_buffer, "%s id: %d sel_anchor(%d, %d)\n", msg, view->caret_change_id, view->selection_anchor.min, view->selection_anchor.max);
// For(view->carets) {
// Appendf(null_buffer, " min: %lld max: %lld front: %d\n", (long long)it.range.min, (long long)it.range.max, it.ifront);
// }
// }
// Merge carets that overlap, this needs to be handled before any edits to
// make sure overlapping edits won't happen.
@@ -195,9 +195,7 @@ void PrintDebugCarets(View *view, const char *msg) {
// mouse_selection_anchor is special case for mouse handling !
void MergeCarets(View *view, Range *mouse_selection_anchor) {
ProfileFunction();
// PrintDebugCarets(view, "before");
view->caret_change_id = CaretChangeID++;
Buffer *buffer = GetBuffer(view->active_buffer);
For(view->carets) it.range = Clamp(*buffer, it.range);
Caret first_caret = view->carets.data[0];
@@ -224,8 +222,6 @@ void MergeCarets(View *view, Range *mouse_selection_anchor) {
}
Swap(&view->carets[first_caret_index], &view->carets[0]);
// PrintDebugCarets(view, "after");
}
void HandleActiveWindowBindings(Window *window, bool *update_scroll) {

View File

@@ -36,24 +36,81 @@
#include "lua_api.cpp"
bool AppIsRunning = true;
bool WaitForEvents = false;
bool WaitForEvents = true;
SDL_Cursor *SDL_MouseCursor = NULL;
struct Key {
SDL_Keycode code;
uint8_t shift;
uint8_t ctrl;
uint8_t alt;
uint8_t super;
};
void GlobalCommand(Key key) {
if (key.code == SDLK_F5) {
AppIsRunning = false;
}
if (key.ctrl && key.code == SDLK_P) {
Window *command_window = GetWindow(CommandWindowID);
if (command_window->visible) {
SetActiveWindow(GetLastActiveWindow());
} else {
SetActiveWindow(command_window->id);
}
}
if (key.ctrl && key.code == SDLK_F) {
Window *search_window = GetWindow(SearchWindowID);
if (search_window->visible) {
SetActiveWindow(GetLastActiveWindow());
} else {
SetActiveWindow(search_window->id);
}
}
if (key.ctrl && key.code == SDLK_1) {
SetActiveWindow({0});
}
if (key.ctrl && key.code == SDLK_2) {
SetActiveWindow({1});
}
if (key.ctrl && key.code == SDLK_3) {
SetActiveWindow({2});
}
}
void WindowCommand(Key key, Window *window, View *view) {
Buffer *buffer = GetBuffer(view->active_buffer);
if (key.code == SDLK_ESCAPE) {
if (window->deactivate_on_escape) {
SetActiveWindow(GetLastActiveWindow());
} else {
view->carets.len = 1;
}
}
}
void ProcessSDLEvent(SDL_Event *event) {
switch (event->type) {
case SDL_EVENT_QUIT: AppIsRunning = false; return;
case SDL_EVENT_KEY_DOWN: {
SDL_KeyboardEvent &key = event->key;
bool shift = key.mod & SDL_KMOD_SHIFT;
bool ctrl = key.mod & SDL_KMOD_CTRL;
bool alt = key.mod & SDL_KMOD_ALT;
bool super = key.mod & SDL_KMOD_GUI;
if (key.key == SDLK_F5) {
AppIsRunning = false;
return;
}
Key k = {key.key};
k.shift = key.mod & SDL_KMOD_SHIFT;
k.ctrl = key.mod & SDL_KMOD_CTRL;
k.alt = key.mod & SDL_KMOD_ALT;
k.super = key.mod & SDL_KMOD_GUI;
GlobalCommand(k);
Window *window = GetActiveWindow();
View *view = GetActiveView(window);
WindowCommand(k, window, view);
MergeCarets(view);
} break;
case SDL_EVENT_KEY_UP: {
SDL_KeyboardEvent &key = event->key;
@@ -66,6 +123,15 @@ void ProcessSDLEvent(SDL_Event *event) {
case SDL_EVENT_TEXT_INPUT: {
SDL_TextInputEvent &b = event->text;
Scratch scratch;
String string = b.text;
String16 string16 = ToString16(scratch, string);
Window *window = GetActiveWindow();
View *view = GetActiveView(window);
Command_Replace(view, string16);
// search = true;
} break;
case SDL_EVENT_MOUSE_MOTION: {
SDL_MouseMotionEvent &b = event->motion;
@@ -98,13 +164,6 @@ void ProcessSDLEvent(SDL_Event *event) {
For(order) {
Window *window = &Windows[it];
if (!window->visible) continue;
// view->main_caret_on_begin_frame = view->carets[0];
// if (window->invisible_when_inactive) {
// if (IsActive(window)) window->visible = true;
// else window->visible = false;
// }
bool mouse_in_window = CheckCollisionPointRec(mouse, window->total_rect);
if (mouse_in_window) {
Window *active_window = GetWindow(ActiveWindow);
@@ -183,6 +242,7 @@ int main()
return 1;
}
SDL_StartTextInput(window);
SDL_GL_SetSwapInterval(1); // vsync
InitRender();
InitLua();
@@ -214,6 +274,20 @@ int main()
BeginFrameRender();
LayoutWindows();
Scratch scratch;
Array<Int> order = GetWindowZOrder(scratch);
For(order) {
Window *window = &Windows[it];
if (window->invisible_when_inactive) {
if (IsActive(window)) window->visible = true;
else window->visible = false;
}
if (!window->visible) continue;
View *view = GetActiveView(window);
view->main_caret_on_begin_frame = view->carets[0];
view->update_scroll = true;
}
SDL_Event event;
if (WaitForEvents) {
SDL_WaitEvent(&event);
@@ -224,16 +298,63 @@ int main()
}
ReplaceInfobarData();
Scratch scratch;
Array<Int> order = GetWindowZOrder(scratch);
For(order) {
Window *window = &Windows[it];
if (!window->visible) continue;
View *view = GetActiveView(window);
Buffer *buffer = GetBuffer(view->active_buffer);
// Scrolling with caret
if (!AreEqual(view->main_caret_on_begin_frame, view->carets[0]) && view->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;
}
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;
}
}
// Clip scroll
{
ProfileScope(clip_scroll);
Int last_line = LastLine(*buffer);
view->scroll.y = Clamp(view->scroll.y, (Int)0, Max((Int)0, (last_line)*FontLineSpacing));
// @note:
// GetCharCountOfLongestLine is a bottleneck, there is probably an algorithm for
// calculating this value incrementally but do we even need X scrollbar or x clipping?
view->scroll.x = ClampBottom(view->scroll.x, (Int)0);
}
}
For(IterateInReverse(&order)) {
Window &window = Windows[it];
if (window.visible) {
if (!window.visible) continue;
// HandleWindowBindings(&window);
DrawWindow(window);
}
}
// {
// Scratch scratch;
// uint64_t ms = SDL_GetTicks();

View File

@@ -42,13 +42,12 @@ struct View {
ViewID id;
BufferID active_buffer;
Vec2I scroll;
Int caret_change_id; // @debug
Array<Caret> carets;
// window | view
Range selection_anchor;
Caret main_caret_on_begin_frame;
bool update_scroll;
};
struct Window {