diff --git a/Sources/Adwaita/View/DropDown+.swift b/Sources/Adwaita/View/DropDown+.swift index bb2fc5e..ecf1513 100644 --- a/Sources/Adwaita/View/DropDown+.swift +++ b/Sources/Adwaita/View/DropDown+.swift @@ -17,27 +17,40 @@ extension DropDown { /// Initialize a combo row. /// - Parameters: - /// - title: The row's title. /// - selection: The selected value. /// - values: The available values. public init( selection: Binding, values: [Element] ) where Element: Identifiable, Element: CustomStringConvertible { + self.init(selection: selection, values: values, id: \.id, description: \.description) + } + + /// Initialize a combo row. + /// - Parameters: + /// - title: The row's title. + /// - selection: The selected value. + /// - values: The available values. + public init( + selection: Binding, + values: [Element], + id: KeyPath, + description: KeyPath + ) where Identifier: Equatable { self.init() self = self.selected(.init { - .init(values.firstIndex { $0.id == selection.wrappedValue } ?? 0) + .init(values.firstIndex { $0[keyPath: id] == selection.wrappedValue } ?? 0) } set: { index in - if let id = values[safe: .init(index)]?.id { + if let id = values[safe: .init(index)]?[keyPath: id] { selection.wrappedValue = id } }) appearFunctions.append { storage, _ in storage.fields[Self.stringList] = gtk_drop_down_get_model(storage.opaquePointer) - Self.updateContent(storage: storage, values: values, element: Element.self) + Self.updateContent(storage: storage, values: values, id: id, description: description) } updateFunctions.append { storage, _, _ in - Self.updateContent(storage: storage, values: values, element: Element.self) + Self.updateContent(storage: storage, values: values, id: id, description: description) } } @@ -45,20 +58,23 @@ extension DropDown { /// - Parameters: /// - storage: The view storage. /// - values: The elements. - /// - element: The type of the elements. - static func updateContent( + /// - id: The keypath to the id. + /// - description: The keypath to the description. + static func updateContent( storage: ViewStorage, values: [Element], - element: Element.Type - ) where Element: Identifiable, Element: CustomStringConvertible { + id: KeyPath, + description: KeyPath + ) where Identifier: Equatable { if let list = storage.fields[Self.stringList] as? OpaquePointer { let old = storage.fields[Self.values] as? [Element] ?? [] - old.identifiableTransform( + old.transform( to: values, + id: id, functions: .init { index in gtk_string_list_remove(list, .init(index)) } insert: { _, element in - gtk_string_list_append(list, element.description) + gtk_string_list_append(list, element[keyPath: description]) } ) storage.fields[Self.values] = values diff --git a/Sources/Adwaita/View/FlowBox+.swift b/Sources/Adwaita/View/FlowBox+.swift index 8abff67..a18706e 100644 --- a/Sources/Adwaita/View/FlowBox+.swift +++ b/Sources/Adwaita/View/FlowBox+.swift @@ -17,19 +17,21 @@ extension FlowBox { /// Initialize `FlowBox`. /// - Parameters: /// - elements: The elements. + /// - id: The element identifier keypath. /// - selection: The identifier of the selected element. Selection disabled if `nil`. /// - content: The view for an element. public init( _ elements: [Element], - selection: Binding? = nil, + id: KeyPath, + selection: Binding? = nil, @ViewBuilder content: @escaping (Element) -> Body ) { - self.init(elements, content: content) - let id: (ViewStorage, [Element]) -> Element.ID? = { storage, elements in + self.init(elements, id: id, content: content) + let getID: (ViewStorage, [Element]) -> Identifier? = { storage, elements in if let child = g_list_nth_data(gtk_flow_box_get_selected_children(storage.opaquePointer), 0) { let element = gtk_flow_box_child_get_child(child.cast()) return elements[safe: storage.content[.mainContent]? - .firstIndex { $0.opaquePointer?.cast() == element }]?.id + .firstIndex { $0.opaquePointer?.cast() == element }]?[keyPath: id] } return nil } @@ -37,12 +39,12 @@ extension FlowBox { updateFunctions.append { storage, _, _ in storage.connectSignal(name: "selected_children_changed", id: Self.selectionField) { if let elements = storage.fields[Self.elementsField] as? [Element], - let id = id(storage, elements) { + let id = getID(storage, elements) { selection.wrappedValue = id } } - if selection.wrappedValue != id(storage, elements), - let index = elements.firstIndex(where: { $0.id == selection.wrappedValue })?.cInt { + if selection.wrappedValue != getID(storage, elements), + let index = elements.firstIndex(where: { $0[keyPath: id] == selection.wrappedValue })?.cInt { gtk_flow_box_select_child( storage.opaquePointer, gtk_flow_box_get_child_at_index(storage.opaquePointer, index) @@ -57,3 +59,20 @@ extension FlowBox { } } + +extension FlowBox where Element: Identifiable, Identifier == Element.ID { + + /// Initialize `FlowBox`. + /// - Parameters: + /// - elements: The elements. + /// - selection: The identifier of the selected element. Selection disabled if `nil`. + /// - content: The view for an element. + public init( + _ elements: [Element], + selection: Binding? = nil, + @ViewBuilder content: @escaping (Element) -> Body + ) { + self.init(elements, id: \.id, selection: selection, content: content) + } + +} diff --git a/Sources/Adwaita/View/ForEach.swift b/Sources/Adwaita/View/ForEach.swift index 3f84ea9..06c643e 100644 --- a/Sources/Adwaita/View/ForEach.swift +++ b/Sources/Adwaita/View/ForEach.swift @@ -9,7 +9,7 @@ import CAdw import LevenshteinTransformations /// A dynamic list but without a list design in the user interface. -public struct ForEach: AdwaitaWidget where Element: Identifiable { +public struct ForEach: AdwaitaWidget where Identifier: Equatable { /// The dynamic widget elements. var elements: [Element] @@ -19,12 +19,20 @@ public struct ForEach: AdwaitaWidget where Element: Identifiable { var horizontal: Bool /// Whether the children should all be the same size. var homogeneous: Bool? + /// The path to the identifier. + var id: KeyPath /// Initialize `ForEach`. - public init(_ elements: [Element], horizontal: Bool = false, @ViewBuilder content: @escaping (Element) -> Body) { + public init( + _ elements: [Element], + id: KeyPath, + horizontal: Bool = false, + @ViewBuilder content: @escaping (Element) -> Body + ) { self.elements = elements self.content = content self.horizontal = horizontal + self.id = id } /// The view storage. @@ -56,8 +64,9 @@ public struct ForEach: AdwaitaWidget where Element: Identifiable { var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? [] let old = storage.fields["element"] as? [Element] ?? [] let widget: UnsafeMutablePointer? = storage.opaquePointer?.cast() - old.identifiableTransform( + old.transform( to: elements, + id: id, functions: .init { index in let child = contentStorage[safe: index]?.opaquePointer gtk_box_remove(widget, child?.cast()) @@ -105,3 +114,15 @@ public struct ForEach: AdwaitaWidget where Element: Identifiable { } } + +extension ForEach where Element: Identifiable, Identifier == Element.ID { + + /// Initialize `ForEach`. + public init(_ elements: [Element], horizontal: Bool = false, @ViewBuilder content: @escaping (Element) -> Body) { + self.elements = elements + self.content = content + self.horizontal = horizontal + self.id = \.id + } + +} diff --git a/Sources/Adwaita/View/Forms/ComboRow+.swift b/Sources/Adwaita/View/Forms/ComboRow+.swift index 0483f5f..f85cf8e 100644 --- a/Sources/Adwaita/View/Forms/ComboRow+.swift +++ b/Sources/Adwaita/View/Forms/ComboRow+.swift @@ -26,11 +26,26 @@ extension ComboRow { selection: Binding, values: [Element] ) where Element: Identifiable, Element: CustomStringConvertible { + self.init(title, selection: selection, values: values, id: \.id, description: \.description) + } + + /// Initialize a combo row. + /// - Parameters: + /// - title: The row's title. + /// - selection: The selected value. + /// - values: The available values. + public init( + _ title: String, + selection: Binding, + values: [Element], + id: KeyPath, + description: KeyPath + ) where Identifier: Equatable { self = self.title(title) self = self.selected(.init { - .init(values.firstIndex { $0.id == selection.wrappedValue } ?? 0) + .init(values.firstIndex { $0[keyPath: id] == selection.wrappedValue } ?? 0) } set: { index in - if let id = values[safe: .init(index)]?.id { + if let id = values[safe: .init(index)]?[keyPath: id] { selection.wrappedValue = id } }) @@ -39,34 +54,10 @@ extension ComboRow { storage.fields[Self.stringList] = list adw_combo_row_set_model(storage.opaquePointer?.cast(), list) g_object_unref(list?.cast()) - Self.updateContent(storage: storage, values: values, element: Element.self) + DropDown.updateContent(storage: storage, values: values, id: id, description: description) } updateFunctions.append { storage, _, _ in - Self.updateContent(storage: storage, values: values, element: Element.self) - } - } - - /// Update the combo row's content. - /// - Parameters: - /// - storage: The view storage. - /// - values: The elements. - /// - element: The type of the elements. - static func updateContent( - storage: ViewStorage, - values: [Element], - element: Element.Type - ) where Element: Identifiable, Element: CustomStringConvertible { - if let list = storage.fields[Self.stringList] as? OpaquePointer { - let old = storage.fields[Self.values] as? [Element] ?? [] - old.identifiableTransform( - to: values, - functions: .init { index in - gtk_string_list_remove(list, .init(index)) - } insert: { _, element in - gtk_string_list_append(list, element.description) - } - ) - storage.fields[Self.values] = values + DropDown.updateContent(storage: storage, values: values, id: id, description: description) } } diff --git a/Sources/Adwaita/View/Generated/ActionRow.swift b/Sources/Adwaita/View/Generated/ActionRow.swift index fe8297d..b9e2f2f 100644 --- a/Sources/Adwaita/View/Generated/ActionRow.swift +++ b/Sources/Adwaita/View/Generated/ActionRow.swift @@ -2,7 +2,7 @@ // ActionRow.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/AspectFrame.swift b/Sources/Adwaita/View/Generated/AspectFrame.swift index 690bfb5..94cfeef 100644 --- a/Sources/Adwaita/View/Generated/AspectFrame.swift +++ b/Sources/Adwaita/View/Generated/AspectFrame.swift @@ -2,7 +2,7 @@ // AspectFrame.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Avatar.swift b/Sources/Adwaita/View/Generated/Avatar.swift index 62a5400..e332ea9 100644 --- a/Sources/Adwaita/View/Generated/Avatar.swift +++ b/Sources/Adwaita/View/Generated/Avatar.swift @@ -2,7 +2,7 @@ // Avatar.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Banner.swift b/Sources/Adwaita/View/Generated/Banner.swift index 5e7b85c..1b92c68 100644 --- a/Sources/Adwaita/View/Generated/Banner.swift +++ b/Sources/Adwaita/View/Generated/Banner.swift @@ -2,7 +2,7 @@ // Banner.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Bin.swift b/Sources/Adwaita/View/Generated/Bin.swift index c3602eb..5a53da7 100644 --- a/Sources/Adwaita/View/Generated/Bin.swift +++ b/Sources/Adwaita/View/Generated/Bin.swift @@ -2,7 +2,7 @@ // Bin.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Box.swift b/Sources/Adwaita/View/Generated/Box.swift index 2607fe5..3be9c31 100644 --- a/Sources/Adwaita/View/Generated/Box.swift +++ b/Sources/Adwaita/View/Generated/Box.swift @@ -2,7 +2,7 @@ // Box.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Button.swift b/Sources/Adwaita/View/Generated/Button.swift index c8d2f43..e6de6bd 100644 --- a/Sources/Adwaita/View/Generated/Button.swift +++ b/Sources/Adwaita/View/Generated/Button.swift @@ -2,7 +2,7 @@ // Button.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/ButtonContent.swift b/Sources/Adwaita/View/Generated/ButtonContent.swift index 9cfc745..5ce1afd 100644 --- a/Sources/Adwaita/View/Generated/ButtonContent.swift +++ b/Sources/Adwaita/View/Generated/ButtonContent.swift @@ -2,7 +2,7 @@ // ButtonContent.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Carousel.swift b/Sources/Adwaita/View/Generated/Carousel.swift index c6b5082..cb8403c 100644 --- a/Sources/Adwaita/View/Generated/Carousel.swift +++ b/Sources/Adwaita/View/Generated/Carousel.swift @@ -2,7 +2,7 @@ // Carousel.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw @@ -19,7 +19,7 @@ import LevenshteinTransformations /// to provide page indicators for `AdwCarousel`. /// /// -public struct Carousel: AdwaitaWidget where Element: Identifiable { +public struct Carousel: AdwaitaWidget where Identifier: Equatable { #if exposeGeneratedAppearUpdateFunctions /// Additional update functions for type extensions. @@ -70,11 +70,14 @@ public struct Carousel: AdwaitaWidget where Element: Identifiable { var elements: [Element] /// The dynamic widget content. var content: (Element) -> Body + /// The dynamic widget identifier key path. + var id: KeyPath /// Initialize `Carousel`. - public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) { + public init(_ elements: [Element], id: KeyPath, @ViewBuilder content: @escaping (Element) -> Body) { self.elements = elements self.content = content + self.id = id } /// The view storage. @@ -126,8 +129,9 @@ public struct Carousel: AdwaitaWidget where Element: Identifiable { var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? [] let old = storage.fields["element"] as? [Element] ?? [] - old.identifiableTransform( + old.transform( to: elements, + id: id, functions: .init { index in adw_carousel_remove(widget, adw_carousel_get_nth_page(widget, UInt(index).cInt)) contentStorage.remove(at: index) @@ -212,3 +216,14 @@ public struct Carousel: AdwaitaWidget where Element: Identifiable { } } + +extension Carousel where Element: Identifiable, Identifier == Element.ID { + + /// Initialize `Carousel`. + public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) { + self.elements = elements + self.content = content + self.id = \.id + } + +} diff --git a/Sources/Adwaita/View/Generated/CenterBox.swift b/Sources/Adwaita/View/Generated/CenterBox.swift index fb47e22..7be3d4e 100644 --- a/Sources/Adwaita/View/Generated/CenterBox.swift +++ b/Sources/Adwaita/View/Generated/CenterBox.swift @@ -2,7 +2,7 @@ // CenterBox.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/CheckButton.swift b/Sources/Adwaita/View/Generated/CheckButton.swift index b131ab7..1c98535 100644 --- a/Sources/Adwaita/View/Generated/CheckButton.swift +++ b/Sources/Adwaita/View/Generated/CheckButton.swift @@ -2,7 +2,7 @@ // CheckButton.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Clamp.swift b/Sources/Adwaita/View/Generated/Clamp.swift index 25fc5f8..1d95074 100644 --- a/Sources/Adwaita/View/Generated/Clamp.swift +++ b/Sources/Adwaita/View/Generated/Clamp.swift @@ -2,7 +2,7 @@ // Clamp.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/ComboRow.swift b/Sources/Adwaita/View/Generated/ComboRow.swift index b73398c..9278a16 100644 --- a/Sources/Adwaita/View/Generated/ComboRow.swift +++ b/Sources/Adwaita/View/Generated/ComboRow.swift @@ -2,7 +2,7 @@ // ComboRow.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/DropDown.swift b/Sources/Adwaita/View/Generated/DropDown.swift index 1541a7f..d325d9a 100644 --- a/Sources/Adwaita/View/Generated/DropDown.swift +++ b/Sources/Adwaita/View/Generated/DropDown.swift @@ -2,7 +2,7 @@ // DropDown.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Entry.swift b/Sources/Adwaita/View/Generated/Entry.swift index fd477ce..5116d87 100644 --- a/Sources/Adwaita/View/Generated/Entry.swift +++ b/Sources/Adwaita/View/Generated/Entry.swift @@ -2,7 +2,7 @@ // Entry.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/EntryRow.swift b/Sources/Adwaita/View/Generated/EntryRow.swift index d7820d9..016578f 100644 --- a/Sources/Adwaita/View/Generated/EntryRow.swift +++ b/Sources/Adwaita/View/Generated/EntryRow.swift @@ -2,7 +2,7 @@ // EntryRow.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/ExpanderRow.swift b/Sources/Adwaita/View/Generated/ExpanderRow.swift index e1b01f4..5746ac4 100644 --- a/Sources/Adwaita/View/Generated/ExpanderRow.swift +++ b/Sources/Adwaita/View/Generated/ExpanderRow.swift @@ -2,7 +2,7 @@ // ExpanderRow.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Fixed.swift b/Sources/Adwaita/View/Generated/Fixed.swift index 3d4b5b7..94f0cc4 100644 --- a/Sources/Adwaita/View/Generated/Fixed.swift +++ b/Sources/Adwaita/View/Generated/Fixed.swift @@ -2,7 +2,7 @@ // Fixed.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/FlowBox.swift b/Sources/Adwaita/View/Generated/FlowBox.swift index 57d4fd2..344b6d8 100644 --- a/Sources/Adwaita/View/Generated/FlowBox.swift +++ b/Sources/Adwaita/View/Generated/FlowBox.swift @@ -2,7 +2,7 @@ // FlowBox.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw @@ -37,7 +37,7 @@ import LevenshteinTransformations /// Also see `Gtk.ListBox`. /// /// -public struct FlowBox: AdwaitaWidget where Element: Identifiable { +public struct FlowBox: AdwaitaWidget where Identifier: Equatable { #if exposeGeneratedAppearUpdateFunctions /// Additional update functions for type extensions. @@ -130,11 +130,14 @@ public struct FlowBox: AdwaitaWidget where Element: Identifiable { var elements: [Element] /// The dynamic widget content. var content: (Element) -> Body + /// The dynamic widget identifier key path. + var id: KeyPath /// Initialize `FlowBox`. - init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) { + init(_ elements: [Element], id: KeyPath, @ViewBuilder content: @escaping (Element) -> Body) { self.elements = elements self.content = content + self.id = id } /// The view storage. @@ -216,8 +219,9 @@ public struct FlowBox: AdwaitaWidget where Element: Identifiable { var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? [] let old = storage.fields["element"] as? [Element] ?? [] - old.identifiableTransform( + old.transform( to: elements, + id: id, functions: .init { index in gtk_flow_box_remove(widget, gtk_flow_box_get_child_at_index(widget, index.cInt)?.cast()) contentStorage.remove(at: index) @@ -377,3 +381,14 @@ public struct FlowBox: AdwaitaWidget where Element: Identifiable { } } + +extension FlowBox where Element: Identifiable, Identifier == Element.ID { + + /// Initialize `FlowBox`. + public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) { + self.elements = elements + self.content = content + self.id = \.id + } + +} diff --git a/Sources/Adwaita/View/Generated/HeaderBar.swift b/Sources/Adwaita/View/Generated/HeaderBar.swift index a060cd4..1c47720 100644 --- a/Sources/Adwaita/View/Generated/HeaderBar.swift +++ b/Sources/Adwaita/View/Generated/HeaderBar.swift @@ -2,7 +2,7 @@ // HeaderBar.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Image.swift b/Sources/Adwaita/View/Generated/Image.swift index 1c9cda9..124e93d 100644 --- a/Sources/Adwaita/View/Generated/Image.swift +++ b/Sources/Adwaita/View/Generated/Image.swift @@ -2,7 +2,7 @@ // Image.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Label.swift b/Sources/Adwaita/View/Generated/Label.swift index 50d1bb5..b3a4365 100644 --- a/Sources/Adwaita/View/Generated/Label.swift +++ b/Sources/Adwaita/View/Generated/Label.swift @@ -2,7 +2,7 @@ // Label.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/LevelBar.swift b/Sources/Adwaita/View/Generated/LevelBar.swift index 510c6ea..5855550 100644 --- a/Sources/Adwaita/View/Generated/LevelBar.swift +++ b/Sources/Adwaita/View/Generated/LevelBar.swift @@ -2,7 +2,7 @@ // LevelBar.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/LinkButton.swift b/Sources/Adwaita/View/Generated/LinkButton.swift index 5972e9e..4fb7fe1 100644 --- a/Sources/Adwaita/View/Generated/LinkButton.swift +++ b/Sources/Adwaita/View/Generated/LinkButton.swift @@ -2,7 +2,7 @@ // LinkButton.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/ListBox.swift b/Sources/Adwaita/View/Generated/ListBox.swift index fa13aa4..53c31a9 100644 --- a/Sources/Adwaita/View/Generated/ListBox.swift +++ b/Sources/Adwaita/View/Generated/ListBox.swift @@ -2,7 +2,7 @@ // ListBox.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw @@ -34,7 +34,7 @@ import LevenshteinTransformations /// as selected when the user tries to select it. /// /// -public struct ListBox: AdwaitaWidget where Element: Identifiable { +public struct ListBox: AdwaitaWidget where Identifier: Equatable { #if exposeGeneratedAppearUpdateFunctions /// Additional update functions for type extensions. @@ -107,11 +107,14 @@ public struct ListBox: AdwaitaWidget where Element: Identifiable { var elements: [Element] /// The dynamic widget content. var content: (Element) -> Body + /// The dynamic widget identifier key path. + var id: KeyPath /// Initialize `ListBox`. - public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) { + public init(_ elements: [Element], id: KeyPath, @ViewBuilder content: @escaping (Element) -> Body) { self.elements = elements self.content = content + self.id = id } /// The view storage. @@ -186,8 +189,9 @@ public struct ListBox: AdwaitaWidget where Element: Identifiable { var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? [] let old = storage.fields["element"] as? [Element] ?? [] - old.identifiableTransform( + old.transform( to: elements, + id: id, functions: .init { index in gtk_list_box_remove(widget, gtk_list_box_get_row_at_index(widget, index.cInt)?.cast()) contentStorage.remove(at: index) @@ -320,3 +324,14 @@ public struct ListBox: AdwaitaWidget where Element: Identifiable { } } + +extension ListBox where Element: Identifiable, Identifier == Element.ID { + + /// Initialize `ListBox`. + public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) { + self.elements = elements + self.content = content + self.id = \.id + } + +} diff --git a/Sources/Adwaita/View/Generated/Menu.swift b/Sources/Adwaita/View/Generated/Menu.swift index 0097846..d4c7018 100644 --- a/Sources/Adwaita/View/Generated/Menu.swift +++ b/Sources/Adwaita/View/Generated/Menu.swift @@ -2,7 +2,7 @@ // Menu.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/NavigationView.swift b/Sources/Adwaita/View/Generated/NavigationView.swift index a1de911..3738341 100644 --- a/Sources/Adwaita/View/Generated/NavigationView.swift +++ b/Sources/Adwaita/View/Generated/NavigationView.swift @@ -2,7 +2,7 @@ // NavigationView.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Overlay.swift b/Sources/Adwaita/View/Generated/Overlay.swift index b2470b4..a9b062b 100644 --- a/Sources/Adwaita/View/Generated/Overlay.swift +++ b/Sources/Adwaita/View/Generated/Overlay.swift @@ -2,7 +2,7 @@ // Overlay.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/OverlaySplitView.swift b/Sources/Adwaita/View/Generated/OverlaySplitView.swift index 6d423da..15d1c34 100644 --- a/Sources/Adwaita/View/Generated/OverlaySplitView.swift +++ b/Sources/Adwaita/View/Generated/OverlaySplitView.swift @@ -2,7 +2,7 @@ // OverlaySplitView.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/PasswordEntryRow.swift b/Sources/Adwaita/View/Generated/PasswordEntryRow.swift index 06f8809..83dfc54 100644 --- a/Sources/Adwaita/View/Generated/PasswordEntryRow.swift +++ b/Sources/Adwaita/View/Generated/PasswordEntryRow.swift @@ -2,7 +2,7 @@ // PasswordEntryRow.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Picture.swift b/Sources/Adwaita/View/Generated/Picture.swift index 4fcff4a..e0c5c83 100644 --- a/Sources/Adwaita/View/Generated/Picture.swift +++ b/Sources/Adwaita/View/Generated/Picture.swift @@ -2,7 +2,7 @@ // Picture.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Popover.swift b/Sources/Adwaita/View/Generated/Popover.swift index 80fc4c6..a07c6f6 100644 --- a/Sources/Adwaita/View/Generated/Popover.swift +++ b/Sources/Adwaita/View/Generated/Popover.swift @@ -2,7 +2,7 @@ // Popover.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/PreferencesGroup.swift b/Sources/Adwaita/View/Generated/PreferencesGroup.swift index 6b4deff..3c3c895 100644 --- a/Sources/Adwaita/View/Generated/PreferencesGroup.swift +++ b/Sources/Adwaita/View/Generated/PreferencesGroup.swift @@ -2,7 +2,7 @@ // PreferencesGroup.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/PreferencesPage.swift b/Sources/Adwaita/View/Generated/PreferencesPage.swift index fc9d2e0..d7d82b9 100644 --- a/Sources/Adwaita/View/Generated/PreferencesPage.swift +++ b/Sources/Adwaita/View/Generated/PreferencesPage.swift @@ -2,7 +2,7 @@ // PreferencesPage.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/PreferencesRow.swift b/Sources/Adwaita/View/Generated/PreferencesRow.swift index fb5a99d..d974f86 100644 --- a/Sources/Adwaita/View/Generated/PreferencesRow.swift +++ b/Sources/Adwaita/View/Generated/PreferencesRow.swift @@ -2,7 +2,7 @@ // PreferencesRow.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/ProgressBar.swift b/Sources/Adwaita/View/Generated/ProgressBar.swift index 1a1a1e1..e04ddfc 100644 --- a/Sources/Adwaita/View/Generated/ProgressBar.swift +++ b/Sources/Adwaita/View/Generated/ProgressBar.swift @@ -2,7 +2,7 @@ // ProgressBar.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/ScrolledWindow.swift b/Sources/Adwaita/View/Generated/ScrolledWindow.swift index 93ea0d8..903b29a 100644 --- a/Sources/Adwaita/View/Generated/ScrolledWindow.swift +++ b/Sources/Adwaita/View/Generated/ScrolledWindow.swift @@ -2,7 +2,7 @@ // ScrolledWindow.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/SearchBar.swift b/Sources/Adwaita/View/Generated/SearchBar.swift index 518f89e..9dcb3fc 100644 --- a/Sources/Adwaita/View/Generated/SearchBar.swift +++ b/Sources/Adwaita/View/Generated/SearchBar.swift @@ -2,7 +2,7 @@ // SearchBar.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/SearchEntry.swift b/Sources/Adwaita/View/Generated/SearchEntry.swift index 6e7efae..94fe417 100644 --- a/Sources/Adwaita/View/Generated/SearchEntry.swift +++ b/Sources/Adwaita/View/Generated/SearchEntry.swift @@ -2,7 +2,7 @@ // SearchEntry.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Separator.swift b/Sources/Adwaita/View/Generated/Separator.swift index df6152b..dc90e4b 100644 --- a/Sources/Adwaita/View/Generated/Separator.swift +++ b/Sources/Adwaita/View/Generated/Separator.swift @@ -2,7 +2,7 @@ // Separator.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/SpinRow.swift b/Sources/Adwaita/View/Generated/SpinRow.swift index bfed1a9..55c97ae 100644 --- a/Sources/Adwaita/View/Generated/SpinRow.swift +++ b/Sources/Adwaita/View/Generated/SpinRow.swift @@ -2,7 +2,7 @@ // SpinRow.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/Spinner.swift b/Sources/Adwaita/View/Generated/Spinner.swift index 926f08d..89f0fcb 100644 --- a/Sources/Adwaita/View/Generated/Spinner.swift +++ b/Sources/Adwaita/View/Generated/Spinner.swift @@ -2,7 +2,7 @@ // Spinner.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/SplitButton.swift b/Sources/Adwaita/View/Generated/SplitButton.swift index 124664f..946d4a6 100644 --- a/Sources/Adwaita/View/Generated/SplitButton.swift +++ b/Sources/Adwaita/View/Generated/SplitButton.swift @@ -2,7 +2,7 @@ // SplitButton.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/StatusPage.swift b/Sources/Adwaita/View/Generated/StatusPage.swift index 5f091d1..8f5719c 100644 --- a/Sources/Adwaita/View/Generated/StatusPage.swift +++ b/Sources/Adwaita/View/Generated/StatusPage.swift @@ -2,7 +2,7 @@ // StatusPage.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/SwitchRow.swift b/Sources/Adwaita/View/Generated/SwitchRow.swift index e77b3b1..6b5ea14 100644 --- a/Sources/Adwaita/View/Generated/SwitchRow.swift +++ b/Sources/Adwaita/View/Generated/SwitchRow.swift @@ -2,7 +2,7 @@ // SwitchRow.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/ToastOverlay.swift b/Sources/Adwaita/View/Generated/ToastOverlay.swift index dd44d42..e4afd06 100644 --- a/Sources/Adwaita/View/Generated/ToastOverlay.swift +++ b/Sources/Adwaita/View/Generated/ToastOverlay.swift @@ -2,7 +2,7 @@ // ToastOverlay.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/ToggleButton.swift b/Sources/Adwaita/View/Generated/ToggleButton.swift index 7478636..c23b6f3 100644 --- a/Sources/Adwaita/View/Generated/ToggleButton.swift +++ b/Sources/Adwaita/View/Generated/ToggleButton.swift @@ -2,7 +2,7 @@ // ToggleButton.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/ToggleGroup.swift b/Sources/Adwaita/View/Generated/ToggleGroup.swift index f300d7d..bb9a129 100644 --- a/Sources/Adwaita/View/Generated/ToggleGroup.swift +++ b/Sources/Adwaita/View/Generated/ToggleGroup.swift @@ -2,7 +2,7 @@ // ToggleGroup.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/ToolbarView.swift b/Sources/Adwaita/View/Generated/ToolbarView.swift index 48cc4a5..3d6f603 100644 --- a/Sources/Adwaita/View/Generated/ToolbarView.swift +++ b/Sources/Adwaita/View/Generated/ToolbarView.swift @@ -2,7 +2,7 @@ // ToolbarView.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/Generated/WindowTitle.swift b/Sources/Adwaita/View/Generated/WindowTitle.swift index fba7910..3bcc118 100644 --- a/Sources/Adwaita/View/Generated/WindowTitle.swift +++ b/Sources/Adwaita/View/Generated/WindowTitle.swift @@ -2,7 +2,7 @@ // WindowTitle.swift // Adwaita // -// Created by auto-generation on 03.02.26. +// Created by auto-generation on 04.02.26. // import CAdw diff --git a/Sources/Adwaita/View/List+.swift b/Sources/Adwaita/View/List+.swift deleted file mode 100644 index e3a6faf..0000000 --- a/Sources/Adwaita/View/List+.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// List+.swift -// Adwaita -// -// Created by david-swift on 16.10.24. -// - -extension List { - - /// Add the "navigation-sidebar" style class. - /// - Parameter active: Whether the style is applied. - /// - Returns: A view. - public func sidebarStyle(_ active: Bool = true) -> AnyView { - style("navigation-sidebar", active: active) - } - - /// Apply the boxed list style class. - /// - Parameter active: Whether the style is applied. - /// - Returns: A view. - public func boxedList(_ active: Bool = true) -> AnyView { - style("boxed-list", active: active) - } - -} diff --git a/Sources/Adwaita/View/List.swift b/Sources/Adwaita/View/List.swift index 5276f72..8a75f94 100644 --- a/Sources/Adwaita/View/List.swift +++ b/Sources/Adwaita/View/List.swift @@ -21,17 +21,19 @@ extension List { /// Initialize `List`. /// - Parameters: /// - elements: The elements. + /// - id: The key path to the elements' identifiers. /// - selection: The identifier of the selected element. Selection disabled if `nil`. /// - content: The view for an element. public init( _ elements: [Element], - selection: Binding?, + id: KeyPath, + selection: Binding?, @ViewBuilder content: @escaping (Element) -> Body ) { - self.init(elements, content: content) - let id: (ViewStorage, [Element]) -> Element.ID? = { storage, elements in + self.init(elements, id: id, content: content) + let getID: (ViewStorage, [Element]) -> Identifier? = { storage, elements in if let row = gtk_list_box_get_selected_row(storage.opaquePointer) { - return elements[safe: .init(gtk_list_box_row_get_index(row))]?.id + return elements[safe: .init(gtk_list_box_row_get_index(row))]?[keyPath: id] } return nil } @@ -39,13 +41,13 @@ extension List { updateFunctions.append { storage, _, _ in storage.connectSignal(name: "selected_rows_changed", id: Self.selectionField) { if let elements = storage.fields[Self.elementsField] as? [Element], - let id = id(storage, elements), + let id = getID(storage, elements), selection.wrappedValue != id { selection.wrappedValue = id } } - if selection.wrappedValue != id(storage, elements), - let index = elements.firstIndex(where: { $0.id == selection.wrappedValue })?.cInt { + if selection.wrappedValue != getID(storage, elements), + let index = elements.firstIndex(where: { $0[keyPath: id] == selection.wrappedValue })?.cInt { gtk_list_box_select_row( storage.opaquePointer, gtk_list_box_get_row_at_index(storage.opaquePointer, index) @@ -59,4 +61,35 @@ extension List { } } + /// Add the "navigation-sidebar" style class. + /// - Parameter active: Whether the style is applied. + /// - Returns: A view. + public func sidebarStyle(_ active: Bool = true) -> AnyView { + style("navigation-sidebar", active: active) + } + + /// Apply the boxed list style class. + /// - Parameter active: Whether the style is applied. + /// - Returns: A view. + public func boxedList(_ active: Bool = true) -> AnyView { + style("boxed-list", active: active) + } + +} + +extension List where Element: Identifiable, Element.ID == Identifier { + + /// Initialize `List`. + /// - Parameters: + /// - elements: The elements. + /// - selection: The identifier of the selected element. Selection disabled if `nil`. + /// - content: The view for an element. + public init( + _ elements: [Element], + selection: Binding?, + @ViewBuilder content: @escaping (Element) -> Body + ) { + self.init(elements, id: \.id, selection: selection, content: content) + } + } diff --git a/Sources/Adwaita/View/ToggleGroup+.swift b/Sources/Adwaita/View/ToggleGroup+.swift index 44a1c7a..9b6aa29 100644 --- a/Sources/Adwaita/View/ToggleGroup+.swift +++ b/Sources/Adwaita/View/ToggleGroup+.swift @@ -23,72 +23,103 @@ extension ToggleGroup { selection: Binding, values: [Element] ) where Element: ToggleGroupItem { + self.init( + selection: selection, + values: values, + id: \.id, + label: \.id.description, + icon: \.icon, + showLabel: \.showLabel + ) + } + + /// Initialize a toggle group. + /// - Parameters: + /// - selection: The selected value. + /// - values: The available values. + /// - id: The path to the identifier. + /// - label: The path to the label. + /// - icon: The path to the icon. + /// - showLabel: The path to the boolean that defines whether to show an element's label. + public init( + selection: Binding, + values: [Element], + id: KeyPath, + label: KeyPath, + icon: KeyPath? = nil, + showLabel: KeyPath? = nil + ) where Identifier: Equatable { self.init() appearFunctions.append { storage, _ in storage.notify(name: "active-name", id: "init") { if let name = adw_toggle_group_get_active_name(storage.opaquePointer), let values = storage.fields[Self.values] as? [Element], - let value = values.first(where: { $0.id.description == String(cString: name) }) { - selection.wrappedValue = value.id + let identifier = values + .map({ $0[keyPath: label] }).first(where: { $0.description == String(cString: name) }), + let value = values.first(where: { $0[keyPath: label] == identifier }) { + selection.wrappedValue = value[keyPath: id] } } - Self.updateContent( - storage: storage, - selection: selection.wrappedValue, - values: values, - updateProperties: true - ) } updateFunctions.append { storage, _, updateProperties in Self.updateContent( storage: storage, selection: selection.wrappedValue, values: values, + id: id, + label: label, + icon: icon, + showLabel: showLabel, updateProperties: updateProperties ) } } + // swiftlint:disable function_parameter_count /// Update the combo row's content. - /// - Parameters: - /// - storage: The view storage. - /// - values: The elements. - /// - updateProperties: Whether to update the properties. - static func updateContent( + static func updateContent( storage: ViewStorage, - selection: Element.ID, + selection: Identifier, values: [Element], + id: KeyPath, + label: KeyPath, + icon: KeyPath?, + showLabel: KeyPath?, updateProperties: Bool - ) where Element: ToggleGroupItem { + ) where Identifier: Equatable { guard updateProperties else { return } let old = storage.fields[Self.values] as? [Element] ?? [] - old.identifiableTransform( + old.transform( to: values, + id: id, functions: .init { index in - if let id = old[safe: index]?.id.description, + if let id = old[safe: index]?[keyPath: label], let toggle = storage.fields[Self.toggle + id] as? OpaquePointer { adw_toggle_group_remove(storage.opaquePointer, toggle) } } insert: { _, element in let toggle = adw_toggle_new() - adw_toggle_set_name(toggle, element.id.description) - if element.showLabel { - adw_toggle_set_label(toggle, element.id.description) + adw_toggle_set_name(toggle, element[keyPath: label]) + if let showLabel, !element[keyPath: showLabel] { + adw_toggle_set_tooltip(toggle, element[keyPath: label]) } else { - adw_toggle_set_tooltip(toggle, element.id.description) + adw_toggle_set_label(toggle, element[keyPath: label]) } - if let icon = element.icon { + if let icon, let icon = element[keyPath: icon] { adw_toggle_set_icon_name(toggle, icon.string) } - storage.fields[Self.toggle + element.id.description] = toggle + storage.fields[Self.toggle + element[keyPath: label]] = toggle adw_toggle_group_add(storage.opaquePointer, toggle) } ) storage.fields[Self.values] = values - adw_toggle_group_set_active_name(storage.opaquePointer, selection.description) + if let selection = values.first(where: { $0[keyPath: id] == selection }) { + adw_toggle_group_set_active_name(storage.opaquePointer, selection[keyPath: label]) + } } + // swiftlint:enable function_parameter_count } diff --git a/Sources/Demo/ToggleGroupDemo.swift b/Sources/Demo/ToggleGroupDemo.swift index 1272130..d916191 100644 --- a/Sources/Demo/ToggleGroupDemo.swift +++ b/Sources/Demo/ToggleGroupDemo.swift @@ -15,8 +15,13 @@ struct ToggleGroupDemo: View { @State private var selection: Subview = .view1 var view: Body { - ToggleGroup(selection: $selection, values: Subview.allCases) - .padding() + ToggleGroup( + selection: $selection, + values: Subview.allCases, + id: \.self, + label: \.rawValue + ) + .padding() VStack { Text(selection.rawValue) .padding() @@ -26,19 +31,11 @@ struct ToggleGroupDemo: View { .padding() } - enum Subview: String, ToggleGroupItem, CaseIterable, CustomStringConvertible { + enum Subview: String, CaseIterable, Equatable { case view1 = "View 1" case view2 = "View 2" - var id: Self { self } - - var description: String { rawValue } - - var icon: Icon? { nil } - - var showLabel: Bool { true } - } } diff --git a/Sources/Generation/GIR/Class+.swift b/Sources/Generation/GIR/Class+.swift index 460ebe8..b768730 100644 --- a/Sources/Generation/GIR/Class+.swift +++ b/Sources/Generation/GIR/Class+.swift @@ -24,7 +24,7 @@ extension Class { .filter { config.requiredProperties.contains($0.name) } var initializer = "\(config.internalInitializer ? "" : "public ")init(" if config.dynamicWidget != nil { - initializer.append("_ elements: [Element], ") + initializer.append("_ elements: [Element], id: KeyPath, ") } for property in requiredProperties { initializer.append("\(property.parameter(config: config, genConfig: genConfig)), ") @@ -46,6 +46,7 @@ extension Class { self.elements = elements self.content = content + self.id = id """ ) } @@ -167,6 +168,8 @@ extension Class { var elements: [Element] /// The dynamic widget content. var content: (Element) -> Body + /// The dynamic widget identifier key path. + var id: KeyPath """ } content += staticWidgetProperties(namespace: namespace, configs: configs) @@ -226,8 +229,9 @@ extension Class { return """ var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? [] let old = storage.fields["element"] as? [Element] ?? [] - old.identifiableTransform( + old.transform( to: elements, + id: id, functions: .init { index in \(dynamicWidget.remove)(\(widget), \(dynamicWidget.getElement)) contentStorage.remove(at: index) diff --git a/Sources/Generation/GIR/Class.swift b/Sources/Generation/GIR/Class.swift index b6e6384..3d2d204 100644 --- a/Sources/Generation/GIR/Class.swift +++ b/Sources/Generation/GIR/Class.swift @@ -64,10 +64,25 @@ struct Class: ClassLike, Decodable { dateFormatter.dateFormat = "dd.MM.yy" let widgetName = config.name ?? config.class let definition: String + var extensions = "" if config.dynamicWidget == nil { definition = "\(widgetName): AdwaitaWidget" } else { - definition = "\(widgetName): AdwaitaWidget where Element: Identifiable" + definition = "\(widgetName): AdwaitaWidget where Identifier: Equatable" + extensions += """ + + extension \(widgetName) where Element: Identifiable, Identifier == Element.ID { + + /// Initialize `\(widgetName)`. + public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) { + self.elements = elements + self.content = content + self.id = \\.id + } + + } + + """ } return """ // @@ -135,7 +150,7 @@ struct Class: ClassLike, Decodable { } \(generateModifiers(config: config, genConfig: genConfig, namespace: namespace, configs: configs)) } - + \(extensions) """ } // swiftlint:enable function_body_length line_length