Add option to pass custom array to view switcher

This commit is contained in:
david-swift 2024-10-19 20:28:08 +02:00
parent 4559a81337
commit c893a8f0c6
2 changed files with 29 additions and 14 deletions

View File

@ -6,21 +6,25 @@
// //
import CAdw import CAdw
import LevenshteinTransformations
/// A picker used for indicating multiple views. /// The view switcher widget.
///
/// It normally controls a `ViewStack` (e.g. via `switch` statements).
public struct ViewSwitcher<Element>: AdwaitaWidget where Element: ViewSwitcherOption { public struct ViewSwitcher<Element>: AdwaitaWidget where Element: ViewSwitcherOption {
/// The selected element. /// 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. /// Whether the wide style is used, that means the icons and titles are on the same line.
var wide = false var wide = false
/// Initialize a view switcher. /// Initialize a view switcher.
/// - Parameter selection: The selected element. /// - Parameters:
public init(selection: Binding<Element>) { /// - elements: The elements.
self._selection = selection /// - selectedElement: The selected element.
public init(_ elements: [Element], selectedElement: Binding<Element>) {
self._selectedElement = selectedElement
self.elements = elements
} }
/// The view storage. /// The view storage.
@ -35,7 +39,7 @@ public struct ViewSwitcher<Element>: AdwaitaWidget where Element: ViewSwitcherOp
let switcher = ViewStorage(adw_view_switcher_new()?.opaque()) let switcher = ViewStorage(adw_view_switcher_new()?.opaque())
let stack = ViewStorage(adw_view_stack_new()?.opaque()) let stack = ViewStorage(adw_view_stack_new()?.opaque())
adw_view_switcher_set_stack(switcher.opaquePointer, stack.opaquePointer) 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( adw_view_stack_add_titled_with_icon(
stack.opaquePointer, stack.opaquePointer,
gtk_label_new(""), gtk_label_new(""),
@ -71,7 +75,7 @@ public struct ViewSwitcher<Element>: AdwaitaWidget where Element: ViewSwitcherOp
stack?.notify(name: "visible-child") { stack?.notify(name: "visible-child") {
if let title = adw_view_stack_get_visible_child_name(stack?.opaquePointer), if let title = adw_view_stack_get_visible_child_name(stack?.opaquePointer),
let option = Element(title: .init(cString: title)) { let option = Element(title: .init(cString: title)) {
selection = option selectedElement = option
} }
} }
if (switcher.previousState as? Self)?.wide != wide { if (switcher.previousState as? Self)?.wide != wide {
@ -80,9 +84,9 @@ public struct ViewSwitcher<Element>: AdwaitaWidget where Element: ViewSwitcherOp
wide ? ADW_VIEW_SWITCHER_POLICY_WIDE : ADW_VIEW_SWITCHER_POLICY_NARROW 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) 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 switcher.previousState = self
} }
@ -98,8 +102,19 @@ public struct ViewSwitcher<Element>: AdwaitaWidget where Element: ViewSwitcherOp
} }
extension ViewSwitcher where Element: CaseIterable {
/// Initialize a view switcher.
/// - Parameter selectedElement: The selected element.
public init(selectedElement: Binding<Element>) {
self._selectedElement = selectedElement
self.elements = .init(Element.allCases)
}
}
/// The protocol an element type for view switcher has to conform to. /// 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. /// The title displayed in the switcher and used for identification.
var title: String { get } var title: String { get }

View File

@ -57,14 +57,14 @@ struct ViewSwitcherDemo: View {
var toolbar: AnyView { var toolbar: AnyView {
HeaderBar(titleButtons: !bottom) { } end: { } HeaderBar(titleButtons: !bottom) { } end: { }
.headerBarTitle { .headerBarTitle {
ViewSwitcher(selection: $selection) ViewSwitcher(selectedElement: $selection)
.wideDesign(!bottom) .wideDesign(!bottom)
} }
} }
} }
enum ViewSwitcherView: String, ViewSwitcherOption { enum ViewSwitcherView: String, ViewSwitcherOption, CaseIterable {
case albums case albums
case artists case artists