Обработка кликов - GyverLibs/GyverPortal GitHub Wiki

Библиотека позволяет обработать клик по компоненту (изменение значения) и сразу получить его новое значение. Удобно в сценариях, когда нужна реакция на единичное действие на странице: клик по кнопке, изменение положения слайдера, переключение галочки и так далее.

  • Для компонентов, в которых есть выбор (цвет, дата, выпадающий список) - значение будет отправлено в программу при изменении. При выборе того же значения данные переданы не будут
  • Для компонентов ввода (текст, цифры) - значение будет отправлено в программу:
    • При изменении и последующем клике в любом месте страницы кроме самого компонента (с поля ввода снимется "фокус")
    • При нажатии на клавишу Enter, когда компонент находится "в фокусе"

Общий сигнал

  • Обработка кликов происходит в подключенной функции-обработчике действия.
  • При клике или изменении значения любого активного компонента на странице (см. таблицу в документации) функция click() вернёт true.
  • Дальнейшую обработку действий рекомендуется поместить в условие, чтобы микроконтроллер не занимался лишней работой:
void action() {
  if (portal.click()) {
    // опрос кликов
    Serial.println(portal.clickName());
  }
}

При помощи clickName() можно узнать имя кликнутого компонента

Поиск компонента

Для определения факта клика по конкретному компоненту нужно передать в click() его имя:

void action() {
  if (portal.click()) {
    if (portal.click("btn")) Serial.println("btn click");
  }
}

Нажатие и отпускание

Кнопка (компоненты BUTTON и BUTTON_MINI) также передают нажатие и отпускание, что позволяет сделать в программе логику "удерживаемой" кнопки:

  • clickDown(имя) - вернёт true, если кнопка была нажата
  • clickUp(имя) - вернёт true, если кнопка была отпущена

Примечания

  • Работает только на ПК, со смартфона удержание обрабатывается иначе
  • Если отпустить курсор вне кнопки - сигнал на отпускание не будет передан!

См. пример btnHold

Парсинг значений

Вместе с сигналом клика библиотека передаёт текущее значение компонента (у всех кроме кнопки). Получить его можно несколькими способами:

В условии

Сначала определяем кликнутый компонент, а затем получаем данные из текущего запроса:

void action() {
  if (portal.click("txt")) Serial.println(portal.getString());
}

В библиотеке предусмотрены парсеры для всех компонентов и типов данных:

String getString(); // получить String строку с компонента
int getInt();       // получить число с компонента
float getFloat();   // получить float с компонента
bool getBool();     // получить состояние чекбокса
GPdate getDate();   // получить дату с компонента
GPtime getTime();   // получить время с компонента
GPcolor getColor(); // получить цвет с компонента

Например перепишем в переменную:

void action() {
  if (portal.click("num")) val = portal.getInt();
}

Автоматически

Есть более удобный вариант для передачи значений в переменные, вот такой набор парсеров:

bool clickStr(имя, char* t);           // переписать в char массив
bool clickStr(имя, char* t, int len);  // + размер массива
bool clickString(имя, String& t);
bool clickInt(имя, int& t);
bool clickFloat(имя, float& t);
bool clickBool(имя, bool& t);
bool clickDate(имя, GPdate& t);
bool clickTime(имя, GPtime& t);
bool clickColor(имя, GPcolor& t);

Данные парсерсы переписывают приходящее значение в указанную переменную и возвращают true при этом событии:

float fval;
String str;

void action() {
  portal.clickFloat("num", fval);   // перепишет при клике
  
  if (portal.clickString("txt", str)) Serial.println(str);
}

См. пример actionClick

Парсер clickStr

Данный парсер переписывает данные в виде текста в массив char. Размер массива должен быть на 1 больше максимальной длины текста, который там хранится (для \0 символа). В clickStr можно передать реальный размер массива. Если текст будет слишком большим - он не запишется в массив, что позволит избежать критической ошибки и зависания программы.

char str[10];

void action() {
  portal.clickStr("txt", str, 10);
}

Подключение кнопки на другой компонент

Кнопку (BUTTON, BUTTON_MINI) можно "подключить" к другому компоненту: при клике по кнопке будет вызван сигнал click с именем кнопки и данными с указанного компонента. Для подключения нужно указать имя компонента третьим аргументом при добавлении кнопки:

GP.BUTTON(имя кнопки, текст кнопки, имя компонента);
GP.BUTTON_MINI(имя кнопки, текст кнопки, имя компонента);

Пример, клик по кнопке отправляет текст из поля txt:

GP.TEXT("txt", "");
GP.BUTTON_MINI("btn", "Send", "txt");

"Массив" компонентов

Библиотека позволяет создавать и обрабатывать компоненты как "массив", то есть назначить одно и то же имя нескольким компонентам и обращаться к ним по индексу. Синтаксис имени такой: name/sub1/sub2..., то есть вложенных имён может быть сколько угодно, разделитель - /. Создадим "массив" слайдеров с именами sld/номер:

for (int i = 0; i < 5; i++) {
  GP.SLIDER(String("sld/") + i);
}

Теперь для поиска сигнала с такого массива нужно использовать clickSub(имя), а внутри условия с ним - clickNameSub(индекс) для получения саб-имени. Из примера выше clickNameSub(0) вернёт sld, а clickNameSub(1) - строку с номером слайдера после /. Получить значение можно так же через getX функции:

if (portal.clickSub("sld")) {   // начинается с sld
  Serial.print("Slider ");
  Serial.print(portal.clickNameSub(1)); // получаем цифру
  Serial.print(": ");
  Serial.println(portal.getInt());
}

См. пример dynamicComponents