在第二生里,菜单是缺少不了的。菜单提供了简单层次关系的一种表达方式,方便表达复杂的层次关系,并且方便写说明书,方便售后服务人员的描述,方便培训。因此,在一个程序没有菜单,往往带来很多不方便的地方。登录界面的菜单如下图:
从上图可以看到
File、Edit、Help几个菜单,那么它是怎么样实现的呢?下面就来分析相关的代码。
下面先来看菜单定义的继承关系:
class LLMenuItemGL : public LLView
可以看到每个菜单项是一个子窗口显示的。
下面就来分析菜单项显示的函数:
#001 void LLMenuItemGL::draw( void )
#002 {
#003
// *FIX: This can be optimized by using switches. Want to avoid
#004
// that until the functionality is finalized.
#005
#006
// HACK: Brief items don't highlight. Pie menu takes care of it. JC
#007
// let disabled items be highlighted, just don't draw them as such
查看菜单是否可以显示,高亮度显示。
#008
if( getEnabled() && getHighlight() && !mBriefItem)
#009
{
#010
gGL.color4fv( sHighlightBackground.mV );
#011
gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 );
#012
}
#013
#014
LLColor4 color;
#015
判断是否显示文字。
#016
U8 font_style = mStyle;
#017
if (getEnabled() && !mDrawTextDisabled )
#018
{
#019
font_style |= LLFontGL::DROP_SHADOW_SOFT;
#020
}
#021
判断是否高亮度显示,选择合适的颜色。
#022
if ( getEnabled() && getHighlight() )
#023
{
#024
color = sHighlightForeground;
#025
}
#026
else if( getEnabled() && !mDrawTextDisabled )
#027
{
#028
color = sEnabledColor;
#029
}
#030
else
#031
{
#032
color = sDisabledColor;
#033
}
#034
显示菜单的文字。
#035
// Draw the text on top.
#036
if (mBriefItem)
#037
{
#038
mFont->render( mLabel, 0, BRIEF_PAD_PIXELS / 2, 0, color,
#039
LLFontGL::LEFT, LLFontGL::BOTTOM, font_style );
#040
}
#041
else
#042
{
#043
if( !mDrawBoolLabel.empty() )
#044
{
#045
mFont->render( mDrawBoolLabel.getWString(), 0, (F32)LEFT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color,
#046
LLFontGL::LEFT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL, FALSE
#047 );
#048
}
#049
mFont->render( mLabel.getWString(), 0, (F32)LEFT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color,
#050
LLFontGL::LEFT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL, FALSE );
#051
if( !mDrawAccelLabel.empty() )
#052
{
#053
mFont->render( mDrawAccelLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) +
#054 1.f, color,
#055
LLFontGL::RIGHT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL,
#056 FALSE );
#057
}
#058
if( !mDrawBranchLabel.empty() )
#059
{
#060
mFont->render( mDrawBranchLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) +
#061 1.f, color,
#062
LLFontGL::RIGHT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL,
#063 FALSE );
#064
}
#065
}
#066
显示快捷键。
#067
// underline "jump" key only when keyboard navigation has been initiated
#068
if (getMenu()->jumpKeysActive() && LLMenuGL::getKeyboardMode())
#069
{
#070
LLString upper_case_label = mLabel.getString();
#071
LLString::toUpper(upper_case_label);
#072
std::string::size_type offset = upper_case_label.find(mJumpKey);
#073
if (offset != std::string::npos)
#074
{
#075
S32 x_begin = LEFT_PLAIN_PIXELS + mFont->getWidth(mLabel, 0, offset);
#076
S32 x_end = LEFT_PLAIN_PIXELS + mFont->getWidth(mLabel, 0, offset + 1);
#077
gl_line_2d(x_begin, (MENU_ITEM_PADDING / 2) + 1, x_end, (MENU_ITEM_PADDING / 2) + 1);
#078
}
#079
}
#080
#081
// clear got hover every frame
#082
setHover(FALSE);
#083 }
通过函数学会怎样输出菜单项,怎么样显示颜色。