Skip to content

Commit 78c561b

Browse files
committed
[update] monospaced flag; fixed textbox visual selection
1 parent 6fe9c74 commit 78c561b

File tree

5 files changed

+58
-15
lines changed

5 files changed

+58
-15
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#
1212
# The above copyright notice and this permission notice shall be included in all
1313
# copies or substantial portions of the Software.
14-
# 1
14+
#
1515
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1616
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1717
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

include/ekg/draw/typography/font.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ namespace ekg::draw {
5656
bool font_size_changed {};
5757
bool was_initialized {};
5858
bool is_any_functional_font_face_loaded {};
59+
bool is_monospaced {};
5960
public:
6061
void init();
6162
void quit();

include/ekg/ui/textbox/textbox.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ namespace ekg {
5656
struct select_draw_layer_t {
5757
public:
5858
bool is_ab_equals {};
59+
bool is_always_static {};
5960
ekg::rect_t<float> rect {};
6061
};
6162

src/draw/typography/font.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,11 @@ void ekg::draw::font::reload() {
401401
);
402402
}
403403

404+
this->is_monospaced = FT_IS_FIXED_WIDTH(text_font_face.ft_face);
405+
this->space_wsize = this->text_height / 3.0f;
406+
404407
FT_Vector space_char_metrics {};
405408
FT_Get_Kerning(text_font_face.ft_face, 32, 32, 0, &space_char_metrics);
406-
this->space_wsize = static_cast<float>(space_char_metrics.x >> 6);
407409

408410
this->text_height = static_cast<float>(this->font_size);
409411
this->offset_text_height = this->text_height / 6;

src/ui/textbox/widget.cpp

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void ekg::ui::refresh_cursors_pos(
4141
const ekg::ui::textbox_operation &operation
4242
) {
4343
for (ekg::textbox_t::cursor_t &cursor : textbox.widget.cursors) {
44-
if (cursor.is_ignored || cursor.a.y < origin.a.y) continue;
44+
if (cursor.is_ignored || cursor.is_deleted || cursor.a.y < origin.a.y) continue;
4545

4646
switch (operation) {
4747
case ekg::ui::textbox_operation::insert_line:
@@ -891,6 +891,8 @@ void ekg::ui::event(
891891
bool should_clear_equals_repeated_cursors {};
892892

893893
for (ekg::textbox_t::cursor_t &cursor : textbox.widget.cursors) {
894+
if (cursor.is_deleted) continue;
895+
894896
cursor_count++;
895897
is_ab_equals = cursor.a == cursor.b;
896898

@@ -1274,7 +1276,7 @@ void ekg::ui::buffering(
12741276

12751277
ekg::rect_t<float> rect_select {};
12761278
for (ekg::textbox_t::select_draw_layer_t &layer : textbox.widget.layers_select) {
1277-
if (layer.is_ab_equals && elapsed_mid_second) {
1279+
if (!layer.is_always_static && layer.is_ab_equals && elapsed_mid_second) {
12781280
continue;
12791281
}
12801282

@@ -1385,7 +1387,7 @@ void ekg::ui::buffering(
13851387
* This technique works because the line height is fixed, ultimately, soon, should be re-worked
13861388
* to support differents text-heights at same time, also, for widgets scrolling (I do not think
13871389
* someone can write a GUI context with +5000000 heights from widgets without pages).
1388-
* []
1390+
*
13891391
* - Rina - 11:39; 08/06/2025
13901392
**/
13911393
float visible_text_height {static_cast<float>(textbox.widget.view_line_index * textbox.widget.rect_text_size.h)};
@@ -1468,41 +1470,76 @@ void ekg::ui::buffering(
14681470
)
14691471
)
14701472
) {
1471-
glyph_wsize = glyph.wsize;
1473+
glyph_wsize = glyph.wsize;
14721474
end_cursor_position = glyph_wsize * is_cursor_at_end_of_line;
14731475
is_ab_equals_selected = property.states.is_focused && cursor == index;
1476+
14741477
is_inline_selected = cursor >= index && cursor < index && !is_ab_equals_selected;
14751478
is_complete_line_selected = false;
14761479

14771480
if (is_inline_selected) {
14781481
if (
14791482
(
1480-
cursor >= ekg::vec2_t<size_t>(0, index.y)
1481-
)
1482-
&&
1483-
(
1484-
cursor <= ekg::vec2_t<size_t>(text_len, index.y)
1483+
(
1484+
cursor >= ekg::vec2_t<size_t>(0, index.y)
1485+
)
1486+
&&
1487+
(
1488+
cursor <= ekg::vec2_t<size_t>(text_len, index.y)
1489+
)
14851490
)
14861491
) {
14871492
is_inline_selected = false;
14881493
}
1494+
14891495
is_complete_line_selected = !is_inline_selected;
14901496
}
14911497

1498+
ekg::textbox_t::cursor_t nearest_cursor {};
1499+
ekg::vec2_t<size_t> next_line_index(0, index.y + 1);
1500+
bool is_next_line_selected_in_some_way {};
1501+
1502+
if (
1503+
!is_complete_line_selected
1504+
&&
1505+
is_last_char_from_line
1506+
&&
1507+
(is_next_line_selected_in_some_way = ekg::ui::find_cursor(textbox, next_line_index, nearest_cursor))
1508+
) {
1509+
glyph_wsize += draw_font.space_wsize;
1510+
}
1511+
1512+
ekg::vec2_t<size_t> next_char_index(next_line_index.x + 1, next_line_index.y);
1513+
if (
1514+
!textbox.color_scheme.caret_cursor
1515+
&&
1516+
is_next_line_selected_in_some_way
1517+
&&
1518+
is_inline_selected
1519+
&&
1520+
!ekg::ui::find_cursor(textbox, next_char_index, nearest_cursor)
1521+
) {
1522+
cursor.rect.x = textbox.color_scheme.gutter_margin;
1523+
cursor.rect.y = pos.y + textbox.widget.rect_text_size.h;
1524+
cursor.rect.w = textbox.color_scheme.cursor_thickness;
1525+
cursor.rect.h = textbox.widget.rect_text_size.h;
1526+
textbox.widget.layers_select.push_back({.is_ab_equals = true, .is_always_static = true, .rect = cursor.rect});
1527+
}
1528+
14921529
if (is_ab_equals_selected) {
14931530
cursor.rect.x = pos.x + end_cursor_position;
14941531
cursor.rect.y = pos.y;
14951532
cursor.rect.w = textbox.color_scheme.caret_cursor ? glyph_wsize : textbox.color_scheme.cursor_thickness;
14961533
cursor.rect.h = textbox.widget.rect_text_size.h;
1497-
textbox.widget.layers_select.push_back({true, cursor.rect});
1534+
textbox.widget.layers_select.push_back({.is_ab_equals = true, .rect = cursor.rect});
14981535
}
14991536

15001537
if (is_inline_selected) {
15011538
cursor.rect.x = pos.x + end_cursor_position;
15021539
cursor.rect.y = pos.y;
15031540
cursor.rect.w = glyph_wsize;
15041541
cursor.rect.h = textbox.widget.rect_text_size.h;
1505-
textbox.widget.layers_select.push_back({false, cursor.rect});
1542+
textbox.widget.layers_select.push_back({.rect = cursor.rect});
15061543
}
15071544

15081545
if (
@@ -1516,6 +1553,8 @@ void ekg::ui::buffering(
15161553
if (is_complete_line_selected && !is_empty) {
15171554
line_wsize += glyph_wsize;
15181555
}
1556+
1557+
is_cursor_at_end_of_line = false;
15191558
}
15201559

15211560
if (is_empty) {
@@ -1596,8 +1635,8 @@ void ekg::ui::buffering(
15961635
cursor.rect.x = textbox.color_scheme.gutter_margin;
15971636
cursor.rect.y = pos.y;
15981637
cursor.rect.h = textbox.widget.rect_text_size.h;
1599-
cursor.rect.w = line_wsize + glyph_wsize;
1600-
textbox.widget.layers_select.push_back({false, cursor.rect});
1638+
cursor.rect.w = line_wsize + draw_font.space_wsize;
1639+
textbox.widget.layers_select.push_back({.rect = cursor.rect});
16011640
is_complete_line_selected = false;
16021641
}
16031642

0 commit comments

Comments
 (0)