From e1189d0e2ee47539edc68c3532e0a5ce64d5dcd1 Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Fri, 4 Jun 2010 13:29:25 +0300 Subject: EXT-7368 FIXED Implemented new "empty_accordion_text" textbox to show help text when there are no visible tabs in accordion. * Textbox always fit whole accordion. * This text is updated with search_term (in link to open Search floater) when new filter substring is passed to accordion. * Accordion is notified by its tabs when their visibility is changed. Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/486/ --HG-- branch : product-engine --- indra/llui/llaccordionctrl.cpp | 66 ++++++++++++++++++++++++++++++++++++++- indra/llui/llaccordionctrl.h | 13 ++++++++ indra/llui/llaccordionctrltab.cpp | 7 +++++ indra/llui/llaccordionctrltab.h | 5 +++ 4 files changed, 90 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 8e0245c451..5f866c49e6 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -66,8 +66,11 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params) , mAutoScrolling( false ) , mAutoScrollRate( 0.f ) , mSelectedTab( NULL ) + , mNoVisibleTabsHelpText(NULL) { - mSingleExpansion = params.single_expansion; + initNoTabsWidget(params.empty_accordion_text); + + mSingleExpansion = params.single_expansion; if(mFitParent && !mSingleExpansion) { llinfos << "fit_parent works best when combined with single_expansion" << llendl; @@ -78,7 +81,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 +174,8 @@ BOOL LLAccordionCtrl::postBuild() } } + updateNoTabsHelpTextVisibility(); + return TRUE; } @@ -187,8 +195,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(); } @@ -359,6 +374,31 @@ void LLAccordionCtrl::removeCollapsibleCtrl(LLView* view) } } +void LLAccordionCtrl::initNoTabsWidget(const LLTextBox::Params& tb_params) +{ + LLTextBox::Params tp = tb_params; + tp.rect(getLocalRect()); + mNoVisibleTabsOrigString = tp.initial_value().asString(); + mNoVisibleTabsHelpText = LLUICtrlFactory::create(tp, this); +} + +void LLAccordionCtrl::updateNoTabsHelpTextVisibility() +{ + bool visible_exists = false; + std::vector::const_iterator it = mAccordionTabs.begin(); + const std::vector::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 @@ -737,6 +777,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 +799,16 @@ void LLAccordionCtrl::reset () mScrollbar->setDocPos(0); } +void LLAccordionCtrl::setFilterSubString(const std::string& filter_string) +{ + LLStringUtil::format_map_t args; + args["[SEARCH_TERM]"] = LLURI::escape(filter_string); + std::string text = mNoVisibleTabsOrigString; + LLStringUtil::format(text, args); + + mNoVisibleTabsHelpText->setValue(text); +} + 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..2f483eafb2 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 @@ -64,10 +65,12 @@ 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 empty_accordion_text; Params() : single_expansion("single_expansion",false) , fit_parent("fit_parent", false) + , empty_accordion_text("empty_accordion_text") {}; }; @@ -105,7 +108,15 @@ public: void reset (); + /** + * Sets filter substring as a search_term for help text when there are no any visible tabs. + */ + void setFilterSubString(const std::string& filter_string); + private: + void initNoTabsWidget(const LLTextBox::Params& tb_params); + void updateNoTabsHelpTextVisibility(); + void arrangeSinge(); void arrangeMultiple(); @@ -131,6 +142,8 @@ private: bool mAutoScrolling; F32 mAutoScrollRate; LLAccordionCtrlTab* mSelectedTab; + LLTextBox* mNoVisibleTabsHelpText; + std::string mNoVisibleTabsOrigString; }; diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 83e67980a3..83fcc77f2a 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -409,6 +409,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) diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index 83a9024a74..be8b464b8e 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -154,6 +154,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); -- cgit v1.2.3 From d1751df1cc5d9bf853f29555de94faec1912e19f Mon Sep 17 00:00:00 2001 From: Sergei Litovchuk Date: Fri, 4 Jun 2010 21:52:38 +0300 Subject: EXT-7610 FIXED Added sorting outfit tabs by name (case insensitive). Reviewed by Neal Orman at https://codereview.productengine.com/secondlife/r/523/. --HG-- branch : product-engine --- indra/llui/llaccordionctrl.cpp | 13 +++++++++++++ indra/llui/llaccordionctrl.h | 35 ++++++++++++++++++++++++++++++++++- indra/llui/llaccordionctrltab.cpp | 2 +- indra/llui/llaccordionctrltab.h | 2 +- 4 files changed, 49 insertions(+), 3 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 5f866c49e6..6bf1347514 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -66,6 +66,7 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params) , mAutoScrolling( false ) , mAutoScrollRate( 0.f ) , mSelectedTab( NULL ) + , mTabComparator( NULL ) , mNoVisibleTabsHelpText(NULL) { initNoTabsWidget(params.empty_accordion_text); @@ -799,6 +800,18 @@ 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; diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h index 2f483eafb2..fc6f2d896c 100644 --- a/indra/llui/llaccordionctrl.h +++ b/indra/llui/llaccordionctrl.h @@ -57,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 { @@ -108,6 +121,9 @@ 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. */ @@ -134,6 +150,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; @@ -141,9 +172,11 @@ private: bool mFitParent; bool mAutoScrolling; F32 mAutoScrollRate; - LLAccordionCtrlTab* mSelectedTab; LLTextBox* mNoVisibleTabsHelpText; std::string mNoVisibleTabsOrigString; + + LLAccordionCtrlTab* mSelectedTab; + const LLTabComparator* mTabComparator; }; diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 83fcc77f2a..1bc8086a27 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -473,7 +473,7 @@ void LLAccordionCtrlTab::setAccordionView(LLView* panel) addChild(panel,0); } -std::string LLAccordionCtrlTab::getTitle() +std::string LLAccordionCtrlTab::getTitle() const { LLAccordionCtrlTabHeader* header = findChild(DD_HEADER_NAME); if (header) diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index be8b464b8e..82e0234bfc 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -115,7 +115,7 @@ 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); -- cgit v1.2.3