Espruino:Примеры/Виджеты Bangle.js

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Виджеты Bangle.js[1]

Эта статья написана с расчётом на то, что вы уже прошли руководство «Разработка под Bangle.js» и примерно понимаете, с чего начать, а также уже, возможно, заглянули в руководство о создании собственного приложения.

Виджеты – это фрагменты кода, запущенные на фоне других приложений. Речь, например, об индикаторах заряда батареи, статуса Bluetooth-соединения и так далее. Обычно под информацию, рисуемую виджетами, отведены 24 пикселя сверху и снизу экрана Bangle.js.

Виджеты включаются не каждым приложением (для этого приложению нужно вызвать Bangle.loadWidgets() и Bangle.drawWidgets()), но они есть практически во всех приложениях для смарт-часов.

Как они работают?

Для загрузки виджетов используется функция Bangle.loadWidgets(), а аргументом в ней служат файлы, заканчивающиеся на «.widget.js». Эта функция добавляет виджеты в глобальную переменную WIDGETS.

Затем функция Bangle.drawWidgets(), используя данные в WIDGETS, задает расположение виджета на экране (tl/tr/bl/br) и его ширину, а потом рисует его.

Когда приложение-хост очищает экран, оно также должно снова вызвать функцию Bangle.drawWidgets().

Чтобы виджет показал обновлённые данные, он должен снова вызвать функцию draw(). Кроме того, если вам нужно изменить ширину виджета (например, добавить индикатор зарядки), вызовите Bangle.drawWidgets(), чтобы заново «уложить» на экране все виджеты и снова их нарисовать.

Как разрабатывать виджеты

Разработка виджетов очень похожа на разработку приложений и во многом даже проще её.

Вы можете разработать виджет и отдельно от приложения, и внутри него. Сначала давайте напишем отдельный виджет – его, если нужно, можно будет запустить прямо в эмуляторе. Код виджета можно найти в GitHub-репозитории Bangle.js по ссылке «apps/_example_widget».

Впишите в верхнюю часть этого кода WIDGETS = {};, а в нижнюю – Bangle.drawWidgets();.

В результате виджет будет выглядеть как-то так:

WIDGETS = {};

(() => {
  function draw() {
    g.reset(); // сбрасываем состояние экземпляра Graphics
               // к настройкам по умолчанию (цвет, шрифт и т.д.)
      // Пишем свой код:
    g.drawString("X", this.x, this.y);
  }

  // Пишем виджет:
  WIDGETS["mywidget"]={
    area:"tl", // tl (сверху слева), tr (сверху справа),
               // bl (снизу слева), br (снизу справа)
    width: 28, // Какой будет ширина виджета?
               // Вы можете поменять её здесь,
               // а потом снова вызвать Bangle.drawWidgets(),
               // чтобы изменения вступили в силу
    draw:draw  // Задаётся, чтобы нарисовать виджет
  };
})()

Bangle.drawWidgets();

Убедитесь, что в IDE задана загрузка в RAM (это вариант по умолчанию) – это задаётся в меню, которое открывается при нажатии на перевёрнутый треугольник под кнопкой загрузки.

Если загрузить этот виджет, в верхней левой части экрана появится буква «X». Поскольку углы Bangle.js закруглены, виджет будет отрисован не с координат (0,0), а чуть ближе к центральной оси.

Пример – отображение даты

Для примера давайте сделаем виджет, который будет показывать дату.

  • Поменяйте название виджета с mywidget на dayofweek
  • Поместите его где хотите – я решил поставить его на позиции tl (сверху слева)
  • Поменяйте ширину
  • Напишите собственную функцию draw() – мы будем показывать только месяц

Я также добавил функцию drawRect(), чтобы видеть границы, в которых нужно оставаться.

WIDGETS = {}; // только для тестирования

(() => {
  var width = 24; // ширина виджета

  function draw() {
    var date = new Date();
    g.reset(); // сбрасываем состояние экземпляра Graphics
               // к настройкам по умолчанию (цвет, шрифт и т.д.)
    g.setFontAlign(0,0); // центрируем текст    
    // Сверяемся с границами:
    g.drawRect(this.x, this.y, this.x+width-1, this.y+23);
    // Используем модуль «locale», чтобы задать
    // сокращённое обозначение месяца на корректном языке:
      var text = require("locale").month(date,1);
    g.setFont("6x8");
    g.drawString(text, this.x+width/2, this.y+12);
  }

  setInterval(function() {
    WIDGETS["date"].draw(WIDGETS["date"]);
  }, 10*60000); // обновляем каждые 10 минут

  // Добавляем виджет:
  WIDGETS["date"]={
    area:"tl",    // tl (сверху слева), tr (сверху справа),
                  // bl (снизу слева), br (снизу справа)
    width: width, // Какой будет ширина виджета?
                  // Вы можете поменять её здесь,
                  // а потом снова вызвать Bangle.drawWidgets(),
                  // чтобы изменения вступили в силу
    draw:draw     // Задаётся, чтобы нарисовать виджет 
  };
})()

Bangle.drawWidgets(); // только для тестирования

Теперь виджет должен выглядеть примерно так:

Теперь нам нужно задать обновление дня в месяце. Конечно, можно сделать поумнее и обновлять его сразу с наступлением нового дня, но в нашем примере мы просто будем обновлять виджет каждые 10 минут.

setInterval(function() {
  WIDGETS["date"].draw(WIDGETS["date"]);
}, 10*60000); // обновляем каждые 10 минут

Наконец, мы можем добавить сверху иконку, чтобы показать, что значит этот текст. Итак:

  • Масштабируем, обрезаем и инвертируем чёрный и белый цвета
  • Открываем конвертер и загружаем туда наше изображение
  • Задаём настройки. В пункте Transparency галочка стоять не должна. Также выберите в меню Colours пункт 2 bit grayscale, а в меню Output as – пункт Image String
  • В результате у вас получится что-то вроде var img = E.toArrayBuffer(atob("DA0CDQBwv//+////////1VVX0AAH0AAH0AAH0AAH0AAH0AAH1VVXv//+"))

Теперь мы можем нарисовать изображение при помощи кода вроде вот этого:

g.drawImage(atob("DA0CDQBwv//+////////1VVX0AAH0AAH0AAH0AAH0AAH0AAH1VVXv//+"), this.x+6, this.y)

Одна картинка нарисована, и теперь мы можем нарисовать внутри неё текущий день месяца. В результате код будет выглядеть примерно вот так:

WIDGETS = {}; // только для тестирования

(() => {
  var width = 24; // ширина виджета

  function draw() {
    var date = new Date();
    g.reset(); // сбрасываем состояние экземпляра Graphics
               // к настройкам по умолчанию (цвет, шрифт и т.д.)
    g.setFontAlign(0,0); // центрируем текст  
    // Сверяемся с границами:  
    //g.drawRect(this.x, this.y, this.x+width-1, this.y+23);
    // Рисуем иконку:    g.drawImage(atob("DA0CDQBwv//+////////1VVX0AAH0AAH0AAH0AAH0AAH0AAH1VVXv//+"), this.x+6, this.y)
    // Рисуем маленькую цифру, обозначающую день месяца:    
    g.drawString(date.getDate(), this.x+width/2, this.y+9);
    // Используем модуль «locale», чтобы задать
    // сокращённое обозначение месяца на корректном языке:
      var text = require("locale").month(date,1);
    g.setFont("6x8");
    g.drawString(text, this.x+width/2, this.y+19);
  }

  setInterval(function() {
    WIDGETS["date"].draw(WIDGETS["date"]);
  }, 10*60000); // обновляем каждые 10 минут

  // Добавляем виджет:
  WIDGETS["date"]={
    area:"tl",    // tl (сверху слева), tr (сверху справа),
                  // bl (снизу слева), br (снизу справа)
    width: width, // Какой будет ширина виджета?
                  // Вы можете поменять её здесь,
                  // а потом снова вызвать Bangle.drawWidgets(),
                  // чтобы изменения вступили в силу
    draw:draw     // Задаётся, чтобы нарисовать виджет
  };
})()

Bangle.drawWidgets(); // только для тестирования

В итоге виджет будет выглядеть примерно вот так:

Виджет внутри приложения

Примечание: Этот код в эмуляторе работать не будет.

Чтобы использовать виджет внутри приложения, нужно поменять некоторые настройки IDE. Мы сохраним виджет в файл в Storage, но потом запустим приложение (циферблат), а не сам виджет.

  • Кликните на перевёрнутый треугольник под кнопкой загрузки
  • Кликните на Storage
  • Кликните на New File
  • Введите название файла «date.wid.js»
  • Зайдите в настройки (иконка с шестерёнкой справа вверху), затем в Communications и задайте в пункте Load after saving настройку Load default application
  • Удалите из кода строчки WIDGETS = {}; (вверху) и Bangle.drawWidgets(); (внизу)

Теперь кликните на кнопку загрузки – теперь ваш виджет будет показан вместе с приложением-циферблатом и другими виджетами.

Кроме того, теперь наш виджет установлен на часы и им можно пользоваться даже без IDE.

Добавление виджета в загрузчик приложений

Возможно, вы уже читали статью «Добавление приложения в загрузчик приложений Bangle.js».

Добавление виджета осуществляется похожим образом:

  • Придумайте для своего виджета короткое название (без пробелов), не повторяющее других названий из этого списка
  • Скопируйте виджет-пример в «apps/вашвиджет»
  • Сохраните код виджета в «apps/вашвиджет/widget.js»
  • Найдите иконку для загрузчика приложений и поместите её в «apps/вашвиджет/widget.png»
  • Откройте «apps/вашвиджет/add_to_apps.json», замените 7chname на вашвиджет (т.е. на название, которое вы придумали для своего виджета), добавьте дополнительную информацию о своём виджете, добавьте содержимое файла в «apps.json» в корневой директории репозитория BangleApps и удалите «apps/вашвиджет/add_to_apps.json»

Теперь вы можете загрузить этот виджет из своей версии загрузчика приложений и отправить запрос (pull request) на добавление этого виджета в главный загрузчик приложений Bangle.js.

См.также

Внешние ссылки