├── .editorconfig
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ └── bug_report.md
└── workflows
│ ├── ci.yml
│ ├── codecov.yml
│ ├── label.yml
│ └── swiftlint.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .swift-version
├── .swiftformat
├── .swiftlint.yml
├── .vscode
├── settings.json
└── tasks.json
├── Brewfile
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── NativeDemo
├── Info.plist
├── LaunchScreen.storyboard
├── NSAppDelegate.swift
├── TokamakDemo Native.entitlements
├── TokamakDemo.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── UIAppDelegate.swift
├── iOS Info.plist
└── macOS.storyboard
├── Package.resolved
├── Package.swift
├── README.md
├── Sources
├── CGDK
│ ├── CGDK-Bridging-Header.h
│ ├── module.modulemap
│ └── termios-Header.h
├── CGTK
│ ├── CGTK-Bridging-Header.h
│ ├── module.modulemap
│ └── termios-Header.h
├── TokamakCore
│ ├── Animation
│ │ ├── Animatable.swift
│ │ ├── AnimatableModifier.swift
│ │ ├── Animation.swift
│ │ ├── Transaction.swift
│ │ ├── VectorArithmetic.swift
│ │ ├── _AnimationBoxBase.swift
│ │ ├── _AnimationSolvers.swift
│ │ ├── _AnyAnimatableData.swift
│ │ └── _VectorMath.swift
│ ├── App
│ │ ├── App.swift
│ │ ├── AppStorage.swift
│ │ ├── Scenes
│ │ │ ├── Scene.swift
│ │ │ ├── SceneBuilder.swift
│ │ │ ├── ScenePhase.swift
│ │ │ ├── SceneStorage.swift
│ │ │ ├── WindowGroup.swift
│ │ │ └── _SceneModifier.swift
│ │ ├── _AnyApp.swift
│ │ ├── _AnyScene.swift
│ │ ├── _StorageProvider.swift
│ │ └── _TupleScene.swift
│ ├── DynamicProperty.swift
│ ├── Environment
│ │ ├── Environment.swift
│ │ ├── EnvironmentKey.swift
│ │ ├── EnvironmentObject.swift
│ │ ├── EnvironmentValues.swift
│ │ └── EnvironmentalModifier.swift
│ ├── Fiber
│ │ ├── AlignmentID.swift
│ │ ├── App
│ │ │ └── AppVisitor.swift
│ │ ├── Fiber+Content.swift
│ │ ├── Fiber+CustomDebugStringConvertible.swift
│ │ ├── Fiber.swift
│ │ ├── FiberElement.swift
│ │ ├── FiberReconciler+TreeReducer.swift
│ │ ├── FiberReconciler.swift
│ │ ├── FiberRenderer.swift
│ │ ├── Layout
│ │ │ ├── ContainedZLayout.swift
│ │ │ ├── Layout.swift
│ │ │ ├── LayoutPriority.swift
│ │ │ ├── LayoutProperties.swift
│ │ │ ├── LayoutSubviews.swift
│ │ │ ├── LayoutValueKey.swift
│ │ │ ├── PaddingLayout+Layout.swift
│ │ │ ├── ProposedViewSize.swift
│ │ │ ├── StackLayout.swift
│ │ │ ├── ViewSpacing.swift
│ │ │ ├── _AspectRatioLayout+Layout.swift
│ │ │ ├── _FlexFrameLayout+Layout.swift
│ │ │ └── _FrameLayout+Layout.swift
│ │ ├── Mutation.swift
│ │ ├── Passes
│ │ │ ├── FiberReconcilerPass.swift
│ │ │ ├── LayoutPass.swift
│ │ │ └── ReconcilePass.swift
│ │ ├── Scene
│ │ │ ├── SceneArguments.swift
│ │ │ └── SceneVisitor.swift
│ │ ├── ViewArguments.swift
│ │ ├── ViewGeometry.swift
│ │ ├── ViewVisitor.swift
│ │ └── walk.swift
│ ├── Modifiers
│ │ ├── AppearanceActionModifier.swift
│ │ ├── AspectRatioLayout.swift
│ │ ├── Effects
│ │ │ ├── ClipEffect.swift
│ │ │ ├── GeometryEffect.swift
│ │ │ ├── OffsetEffect.swift
│ │ │ ├── OpacityEffect.swift
│ │ │ ├── RotationEffect.swift
│ │ │ └── ScaleEffect.swift
│ │ ├── FlexFrameLayout.swift
│ │ ├── FrameLayout.swift
│ │ ├── HoverActionModifier.swift
│ │ ├── LifecycleModifier.swift
│ │ ├── ModifiedContent.swift
│ │ ├── Navigation.swift
│ │ ├── PaddingLayout.swift
│ │ ├── RedactionReasons.swift
│ │ ├── ShadowLayout.swift
│ │ ├── StyleModifiers.swift
│ │ ├── TaskModifier.swift
│ │ ├── ViewModifier.swift
│ │ └── ZIndexModifier.swift
│ ├── MountedViews
│ │ ├── MountedApp.swift
│ │ ├── MountedCompositeElement.swift
│ │ ├── MountedCompositeView.swift
│ │ ├── MountedElement.swift
│ │ ├── MountedEmptyView.swift
│ │ ├── MountedHostView.swift
│ │ ├── MountedScene.swift
│ │ └── UnmountTask.swift
│ ├── Preferences
│ │ ├── PreferenceKey.swift
│ │ ├── _PreferenceActionModifier.swift
│ │ ├── _PreferenceReadingView.swift
│ │ ├── _PreferenceTransformModifier.swift
│ │ └── _PreferenceWritingModifier.swift
│ ├── PreviewProvider.swift
│ ├── Reflection
│ │ ├── Layouts
│ │ │ ├── ExistentialContainter.swift
│ │ │ ├── FieldDescriptor.swift
│ │ │ ├── ProtocolTypeContainer.swift
│ │ │ ├── StructMetadataLayout.swift
│ │ │ ├── StructTypeDescriptor.swift
│ │ │ ├── TargetTypeGenericContextDescriptorHeader.swift
│ │ │ └── ValueWitnessTable.swift
│ │ ├── Metadata
│ │ │ ├── Metadata.swift
│ │ │ ├── MetadataState.swift
│ │ │ └── StructMetadata.swift
│ │ ├── Models
│ │ │ ├── Kind.swift
│ │ │ ├── PropertyInfo.swift
│ │ │ └── TypeInfo.swift
│ │ ├── Pointers
│ │ │ ├── MetadataOffset.swift
│ │ │ ├── Pointers.swift
│ │ │ └── RelativeVectorPointer.swift
│ │ ├── Utilities
│ │ │ ├── GettersSetters.swift
│ │ │ └── Pointer+Extensions.swift
│ │ └── typeConstructorName.swift
│ ├── Renderer.swift
│ ├── Shapes
│ │ ├── AnyShape.swift
│ │ ├── ContainerRelativeShape.swift
│ │ ├── Ellipse.swift
│ │ ├── FixedRoundedRect.swift
│ │ ├── ModifiedShapes.swift
│ │ ├── Path
│ │ │ ├── Path.swift
│ │ │ ├── PathLayout.swift
│ │ │ ├── PathMutations.swift
│ │ │ └── PathSizing.swift
│ │ ├── Rectangle.swift
│ │ ├── Shape.swift
│ │ ├── ShapeModifiers.swift
│ │ ├── ShapeStyles
│ │ │ ├── BackgroundStyle.swift
│ │ │ ├── ForegroundStyle.swift
│ │ │ ├── Gradients
│ │ │ │ ├── AngularGradient.swift
│ │ │ │ ├── EllipticalGradient.swift
│ │ │ │ ├── Gradient.swift
│ │ │ │ ├── LinearGradient.swift
│ │ │ │ └── RadialGradient.swift
│ │ │ ├── HierarchicalShapeStyle.swift
│ │ │ ├── Material.swift
│ │ │ └── ShapeStyle.swift
│ │ ├── StrokeStyle.swift
│ │ ├── StrokedPath.swift
│ │ └── TrimmedPath.swift
│ ├── StackReconciler.swift
│ ├── State
│ │ ├── Binding.swift
│ │ ├── ObservedObject.swift
│ │ ├── State.swift
│ │ ├── StateObject.swift
│ │ └── TargetRef.swift
│ ├── Stubs
│ │ ├── CGStubs.swift
│ │ └── UIColor.swift
│ ├── Styles
│ │ ├── ButtonStyle.swift
│ │ ├── ControlGroupStyle.swift
│ │ ├── ListStyle.swift
│ │ ├── NavigationLinkStyle.swift
│ │ ├── OutlineGroupStyle.swift
│ │ ├── PickerStyle.swift
│ │ ├── PrimitiveButtonStyle.swift
│ │ ├── TextFieldStyle.swift
│ │ └── ToggleStyle.swift
│ ├── Target.swift
│ ├── Tokens
│ │ ├── Angle.swift
│ │ ├── AnyTokenBox.swift
│ │ ├── Axis.swift
│ │ ├── Color
│ │ │ ├── Color.swift
│ │ │ ├── ColorBoxes.swift
│ │ │ └── ColorKeys.swift
│ │ ├── ColorScheme.swift
│ │ ├── Controls
│ │ │ ├── ButtonRole.swift
│ │ │ ├── ControlSize.swift
│ │ │ └── Prominence.swift
│ │ ├── Edge.swift
│ │ ├── Font
│ │ │ ├── Font.swift
│ │ │ ├── FontBoxes.swift
│ │ │ └── FontModifiers.swift
│ │ ├── GridItem.swift
│ │ ├── LayoutDirection.swift
│ │ ├── LineBreakMode.swift
│ │ ├── TextAlignment.swift
│ │ └── UnitPoint.swift
│ ├── ViewTraits
│ │ ├── TagValueTraitKey.swift
│ │ ├── Transition
│ │ │ ├── Transition.swift
│ │ │ └── TransitionBoxes.swift
│ │ ├── _ViewTraitKey.swift
│ │ └── _ViewTraitStore.swift
│ └── Views
│ │ ├── AnyView.swift
│ │ ├── Canvas
│ │ ├── Canvas.swift
│ │ ├── GraphicsContext
│ │ │ ├── BlendMode.swift
│ │ │ ├── Filter.swift
│ │ │ ├── GraphicsContext.swift
│ │ │ ├── Resolvables.swift
│ │ │ └── Shading.swift
│ │ └── TimelineView.swift
│ │ ├── Containers
│ │ ├── DisclosureGroup.swift
│ │ ├── ForEach.swift
│ │ ├── Group.swift
│ │ ├── List
│ │ │ ├── List+Init.swift
│ │ │ ├── List+SelectionValue.swift
│ │ │ └── List.swift
│ │ ├── OutlineGroup.swift
│ │ ├── Section.swift
│ │ ├── TupleView.swift
│ │ └── VariadicView.swift
│ │ ├── Controls
│ │ ├── Button.swift
│ │ ├── ControlGroup.swift
│ │ ├── Link.swift
│ │ └── Selectors
│ │ │ ├── DatePicker.swift
│ │ │ ├── Picker.swift
│ │ │ ├── Slider.swift
│ │ │ └── Toggle.swift
│ │ ├── Image.swift
│ │ ├── Layout
│ │ ├── GeometryReader.swift
│ │ ├── HStack.swift
│ │ ├── LazyHGrid.swift
│ │ ├── LazyVGrid.swift
│ │ ├── ScrollView.swift
│ │ ├── VStack.swift
│ │ └── ZStack.swift
│ │ ├── Navigation
│ │ ├── NavigationBarItem.swift
│ │ ├── NavigationLink.swift
│ │ ├── NavigationView.swift
│ │ ├── Toolbar.swift
│ │ ├── ToolbarContentBuilder.swift
│ │ └── ToolbarItem.swift
│ │ ├── Progress
│ │ ├── ProgressView.swift
│ │ └── ProgressViewStyle.swift
│ │ ├── Spacers
│ │ ├── Divider.swift
│ │ └── Spacer.swift
│ │ ├── Text
│ │ ├── SecureField.swift
│ │ ├── Text.swift
│ │ ├── TextEditor.swift
│ │ └── TextField.swift
│ │ ├── View.swift
│ │ └── ViewBuilder.swift
├── TokamakCoreBenchmark
│ └── main.swift
├── TokamakDOM
│ ├── App
│ │ ├── App.swift
│ │ ├── ColorSchemeObserver.swift
│ │ └── ScenePhaseObserver.swift
│ ├── Core.swift
│ ├── DOMFiberRenderer.swift
│ ├── DOMNode.swift
│ ├── DOMRef.swift
│ ├── DOMRenderer.swift
│ ├── Modifiers
│ │ ├── ActionModifier.swift
│ │ ├── Hover.swift
│ │ ├── ModifiedContent.swift
│ │ └── Transitions.swift
│ ├── Storage
│ │ ├── LocalStorage.swift
│ │ ├── SessionStorage.swift
│ │ └── WebStorage.swift
│ ├── Styles
│ │ ├── ColorScheme.swift
│ │ └── ToggleStyle.swift
│ └── Views
│ │ ├── Buttons
│ │ └── Button.swift
│ │ ├── Canvas
│ │ ├── Canvas.swift
│ │ ├── ImageOperations.swift
│ │ ├── PathOperations.swift
│ │ ├── SymbolOperations.swift
│ │ ├── TextOperations.swift
│ │ └── TimelineView.swift
│ │ ├── Containers
│ │ └── DisclosureGroup.swift
│ │ ├── DynamicHTML.swift
│ │ ├── Layout
│ │ └── GeometryReader.swift
│ │ ├── Navigation
│ │ └── NavigationLink.swift
│ │ ├── Selectors
│ │ ├── DatePicker.swift
│ │ ├── Picker.swift
│ │ └── Slider.swift
│ │ └── Text
│ │ ├── SecureField.swift
│ │ ├── TextEditor.swift
│ │ └── TextField.swift
├── TokamakDemo
│ ├── Buttons
│ │ ├── ButtonStyleDemo.swift
│ │ └── Counter.swift
│ ├── Containers
│ │ ├── ForEachDemo.swift
│ │ ├── ListDemo.swift
│ │ ├── OutlineGroupDemo.swift
│ │ └── SidebarDemo.swift
│ ├── DOM
│ │ ├── DOMRefDemo.swift
│ │ └── URLHashDemo.swift
│ ├── Drawing
│ │ ├── CanvasDemo.swift
│ │ ├── ColorDemo.swift
│ │ ├── PathDemo.swift
│ │ └── ShapeStyleDemo.swift
│ ├── Layout
│ │ ├── GeometryReaderDemo.swift
│ │ ├── GridDemo.swift
│ │ ├── SpacerDemo.swift
│ │ └── StackDemo.swift
│ ├── Misc
│ │ ├── AnimationDemo.swift
│ │ ├── AppStorageDemo.swift
│ │ ├── EnvironmentDemo.swift
│ │ ├── PreferenceKeyDemo.swift
│ │ ├── ProgressViewDemo.swift
│ │ ├── RedactDemo.swift
│ │ └── TransitionDemo.swift
│ ├── Modifiers
│ │ ├── ShadowDemo.swift
│ │ └── TaskDemo.swift
│ ├── Selectors
│ │ ├── DatePickerDemo.swift
│ │ ├── PickerDemo.swift
│ │ ├── SliderDemo.swift
│ │ └── ToggleDemo.swift
│ ├── Text
│ │ ├── TextDemo.swift
│ │ ├── TextEditorDemo.swift
│ │ └── TextFieldDemo.swift
│ ├── TokamakDemo.swift
│ ├── logo-header.png
│ └── main.swift
├── TokamakGTK
│ ├── App
│ │ └── App.swift
│ ├── Core.swift
│ ├── GSignal.swift
│ ├── GTKRenderer.swift
│ ├── GtkContainer+forEach.swift
│ ├── Modifiers
│ │ ├── LayoutModifiers.swift
│ │ └── WidgetModifier.swift
│ ├── Scenes
│ │ ├── SceneContainerView.swift
│ │ └── WindowGroup.swift
│ ├── Shapes
│ │ └── Shape.swift
│ ├── Tokens
│ │ └── BuiltinColors.swift
│ ├── Views
│ │ ├── Button.swift
│ │ ├── Image.swift
│ │ ├── List.swift
│ │ ├── NavigationView.swift
│ │ ├── Picker.swift
│ │ ├── ScrollView.swift
│ │ ├── Stack.swift
│ │ ├── Text.swift
│ │ └── TextField.swift
│ └── Widget.swift
├── TokamakGTKCHelpers
│ ├── include
│ │ └── type_check.h
│ └── type_check.c
├── TokamakGTKDemo
│ ├── logo-header.png
│ └── main.swift
├── TokamakShim
│ └── TokamakShim.swift
├── TokamakStaticHTML
│ ├── App.swift
│ ├── Core.swift
│ ├── Modifiers
│ │ ├── Effects
│ │ │ ├── OffsetEffect.swift
│ │ │ ├── OpacityEffect.swift
│ │ │ ├── RotationEffect.swift
│ │ │ └── ScaleEffect.swift
│ │ ├── LayoutModifiers.swift
│ │ ├── ModifiedContent.swift
│ │ ├── ViewModifier.swift
│ │ ├── _BackgroundShapeModifier.swift
│ │ ├── _BackgroundStyleModifier.swift
│ │ └── _DomTextSanitizer.swift
│ ├── Preferences
│ │ └── Preferences.swift
│ ├── Resources
│ │ └── TokamakStyles.swift
│ ├── Sanitizer.swift
│ ├── Scenes
│ │ └── WindowGroup.swift
│ ├── Shapes
│ │ ├── Path.swift
│ │ ├── Shape.swift
│ │ └── _ShapeView.swift
│ ├── StaticHTMLFiberRenderer.swift
│ ├── StaticHTMLRenderer.swift
│ ├── Tokens
│ │ ├── BuiltinColors.swift
│ │ └── Tokens.swift
│ └── Views
│ │ ├── Buttons
│ │ └── Link.swift
│ │ ├── Containers
│ │ └── List.swift
│ │ ├── HTML.swift
│ │ ├── Head
│ │ ├── Meta.swift
│ │ └── Title.swift
│ │ ├── Images
│ │ └── Image.swift
│ │ ├── Layout
│ │ ├── HStack.swift
│ │ ├── LazyHGrid.swift
│ │ ├── LazyVGrid.swift
│ │ ├── ScrollView.swift
│ │ ├── VStack.swift
│ │ └── ZStack.swift
│ │ ├── Navigation
│ │ └── NavigationView.swift
│ │ ├── Progress
│ │ └── ProgressView.swift
│ │ ├── Spacers
│ │ ├── Divider.swift
│ │ └── Spacer.swift
│ │ └── Text
│ │ └── Text.swift
├── TokamakStaticHTMLBenchmark
│ └── main.swift
├── TokamakStaticHTMLDemo
│ ├── ContentView.swift
│ └── main.swift
└── TokamakTestRenderer
│ ├── App.swift
│ ├── TestFiberRenderer.swift
│ ├── TestRenderer.swift
│ ├── TestView.swift
│ ├── TestViewProxy.swift
│ └── WindowGroup.swift
├── Tests
├── TokamakLayoutTests
│ ├── Alignment+allCases.swift
│ ├── AspectRatioTests.swift
│ ├── ContainedZLayoutTests.swift
│ ├── FrameTests.swift
│ ├── StackTests.swift
│ └── compare.swift
├── TokamakReconcilerTests
│ ├── PreferenceTests.swift
│ └── VisitorTests.swift
├── TokamakStaticHTMLTests
│ ├── HTMLStrategy.swift
│ ├── HTMLTests.swift
│ ├── RenderingTests
│ │ ├── LayoutTests.swift
│ │ ├── ShapeTests.swift
│ │ ├── Snapshotting+Image.swift
│ │ ├── ViewTests.swift
│ │ ├── VisualTests.swift
│ │ └── __Snapshots__
│ │ │ ├── LayoutTests
│ │ │ ├── testAnchoredModifiers.1.png
│ │ │ ├── testAspectRatio.1.png
│ │ │ ├── testAspectRatio.2.png
│ │ │ ├── testBackground.1.png
│ │ │ ├── testBackground.2.png
│ │ │ ├── testFrames.1.png
│ │ │ ├── testOverlay.1.png
│ │ │ ├── testOverlay.2.png
│ │ │ ├── testStacks.1.png
│ │ │ └── testStacks.2.png
│ │ │ ├── ShapeTests
│ │ │ ├── testContainerRelativeShape.1.png
│ │ │ ├── testPath.1.png
│ │ │ └── testStrokedCircle.1.png
│ │ │ ├── ViewTests
│ │ │ └── testProgressView.1.png
│ │ │ └── VisualTests
│ │ │ ├── testContentStyles.1.png
│ │ │ ├── testContentStyles.2.png
│ │ │ ├── testForegroundStyle.1.png
│ │ │ ├── testGradients-A.1.png
│ │ │ ├── testGradients-B.1.png
│ │ │ ├── testMaterial.1.png
│ │ │ ├── testOpacity.1.png
│ │ │ └── testScaleEffect.1.png
│ ├── SanitizerTests.swift
│ └── __Snapshots__
│ │ └── HTMLTests
│ │ ├── testDoubleTitle.1.html
│ │ ├── testDoubleTitleModifier.1.html
│ │ ├── testFontStacks.1.html
│ │ ├── testFontStacks.2.html
│ │ ├── testHTMLSanitizer.1.html
│ │ ├── testHTMLSanitizer.2.html
│ │ ├── testMetaAll.1.html
│ │ ├── testMetaCharset.1.html
│ │ ├── testMetaCharsetModifier.1.html
│ │ ├── testOptional.1.html
│ │ ├── testPaddingFusion.1.html
│ │ ├── testPaddingFusion.2.html
│ │ ├── testPreferencePropagation.1.html
│ │ ├── testTitle.1.html
│ │ └── testTitleModifier.1.html
└── TokamakTests
│ ├── ColorTests.swift
│ ├── EnvironmentTests.swift
│ ├── GetSetStructTests.swift
│ ├── MetadataTests.swift
│ ├── ReconcilerStressTests.swift
│ ├── ReconcilerTests.swift
│ ├── ValuePointerTests.swift
│ └── ValueWitnessTableTests.swift
├── benchmark.sh
└── docs
├── FAQ.md
├── RenderersGuide.md
└── progress.md
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*]
2 | end_of_line = lf
3 | insert_final_newline = true
4 | indent_style = space
5 | indent_size = 2
6 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [carson-katri, kateinoigakukun, MaxDesiatov] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: carson-katri
7 |
8 | ---
9 |
10 |
11 |
12 | **Describe the bug**
13 | A clear and concise description of what the bug is.
14 |
15 | **To Reproduce**
16 | Steps to reproduce the behavior:
17 | 1. Go to '...'
18 | 2. Click on '....'
19 | 3. Scroll down to '....'
20 | 4. See error
21 |
22 |
23 |
24 | **Expected behavior**
25 | A clear and concise description of what you expected to happen.
26 |
27 | **Screenshots**
28 | If this is a layout/rendering issue, please provide screenshots for both Tokamak and SwiftUI that highlight the difference.
29 |
30 | **Desktop (please complete the following information):**
31 | - OS: [e.g. macOS 12.4]
32 | - Browser [e.g. chrome, safari]
33 | - Version of the browser [e.g. 22]
34 | - Version of Tokamak [e.g. 0.10.1]
35 |
36 | **Smartphone (please complete the following information):**
37 | - Device: [e.g. iPhone 6]
38 | - OS: [e.g. iOS15.1]
39 | - Browser [e.g. stock browser, safari]
40 | - Version of the browser [e.g. 22]
41 | - Version of Tokamak [e.g. 0.10.1]
42 |
43 | **Additional context**
44 | Add any other context about the problem here.
45 |
--------------------------------------------------------------------------------
/.github/workflows/codecov.yml:
--------------------------------------------------------------------------------
1 | name: Codecov
2 |
3 | on:
4 | pull_request:
5 | push:
6 | branches: [main]
7 |
8 | jobs:
9 | codecov:
10 | container:
11 | image: swiftlang/swift:nightly-5.7-focal
12 | runs-on: ubuntu-latest
13 | steps:
14 | - run: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y gtk+-3.0 libgtk+-3.0
15 | - name: Checkout Branch
16 | uses: actions/checkout@v2
17 | - name: Build Test Target
18 | run: swift build -Xswiftc -profile-coverage-mapping -Xswiftc -profile-generate --product TokamakPackageTests
19 | - name: Run Tests
20 | run: swift test --enable-code-coverage --skip-build
21 | - name: Generate Branch Coverage Report
22 | uses: mattpolzin/swift-codecov-action@0.7.1
23 | id: cov
24 | with:
25 | MINIMUM_COVERAGE: 15
26 | - name: Post Positive Results
27 | if: ${{ success() }}
28 | run: |
29 | echo "::warning file=Package.swift,line=1,col=1::The current code coverage percentage is passing with ${{ steps.cov.outputs.codecov }} (minimum allowed: ${{ steps.cov.outputs.minimum_coverage }}%)."
30 | - name: Post Negative Results
31 | if: ${{ failure() }}
32 | run: |
33 | echo "::error file=Package.swift,line=1,col=1::The current code coverage percentage is failing with ${{ steps.cov.outputs.codecov }} (minimum allowed: ${{ steps.cov.outputs.minimum_coverage }}%)."
34 |
--------------------------------------------------------------------------------
/.github/workflows/label.yml:
--------------------------------------------------------------------------------
1 | name: Check PR labels
2 |
3 | # Controls when the action will run. Triggers the workflow on push or pull request
4 | # events but only for the `main` branch
5 | on:
6 | pull_request:
7 | branches: [ main ]
8 | types: [ opened, synchronize, reopened, labeled, unlabeled ]
9 |
10 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
11 | jobs:
12 | check-labels:
13 | # The type of runner that the job will run on
14 | runs-on: ubuntu-20.04
15 |
16 | steps:
17 | - name: Match PR Label
18 | uses: zwaldowski/match-label-action@v2
19 | with:
20 | allowed_multiple: >
21 | API design,
22 | bug,
23 | continuous integration,
24 | dependencies,
25 | documentation,
26 | enhancement,
27 | Fiber,
28 | refactor,
29 | SwiftUI compatibility,
30 | test suite,
31 | GTK renderer,
32 |
--------------------------------------------------------------------------------
/.github/workflows/swiftlint.yml:
--------------------------------------------------------------------------------
1 | name: SwiftLint
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - ".github/workflows/swiftlint.yml"
7 | - ".swiftlint.yml"
8 | - "**/*.swift"
9 |
10 | jobs:
11 | SwiftLint:
12 | runs-on: ubuntu-20.04
13 | steps:
14 | - uses: actions/checkout@v1
15 | # Fetch current versions of files
16 | - name: Fetch base ref
17 | run: |
18 | git fetch --prune --no-tags --depth=1 origin +refs/heads/${{ github.base_ref }}:refs/heads/${{ github.base_ref }}
19 | # Diff pull request to current files, then SwiftLint changed files
20 | - name: GitHub Action for SwiftLint
21 | uses: mayk-it/action-swiftlint@3.2.2
22 | env:
23 | DIFF_BASE: ${{ github.base_ref }}
24 | DIFF_HEAD: HEAD
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 |
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata/
15 | *.xccheckout
16 | profile
17 | *.moved-aside
18 | DerivedData
19 | *.hmap
20 | *.ipa
21 | .swiftpm/xcode
22 | *.xcodeproj
23 |
24 | # Bundler
25 | .bundle
26 |
27 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
28 | # Carthage/Checkouts
29 |
30 | Carthage/Build
31 |
32 | # We recommend against adding the Pods directory to your .gitignore. However
33 | # you should judge for yourself, the pros and cons are mentioned at:
34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
35 | #
36 | # Note: if you ignore the Pods directory, make sure to uncomment
37 | # `pod install` in .travis.yml
38 | #
39 | Pods/
40 |
41 | # SwiftPM
42 | .build
43 | /Packages
44 |
45 | # VS Code
46 | .vscode/launch.json
47 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | # See https://pre-commit.com for more information
2 | # See https://pre-commit.com/hooks.html for more hooks
3 | exclude: __Snapshots__
4 | repos:
5 | - repo: https://github.com/pre-commit/pre-commit-hooks
6 | rev: v2.5.0
7 | hooks:
8 | - id: trailing-whitespace
9 | - id: end-of-file-fixer
10 | - id: check-yaml
11 | - id: check-added-large-files
12 | - id: detect-private-key
13 | - id: check-merge-conflict
14 | - repo: https://github.com/hodovani/pre-commit-swift
15 | rev: master
16 | hooks:
17 | - id: swift-lint
18 | - id: swift-format
19 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | wasm-5.6.0-RELEASE
2 |
--------------------------------------------------------------------------------
/.swiftformat:
--------------------------------------------------------------------------------
1 | --indent 2
2 | --indentcase false
3 | --trimwhitespace always
4 | --voidtype tuple
5 | --nospaceoperators ..<,...
6 | --ifdef noindent
7 | --stripunusedargs closure-only
8 | --maxwidth 100
9 | --wraparguments before-first
10 | --funcattributes prev-line
11 | --typeattributes prev-line
12 | --varattributes prev-line
13 | --disable andOperator
14 | --swiftversion 5.6
15 |
--------------------------------------------------------------------------------
/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | disabled_rules:
2 | - trailing_comma
3 | - identifier_name
4 | - void_return
5 | - operator_whitespace
6 | - nesting
7 | - cyclomatic_complexity
8 | - multiple_closures_with_trailing_closure
9 | - type_name
10 | - todo
11 | - large_tuple
12 | - opening_brace
13 |
14 | line_length: 100
15 |
16 | function_body_length:
17 | - 50
18 |
19 | included:
20 | - Sources
21 | - Tests
22 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true,
3 | "licenser.author": "Tokamak contributors",
4 | "cSpell.words": [
5 | "Tokamak"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "label": "swift build",
8 | "type": "shell",
9 | "command": "swift build"
10 | },
11 | {
12 | "label": "swift test",
13 | "type": "shell",
14 | "command": "swift build --product TokamakPackageTests && `xcrun --find xctest` .build/debug/TokamakPackageTests.xctest"
15 | },
16 | {
17 | "label": "carton dev",
18 | "type": "shell",
19 | "command": "carton dev --product TokamakDemo"
20 | },
21 | {
22 | "label": "benchmark",
23 | "type": "shell",
24 | "command": "./benchmark.sh"
25 | },
26 | {
27 | "label": "make",
28 | "type": "shell",
29 | "command": "make",
30 | "problemMatcher": [],
31 | "group": {
32 | "kind": "build",
33 | "isDefault": true
34 | }
35 | },
36 | {
37 | "label": "make run",
38 | "type": "shell",
39 | "command": "make run",
40 | "problemMatcher": [],
41 | "group": {
42 | "kind": "build",
43 | "isDefault": true
44 | }
45 | }
46 | ]
47 | }
48 |
--------------------------------------------------------------------------------
/Brewfile:
--------------------------------------------------------------------------------
1 | brew "pre-commit"
2 | brew "swiftformat"
3 | brew "swiftlint"
4 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | LINKER_FLAGS := $(shell pkg-config --libs gtk+-3.0 gdk-3.0)
2 | C_FLAGS := $(shell pkg-config --cflags gtk+-3.0)
3 | SWIFT_LINKER_FLAGS ?= -Xlinker $(shell echo $(LINKER_FLAGS) | sed -e "s/ / -Xlinker /g" | sed -e "s/-Xlinker -Wl,-framework,/-Xlinker -framework -Xlinker /g")
4 | SWIFT_C_FLAGS ?= -Xcc $(shell echo $(C_FLAGS) | sed -e "s/ / -Xcc /g")
5 |
6 | all: build
7 |
8 | build:
9 | swift build --enable-test-discovery --product TokamakGTKDemo $(SWIFT_C_FLAGS) $(SWIFT_LINKER_FLAGS)
10 |
11 | run: build
12 | .build/debug/TokamakGTKDemo
13 |
--------------------------------------------------------------------------------
/NativeDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSMainStoryboardFile
26 | macOS
27 | NSPrincipalClass
28 | NSApplication
29 |
30 |
31 |
--------------------------------------------------------------------------------
/NativeDemo/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/NativeDemo/NSAppDelegate.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2019-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Jed Fox on 07/01/2020.
16 | //
17 |
18 | import Cocoa
19 | import SwiftUI
20 |
21 | @NSApplicationMain
22 | class AppDelegate: NSObject, NSApplicationDelegate {
23 | var window: NSWindow!
24 |
25 | func applicationDidFinishLaunching(_ aNotification: Notification) {
26 | window = NSWindow(
27 | contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
28 | styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
29 | backing: .buffered, defer: false
30 | )
31 | window.isReleasedWhenClosed = false
32 | window.center()
33 | window.contentView = NSHostingView(rootView: TokamakDemoView())
34 | window.makeKeyAndOrderFront(nil)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/NativeDemo/TokamakDemo Native.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.network.client
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/NativeDemo/TokamakDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NativeDemo/TokamakDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/NativeDemo/UIAppDelegate.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2019-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Jed Fox on 07/01/2020.
16 | //
17 |
18 | import SwiftUI
19 | import UIKit
20 |
21 | // so we only need one Info.plist
22 | public class NSApplication: UIApplication {}
23 |
24 | @UIApplicationMain
25 | class AppDelegate: UIResponder, UIApplicationDelegate {
26 | var window: UIWindow?
27 | func application(
28 | _: UIApplication,
29 | didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil
30 | ) -> Bool {
31 | window = UIWindow()
32 | window?.rootViewController = UIHostingController(rootView: TokamakDemoView())
33 | window?.makeKeyAndVisible()
34 | return true
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Sources/CGDK/CGDK-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #include
2 |
--------------------------------------------------------------------------------
/Sources/CGDK/module.modulemap:
--------------------------------------------------------------------------------
1 | module CGDK {
2 | header "./termios-Header.h"
3 | header "./CGDK-Bridging-Header.h"
4 |
5 | link "gdk-3"
6 |
7 | export *
8 | }
9 |
--------------------------------------------------------------------------------
/Sources/CGDK/termios-Header.h:
--------------------------------------------------------------------------------
1 | #include
--------------------------------------------------------------------------------
/Sources/CGTK/CGTK-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #include
--------------------------------------------------------------------------------
/Sources/CGTK/module.modulemap:
--------------------------------------------------------------------------------
1 | module CGTK {
2 | header "./termios-Header.h"
3 | header "./CGTK-Bridging-Header.h"
4 |
5 | link "gtk-3"
6 |
7 | export *
8 | }
--------------------------------------------------------------------------------
/Sources/CGTK/termios-Header.h:
--------------------------------------------------------------------------------
1 | #include
--------------------------------------------------------------------------------
/Sources/TokamakCore/Animation/AnimatableModifier.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/11/21.
16 | //
17 |
18 | public protocol AnimatableModifier: Animatable, ViewModifier {}
19 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Animation/VectorArithmetic.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/11/21.
16 | //
17 |
18 | import Foundation
19 |
20 | public protocol VectorArithmetic: AdditiveArithmetic {
21 | mutating func scale(by rhs: Double)
22 | var magnitudeSquared: Double { get }
23 | }
24 |
25 | extension Float: VectorArithmetic {
26 | @_transparent
27 | public mutating func scale(by rhs: Double) { self *= Float(rhs) }
28 |
29 | @_transparent
30 | public var magnitudeSquared: Double {
31 | @_transparent get { Double(self * self) }
32 | }
33 | }
34 |
35 | extension Double: VectorArithmetic {
36 | @_transparent
37 | public mutating func scale(by rhs: Double) { self *= rhs }
38 |
39 | @_transparent
40 | public var magnitudeSquared: Double {
41 | @_transparent get { self * self }
42 | }
43 | }
44 |
45 | extension CGFloat: VectorArithmetic {
46 | @_transparent
47 | public mutating func scale(by rhs: Double) { self *= CGFloat(rhs) }
48 |
49 | @_transparent
50 | public var magnitudeSquared: Double {
51 | @_transparent get { Double(self * self) }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/App/Scenes/ScenePhase.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/19/20.
16 | //
17 |
18 | public enum ScenePhase: Comparable {
19 | case active
20 | case inactive
21 | case background
22 | }
23 |
24 | struct ScenePhaseKey: EnvironmentKey {
25 | static let defaultValue: ScenePhase = .active
26 | }
27 |
28 | public extension EnvironmentValues {
29 | var scenePhase: ScenePhase {
30 | get {
31 | self[ScenePhaseKey.self]
32 | }
33 | set {
34 | self[ScenePhaseKey.self] = newValue
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/App/Scenes/_SceneModifier.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/20/20.
16 | //
17 |
18 | public protocol _SceneModifier {
19 | associatedtype Body: Scene
20 | typealias SceneContent = _SceneModifier_Content
21 | func body(content: SceneContent) -> Self.Body
22 | }
23 |
24 | public struct _SceneModifier_Content: Scene where Modifier: _SceneModifier {
25 | public let modifier: Modifier
26 | public let scene: _AnyScene
27 |
28 | @_spi(TokamakCore)
29 | public var body: Never {
30 | neverScene("_SceneModifier_Content")
31 | }
32 | }
33 |
34 | public extension Scene {
35 | func modifier(_ modifier: Modifier) -> ModifiedContent {
36 | .init(content: self, modifier: modifier)
37 | }
38 | }
39 |
40 | public extension _SceneModifier where Body == Never {
41 | func body(content: SceneContent) -> Body {
42 | fatalError("""
43 | \(self) is a primitive `_SceneModifier`, you're not supposed to run `body(content:)`
44 | """)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/App/_StorageProvider.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020-2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/22/20.
16 | //
17 |
18 | import OpenCombineShim
19 |
20 | public protocol _StorageProvider {
21 | func store(key: String, value: Bool?)
22 | func store(key: String, value: Int?)
23 | func store(key: String, value: Double?)
24 | func store(key: String, value: String?)
25 |
26 | func read(key: String) -> Bool?
27 | func read(key: String) -> Int?
28 | func read(key: String) -> Double?
29 | func read(key: String) -> String?
30 |
31 | static var standard: _StorageProvider { get }
32 | var publisher: ObservableObjectPublisher { get }
33 | }
34 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/App/_TupleScene.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/16/20.
16 | //
17 |
18 | struct _TupleScene: Scene, GroupScene {
19 | let value: T
20 | let children: [_AnyScene]
21 | let visit: (SceneVisitor) -> ()
22 |
23 | init(
24 | _ value: T,
25 | children: [_AnyScene],
26 | visit: @escaping (SceneVisitor) -> ()
27 | ) {
28 | self.value = value
29 | self.children = children
30 | self.visit = visit
31 | }
32 |
33 | var body: Never {
34 | neverScene("_TupleScene")
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/DynamicProperty.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020-2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/17/20.
16 | //
17 |
18 | public protocol DynamicProperty {
19 | mutating func update()
20 | }
21 |
22 | public extension DynamicProperty {
23 | mutating func update() {}
24 | }
25 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Environment/EnvironmentalModifier.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/11/21.
16 | //
17 |
18 | /// A modifier that resolves to a concrete modifier in an environment.
19 | public protocol EnvironmentalModifier: ViewModifier {
20 | associatedtype ResolvedModifier: ViewModifier
21 | func resolve(in environment: EnvironmentValues) -> ResolvedModifier
22 | static var _requiresMainThread: Bool { get }
23 | }
24 |
25 | private struct EnvironmentalModifierResolver: ViewModifier, EnvironmentReader
26 | where M: EnvironmentalModifier
27 | {
28 | let modifier: M
29 | var resolved: M.ResolvedModifier!
30 |
31 | func body(content: Content) -> some View {
32 | content.modifier(resolved)
33 | }
34 |
35 | mutating func setContent(from values: EnvironmentValues) {
36 | resolved = modifier.resolve(in: values)
37 | }
38 | }
39 |
40 | public extension EnvironmentalModifier {
41 | static var _requiresMainThread: Bool { true }
42 |
43 | func body(content: _ViewModifier_Content) -> some View {
44 | content.modifier(EnvironmentalModifierResolver(modifier: self))
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Fiber/App/AppVisitor.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 5/31/22.
16 | //
17 |
18 | /// A type that can visit an `App`.
19 | public protocol AppVisitor: ViewVisitor {
20 | func visit(_ app: A)
21 | }
22 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Fiber/FiberElement.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 2/15/22.
16 | //
17 |
18 | /// A reference type that points to a `Renderer`-specific element that has been mounted.
19 | /// For instance, a DOM node in the `DOMFiberRenderer`.
20 | public protocol FiberElement: AnyObject {
21 | associatedtype Content: FiberElementContent
22 | var content: Content { get }
23 | init(from content: Content)
24 | func update(with content: Content)
25 | }
26 |
27 | /// The data used to create an `FiberElement`.
28 | ///
29 | /// We re-use `FiberElement` instances in the `Fiber` tree,
30 | /// but can re-create and copy `FiberElementContent` as often as needed.
31 | public protocol FiberElementContent: Equatable {
32 | init(from primitiveView: V, useDynamicLayout: Bool)
33 | }
34 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Fiber/Layout/LayoutPriority.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 6/22/22.
16 | //
17 |
18 | import Foundation
19 |
20 | @usableFromInline
21 | enum LayoutPriorityTraitKey: _ViewTraitKey {
22 | @inlinable
23 | static var defaultValue: Double { 0 }
24 | }
25 |
26 | public extension View {
27 | @inlinable
28 | func layoutPriority(_ value: Double) -> some View {
29 | _trait(LayoutPriorityTraitKey.self, value)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Fiber/Layout/LayoutProperties.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 6/20/22.
16 | //
17 |
18 | /// Metadata about a `Layout`.
19 | public struct LayoutProperties {
20 | public var stackOrientation: Axis?
21 |
22 | public init() {
23 | stackOrientation = nil
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Fiber/Layout/LayoutValueKey.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 6/20/22.
16 | //
17 |
18 | /// A key that stores a value that can be accessed via a `LayoutSubview`.
19 | public protocol LayoutValueKey {
20 | associatedtype Value
21 | static var defaultValue: Self.Value { get }
22 | }
23 |
24 | public extension View {
25 | @inlinable
26 | func layoutValue(key: K.Type, value: K.Value) -> some View where K: LayoutValueKey {
27 | // LayoutValueKey uses trait keys under the hood.
28 | _trait(_LayoutTrait.self, value)
29 | }
30 | }
31 |
32 | public struct _LayoutTrait: _ViewTraitKey where K: LayoutValueKey {
33 | public static var defaultValue: K.Value {
34 | K.defaultValue
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Fiber/Layout/ProposedViewSize.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 6/20/22.
16 | //
17 |
18 | import Foundation
19 |
20 | @frozen
21 | public struct ProposedViewSize: Equatable {
22 | public var width: CGFloat?
23 | public var height: CGFloat?
24 | public static let zero: ProposedViewSize = .init(width: 0, height: 0)
25 | public static let unspecified: ProposedViewSize = .init(width: nil, height: nil)
26 | public static let infinity: ProposedViewSize = .init(width: .infinity, height: .infinity)
27 | @inlinable
28 | public init(width: CGFloat?, height: CGFloat?) {
29 | (self.width, self.height) = (width, height)
30 | }
31 |
32 | @inlinable
33 | public init(_ size: CGSize) {
34 | self.init(width: size.width, height: size.height)
35 | }
36 |
37 | @inlinable
38 | public func replacingUnspecifiedDimensions(by size: CGSize = CGSize(
39 | width: 10,
40 | height: 10
41 | )) -> CGSize {
42 | CGSize(width: width ?? size.width, height: height ?? size.height)
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Fiber/Mutation.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 2/15/22.
16 | //
17 |
18 | import Foundation
19 |
20 | public enum Mutation {
21 | case insert(
22 | element: Renderer.ElementType,
23 | parent: Renderer.ElementType,
24 | index: Int
25 | )
26 | case remove(element: Renderer.ElementType, parent: Renderer.ElementType?)
27 | case replace(
28 | parent: Renderer.ElementType,
29 | previous: Renderer.ElementType,
30 | replacement: Renderer.ElementType
31 | )
32 | case update(
33 | previous: Renderer.ElementType,
34 | newContent: Renderer.ElementType.Content,
35 | geometry: ViewGeometry
36 | )
37 | case layout(element: Renderer.ElementType, geometry: ViewGeometry)
38 | }
39 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Fiber/Scene/SceneArguments.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 5/30/22.
16 | //
17 |
18 | import Foundation
19 |
20 | public extension Scene {
21 | // By default, we simply pass the inputs through without modifications.
22 | static func _makeScene(_ inputs: SceneInputs) -> SceneOutputs {
23 | .init(inputs: inputs)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Modifiers/AppearanceActionModifier.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | protocol AppearanceActionType {
16 | var appear: (() -> ())? { get }
17 | var disappear: (() -> ())? { get }
18 | }
19 |
20 | /// Underscore is present in the name for SwiftUI compatibility.
21 | struct _AppearanceActionModifier: ViewModifier {
22 | var appear: (() -> ())?
23 | var disappear: (() -> ())?
24 |
25 | typealias Body = Never
26 | }
27 |
28 | extension ModifiedContent: AppearanceActionType
29 | where Content: View, Modifier == _AppearanceActionModifier
30 | {
31 | var appear: (() -> ())? { modifier.appear }
32 | var disappear: (() -> ())? { modifier.disappear }
33 | }
34 |
35 | public extension View {
36 | func onAppear(perform action: (() -> ())? = nil) -> some View {
37 | modifier(_AppearanceActionModifier(appear: action))
38 | }
39 |
40 | func onDisappear(perform action: (() -> ())? = nil) -> some View {
41 | modifier(_AppearanceActionModifier(disappear: action))
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Modifiers/Effects/OffsetEffect.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020-2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/12/21.
16 | //
17 |
18 | import Foundation
19 |
20 | @frozen
21 | public struct _OffsetEffect: GeometryEffect, Equatable {
22 | public var offset: CGSize
23 |
24 | @inlinable
25 | public init(offset: CGSize) {
26 | self.offset = offset
27 | }
28 |
29 | public func effectValue(size: CGSize) -> ProjectionTransform {
30 | .init(.init(translationX: offset.width, y: offset.height))
31 | }
32 |
33 | public var animatableData: CGSize.AnimatableData {
34 | get {
35 | offset.animatableData
36 | }
37 | set {
38 | offset.animatableData = newValue
39 | }
40 | }
41 |
42 | public func body(content: Content) -> some View {
43 | content
44 | }
45 | }
46 |
47 | public extension View {
48 | @inlinable
49 | func offset(_ offset: CGSize) -> some View {
50 | modifier(_OffsetEffect(offset: offset))
51 | }
52 |
53 | @inlinable
54 | func offset(x: CGFloat = 0, y: CGFloat = 0) -> some View {
55 | offset(CGSize(width: x, height: y))
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Modifiers/Effects/OpacityEffect.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 1/20/21.
16 | //
17 |
18 | public struct _OpacityEffect: Animatable, ViewModifier, Equatable {
19 | public var opacity: Double
20 |
21 | public init(opacity: Double) {
22 | self.opacity = opacity
23 | }
24 |
25 | public func body(content: Content) -> some View {
26 | content
27 | }
28 |
29 | public var animatableData: Double {
30 | get { opacity }
31 | set { opacity = newValue }
32 | }
33 | }
34 |
35 | public extension View {
36 | func opacity(_ opacity: Double) -> some View {
37 | modifier(_OpacityEffect(opacity: opacity))
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Modifiers/Effects/RotationEffect.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020-2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/3/20.
16 | //
17 |
18 | import Foundation
19 |
20 | public struct _RotationEffect: GeometryEffect {
21 | public var angle: Angle
22 | public var anchor: UnitPoint
23 |
24 | public init(angle: Angle, anchor: UnitPoint = .center) {
25 | self.angle = angle
26 | self.anchor = anchor
27 | }
28 |
29 | public func effectValue(size: CGSize) -> ProjectionTransform {
30 | .init(CGAffineTransform.identity.rotated(by: CGFloat(angle.radians)))
31 | }
32 |
33 | public func body(content: Content) -> some View {
34 | content
35 | }
36 |
37 | public var animatableData: AnimatablePair {
38 | get {
39 | .init(angle.animatableData, anchor.animatableData)
40 | }
41 | set {
42 | (angle.animatableData, anchor.animatableData) = newValue[]
43 | }
44 | }
45 | }
46 |
47 | public extension View {
48 | func rotationEffect(_ angle: Angle, anchor: UnitPoint = .center) -> some View {
49 | modifier(_RotationEffect(angle: angle, anchor: anchor))
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Modifiers/FrameLayout.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020-2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import Foundation
16 |
17 | public struct _FrameLayout: ViewModifier {
18 | public let width: CGFloat?
19 | public let height: CGFloat?
20 | public let alignment: Alignment
21 |
22 | init(width: CGFloat?, height: CGFloat?, alignment: Alignment) {
23 | self.width = width
24 | self.height = height
25 | self.alignment = alignment
26 | }
27 |
28 | public func body(content: Content) -> some View {
29 | content
30 | }
31 | }
32 |
33 | extension _FrameLayout: Animatable {
34 | public typealias AnimatableData = EmptyAnimatableData
35 | }
36 |
37 | public extension View {
38 | func frame(
39 | width: CGFloat? = nil,
40 | height: CGFloat? = nil,
41 | alignment: Alignment = .center
42 | ) -> some View {
43 | modifier(_FrameLayout(width: width, height: height, alignment: alignment))
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Modifiers/HoverActionModifier.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | /// Underscore is present in the name for SwiftUI compatibility.
15 | public struct _HoverActionModifier: ViewModifier {
16 | public var hover: ((Bool) -> ())?
17 |
18 | public typealias Body = Never
19 | }
20 |
21 | extension ModifiedContent
22 | where Content: View, Modifier == _HoverActionModifier
23 | {
24 | var hover: ((Bool) -> ())? { modifier.hover }
25 | }
26 |
27 | public extension View {
28 | func onHover(perform action: ((Bool) -> ())?) -> some View {
29 | modifier(_HoverActionModifier(hover: action))
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Modifiers/LifecycleModifier.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // FIXME: these should have standalone implementations
16 | public extension View {
17 | @_spi(TokamakCore)
18 | func _onMount(perform action: (() -> ())? = nil) -> some View {
19 | modifier(_AppearanceActionModifier(appear: action))
20 | }
21 |
22 | @_spi(TokamakCore)
23 | func _onUpdate(perform action: (() -> ())? = nil) -> some View {
24 | modifier(_LifecycleActionModifier(update: action))
25 | }
26 |
27 | @_spi(TokamakCore)
28 | func _onUnmount(perform action: (() -> ())? = nil) -> some View {
29 | modifier(_AppearanceActionModifier(disappear: action))
30 | }
31 | }
32 |
33 | protocol LifecycleActionType {
34 | var update: (() -> ())? { get }
35 | }
36 |
37 | struct _LifecycleActionModifier: ViewModifier {
38 | var update: (() -> ())?
39 |
40 | typealias Body = Never
41 | }
42 |
43 | extension ModifiedContent: LifecycleActionType
44 | where Content: View, Modifier == _LifecycleActionModifier
45 | {
46 | var update: (() -> ())? { modifier.update }
47 | }
48 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Modifiers/RedactionReasons.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/31/20.
16 | //
17 |
18 | public struct RedactionReasons: OptionSet {
19 | public let rawValue: Int
20 | public init(rawValue: Int) {
21 | self.rawValue = rawValue
22 | }
23 |
24 | public static let placeholder: Self = .init(rawValue: 1 << 0)
25 | }
26 |
27 | public extension View {
28 | func redacted(reason: RedactionReasons) -> some View {
29 | environment(\.redactionReasons, reason)
30 | }
31 |
32 | func unredacted() -> some View {
33 | environment(\.redactionReasons, [])
34 | }
35 | }
36 |
37 | private struct RedactionReasonsKey: EnvironmentKey {
38 | static let defaultValue: RedactionReasons = []
39 | }
40 |
41 | public extension EnvironmentValues {
42 | var redactionReasons: RedactionReasons {
43 | get {
44 | self[RedactionReasonsKey.self]
45 | }
46 | set {
47 | self[RedactionReasonsKey.self] = newValue
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Modifiers/TaskModifier.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | public extension View {
16 | func task(
17 | priority: TaskPriority = .userInitiated,
18 | _ action: @escaping @Sendable () async -> ()
19 | ) -> some View {
20 | var task: Task<(), Never>?
21 | return onAppear {
22 | task = Task(priority: priority, operation: action)
23 | }
24 | .onDisappear {
25 | task?.cancel()
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Modifiers/ZIndexModifier.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | public struct _ZIndexModifier: ViewModifier {
16 | public let index: Double
17 |
18 | public func body(content: Content) -> some View {
19 | content
20 | }
21 | }
22 |
23 | public extension View {
24 | /// Controls the display order of overlapping views.
25 | /// - Parameters:
26 | /// - value: A relative front-to-back ordering for this view; the default is 0.
27 | func zIndex(_ value: Double = 0) -> some View {
28 | modifier(_ZIndexModifier(index: value))
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/MountedViews/MountedEmptyView.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2019-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Max Desiatov on 05/01/2019.
16 | //
17 |
18 | final class MountedEmptyView: MountedElement {
19 | override func mount(
20 | before sibling: R.TargetType? = nil,
21 | on parent: MountedElement? = nil,
22 | in reconciler: StackReconciler,
23 | with transaction: Transaction
24 | ) {
25 | super.prepareForMount(with: transaction)
26 | super.mount(before: sibling, on: parent, in: reconciler, with: transaction)
27 | }
28 |
29 | override func unmount(
30 | in reconciler: StackReconciler,
31 | with transaction: Transaction,
32 | parentTask: UnmountTask?
33 | ) {
34 | super.unmount(in: reconciler, with: transaction, parentTask: parentTask)
35 | }
36 |
37 | override func update(in reconciler: StackReconciler, with transaction: Transaction?) {}
38 | }
39 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Reflection/Layouts/ExistentialContainter.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2017-2021 Wesley Wickwire and Tokamak contributors
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | struct ExistentialContainer {
24 | let buffer: ExistentialContainerBuffer
25 | let type: Any.Type
26 | let witnessTable: Int
27 | }
28 |
29 | struct ExistentialContainerBuffer {
30 | let buffer1: Int
31 | let buffer2: Int
32 | let buffer3: Int
33 | }
34 |
35 | extension ExistentialContainerBuffer {
36 | static func size() -> Int {
37 | MemoryLayout.size
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Reflection/Layouts/ProtocolTypeContainer.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2017-2021 Wesley Wickwire and Tokamak contributors
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | struct ProtocolTypeContainer {
24 | let type: Any.Type
25 | let witnessTable: Int
26 | }
27 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Reflection/Layouts/StructMetadataLayout.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2017-2021 Wesley Wickwire and Tokamak contributors
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | struct StructMetadataLayout {
24 | let _kind: Int
25 | let typeDescriptor: UnsafePointer
26 | }
27 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Reflection/Layouts/TargetTypeGenericContextDescriptorHeader.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2017-2021 Wesley Wickwire and Tokamak contributors
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | struct TargetTypeGenericContextDescriptorHeader {
24 | let instantiationCache: Int32
25 | let defaultInstantiationPattern: Int32
26 | let base: TargetGenericContextDescriptorHeader
27 | }
28 |
29 | struct TargetGenericContextDescriptorHeader {
30 | let numberOfParams: UInt16
31 | let numberOfRequirements: UInt16
32 | let numberOfKeyArguments: UInt16
33 | let numberOfExtraArguments: UInt16
34 | }
35 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Reflection/Metadata/Metadata.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2017-2021 Wesley Wickwire and Tokamak contributors
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | func metadataPointer(type: Any.Type) -> UnsafePointer {
24 | unsafeBitCast(type, to: UnsafePointer.self)
25 | }
26 |
27 | func metadata(of type: Any.Type) -> StructMetadata {
28 | guard Kind(type: type) == .struct else { fatalError("Reflection is supported only for structs") }
29 |
30 | return StructMetadata(type: type)
31 | }
32 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Reflection/Metadata/MetadataState.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | enum MetadataState: UInt {
16 | case complete = 0x00
17 | case nonTransitiveComplete = 0x01
18 | case layoutComplete = 0x3F
19 | case abstract = 0xFF
20 | }
21 |
22 | private let isBlockingMask: UInt = 0x100
23 |
24 | struct MetadataRequest {
25 | private let bits: UInt
26 |
27 | init(desiredState: MetadataState, isBlocking: Bool) {
28 | if isBlocking {
29 | bits = desiredState.rawValue | isBlockingMask
30 | } else {
31 | bits = desiredState.rawValue & ~isBlockingMask
32 | }
33 | }
34 | }
35 |
36 | struct MetadataResponse {
37 | let metadata: UnsafePointer
38 | let state: MetadataState
39 | }
40 |
41 | @_silgen_name("swift_checkMetadataState")
42 | func _checkMetadataState(_ request: MetadataRequest, _ type: StructMetadata) -> MetadataResponse
43 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Reflection/Pointers/RelativeVectorPointer.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2017-2021 Wesley Wickwire and Tokamak contributors
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | struct RelativeVectorPointer {
24 | let offset: Offset
25 | func vector(metadata: UnsafePointer, n: Int) -> UnsafeBufferPointer {
26 | metadata.advanced(by: numericCast(offset))
27 | .raw.assumingMemoryBound(to: Pointee.self)
28 | .buffer(n: n)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Reflection/typeConstructorName.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | /** Returns name of a given unapplied generic type. `Button` and
16 | `Button` types are different, but when reconciling the tree of mounted views
17 | they are treated the same, thus the `Button` part of the type (the type constructor)
18 | is returned.
19 | */
20 | public func typeConstructorName(_ type: Any.Type) -> String {
21 | String(String(reflecting: type).prefix { $0 != "<" })
22 | }
23 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Shapes/FixedRoundedRect.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020-2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/22/20.
16 | //
17 |
18 | import Foundation
19 |
20 | public struct FixedRoundedRect: Equatable {
21 | public let rect: CGRect
22 | public let cornerSize: CGSize?
23 | public let style: RoundedCornerStyle
24 |
25 | public init(rect: CGRect, cornerSize: CGSize, style: RoundedCornerStyle) {
26 | (self.rect, self.cornerSize, self.style) = (rect, cornerSize, style)
27 | }
28 |
29 | init(capsule rect: CGRect, style: RoundedCornerStyle) {
30 | (self.rect, cornerSize, self.style) = (rect, nil, style)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Shapes/Path/PathSizing.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/21/20.
16 | //
17 |
18 | public extension Path {
19 | enum _Sizing {
20 | case fixed
21 | case flexible
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Shapes/StrokedPath.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/22/20.
16 | //
17 |
18 | public struct StrokedPath: Equatable {
19 | public let path: Path
20 | public let style: StrokeStyle
21 |
22 | public init(path: Path, style: StrokeStyle) {
23 | self.path = path
24 | self.style = style
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Shapes/TrimmedPath.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020-2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/22/20.
16 | //
17 |
18 | import Foundation
19 |
20 | public struct TrimmedPath: Equatable {
21 | public let path: Path
22 | public let from: CGFloat
23 | public let to: CGFloat
24 |
25 | public init(path: Path, from: CGFloat, to: CGFloat) {
26 | self.path = path
27 | self.from = from
28 | self.to = to
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/State/StateObject.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020-2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import OpenCombineShim
16 |
17 | @propertyWrapper
18 | public struct StateObject: DynamicProperty {
19 | public var wrappedValue: ObjectType { (getter?() as? ObservedObject.Wrapper)?.root ?? initial() }
20 |
21 | let initial: () -> ObjectType
22 | var getter: (() -> Any)?
23 |
24 | public init(wrappedValue initial: @autoclosure @escaping () -> ObjectType) {
25 | self.initial = initial
26 | }
27 |
28 | public var projectedValue: ObservedObject.Wrapper {
29 | getter?() as? ObservedObject.Wrapper ?? ObservedObject.Wrapper(root: initial())
30 | }
31 | }
32 |
33 | extension StateObject: ObservedProperty {
34 | var objectWillChange: AnyPublisher<(), Never> {
35 | wrappedValue.objectWillChange.map { _ in }.eraseToAnyPublisher()
36 | }
37 | }
38 |
39 | extension StateObject: ValueStorage {
40 | var anyInitialValue: Any {
41 | ObservedObject.Wrapper(root: initial())
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/State/TargetRef.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | /// A helper protocol for erasing generic parameters of the `_TargetRef` type.
16 | protocol TargetRefType {
17 | var target: Target? { get set }
18 | }
19 |
20 | /** Allows capturing target instance of aclosest descendant host view. The resulting instance
21 | is written to a given `binding`. The actual assignment to this binding is done within the
22 | `MountedCompositeView` implementation. */
23 | public struct _TargetRef: View, TargetRefType {
24 | let binding: Binding
25 |
26 | let view: V
27 |
28 | var target: Target? {
29 | get { binding.wrappedValue as? Target }
30 |
31 | set { binding.wrappedValue = newValue as? T }
32 | }
33 |
34 | public var body: V { view }
35 | }
36 |
37 | public extension View {
38 | /** A modifier that returns a `_TargetRef` value, which captures a target instance of a
39 | closest descendant host view.
40 | The resulting instance is written to a given `binding`. */
41 | @_spi(TokamakCore)
42 | func _targetRef(_ binding: Binding) -> _TargetRef {
43 | .init(binding: binding, view: self)
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Stubs/UIColor.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | public struct UIColor {
16 | let color: Color
17 |
18 | public static let clear: Self = .init(color: .clear)
19 | public static let black: Self = .init(color: .black)
20 | public static let white: Self = .init(color: .white)
21 | public static let gray: Self = .init(color: .gray)
22 | public static let red: Self = .init(color: .red)
23 | public static let green: Self = .init(color: .green)
24 | public static let blue: Self = .init(color: .blue)
25 | public static let orange: Self = .init(color: .orange)
26 | public static let yellow: Self = .init(color: .yellow)
27 | public static let pink: Self = .init(color: .pink)
28 | public static let purple: Self = .init(color: .purple)
29 | }
30 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Styles/ButtonStyle.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Gene Z. Ragan on 07/22/2020.
16 |
17 | public protocol ButtonStyle {
18 | associatedtype Body: View
19 | @ViewBuilder
20 | func makeBody(configuration: Self.Configuration) -> Self.Body
21 | typealias Configuration = ButtonStyleConfiguration
22 | }
23 |
24 | public struct ButtonStyleConfiguration {
25 | public struct Label: View {
26 | public let body: AnyView
27 | }
28 |
29 | public let role: ButtonRole?
30 | public let label: ButtonStyleConfiguration.Label
31 | public let isPressed: Bool
32 | }
33 |
34 | struct AnyButtonStyle: ButtonStyle {
35 | let bodyClosure: (ButtonStyleConfiguration) -> AnyView
36 | let type: Any.Type
37 |
38 | init(_ style: S) {
39 | type = S.self
40 | bodyClosure = {
41 | AnyView(style.makeBody(configuration: $0))
42 | }
43 | }
44 |
45 | func makeBody(configuration: Configuration) -> some View {
46 | bodyClosure(configuration)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Styles/OutlineGroupStyle.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/4/20.
16 | //
17 |
18 | public protocol _OutlineGroupStyle {}
19 |
20 | public struct _DefaultOutlineGroupStyle: _OutlineGroupStyle {
21 | public init() {}
22 | }
23 |
24 | public struct _ListOutlineGroupStyle: _OutlineGroupStyle {
25 | public init() {}
26 | }
27 |
28 | enum _OutlineGroupStyleKey: EnvironmentKey {
29 | static let defaultValue: _OutlineGroupStyle = _DefaultOutlineGroupStyle()
30 | }
31 |
32 | extension EnvironmentValues {
33 | var _outlineGroupStyle: _OutlineGroupStyle {
34 | get {
35 | self[_OutlineGroupStyleKey.self]
36 | }
37 | set {
38 | self[_OutlineGroupStyleKey.self] = newValue
39 | }
40 | }
41 | }
42 |
43 | extension View {
44 | func outlineGroupStyle(_ style: _OutlineGroupStyle) -> some View {
45 | environment(\._outlineGroupStyle, style)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Styles/PickerStyle.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | public protocol PickerStyle {}
16 |
17 | public struct PopUpButtonPickerStyle: PickerStyle {}
18 |
19 | public struct RadioGroupPickerStyle: PickerStyle {}
20 |
21 | public struct SegmentedPickerStyle: PickerStyle {}
22 |
23 | public struct WheelPickerStyle: PickerStyle {}
24 |
25 | public struct DefaultPickerStyle: PickerStyle {}
26 |
27 | enum PickerStyleKey: EnvironmentKey {
28 | static var defaultValue: PickerStyle = DefaultPickerStyle()
29 | }
30 |
31 | extension EnvironmentValues {
32 | var pickerStyle: PickerStyle {
33 | get {
34 | self[PickerStyleKey.self]
35 | }
36 | set {
37 | self[PickerStyleKey.self] = newValue
38 | }
39 | }
40 | }
41 |
42 | public extension View {
43 | func pickerStyle(_ style: PickerStyle) -> some View {
44 | environment(\.pickerStyle, style)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Target.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2019-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Max Desiatov on 10/02/2019.
16 | //
17 |
18 | public protocol Target: AnyObject {
19 | var view: AnyView { get set }
20 | }
21 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Tokens/AnyTokenBox.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 10/24/2020.
16 | //
17 |
18 | /// Allows "late-binding tokens" to be resolved in an environment by a `Renderer` (or `TokamakCore`)
19 | public protocol AnyTokenBox: AnyObject {
20 | associatedtype ResolvedValue
21 | func resolve(in environment: EnvironmentValues) -> ResolvedValue
22 | }
23 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Tokens/Axis.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 06/29/2020.
16 | //
17 |
18 | public enum Axis: Int8, CaseIterable {
19 | case horizontal
20 | case vertical
21 |
22 | public struct Set: OptionSet {
23 | public let rawValue: Int8
24 | public init(rawValue: Int8) {
25 | self.rawValue = rawValue
26 | }
27 |
28 | public static let horizontal: Axis.Set = .init(rawValue: 1 << 0)
29 | public static let vertical: Axis.Set = .init(rawValue: 1 << 1)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Tokens/Color/ColorKeys.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/12/21.
16 | //
17 |
18 | import Foundation
19 |
20 | struct AccentColorKey: EnvironmentKey {
21 | static let defaultValue: Color? = nil
22 | }
23 |
24 | public extension EnvironmentValues {
25 | var accentColor: Color? {
26 | get {
27 | self[AccentColorKey.self]
28 | }
29 | set {
30 | self[AccentColorKey.self] = newValue
31 | }
32 | }
33 | }
34 |
35 | public extension View {
36 | func accentColor(_ accentColor: Color?) -> some View {
37 | environment(\.accentColor, accentColor)
38 | }
39 | }
40 |
41 | struct ForegroundColorKey: EnvironmentKey {
42 | static let defaultValue: Color? = nil
43 | }
44 |
45 | public extension EnvironmentValues {
46 | var foregroundColor: Color? {
47 | get {
48 | self[ForegroundColorKey.self]
49 | }
50 | set {
51 | self[ForegroundColorKey.self] = newValue
52 | }
53 | }
54 | }
55 |
56 | public extension View {
57 | func foregroundColor(_ color: Color?) -> some View {
58 | environment(\.foregroundColor, color)
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Tokens/ColorScheme.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | public enum ColorScheme: CaseIterable, Equatable {
16 | case dark
17 | case light
18 | }
19 |
20 | public struct _ColorSchemeKey: EnvironmentKey {
21 | public static var defaultValue: ColorScheme {
22 | fatalError("\(self) must have a renderer-provided default value")
23 | }
24 | }
25 |
26 | public extension EnvironmentValues {
27 | var colorScheme: ColorScheme {
28 | get { self[_ColorSchemeKey.self] }
29 | set { self[_ColorSchemeKey.self] = newValue }
30 | }
31 | }
32 |
33 | public extension View {
34 | func colorScheme(_ colorScheme: ColorScheme) -> some View {
35 | environment(\.colorScheme, colorScheme)
36 | }
37 | }
38 |
39 | public struct PreferredColorSchemeKey: PreferenceKey {
40 | public typealias Value = ColorScheme?
41 | public static func reduce(value: inout Value, nextValue: () -> Value) {
42 | value = nextValue()
43 | }
44 | }
45 |
46 | public extension View {
47 | func preferredColorScheme(_ colorScheme: ColorScheme?) -> some View {
48 | preference(key: PreferredColorSchemeKey.self, value: colorScheme)
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Tokens/Controls/ButtonRole.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/12/21.
16 | //
17 |
18 | public struct ButtonRole: Equatable {
19 | public static let destructive = ButtonRole(rawValue: 0)
20 | public static let cancel = ButtonRole(rawValue: 1)
21 |
22 | private let rawValue: Int
23 | private init(rawValue: Int) {
24 | self.rawValue = rawValue
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Tokens/Controls/ControlSize.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/12/21.
16 | //
17 |
18 | public enum ControlSize: CaseIterable, Hashable {
19 | case mini
20 | case small
21 | case regular
22 | case large
23 | }
24 |
25 | extension EnvironmentValues {
26 | private enum ControlSizeKey: EnvironmentKey {
27 | static var defaultValue: ControlSize = .regular
28 | }
29 |
30 | public var controlSize: ControlSize {
31 | get {
32 | self[ControlSizeKey.self]
33 | }
34 | set {
35 | self[ControlSizeKey.self] = newValue
36 | }
37 | }
38 | }
39 |
40 | public extension View {
41 | @inlinable
42 | func controlSize(
43 | _ controlSize: ControlSize
44 | ) -> some View {
45 | environment(\.controlSize, controlSize)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Tokens/Controls/Prominence.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/12/21.
16 | //
17 |
18 | public enum Prominence: Hashable {
19 | case standard
20 | case increased
21 | }
22 |
23 | extension EnvironmentValues {
24 | private enum HeaderProminenceKey: EnvironmentKey {
25 | static var defaultValue: Prominence = .standard
26 | }
27 |
28 | public var headerProminence: Prominence {
29 | get {
30 | self[HeaderProminenceKey.self]
31 | }
32 | set {
33 | self[HeaderProminenceKey.self] = newValue
34 | }
35 | }
36 | }
37 |
38 | public extension View {
39 | func headerProminence(_ prominence: Prominence) -> some View {
40 | environment(\.headerProminence, prominence)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Tokens/Font/FontModifiers.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import Foundation
16 |
17 | public extension Font {
18 | func italic() -> Self {
19 | .init(_ModifiedFontBox(previously: provider) {
20 | $0._italic = true
21 | })
22 | }
23 |
24 | func smallCaps() -> Self {
25 | .init(_ModifiedFontBox(previously: provider) {
26 | $0._smallCaps = true
27 | })
28 | }
29 |
30 | func lowercaseSmallCaps() -> Self {
31 | smallCaps()
32 | }
33 |
34 | func uppercaseSmallCaps() -> Self {
35 | smallCaps()
36 | }
37 |
38 | func monospacedDigit() -> Self {
39 | .init(_ModifiedFontBox(previously: provider) {
40 | $0._monospaceDigit = true
41 | })
42 | }
43 |
44 | func weight(_ weight: Weight) -> Self {
45 | .init(_ModifiedFontBox(previously: provider) {
46 | $0._weight = weight
47 | })
48 | }
49 |
50 | func bold() -> Self {
51 | .init(_ModifiedFontBox(previously: provider) {
52 | $0._bold = true
53 | })
54 | }
55 |
56 | func leading(_ leading: Leading) -> Self {
57 | .init(_ModifiedFontBox(previously: provider) {
58 | $0._leading = leading
59 | })
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Tokens/GridItem.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2019-2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/13/20.
16 | //
17 |
18 | import Foundation
19 |
20 | public struct GridItem {
21 | public enum Size {
22 | case fixed(CGFloat)
23 | case flexible(minimum: CGFloat = 10, maximum: CGFloat = .infinity)
24 | case adaptive(minimum: CGFloat, maximum: CGFloat = .infinity)
25 | }
26 |
27 | public var size: GridItem.Size
28 | public var spacing: CGFloat
29 | public var alignment: Alignment
30 |
31 | public init(
32 | _ size: GridItem.Size = .flexible(),
33 | spacing: CGFloat? = nil,
34 | alignment: Alignment? = nil
35 | ) {
36 | self.size = size
37 | self.spacing = spacing ?? 4
38 | self.alignment = alignment ?? .center
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Tokens/LayoutDirection.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 6/20/22.
16 | //
17 |
18 | public enum LayoutDirection: Hashable, CaseIterable {
19 | case leftToRight
20 | case rightToLeft
21 | }
22 |
23 | extension EnvironmentValues {
24 | private enum LayoutDirectionKey: EnvironmentKey {
25 | static var defaultValue: LayoutDirection = .leftToRight
26 | }
27 |
28 | public var layoutDirection: LayoutDirection {
29 | get { self[LayoutDirectionKey.self] }
30 | set { self[LayoutDirectionKey.self] = newValue }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Tokens/LineBreakMode.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2019-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Max Desiatov on 14/02/2019.
16 | //
17 |
18 | public enum LineBreakMode {
19 | case wordWrap
20 | case charWrap
21 | case clip
22 | case truncateHead
23 | case truncateTail
24 | case truncateMiddle
25 | }
26 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Tokens/TextAlignment.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Max Desiatov on 30/12/2018.
16 | //
17 |
18 | public enum TextAlignment: Hashable, CaseIterable {
19 | case leading,
20 | center,
21 | trailing
22 | }
23 |
24 | extension EnvironmentValues {
25 | private struct _MultilineTextAlignmentKey: EnvironmentKey {
26 | static var defaultValue: TextAlignment = .leading
27 | }
28 |
29 | public var multilineTextAlignment: TextAlignment {
30 | get {
31 | self[_MultilineTextAlignmentKey.self]
32 | }
33 | set {
34 | self[_MultilineTextAlignmentKey.self] = newValue
35 | }
36 | }
37 | }
38 |
39 | public extension View {
40 | @inlinable
41 | func multilineTextAlignment(_ alignment: TextAlignment) -> some View {
42 | environment(\.multilineTextAlignment, alignment)
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/ViewTraits/TagValueTraitKey.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 9/23/21.
16 | //
17 |
18 | import Foundation
19 |
20 | public extension View {
21 | @inlinable
22 | func tag(_ tag: V) -> some View where V: Hashable {
23 | _trait(TagValueTraitKey.self, .tagged(tag))
24 | }
25 |
26 | @inlinable
27 | func _untagged() -> some View {
28 | _trait(IsAuxiliaryContentTraitKey.self, true)
29 | }
30 | }
31 |
32 | @usableFromInline
33 | struct TagValueTraitKey: _ViewTraitKey where V: Hashable {
34 | @usableFromInline
35 | enum Value {
36 | case untagged
37 | case tagged(V)
38 | }
39 |
40 | @inlinable
41 | static var defaultValue: Value { .untagged }
42 | }
43 |
44 | @usableFromInline
45 | struct IsAuxiliaryContentTraitKey: _ViewTraitKey {
46 | @inlinable
47 | static var defaultValue: Bool { false }
48 | @usableFromInline typealias Value = Bool
49 | }
50 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/ViewTraits/_ViewTraitStore.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/10/21.
16 | //
17 |
18 | public struct _ViewTraitStore {
19 | public var values = [ObjectIdentifier: Any]()
20 |
21 | public init(values: [ObjectIdentifier: Any] = [:]) {
22 | self.values = values
23 | }
24 |
25 | public func value(forKey key: Key.Type = Key.self) -> Key.Value
26 | where Key: _ViewTraitKey
27 | {
28 | values[ObjectIdentifier(key)] as? Key.Value ?? Key.defaultValue
29 | }
30 |
31 | public mutating func insert(_ value: Key.Value, forKey key: Key.Type = Key.self)
32 | where Key: _ViewTraitKey
33 | {
34 | values[ObjectIdentifier(key)] = value
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Views/Canvas/GraphicsContext/BlendMode.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020-2021 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 9/18/21.
16 | //
17 |
18 | import Foundation
19 |
20 | public extension GraphicsContext {
21 | enum BlendMode: Int32, Equatable {
22 | case normal
23 | case multiply
24 | case screen
25 | case overlay
26 | case darken
27 | case lighten
28 | case colorDodge
29 | case colorBurn
30 | case softLight
31 | case hardLight
32 | case difference
33 | case exclusion
34 | case hue
35 | case saturation
36 | case color
37 | case luminosity
38 | case clear
39 | case copy
40 | case sourceIn
41 | case sourceOut
42 | case sourceAtop
43 | case destinationOver
44 | case destinationIn
45 | case destinationOut
46 | case destinationAtop
47 | case xor
48 | case plusDarker
49 | case plusLighter
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Views/Containers/Group.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | public struct Group {
16 | let content: Content
17 | public init(@ViewBuilder content: () -> Content) {
18 | self.content = content()
19 | }
20 | }
21 |
22 | extension Group: _PrimitiveView, View where Content: View {
23 | public func _visitChildren(_ visitor: V) where V: ViewVisitor {
24 | visitor.visit(content)
25 | }
26 | }
27 |
28 | extension Group: ParentView where Content: View {
29 | @_spi(TokamakCore)
30 | public var children: [AnyView] { (content as? ParentView)?.children ?? [AnyView(content)] }
31 | }
32 |
33 | extension Group: GroupView where Content: View {}
34 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Views/Controls/ControlGroup.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 7/12/21.
16 | //
17 |
18 | public struct ControlGroup: View where Content: View {
19 | let content: Content
20 |
21 | @Environment(\.controlGroupStyle)
22 | var style
23 |
24 | public init(@ViewBuilder content: () -> Content) {
25 | self.content = content()
26 | }
27 |
28 | public var body: some View {
29 | style.makeBody(configuration: .init(content: .init(body: AnyView(content))))
30 | }
31 | }
32 |
33 | public extension ControlGroup where Content == ControlGroupStyleConfiguration.Content {
34 | init(_ configuration: ControlGroupStyleConfiguration) {
35 | content = configuration.content
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Sources/TokamakCore/Views/Controls/Link.swift:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2020 Tokamak contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Created by Carson Katri on 9/9/20.
16 | //
17 |
18 | import struct Foundation.URL
19 |
20 | public struct Link