Scrolling clip and global commands
This commit is contained in:
@@ -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});
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
SDL_KeyboardEvent &key = event->key;
|
||||
|
||||
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,15 +298,62 @@ 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) {
|
||||
// HandleWindowBindings(&window);
|
||||
DrawWindow(window);
|
||||
}
|
||||
if (!window.visible) continue;
|
||||
// HandleWindowBindings(&window);
|
||||
DrawWindow(window);
|
||||
}
|
||||
// {
|
||||
// Scratch scratch;
|
||||
|
||||
@@ -39,16 +39,15 @@ struct Buffer {
|
||||
};
|
||||
|
||||
struct View {
|
||||
ViewID id;
|
||||
BufferID active_buffer;
|
||||
Vec2I scroll;
|
||||
|
||||
Int caret_change_id; // @debug
|
||||
ViewID id;
|
||||
BufferID active_buffer;
|
||||
Vec2I scroll;
|
||||
Array<Caret> carets;
|
||||
|
||||
// window | view
|
||||
Range selection_anchor;
|
||||
Caret main_caret_on_begin_frame;
|
||||
bool update_scroll;
|
||||
};
|
||||
|
||||
struct Window {
|
||||
|
||||
Reference in New Issue
Block a user