26 bool insertMode =
true;
41 bool hasPartialgrapheme =
false;
45 text(), _shapedText(), currentStyle(style)
53 for (ttlet &c : text) {
54 r += to_string(c.grapheme.NFC());
62 cancelPartialgrapheme();
68 for (ttlet &g : gstr) {
72 selectionIndex = cursorIndex = 0;
73 tt_axiom(selectionIndex >= 0);
74 tt_axiom(selectionIndex <= std::ssize(text));
75 tt_axiom(cursorIndex >= 0);
76 tt_axiom(cursorIndex <= std::ssize(text));
89 if (std::ssize(text) == 0) {
92 text_.emplace_back(
grapheme::PS(), text_.back().style, 0);
95 _shapedText =
shaped_text(text_, width, alignment::top_left,
false);
98 [[nodiscard]]
shaped_text shapedText() const noexcept {
102 void setWidth(
float _width)
noexcept {
107 void setCurrentStyle(text_style style)
noexcept {
108 this->currentStyle = style;
114 setCurrentStyle(style);
115 for (
auto &c: text) {
121 size_t size() const noexcept {
128 tt_axiom(index >= 0);
130 tt_axiom(index < std::ssize(text));
132 return text.
begin() + index;
138 tt_axiom(index >= 0);
140 tt_axiom(index <= std::ssize(text));
142 return text.
cbegin() + index;
145 decltype(
auto)
it(
ssize_t index)
const noexcept {
152 if (hasPartialgrapheme) {
153 tt_axiom(cursorIndex != 0);
170 if (selectionIndex < cursorIndex) {
172 }
else if (selectionIndex > cursorIndex) {
183 if (selectionIndex < cursorIndex) {
185 cursorIndex = selectionIndex;
187 }
else if (selectionIndex > cursorIndex) {
189 selectionIndex = cursorIndex;
198 void setmouse_cursorAtCoordinate(
f32x4 coordinate)
noexcept {
200 selectionIndex = cursorIndex = *newmouse_cursorPosition;
201 tt_axiom(selectionIndex >= 0);
202 tt_axiom(selectionIndex <= std::ssize(text));
206 void selectWordAtCoordinate(
f32x4 coordinate)
noexcept {
209 tt_axiom(selectionIndex >= 0);
210 tt_axiom(selectionIndex <= std::ssize(text));
211 tt_axiom(cursorIndex >= 0);
212 tt_axiom(cursorIndex <= std::ssize(text));
216 void selectParagraphAtCoordinate(f32x4 coordinate)
noexcept {
219 tt_axiom(selectionIndex >= 0);
220 tt_axiom(selectionIndex <= std::ssize(text));
221 tt_axiom(cursorIndex >= 0);
222 tt_axiom(cursorIndex <= std::ssize(text));
226 void dragmouse_cursorAtCoordinate(f32x4 coordinate)
noexcept {
228 cursorIndex = *newmouse_cursorPosition;
229 tt_axiom(cursorIndex >= 0);
230 tt_axiom(cursorIndex <= std::ssize(text));
234 void dragWordAtCoordinate(f32x4 coordinate)
noexcept {
236 ttlet [a, b] = _shapedText.
indicesOfWord(*newmouse_cursorPosition);
238 if (selectionIndex <= cursorIndex) {
239 if (a < selectionIndex) {
241 selectionIndex = cursorIndex;
247 if (b > selectionIndex) {
249 selectionIndex = cursorIndex;
256 tt_axiom(selectionIndex >= 0);
257 tt_axiom(selectionIndex <= std::ssize(text));
258 tt_axiom(cursorIndex >= 0);
259 tt_axiom(cursorIndex <= std::ssize(text));
263 void dragParagraphAtCoordinate(f32x4 coordinate)
noexcept {
267 if (selectionIndex <= cursorIndex) {
268 if (a < selectionIndex) {
270 selectionIndex = cursorIndex;
276 if (b > selectionIndex) {
278 selectionIndex = cursorIndex;
285 tt_axiom(selectionIndex >= 0);
286 tt_axiom(selectionIndex <= std::ssize(text));
287 tt_axiom(cursorIndex >= 0);
288 tt_axiom(cursorIndex <= std::ssize(text));
292 void cancelPartialgrapheme() noexcept {
293 if (hasPartialgrapheme) {
294 tt_axiom(cursorIndex >= 1);
296 selectionIndex = --cursorIndex;
297 tt_axiom(selectionIndex >= 0);
298 tt_axiom(selectionIndex <= std::ssize(text));
299 tt_axiom(cursorIndex >= 0);
300 tt_axiom(cursorIndex <= std::ssize(text));
303 hasPartialgrapheme =
false;
315 cancelPartialgrapheme();
318 text.
emplace(
cit(cursorIndex), character, currentStyle);
319 selectionIndex = ++cursorIndex;
320 tt_axiom(selectionIndex >= 0);
321 tt_axiom(selectionIndex <= std::ssize(text));
322 tt_axiom(cursorIndex >= 0);
323 tt_axiom(cursorIndex <= std::ssize(text));
325 hasPartialgrapheme =
true;
333 cancelPartialgrapheme();
337 handle_event(command::text_delete_char_next);
339 text.
emplace(
cit(cursorIndex), character, currentStyle);
340 selectionIndex = ++cursorIndex;
341 tt_axiom(selectionIndex >= 0);
342 tt_axiom(selectionIndex <= std::ssize(text));
343 tt_axiom(cursorIndex >= 0);
344 tt_axiom(cursorIndex <= std::ssize(text));
350 cancelPartialgrapheme();
353 gstring gstr = to_gstring(str);
356 str_attr.
reserve(std::ssize(gstr));
357 for (ttlet &g: gstr) {
358 str_attr.emplace_back(g, currentStyle);
361 text.
insert(
cit(cursorIndex), str_attr.cbegin(), str_attr.cend());
362 selectionIndex = cursorIndex += std::ssize(str_attr);
363 tt_axiom(selectionIndex >= 0);
364 tt_axiom(selectionIndex <= std::ssize(text));
365 tt_axiom(cursorIndex >= 0);
366 tt_axiom(cursorIndex <= std::ssize(text));
374 if (selectionIndex < cursorIndex) {
375 r.
reserve(cursorIndex - selectionIndex);
376 for (
auto i =
cit(selectionIndex); i !=
cit(cursorIndex); ++i) {
379 }
else if (selectionIndex > cursorIndex) {
380 r.reserve(selectionIndex - cursorIndex);
381 for (
auto i =
cit(cursorIndex); i !=
cit(selectionIndex); ++i) {
389 auto r = handleCopy();
390 cancelPartialgrapheme();
395 bool handle_event(command command)
noexcept {
396 auto handled =
false;
398 tt_axiom(cursorIndex <= std::ssize(text));
399 cancelPartialgrapheme();
402 case command::text_cursor_char_left:
406 selectionIndex = cursorIndex = *newmouse_cursorPosition;
410 case command::text_cursor_char_right:
413 selectionIndex = cursorIndex = *newmouse_cursorPosition;
417 case command::text_cursor_word_left:
420 selectionIndex = cursorIndex = *newmouse_cursorPosition;
424 case command::text_cursor_word_right:
427 selectionIndex = cursorIndex = *newmouse_cursorPosition;
431 case command::text_cursor_line_end:
433 selectionIndex = cursorIndex = size() - 1;
436 case command::text_cursor_line_begin:
438 selectionIndex = cursorIndex = 0;
441 case command::text_select_char_left:
444 cursorIndex = *newmouse_cursorPosition;
448 case command::text_select_char_right:
451 cursorIndex = *newmouse_cursorPosition;
455 case command::text_select_word_left:
458 cursorIndex = *newmouse_cursorPosition;
462 case command::text_select_word_right:
465 cursorIndex = *newmouse_cursorPosition;
469 case command::text_select_word:
474 case command::text_select_line_end:
476 cursorIndex = size() - 1;
479 case command::text_select_line_begin:
484 case command::text_select_document:
487 cursorIndex = size() - 1;
490 case command::text_mode_insert:
492 insertMode = !insertMode;
495 case command::text_delete_char_prev:
497 if (cursorIndex != selectionIndex) {
500 }
else if (cursorIndex >= 1) {
501 selectionIndex = --cursorIndex;
507 case command::text_delete_char_next:
509 if (cursorIndex != selectionIndex) {
512 }
else if (cursorIndex < (std::ssize(text) - 1)) {
520 tt_axiom(selectionIndex >= 0);
521 tt_axiom(selectionIndex <= std::ssize(text));
522 tt_axiom(cursorIndex >= 0);
523 tt_axiom(cursorIndex <= std::ssize(text));