package jetbrains.mps.nodeEditor.cells.jetpad;
/*Generated by MPS */
import jetbrains.mps.openapi.editor.EditorContext;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.jetpad.mapper.Mapper;
import jetbrains.jetpad.projectional.diagram.view.DiagramNodeView;
import jetbrains.mps.lang.editor.diagram.runtime.jetpad.views.NodeDecoratorView;
import jetbrains.jetpad.projectional.view.View;
import jetbrains.jetpad.geometry.Vector;
import java.util.ListIterator;
import java.util.Set;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.openapi.editor.cells.EditorCell;
import jetbrains.jetpad.projectional.diagram.view.block.BlockView;
import jetbrains.jetpad.values.Color;
import jetbrains.jetpad.projectional.diagram.view.RootTrait;
import jetbrains.jetpad.projectional.diagram.view.MoveHandler;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import jetbrains.jetpad.projectional.view.ViewTraitBuilder;
import jetbrains.jetpad.projectional.view.ViewEvents;
import jetbrains.jetpad.projectional.view.ViewEventHandler;
import jetbrains.jetpad.event.KeyEvent;
import jetbrains.jetpad.event.Key;
import jetbrains.jetpad.event.ModifierKey;
import jetbrains.mps.lang.editor.diagram.runtime.jetpad.views.MovableContentView;
public abstract class BlockCell extends AbstractJetpadCell {
public BlockCell(EditorContext editorContext, SNode node) {
super(editorContext, node);
}
public abstract Mapper<SNode, DiagramNodeView> createMapper();
public abstract Mapper<SNode, NodeDecoratorView> createDecorationMapper();
private void moveView(ReadableModelProperty<Integer> xProperty, ReadableModelProperty<Integer> yProperty) {
// TODO: not used? remove?
DiagramCell cell = getDiagramCell();
if (cell == null) {
return;
}
Mapper<? super SNode, ?> descendantMapper = cell.getRootMapper().getDescendantMapper(getSNode());
if (descendantMapper != null) {
((View) descendantMapper.getTarget()).moveTo(new Vector(xProperty.get(), yProperty.get()));
((View) descendantMapper.getTarget()).invalidate();
requestRelayout();
}
}
protected String getContentViewMapperSource() {
return getSNode().getNodeId().toString();
}
protected Mapper<SNode, DiagramNodeView> getBlockMapper() {
return (Mapper<SNode, DiagramNodeView>) getDiagramCell().getRootMapper().getDescendantMapper(getSNode());
}
protected View getContentView() {
Mapper<SNode, DiagramNodeView> blockMapper = getBlockMapper();
if (blockMapper == null || blockMapper.getTarget() == null || blockMapper.getTarget().contentView.children().size() == 0) {
return null;
}
return blockMapper.getTarget().contentView.children().get(0);
}
protected void syncPortNodes(Iterable<? extends SNode> ports, ListIterator<SNode> portsIterator, Set<SNode> existingPorts) {
for (SNode nextPort : Sequence.fromIterable(ports)) {
EditorCell portCell = getContext().getEditorComponent().getUpdater().getCurrentUpdateSession().updateChildNodeCell(nextPort);
if (!(portCell instanceof PortCell)) {
continue;
}
syncToNextNode(portsIterator, existingPorts, nextPort, portCell);
}
purgeTailNodes(portsIterator);
}
protected void syncPortObjects(Iterable<?> ports, ListIterator portsIterator, Set existingPorts) {
for (Object port : Sequence.fromIterable(ports)) {
if (existingPorts.contains(port)) {
syncToNextObject(portsIterator, existingPorts, port);
} else {
portsIterator.add(port);
existingPorts.add(port);
}
}
while (portsIterator.hasNext()) {
portsIterator.next();
portsIterator.remove();
}
}
private void syncToNextObject(ListIterator listIterator, Set elementsSet, Object next) {
while (listIterator.hasNext()) {
Object nextFromList = listIterator.next();
if (nextFromList == next) {
return;
}
listIterator.remove();
elementsSet.remove(nextFromList);
}
assert false : "Next element was not found in passed listIterator";
}
protected DiagramNodeView createDiagramNodeView() {
final BlockView blockView = new BlockView();
blockView.minimalSize().set(new Vector(10, 10));
blockView.rect.background().set(Color.TRANSPARENT);
blockView.padding().set(0);
blockView.contentView.prop(RootTrait.MOVE_HANDLER).set(new MoveHandler() {
public void move(Vector delta) {
blockView.move(delta);
blockView.invalidate();
requestRelayout();
}
});
configureView(blockView, new _FunctionTypes._return_P0_E0<Boolean>() {
public Boolean invoke() {
return true;
}
});
blockView.prop(JetpadUtils.CONNECTABLE).set(Boolean.TRUE);
blockView.rect.prop(JetpadUtils.SOURCE).set(getSNode());
blockView.addTrait(new ViewTraitBuilder().on(ViewEvents.KEY_PRESSED, new ViewEventHandler<KeyEvent>() {
@Override
public void handle(View view, KeyEvent e) {
if (!(blockView.focused().get())) {
return;
}
if (e.is(Key.T)) {
blockView.setPortsDirection(blockView.getPortsDirection().turnClockwise());
} else if (e.is(Key.T, ModifierKey.SHIFT)) {
blockView.setPortsDirection(blockView.getPortsDirection().turnCounterclockwise());
}
}
}).build());
return blockView;
}
protected void updatePositionsFromModel(View contentView, DiagramNodeView nodeView) {
Integer xPosition = contentView.prop(MovableContentView.POSITION_X).get();
Integer yPosition = contentView.prop(MovableContentView.POSITION_Y).get();
int x = (xPosition != null ? xPosition : 0);
int y = (yPosition != null ? yPosition : 0);
Vector delta = nodeView.bounds().get().origin.sub(nodeView.rect.bounds().get().origin);
nodeView.moveTo(new Vector(x, y).add(delta));
}
}