| /*=============================================================================# |
| # 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; |
| } |
| } |
| |
| } |