Editing infobar applies changes to buffer

This commit is contained in:
Krzosa Karol
2024-07-31 07:32:42 +02:00
parent 2ab1917b73
commit be99b0aabb
9 changed files with 164 additions and 38 deletions

View File

@@ -700,7 +700,6 @@ struct CircularArray {
T *data;
int16_t cap;
int16_t write;
int16_t buffer_is_full;
};
template <class T>
@@ -718,25 +717,23 @@ void Add(CircularArray<T> *arr, T item) {
arr->cap = 128;
arr->data = AllocArray(arr->allocator, T, arr->cap);
}
int idx = arr->write;
arr->write = (arr->write + 1) % arr->cap;
if (arr->write == 0) arr->buffer_is_full = 1;
arr->data[idx] = item;
int16_t i = arr->write;
arr->write = (arr->write + 1) % arr->cap;
arr->data[i] = item;
}
static int GetCircularIndex(int cap, int idx) {
int result = idx % cap;
if (result < 0) result = cap + result;
return result;
}
template <class T>
T Get(CircularArray<T> *arr, int idx, T default_value) {
if (idx >= arr->cap) return default_value;
int i = arr->write - 1 - idx;
if (i < 0 && arr->buffer_is_full) {
i = arr->cap + i;
}
if (i >= 0 && i < arr->cap) {
return arr->data[i];
} else {
return default_value;
}
int idx = circ->write - 1 - i;
idx = GetCircularIndex(circ->size, idx);
int result = circ->data[idx];
return result;
}
struct UTF32Result {

View File

@@ -150,3 +150,42 @@ String16 CutPostfix(String16 *string, int64_t len) {
*string = Chop(*string, len);
return result;
}
String16 Trim(String16 string) {
if (string.len == 0)
return string;
int64_t whitespace_begin = 0;
for (; whitespace_begin < string.len; whitespace_begin++) {
if (!IsWhitespace(string.data[whitespace_begin])) {
break;
}
}
int64_t whitespace_end = string.len;
for (; whitespace_end != whitespace_begin; whitespace_end--) {
if (!IsWhitespace(string.data[whitespace_end - 1])) {
break;
}
}
if (whitespace_begin == whitespace_end) {
string.len = 0;
} else {
string = GetSlice(string, whitespace_begin, whitespace_end);
}
return string;
}
String16 TrimEnd(String16 string) {
int64_t whitespace_end = string.len;
for (; whitespace_end != 0; whitespace_end--) {
if (!IsWhitespace(string.data[whitespace_end - 1])) {
break;
}
}
String16 result = GetPrefix(string, whitespace_end);
return result;
}

View File

@@ -170,6 +170,7 @@ void ReplaceText(Buffer *buffer, Range range, String16 string) {
Assert(range.min >= 0 && range.min <= buffer->len);
buffer->dirty = true;
buffer->change_id += 1;
buffer->change_frame_id = FrameID;
Int size_to_remove = range.max - range.min;
Int size_to_add = string.len;

View File

@@ -227,6 +227,23 @@ Array<Range> FindAllInBuffer(Allocator allocator, Buffer *buffer, String16 needl
return result;
}
void ToggleFullscreen() {
if (IsInFullscreen) {
SDL_SetWindowSize(SDLWindow, FullScreenSizeX, FullScreenSizeY);
SDL_SetWindowPosition(SDLWindow, FullScreenPositionX, FullScreenPositionY);
} else {
SDL_GetWindowSize(SDLWindow, &FullScreenSizeX, &FullScreenSizeY);
SDL_GetWindowPosition(SDLWindow, &FullScreenPositionX, &FullScreenPositionY);
SDL_DisplayID display = SDL_GetDisplayForWindow(SDLWindow);
const SDL_DisplayMode *dm = SDL_GetCurrentDisplayMode(display);
SDL_SetWindowSize(SDLWindow, dm->w, dm->h);
SDL_SetWindowPosition(SDLWindow, 0, 0);
}
IsInFullscreen = !IsInFullscreen;
}
bool GlobalCommand(Event event) {
ProfileFunction();
bool run_window_command = true;
@@ -314,6 +331,10 @@ bool GlobalCommand(Event event) {
run_window_command = false;
}
if (Press(SDLK_F11)) {
ToggleFullscreen();
}
if (Ctrl(SDLK_P)) {
Window *command_window = GetWindow(CommandWindowID);
if (command_window->visible) {
@@ -366,8 +387,7 @@ void ReportErrorf(const char *fmt, ...) {
STRING_FORMAT(scratch, fmt, string);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error!", string.data, NULL);
Buffer *buffer = GetBuffer("*console*");
if (!buffer) return;
Buffer *buffer = GetBuffer("*console*");
String16 string16 = ToString16(scratch, string);
ReplaceText(buffer, {}, string16);
}

View File

@@ -266,12 +266,74 @@ void ReplaceDebugData() {
Append(buffer, ToString16(scratch, window_list));
}
void ApplyInfobarChanges(Window *window, View *view, Buffer *buffer) {
String16 buffer_string = GetString(*buffer);
Range replace_range = {0, buffer->len};
if (Seek(buffer_string, L" |", &replace_range.max)) {
}
buffer_string = GetString(*buffer, replace_range);
buffer_string = Trim(buffer_string);
String16 col = {};
for (int64_t i = buffer_string.len - 1; i >= 0; i -= 1) {
if (IsDigit(buffer_string.data[i])) {
col.data = buffer_string.data + i;
col.len += 1;
} else if (buffer_string.data[i] == L':') {
break;
} else {
return;
}
}
buffer_string = Chop(buffer_string, col.len + 1);
String16 line = {};
for (int64_t i = buffer_string.len - 1; i >= 0; i -= 1) {
if (IsDigit(buffer_string.data[i])) {
line.data = buffer_string.data + i;
line.len += 1;
} else if (buffer_string.data[i] == L':') {
break;
} else {
return;
}
}
buffer_string = Chop(buffer_string, line.len + 1);
Window *last_window = GetWindow(GetLastActiveWindow());
View *last_view = GetActiveView(last_window);
Buffer *last_buffer = GetBuffer(last_view->active_buffer);
// @todo: maybe intern the filenames?
// @leak
String filepath = ToString(Perm, buffer_string);
if (!BufferNameExists(filepath)) {
last_buffer->name = filepath;
}
Scratch scratch;
String line_string = ToString(scratch, line);
String col_string = ToString(scratch, col);
Int linei = strtoll(line_string.data, NULL, 10) - 1;
Int coli = strtoll(col_string.data, NULL, 10) - 1;
Int buffer_pos = XYToPos(*last_buffer, {coli, linei});
Caret &caret = last_view->carets[0];
if (GetFront(caret) != buffer_pos) {
caret = MakeCaret(buffer_pos);
}
}
void ReplaceInfobarData() {
Window *window = GetWindow(InfoBarWindowID);
if (IsActive(window)) return;
View *view = GetView(window->active_view);
Buffer *buffer = GetBuffer(view->active_buffer);
if (IsActive(window)) {
if (buffer->change_frame_id == FrameID) {
ApplyInfobarChanges(window, view, buffer);
}
return;
}
Window *last_window = GetWindow(GetLastActiveWindow());
View *last_view = GetActiveView(last_window);
@@ -284,7 +346,7 @@ void ReplaceInfobarData() {
String16 buffer_string = GetString(*buffer);
Range replace_range = {0, buffer->len};
if (!Seek(buffer_string, L" |", &replace_range.max)) {
// ReplaceText(buffer, GetEndAsRange(*buffer), L" |");
ReplaceText(buffer, GetEndAsRange(*buffer), L" |");
}
// String s = Format(scratch, " %lld:%lld", (long long)xy.line + 1ll, (long long)xy.col + 1ll);

View File

@@ -39,6 +39,11 @@ inline Buffer *GetBuffer(String name) {
return &Buffers[0];
}
inline Buffer *BufferNameExists(String name) {
For(Buffers) if (it.name == name) return &it;
return NULL;
}
inline View *GetView(ViewID id) {
For(Views) if (it.id.id == id.id) return &it;
return &Views[0];

View File

@@ -13,6 +13,11 @@
#include "external/stb_truetype.h"
#include "external/stb_truetype.c"
SDL_Window *SDLWindow;
bool IsInFullscreen;
int FullScreenSizeX, FullScreenSizeY;
int FullScreenPositionX, FullScreenPositionY;
#include "platform/font.cpp"
#include "platform/render_opengl.cpp"
@@ -141,23 +146,23 @@ int main()
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 *sdl_window = SDL_CreateWindow("Text editor", 1280, 720, window_flags);
if (sdl_window == NULL) {
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
SDLWindow = SDL_CreateWindow("Text editor", 1280, 720, window_flags);
if (SDLWindow == NULL) {
ReportErrorf("Couldn't create window! %s", SDL_GetError());
return 1;
}
SDL_GLContext gl_context = SDL_GL_CreateContext(sdl_window);
SDL_GL_MakeCurrent(sdl_window, gl_context);
SDL_GLContext gl_context = SDL_GL_CreateContext(SDLWindow);
SDL_GL_MakeCurrent(SDLWindow, gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync
SDL_ShowWindow(sdl_window);
SDL_ShowWindow(SDLWindow);
// Set icon
{
uint32_t data = 0xddddddff;
SDL_Surface *surface = SDL_CreateSurfaceFrom(1, 1, SDL_PIXELFORMAT_RGBA8888, &data, sizeof(uint32_t));
SDL_SetWindowIcon(sdl_window, surface);
SDL_SetWindowIcon(SDLWindow, surface);
SDL_DestroySurface(surface);
}
@@ -166,10 +171,10 @@ int main()
return 1;
}
SDL_StartTextInput(sdl_window);
SDL_StartTextInput(SDLWindow);
SDL_GL_SetSwapInterval(1); // vsync
{
float scale = SDL_GetWindowDisplayScale(sdl_window);
float scale = SDL_GetWindowDisplayScale(SDLWindow);
if (scale != 1.0f) DPIScale = scale;
}
@@ -232,7 +237,7 @@ int main()
WaitForEvents = true;
int window_x, window_y;
SDL_GetWindowSize(sdl_window, &window_x, &window_y);
SDL_GetWindowSize(SDLWindow, &window_x, &window_y);
WindowSize = {(float)window_x, (float)window_y};
BeginFrameRender();
LayoutWindows();
@@ -271,7 +276,7 @@ int main()
Buffer *buffer = GetBuffer(view->active_buffer);
const char *dirty = buffer->dirty ? "!" : "";
Format(scratch, "%.*s%s", buffer->name, dirty);
SDL_SetWindowTitle(sdl_window, buffer->name.data);
SDL_SetWindowTitle(SDLWindow, buffer->name.data);
}
ReplaceInfobarData();
ReplaceDebugData();
@@ -310,10 +315,10 @@ int main()
DrawWindow(window);
}
EndFrameRender(ColorBackground);
SDL_GL_SwapWindow(sdl_window);
SDL_GL_SwapWindow(SDLWindow);
}
SDL_DestroyWindow(sdl_window);
SDL_DestroyWindow(SDLWindow);
SDL_Quit();
EndProfiler();

View File

@@ -24,6 +24,7 @@ struct Buffer {
BufferID id;
String name;
Int change_id;
Int change_frame_id;
union {
U16 *data;

View File

@@ -1,6 +1,5 @@
- Windows
- Mark windows as absolute or non-automatic layout and then just loop through windows
- Remove view children, replace with view history
- layouting, resize windows
- column based, choose number of columns and then evenly split - we can adjust sizes using mouse
- maybe we can use first line number to use the window?
@@ -9,12 +8,10 @@
- is this even practical if we have tab based design?
- this would allow to create new windows just like that to inform user and so on
- window borders as flag
- You should be able to edit buffer name, column and line in info bar which would apply to the last open view. Make sure name is unique
- Implement console buffer mimicking vscode with ctrl+~ etc.
- Reverse order of append in console buffer - it should be appending from top to bottom and scrolling
- Modify error popups to not focus, introduce a interaction timer which after some time will make window invisible
- Implement shell interaction in a console buffer
- Fullscreen
- files
- load directory
@@ -29,7 +26,6 @@
- execution
- experiment with using multiple cursors to select command and it's input
-
- mouse
- open selected string or auto enclosed word when right clicking or middle (this needs to be also handled on keyboard level)