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.

134 lines
4.4 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.implicits.FontIcon
  6. import nova.monadic_sfx.implicits.IconLiteral
  7. import nova.monadic_sfx.implicits.JFXButton
  8. import nova.monadic_sfx.implicits.JFXListView
  9. import nova.monadic_sfx.implicits.JFXTextField
  10. import nova.monadic_sfx.implicits.JavaFXMonixObservables._
  11. import nova.monadic_sfx.implicits.MenuItem
  12. import nova.monadic_sfx.util.reactive._
  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.Node
  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. object TodoListView {
  25. def apply(
  26. store: MonixProSubject[
  27. TodoListStore.Action,
  28. (TodoListStore.Action, TodoListStore.State)
  29. ]
  30. ): Task[Node] =
  31. Task.deferAction(implicit s =>
  32. Task {
  33. val cc = CompositeCancelable()
  34. val todos =
  35. store.map { case (_, state) => state.todos }
  36. // Todo(-1, "").some
  37. val _selectedItems = ObjectProperty(Seq.empty[Todo])
  38. new HBox {
  39. padding = Insets(5)
  40. val _content = StringProperty("")
  41. children = Seq(
  42. new JFXTextField {
  43. text ==> _content
  44. },
  45. new JFXListView[Todo] {
  46. def selectedItems = selectionModel().selectedItems.view
  47. selectionModel().selectionMode = SelectionMode.Multiple
  48. selectionModel().selectedItems.observableSeqValue ==> _selectedItems
  49. cc += items <-- todos
  50. val emptyCell = ObjectProperty(new HBox)
  51. cellFactory = _ =>
  52. new ListCell[Todo] {
  53. val _text = StringProperty("")
  54. val _graphic = ObjectProperty(
  55. new HBox {
  56. children = Seq(
  57. new FontIcon {
  58. iconSize = 10
  59. iconLiteral = IconLiteral.Gmi10k
  60. },
  61. new Text {
  62. text <== _text
  63. }
  64. )
  65. }
  66. )
  67. item.asOption.map(
  68. _.fold("")(todo => s"${todo.id} - ${todo.content}")
  69. ) ==> _text
  70. graphic <== item.asOption.flatMap(
  71. _.fold(emptyCell)(_ => _graphic)
  72. )
  73. }
  74. contextMenu = new ContextMenu {
  75. items ++= Seq(
  76. new MenuItem {
  77. text = "Add"
  78. // obsAction.useLazyEval(TodoListStore.Add("blah3")) --> store
  79. },
  80. new MenuItem {
  81. text = "Delete"
  82. obsAction.useIterableEval(_ =>
  83. selectedItems
  84. .map(todo => TodoListStore.Delete(todo.id))
  85. .toList
  86. ) --> store
  87. // obsAction.split(
  88. // _.useLazyEval(me.Task(TodoListStore.Delete(0))) --> store,
  89. // _.useLazyEval(me.Task(TodoListStore.Delete(0))) --> store,
  90. // _.useLazyEval(me.Task(TodoListStore.Delete(0))) --> store
  91. // )
  92. },
  93. new MenuItem {
  94. text = "Edit"
  95. }
  96. )
  97. }
  98. },
  99. new JFXButton {
  100. text = "Add"
  101. // disable <== _selectedItems.map(_.length > 0)
  102. obsAction
  103. .useLazyEval(me.Task(TodoListStore.Add(_content()))) --> store
  104. },
  105. new JFXButton {
  106. text = "Edit"
  107. disable <== _selectedItems.map(_.length > 1)
  108. obsAction.useLazyEval(
  109. me.Task(
  110. TodoListStore.Edit(
  111. _selectedItems
  112. .map(_.headOption.map(_.id).getOrElse(-1))
  113. .value,
  114. _content()
  115. )
  116. )
  117. ) --> store
  118. }
  119. )
  120. }
  121. }
  122. )
  123. }