diff options
author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2010-02-22 14:15:58 -0500 |
---|---|---|
committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2010-02-22 14:15:58 -0500 |
commit | bd84d36c9d08878c895c896e097e8e3310b61cf3 (patch) | |
tree | e2e333ba15c131dfb25c4baf54bcb98fd2a3bd46 /indra/llui | |
parent | 00fdc0acd5e27d353c070706e838a35bf889a536 (diff) | |
parent | 04712617c55c53dbec1f73a4e8834ebe3167e5ed (diff) |
merge
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/llaccordionctrl.cpp | 97 | ||||
-rw-r--r-- | indra/llui/llaccordionctrl.h | 3 | ||||
-rw-r--r-- | indra/llui/llbutton.h | 2 | ||||
-rw-r--r-- | indra/llui/llconsole.cpp | 3 | ||||
-rw-r--r-- | indra/llui/llfloater.cpp | 18 | ||||
-rw-r--r-- | indra/llui/llkeywords.cpp | 82 | ||||
-rw-r--r-- | indra/llui/llkeywords.h | 29 | ||||
-rw-r--r-- | indra/llui/llmenugl.cpp | 40 | ||||
-rw-r--r-- | indra/llui/llmenugl.h | 10 | ||||
-rw-r--r-- | indra/llui/llpanel.cpp | 10 | ||||
-rw-r--r-- | indra/llui/llpanel.h | 8 | ||||
-rw-r--r-- | indra/llui/llresizehandle.cpp | 86 | ||||
-rw-r--r-- | indra/llui/llsearcheditor.cpp | 2 | ||||
-rw-r--r-- | indra/llui/lltabcontainer.cpp | 3 | ||||
-rw-r--r-- | indra/llui/lltextbase.cpp | 40 | ||||
-rw-r--r-- | indra/llui/lltextbase.h | 8 |
16 files changed, 339 insertions, 102 deletions
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index d0c73fbfbc..aa69dfe0cc 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -103,6 +103,13 @@ void LLAccordionCtrl::draw() LLLocalClipRect clip(local_rect); LLPanel::draw(); + /* + S32 width = getRect().getWidth(); + S32 height = getRect().getHeight(); + + gl_rect_2d(0, 0 , width - 1 ,height - 1,LLColor4::green,true); + gl_line_2d(0, 0 , width - 1 ,height - 1,LLColor4::black); + */ } @@ -338,36 +345,55 @@ void LLAccordionCtrl::addCollapsibleCtrl(LLView* view) } - -void LLAccordionCtrl::arrange() +void LLAccordionCtrl::arrangeSinge() { - if( mAccordionTabs.size() == 0) - { - //We do not arrange if we do not have what should be arranged - return; - } - - //Calculate params S32 panel_left = BORDER_MARGIN; // Margin from left side of Splitter S32 panel_top = getRect().getHeight() - BORDER_MARGIN; // Top coordinate of the first panel S32 panel_width = getRect().getWidth() - 4; // Top coordinate of the first panel + S32 panel_height; - - if(mAccordionTabs.size() == 1) + S32 collapsed_height = 0; + + for(size_t i=0;i<mAccordionTabs.size();++i) { - LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[0]); - - LLRect panel_rect = accordion_tab->getRect(); + LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]); - S32 panel_height = getRect().getHeight() - 2*BORDER_MARGIN; + if(accordion_tab->getVisible() == false) //skip hidden accordion tabs + continue; + if(!accordion_tab->isExpanded() ) + { + collapsed_height+=mAccordionTabs[i]->getRect().getHeight(); + } + } - ctrlSetLeftTopAndSize(accordion_tab,panel_rect.mLeft,panel_top,panel_width,panel_height); + S32 expanded_height = getRect().getHeight() - BORDER_MARGIN - collapsed_height; + + for(size_t i=0;i<mAccordionTabs.size();++i) + { + LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]); - show_hide_scrollbar(getRect().getWidth(),getRect().getHeight()); - return; - + if(accordion_tab->getVisible() == false) //skip hidden accordion tabs + continue; + if(!accordion_tab->isExpanded() ) + { + panel_height = accordion_tab->getRect().getHeight(); + } + else + { + panel_height = expanded_height; + } + ctrlSetLeftTopAndSize(mAccordionTabs[i], panel_left, panel_top, panel_width, panel_height); + panel_top-=mAccordionTabs[i]->getRect().getHeight(); } +} + +void LLAccordionCtrl::arrangeMultiple() +{ + S32 panel_left = BORDER_MARGIN; // Margin from left side of Splitter + S32 panel_top = getRect().getHeight() - BORDER_MARGIN; // Top coordinate of the first panel + S32 panel_width = getRect().getWidth() - 4; // Top coordinate of the first panel + //Calculate params for(size_t i = 0; i < mAccordionTabs.size(); i++ ) { LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]); @@ -415,7 +441,40 @@ void LLAccordionCtrl::arrange() show_hide_scrollbar(getRect().getWidth(),getRect().getHeight()); updateLayout(getRect().getWidth(),getRect().getHeight()); +} + + +void LLAccordionCtrl::arrange() +{ + if( mAccordionTabs.size() == 0) + { + //We do not arrange if we do not have what should be arranged + return; + } + + if(mAccordionTabs.size() == 1) + { + S32 panel_top = getRect().getHeight() - BORDER_MARGIN; // Top coordinate of the first panel + S32 panel_width = getRect().getWidth() - 4; // Top coordinate of the first panel + + LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[0]); + + LLRect panel_rect = accordion_tab->getRect(); + + S32 panel_height = getRect().getHeight() - 2*BORDER_MARGIN; + + ctrlSetLeftTopAndSize(accordion_tab,panel_rect.mLeft,panel_top,panel_width,panel_height); + + show_hide_scrollbar(getRect().getWidth(),getRect().getHeight()); + return; + + } + + if(mSingleExpansion) + arrangeSinge (); + else + arrangeMultiple (); } //--------------------------------------------------------------------------------- diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h index d57a42df32..7c29e545b7 100644 --- a/indra/llui/llaccordionctrl.h +++ b/indra/llui/llaccordionctrl.h @@ -105,6 +105,9 @@ public: void reset (); private: + void arrangeSinge(); + void arrangeMultiple(); + // Calc Splitter's height that is necessary to display all child content S32 calcRecuiredHeight(); S32 getRecuiredHeight() const { return mInnerRect.getHeight(); } diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 8f35db1007..6a0d8ef3d6 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -257,6 +257,8 @@ public: void setForcePressedState(bool b) { mForcePressedState = b; } + void setAutoResize(bool auto_resize) { mAutoResize = auto_resize; } + protected: LLPointer<LLUIImage> getImageUnselected() const { return mImageUnselected; } LLPointer<LLUIImage> getImageSelected() const { return mImageSelected; } diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp index a4f69e7ac1..badbddc3cc 100644 --- a/indra/llui/llconsole.cpp +++ b/indra/llui/llconsole.cpp @@ -300,7 +300,8 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, const LLFontGL* font, b S32 paragraph_offset = 0; //Offset into the paragraph text. // Wrap lines that are longer than the view is wide. - while( paragraph_offset < (S32)mParagraphText.length() ) + while( paragraph_offset < (S32)mParagraphText.length() && + mParagraphText[paragraph_offset] != 0) { S32 skip_chars; // skip '\n' // Figure out if a word-wrapped line fits here. diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 0199fe3f57..b6d73cda3c 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1574,22 +1574,25 @@ void LLFloater::draw() LLUIImage* image = NULL; LLColor4 color; + LLColor4 overlay_color; if (isBackgroundOpaque()) { // NOTE: image may not be set image = getBackgroundImage(); color = getBackgroundColor(); + overlay_color = getBackgroundImageOverlay(); } else { image = getTransparentImage(); color = getTransparentColor(); + overlay_color = getTransparentImageOverlay(); } if (image) { // We're using images for this floater's backgrounds - image->draw(getLocalRect(), UI_VERTEX_COLOR % alpha); + image->draw(getLocalRect(), overlay_color % alpha); } else { @@ -2387,10 +2390,17 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out LLRect new_rect; new_rect.setLeftTopAndSize(view_rect.mLeft,view_rect.mTop,new_width, new_height); - floater->reshape( new_width, new_height, TRUE ); - floater->setRect(new_rect); + floater->setShape(new_rect); - floater->translateIntoRect( getLocalRect(), false ); + if (floater->followsRight()) + { + floater->translate(old_width - new_width, 0); + } + + if (floater->followsTop()) + { + floater->translate(0, old_height - new_height); + } } } diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index ede32084d0..75342afbe2 100644 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -218,6 +218,86 @@ void LLKeywords::addToken(LLKeywordToken::TOKEN_TYPE type, llassert(0); } } +LLKeywords::WStringMapIndex::WStringMapIndex(const WStringMapIndex& other) +{ + if(other.mOwner) + { + copyData(other.mData, other.mLength); + } + else + { + mOwner = false; + mLength = other.mLength; + mData = other.mData; + } +} + +LLKeywords::WStringMapIndex::WStringMapIndex(const LLWString& str) +{ + copyData(str.data(), str.size()); +} + +LLKeywords::WStringMapIndex::WStringMapIndex(const llwchar *start, size_t length): +mData(start), mLength(length), mOwner(false) +{ +} + +LLKeywords::WStringMapIndex::~WStringMapIndex() +{ + if(mOwner) + delete[] mData; +} + +void LLKeywords::WStringMapIndex::copyData(const llwchar *start, size_t length) +{ + llwchar *data = new llwchar[length]; + memcpy((void*)data, (const void*)start, length * sizeof(llwchar)); + + mOwner = true; + mLength = length; + mData = data; +} + +bool LLKeywords::WStringMapIndex::operator<(const LLKeywords::WStringMapIndex &other) const +{ + // NOTE: Since this is only used to organize a std::map, it doesn't matter if it uses correct collate order or not. + // The comparison only needs to strictly order all possible strings, and be stable. + + bool result = false; + const llwchar* self_iter = mData; + const llwchar* self_end = mData + mLength; + const llwchar* other_iter = other.mData; + const llwchar* other_end = other.mData + other.mLength; + + while(true) + { + if(other_iter >= other_end) + { + // We've hit the end of other. + // This covers two cases: other being shorter than self, or the strings being equal. + // In either case, we want to return false. + result = false; + break; + } + else if(self_iter >= self_end) + { + // self is shorter than other. + result = true; + break; + } + else if(*self_iter != *other_iter) + { + // The current character differs. The strings are not equal. + result = *self_iter < *other_iter; + break; + } + + self_iter++; + other_iter++; + } + + return result; +} LLColor3 LLKeywords::readColor( const std::string& s ) { @@ -429,7 +509,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW S32 seg_len = p - cur; if( seg_len > 0 ) { - LLWString word( cur, 0, seg_len ); + WStringMapIndex word( cur, seg_len ); word_token_map_t::iterator map_iter = mWordTokenMap.find(word); if( map_iter != mWordTokenMap.end() ) { diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h index 53377869ca..e5b66dfa56 100644 --- a/indra/llui/llkeywords.h +++ b/indra/llui/llkeywords.h @@ -92,8 +92,33 @@ public: const std::string& key, const LLColor3& color, const std::string& tool_tip = LLStringUtil::null); - - typedef std::map<LLWString, LLKeywordToken*> word_token_map_t; + + // This class is here as a performance optimization. + // The word token map used to be defined as std::map<LLWString, LLKeywordToken*>. + // This worked, but caused a performance bottleneck due to memory allocation and string copies + // because it's not possible to search such a map without creating an LLWString. + // Using this class as the map index instead allows us to search using segments of an existing + // text run without copying them first, which greatly reduces overhead in LLKeywords::findSegments(). + class WStringMapIndex + { + public: + // copy constructor + WStringMapIndex(const WStringMapIndex& other); + // constructor from a string (copies the string's data into the new object) + WStringMapIndex(const LLWString& str); + // constructor from pointer and length + // NOTE: does NOT copy data, caller must ensure that the lifetime of the pointer exceeds that of the new object! + WStringMapIndex(const llwchar *start, size_t length); + ~WStringMapIndex(); + bool operator<(const WStringMapIndex &other) const; + private: + void copyData(const llwchar *start, size_t length); + const llwchar *mData; + size_t mLength; + bool mOwner; + }; + + typedef std::map<WStringMapIndex, 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(); } diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index d18abbfb2f..0d56c5ed31 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -657,11 +657,38 @@ LLMenuItemVerticalSeparatorGL::LLMenuItemVerticalSeparatorGL( void ) // Class LLMenuItemTearOffGL //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LLMenuItemTearOffGL::LLMenuItemTearOffGL(const LLMenuItemTearOffGL::Params& p) -: LLMenuItemGL(p), - mParentHandle(p.parent_floater_handle) +: LLMenuItemGL(p) { } +// Returns the first floater ancestor if there is one +LLFloater* LLMenuItemTearOffGL::getParentFloater() +{ + LLView* parent_view = getMenu(); + + while (parent_view) + { + if (dynamic_cast<LLFloater*>(parent_view)) + { + return dynamic_cast<LLFloater*>(parent_view); + } + + bool parent_is_menu = dynamic_cast<LLMenuGL*>(parent_view) && !dynamic_cast<LLMenuBarGL*>(parent_view); + + if (parent_is_menu) + { + // use menu parent + parent_view = dynamic_cast<LLMenuGL*>(parent_view)->getParentMenuItem(); + } + else + { + // just use regular view parent + parent_view = parent_view->getParent(); + } + } + + return NULL; +} void LLMenuItemTearOffGL::onCommit() { @@ -680,7 +707,7 @@ void LLMenuItemTearOffGL::onCommit() getMenu()->needsArrange(); - LLFloater* parent_floater = mParentHandle.get(); + LLFloater* parent_floater = getParentFloater(); LLFloater* tear_off_menu = LLTearOffMenu::create(getMenu()); if (tear_off_menu) @@ -1671,7 +1698,6 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p) mSpilloverMenu(NULL), mJumpKey(p.jump_key), mCreateJumpKeys(p.create_jump_keys), - mParentFloaterHandle(p.parent_floater), mNeedsArrange(FALSE), mShortcutPad(p.shortcut_pad) { @@ -1699,7 +1725,7 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p) void LLMenuGL::initFromParams(const LLMenuGL::Params& p) { LLUICtrl::initFromParams(p); - setCanTearOff(p.can_tear_off, p.parent_floater); + setCanTearOff(p.can_tear_off); } // Destroys the object @@ -1711,12 +1737,11 @@ LLMenuGL::~LLMenuGL( void ) mJumpKeys.clear(); } -void LLMenuGL::setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_handle ) +void LLMenuGL::setCanTearOff(BOOL tear_off) { if (tear_off && mTearOffItem == NULL) { LLMenuItemTearOffGL::Params p; - p.parent_floater_handle = parent_floater_handle; mTearOffItem = LLUICtrlFactory::create<LLMenuItemTearOffGL>(p); addChildInBack(mTearOffItem); } @@ -2233,7 +2258,6 @@ void LLMenuGL::createSpilloverBranch() LLMenuGL::Params p; p.name("More"); p.label("More"); // *TODO: Translate - p.parent_floater(mParentFloaterHandle); p.bg_color(mBackgroundColor); p.bg_visible(true); p.can_tear_off(false); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 8441aaadd4..39d1986461 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -355,7 +355,6 @@ class LLMenuGL public: struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> { - Optional<LLHandle<LLFloater> > parent_floater; Optional<KEY> jump_key; Optional<bool> horizontal_layout, can_tear_off, @@ -430,7 +429,7 @@ public: void setBackgroundColor( const LLUIColor& color ) { mBackgroundColor = color; } const LLUIColor& getBackgroundColor() const { return mBackgroundColor; } void setBackgroundVisible( BOOL b ) { mBgVisible = b; } - void setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>()); + void setCanTearOff(BOOL tear_off); // add a separator to this menu virtual BOOL addSeparator(); @@ -553,7 +552,6 @@ private: class LLMenuItemTearOffGL* mTearOffItem; class LLMenuItemBranchGL* mSpilloverBranch; LLMenuGL* mSpilloverMenu; - LLHandle<LLFloater> mParentFloaterHandle; KEY mJumpKey; BOOL mCreateJumpKeys; S32 mShortcutPad; @@ -814,7 +812,6 @@ class LLMenuItemTearOffGL : public LLMenuItemGL public: struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params> { - Optional<LLHandle<LLFloater> > parent_floater_handle; Params() { name = "tear off"; @@ -823,13 +820,12 @@ public: }; LLMenuItemTearOffGL( const Params& ); - + virtual void onCommit(void); virtual void draw(void); virtual U32 getNominalHeight() const; -private: - LLHandle<LLFloater> mParentHandle; + LLFloater* getParentFloater(); }; diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index d963cf4c98..0cd052eefa 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -80,6 +80,8 @@ LLPanel::Params::Params() background_opaque("background_opaque", false), bg_opaque_color("bg_opaque_color"), bg_alpha_color("bg_alpha_color"), + bg_opaque_image_overlay("bg_opaque_image_overlay"), + bg_alpha_image_overlay("bg_alpha_image_overlay"), bg_opaque_image("bg_opaque_image"), bg_alpha_image("bg_alpha_image"), min_width("min_width", 100), @@ -103,6 +105,8 @@ LLPanel::LLPanel(const LLPanel::Params& p) mBgOpaque(p.background_opaque), mBgOpaqueColor(p.bg_opaque_color()), mBgAlphaColor(p.bg_alpha_color()), + mBgOpaqueImageOverlay(p.bg_opaque_image_overlay), + mBgAlphaImageOverlay(p.bg_alpha_image_overlay), mBgOpaqueImage(p.bg_opaque_image()), mBgAlphaImage(p.bg_alpha_image()), mDefaultBtn(NULL), @@ -199,7 +203,7 @@ void LLPanel::draw() // opaque, in-front look if (mBgOpaqueImage.notNull()) { - mBgOpaqueImage->draw( local_rect, UI_VERTEX_COLOR % alpha ); + mBgOpaqueImage->draw( local_rect, mBgOpaqueImageOverlay % alpha ); } else { @@ -212,7 +216,7 @@ void LLPanel::draw() // transparent, in-back look if (mBgAlphaImage.notNull()) { - mBgAlphaImage->draw( local_rect, UI_VERTEX_COLOR % alpha ); + mBgAlphaImage->draw( local_rect, mBgAlphaImageOverlay % alpha ); } else { @@ -481,6 +485,8 @@ void LLPanel::initFromParams(const LLPanel::Params& p) setTransparentColor(p.bg_alpha_color().get()); mBgOpaqueImage = p.bg_opaque_image(); mBgAlphaImage = p.bg_alpha_image(); + mBgOpaqueImageOverlay = p.bg_opaque_image_overlay; + mBgAlphaImageOverlay = p.bg_alpha_image_overlay; } static LLFastTimer::DeclareTimer FTM_PANEL_SETUP("Panel Setup"); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index 4e53fd7ea3..03e3dc0c0e 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -77,7 +77,9 @@ public: background_opaque; Optional<LLUIColor> bg_opaque_color, - bg_alpha_color; + bg_alpha_color, + bg_opaque_image_overlay, + bg_alpha_image_overlay; // opaque image is for "panel in foreground" look Optional<LLUIImage*> bg_opaque_image, bg_alpha_image; @@ -137,6 +139,8 @@ public: const LLColor4& getTransparentColor() const { return mBgAlphaColor; } LLPointer<LLUIImage> getBackgroundImage() const { return mBgOpaqueImage; } LLPointer<LLUIImage> getTransparentImage() const { return mBgAlphaImage; } + LLColor4 getBackgroundImageOverlay() { return mBgOpaqueImageOverlay; } + LLColor4 getTransparentImageOverlay() { return mBgAlphaImageOverlay; } void setBackgroundVisible( BOOL b ) { mBgVisible = b; } BOOL isBackgroundVisible() const { return mBgVisible; } void setBackgroundOpaque(BOOL b) { mBgOpaque = b; } @@ -262,6 +266,8 @@ private: BOOL mBgOpaque; // use opaque color or image LLUIColor mBgOpaqueColor; LLUIColor mBgAlphaColor; + LLUIColor mBgOpaqueImageOverlay; + LLUIColor mBgAlphaImageOverlay; LLPointer<LLUIImage> mBgOpaqueImage; // "panel in front" look LLPointer<LLUIImage> mBgAlphaImage; // "panel in back" look LLViewBorder* mBorder; diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp index 3df09d124a..00214d451c 100644 --- a/indra/llui/llresizehandle.cpp +++ b/indra/llui/llresizehandle.cpp @@ -124,7 +124,7 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask) { // Make sure the mouse in still over the application. We don't want to make the parent // so big that we can't see the resize handle any more. - + S32 screen_x; S32 screen_y; localPointToScreen(x, y, &screen_x, &screen_y); @@ -136,9 +136,10 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask) if( resizing_view ) { // undock floater when user resize it - if (((LLFloater*)getParent())->isDocked()) + LLFloater* floater_parent = dynamic_cast<LLFloater*>(getParent()); + if (floater_parent && floater_parent->isDocked()) { - ((LLFloater*)getParent())->setDocked(false, false); + floater_parent->setDocked(false, false); } // Resize the parent @@ -146,61 +147,68 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask) LLRect scaled_rect = orig_rect; S32 delta_x = screen_x - mDragLastScreenX; S32 delta_y = screen_y - mDragLastScreenY; - - if(delta_x == 0 && delta_y == 0) - return FALSE; - LLCoordGL mouse_dir; // use hysteresis on mouse motion to preserve user intent when mouse stops moving mouse_dir.mX = (screen_x == mLastMouseScreenX) ? mLastMouseDir.mX : screen_x - mLastMouseScreenX; mouse_dir.mY = (screen_y == mLastMouseScreenY) ? mLastMouseDir.mY : screen_y - mLastMouseScreenY; - mLastMouseScreenX = screen_x; mLastMouseScreenY = screen_y; mLastMouseDir = mouse_dir; - S32 new_width = orig_rect.getWidth(); - S32 new_height = orig_rect.getHeight(); + S32 x_multiple = 1; + S32 y_multiple = 1; + switch( mCorner ) + { + case LEFT_TOP: + x_multiple = -1; + y_multiple = 1; + break; + case LEFT_BOTTOM: + x_multiple = -1; + y_multiple = -1; + break; + case RIGHT_TOP: + x_multiple = 1; + y_multiple = 1; + break; + case RIGHT_BOTTOM: + x_multiple = 1; + y_multiple = -1; + break; + } - S32 new_pos_x = orig_rect.mLeft; - S32 new_pos_y = orig_rect.mTop; + S32 new_width = orig_rect.getWidth() + x_multiple * delta_x; + if( new_width < mMinWidth ) + { + new_width = mMinWidth; + delta_x = x_multiple * (mMinWidth - orig_rect.getWidth()); + } + + S32 new_height = orig_rect.getHeight() + y_multiple * delta_y; + if( new_height < mMinHeight ) + { + new_height = mMinHeight; + delta_y = y_multiple * (mMinHeight - orig_rect.getHeight()); + } switch( mCorner ) { - case LEFT_TOP: - new_width-=delta_x; - new_height+=delta_y; - new_pos_x+=delta_x; - new_pos_y+=delta_y; + case LEFT_TOP: + scaled_rect.translate(delta_x, 0); break; case LEFT_BOTTOM: - new_width-=delta_x; - new_height-=delta_y; - new_pos_x+=delta_x; + scaled_rect.translate(delta_x, delta_y); break; case RIGHT_TOP: - new_width+=delta_x; - new_height+=delta_y; - new_pos_y+=delta_y; break; case RIGHT_BOTTOM: - new_width+=delta_x; - new_height-=delta_y; + scaled_rect.translate(0, delta_y); break; } - new_width = llmax(new_width,mMinWidth); - new_height = llmax(new_height,mMinHeight); - - LLRect::tCoordType screen_width = resizing_view->getParent()->getSnapRect().getWidth(); - LLRect::tCoordType screen_height = resizing_view->getParent()->getSnapRect().getHeight(); - - new_width = llmin(new_width, screen_width); - new_height = llmin(new_height, screen_height); - // temporarily set new parent rect - scaled_rect.setLeftTopAndSize(new_pos_x,new_pos_y,new_width,new_height); - + scaled_rect.mRight = scaled_rect.mLeft + new_width; + scaled_rect.mTop = scaled_rect.mBottom + new_height; resizing_view->setRect(scaled_rect); LLView* snap_view = NULL; @@ -251,11 +259,7 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask) resizing_view->setRect(orig_rect); // translate and scale to new shape - resizing_view->reshape(scaled_rect.getWidth(),scaled_rect.getHeight()); - resizing_view->setRect(scaled_rect); - //set shape to handle dependent floaters... - resizing_view->handleReshape(scaled_rect, false); - + resizing_view->setShape(scaled_rect, true); // update last valid mouse cursor position based on resized view's actual size LLRect new_rect = resizing_view->getRect(); diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index 491eeeab54..8075575bab 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -156,7 +156,7 @@ void LLSearchEditor::setFocus( BOOL b ) void LLSearchEditor::onClearButtonClick(const LLSD& data) { setText(LLStringUtil::null); - mSearchEditor->doDelete(); // force keystroke callback + mSearchEditor->onCommit(); // force keystroke callback } void LLSearchEditor::handleKeystroke() diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index e810b6fe8f..07e4cc22e0 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -214,7 +214,8 @@ LLTabContainer::Params::Params() last_tab("last_tab"), use_custom_icon_ctrl("use_custom_icon_ctrl", false), tab_icon_ctrl_pad("tab_icon_ctrl_pad", 0), - use_ellipses("use_ellipses") + use_ellipses("use_ellipses"), + font_halign("halign") { name(std::string("tab_container")); mouse_opaque = false; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index b84e6f45fb..851fb966ec 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1445,10 +1445,10 @@ LLTextBase::segment_set_t::const_iterator LLTextBase::getSegIterContaining(S32 i } // Finds the text segment (if any) at the give local screen position -LLTextSegmentPtr LLTextBase::getSegmentAtLocalPos( S32 x, S32 y ) +LLTextSegmentPtr LLTextBase::getSegmentAtLocalPos( S32 x, S32 y, bool hit_past_end_of_line) { // Find the cursor position at the requested local screen position - S32 offset = getDocIndexFromLocalCoord( x, y, FALSE ); + S32 offset = getDocIndexFromLocalCoord( x, y, FALSE, hit_past_end_of_line); segment_set_t::iterator seg_iter = getSegIterContaining(offset); if (seg_iter != mSegments.end()) { @@ -1788,7 +1788,7 @@ const LLWString& LLTextBase::getWText() const // will be put to its right. If round is false, the cursor will always be put to the // character's left. -S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const +S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line) const { // Figure out which line we're nearest to. LLRect visible_region = getVisibleDocumentRect(); @@ -1817,7 +1817,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round S32 text_width, text_height; segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height); if (local_x < start_x + text_width // cursor to left of right edge of text - || segmentp->getEnd() >= line_iter->mDocIndexEnd - 1) // or this segment wraps to next line + || (hit_past_end_of_line && (segmentp->getEnd() >= line_iter->mDocIndexEnd - 1))) // or this segment wraps to next line { // Figure out which character we're nearest to. S32 offset; @@ -2402,8 +2402,12 @@ BOOL LLNormalTextSegment::handleHover(S32 x, S32 y, MASK mask) { if (getStyle() && getStyle()->isLink()) { - LLUI::getWindow()->setCursor(UI_CURSOR_HAND); - return TRUE; + // Only process the click if it's actually in this segment, not to the right of the end-of-line. + if(mEditor.getSegmentAtLocalPos(x, y, false) == this) + { + LLUI::getWindow()->setCursor(UI_CURSOR_HAND); + return TRUE; + } } return FALSE; } @@ -2412,8 +2416,12 @@ BOOL LLNormalTextSegment::handleRightMouseDown(S32 x, S32 y, MASK mask) { if (getStyle() && getStyle()->isLink()) { - mEditor.createUrlContextMenu(x, y, getStyle()->getLinkHREF()); - return TRUE; + // Only process the click if it's actually in this segment, not to the right of the end-of-line. + if(mEditor.getSegmentAtLocalPos(x, y, false) == this) + { + mEditor.createUrlContextMenu(x, y, getStyle()->getLinkHREF()); + return TRUE; + } } return FALSE; } @@ -2422,8 +2430,12 @@ BOOL LLNormalTextSegment::handleMouseDown(S32 x, S32 y, MASK mask) { if (getStyle() && getStyle()->isLink()) { - // eat mouse down event on hyperlinks, so we get the mouse up - return TRUE; + // Only process the click if it's actually in this segment, not to the right of the end-of-line. + if(mEditor.getSegmentAtLocalPos(x, y, false) == this) + { + // eat mouse down event on hyperlinks, so we get the mouse up + return TRUE; + } } return FALSE; @@ -2433,8 +2445,12 @@ BOOL LLNormalTextSegment::handleMouseUp(S32 x, S32 y, MASK mask) { if (getStyle() && getStyle()->isLink()) { - LLUrlAction::clickAction(getStyle()->getLinkHREF()); - return TRUE; + // Only process the click if it's actually in this segment, not to the right of the end-of-line. + if(mEditor.getSegmentAtLocalPos(x, y, false) == this) + { + LLUrlAction::clickAction(getStyle()->getLinkHREF()); + return TRUE; + } } return FALSE; diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 3dda6f4cc8..5b24c63557 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -48,6 +48,7 @@ class LLContextMenu; class LLTextSegment; +class LLNormalTextSegment; typedef LLPointer<LLTextSegment> LLTextSegmentPtr; @@ -61,6 +62,9 @@ class LLTextBase protected LLEditMenuHandler { public: + friend class LLTextSegment; + friend class LLNormalTextSegment; + struct LineSpacingParams : public LLInitParam::Choice<LineSpacingParams> { Alternative<F32> multiple; @@ -165,7 +169,7 @@ public: S32 getVPad() { return mVPad; } S32 getHPad() { return mHPad; } - S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const; + S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line = true) const; LLRect getLocalRectFromDocIndex(S32 pos) const; LLRect getDocRectFromDocIndex(S32 pos) const; @@ -275,7 +279,7 @@ protected: // manage segments void getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const; void getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp ); - LLTextSegmentPtr getSegmentAtLocalPos( S32 x, S32 y ); + LLTextSegmentPtr getSegmentAtLocalPos( S32 x, S32 y, bool hit_past_end_of_line = true); segment_set_t::iterator getSegIterContaining(S32 index); segment_set_t::const_iterator getSegIterContaining(S32 index) const; void clearSegments(); |