package org.eclipse.papyrus.uml.diagram.sequence.apex.part.tweaks;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.forms.FormColors;
public abstract class TweakViewer extends StructuredViewer {
private final List<TweakItem> fTweakItems;
private final Composite fContainer;
private Image fGradientBackground;
private TweakItem fSelectedItem;
private ILabelProvider fToolTipLabelProvider;
public TweakViewer(Composite parent, int style) {
fTweakItems = new ArrayList<TweakItem>();
fContainer= new Composite(parent, SWT.NONE);
GridData layoutData= new GridData(SWT.FILL, SWT.TOP, true, false);
fContainer.setLayoutData(layoutData);
fContainer.addTraverseListener(new TraverseListener() {
public void keyTraversed(TraverseEvent e) {
e.doit= true;
}
});
fContainer.setBackgroundMode(SWT.INHERIT_DEFAULT);
fContainer.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event event) {
int height= fContainer.getClientArea().height;
if (fGradientBackground == null || fGradientBackground.getBounds().height != height) {
Image image= height == 0 ? null : createGradientImage(height, event.display);
fContainer.setBackgroundImage(image);
if (fGradientBackground != null)
fGradientBackground.dispose();
fGradientBackground= image;
}
}
});
hookControl(fContainer);
// GridLayout gridLayout= new GridLayout(columns, false);
// gridLayout.marginWidth= 0;
// gridLayout.marginHeight= 0;
// gridLayout.verticalSpacing= 0;
// gridLayout.horizontalSpacing= 0;
// fContainer.setLayout(gridLayout);
FormLayout formLayout = new FormLayout();
formLayout.marginBottom = 2;
fContainer.setLayout(formLayout);
fContainer.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event event) {
refresh();
}
});
}
protected abstract void hookTweakItems(List<TweakItem> items);
protected abstract void unhookTweakItems(List<TweakItem> items);
public void setToolTipLabelProvider(ILabelProvider toolTipLabelProvider) {
fToolTipLabelProvider = toolTipLabelProvider;
}
@Override
protected void inputChanged(Object input, Object oldInput) {
if (fContainer.isDisposed())
return;
disableRedraw();
try {
unhookTweakItems(fTweakItems);
int lastIndex = buildItem(input);
hookTweakItems(fTweakItems);
while (lastIndex < fTweakItems.size()) {
TweakItem item = fTweakItems.remove(fTweakItems.size() - 1);
if (item.getData() != null) {
unmapElement(item.getData());
}
item.dispose();
}
updateSize();
fContainer.layout(true, true);
} finally {
enableRedraw();
}
}
@Override
protected Widget doFindInputItem(Object element) {
if (element == null) {
return null;
}
if (element == getInput() || element.equals(getInput())) {
return doFindItem(element);
}
return null;
}
@Override
protected Widget doFindItem(Object element) {
if (element == null) {
return null;
}
for (int i = 0, size = fTweakItems.size(); i < size; i++) {
TweakItem item = fTweakItems.get(i);
if (item.getData() == element || element.equals(item.getData()))
return item;
}
return null;
}
@Override
protected void doUpdateItem(Widget widget, Object element, boolean fullMap) {
if (widget instanceof TweakItem) {
final TweakItem item = (TweakItem)widget;
if (fullMap) {
associate(element, item);
} else {
Object data = item.getData();
if (data != null) {
unmapElement(data, item);
}
item.setData(element);
mapElement(element, item);
}
}
}
@Override
protected List getSelectionFromWidget() {
if (fSelectedItem == null)
return Collections.EMPTY_LIST;
if (fSelectedItem.getData() == null)
return Collections.EMPTY_LIST;
ArrayList<Object> result= new ArrayList<Object>();
result.add(fSelectedItem.getData());
return result;
}
@Override
protected void internalRefresh(Object element) {
disableRedraw();
try {
TweakItem item= (TweakItem) doFindItem(element);
if (item == null) {
for (int i= 0, size= fTweakItems.size(); i < size; i++) {
TweakItem item1= fTweakItems.get(i);
item1.refresh();
}
} else {
item.refresh();
}
if (updateSize())
fContainer.layout(true, true);
} finally {
enableRedraw();
}
}
@Override
public void reveal(Object element) {
}
@Override
protected void setSelectionToWidget(List l, boolean reveal) {
TweakItem focusItem = null;
for (int i = 0, size = fTweakItems.size(); i < size; i++) {
TweakItem item = fTweakItems.get(i);
if (item.hasFocus()) {
focusItem = item;
}
item.setSelected(false);
}
if (l == null) {
return;
}
for (Iterator<?> iterator = l.iterator(); iterator.hasNext();) {
Object element = iterator.next();
TweakItem item = (TweakItem) doFindItem(element);
if (item != null) {
fSelectedItem = item;
item.setSelected(true);
if (item == focusItem) {
item.setFocus(true);
}
}
}
}
@Override
public Control getControl() {
return fContainer;
}
private int buildItem(Object input) {
IStructuredContentProvider contentProvider = (IStructuredContentProvider)getContentProvider();
Object[] elements = contentProvider.getElements(input);
if (elements == null) {
return 0;
}
int index = 0;
for (Object element : elements) {
TweakItem item;
if (index < fTweakItems.size()) {
item = fTweakItems.get(index);
if (item.getData() != null) {
unmapElement(item.getData());
}
} else {
item = createItem();
fTweakItems.add(item);
}
index += 1;
if (equals(element, item.getData())) {
update(element, null);
} else {
item.setData(element);
item.refresh();
}
mapElement(element, item);
if (contentProvider instanceof ITreeContentProvider) {
buildItem(element);
}
}
return index;
}
private TweakItem createItem() {
TweakItem result = new TweakItem(this, fContainer);
result.setLabelProvider((ILabelProvider) getLabelProvider());
result.setContentProvider((IStructuredContentProvider) getContentProvider());
if (fToolTipLabelProvider != null) {
result.setToolTipLabelProvider(fToolTipLabelProvider);
} else {
result.setToolTipLabelProvider((ILabelProvider) getLabelProvider());
}
return result;
}
private boolean updateSize() {
boolean requiresLayout = true;
return requiresLayout;
}
private void enableRedraw() {
fContainer.setRedraw(true);
}
private void disableRedraw() {
fContainer.setRedraw(false);
}
private int hOffset = 0;
protected int getHorizontalOffset() {
return hOffset;
}
protected void setHorizontalOffset(int offset) {
hOffset = offset;
}
private Image createGradientImage(int height, Display display) {
int width= 50;
Image result= new Image(display, width, height);
GC gc= new GC(result);
Color colorC= createColor(SWT.COLOR_WIDGET_BACKGROUND, SWT.COLOR_LIST_BACKGROUND, 35, display);
Color colorD= createColor(SWT.COLOR_WIDGET_BACKGROUND, SWT.COLOR_LIST_BACKGROUND, 45, display);
Color colorE= createColor(SWT.COLOR_WIDGET_BACKGROUND, SWT.COLOR_LIST_BACKGROUND, 80, display);
Color colorF= createColor(SWT.COLOR_WIDGET_BACKGROUND, SWT.COLOR_LIST_BACKGROUND, 70, display);
Color colorG= createColor(SWT.COLOR_WIDGET_BACKGROUND, SWT.COLOR_WHITE, 45, display);
Color colorH= createColor(SWT.COLOR_WIDGET_NORMAL_SHADOW, SWT.COLOR_LIST_BACKGROUND, 35, display);
try {
drawLine(width, 0, colorC, gc);
drawLine(width, 1, colorC, gc);
gc.setForeground(colorD);
gc.setBackground(colorE);
gc.fillGradientRectangle(0, 2, width, 2 + 8, true);
gc.setBackground(colorE);
gc.fillRectangle(0, 2 + 9, width, height - 4);
drawLine(width, height - 3, colorF, gc);
drawLine(width, height - 2, colorG, gc);
drawLine(width, height - 1, colorH, gc);
} finally {
gc.dispose();
colorC.dispose();
colorD.dispose();
colorE.dispose();
colorF.dispose();
colorG.dispose();
colorH.dispose();
}
return result;
}
private void drawLine(int width, int position, Color color, GC gc) {
gc.setForeground(color);
gc.drawLine(0, position, width, position);
}
private Color createColor(int color1, int color2, int ratio, Display display) {
RGB rgb1= display.getSystemColor(color1).getRGB();
RGB rgb2= display.getSystemColor(color2).getRGB();
RGB blend= FormColors.blend(rgb2, rgb1, ratio);
return new Color(display, blend);
}
@Override
protected void handleDispose(DisposeEvent event) {
if (fGradientBackground != null) {
fGradientBackground.dispose();
fGradientBackground = null;
}
if (fToolTipLabelProvider != null) {
fToolTipLabelProvider.dispose();
fToolTipLabelProvider = null;
}
if (fTweakItems != null) {
Iterator<TweakItem> iterator = fTweakItems.iterator();
while (iterator.hasNext()) {
TweakItem item = iterator.next();
item.dispose();
}
fTweakItems.clear();
}
super.handleDispose(event);
}
}