You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.2 KiB
80 lines
2.2 KiB
package org.gerweck.scalafx.util
|
|
|
|
import shapeless._
|
|
import shapeless.ops.hlist._
|
|
import shapeless.ops.function._
|
|
|
|
import scalafx.beans.property.ObjectProperty
|
|
import scalafx.beans.value.ObservableValue
|
|
|
|
/**
|
|
*
|
|
* @author Sarah Gerweck <sarah@atscale.com>
|
|
*/
|
|
class ObservableTupler
|
|
[HLObs <: HList, HLParams <: HList, TParams <: Product] private
|
|
(hlist: HLObs)
|
|
(implicit
|
|
unwrapper: Mapper.Aux[ObservableUnwrapper.type, HLObs, HLParams],
|
|
tupler: Tupler.Aux[HLParams, TParams],
|
|
lister: ToList[HLObs, Observable[_]]) {
|
|
|
|
def |@|[O, P, Appended <: HList, Unwrap <: HList, Tupled <: Product, ApList]
|
|
(f: ObservableValue[O, P])
|
|
(implicit
|
|
prepend: Prepend.Aux[HLObs, ObservableValue[O, P]::HNil, Appended],
|
|
uw: Mapper.Aux[ObservableUnwrapper.type, Appended, Unwrap],
|
|
tplr: Tupler.Aux[Unwrap, Tupled],
|
|
lst: ToList[Appended, Observable[_]]): ObservableTupler[Appended, Unwrap, Tupled] = {
|
|
val newHL: Appended = hlist :+ f
|
|
new ObservableTupler[Appended, Unwrap, Tupled](newHL)
|
|
}
|
|
|
|
def hlisted: ObservableValue[HLParams, HLParams] = {
|
|
def calculate() = unwrapper(hlist)
|
|
val original = calculate()
|
|
val prop = ObjectProperty[HLParams](original)
|
|
|
|
for {
|
|
component <- hlist.toList
|
|
} {
|
|
component onChange {
|
|
prop.value = calculate()
|
|
}
|
|
}
|
|
prop
|
|
}
|
|
|
|
def tupled: ObservableValue[TParams, TParams] = {
|
|
def calculate() = unwrapper(hlist).tupled
|
|
|
|
val original = calculate()
|
|
val prop = ObjectProperty[TParams](original)
|
|
|
|
for {
|
|
component <- hlist.toList
|
|
} {
|
|
component onChange {
|
|
prop.value = calculate()
|
|
}
|
|
}
|
|
prop
|
|
}
|
|
|
|
def apply[Func, Result]
|
|
(f: Func)
|
|
(implicit ftp: FnToProduct.Aux[Func, HLParams => Result])
|
|
: ObservableValue[Result, Result] = {
|
|
hlisted map ftp(f)
|
|
}
|
|
}
|
|
|
|
object ObservableUnwrapper extends Poly1 {
|
|
implicit def apply[T, U, A](implicit ev1: A => ObservableValue[T, U]): Case.Aux[A, T] = at[A]{ o => o.value }
|
|
}
|
|
|
|
object ObservableTupler {
|
|
def apply[A, A1, B, B1](a: ObservableValue[A, A1], b: ObservableValue[B, B1]) = {
|
|
new ObservableTupler(a::b::HNil)
|
|
}
|
|
}
|