From: Ruben Beltran del Rio Date: Wed, 26 Apr 2023 15:10:19 +0000 (+0200) Subject: Add readme, update API X-Git-Tag: 1.0.0~4 X-Git-Url: https://git.r.bdr.sh/rbdr/patterns/commitdiff_plain/1418fe49617f5d35b14b19fe0ead15fcc43526c8 Add readme, update API --- diff --git a/Package.swift b/Package.swift index 1456b7d..b71fe6f 100644 --- a/Package.swift +++ b/Package.swift @@ -6,13 +6,13 @@ import PackageDescription let package = Package( name: "Patterns", platforms: [ - .macOS(.v10_15) + .macOS(.v12) ], products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( name: "Patterns", - targets: ["Patterns"]), + targets: ["Patterns"]) ], dependencies: [ // Dependencies declare other packages that this package depends on. @@ -26,6 +26,6 @@ let package = Package( dependencies: []), .testTarget( name: "PatternsTests", - dependencies: ["Patterns"]), + dependencies: ["Patterns"]) ] ) diff --git a/README.md b/README.md index 3cce40f..803bd2f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,81 @@ # Patterns -SwiftUI tiling black and white patterns +SwiftUI tiling black and white patterns. + +This project contains `Patterns`, which are built out of `Tiles` with a given +`TileDesign`. + +It also includes a `TilePicker` that can be used to control the selected +design. + +## Available Tile Designs + +The `TileDesign` enum contains the following patterns (shown in the image from +top left to bottom right) + +![Image showing the included patterns] + +* `.grid` +* `.dottedGrid` +* `.stitch` +* `.curvedTile` +* `.brick` +* `.tile` +* `.shadowGrid` +* `.circles` +* `.trees` +* `.shingles` +* `.wicker` +* `.rhombus` +* `.balls` + +## Usage + +The `Pattern` view will tile the selected design in its frame. It has the +following properties: + +* `design: TileDesign`: **required, @Binding**, which design to tile the frame with. +* `pixelSize: CGFloat`: **defaults to 2.0**, the size of a pixel in the tile. +* `foregroundColor: Color`: **defaults to `Color.black`**, the foreground color. +* `backgroundColor: Color`: **defaults to `Color.white`**, the background color. + +``` +// Pattern using default settings +Pattern(design: .constant(TileDesign.shadowGrid)) + +// Pattern using overrides +Pattern(design: $tileDesign, pixelSize: 4.0, foregroundColor: .pink, backgroundColor: .cyan) +``` + +## Using the PatternPicker + +The pattern picker view is intended to be used when you want to allow users to +change the design of the pattern. + +* `selectedDesign: TileDesign`: **required, @Binding**, the current selected + tile design. +* `selectedColor: Color`: **defaults to `Color.accentColor`**, the color of the + border around the selected tile design. + +It also has `pixelSize`, `foregroundColor`, and `backgroundColor` with the +same effect as `Pattern` mentioned above + + +``` +@State var design: TileDesign = .brick +@State var shouldShowPatternPicker = false + +... + +Pattern(design: $pattern) + .frame(width: 32.0).border(.black) + .onTapGesture { + shouldShowPatternPicker = !shouldShowPatternPicker; + } + .popover(isPresented: $shouldShowPatternPicker) { + PatternPicker(selectedDesign: $design) + } + .onChange(of: pattern) { _ in + shouldShowPatternPicker = false; + } +``` diff --git a/Sources/Patterns/Pattern.swift b/Sources/Patterns/Pattern.swift index 1951888..4fbc528 100644 --- a/Sources/Patterns/Pattern.swift +++ b/Sources/Patterns/Pattern.swift @@ -1,14 +1,15 @@ import SwiftUI public struct Pattern: View { - - private let pixelSize: CGFloat = 2.0; private var patternSize: CGFloat { pixelSize * 8.0; } @Binding var design: TileDesign; + var pixelSize: CGFloat = 2.0; + var foregroundColor: Color = .black + var backgroundColor: Color = .white public var body: some View { GeometryReader { gr in @@ -16,7 +17,7 @@ public struct Pattern: View { ForEach(0 ..< 1 + Int(ceil(gr.size.height / patternSize)), id: \.self) { i in HStack(spacing: 0) { ForEach(0 ..< Int(ceil(gr.size.width / patternSize)), id: \.self) { j in - Tile(design: design) + Tile(design: design, pixelSize: pixelSize, foregroundColor: foregroundColor, backgroundColor: backgroundColor) } } } @@ -27,6 +28,13 @@ public struct Pattern: View { struct Pattern_Previews: PreviewProvider { static var previews: some View { - Pattern(design: .constant(TileDesign.grid)) + VStack { + Text("Default") + Pattern(design: .constant(TileDesign.grid)) + Text("Color override") + Pattern(design: .constant(TileDesign.balls), foregroundColor: .pink, backgroundColor: .cyan) + Text("Pixel size override") + Pattern(design: .constant(TileDesign.shingles), pixelSize: 8.0) + } } } diff --git a/Sources/Patterns/PatternPicker.swift b/Sources/Patterns/PatternPicker.swift new file mode 100644 index 0000000..1f7d17b --- /dev/null +++ b/Sources/Patterns/PatternPicker.swift @@ -0,0 +1,51 @@ +import SwiftUI + +public struct PatternPicker: View { + + @Binding var selectedDesign: TileDesign; + + var selectedColor: Color = .accentColor + var pixelSize: CGFloat = 2.0; + var foregroundColor: Color = .black + var backgroundColor: Color = .white + + let patterns = TileDesign.allCases + + let verticalTileCount = Int(ceil(Double(TileDesign.allCases.count) / 5.0)) + + public var body: some View { + VStack(alignment: .leading, spacing: 0) { + ForEach(0 ..< verticalTileCount, id: \.self) { i in + HStack(alignment: .top, spacing: 0) { + ForEach(0 ..< 5) { j in + if i * 5 + j < patterns.count { + Pattern(design: .constant(patterns[i * 5 + j]), pixelSize: pixelSize, foregroundColor: foregroundColor, backgroundColor: backgroundColor) + .frame(width: pixelSize * 16, height: pixelSize * 12) + .border(selectedDesign == patterns[i * 5 + j] ? selectedColor : foregroundColor, width: pixelSize / 2.0) + .onTapGesture(perform: { + selectedDesign = patterns[i * 5 + j] + }) + } + } + } + } + }.background(foregroundColor) + } +} + +struct PatternPicker_Previews: PreviewProvider { + static var previews: some View { + VStack { + Text("Default") + PatternPicker(selectedDesign: .constant(TileDesign.shadowGrid)) + Text("Selected color override") + PatternPicker(selectedDesign: .constant(TileDesign.shadowGrid), + selectedColor: .red) + Text("Color override") + PatternPicker(selectedDesign: .constant(TileDesign.shadowGrid), + foregroundColor: .pink, backgroundColor: .cyan) + Text("Pixel size override") + PatternPicker(selectedDesign: .constant(TileDesign.shadowGrid), pixelSize: 8.0) + } + } +} diff --git a/Sources/Patterns/Tile.swift b/Sources/Patterns/Tile.swift index c27fcf9..3893324 100644 --- a/Sources/Patterns/Tile.swift +++ b/Sources/Patterns/Tile.swift @@ -1,16 +1,17 @@ import SwiftUI -struct Tile: View { - - let pixelSize: CGFloat = 2.0; +public struct Tile: View { let design: TileDesign + var pixelSize: CGFloat = 2.0; + var foregroundColor: Color = .black + var backgroundColor: Color = .white private var pixels: [Int] { design.pixels() } - var body: some View { + public var body: some View { VStack(spacing: 0) { ForEach(0 ..< 8) { i in HStack(spacing: 0) { @@ -18,8 +19,8 @@ struct Tile: View { Rectangle() .frame(width: pixelSize, height: pixelSize) .foregroundColor(pixels[(i % 8) * 8 + j % 8] == 0 - ? .black - : .white + ? foregroundColor + : backgroundColor ) } } @@ -30,6 +31,13 @@ struct Tile: View { struct Tile_Previews: PreviewProvider { static var previews: some View { - Tile(design: .grid) + VStack { + Text("Default") + Tile(design: .grid) + Text("Color override") + Tile(design: .balls, foregroundColor: .pink, backgroundColor: .cyan) + Text("Pixel size override") + Tile(design: .shingles, pixelSize: 8.0) + } } }