blob: 38e27629436077a965bbac779f224634f32616a5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016, 2018 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors: Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.eef.ide.ui.api.widgets;
import java.util.Iterator;
import java.util.List;
import org.eclipse.eef.EEFConditionalStyle;
import org.eclipse.eef.EEFWidgetDescription;
import org.eclipse.eef.EEFWidgetStyle;
import org.eclipse.eef.common.api.utils.Util;
import org.eclipse.eef.core.api.utils.EvalFactory;
import org.eclipse.eef.ide.ui.internal.widgets.styles.EEFColor;
import org.eclipse.eef.ide.ui.internal.widgets.styles.EEFFont;
import org.eclipse.eef.util.EEFConditionalStyleToWidgetStyleSwitch;
import org.eclipse.eef.util.EEFDescriptionToConditionalStylesSwitch;
import org.eclipse.eef.util.EEFDescriptionToWidgetStyleSwitch;
import org.eclipse.emf.ecore.util.Switch;
import org.eclipse.sirius.common.interpreter.api.IInterpreter;
import org.eclipse.sirius.common.interpreter.api.IVariableManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
/**
* This utility class contains various helper method to manipulate styles.
*
* @author sbegaudeau
*/
public class EEFStyleHelper {
/**
* The interpreter.
*/
private IInterpreter interpreter;
/**
* The variable manager.
*/
private IVariableManager variableManager;
/**
* The constructor.
*
* @param interpreter
* The interpreter
* @param variableManager
* The variable manager
*/
public EEFStyleHelper(IInterpreter interpreter, IVariableManager variableManager) {
this.interpreter = interpreter;
this.variableManager = variableManager;
}
/**
* Returns the widget style to use from the given widget description.
*
* @param widgetDescription
* The widget description
* @return The widget style to use
*/
public EEFWidgetStyle getWidgetStyle(EEFWidgetDescription widgetDescription) {
EEFWidgetStyle widgetStyle = null;
List<EEFConditionalStyle> conditionalStyles = this.getDescriptionToConditionalStylesSwitch().doSwitch(widgetDescription);
Iterator<EEFConditionalStyle> iterator = conditionalStyles.iterator();
while (widgetStyle == null && iterator.hasNext()) {
EEFConditionalStyle conditionalStyle = iterator.next();
String preconditionExpression = conditionalStyle.getPreconditionExpression();
Boolean preconditionValid = EvalFactory.of(interpreter, variableManager).logIfInvalidType(Boolean.class).evaluate(preconditionExpression);
if (preconditionValid != null && preconditionValid.booleanValue()) {
widgetStyle = this.getConditionalStyleToWidgetStyleSwitch().doSwitch(conditionalStyle);
}
}
if (widgetStyle == null) {
widgetStyle = this.getDescriptionToWidgetStyleSwitch().doSwitch(widgetDescription);
}
return widgetStyle;
}
/**
* Returns the switch to use to find the conditional styles of a widget description. The switch returned should be
* able to handle the default use case, as a result it is highly recommended to return a composed switch with the
* default one and new switches. Example:<br>
* <code>
* return new ComposedSwitch<>(Arrays.asList(new EEFDescriptionToConditionalStylesSwitch(), new
* CustomDescriptionToConditionalStylesSwitch()));
* </code>
*
* @return The switch to use to find the conditional styles of a widget description
*/
protected Switch<List<EEFConditionalStyle>> getDescriptionToConditionalStylesSwitch() {
return new EEFDescriptionToConditionalStylesSwitch();
}
/**
* Returns the switch to use to find the style of a conditional style. The switch returned should be able to handle
* the default use case, as a result it is highly recommended to return a composed switch with the default one and
* new switches. Example:<br>
* <code>
* return new ComposedSwitch<>(Arrays.asList(new EEFConditionalStyleToWidgetStyleSwitch(), new
* CustomConditionalStyleToWidgetStyleSwitch()));
* </code>
*
* @return The switch to use to find the style of a conditional style
*/
protected Switch<EEFWidgetStyle> getConditionalStyleToWidgetStyleSwitch() {
return new EEFConditionalStyleToWidgetStyleSwitch();
}
/**
* Returns the switch to use to find the style of a description. The switch returned should be able to handle the
* default use case, as a result it is highly recommended to return a composed switch with the default one and new
* switches. Example:<br>
* <code>
* return new ComposedSwitch<>(Arrays.asList(new EEFDescriptionToWidgetStyleSwitch(), new
* EEFDescriptionToWidgetStyleSwitch()));
* </code>
*
* @return The switch to use to find the style of a description.
*/
protected Switch<EEFWidgetStyle> getDescriptionToWidgetStyleSwitch() {
return new EEFDescriptionToWidgetStyleSwitch();
}
/**
* Uses the given expressions to update the style using the given callback.
*
* @param fontNameExpression
* The expression used to compute the name of the font
* @param fontSizeExpression
* The expression used to compute the size of the font
* @param fontStyleExpression
* The expression used to compute the style of the font
* @param defaultFont
* The default font
* @param backgroundColorExpression
* The expression used to compute the background color of the font
* @param foregroundColorExpression
* The expression used to compute the foreground color of the font
* @param callback
* The callback which will be called when a property of the style has been computed
*/
public void applyTextStyle(String fontNameExpression, String fontSizeExpression, String fontStyleExpression, Font defaultFont,
String backgroundColorExpression, String foregroundColorExpression, IEEFTextStyleCallback callback) {
if (!Util.isBlank(foregroundColorExpression)) {
this.applyForegroundColor(foregroundColorExpression, callback);
} else {
callback.applyForegroundColor(new EEFColor((Color) null));
}
if (!Util.isBlank(backgroundColorExpression)) {
this.applyBackgroundColor(backgroundColorExpression, callback);
} else {
callback.applyBackgroundColor(new EEFColor((Color) null));
}
String fontStyleValue = EvalFactory.of(interpreter, variableManager).logIfInvalidType(String.class).evaluate(fontStyleExpression);
this.applyFont(fontNameExpression, fontSizeExpression, defaultFont, callback, fontStyleValue);
this.applyFontStyle(callback, fontStyleValue);
}
/**
* Applies the foreground color computed using the given foreground color expression.
*
* @param foregroundColorExpression
* The expression
* @param callback
* The callback
*/
private void applyForegroundColor(String foregroundColorExpression, IEEFTextStyleCallback callback) {
String foregroundColorCode = EvalFactory.of(interpreter, variableManager).logIfInvalidType(String.class).evaluate(foregroundColorExpression);
if (!Util.isBlank(foregroundColorCode)) {
callback.applyForegroundColor(new EEFColor(foregroundColorCode));
}
}
/**
* Applies the background color computed using the given background color expression.
*
* @param backgroundColorExpression
* The expression
* @param callback
* The callback
*/
private void applyBackgroundColor(String backgroundColorExpression, IEEFTextStyleCallback callback) {
String backgroundColorCode = EvalFactory.of(interpreter, variableManager).logIfInvalidType(String.class).evaluate(backgroundColorExpression);
if (!Util.isBlank(backgroundColorCode)) {
callback.applyBackgroundColor(new EEFColor(backgroundColorCode));
}
}
/**
* Applies the font computed using the given expressions.
*
* @param fontNameExpression
* The expression used to compute the name of the font
* @param fontSizeExpression
* The expression used to compute the size of the font
* @param defaultFont
* The default font
* @param callback
* The callback
* @param fontStyleValue
* The value of the font style (strikeout and/or underline)
*/
private void applyFont(String fontNameExpression, String fontSizeExpression, Font defaultFont, IEEFTextStyleCallback callback,
String fontStyleValue) {
FontData defaultFontData = defaultFont.getFontData()[0];
String fontName = EvalFactory.of(interpreter, variableManager).logIfInvalidType(String.class).defaultValue(defaultFontData.getName())
.evaluate(fontNameExpression);
int fontSize = EvalFactory.of(interpreter, variableManager).logIfInvalidType(Integer.class)
.defaultValue(Integer.valueOf(defaultFontData.getHeight())).evaluate(fontSizeExpression).intValue();
int fontStyle = defaultFontData.getStyle();
if (fontStyleValue == null) {
fontStyle = 0;
} else if (fontStyleValue.contains("bold")) { //$NON-NLS-1$
fontStyle = fontStyle | SWT.BOLD;
} else if (fontStyleValue.contains("italic")) { //$NON-NLS-1$
fontStyle = fontStyle | SWT.ITALIC;
}
EEFFont font = new EEFFont(fontName, fontSize, fontStyle);
callback.applyFont(font);
}
/**
* Applies the font style (underline and/or strikeout).
*
* @param callback
* The callback
* @param fontStyleValue
* The font style value
*/
private void applyFontStyle(IEEFTextStyleCallback callback, String fontStyleValue) {
boolean strikeout = false;
boolean underline = false;
if (fontStyleValue != null && fontStyleValue.contains("underline")) { //$NON-NLS-1$
underline = true;
}
if (fontStyleValue != null && fontStyleValue.contains("strike_through")) { //$NON-NLS-1$
strikeout = true;
}
callback.applyFontStyle(strikeout, underline);
}
/**
* This class will be called to update the style of the text.
*
* @author sbegaudeau
*/
public interface IEEFTextStyleCallback {
/**
* Applies the given font to the widget.
*
* @param font
* The font
*/
void applyFont(EEFFont font);
/**
* Applies the strikeout and/or underline styles.
*
* @param strikeout
* <code>true</code> if the widget should be striked out, <code>false</code> otherwise
* @param underline
* <code>true</code> if the widget should be underlined, <code>false</code> otherwise
*/
void applyFontStyle(boolean strikeout, boolean underline);
/**
* Applies the given foreground color to the widget.
*
* @param color
* The foreground color
*/
void applyForegroundColor(EEFColor color);
/**
* Applies the given background color to the widget.
*
* @param color
* The background color
*/
void applyBackgroundColor(EEFColor color);
}
}