Replace text_editor and bring back ctrl + f, fix circle rendering pos
This commit is contained in:
@@ -128,7 +128,7 @@ int CompileTextEditor() {
|
|||||||
AddCommonFlags(&cmd);
|
AddCommonFlags(&cmd);
|
||||||
For2(lib, libs) For(lib.defines) cmd.add(it);
|
For2(lib, libs) For(lib.defines) cmd.add(it);
|
||||||
|
|
||||||
cmd.add("../src/text_editor/new_text_editor.cpp");
|
cmd.add("../src/text_editor/text_editor.cpp");
|
||||||
cmd.add("../src/basic/win32.cpp");
|
cmd.add("../src/basic/win32.cpp");
|
||||||
|
|
||||||
For2(lib, libs) For(lib.include_paths) cmd.add(Fmt("-I %.*s", S8_Expand(it)));
|
For2(lib, libs) For(lib.include_paths) cmd.add(Fmt("-I %.*s", S8_Expand(it)));
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ bool GlobalCommand(Event event) {
|
|||||||
run_window_command = false;
|
run_window_command = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ctrl(SDLK_P)) {
|
if (Ctrl(SDLK_F)) {
|
||||||
Window *search_window = GetWindow(SearchWindowID);
|
Window *search_window = GetWindow(SearchWindowID);
|
||||||
if (search_window->visible) {
|
if (search_window->visible) {
|
||||||
SetActiveWindow(GetLastActiveWindow());
|
SetActiveWindow(GetLastActiveWindow());
|
||||||
|
|||||||
@@ -1,277 +0,0 @@
|
|||||||
#include <math.h>
|
|
||||||
|
|
||||||
#define BASIC_IMPL
|
|
||||||
#include "basic/basic.h"
|
|
||||||
#include "basic/filesystem.h"
|
|
||||||
#include "basic/string16.cpp"
|
|
||||||
#include "basic/math_int.cpp"
|
|
||||||
#include "basic/math.cpp"
|
|
||||||
#include "profiler/profiler.cpp"
|
|
||||||
|
|
||||||
#include "SDL3/SDL.h"
|
|
||||||
#include "external/glad/glad.h"
|
|
||||||
#include "external/stb_truetype.h"
|
|
||||||
#include "external/stb_truetype.c"
|
|
||||||
|
|
||||||
#include "platform/font.cpp"
|
|
||||||
#include "platform/render_opengl.cpp"
|
|
||||||
|
|
||||||
#include "text_editor.h"
|
|
||||||
#include "buffer_helpers.cpp"
|
|
||||||
#include "buffer.cpp"
|
|
||||||
#include "buffer_multi_cursor.cpp"
|
|
||||||
#include "buffer_history.cpp"
|
|
||||||
#include "buffer_fuzzy_search.cpp"
|
|
||||||
#include "buffer_test_load.cpp"
|
|
||||||
|
|
||||||
#include "management.cpp"
|
|
||||||
#include "window.cpp"
|
|
||||||
#include "commands.cpp"
|
|
||||||
#include "commands_clipboard.cpp"
|
|
||||||
#include "commands_window.cpp"
|
|
||||||
|
|
||||||
#include "colors.cpp"
|
|
||||||
#include "window_draw.cpp"
|
|
||||||
|
|
||||||
#include "lua.hpp"
|
|
||||||
#include "lua_api.cpp"
|
|
||||||
|
|
||||||
void HandleEvent(Event event) {
|
|
||||||
bool run_window_command = GlobalCommand(event);
|
|
||||||
if (run_window_command) {
|
|
||||||
Window *window = GetActiveWindow();
|
|
||||||
View *view = GetActiveView(window);
|
|
||||||
WindowCommand(event, window, view);
|
|
||||||
MergeCarets(view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessSDLEvent(SDL_Event *input_event) {
|
|
||||||
ProfileFunction();
|
|
||||||
Event event = {};
|
|
||||||
SDL_Keymod mod = SDL_GetModState();
|
|
||||||
event.shift = (mod & SDL_KMOD_SHIFT) != 0;
|
|
||||||
event.ctrl = (mod & SDL_KMOD_CTRL) != 0;
|
|
||||||
event.alt = (mod & SDL_KMOD_ALT) != 0;
|
|
||||||
event.super = (mod & SDL_KMOD_GUI) != 0;
|
|
||||||
|
|
||||||
switch (input_event->type) {
|
|
||||||
case SDL_EVENT_QUIT: AppIsRunning = false; return;
|
|
||||||
case SDL_EVENT_KEY_DOWN: {
|
|
||||||
SDL_KeyboardEvent &key = input_event->key;
|
|
||||||
event.key = key.key;
|
|
||||||
} break;
|
|
||||||
case SDL_EVENT_TEXT_INPUT: {
|
|
||||||
SDL_TextInputEvent &b = input_event->text;
|
|
||||||
event.text = b.text;
|
|
||||||
} break;
|
|
||||||
case SDL_EVENT_MOUSE_BUTTON_DOWN: {
|
|
||||||
SDL_MouseButtonEvent &b = input_event->button;
|
|
||||||
event.xmouse = (int16_t)b.x;
|
|
||||||
event.ymouse = (int16_t)b.y;
|
|
||||||
if (b.button == SDL_BUTTON_LEFT) {
|
|
||||||
event.mouse = MOUSE_LEFT;
|
|
||||||
if (b.clicks == 2) {
|
|
||||||
event.mouse_double_click = 1;
|
|
||||||
}
|
|
||||||
} else if (b.button == SDL_BUTTON_RIGHT) {
|
|
||||||
event.mouse = MOUSE_RIGHT;
|
|
||||||
} else if (b.button == SDL_BUTTON_MIDDLE) {
|
|
||||||
event.mouse = MOUSE_MIDDLE;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case SDL_EVENT_MOUSE_BUTTON_UP: {
|
|
||||||
SDL_MouseButtonEvent &b = input_event->button;
|
|
||||||
event.xmouse = (int16_t)b.x;
|
|
||||||
event.ymouse = (int16_t)b.y;
|
|
||||||
if (b.button == SDL_BUTTON_LEFT) {
|
|
||||||
event.mouse = MOUSE_LEFT_UP;
|
|
||||||
} else if (b.button == SDL_BUTTON_RIGHT) {
|
|
||||||
event.mouse = MOUSE_RIGHT_UP;
|
|
||||||
} else if (b.button == SDL_BUTTON_MIDDLE) {
|
|
||||||
event.mouse = MOUSE_MIDDLE_UP;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case SDL_EVENT_MOUSE_WHEEL: {
|
|
||||||
SDL_MouseWheelEvent &b = input_event->wheel;
|
|
||||||
event.xmouse = (int16_t)b.mouse_x;
|
|
||||||
event.ymouse = (int16_t)b.mouse_y;
|
|
||||||
event.wheel = b.y;
|
|
||||||
} break;
|
|
||||||
default: return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if _WIN32
|
|
||||||
int WinMain(void *hInstance, void *hPrevInstance, const char *lpCmdLine, int nShowCmd)
|
|
||||||
#else
|
|
||||||
int main()
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
BeginProfiler();
|
|
||||||
|
|
||||||
InitScratch();
|
|
||||||
InitArena(&Perm);
|
|
||||||
WorkingDir = GetWorkingDir(Perm);
|
|
||||||
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) == -1) {
|
|
||||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't initialize SDL!", SDL_GetError(), NULL);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *glsl_version = "#version 450";
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5);
|
|
||||||
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
|
||||||
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
|
||||||
SDL_Window *window = SDL_CreateWindow("Text editor", 1280, 720, window_flags);
|
|
||||||
if (window == NULL) {
|
|
||||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window!", SDL_GetError(), NULL);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
|
|
||||||
SDL_GL_MakeCurrent(window, gl_context);
|
|
||||||
SDL_GL_SetSwapInterval(1); // Enable vsync
|
|
||||||
SDL_ShowWindow(window);
|
|
||||||
|
|
||||||
// Set icon
|
|
||||||
{
|
|
||||||
uint32_t data = 0xddddddff;
|
|
||||||
SDL_Surface *surface = SDL_CreateSurfaceFrom(1, 1, SDL_PIXELFORMAT_RGBA8888, &data, sizeof(uint32_t));
|
|
||||||
SDL_SetWindowIcon(window, surface);
|
|
||||||
SDL_DestroySurface(surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) {
|
|
||||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't load opengl!", SDL_GetError(), NULL);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_StartTextInput(window);
|
|
||||||
SDL_GL_SetSwapInterval(1); // vsync
|
|
||||||
InitRender();
|
|
||||||
ReloadFont(16);
|
|
||||||
InitLua();
|
|
||||||
|
|
||||||
InitWindows();
|
|
||||||
while (AppIsRunning) {
|
|
||||||
FrameID += 1;
|
|
||||||
int window_x, window_y;
|
|
||||||
SDL_GetWindowSize(window, &window_x, &window_y);
|
|
||||||
WindowSize = {(float)window_x, (float)window_y};
|
|
||||||
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);
|
|
||||||
ProcessSDLEvent(&event);
|
|
||||||
}
|
|
||||||
WaitForEvents = true;
|
|
||||||
while (SDL_PollEvent(&event)) {
|
|
||||||
ProcessSDLEvent(&event);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Event event = {};
|
|
||||||
float xmouse, ymouse;
|
|
||||||
SDL_GetMouseState(&xmouse, &ymouse);
|
|
||||||
event.xmouse = (int16_t)xmouse;
|
|
||||||
event.ymouse = (int16_t)ymouse;
|
|
||||||
event.mouse = MOUSE_MOVE;
|
|
||||||
HandleEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReplaceInfobarData();
|
|
||||||
|
|
||||||
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) continue;
|
|
||||||
// HandleWindowBindings(&window);
|
|
||||||
DrawWindow(window);
|
|
||||||
}
|
|
||||||
EndFrameRender(ColorBackground);
|
|
||||||
SDL_GL_SwapWindow(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_DestroyWindow(window);
|
|
||||||
SDL_Quit();
|
|
||||||
|
|
||||||
EndProfileScope();
|
|
||||||
EndProfiler();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -6,14 +6,17 @@
|
|||||||
#include "basic/string16.cpp"
|
#include "basic/string16.cpp"
|
||||||
#include "basic/math_int.cpp"
|
#include "basic/math_int.cpp"
|
||||||
#include "basic/math.cpp"
|
#include "basic/math.cpp"
|
||||||
|
|
||||||
#include "raylib.h"
|
|
||||||
#include "colors.cpp"
|
|
||||||
#include "raylib_utils.cpp"
|
|
||||||
|
|
||||||
#include "profiler/profiler.cpp"
|
#include "profiler/profiler.cpp"
|
||||||
#include "text_editor.h"
|
|
||||||
|
|
||||||
|
#include "SDL3/SDL.h"
|
||||||
|
#include "external/glad/glad.h"
|
||||||
|
#include "external/stb_truetype.h"
|
||||||
|
#include "external/stb_truetype.c"
|
||||||
|
|
||||||
|
#include "platform/font.cpp"
|
||||||
|
#include "platform/render_opengl.cpp"
|
||||||
|
|
||||||
|
#include "text_editor.h"
|
||||||
#include "buffer_helpers.cpp"
|
#include "buffer_helpers.cpp"
|
||||||
#include "buffer.cpp"
|
#include "buffer.cpp"
|
||||||
#include "buffer_multi_cursor.cpp"
|
#include "buffer_multi_cursor.cpp"
|
||||||
@@ -22,62 +25,253 @@
|
|||||||
#include "buffer_test_load.cpp"
|
#include "buffer_test_load.cpp"
|
||||||
|
|
||||||
#include "management.cpp"
|
#include "management.cpp"
|
||||||
|
#include "window.cpp"
|
||||||
#include "commands.cpp"
|
#include "commands.cpp"
|
||||||
#include "commands_clipboard.cpp"
|
#include "commands_clipboard.cpp"
|
||||||
#include "commands_window.cpp"
|
#include "commands_window.cpp"
|
||||||
#include "window.cpp"
|
|
||||||
|
#include "colors.cpp"
|
||||||
#include "window_draw.cpp"
|
#include "window_draw.cpp"
|
||||||
|
|
||||||
#include "lua.hpp"
|
#include "lua.hpp"
|
||||||
#include "lua_api.cpp"
|
#include "lua_api.cpp"
|
||||||
|
|
||||||
int main(void) {
|
void HandleEvent(Event event) {
|
||||||
InitScratch();
|
bool run_window_command = GlobalCommand(event);
|
||||||
BeginProfiler();
|
if (run_window_command) {
|
||||||
BeginProfileScope("main");
|
Window *window = GetActiveWindow();
|
||||||
|
View *view = GetActiveView(window);
|
||||||
|
WindowCommand(event, window, view);
|
||||||
|
MergeCarets(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Arena Perm = {};
|
void ProcessSDLEvent(SDL_Event *input_event) {
|
||||||
InitArena(&Perm);
|
ProfileFunction();
|
||||||
|
Event event = {};
|
||||||
|
SDL_Keymod mod = SDL_GetModState();
|
||||||
|
event.shift = (mod & SDL_KMOD_SHIFT) != 0;
|
||||||
|
event.ctrl = (mod & SDL_KMOD_CTRL) != 0;
|
||||||
|
event.alt = (mod & SDL_KMOD_ALT) != 0;
|
||||||
|
event.super = (mod & SDL_KMOD_GUI) != 0;
|
||||||
|
|
||||||
WorkingDir = GetWorkingDir(Perm);
|
switch (input_event->type) {
|
||||||
SetWindowState(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI | FLAG_MSAA_4X_HINT);
|
case SDL_EVENT_QUIT: AppIsRunning = false; return;
|
||||||
InitWindow(1280, 720, "hello :)");
|
case SDL_EVENT_KEY_DOWN: {
|
||||||
SetExitKey(KEY_F5);
|
SDL_KeyboardEvent &key = input_event->key;
|
||||||
SetTargetFPS(60);
|
event.key = key.key;
|
||||||
{
|
} break;
|
||||||
uint32_t data = 0xffdddddd;
|
case SDL_EVENT_TEXT_INPUT: {
|
||||||
Image window_icon_image = {(void *)&data, 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8};
|
SDL_TextInputEvent &b = input_event->text;
|
||||||
SetWindowIcon(window_icon_image);
|
event.text = b.text;
|
||||||
|
} break;
|
||||||
|
case SDL_EVENT_MOUSE_BUTTON_DOWN: {
|
||||||
|
SDL_MouseButtonEvent &b = input_event->button;
|
||||||
|
event.xmouse = (int16_t)b.x;
|
||||||
|
event.ymouse = (int16_t)b.y;
|
||||||
|
if (b.button == SDL_BUTTON_LEFT) {
|
||||||
|
event.mouse = MOUSE_LEFT;
|
||||||
|
if (b.clicks == 2) {
|
||||||
|
event.mouse_double_click = 1;
|
||||||
|
}
|
||||||
|
} else if (b.button == SDL_BUTTON_RIGHT) {
|
||||||
|
event.mouse = MOUSE_RIGHT;
|
||||||
|
} else if (b.button == SDL_BUTTON_MIDDLE) {
|
||||||
|
event.mouse = MOUSE_MIDDLE;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case SDL_EVENT_MOUSE_BUTTON_UP: {
|
||||||
|
SDL_MouseButtonEvent &b = input_event->button;
|
||||||
|
event.xmouse = (int16_t)b.x;
|
||||||
|
event.ymouse = (int16_t)b.y;
|
||||||
|
if (b.button == SDL_BUTTON_LEFT) {
|
||||||
|
event.mouse = MOUSE_LEFT_UP;
|
||||||
|
} else if (b.button == SDL_BUTTON_RIGHT) {
|
||||||
|
event.mouse = MOUSE_RIGHT_UP;
|
||||||
|
} else if (b.button == SDL_BUTTON_MIDDLE) {
|
||||||
|
event.mouse = MOUSE_MIDDLE_UP;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case SDL_EVENT_MOUSE_WHEEL: {
|
||||||
|
SDL_MouseWheelEvent &b = input_event->wheel;
|
||||||
|
event.xmouse = (int16_t)b.mouse_x;
|
||||||
|
event.ymouse = (int16_t)b.mouse_y;
|
||||||
|
event.wheel = b.y;
|
||||||
|
} break;
|
||||||
|
default: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuFontSize = 19;
|
HandleEvent(event);
|
||||||
MenuFont = LoadFontEx("c:\\Windows\\Fonts\\Segoeui.ttf", (int)MenuFontSize, NULL, 500);
|
}
|
||||||
ReloadFont(16);
|
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
int WinMain(void *hInstance, void *hPrevInstance, const char *lpCmdLine, int nShowCmd)
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
BeginProfiler();
|
||||||
|
|
||||||
|
InitScratch();
|
||||||
|
InitArena(&Perm);
|
||||||
|
WorkingDir = GetWorkingDir(Perm);
|
||||||
|
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO) == -1) {
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't initialize SDL!", SDL_GetError(), NULL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *glsl_version = "#version 450";
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5);
|
||||||
|
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||||
|
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||||
|
SDL_Window *window = SDL_CreateWindow("Text editor", 1280, 720, window_flags);
|
||||||
|
if (window == NULL) {
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window!", SDL_GetError(), NULL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
|
||||||
|
SDL_GL_MakeCurrent(window, gl_context);
|
||||||
|
SDL_GL_SetSwapInterval(1); // Enable vsync
|
||||||
|
SDL_ShowWindow(window);
|
||||||
|
|
||||||
|
// Set icon
|
||||||
|
{
|
||||||
|
uint32_t data = 0xddddddff;
|
||||||
|
SDL_Surface *surface = SDL_CreateSurfaceFrom(1, 1, SDL_PIXELFORMAT_RGBA8888, &data, sizeof(uint32_t));
|
||||||
|
SDL_SetWindowIcon(window, surface);
|
||||||
|
SDL_DestroySurface(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) {
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't load opengl!", SDL_GetError(), NULL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_StartTextInput(window);
|
||||||
|
SDL_GL_SetSwapInterval(1); // vsync
|
||||||
|
InitRender();
|
||||||
|
ReloadFont(16);
|
||||||
InitLua();
|
InitLua();
|
||||||
|
|
||||||
while (!WindowShouldClose()) {
|
InitWindows();
|
||||||
|
while (AppIsRunning) {
|
||||||
BeginDrawing();
|
FrameID += 1;
|
||||||
ClearBackground(ColorBackground);
|
int window_x, window_y;
|
||||||
|
SDL_GetWindowSize(window, &window_x, &window_y);
|
||||||
|
WindowSize = {(float)window_x, (float)window_y};
|
||||||
|
BeginFrameRender();
|
||||||
|
LayoutWindows();
|
||||||
|
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Array<Int> order = GetWindowZOrder(scratch);
|
Array<Int> order = GetWindowZOrder(scratch);
|
||||||
HandleGlobalCommands();
|
For(order) {
|
||||||
ChangeActiveWindowAndScroll(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);
|
||||||
|
ProcessSDLEvent(&event);
|
||||||
|
}
|
||||||
|
WaitForEvents = true;
|
||||||
|
while (SDL_PollEvent(&event)) {
|
||||||
|
ProcessSDLEvent(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Event event = {};
|
||||||
|
float xmouse, ymouse;
|
||||||
|
SDL_GetMouseState(&xmouse, &ymouse);
|
||||||
|
event.xmouse = (int16_t)xmouse;
|
||||||
|
event.ymouse = (int16_t)ymouse;
|
||||||
|
event.mouse = MOUSE_MOVE;
|
||||||
|
HandleEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
ReplaceInfobarData();
|
ReplaceInfobarData();
|
||||||
|
|
||||||
|
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)) {
|
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);
|
||||||
}
|
}
|
||||||
|
EndFrameRender(ColorBackground);
|
||||||
|
SDL_GL_SwapWindow(window);
|
||||||
}
|
}
|
||||||
SetMouseCursor();
|
|
||||||
EndDrawing();
|
SDL_DestroyWindow(window);
|
||||||
}
|
SDL_Quit();
|
||||||
CloseWindow();
|
|
||||||
EndProfileScope();
|
EndProfileScope();
|
||||||
EndProfiler();
|
EndProfiler();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -125,11 +125,11 @@ void DrawWindow(Window &window) {
|
|||||||
DrawRect(rect, ColorSelection);
|
DrawRect(rect, ColorSelection);
|
||||||
|
|
||||||
if (line_string[col] == ' ' || line_string[col] == '\t') {
|
if (line_string[col] == ' ' || line_string[col] == '\t') {
|
||||||
DrawCircle({pos.x + (float)FontCharSpacing / 2.f, (float)pos.y + MainFont.descent}, MainFont.size / 8.f, ColorWhitespaceDuringSelection);
|
DrawCircle({pos.x + (float)FontCharSpacing / 2.f, (float)pos.y - MainFont.ascent / 2.f}, MainFont.size / 8.f, ColorWhitespaceDuringSelection);
|
||||||
} else if (line_string[col] == '\n') {
|
} else if (line_string[col] == '\n') {
|
||||||
DrawCircle({pos.x + (float)FontCharSpacing / 2.f, pos.y + (float)FontLineSpacing / 2.f}, MainFont.size / 8.f, ColorWhitespaceDuringSelection);
|
DrawCircle({pos.x + (float)FontCharSpacing / 2.f, pos.y - MainFont.ascent / 2.f}, MainFont.size / 8.f, ColorWhitespaceDuringSelection);
|
||||||
} else if (line_string[col] == '\r') {
|
} else if (line_string[col] == '\r') {
|
||||||
DrawCircle({pos.x + (float)FontCharSpacing / 2.f, pos.y + (float)FontLineSpacing / 2.f}, MainFont.size / 8.f, ColorWhitespaceDuringSelection);
|
DrawCircle({pos.x + (float)FontCharSpacing / 2.f, pos.y - MainFont.ascent / 2.f}, MainFont.size / 8.f, ColorWhitespaceDuringSelection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user