Compare commits
2 Commits
101fed6d7d
...
de06ea05cc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de06ea05cc | ||
|
|
5fecc74193 |
@@ -160,7 +160,7 @@ API bool AreOverlapping(Caret a, Caret b) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
API Range GetLineRange(Buffer *buffer, Int line, Int *end_of_buffer) {
|
API Range GetLineRange(Buffer *buffer, Int line, Int *end_of_buffer = NULL) {
|
||||||
Range result = {buffer->line_starts[line], buffer->len};
|
Range result = {buffer->line_starts[line], buffer->len};
|
||||||
if (line + 1 < buffer->line_starts.len) {
|
if (line + 1 < buffer->line_starts.len) {
|
||||||
result.max = buffer->line_starts[line + 1];
|
result.max = buffer->line_starts[line + 1];
|
||||||
@@ -177,14 +177,14 @@ API Range GetLineRangeWithoutNL(Buffer *buffer, Int line) {
|
|||||||
return line_range;
|
return line_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
API String16 GetString(Buffer *buffer, Range range) {
|
API String16 GetString(Buffer *buffer, Range range = {0, INT64_MAX}) {
|
||||||
range.min = Clamp(range.min, (Int)0, buffer->len);
|
range.min = Clamp(range.min, (Int)0, buffer->len);
|
||||||
range.max = Clamp(range.max, (Int)0, buffer->len);
|
range.max = Clamp(range.max, (Int)0, buffer->len);
|
||||||
String16 result = {(char16_t *)buffer->data + range.min, GetSize(range)};
|
String16 result = {(char16_t *)buffer->data + range.min, GetSize(range)};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
API String AllocCharString(Allocator allocator, Buffer *buffer, Range range) {
|
API String AllocCharString(Allocator allocator, Buffer *buffer, Range range = {0, INT64_MAX}) {
|
||||||
String16 string16 = GetString(buffer, range);
|
String16 string16 = GetString(buffer, range);
|
||||||
String result = ToString(allocator, string16);
|
String result = ToString(allocator, string16);
|
||||||
return result;
|
return result;
|
||||||
@@ -211,7 +211,7 @@ API Int LastLine(Buffer *buffer) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
API String16 GetLineString(Buffer *buffer, Int line, Int *end_of_buffer) {
|
API String16 GetLineString(Buffer *buffer, Int line, Int *end_of_buffer = NULL) {
|
||||||
Range range = GetLineRange(buffer, line, end_of_buffer);
|
Range range = GetLineRange(buffer, line, end_of_buffer);
|
||||||
String16 string = GetString(buffer, range);
|
String16 string = GetString(buffer, range);
|
||||||
return string;
|
return string;
|
||||||
@@ -453,7 +453,7 @@ API Int GetFullLineStart(Buffer *buffer, Int pos) {
|
|||||||
return range.min;
|
return range.min;
|
||||||
}
|
}
|
||||||
|
|
||||||
API Int GetFullLineEnd(Buffer *buffer, Int pos, Int *eof) {
|
API Int GetFullLineEnd(Buffer *buffer, Int pos, Int *eof = NULL) {
|
||||||
pos = Clamp(pos, (Int)0, buffer->len);
|
pos = Clamp(pos, (Int)0, buffer->len);
|
||||||
Int line = PosToLine(buffer, pos);
|
Int line = PosToLine(buffer, pos);
|
||||||
Range range = GetLineRange(buffer, line, eof);
|
Range range = GetLineRange(buffer, line, eof);
|
||||||
@@ -674,6 +674,8 @@ void RawValidateLineStarts(Buffer *buffer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These don't handle history, just raw operations on buffer memory
|
||||||
|
// TODO: MAYBE THEY SHOULD!
|
||||||
API void RawReplaceText(Buffer *buffer, Range range, String16 string) {
|
API void RawReplaceText(Buffer *buffer, Range range, String16 string) {
|
||||||
ProfileFunction();
|
ProfileFunction();
|
||||||
Assert(range.max >= range.min);
|
Assert(range.max >= range.min);
|
||||||
@@ -986,6 +988,9 @@ API Array<Edit> BeginEdit(Allocator allocator, Buffer *buffer, Array<Caret> &car
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We can invoke SaveCaretHistoryBeforeBeginEdit(which is basically BeginEdit with
|
||||||
|
// different name before caret altering commands to save caret history
|
||||||
|
// and then call some editing command to edit which is not going to save carets
|
||||||
API void SaveCaretHistoryBeforeBeginEdit(Buffer *buffer, Array<Caret> &carets) {
|
API void SaveCaretHistoryBeforeBeginEdit(Buffer *buffer, Array<Caret> &carets) {
|
||||||
BeginEdit({}, buffer, carets);
|
BeginEdit({}, buffer, carets);
|
||||||
}
|
}
|
||||||
@@ -996,6 +1001,9 @@ API void AssertRanges(Array<Caret> carets) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adjusts caret copies after edit to make them not move after for example
|
||||||
|
// a bar modification. Sometimes works, sometimes doesn't, depends, not an all solving tool.
|
||||||
|
// For example in case of ReopenBuffer, when we select and replace entire buffer, it didn't quite work.
|
||||||
API void AdjustCarets(Array<Edit> edits, Array<Caret> *carets) {
|
API void AdjustCarets(Array<Edit> edits, Array<Caret> *carets) {
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Array<Caret> new_carets = TightCopy(scratch, *carets);
|
Array<Caret> new_carets = TightCopy(scratch, *carets);
|
||||||
@@ -1375,7 +1383,7 @@ void Close(BufferID id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer *CreateBuffer(Allocator allocator, String name, Int size) {
|
Buffer *CreateBuffer(Allocator allocator, String name, Int size = 4096) {
|
||||||
Buffer *result = AllocBuffer(allocator, name, size);
|
Buffer *result = AllocBuffer(allocator, name, size);
|
||||||
Add(&Buffers, result);
|
Add(&Buffers, result);
|
||||||
return result;
|
return result;
|
||||||
@@ -1468,6 +1476,15 @@ String16 ToUnixString16(Allocator allocator, String string_) {
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function as name suggests tries to open a buffer,
|
||||||
|
// there is no name resolution here, path should already be resolved etc.
|
||||||
|
//
|
||||||
|
// 1. It tries to find an already open buffer
|
||||||
|
// 2. Returns a buffer if the file doesn't exist (even if a directory doesn't exist)
|
||||||
|
// - This is a worry for later time, also we want to handle weird names and so on
|
||||||
|
// 3. If file exists we read it, convert to utf16, tabs to spaces etc.
|
||||||
|
//
|
||||||
|
// We don't really care about opening buffers that don't have proper paths
|
||||||
Buffer *BufferOpenFile(String path) {
|
Buffer *BufferOpenFile(String path) {
|
||||||
ProfileFunction();
|
ProfileFunction();
|
||||||
Allocator sys_allocator = GetSystemAllocator();
|
Allocator sys_allocator = GetSystemAllocator();
|
||||||
|
|||||||
@@ -1,164 +0,0 @@
|
|||||||
struct Buffer;
|
|
||||||
struct BufferID { Int id; Buffer *o; };
|
|
||||||
union Range { struct { Int min; Int max; }; Int e[2]; };
|
|
||||||
struct Caret { union { Range range; Int pos[2]; }; Int ifront;};
|
|
||||||
struct XY { Int col; Int line; };
|
|
||||||
|
|
||||||
struct Edit {
|
|
||||||
Range range;
|
|
||||||
String16 string;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HistoryEntry {
|
|
||||||
Array<Edit> edits;
|
|
||||||
Array<Caret> carets;
|
|
||||||
double time;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Buffer {
|
|
||||||
BufferID id;
|
|
||||||
String name;
|
|
||||||
Int begin_frame_change_id;
|
|
||||||
Int change_id;
|
|
||||||
Int user_change_id;
|
|
||||||
Int file_mod_time;
|
|
||||||
|
|
||||||
union {
|
|
||||||
U16 *data;
|
|
||||||
char16_t*str;
|
|
||||||
};
|
|
||||||
Int len;
|
|
||||||
Int cap;
|
|
||||||
Array<Int> line_starts;
|
|
||||||
|
|
||||||
Array<HistoryEntry> undo_stack;
|
|
||||||
Array<HistoryEntry> redo_stack;
|
|
||||||
int edit_phase;
|
|
||||||
struct {
|
|
||||||
unsigned no_history : 1;
|
|
||||||
unsigned no_line_starts : 1;
|
|
||||||
unsigned dirty : 1;
|
|
||||||
unsigned changed_on_disk : 1;
|
|
||||||
unsigned temp : 1;
|
|
||||||
unsigned dont_try_to_save_in_bulk_ops : 1;
|
|
||||||
unsigned close : 1;
|
|
||||||
unsigned special : 1;
|
|
||||||
unsigned is_dir : 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FuzzyPair {
|
|
||||||
int32_t index;
|
|
||||||
float rating;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
KILL_SELECTION = 1,
|
|
||||||
};
|
|
||||||
constexpr Int LAST_LINE = INT64_MAX;
|
|
||||||
|
|
||||||
// @todo: buffer init, deinit
|
|
||||||
API Range MakeRange(Int a, Int b);
|
|
||||||
API Range MakeRange(Int a);
|
|
||||||
API Int GetSize(Range range);
|
|
||||||
API bool AreEqual(Range a, Range b);
|
|
||||||
API bool AreOverlapping(Range a, Range b);
|
|
||||||
API bool InBounds(Range range, Int pos);
|
|
||||||
API Range operator-(Range a, Int value);
|
|
||||||
API Range operator-=(Range &range, Int value);
|
|
||||||
API Range operator+(Range a, Int value);
|
|
||||||
API Range operator+=(Range &range, Int value);
|
|
||||||
API Range GetBufferEndAsRange(Buffer *buffer);
|
|
||||||
API Range GetBufferBeginAsRange(Buffer *buffer);
|
|
||||||
API Range GetRange(Buffer *buffer);
|
|
||||||
API Int Clamp(const Buffer *buffer, Int pos);
|
|
||||||
API Range Clamp(const Buffer *buffer, Range range);
|
|
||||||
|
|
||||||
API Int GetFront(Caret caret);
|
|
||||||
API Int GetBack(Caret caret);
|
|
||||||
API Caret MakeCaret(Int pos);
|
|
||||||
API Caret MakeCaret(Int front, Int back);
|
|
||||||
API Caret SetBack(Caret caret, Int back);
|
|
||||||
API Caret SetFront(Caret caret, Int front);
|
|
||||||
API Caret SetFrontWithAnchor(Caret caret, Caret anchor, Int p);
|
|
||||||
API bool AreEqual(Caret a, Caret b);
|
|
||||||
API bool AreOverlapping(Caret a, Caret b);
|
|
||||||
|
|
||||||
API Range GetLineRange(Buffer *buffer, Int line, Int *end_of_buffer = NULL);
|
|
||||||
API Range GetLineRangeWithoutNL(Buffer *buffer, Int line);
|
|
||||||
API String16 GetString(Buffer *buffer, Range range = {0, INT64_MAX});
|
|
||||||
API String AllocCharString(Allocator allocator, Buffer *buffer, Range range = {0, INT64_MAX});
|
|
||||||
API String16 GetLineString(Buffer *buffer, Int line, Int *end_of_buffer = NULL);
|
|
||||||
API String16 GetLineStringWithoutNL(Buffer *buffer, Int line);
|
|
||||||
|
|
||||||
API XY XYLine(Int line);
|
|
||||||
API Int LastLine(Buffer *buffer);
|
|
||||||
API Int PosToLine(Buffer *buffer, Int pos);
|
|
||||||
API XY PosToXY(Buffer *buffer, Int pos);
|
|
||||||
API Int XYToPos(Buffer *buffer, XY xy);
|
|
||||||
API Int XYToPosWithoutNL(Buffer *buffer, XY xy);
|
|
||||||
API Int XYToPosErrorOutOfBounds(Buffer *buffer, XY xy);
|
|
||||||
|
|
||||||
API char16_t GetChar(Buffer *buffer, Int pos);
|
|
||||||
API bool InBounds(const Buffer *buffer, Int pos);
|
|
||||||
API Int GetWordStart(Buffer *buffer, Int pos);
|
|
||||||
API Int GetWordEnd(Buffer *buffer, Int pos);
|
|
||||||
API bool IsLoadWord(char16_t w);
|
|
||||||
API Int GetLoadWordStart(Buffer *buffer, Int pos);
|
|
||||||
API Int GetLoadWordEnd(Buffer *buffer, Int pos);
|
|
||||||
API Range EncloseLoadWord(Buffer *buffer, Int pos);
|
|
||||||
API Int GetNextWordEnd(Buffer *buffer, Int pos);
|
|
||||||
API Int GetPrevWordStart(Buffer *buffer, Int pos);
|
|
||||||
API Int GetLineStart(Buffer *buffer, Int pos);
|
|
||||||
API Int GetLineEnd(Buffer *buffer, Int pos);
|
|
||||||
API Int GetFullLineStart(Buffer *buffer, Int pos);
|
|
||||||
API Int GetFullLineEnd(Buffer *buffer, Int pos, Int *eof = NULL);
|
|
||||||
API Int GetBufferEnd(Buffer *buffer);
|
|
||||||
API Int GetBufferStart(Buffer *buffer);
|
|
||||||
API Int GetNextEmptyLineStart(Buffer *buffer, Int pos);
|
|
||||||
API Int GetPrevEmptyLineStart(Buffer *buffer, Int pos);
|
|
||||||
API Range EncloseWord(Buffer *buffer, Int pos);
|
|
||||||
API Int SkipSpaces(Buffer *buffer, Int seek);
|
|
||||||
API Range EncloseLine(Buffer *buffer, Int pos);
|
|
||||||
API Range EncloseFullLine(Buffer *buffer, Int pos);
|
|
||||||
API Int OffsetByLine(Buffer *buffer, Int pos, Int line_offset);
|
|
||||||
API Int GetNextChar(Buffer *buffer, Int pos);
|
|
||||||
API Int GetPrevChar(Buffer *buffer, Int pos);
|
|
||||||
API Int GetLineIndent(Buffer *buffer, Int line);
|
|
||||||
API Int GetIndentAtPos(Buffer *buffer, Int pos);
|
|
||||||
API Range GetIndentRangeAtPos(Buffer *buffer, Int pos);
|
|
||||||
|
|
||||||
API Int FindRangeByPos(Array<Range> *ranges, Int pos);
|
|
||||||
|
|
||||||
// These don't handle history, just raw operations on buffer memory
|
|
||||||
API void RawReplaceText(Buffer *buffer, Range range, String16 string);
|
|
||||||
API void RawAppend(Buffer *buffer, String16 string);
|
|
||||||
API void RawAppend(Buffer *buffer, String string);
|
|
||||||
API void RawAppendf(Buffer *buffer, const char *fmt, ...);
|
|
||||||
|
|
||||||
// We can invoke SaveCaretHistoryBeforeBeginEdit(which is basically BeginEdit with
|
|
||||||
// different name before caret altering commands to save caret history
|
|
||||||
// and then call some editing command to edit which is not going to save carets
|
|
||||||
API void SaveCaretHistoryBeforeBeginEdit(Buffer *buffer, Array<Caret> &carets);
|
|
||||||
API Array<Edit> BeginEdit(Allocator allocator, Buffer *buffer, Array<Caret> &carets);
|
|
||||||
API void EndEdit(Buffer *buffer, Array<Edit> *edits, Array<Caret> *carets, bool kill_selection);
|
|
||||||
API void AddEdit(Array<Edit> *e, Range range, String16 string);
|
|
||||||
|
|
||||||
// Merge carets that overlap, this needs to be handled before any edits to
|
|
||||||
// make sure overlapping edits won't happen.
|
|
||||||
//
|
|
||||||
// mouse_selection_anchor is special case for mouse handling !
|
|
||||||
API void MergeCarets(Buffer *buffer, Array<Caret> *carets);
|
|
||||||
|
|
||||||
// Adjusts caret copies after edit to make them not move after for example
|
|
||||||
// a bar modification. Sometimes works, sometimes doesn't, depends, not an all solving tool.
|
|
||||||
// For example in case of ReopenBuffer, when we select and replace entire buffer, it didn't quite work.
|
|
||||||
API void AdjustCarets(Array<Edit> edits, Array<Caret> *carets);
|
|
||||||
API void AssertRanges(Array<Caret> carets);
|
|
||||||
|
|
||||||
API void RedoEdit(Buffer *buffer, Array<Caret> *carets);
|
|
||||||
API void UndoEdit(Buffer *buffer, Array<Caret> *carets);
|
|
||||||
API void ResetHistory(Buffer *buffer);
|
|
||||||
|
|
||||||
API void DeallocHistoryArray(Array<HistoryEntry> *entries);
|
|
||||||
API void DeallocHistoryEntries(Array<HistoryEntry> *entries);
|
|
||||||
@@ -28,6 +28,12 @@ struct Trigger {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CachedTrigger {
|
||||||
|
Trigger *trigger;
|
||||||
|
String key;
|
||||||
|
};
|
||||||
|
Array<CachedTrigger> CachedTriggers;
|
||||||
|
|
||||||
void Advance(Lexer *lex) {
|
void Advance(Lexer *lex) {
|
||||||
if (lex->at < lex->end) {
|
if (lex->at < lex->end) {
|
||||||
if (lex->at[0] == '\n') {
|
if (lex->at[0] == '\n') {
|
||||||
@@ -168,12 +174,6 @@ Trigger *ParseKey(Allocator allocator, String key, char *debug_name) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CachedTrigger {
|
|
||||||
Trigger *trigger;
|
|
||||||
String key;
|
|
||||||
};
|
|
||||||
Array<CachedTrigger> CachedTriggers;
|
|
||||||
|
|
||||||
Trigger *ParseKeyCached(String key) {
|
Trigger *ParseKeyCached(String key) {
|
||||||
key = Trim(key);
|
key = Trim(key);
|
||||||
if (key.len == 0) {
|
if (key.len == 0) {
|
||||||
|
|||||||
@@ -10,6 +10,16 @@ bool SearchCaseSensitive = false;
|
|||||||
bool SearchWordBoundary = false;
|
bool SearchWordBoundary = false;
|
||||||
bool BreakOnError = false;
|
bool BreakOnError = false;
|
||||||
|
|
||||||
|
Allocator SysAllocator = {SystemAllocatorProc};
|
||||||
|
String ConfigDir;
|
||||||
|
float DPIScale = 1.0f;
|
||||||
|
|
||||||
|
// @WARNING: be careful about using this, should only be used for debugging
|
||||||
|
// the problem with this is that we want events to be reproducible.
|
||||||
|
// We eat as many events as we can in a frame, we abstract the frame and so on.
|
||||||
|
// Dont use it
|
||||||
|
Int FrameID;
|
||||||
|
|
||||||
WindowID WindowIDs;
|
WindowID WindowIDs;
|
||||||
ViewID ViewIDs;
|
ViewID ViewIDs;
|
||||||
Int BufferIDs;
|
Int BufferIDs;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "basic/basic.h"
|
#include "basic/basic.h"
|
||||||
#include "basic/basic.cpp"
|
#include "basic/basic.cpp"
|
||||||
#include "profiler.h"
|
#include "profiler.h"
|
||||||
|
|
||||||
#include "SDL3/SDL.h"
|
#include "SDL3/SDL.h"
|
||||||
#include "external/glad/glad.c"
|
#include "external/glad/glad.c"
|
||||||
#include "external/glad/glad.h"
|
#include "external/glad/glad.h"
|
||||||
@@ -12,16 +11,10 @@
|
|||||||
#endif
|
#endif
|
||||||
#define MINICORO_IMPL
|
#define MINICORO_IMPL
|
||||||
#include "external/minicoro.h"
|
#include "external/minicoro.h"
|
||||||
|
|
||||||
#include "render/generated_font.cpp"
|
#include "render/generated_font.cpp"
|
||||||
#include "render/font.cpp"
|
#include "render/font.cpp"
|
||||||
#include "render/opengl.cpp"
|
#include "render/opengl.cpp"
|
||||||
|
|
||||||
#include "buffer.h"
|
|
||||||
#include "view.h"
|
|
||||||
#include "window.h"
|
|
||||||
#include "text_editor.h"
|
#include "text_editor.h"
|
||||||
|
|
||||||
#include "globals.cpp"
|
#include "globals.cpp"
|
||||||
#include "coroutines.cpp"
|
#include "coroutines.cpp"
|
||||||
#include "buffer.cpp"
|
#include "buffer.cpp"
|
||||||
@@ -32,14 +25,11 @@
|
|||||||
#include "window_status.cpp"
|
#include "window_status.cpp"
|
||||||
#include "window_search.cpp"
|
#include "window_search.cpp"
|
||||||
#include "window_build.cpp"
|
#include "window_build.cpp"
|
||||||
|
|
||||||
#include "process.cpp"
|
#include "process.cpp"
|
||||||
#include "event.cpp"
|
#include "event.cpp"
|
||||||
#include "config.cpp"
|
#include "config.cpp"
|
||||||
|
|
||||||
#include "commands.cpp"
|
#include "commands.cpp"
|
||||||
#include "commands_clipboard.cpp"
|
#include "commands_clipboard.cpp"
|
||||||
|
|
||||||
#include "scratch.cpp"
|
#include "scratch.cpp"
|
||||||
#include "draw.cpp"
|
#include "draw.cpp"
|
||||||
#include "test/tests.cpp"
|
#include "test/tests.cpp"
|
||||||
|
|||||||
@@ -1,3 +1,203 @@
|
|||||||
|
struct Buffer;
|
||||||
|
struct View;
|
||||||
|
struct Window;
|
||||||
|
struct BufferID { Int id; Buffer *o; };
|
||||||
|
struct ViewID { Int id; View *o; };
|
||||||
|
struct WindowID { Int id; Window *o; };
|
||||||
|
union Range { struct { Int min; Int max; }; Int e[2]; };
|
||||||
|
struct Caret { union { Range range; Int pos[2]; }; Int ifront;};
|
||||||
|
struct XY { Int col; Int line; };
|
||||||
|
typedef void Function();
|
||||||
|
|
||||||
|
struct FunctionData {
|
||||||
|
String name;
|
||||||
|
Function *function;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Edit {
|
||||||
|
Range range;
|
||||||
|
String16 string;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HistoryEntry {
|
||||||
|
Array<Edit> edits;
|
||||||
|
Array<Caret> carets;
|
||||||
|
double time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Buffer {
|
||||||
|
BufferID id;
|
||||||
|
String name;
|
||||||
|
Int begin_frame_change_id;
|
||||||
|
Int change_id;
|
||||||
|
Int user_change_id;
|
||||||
|
Int file_mod_time;
|
||||||
|
|
||||||
|
union {
|
||||||
|
U16 *data;
|
||||||
|
char16_t*str;
|
||||||
|
};
|
||||||
|
Int len;
|
||||||
|
Int cap;
|
||||||
|
Array<Int> line_starts;
|
||||||
|
|
||||||
|
Array<HistoryEntry> undo_stack;
|
||||||
|
Array<HistoryEntry> redo_stack;
|
||||||
|
int edit_phase;
|
||||||
|
struct {
|
||||||
|
unsigned no_history : 1;
|
||||||
|
unsigned no_line_starts : 1;
|
||||||
|
unsigned dirty : 1;
|
||||||
|
unsigned changed_on_disk : 1;
|
||||||
|
unsigned temp : 1;
|
||||||
|
unsigned dont_try_to_save_in_bulk_ops : 1;
|
||||||
|
unsigned close : 1;
|
||||||
|
unsigned special : 1;
|
||||||
|
unsigned is_dir : 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
enum HookKind {
|
||||||
|
HookKind_Invalid,
|
||||||
|
|
||||||
|
HookKind_AppInit,
|
||||||
|
HookKind_AppUpdate,
|
||||||
|
HookKind_AppExit,
|
||||||
|
|
||||||
|
HookKind_Binding,
|
||||||
|
|
||||||
|
HookKind_BeforeLayoutWindow,
|
||||||
|
HookKind_HandleLayoutWindow,
|
||||||
|
HookKind_AfterLayoutWindow,
|
||||||
|
|
||||||
|
HookKind_BeforeRenderWindow,
|
||||||
|
HookKind_HandleRenderWindow,
|
||||||
|
HookKind_AfterRenderWindow,
|
||||||
|
|
||||||
|
HookKind_BeforeBufferSave,
|
||||||
|
HookKind_HandleBufferSave,
|
||||||
|
HookKind_AfterBufferSave,
|
||||||
|
|
||||||
|
HookKind_BeforeBufferOpen,
|
||||||
|
HookKind_HandleBufferOpen,
|
||||||
|
HookKind_AfterBufferOpen,
|
||||||
|
|
||||||
|
HookKind_ViewUpdate,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Global hooks, per (window, view, buffer) hooks
|
||||||
|
|
||||||
|
struct HookParam {
|
||||||
|
struct Hook *hook;
|
||||||
|
Buffer *buffer;
|
||||||
|
View *view;
|
||||||
|
Window *window;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void HookFunction(HookParam *param);
|
||||||
|
struct Hook {
|
||||||
|
HookKind kind;
|
||||||
|
String name;
|
||||||
|
String doc;
|
||||||
|
HookFunction *function;
|
||||||
|
|
||||||
|
// HookKind_Binding
|
||||||
|
String binding;
|
||||||
|
struct Trigger *trigger;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CommandData {
|
||||||
|
String name;
|
||||||
|
String binding;
|
||||||
|
Function *function;
|
||||||
|
String doc;
|
||||||
|
struct Trigger *trigger;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ViewKind {
|
||||||
|
ViewKind_Normal,
|
||||||
|
ViewKind_FuzzySearch,
|
||||||
|
ViewKind_ActiveSearch,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct View {
|
||||||
|
ViewID id;
|
||||||
|
BufferID active_buffer;
|
||||||
|
ViewKind kind;
|
||||||
|
Vec2I scroll;
|
||||||
|
Array<Caret> carets;
|
||||||
|
|
||||||
|
// window | view
|
||||||
|
Caret main_caret_on_begin_frame;
|
||||||
|
bool update_scroll;
|
||||||
|
|
||||||
|
String hook_cmd;
|
||||||
|
Array<CommandData> hooks;
|
||||||
|
uint64_t prev_search_line_hash;
|
||||||
|
struct {
|
||||||
|
unsigned close : 1;
|
||||||
|
unsigned special : 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GotoCrumb {
|
||||||
|
ViewID view_id;
|
||||||
|
Caret caret;
|
||||||
|
double time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Window {
|
||||||
|
WindowID id;
|
||||||
|
ViewID active_view;
|
||||||
|
|
||||||
|
Rect2I total_rect;
|
||||||
|
Rect2I document_rect;
|
||||||
|
Rect2I scrollbar_rect;
|
||||||
|
Rect2I line_numbers_rect;
|
||||||
|
Rect2I resizer_rect;
|
||||||
|
|
||||||
|
Font *font;
|
||||||
|
double mouse_scroller_offset;
|
||||||
|
int z;
|
||||||
|
double weight;
|
||||||
|
Caret search_bar_anchor;
|
||||||
|
|
||||||
|
GotoCrumb begin_frame_crumb;
|
||||||
|
Array<GotoCrumb> goto_history;
|
||||||
|
Array<GotoCrumb> goto_redo;
|
||||||
|
|
||||||
|
ViewID active_goto_list;
|
||||||
|
Int goto_list_pos;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t draw_scrollbar : 1;
|
||||||
|
uint32_t draw_line_numbers : 1;
|
||||||
|
uint32_t secondary_window_style : 1;
|
||||||
|
uint32_t draw_line_highlight : 1;
|
||||||
|
uint32_t visible : 1;
|
||||||
|
uint32_t primary : 1;
|
||||||
|
uint32_t close : 1;
|
||||||
|
uint32_t sync_visibility_with_focus : 1;
|
||||||
|
uint32_t lose_focus_on_escape : 1;
|
||||||
|
uint32_t lose_visibility_on_escape : 1;
|
||||||
|
uint32_t jump_history : 1;
|
||||||
|
uint32_t skip_checkpoint : 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Scroller {
|
||||||
|
Rect2 rect;
|
||||||
|
double begin;
|
||||||
|
double end;
|
||||||
|
Int line_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BSet {
|
||||||
|
struct Window *window;
|
||||||
|
View *view;
|
||||||
|
Buffer *buffer;
|
||||||
|
};
|
||||||
|
|
||||||
#define EVENT_KINDS \
|
#define EVENT_KINDS \
|
||||||
X(EVENT_NONE) \
|
X(EVENT_NONE) \
|
||||||
X(EVENT_UPDATE) \
|
X(EVENT_UPDATE) \
|
||||||
@@ -54,96 +254,10 @@ struct Event {
|
|||||||
#undef X
|
#undef X
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BSet {
|
struct FuzzyPair {
|
||||||
struct Window *window;
|
int32_t index;
|
||||||
View *view;
|
float rating;
|
||||||
Buffer *buffer;
|
|
||||||
};
|
};
|
||||||
BSet GetBSet(struct Window *window);
|
|
||||||
BSet GetBSet(WindowID window_id);
|
|
||||||
|
|
||||||
|
|
||||||
// @WARNING: be careful about using this, should only be used for debugging
|
|
||||||
// the problem with this is that we want events to be reproducible.
|
|
||||||
// We eat as many events as we can in a frame, we abstract the frame and so on.
|
|
||||||
// Dont use it
|
|
||||||
Int FrameID;
|
|
||||||
|
|
||||||
Allocator SysAllocator = {SystemAllocatorProc};
|
|
||||||
String ConfigDir;
|
|
||||||
float DPIScale = 1.0f;
|
|
||||||
|
|
||||||
void AfterEdit(View *view, Array<Edit> edits);
|
|
||||||
Scroller ComputeScrollerRect(Window *window);
|
|
||||||
void UpdateScroll(Window *window, bool update_caret_scrolling);
|
|
||||||
String GetMainDir();
|
|
||||||
|
|
||||||
void SelectEntireBuffer(View *view);
|
|
||||||
void Replace(View *view, String16 string);
|
|
||||||
void SelectRange(View *view, Range range);
|
|
||||||
void Append(View *view, String16 string, bool scroll_to_end_if_cursor_on_last_line);
|
|
||||||
void Append(View *view, String string, bool scroll_to_end_if_cursor_on_last_line);
|
|
||||||
Array<Edit> ReplaceEx(Allocator scratch, View *view, String16 string);
|
|
||||||
void Eval(String string);
|
|
||||||
void Eval(String16 string);
|
|
||||||
void ReportDebugf(const char *fmt, ...);
|
|
||||||
|
|
||||||
void ReplaceWithoutMovingCarets(Buffer *buffer, Range range, String16 string);
|
|
||||||
void ClipboardCopy(View *view);
|
|
||||||
void ClipboardPaste(View *view);
|
|
||||||
|
|
||||||
void ReportConsolef(const char *fmt, ...);
|
|
||||||
void ReportErrorf(const char *fmt, ...);
|
|
||||||
void ReportWarningf(const char *fmt, ...);
|
|
||||||
void Appendf(View *view, const char *fmt, ...);
|
|
||||||
|
|
||||||
Buffer *CreateBuffer(Allocator allocator, String name, Int size = 4096);
|
|
||||||
View *CreateView(BufferID active_buffer);
|
|
||||||
void ReopenBuffer(Buffer *buffer);
|
|
||||||
bool ProcessIsActive(ViewID view);
|
|
||||||
void EvalCommand(String command);
|
|
||||||
void EvalCommand(String16 command);
|
|
||||||
|
|
||||||
inline bool operator==(BufferID a, BufferID b) { return a.id == b.id; }
|
|
||||||
inline bool operator==(ViewID a, ViewID b) { return a.id == b.id; }
|
|
||||||
inline bool operator!=(BufferID a, BufferID b) { return a.id != b.id; }
|
|
||||||
inline bool operator!=(ViewID a, ViewID b) { return a.id != b.id; }
|
|
||||||
|
|
||||||
// This function as name suggests tries to open a buffer,
|
|
||||||
// there is no name resolution here, path should already be resolved etc.
|
|
||||||
//
|
|
||||||
// 1. It tries to find an already open buffer
|
|
||||||
// 2. Returns a buffer if the file doesn't exist (even if a directory doesn't exist)
|
|
||||||
// - This is a worry for later time, also we want to handle weird names and so on
|
|
||||||
// 3. If file exists we read it, convert to utf16, tabs to spaces etc.
|
|
||||||
//
|
|
||||||
// We don't really care about opening buffers that don't have proper paths
|
|
||||||
Buffer *BufferOpenFile(String path);
|
|
||||||
|
|
||||||
typedef void PFunction(void *param);
|
|
||||||
struct PFunctionData { String name; PFunction *function; };
|
|
||||||
|
|
||||||
struct Register_Function {
|
|
||||||
Register_Function(Array<FunctionData> *functions, String name, Function *f) {
|
|
||||||
int64_t pos = 0;
|
|
||||||
if (Seek(name, "_", &pos, 0)) {
|
|
||||||
name = Skip(name, pos + 1);
|
|
||||||
}
|
|
||||||
Add(functions, {name, f});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#define RegisterFunction(functions, name) Register_Function RF__##name(functions, #name, name)
|
|
||||||
|
|
||||||
struct Register_Command { Register_Command(Array<CommandData> *fucs, Function *function, String name, String binding, String doc = "") { if (StartsWith(name, "CMD_")) name = Skip(name, sizeof("CMD_") - 1); Add(fucs, {name, binding, function, doc}); } };
|
|
||||||
#define RegisterCommand(name, ...) Register_Command RC__##name(&CommandFunctions, name, #name, __VA_ARGS__)
|
|
||||||
|
|
||||||
const int DIR_RIGHT = 0;
|
|
||||||
const int DIR_LEFT = 1;
|
|
||||||
const int DIR_DOWN = 2;
|
|
||||||
const int DIR_UP = 3;
|
|
||||||
const int DIR_COUNT = 4;
|
|
||||||
const bool CTRL_PRESSED = true;
|
|
||||||
const bool SHIFT_PRESS = true;
|
|
||||||
|
|
||||||
enum VariableType {
|
enum VariableType {
|
||||||
VariableType_Invalid,
|
VariableType_Invalid,
|
||||||
@@ -174,8 +288,6 @@ struct Register_Variable {
|
|||||||
type name = __VA_ARGS__; \
|
type name = __VA_ARGS__; \
|
||||||
Register_Variable var_##name(&Variables, VariableType_##type, #name, &name)
|
Register_Variable var_##name(&Variables, VariableType_##type, #name, &name)
|
||||||
|
|
||||||
void AddHook(Array<CommandData> *arr, String name, String binding, Function *function);
|
|
||||||
|
|
||||||
enum OpenKind {
|
enum OpenKind {
|
||||||
OpenKind_Invalid,
|
OpenKind_Invalid,
|
||||||
OpenKind_Skip,
|
OpenKind_Skip,
|
||||||
@@ -200,11 +312,65 @@ struct ResolvedOpen {
|
|||||||
bool existing_buffer;
|
bool existing_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Register_Command { Register_Command(Array<CommandData> *fucs, Function *function, String name, String binding, String doc = "") { if (StartsWith(name, "CMD_")) name = Skip(name, sizeof("CMD_") - 1); Add(fucs, {name, binding, function, doc}); } };
|
||||||
|
#define RegisterCommand(name, ...) Register_Command RC__##name(&CommandFunctions, name, #name, __VA_ARGS__)
|
||||||
|
struct Register_Function {
|
||||||
|
Register_Function(Array<FunctionData> *functions, String name, Function *f) {
|
||||||
|
int64_t pos = 0;
|
||||||
|
if (Seek(name, "_", &pos, 0)) {
|
||||||
|
name = Skip(name, pos + 1);
|
||||||
|
}
|
||||||
|
Add(functions, {name, f});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#define RegisterFunction(functions, name) Register_Function RF__##name(functions, #name, name)
|
||||||
|
void AddHook(Array<CommandData> *arr, String name, String binding, Function *function);
|
||||||
|
|
||||||
|
constexpr int DIR_RIGHT = 0;
|
||||||
|
constexpr int DIR_LEFT = 1;
|
||||||
|
constexpr int DIR_DOWN = 2;
|
||||||
|
constexpr int DIR_UP = 3;
|
||||||
|
constexpr int DIR_COUNT = 4;
|
||||||
|
constexpr bool CTRL_PRESSED = true;
|
||||||
|
constexpr bool SHIFT_PRESS = true;
|
||||||
|
constexpr bool KILL_SELECTION = true;
|
||||||
|
constexpr Int LAST_LINE = INT64_MAX;
|
||||||
|
|
||||||
|
BSet GetBSet(struct Window *window);
|
||||||
|
BSet GetBSet(WindowID window_id);
|
||||||
|
void Append(View *view, String16 string, bool scroll_to_end_if_cursor_on_last_line);
|
||||||
|
void Append(View *view, String string, bool scroll_to_end_if_cursor_on_last_line);
|
||||||
|
void ReplaceWithoutMovingCarets(Buffer *buffer, Range range, String16 string);
|
||||||
|
void ReportDebugf(const char *fmt, ...);
|
||||||
|
void ReportConsolef(const char *fmt, ...);
|
||||||
|
void ReportErrorf(const char *fmt, ...);
|
||||||
|
void ReportWarningf(const char *fmt, ...);
|
||||||
|
void Appendf(View *view, const char *fmt, ...);
|
||||||
|
View *CreateView(BufferID active_buffer);
|
||||||
|
void EvalCommand(String command);
|
||||||
|
void EvalCommand(String16 command);
|
||||||
|
Rect2I GetVisibleCells(Window *window);
|
||||||
ResolvedOpen ResolveOpen(Allocator scratch, String path, ResolveOpenMeta meta);
|
ResolvedOpen ResolveOpen(Allocator scratch, String path, ResolveOpenMeta meta);
|
||||||
BSet Open(String path, ResolveOpenMeta meta = ResolveOpenMeta_Normal);
|
BSet Open(String path, ResolveOpenMeta meta = ResolveOpenMeta_Normal);
|
||||||
BSet Open(String16 path, ResolveOpenMeta meta = ResolveOpenMeta_Normal);
|
BSet Open(String16 path, ResolveOpenMeta meta = ResolveOpenMeta_Normal);
|
||||||
|
|
||||||
void CenterView(WindowID window);
|
void CenterView(WindowID window);
|
||||||
void TrimWhitespace(Buffer *buffer, bool trim_lines_with_caret = false);
|
void TrimWhitespace(Buffer *buffer, bool trim_lines_with_caret = false);
|
||||||
void ApplyFormattingTool(Buffer *buffer, String tool);
|
|
||||||
void JumpTempBuffer(BSet *set, String buffer_name = "");
|
void JumpTempBuffer(BSet *set, String buffer_name = "");
|
||||||
|
void CommandWindowLayout(Rect2I *rect, Int wx, Int wy);
|
||||||
|
void CommandWindowInit();
|
||||||
|
void SearchWindowLayout(Rect2I *rect, Int wx, Int wy);
|
||||||
|
void SearchWindowInit();
|
||||||
|
void StatusWindowInit();
|
||||||
|
void StatusWindowLayout(Rect2I *rect, Int wx, Int wy);
|
||||||
|
void DebugWindowInit();
|
||||||
|
void DebugWindowLayout(Rect2I *rect, Int wx, Int wy);
|
||||||
|
void BuildWindowInit();
|
||||||
|
void BuildWindowLayout(Rect2I *rect, Int wx, Int wy);
|
||||||
|
View *FindView(BufferID buffer_id, View *default_view = NULL);
|
||||||
|
|
||||||
|
bool operator==(BufferID a, BufferID b) { return a.id == b.id; }
|
||||||
|
bool operator==(ViewID a, ViewID b) { return a.id == b.id; }
|
||||||
|
bool operator!=(BufferID a, BufferID b) { return a.id != b.id; }
|
||||||
|
bool operator!=(ViewID a, ViewID b) { return a.id != b.id; }
|
||||||
|
bool operator==(WindowID a, WindowID b) { return a.id == b.id; }
|
||||||
|
bool operator!=(WindowID a, WindowID b) { return a.id != b.id; }
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ void Dealloc(View *view) {
|
|||||||
Dealloc(view->carets.allocator, view);
|
Dealloc(view->carets.allocator, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
API View *FindView(ViewID view_id, View *default_view) {
|
// TODO: default_view should probably be Views[0] but could break stuff
|
||||||
|
API View *FindView(ViewID view_id, View *default_view = NULL) {
|
||||||
For(Views) {
|
For(Views) {
|
||||||
if (it->id == view_id) {
|
if (it->id == view_id) {
|
||||||
return it;
|
return it;
|
||||||
@@ -38,7 +39,7 @@ API View *FindView(BufferID buffer_id, View *default_view) {
|
|||||||
return default_view;
|
return default_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
API View *FindView(String name, View *default_view) {
|
API View *FindView(String name, View *default_view = NULL) {
|
||||||
For(Views) {
|
For(Views) {
|
||||||
Buffer *buffer = GetBuffer(it->active_buffer);
|
Buffer *buffer = GetBuffer(it->active_buffer);
|
||||||
if (buffer->name == name) {
|
if (buffer->name == name) {
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
struct View;
|
|
||||||
struct ViewID { Int id; View *o; };
|
|
||||||
|
|
||||||
typedef void Function();
|
|
||||||
struct FunctionData {
|
|
||||||
String name;
|
|
||||||
Function *function;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CommandData {
|
|
||||||
String name;
|
|
||||||
String binding;
|
|
||||||
Function *function;
|
|
||||||
String doc;
|
|
||||||
struct Trigger *trigger;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ViewKind {
|
|
||||||
ViewKind_Normal,
|
|
||||||
ViewKind_FuzzySearch,
|
|
||||||
ViewKind_ActiveSearch,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct View {
|
|
||||||
ViewID id;
|
|
||||||
BufferID active_buffer;
|
|
||||||
ViewKind kind;
|
|
||||||
Vec2I scroll;
|
|
||||||
Array<Caret> carets;
|
|
||||||
|
|
||||||
// window | view
|
|
||||||
Caret main_caret_on_begin_frame;
|
|
||||||
bool update_scroll;
|
|
||||||
|
|
||||||
String hook_cmd;
|
|
||||||
Array<CommandData> hooks;
|
|
||||||
uint64_t prev_search_line_hash;
|
|
||||||
struct {
|
|
||||||
unsigned close : 1;
|
|
||||||
unsigned special : 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GotoCrumb {
|
|
||||||
ViewID view_id;
|
|
||||||
Caret caret;
|
|
||||||
double time;
|
|
||||||
};
|
|
||||||
|
|
||||||
API ViewID AllocViewID(View *view);
|
|
||||||
API View *CreateView(BufferID active_buffer);
|
|
||||||
API View *FindView(ViewID view_id, View *default_view = NULL);
|
|
||||||
API View *FindView(BufferID buffer_id, View *default_view = NULL);
|
|
||||||
API View *FindView(String name, View *default_view = NULL);
|
|
||||||
API View *GetView(ViewID id);
|
|
||||||
API View *OpenBufferView(String name);
|
|
||||||
API bool ViewIsCrumb(ViewID view_id);
|
|
||||||
API bool ViewIsReferenced(ViewID view);
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
struct Window;
|
|
||||||
struct WindowID { Int id; Window *o; };
|
|
||||||
|
|
||||||
struct Window {
|
|
||||||
WindowID id;
|
|
||||||
ViewID active_view;
|
|
||||||
|
|
||||||
Rect2I total_rect;
|
|
||||||
Rect2I document_rect;
|
|
||||||
Rect2I scrollbar_rect;
|
|
||||||
Rect2I line_numbers_rect;
|
|
||||||
Rect2I resizer_rect;
|
|
||||||
|
|
||||||
Font *font;
|
|
||||||
double mouse_scroller_offset;
|
|
||||||
int z;
|
|
||||||
double weight;
|
|
||||||
Caret search_bar_anchor;
|
|
||||||
|
|
||||||
GotoCrumb begin_frame_crumb;
|
|
||||||
Array<GotoCrumb> goto_history;
|
|
||||||
Array<GotoCrumb> goto_redo;
|
|
||||||
|
|
||||||
ViewID active_goto_list;
|
|
||||||
Int goto_list_pos;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint32_t draw_scrollbar : 1;
|
|
||||||
uint32_t draw_line_numbers : 1;
|
|
||||||
uint32_t secondary_window_style : 1;
|
|
||||||
uint32_t draw_line_highlight : 1;
|
|
||||||
uint32_t visible : 1;
|
|
||||||
uint32_t primary : 1;
|
|
||||||
uint32_t close : 1;
|
|
||||||
uint32_t sync_visibility_with_focus : 1;
|
|
||||||
uint32_t lose_focus_on_escape : 1;
|
|
||||||
uint32_t lose_visibility_on_escape : 1;
|
|
||||||
uint32_t jump_history : 1;
|
|
||||||
uint32_t skip_checkpoint : 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Scroller {
|
|
||||||
Rect2 rect;
|
|
||||||
double begin;
|
|
||||||
double end;
|
|
||||||
Int line_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool operator==(WindowID a, WindowID b) { return a.id == b.id; }
|
|
||||||
inline bool operator!=(WindowID a, WindowID b) { return a.id != b.id; }
|
|
||||||
Rect2I GetVisibleCells(Window *window);
|
|
||||||
Window *CreateWind();
|
|
||||||
|
|
||||||
void CommandWindowLayout(Rect2I *rect, Int wx, Int wy);
|
|
||||||
void CommandWindowInit();
|
|
||||||
|
|
||||||
void SearchWindowLayout(Rect2I *rect, Int wx, Int wy);
|
|
||||||
void SearchWindowInit();
|
|
||||||
|
|
||||||
void StatusWindowInit();
|
|
||||||
void StatusWindowLayout(Rect2I *rect, Int wx, Int wy);
|
|
||||||
|
|
||||||
void DebugWindowInit();
|
|
||||||
void DebugWindowLayout(Rect2I *rect, Int wx, Int wy);
|
|
||||||
|
|
||||||
void BuildWindowInit();
|
|
||||||
void BuildWindowLayout(Rect2I *rect, Int wx, Int wy);
|
|
||||||
Reference in New Issue
Block a user