From 6e61692c5c8b5308781a8b1d63ec49cbb0c2a35b Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Sun, 11 Aug 2024 11:25:13 +0200 Subject: Text selection --- examples/ui.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 100 insertions(+), 10 deletions(-) (limited to 'examples/ui.c') diff --git a/examples/ui.c b/examples/ui.c index 13f0f68..16378d4 100755 --- a/examples/ui.c +++ b/examples/ui.c @@ -444,8 +444,6 @@ void draw_text_area(u32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_sc } void draw_text_cursor(u32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_scale_x, f64 max_scale_y, i64 cursor, i64 selection, i64 num_chars, c8 *text) { - (void) selection; - assert(max_scale_x > 1e-6); assert(max_scale_y > 1e-6); @@ -453,7 +451,6 @@ void draw_text_cursor(u32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_ i64 num_rows = enum_text_rows(num_chars, text); i64 cursor_x = text_cursor(cursor, text); i64 cursor_y = enum_text_rows(cursor, text); - f64 scale_x = width / num_columns; f64 scale_y = height / num_rows; @@ -465,7 +462,49 @@ void draw_text_cursor(u32 color, f64 x0, f64 y0, f64 width, f64 height, f64 max_ kx = k * max_scale_x; ky = k * max_scale_y; - draw_panel(OP_XOR, color, x0 + kx * cursor_x, y0 + ky * cursor_y - ky * CHAR_NUM_BITS_Y, kx * .5, ky * (CHAR_NUM_BITS_Y - 1)); + if (selection != 0) { + i64 selection_x, selection_y; + + if (selection > 0) { + selection_x = text_cursor(cursor + selection, text); + selection_y = enum_text_rows(cursor + selection, text); + } else { + selection_x = cursor_x; + selection_y = cursor_y; + cursor_x = text_cursor(cursor + selection, text); + cursor_y = enum_text_rows(cursor + selection, text); + } + + if (cursor_y == selection_y) + draw_panel(OP_XOR, color, + x0 + kx * cursor_x, + y0 + ky * cursor_y - ky * (CHAR_NUM_BITS_Y + 1), + kx * (selection_x - cursor_x), + ky * (CHAR_NUM_BITS_Y + 1) + ); + else { + draw_panel(OP_XOR, color, + x0 + kx * cursor_x, + y0 + ky * cursor_y - ky * (CHAR_NUM_BITS_Y + 1), + kx * (num_columns - cursor_x), + ky * (CHAR_NUM_BITS_Y + 1) + ); + for (i64 j = cursor_y + CHAR_NUM_BITS_Y + 1; j < selection_y; j += CHAR_NUM_BITS_Y + 1) + draw_panel(OP_XOR, color, + x0, + y0 + ky * j - ky * (CHAR_NUM_BITS_Y + 1), + kx * num_columns, + ky * (CHAR_NUM_BITS_Y + 1) + ); + draw_panel(OP_XOR, color, + x0, + y0 + ky * selection_y - ky * (CHAR_NUM_BITS_Y + 1), + kx * selection_x, + ky * (CHAR_NUM_BITS_Y + 1) + ); + } + } else + draw_panel(OP_XOR, color, x0 + kx * cursor_x, y0 + ky * cursor_y - ky * CHAR_NUM_BITS_Y, kx * .5, ky * (CHAR_NUM_BITS_Y - 1)); } i32 main(i32 argc, c8 **argv) { @@ -540,17 +579,39 @@ i32 main(i32 argc, c8 **argv) { for (i64 i = 0; i < platform.input_size; ++i) switch (platform.input[i]) { case KEY_LEFT: + if (platform.key_down[MOD_SHIFT]) { + if (cursor > 0) + ++selection; + } else if (selection != 0) { + cursor = selection < 0 ? cursor + selection + 1 : cursor + 1; + selection = 0; + } if (cursor > 0) --cursor; break; case KEY_RIGHT: + if (platform.key_down[MOD_SHIFT]) { + if (cursor < text_len) + --selection; + } else if (selection != 0) { + cursor = selection < 0 ? cursor - 1 : cursor + selection - 1; + selection = 0; + } if (cursor < text_len) ++cursor; break; case '\b': - if (cursor > 0 && text_len > 0) { + if (selection != 0) { + i64 i0 = selection < 0 ? cursor + selection : cursor; + i64 i1 = selection < 0 ? cursor : cursor + selection; + for (i64 i = 0; i1 + i < text_len; ++i) + text[i0 + i] = text[i1 + i]; + selection = 0; + cursor = i0; + text_len -= i1 - i0; + } else if (cursor > 0 && text_len > 0) { for (i64 i = cursor; i < text_len; ++i) text[i - 1] = text[i]; --cursor; @@ -558,12 +619,40 @@ i32 main(i32 argc, c8 **argv) { } break; + case KEY_DELETE: + if (selection != 0) { + i64 i0 = selection < 0 ? cursor + selection : cursor; + i64 i1 = selection < 0 ? cursor : cursor + selection; + for (i64 i = 0; i1 + i < text_len; ++i) + text[i0 + i] = text[i1 + i]; + selection = 0; + cursor = i0; + text_len -= i1 - i0; + } else if (cursor < text_len) { + for (i64 i = cursor + 1; i < text_len; ++i) + text[i - 1] = text[i]; + --text_len; + } + break; + default: - if (platform.input[i] > 0 && platform.input[i] < 128 && text_len < (i64) sizeof text) { - for (i64 i = text_len; i > cursor; --i) - text[i] = text[i - 1]; - text[cursor++] = (c8) platform.input[i]; - ++text_len; + if (platform.input[i] > 0 && platform.input[i] < 128) { + if (selection != 0) { + i64 i0 = selection < 0 ? cursor + selection : cursor; + i64 i1 = selection < 0 ? cursor : cursor + selection; + for (i64 i = 0; i1 + i < text_len; ++i) + text[i0 + i] = text[i1 + i]; + selection = 0; + cursor = i0; + text_len -= i1 - i0; + } + + if (text_len < (i64) sizeof text) { + for (i64 i = text_len; i > cursor; --i) + text[i] = text[i - 1]; + text[cursor++] = (c8) platform.input[i]; + ++text_len; + } } } @@ -588,6 +677,7 @@ i32 main(i32 argc, c8 **argv) { // - Clipboard // - Sound // - Sockets +// - Clipboard daemon // // X11 clipboard // https://handmade.network/forums/articles/t/8544-implementing_copy_paste_in_x11 -- cgit v1.2.3