X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.utils.ui%2Fsrc%2Forg%2Fsimantics%2Futils%2Fui%2Fcolor%2FColorGradientAdjustingCanvas.java;fp=bundles%2Forg.simantics.utils.ui%2Fsrc%2Forg%2Fsimantics%2Futils%2Fui%2Fcolor%2FColorGradientAdjustingCanvas.java;h=ea8983f3cf5028833b258750a8c9f694b7c09f3d;hp=0000000000000000000000000000000000000000;hb=bf75fd9740858140eac90c18f0bca0aea3893248;hpb=21f879fcd72d7749836fb64375094ef29573fe8c diff --git a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradientAdjustingCanvas.java b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradientAdjustingCanvas.java new file mode 100644 index 000000000..ea8983f3c --- /dev/null +++ b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradientAdjustingCanvas.java @@ -0,0 +1,258 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.utils.ui.color; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +/** + * + * Canvas that shows color gradients and color positions. + * Without READ_ONLY style the canvas allows user to drag color positions. + * + * @author Marko Luukkainen + * + */ +public class ColorGradientAdjustingCanvas extends ColorGradientCanvas implements ISelectionProvider{ + + ColorValue[] values; + int last; + int coords[]; + int size = 8; + int sized2 = 4; + int width; + int height; + + int selectedValueIndex = -1; + + public ColorGradientAdjustingCanvas(Composite parent, int style) { + super(parent,style|SWT.DOUBLE_BUFFERED|SWT.NO_BACKGROUND); + addMouseListener(new MouseListener() { + + @Override + public void mouseUp(MouseEvent e) { + + } + + @Override + public void mouseDown(MouseEvent e) { + // store and reset selection + int prev = selectedValueIndex; + selectedValueIndex = -1; + + // locate closest ColorValue, and select it. + int d = Integer.MAX_VALUE; + for (int i = 0; i <= last; i++) { + int x = coords[i*2]; + int y = coords[i*2+1]; + int dx = Math.abs(x - e.x); + int dy = Math.abs(y - e.y); + if ((dx < size) && + (dy < size)) { + int dd = dx+dy; + if (dd < d) { + selectedValueIndex = i; + d = dd; + } + } + } + // if selection was changed, update it. + if (prev != selectedValueIndex) { + updateSelection(); + redraw(); + } + } + + @Override + public void mouseDoubleClick(MouseEvent e) { + + } + }); + if ((style&SWT.READ_ONLY) == 0) { + addMouseMoveListener(new MouseMoveListener() { + + @Override + public void mouseMove(MouseEvent e) { + if ((e.stateMask & SWT.BUTTON1)>0) { + if (selectedValueIndex > 0 && selectedValueIndex < last) { + double d; + if ((ColorGradientAdjustingCanvas.this.style | SWT.HORIZONTAL) > 0) { + d = (double)e.x/(double)width; + } else { + d = (double)e.y/(double)height; + } + double r = max-min; + d *= r; + d += min; + double offset = r*0.015; + if (d <= values[selectedValueIndex-1].getValue()+offset) + d = values[selectedValueIndex-1].getValue()+offset; + else if (d >= values[selectedValueIndex+1].getValue()-offset) + d = values[selectedValueIndex+1].getValue()-offset; + values[selectedValueIndex]._setValue(d); + calculateCoords(width, height); + redraw(); + } + } + + } + }); + } + + } + + public void setGradient(ColorGradient gradient) { + int prevSize = 0; + if (values != null) + prevSize = values.length; + + values = gradient.getColorValueArray(); + last = values.length-1; + coords = new int[values.length*2]; + super.setGradient(gradient); + if (selectedValueIndex >= 0 && prevSize != values.length) { + selectedValueIndex = -1; + updateSelection(); + } else { + updateSelection(); + } + } + + double min; + double max; + + private void calculateCoords(int width, int height) { + this.width = width; + this.height = height; + + min = values[0].getValue(); + max = values[last].getValue(); + + if ((ColorGradientAdjustingCanvas.this.style & SWT.HORIZONTAL) > 0) { + for (int i = 0; i <= last ; i++) { + int y = height / 2; + double d = values[i].getValue(); + int x = (int)(((d-min)/(max-min))*(double)width); + coords[i*2] = x; + coords[i*2+1] = y; + } + } else { + for (int i = 0; i <= last ; i++) { + int x = width / 2; + double d = values[i].getValue(); + int y = (int)(((d-min)/(max-min))*(double)height); + coords[i*2] = x; + coords[i*2+1] = y; + } + } + } + + + @Override + protected void paintGradient(GC gc, Rectangle clip) { + if (values != null && values.length > 0) { + Image image = gradient.getGradientImage(clip.width,clip.height,ColorGradientAdjustingCanvas.this.style); + gc.drawImage(image, 0, 0); + image.dispose(); + calculateCoords(clip.width, clip.height); + + Color white = new Color(gc.getDevice(), 255,255,255); + Color yellow = new Color(gc.getDevice(), 255,230,0); + Color black = new Color(gc.getDevice(), 0, 0, 0); + for (int i = 0; i <= last ; i++) { + int x = coords[i*2]; + int y = coords[i*2+1]; + gc.setForeground(black); + if (selectedValueIndex == i) + gc.setBackground(yellow); + else + gc.setBackground(white); + if (i == 0 || i == last ) { + gc.fillRectangle(x-sized2, y-sized2, size, size); + gc.drawRectangle(x-sized2, y-sized2, size, size); + } else { + gc.fillOval(x-sized2, y-sized2, size, size); + gc.drawOval(x-sized2, y-sized2, size, size); + } + } + + white.dispose(); + black.dispose(); + yellow.dispose(); + } else { + gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + gc.fillRectangle(clip); + } + } + + private ISelection selection = new StructuredSelection(); + private List listeners = new ArrayList<>(); + + @Override + public void addSelectionChangedListener(ISelectionChangedListener listener) { + listeners.add(listener); + } + + @Override + public ISelection getSelection() { + return selection; + } + + @Override + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + listeners.remove(listener); + } + + @Override + public void setSelection(ISelection selection) { + ColorValue value = (ColorValue)((StructuredSelection)selection).getFirstElement(); + selectedValueIndex = gradient.getColorValues().indexOf(value); + } + + private void updateSelection() { + if (selectedValueIndex < 0) + selection = new StructuredSelection(); + else + selection = new StructuredSelection(values[selectedValueIndex]); + + for (ISelectionChangedListener l : listeners) { + l.selectionChanged(new SelectionChangedEvent(this, selection)); + } + } + + public int getPointSize() { + return size; + } + + public void setPointSize(int size) { + this.size = size; + this.sized2 = size/2; + } + + +}