text_edit.c - ltkx - GUI toolkit for X11 (old)
HTML git clone git://lumidify.org/ltkx.git (fast, but not encrypted)
HTML git clone https://lumidify.org/ltkx.git (encrypted, but very slow)
HTML git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/ltkx.git (over tor)
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
text_edit.c (4265B)
---
1 /*
2 * This file is part of the Lumidify ToolKit (LTK)
3 * Copyright (c) 2020 lumidify <nobody@lumidify.org>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24 #include <stdint.h>
25 #include <math.h>
26 #include <X11/Xlib.h>
27 #include <X11/Xutil.h>
28 #include "khash.h"
29 #include "stb_truetype.h"
30 #include <fribidi.h>
31 #include <harfbuzz/hb.h>
32 #include <fontconfig/fontconfig.h>
33 #include "text_common.h"
34 #include "ltk.h"
35 #include "array.h"
36 #include "text_buffer.h"
37 #include "text_edit.h"
38 #include "grid.h"
39
40 void
41 ltk_text_edit_draw(LtkTextEdit *te) {
42 Display *display = ltk_get_display();
43 LtkTheme *theme = ltk_get_theme();
44 if (!te->img)
45 ltk_text_edit_resize(te, 0, 0);
46 LtkRect rect = te->widget.rect;
47 LtkWindow *window = te->widget.window;
48 int x = rect.x;
49 if (te->tl->dir == HB_DIRECTION_RTL)
50 x += rect.w - te->img->width;
51 XSetForeground(display, window->gc, theme->window->bg.pixel);
52 XFillRectangle(display, window->xwindow, window->gc, rect.x, rect.y, rect.w, rect.h);
53 XPutImage(
54 display,
55 window->xwindow,
56 window->gc,
57 te->img,
58 0, 0,
59 x, rect.y,
60 te->tl->w_wrapped, te->tl->h_wrapped
61 );
62 }
63
64 /* FIXME: only recalculate if largest line is too wide */
65 void
66 ltk_text_edit_resize(LtkTextEdit *te, int orig_w, int orig_h) {
67 if (te->tl->soft_lines->len == 1 &&
68 te->widget.rect.w >= te->img->width && orig_w >= te->img->width)
69 return;
70 LtkTheme *theme = ltk_get_theme();
71 Display *display = ltk_get_display();
72 Colormap colormap = ltk_get_colormap();
73 XColor fg = theme->window->fg;
74 XColor bg = theme->window->bg;
75 LtkWindow *window = te->widget.window;
76 ltk_text_line_wrap(te->tl, te->widget.rect.w);
77 if (te->img) XDestroyImage(te->img);
78 te->img = ltk_text_line_render(te->tl, display, window->xwindow, window->gc, colormap, fg, bg);
79 }
80
81 #if 0
82 void
83 ltk_text_edit_tmp(LtkTextEdit *te, XEvent event) {
84 /* this should never be negative, but just to be sure... */
85 int local_y = abs(event.xbutton.y - te->widget.rect.y);
86 int i = ((double)local_y / (te->tl->h * te->soft_lines->len)) * te->soft_lines->len;
87 i = i >= te->soft_lines->len ? te->soft_lines->len - 1 : i;
88 int x = event.xbutton.x - te->widget.rect.x;
89 if (te->tl->dir == HB_DIRECTION_RTL)
90 x -= (te->widget.rect.w - te->soft_lines->buf[i]->img->width);
91 int found_pos = 0;
92 te->cursor = ltk_soft_line_get_index_from_pos(
93 x, te->tl, te->soft_lines->buf[i], &found_pos);
94 }
95 #endif
96
97 LtkTextEdit *
98 ltk_text_edit_create(LtkWindow *window, const char *text) {
99 LtkTextEdit *te = malloc(sizeof(LtkTextEdit));
100 if (!te)
101 ltk_fatal("ERROR: Unable to allocate memory for LtkTextEdit.\n");
102 te->img = NULL;
103 ltk_fill_widget_defaults(&te->widget, window, <k_text_edit_draw, <k_text_edit_destroy, 1);
104 /*te->widget.mouse_press = <k_text_edit_tmp;*/
105 te->widget.resize = <k_text_edit_resize;
106 te->tl = ltk_text_line_create(20);
107 ltk_text_edit_insert_text(te, text);
108 return te;
109 }
110
111 void
112 ltk_text_edit_insert_text(LtkTextEdit *te, const char *text) {
113 /* FIXME */
114 ltk_text_line_insert_utf8(te->tl, 0, text);
115 ltk_text_edit_resize(te, 0, 0);
116 ltk_window_invalidate_rect(te->widget.window, te->widget.rect);
117 }
118
119 void ltk_text_edit_destroy(LtkTextEdit *te) {
120 ltk_text_line_destroy(te->tl);
121 if (te->img) XDestroyImage(te->img);
122 free(te);
123 }