blob: 97e70ddba4ef5b763670cec461c624032cab0210 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2013, 2019 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.rtm.base.ui.rexpr;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.statet.jcommons.text.core.input.StringParserInput;
import org.eclipse.statet.ecommons.ui.components.ObjValueEvent;
import org.eclipse.statet.ltk.ast.core.AstInfo;
import org.eclipse.statet.r.core.model.RGraphicFunctions;
import org.eclipse.statet.r.core.rsource.ast.RScanner;
import org.eclipse.statet.r.ui.graphics.RFontFamilyChooser;
import org.eclipse.statet.rtm.base.ui.RtModelUIPlugin;
import org.eclipse.statet.rtm.base.ui.rexpr.RExprWidget.TypeDef;
import org.eclipse.statet.rtm.rtdata.types.RTypedExpr;
public class FontFamilyType extends TypeDef implements PaintListener, Listener {
private Button detail;
private String currentValue;
private String currentFontName;
private Font currentSWTFont;
private RFontFamilyChooser fontChooser;
private final RGraphicFunctions rGraphicFunctions= RGraphicFunctions.DEFAULT;
public FontFamilyType(final RExprTypeUIAdapter type) {
super(type);
}
@Override
public boolean hasDetail() {
return true;
}
@Override
protected Control createDetailControl(final Composite parent) {
this.detail= new Button(parent, SWT.NONE);
this.detail.addPaintListener(this);
this.detail.addListener(SWT.Selection, this);
this.detail.addListener(SWT.Dispose, this);
return this.detail;
}
@Override
public void valueAboutToChange(final ObjValueEvent<RTypedExpr> event) {
final RTypedExpr newExpr= event.newValue;
String newValue= null;
try {
if (newExpr != null && newExpr.getTypeKey() == RTypedExpr.R) {
final RScanner scanner= new RScanner(AstInfo.LEVEL_MODEL_DEFAULT);
newValue= this.rGraphicFunctions.parseFontFamily(scanner.scanExpr(
new StringParserInput(newExpr.getExpr()).init() ));
}
}
catch (final Exception e) {
StatusManager.getManager().handle(new Status(IStatus.ERROR, RtModelUIPlugin.BUNDLE_ID,
"An error occurred when parsing the R font family value expression.", e ));
}
doSetValue(newValue);
this.detail.redraw();
}
@Override
public void paintControl(final PaintEvent e) {
final GC gc= e.gc;
final Point size= this.detail.getSize();
gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_DARK_GRAY));
gc.drawRectangle(4, 4, size.x - 9, size.y - 9);
if (this.currentFontName != null && !this.currentFontName.isEmpty()) {
if (this.currentSWTFont == null) {
this.currentSWTFont= RFontFamilyChooser.createFont(this.detail.getDisplay(), this.currentFontName,
this.detail.getFont().getFontData()[0].getHeight() );
if (this.currentSWTFont == null) {
this.currentFontName= ""; //$NON-NLS-1$
}
}
RFontFamilyChooser.drawPreview(gc, 5, 5, size.x - 11, size.y - 11, this.currentSWTFont);
}
}
@Override
public void handleEvent(final Event event) {
switch (event.type) {
case SWT.Selection:
showColorChooser();
return;
case SWT.Dispose:
if (this.fontChooser != null) {
this.fontChooser.dispose();
}
if (this.currentSWTFont != null) {
this.currentSWTFont.dispose();
this.currentSWTFont= null;
}
return;
default:
break;
}
}
private void showColorChooser() {
if (this.fontChooser == null) {
this.fontChooser= new RFontFamilyChooser() {
@Override
protected void onOK() {
FontFamilyType.this.setValue(getValue());
}
};
}
if (this.fontChooser.isActive()) {
this.fontChooser.close();
return;
}
final Rectangle bounds= this.detail.getBounds();
{ final Point location= this.detail.getParent().toDisplay(new Point(bounds.x, bounds.y));
bounds.x= location.x;
bounds.y= location.y;
}
this.fontChooser.open(this.detail.getShell(), bounds, this.currentValue);
}
private void setValue(final String value) {
if (value == null) {
setExpr(""); //$NON-NLS-1$
return;
}
final StringBuilder sb= new StringBuilder();
sb.append('"');
sb.append(value);
sb.append('"');
doSetValue(value);
this.detail.redraw();
setExpr(sb.toString());
}
private void doSetValue(final String value) {
final String fontName= RFontFamilyChooser.getFontName(value);
if (this.currentSWTFont != null && !this.currentFontName.equals(fontName)) {
this.currentSWTFont.dispose();
this.currentSWTFont= null;
}
this.currentValue= value;
this.currentFontName= fontName;
}
}