Toying with structure, using #if instead of #ifdef because of name checking

This commit is contained in:
Krzosa Karol
2026-01-16 21:31:50 +01:00
parent dcda334767
commit d5c3794a93
20 changed files with 218 additions and 209 deletions

View File

@@ -1483,7 +1483,7 @@ Buffer *BufferOpenFile(String path) {
buffer = CreateBuffer(sys_allocator, path);
} else if (IsDir(path)) {
buffer = CreateBuffer(sys_allocator, path);
#ifdef PLUGIN_DIRECTORY_NAVIGATION
#if PLUGIN_DIRECTORY_NAVIGATION
buffer->is_dir = true;
buffer->temp = true;
#endif
@@ -1513,7 +1513,7 @@ bool BufferIsReferenced(BufferID buffer_id) {
void ReopenBuffer(Buffer *buffer) {
Scratch scratch;
#ifdef PLUGIN_DIRECTORY_NAVIGATION
#if PLUGIN_DIRECTORY_NAVIGATION
if (buffer->is_dir) { InsertDirectoryNavigation(buffer); return; }
#endif

View File

@@ -20,7 +20,7 @@ BSet GetConsoleSet() {
}
String GetDir(Buffer *buffer) {
#ifdef PLUGIN_DIRECTORY_NAVIGATION
#if PLUGIN_DIRECTORY_NAVIGATION
if (buffer->is_dir) {
return buffer->name;
}
@@ -232,19 +232,6 @@ void ReportWarningf(const char *fmt, ...) {
Appendf(null_view, "%S\n", string);
}
void CenterView(WindowID window) {
BSet set = GetBSet(window);
Caret c = set.view->carets[0];
Int front = GetFront(c);
XY xy = PosToXY(set.buffer, front);
Vec2I size = GetSize(set.window->document_rect);
Int y = size.y / 2 / set.window->font->line_spacing;
set.view->scroll.x = 0;
if (xy.line > y) {
set.view->scroll.y = (xy.line) * set.window->font->line_spacing - (size.y / 2);
}
}
void CMD_CenterView() {
CenterView(PrimaryWindowID);
} RegisterCommand(CMD_CenterView, "");
@@ -569,7 +556,7 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) {
return result;
} else {
#ifdef PLUGIN_PROJECT_MANAGEMENT
#if PLUGIN_PROJECT_MANAGEMENT
String workspace_path = Format(alo, "%S/%S", ProjectDirectory, path);
bool existing_buffer = GetBuffer(workspace_path, NULL);
if (existing_buffer || FileExists(workspace_path)) {
@@ -611,7 +598,7 @@ BSet Open(Window *window, String path, ResolveOpenMeta meta, bool set_active = t
}
View *view = WindowOpenBufferView(set.window, o.path);
if (IsDir(o.path)) {
#ifdef PLUGIN_DIRECTORY_NAVIGATION
#if PLUGIN_DIRECTORY_NAVIGATION
OpenDirectoryNavigation(view);
#endif
} else {
@@ -973,7 +960,7 @@ void Coro_ReplaceAll(mco_coro *co) {
if (buffer->special || buffer->temp || buffer->dont_try_to_save_in_bulk_ops) {
continue;
}
#ifdef PLUGIN_DIRECTORY_NAVIGATION
#if PLUGIN_DIRECTORY_NAVIGATION
if (buffer->is_dir) {
continue;
}

View File

@@ -407,7 +407,7 @@ void Set(String string) {
ReloadFont(PathToFont, (U32)FontSize);
}
#ifdef PLUGIN_PROJECT_MANAGEMENT
#if PLUGIN_PROJECT_MANAGEMENT
if (name == "ProjectDirectory") {
SetProjectDirectory(*var->string);
}

View File

@@ -263,7 +263,7 @@ void DrawWindow(Window *window, Event &event) {
}
}
#ifdef PLUGIN_SEARCH_WINDOW
#if PLUGIN_SEARCH_WINDOW
if (SearchWindowID == window->id) {
SetScissor(window->line_numbers_rect);
DrawString(window->font, u"Find: ", ToVec2(window->line_numbers_rect.min), color_text_line_numbers);

View File

@@ -33,7 +33,7 @@ BufferID NullBufferID;
ViewID NullViewID;
WindowID NullWindowID;
#ifdef PLUGIN_SEARCH_WINDOW
#if PLUGIN_SEARCH_WINDOW
WindowID SearchWindowID;
ViewID SearchViewID;
BufferID SearchBufferID;
@@ -155,7 +155,6 @@ RegisterVariable(Int, IndentSize, 4);
RegisterVariable(String, IndentKindWhichIsTabsOrSpaces, "spaces");
RegisterVariable(Int, FontSize, 15);
RegisterVariable(String, PathToFont, "");
RegisterVariable(String, WindowsVCVarsPathToLoadDevEnviroment, "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat");
RegisterVariable(Float, UndoMergeTime, 0.3);
RegisterVariable(Float, JumpHistoryMergeTime, 0.3);
RegisterVariable(String, InternetBrowser, "firefox");
@@ -167,6 +166,9 @@ RegisterVariable(Int, TrimTrailingWhitespace, 1);
// Set at the beginning of the program to current directory
RegisterVariable(String, ProjectDirectory, "");
// PLUGIN_LOAD_VCVARS
RegisterVariable(String, VCVarsPath, "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat");
// PLUGIN_REMEDYBG
RegisterVariable(String, BinaryUnderDebug, "build/te.exe");
RegisterVariable(String, RemedyBGPath, "remedybg.exe");

View File

@@ -1,4 +1,3 @@
#define PLUGIN_BUILD_WINDOW
WindowID BuildWindowID;
ViewID BuildViewID;
BufferID BuildBufferID;

View File

@@ -1,4 +1,3 @@
#define PLUGIN_COMMAND_WINDOW
WindowID CommandWindowID;
void CMD_ShowCommands() {
@@ -39,7 +38,7 @@ void CMD_ShowDebugBufferList() {
ResetBuffer(command_bar.buffer);
For (Buffers) {
bool is_special = it->special || it->temp || it->dont_try_to_save_in_bulk_ops;
#ifdef PLUGIN_DIRECTORY_NAVIGATION
#if PLUGIN_DIRECTORY_NAVIGATION
is_special |= it->is_dir;
#endif
if (!is_special) {
@@ -63,7 +62,7 @@ void CMD_ShowBufferList() {
ResetBuffer(command_bar.buffer);
For (Buffers) {
bool is_special = it->special || it->temp || it->dont_try_to_save_in_bulk_ops;
#ifdef PLUGIN_DIRECTORY_NAVIGATION
#if PLUGIN_DIRECTORY_NAVIGATION
is_special |= it->is_dir;
#endif
if (is_special) {

View File

@@ -1,4 +1,3 @@
#define PLUGIN_DEBUG_WINDOW
WindowID DebugWindowID;
ViewID DebugViewID;
BufferID DebugBufferID;

View File

@@ -1,3 +1,2 @@
#define PLUGIN_DIRECTORY_NAVIGATION
void InsertDirectoryNavigation(struct Buffer *buffer);
void OpenDirectoryNavigation(struct View *view);

View File

@@ -0,0 +1,35 @@
void Windows_SetupVCVarsall(mco_coro *co) {
View *view = NULL;
{
Scratch scratch;
String working_dir = ProjectDirectory;
String buffer_name = GetUniqueBufferName(working_dir, "vcvarsall-");
String cmd = Format(scratch, "\"%S\" && set", VCVarsPath);
view = ExecHidden(buffer_name, cmd, working_dir);
}
for (;;) {
if (!ProcessIsActive(view->id)) {
break;
}
CoYield(co);
}
Scratch scratch;
Buffer *buffer = GetBuffer(view->active_buffer);
String16 string16 = GetString(buffer);
String string = ToString(scratch, string16);
Array<String> lines = Split(scratch, string, "\n");
For (lines) {
String s = Trim(it);
Array<String> values = Split(scratch, s, "=");
if (values.len == 1) continue;
Add(&ProcessEnviroment, Copy(GetSystemAllocator(), s));
}
}
void LoadVCVars() {
CoRemove("Windows_SetupVCVarsall");
CoData *co_data = CoAdd(Windows_SetupVCVarsall);
co_data->dont_wait_until_resolved = true;
CoResume(co_data);
}

View File

@@ -1,3 +1 @@
#define PLUGIN_PROJECT_MANAGEMENT
void SetProjectDirectory(String name);

View File

@@ -1,4 +1,3 @@
#define PLUGIN_RECORD_EVENTS
Buffer *EventBuffer;
void Serialize(Buffer *buffer, String name, EventKind *kind) {

View File

@@ -1,2 +1 @@
#define PLUGIN_RECORD_GC
Buffer *GCInfoBuffer;

View File

@@ -1,2 +0,0 @@
#define PLUGIN_REMEDYBG
void QuitDebugger();

View File

@@ -1,4 +1,3 @@
#define PLUGIN_SEARCH_OPEN_BUFFERS
BufferID SearchOpenBuffersBufferID;
struct SearchOpenBuffersParams {
@@ -19,7 +18,7 @@ void Coro_SearchOpenBuffers(mco_coro *co) {
if (it == NULL || it->special || it->temp || it->dont_try_to_save_in_bulk_ops) {
continue;
}
#ifdef PLUGIN_DIRECTORY_NAVIGATION
#if PLUGIN_DIRECTORY_NAVIGATION
if (it->is_dir) {
continue;
}

View File

@@ -1,4 +1,3 @@
#define PLUGIN_SEARCH_WINDOW
void InitSearchWindow();
void LayoutSearchWindow(Rect2I *rect, int16_t wx, int16_t wy);
void UpdateSearchWindow();

View File

@@ -1,4 +1,3 @@
#define PLUGIN_STATUS_WINDOW
WindowID StatusWindowID;
void InitStatusWindow() {

View File

@@ -14,13 +14,29 @@
#include "render/generated_font.cpp"
#include "render/font.cpp"
#include "render/opengl.cpp"
#define PLUGIN_REMEDYBG 1
#define PLUGIN_SEARCH_WINDOW 1
#define PLUGIN_PROJECT_MANAGEMENT 1
#define PLUGIN_WINDOW_MANAGEMENT 1
#define PLUGIN_DIRECTORY_NAVIGATION 1
#define PLUGIN_SEARCH_OPEN_BUFFERS 1
#define PLUGIN_PROJECT_MANAGEMENT 1
#define PLUGIN_BASIC_COMMANDS 1
#define PLUGIN_COMMAND_WINDOW 1
#define PLUGIN_SEARCH_WINDOW 1
#define PLUGIN_STATUS_WINDOW 1
#define PLUGIN_BUILD_WINDOW 1
#define PLUGIN_DEBUG_WINDOW 1
#define PLUGIN_RECORD_GC 1
#define PLUGIN_RECORD_EVENTS 1
#define PLUGIN_LOAD_VCVARS OS_WINDOWS
#define PLUGIN_DIRECTORY_NAVIGATION 1
#include "plugin_directory_navigation.h"
#include "text_editor.h"
#include "plugin_search_window.h"
#include "plugin_project_management.h"
#if OS_WINDOWS
#include "plugin_remedybg.h"
#endif
#include "text_editor.h"
#include "globals.cpp"
#include "coroutines.cpp"
#include "buffer.cpp"
@@ -35,7 +51,6 @@
#include "scratch.cpp"
#include "draw.cpp"
#include "test/tests.cpp"
#include "plugin_window_management.cpp"
#include "plugin_directory_navigation.cpp"
#include "plugin_search_open_buffers.cpp"
@@ -48,9 +63,8 @@
#include "plugin_debug_window.cpp"
#include "plugin_record_gc.cpp"
#include "plugin_record_events.cpp"
#if OS_WINDOWS
#include "plugin_load_vcvars.cpp"
#include "plugin_remedybg.cpp"
#endif
#if OS_WASM
EM_JS(void, JS_SetMouseCursor, (const char *cursor_str), {
@@ -135,56 +149,8 @@ void SetMouseCursor(Event event) {
SetMouseCursor(SDL_SYSTEM_CURSOR_DEFAULT);
}
void UpdateScroll(Window *window, bool update_caret_scrolling) {
ProfileFunction();
BSet set = GetBSet(window);
// Scrolling with caret
if (update_caret_scrolling) {
Caret c = set.view->carets[0];
Int front = GetFront(c);
XY xy = PosToXY(set.buffer, front);
Rect2I visible = GetVisibleCells(window);
Vec2I visible_cells = GetSize(visible);
Vec2I visible_size = visible_cells * Vec2I{window->font->char_spacing, window->font->line_spacing};
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);
set.view->scroll.y = (set_view_at_line * window->font->line_spacing) + cut_off_y;
}
if (xy.line < visible.min.y + 1) {
set.view->scroll.y = xy.line * window->font->line_spacing;
}
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);
set.view->scroll.x = (set_view_at_line * window->font->char_spacing) + cut_off_x;
}
if (xy.col <= visible.min.x) {
set.view->scroll.x = xy.col * window->font->char_spacing;
}
}
// Clip scroll
{
Int last_line = LastLine(set.buffer);
set.view->scroll.y = Clamp(set.view->scroll.y, (Int)0, Max((Int)0, (last_line - 1) * window->font->line_spacing));
// @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?
set.view->scroll.x = ClampBottom(set.view->scroll.x, (Int)0);
}
}
void CMD_QuitWithoutSaving() {
#ifdef PLUGIN_REMEDYBG
#if PLUGIN_REMEDYBG
QuitDebugger();
#endif
AppIsRunning = false;
@@ -503,18 +469,6 @@ void GarbageCollect() {
ProfileFunction();
Allocator sys_allocator = GetSystemAllocator();
For(Buffers) {
if (it->file_mod_time) {
int64_t new_file_mod_time = GetFileModTime(it->name);
if (it->file_mod_time != new_file_mod_time) {
it->changed_on_disk = true;
if (it->dirty == false) {
ReopenBuffer(it);
}
}
}
}
IterRemove(Views) {
IterRemovePrepare(Views);
@@ -542,7 +496,7 @@ void GarbageCollect() {
}
}
#ifdef PLUGIN_RECORD_GC
#if PLUGIN_RECORD_GC
RawAppendf(GCInfoBuffer, "View %d %S\n", (int)it->id.id, buffer ? buffer->name : String{"NULL"});
#endif
Dealloc(&it->commands);
@@ -568,7 +522,7 @@ void GarbageCollect() {
}
}
#ifdef PLUGIN_RECORD_GC
#if PLUGIN_RECORD_GC
RawAppendf(GCInfoBuffer, "Buff %d %S\n", (int)it->id.id, it->name);
#endif
remove_item = true;
@@ -582,7 +536,7 @@ void GarbageCollect() {
}
if (it->close) {
#ifdef PLUGIN_RECORD_GC
#if PLUGIN_RECORD_GC
RawAppendf(GCInfoBuffer, "Wind %d %d %d %d %d\n", (int)it->id.id, (int)it->total_rect.min.x, (int)it->total_rect.min.y, (int)it->total_rect.max.x, (int)it->total_rect.max.y);
#endif
Dealloc(&it->goto_history);
@@ -599,6 +553,55 @@ void GarbageCollect() {
}
}
void LayoutWindows(int16_t wx, int16_t wy) {
ProfileFunction();
Rect2I screen_rect = RectI0Size(wx, wy);
#if PLUGIN_STATUS_WINDOW
LayoutStatusWindow(&screen_rect, wx, wy);
#endif
#if PLUGIN_SEARCH_WINDOW
LayoutSearchWindow(&screen_rect, wx, wy);
#endif
#if PLUGIN_COMMAND_WINDOW
LayoutCommandWindow(&screen_rect, wx, wy);
#endif
#if PLUGIN_DEBUG_WINDOW
LayoutDebugWindow(&screen_rect, wx, wy);
#endif
#if PLUGIN_BUILD_WINDOW
LayoutBuildWindow(&screen_rect, wx, wy);
#endif
// Column layout
Int c = 0;
double size = WindowCalcEvenResizerValue(wx, &c);
if (c == 0) {
return;
}
int i = 0;
ForItem(n, Windows) {
if (!n->primary) {
continue;
}
n->total_rect = n->document_rect = CutLeft(&screen_rect, (Int)(size * n->weight));
if (i != (c - 1)) {
Int resizer_size = (Int)(PrimaryFont.char_spacing*0.5f);
n->resizer_rect = CutRight(&n->document_rect, resizer_size);
} else {
n->resizer_rect = {};
}
CalcNiceties(n);
i += 1;
}
}
void Update(Event event) {
ProfileFunction();
LayoutWindows(event.xwindow, event.ywindow);
@@ -623,15 +626,15 @@ void Update(Event event) {
OnCommand(event);
#ifdef PLUGIN_DEBUG_WINDOW
#if PLUGIN_DEBUG_WINDOW
UpdateDebugWindow();
#endif
#ifdef PLUGIN_STATUS_WINDOW
#if PLUGIN_STATUS_WINDOW
UpdateStatusWindow();
#endif
#ifdef PLUGIN_SEARCH_WINDOW
#if PLUGIN_SEARCH_WINDOW
UpdateSearchWindow();
#endif
@@ -713,13 +716,13 @@ void Update(Event event) {
{
WindowID id[] = {
{-1}, // This is just so that we have a valid array if all windows are disabled
#ifdef PLUGIN_BUILD_WINDOW
#if PLUGIN_BUILD_WINDOW
BuildWindowID,
#endif
#ifdef PLUGIN_COMMAND_WINDOW
#if PLUGIN_COMMAND_WINDOW
CommandWindowID,
#endif
#ifdef PLUGIN_SEARCH_WINDOW
#if PLUGIN_SEARCH_WINDOW
SearchWindowID,
#endif
};
@@ -742,36 +745,22 @@ void Update(Event event) {
}
}
GarbageCollect();
}
void Windows_SetupVCVarsall(mco_coro *co) {
View *view = NULL;
{
Scratch scratch;
String working_dir = ProjectDirectory;
String buffer_name = GetUniqueBufferName(working_dir, "vcvarsall-");
String cmd = Format(scratch, "\"%S\" && set", WindowsVCVarsPathToLoadDevEnviroment);
view = ExecHidden(buffer_name, cmd, working_dir);
}
for (;;) {
if (!ProcessIsActive(view->id)) {
break;
// Reopen modified buffers
// @todo: This is O(n) so could see slow downs with number of buffers, likely need OS help to make it more
// efficient
For(Buffers) {
if (it->file_mod_time) {
int64_t new_file_mod_time = GetFileModTime(it->name);
if (it->file_mod_time != new_file_mod_time) {
it->changed_on_disk = true;
if (it->dirty == false) {
ReopenBuffer(it);
}
}
}
CoYield(co);
}
Scratch scratch;
Buffer *buffer = GetBuffer(view->active_buffer);
String16 string16 = GetString(buffer);
String string = ToString(scratch, string16);
Array<String> lines = Split(scratch, string, "\n");
For (lines) {
String s = Trim(it);
Array<String> values = Split(scratch, s, "=");
if (values.len == 1) continue;
Add(&ProcessEnviroment, Copy(GetSystemAllocator(), s));
}
GarbageCollect();
}
void MainLoop() {
@@ -781,7 +770,7 @@ void MainLoop() {
Array<Event> frame_events = GetEventsForFrame(scratch);
For(frame_events) {
#ifdef PLUGIN_RECORD_EVENTS
#if PLUGIN_RECORD_EVENTS
if (it.kind != EVENT_UPDATE && !Testing) {
Serialize(EventBuffer, &it);
}
@@ -949,7 +938,7 @@ int main(int argc, char **argv)
if (scale != 1.0f) DPIScale = scale;
}
// Init buffers
// InitBuffers
{
Allocator sys_allocator = GetSystemAllocator();
Scratch scratch;
@@ -959,19 +948,19 @@ int main(int argc, char **argv)
null_view->special = true;
Assert(null_buffer->id == NullBufferID && null_view->id == NullViewID);
#ifdef PLUGIN_RECORD_GC
#if PLUGIN_RECORD_GC
GCInfoBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(ProjectDirectory, "gc"));
GCInfoBuffer->special = true;
GCInfoBuffer->no_history = true;
#endif
#ifdef PLUGIN_RECORD_EVENTS
#if PLUGIN_RECORD_EVENTS
EventBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(ProjectDirectory, "events"));
EventBuffer->no_history = true;
EventBuffer->special = true;
#endif
#ifdef PLUGIN_SEARCH_OPEN_BUFFERS
#if PLUGIN_SEARCH_OPEN_BUFFERS
Buffer *search_project = CreateBuffer(sys_allocator, GetUniqueBufferName(ProjectDirectory, "search_project"));
search_project->no_history = true;
search_project->special = true;
@@ -1002,30 +991,27 @@ int main(int argc, char **argv)
}
if (Testing) InitTests();
#if OS_WINDOWS
CoRemove("Windows_SetupVCVarsall");
CoData *co_data = CoAdd(Windows_SetupVCVarsall);
co_data->dont_wait_until_resolved = true;
CoResume(co_data);
#if PLUGIN_LOAD_VCVARS
LoadVCVars();
#endif
#ifdef PLUGIN_STATUS_WINDOW
#if PLUGIN_STATUS_WINDOW
InitStatusWindow();
#endif
#ifdef PLUGIN_COMMAND_WINDOW
#if PLUGIN_COMMAND_WINDOW
InitCommandWindow();
#endif
#ifdef PLUGIN_DEBUG_WINDOW
#if PLUGIN_DEBUG_WINDOW
InitDebugWindow();
#endif
#ifdef PLUGIN_BUILD_WINDOW
#if PLUGIN_BUILD_WINDOW
InitBuildWindow();
#endif
#ifdef PLUGIN_SEARCH_WINDOW
#if PLUGIN_SEARCH_WINDOW
InitSearchWindow();
#endif

View File

@@ -63,7 +63,7 @@ struct Buffer {
uint32_t dont_try_to_save_in_bulk_ops : 1;
uint32_t close : 1;
uint32_t special : 1;
#ifdef PLUGIN_DIRECTORY_NAVIGATION
#if PLUGIN_DIRECTORY_NAVIGATION
uint32_t is_dir : 1;
#endif
};

View File

@@ -134,55 +134,6 @@ double WindowCalcEvenResizerValue(Int screen_size_x, Int *out_count = NULL) {
return (double)screen_size_x / w;
}
void LayoutWindows(int16_t wx, int16_t wy) {
ProfileFunction();
Rect2I screen_rect = RectI0Size(wx, wy);
#ifdef PLUGIN_STATUS_WINDOW
LayoutStatusWindow(&screen_rect, wx, wy);
#endif
#ifdef PLUGIN_SEARCH_WINDOW
LayoutSearchWindow(&screen_rect, wx, wy);
#endif
#ifdef PLUGIN_COMMAND_WINDOW
LayoutCommandWindow(&screen_rect, wx, wy);
#endif
#ifdef PLUGIN_DEBUG_WINDOW
LayoutDebugWindow(&screen_rect, wx, wy);
#endif
#ifdef PLUGIN_BUILD_WINDOW
LayoutBuildWindow(&screen_rect, wx, wy);
#endif
// Column layout
Int c = 0;
double size = WindowCalcEvenResizerValue(wx, &c);
if (c == 0) {
return;
}
int i = 0;
ForItem(n, Windows) {
if (!n->primary) {
continue;
}
n->total_rect = n->document_rect = CutLeft(&screen_rect, (Int)(size * n->weight));
if (i != (c - 1)) {
Int resizer_size = (Int)(PrimaryFont.char_spacing*0.5f);
n->resizer_rect = CutRight(&n->document_rect, resizer_size);
} else {
n->resizer_rect = {};
}
CalcNiceties(n);
i += 1;
}
}
Window *GetOverlappingWindow(Vec2I p, Window *default_window = NULL) {
For(Windows) {
if (AreOverlapping(p, it->total_rect)) {
@@ -308,3 +259,64 @@ void JumpForward(Window *window) {
}
}
}
void UpdateScroll(Window *window, bool update_caret_scrolling) {
ProfileFunction();
BSet set = GetBSet(window);
// Scrolling with caret
if (update_caret_scrolling) {
Caret c = set.view->carets[0];
Int front = GetFront(c);
XY xy = PosToXY(set.buffer, front);
Rect2I visible = GetVisibleCells(window);
Vec2I visible_cells = GetSize(visible);
Vec2I visible_size = visible_cells * Vec2I{window->font->char_spacing, window->font->line_spacing};
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);
set.view->scroll.y = (set_view_at_line * window->font->line_spacing) + cut_off_y;
}
if (xy.line < visible.min.y + 1) {
set.view->scroll.y = xy.line * window->font->line_spacing;
}
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);
set.view->scroll.x = (set_view_at_line * window->font->char_spacing) + cut_off_x;
}
if (xy.col <= visible.min.x) {
set.view->scroll.x = xy.col * window->font->char_spacing;
}
}
// Clip scroll
{
Int last_line = LastLine(set.buffer);
set.view->scroll.y = Clamp(set.view->scroll.y, (Int)0, Max((Int)0, (last_line - 1) * window->font->line_spacing));
// @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?
set.view->scroll.x = ClampBottom(set.view->scroll.x, (Int)0);
}
}
void CenterView(WindowID window) {
BSet set = GetBSet(window);
Caret c = set.view->carets[0];
Int front = GetFront(c);
XY xy = PosToXY(set.buffer, front);
Vec2I size = GetSize(set.window->document_rect);
Int y = size.y / 2 / set.window->font->line_spacing;
set.view->scroll.x = 0;
if (xy.line > y) {
set.view->scroll.y = (xy.line) * set.window->font->line_spacing - (size.y / 2);
}
}