diff options
-rw-r--r-- | archived/array.h | 70 | ||||
-rw-r--r-- | box.c | 263 | ||||
-rw-r--r-- | chatty.c | 2 | ||||
-rw-r--r-- | chatty.h | 4 | ||||
-rw-r--r-- | ui.h | 1 |
5 files changed, 269 insertions, 71 deletions
diff --git a/archived/array.h b/archived/array.h new file mode 100644 index 0000000..04d2f38 --- /dev/null +++ b/archived/array.h @@ -0,0 +1,70 @@ +#include "chatty.h" + +u64 ArrayLength(u8 *Array); +void ArrayInsert(u8 *Array, u64 Position, u8 Element); +void ArrayCopy(u8 *To, u8 *From); +void ArrayDelete(u8* Array, u64 Position); +u8* ArrayCreate(u8* Container, u64 Capacity); + +// EXAMPLE: CREATE +// +// u64 Capacity = 15; +// u8 ArrayContainer[Capacity + sizeof(Capacity)]; +// u8* Array = ArrayCreate(ArrayContainer, Capacity); +// +// EXAMPLE: API +// +// ArrayCopy(Array, (u8*)"Hello, world!"); +// +// ArrayInsert(Array, 3, 'f'); +// ArrayInsert(Array, 3, 'e'); +// Array[14] = 'd'; +// ArrayDelete(Array, 3); + +#ifdef ARRAY_IMPL + +#include <strings.h> +#include <string.h> + +u64 +ArrayLength(u8 *Array) +{ + return *((u64*)(Array - sizeof(u64))); +} + +void +ArrayInsert(u8 *Array, u64 Position, u8 Element) +{ + memmove(Array + Position + 1, Array + Position, ArrayLength(Array) - Position - 1); + Array[Position] = Element; +} + +// Copy null terminated string without copying over the null terminator +void +ArrayCopy(u8 *To, u8 *From) +{ + u32 i = 0; + while (From[i]) + { + To[i] = From[i]; + i++; + } +} + +void +ArrayDelete(u8* Array, u64 Position) +{ + memmove(Array + Position, Array + Position + 1, ArrayLength(Array) - Position - 1); + Array[ArrayLength(Array) - 1] = 0; +} + +u8* +ArrayCreate(u8* Container, u64 Capacity) +{ + *(u64*)Container = Capacity; + u8 *Array = Container + sizeof(Capacity); + bzero(Array, Capacity); + return Array; +} + +#endif @@ -1,36 +1,29 @@ +#define MAX_INPUT_LEN 64 +#define DEBUG + #define TB_IMPL #include "external/termbox2.h" +#undef TB_IMPL -#include <locale.h> -#include <assert.h> - -#define MAX_INPUT_LEN 70 -#define DEBUG +#define CHATTY_IMPL +#include "chatty.h" +#undef CHATTY_IMPL #include "ui.h" -u32 -DeleteWordBackwards(u32 Pos, wchar_t* Input) -{ - while (Pos && is_whitespace(Input[Pos - 1])) - { - Input[--Pos] = 0; - } - - while (Pos && !is_whitespace(Input[Pos - 1])) - { - Input[--Pos] = 0; - } +#include <locale.h> +#include <assert.h> - return Pos; -} +typedef struct { + u32 X, Y, W, H; +} rect; typedef struct { wchar_t ur, ru, rd, dr, lr, ud; } box_characters; void -Box(u32 BoxX, u32 BoxY, u32 Width, u32 Height, box_characters *Chars) +DrawBox(rect Rect, box_characters *Chars) { wchar_t ur, ru, rd, dr, lr, ud; if (!Chars) @@ -52,29 +45,38 @@ Box(u32 BoxX, u32 BoxY, u32 Width, u32 Height, box_characters *Chars) ud = Chars->ud; } - Height--; - Width--; + Rect.H--; + Rect.W--; - tb_printf(BoxX, BoxY, 0, 0, "%lc", ur); - for (u32 X = 1; X < Width; X++) + tb_printf(Rect.X, Rect.Y, 0, 0, "%lc", ur); + for (u32 X = 1; X < Rect.W; X++) { - tb_printf(BoxX + X, BoxY, 0, 0, "%lc", lr); + tb_printf(Rect.X + X, Rect.Y, 0, 0, "%lc", lr); } - tb_printf(BoxX + Width, BoxY, 0, 0, "%lc", rd); + tb_printf(Rect.X + Rect.W, Rect.Y, 0, 0, "%lc", rd); // Draw vertical bars - for (u32 Y = 1; Y < Height; Y++) + for (u32 Y = 1; Y < Rect.H; Y++) { - tb_printf(BoxX, BoxY + Y, 0, 0, "%lc", ud); - tb_printf(BoxX + Width, BoxY + Y, 0, 0, "%lc", ud); + tb_printf(Rect.X, Rect.Y + Y, 0, 0, "%lc", ud); + tb_printf(Rect.X + Rect.W, Rect.Y + Y, 0, 0, "%lc", ud); } - tb_printf(BoxX, BoxY + Height, 0, 0, "%lc", dr); - for (u32 X = 1; X < Width; X++) + tb_printf(Rect.X, Rect.Y + Rect.H, 0, 0, "%lc", dr); + for (u32 X = 1; X < Rect.W; X++) { - tb_printf(BoxX + X, BoxY + Height, 0, 0, "%lc", lr); + tb_printf(Rect.X + X, Rect.Y + Rect.H, 0, 0, "%lc", lr); } - tb_printf(BoxX + Width, BoxY + Height, 0, 0, "%lc", ru); + tb_printf(Rect.X + Rect.W, Rect.Y + Rect.H, 0, 0, "%lc", ru); +} + + +void +Delete(wchar_t* Text, u64 Pos) +{ + memmove((u8*)(Text + Pos), + (u8*)(Text + Pos + 1), + (MAX_INPUT_LEN - Pos - 1) * sizeof(*Text)); } int @@ -85,78 +87,203 @@ main(void) tb_init(); - Box(0, 0, 32, 4, 0); - tb_present(); - tb_poll_event(&ev); - tb_shutdown(); - return 1; + u32 InputPos = 0; + u32 InputLen = 0; +#if 1 wchar_t Input[MAX_INPUT_LEN] = {0}; - u32 InputIndex = 0; - u32 InputLen = 0; - // Input[InputIndex++] = 1; + wchar_t *t = L"This is some text that no one would want to know, but you could."; + u32 Len = wcslen(t); + for (u32 At = 0; At < Len; At++) + { + Input[At] = t[At]; + } + InputLen = Len; +#endif bytebuf_puts(&global.out, global.caps[TB_CAP_SHOW_CURSOR]); + rect TextBox = {0, 0, 24, 4}; - while (ev.key != TB_KEY_CTRL_C) - { - tb_clear(); +#define BOX_PADDING_X 1 +#define BOX_BORDER_WIDTH 1 + rect Text = { + 2, 1, + TextBox.W - 2*BOX_PADDING_X - 2*BOX_BORDER_WIDTH, + TextBox.H - 2*BOX_BORDER_WIDTH + }; + u32 TextSurface = Text.W * Text.H; +#undef BOX_PADDING_X +#undef BOX_BORDER_WIDTH - InputBox(0, 0, 32, 4, Input, InputLen, True); + DrawBox(TextBox, 0); + // Draw the text + u32 XOffset = 0, YOffset = 0; + for (u32 At = 0; + (At < InputLen) && (At < TextSurface) ; + At++) + { + tb_printf(Text.X + XOffset, + Text.Y + YOffset, + 0, 0, + "%lc", Input[At]); + XOffset++; + if (XOffset == Text.W) { YOffset++; XOffset = 0; } + } - if (InputIndex) tb_printf(0, 3, 0, 0, "'%lc'", Input[InputIndex - 1]); - tb_printf(4, 3, 0, 0, "%d#%d", InputIndex, InputLen); + global.cursor_x = Text.X; + global.cursor_y = Text.Y; + while (ev.key != TB_KEY_CTRL_C) + { tb_present(); - tb_poll_event(&ev); - if (ev.ch && InputLen < MAX_INPUT_LEN) - { - // Add new character to input - Input[InputIndex++] = ev.ch; - InputLen++; - continue; - } + tb_poll_event(&ev); - switch (ev.key) + if (ev.mod & TB_MOD_CTRL) { - case TB_KEY_BACKSPACE2: + switch (ev.key) + { + case TB_KEY_CTRL_D: { - if (!InputLen) break; - Input[InputIndex--] = 0; + if (InputPos == InputLen) break; + Delete(Input, InputPos); + Input[MAX_INPUT_LEN - 1] = 0; InputLen--; } break; case TB_KEY_CTRL_W: { - while (InputIndex && is_whitespace(Input[InputIndex - 1])) + // TODO: this could be one memmove call + while (InputPos && is_whitespace(Input[InputPos - 1])) { - Input[--InputIndex] = 0; + InputPos--; InputLen--; + Delete(Input, InputPos); + Input[MAX_INPUT_LEN - 1] = 0; } - while (InputIndex && !is_whitespace(Input[InputIndex - 1])) + while (InputPos && !is_whitespace(Input[InputPos - 1])) { - Input[--InputIndex] = 0; + InputPos--; InputLen--; + Delete(Input, InputPos); + Input[MAX_INPUT_LEN - 1] = 0; } } break; case TB_KEY_CTRL_U: { - InputIndex = InputLen = 0; - Input[0] = 0; - } + if (!InputPos) break; + memmove(Input, + Input + InputPos, + (InputLen - InputPos) * sizeof(wchar_t)); + InputLen -= InputPos; + InputPos = 0; + } break; + // Delete until end of input + case TB_KEY_CTRL_K: InputLen = InputPos; break; + // Move to start + case TB_KEY_CTRL_A: InputPos = 0; break; + // Move to end + case TB_KEY_CTRL_E: InputPos = InputLen; break; + // Move backwards by one character + case TB_KEY_CTRL_B: if (InputPos) InputPos--; break; + // Move forwards by one character + case TB_KEY_CTRL_F: if (InputPos < InputLen) InputPos++; break; + // Move backwards by word case TB_KEY_ARROW_LEFT: { - if (InputIndex) InputIndex--; + while (InputPos && is_whitespace(Input[--InputPos])); + while (InputPos && !is_whitespace(Input[--InputPos])); } break; + // Move forwards by word case TB_KEY_ARROW_RIGHT: { - if (InputIndex < InputLen) InputIndex++; + while (InputPos < InputLen && is_whitespace(Input[InputPos])) InputPos++; + while (InputPos < InputLen && !is_whitespace(Input[++InputPos])); } break; + } + + } + // Insert new character in Input at InputPos + else if (ev.ch && InputLen < MAX_INPUT_LEN) + { + memmove(Input + InputPos + 1, + Input + InputPos, + (MAX_INPUT_LEN - InputPos - 1) * sizeof(*Input)); + Input[InputPos++] = ev.ch; + InputLen++; + } + else + { + switch (ev.key) + { + case TB_KEY_BACKSPACE2: + { + if (!InputLen) break; + Input[InputPos--] = 0; + InputLen--; + } break; + case TB_KEY_ARROW_LEFT: + { + if (InputPos) InputPos--; + + // Text is assumed to start on (Text.X, Text.Y) + if (global.cursor_x == Text.X && + global.cursor_y == Text.Y) + { + if (InputPos == 0) break; + + global.cursor_x = Text.X + Text.W - 1; + global.cursor_y = Text.Y + Text.H - 1; + // TODO: scroll + break; + } + + global.cursor_x--; + if (global.cursor_x < Text.X) + { + global.cursor_x = Text.X + Text.W - 1; + global.cursor_y--; + } + + } break; + case TB_KEY_ARROW_RIGHT: + { + if (InputPos == InputLen) break; + + InputPos++; + + if (global.cursor_x == Text.X + Text.W - 1 && + global.cursor_y == Text.Y + Text.H - 1) + { + + global.cursor_x = Text.X; + global.cursor_y = Text.Y; + + break; + } + // TODO: scroll + + global.cursor_x++; + if (global.cursor_x == Text.X + Text.W) + { + global.cursor_x = Text.X; + global.cursor_y++; + } + } break; + } } +#ifdef DEBUG + tb_printf(TextBox.X, TextBox.Y, 0, 0, + "%2d,%-2d #%-2d %d/%d", + global.cursor_x, global.cursor_y, + InputPos, + InputLen, MAX_INPUT_LEN); +#endif + + } tb_shutdown(); @@ -22,7 +22,9 @@ // Number of spaces inserted when pressing Tab/Ctrl+I #define TAB_WIDTH 4 +#define CHATTY_IMPL #include "chatty.h" +#undef CHATTY_IMPL #include "protocol.h" #include "ui.h" @@ -64,6 +64,8 @@ void ArenaAlloc(Arena* arena, u64 size); void ArenaRelease(Arena* arena); void* ArenaPush(Arena* arena, u64 size); +#endif // CHATTY_H + #ifdef CHATTY_IMPL global_variable s32 logfd; @@ -127,5 +129,3 @@ ArenaPush(Arena* arena, u64 size) } #endif // CHATTY_IMPL - -#endif // CHATTY_H @@ -1,4 +1,3 @@ -#define CHATTY_IMPL #include "chatty.h" // Format option at a position in raw text, used when iterating to know when to toggle a color |