diff options
| author | Riley Beckett <rbeckettvt@gmail.com> | 2025-10-23 00:07:26 -0400 |
|---|---|---|
| committer | Riley Beckett <rbeckettvt@gmail.com> | 2025-10-23 00:07:26 -0400 |
| commit | 9d8db4146d025e3a967700414a9fc68fa186045e (patch) | |
| tree | 9d0e0d6dd46a2f580f4b2fb4e1fbba2b0c6fb11e | |
| parent | 90d6b2a866c6da29921dfae3d684203fd232ea74 (diff) | |
add basic cursor movement
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | array.h | 17 | ||||
| -rw-r--r-- | config.h | 2 | ||||
| -rw-r--r-- | font.c | 9 | ||||
| -rw-r--r-- | font.h | 1 | ||||
| -rw-r--r-- | graphics.c | 5 | ||||
| -rw-r--r-- | input_field.c | 40 | ||||
| -rw-r--r-- | state.h | 2 |
8 files changed, 75 insertions, 6 deletions
@@ -1,6 +1,9 @@ # SWENU - Simple Wayland ENU -To build: `make` +To build: +```sh +make +``` ## Todo - - [x] "selection" @@ -27,6 +27,23 @@ void* array_add_(void* array, size_t item_size); (array) = NULL; \ } while (0) +#define array_erase(array, index) do { \ + if ((index)) {\ + for (int __i = (index) - 1; __i < array_size((array)) - 1; __i++) \ + (array)[__i] = (array)[__i + 1]; \ + ((array_info*)(array))[-1].size--; \ + } \ +} while(0) + +#define array_insert(array, index, value) do { \ + void* __temp = array_add_((array), sizeof(*(array))); \ + (array) = __temp; \ + for (int __i = array_size((array)) - 1; __i > (index); __i--) \ + (array)[__i] = (array)[__i - 1]; \ + (array)[(index)] = value; \ +} while(0) \ + + #define array_add(array, value) do { \ void* __temp = array_add_((array), sizeof(*(array))); \ (array) = __temp; \ @@ -8,7 +8,7 @@ typedef struct { } color_t; static const uint32_t min_width = 500; -static const uint32_t font_size = 20; +static const uint32_t font_size = 16; static const color_t text_color = {0.85, 0.85, 0.85, 1.0}; static const color_t highlight_color = {0.1, 0.3, 0.7, 1.0}; static const color_t background_color = {0.1, 0.1, 0.1, 1.0}; @@ -156,6 +156,15 @@ int atlas_get_strwidth(client_state* state, const char* str) { return (int)ceil(width); } +int atlas_get_strwidth_len(client_state* state, const char* str, size_t len) { + float width = 0; + // TODO - UNICODE MAKE WORKY + for (int i = 0; i < len; i++) { + width += ceil(state->atlas.metrics[(int)str[i]].advance_x); + } + return (int)ceil(width); +} + void atlas_calc_item_widths(client_state* state) { if (state->items) { array_for_all(item_t, item, state->items) { @@ -8,5 +8,6 @@ void atlas_init(client_state* state); void atlas_create_texture(client_state* state); int atlas_get_strwidth(client_state* state, const char* str); +int atlas_get_strwidth_len(client_state* state, const char* str, size_t len); void atlas_calc_item_widths(client_state* state); #endif // FONT_H_ @@ -2,6 +2,7 @@ #include "array.h" #include "config.h" #include "shader.h" +#include "font.h" void GLAPIENTRY MessageCallback(GLenum source, @@ -203,8 +204,8 @@ void render_frame(client_state *state) { glUseProgram(state->box_shader); glUniform4f(state->b_color_uniform, cursor_color.r,cursor_color.g,cursor_color.b,cursor_color.a); glUniform2f(state->b_screen_size_uniform, state->width, state->height); - glUniform2f(state->b_start_uniform, state->input_buffer_grafix.pixel_len + state->horizontal_spacing / 2.0f, input_y); - glUniform2f(state->b_size_uniform, state->atlas.metrics['m'].bitmap_width, state->line_height); + glUniform2f(state->b_start_uniform, atlas_get_strwidth_len(state, state->input_buffer, state->cursor_index) + state->horizontal_spacing / 2.0f, input_y); + glUniform2f(state->b_size_uniform, state->atlas.metrics['M'].bitmap_width, state->line_height); glDrawArrays(GL_TRIANGLES, 0, 6); float start; diff --git a/input_field.c b/input_field.c index 6ca9a1b..a0d5cc6 100644 --- a/input_field.c +++ b/input_field.c @@ -68,6 +68,7 @@ bool type_key(client_state* state, xkb_keysym_t keysym) { array_free(state->input_buffer); state->input_buffer = array_new(char, len); memcpy(state->input_buffer, selected, len); + state->cursor_index = len; update_text_buffer(state); } @@ -90,6 +91,36 @@ bool type_key(client_state* state, xkb_keysym_t keysym) { return true; } + if (keysym == XKB_KEY_e && ctrl) { + state->cursor_index = array_size(state->input_buffer); + return true; + } + + if (keysym == XKB_KEY_a && ctrl) { + state->cursor_index = 0; + return true; + } + + if (keysym == XKB_KEY_f && ctrl) { + if (state->cursor_index < array_size(state->input_buffer)) { + state->cursor_index++; + } + return true; + } + + if (keysym == XKB_KEY_b && ctrl) { + if (state->cursor_index > 0) { + state->cursor_index--; + } + return true; + } + + if (keysym == XKB_KEY_k && ctrl) { + array_resize(state->input_buffer, state->cursor_index); + update_text_buffer(state); + return true; + } + // paste if (keysym == XKB_KEY_v && ctrl) { FILE* fp = popen("wl-paste --no-newline --type text/plain 2>/dev/null", "r"); @@ -125,8 +156,12 @@ bool type_key(client_state* state, xkb_keysym_t keysym) { if (keysym == XKB_KEY_BackSpace || keysym == XKB_KEY_Delete) { if (ctrl) { array_clear(state->input_buffer); + state->cursor_index = 0; } else { - array_pop(state->input_buffer); + if (state->cursor_index) { + array_erase(state->input_buffer, state->cursor_index); + state->cursor_index--; + } } update_text_buffer(state); return true; @@ -137,7 +172,8 @@ bool type_key(client_state* state, xkb_keysym_t keysym) { int len = xkb_keysym_to_utf8(keysym, buf, sizeof(buf)); if (len > 0) { for (int i = 0; i < strlen(buf); i++) { - array_add(state->input_buffer, buf[i]); + array_insert(state->input_buffer, state->cursor_index, buf[i]); + state->cursor_index++; } update_text_buffer(state); return true; @@ -93,6 +93,8 @@ typedef struct { GLuint b_color_uniform; text_buffer_t input_buffer_grafix; + size_t cursor_index; + // fonts FT_Library ft_library; FT_Face ft_face; |
