Skip to content

Commit

Permalink
Merge pull request #12 from maxxfrazer/docs-and-example
Browse files Browse the repository at this point in the history
1.3.1 Update
- DocC is looking a lot nicer now.
- Changed some initialisers for RUIControls in minor ways.
  - If you're having trouble, swap out `RUI` parameter for `rui` in the initialisers. Otherwise there should be a recommended update Xcode presents to you.
  • Loading branch information
maxxfrazer authored Mar 1, 2023
2 parents 951d641 + 457d810 commit 8873130
Show file tree
Hide file tree
Showing 18 changed files with 274 additions and 40 deletions.
1 change: 1 addition & 0 deletions Sources/RealityUI/HasRUI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ public protocol HasRUIMaterials: HasRUI {
/// This method does not need to be called by outside of a RealityUI class.
func updateMaterials()
}

extension HasRUIMaterials {
fileprivate func materialsShouldChange() {
self.updateMaterials()
Expand Down
4 changes: 3 additions & 1 deletion Sources/RealityUI/HasTurnTouch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import RealityKit

/// An interface used for entities which are to be rotated via one finger drag gestures
public protocol HasTurnTouch: HasPanTouch {}
public protocol HasTurnTouch: HasARTouch {}

public extension HasTurnTouch {
/// Plane that we run the raycast against.
Expand Down Expand Up @@ -104,6 +104,8 @@ public typealias HasPivotTouch = HasTurnTouch
/// A collection of properties for the entities that conform to ``HasTurnTouch``.
@available(*, deprecated, renamed: "TurnComponent")
public typealias PivotComponent = TurnComponent

/// An interface used for entities which are to be rotated via one finger drag gestures
public extension HasTurnTouch {
/// The axis to turn around for the entity.
@available(*, deprecated, renamed: "turnAxis")
Expand Down
16 changes: 14 additions & 2 deletions Sources/RealityUI/RUILongTouchGestureRecognizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,21 @@ extension HasARTouch {

/// An interface used for all entities that have long touches where movement
/// is the main interest (vs HasTouchUpInside)
public protocol HasPanTouch: HasARTouch {}
public protocol HasPanTouch: HasARTouch {
/// A parameter that can be used by being set when the touch starts.
/// It can then be used to know how far a user has toggled since the start of the touch.
/// Do not set this value outside of the class using it.
var panGestureOffset: SIMD3<Float> {get set}
}

public extension HasPanTouch {}
public extension HasPanTouch {
func panTouchStarted(at worldCoordinate: SIMD3<Float>, hasCollided: Bool) {
self.panGestureOffset = self.convert(position: worldCoordinate, from: nil)
}
func panTouchEnded(at worldCoordinate: SIMD3<Float>?, hasCollided: Bool?) {
self.panGestureOffset = .zero
}
}

/// An interface used for all entities that have long touches where movement
/// is is not the main interest (vs HasPanTouch)
Expand Down
19 changes: 13 additions & 6 deletions Sources/RealityUI/RUISlider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ public class RUISlider: Entity, HasSlider, HasModel {
/// - worldCoordinate: Collision of the object or collision plane
/// - hasCollided: Is the touch colliding with the `CollisionComponent` or not.
public func arTouchStarted(at worldCoordinate: SIMD3<Float>, hasCollided: Bool = true) {
let localPos = self.convert(position: worldCoordinate, from: nil)
self.panGestureOffset = self.value - (0.5 - localPos.x / self.sliderLength)
self.panTouchStarted(at: worldCoordinate, hasCollided: hasCollided)
self.startValue = self.value
self.sliderUpdateCallback?(self, .started)
}
/// Called when a touch is still on screen or a mouse is still down.
Expand All @@ -91,7 +91,7 @@ public class RUISlider: Entity, HasSlider, HasModel {
/// - hasCollided: Is the touch colliding with the `CollisionComponent` or not.
public func arTouchUpdated(at worldCoordinate: SIMD3<Float>, hasCollided: Bool = true) {
let localPos = self.convert(position: worldCoordinate, from: nil)
var newPercent = (0.5 - localPos.x / self.sliderLength) + self.panGestureOffset
var newPercent = self.startValue + (self.panGestureOffset.x - localPos.x) / self.sliderLength
self.clampSlideValue(&newPercent)
if self.value == newPercent {
return
Expand All @@ -107,9 +107,10 @@ public class RUISlider: Entity, HasSlider, HasModel {
}

public func arTouchEnded(at worldCoordinate: SIMD3<Float>? = nil, hasCollided: Bool? = nil) {
self.panGestureOffset = 0
updateCollision()
self.sliderUpdateCallback?(self, .ended)
self.panTouchEnded(at: worldCoordinate, hasCollided: hasCollided)
self.startValue = .zero
}
}

Expand Down Expand Up @@ -149,7 +150,8 @@ public struct SliderComponent: Component {
case ended
}

internal var arGestureOffset: Float = 0
internal var arGestureOffset: SIMD3<Float> = .zero
internal var startValue: Float = 0
internal enum UIPart: String {
case thumb
case empty
Expand Down Expand Up @@ -194,6 +196,7 @@ public protocol HasSlider: HasPanTouch, HasRUIMaterials {
/// set isContinuous to `true` to get every change,
/// `false` to just get start and end on each gesture.
var sliderUpdateCallback: ((HasSlider, SliderComponent.SlidingState) -> Void)? { get set }
var startValue: Float { get set }
}

public extension HasSlider {
Expand All @@ -202,10 +205,14 @@ public extension HasSlider {
get { self.components[SliderComponent.self] ?? SliderComponent() }
set { self.components[SliderComponent.self] = newValue }
}
var panGestureOffset: Float {
var panGestureOffset: SIMD3<Float> {
get { self.slider.arGestureOffset }
set { self.slider.arGestureOffset = newValue }
}
var startValue: Float {
get { self.slider.startValue }
set { self.slider.startValue = newValue }
}
/// Length of the slider. The default is 10m.
var sliderLength: Float { self.slider.length }
/// The slider's current value. Ranges from 0 to 1.
Expand Down
20 changes: 5 additions & 15 deletions Sources/RealityUI/RUIStepper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,14 @@ public class RUIStepper: Entity, HasRUIMaterials, HasStepper {
/// Stepper's negative button has been pressed
public var downTrigger: ((HasStepper) -> Void)?

@available(*, deprecated, renamed: "init(stepper:rui:upTrigger:downTrigger:)")
public convenience init(
stepper: StepperComponent? = nil,
RUI: RUIComponent? = nil,
upTrigger: ((HasStepper) -> Void)? = nil,
downTrigger: ((HasStepper) -> Void)? = nil
) {
self.init(stepper: stepper, rui: RUI, upTrigger: upTrigger, downTrigger: downTrigger)
}

/// Creates a RealityUI Stepper entity with optional ``StepperComponent``, ``RUIComponent``,
/// as well as ``RUIStepper/upTrigger`` and ``RUIStepper/downTrigger`` callbacks.
/// - Parameters:
/// - stepper: Details about the stepper colours to be set when initialized.
/// - rui: Details about the RealityUI Entity.
/// - upTrigger: Callback function to receive updates then the up button has been clicked.
/// - downTrigger: Callback function to receive updates then the down button has been clicked.
required public init(
public init(
stepper: StepperComponent? = nil,
rui: RUIComponent? = nil,
upTrigger: ((HasStepper) -> Void)? = nil,
Expand Down Expand Up @@ -152,11 +142,11 @@ public struct StepperComponent: Component {
}
/// Stepper styles
public enum Style {
/// Style of stepper with a + and - symbol
/// Style of stepper with a + and - symbols.
case minusPlus
/// Style of stepper with a "〈" and "〉" symbol
/// Style of stepper with a "〈" and "〉" chevrons.
case arrowLeftRight
/// Style of stepper with up and down pointing symbols
/// Style of stepper with up and down chevrons.
case arrowDownUp
}
#if os(iOS)
Expand Down Expand Up @@ -208,7 +198,7 @@ public struct StepperComponent: Component {
}

/// An interface used for entities with mutliple click actions, like RUIStepper.
public protocol HasStepper: HasPanTouch, HasRUIMaterials {}
public protocol HasStepper: HasARTouch, HasRUIMaterials {}

public extension HasStepper {
func updateMaterials() {
Expand Down
14 changes: 8 additions & 6 deletions Sources/RealityUI/RUISwitch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import RealityKit

/// A RealityUI Switch to be added to a RealityKit scene.
public class RUISwitch: Entity, HasSwitch, HasPanTouch {
public var panGestureOffset: Float = 0
public var panGestureOffset: SIMD3<Float> = .zero

public var collisionPlane: float4x4? {
return self.transformMatrix(relativeTo: nil)
Expand All @@ -30,9 +30,10 @@ public class RUISwitch: Entity, HasSwitch, HasPanTouch {
var distanceTravelled: Float = 0

public func arTouchStarted(at worldCoordinate: SIMD3<Float>, hasCollided: Bool) {
let localPos = self.convert(position: worldCoordinate, from: nil)
self.startedOnThumb = pow(togglePos.x - localPos.x, 2) + pow(togglePos.y - localPos.y, 2) < 0.25
self.panGestureOffset = localPos.x
self.panTouchStarted(at: worldCoordinate, hasCollided: hasCollided)
let moveDiff = self.togglePos - self.panGestureOffset
let xyLenSq = moveDiff.x * moveDiff.x + moveDiff.y * moveDiff.y
self.startedOnThumb = xyLenSq < 0.25
self.distanceTravelled = 0
self.compressThumb()
}
Expand All @@ -44,7 +45,7 @@ public class RUISwitch: Entity, HasSwitch, HasPanTouch {
public func arTouchUpdated(at worldCoordinate: SIMD3<Float>, hasCollided: Bool) {
if self.startedOnThumb, let thumb = self.getModel(part: .thumb) {
let localPos = self.convert(position: worldCoordinate, from: nil)
var newThumbPos = self.togglePos.x + localPos.x - self.panGestureOffset
var newThumbPos = self.togglePos.x + localPos.x - self.panGestureOffset.x
self.clampThumbValue(&newThumbPos)
self.distanceTravelled += abs(thumb.position.x - newThumbPos)
thumb.position.x = newThumbPos
Expand Down Expand Up @@ -84,12 +85,13 @@ public class RUISwitch: Entity, HasSwitch, HasPanTouch {
} else {
self.setOn(self.isOn)
}

self.thumbCompressed = false
self.panTouchEnded(at: worldCoordinate, hasCollided: hasCollided)
}

public func arTouchCancelled() {
self.uncompressThumb()
self.panTouchEnded(at: nil, hasCollided: nil)
}

/// Switch's isOn property has changed
Expand Down
9 changes: 0 additions & 9 deletions Sources/RealityUI/RUIText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,6 @@ open class RUIText: Entity, HasText, HasClick {
self.init(textComponent: textComponent)
}

@available(*, deprecated, renamed: "init(textComponent:rui:tapAction:)")
public convenience init(
textComponent: TextComponent? = nil,
RUI: RUIComponent? = nil,
tapAction: ((HasClick, SIMD3<Float>?) -> Void)? = nil
) {
self.init(textComponent: textComponent, rui: RUI, tapAction: tapAction)
}

/// Creates a RealityUI Text entity.
/// - Parameters:
/// - textComponent: Details about the text object, including text, font, extrusion and more.
Expand Down
18 changes: 18 additions & 0 deletions Sources/RealityUI/RealityUI.docc/HasARTouch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ``RealityUI/HasARTouch``

## Overview

HasARTouch makes it easy to add touch events similar to those seen with <doc:RUIControls>.

Creating a method that inherits the protocol ``HasARTouch`` lets you use the callback methods to add your own custom events to this AR object. ``arTouchUpdated(at:hasCollided:)`` is not only called when you move your finger, but on every new frame in the RealityKit scene.

If you want to use a specific plane, rather that the object's collision shape after the initial touch, just set-up the ``collisionPlane`` parameter. If it is set up, all touch event callbacks will have the collision location as the location on that plane. This is used in classes such as ``RUISlider``, so that you can keep moving the slider without needing to always touch the slider's thumb.

## Topics

### Touch Event Callbacks

- ``arTouchStarted(at:hasCollided:)``
- ``arTouchUpdated(at:hasCollided:)``
- ``arTouchEnded(at:hasCollided:)``
- ``arTouchCancelled()``
31 changes: 31 additions & 0 deletions Sources/RealityUI/RealityUI.docc/RUIButton.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# ``RealityUI/RUIButton``

A control that executes your custom code in response to user interactions.

## Overview

When you tap a button, the button performs any actions attached to it.

## Topics

### Creating a Button

- ``init()``
- ``init(button:rui:touchUpInside:)``
- ``init(button:RUI:updateCallback:)``

### Button Action Callback

- ``touchUpInside``

### Customising a Button

- ``buttonColor``
- ``baseColor``
- ``compress``
- ``size``
- ``cornerRadius``
- ``padding``
- ``button``
- ``ButtonComponent``
- ``HasButton``
2 changes: 1 addition & 1 deletion Sources/RealityUI/RealityUI.docc/RUIControls.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ RUIControls are all the elements such as ``RUISlider``, ``RUISwitch``, ``RUIStep

## Overview

Look below to see how to add all the RUIControls to your RealityKit Scene. Make sure to check out ``<doc:Setup>`` before adding RUIControls; otherwise the touch gestures may not work.
Look below to see how to add all the RUIControls to your RealityKit Scene. Make sure to check out <doc:Setup> before adding RUIControls; otherwise the touch gestures may not work.

## Control Types

Expand Down
34 changes: 34 additions & 0 deletions Sources/RealityUI/RealityUI.docc/RUISlider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# ``RealityUI/RUISlider``

RUISlider is perfect for interpolating a value.

![RealityUI Slider](ruislider-orange-example)

```swift
RUISlider(length: 4, start: 2 / 4) {
print(slider.value)
}
```

## Topics

### Creating a Slider

- ``init()``
- ``init(length:start:steps:updateCallback:)``
- ``init(slider:rui:sliderUpdateCallback:)``
- ``init(slider:RUI:updateCallback:)``

### Slider Value Updates

- ``sliderUpdateCallback``
- ``value``
- ``setPercent(to:animated:)``
- ``isContinuous``

### Slider Properties

- ``steps``
- ``RUISlider/sliderLength``
- ``SliderComponent``
- ``HasSlider``
30 changes: 30 additions & 0 deletions Sources/RealityUI/RealityUI.docc/RUIStepper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# ``RealityUI/RUIStepper``

A control for incrementing or decrementing a value.

## Overview

RUIStepper can be used for changing a value by either incrementing or decrementing based on a set value. This can also be used to cycle through a carousel of options by iterating over an array of elements.

To activate the stepper, the user must press and release from the same side of the stepper. Holding the stepper will not repeatedly call the increment/decrement event.

## Topics

### Creating a Stepper

- ``init()``
- ``init(upTrigger:downTrigger:)``
- ``init(style:upTrigger:downTrigger:)``
- ``init(stepper:rui:upTrigger:downTrigger:)``

### Stepper Value Updates

- ``upTrigger``
- ``downTrigger``

### Customising

- ``style``
- ``stepper``
- ``StepperComponent``
- ``HasStepper``
27 changes: 27 additions & 0 deletions Sources/RealityUI/RealityUI.docc/RUISwitch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# ``RealityUI/RUISwitch``

``RUISwitch`` is a 3D toggle switch with an on and off state.
Default bounding box is approximately 1.6x1x1m

![RUISwitch floating around with an orange background](ruiswitch-orange-example.gif)

```swift
RUISwitch() { switch in
print(switch.isOn)
}
```

## Topics

### Creating a Switch

- ``init()``
- ``init(switchness:rui:switchCallback:)``
- ``switchCallback``
- ``init(switchness:RUI:changedCallback:)``

### Customising The Switch

- ``switchness``
- ``SwitchComponent``
- ``HasSwitch``
Loading

0 comments on commit 8873130

Please sign in to comment.