/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.eas.grid.cells; import java.util.Set; import com.eas.grid.Grid; import com.eas.ui.CommonResources; import com.eas.widgets.boxes.AutoCloseBox; import com.google.gwt.cell.client.AbstractEditableCell; import com.google.gwt.cell.client.Cell; import com.google.gwt.cell.client.ValueUpdater; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.ui.Focusable; import com.google.gwt.user.client.ui.HasText; import com.google.gwt.user.client.ui.HasValue; import com.google.gwt.user.client.ui.Widget; /** * * @author mg * @param <C> */ public abstract class WidgetEditorCell<C> extends AbstractEditableCell<C, WidgetEditorCell.ViewData<C>> { protected static class ViewData<T> { String id; ValueUpdater<T> updater; public ViewData(String aId, ValueUpdater<T> aUpdater) { id = aId; updater = aUpdater; } } protected Widget editor; protected HasValue<C> valueHost; protected Focusable focusHost; public WidgetEditorCell(Widget aEditor, String... consumedEvents) { super(consumedEvents); setEditor(aEditor); } public WidgetEditorCell(Widget aEditor, Set<String> consumedEvents) { super(consumedEvents); setEditor(aEditor); } public Widget getEditor() { return editor; } public void setEditor(Widget aEditor) { editor = aEditor; if (editor == null || ((editor instanceof HasValue<?>) && (editor instanceof HasText))) { valueHost = (HasValue<C>) editor; } else { throw new IllegalArgumentException("Editor must implement interfaces HasValue<?> and HasText"); } if (editor instanceof Focusable) { focusHost = (Focusable) editor; focusHost.setTabIndex(1); } if (editor != null){ CommonResources.INSTANCE.commons().ensureInjected(); editor.getElement().addClassName(CommonResources.INSTANCE.commons().borderSized()); } } protected static class UpdaterRef<C> { public ValueUpdater<C> valueUpdater; public UpdaterRef(ValueUpdater<C> aValueUpdater) { valueUpdater = aValueUpdater; } } public boolean isEditing(Cell.Context context, Element parent, C value) { ViewData<C> viewId = getViewData(context.getKey()); return viewId != null; } public void startEditing(final Cell.Context context, final Element aBoxPositionTemplate, final Element aBoxParent, final C value, ValueUpdater<C> valueUpdater, final Runnable onEditorClose) { Widget oldParent = editor.getParent(); if (oldParent == null) { final UpdaterRef<C> updaterRef = new UpdaterRef<>(valueUpdater); final AutoCloseBox editorBox = new AutoCloseBox() { protected void superClose() { super.close(); } @Override public void close() { Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { superClose(); } }); } }; valueHost.setValue(value); editorBox.setWidget(editor); final HandlerRegistration valueChangeReg = valueHost.addValueChangeHandler(new ValueChangeHandler<C>() { @Override public void onValueChange(ValueChangeEvent<C> event) { if (updaterRef.valueUpdater != null) { updaterRef.valueUpdater.update(valueHost.getValue()); } } }); editorBox.getElement().setClassName("grid-cell-editor-popup"); editorBox.getElement().getStyle().setPosition(Style.Position.ABSOLUTE); editorBox.getElement().getStyle().setDisplay(Style.Display.INLINE_BLOCK); editorBox.getElement().getStyle().setWidth(aBoxPositionTemplate.getClientWidth(), Style.Unit.PX); editorBox.getElement().getStyle().setHeight(aBoxPositionTemplate.getClientHeight(), Style.Unit.PX); editorBox.getElement().getStyle().setLeft(aBoxPositionTemplate.getAbsoluteLeft() - aBoxParent.getAbsoluteLeft(), Style.Unit.PX); editorBox.getElement().getStyle().setTop(aBoxPositionTemplate.getAbsoluteTop() - aBoxParent.getAbsoluteTop(), Style.Unit.PX); final HandlerRegistration editorKeyDownReg = editor.addDomHandler(new KeyDownHandler() { @Override public void onKeyDown(KeyDownEvent event) { if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ESCAPE) { updaterRef.valueUpdater = null; valueHost.setValue(null); editorBox.close(); } else if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) { Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { updaterRef.valueUpdater = null; valueHost.setValue(null); editorBox.close(); } }); } } }, KeyDownEvent.getType()); editorBox.addCloseHandler(new CloseHandler<AutoCloseBox>() { @Override public void onClose(CloseEvent<AutoCloseBox> event) { valueChangeReg.removeHandler(); editorKeyDownReg.removeHandler(); editorBox.setWidget(null); editor.removeFromParent(); setViewData(context.getKey(), null); if (onEditorClose != null) onEditorClose.run(); } }); editorBox.show(aBoxParent); Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { if (editor.isAttached() && focusHost != null) { focusHost.setFocus(true); } } }); } } }