Skip to content

Commit

Permalink
sdlconsole: fix disabled cursor on focus gain. plus tweaks to prompt.
Browse files Browse the repository at this point in the history
  • Loading branch information
dhthwy committed Nov 20, 2024
1 parent b7fe35b commit b44a35a
Showing 1 changed file with 36 additions and 42 deletions.
78 changes: 36 additions & 42 deletions library/Console-sdl-impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ CONSOLE_DECLARE_SYMBOL(SDL_SetRenderDrawColor);
CONSOLE_DECLARE_SYMBOL(SDL_SetTextureBlendMode);
CONSOLE_DECLARE_SYMBOL(SDL_SetTextureColorMod);
CONSOLE_DECLARE_SYMBOL(SDL_SetWindowMinimumSize);
CONSOLE_DECLARE_SYMBOL(SDL_ShowCursor);
CONSOLE_DECLARE_SYMBOL(SDL_ShowWindow);
CONSOLE_DECLARE_SYMBOL(SDL_StartTextInput);
CONSOLE_DECLARE_SYMBOL(SDL_StopTextInput);
Expand Down Expand Up @@ -137,6 +138,7 @@ void bind_sdl_symbols()
CONSOLE_ADD_SYMBOL(SDL_SetTextureBlendMode),
CONSOLE_ADD_SYMBOL(SDL_SetTextureColorMod),
CONSOLE_ADD_SYMBOL(SDL_SetWindowMinimumSize),
CONSOLE_ADD_SYMBOL(SDL_ShowCursor),
CONSOLE_ADD_SYMBOL(SDL_ShowWindow),
CONSOLE_ADD_SYMBOL(SDL_StartTextInput),
CONSOLE_ADD_SYMBOL(SDL_StopTextInput),
Expand Down Expand Up @@ -1653,6 +1655,22 @@ class Widget : public SignalEmitter {

class Prompt : public Widget {
public:
// Holds wrapped lines from input
TextEntry entry;
// The text of the prompt itself.
std::u32string prompt_text;
// The input portion of the prompt.
std::u32string* input;
size_t cursor { 0 }; // position of cursor within an entry
// 1x1 texture stretched to font's single character dimensions
SDL_Texture* cursor_texture;
/*
* For input history.
* use deque to hold a stable reference.
*/
std::deque<std::u32string> history;
int history_index;

Prompt(Widget* parent)
: Widget(parent)
{
Expand All @@ -1678,6 +1696,7 @@ class Prompt : public Widget {
//sdl_tsd.DestroyTexture(cursor_texture);
}

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

case SDLK_b:
if (sdl_console::SDL_GetModState() & KMOD_CTRL) {
cursor = text::prev_word_pos(*input, (size_t)cursor);
cursor = text::prev_word_pos(*input, cursor);
}
break;

case SDLK_f:
if (sdl_console::SDL_GetModState() & KMOD_CTRL) {
cursor = text::next_word_pos(*input, (size_t)cursor);
cursor = text::next_word_pos(*input, cursor);
}
break;
case SDLK_c:
// FIXME: OutputPane also listens for ctrl-c for copying text.
// TODO: Add state for when selecting text
if (sdl_console::SDL_GetModState() & KMOD_CTRL) {
*input += U"^C";
new_interrupted_command();
Expand All @@ -1766,9 +1787,9 @@ class Prompt : public Widget {
void set_command_history(std::deque<std::u32string> saved_history)
{
std::swap(history, saved_history);
saved_history.clear();
input = &history.emplace_back(U"");
history_index = history.size() - 1;
reset_cursor();
}

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

input = &history.emplace_back(U"");
history_index = history.size() - 1;

reset_cursor();
wrap_text();
}

void new_interrupted_command()
{
emit(InternalEventType::new_input, input);
input->clear();
reset_cursor();
wrap_text();
}

void reset_cursor()
{
cursor = 0;
rebuild = true;
}

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

input = &history.at(history_index);
cursor = input->length();
rebuild = true;
wrap_text();
}

void put_input_at_cursor(const std::u32string& str)
Expand All @@ -1836,7 +1857,7 @@ class Prompt : public Widget {
input->insert(cursor, str);
}
cursor += str.length();
rebuild = true;
wrap_text();
}

void erase_input()
Expand All @@ -1851,7 +1872,7 @@ class Prompt : public Widget {
input->erase(cursor-1, 1);
}
cursor -= 1;
rebuild = true;
wrap_text();
}

void move_cursor_left()
Expand All @@ -1874,14 +1895,6 @@ class Prompt : public Widget {
wrap_text();
}

void maybe_rebuild()
{
if (rebuild) {
wrap_text();
rebuild = false;
}
}

void wrap_text()
{
entry.text = prompt_text + *input;
Expand All @@ -1898,7 +1911,7 @@ class Prompt : public Widget {

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

Prompt(const Prompt&) = delete;
Prompt& operator=(const Prompt&) = delete;

// Holds wrapped lines from input
TextEntry entry;
// The text of the prompt itself.
std::u32string prompt_text;
// The input portion of the prompt.
std::u32string* input;
// Prompt text/input/cursor was changed flag
bool rebuild { true };
size_t cursor { 0 }; // position of cursor within an entry
// 1x1 texture stretched to font's single character dimensions
SDL_Texture* cursor_texture;
/*
* For input history.
* use deque to hold a stable reference.
*/
std::deque<std::u32string> history;
int history_index;
};

class Scrollbar : public Widget {
Expand Down Expand Up @@ -2634,7 +2629,7 @@ class OutputPane : public Widget {
{
for (auto& entry : entries) {
for (auto& frag : entry.fragments()) {
if (geometry::is_y_within_bounds(y, frag.coord.y, font->line_height_with_spacing())) {
if (geometry::is_y_within_bounds(y, frag.coord.y, font->line_height)) {
return frag;
}
}
Expand All @@ -2650,7 +2645,7 @@ class OutputPane : public Widget {

void copy_selected_text_to_clipboard()
{
char32_t sep = U'\n';
auto sep = U'\n';
std::u32string clipboard_text;

for (const auto& rect : text_selection.rects) {
Expand Down Expand Up @@ -2697,10 +2692,10 @@ class OutputPane : public Widget {
{
// SDL_RenderSetScale(renderer(), 1.2, 1.2);
sdl_console::SDL_RenderSetViewport(renderer(), &viewport);
prompt.maybe_rebuild();
// TODO: make sure renderer supports blending else highlighting
// will make the text invisible.
render_highlight_selected_text();
if (!text_selection.rects.empty())
render_highlight_selected_text();
// SDL_SetTextureColorMod(font->texture, 0, 128, 0);
render_prompt_and_output();
// SDL_SetTextureColorMod(font->texture, 255, 255, 255);
Expand Down Expand Up @@ -2749,9 +2744,6 @@ class OutputPane : public Widget {

void render_highlight_selected_text()
{
if (text_selection.rects.empty())
return;

set_draw_color(renderer(), colors::mediumgray);
for (auto& rect : text_selection.rects) {

Expand Down Expand Up @@ -2831,6 +2823,8 @@ class MainWindow : public Widget {
} else if (e.event == SDL_WINDOWEVENT_FOCUS_LOST) {
has_focus = false;
} else if (e.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
// TODO: Check if cursor is disabled first.
SDL_ShowCursor(SDL_ENABLE);
has_focus = true;
}
});
Expand Down

0 comments on commit b44a35a

Please sign in to comment.