/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.gwt.widgets.client.listbox;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.event.dom.client.MouseWheelEvent;
import com.google.gwt.event.dom.client.MouseWheelHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import org.pentaho.gwt.widgets.client.utils.ElementUtils;
/**
*
* User: Nick Baker Date: Mar 9, 2009 Time: 11:28:45 AM
*/
public class DefaultListItem extends HorizontalPanel implements ListItem<Object> {
private static final String DROP_INVALID_PNG = "drop_invalid.png"; //$NON-NLS-1$
private static final String DROP_VALID_PNG = "drop_valid.png"; //$NON-NLS-1$
public static final String HOVER = "hover"; //$NON-NLS-1$
public static final String SELECTED = "selected";
public static final String PROXY_VALID = "proxy-valid";
private String text = ""; //$NON-NLS-1$
protected Widget widget;
protected Widget dropWidget;
private Image img;
private Widget extraWidget;
private String baseStyleName = "custom-list"; //$NON-NLS-1$
private Object value;
protected ListItemListener listItemListener;
private String styleName = "custom-list"; //$NON-NLS-1$
private Object backingObject;
protected Image dragIndicator;
public DefaultListItem() {
init();
}
public DefaultListItem( String str ) {
this.text = str;
this.value = this.text;
init();
}
private void init() {
createWidgets();
this.sinkEvents( Event.MOUSEEVENTS );
this.setStylePrimaryName( styleName );
}
/**
* Convenience constructor for creating a listItem with an Image followed by a string..
* <p>
* NOTE: The Image needs to have been constructed with a specified size (ie new Image("src.png",0,0,100,100);)
*
* @param str
* @param img
*/
public DefaultListItem( String str, Image img ) {
this.text = str;
this.value = this.text;
this.img = img;
createWidgets();
this.setStylePrimaryName( styleName );
}
public DefaultListItem( String str, Widget widget ) {
this.text = str;
this.extraWidget = widget;
createWidgets();
this.setStylePrimaryName( styleName );
}
public void setStylePrimaryName( String style ) {
baseStyleName = style;
dropWidget.setStylePrimaryName( style + "-item" ); //$NON-NLS-1$
super.setStylePrimaryName( style + "-item" ); //$NON-NLS-1$
}
/**
* There are two widgets that need to be maintaned. One that shows in the drop-down when not opened, and another that
* shows in the drop-down popup itself.
*/
private void createWidgets() {
formatWidget( this );
widget = this;
HorizontalPanel hbox = new HorizontalPanel();
hbox.setStylePrimaryName( baseStyleName + "-item" ); //$NON-NLS-1$
formatWidget( hbox );
dropWidget = hbox;
}
private void formatWidget( HorizontalPanel panel ) {
panel.sinkEvents( Event.MOUSEEVENTS );
if ( img != null ) {
Image i = new Image( img.getUrl(), img.getOriginLeft(), img.getOriginTop(), img.getWidth(), img.getHeight() );
panel.add( i );
panel.setCellVerticalAlignment( i, HasVerticalAlignment.ALIGN_MIDDLE );
i.getElement().getStyle().setProperty( "marginRight", "5px" ); //$NON-NLS-1$ //$NON-NLS-2$
} else if ( extraWidget != null ) {
Element ele = DOM.clone( extraWidget.getElement(), true );
Widget w = new WrapperWidget( ele );
panel.add( w );
panel.setCellVerticalAlignment( w, HasVerticalAlignment.ALIGN_MIDDLE );
w.getElement().getStyle().setProperty( "marginRight", "5px" ); //$NON-NLS-1$ //$NON-NLS-2$
}
Label label = new Label( text );
label.getElement().getStyle().setProperty( "cursor", "pointer" ); //$NON-NLS-1$ //$NON-NLS-2$
label.setWidth( "100%" ); //$NON-NLS-1$
SimplePanel sp = new SimplePanel();
sp.getElement().getStyle().setProperty( "overflowX", "auto" ); //$NON-NLS-1$ //$NON-NLS-2$
sp.add( label );
panel.add( sp );
panel.setCellWidth( sp, "100%" ); //$NON-NLS-1$
panel.setCellVerticalAlignment( label, HasVerticalAlignment.ALIGN_MIDDLE );
ElementUtils.preventTextSelection( panel.getElement() );
// label.setStylePrimaryName("custom-list-item"); //$NON-NLS-1$
panel.setWidth( "100%" ); //$NON-NLS-1$
}
public void onBrowserEvent( Event event ) {
int code = event.getTypeInt();
switch ( code ) {
case Event.ONMOUSEOVER:
this.addStyleDependentName( HOVER );
break;
case Event.ONMOUSEOUT:
this.removeStyleDependentName( HOVER );
break;
case Event.ONMOUSEUP:
listItemListener.itemSelected( DefaultListItem.this, event );
this.removeStyleDependentName( HOVER );
break;
case Event.ONDBLCLICK:
listItemListener.doAction( DefaultListItem.this );
default:
break;
}
super.onBrowserEvent( event );
}
public Widget getWidgetForDropdown() {
return dropWidget;
}
public Widget getWidget() {
return widget;
}
public Object getValue() {
return this.value;
}
public void setValue( Object o ) {
this.value = o;
}
public void onHoverEnter() {
}
public void onHoverExit() {
}
public void onSelect() {
try {
widget.addStyleDependentName( SELECTED ); //$NON-NLS-1$
} catch ( Exception e ) {
e.printStackTrace();
}
}
public void onDeselect() {
try {
widget.removeStyleDependentName( SELECTED ); //$NON-NLS-1$
} catch ( Exception e ) {
e.printStackTrace();
}
}
public String getText() {
return text;
}
public void setText( String text ) {
this.text = text;
}
private static class WrapperWidget extends Widget {
public WrapperWidget( Element ele ) {
this.setElement( ele );
}
}
public void setListItemListener( ListItemListener listener ) {
this.listItemListener = listener;
}
/**
* DND required methods below
*/
public HandlerRegistration addMouseUpHandler( MouseUpHandler handler ) {
return addDomHandler( handler, MouseUpEvent.getType() );
}
public HandlerRegistration addMouseOutHandler( MouseOutHandler handler ) {
return addDomHandler( handler, MouseOutEvent.getType() );
}
public HandlerRegistration addMouseMoveHandler( MouseMoveHandler handler ) {
return addDomHandler( handler, MouseMoveEvent.getType() );
}
public HandlerRegistration addMouseWheelHandler( MouseWheelHandler handler ) {
return addDomHandler( handler, MouseWheelEvent.getType() );
}
public HandlerRegistration addMouseOverHandler( MouseOverHandler handler ) {
return addDomHandler( handler, MouseOverEvent.getType() );
}
public HandlerRegistration addMouseDownHandler( MouseDownHandler handler ) {
return addDomHandler( handler, MouseDownEvent.getType() );
}
private void makeDraggable() {
clear();
dragIndicator = new Image( GWT.getModuleBaseURL() + DROP_INVALID_PNG );
add( dragIndicator );
Label label = new Label( text );
add( label );
this.setCellWidth( dragIndicator, "16px" );
this.setCellVerticalAlignment( dragIndicator, HasVerticalAlignment.ALIGN_MIDDLE );
addStyleDependentName( "proxy" );
}
public void setDropValid( boolean valid ) {
if ( valid ) {
addStyleDependentName( PROXY_VALID );
dragIndicator.setUrl( GWT.getModuleBaseURL() + DROP_VALID_PNG );
} else {
removeStyleDependentName( PROXY_VALID );
dragIndicator.setUrl( GWT.getModuleBaseURL() + DROP_INVALID_PNG );
}
}
public Widget makeProxy( Widget ele ) {
DefaultListItem item = new DefaultListItem( this.getText() );
item.setWidth( "20px" );
item.makeDraggable();
removeStyleDependentName( HOVER ); //$NON-NLS-1$
return item;
}
public void setBackingObject( Object backingObject ) {
this.backingObject = backingObject;
}
public Object getDragObject() {
return backingObject;
}
public void notifyDragFinished() {
// TODO: implement callbacks to support "move" operations
// listItemListener.notifyDragFinished();
}
}