From 312f1facf819b798d6d297f59c1fc6d771a91f86 Mon Sep 17 00:00:00 2001 From: Katarzyna Streich Date: Wed, 7 Jun 2017 13:28:29 +0100 Subject: [PATCH] Fix wrong layout of new added nodes to map view in explorer. (#794) * Fix wrong layout of new added nodes to map view in explorer. Fix double rendering of myIdentity label. * Make buttons in map view take the whole available space. * Remove party full name from network map view in explorer. --- .../net/corda/explorer/views/Network.kt | 65 +++++++++++++------ 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt index a72f452a59..79af7868b7 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt @@ -54,16 +54,13 @@ class Network : CordaView() { private val mapOriginalHeight = 2000.0 // UI node observables, declare here to create a strong ref to prevent GC, which removes listener from observables. + private var centralLabel: Label? = null private val notaryComponents = notaries.map { it.render() } private val notaryButtons = notaryComponents.map { it.button } private val peerComponents = peers.map { it.render() } private val peerButtons = peerComponents.filtered { it.nodeInfo != myIdentity.value }.map { it.button } - private val myComponent = myIdentity.map { it?.render() } - private val myButton = myComponent.map { it?.button } - private val myMapLabel = myComponent.map { it?.label } private val allComponents = FXCollections.observableArrayList(notaryComponents, peerComponents).concatenate() private val allComponentMap = allComponents.associateBy { it.nodeInfo.legalIdentity } - private val mapLabels = allComponents.map { it.label } private data class MapViewComponents(val nodeInfo: NodeInfo, val button: Button, val label: Label) @@ -83,9 +80,40 @@ class Network : CordaView() { } } + private fun NodeInfo.renderButton(mapLabel: Label): Button { + val node = this + return button { + useMaxWidth = true + graphic = vbox { + label(PartyNameFormatter.short.format(node.legalIdentity.name)) { font = Font.font(font.family, FontWeight.BOLD, 15.0) } + gridpane { + hgap = 5.0 + vgap = 5.0 + row("Pub Key :") { + copyableLabel(SimpleObjectProperty(node.legalIdentity.owningKey.toBase58String())).apply { minWidth = 400.0 } + } + row("Services :") { label(node.advertisedServices.map { it.info }.joinToString(", ")) } + node.physicalLocation?.apply { row("Location :") { label(this@apply.description) } } + } + } + setOnMouseClicked { + centralLabel = mapLabel + mapScrollPane.centerLabel(mapLabel) + } + } + } + private fun NodeInfo.render(): MapViewComponents { val node = this - val mapLabel = label(PartyNameFormatter.short.format(node.legalIdentity.name)) { + val mapLabel = label(PartyNameFormatter.short.format(node.legalIdentity.name)) + mapPane.add(mapLabel) + // applyCss: This method does not normally need to be invoked directly but may be used in conjunction with Parent.layout() + // to size a Node before the next pulse, or if the Scene is not in a Stage. + // It's needed to properly add node label to the map (before that width and height are 0 which results in wrong placement of + // nodes rendered after initial map rendering). + mapPane.applyCss() + mapPane.layout() + mapLabel.apply { graphic = FontAwesomeIconView(FontAwesomeIcon.DOT_CIRCLE_ALT) contentDisplay = ContentDisplay.TOP val coordinate = Bindings.createObjectBinding({ @@ -97,33 +125,28 @@ class Network : CordaView() { layoutYProperty().bind(coordinate.map { it.second - height / 4 }) } - val button = button { - graphic = vbox { - label(PartyNameFormatter.short.format(node.legalIdentity.name)) { font = Font.font(font.family, FontWeight.BOLD, 15.0) } - gridpane { - hgap = 5.0 - vgap = 5.0 - row("Full name :") { label(PartyNameFormatter.full.format(node.legalIdentity.name)) } - row("Pub Key :") { copyableLabel(SimpleObjectProperty(node.legalIdentity.owningKey.toBase58String())) } - row("Services :") { label(node.advertisedServices.map { it.info }.joinToString(", ")) } - node.physicalLocation?.apply { row("Location :") { label(this@apply.description) } } - } - } - setOnMouseClicked { mapScrollPane.centerLabel(mapLabel) } + val button = node.renderButton(mapLabel) + if (node == myIdentity.value) { + // It has to be a copy if we want to have notary both in notaries list and in identity (if we are looking at that particular notary node). + myIdentityPane.apply { center = node.renderButton(mapLabel) } + centralLabel = mapLabel } return MapViewComponents(this, button, mapLabel) } init { - myIdentityPane.centerProperty().bind(myButton) Bindings.bindContent(notaryList.children, notaryButtons) Bindings.bindContent(peerList.children, peerButtons) - Bindings.bindContent(mapPane.children, mapLabels) // Run once when the screen is ready. // TODO : Find a better way to do this. mapPane.heightProperty().addListener { _, old, _ -> - if (old == 0.0) myMapLabel.value?.let { mapScrollPane.centerLabel(it) } + if (old == 0.0) centralLabel?.let { + mapPane.applyCss() + mapPane.layout() + mapScrollPane.centerLabel(it) + } } + // Listen on zooming gesture, if device has gesture support. mapPane.setOnZoom { zoom(it.zoomFactor, Point2D(it.x, it.y)) }