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.

142 lines
4.8 KiB

  1. package nova.monadic_sfx.ui.components.todo
  2. import monix.bio.Task
  3. import monix.execution.cancelables.CompositeCancelable
  4. import monix.{eval => me}
  5. import nova.monadic_sfx.util.controls.FontIcon
  6. import nova.monadic_sfx.util.controls.IconLiteral
  7. import nova.monadic_sfx.util.controls.JFXButton
  8. import nova.monadic_sfx.util.controls.JFXListView
  9. import nova.monadic_sfx.util.controls.JFXTextField
  10. import nova.monadic_sfx.util.controls.MenuItem
  11. import nova.monadic_sfx.implicits._
  12. import nova.monadic_sfx.util.reactive.store._
  13. import org.gerweck.scalafx.util._
  14. import scalafx.Includes._
  15. import scalafx.beans.property.ObjectProperty
  16. import scalafx.beans.property.StringProperty
  17. import scalafx.geometry.Insets
  18. import scalafx.scene.Parent
  19. import scalafx.scene.control.ContextMenu
  20. import scalafx.scene.control.ListCell
  21. import scalafx.scene.control.SelectionMode
  22. import scalafx.scene.layout.HBox
  23. import scalafx.scene.text.Text
  24. import scalafx.geometry.Pos
  25. import scalafx.scene.layout.BorderPane
  26. import scalafx.scene.layout.Priority
  27. object TodoListView {
  28. def apply(
  29. store: Store[TodoListStore.Action, TodoListStore.State]
  30. ): Task[Parent] =
  31. Task.deferAction(implicit s =>
  32. Task {
  33. val cc = CompositeCancelable()
  34. val todos = store.map { case (_, state) => state.todos }
  35. val _selectedItems = ObjectProperty(Seq.empty[Todo])
  36. new BorderPane {
  37. padding = Insets(5)
  38. val _content = StringProperty("")
  39. center = new HBox {
  40. padding = Insets(5)
  41. children ++= Seq(new JFXListView[Todo] {
  42. hgrow = Priority.Always
  43. def selectedItems = selectionModel().selectedItems.view
  44. styleClass ++= Seq("text-white")
  45. selectionModel().selectionMode = SelectionMode.Multiple
  46. selectionModel().selectedItems.observableSeqValue ==> _selectedItems
  47. cc += items <-- todos
  48. val emptyCell = ObjectProperty(new HBox)
  49. cellFactory = _ =>
  50. new ListCell[Todo] {
  51. val _text = StringProperty("")
  52. val _graphic = ObjectProperty(
  53. new HBox {
  54. children = Seq(
  55. new FontIcon {
  56. iconSize = 10
  57. iconLiteral = IconLiteral.Gmi10k
  58. },
  59. new Text {
  60. text <== _text
  61. }
  62. )
  63. }
  64. )
  65. item.asOption.map(
  66. _.fold("")(todo => s"${todo.id} - ${todo.content}")
  67. ) ==> _text
  68. graphic <== item.asOption.flatMap(
  69. _.fold(emptyCell)(_ => _graphic)
  70. )
  71. }
  72. contextMenu = new ContextMenu {
  73. items ++= Seq(
  74. new MenuItem {
  75. text = "Delete"
  76. obsAction.useIterableEval(_ =>
  77. selectedItems
  78. .map(todo => TodoListStore.Delete(todo.id))
  79. .toList
  80. ) --> store
  81. // obsAction.split(
  82. // _.useLazyEval(me.Task(TodoListStore.Delete(0))) --> store,
  83. // _.useLazyEval(me.Task(TodoListStore.Delete(0))) --> store,
  84. // _.useLazyEval(me.Task(TodoListStore.Delete(0))) --> store
  85. // )
  86. },
  87. new MenuItem {
  88. text = "Edit"
  89. }
  90. )
  91. }
  92. })
  93. }
  94. bottom = new HBox {
  95. spacing = 5
  96. padding = Insets(5)
  97. children = Seq(
  98. new JFXTextField {
  99. text ==> _content
  100. },
  101. new JFXButton {
  102. text = "Add"
  103. alignment = Pos.Center
  104. // disable <== _selectedItems.map(_.length > 0)
  105. styleClass = Seq("btn", "btn-primary")
  106. obsAction
  107. .useLazyEval(me.Task(TodoListStore.Add(_content()))) --> store
  108. },
  109. new JFXButton {
  110. text = "Edit"
  111. alignment = Pos.Center
  112. disable <== _selectedItems.map(_.length > 1)
  113. styleClass = Seq("btn", "btn-info")
  114. style = ""
  115. obsAction.useLazyEval(
  116. me.Task(
  117. TodoListStore.Edit(
  118. _selectedItems
  119. .map(_.headOption.map(_.id).getOrElse(-1))
  120. .value,
  121. _content()
  122. )
  123. )
  124. ) --> store
  125. }
  126. )
  127. }
  128. }
  129. }
  130. )
  131. }