Forgot management.cpp
This commit is contained in:
184
src/text_editor/management.cpp
Normal file
184
src/text_editor/management.cpp
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
inline Window *GetWindow(WindowID id) {
|
||||||
|
For(Windows) if (it.id.id == id.id) return ⁢
|
||||||
|
return &Windows[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Buffer *GetBuffer(BufferID id) {
|
||||||
|
For(Buffers) if (it.id.id == id.id) return ⁢
|
||||||
|
return &Buffers[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Buffer *GetBuffer(String name) {
|
||||||
|
For(Buffers) if (it.name == name) return ⁢
|
||||||
|
return &Buffers[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline View *GetView(ViewID id) {
|
||||||
|
For(Views) if (it.id.id == id.id) return ⁢
|
||||||
|
return &Views[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsNull(Buffer *buffer) { return buffer->id.id == NullBufferID.id; }
|
||||||
|
|
||||||
|
void SetActiveWindow(WindowID window);
|
||||||
|
inline bool IsActive(Window *window) { return window->id.id == ActiveWindow.id; }
|
||||||
|
inline bool IsActive(Window *window, View *view) { return window->active_view.id == view->id.id; }
|
||||||
|
inline Window *GetActiveWindow() { return GetWindow(ActiveWindow); }
|
||||||
|
inline View *GetActiveView(Window *window) {
|
||||||
|
if (window->active_view.id == 0) return GetView(window->views[0]);
|
||||||
|
else return GetView(window->active_view);
|
||||||
|
}
|
||||||
|
|
||||||
|
Window *CreateWindow() {
|
||||||
|
Window *w = Alloc(&Windows);
|
||||||
|
w->visible = true;
|
||||||
|
w->draw_scrollbar = true;
|
||||||
|
w->draw_line_numbers = true;
|
||||||
|
w->id = AllocWindowID();
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddView(Window *w, ViewID view) {
|
||||||
|
if (w->active_view.id == 0) w->active_view = view;
|
||||||
|
For(w->views) if (it.id == view.id) return;
|
||||||
|
Add(&w->views, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
View *CreateView(BufferID buffer_id) {
|
||||||
|
View *w = Alloc(&Views);
|
||||||
|
w->id = AllocViewID();
|
||||||
|
w->buffer_id = buffer_id;
|
||||||
|
Add(&w->carets, {0, 0});
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetActiveWindow(WindowID window) {
|
||||||
|
if (LastFrameIDWhenSwitchedActiveWindow != FrameID) {
|
||||||
|
if (ActiveWindow.id != CommandWindowID.id) {
|
||||||
|
LastActiveWindow = ActiveWindow;
|
||||||
|
}
|
||||||
|
ActiveWindow = window;
|
||||||
|
LastFrameIDWhenSwitchedActiveWindow = FrameID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Window *FindParentWindow(ViewID view_id) {
|
||||||
|
ForItem(window, Windows) {
|
||||||
|
if (window.active_view.id == view_id.id) {
|
||||||
|
return &window;
|
||||||
|
} else {
|
||||||
|
ForItem(child_view, window.views) {
|
||||||
|
if (child_view.id == view_id.id) {
|
||||||
|
return &window;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
View *FindViewWithBufferName(String name) {
|
||||||
|
For(Views) {
|
||||||
|
Buffer *buffer = GetBuffer(it.buffer_id);
|
||||||
|
if (buffer->name == name) {
|
||||||
|
return ⁢
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer *BufferOpenFile(String path) {
|
||||||
|
Scratch scratch;
|
||||||
|
String abs_path = GetAbsolutePath(scratch, path);
|
||||||
|
|
||||||
|
Buffer *possible_buffer = GetBuffer(abs_path);
|
||||||
|
if (!IsNull(possible_buffer)) return possible_buffer;
|
||||||
|
|
||||||
|
Allocator sys_allocator = GetSystemAllocator();
|
||||||
|
if (!FileExists(path)) {
|
||||||
|
String dir = ChopLastSlash(abs_path);
|
||||||
|
if (!IsDir(dir)) {
|
||||||
|
return GetBuffer(NullBufferID);
|
||||||
|
} else {
|
||||||
|
path = Copy(sys_allocator, abs_path);
|
||||||
|
Buffer *buffer = CreateBuffer(sys_allocator, path);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
path = Copy(sys_allocator, abs_path);
|
||||||
|
String string = ReadFile(scratch, path);
|
||||||
|
Buffer *buffer = CreateBuffer(sys_allocator, path, string.len * 4);
|
||||||
|
|
||||||
|
for (Int i = 0; i < string.len;) {
|
||||||
|
if (string.data[i] == '\r') {
|
||||||
|
i += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (string.data[i] == '\t') {
|
||||||
|
// @WARNING: DONT INCREASE THE SIZE CARELESSLY, WE NEED TO ADJUST BUFFER SIZE
|
||||||
|
for (Int i = 0; i < 4; i += 1) buffer->data[buffer->len++] = L' ';
|
||||||
|
i += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t u32 = '?';
|
||||||
|
UTF32Result decode = UTF8ToUTF32(string.data + i, (int64_t)(string.len - i));
|
||||||
|
if (!decode.error) {
|
||||||
|
i += decode.advance;
|
||||||
|
u32 = decode.out_str;
|
||||||
|
} else {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UTF16Result encode = UTF32ToUTF16(decode.out_str);
|
||||||
|
if (!encode.error) {
|
||||||
|
for (int64_t encode_i = 0; encode_i < encode.len; encode_i += 1) {
|
||||||
|
buffer->data[buffer->len++] = encode.out_str[encode_i];
|
||||||
|
Assert(buffer->len < buffer->cap);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buffer->data[buffer->len++] = L'?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UpdateLines(buffer, {}, String16{(wchar_t *)buffer->data, buffer->len});
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
View *ViewOpenFile(String name) {
|
||||||
|
// if there is no view for this file, create one
|
||||||
|
View *view = FindViewWithBufferName(name);
|
||||||
|
if (!view) {
|
||||||
|
Buffer *buffer = BufferOpenFile(name);
|
||||||
|
if (IsNull(buffer)) Assert(0); // @todo
|
||||||
|
view = CreateView(buffer->id);
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is a buffer and view for this file then figure out
|
||||||
|
// if we need another view or can we reuse
|
||||||
|
Window *window = FindParentWindow(view->id);
|
||||||
|
if (!window) {
|
||||||
|
Buffer *buffer = BufferOpenFile(name);
|
||||||
|
if (IsNull(buffer)) Assert(0); // @todo
|
||||||
|
view = CreateView(buffer->id);
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new view, 2 view into same buffer at the same time
|
||||||
|
if (window->active_view.id == view->id.id) {
|
||||||
|
Buffer *buffer = BufferOpenFile(name);
|
||||||
|
if (IsNull(buffer)) Assert(0); // @todo
|
||||||
|
view = CreateView(buffer->id);
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlink and reuse
|
||||||
|
For(window->views) {
|
||||||
|
if (it.id == view->id.id) {
|
||||||
|
UnorderedRemove(&window->views, it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return view;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user