32 #pragma GCC optimize ("O2") 43 : m_vga16Ctrl(nullptr),
44 m_backgroundColor(
RGB888(64, 64, 64))
55 void InputBox::begin(
char const * modeline,
int viewPortWidth,
int viewPortHeight)
59 m_dispCtrl = m_vga16Ctrl;
61 m_vga16Ctrl->setResolution(modeline ? modeline :
VESA_640x480_75Hz, viewPortWidth, viewPortHeight);
64 if (!PS2Controller::initialized())
71 m_dispCtrl = displayController;
80 m_vga16Ctrl =
nullptr;
85 InputResult InputBox::textInput(
char const * titleText,
char const * labelText,
char * inOutString,
int maxLength,
char const * buttonCancelText,
char const * buttonOKText,
bool passwordMode)
88 app.backgroundColor = m_backgroundColor;
89 app.titleText = titleText;
90 app.labelText = labelText;
91 app.inOutString = inOutString;
92 app.maxLength = maxLength;
93 app.buttonCancelText = buttonCancelText;
94 app.buttonOKText = buttonOKText;
95 app.passwordMode = passwordMode;
107 app.backgroundColor = m_backgroundColor;
108 app.titleText = titleText;
109 app.messageText = messageText;
110 app.buttonCancelText = buttonCancelText;
111 app.buttonOKText = buttonOKText;
124 va_start(ap, format);
125 int size = vsnprintf(
nullptr, 0, format, ap) + 1;
128 va_start(ap, format);
130 vsnprintf(buf, size, format, ap);
131 r =
message(titleText, buf, buttonCancelText, buttonOKText);
138 int InputBox::select(
char const * titleText,
char const * messageText,
char const * itemsText,
char separator,
char const * buttonCancelText,
char const * buttonOKText,
int OKAfter)
141 app.backgroundColor = m_backgroundColor;
142 app.titleText = titleText;
143 app.messageText = messageText;
144 app.items = itemsText;
145 app.separator = separator;
146 app.itemsList =
nullptr;
147 app.buttonCancelText = buttonCancelText;
148 app.buttonOKText = buttonOKText;
149 app.menuMode =
false;
150 app.autoOK = OKAfter;
154 return app.outSelected;
158 InputResult InputBox::select(
char const * titleText,
char const * messageText, StringList * items,
char const * buttonCancelText,
char const * buttonOKText,
int OKAfter)
161 app.backgroundColor = m_backgroundColor;
162 app.titleText = titleText;
163 app.messageText = messageText;
166 app.itemsList = items;
167 app.buttonCancelText = buttonCancelText;
168 app.buttonOKText = buttonOKText;
169 app.menuMode =
false;
170 app.autoOK = OKAfter;
178 int InputBox::menu(
char const * titleText,
char const * messageText,
char const * itemsText,
char separator)
181 app.backgroundColor = m_backgroundColor;
182 app.titleText = titleText;
183 app.messageText = messageText;
184 app.items = itemsText;
185 app.separator = separator;
186 app.itemsList =
nullptr;
187 app.buttonCancelText =
nullptr;
188 app.buttonOKText =
nullptr;
194 return app.outSelected;
198 int InputBox::menu(
char const * titleText,
char const * messageText, StringList * items)
201 app.backgroundColor = m_backgroundColor;
202 app.titleText = titleText;
203 app.messageText = messageText;
206 app.itemsList = items;
207 app.buttonCancelText =
nullptr;
208 app.buttonOKText =
nullptr;
214 return items->getFirstSelected();
218 InputResult InputBox::progressBoxImpl(ProgressApp & app,
char const * titleText,
char const * buttonCancelText,
bool hasProgressBar,
int width)
220 app.backgroundColor = m_backgroundColor;
221 app.titleText = titleText;
222 app.buttonCancelText = buttonCancelText;
223 app.buttonOKText =
nullptr;
224 app.hasProgressBar = hasProgressBar;
239 void InputApp::init()
243 rootWindow()->frameStyle().backgroundColor = backgroundColor;
246 const int titleHeight = titleText && strlen(titleText) ? font->height : 0;
247 const bool buttonsExist = buttonCancelText || buttonOKText;
248 const int buttonCancelExtent = buttonCancelText ? canvas()->textExtent(font, buttonCancelText) + 10 : 0;
249 const int buttonOKExtent = buttonOKText ? canvas()->textExtent(font, buttonOKText) + 10 : 0;
250 const int buttonsWidth = imax(imax(buttonCancelExtent, buttonOKExtent), 40);
251 const int totButtons = (buttonCancelExtent ? 1 : 0) + (buttonOKExtent ? 1 : 0);
252 const int buttonsHeight = buttonsExist ? font->height + 6 : 0;
253 constexpr
int buttonsSpace = 10;
255 requiredWidth = buttonsWidth * totButtons + (2 * buttonsSpace) * totButtons;
256 requiredHeight = buttonsHeight + titleHeight + font->height * 2 + 5;
260 requiredWidth = imin(requiredWidth, canvas()->getWidth());
262 mainFrame =
new uiFrame(rootWindow(), titleText, UIWINDOW_PARENTCENTER, Size(requiredWidth, requiredHeight),
false);
263 mainFrame->frameProps().resizeable =
false;
264 mainFrame->frameProps().hasMaximizeButton =
false;
265 mainFrame->frameProps().hasMinimizeButton =
false;
266 mainFrame->frameProps().hasCloseButton =
false;
267 mainFrame->onKeyUp = [&](uiKeyEventInfo key) {
277 autoOKLabel =
nullptr;
279 uiWindow * controlToFocus =
nullptr;
285 int panelHeight = buttonsHeight + 10;
286 panel =
new uiPanel(mainFrame, Point(mainFrame->clientPos().X - 1, mainFrame->clientPos().Y + mainFrame->clientSize().height - panelHeight), Size(mainFrame->clientSize().width + 2, panelHeight));
287 panel->windowStyle().borderColor = RGB888(128, 128, 128);
288 panel->panelStyle().backgroundColor = mainFrame->frameStyle().backgroundColor;
292 int y = (panelHeight - buttonsHeight) / 2;
293 int x = panel->clientSize().width - buttonsWidth * totButtons - buttonsSpace * totButtons;
295 if (buttonCancelText) {
296 auto buttonCancel =
new uiButton(panel, buttonCancelText, Point(x, y), Size(buttonsWidth, buttonsHeight));
297 buttonCancel->onClick = [&]() {
301 x += buttonsWidth + buttonsSpace;
302 controlToFocus = buttonCancel;
306 auto buttonOK =
new uiButton(panel, buttonOKText, Point(x, y), Size(buttonsWidth, buttonsHeight));
307 buttonOK->onClick = [&]() {
311 controlToFocus = buttonOK;
315 autoOKLabel =
new uiLabel(panel,
"", Point(4, y + 2));
317 onTimer = [&](uiTimerHandle t) {
318 int now = esp_timer_get_time() / 1000;
319 if (lastUserActionTime() + 900 > now) {
321 destroyWindow(autoOKLabel);
330 autoOKLabel->setTextFmt(
"%d", autoOK);
332 setTimer(
this, 1000);
342 showWindow(mainFrame,
true);
343 setActiveWindow(mainFrame);
345 setFocusedWindow(controlToFocus);
354 void TextInputApp::calcRequiredSize()
356 labelExtent = canvas()->textExtent(font, labelText);
357 editExtent = imin(maxLength * canvas()->textExtent(font,
"M"), rootWindow()->clientSize().
width / 2 - labelExtent);
358 requiredWidth = imax(requiredWidth, editExtent + labelExtent + 10);
359 requiredHeight += font->height;
363 void TextInputApp::addControls()
365 const Point clientPos = mainFrame->clientPos();
367 int x = clientPos.X + 4;
368 int y = clientPos.Y + 8;
370 new uiLabel(mainFrame, labelText, Point(x, y));
372 edit =
new uiTextEdit(mainFrame, inOutString, Point(x + labelExtent + 5, y - 4), Size(editExtent - 15, font->height + 6));
373 edit->textEditProps().passwordMode = passwordMode;
375 mainFrame->onShow = [&]() { setFocusedWindow(edit); };
379 void TextInputApp::finalize()
382 int len = imin(maxLength, strlen(edit->text()));
383 memcpy(inOutString, edit->text(), len);
384 inOutString[len] = 0;
395 void MessageApp::calcRequiredSize()
397 messageExtent = canvas()->textExtent(font, messageText);
398 requiredWidth = imax(requiredWidth, messageExtent + 20);
399 requiredHeight += font->height;
403 void MessageApp::addControls()
405 int x = mainFrame->clientPos().X + (mainFrame->clientSize().width - messageExtent) / 2;
406 int y = mainFrame->clientPos().Y + 6;
408 new uiLabel(mainFrame, messageText, Point(x, y));
412 void MessageApp::finalize()
423 void SelectApp::calcRequiredSize()
425 auto messageExtent = canvas()->textExtent(font, messageText);
426 requiredWidth = imax(requiredWidth, messageExtent + 20);
429 requiredHeight += font->height;
433 auto itemsCount = countItems(&maxLength);
434 listBoxHeight = (font->height + 4) * itemsCount;
435 int requiredHeightUnCut = requiredHeight + listBoxHeight;
436 requiredHeight = imin(requiredHeightUnCut, canvas()->getHeight());
437 requiredWidth = imax(requiredWidth, maxLength * canvas()->textExtent(font,
"M"));
438 if (requiredHeightUnCut > requiredHeight)
439 listBoxHeight -= requiredHeightUnCut - requiredHeight;
443 void SelectApp::addControls()
445 int x = mainFrame->clientPos().X + 4;
446 int y = mainFrame->clientPos().Y + 6;
448 new uiLabel(mainFrame, messageText, Point(x, y));
450 y += font->height + 6;
452 listBox =
new uiListBox(mainFrame, Point(x, y), Size(mainFrame->clientSize().width - 10, listBoxHeight));
454 listBox->items().appendSepList(items, separator);
456 listBox->items().copyFrom(*itemsList);
457 listBox->items().copySelectionMapFrom(*itemsList);
460 listBox->listBoxProps().allowMultiSelect =
false;
461 listBox->listBoxProps().selectOnMouseOver =
true;
462 listBox->onClick = [&]() {
468 mainFrame->onShow = [&]() { setFocusedWindow(listBox); };
472 void SelectApp::finalize()
477 itemsList->copySelectionMapFrom(listBox->items());
483 int SelectApp::countItems(
size_t * maxLength)
488 char const * start = items;
490 auto end = strchr(start, separator);
492 end = strchr(start, 0);
493 int len = end - start;
494 *maxLength = imax(*maxLength, len);
495 start += len + (*end == 0 ? 0 : 1);
498 }
else if (itemsList) {
499 for (
int i = 0; i < itemsList->count(); ++i)
500 *maxLength = imax(*maxLength, strlen(itemsList->get(i)));
501 count += itemsList->count();
512 void ProgressApp::calcRequiredSize()
514 requiredWidth = imax(requiredWidth,
width);
515 requiredHeight += font->height + (hasProgressBar ? progressBarHeight : 0);
519 void ProgressApp::addControls()
521 int x = mainFrame->clientPos().X + 4;
522 int y = mainFrame->clientPos().Y + 6;
524 label =
new uiLabel(mainFrame,
"", Point(x, y));
526 if (hasProgressBar) {
527 y += font->height + 4;
529 progressBar =
new uiProgressBar(mainFrame, Point(x, y), Size(mainFrame->clientSize().width - 8, font->height));
532 mainFrame->onShow = [&]() {
541 void ProgressApp::finalize()
547 bool ProgressApp::update(
int percentage,
char const * format, ...)
550 progressBar->setPercentage(percentage);
553 va_start(ap, format);
554 int size = vsnprintf(
nullptr, 0, format, ap) + 1;
557 va_start(ap, format);
559 vsnprintf(buf, size, format, ap);
Represents a 24 bit RGB color.
Represents the base abstract class for bitmapped display controllers.
InputResult
Result of InputBox dialogs helper class.
Represents the VGA 16 colors bitmapped controller.
#define VESA_640x480_75Hz
static void begin(gpio_num_t port0_clkGPIO, gpio_num_t port0_datGPIO, gpio_num_t port1_clkGPIO=GPIO_UNUSED, gpio_num_t port1_datGPIO=GPIO_UNUSED)
Initializes PS2 device controller.