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() {
|
// void HandleGlobalCommands() {
|
||||||
// if (CtrlPress(KEY_P)) {
|
// if (CtrlPress(KEY_P)) {
|
||||||
// Window *command_window = GetWindow(CommandWindowID);
|
|
||||||
// if (command_window->visible) {
|
|
||||||
// SetActiveWindow(GetLastActiveWindow());
|
|
||||||
// } else {
|
|
||||||
// SetActiveWindow(command_window->id);
|
|
||||||
// }
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if (CtrlPress(KEY_F)) {
|
// if (CtrlPress(KEY_F)) {
|
||||||
@@ -210,11 +205,4 @@ Array<Range> FindAllInBuffer(Allocator allocator, Buffer *buffer, String16 needl
|
|||||||
// ReloadFont(font_size);
|
// 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);
|
Command_EvalLua(view, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintDebugCarets(View *view, const char *msg) {
|
// void PrintDebugCarets(View *view, const char *msg) {
|
||||||
Buffer *null_buffer = GetBuffer(NullBufferID);
|
// 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);
|
// 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) {
|
// 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);
|
// 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
|
// Merge carets that overlap, this needs to be handled before any edits to
|
||||||
// make sure overlapping edits won't happen.
|
// 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 !
|
// mouse_selection_anchor is special case for mouse handling !
|
||||||
void MergeCarets(View *view, Range *mouse_selection_anchor) {
|
void MergeCarets(View *view, Range *mouse_selection_anchor) {
|
||||||
ProfileFunction();
|
ProfileFunction();
|
||||||
// PrintDebugCarets(view, "before");
|
|
||||||
|
|
||||||
view->caret_change_id = CaretChangeID++;
|
|
||||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||||
For(view->carets) it.range = Clamp(*buffer, it.range);
|
For(view->carets) it.range = Clamp(*buffer, it.range);
|
||||||
Caret first_caret = view->carets.data[0];
|
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]);
|
Swap(&view->carets[first_caret_index], &view->carets[0]);
|
||||||
|
|
||||||
// PrintDebugCarets(view, "after");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleActiveWindowBindings(Window *window, bool *update_scroll) {
|
void HandleActiveWindowBindings(Window *window, bool *update_scroll) {
|
||||||
|
|||||||
@@ -36,24 +36,81 @@
|
|||||||
#include "lua_api.cpp"
|
#include "lua_api.cpp"
|
||||||
|
|
||||||
bool AppIsRunning = true;
|
bool AppIsRunning = true;
|
||||||
bool WaitForEvents = false;
|
bool WaitForEvents = true;
|
||||||
SDL_Cursor *SDL_MouseCursor = NULL;
|
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) {
|
void ProcessSDLEvent(SDL_Event *event) {
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case SDL_EVENT_QUIT: AppIsRunning = false; return;
|
case SDL_EVENT_QUIT: AppIsRunning = false; return;
|
||||||
case SDL_EVENT_KEY_DOWN: {
|
case SDL_EVENT_KEY_DOWN: {
|
||||||
SDL_KeyboardEvent &key = event->key;
|
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) {
|
Key k = {key.key};
|
||||||
AppIsRunning = false;
|
k.shift = key.mod & SDL_KMOD_SHIFT;
|
||||||
return;
|
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;
|
} break;
|
||||||
case SDL_EVENT_KEY_UP: {
|
case SDL_EVENT_KEY_UP: {
|
||||||
SDL_KeyboardEvent &key = event->key;
|
SDL_KeyboardEvent &key = event->key;
|
||||||
@@ -66,6 +123,15 @@ void ProcessSDLEvent(SDL_Event *event) {
|
|||||||
case SDL_EVENT_TEXT_INPUT: {
|
case SDL_EVENT_TEXT_INPUT: {
|
||||||
SDL_TextInputEvent &b = event->text;
|
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;
|
} break;
|
||||||
case SDL_EVENT_MOUSE_MOTION: {
|
case SDL_EVENT_MOUSE_MOTION: {
|
||||||
SDL_MouseMotionEvent &b = event->motion;
|
SDL_MouseMotionEvent &b = event->motion;
|
||||||
@@ -98,13 +164,6 @@ void ProcessSDLEvent(SDL_Event *event) {
|
|||||||
For(order) {
|
For(order) {
|
||||||
Window *window = &Windows[it];
|
Window *window = &Windows[it];
|
||||||
if (!window->visible) continue;
|
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);
|
bool mouse_in_window = CheckCollisionPointRec(mouse, window->total_rect);
|
||||||
if (mouse_in_window) {
|
if (mouse_in_window) {
|
||||||
Window *active_window = GetWindow(ActiveWindow);
|
Window *active_window = GetWindow(ActiveWindow);
|
||||||
@@ -183,6 +242,7 @@ int main()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_StartTextInput(window);
|
||||||
SDL_GL_SetSwapInterval(1); // vsync
|
SDL_GL_SetSwapInterval(1); // vsync
|
||||||
InitRender();
|
InitRender();
|
||||||
InitLua();
|
InitLua();
|
||||||
@@ -214,6 +274,20 @@ int main()
|
|||||||
BeginFrameRender();
|
BeginFrameRender();
|
||||||
LayoutWindows();
|
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;
|
SDL_Event event;
|
||||||
if (WaitForEvents) {
|
if (WaitForEvents) {
|
||||||
SDL_WaitEvent(&event);
|
SDL_WaitEvent(&event);
|
||||||
@@ -224,15 +298,62 @@ int main()
|
|||||||
}
|
}
|
||||||
ReplaceInfobarData();
|
ReplaceInfobarData();
|
||||||
|
|
||||||
Scratch scratch;
|
For(order) {
|
||||||
Array<Int> order = GetWindowZOrder(scratch);
|
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)) {
|
For(IterateInReverse(&order)) {
|
||||||
Window &window = Windows[it];
|
Window &window = Windows[it];
|
||||||
if (window.visible) {
|
if (!window.visible) continue;
|
||||||
// HandleWindowBindings(&window);
|
// HandleWindowBindings(&window);
|
||||||
DrawWindow(window);
|
DrawWindow(window);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// {
|
// {
|
||||||
// Scratch scratch;
|
// Scratch scratch;
|
||||||
|
|||||||
@@ -39,16 +39,15 @@ struct Buffer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct View {
|
struct View {
|
||||||
ViewID id;
|
ViewID id;
|
||||||
BufferID active_buffer;
|
BufferID active_buffer;
|
||||||
Vec2I scroll;
|
Vec2I scroll;
|
||||||
|
|
||||||
Int caret_change_id; // @debug
|
|
||||||
Array<Caret> carets;
|
Array<Caret> carets;
|
||||||
|
|
||||||
// window | view
|
// window | view
|
||||||
Range selection_anchor;
|
Range selection_anchor;
|
||||||
Caret main_caret_on_begin_frame;
|
Caret main_caret_on_begin_frame;
|
||||||
|
bool update_scroll;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Window {
|
struct Window {
|
||||||
|
|||||||
Reference in New Issue
Block a user