Skip to content

Commit

Permalink
Updated docs
Browse files Browse the repository at this point in the history
  • Loading branch information
orchetect committed Oct 11, 2024
1 parent b65a1d2 commit 02feaa3
Show file tree
Hide file tree
Showing 16 changed files with 162 additions and 59 deletions.
4 changes: 0 additions & 4 deletions Sources/TimecodeKit/Documentation.docc/Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,3 @@ Value types for representing and working with SMPTE/EBU timecode.
### Additional Value Types

- ``FeetAndFrames``

### Package Internals

- <doc:Internals>
4 changes: 3 additions & 1 deletion Sources/TimecodeKit/Documentation.docc/Getting-Started.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ The library provides UI components that may also be imported if desired.
import TimecodeKitUI
```

The documentation page for ``Timecode`` is a good starting point to jump in. It provides a quick overview of how to form timecode and convert to/from various other time values.
The documentation page for ``Timecode`` provides a quick overview of how to form timecode and convert to/from various other time values.

Example projects are located in the Examples folder to demonstrate usage of the library.

The topics list in the sidebar give overviews of specific areas of concern.

Expand Down
27 changes: 0 additions & 27 deletions Sources/TimecodeKit/Documentation.docc/Internals.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Using rational (fractional) time values and `CMTime`.

Video file metadata and timeline interchange files (AAF, Final Cut Pro XML) encode frame rate and timecode as rational numbers (a fraction consisting of two integers - a numerator and a denominator).

``Timecode`` is capable of initializing from an elapsed time expressed as a rational fraction using a ``TimecodeSourceValue/rational(_:)`` value. The ``Timecode/rationalValue`` property returns the elapsed time expressed as a rational fraction.
``Timecode`` is capable of initializing from an elapsed time expressed as a rational fraction using a `rational` value. The ``Timecode/rationalValue`` property returns the elapsed time expressed as a rational fraction.

```swift
try Timecode(.rational(Fraction(1920919, 30000)), at: .fps29_97)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import Foundation

/// Protocol used in TimecodeKit to provide shared properties and methods for frame rate types.
@_documentation(visibility: internal)
public protocol FrameRateProtocol where
Self: CaseIterable,
AllCases.Index == Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ protocol _GuaranteedRichTimecodeSource {
/// > Note:
/// > This struct is not designed to be used directly. Use the static construction methods to form a value instead.
/// > See ``Timecode`` for more details and examples.
@_documentation(visibility: internal)
public struct TimecodeSourceValue {
var value: _TimecodeSource

Expand All @@ -100,6 +101,7 @@ public struct TimecodeSourceValue {
/// > Note:
/// > This struct is not designed to be used directly. Use the static construction methods to form a value instead.
/// > See ``Timecode`` for more details and examples.
@_documentation(visibility: internal)
public struct AsyncTimecodeSourceValue {
var value: _AsyncTimecodeSource

Expand All @@ -113,6 +115,7 @@ public struct AsyncTimecodeSourceValue {
/// > Note:
/// > This struct is not designed to be used directly. Use the static construction methods to form a value instead.
/// > See ``Timecode`` for more details and examples.
@_documentation(visibility: internal)
public struct FormattedTimecodeSourceValue {
var value: _FormattedTimecodeSource

Expand All @@ -126,6 +129,7 @@ public struct FormattedTimecodeSourceValue {
/// > Note:
/// > This struct is not designed to be used directly. Use the static construction methods to form a value instead.
/// > See ``Timecode`` for more details and examples.
@_documentation(visibility: internal)
public struct RichTimecodeSourceValue {
var value: _RichTimecodeSource

Expand All @@ -140,6 +144,7 @@ public struct RichTimecodeSourceValue {
/// > Note:
/// > This struct is not designed to be used directly. Use the static construction methods to form a value instead.
/// > See ``Timecode`` for more details and examples.
@_documentation(visibility: internal)
public struct AsyncRichTimecodeSourceValue {
var value: _AsyncRichTimecodeSource

Expand All @@ -153,6 +158,7 @@ public struct AsyncRichTimecodeSourceValue {
/// > Note:
/// > This struct is not designed to be used directly. Use the static construction methods to form a value instead.
/// > See ``Timecode`` for more details and examples.
@_documentation(visibility: internal)
public struct GuaranteedTimecodeSourceValue {
var value: _GuaranteedTimecodeSource

Expand All @@ -166,6 +172,7 @@ public struct GuaranteedTimecodeSourceValue {
/// > Note:
/// > This struct is not designed to be used directly. Use the static construction methods to form a value instead.
/// > See ``Timecode`` for more details and examples.
@_documentation(visibility: internal)
public struct GuaranteedRichTimecodeSourceValue {
var value: _GuaranteedRichTimecodeSource

Expand Down
1 change: 1 addition & 0 deletions Sources/TimecodeKit/Utilities/Outsourced/Integers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ extension BinaryInteger {
/// - for the integer 5, this would return 1
/// - for the integer 10, this would return 2
/// - for the integer 250, this would return 3
@_documentation(visibility: internal)
@_disfavoredOverload
public var numberOfDigits: Int {
if self < 10 && self >= 0 || self > -10 && self < 0 {
Expand Down
1 change: 1 addition & 0 deletions Sources/TimecodeKit/Utilities/RangeAttribute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//

/// An individual time attribute of a time range.
@_documentation(visibility: internal)
public enum RangeAttribute: Equatable, Hashable {
case start
case end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import TimecodeKit

// MARK: API Changes in TimecodeKit 2.0.0 UI

@_documentation(visibility: internal)
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
extension Timecode {
@_disfavoredOverload
Expand Down
23 changes: 20 additions & 3 deletions Sources/TimecodeKitUI/Documentation.docc/Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,26 @@ UI controls and tools for formatting and displaying timecode, including user-edi

### AppKit

- ``TimecodeKit/Timecode/TextField``
- ``TimecodeKit/Timecode/TextFieldCell``
- ``TimecodeKitUI/TimecodeKit/Timecode/TextField``
- ``TimecodeKitUI/TimecodeKit/Timecode/TextFieldCell``

### SwiftUI

- ``TimecodeKit/Timecode/stringValueValidatedText(format:invalidModifiers:defaultModifiers:)``
- ``TimecodeField``
- ``TimecodeText``

### SwiftUI View Modifiers

- ``SwiftUICore/View/timecodeFormat(_:)``
- ``SwiftUICore/View/timecodeHighlightStyle(_:)``
- ``SwiftUICore/View/timecodeSeparatorStyle(_:)``
- ``SwiftUICore/View/timecodeValidationStyle(_:)``

### SwiftUI State

- ``TimecodeState``
- ``SwiftUICore/Binding/option(_:)``

### AttributedString

- ``Foundation/AttributedString/init(_:format:separatorStyle:validationStyle:)``
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import TimecodeKit

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension Binding where Value == Timecode.StringFormat {
/// Returns a SwiftUI `Bool` `Binding` that gets and sets the the specified option in ``Timecode/StringFormat``.
/// Returns a SwiftUI `Bool` `Binding` that gets and sets the the specified option in
/// `Timecode.StringFormat`.
///
/// If the option is present, `true` is returned.
/// Setting `true` inserts the option, and setting `false` removes the option.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ import TimecodeKit
// MARK: - TimecodeFormat

/// Sets the timecode string format for ``TimecodeField`` and ``Text(timecode:)`` views.
@_documentation(visibility: internal)
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
struct TimecodeFormatKey: EnvironmentKey {
public static var defaultValue: Timecode.StringFormat = .default()
}

@_documentation(visibility: internal)
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension EnvironmentValues {
/// Sets the timecode string format for ``TimecodeField`` and ``Text(timecode:)`` views.
/// Sets the timecode string format for ``TimecodeField`` and ``TimecodeText`` views.
public var timecodeFormat: Timecode.StringFormat {
get { self[TimecodeFormatKey.self] }
set { self[TimecodeFormatKey.self] = newValue }
Expand All @@ -30,11 +32,13 @@ extension EnvironmentValues {

/// Sets the component highlight style for ``TimecodeField`` views.
/// By default, the application's `accentColor` is used.
@_documentation(visibility: internal)
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
struct TimecodeHighlightStyleKey: EnvironmentKey {
public static var defaultValue: Color? = .accentColor
}

@_documentation(visibility: internal)
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension EnvironmentValues {
/// Sets the component highlight style for ``TimecodeField`` views.
Expand All @@ -47,18 +51,20 @@ extension EnvironmentValues {

// MARK: - TimecodeSeparatorStyle

/// Sets the text separator style for ``TimecodeField`` and ``Text(timecode:)`` views.
/// Sets the text separator style for ``TimecodeField`` and ``TimecodeText`` views.
/// If `color` is nil, the foreground style is used.
///
/// - Note: To set the default color of the component values, use `foregroundColor` or `foregroundStyle` view modifiers.
@_documentation(visibility: internal)
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
struct TimecodeSeparatorStyleKey: EnvironmentKey {
public static var defaultValue: Color? = nil
}

@_documentation(visibility: internal)
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension EnvironmentValues {
/// Sets the text separator style for ``TimecodeField`` and ``Text(timecode:)`` views.
/// Sets the text separator style for ``TimecodeField`` and ``TimecodeText`` views.
/// If `color` is nil, the foreground style is used.
///
/// - Note: To set the default color of the component values, use `foregroundColor` or `foregroundStyle` view modifiers.
Expand All @@ -71,14 +77,16 @@ extension EnvironmentValues {

// MARK: - TimecodeValidationStyle

@_documentation(visibility: internal)
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
struct TimecodeValidationStyleKey: EnvironmentKey {
public static var defaultValue: Color? = .red
}

@_documentation(visibility: internal)
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension EnvironmentValues {
/// Sets timecode component validation style for ``TimecodeField`` and ``Text(timecode:)`` views.
/// Sets timecode component validation style for ``TimecodeField`` and ``TimecodeText`` views.
///
/// This foreground color will be used only for any timecode component values that are invalid for the given
/// properties (frame rate, subframes base, and upper limit).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct TimecodeFormatViewModifier: ViewModifier {

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension View {
/// Sets the timecode string format for ``TimecodeField`` and ``Text(timecode:)`` views.
/// Sets the timecode string format for ``TimecodeField`` and ``TimecodeText`` views.
public func timecodeFormat(
_ format: Timecode.StringFormat
) -> some View {
Expand Down Expand Up @@ -65,10 +65,11 @@ struct TimecodeSeparatorStyleViewModifier: ViewModifier {

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension View {
/// Sets the text separator style for ``TimecodeField`` and ``Text(timecode:)`` views.
/// Sets the text separator style for ``TimecodeField`` and ``TimecodeText`` views.
/// If `color` is nil, the foreground style is used.
///
/// - Note: To set the default color of the component values, use `foregroundColor` or `foregroundStyle` view modifiers.
/// - Note: To set the default color of the component values, use `foregroundColor` or `foregroundStyle` view
/// modifiers.
public func timecodeSeparatorStyle(
_ color: Color? = nil
) -> some View {
Expand All @@ -89,7 +90,7 @@ struct TimecodeValidationStyleViewModifier: ViewModifier {

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension View {
/// Sets timecode component validation style for ``TimecodeField`` and ``Text(timecode:)`` views.
/// Sets timecode component validation style for ``TimecodeField`` and ``TimecodeText`` views.
///
/// This foreground color will be used only for any timecode component values that are invalid for the given
/// properties (frame rate, subframes base, and upper limit).
Expand Down
77 changes: 75 additions & 2 deletions Sources/TimecodeKitUI/SwiftUI/TimecodeField/TimecodeField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,79 @@
import SwiftUI
import TimecodeKit

/// A hybrid text field designed for timecode entry, allowing specialized format and style view modifiers
/// including the ability to colorize invalid timecode components.
///
/// ## Initializers
///
/// The view may be initialized to a `Timecode` instance directly. In this case, it is required to store the
/// `Timecode` instance in the view using the custom ``TimecodeState`` wrapper in place of the typical SwiftUI
/// `@State` wrapper.
///
/// It may then be passed into subviews using normal SwiftUI Bindings.
///
/// ```swift
/// struct ContentView: View {
/// @TimecodeState private var timecode: Timecode = // ...
///
/// var body: some View {
/// TimecodeField(timecode: $timecode)
/// MySubView(timecode: $timecode)
/// }
/// }
///
/// struct MySubView: View {
/// @Binding var timecode: Timecode
/// }
/// ```
///
/// For more granular flexibility, timecode components and properties may be bound as individual properties.
///
/// ```swift
/// @State private var components: Timecode.Components = .zero
/// @State private var frameRate: TimecodeFrameRate = .fps24
///
/// var body: some View {
/// TimecodeField(components: $components, at: frameRate)
/// }
/// ```
///
/// ## Style and Format Modifiers
///
/// You can supply format and style options by using the available view modifiers.
///
/// ```swift
/// TimecodeField(timecode: $timecode)
/// .foregroundColor(.primary)
/// .timecodeFormat([.showSubFrames])
/// .timecodeHighlightStyle(.accentColor)
/// .timecodeSeparatorStyle(.secondary)
/// .timecodeValidationStyle(.red)
/// ```
///
/// ## Focus
///
/// Each timecode component individually receives focus one at a time.
///
/// - On macOS and iOS, the user can click or tap on specific timecode components to move the focus.
/// - On macOS and iOS, a hardware keyboard accepts:
/// - left and right arrow keys to move the focus between timecode components
/// - tab key to advance to the next timecode component
/// - inputting a timecode separator (`.`, `:`) will advance the focus to the next timecode component
/// - On iOS, in the absence of a hardware keyboard, the standard decimal pad keyboard will appear on-screen.
///
/// ## Hardware Keyboard Input
///
/// The view is capable of receiving hardware keyboard input on macOS and iOS, as well as iOS on-screen keyboard input.
///
/// | Key | Description |
/// | --- | --- |
/// | Numeric digit keys | Enters digits for the currently focused timecode component. |
/// | `Return` or `Escape` | Can be used to remove focus from the field. |
/// | `Backspace` | Resets the timecode component to zero if it has freshly received focus. Once the user begins to enter digits into the component, the Backspace key will function as single digit delete akin to a text-entry field.
/// | `Delete` (`Del` key, or `forwardDelete`) | Resets the component to zero. |
///
/// For keys that navigate timecode component focus, see the Focus section above.
@available(macOS 14, iOS 17, *)
@available(watchOS, unavailable)
@available(tvOS, unavailable)
Expand Down Expand Up @@ -50,8 +123,8 @@ public struct TimecodeField: View {
public init(
components: Binding<Timecode.Components>,
at frameRate: TimecodeFrameRate,
base: Timecode.SubFramesBase,
limit: Timecode.UpperLimit
base: Timecode.SubFramesBase = .default(),
limit: Timecode.UpperLimit = .max24Hours
) {
let properties = Timecode.Properties(rate: frameRate, base: base, limit: limit)
self.init(components: components, using: properties)
Expand Down
Loading

0 comments on commit 02feaa3

Please sign in to comment.