Skip to content

Commit 2aa1ef0

Browse files
release: VisuStruct 1.2.0
Add Kotlin simulation engine and UI (play/step/stop, variables, I/O, diagram spotlight). Bump Maven artifact to 1.2.0, extend i18n, palette Lucide icons for simulation/code/about, macOS packaging tweaks, and tests. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 196770c commit 2aa1ef0

42 files changed

Lines changed: 2968 additions & 36 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ git clone https://github.com/code4teaching/VisuStruct.git
2222

2323
---
2424

25+
## Changes in 1.2.0 (summary)
26+
27+
- **Simulation (prep):** **Kotlin** in the Maven build; **`SimulationDocument`** and related types plus **XML decode** aligned with the existing diagram file format; **`Struktogramm.toSimulationDocument()`** exports the current editor state for a future **`step()`** engine (no simulation UI yet).
28+
29+
Full notes: [`release-notes/v1.2.0.md`](release-notes/v1.2.0.md).
30+
2531
## Changes in 1.1.4 (summary)
2632

2733
- **Diagram:** canvas **view zoom** with **⌘+ / ⌘−** (macOS) or **Ctrl+ / Ctrl−** (Windows/Linux); **no** block resize via mouse wheel anymore.
@@ -127,7 +133,7 @@ This release aligns **branding and technical identity** with **VisuStruct**. **`
127133
- **Java 17** target (build and run with JDK 17+).
128134
- **FlatLaf** light/dark themes; **JDOM2**; no legacy AppleJavaExtensions.
129135
- **Motif** look-and-feel removed; **Metal** and FlatLaf available.
130-
- Current fat JAR name follows **`pom.xml`** **`version`** (e.g. **`visustruct-1.1.4.jar`**).
136+
- Current fat JAR name follows **`pom.xml`** **`version`** (e.g. **`visustruct-1.2.0.jar`**).
131137

132138
---
133139

@@ -202,13 +208,13 @@ chmod +x mvnw
202208
Output (version from `pom.xml`):
203209

204210
```text
205-
target/visustruct-1.1.4.jar
211+
target/visustruct-1.2.0.jar
206212
```
207213

208214
## Run
209215

210216
```bash
211-
java -jar target/visustruct-1.1.4.jar
217+
java -jar target/visustruct-1.2.0.jar
212218
```
213219

214220
Double-click may work if `.jar` is associated with Java.

packaging/macos/build-lightweight-app.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
set -euo pipefail
55
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
66
ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
7-
VER="${PROJECT_VERSION:-1.1.4}"
7+
VER="${PROJECT_VERSION:-1.2.0}"
88
JAR_NAME="visustruct-${VER}.jar"
99
OUT="${ROOT}/dist/macos-app-light"
1010
APP="${OUT}/VisuStruct.app"

packaging/macos/build-macos-app.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Voraussetzung: JDK 17+ mit jpackage (im PATH oder JAVA_HOME).
55
set -euo pipefail
66
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
7-
VER="${PROJECT_VERSION:-1.1.4}"
7+
VER="${PROJECT_VERSION:-1.2.0}"
88
JAR="visustruct-${VER}.jar"
99
INPUT="${ROOT}/target"
1010
OUT="${ROOT}/dist/macos-app"

pom.xml

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>de.visustruct</groupId>
66
<artifactId>visustruct</artifactId>
7-
<version>1.1.4</version>
7+
<version>1.2.0</version>
88
<name>VisuStruct</name>
99

1010
<properties>
1111
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1212
<maven.compiler.release>17</maven.compiler.release>
13+
<kotlin.version>2.0.21</kotlin.version>
1314
</properties>
1415

1516
<scm>
@@ -34,6 +35,17 @@
3435
<artifactId>flatlaf-extras</artifactId>
3536
<version>3.7.1</version>
3637
</dependency>
38+
<dependency>
39+
<groupId>org.jetbrains.kotlin</groupId>
40+
<artifactId>kotlin-stdlib</artifactId>
41+
<version>${kotlin.version}</version>
42+
</dependency>
43+
<dependency>
44+
<groupId>org.junit.jupiter</groupId>
45+
<artifactId>junit-jupiter</artifactId>
46+
<version>5.10.2</version>
47+
<scope>test</scope>
48+
</dependency>
3749
</dependencies>
3850

3951
<build>
@@ -57,6 +69,38 @@
5769
</resource>
5870
</resources>
5971
<plugins>
72+
<!-- Kotlin vor Java kompilieren (Java darf Kotlin-APIs nutzen). -->
73+
<plugin>
74+
<groupId>org.jetbrains.kotlin</groupId>
75+
<artifactId>kotlin-maven-plugin</artifactId>
76+
<version>${kotlin.version}</version>
77+
<executions>
78+
<execution>
79+
<id>compile</id>
80+
<goals>
81+
<goal>compile</goal>
82+
</goals>
83+
<phase>process-sources</phase>
84+
</execution>
85+
<execution>
86+
<id>test-compile</id>
87+
<goals>
88+
<goal>test-compile</goal>
89+
</goals>
90+
<phase>test-compile</phase>
91+
</execution>
92+
</executions>
93+
<configuration>
94+
<jvmTarget>17</jvmTarget>
95+
<!-- Explizite Pfade: Default-Erkennung lieferte in diesem Projekt „No sources“ (z. B. # im Pfad). -->
96+
<sourceDirs>
97+
<sourceDir>src/main/kotlin</sourceDir>
98+
</sourceDirs>
99+
<testSourceDirs>
100+
<testSourceDir>src/test/kotlin</testSourceDir>
101+
</testSourceDirs>
102+
</configuration>
103+
</plugin>
60104
<plugin>
61105
<groupId>org.apache.maven.plugins</groupId>
62106
<artifactId>maven-compiler-plugin</artifactId>

release-notes/v1.2.0.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# VisuStruct 1.2.0
2+
3+
Release **after** **1.1.4** (GitHub `master`).
4+
5+
## Simulation (Kotlin)
6+
7+
- **Kotlin** im Maven-Build (`kotlin-stdlib`, explizite Quellpfade für stabile Kompilierung).
8+
- **Modell** `SimulationDocument` / `SimulationElement` / … und **XML-Decoder** (`StructogramXml`), kompatibel zum bestehenden **`.visustruct` / `<struktogramm>`**-Format (Swift/Java-Parität).
9+
- **Editor-Brücke:** `Struktogramm.toSimulationDocument()` — gleiche XML-Quelle wie Speichern / Rückgängig (`xmlErstellen()`).
10+
- **Laufzeit:** `SimulationEngine` mit schrittweiser Ausführung, **Simulations-Ansicht** (Transport, Variablen, Ausgabe, Eingabe), Diagramm-Hervorhebung (letzter/nächster Schritt).
11+
12+
## Build
13+
14+
- Maven: **`de.visustruct:visustruct:1.2.0`**
15+
- Fat JAR: **`visustruct-1.2.0.jar`** (`./mvnw package``target/`)

src/main/java/de/visustruct/control/CanvasStyle.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public final class CanvasStyle {
3232
private static Color dropPreview;
3333
private static Color dragFrame;
3434
private static Color elementFill;
35+
private static Color simulationStepHighlightFill;
3536

3637
private CanvasStyle() {
3738
}
@@ -54,6 +55,7 @@ private static void applyLightPalette() {
5455
dropPreview = new Color(0x803B82F6, true);
5556
dragFrame = new Color(0x3B82F6);
5657
elementFill = Color.WHITE;
58+
simulationStepHighlightFill = new Color(0xBFDBFE);
5759
}
5860

5961
/** Zeichenfläche spürbar dunkler; Blöcke bleiben hell genug für Lesbarkeit. */
@@ -69,6 +71,7 @@ private static void applyDarkPalette() {
6971
dropPreview = new Color(0x805B9FFF, true);
7072
dragFrame = new Color(0x5B9FFF);
7173
elementFill = new Color(0xECECF0);
74+
simulationStepHighlightFill = new Color(0x1E3A5F);
7275
}
7376

7477
private static boolean isFlatDarkTheme() {
@@ -128,4 +131,9 @@ public static Color getDragFrame() {
128131
public static Color getElementFill() {
129132
return elementFill;
130133
}
134+
135+
/** Hintergrund für den aktuellen Simulations-Schritt im Diagramm. */
136+
public static Color getSimulationStepHighlightFill() {
137+
return simulationStepHighlightFill;
138+
}
131139
}

src/main/java/de/visustruct/control/Controlling.java

Lines changed: 77 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
import de.visustruct.i18n.I18n;
4949
import de.visustruct.other.Helpers;
5050
import de.visustruct.other.XActionCommands;
51+
import de.visustruct.simulation.SimulationEngine;
52+
import de.visustruct.simulation.codec.XmlDecodeException;
53+
import de.visustruct.simulation.model.SimulationDocument;
5154
import de.visustruct.struktogrammelemente.StruktogrammElement;
5255
import de.visustruct.view.AuswahlPanel;
5356
import de.visustruct.view.CodeErzeuger;
@@ -61,6 +64,7 @@ public class Controlling implements Konstanten, ActionListener, WindowListener,
6164
private static final Logger LOG = Logger.getLogger(Controlling.class.getName());
6265

6366
private GUI gui;
67+
private boolean simulationMode;
6468
private enum Betriebssysteme {Windows, Mac, Linux};
6569

6670
public Controlling(String[] params){
@@ -181,6 +185,9 @@ private static Betriebssysteme getOS(){
181185

182186

183187
public Struktogramm gibAktuellesStruktogramm(){
188+
if (gui == null) {
189+
return null;
190+
}
184191
return gui.gibTabbedpane().gibAktuellesStruktogramm();
185192
}
186193

@@ -275,15 +282,6 @@ public void bildSpeichern(){
275282
}
276283
}
277284

278-
public void bildSpeichernNurPng(){
279-
Struktogramm str = gibAktuellesStruktogramm();
280-
281-
if(str != null){
282-
GlobalSettings.setzeBildSpeicherpfad(str.alsBilddateiSpeichernNurPng(GlobalSettings.getZuletztGenutzterPfadFuerBild()));
283-
GlobalSettings.saveSettings();
284-
}
285-
}
286-
287285
public void bildDrucken(){
288286
Struktogramm str = gibAktuellesStruktogramm();
289287
if (str == null) {
@@ -460,6 +458,10 @@ public void actionPerformed(ActionEvent e) {
460458
addStruktogrammbeschriftung();
461459
break;
462460

461+
case simulationToggle:
462+
onSimulationToggle();
463+
break;
464+
463465
}
464466

465467
}
@@ -586,12 +588,78 @@ public GUI getGUI(){
586588
return gui;
587589
}
588590

591+
/** Wechsel des Diagramm-Tabs beendet die Simulation (analog iOS-Moduswechsel). */
592+
public void onStruktogrammTabChanged() {
593+
if (simulationMode) {
594+
endSimulationInternal();
595+
}
596+
}
597+
598+
/** Beendet die Simulation (Menü, Tab-Wechsel, Panel-Button „Zurück“). */
599+
public void leaveSimulationMode() {
600+
if (simulationMode) {
601+
endSimulationInternal();
602+
}
603+
}
604+
605+
public boolean isSimulationMode() {
606+
return simulationMode;
607+
}
608+
609+
/** Gleiche Aktion wie Bearbeiten → Simulation… / Diagramm bearbeiten… (Paletten-Button). */
610+
public void toggleSimulationFromUi() {
611+
onSimulationToggle();
612+
}
613+
614+
private void onSimulationToggle() {
615+
if (simulationMode) {
616+
endSimulationInternal();
617+
} else {
618+
enterSimulation();
619+
}
620+
}
621+
622+
private void enterSimulation() {
623+
if (gui.gibTabbedpane().getTabCount() <= 0) {
624+
return;
625+
}
626+
gui.gibElementEditorPanel().applyPendingTextToDiagram();
627+
Struktogramm str = gibAktuellesStruktogramm();
628+
if (str == null) {
629+
return;
630+
}
631+
try {
632+
SimulationDocument doc = str.toSimulationDocument();
633+
SimulationEngine eng = new SimulationEngine(doc);
634+
simulationMode = true;
635+
gui.getSimulationPanel().setEngine(eng);
636+
gui.showSimulationCard();
637+
gui.setEditSimulationMenuText(I18n.tr("menu.edit.diagramMode"));
638+
aktualisierePalettenBeschriftungen();
639+
} catch (XmlDecodeException ex) {
640+
JOptionPane.showMessageDialog(gui, ex.getMessage(), I18n.tr("simulation.error.title"), JOptionPane.ERROR_MESSAGE);
641+
}
642+
}
643+
644+
private void endSimulationInternal() {
645+
simulationMode = false;
646+
gui.showEditorCard();
647+
gui.getSimulationPanel().clearEngine();
648+
gui.setEditSimulationMenuText(I18n.tr("menu.edit.simulation"));
649+
Struktogramm str = gibAktuellesStruktogramm();
650+
if (str != null) {
651+
str.setzeSimulationSpotlightPfad(null);
652+
}
653+
aktualisierePalettenBeschriftungen();
654+
}
655+
589656

590657

591658

592659

593660

594661
public boolean programmBeendenGeklickt(){
662+
leaveSimulationMode();
595663
if(gui.gibTabbedpane().einOderMehrereStruktogrammeNichtGespeichert()){
596664
Object[] options = { I18n.tr("dialog.exitUnsaved.quit"), I18n.tr("dialog.exitUnsaved.stay") };
597665
int r = JOptionPane.showOptionDialog(gui, I18n.tr("dialog.exitUnsaved.message"),

0 commit comments

Comments
 (0)