diff options
| author | Riley Beckett <rbeckettvt@gmail.com> | 2025-10-27 19:40:08 -0400 |
|---|---|---|
| committer | Riley Beckett <rbeckettvt@gmail.com> | 2025-10-27 19:40:08 -0400 |
| commit | e42d9bb1834678fb0275dbcdfc84bc80b1ca27a8 (patch) | |
| tree | 206311382255c1bb04169b08aea9839fb95dc7f4 | |
| parent | 2033b55f91876c8fc0d4cd3cdf9c67972ad5490c (diff) | |
add prompt
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | args.c | 6 | ||||
| -rw-r--r-- | array.h | 6 | ||||
| -rw-r--r-- | graphics.c | 28 | ||||
| -rw-r--r-- | input_field.c | 7 | ||||
| -rw-r--r-- | keybind.c | 11 | ||||
| -rw-r--r-- | keybind.h | 2 | ||||
| -rw-r--r-- | layout.c | 12 | ||||
| -rw-r--r-- | layout.h | 2 | ||||
| -rw-r--r-- | main.c | 6 | ||||
| -rw-r--r-- | state.h | 2 |
11 files changed, 72 insertions, 15 deletions
@@ -5,6 +5,11 @@ To build: make ``` +To install(have to be root): +```sh +make install +``` + ## Todo - - [x] "selection" - [x] figure out whats going on with stderr and exit code @@ -12,16 +12,20 @@ void parse_args(client_state* state, int argc, char* argv[]) { {"exact-match", no_argument, 0, 'e'}, {"verbose", no_argument, 0, 'v'}, {"password", no_argument, 0, 'P'}, + {"prompt", no_argument, 0, 'p'}, {0, 0, 0, 0} }; int opt; int long_index = 0; - while ((opt = getopt_long(argc, argv, "l:cevP", long_opts, &long_index)) != -1) { + while ((opt = getopt_long(argc, argv, "l:p:cevP", long_opts, &long_index)) != -1) { switch (opt) { case 'l': state->lines = atoi(optarg); break; + case 'p': + state->prompt = optarg; + break; case 'c': state->center = true; break; @@ -84,12 +84,12 @@ for (type__* name__; (CONCAT(it__, __LINE__) < CONCAT(end__, __LINE__)) ? (name_ #define array_dump(array, type, name, fmt, ...) do { \ array_print(array); \ - fprintf(stderr, "vals: \n"); \ + fprintf(stderr, "vals: {\n"); \ type* it__ = (array); type* end__ = (array) ? (array) + array_size(array) : NULL; \ for (type* name; it__ < end__ ? (name = it__, true) : false; it__++) { \ - fprintf(stderr, fmt", ", __VA_ARGS__); \ + fprintf(stderr, " "fmt",\n", __VA_ARGS__); \ } \ - fprintf(stderr, "\b\b \n"); \ + fprintf(stderr, "}\n"); \ } while (0) #endif // ARRAY_H_ @@ -178,8 +178,30 @@ void render_frame(client_state *state) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // calculate input buffer size - rect_t input, options; - calculate_layout(state, &input, &options, false); + rect_t prompt, input, options; + calculate_layout(state, &prompt, &input, &options, false); + + if (state->prompt && *state->prompt) { + glScissor(prompt.x, prompt.y, prompt.dx, prompt.dy); + + // draw rect + glUseProgram(state->box_shader); + glUniform4f(state->b_color_uniform, highlight_color.r,highlight_color.g,highlight_color.b,highlight_color.a); + glUniform2f(state->b_screen_size_uniform, state->width, state->height); + glUniform2f(state->b_start_uniform, prompt.x, prompt.y); + glUniform2f(state->b_size_uniform, prompt.dx, prompt.dy); + glDrawArrays(GL_TRIANGLES, 0, 6); + + // draw text + glUseProgram(state->text_shader); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, state->atlas.texture); + glBindVertexArray(state->prompt_text_buffer.vao); + glUniform2f(state->t_screen_size_uniform, state->width, state->height); + glUniform4f(state->t_color_uniform, text_color.r,text_color.g,text_color.b,text_color.a); + glUniform2f(state->t_offset_uniform, prompt.x + state->horizontal_spacing / 2.0f, prompt.y - state->atlas.vert_shift); + glDrawElements(GL_TRIANGLES, state->prompt_text_buffer.num_elements, GL_UNSIGNED_INT, 0); + } // draw input buffer glUseProgram(state->text_shader); @@ -314,7 +336,7 @@ void init_text_buffer(client_state* state, text_buffer_t* buffer, char* text, si // go forward pen_x += m->advance_x; buffer->pixel_len += ceil(m->advance_x); - if (n == 0) buffer->pixel_len += ceil(m->advance_x); // add a second if we are the first to equal padding on the right + // if (n == 0) buffer->pixel_len += ceil(m->advance_x); // add a second if we are the first to equal padding on the right } // vertex buffer diff --git a/input_field.c b/input_field.c index 4672212..4eba923 100644 --- a/input_field.c +++ b/input_field.c @@ -10,8 +10,8 @@ int compare(const void *a, const void *b) { } void update_layout(client_state* state) { - rect_t input, options; - calculate_layout(state, &input, &options, true); + rect_t prompt, input, options; + calculate_layout(state, &prompt, &input, &options, true); } void filter_items(client_state* state) { @@ -79,6 +79,9 @@ key_repeat_t type_key(client_state* state, xkb_keysym_t keysym) { case XKB_KEY_k: return kill_to_end(state); case XKB_KEY_d: return delete_char(state); + + case XKB_KEY_v: return paste_from_clipboard(state); + case XKB_KEY_BackSpace: case XKB_KEY_Delete: return clear_input(state); @@ -101,9 +101,9 @@ key_repeat_t delete_char(client_state* state) { if (state->cursor_index != array_size(state->input_buffer)) { array_erase(state->input_buffer, state->cursor_index); update_text_buffer(state); - return KEY_NO_REPEAT; + return KEY_REPEAT; } - return KEY_REPEAT; + return KEY_NO_REPEAT; } key_repeat_t delete_char_backward(client_state* state) { @@ -122,3 +122,10 @@ key_repeat_t clear_input(client_state* state) { update_text_buffer(state); return KEY_NO_REPEAT; } + +key_repeat_t paste_from_clipboard(client_state* state) { + array_insert_many(state->input_buffer, state->cursor_index, state->clipboard, state->clipboard_size); + state->cursor_index += state->clipboard_size; + update_text_buffer(state); + return KEY_REPEAT; +} @@ -31,4 +31,6 @@ key_repeat_t delete_char(client_state* state); key_repeat_t delete_char_backward(client_state* state); key_repeat_t clear_input(client_state* state); + +key_repeat_t paste_from_clipboard(client_state* state); #endif // KEYBIND_H_ @@ -6,12 +6,18 @@ void init_layout(client_state* state) { } -void calculate_layout(client_state* state, rect_t* input, rect_t* options, bool recalc_options) { +void calculate_layout(client_state* state, rect_t* prompt, rect_t* input, rect_t* options, bool recalc_options) { + if (state->prompt && *state->prompt) { + *prompt = (rect_t){ .x = 0, .y = state->line_height * state->lines, .dx = state->prompt_text_buffer.pixel_len + state->horizontal_spacing, .dy = state->line_height }; + } + else { + *prompt = (rect_t){ 0 }; + } // calculate input rect - *input = (rect_t){ .x = 0, .y = state->line_height * state->lines, .dx = state->width, .dy = state->line_height }; + *input = (rect_t){ .x = prompt->dx, .y = state->line_height * state->lines, .dx = state->width - prompt->dx, .dy = state->line_height }; if (state->lines == 0 && array_size(state->filtered_items) != 0) { - input->dx = state->width / 3.0f; + input->dx = state->width / 3.0f - input->x; } // calculate options rect @@ -4,6 +4,6 @@ #include "state.h" void init_layout(client_state* state); -void calculate_layout(client_state* state, rect_t* input, rect_t* options, bool recalc_options); +void calculate_layout(client_state* state, rect_t* prompt, rect_t* input, rect_t* options, bool recalc_options); #endif @@ -52,6 +52,8 @@ int main(int argc, char* argv[]) { parse_args(&state, argc, argv); read_stdin(&state); + array_dump(state.items, item_t, item, "%s: %lu", item->text, strlen(item->text)); + // find font char* font = get_font("Monospace"); if (!freetype_init(&state, font)) { @@ -88,6 +90,10 @@ int main(int argc, char* argv[]) { // create font altas textures atlas_create_texture(&state); + if (state.prompt && *state.prompt) { + init_text_buffer(&state, &state.prompt_text_buffer, state.prompt, strlen(state.prompt)); + } + // create text buffers init_text_buffer(&state, &state.input_buffer_grafix, "", 0); array_for_all(item_t, item, state.items) { @@ -101,6 +101,7 @@ typedef struct { GLuint b_size_uniform; GLuint b_color_uniform; text_buffer_t input_buffer_grafix; + text_buffer_t prompt_text_buffer; // fonts FT_Library ft_library; @@ -114,6 +115,7 @@ typedef struct { // arguments int lines; + char* prompt; bool exact_match; bool center; bool verbose; |
