/*!
* 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-2016 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.gwt.widgets.client.toolbar;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
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.user.client.Command;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.Widget;
import org.pentaho.gwt.widgets.client.text.ToolTip;
/**
* Manages a PushButton in the common toolbar {@link Toolbar}.
*
* Note, it's not a subclass of PushButton as the PushButton api does not allow the changing of the image after
* instantiation. It is not a decorator because the GWT PushButton does not implement an interface. If these limitations
* change, please change this class.
*
* @author nbaker
*
*/
@SuppressWarnings( "deprecation" )
public class ToolbarButton {
protected DockPanel button = new DockPanel();
protected boolean enabled = true;
protected boolean visible = true;
protected String text;
protected Image image;
protected Image disabledImage;
protected Image currentImage;
protected Label label = new Label();
protected FocusPanel eventWrapper = new FocusPanel();
protected String stylePrimaryName = "toolbar-button"; //$NON-NLS-1$
protected Command command;
protected ToolTip toolTipWidget;
protected String toolTip;
protected Image downImage;
protected Image downImageDisabled;
String className = ""; //$NON-NLS-1$
/**
* Constructs a toolbar button with an image and a label
*
* @param img
* GWT Image object
* @param label
* String containing an option label
*/
public ToolbarButton( Image img, String label ) {
this( img );
this.label.setText( label );
button.add( this.label, DockPanel.EAST );
}
/**
* Constructs a toolbar button with an enabled image, disabled image and a label
*
* @param img
* GWT Image object
* @param disabledImage
* GWT Image object
* @param label
* String containing an option label
*/
public ToolbarButton( Image img, Image disabledImage, String label ) {
this( img, label );
this.disabledImage = disabledImage;
}
/**
* Constructs a toolbar button with an enabled image, disabled image and a label
*
* @param img
* GWT Image object
* @param disabledImage
* GWT Image object
* @param label
* String containing an option label
*/
public ToolbarButton( Image img, Image disabledImage ) {
this( img );
this.disabledImage = disabledImage;
}
/**
* Constructs a toolbar button with an image, currently hardcoded to 16x16
*
* @param img
* GWT Image object
*/
public ToolbarButton( Image img ) {
this.image = img;
this.currentImage = img;
button.add( this.image, DockPanel.CENTER );
button.setCellHorizontalAlignment( this.image, DockPanel.ALIGN_CENTER );
button.setCellVerticalAlignment( this.image, DockPanel.ALIGN_MIDDLE );
button.setStyleName( stylePrimaryName );
eventWrapper.add( button );
addStyleMouseListener();
}
public void setId( String id ) {
if ( ( button != null ) && ( button.getElement() != null ) ) {
button.getElement().setId( id.concat( "_btn" ) ); //$NON-NLS-1$
}
if ( ( eventWrapper != null ) && ( eventWrapper.getElement() != null ) ) {
eventWrapper.getElement().setId( id );
}
}
public void setStylePrimaryName( String styleName ) {
this.stylePrimaryName = styleName;
button.setStylePrimaryName( styleName );
}
protected void addStyleMouseListener() {
// a click listener is more appropriate here to fire the click events
// rather than a mouse-up because the focus panel can (and does) sometimes
// receive mouse up events if a widget 'above' it has been clicked and
// dismissed (on mouse-down). The ensures that only a true click will
// fire a button's command
eventWrapper.addClickListener( new ClickListener() {
public void onClick( Widget sender ) {
if ( !enabled ) {
// ElementUtils.blur(ToolbarButton.this.eventWrapper.getElement());
return;
}
button.removeStyleName( stylePrimaryName + "-down" ); //$NON-NLS-1$
button.removeStyleName( stylePrimaryName + "-hovering" ); //$NON-NLS-1$
command.execute();
// ElementUtils.blur(ToolbarButton.this.eventWrapper.getElement());
}
} );
eventWrapper.addMouseListener( new MouseListener() {
public void onMouseDown( Widget w, int arg1, int arg2 ) {
if ( !enabled ) {
return;
}
button.addStyleName( stylePrimaryName + "-down" ); //$NON-NLS-1$
}
public void onMouseEnter( Widget arg0 ) {
if ( !enabled ) {
return;
}
button.addStyleName( stylePrimaryName + "-hovering" ); //$NON-NLS-1$
}
public void onMouseLeave( Widget arg0 ) {
if ( !enabled ) {
return;
}
button.removeStyleName( stylePrimaryName + "-hovering" ); //$NON-NLS-1$
}
public void onMouseUp( Widget arg0, int arg1, int arg2 ) {
if ( !enabled ) {
// ElementUtils.blur(ToolbarButton.this.eventWrapper.getElement());
return;
}
button.removeStyleName( stylePrimaryName + "-down" ); //$NON-NLS-1$
button.removeStyleName( stylePrimaryName + "-hovering" ); //$NON-NLS-1$
// ElementUtils.blur(ToolbarButton.this.eventWrapper.getElement());
}
public void onMouseMove( Widget arg0, int arg1, int arg2 ) {
}
} );
}
/**
* Gets the enabled status of the button.
*
* @return boolean flag
*/
public boolean isEnabled() {
return enabled;
}
/**
* Sets the enabled status of the button.
*
* @param enabled
* boolean flag
*/
public void setEnabled( boolean enabled ) {
boolean prevState = this.enabled;
this.enabled = enabled;
if ( enabled ) {
button.removeStyleName( stylePrimaryName + "-disabled" ); //$NON-NLS-1$
if ( prevState == false && disabledImage != null ) {
// was disabled, remove old image and put in the enabled one
button.remove( currentImage );
button.add( calculateApporiateImage(), DockPanel.CENTER );
button.setCellHorizontalAlignment( this.image, DockPanel.ALIGN_CENTER );
button.setCellVerticalAlignment( this.image, DockPanel.ALIGN_MIDDLE );
}
} else {
button.addStyleName( stylePrimaryName + "-disabled" ); //$NON-NLS-1$
if ( prevState == true && disabledImage != null ) {
// was enabled, remove old image and put in the disabled one
button.remove( currentImage );
button.add( calculateApporiateImage(), DockPanel.CENTER );
button.setCellHorizontalAlignment( this.disabledImage, DockPanel.ALIGN_CENTER );
button.setCellVerticalAlignment( this.disabledImage, DockPanel.ALIGN_MIDDLE );
}
}
}
public void setTempDisabled( boolean disable ) {
button.setStyleName( this.enabled && !disable ? stylePrimaryName : stylePrimaryName + "-disabled" //$NON-NLS-1$
);
}
/**
* Gets the visibility of the button]
*
* @return boolean flag
*/
public boolean isVisible() {
return visible;
}
/**
* Sets the visibility of the button
*
* @param visible
* boolean flag
*/
public void setVisible( boolean visible ) {
this.visible = visible;
button.setVisible( visible );
}
/**
* Returns the managed PushButton object
*
* @return PushButton concreate object
*/
public FocusPanel getPushButton() {
return eventWrapper;
}
/**
* Returns the image displayed on this button.
*
* @return GWT Image
*/
public Image getImage() {
return image;
}
/**
* Returns the image displayed on this button.
*
* @return GWT Image
*/
public Image getDisabledImage() {
return disabledImage;
}
/**
* Sets the image displayed on this button.
*
* @param img
* GWT Image
*/
public void setImage( Image img ) {
this.image = img;
button.remove( currentImage );
Image curImage = calculateApporiateImage();
button.add( curImage, DockPanel.CENTER );
button.setCellHorizontalAlignment( curImage, DockPanel.ALIGN_CENTER );
button.setCellVerticalAlignment( curImage, DockPanel.ALIGN_MIDDLE );
}
/**
* Sets the image to be displayed on this button when disabled (greyed out).
*
* @param img
* GWT Image
*/
public void setDisabledImage( Image img ) {
if ( !isEnabled() ) {
// was enabled, remove old image and put in the disabled one
this.disabledImage = img;
button.remove( currentImage );
Image curImage = calculateApporiateImage();
button.add( curImage, DockPanel.CENTER );
button.setCellHorizontalAlignment( curImage, DockPanel.ALIGN_CENTER );
button.setCellVerticalAlignment( curImage, DockPanel.ALIGN_MIDDLE );
}
}
/**
* Returns the optional text to be displayed on this button.
*
* @return String
*/
public String getText() {
return text;
}
/**
* Sets the optional text to be displayed on this button.
*
* @param text
* String to be displayed
*/
public void setText( String text ) {
this.text = text;
label.setText( text );
}
/**
* Returns the click listener attached to the button instance.
*
* @return ClickListener
*/
public Command getCommand() {
return command;
}
/**
* Sets the ClickListener on the button. If a ClickListener was previously added to the button, it will be removed
* (let Nick know if you don't like this behavior).
*
* @param clickListener
*/
public void setCommand( Command cmd ) {
this.command = cmd;
}
/**
* Sets the text to be displayed in a hover-tip when a user hovers over the button
*
* @param toolTip
* String
*/
public void setToolTip( String toolTip ) {
this.toolTip = toolTip;
if ( toolTipWidget != null ) {
eventWrapper.removeMouseListener( toolTipWidget );
}
toolTipWidget = new ToolTip( toolTip, 1000 );
eventWrapper.addMouseListener( toolTipWidget );
}
/**
* Gets the text to be displayed in a hover-tip when a user hovers over the button
*
* @return String tooltip
*/
public String getToolTip() {
return toolTip;
}
protected Image calculateApporiateImage() {
currentImage = ( !enabled && disabledImage != null ) ? disabledImage : image;
return currentImage;
}
/**
* Gets the image to be displayed on this button when depressed
*
*/
public Image getDownImage() {
return downImage;
}
/**
* Sets the image to be displayed on this button when depressed
*
* @param img
* GWT Image
*/
public void setDownImage( Image downImage ) {
this.downImage = downImage;
}
public Image getDownImageDisabled() {
return downImageDisabled;
}
public void setDownImageDisabled( Image downImageDisabled ) {
this.downImageDisabled = downImageDisabled;
}
public void addClassName( String className ) {
this.className = className;
updateImg( this.image, true );
if ( this.disabledImage != null ) {
updateImg( this.disabledImage, false );
}
}
private void updateImg( final Image img, boolean enabled ) {
if ( !className.isEmpty() ) {
img.addStyleName( className );
}
String disabledStyle = "pentaho-imagebutton-disabled"; //$NON-NLS-1$
if ( !enabled ) {
img.addStyleName( disabledStyle );
} else {
img.removeStyleName( disabledStyle );
}
final String overStyle = "pentaho-imagebutton-hover"; //$NON-NLS-1$
// Mouse over
img.addMouseOverHandler( new MouseOverHandler() {
@Override
public void onMouseOver( MouseOverEvent event ) {
img.addStyleName( overStyle );
}
} );
// Mouse Out
img.addMouseOutHandler( new MouseOutHandler() {
@Override
public void onMouseOut( MouseOutEvent event ) {
img.removeStyleName( overStyle );
}
} );
final String downStyle = "pentaho-imagebutton-down"; //$NON-NLS-1$
// Mouse Down
img.addMouseDownHandler( new MouseDownHandler() {
@Override
public void onMouseDown( MouseDownEvent event ) {
img.addStyleName( downStyle );
}
} );
// Mouse Up
img.addMouseUpHandler( new MouseUpHandler() {
@Override
public void onMouseUp( MouseUpEvent event ) {
img.removeStyleName( downStyle );
}
} );
}
}