diff --git a/AppStore.xcassets/screenshot-color-key.imageset/Contents.json b/AppStore.xcassets/screenshot-color-key.imageset/Contents.json new file mode 100644 index 0000000..918ae70 --- /dev/null +++ b/AppStore.xcassets/screenshot-color-key.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "screenshot-color-key.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AppStore.xcassets/screenshot-color-key.imageset/screenshot-color-key.png b/AppStore.xcassets/screenshot-color-key.imageset/screenshot-color-key.png new file mode 100644 index 0000000..c5a308a Binary files /dev/null and b/AppStore.xcassets/screenshot-color-key.imageset/screenshot-color-key.png differ diff --git a/AppStore.xcassets/screenshot-color-picker.imageset/Contents.json b/AppStore.xcassets/screenshot-color-picker.imageset/Contents.json new file mode 100644 index 0000000..f1ee404 --- /dev/null +++ b/AppStore.xcassets/screenshot-color-picker.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "screenshot-color-picker.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AppStore.xcassets/screenshot-color-picker.imageset/screenshot-color-picker.png b/AppStore.xcassets/screenshot-color-picker.imageset/screenshot-color-picker.png new file mode 100644 index 0000000..fe7858e Binary files /dev/null and b/AppStore.xcassets/screenshot-color-picker.imageset/screenshot-color-picker.png differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 26588d1..80ff931 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,31 @@ ## [Unreleased](https://gitlab.com/html-validate/html-validate/compare/Unreleased) () +### Features + + - **PlantUMLContentView** add saving state indicator ([a2ac033e07e874a](https://gitlab.com/html-validate/html-validate/commit/a2ac033e07e874a23cccc7c62e3489fbf61bd2a9)) + - (SwiftUI+Conditional) add conditional view extension ([1f5b822dacbebb8](https://gitlab.com/html-validate/html-validate/commit/1f5b822dacbebb813314d4c7df1bf9c3c441b7cb)) + - manage auto save document ([e1b9d4bccc235c6](https://gitlab.com/html-validate/html-validate/commit/e1b9d4bccc235c6df8fcf192033e6078be024f54)) + - complete 'Save Custom Keyboard state' feature ([af060cd8bbe8d21](https://gitlab.com/html-validate/html-validate/commit/af060cd8bbe8d21e9847481fb1a163fd459ef664)) + - add support for color button on custom keyboard that opens a color picker ([e93686ee94a86ea](https://gitlab.com/html-validate/html-validate/commit/e93686ee94a86ea2a5c1c13c70f19756df3250d5)) + - **DebounceObject** add Debounce utility ([7e17ee05ade68b3](https://gitlab.com/html-validate/html-validate/commit/7e17ee05ade68b3a09ac6490aa6ae128569e8cba)) + - start implementation of support for ColorPicker Key in custom keyboard ([f919613f397870d](https://gitlab.com/html-validate/html-validate/commit/f919613f397870d80b37f7f2182784f4308d9208)) + + +### Documentation + + - **readme** update readme ([bcee03131792841](https://gitlab.com/html-validate/html-validate/commit/bcee03131792841980a806d166fc2cf40d2293a0)) +### Refactor + - move PlantUMLDocument in PlantUMLDocumentProxy ([aa37d8c80a8afae](https://gitlab.com/html-validate/html-validate/commit/aa37d8c80a8afae1634a4347a40e7f5ddf527182)) +### ALM + - set next version build ([caf494a0fefa965](https://gitlab.com/html-validate/html-validate/commit/caf494a0fefa965f71050cc69c4196e8996990f1)) + - update line editor package ([98e6d07c1cc7133](https://gitlab.com/html-validate/html-validate/commit/98e6d07c1cc71338e63cd766216dda1e04c37fd7)) + - upgrade version from 1.0 to 1.1 ([8869f4cea125167](https://gitlab.com/html-validate/html-validate/commit/8869f4cea125167c701d69c24d92f94fd546b3d5)) + - **usersettings.json** update configuration ([e522bbd48961481](https://gitlab.com/html-validate/html-validate/commit/e522bbd48961481e4b6caf40fbe03f9d2e75e38c)) "name: v1.0.14" is a release tag diff --git a/PlantUML/PlantUMLApp.swift b/PlantUML/PlantUMLApp.swift index c7e63c4..ef27688 100644 --- a/PlantUML/PlantUMLApp.swift +++ b/PlantUML/PlantUMLApp.swift @@ -9,7 +9,7 @@ import SwiftUI @main struct PlantUMLApp: App { - + init() { URLCache.shared.memoryCapacity = 10_000_000 // ~10 MB memory space URLCache.shared.diskCapacity = 100_000_000 // ~1GB disk cache space @@ -17,11 +17,16 @@ struct PlantUMLApp: App { var body: some Scene { DocumentGroup(newDocument: PlantUMLDocument()) { file in - - PlantUMLContentView(document: file.$document) -// .environment(\.editMode, Binding.constant(EditMode.active)) - .environmentObject( PlantUMLDiagramObject( document: file.document)) - + if #available(iOS 16, *) { + PlantUMLContentView( + document: PlantUMLDocumentProxy( document: file.$document) ) + // [Document based app shows 2 back chevrons on iPad](https://stackoverflow.com/a/74245034/521197) + .toolbarRole(.navigationStack) + } + else { + PlantUMLContentView( + document: PlantUMLDocumentProxy( document: file.$document)) + } } } } diff --git a/PlantUML/PlantUMLContentView.swift b/PlantUML/PlantUMLContentView.swift index 312ad34..9e25c6f 100644 --- a/PlantUML/PlantUMLContentView.swift +++ b/PlantUML/PlantUMLContentView.swift @@ -19,16 +19,15 @@ import LineEditor // case row(id: String) // } -typealias PlantUMLLineEditorView = LineEditorView struct PlantUMLContentView: View { + typealias PlantUMLLineEditorView = LineEditorView + @Environment(\.editMode) private var editMode @Environment(\.openURL) private var openURL @State var keyboardTab: String = "general" - @EnvironmentObject private var diagram: PlantUMLDiagramObject - - @Binding var document: PlantUMLDocument + @StateObject var document: PlantUMLDocumentProxy @State private var isEditorVisible = true //@State private var isPreviewVisible = false @@ -36,29 +35,36 @@ struct PlantUMLContentView: View { @State private var isScaleToFit = true @State private var fontSize = CGFloat(12) - @State var showLine:Bool = false + @State private var showLine:Bool = false - @State var diagramImage:UIImage? + @State private var diagramImage:UIImage? - var PlantUMLDiagramViewFit: some View { - PlantUMLDiagramView( url: diagram.buildURL(), contentMode: .fit ) - } + @State private var saving = false var body: some View { + GeometryReader { geometry in HStack { if( isEditorVisible ) { - PlantUMLLineEditorView( items: $diagram.items, + PlantUMLLineEditorView( items: $document.items, fontSize: $fontSize, showLine: $showLine) { onHide, onPressSymbol in PlantUMLKeyboardView( selectedTab: $keyboardTab, onHide: onHide, onPressSymbol: onPressSymbol) } - - + .onChange(of: document.items ) { _ in + saving = true + document.updateRequest.send() + } + .onReceive(document.updateRequest.publisher) { _ in + withAnimation(.easeInOut(duration: 1.0)) { + document.save() + saving = false + } + } } -// Divider().background(Color.blue).padding() + // Divider().background(Color.blue).padding() if isDiagramVisible { if isScaleToFit { @@ -67,29 +73,29 @@ struct PlantUMLContentView: View { } else { ScrollView([.horizontal, .vertical], showsIndicators: true) { - PlantUMLDiagramView( url: diagram.buildURL(), contentMode: .fill ) + PlantUMLDiagramView( url: document.buildURL(), contentMode: .fill ) .frame( minWidth: geometry.size.width) } .frame( minWidth: geometry.size.width, minHeight: geometry.size.height ) } } - + } + //.navigationBarTitleDisplayMode(.inline) .onRotate(perform: { orientation in if (orientation.isPortrait && isDiagramVisible) || - (orientation.isLandscape && isEditorVisible) + (orientation.isLandscape && isEditorVisible) { isEditorVisible.toggle() } }) - .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItemGroup(placement: .navigationBarLeading) { if isEditorVisible { HStack { - SaveButton() + // SaveButton() + // Divider().background(Color.blue).padding(10) EditButton() - Divider().background(Color.blue).padding(10) fontSizeView() toggleLineNumberView() } @@ -97,24 +103,79 @@ struct PlantUMLContentView: View { } ToolbarItemGroup(placement: .navigationBarTrailing) { HStack( spacing: 0 ) { + SavingStateView( saving: saving ) ToggleEditorButton() - TogglePreviewButton() + ToggleDiagramButton() if isDiagramVisible { ScaleToFitButton() ShareDiagramButton() } } } - } + + } + + } + + var PlantUMLDiagramViewFit: some View { + PlantUMLDiagramView( url: document.buildURL(), contentMode: .fit ) + } + +} + +// +// MARK: - Editor actions - +// +extension PlantUMLContentView { + + // [SwiftUI Let View disappear automatically](https://stackoverflow.com/a/60820491/521197) + struct SavedStateView: View { + @Binding var visible: Bool + let timer = Timer.publish(every: 5.0, on: .main, in: .common).autoconnect() + + var body: some View { + + Text("_saved_" ) + .onReceive(timer) { _ in + withAnimation { + self.visible.toggle() + } + } + .transition( AnyTransition.asymmetric(insertion: .scale, removal: .opacity)) + } + } + + struct SavingStateView: View { + var saving:Bool + @State private var visible = false + + var body: some View { + HStack(alignment: .bottom, spacing: 5) { + if( saving ) { + ProgressView() + Text( "_saving..._") + .onAppear { + visible = true + } + } + else { + if visible { + PlantUMLContentView.SavedStateView( visible: $visible ) + } + } + } + .foregroundColor(Color.secondary) + .frame( maxWidth: 100 ) } + } func toggleLineNumberView() -> some View { Button( action: { showLine.toggle() } ) { Image( systemName: "list.number") } - + } func fontSizeView() -> some View { @@ -123,27 +184,57 @@ struct PlantUMLContentView: View { Image( systemName: "textformat.size.larger") } .padding( EdgeInsets(top:0, leading: 5,bottom: 0, trailing: 0)) - Divider().background(Color.blue) + Divider().background(Color.blue).frame(height:20) Button( action: { fontSize -= 1} ) { Image( systemName: "textformat.size.smaller") } .padding( EdgeInsets(top:0, leading: 5,bottom: 0, trailing: 0)) } -// .overlay { -// RoundedRectangle(cornerRadius: 16) -// .stroke(.blue, lineWidth: 1) -// } - .padding() + // .overlay { + // RoundedRectangle(cornerRadius: 16) + // .stroke(.blue, lineWidth: 1) + // } + //.padding() } + + func ToggleEditorButton() -> some View { + + Button { + if !isEditorVisible { + withAnimation { + diagramImage = nil // avoid popup of share image UIActivityViewController + isEditorVisible.toggle() + } + } + } + label: { + // Label( "Toggle Editor", systemImage: "rectangle.lefthalf.inset.filled" ) + Label( "Toggle Editor", systemImage: "doc.plaintext.fill" ) + .labelStyle(.iconOnly) + .foregroundColor( isEditorVisible ? .blue : .gray) + } + } + + @available(swift, obsoleted: 1.1,message: "from 1.1 auto save has been introduced") func SaveButton() -> some View { - Button( action: saveToDocument ) { + Button( action: { + document.save() + }, + label: { Label( "Save", systemImage: "arrow.down.doc.fill" ) .labelStyle(.titleOnly) - } + }) } + +} +// +// MARK: - Diagram actions +// +extension PlantUMLContentView { + func ShareDiagramButton() -> some View { Button(action: { @@ -157,17 +248,17 @@ struct PlantUMLContentView: View { } } - + } - + func ScaleToFitButton() -> some View { Toggle("fit image", isOn: $isScaleToFit) .toggleStyle(ScaleToFitToggleStyle()) - + } - - func TogglePreviewButton() -> some View { + + func ToggleDiagramButton() -> some View { Button { if isEditorVisible { @@ -177,47 +268,22 @@ struct PlantUMLContentView: View { } } } - label: { -// Label( "Toggle Preview", systemImage: "rectangle.righthalf.inset.filled" ) - Label( "Toggle Preview", systemImage: "photo.fill" ) - - .labelStyle(.iconOnly) - .foregroundColor( isDiagramVisible ? .blue : .gray) - - } - } - - func ToggleEditorButton() -> some View { + label: { + // Label( "Toggle Preview", systemImage: "rectangle.righthalf.inset.filled" ) + Label( "Toggle Preview", systemImage: "photo.fill" ) + + .labelStyle(.iconOnly) + .foregroundColor( isDiagramVisible ? .blue : .gray) - Button { - if !isEditorVisible { - withAnimation { - diagramImage = nil // avoid popup of share image UIActivityViewController - isEditorVisible.toggle() - } - } - } - label: { -// Label( "Toggle Editor", systemImage: "rectangle.lefthalf.inset.filled" ) - Label( "Toggle Editor", systemImage: "doc.plaintext.fill" ) - .labelStyle(.iconOnly) - .foregroundColor( isEditorVisible ? .blue : .gray) - - } } - - -} - -// MARK: ACTIONS -extension PlantUMLContentView { - - internal func saveToDocument() { - document.text = diagram.description } - + + + } + +// MARK: - Preview - struct ContentView_Previews: PreviewProvider { static var text = """ @@ -235,22 +301,21 @@ myactor -> participant1 Group { NavigationView { - PlantUMLContentView(document: .constant(PlantUMLDocument())) + PlantUMLContentView( document: PlantUMLDocumentProxy( document: .constant(PlantUMLDocument()))) .previewDevice(PreviewDevice(rawValue: "iPad mini (6th generation)")) .environment(\.editMode, Binding.constant(EditMode.inactive)) - .environmentObject( PlantUMLDiagramObject( text: text) ) } .navigationViewStyle(.stack) .previewInterfaceOrientation(.landscapeRight) - + NavigationView { - PlantUMLContentView(document: .constant(PlantUMLDocument())) + PlantUMLContentView( document: PlantUMLDocumentProxy( document: .constant(PlantUMLDocument()))) .previewDevice(PreviewDevice(rawValue: "iPad mini (6th generation)")) .environment(\.editMode, Binding.constant(EditMode.inactive)) - .environmentObject( PlantUMLDiagramObject( text: text) ) } .navigationViewStyle(.stack) .previewInterfaceOrientation(.portrait) } } } + diff --git a/PlantUML/PlantUMLDiagramObject.swift b/PlantUML/PlantUMLDiagramObject.swift deleted file mode 100644 index 4a6f261..0000000 --- a/PlantUML/PlantUMLDiagramObject.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// PlantUMLDiagramBuilder.swift -// PlantUML -// -// Created by Bartolomeo Sorrentino on 03/08/22. -// - -import Foundation -import PlantUMLFramework - -class PlantUMLDiagramObject : ObservableObject, CustomStringConvertible { - - @Published var items:Array - - var description: String { - self.items.map { $0.rawValue }.joined( separator: "\n" ) - } - - let presenter = PlantUMLBrowserPresenter( format: .imagePng ) - - init( text: String ) { - self.items = - text - .split(whereSeparator: \.isNewline) - .map { line in - SyntaxStructure( rawValue: String(line) ) - } - - } - - convenience init( document: PlantUMLDocument ) { - - self.init(text: document.text ) - } - - func buildURL() -> URL { - let script = PlantUMLScript( items: items ) - - return presenter.url( of: script ) - } - - -} diff --git a/PlantUML/PlantUMLDocumentProxy.swift b/PlantUML/PlantUMLDocumentProxy.swift new file mode 100644 index 0000000..e0cc0c4 --- /dev/null +++ b/PlantUML/PlantUMLDocumentProxy.swift @@ -0,0 +1,67 @@ +// +// PlantUMLDiagramBuilder.swift +// PlantUML +// +// Created by Bartolomeo Sorrentino on 03/08/22. +// + +import Foundation +import PlantUMLFramework +import Combine +import SwiftUI + +class DebounceRequest { + + private var requestSubject = PassthroughSubject() + + public let publisher:AnyPublisher + + init( debounceInSeconds seconds: Double ) { + + publisher = requestSubject + .debounce(for: .seconds(seconds), scheduler: RunLoop.main) + .eraseToAnyPublisher() + + } + + func send() { + requestSubject.send(()) + } +} + +class PlantUMLDocumentProxy : ObservableObject, CustomStringConvertible { + + @Binding var object: PlantUMLDocument + @Published var items:Array + + let updateRequest = DebounceRequest( debounceInSeconds: 0.5) + + var description: String { + self.items.map { $0.rawValue }.joined( separator: "\n" ) + } + + let presenter = PlantUMLBrowserPresenter( format: .imagePng ) + + init( document: Binding ) { + print( "PlantUMLDiagramObject.init" ) + self._object = document + self.items = document.wrappedValue.text + .split(whereSeparator: \.isNewline) + .map { line in + SyntaxStructure( rawValue: String(line) ) + } + } + + func buildURL() -> URL { + let script = PlantUMLScript( items: items ) + + return presenter.url( of: script ) + } + + func save() { + print( "save document") + self.object.text = self.description + } + + +} diff --git a/PlantUML/SwiftUI+Conditional.swift b/PlantUML/SwiftUI+Conditional.swift new file mode 100644 index 0000000..14862af --- /dev/null +++ b/PlantUML/SwiftUI+Conditional.swift @@ -0,0 +1,32 @@ +// +// SwiftUI+Conditional.swift +// PlantUMLApp +// +// Created by Bartolomeo Sorrentino on 18/01/23. +// + +import SwiftUI + +// +// This extension lets us add the .if modifier to our Views and will only apply the modifiers we add if the condition is met. +// +// inspired by [Conditional modifier](https://designcode.io/swiftui-handbook-conditional-modifier) +extension View { + + @ViewBuilder func `if`(_ condition: Bool, then transform: (Self) -> Content) -> some View { + if condition { + transform(self) + } else { + self + } + } + + @ViewBuilder func `if`(_ condition: Bool, then transformThen: (Self) -> Content, else transformElse: (Self) -> Content ) -> some View { + if condition { + transformThen(self) + } else { + transformElse(self) + } + } + +} diff --git a/PlantUMLApp.xcodeproj/project.pbxproj b/PlantUMLApp.xcodeproj/project.pbxproj index 8c2a008..f95dc07 100644 --- a/PlantUMLApp.xcodeproj/project.pbxproj +++ b/PlantUMLApp.xcodeproj/project.pbxproj @@ -12,13 +12,14 @@ A043CE7C28E08C4C005A3AF7 /* PlantUMLKeyboard in Frameworks */ = {isa = PBXBuildFile; productRef = A043CE7B28E08C4C005A3AF7 /* PlantUMLKeyboard */; }; A047206F29549ACC007E061F /* SwiftUI+Share.swift in Sources */ = {isa = PBXBuildFile; fileRef = A047206E29549ACC007E061F /* SwiftUI+Share.swift */; }; A047207029549ACC007E061F /* SwiftUI+Share.swift in Sources */ = {isa = PBXBuildFile; fileRef = A047206E29549ACC007E061F /* SwiftUI+Share.swift */; }; + A05923192978106B00A1E12F /* SwiftUI+Conditional.swift in Sources */ = {isa = PBXBuildFile; fileRef = A05923182978106B00A1E12F /* SwiftUI+Conditional.swift */; }; A08AA78429561170004DE329 /* View+UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A08AA78329561170004DE329 /* View+UIImage.swift */; }; A0943A6F2944A44900342426 /* ScaleToFit+ToggleStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0943A6E2944A44900342426 /* ScaleToFit+ToggleStyle.swift */; }; A0943A702944A44900342426 /* ScaleToFit+ToggleStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0943A6E2944A44900342426 /* ScaleToFit+ToggleStyle.swift */; }; A0A42A76289ABC2D00E929EB /* PlantUMLDiagramView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A42A75289ABC2D00E929EB /* PlantUMLDiagramView.swift */; }; A0A42A77289ABC2D00E929EB /* PlantUMLDiagramView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A42A75289ABC2D00E929EB /* PlantUMLDiagramView.swift */; }; - A0A42A79289AC37C00E929EB /* PlantUMLDiagramObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A42A78289AC37C00E929EB /* PlantUMLDiagramObject.swift */; }; - A0A42A7A289AC37C00E929EB /* PlantUMLDiagramObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A42A78289AC37C00E929EB /* PlantUMLDiagramObject.swift */; }; + A0A42A79289AC37C00E929EB /* PlantUMLDocumentProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A42A78289AC37C00E929EB /* PlantUMLDocumentProxy.swift */; }; + A0A42A7A289AC37C00E929EB /* PlantUMLDocumentProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A42A78289AC37C00E929EB /* PlantUMLDocumentProxy.swift */; }; A0BFBA9A290D551F008340E3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = A0BFBA9C290D551F008340E3 /* Localizable.strings */; }; A0D3C64A28984A0E000838D7 /* PlantUMLApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D3C64928984A0E000838D7 /* PlantUMLApp.swift */; }; A0D3C64C28984A0E000838D7 /* PlantUMLDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D3C64B28984A0E000838D7 /* PlantUMLDocument.swift */; }; @@ -55,12 +56,13 @@ A01552A228CF47DF00F2B8A1 /* PlantUMLFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = PlantUMLFramework; sourceTree = ""; }; A01907EF2951CD5C0059CCBE /* privacy_policy.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = privacy_policy.md; sourceTree = ""; }; A047206E29549ACC007E061F /* SwiftUI+Share.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SwiftUI+Share.swift"; sourceTree = ""; }; + A05923182978106B00A1E12F /* SwiftUI+Conditional.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SwiftUI+Conditional.swift"; sourceTree = ""; }; A08AA78329561170004DE329 /* View+UIImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+UIImage.swift"; sourceTree = ""; }; A0943A6D29448A1700342426 /* AppStore.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = AppStore.xcassets; sourceTree = ""; }; A0943A6E2944A44900342426 /* ScaleToFit+ToggleStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ScaleToFit+ToggleStyle.swift"; sourceTree = ""; }; A09A6DDA293D0E5E000856ED /* AsyncImage+Cache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AsyncImage+Cache.swift"; sourceTree = ""; }; A0A42A75289ABC2D00E929EB /* PlantUMLDiagramView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlantUMLDiagramView.swift; sourceTree = ""; }; - A0A42A78289AC37C00E929EB /* PlantUMLDiagramObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlantUMLDiagramObject.swift; sourceTree = ""; }; + A0A42A78289AC37C00E929EB /* PlantUMLDocumentProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlantUMLDocumentProxy.swift; sourceTree = ""; }; A0A42A7B289AD9FA00E929EB /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; A0BFBA9B290D551F008340E3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; A0D3C64628984A0E000838D7 /* PlantUMLApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PlantUMLApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -144,14 +146,15 @@ children = ( A08AA78329561170004DE329 /* View+UIImage.swift */, A047206E29549ACC007E061F /* SwiftUI+Share.swift */, + A05923182978106B00A1E12F /* SwiftUI+Conditional.swift */, A0943A6E2944A44900342426 /* ScaleToFit+ToggleStyle.swift */, A0F2B14129353C2D00A44481 /* SwiftUI+Rotate.swift */, A09A6DDA293D0E5E000856ED /* AsyncImage+Cache.swift */, A0D3C64928984A0E000838D7 /* PlantUMLApp.swift */, A0D3C64B28984A0E000838D7 /* PlantUMLDocument.swift */, + A0A42A78289AC37C00E929EB /* PlantUMLDocumentProxy.swift */, A0D3C64D28984A0E000838D7 /* PlantUMLContentView.swift */, A0A42A75289ABC2D00E929EB /* PlantUMLDiagramView.swift */, - A0A42A78289AC37C00E929EB /* PlantUMLDiagramObject.swift */, A0BFBA9C290D551F008340E3 /* Localizable.strings */, A0D3C64F28984A10000838D7 /* Assets.xcassets */, A0D3C65428984A10000838D7 /* Info.plist */, @@ -327,13 +330,14 @@ files = ( A0FB8F9C295616BF00910896 /* View+UIImage.swift in Sources */, A0277C0B293D11D7005435AE /* AsyncImage+Cache.swift in Sources */, - A0A42A79289AC37C00E929EB /* PlantUMLDiagramObject.swift in Sources */, + A0A42A79289AC37C00E929EB /* PlantUMLDocumentProxy.swift in Sources */, A0D3C64A28984A0E000838D7 /* PlantUMLApp.swift in Sources */, A0943A6F2944A44900342426 /* ScaleToFit+ToggleStyle.swift in Sources */, A0D3C64C28984A0E000838D7 /* PlantUMLDocument.swift in Sources */, A0D3C64E28984A0E000838D7 /* PlantUMLContentView.swift in Sources */, A047206F29549ACC007E061F /* SwiftUI+Share.swift in Sources */, A0F2B14229353C2D00A44481 /* SwiftUI+Rotate.swift in Sources */, + A05923192978106B00A1E12F /* SwiftUI+Conditional.swift in Sources */, A0A42A76289ABC2D00E929EB /* PlantUMLDiagramView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -351,7 +355,7 @@ buildActionMask = 2147483647; files = ( A0D3C66A28984A11000838D7 /* PlantUMLUITestsLaunchTests.swift in Sources */, - A0A42A7A289AC37C00E929EB /* PlantUMLDiagramObject.swift in Sources */, + A0A42A7A289AC37C00E929EB /* PlantUMLDocumentProxy.swift in Sources */, A0A42A77289ABC2D00E929EB /* PlantUMLDiagramView.swift in Sources */, A0F2B14329353C2D00A44481 /* SwiftUI+Rotate.swift in Sources */, A08AA78429561170004DE329 /* View+UIImage.swift in Sources */, @@ -508,7 +512,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = "\"PlantUML/Preview Content\""; DEVELOPMENT_TEAM = 48J595L9BX; ENABLE_PREVIEWS = YES; @@ -544,7 +548,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = "\"PlantUML/Preview Content\""; DEVELOPMENT_TEAM = 48J595L9BX; ENABLE_PREVIEWS = YES; diff --git a/PlantUMLFramework/Sources/PlantUMLFramework/SyntaxStructure.swift b/PlantUMLFramework/Sources/PlantUMLFramework/SyntaxStructure.swift index bdbda96..8e7c462 100644 --- a/PlantUMLFramework/Sources/PlantUMLFramework/SyntaxStructure.swift +++ b/PlantUMLFramework/Sources/PlantUMLFramework/SyntaxStructure.swift @@ -3,7 +3,7 @@ import Foundation /// Swift type representationg an AST element (analogue to SourceKitten's Structure) public struct SyntaxStructure: Codable, Identifiable, RawRepresentable { - public var id: String + public private(set) var id: String public var rawValue: String public init( rawValue: String ) { @@ -12,7 +12,9 @@ public struct SyntaxStructure: Codable, Identifiable, RawRepresentable { } } - +extension SyntaxStructure : Equatable { + +} extension String.StringInterpolation { mutating func appendInterpolation(_ item: SyntaxStructure) { appendInterpolation(item.rawValue) diff --git a/README.md b/README.md index 3e3a587..1be9d7a 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,14 @@ This is a native PlantUML editor app for iPad. It allows using iPad to draw diag 2. Share Documents with iCLoud 3. Line Text Editor * Support of Paste from Clipboard - * Provides add below / add above keyboard buttons + * Provides add below / add above keyboard buttons + * Auto save over modification 4. PlantUML Custom Keyboard * Common symbols * Sequence symbols * Deployment symbols + * Color key + > Open a color picker for choosing the color to apply 5. Diagram Preview > Preview relies on [PlantUML online server](https://plantuml.com/server) so it requires internet connection * Built in cache management @@ -29,7 +32,6 @@ Below all references that helped to develop such App * [SwiftPlantUML](https://github.com/MarcoEidinger/SwiftPlantUML) * [How to detect device rotation](https://www.hackingwithswift.com/quick-start/swiftui/how-to-detect-device-rotation) * [How can I add caching to AsyncImage](https://stackoverflow.com/a/70916651/521197) -* [For further info](https://plantuml.com/class-diagram#4b62dd14f1d33739) * [SwiftUI: Forcing an Update](https://stackoverflow.com/a/65095862/521197) * [Class Diagram](https://plantuml.com/class-diagram) * [Get the current first responder without using a private API](https://stackoverflow.com/a/1823360/521197) diff --git a/~/Library/Microsoft/PowerAppsCli/usersettings.json b/~/Library/Microsoft/PowerAppsCli/usersettings.json deleted file mode 100644 index d4260c0..0000000 --- a/~/Library/Microsoft/PowerAppsCli/usersettings.json +++ /dev/null @@ -1 +0,0 @@ -{"uniqueId":"d67c2bb3-ce99-4e95-becd-f5d782fdaecb","settingVersion":"1.0","telemetryEnabled":true} \ No newline at end of file