Skip to content

Commit 53c354d

Browse files
authored
Merge pull request #38 from mtj0928/support-macro
support macro
2 parents 2c58432 + 1773e88 commit 53c354d

File tree

57 files changed

+458
-127
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+458
-127
lines changed

Package.resolved

+19-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,27 @@
1414
"kind" : "remoteSourceControl",
1515
"location" : "https://github.com/apple/swift-docc-plugin",
1616
"state" : {
17-
"revision" : "3303b164430d9a7055ba484c8ead67a52f7b74f6",
17+
"revision" : "26ac5758409154cc448d7ab82389c520fa8a8247",
18+
"version" : "1.3.0"
19+
}
20+
},
21+
{
22+
"identity" : "swift-docc-symbolkit",
23+
"kind" : "remoteSourceControl",
24+
"location" : "https://github.com/apple/swift-docc-symbolkit",
25+
"state" : {
26+
"revision" : "b45d1f2ed151d057b54504d653e0da5552844e34",
1827
"version" : "1.0.0"
1928
}
29+
},
30+
{
31+
"identity" : "swift-syntax",
32+
"kind" : "remoteSourceControl",
33+
"location" : "https://github.com/apple/swift-syntax.git",
34+
"state" : {
35+
"revision" : "67c5007099d9ffdd292f421f81f4efe5ee42963e",
36+
"version" : "509.0.0-swift-DEVELOPMENT-SNAPSHOT-2023-07-10-a"
37+
}
2038
}
2139
],
2240
"version" : 2

Package.swift

+24-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
// swift-tools-version: 5.7
1+
// swift-tools-version: 5.9
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
5+
import CompilerPluginSupport
56

67
let package = Package(
78
name: "SlideKit",
@@ -12,9 +13,29 @@ let package = Package(
1213
dependencies: [
1314
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
1415
.package(url: "https://github.com/JohnSundell/Splash", from: "0.1.0"),
16+
.package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0"),
1517
],
1618
targets: [
17-
.target(name: "SlideKit", dependencies: ["Splash"]),
18-
.testTarget(name: "SlideKitTests", dependencies: ["SlideKit"]),
19+
.target(
20+
name: "SlideKit",
21+
dependencies: [
22+
"SlideKitMacros",
23+
"Splash"
24+
]
25+
),
26+
.macro(
27+
name: "SlideKitMacros",
28+
dependencies: [
29+
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
30+
.product(name: "SwiftCompilerPlugin", package: "swift-syntax")
31+
]
32+
),
33+
.testTarget(
34+
name: "SlideKitTests",
35+
dependencies: [
36+
"SlideKit",
37+
.product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax")
38+
]
39+
)
1940
]
2041
)

README.md

+9-4
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ You can easily make presentation slides and customize the design perfectly becau
55

66
![Slides](https://user-images.githubusercontent.com/12427733/190956930-ea9ce4d0-0a19-4bb3-b43b-28dd2d73374a.png)
77

8+
## Requirements
9+
- Xcode 15+
10+
- Swift 5.9
811

9-
## Document
12+
## Documents
1013
First, see the [Tutorial for SlideKit](https://mtj0928.github.io/SlideKit/tutorials/meet-slidekit).
1114
You can learn how to use SlideKit and make presentation slides through making the sample presentation slides.
1215

@@ -22,14 +25,15 @@ If you want to know more details, refer the [DocC Style Document](https://mtj092
2225
- [x] Show the current slide index at bottom right on slide.
2326
- [x] Support two windows, presentation window and presenter window.
2427
- [x] Show scripts on only presenter window (only macOS)
25-
- [x] Provide `PhasedState`, so you can divide a one slide step by step.
28+
- [x] Provide `@Phase`, so you can divide a one slide step by step.
2629
- [x] Export PDF file (only macOS 13+)
2730

2831
## Simple Example
2932
You can create a presentation by SwiftUI like this.
3033

3134
```swift
32-
struct IntroductionSlide: Slide {
35+
@Slide
36+
struct IntroductionSlide: View {
3337
var body: some View {
3438
HeaderSlide("SlideKit") {
3539
Item("SlideKit helps you make presentation slides by SwiftUI")
@@ -47,4 +51,5 @@ And then, this is the result of the code.
4751

4852
## Presentations made with SlideKit
4953
If you make presentations slide with SlideKit, add it to the following litst!!
50-
- [After iOSDC](https://github.com/mtj0928/AfteriOSDC): A presentation which shares the hard points to make presentations slides by SwiftUI. (Japanese)
54+
- [After iOSDC](https://github.com/mtj0928/AfteriOSDC): A presentation, which shares the hard points to make presentations slides by SwiftUI. (Japanese)
55+
- [iOSDC23](https://github.com/mtj0928/iOSDC23) A presentation, which shows a dependency injection strategy on SwiftUI. (Japanese)

SlideKit.xcworkspace/xcshareddata/swiftpm/Package.resolved

+19-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,27 @@
1414
"kind" : "remoteSourceControl",
1515
"location" : "https://github.com/apple/swift-docc-plugin",
1616
"state" : {
17-
"revision" : "3303b164430d9a7055ba484c8ead67a52f7b74f6",
17+
"revision" : "26ac5758409154cc448d7ab82389c520fa8a8247",
18+
"version" : "1.3.0"
19+
}
20+
},
21+
{
22+
"identity" : "swift-docc-symbolkit",
23+
"kind" : "remoteSourceControl",
24+
"location" : "https://github.com/apple/swift-docc-symbolkit",
25+
"state" : {
26+
"revision" : "b45d1f2ed151d057b54504d653e0da5552844e34",
1827
"version" : "1.0.0"
1928
}
29+
},
30+
{
31+
"identity" : "swift-syntax",
32+
"kind" : "remoteSourceControl",
33+
"location" : "https://github.com/apple/swift-syntax.git",
34+
"state" : {
35+
"revision" : "6ad4ea24b01559dde0773e3d091f1b9e36175036",
36+
"version" : "509.0.2"
37+
}
2038
}
2139
],
2240
"version" : 2

SlideKitDemo-iOS/SlideKitDemo-iOS/Slides/BasicSlide.swift

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
import SlideKit
99
import SwiftUI
1010

11-
struct BasicSlide: Slide {
11+
@Slide
12+
struct BasicSlide: View {
1213
var body: some View {
1314
HeaderSlide("Title") {
1415
Item("Hoge") {
@@ -28,7 +29,8 @@ struct BasicSlide: Slide {
2829
}
2930
}
3031

31-
struct SampleSlide: Slide {
32+
@Slide
33+
struct SampleSlide: View {
3234
var body: some View {
3335
HeaderSlide("Sample Slide") {
3436
Item("This is a sample slide.") {

SlideKitDemo-iOS/SlideKitDemo-iOS/Slides/TitleSlide.swift

+5-4
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@
88
import SlideKit
99
import SwiftUI
1010

11-
struct TitleSlide: Slide {
11+
@Slide
12+
struct TitleSlide: View {
1213

1314
enum SlidePhasedState: Int, PhasedState {
1415
case initial, double
1516
}
1617

17-
@Phase var phasedStateStore
18-
1918
let title: String
19+
@Phase var phase: SlidePhasedState
2020

2121
var body: some View {
2222
VStack {
2323
Text(title)
24-
if phasedStateStore.when(.double) {
24+
if phase == .double {
2525
Text(title)
2626
}
2727
}
@@ -35,5 +35,6 @@ struct TitleSlide_Previews: PreviewProvider {
3535
TitleSlide(title: "Hoge")
3636
TitleSlide(title: "Piyo")
3737
}
38+
.preferredColorScheme(.dark)
3839
}
3940
}

SlideKitDemo-macOS/SlideKitDemo-macOS.xcodeproj/project.pbxproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@
311311
"$(inherited)",
312312
"@executable_path/../Frameworks",
313313
);
314-
MACOSX_DEPLOYMENT_TARGET = 12.4;
314+
MACOSX_DEPLOYMENT_TARGET = 13.0;
315315
MARKETING_VERSION = 1.0;
316316
PRODUCT_BUNDLE_IDENTIFIER = "net.matsuji.SlideKitDemo-macOS";
317317
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -340,7 +340,7 @@
340340
"$(inherited)",
341341
"@executable_path/../Frameworks",
342342
);
343-
MACOSX_DEPLOYMENT_TARGET = 12.4;
343+
MACOSX_DEPLOYMENT_TARGET = 13.0;
344344
MARKETING_VERSION = 1.0;
345345
PRODUCT_BUNDLE_IDENTIFIER = "net.matsuji.SlideKitDemo-macOS";
346346
PRODUCT_NAME = "$(TARGET_NAME)";

SlideKitDemo-macOS/SlideKitDemo-macOS/SlideKitDemo_macOSApp.swift

+6-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import SlideKit
1111
@main
1212
struct SlideKitDemo_macOSApp: App {
1313

14+
@Environment(\.openWindow) var openWindow
15+
1416
/// Edit slide configurations in SlideConfiguration.swift
1517
private static let configuration = SlideConfiguration()
1618

@@ -29,10 +31,12 @@ struct SlideKitDemo_macOSApp: App {
2931
presentationContentView
3032
}
3133
}
32-
.setupAsPresentationWindow(Self.configuration.slideIndexController, appName: "slide")
34+
.setupAsPresentationWindow(Self.configuration.slideIndexController) {
35+
openWindow(id: "presenter")
36+
}
3337
.addPDFExportCommands(for: presentationContentView, with: Self.configuration.slideIndexController, size: Self.configuration.size)
3438

35-
WindowGroup {
39+
WindowGroup(id: "presenter") {
3640
macOSPresenterView(
3741
slideSize: Self.configuration.size,
3842
slideIndexController: Self.configuration.slideIndexController

SlideKitDemo-macOS/SlideKitDemo-macOS/Slides/BasicSlide.swift

+7-5
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,22 @@
88
import SlideKit
99
import SwiftUI
1010

11-
struct BasicSlide: Slide {
11+
@Slide
12+
struct BasicSlide: View {
1213

13-
enum SlidePhasedState: Int, PhasedState {
14+
enum SlidePhase: Int, PhasedState {
1415
case initial, next
1516
}
1617

17-
@Phase var phasedStateStore
18+
@Phase var phase: SlidePhase
1819

1920
var body: some View {
2021
HeaderSlide("How to use the slide") {
2122
Item("Please tap the right half of this window") {
2223
Item("You can go to the next state")
2324
Item("You can also use \"return\" or \"\"")
2425
}
25-
if phasedStateStore.when(.next) {
26+
if phase == .next {
2627
Item("Please tap the left half of this window") {
2728
Item("You can back the previous slide")
2829
Item("You can also use \"\"")
@@ -32,7 +33,7 @@ struct BasicSlide: Slide {
3233
}
3334

3435
var script: String {
35-
switch phasedStateStore.current {
36+
switch phase {
3637
case .initial:
3738
return """
3839
Let me show how to use the slide.
@@ -50,6 +51,7 @@ struct BasicSlide_Previews: PreviewProvider {
5051
static var previews: some View {
5152
SlidePreview {
5253
BasicSlide()
54+
.phase(.next)
5355
}
5456
}
5557
}

SlideKitDemo-macOS/SlideKitDemo-macOS/Slides/CustomHeaderStyleSlide.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
import SlideKit
99
import SwiftUI
1010

11-
struct CustomHeaderStyleSlide: Slide {
11+
@Slide
12+
struct CustomHeaderStyleSlide: View {
1213
var body: some View {
1314
HeaderSlide("Custom Style Slide") {
1415
Item("Header Slide Style") {

Sources/SlideKit/EnvironmentValues/EnvironmentValues+ObservableObjectContainer.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77

88
import SwiftUI
99

10-
private enum Key: EnvironmentKey {
11-
static let defaultValue = ObservableObjectContainer()
10+
public enum ObservableObjectContainerKey: EnvironmentKey {
11+
public static let defaultValue = ObservableObjectContainer()
1212
}
1313

1414
extension EnvironmentValues {
1515

1616
public var observableObjectContainer: ObservableObjectContainer {
17-
get { self[Key.self] }
18-
set { self[Key.self] = newValue }
17+
get { self[ObservableObjectContainerKey.self] }
18+
set { self[ObservableObjectContainerKey.self] = newValue }
1919
}
2020
}

Sources/SlideKit/PhaseWrapper.swift

+19-7
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,34 @@ import SwiftUI
1111
@propertyWrapper
1212
public struct PhaseWrapper<State: PhasedState>: DynamicProperty {
1313

14-
@Environment(\.observableObjectContainer)
15-
private var observableObjectContainer
14+
@Environment(\.slideIndexController)
15+
private var slideIndexController
1616

1717
@ObservedObject
1818
private var internalPhasedStore = InternalObservableObject<PhasedStateStore<State>>()
1919

2020
public init() {
2121
}
2222

23-
public var wrappedValue: PhasedStateStore<State> {
24-
if internalPhasedStore.observedObject == nil {
25-
internalPhasedStore.observedObject = observableObjectContainer.resolve {
26-
PhasedStateStore()
23+
public var wrappedValue: State {
24+
get {
25+
projectedValue.current
26+
}
27+
set {
28+
projectedValue.current = newValue
29+
}
30+
}
31+
32+
public var projectedValue: PhasedStateStore<State> {
33+
get {
34+
if internalPhasedStore.observedObject == nil {
35+
internalPhasedStore.observedObject = slideIndexController?.phaseStateStore()
2736
}
37+
return internalPhasedStore.observedObject!
38+
}
39+
nonmutating set {
40+
internalPhasedStore.observedObject = newValue
2841
}
29-
return internalPhasedStore.observedObject!
3042
}
3143
}
3244

Sources/SlideKit/PhasedStateStore.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ protocol PhasedStateStoreProtocol {
1616

1717
public class PhasedStateStore<State: PhasedState>: ObservableObject, PhasedStateStoreProtocol {
1818

19-
@Published public private(set) var current: State
19+
@Published public var current: State
2020

2121
public init(_ state: State = .initial) {
2222
self.current = state

Sources/SlideKit/Slide.swift

+5-19
Original file line numberDiff line numberDiff line change
@@ -40,35 +40,21 @@ public protocol Slide: View {
4040
/// The default type is ``SimplePhasedState``.
4141
associatedtype SlidePhasedState: PhasedState
4242

43-
typealias Phase = PhaseWrapper<SlidePhasedState>
44-
45-
/// A store which controls current `SlidePhasedState`.
46-
///
47-
/// You can get current `SlidePhasedState` and forward / back it.
48-
/// > Note: The property must be defined with `Phase` like the bellow.
49-
///
50-
/// ```swift
51-
/// @Phase var phasedStateStore: PhasedStateStore<SlidePhasedState>
52-
/// ```
53-
var phasedStateStore: PhasedStateStore<SlidePhasedState> { get }
54-
5543
/// A script for the current slide. The script will be shown on presenter view (macOS only).
5644
/// The default value is an empty String.
5745
var script: String { get }
5846

5947
/// A boolean value indicating whether the slide index at the right bottom is hidden or not.
6048
/// The default value is `false`
6149
var shouldHideIndex: Bool { get }
50+
51+
/// Inject PhasedStateStore.
52+
/// This function should be called by SlideKit, please do not call the function.
53+
func phasesStateSore(_ phasedStateStore: PhasedStateStore<SlidePhasedState>)
6254
}
6355

6456
extension Slide {
6557
public var script: String { "" }
6658
public var shouldHideIndex: Bool { false }
67-
}
68-
69-
extension Slide where SlidePhasedState == SimplePhasedState {
70-
71-
public var phasedStateStore: PhasedStateStore<SimplePhasedState> {
72-
PhasedStateStore()
73-
}
59+
public func phasesStateSore(_ phasedStateStore: PhasedStateStore<SlidePhasedState>) {}
7460
}

0 commit comments

Comments
 (0)