HobDrive Layout Specification
| Index | English | Russian |
This document collects the layout tags, attributes and options used by HobDrive UI layout files.
Table of Contents
- HobDrive Layout Specification
- Layout Contract
- Top-level tags
- section
- Layout containers
- item
- Special item types
- Decorators and nested elements
- Layout-level attributes and features from changelog
- Sensor and expression features
- Sensor lists and autogenerated panels
- Conditional expressions
- Interpolation in Expressions
- Grid sizing hints
- Other useful attributes and behaviors (from changelog and examples)
- Widget and decorator attributes (observed in
user.layout)
Layout Contract
- Inputs: XML-like layout files (tags:
ui,section,grid,item,union,stack-vertical,stack-horizontal, etc.) - Output: Rendered UI screens in HobDrive; conditional visibility and decorators influence on runtime behavior
- Error modes: invalid attributes are ignored or fallback to defaults; missing sensors show as empty/unavailable
- Success criteria: layout renders and respects conditional
ifattributes, grid placement, decorators and widget attributes
Top-level tags
-
ui— root element for a layout file. Containssectionelements and other layout constructs. -
include— allows embedding another layout file or fragment. Attributes:file— relative path to the included layout (e.g.,file="default-tripcomp.layout").if— optional condition which controls whether the included file is processed (same expression syntax assectionif).- Includes are evaluated when the file is loaded and are commonly used to compose main layouts from reusable fragments (trip computer, HUD, dashkits).
Example:
<include file="default-tripcomp.layout" if='${!sexists("GasTrigger")}'/>
section
Defines a logical screen/page block. Common attributes:
name— human-readable section name (used in UI lists).fixed—true/false(whether the section is fixed in navigation).if— conditional expression (a sensor name or expression). Section is shown only if condition evaluates truthy. Examples:if="Oxygen_b1s1",if="PortraitLayout",if="Renault_01_11103.ControlModuleVoltage".class— CSS-like class used by system to apply predefined behaviors (e.g.,SensorList).ns— namespace for sensor filtering when usingSensorList.exclude— regex to exclude sensor IDs in generated sensor listsmaximize-focus— (from changelog)true/falseremove optional controls when focusedcontrols—autohideor other values to control UI buttons
Example:
<section name="GPS">
...
</section>
<section name="Fuel Trims" if="STFT1">
...
</section>
config elements
config— declare UI-configurable options that appear in settings dialogs. Typical attributes:id— unique identifier accessible from layout expressions (e.g.,${Layout_ECUFuel}).type—bool,int,string, etc.default— default value.title,descr— text shown in UI; localized variants liketitle-ru,descr-ruare supported.
Example:
<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="Если включено - уровень топлива будет браться из ЭБУ. Иначе - показывается оценочный уровень топлива"/>
Layout containers
grid— places childitems into a table-like grid.- Attributes:
rows,cols— comma-separated size hints. Example:rows=",," cols=",35". rowsandcolscan include numeric heights/widths or empty entries for flexible sizing.-
grids can be nested.
stack-vertical/stack-horizontal— stack items vertically/horizontally;columnsmay be used.- Example:
<stack-vertical columns="${LandscapeLayout ? 2 : 1}">
- Example:
union— allows compositing several alternate layouts into same area (used in TPMS layout).- Use
unionwhen multiple mutually-exclusive sub-layouts should occupy the same grid area; each child typically contains its owngrid.
- Use
-
optional/volatile(section attributes) — lightweight hints used by some default layouts:optional="true"marks screens that can be hidden,volatilemarks temporary screens. switch— selects one of its child elements to show based on anindexexpression. Useful for small cycling lists or conditional items.- Attributes:
index— an expression or integer selecting which child to show (0-based). Can reference sensor values viasvalue(...)or any TinyExe expression.interval— when present,indexmay be evaluated periodically using this interval (milliseconds) to cycle children.if— optional condition to entirely enable the switch.
- Children are typical
items (or nested grids); whenindexresolves to a child index that child is displayed.
- Attributes:
Example (cycle temperature sensors every 4 seconds):
<switch if='${Layout_RollTemp = true}' index='$${ svalue("DateTime") / 4000 }'>
<item id="ATFTemp" .../>
<item id="CVTTemp" .../>
<item id="EngineOilTemp" .../>
</switch>
item
Represents a widget in a grid or stack. Common attributes and usages:
id— sensor or special control identifier. Examples:RPM,Latitude,ControlModuleVoltage.type—button,static, etc. Defaults to a sensor/value widget when omitted.text— for buttons or static items, visible text.action— forbutton: action string such asinvoke(FAN_ON)orrun(...).size— visual size hint:micro,small,normal,large,huge,extralargeor numeric.precision— number of decimal digits or special tags like6fixed.inherit— refers to a decorator or style name, e.g.,inherit="_ColoredOnOff"or_MB_Battery.colspan/rowspan— span cells in the grid.description— extra attribute used to style or position small descriptive labels (e.g.,description="aside").period— update period in milliseconds (e.g.,period='5000'onControlModuleVoltage).wrap— filter expression for smoothing or prediction: examples from changelog:wrap="predict(50,0.7)"wrap="smooth(400,100,5)"wrap="average(30)"
-
custom attributes:
text-values,custom-units,colored-descr,text-evaluator(see changelog entries where used) onclick— item-level click handler (navigates or runs named actions). Examples:onclick="NewFueling",onclick="Go(Efficiency)".actions— comma-separated list of actions available in sensor info dialog. Example:actions="SetupOdometer".units— visual placement of unit text:units="below",units="aside"orunits="hidden".interval— an update interval used for dynamic UI behaviour or internal timers (different from sensorperiod).decorator-XXX- special syntax to enable decorators.
Example usages:
<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"/>
- type specifics and chart attributes:
type="chart"— renders a chart for the sensor; common chart attributes:chart='line',time-scale,min-limit,max-limit,cover-description.border-opacity— visual border control (used on charts/gauges in dashkits).custom-description/description/custom-units— allow custom labels and units.
- item extradata access:
id="sensor[extradata]"— render additional data stored with a sensor (e.g.,TripTime[fillup]).
Examples:
Special item types
- type=”button” — clickable button. Use
action=”invoke(NAME)” to call ECU/service action. - type=”static” — static text block. E.g.
type="static" size="micro" - gauge / chart / image decorators — declared either as
itemwith nested decorators or in gauge/theme files; can accept decorators.
Decorators and nested elements
item may contain nested decorators. Example syntax:
image decorator
Attributes: image-zorder, image-path, image-scale, image-width, image-height, image-rotate (can contain dynamic expressions).
Many attributes can accept dynamic expressions such as image-rotate='$${ Sensor_Value - 45 }'.
progress decorator
<item id="Speed" decorator-10="touch-progress"/>
This is a system decorator, used to draw dynamic line on press.
tile decorator
<item id="Speed" decorator-10="tile"/>
Draws a tile behind the gauge.
padding decorator
Padding decorator is used to “pad” space in iitem. Values are for TOP, RIGHT, BOTTOM, LEFT.
You can use percentage values.
<item id="Speed">
<padding padding="0 0 0 120"/>
</item/>
crop decorator
Crop decorator cuts (hides) part of the previously rendered widget.
<item id="Test" border-opacity="1" type='roundbar' red-green="150,0">
<crop crop="10% 10% 10% 10%"/>
</item>
visibile / visibility decorator
This decorator just enables/disables drawing in runtime. You can use dynamic $$ evaluation.
<item id="AT_R" visibility='$${Sensor_Value}'/>
filter decorator
The filter decorator is a powerful tool for applying visual effects and transformations to UI elements. It supports both draw effects (visual filters) and matrix transformations (geometric changes).
Attributes
effect— semicolon-separated list of filter functions to apply. Each filter is a function call with parameters.mode— controls when the filter is applied in the rendering pipeline:before— applies filter before rendering the target element, then renders the element normallyin(default) — applies filter to the target element onlyafter— renders the target element first, then applies filter
interval— optional; update interval in milliseconds for dynamic filter expressions (using$${}syntax)
Draw Effects
These filters modify the visual appearance without changing geometry. Multiple filters can be chained with semicolons.
blur(radiusX, radiusY)
- Applies Gaussian blur to the element
radiusX— horizontal blur radius in pixelsradiusY— vertical blur radius in pixels- Example:
effect="blur(2,2)"— applies 2px blur in both directions
drop-shadow(dx, dy, sigmaX, sigmaY)
- Creates a drop shadow effect
dx— horizontal shadow offset in pixelsdy— vertical shadow offset in pixelssigmaX— horizontal blur sigmasigmaY— vertical blur sigma (optional, defaults to sigmaX if omitted)- Shadow color is black
- Example:
effect="drop-shadow(5,5,3,3)"— shadow offset 5px right and down with 3px blur
transparent(alpha)
- Adjusts element transparency
alpha— opacity reduction (0.0 = fully transparent, 1.0 = no change)- Example:
effect="transparent(0.5)"— makes element 50% more transparent
dilate(radiusX, radiusY)
- Expands bright areas (morphological dilation)
radiusX— horizontal dilation radius in pixelsradiusY— vertical dilation radius in pixels- Example:
effect="dilate(2,2)"— expands bright areas by 2px
erode(radiusX, radiusY)
- Shrinks bright areas (morphological erosion)
radiusX— horizontal erosion radius in pixelsradiusY— vertical erosion radius in pixels- Example:
effect="erode(2,2)"— erodes bright areas by 2px
brightness(factor)
- Adjusts brightness of the element
factor— brightness multiplier (0.0 = black, 1.0 = original, >1.0 = brighter)- Example:
effect="brightness(1.5)"— increases brightness by 50%
contrast(factor)
- Adjusts contrast of the element
factor— contrast multiplier (0.0 = gray, 1.0 = original, >1.0 = higher contrast)- Example:
effect="contrast(1.3)"— increases contrast by 30%
invert()
- Inverts colors (negative effect)
- No parameters
- Example:
effect="invert()"— creates color negative
sepia()
- Applies sepia tone (warm brownish tint)
- No parameters
- Example:
effect="sepia()"— vintage photo effect
grayscale()
- Converts to grayscale (luminance-based)
- No parameters
- Uses standard luminance weights (R: 0.2126, G: 0.7152, B: 0.0722)
- Example:
effect="grayscale()"— black and white effect
saturate(amount)
- Adjusts color saturation
amount— saturation change (-1.0 = desaturate, 0.0 = no change, >0.0 = more saturated)- Example:
effect="saturate(0.5)"— increases saturation by 50% - Example:
effect="saturate(-0.3)"— reduces saturation by 30%
colorfilter(r, g, b)
- Tints the element with a specific color while preserving brightness
r— red component (0-255)g— green component (0-255)b— blue component (0-255)- Converts image to grayscale then applies color tint
- Example:
effect="colorfilter(255,100,50)"— orange tint
remove-black()
- Makes black pixels transparent (useful for removing black backgrounds)
- No parameters
- Alpha channel becomes proportional to pixel brightness
- Example:
effect="remove-black()"— removes black background from images
Matrix Transformations
Important: Matrix transformations (rotate, offset, zoom) modify geometry and should not be mixed with draw effects in the same filter. Use separate <filter> decorators if you need both.
rotate(angle, [pivotX, pivotY])
- Rotates the element
angle— rotation angle in degreespivotX— optional; horizontal pivot point (percentage or pixels, default: 50%)pivotY— optional; vertical pivot point (percentage or pixels, default: 50%)- Example:
effect="rotate(45)"— rotates 45° around center - Example:
effect="rotate(90,0%,0%)"— rotates 90° around top-left corner - Dynamic example:
effect="rotate($${Sensor_Value})"— rotates based on sensor value
offset(dx, dy)
- Translates (moves) the element
dx— horizontal offset (percentage or pixels)dy— vertical offset (percentage or pixels)- Example:
effect="offset(10,20)"— moves 10px right, 20px down - Example:
effect="offset(50%,0)"— moves 50% of width to the right
zoom(scale) or zoom(scaleX, scaleY, [pivotX, pivotY])
- Scales the element
scale— uniform scale factor (1.0 = original size)- OR:
scaleX— horizontal scale factorscaleY— vertical scale factorpivotX— optional; horizontal scaling center (percentage or pixels)pivotY— optional; vertical scaling center (percentage or pixels)- Example:
effect="zoom(1.5)"— scales to 150% around center - Example:
effect="zoom(2,1)"— doubles width only - Example:
effect="zoom(0.5,0.5,0%,0%)"— scales to 50% from top-left corner
Usage Examples
Simple blur effect:
<item id="Speed">
<filter effect="blur(2,2)"/>
</item>
Multiple chained effects:
<item id="Temperature">
<filter effect="grayscale();saturate(0.5);brightness(1.2)"/>
</item>
Dynamic rotation based on sensor value:
<item id="Compass">
<filter effect="rotate($${Sensor_Value},50%,50%)" interval="100"/>
</item>
Mode usage with multiple decorators:
<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>
Color tinting:
<item id="Warning">
<filter effect="colorfilter(255,0,0)"/> <!-- Red tint -->
</item>
Best Practices
- Chain multiple draw effects in a single filter using semicolons for better performance
- Don’t mix matrix transformations with draw effects in the same
effectattribute - Use
intervalattribute only when you have dynamic$${}expressions that need periodic updates - Use
mode="in"(default) for most cases; usemode="before"ormode="after"for special layering needs - Pair
<break/>decorator before filters when you want to apply effects only to subsequent decorators, not the base element
break decorator
You can use break to abort overlaying of other decorators. Break means drawing pipeline starts from empty.
In this example break is used to apply filters only to the image decorator. not to the original content of “Speed” gauge (value and chart).
<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>
Layout-level attributes and features from changelog
if— conditional rendering for section or item. Can use sensor names, boolean flags likePortraitLayout,LandscapeLayout, or compound expressions.ignore-gaugesin section — ignores global gauge attributes for all elements inside the section.gaugelocal definitions — gauge definitions can be declared insidesectionto scope them locally.swap-directionon gauges:swap-direction="true"to change direction of bar or roundbar.horizontal-offsetin roundbar.breakdecorator —<break/>splits rendering into independent stages.maximize-focus,controls="autohide"— useful for dash panels.time-scale— used in charts to compress/expand time axis.text-evaluator— advanced gauge attribute (returns arbitrary dynamic text), used in tank/description rendering.
Additional attributes and behaviors observed in layout files and changelogs:
optional/volatileonsection(controls visibility rules in some hosts).periodonitem— refresh period in milliseconds.precision— numeric formatting or special formats (e.g.,6fixed).colspan/rowspan— grid spanning.
Example of a chart item with filters and custom description:
Sensor and expression features
- Sensors can be referenced directly by
idinifattributes or as item ids. - TinyExe helpers and
evalexpressions available in ecuxml. Variables and functions accessible include: Pi, E, PositiveInfinity, NegativeInfinity and other globals from themes or gauge definitions. - Filters for sensors (wrap) as above.
TinyExe / eval example (from changelogs):
image-rotate='$${ Sensor_Value - 45 }'
Sensor formatted access example:
<item id="TripTime[fillup]"/> — uses extradata from sensor history APIs.
Sensor lists and autogenerated panels
sectionwithclass="SensorList"andns="<namespace>"generates a screen listing sensors for a namespace. Useexcluderegex to filter out unwanted sensor IDs. Example:
Conditional expressions
- The
ifattribute can be a simple sensor presence test (e.g.,if="STFT1") or a full expression referencing theme variables, day/night flags, layout flags, and sensor values. Example seen:if="SY_ABS_TEVES.ABS_ControlModuleVoltage, Chery_A21_ABS_TRW.ABS_ControlModuleVoltage"
Notes: if can contain comma-separated identifiers which act as OR conditions in practice (layout files often list multiple sensors/namespaces separated by commas).
Interpolation in Expressions
In addition to unadorned expressions, two interpolation styles are available:
-
${ } interpolation: Evaluated once when the layout is built. Use this form for static computations or one-time assignments. Applicable for any attributes.
-
$${ } interpolation: Evaluated dynamically, making it suitable for values that update over time (e.g., animations or periodic sensor updates). Only applicable to the selected elements/attributes:
text-evaluator,switch[index],visibility,image-rotate,image-path,crop
These forms allow embedding TinyExe expressions within attribute values to achieve either static or dynamic evaluation as needed.
Grid sizing hints
rowsandcolsaccept comma separated values. Empty entries are flexible cells, numbers provide fixed size hints. Example:rows="30,,," cols="30,,30".
You can nest grid elements to create complex responsive regions.
Other useful attributes and behaviors (from changelog and examples)
periodonitem— sets refresh period for the widget.precision— formatting precision or special tags like6fixed.description="aside"— places descriptive text aside.inherit— reuses widget styling (colors/formatting) from theme or other definitions.text-valuesandcustom-unitsallow mapping numeric values to textual labels or alternate unit systems.min-limit/max-limit— clamp values for charts.
Widget and decorator attributes (observed in user.layout)
-
type (examples):
bar,roundbar,chart,text,static— many visual widgets are selected viatypeon theitem. -
cache-interval— UI cache/refresh hint (milliseconds or unit) used to control smoothing/plotting; frequently used onchartand gauge-like widgets. Example:cache-interval="6". -
red-green— color threshold list; comma-separated numbers indicating color boundaries (interpretation depends on widget). Examples:red-green="100,5",red-green="10,120,150". -
bars-count— number of bars or segments used by bar/roundbar widgets. Example:bars-count="10". -
transparent—true/falsewhether background is transparent for the widget. -
border-width/border-opacity— visual border control. Example:border-width="3",border-opacity="1". -
colored-value— whether value text is colored according to thresholds:colored-value="true". -
fade-coeff— visual fading coefficient used on charts/gauges to control trail transparency:fade-coeff="0.8". -
width-compression— compress drawing horizontally:width-compression="0.9". -
item-size/item-width/item-height/item-spacing— sizing controls for roundbars and similar widgets (absolute/logical units). Example:item-size="25",item-width="10",item-height="10",item-spacing="20". -
small-radius-delta/small-radis-delta(typo variants observed) — small radius adjustments used for roundbars. -
start-angle/end-angle/radius/vertical-offset— roundbar geometry attributes to control arc start/end and offset. -
item-width/item-heightvsitem-size— some widgets useitem-sizewhile others use width/height pair. -
corn-angle/middle-angle— additional roundbar geometry attributes (observed in test layouts). -
decorator-p(padding) andp-padding— decorator shorthand for padding decorator. Example:decorator-p="padding" p-padding="10 10 10 10". -
decorator-i/decorator-iNpattern — numbered decorators for multiple images on a single item. Usedecorator-i1="image"andi1-image-path,i1-image-rotate,i1-image-zorder,i1-image-rotate-align, etc. The unnumbereddecorator-i="image"with nested<image>elements is also supported.Examples: ```xml
- rotate / scale attributes on nested `<image>` decorators — `rotate` can contain dynamic TinyExe expressions and `scale` applies an image scale.
- custom-units — used on `DateTime` to show time variants: `custom-units="time12"`, `time`, `timesec`, `datetime`, `seconds`.
- border-opacity used on static/test items to preview borders: `border-opacity="1"`.
- numeric `size` on `item` — static items can use numeric `size` values (e.g., `size="72"`, `size="32"`) besides named sizes (`small`, `normal`, `large`).
Common `type` values seen in dashkits:
- `type="text"` — textual rendering of a sensor with `text-values` mapping.
- `type="chart"` — time-series chart for sensor.
- `type="button"` — user-invokable action.
Example: `text-values` and `type=text` usage in dashb3 kits:
`<item id="RPM" wrap="predict(50, 0.7)" text-values="0:" type="text" description="hidden">`
## Advanced: ecuxml and sensor definitions
- sensor definitions and `eval` expressions live in ecuxml files. Key features mentioned across changelogs:
- `<eval>` expressions for computed sensors
- `base-data` / `base-raw` for raw bytes
- functions `get(offset)`, `get_word()` etc.
- `text` tag with offset/length for string sensors
## Best practices and tips
- Use `if` broadly to keep layout files modular; layout files are only loaded for relevant ECUs, but `if` helps avoid rendering empty sections.
- Use `SensorList` sections for generic sensor browsing screens and `exclude` to filter noisy sensors.
- Prefer nested decorators for complex visuals; they are simpler and localized.
- Use `wrap` filters on noisy sensors (GPS, speed, MAF) for smoother rendering.
- Keep gauges local to section when possible using `ignore-gauges` and local `gauge` declarations to reduce global side-effects.
## Appendix — common attributes quick reference
- section: `name`, `fixed`, `if`, `class`, `ns`, `exclude`, `maximize-focus`, `controls`
- grid: `rows`, `cols`
- item: `id`, `type`, `text`, `action`, `size`, `precision`, `inherit`, `colspan`, `rowspan`, `description`, `period`, `wrap`
- decorators: `image` (`image-path`, `image-scale`, `image-zorder`, `image-rotate`, `image-width`/`image-height`)
## Try it — ready templates
Copy these minimal examples into a skin file to try the patterns.
GPS panel (minimal)
```xml
<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 (buttons + 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>
