summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llbutton.cpp20
-rw-r--r--indra/llui/llbutton.h2
-rw-r--r--indra/llui/llfloater.cpp35
-rw-r--r--indra/llui/llfloater.h1
-rw-r--r--indra/llui/lliconctrl.cpp13
-rw-r--r--indra/llui/lliconctrl.h7
-rw-r--r--indra/llui/lllayoutstack.cpp2
-rw-r--r--indra/llui/llmenubutton.cpp8
-rw-r--r--indra/llui/llmenubutton.h3
-rw-r--r--indra/llui/llmenugl.cpp2
-rw-r--r--indra/llui/llmodaldialog.cpp14
-rw-r--r--indra/llui/llprogressbar.cpp24
-rw-r--r--indra/llui/llscrolllistctrl.cpp88
-rw-r--r--indra/llui/llscrolllistctrl.h10
-rw-r--r--indra/llui/llspinctrl.cpp2
-rw-r--r--indra/llui/lltabcontainer.cpp18
-rw-r--r--indra/llui/lltextbase.cpp51
-rw-r--r--indra/llui/lltextbase.h7
-rw-r--r--indra/llui/lltexteditor.h1
-rw-r--r--indra/llui/lltextutil.cpp16
-rw-r--r--indra/llui/lltextutil.h12
-rw-r--r--indra/llui/llurlaction.cpp9
-rw-r--r--indra/llui/llurlaction.h1
23 files changed, 275 insertions, 71 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 0e59fdf519..8028f397f3 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -102,6 +102,7 @@ LLButton::Params::Params()
scale_image("scale_image", true),
hover_glow_amount("hover_glow_amount"),
commit_on_return("commit_on_return", true),
+ commit_on_capture_lost("commit_on_capture_lost", false),
display_pressed_state("display_pressed_state", true),
use_draw_context_alpha("use_draw_context_alpha", true),
badge("badge"),
@@ -165,6 +166,7 @@ LLButton::LLButton(const LLButton::Params& p)
mBottomVPad(p.pad_bottom),
mHoverGlowStrength(p.hover_glow_amount),
mCommitOnReturn(p.commit_on_return),
+ mCommitOnCaptureLost(p.commit_on_capture_lost),
mFadeWhenDisabled(FALSE),
mForcePressedState(false),
mDisplayPressedState(p.display_pressed_state),
@@ -475,6 +477,10 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
// We only handle the click if the click both started and ended within us
if( hasMouseCapture() )
{
+ // reset timers before focus change, to not cause
+ // additional commits if mCommitOnCaptureLost.
+ resetMouseDownTimer();
+
// Always release the mouse
gFocusMgr.setMouseCapture( NULL );
@@ -489,8 +495,6 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
// Regardless of where mouseup occurs, handle callback
if(mMouseUpSignal) (*mMouseUpSignal)(this, LLSD());
- resetMouseDownTimer();
-
// DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked.
// If mouseup in the widget, it's been clicked
if (pointInView(x, y))
@@ -1195,6 +1199,18 @@ void LLButton::setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignmen
void LLButton::onMouseCaptureLost()
{
+ if (mCommitOnCaptureLost
+ && mMouseDownTimer.getStarted())
+ {
+ if (mMouseUpSignal) (*mMouseUpSignal)(this, LLSD());
+
+ if (mIsToggle)
+ {
+ toggleState();
+ }
+
+ LLUICtrl::onCommit();
+ }
resetMouseDownTimer();
}
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 572d36996c..ccd31e90c0 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -124,6 +124,7 @@ public:
Optional<bool> is_toggle,
scale_image,
commit_on_return,
+ commit_on_capture_lost,
display_pressed_state;
Optional<F32> hover_glow_amount;
@@ -374,6 +375,7 @@ protected:
F32 mCurGlowStrength;
bool mCommitOnReturn;
+ bool mCommitOnCaptureLost;
bool mFadeWhenDisabled;
bool mForcePressedState;
bool mDisplayPressedState;
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 03efd09689..d413fab270 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -259,6 +259,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mMinHeight(p.min_height),
mHeaderHeight(p.header_height),
mLegacyHeaderHeight(p.legacy_header_height),
+ mDefaultRectForGroup(true),
mMinimized(FALSE),
mForeground(FALSE),
mFirstLook(TRUE),
@@ -761,17 +762,13 @@ void LLFloater::closeFloater(bool app_quitting)
for(handle_set_iter_t dependent_it = mDependents.begin();
dependent_it != mDependents.end(); )
{
-
LLFloater* floaterp = dependent_it->get();
- if (floaterp)
- {
- ++dependent_it;
- floaterp->closeFloater(app_quitting);
- }
- else
- {
- mDependents.erase(dependent_it++);
- }
+ dependent_it = mDependents.erase(dependent_it);
+ if (floaterp)
+ {
+ floaterp->mDependeeHandle = LLHandle<LLFloater>();
+ floaterp->closeFloater(app_quitting);
+ }
}
cleanupHandles();
@@ -906,7 +903,10 @@ bool LLFloater::applyRectControl()
if (last_in_group && last_in_group != this)
{
// other floaters in our group, position ourselves relative to them and don't save the rect
- mRectControl.clear();
+ if (mDefaultRectForGroup)
+ {
+ mRectControl.clear();
+ }
mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;
}
else
@@ -1439,7 +1439,7 @@ void LLFloater::cleanupHandles()
LLFloater* floaterp = dependent_it->get();
if (!floaterp)
{
- mDependents.erase(dependent_it++);
+ dependent_it = mDependents.erase(dependent_it);
}
else
{
@@ -3481,8 +3481,15 @@ void LLFloater::stackWith(LLFloater& other)
}
next_rect.translate(floater_offset, -floater_offset);
- next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
-
+ const LLRect& rect = getControlGroup()->getRect(mRectControl);
+ if (rect.notEmpty() && !mDefaultRectForGroup && mResizable)
+ {
+ next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
+ }
+ else
+ {
+ next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
+ }
setShape(next_rect);
if (!other.getHost())
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 306760b7fb..668cd208a9 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -454,6 +454,7 @@ public:
protected:
bool mSaveRect;
+ bool mDefaultRectForGroup;
std::string mRectControl;
std::string mPosXControl;
std::string mPosYControl;
diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp
index 82b01e705d..e01aba402e 100644
--- a/indra/llui/lliconctrl.cpp
+++ b/indra/llui/lliconctrl.cpp
@@ -35,6 +35,7 @@
#include "llui.h"
#include "lluictrlfactory.h"
#include "lluiimage.h"
+#include "llwindow.h"
static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon");
@@ -42,6 +43,7 @@ LLIconCtrl::Params::Params()
: image("image_name"),
color("color"),
use_draw_context_alpha("use_draw_context_alpha", true),
+ interactable("interactable", false),
scale_image("scale_image"),
min_width("min_width", 0),
min_height("min_height", 0)
@@ -52,6 +54,7 @@ LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
mColor(p.color()),
mImagep(p.image),
mUseDrawContextAlpha(p.use_draw_context_alpha),
+ mInteractable(p.interactable),
mPriority(0),
mMinWidth(p.min_width),
mMinHeight(p.min_height),
@@ -81,6 +84,16 @@ void LLIconCtrl::draw()
LLUICtrl::draw();
}
+BOOL LLIconCtrl::handleHover(S32 x, S32 y, MASK mask)
+{
+ if (mInteractable && getEnabled())
+ {
+ getWindow()->setCursor(UI_CURSOR_HAND);
+ return TRUE;
+ }
+ return LLUICtrl::handleHover(x, y, mask);
+}
+
// virtual
// value might be a string or a UUID
void LLIconCtrl::setValue(const LLSD& value)
diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h
index dd83e78fd3..9c3b517bca 100644
--- a/indra/llui/lliconctrl.h
+++ b/indra/llui/lliconctrl.h
@@ -48,7 +48,8 @@ public:
{
Optional<LLUIImage*> image;
Optional<LLUIColor> color;
- Optional<bool> use_draw_context_alpha;
+ Optional<bool> use_draw_context_alpha,
+ interactable;
Optional<S32> min_width,
min_height;
Ignored scale_image;
@@ -67,6 +68,9 @@ public:
// llview overrides
virtual void draw();
+ // llview overrides
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+
// lluictrl overrides
virtual void setValue(const LLSD& value );
@@ -88,6 +92,7 @@ protected:
// If set to true (default), use the draw context transparency.
// If false, will use transparency returned by getCurrentTransparency(). See STORM-698.
bool mUseDrawContextAlpha;
+ bool mInteractable;
private:
LLUIColor mColor;
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index aac28e04b9..77938edf27 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -395,7 +395,6 @@ void LLLayoutStack::updateLayout()
space_to_distribute += panelp ? ll_round((F32)mPanelSpacing * panelp->getVisibleAmount()) : 0;
S32 remaining_space = space_to_distribute;
- F32 fraction_distributed = 0.f;
if (space_to_distribute > 0 && total_visible_fraction > 0.f)
{ // give space proportionally to visible auto resize panels
BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
@@ -404,7 +403,6 @@ void LLLayoutStack::updateLayout()
{
F32 fraction_to_distribute = (panelp->mFractionalSize * panelp->getAutoResizeFactor()) / (total_visible_fraction);
S32 delta = ll_round((F32)space_to_distribute * fraction_to_distribute);
- fraction_distributed += fraction_to_distribute;
panelp->mTargetDim += delta;
remaining_space -= delta;
}
diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index 303afcda15..583704418b 100644
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -40,6 +40,7 @@ void LLMenuButton::MenuPositions::declareValues()
declare("topleft", MP_TOP_LEFT);
declare("topright", MP_TOP_RIGHT);
declare("bottomleft", MP_BOTTOM_LEFT);
+ declare("bottomright", MP_BOTTOM_RIGHT);
}
LLMenuButton::Params::Params()
@@ -212,6 +213,13 @@ void LLMenuButton::updateMenuOrigin()
mY = rect.mBottom;
break;
}
+ case MP_BOTTOM_RIGHT:
+ {
+ const LLRect& menu_rect = menu->getRect();
+ mX = rect.mRight - menu_rect.getWidth();
+ mY = rect.mBottom;
+ break;
+ }
}
}
diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h
index 67ec1983b3..e42f8f53bd 100644
--- a/indra/llui/llmenubutton.h
+++ b/indra/llui/llmenubutton.h
@@ -41,7 +41,8 @@ public:
{
MP_TOP_LEFT,
MP_TOP_RIGHT,
- MP_BOTTOM_LEFT
+ MP_BOTTOM_LEFT,
+ MP_BOTTOM_RIGHT
} EMenuPosition;
struct MenuPositions
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 8f00d1274e..4264028338 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3960,8 +3960,8 @@ void LLTearOffMenu::draw()
{
// animate towards target height
reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
- mMenu->needsArrange();
}
+ mMenu->needsArrange();
LLFloater::draw();
}
diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp
index 5cfa8ea973..3e5978eb59 100644
--- a/indra/llui/llmodaldialog.cpp
+++ b/indra/llui/llmodaldialog.cpp
@@ -100,7 +100,10 @@ void LLModalDialog::onOpen(const LLSD& key)
if (!sModalStack.empty())
{
LLModalDialog* front = sModalStack.front();
- front->setVisible(FALSE);
+ if (front != this)
+ {
+ front->setVisible(FALSE);
+ }
}
// This is a modal dialog. It sucks up all mouse and keyboard operations.
@@ -108,7 +111,14 @@ void LLModalDialog::onOpen(const LLSD& key)
LLUI::getInstance()->addPopup(this);
setFocus(TRUE);
- sModalStack.push_front( this );
+ std::list<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this);
+ if (iter != sModalStack.end())
+ {
+ // if already present, we want to move it to front.
+ sModalStack.erase(iter);
+ }
+
+ sModalStack.push_front(this);
}
}
diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp
index 209796565c..cf57b1fe76 100644
--- a/indra/llui/llprogressbar.cpp
+++ b/indra/llui/llprogressbar.cpp
@@ -69,16 +69,22 @@ void LLProgressBar::draw()
static LLTimer timer;
F32 alpha = getDrawContext().mAlpha;
- LLColor4 image_bar_color = mColorBackground.get();
- image_bar_color.setAlpha(alpha);
- mImageBar->draw(getLocalRect(), image_bar_color);
+ if (mImageBar) // optional according to parameters
+ {
+ LLColor4 image_bar_color = mColorBackground.get();
+ image_bar_color.setAlpha(alpha);
+ mImageBar->draw(getLocalRect(), image_bar_color);
+ }
- alpha *= 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32()));
- LLColor4 bar_color = mColorBar.get();
- bar_color.mV[VALPHA] *= alpha; // modulate alpha
- LLRect progress_rect = getLocalRect();
- progress_rect.mRight = ll_round(getRect().getWidth() * (mPercentDone / 100.f));
- mImageFill->draw(progress_rect, bar_color);
+ if (mImageFill)
+ {
+ alpha *= 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32()));
+ LLColor4 bar_color = mColorBar.get();
+ bar_color.mV[VALPHA] *= alpha; // modulate alpha
+ LLRect progress_rect = getLocalRect();
+ progress_rect.mRight = ll_round(getRect().getWidth() * (mPercentDone / 100.f));
+ mImageFill->draw(progress_rect, bar_color);
+ }
}
void LLProgressBar::setValue(const LLSD& value)
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 11b0eb9f80..65c7b420ce 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1388,6 +1388,84 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
return found;
}
+U32 LLScrollListCtrl::searchItems(const std::string& substring, bool case_sensitive, bool focus)
+{
+ return searchItems(utf8str_to_wstring(substring), case_sensitive, focus);
+}
+
+U32 LLScrollListCtrl::searchItems(const LLWString& substring, bool case_sensitive, bool focus)
+{
+ U32 found = 0;
+
+ LLWString substring_trimmed(substring);
+ S32 len = substring_trimmed.size();
+
+ if (0 == len)
+ {
+ // at the moment search for empty element is not supported
+ return 0;
+ }
+ else
+ {
+ deselectAllItems(TRUE);
+ if (!case_sensitive)
+ {
+ // do comparisons in lower case
+ LLWStringUtil::toLower(substring_trimmed);
+ }
+
+ for (item_list::iterator iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ {
+ LLScrollListItem* item = *iter;
+ // Only select enabled items with matching names
+ if (!item->getEnabled())
+ {
+ continue;
+ }
+ LLScrollListCell* cellp = item->getColumn(getSearchColumn());
+ if (!cellp)
+ {
+ continue;
+ }
+ LLWString item_label = utf8str_to_wstring(cellp->getValue().asString());
+ if (!case_sensitive)
+ {
+ LLWStringUtil::toLower(item_label);
+ }
+ // remove extraneous whitespace from searchable label
+ LLWStringUtil::trim(item_label);
+
+ size_t found_iter = item_label.find(substring_trimmed);
+
+ if (found_iter != std::string::npos)
+ {
+ // find offset of matching text
+ cellp->highlightText(found_iter, substring_trimmed.size());
+ selectItem(item, -1, FALSE);
+
+ found++;
+
+ if (!mAllowMultipleSelection)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ if (focus && found != 0)
+ {
+ mNeedsScroll = true;
+ }
+
+ if (mCommitOnSelectionChange)
+ {
+ commitIfChanged();
+ }
+
+ return found;
+}
+
const std::string LLScrollListCtrl::getSelectedItemLabel(S32 column) const
{
LLScrollListItem* item;
@@ -1912,6 +1990,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id));
registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));
registrar.add("Url.RemoveFriend", boost::bind(&LLScrollListCtrl::removeFriend, id));
+ registrar.add("Url.ReportAbuse", boost::bind(&LLScrollListCtrl::reportAbuse, id, is_group));
registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));
registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));
registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group));
@@ -1975,6 +2054,15 @@ void LLScrollListCtrl::removeFriend(std::string id)
LLUrlAction::removeFriend(slurl);
}
+void LLScrollListCtrl::reportAbuse(std::string id, bool is_group)
+{
+ if (!is_group)
+ {
+ std::string slurl = "secondlife:///app/agent/" + id + "/about";
+ LLUrlAction::reportAbuse(slurl);
+ }
+}
+
void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
{
// open the resident's details or the group details
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 08134bbfc8..77d10fdec7 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -267,6 +267,14 @@ public:
const std::string getSelectedItemLabel(S32 column = 0) const;
LLSD getSelectedValue();
+ // If multi select is on, select all element that include substring,
+ // otherwise select first match only.
+ // If focus is true will scroll to selection.
+ // Returns number of results.
+ // Note: at the moment search happens in one go and is expensive
+ U32 searchItems(const std::string& substring, bool case_sensitive = false, bool focus = true);
+ U32 searchItems(const LLWString& substring, bool case_sensitive = false, bool focus = true);
+
// DEPRECATED: Use LLSD versions of setCommentText() and getSelectedValue().
// "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which
// has an associated, unique UUID, and only one of which can be selected at a time.
@@ -325,6 +333,7 @@ public:
// support right-click context menus for avatar/group lists
enum ContextMenuType { MENU_NONE, MENU_AVATAR, MENU_GROUP };
void setContextMenu(const ContextMenuType &menu) { mContextMenuType = menu; }
+ ContextMenuType getContextMenuType() { return mContextMenuType; }
// Overridden from LLView
/*virtual*/ void draw();
@@ -460,6 +469,7 @@ private:
static void sendIM(std::string id);
static void addFriend(std::string id);
static void removeFriend(std::string id);
+ static void reportAbuse(std::string id, bool is_group);
static void showNameDetails(std::string id, bool is_group);
static void copyNameToClipboard(std::string id, bool is_group);
static void copySLURLToClipboard(std::string id, bool is_group);
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index ee78b82429..ef7c8ec012 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -103,6 +103,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
up_button_params.rect = LLRect(btn_left, getRect().getHeight(), btn_right, getRect().getHeight() - spinctrl_btn_height);
up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
+ up_button_params.commit_on_capture_lost = true;
mUpBtn = LLUICtrlFactory::create<LLButton>(up_button_params);
addChild(mUpBtn);
@@ -111,6 +112,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
down_button_params.rect = LLRect(btn_left, getRect().getHeight() - spinctrl_btn_height, btn_right, getRect().getHeight() - 2 * spinctrl_btn_height);
down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
+ down_button_params.commit_on_capture_lost = true;
mDownBtn = LLUICtrlFactory::create<LLButton>(down_button_params);
addChild(mDownBtn);
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 459fdcf2ae..0aa7a2d217 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -402,9 +402,13 @@ void LLTabContainer::draw()
S32 cur_scroll_pos = getScrollPos();
if (cur_scroll_pos > 0)
{
- S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
- if (!mIsVertical)
+ if (mIsVertical)
{
+ target_pixel_scroll = cur_scroll_pos * (BTN_HEIGHT + tabcntrv_pad);
+ }
+ else
+ {
+ S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
if (cur_scroll_pos == 0)
@@ -1189,13 +1193,15 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
sendChildToFront(mNextArrowBtn);
sendChildToFront(mJumpPrevArrowBtn);
sendChildToFront(mJumpNextArrowBtn);
-
+
+ updateMaxScrollPos();
+
if( select )
{
selectLastTab();
+ mScrollPos = mMaxScrollPos;
}
- updateMaxScrollPos();
}
void LLTabContainer::addPlaceholder(LLPanel* child, const std::string& label)
@@ -2079,9 +2085,9 @@ void LLTabContainer::updateMaxScrollPos()
if( tab_total_height > available_height )
{
static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0);
- S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad);
+ S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad) - mNextArrowBtn->getRect().mBottom;
S32 additional_needed = tab_total_height - available_height_with_arrows;
- setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) );
+ setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT + tabcntrv_pad) ) );
no_scroll = FALSE;
}
}
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 0dc99fdde6..7e4aaa53bf 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -163,6 +163,7 @@ LLTextBase::Params::Params()
font_shadow("font_shadow"),
wrap("wrap"),
trusted_content("trusted_content", true),
+ always_show_icons("always_show_icons", false),
use_ellipses("use_ellipses", false),
parse_urls("parse_urls", false),
force_urls_external("force_urls_external", false),
@@ -212,6 +213,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mClip(p.clip),
mClipPartial(p.clip_partial && !p.allow_scroll),
mTrustedContent(p.trusted_content),
+ mAlwaysShowIcons(p.always_show_icons),
mTrackEnd( p.track_end ),
mScrollIndex(-1),
mSelectionStart( 0 ),
@@ -448,8 +450,48 @@ void LLTextBase::drawSelectionBackground()
++rect_it)
{
LLRect selection_rect = *rect_it;
- selection_rect = *rect_it;
- selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
+ if (mScroller)
+ {
+ // If scroller is On content_display_rect has correct rect and safe to use as is
+ // Note: we might need to account for border
+ selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
+ }
+ else
+ {
+ // If scroller is Off content_display_rect will have rect from document, adjusted to text width, heigh and position
+ // and we have to acount for offset depending on position
+ S32 v_delta = 0;
+ S32 h_delta = 0;
+ switch (mVAlign)
+ {
+ case LLFontGL::TOP:
+ v_delta = mVisibleTextRect.mTop - content_display_rect.mTop - mVPad;
+ break;
+ case LLFontGL::VCENTER:
+ v_delta = (llmax(mVisibleTextRect.getHeight() - content_display_rect.mTop, -content_display_rect.mBottom) + (mVisibleTextRect.mBottom - content_display_rect.mBottom)) / 2;
+ break;
+ case LLFontGL::BOTTOM:
+ v_delta = mVisibleTextRect.mBottom - content_display_rect.mBottom;
+ break;
+ default:
+ break;
+ }
+ switch (mHAlign)
+ {
+ case LLFontGL::LEFT:
+ h_delta = mVisibleTextRect.mLeft - content_display_rect.mLeft + mHPad;
+ break;
+ case LLFontGL::HCENTER:
+ h_delta = (llmax(mVisibleTextRect.getWidth() - content_display_rect.mLeft, -content_display_rect.mRight) + (mVisibleTextRect.mRight - content_display_rect.mRight)) / 2;
+ break;
+ case LLFontGL::RIGHT:
+ h_delta = mVisibleTextRect.mRight - content_display_rect.mRight;
+ break;
+ default:
+ break;
+ }
+ selection_rect.translate(h_delta, v_delta);
+ }
gl_rect_2d(selection_rect, selection_color);
}
}
@@ -2007,6 +2049,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url));
registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url));
+ registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url));
registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
@@ -2116,7 +2159,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
LLUrlMatch match;
std::string text = new_text;
while ( LLUrlRegistry::instance().findUrl(text, match,
- boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted()))
+ boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted() || mAlwaysShowIcons))
{
start = match.getStart();
end = match.getEnd()+1;
@@ -2141,7 +2184,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
// add icon before url if need
- LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted());
+ LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted() || mAlwaysShowIcons);
if ((isContentTrusted() || match.isTrusted()) && !match.getIcon().empty() )
{
setLastSegmentToolTip(LLTrans::getString("TooltipSLIcon"));
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index a4e83b42b4..25f8fa1c2b 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -321,7 +321,8 @@ public:
parse_highlights,
clip,
clip_partial,
- trusted_content;
+ trusted_content,
+ always_show_icons;
Optional<S32> v_pad,
h_pad;
@@ -369,6 +370,8 @@ public:
virtual void onFocusReceived();
virtual void onFocusLost();
+ void setParseHTML(bool parse_html) { mParseHTML = parse_html; }
+
// LLSpellCheckMenuHandler overrides
/*virtual*/ bool getSpellCheck() const;
@@ -702,6 +705,8 @@ protected:
bool mAutoIndent;
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
bool mSkipTripleClick;
+ bool mAlwaysShowIcons;
+
bool mSkipLinkUnderline;
// support widgets
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 26702b2412..1a10d2fd1e 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -196,6 +196,7 @@ public:
const LLUUID& getSourceID() const { return mSourceID; }
const LLTextSegmentPtr getPreviousSegment() const;
+ const LLTextSegmentPtr getLastSegment() const;
void getSelectedSegments(segment_vec_t& segments) const;
void setShowContextMenu(bool show) { mShowContextMenu = show; }
diff --git a/indra/llui/lltextutil.cpp b/indra/llui/lltextutil.cpp
index 538508b856..78049319bc 100644
--- a/indra/llui/lltextutil.cpp
+++ b/indra/llui/lltextutil.cpp
@@ -76,22 +76,6 @@ void LLTextUtil::textboxSetGreyedVal(LLTextBox *txtbox, const LLStyle::Params& n
txtbox->appendText(text.substr(greyed_begin + greyed_len), false, normal_style);
}
-const std::string& LLTextUtil::formatPhoneNumber(const std::string& phone_str)
-{
- static const std::string PHONE_SEPARATOR = LLUI::getInstance()->mSettingGroups["config"]->getString("AvalinePhoneSeparator");
- static const S32 PHONE_PART_LEN = 2;
-
- static std::string formatted_phone_str;
- formatted_phone_str = phone_str;
- S32 separator_pos = (S32)(formatted_phone_str.size()) - PHONE_PART_LEN;
- for (; separator_pos >= PHONE_PART_LEN; separator_pos -= PHONE_PART_LEN)
- {
- formatted_phone_str.insert(separator_pos, PHONE_SEPARATOR);
- }
-
- return formatted_phone_str;
-}
-
bool LLTextUtil::processUrlMatch(LLUrlMatch* match,LLTextBase* text_base, bool is_content_trusted)
{
if (match == 0 || text_base == 0)
diff --git a/indra/llui/lltextutil.h b/indra/llui/lltextutil.h
index a9c143e445..1adc3516f7 100644
--- a/indra/llui/lltextutil.h
+++ b/indra/llui/lltextutil.h
@@ -59,18 +59,6 @@ namespace LLTextUtil
const std::string& greyed);
/**
- * Formats passed phone number to be more human readable.
- *
- * It just divides the number on parts by two digits from right to left. The first left part
- * can have 2 or 3 digits, i.e. +44-33-33-44-55-66 or 12-34-56-78-90. Separator is set in
- * application settings (AvalinePhoneSeparator)
- *
- * @param[in] phone_str string with original phone number
- * @return reference to string with formatted phone number
- */
- const std::string& formatPhoneNumber(const std::string& phone_str);
-
- /**
* Adds icon before url if need.
*
* @param[in] match an object with results of matching
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index 84ea770a8d..8216046174 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -222,6 +222,15 @@ void LLUrlAction::removeFriend(std::string url)
}
}
+void LLUrlAction::reportAbuse(std::string url)
+{
+ std::string id_str = getUserID(url);
+ if (LLUUID::validate(id_str))
+ {
+ executeSLURL("secondlife:///app/agent/" + id_str + "/reportAbuse");
+ }
+}
+
void LLUrlAction::blockObject(std::string url)
{
std::string object_id = getObjectId(url);
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index 2d2a8dfef1..c2c576254d 100644
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -82,6 +82,7 @@ public:
static void sendIM(std::string url);
static void addFriend(std::string url);
static void removeFriend(std::string url);
+ static void reportAbuse(std::string url);
static void blockObject(std::string url);
static void unblockObject(std::string url);