/*
* 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.TextBuilderImpl;
import jetbrains.mps.editor.runtime.style.ScriptKind;
import jetbrains.mps.editor.runtime.style.StyleAttributes;
import jetbrains.mps.nodeEditor.EditorSettings;
import jetbrains.mps.nodeEditor.cells.EditorCell_Label;
import jetbrains.mps.openapi.editor.TextBuilder;
import jetbrains.mps.openapi.editor.cells.EditorCell;
import jetbrains.mps.openapi.editor.cells.EditorCell_Collection;
/**
* Sergey.Sinchuk, Oct 29, 2009
*/
public class CellLayout_Superscript extends AbstractCellLayout {
private int myBaseScale = 0;
private static final double scaleCoo = 0.8;
@Override
public boolean canBeFolded() {
return true;
}
private void applyScalingInt(EditorCell cell, int scale) {
if (cell instanceof EditorCell_Collection) {
EditorCell_Collection collection = (EditorCell_Collection) cell;
jetbrains.mps.openapi.editor.cells.CellLayout layout = collection.getCellLayout();
if (layout instanceof CellLayout_Superscript) {
((CellLayout_Superscript) layout).myBaseScale = scale;
} else {
for (EditorCell c : collection) {
applyScalingInt(c, scale);
}
}
}
if (cell instanceof EditorCell_Label) {
EditorCell_Label label = (EditorCell_Label) cell;
Integer oldFontSize = label.getStyle().get(StyleAttributes.ORIGINAL_FONT_SIZE);
Integer fontSize = label.getStyle().get(StyleAttributes.FONT_SIZE);
if (fontSize == null) {
fontSize = EditorSettings.getInstance().getFontSize();
}
if (oldFontSize == null) {
oldFontSize = fontSize;
label.getStyle().set(StyleAttributes.ORIGINAL_FONT_SIZE, oldFontSize);
}
fontSize = (int) Math.round(oldFontSize * Math.pow(scaleCoo, scale));
if (!fontSize.equals(oldFontSize)) {
label.getStyle().set(StyleAttributes.FONT_SIZE, fontSize);
}
}
}
public void applyScaling(EditorCell_Collection editorCells) {
for (EditorCell cell : editorCells) {
int i = cell.getStyle().get(StyleAttributes.SCRIPT_KIND) != ScriptKind.NORMAL ? 1 : 0;
applyScalingInt(cell, myBaseScale + i);
}
}
@Override
public void doLayout(EditorCell_Collection editorCells) {
Iterable<EditorCell> cells = editorCells.getContentCells();
final int x = editorCells.getX();
final int y = editorCells.getY();
int width;
int height;
int floor1 = 0;
int floor2 = 0;
int floor3 = 0;
int floor1x = x;
int floor2x = x;
int floor3x = x;
applyScaling(editorCells);
for (EditorCell cell : cells) {
cell.relayout();
ScriptKind skind = cell.getStyle().get(StyleAttributes.SCRIPT_KIND);
int cellHeight = cell.getHeight();
switch (skind) {
case NORMAL:
floor2 = Math.max(floor2, cellHeight);
break;
case SUBSCRIPT:
floor1 = Math.max(floor1, cellHeight);
break;
case SUPERSCRIPT:
floor3 = Math.max(floor3, cellHeight);
break;
}
}
for (EditorCell cell : cells) {
ScriptKind skind = cell.getStyle().get(StyleAttributes.SCRIPT_KIND);
switch (skind) {
case NORMAL:
floor2x = Math.max(floor2x, Math.max(floor1x, floor3x));
cell.setY(y + floor3);
cell.setX(floor2x);
floor2x += cell.getWidth();
floor3x = floor2x;
floor1x = floor2x;
break;
case SUBSCRIPT:
cell.setX(floor1x);
cell.setY(y + floor2 + floor3);
floor1x += cell.getWidth();
break;
case SUPERSCRIPT:
cell.setX(floor3x);
cell.setY(y);
floor3x += cell.getWidth();
break;
}
}
width = Math.max(floor2x, Math.max(floor1x, floor3x)) - x;
height = floor1 + floor2 + floor3;
editorCells.setWidth(width);
editorCells.setHeight(height);
}
@Override
public TextBuilder doLayoutText(Iterable<EditorCell> editorCells) {
TextBuilder result = new TextBuilderImpl();
for (EditorCell editorCell : editorCells) {
result.appendToTheBottom(editorCell.renderText());
}
return result;
}
@Override
public int getAscent(EditorCell_Collection editorCells) {
int floor2 = 0;
int floor3 = 0;
for (EditorCell cell : editorCells.getContentCells()) {
cell.relayout();
ScriptKind skind = cell.getStyle().get(StyleAttributes.SCRIPT_KIND);
switch (skind) {
case NORMAL:
floor2 = Math.max(floor2, cell.getAscent());
break;
case SUPERSCRIPT:
floor3 = Math.max(floor3, cell.getHeight());
break;
}
}
return floor3 + floor2;
}
@Override
public int getRightInternalInset(EditorCell_Collection editorCell_collection) {
return editorCell_collection.isEmpty() ? 0 : editorCell_collection.firstCell().getRightInset();
}
public String toString() {
return "Vertical";
}
}