diff options
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/llui/llaccordionctrl.cpp | 20 | ||||
-rw-r--r-- | indra/llui/llaccordionctrltab.cpp | 3 | ||||
-rw-r--r-- | indra/llui/llflatlistview.cpp | 6 | ||||
-rw-r--r-- | indra/llui/lllineeditor.cpp | 2 | ||||
-rw-r--r-- | indra/llui/llloadingindicator.cpp | 135 | ||||
-rw-r--r-- | indra/llui/llloadingindicator.h | 93 | ||||
-rw-r--r-- | indra/llui/llui.cpp | 4 | ||||
-rw-r--r-- | indra/llui/lluifwd.h | 1 | ||||
-rw-r--r-- | indra/llui/llurlentry.cpp | 32 | ||||
-rw-r--r-- | indra/llui/llurlentry.h | 15 | ||||
-rw-r--r-- | indra/llui/llurlregistry.cpp | 6 |
12 files changed, 308 insertions, 11 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 532b6b6524..3ecab90756 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -52,6 +52,7 @@ set(llui_SOURCE_FILES llkeywords.cpp lllayoutstack.cpp lllineeditor.cpp + llloadingindicator.cpp lllocalcliprect.cpp llmenubutton.cpp llmenugl.cpp @@ -144,6 +145,7 @@ set(llui_HEADER_FILES lllayoutstack.h lllazyvalue.h lllineeditor.h + llloadingindicator.h lllocalcliprect.h llmenubutton.h llmenugl.h diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 136fd2a9ac..5d1d57cbb2 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -329,7 +329,7 @@ void LLAccordionCtrl::addCollapsibleCtrl(LLView* view) LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(view); if(!accordion_tab) return; - if(std::find(getChildList()->begin(),getChildList()->end(),accordion_tab) == getChildList()->end()) + if(std::find(beginChild(), endChild(), accordion_tab) == endChild()) addChild(accordion_tab); mAccordionTabs.push_back(accordion_tab); @@ -343,7 +343,7 @@ void LLAccordionCtrl::removeCollapsibleCtrl(LLView* view) if(!accordion_tab) return; - if(std::find(getChildList()->begin(),getChildList()->end(),accordion_tab) != getChildList()->end()) + if(std::find(beginChild(), endChild(), accordion_tab) != endChild()) removeChild(accordion_tab); for (std::vector<LLAccordionCtrlTab*>::iterator iter = mAccordionTabs.begin(); @@ -668,15 +668,23 @@ S32 LLAccordionCtrl::notifyParent(const LLSD& info) LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]); if(accordion_tab->hasFocus() && i>0) { + bool prev_visible_tab_found = false; while(i>0) { if(mAccordionTabs[--i]->getVisible()) + { + prev_visible_tab_found = true; break; + } } - - accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]); - accordion_tab->notify(LLSD().with("action","select_last")); - return 1; + + if (prev_visible_tab_found) + { + accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]); + accordion_tab->notify(LLSD().with("action","select_last")); + return 1; + } + break; } } return 0; diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index d389236642..3c706ce90e 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -554,7 +554,8 @@ S32 LLAccordionCtrlTab::notifyParent(const LLSD& info) } //LLAccordionCtrl should rearrange accodion tab if one of accordion change its size - getParent()->notifyParent(info); + if (getParent()) // A parent may not be set if tabs are added dynamically. + getParent()->notifyParent(info); return 1; } else if(str_action == "select_prev") diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 990bf5cd22..e0b2244654 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -744,12 +744,18 @@ LLRect LLFlatListView::getLastSelectedItemRect() void LLFlatListView::selectFirstItem () { + // No items - no actions! + if (mItemPairs.empty()) return; + selectItemPair(mItemPairs.front(), true); ensureSelectedVisible(); } void LLFlatListView::selectLastItem () { + // No items - no actions! + if (mItemPairs.empty()) return; + selectItemPair(mItemPairs.back(), true); ensureSelectedVisible(); } diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 843f72d8e4..45f9de8e8d 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1440,7 +1440,7 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char) BOOL LLLineEditor::canDoDelete() const { - return ( !mReadOnly && (!mPassDelete || (hasSelection() || (getCursor() < mText.length()))) ); + return ( !mReadOnly && mText.length() > 0 && (!mPassDelete || (hasSelection() || (getCursor() < mText.length()))) ); } void LLLineEditor::doDelete() diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp new file mode 100644 index 0000000000..8dec6ea9df --- /dev/null +++ b/indra/llui/llloadingindicator.cpp @@ -0,0 +1,135 @@ +/** + * @file llloadingindicator.cpp + * @brief Perpetual loading indicator + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llloadingindicator.h" + +// Linden library includes +#include "llsingleton.h" + +// Project includes +#include "lluictrlfactory.h" +#include "lluiimage.h" + +static LLDefaultChildRegistry::Register<LLLoadingIndicator> r("loading_indicator"); + +/////////////////////////////////////////////////////////////////////////////// +// LLLoadingIndicator::Data class +/////////////////////////////////////////////////////////////////////////////// + +/** + * Pre-loaded images shared by all instances of the widget + */ +class LLLoadingIndicator::Data: public LLSingleton<LLLoadingIndicator::Data> +{ +public: + /*virtual*/ void initSingleton(); // from LLSingleton + + LLPointer<LLUIImage> getNextImage(S8& idx) const; + U8 getImagesCount() const { return NIMAGES; } +private: + + static const U8 NIMAGES = 12; + LLPointer<LLUIImage> mImages[NIMAGES]; +}; + +// virtual +// Called right after the instance gets constructed. +void LLLoadingIndicator::Data::initSingleton() +{ + // Load images. + for (U8 i = 0; i < NIMAGES; ++i) + { + std::string img_name = llformat("Progress_%d", i+1); + mImages[i] = LLUI::getUIImage(img_name, 0); + llassert(mImages[i]); + } +} + +LLPointer<LLUIImage> LLLoadingIndicator::Data::getNextImage(S8& idx) const +{ + // Actually selects previous image because + // current images seem to be in wrong order; + // performs array bounds checking. + idx = idx > 0 ? llmin(NIMAGES-1, idx-1) : NIMAGES-1; + return mImages[idx]; +} + +/////////////////////////////////////////////////////////////////////////////// +// LLLoadingIndicator class +/////////////////////////////////////////////////////////////////////////////// + +LLLoadingIndicator::LLLoadingIndicator(const Params& p) +: LLUICtrl(p) + , mRotationsPerSec(p.rotations_per_sec > 0 ? p.rotations_per_sec : 1.0f) + , mCurImageIdx(-1) +{ + // Select initial image. + mCurImagep = Data::instance().getNextImage(mCurImageIdx); + + // Start timer for switching images. + start(); +} + +void LLLoadingIndicator::draw() +{ + // Time to switch to the next image? + if (mImageSwitchTimer.getStarted() && mImageSwitchTimer.hasExpired()) + { + // Switch to the next image. + mCurImagep = Data::instance().getNextImage(mCurImageIdx); + + // Restart timer. + start(); + } + + // Draw current image. + if( mCurImagep.notNull() ) + { + mCurImagep->draw(getLocalRect(), LLColor4::white % getDrawContext().mAlpha); + } + + LLUICtrl::draw(); +} + +void LLLoadingIndicator::stop() +{ + mImageSwitchTimer.stop(); +} + +void LLLoadingIndicator::start() +{ + mImageSwitchTimer.start(); + F32 period = 1.0f / (Data::instance().getImagesCount() * mRotationsPerSec); + mImageSwitchTimer.setTimerExpirySec(period); +} diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h new file mode 100644 index 0000000000..32dd1fead8 --- /dev/null +++ b/indra/llui/llloadingindicator.h @@ -0,0 +1,93 @@ +/** + * @file llloadingindicator.h + * @brief Perpetual loading indicator + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLLOADINGINDICATOR_H +#define LL_LLLOADINGINDICATOR_H + +#include "lluictrl.h" + +/////////////////////////////////////////////////////////////////////////////// +// class LLLoadingIndicator +/////////////////////////////////////////////////////////////////////////////// + +/** + * Perpetual loading indicator (a la MacOSX or YouTube) + * + * Number of rotations per second can be overriden + * with the "roations_per_sec" parameter. + * + * Can start/stop spinning. + * + * @see start() + * @see stop() + */ +class LLLoadingIndicator +: public LLUICtrl +{ + LOG_CLASS(LLLoadingIndicator); +public: + struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> + { + Optional<F32> rotations_per_sec; + Params() + : rotations_per_sec("rotations_per_sec", 1.0f) + {} + }; + + virtual ~LLLoadingIndicator() {} + + // llview overrides + virtual void draw(); + + /** + * Stop spinning. + */ + void stop(); + + /** + * Start spinning. + */ + void start(); + +private: + LLLoadingIndicator(const Params&); + friend class LLUICtrlFactory; + + class Data; + + F32 mRotationsPerSec; + S8 mCurImageIdx; + LLPointer<LLUIImage> mCurImagep; + LLFrameTimer mImageSwitchTimer; +}; + +#endif // LL_LLLOADINGINDICATOR_H diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index f9a4ed7285..bf12384a28 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -56,6 +56,7 @@ #include "llfloaterreg.h" #include "llmenugl.h" #include "llmenubutton.h" +#include "llloadingindicator.h" #include "llwindow.h" // for registration @@ -94,7 +95,10 @@ std::list<std::string> gUntranslated; static LLDefaultChildRegistry::Register<LLFilterEditor> register_filter_editor("filter_editor"); static LLDefaultChildRegistry::Register<LLFlyoutButton> register_flyout_button("flyout_button"); static LLDefaultChildRegistry::Register<LLSearchEditor> register_search_editor("search_editor"); + +// register other widgets which otherwise may not be linked in static LLDefaultChildRegistry::Register<LLMenuButton> register_menu_button("menu_button"); +static LLDefaultChildRegistry::Register<LLLoadingIndicator> register_loading_indicator("loading_indicator"); // diff --git a/indra/llui/lluifwd.h b/indra/llui/lluifwd.h index f99bb39fdd..d6047b943c 100644 --- a/indra/llui/lluifwd.h +++ b/indra/llui/lluifwd.h @@ -39,6 +39,7 @@ class LLComboBox; class LLDragHandle; class LLFloater; class LLIconCtrl; +class LLLoadingIndicator; class LLLineEditor; class LLMenuGL; class LLPanel; diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 736de651da..3375c13c94 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -765,3 +765,35 @@ std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelC { return getUrl(url); } + +// +// LLUrlEntryIcon describes an icon with <icon>...</icon> tags +// +LLUrlEntryIcon::LLUrlEntryIcon() +{ + mPattern = boost::regex("<icon\\s*>\\s*([^<]*)?\\s*</icon\\s*>", + boost::regex::perl|boost::regex::icase); + mDisabledLink = true; +} + +std::string LLUrlEntryIcon::getUrl(const std::string &url) const +{ + return LLStringUtil::null; +} + +std::string LLUrlEntryIcon::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ + return LLStringUtil::null; +} + +std::string LLUrlEntryIcon::getIcon(const std::string &url) +{ + // Grep icon info between <icon>...</icon> tags + // matches[1] contains the icon name/path + boost::match_results<std::string::const_iterator> matches; + mIcon = (boost::regex_match(url, matches, mPattern) && matches[1].matched) + ? matches[1] + : LLStringUtil::null; + LLStringUtil::trim(mIcon); + return mIcon; +} diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 29575d752c..71f030677a 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -77,7 +77,7 @@ public: virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; } /// Return an icon that can be displayed next to Urls of this type - std::string getIcon() const { return mIcon; } + virtual std::string getIcon(const std::string &url) { return mIcon; } /// Return the color to render the displayed text LLUIColor getColor() const { return mColor; } @@ -296,4 +296,17 @@ public: /*virtual*/ std::string getUrl(const std::string &string) const; }; +/// +/// LLUrlEntryIcon describes an icon with <icon>...</icon> tags +/// +class LLUrlEntryIcon : public LLUrlEntryBase +{ +public: + LLUrlEntryIcon(); + /*virtual*/ std::string getUrl(const std::string &string) const; + /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ std::string getIcon(const std::string &url); +}; + + #endif diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 0a70aa586a..4341286eb4 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -45,6 +45,7 @@ LLUrlRegistry::LLUrlRegistry() { // Urls are matched in the order that they were registered registerUrl(new LLUrlEntryNoLink()); + registerUrl(new LLUrlEntryIcon()); registerUrl(new LLUrlEntrySLURL()); registerUrl(new LLUrlEntryHTTP()); registerUrl(new LLUrlEntryHTTPLabel()); @@ -135,7 +136,8 @@ static bool stringHasUrl(const std::string &text) text.find(".net") != std::string::npos || text.find(".edu") != std::string::npos || text.find(".org") != std::string::npos || - text.find("<nolink>") != std::string::npos); + text.find("<nolink>") != std::string::npos || + text.find("<icon") != std::string::npos); } bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb) @@ -177,7 +179,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL match_entry->getUrl(url), match_entry->getLabel(url, cb), match_entry->getTooltip(url), - match_entry->getIcon(), + match_entry->getIcon(url), match_entry->getColor(), match_entry->getMenuName(), match_entry->getLocation(url), |