Skip to content

Commit

Permalink
Color declaration compatibility check for subtypes
Browse files Browse the repository at this point in the history
  • Loading branch information
rensink committed Nov 15, 2024
1 parent 3e4351d commit 02b10d8
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 38 deletions.
5 changes: 3 additions & 2 deletions src/main/java/nl/utwente/groove/grammar/model/TypeModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,9 @@ private void addNodeType(AspectNode modelNode, TypeLabel typeLabel,
if (modelNode.has(IMPORT)) {
typeNode.setImported(true);
}
if (modelNode.hasColor()) {
typeNode.setColor(modelNode.getColor());
var color = modelNode.getColor();
if (color != null) {
typeNode.setDeclaredColor(color);
}
if (modelNode.has(EDGE)) {
typeNode.setLabelPattern(modelNode.getEdgePattern());
Expand Down
34 changes: 27 additions & 7 deletions src/main/java/nl/utwente/groove/grammar/type/TypeGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,9 @@ public Map<TypeNode,TypeNode> add(TypeGraph other) throws FormatException {
if (source.isAbstract()) {
image.setAbstract();
}
if (source.getColor() != null) {
image.setColor(source.getColor());
var color = source.getDeclaredColor();
if (color != null) {
image.setDeclaredColor(color);
}
image.setLabelPattern(source.getLabelPattern());
boolean imported = source.isImported() && (oldImage == null || oldImage.isImported());
Expand Down Expand Up @@ -296,9 +297,28 @@ && hasCommonSubtype(edge1.target(), edge2.target())) {
}
}
// check for inconsistent color specifications in the type hierarchy
// this occurs if a node type has no color specification, whereas two
// of its supertypes have distinct ones.

// this occurs if two node types with declared colours share a subtype.
var coloredNodes = nodeSet().stream().filter(TypeNode::hasDeclaredColor).toList();
for (var n1 : coloredNodes) {
var n1Color = n1.getDeclaredColor();
assert n1Color != null;
boolean start = false;
for (var n2 : coloredNodes) {
if (n1 == n2) {
start = true;
continue;
}
if (!start) {
continue;
}
if (n1Color.equals(n2.getDeclaredColor())) {
continue;
}
if (hasCommonSubtype(n1, n2)) {
errors.add("Incompatible color declarations on %s and %s", n1, n2);
}
}
}
errors.throwException();
}

Expand Down Expand Up @@ -331,7 +351,7 @@ public boolean setFixed() {
}
}
// propagate colours to subtypes
var coloredNodes = nodeSet().stream().filter(TypeNode::hasColor).toList();
var coloredNodes = nodeSet().stream().filter(TypeNode::hasDeclaredColor).toList();
for (TypeNode node : coloredNodes) {
// propagate colours
Color color = node.getColor();
Expand All @@ -343,7 +363,7 @@ public boolean setFixed() {
TypeNode subNode = subNodeIter.next();
subNodeIter.remove();
if (subNode.getColor() == null) {
subNode.setColor(color);
subNode.setDerivedColor(color);
} else {
propagatees.removeAll(this.nodeSubtypeMap.get(subNode));
}
Expand Down
34 changes: 26 additions & 8 deletions src/main/java/nl/utwente/groove/grammar/type/TypeNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -201,23 +201,41 @@ public final void setLabelPattern(@Nullable LabelPattern pattern) {
/** The label pattern of this node, if any. */
private @Nullable LabelPattern pattern;

/** Sets the declared (and derived) colour of this type node. */
public void setDeclaredColor(Color colour) {
this.declaredColour = this.derivedColour = colour;
}

/** Indicates if this type node has a declared display colour. */
public boolean hasDeclaredColor() {
return this.declaredColour != null;
}

/** Returns the declared colour of this type node, if any. */
public @Nullable Color getDeclaredColor() {
return this.declaredColour;
}

/** The declared display colour of this node, if any. */
private @Nullable Color declaredColour;

/** Returns the (possibly {@code null}) colour of this type node. */
public final @Nullable Color getColor() {
return this.colour;
return this.derivedColour;
}

/** Indicates if this type node has an explicitly set colour. */
/** Indicates if this type node has a (declared or derived) display colour. */
public final boolean hasColor() {
return this.colour != null;
return this.derivedColour != null;
}

/** Sets the colour of this type node. */
public final void setColor(@Nullable Color colour) {
this.colour = colour;
/** Sets the derived colour of this type node. */
void setDerivedColor(Color colour) {
this.derivedColour = colour;
}

/** The display colour of this node, if any. */
private @Nullable Color colour;
/** The derived display colour of this node, if any. */
private @Nullable Color derivedColour;

@Override
public TypeGraph getGraph() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private void checkLabelTree(LabelTree<?> tree) {
public void execute() {
TypeNode typeNode = getGrammarModel().getTypeGraph().getNode(this.label);
assert typeNode != null; // ensured by the label
Color initColour = typeNode.getColor();
Color initColour = typeNode.getDeclaredColor();
if (initColour != null) {
this.chooser.setColor(initColour);
}
Expand Down
21 changes: 1 addition & 20 deletions src/main/java/nl/utwente/groove/gui/look/ColorValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,12 @@
package nl.utwente.groove.gui.look;

import java.awt.Color;
import java.util.Objects;

import org.eclipse.jdt.annotation.NonNull;

import nl.utwente.groove.grammar.aspect.AspectNode;
import nl.utwente.groove.grammar.type.TypeNode;
import nl.utwente.groove.graph.GraphRole;
import nl.utwente.groove.gui.jgraph.AspectJEdge;
import nl.utwente.groove.gui.jgraph.AspectJVertex;
import nl.utwente.groove.util.Groove;

/**
* Refresher for the controlled colour value of a JCell.
Expand All @@ -44,28 +40,13 @@ protected Color getForJVertex(AspectJVertex jVertex) {
} else {
TypeNode nodeType = jVertex.getNodeType();
if (nodeType != null) {
result = getColor(nodeType);
result = nodeType.getColor();
}
}
}
return result;
}

/** Recursively finds the "closest" color specification among this node type and its supertypes. */
private Color getColor(@NonNull TypeNode nodeType) {
Color result = nodeType.getColor();
if (result == null) {
result = Groove
.orElseNull(nodeType
.getDirectSupertypes()
.stream()
.map(this::getColor)
.filter(Objects::nonNull)
.findFirst());
}
return result;
}

@Override
protected Color getForJEdge(AspectJEdge jEdge) {
Color result = null;
Expand Down

0 comments on commit 02b10d8

Please sign in to comment.