de.sciss.lucre.swing.impl.DoubleSpinnerViewImpl.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lucreswing_2.13.0-RC2 Show documentation
Show all versions of lucreswing_2.13.0-RC2 Show documentation
Swing support for Lucre, and common views
The newest version!
/*
* DoubleSpinnerViewImpl.scala
* (LucreSwing)
*
* Copyright (c) 2014-2019 Hanns Holger Rutz. All rights reserved.
*
* This software is published under the GNU Lesser General Public License v2.1+
*
*
* For further information, please contact Hanns Holger Rutz at
* [email protected]
*/
package de.sciss.lucre.swing.impl
import de.sciss.desktop.UndoManager
import de.sciss.lucre.expr.CellView
import de.sciss.lucre.stm
import de.sciss.lucre.stm.{Disposable, Sys}
import de.sciss.lucre.swing.DoubleSpinnerView
import de.sciss.lucre.swing.LucreSwing.{deferTx, requireEDT}
import de.sciss.swingplus.Spinner
import javax.swing.{JSpinner, SpinnerNumberModel}
object DoubleSpinnerViewImpl {
def apply[S <: Sys[S]](_cell: CellView[S#Tx, Double], name: String, width: Int)
(implicit tx: S#Tx, cursor: stm.Cursor[S],
undoManager: UndoManager): DoubleSpinnerView[S] = {
val res: Impl[S] = new Impl[S](maxWidth = width) {
impl =>
protected var (value, committer) = CellViewFactory.mkCommitter(_cell, name)(tx, cursor)
protected val observer: Disposable[S#Tx] = CellViewFactory.mkObserver (_cell, impl)
}
deferTx(res.guiInit())
res
}
def optional[S <: Sys[S]](_cell: CellView[S#Tx, Option[Double]], name: String, width: Int, default0: Option[Double])
(implicit tx: S#Tx, cursor: stm.Cursor[S],
undoManager: UndoManager): DoubleSpinnerView.Optional[S] = {
val res: OptionalImpl[S] = new OptionalImpl[S](maxWidth = width) {
impl =>
protected var (value, committer) = CellViewFactory.mkCommitter(_cell, name)(tx, cursor)
protected val observer: Disposable[S#Tx] = CellViewFactory.mkObserver (_cell, impl)
// private val defaultRef = Ref(Option.empty[S#Tx => Double])
private var _default = default0
// def default(implicit tx: S#Tx): Option[S#Tx => Double] = defaultRef.get(tx.peer)
def default: Option[Double] = {
requireEDT()
_default
}
// def default_=(option: Option[S#Tx => Double])(implicit tx: S#Tx): Unit =
// defaultRef.set(option)(tx.peer)
def default_=(value: Option[Double]): Unit = {
requireEDT()
_default = value
if (this.value.isEmpty) {
component.peer.getEditor match {
case editor: JSpinner.DefaultEditor =>
editor.getTextField.setValue(editor.getSpinner.getValue)
case _ =>
}
}
}
// protected def defaultValue: Option[Double] = defaultRef.single.get.fol
}
deferTx(res.guiInit())
res
}
private abstract class Impl[S <: Sys[S]](maxWidth: Int)
(implicit cursor: stm.Cursor[S], undoManager: UndoManager)
extends DefinedNumberSpinnerViewImpl[S, Double](maxWidth) with DoubleSpinnerView[S] {
override type C = Spinner
// final protected val tpe = expr.Double
final protected def parseModelValue(v: Any): Option[Double] = v match {
case i: Double => Some(i)
case _ => None
}
// do away with idiotic grouping and increase max fraction digits
override protected def mkSpinner: Spinner = {
val sp = super.mkSpinner
sp.peer.getEditor match {
case ed: JSpinner.NumberEditor =>
val fmt = ed.getFormat
fmt.setMaximumFractionDigits(5)
fmt.setGroupingUsed(false)
ed.getTextField.setText(fmt.format(sp.value))
case _ =>
}
sp
}
protected lazy val model: SpinnerNumberModel = new SpinnerNumberModel(value, Double.MinValue, Double.MaxValue, 0.1)
}
private abstract class OptionalImpl[S <: Sys[S]](maxWidth: Int)
(implicit cursor: stm.Cursor[S], undoManager: UndoManager)
extends OptionalNumberSpinnerViewImpl[S, Double](maxWidth, false) with DoubleSpinnerView.Optional[S] {
override type C = Spinner
final protected def parseModelValue(v: Any): Option[Option[Double]] = v match {
case Some(d: Double) => Some(Some(d))
case None => Some(None)
case _ => None
}
final protected def valueToComponent(): Unit =
if (parseModelValue(component.value) != Some(value)) {
component.value = value // .getOrElse(Double.NaN)
// component.foreground = if (value.isDefined) null else Color.gray
}
protected lazy val model = new NumericOptionSpinnerModel[Double](value0 = value,
minimum0 = Some(Double.MinValue), maximum0 = Some(Double.MaxValue), stepSize0 = 0.1)
}
}