Skip to content

Commit b44a35a

Browse files
committed
sdlconsole: fix disabled cursor on focus gain. plus tweaks to prompt.
1 parent b7fe35b commit b44a35a

File tree

1 file changed

+36
-42
lines changed

1 file changed

+36
-42
lines changed

library/Console-sdl-impl.cpp

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ CONSOLE_DECLARE_SYMBOL(SDL_SetRenderDrawColor);
7676
CONSOLE_DECLARE_SYMBOL(SDL_SetTextureBlendMode);
7777
CONSOLE_DECLARE_SYMBOL(SDL_SetTextureColorMod);
7878
CONSOLE_DECLARE_SYMBOL(SDL_SetWindowMinimumSize);
79+
CONSOLE_DECLARE_SYMBOL(SDL_ShowCursor);
7980
CONSOLE_DECLARE_SYMBOL(SDL_ShowWindow);
8081
CONSOLE_DECLARE_SYMBOL(SDL_StartTextInput);
8182
CONSOLE_DECLARE_SYMBOL(SDL_StopTextInput);
@@ -137,6 +138,7 @@ void bind_sdl_symbols()
137138
CONSOLE_ADD_SYMBOL(SDL_SetTextureBlendMode),
138139
CONSOLE_ADD_SYMBOL(SDL_SetTextureColorMod),
139140
CONSOLE_ADD_SYMBOL(SDL_SetWindowMinimumSize),
141+
CONSOLE_ADD_SYMBOL(SDL_ShowCursor),
140142
CONSOLE_ADD_SYMBOL(SDL_ShowWindow),
141143
CONSOLE_ADD_SYMBOL(SDL_StartTextInput),
142144
CONSOLE_ADD_SYMBOL(SDL_StopTextInput),
@@ -1653,6 +1655,22 @@ class Widget : public SignalEmitter {
16531655

16541656
class Prompt : public Widget {
16551657
public:
1658+
// Holds wrapped lines from input
1659+
TextEntry entry;
1660+
// The text of the prompt itself.
1661+
std::u32string prompt_text;
1662+
// The input portion of the prompt.
1663+
std::u32string* input;
1664+
size_t cursor { 0 }; // position of cursor within an entry
1665+
// 1x1 texture stretched to font's single character dimensions
1666+
SDL_Texture* cursor_texture;
1667+
/*
1668+
* For input history.
1669+
* use deque to hold a stable reference.
1670+
*/
1671+
std::deque<std::u32string> history;
1672+
int history_index;
1673+
16561674
Prompt(Widget* parent)
16571675
: Widget(parent)
16581676
{
@@ -1678,6 +1696,7 @@ class Prompt : public Widget {
16781696
//sdl_tsd.DestroyTexture(cursor_texture);
16791697
}
16801698

1699+
// NOTE: Only called by constructor.
16811700
void create_cursor_texture()
16821701
{
16831702
cursor_texture = sdl_tsd.CreateTexture(renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC, 1, 1);
@@ -1745,16 +1764,18 @@ class Prompt : public Widget {
17451764

17461765
case SDLK_b:
17471766
if (sdl_console::SDL_GetModState() & KMOD_CTRL) {
1748-
cursor = text::prev_word_pos(*input, (size_t)cursor);
1767+
cursor = text::prev_word_pos(*input, cursor);
17491768
}
17501769
break;
17511770

17521771
case SDLK_f:
17531772
if (sdl_console::SDL_GetModState() & KMOD_CTRL) {
1754-
cursor = text::next_word_pos(*input, (size_t)cursor);
1773+
cursor = text::next_word_pos(*input, cursor);
17551774
}
17561775
break;
17571776
case SDLK_c:
1777+
// FIXME: OutputPane also listens for ctrl-c for copying text.
1778+
// TODO: Add state for when selecting text
17581779
if (sdl_console::SDL_GetModState() & KMOD_CTRL) {
17591780
*input += U"^C";
17601781
new_interrupted_command();
@@ -1766,9 +1787,9 @@ class Prompt : public Widget {
17661787
void set_command_history(std::deque<std::u32string> saved_history)
17671788
{
17681789
std::swap(history, saved_history);
1769-
saved_history.clear();
17701790
input = &history.emplace_back(U"");
17711791
history_index = history.size() - 1;
1792+
reset_cursor();
17721793
}
17731794

17741795
void new_command_input()
@@ -1780,21 +1801,21 @@ class Prompt : public Widget {
17801801

17811802
input = &history.emplace_back(U"");
17821803
history_index = history.size() - 1;
1783-
17841804
reset_cursor();
1805+
wrap_text();
17851806
}
17861807

17871808
void new_interrupted_command()
17881809
{
17891810
emit(InternalEventType::new_input, input);
17901811
input->clear();
17911812
reset_cursor();
1813+
wrap_text();
17921814
}
17931815

17941816
void reset_cursor()
17951817
{
17961818
cursor = 0;
1797-
rebuild = true;
17981819
}
17991820

18001821
void set_prompt_text(const std::u32string& value)
@@ -1823,7 +1844,7 @@ class Prompt : public Widget {
18231844

18241845
input = &history.at(history_index);
18251846
cursor = input->length();
1826-
rebuild = true;
1847+
wrap_text();
18271848
}
18281849

18291850
void put_input_at_cursor(const std::u32string& str)
@@ -1836,7 +1857,7 @@ class Prompt : public Widget {
18361857
input->insert(cursor, str);
18371858
}
18381859
cursor += str.length();
1839-
rebuild = true;
1860+
wrap_text();
18401861
}
18411862

18421863
void erase_input()
@@ -1851,7 +1872,7 @@ class Prompt : public Widget {
18511872
input->erase(cursor-1, 1);
18521873
}
18531874
cursor -= 1;
1854-
rebuild = true;
1875+
wrap_text();
18551876
}
18561877

18571878
void move_cursor_left()
@@ -1874,14 +1895,6 @@ class Prompt : public Widget {
18741895
wrap_text();
18751896
}
18761897

1877-
void maybe_rebuild()
1878-
{
1879-
if (rebuild) {
1880-
wrap_text();
1881-
rebuild = false;
1882-
}
1883-
}
1884-
18851898
void wrap_text()
18861899
{
18871900
entry.text = prompt_text + *input;
@@ -1898,7 +1911,7 @@ class Prompt : public Widget {
18981911

18991912
// If cursor is the head, nullopt will be returned as it falls outside
19001913
// the fragment boundary. Maybe FIXME
1901-
auto& line = [this, cursor_pos]()->auto& {
1914+
auto& line = [this, cursor_pos]() -> auto& {
19021915
if (auto line_opt = entry.fragment_from_offset(cursor_pos)) {
19031916
return line_opt.value().get();
19041917
} else {
@@ -1929,24 +1942,6 @@ class Prompt : public Widget {
19291942

19301943
Prompt(const Prompt&) = delete;
19311944
Prompt& operator=(const Prompt&) = delete;
1932-
1933-
// Holds wrapped lines from input
1934-
TextEntry entry;
1935-
// The text of the prompt itself.
1936-
std::u32string prompt_text;
1937-
// The input portion of the prompt.
1938-
std::u32string* input;
1939-
// Prompt text/input/cursor was changed flag
1940-
bool rebuild { true };
1941-
size_t cursor { 0 }; // position of cursor within an entry
1942-
// 1x1 texture stretched to font's single character dimensions
1943-
SDL_Texture* cursor_texture;
1944-
/*
1945-
* For input history.
1946-
* use deque to hold a stable reference.
1947-
*/
1948-
std::deque<std::u32string> history;
1949-
int history_index;
19501945
};
19511946

19521947
class Scrollbar : public Widget {
@@ -2634,7 +2629,7 @@ class OutputPane : public Widget {
26342629
{
26352630
for (auto& entry : entries) {
26362631
for (auto& frag : entry.fragments()) {
2637-
if (geometry::is_y_within_bounds(y, frag.coord.y, font->line_height_with_spacing())) {
2632+
if (geometry::is_y_within_bounds(y, frag.coord.y, font->line_height)) {
26382633
return frag;
26392634
}
26402635
}
@@ -2650,7 +2645,7 @@ class OutputPane : public Widget {
26502645

26512646
void copy_selected_text_to_clipboard()
26522647
{
2653-
char32_t sep = U'\n';
2648+
auto sep = U'\n';
26542649
std::u32string clipboard_text;
26552650

26562651
for (const auto& rect : text_selection.rects) {
@@ -2697,10 +2692,10 @@ class OutputPane : public Widget {
26972692
{
26982693
// SDL_RenderSetScale(renderer(), 1.2, 1.2);
26992694
sdl_console::SDL_RenderSetViewport(renderer(), &viewport);
2700-
prompt.maybe_rebuild();
27012695
// TODO: make sure renderer supports blending else highlighting
27022696
// will make the text invisible.
2703-
render_highlight_selected_text();
2697+
if (!text_selection.rects.empty())
2698+
render_highlight_selected_text();
27042699
// SDL_SetTextureColorMod(font->texture, 0, 128, 0);
27052700
render_prompt_and_output();
27062701
// SDL_SetTextureColorMod(font->texture, 255, 255, 255);
@@ -2749,9 +2744,6 @@ class OutputPane : public Widget {
27492744

27502745
void render_highlight_selected_text()
27512746
{
2752-
if (text_selection.rects.empty())
2753-
return;
2754-
27552747
set_draw_color(renderer(), colors::mediumgray);
27562748
for (auto& rect : text_selection.rects) {
27572749

@@ -2831,6 +2823,8 @@ class MainWindow : public Widget {
28312823
} else if (e.event == SDL_WINDOWEVENT_FOCUS_LOST) {
28322824
has_focus = false;
28332825
} else if (e.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
2826+
// TODO: Check if cursor is disabled first.
2827+
SDL_ShowCursor(SDL_ENABLE);
28342828
has_focus = true;
28352829
}
28362830
});

0 commit comments

Comments
 (0)