diff options
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/lldockablefloater.h | 3 | ||||
-rw-r--r-- | indra/llui/lldockcontrol.h | 3 | ||||
-rw-r--r-- | indra/llui/llflatlistview.cpp | 8 | ||||
-rw-r--r-- | indra/llui/llhelp.h | 2 | ||||
-rw-r--r-- | indra/llui/llmenugl.cpp | 2 | ||||
-rw-r--r-- | indra/llui/llmenugl.h | 15 | ||||
-rw-r--r-- | indra/llui/llpanel.h | 1 | ||||
-rw-r--r-- | indra/llui/llscrollcontainer.cpp | 31 | ||||
-rw-r--r-- | indra/llui/lltextbase.cpp | 43 | ||||
-rw-r--r-- | indra/llui/lltextbase.h | 8 | ||||
-rw-r--r-- | indra/llui/lltexteditor.cpp | 3 | ||||
-rw-r--r-- | indra/llui/llui.cpp | 6 | ||||
-rw-r--r-- | indra/llui/lluictrl.cpp | 29 | ||||
-rw-r--r-- | indra/llui/lluictrl.h | 17 | ||||
-rw-r--r-- | indra/llui/lluiimage.cpp | 36 | ||||
-rw-r--r-- | indra/llui/lluiimage.h | 9 | ||||
-rw-r--r-- | indra/llui/llurlentry.cpp | 25 | ||||
-rw-r--r-- | indra/llui/llurlentry.h | 11 | ||||
-rw-r--r-- | indra/llui/llurlregistry.cpp | 18 |
19 files changed, 172 insertions, 98 deletions
diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h index 46491d8a29..2c339f4a3f 100644 --- a/indra/llui/lldockablefloater.h +++ b/indra/llui/lldockablefloater.h @@ -83,6 +83,8 @@ public: virtual void onDockHidden(); virtual void onDockShown(); + LLDockControl* getDockControl(); + private: /** * Provides unique of dockable floater. @@ -92,7 +94,6 @@ private: protected: void setDockControl(LLDockControl* dockControl); - LLDockControl* getDockControl(); const LLUIImagePtr& getDockTongue(); private: diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h index 30a45bedc7..550955c4c5 100644 --- a/indra/llui/lldockcontrol.h +++ b/indra/llui/lldockcontrol.h @@ -76,6 +76,9 @@ public: // gets a rect that bounds possible positions for a dockable control (EXT-1111) void getAllowedRect(LLRect& rect); + S32 getTongueWidth() { return mDockTongue->getWidth(); } + S32 getTongueHeight() { return mDockTongue->getHeight(); } + private: virtual void moveDockable(); private: diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 831ac66d06..64a4824a17 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -891,7 +891,13 @@ void LLFlatListView::setNoItemsCommentVisible(bool visible) const // We have to update child rect here because of issues with rect after reshaping while creating LLTextbox // It is possible to have invalid LLRect if Flat List is in LLAccordionTab LLRect comment_rect = getLocalRect(); - comment_rect.stretch(-getBorderWidth()); + + // To see comment correctly (EXT - 3244) in mNoItemsCommentTextbox we must get border width + // of LLFlatListView (@see getBorderWidth()) and stretch mNoItemsCommentTextbox to this width + // But getBorderWidth() returns 0 if LLFlatListView not visible. So we have to get border width + // from 'scroll_border' + LLViewBorder* scroll_border = getChild<LLViewBorder>("scroll border"); + comment_rect.stretch(-scroll_border->getBorderWidth()); mNoItemsCommentTextbox->setRect(comment_rect); } mNoItemsCommentTextbox->setVisible(visible); diff --git a/indra/llui/llhelp.h b/indra/llui/llhelp.h index 82c3bc385f..938419d374 100644 --- a/indra/llui/llhelp.h +++ b/indra/llui/llhelp.h @@ -42,6 +42,8 @@ class LLHelp virtual std::string defaultTopic() = 0; // return topic to use before the user logs in virtual std::string preLoginTopic() = 0; + // return topic to use for the top-level help, invoked by F1 + virtual std::string f1HelpTopic() = 0; }; #endif // headerguard diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 907f2352a0..fd5c2b7fef 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -761,7 +761,7 @@ void LLMenuItemCallGL::initFromParams(const Params& p) { if (p.on_visible.isProvided()) { - mVisibleSignal.connect(initVisibleCallback(p.on_visible)); + mVisibleSignal.connect(initEnableCallback(p.on_visible)); } if (p.on_enable.isProvided()) { diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index cbb9b4d344..61e06f9e5f 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -175,9 +175,7 @@ protected: // This function appends the character string representation of // the current accelerator key and mask to the provided string. void appendAcceleratorString( std::string& st ) const; - - void initMenuEnableCallback(const EnableCallbackParam& cb, enable_signal_t& sig); - + protected: KEY mAcceleratorKey; MASK mAcceleratorMask; @@ -249,7 +247,7 @@ public: { Optional<EnableCallbackParam > on_enable; Optional<CommitCallbackParam > on_click; - Optional<VisibleCallbackParam > on_visible; + Optional<EnableCallbackParam > on_visible; Params() : on_enable("on_enable"), on_click("on_click"), @@ -284,15 +282,10 @@ public: { return mEnableSignal.connect(cb); } - - boost::signals2::connection setVisibleCallback( const visible_signal_t::slot_type& cb ) - { - return mVisibleSignal.connect(cb); - } - + private: enable_signal_t mEnableSignal; - visible_signal_t mVisibleSignal; + enable_signal_t mVisibleSignal; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index a8bd5fd5e5..d0986a06d3 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -249,7 +249,6 @@ protected: LLCallbackMap::map_t mFactoryMap; CommitCallbackRegistry::ScopedRegistrar mCommitCallbackRegistrar; EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar; - VisibleCallbackRegistry::ScopedRegistrar mVisibleCallbackRegistrar; commit_signal_t* mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD() diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index f6caed4617..a5e47e8547 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -235,18 +235,37 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask) BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks ) { - if(LLUICtrl::handleScrollWheel(x,y,clicks)) + // Give event to my child views - they may have scroll bars + // (Bad UI design, but technically possible.) + if (LLUICtrl::handleScrollWheel(x,y,clicks)) return TRUE; - for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) - { - // Note: tries vertical and then horizontal + // When the vertical scrollbar is visible, scroll wheel + // only affects vertical scrolling. It's confusing to have + // scroll wheel perform both vertical and horizontal in a + // single container. + LLScrollbar* vertical = mScrollbar[VERTICAL]; + if (vertical->getVisible() + && vertical->getEnabled()) + { // Pretend the mouse is over the scrollbar - if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) ) + if (vertical->handleScrollWheel( 0, 0, clicks ) ) { updateScroll(); - return TRUE; } + // Always eat the event + return TRUE; + } + + LLScrollbar* horizontal = mScrollbar[HORIZONTAL]; + // Test enablement and visibility for consistency with + // LLView::childrenHandleScrollWheel(). + if (horizontal->getVisible() + && horizontal->getEnabled() + && horizontal->handleScrollWheel( 0, 0, clicks ) ) + { + updateScroll(); + return TRUE; } return FALSE; } diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 82a3c5cf47..e0503a0844 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -194,7 +194,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mHAlign(p.font_halign), mLineSpacingMult(p.line_spacing.multiple), mLineSpacingPixels(p.line_spacing.pixels), - mClipPartial(p.clip_partial), + mClipPartial(p.clip_partial && !p.allow_scroll), mTrackEnd( p.track_end ), mScrollIndex(-1), mSelectionStart( 0 ), @@ -529,11 +529,6 @@ void LLTextBase::drawText() S32 next_line = cur_line + 1; line_info& line = mLineInfoList[cur_line]; - if ((line.mRect.mTop - scrolled_view_rect.mBottom) < mTextRect.mBottom) - { - break; - } - S32 next_start = -1; S32 line_end = text_len; @@ -543,17 +538,9 @@ void LLTextBase::drawText() line_end = next_start; } - // A patch for EXT-1944 "Implement ellipses in message well" - // introduced a regression where text in SansSerif ending in the - // letter "r" is clipped. This may be due to an off-by-one in - // font width information out of FreeType with our fractional font - // sizes. For now, just make an extra pixel of space to resolve - // EXT-2971 "Letter R doesn't show when it's the last letter in a - // text block". See James/Richard for details. - const S32 FIX_CLIPPING_HACK = 1; LLRect text_rect(line.mRect.mLeft + mTextRect.mLeft - scrolled_view_rect.mLeft, line.mRect.mTop - scrolled_view_rect.mBottom + mTextRect.mBottom, - llmin(mDocumentView->getRect().getWidth(), line.mRect.mRight) - scrolled_view_rect.mLeft + FIX_CLIPPING_HACK, + llmin(mDocumentView->getRect().getWidth(), line.mRect.mRight) - scrolled_view_rect.mLeft, line.mRect.mBottom - scrolled_view_rect.mBottom + mTextRect.mBottom); // draw a single line of text @@ -1086,6 +1073,10 @@ void LLTextBase::reflow(S32 start_index) { mReflowNeeded = FALSE; + // shrink document to minimum size (visible portion of text widget) + // to force inlined widgets with follows set to shrink + mDocumentView->setShape(mTextRect); + bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false; LLRect old_cursor_rect = getLocalRectFromDocIndex(mCursorPos); @@ -1348,13 +1339,11 @@ std::pair<S32, S32> LLTextBase::getVisibleLines(bool fully_visible) if (fully_visible) { - // binary search for line that starts before top of visible buffer and starts before end of visible buffer first_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mTop, compare_top()); last_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mBottom, compare_bottom()); } else { - // binary search for line that starts before top of visible buffer and starts before end of visible buffer first_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mTop, compare_bottom()); last_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mBottom, compare_top()); } @@ -2091,6 +2080,8 @@ void LLTextBase::updateRects() } mContentsRect.mTop += mVPad; + // subtract a pixel off the bottom to deal with rounding errors in measuring font height + mContentsRect.mBottom -= 1; S32 delta_pos = -mContentsRect.mBottom; // move line segments to fit new document rect @@ -2105,7 +2096,7 @@ void LLTextBase::updateRects() LLRect doc_rect = mContentsRect; // use old mTextRect constraint document to width of viewable region doc_rect.mLeft = 0; - doc_rect.mRight = mTextRect.getWidth(); + doc_rect.mRight = llmax(mTextRect.getWidth(), mContentsRect.mRight); mDocumentView->setShape(doc_rect); @@ -2125,7 +2116,7 @@ void LLTextBase::updateRects() } // update document container again, using new mTextRect - doc_rect.mRight = doc_rect.mLeft + mTextRect.getWidth(); + doc_rect.mRight = llmax(mTextRect.getWidth(), mContentsRect.mRight); mDocumentView->setShape(doc_rect); } @@ -2218,6 +2209,12 @@ LLNormalTextSegment::LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 mEditor(editor) { mFontHeight = llceil(mStyle->getFont()->getLineHeight()); + + LLUIImagePtr image = mStyle->getImage(); + if (image.notNull()) + { + mImageLoadedConnection = image->addLoadedCallback(boost::bind(&LLTextBase::needsReflow, &mEditor)); + } } LLNormalTextSegment::LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible) @@ -2230,6 +2227,12 @@ LLNormalTextSegment::LLNormalTextSegment( const LLColor4& color, S32 start, S32 mFontHeight = llceil(mStyle->getFont()->getLineHeight()); } +LLNormalTextSegment::~LLNormalTextSegment() +{ + mImageLoadedConnection.disconnect(); +} + + F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) { if( end - start > 0 ) @@ -2243,7 +2246,7 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec // Center the image vertically S32 image_bottom = draw_rect.getCenterY() - (style_image_height/2); image->draw(draw_rect.mLeft, image_bottom, - style_image_width, style_image_height); + style_image_width, style_image_height, color); } return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect); diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index c60b040655..0138ca3704 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -136,7 +136,6 @@ public: // TODO: move into LLTextSegment? void createUrlContextMenu(S32 x, S32 y, const std::string &url); // create a popup context menu for the given Url - // Text accessors // TODO: add optional style parameter virtual void setText(const LLStringExplicit &utf8str , const LLStyle::Params& input_params = LLStyle::Params()); // uses default style @@ -148,6 +147,8 @@ public: LLWString getWText() const; void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params()); + // force reflow of text + void needsReflow() { mReflowNeeded = TRUE; } S32 getLength() const { return getWText().length(); } S32 getLineCount() const { return mLineInfoList.size(); } @@ -162,7 +163,6 @@ public: S32 getVPad() { return mVPad; } S32 getHPad() { return mHPad; } - S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const; LLRect getLocalRectFromDocIndex(S32 pos) const; LLRect getDocRectFromDocIndex(S32 pos) const; @@ -180,6 +180,7 @@ public: void changePage( S32 delta ); void changeLine( S32 delta ); + const LLFontGL* getDefaultFont() const { return mDefaultFont; } public: @@ -303,7 +304,6 @@ protected: // misc void updateRects(); - void needsReflow() { mReflowNeeded = TRUE; } void needsScroll() { mScrollNeeded = TRUE; } void replaceUrlLabel(const std::string &url, const std::string &label); @@ -426,6 +426,7 @@ class LLNormalTextSegment : public LLTextSegment public: LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextBase& editor ); LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE); + ~LLNormalTextSegment(); /*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; /*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const; @@ -457,6 +458,7 @@ protected: S32 mFontHeight; LLKeywordToken* mToken; std::string mTooltip; + boost::signals2::connection mImageLoadedConnection; }; class LLIndexSegment : public LLTextSegment diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index e68affc36c..faf9ccbeb8 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -1887,9 +1887,10 @@ void LLTextEditor::doDelete() removeChar(); } - onKeyStroke(); } + onKeyStroke(); + needsReflow(); } diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 4cf503b413..6603887905 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1847,8 +1847,8 @@ LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname) // spawn_x and spawn_y are top left corner of view in screen GL coordinates void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y) { - const S32 CURSOR_HEIGHT = 18; // Approximate "normal" cursor size - const S32 CURSOR_WIDTH = 9; + const S32 CURSOR_HEIGHT = 16; // Approximate "normal" cursor size + const S32 CURSOR_WIDTH = 8; LLView* parent = view->getParent(); @@ -1866,7 +1866,7 @@ void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y) LLRect virtual_window_rect = parent->getLocalRect(); LLRect mouse_rect; - const S32 MOUSE_CURSOR_PADDING = 5; + const S32 MOUSE_CURSOR_PADDING = 1; mouse_rect.setLeftTopAndSize(mouse_x - MOUSE_CURSOR_PADDING, mouse_y + MOUSE_CURSOR_PADDING, CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2, diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 706712ec5e..6044908ca7 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -232,11 +232,6 @@ bool default_enable_handler(LLUICtrl* ctrl, const LLSD& param) return true; } -bool default_visible_handler(LLUICtrl* ctrl, const LLSD& param) -{ - return true; -} - LLUICtrl::commit_signal_t::slot_type LLUICtrl::initCommitCallback(const CommitCallbackParam& cb) { @@ -290,30 +285,6 @@ LLUICtrl::enable_signal_t::slot_type LLUICtrl::initEnableCallback(const EnableCa return default_enable_handler; } -LLUICtrl::visible_signal_t::slot_type LLUICtrl::initVisibleCallback(const VisibleCallbackParam& cb) -{ - // Set the callback function - if (cb.function.isProvided()) - { - if (cb.parameter.isProvided()) - return boost::bind(cb.function(), this, cb.parameter); - else - return cb.function(); - } - else - { - visible_callback_t* func = (VisibleCallbackRegistry::getValue(cb.function_name)); - if (func) - { - if (cb.parameter.isProvided()) - return boost::bind((*func), this, cb.parameter); - else - return visible_signal_t::slot_type(*func); - } - } - return default_visible_handler; -} - // virtual void LLUICtrl::onMouseEnter(S32 x, S32 y, MASK mask) { diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index b20ff5d798..b9a4f61e15 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -63,9 +63,6 @@ public: typedef boost::function<bool (LLUICtrl* ctrl, const LLSD& param)> enable_callback_t; typedef boost::signals2::signal<bool (LLUICtrl* ctrl, const LLSD& param), boost_boolean_combiner> enable_signal_t; - typedef boost::function<bool (LLUICtrl* ctrl, const LLSD& param)> visible_callback_t; - typedef boost::signals2::signal<bool (LLUICtrl* ctrl, const LLSD& param), boost_boolean_combiner> visible_signal_t; - struct CallbackParam : public LLInitParam::Block<CallbackParam> { Ignored name; @@ -83,16 +80,12 @@ public: Optional<commit_callback_t> function; }; + // also used for visible callbacks struct EnableCallbackParam : public LLInitParam::Block<EnableCallbackParam, CallbackParam > { Optional<enable_callback_t> function; }; - - struct VisibleCallbackParam : public LLInitParam::Block<VisibleCallbackParam, CallbackParam > - { - Optional<visible_callback_t> function; - }; - + struct EnableControls : public LLInitParam::Choice<EnableControls> { Alternative<std::string> enabled; @@ -148,7 +141,6 @@ protected: commit_signal_t::slot_type initCommitCallback(const CommitCallbackParam& cb); enable_signal_t::slot_type initEnableCallback(const EnableCallbackParam& cb); - visible_signal_t::slot_type initVisibleCallback(const VisibleCallbackParam& cb); // We need this virtual so we can override it with derived versions virtual LLViewModel* getViewModel() const; @@ -269,10 +261,9 @@ public: {}; class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry>{}; + // the enable callback registry is also used for visiblity callbacks class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry>{}; - class VisibleCallbackRegistry : public CallbackRegistry<visible_callback_t, VisibleCallbackRegistry>{}; - - + protected: static bool controlListener(const LLSD& newvalue, LLHandle<LLUICtrl> handle, std::string type); diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp index a8683e55c3..f941f391eb 100644 --- a/indra/llui/lluiimage.cpp +++ b/indra/llui/lluiimage.cpp @@ -39,18 +39,20 @@ #include "lluiimage.h" #include "llui.h" -LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image) : - mName(name), - mImage(image), - mScaleRegion(0.f, 1.f, 1.f, 0.f), - mClipRegion(0.f, 1.f, 1.f, 0.f), - mUniformScaling(TRUE), - mNoClip(TRUE) +LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image) +: mName(name), + mImage(image), + mScaleRegion(0.f, 1.f, 1.f, 0.f), + mClipRegion(0.f, 1.f, 1.f, 0.f), + mUniformScaling(TRUE), + mNoClip(TRUE), + mImageLoaded(NULL) { } LLUIImage::~LLUIImage() { + delete mImageLoaded; } void LLUIImage::setClipRegion(const LLRectf& region) @@ -138,6 +140,25 @@ S32 LLUIImage::getTextureHeight() const return mImage->getHeight(0); } +boost::signals2::connection LLUIImage::addLoadedCallback( const image_loaded_signal_t::slot_type& cb ) +{ + if (!mImageLoaded) + { + mImageLoaded = new image_loaded_signal_t(); + } + return mImageLoaded->connect(cb); +} + + +void LLUIImage::onImageLoaded() +{ + if (mImageLoaded) + { + (*mImageLoaded)(); + } +} + + namespace LLInitParam { LLUIImage* TypedParam<LLUIImage*>::getValueFromBlock() const @@ -170,3 +191,4 @@ namespace LLInitParam return (a == b); } } + diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h index 9d734bcfdf..5fa9610ab2 100644 --- a/indra/llui/lluiimage.h +++ b/indra/llui/lluiimage.h @@ -39,6 +39,7 @@ #include "llrefcount.h" #include "llrect.h" #include <boost/function.hpp> +#include <boost/signals2.hpp> #include "llinitparam.h" #include "lltexture.h" @@ -47,6 +48,8 @@ extern const LLColor4 UI_VERTEX_COLOR; class LLUIImage : public LLRefCount { public: + typedef boost::signals2::signal<void (void)> image_loaded_signal_t; + LLUIImage(const std::string& name, LLPointer<LLTexture> image); virtual ~LLUIImage(); @@ -77,7 +80,13 @@ public: S32 getTextureWidth() const; S32 getTextureHeight() const; + boost::signals2::connection addLoadedCallback( const image_loaded_signal_t::slot_type& cb ); + + void onImageLoaded(); + protected: + image_loaded_signal_t* mImageLoaded; + std::string mName; LLRectf mScaleRegion; LLRectf mClipRegion; diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 7694d02837..7350457274 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -197,6 +197,31 @@ std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) } // +// LLUrlEntryHTTPNoProtocol Describes generic Urls like www.google.com +// +LLUrlEntryHTTPNoProtocol::LLUrlEntryHTTPNoProtocol() +{ + mPattern = boost::regex("(\\bwww\\.\\S+\\.\\S+|\\S+.com\\S*|\\S+.net\\S*|\\S+.edu\\S*|\\S+.org\\S*)", + boost::regex::perl|boost::regex::icase); + mMenuName = "menu_url_http.xml"; + mTooltip = LLTrans::getString("TooltipHttpUrl"); +} + +std::string LLUrlEntryHTTPNoProtocol::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ + return unescapeUrl(url); +} + +std::string LLUrlEntryHTTPNoProtocol::getUrl(const std::string &string) +{ + if (string.find("://") == std::string::npos) + { + return "http://" + escapeUrl(string); + } + return escapeUrl(string); +} + +// // LLUrlEntrySLURL Describes generic http: and https: Urls // LLUrlEntrySLURL::LLUrlEntrySLURL() diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index b3fb333fdd..4adffde99c 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -135,6 +135,17 @@ public: }; /// +/// LLUrlEntryHTTPNoProtocol Describes generic Urls like www.google.com +/// +class LLUrlEntryHTTPNoProtocol : public LLUrlEntryBase +{ +public: + LLUrlEntryHTTPNoProtocol(); + /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ std::string getUrl(const std::string &string); +}; + +/// /// LLUrlEntrySLURL Describes http://slurl.com/... Urls /// class LLUrlEntrySLURL : public LLUrlEntryBase diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index f47db2db1a..afcff0d409 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -58,6 +58,9 @@ LLUrlRegistry::LLUrlRegistry() //so it should be registered in the end of list registerUrl(new LLUrlEntrySL()); registerUrl(new LLUrlEntrySLLabel()); + // most common pattern is a URL without any protocol, + // e.g., "secondlife.com" + registerUrl(new LLUrlEntryHTTPNoProtocol()); } LLUrlRegistry::~LLUrlRegistry() @@ -118,10 +121,23 @@ static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &en return true; } +static bool stringHasUrl(const std::string &text) +{ + // fast heuristic test for a URL in a string. This is used + // to avoid lots of costly regex calls, BUT it needs to be + // kept in sync with the LLUrlEntry regexes we support. + return (text.find("://") != std::string::npos || + text.find("www.") != std::string::npos || + text.find(".com") != std::string::npos || + text.find(".net") != std::string::npos || + text.find(".edu") != std::string::npos || + text.find(".org") != std::string::npos); +} + bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb) { // avoid costly regexes if there is clearly no URL in the text - if (text.find("://") == std::string::npos) + if (! stringHasUrl(text)) { return false; } |