Back to documentation index

Спецификация языка разметки HobDrive

Главная English Russian

Этот документ собирает теги, атрибуты и опции, используемые в файлах макетов (layout) интерфейса HobDrive

Цель: дать краткую и практичную справку для создания и редактирования UI-раскладок (панели, экраны ЭБУ, гибрид/GPS панели и т.д.).

Содержание

Контракт макета

Верхнеуровневые теги

Пример:

<include file="default-tripcomp.layout" if='${!sexists("GasTrigger")}'/>

Файлы макетов и порядок загрузки

Обычный интерфейс HobDrive собирается из стандартных layout-файлов приложения и пользовательских переопределений.

Типичные стандартные файлы:

Пользовательские файлы:

Стандартные default-*.layout и default*.gauge не стоит редактировать напрямую: они могут быть заменены при обновлении приложения. Для своих изменений используйте user.layout, user1.layout, user.gauge или DashKit.

user.gauge отличается от user.layout: HobDrive может автоматически изменять его из диалога настройки вида сенсора. Ручное редактирование возможно, но требует осторожности, чтобы не конфликтовать с настройками, сделанными через интерфейс.

section

Определяет логический блок экрана/страницы. Общие атрибуты:

Примеры:

<section name="GPS">
  ...
</section>
<section name="Fuel Trims" if="STFT1">
  ...
</section>

Навигационный пример:

<section name="My Diagnostics" title="Диагностика" optional="true" order="2" if="STFT1">
  <grid rows="," cols=",">
    <item id="STFT1"/>
    <item id="LTFT1"/>
  </grid>
</section>

Видимость секций в приложении

В runtime у секции есть состояние Optional.

Если секция должна быть доступна только при конкретном датчике, ECU или ориентации, используйте if.

Частые условия:

<section name="Only ATF" if="ATFTemp">
  ...
</section>

<section name="Portrait Tools" if="PortraitLayout">
  ...
</section>

<section name="Landscape Tools" if="LandscapeLayout">
  ...
</section>

config элементы

Пример:

<config id="Layout_ECUFuel" type="bool" default="false"
        title="Use Fuel Level data from ECU"
        descr="If enabled - fuel level will be shown from ECU. Otherwise - estimated from fuel consumption"
        title-ru="Показывать уровень топлива из ЭБУ"
        descr-ru="Если включено - уровень топлива будет браться из ЭБУ. Иначе - показывается оценочный уровень топлива"/>

Контейнеры макета

Пример (циклим температуры каждые 4 секунды):

<switch if='${Layout_RollTemp = true}' index='$${ svalue("DateTime") / 4000 }'>
  <item id="ATFTemp" .../>
  <item id="CVTTemp" .../>
  <item id="EngineOilTemp" .../>
</switch>

item

Представляет виджет в grid или stack. Общие атрибуты и примеры использования:

Примеры:

<item id="FuelLevel" if='${Layout_ECUFuel != true}' inherit="_FuelIndicator, _EditAction" onclick="NewFueling"/>
<item id="Odometer" if="${Layout_ECU_Odometer != true}" actions="SetupOdometer" size="large" inherit="_EditAction"/>

Действия элементов

Действия можно привязать к элементам через onclick, ondoubleclick, onhold, action и actions.

Примеры:

<item id="FuelLevel" onclick="NewFueling"/>
<item id="Speed" onhold="SensorInformation"/>
<item type="button" text="Min" action="Minimize"/>
<item id="Speed" actions="SetupOdometer, Minimize, Shutdown"/>
<item id="EfficiencyPercentage" onclick="Go(Efficiency)"/>

Частые действия:

Примеры:

<item id='Latitude' precision='6fixed' size="normal"/>
<item type="button" text="Fan On" action="invoke(FAN_ON)" size='extralarge' />
<item id='Lambda' colspan="2"/>

Специальные типы item

Декораторы и вложенные элементы

item может содержать вложенные декораторы. Пример синтаксиса:

<item id="Speed">
  <image image-zorder="bottom" image-path="images/dashboard-svgrepo-com.svg" image-scale="0.5"/>
  <image image-zorder="bottom" image-path="images/arrow.png" image-scale="0.5"/>
</item>

Современная вложенная форма удобнее для новых макетов, потому что все параметры декоратора находятся рядом с item.

Также поддерживается старый атрибутный синтаксис decorator-*, который часто встречается в существующих gauge и layout файлах:

<item id="Speed"
      decorator-i1="image"
      i1-image-zorder="bottom"
      i1-image-path="images/gauges/without_arrow_circle.png"
      decorator-i2="image"
      i2-image-zorder="bottom"
      i2-image-path="images/gauges/arrow.png"
      i2-image-rotate='$${ Sensor_Value - 45 }'
      i2-image-scale="1"/>

Идентификатор после decorator- произвольный (i1, bg, pad, action и т.д.). Атрибуты декоратора задаются с тем же префиксом: i1-image-path, pad-padding, action-image-align.

Порядок наложения старых декораторов определяется сортировкой их идентификаторов. Для предсказуемого порядка удобно использовать числовые или алфавитные префиксы: d1, d2, d3.

Декоратор image

Атрибуты: image-zorder, image-path, image-scale, image-width, image-height, image-align, image-aspect, image-rotate, image-rotate-align (могут содержать динамические выражения).

Многие атрибуты могут принимать динамические выражения, например image-rotate='$${ Sensor_Value - 45 }'.

Путь image-path обычно задается относительно папки ресурсов HobDrive или текущего DashKit. Для прозрачности используйте PNG или SVG.

Пример динамической картинки:

<item id="RPM">
  <image image-zorder="bottom"
         image-path='images/gauges/rpms/$${ceiling(Sensor_Value/1000*2)}.png'
         image-align="hcenter,bottom"
         image-scale="0.8"/>
</item>

Декоратор progress

<item id="Speed" decorator-10="touch-progress"/>

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

Декоратор tile

<item id="Speed" decorator-10="tile"/>

Рисует плитку позади gauge.

Декоратор padding

Декоратор padding используется для создания отступов в item. Значения задаются для TOP, RIGHT, BOTTOM, LEFT.

Можно использовать процентные значения.

<item id="Speed">
    <padding padding="0 0 0 120"/>
</item>

Декоратор crop

Декоратор crop обрезает (скрывает) часть ранее отрисованного виджета.

<item id="Test" border-opacity="1" type='roundbar' red-green="150,0">
  <crop crop="10% 10% 10% 10%"/>
</item>

Декоратор visible / visibility

Этот декоратор просто включает/отключает отрисовку во время выполнения. Вы можете использовать динамическую оценку $$.

<item id="AT_R" visibility='$${Sensor_Value}'/>

Декоратор filter

Декоратор filter — это мощный инструмент для применения визуальных эффектов и преобразований к элементам UI. Он поддерживает как эффекты отрисовки (визуальные фильтры), так и матричные преобразования (геометрические изменения).

Атрибуты

Эффекты отрисовки

Эти фильтры изменяют визуальный вид без изменения геометрии. Несколько фильтров можно объединить в цепочку с помощью точки с запятой.

blur(radiusX, radiusY)

drop-shadow(dx, dy, sigmaX, sigmaY)

transparent(alpha)

dilate(radiusX, radiusY)

erode(radiusX, radiusY)

brightness(factor)

contrast(factor)

invert()

sepia()

grayscale()

saturate(amount)

colorfilter(r, g, b)

remove-black()

Матричные преобразования

Важно: Матричные преобразования (rotate, offset, zoom) изменяют геометрию и не должны смешиваться с эффектами отрисовки в одном фильтре. Используйте отдельные декораторы <filter>, если вам нужно и то, и другое.

rotate(angle, [pivotX, pivotY])

offset(dx, dy)

zoom(scale) или zoom(scaleX, scaleY, [pivotX, pivotY])

Примеры использования

Простой эффект размытия:

<item id="Speed">
  <filter effect="blur(2,2)"/>
</item>

Несколько объединённых в цепочку эффектов:

<item id="Temperature">
  <filter effect="grayscale();saturate(0.5);brightness(1.2)"/>
</item>

Динамическое вращение на основе значения датчика:

<item id="Compass">
  <filter effect="rotate($${Sensor_Value},50%,50%)" interval="100"/>
</item>

Использование режима с несколькими декораторами:

<item id="Speed" type="chart" chart='line'>
  <break/>
  <image image-zorder="bottom" image-path="images/ui/arrow.png"/>
  <filter effect="rotate($${180+Sensor_Value%360},50%,50%)" mode="in" interval="100"/>
  <filter effect="blur(1,1)" mode="after"/>
  <padding padding="0 0 0 120"/>
</item>

Цветовое тонирование:

<item id="Warning">
  <filter effect="colorfilter(255,0,0)"/>  <!-- Красный оттенок -->
</item>

Лучшие практики

Декоратор break

Вы можете использовать break для прерывания наложения других декораторов. Break означает, что конвейер отрисовки начинается с пустого.

В этом примере break используется для применения фильтров только к декоратору image, а не к исходному содержимому gauge “Speed” (значению и графику).

<item id="Speed" type="chart" chart='line'>
  <break/>
  <image image-zorder="bottom" image-path="images/ui/arrow-circle-right.png" image-scale="0.6"/>
  <filter effect="rotate($${180+Sensor_Value%360},50%,50%)" mode="in" interval="100"/>
  <filter effect="blur(1,1)"/>
  <padding padding="0 0 0 120"/>
</item>

Уровневые атрибуты и функции (из changelog)

Дополнительные наблюдаемые атрибуты и поведения:

Пример графика с фильтрами и кастомным описанием:

<item id="Speed" wrap="predict(50,0.7)" type="chart" chart='line' period="100" precision="0" custom-description="Predictive speed" border-opacity="1"/>

Сенсоры и выражения

Пример TinyExe / eval:

image-rotate='$${ Sensor_Value - 45 }'

Пример доступа к extradata:

<item id="TripTime[fillup]"/>

SensorList и автогенерируемые панели

Примеры (взято из реальных layout)

<section name="GPS">
  <grid rows=",," cols=",,">
    <item id='Latitude' precision='6fixed' size="normal"/>
    <item id='Longitude' precision='6fixed' size="normal"/>
    <item id='Satellites'/>
    <item id='Altitude' precision='1'/>
    <item id='GPSSpeed' precision='1'/>
    <item id='ActiveSatellites'/>
    <item id='Direction'/>
    <item id='GPSOBD2SpeedDiff'/>
    <item id='FixedPosition'/>
  </grid>
</section>
<section name="FAN" fixed="false" if="PortraitLayout">
  <grid rows=",," cols="">
    <item id="FAN_Status" inherit="_ColoredOnOff" size='large'/>
    <item type="button" text="Fan On" action="invoke(FAN_ON)" size='extralarge' />
    <item type="button" text="Fan Off" action="invoke(FAN_OFF)" size='extralarge' />
  </grid>
</section>
<section name="Fuel Trims" if="STFT1">
  <grid rows="," cols=",">
    <item id="STFT1" size='large' precision="1" />
    <item id="STFT2" size='large' precision="1" />
    <item id="LTFT1" size='large' precision="1" />
    <item id="LTFT2" size='large' precision="1" />
  </grid>
</section>

Условные выражения

Примечание: if может содержать через запятую несколько идентификаторов, которые в практике работают как OR (множество вариантов).

Интерполяция в выражениях

Кроме простых выражений доступны два стиля интерполяции:

Эти формы позволяют вставлять TinyExe-выражения в значения атрибутов для статического или динамического вычисления.

Подсказки по размерам сетки

Можно вкладывать grid для создания сложных адаптивных областей.

Дополнительные полезные атрибуты и поведения

Widget и атрибуты декораторов (из user.layout)

Примеры:

<item id="Speed" decorator-i1="image" i1-image-zorder="bottom" i1-image-path="images/gauges/without_arrow_circle.png" i1-image-rotate='$${...}' i1-image-rotate-align="center"/>

<item id="Speed">
  <image zorder="bottom" path="images/gauges/without_arrow_circle.png"/>
  <image zorder="bottom" path="images/gauges/arrow.png" rotate='$${...}' scale="1"/>
</item>

Частые type в dashkits

Пример использования text-values:

<item id="RPM" wrap="predict(50, 0.7)" text-values="0:" type="text" description="hidden">

Advanced: ecuxml и определения сенсоров

Практические рекомендации

DashKit-пакеты

DashKit — это папка с метаданными, layout-файлами и ресурсами, которую HobDrive может скачать из GitHub и установить в пользовательскую директорию как отдельное переопределение.

Официальный репозиторий: hobdrive/hobdrive-dashkits.

Шаблон для своих пакетов: hobdrive/template-dashkits.

Минимальная структура:

community/my-dashkit/
  info.json
  user.layout
  images/
  README.md

info.json:

{
  "name": "My DashKit",
  "version": "1.0.0",
  "description": "Custom dashboard for HobDrive",
  "author": "Your Name"
}

Поддерживаемые поля info.json:

user.layout внутри DashKit использует тот же синтаксис, что и обычный пользовательский user.layout. Изображения можно класть рядом в images/ и ссылаться на них из image-path.

При установке HobDrive создает локальную папку вида:

override-<DashKitName>-<repo>-<branch>/

Эта папка читается как пользовательское переопределение. Поэтому DashKit может добавлять собственные user.layout, изображения, темы и другие ресурсы, не изменяя стандартные файлы приложения.

В приложении DashKits открываются через Настройки -> Настройки Дэш Панелей. Источник задается как GitHub owner/repo и ветка/ref; значения по умолчанию: hobdrive/hobdrive-dashkits, main.

Appendix — быстрый справочник по атрибутам

Try it — готовые шаблоны

GPS panel (минимальный)

<ui>
  <section name="GPS">
    <grid rows=",," cols=",,">
      <item id='Latitude' precision='6fixed' size="normal"/>
      <item id='Longitude' precision='6fixed' size="normal"/>
      <item id='GPSSpeed' precision='1' />
    </grid>
  </section>
</ui>

Fan control (кнопки + inherit)

<ui>
  <section name="FAN" fixed="false" if="PortraitLayout">
    <grid rows=",," cols="">
      <item id="FAN_Status" inherit="_ColoredOnOff" size='large'/>
      <item type="button" text="Fan On" action="invoke(FAN_ON)" size='extralarge' />
      <item type="button" text="Fan Off" action="invoke(FAN_OFF)" size='extralarge' />
    </grid>
  </section>
</ui>

Hybrid summary example

<ui>
  <section name="Hybrid">
    <grid rows="30,,," cols="30,,30">
      <item id="Efficiency_Battery" size='huge' />
      <item id="FuelEconomy_NoBattery" size='huge' />
      <item id="BatteryCurrent" />
      <item id="SoC" />
    </grid>
  </section>
</ui>

Файл переведён с сохранением терминов, имен атрибутов и примеров в исходном английском виде.