GUI model¶
This section presents the GUI Metamodel, which provides a framework for specifying, structuring, and organizing graphical user interface (GUI) components within the BESSER platform. The metamodel builds upon concepts inspired by the Interaction Flow Modeling Language (IFML), ensuring interoperability with standard UI modeling tools and supporting integration with B-UML structural models. This new metamodel introduces a modular structure, new UI element types, layout and style definitions, and finer control of positioning and hierarchy.
Note
The classes highlighted in green originate from the structural metamodel.
Overview¶
A GUIModel represents the complete user interface specification of an application. It is organized into modules and screens, each describing specific application areas and their visual composition. Screens contain one or more view containers, which define the layout and structure of visual elements.
1. Structural organization
The upper level of the metamodel defines the organization of the interface:
- GUIModel contains multiple Modules
- Each Module defines several Screens
- Each Screen hosts one or more ViewContainers arranged with specific Layouts
2. Visual composition
View containers hold collections of ViewElements that represent visible components such as buttons, menus, forms, lists, images, links, or embedded content.
These elements can be combined and nested to compose complex user interfaces.
3. Presentation and layout
Dedicated classes like Layout, Position, and Size describe how components are arranged and styled.
Enumerations such as Alignment, UnitSize, and PositionType offer standardized visual options for spacing, orientation, and alignment.
4. Interaction and behavior
Interactive elements—such as Button, Form, and Menu, can be linked to application logic or data bindings.
Attributes like ButtonType and ButtonActionType define common actions (e.g., Submit, Cancel, Navigate, Edit) in a platform-independent way.
Supported Notations¶
You can create and manipulate GUI models using:
Component Types¶
The GUI metamodel provides a rich set of view components for building user interfaces:
Button: A clickable control. Configured via
ButtonType(submit,reset,button) andButtonActionType(navigate,submit,reset,custom).Text: A static or dynamic text element for displaying labels, headings, or paragraphs.
Image: Displays an image resource within the interface.
InputField: A data-entry control. Configured via
InputFieldType— see Input Fields below.Form: A container that groups related
InputFieldinstances — see Forms below.Alert: An inline message banner for status feedback — see Alert below.
Menu and MenuItem: Navigation components for organizing links and actions into hierarchical menus.
DataList: Displays a collection of data records, typically bound to a domain model class.
Link: A hyperlink element for navigation between screens or to external URLs.
EmbeddedContent: Embeds external content (e.g., iframes, media players) within a screen.
Input Fields¶
InputFieldType selects the widget used to capture a value. It covers 29 kinds grouped by
data category: text (Text, TextArea, RichText, Password, Search, Tags,
OTP, Hidden), formatted text (Email, URL, Tel), numeric (Number,
Slider, Spinner, Rating), boolean (Checkbox, Toggle), selection
(Dropdown, RadioGroup, CheckboxGroup, MultiSelect), date/time (Date,
Time, DateTime, DateRange), file (File, ImageUpload), and Color.
Range is kept as a backward-compatible alias for Slider.
InputField also exposes optional form-metadata attributes: label, placeholder,
required, default_value, options (list[SelectOption]), min_value,
max_value, step, help_text, disabled, readonly, and multiple.
All default to None / False / "" so existing code is unaffected.
SelectOption (label: str, value: str) provides the individual choices for
Dropdown, RadioGroup, CheckboxGroup, and MultiSelect fields.
Forms¶
Form gains five new optional attributes alongside the existing inputFields:
title (heading above the form), submit_label (default "Submit"),
show_cancel / cancel_label (optional cancel button), and columns (1–4
uniform grid layout, default 1). All have backward-compatible defaults.
A form that creates records of a class carries a data_binding
(DataBinding(domain_concept=<Class>)), and each of its InputFields a
DataBinding whose data_field is the attribute it edits. When the
editor’s form is processed, the class comes from the form’s data-source
(class id or name) or, without one, from the input names when they are all
attributes of exactly one class and supply every attribute a new record of it
requires (so a lookup form is not bound); a <label> becomes its input’s label
and the first submit button’s text the submit_label. The React generator
renders a bound form as a FormBlock that POSTs to /<class>/ (see
React Generator).
Alert¶
Alert is a new ViewComponent for inline status messages — useful when agents
generate GUIs and need to surface feedback alongside a form. It carries content: str,
severity: AlertSeverity (Info | Success | Warning | Error),
an optional title, and a dismissible flag.
Dashboard Components¶
For data visualization and dashboard-style interfaces, the metamodel includes:
LineChart, BarChart, PieChart, RadarChart, RadialBarChart: Chart components for visualizing data series in various formats.
Table: A tabular data display with support for typed columns:
Column: A basic table column.FieldColumn: A column bound to a specific class attribute.LookupColumn: A column that resolves values through an association.
Map: An interactive multi-layer map backed by OpenStreetMap via the Leaflet library. Supports static and data-bound layers of types:
points,geojson,choropleth,heatmap— see Map Component below and Map Component Reference.AgentComponent: A component that integrates a BESSER Agent Framework (BAF) agent into the user interface, enabling conversational or AI-driven interactions.
A MetricCard’s or a chart Series’ DataBinding may carry an optional
aggregation (a DataAggregation: SUM, AVG, COUNT, MIN,
MAX, MEDIAN, FIRST, LAST; the names "sum", "avg",
"count", "min", "max" are accepted too). A metric card shows the
aggregation of its data_field over all records; a chart series groups the
records by its label_field and aggregates each group. In the editor JSON it
is the aggregation attribute of the metric card, of a chart series, or of
the chart (for all its series).
Map Component¶
Map is a ViewComponent that renders an interactive OpenStreetMap tile layer
with one or more typed data layers stacked on top. It requires no API key.
See Map Component Reference for full documentation including the column contract table,
auto-detection rules, and the generated-code guide.
Map constructor parameters
Parameter |
Default |
Description |
|---|---|---|
|
(required) |
Unique component name. |
|
|
Optional heading displayed above the map. |
|
|
Initial map centre latitude (decimal degrees). |
|
|
Initial map centre longitude (decimal degrees). |
|
|
Initial zoom level (1 = world, 18 = street). |
|
|
List of |
WorldMap and LocationMap are thin subclasses of Map that forward all
keyword arguments unchanged.
MapLayerType
from besser.BUML.metamodel.gui.dashboard import MapLayerType
MapLayerType.points # lat/lng markers
MapLayerType.geojson # GeoJSON polygons or lines
MapLayerType.choropleth # value-coloured GeoJSON + auto legend
MapLayerType.heatmap # density heat layer
When layer_type is None, effective_layer_type() infers the type from the
configured field references and, as a final fallback, from the bound class’s attribute
names and types. See Map Component Reference for the full auto-detection rules.
MapLayer constructor parameters
Parameter |
Default |
Description |
|---|---|---|
|
(required) |
Unique layer name. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Python code example — multi-layer map
from besser.BUML.metamodel.structural import (
Class, Property, DomainModel, FloatType, StringType,
)
from besser.BUML.metamodel.gui import GUIModel, Module, Screen, DataBinding
from besser.BUML.metamodel.gui.dashboard import Map, MapLayer, MapLayerType
# Domain model
lat = Property(name="latitude", type=FloatType)
lng = Property(name="longitude", type=FloatType)
store_name = Property(name="name", type=StringType)
store = Class(name="Store", attributes={lat, lng, store_name})
geometry = Property(name="geometry", type=StringType)
population = Property(name="population", type=FloatType)
canton = Class(name="Canton", attributes={geometry, population})
domain = DomainModel(name="LuxMap", types={store, canton})
# Layers
store_layer = MapLayer(
name="stores",
layer_type=MapLayerType.points,
data_binding=DataBinding(name="store_binding", domain_concept=store),
latitude_field=lat,
longitude_field=lng,
label_field=store_name,
)
canton_layer = MapLayer(
name="cantons",
layer_type=MapLayerType.choropleth,
data_binding=DataBinding(name="canton_binding", domain_concept=canton),
geojson_field=geometry,
value_field=population,
)
# Map
lux_map = Map(
name="LuxMap",
title="Luxembourg — Stores & Cantons",
center_latitude=49.8153,
center_longitude=6.1296,
zoom=9,
layers=[store_layer, canton_layer],
)
screen = Screen(name="MapScreen", description="", view_elements={lux_map},
is_main_page=True)
module = Module(name="AppModule", screens={screen})
gui = GUIModel(name="LuxApp", package="com.example.lux",
versionCode="1", versionName="1.0", modules={module})
Layout and Styling¶
The metamodel provides fine-grained control over how components are arranged and styled:
LayoutType: Defines the arrangement strategy for child components within a container. Supported values:
vertical,horizontal,grid,stack.Alignment: Controls how components are aligned within their container (e.g., start, center, end).
UnitSize: Specifies the unit of measurement for size values (e.g., pixels, percentages).
PositionType: Determines how a component is positioned (e.g.,
static,relative,absolute,fixed).Style: A dedicated class for visual customization that allows setting properties such as colors, fonts, borders, padding, and margins on any view component.
Stylesheet:
GUIModel.stylesheet(str, default"") holds raw CSS shared by the whole GUI: class and compound-selector rules,:rootdesign tokens (CSS custom properties),@mediablocks and state rules such as:hover. Components opt in through theircss_classes. When a GUI diagram is imported from the web editor, every rule not tied to a single element id is kept here in its original order, while element-id rules still become that component’sStyling.gui_model = GUIModel( name="Shop", package="", versionCode="1", versionName="1.0", modules={module}, description="", stylesheet=":root{--ds-primary:#15293d}\n" ".app-btn{background:var(--ds-primary)}\n" "@media (max-width:850px){.app-btn{width:100%}}\n", )
Python Code Example¶
The following example demonstrates how to create a simple GUI model programmatically:
from besser.BUML.metamodel.gui import *
screen = Screen(name="MainScreen")
button = Button(name="submitBtn", button_type=ButtonType.submit)
text = Text(name="welcomeText")
screen.add_component(button)
screen.add_component(text)
gui_model = GUIModel(name="MyApp", screens={screen})