170 lines
5.4 KiB
Java
170 lines
5.4 KiB
Java
package org.gcube.portlets.admin.authportletmanager.client.pagelayout;
|
|
import com.google.gwt.cell.client.AbstractCell;
|
|
import com.google.gwt.cell.client.Cell;
|
|
import com.google.gwt.cell.client.Cell.Context;
|
|
import com.google.gwt.dom.client.Document;
|
|
import com.google.gwt.dom.client.Element;
|
|
import com.google.gwt.dom.client.NativeEvent;
|
|
import com.google.gwt.dom.client.Style.Cursor;
|
|
import com.google.gwt.dom.client.Style.Position;
|
|
import com.google.gwt.dom.client.Style.Unit;
|
|
import com.google.gwt.event.shared.HandlerRegistration;
|
|
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
|
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
|
|
import com.google.gwt.user.cellview.client.AbstractCellTable;
|
|
import com.google.gwt.user.cellview.client.Column;
|
|
import com.google.gwt.user.cellview.client.Header;
|
|
import com.google.gwt.user.client.Event;
|
|
import com.google.gwt.user.client.Event.NativePreviewEvent;
|
|
import com.google.gwt.user.client.Event.NativePreviewHandler;
|
|
|
|
/**
|
|
* ResizableHeader for DataGrid
|
|
*
|
|
* @author "Alessandro Pieve " <a
|
|
* href="mailto:alessandro.pieve@isti.cnr.it">alessandro.pieve@isti.cnr.it</a>
|
|
*
|
|
*/
|
|
|
|
|
|
public class ResizableHeader<T> extends Header<String> {
|
|
|
|
private Column<T, ?> column = null;
|
|
private AbstractCellTable<T> cellTable;
|
|
private String title = "";
|
|
private static final int width = 20;
|
|
|
|
public ResizableHeader(String title, AbstractCellTable<T> cellTable, Column<T, ?> column) {
|
|
super(new HeaderCell());
|
|
this.title = title;
|
|
this.cellTable = cellTable;
|
|
this.column = column;
|
|
}
|
|
|
|
@Override
|
|
public String getValue() {
|
|
return title;
|
|
}
|
|
|
|
@Override
|
|
public void onBrowserEvent(Context context, Element target, NativeEvent event) {
|
|
String eventType = event.getType();
|
|
if (eventType.equals("mousemove")) {
|
|
new ColumnResizeHelper<T>(cellTable, column, target);
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void setCursor(Element element, Cursor cursor) {
|
|
element.getStyle().setCursor(cursor);
|
|
}
|
|
|
|
class ColumnResizeHelper<E> implements NativePreviewHandler {
|
|
|
|
private HandlerRegistration handler;
|
|
private AbstractCellTable<E> table;
|
|
private Column<E, ?> col;
|
|
private Element el;
|
|
private boolean mousedown;
|
|
private Element measuringElement;
|
|
|
|
public ColumnResizeHelper(AbstractCellTable<E> table, Column<E, ?> col, Element el) {
|
|
this.el = el;
|
|
this.table = table;
|
|
this.col = col;
|
|
handler = Event.addNativePreviewHandler(this);
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
@Override
|
|
public void onPreviewNativeEvent(NativePreviewEvent event) {
|
|
NativeEvent nativeEvent = event.getNativeEvent();
|
|
nativeEvent.preventDefault();
|
|
nativeEvent.stopPropagation();
|
|
|
|
String eventType = nativeEvent.getType();
|
|
int clientX = nativeEvent.getClientX();
|
|
if (eventType.equals("mousemove") && mousedown) {
|
|
int absoluteLeft = el.getAbsoluteLeft();
|
|
int newWidth = clientX - absoluteLeft;
|
|
newWidth = newWidth < width ? width : newWidth;
|
|
table.setColumnWidth(col, newWidth + "px");
|
|
return;
|
|
}
|
|
|
|
if (eventType.equals("mousemove") || eventType.equals("mousedown")) {
|
|
Element eventTargetEl = nativeEvent.getEventTarget().cast();
|
|
int absoluteLeft = eventTargetEl.getAbsoluteLeft();
|
|
int offsetWidth = eventTargetEl.getOffsetWidth();
|
|
if (clientX > absoluteLeft + offsetWidth - width) {
|
|
if (eventType.equals("mousedown")) {
|
|
mousedown = true;
|
|
} else {
|
|
setCursor(el, Cursor.COL_RESIZE);
|
|
}
|
|
} else {
|
|
removeHandler();
|
|
return;
|
|
}
|
|
} else if (eventType.equals("mouseup")) {
|
|
mousedown = false;
|
|
} else if (eventType.equals("mouseout") && !mousedown) {
|
|
removeHandler();
|
|
return;
|
|
}
|
|
|
|
if (eventType.equals("dblclick")) {
|
|
// Get column
|
|
nativeEvent.preventDefault();
|
|
nativeEvent.stopPropagation();
|
|
double max = 0;
|
|
startMeasuring();
|
|
for (E t : table.getVisibleItems()) {
|
|
Object value = col.getValue(t);
|
|
SafeHtmlBuilder sb = new SafeHtmlBuilder();
|
|
Cell<Object> cell = (Cell<Object>) col.getCell();
|
|
cell.render(null, value, sb);
|
|
max = Math.max(measureText(sb.toSafeHtml().asString()), max);
|
|
}
|
|
finishMeasuring();
|
|
table.setColumnWidth(col, (max + width) + "px");
|
|
removeHandler();
|
|
}
|
|
}
|
|
|
|
private void removeHandler() {
|
|
handler.removeHandler();
|
|
setCursor(el, Cursor.DEFAULT);
|
|
}
|
|
|
|
private void startMeasuring() {
|
|
Document document = Document.get();
|
|
measuringElement = document.createElement("div");
|
|
measuringElement.getStyle().setPosition(Position.ABSOLUTE);
|
|
measuringElement.getStyle().setLeft(-1000, Unit.PX);
|
|
measuringElement.getStyle().setTop(-1000, Unit.PX);
|
|
document.getBody().appendChild(measuringElement);
|
|
}
|
|
|
|
private double measureText(String text) {
|
|
measuringElement.setInnerHTML(text);
|
|
return measuringElement.getOffsetWidth();
|
|
}
|
|
|
|
private void finishMeasuring() {
|
|
Document.get().getBody().removeChild(measuringElement);
|
|
}
|
|
}
|
|
|
|
static class HeaderCell extends AbstractCell<String> {
|
|
public HeaderCell() {
|
|
super("click", "mousedown", "mousemove", "dblclick");
|
|
}
|
|
|
|
@Override
|
|
public void render(Context context, String value, SafeHtmlBuilder sb) {
|
|
sb.append(SafeHtmlUtils.fromString(value));
|
|
}
|
|
}
|
|
}; |