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.

159 lines
4.3 KiB

  1. package nova.monadic_sfx
  2. import com.softwaremill.macwire._
  3. import io.odin.Logger
  4. import monix.bio.Task
  5. import monix.catnap.ConcurrentChannel
  6. import nova.monadic_sfx.executors.Schedulers
  7. import nova.monadic_sfx.implicits.JFXButton
  8. import nova.monadic_sfx.implicits.JavaFXMonixObservables._
  9. import nova.monadic_sfx.ui.MyFxApp
  10. import nova.monadic_sfx.ui.components.todo.Todo
  11. import nova.monadic_sfx.ui.components.todo.TodoListComponent
  12. import nova.monadic_sfx.ui.components.todo.TodoListView
  13. import nova.monadic_sfx.util.IOUtils._
  14. import org.gerweck.scalafx.util._
  15. import scalafx.Includes._
  16. import scalafx.application.JFXApp.PrimaryStage
  17. import scalafx.beans.property.ObjectProperty
  18. import scalafx.beans.property.StringProperty
  19. import scalafx.collections.ObservableBuffer
  20. import scalafx.geometry.Insets
  21. import scalafx.scene.Scene
  22. import scalafx.scene.control.TableColumn
  23. import scalafx.scene.control.TableView
  24. import scalafx.scene.layout.HBox
  25. import scalafx.scene.paint.Color
  26. import scalafx.scene.shape.Rectangle
  27. class MainApp(
  28. // spawnProtocol: ActorSystem[SpawnProtocol.Command],
  29. schedulers: Schedulers,
  30. startTime: Long
  31. )(implicit logger: Logger[Task]) {
  32. lazy val addTodoButton = new JFXButton {
  33. text = "Add"
  34. }
  35. lazy val addTodoObs = addTodoButton.observableAction()
  36. lazy val todoListView = TodoListView.defaultListView
  37. lazy val _scene = new Scene {
  38. root = new HBox {
  39. padding = Insets(20)
  40. content = new Rectangle {
  41. width = 400
  42. height = 200
  43. fill = Color.DeepSkyBlue
  44. }
  45. children ++= Seq(
  46. new JFXButton {
  47. text = "DummyButton"
  48. },
  49. new JFXButton {
  50. text = "DummyButton2"
  51. },
  52. addTodoButton,
  53. Test.ttv
  54. // todoListView
  55. )
  56. }
  57. }
  58. private lazy val stage = new PrimaryStage {
  59. title = "Simple ScalaFX App"
  60. scene = _scene
  61. width = 800
  62. height = 400
  63. }
  64. // implicit val l = logger
  65. // implicit val sp = spawnProtocol
  66. val program = for {
  67. (fxApp, fxAppFib) <- wire[MyFxApp].init(stage)
  68. // _ <- Task(fxApp.stage = stage)
  69. // .executeOn(schedulers.fx)
  70. // .delayExecution(2000.millis)
  71. todoComponent <- createTodoComponent
  72. _ <- toIO(
  73. addTodoObs
  74. .mapEval(_ =>
  75. toTask(todoComponent.send(TodoListComponent.Add(Todo(1, "blah"))))
  76. )
  77. .completedL
  78. .executeOn(schedulers.fx)
  79. .startAndForget
  80. )
  81. _ <- logger.info(
  82. s"Application started in ${(System.currentTimeMillis() - startTime) / 1000f} seconds"
  83. )
  84. _ <- fxAppFib.join
  85. } yield ()
  86. def createTodoComponent: Task[TodoListComponent] = {
  87. for {
  88. channel <-
  89. ConcurrentChannel
  90. .of[Task, TodoListComponent.Complete, TodoListComponent.Command]
  91. scheduler = schedulers.fx
  92. (lv, delObs, editObs) <-
  93. TodoListView.defaultListView2.executeOn(scheduler)
  94. todoLV = new TodoListView(lv)
  95. todoComponent <- wire[TodoListComponent.Props].create
  96. // TODO make this a "message pass" instead of mutating directly
  97. _ <- Task(_scene.getChildren += lv).executeOn(scheduler)
  98. _ <- toIO(
  99. delObs
  100. .doOnNext(_ => toTask(logger.debug("Pressed delete")))
  101. .doOnNext(todo =>
  102. toTask(
  103. for {
  104. _ <- logger.debug(s"Got todo $todo")
  105. _ <- todoComponent.send(TodoListComponent.Delete(todo.id))
  106. // _ <- Task.sequence(
  107. // lst.map(todo =>
  108. // todoComponent.send(TodoListComponent.Delete(todo.id))
  109. // )
  110. // )
  111. } yield ()
  112. )
  113. )
  114. .completedL
  115. ).startAndForget
  116. _ <- toIO(
  117. editObs
  118. .doOnNext(_ => toTask(logger.debug("Pressed edit")))
  119. .completedL
  120. ).startAndForget
  121. } yield todoComponent
  122. }
  123. }
  124. class TestModel(_name: String, _age: Int) {
  125. val name = StringProperty(_name).readOnly
  126. val age = ObjectProperty(_age).readOnly
  127. }
  128. object Test {
  129. val items = ObservableBuffer(
  130. new TestModel("hmm", 1),
  131. new TestModel("hmm2", 2)
  132. )
  133. val ttv = new TableView[TestModel](items) {
  134. columns ++= Seq(
  135. new TableColumn[TestModel, String] {
  136. text = "Name"
  137. cellValueFactory = { _.value.name }
  138. },
  139. new TableColumn[TestModel, Int] {
  140. text = "Age"
  141. cellValueFactory = { _.value.age }
  142. }
  143. )
  144. }
  145. }