commit 59e4368e073cc9c2a99bfb26f928e120502c5ce5
parent 8ba1124273be1373b9afbfcefbf2a4df2d6fec24
Author: lumidify <nobody@lumidify.org>
Date: Fri, 25 Aug 2023 14:56:01 +0200
Add basic support for RTL text to line entry
Diffstat:
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/src/entry.c b/src/entry.c
@@ -14,8 +14,10 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* FIXME: support RTL text! */
/* FIXME: allow opening text in external program */
+/* FIXME: cursors jump weirdly with bidi text
+ (need to support strong/weak cursors in pango backend) */
+/* FIXME: set imspot - needs to be standardized so widgets don't all do their own thing */
#include <stdio.h>
#include <ctype.h>
@@ -287,7 +289,10 @@ ltk_entry_redraw_surface(ltk_entry *entry, ltk_surface *s) {
int text_w, text_h;
ltk_text_line_get_size(entry->tl, &text_w, &text_h);
/* FIXME: what if text_h > rect.h? */
- int text_x = bw + theme.pad;
+ int x_offset = 0;
+ if (text_w < rect.w - 2 * (bw + theme.pad) && ltk_text_line_get_softline_direction(entry->tl, 0) == LTK_TEXT_RTL)
+ x_offset = rect.w - 2 * (bw + theme.pad) - text_w;
+ int text_x = bw + theme.pad + x_offset;
int text_y = (rect.h - text_h) / 2;
ltk_rect clip_rect = (ltk_rect){text_x, text_y, rect.w - 2 * bw - 2 * theme.pad, text_h};
ltk_text_line_draw_clipped(entry->tl, s, &theme.text_color, text_x - entry->cur_offset, text_y, clip_rect);
@@ -300,6 +305,16 @@ ltk_entry_redraw_surface(ltk_entry *entry, ltk_surface *s) {
entry->widget.dirty = 0;
}
+static size_t
+xy_to_pos(ltk_entry *e, int x, int y, int snap) {
+ int side = theme.border_width + theme.pad;
+ int text_w, text_h;
+ ltk_text_line_get_size(e->tl, &text_w, &text_h);
+ if (text_w < e->widget.lrect.w - 2 * side && ltk_text_line_get_softline_direction(e->tl, 0) == LTK_TEXT_RTL)
+ x -= e->widget.lrect.w - 2 * side - text_w;
+ return ltk_text_line_xy_to_pos(e->tl, x - side + e->cur_offset, y - side, snap);
+}
+
static void
set_selection(ltk_entry *entry, size_t start, size_t end) {
entry->sel_start = start;
@@ -604,7 +619,7 @@ ltk_entry_mouse_press(ltk_widget *self, ltk_button_event *event) {
allow a config option to revert to the naive behavior - I hate it
when word boundaries stop at punctuation because it's really
annoying to select URLs, etc. then. */
- e->pos = ltk_text_line_xy_to_pos(e->tl, event->x - side + e->cur_offset, event->y - side, 0);
+ e->pos = xy_to_pos(e, event->x, event->y, 0);
size_t cur = e->pos;
size_t left = 0, right = 0;
if (isspace(e->text[e->pos])) {
@@ -641,7 +656,7 @@ ltk_entry_mouse_press(ltk_widget *self, ltk_button_event *event) {
set_selection(e, left, right);
e->sel_side = 0;
} else if (event->type == LTK_BUTTONPRESS_EVENT) {
- e->pos = ltk_text_line_xy_to_pos(e->tl, event->x - side + e->cur_offset, event->y - side, 1);
+ e->pos = xy_to_pos(e, event->x, event->y, 1);
set_selection(e, e->pos, e->pos);
e->selecting = 1;
e->sel_side = 0;
@@ -650,7 +665,7 @@ ltk_entry_mouse_press(ltk_widget *self, ltk_button_event *event) {
/* FIXME: configure if this should change the position or paste at the current position
(see behavior in ledit) */
wipe_selection(e);
- e->pos = ltk_text_line_xy_to_pos(e->tl, event->x - side + e->cur_offset, event->y - side, 1);
+ e->pos = xy_to_pos(e, event->x, event->y, 1);
paste_primary(e, NULL);
}
return 0;
@@ -674,8 +689,7 @@ ltk_entry_motion_notify(ltk_widget *self, ltk_motion_event *event) {
is being selected (FIXME: a bit weird) */
if (e->sel_start == e->sel_end && e->pos != e->sel_start)
e->sel_start = e->sel_end = e->pos;
- int side = theme.border_width + theme.pad;
- size_t new = ltk_text_line_xy_to_pos(e->tl, event->x - side + e->cur_offset, event->y - side, 1);
+ size_t new = xy_to_pos(e, event->x, event->y, 1);
size_t otherpos = e->sel_side == 1 ? e->sel_start : e->sel_end;
e->pos = new;
/* this takes care of moving the shown text when the mouse is