diff options
Diffstat (limited to 'indra/llui')
73 files changed, 4832 insertions, 5552 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index ce3a4b64c7..6c27ccc037 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -189,7 +189,7 @@ void LLButton::init(void (*click_callback)(void*), void *callback_data, const LL mGLFont = ( font ? font : LLFontGL::sSansSerif); // Hack to make sure there is space for at least one character - if (mRect.getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(" ")) + if (getRect().getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(" ")) { // Use old defaults mLeftHPad = LLBUTTON_ORIG_H_PAD; @@ -252,12 +252,12 @@ void LLButton::onCommit() (*mMouseUpCallback)(mCallbackUserData); } - if (mSoundFlags & MOUSE_DOWN) + if (getSoundFlags() & MOUSE_DOWN) { make_ui_sound("UISndClick"); } - if (mSoundFlags & MOUSE_UP) + if (getSoundFlags() & MOUSE_UP) { make_ui_sound("UISndClickRelease"); } @@ -279,7 +279,7 @@ void LLButton::onCommit() BOOL LLButton::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) { BOOL handled = FALSE; - if( getVisible() && mEnabled && !called_from_parent && ' ' == uni_char && !gKeyboard->getKeyRepeated(' ')) + if( getVisible() && getEnabled() && !called_from_parent && ' ' == uni_char && !gKeyboard->getKeyRepeated(' ')) { if (mIsToggle) { @@ -298,7 +298,7 @@ BOOL LLButton::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) BOOL LLButton::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) { BOOL handled = FALSE; - if( getVisible() && mEnabled && !called_from_parent ) + if( getVisible() && getEnabled() && !called_from_parent ) { if( mCommitOnReturn && KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key)) { @@ -337,7 +337,7 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) mMouseDownTimer.start(); mMouseDownFrame = LLFrameTimer::getFrameCount(); - if (mSoundFlags & MOUSE_DOWN) + if (getSoundFlags() & MOUSE_DOWN) { make_ui_sound("UISndClick"); } @@ -367,7 +367,7 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) // If mouseup in the widget, it's been clicked if (pointInView(x, y)) { - if (mSoundFlags & MOUSE_UP) + if (getSoundFlags() & MOUSE_UP) { make_ui_sound("UISndClickRelease"); } @@ -400,7 +400,7 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) if (mMouseDownTimer.getStarted() && NULL != mHeldDownCallback) { - F32 elapsed = mMouseDownTimer.getElapsedTimeF32(); + F32 elapsed = getHeldDownTime(); if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= LLFrameTimer::getFrameCount() - mMouseDownFrame) { mHeldDownCallback( mCallbackUserData ); @@ -505,11 +505,11 @@ void LLButton::draw() // enabled and tentative // or // disabled but checked - if (!mImageDisabledSelected.isNull() && ( (mEnabled && mTentative) || (!mEnabled && pressed ) ) ) + if (!mImageDisabledSelected.isNull() && ( (getEnabled() && getTentative()) || (!getEnabled() && pressed ) ) ) { mImagep = mImageDisabledSelected; } - else if (!mImageDisabled.isNull() && !mEnabled && !pressed) + else if (!mImageDisabled.isNull() && !getEnabled() && !pressed) { mImagep = mImageDisabled; } @@ -523,7 +523,7 @@ void LLButton::draw() LLColor4 label_color; // label changes when button state changes, not when pressed - if ( mEnabled ) + if ( getEnabled() ) { if ( mToggleState ) { @@ -551,7 +551,7 @@ void LLButton::draw() if( mToggleState ) { - if( mEnabled || mDisabledSelectedLabel.empty() ) + if( getEnabled() || mDisabledSelectedLabel.empty() ) { label = mSelectedLabel; } @@ -562,7 +562,7 @@ void LLButton::draw() } else { - if( mEnabled || mDisabledLabel.empty() ) + if( getEnabled() || mDisabledLabel.empty() ) { label = mUnselectedLabel; } @@ -573,7 +573,7 @@ void LLButton::draw() } // draw default button border - if (mEnabled && mBorderEnabled && gFocusMgr.getAppHasFocus()) // because we're the default button in a panel + if (getEnabled() && mBorderEnabled && gFocusMgr.getAppHasFocus()) // because we're the default button in a panel { drawBorder(LLUI::sColorsGroup->getColor( "ButtonBorderColor" ), BORDER_SIZE); } @@ -598,7 +598,7 @@ void LLButton::draw() // Otherwise draw basic rectangular button. if( mImagep.notNull() && !mScaleImage) { - mImagep->draw(0, 0, mEnabled ? mImageColor : mDisabledImageColor ); + mImagep->draw(0, 0, getEnabled() ? mImageColor : mDisabledImageColor ); if (mCurGlowStrength > 0.01f) { glBlendFunc(GL_SRC_ALPHA, GL_ONE); @@ -609,26 +609,26 @@ void LLButton::draw() else if ( mImagep.notNull() && mScaleImage) { - mImagep->draw(0, 0, mRect.getWidth(), mRect.getHeight(), mEnabled ? mImageColor : mDisabledImageColor ); + mImagep->draw(0, 0, getRect().getWidth(), getRect().getHeight(), getEnabled() ? mImageColor : mDisabledImageColor ); if (mCurGlowStrength > 0.01f) { glBlendFunc(GL_SRC_ALPHA, GL_ONE); - mImagep->drawSolid(0, 0, mRect.getWidth(), mRect.getHeight(), LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); + mImagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } } else { // no image - llwarns << "No image for button " << mName << llendl; + llwarns << "No image for button " << getName() << llendl; // draw it in pink so we can find it - gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4::pink1, FALSE); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4::pink1, FALSE); } // let overlay image and text play well together S32 text_left = mLeftHPad; - S32 text_right = mRect.getWidth() - mRightHPad; - S32 text_width = mRect.getWidth() - mLeftHPad - mRightHPad; + S32 text_right = getRect().getWidth() - mRightHPad; + S32 text_width = getRect().getWidth() - mLeftHPad - mRightHPad; // draw overlay image if (mImageOverlay.notNull()) @@ -637,7 +637,7 @@ void LLButton::draw() S32 overlay_width = mImageOverlay->getWidth(); S32 overlay_height = mImageOverlay->getHeight(); - F32 scale_factor = llmin((F32)mRect.getWidth() / (F32)overlay_width, (F32)mRect.getHeight() / (F32)overlay_height, 1.f); + F32 scale_factor = llmin((F32)getRect().getWidth() / (F32)overlay_width, (F32)getRect().getHeight() / (F32)overlay_height, 1.f); overlay_width = llround((F32)overlay_width * scale_factor); overlay_height = llround((F32)overlay_height * scale_factor); @@ -682,7 +682,7 @@ void LLButton::draw() text_right -= overlay_width + 1; text_width -= overlay_width + 1; mImageOverlay->draw( - mRect.getWidth() - mRightHPad - overlay_width, + getRect().getWidth() - mRightHPad - overlay_width, center_y - (overlay_height / 2), overlay_width, overlay_height, @@ -706,7 +706,7 @@ void LLButton::draw() x = text_right; break; case LLFontGL::HCENTER: - x = mRect.getWidth() / 2; + x = getRect().getWidth() / 2; break; case LLFontGL::LEFT: default: @@ -714,7 +714,7 @@ void LLButton::draw() break; } - S32 y_offset = 2 + (mRect.getHeight() - 20)/2; + S32 y_offset = 2 + (getRect().getHeight() - 20)/2; if (pressed) { @@ -743,8 +743,8 @@ void LLButton::draw() void LLButton::drawBorder(const LLColor4& color, S32 size) { S32 left = -size; - S32 top = mRect.getHeight() + size; - S32 right = mRect.getWidth() + size; + S32 top = getRect().getHeight() + size; + S32 right = getRect().getWidth() + size; S32 bottom = -size; if (mImagep.isNull()) @@ -1146,7 +1146,7 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa return button; } -void LLButton::setHelpURLCallback(std::string help_url) +void LLButton::setHelpURLCallback(const LLString &help_url) { mHelpURL = help_url; setClickedCallback(clicked_help,this); diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 0e140a45a6..a181fbbf56 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -52,10 +52,14 @@ extern S32 LLBUTTON_V_PAD; extern S32 BTN_HEIGHT_SMALL; extern S32 BTN_HEIGHT; - // All button widths should be rounded up to this size extern S32 BTN_GRID; +// +// Helpful functions +// +S32 round_up(S32 grid, S32 value); + class LLUICtrlFactory; @@ -124,6 +128,7 @@ public: BOOL getFlashing() const { return mFlashing; } void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } + LLFontGL::HAlign getHAlign() const { return mHAlign; } void setLeftHPad( S32 pad ) { mLeftHPad = pad; } void setRightHPad( S32 pad ) { mRightHPad = pad; } @@ -162,6 +167,7 @@ public: void setFont(const LLFontGL *font) { mGLFont = ( font ? font : LLFontGL::sSansSerif); } void setScaleImage(BOOL scale) { mScaleImage = scale; } + BOOL getScaleImage() const { return mScaleImage; } void setDropShadowedText(BOOL b) { mDropShadowedText = b; } @@ -171,9 +177,10 @@ public: void setHoverGlowStrength(F32 strength) { mHoverGlowStrength = strength; } -public: void setImageUnselected(const LLString &image_name); + const LLString& getImageUnselectedName() const { return mImageUnselectedName; } void setImageSelected(const LLString &image_name); + const LLString& getImageSelectedName() const { return mImageSelectedName; } void setImageHoverSelected(const LLString &image_name); void setImageHoverUnselected(const LLString &image_name); void setImageDisabled(const LLString &image_name); @@ -187,14 +194,29 @@ public: void setImageDisabledSelected(LLPointer<LLUIImage> image); void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; } - BOOL getCommitOnReturn() { return mCommitOnReturn; } + BOOL getCommitOnReturn() const { return mCommitOnReturn; } + + void setHelpURLCallback(const LLString &help_url); + const LLString& getHelpURL() const { return mHelpURL; } - void setHelpURLCallback(std::string help_url); - LLString getHelpURL() { return mHelpURL; } protected: + virtual void drawBorder(const LLColor4& color, S32 size); -protected: + void setImageUnselectedID(const LLUUID &image_id); + const LLUUID& getImageUnselectedID() const { return mImageUnselectedID; } + void setImageSelectedID(const LLUUID &image_id); + const LLUUID& getImageSelectedID() const { return mImageSelectedID; } + void setImageHoverSelectedID(const LLUUID &image_id); + void setImageHoverUnselectedID(const LLUUID &image_id); + void setImageDisabledID(const LLUUID &image_id); + void setImageDisabledSelectedID(const LLUUID &image_id); + const LLPointer<LLUIImage>& getImageUnselected() const { return mImageUnselected; } + const LLPointer<LLUIImage>& getImageSelected() const { return mImageSelected; } + + LLFrameTimer mMouseDownTimer; + +private: void (*mClickedCallback)(void* data ); void (*mMouseDownCallback)(void *data); @@ -203,7 +225,6 @@ protected: const LLFontGL *mGLFont; - LLFrameTimer mMouseDownTimer; S32 mMouseDownFrame; F32 mHeldDownDelay; // seconds, after which held-down callbacks get called S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called @@ -232,7 +253,6 @@ protected: LLUIString mDisabledSelectedLabel; LLColor4 mDisabledSelectedLabelColor; - LLUUID mImageUnselectedID; LLUUID mImageSelectedID; LLUUID mImageHoverSelectedID; @@ -280,7 +300,4 @@ protected: LLFrameTimer mFlashingTimer; }; -// Helpful functions -S32 round_up(S32 grid, S32 value); - #endif // LL_LLBUTTON_H diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index b0a7e9d27f..536e9a6dc6 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -212,7 +212,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) void LLCheckBoxCtrl::draw() { - if (mEnabled) + if (getEnabled()) { mLabel->setColor( mTextEnabledColor ); } diff --git a/indra/llui/llclipboard.cpp b/indra/llui/llclipboard.cpp index fc3967f5bf..b5c46cdff1 100644 --- a/indra/llui/llclipboard.cpp +++ b/indra/llui/llclipboard.cpp @@ -61,7 +61,7 @@ void LLClipboard::copyFromSubstring(const LLWString &src, S32 pos, S32 len, cons } -LLWString LLClipboard::getPasteWString( LLUUID* source_id ) +const LLWString& LLClipboard::getPasteWString( LLUUID* source_id ) { if( mSourceID.notNull() ) { @@ -88,7 +88,7 @@ LLWString LLClipboard::getPasteWString( LLUUID* source_id ) } -BOOL LLClipboard::canPasteString() +BOOL LLClipboard::canPasteString() const { return LLView::getWindow()->isClipboardTextAvailable(); } diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h index 999a17acc2..31ebd04826 100644 --- a/indra/llui/llclipboard.h +++ b/indra/llui/llclipboard.h @@ -36,24 +36,20 @@ #include "llstring.h" #include "lluuid.h" -// -// Classes -// + class LLClipboard { -protected: - LLUUID mSourceID; - LLWString mString; - public: LLClipboard(); ~LLClipboard(); void copyFromSubstring(const LLWString ©_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null ); - - - BOOL canPasteString(); - LLWString getPasteWString(LLUUID* source_id = NULL); + BOOL canPasteString() const; + const LLWString& getPasteWString(LLUUID* source_id = NULL); + +private: + LLUUID mSourceID; + LLWString mString; }; diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 28237823dd..250ca523d2 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -99,7 +99,7 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString mList->setCommitOnKeyboardMovement(FALSE); addChild(mList); - LLRect border_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect border_rect(0, getRect().getHeight(), getRect().getWidth(), 0); mBorder = new LLViewBorder( "combo border", border_rect ); addChild( mBorder ); mBorder->setFollowsAll(); @@ -444,7 +444,7 @@ void LLComboBox::setButtonVisible(BOOL visible) mButton->setVisible(visible); if (mTextEntry) { - LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); if (visible) { text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth(0)) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); @@ -460,7 +460,7 @@ void LLComboBox::draw() { mBorder->setKeyboardFocusHighlight(hasFocus()); - mButton->setEnabled(mEnabled /*&& !mList->isEmpty()*/); + mButton->setEnabled(getEnabled() /*&& !mList->isEmpty()*/); // Draw children normally LLUICtrl::draw(); @@ -494,13 +494,13 @@ void LLComboBox::updateLayout() if (mAllowTextEntry) { S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton"); - mButton->setRect(LLRect( mRect.getWidth() - llmax(8,mArrowImage->getWidth(0)) - 2 * shadow_size, + mButton->setRect(LLRect( getRect().getWidth() - llmax(8,mArrowImage->getWidth(0)) - 2 * shadow_size, rect.mTop, rect.mRight, rect.mBottom)); mButton->setTabStop(FALSE); if (!mTextEntry) { - LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth(0)) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); // clear label on button LLString cur_label = mButton->getLabelSelected(); @@ -575,7 +575,7 @@ void LLComboBox::showList() LLRect rect = mList->getRect(); - S32 min_width = mRect.getWidth(); + S32 min_width = getRect().getWidth(); S32 max_width = llmax(min_width, MAX_COMBO_WIDTH); S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width); @@ -589,7 +589,7 @@ void LLComboBox::showList() else { // stack on top or bottom, depending on which has more room - if (-root_view_local.mBottom > root_view_local.mTop - mRect.getHeight()) + if (-root_view_local.mBottom > root_view_local.mTop - getRect().getHeight()) { // Move rect so it hangs off the bottom of this view rect.setLeftTopAndSize(0, 0, list_width, llmin(-root_view_local.mBottom, rect.getHeight())); @@ -597,21 +597,21 @@ void LLComboBox::showList() else { // move rect so it stacks on top of this view (clipped to size of screen) - rect.setOriginAndSize(0, mRect.getHeight(), list_width, llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); + rect.setOriginAndSize(0, getRect().getHeight(), list_width, llmin(root_view_local.mTop - getRect().getHeight(), rect.getHeight())); } } } else // ABOVE { - if (rect.getHeight() <= root_view_local.mTop - mRect.getHeight()) + if (rect.getHeight() <= root_view_local.mTop - getRect().getHeight()) { // move rect so it stacks on top of this view (clipped to size of screen) - rect.setOriginAndSize(0, mRect.getHeight(), list_width, llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); + rect.setOriginAndSize(0, getRect().getHeight(), list_width, llmin(root_view_local.mTop - getRect().getHeight(), rect.getHeight())); } else { // stack on top or bottom, depending on which has more room - if (-root_view_local.mBottom > root_view_local.mTop - mRect.getHeight()) + if (-root_view_local.mBottom > root_view_local.mTop - getRect().getHeight()) { // Move rect so it hangs off the bottom of this view rect.setLeftTopAndSize(0, 0, list_width, llmin(-root_view_local.mBottom, rect.getHeight())); @@ -619,7 +619,7 @@ void LLComboBox::showList() else { // move rect so it stacks on top of this view (clipped to size of screen) - rect.setOriginAndSize(0, mRect.getHeight(), list_width, llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); + rect.setOriginAndSize(0, getRect().getHeight(), list_width, llmin(root_view_local.mTop - getRect().getHeight(), rect.getHeight())); } } @@ -752,15 +752,15 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_ { tool_tip = getShowNamesToolTip(); } - else if (!mToolTipMsg.empty()) - { - tool_tip = mToolTipMsg; - } else { - tool_tip = getValue().asString(); + tool_tip = getToolTip(); + if (tool_tip.empty()) + { + tool_tip = getValue().asString(); + } } - + if( !tool_tip.empty() ) { msg = tool_tip; @@ -770,7 +770,7 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_ 0, 0, &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); localPointToScreen( - mRect.getWidth(), mRect.getHeight(), + getRect().getWidth(), getRect().getHeight(), &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); } return TRUE; @@ -1037,11 +1037,11 @@ BOOL LLComboBox::setCurrentByID(const LLUUID& id) return found; } -LLUUID LLComboBox::getCurrentID() +LLUUID LLComboBox::getCurrentID() const { return mList->getStringUUIDSelectedItem(); } -BOOL LLComboBox::setSelectedByValue(LLSD value, BOOL selected) +BOOL LLComboBox::setSelectedByValue(const LLSD& value, BOOL selected) { BOOL found = mList->setSelectedByValue(value, selected); if (found) @@ -1056,7 +1056,7 @@ LLSD LLComboBox::getSelectedValue() return mList->getSelectedValue(); } -BOOL LLComboBox::isSelected(LLSD value) +BOOL LLComboBox::isSelected(const LLSD& value) const { return mList->isSelected(value); } @@ -1190,14 +1190,14 @@ void LLFlyoutButton::updateLayout() { LLComboBox::updateLayout(); - mButton->setOrigin(mRect.getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, 0); - mButton->reshape(FLYOUT_BUTTON_ARROW_WIDTH, mRect.getHeight()); + mButton->setOrigin(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, 0); + mButton->reshape(FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight()); mButton->setFollows(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); mButton->setTabStop(FALSE); mButton->setImageOverlay(mListPosition == BELOW ? "down_arrow.tga" : "up_arrow.tga", LLFontGL::RIGHT); mActionButton->setOrigin(0, 0); - mActionButton->reshape(mRect.getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, mRect.getHeight()); + mActionButton->reshape(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight()); } //static diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 303ba83e92..13c2455d61 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -158,10 +158,10 @@ public: virtual BOOL selectNthItem( S32 index ) { return setCurrentByIndex(index); } virtual S32 getFirstSelectedIndex() const { return getCurrentIndex(); } virtual BOOL setCurrentByID( const LLUUID& id ); - virtual LLUUID getCurrentID(); // LLUUID::null if no items in menu - virtual BOOL setSelectedByValue(LLSD value, BOOL selected); + virtual LLUUID getCurrentID() const; // LLUUID::null if no items in menu + virtual BOOL setSelectedByValue(const LLSD& value, BOOL selected); virtual LLSD getSelectedValue(); - virtual BOOL isSelected(LLSD value); + virtual BOOL isSelected(const LLSD& value) const; virtual BOOL operateOnSelection(EOperation op); virtual BOOL operateOnAll(EOperation op); @@ -182,18 +182,20 @@ public: void updateSelection(); virtual void showList(); virtual void hideList(); - + protected: LLButton* mButton; LLScrollListCtrl* mList; - S32 mButtonPadding; LLViewBorder* mBorder; + EPreferredPosition mListPosition; + LLPointer<LLImageGL> mArrowImage; + +private: + S32 mButtonPadding; LLLineEditor* mTextEntry; - LLPointer<LLImageGL> mArrowImage; BOOL mAllowTextEntry; S32 mMaxChars; BOOL mTextEntryTentative; - EPreferredPosition mListPosition; void (*mPrearrangeCallback)(LLUICtrl*,void*); void (*mTextEntryCallback)(LLLineEditor*, void*); }; diff --git a/indra/llui/llctrlselectioninterface.h b/indra/llui/llctrlselectioninterface.h index 77811d049b..e43e20a4c0 100644 --- a/indra/llui/llctrlselectioninterface.h +++ b/indra/llui/llctrlselectioninterface.h @@ -63,14 +63,14 @@ public: // TomY TODO: Simply cast the UUIDs to LLSDs, using the selectByValue function virtual BOOL setCurrentByID( const LLUUID& id ) = 0; - virtual LLUUID getCurrentID() = 0; + virtual LLUUID getCurrentID() const = 0; - BOOL selectByValue(LLSD value); - BOOL deselectByValue(LLSD value); - virtual BOOL setSelectedByValue(LLSD value, BOOL selected) = 0; + BOOL selectByValue(const LLSD value); + BOOL deselectByValue(const LLSD value); + virtual BOOL setSelectedByValue(const LLSD& value, BOOL selected) = 0; virtual LLSD getSelectedValue() = 0; - virtual BOOL isSelected(LLSD value) = 0; + virtual BOOL isSelected(const LLSD& value) const = 0; virtual BOOL operateOnSelection(EOperation op) = 0; virtual BOOL operateOnAll(EOperation op) = 0; @@ -100,7 +100,7 @@ class LLCtrlScrollInterface public: virtual ~LLCtrlScrollInterface(); - virtual S32 getScrollPos() = 0; + virtual S32 getScrollPos() const = 0; virtual void setScrollPos( S32 pos ) = 0; virtual void scrollToShowSelected() = 0; }; diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index ca536ea024..a4e92e11d0 100644 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -74,7 +74,24 @@ LLDragHandle::LLDragHandle( const LLString& name, const LLRect& rect, const LLSt void LLDragHandle::setTitleVisible(BOOL visible) { - mTitleBox->setVisible(visible); + if(mTitleBox) + { + mTitleBox->setVisible(visible); + } +} + +void LLDragHandle::setTitleBox(LLTextBox* titlebox) +{ + if( mTitleBox ) + { + removeChild(mTitleBox); + delete mTitleBox; + } + mTitleBox = titlebox; + if(mTitleBox) + { + addChild( mTitleBox ); + } } LLDragHandleTop::LLDragHandleTop(const LLString& name, const LLRect &rect, const LLString& title) @@ -113,46 +130,28 @@ LLString LLDragHandleLeft::getWidgetTag() const void LLDragHandleTop::setTitle(const LLString& title) { - if( mTitleBox ) - { - removeChild(mTitleBox); - delete mTitleBox; - } - LLString trimmed_title = title; LLString::trim(trimmed_title); const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF ); - mTitleBox = new LLTextBox( "Drag Handle Title", mRect, trimmed_title, font ); - mTitleBox->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT); - mTitleBox->setFontStyle(LLFontGL::DROP_SHADOW_SOFT); - reshapeTitleBox(); + LLTextBox* titlebox = new LLTextBox( "Drag Handle Title", getRect(), trimmed_title, font ); + titlebox->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT); + titlebox->setFontStyle(LLFontGL::DROP_SHADOW_SOFT); - // allow empty titles, as default behavior replaces them with title box name - if (trimmed_title.empty()) - { - mTitleBox->setText(LLString::null); - } - addChild( mTitleBox ); + setTitleBox(titlebox); + reshapeTitleBox(); } const LLString& LLDragHandleTop::getTitle() const { - return mTitleBox->getText(); + return getTitleBox() == NULL ? LLString::null : getTitleBox()->getText(); } void LLDragHandleLeft::setTitle(const LLString& ) { - if( mTitleBox ) - { - removeChild(mTitleBox); - delete mTitleBox; - } - - mTitleBox = NULL; - + setTitleBox(NULL); /* no title on left edge */ } @@ -166,14 +165,14 @@ const LLString& LLDragHandleLeft::getTitle() const void LLDragHandleTop::draw() { /* Disable lines. Can drag anywhere in most windows. JC - if( getVisible() && mEnabled && mForeground) + if( getVisible() && getEnabled() && mForeground) { const S32 BORDER_PAD = 2; const S32 HPAD = 2; const S32 VPAD = 2; S32 left = BORDER_PAD + HPAD; - S32 top = mRect.getHeight() - 2 * VPAD; - S32 right = mRect.getWidth() - HPAD; + S32 top = getRect().getHeight() - 2 * VPAD; + S32 right = getRect().getWidth() - HPAD; // S32 bottom = VPAD; // draw lines for drag areas @@ -183,7 +182,7 @@ void LLDragHandleTop::draw() LLRect title_rect = mTitleBox->getRect(); S32 title_right = title_rect.mLeft + mTitleWidth; - BOOL show_right_side = title_right < mRect.getWidth(); + BOOL show_right_side = title_right < getRect().getWidth(); for( S32 i=0; i<4; i++ ) { @@ -204,9 +203,9 @@ void LLDragHandleTop::draw() */ // Colorize the text to match the frontmost state - if (mTitleBox) + if (getTitleBox()) { - mTitleBox->setEnabled(mForeground); + getTitleBox()->setEnabled(getForeground()); } LLView::draw(); @@ -217,7 +216,7 @@ void LLDragHandleTop::draw() void LLDragHandleLeft::draw() { /* Disable lines. Can drag anywhere in most windows. JC - if( getVisible() && mEnabled && mForeground ) + if( getVisible() && getEnabled() && mForeground ) { const S32 BORDER_PAD = 2; // const S32 HPAD = 2; @@ -225,8 +224,8 @@ void LLDragHandleLeft::draw() const S32 LINE_SPACING = 3; S32 left = BORDER_PAD + LINE_SPACING; - S32 top = mRect.getHeight() - 2 * VPAD; -// S32 right = mRect.getWidth() - HPAD; + S32 top = getRect().getHeight() - 2 * VPAD; +// S32 right = getRect().getWidth() - HPAD; S32 bottom = VPAD; // draw lines for drag areas @@ -234,7 +233,7 @@ void LLDragHandleLeft::draw() // no titles yet //LLRect title_rect = mTitleBox->getRect(); //S32 title_right = title_rect.mLeft + mTitleWidth; - //BOOL show_right_side = title_right < mRect.getWidth(); + //BOOL show_right_side = title_right < getRect().getWidth(); S32 line = left; for( S32 i=0; i<4; i++ ) @@ -249,9 +248,9 @@ void LLDragHandleLeft::draw() */ // Colorize the text to match the frontmost state - if (mTitleBox) + if (getTitleBox()) { - mTitleBox->setEnabled(mForeground); + getTitleBox()->setEnabled(getForeground()); } LLView::draw(); @@ -259,19 +258,23 @@ void LLDragHandleLeft::draw() void LLDragHandleTop::reshapeTitleBox() { + if( ! getTitleBox()) + { + return; + } const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF ); - S32 title_width = font->getWidth( mTitleBox->getText() ) + TITLE_PAD; - if (mMaxTitleWidth > 0) - title_width = llmin(title_width, mMaxTitleWidth); + S32 title_width = font->getWidth( getTitleBox()->getText() ) + TITLE_PAD; + if (getMaxTitleWidth() > 0) + title_width = llmin(title_width, getMaxTitleWidth()); S32 title_height = llround(font->getLineHeight()); LLRect title_rect; title_rect.setLeftTopAndSize( LEFT_PAD, - mRect.getHeight() - BORDER_PAD, - mRect.getWidth() - LEFT_PAD - RIGHT_PAD, + getRect().getHeight() - BORDER_PAD, + getRect().getWidth() - LEFT_PAD - RIGHT_PAD, title_height); - mTitleBox->setRect( title_rect ); + getTitleBox()->setRect( title_rect ); } void LLDragHandleTop::reshape(S32 width, S32 height, BOOL called_from_parent) diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h index cd3ce04718..940eb21e66 100644 --- a/indra/llui/lldraghandle.h +++ b/indra/llui/lldraghandle.h @@ -45,11 +45,14 @@ class LLDragHandle : public LLView { public: LLDragHandle(const LLString& name, const LLRect& rect, const LLString& title ); + virtual ~LLDragHandle() { setTitleBox(NULL); } virtual void setValue(const LLSD& value); void setForeground(BOOL b) { mForeground = b; } + BOOL getForeground() const { return mForeground; } void setMaxTitleWidth(S32 max_width) {mMaxTitleWidth = llmin(max_width, mMaxTitleWidth); } + S32 getMaxTitleWidth() const { return mMaxTitleWidth; } void setTitleVisible(BOOL visible); virtual void setTitle( const LLString& title ) = 0; @@ -61,6 +64,10 @@ public: virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); protected: + LLTextBox* getTitleBox() const { return mTitleBox; } + void setTitleBox(LLTextBox*); + +private: S32 mDragLastScreenX; S32 mDragLastScreenY; S32 mLastMouseScreenX; diff --git a/indra/llui/lleditmenuhandler.cpp b/indra/llui/lleditmenuhandler.cpp index 9fb9cbe16c..435556b56c 100644 --- a/indra/llui/lleditmenuhandler.cpp +++ b/indra/llui/lleditmenuhandler.cpp @@ -33,98 +33,6 @@ #include "lleditmenuhandler.h" -LLEditMenuHandler* gEditMenuHandler = NULL; +/* static */ +LLEditMenuHandler* LLEditMenuHandler::gEditMenuHandler = NULL; -// virtual -LLEditMenuHandler::~LLEditMenuHandler() -{ } - -// virtual -void LLEditMenuHandler::undo() -{ } - -// virtual -BOOL LLEditMenuHandler::canUndo() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::redo() -{ } - -// virtual -BOOL LLEditMenuHandler::canRedo() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::cut() -{ } - -// virtual -BOOL LLEditMenuHandler::canCut() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::copy() -{ } - -// virtual -BOOL LLEditMenuHandler::canCopy() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::paste() -{ } - -// virtual -BOOL LLEditMenuHandler::canPaste() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::doDelete() -{ } - -// virtual -BOOL LLEditMenuHandler::canDoDelete() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::selectAll() -{ } - -// virtual -BOOL LLEditMenuHandler::canSelectAll() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::deselect() -{ } - -// virtual -BOOL LLEditMenuHandler::canDeselect() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::duplicate() -{ } - -// virtual -BOOL LLEditMenuHandler::canDuplicate() -{ - return FALSE; -} diff --git a/indra/llui/lleditmenuhandler.h b/indra/llui/lleditmenuhandler.h index b035a29fb4..22f5076c93 100644 --- a/indra/llui/lleditmenuhandler.h +++ b/indra/llui/lleditmenuhandler.h @@ -37,37 +37,43 @@ class LLEditMenuHandler { public: // this is needed even though this is just an interface class. - virtual ~LLEditMenuHandler(); + virtual ~LLEditMenuHandler() {}; - virtual void undo(); - virtual BOOL canUndo(); + virtual void undo() {}; + virtual BOOL canUndo() const { return FALSE; } - virtual void redo(); - virtual BOOL canRedo(); + virtual void redo() {}; + virtual BOOL canRedo() const { return FALSE; } - virtual void cut(); - virtual BOOL canCut(); + virtual void cut() {}; + virtual BOOL canCut() const { return FALSE; } - virtual void copy(); - virtual BOOL canCopy(); + virtual void copy() {}; + virtual BOOL canCopy() const { return FALSE; } - virtual void paste(); - virtual BOOL canPaste(); + virtual void paste() {}; + virtual BOOL canPaste() const { return FALSE; } // "delete" is a keyword - virtual void doDelete(); - virtual BOOL canDoDelete(); + virtual void doDelete() {}; + virtual BOOL canDoDelete() const { return FALSE; } - virtual void selectAll(); - virtual BOOL canSelectAll(); + virtual void selectAll() {}; + virtual BOOL canSelectAll() const { return FALSE; } - virtual void deselect(); - virtual BOOL canDeselect(); + virtual void deselect() {}; + virtual BOOL canDeselect() const { return FALSE; } - virtual void duplicate(); - virtual BOOL canDuplicate(); + virtual void duplicate() {}; + virtual BOOL canDuplicate() const { return FALSE; } + + // TODO: Instead of being a public data member, it would be better to hide it altogether + // and have a "set" method and then a bunch of static versions of the cut, copy, paste + // methods, etc that operate on the current global instance. That would drastically + // simplify the existing code that accesses this global variable by putting all the + // null checks in the one implementation of those static methods. -MG + static LLEditMenuHandler* gEditMenuHandler; }; -extern LLEditMenuHandler* gEditMenuHandler; #endif diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 0754d0eda9..5c1f8429d1 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -142,20 +142,18 @@ LLFloater::LLFloater() : mButtons[i] = NULL; } mDragHandle = NULL; + mHandle.bind(this); } LLFloater::LLFloater(const LLString& name) -: LLPanel(name) +: LLPanel(name), mAutoFocus(TRUE) // automatically take focus when opened { for (S32 i = 0; i < BUTTON_COUNT; i++) { mButtonsEnabled[i] = FALSE; mButtons[i] = NULL; } - LLString title; // null string - // automatically take focus when opened - mAutoFocus = TRUE; init(title, FALSE, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, FALSE, TRUE, TRUE); // defaults } @@ -168,15 +166,13 @@ LLFloater::LLFloater(const LLString& name, const LLRect& rect, const LLString& t BOOL minimizable, BOOL close_btn, BOOL bordered) -: LLPanel(name, rect, bordered) +: LLPanel(name, rect, bordered), mAutoFocus(TRUE) // automatically take focus when opened { for (S32 i = 0; i < BUTTON_COUNT; i++) { mButtonsEnabled[i] = FALSE; mButtons[i] = NULL; } - // automatically take focus when opened - mAutoFocus = TRUE; init( title, resizable, min_width, min_height, drag_on_left, minimizable, close_btn); } @@ -188,15 +184,13 @@ LLFloater::LLFloater(const LLString& name, const LLString& rect_control, const L BOOL minimizable, BOOL close_btn, BOOL bordered) -: LLPanel(name, rect_control, bordered) +: LLPanel(name, rect_control, bordered), mAutoFocus(TRUE) // automatically take focus when opened { for (S32 i = 0; i < BUTTON_COUNT; i++) { mButtonsEnabled[i] = FALSE; mButtons[i] = NULL; } - // automatically take focus when opened - mAutoFocus = TRUE; init( title, resizable, min_width, min_height, drag_on_left, minimizable, close_btn); } @@ -206,6 +200,8 @@ void LLFloater::init(const LLString& title, BOOL resizable, S32 min_width, S32 min_height, BOOL drag_on_left, BOOL minimizable, BOOL close_btn) { + mHandle.bind(this); + // Init function can be called more than once, so clear out old data. for (S32 i = 0; i < BUTTON_COUNT; i++) { @@ -219,20 +215,20 @@ void LLFloater::init(const LLString& title, } mButtonScale = 1.f; - BOOL need_border = mBorder != NULL; - + //sjb: Thia is a bit of a hack: + BOOL need_border = hasBorder(); + // remove the border since deleteAllChildren() will also delete the border (but not clear mBorder) + removeBorder(); // this will delete mBorder too deleteAllChildren(); - // make sure we don't have a pointer to an old, deleted border - mBorder = NULL; - //sjb: HACK! we had a border which was just deleted, so re-create it + // add the border back if we want it if (need_border) { - addBorder(); + addBorder(); } // chrome floaters don't take focus at all - mIsFocusRoot = !getIsChrome(); + setFocusRoot(!getIsChrome()); // Reset cached pointers mDragHandle = NULL; @@ -257,7 +253,7 @@ void LLFloater::init(const LLString& title, // Floaters start not minimized. When minimized, they save their // prior rectangle to be used on restore. mMinimized = FALSE; - mPreviousRect.set(0,0,0,0); + mExpandedRect.set(0,0,0,0); S32 close_pad; // space to the right of close box S32 close_box_size; // For layout purposes, how big is the close box? @@ -288,31 +284,20 @@ void LLFloater::init(const LLString& title, // Drag Handle // Add first so it's in the background. // const S32 drag_pad = 2; - LLRect drag_handle_rect; - if (!drag_on_left) - { - drag_handle_rect.set( 0, mRect.getHeight(), mRect.getWidth(), 0 ); - - /* - drag_handle_rect.setLeftTopAndSize( - 0, mRect.getHeight(), - mRect.getWidth() - - LLPANEL_BORDER_WIDTH - - drag_pad - - minimize_box_size - minimize_pad - - close_box_size - close_pad, - DRAG_HANDLE_HEIGHT); - */ - mDragHandle = new LLDragHandleTop( "Drag Handle", drag_handle_rect, title ); - } - else + if (drag_on_left) { + LLRect drag_handle_rect; drag_handle_rect.setOriginAndSize( 0, 0, DRAG_HANDLE_WIDTH, - mRect.getHeight() - LLPANEL_BORDER_WIDTH - close_box_size); + getRect().getHeight() - LLPANEL_BORDER_WIDTH - close_box_size); mDragHandle = new LLDragHandleLeft("drag", drag_handle_rect, title ); } + else // drag on top + { + LLRect drag_handle_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 ); + mDragHandle = new LLDragHandleTop( "Drag Handle", drag_handle_rect, title ); + } addChild(mDragHandle); // Resize Handle @@ -327,28 +312,28 @@ void LLFloater::init(const LLString& title, mResizeBar[LLResizeBar::LEFT] = new LLResizeBar( "resizebar_left", this, - LLRect( 0, mRect.getHeight(), RESIZE_BAR_THICKNESS, 0), + LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0), min_width, S32_MAX, LLResizeBar::LEFT ); addChild( mResizeBar[0] ); mResizeBar[LLResizeBar::TOP] = new LLResizeBar( "resizebar_top", this, - LLRect( 0, mRect.getHeight(), mRect.getWidth(), mRect.getHeight() - RESIZE_BAR_THICKNESS), + LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS), min_height, S32_MAX, LLResizeBar::TOP ); addChild( mResizeBar[1] ); mResizeBar[LLResizeBar::RIGHT] = new LLResizeBar( "resizebar_right", this, - LLRect( mRect.getWidth() - RESIZE_BAR_THICKNESS, mRect.getHeight(), mRect.getWidth(), 0), + LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0), min_width, S32_MAX, LLResizeBar::RIGHT ); addChild( mResizeBar[2] ); mResizeBar[LLResizeBar::BOTTOM] = new LLResizeBar( "resizebar_bottom", this, - LLRect( 0, RESIZE_BAR_THICKNESS, mRect.getWidth(), 0), + LLRect( 0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0), min_height, S32_MAX, LLResizeBar::BOTTOM ); addChild( mResizeBar[3] ); @@ -356,14 +341,14 @@ void LLFloater::init(const LLString& title, // Resize handles (corners) mResizeHandle[0] = new LLResizeHandle( "Resize Handle", - LLRect( mRect.getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, mRect.getWidth(), 0), + LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0), min_width, min_height, LLResizeHandle::RIGHT_BOTTOM); addChild(mResizeHandle[0]); mResizeHandle[1] = new LLResizeHandle( "resize", - LLRect( mRect.getWidth() - RESIZE_HANDLE_WIDTH, mRect.getHeight(), mRect.getWidth(), mRect.getHeight() - RESIZE_HANDLE_HEIGHT), + LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT), min_width, min_height, LLResizeHandle::RIGHT_TOP ); @@ -377,7 +362,7 @@ void LLFloater::init(const LLString& title, addChild(mResizeHandle[2]); mResizeHandle[3] = new LLResizeHandle( "resize", - LLRect( 0, mRect.getHeight(), RESIZE_HANDLE_WIDTH, mRect.getHeight() - RESIZE_HANDLE_HEIGHT ), + LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ), min_width, min_height, LLResizeHandle::LEFT_TOP ); @@ -413,7 +398,7 @@ void LLFloater::init(const LLString& title, setVisible(FALSE); // add self to handle->floater map - sFloaterMap[mViewHandle] = this; + sFloaterMap[mHandle] = this; if (!getParent()) { @@ -450,7 +435,7 @@ LLFloater::~LLFloater() // correct, non-minimized positions. setMinimized( FALSE ); - sFloaterMap.erase(mViewHandle); + sFloaterMap.erase(mHandle); delete mDragHandle; for (S32 i = 0; i < 4; i++) @@ -460,22 +445,6 @@ LLFloater::~LLFloater() } } -// virtual -EWidgetType LLFloater::getWidgetType() const -{ - return WIDGET_TYPE_FLOATER; -} - -// virtual -LLString LLFloater::getWidgetTag() const -{ - return LL_FLOATER_TAG; -} - -void LLFloater::destroy() -{ - die(); -} void LLFloater::setVisible( BOOL visible ) { @@ -501,7 +470,7 @@ void LLFloater::setVisible( BOOL visible ) for(handle_set_iter_t dependent_it = mDependents.begin(); dependent_it != mDependents.end(); ) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* floaterp = dependent_it->get(); if (floaterp) { @@ -513,10 +482,10 @@ void LLFloater::setVisible( BOOL visible ) void LLFloater::open() /* Flawfinder: ignore */ { - if (mSoundFlags != SILENT + if (getSoundFlags() != SILENT // don't play open sound for hosted (tabbed) windows && !getHost() - && !sHostp + && !getFloaterHost() && (!getVisible() || isMinimized())) { make_ui_sound("UISndWindowOpen"); @@ -524,17 +493,16 @@ void LLFloater::open() /* Flawfinder: ignore */ //RN: for now, we don't allow rehosting from one multifloater to another // just need to fix the bugs - LLMultiFloater* hostp = getHost(); - if (sHostp != NULL && hostp == NULL) + if (getFloaterHost() != NULL && getHost() == NULL) { // needs a host // only select tabs if window they are hosted in is visible - sHostp->addFloater(this, sHostp->getVisible()); + getFloaterHost()->addFloater(this, getFloaterHost()->getVisible()); } - else if (hostp != NULL) + else if (getHost() != NULL) { // already hosted - hostp->showFloater(this); + getHost()->showFloater(this); } else { @@ -558,7 +526,7 @@ void LLFloater::close(bool app_quitting) ((LLMultiFloater*)getHost())->removeFloater(this); } - if (mSoundFlags != SILENT + if (getSoundFlags() != SILENT && getVisible() && !getHost() && !app_quitting) @@ -571,7 +539,7 @@ void LLFloater::close(bool app_quitting) dependent_it != mDependents.end(); ) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* floaterp = dependent_it->get(); if (floaterp) { ++dependent_it; @@ -595,7 +563,7 @@ void LLFloater::close(bool app_quitting) // give focus to dependee floater if it exists, and we had focus first if (isDependent()) { - LLFloater* dependee = LLFloater::getFloaterByHandle(mDependeeHandle); + LLFloater* dependee = mDependeeHandle.get(); if (dependee && !dependee->isDead()) { dependee->setFocus(TRUE); @@ -661,20 +629,15 @@ void LLFloater::center() // hosted floaters can't move return; } - const LLRect &window = gFloaterView->getRect(); - - S32 left = window.mLeft + (window.getWidth() - mRect.getWidth()) / 2; - S32 bottom = window.mBottom + (window.getHeight() - mRect.getHeight()) / 2; - - translate( left - mRect.mLeft, bottom - mRect.mBottom ); + centerWithin(gFloaterView->getRect()); } void LLFloater::applyRectControl() { - if (!mRectControl.empty()) + if (!getRectControl().empty()) { - const LLRect& rect = LLUI::sConfigGroup->getRect(mRectControl); - translate( rect.mLeft - mRect.mLeft, rect.mBottom - mRect.mBottom); + const LLRect& rect = LLUI::sConfigGroup->getRect(getRectControl()); + translate( rect.mLeft - getRect().mLeft, rect.mBottom - getRect().mBottom); if (mResizable) { reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight())); @@ -715,7 +678,7 @@ LLString LLFloater::getShortTitle() -BOOL LLFloater::canSnapTo(LLView* other_view) +BOOL LLFloater::canSnapTo(const LLView* other_view) { if (NULL == other_view) { @@ -727,7 +690,7 @@ BOOL LLFloater::canSnapTo(LLView* other_view) { LLFloater* other_floaterp = (LLFloater*)other_view; - if (other_floaterp->getSnapTarget() == mViewHandle && mDependents.find(other_floaterp->getHandle()) != mDependents.end()) + if (other_floaterp->getSnapTarget() == getHandle() && mDependents.find(other_floaterp->getHandle()) != mDependents.end()) { // this is a dependent that is already snapped to us, so don't snap back to it return FALSE; @@ -737,7 +700,7 @@ BOOL LLFloater::canSnapTo(LLView* other_view) return LLPanel::canSnapTo(other_view); } -void LLFloater::snappedTo(LLView* snap_view) +void LLFloater::snappedTo(const LLView* snap_view) { if (!snap_view || snap_view == getParent()) { @@ -754,7 +717,7 @@ void LLFloater::snappedTo(LLView* snap_view) void LLFloater::userSetShape(const LLRect& new_rect) { - LLRect old_rect = mRect; + const LLRect& old_rect = getRect(); LLView::userSetShape(new_rect); // if not minimized, adjust all snapped dependents to new shape @@ -764,22 +727,22 @@ void LLFloater::userSetShape(const LLRect& new_rect) for(handle_set_iter_t dependent_it = mDependents.begin(); dependent_it != mDependents.end(); ++dependent_it) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* floaterp = dependent_it->get(); // is a dependent snapped to us? - if (floaterp && floaterp->getSnapTarget() == mViewHandle) + if (floaterp && floaterp->getSnapTarget() == getHandle()) { S32 delta_x = 0; S32 delta_y = 0; // check to see if it snapped to right or top, and move if dependee floater is resizing LLRect dependent_rect = floaterp->getRect(); - if (dependent_rect.mLeft - mRect.mLeft >= old_rect.getWidth() || // dependent on my right? - dependent_rect.mRight == mRect.mLeft + old_rect.getWidth()) // dependent aligned with my right + if (dependent_rect.mLeft - getRect().mLeft >= old_rect.getWidth() || // dependent on my right? + dependent_rect.mRight == getRect().mLeft + old_rect.getWidth()) // dependent aligned with my right { // was snapped directly onto right side or aligned with it delta_x += new_rect.getWidth() - old_rect.getWidth(); } - if (dependent_rect.mBottom - mRect.mBottom >= old_rect.getHeight() || - dependent_rect.mTop == mRect.mBottom + old_rect.getHeight()) + if (dependent_rect.mBottom - getRect().mBottom >= old_rect.getHeight() || + dependent_rect.mTop == getRect().mBottom + old_rect.getHeight()) { // was snapped directly onto top side or aligned with it delta_y += new_rect.getHeight() - old_rect.getHeight(); @@ -812,7 +775,7 @@ void LLFloater::setMinimized(BOOL minimize) if (minimize) { - mPreviousRect = mRect; + mExpandedRect = getRect(); reshape( MINIMIZED_WIDTH, LLFLOATER_HEADER_SIZE, TRUE); @@ -843,7 +806,7 @@ void LLFloater::setMinimized(BOOL minimize) LLView* viewp = *child_it; if (!viewp->getVisible()) { - mMinimizedHiddenChildren.push_back(viewp->mViewHandle); + mMinimizedHiddenChildren.push_back(viewp->getHandle()); } viewp->setVisible(FALSE); } @@ -860,7 +823,7 @@ void LLFloater::setMinimized(BOOL minimize) dependent_it != mDependents.end(); ++dependent_it) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* floaterp = dependent_it->get(); if (floaterp) { if (floaterp->isMinimizeable()) @@ -890,8 +853,8 @@ void LLFloater::setMinimized(BOOL minimize) mPreviousMinimizedBottom = currentRect.mBottom; } - reshape( mPreviousRect.getWidth(), mPreviousRect.getHeight(), TRUE ); - setOrigin( mPreviousRect.mLeft, mPreviousRect.mBottom ); + reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE ); + setOrigin( mExpandedRect.mLeft, mExpandedRect.mBottom ); if (mButtonsEnabled[BUTTON_RESTORE]) { @@ -906,10 +869,10 @@ void LLFloater::setMinimized(BOOL minimize) viewp->setVisible(TRUE); } - std::vector<LLViewHandle>::iterator itor = mMinimizedHiddenChildren.begin(); + std::vector<LLHandle<LLView> >::iterator itor = mMinimizedHiddenChildren.begin(); for ( ; itor != mMinimizedHiddenChildren.end(); ++itor) { - LLView* viewp = LLView::getViewByHandle(*itor); + LLView* viewp = itor->get(); if(viewp) { viewp->setVisible(FALSE); @@ -922,7 +885,7 @@ void LLFloater::setMinimized(BOOL minimize) dependent_it != mDependents.end(); ++dependent_it) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* floaterp = dependent_it->get(); if (floaterp) { floaterp->setMinimized(FALSE); @@ -979,7 +942,7 @@ void LLFloater::setIsChrome(BOOL is_chrome) // remove focus if we're changing to chrome setFocus(FALSE); // can't Ctrl-Tab to "chrome" floaters - mIsFocusRoot = FALSE; + setFocusRoot(FALSE); } // no titles displayed on "chrome" floaters @@ -1011,7 +974,7 @@ void LLFloater::cleanupHandles() for(handle_set_iter_t dependent_it = mDependents.begin(); dependent_it != mDependents.end(); ) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* floaterp = dependent_it->get(); if (!floaterp) { mDependents.erase(dependent_it++); @@ -1085,7 +1048,7 @@ void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition) if (reposition) { floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp)); - floaterp->setSnapTarget(mViewHandle); + floaterp->setSnapTarget(getHandle()); } gFloaterView->adjustToFitScreen(floaterp, FALSE); if (floaterp->isFrontmost()) @@ -1095,9 +1058,9 @@ void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition) } } -void LLFloater::addDependentFloater(LLViewHandle dependent, BOOL reposition) +void LLFloater::addDependentFloater(LLHandle<LLFloater> dependent, BOOL reposition) { - LLFloater* dependent_floaterp = LLFloater::getFloaterByHandle(dependent); + LLFloater* dependent_floaterp = dependent.get(); if(dependent_floaterp) { addDependentFloater(dependent_floaterp, reposition); @@ -1107,7 +1070,7 @@ void LLFloater::addDependentFloater(LLViewHandle dependent, BOOL reposition) void LLFloater::removeDependentFloater(LLFloater* floaterp) { mDependents.erase(floaterp->getHandle()); - floaterp->mDependeeHandle = LLViewHandle::sDeadHandle; + floaterp->mDependeeHandle = LLHandle<LLFloater>(); } // virtual @@ -1215,32 +1178,13 @@ void LLFloater::setFrontmost(BOOL take_focus) } } -// static -LLFloater* LLFloater::getFloaterByHandle(LLViewHandle handle) -{ - LLFloater* floater = NULL; - if (sFloaterMap.count(handle)) - { - floater = sFloaterMap[handle]; - } - if (floater && !floater->isDead()) - { - return floater; - } - else - { - return NULL; - } -} - //static void LLFloater::setEditModeEnabled(BOOL enable) { if (enable != sEditModeEnabled) { S32 count = 0; - std::map<LLViewHandle, LLFloater*>::iterator iter; - for(iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter) + for(handle_map_iter_t iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter) { LLFloater* floater = iter->second; if (!floater->isDead()) @@ -1255,41 +1199,6 @@ void LLFloater::setEditModeEnabled(BOOL enable) sEditModeEnabled = enable; } -//static -BOOL LLFloater::getEditModeEnabled() -{ - return sEditModeEnabled; -} - -//static -void LLFloater::show(LLFloater* floaterp) -{ - if (floaterp) - { - gFocusMgr.triggerFocusFlash(); - floaterp->open(); - if (floaterp->getHost()) - { - floaterp->getHost()->open(); - } - } -} - -//static -void LLFloater::hide(LLFloater* floaterp) -{ - if (floaterp) floaterp->close(); -} - -//static -BOOL LLFloater::visible(LLFloater* floaterp) -{ - if (floaterp) - { - return !floaterp->isMinimized() && floaterp->isInVisibleChain(); - } - return FALSE; -} // static void LLFloater::onClickMinimize(void *userdata) @@ -1316,9 +1225,9 @@ void LLFloater::onClickTearOff(void *userdata) self->open(); /* Flawfinder: ignore */ // only force position for floaters that don't have that data saved - if (self->mRectControl.empty()) + if (self->getRectControl().empty()) { - new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - LLFLOATER_HEADER_SIZE - 5, self->mRect.getWidth(), self->mRect.getHeight()); + new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - LLFLOATER_HEADER_SIZE - 5, self->getRect().getWidth(), self->getRect().getHeight()); self->setRect(new_rect); } gFloaterView->adjustToFitScreen(self, FALSE); @@ -1327,7 +1236,7 @@ void LLFloater::onClickTearOff(void *userdata) } else //Attach to parent. { - LLMultiFloater* new_host = (LLMultiFloater*)LLFloater::getFloaterByHandle(self->mLastHostHandle); + LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get(); if (new_host) { new_host->showFloater(self); @@ -1351,7 +1260,7 @@ void LLFloater::closeFocusedFloater() { LLFloater* focused_floater = NULL; - std::map<LLViewHandle, LLFloater*>::iterator iter; + handle_map_iter_t iter; for(iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter) { focused_floater = iter->second; @@ -1396,16 +1305,16 @@ void LLFloater::draw() if( getVisible() ) { // draw background - if( mBgVisible ) + if( isBackgroundVisible() ) { S32 left = LLPANEL_BORDER_WIDTH; - S32 top = mRect.getHeight() - LLPANEL_BORDER_WIDTH; - S32 right = mRect.getWidth() - LLPANEL_BORDER_WIDTH; + S32 top = getRect().getHeight() - LLPANEL_BORDER_WIDTH; + S32 right = getRect().getWidth() - LLPANEL_BORDER_WIDTH; S32 bottom = LLPANEL_BORDER_WIDTH; LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow"); F32 shadow_offset = (F32)LLUI::sConfigGroup->getS32("DropShadowFloater"); - if (!mBgOpaque) + if (!isBackgroundOpaque()) { shadow_offset *= 0.2f; shadow_color.mV[VALPHA] *= 0.5f; @@ -1415,13 +1324,13 @@ void LLFloater::draw() llround(shadow_offset)); // No transparent windows in simple UI - if (mBgOpaque) + if (isBackgroundOpaque()) { - gl_rect_2d( left, top, right, bottom, mBgColorOpaque ); + gl_rect_2d( left, top, right, bottom, getBackgroundColor() ); } else { - gl_rect_2d( left, top, right, bottom, mBgColorAlpha ); + gl_rect_2d( left, top, right, bottom, getTransparentColor() ); } if(gFocusMgr.childHasKeyboardFocus(this) && !getIsChrome() && !getTitle().empty()) @@ -1434,19 +1343,19 @@ void LLFloater::draw() } } - if( mDefaultBtn) + if( getDefaultButton() ) { - if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled()) + if (gFocusMgr.childHasKeyboardFocus( this ) && getDefaultButton()->getEnabled()) { LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); // is this button a direct descendent and not a nested widget (e.g. checkbox)? BOOL focus_is_child_button = focus_ctrl->getWidgetType() == WIDGET_TYPE_BUTTON && focus_ctrl->getParent() == this; // only enable default button when current focus is not a button - mDefaultBtn->setBorderEnabled(!focus_is_child_button); + getDefaultButton()->setBorderEnabled(!focus_is_child_button); } else { - mDefaultBtn->setBorderEnabled(FALSE); + getDefaultButton()->setBorderEnabled(FALSE); } } @@ -1461,13 +1370,13 @@ void LLFloater::draw() LLView::draw(); - if( mBgVisible ) + if( isBackgroundVisible() ) { // add in a border to improve spacialized visual aclarity ;) // use lines instead of gl_rect_2d so we can round the edges as per james' recommendation LLUI::setLineWidth(1.5f); LLColor4 outlineColor = gFocusMgr.childHasKeyboardFocus(this) ? LLUI::sColorsGroup->getColor("FloaterFocusBorderColor") : LLUI::sColorsGroup->getColor("FloaterUnfocusBorderColor"); - gl_rect_2d_offset_local(0, mRect.getHeight() + 1, mRect.getWidth() + 1, 0, outlineColor, -LLPANEL_BORDER_WIDTH, FALSE); + gl_rect_2d_offset_local(0, getRect().getHeight() + 1, getRect().getWidth() + 1, 0, outlineColor, -LLPANEL_BORDER_WIDTH, FALSE); LLUI::setLineWidth(1.f); } @@ -1481,7 +1390,7 @@ void LLFloater::draw() // when last host goes away if (mCanTearOff && !getHost()) { - LLFloater* old_host = gFloaterView->getFloaterByHandle(mLastHostHandle); + LLFloater* old_host = mLastHostHandle.get(); if (!old_host) { setCanTearOff(FALSE); @@ -1490,33 +1399,6 @@ void LLFloater::draw() } } -// virtual -void LLFloater::onOpen() -{ -} - -// virtual -void LLFloater::onClose(bool app_quitting) -{ - destroy(); -} - -// virtual -BOOL LLFloater::canClose() -{ - return TRUE; -} - -// virtual -BOOL LLFloater::canSaveAs() -{ - return FALSE; -} - -// virtual -void LLFloater::saveAs() -{ -} void LLFloater::setCanMinimize(BOOL can_minimize) { @@ -1585,28 +1467,28 @@ void LLFloater::setCanResize(BOOL can_resize) mResizeBar[0] = new LLResizeBar( "resizebar_left", this, - LLRect( 0, mRect.getHeight(), RESIZE_BAR_THICKNESS, 0), + LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0), mMinWidth, S32_MAX, LLResizeBar::LEFT ); addChild( mResizeBar[0] ); mResizeBar[1] = new LLResizeBar( "resizebar_top", this, - LLRect( 0, mRect.getHeight(), mRect.getWidth(), mRect.getHeight() - RESIZE_BAR_THICKNESS), + LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS), mMinHeight, S32_MAX, LLResizeBar::TOP ); addChild( mResizeBar[1] ); mResizeBar[2] = new LLResizeBar( "resizebar_right", this, - LLRect( mRect.getWidth() - RESIZE_BAR_THICKNESS, mRect.getHeight(), mRect.getWidth(), 0), + LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0), mMinWidth, S32_MAX, LLResizeBar::RIGHT ); addChild( mResizeBar[2] ); mResizeBar[3] = new LLResizeBar( "resizebar_bottom", this, - LLRect( 0, RESIZE_BAR_THICKNESS, mRect.getWidth(), 0), + LLRect( 0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0), mMinHeight, S32_MAX, LLResizeBar::BOTTOM ); addChild( mResizeBar[3] ); @@ -1614,14 +1496,14 @@ void LLFloater::setCanResize(BOOL can_resize) // Resize handles (corners) mResizeHandle[0] = new LLResizeHandle( "Resize Handle", - LLRect( mRect.getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, mRect.getWidth(), 0), + LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0), mMinWidth, mMinHeight, LLResizeHandle::RIGHT_BOTTOM); addChild(mResizeHandle[0]); mResizeHandle[1] = new LLResizeHandle( "resize", - LLRect( mRect.getWidth() - RESIZE_HANDLE_WIDTH, mRect.getHeight(), mRect.getWidth(), mRect.getHeight() - RESIZE_HANDLE_HEIGHT), + LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT), mMinWidth, mMinHeight, LLResizeHandle::RIGHT_TOP ); @@ -1635,7 +1517,7 @@ void LLFloater::setCanResize(BOOL can_resize) addChild(mResizeHandle[2]); mResizeHandle[3] = new LLResizeHandle( "resize", - LLRect( 0, mRect.getHeight(), RESIZE_HANDLE_WIDTH, mRect.getHeight() - RESIZE_HANDLE_HEIGHT ), + LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ), mMinWidth, mMinHeight, LLResizeHandle::LEFT_TOP ); @@ -1672,15 +1554,15 @@ void LLFloater::updateButtons() { btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH, - mRect.getHeight() - CLOSE_BOX_FROM_TOP - (LLFLOATER_CLOSE_BOX_SIZE + 1) * button_count, + getRect().getHeight() - CLOSE_BOX_FROM_TOP - (LLFLOATER_CLOSE_BOX_SIZE + 1) * button_count, llround((F32)LLFLOATER_CLOSE_BOX_SIZE * mButtonScale), llround((F32)LLFLOATER_CLOSE_BOX_SIZE * mButtonScale)); } else { btn_rect.setLeftTopAndSize( - mRect.getWidth() - LLPANEL_BORDER_WIDTH - (LLFLOATER_CLOSE_BOX_SIZE + 1) * button_count, - mRect.getHeight() - CLOSE_BOX_FROM_TOP, + getRect().getWidth() - LLPANEL_BORDER_WIDTH - (LLFLOATER_CLOSE_BOX_SIZE + 1) * button_count, + getRect().getHeight() - CLOSE_BOX_FROM_TOP, llround((F32)LLFLOATER_CLOSE_BOX_SIZE * mButtonScale), llround((F32)LLFLOATER_CLOSE_BOX_SIZE * mButtonScale)); } @@ -1698,7 +1580,7 @@ void LLFloater::updateButtons() } } - mDragHandle->setMaxTitleWidth(mRect.getWidth() - (button_count * (LLFLOATER_CLOSE_BOX_SIZE + 1))); + mDragHandle->setMaxTitleWidth(getRect().getWidth() - (button_count * (LLFLOATER_CLOSE_BOX_SIZE + 1))); } void LLFloater::buildButtons() @@ -1710,15 +1592,15 @@ void LLFloater::buildButtons() { btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH, - mRect.getHeight() - CLOSE_BOX_FROM_TOP - (LLFLOATER_CLOSE_BOX_SIZE + 1) * (i + 1), + getRect().getHeight() - CLOSE_BOX_FROM_TOP - (LLFLOATER_CLOSE_BOX_SIZE + 1) * (i + 1), llround(LLFLOATER_CLOSE_BOX_SIZE * mButtonScale), llround(LLFLOATER_CLOSE_BOX_SIZE * mButtonScale)); } else { btn_rect.setLeftTopAndSize( - mRect.getWidth() - LLPANEL_BORDER_WIDTH - (LLFLOATER_CLOSE_BOX_SIZE + 1) * (i + 1), - mRect.getHeight() - CLOSE_BOX_FROM_TOP, + getRect().getWidth() - LLPANEL_BORDER_WIDTH - (LLFLOATER_CLOSE_BOX_SIZE + 1) * (i + 1), + getRect().getHeight() - CLOSE_BOX_FROM_TOP, llround(LLFLOATER_CLOSE_BOX_SIZE * mButtonScale), llround(LLFLOATER_CLOSE_BOX_SIZE * mButtonScale)); } @@ -1761,16 +1643,6 @@ LLFloaterView::LLFloaterView( const LLString& name, const LLRect& rect ) resetStartingFloaterPosition(); } -EWidgetType LLFloaterView::getWidgetType() const -{ - return WIDGET_TYPE_FLOATER_VIEW; -} - -LLString LLFloaterView::getWidgetTag() const -{ - return LL_FLOATER_VIEW_TAG; -} - // By default, adjust vertical. void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent) { @@ -1780,8 +1652,8 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent) // When reshaping this view, make the floaters follow their closest edge. void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent, BOOL adjust_vertical) { - S32 old_width = mRect.getWidth(); - S32 old_height = mRect.getHeight(); + S32 old_width = getRect().getWidth(); + S32 old_height = getRect().getHeight(); for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) { @@ -1835,7 +1707,7 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent, BOOL for(LLFloater::handle_set_iter_t dependent_it = floaterp->mDependents.begin(); dependent_it != floaterp->mDependents.end(); ++dependent_it) { - LLFloater* dependent_floaterp = getFloaterByHandle(*dependent_it); + LLFloater* dependent_floaterp = dependent_it->get(); if (dependent_floaterp) { dependent_floaterp->setFollows(follow_flags); @@ -1937,7 +1809,7 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF for(LLFloater::handle_set_iter_t dependent_it = reference_floater->mDependents.begin(); dependent_it != reference_floater->mDependents.end(); ++dependent_it) { - LLFloater* sibling = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* sibling = dependent_it->get(); // check for dependents within 10 pixels of base floater if (sibling && sibling != neighbor && @@ -1949,8 +1821,8 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF } S32 left_margin = llmax(0, base_rect.mLeft); - S32 right_margin = llmax(0, mRect.getWidth() - base_rect.mRight); - S32 top_margin = llmax(0, mRect.getHeight() - base_rect.mTop); + S32 right_margin = llmax(0, getRect().getWidth() - base_rect.mRight); + S32 top_margin = llmax(0, getRect().getHeight() - base_rect.mTop); S32 bottom_margin = llmax(0, base_rect.mBottom); // find position for floater in following order @@ -1959,22 +1831,22 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF { if (right_margin > width) { - new_rect.translate(base_rect.mRight - neighbor->mRect.mLeft, base_rect.mTop - neighbor->mRect.mTop); + new_rect.translate(base_rect.mRight - neighbor->getRect().mLeft, base_rect.mTop - neighbor->getRect().mTop); return new_rect; } else if (left_margin > width) { - new_rect.translate(base_rect.mLeft - neighbor->mRect.mRight, base_rect.mTop - neighbor->mRect.mTop); + new_rect.translate(base_rect.mLeft - neighbor->getRect().mRight, base_rect.mTop - neighbor->getRect().mTop); return new_rect; } else if (bottom_margin > height) { - new_rect.translate(base_rect.mLeft - neighbor->mRect.mLeft, base_rect.mBottom - neighbor->mRect.mTop); + new_rect.translate(base_rect.mLeft - neighbor->getRect().mLeft, base_rect.mBottom - neighbor->getRect().mTop); return new_rect; } else if (top_margin > height) { - new_rect.translate(base_rect.mLeft - neighbor->mRect.mLeft, base_rect.mTop - neighbor->mRect.mBottom); + new_rect.translate(base_rect.mLeft - neighbor->getRect().mLeft, base_rect.mTop - neighbor->getRect().mBottom); return new_rect; } @@ -1989,15 +1861,6 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF return new_rect; } -void LLFloaterView::setCycleMode(BOOL mode) -{ - mFocusCycleMode = mode; -} - -BOOL LLFloaterView::getCycleMode() -{ - return mFocusCycleMode; -} void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus) { @@ -2027,7 +1890,7 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus) for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); dependent_it != floater->mDependents.end(); ) { - LLFloater* sibling = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* sibling = dependent_it->get(); if (sibling) { floaters_to_move.push_back(sibling); @@ -2058,7 +1921,7 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus) for(LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin(); dependent_it != child->mDependents.end(); ) { - LLFloater* dependent = getFloaterByHandle(*dependent_it); + LLFloater* dependent = dependent_it->get(); if (dependent) { sendChildToFront(dependent); @@ -2099,7 +1962,7 @@ void LLFloaterView::highlightFocusedFloater() dependent_it != floater->mDependents.end(); ++dependent_it) { - LLFloater* dependent_floaterp = getFloaterByHandle(*dependent_it); + LLFloater* dependent_floaterp = dependent_it->get(); if (dependent_floaterp && gFocusMgr.childHasKeyboardFocus(dependent_floaterp)) { floater_or_dependent_has_focus = TRUE; @@ -2112,7 +1975,7 @@ void LLFloaterView::highlightFocusedFloater() for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); dependent_it != floater->mDependents.end(); ) { - LLFloater* dependent_floaterp = getFloaterByHandle(*dependent_it); + LLFloater* dependent_floaterp = dependent_it->get(); if (dependent_floaterp) { dependent_floaterp->setForeground(floater_or_dependent_has_focus); @@ -2341,9 +2204,9 @@ void LLFloaterView::draw() } } -const LLRect LLFloaterView::getSnapRect() const +LLRect LLFloaterView::getSnapRect() const { - LLRect snap_rect = mRect; + LLRect snap_rect = getRect(); snap_rect.mBottom += mSnapOffsetBottom; return snap_rect; @@ -2410,23 +2273,6 @@ void LLFloaterView::syncFloaterTabOrder() } } -LLFloater* LLFloaterView::getFloaterByHandle(LLViewHandle handle) -{ - if (handle == LLViewHandle::sDeadHandle) - { - return NULL; - } - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - if (((LLFloater*)viewp)->getHandle() == handle) - { - return (LLFloater*)viewp; - } - } - return NULL; -} - LLFloater* LLFloaterView::getParentFloater(LLView* viewp) { LLView* parentp = viewp->getParent(); @@ -2492,13 +2338,13 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) LLMultiFloater::LLMultiFloater() : mTabContainer(NULL), - mTabPos(LLTabContainerCommon::TOP), + mTabPos(LLTabContainer::TOP), mAutoResize(TRUE) { } -LLMultiFloater::LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos) : +LLMultiFloater::LLMultiFloater(LLTabContainer::TabPosition tab_pos) : mTabContainer(NULL), mTabPos(tab_pos), mAutoResize(TRUE) @@ -2509,7 +2355,7 @@ LLMultiFloater::LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos) : LLMultiFloater::LLMultiFloater(const LLString &name) : LLFloater(name), mTabContainer(NULL), - mTabPos(LLTabContainerCommon::TOP), + mTabPos(LLTabContainer::TOP), mAutoResize(FALSE) { } @@ -2521,16 +2367,16 @@ LLMultiFloater::LLMultiFloater( BOOL auto_resize) : LLFloater(name, rect, name), mTabContainer(NULL), - mTabPos(LLTabContainerCommon::TOP), + mTabPos(LLTabContainer::TOP), mAutoResize(auto_resize) { mTabContainer = new LLTabContainer("Preview Tabs", - LLRect(LLPANEL_BORDER_WIDTH, mRect.getHeight() - LLFLOATER_HEADER_SIZE, mRect.getWidth() - LLPANEL_BORDER_WIDTH, 0), + LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0), mTabPos, - NULL, - NULL); + FALSE, + FALSE); mTabContainer->setFollowsAll(); - if (mResizable) + if (isResizable()) { mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH); } @@ -2549,12 +2395,12 @@ LLMultiFloater::LLMultiFloater( mAutoResize(auto_resize) { mTabContainer = new LLTabContainer("Preview Tabs", - LLRect(LLPANEL_BORDER_WIDTH, mRect.getHeight() - LLFLOATER_HEADER_SIZE, mRect.getWidth() - LLPANEL_BORDER_WIDTH, 0), - mTabPos, - NULL, - NULL); + LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0), + mTabPos, + FALSE, + FALSE); mTabContainer->setFollowsAll(); - if (mResizable && mTabPos == LLTabContainerCommon::BOTTOM) + if (isResizable() && mTabPos == LLTabContainer::BOTTOM) { mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH); } @@ -2563,21 +2409,6 @@ LLMultiFloater::LLMultiFloater( } -LLMultiFloater::~LLMultiFloater() -{ -} - -// virtual -EWidgetType LLMultiFloater::getWidgetType() const -{ - return WIDGET_TYPE_MULTI_FLOATER; -} - -// virtual -LLString LLMultiFloater::getWidgetTag() const -{ - return LL_MULTI_FLOATER_TAG; -} void LLMultiFloater::open() /* Flawfinder: ignore */ { @@ -2597,7 +2428,7 @@ void LLMultiFloater::onClose(bool app_quitting) { if(closeAllFloaters() == TRUE) { - LLFloater::onClose(app_quitting ? true : false); + LLFloater::onClose(app_quitting); }//else not all tabs could be closed... } @@ -2648,16 +2479,18 @@ BOOL LLMultiFloater::closeAllFloaters() void LLMultiFloater::growToFit(S32 content_width, S32 content_height) { - S32 new_width = llmax(mRect.getWidth(), content_width + LLPANEL_BORDER_WIDTH * 2); - S32 new_height = llmax(mRect.getHeight(), content_height + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT); + S32 new_width = llmax(getRect().getWidth(), content_width + LLPANEL_BORDER_WIDTH * 2); + S32 new_height = llmax(getRect().getHeight(), content_height + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT); - if (isMinimized()) - { - mPreviousRect.setLeftTopAndSize(mPreviousRect.mLeft, mPreviousRect.mTop, new_width, new_height); - } + if (isMinimized()) + { + LLRect newrect; + newrect.setLeftTopAndSize(getExpandedRect().mLeft, getExpandedRect().mTop, new_width, new_height); + setExpandedRect(newrect); + } else { - S32 old_height = mRect.getHeight(); + S32 old_height = getRect().getHeight(); reshape(new_width, new_height); // keep top left corner in same position translate(0, old_height - new_height); @@ -2737,7 +2570,7 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, } floaterp->setHost(this); - if (mMinimized) + if (isMinimized()) { floaterp->setVisible(FALSE); } @@ -2920,7 +2753,7 @@ void LLMultiFloater::onTabSelected(void* userdata, bool from_click) void LLMultiFloater::setCanResize(BOOL can_resize) { LLFloater::setCanResize(can_resize); - if (mResizable && mTabContainer->getTabPosition() == LLTabContainer::BOTTOM) + if (isResizable() && mTabContainer->getTabPosition() == LLTabContainer::BOTTOM) { mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH); } @@ -2963,20 +2796,23 @@ void LLMultiFloater::updateResizeLimits() } setResizeLimits(new_min_width, new_min_height); - S32 cur_height = mRect.getHeight(); - S32 new_width = llmax(mRect.getWidth(), new_min_width); - S32 new_height = llmax(mRect.getHeight(), new_min_height); + S32 cur_height = getRect().getHeight(); + S32 new_width = llmax(getRect().getWidth(), new_min_width); + S32 new_height = llmax(getRect().getHeight(), new_min_height); if (isMinimized()) { - mPreviousRect.setLeftTopAndSize(mPreviousRect.mLeft, mPreviousRect.mTop, llmax(mPreviousRect.getWidth(), new_width), llmax(mPreviousRect.getHeight(), new_height)); + const LLRect& expanded = getExpandedRect(); + LLRect newrect; + newrect.setLeftTopAndSize(expanded.mLeft, expanded.mTop, llmax(expanded.getWidth(), new_width), llmax(expanded.getHeight(), new_height)); + setExpandedRect(newrect); } else { reshape(new_width, new_height); // make sure upper left corner doesn't move - translate(0, cur_height - mRect.getHeight()); + translate(0, cur_height - getRect().getHeight()); // make sure this window is visible on screen when it has been modified // (tab added, etc) diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 1d88501b01..5eb55e0420 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -112,8 +112,8 @@ public: void initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory, BOOL open = TRUE); /*virtual*/ void userSetShape(const LLRect& new_rect); - /*virtual*/ BOOL canSnapTo(LLView* other_view); - /*virtual*/ void snappedTo(LLView* snap_view); + /*virtual*/ BOOL canSnapTo(const LLView* other_view); + /*virtual*/ void snappedTo(const LLView* snap_view); /*virtual*/ void setFocus( BOOL b ); /*virtual*/ void setIsChrome(BOOL is_chrome); @@ -122,16 +122,14 @@ public: virtual void init(const LLString& title, BOOL resizable, S32 min_width, S32 min_height, BOOL drag_on_left, BOOL minimizable, BOOL close_btn); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_FLOATER; } + virtual LLString getWidgetTag() const { return LL_FLOATER_TAG; }; virtual void open(); /* Flawfinder: ignore */ // If allowed, close the floater cleanly, releasing focus. // app_quitting is passed to onClose() below. virtual void close(bool app_quitting = false); - - void setAutoFocus(BOOL focus) { mAutoFocus = focus; setFocus(focus); } // Release keyboard and mouse focus void releaseFocus(); @@ -142,18 +140,18 @@ public: void applyRectControl(); - LLMultiFloater* getHost() { return (LLMultiFloater*)LLFloater::getFloaterByHandle(mHostHandle); } + LLMultiFloater* getHost() { return (LLMultiFloater*)mHostHandle.get(); } void setTitle( const LLString& title ); - const LLString& getTitle() const; + const LLString& getTitle() const; void setShortTitle( const LLString& short_title ); LLString getShortTitle(); virtual void setMinimized(BOOL b); void moveResizeHandlesToFront(); void addDependentFloater(LLFloater* dependent, BOOL reposition = TRUE); - void addDependentFloater(LLViewHandle dependent_handle, BOOL reposition = TRUE); - LLFloater* getDependee() { return (LLFloater*)LLFloater::getFloaterByHandle(mDependeeHandle); } - void removeDependentFloater(LLFloater* dependent); + void addDependentFloater(LLHandle<LLFloater> dependent_handle, BOOL reposition = TRUE); + LLFloater* getDependee() { return (LLFloater*)mDependeeHandle.get(); } + void removeDependentFloater(LLFloater* dependent); BOOL isMinimized() { return mMinimized; } BOOL isFrontmost(); BOOL isDependent() { return !mDependeeHandle.isDead(); } @@ -167,10 +165,9 @@ public: void setResizeLimits( S32 min_width, S32 min_height ); void getResizeLimits( S32* min_width, S32* min_height ) { *min_width = mMinWidth; *min_height = mMinHeight; } - bool isMinimizeable() const{ return mButtonsEnabled[BUTTON_MINIMIZE]; } // Does this window have a close button, NOT can we close it right now. - bool isCloseable() const{ return (mButtonsEnabled[BUTTON_CLOSE] ? true : false); } + bool isCloseable() const{ return (mButtonsEnabled[BUTTON_CLOSE]); } bool isDragOnLeft() const{ return mDragOnLeft; } S32 getMinWidth() const{ return mMinWidth; } S32 getMinHeight() const{ return mMinHeight; } @@ -181,29 +178,28 @@ public: virtual void draw(); - // does nothing by default - virtual void onOpen(); + virtual void onOpen() {} // Call destroy() to free memory, or setVisible(FALSE) to keep it // If app_quitting, you might not want to save your visibility. // Defaults to destroy(). - virtual void onClose(bool app_quitting); + virtual void onClose(bool app_quitting) { destroy(); } - // Defaults to true. - virtual BOOL canClose(); + virtual BOOL canClose() const { return TRUE; } virtual void setVisible(BOOL visible); void setFrontmost(BOOL take_focus = TRUE); // Defaults to false. - virtual BOOL canSaveAs(); + virtual BOOL canSaveAs() const { return FALSE; } - // Defaults to no-op. - virtual void saveAs(); + virtual void saveAs() {} - void setSnapTarget(LLViewHandle handle) { mSnappedTo = handle; } + void setSnapTarget(LLHandle<LLFloater> handle) { mSnappedTo = handle; } void clearSnapTarget() { mSnappedTo.markDead(); } - LLViewHandle getSnapTarget() { return mSnappedTo; } + LLHandle<LLFloater> getSnapTarget() { return mSnappedTo; } + + LLHandle<LLFloater> getHandle() { return mHandle; } static void closeFocusedFloater(); @@ -214,39 +210,39 @@ public: static void setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; } static void setEditModeEnabled(BOOL enable); - static BOOL getEditModeEnabled(); + static BOOL getEditModeEnabled() { return sEditModeEnabled; } static LLMultiFloater* getFloaterHost() {return sHostp; } - static void show(LLFloater* floaterp); - static void hide(LLFloater* floaterp); - static BOOL visible(LLFloater* floaterp); - - static LLFloater* getFloaterByHandle(LLViewHandle handle); - protected: - // Don't call this directly. You probably want to call close(). JC - void destroy(); + virtual void bringToFront(S32 x, S32 y); - virtual void setVisibleAndFrontmost(BOOL take_focus=TRUE); + virtual void setVisibleAndFrontmost(BOOL take_focus=TRUE); + + void setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized + const LLRect& getExpandedRect() const { return mExpandedRect; } + + void setAutoFocus(BOOL focus) { mAutoFocus = focus; } // whether to automatically take focus when opened + LLDragHandle* getDragHandle() const { return mDragHandle; } + + void destroy() { die(); } // Don't call this directly. You probably want to call close(). JC + +private: + void setForeground(BOOL b); // called only by floaterview void cleanupHandles(); // remove handles to dead floaters void createMinimizeButton(); void updateButtons(); void buildButtons(); -protected: -// static LLViewerImage* sBackgroundImage; -// static LLViewerImage* sShadowImage; - + LLRect mExpandedRect; LLDragHandle* mDragHandle; LLResizeBar* mResizeBar[4]; LLResizeHandle* mResizeHandle[4]; LLButton *mMinimizeButton; BOOL mCanTearOff; BOOL mMinimized; - LLRect mPreviousRect; BOOL mForeground; - LLViewHandle mDependeeHandle; + LLHandle<LLFloater> mDependeeHandle; LLString mShortTitle; BOOL mFirstLook; // TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible. @@ -255,25 +251,24 @@ protected: S32 mMinWidth; S32 mMinHeight; - BOOL mAutoFocus; BOOL mEditing; - typedef std::set<LLViewHandle> handle_set_t; - typedef std::set<LLViewHandle>::iterator handle_set_iter_t; + typedef std::set<LLHandle<LLFloater> > handle_set_t; + typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t; handle_set_t mDependents; bool mDragOnLeft; BOOL mButtonsEnabled[BUTTON_COUNT]; LLButton* mButtons[BUTTON_COUNT]; F32 mButtonScale; - - LLViewHandle mSnappedTo; + BOOL mAutoFocus; + LLHandle<LLFloater> mSnappedTo; - LLViewHandle mHostHandle; - LLViewHandle mLastHostHandle; + LLHandle<LLFloater> mHostHandle; + LLHandle<LLFloater> mLastHostHandle; - static BOOL sEditModeEnabled; static LLMultiFloater* sHostp; + static BOOL sEditModeEnabled; static LLString sButtonActiveImageNames[BUTTON_COUNT]; static LLString sButtonInactiveImageNames[BUTTON_COUNT]; static LLString sButtonPressedImageNames[BUTTON_COUNT]; @@ -282,15 +277,18 @@ protected: typedef void (*click_callback)(void *); static click_callback sButtonCallbacks[BUTTON_COUNT]; - typedef std::map<LLViewHandle, LLFloater*> handle_map_t; - typedef std::map<LLViewHandle, LLFloater*>::iterator handle_map_iter_t; + typedef std::map<LLHandle<LLFloater>, LLFloater*> handle_map_t; + typedef std::map<LLHandle<LLFloater>, LLFloater*>::iterator handle_map_iter_t; static handle_map_t sFloaterMap; - std::vector<LLViewHandle> mMinimizedHiddenChildren; + std::vector<LLHandle<LLView> > mMinimizedHiddenChildren; BOOL mHasBeenDraggedWhileMinimized; S32 mPreviousMinimizedBottom; S32 mPreviousMinimizedLeft; + +private: + LLRootHandle<LLFloater> mHandle; }; ///////////////////////////////////////////////////////////// @@ -302,14 +300,14 @@ class LLFloaterView : public LLUICtrl public: LLFloaterView( const LLString& name, const LLRect& rect ); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_FLOATER_VIEW; } + virtual LLString getWidgetTag() const { return LL_FLOATER_VIEW_TAG; } /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); void reshape(S32 width, S32 height, BOOL called_from_parent, BOOL adjust_vertical); /*virtual*/ void draw(); - /*virtual*/ const LLRect getSnapRect() const; + /*virtual*/ LLRect getSnapRect() const; void refresh(); void getNewFloaterPosition( S32* left, S32* top ); @@ -325,8 +323,8 @@ public: void pushVisibleAll(BOOL visible, const skip_list_t& skip_list = skip_list_t()); void popVisibleAll(const skip_list_t& skip_list = skip_list_t()); - void setCycleMode(BOOL mode); - BOOL getCycleMode(); + void setCycleMode(BOOL mode) { mFocusCycleMode = mode; } + BOOL getCycleMode() const { return mFocusCycleMode; } void bringToFront( LLFloater* child, BOOL give_focus = TRUE ); void highlightFocusedFloater(); void unhighlightFocusedFloater(); @@ -342,10 +340,6 @@ public: LLFloater* getFocusedFloater(); void syncFloaterTabOrder(); - // Get a floater based the handle. If this returns NULL, it is up - // to the caller to discard the handle. - LLFloater* getFloaterByHandle(LLViewHandle handle); - // Returns z order of child provided. 0 is closest, larger numbers // are deeper in the screen. If there is no such child, the return // value is not defined. @@ -361,15 +355,16 @@ private: S32 mSnapOffsetBottom; }; +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLMultiFloater&oldid=81376 class LLMultiFloater : public LLFloater { public: LLMultiFloater(); - LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos); + LLMultiFloater(LLTabContainer::TabPosition tab_pos); LLMultiFloater(const LLString& name); LLMultiFloater(const LLString& name, const LLRect& rect, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE); LLMultiFloater(const LLString& name, const LLString& rect_control, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE); - virtual ~LLMultiFloater(); + virtual ~LLMultiFloater() {}; virtual BOOL postBuild(); /*virtual*/ void open(); /* Flawfinder: ignore */ @@ -377,12 +372,12 @@ public: /*virtual*/ void draw(); /*virtual*/ void setVisible(BOOL visible); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); - /*virtual*/ EWidgetType getWidgetType() const; - /*virtual*/ LLString getWidgetTag() const; + /*virtual*/ EWidgetType getWidgetType() const { return WIDGET_TYPE_MULTI_FLOATER; } + /*virtual*/ LLString getWidgetTag() const { return LL_MULTI_FLOATER_TAG; }; virtual void setCanResize(BOOL can_resize); virtual void growToFit(S32 content_width, S32 content_height); - virtual void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainerCommon::eInsertionPoint insertion_point = LLTabContainerCommon::END); + virtual void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); virtual void showFloater(LLFloater* floaterp); virtual void removeFloater(LLFloater* floaterp); @@ -400,7 +395,7 @@ public: virtual void setFloaterFlashing(LLFloater* floaterp, BOOL flashing); virtual BOOL closeAllFloaters(); //Returns FALSE if the floater could not be closed due to pending confirmation dialogs - void setTabContainer(LLTabContainerCommon* tab_container) { if (!mTabContainer) mTabContainer = tab_container; } + void setTabContainer(LLTabContainer* tab_container) { if (!mTabContainer) mTabContainer = tab_container; } static void onTabSelected(void* userdata, bool); virtual void updateResizeLimits(); @@ -414,15 +409,56 @@ protected: BOOL mCanResize; }; - LLTabContainerCommon* mTabContainer; + LLTabContainer* mTabContainer; - typedef std::map<LLViewHandle, LLFloaterData> floater_data_map_t; + typedef std::map<LLHandle<LLFloater>, LLFloaterData> floater_data_map_t; floater_data_map_t mFloaterDataMap; - LLTabContainerCommon::TabPosition mTabPos; + LLTabContainer::TabPosition mTabPos; BOOL mAutoResize; }; +// visibility policy specialized for floaters +template<> +class VisibilityPolicy<LLFloater> +{ +public: + // visibility methods + static bool visible(LLFloater* instance, const LLSD& key) + { + if (instance) + { + return !instance->isMinimized() && instance->isInVisibleChain(); + } + return FALSE; + } + + static void show(LLFloater* instance, const LLSD& key) + { + if (instance) + { + instance->open(); + if (instance->getHost()) + { + instance->getHost()->open(); + } + } + } + + static void hide(LLFloater* instance, const LLSD& key) + { + if (instance) instance->close(); + } +}; + + +// singleton implementation for floaters (provides visibility policy) +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=79410 + +template <class T> class LLFloaterSingleton : public LLUISingleton<T, VisibilityPolicy<LLFloater> > +{ +}; + extern LLFloaterView* gFloaterView; diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index e3337eb588..29c6aa3c30 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -57,12 +57,8 @@ LLFocusMgr::LLFocusMgr() { } -LLFocusMgr::~LLFocusMgr() -{ - mFocusHistory.clear(); -} -void LLFocusMgr::releaseFocusIfNeeded( LLView* view ) +void LLFocusMgr::releaseFocusIfNeeded( const LLView* view ) { if( childHasMouseCapture( view ) ) { @@ -146,7 +142,7 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock) if (focus_subtree) { - mFocusHistory[focus_subtree->mViewHandle] = mKeyboardFocus ? mKeyboardFocus->mViewHandle : LLViewHandle::sDeadHandle; + mFocusHistory[focus_subtree->getHandle()] = mKeyboardFocus ? mKeyboardFocus->getHandle() : LLHandle<LLView>(); } } @@ -156,10 +152,6 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock) } } -void LLFocusMgr::setDefaultKeyboardFocus(LLUICtrl* default_focus) -{ - mDefaultKeyboardFocus = default_focus; -} // Returns TRUE is parent or any descedent of parent has keyboard focus. BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const @@ -177,7 +169,7 @@ BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const } // Returns TRUE is parent or any descedent of parent is the mouse captor. -BOOL LLFocusMgr::childHasMouseCapture( LLView* parent ) +BOOL LLFocusMgr::childHasMouseCapture( const LLView* parent ) const { if( mMouseCaptor && mMouseCaptor->isView() ) { @@ -194,7 +186,7 @@ BOOL LLFocusMgr::childHasMouseCapture( LLView* parent ) return FALSE; } -void LLFocusMgr::removeKeyboardFocusWithoutCallback( LLView* focus ) +void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLView* focus ) { // should be ok to unlock here, as you have to know the locked view // in order to unlock it @@ -253,7 +245,7 @@ void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor ) } } -void LLFocusMgr::removeMouseCaptureWithoutCallback( LLMouseHandler* captor ) +void LLFocusMgr::removeMouseCaptureWithoutCallback( const LLMouseHandler* captor ) { //if (mFocusLocked) //{ @@ -269,7 +261,7 @@ void LLFocusMgr::removeMouseCaptureWithoutCallback( LLMouseHandler* captor ) } -BOOL LLFocusMgr::childIsTopCtrl( LLView* parent ) +BOOL LLFocusMgr::childIsTopCtrl( const LLView* parent ) const { LLView* top_view = (LLView*)mTopCtrl; while( top_view ) @@ -304,7 +296,7 @@ void LLFocusMgr::setTopCtrl( LLUICtrl* new_top ) } } -void LLFocusMgr::removeTopCtrlWithoutCallback( LLUICtrl* top_view ) +void LLFocusMgr::removeTopCtrlWithoutCallback( const LLUICtrl* top_view ) { if( mTopCtrl == top_view ) { @@ -325,12 +317,12 @@ void LLFocusMgr::unlockFocus() mLockedView = NULL; } -F32 LLFocusMgr::getFocusFlashAmt() +F32 LLFocusMgr::getFocusFlashAmt() const { return clamp_rescale(getFocusTime(), 0.f, FOCUS_FADE_TIME, mFocusWeight, 0.f); } -LLColor4 LLFocusMgr::getFocusColor() +LLColor4 LLFocusMgr::getFocusColor() const { LLColor4 focus_color = lerp(LLUI::sColorsGroup->getColor( "FocusColor" ), LLColor4::white, getFocusFlashAmt()); // de-emphasize keyboard focus when app has lost focus (to avoid typing into wrong window problem) @@ -362,15 +354,15 @@ void LLFocusMgr::setAppHasFocus(BOOL focus) mAppHasFocus = focus; } -LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) +LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const { if (subtree_root) { - focus_history_map_t::iterator found_it = mFocusHistory.find(subtree_root->mViewHandle); + focus_history_map_t::const_iterator found_it = mFocusHistory.find(subtree_root->getHandle()); if (found_it != mFocusHistory.end()) { // found last focus for this subtree - return static_cast<LLUICtrl*>(LLView::getViewByHandle(found_it->second)); + return static_cast<LLUICtrl*>(found_it->second.get()); } } return NULL; @@ -380,6 +372,6 @@ void LLFocusMgr::clearLastFocusForGroup(LLView* subtree_root) { if (subtree_root) { - mFocusHistory.erase(subtree_root->mViewHandle); + mFocusHistory.erase(subtree_root->getHandle()); } } diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index 20dc21fc3a..a3ca8bee26 100644 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -45,48 +45,48 @@ class LLFocusMgr { public: LLFocusMgr(); - ~LLFocusMgr(); + ~LLFocusMgr() { mFocusHistory.clear(); } // Mouse Captor void setMouseCapture(LLMouseHandler* new_captor); // new_captor = NULL to release the mouse. - LLMouseHandler* getMouseCapture() { return mMouseCaptor; } - void removeMouseCaptureWithoutCallback( LLMouseHandler* captor ); - BOOL childHasMouseCapture( LLView* parent ); + LLMouseHandler* getMouseCapture() const { return mMouseCaptor; } + void removeMouseCaptureWithoutCallback( const LLMouseHandler* captor ); + BOOL childHasMouseCapture( const LLView* parent ) const; // Keyboard Focus void setKeyboardFocus(LLUICtrl* new_focus, BOOL lock = FALSE); // new_focus = NULL to release the focus. LLUICtrl* getKeyboardFocus() const { return mKeyboardFocus; } LLUICtrl* getLastKeyboardFocus() const { return mLastKeyboardFocus; } BOOL childHasKeyboardFocus( const LLView* parent ) const; - void removeKeyboardFocusWithoutCallback( LLView* focus ); + void removeKeyboardFocusWithoutCallback( const LLView* focus ); F32 getFocusTime() const { return mFocusTimer.getElapsedTimeF32(); } - F32 getFocusFlashAmt(); - LLColor4 getFocusColor(); + F32 getFocusFlashAmt() const; + LLColor4 getFocusColor() const; void triggerFocusFlash(); - BOOL getAppHasFocus() { return mAppHasFocus; } + BOOL getAppHasFocus() const { return mAppHasFocus; } void setAppHasFocus(BOOL focus); - LLUICtrl* getLastFocusForGroup(LLView* subtree_root); + LLUICtrl* getLastFocusForGroup(LLView* subtree_root) const; void clearLastFocusForGroup(LLView* subtree_root); // If setKeyboardFocus(NULL) is called, and there is a non-NULL default // keyboard focus view, focus goes there. JC - void setDefaultKeyboardFocus(LLUICtrl* default_focus); + void setDefaultKeyboardFocus(LLUICtrl* default_focus) { mDefaultKeyboardFocus = default_focus; } LLUICtrl* getDefaultKeyboardFocus() const { return mDefaultKeyboardFocus; } // Top View void setTopCtrl(LLUICtrl* new_top); LLUICtrl* getTopCtrl() const { return mTopCtrl; } - void removeTopCtrlWithoutCallback( LLUICtrl* top_view ); - BOOL childIsTopCtrl( LLView* parent ); + void removeTopCtrlWithoutCallback( const LLUICtrl* top_view ); + BOOL childIsTopCtrl( const LLView* parent ) const; // All Three - void releaseFocusIfNeeded( LLView* top_view ); + void releaseFocusIfNeeded( const LLView* top_view ); void lockFocus(); void unlockFocus(); - BOOL focusLocked() { return mLockedView != NULL; } + BOOL focusLocked() const { return mLockedView != NULL; } -protected: +private: LLUICtrl* mLockedView; // Mouse Captor @@ -105,7 +105,7 @@ protected: BOOL mAppHasFocus; - typedef std::map<LLViewHandle, LLViewHandle> focus_history_map_t; + typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t; focus_history_map_t mFocusHistory; #ifdef _DEBUG @@ -119,3 +119,4 @@ extern LLFocusMgr gFocusMgr; #endif // LL_LLFOCUSMGR_H + diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp index a063ebcd25..f47f166c45 100644 --- a/indra/llui/lliconctrl.cpp +++ b/indra/llui/lliconctrl.cpp @@ -91,8 +91,8 @@ void LLIconCtrl::draw() if( mImagep.notNull() ) { mImagep->draw(0, 0, - mRect.getWidth(), mRect.getHeight(), - mColor ); + getRect().getWidth(), getRect().getHeight(), + mColor ); } LLUICtrl::draw(); diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h index 1e474d0935..6535c0bb0b 100644 --- a/indra/llui/lliconctrl.h +++ b/indra/llui/lliconctrl.h @@ -69,7 +69,7 @@ public: virtual LLXMLNodePtr getXML(bool save_children = true) const; static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); -protected: +private: LLColor4 mColor; LLString mImageName; LLUUID mImageID; diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index 85d8f4b5c2..a81e26f880 100644 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -41,7 +41,7 @@ const U32 KEYWORD_FILE_CURRENT_VERSION = 2; -inline BOOL LLKeywordToken::isHead(const llwchar* s) +inline BOOL LLKeywordToken::isHead(const llwchar* s) const { // strncmp is much faster than string compare BOOL res = TRUE; diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h index d279d2e627..fe36d7cbf6 100644 --- a/indra/llui/llkeywords.h +++ b/indra/llui/llkeywords.h @@ -56,11 +56,12 @@ public: { } - S32 getLength() { return mToken.size(); } - BOOL isHead(const llwchar* s); - const LLColor3& getColor() { return mColor; } - TOKEN_TYPE getType() { return mType; } - const LLWString& getToolTip() { return mToolTip; } + S32 getLength() const { return mToken.size(); } + BOOL isHead(const llwchar* s) const; + const LLWString& getToken() const { return mToken; } + const LLColor3& getColor() const { return mColor; } + TOKEN_TYPE getType() const { return mType; } + const LLWString& getToolTip() const { return mToolTip; } #ifdef _DEBUG void dump(); @@ -68,10 +69,8 @@ public: private: TOKEN_TYPE mType; -public: LLWString mToken; LLColor3 mColor; -private: LLWString mToolTip; }; @@ -82,30 +81,31 @@ public: ~LLKeywords(); BOOL loadFromFile(const LLString& filename); - BOOL isLoaded() { return mLoaded; } + BOOL isLoaded() const { return mLoaded; } void findSegments(std::vector<LLTextSegment *> *seg_list, const LLWString& text, const LLColor4 &defaultColor ); -#ifdef _DEBUG - void dump(); -#endif - // Add the token as described void addToken(LLKeywordToken::TOKEN_TYPE type, const LLString& key, const LLColor3& color, const LLString& tool_tip = LLString::null); + typedef std::map<LLWString, LLKeywordToken*> word_token_map_t; + typedef word_token_map_t::const_iterator keyword_iterator_t; + keyword_iterator_t begin() const { return mWordTokenMap.begin(); } + keyword_iterator_t end() const { return mWordTokenMap.end(); } + +#ifdef _DEBUG + void dump(); +#endif + private: LLColor3 readColor(const LLString& s); void insertSegment(std::vector<LLTextSegment *> *seg_list, LLTextSegment* new_segment, S32 text_len, const LLColor4 &defaultColor); -private: - BOOL mLoaded; -public: - typedef std::map<LLWString, LLKeywordToken*> word_token_map_t; + BOOL mLoaded; word_token_map_t mWordTokenMap; -private: typedef std::deque<LLKeywordToken*> token_list_t; token_list_t mLineTokenList; token_list_t mDelimiterTokenList; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 4297f5fef8..391b28a21f 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -81,44 +81,6 @@ const S32 PREEDIT_STANDOUT_GAP = 1; const S32 PREEDIT_STANDOUT_POSITION = 2; const S32 PREEDIT_STANDOUT_THICKNESS = 2; -// This is a friend class of and is only used by LLLineEditor -class LLLineEditorRollback -{ -public: - LLLineEditorRollback( LLLineEditor* ed ) - : - mCursorPos( ed->mCursorPos ), - mScrollHPos( ed->mScrollHPos ), - mIsSelecting( ed->mIsSelecting ), - mSelectionStart( ed->mSelectionStart ), - mSelectionEnd( ed->mSelectionEnd ) - { - mText = ed->getText(); - } - - void doRollback( LLLineEditor* ed ) - { - ed->mCursorPos = mCursorPos; - ed->mScrollHPos = mScrollHPos; - ed->mIsSelecting = mIsSelecting; - ed->mSelectionStart = mSelectionStart; - ed->mSelectionEnd = mSelectionEnd; - ed->mText = mText; - ed->mPrevText = mText; - } - - LLString getText() { return mText; } - -private: - LLString mText; - S32 mCursorPos; - S32 mScrollHPos; - BOOL mIsSelecting; - S32 mSelectionStart; - S32 mSelectionEnd; -}; - - // // Member functions // @@ -190,7 +152,7 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect, setFocusLostCallback(focus_lost_callback); mMinHPixels = mBorderThickness + UI_LINEEDITOR_H_PAD + mBorderLeft; - mMaxHPixels = mRect.getWidth() - mMinHPixels - mBorderThickness - mBorderRight; + mMaxHPixels = getRect().getWidth() - mMinHPixels - mBorderThickness - mBorderRight; mScrollTimer.reset(); @@ -200,7 +162,7 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect, // Scalable UI somehow made these rectangles off-by-one. // I don't know why. JC - LLRect border_rect(0, mRect.getHeight()-1, mRect.getWidth()-1, 0); + LLRect border_rect(0, getRect().getHeight()-1, getRect().getWidth()-1, 0); mBorder = new LLViewBorder( "line ed border", border_rect, border_bevel, border_style, mBorderThickness ); addChild( mBorder ); mBorder->setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP|FOLLOWS_BOTTOM); @@ -219,17 +181,6 @@ LLLineEditor::~LLLineEditor() } } -//virtual -EWidgetType LLLineEditor::getWidgetType() const -{ - return WIDGET_TYPE_LINE_EDITOR; -} - -//virtual -LLString LLLineEditor::getWidgetTag() const -{ - return LL_LINE_EDITOR_TAG; -} void LLLineEditor::onFocusReceived() { @@ -269,18 +220,6 @@ void LLLineEditor::onCommit() selectAll(); } -// virtual -BOOL LLLineEditor::isDirty() const -{ - return ( mText.getString() != mPrevText ); -} - -// virtual -void LLLineEditor::resetDirty() -{ - mPrevText = mText.getString(); -} - // line history support void LLLineEditor::updateHistory() @@ -306,12 +245,7 @@ void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent) { LLUICtrl::reshape(width, height, called_from_parent ); - mMaxHPixels = mRect.getWidth() - 2 * (mBorderThickness + UI_LINEEDITOR_H_PAD) + 1 - mBorderRight; -} - -void LLLineEditor::setEnableLineHistory( BOOL enabled ) -{ - mHaveHistory = enabled; + mMaxHPixels = getRect().getWidth() - 2 * (mBorderThickness + UI_LINEEDITOR_H_PAD) + 1 - mBorderRight; } void LLLineEditor::setEnabled(BOOL enabled) @@ -330,16 +264,12 @@ void LLLineEditor::setMaxTextLength(S32 max_text_length) void LLLineEditor::setBorderWidth(S32 left, S32 right) { - mBorderLeft = llclamp(left, 0, mRect.getWidth()); - mBorderRight = llclamp(right, 0, mRect.getWidth()); + mBorderLeft = llclamp(left, 0, getRect().getWidth()); + mBorderRight = llclamp(right, 0, getRect().getWidth()); mMinHPixels = mBorderThickness + UI_LINEEDITOR_H_PAD + mBorderLeft; - mMaxHPixels = mRect.getWidth() - mMinHPixels - mBorderThickness - mBorderRight; + mMaxHPixels = getRect().getWidth() - mMinHPixels - mBorderThickness - mBorderRight; } -void LLLineEditor::setLabel(const LLStringExplicit &new_label) -{ - mLabel = new_label; -} void LLLineEditor::setText(const LLStringExplicit &new_text) { @@ -451,12 +381,11 @@ void LLLineEditor::setCursorToEnd() deselect(); } -BOOL LLLineEditor::canDeselect() +BOOL LLLineEditor::canDeselect() const { return hasSelection(); } - void LLLineEditor::deselect() { mSelectionStart = 0; @@ -481,7 +410,7 @@ void LLLineEditor::endSelection() } } -BOOL LLLineEditor::canSelectAll() +BOOL LLLineEditor::canSelectAll() const { return TRUE; } @@ -554,7 +483,7 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask) BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask) { - if (x < mBorderLeft || x > (mRect.getWidth() - mBorderRight)) + if (x < mBorderLeft || x > (getRect().getWidth() - mBorderRight)) { return LLUICtrl::handleMouseDown(x, y, mask); } @@ -634,7 +563,7 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; - if (!hasMouseCapture() && (x < mBorderLeft || x > (mRect.getWidth() - mBorderRight))) + if (!hasMouseCapture() && (x < mBorderLeft || x > (getRect().getWidth() - mBorderRight))) { return LLUICtrl::handleHover(x, y, mask); } @@ -705,7 +634,7 @@ BOOL LLLineEditor::handleMouseUp(S32 x, S32 y, MASK mask) handled = TRUE; } - if (!handled && (x < mBorderLeft || x > (mRect.getWidth() - mBorderRight))) + if (!handled && (x < mBorderLeft || x > (getRect().getWidth() - mBorderRight))) { return LLUICtrl::handleMouseUp(x, y, mask); } @@ -856,11 +785,6 @@ BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) switch( key ) { case KEY_LEFT: - if (mIgnoreArrowKeys) - { - handled = FALSE; - break; - } if( 0 < getCursor() ) { S32 cursorPos = getCursor() - 1; @@ -877,11 +801,6 @@ BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) break; case KEY_RIGHT: - if (mIgnoreArrowKeys) - { - handled = FALSE; - break; - } if( getCursor() < mText.length()) { S32 cursorPos = getCursor() + 1; @@ -899,22 +818,12 @@ BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) case KEY_PAGE_UP: case KEY_HOME: - if (mIgnoreArrowKeys) - { - handled = FALSE; - break; - } extendSelection( 0 ); break; case KEY_PAGE_DOWN: case KEY_END: { - if (mIgnoreArrowKeys) - { - handled = FALSE; - break; - } S32 len = mText.length(); if( len ) { @@ -962,7 +871,7 @@ void LLLineEditor::deleteSelection() } } -BOOL LLLineEditor::canCut() +BOOL LLLineEditor::canCut() const { return !mReadOnly && !mDrawAsterixes && hasSelection(); } @@ -996,7 +905,7 @@ void LLLineEditor::cut() } } -BOOL LLLineEditor::canCopy() +BOOL LLLineEditor::canCopy() const { return !mDrawAsterixes && hasSelection(); } @@ -1013,7 +922,7 @@ void LLLineEditor::copy() } } -BOOL LLLineEditor::canPaste() +BOOL LLLineEditor::canPaste() const { return !mReadOnly && gClipboard.canPasteString(); } @@ -1148,8 +1057,9 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) break; case KEY_LEFT: - if (!mIgnoreArrowKeys - && mask != MASK_ALT) + if (mIgnoreArrowKeys && mask == MASK_NONE) + break; + if ((mask & MASK_ALT) == 0) { if( hasSelection() ) { @@ -1174,8 +1084,9 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) break; case KEY_RIGHT: - if (!mIgnoreArrowKeys - && mask != MASK_ALT) + if (mIgnoreArrowKeys && mask == MASK_NONE) + break; + if ((mask & MASK_ALT) == 0) { if (hasSelection()) { @@ -1428,7 +1339,7 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_pare } -BOOL LLLineEditor::canDoDelete() +BOOL LLLineEditor::canDoDelete() const { return ( !mReadOnly && (!mPassDelete || (hasSelection() || (getCursor() < mText.length()))) ); } @@ -1490,7 +1401,7 @@ void LLLineEditor::draw() } // draw rectangle for the background - LLRect background( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 ); background.stretch( -mBorderThickness ); LLColor4 bg_color = mReadOnlyBgColor; @@ -1521,7 +1432,7 @@ void LLLineEditor::draw() LLColor4 text_color; if (!mReadOnly) { - if (!mTentative) + if (!getTentative()) { text_color = mFgColor; } @@ -1846,7 +1757,7 @@ BOOL LLLineEditor::prevalidateFloat(const LLWString &str) if( 0 < len ) { // May be a comma or period, depending on the locale - char decimal_point = gResMgr->getDecimalPoint(); + llwchar decimal_point = (llwchar)gResMgr->getDecimalPoint(); S32 i = 0; @@ -1895,7 +1806,7 @@ BOOL LLLineEditor::postvalidateFloat(const LLString &str) } // May be a comma or period, depending on the locale - char decimal_point = gResMgr->getDecimalPoint(); + llwchar decimal_point = (llwchar)gResMgr->getDecimalPoint(); for( ; i < len; i++ ) { @@ -2366,18 +2277,6 @@ void LLLineEditor::setColorParameters(LLXMLNodePtr node) } } -void LLLineEditor::setValue(const LLSD& value ) -{ - setText(value.asString()); -} - -LLSD LLLineEditor::getValue() const -{ - LLString str = getText(); - LLSD ret(str); - return ret; -} - BOOL LLLineEditor::setTextArg( const LLString& key, const LLStringExplicit& text ) { mText.setArg(key, text); @@ -2504,7 +2403,7 @@ BOOL LLLineEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect if (control) { LLRect control_rect_screen; - localRectToScreen(mRect, &control_rect_screen); + localRectToScreen(getRect(), &control_rect_screen); LLUI::screenRectToGL(control_rect_screen, control); } @@ -2534,21 +2433,21 @@ BOOL LLLineEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect { S32 query_local = findPixelNearestPos(query - getCursor()); S32 query_screen_x, query_screen_y; - localPointToScreen(query_local, mRect.getHeight() / 2, &query_screen_x, &query_screen_y); + localPointToScreen(query_local, getRect().getHeight() / 2, &query_screen_x, &query_screen_y); LLUI::screenPointToGL(query_screen_x, query_screen_y, &coord->mX, &coord->mY); } if (bounds) { S32 preedit_left_local = findPixelNearestPos(llmax(preedit_left_column, mScrollHPos) - getCursor()); - S32 preedit_right_local = llmin(findPixelNearestPos(preedit_right_column - getCursor()), mRect.getWidth() - mBorderThickness); + S32 preedit_right_local = llmin(findPixelNearestPos(preedit_right_column - getCursor()), getRect().getWidth() - mBorderThickness); if (preedit_left_local > preedit_right_local) { // Is this condition possible? preedit_right_local = preedit_left_local; } - LLRect preedit_rect_local(preedit_left_local, mRect.getHeight(), preedit_right_local, 0); + LLRect preedit_rect_local(preedit_left_local, getRect().getHeight(), preedit_right_local, 0); LLRect preedit_rect_screen; localRectToScreen(preedit_rect_local, &preedit_rect_screen); LLUI::screenRectToGL(preedit_rect_screen, bounds); @@ -2632,7 +2531,7 @@ LLSearchEditor::LLSearchEditor(const LLString& name, LLUICtrl(name, rect, TRUE, NULL, userdata), mSearchCallback(search_callback) { - LLRect search_edit_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect search_edit_rect(0, getRect().getHeight(), getRect().getWidth(), 0); mSearchEdit = new LLLineEditor("search edit", search_edit_rect, LLString::null, @@ -2668,55 +2567,6 @@ LLSearchEditor::LLSearchEditor(const LLString& name, mSearchEdit->setBorderWidth(0, btn_width); } -LLSearchEditor::~LLSearchEditor() -{ -} - -//virtual -EWidgetType LLSearchEditor::getWidgetType() const -{ - return WIDGET_TYPE_SEARCH_EDITOR; -} - -//virtual -LLString LLSearchEditor::getWidgetTag() const -{ - return LL_SEARCH_EDITOR_TAG; -} - -//virtual -void LLSearchEditor::setValue(const LLSD& value ) -{ - mSearchEdit->setValue(value); -} - -//virtual -LLSD LLSearchEditor::getValue() const -{ - return mSearchEdit->getValue(); -} - -//virtual -BOOL LLSearchEditor::setTextArg( const LLString& key, const LLStringExplicit& text ) -{ - return mSearchEdit->setTextArg(key, text); -} - -//virtual -BOOL LLSearchEditor::setLabelArg( const LLString& key, const LLStringExplicit& text ) -{ - return mSearchEdit->setLabelArg(key, text); -} - -//virtual -void LLSearchEditor::clear() -{ - if (mSearchEdit) - { - mSearchEdit->clear(); - } -} - void LLSearchEditor::draw() { @@ -2725,10 +2575,6 @@ void LLSearchEditor::draw() LLUICtrl::draw(); } -void LLSearchEditor::setText(const LLStringExplicit &new_text) -{ - mSearchEdit->setText(new_text); -} //static void LLSearchEditor::onSearchEdit(LLLineEditor* caller, void* user_data ) diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 0739315c4d..6210c37ef3 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -1,6 +1,15 @@ /** * @file lllineeditor.h - * @brief LLLineEditor base class + * @brief Text editor widget to let users enter/edit a single line. + * + * Features: + * Text entry of a single line (text, delete, left and right arrow, insert, return). + * Callbacks either on every keystroke or just on the return key. + * Focus (allow multiple text entry widgets) + * Clipboard (cut, copy, and paste) + * Horizontal scrolling to allow strings longer than widget size allows + * Pre-validation (limit which keys can be used) + * Optional line history so previous entries can be recalled by CTRL UP/DOWN * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -29,19 +38,6 @@ * $/LicenseInfo$ */ -// Text editor widget to let users enter/edit a single line. -// -// -// Features: -// Text entry of a single line (text, delete, left and right arrow, insert, return). -// Callbacks either on every keystroke or just on the return key. -// Focus (allow multiple text entry widgets) -// Clipboard (cut, copy, and paste) -// Horizontal scrolling to allow strings longer than widget size allows -// Pre-validation (limit which keys can be used) -// Optional line history so previous entries can be recalled by CTRL UP/DOWN - - #ifndef LL_LLLINEEDITOR_H #define LL_LLLINEEDITOR_H @@ -61,13 +57,10 @@ class LLButton; typedef BOOL (*LLLinePrevalidateFunc)(const LLWString &wstr); -// -// Classes -// + class LLLineEditor : public LLUICtrl, public LLEditMenuHandler, protected LLPreeditor { - friend class LLLineEditorRollback; public: LLLineEditor(const LLString& name, @@ -85,8 +78,8 @@ public: S32 border_thickness = 1); virtual ~LLLineEditor(); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_LINE_EDITOR; } + virtual LLString getWidgetTag() const { return LL_LINE_EDITOR_TAG; }; virtual LLXMLNodePtr getXML(bool save_children = true) const; void setColorParameters(LLXMLNodePtr node); static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); @@ -102,22 +95,22 @@ public: // LLEditMenuHandler overrides virtual void cut(); - virtual BOOL canCut(); + virtual BOOL canCut() const; virtual void copy(); - virtual BOOL canCopy(); + virtual BOOL canCopy() const; virtual void paste(); - virtual BOOL canPaste(); + virtual BOOL canPaste() const; virtual void doDelete(); - virtual BOOL canDoDelete(); + virtual BOOL canDoDelete() const; virtual void selectAll(); - virtual BOOL canSelectAll(); + virtual BOOL canSelectAll() const; virtual void deselect(); - virtual BOOL canDeselect(); + virtual BOOL canDeselect() const; // view overrides virtual void draw(); @@ -133,16 +126,16 @@ public: virtual void setRect(const LLRect& rect); virtual BOOL acceptsTextInput() const; virtual void onCommit(); - virtual BOOL isDirty() const; // Returns TRUE if the user has changed value at all - virtual void resetDirty(); // Clear dirty state + virtual BOOL isDirty() const { return mText.getString() != mPrevText; } // Returns TRUE if user changed value at all + virtual void resetDirty() { mPrevText = mText.getString(); } // Clear dirty state // assumes UTF8 text - virtual void setValue(const LLSD& value ); - virtual LLSD getValue() const; + virtual void setValue(const LLSD& value ) { setText(value.asString()); } + virtual LLSD getValue() const { return LLSD(getText()); } virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ); virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); - void setLabel(const LLStringExplicit &new_label); + void setLabel(const LLStringExplicit &new_label) { mLabel = new_label; } void setText(const LLStringExplicit &new_text); const LLString& getText() const { return mText.getString(); } @@ -179,7 +172,6 @@ public: void setIgnoreArrowKeys(BOOL b) { mIgnoreArrowKeys = b; } void setIgnoreTab(BOOL b) { mIgnoreTab = b; } void setPassDelete(BOOL b) { mPassDelete = b; } - void setDrawAsterixes(BOOL b); // get the cursor position of the beginning/end of the prev/next word in the text @@ -216,23 +208,24 @@ public: static BOOL postvalidateFloat(const LLString &str); // line history support: - void setEnableLineHistory( BOOL enabled ); // switches line history on or off + void setEnableLineHistory( BOOL enabled ) { mHaveHistory = enabled; } // switches line history on or off void updateHistory(); // stores current line in history -protected: +private: + // private helper classes void removeChar(); void addChar(const llwchar c); void setCursorAtLocalPos(S32 local_mouse_x); - S32 findPixelNearestPos(S32 cursor_offset = 0) const; void reportBadKeystroke(); - BOOL handleSpecialKey(KEY key, MASK mask); BOOL handleSelectionKey(KEY key, MASK mask); BOOL handleControlKey(KEY key, MASK mask); S32 handleCommitKey(KEY key, MASK mask); -protected: + // + // private data members + // void updateAllowingLanguageInput(); BOOL hasPreeditString() const; // Implementation (overrides) of LLPreeditor @@ -308,13 +301,53 @@ protected: LLWString mPreeditOverwrittenWString; std::vector<S32> mPreeditPositions; LLPreeditor::standouts_t mPreeditStandouts; -}; - + // private helper class + class LLLineEditorRollback + { + public: + LLLineEditorRollback( LLLineEditor* ed ) + : + mCursorPos( ed->mCursorPos ), + mScrollHPos( ed->mScrollHPos ), + mIsSelecting( ed->mIsSelecting ), + mSelectionStart( ed->mSelectionStart ), + mSelectionEnd( ed->mSelectionEnd ) + { + mText = ed->getText(); + } + + void doRollback( LLLineEditor* ed ) + { + ed->mCursorPos = mCursorPos; + ed->mScrollHPos = mScrollHPos; + ed->mIsSelecting = mIsSelecting; + ed->mSelectionStart = mSelectionStart; + ed->mSelectionEnd = mSelectionEnd; + ed->mText = mText; + ed->mPrevText = mText; + } + + LLString getText() { return mText; } + + private: + LLString mText; + S32 mCursorPos; + S32 mScrollHPos; + BOOL mIsSelecting; + S32 mSelectionStart; + S32 mSelectionEnd; + }; // end class LLLineEditorRollback + +}; // end class LLLineEditor + + + +/* + * @brief A line editor with a button to clear it and a callback to call on every edit event. + */ class LLSearchEditor : public LLUICtrl { -friend class LLLineEditorRollback; - public: LLSearchEditor(const LLString& name, const LLRect& rect, @@ -322,34 +355,34 @@ public: void (*search_callback)(const LLString& search_string, void* user_data), void* userdata); - virtual ~LLSearchEditor(); + virtual ~LLSearchEditor() {} /*virtual*/ void draw(); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SEARCH_EDITOR; } + virtual LLString getWidgetTag() const { return LL_SEARCH_EDITOR_TAG; } static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - void setText(const LLStringExplicit &new_text); + void setText(const LLStringExplicit &new_text) { mSearchEdit->setText(new_text); } void setSearchCallback(void (*search_callback)(const LLString& search_string, void* user_data), void* data) { mSearchCallback = search_callback; mCallbackUserData = data; } // LLUICtrl interface - virtual void setValue(const LLSD& value ); - virtual LLSD getValue() const; - virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ); - virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); - virtual void clear(); + virtual void setValue(const LLSD& value ) { mSearchEdit->setValue(value); } + virtual LLSD getValue() const { return mSearchEdit->getValue(); } + virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ) { return mSearchEdit->setTextArg( key, text); } + virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ) { return mSearchEdit->setLabelArg(key, text); } + virtual void clear() { if (mSearchEdit) mSearchEdit->clear(); } -protected: - LLLineEditor* mSearchEdit; - LLButton* mClearSearchButton; +private: + static void onSearchEdit(LLLineEditor* caller, void* user_data ); + static void onClearSearch(void* user_data); + LLLineEditor* mSearchEdit; + class LLButton* mClearSearchButton; void (*mSearchCallback)(const LLString& search_string, void* user_data); - static void onSearchEdit(LLLineEditor* caller, void* user_data ); - static void onClearSearch(void* user_data); }; #endif // LL_LINEEDITOR_ diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 19a5085a25..4e94aff7a5 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -112,12 +112,11 @@ LLColor4 LLMenuItemGL::sEnabledColor( 0.0f, 0.0f, 0.0f, 1.0f ); LLColor4 LLMenuItemGL::sDisabledColor( 0.5f, 0.5f, 0.5f, 1.0f ); LLColor4 LLMenuItemGL::sHighlightBackground( 0.0f, 0.0f, 0.7f, 1.0f ); LLColor4 LLMenuItemGL::sHighlightForeground( 1.0f, 1.0f, 1.0f, 1.0f ); -BOOL LLMenuItemGL::sDropShadowText = TRUE; LLColor4 LLMenuGL::sDefaultBackgroundColor( 0.25f, 0.25f, 0.25f, 0.75f ); BOOL LLMenuGL::sKeyboardMode = FALSE; -LLViewHandle LLMenuHolderGL::sItemLastSelectedHandle; +LLHandle<LLView> LLMenuHolderGL::sItemLastSelectedHandle; LLFrameTimer LLMenuHolderGL::sItemActivationTimer; //LLColor4 LLMenuGL::sBackgroundColor( 0.8f, 0.8f, 0.0f, 1.0f ); @@ -199,7 +198,7 @@ BOOL LLMenuItemGL::handleKey(KEY key, MASK mask, BOOL called_from_parent) if( called_from_parent ) { // Downward traversal - if (mEnabled) + if (getEnabled()) { handled = childrenHandleKey( key, mask ) != NULL; } @@ -215,7 +214,7 @@ BOOL LLMenuItemGL::handleKey(KEY key, MASK mask, BOOL called_from_parent) BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask) { - if( mEnabled && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) + if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) { doIt(); return TRUE; @@ -225,15 +224,10 @@ BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask) BOOL LLMenuItemGL::handleHover(S32 x, S32 y, MASK mask) { - mGotHover = TRUE; + setHover(TRUE); getWindow()->setCursor(UI_CURSOR_ARROW); return TRUE; } - -void LLMenuItemGL::setBriefItem(BOOL b) -{ - mBriefItem = b; -} // This function checks to see if the accelerator key is already in use; // if not, it will be added to the list @@ -282,7 +276,7 @@ BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp) // This function appends the character string representation of // the current accelerator key and mask to the provided string. -void LLMenuItemGL::appendAcceleratorString( LLString& st ) +void LLMenuItemGL::appendAcceleratorString( LLString& st ) const { // break early if this is a silly thing to do. if( KEY_NONE == mAcceleratorKey ) @@ -332,52 +326,14 @@ void LLMenuItemGL::setJumpKey(KEY key) mJumpKey = LLStringOps::toUpper((char)key); } -KEY LLMenuItemGL::getJumpKey() -{ - return mJumpKey; -} - - -// set the font used by all of the menu objects -void LLMenuItemGL::setFont(LLFontGL* font) -{ - mFont = font; -} - -// returns the height in pixels for the current font. -U32 LLMenuItemGL::getNominalHeight( void ) -{ - return llround(mFont->getLineHeight()) + MENU_ITEM_PADDING; -} - -// functions to control the color scheme -void LLMenuItemGL::setEnabledColor( const LLColor4& color ) -{ - sEnabledColor = color; -} - -void LLMenuItemGL::setDisabledColor( const LLColor4& color ) -{ - sDisabledColor = color; -} - -void LLMenuItemGL::setHighlightBGColor( const LLColor4& color ) -{ - sHighlightBackground = color; -} -void LLMenuItemGL::setHighlightFGColor( const LLColor4& color ) -{ - sHighlightForeground = color; +// virtual +U32 LLMenuItemGL::getNominalHeight( void ) const +{ + return llround(mFont->getLineHeight()) + MENU_ITEM_PADDING; } -// change the label -void LLMenuItemGL::setLabel( const LLStringExplicit& label ) -{ - mLabel = label; -} - // Get the parent menu for this item LLMenuGL* LLMenuItemGL::getMenu() { @@ -388,7 +344,7 @@ LLMenuGL* LLMenuItemGL::getMenu() // getNominalWidth() - returns the normal width of this control in // pixels - this is used for calculating the widest item, as well as // for horizontal arrangement. -U32 LLMenuItemGL::getNominalWidth( void ) +U32 LLMenuItemGL::getNominalWidth( void ) const { U32 width; @@ -442,17 +398,6 @@ void LLMenuItemGL::doIt( void ) mHighlight = highlight; } -// determine if this object represents an active sub-menu -BOOL LLMenuItemGL::isActive( void ) const -{ - return FALSE; -} - -// determine if this object represents an open sub-menu -BOOL LLMenuItemGL::isOpen( void ) const -{ - return FALSE; -} BOOL LLMenuItemGL::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) { @@ -490,7 +435,7 @@ BOOL LLMenuItemGL::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) BOOL LLMenuItemGL::handleMouseUp( S32 x, S32 y, MASK ) { - if (mEnabled) + if (getEnabled()) { // switch to mouse navigation mode LLMenuGL::setKeyboardMode(FALSE); @@ -504,7 +449,7 @@ BOOL LLMenuItemGL::handleMouseUp( S32 x, S32 y, MASK ) BOOL LLMenuItemGL::handleMouseDown( S32 x, S32 y, MASK ) { - if (mEnabled) + if (getEnabled()) { // switch to mouse navigation mode LLMenuGL::setKeyboardMode(FALSE); @@ -512,10 +457,7 @@ BOOL LLMenuItemGL::handleMouseDown( S32 x, S32 y, MASK ) setHighlight(TRUE); return TRUE; } - else - { - return FALSE; - } + return FALSE; } @@ -529,13 +471,13 @@ void LLMenuItemGL::draw( void ) if( getEnabled() && getHighlight() && !mBriefItem) { glColor4fv( sHighlightBackground.mV ); - gl_rect_2d( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 ); } LLColor4 color; U8 font_style = mStyle; - if (LLMenuItemGL::sDropShadowText && getEnabled() && !mDrawTextDisabled ) + if (getEnabled() && !mDrawTextDisabled ) { font_style |= LLFontGL::DROP_SHADOW_SOFT; } @@ -570,12 +512,12 @@ void LLMenuItemGL::draw( void ) LLFontGL::LEFT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL, FALSE ); if( !mDrawAccelLabel.empty() ) { - mFont->render( mDrawAccelLabel.getWString(), 0, (F32)mRect.mRight - (F32)RIGHT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color, + mFont->render( mDrawAccelLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color, LLFontGL::RIGHT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL, FALSE ); } if( !mDrawBranchLabel.empty() ) { - mFont->render( mDrawBranchLabel.getWString(), 0, (F32)mRect.mRight - (F32)RIGHT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color, + mFont->render( mDrawBranchLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color, LLFontGL::RIGHT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL, FALSE ); } } @@ -595,7 +537,7 @@ void LLMenuItemGL::draw( void ) } // clear got hover every frame - mGotHover = FALSE; + setHover(FALSE); } BOOL LLMenuItemGL::setLabelArg( const LLString& key, const LLStringExplicit& text ) @@ -628,7 +570,7 @@ public: virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); - virtual U32 getNominalHeight( void ) { return SEPARATOR_HEIGHT_PIXELS; } + virtual U32 getNominalHeight( void ) const { return SEPARATOR_HEIGHT_PIXELS; } }; LLMenuItemSeparatorGL::LLMenuItemSeparatorGL( const LLString &name ) : @@ -638,42 +580,42 @@ LLMenuItemSeparatorGL::LLMenuItemSeparatorGL( const LLString &name ) : void LLMenuItemSeparatorGL::draw( void ) { - glColor4fv( sDisabledColor.mV ); - const S32 y = mRect.getHeight() / 2; + glColor4fv( getDisabledColor().mV ); + const S32 y = getRect().getHeight() / 2; const S32 PAD = 6; - gl_line_2d( PAD, y, mRect.getWidth() - PAD, y ); + gl_line_2d( PAD, y, getRect().getWidth() - PAD, y ); } BOOL LLMenuItemSeparatorGL::handleMouseDown(S32 x, S32 y, MASK mask) { LLMenuGL* parent_menu = getMenu(); - if (y > mRect.getHeight() / 2) + if (y > getRect().getHeight() / 2) { - return parent_menu->handleMouseDown(x + mRect.mLeft, mRect.mTop + 1, mask); + return parent_menu->handleMouseDown(x + getRect().mLeft, getRect().mTop + 1, mask); } else { - return parent_menu->handleMouseDown(x + mRect.mLeft, mRect.mBottom - 1, mask); + return parent_menu->handleMouseDown(x + getRect().mLeft, getRect().mBottom - 1, mask); } } BOOL LLMenuItemSeparatorGL::handleMouseUp(S32 x, S32 y, MASK mask) { LLMenuGL* parent_menu = getMenu(); - if (y > mRect.getHeight() / 2) + if (y > getRect().getHeight() / 2) { - return parent_menu->handleMouseUp(x + mRect.mLeft, mRect.mTop + 1, mask); + return parent_menu->handleMouseUp(x + getRect().mLeft, getRect().mTop + 1, mask); } else { - return parent_menu->handleMouseUp(x + mRect.mLeft, mRect.mBottom - 1, mask); + return parent_menu->handleMouseUp(x + getRect().mLeft, getRect().mBottom - 1, mask); } } BOOL LLMenuItemSeparatorGL::handleHover(S32 x, S32 y, MASK mask) { LLMenuGL* parent_menu = getMenu(); - if (y > mRect.getHeight() / 2) + if (y > getRect().getHeight() / 2) { parent_menu->highlightPrevItem(this, FALSE); return FALSE; @@ -711,24 +653,13 @@ LLMenuItemVerticalSeparatorGL::LLMenuItemVerticalSeparatorGL( void ) //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuItemTearOffGL -// -// This class represents a separator. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LLMenuItemTearOffGL::LLMenuItemTearOffGL(LLViewHandle parent_floater_handle) : +LLMenuItemTearOffGL::LLMenuItemTearOffGL(LLHandle<LLFloater> parent_floater_handle) : LLMenuItemGL("tear off", TEAROFF_SEPARATOR_LABEL), mParentHandle(parent_floater_handle) { } -EWidgetType LLMenuItemTearOffGL::getWidgetType() const -{ - return WIDGET_TYPE_TEAROFF_MENU; -} - -LLString LLMenuItemTearOffGL::getWidgetTag() const -{ - return LL_MENU_ITEM_TEAR_OFF_GL_TAG; -} void LLMenuItemTearOffGL::doIt() { @@ -747,7 +678,7 @@ void LLMenuItemTearOffGL::doIt() getMenu()->arrange(); - LLFloater* parent_floater = LLFloater::getFloaterByHandle(mParentHandle); + LLFloater* parent_floater = mParentHandle.get(); LLFloater* tear_off_menu = LLTearOffMenu::create(getMenu()); if (tear_off_menu) @@ -768,27 +699,31 @@ void LLMenuItemTearOffGL::doIt() void LLMenuItemTearOffGL::draw() { // disabled items can be highlighted, but shouldn't render as such - if( getEnabled() && getHighlight() && !mBriefItem) + if( getEnabled() && getHighlight() && !isBriefItem()) { - glColor4fv( sHighlightBackground.mV ); - gl_rect_2d( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + glColor4fv( getHighlightBGColor().mV ); + gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 ); } - if (mEnabled) + if (getEnabled()) { - glColor4fv( sEnabledColor.mV ); + glColor4fv( getEnabledColor().mV ); } else { - glColor4fv( sDisabledColor.mV ); + glColor4fv( getDisabledColor().mV ); } - const S32 y = mRect.getHeight() / 3; + const S32 y = getRect().getHeight() / 3; const S32 PAD = 6; - gl_line_2d( PAD, y, mRect.getWidth() - PAD, y ); - gl_line_2d( PAD, y * 2, mRect.getWidth() - PAD, y * 2 ); + gl_line_2d( PAD, y, getRect().getWidth() - PAD, y ); + gl_line_2d( PAD, y * 2, getRect().getWidth() - PAD, y * 2 ); +} + +U32 LLMenuItemTearOffGL::getNominalHeight( void ) const +{ + return TEAROFF_SEPARATOR_HEIGHT_PIXELS; } -U32 LLMenuItemTearOffGL::getNominalHeight( void ) { return TEAROFF_SEPARATOR_HEIGHT_PIXELS; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuItemBlankGL @@ -799,22 +734,16 @@ U32 LLMenuItemTearOffGL::getNominalHeight( void ) { return TEAROFF_SEPARATOR_HEI class LLMenuItemBlankGL : public LLMenuItemGL { public: - LLMenuItemBlankGL( void ); - + LLMenuItemBlankGL( void ) : LLMenuItemGL( "", "" ) + { + setEnabled(FALSE); + } virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_BLANK; } virtual LLString getWidgetTag() const { return LL_MENU_ITEM_BLANK_GL_TAG; } - - // doIt() - do the primary funcationality of the menu item. virtual void doIt( void ) {} - virtual void draw( void ) {} }; -LLMenuItemBlankGL::LLMenuItemBlankGL( void ) -: LLMenuItemGL( "", "" ) -{ - mEnabled = FALSE; -} ///============================================================================ /// Class LLMenuItemCallGL @@ -905,7 +834,7 @@ void LLMenuItemCallGL::setEnabledControl(LLString enabled_control, LLView *conte } else { - context->addBoolControl(enabled_control, mEnabled); + context->addBoolControl(enabled_control, getEnabled()); control = context->findControl(enabled_control); control->registerListener(this, "ENABLED"); } @@ -925,7 +854,7 @@ void LLMenuItemCallGL::setVisibleControl(LLString enabled_control, LLView *conte } else { - context->addBoolControl(enabled_control, mEnabled); + context->addBoolControl(enabled_control, getEnabled()); control = context->findControl(enabled_control); control->registerListener(this, "VISIBLE"); } @@ -989,16 +918,6 @@ void LLMenuItemCallGL::doIt( void ) LLMenuItemGL::doIt(); } -EWidgetType LLMenuItemCallGL::getWidgetType() const -{ - return WIDGET_TYPE_MENU_ITEM_CALL; -} - -LLString LLMenuItemCallGL::getWidgetTag() const -{ - return LL_MENU_ITEM_CALL_GL_TAG; -} - void LLMenuItemCallGL::buildDrawLabel( void ) { LLPointer<LLEvent> fired_event = new LLEvent(this); @@ -1018,7 +937,7 @@ void LLMenuItemCallGL::buildDrawLabel( void ) BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask ) { - if( (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) + if( (!gKeyboard->getKeyRepeated(key) || getAllowKeyRepeat()) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) { LLPointer<LLEvent> fired_event = new LLEvent(this); fireEvent(fired_event, "on_build"); @@ -1026,7 +945,7 @@ BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask ) { setEnabled( mEnabledCallback( mUserData ) ); } - if( !mEnabled ) + if( !getEnabled() ) { if( mOnDisabledCallback ) { @@ -1127,20 +1046,10 @@ LLXMLNodePtr LLMenuItemCheckGL::getXML(bool save_children) const return node; } -EWidgetType LLMenuItemCheckGL::getWidgetType() const -{ - return WIDGET_TYPE_MENU_ITEM_CHECK; -} - -LLString LLMenuItemCheckGL::getWidgetTag() const -{ - return LL_MENU_ITEM_CHECK_GL_TAG; -} - // called to rebuild the draw label void LLMenuItemCheckGL::buildDrawLabel( void ) { - if(mChecked || (mCheckCallback && mCheckCallback( mUserData ) ) ) + if(mChecked || (mCheckCallback && mCheckCallback( getUserData() ) ) ) { mDrawBoolLabel = BOOLEAN_TRUE_PREFIX; } @@ -1216,23 +1125,13 @@ LLView* LLMenuItemBranchGL::getChildByName(const LLString& name, BOOL recurse) c return mBranch; } // Always recurse on branches - return mBranch->getChildByName(name, recurse); -} - -EWidgetType LLMenuItemBranchGL::getWidgetType() const -{ - return WIDGET_TYPE_MENU_ITEM_BRANCH; -} - -LLString LLMenuItemBranchGL::getWidgetTag() const -{ - return LL_MENU_ITEM_BRANCH_GL_TAG; + return mBranch->getChild<LLView>(name, recurse); } // virtual BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask) { - if (mEnabled) + if (getEnabled()) { // switch to mouse navigation mode LLMenuGL::setKeyboardMode(FALSE); @@ -1335,18 +1234,11 @@ BOOL LLMenuItemBranchGL::handleUnicodeChar(llwchar uni_char, BOOL called_from_pa } -// set the hover status (called by it's menu) void LLMenuItemBranchGL::setHighlight( BOOL highlight ) { if (highlight == getHighlight()) return; - // make sure only yourself is highlighted - if (highlight) - { - getMenu()->clearHoverItem(); - } - - BOOL auto_open = mEnabled && (!mBranch->getVisible() || mBranch->getTornOff()); + BOOL auto_open = getEnabled() && (!mBranch->getVisible() || mBranch->getTornOff()); // torn off menus don't open sub menus on hover unless they have focus if (getMenu()->getTornOff() && !((LLFloater*)getMenu()->getParent())->hasFocus()) { @@ -1357,8 +1249,7 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight ) { auto_open = FALSE; } - - mHighlight = highlight; + LLMenuItemGL::setHighlight(highlight); if( highlight ) { if(auto_open) @@ -1380,11 +1271,6 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight ) } } -void LLMenuItemBranchGL::setEnabledSubMenus(BOOL enabled) -{ - mBranch->setEnabledSubMenus(enabled); -} - void LLMenuItemBranchGL::draw() { LLMenuItemGL::draw(); @@ -1394,18 +1280,6 @@ void LLMenuItemBranchGL::draw() } } -// determine if this object is active -// which, for branching menus, means the branch is open and has "focus" -BOOL LLMenuItemBranchGL::isActive( void ) const -{ - return isOpen() && mBranch->getHighlightedItem(); -} - -BOOL LLMenuItemBranchGL::isOpen( void ) const -{ - return mBranch->isOpen(); -} - void LLMenuItemBranchGL::updateBranchParent(LLView* parentp) { if (mBranch->getParent() == NULL) @@ -1478,8 +1352,8 @@ void LLMenuItemBranchGL::openMenu() LLRect rect = mBranch->getRect(); // calculate root-view relative position for branch menu - S32 left = mRect.mRight; - S32 top = mRect.mTop - mRect.mBottom; + S32 left = getRect().mRight; + S32 top = getRect().mTop - getRect().mBottom; localPointToOtherView(left, top, &left, &top, mBranch->getParent()); @@ -1505,7 +1379,7 @@ void LLMenuItemBranchGL::openMenu() if( x - menu_region_rect.mLeft > menu_region_width - rect.getWidth() ) { // move sub-menu over to left side - delta_x = llmax(-x, (-1 * (rect.getWidth() + mRect.getWidth()))); + delta_x = llmax(-x, (-1 * (rect.getWidth() + getRect().getWidth()))); } mBranch->translate( delta_x, delta_y ); mBranch->setVisible( TRUE ); @@ -1536,7 +1410,7 @@ public: // returns the normal width of this control in pixels - this is // used for calculating the widest item, as well as for horizontal // arrangement. - virtual U32 getNominalWidth( void ); + virtual U32 getNominalWidth( void ) const; // called to rebuild the draw label virtual void buildDrawLabel( void ); @@ -1570,10 +1444,10 @@ LLMenuItemBranchDownGL::LLMenuItemBranchDownGL( const LLString& name, // returns the normal width of this control in pixels - this is used // for calculating the widest item, as well as for horizontal // arrangement. -U32 LLMenuItemBranchDownGL::getNominalWidth( void ) +U32 LLMenuItemBranchDownGL::getNominalWidth( void ) const { U32 width = LEFT_PAD_PIXELS + LEFT_WIDTH_PIXELS + RIGHT_PAD_PIXELS; - width += mFont->getWidth( mLabel.getWString().c_str() ); + width += getFont()->getWidth( mLabel.getWString().c_str() ); return width; } @@ -1588,32 +1462,33 @@ void LLMenuItemBranchDownGL::buildDrawLabel( void ) void LLMenuItemBranchDownGL::openMenu( void ) { - if( mBranch->getVisible() && !mBranch->getTornOff() ) + LLMenuGL* branch = getBranch(); + if( branch->getVisible() && !branch->getTornOff() ) { - mBranch->setVisible( FALSE ); + branch->setVisible( FALSE ); } else { - if (mBranch->getTornOff()) + if (branch->getTornOff()) { - gFloaterView->bringToFront((LLFloater*)mBranch->getParent()); + gFloaterView->bringToFront((LLFloater*)branch->getParent()); } else { // We're showing the drop-down menu, so patch up its labels/rects - mBranch->arrange(); + branch->arrange(); - LLRect rect = mBranch->getRect(); + LLRect rect = branch->getRect(); S32 left = 0; - S32 top = mRect.mBottom; - localPointToOtherView(left, top, &left, &top, mBranch->getParent()); + S32 top = getRect().mBottom; + localPointToOtherView(left, top, &left, &top, branch->getParent()); rect.setLeftTopAndSize( left, top, rect.getWidth(), rect.getHeight() ); - mBranch->setRect( rect ); + branch->setRect( rect ); S32 x = 0; S32 y = 0; - mBranch->localPointToScreen( 0, 0, &x, &y ); + branch->localPointToScreen( 0, 0, &x, &y ); S32 delta_x = 0; LLCoordScreen window_size; @@ -1625,13 +1500,11 @@ void LLMenuItemBranchDownGL::openMenu( void ) { delta_x = (window_width - rect.getWidth()) - x; } - mBranch->translate( delta_x, 0 ); + branch->translate( delta_x, 0 ); setHighlight(TRUE); - mBranch->setVisible( TRUE ); + branch->setVisible( TRUE ); } - - } } @@ -1640,21 +1513,18 @@ void LLMenuItemBranchDownGL::setHighlight( BOOL highlight ) { if (highlight == getHighlight()) return; - if (highlight) - { - getMenu()->clearHoverItem(); - } - mHighlight = highlight; + //NOTE: Purposely calling all the way to the base to bypass auto-open. + LLMenuItemGL::setHighlight(highlight); if( !highlight) { - if (mBranch->getTornOff()) + if (getBranch()->getTornOff()) { - ((LLFloater*)mBranch->getParent())->setFocus(FALSE); - mBranch->clearHoverItem(); + ((LLFloater*)getBranch()->getParent())->setFocus(FALSE); + getBranch()->clearHoverItem(); } else { - mBranch->setVisible( FALSE ); + getBranch()->setVisible( FALSE ); } } } @@ -1684,8 +1554,8 @@ BOOL LLMenuItemBranchDownGL::handleMouseUp( S32 x, S32 y, MASK mask ) BOOL LLMenuItemBranchDownGL::handleAcceleratorKey(KEY key, MASK mask) { - BOOL branch_visible = mBranch->getVisible(); - BOOL handled = mBranch->handleAcceleratorKey(key, mask); + BOOL branch_visible = getBranch()->getVisible(); + BOOL handled = getBranch()->handleAcceleratorKey(key, mask); if (handled && !branch_visible && getVisible()) { // flash this menu entry because we triggered an invisible menu item @@ -1697,7 +1567,7 @@ BOOL LLMenuItemBranchDownGL::handleAcceleratorKey(KEY key, MASK mask) BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) { - BOOL menu_open = mBranch->getVisible(); + BOOL menu_open = getBranch()->getVisible(); // don't do keyboard navigation of top-level menus unless in keyboard mode, or menu expanded if (getHighlight() && getMenu()->getVisible() && (isActive() || LLMenuGL::getKeyboardMode())) { @@ -1738,7 +1608,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_ { doIt(); } - mBranch->highlightNextItem(NULL); + getBranch()->highlightNextItem(NULL); return TRUE; } else if (key == KEY_UP) @@ -1750,7 +1620,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_ { doIt(); } - mBranch->highlightPrevItem(NULL); + getBranch()->highlightPrevItem(NULL); return TRUE; } } @@ -1761,19 +1631,19 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_ void LLMenuItemBranchDownGL::draw( void ) { //FIXME: try removing this - if (mBranch->getVisible() && !mBranch->getTornOff()) + if (getBranch()->getVisible() && !getBranch()->getTornOff()) { setHighlight(TRUE); } if( getHighlight() ) { - glColor4fv( sHighlightBackground.mV ); - gl_rect_2d( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + glColor4fv( getHighlightBGColor().mV ); + gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 ); } - U8 font_style = mStyle; - if (LLMenuItemGL::sDropShadowText && getEnabled() && !mDrawTextDisabled ) + U8 font_style = getFontStyle(); + if (getEnabled() && !getDrawTextDisabled() ) { font_style |= LLFontGL::DROP_SHADOW_SOFT; } @@ -1781,17 +1651,17 @@ void LLMenuItemBranchDownGL::draw( void ) LLColor4 color; if (getHighlight()) { - color = sHighlightForeground; + color = getHighlightFGColor(); } - else if( mEnabled ) + else if( getEnabled() ) { - color = sEnabledColor; + color = getEnabledColor(); } else { - color = sDisabledColor; + color = getDisabledColor(); } - mFont->render( mLabel.getWString(), 0, (F32)mRect.getWidth() / 2.f, (F32)LABEL_BOTTOM_PAD_PIXELS, color, + getFont()->render( mLabel.getWString(), 0, (F32)getRect().getWidth() / 2.f, (F32)LABEL_BOTTOM_PAD_PIXELS, color, LLFontGL::HCENTER, LLFontGL::BOTTOM, font_style ); @@ -1800,19 +1670,19 @@ void LLMenuItemBranchDownGL::draw( void ) { LLString upper_case_label = mLabel.getString(); LLString::toUpper(upper_case_label); - std::string::size_type offset = upper_case_label.find(mJumpKey); + std::string::size_type offset = upper_case_label.find(getJumpKey()); if (offset != std::string::npos) { - S32 x_offset = llround((F32)mRect.getWidth() / 2.f - mFont->getWidthF32(mLabel.getString(), 0, S32_MAX) / 2.f); - S32 x_begin = x_offset + mFont->getWidth(mLabel, 0, offset); - S32 x_end = x_offset + mFont->getWidth(mLabel, 0, offset + 1); + S32 x_offset = llround((F32)getRect().getWidth() / 2.f - getFont()->getWidthF32(mLabel.getString(), 0, S32_MAX) / 2.f); + S32 x_begin = x_offset + getFont()->getWidth(mLabel, 0, offset); + S32 x_end = x_offset + getFont()->getWidth(mLabel, 0, offset + 1); gl_line_2d(x_begin, LABEL_BOTTOM_PAD_PIXELS, x_end, LABEL_BOTTOM_PAD_PIXELS); } } // reset every frame so that we only show highlight // when we get hover events on that frame - mGotHover = FALSE; + setHover(FALSE); } ///============================================================================ @@ -1820,7 +1690,7 @@ void LLMenuItemBranchDownGL::draw( void ) ///============================================================================ // Default constructor -LLMenuGL::LLMenuGL( const LLString& name, const LLString& label, LLViewHandle parent_floater_handle ) +LLMenuGL::LLMenuGL( const LLString& name, const LLString& label, LLHandle<LLFloater> parent_floater_handle ) : LLUICtrl( name, LLRect(), FALSE, NULL, NULL ), mBackgroundColor( sDefaultBackgroundColor ), mBgVisible( TRUE ), @@ -1845,7 +1715,7 @@ LLMenuGL::LLMenuGL( const LLString& name, const LLString& label, LLViewHandle pa setTabStop(FALSE); } -LLMenuGL::LLMenuGL( const LLString& label, LLViewHandle parent_floater_handle ) +LLMenuGL::LLMenuGL( const LLString& label, LLHandle<LLFloater> parent_floater_handle ) : LLUICtrl( label, LLRect(), FALSE, NULL, NULL ), mBackgroundColor( sDefaultBackgroundColor ), mBgVisible( TRUE ), @@ -1879,7 +1749,7 @@ LLMenuGL::~LLMenuGL( void ) mJumpKeys.clear(); } -void LLMenuGL::setCanTearOff(BOOL tear_off, LLViewHandle parent_floater_handle ) +void LLMenuGL::setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_handle ) { if (tear_off && mTearOffItem == NULL) { @@ -2317,29 +2187,13 @@ LLView* LLMenuGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa return menu; } -// control the color scheme -void LLMenuGL::setDefaultBackgroundColor( const LLColor4& color ) -{ - sDefaultBackgroundColor = color; -} - -void LLMenuGL::setBackgroundColor( const LLColor4& color ) -{ - mBackgroundColor = color; -} - -LLColor4 LLMenuGL::getBackgroundColor() -{ - return mBackgroundColor; -} - // rearrange the child rects so they fit the shape of the menu. void LLMenuGL::arrange( void ) { // calculate the height & width, and set our rect based on that // information. - LLRect initial_rect = mRect; + const LLRect& initial_rect = getRect(); U32 width = 0, height = MENU_ITEM_PADDING; @@ -2349,8 +2203,9 @@ void LLMenuGL::arrange( void ) { const LLRect menu_region_rect = LLMenuGL::sMenuContainer ? LLMenuGL::sMenuContainer->getMenuRect() : LLRect(0, S32_MAX, S32_MAX, 0); - U32 max_width = menu_region_rect.getWidth(); - U32 max_height = menu_region_rect.getHeight(); + // torn off menus are not constrained to the size of the screen + U32 max_width = getTornOff() ? U32_MAX : menu_region_rect.getWidth(); + U32 max_height = getTornOff() ? U32_MAX : menu_region_rect.getHeight(); // *FIX: create the item first and then ask for its dimensions? S32 spillover_item_width = PLAIN_PAD_PIXELS + LLFontGL::sSansSerif->getWidth( "More" ); S32 spillover_item_height = llround(LLFontGL::sSansSerif->getLineHeight()) + MENU_ITEM_PADDING; @@ -2429,8 +2284,7 @@ void LLMenuGL::arrange( void ) } } - mRect.mRight = mRect.mLeft + width; - mRect.mTop = mRect.mBottom + height; + setRect(LLRect(getRect().mLeft, getRect().mBottom + height, getRect().mLeft + width, getRect().mBottom)); S32 cur_height = (S32)llmin(max_height, height); S32 cur_width = 0; @@ -2622,8 +2476,7 @@ void LLMenuGL::empty( void ) // Adjust rectangle of the menu void LLMenuGL::setLeftAndBottom(S32 left, S32 bottom) { - mRect.mLeft = left; - mRect.mBottom = bottom; + setRect(LLRect(left, getRect().mTop, getRect().mRight, bottom)); arrange(); } @@ -2953,7 +2806,7 @@ BOOL LLMenuGL::handleKey( KEY key, MASK mask, BOOL called_from_parent ) BOOL handled = FALSE; // Pass down even if not visible - if( mEnabled && called_from_parent ) + if( getEnabled() && called_from_parent ) { for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) { @@ -2981,7 +2834,7 @@ BOOL LLMenuGL::handleKey( KEY key, MASK mask, BOOL called_from_parent ) BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask) { // don't handle if not enabled - if(!mEnabled) + if(!getEnabled()) { return FALSE; } @@ -3080,7 +2933,7 @@ void LLMenuGL::draw( void ) { if (mDropShadowed && !mTornOff) { - gl_drop_shadow(0, mRect.getHeight(), mRect.getWidth(), 0, + gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, LLUI::sColorsGroup->getColor("ColorDropShadow"), LLUI::sConfigGroup->getS32("DropShadowFloater") ); } @@ -3089,7 +2942,7 @@ void LLMenuGL::draw( void ) if( mBgVisible ) { - gl_rect_2d( 0, mRect.getHeight(), mRect.getWidth(), 0, mBackgroundColor ); + gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0, mBackgroundColor ); } LLView::draw(); } @@ -3139,7 +2992,7 @@ LLMenuGL* LLMenuGL::getChildMenuByName(const LLString& name, BOOL recurse) const return (LLMenuGL*)view; } } - llwarns << "Child Menu " << name << " not found in menu " << mName << llendl; + llwarns << "Child Menu " << name << " not found in menu " << getName() << llendl; return NULL; } @@ -3254,7 +3107,7 @@ void LLPieMenuBranch::buildDrawLabel( void ) if(mEnabledCallback) { setEnabled(mEnabledCallback(mUserData)); - mDrawTextDisabled = FALSE; + setDrawTextDisabled(FALSE); } else { @@ -3273,7 +3126,7 @@ void LLPieMenuBranch::buildDrawLabel( void ) break; } } - mDrawTextDisabled = !any_enabled; + setDrawTextDisabled(!any_enabled); setEnabled(TRUE); } @@ -3334,20 +3187,6 @@ LLPieMenu::LLPieMenu(const LLString& name) setCanTearOff(FALSE); } -// virtual -LLPieMenu::~LLPieMenu() -{ } - - -EWidgetType LLPieMenu::getWidgetType() const -{ - return WIDGET_TYPE_PIE_MENU; -} - -LLString LLPieMenu::getWidgetTag() const -{ - return LL_PIE_MENU_TAG; -} void LLPieMenu::initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory) { @@ -3621,8 +3460,8 @@ void LLPieMenu::draw() mHoverItem = NULL; } - F32 width = (F32) mRect.getWidth(); - F32 height = (F32) mRect.getHeight(); + F32 width = (F32) getRect().getWidth(); + F32 height = (F32) getRect().getHeight(); mCurRadius = PIE_SCALE_FACTOR * llmax( width/2, height/2 ); mOuterRingAlpha = mUseInfiniteRadius ? 0.f : 1.f; @@ -3696,8 +3535,8 @@ void LLPieMenu::draw() void LLPieMenu::drawBackground(LLMenuItemGL* itemp, LLColor4& color) { - F32 width = (F32) mRect.getWidth(); - F32 height = (F32) mRect.getHeight(); + F32 width = (F32) getRect().getWidth(); + F32 height = (F32) getRect().getHeight(); F32 center_x = width/2; F32 center_y = height/2; S32 steps = 100; @@ -3790,7 +3629,8 @@ void LLPieMenu::arrange() // TODO: Compute actual bounding rect for menu - mRect.setOriginAndSize(mRect.mLeft, mRect.mBottom, rect_width, rect_height ); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast<LLRect&>(getRect()).setOriginAndSize(getRect().mLeft, getRect().mBottom, rect_width, rect_height ); // place items around a circle, with item 0 at positive X, // rotating counter-clockwise @@ -3827,8 +3667,8 @@ LLMenuItemGL *LLPieMenu::pieItemFromXY(S32 x, S32 y) // An arc of the pie menu is 45 degrees const F32 ARC_DEG = 45.f; - S32 delta_x = x - mRect.getWidth() / 2; - S32 delta_y = y - mRect.getHeight() / 2; + S32 delta_x = x - getRect().getWidth() / 2; + S32 delta_y = y - getRect().getHeight() / 2; // circle safe zone in the center S32 dist_squared = delta_x*delta_x + delta_y*delta_y; @@ -3838,7 +3678,7 @@ LLMenuItemGL *LLPieMenu::pieItemFromXY(S32 x, S32 y) } // infinite radius is only used with right clicks - S32 radius = llmax( mRect.getWidth()/2, mRect.getHeight()/2 ); + S32 radius = llmax( getRect().getWidth()/2, getRect().getHeight()/2 ); if (!(mUseInfiniteRadius && mRightMouseDown) && dist_squared > radius * radius) { return NULL; @@ -3876,8 +3716,8 @@ S32 LLPieMenu::pieItemIndexFromXY(S32 x, S32 y) // An arc of the pie menu is 45 degrees const F32 ARC_DEG = 45.f; // correct for non-square pixels - S32 delta_x = x - mRect.getWidth() / 2; - S32 delta_y = y - mRect.getHeight() / 2; + S32 delta_x = x - getRect().getWidth() / 2; + S32 delta_y = y - getRect().getHeight() / 2; // circle safe zone in the center if (delta_x*delta_x + delta_y*delta_y < PIE_CENTER_SIZE*PIE_CENTER_SIZE) @@ -3900,8 +3740,8 @@ S32 LLPieMenu::pieItemIndexFromXY(S32 x, S32 y) void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) { - S32 width = mRect.getWidth(); - S32 height = mRect.getHeight(); + S32 width = getRect().getWidth(); + S32 height = getRect().getHeight(); const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect(); @@ -3911,40 +3751,45 @@ void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) S32 local_x, local_y; parent_view->screenPointToLocal(x, y, &local_x, &local_y); - mRect.setCenterAndSize(local_x, local_y, width, height); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast<LLRect&>(getRect()).setCenterAndSize(local_x, local_y, width, height); arrange(); // Adjust the pie rectangle to keep it on screen - if (mRect.mLeft < menu_region_rect.mLeft) + if (getRect().mLeft < menu_region_rect.mLeft) { - //mShiftHoriz = menu_region_rect.mLeft - mRect.mLeft; - //mRect.translate( mShiftHoriz, 0 ); - mRect.translate( menu_region_rect.mLeft - mRect.mLeft, 0 ); + //mShiftHoriz = menu_region_rect.mLeft - getRect().mLeft; + //getRect().translate( mShiftHoriz, 0 ); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast<LLRect&>(getRect()).translate( menu_region_rect.mLeft - getRect().mLeft, 0 ); moved = TRUE; } - if (mRect.mRight > menu_region_rect.mRight) + if (getRect().mRight > menu_region_rect.mRight) { - //mShiftHoriz = menu_region_rect.mRight - mRect.mRight; - //mRect.translate( mShiftHoriz, 0); - mRect.translate( menu_region_rect.mRight - mRect.mRight, 0 ); + //mShiftHoriz = menu_region_rect.mRight - getRect().mRight; + //getRect().translate( mShiftHoriz, 0); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast<LLRect&>(getRect()).translate( menu_region_rect.mRight - getRect().mRight, 0 ); moved = TRUE; } - if (mRect.mBottom < menu_region_rect.mBottom) + if (getRect().mBottom < menu_region_rect.mBottom) { - //mShiftVert = menu_region_rect.mBottom - mRect.mBottom; - //mRect.translate( 0, mShiftVert ); - mRect.translate( 0, menu_region_rect.mBottom - mRect.mBottom ); + //mShiftVert = menu_region_rect.mBottom - getRect().mBottom; + //getRect().translate( 0, mShiftVert ); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast<LLRect&>(getRect()).translate( 0, menu_region_rect.mBottom - getRect().mBottom ); moved = TRUE; } - if (mRect.mTop > menu_region_rect.mTop) + if (getRect().mTop > menu_region_rect.mTop) { - //mShiftVert = menu_region_rect.mTop - mRect.mTop; - //mRect.translate( 0, mShiftVert ); - mRect.translate( 0, menu_region_rect.mTop - mRect.mTop ); + //mShiftVert = menu_region_rect.mTop - getRect().mTop; + //getRect().translate( 0, mShiftVert ); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast<LLRect&>(getRect()).translate( 0, menu_region_rect.mTop - getRect().mTop ); moved = TRUE; } @@ -3953,8 +3798,8 @@ void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) if (moved) { LLCoordGL center; - center.mX = (mRect.mLeft + mRect.mRight) / 2; - center.mY = (mRect.mTop + mRect.mBottom) / 2; + center.mX = (getRect().mLeft + getRect().mRight) / 2; + center.mY = (getRect().mTop + getRect().mBottom) / 2; LLUI::setCursorPositionLocal(getParent(), center.mX, center.mY); } @@ -4066,7 +3911,7 @@ LLView* LLMenuBarGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory LLMenuBarGL *menubar = new LLMenuBarGL(name); - LLViewHandle parent_handle = LLViewHandle::sDeadHandle; + LLHandle<LLFloater> parent_handle; if (parent->getWidgetType() == WIDGET_TYPE_FLOATER) { parent_handle = ((LLFloater*)parent)->getHandle(); @@ -4246,7 +4091,7 @@ BOOL LLMenuBarGL::jumpKeysActive() void LLMenuBarGL::arrange( void ) { U32 pos = 0; - LLRect rect( 0, mRect.getHeight(), 0, 0 ); + LLRect rect( 0, getRect().getHeight(), 0, 0 ); item_list_t::const_iterator item_iter; for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) { @@ -4398,25 +4243,12 @@ LLMenuHolderGL::LLMenuHolderGL(const LLString& name, const LLRect& rect, BOOL mo mCanHide = TRUE; } -LLMenuHolderGL::~LLMenuHolderGL() -{ -} - -EWidgetType LLMenuHolderGL::getWidgetType() const -{ - return WIDGET_TYPE_MENU_HOLDER; -} - -LLString LLMenuHolderGL::getWidgetTag() const -{ - return LL_MENU_HOLDER_GL_TAG; -} void LLMenuHolderGL::draw() { LLView::draw(); // now draw last selected item as overlay - LLMenuItemGL* selecteditem = (LLMenuItemGL*)LLView::getViewByHandle(sItemLastSelectedHandle); + LLMenuItemGL* selecteditem = (LLMenuItemGL*)sItemLastSelectedHandle.get(); if (selecteditem && sItemActivationTimer.getStarted() && sItemActivationTimer.getElapsedTimeF32() < ACTIVATE_HIGHLIGHT_TIME) { // make sure toggle items, for example, show the proper state when fading out @@ -4426,10 +4258,10 @@ void LLMenuHolderGL::draw() selecteditem->localRectToOtherView(selecteditem->getLocalRect(), &item_rect, this); F32 interpolant = sItemActivationTimer.getElapsedTimeF32() / ACTIVATE_HIGHLIGHT_TIME; - F32 alpha = lerp(LLMenuItemGL::sHighlightBackground.mV[VALPHA], 0.f, interpolant); - LLColor4 bg_color(LLMenuItemGL::sHighlightBackground.mV[VRED], - LLMenuItemGL::sHighlightBackground.mV[VGREEN], - LLMenuItemGL::sHighlightBackground.mV[VBLUE], + F32 alpha = lerp(LLMenuItemGL::getHighlightBGColor().mV[VALPHA], 0.f, interpolant); + LLColor4 bg_color(LLMenuItemGL::getHighlightBGColor().mV[VRED], + LLMenuItemGL::getHighlightBGColor().mV[VGREEN], + LLMenuItemGL::getHighlightBGColor().mV[VBLUE], alpha); LLUI::pushMatrix(); @@ -4466,7 +4298,7 @@ BOOL LLMenuHolderGL::handleRightMouseDown( S32 x, S32 y, MASK mask ) void LLMenuHolderGL::reshape(S32 width, S32 height, BOOL called_from_parent) { - if (width != mRect.getWidth() || height != mRect.getHeight()) + if (width != getRect().getWidth() || height != getRect().getHeight()) { hideMenus(); } @@ -4486,10 +4318,6 @@ BOOL LLMenuHolderGL::hasVisibleMenu() const return FALSE; } -const LLRect LLMenuHolderGL::getMenuRect() const -{ - return getLocalRect(); -} BOOL LLMenuHolderGL::hideMenus() { @@ -4522,7 +4350,7 @@ BOOL LLMenuHolderGL::hideMenus() void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item) { - sItemLastSelectedHandle = item->mViewHandle; + sItemLastSelectedHandle = item->getHandle(); sItemActivationTimer.start(); } @@ -4532,20 +4360,24 @@ void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item) LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : LLFloater(menup->getName(), LLRect(0, 100, 100, 0), menup->getLabel(), FALSE, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, FALSE, FALSE) { + // flag menu as being torn off + menup->setTornOff(TRUE); + // update menu layout as torn off menu (no spillover menus) + menup->arrange(); + LLRect rect; menup->localRectToOtherView(LLRect(-1, menup->getRect().getHeight(), menup->getRect().getWidth() + 3, 0), &rect, gFloaterView); + // make sure this floater is big enough for menu mTargetHeight = (F32)(rect.getHeight() + LLFLOATER_HEADER_SIZE + 5); reshape(rect.getWidth(), rect.getHeight()); setRect(rect); - mOldParent = menup->getParent(); - mOldParent->removeChild(menup); + // attach menu to floater menup->setFollowsAll(); + mOldParent = menup->getParent(); addChild(menup); menup->setVisible(TRUE); menup->translate(-menup->getRect().mLeft + 1, -menup->getRect().mBottom + 1); - - menup->setTornOff(TRUE); menup->setDropShadowed(FALSE); mMenu = menup; @@ -4554,19 +4386,16 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : mMenu->highlightNextItem(NULL); } -LLTearOffMenu::~LLTearOffMenu() -{ -} void LLTearOffMenu::draw() { - mMenu->setBackgroundVisible(mBgOpaque); + mMenu->setBackgroundVisible(isBackgroundOpaque()); mMenu->arrange(); - if (mRect.getHeight() != mTargetHeight) + if (getRect().getHeight() != mTargetHeight) { // animate towards target height - reshape(mRect.getWidth(), llceil(lerp((F32)mRect.getHeight(), mTargetHeight, LLCriticalDamp::getInterpolant(0.05f)))); + reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLCriticalDamp::getInterpolant(0.05f)))); } else { @@ -4667,23 +4496,3 @@ void LLTearOffMenu::onClose(bool app_quitting) destroy(); } -///============================================================================ -/// Class LLEditMenuHandlerMgr -///============================================================================ -LLEditMenuHandlerMgr& LLEditMenuHandlerMgr::getInstance() -{ - static LLEditMenuHandlerMgr instance; - return instance; -} - -LLEditMenuHandlerMgr::LLEditMenuHandlerMgr() -{ -} - -LLEditMenuHandlerMgr::~LLEditMenuHandlerMgr() -{ -} - -///============================================================================ -/// Local function definitions -///============================================================================ diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index ce33f8a379..e9b80e562b 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -44,8 +44,6 @@ #include "lluistring.h" #include "llview.h" -class LLMenuItemGL; -class LLMenuHolderGL; extern S32 MENU_BAR_HEIGHT; extern S32 MENU_BAR_WIDTH; @@ -77,13 +75,19 @@ typedef void (*label_callback)(LLString&,void*); // The LLMenuItemGL represents a single menu item in a menu. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLFontGL; -class LLMenuGL; - - class LLMenuItemGL : public LLView { public: + // static functions to control the global color scheme. + static void setEnabledColor( const LLColor4& color ) { sEnabledColor = color; } + static const LLColor4& getEnabledColor() { return sEnabledColor; } + static void setDisabledColor( const LLColor4& color ) { sDisabledColor = color; } + static const LLColor4& getDisabledColor() { return sDisabledColor; } + static void setHighlightBGColor( const LLColor4& color ) { sHighlightBackground = color; } + static const LLColor4& getHighlightBGColor() { return sHighlightBackground; } + static void setHighlightFGColor( const LLColor4& color ) { sHighlightForeground = color; } + static const LLColor4& getHighlightFGColor() { return sHighlightForeground; } + LLMenuItemGL( const LLString& name, const LLString& label, KEY key = KEY_NONE, MASK = MASK_NONE ); virtual void setValue(const LLSD& value) { setLabel(value.asString()); } @@ -99,44 +103,38 @@ public: virtual BOOL handleAcceleratorKey(KEY key, MASK mask); - BOOL getHighlight() const { return mHighlight; } - void setJumpKey(KEY key); - KEY getJumpKey(); + KEY getJumpKey() const { return mJumpKey; } // set the font used by this item. - void setFont(LLFontGL* font); + void setFont(const LLFontGL* font) { mFont = font; } + const LLFontGL* getFont() const { return mFont; } void setFontStyle(U8 style) { mStyle = style; } + U8 getFontStyle() const { return mStyle; } // returns the height in pixels for the current font. - virtual U32 getNominalHeight( void ); - - // functions to control the color scheme - static void setEnabledColor( const LLColor4& color ); - static void setDisabledColor( const LLColor4& color ); - static void setHighlightBGColor( const LLColor4& color ); - static void setHighlightFGColor( const LLColor4& color ); + virtual U32 getNominalHeight( void ) const; // Marks item as not needing space for check marks or accelerator keys - virtual void setBriefItem(BOOL brief); + virtual void setBriefItem(BOOL brief) { mBriefItem = brief; } + virtual BOOL isBriefItem() const { return mBriefItem; } virtual BOOL addToAcceleratorList(std::list<LLKeyBinding*> *listp); void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; } - - // return the name label - LLString getLabel( void ) const { return mLabel.getString(); } + BOOL getAllowKeyRepeat() const { return mAllowKeyRepeat; } // change the label - void setLabel( const LLStringExplicit& label ); + void setLabel( const LLStringExplicit& label ) { mLabel = label; } + LLString getLabel( void ) const { return mLabel.getString(); } virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); // Get the parent menu for this item - virtual LLMenuGL* getMenu(); + virtual class LLMenuGL* getMenu(); // returns the normal width of this control in pixels - this is // used for calculating the widest item, as well as for horizontal // arrangement. - virtual U32 getNominalWidth( void ); + virtual U32 getNominalWidth( void ) const; // buildDrawLabel() - constructs the string used during the draw() // function. This reduces the overall string manipulation, but can @@ -155,14 +153,14 @@ public: // doIt() - do the primary funcationality of the menu item. virtual void doIt( void ); - // set the hover status (called by it's menu) virtual void setHighlight( BOOL highlight ); + virtual BOOL getHighlight() const { return mHighlight; } // determine if this represents an active sub-menu - virtual BOOL isActive( void ) const; + virtual BOOL isActive( void ) const { return FALSE; } // determine if this represents an open sub-menu - virtual BOOL isOpen( void ) const; + virtual BOOL isOpen( void ) const { return FALSE; } virtual void setEnabledSubMenus(BOOL enable){}; @@ -172,24 +170,20 @@ public: virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); virtual void draw( void ); - BOOL getHover() { return mGotHover; } + BOOL getHover() const { return mGotHover; } + void setDrawTextDisabled(BOOL disabled) { mDrawTextDisabled = disabled; } BOOL getDrawTextDisabled() const { return mDrawTextDisabled; } protected: + void setHover(BOOL hover) { mGotHover = hover; } + // This function appends the character string representation of // the current accelerator key and mask to the provided string. - void appendAcceleratorString( LLString& st ); - -public: - static LLColor4 sEnabledColor; - static LLColor4 sDisabledColor; - static LLColor4 sHighlightBackground; - static LLColor4 sHighlightForeground; - -protected: - static BOOL sDropShadowText; + void appendAcceleratorString( LLString& st ) const; + KEY mAcceleratorKey; + MASK mAcceleratorMask; // mLabel contains the actual label specified by the user. LLUIString mLabel; @@ -200,12 +194,15 @@ protected: LLUIString mDrawAccelLabel; LLUIString mDrawBranchLabel; + BOOL mHighlight; +private: + static LLColor4 sEnabledColor; + static LLColor4 sDisabledColor; + static LLColor4 sHighlightBackground; + static LLColor4 sHighlightForeground; + // Keyboard and mouse variables - KEY mJumpKey; - KEY mAcceleratorKey; - MASK mAcceleratorMask; BOOL mAllowKeyRepeat; - BOOL mHighlight; BOOL mGotHover; // If true, suppress normal space for check marks on the left and accelerator @@ -213,10 +210,11 @@ protected: BOOL mBriefItem; // Font for this item - LLFontGL* mFont; - + const LLFontGL* mFont; U8 mStyle; BOOL mDrawTextDisabled; + + KEY mJumpKey; }; @@ -229,14 +227,6 @@ protected: class LLMenuItemCallGL : public LLMenuItemGL { -protected: - menu_callback mCallback; - // mEnabledCallback should return TRUE if the item should be enabled - enabled_callback mEnabledCallback; - label_callback mLabelCallback; - void* mUserData; - on_disabled_callback mOnDisabledCallback; - public: // normal constructor LLMenuItemCallGL( const LLString& name, @@ -277,8 +267,8 @@ public: virtual LLString getType() const { return "call"; } - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_CALL; } + virtual LLString getWidgetTag() const { return LL_MENU_ITEM_CALL_GL_TAG; } void setEnabledControl(LLString enabled_control, LLView *context); void setVisibleControl(LLString enabled_control, LLView *context); @@ -302,6 +292,14 @@ public: //virtual void draw(); virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata); + +private: + menu_callback mCallback; + // mEnabledCallback should return TRUE if the item should be enabled + enabled_callback mEnabledCallback; + label_callback mLabelCallback; + void* mUserData; + on_disabled_callback mOnDisabledCallback; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -310,17 +308,13 @@ public: // The LLMenuItemCheckGL is an extension of the LLMenuItemCallGL // class, by allowing another method to be specified which determines // if the menu item should consider itself checked as true or not. Be -// careful that the check callback provided - it needs to be VERY +// careful that the provided callback is fast - it needs to be VERY // FUCKING EFFICIENT, because it may need to be checked a lot. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLMenuItemCheckGL : public LLMenuItemCallGL { -protected: - check_callback mCheckCallback; - BOOL mChecked; - public: LLMenuItemCheckGL( const LLString& name, const LLString& label, @@ -348,8 +342,8 @@ public: void setCheckedControl(LLString checked_control, LLView *context); virtual void setValue(const LLSD& value) { mChecked = value.asBoolean(); } - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_CHECK; } + virtual LLString getWidgetTag() const { return LL_MENU_ITEM_CHECK_GL_TAG; } virtual LLString getType() const { return "check"; } @@ -358,8 +352,9 @@ public: virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata); - // LLView Functionality - //virtual void draw( void ); +private: + check_callback mCheckCallback; + BOOL mChecked; }; @@ -372,9 +367,6 @@ public: class LLMenuItemToggleGL : public LLMenuItemGL { -protected: - BOOL* mToggle; - public: LLMenuItemToggleGL( const LLString& name, const LLString& label, BOOL* toggle, @@ -394,6 +386,9 @@ public: // LLView Functionality //virtual void draw( void ); + +private: + BOOL* mToggle; }; @@ -408,16 +403,14 @@ public: // it in the appendMenu() method. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLMenuArrowGL; -class LLMenuItemBranchGL; -class LLMenuItemTearOffGL; - class LLMenuGL : public LLUICtrl +// TODO: The menu and menu item classes share a great deal of functionality and perhaps should be united. +// I think it may make the most sense to make LLMenuGL be a subclass of LLMenuItemGL. -MG { public: - LLMenuGL( const LLString& name, const LLString& label, LLViewHandle parent_floater = LLViewHandle::sDeadHandle ); - LLMenuGL( const LLString& label, LLViewHandle parent_floater = LLViewHandle::sDeadHandle ); + LLMenuGL( const LLString& name, const LLString& label, LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>()); + LLMenuGL( const LLString& label, LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>() ); virtual ~LLMenuGL( void ); virtual LLXMLNodePtr getXML(bool save_children = true) const; static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); @@ -446,11 +439,12 @@ public: const LLString& getLabel( void ) const { return mLabel.getString(); } void setLabel(const LLStringExplicit& label) { mLabel = label; } - static void setDefaultBackgroundColor( const LLColor4& color ); - void setBackgroundColor( const LLColor4& color ); - LLColor4 getBackgroundColor(); + // background colors + static void setDefaultBackgroundColor( const LLColor4& color ) { sDefaultBackgroundColor = color; } + void setBackgroundColor( const LLColor4& color ) { mBackgroundColor = color; } + const LLColor4& getBackgroundColor() const { return mBackgroundColor; } void setBackgroundVisible( BOOL b ) { mBgVisible = b; } - void setCanTearOff(BOOL tear_off, LLViewHandle parent_floater_handle = LLViewHandle::sDeadHandle); + void setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>()); // Add the menu item to this menu. virtual BOOL append( LLMenuItemGL* item ); @@ -524,7 +518,7 @@ public: BOOL getCanTearOff() { return mTearOffItem != NULL; } - KEY getJumpKey() { return mJumpKey; } + KEY getJumpKey() const { return mJumpKey; } void setJumpKey(KEY key) { mJumpKey = key; } static void setKeyboardMode(BOOL mode) { sKeyboardMode = mode; } @@ -532,40 +526,42 @@ public: static void onFocusLost(LLView* old_focus); - static LLMenuHolderGL* sMenuContainer; + static class LLMenuHolderGL* sMenuContainer; protected: void createSpilloverBranch(); void cleanupSpilloverBranch(); -protected: + // TODO: create accessor methods for these? + typedef std::list< LLMenuItemGL* > item_list_t; + item_list_t mItems; + typedef std::map<KEY, LLMenuItemGL*> navigation_key_map_t; + navigation_key_map_t mJumpKeys; + S32 mLastMouseX; + S32 mLastMouseY; + S32 mMouseVelX; + S32 mMouseVelY; + BOOL mHorizontalLayout; + BOOL mKeepFixedSize; + +private: static LLColor4 sDefaultBackgroundColor; static BOOL sKeyboardMode; LLColor4 mBackgroundColor; BOOL mBgVisible; - typedef std::list< LLMenuItemGL* > item_list_t; - item_list_t mItems; - typedef std::map<KEY, LLMenuItemGL*> navigation_key_map_t; - navigation_key_map_t mJumpKeys; LLMenuItemGL* mParentMenuItem; LLUIString mLabel; BOOL mDropShadowed; // Whether to drop shadow - BOOL mHorizontalLayout; - BOOL mKeepFixedSize; BOOL mHasSelection; LLFrameTimer mFadeTimer; - S32 mLastMouseX; - S32 mLastMouseY; - S32 mMouseVelX; - S32 mMouseVelY; BOOL mTornOff; - LLMenuItemTearOffGL* mTearOffItem; - LLMenuItemBranchGL* mSpilloverBranch; + class LLMenuItemTearOffGL* mTearOffItem; + class LLMenuItemBranchGL* mSpilloverBranch; LLMenuGL* mSpilloverMenu; - LLViewHandle mParentFloaterHandle; + LLHandle<LLFloater> mParentFloaterHandle; KEY mJumpKey; -}; +}; // end class LLMenuGL @@ -578,20 +574,15 @@ protected: class LLMenuItemBranchGL : public LLMenuItemGL { -protected: - LLMenuGL* mBranch; - public: LLMenuItemBranchGL( const LLString& name, const LLString& label, LLMenuGL* branch, KEY key = KEY_NONE, MASK mask = MASK_NONE ); virtual LLXMLNodePtr getXML(bool save_children = true) const; - virtual LLView* getChildByName(const LLString& name, BOOL recurse) const; - - virtual LLString getType() const { return "menu"; } + virtual LLString getType() const { return "menu"; } - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_BRANCH; } + virtual LLString getWidgetTag() const { return LL_MENU_ITEM_BRANCH_GL_TAG; } virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); @@ -615,9 +606,9 @@ public: virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); - virtual BOOL isActive() const; + virtual BOOL isActive() const { return isOpen() && mBranch->getHighlightedItem(); } - virtual BOOL isOpen() const; + virtual BOOL isOpen() const { return mBranch->isOpen(); } LLMenuGL *getBranch() const { return mBranch; } @@ -628,11 +619,16 @@ public: virtual void draw(); - virtual void setEnabledSubMenus(BOOL enabled); + virtual void setEnabledSubMenus(BOOL enabled) { mBranch->setEnabledSubMenus(enabled); } virtual void openMenu(); -}; +protected: + virtual LLView* getChildByName(const LLString& name, BOOL recurse) const; + +private: + LLMenuGL* mBranch; +}; // end class LLMenuItemBranchGL @@ -647,10 +643,10 @@ class LLPieMenu public: LLPieMenu(const LLString& name, const LLString& label); LLPieMenu(const LLString& name); - virtual ~LLPieMenu(); + virtual ~LLPieMenu() {} - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_PIE_MENU; } + virtual LLString getWidgetTag() const { return LL_PIE_MENU_TAG; } void initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory); @@ -682,11 +678,10 @@ public: void show(S32 x, S32 y, BOOL mouse_down); void hide(BOOL item_selected); -protected: +private: LLMenuItemGL *pieItemFromXY(S32 x, S32 y); S32 pieItemIndexFromXY(S32 x, S32 y); -private: // These cause menu items to be spuriously selected by right-clicks // near the window edge at low frame rates. I don't think they are // needed unless you shift the menu position in the draw() function. JC @@ -703,6 +698,7 @@ private: BOOL mRightMouseDown; }; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuBarGL // @@ -711,10 +707,6 @@ private: class LLMenuBarGL : public LLMenuGL { -protected: - std::list <LLKeyBinding*> mAccelerators; - BOOL mAltKeyTrigger; - public: LLMenuBarGL( const LLString& name ); virtual ~LLMenuBarGL(); @@ -748,9 +740,11 @@ public: void resetMenuTrigger() { mAltKeyTrigger = FALSE; } -protected: +private: void checkMenuTrigger(); + std::list <LLKeyBinding*> mAccelerators; + BOOL mAltKeyTrigger; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -763,10 +757,10 @@ class LLMenuHolderGL : public LLPanel public: LLMenuHolderGL(); LLMenuHolderGL(const LLString& name, const LLRect& rect, BOOL mouse_opaque, U32 follows = FOLLOWS_NONE); - virtual ~LLMenuHolderGL(); + virtual ~LLMenuHolderGL() {} - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_HOLDER; } + virtual LLString getWidgetTag() const { return LL_MENU_HOLDER_GL_TAG; } virtual BOOL hideMenus(); void reshape(S32 width, S32 height, BOOL called_from_parent); @@ -777,13 +771,13 @@ public: virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); - virtual const LLRect getMenuRect() const; + virtual const LLRect getMenuRect() const { return getLocalRect(); } virtual BOOL hasVisibleMenu() const; static void setActivatedItem(LLMenuItemGL* item); -protected: - static LLViewHandle sItemLastSelectedHandle; +private: + static LLHandle<LLView> sItemLastSelectedHandle; static LLFrameTimer sItemActivationTimer; BOOL mCanHide; @@ -793,12 +787,13 @@ protected: // Class LLTearOffMenu // // Floater that hosts a menu +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLTearOffMenu&oldid=81344 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTearOffMenu : public LLFloater { public: static LLTearOffMenu* create(LLMenuGL* menup); - virtual ~LLTearOffMenu(); + virtual ~LLTearOffMenu() {} virtual void onClose(bool app_quitting); virtual void draw(void); virtual void onFocusReceived(); @@ -807,10 +802,9 @@ public: virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); virtual void translate(S32 x, S32 y); -protected: +private: LLTearOffMenu(LLMenuGL* menup); -protected: LLView* mOldParent; LLMenuGL* mMenu; F32 mTargetHeight; @@ -825,19 +819,19 @@ protected: class LLMenuItemTearOffGL : public LLMenuItemGL { public: - LLMenuItemTearOffGL( LLViewHandle parent_floater_handle = (LLViewHandle)LLViewHandle::sDeadHandle ); + LLMenuItemTearOffGL( LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>()); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TEAROFF_MENU; } + virtual LLString getWidgetTag() const { return LL_MENU_ITEM_TEAR_OFF_GL_TAG; } - virtual LLString getType() const { return "tearoff_menu"; } + virtual LLString getType() const { return "tearoff_menu"; } virtual void doIt(void); virtual void draw(void); - virtual U32 getNominalHeight(); + virtual U32 getNominalHeight() const; -protected: - LLViewHandle mParentHandle; +private: + LLHandle<LLFloater> mParentHandle; }; @@ -845,11 +839,13 @@ protected: class LLEditMenuHandlerMgr { public: - LLEditMenuHandlerMgr& getInstance(); - virtual ~LLEditMenuHandlerMgr(); -protected: - LLEditMenuHandlerMgr(); - + LLEditMenuHandlerMgr& getInstance() { + static LLEditMenuHandlerMgr instance; + return instance; + } + virtual ~LLEditMenuHandlerMgr() {} +private: + LLEditMenuHandlerMgr() {}; }; #endif // LL_LLMENUGL_H diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index af14ec418f..a150d295e5 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -74,10 +74,10 @@ LLModalDialog::~LLModalDialog() void LLModalDialog::open() /* Flawfinder: ignore */ { // SJB: Hack! Make sure we don't ever host a modal dialog - LLMultiFloater* thost = LLFloater::sHostp; - LLFloater::sHostp = NULL; + LLMultiFloater* thost = LLFloater::getFloaterHost(); + LLFloater::setFloaterHost(NULL); LLFloater::open(); - LLFloater::sHostp = thost; + LLFloater::setFloaterHost(thost); } void LLModalDialog::reshape(S32 width, S32 height, BOOL called_from_parent) @@ -157,14 +157,18 @@ void LLModalDialog::setVisible( BOOL visible ) BOOL LLModalDialog::handleMouseDown(S32 x, S32 y, MASK mask) { - if (!LLFloater::handleMouseDown(x, y, mask)) + if (mModal) { - if (mModal) + if (!LLFloater::handleMouseDown(x, y, mask)) { // Click was outside the panel make_ui_sound("UISndInvalidOp"); } } + else + { + LLFloater::handleMouseDown(x, y, mask); + } return TRUE; } @@ -247,7 +251,7 @@ void LLModalDialog::draw() LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow"); S32 shadow_lines = LLUI::sConfigGroup->getS32("DropShadowFloater"); - gl_drop_shadow( 0, mRect.getHeight(), mRect.getWidth(), 0, + gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0, shadow_color, shadow_lines); LLFloater::draw(); @@ -276,11 +280,7 @@ void LLModalDialog::draw() void LLModalDialog::centerOnScreen() { LLVector2 window_size = LLUI::getWindowSize(); - - S32 dialog_left = (llround(window_size.mV[VX]) - mRect.getWidth()) / 2; - S32 dialog_bottom = (llround(window_size.mV[VY]) - mRect.getHeight()) / 2; - - translate( dialog_left - mRect.mLeft, dialog_bottom - mRect.mBottom ); + centerWithin(LLRect(0, 0, llround(window_size.mV[VX]), llround(window_size.mV[VY]))); } @@ -319,3 +319,4 @@ void LLModalDialog::onAppFocusGained() } + diff --git a/indra/llui/llmodaldialog.h b/indra/llui/llmodaldialog.h index dcd5644f60..f13e5c37b7 100644 --- a/indra/llui/llmodaldialog.h +++ b/indra/llui/llmodaldialog.h @@ -40,7 +40,7 @@ class LLModalDialog; // By default, a ModalDialog is modal, i.e. no other window can have focus // However, for the sake of code reuse and simplicity, if mModal == false, // the dialog behaves like a normal floater - +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLModalDialog&oldid=81385 class LLModalDialog : public LLFloater { public: @@ -67,6 +67,8 @@ public: /*virtual*/ void setVisible(BOOL visible); /*virtual*/ void draw(); + BOOL isModal() const { return mModal; } + static void onAppFocusLost(); static void onAppFocusGained(); @@ -75,9 +77,9 @@ public: protected: void centerOnScreen(); -protected: +private: LLFrameTimer mVisibleTime; - BOOL mModal; // do not change this after creation! + const BOOL mModal; static std::list<LLModalDialog*> sModalStack; // Top of stack is currently being displayed }; diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 07ebfb7979..6554a25dcf 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -60,10 +60,10 @@ #include "llresizebar.h" #include "llcriticaldamp.h" -LLPanel::panel_map_t LLPanel::sPanelMap; LLPanel::alert_queue_t LLPanel::sAlertQueue; const S32 RESIZE_BAR_OVERLAP = 1; +const S32 RESIZE_BAR_HEIGHT = 3; void LLPanel::init() { @@ -78,8 +78,7 @@ void LLPanel::init() setIsChrome(FALSE); //is this a decorator to a live window or a form? mLastTabGroup = 0; - // add self to handle->panel map - sPanelMap[mViewHandle] = this; + mPanelHandle.bind(this); setTabStop(FALSE); } @@ -121,31 +120,11 @@ LLPanel::LLPanel(const LLString& name, const LLString& rect_control, BOOL border } } -void LLPanel::addBorder(LLViewBorder::EBevel border_bevel, - LLViewBorder::EStyle border_style, S32 border_thickness) -{ - removeBorder(); - mBorder = new LLViewBorder( "panel border", - LLRect(0, mRect.getHeight(), mRect.getWidth(), 0), - border_bevel, border_style, border_thickness ); - mBorder->setSaveToXML(false); - addChild( mBorder ); -} - -void LLPanel::removeBorder() -{ - delete mBorder; - mBorder = NULL; -} - - LLPanel::~LLPanel() { storeRectControl(); - sPanelMap.erase(mViewHandle); } - // virtual EWidgetType LLPanel::getWidgetType() const { @@ -159,7 +138,7 @@ LLString LLPanel::getWidgetTag() const } // virtual -BOOL LLPanel::isPanel() +BOOL LLPanel::isPanel() const { return TRUE; } @@ -170,6 +149,24 @@ BOOL LLPanel::postBuild() return TRUE; } +void LLPanel::addBorder(LLViewBorder::EBevel border_bevel, + LLViewBorder::EStyle border_style, S32 border_thickness) +{ + removeBorder(); + mBorder = new LLViewBorder( "panel border", + LLRect(0, getRect().getHeight(), getRect().getWidth(), 0), + border_bevel, border_style, border_thickness ); + mBorder->setSaveToXML(false); + addChild( mBorder ); +} + +void LLPanel::removeBorder() +{ + delete mBorder; + mBorder = NULL; +} + + // virtual void LLPanel::clearCtrls() { @@ -200,8 +197,8 @@ void LLPanel::draw() { //RN: I don't see the point of this S32 left = 0;//LLPANEL_BORDER_WIDTH; - S32 top = mRect.getHeight();// - LLPANEL_BORDER_WIDTH; - S32 right = mRect.getWidth();// - LLPANEL_BORDER_WIDTH; + S32 top = getRect().getHeight();// - LLPANEL_BORDER_WIDTH; + S32 right = getRect().getWidth();// - LLPANEL_BORDER_WIDTH; S32 bottom = 0;//LLPANEL_BORDER_WIDTH; if (mBgOpaque ) @@ -272,13 +269,13 @@ BOOL LLPanel::handleKey(KEY key, MASK mask, BOOL called_from_parent) if( (mask == MASK_SHIFT) && (KEY_TAB == key)) { //SHIFT-TAB - LLView* cur_focus = gFocusMgr.getKeyboardFocus(); + LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); if (cur_focus && gFocusMgr.childHasKeyboardFocus(this)) { - LLView* focus_root = cur_focus; - while(cur_focus->getParent()) + LLUICtrl* focus_root = cur_focus; + while(cur_focus->getParentUICtrl()) { - cur_focus = cur_focus->getParent(); + cur_focus = cur_focus->getParentUICtrl(); if (cur_focus->isFocusRoot()) { // this is the root-most focus root found so far @@ -287,7 +284,7 @@ BOOL LLPanel::handleKey(KEY key, MASK mask, BOOL called_from_parent) } handled = focus_root->focusPrevItem(FALSE); } - else if (!cur_focus && mIsFocusRoot) + else if (!cur_focus && isFocusRoot()) { handled = focusLastItem(); if (!handled) @@ -301,13 +298,13 @@ BOOL LLPanel::handleKey(KEY key, MASK mask, BOOL called_from_parent) if( (mask == MASK_NONE ) && (KEY_TAB == key)) { //TAB - LLView* cur_focus = gFocusMgr.getKeyboardFocus(); + LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); if (cur_focus && gFocusMgr.childHasKeyboardFocus(this)) { - LLView* focus_root = cur_focus; - while(cur_focus->getParent()) + LLUICtrl* focus_root = cur_focus; + while(cur_focus->getParentUICtrl()) { - cur_focus = cur_focus->getParent(); + cur_focus = cur_focus->getParentUICtrl(); if (cur_focus->isFocusRoot()) { focus_root = cur_focus; @@ -315,7 +312,7 @@ BOOL LLPanel::handleKey(KEY key, MASK mask, BOOL called_from_parent) } handled = focus_root->focusNextItem(FALSE); } - else if (!cur_focus && mIsFocusRoot) + else if (!cur_focus && isFocusRoot()) { handled = focusFirstItem(); if (!handled) @@ -392,12 +389,12 @@ void LLPanel::requires(LLString name, EWidgetType type) mRequirements[name] = type; } -BOOL LLPanel::checkRequirements() +BOOL LLPanel::checkRequirements() const { BOOL retval = TRUE; LLString message; - for (requirements_map_t::iterator i = mRequirements.begin(); i != mRequirements.end(); ++i) + for (requirements_map_t::const_iterator i = mRequirements.begin(); i != mRequirements.end(); ++i) { if (!this->getCtrlByNameAndType(i->first, i->second)) { @@ -473,21 +470,6 @@ void LLPanel::setFocus(BOOL b) } } -void LLPanel::setBackgroundColor(const LLColor4& color) -{ - mBgColorOpaque = color; -} - -LLColor4 LLPanel::getBackgroundColor() -{ - return mBgColorOpaque; -} - -void LLPanel::setTransparentColor(const LLColor4& color) -{ - mBgColorAlpha = color; -} - void LLPanel::setBorderVisible(BOOL b) { if (mBorder) @@ -496,18 +478,18 @@ void LLPanel::setBorderVisible(BOOL b) } } -LLView* LLPanel::getCtrlByNameAndType(const LLString& name, EWidgetType type) +LLUICtrl* LLPanel::getCtrlByNameAndType(const LLString& name, EWidgetType type) const { LLView* view = getChildByName(name, TRUE); - if (view) + if (view && view->isCtrl()) { if (type == WIDGET_TYPE_DONTCARE || view->getWidgetType() == type) { - return view; + return (LLUICtrl*)view; } else { - llwarns << "Widget " << name << " has improper type in panel " << mName << "\n" + llwarns << "Widget " << name << " has improper type in panel " << getName() << "\n" << "Is: \t\t" << view->getWidgetType() << "\n" << "Should be: \t" << type << llendl; @@ -520,17 +502,6 @@ LLView* LLPanel::getCtrlByNameAndType(const LLString& name, EWidgetType type) return NULL; } -// static -LLPanel* LLPanel::getPanelByHandle(LLViewHandle handle) -{ - if (!sPanelMap.count(handle)) - { - return NULL; - } - - return sPanelMap[handle]; -} - // virtual LLXMLNodePtr LLPanel::getXML(bool save_children) const { @@ -718,7 +689,7 @@ void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parent) setLabel(label); } -LLString LLPanel::getFormattedUIString(const LLString& name, const LLString::format_map_t& args) const +LLString LLPanel::getString(const LLString& name, const LLString::format_map_t& args) const { ui_string_map_t::const_iterator found_it = mUIStrings.find(name); if (found_it != mUIStrings.end()) @@ -728,6 +699,7 @@ LLString LLPanel::getFormattedUIString(const LLString& name, const LLString::for formatted_string.setArgList(args); return formatted_string.getString(); } + llerrs << "Failed to find string " << name << " in panel " << getName() << llendl; return LLString::null; } @@ -738,13 +710,14 @@ LLUIString LLPanel::getUIString(const LLString& name) const { return found_it->second; } + llerrs << "Failed to find string " << name << " in panel " << getName() << llendl; return LLUIString(LLString::null); } void LLPanel::childSetVisible(const LLString& id, bool visible) { - LLView* child = getChildByName(id, true); + LLView* child = getChild<LLView>(id); if (child) { child->setVisible(visible); @@ -753,7 +726,7 @@ void LLPanel::childSetVisible(const LLString& id, bool visible) bool LLPanel::childIsVisible(const LLString& id) const { - LLView* child = getChildByName(id, true); + LLView* child = getChild<LLView>(id); if (child) { return (bool)child->getVisible(); @@ -763,7 +736,7 @@ bool LLPanel::childIsVisible(const LLString& id) const void LLPanel::childSetEnabled(const LLString& id, bool enabled) { - LLView* child = getChildByName(id, true); + LLView* child = getChild<LLView>(id); if (child) { child->setEnabled(enabled); @@ -772,7 +745,7 @@ void LLPanel::childSetEnabled(const LLString& id, bool enabled) void LLPanel::childSetTentative(const LLString& id, bool tentative) { - LLView* child = getChildByName(id, true); + LLView* child = getChild<LLView>(id); if (child) { child->setTentative(tentative); @@ -781,7 +754,7 @@ void LLPanel::childSetTentative(const LLString& id, bool tentative) bool LLPanel::childIsEnabled(const LLString& id) const { - LLView* child = getChildByName(id, true); + LLView* child = getChild<LLView>(id); if (child) { return (bool)child->getEnabled(); @@ -792,7 +765,7 @@ bool LLPanel::childIsEnabled(const LLString& id) const void LLPanel::childSetToolTip(const LLString& id, const LLString& msg) { - LLView* child = getChildByName(id, true); + LLView* child = getChild<LLView>(id); if (child) { child->setToolTip(msg); @@ -801,7 +774,7 @@ void LLPanel::childSetToolTip(const LLString& id, const LLString& msg) void LLPanel::childSetRect(const LLString& id, const LLRect& rect) { - LLView* child = getChildByName(id, true); + LLView* child = getChild<LLView>(id); if (child) { child->setRect(rect); @@ -810,7 +783,7 @@ void LLPanel::childSetRect(const LLString& id, const LLRect& rect) bool LLPanel::childGetRect(const LLString& id, LLRect& rect) const { - LLView* child = getChildByName(id, true); + LLView* child = getChild<LLView>(id); if (child) { rect = child->getRect(); @@ -821,7 +794,7 @@ bool LLPanel::childGetRect(const LLString& id, LLRect& rect) const void LLPanel::childSetFocus(const LLString& id, BOOL focus) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { child->setFocus(focus); @@ -830,7 +803,7 @@ void LLPanel::childSetFocus(const LLString& id, BOOL focus) BOOL LLPanel::childHasFocus(const LLString& id) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { return child->hasFocus(); @@ -845,7 +818,7 @@ BOOL LLPanel::childHasFocus(const LLString& id) void LLPanel::childSetFocusChangedCallback(const LLString& id, void (*cb)(LLFocusableElement*, void*), void* user_data) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { child->setFocusChangedCallback(cb, user_data); @@ -854,7 +827,7 @@ void LLPanel::childSetFocusChangedCallback(const LLString& id, void (*cb)(LLFocu void LLPanel::childSetCommitCallback(const LLString& id, void (*cb)(LLUICtrl*, void*), void *userdata ) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { child->setCommitCallback(cb); @@ -864,7 +837,7 @@ void LLPanel::childSetCommitCallback(const LLString& id, void (*cb)(LLUICtrl*, v void LLPanel::childSetDoubleClickCallback(const LLString& id, void (*cb)(void*), void *userdata ) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { child->setDoubleClickCallback(cb); @@ -877,7 +850,7 @@ void LLPanel::childSetDoubleClickCallback(const LLString& id, void (*cb)(void*), void LLPanel::childSetValidate(const LLString& id, BOOL (*cb)(LLUICtrl*, void*)) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { child->setValidateBeforeCommit(cb); @@ -886,7 +859,7 @@ void LLPanel::childSetValidate(const LLString& id, BOOL (*cb)(LLUICtrl*, void*)) void LLPanel::childSetUserData(const LLString& id, void* userdata) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { child->setCallbackUserData(userdata); @@ -895,16 +868,16 @@ void LLPanel::childSetUserData(const LLString& id, void* userdata) void LLPanel::childSetColor(const LLString& id, const LLColor4& color) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { child->setColor(color); } } -LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const LLString& id) +LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const LLString& id) const { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { return child->getSelectionInterface(); @@ -912,9 +885,9 @@ LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const LLString& id return NULL; } -LLCtrlListInterface* LLPanel::childGetListInterface(const LLString& id) +LLCtrlListInterface* LLPanel::childGetListInterface(const LLString& id) const { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { return child->getListInterface(); @@ -922,9 +895,9 @@ LLCtrlListInterface* LLPanel::childGetListInterface(const LLString& id) return NULL; } -LLCtrlScrollInterface* LLPanel::childGetScrollInterface(const LLString& id) +LLCtrlScrollInterface* LLPanel::childGetScrollInterface(const LLString& id) const { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { return child->getScrollInterface(); @@ -934,7 +907,7 @@ LLCtrlScrollInterface* LLPanel::childGetScrollInterface(const LLString& id) void LLPanel::childSetValue(const LLString& id, LLSD value) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLView* child = getChild<LLView>(id, true); if (child) { child->setValue(value); @@ -943,7 +916,7 @@ void LLPanel::childSetValue(const LLString& id, LLSD value) LLSD LLPanel::childGetValue(const LLString& id) const { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLView* child = getChild<LLView>(id, true); if (child) { return child->getValue(); @@ -954,7 +927,7 @@ LLSD LLPanel::childGetValue(const LLString& id) const BOOL LLPanel::childSetTextArg(const LLString& id, const LLString& key, const LLStringExplicit& text) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { return child->setTextArg(key, text); @@ -964,7 +937,7 @@ BOOL LLPanel::childSetTextArg(const LLString& id, const LLString& key, const LLS BOOL LLPanel::childSetLabelArg(const LLString& id, const LLString& key, const LLStringExplicit& text) { - LLView* child = getChildByName(id, true); + LLView* child = getChild<LLView>(id); if (child) { return child->setLabelArg(key, text); @@ -984,7 +957,7 @@ BOOL LLPanel::childSetToolTipArg(const LLString& id, const LLString& key, const void LLPanel::childSetMinValue(const LLString& id, LLSD min_value) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { child->setMinValue(min_value); @@ -993,7 +966,7 @@ void LLPanel::childSetMinValue(const LLString& id, LLSD min_value) void LLPanel::childSetMaxValue(const LLString& id, LLSD max_value) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild<LLUICtrl>(id, true); if (child) { child->setMaxValue(max_value); @@ -1002,16 +975,16 @@ void LLPanel::childSetMaxValue(const LLString& id, LLSD max_value) void LLPanel::childShowTab(const LLString& id, const LLString& tabname, bool visible) { - LLTabContainerCommon* child = LLUICtrlFactory::getTabContainerByName(this, id); + LLTabContainer* child = LLUICtrlFactory::getTabContainerByName(this, id); if (child) { child->selectTabByName(tabname); } } -LLPanel *LLPanel::childGetVisibleTab(const LLString& id) +LLPanel *LLPanel::childGetVisibleTab(const LLString& id) const { - LLTabContainerCommon* child = LLUICtrlFactory::getTabContainerByName(this, id); + LLTabContainer* child = LLUICtrlFactory::getTabContainerByName(this, id); if (child) { return child->getCurrentPanel(); @@ -1021,7 +994,7 @@ LLPanel *LLPanel::childGetVisibleTab(const LLString& id) void LLPanel::childSetTabChangeCallback(const LLString& id, const LLString& tabname, void (*on_tab_clicked)(void*, bool), void *userdata) { - LLTabContainerCommon* child = LLUICtrlFactory::getTabContainerByName(this, id); + LLTabContainer* child = LLUICtrlFactory::getTabContainerByName(this, id); if (child) { LLPanel *panel = child->getPanelByName(tabname); @@ -1033,11 +1006,6 @@ void LLPanel::childSetTabChangeCallback(const LLString& id, const LLString& tabn } } -void LLPanel::childSetText(const LLString& id, const LLStringExplicit& text) -{ - childSetValue(id, LLSD(text)); -} - void LLPanel::childSetKeystrokeCallback(const LLString& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data) { LLLineEditor* child = LLUICtrlFactory::getLineEditorByName(this, id); @@ -1060,11 +1028,6 @@ void LLPanel::childSetPrevalidate(const LLString& id, BOOL (*func)(const LLWStri } } -LLString LLPanel::childGetText(const LLString& id) -{ - return childGetValue(id).asString(); -} - void LLPanel::childSetWrappedText(const LLString& id, const LLString& text, bool visible) { LLTextBox* child = (LLTextBox*)getCtrlByNameAndType(id, WIDGET_TYPE_TEXT_BOX); @@ -1095,7 +1058,7 @@ void LLPanel::childSetActionTextbox(const LLString& id, void(*function)(void*)) void LLPanel::childSetControlName(const LLString& id, const LLString& control_name) { - LLView* view = getChildByName(id, TRUE); + LLView* view = getChild<LLView>(id); if (view) { view->setControlName(control_name, NULL); @@ -1145,7 +1108,7 @@ void LLPanel::storeRectControl() { if( !mRectControl.empty() ) { - LLUI::sConfigGroup->setRect( mRectControl, mRect ); + LLUI::sConfigGroup->setRect( mRectControl, getRect() ); } } @@ -1215,6 +1178,19 @@ LLLayoutStack::~LLLayoutStack() std::for_each(mPanels.begin(), mPanels.end(), DeletePointer()); } +// virtual +EWidgetType LLLayoutStack::getWidgetType() const +{ + return WIDGET_TYPE_LAYOUT_STACK; +} + +// virtual +LLString LLLayoutStack::getWidgetTag() const +{ + return LL_LAYOUT_STACK_TAG; +} + + void LLLayoutStack::draw() { updateLayout(); @@ -1326,23 +1302,13 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor return layout_stackp; } -S32 LLLayoutStack::getMinWidth() -{ - return mMinWidth; -} - -S32 LLLayoutStack::getMinHeight() -{ - return mMinHeight; -} - S32 LLLayoutStack::getDefaultHeight(S32 cur_height) { // if we are spanning our children (crude upward propagation of size) // then don't enforce our size on our children if (mOrientation == HORIZONTAL) { - cur_height = llmax(mMinHeight, mRect.getHeight()); + cur_height = llmax(mMinHeight, getRect().getHeight()); } return cur_height; @@ -1354,7 +1320,7 @@ S32 LLLayoutStack::getDefaultWidth(S32 cur_width) // then don't enforce our size on our children if (mOrientation == VERTICAL) { - cur_width = llmax(mMinWidth, mRect.getWidth()); + cur_width = llmax(mMinWidth, getRect().getWidth()); } return cur_width; @@ -1476,15 +1442,15 @@ void LLLayoutStack::updateLayout(BOOL force_resize) S32 pixels_to_distribute; if (mOrientation == HORIZONTAL) { - pixels_to_distribute = mRect.getWidth() - total_width; + pixels_to_distribute = getRect().getWidth() - total_width; } else //VERTICAL { - pixels_to_distribute = mRect.getHeight() - total_height; + pixels_to_distribute = getRect().getHeight() - total_height; } S32 cur_x = 0; - S32 cur_y = mRect.getHeight(); + S32 cur_y = getRect().getHeight(); for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { @@ -1619,18 +1585,19 @@ void LLLayoutStack::updateLayout(BOOL force_resize) // not enough room to fit existing contents if (!force_resize && ((cur_y != -mPanelSpacing) - || (cur_x != mRect.getWidth() + mPanelSpacing))) + || (cur_x != getRect().getWidth() + mPanelSpacing))) { // do another layout pass with all stacked elements contributing // even those that don't usually resize llassert_always(force_resize == FALSE); updateLayout(TRUE); } -} +} // end LLLayoutStack::updateLayout -LLLayoutStack::LLEmbeddedPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) + +LLLayoutStack::LLEmbeddedPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const { - e_panel_list_t::iterator panel_it; + e_panel_list_t::const_iterator panel_it; for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { if ((*panel_it)->mPanel == panelp) diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index 88b4ecb76b..2fdf95df58 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -33,10 +33,11 @@ #ifndef LL_LLPANEL_H #define LL_LLPANEL_H -// Opaque view with a background and a border. Can contain LLUICtrls. #include "llcallbackmap.h" #include "lluictrl.h" +#include "llbutton.h" +#include "lllineeditor.h" #include "llviewborder.h" #include "lluistring.h" #include "v4color.h" @@ -47,39 +48,26 @@ const S32 LLPANEL_BORDER_WIDTH = 1; const BOOL BORDER_YES = TRUE; const BOOL BORDER_NO = FALSE; -class LLViewerImage; -class LLUUID; -class LLCheckBoxCtrl; -class LLComboBox; -class LLIconCtrl; -class LLLineEditor; -class LLRadioGroup; -class LLScrollListCtrl; -class LLSliderCtrl; -class LLSpinCtrl; -class LLTextBox; -class LLTextEditor; - -class LLAlertInfo + +struct LLAlertInfo { -public: LLString mLabel; LLString::format_map_t mArgs; - LLAlertInfo(LLString label, LLString::format_map_t args) - : mLabel(label), mArgs(args) { } - - LLAlertInfo() { } + LLAlertInfo(LLString label, LLString::format_map_t args) : mLabel(label), mArgs(args) { } + LLAlertInfo(){} }; -class LLPanel : public LLUICtrl + +/* + * General purpose concrete view base class. + * Transparent or opaque, + * With or without border, + * Can contain LLUICtrls. + */ +class LLPanel : public LLUICtrl { public: - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; - - // defaults to TRUE - virtual BOOL isPanel(); // minimal constructor for data-driven initialization LLPanel(); @@ -89,71 +77,74 @@ public: LLPanel(const LLString& name, const LLRect& rect, BOOL bordered = TRUE); // Position and size are saved to rect_control - LLPanel(const LLString& name, const LLString& rect_control, BOOL bordered = TRUE); + LLPanel(const LLString& name, const LLString& rect_control, BOOL bordered = TRUE); + + /*virtual*/ ~LLPanel(); + + // LLView interface + /*virtual*/ EWidgetType getWidgetType() const; + /*virtual*/ LLString getWidgetTag() const; + /*virtual*/ BOOL isPanel() const; + /*virtual*/ void draw(); + /*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent ); + /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ); + /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; + // From LLFocusableElement + /*virtual*/ void setFocus( BOOL b ); + + // New virtuals + virtual void refresh(); // called in setFocus() + virtual BOOL postBuild(); + virtual void clearCtrls(); // overridden in LLPanelObject and LLPanelVolume + + // Border controls void addBorder( LLViewBorder::EBevel border_bevel = LLViewBorder::BEVEL_OUT, LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE, S32 border_thickness = LLPANEL_BORDER_WIDTH ); - - void removeBorder(); - - virtual ~LLPanel(); - virtual void draw(); - virtual void refresh(); // called in setFocus() - virtual void setFocus( BOOL b ); - void setFocusRoot(BOOL b) { mIsFocusRoot = b; } - virtual BOOL handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ); - virtual BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent ); - virtual BOOL postBuild(); + void removeBorder(); + BOOL hasBorder() const { return mBorder != NULL; } + void setBorderVisible( BOOL b ); void requires(LLString name, EWidgetType type = WIDGET_TYPE_DONTCARE); - BOOL checkRequirements(); - - static void alertXml(LLString label, LLString::format_map_t args = LLString::format_map_t()); - static BOOL nextAlert(LLAlertInfo &alert); + BOOL checkRequirements() const; - void setBackgroundColor( const LLColor4& color ); - LLColor4 getBackgroundColor(); - void setTransparentColor(const LLColor4& color); + void setBackgroundColor( const LLColor4& color ) { mBgColorOpaque = color; } + const LLColor4& getBackgroundColor() const { return mBgColorOpaque; } + void setTransparentColor(const LLColor4& color) { mBgColorAlpha = color; } + const LLColor4& getTransparentColor() const { return mBgColorAlpha; } void setBackgroundVisible( BOOL b ) { mBgVisible = b; } + BOOL isBackgroundVisible() const { return mBgVisible; } void setBackgroundOpaque(BOOL b) { mBgOpaque = b; } + BOOL isBackgroundOpaque() const { return mBgOpaque; } void setDefaultBtn(LLButton* btn = NULL); void setDefaultBtn(const LLString& id); void setLabel(const LLStringExplicit& label) { mLabel = label; } LLString getLabel() const { return mLabel; } void setRectControl(const LLString& rect_control) { mRectControl.assign(rect_control); } + const LLString& getRectControl() const { return mRectControl; } void storeRectControl(); - - void setBorderVisible( BOOL b ); void setCtrlsEnabled(BOOL b); - virtual void clearCtrls(); - - LLViewHandle getHandle() { return mViewHandle; } - S32 getLastTabGroup() { return mLastTabGroup; } + LLHandle<LLPanel> getHandle() const { return mPanelHandle; } - LLView* getCtrlByNameAndType(const LLString& name, EWidgetType type); + S32 getLastTabGroup() const { return mLastTabGroup; } - static LLPanel* getPanelByHandle(LLViewHandle handle); + LLUICtrl* getCtrlByNameAndType(const LLString& name, EWidgetType type) const; - virtual const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; } + const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; } - virtual LLXMLNodePtr getXML(bool save_children = true) const; - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); void initChildrenXML(LLXMLNodePtr node, LLUICtrlFactory* factory); void setPanelParameters(LLXMLNodePtr node, LLView *parentp); - LLString getFormattedUIString(const LLString& name, const LLString::format_map_t& args = LLUIString::sNullArgs) const; + LLString getString(const LLString& name, const LLString::format_map_t& args = LLUIString::sNullArgs) const; LLUIString getUIString(const LLString& name) const; // ** Wrappers for setting child properties by name ** -TomY - // Override to set not found list - virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; - // LLView void childSetVisible(const LLString& name, bool visible); void childShow(const LLString& name) { childSetVisible(name, true); } @@ -182,9 +173,9 @@ public: void childSetColor(const LLString& id, const LLColor4& color); - LLCtrlSelectionInterface* childGetSelectionInterface(const LLString& id); - LLCtrlListInterface* childGetListInterface(const LLString& id); - LLCtrlScrollInterface* childGetScrollInterface(const LLString& id); + LLCtrlSelectionInterface* childGetSelectionInterface(const LLString& id) const; + LLCtrlListInterface* childGetListInterface(const LLString& id) const; + LLCtrlScrollInterface* childGetScrollInterface(const LLString& id) const; // This is the magic bullet for data-driven UI void childSetValue(const LLString& id, LLSD value); @@ -202,15 +193,15 @@ public: // LLTabContainer void childShowTab(const LLString& id, const LLString& tabname, bool visible = true); - LLPanel *childGetVisibleTab(const LLString& id); + LLPanel *childGetVisibleTab(const LLString& id) const; void childSetTabChangeCallback(const LLString& id, const LLString& tabname, void (*on_tab_clicked)(void*, bool), void *userdata); // LLTextBox void childSetWrappedText(const LLString& id, const LLString& text, bool visible = true); // LLTextBox/LLTextEditor/LLLineEditor - void childSetText(const LLString& id, const LLStringExplicit& text); - LLString childGetText(const LLString& id); + void childSetText(const LLString& id, const LLStringExplicit& text) { childSetValue(id, LLSD(text)); } + LLString childGetText(const LLString& id) const { return childGetValue(id).asString(); } // LLLineEditor void childSetKeystrokeCallback(const LLString& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data); @@ -225,16 +216,23 @@ public: void childNotFound(const LLString& id) const; void childDisplayNotFound(); - typedef std::queue<LLAlertInfo> alert_queue_t; - static alert_queue_t sAlertQueue; + static void alertXml(LLString label, LLString::format_map_t args = LLString::format_map_t()); + static BOOL nextAlert(LLAlertInfo &alert); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + +protected: + // Override to set not found list + LLButton* getDefaultButton() { return mDefaultBtn; } + LLCallbackMap::map_t mFactoryMap; - typedef std::map<LLString, LLUIString> ui_string_map_t; + // Override to set not found list: + virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; private: - // common constructor + // common construction logic void init(); - -protected: + + // From LLView virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group ); virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group); @@ -251,18 +249,20 @@ protected: BOOL mBgOpaque; LLViewBorder* mBorder; LLButton* mDefaultBtn; - LLCallbackMap::map_t mFactoryMap; LLString mLabel; S32 mLastTabGroup; + LLRootHandle<LLPanel> mPanelHandle; + typedef std::map<LLString, LLUIString> ui_string_map_t; ui_string_map_t mUIStrings; typedef std::map<LLString, EWidgetType> requirements_map_t; requirements_map_t mRequirements; - typedef std::map<LLViewHandle, LLPanel*> panel_map_t; - static panel_map_t sPanelMap; -}; + typedef std::queue<LLAlertInfo> alert_queue_t; + static alert_queue_t sAlertQueue; +}; // end class LLPanel + class LLLayoutStack : public LLView { @@ -280,37 +280,33 @@ public: /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; /*virtual*/ void removeCtrl(LLUICtrl* ctrl); - virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_LAYOUT_STACK; } - virtual LLString getWidgetTag() const { return LL_LAYOUT_STACK_TAG; } + virtual EWidgetType getWidgetType() const; + virtual LLString getWidgetTag() const; static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - S32 getMinWidth(); - S32 getMinHeight(); + S32 getMinWidth() const { return mMinWidth; } + S32 getMinHeight() const { return mMinHeight; } void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, S32 index = S32_MAX); void removePanel(LLPanel* panel); void updateLayout(BOOL force_resize = FALSE); -protected: - struct LLEmbeddedPanel; - - LLEmbeddedPanel* findEmbeddedPanel(LLPanel* panelp); +private: void calcMinExtents(); - S32 getMinStackSize(); - S32 getCurStackSize(); S32 getDefaultHeight(S32 cur_height); S32 getDefaultWidth(S32 cur_width); -protected: - eLayoutOrientation mOrientation; + const eLayoutOrientation mOrientation; + struct LLEmbeddedPanel; typedef std::vector<LLEmbeddedPanel*> e_panel_list_t; e_panel_list_t mPanels; + LLEmbeddedPanel* findEmbeddedPanel(LLPanel* panelp) const; S32 mMinWidth; S32 mMinHeight; S32 mPanelSpacing; -}; +}; // end class LLLayoutStack #endif diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 6fba415d35..8bda6780a2 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -29,9 +29,6 @@ * $/LicenseInfo$ */ -// An invisible view containing multiple mutually exclusive toggling -// buttons (usually radio buttons). Automatically handles the mutex -// condition by highlighting only one button at a time. #include "linden_common.h" @@ -45,6 +42,7 @@ #include "llui.h" #include "llfocusmgr.h" + LLRadioGroup::LLRadioGroup(const LLString& name, const LLRect& rect, const LLString& control_name, LLUICtrlCallback callback, @@ -73,7 +71,7 @@ void LLRadioGroup::init(BOOL border) if (border) { addChild( new LLViewBorder( "radio group border", - LLRect(0, mRect.getHeight(), mRect.getWidth(), 0), + LLRect(0, getRect().getHeight(), getRect().getWidth(), 0), LLViewBorder::BEVEL_NONE, LLViewBorder::STYLE_LINE, 1 ) ); @@ -146,11 +144,6 @@ void LLRadioGroup::setIndexEnabled(S32 index, BOOL enabled) } } -S32 LLRadioGroup::getSelectedIndex() const -{ - return mSelectedIndex; -} - BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event) { if (index < 0 || index >= (S32)mRadioButtons.size()) @@ -452,12 +445,12 @@ BOOL LLRadioGroup::setCurrentByID( const LLUUID& id ) return FALSE; } -LLUUID LLRadioGroup::getCurrentID() +LLUUID LLRadioGroup::getCurrentID() const { return LLUUID::null; } -BOOL LLRadioGroup::setSelectedByValue(LLSD value, BOOL selected) +BOOL LLRadioGroup::setSelectedByValue(const LLSD& value, BOOL selected) { S32 idx = 0; std::string value_string = value.asString(); @@ -480,7 +473,7 @@ LLSD LLRadioGroup::getSelectedValue() return getValue(); } -BOOL LLRadioGroup::isSelected(LLSD value) +BOOL LLRadioGroup::isSelected(const LLSD& value) const { S32 idx = 0; std::string value_string = value.asString(); @@ -510,13 +503,6 @@ BOOL LLRadioGroup::operateOnAll(EOperation op) } -LLRadioCtrl::LLRadioCtrl(const LLString& name, const LLRect& rect, const LLString& label, - const LLFontGL* font, void (*commit_callback)(LLUICtrl*, void*), void* callback_userdata) : - LLCheckBoxCtrl(name, rect, label, font, commit_callback, callback_userdata, FALSE, RADIO_STYLE) -{ - setTabStop(FALSE); -} - LLRadioCtrl::~LLRadioCtrl() { } diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h index 5db1baeaec..d35bd741d7 100644 --- a/indra/llui/llradiogroup.h +++ b/indra/llui/llradiogroup.h @@ -29,10 +29,6 @@ * $/LicenseInfo$ */ -// An invisible view containing multiple mutually exclusive toggling -// buttons (usually radio buttons). Automatically handles the mutex -// condition by highlighting only one button at a time. - #ifndef LL_LLRADIOGROUP_H #define LL_LLRADIOGROUP_H @@ -40,21 +36,30 @@ #include "llcheckboxctrl.h" #include "llctrlselectioninterface.h" -class LLFontGL; -// Radio controls are checkbox controls with use_radio_style true +/* + * A checkbox control with use_radio_style == true. + */ class LLRadioCtrl : public LLCheckBoxCtrl { public: - LLRadioCtrl(const LLString& name, const LLRect& rect, const LLString& label, - const LLFontGL* font = NULL, - void (*commit_callback)(LLUICtrl*, void*) = NULL, - void* callback_userdata = NULL); + LLRadioCtrl(const LLString& name, const LLRect& rect, const LLString& label, const LLFontGL* font = NULL, + void (*commit_callback)(LLUICtrl*, void*) = NULL, void* callback_userdata = NULL) : + LLCheckBoxCtrl(name, rect, label, font, commit_callback, callback_userdata, FALSE, RADIO_STYLE) + { + setTabStop(FALSE); + } /*virtual*/ ~LLRadioCtrl(); /*virtual*/ void setValue(const LLSD& value); }; + +/* + * An invisible view containing multiple mutually exclusive toggling + * buttons (usually radio buttons). Automatically handles the mutex + * condition by highlighting only one button at a time. + */ class LLRadioGroup : public LLUICtrl, public LLCtrlSelectionInterface { @@ -88,7 +93,7 @@ public: void setIndexEnabled(S32 index, BOOL enabled); // return the index value of the selected item - S32 getSelectedIndex() const; + S32 getSelectedIndex() const { return mSelectedIndex; } // set the index value programatically BOOL setSelectedIndex(S32 index, BOOL from_event = FALSE); @@ -97,8 +102,7 @@ public: virtual void setValue(const LLSD& value ); virtual LLSD getValue() const; - // Draw the group, but also fix the highlighting based on the - // control. + // Draw the group, but also fix the highlighting based on the control. void draw(); // You must use this method to add buttons to a radio group. @@ -106,8 +110,7 @@ public: // correctly. LLRadioCtrl* addRadioButton(const LLString& name, const LLString& label, const LLRect& rect, const LLFontGL* font); LLRadioCtrl* getRadioButton(const S32& index) { return mRadioButtons[index]; } - // Update the control as needed. Userdata must be a pointer to the - // button. + // Update the control as needed. Userdata must be a pointer to the button. static void onClickButton(LLUICtrl* radio, void* userdata); //======================================================================== @@ -120,14 +123,14 @@ public: /*virtual*/ BOOL selectNthItem( S32 index ) { return setSelectedIndex(index); } /*virtual*/ S32 getFirstSelectedIndex() const { return getSelectedIndex(); } /*virtual*/ BOOL setCurrentByID( const LLUUID& id ); - /*virtual*/ LLUUID getCurrentID(); // LLUUID::null if no items in menu - /*virtual*/ BOOL setSelectedByValue(LLSD value, BOOL selected); + /*virtual*/ LLUUID getCurrentID() const; // LLUUID::null if no items in menu + /*virtual*/ BOOL setSelectedByValue(const LLSD& value, BOOL selected); /*virtual*/ LLSD getSelectedValue(); - /*virtual*/ BOOL isSelected(LLSD value); + /*virtual*/ BOOL isSelected(const LLSD& value) const; /*virtual*/ BOOL operateOnSelection(EOperation op); /*virtual*/ BOOL operateOnAll(EOperation op); -protected: +private: // protected function shared by the two constructors. void init(BOOL border); diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp index ac8c47c91c..40346513cf 100644 --- a/indra/llui/llresizebar.cpp +++ b/indra/llui/llresizebar.cpp @@ -33,8 +33,6 @@ #include "llresizebar.h" -//#include "llviewermenu.h" -//#include "llviewerimagelist.h" #include "llmath.h" #include "llui.h" #include "llmenugl.h" @@ -87,7 +85,7 @@ LLResizeBar::LLResizeBar( const LLString& name, LLView* resizing_view, const LLR BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask) { - if( mEnabled ) + if( getEnabled() ) { // Route future Mouse messages here preemptively. (Release on mouse up.) // No handler needed for focus lost since this clas has no state that depends on it. @@ -119,15 +117,6 @@ BOOL LLResizeBar::handleMouseUp(S32 x, S32 y, MASK mask) return handled; } -EWidgetType LLResizeBar::getWidgetType() const -{ - return WIDGET_TYPE_RESIZE_BAR; -} - -LLString LLResizeBar::getWidgetTag() const -{ - return LL_RESIZE_BAR_TAG; -} BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask) { @@ -267,5 +256,34 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask) } return handled; +} // end LLResizeBar::handleHover + +BOOL LLResizeBar::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + LLRect orig_rect = mResizingView->getRect(); + LLRect scaled_rect = orig_rect; + + if (mSnappingEnabled) + { + switch( mSide ) + { + case LEFT: + mResizingView->findSnapEdge(scaled_rect.mLeft, LLCoordGL(0, 0), SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, S32_MAX); + break; + case TOP: + mResizingView->findSnapEdge(scaled_rect.mTop, LLCoordGL(0, 0), SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, S32_MAX); + break; + case RIGHT: + mResizingView->findSnapEdge(scaled_rect.mRight, LLCoordGL(0, 0), SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, S32_MAX); + break; + case BOTTOM: + mResizingView->findSnapEdge(scaled_rect.mBottom, LLCoordGL(0, 0), SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, S32_MAX); + break; + } + } + + mResizingView->reshape(scaled_rect.getWidth(), scaled_rect.getHeight()); + mResizingView->setOrigin(scaled_rect.mLeft, scaled_rect.mBottom); + return TRUE; } diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h index d040a8b229..a3fef1a28c 100644 --- a/indra/llui/llresizebar.h +++ b/indra/llui/llresizebar.h @@ -42,18 +42,19 @@ public: LLResizeBar(const LLString& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side ); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_RESIZE_BAR; } + virtual LLString getWidgetTag() const { return LL_RESIZE_BAR_TAG; } // virtual void draw(); No appearance virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); void setResizeLimits( S32 min_size, S32 max_size ) { mMinSize = min_size; mMaxSize = max_size; } void setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; } -protected: +private: S32 mDragLastScreenX; S32 mDragLastScreenY; S32 mLastMouseScreenX; @@ -61,13 +62,11 @@ protected: LLCoordGL mLastMouseDir; S32 mMinSize; S32 mMaxSize; - Side mSide; + const Side mSide; BOOL mSnappingEnabled; LLView* mResizingView; }; -const S32 RESIZE_BAR_HEIGHT = 3; - #endif // LL_RESIZEBAR_H diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp index 120323e7d1..36028a4513 100644 --- a/indra/llui/llresizehandle.cpp +++ b/indra/llui/llresizehandle.cpp @@ -75,23 +75,13 @@ LLResizeHandle::LLResizeHandle( const LLString& name, const LLRect& rect, S32 mi setSaveToXML(FALSE); } -EWidgetType LLResizeHandle::getWidgetType() const -{ - return WIDGET_TYPE_RESIZE_HANDLE; -} - -LLString LLResizeHandle::getWidgetTag() const -{ - return LL_RESIZE_HANDLE_TAG; -} - BOOL LLResizeHandle::handleMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; if( getVisible() && pointInHandle(x, y) ) { handled = TRUE; - if( mEnabled ) + if( getEnabled() ) { // Route future Mouse messages here preemptively. (Release on mouse up.) // No handler needed for focus lost since this clas has no state that depends on it. @@ -292,10 +282,12 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask) handled = TRUE; } - else - if( getVisible() && pointInHandle( x, y ) ) + else // don't have mouse capture { - handled = TRUE; + if( getVisible() && pointInHandle( x, y ) ) + { + handled = TRUE; + } } if( handled ) @@ -314,7 +306,8 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask) } return handled; -} +} // end handleHover + // assumes GL state is set for 2D void LLResizeHandle::draw() @@ -330,8 +323,8 @@ BOOL LLResizeHandle::pointInHandle( S32 x, S32 y ) { if( pointInView(x, y) ) { - const S32 TOP_BORDER = (mRect.getHeight() - RESIZE_BORDER_WIDTH); - const S32 RIGHT_BORDER = (mRect.getWidth() - RESIZE_BORDER_WIDTH); + const S32 TOP_BORDER = (getRect().getHeight() - RESIZE_BORDER_WIDTH); + const S32 RIGHT_BORDER = (getRect().getWidth() - RESIZE_BORDER_WIDTH); switch( mCorner ) { diff --git a/indra/llui/llresizehandle.h b/indra/llui/llresizehandle.h index 2701613192..34be319786 100644 --- a/indra/llui/llresizehandle.h +++ b/indra/llui/llresizehandle.h @@ -46,8 +46,8 @@ public: LLResizeHandle(const LLString& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner = RIGHT_BOTTOM ); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_RESIZE_HANDLE; } + virtual LLString getWidgetTag() const { return LL_RESIZE_HANDLE_TAG; } virtual void draw(); virtual BOOL handleHover(S32 x, S32 y, MASK mask); @@ -56,10 +56,9 @@ public: void setResizeLimits( S32 min_width, S32 min_height ) { mMinWidth = min_width; mMinHeight = min_height; } -protected: +private: BOOL pointInHandle( S32 x, S32 y ); -protected: S32 mDragLastScreenX; S32 mDragLastScreenY; S32 mLastMouseScreenX; @@ -68,7 +67,7 @@ protected: LLPointer<LLImageGL> mImage; S32 mMinWidth; S32 mMinHeight; - ECorner mCorner; + const ECorner mCorner; }; const S32 RESIZE_HANDLE_HEIGHT = 16; diff --git a/indra/llui/llresmgr.h b/indra/llui/llresmgr.h index be2a35513f..1a452f7381 100644 --- a/indra/llui/llresmgr.h +++ b/indra/llui/llresmgr.h @@ -29,8 +29,6 @@ * $/LicenseInfo$ */ -// NOTE: this is a MINIMAL implementation. The interface will remain, but the implementation will -// (when the time is right) become dynamic and probably use external files. #ifndef LL_LLRESMGR_H #define LL_LLRESMGR_H @@ -157,11 +155,10 @@ public: LLLocale(const LLString& locale_string); virtual ~LLLocale(); -public: static const LLString USER_LOCALE; static const LLString SYSTEM_LOCALE; -protected: +private: LLString mPrevLocaleString; }; diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index b106bb570d..056a94afb8 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -92,7 +92,7 @@ LLScrollbar::LLScrollbar( if( LLScrollbar::VERTICAL == mOrientation ) { - line_up_rect.setLeftTopAndSize( 0, mRect.getHeight(), SCROLLBAR_SIZE, SCROLLBAR_SIZE ); + line_up_rect.setLeftTopAndSize( 0, getRect().getHeight(), SCROLLBAR_SIZE, SCROLLBAR_SIZE ); line_up_img="UIImgBtnScrollUpOutUUID"; line_up_selected_img="UIImgBtnScrollUpInUUID"; @@ -107,7 +107,7 @@ LLScrollbar::LLScrollbar( line_up_img="UIImgBtnScrollLeftOutUUID"; line_up_selected_img="UIImgBtnScrollLeftInUUID"; - line_down_rect.setOriginAndSize( mRect.getWidth() - SCROLLBAR_SIZE, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE ); + line_down_rect.setOriginAndSize( getRect().getWidth() - SCROLLBAR_SIZE, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE ); line_down_img="UIImgBtnScrollRightOutUUID"; line_down_selected_img="UIImgBtnScrollRightInUUID"; } @@ -210,7 +210,7 @@ void LLScrollbar::updateThumbRect() const S32 THUMB_MIN_LENGTH = 16; - S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? mRect.getWidth() : mRect.getHeight(); + S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? getRect().getWidth() : getRect().getHeight(); S32 thumb_bg_length = window_length - 2 * SCROLLBAR_SIZE; S32 visible_lines = llmin( mDocSize, mPageSize ); S32 thumb_length = mDocSize ? llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH ) : thumb_bg_length; @@ -300,8 +300,8 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask) BOOL handled = FALSE; if( hasMouseCapture() ) { - S32 height = mRect.getHeight(); - S32 width = mRect.getWidth(); + S32 height = getRect().getHeight(); + S32 width = getRect().getWidth(); if( VERTICAL == mOrientation ) { @@ -408,13 +408,13 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask) mDocChanged = FALSE; return handled; -} +} // end handleHover BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks) { BOOL handled = FALSE; - if( getVisible() && mRect.localPointInRect( x, y ) ) + if( getVisible() && getRect().localPointInRect( x, y ) ) { if( getEnabled() ) { @@ -427,7 +427,7 @@ BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks) } BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, void *carge_data, EAcceptance *accept, LLString &tooltip_msg) + EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, LLString &tooltip_msg) { // enable this to get drag and drop to control scrollbars //if (!drop) @@ -436,7 +436,7 @@ BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, // S32 variable_lines = getDocPosMax(); // S32 pos = (VERTICAL == mOrientation) ? y : x; // S32 thumb_length = (VERTICAL == mOrientation) ? mThumbRect.getHeight() : mThumbRect.getWidth(); - // S32 thumb_track_length = (VERTICAL == mOrientation) ? (mRect.getHeight() - 2 * SCROLLBAR_SIZE) : (mRect.getWidth() - 2 * SCROLLBAR_SIZE); + // S32 thumb_track_length = (VERTICAL == mOrientation) ? (getRect().getHeight() - 2 * SCROLLBAR_SIZE) : (getRect().getWidth() - 2 * SCROLLBAR_SIZE); // S32 usable_track_length = thumb_track_length - thumb_length; // F32 ratio = (VERTICAL == mOrientation) ? F32(pos - SCROLLBAR_SIZE - thumb_length) / usable_track_length // : F32(pos - SCROLLBAR_SIZE) / usable_track_length; @@ -485,7 +485,7 @@ void LLScrollbar::draw() screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y); BOOL other_captor = gFocusMgr.getMouseCapture() && gFocusMgr.getMouseCapture() != this; - BOOL hovered = mEnabled && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y)); + BOOL hovered = getEnabled() && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y)); if (hovered) { mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f)); @@ -504,8 +504,8 @@ void LLScrollbar::draw() if (!rounded_rect_imagep) { gl_rect_2d(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0, - mOrientation == VERTICAL ? mRect.getHeight() - 2 * SCROLLBAR_SIZE : mRect.getHeight(), - mOrientation == HORIZONTAL ? mRect.getWidth() - 2 * SCROLLBAR_SIZE : mRect.getWidth(), + mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(), + mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(), mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, mTrackColor, TRUE); gl_rect_2d(mThumbRect, mThumbColor, TRUE); @@ -518,8 +518,8 @@ void LLScrollbar::draw() mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, 16, 16, - mOrientation == HORIZONTAL ? mRect.getWidth() - 2 * SCROLLBAR_SIZE : mRect.getWidth(), - mOrientation == VERTICAL ? mRect.getHeight() - 2 * SCROLLBAR_SIZE : mRect.getHeight(), + mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(), + mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(), rounded_rect_imagep, mTrackColor, TRUE); @@ -553,7 +553,8 @@ void LLScrollbar::draw() // Draw children LLView::draw(); } -} +} // end draw + void LLScrollbar::changeLine( S32 delta, BOOL update_thumb ) { @@ -579,21 +580,12 @@ void LLScrollbar::setValue(const LLSD& value) setDocPos((S32) value.asInteger()); } -EWidgetType LLScrollbar::getWidgetType() const -{ - return WIDGET_TYPE_SCROLLBAR; -} - -LLString LLScrollbar::getWidgetTag() const -{ - return LL_SCROLLBAR_TAG; -} BOOL LLScrollbar::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) { BOOL handled = FALSE; - if( getVisible() && mEnabled && !called_from_parent ) + if( getVisible() && getEnabled() && !called_from_parent ) { switch( key ) { @@ -661,3 +653,4 @@ void LLScrollbar::onLineDownBtnPressed( void* userdata ) self->changeLine( self->mStepSize, TRUE ); } + diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index 50aa3cafe9..ac0bd37e3a 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -61,8 +61,9 @@ public: virtual ~LLScrollbar(); virtual void setValue(const LLSD& value); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SCROLLBAR; } + virtual LLString getWidgetTag() const { return LL_SCROLLBAR_TAG; } // Overrides from LLView virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); @@ -71,32 +72,33 @@ public: virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, void *carge_data, EAcceptance *accept, LLString &tooltip_msg); + EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, LLString &tooltip_msg); virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); virtual void draw(); - void setDocParams( S32 size, S32 pos ); - // How long the "document" is. void setDocSize( S32 size ); - S32 getDocSize() { return mDocSize; } + S32 getDocSize() const { return mDocSize; } // How many "lines" the "document" has scrolled. // 0 <= DocPos <= DocSize - DocVisibile void setDocPos( S32 pos ); - S32 getDocPos() { return mDocPos; } + S32 getDocPos() const { return mDocPos; } BOOL isAtBeginning(); BOOL isAtEnd(); + // Setting both at once. + void setDocParams( S32 size, S32 pos ); + // How many "lines" of the "document" is can appear on a page. void setPageSize( S32 page_size ); - S32 getPageSize() { return mPageSize; } + S32 getPageSize() const { return mPageSize; } // The farthest the document can be scrolled (top of the last page). - S32 getDocPosMax() { return llmax( 0, mDocSize - mPageSize); } + S32 getDocPosMax() const { return llmax( 0, mDocSize - mPageSize); } void pageUp(S32 overlap); void pageDown(S32 overlap); @@ -110,15 +112,15 @@ public: void setShadowColor( const LLColor4& color ) { mShadowColor = color; } void setOnScrollEndCallback(void (*callback)(void*), void* userdata) { mOnScrollEndCallback = callback; mOnScrollEndData = userdata;} -protected: + +private: void updateThumbRect(); void changeLine(S32 delta, BOOL update_thumb ); -protected: void (*mChangeCallback)( S32 new_pos, LLScrollbar* self, void* userdata ); void* mCallbackUserData; - ORIENTATION mOrientation; + const ORIENTATION mOrientation; S32 mDocSize; // Size of the document that the scrollbar is modeling. Units depend on the user. 0 <= mDocSize. S32 mDocPos; // Position within the doc that the scrollbar is modeling, in "lines" (user size) S32 mPageSize; // Maximum number of lines that can be seen at one time. diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 34a29cef51..b9d5141eb7 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -29,14 +29,6 @@ * $/LicenseInfo$ */ -//***************************************************************************** -// -// A view meant to encapsulate a clipped region which is -// scrollable. It automatically takes care of pixel perfect scrolling -// and cliipping, as well as turning the scrollbars on or off based on -// the width and height of the view you're scrolling. -// -//***************************************************************************** #include "linden_common.h" @@ -112,11 +104,11 @@ LLScrollableContainerView::LLScrollableContainerView( const LLString& name, cons void LLScrollableContainerView::init() { - LLRect border_rect( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 ); mBorder = new LLViewBorder( "scroll border", border_rect, LLViewBorder::BEVEL_IN ); addChild( mBorder ); - mInnerRect.set( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 ); mInnerRect.stretch( -mBorder->getBorderWidth() ); LLRect vertical_scroll_rect = mInnerRect; @@ -165,25 +157,6 @@ LLScrollableContainerView::~LLScrollableContainerView( void ) mScrolledView = NULL; } -/* -// scrollbar handlers -void LLScrollableContainerView::horizontalChange( S32 new_pos, - LLScrollbar* sb, - void* user_data ) -{ - LLScrollableContainerView* cont = reinterpret_cast<LLScrollableContainerView*>(user_data); -// cont->scrollHorizontal( new_pos ); -} - - -void LLScrollableContainerView::verticalChange( S32 new_pos, LLScrollbar* sb, - void* user_data ) -{ - LLScrollableContainerView* cont = reinterpret_cast<LLScrollableContainerView*>(user_data); -// cont->scrollVertical( new_pos ); -} -*/ - // internal scrollbar handlers // virtual void LLScrollableContainerView::scrollHorizontal( S32 new_pos ) @@ -215,7 +188,7 @@ void LLScrollableContainerView::reshape(S32 width, S32 height, { LLUICtrl::reshape( width, height, called_from_parent ); - mInnerRect.set( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 ); mInnerRect.stretch( -mBorder->getBorderWidth() ); if (mScrolledView) @@ -238,7 +211,7 @@ void LLScrollableContainerView::reshape(S32 width, S32 height, BOOL LLScrollableContainerView::handleKey( KEY key, MASK mask, BOOL called_from_parent ) { - if( getVisible() && mEnabled ) + if( getVisible() && getEnabled() ) { if( called_from_parent ) { @@ -278,7 +251,7 @@ BOOL LLScrollableContainerView::handleKey( KEY key, MASK mask, BOOL called_from_ BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks ) { - if( mEnabled ) + if( getEnabled() ) { for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) { @@ -295,7 +268,8 @@ BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks ) // Opaque return TRUE; } -BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) + +BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) const { if(mScrollbar[axis]->getVisible()) { @@ -315,6 +289,7 @@ BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContaine } return FALSE; } + BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, @@ -419,19 +394,19 @@ BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, LLString& msg, LLRec return TRUE; } -void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) +void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { const LLRect& rect = mScrolledView->getRect(); calcVisibleSize(rect, visible_width, visible_height, show_h_scrollbar, show_v_scrollbar); } -void LLScrollableContainerView::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) +void LLScrollableContainerView::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { S32 doc_width = doc_rect.getWidth(); S32 doc_height = doc_rect.getHeight(); - *visible_width = mRect.getWidth() - 2 * mBorder->getBorderWidth(); - *visible_height = mRect.getHeight() - 2 * mBorder->getBorderWidth(); + *visible_width = getRect().getWidth() - 2 * mBorder->getBorderWidth(); + *visible_height = getRect().getHeight() - 2 * mBorder->getBorderWidth(); *show_v_scrollbar = FALSE; if( *visible_height < doc_height ) @@ -544,7 +519,7 @@ void LLScrollableContainerView::draw() drawDebugRect(); } } -} +} // end draw void LLScrollableContainerView::updateScroll() { @@ -560,9 +535,9 @@ void LLScrollableContainerView::updateScroll() S32 border_width = mBorder->getBorderWidth(); if( show_v_scrollbar ) { - if( doc_rect.mTop < mRect.getHeight() - border_width ) + if( doc_rect.mTop < getRect().getHeight() - border_width ) { - mScrolledView->translate( 0, mRect.getHeight() - border_width - doc_rect.mTop ); + mScrolledView->translate( 0, getRect().getHeight() - border_width - doc_rect.mTop ); } scrollVertical( mScrollbar[VERTICAL]->getDocPos() ); @@ -587,7 +562,7 @@ void LLScrollableContainerView::updateScroll() } else { - mScrolledView->translate( 0, mRect.getHeight() - border_width - doc_rect.mTop ); + mScrolledView->translate( 0, getRect().getHeight() - border_width - doc_rect.mTop ); mScrollbar[VERTICAL]->setVisible( FALSE ); mScrollbar[VERTICAL]->setDocPos( 0 ); @@ -626,7 +601,7 @@ void LLScrollableContainerView::updateScroll() mScrollbar[VERTICAL]->setDocSize( doc_height ); mScrollbar[VERTICAL]->setPageSize( visible_height ); -} +} // end updateScroll void LLScrollableContainerView::setBorderVisible(BOOL b) { @@ -723,7 +698,7 @@ void LLScrollableContainerView::goToBottom() mScrollbar[VERTICAL]->setDocPos(mScrollbar[VERTICAL]->getDocSize()); } -S32 LLScrollableContainerView::getBorderWidth() +S32 LLScrollableContainerView::getBorderWidth() const { if (mBorder) { @@ -803,7 +778,3 @@ LLView* LLScrollableContainerView::fromXML(LLXMLNodePtr node, LLView *parent, LL return ret; } - -///---------------------------------------------------------------------------- -/// Local function definitions -///---------------------------------------------------------------------------- diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index 9f1978be97..0bffd0438f 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -40,21 +40,18 @@ #include "llcoord.h" #include "llscrollbar.h" -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLScrollableContainerView -// -// A view meant to encapsulate a clipped region which is -// scrollable. It automatically takes care of pixel perfect scrolling -// and cliipping, as well as turning the scrollbars on or off based on -// the width and height of the view you're scrolling. -// -// This class is a decorator class. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLViewBorder; class LLUICtrlFactory; - +/***************************************************************************** + * + * A decorator view class meant to encapsulate a clipped region which is + * scrollable. It automatically takes care of pixel perfect scrolling + * and cliipping, as well as turning the scrollbars on or off based on + * the width and height of the view you're scrolling. + * + *****************************************************************************/ class LLScrollableContainerView : public LLUICtrl { public: @@ -70,32 +67,26 @@ public: const LLColor4& bg_color = LLColor4(0,0,0,0) ); virtual ~LLScrollableContainerView( void ); - void init(); - void setScrolledView(LLView* view) { mScrolledView = view; } virtual void setValue(const LLSD& value) { mInnerRect.setValue(value); } virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SCROLL_CONTAINER; } virtual LLString getWidgetTag() const { return LL_SCROLLABLE_CONTAINER_VIEW_TAG; } - // scrollbar handlers - static void horizontalChange( S32 new_pos, LLScrollbar* sb, void* user_data ); - static void verticalChange( S32 new_pos, LLScrollbar* sb, void* user_data ); - - void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ); - void calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ); + void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const; + void calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const; void setBorderVisible( BOOL b ); void scrollToShowRect( const LLRect& rect, const LLCoordGL& desired_offset ); void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; } - const LLRect& getScrolledViewRect() { return mScrolledView->getRect(); } + const LLRect& getScrolledViewRect() const { return mScrolledView->getRect(); } void pageUp(S32 overlap = 0); void pageDown(S32 overlap = 0); void goToTop(); void goToBottom(); - S32 getBorderWidth(); + S32 getBorderWidth() const; - BOOL needsToScroll(S32 x, S32 y, SCROLL_ORIENTATION axis); + BOOL needsToScroll(S32 x, S32 y, SCROLL_ORIENTATION axis) const; // LLView functionality virtual void reshape(S32 width, S32 height, BOOL called_from_parent); @@ -113,7 +104,9 @@ public: virtual LLXMLNodePtr getXML(bool save_children = true) const; static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); -protected: +private: + void init(); + // internal scrollbar handlers virtual void scrollHorizontal( S32 new_pos ); virtual void scrollVertical( S32 new_pos ); diff --git a/indra/llui/llscrollingpanellist.cpp b/indra/llui/llscrollingpanellist.cpp index 76389e17b4..70309ba6bc 100644 --- a/indra/llui/llscrollingpanellist.cpp +++ b/indra/llui/llscrollingpanellist.cpp @@ -126,20 +126,6 @@ void LLScrollingPanelList::updatePanelVisiblilty() } } -void LLScrollingPanelList::setValue(const LLSD& value) -{ - -} - -EWidgetType LLScrollingPanelList::getWidgetType() const -{ - return WIDGET_TYPE_SCROLLING_PANEL_LIST; -} - -LLString LLScrollingPanelList::getWidgetTag() const -{ - return LL_SCROLLING_PANEL_LIST_TAG; -} void LLScrollingPanelList::draw() { @@ -165,9 +151,3 @@ LLView* LLScrollingPanelList::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtr return scrolling_panel_list; } -// virtual -LLXMLNodePtr LLScrollingPanelList::getXML(bool save_children) const -{ - LLXMLNodePtr node = LLUICtrl::getXML(); - return node; -} diff --git a/indra/llui/llscrollingpanellist.h b/indra/llui/llscrollingpanellist.h index f697a99a06..cb832f4bec 100644 --- a/indra/llui/llscrollingpanellist.h +++ b/indra/llui/llscrollingpanellist.h @@ -35,30 +35,31 @@ #include "llview.h" #include "llpanel.h" -// virtual class for scrolling panels +/* + * Pure virtual class represents a scrolling panel. + */ class LLScrollingPanel : public LLPanel { public: - LLScrollingPanel(const LLString& name, const LLRect& rect) - : LLPanel(name, rect) - { - } + LLScrollingPanel(const LLString& name, const LLRect& rect) : LLPanel(name, rect) { } virtual void updatePanel(BOOL allow_modify) = 0; - }; - -// A set of panels that are displayed in a vertical sequence inside a scroll container. + + +/* + * A set of panels that are displayed in a vertical sequence inside a scroll container. + */ class LLScrollingPanelList : public LLUICtrl { public: LLScrollingPanelList(const LLString& name, const LLRect& rect) : LLUICtrl(name, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_BOTTOM ) {} - virtual void setValue(const LLSD& value); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual void setValue(const LLSD& value) {}; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SCROLLING_PANEL_LIST; } + virtual LLString getWidgetTag() const { return LL_SCROLLING_PANEL_LIST_TAG; } - virtual LLXMLNodePtr getXML(bool save_children) const; + virtual LLXMLNodePtr getXML(bool save_children) const { return LLUICtrl::getXML(); } virtual void draw(); @@ -68,9 +69,8 @@ public: static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); -protected: +private: void updatePanelVisiblilty(); -protected: std::deque<LLScrollingPanel*> mPanelList; }; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 9d38bd0dab..94053980e6 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1,4 +1,4 @@ -/** + /** * @file llscrolllistctrl.cpp * @brief LLScrollListCtrl base class * @@ -126,7 +126,7 @@ LLScrollListIcon::~LLScrollListIcon() { } -void LLScrollListIcon::setValue(LLSD value) +void LLScrollListIcon::setValue(const LLSD& value) { mImageUUID = value.asUUID(); // don't use default image specified by LLUUID::null, use no image in that case @@ -142,11 +142,11 @@ void LLScrollListIcon::setColor(const LLColor4& color) S32 LLScrollListIcon::getWidth() const { // if no specified fix width, use width of icon - if (mWidth == 0) + if (LLScrollListCell::getWidth() == 0) { return mIcon->getWidth(); } - return mWidth; + return LLScrollListCell::getWidth(); } @@ -170,11 +170,11 @@ LLScrollListCheck::LLScrollListCheck(LLCheckBoxCtrl* check_box, S32 width) rect.mRight = rect.mLeft + width; mCheckBox->setRect(rect); - mWidth = width; + setWidth(width); } else { - mWidth = rect.getWidth(); //check_box->getWidth(); + setWidth(rect.getWidth()); //check_box->getWidth(); } } @@ -271,6 +271,12 @@ void LLScrollListText::setText(const LLStringExplicit& text) mText = text; } +//virtual +void LLScrollListText::setValue(const LLSD& text) +{ + setText(text.asString()); +} + void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_color) const { const LLColor4* display_color; @@ -373,7 +379,7 @@ void LLScrollListItem::setColumn( S32 column, LLScrollListCell *cell ) } } -LLString LLScrollListItem::getContentsCSV() +LLString LLScrollListItem::getContentsCSV() const { LLString ret; @@ -547,8 +553,8 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, mItemListRect.setOriginAndSize( mBorderThickness + LIST_BORDER_PAD, mBorderThickness + LIST_BORDER_PAD, - mRect.getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ), - mRect.getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) ); + getRect().getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ), + getRect().getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) ); updateLineHeight(); @@ -557,7 +563,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, // Init the scrollbar LLRect scroll_rect; scroll_rect.setOriginAndSize( - mRect.getWidth() - mBorderThickness - SCROLLBAR_SIZE, + getRect().getWidth() - mBorderThickness - SCROLLBAR_SIZE, mItemListRect.mBottom, SCROLLBAR_SIZE, mItemListRect.getHeight()); @@ -578,7 +584,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, // Border if (show_border) { - LLRect border_rect( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 ); mBorder = new LLViewBorder( "dlg border", border_rect, LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, 1 ); addChild(mBorder); } @@ -745,8 +751,8 @@ void LLScrollListCtrl::updateLayout() mItemListRect.setOriginAndSize( mBorderThickness + LIST_BORDER_PAD, mBorderThickness + LIST_BORDER_PAD, - mRect.getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ), - mRect.getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) - heading_size ); + getRect().getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ), + getRect().getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) - heading_size ); // how many lines of content in a single "page" mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0; @@ -754,7 +760,7 @@ void LLScrollListCtrl::updateLayout() if (scrollbar_visible) { // provide space on the right for scrollbar - mItemListRect.mRight = mRect.getWidth() - ( mBorderThickness + LIST_BORDER_PAD ) - SCROLLBAR_SIZE; + mItemListRect.mRight = getRect().getWidth() - ( mBorderThickness + LIST_BORDER_PAD ) - SCROLLBAR_SIZE; } mScrollbar->reshape(SCROLLBAR_SIZE, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0)); @@ -770,7 +776,7 @@ void LLScrollListCtrl::updateLayout() void LLScrollListCtrl::fitContents(S32 max_width, S32 max_height) { S32 height = llmin( getRequiredRect().getHeight(), max_height ); - S32 width = mRect.getWidth(); + S32 width = getRect().getWidth(); reshape( width, height ); } @@ -782,7 +788,7 @@ LLRect LLScrollListCtrl::getRequiredRect() S32 height = (mLineHeight * getItemCount()) + (2 * ( mBorderThickness + LIST_BORDER_PAD )) + heading_size; - S32 width = mRect.getWidth(); + S32 width = getRect().getWidth(); return LLRect(0, height, width, 0); } @@ -1221,10 +1227,10 @@ S32 LLScrollListCtrl::selectMultiple( LLDynamicArray<LLUUID> ids ) return count; } -S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) +S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) const { S32 index = 0; - item_list::iterator iter; + item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem *itemp = *iter; @@ -1237,10 +1243,10 @@ S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) return -1; } -S32 LLScrollListCtrl::getItemIndex( LLUUID& target_id ) +S32 LLScrollListCtrl::getItemIndex( LLUUID& target_id ) const { S32 index = 0; - item_list::iterator iter; + item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem *itemp = *iter; @@ -1542,7 +1548,7 @@ BOOL LLScrollListCtrl::selectByID( const LLUUID& id ) return selectByValue( LLSD(id) ); } -BOOL LLScrollListCtrl::setSelectedByValue(LLSD value, BOOL selected) +BOOL LLScrollListCtrl::setSelectedByValue(const LLSD& value, BOOL selected) { BOOL found = FALSE; @@ -1575,9 +1581,9 @@ BOOL LLScrollListCtrl::setSelectedByValue(LLSD value, BOOL selected) return found; } -BOOL LLScrollListCtrl::isSelected(LLSD value) +BOOL LLScrollListCtrl::isSelected(const LLSD& value) const { - item_list::iterator iter; + item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem* item = *iter; @@ -1589,7 +1595,7 @@ BOOL LLScrollListCtrl::isSelected(LLSD value) return FALSE; } -LLUUID LLScrollListCtrl::getStringUUIDSelectedItem() +LLUUID LLScrollListCtrl::getStringUUIDSelectedItem() const { LLScrollListItem* item = getFirstSelected(); @@ -1715,7 +1721,7 @@ void LLScrollListCtrl::draw() scrollToShowSelected(); mNeedsScroll = FALSE; } - LLRect background(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0); // Draw background if (mBackgroundVisible) { @@ -2452,16 +2458,6 @@ void LLScrollListCtrl::commitIfChanged() } } -void LLScrollListCtrl::setSorted(BOOL sorted) -{ - mSorted = sorted; -} - -BOOL LLScrollListCtrl::isSorted() -{ - return mSorted; -} - struct SameSortColumn { SameSortColumn(S32 column) : mColumn(column) {} @@ -2538,7 +2534,7 @@ void LLScrollListCtrl::sortItems() setSorted(TRUE); } -S32 LLScrollListCtrl::getScrollPos() +S32 LLScrollListCtrl::getScrollPos() const { return mScrollbar->getDocPos(); } @@ -2884,7 +2880,7 @@ void LLScrollListCtrl::copy() } // virtual -BOOL LLScrollListCtrl::canCopy() +BOOL LLScrollListCtrl::canCopy() const { return (getFirstSelected() != NULL); } @@ -2897,25 +2893,12 @@ void LLScrollListCtrl::cut() } // virtual -BOOL LLScrollListCtrl::canCut() +BOOL LLScrollListCtrl::canCut() const { return canCopy() && canDoDelete(); } // virtual -void LLScrollListCtrl::doDelete() -{ - // Not yet implemented -} - -// virtual -BOOL LLScrollListCtrl::canDoDelete() -{ - // Not yet implemented - return FALSE; -} - -// virtual void LLScrollListCtrl::selectAll() { // Deselects all other items @@ -2936,7 +2919,7 @@ void LLScrollListCtrl::selectAll() } // virtual -BOOL LLScrollListCtrl::canSelectAll() +BOOL LLScrollListCtrl::canSelectAll() const { return getCanSelect() && mAllowMultipleSelection && !(mMaxSelectable > 0 && mItemList.size() > mMaxSelectable); } @@ -2948,7 +2931,7 @@ void LLScrollListCtrl::deselect() } // virtual -BOOL LLScrollListCtrl::canDeselect() +BOOL LLScrollListCtrl::canDeselect() const { return getCanSelect(); } @@ -3039,7 +3022,7 @@ void LLScrollListCtrl::onClickColumn(void *userdata) LLScrollListCtrl *parent = info->mParentCtrl; if (!parent) return; - U32 column_index = info->mIndex; + S32 column_index = info->mIndex; LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex]; bool ascending = column->mSortAscending; @@ -3412,14 +3395,14 @@ LLColumnHeader::LLColumnHeader(const LLString& label, const LLRect &rect, LLScro mAscendingText = "[LOW]...[HIGH](Ascending)"; mDescendingText = "[HIGH]...[LOW](Descending)"; - mList->reshape(llmax(mList->getRect().getWidth(), 110, mRect.getWidth()), mList->getRect().getHeight()); + mList->reshape(llmax(mList->getRect().getWidth(), 110, getRect().getWidth()), mList->getRect().getHeight()); // resize handles on left and right const S32 RESIZE_BAR_THICKNESS = 3; mResizeBar = new LLResizeBar( "resizebar", this, - LLRect( mRect.getWidth() - RESIZE_BAR_THICKNESS, mRect.getHeight(), mRect.getWidth(), 0), + LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0), MIN_COLUMN_WIDTH, S32_MAX, LLResizeBar::RIGHT ); addChild(mResizeBar); @@ -3440,10 +3423,10 @@ void LLColumnHeader::draw() mButton->setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, draw_arrow ? LLColor4::white : LLColor4::transparent); mArrowImage = mButton->getImageOverlay()->getImage(); - //BOOL clip = mRect.mRight > mColumn->mParentCtrl->getItemListRect().getWidth(); + //BOOL clip = getRect().mRight > mColumn->mParentCtrl->getItemListRect().getWidth(); //LLGLEnable scissor_test(clip ? GL_SCISSOR_TEST : GL_FALSE); - //LLRect column_header_local_rect(-mRect.mLeft, mRect.getHeight(), mColumn->mParentCtrl->getItemListRect().getWidth() - mRect.mLeft, 0); + //LLRect column_header_local_rect(-getRect().mLeft, getRect().getHeight(), mColumn->mParentCtrl->getItemListRect().getWidth() - getRect().mLeft, 0); //LLUI::setScissorRegionLocal(column_header_local_rect); // Draw children @@ -3587,13 +3570,13 @@ void LLColumnHeader::showList() S32 text_width = LLFontGL::sSansSerifSmall->getWidth(ascending_string); text_width = llmax(text_width, LLFontGL::sSansSerifSmall->getWidth(descending_string)) + 10; - text_width = llmax(text_width, mRect.getWidth() - 30); + text_width = llmax(text_width, getRect().getWidth() - 30); mList->getColumn(0)->mWidth = text_width; ((LLScrollListText*)mList->getFirstData()->getColumn(0))->setText(ascending_string); ((LLScrollListText*)mList->getLastData()->getColumn(0))->setText(descending_string); - mList->reshape(llmax(text_width + 30, 110, mRect.getWidth()), mList->getRect().getHeight()); + mList->reshape(llmax(text_width + 30, 110, getRect().getWidth()), mList->getRect().getHeight()); LLComboBox::showList(); } @@ -3666,7 +3649,7 @@ LLView* LLColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_d void LLColumnHeader::userSetShape(const LLRect& new_rect) { S32 new_width = new_rect.getWidth(); - S32 delta_width = new_width - (mRect.getWidth() + mColumn->mParentCtrl->getColumnPadding()); + S32 delta_width = new_width - getRect().getWidth(); if (delta_width != 0) { @@ -3726,7 +3709,7 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect) } // propagate constrained delta_width to new width for this column - new_width = mRect.getWidth() + delta_width - mColumn->mParentCtrl->getColumnPadding(); + new_width = getRect().getWidth() + delta_width - mColumn->mParentCtrl->getColumnPadding(); // use requested width mColumn->mWidth = new_width; diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index aa0af7dcd8..d889512ee6 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -1,6 +1,5 @@ /** * @file llscrolllistctrl.h - * @brief LLScrollListCtrl base class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -43,16 +42,20 @@ #include "llstring.h" #include "llimagegl.h" #include "lleditmenuhandler.h" -#include "llviewborder.h" #include "llframetimer.h" #include "llcheckboxctrl.h" #include "llcombobox.h" +#include "llscrollbar.h" +#include "llresizebar.h" -class LLScrollbar; -class LLScrollListCtrl; -class LLColumnHeader; -class LLResizeBar; - +/* + * Represents a cell in a scrollable table. + * + * Sub-classes must return height and other properties + * though width accessors are implemented by the base class. + * It is therefore important for sub-class constructors to call + * setWidth() with realistic values. + */ class LLScrollListCell { public: @@ -63,21 +66,24 @@ public: virtual S32 getContentWidth() const { return 0; } virtual S32 getHeight() const = 0; virtual const LLSD getValue() const { return LLString::null; } - virtual void setValue(LLSD value) { } + virtual void setValue(const LLSD& value) { } virtual BOOL getVisible() const { return TRUE; } virtual void setWidth(S32 width) { mWidth = width; } virtual void highlightText(S32 offset, S32 num_chars) {} - virtual BOOL isText() = 0; + virtual BOOL isText() const = 0; virtual void setColor(const LLColor4&) {} virtual void onCommit() {}; - virtual BOOL handleClick() { return FALSE; } - virtual void setEnabled(BOOL enable) { } + virtual BOOL handleClick() { return FALSE; } + virtual void setEnabled(BOOL enable) { } -protected: +private: S32 mWidth; }; +/* + * Draws a horizontal line. + */ class LLScrollListSeparator : public LLScrollListCell { public: @@ -85,9 +91,12 @@ public: virtual ~LLScrollListSeparator() {}; virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; // truncate to given width, if possible virtual S32 getHeight() const { return 5; }; - virtual BOOL isText() { return FALSE; } + virtual BOOL isText() const { return FALSE; } }; +/* + * Cell displaying a text label. + */ class LLScrollListText : public LLScrollListCell { public: @@ -97,12 +106,13 @@ public: virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; virtual S32 getContentWidth() const; virtual S32 getHeight() const { return llround(mFont->getLineHeight()); } - virtual const LLSD getValue() const { return LLSD(mText.getString()); } + virtual void setValue(const LLSD& value); + virtual const LLSD getValue() const { return LLSD(mText.getString()); } virtual BOOL getVisible() const { return mVisible; } virtual void highlightText(S32 offset, S32 num_chars) {mHighlightOffset = offset; mHighlightCount = num_chars;} virtual void setColor(const LLColor4&); - virtual BOOL isText() { return TRUE; } + virtual BOOL isText() const { return TRUE; } void setText(const LLStringExplicit& text); void setFontStyle(const U8 font_style) { mFontStyle = font_style; } @@ -122,6 +132,9 @@ private: static U32 sCount; }; +/* + * Cell displaying an image. + */ class LLScrollListIcon : public LLScrollListCell { public: @@ -133,8 +146,8 @@ public: // used as sort criterion virtual const LLSD getValue() const { return LLSD(mImageUUID); } virtual void setColor(const LLColor4&); - virtual BOOL isText() { return FALSE; } - virtual void setValue(LLSD value); + virtual BOOL isText()const { return FALSE; } + virtual void setValue(const LLSD& value); private: LLPointer<LLImageGL> mIcon; @@ -142,6 +155,9 @@ private: LLColor4 mColor; }; +/* + * An interactive cell containing a check box. + */ class LLScrollListCheck : public LLScrollListCell { public: @@ -150,19 +166,22 @@ public: virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; virtual S32 getHeight() const { return 0; } virtual const LLSD getValue() const { return mCheckBox->getValue(); } - virtual void setValue(LLSD value) { mCheckBox->setValue(value); } + virtual void setValue(const LLSD& value) { mCheckBox->setValue(value); } virtual void onCommit() { mCheckBox->onCommit(); } virtual BOOL handleClick(); virtual void setEnabled(BOOL enable) { mCheckBox->setEnabled(enable); } LLCheckBoxCtrl* getCheckBox() { return mCheckBox; } - virtual BOOL isText() { return FALSE; } + virtual BOOL isText() const { return FALSE; } private: LLCheckBoxCtrl* mCheckBox; }; +/* + * A simple data class describing a column within a scroll list. + */ class LLScrollListColumn { public: @@ -243,6 +262,9 @@ public: mHeader = NULL; } + // Public data is fine so long as this remains a simple struct-like data class. + // If it ever gets any smarter than that, these should all become private + // with protected or public accessor methods added as needed. -MG LLString mName; LLString mSortingColumn; BOOL mSortAscending; @@ -253,7 +275,7 @@ public: S32 mMaxContentWidth; S32 mIndex; LLScrollListCtrl* mParentCtrl; - LLColumnHeader* mHeader; + class LLColumnHeader* mHeader; LLFontGL::HAlign mFontAlignment; }; @@ -282,7 +304,7 @@ public: static void onMouseDown(void* user_data); static void onHeldDown(void* user_data); -protected: +private: LLScrollListColumn* mColumn; LLResizeBar* mResizeBar; LLString mOrigLabel; @@ -329,11 +351,11 @@ public: void setColumn( S32 column, LLScrollListCell *cell ); - S32 getNumColumns() const { return mColumns.size(); } + S32 getNumColumns() const { return mColumns.size(); } LLScrollListCell *getColumn(const S32 i) const { if (0 <= i && i < (S32)mColumns.size()) { return mColumns[i]; } return NULL; } - LLString getContentsCSV(); + LLString getContentsCSV() const; virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); @@ -345,6 +367,11 @@ private: std::vector<LLScrollListCell *> mColumns; }; +/* + * A graphical control representing a scrollable table. + * Cells in the table can be simple text or more complicated things + * such as icons or even interactive elements like check boxes. + */ class LLScrollListItemComment : public LLScrollListItem { public: @@ -419,7 +446,7 @@ public: // DEPRECATED: Use setSelectedByValue() below. BOOL setCurrentByID( const LLUUID& id ) { return selectByID(id); } - virtual LLUUID getCurrentID() { return getStringUUIDSelectedItem(); } + virtual LLUUID getCurrentID() const { return getStringUUIDSelectedItem(); } BOOL operateOnSelection(EOperation op); BOOL operateOnAll(EOperation op); @@ -431,11 +458,11 @@ public: // Match item by value.asString(), which should work for string, integer, uuid. // Returns FALSE if not found. - BOOL setSelectedByValue(LLSD value, BOOL selected); + BOOL setSelectedByValue(const LLSD& value, BOOL selected); - BOOL isSorted(); + BOOL isSorted() const { return mSorted; } - virtual BOOL isSelected(LLSD value); + virtual BOOL isSelected(const LLSD& value) const; BOOL handleClick(S32 x, S32 y, MASK mask); BOOL selectFirstItem(); @@ -458,8 +485,8 @@ public: void setCanSelect(BOOL can_select) { mCanSelect = can_select; } virtual BOOL getCanSelect() const { return mCanSelect; } - S32 getItemIndex( LLScrollListItem* item ); - S32 getItemIndex( LLUUID& item_id ); + S32 getItemIndex( LLScrollListItem* item ) const; + S32 getItemIndex( LLUUID& item_id ) const; LLScrollListItem* addCommentText( const LLString& comment_text, EAddPosition pos = ADD_BOTTOM); LLScrollListItem* addSeparator(EAddPosition pos); @@ -479,12 +506,11 @@ public: // "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which // has an associated, unique UUID, and only one of which can be selected at a time. LLScrollListItem* addStringUUIDItem(const LLString& item_text, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, S32 column_width = 0); - LLUUID getStringUUIDSelectedItem(); + LLUUID getStringUUIDSelectedItem() const; LLScrollListItem* getFirstSelected() const; virtual S32 getFirstSelectedIndex() const; std::vector<LLScrollListItem*> getAllSelected() const; - LLScrollListItem* getLastSelectedItem() const { return mLastSelected; } // iterate over all items @@ -517,7 +543,7 @@ public: S32 getMaxSelectable() { return mMaxSelectable; } - virtual S32 getScrollPos(); + virtual S32 getScrollPos() const; virtual void setScrollPos( S32 pos ); S32 getSearchColumn() { return mSearchColumn; } @@ -573,19 +599,13 @@ public: // LLEditMenuHandler functions virtual void copy(); - virtual BOOL canCopy(); - + virtual BOOL canCopy() const; virtual void cut(); - virtual BOOL canCut(); - - virtual void doDelete(); - virtual BOOL canDoDelete(); - + virtual BOOL canCut() const; virtual void selectAll(); - virtual BOOL canSelectAll(); - + virtual BOOL canSelectAll() const; virtual void deselect(); - virtual BOOL canDeselect(); + virtual BOOL canDeselect() const; void setNumDynamicColumns(int num) { mNumDynamicWidthColumns = num; } void setTotalStaticColumnWidth(int width) { mTotalStaticColumnWidth = width; } @@ -611,9 +631,14 @@ protected: // The LLScrollListCtrl owns its items and is responsible for deleting them // (except in the case that the addItem() call fails, in which case it is up // to the caller to delete the item) - + // // returns FALSE if item faile to be added to list, does NOT delete 'item' BOOL addItem( LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM, BOOL requires_column = TRUE ); + + typedef std::deque<LLScrollListItem *> item_list; + item_list& getItemList() { return mItemList; } + +private: void selectPrevItem(BOOL extend_selection); void selectNextItem(BOOL extend_selection); void drawItems(); @@ -624,10 +649,10 @@ protected: void selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE); void deselectItem(LLScrollListItem* itemp); void commitIfChanged(); - void setSorted(BOOL sorted); + void setSorted(BOOL sorted) { mSorted = sorted; } BOOL setSort(S32 column, BOOL ascending); -protected: + S32 mCurIndex; // For get[First/Next]Data S32 mCurSelectedIndex; // For get[First/Next]Selected @@ -646,7 +671,6 @@ protected: BOOL mCanSelect; BOOL mDisplayColumnHeaders; - typedef std::deque<LLScrollListItem *> item_list; item_list mItemList; LLScrollListItem *mLastSelected; @@ -675,7 +699,7 @@ protected: void (*mOnSortChangedCallback)(void* userdata); S32 mHighlightedItem; - LLViewBorder* mBorder; + class LLViewBorder* mBorder; LLWString mSearchString; LLFrameTimer mSearchTimer; @@ -697,15 +721,9 @@ protected: typedef std::pair<S32, BOOL> sort_column_t; std::vector<sort_column_t> mSortColumns; -public: // HACK: Did we draw one selected item this frame? BOOL mDrewSelected; -}; - -const BOOL MULTIPLE_SELECT_YES = TRUE; -const BOOL MULTIPLE_SELECT_NO = FALSE; +}; // end class LLScrollListCtrl -const BOOL SHOW_BORDER_YES = TRUE; -const BOOL SHOW_BORDER_NO = FALSE; #endif // LL_SCROLLLISTCTRL_H diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp index bd91d562aa..8b5bb1f3f6 100644 --- a/indra/llui/llslider.cpp +++ b/indra/llui/llslider.cpp @@ -82,15 +82,6 @@ LLSlider::LLSlider( mDragStartThumbRect = mThumbRect; } -EWidgetType LLSlider::getWidgetType() const -{ - return WIDGET_TYPE_SLIDER_BAR; -} - -LLString LLSlider::getWidgetTag() const -{ - return LL_SLIDER_TAG; -} void LLSlider::setValue(F32 value, BOOL from_event) { @@ -118,7 +109,7 @@ void LLSlider::updateThumbRect() S32 thumb_width = mThumbImage->getWidth(); S32 thumb_height = mThumbImage->getHeight(); S32 left_edge = (thumb_width / 2); - S32 right_edge = mRect.getWidth() - (thumb_width / 2); + S32 right_edge = getRect().getWidth() - (thumb_width / 2); S32 x = left_edge + S32( t * (right_edge - left_edge) ); mThumbRect.mLeft = x - (thumb_width / 2); @@ -140,18 +131,13 @@ void LLSlider::setValueAndCommit(F32 value) } -F32 LLSlider::getValueF32() const -{ - return mValue; -} - BOOL LLSlider::handleHover(S32 x, S32 y, MASK mask) { if( hasMouseCapture() ) { S32 thumb_half_width = mThumbImage->getWidth()/2; S32 left_edge = thumb_half_width; - S32 right_edge = mRect.getWidth() - (thumb_half_width); + S32 right_edge = getRect().getWidth() - (thumb_half_width); x += mMouseOffset; x = llclamp( x, left_edge, right_edge ); @@ -231,10 +217,10 @@ BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask) return TRUE; } -BOOL LLSlider::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) +BOOL LLSlider::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) { BOOL handled = FALSE; - if( getVisible() && mEnabled && !called_from_parent ) + if( getVisible() && getEnabled() && !called_from_parent ) { switch(key) { @@ -272,14 +258,14 @@ void LLSlider::draw() LLRect rect(mDragStartThumbRect); - F32 opacity = mEnabled ? 1.f : 0.3f; + F32 opacity = getEnabled() ? 1.f : 0.3f; LLColor4 center_color = (mThumbCenterColor % opacity); LLColor4 track_color = (mTrackColor % opacity); // Track LLRect track_rect(mThumbImage->getWidth() / 2, getLocalRect().getCenterY() + (mTrackImage->getHeight() / 2), - mRect.getWidth() - mThumbImage->getWidth() / 2, + getRect().getWidth() - mThumbImage->getWidth() / 2, getLocalRect().getCenterY() - (mTrackImage->getHeight() / 2) ); gl_draw_scaled_image_with_border(track_rect.mLeft, track_rect.mBottom, 3, 3, track_rect.getWidth(), track_rect.getHeight(), @@ -334,14 +320,14 @@ LLXMLNodePtr LLSlider::getXML(bool save_children) const node->createChild("min_val", TRUE)->setFloatValue(getMinValue()); node->createChild("max_val", TRUE)->setFloatValue(getMaxValue()); node->createChild("increment", TRUE)->setFloatValue(getIncrement()); - node->createChild("volume", TRUE)->setBoolValue(getVolumeSlider()); + node->createChild("volume", TRUE)->setBoolValue(mVolumeSlider); return node; } //static -LLView* LLSlider::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) +LLView* LLSlider::fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory) { LLString name("slider_bar"); node->getAttributeString("name", name); diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h index 55be2afbcc..6b1acfeaaa 100644 --- a/indra/llui/llslider.h +++ b/indra/llui/llslider.h @@ -35,7 +35,6 @@ #include "lluictrl.h" #include "v4color.h" -class LLUICtrlFactory; class LLImageGL; class LLSlider : public LLUICtrl @@ -50,16 +49,16 @@ public: F32 min_value, F32 max_value, F32 increment, - BOOL volume, + BOOL volume, //TODO: create a "volume" slider sub-class or just use image art, no? -MG const LLString& control_name = LLString::null ); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SLIDER_BAR; } + virtual LLString getWidgetTag() const { return LL_SLIDER_TAG; } virtual LLXMLNodePtr getXML(bool save_children = true) const; - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); void setValue( F32 value, BOOL from_event = FALSE ); - F32 getValueF32() const; + F32 getValueF32() const { return mValue; } virtual void setValue(const LLSD& value ) { setValue((F32)value.asReal(), TRUE); } virtual LLSD getValue() const { return LLSD(getValueF32()); } @@ -71,7 +70,6 @@ public: F32 getMinValue() const { return mMinValue; } F32 getMaxValue() const { return mMaxValue; } F32 getIncrement() const { return mIncrement; } - BOOL getVolumeSlider() const { return mVolumeSlider; } void setMinValue(F32 min_value) {mMinValue = min_value;} void setMaxValue(F32 max_value) {mMaxValue = max_value;} void setIncrement(F32 increment) {mIncrement = increment;} @@ -84,11 +82,10 @@ public: virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); virtual void draw(); -protected: +private: void setValueAndCommit(F32 value); void updateThumbRect(); -protected: F32 mValue; F32 mInitialValue; F32 mMinValue; diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index 3ff3a4f884..763be1d7e3 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -81,7 +81,7 @@ LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect, mSliderMouseUpCallback( NULL ), mSliderMouseDownCallback( NULL ) { - S32 top = mRect.getHeight(); + S32 top = getRect().getHeight(); S32 bottom = 0; S32 left = 0; @@ -97,7 +97,7 @@ LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect, addChild(mLabelBox); } - S32 slider_right = mRect.getWidth(); + S32 slider_right = getRect().getWidth(); if( show_text ) { slider_right = text_left - SLIDERCTRL_SPACING; @@ -115,7 +115,7 @@ LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect, if( show_text ) { - LLRect text_rect( text_left, top, mRect.getWidth(), bottom ); + LLRect text_rect( text_left, top, getRect().getWidth(), bottom ); if( can_edit_text ) { mEditor = new LLLineEditor( "SliderCtrl Editor", text_rect, @@ -144,10 +144,6 @@ LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect, updateText(); } -LLSliderCtrl::~LLSliderCtrl() -{ - // Children all cleaned up by default view destructor. -} // static void LLSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata ) @@ -158,10 +154,6 @@ void LLSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata self->onFocusReceived(); } -F32 LLSliderCtrl::getValueF32() const -{ - return mSlider->getValueF32(); -} void LLSliderCtrl::setValue(F32 v, BOOL from_event) { @@ -209,11 +201,6 @@ void LLSliderCtrl::clear() } -BOOL LLSliderCtrl::isMouseHeldDown() -{ - return mSlider->hasMouseCapture(); -} - void LLSliderCtrl::updateText() { if( mEditor || mTextBox ) @@ -427,18 +414,6 @@ void LLSliderCtrl::reportInvalidData() make_ui_sound("UISndBadKeystroke"); } -//virtual -LLString LLSliderCtrl::getControlName() const -{ - return mSlider->getControlName(); -} - -// virtual -void LLSliderCtrl::setControlName(const LLString& control_name, LLView* context) -{ - mSlider->setControlName(control_name, context); -} - // virtual LLXMLNodePtr LLSliderCtrl::getXML(bool save_children) const { diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h index de1c09639c..f154c230f4 100644 --- a/indra/llui/llsliderctrl.h +++ b/indra/llui/llsliderctrl.h @@ -1,6 +1,6 @@ /** * @file llsliderctrl.h - * @brief LLSliderCtrl base class + * @brief Decorated wrapper for a LLSlider. * * $LicenseInfo:firstyear=2002&license=viewergpl$ * @@ -44,13 +44,6 @@ const S32 SLIDERCTRL_SPACING = 4; // space between label, slider, and text const S32 SLIDERCTRL_HEIGHT = 16; -// -// Classes -// -class LLFontGL; -class LLLineEditor; -class LLSlider; - class LLSliderCtrl : public LLUICtrl { @@ -63,41 +56,41 @@ public: S32 text_left, BOOL show_text, BOOL can_edit_text, - BOOL volume, + BOOL volume, //TODO: create a "volume" slider sub-class or just use image art, no? -MG void (*commit_callback)(LLUICtrl*, void*), void* callback_userdata, F32 initial_value, F32 min_value, F32 max_value, F32 increment, const LLString& control_which = LLString::null ); - virtual ~LLSliderCtrl(); + virtual ~LLSliderCtrl() {} // Children all cleaned up by default view destructor. virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SLIDER; } virtual LLString getWidgetTag() const { return LL_SLIDER_CTRL_TAG; } virtual LLXMLNodePtr getXML(bool save_children = true) const; static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - F32 getValueF32() const; + F32 getValueF32() const { return mSlider->getValueF32(); } void setValue(F32 v, BOOL from_event = FALSE); - virtual void setValue(const LLSD& value ) { setValue((F32)value.asReal(), TRUE); } - virtual LLSD getValue() const { return LLSD(getValueF32()); } + virtual void setValue(const LLSD& value) { setValue((F32)value.asReal(), TRUE); } + virtual LLSD getValue() const { return LLSD(getValueF32()); } virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); } - virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); } + virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); } - BOOL isMouseHeldDown(); + BOOL isMouseHeldDown() const { return mSlider->hasMouseCapture(); } virtual void setEnabled( BOOL b ); virtual void clear(); virtual void setPrecision(S32 precision); - void setMinValue(F32 min_value) {mSlider->setMinValue(min_value);} - void setMaxValue(F32 max_value) {mSlider->setMaxValue(max_value);} - void setIncrement(F32 increment) {mSlider->setIncrement(increment);} + void setMinValue(F32 min_value) { mSlider->setMinValue(min_value); } + void setMaxValue(F32 max_value) { mSlider->setMaxValue(max_value); } + void setIncrement(F32 increment) { mSlider->setIncrement(increment); } F32 getMinValue() { return mSlider->getMinValue(); } F32 getMaxValue() { return mSlider->getMaxValue(); } - void setLabel(const LLStringExplicit& label) { if (mLabelBox) mLabelBox->setText(label); } + void setLabel(const LLStringExplicit& label) { if (mLabelBox) mLabelBox->setText(label); } void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; } void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; } @@ -109,8 +102,8 @@ public: virtual void setTentative(BOOL b); // marks value as tentative virtual void onCommit(); // mark not tentative, then commit - virtual void setControlName(const LLString& control_name, LLView* context); - virtual LLString getControlName() const; + virtual void setControlName(const LLString& control_name, LLView* context) { mSlider->setControlName(control_name, context); } + virtual LLString getControlName() const { return mSlider->getControlName(); } static void onSliderCommit(LLUICtrl* caller, void* userdata); static void onSliderMouseDown(LLUICtrl* caller,void* userdata); @@ -124,7 +117,6 @@ private: void updateText(); void reportInvalidData(); -private: const LLFontGL* mFont; BOOL mShowText; BOOL mCanEditText; @@ -136,7 +128,7 @@ private: F32 mValue; LLSlider* mSlider; - LLLineEditor* mEditor; + class LLLineEditor* mEditor; LLTextBox* mTextBox; LLColor4 mTextEnabledColor; diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index c4b7de768a..36f801c2e6 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -72,7 +72,7 @@ LLSpinCtrl::LLSpinCtrl( const LLString& name, const LLRect& rect, const LLString mTextDisabledColor( LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ), mbHasBeenSet( FALSE ) { - S32 top = mRect.getHeight(); + S32 top = getRect().getHeight(); S32 bottom = top - 2 * SPINCTRL_BTN_HEIGHT; S32 centered_top = top; S32 centered_bottom = bottom; @@ -121,7 +121,7 @@ LLSpinCtrl::LLSpinCtrl( const LLString& name, const LLRect& rect, const LLString mDownBtn->setTabStop(FALSE); addChild(mDownBtn); - LLRect editor_rect( btn_right + 1, centered_top, mRect.getWidth(), centered_bottom ); + LLRect editor_rect( btn_right + 1, centered_top, getRect().getWidth(), centered_bottom ); mEditor = new LLLineEditor( "SpinCtrl Editor", editor_rect, "", font, MAX_STRING_LENGTH, &LLSpinCtrl::onEditorCommit, NULL, NULL, this, @@ -140,11 +140,6 @@ LLSpinCtrl::LLSpinCtrl( const LLString& name, const LLRect& rect, const LLString setUseBoundingRect( TRUE ); } -LLSpinCtrl::~LLSpinCtrl() -{ - // Children all cleaned up by default view destructor. -} - F32 clamp_precision(F32 value, S32 decimal_precision) { @@ -253,10 +248,6 @@ void LLSpinCtrl::setValue(const LLSD& value ) } } -LLSD LLSpinCtrl::getValue() const -{ - return mValue; -} void LLSpinCtrl::clear() { @@ -356,7 +347,7 @@ void LLSpinCtrl::setTentative(BOOL b) } -BOOL LLSpinCtrl::isMouseHeldDown() +BOOL LLSpinCtrl::isMouseHeldDown() const { return mDownBtn->hasMouseCapture() @@ -366,9 +357,7 @@ BOOL LLSpinCtrl::isMouseHeldDown() void LLSpinCtrl::onCommit() { setTentative(FALSE); - setControlValue(mValue); - LLUICtrl::onCommit(); } @@ -412,7 +401,7 @@ void LLSpinCtrl::draw() { if( mLabelBox ) { - mLabelBox->setColor( mEnabled ? mTextEnabledColor : mTextDisabledColor ); + mLabelBox->setColor( getEnabled() ? mTextEnabledColor : mTextDisabledColor ); } LLUICtrl::draw(); } @@ -420,7 +409,7 @@ void LLSpinCtrl::draw() BOOL LLSpinCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks) { - if( mEnabled ) + if( getEnabled() ) { if( clicks > 0 ) { @@ -551,7 +540,3 @@ LLView* LLSpinCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory * return spinner; } -BOOL LLSpinCtrl::isDirty() const -{ - return( mValue != mInitialValue ); -} diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h index 5fc3ccdcc1..77a91f80c1 100644 --- a/indra/llui/llspinctrl.h +++ b/indra/llui/llspinctrl.h @@ -1,6 +1,6 @@ /** * @file llspinctrl.h - * @brief LLSpinCtrl base class + * @brief Typical spinner with "up" and "down" arrow buttons. * * $LicenseInfo:firstyear=2002&license=viewergpl$ * @@ -47,15 +47,6 @@ const S32 SPINCTRL_SPACING = 2; // space between label right and button const S32 SPINCTRL_HEIGHT = 2 * SPINCTRL_BTN_HEIGHT; const S32 SPINCTRL_DEFAULT_LABEL_WIDTH = 10; -// -// Classes -// -class LLFontGL; -class LLButton; -class LLTextBox; -class LLLineEditor; -class LLUICtrlFactory; - class LLSpinCtrl : public LLUICtrl @@ -70,26 +61,26 @@ public: const LLString& control_name = LLString(), S32 label_width = SPINCTRL_DEFAULT_LABEL_WIDTH ); - virtual ~LLSpinCtrl(); + virtual ~LLSpinCtrl() {} // Children all cleaned up by default view destructor. virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SPINNER; } virtual LLString getWidgetTag() const { return LL_SPIN_CTRL_TAG; } virtual LLXMLNodePtr getXML(bool save_children = true) const; - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); virtual void setValue(const LLSD& value ); - virtual LLSD getValue() const; - F32 get() { return (F32)getValue().asReal(); } + virtual LLSD getValue() const { return mValue; } + F32 get() const { return (F32)getValue().asReal(); } void set(F32 value) { setValue(value); mInitialValue = value; } virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); } virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); } - BOOL isMouseHeldDown(); + BOOL isMouseHeldDown() const; virtual void setEnabled( BOOL b ); virtual void setFocus( BOOL b ); virtual void clear(); - virtual BOOL isDirty() const; + virtual BOOL isDirty() const { return( mValue != mInitialValue ); } virtual void setPrecision(S32 precision); virtual void setMinValue(F32 min) { mMinValue = min; } @@ -119,12 +110,10 @@ public: static void onUpBtn(void *userdata); static void onDownBtn(void *userdata); -protected: +private: void updateEditor(); void reportInvalidData(); -protected: - F32 mValue; F32 mInitialValue; F32 mMaxValue; @@ -132,14 +121,14 @@ protected: F32 mIncrement; S32 mPrecision; - LLTextBox* mLabelBox; + class LLTextBox* mLabelBox; - LLLineEditor* mEditor; + class LLLineEditor* mEditor; LLColor4 mTextEnabledColor; LLColor4 mTextDisabledColor; - LLButton* mUpBtn; - LLButton* mDownBtn; + class LLButton* mUpBtn; + class LLButton* mDownBtn; BOOL mbHasBeenSet; }; diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp index 2d3534e7be..695dd2a16f 100644 --- a/indra/llui/llstyle.cpp +++ b/indra/llui/llstyle.cpp @@ -71,11 +71,6 @@ LLStyle::LLStyle(BOOL is_visible, const LLColor4 &color, const LLString& font_na init(is_visible, color, font_name); } -LLStyle::~LLStyle() -{ - free(); -} - void LLStyle::init(BOOL is_visible, const LLColor4 &color, const LLString& font_name) { mVisible = is_visible; @@ -91,14 +86,6 @@ void LLStyle::init(BOOL is_visible, const LLColor4 &color, const LLString& font_ mIsEmbeddedItem = FALSE; } -void LLStyle::free() -{ -} - -LLFONT_ID LLStyle::getFontID() const -{ - return mFontID; -} // Copy assignment LLStyle &LLStyle::operator=(const LLStyle &rhs) @@ -122,48 +109,6 @@ LLStyle &LLStyle::operator=(const LLStyle &rhs) return *this; } -// Compare -bool LLStyle::operator==(const LLStyle &rhs) const -{ - if ((mVisible != rhs.isVisible()) - || (mColor != rhs.getColor()) - || (mFontName != rhs.getFontString()) - || (mLink != rhs.getLinkHREF()) - || (mImagep != rhs.mImagep) - || (mImageHeight != rhs.mImageHeight) - || (mImageWidth != rhs.mImageWidth) - || (mItalic != rhs.mItalic) - || (mBold != rhs.mBold) - || (mUnderline != rhs.mUnderline) - || (mDropShadow != rhs.mDropShadow) - || (mIsEmbeddedItem != rhs.mIsEmbeddedItem) - ) - { - return FALSE; - } - return TRUE; -} - -bool LLStyle::operator!=(const LLStyle& rhs) const -{ - return !(*this == rhs); -} - - -const LLColor4& LLStyle::getColor() const -{ - return(mColor); -} - -void LLStyle::setColor(const LLColor4 &color) -{ - mColor = color; -} - -const LLString& LLStyle::getFontString() const -{ - return mFontName; -} void LLStyle::setFontName(const LLString& fontname) { @@ -192,52 +137,15 @@ void LLStyle::setFontName(const LLString& fontname) } } -const LLString& LLStyle::getLinkHREF() const -{ - return mLink; -} - -void LLStyle::setLinkHREF(const LLString& href) -{ - mLink = href; -} - -BOOL LLStyle::isLink() const -{ - return mLink.size(); -} - -BOOL LLStyle::isVisible() const -{ - return mVisible; -} - -void LLStyle::setVisible(BOOL is_visible) -{ - mVisible = is_visible; -} - -LLImageGL *LLStyle::getImage() const -{ - return mImagep; -} void LLStyle::setImage(const LLString& src) { - if (src.size() < UUID_STR_LENGTH - 1) - { - return; - } - else + if (src.size() >= UUID_STR_LENGTH - 1) { mImagep = LLUI::sImageProvider->getImageByID(LLUUID(src)); } } -BOOL LLStyle::isImage() const -{ - return ((mImageWidth != 0) && (mImageHeight != 0)); -} void LLStyle::setImageSize(S32 width, S32 height) { diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index 809253fd9b..b425640a36 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -46,36 +46,52 @@ public: LLStyle &operator=(const LLStyle &rhs); - virtual ~LLStyle(); + virtual ~LLStyle() { } virtual void init (BOOL is_visible, const LLColor4 &color, const LLString& font_name); - virtual void free (); - bool operator==(const LLStyle &rhs) const; - bool operator!=(const LLStyle &rhs) const; + virtual const LLColor4& getColor() const { return mColor; } + virtual void setColor(const LLColor4 &color) { mColor = color; } - virtual const LLColor4& getColor() const; - virtual void setColor(const LLColor4 &color); + virtual BOOL isVisible() const { return mVisible; } + virtual void setVisible(BOOL is_visible) { mVisible = is_visible; } - virtual BOOL isVisible() const; - virtual void setVisible(BOOL is_visible); - - virtual const LLString& getFontString() const; + virtual const LLString& getFontString() const { return mFontName; } virtual void setFontName(const LLString& fontname); - virtual LLFONT_ID getFontID() const; + virtual LLFONT_ID getFontID() const { return mFontID; } - virtual const LLString& getLinkHREF() const; - virtual void setLinkHREF(const LLString& fontname); - virtual BOOL isLink() const; + virtual const LLString& getLinkHREF() const { return mLink; } + virtual void setLinkHREF(const LLString& href) { mLink = href; } + virtual BOOL isLink() const { return mLink.size(); } - virtual LLImageGL *getImage() const; + virtual LLImageGL *getImage() const { return mImagep; } virtual void setImage(const LLString& src); - virtual BOOL isImage() const; + virtual BOOL isImage() const { return ((mImageWidth != 0) && (mImageHeight != 0)); } virtual void setImageSize(S32 width, S32 height); BOOL getIsEmbeddedItem() const { return mIsEmbeddedItem; } void setIsEmbeddedItem( BOOL b ) { mIsEmbeddedItem = b; } + // inlined here to make it easier to compare to member data below. -MG + bool operator==(const LLStyle &rhs) const + { + return + mVisible == rhs.isVisible() + && mColor == rhs.getColor() + && mFontName == rhs.getFontString() + && mLink == rhs.getLinkHREF() + && mImagep == rhs.mImagep + && mImageHeight == rhs.mImageHeight + && mImageWidth == rhs.mImageWidth + && mItalic == rhs.mItalic + && mBold == rhs.mBold + && mUnderline == rhs.mUnderline + && mDropShadow == rhs.mDropShadow + && mIsEmbeddedItem == rhs.mIsEmbeddedItem; + } + + bool operator!=(const LLStyle& rhs) const { return !(*this == rhs); } + public: BOOL mItalic; BOOL mBold; @@ -84,14 +100,13 @@ public: S32 mImageWidth; S32 mImageHeight; -protected: +private: BOOL mVisible; LLColor4 mColor; LLString mFontName; LLFONT_ID mFontID; LLString mLink; LLPointer<LLImageGL> mImagep; - BOOL mIsEmbeddedItem; }; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 148060359f..4568ebac29 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -1,6 +1,6 @@ /** * @file lltabcontainer.cpp - * @brief LLTabContainerCommon base class + * @brief LLTabContainer class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -30,33 +30,23 @@ */ #include "linden_common.h" - #include "lltabcontainer.h" - #include "llfocusmgr.h" -#include "llfontgl.h" -#include "llgl.h" - #include "llbutton.h" #include "llrect.h" -#include "llpanel.h" #include "llresmgr.h" -#include "llkeyboard.h" #include "llresizehandle.h" -#include "llui.h" #include "lltextbox.h" -#include "llcontrol.h" #include "llcriticaldamp.h" #include "lluictrlfactory.h" - #include "lltabcontainervertical.h" -#include "llglheaders.h" const F32 SCROLL_STEP_TIME = 0.4f; const F32 SCROLL_DELAY_TIME = 0.5f; const S32 TAB_PADDING = 15; const S32 TABCNTR_TAB_MIN_WIDTH = 60; +const S32 TABCNTR_VERT_TAB_MIN_WIDTH = 100; const S32 TABCNTR_TAB_MAX_WIDTH = 150; const S32 TABCNTR_TAB_PARTIAL_WIDTH = 12; // When tabs are parially obscured, how much can you still see. const S32 TABCNTR_TAB_HEIGHT = 16; @@ -64,12 +54,19 @@ const S32 TABCNTR_ARROW_BTN_SIZE = 16; const S32 TABCNTR_BUTTON_PANEL_OVERLAP = 1; // how many pixels the tab buttons and tab panels overlap. const S32 TABCNTR_TAB_H_PAD = 4; +const S32 TABCNTR_CLOSE_BTN_SIZE = 16; +const S32 TABCNTR_HEADER_HEIGHT = LLPANEL_BORDER_WIDTH + TABCNTR_CLOSE_BTN_SIZE; + +const S32 TABCNTRV_CLOSE_BTN_SIZE = 16; +const S32 TABCNTRV_HEADER_HEIGHT = LLPANEL_BORDER_WIDTH + TABCNTRV_CLOSE_BTN_SIZE; +//const S32 TABCNTRV_TAB_WIDTH = 100; +const S32 TABCNTRV_ARROW_BTN_SIZE = 16; +const S32 TABCNTRV_PAD = 0; + -LLTabContainerCommon::LLTabContainerCommon( - const LLString& name, const LLRect& rect, - TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - BOOL bordered ) + +LLTabContainer::LLTabContainer(const LLString& name, const LLRect& rect, TabPosition pos, + BOOL bordered, BOOL is_vertical ) : LLPanel(name, rect, bordered), mCurrentTabIdx(-1), @@ -78,50 +75,65 @@ LLTabContainerCommon::LLTabContainerCommon( mScrollPos(0), mScrollPosPixels(0), mMaxScrollPos(0), - mCloseCallback( close_callback ), - mCallbackUserdata( callback_userdata ), + mCloseCallback( NULL ), + mCallbackUserdata( NULL ), mTitleBox(NULL), mTopBorderHeight(LLPANEL_BORDER_WIDTH), mTabPosition(pos), - mLockedTabCount(0) + mLockedTabCount(0), + mMinTabWidth(TABCNTR_TAB_MIN_WIDTH), + mMaxTabWidth(TABCNTR_TAB_MAX_WIDTH), + mPrevArrowBtn(NULL), + mNextArrowBtn(NULL), + mIsVertical(is_vertical), + // Horizontal Specific + mJumpPrevArrowBtn(NULL), + mJumpNextArrowBtn(NULL), + mRightTabBtnOffset(0), + mTotalTabWidth(0) { + //RN: HACK to support default min width for legacy vertical tab containers + if (mIsVertical) + { + mMinTabWidth = TABCNTR_VERT_TAB_MIN_WIDTH; + } setMouseOpaque(FALSE); + initButtons( ); mDragAndDropDelayTimer.stop(); } +LLTabContainer::~LLTabContainer() +{ + std::for_each(mTabList.begin(), mTabList.end(), DeletePointer()); +} -LLTabContainerCommon::LLTabContainerCommon( - const LLString& name, - const LLString& rect_control, - TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - BOOL bordered ) - : - LLPanel(name, rect_control, bordered), - mCurrentTabIdx(-1), - mTabsHidden(FALSE), - mScrolled(FALSE), - mScrollPos(0), - mScrollPosPixels(0), - mMaxScrollPos(0), - mCloseCallback( close_callback ), - mCallbackUserdata( callback_userdata ), - mTitleBox(NULL), - mTopBorderHeight(LLPANEL_BORDER_WIDTH), - mTabPosition(pos), - mLockedTabCount(0) +//virtual +void LLTabContainer::setValue(const LLSD& value) { - setMouseOpaque(FALSE); - mDragAndDropDelayTimer.stop(); + selectTab((S32) value.asInteger()); } +//virtual +EWidgetType LLTabContainer::getWidgetType() const +{ + return WIDGET_TYPE_TAB_CONTAINER; +} -LLTabContainerCommon::~LLTabContainerCommon() +//virtual +LLString LLTabContainer::getWidgetTag() const { - std::for_each(mTabList.begin(), mTabList.end(), DeletePointer()); + return LL_TAB_CONTAINER_COMMON_TAG; } -LLView* LLTabContainerCommon::getChildByName(const LLString& name, BOOL recurse) const +//virtual +void LLTabContainer::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLPanel::reshape( width, height, called_from_parent ); + updateMaxScrollPos(); +} + +//virtual +LLView* LLTabContainer::getChildByName(const LLString& name, BOOL recurse) const { tuple_list_t::const_iterator itor; for (itor = mTabList.begin(); itor != mTabList.end(); ++itor) @@ -137,7 +149,7 @@ LLView* LLTabContainerCommon::getChildByName(const LLString& name, BOOL recurse) for (itor = mTabList.begin(); itor != mTabList.end(); ++itor) { LLPanel *panel = (*itor)->mTabPanel; - LLView *child = panel->getChildByName(name, recurse); + LLView *child = panel->getChild<LLView>(name, recurse); if (child) { return child; @@ -147,25 +159,750 @@ LLView* LLTabContainerCommon::getChildByName(const LLString& name, BOOL recurse) return LLView::getChildByName(name, recurse); } -void LLTabContainerCommon::addPlaceholder(LLPanel* child, const LLString& label) +// virtual +void LLTabContainer::draw() { - addTabPanel(child, label, FALSE, NULL, NULL, 0, TRUE); + S32 target_pixel_scroll = 0; + S32 cur_scroll_pos = mIsVertical ? 0 : getScrollPos(); + if (cur_scroll_pos > 0) + { + S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + if (cur_scroll_pos == 0) + { + break; + } + target_pixel_scroll += (*iter)->mButton->getRect().getWidth(); + cur_scroll_pos--; + } + + // Show part of the tab to the left of what is fully visible + target_pixel_scroll -= TABCNTR_TAB_PARTIAL_WIDTH; + // clamp so that rightmost tab never leaves right side of screen + target_pixel_scroll = llmin(mTotalTabWidth - available_width_with_arrows, target_pixel_scroll); + } + + setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f))); + if( getVisible() ) + { + BOOL has_scroll_arrows = (mMaxScrollPos > 0) || (mScrollPosPixels > 0); + if (!mIsVertical) + { + mJumpPrevArrowBtn->setVisible( has_scroll_arrows ); + mJumpNextArrowBtn->setVisible( has_scroll_arrows ); + } + mPrevArrowBtn->setVisible( has_scroll_arrows ); + mNextArrowBtn->setVisible( has_scroll_arrows ); + + S32 left = 0, top = 0; + if (mIsVertical) + { + top = getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1 - (has_scroll_arrows ? TABCNTRV_ARROW_BTN_SIZE : 0); + top += getScrollPosPixels(); + } + else + { + // Set the leftmost position of the tab buttons. + left = LLPANEL_BORDER_WIDTH + (has_scroll_arrows ? (TABCNTR_ARROW_BTN_SIZE * 2) : TABCNTR_TAB_H_PAD); + left -= getScrollPosPixels(); + } + + // Hide all the buttons + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + tuple->mButton->setVisible( FALSE ); + } + + LLPanel::draw(); + + // if tabs are hidden, don't draw them and leave them in the invisible state + if (!getTabsHidden()) + { + // Show all the buttons + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + tuple->mButton->setVisible( TRUE ); + } + + // Draw some of the buttons... + LLRect clip_rect = getLocalRect(); + if (has_scroll_arrows) + { + // ...but clip them. + if (mIsVertical) + { + clip_rect.mBottom = mNextArrowBtn->getRect().mTop + 3*TABCNTRV_PAD; + clip_rect.mTop = mPrevArrowBtn->getRect().mBottom - 3*TABCNTRV_PAD; + } + else + { + clip_rect.mLeft = mPrevArrowBtn->getRect().mRight; + clip_rect.mRight = mNextArrowBtn->getRect().mLeft; + } + } + LLLocalClipRect clip(clip_rect); + + S32 max_scroll_visible = getTabCount() - getMaxScrollPos() + getScrollPos(); + S32 idx = 0; + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + + tuple->mButton->translate( left ? left - tuple->mButton->getRect().mLeft : 0, + top ? top - tuple->mButton->getRect().mTop : 0 ); + if (top) top -= BTN_HEIGHT + TABCNTRV_PAD; + if (left) left += tuple->mButton->getRect().getWidth(); + + if (!mIsVertical) + { + if( idx < getScrollPos() ) + { + if( tuple->mButton->getFlashing() ) + { + mPrevArrowBtn->setFlashing( TRUE ); + } + } + else if( max_scroll_visible < idx ) + { + if( tuple->mButton->getFlashing() ) + { + mNextArrowBtn->setFlashing( TRUE ); + } + } + } + LLUI::pushMatrix(); + { + LLUI::translate((F32)tuple->mButton->getRect().mLeft, (F32)tuple->mButton->getRect().mBottom, 0.f); + tuple->mButton->draw(); + } + LLUI::popMatrix(); + + idx++; + } + + + if( mIsVertical && has_scroll_arrows ) + { + // Redraw the arrows so that they appears on top. + glPushMatrix(); + glTranslatef((F32)mPrevArrowBtn->getRect().mLeft, (F32)mPrevArrowBtn->getRect().mBottom, 0.f); + mPrevArrowBtn->draw(); + glPopMatrix(); + + glPushMatrix(); + glTranslatef((F32)mNextArrowBtn->getRect().mLeft, (F32)mNextArrowBtn->getRect().mBottom, 0.f); + mNextArrowBtn->draw(); + glPopMatrix(); + } + } + + mPrevArrowBtn->setFlashing(FALSE); + mNextArrowBtn->setFlashing(FALSE); + } } -void LLTabContainerCommon::lockTabs(S32 num_tabs) + +// virtual +BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) { - // count current tabs or use supplied value and ensure no new tabs get - // inserted between them - mLockedTabCount = num_tabs > 0 ? llmin(getTabCount(), num_tabs) : getTabCount(); + BOOL handled = FALSE; + BOOL has_scroll_arrows = (getMaxScrollPos() > 0); + + if (has_scroll_arrows) + { + if (mJumpPrevArrowBtn&& mJumpPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom; + handled = mJumpPrevArrowBtn->handleMouseDown(local_x, local_y, mask); + } + else if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom; + handled = mJumpNextArrowBtn->handleMouseDown(local_x, local_y, mask); + } + else if (mPrevArrowBtn && mPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mPrevArrowBtn->getRect().mBottom; + handled = mPrevArrowBtn->handleMouseDown(local_x, local_y, mask); + } + else if (mNextArrowBtn && mNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mNextArrowBtn->getRect().mLeft; + S32 local_y = y - mNextArrowBtn->getRect().mBottom; + handled = mNextArrowBtn->handleMouseDown(local_x, local_y, mask); + } + } + if (!handled) + { + handled = LLPanel::handleMouseDown( x, y, mask ); + } + + if (getTabCount() > 0) + { + LLTabTuple* firsttuple = getTab(0); + LLRect tab_rect; + if (mIsVertical) + { + tab_rect = LLRect(firsttuple->mButton->getRect().mLeft, + has_scroll_arrows ? mPrevArrowBtn->getRect().mBottom - TABCNTRV_PAD : mPrevArrowBtn->getRect().mTop, + firsttuple->mButton->getRect().mRight, + has_scroll_arrows ? mNextArrowBtn->getRect().mTop + TABCNTRV_PAD : mNextArrowBtn->getRect().mBottom ); + } + else + { + tab_rect = LLRect(has_scroll_arrows ? mPrevArrowBtn->getRect().mRight : mJumpPrevArrowBtn->getRect().mLeft, + firsttuple->mButton->getRect().mTop, + has_scroll_arrows ? mNextArrowBtn->getRect().mLeft : mJumpNextArrowBtn->getRect().mRight, + firsttuple->mButton->getRect().mBottom ); + } + if( tab_rect.pointInRect( x, y ) ) + { + LLButton* tab_button = getTab(getCurrentPanelIndex())->mButton; + gFocusMgr.setMouseCapture(this); + gFocusMgr.setKeyboardFocus(tab_button); + } + } + return handled; +} + +// virtual +BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask ) +{ + BOOL handled = FALSE; + BOOL has_scroll_arrows = (getMaxScrollPos() > 0); + + if (has_scroll_arrows) + { + if (mJumpPrevArrowBtn && mJumpPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom; + handled = mJumpPrevArrowBtn->handleHover(local_x, local_y, mask); + } + else if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom; + handled = mJumpNextArrowBtn->handleHover(local_x, local_y, mask); + } + else if (mPrevArrowBtn && mPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mPrevArrowBtn->getRect().mBottom; + handled = mPrevArrowBtn->handleHover(local_x, local_y, mask); + } + else if (mNextArrowBtn && mNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mNextArrowBtn->getRect().mLeft; + S32 local_y = y - mNextArrowBtn->getRect().mBottom; + handled = mNextArrowBtn->handleHover(local_x, local_y, mask); + } + } + if (!handled) + { + handled = LLPanel::handleHover(x, y, mask); + } + + commitHoveredButton(x, y); + return handled; } -void LLTabContainerCommon::unlockTabs() +// virtual +BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask ) { - mLockedTabCount = 0; + BOOL handled = FALSE; + BOOL has_scroll_arrows = (getMaxScrollPos() > 0); + + if (has_scroll_arrows) + { + if (mJumpPrevArrowBtn && mJumpPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom; + handled = mJumpPrevArrowBtn->handleMouseUp(local_x, local_y, mask); + } + else if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom; + handled = mJumpNextArrowBtn->handleMouseUp(local_x, local_y, mask); + } + else if (mPrevArrowBtn && mPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mPrevArrowBtn->getRect().mBottom; + handled = mPrevArrowBtn->handleMouseUp(local_x, local_y, mask); + } + else if (mNextArrowBtn && mNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mNextArrowBtn->getRect().mLeft; + S32 local_y = y - mNextArrowBtn->getRect().mBottom; + handled = mNextArrowBtn->handleMouseUp(local_x, local_y, mask); + } + } + if (!handled) + { + handled = LLPanel::handleMouseUp( x, y, mask ); + } + + commitHoveredButton(x, y); + LLPanel* cur_panel = getCurrentPanel(); + if (hasMouseCapture()) + { + if (cur_panel) + { + if (!cur_panel->focusFirstItem(FALSE)) + { + // if nothing in the panel gets focus, make sure the new tab does + // otherwise the last tab might keep focus + getTab(getCurrentPanelIndex())->mButton->setFocus(TRUE); + } + } + gFocusMgr.setMouseCapture(NULL); + } + return handled; +} + +// virtual +BOOL LLTabContainer::handleToolTip( S32 x, S32 y, LLString& msg, LLRect* sticky_rect ) +{ + BOOL handled = LLPanel::handleToolTip( x, y, msg, sticky_rect ); + if (!handled && getTabCount() > 0) + { + LLTabTuple* firsttuple = getTab(0); + + BOOL has_scroll_arrows = (getMaxScrollPos() > 0); + LLRect clip; + if (mIsVertical) + { + clip = LLRect(firsttuple->mButton->getRect().mLeft, + has_scroll_arrows ? mPrevArrowBtn->getRect().mBottom - TABCNTRV_PAD : mPrevArrowBtn->getRect().mTop, + firsttuple->mButton->getRect().mRight, + has_scroll_arrows ? mNextArrowBtn->getRect().mTop + TABCNTRV_PAD : mNextArrowBtn->getRect().mBottom ); + } + else + { + clip = LLRect(has_scroll_arrows ? mPrevArrowBtn->getRect().mRight : mJumpPrevArrowBtn->getRect().mLeft, + firsttuple->mButton->getRect().mTop, + has_scroll_arrows ? mNextArrowBtn->getRect().mLeft : mJumpNextArrowBtn->getRect().mRight, + firsttuple->mButton->getRect().mBottom ); + } + + if( clip.pointInRect( x, y ) ) + { + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + tuple->mButton->setVisible( TRUE ); + S32 local_x = x - tuple->mButton->getRect().mLeft; + S32 local_y = y - tuple->mButton->getRect().mBottom; + handled = tuple->mButton->handleToolTip( local_x, local_y, msg, sticky_rect ); + if( handled ) + { + break; + } + } + } + + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + tuple->mButton->setVisible( FALSE ); + } + } + return handled; +} + +// virtual +BOOL LLTabContainer::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) +{ + if (!getEnabled()) return FALSE; + + if (!gFocusMgr.childHasKeyboardFocus(this)) return FALSE; + + BOOL handled = FALSE; + if (key == KEY_LEFT && mask == MASK_ALT) + { + selectPrevTab(); + handled = TRUE; + } + else if (key == KEY_RIGHT && mask == MASK_ALT) + { + selectNextTab(); + handled = TRUE; + } + + if (handled) + { + if (getCurrentPanel()) + { + getCurrentPanel()->setFocus(TRUE); + } + } + + if (!gFocusMgr.childHasKeyboardFocus(getCurrentPanel())) + { + // if child has focus, but not the current panel, focus is on a button + if (mIsVertical) + { + switch(key) + { + case KEY_UP: + selectPrevTab(); + handled = TRUE; + break; + case KEY_DOWN: + selectNextTab(); + handled = TRUE; + break; + case KEY_LEFT: + handled = TRUE; + break; + case KEY_RIGHT: + if (getTabPosition() == LEFT && getCurrentPanel()) + { + getCurrentPanel()->setFocus(TRUE); + } + handled = TRUE; + break; + default: + break; + } + } + else + { + switch(key) + { + case KEY_UP: + if (getTabPosition() == BOTTOM && getCurrentPanel()) + { + getCurrentPanel()->setFocus(TRUE); + } + handled = TRUE; + break; + case KEY_DOWN: + if (getTabPosition() == TOP && getCurrentPanel()) + { + getCurrentPanel()->setFocus(TRUE); + } + handled = TRUE; + break; + case KEY_LEFT: + selectPrevTab(); + handled = TRUE; + break; + case KEY_RIGHT: + selectNextTab(); + handled = TRUE; + break; + default: + break; + } + } + } + return handled; +} + +// virtual +LLXMLNodePtr LLTabContainer::getXML(bool save_children) const +{ + LLXMLNodePtr node = LLPanel::getXML(); + node->createChild("tab_position", TRUE)->setStringValue((getTabPosition() == TOP ? "top" : "bottom")); + return node; +} + +// virtual +BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType type, void* cargo_data, EAcceptance *accept, LLString &tooltip) +{ + BOOL has_scroll_arrows = (getMaxScrollPos() > 0); + + if( mDragAndDropDelayTimer.getElapsedTimeF32() > SCROLL_DELAY_TIME ) + { + if (has_scroll_arrows) + { + if (mJumpPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom; + mJumpPrevArrowBtn->handleHover(local_x, local_y, mask); + } + if (mJumpNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom; + mJumpNextArrowBtn->handleHover(local_x, local_y, mask); + } + if (mPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mPrevArrowBtn->getRect().mBottom; + mPrevArrowBtn->handleHover(local_x, local_y, mask); + } + else if (mNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mNextArrowBtn->getRect().mLeft; + S32 local_y = y - mNextArrowBtn->getRect().mBottom; + mNextArrowBtn->handleHover(local_x, local_y, mask); + } + } + + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + tuple->mButton->setVisible( TRUE ); + S32 local_x = x - tuple->mButton->getRect().mLeft; + S32 local_y = y - tuple->mButton->getRect().mBottom; + if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible()) + { + tuple->mButton->onCommit(); + mDragAndDropDelayTimer.stop(); + } + } + } + + return LLView::handleDragAndDrop(x, y, mask, drop, type, cargo_data, accept, tooltip); } -void LLTabContainerCommon::removeTabPanel(LLPanel* child) +void LLTabContainer::addTabPanel(LLPanel* child, + const LLString& label, + BOOL select, + void (*on_tab_clicked)(void*, bool), + void* userdata, + S32 indent, + BOOL placeholder, + eInsertionPoint insertion_point) { + if (child->getParent() == this) + { + // already a child of mine + return; + } + const LLFontGL* font = gResMgr->getRes( mIsVertical ? LLFONT_SANSSERIF : LLFONT_SANSSERIF_SMALL ); + + // Store the original label for possible xml export. + child->setLabel(label); + LLString trimmed_label = label; + LLString::trim(trimmed_label); + + S32 button_width = mMinTabWidth; + if (!mIsVertical) + { + button_width = llclamp(font->getWidth(trimmed_label) + TAB_PADDING, mMinTabWidth, mMaxTabWidth); + } + + // Tab panel + S32 tab_panel_top; + S32 tab_panel_bottom; + if( getTabPosition() == LLTabContainer::TOP ) + { + S32 tab_height = mIsVertical ? BTN_HEIGHT : TABCNTR_TAB_HEIGHT; + tab_panel_top = getRect().getHeight() - getTopBorderHeight() - (tab_height - TABCNTR_BUTTON_PANEL_OVERLAP); + tab_panel_bottom = LLPANEL_BORDER_WIDTH; + } + else + { + tab_panel_top = getRect().getHeight() - getTopBorderHeight(); + tab_panel_bottom = (TABCNTR_TAB_HEIGHT - TABCNTR_BUTTON_PANEL_OVERLAP); // Run to the edge, covering up the border + } + + LLRect tab_panel_rect; + if (mIsVertical) + { + tab_panel_rect = LLRect(mMinTabWidth + (LLPANEL_BORDER_WIDTH * 2) + TABCNTRV_PAD, + getRect().getHeight() - LLPANEL_BORDER_WIDTH, + getRect().getWidth() - LLPANEL_BORDER_WIDTH, + LLPANEL_BORDER_WIDTH); + } + else + { + tab_panel_rect = LLRect(LLPANEL_BORDER_WIDTH, + tab_panel_top, + getRect().getWidth()-LLPANEL_BORDER_WIDTH, + tab_panel_bottom ); + } + child->setFollowsAll(); + child->translate( tab_panel_rect.mLeft - child->getRect().mLeft, tab_panel_rect.mBottom - child->getRect().mBottom); + child->reshape( tab_panel_rect.getWidth(), tab_panel_rect.getHeight(), TRUE ); + child->setBackgroundVisible( FALSE ); // No need to overdraw + // add this child later + + child->setVisible( FALSE ); // Will be made visible when selected + + mTotalTabWidth += button_width; + + // Tab button + LLRect btn_rect; // Note: btn_rect.mLeft is just a dummy. Will be updated in draw(). + LLString tab_img; + LLString tab_selected_img; + S32 tab_fudge = 1; // To make new tab art look better, nudge buttons up 1 pel + + if (mIsVertical) + { + btn_rect.setLeftTopAndSize(TABCNTRV_PAD + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor + (getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + TABCNTRV_PAD) * getTabCount()), + mMinTabWidth, + BTN_HEIGHT); + } + else if( getTabPosition() == LLTabContainer::TOP ) + { + btn_rect.setLeftTopAndSize( 0, getRect().getHeight() - getTopBorderHeight() + tab_fudge, button_width, TABCNTR_TAB_HEIGHT ); + tab_img = "tab_top_blue.tga"; + tab_selected_img = "tab_top_selected_blue.tga"; + } + else + { + btn_rect.setOriginAndSize( 0, 0 + tab_fudge, button_width, TABCNTR_TAB_HEIGHT ); + tab_img = "tab_bottom_blue.tga"; + tab_selected_img = "tab_bottom_selected_blue.tga"; + } + + LLTextBox* textbox = NULL; + LLButton* btn = NULL; + + if (placeholder) + { + btn_rect.translate(0, -LLBUTTON_V_PAD-2); + textbox = new LLTextBox(trimmed_label, btn_rect, trimmed_label, font); + + btn = new LLButton("", LLRect(0,0,0,0)); + } + else + { + if (mIsVertical) + { + btn = new LLButton("vert tab button", + btn_rect, + "", + "", + "", + &LLTabContainer::onTabBtn, NULL, + font, + trimmed_label, trimmed_label); + btn->setImages("tab_left.tga", "tab_left_selected.tga"); + btn->setScaleImage(TRUE); + btn->setHAlign(LLFontGL::LEFT); + btn->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); + btn->setTabStop(FALSE); + if (indent) + { + btn->setLeftHPad(indent); + } + } + else + { + LLString tooltip = trimmed_label; + tooltip += "\nAlt-Left arrow for previous tab"; + tooltip += "\nAlt-Right arrow for next tab"; + + btn = new LLButton(LLString(child->getName()) + " tab", + btn_rect, + "", "", "", + &LLTabContainer::onTabBtn, NULL, // set userdata below + font, + trimmed_label, trimmed_label ); + btn->setVisible( FALSE ); + btn->setToolTip( tooltip ); + btn->setScaleImage(TRUE); + btn->setImages(tab_img, tab_selected_img); + + // Try to squeeze in a bit more text + btn->setLeftHPad( 4 ); + btn->setRightHPad( 2 ); + btn->setHAlign(LLFontGL::LEFT); + btn->setTabStop(FALSE); + if (indent) + { + btn->setLeftHPad(indent); + } + + if( getTabPosition() == TOP ) + { + btn->setFollowsTop(); + } + else + { + btn->setFollowsBottom(); + } + } + } + + LLTabTuple* tuple = new LLTabTuple( this, child, btn, on_tab_clicked, userdata, textbox ); + insertTuple( tuple, insertion_point ); + + if (textbox) + { + textbox->setSaveToXML(false); + addChild( textbox, 0 ); + } + if (btn) + { + btn->setSaveToXML(false); + btn->setCallbackUserData( tuple ); + addChild( btn, 0 ); + } + if (child) + { + addChild(child, 1); + } + + if( select ) + { + selectLastTab(); + } + + updateMaxScrollPos(); +} + +void LLTabContainer::addPlaceholder(LLPanel* child, const LLString& label) +{ + addTabPanel(child, label, FALSE, NULL, NULL, 0, TRUE); +} + +void LLTabContainer::removeTabPanel(LLPanel* child) +{ + if (mIsVertical) + { + // Fix-up button sizes + S32 tab_count = 0; + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + LLRect rect; + rect.setLeftTopAndSize(TABCNTRV_PAD + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor + (getRect().getHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + TABCNTRV_PAD) * (tab_count)), + mMinTabWidth, + BTN_HEIGHT); + if (tuple->mPlaceholderText) + { + tuple->mPlaceholderText->setRect(rect); + } + else + { + tuple->mButton->setRect(rect); + } + tab_count++; + } + } + else + { + // Adjust the total tab width. + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + if( tuple->mTabPanel == child ) + { + mTotalTabWidth -= tuple->mButton->getRect().getWidth(); + break; + } + } + } + BOOL has_focus = gFocusMgr.childHasKeyboardFocus(this); // If the tab being deleted is the selected one, select a different tab. @@ -207,7 +944,27 @@ void LLTabContainerCommon::removeTabPanel(LLPanel* child) updateMaxScrollPos(); } -void LLTabContainerCommon::deleteAllTabs() +void LLTabContainer::lockTabs(S32 num_tabs) +{ + // count current tabs or use supplied value and ensure no new tabs get + // inserted between them + mLockedTabCount = num_tabs > 0 ? llmin(getTabCount(), num_tabs) : getTabCount(); +} + +void LLTabContainer::unlockTabs() +{ + mLockedTabCount = 0; +} + +void LLTabContainer::enableTabButton(S32 which, BOOL enable) +{ + if (which >= 0 && which < (S32)mTabList.size()) + { + mTabList[which]->mButton->setEnabled(enable); + } +} + +void LLTabContainer::deleteAllTabs() { // Remove all the tab buttons and delete them. Also, unlink all the child panels. for(std::vector<LLTabTuple*>::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) @@ -229,56 +986,26 @@ void LLTabContainerCommon::deleteAllTabs() mCurrentTabIdx = -1; } - -LLPanel* LLTabContainerCommon::getCurrentPanel() +LLPanel* LLTabContainer::getCurrentPanel() { - if (mCurrentTabIdx < 0 || mCurrentTabIdx >= (S32) mTabList.size()) return NULL; - - return mTabList[mCurrentTabIdx]->mTabPanel; -} - -LLTabContainerCommon::LLTabTuple* LLTabContainerCommon::getTabByPanel(LLPanel* child) -{ - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + if (mCurrentTabIdx >= 0 && mCurrentTabIdx < (S32) mTabList.size()) { - LLTabTuple* tuple = *iter; - if( tuple->mTabPanel == child ) - { - return tuple; - } + return mTabList[mCurrentTabIdx]->mTabPanel; } return NULL; } -void LLTabContainerCommon::setTabChangeCallback(LLPanel* tab, void (*on_tab_clicked)(void*, bool)) -{ - LLTabTuple* tuplep = getTabByPanel(tab); - if (tuplep) - { - tuplep->mOnChangeCallback = on_tab_clicked; - } -} - -void LLTabContainerCommon::setTabUserData(LLPanel* tab, void* userdata) -{ - LLTabTuple* tuplep = getTabByPanel(tab); - if (tuplep) - { - tuplep->mUserData = userdata; - } -} - -S32 LLTabContainerCommon::getCurrentPanelIndex() +S32 LLTabContainer::getCurrentPanelIndex() { return mCurrentTabIdx; } -S32 LLTabContainerCommon::getTabCount() +S32 LLTabContainer::getTabCount() { return mTabList.size(); } -LLPanel* LLTabContainerCommon::getPanelByIndex(S32 index) +LLPanel* LLTabContainer::getPanelByIndex(S32 index) { if (index >= 0 && index < (S32)mTabList.size()) { @@ -287,7 +1014,7 @@ LLPanel* LLTabContainerCommon::getPanelByIndex(S32 index) return NULL; } -S32 LLTabContainerCommon::getIndexForPanel(LLPanel* panel) +S32 LLTabContainer::getIndexForPanel(LLPanel* panel) { for (S32 index = 0; index < (S32)mTabList.size(); index++) { @@ -299,7 +1026,7 @@ S32 LLTabContainerCommon::getIndexForPanel(LLPanel* panel) return -1; } -S32 LLTabContainerCommon::getPanelIndexByTitle(const LLString& title) +S32 LLTabContainer::getPanelIndexByTitle(const LLString& title) { for (S32 index = 0 ; index < (S32)mTabList.size(); index++) { @@ -311,7 +1038,7 @@ S32 LLTabContainerCommon::getPanelIndexByTitle(const LLString& title) return -1; } -LLPanel *LLTabContainerCommon::getPanelByName(const LLString& name) +LLPanel *LLTabContainer::getPanelByName(const LLString& name) { for (S32 index = 0 ; index < (S32)mTabList.size(); index++) { @@ -324,34 +1051,71 @@ LLPanel *LLTabContainerCommon::getPanelByName(const LLString& name) return NULL; } +// Change the name of the button for the current tab. +void LLTabContainer::setCurrentTabName(const LLString& name) +{ + // Might not have a tab selected + if (mCurrentTabIdx < 0) return; + + mTabList[mCurrentTabIdx]->mButton->setLabelSelected(name); + mTabList[mCurrentTabIdx]->mButton->setLabelUnselected(name); +} -void LLTabContainerCommon::scrollNext() +void LLTabContainer::selectFirstTab() { - // No wrap - if( mScrollPos < mMaxScrollPos ) - { - mScrollPos++; - } + selectTab( 0 ); } -void LLTabContainerCommon::scrollPrev() + +void LLTabContainer::selectLastTab() { - // No wrap - if( mScrollPos > 0 ) + selectTab( mTabList.size()-1 ); +} + +void LLTabContainer::selectNextTab() +{ + BOOL tab_has_focus = FALSE; + if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus()) + { + tab_has_focus = TRUE; + } + S32 idx = mCurrentTabIdx+1; + if (idx >= (S32)mTabList.size()) + idx = 0; + while (!selectTab(idx) && idx != mCurrentTabIdx) { - mScrollPos--; + idx = (idx + 1 ) % (S32)mTabList.size(); + } + + if (tab_has_focus) + { + mTabList[idx]->mButton->setFocus(TRUE); } } -void LLTabContainerCommon::enableTabButton(S32 which, BOOL enable) +void LLTabContainer::selectPrevTab() { - if (which >= 0 && which < (S32)mTabList.size()) + BOOL tab_has_focus = FALSE; + if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus()) { - mTabList[which]->mButton->setEnabled(enable); + tab_has_focus = TRUE; } -} + S32 idx = mCurrentTabIdx-1; + if (idx < 0) + idx = mTabList.size()-1; + while (!selectTab(idx) && idx != mCurrentTabIdx) + { + idx = idx - 1; + if (idx < 0) + idx = mTabList.size()-1; + } + if (tab_has_focus) + { + mTabList[idx]->mButton->setFocus(TRUE); + } +} -BOOL LLTabContainerCommon::selectTabPanel(LLPanel* child) +BOOL LLTabContainer::selectTabPanel(LLPanel* child) { S32 idx = 0; for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) @@ -366,12 +1130,108 @@ BOOL LLTabContainerCommon::selectTabPanel(LLPanel* child) return FALSE; } -BOOL LLTabContainerCommon::selectTabByName(const LLString& name) +BOOL LLTabContainer::selectTab(S32 which) +{ + if (which >= getTabCount()) return FALSE; + if (which < 0) return FALSE; + + //if( gFocusMgr.childHasKeyboardFocus( this ) ) + //{ + // gFocusMgr.setKeyboardFocus( NULL ); + //} + + LLTabTuple* selected_tuple = getTab(which); + if (!selected_tuple) + { + return FALSE; + } + + BOOL is_visible = FALSE; + if (getTab(which)->mButton->getEnabled()) + { + setCurrentPanelIndex(which); + + S32 i = 0; + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + BOOL is_selected = ( tuple == selected_tuple ); + tuple->mTabPanel->setVisible( is_selected ); +// tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here. + tuple->mButton->setToggleState( is_selected ); + // RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs + tuple->mButton->setTabStop( is_selected ); + + if( is_selected && (mIsVertical || (getMaxScrollPos() > 0))) + { + // Make sure selected tab is within scroll region + if (mIsVertical) + { + S32 num_visible = getTabCount() - getMaxScrollPos(); + if( i >= getScrollPos() && i <= getScrollPos() + num_visible) + { + setCurrentPanelIndex(which); + is_visible = TRUE; + } + else + { + is_visible = FALSE; + } + } + else + { + if( i < getScrollPos() ) + { + setScrollPos(i); + } + else + { + S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); + S32 running_tab_width = tuple->mButton->getRect().getWidth(); + S32 j = i - 1; + S32 min_scroll_pos = i; + if (running_tab_width < available_width_with_arrows) + { + while (j >= 0) + { + LLTabTuple* other_tuple = getTab(j); + running_tab_width += other_tuple->mButton->getRect().getWidth(); + if (running_tab_width > available_width_with_arrows) + { + break; + } + j--; + } + min_scroll_pos = j + 1; + } + setScrollPos(llclamp(getScrollPos(), min_scroll_pos, i)); + setScrollPos(llmin(getScrollPos(), getMaxScrollPos())); + } + is_visible = TRUE; + } + } + i++; + } + if( selected_tuple->mOnChangeCallback ) + { + selected_tuple->mOnChangeCallback( selected_tuple->mUserData, false ); + } + } + if (mIsVertical && getCurrentPanelIndex() >= 0) + { + LLTabTuple* tuple = getTab(getCurrentPanelIndex()); + tuple->mTabPanel->setVisible( TRUE ); + tuple->mButton->setToggleState( TRUE ); + } + return is_visible; +} + +BOOL LLTabContainer::selectTabByName(const LLString& name) { LLPanel* panel = getPanelByName(name); if (!panel) { - llwarns << "LLTabContainerCommon::selectTabByName(" + llwarns << "LLTabContainer::selectTabByName(" << name << ") failed" << llendl; return FALSE; } @@ -380,74 +1240,131 @@ BOOL LLTabContainerCommon::selectTabByName(const LLString& name) return result; } - -void LLTabContainerCommon::selectFirstTab() +BOOL LLTabContainer::getTabPanelFlashing(LLPanel *child) { - selectTab( 0 ); + LLTabTuple* tuple = getTabByPanel(child); + if( tuple ) + { + return tuple->mButton->getFlashing(); + } + return FALSE; } - -void LLTabContainerCommon::selectLastTab() +void LLTabContainer::setTabPanelFlashing(LLPanel* child, BOOL state ) { - selectTab( mTabList.size()-1 ); + LLTabTuple* tuple = getTabByPanel(child); + if( tuple ) + { + tuple->mButton->setFlashing( state ); + } } - -void LLTabContainerCommon::selectNextTab() +void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const LLColor4& color) { - BOOL tab_has_focus = FALSE; - if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus()) - { - tab_has_focus = TRUE; - } - S32 idx = mCurrentTabIdx+1; - if (idx >= (S32)mTabList.size()) - idx = 0; - while (!selectTab(idx) && idx != mCurrentTabIdx) + LLTabTuple* tuple = getTabByPanel(child); + if( tuple ) { - idx = (idx + 1 ) % (S32)mTabList.size(); + tuple->mButton->setImageOverlay(image_name, LLFontGL::RIGHT, color); + + if (!mIsVertical) + { + const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); + // remove current width from total tab strip width + mTotalTabWidth -= tuple->mButton->getRect().getWidth(); + + S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? + tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : + 0; + + tuple->mPadding = image_overlay_width; + + tuple->mButton->setRightHPad(6); + tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), + tuple->mButton->getRect().getHeight()); + // add back in button width to total tab strip width + mTotalTabWidth += tuple->mButton->getRect().getWidth(); + + // tabs have changed size, might need to scroll to see current tab + updateMaxScrollPos(); + } } +} - if (tab_has_focus) +void LLTabContainer::setTitle(const LLString& title) +{ + if (mTitleBox) { - mTabList[idx]->mButton->setFocus(TRUE); + mTitleBox->setText( title ); } } -void LLTabContainerCommon::selectPrevTab() +const LLString LLTabContainer::getPanelTitle(S32 index) { - BOOL tab_has_focus = FALSE; - if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus()) + if (index >= 0 && index < (S32)mTabList.size()) { - tab_has_focus = TRUE; + LLButton* tab_button = mTabList[index]->mButton; + return tab_button->getLabelSelected(); } - S32 idx = mCurrentTabIdx-1; - if (idx < 0) - idx = mTabList.size()-1; - while (!selectTab(idx) && idx != mCurrentTabIdx) + return LLString::null; +} + +void LLTabContainer::setTopBorderHeight(S32 height) +{ + mTopBorderHeight = height; +} + +S32 LLTabContainer::getTopBorderHeight() const +{ + return mTopBorderHeight; +} + +void LLTabContainer::setTabChangeCallback(LLPanel* tab, void (*on_tab_clicked)(void*, bool)) +{ + LLTabTuple* tuplep = getTabByPanel(tab); + if (tuplep) { - idx = idx - 1; - if (idx < 0) - idx = mTabList.size()-1; + tuplep->mOnChangeCallback = on_tab_clicked; } - if (tab_has_focus) +} + +void LLTabContainer::setTabUserData(LLPanel* tab, void* userdata) +{ + LLTabTuple* tuplep = getTabByPanel(tab); + if (tuplep) { - mTabList[idx]->mButton->setFocus(TRUE); + tuplep->mUserData = userdata; } -} +} +void LLTabContainer::setRightTabBtnOffset(S32 offset) +{ + mNextArrowBtn->translate( -offset - mRightTabBtnOffset, 0 ); + mRightTabBtnOffset = offset; + updateMaxScrollPos(); +} -void LLTabContainerCommon::reshape(S32 width, S32 height, BOOL called_from_parent) +void LLTabContainer::setPanelTitle(S32 index, const LLString& title) { - LLPanel::reshape( width, height, called_from_parent ); + if (index >= 0 && index < getTabCount()) + { + LLTabTuple* tuple = getTab(index); + LLButton* tab_button = tuple->mButton; + const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); + mTotalTabWidth -= tab_button->getRect().getWidth(); + tab_button->reshape(llclamp(fontp->getWidth(title) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight()); + mTotalTabWidth += tab_button->getRect().getWidth(); + tab_button->setLabelSelected(title); + tab_button->setLabelUnselected(title); + } updateMaxScrollPos(); } + // static -void LLTabContainerCommon::onTabBtn( void* userdata ) +void LLTabContainer::onTabBtn( void* userdata ) { LLTabTuple* tuple = (LLTabTuple*) userdata; - LLTabContainerCommon* self = tuple->mTabContainer; + LLTabContainer* self = tuple->mTabContainer; self->selectTabPanel( tuple->mTabPanel ); if( tuple->mOnChangeCallback ) @@ -459,7 +1376,7 @@ void LLTabContainerCommon::onTabBtn( void* userdata ) } // static -void LLTabContainerCommon::onCloseBtn( void* userdata ) +void LLTabContainer::onCloseBtn( void* userdata ) { LLTabContainer* self = (LLTabContainer*) userdata; if( self->mCloseCallback ) @@ -469,7 +1386,7 @@ void LLTabContainerCommon::onCloseBtn( void* userdata ) } // static -void LLTabContainerCommon::onNextBtn( void* userdata ) +void LLTabContainer::onNextBtn( void* userdata ) { // Scroll tabs to the left LLTabContainer* self = (LLTabContainer*) userdata; @@ -481,7 +1398,7 @@ void LLTabContainerCommon::onNextBtn( void* userdata ) } // static -void LLTabContainerCommon::onNextBtnHeld( void* userdata ) +void LLTabContainer::onNextBtnHeld( void* userdata ) { LLTabContainer* self = (LLTabContainer*) userdata; if (self->mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME) @@ -493,7 +1410,7 @@ void LLTabContainerCommon::onNextBtnHeld( void* userdata ) } // static -void LLTabContainerCommon::onPrevBtn( void* userdata ) +void LLTabContainer::onPrevBtn( void* userdata ) { LLTabContainer* self = (LLTabContainer*) userdata; if (!self->mScrolled) @@ -503,26 +1420,22 @@ void LLTabContainerCommon::onPrevBtn( void* userdata ) self->mScrolled = FALSE; } - -void LLTabContainerCommon::onJumpFirstBtn( void* userdata ) +// static +void LLTabContainer::onJumpFirstBtn( void* userdata ) { LLTabContainer* self = (LLTabContainer*) userdata; - self->mScrollPos = 0; - } - -void LLTabContainerCommon::onJumpLastBtn( void* userdata ) +// static +void LLTabContainer::onJumpLastBtn( void* userdata ) { LLTabContainer* self = (LLTabContainer*) userdata; - self->mScrollPos = self->mMaxScrollPos; } - // static -void LLTabContainerCommon::onPrevBtnHeld( void* userdata ) +void LLTabContainer::onPrevBtnHeld( void* userdata ) { LLTabContainer* self = (LLTabContainer*) userdata; if (self->mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME) @@ -533,68 +1446,8 @@ void LLTabContainerCommon::onPrevBtnHeld( void* userdata ) } } -BOOL LLTabContainerCommon::getTabPanelFlashing(LLPanel *child) -{ - LLTabTuple* tuple = getTabByPanel(child); - if( tuple ) - { - return tuple->mButton->getFlashing(); - } - return FALSE; -} - -void LLTabContainerCommon::setTabPanelFlashing(LLPanel* child, BOOL state ) -{ - LLTabTuple* tuple = getTabByPanel(child); - if( tuple ) - { - tuple->mButton->setFlashing( state ); - } -} - -void LLTabContainerCommon::setTabImage(LLPanel* child, std::string img_name, const LLColor4& color) -{ - LLTabTuple* tuple = getTabByPanel(child); - if( tuple ) - { - tuple->mButton->setImageOverlay(img_name, LLFontGL::RIGHT, color); - } -} - -void LLTabContainerCommon::setTitle(const LLString& title) -{ - if (mTitleBox) - { - mTitleBox->setText( title ); - } -} - -const LLString LLTabContainerCommon::getPanelTitle(S32 index) -{ - if (index >= 0 && index < (S32)mTabList.size()) - { - LLButton* tab_button = mTabList[index]->mButton; - return tab_button->getLabelSelected(); - } - return LLString::null; -} - -void LLTabContainerCommon::setTopBorderHeight(S32 height) -{ - mTopBorderHeight = height; -} - -// Change the name of the button for the current tab. -void LLTabContainerCommon::setCurrentTabName(const LLString& name) -{ - // Might not have a tab selected - if (mCurrentTabIdx < 0) return; - - mTabList[mCurrentTabIdx]->mButton->setLabelSelected(name); - mTabList[mCurrentTabIdx]->mButton->setLabelUnselected(name); -} - -LLView* LLTabContainerCommon::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) +// static +LLView* LLTabContainer::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) { LLString name("tab_container"); node->getAttributeString("name", name); @@ -626,58 +1479,30 @@ LLView* LLTabContainerCommon::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtr BOOL border = FALSE; node->getAttributeBOOL("border", border); - // Create the correct container type. - LLTabContainerCommon* tab_container = NULL; - - if (is_vertical) + LLTabContainer* tab_container = new LLTabContainer(name, LLRect::null, tab_position, border, is_vertical); + + S32 tab_min_width = tab_container->mMinTabWidth; + if (node->hasAttribute("tab_width")) { - // Vertical tabs can specify tab width - U32 tab_width = TABCNTRV_TAB_WIDTH; - if (node->hasAttribute("tab_width")) - { - node->getAttributeU32("tab_width", tab_width); - } - - tab_container = new LLTabContainerVertical(name, - LLRect::null, - NULL, - NULL, - tab_width, - border); - + node->getAttributeS32("tab_width", tab_min_width); } - else // horizontal tab container + else if( node->hasAttribute("tab_min_width")) { - // Horizontal tabs can have a title (?) - LLString title(LLString::null); - if (node->hasAttribute("title")) - { - node->getAttributeString("title", title); - } + node->getAttributeS32("tab_min_width", tab_min_width); + } - tab_container = new LLTabContainer(name, - LLRect::null, - tab_position, - NULL, - NULL, - title, - border); - - if(node->hasAttribute("tab_min_width")) - { - S32 minTabWidth=0; - node->getAttributeS32("tab_min_width",minTabWidth); - ((LLTabContainer*)tab_container)->setMinTabWidth(minTabWidth); - } - if(node->hasAttribute("tab_max_width")) - { - S32 maxTabWidth=0; - node->getAttributeS32("tab_max_width",maxTabWidth); - ((LLTabContainer*)tab_container)->setMaxTabWidth(maxTabWidth); - } + S32 tab_max_width = tab_container->mMaxTabWidth; + if (node->hasAttribute("tab_max_width")) + { + node->getAttributeS32("tab_max_width", tab_max_width); } + + tab_container->setMinTabWidth(tab_min_width); + tab_container->setMaxTabWidth(tab_max_width); - node->getAttributeBOOL("hide_tabs", tab_container->mTabsHidden); + BOOL hidden(tab_container->getTabsHidden()); + node->getAttributeBOOL("hide_tabs", hidden); + tab_container->setTabsHidden(hidden); tab_container->setPanelParameters(node, parent); @@ -718,76 +1543,12 @@ LLView* LLTabContainerCommon::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtr return tab_container; } -void LLTabContainerCommon::insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_point) -{ - switch(insertion_point) - { - case START: - // insert the new tab in the front of the list - mTabList.insert(mTabList.begin() + mLockedTabCount, tuple); - break; - case LEFT_OF_CURRENT: - // insert the new tab before the current tab (but not before mLockedTabCount) - { - tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx); - mTabList.insert(current_iter, tuple); - } - break; - - case RIGHT_OF_CURRENT: - // insert the new tab after the current tab (but not before mLockedTabCount) - { - tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx + 1); - mTabList.insert(current_iter, tuple); - } - break; - case END: - default: - mTabList.push_back( tuple ); - } -} - - -LLTabContainer::LLTabContainer( - const LLString& name, const LLRect& rect, TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - const LLString& title, BOOL bordered ) - : - LLTabContainerCommon(name, rect, pos, close_callback, callback_userdata, bordered), - mLeftArrowBtn(NULL), - mJumpLeftArrowBtn(NULL), - mRightArrowBtn(NULL), - mJumpRightArrowBtn(NULL), - mRightTabBtnOffset(0), - mMinTabWidth(TABCNTR_TAB_MIN_WIDTH), - mMaxTabWidth(TABCNTR_TAB_MAX_WIDTH), - mTotalTabWidth(0) -{ - initButtons( ); -} - -LLTabContainer::LLTabContainer( - const LLString& name, const LLString& rect_control, TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - const LLString& title, BOOL bordered ) - : - LLTabContainerCommon(name, rect_control, pos, close_callback, callback_userdata, bordered), - mLeftArrowBtn(NULL), - mJumpLeftArrowBtn(NULL), - mRightArrowBtn(NULL), - mJumpRightArrowBtn(NULL), - mRightTabBtnOffset(0), - mMinTabWidth(TABCNTR_TAB_MIN_WIDTH), - mMaxTabWidth(TABCNTR_TAB_MAX_WIDTH), - mTotalTabWidth(0) -{ - initButtons( ); -} +// private void LLTabContainer::initButtons() { // Hack: - if (mRect.getHeight() == 0 || mLeftArrowBtn) + if (getRect().getHeight() == 0 || mPrevArrowBtn) { return; // Don't have a rect yet or already got called } @@ -795,881 +1556,255 @@ void LLTabContainer::initButtons() LLString out_id; LLString in_id; - S32 arrow_fudge = 1; // match new art better - - // tabs on bottom reserve room for resize handle (just in case) - if (mTabPosition == BOTTOM) + if (mIsVertical) { - mRightTabBtnOffset = RESIZE_HANDLE_WIDTH; - } - - // Left and right scroll arrows (for when there are too many tabs to show all at once). - S32 btn_top = (mTabPosition == TOP ) ? mRect.getHeight() - mTopBorderHeight : TABCNTR_ARROW_BTN_SIZE + 1; - - LLRect left_arrow_btn_rect; - left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1+TABCNTR_ARROW_BTN_SIZE, btn_top + arrow_fudge, TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); - - LLRect jump_left_arrow_btn_rect; - jump_left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1, btn_top + arrow_fudge, TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); - - S32 right_pad = TABCNTR_ARROW_BTN_SIZE + LLPANEL_BORDER_WIDTH + 1; - - LLRect right_arrow_btn_rect; - right_arrow_btn_rect.setLeftTopAndSize( mRect.getWidth() - mRightTabBtnOffset - right_pad - TABCNTR_ARROW_BTN_SIZE, - btn_top + arrow_fudge, - TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); + // Left and right scroll arrows (for when there are too many tabs to show all at once). + S32 btn_top = getRect().getHeight(); + S32 btn_top_lower = getRect().mBottom+TABCNTRV_ARROW_BTN_SIZE; + LLRect up_arrow_btn_rect; + up_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top, TABCNTRV_ARROW_BTN_SIZE, TABCNTRV_ARROW_BTN_SIZE ); - LLRect jump_right_arrow_btn_rect; - jump_right_arrow_btn_rect.setLeftTopAndSize( mRect.getWidth() - mRightTabBtnOffset - right_pad, - btn_top + arrow_fudge, - TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); + LLRect down_arrow_btn_rect; + down_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top_lower, TABCNTRV_ARROW_BTN_SIZE, TABCNTRV_ARROW_BTN_SIZE ); - out_id = "UIImgBtnJumpLeftOutUUID"; - in_id = "UIImgBtnJumpLeftInUUID"; - mJumpLeftArrowBtn = new LLButton( - "Jump Left Arrow", jump_left_arrow_btn_rect, - out_id, in_id, "", - &LLTabContainer::onJumpFirstBtn, this, LLFontGL::sSansSerif ); - mJumpLeftArrowBtn->setFollowsLeft(); - mJumpLeftArrowBtn->setSaveToXML(false); - mJumpLeftArrowBtn->setTabStop(FALSE); - addChild(mJumpLeftArrowBtn); + out_id = "UIImgBtnScrollUpOutUUID"; + in_id = "UIImgBtnScrollUpInUUID"; + mPrevArrowBtn = new LLButton("Up Arrow", up_arrow_btn_rect, + out_id, in_id, "", + &onPrevBtn, this, NULL ); + mPrevArrowBtn->setFollowsTop(); + mPrevArrowBtn->setFollowsLeft(); - out_id = "UIImgBtnScrollLeftOutUUID"; - in_id = "UIImgBtnScrollLeftInUUID"; - mLeftArrowBtn = new LLButton( - "Left Arrow", left_arrow_btn_rect, - out_id, in_id, "", - &LLTabContainer::onPrevBtn, this, LLFontGL::sSansSerif ); - mLeftArrowBtn->setHeldDownCallback(onPrevBtnHeld); - mLeftArrowBtn->setFollowsLeft(); - mLeftArrowBtn->setSaveToXML(false); - mLeftArrowBtn->setTabStop(FALSE); - addChild(mLeftArrowBtn); - - out_id = "UIImgBtnJumpRightOutUUID"; - in_id = "UIImgBtnJumpRightInUUID"; - mJumpRightArrowBtn = new LLButton( - "Jump Right Arrow", jump_right_arrow_btn_rect, - out_id, in_id, "", - &LLTabContainer::onJumpLastBtn, this, - LLFontGL::sSansSerif); - mJumpRightArrowBtn->setFollowsRight(); - mJumpRightArrowBtn->setSaveToXML(false); - mJumpRightArrowBtn->setTabStop(FALSE); - addChild(mJumpRightArrowBtn); - - out_id = "UIImgBtnScrollRightOutUUID"; - in_id = "UIImgBtnScrollRightInUUID"; - mRightArrowBtn = new LLButton( - "Right Arrow", right_arrow_btn_rect, - out_id, in_id, "", - &LLTabContainer::onNextBtn, this, - LLFontGL::sSansSerif); - mRightArrowBtn->setFollowsRight(); - mRightArrowBtn->setHeldDownCallback(onNextBtnHeld); - mRightArrowBtn->setSaveToXML(false); - mRightArrowBtn->setTabStop(FALSE); - addChild(mRightArrowBtn); - - - if( mTabPosition == TOP ) - { - mRightArrowBtn->setFollowsTop(); - mLeftArrowBtn->setFollowsTop(); - mJumpLeftArrowBtn->setFollowsTop(); - mJumpRightArrowBtn->setFollowsTop(); + out_id = "UIImgBtnScrollDownOutUUID"; + in_id = "UIImgBtnScrollDownInUUID"; + mNextArrowBtn = new LLButton("Down Arrow", down_arrow_btn_rect, + out_id, in_id, "", + &onNextBtn, this, NULL ); + mNextArrowBtn->setFollowsBottom(); + mNextArrowBtn->setFollowsLeft(); } - else + else // Horizontal { - mRightArrowBtn->setFollowsBottom(); - mLeftArrowBtn->setFollowsBottom(); - mJumpLeftArrowBtn->setFollowsBottom(); - mJumpRightArrowBtn->setFollowsBottom(); - } - - // set default tab group to be panel contents - mDefaultTabGroup = 1; -} + S32 arrow_fudge = 1; // match new art better -LLTabContainer::~LLTabContainer() -{ -} - -void LLTabContainer::addTabPanel(LLPanel* child, - const LLString& label, - BOOL select, - void (*on_tab_clicked)(void*, bool), - void* userdata, - S32 indent, - BOOL placeholder, - eInsertionPoint insertion_point) -{ - if (child->getParent() == this) - { - // already a child of mine - return; - } - const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); + // tabs on bottom reserve room for resize handle (just in case) + if (getTabPosition() == BOTTOM) + { + mRightTabBtnOffset = RESIZE_HANDLE_WIDTH; + } - // Store the original label for possible xml export. - child->setLabel(label); - LLString trimmed_label = label; - LLString::trim(trimmed_label); + // Left and right scroll arrows (for when there are too many tabs to show all at once). + S32 btn_top = (getTabPosition() == TOP ) ? getRect().getHeight() - getTopBorderHeight() : TABCNTR_ARROW_BTN_SIZE + 1; - S32 button_width = llclamp(font->getWidth(trimmed_label) + TAB_PADDING, mMinTabWidth, mMaxTabWidth); + LLRect left_arrow_btn_rect; + left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1+TABCNTR_ARROW_BTN_SIZE, btn_top + arrow_fudge, TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); - // Tab panel - S32 tab_panel_top; - S32 tab_panel_bottom; - if( LLTabContainer::TOP == mTabPosition ) - { - tab_panel_top = mRect.getHeight() - mTopBorderHeight - (TABCNTR_TAB_HEIGHT - TABCNTR_BUTTON_PANEL_OVERLAP); - tab_panel_bottom = LLPANEL_BORDER_WIDTH; - } - else - { - tab_panel_top = mRect.getHeight() - mTopBorderHeight; - tab_panel_bottom = (TABCNTR_TAB_HEIGHT - TABCNTR_BUTTON_PANEL_OVERLAP); // Run to the edge, covering up the border - } - - LLRect tab_panel_rect( - LLPANEL_BORDER_WIDTH, - tab_panel_top, - mRect.getWidth()-LLPANEL_BORDER_WIDTH, - tab_panel_bottom ); + LLRect jump_left_arrow_btn_rect; + jump_left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1, btn_top + arrow_fudge, TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); - child->setFollowsAll(); - child->translate( tab_panel_rect.mLeft - child->getRect().mLeft, tab_panel_rect.mBottom - child->getRect().mBottom); - child->reshape( tab_panel_rect.getWidth(), tab_panel_rect.getHeight(), TRUE ); - child->setBackgroundVisible( FALSE ); // No need to overdraw - // add this child later + S32 right_pad = TABCNTR_ARROW_BTN_SIZE + LLPANEL_BORDER_WIDTH + 1; - child->setVisible( FALSE ); // Will be made visible when selected + LLRect right_arrow_btn_rect; + right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad - TABCNTR_ARROW_BTN_SIZE, + btn_top + arrow_fudge, + TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); - mTotalTabWidth += button_width; - // Tab button - LLRect btn_rect; // Note: btn_rect.mLeft is just a dummy. Will be updated in draw(). - LLString tab_img; - LLString tab_selected_img; - S32 tab_fudge = 1; // To make new tab art look better, nudge buttons up 1 pel + LLRect jump_right_arrow_btn_rect; + jump_right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad, + btn_top + arrow_fudge, + TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); - if( LLTabContainer::TOP == mTabPosition ) - { - btn_rect.setLeftTopAndSize( 0, mRect.getHeight() - mTopBorderHeight + tab_fudge, button_width, TABCNTR_TAB_HEIGHT ); - tab_img = "tab_top_blue.tga"; - tab_selected_img = "tab_top_selected_blue.tga"; - } - else - { - btn_rect.setOriginAndSize( 0, 0 + tab_fudge, button_width, TABCNTR_TAB_HEIGHT ); - tab_img = "tab_bottom_blue.tga"; - tab_selected_img = "tab_bottom_selected_blue.tga"; - } + out_id = "UIImgBtnJumpLeftOutUUID"; + in_id = "UIImgBtnJumpLeftInUUID"; + mJumpPrevArrowBtn = new LLButton("Jump Left Arrow", jump_left_arrow_btn_rect, + out_id, in_id, "", + &LLTabContainer::onJumpFirstBtn, this, LLFontGL::sSansSerif ); + mJumpPrevArrowBtn->setFollowsLeft(); - if (placeholder) - { - // *FIX: wont work for horizontal tabs - btn_rect.translate(0, -LLBUTTON_V_PAD-2); - LLString box_label = trimmed_label; - LLTextBox* text = new LLTextBox(box_label, btn_rect, box_label, font); - addChild( text, 0 ); - - LLButton* btn = new LLButton("", LLRect(0,0,0,0)); - LLTabTuple* tuple = new LLTabTuple( this, child, btn, on_tab_clicked, userdata, text ); - addChild( btn, 0 ); - addChild( child, 1 ); - insertTuple(tuple, insertion_point); - } - else - { - LLString tooltip = trimmed_label; - tooltip += "\nAlt-Left arrow for previous tab"; - tooltip += "\nAlt-Right arrow for next tab"; - - LLButton* btn = new LLButton( - LLString(child->getName()) + " tab", - btn_rect, - "", "", "", - &LLTabContainer::onTabBtn, NULL, // set userdata below - font, - trimmed_label, trimmed_label ); - btn->setSaveToXML(false); - btn->setVisible( FALSE ); - btn->setToolTip( tooltip ); - btn->setScaleImage(TRUE); - btn->setImages(tab_img, tab_selected_img); - - // Try to squeeze in a bit more text - btn->setLeftHPad( 4 ); - btn->setRightHPad( 2 ); - btn->setHAlign(LLFontGL::LEFT); - btn->setTabStop(FALSE); - if (indent) - { - btn->setLeftHPad(indent); - } - - if( mTabPosition == TOP ) + out_id = "UIImgBtnScrollLeftOutUUID"; + in_id = "UIImgBtnScrollLeftInUUID"; + mPrevArrowBtn = new LLButton("Left Arrow", left_arrow_btn_rect, + out_id, in_id, "", + &LLTabContainer::onPrevBtn, this, LLFontGL::sSansSerif ); + mPrevArrowBtn->setHeldDownCallback(onPrevBtnHeld); + mPrevArrowBtn->setFollowsLeft(); + + out_id = "UIImgBtnJumpRightOutUUID"; + in_id = "UIImgBtnJumpRightInUUID"; + mJumpNextArrowBtn = new LLButton("Jump Right Arrow", jump_right_arrow_btn_rect, + out_id, in_id, "", + &LLTabContainer::onJumpLastBtn, this, + LLFontGL::sSansSerif); + mJumpNextArrowBtn->setFollowsRight(); + + out_id = "UIImgBtnScrollRightOutUUID"; + in_id = "UIImgBtnScrollRightInUUID"; + mNextArrowBtn = new LLButton("Right Arrow", right_arrow_btn_rect, + out_id, in_id, "", + &LLTabContainer::onNextBtn, this, + LLFontGL::sSansSerif); + mNextArrowBtn->setFollowsRight(); + + if( getTabPosition() == TOP ) { - btn->setFollowsTop(); + mNextArrowBtn->setFollowsTop(); + mPrevArrowBtn->setFollowsTop(); + mJumpPrevArrowBtn->setFollowsTop(); + mJumpNextArrowBtn->setFollowsTop(); } else { - btn->setFollowsBottom(); + mNextArrowBtn->setFollowsBottom(); + mPrevArrowBtn->setFollowsBottom(); + mJumpPrevArrowBtn->setFollowsBottom(); + mJumpNextArrowBtn->setFollowsBottom(); } - - LLTabTuple* tuple = new LLTabTuple( this, child, btn, on_tab_clicked, userdata ); - btn->setCallbackUserData( tuple ); - addChild( btn, 0 ); - addChild( child, 1 ); - insertTuple(tuple, insertion_point); } - updateMaxScrollPos(); + mPrevArrowBtn->setHeldDownCallback(onPrevBtnHeld); + mPrevArrowBtn->setSaveToXML(false); + mPrevArrowBtn->setTabStop(FALSE); + addChild(mPrevArrowBtn); - if( select ) + mNextArrowBtn->setHeldDownCallback(onNextBtnHeld); + mNextArrowBtn->setSaveToXML(false); + mNextArrowBtn->setTabStop(FALSE); + addChild(mNextArrowBtn); + + if (mJumpPrevArrowBtn) { - selectLastTab(); + mJumpPrevArrowBtn->setSaveToXML(false); + mJumpPrevArrowBtn->setTabStop(FALSE); + addChild(mJumpPrevArrowBtn); } + + if (mJumpNextArrowBtn) + { + mJumpNextArrowBtn->setSaveToXML(false); + mJumpNextArrowBtn->setTabStop(FALSE); + addChild(mJumpNextArrowBtn); + } + + // set default tab group to be panel contents + setDefaultTabGroup(1); } -void LLTabContainer::removeTabPanel(LLPanel* child) +LLTabContainer::LLTabTuple* LLTabContainer::getTabByPanel(LLPanel* child) { - // Adjust the total tab width. for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { LLTabTuple* tuple = *iter; if( tuple->mTabPanel == child ) { - mTotalTabWidth -= tuple->mButton->getRect().getWidth(); - break; + return tuple; } } - - LLTabContainerCommon::removeTabPanel(child); -} - -void LLTabContainer::setPanelTitle(S32 index, const LLString& title) -{ - if (index >= 0 && index < (S32)mTabList.size()) - { - LLTabTuple* tuple = mTabList[index]; - LLButton* tab_button = tuple->mButton; - const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); - mTotalTabWidth -= tab_button->getRect().getWidth(); - tab_button->reshape(llclamp(fontp->getWidth(title) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight()); - mTotalTabWidth += tab_button->getRect().getWidth(); - tab_button->setLabelSelected(title); - tab_button->setLabelUnselected(title); - } - updateMaxScrollPos(); + return NULL; } - -void LLTabContainer::updateMaxScrollPos() +void LLTabContainer::insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_point) { - S32 tab_space = 0; - S32 available_space = 0; - tab_space = mTotalTabWidth; - available_space = mRect.getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_TAB_H_PAD); - - if( tab_space > available_space ) + switch(insertion_point) { - S32 available_width_with_arrows = mRect.getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); - // subtract off reserved portion on left - available_width_with_arrows -= TABCNTR_TAB_PARTIAL_WIDTH; - - S32 running_tab_width = 0; - mMaxScrollPos = mTabList.size(); - for(tuple_list_t::reverse_iterator tab_it = mTabList.rbegin(); tab_it != mTabList.rend(); ++tab_it) + case START: + // insert the new tab in the front of the list + mTabList.insert(mTabList.begin() + mLockedTabCount, tuple); + break; + case LEFT_OF_CURRENT: + // insert the new tab before the current tab (but not before mLockedTabCount) { - running_tab_width += (*tab_it)->mButton->getRect().getWidth(); - if (running_tab_width > available_width_with_arrows) - { - break; - } - mMaxScrollPos--; + tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx); + mTabList.insert(current_iter, tuple); } - // in case last tab doesn't actually fit on screen, make it the last scrolling position - mMaxScrollPos = llmin(mMaxScrollPos, (S32)mTabList.size() - 1); - } - else - { - mMaxScrollPos = 0; - mScrollPos = 0; - } - if (mScrollPos > mMaxScrollPos) - { - mScrollPos = mMaxScrollPos; - } -} + break; -void LLTabContainer::commitHoveredButton(S32 x, S32 y) -{ - if (hasMouseCapture()) - { - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + case RIGHT_OF_CURRENT: + // insert the new tab after the current tab (but not before mLockedTabCount) { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( TRUE ); - S32 local_x = x - tuple->mButton->getRect().mLeft; - S32 local_y = y - tuple->mButton->getRect().mBottom; - if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible()) - { - tuple->mButton->onCommit(); - } + tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx + 1); + mTabList.insert(current_iter, tuple); } + break; + case END: + default: + mTabList.push_back( tuple ); } } -void LLTabContainer::setMinTabWidth(S32 width) -{ - mMinTabWidth = width; -} - -void LLTabContainer::setMaxTabWidth(S32 width) -{ - mMaxTabWidth = width; -} - -S32 LLTabContainer::getMinTabWidth() const -{ - return mMinTabWidth; -} -S32 LLTabContainer::getMaxTabWidth() const -{ - return mMaxTabWidth; -} -BOOL LLTabContainer::selectTab(S32 which) +void LLTabContainer::updateMaxScrollPos() { - if (which >= (S32)mTabList.size()) return FALSE; - if (which < 0) return FALSE; - - //if( gFocusMgr.childHasKeyboardFocus( this ) ) - //{ - // gFocusMgr.setKeyboardFocus( NULL ); - //} - - LLTabTuple* selected_tuple = mTabList[which]; - if (!selected_tuple) - { - return FALSE; - } - - if (mTabList[which]->mButton->getEnabled()) + BOOL no_scroll = TRUE; + if (mIsVertical) { - mCurrentTabIdx = which; - - S32 i = 0; - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + S32 tab_total_height = (BTN_HEIGHT + TABCNTRV_PAD) * getTabCount(); + S32 available_height = getRect().getHeight() - getTopBorderHeight(); + if( tab_total_height > available_height ) { - LLTabTuple* tuple = *iter; - BOOL is_selected = ( tuple == selected_tuple ); - tuple->mTabPanel->setVisible( is_selected ); -// tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here. - tuple->mButton->setToggleState( is_selected ); - // RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs - tuple->mButton->setTabStop( is_selected ); - - if( is_selected && mMaxScrollPos > 0) - { - // Make sure selected tab is within scroll region - if( i < mScrollPos ) - { - mScrollPos = i; - } - else - { - S32 available_width_with_arrows = mRect.getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); - S32 running_tab_width = tuple->mButton->getRect().getWidth(); - S32 j = i - 1; - S32 min_scroll_pos = i; - if (running_tab_width < available_width_with_arrows) - { - while (j >= 0) - { - LLTabTuple* other_tuple = mTabList[j]; - running_tab_width += other_tuple->mButton->getRect().getWidth(); - if (running_tab_width > available_width_with_arrows) - { - break; - } - j--; - } - min_scroll_pos = j + 1; - } - mScrollPos = llclamp(mScrollPos, min_scroll_pos, i); - mScrollPos = llmin(mScrollPos, mMaxScrollPos); - } - } - i++; - } - if( selected_tuple->mOnChangeCallback ) - { - selected_tuple->mOnChangeCallback( selected_tuple->mUserData, false ); + S32 available_height_with_arrows = getRect().getHeight() - 2*(TABCNTRV_ARROW_BTN_SIZE + 3*TABCNTRV_PAD); + S32 additional_needed = tab_total_height - available_height_with_arrows; + setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) ); + no_scroll = FALSE; } - return TRUE; } else { - return FALSE; - } -} + S32 tab_space = 0; + S32 available_space = 0; + tab_space = mTotalTabWidth; + available_space = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_TAB_H_PAD); -void LLTabContainer::draw() -{ - S32 target_pixel_scroll = 0; - S32 cur_scroll_pos = mScrollPos; - if (cur_scroll_pos > 0) - { - S32 available_width_with_arrows = mRect.getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + if( tab_space > available_space ) { - if (cur_scroll_pos == 0) - { - break; - } - target_pixel_scroll += (*iter)->mButton->getRect().getWidth(); - cur_scroll_pos--; - } + S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); + // subtract off reserved portion on left + available_width_with_arrows -= TABCNTR_TAB_PARTIAL_WIDTH; - // Show part of the tab to the left of what is fully visible - target_pixel_scroll -= TABCNTR_TAB_PARTIAL_WIDTH; - // clamp so that rightmost tab never leaves right side of screen - target_pixel_scroll = llmin(mTotalTabWidth - available_width_with_arrows, target_pixel_scroll); - } - - mScrollPosPixels = (S32)lerp((F32)mScrollPosPixels, (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f)); - if( getVisible() ) - { - BOOL has_scroll_arrows = (mMaxScrollPos > 0) || (mScrollPosPixels > 0); - mJumpLeftArrowBtn->setVisible( has_scroll_arrows ); - mJumpRightArrowBtn->setVisible( has_scroll_arrows ); - mLeftArrowBtn->setVisible( has_scroll_arrows ); - mRightArrowBtn->setVisible( has_scroll_arrows ); - - // Set the leftmost position of the tab buttons. - S32 left = LLPANEL_BORDER_WIDTH + (has_scroll_arrows ? (TABCNTR_ARROW_BTN_SIZE * 2) : TABCNTR_TAB_H_PAD); - left -= mScrollPosPixels; - - // Hide all the buttons - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( FALSE ); - } - - LLPanel::draw(); - - // if tabs are hidden, don't draw them and leave them in the invisible state - if (!mTabsHidden) - { - // Show all the buttons - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( TRUE ); - } - - // Draw some of the buttons... - LLRect clip_rect = getLocalRect(); - if (has_scroll_arrows) + S32 running_tab_width = 0; + setMaxScrollPos(getTabCount()); + for(tuple_list_t::reverse_iterator tab_it = mTabList.rbegin(); tab_it != mTabList.rend(); ++tab_it) { - // ...but clip them. - clip_rect.mLeft = mLeftArrowBtn->getRect().mRight; - clip_rect.mRight = mRightArrowBtn->getRect().mLeft; - } - LLLocalClipRect clip(clip_rect); - - S32 max_scroll_visible = mTabList.size() - mMaxScrollPos + mScrollPos; - S32 idx = 0; - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - - tuple->mButton->translate( left - tuple->mButton->getRect().mLeft, 0 ); - left += tuple->mButton->getRect().getWidth(); - - if( idx < mScrollPos ) - { - if( tuple->mButton->getFlashing() ) - { - mLeftArrowBtn->setFlashing( TRUE ); - } - } - else - if( max_scroll_visible < idx ) + running_tab_width += (*tab_it)->mButton->getRect().getWidth(); + if (running_tab_width > available_width_with_arrows) { - if( tuple->mButton->getFlashing() ) - { - mRightArrowBtn->setFlashing( TRUE ); - } - } - - LLUI::pushMatrix(); - { - LLUI::translate((F32)tuple->mButton->getRect().mLeft, (F32)tuple->mButton->getRect().mBottom, 0.f); - tuple->mButton->draw(); + break; } - LLUI::popMatrix(); - - idx++; + setMaxScrollPos(getMaxScrollPos()-1); } + // in case last tab doesn't actually fit on screen, make it the last scrolling position + setMaxScrollPos(llmin(getMaxScrollPos(), getTabCount() - 1)); + no_scroll = FALSE; } - - mLeftArrowBtn->setFlashing(FALSE); - mRightArrowBtn->setFlashing(FALSE); } -} - - -void LLTabContainer::setRightTabBtnOffset(S32 offset) -{ - mRightArrowBtn->translate( -offset - mRightTabBtnOffset, 0 ); - mRightTabBtnOffset = offset; - updateMaxScrollPos(); -} - -BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - BOOL has_scroll_arrows = (mMaxScrollPos > 0); - - if (has_scroll_arrows) - { - if (mJumpLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpLeftArrowBtn->getRect().mBottom; - handled = mJumpLeftArrowBtn->handleMouseDown(local_x, local_y, mask); - } - if (mJumpRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpRightArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpRightArrowBtn->getRect().mBottom; - handled = mJumpRightArrowBtn->handleMouseDown(local_x, local_y, mask); - } - if (mLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mLeftArrowBtn->getRect().mBottom; - handled = mLeftArrowBtn->handleMouseDown(local_x, local_y, mask); - } - else if (mRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mRightArrowBtn->getRect().mLeft; - S32 local_y = y - mRightArrowBtn->getRect().mBottom; - handled = mRightArrowBtn->handleMouseDown(local_x, local_y, mask); - } - } - if (!handled) + if (no_scroll) { - handled = LLPanel::handleMouseDown( x, y, mask ); - } - - if (mTabList.size() > 0) - { - LLTabTuple* firsttuple = mTabList[0]; - LLRect tab_rect(has_scroll_arrows ? mLeftArrowBtn->getRect().mRight : mJumpLeftArrowBtn->getRect().mLeft, - firsttuple->mButton->getRect().mTop, - has_scroll_arrows ? mRightArrowBtn->getRect().mLeft : mJumpRightArrowBtn->getRect().mRight, - firsttuple->mButton->getRect().mBottom ); - if( tab_rect.pointInRect( x, y ) ) - { - LLButton* tab_button = mTabList[getCurrentPanelIndex()]->mButton; - gFocusMgr.setMouseCapture(this); - gFocusMgr.setKeyboardFocus(tab_button); - } - } - return handled; -} - -BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - BOOL has_scroll_arrows = (mMaxScrollPos > 0); - - if (has_scroll_arrows) - { - if (mJumpLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpLeftArrowBtn->getRect().mBottom; - handled = mJumpLeftArrowBtn->handleHover(local_x, local_y, mask); - } - if (mJumpRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpRightArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpRightArrowBtn->getRect().mBottom; - handled = mJumpRightArrowBtn->handleHover(local_x, local_y, mask); - } - if (mLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mLeftArrowBtn->getRect().mBottom; - handled = mLeftArrowBtn->handleHover(local_x, local_y, mask); - } - else if (mRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mRightArrowBtn->getRect().mLeft; - S32 local_y = y - mRightArrowBtn->getRect().mBottom; - handled = mRightArrowBtn->handleHover(local_x, local_y, mask); - } + setMaxScrollPos(0); + setScrollPos(0); } - if (!handled) + if (getScrollPos() > getMaxScrollPos()) { - handled = LLPanel::handleHover(x, y, mask); + setScrollPos(getMaxScrollPos()); // maybe just enforce this via limits in setScrollPos instead? } - - commitHoveredButton(x, y); - return handled; } -BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask ) +void LLTabContainer::commitHoveredButton(S32 x, S32 y) { - BOOL handled = FALSE; - BOOL has_scroll_arrows = (mMaxScrollPos > 0); - - if (has_scroll_arrows) - { - if (mJumpLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpLeftArrowBtn->getRect().mBottom; - handled = mJumpLeftArrowBtn->handleMouseUp(local_x, local_y, mask); - } - if (mJumpRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpRightArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpRightArrowBtn->getRect().mBottom; - handled = mJumpRightArrowBtn->handleMouseUp(local_x, local_y, mask); - } - if (mLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mLeftArrowBtn->getRect().mBottom; - handled = mLeftArrowBtn->handleMouseUp(local_x, local_y, mask); - } - else if (mRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mRightArrowBtn->getRect().mLeft; - S32 local_y = y - mRightArrowBtn->getRect().mBottom; - handled = mRightArrowBtn->handleMouseUp(local_x, local_y, mask); - } - } - if (!handled) - { - handled = LLPanel::handleMouseUp( x, y, mask ); - } - - commitHoveredButton(x, y); - LLPanel* cur_panel = getCurrentPanel(); if (hasMouseCapture()) { - if (cur_panel) - { - if (!cur_panel->focusFirstItem(FALSE)) - { - // if nothing in the panel gets focus, make sure the new tab does - // otherwise the last tab might keep focus - mTabList[getCurrentPanelIndex()]->mButton->setFocus(TRUE); - } - } - gFocusMgr.setMouseCapture(NULL); - } - return handled; -} - -BOOL LLTabContainer::handleToolTip( S32 x, S32 y, LLString& msg, LLRect* sticky_rect ) -{ - BOOL handled = LLPanel::handleToolTip( x, y, msg, sticky_rect ); - if (!handled && mTabList.size() > 0) - { - LLTabTuple* firsttuple = mTabList[0]; - - BOOL has_scroll_arrows = (mMaxScrollPos > 0); - LLRect clip( - has_scroll_arrows ? mJumpLeftArrowBtn->getRect().mRight : mJumpLeftArrowBtn->getRect().mLeft, - firsttuple->mButton->getRect().mTop, - has_scroll_arrows ? mRightArrowBtn->getRect().mLeft : mRightArrowBtn->getRect().mRight, - 0 ); - if( clip.pointInRect( x, y ) ) - { - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( TRUE ); - S32 local_x = x - tuple->mButton->getRect().mLeft; - S32 local_y = y - tuple->mButton->getRect().mBottom; - handled = tuple->mButton->handleToolTip( local_x, local_y, msg, sticky_rect ); - if( handled ) - { - break; - } - } - } - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( FALSE ); - } - } - return handled; -} - -BOOL LLTabContainer::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) -{ - if (!getEnabled()) return FALSE; - - if (!gFocusMgr.childHasKeyboardFocus(this)) return FALSE; - - BOOL handled = FALSE; - if (key == KEY_LEFT && mask == MASK_ALT) - { - selectPrevTab(); - handled = TRUE; - } - else if (key == KEY_RIGHT && mask == MASK_ALT) - { - selectNextTab(); - handled = TRUE; - } - - if (handled) - { - if (getCurrentPanel()) - { - getCurrentPanel()->setFocus(TRUE); - } - } - - if (!gFocusMgr.childHasKeyboardFocus(getCurrentPanel())) - { - // if child has focus, but not the current panel, focus - // is on a button - switch(key) - { - case KEY_UP: - if (getTabPosition() == BOTTOM && getCurrentPanel()) - { - getCurrentPanel()->setFocus(TRUE); - } - handled = TRUE; - break; - case KEY_DOWN: - if (getTabPosition() == TOP && getCurrentPanel()) - { - getCurrentPanel()->setFocus(TRUE); - } - handled = TRUE; - break; - case KEY_LEFT: - selectPrevTab(); - handled = TRUE; - break; - case KEY_RIGHT: - selectNextTab(); - handled = TRUE; - break; - default: - break; - } - } - return handled; -} - -// virtual -LLXMLNodePtr LLTabContainer::getXML(bool save_children) const -{ - LLXMLNodePtr node = LLTabContainerCommon::getXML(); - - node->createChild("tab_position", TRUE)->setStringValue((mTabPosition == TOP ? "top" : "bottom")); - - return node; -} - -BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType type, void* cargo_data, EAcceptance *accept, LLString &tooltip) -{ - BOOL has_scroll_arrows = (mMaxScrollPos > 0); - - if( mDragAndDropDelayTimer.getElapsedTimeF32() > SCROLL_DELAY_TIME ) - { - - if (has_scroll_arrows) - { - if (mJumpLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpLeftArrowBtn->getRect().mBottom; - mJumpLeftArrowBtn->handleHover(local_x, local_y, mask); - } - if (mJumpRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpRightArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpRightArrowBtn->getRect().mBottom; - mJumpRightArrowBtn->handleHover(local_x, local_y, mask); - } - if (mLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mLeftArrowBtn->getRect().mBottom; - mLeftArrowBtn->handleHover(local_x, local_y, mask); - } - else if (mRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mRightArrowBtn->getRect().mLeft; - S32 local_y = y - mRightArrowBtn->getRect().mBottom; - mRightArrowBtn->handleHover(local_x, local_y, mask); - } - } - - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( TRUE ); - S32 local_x = x - tuple->mButton->getRect().mLeft; - S32 local_y = y - tuple->mButton->getRect().mBottom; - if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible()) + tuple->mButton->setVisible( TRUE ); + S32 local_x = x - tuple->mButton->getRect().mLeft; + S32 local_y = y - tuple->mButton->getRect().mBottom; + if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible()) { tuple->mButton->onCommit(); - mDragAndDropDelayTimer.stop(); } } } - - return LLView::handleDragAndDrop(x, y, mask, drop, type, cargo_data, accept, tooltip); } -void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const LLColor4& color) -{ - LLTabTuple* tuple = getTabByPanel(child); - if( tuple ) - { - tuple->mButton->setImageOverlay(image_name, LLFontGL::RIGHT, color); - - const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); - // remove current width from total tab strip width - mTotalTabWidth -= tuple->mButton->getRect().getWidth(); - - S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? - tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : - 0; - - tuple->mPadding = image_overlay_width; - - tuple->mButton->setRightHPad(6); - tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), - tuple->mButton->getRect().getHeight()); - // add back in button width to total tab strip width - mTotalTabWidth += tuple->mButton->getRect().getWidth(); - - // tabs have changed size, might need to scroll to see current tab - updateMaxScrollPos(); - } -} diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index b72ecb8126..7c0463ee5b 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -1,6 +1,6 @@ /** * @file lltabcontainer.h - * @brief LLTabContainerCommon base class + * @brief LLTabContainer class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -29,19 +29,16 @@ * $/LicenseInfo$ */ -// Fear my script-fu! - #ifndef LL_TABCONTAINER_H #define LL_TABCONTAINER_H #include "llpanel.h" +#include "lltextbox.h" #include "llframetimer.h" -class LLButton; -class LLTextBox; - +extern const S32 TABCNTR_HEADER_HEIGHT; -class LLTabContainerCommon : public LLPanel +class LLTabContainer : public LLPanel { public: enum TabPosition @@ -58,81 +55,82 @@ public: RIGHT_OF_CURRENT } eInsertionPoint; - LLTabContainerCommon( const LLString& name, - const LLRect& rect, - TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - BOOL bordered = TRUE); - - LLTabContainerCommon( const LLString& name, - const LLString& rect_control, - TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - BOOL bordered = TRUE); + LLTabContainer( const LLString& name, const LLRect& rect, TabPosition pos, + BOOL bordered, BOOL is_vertical); - virtual ~LLTabContainerCommon(); + /*virtual*/ ~LLTabContainer(); - virtual void initButtons() = 0; - - virtual void setValue(const LLSD& value) { selectTab((S32) value.asInteger()); } - virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TAB_CONTAINER; } - virtual LLString getWidgetTag() const { return LL_TAB_CONTAINER_COMMON_TAG; } - - virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; - - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - - virtual void addTabPanel(LLPanel* child, - const LLString& label, - BOOL select = FALSE, - void (*on_tab_clicked)(void*, bool) = NULL, - void* userdata = NULL, - S32 indent = 0, - BOOL placeholder = FALSE, - eInsertionPoint insertion_point = END) = 0; - virtual void addPlaceholder(LLPanel* child, const LLString& label); - virtual void lockTabs(S32 num_tabs = 0); - virtual void unlockTabs(); - S32 getNumLockedTabs() { return mLockedTabCount; } - - virtual void enableTabButton(S32 which, BOOL enable); - - virtual void removeTabPanel( LLPanel* child ); - virtual void deleteAllTabs(); - virtual LLPanel* getCurrentPanel(); - virtual S32 getCurrentPanelIndex(); - virtual S32 getTabCount(); - virtual S32 getPanelIndexByTitle(const LLString& title); - virtual LLPanel* getPanelByIndex(S32 index); - virtual LLPanel* getPanelByName(const LLString& name); - virtual S32 getIndexForPanel(LLPanel* panel); - - virtual void setCurrentTabName(const LLString& name); - - - virtual void selectFirstTab(); - virtual void selectLastTab(); - virtual BOOL selectTabPanel( LLPanel* child ); - virtual BOOL selectTab(S32 which) = 0; - virtual BOOL selectTabByName(const LLString& title); - virtual void selectNextTab(); - virtual void selectPrevTab(); + // from LLView + /*virtual*/ void setValue(const LLSD& value); + /*virtual*/ EWidgetType getWidgetType() const; + /*virtual*/ LLString getWidgetTag() const; + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); + /*virtual*/ void draw(); + /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect ); + /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); + /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType type, void* cargo_data, + EAcceptance* accept, LLString& tooltip); + /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; + + void addTabPanel(LLPanel* child, + const LLString& label, + BOOL select = FALSE, + void (*on_tab_clicked)(void*, bool) = NULL, + void* userdata = NULL, + S32 indent = 0, + BOOL placeholder = FALSE, + eInsertionPoint insertion_point = END); + void addPlaceholder(LLPanel* child, const LLString& label); + void removeTabPanel( LLPanel* child ); + void lockTabs(S32 num_tabs = 0); + void unlockTabs(); + S32 getNumLockedTabs() { return mLockedTabCount; } + void enableTabButton(S32 which, BOOL enable); + void deleteAllTabs(); + LLPanel* getCurrentPanel(); + S32 getCurrentPanelIndex(); + S32 getTabCount(); + LLPanel* getPanelByIndex(S32 index); + S32 getIndexForPanel(LLPanel* panel); + S32 getPanelIndexByTitle(const LLString& title); + LLPanel* getPanelByName(const LLString& name); + void setCurrentTabName(const LLString& name); + + void selectFirstTab(); + void selectLastTab(); + void selectNextTab(); + void selectPrevTab(); + BOOL selectTabPanel( LLPanel* child ); + BOOL selectTab(S32 which); + BOOL selectTabByName(const LLString& title); BOOL getTabPanelFlashing(LLPanel* child); void setTabPanelFlashing(LLPanel* child, BOOL state); - virtual void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white); + void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white); void setTitle( const LLString& title ); const LLString getPanelTitle(S32 index); - void setDragAndDropDelayTimer() { mDragAndDropDelayTimer.start(); } - - virtual void setTopBorderHeight(S32 height); + void setTopBorderHeight(S32 height); + S32 getTopBorderHeight() const; - virtual void setTabChangeCallback(LLPanel* tab, void (*on_tab_clicked)(void*,bool)); - virtual void setTabUserData(LLPanel* tab, void* userdata); + void setTabChangeCallback(LLPanel* tab, void (*on_tab_clicked)(void*,bool)); + void setTabUserData(LLPanel* tab, void* userdata); - virtual void reshape(S32 width, S32 height, BOOL called_from_parent); + void setRightTabBtnOffset( S32 offset ); + void setPanelTitle(S32 index, const LLString& title); + TabPosition getTabPosition() const { return mTabPosition; } + void setMinTabWidth(S32 width) { mMinTabWidth = width; } + void setMaxTabWidth(S32 width) { mMaxTabWidth = width; } + S32 getMinTabWidth() const { return mMinTabWidth; } + S32 getMaxTabWidth() const { return mMaxTabWidth; } + + void startDragAndDropDelayTimer() { mDragAndDropDelayTimer.start(); } + static void onCloseBtn(void* userdata); static void onTabBtn(void* userdata); static void onNextBtn(void* userdata); @@ -142,17 +140,17 @@ public: static void onJumpFirstBtn( void* userdata ); static void onJumpLastBtn( void* userdata ); - virtual void setRightTabBtnOffset( S32 offset ) { } - virtual void setPanelTitle(S32 index, const LLString& title) { } + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - virtual TabPosition getTabPosition() { return mTabPosition; } +protected: + /*virtual*/ LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; -protected: +private: // Structure used to map tab buttons to and from tab panels struct LLTabTuple { - LLTabTuple( LLTabContainerCommon* c, LLPanel* p, LLButton* b, + LLTabTuple( LLTabContainer* c, LLPanel* p, LLButton* b, void (*cb)(void*,bool), void* userdata, LLTextBox* placeholder = NULL ) : mTabContainer(c), @@ -165,7 +163,7 @@ protected: mPadding(0) {} - LLTabContainerCommon* mTabContainer; + LLTabContainer* mTabContainer; LLPanel* mTabPanel; LLButton* mButton; void (*mOnChangeCallback)(void*, bool); @@ -175,8 +173,35 @@ protected: S32 mPadding; }; + void initButtons(); + + LLTabTuple* getTab(S32 index) { return mTabList[index]; } + LLTabTuple* getTabByPanel(LLPanel* child); + void insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_point); + + S32 getScrollPos() const { return mScrollPos; } + void setScrollPos(S32 pos) { mScrollPos = pos; } + S32 getMaxScrollPos() const { return mMaxScrollPos; } + void setMaxScrollPos(S32 pos) { mMaxScrollPos = pos; } + S32 getScrollPosPixels() const { return mScrollPosPixels; } + void setScrollPosPixels(S32 pixels) { mScrollPosPixels = pixels; } + + void setTabsHidden(BOOL hidden) { mTabsHidden = hidden; } + BOOL getTabsHidden() const { return mTabsHidden; } + + void setCurrentPanelIndex(S32 index) { mCurrentTabIdx = index; } + + void scrollPrev() { mScrollPos = llmax(0, mScrollPos-1); } // No wrap + void scrollNext() { mScrollPos = llmin(mScrollPos+1, mMaxScrollPos); } // No wrap + + void updateMaxScrollPos(); + void commitHoveredButton(S32 x, S32 y); + + // Variables + typedef std::vector<LLTabTuple*> tuple_list_t; tuple_list_t mTabList; + S32 mCurrentTabIdx; BOOL mTabsHidden; @@ -186,8 +211,6 @@ protected: S32 mScrollPosPixels; S32 mMaxScrollPos; - LLFrameTimer mDragAndDropDelayTimer; - void (*mCloseCallback)(void*); void* mCallbackUserdata; @@ -196,87 +219,23 @@ protected: S32 mTopBorderHeight; TabPosition mTabPosition; S32 mLockedTabCount; + S32 mMinTabWidth; + LLButton* mPrevArrowBtn; + LLButton* mNextArrowBtn; -protected: - void scrollPrev(); - void scrollNext(); - - virtual void updateMaxScrollPos() = 0; - virtual void commitHoveredButton(S32 x, S32 y) = 0; - LLTabTuple* getTabByPanel(LLPanel* child); - void insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_point); -}; - -class LLTabContainer : public LLTabContainerCommon -{ -public: - LLTabContainer( const LLString& name, const LLRect& rect, TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - const LLString& title=LLString::null, BOOL bordered = TRUE ); - - LLTabContainer( const LLString& name, const LLString& rect_control, TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - const LLString& title=LLString::null, BOOL bordered = TRUE ); - - ~LLTabContainer(); - - /*virtual*/ void initButtons(); - - /*virtual*/ void draw(); - - /*virtual*/ void addTabPanel(LLPanel* child, - const LLString& label, - BOOL select = FALSE, - void (*on_tab_clicked)(void*, bool) = NULL, - void* userdata = NULL, - S32 indent = 0, - BOOL placeholder = FALSE, - eInsertionPoint insertion_point = END); - - /*virtual*/ BOOL selectTab(S32 which); - /*virtual*/ void removeTabPanel( LLPanel* child ); - - /*virtual*/ void setPanelTitle(S32 index, const LLString& title); - /*virtual*/ void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white); - /*virtual*/ void setRightTabBtnOffset( S32 offset ); - - /*virtual*/ void setMinTabWidth(S32 width); - /*virtual*/ void setMaxTabWidth(S32 width); - - /*virtual*/ S32 getMinTabWidth() const; - /*virtual*/ S32 getMaxTabWidth() const; - - /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect ); - /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); - /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType type, void* cargo_data, - EAcceptance* accept, LLString& tooltip); - - virtual LLXMLNodePtr getXML(bool save_children = true) const; - + BOOL mIsVertical; -protected: - - LLButton* mLeftArrowBtn; - LLButton* mJumpLeftArrowBtn; - LLButton* mRightArrowBtn; - LLButton* mJumpRightArrowBtn; + // Horizontal specific + LLButton* mJumpPrevArrowBtn; + LLButton* mJumpNextArrowBtn; S32 mRightTabBtnOffset; // Extra room to the right of the tab buttons. -protected: - virtual void updateMaxScrollPos(); - virtual void commitHoveredButton(S32 x, S32 y); - - S32 mMinTabWidth; S32 mMaxTabWidth; S32 mTotalTabWidth; + + LLFrameTimer mDragAndDropDelayTimer; }; -const S32 TABCNTR_CLOSE_BTN_SIZE = 16; -const S32 TABCNTR_HEADER_HEIGHT = LLPANEL_BORDER_WIDTH + TABCNTR_CLOSE_BTN_SIZE; #endif // LL_TABCONTAINER_H diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 3b15e3a25f..0c5bc2da81 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -30,21 +30,14 @@ */ #include "linden_common.h" - #include "lltextbox.h" - -#include "llerror.h" -#include "llgl.h" -#include "llui.h" #include "lluictrlfactory.h" -#include "llcontrol.h" #include "llfocusmgr.h" -#include "llstl.h" -#include <boost/tokenizer.hpp> LLTextBox::LLTextBox(const LLString& name, const LLRect& rect, const LLString& text, const LLFontGL* font, BOOL mouse_opaque) : LLUICtrl(name, rect, mouse_opaque, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP ), + mFontGL(font ? font : LLFontGL::sSansSerifSmall), mTextColor( LLUI::sColorsGroup->getColor( "LabelTextColor" ) ), mDisabledColor( LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ), mBackgroundColor( LLUI::sColorsGroup->getColor( "DefaultBackgroundColor" ) ), @@ -64,9 +57,7 @@ LLTextBox::LLTextBox(const LLString& name, const LLRect& rect, const LLString& t mClickedCallback(NULL), mCallbackUserData(NULL) { - // TomY TODO Nuke this eventually - setText( !text.empty() ? text : name ); - mFontGL = font ? font : LLFontGL::sSansSerifSmall; + setText( text ); setTabStop(FALSE); } @@ -93,25 +84,54 @@ LLTextBox::LLTextBox(const LLString& name, const LLString& text, F32 max_width, mClickedCallback(NULL), mCallbackUserData(NULL) { - setWrappedText(!text.empty() ? text : name, max_width); + setWrappedText(text, max_width); reshapeToFitText(); setTabStop(FALSE); } -LLTextBox::~LLTextBox() -{ -} - -// virtual -EWidgetType LLTextBox::getWidgetType() const +LLTextBox::LLTextBox(const LLString& name_and_label, const LLRect& rect) : + LLUICtrl(name_and_label, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP), + mFontGL(LLFontGL::sSansSerifSmall), + mTextColor(LLUI::sColorsGroup->getColor("LabelTextColor")), + mDisabledColor(LLUI::sColorsGroup->getColor("LabelDisabledColor")), + mBackgroundColor(LLUI::sColorsGroup->getColor("DefaultBackgroundColor")), + mBorderColor(LLUI::sColorsGroup->getColor("DefaultHighlightLight")), + mBackgroundVisible(FALSE), + mBorderVisible(FALSE), + mFontStyle(LLFontGL::DROP_SHADOW_SOFT), + mBorderDropShadowVisible(FALSE), + mHPad(0), + mVPad(0), + mHAlign(LLFontGL::LEFT), + mVAlign( LLFontGL::TOP ), + mClickedCallback(NULL), + mCallbackUserData(NULL) { - return WIDGET_TYPE_TEXT_BOX; + setText( name_and_label ); + setTabStop(FALSE); } -// virtual -LLString LLTextBox::getWidgetTag() const +LLTextBox::LLTextBox(const LLString& name_and_label) : + LLUICtrl(name_and_label, LLRect(0, 0, 1, 1), TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP), + mFontGL(LLFontGL::sSansSerifSmall), + mTextColor(LLUI::sColorsGroup->getColor("LabelTextColor")), + mDisabledColor(LLUI::sColorsGroup->getColor("LabelDisabledColor")), + mBackgroundColor(LLUI::sColorsGroup->getColor("DefaultBackgroundColor")), + mBorderColor(LLUI::sColorsGroup->getColor("DefaultHighlightLight")), + mBackgroundVisible(FALSE), + mBorderVisible(FALSE), + mFontStyle(LLFontGL::DROP_SHADOW_SOFT), + mBorderDropShadowVisible(FALSE), + mHPad(0), + mVPad(0), + mHAlign(LLFontGL::LEFT), + mVAlign( LLFontGL::TOP ), + mClickedCallback(NULL), + mCallbackUserData(NULL) { - return LL_TEXT_BOX_TAG; + setWrappedText(name_and_label); + reshapeToFitText(); + setTabStop(FALSE); } BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask) @@ -127,7 +147,7 @@ BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask) // Route future Mouse messages here preemptively. (Release on mouse up.) gFocusMgr.setMouseCapture( this ); - if (mSoundFlags & MOUSE_DOWN) + if (getSoundFlags() & MOUSE_DOWN) { make_ui_sound("UISndClick"); } @@ -153,7 +173,7 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask) // Release the mouse gFocusMgr.setMouseCapture( NULL ); - if (mSoundFlags & MOUSE_UP) + if (getSoundFlags() & MOUSE_UP) { make_ui_sound("UISndClickRelease"); } @@ -294,16 +314,6 @@ S32 LLTextBox::getTextPixelHeight() } -void LLTextBox::setValue(const LLSD& value ) -{ - setText(value.asString()); -} - -LLSD LLTextBox::getValue() const -{ - return LLSD(getText()); -} - BOOL LLTextBox::setTextArg( const LLString& key, const LLStringExplicit& text ) { mText.setArg(key, text); @@ -324,13 +334,13 @@ void LLTextBox::draw() { static LLColor4 color_drop_shadow = LLUI::sColorsGroup->getColor("ColorDropShadow"); static S32 drop_shadow_tooltip = LLUI::sConfigGroup->getS32("DropShadowTooltip"); - gl_drop_shadow(0, mRect.getHeight(), mRect.getWidth(), 0, + gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, color_drop_shadow, drop_shadow_tooltip); } if (mBackgroundVisible) { - LLRect r( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 ); gl_rect_2d( r, mBackgroundColor ); } @@ -341,14 +351,14 @@ void LLTextBox::draw() text_x = mHPad; break; case LLFontGL::HCENTER: - text_x = mRect.getWidth() / 2; + text_x = getRect().getWidth() / 2; break; case LLFontGL::RIGHT: - text_x = mRect.getWidth() - mHPad; + text_x = getRect().getWidth() - mHPad; break; } - S32 text_y = mRect.getHeight() - mVPad; + S32 text_y = getRect().getHeight() - mVPad; if ( getEnabled() ) { @@ -360,7 +370,6 @@ void LLTextBox::draw() { drawText( text_x, text_y, mTextColor ); } - } else { @@ -385,7 +394,14 @@ void LLTextBox::reshape(S32 width, S32 height, BOOL called_from_parent) void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) { - if( !mLineLengthList.empty() ) + if( mLineLengthList.empty() ) + { + mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color, + mHAlign, mVAlign, + mFontStyle, + S32_MAX, getRect().getWidth(), NULL, TRUE, mUseEllipses); + } + else { S32 cur_pos = 0; for (std::vector<S32>::iterator iter = mLineLengthList.begin(); @@ -395,21 +411,13 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) mFontGL->render(mText.getWString(), cur_pos, (F32)x, (F32)y, color, mHAlign, mVAlign, mFontStyle, - line_length, mRect.getWidth(), NULL, TRUE, mUseEllipses ); + line_length, getRect().getWidth(), NULL, TRUE, mUseEllipses ); cur_pos += line_length + 1; y -= llfloor(mFontGL->getLineHeight()); } } - else - { - mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color, - mHAlign, mVAlign, - mFontStyle, - S32_MAX, mRect.getWidth(), NULL, TRUE, mUseEllipses); - } } - void LLTextBox::reshapeToFitText() { S32 width = getTextPixelWidth(); @@ -423,28 +431,19 @@ LLXMLNodePtr LLTextBox::getXML(bool save_children) const LLXMLNodePtr node = LLUICtrl::getXML(); // Attributes - node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mFontGL)); - node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(mHAlign)); - addColorXML(node, mTextColor, "text_color", "LabelTextColor"); addColorXML(node, mDisabledColor, "disabled_color", "LabelDisabledColor"); addColorXML(node, mBackgroundColor, "bg_color", "DefaultBackgroundColor"); addColorXML(node, mBorderColor, "border_color", "DefaultHighlightLight"); - node->createChild("bg_visible", TRUE)->setBoolValue(mBackgroundVisible); - node->createChild("border_visible", TRUE)->setBoolValue(mBorderVisible); - node->createChild("border_drop_shadow_visible", TRUE)->setBoolValue(mBorderDropShadowVisible); - node->createChild("h_pad", TRUE)->setIntValue(mHPad); - node->createChild("v_pad", TRUE)->setIntValue(mVPad); // Contents - node->setStringValue(mText); return node; @@ -459,12 +458,6 @@ LLView* LLTextBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f LLString text = node->getTextContents(); - // TomY Yes I know this is a hack, but insert a space to make a blank text field - if (text == "") - { - text = " "; - } - LLTextBox* text_box = new LLTextBox(name, LLRect(), text, @@ -510,6 +503,5 @@ LLView* LLTextBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f text_box->setHoverActive(hover_active); } - return text_box; } diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index d25452b941..ce3a9bb12e 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -35,11 +35,8 @@ #include "lluictrl.h" #include "v4color.h" #include "llstring.h" -#include "llfontgl.h" #include "lluistring.h" -class LLUICtrlFactory; - class LLTextBox : public LLUICtrl @@ -48,18 +45,22 @@ public: // By default, follows top and left and is mouse-opaque. // If no text, text = name. // If no font, uses default system font. - LLTextBox(const LLString& name, const LLRect& rect, const LLString& text = LLString::null, + LLTextBox(const LLString& name, const LLRect& rect, const LLString& text, const LLFontGL* font = NULL, BOOL mouse_opaque = TRUE ); // Construct a textbox which handles word wrapping for us. LLTextBox(const LLString& name, const LLString& text, F32 max_width = 200, const LLFontGL* font = NULL, BOOL mouse_opaque = TRUE ); - virtual ~LLTextBox(); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + // "Simple" constructors for text boxes that have the same name and label *TO BE DEPRECATED* + LLTextBox(const LLString& name_and_label, const LLRect& rect); + LLTextBox(const LLString& name_and_label); + + virtual ~LLTextBox() {} + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TEXT_BOX; } + virtual LLString getWidgetTag() const { return LL_TEXT_BOX_TAG; } virtual LLXMLNodePtr getXML(bool save_children = true) const; - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); virtual void draw(); virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -77,8 +78,7 @@ public: void setHoverActive( BOOL active ) { mHoverActive = active; } void setText( const LLStringExplicit& text ); - void setWrappedText(const LLStringExplicit& text, F32 max_width = -1.0); - // default width means use existing control width + void setWrappedText(const LLStringExplicit& text, F32 max_width = -1.0); // -1 means use existing control width void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; } void setBackgroundVisible(BOOL visible) { mBackgroundVisible = visible; } @@ -90,7 +90,7 @@ public: void setRightAlign() { mHAlign = LLFontGL::RIGHT; } void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } void setClickedCallback( void (*cb)(void *data) ){ mClickedCallback = cb; } // mouse down and up within button - void setCallbackUserData( void* data ) { mCallbackUserData = data; } + void setCallbackUserData( void* data ) { mCallbackUserData = data; } const LLFontGL* getFont() const { return mFontGL; } @@ -100,16 +100,14 @@ public: S32 getTextPixelWidth(); S32 getTextPixelHeight(); - - virtual void setValue(const LLSD& value ); - virtual LLSD getValue() const; + virtual void setValue(const LLSD& value ) { setText(value.asString()); } + virtual LLSD getValue() const { return LLSD(getText()); } virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ); -protected: +private: void setLineLengths(); void drawText(S32 x, S32 y, const LLColor4& color ); -protected: LLUIString mText; const LLFontGL* mFontGL; LLColor4 mTextColor; diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 7cd164ec14..540283c3fe 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -63,15 +63,12 @@ // // Globals // - BOOL gDebugTextEditorTips = FALSE; // // Constants // - const S32 UI_TEXTEDITOR_BUFFER_BLOCK_SIZE = 512; - const S32 UI_TEXTEDITOR_BORDER = 1; const S32 UI_TEXTEDITOR_H_PAD = 4; const S32 UI_TEXTEDITOR_V_PAD_TOP = 4; @@ -93,67 +90,33 @@ void (* LLTextEditor::mURLcallback)(const char*) = NULL; bool (* LLTextEditor::mSecondlifeURLcallback)(const std::string&) = NULL; bool (* LLTextEditor::mSecondlifeURLcallbackRightClick)(const std::string&) = NULL; -/////////////////////////////////////////////////////////////////// -//virtuals -BOOL LLTextCmd::canExtend(S32 pos) -{ - return FALSE; -} - -void LLTextCmd::blockExtensions() -{ -} - -BOOL LLTextCmd::extendAndExecute( LLTextEditor* editor, S32 pos, llwchar c, S32* delta ) -{ - llassert(0); - return 0; -} - -BOOL LLTextCmd::hasExtCharValue( llwchar value ) -{ - return FALSE; -} - -// Utility funcs -S32 LLTextCmd::insert(LLTextEditor* editor, S32 pos, const LLWString &wstr) -{ - return editor->insertStringNoUndo( pos, wstr ); -} -S32 LLTextCmd::remove(LLTextEditor* editor, S32 pos, S32 length) -{ - return editor->removeStringNoUndo( pos, length ); -} -S32 LLTextCmd::overwrite(LLTextEditor* editor, S32 pos, llwchar wc) -{ - return editor->overwriteCharNoUndo(pos, wc); -} /////////////////////////////////////////////////////////////////// -class LLTextCmdInsert : public LLTextCmd +class LLTextEditor::LLTextCmdInsert : public LLTextEditor::LLTextCmd { public: LLTextCmdInsert(S32 pos, BOOL group_with_next, const LLWString &ws) : LLTextCmd(pos, group_with_next), mWString(ws) { } + virtual ~LLTextCmdInsert() {} virtual BOOL execute( LLTextEditor* editor, S32* delta ) { - *delta = insert(editor, mPos, mWString ); + *delta = insert(editor, getPosition(), mWString ); LLWString::truncate(mWString, *delta); //mWString = wstring_truncate(mWString, *delta); return (*delta != 0); } virtual S32 undo( LLTextEditor* editor ) { - remove(editor, mPos, mWString.length() ); - return mPos; + remove(editor, getPosition(), mWString.length() ); + return getPosition(); } virtual S32 redo( LLTextEditor* editor ) { - insert(editor, mPos, mWString ); - return mPos + mWString.length(); + insert(editor, getPosition(), mWString ); + return getPosition() + mWString.length(); } private: @@ -161,8 +124,7 @@ private: }; /////////////////////////////////////////////////////////////////// - -class LLTextCmdAddChar : public LLTextCmd +class LLTextEditor::LLTextCmdAddChar : public LLTextEditor::LLTextCmd { public: LLTextCmdAddChar( S32 pos, BOOL group_with_next, llwchar wc) @@ -173,13 +135,13 @@ public: { mBlockExtensions = TRUE; } - virtual BOOL canExtend(S32 pos) + virtual BOOL canExtend(S32 pos) const { - return !mBlockExtensions && (pos == mPos + (S32)mWString.length()); + return !mBlockExtensions && (pos == getPosition() + (S32)mWString.length()); } virtual BOOL execute( LLTextEditor* editor, S32* delta ) { - *delta = insert(editor, mPos, mWString); + *delta = insert(editor, getPosition(), mWString); LLWString::truncate(mWString, *delta); //mWString = wstring_truncate(mWString, *delta); return (*delta != 0); @@ -198,13 +160,13 @@ public: } virtual S32 undo( LLTextEditor* editor ) { - remove(editor, mPos, mWString.length() ); - return mPos; + remove(editor, getPosition(), mWString.length() ); + return getPosition(); } virtual S32 redo( LLTextEditor* editor ) { - insert(editor, mPos, mWString ); - return mPos + mWString.length(); + insert(editor, getPosition(), mWString ); + return getPosition() + mWString.length(); } private: @@ -215,7 +177,7 @@ private: /////////////////////////////////////////////////////////////////// -class LLTextCmdOverwriteChar : public LLTextCmd +class LLTextEditor::LLTextCmdOverwriteChar : public LLTextEditor::LLTextCmd { public: LLTextCmdOverwriteChar( S32 pos, BOOL group_with_next, llwchar wc) @@ -223,20 +185,20 @@ public: virtual BOOL execute( LLTextEditor* editor, S32* delta ) { - mOldChar = editor->getWChar(mPos); - overwrite(editor, mPos, mChar); + mOldChar = editor->getWChar(getPosition()); + overwrite(editor, getPosition(), mChar); *delta = 0; return TRUE; } virtual S32 undo( LLTextEditor* editor ) { - overwrite(editor, mPos, mOldChar); - return mPos; + overwrite(editor, getPosition(), mOldChar); + return getPosition(); } virtual S32 redo( LLTextEditor* editor ) { - overwrite(editor, mPos, mChar); - return mPos+1; + overwrite(editor, getPosition(), mChar); + return getPosition()+1; } private: @@ -246,7 +208,7 @@ private: /////////////////////////////////////////////////////////////////// -class LLTextCmdRemove : public LLTextCmd +class LLTextEditor::LLTextCmdRemove : public LLTextEditor::LLTextCmd { public: LLTextCmdRemove( S32 pos, BOOL group_with_next, S32 len ) : @@ -255,30 +217,27 @@ public: } virtual BOOL execute( LLTextEditor* editor, S32* delta ) { - mWString = editor->getWSubString(mPos, mLen); - *delta = remove(editor, mPos, mLen ); + mWString = editor->getWSubString(getPosition(), mLen); + *delta = remove(editor, getPosition(), mLen ); return (*delta != 0); } virtual S32 undo( LLTextEditor* editor ) { - insert(editor, mPos, mWString ); - return mPos + mWString.length(); + insert(editor, getPosition(), mWString ); + return getPosition() + mWString.length(); } virtual S32 redo( LLTextEditor* editor ) { - remove(editor, mPos, mLen ); - return mPos; + remove(editor, getPosition(), mLen ); + return getPosition(); } private: LLWString mWString; S32 mLen; }; -/////////////////////////////////////////////////////////////////// -// -// Member functions -// +/////////////////////////////////////////////////////////////////// LLTextEditor::LLTextEditor( const LLString& name, @@ -309,7 +268,7 @@ LLTextEditor::LLTextEditor( mFocusBgColor( LLUI::sColorsGroup->getColor( "TextBgFocusColor" ) ), mReadOnly(FALSE), mWordWrap( FALSE ), - mTabToNextField( TRUE ), + mTabsToNextField( TRUE ), mCommitOnFocusLost( FALSE ), mHideScrollbarForShortDocs( FALSE ), mTakesNonScrollClicks( TRUE ), @@ -344,10 +303,10 @@ LLTextEditor::LLTextEditor( // Init the scrollbar LLRect scroll_rect; scroll_rect.setOriginAndSize( - mRect.getWidth() - UI_TEXTEDITOR_BORDER - SCROLLBAR_SIZE, + getRect().getWidth() - UI_TEXTEDITOR_BORDER - SCROLLBAR_SIZE, UI_TEXTEDITOR_BORDER, SCROLLBAR_SIZE, - mRect.getHeight() - 2 * UI_TEXTEDITOR_BORDER ); + getRect().getHeight() - 2 * UI_TEXTEDITOR_BORDER ); S32 lines_in_doc = getLineCount(); mScrollbar = new LLScrollbar( "Scrollbar", scroll_rect, LLScrollbar::VERTICAL, @@ -363,7 +322,7 @@ LLTextEditor::LLTextEditor( mScrollbar->setOnScrollEndCallback(mOnScrollEndCallback, mOnScrollEndData); addChild(mScrollbar); - mBorder = new LLViewBorder( "text ed border", LLRect(0, mRect.getHeight(), mRect.getWidth(), 0), LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, UI_TEXTEDITOR_BORDER ); + mBorder = new LLViewBorder( "text ed border", LLRect(0, getRect().getHeight(), getRect().getWidth(), 0), LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, UI_TEXTEDITOR_BORDER ); addChild( mBorder ); appendText(default_text, FALSE, FALSE); @@ -392,12 +351,6 @@ LLTextEditor::~LLTextEditor() std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); } -//virtual -LLString LLTextEditor::getWidgetTag() const -{ - return LL_TEXT_EDITOR_TAG; -} - void LLTextEditor::setTrackColor( const LLColor4& color ) { mScrollbar->setTrackColor(color); @@ -422,7 +375,7 @@ void LLTextEditor::updateLineStartList(S32 startpos) { updateSegments(); - bindEmbeddedChars( mGLFont ); + bindEmbeddedChars( const_cast<LLFontGL*>(mGLFont) ); S32 seg_num = mSegments.size(); S32 seg_idx = 0; @@ -499,7 +452,7 @@ void LLTextEditor::updateLineStartList(S32 startpos) } } - unbindEmbeddedChars(mGLFont); + unbindEmbeddedChars(const_cast<LLFontGL*>(mGLFont)); mScrollbar->setDocSize( getLineCount() ); @@ -515,11 +468,6 @@ void LLTextEditor::updateLineStartList(S32 startpos) // LLTextEditor // Public methods -//static -BOOL LLTextEditor::isPartOfWord(llwchar c) { return (c == '_') || isalnum(c); } - - - BOOL LLTextEditor::truncate() { BOOL did_truncate = FALSE; @@ -581,6 +529,7 @@ void LLTextEditor::setWText(const LLWString &wtext) resetDirty(); } +// virtual void LLTextEditor::setValue(const LLSD& value) { setText(value.asString()); @@ -600,6 +549,7 @@ const LLString& LLTextEditor::getText() const return mUTF8Text; } +// virtual LLSD LLTextEditor::getValue() const { return LLSD(getText()); @@ -622,7 +572,10 @@ void LLTextEditor::setBorderVisible(BOOL b) mBorder->setVisible(b); } - +BOOL LLTextEditor::isBorderVisible() const +{ + return mBorder->getVisible(); +} void LLTextEditor::setHideScrollbarForShortDocs(BOOL b) { @@ -734,12 +687,6 @@ void LLTextEditor::replaceTextAll(const LLString& search_text, const LLString& r mScrollbar->setDocPos(cur_pos); } -void LLTextEditor::setTakesNonScrollClicks(BOOL b) -{ - mTakesNonScrollClicks = b; -} - - // Picks a new cursor position based on the screen size of text being drawn. void LLTextEditor::setCursorAtLocalPos( S32 local_x, S32 local_y, BOOL round ) { @@ -774,11 +721,6 @@ S32 LLTextEditor::nextWordPos(S32 cursorPos) const return cursorPos; } -S32 LLTextEditor::getLineCount() const -{ - return mLineStartList.size(); -} - S32 LLTextEditor::getLineStart( S32 line ) const { S32 num_lines = getLineCount(); @@ -796,7 +738,7 @@ S32 LLTextEditor::getLineStart( S32 line ) const } // Given an offset into text (pos), find the corresponding line (from the start of the doc) and an offset into the line. -void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp ) +void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp ) const { if (mLineStartList.empty()) { @@ -809,7 +751,7 @@ void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp ) getSegmentAndOffset( startpos, &seg_idx, &seg_offset ); line_info tline(seg_idx, seg_offset); - line_list_t::iterator iter = std::upper_bound(mLineStartList.begin(), mLineStartList.end(), tline, line_info_compare()); + line_list_t::const_iterator iter = std::upper_bound(mLineStartList.begin(), mLineStartList.end(), tline, line_info_compare()); if (iter != mLineStartList.begin()) --iter; *linep = iter - mLineStartList.begin(); S32 line_start = mSegments[iter->mSegment]->getStart() + iter->mOffset; @@ -817,7 +759,7 @@ void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp ) } } -void LLTextEditor::getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) +void LLTextEditor::getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) const { if (mSegments.empty()) { @@ -826,46 +768,21 @@ void LLTextEditor::getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp } LLTextSegment tseg(startpos); - segment_list_t::iterator seg_iter; + segment_list_t::const_iterator seg_iter; seg_iter = std::upper_bound(mSegments.begin(), mSegments.end(), &tseg, LLTextSegment::compare()); if (seg_iter != mSegments.begin()) --seg_iter; *segidxp = seg_iter - mSegments.begin(); *offsetp = startpos - (*seg_iter)->getStart(); } -const LLWString& LLTextEditor::getWText() const -{ - return mWText; -} - -S32 LLTextEditor::getLength() const -{ - return mWText.length(); -} - -llwchar LLTextEditor::getWChar(S32 pos) -{ - return mWText[pos]; -} - -LLWString LLTextEditor::getWSubString(S32 pos, S32 len) -{ - return mWText.substr(pos, len); -} - -LLTextSegment* LLTextEditor::getCurrentSegment() -{ - return getSegmentAtOffset(mCursorPos); -} - -LLTextSegment* LLTextEditor::getPreviousSegment() +const LLTextSegment* LLTextEditor::getPreviousSegment() { // find segment index at character to left of cursor (or rightmost edge of selection) S32 idx = llmax(0, getSegmentIdxAtOffset(mCursorPos) - 1); return idx >= 0 ? mSegments[idx] : NULL; } -void LLTextEditor::getSelectedSegments(std::vector<LLTextSegment*>& segments) +void LLTextEditor::getSelectedSegments(std::vector<const LLTextSegment*>& segments) { S32 left = hasSelection() ? llmin(mSelectionStart, mSelectionEnd) : mCursorPos; S32 right = hasSelection() ? llmax(mSelectionStart, mSelectionEnd) : mCursorPos; @@ -878,7 +795,7 @@ void LLTextEditor::getSelectedSegments(std::vector<LLTextSegment*>& segments) } } -S32 LLTextEditor::getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) +S32 LLTextEditor::getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const { // If round is true, if the position is on the right half of a character, the cursor // will be put to its right. If round is false, the cursor will always be put to the @@ -916,13 +833,13 @@ S32 LLTextEditor::getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL rou if (mAllowEmbeddedItems) { // Figure out which character we're nearest to. - bindEmbeddedChars(mGLFont); + bindEmbeddedChars(const_cast<LLFontGL*>(mGLFont)); pos = mGLFont->charFromPixelOffset(mWText.c_str(), line_start, (F32)(local_x - mTextRect.mLeft), (F32)(mTextRect.getWidth()), line_len, round, TRUE); - unbindEmbeddedChars(mGLFont); + unbindEmbeddedChars(const_cast<LLFontGL*>(mGLFont)); } else { @@ -958,8 +875,8 @@ void LLTextEditor::setCursorPos(S32 offset) mDesiredXPixel = -1; } - -BOOL LLTextEditor::canDeselect() +// virtual +BOOL LLTextEditor::canDeselect() const { return hasSelection(); } @@ -1126,12 +1043,13 @@ void LLTextEditor::indentSelectedLines( S32 spaces ) } } - -BOOL LLTextEditor::canSelectAll() +//virtual +BOOL LLTextEditor::canSelectAll() const { return TRUE; } +// virtual void LLTextEditor::selectAll() { mSelectionStart = getLength(); @@ -1143,7 +1061,7 @@ void LLTextEditor::selectAll() BOOL LLTextEditor::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) { for ( child_list_const_iter_t child_it = getChildList()->begin(); - child_it != getChildList()->end(); ++child_it) + child_it != getChildList()->end(); ++child_it) { LLView* viewp = *child_it; S32 local_x = x - viewp->getRect().mLeft; @@ -1159,7 +1077,7 @@ BOOL LLTextEditor::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rec return TRUE; } - LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); + const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); if( cur_segment ) { BOOL has_tool_tip = FALSE; @@ -1267,7 +1185,7 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) } // Delay cursor flashing - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); return handled; } @@ -1320,7 +1238,7 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) if( handled ) { // Delay cursor flashing - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); } // Opaque @@ -1329,7 +1247,7 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) // Check to see if we're over an HTML-style link if( !mSegments.empty() ) { - LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); + const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); if( cur_segment ) { if(cur_segment->getStyle().isLink()) @@ -1353,7 +1271,7 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) if( !handled ) { lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl; - if (!mScrollbar->getVisible() || x < mRect.getWidth() - SCROLLBAR_SIZE) + if (!mScrollbar->getVisible() || x < getRect().getWidth() - SCROLLBAR_SIZE) { getWindow()->setCursor(UI_CURSOR_IBEAM); } @@ -1411,7 +1329,7 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) } // Delay cursor flashing - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); if( hasMouseCapture() ) { @@ -1467,7 +1385,7 @@ BOOL LLTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) mIsSelecting = FALSE; // delay cursor flashing - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); handled = TRUE; } @@ -1548,50 +1466,51 @@ S32 LLTextEditor::overwriteChar(S32 pos, llwchar wc) // a pseudo-tab (up to for spaces in a row) void LLTextEditor::removeCharOrTab() { - if( getEnabled() ) + if( !getEnabled() ) { - if( mCursorPos > 0 ) - { - S32 chars_to_remove = 1; + return; + } + if( mCursorPos > 0 ) + { + S32 chars_to_remove = 1; - const LLWString &text = mWText; - if (text[mCursorPos - 1] == ' ') + const LLWString &text = mWText; + if (text[mCursorPos - 1] == ' ') + { + // Try to remove a "tab" + S32 line, offset; + getLineAndOffset(mCursorPos, &line, &offset); + if (offset > 0) { - // Try to remove a "tab" - S32 line, offset; - getLineAndOffset(mCursorPos, &line, &offset); - if (offset > 0) + chars_to_remove = offset % SPACES_PER_TAB; + if( chars_to_remove == 0 ) { - chars_to_remove = offset % SPACES_PER_TAB; - if( chars_to_remove == 0 ) - { - chars_to_remove = SPACES_PER_TAB; - } + chars_to_remove = SPACES_PER_TAB; + } - for( S32 i = 0; i < chars_to_remove; i++ ) + for( S32 i = 0; i < chars_to_remove; i++ ) + { + if (text[ mCursorPos - i - 1] != ' ') { - if (text[ mCursorPos - i - 1] != ' ') - { - // Fewer than a full tab's worth of spaces, so - // just delete a single character. - chars_to_remove = 1; - break; - } + // Fewer than a full tab's worth of spaces, so + // just delete a single character. + chars_to_remove = 1; + break; } } } - - for (S32 i = 0; i < chars_to_remove; i++) - { - setCursorPos(mCursorPos - 1); - remove( mCursorPos, 1, FALSE ); - } } - else + + for (S32 i = 0; i < chars_to_remove; i++) { - reportBadKeystroke(); + setCursorPos(mCursorPos - 1); + remove( mCursorPos, 1, FALSE ); } } + else + { + reportBadKeystroke(); + } } // Remove a single character from the text @@ -1602,17 +1521,18 @@ S32 LLTextEditor::removeChar(S32 pos) void LLTextEditor::removeChar() { - if (getEnabled()) + if (!getEnabled()) { - if (mCursorPos > 0) - { - setCursorPos(mCursorPos - 1); - removeChar(mCursorPos); - } - else - { - reportBadKeystroke(); - } + return; + } + if (mCursorPos > 0) + { + setCursorPos(mCursorPos - 1); + removeChar(mCursorPos); + } + else + { + reportBadKeystroke(); } } @@ -1639,19 +1559,20 @@ S32 LLTextEditor::addChar(S32 pos, llwchar wc) void LLTextEditor::addChar(llwchar wc) { - if( getEnabled() ) + if( !getEnabled() ) { - if( hasSelection() ) - { - deleteSelection(TRUE); - } - else if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) - { - removeChar(mCursorPos); - } - - setCursorPos(mCursorPos + addChar( mCursorPos, wc )); + return; } + if( hasSelection() ) + { + deleteSelection(TRUE); + } + else if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) + { + removeChar(mCursorPos); + } + + setCursorPos(mCursorPos + addChar( mCursorPos, wc )); } @@ -1747,7 +1668,6 @@ BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask) } } - if( !handled && mHandleEditKeysDirectly ) { if( (MASK_CONTROL & mask) && ('A' == key) ) @@ -1900,7 +1820,8 @@ void LLTextEditor::deleteSelection(BOOL group_with_next_op ) } } -BOOL LLTextEditor::canCut() +// virtual +BOOL LLTextEditor::canCut() const { return !mReadOnly && hasSelection(); } @@ -1908,36 +1829,37 @@ BOOL LLTextEditor::canCut() // cut selection to clipboard void LLTextEditor::cut() { - if( canCut() ) + if( !canCut() ) { - S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); - S32 length = abs( mSelectionStart - mSelectionEnd ); - gClipboard.copyFromSubstring( mWText, left_pos, length, mSourceID ); - deleteSelection( FALSE ); - - updateLineStartList(); - updateScrollFromCursor(); + return; } + S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); + S32 length = abs( mSelectionStart - mSelectionEnd ); + gClipboard.copyFromSubstring( mWText, left_pos, length, mSourceID ); + deleteSelection( FALSE ); + + updateLineStartList(); + updateScrollFromCursor(); } -BOOL LLTextEditor::canCopy() +BOOL LLTextEditor::canCopy() const { return hasSelection(); } - // copy selection to clipboard void LLTextEditor::copy() { - if( canCopy() ) + if( !canCopy() ) { - S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); - S32 length = abs( mSelectionStart - mSelectionEnd ); - gClipboard.copyFromSubstring(mWText, left_pos, length, mSourceID); + return; } + S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); + S32 length = abs( mSelectionStart - mSelectionEnd ); + gClipboard.copyFromSubstring(mWText, left_pos, length, mSourceID); } -BOOL LLTextEditor::canPaste() +BOOL LLTextEditor::canPaste() const { return !mReadOnly && gClipboard.canPasteString(); } @@ -1946,47 +1868,49 @@ BOOL LLTextEditor::canPaste() // paste from clipboard void LLTextEditor::paste() { - if (canPaste()) + if (!canPaste()) + { + return; + } + LLUUID source_id; + LLWString paste = gClipboard.getPasteWString(&source_id); + if (paste.empty()) { - LLUUID source_id; - LLWString paste = gClipboard.getPasteWString(&source_id); - if (!paste.empty()) + return; + } + // Delete any selected characters (the paste replaces them) + if( hasSelection() ) + { + deleteSelection(TRUE); + } + + // Clean up string (replace tabs and remove characters that our fonts don't support). + LLWString clean_string(paste); + LLWString::replaceTabsWithSpaces(clean_string, SPACES_PER_TAB); + if( mAllowEmbeddedItems ) + { + const llwchar LF = 10; + S32 len = clean_string.length(); + for( S32 i = 0; i < len; i++ ) { - // Delete any selected characters (the paste replaces them) - if( hasSelection() ) + llwchar wc = clean_string[i]; + if( (wc < LLFont::FIRST_CHAR) && (wc != LF) ) { - deleteSelection(TRUE); + clean_string[i] = LL_UNKNOWN_CHAR; } - - // Clean up string (replace tabs and remove characters that our fonts don't support). - LLWString clean_string(paste); - LLWString::replaceTabsWithSpaces(clean_string, SPACES_PER_TAB); - if( mAllowEmbeddedItems ) + else if (wc >= FIRST_EMBEDDED_CHAR && wc <= LAST_EMBEDDED_CHAR) { - const llwchar LF = 10; - S32 len = clean_string.length(); - for( S32 i = 0; i < len; i++ ) - { - llwchar wc = clean_string[i]; - if( (wc < LLFont::FIRST_CHAR) && (wc != LF) ) - { - clean_string[i] = LL_UNKNOWN_CHAR; - } - else if (wc >= FIRST_EMBEDDED_CHAR && wc <= LAST_EMBEDDED_CHAR) - { - clean_string[i] = pasteEmbeddedItem(wc); - } - } + clean_string[i] = pasteEmbeddedItem(wc); } - - // Insert the new text into the existing text. - setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE)); - deselect(); - - updateLineStartList(); - updateScrollFromCursor(); } } + + // Insert the new text into the existing text. + setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE)); + deselect(); + + updateLineStartList(); + updateScrollFromCursor(); } @@ -2240,7 +2164,7 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) { // Special case for TAB. If want to move to next field, report // not handled and let the parent take care of field movement. - if (KEY_TAB == key && mTabToNextField) + if (KEY_TAB == key && mTabsToNextField) { return FALSE; } @@ -2296,7 +2220,7 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) if( handled ) { - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); // Most keystrokes will make the selection box go away, but not all will. if( !selection_modified && @@ -2350,7 +2274,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_pare if( handled ) { - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); // Most keystrokes will make the selection box go away, but not all will. deselect(); @@ -2364,58 +2288,58 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_pare } - -BOOL LLTextEditor::canDoDelete() +// virtual +BOOL LLTextEditor::canDoDelete() const { return !mReadOnly && ( hasSelection() || (mCursorPos < getLength()) ); } void LLTextEditor::doDelete() { - if( canDoDelete() ) + if( !canDoDelete() ) { - if( hasSelection() ) + return; + } + if( hasSelection() ) + { + deleteSelection(FALSE); + } + else + if( mCursorPos < getLength() ) + { + S32 i; + S32 chars_to_remove = 1; + const LLWString &text = mWText; + if( (text[ mCursorPos ] == ' ') && (mCursorPos + SPACES_PER_TAB < getLength()) ) { - deleteSelection(FALSE); - } - else - if( mCursorPos < getLength() ) - { - S32 i; - S32 chars_to_remove = 1; - const LLWString &text = mWText; - if( (text[ mCursorPos ] == ' ') && (mCursorPos + SPACES_PER_TAB < getLength()) ) + // Try to remove a full tab's worth of spaces + S32 line, offset; + getLineAndOffset( mCursorPos, &line, &offset ); + chars_to_remove = SPACES_PER_TAB - (offset % SPACES_PER_TAB); + if( chars_to_remove == 0 ) { - // Try to remove a full tab's worth of spaces - S32 line, offset; - getLineAndOffset( mCursorPos, &line, &offset ); - chars_to_remove = SPACES_PER_TAB - (offset % SPACES_PER_TAB); - if( chars_to_remove == 0 ) - { - chars_to_remove = SPACES_PER_TAB; - } - - for( i = 0; i < chars_to_remove; i++ ) - { - if( text[mCursorPos + i] != ' ' ) - { - chars_to_remove = 1; - break; - } - } + chars_to_remove = SPACES_PER_TAB; } - for( i = 0; i < chars_to_remove; i++ ) { - setCursorPos(mCursorPos + 1); - removeChar(); + if( text[mCursorPos + i] != ' ' ) + { + chars_to_remove = 1; + break; + } } } - updateLineStartList(); - updateScrollFromCursor(); + for( i = 0; i < chars_to_remove; i++ ) + { + setCursorPos(mCursorPos + 1); + removeChar(); + } } + + updateLineStartList(); + updateScrollFromCursor(); } //---------------------------------------------------------------------------- @@ -2429,65 +2353,66 @@ void LLTextEditor::blockUndo() mUndoStack.clear(); } - -BOOL LLTextEditor::canUndo() +// virtual +BOOL LLTextEditor::canUndo() const { return !mReadOnly && mLastCmd != NULL; } void LLTextEditor::undo() { - if( canUndo() ) + if( !canUndo() ) { - deselect(); - - S32 pos = 0; - do - { - pos = mLastCmd->undo(this); - undo_stack_t::iterator iter = std::find(mUndoStack.begin(), mUndoStack.end(), mLastCmd); - if (iter != mUndoStack.end()) - ++iter; - if (iter != mUndoStack.end()) - mLastCmd = *iter; - else - mLastCmd = NULL; + return; + } + deselect(); + S32 pos = 0; + do + { + pos = mLastCmd->undo(this); + undo_stack_t::iterator iter = std::find(mUndoStack.begin(), mUndoStack.end(), mLastCmd); + if (iter != mUndoStack.end()) + ++iter; + if (iter != mUndoStack.end()) + mLastCmd = *iter; + else + mLastCmd = NULL; } while( mLastCmd && mLastCmd->groupWithNext() ); setCursorPos(pos); - updateLineStartList(); - updateScrollFromCursor(); - } + updateLineStartList(); + updateScrollFromCursor(); } -BOOL LLTextEditor::canRedo() +BOOL LLTextEditor::canRedo() const { return !mReadOnly && (mUndoStack.size() > 0) && (mLastCmd != mUndoStack.front()); } void LLTextEditor::redo() { - if( canRedo() ) + if( !canRedo() ) { - deselect(); - - S32 pos = 0; - do + return; + } + deselect(); + S32 pos = 0; + do + { + if( !mLastCmd ) { - if( !mLastCmd ) - { - mLastCmd = mUndoStack.back(); - } + mLastCmd = mUndoStack.back(); + } + else + { + undo_stack_t::iterator iter = std::find(mUndoStack.begin(), mUndoStack.end(), mLastCmd); + if (iter != mUndoStack.begin()) + mLastCmd = *(--iter); else - { - undo_stack_t::iterator iter = std::find(mUndoStack.begin(), mUndoStack.end(), mLastCmd); - if (iter != mUndoStack.begin()) - mLastCmd = *(--iter); - else - mLastCmd = NULL; - } + mLastCmd = NULL; + } if( mLastCmd ) { @@ -2500,9 +2425,8 @@ void LLTextEditor::redo() setCursorPos(pos); - updateLineStartList(); - updateScrollFromCursor(); - } + updateLineStartList(); + updateScrollFromCursor(); } void LLTextEditor::onFocusReceived() @@ -2548,8 +2472,8 @@ void LLTextEditor::setEnabled(BOOL enabled) void LLTextEditor::drawBackground() { S32 left = 0; - S32 top = mRect.getHeight(); - S32 right = mRect.getWidth(); + S32 top = getRect().getHeight(); + S32 right = getRect().getWidth(); S32 bottom = 0; LLColor4 bg_color = mReadOnlyBgColor; @@ -2812,7 +2736,7 @@ void LLTextEditor::drawCursor() if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection() && text[mCursorPos] != '\n') { - LLTextSegment* segmentp = getSegmentAtOffset(mCursorPos); + const LLTextSegment* segmentp = getSegmentAtOffset(mCursorPos); LLColor4 text_color; if (segmentp) { @@ -2945,122 +2869,118 @@ void LLTextEditor::drawText() { const LLWString &text = mWText; const S32 text_len = getLength(); + if( text_len <= 0 ) + { + return; + } + S32 selection_left = -1; + S32 selection_right = -1; + // Draw selection even if we don't have keyboard focus for search/replace + if( hasSelection()) + { + selection_left = llmin( mSelectionStart, mSelectionEnd ); + selection_right = llmax( mSelectionStart, mSelectionEnd ); + } - if( text_len > 0 ) + LLGLSUIDefault gls_ui; + + S32 cur_line = mScrollbar->getDocPos(); + S32 num_lines = getLineCount(); + if (cur_line >= num_lines) + { + return; + } + + S32 line_start = getLineStart(cur_line); + LLTextSegment t(line_start); + segment_list_t::iterator seg_iter; + seg_iter = std::upper_bound(mSegments.begin(), mSegments.end(), &t, LLTextSegment::compare()); + if (seg_iter == mSegments.end() || (*seg_iter)->getStart() > line_start) --seg_iter; + LLTextSegment* cur_segment = *seg_iter; + + S32 line_height = llround( mGLFont->getLineHeight() ); + F32 text_y = (F32)(mTextRect.mTop - line_height); + while((mTextRect.mBottom <= text_y) && (cur_line < num_lines)) { - S32 selection_left = -1; - S32 selection_right = -1; - // Draw selection even if we don't have keyboard focus for search/replace - if( hasSelection()) + S32 next_start = -1; + S32 line_end = text_len; + + if ((cur_line + 1) < num_lines) { - selection_left = llmin( mSelectionStart, mSelectionEnd ); - selection_right = llmax( mSelectionStart, mSelectionEnd ); + next_start = getLineStart(cur_line + 1); + line_end = next_start; } - - LLGLSUIDefault gls_ui; - - S32 cur_line = mScrollbar->getDocPos(); - S32 num_lines = getLineCount(); - if (cur_line >= num_lines) + if ( text[line_end-1] == '\n' ) { - return; + --line_end; } - S32 line_start = getLineStart(cur_line); - LLTextSegment t(line_start); - segment_list_t::iterator seg_iter; - seg_iter = std::upper_bound(mSegments.begin(), mSegments.end(), &t, LLTextSegment::compare()); - if (seg_iter == mSegments.end() || (*seg_iter)->getStart() > line_start) --seg_iter; - LLTextSegment* cur_segment = *seg_iter; - - S32 line_height = llround( mGLFont->getLineHeight() ); - F32 text_y = (F32)(mTextRect.mTop - line_height); - while((mTextRect.mBottom <= text_y) && (cur_line < num_lines)) - { - S32 next_start = -1; - S32 line_end = text_len; + F32 text_x = (F32)mTextRect.mLeft; - if ((cur_line + 1) < num_lines) - { - next_start = getLineStart(cur_line + 1); - line_end = next_start; - } - if ( text[line_end-1] == '\n' ) + S32 seg_start = line_start; + while( seg_start < line_end ) + { + while( cur_segment->getEnd() <= seg_start ) { - --line_end; + seg_iter++; + if (seg_iter == mSegments.end()) + { + llwarns << "Ran off the segmentation end!" << llendl; + return; + } + cur_segment = *seg_iter; } - F32 text_x = (F32)mTextRect.mLeft; - - S32 seg_start = line_start; - while( seg_start < line_end ) + // Draw a segment within the line + S32 clipped_end = llmin( line_end, cur_segment->getEnd() ); + S32 clipped_len = clipped_end - seg_start; + if( clipped_len > 0 ) { - while( cur_segment->getEnd() <= seg_start ) + LLStyle style = cur_segment->getStyle(); + if ( style.isImage() && (cur_segment->getStart() >= seg_start) && (cur_segment->getStart() <= clipped_end)) { - seg_iter++; - if (seg_iter == mSegments.end()) - { - llwarns << "Ran off the segmentation end!" << llendl; - return; - } - cur_segment = *seg_iter; + LLImageGL *image = style.getImage(); + gl_draw_scaled_image( llround(text_x), llround(text_y)+line_height-style.mImageHeight, style.mImageWidth, style.mImageHeight, image, LLColor4::white ); } - - // Draw a segment within the line - S32 clipped_end = llmin( line_end, cur_segment->getEnd() ); - S32 clipped_len = clipped_end - seg_start; - if( clipped_len > 0 ) - { - LLStyle style = cur_segment->getStyle(); - if ( style.isImage() && (cur_segment->getStart() >= seg_start) && (cur_segment->getStart() <= clipped_end)) - { - LLImageGL *image = style.getImage(); - - gl_draw_scaled_image( llround(text_x), llround(text_y)+line_height-style.mImageHeight, style.mImageWidth, style.mImageHeight, image, LLColor4::white ); - - } - if (cur_segment == mHoverSegment && style.getIsEmbeddedItem()) - { - style.mUnderline = TRUE; - } + if (cur_segment == mHoverSegment && style.getIsEmbeddedItem()) + { + style.mUnderline = TRUE; + } - S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); - - if ( (mParseHTML) && (left_pos > seg_start) && (left_pos < clipped_end) && mIsSelecting && (mSelectionStart == mSelectionEnd) ) - { - mHTML = style.getLinkHREF(); - } + S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); + + if ( (mParseHTML) && (left_pos > seg_start) && (left_pos < clipped_end) && mIsSelecting && (mSelectionStart == mSelectionEnd) ) + { + mHTML = style.getLinkHREF(); + } - drawClippedSegment( text, seg_start, clipped_end, text_x, text_y, selection_left, selection_right, style, &text_x ); + drawClippedSegment( text, seg_start, clipped_end, text_x, text_y, selection_left, selection_right, style, &text_x ); - // Note: text_x is incremented by drawClippedSegment() - seg_start += clipped_len; - } + // Note: text_x is incremented by drawClippedSegment() + seg_start += clipped_len; } + } // move down one line text_y -= (F32)line_height; - line_start = next_start; - cur_line++; - } + line_start = next_start; + cur_line++; } } // Draws a single text segment, reversing the color for selection if needed. void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyle& style, F32* right_x ) { - const LLFontGL* font = mGLFont; - - LLColor4 color; - if (!style.isVisible()) { return; } - color = style.getColor(); + const LLFontGL* font = mGLFont; + + LLColor4 color = style.getColor(); if ( style.getFontString()[0] ) { @@ -3131,12 +3051,14 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 void LLTextEditor::draw() { - if( getVisible() ) + if( !getVisible() ) { - { - LLLocalClipRect clip(LLRect(0, mRect.getHeight(), mRect.getWidth() - (mScrollbar->getVisible() ? SCROLLBAR_SIZE : 0), 0)); + return; + } + { + LLLocalClipRect clip(LLRect(0, getRect().getHeight(), getRect().getWidth() - (mScrollbar->getVisible() ? SCROLLBAR_SIZE : 0), 0)); - bindEmbeddedChars( mGLFont ); + bindEmbeddedChars( const_cast<LLFontGL*>(mGLFont) ); drawBackground(); drawSelectionBackground(); @@ -3144,34 +3066,30 @@ void LLTextEditor::draw() drawText(); drawCursor(); - unbindEmbeddedChars( mGLFont ); + unbindEmbeddedChars( const_cast<LLFontGL*>(mGLFont) ); - //RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret - // when in readonly mode - mBorder->setKeyboardFocusHighlight( gFocusMgr.getKeyboardFocus() == this);// && !mReadOnly); - } - LLView::draw(); // Draw children (scrollbar and border) + //RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret + // when in readonly mode + mBorder->setKeyboardFocusHighlight( gFocusMgr.getKeyboardFocus() == this);// && !mReadOnly); } // remember if we are supposed to be at the bottom of the buffer mScrolledToBottom = isScrolledToBottom(); -} -void LLTextEditor::reportBadKeystroke() -{ - make_ui_sound("UISndBadKeystroke"); + LLView::draw(); // Draw children (scrollbar and border) } void LLTextEditor::onTabInto() { // selecting all on tabInto causes users to hit tab twice and replace their text with a tab character - // theoretically, one could selectAll if mTabToNextField is true, but we couldn't think of a use case + // theoretically, one could selectAll if mTabsToNextField is true, but we couldn't think of a use case // where you'd want to select all anyway // preserve insertion point when returning to the editor //selectAll(); } +// virtual void LLTextEditor::clear() { setText(LLString::null); @@ -3200,7 +3118,7 @@ void LLTextEditor::setFocus( BOOL new_state ) gEditMenuHandler = this; // Don't start the cursor flashing right away - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); } else { @@ -3214,6 +3132,7 @@ void LLTextEditor::setFocus( BOOL new_state ) } } +// virtual BOOL LLTextEditor::acceptsTextInput() const { return !mReadOnly; @@ -3268,7 +3187,7 @@ void LLTextEditor::changePage( S32 delta ) void LLTextEditor::changeLine( S32 delta ) { - bindEmbeddedChars( mGLFont ); + bindEmbeddedChars( const_cast<LLFontGL*>(mGLFont) ); S32 line, offset; getLineAndOffset( mCursorPos, &line, &offset ); @@ -3295,7 +3214,7 @@ void LLTextEditor::changeLine( S32 delta ) } else { - unbindEmbeddedChars( mGLFont ); + unbindEmbeddedChars( const_cast<LLFontGL*>(mGLFont) ); return; } @@ -3320,7 +3239,7 @@ void LLTextEditor::changeLine( S32 delta ) // put desired position into remember-buffer after setCursorPos() mDesiredXPixel = desired_x_pixel; - unbindEmbeddedChars( mGLFont ); + unbindEmbeddedChars( const_cast<LLFontGL*>(mGLFont) ); } BOOL LLTextEditor::isScrolledToTop() @@ -3768,20 +3687,14 @@ BOOL LLTextEditor::tryToRevertToPristineState() return isPristine(); // TRUE => success } -// virtual Return TRUE if changes have been made -BOOL LLTextEditor::isDirty() const -{ - return( mLastCmd != NULL || (mPristineCmd && (mPristineCmd != mLastCmd)) ); -} - void LLTextEditor::updateTextRect() { mTextRect.setOriginAndSize( UI_TEXTEDITOR_BORDER + UI_TEXTEDITOR_H_PAD, UI_TEXTEDITOR_BORDER, - mRect.getWidth() - SCROLLBAR_SIZE - 2 * (UI_TEXTEDITOR_BORDER + UI_TEXTEDITOR_H_PAD), - mRect.getHeight() - 2 * UI_TEXTEDITOR_BORDER - UI_TEXTEDITOR_V_PAD_TOP ); + getRect().getWidth() - SCROLLBAR_SIZE - 2 * (UI_TEXTEDITOR_BORDER + UI_TEXTEDITOR_H_PAD), + getRect().getHeight() - 2 * UI_TEXTEDITOR_BORDER - UI_TEXTEDITOR_V_PAD_TOP ); } void LLTextEditor::loadKeywords(const LLString& filename, @@ -3862,8 +3775,7 @@ void LLTextEditor::pruneSegments() } else { - llwarns << "Tried to erase end of empty LLTextEditor" - << llendl; + llwarns << "Tried to erase end of empty LLTextEditor" << llendl; } } @@ -3949,21 +3861,9 @@ BOOL LLTextEditor::handleMouseUpOverSegment(S32 x, S32 y, MASK mask) return FALSE; } -llwchar LLTextEditor::pasteEmbeddedItem(llwchar ext_char) -{ - return ext_char; -} - -void LLTextEditor::bindEmbeddedChars(const LLFontGL* font) -{ -} - -void LLTextEditor::unbindEmbeddedChars(const LLFontGL* font) -{ -} // Finds the text segment (if any) at the give local screen position -LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) +const LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) const { // Find the cursor position at the requested local screen position S32 offset = getCursorPosFromLocalCoord( x, y, FALSE ); @@ -3971,13 +3871,13 @@ LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) return idx >= 0 ? mSegments[idx] : NULL; } -LLTextSegment* LLTextEditor::getSegmentAtOffset(S32 offset) +const LLTextSegment* LLTextEditor::getSegmentAtOffset(S32 offset) const { S32 idx = getSegmentIdxAtOffset(offset); return idx >= 0 ? mSegments[idx] : NULL; } -S32 LLTextEditor::getSegmentIdxAtOffset(S32 offset) +S32 LLTextEditor::getSegmentIdxAtOffset(S32 offset) const { if (mSegments.empty() || offset < 0 || offset >= getLength()) { @@ -4149,7 +4049,7 @@ LLTextSegment::LLTextSegment( const LLColor3& color, S32 start, S32 end ) : { } -BOOL LLTextSegment::getToolTip(LLString& msg) +BOOL LLTextSegment::getToolTip(LLString& msg) const { if (mToken && !mToken->getToolTip().empty()) { @@ -4162,7 +4062,7 @@ BOOL LLTextSegment::getToolTip(LLString& msg) -void LLTextSegment::dump() +void LLTextSegment::dump() const { llinfos << "Segment [" << // mColor.mV[VX] << ", " << @@ -4182,13 +4082,9 @@ LLXMLNodePtr LLTextEditor::getXML(bool save_children) const // Attributes node->createChild("max_length", TRUE)->setIntValue(getMaxLength()); - node->createChild("embedded_items", TRUE)->setBoolValue(mAllowEmbeddedItems); - node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mGLFont)); - node->createChild("word_wrap", TRUE)->setBoolValue(mWordWrap); - node->createChild("hide_scrollbar", TRUE)->setBoolValue(mHideScrollbarForShortDocs); addColorXML(node, mCursorColor, "cursor_color", "TextCursorColor"); @@ -4274,7 +4170,7 @@ void LLTextEditor::setTextEditorParameters(LLXMLNodePtr node) } /////////////////////////////////////////////////////////////////// -S32 LLTextEditor::findHTMLToken(const LLString &line, S32 pos, BOOL reverse) +S32 LLTextEditor::findHTMLToken(const LLString &line, S32 pos, BOOL reverse) const { LLString openers=" \t('\"[{<>"; LLString closers=" \t)'\"]}><;"; @@ -4311,7 +4207,7 @@ S32 LLTextEditor::findHTMLToken(const LLString &line, S32 pos, BOOL reverse) return retval; } -BOOL LLTextEditor::findHTML(const LLString &line, S32 *begin, S32 *end) +BOOL LLTextEditor::findHTML(const LLString &line, S32 *begin, S32 *end) const { S32 m1,m2,m3; diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 838154655c..7055e98a76 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -52,24 +52,16 @@ class LLKeywordToken; class LLTextCmd; class LLUICtrlFactory; -// -// Constants -// - -const llwchar FIRST_EMBEDDED_CHAR = 0x100000; -const llwchar LAST_EMBEDDED_CHAR = 0x10ffff; -const S32 MAX_EMBEDDED_ITEMS = LAST_EMBEDDED_CHAR - FIRST_EMBEDDED_CHAR + 1; - -// -// Classes -// -class LLTextSegment; -class LLTextCmd; - class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor { - friend class LLTextCmd; public: + // + // Constants + // + static const llwchar FIRST_EMBEDDED_CHAR = 0x100000; + static const llwchar LAST_EMBEDDED_CHAR = 0x10ffff; + static const S32 MAX_EMBEDDED_ITEMS = LAST_EMBEDDED_CHAR - FIRST_EMBEDDED_CHAR + 1; + LLTextEditor(const LLString& name, const LLRect& rect, S32 max_length, @@ -80,10 +72,10 @@ public: virtual ~LLTextEditor(); virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TEXT_EDITOR; } - virtual LLString getWidgetTag() const; + virtual LLString getWidgetTag() const { return LL_TEXT_EDITOR_TAG; } virtual LLXMLNodePtr getXML(bool save_children = true) const; - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); void setTextEditorParameters(LLXMLNodePtr node); void setParseHTML(BOOL parsing) {mParseHTML=parsing;} @@ -102,7 +94,6 @@ public: EAcceptance *accept, LLString& tooltip_msg); virtual void onMouseCaptureLost(); - // view overrides virtual void reshape(S32 width, S32 height, BOOL called_from_parent); virtual void draw(); @@ -115,32 +106,25 @@ public: virtual void clear(); virtual void setFocus( BOOL b ); virtual BOOL acceptsTextInput() const; - virtual BOOL isDirty() const; + virtual BOOL isDirty() const { return( mLastCmd != NULL || (mPristineCmd && (mPristineCmd != mLastCmd)) ); } // LLEditMenuHandler interface virtual void undo(); - virtual BOOL canUndo(); - + virtual BOOL canUndo() const; virtual void redo(); - virtual BOOL canRedo(); - + virtual BOOL canRedo() const; virtual void cut(); - virtual BOOL canCut(); - + virtual BOOL canCut() const; virtual void copy(); - virtual BOOL canCopy(); - + virtual BOOL canCopy() const; virtual void paste(); - virtual BOOL canPaste(); - + virtual BOOL canPaste() const; virtual void doDelete(); - virtual BOOL canDoDelete(); - + virtual BOOL canDoDelete() const; virtual void selectAll(); - virtual BOOL canSelectAll(); - + virtual BOOL canSelectAll() const; virtual void deselect(); - virtual BOOL canDeselect(); + virtual BOOL canDeselect() const; void selectNext(const LLString& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); BOOL replaceText(const LLString& search_text, const LLString& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); @@ -152,6 +136,7 @@ public: // Text editing virtual void makePristine(); BOOL isPristine() const; + BOOL allowsEmbeddedItems() const { return mAllowEmbeddedItems; } // inserts text at cursor void insertText(const LLString &text); @@ -180,18 +165,21 @@ public: void getCurrentLineAndColumn( S32* line, S32* col, BOOL include_wordwrap ); + // Keywords support void loadKeywords(const LLString& filename, const LLDynamicArray<const char*>& funcs, const LLDynamicArray<const char*>& tooltips, const LLColor3& func_color); + LLKeywords::keyword_iterator_t keywordsBegin() { return mKeywords.begin(); } + LLKeywords::keyword_iterator_t keywordsEnd() { return mKeywords.end(); } + // Color support void setCursorColor(const LLColor4& c) { mCursorColor = c; } void setFgColor( const LLColor4& c ) { mFgColor = c; } void setTextDefaultColor( const LLColor4& c ) { mDefaultColor = c; } void setReadOnlyFgColor( const LLColor4& c ) { mReadOnlyFgColor = c; } void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; } void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } - void setTrackColor( const LLColor4& color ); void setThumbColor( const LLColor4& color ); void setHighlightColor( const LLColor4& color ); @@ -200,11 +188,13 @@ public: // Hacky methods to make it into a word-wrapping, potentially scrolling, // read-only text box. void setBorderVisible(BOOL b); - void setTakesNonScrollClicks(BOOL b); + BOOL isBorderVisible() const; + void setTakesNonScrollClicks(BOOL b) { mTakesNonScrollClicks = b; } void setHideScrollbarForShortDocs(BOOL b); void setWordWrap( BOOL b ); - void setTabToNextField(BOOL b) { mTabToNextField = b; } + void setTabsToNextField(BOOL b) { mTabsToNextField = b; } + BOOL tabsToNextField() const { return mTabsToNextField; } void setCommitOnFocusLost(BOOL b) { mCommitOnFocusLost = b; } // Hack to handle Notecards @@ -215,7 +205,9 @@ public: void setTakesFocus(BOOL b) { mTakesFocus = b; } void setSourceID(const LLUUID& id) { mSourceID = id; } + const LLUUID& getSourceID() const { return mSourceID; } void setAcceptCallingCardNames(BOOL enable) { mAcceptCallingCardNames = enable; } + BOOL acceptsCallingCardNames() const { return mAcceptCallingCardNames; } void setHandleEditKeysDirectly( BOOL b ) { mHandleEditKeysDirectly = b; } @@ -250,49 +242,46 @@ public: BOOL isScrolledToBottom(); // Getters - const LLWString& getWText() const; - llwchar getWChar(S32 pos); - LLWString getWSubString(S32 pos, S32 len); + const LLWString& getWText() const { return mWText; } + llwchar getWChar(S32 pos) const { return mWText[pos]; } + LLWString getWSubString(S32 pos, S32 len) const { return mWText.substr(pos, len); } - LLTextSegment* getCurrentSegment(); - LLTextSegment* getPreviousSegment(); - void getSelectedSegments(std::vector<LLTextSegment*>& segments); + const LLTextSegment* getCurrentSegment() { return getSegmentAtOffset(mCursorPos); } + const LLTextSegment* getPreviousSegment(); + void getSelectedSegments(std::vector<const LLTextSegment*>& segments); protected: - S32 getLength() const; - void getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ); + // + // Methods + // - void drawBackground(); - void drawSelectionBackground(); - void drawCursor(); - void drawText(); - void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyle& color, F32* right_x); + S32 getLength() const { return mWText.length(); } + void getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) const; void drawPreeditMarker(); void updateLineStartList(S32 startpos = 0); void updateScrollFromCursor(); void updateTextRect(); - void updateSegments(); - void pruneSegments(); + const LLRect& getTextRect() const { return mTextRect; } void assignEmbedded(const LLString &s); BOOL truncate(); // Returns true if truncation occurs - static BOOL isPartOfWord(llwchar c); + static BOOL isPartOfWord(llwchar c) { return (c == '_') || isalnum(c); } void removeCharOrTab(); void setCursorAtLocalPos(S32 x, S32 y, BOOL round); - S32 getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ); + S32 getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const; void indentSelectedLines( S32 spaces ); S32 indentLine( S32 pos, S32 spaces ); void unindentLineBeforeCloseBrace(); - S32 getSegmentIdxAtOffset(S32 offset); - LLTextSegment* getSegmentAtLocalPos(S32 x, S32 y); - LLTextSegment* getSegmentAtOffset(S32 offset); + S32 getSegmentIdxAtOffset(S32 offset) const; + const LLTextSegment* getSegmentAtLocalPos(S32 x, S32 y) const; + const LLTextSegment* getSegmentAtOffset(S32 offset) const; - void reportBadKeystroke(); + void reportBadKeystroke() { make_ui_sound("UISndBadKeystroke"); } BOOL handleNavigationKey(const KEY key, const MASK mask); BOOL handleSpecialKey(const KEY key, const MASK mask, BOOL* return_key_hit); @@ -309,29 +298,58 @@ protected: S32 prevWordPos(S32 cursorPos) const; S32 nextWordPos(S32 cursorPos) const; - S32 getLineCount() const; + S32 getLineCount() const { return mLineStartList.size(); } S32 getLineStart( S32 line ) const; - void getLineAndOffset(S32 pos, S32* linep, S32* offsetp); + void getLineAndOffset(S32 pos, S32* linep, S32* offsetp) const; S32 getPos(S32 line, S32 offset); void changePage(S32 delta); void changeLine(S32 delta); void autoIndent(); - - S32 execute(LLTextCmd* cmd); void findEmbeddedItemSegments(); virtual BOOL handleMouseUpOverSegment(S32 x, S32 y, MASK mask); - virtual llwchar pasteEmbeddedItem(llwchar ext_char); - virtual void bindEmbeddedChars(const LLFontGL* font); - virtual void unbindEmbeddedChars(const LLFontGL* font); + + virtual llwchar pasteEmbeddedItem(llwchar ext_char) { return ext_char; } + virtual void bindEmbeddedChars(LLFontGL* font) const {} + virtual void unbindEmbeddedChars(LLFontGL* font) const {} - S32 findHTMLToken(const LLString &line, S32 pos, BOOL reverse); - BOOL findHTML(const LLString &line, S32 *begin, S32 *end); + S32 findHTMLToken(const LLString &line, S32 pos, BOOL reverse) const; + BOOL findHTML(const LLString &line, S32 *begin, S32 *end) const; + + // Abstract inner base class representing an undoable editor command. + // Concrete sub-classes can be defined for operations such as insert, remove, etc. + // Used as arguments to the execute() method below. + class LLTextCmd + { + public: + LLTextCmd( S32 pos, BOOL group_with_next ) : mPos(pos), mGroupWithNext(group_with_next) {} + virtual ~LLTextCmd() {} + virtual BOOL execute(LLTextEditor* editor, S32* delta) = 0; + virtual S32 undo(LLTextEditor* editor) = 0; + virtual S32 redo(LLTextEditor* editor) = 0; + virtual BOOL canExtend(S32 pos) const { return FALSE; } + virtual void blockExtensions() {} + virtual BOOL extendAndExecute( LLTextEditor* editor, S32 pos, llwchar c, S32* delta ) { llassert(0); return 0; } + virtual BOOL hasExtCharValue( llwchar value ) const { return FALSE; } + + // Defined here so they can access protected LLTextEditor editing methods + S32 insert(LLTextEditor* editor, S32 pos, const LLWString &wstr) { return editor->insertStringNoUndo( pos, wstr ); } + S32 remove(LLTextEditor* editor, S32 pos, S32 length) { return editor->removeStringNoUndo( pos, length ); } + S32 overwrite(LLTextEditor* editor, S32 pos, llwchar wc) { return editor->overwriteCharNoUndo(pos, wc); } + + S32 getPosition() const { return mPos; } + BOOL groupWithNext() const { return mGroupWithNext; } + + private: + const S32 mPos; + BOOL mGroupWithNext; + }; + // Here's the method that takes and applies text commands. + S32 execute(LLTextCmd* cmd); -protected: // Undoable operations void addChar(llwchar c); // at mCursorPos S32 addChar(S32 pos, llwchar wc); @@ -342,12 +360,13 @@ protected: S32 remove(const S32 pos, const S32 length, const BOOL group_with_next_op); S32 append(const LLWString &wstr, const BOOL group_with_next_op); - // direct operations + // Direct operations S32 insertStringNoUndo(S32 pos, const LLWString &wstr); // returns num of chars actually inserted S32 removeStringNoUndo(S32 pos, S32 length); S32 overwriteCharNoUndo(S32 pos, llwchar wc); - -protected: + + void resetKeystrokeTimer() { mKeystrokeTimer.reset(); } + void updateAllowingLanguageInput(); BOOL hasPreeditString() const; @@ -360,14 +379,76 @@ protected: virtual void getSelectionRange(S32 *position, S32 *length) const; virtual BOOL getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const; virtual S32 getPreeditFontSize() const; + // + // Protected data + // + // Probably deserves serious thought to hiding as many of these + // as possible behind protected accessor methods. + // -public: + // I-beam is just after the mCursorPos-th character. + S32 mCursorPos; + + // Use these to determine if a click on an embedded item is a drag or not. + S32 mMouseDownX; + S32 mMouseDownY; + + // Are we in the middle of a drag-select? To figure out if there is a current + // selection, call hasSelection(). + BOOL mIsSelecting; + S32 mSelectionStart; + S32 mSelectionEnd; + S32 mLastSelectionX; + S32 mLastSelectionY; + + BOOL mParseHTML; + LLString mHTML; + + typedef std::vector<LLTextSegment *> segment_list_t; + segment_list_t mSegments; + const LLTextSegment* mHoverSegment; + + // Scrollbar data + class LLScrollbar* mScrollbar; + BOOL mHideScrollbarForShortDocs; + BOOL mTakesNonScrollClicks; + void (*mOnScrollEndCallback)(void*); + void *mOnScrollEndData; + + LLWString mPreeditWString; + LLWString mPreeditOverwrittenWString; + std::vector<S32> mPreeditPositions; + std::vector<BOOL> mPreeditStandouts; + +private: + + // + // Methods + // + void updateSegments(); + void pruneSegments(); + + void drawBackground(); + void drawSelectionBackground(); + void drawCursor(); + void drawText(); + void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyle& color, F32* right_x); + + // + // Data + // LLKeywords mKeywords; static LLColor4 mLinkColor; static void (*mURLcallback) (const char* url); static bool (*mSecondlifeURLcallback) (const std::string& url); static bool (*mSecondlifeURLcallbackRightClick) (const std::string& url); -protected: + + // Concrete LLTextCmd sub-classes used by the LLTextEditor base class + class LLTextCmdInsert; + class LLTextCmdAddChar; + class LLTextCmdOverwriteChar; + class LLTextCmdRemove; + LLWString mWText; mutable LLString mUTF8Text; mutable BOOL mTextIsUpToDate; @@ -376,8 +457,7 @@ protected: const LLFontGL* mGLFont; - LLScrollbar* mScrollbar; - LLViewBorder* mBorder; + class LLViewBorder* mBorder; BOOL mBaseDocIsPristine; LLTextCmd* mPristineCmd; @@ -387,7 +467,6 @@ protected: typedef std::deque<LLTextCmd*> undo_stack_t; undo_stack_t mUndoStack; - S32 mCursorPos; // I-beam is just after the mCursorPos-th character. S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be LLRect mTextRect; // The rect in which text is drawn. Excludes borders. // List of offsets and segment index of the start of each line. Always has at least one node (0). @@ -411,20 +490,7 @@ protected: }; typedef std::vector<line_info> line_list_t; line_list_t mLineStartList; - - // Are we in the middle of a drag-select? To figure out if there is a current - // selection, call hasSelection(). - BOOL mIsSelecting; - - S32 mSelectionStart; - S32 mSelectionEnd; - - void (*mOnScrollEndCallback)(void*); - void *mOnScrollEndData; - typedef std::vector<LLTextSegment *> segment_list_t; - segment_list_t mSegments; - LLTextSegment* mHoverSegment; LLFrameTimer mKeystrokeTimer; LLColor4 mCursorColor; @@ -439,11 +505,9 @@ protected: BOOL mReadOnly; BOOL mWordWrap; - BOOL mTabToNextField; // if true, tab moves focus to next field, else inserts spaces + BOOL mTabsToNextField; // if true, tab moves focus to next field, else inserts spaces BOOL mCommitOnFocusLost; BOOL mTakesFocus; - BOOL mHideScrollbarForShortDocs; - BOOL mTakesNonScrollClicks; BOOL mTrackBottom; // if true, keeps scroll position at bottom during resize BOOL mScrolledToBottom; @@ -453,24 +517,14 @@ protected: LLUUID mSourceID; - BOOL mHandleEditKeysDirectly; // If true, the standard edit keys (Ctrl-X, Delete, etc,) are handled here instead of routed by the menu system + // If true, the standard edit keys (Ctrl-X, Delete, etc,) are handled here + //instead of routed by the menu system + BOOL mHandleEditKeysDirectly; - // Use these to determine if a click on an embedded item is a drag - // or not. - S32 mMouseDownX; - S32 mMouseDownY; + LLCoordGL mLastIMEPosition; // Last position of the IME editor +}; // end class LLTextEditor - S32 mLastSelectionX; - S32 mLastSelectionY; - BOOL mParseHTML; - LLString mHTML; - - LLWString mPreeditWString; - LLWString mPreeditOverwrittenWString; - std::vector<S32> mPreeditPositions; - std::vector<BOOL> mPreeditStandouts; -}; class LLTextSegment { @@ -482,21 +536,20 @@ public: LLTextSegment( const LLColor4& color, S32 start, S32 end ); LLTextSegment( const LLColor3& color, S32 start, S32 end ); - S32 getStart() { return mStart; } - S32 getEnd() { return mEnd; } + S32 getStart() const { return mStart; } + S32 getEnd() const { return mEnd; } void setEnd( S32 end ) { mEnd = end; } - const LLColor4& getColor() { return mStyle.getColor(); } + const LLColor4& getColor() const { return mStyle.getColor(); } void setColor(const LLColor4 &color) { mStyle.setColor(color); } - const LLStyle& getStyle() { return mStyle; } + const LLStyle& getStyle() const { return mStyle; } void setStyle(const LLStyle &style) { mStyle = style; } void setIsDefault(BOOL b) { mIsDefault = b; } - BOOL getIsDefault() { return mIsDefault; } - + BOOL getIsDefault() const { return mIsDefault; } void setToken( LLKeywordToken* token ) { mToken = token; } - LLKeywordToken* getToken() { return mToken; } - BOOL getToolTip( LLString& msg ); + LLKeywordToken* getToken() const { return mToken; } + BOOL getToolTip( LLString& msg ) const; - void dump(); + void dump() const; struct compare { @@ -514,34 +567,5 @@ private: BOOL mIsDefault; }; -class LLTextCmd -{ -public: - LLTextCmd( S32 pos, BOOL group_with_next ) - : mPos(pos), - mGroupWithNext(group_with_next) - { - } - virtual ~LLTextCmd() {} - virtual BOOL execute(LLTextEditor* editor, S32* delta) = 0; - virtual S32 undo(LLTextEditor* editor) = 0; - virtual S32 redo(LLTextEditor* editor) = 0; - virtual BOOL canExtend(S32 pos); - virtual void blockExtensions(); - virtual BOOL extendAndExecute( LLTextEditor* editor, S32 pos, llwchar c, S32* delta ); - virtual BOOL hasExtCharValue( llwchar value ); - - // Define these here so they can access LLTextEditor through the friend relationship - S32 insert(LLTextEditor* editor, S32 pos, const LLWString &wstr); - S32 remove(LLTextEditor* editor, S32 pos, S32 length); - S32 overwrite(LLTextEditor* editor, S32 pos, llwchar wc); - - BOOL groupWithNext() { return mGroupWithNext; } - -protected: - S32 mPos; - BOOL mGroupWithNext; -}; - #endif // LL_TEXTEDITOR_ diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 7561fe8b48..ad523db78b 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1644,7 +1644,7 @@ void LLUI::setCursorPositionScreen(S32 x, S32 y) } //static -void LLUI::setCursorPositionLocal(LLView* viewp, S32 x, S32 y) +void LLUI::setCursorPositionLocal(const LLView* viewp, S32 x, S32 y) { S32 screen_x, screen_y; viewp->localPointToScreen(x, y, &screen_x, &screen_y); @@ -1847,12 +1847,12 @@ void LLUIImage::setScaleRegion(const LLRectf& region) } //TODO: move drawing implementation inside class -void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) +void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const { gl_draw_image(x, y, mImage, color, mClipRegion); } -void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) +void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const { if (mUniformScaling) { @@ -1871,7 +1871,7 @@ void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) } } -void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) +void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const { gl_draw_scaled_image_with_border( x, y, @@ -1883,7 +1883,7 @@ void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& c mScaleRegion); } -void LLUIImage::drawSolid(S32 x, S32 y, const LLColor4& color) +void LLUIImage::drawSolid(S32 x, S32 y, const LLColor4& color) const { gl_draw_scaled_image_with_border( x, y, @@ -1895,12 +1895,12 @@ void LLUIImage::drawSolid(S32 x, S32 y, const LLColor4& color) mScaleRegion); } -S32 LLUIImage::getWidth() +S32 LLUIImage::getWidth() const { return mImage->getWidth(0); } -S32 LLUIImage::getHeight() +S32 LLUIImage::getHeight() const { return mImage->getHeight(0); } diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 05982aa9e2..b5b15eef23 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -1,6 +1,6 @@ /** * @file llui.h - * @brief UI implementation + * @brief GL function declarations and other general static UI services. * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -43,7 +43,10 @@ #include <stack> #include "llimagegl.h" -class LLColor4; +// LLUIFactory +#include "llsd.h" + +class LLColor4; class LLVector3; class LLVector2; class LLUUID; @@ -147,11 +150,15 @@ inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL extern BOOL gShowTextEditCursor; class LLImageProviderInterface; + typedef void (*LLUIAudioCallback)(const LLUUID& uuid); class LLUI { public: + // + // Methods + // static void initClass(LLControlGroup* config, LLControlGroup* colors, LLControlGroup* assets, @@ -169,10 +176,10 @@ public: //helper functions (should probably move free standing rendering helper functions here) static LLString locateSkin(const LLString& filename); static void setCursorPositionScreen(S32 x, S32 y); - static void setCursorPositionLocal(LLView* viewp, S32 x, S32 y); + static void setCursorPositionLocal(const LLView* viewp, S32 x, S32 y); static void setScaleFactor(const LLVector2& scale_factor); static void setLineWidth(F32 width); - static LLUUID findAssetUUIDByName(const LLString& name); + static LLUUID findAssetUUIDByName(const LLString& name); static LLUIImage* getUIImageByName(const LLString& name); static LLVector2 getWindowSize(); static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y); @@ -181,7 +188,9 @@ public: static void glRectToScreen(const LLRect& gl, LLRect *screen); static void setHtmlHelp(LLHtmlHelp* html_help); -public: + // + // Data + // static LLControlGroup* sConfigGroup; static LLControlGroup* sColorsGroup; static LLControlGroup* sAssetsGroup; @@ -287,93 +296,179 @@ typedef enum e_widget_type WIDGET_TYPE_COUNT } EWidgetType; -// Manages generation of UI elements by LLSD, such that there is -// only one instance per uniquely identified LLSD parameter -// Class T is the instance type being managed, and INSTANCE_ADDAPTOR -// wraps an instance of the class with handlers for show/hide semantics, etc. -template <class T, class INSTANCE_ADAPTOR = T> -class LLUIInstanceMgr +// FactoryPolicy is a static class that controls the creation and lookup of UI elements, +// such as floaters. +// The key parameter is used to provide a unique identifier and/or associated construction +// parameters for a given UI instance +// +// Specialize this traits for different types, or provide a class with an identical interface +// in the place of the traits parameter +// +// For example: +// +// template <> +// class FactoryPolicy<MyClass> /* FactoryPolicy specialized for MyClass */ +// { +// public: +// static MyClass* findInstance(const LLSD& key = LLSD()) +// { +// /* return instance of MyClass associated with key */ +// } +// +// static MyClass* createInstance(const LLSD& key = LLSD()) +// { +// /* create new instance of MyClass using key for construction parameters */ +// } +// } +// +// class MyClass : public LLUIFactory<MyClass> +// { +// /* uses FactoryPolicy<MyClass> by default */ +// } + +template <class T> +class FactoryPolicy +{ +public: + // basic factory methods + static T* findInstance(const LLSD& key); // unimplemented, provide specialiation + static T* createInstance(const LLSD& key); // unimplemented, provide specialiation +}; + +// VisibilityPolicy controls the visibility of UI elements, such as floaters. +// The key parameter is used to store the unique identifier of a given UI instance +// +// Specialize this traits for different types, or duplicate this interface for specific instances +// (see above) + +template <class T> +class VisibilityPolicy +{ +public: + // visibility methods + static bool visible(T* instance, const LLSD& key); // unimplemented, provide specialiation + static void show(T* instance, const LLSD& key); // unimplemented, provide specialiation + static void hide(T* instance, const LLSD& key); // unimplemented, provide specialiation +}; + +// Manages generation of UI elements by LLSD, such that (generally) there is +// a unique instance per distinct LLSD parameter +// Class T is the instance type being managed, and the FACTORY_POLICY and VISIBILITY_POLICY +// classes provide static methods for creating, accessing, showing and hiding the associated +// element T +template <class T, class FACTORY_POLICY = FactoryPolicy<T>, class VISIBILITY_POLICY = VisibilityPolicy<T> > +class LLUIFactory { public: - LLUIInstanceMgr() + // give names to the template parameters so derived classes can refer to them + // except this doesn't work in gcc + typedef FACTORY_POLICY factory_policy_t; + typedef VISIBILITY_POLICY visibility_policy_t; + + LLUIFactory() { } - virtual ~LLUIInstanceMgr() + virtual ~LLUIFactory() { } // default show and hide methods - static T* showInstance(const LLSD& seed = LLSD()) + static T* showInstance(const LLSD& key = LLSD()) { - T* instance = INSTANCE_ADAPTOR::getInstance(seed); - INSTANCE_ADAPTOR::show(instance); + T* instance = getInstance(key); + if (instance != NULL) + { + VISIBILITY_POLICY::show(instance, key); + } return instance; } - static void hideInstance(const LLSD& seed = LLSD()) + static void hideInstance(const LLSD& key = LLSD()) { - T* instance = INSTANCE_ADAPTOR::getInstance(seed); - INSTANCE_ADAPTOR::hide(instance); + T* instance = getInstance(key); + if (instance != NULL) + { + VISIBILITY_POLICY::hide(instance, key); + } } - static void toggleInstance(const LLSD& seed = LLSD()) + static void toggleInstance(const LLSD& key = LLSD()) { - if (INSTANCE_ADAPTOR::instanceVisible(seed)) + if (instanceVisible(key)) { - INSTANCE_ADAPTOR::hideInstance(seed); + hideInstance(key); } else { - INSTANCE_ADAPTOR::showInstance(seed); + showInstance(key); } } - static BOOL instanceVisible(const LLSD& seed = LLSD()) + static bool instanceVisible(const LLSD& key = LLSD()) { - T* instance = INSTANCE_ADAPTOR::findInstance(seed); - return instance != NULL && INSTANCE_ADAPTOR::visible(instance); + T* instance = FACTORY_POLICY::findInstance(key); + return instance != NULL && VISIBILITY_POLICY::visible(instance, key); } - static T* getInstance(const LLSD& seed = LLSD()) + static T* getInstance(const LLSD& key = LLSD()) { - T* instance = INSTANCE_ADAPTOR::findInstance(seed); + T* instance = FACTORY_POLICY::findInstance(key); if (instance == NULL) { - instance = INSTANCE_ADAPTOR::createInstance(seed); + instance = FACTORY_POLICY::createInstance(key); } return instance; } }; -// Creates a UI singleton by ignoring the identifying parameter -// and always generating the same instance via the LLUIInstanceMgr interface. -// Note that since UI elements can be destroyed by their hierarchy, this singleton -// pattern uses a static pointer to an instance that will be re-created as needed. -template <class T, class INSTANCE_ADAPTOR = T> -class LLUISingleton: public LLUIInstanceMgr<T, INSTANCE_ADAPTOR> + +// Creates a UI singleton by ignoring the identifying parameter +// and always generating the same instance via the LLUIFactory interface. +// Note that since UI elements can be destroyed by their hierarchy, this singleton +// pattern uses a static pointer to an instance that will be re-created as needed. +// +// Usage Pattern: +// +// class LLFloaterFoo : public LLFloater, public LLUISingleton<LLFloaterFoo> +// { +// friend class LLUISingleton<LLFloaterFoo>; +// private: +// LLFloaterFoo(const LLSD& key); +// }; +// +// Note that LLUISingleton takes an option VisibilityPolicy parameter that defines +// how showInstance(), hideInstance(), etc. work. +// +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLUISingleton&oldid=79352 + +template <class T, class VISIBILITY_POLICY = VisibilityPolicy<T> > +class LLUISingleton: public LLUIFactory<T, LLUISingleton<T, VISIBILITY_POLICY>, VISIBILITY_POLICY> { -public: - // default constructor assumes T is derived from LLUISingleton (a true singleton) - LLUISingleton() : LLUIInstanceMgr<T, INSTANCE_ADAPTOR>() { sInstance = (T*)this; } +protected: + + // T must derive from LLUISingleton<T> + LLUISingleton() { sInstance = static_cast<T*>(this); } + ~LLUISingleton() { sInstance = NULL; } - static T* findInstance(const LLSD& seed = LLSD()) +public: + static T* findInstance(const LLSD& key = LLSD()) { return sInstance; } - - static T* createInstance(const LLSD& seed = LLSD()) + + static T* createInstance(const LLSD& key = LLSD()) { if (sInstance == NULL) { - sInstance = new T(seed); + sInstance = new T(key); } return sInstance; } -protected: +private: static T* sInstance; }; @@ -412,14 +507,15 @@ public: void setScaleRegion(const LLRectf& region); LLPointer<LLImageGL> getImage() { return mImage; } + const LLPointer<LLImageGL>& getImage() const { return mImage; } - void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR); - void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR); - void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color); - void drawSolid(S32 x, S32 y, const LLColor4& color); + void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const; + void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const; + void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const; + void drawSolid(S32 x, S32 y, const LLColor4& color) const; - S32 getWidth(); - S32 getHeight(); + S32 getWidth() const; + S32 getHeight() const; protected: LLRectf mScaleRegion; @@ -429,6 +525,140 @@ protected: BOOL mNoClip; }; + +template <typename T> +class LLTombStone : public LLRefCount +{ +public: + LLTombStone(T* target = NULL) : mTarget(target) {} + + void setTarget(T* target) { mTarget = target; } + T* getTarget() const { return mTarget; } +private: + T* mTarget; +}; + +// LLHandles are used to refer to objects whose lifetime you do not control or influence. +// Calling get() on a handle will return a pointer to the referenced object or NULL, +// if the object no longer exists. Note that during the lifetime of the returned pointer, +// you are assuming that the object will not be deleted by any action you perform, +// or any other thread, as normal when using pointers, so avoid using that pointer outside of +// the local code block. +// +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 + +template <typename T> +class LLHandle +{ +public: + LLHandle() : mTombStone(sDefaultTombStone) {} + const LLHandle<T>& operator =(const LLHandle<T>& other) + { + mTombStone = other.mTombStone; + return *this; + } + + bool isDead() const + { + return mTombStone->getTarget() == NULL; + } + + void markDead() + { + mTombStone = sDefaultTombStone; + } + + T* get() const + { + return mTombStone->getTarget(); + } + + friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs) + { + return lhs.mTombStone == rhs.mTombStone; + } + friend bool operator!= (const LLHandle<T>& lhs, const LLHandle<T>& rhs) + { + return !(lhs == rhs); + } + friend bool operator< (const LLHandle<T>& lhs, const LLHandle<T>& rhs) + { + return lhs.mTombStone < rhs.mTombStone; + } + friend bool operator> (const LLHandle<T>& lhs, const LLHandle<T>& rhs) + { + return lhs.mTombStone > rhs.mTombStone; + } +protected: + +protected: + LLPointer<LLTombStone<T> > mTombStone; + +private: + static LLPointer<LLTombStone<T> > sDefaultTombStone; +}; + +// initialize static "empty" tombstone pointer +template <typename T> LLPointer<LLTombStone<T> > LLHandle<T>::sDefaultTombStone = new LLTombStone<T>(); + + +template <typename T> +class LLRootHandle : public LLHandle<T> +{ +public: + LLRootHandle(T* object) { bind(object); } + LLRootHandle() {}; + ~LLRootHandle() { unbind(); } + + // this is redundant, since a LLRootHandle *is* an LLHandle + LLHandle<T> getHandle() { return LLHandle<T>(*this); } + + void bind(T* object) + { + // unbind existing tombstone + if (LLHandle<T>::mTombStone.notNull()) + { + if (LLHandle<T>::mTombStone->getTarget() == object) return; + LLHandle<T>::mTombStone->setTarget(NULL); + } + // tombstone reference counted, so no paired delete + LLHandle<T>::mTombStone = new LLTombStone<T>(object); + } + + void unbind() + { + LLHandle<T>::mTombStone->setTarget(NULL); + } + + //don't allow copying of root handles, since there should only be one +private: + LLRootHandle(const LLRootHandle& other) {}; +}; + +// Use this as a mixin for simple classes that need handles and when you don't +// want handles at multiple points of the inheritance hierarchy +template <typename T> +class LLHandleProvider +{ +protected: + typedef LLHandle<T> handle_type_t; + LLHandleProvider() + { + // provided here to enforce T deriving from LLHandleProvider<T> + } + + LLHandle<T> getHandle() + { + // perform lazy binding to avoid small tombstone allocations for handle + // providers whose handles are never referenced + mHandle.bind(static_cast<T*>(this)); + return mHandle; + } + +private: + LLRootHandle<T> mHandle; +}; + //RN: maybe this needs to moved elsewhere? class LLImageProviderInterface { diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index ee6176fff6..ade301a32e 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -32,20 +32,9 @@ //#include "llviewerprecompiledheaders.h" #include "linden_common.h" - #include "lluictrl.h" - -#include "llgl.h" -#include "llui.h" -#include "lluiconstants.h" #include "llfocusmgr.h" -#include "v3color.h" - -#include "llstring.h" -#include "llfontgl.h" -#include "llkeyboard.h" -const U32 MAX_STRING_LENGTH = 10; LLFocusableElement::LLFocusableElement() : mFocusLostCallback(NULL), @@ -55,6 +44,11 @@ LLFocusableElement::LLFocusableElement() { } +//virtual +LLFocusableElement::~LLFocusableElement() +{ +} + void LLFocusableElement::onFocusReceived() { if( mFocusReceivedCallback ) @@ -138,6 +132,18 @@ void LLUICtrl::onCommit() } } +//virtual +BOOL LLUICtrl::isCtrl() const +{ + return TRUE; +} + +//virtual +LLSD LLUICtrl::getValue() const +{ + return LLSD(); +} + // virtual BOOL LLUICtrl::setTextArg( const LLString& key, const LLStringExplicit& text ) { @@ -176,7 +182,7 @@ BOOL LLUICtrl::hasFocus() const void LLUICtrl::setFocus(BOOL b) { // focus NEVER goes to ui ctrls that are disabled! - if (!mEnabled) + if (!getEnabled()) { return; } @@ -266,6 +272,17 @@ BOOL LLUICtrl::acceptsTextInput() const return FALSE; } +//virtual +BOOL LLUICtrl::isDirty() const +{ + return FALSE; +}; + +//virtual +void LLUICtrl::resetDirty() +{ +} + // virtual void LLUICtrl::onTabInto() { @@ -315,7 +332,7 @@ public: CompareByDefaultTabGroup(LLView::child_tab_order_t order, S32 default_tab_group): LLCompareByTabOrder(order), mDefaultTabGroup(default_tab_group) {} -protected: +private: /*virtual*/ bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const { S32 ag = a.first; // tab group for a @@ -329,8 +346,10 @@ protected: S32 mDefaultTabGroup; }; -// sorter for plugging into the query -class DefaultTabGroupFirstSorter : public LLQuerySorter, public LLSingleton<DefaultTabGroupFirstSorter> + +// Sorter for plugging into the query. +// I'd have defined it local to the one method that uses it but that broke the VS 05 compiler. -MG +class LLUICtrl::DefaultTabGroupFirstSorter : public LLQuerySorter, public LLSingleton<DefaultTabGroupFirstSorter> { public: /*virtual*/ void operator() (LLView * parent, viewList_t &children) const @@ -339,14 +358,13 @@ public: } }; - BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash) { // try to select default tab group child - LLCtrlQuery query = LLView::getTabOrderQuery(); + LLCtrlQuery query = getTabOrderQuery(); // sort things such that the default tab group is at the front query.setSorter(DefaultTabGroupFirstSorter::getInstance()); - LLView::child_list_t result = query(this); + child_list_t result = query(this); if(result.size() > 0) { LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front()); @@ -361,10 +379,116 @@ BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash) } return TRUE; } - // fall back on default behavior if we didn't find anything - return LLView::focusFirstItem(prefer_text_fields); + // search for text field first + if(prefer_text_fields) + { + LLCtrlQuery query = getTabOrderQuery(); + query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); + child_list_t result = query(this); + if(result.size() > 0) + { + LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front()); + if(!ctrl->hasFocus()) + { + ctrl->setFocus(TRUE); + ctrl->onTabInto(); + gFocusMgr.triggerFocusFlash(); + } + return TRUE; + } + } + // no text field found, or we don't care about text fields + result = getTabOrderQuery().run(this); + if(result.size() > 0) + { + LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front()); + if(!ctrl->hasFocus()) + { + ctrl->setFocus(TRUE); + ctrl->onTabInto(); + gFocusMgr.triggerFocusFlash(); + } + return TRUE; + } + return FALSE; } +BOOL LLUICtrl::focusLastItem(BOOL prefer_text_fields) +{ + // search for text field first + if(prefer_text_fields) + { + LLCtrlQuery query = getTabOrderQuery(); + query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); + child_list_t result = query(this); + if(result.size() > 0) + { + LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back()); + if(!ctrl->hasFocus()) + { + ctrl->setFocus(TRUE); + ctrl->onTabInto(); + gFocusMgr.triggerFocusFlash(); + } + return TRUE; + } + } + // no text field found, or we don't care about text fields + child_list_t result = getTabOrderQuery().run(this); + if(result.size() > 0) + { + LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back()); + if(!ctrl->hasFocus()) + { + ctrl->setFocus(TRUE); + ctrl->onTabInto(); + gFocusMgr.triggerFocusFlash(); + } + return TRUE; + } + return FALSE; +} + +BOOL LLUICtrl::focusNextItem(BOOL text_fields_only) +{ + // this assumes that this method is called on the focus root. + LLCtrlQuery query = getTabOrderQuery(); + if(text_fields_only || LLUI::sConfigGroup->getBOOL("TabToTextFieldsOnly")) + { + query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); + } + child_list_t result = query(this); + return focusNext(result); +} + +BOOL LLUICtrl::focusPrevItem(BOOL text_fields_only) +{ + // this assumes that this method is called on the focus root. + LLCtrlQuery query = getTabOrderQuery(); + if(text_fields_only || LLUI::sConfigGroup->getBOOL("TabToTextFieldsOnly")) + { + query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); + } + child_list_t result = query(this); + return focusPrev(result); +} + +const LLUICtrl* LLUICtrl::findRootMostFocusRoot() const +{ + const LLUICtrl* focus_root = NULL; + const LLUICtrl* next_view = this; + while(next_view) + { + if (next_view->isFocusRoot()) + { + focus_root = next_view; + } + next_view = next_view->getParentUICtrl(); + } + return focus_root; +} + + /* // Don't let the children handle the tool tip. Handle it here instead. BOOL LLUICtrl::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) @@ -381,7 +505,7 @@ BOOL LLUICtrl::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_sc 0, 0, &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); localPointToScreen( - mRect.getWidth(), mRect.getHeight(), + getRect().getWidth(), getRect().getHeight(), &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); handled = TRUE; @@ -425,7 +549,26 @@ LLPanel* LLUICtrl::getParentPanel() const { parent = parent->getParent(); } - return reinterpret_cast<LLPanel*>(parent); + return (LLPanel*)(parent); +} + +// Skip over any parents that are not LLUICtrl's +// Used in focus logic since only LLUICtrl elements can have focus +LLUICtrl* LLUICtrl::getParentUICtrl() const +{ + LLView* parent = getParent(); + while (parent) + { + if (parent->isCtrl()) + { + return (LLUICtrl*)(parent); + } + else + { + parent = parent->getParent(); + } + } + return NULL; } // virtual diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index e47ee318be..81b00d4ec3 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -37,28 +37,13 @@ #include "llrect.h" #include "llsd.h" -// -// Classes -// -class LLFontGL; -class LLButton; -class LLTextBox; -class LLLineEditor; -class LLUICtrl; -class LLPanel; -class LLCtrlSelectionInterface; -class LLCtrlListInterface; -class LLCtrlScrollInterface; - -typedef void (*LLUICtrlCallback)(LLUICtrl* ctrl, void* userdata); -typedef BOOL (*LLUICtrlValidate)(LLUICtrl* ctrl, void* userdata); class LLFocusableElement { friend class LLFocusMgr; // allow access to focus change handlers public: LLFocusableElement(); - virtual ~LLFocusableElement() {}; + virtual ~LLFocusableElement(); virtual void setFocus( BOOL b ); virtual BOOL hasFocus() const; @@ -80,63 +65,74 @@ class LLUICtrl : public LLView, public LLFocusableElement { public: + typedef void (*LLUICtrlCallback)(LLUICtrl* ctrl, void* userdata); + typedef BOOL (*LLUICtrlValidate)(LLUICtrl* ctrl, void* userdata); + LLUICtrl(); LLUICtrl( const LLString& name, const LLRect& rect, BOOL mouse_opaque, LLUICtrlCallback callback, void* callback_userdata, U32 reshape=FOLLOWS_NONE); - virtual ~LLUICtrl(); + /*virtual*/ ~LLUICtrl(); // LLView interface - //virtual BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect); - virtual void initFromXML(LLXMLNodePtr node, LLView* parent); - virtual LLXMLNodePtr getXML(bool save_children = true) const; - - virtual LLSD getValue() const { return LLSD(); } - - // Defaults to no-op - virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ); - - // Defaults to no-op - virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); + /*virtual*/ void initFromXML(LLXMLNodePtr node, LLView* parent); + /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; + /*virtual*/ BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); + /*virtual*/ void onFocusReceived(); + /*virtual*/ void onFocusLost(); + /*virtual*/ BOOL isCtrl() const; + /*virtual*/ void setTentative(BOOL b); + /*virtual*/ BOOL getTentative() const; + + // From LLFocusableElement + /*virtual*/ void setFocus( BOOL b ); + /*virtual*/ BOOL hasFocus() const; + + // New virtuals - // Defaults to return NULL - virtual LLCtrlSelectionInterface* getSelectionInterface(); - virtual LLCtrlListInterface* getListInterface(); - virtual LLCtrlScrollInterface* getScrollInterface(); + // Return NULL by default (overrride if the class has the appropriate interface) + virtual class LLCtrlSelectionInterface* getSelectionInterface(); + virtual class LLCtrlListInterface* getListInterface(); + virtual class LLCtrlScrollInterface* getScrollInterface(); - virtual void setFocus( BOOL b ); - virtual BOOL hasFocus() const; + virtual LLSD getValue() const; + virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ); + virtual void setIsChrome(BOOL is_chrome); - virtual void onFocusReceived(); - virtual void onFocusLost(); + virtual BOOL acceptsTextInput() const; // Defaults to false + // A control is dirty if the user has modified its value. + // Editable controls should override this. + virtual BOOL isDirty() const; // Defauls to false + virtual void resetDirty(); //Defaults to no-op + + // Call appropriate callbacks virtual void onLostTop(); // called when registered as top ctrl and user clicks elsewhere - - virtual void setTabStop( BOOL b ); - virtual BOOL hasTabStop() const; - - // Defaults to false - virtual BOOL acceptsTextInput() const; - - // Default to no-op + virtual void onCommit(); + + // Default to no-op: virtual void onTabInto(); virtual void clear(); + virtual void setDoubleClickCallback( void (*cb)(void*) ); + virtual void setColor(const LLColor4& color); + virtual void setMinValue(LLSD min_value); + virtual void setMaxValue(LLSD max_value); - virtual void setIsChrome(BOOL is_chrome); - virtual BOOL getIsChrome() const; - - virtual void onCommit(); + BOOL focusNextItem(BOOL text_entry_only); + BOOL focusPrevItem(BOOL text_entry_only); + BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE ); + BOOL focusLastItem(BOOL prefer_text_fields = FALSE); - virtual BOOL isCtrl() const { return TRUE; } - // "Tentative" controls have a proposed value, but haven't committed - // it yet. This is used when multiple objects are selected and we - // want to display a parameter that differs between the objects. - virtual void setTentative(BOOL b); - virtual BOOL getTentative() const; + // Non Virtuals + BOOL getIsChrome() const; + + void setTabStop( BOOL b ); + BOOL hasTabStop() const; // Returns containing panel/floater or NULL if none found. - LLPanel* getParentPanel() const; + class LLPanel* getParentPanel() const; + class LLUICtrl* getParentUICtrl() const; void* getCallbackUserData() const { return mCallbackUserData; } void setCallbackUserData( void* data ) { mCallbackUserData = data; } @@ -144,18 +140,8 @@ public: void setCommitCallback( void (*cb)(LLUICtrl*, void*) ) { mCommitCallback = cb; } void setValidateBeforeCommit( BOOL(*cb)(LLUICtrl*, void*) ) { mValidateCallback = cb; } void setLostTopCallback( void (*cb)(LLUICtrl*, void*) ) { mLostTopCallback = cb; } - - // Defaults to no-op! - virtual void setDoubleClickCallback( void (*cb)(void*) ); - - // Defaults to no-op - virtual void setColor(const LLColor4& color); - - // Defaults to no-op - virtual void setMinValue(LLSD min_value); - virtual void setMaxValue(LLSD max_value); - - /*virtual*/ BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE ); + + const LLUICtrl* findRootMostFocusRoot() const; class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter> { @@ -165,11 +151,6 @@ public: } }; - // Returns TRUE if the user has modified this control. Editable controls should override this. - virtual BOOL isDirty() const { return FALSE; }; - // Clear the dirty state - virtual void resetDirty() {}; - protected: void (*mCommitCallback)( LLUICtrl* ctrl, void* userdata ); @@ -177,13 +158,14 @@ protected: BOOL (*mValidateCallback)( LLUICtrl* ctrl, void* userdata ); void* mCallbackUserData; - BOOL mTentative; - BOOL mTabStop; private: - BOOL mIsChrome; + BOOL mTabStop; + BOOL mIsChrome; + BOOL mTentative; + class DefaultTabGroupFirstSorter; }; #endif // LL_LLUICTRL_H diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 1e8798e7f7..47919408ab 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -67,7 +67,6 @@ #include "llui.h" #include "llviewborder.h" - const char XML_HEADER[] = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n"; // *NOTE: If you add a new class derived from LLPanel, add a check for its @@ -214,7 +213,7 @@ LLUICtrlFactory::LLUICtrlFactory() LLUICtrlCreator<LLUICtrlLocate>::registerCreator(LL_UI_CTRL_LOCATE_TAG, this); LLUICtrlCreator<LLUICtrlLocate>::registerCreator(LL_PAD_TAG, this); LLUICtrlCreator<LLViewBorder>::registerCreator(LL_VIEW_BORDER_TAG, this); - LLUICtrlCreator<LLTabContainerCommon>::registerCreator(LL_TAB_CONTAINER_COMMON_TAG, this); + LLUICtrlCreator<LLTabContainer>::registerCreator(LL_TAB_CONTAINER_COMMON_TAG, this); LLUICtrlCreator<LLScrollableContainerView>::registerCreator(LL_SCROLLABLE_CONTAINER_VIEW_TAG, this); LLUICtrlCreator<LLPanel>::registerCreator(LL_PANEL_TAG, this); LLUICtrlCreator<LLMenuGL>::registerCreator(LL_MENU_GL_TAG, this); @@ -223,7 +222,6 @@ LLUICtrlFactory::LLUICtrlFactory() LLUICtrlCreator<LLLayoutStack>::registerCreator(LL_LAYOUT_STACK_TAG, this); setupPaths(); - } void LLUICtrlFactory::setupPaths() @@ -234,14 +232,7 @@ void LLUICtrlFactory::setupPaths() BOOL success = LLXMLNode::parseFile(filename, root, NULL); mXUIPaths.clear(); - if (!success) - { - LLString slash = gDirUtilp->getDirDelimiter(); - LLString dir = gDirUtilp->getAppRODataDir() + slash + "skins" + slash + "xui" + slash + "en-us" + slash; - llwarns << "XUI::config file unable to open." << llendl; - mXUIPaths.push_back(dir); - } - else + if (success) { LLXMLNodePtr path; LLString app_dir = gDirUtilp->getAppRODataDir(); @@ -267,16 +258,15 @@ void LLUICtrlFactory::setupPaths() } } } - - + else // parsing failed + { + LLString slash = gDirUtilp->getDirDelimiter(); + LLString dir = gDirUtilp->getAppRODataDir() + slash + "skins" + slash + "xui" + slash + "en-us" + slash; + llwarns << "XUI::config file unable to open." << llendl; + mXUIPaths.push_back(dir); + } } -//----------------------------------------------------------------------------- -// ~LLUICtrlFactory() -//----------------------------------------------------------------------------- -LLUICtrlFactory::~LLUICtrlFactory() -{ -} //----------------------------------------------------------------------------- @@ -284,7 +274,6 @@ LLUICtrlFactory::~LLUICtrlFactory() //----------------------------------------------------------------------------- bool LLUICtrlFactory::getLayeredXMLNode(const LLString &filename, LLXMLNodePtr& root) { - if (!LLXMLNode::parseFile(mXUIPaths.front() + filename, root, NULL)) { if (!LLXMLNode::parseFile(filename, root, NULL)) @@ -347,7 +336,7 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const LLString &filename if (LLUI::sShowXUINames) { - floaterp->mToolTipMsg = filename; + floaterp->setToolTip(filename); } if (factory_map) @@ -355,7 +344,7 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const LLString &filename mFactoryStack.pop_front(); } - LLViewHandle handle = floaterp->getHandle(); + LLHandle<LLFloater> handle = floaterp->getHandle(); mBuiltFloaters[handle] = filename; } @@ -411,10 +400,10 @@ BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const LLString &filename, if (LLUI::sShowXUINames) { - panelp->mToolTipMsg = filename; + panelp->setToolTip(filename); } - LLViewHandle handle = panelp->getHandle(); + LLHandle<LLPanel> handle = panelp->getHandle(); mBuiltPanels[handle] = filename; if (factory_map) @@ -446,8 +435,6 @@ LLMenuGL *LLUICtrlFactory::buildMenu(const LLString &filename, LLView* parentp) return NULL; } - - if (root->hasName("menu")) { menu = (LLMenuGL*)LLMenuGL::fromXML(root, parentp, this); @@ -459,7 +446,7 @@ LLMenuGL *LLUICtrlFactory::buildMenu(const LLString &filename, LLView* parentp) if (LLUI::sShowXUINames) { - menu->mToolTipMsg = filename; + menu->setToolTip(filename); } return menu; @@ -470,7 +457,6 @@ LLMenuGL *LLUICtrlFactory::buildMenu(const LLString &filename, LLView* parentp) //----------------------------------------------------------------------------- LLPieMenu *LLUICtrlFactory::buildPieMenu(const LLString &filename, LLView* parentp) { - LLXMLNodePtr root; if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) @@ -494,29 +480,13 @@ LLPieMenu *LLUICtrlFactory::buildPieMenu(const LLString &filename, LLView* paren if (LLUI::sShowXUINames) { - menu->mToolTipMsg = filename; + menu->setToolTip(filename); } return menu; } //----------------------------------------------------------------------------- -// removePanel() -//----------------------------------------------------------------------------- -void LLUICtrlFactory::removePanel(LLPanel* panelp) -{ - mBuiltPanels.erase(panelp->getHandle()); -} - -//----------------------------------------------------------------------------- -// removeFloater() -//----------------------------------------------------------------------------- -void LLUICtrlFactory::removeFloater(LLFloater* floaterp) -{ - mBuiltFloaters.erase(floaterp->getHandle()); -} - -//----------------------------------------------------------------------------- // rebuild() //----------------------------------------------------------------------------- void LLUICtrlFactory::rebuild() @@ -525,48 +495,48 @@ void LLUICtrlFactory::rebuild() for (built_panel_it = mBuiltPanels.begin(); built_panel_it != mBuiltPanels.end(); ++built_panel_it) + { + LLString filename = built_panel_it->second; + LLPanel* panelp = built_panel_it->first.get(); + if (!panelp) { - LLString filename = built_panel_it->second; - LLPanel* panelp = LLPanel::getPanelByHandle(built_panel_it->first); - if (!panelp) - { - continue; - } - llinfos << "Rebuilding UI panel " << panelp->getName() - << " from " << filename - << llendl; - BOOL visible = panelp->getVisible(); - panelp->setVisible(FALSE); - panelp->setFocus(FALSE); - panelp->deleteAllChildren(); - - buildPanel(panelp, filename.c_str(), &panelp->getFactoryMap()); - panelp->setVisible(visible); + continue; } + llinfos << "Rebuilding UI panel " << panelp->getName() + << " from " << filename + << llendl; + BOOL visible = panelp->getVisible(); + panelp->setVisible(FALSE); + panelp->setFocus(FALSE); + panelp->deleteAllChildren(); + + buildPanel(panelp, filename.c_str(), &panelp->getFactoryMap()); + panelp->setVisible(visible); + } built_floater_t::iterator built_floater_it; for (built_floater_it = mBuiltFloaters.begin(); built_floater_it != mBuiltFloaters.end(); ++built_floater_it) + { + LLFloater* floaterp = built_floater_it->first.get(); + if (!floaterp) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(built_floater_it->first); - if (!floaterp) - { - continue; - } - LLString filename = built_floater_it->second; - llinfos << "Rebuilding UI floater " << floaterp->getName() - << " from " << filename - << llendl; - BOOL visible = floaterp->getVisible(); - floaterp->setVisible(FALSE); - floaterp->setFocus(FALSE); - floaterp->deleteAllChildren(); - - gFloaterView->removeChild(floaterp); - buildFloater(floaterp, filename, &floaterp->getFactoryMap()); - floaterp->setVisible(visible); + continue; } + LLString filename = built_floater_it->second; + llinfos << "Rebuilding UI floater " << floaterp->getName() + << " from " << filename + << llendl; + BOOL visible = floaterp->getVisible(); + floaterp->setVisible(FALSE); + floaterp->setFocus(FALSE); + floaterp->deleteAllChildren(); + + gFloaterView->removeChild(floaterp); + buildFloater(floaterp, filename, &floaterp->getFactoryMap()); + floaterp->setVisible(visible); + } } //----------------------------------------------------------------------------- @@ -674,113 +644,93 @@ BOOL LLUICtrlFactory::getAttributeColor(LLXMLNodePtr node, const LLString& name, //============================================================================ -LLButton* LLUICtrlFactory::getButtonByName(LLPanel* panelp, const LLString& name) +LLButton* LLUICtrlFactory::getButtonByName(const LLPanel* panelp, const LLString& name) { - return (LLButton*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_BUTTON); + return panelp->getChild<LLButton>(name); } -LLCheckBoxCtrl* LLUICtrlFactory::getCheckBoxByName(LLPanel* panelp, const LLString& name) +LLCheckBoxCtrl* LLUICtrlFactory::getCheckBoxByName(const LLPanel* panelp, const LLString& name) { - return (LLCheckBoxCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_CHECKBOX); + return panelp->getChild<LLCheckBoxCtrl>(name); } -LLComboBox* LLUICtrlFactory::getComboBoxByName(LLPanel* panelp, const LLString& name) +LLComboBox* LLUICtrlFactory::getComboBoxByName(const LLPanel* panelp, const LLString& name) { - return (LLComboBox*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_COMBO_BOX); + return panelp->getChild<LLComboBox>(name); } -LLIconCtrl* LLUICtrlFactory::getIconByName(LLPanel* panelp, const LLString& name) +LLIconCtrl* LLUICtrlFactory::getIconByName(const LLPanel* panelp, const LLString& name) { - return (LLIconCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_ICON); + return panelp->getChild<LLIconCtrl>(name); } -LLLineEditor* LLUICtrlFactory::getLineEditorByName(LLPanel* panelp, const LLString& name) +LLLineEditor* LLUICtrlFactory::getLineEditorByName(const LLPanel* panelp, const LLString& name) { - return (LLLineEditor*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_LINE_EDITOR); + return panelp->getChild<LLLineEditor>(name); } -LLNameListCtrl* LLUICtrlFactory::getNameListByName(LLPanel* panelp, const LLString& name) +LLRadioGroup* LLUICtrlFactory::getRadioGroupByName(const LLPanel* panelp, const LLString& name) { - return (LLNameListCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_NAME_LIST); + return panelp->getChild<LLRadioGroup>(name); } -LLRadioGroup* LLUICtrlFactory::getRadioGroupByName(LLPanel* panelp, const LLString& name) +LLScrollListCtrl* LLUICtrlFactory::getScrollListByName(const LLPanel* panelp, const LLString& name) { - return (LLRadioGroup*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_RADIO_GROUP); + return panelp->getChild<LLScrollListCtrl>(name); } -LLScrollListCtrl* LLUICtrlFactory::getScrollListByName(LLPanel* panelp, const LLString& name) +LLSliderCtrl* LLUICtrlFactory::getSliderByName(const LLPanel* panelp, const LLString& name) { - return (LLScrollListCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SCROLL_LIST); + return panelp->getChild<LLSliderCtrl>(name); } -LLSliderCtrl* LLUICtrlFactory::getSliderByName(LLPanel* panelp, const LLString& name) +LLSlider* LLUICtrlFactory::getSliderBarByName(const LLPanel* panelp, const LLString& name) { - return (LLSliderCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SLIDER); + return panelp->getChild<LLSlider>(name); } -LLSlider* LLUICtrlFactory::getSliderBarByName(LLPanel* panelp, const LLString& name) +LLSpinCtrl* LLUICtrlFactory::getSpinnerByName(const LLPanel* panelp, const LLString& name) { - return (LLSlider*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SLIDER_BAR); + return panelp->getChild<LLSpinCtrl>(name); } -LLSpinCtrl* LLUICtrlFactory::getSpinnerByName(LLPanel* panelp, const LLString& name) +LLTextBox* LLUICtrlFactory::getTextBoxByName(const LLPanel* panelp, const LLString& name) { - return (LLSpinCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SPINNER); + return panelp->getChild<LLTextBox>(name); } -LLTextBox* LLUICtrlFactory::getTextBoxByName(LLPanel* panelp, const LLString& name) +LLTextEditor* LLUICtrlFactory::getTextEditorByName(const LLPanel* panelp, const LLString& name) { - return (LLTextBox*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_TEXT_BOX); + return panelp->getChild<LLTextEditor>(name); } -LLTextEditor* LLUICtrlFactory::getTextEditorByName(LLPanel* panelp, const LLString& name) +LLTabContainer* LLUICtrlFactory::getTabContainerByName(const LLPanel* panelp, const LLString& name) { - return (LLTextEditor*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_TEXT_EDITOR); -} - -LLTabContainerCommon* LLUICtrlFactory::getTabContainerByName(LLPanel* panelp, const LLString& name) -{ - return (LLTabContainerCommon*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_TAB_CONTAINER); -} - -LLScrollableContainerView* LLUICtrlFactory::getScrollableContainerByName(LLPanel* panelp, const LLString& name) -{ - return (LLScrollableContainerView*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SCROLL_CONTAINER); + return panelp->getChild<LLTabContainer>(name); } -LLTextureCtrl* LLUICtrlFactory::getTexturePickerByName(LLPanel* panelp, const LLString& name) +LLScrollableContainerView* LLUICtrlFactory::getScrollableContainerByName(const LLPanel* panelp, const LLString& name) { - return (LLTextureCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_TEXTURE_PICKER); -} - -LLPanel* LLUICtrlFactory::getPanelByName(LLPanel* panelp, const LLString& name) -{ - return (LLPanel*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_PANEL); -} - -LLColorSwatchCtrl* LLUICtrlFactory::getColorSwatchByName(LLPanel* panelp, const LLString& name) -{ - return (LLColorSwatchCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_COLOR_SWATCH); + return panelp->getChild<LLScrollableContainerView>(name); } -LLWebBrowserCtrl* LLUICtrlFactory::getWebBrowserCtrlByName(LLPanel* panelp, const LLString& name) +LLPanel* LLUICtrlFactory::getPanelByName(const LLPanel* panelp, const LLString& name) { - return (LLWebBrowserCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_WEBBROWSER); + return panelp->getChild<LLPanel>(name); } -LLMenuItemCallGL* LLUICtrlFactory::getMenuItemCallByName(LLPanel* panelp, const LLString& name) +LLMenuItemCallGL* LLUICtrlFactory::getMenuItemCallByName(const LLPanel* panelp, const LLString& name) { - return (LLMenuItemCallGL*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_MENU_ITEM_CALL); + return panelp->getChild<LLMenuItemCallGL>(name); } -LLScrollingPanelList* LLUICtrlFactory::getScrollingPanelList(LLPanel* panelp, const LLString& name) +LLScrollingPanelList* LLUICtrlFactory::getScrollingPanelList(const LLPanel* panelp, const LLString& name) { - return (LLScrollingPanelList*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SCROLLING_PANEL_LIST); + return panelp->getChild<LLScrollingPanelList>(name); } -LLCtrlListInterface* LLUICtrlFactory::getListInterfaceByName(LLPanel* panelp, const LLString& name) +LLCtrlListInterface* LLUICtrlFactory::getListInterfaceByName(const LLPanel* panelp, const LLString& name) { LLView* viewp = panelp->getCtrlByNameAndType(name, WIDGET_TYPE_DONTCARE); if (viewp && viewp->isCtrl()) @@ -790,7 +740,7 @@ LLCtrlListInterface* LLUICtrlFactory::getListInterfaceByName(LLPanel* panelp, co return NULL; } -LLCtrlSelectionInterface* LLUICtrlFactory::getSelectionInterfaceByName(LLPanel* panelp, const LLString& name) +LLCtrlSelectionInterface* LLUICtrlFactory::getSelectionInterfaceByName(const LLPanel* panelp, const LLString& name) { LLView* viewp = panelp->getCtrlByNameAndType(name, WIDGET_TYPE_DONTCARE); if (viewp && viewp->isCtrl()) @@ -800,7 +750,7 @@ LLCtrlSelectionInterface* LLUICtrlFactory::getSelectionInterfaceByName(LLPanel* return NULL; } -LLCtrlScrollInterface* LLUICtrlFactory::getScrollInterfaceByName(LLPanel* panelp, const LLString& name) +LLCtrlScrollInterface* LLUICtrlFactory::getScrollInterfaceByName(const LLPanel* panelp, const LLString& name) { LLView* viewp = panelp->getCtrlByNameAndType(name, WIDGET_TYPE_DONTCARE); if (viewp && viewp->isCtrl()) diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 486ed12721..1b90e64322 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -38,68 +38,35 @@ #include "llcallbackmap.h" #include "llfloater.h" -class LLControlGroup; class LLView; -class LLFontGL; - -class LLFloater; class LLPanel; -class LLButton; -class LLCheckBoxCtrl; -class LLComboBox; -class LLIconCtrl; -class LLLineEditor; -class LLMenuGL; -class LLMenuBarGL; -class LLMenuItemCallGL; -class LLNameListCtrl; -class LLPieMenu; -class LLRadioGroup; -class LLSearchEditor; -class LLScrollableContainerView; -class LLScrollListCtrl; -class LLSlider; -class LLSliderCtrl; -class LLSpinCtrl; -class LLTextBox; -class LLTextEditor; -class LLTextureCtrl; -class LLWebBrowserCtrl; -class LLViewBorder; -class LLColorSwatchCtrl; -class LLScrollingPanelList; -class LLCtrlListInterface; -class LLCtrlSelectionInterface; -class LLCtrlScrollInterface; - -// Widget class LLUICtrlFactory { public: LLUICtrlFactory(); // do not call! needs to be public so run-time can clean up the singleton - virtual ~LLUICtrlFactory(); + virtual ~LLUICtrlFactory() {} void setupPaths(); void buildFloater(LLFloater* floaterp, const LLString &filename, - const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE); - + const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE); BOOL buildPanel(LLPanel* panelp, const LLString &filename, const LLCallbackMap::map_t* factory_map = NULL); - LLMenuGL *buildMenu(const LLString &filename, LLView* parentp); + void removePanel(LLPanel* panelp) { mBuiltPanels.erase(panelp->getHandle()); } + void removeFloater(LLFloater* floaterp) { mBuiltFloaters.erase(floaterp->getHandle()); } - LLPieMenu *buildPieMenu(const LLString &filename, LLView* parentp); + class LLMenuGL *buildMenu(const LLString &filename, LLView* parentp); + class LLPieMenu *buildPieMenu(const LLString &filename, LLView* parentp); // Does what you want for LLFloaters and LLPanels // Returns 0 on success S32 saveToXML(LLView* viewp, const LLString& filename); - void removePanel(LLPanel* panelp); - void removeFloater(LLFloater* floaterp); + // Rebuilds all currently built panels. void rebuild(); static EWidgetType getWidgetType(const LLString& ctrl_type); @@ -107,38 +74,42 @@ public: static BOOL getAttributeColor(LLXMLNodePtr node, const LLString& name, LLColor4& color); // specific typed getters - static LLButton* getButtonByName( LLPanel* panelp, const LLString& name); - static LLCheckBoxCtrl* getCheckBoxByName( LLPanel* panelp, const LLString& name); - static LLComboBox* getComboBoxByName( LLPanel* panelp, const LLString& name); - static LLIconCtrl* getIconByName( LLPanel* panelp, const LLString& name); - static LLLineEditor* getLineEditorByName( LLPanel* panelp, const LLString& name); - static LLNameListCtrl* getNameListByName( LLPanel* panelp, const LLString& name); - static LLRadioGroup* getRadioGroupByName( LLPanel* panelp, const LLString& name); - static LLScrollListCtrl* getScrollListByName( LLPanel* panelp, const LLString& name); - static LLSliderCtrl* getSliderByName( LLPanel* panelp, const LLString& name); - static LLSlider* getSliderBarByName( LLPanel* panelp, const LLString& name); - static LLSpinCtrl* getSpinnerByName( LLPanel* panelp, const LLString& name); - static LLTextBox* getTextBoxByName( LLPanel* panelp, const LLString& name); - static LLTextEditor* getTextEditorByName( LLPanel* panelp, const LLString& name); - static LLTabContainerCommon* getTabContainerByName( LLPanel* panelp, const LLString& name); - static LLScrollableContainerView* getScrollableContainerByName(LLPanel* panelp, const LLString& name); - static LLTextureCtrl* getTexturePickerByName( LLPanel* panelp, const LLString& name); - static LLPanel* getPanelByName(LLPanel* panelp, const LLString& name); - static LLColorSwatchCtrl* getColorSwatchByName(LLPanel* panelp, const LLString& name); - static LLWebBrowserCtrl* getWebBrowserCtrlByName(LLPanel* panelp, const LLString& name); - static LLMenuItemCallGL* getMenuItemCallByName(LLPanel* panelp, const LLString& name); - static LLScrollingPanelList* getScrollingPanelList(LLPanel* panelp, const LLString& name); + static class LLButton* getButtonByName( const LLPanel* panelp, const LLString& name); + static class LLCheckBoxCtrl* getCheckBoxByName( const LLPanel* panelp, const LLString& name); + static class LLComboBox* getComboBoxByName( const LLPanel* panelp, const LLString& name); + static class LLIconCtrl* getIconByName( const LLPanel* panelp, const LLString& name); + static class LLLineEditor* getLineEditorByName( const LLPanel* panelp, const LLString& name); + static class LLRadioGroup* getRadioGroupByName( const LLPanel* panelp, const LLString& name); + static class LLScrollListCtrl* getScrollListByName( const LLPanel* panelp, const LLString& name); + static class LLSliderCtrl* getSliderByName( const LLPanel* panelp, const LLString& name); + static class LLSlider* getSliderBarByName( const LLPanel* panelp, const LLString& name); + static class LLSpinCtrl* getSpinnerByName( const LLPanel* panelp, const LLString& name); + static class LLTextBox* getTextBoxByName( const LLPanel* panelp, const LLString& name); + static class LLTextEditor* getTextEditorByName( const LLPanel* panelp, const LLString& name); + static class LLTabContainer* getTabContainerByName( const LLPanel* panelp, const LLString& name); + static class LLScrollableContainerView* getScrollableContainerByName(const LLPanel* panelp, const LLString& name); + static class LLPanel* getPanelByName( const LLPanel* panelp, const LLString& name); + static class LLMenuItemCallGL* getMenuItemCallByName( const LLPanel* panelp, const LLString& name); + static class LLScrollingPanelList* getScrollingPanelList( const LLPanel* panelp, const LLString& name); // interface getters - static LLCtrlListInterface* getListInterfaceByName(LLPanel* panelp, const LLString& name); - static LLCtrlSelectionInterface* getSelectionInterfaceByName(LLPanel* panelp, const LLString& name); - static LLCtrlScrollInterface* getScrollInterfaceByName(LLPanel* panelp, const LLString& name); + static LLCtrlListInterface* getListInterfaceByName( const LLPanel* panelp, const LLString& name); + static LLCtrlSelectionInterface* getSelectionInterfaceByName(const LLPanel* panelp, const LLString& name); + static LLCtrlScrollInterface* getScrollInterfaceByName(const LLPanel* panelp, const LLString& name); LLPanel* createFactoryPanel(LLString name); virtual LLView* createCtrlWidget(LLPanel *parent, LLXMLNodePtr node); virtual void createWidget(LLPanel *parent, LLXMLNodePtr node); + template <class T> T* createDummyWidget(const LLString& name) + { + return NULL; + //static LLPanel dummy_panel; + //LLXMLNodePtr new_node_ptr = new LLXMLNode(T::getWidgetTag(), FALSE); + //return createWidget(&dummy_panel, new_node_ptr); + } + // Creator library typedef LLView* (*creator_function_t)(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); void registerCreator(LLString ctrlname, creator_function_t function); @@ -147,10 +118,21 @@ public: protected: + template<class T> + class LLUICtrlCreator + { + public: + static void registerCreator(LLString name, LLUICtrlFactory *factory) + { + factory->registerCreator(name, T::fromXML); + } + }; + +private: - typedef std::map<LLViewHandle, LLString> built_panel_t; + typedef std::map<LLHandle<LLPanel>, LLString> built_panel_t; built_panel_t mBuiltPanels; - typedef std::map<LLViewHandle, LLString> built_floater_t; + typedef std::map<LLHandle<LLFloater>, LLString> built_floater_t; built_floater_t mBuiltFloaters; std::deque<const LLCallbackMap::map_t*> mFactoryStack; @@ -162,14 +144,5 @@ protected: static std::vector<LLString> mXUIPaths; }; -template<class T> -class LLUICtrlCreator -{ -public: - static void registerCreator(LLString name, LLUICtrlFactory *factory) - { - factory->registerCreator(name, T::fromXML); - } -}; -#endif //LL_LLWIDGETFACTORY_H +#endif //LLUICTRLFACTORY_H diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp index b0da5dd7fb..d6496b1a41 100644 --- a/indra/llui/lluistring.cpp +++ b/indra/llui/lluistring.cpp @@ -1,6 +1,6 @@ /** * @file lluistring.cpp - * @brief LLUIString base class + * @brief LLUIString implementation. * * $LicenseInfo:firstyear=2006&license=viewergpl$ * @@ -30,14 +30,11 @@ */ #include "linden_common.h" - #include "lluistring.h" const LLString::format_map_t LLUIString::sNullArgs; -// public - LLUIString::LLUIString(const LLString& instring, const LLString::format_map_t& args) : mOrig(instring), mArgs(args) @@ -98,13 +95,6 @@ void LLUIString::clear() mWResult.clear(); } -void LLUIString::clearArgs() -{ - mArgs.clear(); -} - -// private - void LLUIString::format() { mResult = mOrig; diff --git a/indra/llui/lluistring.h b/indra/llui/lluistring.h index ede8aefbca..dd787baafe 100644 --- a/indra/llui/lluistring.h +++ b/indra/llui/lluistring.h @@ -1,7 +1,7 @@ /** * @file lluistring.h * @author: Steve Bennetts - * @brief LLUIString base class + * @brief A fancy wrapper for LLString supporting argument substitutions. * * $LicenseInfo:firstyear=2006&license=viewergpl$ * @@ -33,12 +33,6 @@ #ifndef LL_LLUISTRING_H #define LL_LLUISTRING_H -// lluistring.h -// -// Copyright 2006, Linden Research, Inc. -// Original aurthor: Steve - -#include "stdtypes.h" #include "llstring.h" #include <string> @@ -89,7 +83,7 @@ public: S32 length() const { return mWResult.size(); } void clear(); - void clearArgs(); + void clearArgs() { mArgs.clear(); } // These utuilty functions are included for text editing. // They do not affect mOrig and do not perform argument substitution diff --git a/indra/llui/llundo.cpp b/indra/llui/llundo.cpp index 6fd5d08654..8104351d11 100644 --- a/indra/llui/llundo.cpp +++ b/indra/llui/llundo.cpp @@ -1,6 +1,5 @@ /** * @file llundo.cpp - * @brief LLUndo class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -29,12 +28,8 @@ * $/LicenseInfo$ */ -// Generic interface for undo/redo circular buffer - #include "linden_common.h" - #include "llundo.h" -#include "llerror.h" // TODO: @@ -82,7 +77,7 @@ LLUndoBuffer::~LLUndoBuffer() //----------------------------------------------------------------------------- // getNextAction() //----------------------------------------------------------------------------- -LLUndoAction *LLUndoBuffer::getNextAction(BOOL setClusterBegin) +LLUndoBuffer::LLUndoAction* LLUndoBuffer::getNextAction(BOOL setClusterBegin) { LLUndoAction *nextAction = mActions[mNextAction]; diff --git a/indra/llui/llundo.h b/indra/llui/llundo.h index 8b982978f5..99f0f59116 100644 --- a/indra/llui/llundo.h +++ b/indra/llui/llundo.h @@ -1,6 +1,6 @@ /** * @file llundo.h - * @brief LLUndo class header file + * @brief Generic interface for undo/redo circular buffer. * * $LicenseInfo:firstyear=2000&license=viewergpl$ * @@ -32,34 +32,24 @@ #ifndef LL_LLUNDO_H #define LL_LLUNDO_H -class LLUndoAction -{ - friend class LLUndoBuffer; -protected: - S32 mClusterID; -protected: - LLUndoAction(): mClusterID(0) {}; - virtual ~LLUndoAction(){}; - -public: - static LLUndoAction *create() { return NULL; } - - virtual void undo() = 0; - virtual void redo() = 0; - virtual void cleanup() {}; -}; class LLUndoBuffer { -protected: - LLUndoAction **mActions; // array of pointers to undoactions - S32 mNumActions; // total number of actions in ring buffer - S32 mNextAction; // next action to perform undo/redo on - S32 mLastAction; // last action actually added to undo buffer - S32 mFirstAction; // beginning of ring buffer (don't undo any further) - S32 mOperationID; // current operation id, for undoing and redoing in clusters - public: + class LLUndoAction + { + friend class LLUndoBuffer; + public: + virtual void undo() = 0; + virtual void redo() = 0; + virtual void cleanup() {}; + protected: + LLUndoAction(): mClusterID(0) {}; + virtual ~LLUndoAction(){}; + private: + S32 mClusterID; + }; + LLUndoBuffer( LLUndoAction (*create_func()), S32 initial_count ); virtual ~LLUndoBuffer(); @@ -70,6 +60,14 @@ public: BOOL canRedo() { return (mNextAction != mLastAction); } void flushActions(); + +private: + LLUndoAction **mActions; // array of pointers to undoactions + S32 mNumActions; // total number of actions in ring buffer + S32 mNextAction; // next action to perform undo/redo on + S32 mLastAction; // last action actually added to undo buffer + S32 mFirstAction; // beginning of ring buffer (don't undo any further) + S32 mOperationID; // current operation id, for undoing and redoing in clusters }; #endif //LL_LLUNDO_H diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 370288e949..1014f17898 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -61,48 +61,11 @@ BOOL LLView::sForceReshape = FALSE; LLView* LLView::sEditingUIView = NULL; S32 LLView::sLastLeftXML = S32_MIN; S32 LLView::sLastBottomXML = S32_MIN; -std::map<LLViewHandle,LLView*> LLView::sViewHandleMap; - -S32 LLViewHandle::sNextID = 0; -LLViewHandle LLViewHandle::sDeadHandle; #if LL_DEBUG BOOL LLView::sIsDrawing = FALSE; #endif -//static -LLView* LLView::getViewByHandle(LLViewHandle handle) -{ - if (handle == LLViewHandle::sDeadHandle) - { - return NULL; - } - std::map<LLViewHandle,LLView*>::iterator iter = sViewHandleMap.find(handle); - if (iter != sViewHandleMap.end()) - { - return iter->second; - } - else - { - return NULL; - } -} - -//static -BOOL LLView::deleteViewByHandle(LLViewHandle handle) -{ - std::map<LLViewHandle,LLView*>::iterator iter = sViewHandleMap.find(handle); - if (iter != sViewHandleMap.end()) - { - delete iter->second; // will remove from map - return TRUE; - } - else - { - return FALSE; - } -} - LLView::LLView() : mParentView(NULL), mReshapeFlags(FOLLOWS_NONE), @@ -115,11 +78,8 @@ LLView::LLView() : mLastVisible(TRUE), mUseBoundingRect(FALSE), mVisible(TRUE), - mHidden(FALSE), mNextInsertionOrdinal(0) { - mViewHandle.init(); - sViewHandleMap[mViewHandle] = this; } LLView::LLView(const LLString& name, BOOL mouse_opaque) : @@ -135,11 +95,8 @@ LLView::LLView(const LLString& name, BOOL mouse_opaque) : mLastVisible(TRUE), mUseBoundingRect(FALSE), mVisible(TRUE), - mHidden(FALSE), mNextInsertionOrdinal(0) { - mViewHandle.init(); - sViewHandleMap[mViewHandle] = this; } @@ -159,11 +116,8 @@ LLView::LLView( mLastVisible(TRUE), mUseBoundingRect(FALSE), mVisible(TRUE), - mHidden(FALSE), mNextInsertionOrdinal(0) { - mViewHandle.init(); - sViewHandleMap[mViewHandle] = this; } @@ -183,8 +137,6 @@ LLView::~LLView() gFocusMgr.removeMouseCaptureWithoutCallback( this ); } - sViewHandleMap.erase(mViewHandle); - deleteAllChildren(); if (mParentView != NULL) @@ -203,7 +155,7 @@ LLView::~LLView() } // virtual -BOOL LLView::isView() +BOOL LLView::isView() const { return TRUE; } @@ -215,16 +167,12 @@ BOOL LLView::isCtrl() const } // virtual -BOOL LLView::isPanel() +BOOL LLView::isPanel() const { return FALSE; } -void LLView::setMouseOpaque(BOOL b) -{ - mMouseOpaque = b; -} - +// virtual void LLView::setToolTip(const LLStringExplicit& msg) { mToolTipMsg = msg; @@ -248,52 +196,6 @@ void LLView::setRect(const LLRect& rect) updateBoundingRect(); } - -void LLView::setFollows(U32 flags) -{ - mReshapeFlags = flags; -} - -void LLView::setFollowsNone() -{ - mReshapeFlags = FOLLOWS_NONE; -} - -void LLView::setFollowsLeft() -{ - mReshapeFlags |= FOLLOWS_LEFT; -} - -void LLView::setFollowsTop() -{ - mReshapeFlags |= FOLLOWS_TOP; -} - -void LLView::setFollowsRight() -{ - mReshapeFlags |= FOLLOWS_RIGHT; -} - -void LLView::setFollowsBottom() -{ - mReshapeFlags |= FOLLOWS_BOTTOM; -} - -void LLView::setFollowsAll() -{ - mReshapeFlags |= FOLLOWS_ALL; -} - -void LLView::setSoundFlags(U8 flags) -{ - mSoundFlags = flags; -} - -void LLView::setName(LLString name) -{ - mName = name; -} - void LLView::setUseBoundingRect( BOOL use_bounding_rect ) { if (mUseBoundingRect != use_bounding_rect) @@ -308,11 +210,6 @@ BOOL LLView::getUseBoundingRect() return mUseBoundingRect; } -const LLString& LLView::getToolTip() -{ - return mToolTipMsg.getString(); -} - // virtual const LLString& LLView::getName() const { @@ -452,8 +349,6 @@ void LLView::removeCtrl(LLUICtrl* ctrl) } } -S32 LLView::getDefaultTabGroup() const { return mDefaultTabGroup; } - LLView::ctrl_list_t LLView::getCtrlList() const { ctrl_list_t controls; @@ -476,12 +371,6 @@ LLView::ctrl_list_t LLView::getCtrlListSorted() const return controls; } -LLCompareByTabOrder::LLCompareByTabOrder(LLView::child_tab_order_t order): mTabOrder(order) {} - -bool LLCompareByTabOrder::compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const -{ - return a < b; -} // This method compares two LLViews by the tab order specified in the comparator object. The // code for this is a little convoluted because each argument can have four states: @@ -537,68 +426,69 @@ BOOL LLView::isInEnabledChain() const return TRUE; } -BOOL LLView::isFocusRoot() const +// virtual +BOOL LLView::canFocusChildren() const { - return mIsFocusRoot; + return TRUE; } -LLView* LLView::findRootMostFocusRoot() +//virtual +void LLView::setTentative(BOOL b) { - LLView* focus_root = NULL; - LLView* next_view = this; - while(next_view) - { - if (next_view->isFocusRoot()) - { - focus_root = next_view; - } - next_view = next_view->getParent(); - } - return focus_root; } -BOOL LLView::canFocusChildren() const +//virtual +BOOL LLView::getTentative() const { - return TRUE; + return FALSE; } -BOOL LLView::focusNextRoot() +//virtual +void LLView::setEnabled(BOOL enabled) { - LLView::child_list_t result = LLView::getFocusRootsQuery().run(this); - return LLView::focusNext(result); + mEnabled = enabled; } -BOOL LLView::focusPrevRoot() +//virtual +BOOL LLView::setLabelArg( const LLString& key, const LLStringExplicit& text ) { - LLView::child_list_t result = LLView::getFocusRootsQuery().run(this); - return LLView::focusPrev(result); + return FALSE; } -BOOL LLView::focusNextItem(BOOL text_fields_only) +//virtual +LLRect LLView::getSnapRect() const { - // this assumes that this method is called on the focus root. - LLCtrlQuery query = LLView::getTabOrderQuery(); - if(text_fields_only || LLUI::sConfigGroup->getBOOL("TabToTextFieldsOnly")) - { - query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); - } - LLView::child_list_t result = query(this); + return mRect; +} + +//virtual +LLRect LLView::getRequiredRect() +{ + return mRect; +} + +//virtual +void LLView::onFocusLost() +{ +} + +//virtual +void LLView::onFocusReceived() +{ +} + +BOOL LLView::focusNextRoot() +{ + LLView::child_list_t result = LLView::getFocusRootsQuery().run(this); return LLView::focusNext(result); } -BOOL LLView::focusPrevItem(BOOL text_fields_only) +BOOL LLView::focusPrevRoot() { - // this assumes that this method is called on the focus root. - LLCtrlQuery query = LLView::getTabOrderQuery(); - if(text_fields_only || LLUI::sConfigGroup->getBOOL("TabToTextFieldsOnly")) - { - query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); - } - LLView::child_list_t result = query(this); + LLView::child_list_t result = LLView::getFocusRootsQuery().run(this); return LLView::focusPrev(result); } - // static BOOL LLView::focusNext(LLView::child_list_t & result) { @@ -674,80 +564,6 @@ BOOL LLView::focusPrev(LLView::child_list_t & result) return FALSE; } -BOOL LLView::focusFirstItem(BOOL prefer_text_fields) -{ - // search for text field first - if(prefer_text_fields) - { - LLCtrlQuery query = LLView::getTabOrderQuery(); - query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); - LLView::child_list_t result = query(this); - if(result.size() > 0) - { - LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front()); - if(!ctrl->hasFocus()) - { - ctrl->setFocus(TRUE); - ctrl->onTabInto(); - gFocusMgr.triggerFocusFlash(); - } - return TRUE; - } - } - // no text field found, or we don't care about text fields - LLView::child_list_t result = LLView::getTabOrderQuery().run(this); - if(result.size() > 0) - { - LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front()); - if(!ctrl->hasFocus()) - { - ctrl->setFocus(TRUE); - ctrl->onTabInto(); - gFocusMgr.triggerFocusFlash(); - } - return TRUE; - } - return FALSE; -} - -BOOL LLView::focusLastItem(BOOL prefer_text_fields) -{ - // search for text field first - if(prefer_text_fields) - { - LLCtrlQuery query = LLView::getTabOrderQuery(); - query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); - LLView::child_list_t result = query(this); - if(result.size() > 0) - { - LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back()); - if(!ctrl->hasFocus()) - { - ctrl->setFocus(TRUE); - ctrl->onTabInto(); - gFocusMgr.triggerFocusFlash(); - } - return TRUE; - } - } - // no text field found, or we don't care about text fields - LLView::child_list_t result = LLView::getTabOrderQuery().run(this); - if(result.size() > 0) - { - LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back()); - if(!ctrl->hasFocus()) - { - ctrl->setFocus(TRUE); - ctrl->onTabInto(); - gFocusMgr.triggerFocusFlash(); - } - return TRUE; - } - return FALSE; -} - - - // delete all children. Override this function if you need to // perform any extra clean up such as cached pointers to selected // children, etc. @@ -773,23 +589,6 @@ void LLView::setAllChildrenEnabled(BOOL b) } // virtual -void LLView::setTentative(BOOL b) -{ -} - -// virtual -BOOL LLView::getTentative() const -{ - return FALSE; -} - -// virtual -void LLView::setEnabled(BOOL enabled) -{ - mEnabled = enabled; -} - -// virtual void LLView::setVisible(BOOL visible) { if ( mVisible != visible ) @@ -812,18 +611,6 @@ void LLView::setVisible(BOOL visible) } // virtual -void LLView::setHidden(BOOL hidden) -{ - mHidden = hidden; -} - -// virtual -BOOL LLView::setLabelArg(const LLString& key, const LLStringExplicit& text) -{ - return FALSE; -} - -// virtual void LLView::onVisibilityChange ( BOOL new_visibility ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) @@ -845,9 +632,9 @@ void LLView::translate(S32 x, S32 y) } // virtual -BOOL LLView::canSnapTo(LLView* other_view) +BOOL LLView::canSnapTo(const LLView* other_view) const { - return other_view->getVisible(); + return other_view != this && other_view->getVisible(); } // virtual @@ -956,7 +743,7 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent) if( called_from_parent ) { // Downward traversal - if (getVisible() && mEnabled) + if (getVisible() && getEnabled()) { handled = childrenHandleKey( key, mask ) != NULL; } @@ -1003,7 +790,7 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) if( called_from_parent ) { // Downward traversal - if (getVisible() && mEnabled) + if (getVisible() && getEnabled()) { handled = childrenHandleUnicodeChar( uni_char ) != NULL; } @@ -1074,16 +861,16 @@ LLView* LLView::childrenHandleDragAndDrop(S32 x, S32 y, MASK mask, LLView* handled_view = FALSE; // CRO this is an experiment to allow drag and drop into object inventory based on the DragAndDrop tool's permissions rather than the parent if( getVisible() ) -// if( getVisible() && mEnabled ) +// if( getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if( viewp->pointInView(local_x, local_y) && viewp->getVisible() && - viewp->mEnabled && + viewp->getEnabled() && viewp->handleDragAndDrop(local_x, local_y, mask, drop, cargo_type, cargo_data, @@ -1158,7 +945,7 @@ BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask) BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks) { BOOL handled = FALSE; - if( getVisible() && mEnabled ) + if( getVisible() && getEnabled() ) { handled = childrenHandleScrollWheel( x, y, clicks ) != NULL; if( !handled && blockMouseEvent(x, y) ) @@ -1192,13 +979,13 @@ BOOL LLView::handleRightMouseUp(S32 x, S32 y, MASK mask) LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) { LLView* handled_view = NULL; - if (getVisible() && mEnabled ) + if (getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if (viewp->pointInView(local_x, local_y) && viewp->handleScrollWheel( local_x, local_y, clicks )) { @@ -1218,13 +1005,13 @@ LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask) { LLView* handled_view = NULL; - if (getVisible() && mEnabled ) + if (getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if(viewp->pointInView(local_x, local_y) && viewp->getVisible() && viewp->getEnabled() && @@ -1248,7 +1035,7 @@ LLView* LLView::childrenHandleKey(KEY key, MASK mask) { LLView* handled_view = NULL; - if ( getVisible() && mEnabled ) + if ( getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { @@ -1273,7 +1060,7 @@ LLView* LLView::childrenHandleUnicodeChar(llwchar uni_char) { LLView* handled_view = NULL; - if ( getVisible() && mEnabled ) + if ( getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { @@ -1300,12 +1087,12 @@ LLView* LLView::childrenHandleMouseDown(S32 x, S32 y, MASK mask) for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if (viewp->pointInView(local_x, local_y) && viewp->getVisible() && - viewp->mEnabled && + viewp->getEnabled() && viewp->handleMouseDown( local_x, local_y, mask )) { if (sDebugMouseHandling) @@ -1323,16 +1110,16 @@ LLView* LLView::childrenHandleRightMouseDown(S32 x, S32 y, MASK mask) { LLView* handled_view = NULL; - if (getVisible() && mEnabled ) + if (getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if (viewp->pointInView(local_x, local_y) && viewp->getVisible() && - viewp->mEnabled && + viewp->getEnabled() && viewp->handleRightMouseDown( local_x, local_y, mask )) { if (sDebugMouseHandling) @@ -1351,16 +1138,16 @@ LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask) { LLView* handled_view = NULL; - if (getVisible() && mEnabled ) + if (getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if (viewp->pointInView(local_x, local_y) && viewp->getVisible() && - viewp->mEnabled && + viewp->getEnabled() && viewp->handleDoubleClick( local_x, local_y, mask )) { if (sDebugMouseHandling) @@ -1378,18 +1165,18 @@ LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask) LLView* LLView::childrenHandleMouseUp(S32 x, S32 y, MASK mask) { LLView* handled_view = NULL; - if( getVisible() && mEnabled ) + if( getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if (!viewp->pointInView(local_x, local_y)) continue; if (!viewp->getVisible()) continue; - if (!viewp->mEnabled) + if (!viewp->getEnabled()) continue; if (viewp->handleMouseUp( local_x, local_y, mask )) { @@ -1408,16 +1195,16 @@ LLView* LLView::childrenHandleMouseUp(S32 x, S32 y, MASK mask) LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask) { LLView* handled_view = NULL; - if( getVisible() && mEnabled ) + if( getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if (viewp->pointInView(local_x, local_y) && viewp->getVisible() && - viewp->mEnabled && + viewp->getEnabled() && viewp->handleRightMouseUp( local_x, local_y, mask )) { if (sDebugMouseHandling) @@ -1440,8 +1227,8 @@ void LLView::draw() drawDebugRect(); // Check for bogus rectangle - if (mRect.mRight <= mRect.mLeft - || mRect.mTop <= mRect.mBottom) + if (getRect().mRight <= getRect().mLeft + || getRect().mTop <= getRect().mBottom) { llwarns << "Bogus rectangle for " << getName() << " with " << mRect << llendl; } @@ -1578,14 +1365,14 @@ void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_dr void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) { // compute how much things changed and apply reshape logic to children - S32 delta_width = width - mRect.getWidth(); - S32 delta_height = height - mRect.getHeight(); + S32 delta_width = width - getRect().getWidth(); + S32 delta_height = height - getRect().getHeight(); if (delta_width || delta_height || sForceReshape) { // adjust our rectangle - mRect.mRight = mRect.mLeft + width; - mRect.mTop = mRect.mBottom + height; + mRect.mRight = getRect().mLeft + width; + mRect.mTop = getRect().mBottom + height; // move child views according to reshape flags for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) @@ -1631,8 +1418,8 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) // for now, same as bottom } - S32 delta_x = child_rect.mLeft - viewp->mRect.mLeft; - S32 delta_y = child_rect.mBottom - viewp->mRect.mBottom; + S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft; + S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom; viewp->translate( delta_x, delta_y ); viewp->reshape(child_rect.getWidth(), child_rect.getHeight()); } @@ -1649,11 +1436,6 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) updateBoundingRect(); } -LLRect LLView::getRequiredRect() -{ - return mRect; -} - void LLView::updateBoundingRect() { if (isDead()) return; @@ -1701,16 +1483,16 @@ void LLView::updateBoundingRect() } } -const LLRect LLView::getScreenRect() const +LLRect LLView::getScreenRect() const { // *FIX: check for one-off error LLRect screen_rect; localPointToScreen(0, 0, &screen_rect.mLeft, &screen_rect.mBottom); - localPointToScreen(mRect.getWidth(), mRect.getHeight(), &screen_rect.mRight, &screen_rect.mTop); + localPointToScreen(getRect().getWidth(), getRect().getHeight(), &screen_rect.mRight, &screen_rect.mTop); return screen_rect; } -const LLRect LLView::getLocalBoundingRect() const +LLRect LLView::getLocalBoundingRect() const { LLRect local_bounding_rect = getBoundingRect(); local_bounding_rect.translate(-mRect.mLeft, -mRect.mBottom); @@ -1719,20 +1501,20 @@ const LLRect LLView::getLocalBoundingRect() const } -const LLRect LLView::getLocalRect() const +LLRect LLView::getLocalRect() const { - LLRect local_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect local_rect(0, getRect().getHeight(), getRect().getWidth(), 0); return local_rect; } -const LLRect LLView::getLocalSnapRect() const +LLRect LLView::getLocalSnapRect() const { LLRect local_snap_rect = getSnapRect(); - local_snap_rect.translate(-mRect.mLeft, -mRect.mBottom); + local_snap_rect.translate(-getRect().mLeft, -getRect().mBottom); return local_snap_rect; } -BOOL LLView::hasAncestor(const LLView* parentp) +BOOL LLView::hasAncestor(const LLView* parentp) const { if (!parentp) { @@ -1771,7 +1553,7 @@ BOOL LLView::childHasKeyboardFocus( const LLString& childname ) const BOOL LLView::hasChild(const LLString& childname, BOOL recurse) const { - return getChildByName(childname, recurse) ? TRUE : FALSE; + return getChildByName(childname, recurse) != NULL; } //----------------------------------------------------------------------------- @@ -1829,55 +1611,55 @@ BOOL LLView::blockMouseEvent(S32 x, S32 y) const // virtual void LLView::screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const { - *local_x = screen_x - mRect.mLeft; - *local_y = screen_y - mRect.mBottom; + *local_x = screen_x - getRect().mLeft; + *local_y = screen_y - getRect().mBottom; const LLView* cur = this; while( cur->mParentView ) { cur = cur->mParentView; - *local_x -= cur->mRect.mLeft; - *local_y -= cur->mRect.mBottom; + *local_x -= cur->getRect().mLeft; + *local_y -= cur->getRect().mBottom; } } void LLView::localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const { - *screen_x = local_x + mRect.mLeft; - *screen_y = local_y + mRect.mBottom; + *screen_x = local_x + getRect().mLeft; + *screen_y = local_y + getRect().mBottom; const LLView* cur = this; while( cur->mParentView ) { cur = cur->mParentView; - *screen_x += cur->mRect.mLeft; - *screen_y += cur->mRect.mBottom; + *screen_x += cur->getRect().mLeft; + *screen_y += cur->getRect().mBottom; } } void LLView::screenRectToLocal(const LLRect& screen, LLRect* local) const { *local = screen; - local->translate( -mRect.mLeft, -mRect.mBottom ); + local->translate( -getRect().mLeft, -getRect().mBottom ); const LLView* cur = this; while( cur->mParentView ) { cur = cur->mParentView; - local->translate( -cur->mRect.mLeft, -cur->mRect.mBottom ); + local->translate( -cur->getRect().mLeft, -cur->getRect().mBottom ); } } void LLView::localRectToScreen(const LLRect& local, LLRect* screen) const { *screen = local; - screen->translate( mRect.mLeft, mRect.mBottom ); + screen->translate( getRect().mLeft, getRect().mBottom ); const LLView* cur = this; while( cur->mParentView ) { cur = cur->mParentView; - screen->translate( cur->mRect.mLeft, cur->mRect.mBottom ); + screen->translate( cur->getRect().mLeft, cur->getRect().mBottom ); } } @@ -1891,12 +1673,15 @@ LLView* LLView::getRootView() return view; } -//static -LLWindow* LLView::getWindow(void) +BOOL LLView::deleteViewByHandle(LLHandle<LLView> handle) { - return LLUI::sWindow; + LLView* viewp = handle.get(); + + delete viewp; + return viewp != NULL; } + // Moves the view so that it is entirely inside of constraint. // If the view will not fit because it's too big, aligns with the top and left. // (Why top and left? That's where the drag bars are for floaters.) @@ -1909,50 +1694,50 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs { const S32 KEEP_ONSCREEN_PIXELS = 16; - if( mRect.mRight - KEEP_ONSCREEN_PIXELS < constraint.mLeft ) + if( getRect().mRight - KEEP_ONSCREEN_PIXELS < constraint.mLeft ) { - delta_x = constraint.mLeft - (mRect.mRight - KEEP_ONSCREEN_PIXELS); + delta_x = constraint.mLeft - (getRect().mRight - KEEP_ONSCREEN_PIXELS); } else - if( mRect.mLeft + KEEP_ONSCREEN_PIXELS > constraint.mRight ) + if( getRect().mLeft + KEEP_ONSCREEN_PIXELS > constraint.mRight ) { - delta_x = constraint.mRight - (mRect.mLeft + KEEP_ONSCREEN_PIXELS); - delta_x += llmax( 0, mRect.getWidth() - constraint.getWidth() ); + delta_x = constraint.mRight - (getRect().mLeft + KEEP_ONSCREEN_PIXELS); + delta_x += llmax( 0, getRect().getWidth() - constraint.getWidth() ); } - if( mRect.mTop > constraint.mTop ) + if( getRect().mTop > constraint.mTop ) { - delta_y = constraint.mTop - mRect.mTop; + delta_y = constraint.mTop - getRect().mTop; } else - if( mRect.mTop - KEEP_ONSCREEN_PIXELS < constraint.mBottom ) + if( getRect().mTop - KEEP_ONSCREEN_PIXELS < constraint.mBottom ) { - delta_y = constraint.mBottom - (mRect.mTop - KEEP_ONSCREEN_PIXELS); - delta_y -= llmax( 0, mRect.getHeight() - constraint.getHeight() ); + delta_y = constraint.mBottom - (getRect().mTop - KEEP_ONSCREEN_PIXELS); + delta_y -= llmax( 0, getRect().getHeight() - constraint.getHeight() ); } } else { - if( mRect.mLeft < constraint.mLeft ) + if( getRect().mLeft < constraint.mLeft ) { - delta_x = constraint.mLeft - mRect.mLeft; + delta_x = constraint.mLeft - getRect().mLeft; } else - if( mRect.mRight > constraint.mRight ) + if( getRect().mRight > constraint.mRight ) { - delta_x = constraint.mRight - mRect.mRight; - delta_x += llmax( 0, mRect.getWidth() - constraint.getWidth() ); + delta_x = constraint.mRight - getRect().mRight; + delta_x += llmax( 0, getRect().getWidth() - constraint.getWidth() ); } - if( mRect.mTop > constraint.mTop ) + if( getRect().mTop > constraint.mTop ) { - delta_y = constraint.mTop - mRect.mTop; + delta_y = constraint.mTop - getRect().mTop; } else - if( mRect.mBottom < constraint.mBottom ) + if( getRect().mBottom < constraint.mBottom ) { - delta_y = constraint.mBottom - mRect.mBottom; - delta_y -= llmax( 0, mRect.getHeight() - constraint.getHeight() ); + delta_y = constraint.mBottom - getRect().mBottom; + delta_y -= llmax( 0, getRect().getHeight() - constraint.getHeight() ); } } @@ -1964,10 +1749,18 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs return FALSE; } -BOOL LLView::localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view) +void LLView::centerWithin(const LLRect& bounds) { - LLView* cur_view = this; - LLView* root_view = NULL; + S32 left = bounds.mLeft + (bounds.getWidth() - getRect().getWidth()) / 2; + S32 bottom = bounds.mBottom + (bounds.getHeight() - getRect().getHeight()) / 2; + + translate( left - getRect().mLeft, bottom - getRect().mBottom ); +} + +BOOL LLView::localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view) const +{ + const LLView* cur_view = this; + const LLView* root_view = NULL; while (cur_view) { @@ -2058,8 +1851,8 @@ LLXMLNodePtr LLView::getXML(bool save_children) const node->createChild("height", TRUE)->setIntValue(getRect().getHeight()); LLView* parent = getParent(); - S32 left = mRect.mLeft; - S32 bottom = mRect.mBottom; + S32 left = getRect().mLeft; + S32 bottom = getRect().mBottom; if (parent) bottom -= parent->getRect().getHeight(); node->createChild("left", TRUE)->setIntValue(left); @@ -2095,7 +1888,6 @@ LLXMLNodePtr LLView::getXML(bool save_children) const node->createChild("follows", TRUE)->setStringValue(buffer.str()); } // Export all widgets as enabled and visible - code must disable. - node->createChild("hidden", TRUE)->setBoolValue(mHidden); node->createChild("mouse_opaque", TRUE)->setBoolValue(mMouseOpaque ); if (!mToolTipMsg.getString().empty()) { @@ -2106,7 +1898,7 @@ LLXMLNodePtr LLView::getXML(bool save_children) const node->createChild("sound_flags", TRUE)->setIntValue((S32)mSoundFlags); } - node->createChild("enabled", TRUE)->setBoolValue(mEnabled); + node->createChild("enabled", TRUE)->setBoolValue(getEnabled()); if (!mControlName.empty()) { @@ -2194,6 +1986,15 @@ const LLCtrlQuery & LLView::getTabOrderQuery() return query; } +// This class is only used internally by getFocusRootsQuery below. +class LLFocusRootsFilter : public LLQueryFilter, public LLSingleton<LLFocusRootsFilter> +{ + /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const + { + return filterResult_t(view->isCtrl() && view->isFocusRoot(), !view->isFocusRoot()); + } +}; + // static const LLCtrlQuery & LLView::getFocusRootsQuery() { @@ -2201,7 +2002,7 @@ const LLCtrlQuery & LLView::getFocusRootsQuery() if(query.getPreFilters().size() == 0) { query.addPreFilter(LLVisibleFilter::getInstance()); query.addPreFilter(LLEnabledFilter::getInstance()); - query.addPreFilter(LLView::LLFocusRootsFilter::getInstance()); + query.addPreFilter(LLFocusRootsFilter::getInstance()); query.addPostFilter(LLRootsFilter::getInstance()); } return query; @@ -2211,167 +2012,189 @@ const LLCtrlQuery & LLView::getFocusRootsQuery() void LLView::userSetShape(const LLRect& new_rect) { reshape(new_rect.getWidth(), new_rect.getHeight()); - translate(new_rect.mLeft - mRect.mLeft, new_rect.mBottom - mRect.mBottom); + translate(new_rect.mLeft - getRect().mLeft, new_rect.mBottom - getRect().mBottom); } LLView* LLView::findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding) { + new_rect = mRect; LLView* snap_view = NULL; if (!mParentView) { - new_rect = mRect; - return snap_view; + return NULL; } - - // If the view is near the edge of its parent, snap it to - // the edge. - LLRect test_rect = getSnapRect(); - LLRect view_rect = getSnapRect(); - test_rect.stretch(padding); - view_rect.stretch(padding); - - BOOL snapped_x = FALSE; - BOOL snapped_y = FALSE; - - LLRect parent_local_snap_rect = mParentView->getLocalSnapRect(); - - if (snap_type == SNAP_PARENT || snap_type == SNAP_PARENT_AND_SIBLINGS) + + S32 delta_x = 0; + S32 delta_y = 0; + if (mouse_dir.mX >= 0) { - if (llabs(parent_local_snap_rect.mRight - test_rect.mRight) <= threshold && (parent_local_snap_rect.mRight - test_rect.mRight) * mouse_dir.mX >= 0) - { - view_rect.translate(parent_local_snap_rect.mRight - view_rect.mRight, 0); - snap_view = mParentView; - snapped_x = TRUE; - } - - if (llabs(test_rect.mLeft - parent_local_snap_rect.mLeft) <= threshold && test_rect.mLeft * mouse_dir.mX <= 0) - { - view_rect.translate(parent_local_snap_rect.mLeft - view_rect.mLeft, 0); - snap_view = mParentView; - snapped_x = TRUE; - } - - if (llabs(test_rect.mBottom - parent_local_snap_rect.mBottom) <= threshold && test_rect.mBottom * mouse_dir.mY <= 0) - { - view_rect.translate(0, parent_local_snap_rect.mBottom - view_rect.mBottom); - snap_view = mParentView; - snapped_y = TRUE; - } - - if (llabs(parent_local_snap_rect.mTop - test_rect.mTop) <= threshold && (parent_local_snap_rect.mTop - test_rect.mTop) * mouse_dir.mY >= 0) - { - view_rect.translate(0, parent_local_snap_rect.mTop - view_rect.mTop); - snap_view = mParentView; - snapped_y = TRUE; - } + S32 new_right = mRect.mRight; + LLView* view = findSnapEdge(new_right, mouse_dir, SNAP_RIGHT, snap_type, threshold, padding); + delta_x = new_right - mRect.mRight; + snap_view = view ? view : snap_view; } - if (snap_type == SNAP_SIBLINGS || snap_type == SNAP_PARENT_AND_SIBLINGS) - { - for ( child_list_const_iter_t child_it = mParentView->getChildList()->begin(); - child_it != mParentView->getChildList()->end(); ++child_it) - { - LLView* siblingp = *child_it; - // skip self - if (siblingp == this || !siblingp->getVisible() || !canSnapTo(siblingp)) - { - continue; - } - - LLRect sibling_rect = siblingp->getSnapRect(); - - if (!snapped_x && llabs(test_rect.mRight - sibling_rect.mLeft) <= threshold && (test_rect.mRight - sibling_rect.mLeft) * mouse_dir.mX <= 0) - { - view_rect.translate(sibling_rect.mLeft - view_rect.mRight, 0); - if (!snapped_y) - { - if (llabs(test_rect.mTop - sibling_rect.mTop) <= threshold && (test_rect.mTop - sibling_rect.mTop) * mouse_dir.mY <= 0) - { - view_rect.translate(0, sibling_rect.mTop - test_rect.mTop); - snapped_y = TRUE; - } - else if (llabs(test_rect.mBottom - sibling_rect.mBottom) <= threshold && (test_rect.mBottom - sibling_rect.mBottom) * mouse_dir.mY <= 0) - { - view_rect.translate(0, sibling_rect.mBottom - test_rect.mBottom); - snapped_y = TRUE; - } - } - snap_view = siblingp; - snapped_x = TRUE; - } - if (!snapped_x && llabs(test_rect.mLeft - sibling_rect.mRight) <= threshold && (test_rect.mLeft - sibling_rect.mRight) * mouse_dir.mX <= 0) - { - view_rect.translate(sibling_rect.mRight - view_rect.mLeft, 0); - if (!snapped_y) - { - if (llabs(test_rect.mTop - sibling_rect.mTop) <= threshold && (test_rect.mTop - sibling_rect.mTop) * mouse_dir.mY <= 0) - { - view_rect.translate(0, sibling_rect.mTop - test_rect.mTop); - snapped_y = TRUE; - } - else if (llabs(test_rect.mBottom - sibling_rect.mBottom) <= threshold && (test_rect.mBottom - sibling_rect.mBottom) * mouse_dir.mY <= 0) - { - view_rect.translate(0, sibling_rect.mBottom - test_rect.mBottom); - snapped_y = TRUE; - } - } - snap_view = siblingp; - snapped_x = TRUE; - } + if (mouse_dir.mX <= 0) + { + S32 new_left = mRect.mLeft; + LLView* view = findSnapEdge(new_left, mouse_dir, SNAP_LEFT, snap_type, threshold, padding); + delta_x = new_left - mRect.mLeft; + snap_view = view ? view : snap_view; + } - if (!snapped_y && llabs(test_rect.mBottom - sibling_rect.mTop) <= threshold && (test_rect.mBottom - sibling_rect.mTop) * mouse_dir.mY <= 0) - { - view_rect.translate(0, sibling_rect.mTop - view_rect.mBottom); - if (!snapped_x) - { - if (llabs(test_rect.mLeft - sibling_rect.mLeft) <= threshold && (test_rect.mLeft - sibling_rect.mLeft) * mouse_dir.mX <= 0) - { - view_rect.translate(sibling_rect.mLeft - test_rect.mLeft, 0); - snapped_x = TRUE; - } - else if (llabs(test_rect.mRight - sibling_rect.mRight) <= threshold && (test_rect.mRight - sibling_rect.mRight) * mouse_dir.mX <= 0) - { - view_rect.translate(sibling_rect.mRight - test_rect.mRight, 0); - snapped_x = TRUE; - } - } - snap_view = siblingp; - snapped_y = TRUE; - } + if (mouse_dir.mY >= 0) + { + S32 new_top = mRect.mTop; + LLView* view = findSnapEdge(new_top, mouse_dir, SNAP_TOP, snap_type, threshold, padding); + delta_y = new_top - mRect.mTop; + snap_view = view ? view : snap_view; + } - if (!snapped_y && llabs(test_rect.mTop - sibling_rect.mBottom) <= threshold && (test_rect.mTop - sibling_rect.mBottom) * mouse_dir.mY <= 0) - { - view_rect.translate(0, sibling_rect.mBottom - view_rect.mTop); - if (!snapped_x) - { - if (llabs(test_rect.mLeft - sibling_rect.mLeft) <= threshold && (test_rect.mLeft - sibling_rect.mLeft) * mouse_dir.mX <= 0) - { - view_rect.translate(sibling_rect.mLeft - test_rect.mLeft, 0); - snapped_x = TRUE; - } - else if (llabs(test_rect.mRight - sibling_rect.mRight) <= threshold && (test_rect.mRight - sibling_rect.mRight) * mouse_dir.mX <= 0) - { - view_rect.translate(sibling_rect.mRight - test_rect.mRight, 0); - snapped_x = TRUE; - } - } - snap_view = siblingp; - snapped_y = TRUE; - } - - if (snapped_x && snapped_y) - { - break; - } - } + if (mouse_dir.mY <= 0) + { + S32 new_bottom = mRect.mBottom; + LLView* view = findSnapEdge(new_bottom, mouse_dir, SNAP_BOTTOM, snap_type, threshold, padding); + delta_y = new_bottom - mRect.mBottom; + snap_view = view ? view : snap_view; } - // shrink actual view rect back down - view_rect.stretch(-padding); - new_rect = view_rect; + new_rect.translate(delta_x, delta_y); return snap_view; + + //// If the view is near the edge of its parent, snap it to + //// the edge. + //LLRect test_rect = getSnapRect(); + //LLRect view_rect = getSnapRect(); + //test_rect.stretch(padding); + //view_rect.stretch(padding); + + //S32 x_threshold = threshold; + //S32 y_threshold = threshold; + + //LLRect parent_local_snap_rect = mParentView->getLocalSnapRect(); + + //if (snap_type == SNAP_PARENT || snap_type == SNAP_PARENT_AND_SIBLINGS) + //{ + // if (llabs(parent_local_snap_rect.mRight - test_rect.mRight) <= x_threshold && (parent_local_snap_rect.mRight - test_rect.mRight) * mouse_dir.mX >= 0) + // { + // view_rect.translate(parent_local_snap_rect.mRight - view_rect.mRight, 0); + // snap_view = mParentView; + // x_threshold = llabs(parent_local_snap_rect.mRight - test_rect.mRight); + // } + + // if (llabs(test_rect.mLeft - parent_local_snap_rect.mLeft) <= x_threshold && test_rect.mLeft * mouse_dir.mX <= 0) + // { + // view_rect.translate(parent_local_snap_rect.mLeft - view_rect.mLeft, 0); + // snap_view = mParentView; + // x_threshold = llabs(test_rect.mLeft - parent_local_snap_rect.mLeft); + // } + + // if (llabs(test_rect.mBottom - parent_local_snap_rect.mBottom) <= y_threshold && test_rect.mBottom * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, parent_local_snap_rect.mBottom - view_rect.mBottom); + // snap_view = mParentView; + // y_threshold = llabs(test_rect.mBottom - parent_local_snap_rect.mBottom); + // } + + // if (llabs(parent_local_snap_rect.mTop - test_rect.mTop) <= y_threshold && (parent_local_snap_rect.mTop - test_rect.mTop) * mouse_dir.mY >= 0) + // { + // view_rect.translate(0, parent_local_snap_rect.mTop - view_rect.mTop); + // snap_view = mParentView; + // y_threshold = llabs(parent_local_snap_rect.mTop - test_rect.mTop); + // } + //} + //if (snap_type == SNAP_SIBLINGS || snap_type == SNAP_PARENT_AND_SIBLINGS) + //{ + // for ( child_list_const_iter_t child_it = mParentView->getChildList()->begin(); + // child_it != mParentView->getChildList()->end(); ++child_it) + // { + // LLView* siblingp = *child_it; + + // // skip non-snappable views (self, invisible views, etc) + // if (!canSnapTo(siblingp)) continue; + + // LLRect sibling_rect = siblingp->getSnapRect(); + + // if (llabs(test_rect.mRight - sibling_rect.mLeft) <= x_threshold + // && (test_rect.mRight - sibling_rect.mLeft) * mouse_dir.mX <= 0) + // { + // view_rect.translate(sibling_rect.mLeft - view_rect.mRight, 0); + // if (llabs(test_rect.mTop - sibling_rect.mTop) <= y_threshold && (test_rect.mTop - sibling_rect.mTop) * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, sibling_rect.mTop - test_rect.mTop); + // y_threshold = llabs(test_rect.mTop - sibling_rect.mTop); + // } + // else if (llabs(test_rect.mBottom - sibling_rect.mBottom) <= y_threshold && (test_rect.mBottom - sibling_rect.mBottom) * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, sibling_rect.mBottom - test_rect.mBottom); + // y_threshold = llabs(test_rect.mBottom - sibling_rect.mBottom); + // } + // snap_view = siblingp; + // x_threshold = llabs(test_rect.mRight - sibling_rect.mLeft); + // } + + // if (llabs(test_rect.mLeft - sibling_rect.mRight) <= x_threshold + // && (test_rect.mLeft - sibling_rect.mRight) * mouse_dir.mX <= 0) + // { + // view_rect.translate(sibling_rect.mRight - view_rect.mLeft, 0); + // if (llabs(test_rect.mTop - sibling_rect.mTop) <= y_threshold && (test_rect.mTop - sibling_rect.mTop) * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, sibling_rect.mTop - test_rect.mTop); + // y_threshold = llabs(test_rect.mTop - sibling_rect.mTop); + // } + // else if (llabs(test_rect.mBottom - sibling_rect.mBottom) <= y_threshold && (test_rect.mBottom - sibling_rect.mBottom) * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, sibling_rect.mBottom - test_rect.mBottom); + // y_threshold = llabs(test_rect.mBottom - sibling_rect.mBottom); + // } + // snap_view = siblingp; + // x_threshold = llabs(test_rect.mLeft - sibling_rect.mRight); + // } + + // if (llabs(test_rect.mBottom - sibling_rect.mTop) <= y_threshold + // && (test_rect.mBottom - sibling_rect.mTop) * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, sibling_rect.mTop - view_rect.mBottom); + // if (llabs(test_rect.mLeft - sibling_rect.mLeft) <= x_threshold && (test_rect.mLeft - sibling_rect.mLeft) * mouse_dir.mX <= 0) + // { + // view_rect.translate(sibling_rect.mLeft - test_rect.mLeft, 0); + // x_threshold = llabs(test_rect.mLeft - sibling_rect.mLeft); + // } + // else if (llabs(test_rect.mRight - sibling_rect.mRight) <= x_threshold && (test_rect.mRight - sibling_rect.mRight) * mouse_dir.mX <= 0) + // { + // view_rect.translate(sibling_rect.mRight - test_rect.mRight, 0); + // x_threshold = llabs(test_rect.mRight - sibling_rect.mRight); + // } + // snap_view = siblingp; + // y_threshold = llabs(test_rect.mBottom - sibling_rect.mTop); + // } + + // if (llabs(test_rect.mTop - sibling_rect.mBottom) <= y_threshold + // && (test_rect.mTop - sibling_rect.mBottom) * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, sibling_rect.mBottom - view_rect.mTop); + // if (llabs(test_rect.mLeft - sibling_rect.mLeft) <= x_threshold && (test_rect.mLeft - sibling_rect.mLeft) * mouse_dir.mX <= 0) + // { + // view_rect.translate(sibling_rect.mLeft - test_rect.mLeft, 0); + // x_threshold = llabs(test_rect.mLeft - sibling_rect.mLeft); + // } + // else if (llabs(test_rect.mRight - sibling_rect.mRight) <= x_threshold && (test_rect.mRight - sibling_rect.mRight) * mouse_dir.mX <= 0) + // { + // view_rect.translate(sibling_rect.mRight - test_rect.mRight, 0); + // x_threshold = llabs(test_rect.mRight - sibling_rect.mRight); + // } + // snap_view = siblingp; + // y_threshold = llabs(test_rect.mTop - sibling_rect.mBottom); + // } + // } + //} + + //// shrink actual view rect back down + //view_rect.stretch(-padding); + //new_rect = view_rect; + //return snap_view; } LLView* LLView::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding) @@ -2407,8 +2230,8 @@ LLView* LLView::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESna LLRect test_rect = snap_rect; test_rect.stretch(padding); - BOOL snapped_x = FALSE; - BOOL snapped_y = FALSE; + S32 x_threshold = threshold; + S32 y_threshold = threshold; LLRect parent_local_snap_rect = mParentView->getLocalSnapRect(); @@ -2417,35 +2240,38 @@ LLView* LLView::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESna switch(snap_edge) { case SNAP_RIGHT: - if (llabs(parent_local_snap_rect.mRight - test_rect.mRight) <= threshold && (parent_local_snap_rect.mRight - test_rect.mRight) * mouse_dir.mX >= 0) + if (llabs(parent_local_snap_rect.mRight - test_rect.mRight) <= x_threshold + && (parent_local_snap_rect.mRight - test_rect.mRight) * mouse_dir.mX >= 0) { snap_pos = parent_local_snap_rect.mRight - padding; snap_view = mParentView; - snapped_x = TRUE; + x_threshold = llabs(parent_local_snap_rect.mRight - test_rect.mRight); } break; case SNAP_LEFT: - if (llabs(test_rect.mLeft - parent_local_snap_rect.mLeft) <= threshold && test_rect.mLeft * mouse_dir.mX <= 0) + if (llabs(test_rect.mLeft - parent_local_snap_rect.mLeft) <= x_threshold + && test_rect.mLeft * mouse_dir.mX <= 0) { snap_pos = parent_local_snap_rect.mLeft + padding; snap_view = mParentView; - snapped_x = TRUE; + x_threshold = llabs(test_rect.mLeft - parent_local_snap_rect.mLeft); } break; case SNAP_BOTTOM: - if (llabs(test_rect.mBottom - parent_local_snap_rect.mBottom) <= threshold && test_rect.mBottom * mouse_dir.mY <= 0) + if (llabs(test_rect.mBottom - parent_local_snap_rect.mBottom) <= y_threshold + && test_rect.mBottom * mouse_dir.mY <= 0) { snap_pos = parent_local_snap_rect.mBottom + padding; snap_view = mParentView; - snapped_y = TRUE; + y_threshold = llabs(test_rect.mBottom - parent_local_snap_rect.mBottom); } break; case SNAP_TOP: - if (llabs(parent_local_snap_rect.mTop - test_rect.mTop) <= threshold && (parent_local_snap_rect.mTop - test_rect.mTop) * mouse_dir.mY >= 0) + if (llabs(parent_local_snap_rect.mTop - test_rect.mTop) <= y_threshold && (parent_local_snap_rect.mTop - test_rect.mTop) * mouse_dir.mY >= 0) { snap_pos = parent_local_snap_rect.mTop - padding; snap_view = mParentView; - snapped_y = TRUE; + y_threshold = llabs(parent_local_snap_rect.mTop - test_rect.mTop); } break; default: @@ -2459,111 +2285,100 @@ LLView* LLView::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESna child_it != mParentView->getChildList()->end(); ++child_it) { LLView* siblingp = *child_it; - // skip self - if (siblingp == this || !siblingp->getVisible() || !canSnapTo(siblingp)) - { - continue; - } + + if (!canSnapTo(siblingp)) continue; LLRect sibling_rect = siblingp->getSnapRect(); switch(snap_edge) { case SNAP_RIGHT: - if (!snapped_x) + if (llabs(test_rect.mRight - sibling_rect.mLeft) <= x_threshold + && (test_rect.mRight - sibling_rect.mLeft) * mouse_dir.mX <= 0) { - if (llabs(test_rect.mRight - sibling_rect.mLeft) <= threshold && (test_rect.mRight - sibling_rect.mLeft) * mouse_dir.mX <= 0) + snap_pos = sibling_rect.mLeft - padding; + snap_view = siblingp; + x_threshold = llabs(test_rect.mRight - sibling_rect.mLeft); + } + // if snapped with sibling along other axis, check for shared edge + else if (llabs(sibling_rect.mTop - (test_rect.mBottom - padding)) <= y_threshold + || llabs(sibling_rect.mBottom - (test_rect.mTop + padding)) <= x_threshold) + { + if (llabs(test_rect.mRight - sibling_rect.mRight) <= x_threshold + && (test_rect.mRight - sibling_rect.mRight) * mouse_dir.mX <= 0) { - snap_pos = sibling_rect.mLeft - padding; + snap_pos = sibling_rect.mRight; snap_view = siblingp; - snapped_x = TRUE; - } - // if snapped with sibling along other axis, check for shared edge - else if (llabs(sibling_rect.mTop - (test_rect.mBottom - padding)) <= threshold || - llabs(sibling_rect.mBottom - (test_rect.mTop + padding)) <= threshold) - { - if (llabs(test_rect.mRight - sibling_rect.mRight) <= threshold && (test_rect.mRight - sibling_rect.mRight) * mouse_dir.mX <= 0) - { - snap_pos = sibling_rect.mRight; - snap_view = siblingp; - snapped_x = TRUE; - } + x_threshold = llabs(test_rect.mRight - sibling_rect.mRight); } } break; case SNAP_LEFT: - if (!snapped_x) + if (llabs(test_rect.mLeft - sibling_rect.mRight) <= x_threshold + && (test_rect.mLeft - sibling_rect.mRight) * mouse_dir.mX <= 0) + { + snap_pos = sibling_rect.mRight + padding; + snap_view = siblingp; + x_threshold = llabs(test_rect.mLeft - sibling_rect.mRight); + } + // if snapped with sibling along other axis, check for shared edge + else if (llabs(sibling_rect.mTop - (test_rect.mBottom - padding)) <= y_threshold + || llabs(sibling_rect.mBottom - (test_rect.mTop + padding)) <= y_threshold) { - if (llabs(test_rect.mLeft - sibling_rect.mRight) <= threshold && (test_rect.mLeft - sibling_rect.mRight) * mouse_dir.mX <= 0) + if (llabs(test_rect.mLeft - sibling_rect.mLeft) <= x_threshold + && (test_rect.mLeft - sibling_rect.mLeft) * mouse_dir.mX <= 0) { - snap_pos = sibling_rect.mRight + padding; + snap_pos = sibling_rect.mLeft; snap_view = siblingp; - snapped_x = TRUE; - } - // if snapped with sibling along other axis, check for shared edge - else if (llabs(sibling_rect.mTop - (test_rect.mBottom - padding)) <= threshold || - llabs(sibling_rect.mBottom - (test_rect.mTop + padding)) <= threshold) - { - if (llabs(test_rect.mLeft - sibling_rect.mLeft) <= threshold && (test_rect.mLeft - sibling_rect.mLeft) * mouse_dir.mX <= 0) - { - snap_pos = sibling_rect.mLeft; - snap_view = siblingp; - snapped_x = TRUE; - } + x_threshold = llabs(test_rect.mLeft - sibling_rect.mLeft); } } break; case SNAP_BOTTOM: - if (!snapped_y) + if (llabs(test_rect.mBottom - sibling_rect.mTop) <= y_threshold + && (test_rect.mBottom - sibling_rect.mTop) * mouse_dir.mY <= 0) { - if (llabs(test_rect.mBottom - sibling_rect.mTop) <= threshold && (test_rect.mBottom - sibling_rect.mTop) * mouse_dir.mY <= 0) + snap_pos = sibling_rect.mTop + padding; + snap_view = siblingp; + y_threshold = llabs(test_rect.mBottom - sibling_rect.mTop); + } + // if snapped with sibling along other axis, check for shared edge + else if (llabs(sibling_rect.mRight - (test_rect.mLeft - padding)) <= x_threshold + || llabs(sibling_rect.mLeft - (test_rect.mRight + padding)) <= x_threshold) + { + if (llabs(test_rect.mBottom - sibling_rect.mBottom) <= y_threshold + && (test_rect.mBottom - sibling_rect.mBottom) * mouse_dir.mY <= 0) { - snap_pos = sibling_rect.mTop + padding; + snap_pos = sibling_rect.mBottom; snap_view = siblingp; - snapped_y = TRUE; - } - // if snapped with sibling along other axis, check for shared edge - else if (llabs(sibling_rect.mRight - (test_rect.mLeft - padding)) <= threshold || - llabs(sibling_rect.mLeft - (test_rect.mRight + padding)) <= threshold) - { - if (llabs(test_rect.mBottom - sibling_rect.mBottom) <= threshold && (test_rect.mBottom - sibling_rect.mBottom) * mouse_dir.mY <= 0) - { - snap_pos = sibling_rect.mBottom; - snap_view = siblingp; - snapped_y = TRUE; - } + y_threshold = llabs(test_rect.mBottom - sibling_rect.mBottom); } } break; case SNAP_TOP: - if (!snapped_y) + if (llabs(test_rect.mTop - sibling_rect.mBottom) <= y_threshold + && (test_rect.mTop - sibling_rect.mBottom) * mouse_dir.mY <= 0) + { + snap_pos = sibling_rect.mBottom - padding; + snap_view = siblingp; + y_threshold = llabs(test_rect.mTop - sibling_rect.mBottom); + } + // if snapped with sibling along other axis, check for shared edge + else if (llabs(sibling_rect.mRight - (test_rect.mLeft - padding)) <= x_threshold + || llabs(sibling_rect.mLeft - (test_rect.mRight + padding)) <= x_threshold) { - if (llabs(test_rect.mTop - sibling_rect.mBottom) <= threshold && (test_rect.mTop - sibling_rect.mBottom) * mouse_dir.mY <= 0) + if (llabs(test_rect.mTop - sibling_rect.mTop) <= y_threshold + && (test_rect.mTop - sibling_rect.mTop) * mouse_dir.mY <= 0) { - snap_pos = sibling_rect.mBottom - padding; + snap_pos = sibling_rect.mTop; snap_view = siblingp; - snapped_y = TRUE; - } - // if snapped with sibling along other axis, check for shared edge - else if (llabs(sibling_rect.mRight - (test_rect.mLeft - padding)) <= threshold || - llabs(sibling_rect.mLeft - (test_rect.mRight + padding)) <= threshold) - { - if (llabs(test_rect.mTop - sibling_rect.mTop) <= threshold && (test_rect.mTop - sibling_rect.mTop) * mouse_dir.mY <= 0) - { - snap_pos = sibling_rect.mTop; - snap_view = siblingp; - snapped_y = TRUE; - } + y_threshold = llabs(test_rect.mTop - sibling_rect.mTop); } } break; default: llerrs << "Invalid snap edge" << llendl; } - if (snapped_x && snapped_y) - { - break; - } } } @@ -2571,21 +2386,6 @@ LLView* LLView::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESna return snap_view; } -bool operator==(const LLViewHandle& lhs, const LLViewHandle& rhs) -{ - return lhs.mID == rhs.mID; -} - -bool operator!=(const LLViewHandle& lhs, const LLViewHandle& rhs) -{ - return lhs.mID != rhs.mID; -} - -bool operator<(const LLViewHandle &lhs, const LLViewHandle &rhs) -{ - return lhs.mID < rhs.mID; -} - //----------------------------------------------------------------------------- // Listener dispatch functions //----------------------------------------------------------------------------- @@ -2876,13 +2676,6 @@ void LLView::initFromXML(LLXMLNodePtr node, LLView* parent) setVisible(visible); } - if (node->hasAttribute("hidden")) - { - BOOL hidden; - node->getAttributeBOOL("hidden", hidden); - setHidden(hidden); - } - node->getAttributeBOOL("use_bounding_rect", mUseBoundingRect); node->getAttributeBOOL("mouse_opaque", mMouseOpaque); @@ -3014,12 +2807,6 @@ void LLView::setControlValue(const LLSD& value) } //virtual -LLString LLView::getControlName() const -{ - return mControlName; -} - -//virtual void LLView::setControlName(const LLString& control_name, LLView *context) { if (context == NULL) @@ -3058,11 +2845,6 @@ bool LLView::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) return FALSE; } -void LLView::setValue(const LLSD& value) -{ -} - - void LLView::addBoolControl(LLString name, bool initial_value) { mFloaterControls[name] = new LLControl(name, TYPE_BOOLEAN, initial_value, "Internal floater control"); @@ -3077,3 +2859,14 @@ LLControlBase *LLView::getControl(LLString name) } return NULL; } + +//virtual +void LLView::setValue(const LLSD& value) +{ +} + +//virtual +LLSD LLView::getValue() const +{ + return LLSD(); +} diff --git a/indra/llui/llview.h b/indra/llui/llview.h index e54983d67d..c8556c7edc 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -52,10 +52,6 @@ #include "stdenums.h" #include "lluistring.h" -class LLColor4; -class LLWindow; -class LLUICtrl; -class LLScrollListItem; const U32 FOLLOWS_NONE = 0x00; const U32 FOLLOWS_LEFT = 0x01; @@ -69,29 +65,90 @@ const BOOL NOT_MOUSE_OPAQUE = FALSE; const U32 GL_NAME_UI_RESERVED = 2; -class LLSimpleListener; -class LLEventDispatcher; -class LLViewHandle -{ -public: - LLViewHandle() { mID = 0; } - - void init() { mID = ++sNextID; } - void markDead() { mID = 0; } - BOOL isDead() { return (mID == 0); } - friend bool operator==(const LLViewHandle& lhs, const LLViewHandle& rhs); - friend bool operator!=(const LLViewHandle& lhs, const LLViewHandle& rhs); - friend bool operator<(const LLViewHandle &a, const LLViewHandle &b); - -public: - static LLViewHandle sDeadHandle; +/* +// virtual functions defined in LLView: + +virtual BOOL isCtrl() const; + LLUICtrl +virtual BOOL isPanel(); + LLPanel +virtual void setRect(const LLRect &rect); + LLLineEditor +virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group); +virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group); +virtual void removeCtrl( LLUICtrl* ctrl); + LLPanel +virtual BOOL canFocusChildren() const { return TRUE; } + LLFolderView +virtual void deleteAllChildren(); + LLFolderView, LLPanelInventory +virtual void setTentative(BOOL b) {} + LLUICtrl, LLSliderCtrl, LLSpinCtrl +virtual BOOL getTentative() const { return FALSE; } + LLUICtrl, LLCheckBoxCtrl +virtual void setVisible(BOOL visible); + LLFloater, LLAlertDialog, LLMenuItemGL, LLModalDialog +virtual void setEnabled(BOOL enabled) { mEnabled = enabled; } + LLCheckBoxCtrl, LLComboBox, LLLineEditor, LLMenuGL, LLRadioGroup, etc +virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ) { return FALSE; } + LLUICtrl, LLButton, LLCheckBoxCtrl, LLLineEditor, LLMenuGL, LLSliderCtrl +virtual void onVisibilityChange ( BOOL curVisibilityIn ); + LLMenuGL +virtual LLRect getSnapRect() const { return mRect; } *TODO: Make non virtual + LLFloater +virtual LLRect getRequiredRect() { return mRect; } + LLScrolllistCtrl +virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + LLUICtrl, et. al. +virtual void translate( S32 x, S32 y ); + LLMenuGL +virtual void userSetShape(const LLRect& new_rect); + LLFloater, LLScrollLIstVtrl +virtual LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0); +virtual LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0); + LLScrollListCtrl +virtual BOOL canSnapTo(const LLView* other_view) const { return other_view != this && other_view->getVisible(); } + LLFloater +virtual void snappedTo(LLView* snap_view) {} + LLFloater +virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); + * +virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); + * +virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,EDragAndDropType cargo_type,void* cargo_data,EAcceptance* accept,LLString& tooltip_msg); + * +virtual void draw(); + * +virtual EWidgetType getWidgetType() const = 0; + * +virtual LLString getWidgetTag() const = 0; + * +virtual LLXMLNodePtr getXML(bool save_children = true) const; + * +virtual void initFromXML(LLXMLNodePtr node, LLView* parent); + * +virtual void onFocusLost() {} + LLUICtrl, LLScrollListCtrl, LLMenuGL, LLLineEditor, LLComboBox +virtual void onFocusReceived() {} + LLUICtrl, LLTextEditor, LLScrollListVtrl, LLMenuGL, LLLineEditor +virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; + LLTabContainer, LLPanel, LLMenuGL +virtual void setControlName(const LLString& control, LLView *context); + LLSliderCtrl, LLCheckBoxCtrl +virtual LLString getControlName() const { return mControlName; } + LLSliderCtrl, LLCheckBoxCtrl +virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata); + LLMenuItem +virtual void setValue(const LLSD& value); + * protected: - S32 mID; - - static S32 sNextID; -}; +virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); + * +virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); + * +*/ class LLView : public LLMouseHandler, public LLMortician, public LLSimpleListenerObservable { @@ -128,7 +185,7 @@ public: typedef child_list_t::reverse_iterator child_list_reverse_iter_t; typedef child_list_t::const_reverse_iterator child_list_const_reverse_iter_t; - typedef std::vector<LLUICtrl *> ctrl_list_t; + typedef std::vector<class LLUICtrl *> ctrl_list_t; typedef std::pair<S32, S32> tab_order_t; typedef std::pair<LLUICtrl *, tab_order_t> tab_order_pair_t; @@ -139,105 +196,48 @@ public: typedef child_tab_order_t::reverse_iterator child_tab_order_reverse_iter_t; typedef child_tab_order_t::const_reverse_iterator child_tab_order_const_reverse_iter_t; -private: - LLView* mParentView; - child_list_t mChildList; - -protected: - LLString mName; - // location in pixels, relative to surrounding structure, bottom,left=0,0 - LLRect mRect; - LLRect mBoundingRect; - - U32 mReshapeFlags; - - child_tab_order_t mCtrlOrder; - S32 mDefaultTabGroup; - - BOOL mEnabled; // Enabled means "accepts input that has an effect on the state of the application." - // A disabled view, for example, may still have a scrollbar that responds to mouse events. - BOOL mMouseOpaque; // Opaque views handle all mouse events that are over their rect. - LLUIString mToolTipMsg; // isNull() is true if none. - - U8 mSoundFlags; - BOOL mSaveToXML; - - BOOL mIsFocusRoot; - BOOL mUseBoundingRect; // hit test against bounding rectangle that includes all child elements - -public: - LLViewHandle mViewHandle; - BOOL mLastVisible; - -private: - BOOL mVisible; - BOOL mHidden; // Never show (generally for replacement text only) - - S32 mNextInsertionOrdinal; - -protected: - static LLWindow* sWindow; // All root views must know about their window. - -public: - static BOOL sDebugRects; // Draw debug rects behind everything. - static BOOL sDebugKeys; - static S32 sDepth; - static BOOL sDebugMouseHandling; - static LLString sMouseHandlerMessage; - static S32 sSelectID; - static BOOL sEditingUI; - static LLView* sEditingUIView; - static S32 sLastLeftXML; - static S32 sLastBottomXML; - static std::map<LLViewHandle,LLView*> sViewHandleMap; - static BOOL sForceReshape; - -public: - static LLView* getViewByHandle(LLViewHandle handle); - static BOOL deleteViewByHandle(LLViewHandle handle); - -public: LLView(); LLView(const LLString& name, BOOL mouse_opaque); LLView(const LLString& name, const LLRect& rect, BOOL mouse_opaque, U32 follows=FOLLOWS_NONE); virtual ~LLView(); - // Hack to support LLFocusMgr - virtual BOOL isView(); + // Hack to support LLFocusMgr (from LLMouseHandler) + /*virtual*/ BOOL isView() const; // Some UI widgets need to be added as controls. Others need to // be added as regular view children. isCtrl should return TRUE // if a widget needs to be added as a ctrl virtual BOOL isCtrl() const; - virtual BOOL isPanel(); + virtual BOOL isPanel() const; // // MANIPULATORS // - void setMouseOpaque( BOOL b ); + void setMouseOpaque( BOOL b ) { mMouseOpaque = b; } + BOOL getMouseOpaque() const { return mMouseOpaque; } void setToolTip( const LLStringExplicit& msg ); BOOL setToolTipArg( const LLStringExplicit& key, const LLStringExplicit& text ); void setToolTipArgs( const LLString::format_map_t& args ); virtual void setRect(const LLRect &rect); - void setFollows(U32 flags); + void setFollows(U32 flags) { mReshapeFlags = flags; } // deprecated, use setFollows() with FOLLOWS_LEFT | FOLLOWS_TOP, etc. - void setFollowsNone(); - void setFollowsLeft(); - void setFollowsTop(); - void setFollowsRight(); - void setFollowsBottom(); - void setFollowsAll(); - - void setSoundFlags(U8 flags); - void setName(LLString name); + void setFollowsNone() { mReshapeFlags = FOLLOWS_NONE; } + void setFollowsLeft() { mReshapeFlags |= FOLLOWS_LEFT; } + void setFollowsTop() { mReshapeFlags |= FOLLOWS_TOP; } + void setFollowsRight() { mReshapeFlags |= FOLLOWS_RIGHT; } + void setFollowsBottom() { mReshapeFlags |= FOLLOWS_BOTTOM; } + void setFollowsAll() { mReshapeFlags |= FOLLOWS_ALL; } + + void setSoundFlags(U8 flags) { mSoundFlags = flags; } + void setName(LLString name) { mName = name; } void setUseBoundingRect( BOOL use_bounding_rect ); BOOL getUseBoundingRect(); - const LLString& getToolTip(); + const LLString& getToolTip() const { return mToolTipMsg.getString(); } void sendChildToFront(LLView* child); void sendChildToBack(LLView* child); @@ -253,61 +253,47 @@ public: virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group); virtual void removeCtrl( LLUICtrl* ctrl); - child_tab_order_t getCtrlOrder() const { return mCtrlOrder; } + child_tab_order_t getCtrlOrder() const { return mCtrlOrder; } ctrl_list_t getCtrlList() const; ctrl_list_t getCtrlListSorted() const; - S32 getDefaultTabGroup() const; + + void setDefaultTabGroup(S32 d) { mDefaultTabGroup = d; } + S32 getDefaultTabGroup() const { return mDefaultTabGroup; } BOOL isInVisibleChain() const; BOOL isInEnabledChain() const; - BOOL isFocusRoot() const; - LLView* findRootMostFocusRoot(); + void setFocusRoot(BOOL b) { mIsFocusRoot = b; } + BOOL isFocusRoot() const { return mIsFocusRoot; } virtual BOOL canFocusChildren() const; - class LLFocusRootsFilter : public LLQueryFilter, public LLSingleton<LLFocusRootsFilter> - { - /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const - { - return filterResult_t(view->isCtrl() && view->isFocusRoot(), TRUE); - } - }; - - virtual BOOL focusNextRoot(); - virtual BOOL focusPrevRoot(); - - virtual BOOL focusNextItem(BOOL text_entry_only); - virtual BOOL focusPrevItem(BOOL text_entry_only); - virtual BOOL focusFirstItem(BOOL prefer_text_fields = FALSE ); - virtual BOOL focusLastItem(BOOL prefer_text_fields = FALSE); + BOOL focusNextRoot(); + BOOL focusPrevRoot(); // delete all children. Override this function if you need to // perform any extra clean up such as cached pointers to selected // children, etc. virtual void deleteAllChildren(); - // by default, does nothing virtual void setTentative(BOOL b); - // by default, returns false virtual BOOL getTentative() const; - virtual void setAllChildrenEnabled(BOOL b); + void setAllChildrenEnabled(BOOL b); - virtual void setEnabled(BOOL enabled); virtual void setVisible(BOOL visible); - virtual void setHidden(BOOL hidden); // Never show (replacement text) + BOOL getVisible() const { return mVisible; } + virtual void setEnabled(BOOL enabled); + BOOL getEnabled() const { return mEnabled; } + U8 getSoundFlags() const { return mSoundFlags; } - // by default, does nothing and returns false virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); virtual void onVisibilityChange ( BOOL curVisibilityIn ); void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); } void popVisible() { setVisible(mLastVisible); mLastVisible = TRUE; } + + LLHandle<LLView> getHandle() { mHandle.bind(this); return mHandle; } - // - // ACCESSORS - // - BOOL getMouseOpaque() const { return mMouseOpaque; } U32 getFollows() const { return mReshapeFlags; } BOOL followsLeft() const { return mReshapeFlags & FOLLOWS_LEFT; } @@ -318,26 +304,26 @@ public: const LLRect& getRect() const { return mRect; } const LLRect& getBoundingRect() const { return mBoundingRect; } - const LLRect getLocalBoundingRect() const; - const LLRect getScreenRect() const; - const LLRect getLocalRect() const; - virtual const LLRect getSnapRect() const { return mRect; } - virtual const LLRect getLocalSnapRect() const; - - virtual LLRect getRequiredRect(); // Get required size for this object. 0 for width/height means don't care. + LLRect getLocalBoundingRect() const; + LLRect getScreenRect() const; + LLRect getLocalRect() const; + virtual LLRect getSnapRect() const; + LLRect getLocalSnapRect() const; + + // Override and return required size for this object. 0 for width/height means don't care. + virtual LLRect getRequiredRect(); void updateBoundingRect(); LLView* getRootView(); LLView* getParent() const { return mParentView; } - LLView* getFirstChild() { return (mChildList.empty()) ? NULL : *(mChildList.begin()); } + LLView* getFirstChild() const { return (mChildList.empty()) ? NULL : *(mChildList.begin()); } S32 getChildCount() const { return (S32)mChildList.size(); } template<class _Pr3> void sortChildren(_Pr3 _Pred) { mChildList.sort(_Pred); } - BOOL hasAncestor(const LLView* parentp); - + BOOL hasAncestor(const LLView* parentp) const; BOOL hasChild(const LLString& childname, BOOL recurse = FALSE) const; - BOOL childHasKeyboardFocus( const LLString& childname ) const; + // // UTILITIES // @@ -345,15 +331,15 @@ public: // Default behavior is to use reshape flags to resize child views virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); virtual void translate( S32 x, S32 y ); - virtual void setOrigin( S32 x, S32 y ) { mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); } + void setOrigin( S32 x, S32 y ) { mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); } BOOL translateIntoRect( const LLRect& constraint, BOOL allow_partial_outside ); + void centerWithin(const LLRect& bounds); virtual void userSetShape(const LLRect& new_rect); virtual LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0); virtual LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0); - // Defaults to other_view->getVisible() - virtual BOOL canSnapTo(LLView* other_view); + virtual BOOL canSnapTo(const LLView* other_view) const; virtual void snappedTo(LLView* snap_view); @@ -365,49 +351,97 @@ public: EAcceptance* accept, LLString& tooltip_msg); - // LLMouseHandler functions - // Default behavior is to pass events to children - - /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); - /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ void onMouseCaptureLost(); - /*virtual*/ BOOL hasMouseCapture(); - - // Default behavior is to pass the tooltip event to children, - // then display mToolTipMsg if no child handled it. - /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect); - LLString getShowNamesToolTip(); virtual void draw(); - void drawDebugRect(); - void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE); - - virtual const LLString& getName() const; - virtual EWidgetType getWidgetType() const = 0; virtual LLString getWidgetTag() const = 0; virtual LLXMLNodePtr getXML(bool save_children = true) const; - static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect()); virtual void initFromXML(LLXMLNodePtr node, LLView* parent); void parseFollowsFlags(LLXMLNodePtr node); + // Some widgets, like close box buttons, don't need to be saved + BOOL getSaveToXML() const { return mSaveToXML; } + void setSaveToXML(BOOL b) { mSaveToXML = b; } + + virtual void onFocusLost(); + virtual void onFocusReceived(); + + typedef enum e_hit_test_type + { + HIT_TEST_USE_BOUNDING_RECT, + HIT_TEST_IGNORE_BOUNDING_RECT + }EHitTestType; + + BOOL parentPointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const; + BOOL pointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const; + BOOL blockMouseEvent(S32 x, S32 y) const; + + // See LLMouseHandler virtuals for screenPointToLocal and localPointToScreen + BOOL localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view) const; + BOOL localRectToOtherView( const LLRect& local, LLRect* other, LLView* other_view ) const; + void screenRectToLocal( const LLRect& screen, LLRect* local ) const; + void localRectToScreen( const LLRect& local, LLRect* screen ) const; + + // Listener dispatching functions (Dispatcher deletes pointers to listeners on deregistration or destruction) + LLSimpleListener* getListenerByName(const LLString &callback_name); + void registerEventListener(LLString name, LLSimpleListener* function); + void deregisterEventListener(LLString name); + LLString findEventListener(LLSimpleListener *listener) const; + void addListenerToControl(LLEventDispatcher *observer, const LLString& name, LLSD filter, LLSD userdata); + + void addBoolControl(LLString name, bool initial_value); + LLControlBase *getControl(LLString name); + LLControlBase *findControl(LLString name); + + void setControlValue(const LLSD& value); + virtual void setControlName(const LLString& control, LLView *context); + virtual LLString getControlName() const { return mControlName; } + virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata); + virtual void setValue(const LLSD& value); + virtual LLSD getValue() const; + + const child_list_t* getChildList() const { return &mChildList; } + + // LLMouseHandler functions + // Default behavior is to pass events to children + /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect); // Display mToolTipMsg if no child handles it. + /*virtual*/ const LLString& getName() const; + /*virtual*/ void onMouseCaptureLost(); + /*virtual*/ BOOL hasMouseCapture(); + /*virtual*/ BOOL isView(); // Hack to support LLFocusMgr + /*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const; + /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const; + + template <class T> T* getChild(const LLString& name, BOOL recurse = TRUE) const + { + T* result = dynamic_cast<T*>(getChildByName(name, TRUE)); + //if (!result) + //{ + // // create dummy widget instance here + // result = gUICtrlFactory->createDummyWidget<T>(name); + //} + return result; + } + + // statics + static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect()); + static LLFontGL* selectFont(LLXMLNodePtr node); static LLFontGL::HAlign selectFontHAlign(LLXMLNodePtr node); static LLFontGL::VAlign selectFontVAlign(LLXMLNodePtr node); static LLFontGL::StyleFlags selectFontStyle(LLXMLNodePtr node); - // Some widgets, like close box buttons, don't need to be saved - BOOL getSaveToXML() const { return mSaveToXML; } - void setSaveToXML(BOOL b) { mSaveToXML = b; } - + // Only saves color if different from default setting. static void addColorXML(LLXMLNodePtr node, const LLColor4& color, const LLString& xml_name, const LLString& control_name); @@ -432,54 +466,17 @@ public: // return query for iterating over focus roots in tab order static const LLCtrlQuery & getFocusRootsQuery(); - BOOL getEnabled() const { return mEnabled; } - BOOL getVisible() const { return mVisible && !mHidden; } - U8 getSoundFlags() const { return mSoundFlags; } - - typedef enum e_hit_test_type - { - HIT_TEST_USE_BOUNDING_RECT, - HIT_TEST_IGNORE_BOUNDING_RECT - }EHitTestType; - - BOOL parentPointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const; - BOOL pointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const; - BOOL blockMouseEvent(S32 x, S32 y) const; - - virtual void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const; - virtual void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const; - virtual BOOL localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view); - virtual void screenRectToLocal( const LLRect& screen, LLRect* local ) const; - virtual void localRectToScreen( const LLRect& local, LLRect* screen ) const; - virtual BOOL localRectToOtherView( const LLRect& local, LLRect* other, LLView* other_view ) const; - - - static LLWindow* getWindow(void); - - // Listener dispatching functions (Dispatcher deletes pointers to listeners on deregistration or destruction) - LLSimpleListener* getListenerByName(const LLString &callback_name); - void registerEventListener(LLString name, LLSimpleListener* function); - void deregisterEventListener(LLString name); - LLString findEventListener(LLSimpleListener *listener) const; - void addListenerToControl(LLEventDispatcher *observer, const LLString& name, LLSD filter, LLSD userdata); - - virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; - - void addBoolControl(LLString name, bool initial_value); - LLControlBase *getControl(LLString name); - virtual LLControlBase *findControl(LLString name); - - void setControlValue(const LLSD& value); - virtual void setControlName(const LLString& control, LLView *context); - virtual LLString getControlName() const; - virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata); - virtual void setValue(const LLSD& value); - const child_list_t* getChildList() const { return &mChildList; } + static BOOL deleteViewByHandle(LLHandle<LLView> handle); + static LLWindow* getWindow(void) { return LLUI::sWindow; } + protected: virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); + void drawDebugRect(); + void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE); + LLView* childrenHandleKey(KEY key, MASK mask); LLView* childrenHandleUnicodeChar(llwchar uni_char); LLView* childrenHandleDragAndDrop(S32 x, S32 y, MASK mask, @@ -497,15 +494,64 @@ protected: LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask); - typedef std::map<LLString, LLPointer<LLSimpleListener> > dispatch_list_t; - dispatch_list_t mDispatchList; - -protected: typedef std::map<LLString, LLControlBase*> control_map_t; control_map_t mFloaterControls; + virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; + +private: + LLView* mParentView; + child_list_t mChildList; + + LLString mName; + // location in pixels, relative to surrounding structure, bottom,left=0,0 + LLRect mRect; + LLRect mBoundingRect; + + U32 mReshapeFlags; + + child_tab_order_t mCtrlOrder; + S32 mDefaultTabGroup; + + BOOL mEnabled; // Enabled means "accepts input that has an effect on the state of the application." + // A disabled view, for example, may still have a scrollbar that responds to mouse events. + BOOL mMouseOpaque; // Opaque views handle all mouse events that are over their rect. + LLUIString mToolTipMsg; // isNull() is true if none. + + U8 mSoundFlags; + BOOL mSaveToXML; + + BOOL mIsFocusRoot; + BOOL mUseBoundingRect; // hit test against bounding rectangle that includes all child elements + + LLRootHandle<LLView> mHandle; + BOOL mLastVisible; + + BOOL mVisible; + + S32 mNextInsertionOrdinal; + + static LLWindow* sWindow; // All root views must know about their window. + + typedef std::map<LLString, LLPointer<LLSimpleListener> > dispatch_list_t; + dispatch_list_t mDispatchList; + LLString mControlName; - friend class LLUICtrlFactory; + + +// Just debugging stuff? We should try to hide anything that's not. -MG +public: + static BOOL sDebugRects; // Draw debug rects behind everything. + static BOOL sDebugKeys; + static S32 sDepth; + static BOOL sDebugMouseHandling; + static LLString sMouseHandlerMessage; + static S32 sSelectID; + static BOOL sEditingUI; + static LLView* sEditingUIView; + static S32 sLastLeftXML; + static S32 sLastBottomXML; + static BOOL sForceReshape; }; @@ -514,12 +560,12 @@ protected: class LLCompareByTabOrder { public: - LLCompareByTabOrder(LLView::child_tab_order_t order); + LLCompareByTabOrder(LLView::child_tab_order_t order) : mTabOrder(order) {} virtual ~LLCompareByTabOrder() {} bool operator() (const LLView* const a, const LLView* const b) const; -protected: - virtual bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const; +private: + virtual bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const { return a < b; } LLView::child_tab_order_t mTabOrder; }; -#endif +#endif //LL_LLVIEW_H diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp index 8fbe671613..546eb23c03 100644 --- a/indra/llui/llviewborder.cpp +++ b/indra/llui/llviewborder.cpp @@ -1,6 +1,5 @@ /** * @file llviewborder.cpp - * @brief LLViewBorder base class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -29,19 +28,8 @@ * $/LicenseInfo$ */ -// A customizable decorative border. Does not interact with mouse events. - #include "linden_common.h" - #include "llviewborder.h" - -#include "llgl.h" -#include "llui.h" -#include "llimagegl.h" -//#include "llviewerimagelist.h" -#include "llcontrol.h" -#include "llglheaders.h" -#include "v2math.h" #include "llfocusmgr.h" LLViewBorder::LLViewBorder( const LLString& name, const LLRect& rect, EBevel bevel, EStyle style, S32 width ) @@ -53,7 +41,6 @@ LLViewBorder::LLViewBorder( const LLString& name, const LLRect& rect, EBevel bev mHighlightDark( LLUI::sColorsGroup->getColor( "DefaultHighlightDark" ) ), mShadowLight( LLUI::sColorsGroup->getColor( "DefaultShadowLight" ) ), mShadowDark( LLUI::sColorsGroup->getColor( "DefaultShadowDark" ) ), -// mKeyboardFocusColor(LLUI::sColorsGroup->getColor( "FocusColor" ) ), mBorderWidth( width ), mTexture( NULL ), mHasKeyboardFocus( FALSE ) @@ -61,12 +48,6 @@ LLViewBorder::LLViewBorder( const LLString& name, const LLRect& rect, EBevel bev setFollowsAll(); } -// virtual -BOOL LLViewBorder::isCtrl() const -{ - return FALSE; -} - void LLViewBorder::setColors( const LLColor4& shadow_dark, const LLColor4& highlight_light ) { mShadowDark = shadow_dark; @@ -160,8 +141,8 @@ void LLViewBorder::drawOnePixelLines() } S32 left = 0; - S32 top = mRect.getHeight(); - S32 right = mRect.getWidth(); + S32 top = getRect().getHeight(); + S32 right = getRect().getWidth(); S32 bottom = 0; glColor4fv( top_color.mV ); @@ -219,8 +200,8 @@ void LLViewBorder::drawTwoPixelLines() } S32 left = 0; - S32 top = mRect.getHeight(); - S32 right = mRect.getWidth(); + S32 top = getRect().getHeight(); + S32 right = getRect().getWidth(); S32 bottom = 0; // draw borders @@ -253,10 +234,10 @@ void LLViewBorder::drawTextures() glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); - drawTextureTrapezoid( 0.f, mBorderWidth, mRect.getWidth(), 0, 0 ); - drawTextureTrapezoid( 90.f, mBorderWidth, mRect.getHeight(), (F32)mRect.getWidth(),0 ); - drawTextureTrapezoid( 180.f, mBorderWidth, mRect.getWidth(), (F32)mRect.getWidth(),(F32)mRect.getHeight() ); - drawTextureTrapezoid( 270.f, mBorderWidth, mRect.getHeight(), 0, (F32)mRect.getHeight() ); + drawTextureTrapezoid( 0.f, mBorderWidth, getRect().getWidth(), 0, 0 ); + drawTextureTrapezoid( 90.f, mBorderWidth, getRect().getHeight(), (F32)getRect().getWidth(),0 ); + drawTextureTrapezoid( 180.f, mBorderWidth, getRect().getWidth(), (F32)getRect().getWidth(),(F32)getRect().getHeight() ); + drawTextureTrapezoid( 270.f, mBorderWidth, getRect().getHeight(), 0, (F32)getRect().getHeight() ); } @@ -292,7 +273,7 @@ void LLViewBorder::drawTextureTrapezoid( F32 degrees, S32 width, S32 length, F32 glPopMatrix(); } -bool LLViewBorder::getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel& bevel_style) +BOOL LLViewBorder::getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel& bevel_style) { if (node->hasAttribute("bevel_style")) { @@ -316,25 +297,11 @@ bool LLViewBorder::getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel { bevel_style = LLViewBorder::BEVEL_BRIGHT; } - return true; + return TRUE; } - return false; -} - -void LLViewBorder::setValue(const LLSD& val) -{ - setRect(LLRect(val)); -} - -EWidgetType LLViewBorder::getWidgetType() const -{ - return WIDGET_TYPE_VIEW_BORDER; + return FALSE; } -LLString LLViewBorder::getWidgetTag() const -{ - return LL_VIEW_BORDER_TAG; -} // static LLView* LLViewBorder::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) diff --git a/indra/llui/llviewborder.h b/indra/llui/llviewborder.h index 6a91c5ebf7..e9fd8aa4e1 100644 --- a/indra/llui/llviewborder.h +++ b/indra/llui/llviewborder.h @@ -1,6 +1,6 @@ /** * @file llviewborder.h - * @brief LLViewBorder base class + * @brief A customizable decorative border. Does not interact with mouse events. * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -29,64 +29,53 @@ * $/LicenseInfo$ */ -// A customizable decorative border. Does not interact with mouse events. - #ifndef LL_LLVIEWBORDER_H #define LL_LLVIEWBORDER_H #include "llview.h" -#include "v4color.h" -#include "lluuid.h" -#include "llimagegl.h" -#include "llxmlnode.h" - -class LLUUID; -class LLUICtrlFactory; class LLViewBorder : public LLView { public: enum EBevel { BEVEL_IN, BEVEL_OUT, BEVEL_BRIGHT, BEVEL_NONE }; - enum EStyle { STYLE_LINE, STYLE_TEXTURE }; LLViewBorder( const LLString& name, const LLRect& rect, EBevel bevel = BEVEL_OUT, EStyle style = STYLE_LINE, S32 width = 1 ); - virtual void setValue(const LLSD& val); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual void setValue(const LLSD& val) { setRect(LLRect(val)); } + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_VIEW_BORDER; } + virtual LLString getWidgetTag() const { return LL_VIEW_BORDER_TAG; } - virtual BOOL isCtrl() const; + virtual BOOL isCtrl() const { return FALSE; } // llview functionality virtual void draw(); - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - static bool getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel& bevel_style); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); + static BOOL getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel& bevel_style); void setBorderWidth(S32 width) { mBorderWidth = width; } + S32 getBorderWidth() const { return mBorderWidth; } void setBevel(EBevel bevel) { mBevel = bevel; } + EBevel getBevel() const { return mBevel; } void setColors( const LLColor4& shadow_dark, const LLColor4& highlight_light ); void setColorsExtended( const LLColor4& shadow_light, const LLColor4& shadow_dark, const LLColor4& highlight_light, const LLColor4& highlight_dark ); - void setTexture( const LLUUID &image_id ); + void setTexture( const class LLUUID &image_id ); - EBevel getBevel() const { return mBevel; } EStyle getStyle() const { return mStyle; } - S32 getBorderWidth() const { return mBorderWidth; } void setKeyboardFocusHighlight( BOOL b ) { mHasKeyboardFocus = b; } -protected: +private: void drawOnePixelLines(); void drawTwoPixelLines(); void drawTextures(); void drawTextureTrapezoid( F32 degrees, S32 width, S32 length, F32 start_x, F32 start_y ); -protected: EBevel mBevel; - EStyle mStyle; + const EStyle mStyle; LLColor4 mHighlightLight; LLColor4 mHighlightDark; LLColor4 mShadowLight; diff --git a/indra/llui/llviewquery.cpp b/indra/llui/llviewquery.cpp index db00c76821..dedc9a6ebb 100644 --- a/indra/llui/llviewquery.cpp +++ b/indra/llui/llviewquery.cpp @@ -71,22 +71,9 @@ filterResult_t LLWidgetTypeFilter::operator() (const LLView* const view, const v return filterResult_t(view->getWidgetType() == mType, TRUE); } +// // LLViewQuery - -LLViewQuery::LLViewQuery(): mPreFilters(), mPostFilters(), mSorterp() -{ -} - -void LLViewQuery::addPreFilter(const LLQueryFilter* prefilter) { mPreFilters.push_back(prefilter); } - -void LLViewQuery::addPostFilter(const LLQueryFilter* postfilter) { mPostFilters.push_back(postfilter); } - -const LLViewQuery::filterList_t & LLViewQuery::getPreFilters() const { return mPreFilters; } - -const LLViewQuery::filterList_t & LLViewQuery::getPostFilters() const { return mPostFilters; } - -void LLViewQuery::setSorter(const LLQuerySorter* sorterp) { mSorterp = sorterp; } -const LLQuerySorter* LLViewQuery::getSorter() const { return mSorterp; } +// viewList_t LLViewQuery::run(LLView* view) const { diff --git a/indra/llui/llviewquery.h b/indra/llui/llviewquery.h index 63559e8240..59ef1c1896 100644 --- a/indra/llui/llviewquery.h +++ b/indra/llui/llviewquery.h @@ -42,12 +42,12 @@ class LLView; typedef std::list<LLView *> viewList_t; typedef std::pair<BOOL, BOOL> filterResult_t; -// Abstract base class for all filters. +// Abstract base class for all query filters. class LLQueryFilter { public: virtual ~LLQueryFilter() {}; - virtual filterResult_t operator() (const LLView* const view, const viewList_t & children) const =0; + virtual filterResult_t operator() (const LLView* const view, const viewList_t & children) const = 0; }; class LLQuerySorter @@ -105,25 +105,28 @@ public: typedef filterList_t::iterator filterList_iter_t; typedef filterList_t::const_iterator filterList_const_iter_t; - LLViewQuery(); + LLViewQuery() : mPreFilters(), mPostFilters(), mSorterp() {} virtual ~LLViewQuery() {} - void addPreFilter(const LLQueryFilter* prefilter); - void addPostFilter(const LLQueryFilter* postfilter); - const filterList_t & getPreFilters() const; - const filterList_t & getPostFilters() const; + void addPreFilter(const LLQueryFilter* prefilter) { mPreFilters.push_back(prefilter); } + void addPostFilter(const LLQueryFilter* postfilter) { mPostFilters.push_back(postfilter); } + const filterList_t & getPreFilters() const { return mPreFilters; } + const filterList_t & getPostFilters() const { return mPostFilters; } - void setSorter(const LLQuerySorter* sorter); - const LLQuerySorter* getSorter() const; + void setSorter(const LLQuerySorter* sorter) { mSorterp = sorter; } + const LLQuerySorter* getSorter() const { return mSorterp; } viewList_t run(LLView * view) const; // syntactic sugar viewList_t operator () (LLView * view) const { return run(view); } -protected: + // override this method to provide iteration over other types of children virtual void filterChildren(LLView * view, viewList_t & filtered_children) const; + +private: + filterResult_t runFilters(LLView * view, const viewList_t children, const filterList_t filters) const; -protected: + filterList_t mPreFilters; filterList_t mPostFilters; const LLQuerySorter* mSorterp; @@ -135,4 +138,4 @@ public: LLCtrlQuery(); }; -#endif +#endif // LL_LLVIEWQUERY_H |