mirror of
https://github.com/yattee/yattee.git
synced 2026-02-20 17:59:45 +00:00
116 lines
3.8 KiB
Swift
116 lines
3.8 KiB
Swift
//
|
|
// TapGesturesSettings.swift
|
|
// Yattee
|
|
//
|
|
// Settings for tap gesture recognition and behavior.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
/// Settings for tap gestures on the player.
|
|
struct TapGesturesSettings: Codable, Hashable, Sendable {
|
|
/// Whether tap gestures are enabled.
|
|
var isEnabled: Bool
|
|
|
|
/// The zone layout to use.
|
|
var layout: TapZoneLayout
|
|
|
|
/// Configuration for each zone in the layout.
|
|
var zoneConfigurations: [TapZoneConfiguration]
|
|
|
|
/// Double-tap timing window in milliseconds.
|
|
var doubleTapInterval: Int
|
|
|
|
// MARK: - Initialization
|
|
|
|
/// Creates tap gestures settings.
|
|
/// - Parameters:
|
|
/// - isEnabled: Whether enabled (default: false).
|
|
/// - layout: Zone layout (default: horizontalSplit).
|
|
/// - zoneConfigurations: Zone configurations.
|
|
/// - doubleTapInterval: Double-tap timing in ms (default: 300).
|
|
init(
|
|
isEnabled: Bool = false,
|
|
layout: TapZoneLayout = .horizontalSplit,
|
|
zoneConfigurations: [TapZoneConfiguration]? = nil,
|
|
doubleTapInterval: Int = 300
|
|
) {
|
|
self.isEnabled = isEnabled
|
|
self.layout = layout
|
|
self.zoneConfigurations = zoneConfigurations ?? Self.defaultConfigurations(for: layout)
|
|
self.doubleTapInterval = doubleTapInterval
|
|
}
|
|
|
|
// MARK: - Defaults
|
|
|
|
/// Default settings with gestures disabled.
|
|
static let `default` = TapGesturesSettings()
|
|
|
|
/// Creates default zone configurations for a layout.
|
|
/// - Parameter layout: The zone layout.
|
|
/// - Returns: Default configurations with sensible actions.
|
|
static func defaultConfigurations(for layout: TapZoneLayout) -> [TapZoneConfiguration] {
|
|
layout.positions.map { position in
|
|
TapZoneConfiguration(
|
|
position: position,
|
|
action: defaultAction(for: position)
|
|
)
|
|
}
|
|
}
|
|
|
|
/// Returns the default action for a zone position.
|
|
private static func defaultAction(for position: TapZonePosition) -> TapGestureAction {
|
|
switch position {
|
|
case .full:
|
|
.togglePlayPause
|
|
case .left, .leftThird, .topLeft, .bottomLeft:
|
|
.seekBackward(seconds: 10)
|
|
case .right, .rightThird, .topRight, .bottomRight:
|
|
.seekForward(seconds: 10)
|
|
case .top:
|
|
.togglePlayPause
|
|
case .bottom:
|
|
.togglePlayPause
|
|
case .center:
|
|
.togglePlayPause
|
|
}
|
|
}
|
|
|
|
// MARK: - Helpers
|
|
|
|
/// Returns the configuration for a specific position.
|
|
/// - Parameter position: The zone position.
|
|
/// - Returns: The configuration, or nil if not found.
|
|
func configuration(for position: TapZonePosition) -> TapZoneConfiguration? {
|
|
zoneConfigurations.first { $0.position == position }
|
|
}
|
|
|
|
/// Updates the configuration for a zone, or adds it if not present.
|
|
/// - Parameter config: The updated configuration.
|
|
/// - Returns: Updated settings.
|
|
func withUpdatedConfiguration(_ config: TapZoneConfiguration) -> TapGesturesSettings {
|
|
var settings = self
|
|
if let index = settings.zoneConfigurations.firstIndex(where: { $0.position == config.position }) {
|
|
settings.zoneConfigurations[index] = config
|
|
} else {
|
|
settings.zoneConfigurations.append(config)
|
|
}
|
|
return settings
|
|
}
|
|
|
|
/// Creates settings with a new layout, generating default configurations.
|
|
/// - Parameter newLayout: The new layout.
|
|
/// - Returns: Updated settings with new layout and configurations.
|
|
func withLayout(_ newLayout: TapZoneLayout) -> TapGesturesSettings {
|
|
var settings = self
|
|
settings.layout = newLayout
|
|
settings.zoneConfigurations = Self.defaultConfigurations(for: newLayout)
|
|
return settings
|
|
}
|
|
|
|
// MARK: - Validation
|
|
|
|
/// Double-tap interval range in milliseconds.
|
|
static let doubleTapIntervalRange = 150...600
|
|
}
|