commit 5f96463537ee5b750ce72138ef7d990cceed72c4
parent 4afd25647a23c332ddc8349dd845415165b2e047
Author: Alexey Kutepov <reximkut@gmail.com>
Date: Fri, 2 Jul 2021 19:44:21 +0700
Merge pull request #4 from tsoding/cursor
Cursor
Diffstat:
| M | main.c | | | 119 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- |
1 file changed, 91 insertions(+), 28 deletions(-)
diff --git a/main.c b/main.c
@@ -78,6 +78,7 @@ Font font_load_from_file(SDL_Renderer *renderer, const char *file_path)
Font font = {0};
SDL_Surface *font_surface = surface_from_file(file_path);
+ scc(SDL_SetColorKey(font_surface, SDL_TRUE, 0xFF000000));
font.spritesheet = scp(SDL_CreateTextureFromSurface(renderer, font_surface));
SDL_FreeSurface(font_surface);
@@ -96,7 +97,7 @@ Font font_load_from_file(SDL_Renderer *renderer, const char *file_path)
return font;
}
-void render_char(SDL_Renderer *renderer, Font *font, char c, Vec2f pos, float scale)
+void render_char(SDL_Renderer *renderer, const Font *font, char c, Vec2f pos, float scale)
{
const SDL_Rect dst = {
.x = (int) floorf(pos.x),
@@ -105,21 +106,28 @@ void render_char(SDL_Renderer *renderer, Font *font, char c, Vec2f pos, float sc
.h = (int) floorf(FONT_CHAR_HEIGHT * scale),
};
- assert(c >= ASCII_DISPLAY_LOW);
- assert(c <= ASCII_DISPLAY_HIGH);
- const size_t index = c - ASCII_DISPLAY_LOW;
+ size_t index = '?' - ASCII_DISPLAY_LOW;
+ if (ASCII_DISPLAY_LOW <= c && c <= ASCII_DISPLAY_HIGH) {
+ index = c - ASCII_DISPLAY_LOW;
+ }
+
scc(SDL_RenderCopy(renderer, font->spritesheet, &font->glyph_table[index], &dst));
}
-void render_text_sized(SDL_Renderer *renderer, Font *font, const char *text, size_t text_size, Vec2f pos, Uint32 color, float scale)
+void set_texture_color(SDL_Texture *texture, Uint32 color)
{
scc(SDL_SetTextureColorMod(
- font->spritesheet,
+ texture,
(color >> (8 * 0)) & 0xff,
(color >> (8 * 1)) & 0xff,
(color >> (8 * 2)) & 0xff));
- scc(SDL_SetTextureAlphaMod(font->spritesheet, (color >> (8 * 3)) & 0xff));
+ scc(SDL_SetTextureAlphaMod(texture, (color >> (8 * 3)) & 0xff));
+}
+
+void render_text_sized(SDL_Renderer *renderer, Font *font, const char *text, size_t text_size, Vec2f pos, Uint32 color, float scale)
+{
+ set_texture_color(font->spritesheet, color);
Vec2f pen = pos;
for (size_t i = 0; i < text_size; ++i) {
@@ -128,41 +136,88 @@ void render_text_sized(SDL_Renderer *renderer, Font *font, const char *text, siz
}
}
-void render_text(SDL_Renderer *renderer, Font *font, const char *text, Vec2f pos, Uint32 color, float scale)
-{
- render_text_sized(renderer, font, text, strlen(text), pos, color, scale);
-}
-
#define BUFFER_CAPACITY 1024
char buffer[BUFFER_CAPACITY];
size_t buffer_cursor = 0;
size_t buffer_size = 0;
+void buffer_insert_text_before_cursor(const char *text)
+{
+ size_t text_size = strlen(text);
+ const size_t free_space = BUFFER_CAPACITY - buffer_size;
+ if (text_size > free_space) {
+ text_size = free_space;
+ }
+ memmove(buffer + buffer_cursor + text_size,
+ buffer + buffer_cursor,
+ buffer_size - buffer_cursor);
+ memcpy(buffer + buffer_cursor, text, text_size);
+ buffer_size += text_size;
+ buffer_cursor += text_size;
+}
+
+void buffer_backspace(void)
+{
+ if (buffer_cursor > 0 && buffer_size > 0) {
+ memmove(buffer + buffer_cursor - 1,
+ buffer + buffer_cursor,
+ buffer_size - buffer_cursor);
+ buffer_size -= 1;
+ buffer_cursor -= 1;
+ }
+}
+
+void buffer_delete(void)
+{
+ if (buffer_cursor < buffer_size && buffer_size > 0) {
+ memmove(buffer + buffer_cursor,
+ buffer + buffer_cursor + 1,
+ buffer_size - buffer_cursor);
+ buffer_size -= 1;
+ }
+}
+
#define UNHEX(color) \
((color) >> (8 * 0)) & 0xFF, \
((color) >> (8 * 1)) & 0xFF, \
((color) >> (8 * 2)) & 0xFF, \
((color) >> (8 * 3)) & 0xFF
-void render_cursor(SDL_Renderer *renderer, Uint32 color)
+void render_cursor(SDL_Renderer *renderer, const Font *font)
{
+ const Vec2f pos = vec2f((float) buffer_cursor * FONT_CHAR_WIDTH * FONT_SCALE, 0.0f);
+
const SDL_Rect rect = {
- .x = (int) floorf((float) buffer_cursor * FONT_CHAR_WIDTH * FONT_SCALE),
- .y = 0,
+ .x = (int) floorf(pos.x),
+ .y = (int) floorf(pos.y),
.w = FONT_CHAR_WIDTH * FONT_SCALE,
.h = FONT_CHAR_HEIGHT * FONT_SCALE,
};
- scc(SDL_SetRenderDrawColor(renderer, UNHEX(color)));
+ scc(SDL_SetRenderDrawColor(renderer, UNHEX(0xFFFFFFFF)));
scc(SDL_RenderFillRect(renderer, &rect));
+
+ set_texture_color(font->spritesheet, 0xFF000000);
+ if (buffer_cursor < buffer_size) {
+ render_char(renderer, font, buffer[buffer_cursor], pos, FONT_SCALE);
+ }
}
+
+// TODO: Jump forward/backward by a word
+// TODO: Delete a word
+// TODO: Blinking cursor
+// TODO: Multiple lines
+// TODO: Save/Load file
+
int main(int argc, char **argv)
{
(void) argc;
(void) argv;
+ buffer_insert_text_before_cursor("Hello, World");
+
scc(SDL_Init(SDL_INIT_VIDEO));
SDL_Window *window =
@@ -188,9 +243,24 @@ int main(int argc, char **argv)
case SDL_KEYDOWN: {
switch (event.key.keysym.sym) {
case SDLK_BACKSPACE: {
- if (buffer_size > 0) {
- buffer_size -= 1;
- buffer_cursor = buffer_size;
+ buffer_backspace();
+ }
+ break;
+
+ case SDLK_DELETE: {
+ buffer_delete();
+ } break;
+
+ case SDLK_LEFT: {
+ if (buffer_cursor > 0) {
+ buffer_cursor -= 1;
+ }
+ }
+ break;
+
+ case SDLK_RIGHT: {
+ if (buffer_cursor < buffer_size) {
+ buffer_cursor += 1;
}
}
break;
@@ -199,14 +269,7 @@ int main(int argc, char **argv)
break;
case SDL_TEXTINPUT: {
- size_t text_size = strlen(event.text.text);
- const size_t free_space = BUFFER_CAPACITY - buffer_size;
- if (text_size > free_space) {
- text_size = free_space;
- }
- memcpy(buffer + buffer_size, event.text.text, text_size);
- buffer_size += text_size;
- buffer_cursor = buffer_size;
+ buffer_insert_text_before_cursor(event.text.text);
}
break;
}
@@ -216,7 +279,7 @@ int main(int argc, char **argv)
scc(SDL_RenderClear(renderer));
render_text_sized(renderer, &font, buffer, buffer_size, vec2f(0.0, 0.0), 0xFFFFFFFF, FONT_SCALE);
- render_cursor(renderer, 0xFFFFFFFF);
+ render_cursor(renderer, &font);
SDL_RenderPresent(renderer);
}