Skip to content

Commit 5dcbbd7

Browse files
committed
[fix] multi-cursor erasing complex glitchy
1 parent 150496a commit 5dcbbd7

File tree

4 files changed

+144
-7
lines changed

4 files changed

+144
-7
lines changed

include/ekg/ui/textbox/textbox.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ namespace ekg {
6767
ekg::vec2_t<size_t> b {};
6868
ekg::vec2_t<size_t> delta {};
6969
ekg::rect_t<float> rect {};
70+
bool is_ignored {};
7071
public:
7172
bool operator == (const ekg::vec2_t<size_t> &index) {
7273
return index.x == this->a.x && index.y == this->a.y && index.x == this->b.x && index.y == this->b.y;
@@ -93,7 +94,11 @@ namespace ekg {
9394
}
9495

9596
bool operator == (const ekg::textbox_t::cursor_t &cursor) {
96-
return *this == cursor.a && *this == cursor.b;
97+
return (this->a.x == cursor.a.x && this->a.y == cursor.a.y) && (this->b.x == cursor.b.x && this->b.y == cursor.b.y);
98+
}
99+
100+
bool operator != (const ekg::textbox_t::cursor_t &cursor) {
101+
return !(*this == cursor);
97102
}
98103
};
99104

include/ekg/ui/textbox/widget.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@
2828
#include "textbox.hpp"
2929

3030
namespace ekg::ui {
31+
void refresh_cursors_pos(
32+
ekg::textbox_t &textbox,
33+
ekg::textbox_t::cursor_t &origin,
34+
const ekg::vec2_t<size_t> &displacement_a,
35+
const ekg::vec2_t<size_t> &displacement_b,
36+
const ekg::vec2_t<size_t> &displacement_delta,
37+
ekg::flags_t direction
38+
);
39+
3140
bool find_cursor(
3241
ekg::textbox_t &textbox,
3342
ekg::vec2_t<size_t> &index,
@@ -54,7 +63,7 @@ namespace ekg::ui {
5463
ekg::textbox_t::cursor_t &cursor
5564
);
5665

57-
void refresh_scroll_sizes(
66+
void refresh_scroll_positions(
5867
ekg::textbox_t &textbox
5968
);
6069

src/ui/textbox/textbox.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* copies of the Software, and to permit persons to whom the Software is
1111
* furnished to do so, subject to the following conditions:
1212
*
13-
* The above copyright notice and this permission notice shall be included in all
13+
* The above copyright `notice and this permission notice shall be included in all
1414
* copies or substantial portions of the Software.
1515
*
1616
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

src/ui/textbox/widget.cpp

Lines changed: 127 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,74 @@
3333
#include "ekg/core/pools.hpp"
3434
#include "ekg/math/floating_point.hpp"
3535

36-
void ekg::ui::refresh_scroll_sizes(
36+
void ekg::ui::refresh_cursors_pos(
37+
ekg::textbox_t &textbox,
38+
ekg::textbox_t::cursor_t &origin,
39+
const ekg::vec2_t<size_t> &displacement_a,
40+
const ekg::vec2_t<size_t> &displacement_b,
41+
const ekg::vec2_t<size_t> &displacement_delta,
42+
ekg::flags_t direction
43+
) {
44+
bool is_resize {ekg::has<ekg::dock>(direction, ekg::dock::resize)};
45+
for (ekg::textbox_t::cursor_t &cursor : textbox.widget.cursors) {
46+
if (cursor.is_ignored) continue;
47+
if (cursor.a.y < origin.a.y) continue;
48+
49+
if (!is_resize) {
50+
if (
51+
cursor.a.y == origin.a.y
52+
&&
53+
cursor.a.x > origin.a.x
54+
) {
55+
cursor.a.x = ekg::has<ekg::dock>(direction, ekg::dock::left)
56+
? (cursor.a.x - displacement_a.x) : (cursor.a.x + displacement_a.x);
57+
}
58+
59+
if (
60+
cursor.b.y == origin.b.y
61+
&&
62+
cursor.b.x > origin.b.x
63+
) {
64+
cursor.b.x = ekg::has<ekg::dock>(direction, ekg::dock::left)
65+
? (cursor.b.x - displacement_b.x) : (cursor.b.x + displacement_b.x);
66+
}
67+
68+
if (cursor.a.y >= origin.b.y) {
69+
cursor.a.y -= displacement_a.y;
70+
cursor.b.y -= displacement_b.y;
71+
}
72+
} else {
73+
if (
74+
cursor.a.y == origin.b.y
75+
&&
76+
cursor.a.x > origin.b.x
77+
) {
78+
cursor.a.x = (origin.a.x < origin.b.x) ?
79+
cursor.a.x - (origin.b.x - origin.a.x)
80+
:
81+
cursor.a.x + (origin.a.x - origin.b.x);
82+
}
83+
84+
if (
85+
cursor.b.y == origin.b.y
86+
&&
87+
cursor.b.x > origin.b.x
88+
) {
89+
cursor.b.x = (origin.a.x < origin.b.x) ?
90+
cursor.b.x- (origin.b.x - origin.a.x)
91+
:
92+
cursor.b.x + (origin.a.x - origin.b.x);
93+
}
94+
95+
if (cursor.a.y >= origin.b.y) {
96+
cursor.a.y -= displacement_a.y;
97+
cursor.b.y -= displacement_b.y;
98+
}
99+
}
100+
}
101+
}
102+
103+
void ekg::ui::refresh_scroll_positions(
37104
ekg::textbox_t &textbox
38105
) {
39106
size_t highest_size {};
@@ -211,6 +278,33 @@ void ekg::ui::handle_cursor_interact(
211278
ekg::input_info_t &input
212279
) {
213280
if (input.was_released && !input.was_typed) {
281+
if (
282+
textbox.widget.current_cursor_index != UINT64_MAX
283+
&&
284+
textbox.widget.current_cursor_index < textbox.widget.cursors.size()
285+
) {
286+
ekg::textbox_t::cursor_t cursor {
287+
textbox.widget.cursors[textbox.widget.current_cursor_index]
288+
};
289+
290+
std::vector<ekg::textbox_t::cursor_t> new_cursors {};
291+
for (size_t i {}; i < textbox.widget.cursors.size(); i++) {
292+
ekg::textbox_t::cursor_t cur {textbox.widget.cursors[i]};
293+
if (cursor == cur) {
294+
new_cursors.push_back(cur);
295+
continue;
296+
}
297+
298+
if (cursor >= cur.a && cursor <= cur.b) {
299+
continue;
300+
}
301+
302+
new_cursors.push_back(cur);
303+
}
304+
305+
textbox.widget.cursors = new_cursors;
306+
}
307+
214308
textbox.widget.current_cursor_index = UINT64_MAX;
215309
}
216310

@@ -304,6 +398,21 @@ void ekg::ui::handle_erase(
304398
std::string line {textbox.text.at(cursor.a.y)};
305399
std::string concated {};
306400

401+
ekg::textbox_t::cursor_t origin {cursor};
402+
origin.a = origin.delta;
403+
origin.b = origin.delta;
404+
405+
cursor.is_ignored = true;
406+
ekg::ui::refresh_cursors_pos(
407+
textbox,
408+
origin,
409+
{cursor.b.x - cursor.a.x, 0},
410+
{cursor.b.x - cursor.a.x, 0},
411+
{cursor.b.x - cursor.a.x, 0},
412+
ekg::dock::left
413+
);
414+
cursor.is_ignored = false;
415+
307416
ekg::utf8_concat(
308417
line,
309418
{0, cursor.a.x, cursor.b.x, line.size()},
@@ -322,6 +431,19 @@ void ekg::ui::handle_erase(
322431
return;
323432
}
324433

434+
ekg::textbox_t::cursor_t origin {cursor};
435+
436+
cursor.is_ignored = true;
437+
ekg::ui::refresh_cursors_pos(
438+
textbox,
439+
origin,
440+
{cursor.b.x, cursor.b.y - cursor.a.y},
441+
{cursor.b.x, cursor.b.y - cursor.a.y},
442+
{cursor.b.x, cursor.b.y - cursor.a.y},
443+
ekg::dock::left | ekg::dock::resize
444+
);
445+
446+
cursor.is_ignored = false;
325447
textbox.text.set(
326448
cursor.a.y,
327449
ekg::utf8_substr(
@@ -425,7 +547,6 @@ void ekg::ui::reload(
425547
textbox.widget.scrollbar.rect.x = rect_abs.x;
426548
textbox.widget.scrollbar.rect.y = rect_abs.y;
427549
textbox.widget.scrollbar.acceleration = {textbox.widget.rect_text_size.h, textbox.widget.rect_text_size.h};
428-
429550
textbox.widget.scrollbar.color_scheme = ekg::p_core->handler_theme.get_current_theme().scrollbar_color_scheme;
430551

431552
ekg::ui::reload(
@@ -436,7 +557,7 @@ void ekg::ui::reload(
436557
false
437558
);
438559

439-
ekg::ui::refresh_scroll_sizes(textbox);
560+
ekg::ui::refresh_scroll_positions(textbox);
440561
}
441562

442563
void ekg::ui::event(
@@ -704,6 +825,8 @@ void ekg::ui::event(
704825
}
705826

706827
is_ab_equals = true;
828+
} else {
829+
cursor.delta = cursor.a;
707830
}
708831

709832

@@ -930,7 +1053,7 @@ void ekg::ui::event(
9301053
}
9311054

9321055
if (is_action_erase_fired || input.was_typed || is_action_break_line_fired) {
933-
ekg::ui::refresh_scroll_sizes(textbox);
1056+
ekg::ui::refresh_scroll_positions(textbox);
9341057
}
9351058

9361059
ekg::gui.ui.redraw = true;

0 commit comments

Comments
 (0)