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)); } }