summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorKent Quirk <q@lindenlab.com>2010-02-18 20:36:47 -0500
committerKent Quirk <q@lindenlab.com>2010-02-18 20:36:47 -0500
commit6b48a59c9994b746a5f1ba2c7d74688ddc6d5215 (patch)
treebdec31d68e51269ee3c534e22e922c468d7e032e /indra
parent2d00beeed20d7fff74252099817776aeba399b42 (diff)
parentc4b42ca78ff214eef66e9fafa369edd3c4ac08c0 (diff)
merge changes from backing out the directory change of default to base
Diffstat (limited to 'indra')
-rw-r--r--indra/llrender/llfontfreetype.cpp23
-rw-r--r--indra/llrender/llfontfreetype.h2
-rw-r--r--indra/llrender/llfontgl.cpp57
-rw-r--r--indra/llui/llfloater.cpp13
-rw-r--r--indra/llui/llkeywords.cpp82
-rw-r--r--indra/llui/llkeywords.h29
-rw-r--r--indra/llui/llmenugl.cpp40
-rw-r--r--indra/llui/llmenugl.h10
-rw-r--r--indra/llui/llresizehandle.cpp86
-rw-r--r--indra/llui/lltextbase.cpp40
-rw-r--r--indra/llui/lltextbase.h8
-rw-r--r--indra/newview/app_settings/settings.xml13
-rw-r--r--indra/newview/llagentwearables.cpp1
-rw-r--r--indra/newview/llbottomtray.cpp2
-rw-r--r--indra/newview/llfloaterpreference.cpp26
-rw-r--r--indra/newview/llpanelnearbymedia.cpp31
-rw-r--r--indra/newview/llpanelnearbymedia.h10
-rw-r--r--indra/newview/lltexlayer.cpp4
-rw-r--r--indra/newview/llvieweraudio.cpp2
-rw-r--r--indra/newview/llviewermedia.cpp3
-rw-r--r--indra/newview/llvoiceclient.cpp15
21 files changed, 350 insertions, 147 deletions
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index 22fad792da..a86bbbffff 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -270,6 +270,14 @@ F32 LLFontFreetype::getXAdvance(llwchar wch) const
return (F32)mFontBitmapCachep->getMaxCharWidth();
}
+F32 LLFontFreetype::getXAdvance(const LLFontGlyphInfo* glyph) const
+{
+ if (mFTFace == NULL)
+ return 0.0;
+
+ return glyph->mXAdvance;
+}
+
F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const
{
if (mFTFace == NULL)
@@ -289,6 +297,21 @@ F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const
return delta.x*(1.f/64.f);
}
+F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const
+{
+ if (mFTFace == NULL)
+ return 0.0;
+
+ U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
+ U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
+
+ FT_Vector delta;
+
+ llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta));
+
+ return delta.x*(1.f/64.f);
+}
+
BOOL LLFontFreetype::hasGlyph(llwchar wch) const
{
llassert(!mIsFallback);
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index 7a5d029038..f60d09316d 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -128,7 +128,9 @@ public:
};
F32 getXAdvance(llwchar wc) const;
+ F32 getXAdvance(const LLFontGlyphInfo* glyph) const;
F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters
+ F32 getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const; // Get the kerning between the two characters
LLFontGlyphInfo* getGlyphInfo(llwchar wch) const;
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index b6a6b448ee..f1f86fd638 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -249,11 +249,18 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
// Remember last-used texture to avoid unnecesssary bind calls.
LLImageGL *last_bound_texture = NULL;
+ const LLFontGlyphInfo* next_glyph = NULL;
+
for (i = begin_offset; i < begin_offset + length; i++)
{
llwchar wch = wstr[i];
- const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
+ const LLFontGlyphInfo* fgi = next_glyph;
+ next_glyph = NULL;
+ if(!fgi)
+ {
+ fgi = mFontFreetype->getGlyphInfo(wch);
+ }
if (!fgi)
{
llerrs << "Missing Glyph Info" << llendl;
@@ -295,7 +302,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
if (next_char && (next_char < LAST_CHARACTER))
{
// Kern this puppy.
- cur_x += mFontFreetype->getXKerning(wch, next_char);
+ next_glyph = mFontFreetype->getGlyphInfo(next_char);
+ cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
}
// Round after kerning.
@@ -435,14 +443,21 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
F32 cur_x = 0;
const S32 max_index = begin_offset + max_chars;
+ const LLFontGlyphInfo* next_glyph = NULL;
+
F32 width_padding = 0.f;
for (S32 i = begin_offset; i < max_index && wchars[i] != 0; i++)
{
llwchar wch = wchars[i];
- const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
+ const LLFontGlyphInfo* fgi = next_glyph;
+ next_glyph = NULL;
+ if(!fgi)
+ {
+ fgi = mFontFreetype->getGlyphInfo(wch);
+ }
- F32 advance = mFontFreetype->getXAdvance(wch);
+ F32 advance = mFontFreetype->getXAdvance(fgi);
// for the last character we want to measure the greater of its width and xadvance values
// so keep track of the difference between these values for the each character we measure
@@ -459,7 +474,8 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
&& (next_char < LAST_CHARACTER))
{
// Kern this puppy.
- cur_x += mFontFreetype->getXKerning(wch, next_char);
+ next_glyph = mFontFreetype->getGlyphInfo(next_char);
+ cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
}
// Round after kerning.
cur_x = (F32)llround(cur_x);
@@ -492,6 +508,8 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
// avoid S32 overflow when max_pixels == S32_MAX by staying in floating point
F32 scaled_max_pixels = ceil(max_pixels * sScaleX);
F32 width_padding = 0.f;
+
+ LLFontGlyphInfo* next_glyph = NULL;
S32 i;
for (i=0; (i < max_chars); i++)
@@ -534,8 +552,13 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
in_word = TRUE;
}
}
-
- LLFontGlyphInfo* fgi = mFontFreetype->getGlyphInfo(wch);
+
+ LLFontGlyphInfo* fgi = next_glyph;
+ next_glyph = NULL;
+ if(!fgi)
+ {
+ fgi = mFontFreetype->getGlyphInfo(wch);
+ }
// account for glyphs that run beyond the starting point for the next glyphs
width_padding = llmax( 0.f, // always use positive padding amount
@@ -554,7 +577,8 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
if (((i+1) < max_chars) && wchars[i+1])
{
// Kern this puppy.
- cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]);
+ next_glyph = mFontFreetype->getGlyphInfo(wchars[i+1]);
+ cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
}
// Round after kerning.
@@ -660,6 +684,8 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
const S32 max_index = begin_offset + llmin(S32_MAX - begin_offset, max_chars);
F32 scaled_max_pixels = max_pixels * sScaleX;
+
+ const LLFontGlyphInfo* next_glyph = NULL;
S32 pos;
for (pos = begin_offset; pos < max_index; pos++)
@@ -669,7 +695,15 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
{
break; // done
}
- F32 char_width = mFontFreetype->getXAdvance(wch);
+
+ const LLFontGlyphInfo* glyph = next_glyph;
+ next_glyph = NULL;
+ if(!glyph)
+ {
+ glyph = mFontFreetype->getGlyphInfo(wch);
+ }
+
+ F32 char_width = mFontFreetype->getXAdvance(glyph);
if (round)
{
@@ -695,11 +729,12 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
if (((pos + 1) < max_index)
&& (wchars[(pos + 1)]))
{
- llwchar next_char = wchars[pos + 1];
// Kern this puppy.
- cur_x += mFontFreetype->getXKerning(wch, next_char);
+ next_glyph = mFontFreetype->getGlyphInfo(wchars[pos + 1]);
+ cur_x += mFontFreetype->getXKerning(glyph, next_glyph);
}
+
// Round after kerning.
cur_x = llround(cur_x);
}
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index a55915af35..f3cd112b9a 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2376,10 +2376,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/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/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();
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 8beff26654..f58f4ac594 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4598,7 +4598,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>MediaShowWithinParcel</key>
<map>
@@ -10393,17 +10393,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>VoiceDefaultInternalLevel</key>
- <map>
- <key>Comment</key>
- <string>Internal level of voice set by default. Is equivalent to 0.5 (from 0.0-1.0 range) external voice level (internal = 400 * external^2).</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>100</integer>
- </map>
<key>VoiceEarLocation</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 68ee9cd612..f4bc35002b 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1673,6 +1673,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
if (mAvatarObject)
{
mAvatarObject->updateVisualParams();
+ mAvatarObject->invalidateAll();
}
// Start rendering & update the server
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 95a946cee8..459a61dec3 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -350,7 +350,7 @@ void LLBottomTray::setVisible(BOOL visible)
{
mBottomTrayLite->setVisible(visible);
}
- else
+ else
{
LLPanel::setVisible(visible);
}
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index f20ef76bed..c6719a3092 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -321,9 +321,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.VertexShaderEnable", boost::bind(&LLFloaterPreference::onVertexShaderEnable, this));
mCommitCallbackRegistrar.add("Pref.WindowedMod", boost::bind(&LLFloaterPreference::onCommitWindowedMode, this));
mCommitCallbackRegistrar.add("Pref.UpdateSliderText", boost::bind(&LLFloaterPreference::onUpdateSliderText,this, _1,_2));
- mCommitCallbackRegistrar.add("Pref.ParcelMediaAutoPlayEnable", boost::bind(&LLFloaterPreference::onCommitParcelMediaAutoPlayEnable, this));
- mCommitCallbackRegistrar.add("Pref.MediaEnabled", boost::bind(&LLFloaterPreference::onCommitMediaEnabled, this));
- mCommitCallbackRegistrar.add("Pref.MusicEnabled", boost::bind(&LLFloaterPreference::onCommitMusicEnabled, this));
mCommitCallbackRegistrar.add("Pref.QualityPerformance", boost::bind(&LLFloaterPreference::onChangeQuality, this, _2));
mCommitCallbackRegistrar.add("Pref.applyUIColor", boost::bind(&LLFloaterPreference::applyUIColor, this ,_1, _2));
mCommitCallbackRegistrar.add("Pref.getUIColor", boost::bind(&LLFloaterPreference::getUIColor, this ,_1, _2));
@@ -957,29 +954,6 @@ void LLFloaterPreference::disableUnavailableSettings()
}
}
-void LLFloaterPreference::onCommitParcelMediaAutoPlayEnable()
-{
- BOOL autoplay = getChild<LLCheckBoxCtrl>("autoplay_enabled")->get();
-
- gSavedSettings.setBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING, autoplay);
-
- lldebugs << "autoplay now = " << int(autoplay) << llendl;
-}
-
-void LLFloaterPreference::onCommitMediaEnabled()
-{
- LLCheckBoxCtrl *media_enabled_ctrl = getChild<LLCheckBoxCtrl>("media_enabled");
- bool enabled = media_enabled_ctrl->get();
- gSavedSettings.setBOOL("AudioStreamingMedia", enabled);
-}
-
-void LLFloaterPreference::onCommitMusicEnabled()
-{
- LLCheckBoxCtrl *music_enabled_ctrl = getChild<LLCheckBoxCtrl>("music_enabled");
- bool enabled = music_enabled_ctrl->get();
- gSavedSettings.setBOOL("AudioStreamingMusic", enabled);
-}
-
void LLFloaterPreference::refresh()
{
LLPanel::refresh();
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
index 6a88c916d7..8ad5389566 100644
--- a/indra/newview/llpanelnearbymedia.cpp
+++ b/indra/newview/llpanelnearbymedia.cpp
@@ -38,6 +38,7 @@
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "llresizebar.h"
+#include "llresizehandle.h"
#include "llscrolllistctrl.h"
#include "llscrolllistitem.h"
#include "llscrolllistcell.h"
@@ -116,6 +117,20 @@ BOOL LLPanelNearByMedia::postBuild()
p.resizing_view = this;
addChild( LLUICtrlFactory::create<LLResizeBar>(p) );
+ p.rect = LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0);
+ p.name = "resizebar_left";
+ p.min_size = getRect().getWidth();
+ p.side = LLResizeBar::LEFT;
+ addChild( LLUICtrlFactory::create<LLResizeBar>(p) );
+
+ LLResizeHandle::Params resize_handle_p;
+ resize_handle_p.rect = LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 );
+ resize_handle_p.mouse_opaque(false);
+ resize_handle_p.min_width(getRect().getWidth());
+ resize_handle_p.min_height(getRect().getHeight());
+ resize_handle_p.corner(LLResizeHandle::LEFT_BOTTOM);
+ addChild(LLUICtrlFactory::create<LLResizeHandle>(resize_handle_p));
+
mNearbyMediaPanel = getChild<LLUICtrl>("nearby_media_panel");
mMediaList = getChild<LLScrollListCtrl>("media_list");
mEnableAllCtrl = getChild<LLUICtrl>("all_nearby_media_enable_btn");
@@ -148,8 +163,10 @@ BOOL LLPanelNearByMedia::postBuild()
updateColumns();
LLView* minimized_controls = getChildView("minimized_controls");
- mMoreHeight = getRect().getHeight();
- mLessHeight = getRect().getHeight() - minimized_controls->getRect().mBottom;
+ mMoreRect = getRect();
+ mLessRect = getRect();
+ mLessRect.mBottom = minimized_controls->getRect().mBottom;
+
getChild<LLUICtrl>("more_less_btn")->setValue(false);
onMoreLess();
@@ -207,7 +224,7 @@ void LLPanelNearByMedia::reshape(S32 width, S32 height, BOOL called_from_parent)
LLButton* more_less_btn = getChild<LLButton>("more_less_btn");
if (more_less_btn->getValue().asBoolean())
{
- mMoreHeight = getRect().getHeight();
+ mMoreRect = getRect();
}
}
@@ -614,6 +631,8 @@ void LLPanelNearByMedia::refreshList()
// Clear all items so the list gets regenerated.
mMediaList->deleteAllItems();
+ mParcelAudioItem = NULL;
+ mParcelMediaItem = NULL;
all_items_deleted = true;
updateColumns();
@@ -926,10 +945,8 @@ void LLPanelNearByMedia::onMoreLess()
// enable resizing when expanded
getChildView("resizebar_bottom")->setEnabled(is_more);
- S32 new_height = is_more ? mMoreHeight : mLessHeight;
-
- LLRect new_rect = getRect();
- new_rect.mBottom = new_rect.mTop - new_height;
+ LLRect new_rect = is_more ? mMoreRect : mLessRect;
+ new_rect.translate(getRect().mRight - new_rect.mRight, getRect().mTop - new_rect.mTop);
setShape(new_rect);
}
diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h
index eedfd447de..6fe724266b 100644
--- a/indra/newview/llpanelnearbymedia.h
+++ b/indra/newview/llpanelnearbymedia.h
@@ -174,11 +174,11 @@ private:
std::string mParcelMediaName;
std::string mParcelAudioName;
- S32 mMoreHeight;
- S32 mLessHeight;
- LLFrameTimer mHoverTimer;
- LLScrollListItem* mParcelMediaItem;
- LLScrollListItem* mParcelAudioItem;
+ LLRect mMoreRect;
+ LLRect mLessRect;
+ LLFrameTimer mHoverTimer;
+ LLScrollListItem* mParcelMediaItem;
+ LLScrollListItem* mParcelAudioItem;
};
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index ddb6405c41..662e6dcabe 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -167,8 +167,8 @@ void LLTexLayerSetBuffer::popProjection() const
BOOL LLTexLayerSetBuffer::needsRender()
{
const LLVOAvatarSelf* avatar = mTexLayerSet->getAvatar();
- BOOL upload_now = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal();
- BOOL needs_update = gAgentQueryManager.hasNoPendingQueries() && (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating;
+ BOOL upload_now = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal() && gAgentQueryManager.hasNoPendingQueries();
+ BOOL needs_update = (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating;
if (needs_update)
{
BOOL invalid_skirt = avatar->getBakedTE(mTexLayerSet) == LLVOAvatarDefines::TEX_SKIRT_BAKED && !avatar->isWearingWearableType(WT_SKIRT);
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 934981b0ad..1d935f5ab8 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -251,7 +251,7 @@ void audio_update_wind(bool force_update)
{
// initialize wind volume (force_update) by using large volume_delta
// which is sufficient to completely turn off or turn on wind noise
- volume_delta = max_wind_volume;
+ volume_delta = 1.f;
}
// mute wind when not flying
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 642f672faf..395467dffb 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1318,6 +1318,9 @@ void LLViewerMediaImpl::loadURI()
{
if(mMediaSource)
{
+ // trim whitespace from front and back of URL - fixes EXT-5363
+ LLStringUtil::trim( mMediaURL );
+
// *HACK: we don't know if the URI coming in is properly escaped
// (the contract doesn't specify whether it is escaped or not.
// but LLQtWebKit expects it to be, so we do our best to encode
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 3d153db733..59606f17b2 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -1115,10 +1115,9 @@ public:
* Gets stored external (vivox) volume level for specified speaker and
* transforms it into internal (viewer) level.
*
- * If specified user is not found default level will be returned. It is equivalent of
- * external level 0.5 from the 0.0..1.0 range.
+ * If specified user is not found -1 will be returned.
* Internal level is calculated as: internal = 400 * external^2
- * Maps 0.0 to 1.0 to internal values 0-400 with default 0.5 == 100
+ * Maps 0.0 to 1.0 to internal values 0-400
*
* @param[in] speaker_id - LLUUID of user to get his volume level
*/
@@ -1157,9 +1156,8 @@ void LLSpeakerVolumeStorage::storeSpeakerVolume(const LLUUID& speaker_id, F32 vo
S32 LLSpeakerVolumeStorage::getSpeakerVolume(const LLUUID& speaker_id)
{
- // default internal level of user voice.
- const static LLUICachedControl<S32> DEFAULT_INTERNAL_VOLUME_LEVEL("VoiceDefaultInternalLevel", 100);
- S32 ret_val = DEFAULT_INTERNAL_VOLUME_LEVEL;
+ // Return value of -1 indicates no level is stored for this speaker
+ S32 ret_val = -1;
speaker_data_map_t::const_iterator it = mSpeakersData.find(speaker_id);
if (it != mSpeakersData.end())
@@ -5045,6 +5043,11 @@ LLVoiceClient::participantState *LLVoiceClient::sessionState::addParticipant(con
mParticipantsByUUID.insert(participantUUIDMap::value_type(&(result->mAvatarID), result));
result->mUserVolume = LLSpeakerVolumeStorage::getInstance()->getSpeakerVolume(result->mAvatarID);
+ if (result->mUserVolume != -1)
+ {
+ result->mVolumeDirty = true;
+ mVolumeDirty = true;
+ }
LL_DEBUGS("Voice") << "participant \"" << result->mURI << "\" added." << LL_ENDL;
}