summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llaccordionctrl.cpp104
-rw-r--r--indra/llui/llaccordionctrl.h61
-rw-r--r--indra/llui/llaccordionctrltab.cpp49
-rw-r--r--indra/llui/llaccordionctrltab.h16
-rw-r--r--indra/llui/llfloater.cpp7
-rw-r--r--indra/llui/llkeywords.cpp54
-rw-r--r--indra/llui/llkeywords.h3
-rw-r--r--indra/llui/lllineeditor.cpp5
-rw-r--r--indra/llui/llmultifloater.cpp10
-rw-r--r--indra/llui/llmultifloater.h1
-rw-r--r--indra/llui/lltextbase.cpp67
-rw-r--r--indra/llui/lltextbase.h8
12 files changed, 324 insertions, 61 deletions
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index 8e0245c451..237d42090f 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -66,8 +66,13 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
, mAutoScrolling( false )
, mAutoScrollRate( 0.f )
, mSelectedTab( NULL )
+ , mTabComparator( NULL )
+ , mNoVisibleTabsHelpText(NULL)
+ , mNoVisibleTabsOrigString(params.no_visible_tabs_text.initial_value().asString())
{
- mSingleExpansion = params.single_expansion;
+ initNoTabsWidget(params.no_matched_tabs_text);
+
+ mSingleExpansion = params.single_expansion;
if(mFitParent && !mSingleExpansion)
{
llinfos << "fit_parent works best when combined with single_expansion" << llendl;
@@ -78,7 +83,10 @@ LLAccordionCtrl::LLAccordionCtrl() : LLPanel()
, mAutoScrolling( false )
, mAutoScrollRate( 0.f )
, mSelectedTab( NULL )
+ , mNoVisibleTabsHelpText(NULL)
{
+ initNoTabsWidget(LLTextBox::Params());
+
mSingleExpansion = false;
mFitParent = false;
LLUICtrlFactory::getInstance()->buildPanel(this, "accordion_parent.xml");
@@ -168,6 +176,8 @@ BOOL LLAccordionCtrl::postBuild()
}
}
+ updateNoTabsHelpTextVisibility();
+
return TRUE;
}
@@ -187,8 +197,15 @@ void LLAccordionCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
rcLocal.mRight = rcLocal.mLeft + width;
rcLocal.mTop = rcLocal.mBottom + height;
+ // get textbox a chance to reshape its content
+ mNoVisibleTabsHelpText->reshape(width, height, called_from_parent);
+
setRect(rcLocal);
+ // assume that help text is always fit accordion.
+ // necessary text paddings can be set via h_pad and v_pad
+ mNoVisibleTabsHelpText->setRect(getLocalRect());
+
arrange();
}
@@ -336,7 +353,7 @@ void LLAccordionCtrl::addCollapsibleCtrl(LLView* view)
mAccordionTabs.push_back(accordion_tab);
accordion_tab->setDropDownStateChangedCallback( boost::bind(&LLAccordionCtrl::onCollapseCtrlCloseOpen, this, mAccordionTabs.size() - 1) );
-
+ arrange();
}
void LLAccordionCtrl::removeCollapsibleCtrl(LLView* view)
@@ -359,6 +376,31 @@ void LLAccordionCtrl::removeCollapsibleCtrl(LLView* view)
}
}
+void LLAccordionCtrl::initNoTabsWidget(const LLTextBox::Params& tb_params)
+{
+ LLTextBox::Params tp = tb_params;
+ tp.rect(getLocalRect());
+ mNoMatchedTabsOrigString = tp.initial_value().asString();
+ mNoVisibleTabsHelpText = LLUICtrlFactory::create<LLTextBox>(tp, this);
+}
+
+void LLAccordionCtrl::updateNoTabsHelpTextVisibility()
+{
+ bool visible_exists = false;
+ std::vector<LLAccordionCtrlTab*>::const_iterator it = mAccordionTabs.begin();
+ const std::vector<LLAccordionCtrlTab*>::const_iterator it_end = mAccordionTabs.end();
+ for (; it != it_end; ++it)
+ {
+ if ((*it)->getVisible())
+ {
+ visible_exists = true;
+ break;
+ }
+ }
+
+ mNoVisibleTabsHelpText->setVisible(!visible_exists);
+}
+
void LLAccordionCtrl::arrangeSinge()
{
S32 panel_left = BORDER_MARGIN; // Margin from left side of Splitter
@@ -482,6 +524,8 @@ void LLAccordionCtrl::arrangeMultiple()
void LLAccordionCtrl::arrange()
{
+ updateNoTabsHelpTextVisibility();
+
if( mAccordionTabs.size() == 0)
{
//We do not arrange if we do not have what should be arranged
@@ -500,6 +544,8 @@ void LLAccordionCtrl::arrange()
S32 panel_height = getRect().getHeight() - 2*BORDER_MARGIN;
+ if (accordion_tab->getFitParent())
+ panel_height = accordion_tab->getRect().getHeight();
ctrlSetLeftTopAndSize(accordion_tab,panel_rect.mLeft,panel_top,panel_width,panel_height);
show_hide_scrollbar(getRect().getWidth(),getRect().getHeight());
@@ -737,6 +783,20 @@ S32 LLAccordionCtrl::notifyParent(const LLSD& info)
}
return 1;
}
+ else if (info.has("child_visibility_change"))
+ {
+ BOOL new_visibility = info["child_visibility_change"];
+ if (new_visibility)
+ {
+ // there is at least one visible tab
+ mNoVisibleTabsHelpText->setVisible(FALSE);
+ }
+ else
+ {
+ // it could be the latest visible tab, check all of them
+ updateNoTabsHelpTextVisibility();
+ }
+ }
return LLPanel::notifyParent(info);
}
void LLAccordionCtrl::reset ()
@@ -745,6 +805,46 @@ void LLAccordionCtrl::reset ()
mScrollbar->setDocPos(0);
}
+void LLAccordionCtrl::sort()
+{
+ if (!mTabComparator)
+ {
+ llwarns << "No comparator specified for sorting accordion tabs." << llendl;
+ return;
+ }
+
+ std::sort(mAccordionTabs.begin(), mAccordionTabs.end(), LLComparatorAdaptor(*mTabComparator));
+ arrange();
+}
+
+void LLAccordionCtrl::setFilterSubString(const std::string& filter_string)
+{
+ LLStringUtil::format_map_t args;
+ args["[SEARCH_TERM]"] = LLURI::escape(filter_string);
+ std::string text = filter_string.empty() ? mNoVisibleTabsOrigString : mNoMatchedTabsOrigString;
+ LLStringUtil::format(text, args);
+
+ mNoVisibleTabsHelpText->setValue(text);
+}
+
+const LLAccordionCtrlTab* LLAccordionCtrl::getExpandedTab() const
+{
+ typedef std::vector<LLAccordionCtrlTab*>::const_iterator tabs_const_iterator;
+
+ const LLAccordionCtrlTab* result = 0;
+
+ for (tabs_const_iterator i = mAccordionTabs.begin(); i != mAccordionTabs.end(); ++i)
+ {
+ if ((*i)->isExpanded())
+ {
+ result = *i;
+ break;
+ }
+ }
+
+ return result;
+}
+
S32 LLAccordionCtrl::calcExpandedTabHeight(S32 tab_index /* = 0 */, S32 available_height /* = 0 */)
{
if(tab_index < 0)
diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h
index a029201c90..b5fdf796cd 100644
--- a/indra/llui/llaccordionctrl.h
+++ b/indra/llui/llaccordionctrl.h
@@ -34,6 +34,7 @@
#define LL_ACCORDIONCTRL_H
#include "llpanel.h"
+#include "lltextbox.h"
#include "llscrollbar.h"
#include <vector>
@@ -56,6 +57,19 @@ private:
public:
+ /**
+ * Abstract comparator for accordion tabs.
+ */
+ class LLTabComparator
+ {
+ public:
+ LLTabComparator() {};
+ virtual ~LLTabComparator() {};
+
+ /** Returns true if tab1 < tab2, false otherwise */
+ virtual bool compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const = 0;
+ };
+
struct Params
: public LLInitParam::Block<Params, LLPanel::Params>
{
@@ -64,10 +78,14 @@ public:
accordion tabs are responsible for scrolling their content.
*NOTE fit_parent works best when combined with single_expansion.
Accordion view should implement getRequiredRect() and provide valid height*/
+ Optional<LLTextBox::Params> no_matched_tabs_text;
+ Optional<LLTextBox::Params> no_visible_tabs_text;
Params()
: single_expansion("single_expansion",false)
, fit_parent("fit_parent", false)
+ , no_matched_tabs_text("no_matched_tabs_text")
+ , no_visible_tabs_text("no_visible_tabs_text")
{};
};
@@ -105,7 +123,27 @@ public:
void reset ();
+ void setComparator(const LLTabComparator* comp) { mTabComparator = comp; }
+ void sort();
+
+ /**
+ * Sets filter substring as a search_term for help text when there are no any visible tabs.
+ */
+ void setFilterSubString(const std::string& filter_string);
+
+ /**
+ * This method returns the first expanded accordion tab.
+ * It is expected to be called for accordion which doesn't allow multiple
+ * tabs to be expanded. Use with care.
+ */
+ const LLAccordionCtrlTab* getExpandedTab() const;
+
+ const LLAccordionCtrlTab* getSelectedTab() const { return mSelectedTab; }
+
private:
+ void initNoTabsWidget(const LLTextBox::Params& tb_params);
+ void updateNoTabsHelpTextVisibility();
+
void arrangeSinge();
void arrangeMultiple();
@@ -123,6 +161,21 @@ private:
BOOL autoScroll (S32 x, S32 y);
+ /**
+ * An adaptor for LLTabComparator
+ */
+ struct LLComparatorAdaptor
+ {
+ LLComparatorAdaptor(const LLTabComparator& comparator) : mComparator(comparator) {};
+
+ bool operator()(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2)
+ {
+ return mComparator.compare(tab1, tab2);
+ }
+
+ const LLTabComparator& mComparator;
+ };
+
private:
LLRect mInnerRect;
LLScrollbar* mScrollbar;
@@ -130,7 +183,13 @@ private:
bool mFitParent;
bool mAutoScrolling;
F32 mAutoScrollRate;
- LLAccordionCtrlTab* mSelectedTab;
+ LLTextBox* mNoVisibleTabsHelpText;
+
+ std::string mNoMatchedTabsOrigString;
+ std::string mNoVisibleTabsOrigString;
+
+ LLAccordionCtrlTab* mSelectedTab;
+ const LLTabComparator* mTabComparator;
};
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 83e67980a3..20e4b7867c 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -76,6 +76,8 @@ public:
std::string getTitle();
void setTitle(const std::string& title, const std::string& hl);
+ void setTitleFontStyle(std::string style);
+
void setSelected(bool is_selected) { mIsSelected = is_selected; }
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
@@ -102,6 +104,9 @@ private:
LLPointer<LLUIImage> mImageHeaderPressed;
LLPointer<LLUIImage> mImageHeaderFocused;
+ // style saved when applying it in setTitleFontStyle
+ LLStyle::Params mStyleParams;
+
LLUIColor mHeaderBGColor;
bool mNeedsHighlight;
@@ -170,12 +175,23 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitle(const std::string& t
{
LLTextUtil::textboxSetHighlightedVal(
mHeaderTextbox,
- LLStyle::Params(),
+ mStyleParams,
title,
hl);
}
}
+void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitleFontStyle(std::string style)
+{
+ if (mHeaderTextbox)
+ {
+ std::string text = mHeaderTextbox->getText();
+ mStyleParams.font(mHeaderTextbox->getDefaultFont());
+ mStyleParams.font.style(style);
+ mHeaderTextbox->setText(text, mStyleParams);
+ }
+}
+
void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
{
S32 width = getRect().getWidth();
@@ -409,6 +425,13 @@ void LLAccordionCtrlTab::changeOpenClose(bool is_open)
}
}
+void LLAccordionCtrlTab::handleVisibilityChange(BOOL new_visibility)
+{
+ LLUICtrl::handleVisibilityChange(new_visibility);
+
+ notifyParent(LLSD().with("child_visibility_change", new_visibility));
+}
+
BOOL LLAccordionCtrlTab::handleMouseDown(S32 x, S32 y, MASK mask)
{
if(mCollapsible && mHeaderVisible && mCanOpenClose)
@@ -466,7 +489,7 @@ void LLAccordionCtrlTab::setAccordionView(LLView* panel)
addChild(panel,0);
}
-std::string LLAccordionCtrlTab::getTitle()
+std::string LLAccordionCtrlTab::getTitle() const
{
LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
if (header)
@@ -488,6 +511,15 @@ void LLAccordionCtrlTab::setTitle(const std::string& title, const std::string& h
}
}
+void LLAccordionCtrlTab::setTitleFontStyle(std::string style)
+{
+ LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
+ if (header)
+ {
+ header->setTitleFontStyle(style);
+ }
+}
+
boost::signals2::connection LLAccordionCtrlTab::setFocusReceivedCallback(const focus_signal_t::slot_type& cb)
{
LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
@@ -961,3 +993,16 @@ BOOL LLAccordionCtrlTab::handleToolTip(S32 x, S32 y, MASK mask)
}
return LLUICtrl::handleToolTip(x, y, mask);
}
+BOOL LLAccordionCtrlTab::handleScrollWheel ( S32 x, S32 y, S32 clicks )
+{
+ if( LLUICtrl::handleScrollWheel(x,y,clicks))
+ {
+ return TRUE;
+ }
+ if( mScrollbar && mScrollbar->getVisible() && mScrollbar->handleScrollWheel( 0, 0, clicks ) )
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index 83a9024a74..e17ecc5319 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -37,6 +37,7 @@
#include "llrect.h"
#include "lluictrl.h"
#include "lluicolor.h"
+#include "llstyle.h"
class LLUICtrlFactory;
class LLUIImage;
@@ -115,11 +116,14 @@ public:
void setAccordionView(LLView* panel);
LLView* getAccordionView() { return mContainerPanel; };
- std::string getTitle();
+ std::string getTitle() const;
// Set text and highlight substring in LLAccordionCtrlTabHeader
void setTitle(const std::string& title, const std::string& hl = LLStringUtil::null);
+ // Set text font style in LLAccordionCtrlTabHeader
+ void setTitleFontStyle(std::string style);
+
boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb);
boost::signals2::connection setFocusLostCallback(const focus_signal_t::slot_type& cb);
@@ -154,6 +158,11 @@ public:
// Call reshape after changing size
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ /**
+ * Raises notifyParent event with "child_visibility_change" = new_visibility
+ */
+ void handleVisibilityChange(BOOL new_visibility);
+
// Changes expand/collapse state and triggers expand/collapse callbacks
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
@@ -161,10 +170,12 @@ public:
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask);
+ virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
+
virtual bool addChild(LLView* child, S32 tab_group);
- bool isExpanded() { return mDisplayChildren; }
+ bool isExpanded() const { return mDisplayChildren; }
S32 getHeaderHeight();
@@ -185,6 +196,7 @@ public:
void showAndFocusHeader();
void setFitPanel( bool fit ) { mFitPanel = true; }
+ bool getFitParent() const { return mFitPanel; }
protected:
void adjustContainerPanel (const LLRect& child_rect);
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index fad98e553f..9a56372e68 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -347,7 +347,7 @@ void LLFloater::layoutDragHandle()
{
rect = getLocalRect();
}
- mDragHandle->setRect(rect);
+ mDragHandle->setShape(rect);
updateTitleButtons();
}
@@ -810,6 +810,11 @@ void LLFloater::applyTitle()
{
mDragHandle->setTitle ( mTitle );
}
+
+ if (getHost())
+ {
+ getHost()->updateFloaterTitle(this);
+ }
}
std::string LLFloater::getCurrentTitle() const
diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp
index 75342afbe2..e9614ea660 100644
--- a/indra/llui/llkeywords.cpp
+++ b/indra/llui/llkeywords.cpp
@@ -339,6 +339,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
{
if( *cur == '\n' )
{
+ LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(cur-base);
+ text_segment->setToken( 0 );
+ insertSegment( *seg_list, text_segment, text_len, defaultColor, editor);
cur++;
if( !*cur || *cur == '\n' )
{
@@ -378,9 +381,8 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
}
S32 seg_end = cur - base;
- LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor );
- text_segment->setToken( cur_token );
- insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
+ //create segments from seg_start to seg_end
+ insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, defaultColor, editor);
line_done = TRUE; // to break out of second loop.
break;
}
@@ -486,11 +488,12 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
seg_end = seg_start + between_delimiters + cur_delimiter->getLength();
}
-
+ insertSegments(wtext, *seg_list,cur_delimiter, text_len, seg_start, seg_end, defaultColor, editor);
+ /*
LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_delimiter->getColor(), seg_start, seg_end, editor );
text_segment->setToken( cur_delimiter );
insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
-
+ */
// Note: we don't increment cur, since the end of one delimited seg may be immediately
// followed by the start of another one.
continue;
@@ -519,10 +522,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
// llinfos << "Seg: [" << word.c_str() << "]" << llendl;
-
- LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor );
- text_segment->setToken( cur_token );
- insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
+ insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, defaultColor, editor);
}
cur += seg_len;
continue;
@@ -537,24 +537,50 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
}
}
-void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>* seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, LLTextEditor& editor )
+void LLKeywords::insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* cur_token, S32 text_len, S32 seg_start, S32 seg_end, const LLColor4 &defaultColor, LLTextEditor& editor )
+{
+ std::string::size_type pos = wtext.find('\n',seg_start);
+
+ while (pos!=-1 && pos < (std::string::size_type)seg_end)
+ {
+ if (pos!=seg_start)
+ {
+ LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, pos, editor );
+ text_segment->setToken( cur_token );
+ insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
+ }
+
+ LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(pos);
+ text_segment->setToken( cur_token );
+ insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
+
+ seg_start = pos+1;
+ pos = wtext.find('\n',seg_start);
+ }
+
+ LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor );
+ text_segment->setToken( cur_token );
+ insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
+}
+
+void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, LLTextEditor& editor )
{
- LLTextSegmentPtr last = seg_list->back();
+ LLTextSegmentPtr last = seg_list.back();
S32 new_seg_end = new_segment->getEnd();
if( new_segment->getStart() == last->getStart() )
{
- seg_list->pop_back();
+ seg_list.pop_back();
}
else
{
last->setEnd( new_segment->getStart() );
}
- seg_list->push_back( new_segment );
+ seg_list.push_back( new_segment );
if( new_seg_end < text_len )
{
- seg_list->push_back( new LLNormalTextSegment( defaultColor, new_seg_end, text_len, editor ) );
+ seg_list.push_back( new LLNormalTextSegment( defaultColor, new_seg_end, text_len, editor ) );
}
}
diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h
index e5b66dfa56..09378e408b 100644
--- a/indra/llui/llkeywords.h
+++ b/indra/llui/llkeywords.h
@@ -129,7 +129,8 @@ public:
private:
LLColor3 readColor(const std::string& s);
- void insertSegment(std::vector<LLTextSegmentPtr> *seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, class LLTextEditor& editor);
+ void insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, class LLTextEditor& editor);
+ void insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* token, S32 text_len, S32 seg_start, S32 seg_end, const LLColor4 &defaultColor, LLTextEditor& editor);
BOOL mLoaded;
word_token_map_t mWordTokenMap;
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 45f9de8e8d..c93ca1af88 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -377,7 +377,10 @@ void LLLineEditor::setText(const LLStringExplicit &new_text)
setCursor(llmin((S32)mText.length(), getCursor()));
// Set current history line to end of history.
- mCurrentHistoryLine = mLineHistory.end() - 1;
+ if(mLineHistory.end() != mLineHistory.begin())
+ {
+ mCurrentHistoryLine = mLineHistory.end() - 1;
+ }
mPrevText = mText;
}
diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index 3aea648562..b1dbce0000 100644
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -238,6 +238,16 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
moveResizeHandlesToFront();
}
+void LLMultiFloater::updateFloaterTitle(LLFloater* floaterp)
+{
+ S32 index = mTabContainer->getIndexForPanel(floaterp);
+ if (index != -1)
+ {
+ mTabContainer->setPanelTitle(index, floaterp->getShortTitle());
+ }
+}
+
+
/**
BOOL selectFloater(LLFloater* floaterp)
diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h
index bbf2c56fe7..24a841f64e 100644
--- a/indra/llui/llmultifloater.h
+++ b/indra/llui/llmultifloater.h
@@ -80,6 +80,7 @@ public:
void onTabSelected();
virtual void updateResizeLimits();
+ virtual void updateFloaterTitle(LLFloater* floaterp);
protected:
struct LLFloaterData
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index cfa341ea23..4d835b869f 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -152,6 +152,7 @@ LLTextBase::Params::Params()
bg_writeable_color("bg_writeable_color"),
bg_focus_color("bg_focus_color"),
allow_scroll("allow_scroll", true),
+ plain_text("plain_text",false),
track_end("track_end", false),
read_only("read_only", false),
v_pad("v_pad", 0),
@@ -200,6 +201,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mSelectionStart( 0 ),
mSelectionEnd( 0 ),
mIsSelecting( FALSE ),
+ mPlainText ( p.plain_text ),
mWordWrap(p.wrap),
mUseEllipses( p.use_ellipses ),
mParseHTML(p.allow_html),
@@ -1101,7 +1103,7 @@ S32 LLTextBase::getLeftOffset(S32 width)
case LLFontGL::LEFT:
return mHPad;
case LLFontGL::HCENTER:
- return mHPad + (mVisibleTextRect.getWidth() - width - mHPad) / 2;
+ return mHPad + llmax(0, (mVisibleTextRect.getWidth() - width - mHPad) / 2);
case LLFontGL::RIGHT:
return mVisibleTextRect.getWidth() - width;
default:
@@ -1207,11 +1209,6 @@ void LLTextBase::reflow()
// grow line height as necessary based on reported height of this segment
line_height = llmax(line_height, segment_height);
remaining_pixels -= segment_width;
- if (remaining_pixels < 0)
- {
- // getNumChars() and getDimensions() should return consistent results
- remaining_pixels = 0;
- }
seg_offset += character_count;
@@ -1630,7 +1627,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
part = (S32)LLTextParser::MIDDLE;
}
std::string subtext=text.substr(0,start);
- appendAndHighlightTextImpl(subtext, part, style_params);
+ appendAndHighlightText(subtext, part, style_params);
}
// output an optional icon before the Url
@@ -1652,7 +1649,14 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
// output the styled Url
- appendAndHighlightTextImpl(match.getLabel(), part, link_params);
+ // output the styled Url (unless we've been asked to suppress hyperlinking)
+ if (match.isLinkDisabled())
+ {
+ appendAndHighlightText(match.getLabel(), part, style_params);
+ }
+ else
+ {
+ appendAndHighlightText(match.getLabel(), part, link_params);
// set the tooltip for the Url label
if (! match.getTooltip().empty())
@@ -1680,11 +1684,11 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
if (part != (S32)LLTextParser::WHOLE)
part=(S32)LLTextParser::END;
if (end < (S32)text.length())
- appendAndHighlightTextImpl(text, part, style_params);
+ appendAndHighlightText(text, part, style_params);
}
else
{
- appendAndHighlightTextImpl(new_text, part, style_params);
+ appendAndHighlightText(new_text, part, style_params);
}
}
@@ -1695,23 +1699,7 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
if(prepend_newline)
appendLineBreakSegment(input_params);
- std::string::size_type start = 0;
- std::string::size_type pos = new_text.find("\n",start);
-
- while(pos!=-1)
- {
- if(pos!=start)
- {
- std::string str = std::string(new_text,start,pos-start);
- appendTextImpl(str,input_params);
- }
- appendLineBreakSegment(input_params);
- start = pos+1;
- pos = new_text.find("\n",start);
- }
-
- std::string str = std::string(new_text,start,new_text.length()-start);
- appendTextImpl(str,input_params);
+ appendTextImpl(new_text,input_params);
}
void LLTextBase::needsReflow(S32 index)
@@ -1731,6 +1719,10 @@ void LLTextBase::appendLineBreakSegment(const LLStyle::Params& style_params)
void LLTextBase::appendImageSegment(S32 highlight_part, const LLStyle::Params& style_params)
{
+ if(getPlainText())
+ {
+ return;
+ }
segment_vec_t segments;
LLStyleConstSP sp(new LLStyle(style_params));
segments.push_back(new LLImageTextSegment(sp, getLength(),*this));
@@ -1810,13 +1802,10 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig
}
}
-void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& style_params)
+void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params)
{
if (new_text.empty()) return;
- if(prepend_newline)
- appendLineBreakSegment(style_params);
-
std::string::size_type start = 0;
std::string::size_type pos = new_text.find("\n",start);
@@ -1917,7 +1906,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
{
// Figure out which line we're nearest to.
LLRect visible_region = getVisibleDocumentRect();
-
+
// binary search for line that starts before local_y
line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), local_y - mVisibleTextRect.mBottom + visible_region.mBottom, compare_bottom());
@@ -1927,7 +1916,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
}
S32 pos = getLength();
- S32 start_x = mVisibleTextRect.mLeft + line_iter->mRect.mLeft;
+ S32 start_x = mVisibleTextRect.mLeft + line_iter->mRect.mLeft - visible_region.mLeft;
segment_set_t::iterator line_seg_iter;
S32 line_seg_offset;
@@ -2772,6 +2761,12 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
editor->addDocumentChild(mView);
}
+LLLineBreakTextSegment::LLLineBreakTextSegment(S32 pos):LLTextSegment(pos,pos+1)
+{
+ LLStyleSP s( new LLStyle(LLStyle::Params().visible(true)));
+
+ mFontHeight = llceil(s->getFont()->getLineHeight());
+}
LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLTextSegment(pos,pos+1)
{
mFontHeight = llceil(style->getFont()->getLineHeight());
@@ -2814,7 +2809,7 @@ bool LLImageTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width
height = llceil(mStyle->getFont()->getLineHeight());;
LLUIImagePtr image = mStyle->getImage();
- if( image.notNull())
+ if( num_chars>0 && image.notNull())
{
width += image->getWidth() + IMAGE_HPAD;
height = llmax(height, image->getHeight() + IMAGE_HPAD );
@@ -2826,13 +2821,13 @@ S32 LLImageTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
{
LLUIImagePtr image = mStyle->getImage();
S32 image_width = image->getWidth();
- if(num_pixels>image_width + IMAGE_HPAD)
+ if(line_offset == 0 || num_pixels>image_width + IMAGE_HPAD)
{
return 1;
}
-
return 0;
}
+
F32 LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
{
if ( (start >= 0) && (end <= mEnd - mStart))
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 7041b9a109..25c538951a 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -86,6 +86,7 @@ public:
track_end,
read_only,
allow_scroll,
+ plain_text,
wrap,
use_ellipses,
allow_html,
@@ -177,6 +178,9 @@ public:
void setReadOnly(bool read_only) { mReadOnly = read_only; }
bool getReadOnly() { return mReadOnly; }
+ void setPlainText(bool value) { mPlainText = value;}
+ bool getPlainText() const { return mPlainText; }
+
// cursor manipulation
bool setCursor(S32 row, S32 column);
bool setCursorPos(S32 cursor_pos, bool keep_cursor_offset = false);
@@ -274,7 +278,7 @@ protected:
S32 insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted
S32 removeStringNoUndo(S32 pos, S32 length);
S32 overwriteCharNoUndo(S32 pos, llwchar wc);
- void appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& stylep);
+ void appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep);
// manage segments
@@ -370,6 +374,7 @@ protected:
bool mReadOnly;
bool mBGVisible; // render background?
bool mClipPartial; // false if we show lines that are partially inside bounding rect
+ bool mPlainText; // didn't use Image or Icon segments
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
// support widgets
@@ -523,6 +528,7 @@ class LLLineBreakTextSegment : public LLTextSegment
public:
LLLineBreakTextSegment(LLStyleConstSP style,S32 pos);
+ LLLineBreakTextSegment(S32 pos);
~LLLineBreakTextSegment();
bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;