//
|
// NSControl+Rx.swift
|
// RxCocoa
|
//
|
// Created by Krunoslav Zaher on 5/31/15.
|
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
|
//
|
|
#if os(macOS)
|
|
import Cocoa
|
import RxSwift
|
|
private var rx_value_key: UInt8 = 0
|
private var rx_control_events_key: UInt8 = 0
|
|
extension Reactive where Base: NSControl {
|
|
/// Reactive wrapper for control event.
|
public var controlEvent: ControlEvent<()> {
|
MainScheduler.ensureRunningOnMainThread()
|
|
let source = self.lazyInstanceObservable(&rx_control_events_key) { () -> Observable<Void> in
|
Observable.create { [weak control = self.base] observer in
|
MainScheduler.ensureRunningOnMainThread()
|
|
guard let control = control else {
|
observer.on(.completed)
|
return Disposables.create()
|
}
|
|
let observer = ControlTarget(control: control) { _ in
|
observer.on(.next(()))
|
}
|
|
return observer
|
}
|
.take(until: self.deallocated)
|
.share()
|
}
|
|
return ControlEvent(events: source)
|
}
|
|
/// Creates a `ControlProperty` that is triggered by target/action pattern value updates.
|
///
|
/// - parameter getter: Property value getter.
|
/// - parameter setter: Property value setter.
|
public func controlProperty<T>(
|
getter: @escaping (Base) -> T,
|
setter: @escaping (Base, T) -> Void
|
) -> ControlProperty<T> {
|
MainScheduler.ensureRunningOnMainThread()
|
|
let source = self.base.rx.lazyInstanceObservable(&rx_value_key) { () -> Observable<()> in
|
return Observable.create { [weak weakControl = self.base] (observer: AnyObserver<()>) in
|
guard let control = weakControl else {
|
observer.on(.completed)
|
return Disposables.create()
|
}
|
|
observer.on(.next(()))
|
|
let observer = ControlTarget(control: control) { _ in
|
if weakControl != nil {
|
observer.on(.next(()))
|
}
|
}
|
|
return observer
|
}
|
.take(until: self.deallocated)
|
.share(replay: 1, scope: .whileConnected)
|
}
|
.flatMap { [weak base] _ -> Observable<T> in
|
guard let control = base else { return Observable.empty() }
|
return Observable.just(getter(control))
|
}
|
|
let bindingObserver = Binder(self.base, binding: setter)
|
|
return ControlProperty(values: source, valueSink: bindingObserver)
|
}
|
}
|
|
|
#endif
|