summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llscrollcontainer.cpp31
-rw-r--r--indra/llui/lltextbase.cpp41
-rw-r--r--indra/llui/lltextbase.h8
-rw-r--r--indra/llui/llui.cpp6
-rw-r--r--indra/llui/lluiimage.cpp36
-rw-r--r--indra/llui/lluiimage.h9
6 files changed, 92 insertions, 39 deletions
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..2a9515171a 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());
}
@@ -2105,7 +2094,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 +2114,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 +2207,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 +2225,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 +2244,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/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/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;