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(
point2 coordinate)
noexcept
201 selectionIndex = cursorIndex = *newmouse_cursorPosition;
202 tt_axiom(selectionIndex >= 0);
203 tt_axiom(selectionIndex <= std::ssize(text));
207 void selectWordAtCoordinate(
point2 coordinate)
noexcept
211 tt_axiom(selectionIndex >= 0);
212 tt_axiom(selectionIndex <= std::ssize(text));
213 tt_axiom(cursorIndex >= 0);
214 tt_axiom(cursorIndex <= std::ssize(text));
218 void selectParagraphAtCoordinate(point2 coordinate)
noexcept
222 tt_axiom(selectionIndex >= 0);
223 tt_axiom(selectionIndex <= std::ssize(text));
224 tt_axiom(cursorIndex >= 0);
225 tt_axiom(cursorIndex <= std::ssize(text));
229 void dragmouse_cursorAtCoordinate(point2 coordinate)
noexcept
232 cursorIndex = *newmouse_cursorPosition;
233 tt_axiom(cursorIndex >= 0);
234 tt_axiom(cursorIndex <= std::ssize(text));
238 void dragWordAtCoordinate(point2 coordinate)
noexcept
241 ttlet [a, b] = _shapedText.
indicesOfWord(*newmouse_cursorPosition);
243 if (selectionIndex <= cursorIndex) {
244 if (a < selectionIndex) {
246 selectionIndex = cursorIndex;
252 if (b > selectionIndex) {
254 selectionIndex = cursorIndex;
261 tt_axiom(selectionIndex >= 0);
262 tt_axiom(selectionIndex <= std::ssize(text));
263 tt_axiom(cursorIndex >= 0);
264 tt_axiom(cursorIndex <= std::ssize(text));
268 void dragParagraphAtCoordinate(point2 coordinate)
noexcept
273 if (selectionIndex <= cursorIndex) {
274 if (a < selectionIndex) {
276 selectionIndex = cursorIndex;
282 if (b > selectionIndex) {
284 selectionIndex = cursorIndex;
291 tt_axiom(selectionIndex >= 0);
292 tt_axiom(selectionIndex <= std::ssize(text));
293 tt_axiom(cursorIndex >= 0);
294 tt_axiom(cursorIndex <= std::ssize(text));
298 void cancelPartialgrapheme() noexcept {
299 if (hasPartialgrapheme) {
300 tt_axiom(cursorIndex >= 1);
302 selectionIndex = --cursorIndex;
303 tt_axiom(selectionIndex >= 0);
304 tt_axiom(selectionIndex <= std::ssize(text));
305 tt_axiom(cursorIndex >= 0);
306 tt_axiom(cursorIndex <= std::ssize(text));
309 hasPartialgrapheme =
false;
321 cancelPartialgrapheme();
324 text.
emplace(
cit(cursorIndex), character, currentStyle);
325 selectionIndex = ++cursorIndex;
326 tt_axiom(selectionIndex >= 0);
327 tt_axiom(selectionIndex <= std::ssize(text));
328 tt_axiom(cursorIndex >= 0);
329 tt_axiom(cursorIndex <= std::ssize(text));
331 hasPartialgrapheme =
true;
339 cancelPartialgrapheme();
343 handle_event(command::text_delete_char_next);
345 text.
emplace(
cit(cursorIndex), character, currentStyle);
346 selectionIndex = ++cursorIndex;
347 tt_axiom(selectionIndex >= 0);
348 tt_axiom(selectionIndex <= std::ssize(text));
349 tt_axiom(cursorIndex >= 0);
350 tt_axiom(cursorIndex <= std::ssize(text));
356 cancelPartialgrapheme();
359 gstring gstr = to_gstring(str);
362 str_attr.
reserve(std::ssize(gstr));
363 for (ttlet &g: gstr) {
364 str_attr.emplace_back(g, currentStyle);
367 text.
insert(
cit(cursorIndex), str_attr.cbegin(), str_attr.cend());
368 selectionIndex = cursorIndex += std::ssize(str_attr);
369 tt_axiom(selectionIndex >= 0);
370 tt_axiom(selectionIndex <= std::ssize(text));
371 tt_axiom(cursorIndex >= 0);
372 tt_axiom(cursorIndex <= std::ssize(text));
380 if (selectionIndex < cursorIndex) {
381 r.
reserve(cursorIndex - selectionIndex);
382 for (
auto i =
cit(selectionIndex); i !=
cit(cursorIndex); ++i) {
385 }
else if (selectionIndex > cursorIndex) {
386 r.reserve(selectionIndex - cursorIndex);
387 for (
auto i =
cit(cursorIndex); i !=
cit(selectionIndex); ++i) {
395 auto r = handleCopy();
396 cancelPartialgrapheme();
401 bool handle_event(command command)
noexcept {
402 auto handled =
false;
404 tt_axiom(cursorIndex <= std::ssize(text));
405 cancelPartialgrapheme();
408 case command::text_cursor_char_left:
412 selectionIndex = cursorIndex = *newmouse_cursorPosition;
416 case command::text_cursor_char_right:
419 selectionIndex = cursorIndex = *newmouse_cursorPosition;
423 case command::text_cursor_word_left:
426 selectionIndex = cursorIndex = *newmouse_cursorPosition;
430 case command::text_cursor_word_right:
433 selectionIndex = cursorIndex = *newmouse_cursorPosition;
437 case command::text_cursor_line_end:
439 selectionIndex = cursorIndex = size() - 1;
442 case command::text_cursor_line_begin:
444 selectionIndex = cursorIndex = 0;
447 case command::text_select_char_left:
450 cursorIndex = *newmouse_cursorPosition;
454 case command::text_select_char_right:
457 cursorIndex = *newmouse_cursorPosition;
461 case command::text_select_word_left:
464 cursorIndex = *newmouse_cursorPosition;
468 case command::text_select_word_right:
471 cursorIndex = *newmouse_cursorPosition;
475 case command::text_select_word:
480 case command::text_select_line_end:
482 cursorIndex = size() - 1;
485 case command::text_select_line_begin:
490 case command::text_select_document:
493 cursorIndex = size() - 1;
496 case command::text_mode_insert:
498 insertMode = !insertMode;
501 case command::text_delete_char_prev:
503 if (cursorIndex != selectionIndex) {
506 }
else if (cursorIndex >= 1) {
507 selectionIndex = --cursorIndex;
513 case command::text_delete_char_next:
515 if (cursorIndex != selectionIndex) {
518 }
else if (cursorIndex < (std::ssize(text) - 1)) {
526 tt_axiom(selectionIndex >= 0);
527 tt_axiom(selectionIndex <= std::ssize(text));
528 tt_axiom(cursorIndex >= 0);
529 tt_axiom(cursorIndex <= std::ssize(text));