diff --git a/SimDirs/ContentView.swift b/SimDirs/ContentView.swift index d7d9ce5..702f10b 100644 --- a/SimDirs/ContentView.swift +++ b/SimDirs/ContentView.swift @@ -17,7 +17,7 @@ struct ContentView: View { var body: some View { VStack { NavigationView { - List { + List(selection: $state.selection) { Divider() switch state.base { @@ -26,12 +26,12 @@ struct ContentView: View { case let .device(_, item): ForEach(item.visibleChildren) { - SourceItemGroup(selection: $state.selection, item: $0) + SourceItemGroup(item: $0, selection: $state.selection) } case let .runtime(_, item): ForEach(item.visibleChildren) { - SourceItemGroup(selection: $state.selection, item: $0) + SourceItemGroup(item: $0, selection: $state.selection) } } } diff --git a/SimDirs/Presentation/SourceItem.swift b/SimDirs/Presentation/SourceItem.swift index 40d42b2..a4e706c 100644 --- a/SimDirs/Presentation/SourceItem.swift +++ b/SimDirs/Presentation/SourceItem.swift @@ -16,6 +16,7 @@ protocol SourceItem: Identifiable, ObservableObject { var children : [Child] { get set } var visibleChildren : [Child] { get set } var customImgDesc : SourceImageDesc? { get } + var isExpanded : Bool { get set } } extension SourceItem { @@ -54,10 +55,21 @@ extension SourceItem { return match || !visibleChildren.isEmpty } + + func toggleExpanded(_ expanded: Bool? = nil, deep: Bool) { + isExpanded = expanded ?? !isExpanded + + if deep { + for child in children { + child.toggleExpanded(isExpanded, deep: true) + } + } + } } class SourceItemVal: SourceItem { @Published var visibleChildren : [Child] + @Published var isExpanded : Bool var id = UUID() var data : Model @@ -70,6 +82,7 @@ class SourceItemVal: SourceItem { self.children = children self.visibleChildren = children self.customImgDesc = customImgDesc + self.isExpanded = false } } @@ -78,4 +91,5 @@ class SourceItemNone: SourceItem { var data = SourceItemDataNone() var children = [SourceItemNone]() var visibleChildren = [SourceItemNone]() + var isExpanded = false } diff --git a/SimDirs/Views/SourceItem Views/SourceItemGroup.swift b/SimDirs/Views/SourceItem Views/SourceItemGroup.swift index eeaf198..cef317f 100644 --- a/SimDirs/Views/SourceItem Views/SourceItemGroup.swift +++ b/SimDirs/Views/SourceItem Views/SourceItemGroup.swift @@ -8,25 +8,41 @@ import SwiftUI struct SourceItemGroup: View { - @State private var isExpanded = false // would like to move into Item - @Binding var selection: UUID? - @StateObject var item: Item + @StateObject var item : Item + @Binding var selection : UUID? var body: some View { - if item.visibleChildren.count > 0 { - DisclosureGroup( - isExpanded: $isExpanded) { - ForEach(item.visibleChildren) { childItem in - SourceItemGroup(selection: $selection, item: childItem) - } - } label: { - SourceItemLink(selection: $selection, item: item) - } + HStack(spacing: 0) { + let button = Button(action: { + let optionActive = NSApplication.shared.currentEvent?.modifierFlags.contains(.option) == true - } - else { + withAnimation(.easeInOut(duration: 0.2)) { + item.toggleExpanded(deep: optionActive) + } + }, label: { + Image(systemName: "chevron.right") + .padding(.horizontal, 2.0) + .contentShape(Rectangle()) + .rotationEffect(.degrees(item.isExpanded ? 90.0 : 0.0)) + }) + .buttonStyle(.plain) + + if item.visibleChildren.count == 0 { + button.hidden() + } + else { + button + } + SourceItemLink(selection: $selection, item: item) } + + if item.isExpanded { + ForEach(item.visibleChildren) { childItem in + SourceItemGroup(item: childItem, selection: $selection) + } + .padding(.leading, 12.0) + } } } @@ -36,6 +52,10 @@ struct SourceItemGroup_Previews: PreviewProvider { static var sampleItem = state.deviceStyleItems()[0] static var previews: some View { - SourceItemGroup(selection: $selection, item: sampleItem) + List { + SourceItemGroup(item: sampleItem, selection: $selection) + SourceItemGroup(item: sampleItem, selection: $selection) + SourceItemGroup(item: sampleItem, selection: $selection) + } } } diff --git a/SimDirs/Views/SourceItem Views/SourceItemLink.swift b/SimDirs/Views/SourceItem Views/SourceItemLink.swift index 10cb7be..fe7e47f 100644 --- a/SimDirs/Views/SourceItem Views/SourceItemLink.swift +++ b/SimDirs/Views/SourceItem Views/SourceItemLink.swift @@ -15,10 +15,7 @@ struct SourceItemLink: View { var body: some View { NavigationLink(tag: item.id, selection: $selection, destination: { SourceItemContent(item: item) }, - label: { - SourceItemLabel(item: item) - .padding(.leading, 2.0) - } + label: { SourceItemLabel(item: item) } ) } }