/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.grammarbased.ui.figures;
import org.whole.lang.iterators.IEntityIterator;
import org.whole.lang.iterators.IteratorFactory;
import org.whole.lang.matchers.Matcher;
import org.whole.lang.model.IEntity;
import org.whole.lang.reflect.EntityDescriptorEnum;
import org.whole.lang.reflect.FeatureDescriptorEnum;
import org.whole.lang.reflect.ILanguageKit;
import org.whole.lang.ui.figures.CompositeFigure;
import org.whole.lang.ui.figures.CompositePlaceHolderBorder;
import org.whole.lang.ui.figures.ContentPaneFigure;
import org.whole.lang.ui.figures.EntityFigure;
import org.whole.lang.ui.figures.EntityLabel;
import org.whole.lang.ui.figures.IEntityFigure;
import org.whole.lang.ui.figures.LabelFactory;
import org.whole.lang.ui.figures.StringSeparatedCompositeColumnFigure;
import org.whole.lang.ui.figures.StringSeparatedCompositeRowFigure;
import org.whole.lang.ui.figures.TableFigure;
import org.whole.lang.ui.layout.Alignment;
import org.whole.lang.ui.layout.ColumnLayout;
import org.whole.lang.ui.layout.ICompositeEntityLayout;
import org.whole.lang.ui.layout.RowLayout;
import org.whole.lang.ui.layout.StackLayout;
import org.whole.lang.util.DataTypeUtils;
import org.whole.lang.util.EntityUtils;
import org.whole.lang.util.StringUtils;
/**
* @author Enrico Persiani
*/
public class GrammarBasedUIUtils {
public static IEntityFigure createSequenceFigure(IEntity entity, ContentPaneFigure contentPaneFigure, boolean embed) {
FeatureDescriptorEnum fdEnum = entity.wGetLanguageKit().getFeatureDescriptorEnum();
IEntity multiline = entity.wGet(fdEnum.valueOf("multiline"));
ICompositeEntityLayout layout = EntityUtils.safeBooleanValue(multiline, false) ?
new ColumnLayout() : new RowLayout();
//TODO complete optional behavior
IEntity optional = entity.wGet(fdEnum.valueOf("optional"));
IEntityFigure figure;
if (embed) {
contentPaneFigure.setLayoutManager(layout.withSpacing(5));
figure = contentPaneFigure;
} else
figure = new EntityFigure(layout.withSpacing(5));
IEntity childFigures = entity.wGet(fdEnum.valueOf("figures"));
for (int i=0, size=childFigures.wSize(); i<size; i++)
addChildFigure(childFigures.wGet(i), contentPaneFigure, figure);
return figure;
}
public static IEntityFigure createTerminalFigure(IEntity entity) {
FeatureDescriptorEnum fdEnum = entity.wGetLanguageKit().getFeatureDescriptorEnum();
IEntity category = entity.wGet(fdEnum.valueOf("category"));
IEntity literal = entity.wGet(fdEnum.valueOf("literal"));
EntityLabel label = createEntityLabel(category);
label.setText(StringUtils.unescapeString(DataTypeUtils.getAsPresentationString(literal)));
return label;
}
public static IEntityFigure createIndent() {
return new EntityFigure(new StackLayout().withMarginLeft(32 - 5));
}
public static IEntityFigure createNonTerminalFigure(IEntity entity, ContentPaneFigure contentPaneFigure) {
int i=0, size=contentPaneFigure.getContentPanesSize();
for (; i<size; i++)
if (contentPaneFigure.getContentPane(i) == null)
break;
return (IEntityFigure) (contentPaneFigure instanceof CompositeEntityFigure ?
contentPaneFigure.createContentPane(i, createCompositeFigure(entity)) :
contentPaneFigure.createContentPane(i));
}
public static void addChildFigure(IEntity entity, ContentPaneFigure contentPaneFigure, IEntityFigure parent) {
addChildFigure(entity, contentPaneFigure, parent, false);
}
public static void addChildFigure(IEntity entity, ContentPaneFigure contentPaneFigure, IEntityFigure parent, boolean embed) {
if (!EntityUtils.isNotResolver(entity))
return;
String edName = entity.wGetEntityDescriptor().getName();
if ("SequenceFigure".equals(edName)) {
IEntityFigure child = createSequenceFigure(entity, contentPaneFigure, embed);
if (!embed)
parent.add(child);
}
else if ("NonTerminalFigure".equals(edName))
parent.add(createNonTerminalFigure(entity, contentPaneFigure));
else if ("TerminalFigure".equals(edName))
parent.add(createTerminalFigure(entity));
else if ("Indent".equals(edName))
parent.add(createIndent());
}
public static EntityLabel createEntityLabel(IEntity entity) {
String category = DataTypeUtils.getAsPresentationString(entity);
EntityLabel label = null;
if ("KEYWORD".equals(category))
label = LabelFactory.createKeyword();
else if ("DELIMITER".equals(category))
label = LabelFactory.createLiteral();
else if ("IDENTIFIER".equals(category))
label = LabelFactory.createIdentifier();
else if ("LITERAL".equals(category))
label = LabelFactory.createContent();
else if ("OPERATOR".equals(category))
label = LabelFactory.createContentLight();
else if ("PARENTHESIS".equals(category))
label = LabelFactory.createContentLighter();
else if ("SEPARATOR".equals(category))
label = LabelFactory.createLiteral();//FIXME missing label category
return label;
}
public static String calculateSeparator(IEntity entity) {
EntityDescriptorEnum edEnum = entity.wGetLanguageKit().getEntityDescriptorEnum();
StringBuilder sb = new StringBuilder();
IEntityIterator<IEntity> iterator = IteratorFactory.descendantOrSelfMatcherIterator().withPattern(edEnum.valueOf("Literal"));
iterator.reset(entity);
while (iterator.hasNext())
sb.append(EntityUtils.safeStringValue(iterator.next(), ""));
String separatorText = sb.toString();
return separatorText.trim();
}
public static IEntityFigure createCompositeFigure(IEntity entity) {
ILanguageKit lk = entity.wGetLanguageKit();
EntityDescriptorEnum edEnum = lk.getEntityDescriptorEnum();
FeatureDescriptorEnum fdEnum = lk.getFeatureDescriptorEnum();
IEntity configuration = Matcher.findAncestor(edEnum.valueOf("CompositePart"), entity);
IEntity multiline = configuration.wGet(fdEnum.valueOf("multiline"));
boolean isMultiline = EntityUtils.safeBooleanValue(multiline, false);
IEntity columns = configuration.wGet(fdEnum.valueOf("columns"));
int columnsNum = EntityUtils.safeIntValue(columns, 0);
IEntity separator = configuration.wGet(fdEnum.valueOf("separator"));
IEntityFigure entityFigure;
if (EntityUtils.isNotResolver(separator)) {
String separatorText = GrammarBasedUIUtils.calculateSeparator(separator);
CompositeFigure compositeFigure = isMultiline ? new StringSeparatedCompositeColumnFigure(separatorText, 10) :
new StringSeparatedCompositeRowFigure(separatorText, 10);
if (isMultiline)
compositeFigure.getLayoutManager().withMinorAlignment(Alignment.LEADING);
entityFigure = compositeFigure;
} else if (columnsNum > 0) {
TableFigure tableFigure = new TableFigure(columnsNum);
tableFigure.setBorder(CompositePlaceHolderBorder.OPTIONAL_VERTICAL);
entityFigure = tableFigure;
} else
entityFigure = new CompositeFigure(!isMultiline, true);
return entityFigure;
}
}