llbutton.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llbutton.h"
00035 
00036 // Linden library includes
00037 #include "v4color.h"
00038 #include "llstring.h"
00039 
00040 // Project includes
00041 #include "llkeyboard.h"
00042 #include "llgl.h"
00043 #include "llui.h"
00044 #include "lluiconstants.h"
00045 //#include "llcallbacklist.h"
00046 #include "llresmgr.h"
00047 #include "llcriticaldamp.h"
00048 #include "llglheaders.h"
00049 #include "llfocusmgr.h"
00050 #include "llwindow.h"
00051 
00052 // globals loaded from settings.xml
00053 S32     LLBUTTON_ORIG_H_PAD     = 6; // Pre-zoomable UI
00054 S32     LLBUTTON_H_PAD  = 0;
00055 S32     LLBUTTON_V_PAD  = 0;
00056 S32 BTN_HEIGHT_SMALL= 0;
00057 S32 BTN_HEIGHT          = 0;
00058 
00059 S32 BTN_GRID            = 12;
00060 S32 BORDER_SIZE = 1;
00061 
00062 // static
00063 LLFrameTimer    LLButton::sFlashingTimer;
00064 
00065 LLButton::LLButton(     const LLString& name, const LLRect& rect, const LLString& control_name, void (*click_callback)(void*), void *callback_data)
00066 :       LLUICtrl(name, rect, TRUE, NULL, NULL),
00067         mClickedCallback( click_callback ),
00068         mMouseDownCallback( NULL ),
00069         mMouseUpCallback( NULL ),
00070         mHeldDownCallback( NULL ),
00071         mGLFont( NULL ),
00072         mMouseDownFrame( 0 ),
00073         mHeldDownDelay( 0.5f ),                 // seconds until held-down callback is called
00074         mHeldDownFrameDelay( 0 ),
00075         mImageUnselected( NULL ),
00076         mImageSelected( NULL ),
00077         mImageHoverSelected( NULL ),
00078         mImageHoverUnselected( NULL ),
00079         mImageDisabled( NULL ),
00080         mImageDisabledSelected( NULL ),
00081         mToggleState( FALSE ),
00082         mScaleImage( TRUE ),
00083         mDropShadowedText( TRUE ),
00084         mBorderEnabled( FALSE ),
00085         mFlashing( FALSE ),
00086         mHAlign( LLFontGL::HCENTER ),
00087         mLeftHPad( LLBUTTON_H_PAD ),
00088         mRightHPad( LLBUTTON_H_PAD ),
00089         mFixedWidth( 16 ),
00090         mFixedHeight( 16 ),
00091         mHoverGlowStrength(0.15f),
00092         mCurGlowStrength(0.f),
00093         mNeedsHighlight(FALSE),
00094         mCommitOnReturn(TRUE),
00095         mImagep( NULL )
00096 {
00097         mUnselectedLabel = name;
00098         mSelectedLabel = name;
00099 
00100         setImageUnselected("button_enabled_32x128.tga");
00101         setImageSelected("button_enabled_selected_32x128.tga");
00102         setImageDisabled("button_disabled_32x128.tga");
00103         setImageDisabledSelected("button_disabled_32x128.tga");
00104 
00105         mImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" );
00106         mDisabledImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" );
00107 
00108         init(click_callback, callback_data, NULL, control_name);
00109 }
00110 
00111 
00112 LLButton::LLButton(const LLString& name, const LLRect& rect, 
00113                                    const LLString &unselected_image_name, 
00114                                    const LLString &selected_image_name, 
00115                                    const LLString& control_name,
00116                                    void (*click_callback)(void*),
00117                                    void *callback_data,
00118                                    const LLFontGL *font,
00119                                    const LLString& unselected_label, 
00120                                    const LLString& selected_label )
00121 :       LLUICtrl(name, rect, TRUE, NULL, NULL),
00122         mClickedCallback( click_callback ),
00123         mMouseDownCallback( NULL ),
00124         mMouseUpCallback( NULL ),
00125         mHeldDownCallback( NULL ),
00126         mGLFont( NULL ),
00127         mMouseDownFrame( 0 ),
00128         mHeldDownDelay( 0.5f ),                 // seconds until held-down callback is called
00129         mHeldDownFrameDelay( 0 ),
00130         mImageUnselected( NULL ),
00131         mImageSelected( NULL ),
00132         mImageHoverSelected( NULL ),
00133         mImageHoverUnselected( NULL ),
00134         mImageDisabled( NULL ),
00135         mImageDisabledSelected( NULL ),
00136         mToggleState( FALSE ),
00137         mScaleImage( TRUE ),
00138         mDropShadowedText( TRUE ),
00139         mBorderEnabled( FALSE ),
00140         mFlashing( FALSE ),
00141         mHAlign( LLFontGL::HCENTER ),
00142         mLeftHPad( LLBUTTON_H_PAD ), 
00143         mRightHPad( LLBUTTON_H_PAD ),
00144         mFixedWidth( 16 ),
00145         mFixedHeight( 16 ),
00146         mHoverGlowStrength(0.25f),
00147         mCurGlowStrength(0.f),
00148         mNeedsHighlight(FALSE),
00149         mCommitOnReturn(TRUE),
00150         mImagep( NULL )
00151 {
00152         mUnselectedLabel = unselected_label;
00153         mSelectedLabel = selected_label;
00154 
00155         // by default, disabled color is same as enabled
00156         mImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" );
00157         mDisabledImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" );
00158 
00159         if( unselected_image_name != "" )
00160         {
00161                 setImageUnselected(unselected_image_name);
00162                 setImageDisabled(unselected_image_name);
00163                 
00164                 mDisabledImageColor.mV[VALPHA] = 0.5f;
00165                 mImageDisabled = mImageUnselected;
00166                 mDisabledImageColor.mV[VALPHA] = 0.5f;
00167                 // user-specified image - don't use fixed borders unless requested
00168                 mFixedWidth = 0;
00169                 mFixedHeight = 0;
00170                 mScaleImage = FALSE;
00171         }
00172         else
00173         {
00174                 setImageUnselected("button_enabled_32x128.tga");
00175                 setImageDisabled("button_disabled_32x128.tga");
00176         }
00177 
00178         if( selected_image_name != "" )
00179         {
00180                 setImageSelected(selected_image_name);
00181                 setImageDisabledSelected(selected_image_name);
00182 
00183                 mDisabledImageColor.mV[VALPHA] = 0.5f;
00184                 // user-specified image - don't use fixed borders unless requested
00185                 mFixedWidth = 0;
00186                 mFixedHeight = 0;
00187                 mScaleImage = FALSE;
00188         }
00189         else
00190         {
00191                 setImageSelected("button_enabled_selected_32x128.tga");
00192                 setImageDisabledSelected("button_disabled_32x128.tga");
00193         }
00194 
00195         init(click_callback, callback_data, font, control_name);
00196 }
00197 
00198 void LLButton::init(void (*click_callback)(void*), void *callback_data, const LLFontGL* font, const LLString& control_name)
00199 {
00200         mGLFont = ( font ? font : LLFontGL::sSansSerif);
00201 
00202         // Hack to make sure there is space for at least one character
00203         if (mRect.getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(" "))
00204         {
00205                 // Use old defaults
00206                 mLeftHPad = LLBUTTON_ORIG_H_PAD;
00207                 mRightHPad = LLBUTTON_ORIG_H_PAD;
00208         }
00209         
00210         mCallbackUserData = callback_data;
00211         mMouseDownTimer.stop();
00212 
00213         setControlName(control_name, NULL);
00214 
00215         mUnselectedLabelColor = (                       LLUI::sColorsGroup->getColor( "ButtonLabelColor" ) );
00216         mSelectedLabelColor = (                 LLUI::sColorsGroup->getColor( "ButtonLabelSelectedColor" ) );
00217         mDisabledLabelColor = (                 LLUI::sColorsGroup->getColor( "ButtonLabelDisabledColor" ) );
00218         mDisabledSelectedLabelColor = ( LLUI::sColorsGroup->getColor( "ButtonLabelSelectedDisabledColor" ) );
00219         mHighlightColor = (                             LLUI::sColorsGroup->getColor( "ButtonUnselectedFgColor" ) );
00220         mUnselectedBgColor = (                          LLUI::sColorsGroup->getColor( "ButtonUnselectedBgColor" ) );
00221         mSelectedBgColor = (                            LLUI::sColorsGroup->getColor( "ButtonSelectedBgColor" ) );
00222 
00223         mImageOverlayAlignment = LLFontGL::HCENTER;
00224         mImageOverlayColor = LLColor4::white;
00225 }
00226 
00227 LLButton::~LLButton()
00228 {
00229         if( hasMouseCapture() )
00230         {
00231                 gFocusMgr.setMouseCapture( NULL );
00232         }
00233 }
00234 
00235 // virtual
00236 EWidgetType LLButton::getWidgetType() const
00237 {
00238         return WIDGET_TYPE_BUTTON;
00239 }
00240 
00241 // virtual
00242 LLString LLButton::getWidgetTag() const
00243 {
00244         return LL_BUTTON_TAG;
00245 }
00246 
00247 // HACK: Committing a button is the same as instantly clicking it.
00248 // virtual
00249 void LLButton::onCommit()
00250 {
00251         // WARNING: Sometimes clicking a button destroys the floater or
00252         // panel containing it.  Therefore we need to call mClickedCallback
00253         // LAST, otherwise this becomes deleted memory.
00254         LLUICtrl::onCommit();
00255 
00256         if (mMouseDownCallback)
00257         {
00258                 (*mMouseDownCallback)(mCallbackUserData);
00259         }
00260         
00261         if (mMouseUpCallback)
00262         {
00263                 (*mMouseUpCallback)(mCallbackUserData);
00264         }
00265 
00266         if (mSoundFlags & MOUSE_DOWN)
00267         {
00268                 make_ui_sound("UISndClick");
00269         }
00270 
00271         if (mSoundFlags & MOUSE_UP)
00272         {
00273                 make_ui_sound("UISndClickRelease");
00274         }
00275 
00276         if (mClickedCallback)
00277         {
00278                 (*mClickedCallback)( mCallbackUserData );
00279         }
00280 }
00281 
00282 
00283 
00284 BOOL LLButton::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent)
00285 {
00286         BOOL handled = FALSE;
00287         if( getVisible() && mEnabled && !called_from_parent && ' ' == uni_char && !gKeyboard->getKeyRepeated(' '))
00288         {
00289                 if (mClickedCallback)
00290                 {
00291                         (*mClickedCallback)( mCallbackUserData );
00292                 }
00293                 handled = TRUE;         
00294         }
00295         return handled; 
00296 }
00297 
00298 BOOL LLButton::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent )
00299 {
00300         BOOL handled = FALSE;
00301         if( getVisible() && mEnabled && !called_from_parent )
00302         {
00303                 if( mCommitOnReturn && KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key))
00304                 {
00305                         if (mClickedCallback)
00306                         {
00307                                 (*mClickedCallback)( mCallbackUserData );
00308                         }
00309                         handled = TRUE;
00310                 }
00311         }
00312         return handled;
00313 }
00314 
00315 
00316 BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)
00317 {
00318         // Route future Mouse messages here preemptively.  (Release on mouse up.)
00319         gFocusMgr.setMouseCapture( this );
00320 
00321         if (hasTabStop() && !getIsChrome())
00322         {
00323                 setFocus(TRUE);
00324         }
00325 
00326         if (mMouseDownCallback)
00327         {
00328                 (*mMouseDownCallback)(mCallbackUserData);
00329         }
00330 
00331         mMouseDownTimer.start();
00332         mMouseDownFrame = LLFrameTimer::getFrameCount();
00333         
00334         if (mSoundFlags & MOUSE_DOWN)
00335         {
00336                 make_ui_sound("UISndClick");
00337         }
00338 
00339         return TRUE;
00340 }
00341 
00342 
00343 BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
00344 {
00345         // We only handle the click if the click both started and ended within us
00346         if( hasMouseCapture() )
00347         {
00348                 // Always release the mouse
00349                 gFocusMgr.setMouseCapture( NULL );
00350 
00351                 // Regardless of where mouseup occurs, handle callback
00352                 if (mMouseUpCallback)
00353                 {
00354                         (*mMouseUpCallback)(mCallbackUserData);
00355                 }
00356 
00357                 // DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked.
00358                 // If mouseup in the widget, it's been clicked
00359                 if (pointInView(x, y))
00360                 {
00361                         if (mSoundFlags & MOUSE_UP)
00362                         {
00363                                 make_ui_sound("UISndClickRelease");
00364                         }
00365 
00366                         if (mClickedCallback)
00367                         {
00368                                 (*mClickedCallback)( mCallbackUserData );
00369                         }                       
00370                 }
00371 
00372                 mMouseDownTimer.stop();
00373                 mMouseDownTimer.reset();
00374         }
00375 
00376         return TRUE;
00377 }
00378 
00379 
00380 BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
00381 {
00382         BOOL    handled = FALSE;
00383 
00384         LLMouseHandler* other_captor = gFocusMgr.getMouseCapture();
00385         mNeedsHighlight = other_captor == NULL || 
00386                                 other_captor == this ||
00387                                 // this following bit is to support modal dialogs
00388                                 (other_captor->isView() && hasAncestor((LLView*)other_captor));
00389 
00390         if (mMouseDownTimer.getStarted() && NULL != mHeldDownCallback)
00391         {
00392                 F32 elapsed = mMouseDownTimer.getElapsedTimeF32();
00393                 if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= LLFrameTimer::getFrameCount() - mMouseDownFrame)
00394                 {
00395                         mHeldDownCallback( mCallbackUserData );         
00396                 }
00397         }
00398 
00399         // We only handle the click if the click both started and ended within us
00400         if( hasMouseCapture() )
00401         {
00402                 handled = TRUE;
00403         }
00404         else if( getVisible() )
00405         {
00406                 // Opaque
00407                 handled = TRUE;
00408         }
00409 
00410         if( handled )
00411         {
00412                 getWindow()->setCursor(UI_CURSOR_ARROW);
00413                 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;              
00414         }
00415 
00416         return handled;
00417 }
00418 
00419 
00420 // virtual
00421 void LLButton::draw()
00422 {
00423         if( getVisible() ) 
00424         {
00425                 BOOL flash = FALSE;
00426                 if( mFlashing )
00427                 {
00428                         F32 elapsed = LLButton::sFlashingTimer.getElapsedTimeF32();
00429                         flash = S32(elapsed * 2) & 1;
00430                 }
00431 
00432                 BOOL pressed_by_keyboard = FALSE;
00433                 if (hasFocus())
00434                 {
00435                         pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mCommitOnReturn && gKeyboard->getKeyDown(KEY_RETURN));
00436                 }
00437 
00438                 // Unselected image assignments
00439                 S32 local_mouse_x;
00440                 S32 local_mouse_y;
00441                 LLCoordWindow cursor_pos_window;
00442                 getWindow()->getCursorPosition(&cursor_pos_window);
00443                 LLCoordGL cursor_pos_gl;
00444                 getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl);
00445                 cursor_pos_gl.mX = llround((F32)cursor_pos_gl.mX / LLUI::sGLScaleFactor.mV[VX]);
00446                 cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]);
00447                 screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y);
00448 
00449                 BOOL pressed = pressed_by_keyboard || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y));
00450 
00451                 BOOL display_state = FALSE;
00452                 if( pressed )
00453                 {
00454                         mImagep = mImageSelected;
00455                         // show the resulting state after releasing the mouse button while it is down
00456                         display_state = mToggleState ? FALSE : TRUE;
00457                 }
00458                 else
00459                 {
00460                         display_state = mToggleState || flash;
00461                 }
00462                 
00463                 BOOL use_glow_effect = FALSE;
00464                 if ( mNeedsHighlight )
00465                 {
00466                         if (display_state)
00467                         {
00468                                 if (mImageHoverSelected)
00469                                 {
00470                                         mImagep = mImageHoverSelected;
00471                                 }
00472                                 else
00473                                 {
00474                                         mImagep = mImageSelected;
00475                                         use_glow_effect = TRUE;
00476                                 }
00477                         }
00478                         else
00479                         {
00480                                 if (mImageHoverUnselected)
00481                                 {
00482                                         mImagep = mImageHoverUnselected;
00483                                 }
00484                                 else
00485                                 {
00486                                         mImagep = mImageUnselected;
00487                                         use_glow_effect = TRUE;
00488                                 }
00489                         }
00490                 }
00491                 else if ( display_state )
00492                 {
00493                         mImagep = mImageSelected;
00494                 }
00495                 else
00496                 {
00497                         mImagep = mImageUnselected;
00498                 }
00499 
00500                 // Override if more data is available
00501                 // HACK: Use gray checked state to mean either:
00502                 //   enabled and tentative
00503                 // or
00504                 //   disabled but checked
00505                 if (!mImageDisabledSelected.isNull() && ( (mEnabled && mTentative) || (!mEnabled && display_state ) ) )
00506                 {
00507                         mImagep = mImageDisabledSelected;
00508                 }
00509                 else if (!mImageDisabled.isNull() && !mEnabled && !display_state)
00510                 {
00511                         mImagep = mImageDisabled;
00512                 }
00513 
00514                 if (mNeedsHighlight && !mImagep)
00515                 {
00516                         use_glow_effect = TRUE;
00517                 }
00518 
00519                 // Figure out appropriate color for the text
00520                 LLColor4 label_color;
00521 
00522                 if ( mEnabled )
00523                 {
00524                         if ( !display_state )
00525                         {
00526                                 label_color = mUnselectedLabelColor;
00527                         }
00528                         else
00529                         {
00530                                 label_color = mSelectedLabelColor;
00531                         }
00532                 }
00533                 else
00534                 {
00535                         if ( !display_state )
00536                         {
00537                                 label_color = mDisabledLabelColor;
00538                         }
00539                         else
00540                         {
00541                                 label_color = mDisabledSelectedLabelColor;
00542                         }
00543                 }
00544 
00545                 // Unselected label assignments
00546                 LLWString label;
00547 
00548                 if( display_state )
00549                 {
00550                         if( mEnabled || mDisabledSelectedLabel.empty() )
00551                         {
00552                                 label = mSelectedLabel;
00553                         }
00554                         else
00555                         {
00556                                 label = mDisabledSelectedLabel;
00557                         }
00558                 }
00559                 else
00560                 {
00561                         if( mEnabled || mDisabledLabel.empty() )
00562                         {
00563                                 label = mUnselectedLabel;
00564                         }
00565                         else
00566                         {
00567                                 label = mDisabledLabel;
00568                         }
00569                 }
00570                 
00571                 // draw default button border
00572                 if (mEnabled && mBorderEnabled && gFocusMgr.getAppHasFocus()) // because we're the default button in a panel
00573                 {
00574                         drawBorder(LLUI::sColorsGroup->getColor( "ButtonBorderColor" ), BORDER_SIZE);
00575                 }
00576 
00577                 // overlay with keyboard focus border
00578                 if (hasFocus())
00579                 {
00580                         F32 lerp_amt = gFocusMgr.getFocusFlashAmt();
00581                         drawBorder(gFocusMgr.getFocusColor(), llround(lerp(1.f, 3.f, lerp_amt)));
00582                 }
00583                 
00584                 if (use_glow_effect)
00585                 {
00586                         mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f));
00587                 }
00588                 else
00589                 {
00590                         mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f));
00591                 }
00592 
00593                 // Draw button image, if available.
00594                 // Otherwise draw basic rectangular button.
00595                 if( mImagep.notNull() && !mScaleImage)
00596                 {
00597                         gl_draw_image( 0, 0, mImagep, mEnabled ? mImageColor : mDisabledImageColor );
00598                         if (mCurGlowStrength > 0.01f)
00599                         {
00600                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00601                                 gl_draw_scaled_image_with_border(0, 0, 0, 0, mImagep->getWidth(), mImagep->getHeight(), mImagep, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength), TRUE);
00602                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00603                         }
00604                 }
00605                 else
00606                 if ( mImagep.notNull() && mScaleImage)
00607                 {
00608                         gl_draw_scaled_image_with_border(0, 0, mFixedWidth, mFixedHeight, mRect.getWidth(), mRect.getHeight(), 
00609                                                                                         mImagep, mEnabled ? mImageColor : mDisabledImageColor  );
00610                         if (mCurGlowStrength > 0.01f)
00611                         {
00612                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00613                                 gl_draw_scaled_image_with_border(0, 0, mFixedWidth, mFixedHeight, mRect.getWidth(), mRect.getHeight(), 
00614                                                                                         mImagep, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength), TRUE);
00615                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00616                         }
00617                 }
00618                 else
00619                 {
00620                         // no image
00621                         llwarns << "No image for button " << mName << llendl;
00622                         // draw it in pink so we can find it
00623                         gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4::pink1, FALSE);
00624                 }
00625 
00626                 // draw overlay image
00627                 if (mImageOverlay.notNull())
00628                 {
00629                         const S32 IMG_PAD = 5;
00630                         // get max width and height (discard level 0)
00631                         S32 overlay_width = mImageOverlay->getWidth(0);
00632                         S32 overlay_height = mImageOverlay->getHeight(0);
00633 
00634                         F32 scale_factor = llmin((F32)mRect.getWidth() / (F32)overlay_width, (F32)mRect.getHeight() / (F32)overlay_height, 1.f);
00635                         overlay_width = llround((F32)overlay_width * scale_factor);
00636                         overlay_height = llround((F32)overlay_height * scale_factor);
00637 
00638                         S32 center_x = getLocalRect().getCenterX();
00639                         S32 center_y = getLocalRect().getCenterY();
00640 
00641                         switch(mImageOverlayAlignment)
00642                         {
00643                         case LLFontGL::LEFT:
00644                                 gl_draw_scaled_image(
00645                                         IMG_PAD, 
00646                                         center_y - (overlay_height / 2), 
00647                                         overlay_width, 
00648                                         overlay_height, 
00649                                         mImageOverlay,
00650                                         mImageOverlayColor);
00651                                 break;
00652                         case LLFontGL::HCENTER:
00653                                 gl_draw_scaled_image(
00654                                         center_x - (overlay_width / 2), 
00655                                         center_y - (overlay_height / 2), 
00656                                         overlay_width, 
00657                                         overlay_height, 
00658                                         mImageOverlay,
00659                                         mImageOverlayColor);
00660                                 break;
00661                         case LLFontGL::RIGHT:
00662                                 gl_draw_scaled_image(
00663                                         mRect.getWidth() - IMG_PAD - overlay_width, 
00664                                         center_y - (overlay_height / 2), 
00665                                         overlay_width, 
00666                                         overlay_height, 
00667                                         mImageOverlay,
00668                                         mImageOverlayColor);
00669                                 break;
00670                         default:
00671                                 // draw nothing
00672                                 break;
00673                         }
00674                 }
00675 
00676                 // Draw label
00677                 if( !label.empty() )
00678                 {
00679                         S32 drawable_width = mRect.getWidth() - mLeftHPad - mRightHPad;
00680 
00681                         LLWString::trim(label);
00682 
00683                         S32 x;
00684                         switch( mHAlign )
00685                         {
00686                         case LLFontGL::RIGHT:
00687                                 x = mRect.getWidth() - mRightHPad;
00688                                 break;
00689                         case LLFontGL::HCENTER:
00690                                 x = mRect.getWidth() / 2;
00691                                 break;
00692                         case LLFontGL::LEFT:
00693                         default:
00694                                 x = mLeftHPad;
00695                                 break;
00696                         }
00697 
00698                         S32 y_offset = 2 + (mRect.getHeight() - 20)/2;
00699                 
00700                         if (pressed || display_state)
00701                         {
00702                                 y_offset--;
00703                                 x++;
00704                         }
00705 
00706                         mGLFont->render(label, 0, (F32)x, (F32)(LLBUTTON_V_PAD + y_offset), 
00707                                 label_color,
00708                                 mHAlign, LLFontGL::BOTTOM,
00709                                 mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NORMAL,
00710                                 U32_MAX, drawable_width,
00711                                 NULL, FALSE, FALSE);
00712                 }
00713 
00714                 if (sDebugRects 
00715                         || (LLView::sEditingUI && this == LLView::sEditingUIView))
00716                 {
00717                         drawDebugRect();
00718                 }
00719         }
00720         // reset hover status for next frame
00721         mNeedsHighlight = FALSE;
00722 }
00723 
00724 void LLButton::drawBorder(const LLColor4& color, S32 size)
00725 {
00726         S32 left = -size;
00727         S32 top = mRect.getHeight() + size;
00728         S32 right = mRect.getWidth() + size;
00729         S32 bottom = -size;
00730 
00731         if (mImagep.isNull())
00732         {
00733                 gl_rect_2d(left, top, right, bottom, color, FALSE);
00734                 return;
00735         }
00736 
00737         if (mScaleImage)
00738         {
00739                 gl_draw_scaled_image_with_border(left, bottom, mFixedWidth, mFixedHeight, right-left, top-bottom, 
00740                                                                 mImagep, color, TRUE );
00741         }
00742         else
00743         {
00744                 gl_draw_scaled_image_with_border(left, bottom, 0, 0, mImagep->getWidth() + size * 2, 
00745                                                                 mImagep->getHeight() + size * 2, mImagep, color, TRUE );
00746         }
00747 }
00748 
00749 void LLButton::setClickedCallback(void (*cb)(void*), void* userdata)
00750 {
00751         mClickedCallback = cb;
00752         if (userdata)
00753         {
00754                 mCallbackUserData = userdata;
00755         }
00756 }
00757 
00758 
00759 void LLButton::setToggleState(BOOL b)
00760 {
00761         if( b != mToggleState )
00762         {
00763                 mToggleState = b;
00764                 LLValueChangedEvent *evt = new LLValueChangedEvent(this, mToggleState);
00765                 fireEvent(evt, "");
00766         }
00767 }
00768 
00769 void LLButton::setValue(const LLSD& value )
00770 {
00771         mToggleState = value.asBoolean();
00772 }
00773 
00774 LLSD LLButton::getValue() const
00775 {
00776         return mToggleState;
00777 }
00778 
00779 void LLButton::setLabel( const LLStringExplicit& label )
00780 {
00781         setLabelUnselected(label);
00782         setLabelSelected(label);
00783 }
00784 
00785 //virtual
00786 BOOL LLButton::setLabelArg( const LLString& key, const LLStringExplicit& text )
00787 {
00788         mUnselectedLabel.setArg(key, text);
00789         mSelectedLabel.setArg(key, text);
00790         return TRUE;
00791 }
00792 
00793 void LLButton::setLabelUnselected( const LLStringExplicit& label )
00794 {
00795         mUnselectedLabel = label;
00796 }
00797 
00798 void LLButton::setLabelSelected( const LLStringExplicit& label )
00799 {
00800         mSelectedLabel = label;
00801 }
00802 
00803 void LLButton::setDisabledLabel( const LLStringExplicit& label )
00804 {
00805         mDisabledLabel = label;
00806 }
00807 
00808 void LLButton::setDisabledSelectedLabel( const LLStringExplicit& label )
00809 {
00810         mDisabledSelectedLabel = label;
00811 }
00812 
00813 void LLButton::setImageUnselectedID( const LLUUID &image_id )
00814 {       
00815         mImageUnselectedName = "";
00816         mImageUnselected = LLUI::sImageProvider->getUIImageByID(image_id);
00817 }
00818 
00819 void LLButton::setImages( const LLString &image_name, const LLString &selected_name )
00820 {
00821         setImageUnselected(image_name);
00822         setImageSelected(selected_name);
00823 
00824 }
00825 
00826 void LLButton::setImageSelectedID( const LLUUID &image_id )
00827 {
00828         mImageSelectedName = "";
00829         mImageSelected = LLUI::sImageProvider->getUIImageByID(image_id);
00830 }
00831 
00832 void LLButton::setImageColor(const LLColor4& c)         
00833 { 
00834         mImageColor = c; 
00835 }
00836 
00837 
00838 void LLButton::setImageDisabledID( const LLUUID &image_id )
00839 {
00840         mImageDisabledName = "";
00841         mImageDisabled = LLUI::sImageProvider->getUIImageByID(image_id);
00842         mDisabledImageColor = mImageColor;
00843         mDisabledImageColor.mV[VALPHA] *= 0.5f;
00844 }
00845 
00846 void LLButton::setImageDisabledSelectedID( const LLUUID &image_id )
00847 {       
00848         mImageDisabledSelectedName = "";
00849         mImageDisabledSelected = LLUI::sImageProvider->getUIImageByID(image_id);
00850         mDisabledImageColor = mImageColor;
00851         mDisabledImageColor.mV[VALPHA] *= 0.5f;
00852 }
00853 
00854 void LLButton::setDisabledImages( const LLString &image_name, const LLString &selected_name, const LLColor4& c )
00855 {
00856         setImageDisabled(image_name);
00857         setImageDisabledSelected(selected_name);
00858         mDisabledImageColor = c;
00859 }
00860 
00861 
00862 void LLButton::setImageHoverSelectedID( const LLUUID& image_id )
00863 {
00864         mImageHoverSelectedName = "";
00865         mImageHoverSelected = LLUI::sImageProvider->getUIImageByID(image_id);
00866 }
00867 
00868 void LLButton::setDisabledImages( const LLString &image_name, const LLString &selected_name)
00869 {
00870         LLColor4 clr = mImageColor;
00871         clr.mV[VALPHA] *= .5f;
00872         setDisabledImages( image_name, selected_name, clr );
00873 }
00874 
00875 void LLButton::setImageHoverUnselectedID( const LLUUID& image_id )
00876 {
00877         mImageHoverUnselectedName = "";
00878         mImageHoverUnselected = LLUI::sImageProvider->getUIImageByID(image_id);
00879 }
00880 
00881 void LLButton::setHoverImages( const LLString& image_name, const LLString& selected_name )
00882 {
00883         setImageHoverUnselected(image_name);
00884         setImageHoverSelected(selected_name);
00885 }
00886 
00887 void LLButton::setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment, const LLColor4& color)
00888 {
00889         if (image_name.empty())
00890         {
00891                 mImageOverlay = NULL;
00892         }
00893         else
00894         {
00895                 LLUUID overlay_image_id = LLUI::findAssetUUIDByName(image_name);
00896                 mImageOverlay = LLUI::sImageProvider->getUIImageByID(overlay_image_id);
00897                 mImageOverlayAlignment = alignment;
00898                 mImageOverlayColor = color;
00899         }
00900 }
00901 
00902 
00903 void LLButton::onMouseCaptureLost()
00904 {
00905         mMouseDownTimer.stop();
00906         mMouseDownTimer.reset();
00907 }
00908 
00909 //-------------------------------------------------------------------------
00910 // LLSquareButton
00911 //-------------------------------------------------------------------------
00912 LLSquareButton::LLSquareButton(const LLString& name, const LLRect& rect, 
00913                 const LLString& label,
00914                 const LLFontGL *font,
00915                 const LLString& control_name,   
00916                 void (*click_callback)(void*),
00917                 void *callback_data,
00918                 const LLString& selected_label )
00919 :       LLButton(name, rect, "","", 
00920                         control_name, 
00921                         click_callback, callback_data,
00922                         font,
00923                         label, 
00924                         (selected_label.empty() ? label : selected_label) )
00925 { 
00926         setImageUnselected("square_btn_32x128.tga");
00927         //      mImageUnselected = LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("square_btn_32x128.tga")));
00928         setImageSelected("square_btn_selected_32x128.tga");
00929         //      mImageSelectedImage = LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("square_btn_selected_32x128.tga")));
00930         setImageDisabled("square_btn_32x128.tga");
00931         //mDisabledImage = LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("square_btn_32x128.tga")));
00932         setImageDisabledSelected("square_btn_selected_32x128.tga");
00933         //mDisabledSelectedImage = LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("square_btn_selected_32x128.tga")));
00934         mImageColor = LLUI::sColorsGroup->getColor("ButtonColor");
00935 }
00936 
00937 //-------------------------------------------------------------------------
00938 // Utilities
00939 //-------------------------------------------------------------------------
00940 S32 round_up(S32 grid, S32 value)
00941 {
00942         S32 mod = value % grid;
00943 
00944         if (mod > 0)
00945         {
00946                 // not even multiple
00947                 return value + (grid - mod);
00948         }
00949         else
00950         {
00951                 return value;
00952         }
00953 }
00954 
00955 void                    LLButton::setImageUnselected(const LLString &image_name)
00956 {       
00957         setImageUnselectedID(LLUI::findAssetUUIDByName(image_name));
00958         mImageUnselectedName = image_name;
00959 }
00960 
00961 void                    LLButton::setImageSelected(const LLString &image_name)
00962 {       
00963         setImageSelectedID(LLUI::findAssetUUIDByName(image_name));
00964         mImageSelectedName = image_name;
00965 }
00966 
00967 void                    LLButton::setImageHoverSelected(const LLString &image_name)
00968 {
00969         setImageHoverSelectedID(LLUI::findAssetUUIDByName(image_name));
00970         mImageHoverSelectedName = image_name;
00971 }
00972 
00973 void                    LLButton::setImageHoverUnselected(const LLString &image_name)
00974 {
00975         setImageHoverUnselectedID(LLUI::findAssetUUIDByName(image_name));
00976         mImageHoverUnselectedName = image_name;
00977 }
00978 
00979 void                    LLButton::setImageDisabled(const LLString &image_name)
00980 {
00981         setImageDisabledID(LLUI::findAssetUUIDByName(image_name));
00982         mImageDisabledName = image_name;
00983 }
00984 
00985 void                    LLButton::setImageDisabledSelected(const LLString &image_name)
00986 {
00987         setImageDisabledSelectedID(LLUI::findAssetUUIDByName(image_name));
00988         mImageDisabledSelectedName = image_name;
00989 }
00990 
00991 void LLButton::addImageAttributeToXML(LLXMLNodePtr node, 
00992                                                                           const LLString& image_name,
00993                                                                           const LLUUID& image_id,
00994                                                                           const LLString& xml_tag_name) const
00995 {
00996         if( !image_name.empty() )
00997         {
00998                 node->createChild(xml_tag_name, TRUE)->setStringValue(image_name);
00999         }
01000         else if( image_id != LLUUID::null )
01001         {
01002                 node->createChild(xml_tag_name + "_id", TRUE)->setUUIDValue(image_id);
01003         }
01004 }
01005 
01006 // virtual
01007 LLXMLNodePtr LLButton::getXML(bool save_children) const
01008 {
01009         LLXMLNodePtr node = LLUICtrl::getXML();
01010 
01011         node->createChild("label", TRUE)->setStringValue(getLabelUnselected());
01012         node->createChild("label_selected", TRUE)->setStringValue(getLabelSelected());
01013         node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mGLFont));
01014         node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(mHAlign));
01015         node->createChild("border_width", TRUE)->setIntValue(mFixedWidth);
01016         node->createChild("border_height", TRUE)->setIntValue(mFixedHeight);
01017 
01018         addImageAttributeToXML(node,mImageUnselectedName,mImageUnselectedID,"image_unselected");
01019         addImageAttributeToXML(node,mImageSelectedName,mImageSelectedID,"image_selected");
01020         addImageAttributeToXML(node,mImageHoverSelectedName,mImageHoverSelectedID,"image_hover_selected");
01021         addImageAttributeToXML(node,mImageHoverUnselectedName,mImageHoverUnselectedID,"image_hover_unselected");
01022         addImageAttributeToXML(node,mImageDisabledName,mImageDisabledID,"image_disabled");
01023         addImageAttributeToXML(node,mImageDisabledSelectedName,mImageDisabledSelectedID,"image_disabled_selected");
01024 
01025         node->createChild("scale_image", TRUE)->setBoolValue(mScaleImage);
01026 
01027         return node;
01028 }
01029 
01030 void clicked_help(void* data)
01031 {
01032         LLButton* self = (LLButton*)data;
01033         if (!self) return;
01034         
01035         if (!LLUI::sHtmlHelp)
01036         {
01037                 return;
01038         }
01039         
01040         LLUI::sHtmlHelp->show(self->getHelpURL(), "");
01041 }
01042 
01043 // static
01044 LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
01045 {
01046         LLString name("button");
01047         node->getAttributeString("name", name);
01048 
01049         LLString label = name;
01050         node->getAttributeString("label", label);
01051 
01052         LLString label_selected = label;
01053         node->getAttributeString("label_selected", label_selected);
01054 
01055         LLFontGL* font = selectFont(node);
01056 
01057         LLString        image_unselected;
01058         if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected);
01059         
01060         LLString        image_selected;
01061         if (node->hasAttribute("image_selected")) node->getAttributeString("image_selected",image_selected);
01062         
01063         LLString        image_hover_selected;
01064         if (node->hasAttribute("image_hover_selected")) node->getAttributeString("image_hover_selected",image_hover_selected);
01065         
01066         LLString        image_hover_unselected;
01067         if (node->hasAttribute("image_hover_unselected")) node->getAttributeString("image_hover_unselected",image_hover_unselected);
01068         
01069         LLString        image_disabled_selected;
01070         if (node->hasAttribute("image_disabled_selected")) node->getAttributeString("image_disabled_selected",image_disabled_selected);
01071         
01072         LLString        image_disabled;
01073         if (node->hasAttribute("image_disabled")) node->getAttributeString("image_disabled",image_disabled);
01074 
01075         LLString        image_overlay;
01076         node->getAttributeString("image_overlay", image_overlay);
01077 
01078         LLFontGL::HAlign image_overlay_alignment = LLFontGL::HCENTER;
01079         LLString image_overlay_alignment_string;
01080         if (node->hasAttribute("image_overlay_alignment"))
01081         {
01082                 node->getAttributeString("image_overlay_alignment", image_overlay_alignment_string);
01083                 image_overlay_alignment = LLFontGL::hAlignFromName(image_overlay_alignment_string);
01084         }
01085 
01086 
01087         LLButton *button = new LLButton(name, 
01088                         LLRect(),
01089                         image_unselected,
01090                         image_selected,
01091                         "", 
01092                         NULL, 
01093                         parent,
01094                         font,
01095                         label,
01096                         label_selected);
01097 
01098         node->getAttributeS32("border_width", button->mFixedWidth);
01099         node->getAttributeS32("border_height", button->mFixedHeight);
01100 
01101         if(image_hover_selected != LLString::null) button->setImageHoverSelected(image_hover_selected);
01102         
01103         if(image_hover_unselected != LLString::null) button->setImageHoverUnselected(image_hover_unselected);
01104         
01105         if(image_disabled_selected != LLString::null) button->setImageDisabledSelected(image_disabled_selected );
01106         
01107         if(image_disabled != LLString::null) button->setImageDisabled(image_disabled);
01108         
01109         if(image_overlay != LLString::null) button->setImageOverlay(image_overlay, image_overlay_alignment);
01110 
01111         if (node->hasAttribute("halign"))
01112         {
01113                 LLFontGL::HAlign halign = selectFontHAlign(node);
01114                 button->setHAlign(halign);
01115         }
01116 
01117         if (node->hasAttribute("scale_image"))
01118         {
01119                 BOOL    needsScale = FALSE;
01120                 node->getAttributeBOOL("scale_image",needsScale);
01121                 button->setScaleImage( needsScale );
01122         }
01123 
01124         if(label.empty())
01125         {
01126                 button->setLabelUnselected(node->getTextContents());
01127         }
01128         if (label_selected.empty())
01129         {
01130                 button->setLabelSelected(node->getTextContents());
01131         }
01132                 
01133         if (node->hasAttribute("help_url")) 
01134         {
01135                 LLString        help_url;
01136                 node->getAttributeString("help_url",help_url);
01137                 button->setHelpURLCallback(help_url);
01138         }
01139 
01140         button->initFromXML(node, parent);
01141         
01142         return button;
01143 }
01144 
01145 void LLButton::setHelpURLCallback(std::string help_url)
01146 {
01147         mHelpURL = help_url;
01148         setClickedCallback(clicked_help,this);
01149 }

Generated on Thu Jul 1 06:08:20 2010 for Second Life Viewer by  doxygen 1.4.7