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.
163 lines
5.6 KiB
163 lines
5.6 KiB
package nova.monadic_sfx.ui.components.todo
|
|
|
|
import monix.bio.Task
|
|
import monix.eval.Coeval
|
|
import monix.execution.cancelables.CompositeCancelable
|
|
import monix.{eval => me}
|
|
import nova.monadic_sfx.implicits._
|
|
import nova.monadic_sfx.util.controls.FontIcon
|
|
import nova.monadic_sfx.util.controls.IconLiteral
|
|
import nova.monadic_sfx.util.controls.JFXButton
|
|
import nova.monadic_sfx.util.controls.JFXListView
|
|
import nova.monadic_sfx.util.controls.JFXTextField
|
|
import nova.monadic_sfx.util.controls.MenuItem
|
|
import nova.monadic_sfx.util.reactive.store._
|
|
import org.gerweck.scalafx.util._
|
|
import scalafx.Includes._
|
|
import scalafx.beans.property.ObjectProperty
|
|
import scalafx.beans.property.StringProperty
|
|
import scalafx.collections.ObservableBuffer
|
|
import scalafx.geometry.Insets
|
|
import scalafx.geometry.Pos
|
|
import scalafx.scene.Parent
|
|
import scalafx.scene.control.ContextMenu
|
|
import scalafx.scene.control.Label
|
|
import scalafx.scene.control.ListCell
|
|
import scalafx.scene.control.SelectionMode
|
|
import scalafx.scene.layout.BorderPane
|
|
import scalafx.scene.layout.HBox
|
|
import scalafx.scene.layout.Priority
|
|
import scalafx.scene.paint.Color
|
|
|
|
object TodoListView {
|
|
def apply(
|
|
store: Store[TodoListStore.Action, TodoListStore.State]
|
|
): Task[Parent] =
|
|
Task.deferAction(implicit s =>
|
|
Task {
|
|
implicit val cc = CompositeCancelable()
|
|
val todos = store
|
|
.map { case (_, state) => state.todos }
|
|
.distinctUntilChanged
|
|
.map(ObservableBuffer.from)
|
|
.doOnNextF(item => Coeval(println(s"Received item: $item")))
|
|
val _selectedItems = ObjectProperty(Seq.empty[Todo])
|
|
|
|
new BorderPane {
|
|
padding = Insets(5)
|
|
hgrow = Priority.Always
|
|
val _content = StringProperty("")
|
|
center = new HBox {
|
|
padding = Insets(5)
|
|
children ++= Seq(new JFXListView[Todo] {
|
|
id = "todoList"
|
|
hgrow = Priority.Always
|
|
def selectedItems = selectionModel().selectedItems.view
|
|
styleClass ++= Seq("text-white", "clear-list-view")
|
|
selectionModel().selectionMode = SelectionMode.Multiple
|
|
selectionModel().selectedItems.observableSeqValue ==> _selectedItems
|
|
|
|
items <-- todos.map(_.delegate)
|
|
|
|
val emptyCell = ObjectProperty(new HBox)
|
|
cellFactory = _ =>
|
|
new ListCell[Todo] {
|
|
val _text = StringProperty("")
|
|
val _graphic = ObjectProperty(
|
|
new HBox {
|
|
styleClass ++= Seq("text-white", "strong", "todo-cell")
|
|
children = Seq(
|
|
new FontIcon {
|
|
iconSize = 20
|
|
iconLiteral = IconLiteral.Gmi10k
|
|
fill = Color.White
|
|
},
|
|
new Label {
|
|
style = "-fx-text-fill: white "
|
|
styleClass ++= Seq("text-white", "strong")
|
|
text <== _text
|
|
}
|
|
)
|
|
}
|
|
)
|
|
|
|
item.asOption.map(
|
|
_.fold("")(todo => s"${todo.id} - ${todo.content}")
|
|
) ==> _text
|
|
|
|
graphic <== item.asOption.flatMap(
|
|
_.fold(emptyCell)(_ => _graphic)
|
|
)
|
|
|
|
}
|
|
|
|
contextMenu = new ContextMenu {
|
|
items ++= Seq(
|
|
new MenuItem {
|
|
text = "Delete"
|
|
obsAction.useIterableEval(_ =>
|
|
selectedItems
|
|
.map(todo => TodoListStore.Delete(todo.id))
|
|
.toList
|
|
) --> store
|
|
|
|
// obsAction.split(
|
|
// _.useLazyEval(me.Task(TodoListStore.Delete(0))) --> store,
|
|
// _.useLazyEval(me.Task(TodoListStore.Delete(0))) --> store,
|
|
// _.useLazyEval(me.Task(TodoListStore.Delete(0))) --> store
|
|
// )
|
|
},
|
|
new MenuItem {
|
|
text = "Edit"
|
|
}
|
|
)
|
|
}
|
|
})
|
|
|
|
}
|
|
|
|
bottom = new HBox {
|
|
spacing = 5
|
|
padding = Insets(5)
|
|
children = Seq(
|
|
new JFXTextField {
|
|
id = "todoInputField"
|
|
style = "-fx-background-color: rgb(38,38,38);"
|
|
styleClass += "text-white"
|
|
text ==> _content
|
|
vgrow = Priority.Always
|
|
},
|
|
new JFXButton {
|
|
id = "todoAddButton"
|
|
text = "Add"
|
|
alignment = Pos.Center
|
|
// disable <== _selectedItems.map(_.length > 0)
|
|
styleClass = Seq("btn", "btn-primary")
|
|
obsAction
|
|
.useLazyEval(
|
|
me.Task(TodoListStore.Add(_content()))
|
|
) --> store
|
|
},
|
|
new JFXButton {
|
|
id = "todoEditButton"
|
|
text = "Edit"
|
|
alignment = Pos.Center
|
|
disable <== _selectedItems.map(_.length > 1)
|
|
styleClass = Seq("btn", "btn-info")
|
|
obsAction.useLazyEval(
|
|
me.Task(
|
|
TodoListStore.Edit(
|
|
_selectedItems
|
|
.map(_.headOption.map(_.id).getOrElse(-1))
|
|
.value,
|
|
_content()
|
|
)
|
|
)
|
|
) --> store
|
|
}
|
|
)
|
|
}
|
|
}
|
|
}
|
|
)
|
|
}
|