/******************************************************************************
* Copyright (c) 2011, 2016 Stephan Schwiebert 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:
* Stephan Schwiebert - initial API and implementation
*
*******************************************************************************/
package org.eclipse.gef.cloudio.internal.ui.view;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.Assert;
import org.eclipse.gef.cloudio.internal.ui.CloudioUiBundle;
import org.eclipse.gef.cloudio.internal.ui.TagCloudViewer;
import org.eclipse.gef.cloudio.internal.ui.Word;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FontDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
/**
* Provides options to modify the rendering of a {@link TagCloudViewer} using an
* {@link IEditableCloudLabelProvider}.
*
* @author sschwieb
*
*/
public class CloudOptionsComposite extends Composite {
protected TagCloudViewer viewer;
protected List<RGB> colors = new ArrayList<>();
protected List<FontData> fonts = new ArrayList<>();
protected List<List<RGB>> colorSchemes = new ArrayList<>();
protected int currentScheme;
private static class ListContentProvider implements ITreeContentProvider {
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
@Override
public Object[] getElements(Object inputElement) {
return ((List<?>) inputElement).toArray();
}
@Override
public Object[] getChildren(Object parentElement) {
return null;
}
@Override
public Object getParent(Object element) {
return null;
}
@Override
public boolean hasChildren(Object element) {
return false;
}
}
public CloudOptionsComposite(Composite parent, int style, TagCloudViewer viewer) {
super(parent, style);
Assert.isLegal(viewer.getLabelProvider() instanceof IEditableCloudLabelProvider,
"Cloud label provider must be of type " + IEditableCloudLabelProvider.class);
this.viewer = viewer;
setLayout(new GridLayout());
addGroups();
}
protected void addGroups() {
addLayoutButtons(this);
addColorButtons(this);
addFontButtons(this);
}
protected void addScheme(RGB... rgbs) {
List<RGB> colors = new ArrayList<>();
for (RGB rgb : rgbs) {
colors.add(rgb);
}
colorSchemes.add(colors);
}
protected void updateColors() {
IEditableCloudLabelProvider lp = (IEditableCloudLabelProvider) viewer.getLabelProvider();
lp.setColors(colors);
List<Word> words = viewer.getCloud().getWords();
for (Word word : words) {
word.setColor(lp.getColor(word.data));
}
viewer.getCloud().redrawTextLayerImage();
}
protected void updateFonts() {
IEditableCloudLabelProvider lp = (IEditableCloudLabelProvider) viewer.getLabelProvider();
lp.setFonts(fonts);
}
protected void initColors() {
addScheme(new RGB(222, 177, 17), new RGB(97, 28, 24), new RGB(102, 109, 17), new RGB(189, 112, 20),
new RGB(111, 92, 16), new RGB(111, 32, 27));
addScheme(new RGB(1, 175, 255), new RGB(57, 99, 213), new RGB(21, 49, 213), new RGB(30, 125, 42));
addScheme(new RGB(255, 92, 93), new RGB(255, 0, 0), new RGB(255, 41, 43), new RGB(182, 31, 32),
new RGB(153, 0, 0));
addScheme(new RGB(255, 157, 0), new RGB(255, 206, 0), new RGB(40, 0, 159), new RGB(0, 41, 156));
addScheme(new RGB(255, 46, 0), new RGB(255, 255, 14), new RGB(183, 183, 183), new RGB(122, 122, 122),
new RGB(81, 81, 81), new RGB(61, 61, 61), new RGB(165, 165, 165));
addScheme(new RGB(255, 0, 206), new RGB(255, 220, 0), new RGB(0, 255, 42));
addScheme(new RGB(89, 79, 69), new RGB(168, 165, 126), new RGB(68, 49, 14), new RGB(86, 68, 34),
new RGB(148, 141, 129), new RGB(92, 90, 41));
addScheme(new RGB(66, 71, 37), new RGB(85, 122, 18), new RGB(117, 131, 49), new RGB(49, 45, 17));
addScheme(new RGB(254, 213, 44), new RGB(255, 177, 10), new RGB(233, 121, 0), new RGB(229, 109, 3),
new RGB(202, 80, 8), new RGB(129, 52, 7), new RGB(89, 47, 14));
addScheme(new RGB(139, 124, 115), new RGB(91, 95, 129), new RGB(50, 23, 18), new RGB(255, 251, 237));
nextColors();
}
protected void nextColors() {
currentScheme = (currentScheme + 1) % colorSchemes.size();
colors = colorSchemes.get(currentScheme);
}
protected Group addFontButtons(final Composite parent) {
Group buttons = new Group(parent, SWT.SHADOW_IN);
buttons.setLayout(new GridLayout(2, false));
buttons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
Label l = new Label(buttons, SWT.NONE);
l.setText("Fonts");
GridData gd = new GridData();
gd.horizontalSpan = 2;
l.setLayoutData(gd);
final TreeViewer tv = new TreeViewer(buttons);
Composite comp = new Composite(buttons, SWT.NONE);
comp.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, true));
comp.setLayout(new RowLayout(SWT.VERTICAL));
tv.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
ListContentProvider cp = new ListContentProvider();
tv.setContentProvider(cp);
tv.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
FontData fd = (FontData) element;
return fd.getName();
}
});
fonts.add(getFont().getFontData()[0]);
tv.setInput(fonts);
Button add = new Button(comp, SWT.FLAT);
add.setImage(CloudioUiBundle.getDefault().getImageRegistry().get(CloudioUiBundle.ADD));
add.setToolTipText("Add font...");
add.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
FontDialog fd = new FontDialog(parent.getShell());
FontData fontData = fd.open();
if (fontData != null) {
fonts.add(fontData);
tv.setInput(fonts);
updateFonts();
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
Button remove = new Button(comp, SWT.FLAT);
remove.setToolTipText("Remove selected fonts");
remove.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
IStructuredSelection selection = (IStructuredSelection) tv.getSelection();
fonts.removeAll(selection.toList());
tv.setInput(fonts);
updateFonts();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
remove.setImage(CloudioUiBundle.getDefault().getImageRegistry().get(CloudioUiBundle.REMOVE));
return buttons;
}
protected Image createImageFromColor(RGB rgb, int size) {
Image image;
Color color = new Color(Display.getDefault(), rgb);
image = new Image(Display.getDefault(), size, size);
GC gc = new GC(image);
gc.setBackground(color);
gc.fillRoundRectangle(0, 0, size, size, 3, 3);
color.dispose();
gc.dispose();
return image;
}
protected Group addColorButtons(final Composite parent) {
Group buttons = new Group(parent, SWT.SHADOW_IN);
buttons.setLayout(new GridLayout(2, false));
buttons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
Label l = new Label(buttons, SWT.NONE);
l.setText("Colors");
GridData gd = new GridData();
gd.horizontalSpan = 2;
l.setLayoutData(gd);
final TreeViewer tv = new TreeViewer(buttons);
Composite comp = new Composite(buttons, SWT.NONE);
comp.setLayout(new RowLayout(SWT.VERTICAL));
comp.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, true));
tv.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
ListContentProvider cp = new ListContentProvider();
tv.setContentProvider(cp);
tv.setLabelProvider(new ColumnLabelProvider() {
private Map<Object, Image> images = new HashMap<>();
@Override
public Image getImage(Object element) {
Image image = images.get(element);
if (image == null) {
RGB rgb = (RGB) element;
image = createImageFromColor(rgb, 24);
images.put(element, image);
}
return image;
}
@Override
public void dispose() {
Collection<Image> images = this.images.values();
for (Image image : images) {
image.dispose();
}
this.images.clear();
}
});
initColors();
tv.setInput(colors);
Button add = new Button(comp, SWT.FLAT);
add.setImage(CloudioUiBundle.getDefault().getImageRegistry().get(CloudioUiBundle.ADD));
add.setToolTipText("Add color...");
add.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
ColorDialog cd = new ColorDialog(parent.getShell());
RGB color = cd.open();
if (color != null) {
colors.add(color);
tv.setInput(colors);
updateColors();
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
Button remove = new Button(comp, SWT.FLAT);
remove.setToolTipText("Remove selected colors");
remove.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
IStructuredSelection selection = (IStructuredSelection) tv.getSelection();
colors.removeAll(selection.toList());
tv.setInput(colors);
updateColors();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
remove.setImage(CloudioUiBundle.getDefault().getImageRegistry().get(CloudioUiBundle.REMOVE));
Button toggle = new Button(comp, SWT.FLAT);
toggle.setToolTipText("Toggle Colors");
toggle.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
nextColors();
tv.setInput(colors);
updateColors();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
toggle.setImage(CloudioUiBundle.getDefault().getImageRegistry().get(CloudioUiBundle.TOGGLE_COLORS));
comp = new Composite(buttons, SWT.NONE);
gd = new GridData(SWT.FILL, SWT.FILL, true, false);
gd.horizontalSpan = 2;
comp.setLayout(new GridLayout(2, true));
comp.setLayoutData(gd);
final Button bg = new Button(comp, SWT.FLAT);
bg.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
bg.setText("Background");
bg.setImage(createImageFromColor(viewer.getCloud().getBackground().getRGB(), 16));
bg.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
ColorDialog cd = new ColorDialog(parent.getShell());
RGB color = cd.open();
if (color == null)
return;
Color old = viewer.getCloud().getBackground();
Color c = new Color(Display.getDefault(), color);
viewer.getCloud().setBackground(c);
old.dispose();
viewer.getCloud().redrawTextLayerImage();
Image oldImage = bg.getImage();
Image newImage = createImageFromColor(color, 16);
bg.setImage(newImage);
oldImage.dispose();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
final Button sel = new Button(comp, SWT.FLAT);
sel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
sel.setText("Selection");
sel.setImage(createImageFromColor(viewer.getCloud().getSelectionColor().getRGB(), 16));
sel.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
ColorDialog cd = new ColorDialog(parent.getShell());
RGB color = cd.open();
if (color == null)
return;
Color old = viewer.getCloud().getSelectionColor();
Color c = new Color(Display.getDefault(), color);
viewer.getCloud().setSelectionColor(c);
old.dispose();
viewer.getCloud().redrawTextLayerImage();
Image oldImage = sel.getImage();
Image newImage = createImageFromColor(color, 16);
sel.setImage(newImage);
oldImage.dispose();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
return buttons;
}
protected Group addLayoutButtons(Composite parent) {
Group buttons = new Group(parent, SWT.SHADOW_IN);
buttons.setLayout(new GridLayout(2, true));
buttons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
Label l = new Label(buttons, SWT.NONE);
l.setText("Number of Words");
final Combo words = new Combo(buttons, SWT.DROP_DOWN | SWT.READ_ONLY);
words.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
words.setItems(new String[] { "100", "200", "300", "400", "500", "600", "700", "800", "900", "1000", "1100",
"1200", "1300", "1400", "1500", "1600", "1700", "1800", "1900", "2000" });
words.select(2);
words.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
String item = words.getItem(words.getSelectionIndex());
viewer.setMaxWords(Integer.parseInt(item));
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
l = new Label(buttons, SWT.NONE);
l.setText("Max Font Size");
final Combo font = new Combo(buttons, SWT.DROP_DOWN | SWT.READ_ONLY);
font.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
font.setItems(new String[] { "50", "100", "150", "200", "250", "300", "350", "400", "450", "500" });
font.select(1);
font.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
String item = font.getItem(font.getSelectionIndex());
viewer.getCloud().setMaxFontSize(Integer.parseInt(item));
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
l = new Label(buttons, SWT.NONE);
l.setText("Min Font Size");
final Combo minFont = new Combo(buttons, SWT.DROP_DOWN | SWT.READ_ONLY);
minFont.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
minFont.setItems(new String[] { "10", "15", "20", "25", "30", "35", "40", "45", "50" });
minFont.select(1);
minFont.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
String item = minFont.getItem(minFont.getSelectionIndex());
viewer.getCloud().setMinFontSize(Integer.parseInt(item));
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
l = new Label(buttons, SWT.NONE);
l.setText("Boost");
final Combo boost = new Combo(buttons, SWT.DROP_DOWN | SWT.READ_ONLY);
boost.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
boost.setItems(new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" });
boost.select(0);
boost.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
String item = boost.getItem(boost.getSelectionIndex());
viewer.setBoost(Integer.parseInt(item));
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
l = new Label(buttons, SWT.NONE);
l.setText("Boost Factor");
final Combo boostFactor = new Combo(buttons, SWT.DROP_DOWN | SWT.READ_ONLY);
boostFactor.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
boostFactor.setItems(new String[] { "1", "1.5", "2", "2.5", "3", "3.5", "4", "4.5", "5" });
boostFactor.select(0);
boostFactor.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
String item = boostFactor.getItem(boostFactor.getSelectionIndex());
viewer.setBoostFactor(Float.parseFloat(item));
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
if (viewer.getLabelProvider() instanceof IEditableCloudLabelProvider) {
}
l = new Label(buttons, SWT.NONE);
l.setText("Angles");
final Combo angles = new Combo(buttons, SWT.DROP_DOWN | SWT.READ_ONLY);
angles.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
angles.setItems(new String[] { "Horizontal only", "Vertical only", "Horizontal & Vertical",
"45 Degrees, mostly horizontal", "45 Degrees", "Random" });
final List<List<Float>> anglesLists = new ArrayList<>();
anglesLists.add(Arrays.asList(0F));
anglesLists.add(Arrays.asList(-90F, 90F));
anglesLists.add(Arrays.asList(0F, -90F, 0F, 90F));
anglesLists.add(Arrays.asList(0F, -90F, -45F, 0F, 45F, 90F, 0F, 0F, 0F, 0F));
anglesLists.add(Arrays.asList(-90F, -45F, 0F, 45F, 90F));
List<Float> tmp = new ArrayList<>();
for (int i = -90; i <= 90; i++) {
tmp.add((float) i);
}
anglesLists.add(tmp);
angles.select(0);
angles.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
int index = angles.getSelectionIndex();
IEditableCloudLabelProvider lp = (IEditableCloudLabelProvider) viewer.getLabelProvider();
lp.setAngles(anglesLists.get(index));
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
return buttons;
}
public List<RGB> getColors() {
return colors;
}
public List<FontData> getFonts() {
return fonts;
}
}