diff --git a/numass-control/control-room/src/main/kotlin/inr/numass/control/BoardController.kt b/numass-control/control-room/src/main/kotlin/inr/numass/control/BoardController.kt index 5b3f9706..adc976cf 100644 --- a/numass-control/control-room/src/main/kotlin/inr/numass/control/BoardController.kt +++ b/numass-control/control-room/src/main/kotlin/inr/numass/control/BoardController.kt @@ -13,14 +13,11 @@ import javafx.beans.property.SimpleObjectProperty import javafx.collections.FXCollections import javafx.collections.ObservableList import tornadofx.* -import java.util.* /** * Created by darksnake on 12-May-17. */ class BoardController() : Controller() { - private val serviceLoader = ServiceLoader.load(DeviceViewFactory::class.java); - val devices: ObservableList> = FXCollections.observableArrayList>(); val storageProperty = SimpleObjectProperty() @@ -41,7 +38,7 @@ class BoardController() : Controller() { } } - if(meta.hasMeta("storage")){ + if (meta.hasMeta("storage")) { storage = buildStorage(context, meta); val storageConnection = StorageConnection(storage); devices.forEach { @@ -61,12 +58,13 @@ class BoardController() : Controller() { private fun buildDeviceView(context: Context, deviceMeta: Meta): DeviceViewConnection<*> { context.logger.info("Building device with meta: {}", deviceMeta) - val factory = serviceLoader.find { - it.type == deviceMeta.getString("type") - }; - if (factory != null) { - val device = factory.build(context, deviceMeta); - val view = factory.buildView(device); + val factory = context.serviceStream(DeviceViewFactory::class.java) + .filter { it.type == deviceMeta.getString("type") } + .findFirst(); + + if (factory.isPresent) { + val device = factory.get().build(context, deviceMeta); + val view = factory.get().buildView(device); device.connect(view, Roles.VIEW_ROLE, Roles.DEVICE_LISTENER_ROLE) device.init(); return view; @@ -76,7 +74,10 @@ class BoardController() : Controller() { } private fun buildStorage(context: Context, meta: Meta): Storage { - val storageMeta = meta.getMeta("storage"); + val storageMeta = meta.getMeta("storage").builder + .putValue("readOnly", false) + .putValue("monitor", true) + context.logger.info("Creating storage for server with meta {}", storageMeta) var storage = StorageFactory.buildStorage(context, storageMeta); diff --git a/numass-control/control-room/src/main/kotlin/inr/numass/control/BoardView.kt b/numass-control/control-room/src/main/kotlin/inr/numass/control/BoardView.kt index ef6860c2..470d2648 100644 --- a/numass-control/control-room/src/main/kotlin/inr/numass/control/BoardView.kt +++ b/numass-control/control-room/src/main/kotlin/inr/numass/control/BoardView.kt @@ -1,8 +1,10 @@ package inr.numass.control import hep.dataforge.control.devices.Device +import hep.dataforge.control.devices.PortSensor import hep.dataforge.fx.fragments.FXFragment import hep.dataforge.fx.fragments.FragmentWindow +import hep.dataforge.storage.filestorage.FileStorage import inr.numass.control.NumassControlUtils.getDFIcon import javafx.geometry.Orientation import javafx.geometry.Pos @@ -22,63 +24,80 @@ class BoardView : View("Numass control board", ImageView(getDFIcon())) { prefWidth = 200.0 center { vbox { - hbox { - alignment = Pos.CENTER + //Server pane + titledpane(title = "Server", collapsible = false) { vgrow = Priority.ALWAYS; - prefHeight = 40.0 - text("Server") // TODO add fancy style here - separator(Orientation.VERTICAL) - var serverLabel: Hyperlink by singleAssign(); - togglebutton("Start") { - isSelected = false - disableProperty().bind(controller.serverManagerProperty.isNull) - action { - if (isSelected) { - text = "Stop" - controller.serverManager.startServer() - serverLabel.text = controller.serverManager.link; + hbox { + alignment = Pos.CENTER_LEFT + prefHeight = 40.0 + var serverLabel: Hyperlink by singleAssign(); + togglebutton("Start") { + isSelected = false + disableProperty().bind(controller.serverManagerProperty.isNull) + action { + if (isSelected) { + text = "Stop" + controller.serverManager.startServer() + serverLabel.text = controller.serverManager.link; + } else { + text = "Start" + controller.serverManager.stopServer() + serverLabel.text = "" + } + } + } + text("Started: ") { + paddingHorizontal = 5 + } + indicator { + bind(controller.serverManager.isStarted) + } + separator(Orientation.VERTICAL) + text("Address: ") + serverLabel = hyperlink { + action { + hostServices.showDocument(controller.serverManager.link); + } + } + } + } + titledpane(title = "Storage", collapsible = true) { + vgrow = Priority.ALWAYS; + hbox { + alignment = Pos.CENTER_LEFT + prefHeight = 40.0 + label(stringBinding(controller.storage) { + val storage = controller.storage + if (storage is FileStorage) { + "Path: " + storage.dataDir; } else { - text = "Start" - controller.serverManager.stopServer() - serverLabel.text = "" + "Name: " + controller.storage.fullPath } - } - } - indicator { - bind(controller.serverManager.isStarted) - } - serverLabel = hyperlink { - action { - hostServices.showDocument(controller.serverManager.link); - } + }) } } separator(Orientation.HORIZONTAL) - hbox { - alignment = Pos.CENTER + scrollpane(fitToWidth = true, fitToHeight = true) { vgrow = Priority.ALWAYS; - prefHeight = 40.0 - text("Storage") - separator(Orientation.VERTICAL) - label(stringBinding(controller.storage) { - controller.storage.fullPath - }) - } - separator(Orientation.HORIZONTAL) - vbox { - vgrow = Priority.ALWAYS; - prefHeight = 40.0 - bindChildren(controller.devices) { connection -> - hbox { - alignment = Pos.CENTER - vgrow = Priority.ALWAYS; - text("Device: " + connection.device.name) - separator(Orientation.VERTICAL) - indicator { - bind(connection, Device.INITIALIZED_STATE) + vbox { + prefHeight = 40.0 + bindChildren(controller.devices) { connection -> + titledpane(title = "Device: " + connection.device.name, collapsible = true) { + hbox { + alignment = Pos.CENTER_LEFT + vgrow = Priority.ALWAYS; + deviceStateIndicator(connection,Device.INITIALIZED_STATE) + deviceStateIndicator(connection, PortSensor.CONNECTED_STATE) + deviceStateIndicator(connection, "storing") + pane { + hgrow = Priority.ALWAYS + } + togglebutton("View") { + isSelected = false + FragmentWindow(FXFragment.buildFromNode(connection.device.name) { connection.fxNode }).bindTo(this) + } + } } - val viewButton = togglebutton("View") - FragmentWindow(FXFragment.buildFromNode(connection.device.name) { connection.fxNode }).bindTo(viewButton) } } } diff --git a/numass-control/control-room/src/main/kotlin/inr/numass/control/ControlFXExtensions.kt b/numass-control/control-room/src/main/kotlin/inr/numass/control/ControlFXExtensions.kt index 5d71de4c..cae2bd12 100644 --- a/numass-control/control-room/src/main/kotlin/inr/numass/control/ControlFXExtensions.kt +++ b/numass-control/control-room/src/main/kotlin/inr/numass/control/ControlFXExtensions.kt @@ -3,6 +3,7 @@ package inr.numass.control import hep.dataforge.values.Value import javafx.beans.value.ObservableValue import javafx.event.EventTarget +import javafx.geometry.Orientation import javafx.scene.paint.Color import javafx.scene.paint.Paint import javafx.scene.shape.Circle @@ -19,7 +20,6 @@ class Indicator(radius: Double = 10.0) : Circle(radius, Color.GRAY) { init { stroke = Color.BLACK; strokeType = StrokeType.INSIDE; - tooltip { } } /** @@ -30,9 +30,10 @@ class Indicator(radius: Double = 10.0) : Circle(radius, Color.GRAY) { throw RuntimeException("Indicator already bound"); } else { binding = observable; - } - observable.addListener { _, _, value -> - fill = transform(value); + fill = transform(observable.value) + observable.addListener { _, _, value -> + fill = transform(value); + } } } @@ -79,4 +80,17 @@ fun Indicator.bind(connection: DeviceViewConnection<*>, state: String, transform } } } +} + +/** + * State name + indicator + */ +fun EventTarget.deviceStateIndicator(connection: DeviceViewConnection<*>, state: String, transform: ((Value) -> Paint)? = null) { + if (connection.device.hasState(state)) { + text("${state.toUpperCase()}: ") + indicator { + bind(connection, state, transform); + } + separator(Orientation.VERTICAL) + } } \ No newline at end of file diff --git a/numass-control/control-room/src/main/kotlin/inr/numass/control/ServerApp.kt b/numass-control/control-room/src/main/kotlin/inr/numass/control/ServerApp.kt index e44c4cbf..8127e20d 100644 --- a/numass-control/control-room/src/main/kotlin/inr/numass/control/ServerApp.kt +++ b/numass-control/control-room/src/main/kotlin/inr/numass/control/ServerApp.kt @@ -1,9 +1,9 @@ package inr.numass.control import hep.dataforge.context.Context -import hep.dataforge.context.Global import javafx.stage.Stage import tornadofx.* +import java.io.File /** * Created by darksnake on 19-May-17. @@ -14,7 +14,11 @@ class ServerApp : App(BoardView::class) { override fun start(stage: Stage) { NumassControlUtils.getConfig(this).ifPresent { - context = Global.getContext("NUMASS-SERVER"); + val libPath = parameters.named.getOrDefault("libPath","../lib"); + context = Context + .builder("NUMASS-SERVER") + .classPath(File(libPath).toURI().toURL()) + .build() controller.load(context, it); } super.start(stage) diff --git a/numass-control/msp/src/main/java/inr/numass/control/msp/fx/MspApp.java b/numass-control/msp/src/main/java/inr/numass/control/msp/fx/MspApp.java index e33cfad3..b923cf09 100644 --- a/numass-control/msp/src/main/java/inr/numass/control/msp/fx/MspApp.java +++ b/numass-control/msp/src/main/java/inr/numass/control/msp/fx/MspApp.java @@ -36,7 +36,7 @@ public class MspApp extends NumassControlApplication { } @Override - protected DeviceFactory getDeviceFactory() { + protected DeviceFactory getDeviceFactory() { return new MspDeviceFactory(); } diff --git a/numass-control/vac/src/main/java/inr/numass/control/readvac/fx/ReadVac.java b/numass-control/vac/src/main/java/inr/numass/control/readvac/fx/ReadVac.java index b607d6bf..3e644562 100644 --- a/numass-control/vac/src/main/java/inr/numass/control/readvac/fx/ReadVac.java +++ b/numass-control/vac/src/main/java/inr/numass/control/readvac/fx/ReadVac.java @@ -25,7 +25,7 @@ public class ReadVac extends NumassControlApplication { } @Override - protected DeviceFactory getDeviceFactory() { + protected DeviceFactory getDeviceFactory() { return new VacDeviceFactory(); } diff --git a/numass-viewer/build.gradle b/numass-viewer/build.gradle index 25e26b31..d74028dd 100644 --- a/numass-viewer/build.gradle +++ b/numass-viewer/build.gradle @@ -27,7 +27,7 @@ dependencies { compile 'org.controlsfx:controlsfx:8.40.12' - compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:'1.1.2-3" + compile "org.jetbrains.kotlin:kotlin-stdlib-jre8" compile "no.tornado:tornadofx:1.7.4" }