@@ -76,6 +76,7 @@ CONSOLE_DECLARE_SYMBOL(SDL_SetRenderDrawColor);
7676CONSOLE_DECLARE_SYMBOL (SDL_SetTextureBlendMode);
7777CONSOLE_DECLARE_SYMBOL (SDL_SetTextureColorMod);
7878CONSOLE_DECLARE_SYMBOL (SDL_SetWindowMinimumSize);
79+ CONSOLE_DECLARE_SYMBOL (SDL_ShowCursor);
7980CONSOLE_DECLARE_SYMBOL (SDL_ShowWindow);
8081CONSOLE_DECLARE_SYMBOL (SDL_StartTextInput);
8182CONSOLE_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
16541656class Prompt : public Widget {
16551657public:
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
19521947class 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