All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.sciss.mellite.impl.timeline.TimelineFrameImpl.scala Maven / Gradle / Ivy

/*
 *  TimelineFrameImpl.scala
 *  (Mellite)
 *
 *  Copyright (c) 2012-2023 Hanns Holger Rutz. All rights reserved.
 *
 *  This software is published under the GNU Affero General Public License v3+
 *
 *
 *  For further information, please contact Hanns Holger Rutz at
 *  [email protected]
 */

package de.sciss.mellite.impl.timeline

import de.sciss.desktop.{Menu, OptionPane, Window}
import de.sciss.lucre.Source
import de.sciss.lucre.edit.UndoManager
import de.sciss.lucre.expr.CellView
import de.sciss.lucre.impl.BiGroupImpl
import de.sciss.lucre.synth.Txn
import de.sciss.mellite.impl.WorkspaceWindowImpl
import de.sciss.mellite.impl.proc.ProcObjView
import de.sciss.mellite.{Application, TimelineFrame, TimelineView, UniverseHandler}
import de.sciss.proc.Timeline

import scala.swing.Action

object TimelineFrameImpl {
  def apply[T <: Txn[T]](obj: Timeline[T])
                        (implicit tx: T, handler: UniverseHandler[T]): TimelineFrame[T] =
    handler(obj, TimelineFrame)(newInstance(obj))

  private def newInstance[T <: Txn[T]](obj: Timeline[T])
                        (implicit tx: T, handler: UniverseHandler[T]): TimelineFrame[T] = {
    implicit val undoMgr: UndoManager[T] = UndoManager()
    val tlv     = TimelineView[T](obj)
    val name    = CellView.name(obj)
    import Timeline.format
    val groupH  = tx.newHandle(obj)
    val res     = new Impl(tlv, groupH)
    res.init().setTitle(name.map(n => s"$n : Timeline"))
    res
  }

  private final class Impl[T <: Txn[T]](val view: TimelineView[T], groupH: Source[T, Timeline[T]])
                                       (implicit val handler: UniverseHandler[T])
    extends TimelineFrame[T] with WorkspaceWindowImpl[T] {

    import view.{cursor => _cursor}

    override def key: Key = TimelineFrame

    override def newWindow()(implicit tx: T): TimelineFrame[T] =
      newInstance(view.obj)

    override protected def initGUI(): Unit = {
      super.initGUI()

      val mf = Application.windowHandler.menuFactory
      val me = Some(window)

      bindMenus(
        "edit.select-all"         -> view.actionSelectAll,
        "edit.delete"             -> view.actionDelete,
        "actions.stop-all-sound"  -> view.actionStopAllSound,
        // "timeline.splitObjects" -> view.splitObjectsAction,

        "actions.debug-print"     -> Action(null) {
          val it = view.selectionModel.iterator
          if (it.hasNext)
            it.foreach {
              case pv: ProcObjView.Timeline[T] =>
                println(pv.debugString)
                println(_cursor.step { implicit tx => pv.obj.toString() })
                println("--- targets ---")
                println(_cursor.step { implicit tx => pv.targets.mkString("\n") })
              case _ =>
            }
          else {
            val (treeS, opt) = _cursor.step { implicit tx =>
              val s1 = groupH().debugPrint
              val s2 = BiGroupImpl.verifyConsistency(groupH(), reportOnly = true)
              (s1, s2)
            }
            if (opt.isEmpty) {
              println("No problems found!")
            } else {
              println(treeS)
              println()
              opt.foreach(println)

              val pane = OptionPane.confirmation(message = "Correct the data structure?",
                optionType = OptionPane.Options.YesNo, messageType = OptionPane.Message.Warning)
              pane.title = "Sanitize Timeline"
              val sel = pane.show(Some(window))
              import de.sciss.equal.Implicits._
              if (sel === OptionPane.Result.Yes) _cursor.step { implicit tx =>
                BiGroupImpl.verifyConsistency(groupH(), reportOnly = false)
              }
            }
          }
        }
      )

      // --- timeline menu ---
      import Menu.{Group, Item}
      val mTimeline = Group("timeline", "Timeline")
        // .add(Item("trimToSelection",    proxy("Trim to Selection",        (menu1 + Key.F5))))
//        .add(Item("insert-span"           , proxy(("Insert Span...",          menu1 + shift + Key.E))))
//        .add(Item("clear-span"            , view.actionClearSpan ))
//        .add(Item("remove-span"           , view.actionRemoveSpan))
//        .add(Item("dup-span-to-pos"       , "Duplicate Span to Cursor"))
//        .addLine()
//        .add(Item("nudge-amount"          , "Nudge Amount..."))
//        .add(Item("nudge-left"            , proxy(("Nudge Objects Backward",  plain + Key.Minus))))
//        .add(Item("nudge-right"           , proxy(("Nudge Objects Forward",   plain + Key.Plus))))
//        .addLine()
        .add(Item("select-following"      , view.actionSelectFollowing))
        .add(Item("align-obj-start-to-pos", view.actionAlignObjectsToCursor))
        .add(Item("split-objects"         , view.actionSplitObjects))
        .add(Item("clean-up-objects"      , view.actionCleanUpObjects))
        .addLine()
//        .add(Item("sel-stop-to-start"     , "Flip Selection Backward"))
//        .add(Item("sel-start-to-stop"     , "Flip Selection Forward"))
//        .addLine()
        .add(Item("drop-marker"           , view.actionDropMarker))
        .add(Item("drop-named-marker"     , view.actionDropNamedMarker))

      window.reactions += {
        case Window.Activated(_) => view.canvas.canvasComponent.requestFocusInWindow()
      }

      mf.add(me, mTimeline)
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy