package fr.lteconsulting.hexa.client.ui.editable; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.HasClickHandlers; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.resources.client.ImageResource; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HasText; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.Widget; public abstract class EditableWidget<WIDGET extends Widget & HasText & HasClickHandlers, COOKIE> extends Composite implements ClickHandler, KeyUpHandler, BlurHandler { public interface Callback<WIDGET extends Widget & HasText & HasClickHandlers, COOKIE> { void onWantChange( String text, EditableWidget<WIDGET, COOKIE> widget, COOKIE cookie ); } public interface OnEditCallback<WIDGET extends Widget & HasText & HasClickHandlers, COOKIE> { // return false to cancel edition // during the call to this method, callee can call setText() to set the // text in the textbox boolean onEdit( EditableWidget<WIDGET, COOKIE> widget, COOKIE cookie ); } ImageResource m_loadingImage = null; WIDGET m_widget = null; boolean m_fEditing = false; String m_editingText = null; Callback<WIDGET, COOKIE> m_callback; OnEditCallback<WIDGET, COOKIE> m_onEditCallback = null; COOKIE m_cookie; SimplePanel m_spot = new SimplePanel(); boolean fEditable = true; // by default TextBox m_box = null; // GrowingTextArea m_box = null; Image m_image = null; double m_fontSize; Unit m_fontSizeUnit = null; // This method is called when the display widget needs to be initialized abstract WIDGET implInitDisplayWidget(); public EditableWidget( ImageResource loadingImage, Callback<WIDGET, COOKIE> callback, COOKIE cookie ) { m_loadingImage = loadingImage; m_callback = callback; m_cookie = cookie; initWidget( m_spot ); m_widget = implInitDisplayWidget(); m_widget.addClickHandler( this ); } public void setEditable( boolean fEditable ) { this.fEditable = fEditable; } public void setOnEditCallback( OnEditCallback<WIDGET, COOKIE> callback ) { m_onEditCallback = callback; } public void setText( String text ) { if( m_fEditing ) { m_editingText = text; } else { if( text==null || text.trim().isEmpty() ) text = "..."; m_widget.setText( text ); m_spot.setWidget( m_widget ); } } public void setFontSize( double value, Unit unit ) { m_fontSize = value; m_fontSizeUnit = unit; m_widget.getElement().getStyle().setFontSize( m_fontSize, m_fontSizeUnit ); if( m_box != null ) m_box.getElement().getStyle().setFontSize( m_fontSize, m_fontSizeUnit ); } @Override public void onClick( ClickEvent event ) { if( !fEditable ) return; m_editingText = null; if( m_onEditCallback != null ) { m_fEditing = true; if( !m_onEditCallback.onEdit( this, m_cookie ) ) { m_fEditing = false; return; } m_fEditing = false; } String text = m_editingText; if( text == null ) text = m_widget.getText(); if( m_box == null ) { m_box = new TextBox(); // m_box = new GrowingTextArea(); if( m_fontSizeUnit != null ) m_box.getElement().getStyle().setFontSize( m_fontSize, m_fontSizeUnit ); m_box.addKeyUpHandler( this ); m_box.addBlurHandler( this ); } m_spot.setWidget( m_box ); // if( text != null ) // m_box.setVisibleLength( text.length() + 10 ); m_box.setText( text ); m_box.setFocus( true ); m_box.selectAll(); } @Override public void onKeyUp( KeyUpEvent event ) { if( event.getNativeKeyCode() == KeyCodes.KEY_ENTER ) { if( m_image == null ) m_image = new Image( m_loadingImage ); m_spot.setWidget( m_image ); m_callback.onWantChange( m_box.getText(), this, m_cookie ); } else if( event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE ) { m_spot.setWidget( m_widget ); } } @Override public void onBlur( BlurEvent event ) { m_spot.setWidget( m_widget ); } }