第二人生的源码分析(八十八)LLButton类显示按钮的名称

前面介绍按钮可以显示在窗口里,以及这个类的声明,现在来仔细地分析一下它是怎么样实现名称显示的。
在构造函数里先保存传送入来的名称,如下:
#001 mUnselectedLabel = unselected_label;
#002 mSelectedLabel = selected_label;
#003
从类声明里可以看到mSelectedLabel和mUnselectedLabel都是声明为类LLUIString的实例,由于类LLUIString只支持LLString构造函数的名称,因此它不能显示UNICODE的字符串。
显示按钮的函数如下:
#001void 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处理的字体类来显示字符串,实现按钮的名称显示。
阅读更多
上一篇第二人生的源码分析(八十七)LLButton类实现按钮功能
下一篇第二人生的源码分析(八十九)从XML里创建LLButton
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭