package org.xmind.cathy.internal.css;
import org.eclipse.e4.ui.css.core.dom.properties.Gradient;
import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler;
import org.eclipse.e4.ui.css.core.engine.CSSEngine;
import org.eclipse.e4.ui.css.swt.helpers.CSSSWTColorHelper;
import org.eclipse.e4.ui.css.swt.properties.AbstractCSSPropertySWTHandler;
import org.eclipse.e4.ui.internal.css.swt.ICTabRendering;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabFolderRenderer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
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.w3c.dom.css.CSSValue;
import org.xmind.cathy.internal.ICathyConstants;
@SuppressWarnings("restriction")
public class CSSPropertyUnselectedTabsColorSWTHandler
extends AbstractCSSPropertySWTHandler {
private static final String RESIZE_LISTENER = "CSSPropertyUnselectedTabsColorSWTHandler.resizeListener"; //$NON-NLS-1$
public static final ICSSPropertyHandler INSTANCE = new CSSPropertyUnselectedTabsColorSWTHandler();
@Override
protected void applyCSSProperty(Control control, String property,
CSSValue value, String pseudo, CSSEngine engine) throws Exception {
if (!(control instanceof CTabFolder)
|| !isUnselectedTabsColorProp(property)) {
return;
}
CTabFolder folder = ((CTabFolder) control);
CTabFolderRenderer renderer = folder.getRenderer();
if (!(renderer instanceof ICTabRendering)) {
return;
}
if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
Color color = (Color) engine.convert(value, Color.class,
control.getDisplay());
((ICTabRendering) renderer).setUnselectedTabsColor(color);
folder.setBackground(null);
removeResizeEventListener(folder);
return;
}
if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) {
Gradient grad = (Gradient) engine.convert(value, Gradient.class,
control.getDisplay());
if (grad == null) {
return;
}
Color[] colors = null;
int[] percents = null;
if (!grad.getValues().isEmpty()) {
colors = CSSSWTColorHelper.getSWTColors(grad,
control.getDisplay(), engine);
percents = CSSSWTColorHelper.getPercents(grad);
}
((ICTabRendering) renderer).setUnselectedTabsColor(colors,
percents);
folder.setBackground(null, null, false);
appendResizeEventListener(folder);
}
}
@Override
protected String retrieveCSSProperty(Control control, String property,
String pseudo, CSSEngine engine) throws Exception {
return null;
}
private boolean isUnselectedTabsColorProp(String property) {
return ICathyConstants.PROPERTY_UNSELECTED_TABS_COLOR.equals(property);
}
// TODO: It needs to be refactored when the Bug 33276 gets fixed
private void appendResizeEventListener(CTabFolder folder) {
if (hasResizeEventListener(folder)) {
return;
}
final Listener resizeListener = new Listener() {
public void handleEvent(Event event) {
CTabFolder folder = (CTabFolder) event.widget;
for (Control child : folder.getChildren()) {
if (isReskinRequired(child)) {
child.reskin(SWT.NONE);
}
}
}
};
folder.addListener(SWT.Resize, resizeListener);
folder.setData(RESIZE_LISTENER, resizeListener);
folder.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
e.widget.removeListener(SWT.Resize, resizeListener);
}
});
}
private void removeResizeEventListener(CTabFolder folder) {
Object obj = folder.getData(RESIZE_LISTENER);
if (obj instanceof Listener) {
folder.removeListener(SWT.Resize, (Listener) obj);
folder.setData(RESIZE_LISTENER, null);
}
}
private boolean hasResizeEventListener(CTabFolder folder) {
return folder.getData(RESIZE_LISTENER) instanceof Listener;
}
private boolean isReskinRequired(Control control) {
if (control instanceof Composite) {
Composite composite = (Composite) control;
return composite.isVisible() && composite.getChildren().length > 0;
}
return false;
}
}