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

klighd +.piccolo: enabled support of multiple KTexts per KLabel as demanded in #43 #55

Merged
merged 1 commit into from
Aug 3, 2020
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 @@ -153,12 +153,6 @@ public static void validate(final KNode graph) {
if (node.getInsets() == null) {
node.setInsets(FACTORY.createKInsets());
}
// Make sure labels are OK
} else if (element instanceof KLabel) {
KLabel label = (KLabel) element;
if (label.getText() == null) {
label.setText("");
}
// Make sure edges are OK
} else if (element instanceof KEdge) {
KEdge edge = (KEdge) element;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ public class DiagramController {
/** whether edges are drawn before nodes, i.e. nodes have priority over edges. */
private final boolean edgesFirst;

/** whether figure descriptions of KLabels may contain multiple KTexts. */
private final boolean multipleKTextsPerKLabel;

/** whether to record layout changes, will be set to true by the KlighdLayoutManager. */
private boolean record = false;

Expand Down Expand Up @@ -175,6 +178,7 @@ public DiagramController(final KNode graph, final KlighdMainCamera camera, final
final ViewContext viewContext) {
this(graph, camera, sync,
getProperty(viewContext, KlighdProperties.EDGES_FIRST).booleanValue(),
getProperty(viewContext, KlighdProperties.MULTIPLE_KTEXTS_PER_KLABEL).booleanValue(),
getProperty(viewContext, KlighdProperties.ZOOM_TO_FIT_CONTENT_SPACING));

camera.initClipsPortAndLabelsVisibility(
Expand All @@ -199,13 +203,22 @@ private static <T> T getProperty(ViewContext context, IProperty<T> property) {
* @param edgesFirst
* determining whether edges are drawn before nodes, i.e. nodes have priority over
* edges
* @param multipleKTextsPerKLabel
* whether figure descriptions of KLabels may contain multiple KTexts.
* @param defaultZoomToFitContentSpacing
* default spacing to be applied if {@link ZoomStyle#ZOOM_TO_FIT_CONTENT} is
* demanded, see also
* {@link de.cau.cs.kieler.klighd.util.KlighdProperties#ZOOM_TO_FIT_CONTENT_SPACING},
* may be <code>null</code>
*/
protected DiagramController(final KNode graph, final KlighdMainCamera camera, final boolean sync,
final boolean edgesFirst, final Spacing defaultZoomToFitContentSpacing) {
protected DiagramController(final KNode graph, final KlighdMainCamera camera,
final boolean sync, final boolean edgesFirst, final boolean multipleKTextsPerKLabel,
final Spacing defaultZoomToFitContentSpacing) {
DiagramControllerHelper.resetGraphElement(graph);

this.sync = sync;
this.edgesFirst = edgesFirst;
this.multipleKTextsPerKLabel = multipleKTextsPerKLabel;

this.canvasCamera = camera;

Expand Down Expand Up @@ -1884,7 +1897,7 @@ private void updateRendering(final KLabelNode labelRep) {
if (renderingController == null) {
// the new rendering controller is attached to nodeRep in the constructor of
// AbstractRenderingController
renderingController = new KLabelRenderingController(labelRep);
renderingController = new KLabelRenderingController(labelRep, multipleKTextsPerKLabel);
// labelRep.addAttribute(RENDERING_KEY, renderingController);
renderingController.initialize(this, sync);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,27 @@
import de.cau.cs.kieler.klighd.microlayout.PlacementUtil;
import de.cau.cs.kieler.klighd.piccolo.internal.nodes.KLabelNode;
import de.cau.cs.kieler.klighd.piccolo.internal.nodes.KlighdStyledText;
import de.cau.cs.kieler.klighd.util.KlighdProperties;
import edu.umd.cs.piccolo.PNode;

/**
* @author mri, chsch
*/
public class KLabelRenderingController extends AbstractKGERenderingController<KLabel, KLabelNode> {

/** whether figure descriptions shall be checked for at most one {@link KText} element. */
private final boolean validateSingleKText;

/**
* Constructs a rendering controller for a label.
*
* @param label
* the Piccolo node representing a label
* @param multipleKTextsPerKLabel
* whether figure descriptions of KLabels may contain multiple KTexts.
*/
public KLabelRenderingController(final KLabelNode label) {
public KLabelRenderingController(final KLabelNode label, final boolean multipleKTextsPerKLabel) {
super(label.getViewModelElement(), label);
this.validateSingleKText = !multipleKTextsPerKLabel;
}

/**
Expand Down Expand Up @@ -88,19 +93,11 @@ private PNodeController<?> handleLabelRendering(final KRendering rendering,

final KText kText = Iterators.getNext(kTexts, null);

if (kText == null || kTexts.hasNext()) {
if (kText == null || validateSingleKText && kTexts.hasNext()) {
throw new RuntimeException("KLabel " + getGraphElement()
+ " must (deeply) contain exactly 1 KText element.");
}

// Transfer selectability from KLabel to KText to properly handle the selection handlers
// Should only apply if the KText is not configured but KLabel is configured
if (!kText.getProperties().contains(KlighdProperties.NOT_SELECTABLE)
&& getGraphElement().getProperties().contains(KlighdProperties.NOT_SELECTABLE)) {
kText.setProperty(KlighdProperties.NOT_SELECTABLE,
getGraphElement().getProperty(KlighdProperties.NOT_SELECTABLE));
}

// create the rendering
final PNodeController<?> controller =
createRendering(rendering, parent, Bounds.of(parent.getBoundsReference()));
Expand All @@ -113,14 +110,16 @@ && getGraphElement().getProperties().contains(KlighdProperties.NOT_SELECTABLE))
// the opposite should never happen (see test above), this test is just for preventing
// null pointer exceptions

textController.getNode().setText(parent.getText());
textController.getNode().setText(
parent.getText() != null ? parent.getText() : kText.getText());

// add a listener on the parent's bend points
addListener(KLabelNode.PROPERTY_TEXT, parent, controller.getNode(),
new PropertyChangeListener() {

public void propertyChange(final PropertyChangeEvent e) {
textController.getNode().setText(parent.getText());
textController.getNode().setText(
parent.getText() != null ? parent.getText() : kText.getText());
textController.getNode().repaint();
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class KLabelNode extends KGraphElementNode<KLabel> {
private KLabelRenderingController renderingController;

/** the text. */
private String text = "";
private String text = null;

/**
* Constructs a Piccolo2D node for representing a {@code KLabel}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public String getText() {
* The text string to be displayed.
*/
public void setText(final String theText) {
this.text = theText;
this.text = theText == null ? "" : theText;
updateBounds();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@
import de.cau.cs.kieler.klighd.krendering.KRenderingFactory;
import de.cau.cs.kieler.klighd.krendering.KRenderingOptions;
import de.cau.cs.kieler.klighd.krendering.KRenderingRef;
import de.cau.cs.kieler.klighd.krendering.KRenderingUtil;
import de.cau.cs.kieler.klighd.krendering.KText;
import de.cau.cs.kieler.klighd.labels.management.LabelManagementResult;
import de.cau.cs.kieler.klighd.microlayout.Bounds;
import de.cau.cs.kieler.klighd.microlayout.PlacementUtil;
Expand Down Expand Up @@ -552,9 +554,19 @@ private void createLabel(final LayoutMapping mapping, final KLabel label,
final ElkGraphElement layoutLabeledElement, final boolean estimateSize,
final boolean setFontLayoutOptions) {

final KText kText = Iterators.getNext(
Iterators.filter(
KRenderingUtil.selfAndAllChildren(label.getData(KRendering.class)),
KText.class),
null);

final String labelText =
label.getText() != null ? label.getText()
: kText != null ? kText.getText() : "";

final ElkLabel layoutLabel =
ElkGraphUtil.createLabel(label.getText(), layoutLabeledElement);
ElkGraphUtil.createLabel(labelText, layoutLabeledElement);

KIdentifier id = label.getData(KIdentifier.class);
if (id != null && !Strings.isNullOrEmpty(id.getId())) {
layoutLabel.setIdentifier(id.getId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ private KlighdProperties() {
* {@link de.cau.cs.kieler.klighd.kgraph.KGraphElement KGraphElement} (kge) into the corresponding
* diagram if the value is true.<br>
* This property is currently to be attached to the kge's
* {@link de.cau.cs.kieler.kiml.klayoutdata.KLayoutData } data during the view synthesis process.
* {@link de.cau.cs.kieler.klighd.kgraph.KLayoutData KLayoutData} data during the view synthesis process.
* If it is absent the kge is incorporated, anyway.
*/
public static final IProperty<Boolean> SHOW = new Property<Boolean>(
Expand Down Expand Up @@ -256,8 +256,8 @@ public static boolean isSelectable(final EObject viewElement) {
* Property determining whether the diagram zoom scale-based visibility configurations of the
* {@link de.cau.cs.kieler.klighd.krendering.KRendering KRendering} it is defined on shall apply
* to its children, as well. Configuring this property on {@link KGraphElement KGraphElements}
* (' {@link KLayoutData}) will have no effect, {@link KGraphElement KGraphElements'} children
* are automatically skipped by default.
* (' {@link de.cau.cs.kieler.klighd.kgraph.KLayoutData KLayoutData}) will have no effect,
* {@link KGraphElement KGraphElements'} children are automatically skipped by default.
*/
public static final IProperty<Boolean> VISIBILITY_PROPAGATE_TO_CHILDREN = new Property<Boolean>(
"de.cau.cs.kieler.klighd.visibilityPropagateToChildren", false);
Expand Down Expand Up @@ -308,6 +308,16 @@ public static boolean isSelectable(final EObject viewElement) {
public static final IProperty<Boolean> EDGES_FIRST = new Property<Boolean>(
"klighd.edgesFirst", false);

/**
* Property for globally determining whether figure descriptions of
* {@link de.cau.cs.kieler.klighd.kgraph.KLabel KLabel}s may contain multiple KTexts. Enabling
* this has implications on the applicability of layout algorithms performing the computation of
* the label size on their own, as well as the on the applicability of
* {@link org.eclipse.elk.core.labels.ILabelManager ILabelManager}s.
*/
public static final IProperty<Boolean> MULTIPLE_KTEXTS_PER_KLABEL = new Property<Boolean>(
"klighd.multipleKTextsPerKLabel", false);

/**
* Determines whether the ports and port labels of clipped nodes should be shown or not.
* By default the ports are shown, preventing issues with links to external ports.
Expand Down