|
|
@ -1,22 +1,27 @@ |
|
|
|
package nova.monadic_sfx.ui.components.todo |
|
|
|
|
|
|
|
import monix.bio.Task |
|
|
|
import monix.execution.cancelables.CompositeCancelable |
|
|
|
import nova.monadic_sfx.implicits.FontIcon |
|
|
|
import nova.monadic_sfx.implicits.IconLiteral |
|
|
|
import nova.monadic_sfx.implicits.JFXButton |
|
|
|
import nova.monadic_sfx.implicits.JFXListView |
|
|
|
import nova.monadic_sfx.implicits.JFXTextField |
|
|
|
import nova.monadic_sfx.implicits.JavaFXMonixObservables._ |
|
|
|
import nova.monadic_sfx.implicits.MenuItem |
|
|
|
import nova.monadic_sfx.util.reactive._ |
|
|
|
import org.gerweck.scalafx.util._ |
|
|
|
import scalafx.Includes._ |
|
|
|
import scalafx.beans.property.ObjectProperty |
|
|
|
import scalafx.beans.property.StringProperty |
|
|
|
import scalafx.geometry.Insets |
|
|
|
import scalafx.scene.Node |
|
|
|
import scalafx.scene.control.ContextMenu |
|
|
|
import scalafx.scene.control.ListCell |
|
|
|
import scalafx.scene.control.SelectionMode |
|
|
|
import scalafx.scene.layout.HBox |
|
|
|
import scalafx.scene.text.Text |
|
|
|
import nova.monadic_sfx.util.reactive._ |
|
|
|
import org.gerweck.scalafx.util._ |
|
|
|
import scalafx.beans.property.ObjectProperty |
|
|
|
import nova.monadic_sfx.implicits.MenuItem |
|
|
|
import monix.execution.cancelables.CompositeCancelable |
|
|
|
import monix.{eval => me} |
|
|
|
|
|
|
|
object TodoListView { |
|
|
|
def apply( |
|
|
@ -24,67 +29,99 @@ object TodoListView { |
|
|
|
TodoListStore.Command, |
|
|
|
(TodoListStore.Command, TodoListStore.State) |
|
|
|
] |
|
|
|
): Task[JFXListView[Todo]] = |
|
|
|
): Task[Node] = |
|
|
|
Task.deferAction(implicit s => |
|
|
|
Task { |
|
|
|
val cc = CompositeCancelable() |
|
|
|
val todos = |
|
|
|
store.map { case (_, state) => state.todos } |
|
|
|
// Todo(-1, "").some |
|
|
|
val _selectedItems = ObjectProperty(Seq.empty[Todo]) |
|
|
|
|
|
|
|
new JFXListView[Todo] { |
|
|
|
def selectedItems = selectionModel().selectedItems.view |
|
|
|
new HBox { |
|
|
|
padding = Insets(5) |
|
|
|
val _content = StringProperty("") |
|
|
|
children = Seq( |
|
|
|
new JFXTextField { |
|
|
|
text ==> _content |
|
|
|
}, |
|
|
|
new JFXListView[Todo] { |
|
|
|
def selectedItems = selectionModel().selectedItems.view |
|
|
|
|
|
|
|
cc += items <-- todos |
|
|
|
cc += items <-- todos |
|
|
|
|
|
|
|
val emptyCell = ObjectProperty(new HBox) |
|
|
|
cellFactory = _ => |
|
|
|
new ListCell[Todo] { |
|
|
|
val _text = StringProperty("") |
|
|
|
val _graphic = ObjectProperty( |
|
|
|
new HBox { |
|
|
|
children = Seq( |
|
|
|
new FontIcon { |
|
|
|
iconSize = 10 |
|
|
|
iconLiteral = IconLiteral.Gmi10k |
|
|
|
}, |
|
|
|
new Text { |
|
|
|
text <== _text |
|
|
|
val emptyCell = ObjectProperty(new HBox) |
|
|
|
cellFactory = _ => |
|
|
|
new ListCell[Todo] { |
|
|
|
val _text = StringProperty("") |
|
|
|
val _graphic = ObjectProperty( |
|
|
|
new HBox { |
|
|
|
children = Seq( |
|
|
|
new FontIcon { |
|
|
|
iconSize = 10 |
|
|
|
iconLiteral = IconLiteral.Gmi10k |
|
|
|
}, |
|
|
|
new Text { |
|
|
|
text <== _text |
|
|
|
} |
|
|
|
) |
|
|
|
} |
|
|
|
) |
|
|
|
} |
|
|
|
) |
|
|
|
|
|
|
|
item.asOption.map( |
|
|
|
_.fold("")(todo => s"${todo.id} - ${todo.content}") |
|
|
|
) --> _text |
|
|
|
item.asOption.map( |
|
|
|
_.fold("")(todo => s"${todo.id} - ${todo.content}") |
|
|
|
) ==> _text |
|
|
|
|
|
|
|
graphic <== item.asOption.flatMap( |
|
|
|
_.fold(emptyCell)(_ => _graphic) |
|
|
|
) |
|
|
|
graphic <== item.asOption.flatMap( |
|
|
|
_.fold(emptyCell)(_ => _graphic) |
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
selectionModel().selectionMode = SelectionMode.Multiple |
|
|
|
selectionModel().selectionMode = SelectionMode.Multiple |
|
|
|
selectionModel().selectedItems.observableSeqValue ==> _selectedItems |
|
|
|
|
|
|
|
contextMenu = new ContextMenu { |
|
|
|
items ++= Seq( |
|
|
|
new MenuItem { |
|
|
|
text = "Add" |
|
|
|
obsAction.useLazy(TodoListStore.Add("blah3")) --> store |
|
|
|
}, |
|
|
|
new MenuItem { |
|
|
|
text = "Delete" |
|
|
|
obsAction.useIterable(_ => |
|
|
|
selectedItems |
|
|
|
.map(todo => TodoListStore.Delete(todo.id)) |
|
|
|
.toList |
|
|
|
) --> store |
|
|
|
}, |
|
|
|
new MenuItem { |
|
|
|
text = "Edit" |
|
|
|
contextMenu = new ContextMenu { |
|
|
|
items ++= Seq( |
|
|
|
new MenuItem { |
|
|
|
text = "Add" |
|
|
|
// obsAction.useLazyEval(TodoListStore.Add("blah3")) --> store |
|
|
|
}, |
|
|
|
new MenuItem { |
|
|
|
text = "Delete" |
|
|
|
obsAction.useIterableEval(_ => |
|
|
|
selectedItems |
|
|
|
.map(todo => TodoListStore.Delete(todo.id)) |
|
|
|
.toList |
|
|
|
) --> store |
|
|
|
}, |
|
|
|
new MenuItem { |
|
|
|
text = "Edit" |
|
|
|
} |
|
|
|
) |
|
|
|
} |
|
|
|
) |
|
|
|
} |
|
|
|
}, |
|
|
|
new JFXButton { |
|
|
|
text = "Add" |
|
|
|
disable <== _selectedItems.map(_.length > 0) |
|
|
|
obsAction |
|
|
|
.useLazyEval(me.Task(TodoListStore.Add(_content()))) --> store |
|
|
|
}, |
|
|
|
new JFXButton { |
|
|
|
text = "Edit" |
|
|
|
disable <== _selectedItems.map(_.length > 1) |
|
|
|
obsAction.useLazyEval( |
|
|
|
me.Task( |
|
|
|
TodoListStore.Edit( |
|
|
|
_selectedItems |
|
|
|
.map(_.headOption.map(_.id).getOrElse(-1)) |
|
|
|
.value, |
|
|
|
_content() |
|
|
|
) |
|
|
|
) |
|
|
|
) --> store |
|
|
|
} |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
) |
|
|
|