package jetbrains.mps.debugger.core; /*Generated by MPS */ import jetbrains.mps.nodeEditor.AbstractAdditionalPainter; import java.util.Map; import jetbrains.mps.nodeEditor.EditorComponent; import jetbrains.mps.openapi.editor.cells.EditorCell; import jetbrains.mps.internal.collections.runtime.MapSequence; import java.util.HashMap; import org.jetbrains.annotations.Nullable; import java.awt.Color; import org.jetbrains.mps.openapi.model.SNodeReference; import java.awt.Graphics; import org.jetbrains.mps.openapi.module.SRepository; import org.jetbrains.mps.openapi.module.ModelAccess; import org.jetbrains.mps.openapi.model.SNode; import java.awt.Rectangle; import jetbrains.mps.nodeEditor.cells.EditorCell_Label; import jetbrains.mps.nodeEditor.cells.CellFinderUtil; import jetbrains.mps.nodeEditor.cells.GeometryUtil; import jetbrains.mps.openapi.editor.cells.EditorCell_Collection; import jetbrains.mps.nodeEditor.cellLayout.CellLayout_Horizontal; import org.jetbrains.mps.util.Condition; public abstract class DebuggerCellPainter<E> extends AbstractAdditionalPainter<E> { private static final int LEFT_MARGIN = 4; private Map<EditorComponent, EditorCell> myCells = MapSequence.fromMap(new HashMap<EditorComponent, EditorCell>()); public DebuggerCellPainter() { } @Nullable protected abstract Color getCellBackgroundColor(); @Nullable protected abstract Color getStripeBackgroundColor(); @Nullable protected abstract Color getFrameColor(); @Nullable protected abstract SNodeReference getSNode(); @Override public void afterAdding(EditorComponent component) { super.afterAdding(component); setComponentParameters(component); } @Override public void beforeRemoval(EditorComponent component) { resetComponentParameters(component); super.beforeRemoval(component); } @Override public boolean paintsAbove() { return true; } @Override public void paint(Graphics graphics, EditorComponent editorComponent) { EditorCell nodeCell = getNodeCell(editorComponent); if (nodeCell == null) { return; } Color frameColor = getFrameColor(); if (frameColor == null) { return; } graphics.setColor(frameColor); graphics.drawRect(nodeCell.getX(), nodeCell.getY(), nodeCell.getWidth() - 1, nodeCell.getHeight() - 1); } @Override public boolean paintsBackground() { return true; } @Override public void paintBackground(Graphics graphics, EditorComponent component) { paintStripeBackground(graphics, component); paintCellBackground(graphics, component); } private void setComponentParameters(final EditorComponent editorComponent) { final SRepository repository = editorComponent.getEditorContext().getRepository(); ModelAccess ma = repository.getModelAccess(); ma.runReadAction(new Runnable() { public void run() { SNode node = (getSNode() == null ? null : getSNode().resolve(repository)); MapSequence.fromMap(myCells).put(editorComponent, (node == null ? null : editorComponent.getBigValidCellForNode(node))); } }); } private void resetComponentParameters(EditorComponent editorComponent) { MapSequence.fromMap(myCells).removeKey(editorComponent); } private void paintCellBackground(Graphics graphics, EditorComponent editorComponent) { if (isInCellMode(editorComponent)) { Color cellBackgroundColor = getCellBackgroundColor(); if (cellBackgroundColor == null) { return; } graphics.setColor(cellBackgroundColor); Rectangle cellCoverage = getCellCoverage(editorComponent); if (cellCoverage == null) { return; } graphics.fillRect(cellCoverage.x, cellCoverage.y, cellCoverage.width, cellCoverage.height); } } private void paintStripeBackground(Graphics graphics, EditorComponent editorComponent) { if (isInCellMode(editorComponent)) { return; } Color stripeBackgroundColor = getStripeBackgroundColor(); if (stripeBackgroundColor == null) { return; } graphics.setColor(stripeBackgroundColor); Rectangle stripeCoverage = getStripeCoverage(editorComponent); if (stripeCoverage == null) { return; } graphics.fillRect(stripeCoverage.x, stripeCoverage.y, stripeCoverage.width, stripeCoverage.height); } @Nullable private EditorCell getNodeCell(final EditorComponent editorComponent) { return MapSequence.fromMap(myCells).get(editorComponent); } @Nullable private EditorCell_Label getStripeCell(EditorComponent editorComponent) { EditorCell nodeCell = getNodeCell(editorComponent); if (nodeCell == null) { return null; } if (nodeCell instanceof EditorCell_Label) { return (EditorCell_Label) nodeCell; } return CellFinderUtil.findChildByClass(nodeCell, EditorCell_Label.class, true); } @Nullable protected Rectangle calculateCoverageArea(EditorComponent editorComponent) { if (isInCellMode(editorComponent)) { return getCellCoverage(editorComponent); } return getStripeCoverage(editorComponent); } @Nullable private Rectangle getCellCoverage(EditorComponent editorComponent) { EditorCell nodeCell = getNodeCell(editorComponent); if (nodeCell == null) { return null; } return GeometryUtil.getBounds(nodeCell); } @Nullable private Rectangle getStripeCoverage(EditorComponent editorComponent) { EditorCell_Label stripeCell = getStripeCell(editorComponent); if (stripeCell == null) { return null; } return new Rectangle(LEFT_MARGIN, stripeCell.getY(), editorComponent.getWidth() - LEFT_MARGIN, stripeCell.getHeight() - stripeCell.getTopInset() - stripeCell.getBottomInset()); } private boolean isInCellMode(EditorComponent editorComponent) { EditorCell nodeCell = getNodeCell(editorComponent); if (nodeCell == null) { // whatever return false; } EditorCell_Collection parent = nodeCell.getParent(); if (parent == null) { return false; } if (parent.getCellLayout() instanceof CellLayout_Horizontal) { // if immediate parent is a horisontal collection return true; } return CellFinderUtil.findParent(nodeCell, new Condition<EditorCell_Collection>() { @Override public boolean met(EditorCell_Collection cellCollection) { // do not want an explicit dependency on table.runtime return eq_mgy25g_a0b0a0a1a0f0x(cellCollection.getClass().getSimpleName(), "EditorCell_Table"); } }) != null; } private static boolean eq_mgy25g_a0b0a0a1a0f0x(Object a, Object b) { return (a != null ? a.equals(b) : a == b); } }