blob: 55f2ad3d271b0a03fd108d1e4d1e96be05bd7421 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 - 2005 University Of British Columbia and others.
* 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:
* University Of British Columbia - initial API and implementation
*******************************************************************************/
package org.eclipse.mylar.ui.internal.views;
import java.util.*;
import org.eclipse.mylar.core.IMylarElement;
import org.eclipse.mylar.core.MylarPlugin;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
/**
* @author Mik Kersten
*/
public class Highlighter {
private final int NUM_LEVELS = 40;
private final List<Color> ELEVATIONS = new ArrayList<Color>();
private String name;
private Color core;
private Color landmarkColor;
private Color highlightColor;
private Color black = new Color(Display.getCurrent(), 0, 0, 0);
private Color base = new Color(Display.getCurrent(), 255, 255, 255);
private boolean isGradient;
private boolean isIntersection;
public boolean isIntersection() {
return isIntersection;
}
public void setIntersection(boolean isIntersection) {
this.isIntersection = isIntersection;
}
public Highlighter(String name, Color coreColor, boolean isGradient) {
this.name = name;
this.core = coreColor;
this.isGradient = isGradient;
initializeGradients();
initializeHighlight();
if (!isGradient) {
this.landmarkColor = coreColor;
} else {
initializeLandmark();
}
}
public Highlighter(String attributes) {
this.initializeFromString(attributes);
initializeGradients();
initializeHighlight();
if (!isGradient) {
this.landmarkColor = highlightColor;
} else {
initializeLandmark();
}
}
public Color getHighlightColor() {
return highlightColor;
}
public Color getLandmarkColor() {
return landmarkColor;
}
public Color getHighlight(IMylarElement info, boolean isLandmark) {
if (info.getInterest().getValue() > 0) {
if (isLandmark) {
return landmarkColor;
} else {
if (isGradient) {
return mapDoiToElevation(info);
} else {
return highlightColor;
}
}
} else {
return base;
}
}
public Color mapDoiToElevation(IMylarElement info) {
if (info == null)
return base;
if (info.getInterest().getValue() < 0)
return highlightColor;
int step = 2;
Color color = base;
for (Iterator<Color> it = ELEVATIONS.iterator(); it.hasNext();) {
color = it.next();
if (info.getInterest().getValue() < step)
return color;
step += 2;
}
return color; // darkest color supported
// return landmarkColor;
}
private void initializeHighlight() {
try {
int redStep = (int) Math.ceil((core.getRed() + 2 * base.getRed()) / 3);
int greenStep = (int) Math.ceil((core.getGreen() + 2 * base.getGreen()) / 3);
int blueStep = (int) Math.ceil((core.getBlue() + 2 * base.getBlue()) / 3);
highlightColor = new Color(Display.getDefault(), redStep, greenStep, blueStep);
} catch (Throwable t) {
MylarPlugin.log(t, "highlighter init failed");
}
}
private void initializeLandmark() {
try {
int redStep = (int) Math.ceil((2 * core.getRed() + black.getRed()) / 3);
int greenStep = (int) Math.ceil((2 * core.getGreen() + black.getGreen()) / 3);
int blueStep = (int) Math.ceil((2 * core.getBlue() + black.getBlue()) / 3);
landmarkColor = new Color(Display.getDefault(), redStep, greenStep, blueStep);
} catch (Throwable t) {
MylarPlugin.log(t, "landmark init failed");
}
}
private void initializeGradients() {
try {
int redStep = (int) Math.ceil((core.getRed() - base.getRed()) / NUM_LEVELS);
int greenStep = (int) Math.ceil((core.getGreen() - base.getGreen()) / NUM_LEVELS);
int blueStep = (int) Math.ceil((core.getBlue() - base.getBlue()) / NUM_LEVELS);
int OFFSET = 5;
int red = base.getRed() + redStep*OFFSET;
int green = base.getGreen() + greenStep*OFFSET;
int blue = base.getBlue() + blueStep*OFFSET;
for (int i = 0; i < NUM_LEVELS - OFFSET; i++) {
if (red > 255)
red = 255; // TODO: fix this mess
if (green > 255)
green = 255;
if (blue > 255)
blue = 255;
if (red < 0)
red = 0;
if (green < 0)
green = 0;
if (blue < 0)
blue = 0;
ELEVATIONS.add(new Color(Display.getDefault(), red, green, blue));
red += redStep;
blue += blueStep;
green += greenStep;
}
} catch (Throwable t) {
MylarPlugin.log(t, "gradients failed");
}
}
@Override
public String toString() {
return name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Color getBase() {
return base;
}
public void setBase(Color base) {
this.base = base;
}
public static Color blend(List<Highlighter> highlighters, IMylarElement info, boolean isLandmark) {
int red = 0;
int green = 0;
int blue = 0;
int num = highlighters.size();
for (Iterator<Highlighter> it = highlighters.iterator(); it.hasNext();) {
Highlighter highlighter = it.next();
Color color = highlighter.getHighlight(info, isLandmark);
red += color.getRed();
green += color.getGreen();
blue += color.getBlue();
}
return new Color(Display.getDefault(), red / num, green / num, blue / num);
}
public boolean isGradient() {
return isGradient;
}
public void setGradient(boolean isGradient) {
this.isGradient = isGradient;
}
public Color getCore() {
return core;
}
public void setCore(Color core) {
this.core = core;
this.initializeGradients();
this.initializeHighlight();
this.initializeLandmark();
}
public String getType() {
String res = "";
if (this.isGradient) {
res = new String("Gradient");
} else if (this.isIntersection) {
res = new String("Intersection");
} else {
res = new String("Solid");
}
return res;
}
public String externalizeToString() {
String result = new String();
Integer r = new Integer(this.core.getRed());
Integer g = new Integer(this.core.getGreen());
Integer b = new Integer(this.core.getBlue());
result = r.toString() + ";" + g.toString() + ";" + b.toString() + ";" + this.name + ";" + this.getType();
return result;
}
private void initializeFromString(String attributes) {
String[] data = attributes.split(";");
Integer r = new Integer(data[0]);
Integer g = new Integer(data[1]);
Integer b = new Integer(data[2]);
this.core = new Color(Display.getCurrent(), r.intValue(), g.intValue(), b.intValue());
this.name = data[3];
if (data[4].compareTo("Gradient") == 0) {
this.isGradient = true;
this.isIntersection = false;
} else if (data[4].compareTo("Intersection") == 0) {
this.isGradient = false;
this.isIntersection = true;
} else {
this.isGradient = false;
this.isIntersection = false;
}
}
}