55{
56 int res = -2;
57 ssize_t CurrentActiveTextInput = 0;
58 bool running = true;
59
60 if (!_window || !_renderer)
61 return -2;
62 try
63 {
64 while (running)
65 {
66 if (!clear_window(_renderer))
67 throw;
68
69 if (!update_text())
70 throw;
71
72 if (!_buttons.update(_renderer))
73 throw;
74
75 SDL_Event event = {};
76 SDL_WaitEvent(&event);
77 switch (event.type)
78 {
79 case SDL_KEYDOWN:
80 switch (event.key.keysym.sym)
81 {
82 case SDLK_UP:
83 case SDLK_BACKSPACE:
84 if (CurrentActiveTextInput > 0)
85 CurrentActiveTextInput--;
86 else
87 CurrentActiveTextInput =
88 WINPR_ASSERTING_INT_CAST(ssize_t, _list.size() - 1);
89 break;
90 case SDLK_DOWN:
91 case SDLK_TAB:
92 {
93 if (CurrentActiveTextInput < 0)
94 CurrentActiveTextInput = 0;
95 else
96 CurrentActiveTextInput++;
97
98 const auto s = _list.size();
99 if (s <= 0)
100 CurrentActiveTextInput = 0;
101 else
102 CurrentActiveTextInput =
103 CurrentActiveTextInput % WINPR_ASSERTING_INT_CAST(ssize_t, s);
104 }
105 break;
106 case SDLK_RETURN:
107 case SDLK_RETURN2:
108 case SDLK_KP_ENTER:
109 running = false;
110 res = WINPR_ASSERTING_INT_CAST(int, CurrentActiveTextInput);
111 break;
112 case SDLK_ESCAPE:
113 running = false;
114 res = INPUT_BUTTON_CANCEL;
115 break;
116 default:
117 break;
118 }
119 break;
120 case SDL_MOUSEMOTION:
121 {
122 ssize_t TextInputIndex = get_index(event.button);
123 reset_mouseover();
124 if (TextInputIndex >= 0)
125 {
126 auto& cur = _list[WINPR_ASSERTING_INT_CAST(size_t, TextInputIndex)];
127 if (!cur.set_mouseover(_renderer, true))
128 throw;
129 }
130
131 _buttons.set_mouseover(event.button.x, event.button.y);
132 }
133 break;
134 case SDL_MOUSEBUTTONDOWN:
135 {
136 auto button = _buttons.get_selected(event.button);
137 if (button)
138 {
139 running = false;
140 if (button->id() == INPUT_BUTTON_CANCEL)
141 res = INPUT_BUTTON_CANCEL;
142 else
143 res = static_cast<int>(CurrentActiveTextInput);
144 }
145 else
146 {
147 CurrentActiveTextInput = get_index(event.button);
148 }
149 }
150 break;
151 case SDL_QUIT:
152 res = INPUT_BUTTON_CANCEL;
153 running = false;
154 break;
155 default:
156 break;
157 }
158
159 reset_highlight();
160 if (CurrentActiveTextInput >= 0)
161 {
162 auto& cur = _list[WINPR_ASSERTING_INT_CAST(size_t, CurrentActiveTextInput)];
163 if (!cur.set_highlight(_renderer, true))
164 throw;
165 }
166
167 SDL_RenderPresent(_renderer);
168 }
169 }
170 catch (...)
171 {
172 return -1;
173 }
174 return res;
175}