Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8c92504
Extract PaletteActionList and SimulationDetailView from ContentView
claude Oct 18, 2026
fc3ecc7
Move inspector hints and Fallauswahl path helpers out of ContentView
claude Oct 18, 2026
eb79ba5
Bundle PNG, file, PDF and print export in DiagramExporter
claude Oct 18, 2026
3ae4ee1
Split DiagramCanvasView into view, drop zones and renderer
claude Oct 18, 2026
cbf53ae
Merge branch 'palette-view' into inspector-helpers
claude Oct 19, 2026
d852cb9
Merge simulation-controller into palette-view
claude Oct 19, 2026
d2972b4
Merge branch 'inspector-helpers' into export-actions
claude Oct 19, 2026
55fd215
Merge branch 'export-actions' into canvas-split
claude Oct 19, 2026
a2a3759
Merge branch 'palette-view' into inspector-helpers
claude Oct 19, 2026
fab9f8f
Merge branch 'simulation-controller' into palette-view
claude Oct 19, 2026
820be7d
Merge branch 'inspector-helpers' into export-actions
claude Oct 19, 2026
3057857
Merge export-actions into canvas-split
claude Oct 19, 2026
a7b0a39
Merge branch 'palette-view' into inspector-helpers
claude Oct 19, 2026
9bf2f73
Merge branch 'simulation-controller' into palette-view
claude Oct 19, 2026
6ad16af
Merge branch 'export-actions' into canvas-split
claude Oct 19, 2026
2cf9ea9
Merge branch 'inspector-helpers' into export-actions
claude Oct 19, 2026
14d0997
Merge pull request #18 from code4teaching/canvas-split
code4teaching Oct 19, 2026
69d6259
Merge pull request #17 from code4teaching/export-actions
code4teaching Oct 19, 2026
74ec7ac
Merge pull request #16 from code4teaching/inspector-helpers
code4teaching Oct 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Foundation

extension VisuStructDocumentEditing {
/// Innerste **Fallauswahl** (`multiway`), die `path` enthält (oder selbst ist) — für „Fall hinzufügen/entfernen“.
public static func multiwayAncestorPath(for path: [Int]?, in doc: VisuStructDocument) -> [Int]? {
guard let path, !path.isEmpty else { return nil }
for len in stride(from: path.count, through: 1, by: -1) {
let prefix = Array(path.prefix(len))
if let el = try? element(at: prefix, in: doc),
el.type == .fallauswahl {
return prefix
}
}
return nil
}

/// Spaltenindex der Fallauswahl, wenn die Auswahl **in** einer Spalte liegt (`[…, fall, spalte, …]`).
public static func caseIndex(of selectedPath: [Int]?, inMultiwayAt multiwayPath: [Int]) -> Int? {
guard let sp = selectedPath, sp.count > multiwayPath.count else { return nil }
return sp[multiwayPath.count]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import XCTest
import VisuStructCore

final class MultiwayPathTests: XCTestCase {
/// `[0]` Anweisung, `[1]` Fallauswahl mit zwei Fällen; im zweiten Fall eine innere Fallauswahl `[1, 1, 0]`.
private func document() -> VisuStructDocument {
let statement = VisuStructElement(type: .anweisung, textLines: ["x = 1"])
let inner = VisuStructElement(
type: .fallauswahl,
textLines: ["y"],
cases: [
VisuStructCase(name: "1", elements: [statement]),
VisuStructCase(name: "default", elements: [statement]),
]
)
let outer = VisuStructElement(
type: .fallauswahl,
textLines: ["x"],
cases: [
VisuStructCase(name: "1", elements: [statement]),
VisuStructCase(name: "default", elements: [inner]),
]
)
var doc = VisuStructDocumentEditing.newEmpty()
doc.elements = [statement, outer]
return doc
}

func testAncestorIsInnermostFallauswahl() {
let doc = document()
XCTAssertNil(VisuStructDocumentEditing.multiwayAncestorPath(for: nil, in: doc))
XCTAssertNil(VisuStructDocumentEditing.multiwayAncestorPath(for: [0], in: doc))
XCTAssertEqual(VisuStructDocumentEditing.multiwayAncestorPath(for: [1], in: doc), [1])
XCTAssertEqual(VisuStructDocumentEditing.multiwayAncestorPath(for: [1, 0, 0], in: doc), [1])
XCTAssertEqual(VisuStructDocumentEditing.multiwayAncestorPath(for: [1, 1, 0], in: doc), [1, 1, 0])
XCTAssertEqual(VisuStructDocumentEditing.multiwayAncestorPath(for: [1, 1, 0, 1, 0], in: doc), [1, 1, 0])
}

func testCaseIndex() {
XCTAssertNil(VisuStructDocumentEditing.caseIndex(of: [1], inMultiwayAt: [1]))
XCTAssertNil(VisuStructDocumentEditing.caseIndex(of: nil, inMultiwayAt: [1]))
XCTAssertEqual(VisuStructDocumentEditing.caseIndex(of: [1, 1, 0], inMultiwayAt: [1]), 1)
}
}
Loading
Loading