Add support for pickers
This commit is contained in:
parent
43f53e1681
commit
badc0c12f6
59
Sources/Core/View/Picker.swift
Normal file
59
Sources/Core/View/Picker.swift
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
//
|
||||||
|
// Picker.swift
|
||||||
|
// MacBackend
|
||||||
|
//
|
||||||
|
// Created by david-swift on 08.12.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
/// A picker view.
|
||||||
|
public struct Picker<Item>: SwiftUIWidget where Item: Hashable, Item: CustomStringConvertible {
|
||||||
|
|
||||||
|
/// The selected item.
|
||||||
|
@Meta.Binding var selection: Item
|
||||||
|
/// The picker's label.
|
||||||
|
var label: String
|
||||||
|
/// The picker's items.
|
||||||
|
var items: [Item]
|
||||||
|
/// Whether to use the segmented picker stlye.
|
||||||
|
var segmented = false
|
||||||
|
|
||||||
|
/// Initialize the picker.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - label: The picker's label.
|
||||||
|
/// - items: The picker's items.
|
||||||
|
/// - selection: The selected item.
|
||||||
|
public init(_ label: String, items: [Item], selection: Meta.Binding<Item>) {
|
||||||
|
self._selection = selection
|
||||||
|
self.label = label
|
||||||
|
self.items = items
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the SwiftUI view.
|
||||||
|
/// - Parameter properties: The widget data.
|
||||||
|
/// - Returns: The SwiftUI view.
|
||||||
|
public static func view(properties: Picker<Item>) -> some SwiftUI.View {
|
||||||
|
let picker = SwiftUI.Picker(properties.label, selection: properties._selection.swiftUI) {
|
||||||
|
ForEach(properties.items, id: \.hashValue) { item in
|
||||||
|
SwiftUI.Text(item.description)
|
||||||
|
.tag(item.description)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if properties.segmented {
|
||||||
|
picker
|
||||||
|
.pickerStyle(.segmented)
|
||||||
|
} else {
|
||||||
|
picker
|
||||||
|
.pickerStyle(.automatic)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Make the picker segmented.
|
||||||
|
/// - Parameter segmented: Whether the picker is segmented.
|
||||||
|
/// - Returns: The picker.
|
||||||
|
public func segmented(_ segmented: Bool = true) -> Self {
|
||||||
|
modify { $0.segmented = segmented }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -14,6 +14,8 @@ public struct ToolbarView: SwiftUIWidget {
|
|||||||
var child: Meta.AnyView
|
var child: Meta.AnyView
|
||||||
/// The toolbar views.
|
/// The toolbar views.
|
||||||
var toolbarViews: Body
|
var toolbarViews: Body
|
||||||
|
/// The toolbar type.
|
||||||
|
var toolbarType: ToolbarType = .end
|
||||||
|
|
||||||
/// The wrapped views.
|
/// The wrapped views.
|
||||||
public var wrappedViews: [String: Meta.AnyView] {
|
public var wrappedViews: [String: Meta.AnyView] {
|
||||||
@ -25,22 +27,61 @@ public struct ToolbarView: SwiftUIWidget {
|
|||||||
/// Initialize the padding view.
|
/// Initialize the padding view.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - child: The wrapped view.
|
/// - child: The wrapped view.
|
||||||
|
/// - type: The position.
|
||||||
/// - toolbarViews: The views in the toolbar.
|
/// - toolbarViews: The views in the toolbar.
|
||||||
public init(child: Meta.AnyView, @Meta.ViewBuilder toolbarViews: () -> Body) {
|
public init(child: Meta.AnyView, type: ToolbarType, @Meta.ViewBuilder toolbarViews: () -> Body) {
|
||||||
self.child = child
|
self.child = child
|
||||||
self.toolbarViews = toolbarViews()
|
self.toolbarViews = toolbarViews()
|
||||||
|
self.toolbarType = type
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The type of toolbar.
|
||||||
|
public enum ToolbarType {
|
||||||
|
|
||||||
|
/// A leading toolbar.
|
||||||
|
case start
|
||||||
|
/// A trailing toolbar.
|
||||||
|
case end
|
||||||
|
/// A centered toolbar.
|
||||||
|
case center
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the SwiftUI view.
|
/// Get the SwiftUI view.
|
||||||
/// - Parameter properties: The widget data.
|
/// - Parameter properties: The widget data.
|
||||||
/// - Returns: The SwiftUI view.
|
/// - Returns: The SwiftUI view.
|
||||||
public static func view(properties: Self) -> some SwiftUI.View {
|
public static func view(properties: Self) -> some SwiftUI.View {
|
||||||
|
switch properties.toolbarType {
|
||||||
|
case .end:
|
||||||
MacBackendView(.mainContent)
|
MacBackendView(.mainContent)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ForEach(properties.toolbarViews.indices, id: \.self) { index in
|
ForEach(properties.toolbarViews.indices, id: \.self) { index in
|
||||||
MacBackendView("\(index)")
|
MacBackendView("\(index)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case .start:
|
||||||
|
MacBackendView(.mainContent)
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .navigation) {
|
||||||
|
SwiftUI.HStack {
|
||||||
|
ForEach(properties.toolbarViews.indices, id: \.self) { index in
|
||||||
|
MacBackendView("\(index)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case .center:
|
||||||
|
MacBackendView(.mainContent)
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .principal) {
|
||||||
|
SwiftUI.HStack {
|
||||||
|
ForEach(properties.toolbarViews.indices, id: \.self) { index in
|
||||||
|
MacBackendView("\(index)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,8 +25,17 @@ struct Demo: App {
|
|||||||
@State private var selectedElement: String?
|
@State private var selectedElement: String?
|
||||||
@State private var alert = false
|
@State private var alert = false
|
||||||
@State private var menuPresented = false
|
@State private var menuPresented = false
|
||||||
|
@State private var selection = "Hello"
|
||||||
|
|
||||||
var scene: Scene {
|
var scene: Scene {
|
||||||
|
Window(id: "secondary") { _ in
|
||||||
|
Text(selection)
|
||||||
|
.centeredToolbar {
|
||||||
|
Picker("Test", items: ["Hello", "World"], selection: $selection)
|
||||||
|
.segmented()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(width: .constant(800), height: .constant(600))
|
||||||
Window("Main", id: "main") { _ in
|
Window("Main", id: "main") { _ in
|
||||||
NavigationSplitView {
|
NavigationSplitView {
|
||||||
List(elements, selection: $selectedElement) { element in
|
List(elements, selection: $selectedElement) { element in
|
||||||
|
|||||||
@ -39,11 +39,25 @@ extension AnyView {
|
|||||||
MenuWrapper(content: { self }, isPresented: isPresented, menu: menu)
|
MenuWrapper(content: { self }, isPresented: isPresented, menu: menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the toolbar.
|
/// Add toolbar items to the end.
|
||||||
/// - Parameter content: The toolbar's content.
|
/// - Parameter content: The toolbar's content.
|
||||||
/// - Returns: The view.
|
/// - Returns: The view.
|
||||||
public func toolbar(@ViewBuilder content: () -> Body) -> AnyView {
|
public func toolbar(@ViewBuilder content: () -> Body) -> AnyView {
|
||||||
ToolbarView(child: self, toolbarViews: content)
|
ToolbarView(child: self, type: .end, toolbarViews: content)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add toolbar items to the start.
|
||||||
|
/// - Parameter content: The toolbar's content.
|
||||||
|
/// - Returns: The view.
|
||||||
|
public func leadingToolbar(@ViewBuilder content: () -> Body) -> AnyView {
|
||||||
|
ToolbarView(child: self, type: .start, toolbarViews: content)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add centered toolbar items.
|
||||||
|
/// - Parameter content: The toolbar's content.
|
||||||
|
/// - Returns: The view.
|
||||||
|
public func centeredToolbar(@ViewBuilder content: () -> Body) -> AnyView {
|
||||||
|
ToolbarView(child: self, type: .center, toolbarViews: content)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user