前面介绍按钮可以显示在窗口里,以及这个类的声明,现在来仔细地分析一下它是怎么样实现名称显示的。
在构造函数里先保存传送入来的名称,如下:
#001
mUnselectedLabel = unselected_label;
#002
mSelectedLabel = selected_label;
#003
从类声明里可以看到
mSelectedLabel和mUnselectedLabel都是声明为类LLUIString的实例,由于类LLUIString只支持LLString构造函数的名称,因此它不能显示UNICODE的字符串。
显示按钮的函数如下:
#001 void LLButton::draw()
#002 {
查看这个按键是否可以显示。
#003
if( getVisible() )
#004
{
设置动态效果。
#005
BOOL flash = FALSE;
#006
if( mFlashing )
#007
{
#008
F32 elapsed = mFlashingTimer.getElapsedTimeF32();
#009
S32 flash_count = S32(elapsed * LLUI::sConfigGroup->getF32("ButtonFlashRate") * 2.f);
#010
// flash on or off?
#011
flash = (flash_count % 2 == 0) || flash_count > (F32)LLUI::sConfigGroup->getS32("ButtonFlashCount");
#012
}
#013
是否有输入焦点。
#014
BOOL pressed_by_keyboard = FALSE;
#015
if (hasFocus())
#016
{
#017
pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mCommitOnReturn && gKeyboard->getKeyDown(KEY_RETURN));
#018
}
#019
没有选中的图片显示。
#020
// Unselected image assignments
#021
S32 local_mouse_x;
#022
S32 local_mouse_y;
#023
LLCoordWindow cursor_pos_window;
#024
getWindow()->getCursorPosition(&cursor_pos_window);
#025
LLCoordGL cursor_pos_gl;
#026
getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl);
#027
cursor_pos_gl.mX = llround((F32)cursor_pos_gl.mX / LLUI::sGLScaleFactor.mV[VX]);
#028
cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]);
#029
screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y);
#030
按下显示的处理,主要选择不同的图片。
#031
BOOL pressed = pressed_by_keyboard
#032
|| (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y))
#033
|| mToggleState;
#034
#035
BOOL use_glow_effect = FALSE;
#036
if ( mNeedsHighlight || flash )
#037
{
#038
if (pressed)
#039
{
#040
if (mImageHoverSelected)
#041
{
#042
mImagep = mImageHoverSelected;
#043
}
#044
else
#045
{
#046
mImagep = mImageSelected;
#047
use_glow_effect = TRUE;
#048
}
#049
}
#050
else
#051
{
#052
if (mImageHoverUnselected)
#053
{
#054
mImagep = mImageHoverUnselected;
#055
}
#056
else
#057
{
#058
mImagep = mImageUnselected;
#059
use_glow_effect = TRUE;
#060
}
#061
}
#062
}
#063
else if ( pressed )
#064
{
#065
mImagep = mImageSelected;
#066
}
#067
else
#068
{
#069
mImagep = mImageUnselected;
#070
}
#071
#072
// Override if more data is available
#073
// HACK: Use gray checked state to mean either:
#074
// enabled and tentative
#075
// or
#076
// disabled but checked
保存选择的显示图片。
#077
if (!mImageDisabledSelected.isNull() && ( (getEnabled() && getTentative()) || (!getEnabled() && pressed ) ) )
#078
{
#079
mImagep = mImageDisabledSelected;
#080
}
#081
else if (!mImageDisabled.isNull() && !getEnabled() && !pressed)
#082
{
#083
mImagep = mImageDisabled;
#084
}
#085
#086
if (mNeedsHighlight && !mImagep)
#087
{
#088
use_glow_effect = TRUE;
#089
}
#090
#091
// Figure out appropriate color for the text
#092
LLColor4 label_color;
#093
获取按钮显示的颜色。
#094
// label changes when button state changes, not when pressed
#095
if ( getEnabled() )
#096
{
#097
if ( mToggleState )
#098
{
#099
label_color = mSelectedLabelColor;
#100
}
#101
else
#102
{
#103
label_color = mUnselectedLabelColor;
#104
}
#105
}
#106
else
#107
{
#108
if ( mToggleState )
#109
{
#110
label_color = mDisabledSelectedLabelColor;
#111
}
#112
else
#113
{
#114
label_color = mDisabledLabelColor;
#115
}
#116
}
#117
准备显示的字符串。
#118
// Unselected label assignments
#119
LLWString label;
#120
#121
if( mToggleState )
#122
{
#123
if( getEnabled() || mDisabledSelectedLabel.empty() )
#124
{
#125
label = mSelectedLabel;
#126
}
#127
else
#128
{
#129
label = mDisabledSelectedLabel;
#130
}
#131
}
#132
else
#133
{
#134
if( getEnabled() || mDisabledLabel.empty() )
#135
{
#136
label = mUnselectedLabel;
#137
}
#138
else
#139
{
#140
label = mDisabledLabel;
#141
}
#142
}
#143
#144
//测试一下。
#145
//label = L"测试
";
#146
显示按钮的边界。
#147
// draw default button border
#148
if (getEnabled() && mBorderEnabled && gFocusMgr.getAppHasFocus()) // because we're the default button in a panel
#149
{
#150
drawBorder(LLUI::sColorsGroup->getColor( "ButtonBorderColor" ), BORDER_SIZE);
#151
}
#152
#153
// overlay with keyboard focus border
#154
if (hasFocus())
#155
{
#156
F32 lerp_amt = gFocusMgr.getFocusFlashAmt();
#157
drawBorder(gFocusMgr.getFocusColor(), llround(lerp(1.f, 3.f, lerp_amt)));
#158
}
#159
#160
if (use_glow_effect)
#161
{
#162
mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f));
#163
}
#164
else
#165
{
#166
mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f));
#167
}
#168
#169
// Draw button image, if available.
#170
// Otherwise draw basic rectangular button.
#171
if( mImagep.notNull() && !mScaleImage)
#172
{
#173
mImagep->draw(0, 0, getEnabled() ? mImageColor : mDisabledImageColor );
#174
if (mCurGlowStrength > 0.01f)
#175
{
#176
gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
#177
mImagep->drawSolid(0, 0, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
#178
gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#179
}
#180
}
#181
else
#182
if ( mImagep.notNull() && mScaleImage)
#183
{
#184
mImagep->draw(0, 0, getRect().getWidth(), getRect().getHeight(), getEnabled() ? mImageColor : mDisabledImageColor );
#185
if (mCurGlowStrength > 0.01f)
#186
{
#187
gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
#188
mImagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
#189
gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#190
}
#191
}
#192
else
#193
{
#194
// no image
#195
llwarns << "No image for button " << getName() << llendl;
#196
// draw it in pink so we can find it
#197
gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4::pink1, FALSE);
#198
}
#199
计算显示字符串的位置。
#200
// let overlay image and text play well together
#201
S32 text_left = mLeftHPad;
#202
S32 text_right = getRect().getWidth() - mRightHPad;
#203
S32 text_width = getRect().getWidth() - mLeftHPad - mRightHPad;
#204
#205
// draw overlay image
#206
if (mImageOverlay.notNull())
#207
{
#208
// get max width and height (discard level 0)
#209
S32 overlay_width = mImageOverlay->getWidth();
#210
S32 overlay_height = mImageOverlay->getHeight();
#211
#212
F32 scale_factor = llmin((F32)getRect().getWidth() / (F32)overlay_width, (F32)getRect().getHeight() / (F32)overlay_height, 1.f);
#213
overlay_width = llround((F32)overlay_width * scale_factor);
#214
overlay_height = llround((F32)overlay_height * scale_factor);
#215
#216
S32 center_x = getLocalRect().getCenterX();
#217
S32 center_y = getLocalRect().getCenterY();
#218
#219
//FUGLY HACK FOR "DEPRESSED" BUTTONS
#220
if (pressed)
#221
{
#222
center_y--;
#223
center_x++;
#224
}
#225
#226
// fade out overlay images on disabled buttons
#227
LLColor4 overlay_color = mImageOverlayColor;
#228
if (!getEnabled())
#229
{
#230
overlay_color.mV[VALPHA] = 0.5f;
#231
}
#232
#233
switch(mImageOverlayAlignment)
#234
{
#235
case LLFontGL::LEFT:
#236
text_left += overlay_width + 1;
#237
text_width -= overlay_width + 1;
#238
mImageOverlay->draw(
#239
mLeftHPad,
#240
center_y - (overlay_height / 2),
#241
overlay_width,
#242
overlay_height,
#243
overlay_color);
#244
break;
#245
case LLFontGL::HCENTER:
#246
mImageOverlay->draw(
#247
center_x - (overlay_width / 2),
#248
center_y - (overlay_height / 2),
#249
overlay_width,
#250
overlay_height,
#251
overlay_color);
#252
break;
#253
case LLFontGL::RIGHT:
#254
text_right -= overlay_width + 1;
#255
text_width -= overlay_width + 1;
#256
mImageOverlay->draw(
#257
getRect().getWidth() - mRightHPad - overlay_width,
#258
center_y - (overlay_height / 2),
#259
overlay_width,
#260
overlay_height,
#261
overlay_color);
#262
break;
#263
default:
#264
// draw nothing
#265
break;
#266
}
#267
}
#268
显示按钮的字符串。
#269
// Draw label
#270
if( !label.empty() )
#271
{
#272
LLWString::trim(label);
#273
#274
S32 x;
#275
switch( mHAlign )
#276
{
#277
case LLFontGL::RIGHT:
#278
x = text_right;
#279
break;
#280
case LLFontGL::HCENTER:
#281
x = getRect().getWidth() / 2;
#282
break;
#283
case LLFontGL::LEFT:
#284
default:
#285
x = text_left;
#286
break;
#287
}
#288
#289
S32 y_offset = 2 + (getRect().getHeight() - 20)/2;
#290
#291
if (pressed)
#292
{
#293
y_offset--;
#294
x++;
#295
}
#296
主要调用
OPENGL里的字体处理类来显示字符串。
#297
mGLFont->render(label, 0, (F32)x, (F32)(LLBUTTON_V_PAD + y_offset),
#298
label_color,
#299
mHAlign, LLFontGL::BOTTOM,
#300
mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NORMAL,
#301
U32_MAX, text_width,
#302
NULL, FALSE, FALSE);
#303
}
#304
#305
if (sDebugRects
#306
|| (LLView::sEditingUI && this == LLView::sEditingUIView))
#307
{
#308
drawDebugRect();
#309
}
#310
}
#311
// reset hover status for next frame
#312
mNeedsHighlight = FALSE;
#313 }
#314
在这个函数里,先要选择按钮背景的图片,然后根据是否选中显示不同的图片,不同的颜色,最后调用
OPENGL处理的字体类来显示字符串,实现按钮的名称显示。