/* * 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; } }