Skip to content
This repository was archived by the owner on Nov 7, 2026. It is now read-only.

Commit 5abe9cf

Browse files
Merge pull request #29 from code4teaching/palette-actions
Palette: Teilen, Export und Info ins Ablage-Menü
2 parents ef47150 + 4f5da50 commit 5abe9cf

3 files changed

Lines changed: 93 additions & 74 deletions

File tree

‎VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ContentView.swift‎

Lines changed: 19 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,21 @@ struct ContentView: View {
249249
printDiagram()
250250
#endif
251251
}
252+
.onReceive(NotificationCenter.default.publisher(for: DiagramMenuNotification.sharePNG)) { _ in
253+
guard !isSimulationMode else { return }
254+
exportPNG()
255+
}
256+
.onReceive(NotificationCenter.default.publisher(for: DiagramMenuNotification.shareDocument)) { _ in
257+
guard !isSimulationMode else { return }
258+
shareDocumentAsFile()
259+
}
260+
.onReceive(NotificationCenter.default.publisher(for: DiagramMenuNotification.exportPDF)) { _ in
261+
guard !isSimulationMode else { return }
262+
shareDiagramPDF()
263+
}
264+
.onReceive(NotificationCenter.default.publisher(for: DiagramMenuNotification.showAbout)) { _ in
265+
showInfo = true
266+
}
252267
.onReceive(NotificationCenter.default.publisher(for: DiagramMenuNotification.close)) { _ in
253268
guard !isSimulationMode else { return }
254269
requestCloseDiagramTab(id: tabsModel.selectedTabId)
@@ -599,65 +614,6 @@ struct ContentView: View {
599614
.accessibilityLabel(
600615
codeGeneratorAccessGranted ? lang.tr("a11y_generate_code") : lang.tr("a11y_generate_code_locked")
601616
)
602-
Button {
603-
exportPNG()
604-
} label: {
605-
Label(lang.tr("action_share_png"), systemImage: "square.and.arrow.up")
606-
.foregroundStyle(isSimulationMode ? .tertiary : .primary)
607-
}
608-
.buttonStyle(PaletteListElementButtonStyle())
609-
.disabledAndDimmed(isSimulationMode)
610-
.listRowInsets(
611-
isCompact
612-
? EdgeInsets(top: 3, leading: 10, bottom: 3, trailing: 10)
613-
: EdgeInsets(top: 5, leading: 12, bottom: 5, trailing: 12)
614-
)
615-
.listRowSeparator(.hidden)
616-
.listRowBackground(Color.clear)
617-
Button {
618-
shareDocumentAsFile()
619-
} label: {
620-
Label(lang.tr("action_share_document"), systemImage: "square.and.arrow.up.on.square")
621-
.foregroundStyle(isSimulationMode ? .tertiary : .primary)
622-
}
623-
.buttonStyle(PaletteListElementButtonStyle())
624-
.disabledAndDimmed(isSimulationMode)
625-
.listRowInsets(
626-
isCompact
627-
? EdgeInsets(top: 3, leading: 10, bottom: 3, trailing: 10)
628-
: EdgeInsets(top: 5, leading: 12, bottom: 5, trailing: 12)
629-
)
630-
.listRowSeparator(.hidden)
631-
.listRowBackground(Color.clear)
632-
Button {
633-
shareDiagramPDF()
634-
} label: {
635-
Label(lang.tr("action_export_pdf"), systemImage: "doc.text.magnifyingglass")
636-
.foregroundStyle(isSimulationMode ? .tertiary : .primary)
637-
}
638-
.buttonStyle(PaletteListElementButtonStyle())
639-
.disabledAndDimmed(isSimulationMode)
640-
.listRowInsets(
641-
isCompact
642-
? EdgeInsets(top: 3, leading: 10, bottom: 3, trailing: 10)
643-
: EdgeInsets(top: 5, leading: 12, bottom: 5, trailing: 12)
644-
)
645-
.listRowSeparator(.hidden)
646-
.listRowBackground(Color.clear)
647-
648-
Button {
649-
showInfo = true
650-
} label: {
651-
Label(lang.tr("action_about"), systemImage: "info.circle")
652-
}
653-
.buttonStyle(PaletteListElementButtonStyle())
654-
.listRowInsets(
655-
isCompact
656-
? EdgeInsets(top: 3, leading: 10, bottom: 4, trailing: 10)
657-
: EdgeInsets(top: 5, leading: 12, bottom: 8, trailing: 12)
658-
)
659-
.listRowSeparator(.hidden)
660-
.listRowBackground(Color.clear)
661617
}
662618
}
663619
.listStyle(.insetGrouped)
@@ -754,6 +710,10 @@ struct ContentView: View {
754710
onSave: performPrimarySave,
755711
onSaveAs: { showExporter = true },
756712
onPrint: printAction,
713+
onSharePNG: exportPNG,
714+
onShareDocument: shareDocumentAsFile,
715+
onExportPDF: shareDiagramPDF,
716+
onShowAbout: { showInfo = true },
757717
onKeyboardDismiss: {
758718
focusedField = nil
759719
if isPhone { hideInspectorOnPhone = true }

‎VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Toolbar/DiagramMainEditorToolbar.swift‎

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import SwiftUI
22

3-
/// Hauptfenster-Toolbar: Titel, Undo/Redo, Datei-Menü, Palette (iPhone), Tastatur „Fertig“.
3+
/// Hauptfenster-Toolbar: Titel, Undo/Redo, Datei-Menü (inkl. Teilen/Export und Info), Palette (iPhone), Tastatur „Fertig“.
44
/// Diagramm-Reiter liegen in `DiagramTabStrip`.
55
struct DiagramMainEditorToolbar: ToolbarContent {
66
@Environment(\.appLanguage) private var lang
@@ -29,6 +29,11 @@ struct DiagramMainEditorToolbar: ToolbarContent {
2929
/// Nur unter UIKit (Druck); sonst `nil` und kein Eintrag.
3030
let onPrint: (() -> Void)?
3131

32+
let onSharePNG: () -> Void
33+
let onShareDocument: () -> Void
34+
let onExportPDF: () -> Void
35+
let onShowAbout: () -> Void
36+
3237
let onKeyboardDismiss: () -> Void
3338

3439
var body: some ToolbarContent {
@@ -76,8 +81,8 @@ struct DiagramMainEditorToolbar: ToolbarContent {
7681
Menu {
7782
Button(action: onOpenImporter) {
7883
Label(lang.tr("menu_open"), systemImage: "square.and.arrow.down")
79-
.foregroundStyle(isSimulationMode ? .tertiary : .primary)
8084
}
85+
.disabled(isSimulationMode)
8186
Menu {
8287
if recentFiles.isEmpty {
8388
Text(lang.tr("recent_files_empty"))
@@ -97,26 +102,43 @@ struct DiagramMainEditorToolbar: ToolbarContent {
97102
} label: {
98103
Label(lang.tr("recent_files_menu"), systemImage: "clock")
99104
}
105+
.disabled(isSimulationMode)
100106
Divider()
101-
Button(action: onSave) {
102-
Label(lang.tr("menu_save"), systemImage: "arrow.down.doc")
103-
}
104-
Button(action: onSaveAs) {
105-
Label(lang.tr("menu_save_as"), systemImage: "square.and.arrow.up")
107+
Group {
108+
Button(action: onSave) {
109+
Label(lang.tr("menu_save"), systemImage: "arrow.down.doc")
110+
}
111+
Button(action: onSaveAs) {
112+
Label(lang.tr("menu_save_as"), systemImage: "square.and.arrow.up")
113+
}
106114
}
107-
#if canImport(UIKit)
108-
if let onPrint {
109-
Divider()
110-
Button(action: onPrint) {
111-
Label(lang.tr("menu_print"), systemImage: "printer")
115+
.disabled(isSimulationMode)
116+
Section {
117+
Button(action: onShareDocument) {
118+
Label(lang.tr("action_share_document"), systemImage: "square.and.arrow.up.on.square")
119+
}
120+
Button(action: onSharePNG) {
121+
Label(lang.tr("action_share_png"), systemImage: "photo")
122+
}
123+
Button(action: onExportPDF) {
124+
Label(lang.tr("action_export_pdf"), systemImage: "doc.text.magnifyingglass")
112125
}
126+
#if canImport(UIKit)
127+
if let onPrint {
128+
Button(action: onPrint) {
129+
Label(lang.tr("menu_print"), systemImage: "printer")
130+
}
131+
}
132+
#endif
133+
}
134+
.disabled(isSimulationMode)
135+
Divider()
136+
Button(action: onShowAbout) {
137+
Label(lang.tr("action_about"), systemImage: "info.circle")
113138
}
114-
#endif
115139
} label: {
116140
Label(lang.tr("menu_file"), systemImage: "folder")
117-
.foregroundStyle(isSimulationMode ? .tertiary : .primary)
118141
}
119-
.disabledAndDimmed(isSimulationMode)
120142
}
121143
#if canImport(UIKit)
122144
ToolbarItemGroup(placement: .keyboard) {

‎VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/VisuStructApp.swift‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ enum DiagramMenuNotification {
4747
static let printDocument = Notification.Name("visustruct.menu.print")
4848
static let close = Notification.Name("visustruct.menu.close")
4949
static let openRecent = Notification.Name("visustruct.menu.openRecent")
50+
static let sharePNG = Notification.Name("visustruct.menu.sharePNG")
51+
static let shareDocument = Notification.Name("visustruct.menu.shareDocument")
52+
static let exportPDF = Notification.Name("visustruct.menu.exportPDF")
53+
static let showAbout = Notification.Name("visustruct.menu.showAbout")
5054

5155
static let recentFileIDKey = "id"
5256
}
@@ -124,6 +128,22 @@ final class DiagramCommandCenter: ObservableObject {
124128
NotificationCenter.default.post(name: DiagramMenuNotification.close, object: nil)
125129
}
126130

131+
func sharePNG() {
132+
NotificationCenter.default.post(name: DiagramMenuNotification.sharePNG, object: nil)
133+
}
134+
135+
func shareDocument() {
136+
NotificationCenter.default.post(name: DiagramMenuNotification.shareDocument, object: nil)
137+
}
138+
139+
func exportPDF() {
140+
NotificationCenter.default.post(name: DiagramMenuNotification.exportPDF, object: nil)
141+
}
142+
143+
func showAbout() {
144+
NotificationCenter.default.post(name: DiagramMenuNotification.showAbout, object: nil)
145+
}
146+
127147
func openRecent(_ file: RecentVisuStructFile) {
128148
NotificationCenter.default.post(
129149
name: DiagramMenuNotification.openRecent,
@@ -297,6 +317,11 @@ private struct VisuStructCommands: Commands {
297317
}
298318

299319
var body: some Commands {
320+
CommandGroup(replacing: .appInfo) {
321+
Button(lang.tr("action_about")) {
322+
commandCenter.showAbout()
323+
}
324+
}
300325
CommandGroup(replacing: .newItem) {
301326
Button(lang.tr("menu_new")) {
302327
commandCenter.newDocument()
@@ -316,6 +341,18 @@ private struct VisuStructCommands: Commands {
316341
.keyboardShortcut("s", modifiers: [.command, .shift])
317342
.disabled(!commandCenter.canSaveAs)
318343
Divider()
344+
Button(lang.tr("action_share_document")) {
345+
commandCenter.shareDocument()
346+
}
347+
.disabled(!commandCenter.canPrint)
348+
Button(lang.tr("action_share_png")) {
349+
commandCenter.sharePNG()
350+
}
351+
.disabled(!commandCenter.canPrint)
352+
Button(lang.tr("action_export_pdf")) {
353+
commandCenter.exportPDF()
354+
}
355+
.disabled(!commandCenter.canPrint)
319356
Button(lang.tr("menu_print")) {
320357
commandCenter.printDocument()
321358
}

0 commit comments

Comments
 (0)