diff --git a/Sources/Core/View/ViewSwitcher.swift b/Sources/Core/View/ViewSwitcher.swift index b87ca9a..6311b63 100644 --- a/Sources/Core/View/ViewSwitcher.swift +++ b/Sources/Core/View/ViewSwitcher.swift @@ -6,21 +6,25 @@ // import CAdw +import LevenshteinTransformations -/// A picker used for indicating multiple views. -/// -/// It normally controls a `ViewStack` (e.g. via `switch` statements). +/// The view switcher widget. public struct ViewSwitcher: AdwaitaWidget where Element: ViewSwitcherOption { /// The selected element. - @Binding var selection: Element + @Binding var selectedElement: Element + /// The elements. + var elements: [Element] /// Whether the wide style is used, that means the icons and titles are on the same line. var wide = false /// Initialize a view switcher. - /// - Parameter selection: The selected element. - public init(selection: Binding) { - self._selection = selection + /// - Parameters: + /// - elements: The elements. + /// - selectedElement: The selected element. + public init(_ elements: [Element], selectedElement: Binding) { + self._selectedElement = selectedElement + self.elements = elements } /// The view storage. @@ -35,7 +39,7 @@ public struct ViewSwitcher: AdwaitaWidget where Element: ViewSwitcherOp let switcher = ViewStorage(adw_view_switcher_new()?.opaque()) let stack = ViewStorage(adw_view_stack_new()?.opaque()) adw_view_switcher_set_stack(switcher.opaquePointer, stack.opaquePointer) - for option in Element.allCases { + for option in elements { adw_view_stack_add_titled_with_icon( stack.opaquePointer, gtk_label_new(""), @@ -71,7 +75,7 @@ public struct ViewSwitcher: AdwaitaWidget where Element: ViewSwitcherOp stack?.notify(name: "visible-child") { if let title = adw_view_stack_get_visible_child_name(stack?.opaquePointer), let option = Element(title: .init(cString: title)) { - selection = option + selectedElement = option } } if (switcher.previousState as? Self)?.wide != wide { @@ -80,9 +84,9 @@ public struct ViewSwitcher: AdwaitaWidget where Element: ViewSwitcherOp wide ? ADW_VIEW_SWITCHER_POLICY_WIDE : ADW_VIEW_SWITCHER_POLICY_NARROW ) } - if (switcher.previousState as? Self)?.selection.title != selection.title { + if (switcher.previousState as? Self)?.selectedElement.title != selectedElement.title { let stack = adw_view_switcher_get_stack(switcher.opaquePointer) - adw_view_stack_set_visible_child_name(stack, selection.title) + adw_view_stack_set_visible_child_name(stack, selectedElement.title) } switcher.previousState = self } @@ -98,8 +102,19 @@ public struct ViewSwitcher: AdwaitaWidget where Element: ViewSwitcherOp } +extension ViewSwitcher where Element: CaseIterable { + + /// Initialize a view switcher. + /// - Parameter selectedElement: The selected element. + public init(selectedElement: Binding) { + self._selectedElement = selectedElement + self.elements = .init(Element.allCases) + } + +} + /// The protocol an element type for view switcher has to conform to. -public protocol ViewSwitcherOption: CaseIterable { +public protocol ViewSwitcherOption { /// The title displayed in the switcher and used for identification. var title: String { get } diff --git a/Sources/Demo/ViewSwitcherDemo.swift b/Sources/Demo/ViewSwitcherDemo.swift index be05616..728c494 100644 --- a/Sources/Demo/ViewSwitcherDemo.swift +++ b/Sources/Demo/ViewSwitcherDemo.swift @@ -57,14 +57,14 @@ struct ViewSwitcherDemo: View { var toolbar: AnyView { HeaderBar(titleButtons: !bottom) { } end: { } .headerBarTitle { - ViewSwitcher(selection: $selection) + ViewSwitcher(selectedElement: $selection) .wideDesign(!bottom) } } } - enum ViewSwitcherView: String, ViewSwitcherOption { + enum ViewSwitcherView: String, ViewSwitcherOption, CaseIterable { case albums case artists