![JAR search and dependency download from the Maven repository](/logo.png)
rwt.widgets.base.WidgetToolTip.js Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2009, 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
rwt.qx.Class.define( "rwt.widgets.base.WidgetToolTip", {
extend : rwt.widgets.base.Popup,
include : rwt.animation.VisibilityAnimationMixin,
construct : function() {
this.base( arguments );
this._label = new rwt.widgets.base.MultiCellWidget( [ "label" ] );
this._label.setParent( this );
this._pointer = null;
this._showTimer = new rwt.client.Timer();
this._showTimer.addEventListener( "interval", this._onshowtimer, this );
this._hideTimer = new rwt.client.Timer();
this._hideTimer.addEventListener( "interval", this._onhidetimer, this );
this._lastWidget = null;
this._fallbackMode = false;
this.addEventListener( "mouseover", this._onMouseOver );
this.addEventListener( "mouseout", this._onMouseOver );
this.addEventListener( "mouseup", this._onMouseUp );
this._config = {};
this.setRestrictToPageOnOpen( false );
},
statics : {
getInstance : function() {
return rwt.runtime.Singletons.get( rwt.widgets.base.WidgetToolTip );
},
setToolTipText : function( widget, value ) {
if( value != null && value !== "" ) {
var text = value;
if( widget.getUserData( "toolTipMarkupEnabled" ) !== true ) {
var EncodingUtil = rwt.util.Encoding;
text = EncodingUtil.escapeText( text, false );
text = EncodingUtil.replaceNewLines( text, "
" );
}
widget.setToolTipText( text );
widget.dispatchSimpleEvent( "updateToolTip", widget );
} else {
widget.setToolTipText( null );
}
}
},
properties : {
appearance : {
refine : true,
init : "widget-tool-tip"
},
mousePointerOffsetX : {
check : "Integer",
init : 1
},
mousePointerOffsetY : {
check : "Integer",
init : 20
},
boundToWidget : {
check : "rwt.widgets.base.Widget",
apply : "_applyBoundToWidget",
nullable : true,
init : null
},
pointers : {
nullable : true,
init : null,
themeable : true
},
textAlign : {
check : [ "left", "center", "right" ],
init : "center",
themeable : true,
apply : "_applyTextAlign"
}
},
members : {
_minZIndex : 1e7,
_targetDistance : 4,
updateText : function() {
if( this.getBoundToWidget() ) {
this._updateTextInternal();
if( this.getText() && !this._showTimer.isEnabled() ) {
this._onshowtimer();
}
if( !this.getText() ) {
this._quickHide();
}
}
},
getLastWidget : function() {
return this._lastWidget;
},
getFocusRoot : function() {
return null; // prevent setting clientDocument as a focused widget
},
_applyElement : function( value, old ) {
this.base( arguments, value, old );
},
_applyTextAlign : function( value ) {
this._label.setHorizontalChildrenAlign( value );
},
_getPointerElement : function() {
if( this._pointer == null ) {
this._pointer = document.createElement( "div" );
this._pointer.style.position = "absolute";
rwt.html.Style.setBackgroundRepeat( this._pointer, "no-repeat" );
rwt.html.Style.setPointerEvents( this._pointer, "none" );
this.getElement().appendChild( this._pointer );
}
return this._pointer;
},
_applyBoundToWidget : function( value, old ) {
if( value ) {
this.setParent( rwt.widgets.base.ClientDocument.getInstance() );
this._config = rwt.widgets.util.ToolTipConfig.getConfig( this.getBoundToWidget() );
this._showTimer.setInterval( this._config.appearDelay || 1000 );
this._hideTimer.setInterval( this._config.disappearDelay || 200 );
this.setAutoHide( this._config.autoHide !== false );
} else if( old ) {
this._config = {};
}
},
_beforeAppear : function() {
this.base( arguments );
this._stopShowTimer();
},
_beforeDisappear : function() {
this.base( arguments );
this._stopHideTimer();
},
_startShowTimer : function() {
if( this._allowQuickAppear()
&& ( this._config.appearOn === "enter" || this._lastWidget == this.getBoundToWidget() ) ) {
this._onshowtimer();
} else {
if( !this._showTimer.getEnabled() ) {
this._showTimer.start();
}
}
},
_allowQuickAppear : function() {
var now = ( new Date() ).getTime();
return this.isSeeable() || ( this._hideTimeStamp > 0 && ( now - this._hideTimeStamp ) < 300 );
},
_startHideTimer : function() {
if( !this._hideTimer.getEnabled() ) {
this._hideTimer.start();
}
},
_stopShowTimer : function() {
if( this._showTimer.getEnabled() ) {
this._showTimer.stop();
}
},
_stopHideTimer : function() {
if( this._hideTimer.getEnabled() ) {
this._hideTimer.stop();
}
},
_onMouseOver : function( event ) {
if( this._pointer && this._pointer === event.getDomTarget() ) {
return;
}
if( this.getElement().getElementsByTagName( "a" ).length > 0 ) {
return;
}
this._quickHide();
},
_onMouseUp : function() {
rwt.client.Timer.once( function() {
this._quickHide();
}, this, 100 );
},
_quickHide : function() {
if( this._disappearAnimation && this._disappearAnimation.isRunning() ) {
this._disappearAnimation.skip();
} else if( this._disappearAnimation && this._disappearAnimation.getDefaultRenderer().isActive() ) {
this._disappearAnimation.getDefaultRenderer().setActive( false );
this.hide();
this._disappearAnimation.getDefaultRenderer().setActive( true );
} else {
this.hide();
}
},
_handleMouseMove : function( event ) {
if( this.getBoundToWidget() ) {
if( this.isSeeable() && !this._hideTimer.getEnabled() ) {
if( this._config.disappearOn === "move" || this._fallbackMode ) {
this._startHideTimer();
} else if( this._config.disappearOn === "exitTargetBounds" ) {
var bounds = this._getTargetBounds();
var x = event.getPageX();
var y = event.getPageY();
if( ( x < bounds.left ) || ( x > ( bounds.left + bounds.width ) )
|| ( y < bounds.top ) || ( y > ( bounds.top + bounds.height ) ) )
{
this._startHideTimer();
}
}
} else {
if( this._config.appearOn === "rest" ) {
this._showTimer.restart(); // TODO: ignore small movements for start?
}
}
}
},
_onshowtimer : function() {
this._lastWidget = this.getBoundToWidget();
this._stopShowTimer();
this._stopHideTimer();
this._updateTextInternal();
if( this.getText() ) {
if( this._allowQuickAppear()
&& this._appearAnimation
&& this._appearAnimation.getDefaultRenderer().isActive()
&& !this.isSeeable() )
{
this._appearAnimation.getDefaultRenderer().setActive( false );
this.show();
this._appearAnimation.getDefaultRenderer().setActive( true );
} else {
this.show();
}
rwt.widgets.base.Widget.flushGlobalQueues(); // render new dimension
this._afterAppearLayout();
rwt.widgets.base.Widget.flushGlobalQueues(); // render position
} else if( this.getBoundToWidget().requestToolTipText ) {
this.getBoundToWidget().requestToolTipText();
}
},
_onhidetimer : function() {
if( this._config.appearOn === "rest" ) {
this._showTimer.start();
}
return this.hide();
},
_afterAppearLayout : function() {
var targetBounds = this._getTargetBounds();
this._fallbackMode = this._computeFallbackMode( targetBounds );
var viewportBounds = this._getViewportBounds();
var selfDimension = this._getOwnDimension();
var newPosition = this._getPositionAfterAppear( targetBounds, viewportBounds, selfDimension );
this.setLeft( newPosition[ 0 ] );
this.setTop( newPosition[ 1 ] );
var selfInnerBounds = {
left : newPosition[ 0 ] + this._cachedBorderLeft,
top : newPosition[ 1 ] + this._cachedBorderTop,
width : selfDimension.width - this._cachedBorderLeft - this._cachedBorderRight,
height : selfDimension.height - this._cachedBorderTop - this._cachedBorderBottom
};
this._renderPointer( targetBounds, selfInnerBounds );
},
_renderPointer : function( target, self ) {
var pointers = this.getPointers();
var enabled = this._config.position
&& this._config.position !== "mouse" && pointers
&& !this._fallbackMode;
this._getPointerElement().style.display = "none";
if( enabled ) {
var direction = this._getDirection( target, self );
if( direction === "up" && pointers[ 0 ] ) {
this._renderPointerUp( target, self );
} else if( direction === "down" && pointers[ 2 ] ) {
this._renderPointerDown( target, self );
} else if( direction === "left" && pointers[ 3 ] ) {
this._renderPointerLeft( target, self );
} else if( direction === "right" && pointers[ 1 ] ) {
this._renderPointerRight( target, self );
}
}
},
_renderPointerUp : function( target, self ) {
var pointer = this.getPointers()[ 0 ];
var element = this._getPointerElement();
rwt.html.Style.setBackgroundImage( element, pointer[ 0 ] );
element.style.width = pointer[ 1 ] + "px";
element.style.height = pointer[ 2 ] + "px";
element.style.top = ( -1 * pointer[ 2 ] ) + "px";
this._renderPointerHorizontalAlign( target, self, pointer );
element.style.display = "";
},
_renderPointerDown : function( target, self ) {
var pointer = this.getPointers()[ 2 ];
var element = this._getPointerElement();
rwt.html.Style.setBackgroundImage( element, pointer[ 0 ] );
element.style.width = pointer[ 1 ] + "px";
element.style.height = pointer[ 2 ] + "px";
element.style.top = self.height + "px";
this._renderPointerHorizontalAlign( target, self, pointer );
element.style.display = "";
},
_renderPointerLeft : function( target, self ) {
var pointer = this.getPointers()[ 3 ];
var element = this._getPointerElement();
var targetCenter = this._getBoundsCenter( target );
rwt.html.Style.setBackgroundImage( element, pointer[ 0 ] );
element.style.width = pointer[ 1 ] + "px";
element.style.height = pointer[ 2 ] + "px";
element.style.left = ( -1 * pointer[ 1 ] ) + "px";
element.style.top = Math.round( targetCenter.top - self.top - pointer[ 2 ] / 2 ) + "px";
element.style.display = "";
},
_renderPointerRight : function( target, self ) {
var pointer = this.getPointers()[ 1 ];
var element = this._getPointerElement();
var targetCenter = this._getBoundsCenter( target );
rwt.html.Style.setBackgroundImage( element, pointer[ 0 ] );
element.style.width = pointer[ 1 ] + "px";
element.style.height = pointer[ 2 ] + "px";
element.style.left = self.width + "px";
element.style.top = Math.round( targetCenter.top - self.top - pointer[ 2 ] / 2 ) + "px";
element.style.display = "";
},
_renderPointerHorizontalAlign : function( target, self, pointer ) {
var element = this._getPointerElement();
if( this._config.position === "align-left" ) {
var targetedLeft = target.left
+ this._targetDistance
+ this._cachedBorderLeft
+ this.getPaddingLeft();
element.style.left = Math.round( targetedLeft - self.left ) + "px";
} else {
var targetCenter = this._getBoundsCenter( target );
element.style.left = Math.round( targetCenter.left - self.left - pointer[ 1 ] / 2 ) + "px";
}
},
_getDirection : function( target, self ) {
var targetBetweenSelfX = target.left >= self.left && target.left <= ( self.left + self.width );
var selfBetweenTargetX = self.left >= target.left && self.left <= ( target.left + target.width );
if( targetBetweenSelfX || selfBetweenTargetX ) {
return self.top > target.top ? "up" : "down";
} else {
return self.left > target.left ? "left" : "right";
}
},
_getBoundsCenter : function( bounds ) { // may return float!
return {
left : bounds.left + bounds.width / 2,
top : bounds.top + bounds.height / 2
};
},
_updateTextInternal : function() {
this._label.setCellContent( 0, this.getBoundToWidget().getToolTipText() );
},
_computeFallbackMode : function( target ) {
var viewport = this._getViewportBounds();
var left = target.left;
var right = target.left + target.width;
var top = target.top;
var bottom = target.top + target.height;
if( left < viewport.left
|| top < viewport.top
|| right > viewport.left + viewport.width
|| bottom > viewport.top + viewport.height )
{
return true;
}
var display = this.getElement().style.display;
this.getElement().style.display = "none";
var targetElements = [
document.elementFromPoint( left + target.width / 2 - viewport.left, top + 1 - viewport.top ),
document.elementFromPoint( right - 1 - viewport.left, top + target.height / 2 - viewport.top ),
document.elementFromPoint( left + target.width / 2 - viewport.left, bottom - 1 - viewport.top ),
document.elementFromPoint( left + 1 - viewport.left, top + target.height / 2 - viewport.top )
];
this.getElement().style.display = display;
var boundWidget = this.getBoundToWidget();
for( var i = 0; i < 4; i++ ) {
var widget = rwt.event.EventHandlerUtil.getOriginalTargetObject( targetElements[ i ] );
if( widget == null || !( boundWidget === widget || boundWidget.contains( widget ) ) ) {
return true;
}
}
return false; // all four edges are visible on screen
},
getText : function() {
return this._label.getCellContent( 0 );
},
_getPositionAfterAppear : function( target, viewport, self ) {
var result;
if( !this._fallbackMode ) {
switch( this._config.position ) {
case "horizontal-center":
result = this._positionHorizontalCenter( target, viewport, self );
break;
case "align-left":
result = this._positionAlignLeft( target, viewport, self );
break;
case "vertical-center":
result = this._positionVerticalCenter( target, viewport, self );
break;
default:
result = this._positionMouseRelative( target, viewport, self );
break;
}
} else {
result = this._positionMouseRelative( target, viewport, self );
}
result[ 0 ] = Math.min( result[ 0 ], viewport.left + viewport.width - self.width );
result[ 1 ] = Math.min( result[ 1 ], viewport.top + viewport.height - self.height );
result[ 0 ] = Math.max( result[ 0 ], viewport.left );
result[ 1 ] = Math.max( result[ 1 ], viewport.top );
return result;
},
_positionMouseRelative : function() {
return [
rwt.event.MouseEvent.getPageX() + this.getMousePointerOffsetX(),
rwt.event.MouseEvent.getPageY() + this.getMousePointerOffsetY()
];
},
_positionHorizontalCenter : function( target, viewport, self ) {
var left = this._getHorizontalOffsetCentered( target, self, viewport );
var top = this._getVerticalOffsetAutoByAbsolutePosition( target, self, viewport );
return [ left, top ];
},
_positionAlignLeft : function( target, viewport, self ) {
var left = this._getHorizontalOffsetAlignLeft( target, self, viewport );
var top = this._getVerticalOffsetAutoByAbsolutePosition( target, self, viewport );
return [ left, top ];
},
_positionVerticalCenter : function( target, viewport, self ) {
var left = this._getHorizontalOffsetAuto( target, self, viewport );
var top = this._getVerticalOffsetCentered( target, self, viewport );
return [ left, top ];
},
_getVerticalOffsetAutoByAbsolutePosition : function( target, self ) {
var top = this._getVerticalOffsetTop( target, self );
if( top < 30 ) {
top = this._getVerticalOffsetBottom( target, self );
}
return top;
},
_getVerticalOffsetTop : function( target, self ) {
return target.top - self.height - this._getTargetDistance( "down" );
},
_getVerticalOffsetBottom : function( target ) {
return target.top + target.height + this._getTargetDistance( "up" );
},
_getHorizontalOffsetCentered : function( target, self ) {
return Math.round( target.left + ( target.width / 2 ) - self.width / 2 );
},
_getHorizontalOffsetAlignLeft : function( target ) {
return target.left + this._targetDistance;
},
_getHorizontalOffsetAuto : function( target, self, viewport ) {
var leftSpace = target.left;
var rightSpace = viewport.width - leftSpace - target.width;
if( leftSpace > rightSpace ) {
return target.left - self.width - this._getTargetDistance( "right" );
} else {
return target.left + target.width + this._getTargetDistance( "left" );
}
},
_getVerticalOffsetCentered : function( target, self ) {
return Math.round( target.top + ( target.height / 2 ) - self.height / 2 );
},
_getTargetBounds : function() {
var widget = this.getBoundToWidget();
var location = rwt.html.Location.get( widget.getElement() );
var result = {
"left" : location.left,
"top" : location.top,
"width" : widget.getBoxWidth(),
"height" : widget.getBoxHeight()
};
if( widget.getToolTipTargetBounds ) {
var innerBounds = widget.getToolTipTargetBounds();
result.left += innerBounds.left;
result.top += innerBounds.top;
result.width = innerBounds.width;
result.height = innerBounds.height;
}
return result;
},
_getViewportBounds : function() {
var viewport = rwt.html.Viewport;
return {
"left" : viewport.getScrollLeft(),
"top" : viewport.getScrollTop(),
"width" : viewport.getWidth(),
"height" : viewport.getHeight()
};
},
_getOwnDimension : function() {
return { "width" : this.getBoxWidth(), "height" : this.getBoxHeight() };
},
_getTargetDistance : function( direction ) {
var overlap = typeof this._config.overlap === "number" ? this._config.overlap : 4;
var pointers = this.getPointers();
if( direction === "up" && pointers && pointers[ 0 ] ) {
return pointers[ 0 ][ 2 ] - overlap;
} else if( direction === "down" && pointers && pointers[ 2 ] ) {
return pointers[ 2 ][ 2 ] - overlap;
} else if( direction === "left" && pointers && pointers[ 3 ] ) {
return pointers[ 3 ][ 1 ] - overlap;
} else if( direction === "right" && pointers && pointers[ 1 ] ) {
return pointers[ 1 ][ 1 ] - overlap;
} else {
return this._targetDistance;
}
}
},
destruct : function() {
this._disposeObjects("_showTimer", "_hideTimer", "_label");
}
} );
© 2015 - 2025 Weber Informatics LLC | Privacy Policy