/* * Copyright 2003-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.nodeEditor.leftHighlighter; import jetbrains.mps.nodeEditor.EditorComponent; import jetbrains.mps.openapi.editor.cells.CellInfo; import jetbrains.mps.openapi.editor.cells.EditorCell; import org.jetbrains.annotations.NotNull; import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; /** * User: Alexander Shatalin * Date: 02.03.2010 */ public class HighlighterBracket { private static final int BRACKET_LINE_THICKNESS = 2; private static final int ADDITIONAL_HORIZONTAL_SHIFT = 3; private BracketEdge myBegginingEdge = new BracketEdge(0, true); private BracketEdge myEndingEdge = new BracketEdge(0, false); private Color myColor; private CellInfo myCellInfo; private EditorComponent myEditor; private CellInfo mySecondCellInfo; // level should be at least 1 private int myLevel = 1; private boolean myRightToLeft; public static int getBracketWidth(int level) { return 2 * BRACKET_LINE_THICKNESS + (level - 1) * BRACKET_LINE_THICKNESS * 3 / 2 + ADDITIONAL_HORIZONTAL_SHIFT; } public HighlighterBracket(CellInfo cellInfo, CellInfo secondCellInfo, Color c, EditorComponent editorComponent, boolean rightToLeft) { myColor = c; myEditor = editorComponent; myCellInfo = cellInfo; mySecondCellInfo = secondCellInfo; myRightToLeft = rightToLeft; relayout(); } public boolean relayout() { EditorCell cell1 = myCellInfo.findCell(myEditor); EditorCell cell2 = mySecondCellInfo.findCell(myEditor); if (cell1 != null && cell2 != null) { if (cell1.getY() <= cell2.getY()) { setY1(cell1.getY()); setY2(cell2.getY() + cell2.getHeight()); } else { setY1(cell2.getY()); setY2(cell1.getY() + cell1.getHeight()); } return true; } else { return false; } } public BracketEdge getBeginningEdge() { return myBegginingEdge; } public BracketEdge getEndingEdge() { return myEndingEdge; } public void paint(Graphics g, Rectangle clipBounds) { if (clipBounds.y + clipBounds.height < getY1() || clipBounds.y > getY2()) { return; } int bracketWidth = getBracketWidth(getLevel()); if (clipBounds.x + clipBounds.width < (myRightToLeft ? 0 : -bracketWidth) || clipBounds.x > (myRightToLeft ? bracketWidth : 0)) { return; } g.setColor(myColor); int horizontalSegmentLength = bracketWidth - BRACKET_LINE_THICKNESS - ADDITIONAL_HORIZONTAL_SHIFT; g.fillRect(getHorizontalSegmentStartX(horizontalSegmentLength), getY1(), horizontalSegmentLength, BRACKET_LINE_THICKNESS); g.fillRect(getVerticalSegmentStartX(bracketWidth), getY1(), BRACKET_LINE_THICKNESS, getY2() - getY1()); g.fillRect(getHorizontalSegmentStartX(horizontalSegmentLength), getY2() - BRACKET_LINE_THICKNESS, horizontalSegmentLength, BRACKET_LINE_THICKNESS); } private int getHorizontalSegmentStartX(int horizontalSegmentLength) { // +1 is added here because of Graphics.fillRect() specific see javadoc for details return myRightToLeft ? ADDITIONAL_HORIZONTAL_SHIFT + 1 : -horizontalSegmentLength - ADDITIONAL_HORIZONTAL_SHIFT; } private int getVerticalSegmentStartX(int bracketWidth) { // +1 is added here because of Graphics.fillRect() specific see javadoc for details return myRightToLeft ? bracketWidth - BRACKET_LINE_THICKNESS + 1 : -bracketWidth; } public CellInfo getCell() { return myCellInfo; } private int getY1() { return myBegginingEdge.myY; } private void setY1(int y1) { myBegginingEdge.myY = y1; } private int getY2() { return myEndingEdge.myY; } private void setY2(int y2) { myEndingEdge.myY = y2; } public void setLevel(int level) { myLevel = level; } public int getLevel() { return myLevel; } public class BracketEdge implements Comparable<BracketEdge> { public int myY; private boolean myBeginning; public BracketEdge(int y, boolean beginning) { myY = y; myBeginning = beginning; } @NotNull public HighlighterBracket getBracket() { return HighlighterBracket.this; } public boolean isBeggining() { return myBeginning; } @Override public int compareTo(BracketEdge o) { if (myY == o.myY) { if (isBeggining() && !o.isBeggining()) { return 1; } else if (isBeggining() && o.isBeggining()) { return o.getBracket().getY2() - getBracket().getY2(); } else if (!isBeggining() && o.isBeggining()) { return -1; } else if (!isBeggining() && !o.isBeggining()) { return o.getBracket().getY1() - getBracket().getY1(); } } return myY - o.myY; } } }