Skip to content

Commit

Permalink
Merge pull request #38 from mtj0928/support-macro
Browse files Browse the repository at this point in the history
support macro
  • Loading branch information
mtj0928 committed Dec 15, 2023
2 parents 2c58432 + 1773e88 commit 53c354d
Show file tree
Hide file tree
Showing 57 changed files with 458 additions and 127 deletions.
20 changes: 19 additions & 1 deletion Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,27 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-plugin",
"state" : {
"revision" : "3303b164430d9a7055ba484c8ead67a52f7b74f6",
"revision" : "26ac5758409154cc448d7ab82389c520fa8a8247",
"version" : "1.3.0"
}
},
{
"identity" : "swift-docc-symbolkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-symbolkit",
"state" : {
"revision" : "b45d1f2ed151d057b54504d653e0da5552844e34",
"version" : "1.0.0"
}
},
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"state" : {
"revision" : "67c5007099d9ffdd292f421f81f4efe5ee42963e",
"version" : "509.0.0-swift-DEVELOPMENT-SNAPSHOT-2023-07-10-a"
}
}
],
"version" : 2
Expand Down
27 changes: 24 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// swift-tools-version: 5.7
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
import CompilerPluginSupport

let package = Package(
name: "SlideKit",
Expand All @@ -12,9 +13,29 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
.package(url: "https://github.com/JohnSundell/Splash", from: "0.1.0"),
.package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0"),
],
targets: [
.target(name: "SlideKit", dependencies: ["Splash"]),
.testTarget(name: "SlideKitTests", dependencies: ["SlideKit"]),
.target(
name: "SlideKit",
dependencies: [
"SlideKitMacros",
"Splash"
]
),
.macro(
name: "SlideKitMacros",
dependencies: [
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
.product(name: "SwiftCompilerPlugin", package: "swift-syntax")
]
),
.testTarget(
name: "SlideKitTests",
dependencies: [
"SlideKit",
.product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax")
]
)
]
)
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ You can easily make presentation slides and customize the design perfectly becau

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

## Requirements
- Xcode 15+
- Swift 5.9

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

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

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

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

## Presentations made with SlideKit
If you make presentations slide with SlideKit, add it to the following litst!!
- [After iOSDC](https://github.com/mtj0928/AfteriOSDC): A presentation which shares the hard points to make presentations slides by SwiftUI. (Japanese)
- [After iOSDC](https://github.com/mtj0928/AfteriOSDC): A presentation, which shares the hard points to make presentations slides by SwiftUI. (Japanese)
- [iOSDC23](https://github.com/mtj0928/iOSDC23) A presentation, which shows a dependency injection strategy on SwiftUI. (Japanese)
20 changes: 19 additions & 1 deletion SlideKit.xcworkspace/xcshareddata/swiftpm/Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,27 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-plugin",
"state" : {
"revision" : "3303b164430d9a7055ba484c8ead67a52f7b74f6",
"revision" : "26ac5758409154cc448d7ab82389c520fa8a8247",
"version" : "1.3.0"
}
},
{
"identity" : "swift-docc-symbolkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-symbolkit",
"state" : {
"revision" : "b45d1f2ed151d057b54504d653e0da5552844e34",
"version" : "1.0.0"
}
},
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"state" : {
"revision" : "6ad4ea24b01559dde0773e3d091f1b9e36175036",
"version" : "509.0.2"
}
}
],
"version" : 2
Expand Down
6 changes: 4 additions & 2 deletions SlideKitDemo-iOS/SlideKitDemo-iOS/Slides/BasicSlide.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
import SlideKit
import SwiftUI

struct BasicSlide: Slide {
@Slide
struct BasicSlide: View {
var body: some View {
HeaderSlide("Title") {
Item("Hoge") {
Expand All @@ -28,7 +29,8 @@ struct BasicSlide: Slide {
}
}

struct SampleSlide: Slide {
@Slide
struct SampleSlide: View {
var body: some View {
HeaderSlide("Sample Slide") {
Item("This is a sample slide.") {
Expand Down
9 changes: 5 additions & 4 deletions SlideKitDemo-iOS/SlideKitDemo-iOS/Slides/TitleSlide.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@
import SlideKit
import SwiftUI

struct TitleSlide: Slide {
@Slide
struct TitleSlide: View {

enum SlidePhasedState: Int, PhasedState {
case initial, double
}

@Phase var phasedStateStore

let title: String
@Phase var phase: SlidePhasedState

var body: some View {
VStack {
Text(title)
if phasedStateStore.when(.double) {
if phase == .double {
Text(title)
}
}
Expand All @@ -35,5 +35,6 @@ struct TitleSlide_Previews: PreviewProvider {
TitleSlide(title: "Hoge")
TitleSlide(title: "Piyo")
}
.preferredColorScheme(.dark)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "net.matsuji.SlideKitDemo-macOS";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -340,7 +340,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "net.matsuji.SlideKitDemo-macOS";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import SlideKit
@main
struct SlideKitDemo_macOSApp: App {

@Environment(\.openWindow) var openWindow

/// Edit slide configurations in SlideConfiguration.swift
private static let configuration = SlideConfiguration()

Expand All @@ -29,10 +31,12 @@ struct SlideKitDemo_macOSApp: App {
presentationContentView
}
}
.setupAsPresentationWindow(Self.configuration.slideIndexController, appName: "slide")
.setupAsPresentationWindow(Self.configuration.slideIndexController) {
openWindow(id: "presenter")
}
.addPDFExportCommands(for: presentationContentView, with: Self.configuration.slideIndexController, size: Self.configuration.size)

WindowGroup {
WindowGroup(id: "presenter") {
macOSPresenterView(
slideSize: Self.configuration.size,
slideIndexController: Self.configuration.slideIndexController
Expand Down
12 changes: 7 additions & 5 deletions SlideKitDemo-macOS/SlideKitDemo-macOS/Slides/BasicSlide.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@
import SlideKit
import SwiftUI

struct BasicSlide: Slide {
@Slide
struct BasicSlide: View {

enum SlidePhasedState: Int, PhasedState {
enum SlidePhase: Int, PhasedState {
case initial, next
}

@Phase var phasedStateStore
@Phase var phase: SlidePhase

var body: some View {
HeaderSlide("How to use the slide") {
Item("Please tap the right half of this window") {
Item("You can go to the next state")
Item("You can also use \"return\" or \"\"")
}
if phasedStateStore.when(.next) {
if phase == .next {
Item("Please tap the left half of this window") {
Item("You can back the previous slide")
Item("You can also use \"\"")
Expand All @@ -32,7 +33,7 @@ struct BasicSlide: Slide {
}

var script: String {
switch phasedStateStore.current {
switch phase {
case .initial:
return """
Let me show how to use the slide.
Expand All @@ -50,6 +51,7 @@ struct BasicSlide_Previews: PreviewProvider {
static var previews: some View {
SlidePreview {
BasicSlide()
.phase(.next)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
import SlideKit
import SwiftUI

struct CustomHeaderStyleSlide: Slide {
@Slide
struct CustomHeaderStyleSlide: View {
var body: some View {
HeaderSlide("Custom Style Slide") {
Item("Header Slide Style") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

import SwiftUI

private enum Key: EnvironmentKey {
static let defaultValue = ObservableObjectContainer()
public enum ObservableObjectContainerKey: EnvironmentKey {
public static let defaultValue = ObservableObjectContainer()
}

extension EnvironmentValues {

public var observableObjectContainer: ObservableObjectContainer {
get { self[Key.self] }
set { self[Key.self] = newValue }
get { self[ObservableObjectContainerKey.self] }
set { self[ObservableObjectContainerKey.self] = newValue }
}
}
26 changes: 19 additions & 7 deletions Sources/SlideKit/PhaseWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,34 @@ import SwiftUI
@propertyWrapper
public struct PhaseWrapper<State: PhasedState>: DynamicProperty {

@Environment(\.observableObjectContainer)
private var observableObjectContainer
@Environment(\.slideIndexController)
private var slideIndexController

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

public init() {
}

public var wrappedValue: PhasedStateStore<State> {
if internalPhasedStore.observedObject == nil {
internalPhasedStore.observedObject = observableObjectContainer.resolve {
PhasedStateStore()
public var wrappedValue: State {
get {
projectedValue.current
}
set {
projectedValue.current = newValue
}
}

public var projectedValue: PhasedStateStore<State> {
get {
if internalPhasedStore.observedObject == nil {
internalPhasedStore.observedObject = slideIndexController?.phaseStateStore()
}
return internalPhasedStore.observedObject!
}
nonmutating set {
internalPhasedStore.observedObject = newValue
}
return internalPhasedStore.observedObject!
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/SlideKit/PhasedStateStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protocol PhasedStateStoreProtocol {

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

@Published public private(set) var current: State
@Published public var current: State

public init(_ state: State = .initial) {
self.current = state
Expand Down
24 changes: 5 additions & 19 deletions Sources/SlideKit/Slide.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,21 @@ public protocol Slide: View {
/// The default type is ``SimplePhasedState``.
associatedtype SlidePhasedState: PhasedState

typealias Phase = PhaseWrapper<SlidePhasedState>

/// A store which controls current `SlidePhasedState`.
///
/// You can get current `SlidePhasedState` and forward / back it.
/// > Note: The property must be defined with `Phase` like the bellow.
///
/// ```swift
/// @Phase var phasedStateStore: PhasedStateStore<SlidePhasedState>
/// ```
var phasedStateStore: PhasedStateStore<SlidePhasedState> { get }

/// A script for the current slide. The script will be shown on presenter view (macOS only).
/// The default value is an empty String.
var script: String { get }

/// A boolean value indicating whether the slide index at the right bottom is hidden or not.
/// The default value is `false`
var shouldHideIndex: Bool { get }

/// Inject PhasedStateStore.
/// This function should be called by SlideKit, please do not call the function.
func phasesStateSore(_ phasedStateStore: PhasedStateStore<SlidePhasedState>)
}

extension Slide {
public var script: String { "" }
public var shouldHideIndex: Bool { false }
}

extension Slide where SlidePhasedState == SimplePhasedState {

public var phasedStateStore: PhasedStateStore<SimplePhasedState> {
PhasedStateStore()
}
public func phasesStateSore(_ phasedStateStore: PhasedStateStore<SlidePhasedState>) {}
}
Loading

0 comments on commit 53c354d

Please sign in to comment.