2012-04-14 15:47:44 +00:00
# include "tooltips.hpp"
2012-04-15 19:14:14 +00:00
# include "window_manager.hpp"
2012-04-16 20:58:16 +00:00
# include "../mwworld/class.hpp"
2012-04-15 19:14:14 +00:00
# include <boost/lexical_cast.hpp>
2012-04-14 15:47:44 +00:00
using namespace MWGui ;
using namespace MyGUI ;
2012-04-15 19:14:14 +00:00
ToolTips : : ToolTips ( WindowManager * windowManager ) :
2012-04-14 15:47:44 +00:00
Layout ( " openmw_tooltips.xml " )
, mGameMode ( true )
2012-04-15 19:14:14 +00:00
, mWindowManager ( windowManager )
2012-04-16 13:00:44 +00:00
, mFullHelp ( false )
2012-04-14 15:47:44 +00:00
{
getWidget ( mDynamicToolTipBox , " DynamicToolTipBox " ) ;
mDynamicToolTipBox - > setVisible ( false ) ;
// turn off mouse focus so that getMouseFocusWidget returns the correct widget,
// even if the mouse is over the tooltip
mDynamicToolTipBox - > setNeedMouseFocus ( false ) ;
mMainWidget - > setNeedMouseFocus ( false ) ;
}
void ToolTips : : onFrame ( float frameDuration )
{
/// \todo Store a MWWorld::Ptr in the widget user data, retrieve it here and construct a tooltip dynamically
2012-04-15 22:16:35 +00:00
/// \todo we are destroying/creating the tooltip widgets every frame here,
/// because the tooltip might change (e.g. when trap is activated)
/// is there maybe a better way (listener when the object changes)?
for ( size_t i = 0 ; i < mDynamicToolTipBox - > getChildCount ( ) ; + + i )
{
mDynamicToolTipBox - > _destroyChildWidget ( mDynamicToolTipBox - > getChildAt ( i ) ) ;
}
2012-04-14 15:47:44 +00:00
const IntSize & viewSize = RenderManager : : getInstance ( ) . getViewSize ( ) ;
2012-04-15 15:10:08 +00:00
if ( ! mGameMode )
{
Widget * focus = InputManager : : getInstance ( ) . getMouseFocusWidget ( ) ;
2012-04-15 19:14:14 +00:00
if ( focus = = 0 )
{
2012-04-15 22:16:35 +00:00
mDynamicToolTipBox - > setVisible ( false ) ;
2012-04-15 19:14:14 +00:00
return ;
}
2012-04-15 22:16:35 +00:00
IntSize tooltipSize ;
2012-04-15 19:14:14 +00:00
std : : string type = focus - > getUserString ( " ToolTipType " ) ;
std : : string text = focus - > getUserString ( " ToolTipText " ) ;
2012-04-18 14:53:56 +00:00
ToolTipInfo info ;
2012-04-15 22:16:35 +00:00
if ( type = = " " )
2012-04-15 19:14:14 +00:00
{
2012-04-15 22:16:35 +00:00
mDynamicToolTipBox - > setVisible ( false ) ;
2012-04-15 19:14:14 +00:00
return ;
2012-04-18 14:53:56 +00:00
}
2012-04-15 22:16:35 +00:00
else if ( type = = " Text " )
2012-04-18 14:53:56 +00:00
{
info . caption = text ;
}
2012-04-15 22:16:35 +00:00
else if ( type = = " CaptionText " )
{
std : : string caption = focus - > getUserString ( " ToolTipCaption " ) ;
2012-04-18 14:53:56 +00:00
info . caption = caption ;
info . text = text ;
2012-04-15 22:16:35 +00:00
}
else if ( type = = " ImageCaptionText " )
{
std : : string caption = focus - > getUserString ( " ToolTipCaption " ) ;
std : : string image = focus - > getUserString ( " ToolTipImage " ) ;
2012-04-16 13:00:44 +00:00
std : : string sizeString = focus - > getUserString ( " ToolTipImageSize " ) ;
2012-04-18 14:53:56 +00:00
info . text = text ;
info . caption = caption ;
info . icon = image ;
2012-04-15 22:16:35 +00:00
}
2012-04-18 14:53:56 +00:00
tooltipSize = createToolTip ( info ) ;
2012-04-14 15:47:44 +00:00
2012-04-15 15:10:08 +00:00
IntPoint tooltipPosition = InputManager : : getInstance ( ) . getMousePosition ( ) + IntPoint ( 0 , 24 ) ;
// make the tooltip stay completely in the viewport
2012-04-17 14:49:28 +00:00
if ( ( tooltipPosition . left + tooltipSize . width ) > viewSize . width )
2012-04-15 15:10:08 +00:00
{
2012-04-17 14:49:28 +00:00
tooltipPosition . left = viewSize . width - tooltipSize . width ;
2012-04-15 15:10:08 +00:00
}
2012-04-17 14:49:28 +00:00
if ( ( tooltipPosition . top + tooltipSize . height ) > viewSize . height )
2012-04-15 15:10:08 +00:00
{
2012-04-17 14:49:28 +00:00
tooltipPosition . top = viewSize . height - tooltipSize . height ;
2012-04-15 15:10:08 +00:00
}
2012-04-17 14:49:28 +00:00
setCoord ( tooltipPosition . left , tooltipPosition . top , tooltipSize . width , tooltipSize . height ) ;
2012-04-17 14:00:13 +00:00
mDynamicToolTipBox - > setVisible ( true ) ;
2012-04-14 15:47:44 +00:00
}
2012-04-15 15:10:08 +00:00
else
2012-04-14 15:47:44 +00:00
{
2012-04-15 15:10:08 +00:00
if ( ! mFocusObject . isEmpty ( ) )
{
2012-04-15 19:14:14 +00:00
IntSize tooltipSize = getToolTipViaPtr ( ) ;
2012-04-15 15:10:08 +00:00
2012-04-15 19:14:14 +00:00
// adjust tooltip size to fit its content, position it above the crosshair
/// \todo Slide the tooltip along the bounding box of the focused object (like in Morrowind)
setCoord ( viewSize . width / 2 - ( tooltipSize . width ) / 2.f ,
viewSize . height / 2 - ( tooltipSize . height ) - 32 ,
tooltipSize . width ,
tooltipSize . height ) ;
}
else
mDynamicToolTipBox - > setVisible ( false ) ;
}
}
2012-04-15 15:10:08 +00:00
2012-04-15 19:14:14 +00:00
void ToolTips : : enterGameMode ( )
{
mGameMode = true ;
}
2012-04-15 15:10:08 +00:00
2012-04-15 19:14:14 +00:00
void ToolTips : : enterGuiMode ( )
{
mGameMode = false ;
}
2012-04-15 15:10:08 +00:00
2012-04-15 19:14:14 +00:00
void ToolTips : : setFocusObject ( const MWWorld : : Ptr & focus )
{
mFocusObject = focus ;
}
2012-04-15 15:10:08 +00:00
2012-04-15 19:14:14 +00:00
IntSize ToolTips : : getToolTipViaPtr ( )
{
// this the maximum width of the tooltip before it starts word-wrapping
setCoord ( 0 , 0 , 300 , 300 ) ;
2012-04-15 15:10:08 +00:00
2012-04-15 19:14:14 +00:00
IntSize tooltipSize ;
2012-04-15 15:10:08 +00:00
2012-04-16 20:58:16 +00:00
const MWWorld : : Class & object = MWWorld : : Class : : get ( mFocusObject ) ;
if ( ! object . hasToolTip ( mFocusObject ) )
2012-04-15 19:14:14 +00:00
{
2012-04-16 20:58:16 +00:00
mDynamicToolTipBox - > setVisible ( false ) ;
2012-04-15 19:14:14 +00:00
}
2012-04-16 20:58:16 +00:00
else
2012-04-15 19:14:14 +00:00
{
2012-04-16 20:58:16 +00:00
mDynamicToolTipBox - > setVisible ( true ) ;
2012-04-15 15:10:08 +00:00
2012-04-16 20:58:16 +00:00
ToolTipInfo info = object . getToolTipInfo ( mFocusObject , mWindowManager - > getEnvironment ( ) ) ;
2012-04-18 14:53:56 +00:00
tooltipSize = createToolTip ( info ) ;
2012-04-15 19:14:14 +00:00
}
2012-04-15 15:10:08 +00:00
2012-04-15 19:14:14 +00:00
return tooltipSize ;
}
2012-04-15 15:10:08 +00:00
2012-04-15 19:14:14 +00:00
void ToolTips : : findImageExtension ( std : : string & image )
{
int len = image . size ( ) ;
if ( len < 4 ) return ;
2012-04-15 15:10:08 +00:00
2012-04-15 19:14:14 +00:00
if ( ! Ogre : : ResourceGroupManager : : getSingleton ( ) . resourceExists ( Ogre : : ResourceGroupManager : : AUTODETECT_RESOURCE_GROUP_NAME , image ) )
{
// Change texture extension to .dds
image [ len - 3 ] = ' d ' ;
image [ len - 2 ] = ' d ' ;
image [ len - 1 ] = ' s ' ;
}
}
2012-04-15 15:10:08 +00:00
2012-04-18 14:53:56 +00:00
IntSize ToolTips : : createToolTip ( const ToolTipInfo & info )
2012-04-15 19:14:14 +00:00
{
2012-04-18 14:53:56 +00:00
std : : string caption = info . caption ;
std : : string image = info . icon ;
int imageSize = ( image ! = " " ) ? 32 : 0 ;
std : : string text = info . text ;
2012-04-15 19:14:14 +00:00
// remove the first newline (easier this way)
2012-04-18 14:53:56 +00:00
if ( text . size ( ) > 0 & & text [ 0 ] = = ' \n ' )
text . erase ( 0 , 1 ) ;
2012-04-15 15:10:08 +00:00
2012-04-17 14:49:28 +00:00
// this the maximum width of the tooltip before it starts word-wrapping
setCoord ( 0 , 0 , 300 , 300 ) ;
const IntPoint padding ( 8 , 8 ) ;
const int imageCaptionHPadding = 8 ;
const int imageCaptionVPadding = 4 ;
2012-04-15 19:14:14 +00:00
std : : string realImage = " icons \\ " + image ;
findImageExtension ( realImage ) ;
2012-04-15 15:10:08 +00:00
2012-04-15 19:14:14 +00:00
EditBox * captionWidget = mDynamicToolTipBox - > createWidget < EditBox > ( " NormalText " , IntCoord ( 0 , 0 , 300 , 300 ) , Align : : Left | Align : : Top , " ToolTipCaption " ) ;
captionWidget - > setProperty ( " Static " , " true " ) ;
captionWidget - > setCaption ( caption ) ;
2012-04-17 14:49:28 +00:00
IntSize captionSize = captionWidget - > getTextSize ( ) ;
int captionHeight = std : : max ( captionSize . height , imageSize ) ;
EditBox * textWidget = mDynamicToolTipBox - > createWidget < EditBox > ( " SandText " , IntCoord ( 0 , captionHeight + imageCaptionVPadding , 300 , 300 - captionHeight - imageCaptionVPadding ) , Align : : Stretch , " ToolTipText " ) ;
2012-04-15 19:14:14 +00:00
textWidget - > setProperty ( " Static " , " true " ) ;
textWidget - > setProperty ( " MultiLine " , " true " ) ;
2012-04-15 22:16:35 +00:00
textWidget - > setProperty ( " WordWrap " , " true " ) ;
2012-04-18 14:53:56 +00:00
textWidget - > setCaption ( text ) ;
2012-04-17 14:49:28 +00:00
textWidget - > setTextAlign ( Align : : HCenter | Align : : Top ) ;
2012-04-15 19:14:14 +00:00
IntSize textSize = textWidget - > getTextSize ( ) ;
2012-04-15 15:10:08 +00:00
2012-04-15 19:14:14 +00:00
captionSize + = IntSize ( imageSize , 0 ) ; // adjust for image
2012-04-17 14:49:28 +00:00
IntSize totalSize = IntSize ( std : : max ( textSize . width , captionSize . width + ( ( image ! = " " ) ? imageCaptionHPadding : 0 ) ) ,
2012-04-18 14:53:56 +00:00
( ( text ! = " " ) ? textSize . height + imageCaptionVPadding : 0 ) + captionHeight ) ;
2012-04-15 15:10:08 +00:00
2012-04-17 14:49:28 +00:00
if ( image ! = " " )
{
ImageBox * imageWidget = mDynamicToolTipBox - > createWidget < ImageBox > ( " ImageBox " ,
IntCoord ( ( totalSize . width - captionSize . width - imageCaptionHPadding ) / 2 , 0 , imageSize , imageSize ) ,
Align : : Left | Align : : Top , " ToolTipImage " ) ;
imageWidget - > setImageTexture ( realImage ) ;
imageWidget - > setPosition ( imageWidget - > getPosition ( ) + padding ) ;
}
2012-04-15 15:10:08 +00:00
2012-04-17 14:49:28 +00:00
captionWidget - > setCoord ( ( totalSize . width - captionSize . width ) / 2 + imageSize ,
( captionHeight - captionSize . height ) / 2 ,
captionSize . width - imageSize ,
captionSize . height ) ;
2012-04-15 15:10:08 +00:00
2012-04-17 14:49:28 +00:00
captionWidget - > setPosition ( captionWidget - > getPosition ( ) + padding ) ;
textWidget - > setPosition ( textWidget - > getPosition ( ) + IntPoint ( 0 , padding . top ) ) ; // only apply vertical padding, the horizontal works automatically due to Align::HCenter
2012-04-15 15:10:08 +00:00
2012-04-17 14:49:28 +00:00
totalSize + = IntSize ( padding . left * 2 , padding . top * 2 ) ;
2012-04-14 15:47:44 +00:00
2012-04-17 14:49:28 +00:00
return totalSize ;
2012-04-15 22:16:35 +00:00
}
2012-04-15 19:14:14 +00:00
std : : string ToolTips : : toString ( const float value )
2012-04-14 15:47:44 +00:00
{
2012-04-15 19:14:14 +00:00
std : : ostringstream stream ;
stream < < std : : setprecision ( 3 ) < < value ;
return stream . str ( ) ;
2012-04-14 15:47:44 +00:00
}
2012-04-15 19:14:14 +00:00
std : : string ToolTips : : toString ( const int value )
2012-04-14 15:47:44 +00:00
{
2012-04-15 19:14:14 +00:00
std : : ostringstream stream ;
stream < < value ;
return stream . str ( ) ;
2012-04-14 15:47:44 +00:00
}
2012-04-15 15:10:08 +00:00
2012-04-16 20:58:16 +00:00
std : : string ToolTips : : getValueString ( const int value , const std : : string & prefix )
2012-04-15 15:10:08 +00:00
{
2012-04-15 19:14:14 +00:00
if ( value = = 0 )
return " " ;
else
2012-04-16 20:58:16 +00:00
return " \n " + prefix + " : " + toString ( value ) ;
}
std : : string ToolTips : : getMiscString ( const std : : string & text , const std : : string & prefix )
{
if ( text = = " " )
return " " ;
else
return " \n " + prefix + " : " + text ;
2012-04-15 15:10:08 +00:00
}
2012-04-16 13:00:44 +00:00
void ToolTips : : toggleFullHelp ( )
{
mFullHelp = ! mFullHelp ;
}
2012-04-16 20:58:16 +00:00
bool ToolTips : : getFullHelp ( ) const
{
return mFullHelp ;
}