/*
* 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.cellLayout;
import jetbrains.mps.editor.runtime.style.Measure;
import jetbrains.mps.editor.runtime.style.Padding;
import jetbrains.mps.editor.runtime.style.StyleAttributes;
import jetbrains.mps.nodeEditor.EditorSettings;
import jetbrains.mps.nodeEditor.cells.FontRegistry;
import jetbrains.mps.openapi.editor.cells.CellTraversalUtil;
import jetbrains.mps.openapi.editor.cells.EditorCell;
import jetbrains.mps.openapi.editor.cells.EditorCell_Collection;
import java.awt.Font;
import java.awt.FontMetrics;
public class PunctuationUtil {
static void addGaps(EditorCell cell, boolean skipLeft, boolean skipRight) {
if (cell instanceof EditorCell_Collection &&
(hasPunctuableLayout((EditorCell_Collection) cell) || cell.getStyle().get(StyleAttributes.DRAW_BORDER))) {
return;
}
int gap = getHorizontalGap(cell.getParent());
cell.setLeftGap(!skipLeft && hasLeftGap(cell) ? gap / 2 : 0);
cell.setRightGap(!skipRight && hasRightGap(cell) ? gap / 2 : 0);
}
static int getLeftGap(EditorCell cell) {
if (cell instanceof EditorCell_Collection &&
(hasPunctuableLayout((EditorCell_Collection) cell) || cell.getStyle().get(StyleAttributes.DRAW_BORDER))) {
return 0;
}
return hasLeftGap(cell) ? getHorizontalGap(cell.getParent()) / 2 : 0;
}
private static boolean hasRightGap(EditorCell currentCell) {
return (!rightCellHasPunctuationLeft(currentCell) || currentCell.getStyle().get(StyleAttributes.DRAW_BORDER))
&& !hasPunctuationRight(currentCell);
}
public static boolean hasLeftGap(EditorCell currentCell) {
return (!leftCellHasPunctuationRight(currentCell) || currentCell.getStyle().get(StyleAttributes.DRAW_BORDER))
&& !hasPunctuationLeft(currentCell);
}
static boolean leftCellHasPunctuationRight(EditorCell currentCell) {
EditorCell_Collection parent = currentCell.getParent();
if (parent == null || !hasPunctuableLayout(parent)) {
return true;
}
if (parent.getCellLayout() instanceof CellLayout_Indent && CellLayout_Indent.isOnNewLine(parent, currentCell)) {
return true;
}
if (parent.firstCell() == currentCell) {
return leftCellHasPunctuationRight(parent);
}
EditorCell leftCell = CellTraversalUtil.getPrevLeaf(currentCell);
if (parent.getCellLayout() instanceof CellLayout_Indent && CellLayout_Indent.isNewLineAfter(parent, leftCell)) {
return true;
}
if (leftCell instanceof EditorCell_Collection) {
return leftCellHasPunctuationRight(leftCell);
}
return hasPunctuationRight(leftCell);
}
private static boolean rightCellHasPunctuationLeft(EditorCell currentCell) {
EditorCell_Collection parent = currentCell.getParent();
if (parent == null || !hasPunctuableLayout(parent)) {
return true;
}
if (parent.lastCell() == currentCell) {
return rightCellHasPunctuationLeft(parent);
}
EditorCell rightCell = CellTraversalUtil.getNextLeaf(currentCell);
if (rightCell instanceof EditorCell_Collection) {
return rightCellHasPunctuationLeft(rightCell);
}
return hasPunctuationLeft(rightCell);
}
private static Boolean hasPunctuationRight(EditorCell cell) {
if (cell == null) {
return true;
}
return CellTraversalUtil.getLastLeaf(cell).getStyle().get(StyleAttributes.PUNCTUATION_RIGHT);
}
static Boolean hasPunctuationLeft(EditorCell cell) {
if (cell == null) {
return true;
}
return CellTraversalUtil.getFirstLeaf(cell).getStyle().get(StyleAttributes.PUNCTUATION_LEFT);
}
private static int getHorizontalGap(EditorCell_Collection editorCells) {
Padding padding = editorCells.getStyle().get(StyleAttributes.HORIZONTAL_GAP);
if (padding.getType() == Measure.PIXELS) {
return (int) padding.getValue();
} else {
Font f = EditorSettings.getInstance().getDefaultEditorFont();
FontMetrics m = FontRegistry.getInstance().getFontMetrics(f);
return (int) (padding.getValue() * m.charWidth(' '));
}
}
private static boolean hasPunctuableLayout(EditorCell_Collection collection) {
return collection.getCellLayout() instanceof CellLayout_Horizontal || collection.getCellLayout() instanceof CellLayout_Indent;
}
}