/*****************************************************************************
* Copyright (c) 2015 CEA LIST.
*
* 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:
* Dirk Fauth <dirk.fauth@googlemail.com> - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.nebula.widgets.nattable.extension.e4.css;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.e4.ui.css.core.engine.CSSEngine;
import org.eclipse.e4.ui.css.swt.dom.WidgetElement;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.swt.SWT;
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.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@SuppressWarnings("restriction")
public class NatTableElementAdapter extends WidgetElement {
/**
* Static flag to ensure that the update listener is only applied once to
* the display.
*/
private static boolean listenerApplied = false;
/**
* Collection of virtual children that can be used as child selectors in CSS
* that will be mapped to NatTable labels.
*/
List<Node> virtualChildren = new ArrayList<>();
public NatTableElementAdapter(final NatTable natTable, final CSSEngine engine) {
super(natTable, engine);
addStaticPseudoInstance("normal");
addStaticPseudoInstance("select");
addStaticPseudoInstance("edit");
addStaticPseudoInstance("hover");
addStaticPseudoInstance("select-hover");
// add virtual children for all labels that can be applied in the given
// NatTable instance
for (String label : natTable.getProvidedLabels()) {
addVirtualChild(label);
}
if (!listenerApplied) {
// The listener added via CSSSWTApplyStylesListener does not apply
// styles for the children. But as NatTable styling is done via
// virtual children for the labels, it is important to apply the
// styles also to the children on skinning.
natTable.getDisplay().addListener(SWT.Skin, new Listener() {
@Override
public void handleEvent(Event event) {
if (engine != null && event.widget instanceof NatTable) {
engine.applyStyles(event.widget, true);
}
}
});
// the special NatTable related update listener is registered, so we
// won't add additional listeners for additional NatTable instances
listenerApplied = true;
}
}
@Override
public Node getParentNode() {
Control control = getControl();
Composite parent = control.getParent();
if (parent != null) {
Element element = getElement(parent);
return element;
}
return null;
}
protected NatTable getControl() {
return (NatTable) getNativeWidget();
}
@Override
public NodeList getChildNodes() {
// only need to return a non-null value
// strange implementation
return this;
}
@Override
public int getLength() {
return this.virtualChildren.size();
}
@Override
public Node item(int index) {
return this.virtualChildren.get(index);
}
/**
* Add a virtual child to the {@link NatTableElementAdapter}. This way the
* given label can be used as child selector in the CSS file.
*
* @param label
* The label that should be usable as child selector.
*/
public void addVirtualChild(String label) {
this.virtualChildren.add(
new NatTableWrapperElementAdapter(
new NatTableWrapper(getControl(), label), this.engine, this));
}
}