Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added proxy view renderings for bundles #39

Merged
merged 1 commit into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -821,11 +821,12 @@ class OsgiStyles {
* @param inOverview If this bundle is shown in a bundle overview.
* @param hasChildren If this rendering should leave space for a child area.
* @param context The view context used in the synthesis.
* @param isProxy If this is the proxy representation of the bundle.
*
* @return The entire rendering for a bundle.
*/
def KRoundedRectangle addBundleRendering(KNode node, Bundle b, boolean inOverview, boolean hasChildren,
ViewContext context) {
ViewContext context, boolean isProxy) {
node.addRoundedRectangle(ROUNDNESS, ROUNDNESS) => [
addDoubleClickAction(OpenBundleManifestAction::ID)
if (b.isIsExternal) {
Expand All @@ -837,7 +838,7 @@ class OsgiStyles {
addRectangle => [
val interactiveButtons = context.getOptionValue(INTERACTIVE_BUTTONS) as Boolean
var columns = 1
if (interactiveButtons) {
if (interactiveButtons && !isProxy) {
columns += 2
}
setGridPlacement(columns)
Expand All @@ -851,12 +852,20 @@ class OsgiStyles {
if (b.descriptiveName !== null) {
name += b.descriptiveName
}
addSimpleLabel(name) => [
// Shorten the name for proxies and add the long name as a hover tooltip
var shortenedName = name
if (shortenedName.length > 18) {
shortenedName = shortenedName.substring(0, 15) + "..."
}
val kText = addSimpleLabel(isProxy ? shortenedName : name) => [
fontBold = true
selectionFontBold = true
]
if (isProxy && shortenedName != name) {
kText.tooltip = name
}
]
if (interactiveButtons) {
if (interactiveButtons && !isProxy) {
addVerticalLine
if (inOverview) {
addCollapseExpandButton(false, context)
Expand All @@ -865,36 +874,38 @@ class OsgiStyles {
}
}
]
addHorizontalSeperatorLine(1, 0)
addRectangle => [
invisible = true
addSimpleLabel("ID: " + SynthesisUtils.getId(b.uniqueId, context)) => [
tooltip = b.uniqueId
addSingleClickAction(SelectRelatedAction::ID, ModifierState.NOT_PRESSED, ModifierState.NOT_PRESSED,
ModifierState.NOT_PRESSED)
if (!isProxy) {
addHorizontalSeperatorLine(1, 0)
addRectangle => [
invisible = true
addSimpleLabel("ID: " + SynthesisUtils.getId(b.uniqueId, context)) => [
tooltip = b.uniqueId
addSingleClickAction(SelectRelatedAction::ID, ModifierState.NOT_PRESSED, ModifierState.NOT_PRESSED,
ModifierState.NOT_PRESSED)
]
]
]
if (context.getOptionValue(FILTER_DESCRIPTIONS) as Boolean) {
val desc = SynthesisUtils.descriptionLabel(b.about, context)
if (!desc.empty) {
addRectangle => [
invisible = true
addSimpleLabel("Description: " + desc) => [
tooltip = b.about
addSingleClickAction(SelectRelatedAction::ID, ModifierState.NOT_PRESSED, ModifierState.NOT_PRESSED,
ModifierState.NOT_PRESSED)
if (context.getOptionValue(FILTER_DESCRIPTIONS) as Boolean) {
val desc = SynthesisUtils.descriptionLabel(b.about, context)
if (!desc.empty) {
addRectangle => [
invisible = true
addSimpleLabel("Description: " + desc) => [
tooltip = b.about
addSingleClickAction(SelectRelatedAction::ID, ModifierState.NOT_PRESSED, ModifierState.NOT_PRESSED,
ModifierState.NOT_PRESSED)
]
]
]
}
}
}
if (hasChildren) {
addHorizontalSeperatorLine(1, 0)
addChildArea
if (hasChildren) {
addHorizontalSeperatorLine(1, 0)
addChildArea
}
addSingleClickAction(SelectRelatedAction::ID, ModifierState.NOT_PRESSED, ModifierState.NOT_PRESSED,
ModifierState.NOT_PRESSED)
setSelectionStyle
}
setShadow(SHADOW_COLOR.color, 4, 4)
addSingleClickAction(SelectRelatedAction::ID, ModifierState.NOT_PRESSED, ModifierState.NOT_PRESSED,
ModifierState.NOT_PRESSED)
setSelectionStyle
]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import de.cau.cs.kieler.klighd.kgraph.KNode
import de.cau.cs.kieler.klighd.krendering.extensions.KNodeExtensions
import de.cau.cs.kieler.klighd.krendering.extensions.KPortExtensions
import de.cau.cs.kieler.klighd.syntheses.AbstractSubSynthesis
import de.cau.cs.kieler.klighd.util.KlighdProperties
import de.cau.cs.kieler.osgiviz.OsgiOptions
import de.cau.cs.kieler.osgiviz.OsgiStyles
import de.cau.cs.kieler.osgiviz.SynthesisUtils
Expand Down Expand Up @@ -54,79 +55,86 @@ class BundleSynthesis extends AbstractSubSynthesis<BundleContext, KNode> {

override transform(BundleContext bc) {
val bundle = bc.modelElement
return #[
bc.createNode() => [
addLayoutParam(CoreOptions::PORT_CONSTRAINTS, PortConstraints::FIXED_ORDER)
associateWith(bc)
data += createKIdentifier => [ it.id = bc.hashCode.toString ]

// Only show any connection ports if this bundle is shown in a bundle overview.
if (bc.parent instanceof BundleOverviewContext) {
// The ports that show the connection to the usedBy / required bundles with actions to add them to
// the view.
val filteredUsedByBundles = SynthesisUtils.filteredElements(bundle.usedByBundle,
bc.parent as IOverviewVisualizationContext<Bundle>, usedContext)
if (!filteredUsedByBundles.empty) {
ports += createPort(bc, "usedByBundles") => [
associateWith(bc)
// Identifier helps for connecting to this port later.
data += createKIdentifier => [ it.id = "usedByBundles" ]
// Used by bundles are always shown and expanded to the west against the drawing direction.
addLayoutParam(CoreOptions::PORT_SIDE, PortSide::WEST)
addUsedByBundlesPortRendering(filteredUsedByBundles.size, bc.allRequiringBundlesShown)
width = 12
height = 12
]
}
val filteredRequiredBundles = SynthesisUtils.filteredElements(bundle.requiredBundles,
bc.parent as IOverviewVisualizationContext<Bundle>, usedContext)
if (!filteredRequiredBundles.empty) {
ports += createPort(bc, "requiredBundles") => [
associateWith(bc)
data += createKIdentifier => [ it.id = "requiredBundles" ]
// Required bundles are always shown and expanded to the east with the drawing direction.
addLayoutParam(CoreOptions::PORT_SIDE, PortSide::EAST)
addLayoutParam(CoreOptions::PORT_INDEX, 0)
addRequiredBundlesPortRendering(filteredRequiredBundles.size, bc.allRequiredBundlesShown)
width = 12
height = 12
]
}
// Port for connection of imported packages.
val importedPackages = bundle.importedPackages
if (!importedPackages.empty) {
ports += createPort(bc, "importedPackages") => [
associateWith(bc)
data += createKIdentifier => [ it.id = "importedPackages" ]
// Bundles supporting used packages are always shown and expanded to the east with the drawing direction.
addLayoutParam(CoreOptions::PORT_SIDE, PortSide::EAST)
addLayoutParam(CoreOptions::PORT_INDEX, 1)
addUsedPackagesPortRendering(bc.allUsedPackagesShown)
width = 12
height = 12
]
}
}

// Show a service component overview of all service components provided by this bundle.
// Only show this, if the option for it says so and if the context is available.
if (usedContext.getOptionValue(OsgiOptions.BUNDLE_SHOW_SERVICES) === true
&& bc.serviceOverviewContext !== null) {
setLayoutOption(CoreOptions::NODE_SIZE_CONSTRAINTS, EnumSet.of(SizeConstraint.MINIMUM_SIZE))
// Commented out due to null pointer in ELK caused by a possible hierarchic edge going over this box layout
val node = bc.createNode()
val proxy = bc.createNode("proxy")
node.addLayoutParam(CoreOptions::PORT_CONSTRAINTS, PortConstraints::FIXED_ORDER)
node.associateWith(bc)
proxy.associateWith(bc)
node.data += createKIdentifier => [ it.id = bc.hashCode.toString ]
proxy.data += createKIdentifier => [ it.id = bc.hashCode.toString + "-proxy"]

// Only show any connection ports if this bundle is shown in a bundle overview.
if (bc.parent instanceof BundleOverviewContext) {
// The ports that show the connection to the usedBy / required bundles with actions to add them to
// the view.
val filteredUsedByBundles = SynthesisUtils.filteredElements(bundle.usedByBundle,
bc.parent as IOverviewVisualizationContext<Bundle>, usedContext)
if (!filteredUsedByBundles.empty) {
node.ports += createPort(bc, "usedByBundles") => [
associateWith(bc)
// Identifier helps for connecting to this port later.
data += createKIdentifier => [ it.id = "usedByBundles" ]
// Used by bundles are always shown and expanded to the west against the drawing direction.
addLayoutParam(CoreOptions::PORT_SIDE, PortSide::WEST)
addUsedByBundlesPortRendering(filteredUsedByBundles.size, bc.allRequiringBundlesShown)
width = 12
height = 12
]
}
val filteredRequiredBundles = SynthesisUtils.filteredElements(bundle.requiredBundles,
bc.parent as IOverviewVisualizationContext<Bundle>, usedContext)
if (!filteredRequiredBundles.empty) {
node.ports += createPort(bc, "requiredBundles") => [
associateWith(bc)
data += createKIdentifier => [ it.id = "requiredBundles" ]
// Required bundles are always shown and expanded to the east with the drawing direction.
addLayoutParam(CoreOptions::PORT_SIDE, PortSide::EAST)
addLayoutParam(CoreOptions::PORT_INDEX, 0)
addRequiredBundlesPortRendering(filteredRequiredBundles.size, bc.allRequiredBundlesShown)
width = 12
height = 12
]
}
// Port for connection of imported packages.
val importedPackages = bundle.importedPackages
if (!importedPackages.empty) {
node.ports += createPort(bc, "importedPackages") => [
associateWith(bc)
data += createKIdentifier => [ it.id = "importedPackages" ]
// Bundles supporting used packages are always shown and expanded to the east with the drawing direction.
addLayoutParam(CoreOptions::PORT_SIDE, PortSide::EAST)
addLayoutParam(CoreOptions::PORT_INDEX, 1)
addUsedPackagesPortRendering(bc.allUsedPackagesShown)
width = 12
height = 12
]
}
}

// Show a service component overview of all service components provided by this bundle.
// Only show this, if the option for it says so and if the context is available.
if (usedContext.getOptionValue(OsgiOptions.BUNDLE_SHOW_SERVICES) === true
&& bc.serviceOverviewContext !== null) {
node.setLayoutOption(CoreOptions::NODE_SIZE_CONSTRAINTS, EnumSet.of(SizeConstraint.MINIMUM_SIZE))
// Commented out due to null pointer in ELK caused by a possible hierarchic edge going over this box layout
// SynthesisUtils.configureBoxLayout(it)
// setLayoutOption(BoxLayouterOptions.BOX_PACKING_MODE, PackingMode.GROUP_MIXED)
val componentOverviewNodes = serviceOverviewSynthesis.transform(bc.serviceOverviewContext)
children += componentOverviewNodes
}

// Add the rendering.
val hasChildren = !children.empty
val boolean inOverview = bc.parent instanceof BundleOverviewContext
|| bc.parent instanceof ServiceOverviewContext
addBundleRendering(bundle, inOverview, hasChildren, usedContext)
]
]
val componentOverviewNodes = serviceOverviewSynthesis.transform(bc.serviceOverviewContext)
node.children += componentOverviewNodes
}

// Add the rendering.
val hasChildren = !node.children.empty
val boolean inOverview = bc.parent instanceof BundleOverviewContext
|| bc.parent instanceof ServiceOverviewContext
node.addBundleRendering(bundle, inOverview, hasChildren, usedContext, false)
proxy.addBundleRendering(bundle, inOverview, hasChildren, usedContext, true)

node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true)
// FIXME: Do we need to create a proxy node if we only need its data?
node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, proxy.data)

return #[node]
}

}
Loading