PIPKIT · Drawing

Текст, шрифты, иконки, фигуры, градиенты и эффекты.

Здесь собран исходный draw API из API.md без упрощения: типографика, иконки, фигуры, градиенты и эффекты.

7. Текст, шрифты и иконки

7.1. Встроенные шрифты

Текущий шрифт настраивается отдельными методами:

ui.setFont(WixMadeForDisplay);   // выбирает семейство шрифта
ui.setFontSize(18);              // задаёт текущий размер в пикселях

В библиотеке сейчас есть два встроенных семейства:

  • WixMadeForDisplay
  • KronaOne

Для веса можно передавать либо число, либо готовый токен:

ui.setFontWeight(450);        // обычно это диапазон `100..900`
ui.setFontWeight(Semibold);
  • Thin
  • Light
  • Regular
  • Medium
  • Semibold
  • Bold
  • Black

Текущее состояние тоже можно читать:

ui.fontId();      // текущий FontId
ui.fontSize();    // текущий размер шрифта
ui.fontWeight();  // текущая толщина шрифта

7.2. Текстовые стили

ui.setTextStyle(H1);

setTextStyle(...) быстро выставляет готовый пресет под тип текста.

Доступные стили:

  • H1 - крупный заголовок
  • H2 - подзаголовок или вторичный заголовок
  • Body - основной текст интерфейса
  • Caption - мелкие подписи и пояснения

7.3. Обычный текст

ui.drawText()
    .pos(center, 32)                   // точка привязки текста
    .font(WixMadeForDisplay, 18)       // конкретный шрифт, размер и насыщенность
    .weight(Semibold)                  // вес текста
    .text("Hello")                     // сама строка
    .color(ui.rgb(255, 255, 255))      // цвет текста
    .bgColor(ui.rgb(0, 0, 0))          // фон под текстом
    .align(Center);                    // выравнивание относительно точки `pos(...)`

drawText() рисует строку сразу в текущий кадр.

Если текст обновляется на одном и том же месте, используйте updateText():

ui.updateText()
    .pos(center, 32)
    .text("Updated")
    .color(ui.rgb(255, 255, 255))
    .align(Center);
  • drawText() рисует текст как есть
  • updateText() сначала очищает прошлую область и потом рисует новое значение на том же месте

7.4. Бегущая строка и многоточие

ui.drawTextMarquee()
    .pos(20, 80)                                  // точка привязки строки
    .width(140)                                   // ширина области, внутри которой идёт прокрутка
    .font(WixMadeForDisplay, 18)                  // конкретный шрифт и его размер
    .weight(Semibold)                             // насыщенность начертания
    .text("Very long text that does not fit")     // сама строка
    .color(ui.rgb(255, 255, 255))                 // цвет текста
    .speed(30)                                    // скорость движения в пикселях в секунду
    .holdStart(700)                               // пауза перед началом движения
    .phaseStart(0)                                // стартовая фаза, если нужна синхронизация
    .align(Left);                                 // выравнивание строки внутри заданной ширины

drawTextMarquee() нужен для длинной строки, которая должна прокручиваться внутри ограниченной ширины.

ui.drawTextEllipsized()
    .pos(20, 110)                                 // точка привязки строки
    .width(140)                                   // ширина области, в которую текст должен уместиться
    .font(WixMadeForDisplay, 18)                  // конкретный шрифт и его размер
    .weight(Semibold)                             // насыщенность начертания
    .text("Very long text that does not fit")     // сама строка
    .color(ui.rgb(255, 255, 255));                // цвет текста

drawTextEllipsized() обрезает строку по width(...) и добавляет многоточие

7.5. Иконки

Обычные иконки берутся из набора IconId

ui.drawIcon()
    .pos(20, 20)                      // позиция иконки
    .size(18)                         // итоговый размер в пикселях
    .icon(warning)                    // конкретный `IconId`
    .color(ui.rgb(255, 255, 255))     // основной цвет слоя
    .bgColor(ui.rgb(0, 0, 0));        // фон под иконкой

Отдельного updateIcon() нет.

Если иконка многослойная, слои можно рисовать отдельно разными цветами:

ui.drawIcon()
    .pos(200, 10)
    .size(18)
    .icon(battery_l0)
    .color(ui.rgb(255, 255, 255));

ui.drawIcon()
    .pos(200, 10)
    .size(18)
    .icon(battery_l1)
    .color(ui.rgb(0, 200, 120));

Для animated icons используются отдельные runtime-вызовы.

Обычная отрисовка:

ui.drawAnimIcon()
    .pos(92, 120)
    .size(56)
    .icon(setting_anim)
    .color(ui.rgb(235, 235, 235));

drawAnimIcon() рисует анимированную иконку как есть

Локальное обновление поверх известного фона:

ui.updateAnimIcon()
    .pos(92, 120)
    .size(56)
    .icon(setting_anim)
    .color(ui.rgb(235, 235, 235))
    .bgColor(ui.rgb(10, 10, 10));

updateAnimIcon() сначала очищает область через bgColor, потом рисует новый кадр

Создание иконок из sources

Чтобы добавить свою иконку:

  1. положить source-файл в tools/icons/sources/
  2. пересобрать проект — генератор сам обновит готовые файлы в lib/PipKit/PipGUI/Graphics/Text/Icons/
  3. использовать иконку по имени файла

Пример:

  • файл tools/icons/sources/checkmark.svg
  • в коде: .icon(checkmark)

Что важно:

  • генератор читает и .svg, и .json рекурсивно
  • файлы могут лежать как прямо в корне sources, так и в любых подпапках
  • имя для C++ генерируется из относительного пути, так что вложенные папки тоже поддерживаются

Что появится в коде:

  • для обычной однослойной иконки из name.svg появляется alias name
  • для многослойной иконки появляются alias вида name_l0, name_l1, name_l2
  • дополнительно экспортируются и enum-константы IconName, IconNameL0, IconNameL1 и т.д.
  • для анимированной иконки из name.json появляется alias name_anim

Если в имени файла есть -, пробелы или другие неподходящие символы, генератор сам приводит имя к валидному C++-идентификатору через _.

  • .svg идёт в обычный static PSDF pipeline.
  • .json идёт в animated PSDF pipeline.

8. Фигуры

ui.drawRect()
    .pos(20, 40)
    .size(100, 40)
    .radius(10)
    .fill(ui.rgb(0, 120, 255))
    .border(1, ui.rgb(255, 255, 255));

Что важно:

  • fill(color565) — задаёт заливку; если не вызывать, фигура остаётся без заливки
  • border(widthPx, color565) — задаёт контур; если не вызывать, контура не будет
  • fill(...) и border(...) можно использовать вместе или по отдельности

8.1 Линия

ui.drawLine()
    .from(20, 20)                      // начало линии
    .to(140, 60)                       // конец линии
    .thickness(2)                      // толщина линии; по умолчанию `1`
    .color(ui.rgb(255, 255, 255))      // цвет линии

8.2 Прямоугольник

ui.drawRect()
    .pos(20, 40)                          // левый верхний угол прямоугольника
    .size(100, 40)                        // ширина и высота
    .radius(10)                           // один радиус для всех углов
    // .radius(10, 14, 18, 22)            // или отдельные радиусы: tl, tr, br, bl
    .fill(ui.rgb(0, 120, 255))            // цвет заливки
    .border(1, ui.rgb(255, 255, 255))     // толщина и цвет контура

8.3 Круг

ui.drawCircle()
    .pos(50, 50)                          // центр круга
    .radius(18)                           // радиус
    .fill(ui.rgb(0, 87, 250))             // цвет заливки
    .border(1, ui.rgb(255, 255, 255))     // толщина и цвет контура

8.4 Эллипс

ui.drawEllipse()
    .pos(120, 50)                         // центр эллипса
    .radiusX(28)                          // горизонтальная полуось
    .radiusY(16)                          // вертикальная полуось
    .fill(ui.rgb(255, 0, 72))             // цвет заливки
    .border(1, ui.rgb(255, 255, 255))     // толщина и цвет контура

8.5 Треугольник

ui.drawTriangle()
    .point0(40, 120)                      // первая вершина
    .point1(70, 80)                       // вторая вершина
    .point2(100, 120)                     // третья вершина
    // .radius(8)                         // опционально: скругление углов
    .fill(ui.rgb(0, 200, 120))            // цвет заливки
    .border(1, ui.rgb(255, 255, 255))     // толщина и цвет контура

8.6 Дуга

ui.drawArc()
    .pos(100, 80)                     // центр дуги
    .radius(28)                       // внешний радиус
    .thickness(6)                     // толщина; по умолчанию 1
    .start(-90.0f)                    // начальный угол в градусах
    .end(90.0f)                       // конечный угол в градусах
    .color(ui.rgb(80, 255, 120))      // цвет дуги

У дуги концы всегда скруглённые, а диапазон 0..360 рисует полный круг.

8.7 Сквиркль

ui.drawSquircleRect()
    .pos(54, 134)                         // левый верхний угол области
    .size(52, 52)                         // ширина и высота
    .radius(26)                           // один радиус для всех углов
    // .radius(18, 22, 26, 30)            // или отдельные радиусы: tl, tr, br, bl
    .fill(ui.rgb(255, 128, 0))            // цвет заливки
    .border(1, ui.rgb(255, 255, 255))     // толщина и цвет контура

9. Градиенты

У всех градиентов pos(...) и size(...) задают прямоугольную область рисования.

9.1. Вертикальный

ui.gradientVertical()
    .pos(20, 20)
    .size(120, 40)
    .TColor(ui.rgb(255, 0, 72))
    .BColor(ui.rgb(0, 87, 250))
  • цвет плавно меняется сверху вниз

9.2. Горизонтальный

ui.gradientHorizontal()
    .pos(20, 70)
    .size(120, 40)
    .LColor(ui.rgb(255, 128, 0))
    .RColor(ui.rgb(80, 255, 120))
  • цвет плавно меняется слева направо

9.3. Диагональный

ui.gradientDiagonal()
    .pos(20, 170)
    .size(120, 40)
    .TLColor(ui.rgb(255, 255, 255))
    .BRColor(ui.rgb(30, 30, 30))
  • плавный переход по диагонали от верхнего левого к нижнему правому углу

9.4. 4 угла

ui.gradientCorners()
    .pos(20, 120)
    .size(120, 40)
    .TLColor(ui.rgb(255, 0, 72))
    .TRColor(ui.rgb(0, 87, 250))
    .BLColor(ui.rgb(80, 255, 120))
    .BRColor(ui.rgb(255, 128, 0))
  • каждая вершина прямоугольника получает свой цвет, внутри идёт двунаправленная интерполяция между четырьмя углами

9.5. Радиальный

ui.gradientRadial()
    .pos(20, 220)
    .size(120, 60)
    .center(80, 250)
    .radius(40)
    .innerColor(ui.rgb(255, 255, 255))
    .outerColor(ui.rgb(0, 87, 250))
  • center(...) задаёт центр градиента в координатах экрана
  • radius(...) задаёт радиус перехода
  • innerColor(...) и outerColor(...) задают цвета в центре и на периферии

10. Эффекты

10.1. Blur

ui.drawBlur()
    .pos(0, 180)                  // левый верхний угол blur-области
    .size(240, 40)                // ширина и высота области
    .radius(10)                   // сила blur; чем больше, тем мягче и тяжелее эффект
    .direction(TopDown)           // если указать, material пойдёт по этому направлению
    .material(160, -1)            // сила material и его цвет; -1 = цвет фона библиотеки

Для обновления части экрана:

ui.updateBlur()
    .pos(0, 180)                  // та же область, которую нужно перерисовать
    .size(240, 40)                // тот же размер blur-региона
    .radius(10)                   // тот же blur-радиус
    .direction(TopDown)           // то же направление материала
    .material(160, -1)            // те же параметры material

updateBlur() нужен для in-place перерисовки той же blur-области без полной перерисовки экрана.

direction(...) поддерживает:

  • TopDown - материал и его усиление идут сверху вниз
  • BottomUp - материал и его усиление идут снизу вверх
  • LeftRight - материал и его усиление идут слева направо
  • RightLeft - материал и его усиление идут справа налево

material(strength, color) управляет только верхним tinted-слоем поверх blur:

  • чем больше strength, тем заметнее tinted-слой поверх blur
  • color = -1 - взять текущий цвет фона библиотеки

То есть blur остаётся тем же, а меняется только то, как поверх него распределяется tinted-слой.

10.2. Glow

Круг:

ui.drawGlowCircle()
    .pos(60, 90)                          // центр круга
    .radius(18)                           // радиус фигуры
    .fillColor(ui.rgb(255, 255, 255))     // цвет самой фигуры
    .glowColor(ui.rgb(0, 120, 255))       // цвет свечения вокруг
    .glowSize(16)                         // толщина зоны свечения
    .glowStrength(220)                    // интенсивность свечения
    .anim(Pulse)                          // тип анимации свечения
    .pulseMs(1200)                        // период пульсации в миллисекундах

Для in-place обновления есть updateGlowCircle(). Если glow нужно обновлять на месте без грязных хвостов, добавь bgColor(...) с цветом фона под фигурой.

anim(...) поддерживает:

  • None - свечение статичное, без анимации
  • Pulse - свечение плавно пульсирует по силе

Code copied