Used MutHistory to implement forward/backward
router buttons
This commit is contained in:
parent
d18c884168
commit
5b50f161d2
@ -4,6 +4,7 @@ import java.util.concurrent.TimeUnit
|
||||
|
||||
import scala.util.Random
|
||||
|
||||
import com.jfoenix.controls.JFXDialog
|
||||
import com.softwaremill.macwire._
|
||||
import io.odin.Logger
|
||||
import monix.bio.IO
|
||||
@ -11,14 +12,16 @@ import monix.bio.Task
|
||||
import monix.eval.Coeval
|
||||
import monix.{eval => me}
|
||||
import nova.monadic_sfx.executors.Schedulers
|
||||
import nova.monadic_sfx.util.controls.JFXButton
|
||||
import nova.monadic_sfx.implicits._
|
||||
import nova.monadic_sfx.ui.MyFxApp
|
||||
import nova.monadic_sfx.ui.components.router.FXRouter
|
||||
import nova.monadic_sfx.ui.components.router.Page
|
||||
import nova.monadic_sfx.ui.components.todo.TodoListStore
|
||||
import nova.monadic_sfx.ui.components.todo.TodoListView
|
||||
import nova.monadic_sfx.util.MutHistory
|
||||
import nova.monadic_sfx.util.controls.JFXButton
|
||||
import org.gerweck.scalafx.util._
|
||||
import org.kordamp.bootstrapfx.BootstrapFX
|
||||
import scalafx.Includes._
|
||||
import scalafx.application.JFXApp.PrimaryStage
|
||||
import scalafx.beans.property.ObjectProperty
|
||||
@ -32,9 +35,9 @@ import scalafx.scene.control.Label
|
||||
import scalafx.scene.control.TableColumn
|
||||
import scalafx.scene.control.TableView
|
||||
import scalafx.scene.layout.BorderPane
|
||||
import scalafx.scene.layout.FlowPane
|
||||
import scalafx.scene.layout.HBox
|
||||
import scalafx.scene.layout.Priority
|
||||
import scalafx.scene.layout.StackPane
|
||||
|
||||
class MainApp(
|
||||
// spawnProtocol: ActorSystem[SpawnProtocol.Command],
|
||||
@ -45,6 +48,12 @@ class MainApp(
|
||||
private lazy val _scene = new Scene {
|
||||
root = new HBox {
|
||||
padding = Insets(20)
|
||||
// style = """| -fx-background-color: rgb(38, 38, 38);
|
||||
// | -fx-text-fill: white;""".stripMargin
|
||||
stylesheets ++= Seq(
|
||||
BootstrapFX.bootstrapFXStylesheet,
|
||||
os.rel / "static" / "css" / "main.css"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,6 +62,7 @@ class MainApp(
|
||||
scene = _scene
|
||||
width = 640
|
||||
height = 480
|
||||
// resizable = false
|
||||
}
|
||||
|
||||
val program = for {
|
||||
@ -61,10 +71,12 @@ class MainApp(
|
||||
wire[MainAppDelegate].init
|
||||
.flatMap(mainSceneNode => Task(_scene.getChildren += mainSceneNode))
|
||||
.executeOn(schedulers.fx)
|
||||
_ <- Task(stage.resizable = false).executeOn(schedulers.fx)
|
||||
currentTime <- IO.clock.realTime(TimeUnit.MILLISECONDS)
|
||||
_ <- logger.info(
|
||||
s"Application started in ${(currentTime - startTime) / 1000f} seconds"
|
||||
)
|
||||
// _ <- Task(CSSFX.start(stage))
|
||||
_ <- fxAppFib.join
|
||||
} yield ()
|
||||
|
||||
@ -81,30 +93,39 @@ class MainAppDelegate(schedulers: Schedulers)(implicit logger: Logger[Task]) {
|
||||
val init =
|
||||
for {
|
||||
//FXRouter does not allocate mutable state so it's ok to use pure here
|
||||
router <- Task.pure(new FXRouter[Page])
|
||||
history <- Task(new MutHistory[Page](Page.Home))
|
||||
router <- Task.pure(new FXRouter[Page](history))
|
||||
routerStore <- router.store(Page.Home, logger)
|
||||
todoStore <- TodoListStore(logger)
|
||||
todoComponent <- TodoListView(todoStore)
|
||||
resolver: PartialFunction[Page, Task[Parent]] = {
|
||||
case Page.Home =>
|
||||
Task(new Label {
|
||||
styleClass ++= Seq("text-white")
|
||||
text = "HomePage"
|
||||
})
|
||||
case Page.UserHome(id0) =>
|
||||
Task(new Label {
|
||||
styleClass ++= Seq("text-white")
|
||||
text = s"User Home, Id = $id0"
|
||||
})
|
||||
case Page.Todo =>
|
||||
Task(todoComponent)
|
||||
Task.pure(todoComponent)
|
||||
}
|
||||
routerNode <-
|
||||
Task
|
||||
.deferAction(implicit s =>
|
||||
Task(new HBox {
|
||||
alignment = Pos.Center
|
||||
//TODO find a better way to do this
|
||||
var oldValue: Option[Parent] = None
|
||||
children <-- router
|
||||
.render(resolver)(routerStore)
|
||||
// .scanEvalF[Coeval, (Option[Parent], Option[Parent])](
|
||||
// Coeval.pure(None -> None)
|
||||
// ) {
|
||||
// case (oldValue, newValue) => Coeval(None -> None)
|
||||
// }
|
||||
// call cancel on the old component to cancel all subscriptions
|
||||
.doOnNextF(newValue =>
|
||||
Coeval { oldValue.foreach(_ => ()) } >> Coeval {
|
||||
@ -116,14 +137,41 @@ class MainAppDelegate(schedulers: Schedulers)(implicit logger: Logger[Task]) {
|
||||
)
|
||||
|
||||
mainSceneNode <- Task.deferAction(implicit s =>
|
||||
Task(new BorderPane {
|
||||
Task(new StackPane { root =>
|
||||
hgrow = Priority.Always
|
||||
vgrow = Priority.Always
|
||||
children = new BorderPane {
|
||||
hgrow = Priority.Always
|
||||
vgrow = Priority.Always
|
||||
center = routerNode
|
||||
bottom = new FlowPane {
|
||||
bottom = new HBox {
|
||||
alignment = Pos.Center
|
||||
hgap = 20
|
||||
spacing = 20
|
||||
children = Seq(
|
||||
new JFXButton {
|
||||
text = "Forward"
|
||||
style = buttonStyle
|
||||
onAction = () => {
|
||||
history.forward()
|
||||
routerStore.onNext(FXRouter.HistoryEvent(history.current))
|
||||
}
|
||||
},
|
||||
new JFXButton {
|
||||
text = "Backward"
|
||||
style = buttonStyle
|
||||
onAction = () => {
|
||||
history.backward()
|
||||
routerStore.onNext(FXRouter.HistoryEvent(history.current))
|
||||
}
|
||||
},
|
||||
new JFXButton {
|
||||
text = "Home"
|
||||
style = buttonStyle
|
||||
obsAction
|
||||
.useLazyEval(
|
||||
me.Task.pure(FXRouter.Replace(Page.Home))
|
||||
) --> routerStore
|
||||
},
|
||||
new JFXButton {
|
||||
text = "Todo"
|
||||
style = buttonStyle
|
||||
@ -137,11 +185,25 @@ class MainAppDelegate(schedulers: Schedulers)(implicit logger: Logger[Task]) {
|
||||
style = buttonStyle
|
||||
obsAction
|
||||
.useLazyEval(
|
||||
me.Task(FXRouter.Replace(Page.UserHome(Random.nextInt(20))))
|
||||
me.Task(
|
||||
FXRouter.Replace(Page.UserHome(Random.nextInt(20)))
|
||||
)
|
||||
) --> routerStore
|
||||
},
|
||||
new JFXButton {
|
||||
text = "Dialog"
|
||||
style = buttonStyle
|
||||
val d = new JFXDialog()
|
||||
d.setContent(new HBox {
|
||||
children = Seq(new Label("hmm"))
|
||||
padding = Insets(20)
|
||||
})
|
||||
d.styleClass ++= Seq("text-white")
|
||||
onAction = () => d.show(root)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
} yield mainSceneNode
|
||||
|
@ -5,10 +5,10 @@ import java.time.LocalDateTime
|
||||
import io.circe.Encoder
|
||||
import io.odin.Logger
|
||||
import monix.bio.Task
|
||||
import monix.reactive.OverflowStrategy
|
||||
import monix.reactive.subjects.ConcurrentSubject
|
||||
import monix.eval.Coeval
|
||||
import monix.reactive.Observable
|
||||
import monix.reactive.OverflowStrategy
|
||||
import monix.reactive.subjects.ConcurrentSubject
|
||||
|
||||
object Store {
|
||||
def createL[A, M](
|
||||
|
Loading…
Reference in New Issue
Block a user