//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2010, 2026 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
//
// This program and the accompanying materials are made available
// under the terms of the MIT License which is available at
// https://opensource.org/licenses/MIT
//
// SPDX-License-Identifier: MIT
//////////////////////////////////////////////////////////////////////////////

include::../_part_attributes.asciidoc[]

:leveloffset: -2

[[lang-tut-svg-chapter-interaction]]
== SVG interaction

indexterm:[SVG,interaction]
SVG interaction allows SVG images that are used for SVG visualization to be used to interactively control the model.
That is, SVG interaction allows certain elements of SVG images to be made interactive, such that clicking them has an effect on the model.
If we consider that SVG visualization allows to have an SVG image be updated based on the state of the model, mapping the model state to the image, then SVG interaction kind of works the other way around, mapping clicks of elements in the image to effects on the behavior of the model.

The idea of SVG interaction is that certain SVG elements are coupled (mapped) to events or updates in the CIF specification.
Clicking on those graphical elements then results in the corresponding event being taken or update being executed.
This way, the user interface of a system can be modeled graphically, and can be coupled to the specification, by means of events and updates.
The user interface of the system is thus part of the specification, but is controlled interactively (at runtime) by the user.

=== Example

As an example, consider a button and a lamp.
Clicking the button turns on the lamp.
Clicking the button again off the lamp.
We can use SVG visualization and interaction to model this, which allows for interactive simulation.
Initially, the button (on the left) is unpushed (the wide rectangle) and the lamp (on the right) is off (silver color):

image::{lang-tut-imgsdir}/svg/button_lamp/button_lamp_unpushed_off.png[]

Clicking the button pushes it (it becomes less wide) and turns on the lamp (yellow color):

image::{lang-tut-imgsdir}/svg/button_lamp/button_lamp_pushed_on.png[]

[[lang-tut-svg-chapter-interaction-svgin]]
=== CIF/SVG input mappings

Interactivity is specified by means of CIF/SVG input mappings.
There are two types of input mappings: those that map to events and those that map to updates.

[[lang-tut-svg-chapter-interaction-interactive-events]]
An input mapping may map to an event, allowing a click on an interactive element to map to executing a single transition for an event.
The events that are coupled to visualization elements are called _SVG interactive events_ or _SVG input events_.

An input mapping may also map to updates, allowing a click on an interactive element to lead to <<lang-tut-reuse2-chapter-input-variables,input variables>> being updated by assigning them (new) values.

indexterm:[SVG input mapping,single event input mapping]

[[lang-tut-svg-chapter-interaction-event-single]]
=== Single event input mapping

The simplest form of an SVG input mapping maps to a single event.
For instance:

[source, cif]
----
svgin id "button" event machine.button.toggle;
----

This input mapping maps the SVG element with <<lang-tut-svg-chapter-visualization-svg-id,id>> `button` to the `machine.button.toggle` event from the CIF specification.
Specifying an input mapping for an SVG element turns that SVG element into an _interactive SVG element_.
In this case, the `machine.button.toggle` event is disabled until the element with id `button` is clicked.
Each click enables the event, allowing at most one transition for it.
If the event is enabled in the rest of the model, a transition is taken for it, and the event becomes disabled again.
If the event is not enabled in the rest of the model, for instance because some automaton with the event in its alphabet can't synchronize in its current location, then the click is ignored and the event becomes disabled again.
The event remains disabled until the `button` element is clicked again.

indexterm:[SVG input mapping,if event input mapping]

[[lang-tut-svg-chapter-interaction-event-if]]
=== `if` event input mapping

Sometimes, the simple _single event input mapping_ is not enough.
Consider for instance the following CIF specification:

[source, cif]
----
automaton button:
  event u_pushed, u_released;

  location Released:
    initial;
    edge u_pushed goto Pushed;

  location Pushed:
    edge u_released goto Released;
end
----

This specification models a `button` that is initially released (location `Released`).
When the button is pushed (event `u_pushed`), the location is updated to `Pushed`.
If we now want to couple a graphical representation of a button to this CIF specification, the event to choose depends on the current location of the `button` automaton.
This can be mapped using an _if event input mapping_, as follows:

[source, cif]
----
svgin id "button" event
  if   button.Released: button.u_pushed
  elif button.Pushed:   button.u_released
  end;
----

If the button is released, the `u_pushed` event is chosen, and if the button is pushed, the `u_released` event is chosen.

The `if` event input mappings are essentially an <<lang-tut-values-chapter-if-expression,`if` expression>> that result in an event rather than a value.
The conditions (such as `button.Released`) are guard expressions that evaluate to a boolean value.
The guard expressions may be arbitrary expressions, similar to the use of expressions in output mappings.

If a condition holds, the corresponding event is chosen.
The entries are processed in the order they are specified: if the first guard (of the `if`) holds, the first event is chosen, otherwise if the second guard (of an `elif`) holds, the second event is chosen, etc.
The `elif` parts are optional, and you may include as many as you want.
The last part of the `if` is optionally allowed to be an `else`, to indicate that if none of the previous guards hold, the event of the `else` is to be chosen.

indexterm:[SVG input mapping,update input mapping]

[[lang-tut-svg-chapter-interaction-update]]
=== Update input mapping

An SVG input mapping can also update the values of <<lang-tut-reuse2-chapter-input-variables,input variables>>.
For instance:

[source, cif]
----
input int counter;

svgin id "increase" do counter := counter + 1;
svgin id "decrease" do counter := counter - 1;
----

In this example, by clicking the SVG element with id `increase` the value of `counter` is increased by one.
Similarly, clicking the SVG element with id `decrease` decreases the value of `counter` by one.

Be aware that the initial value of an input variable cannot be set in the specification.
Instead, CIF tools like the <<tools-cifsim-chapter-index,CIF simulator>> allow to <<tools-cifsim-chapter-init,set the initial value via an option>>.
