PIPKIT · Overlays Tools

Уведомления, popup, ошибки и скриншоты.

Здесь лежат overlays и screenshot subsystem из API.md в исходной разбивке по подпунктам.

16. Уведомления, toast, ошибки

16.1. Toast

ui.showToast()
    .text("Saved")    // основной текст toast; можно оставить пустым, если нужен только значок
    .icon(error)      // необязательная иконка слева
    .pos(top);        // `top` или `down`; по умолчанию используется `down`

Позиции toast:

  • top — появляется сверху
  • down — появляется снизу

Проверка активности:

bool active = ui.toastActive();    // `true`, пока toast еще анимируется или висит на экране

Поведение:

  • если не заданы и текст, и иконка, toast не показывается
  • toast сам показывается, держится на экране и затем скрывается с анимацией

16.2. Notification

ui.showNotification()
    .text("Settings", "Changes applied") // заголовок и основной текст карточки
    .button("OK")                        // подпись кнопки подтверждения
    .delay(0)                            // автозакрытие в секундах; `0` значит без таймера
    .type(Normal)                        // semantic-тип уведомления
    .icon(warning);                      // необязательная иконка; без нее библиотека берет visual от `type(...)`

Типы уведомления:

  • Normal
  • Warning
  • Error

Управление:

bool active = ui.notificationActive();

16.3. Popup menu

Самый обычный сценарий:

static const char *menuItems[] = {"Edit", "Rename", "Delete"};

auto button = ui.updateButton()
    .label("Open menu")
    .pos(center, 188)
    .size(180, 32)
    .baseColor(ui.rgb(0, 87, 250))
    .radius(10);

ui.showPopupMenu()
    .items(menuItems)                  // обычный массив строк
    .anchor(button)                    // привязка к fluent-компоненту; меню само откроется над ним или под ним
    .width(120)                        // ширина меню; если не задать, библиотека подберет сама
    .selected(0);                      // стартовый выделенный пункт; если не задавать, берется дефолт

Результат выбора:

if (ui.popupMenuHasResult())                      // говорит, что пользователь уже выбрал пункт
{
    int16_t picked = ui.popupMenuTakeResult();    // возвращает индекс выбранного пункта и сразу сбрасывает флаг результата
}

Что важно:

  • .selected(index) нужен только если хочешь вручную задать стартовый курсор
  • .anchor(component) берет прямоугольник fluent-компонента и открывает меню по центру над ним или под ним
  • если использовать короткий паттерн без popupMenuHasResult(), то popupMenuTakeResult() == -1 значит, что результата пока нет

Выбор пункта:

  • 2-button режим: удержание NEXT подтверждает текущий пункт; удержание PREV закрывает меню без выбора
  • 3-button режим: короткое нажатие SELECT подтверждает текущий пункт; удержание PREV закрывает меню без выбора

16.4. Ошибки

ui.showError()
    .message("Low battery")
    .code("0xLOWBAT")
    .type(Warning)
    .button("OK");

ui.showError()
    .message("LittleFS mount failed")
    .code("0xLFS")
    .type(Error)
    .button("Retry");

Управление:

ui.nextError();                                                                 // переключает на следующую ошибку
ui.prevError();                                                                 // переключает на предыдущую ошибку
ui.errorActive();                                                               // сообщает, активен ли сейчас error overlay
ui.setErrorButtonDown(btnOk.isDown());                                          // короткий совместимый wrapper для простого сценария с одной кнопкой
ui.setErrorButtonsDown(btnNext.isDown(), btnPrev.isDown(), btnCombo.isDown());  // полный input API для error overlay

Поведение:

  • если ошибок несколько, первой показывается последняя добавленная
  • Warning можно закрыть
  • Error не закрывается пользовательской кнопкой

17. Скриншоты

17.1. Build-time флаги

  • PIPGUI_SCREENSHOTS
  • 1 по умолчанию
  • 0 полностью выключает систему скриншотов
  • PIPGUI_SCREENSHOT_MODE
  • 1 — serial capture
  • 2 — запись в LittleFS

Для режима 2 нужен LittleFS. Библиотека сама создаёт /PipKit/, /PipKit/screenshots/ и /PipKit/thumbnails/.

17.2. Serial capture

Скрипт на ПК:

python tools/screenshots/bin/capture.py
  • при запуске без параметров tool покажет меню: port, baud и output directory

Быстрый прямой запуск тоже можно:

python tools/screenshots/bin/capture.py --port COM9 --baud 1000000

17.3. Flash (LittleFS)

В режиме 2 сохраняются:

  • full screenshot: /PipKit/screenshots/pscr_00000001.pscr
  • thumbnail: /PipKit/thumbnails/<WxH>/pscr_00000001.pscr

Галерея показывает новые сверху.

17.4. Запуск скриншота

bool started = ui.startScreenshot();
  • startScreenshot() запускает захват асинхронно
  • если snapshot-buffer не удалось выделить, функция вернёт false
  • built-in shortcut фиксированный: удержание Next + Prev 300 ms

17.5. Галерея миниатюр

Отрисовка галереи:

ui.drawScreenshot()
    .pos(8, 28)     // x, y области галереи
    .size(224, 284) // w, h области галереи
    .grid(3, 5)     // cols, rows видимой сетки
    .padding(8);    // отступ между ячейками в самой сетке

Что делает drawScreenshot():

  • рисует текущую screenshot gallery в заданной области
  • сам берёт entries из внутреннего screenshot store
  • сам вычисляет размер миниатюр и вместимость галереи из size(...), grid(...) и padding(...)
  • в serial mode просто покажет пустое состояние, если gallery backend не используется

Дополнительно:

uint8_t count = ui.screenshotCount();

Code copied