diff options
Diffstat (limited to 'indra/llui')
32 files changed, 225 insertions, 160 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 9ce8ce8d55..4944ed4fe7 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -81,6 +81,10 @@ LLButton::Params::Params() image_pressed_selected("image_pressed_selected"), image_overlay("image_overlay"), image_overlay_alignment("image_overlay_alignment", std::string("center")), + image_left_pad("image_left_pad"), + image_right_pad("image_right_pad"), + image_top_pad("image_top_pad"), + image_bottom_pad("image_bottom_pad"), label_color("label_color"), label_color_selected("label_color_selected"), // requires is_toggle true label_color_disabled("label_color_disabled"), @@ -140,6 +144,10 @@ LLButton::LLButton(const LLButton::Params& p) mImageOverlay(p.image_overlay()), mImageOverlayColor(p.image_overlay_color()), mImageOverlayAlignment(LLFontGL::hAlignFromName(p.image_overlay_alignment)), + mImageOverlayLeftPad(p.image_left_pad), + mImageOverlayRightPad(p.image_right_pad), + mImageOverlayTopPad(p.image_top_pad), + mImageOverlayBottomPad(p.image_bottom_pad), mIsToggle(p.is_toggle), mScaleImage(p.scale_image), mDropShadowedText(p.label_shadow), @@ -763,6 +771,12 @@ void LLButton::draw() center_x++; } + S32 text_width_delta = overlay_width + 1; + // if image paddings set, they should participate in scaling process + S32 image_size_delta = mImageOverlayTopPad + mImageOverlayBottomPad; + overlay_width = overlay_width - image_size_delta; + overlay_height = overlay_height - image_size_delta; + // fade out overlay images on disabled buttons LLColor4 overlay_color = mImageOverlayColor.get(); if (!enabled) @@ -774,8 +788,8 @@ void LLButton::draw() switch(mImageOverlayAlignment) { case LLFontGL::LEFT: - text_left += overlay_width + 1; - text_width -= overlay_width + 1; + text_left += overlay_width + mImageOverlayRightPad + 1; + text_width -= text_width_delta; mImageOverlay->draw( mLeftHPad, center_y - (overlay_height / 2), @@ -792,8 +806,8 @@ void LLButton::draw() overlay_color); break; case LLFontGL::RIGHT: - text_right -= overlay_width + 1; - text_width -= overlay_width + 1; + text_right -= overlay_width + mImageOverlayLeftPad+ 1; + text_width -= text_width_delta; mImageOverlay->draw( getRect().getWidth() - mRightHPad - overlay_width, center_y - (overlay_height / 2), diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index cd149e3113..8e5f19602f 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -106,6 +106,12 @@ public: Optional<S32> pad_left; Optional<S32> pad_bottom; // under text label + //image overlay paddings + Optional<S32> image_left_pad; + Optional<S32> image_right_pad; + Optional<S32> image_top_pad; + Optional<S32> image_bottom_pad; + // callbacks Optional<CommitCallbackParam> click_callback, // alias -> commit_callback mouse_down_callback, @@ -186,6 +192,15 @@ public: void setLeftHPad( S32 pad ) { mLeftHPad = pad; } void setRightHPad( S32 pad ) { mRightHPad = pad; } + void setImageOverlayLeftPad( S32 pad ) { mImageOverlayLeftPad = pad; } + S32 getImageOverlayLeftPad() const { return mImageOverlayLeftPad; } + void setImageOverlayRightPad( S32 pad ) { mImageOverlayRightPad = pad; } + S32 getImageOverlayRightPad() const { return mImageOverlayRightPad; } + void setImageOverlayTopPad( S32 pad ) { mImageOverlayTopPad = pad; } + S32 getImageOverlayTopPad() const { return mImageOverlayTopPad; } + void setImageOverlayBottomPad( S32 pad ) { mImageOverlayBottomPad = pad; } + S32 getImageOverlayBottomPad() const { return mImageOverlayBottomPad; } + const std::string getLabelUnselected() const { return wstring_to_utf8str(mUnselectedLabel); } const std::string getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); } @@ -313,6 +328,11 @@ private: S32 mRightHPad; S32 mBottomVPad; // under text label + S32 mImageOverlayLeftPad; + S32 mImageOverlayRightPad; + S32 mImageOverlayTopPad; + S32 mImageOverlayBottomPad; + F32 mHoverGlowStrength; F32 mCurGlowStrength; diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index f29e8785eb..9d23daf56d 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -103,7 +103,8 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) mPrearrangeCallback(p.prearrange_callback()), mTextEntryCallback(p.text_entry_callback()), mListPosition(p.list_position), - mLastSelectedIndex(-1) + mLastSelectedIndex(-1), + mLabel(p.label) { // Text label button @@ -490,6 +491,7 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p) params.handle_edit_keys_directly(true); params.commit_on_focus_lost(false); params.follows.flags(FOLLOWS_ALL); + params.label(mLabel); mTextEntry = LLUICtrlFactory::create<LLLineEditor> (params); mTextEntry->setText(cur_label); mTextEntry->setIgnoreTab(TRUE); @@ -505,7 +507,8 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p) mButton->setRect(rect); mButton->setTabStop(TRUE); mButton->setHAlign(LLFontGL::LEFT); - + mButton->setLabel(mLabel.getString()); + if (mTextEntry) { mTextEntry->setVisible(FALSE); @@ -633,7 +636,7 @@ void LLComboBox::hideList() if(mLastSelectedIndex >= 0) mList->selectNthItem(mLastSelectedIndex); } - else + else if(mLastSelectedIndex >= 0) mList->selectNthItem(mLastSelectedIndex); mButton->setToggleState(FALSE); diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp index 59499f987b..0237c80efa 100644 --- a/indra/llui/llconsole.cpp +++ b/indra/llui/llconsole.cpp @@ -66,7 +66,9 @@ LLConsole::LLConsole(const LLConsole::Params& p) : LLUICtrl(p), LLFixedBuffer(p.max_lines), mLinePersistTime(p.persist_time), // seconds - mFont(p.font) + mFont(p.font), + mConsoleWidth(0), + mConsoleHeight(0) { if (p.font_size_index.isProvided()) { diff --git a/indra/llui/llconsole.h b/indra/llui/llconsole.h index 5800a82922..4719950f28 100644 --- a/indra/llui/llconsole.h +++ b/indra/llui/llconsole.h @@ -150,8 +150,6 @@ private: F32 mLinePersistTime; // Age at which to stop drawing. F32 mFadeTime; // Age at which to start fading const LLFontGL* mFont; - S32 mLastBoxHeight; - S32 mLastBoxWidth; S32 mConsoleWidth; S32 mConsoleHeight; diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp index 0d8e54aa48..d836a5f4cd 100644 --- a/indra/llui/lldockcontrol.cpp +++ b/indra/llui/lldockcontrol.cpp @@ -37,7 +37,11 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater, const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) : - mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(dockTongue) + mDockWidget(dockWidget), + mDockableFloater(dockableFloater), + mDockTongue(dockTongue), + mDockTongueX(0), + mDockTongueY(0) { mDockAt = dockAt; diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index a93c666648..832f148902 100644 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -113,6 +113,7 @@ void LLDragHandleTop::setTitle(const std::string& title) params.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT); params.font_shadow(LLFontGL::DROP_SHADOW_SOFT); params.use_ellipses = true; + params.allow_html = false; //cancel URL replacement in floater title mTitleBox = LLUICtrlFactory::create<LLTextBox> (params); addChild( mTitleBox ); } diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 3694ecd4f4..92993650a7 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -289,8 +289,8 @@ void LLFlatListView::resetSelection(bool no_commit_on_deselection /*= false*/) onCommit(); } - // Stretch selected items rect to ensure it won't be clipped - mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1)); + // Stretch selected item rect to ensure it won't be clipped + mSelectedItemsBorder->setRect(getLastSelectedItemRect().stretch(-1)); } void LLFlatListView::setNoItemsCommentText(const std::string& comment_text) @@ -393,7 +393,7 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p) LLViewBorder::Params params; params.name("scroll border"); - params.rect(getSelectedItemsRect()); + params.rect(getLastSelectedItemRect()); params.visible(false); params.bevel_style(LLViewBorder::BEVEL_IN); mSelectedItemsBorder = LLUICtrlFactory::create<LLViewBorder> (params); @@ -480,8 +480,8 @@ void LLFlatListView::rearrangeItems() item_new_top -= (rc.getHeight() + mItemPad); } - // Stretch selected items rect to ensure it won't be clipped - mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1)); + // Stretch selected item rect to ensure it won't be clipped + mSelectedItemsBorder->setRect(getLastSelectedItemRect().stretch(-1)); } void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask) @@ -664,8 +664,8 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select) onCommit(); } - // Stretch selected items rect to ensure it won't be clipped - mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1)); + // Stretch selected item rect to ensure it won't be clipped + mSelectedItemsBorder->setRect(getLastSelectedItemRect().stretch(-1)); return true; } @@ -680,23 +680,6 @@ LLRect LLFlatListView::getLastSelectedItemRect() return mSelectedItemPairs.back()->first->getRect(); } -LLRect LLFlatListView::getSelectedItemsRect() -{ - if (!mSelectedItemPairs.size()) - { - return LLRect::null; - } - LLRect rc = getLastSelectedItemRect(); - for ( pairs_const_iterator_t - it = mSelectedItemPairs.begin(), - it_end = mSelectedItemPairs.end(); - it != it_end; ++it ) - { - rc.unionWith((*it)->first->getRect()); - } - return rc; -} - void LLFlatListView::selectFirstItem () { selectItemPair(mItemPairs.front(), true); @@ -819,8 +802,8 @@ bool LLFlatListView::selectAll() onCommit(); } - // Stretch selected items rect to ensure it won't be clipped - mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1)); + // Stretch selected item rect to ensure it won't be clipped + mSelectedItemsBorder->setRect(getLastSelectedItemRect().stretch(-1)); return true; } diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index 5999e79f61..949a731507 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -368,8 +368,6 @@ protected: LLRect getLastSelectedItemRect(); - LLRect getSelectedItemsRect(); - void ensureSelectedVisible(); private: diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 79d8f90fec..de46d89d6f 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1916,9 +1916,10 @@ static LLDefaultChildRegistry::Register<LLFloaterView> r("floater_view"); LLFloaterView::LLFloaterView (const Params& p) : LLUICtrl (p), + mFocusCycleMode(FALSE), - mSnapOffsetBottom(0) - ,mSnapOffsetRight(0) + mSnapOffsetBottom(0), + mSnapOffsetRight(0) { } diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index f70495c0f0..8c9dacbd20 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -468,9 +468,6 @@ public: void setSnapOffsetRight(S32 offset) { mSnapOffsetRight = offset; } private: - S32 mColumn; - S32 mNextLeft; - S32 mNextTop; BOOL mFocusCycleMode; S32 mSnapOffsetBottom; S32 mSnapOffsetRight; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index c172a2b714..7fa9a88059 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1651,6 +1651,7 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p) mBackgroundColor( p.bg_color() ), mBgVisible( p.bg_visible ), mDropShadowed( p.drop_shadow ), + mHasSelection(false), mHorizontalLayout( p.horizontal_layout ), mScrollable(mHorizontalLayout ? FALSE : p.scrollable), // Scrolling is supported only for vertical layout mMaxScrollableItems(p.max_scrollable_items), @@ -1875,17 +1876,21 @@ void LLMenuGL::scrollItemsDown() item_list_t::iterator next_item_iter; - for (next_item_iter = ++cur_item_iter; next_item_iter != mItems.end(); next_item_iter++) + if (cur_item_iter != mItems.end()) { - if( (*next_item_iter)->getVisible()) + for (next_item_iter = ++cur_item_iter; next_item_iter != mItems.end(); next_item_iter++) { - break; + if( (*next_item_iter)->getVisible()) + { + break; + } + } + + if (next_item_iter != mItems.end() && + (*next_item_iter)->getVisible()) + { + mFirstVisibleItem = *next_item_iter; } - } - - if ((*next_item_iter)->getVisible()) - { - mFirstVisibleItem = *next_item_iter; } mNeedsArrange = TRUE; @@ -2809,7 +2814,7 @@ BOOL LLMenuGL::handleHover( S32 x, S32 y, MASK mask ) ((LLMenuItemGL*)viewp)->setHighlight(TRUE); LLMenuGL::setKeyboardMode(FALSE); } - mHasSelection = TRUE; + mHasSelection = true; } } } @@ -2888,7 +2893,7 @@ void LLMenuGL::setVisible(BOOL visible) } else { - mHasSelection = FALSE; + mHasSelection = true; mFadeTimer.stop(); } diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 61e06f9e5f..8441aaadd4 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -546,7 +546,7 @@ private: LLHandle<LLView> mParentMenuItem; LLUIString mLabel; BOOL mDropShadowed; // Whether to drop shadow - BOOL mHasSelection; + bool mHasSelection; LLFrameTimer mFadeTimer; LLTimer mScrollItemsTimer; BOOL mTornOff; diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 86989012ee..5816cef6af 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -283,6 +283,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLXMLNodeP } LLNotificationForm::LLNotificationForm(const LLSD& sd) + : mIgnore(IGNORE_NO) { if (sd.isArray()) { @@ -384,7 +385,8 @@ LLNotificationTemplate::LLNotificationTemplate() : mExpireSeconds(0), mExpireOption(-1), mURLOption(-1), - mURLOpenExternally(-1), + mURLOpenExternally(-1), + mPersist(false), mUnique(false), mPriority(NOTIFICATION_PRIORITY_NORMAL) { @@ -1058,6 +1060,7 @@ LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelN if(p == mChannels.end()) { llerrs << "Did not find channel named " << channelName << llendl; + return LLNotificationChannelPtr(); } return p->second; } diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index aeb4cebf1b..d55e0f4043 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -371,7 +371,7 @@ private: // this is just for making it easy to look things up in a set organized by UUID -- DON'T USE IT // for anything real! - LLNotification(LLUUID uuid) : mId(uuid) {} + LLNotification(LLUUID uuid) : mId(uuid), mCancelled(false), mRespondedTo(false), mIgnored(false), mTemporaryResponder(false) {} void cancel(); @@ -621,7 +621,7 @@ namespace LLNotificationComparators struct orderBy { typedef boost::function<T (LLNotificationPtr)> field_t; - orderBy(field_t field, EDirection = ORDER_INCREASING) : mField(field) {} + orderBy(field_t field, EDirection direction = ORDER_INCREASING) : mField(field), mDirection(direction) {} bool operator()(LLNotificationPtr lhs, LLNotificationPtr rhs) { if (mDirection == ORDER_DECREASING) diff --git a/indra/llui/llnotificationsutil.cpp b/indra/llui/llnotificationsutil.cpp index f343d27cb4..54bdb4bd66 100644 --- a/indra/llui/llnotificationsutil.cpp +++ b/indra/llui/llnotificationsutil.cpp @@ -94,3 +94,8 @@ void LLNotificationsUtil::cancel(LLNotificationPtr pNotif) { LLNotifications::instance().cancel(pNotif); } + +LLNotificationPtr LLNotificationsUtil::find(LLUUID uuid) +{ + return LLNotifications::instance().find(uuid); +} diff --git a/indra/llui/llnotificationsutil.h b/indra/llui/llnotificationsutil.h index d552fa915b..338204924a 100644 --- a/indra/llui/llnotificationsutil.h +++ b/indra/llui/llnotificationsutil.h @@ -65,6 +65,8 @@ namespace LLNotificationsUtil S32 getSelectedOption(const LLSD& notification, const LLSD& response); void cancel(LLNotificationPtr pNotif); + + LLNotificationPtr find(LLUUID uuid); } #endif diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 78386220d9..478e270c98 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1534,7 +1534,7 @@ LLRect LLScrollListCtrl::getCellRect(S32 row_index, S32 column_index) S32 rect_bottom = getRowOffsetFromIndex(row_index); LLScrollListColumn* columnp = getColumn(column_index); cell_rect.setOriginAndSize(rect_left, rect_bottom, - rect_left + columnp->getWidth(), mLineHeight); + /*rect_left + */columnp->getWidth(), mLineHeight); return cell_rect; } diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp index 71511f69a4..b8f93b6a0e 100644 --- a/indra/llui/llstyle.cpp +++ b/indra/llui/llstyle.cpp @@ -49,7 +49,10 @@ LLStyle::Params::Params() LLStyle::LLStyle(const LLStyle::Params& p) -: mVisible(p.visible), +: mItalic(FALSE), + mBold(FALSE), + mUnderline(FALSE), + mVisible(p.visible), mColor(p.color()), mReadOnlyColor(p.readonly_color()), mFont(p.font()), diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 43c44f2253..6be76605fd 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -1373,6 +1373,8 @@ BOOL LLTabContainer::setTab(S32 which) { LLTabTuple* tuple = *iter; BOOL is_selected = ( tuple == selected_tuple ); + tuple->mButton->setUseEllipses(TRUE); + tuple->mButton->setHAlign(LLFontGL::LEFT); tuple->mTabPanel->setVisible( is_selected ); // tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here. tuple->mButton->setToggleState( is_selected ); @@ -1478,63 +1480,54 @@ void LLTabContainer::setTabPanelFlashing(LLPanel* child, BOOL state ) void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const LLColor4& color) { - static LLUICachedControl<S32> tab_padding ("UITabPadding", 0); LLTabTuple* tuple = getTabByPanel(child); if( tuple ) { - tuple->mButton->setImageOverlay(image_name, LLFontGL::RIGHT, color); - - if (!mIsVertical) - { - // 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(mFont->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(); - } + tuple->mButton->setImageOverlay(image_name, LLFontGL::LEFT, color); + reshape_tuple(tuple); } } void LLTabContainer::setTabImage(LLPanel* child, const LLUUID& image_id, const LLColor4& color) { - static LLUICachedControl<S32> tab_padding ("UITabPadding", 0); LLTabTuple* tuple = getTabByPanel(child); if( tuple ) { - tuple->mButton->setImageOverlay(image_id, LLFontGL::RIGHT, color); + tuple->mButton->setImageOverlay(image_id, LLFontGL::LEFT, color); + reshape_tuple(tuple); + } +} - if (!mIsVertical) - { - // remove current width from total tab strip width - mTotalTabWidth -= tuple->mButton->getRect().getWidth(); +void LLTabContainer::reshape_tuple(LLTabTuple* tuple) +{ + static LLUICachedControl<S32> tab_padding ("UITabPadding", 0); + static LLUICachedControl<S32> image_left_padding ("UIButtonImageLeftPadding", 4); + static LLUICachedControl<S32> image_right_padding ("UIButtonImageRightPadding", 4); + static LLUICachedControl<S32> image_top_padding ("UIButtonImageTopPadding", 2); + static LLUICachedControl<S32> image_bottom_padding ("UIButtonImageBottomPadding", 2); - S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? - tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : - 0; + if (!mIsVertical) + { + tuple->mButton->setImageOverlayLeftPad(image_left_padding); + tuple->mButton->setImageOverlayRightPad(image_right_padding); + tuple->mButton->setImageOverlayTopPad(image_top_padding); + tuple->mButton->setImageOverlayBottomPad(image_bottom_padding); - tuple->mPadding = image_overlay_width; + // remove current width from total tab strip width + mTotalTabWidth -= tuple->mButton->getRect().getWidth(); - tuple->mButton->setRightHPad(6); - tuple->mButton->reshape(llclamp(mFont->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(); + S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? + tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : 0; - // tabs have changed size, might need to scroll to see current tab - updateMaxScrollPos(); - } + tuple->mPadding = image_overlay_width; + + tuple->mButton->reshape(llclamp(mFont->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(); } } @@ -1597,7 +1590,10 @@ void LLTabContainer::onTabBtn( const LLSD& data, LLPanel* panel ) LLTabTuple* tuple = getTabByPanel(panel); selectTabPanel( panel ); - tuple->mTabPanel->setFocus(TRUE); + if (tuple) + { + tuple->mTabPanel->setFocus(TRUE); + } } void LLTabContainer::onNextBtn( const LLSD& data ) diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 33c49e0d6f..2a55877d3c 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -228,6 +228,7 @@ private: // updates tab button images given the tuple, tab position and the corresponding params void update_images(LLTabTuple* tuple, TabParams params, LLTabContainer::TabPosition pos); + void reshape_tuple(LLTabTuple* tuple); // Variables diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 8abbc833e5..978bd317e2 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1512,25 +1512,6 @@ void LLTextBase::setText(const LLStringExplicit &utf8str, const LLStyle::Params& onValueChange(0, getLength()); } -void LLTextBase::addBlackListUrl(const std::string &url) -{ - mBlackListUrls.push_back(url); -} - -bool LLTextBase::isBlackListUrl(const std::string &url) const -{ - std::vector<std::string>::const_iterator it; - for (it = mBlackListUrls.begin(); it != mBlackListUrls.end(); ++it) - { - const std::string &blacklist_url = *it; - if (url.find(blacklist_url) != std::string::npos) - { - return true; - } - } - return false; -} - //virtual std::string LLTextBase::getText() const { @@ -1606,11 +1587,10 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c } } - // output the styled Url (unless we've been asked to suppress it) - if (isBlackListUrl(match.getUrl())) + // output the styled Url (unless we've been asked to suppress hyperlinking) + if (match.isLinkDisabled()) { - std::string orig_url = text.substr(start, end-start); - appendAndHighlightText(orig_url, prepend_newline, part, style_params); + appendAndHighlightText(match.getLabel(), prepend_newline, part, style_params); } else { diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index e1c6cc36ab..dc3671eab1 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -187,9 +187,6 @@ public: const LLFontGL* getDefaultFont() const { return mDefaultFont; } LLStyle::Params getDefaultStyle(); - // tell the text object to suppress auto highlighting of a specific URL - void addBlackListUrl(const std::string &url); - public: // Fired when a URL link is clicked commit_signal_t mURLClickSignal; @@ -312,7 +309,6 @@ protected: void updateRects(); void needsScroll() { mScrollNeeded = TRUE; } void replaceUrlLabel(const std::string &url, const std::string &label); - bool isBlackListUrl(const std::string &url) const; protected: // text segmentation and flow @@ -364,9 +360,6 @@ protected: LLView* mDocumentView; class LLScrollContainer* mScroller; - // list of URLs to suppress from automatic hyperlinking - std::vector<std::string> mBlackListUrls; - // transient state bool mReflowNeeded; // need to reflow text because of change to text contents or display region bool mScrollNeeded; // need to change scroll region because of change to cursor position diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 01c7a81309..173fde8e76 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -400,7 +400,8 @@ bool LLToolTip::hasClickCallback() // LLToolTipMgr::LLToolTipMgr() -: mToolTip(NULL), +: mToolTipsBlocked(false), + mToolTip(NULL), mNeedsToolTip(false) {} diff --git a/indra/llui/lluistring.h b/indra/llui/lluistring.h index 7ec0fd603a..32cfc0d9cd 100644 --- a/indra/llui/lluistring.h +++ b/indra/llui/lluistring.h @@ -64,7 +64,7 @@ class LLUIString public: // These methods all perform appropriate argument substitution // and modify mOrig where appropriate - LLUIString() {} + LLUIString() : mNeedsResult(false), mNeedsWResult(false) {} LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args); LLUIString(const std::string& instring) { assign(instring); } diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 4927e57a52..58148ad2aa 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -39,8 +39,9 @@ #include "lltrans.h" #include "lluicolortable.h" -LLUrlEntryBase::LLUrlEntryBase() -: mColor(LLUIColorTable::instance().getColor("HTMLLinkColor")) +LLUrlEntryBase::LLUrlEntryBase() : + mColor(LLUIColorTable::instance().getColor("HTMLLinkColor")), + mDisabledLink(false) { } @@ -204,7 +205,7 @@ LLUrlEntryHTTPNoProtocol::LLUrlEntryHTTPNoProtocol() mPattern = boost::regex("(" "\\bwww\\.\\S+\\.\\S+" // i.e. www.FOO.BAR "|" // or - "(?<!@)\\b[^[:space:]:@/]+\\.(?:com|net|edu|org)([/:]\\S*)?\\b" // i.e. FOO.net + "(?<!@)\\b[^[:space:]:@/>]+\\.(?:com|net|edu|org)([/:][^[:space:]<]*)?\\b" // i.e. FOO.net ")", boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_http.xml"; @@ -641,3 +642,20 @@ std::string LLUrlEntryWorldMap::getLocation(const std::string &url) const // return the part of the Url after secondlife:///app/worldmap/ part return ::getStringAfterToken(url, "app/worldmap/"); } + +// +// LLUrlEntryNoLink lets us turn of URL detection with <nolink>...</nolink> tags +// +LLUrlEntryNoLink::LLUrlEntryNoLink() +{ + mPattern = boost::regex("<nolink>[^[:space:]<]+</nolink>", + boost::regex::perl|boost::regex::icase); + mDisabledLink = true; +} + +std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ + // return the text between the <nolink> and </nolink> tags + return url.substr(8, url.size()-8-9); +} + diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 4adffde99c..94455ac247 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -91,6 +91,9 @@ public: /// Return the name of a SL location described by this Url, if any virtual std::string getLocation(const std::string &url) const { return ""; } + /// is this a match for a URL that should not be hyperlinked? + bool isLinkDisabled() const { return mDisabledLink; } + protected: std::string getIDStringFromUrl(const std::string &url) const; std::string escapeUrl(const std::string &url) const; @@ -111,6 +114,7 @@ protected: std::string mTooltip; LLUIColor mColor; std::multimap<std::string, LLUrlEntryObserver> mObservers; + bool mDisabledLink; }; /// @@ -267,4 +271,14 @@ public: /*virtual*/ std::string getLocation(const std::string &url) const; }; +/// +/// LLUrlEntryNoLink lets us turn of URL detection with <nolink>...</nolink> tags +/// +class LLUrlEntryNoLink : public LLUrlEntryBase +{ +public: + LLUrlEntryNoLink(); + /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); +}; + #endif diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp index 3b47145a22..72a199c220 100644 --- a/indra/llui/llurlmatch.cpp +++ b/indra/llui/llurlmatch.cpp @@ -41,14 +41,17 @@ LLUrlMatch::LLUrlMatch() : mLabel(""), mTooltip(""), mIcon(""), - mMenuName("") + mMenuName(""), + mLocation(""), + mDisabledLink(false) { } void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, const LLUIColor& color, - const std::string &menu, const std::string &location) + const std::string &menu, const std::string &location, + bool disabled_link) { mStart = start; mEnd = end; @@ -59,4 +62,5 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, mColor = color; mMenuName = menu; mLocation = location; + mDisabledLink = disabled_link; } diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h index 7f5767923a..e86762548b 100644 --- a/indra/llui/llurlmatch.h +++ b/indra/llui/llurlmatch.h @@ -83,11 +83,14 @@ public: /// return the SL location that this Url describes, or "" if none. std::string getLocation() const { return mLocation; } + /// is this a match for a URL that should not be hyperlinked? + bool isLinkDisabled() const { return mDisabledLink; } + /// Change the contents of this match object (used by LLUrlRegistry) void setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, const LLUIColor& color, const std::string &menu, - const std::string &location); + const std::string &location, bool disabled_link); private: U32 mStart; @@ -99,6 +102,7 @@ private: std::string mMenuName; std::string mLocation; LLUIColor mColor; + bool mDisabledLink; }; #endif diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index ad5c0911f8..55eb8950e9 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -44,6 +44,7 @@ void LLUrlRegistryNullCallback(const std::string &url, const std::string &label) LLUrlRegistry::LLUrlRegistry() { // Urls are matched in the order that they were registered + registerUrl(new LLUrlEntryNoLink()); registerUrl(new LLUrlEntrySLURL()); registerUrl(new LLUrlEntryHTTP()); registerUrl(new LLUrlEntryHTTPLabel()); @@ -176,7 +177,8 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL match_entry->getIcon(), match_entry->getColor(), match_entry->getMenuName(), - match_entry->getLocation(url)); + match_entry->getLocation(url), + match_entry->isLinkDisabled()); return true; } @@ -204,9 +206,13 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr S32 end = start + wurl.size() - 1; match.setValues(start, end, match.getUrl(), - match.getLabel(), match.getTooltip(), - match.getIcon(), match.getColor(), - match.getMenuName(), match.getLocation()); + match.getLabel(), + match.getTooltip(), + match.getIcon(), + match.getColor(), + match.getMenuName(), + match.getLocation(), + match.isLinkDisabled()); return true; } return false; diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 80be8fcbf7..bc97cf3df2 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -33,7 +33,7 @@ LLUIColor LLUIColorTable::getColor(const std::string& name, const LLColor4& defa return LLUIColor(); } -LLUIColor::LLUIColor() {} +LLUIColor::LLUIColor() : mColorPtr(NULL) {} namespace tut { @@ -610,5 +610,13 @@ namespace tut testRegex("invalid .net URL", r, "foo.netty", ""); + + testRegex("XML tags around URL [1]", r, + "<foo>secondlife.com</foo>", + "secondlife.com"); + + testRegex("XML tags around URL [2]", r, + "<foo>secondlife.com/status?bar=1</foo>", + "secondlife.com/status?bar=1"); } } diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp index e8cf135346..24a32de268 100644 --- a/indra/llui/tests/llurlmatch_test.cpp +++ b/indra/llui/tests/llurlmatch_test.cpp @@ -25,6 +25,7 @@ // link seam LLUIColor::LLUIColor() + : mColorPtr(NULL) {} namespace tut @@ -53,7 +54,7 @@ namespace tut LLUrlMatch match; ensure("empty()", match.empty()); - match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLUIColor(), "", ""); + match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLUIColor(), "", "", false); ensure("! empty()", ! match.empty()); } @@ -66,7 +67,7 @@ namespace tut LLUrlMatch match; ensure_equals("getStart() == 0", match.getStart(), 0); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); ensure_equals("getStart() == 10", match.getStart(), 10); } @@ -79,7 +80,7 @@ namespace tut LLUrlMatch match; ensure_equals("getEnd() == 0", match.getEnd(), 0); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); ensure_equals("getEnd() == 20", match.getEnd(), 20); } @@ -92,10 +93,10 @@ namespace tut LLUrlMatch match; ensure_equals("getUrl() == ''", match.getUrl(), ""); - match.setValues(10, 20, "http://slurl.com/", "", "", "", LLUIColor(), "", ""); + match.setValues(10, 20, "http://slurl.com/", "", "", "", LLUIColor(), "", "", false); ensure_equals("getUrl() == 'http://slurl.com/'", match.getUrl(), "http://slurl.com/"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); ensure_equals("getUrl() == '' (2)", match.getUrl(), ""); } @@ -108,10 +109,10 @@ namespace tut LLUrlMatch match; ensure_equals("getLabel() == ''", match.getLabel(), ""); - match.setValues(10, 20, "", "Label", "", "", LLUIColor(), "", ""); + match.setValues(10, 20, "", "Label", "", "", LLUIColor(), "", "", false); ensure_equals("getLabel() == 'Label'", match.getLabel(), "Label"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); ensure_equals("getLabel() == '' (2)", match.getLabel(), ""); } @@ -124,10 +125,10 @@ namespace tut LLUrlMatch match; ensure_equals("getTooltip() == ''", match.getTooltip(), ""); - match.setValues(10, 20, "", "", "Info", "", LLUIColor(), "", ""); + match.setValues(10, 20, "", "", "Info", "", LLUIColor(), "", "", false); ensure_equals("getTooltip() == 'Info'", match.getTooltip(), "Info"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); ensure_equals("getTooltip() == '' (2)", match.getTooltip(), ""); } @@ -140,10 +141,10 @@ namespace tut LLUrlMatch match; ensure_equals("getIcon() == ''", match.getIcon(), ""); - match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "", ""); + match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "", "", false); ensure_equals("getIcon() == 'Icon'", match.getIcon(), "Icon"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); ensure_equals("getIcon() == '' (2)", match.getIcon(), ""); } @@ -156,10 +157,10 @@ namespace tut LLUrlMatch match; ensure("getMenuName() empty", match.getMenuName().empty()); - match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", ""); + match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "", false); ensure_equals("getMenuName() == \"xui_file.xml\"", match.getMenuName(), "xui_file.xml"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); ensure("getMenuName() empty (2)", match.getMenuName().empty()); } @@ -172,10 +173,10 @@ namespace tut LLUrlMatch match; ensure("getLocation() empty", match.getLocation().empty()); - match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "Paris"); + match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "Paris", false); ensure_equals("getLocation() == \"Paris\"", match.getLocation(), "Paris"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", ""); + match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); ensure("getLocation() empty (2)", match.getLocation().empty()); } } |