MyGUI支持tooltips, 也叫flyovers. 但仍有一些手工的工作要做来在程序中引用它们。
Layout
开始,你应该从一个layout开始:
<?xml version="1.0" encoding="UTF-8"?> <MyGUI type="Layout"> <Widget type="Widget" skin="PanelSmall" position="200 480 144 32" layer="ToolTip" name="tooltipPanel"> <Property key="Widget_Visible" value="false"/> <Widget type="Edit" skin="WordWrapSimple" position="3 3 138 92" align="Stretch"> <Property key="Edit_WordWrap" value="true"/> <Property key="Edit_Static" value="true"/> <Property key="Text_TextAlign" value="Left Top"/> <Property key="Widget_Caption" value="[ToolTip Info]"/> </Widget> </Widget> </MyGUI>
这个layout是完整的MyGUI直接可用的,你可使用任何你喜欢的MyGUI widgets,但这个在一个panel内部的一个edit的结合能到达目的(且有附加的优点,被作者在MyGUI Layout Editor中偏爱)。这个edit的标题caption是个不重要的预留位placeholder,可让他成为任何你想要的或者留着它。位置属性也不重要,因为会在代码中指定。这个片段是单独的,也可在其他需要tooltip的layout中引用。唯一要注意的是当在其他layout中包含它的时候确保它的父标记parent tag是<MyGUI>。
加载Layout
加载layout 并保存一些之后用的指针:
MyGUI::VectorWidgetPtr widgets = MyGUI::LayoutManager::getInstance().loadLayout("ToolTip.layout"); MyGUI::Widget *mToolTip = MyGUI::Gui::getInstance().findWidget<MyGUI::Widget>("toolTip"); // Alternative if ToolTip.layout contains solely the sample elements // MyGUI::Widget *toolTip = widgets[0]->castType<MyGUI::Widget>(); MyGUI::Edit *mToolTipEdit = mToolTip->getChildAt(0)->castType<MyGUI::Edit>();
上面的代码不是直接可用的. 应该插入到你的UI类初始化的地方。以m开头的变量应该是成员变量。
设立Widgets
设立一写窗口部件widgets来使用工具提示tooltip。开始,一个不是很有用的layout:
<?xml version="1.0" encoding="UTF-8"?> <MyGUI type="Layout"> <Widget type="Button" skin="Button" position="184 133 96 24" name="someButton"> <Property key="Widget_Caption" value="A Button"/> <Property key="Widget_NeedToolTip" value="true"/> </Widget> <Widget type="Edit" skin="Edit" position="152 65 160 24" name="passwordEdit"> <Property key="Edit_Password" value="true"/> <Property key="Edit_MaxTextLength" value="512"/> <Property key="Widget_NeedToolTip" value="true"/> </Widget> </MyGUI>
上面的layout会被加载,但不会很有用,因为它会在ogre的视图viewport中随机的悬挂。
第二,相应的c++代码:
mSomeButton->eventToolTip = MyGUI::newDelegate(this, &UIClass::notifyToolTip); mSomePasswordEdit->eventToolTip = MyGUI::newDelegate(this, &UIClass::notifyToolTip); // NOTE: MyGUI Edit widgets are actually composite widgets. // They have an automatically created client widget. // Note it is a client widget, NOT a child widget. // It does not show up in a layout file, so the NeedToolTip property must be set manually in code. // It is a descendant of MyGUI::Widget, so it has the usual API. mSomePasswordEdit->getClientWidget()->setNeedTooltip(); mSomePasswordEdit->getClientWidget()->eventToolTip = MyGUI::newDelegate(this, &UIClass::notifyToolTip); // Set some tooltip text. This text can be stored anywhere, as long as the notifyToolTip method // can get at it. Adding it to the widgets themelves is handy. mSomeButton->setUserString("tooltip", "Click me and nothing happens"); mSomePasswordEdit->setUserString("tooltip", "A password edit box. Be creative!"); mSomePasswordEdit->getClientWidget()->setUserString("tooltip", "A password edit box. Be creative!");
如果你想省略掉edit上的tip,你可以。它只在一个edit框外面3个像素可见。widget的屏幕区域的大部分都被其client widget客户部件占用。
Note this sample uses hard coded strings, rather than language manager tags.
Tooltip通知方法
最后, 大量注释的tooltip回调方法和一个帮助方法:
void UIClass::notifyToolTip(MyGUI::Widget *sender, const MyGUI::ToolTipInfo &info) { if (info.type == MyGUI::ToolTipInfo::Show) { // First fetch the viewport size. (Do not try to getParent()->getSize(). // Top level widgets do not have parents, but getParentSize() returns something useful anyway.) const MyGUI::IntSize &viewSize = mToolTip->getParentSize(); // Then set our tooltip panel size to something excessive... mToolTip->setSize(viewSize.width/2, viewSize.height/2); // ... update its caption to whatever the sender widget has for tooltip text // (You did use setUserString(), right?)... mToolTipText->setCaption(sender->getUserString("tooltip")); // ... fetch the new text size from the tooltip's Edit control... const MyGUI::IntSize &textsize = mToolTipText->getTextSize(); // ... and resize the tooltip panel to match it. The Stretch property on the Edit // control will see to it that the Edit control resizes along with it. // The constants are padding to fit in the edges of the PanelSmall skin; adjust as // necessary for your theme. mToolTip->setSize(textsize.width + 6, textsize.height + 6); // You can fade it in smooth if you like, but that gets obnoxious. mToolTip->setVisible(true); boundedMove(mToolTip, info.point); } else if (info.type == MyGUI::ToolTipInfo::Hide) { mToolTip->setVisible(false); } else if (info.type == MyGUI::ToolTipInfo::Move) { boundedMove(mToolTip, info.point); } } /** Move a widget to a point while making it stay in the viewport. @param moving The widget that will be moving. @param point The desired destination viewport coordinates (which may not be the final resting place of the widget). */ void UIClass::boundedMove(MyGUI::Widget *moving, const MyGUI::IntPoint & point) { const MyGUI::IntPoint offset(16, 16); // typical mouse cursor size - offset out from under it MyGUI::IntPoint boundedpoint = point + offset; const MyGUI::IntSize& size = moving->getSize(); const MyGUI::IntSize& view_size = moving->getParentSize(); if ((boundedpoint.left + size.width) > view_size.width) { boundedpoint.left -= offset.left + offset.left + size.width; } if ((boundedpoint.top + size.height) > view_size.height) { boundedpoint.top -= offset.top + offset.top + size.height; } moving->setPosition(boundedpoint); }
上面的代码可耻的是从MyGUI's Layout Editor来的, 和添加新代码来让tip窗口和tip文字确切的匹配大小。
唯一困难的是一些MyGUI widget是composite widget组合的。在启用tips时在他们客户区域clients有一点额外的工作。
相应ogre的代码及layout下载地址:http://download.youkuaiyun.com/detail/adfansong/5994641