blob: 73be235d34ba84adec2e1cf6f67ce632df1a5057 [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 com.ibm.icu.text.DecimalFormat;
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.Color;
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.DoubleText;
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.RAlphaChooser;
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 AlphaType extends TypeDef implements PaintListener, Listener {
private Button detail;
private Float currentValue;
private int current255= -1;
private Color currentSWTColor;
private RAlphaChooser alphaChooser;
private final RGraphicFunctions rGraphicFunctions= RGraphicFunctions.DEFAULT;
public AlphaType(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;
Float newValue= null;
try {
if (newExpr != null && newExpr.getTypeKey() == RTypedExpr.R) {
final RScanner scanner= new RScanner(AstInfo.LEVEL_MODEL_DEFAULT);
newValue= this.rGraphicFunctions.parseAlpha(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 alpha 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.currentValue != null) {
if (this.currentSWTColor == null) {
this.currentSWTColor= new Color(this.detail.getDisplay(),
this.current255, this.current255, this.current255);
}
RAlphaChooser.drawPreview(gc, 5, 5, size.x - 11, size.y - 11, this.currentSWTColor);
}
}
@Override
public void handleEvent(final Event event) {
switch (event.type) {
case SWT.Selection:
showColorChooser();
return;
case SWT.Dispose:
if (this.alphaChooser != null) {
this.alphaChooser.dispose();
}
if (this.currentSWTColor != null) {
this.currentSWTColor.dispose();
this.currentSWTColor= null;
}
return;
default:
break;
}
}
private void showColorChooser() {
if (this.alphaChooser == null) {
this.alphaChooser= new RAlphaChooser() {
@Override
protected void onOK() {
AlphaType.this.setValue(getValue());
}
};
}
if (this.alphaChooser.isActive()) {
this.alphaChooser.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.alphaChooser.open(this.detail.getShell(), bounds, this.currentValue);
}
private void setValue(final Float value) {
if (value == null) {
setExpr(""); //$NON-NLS-1$
return;
}
final StringBuilder sb= new StringBuilder();
final DecimalFormat format= DoubleText.createFormat(3);
sb.append(format.format(value.doubleValue()));
doSetValue(value);
this.detail.redraw();
setExpr(sb.toString());
}
private void doSetValue(final Float value) {
if (value != null) {
final int v255= 255 - Math.round(value * 255);
if (this.currentSWTColor != null && v255 != this.current255) {
this.currentSWTColor.dispose();
this.currentSWTColor= null;
}
this.currentValue= value;
this.current255= v255;
}
else {
this.currentValue= null;
}
}
}