diff options
Diffstat (limited to 'indra/llui')
36 files changed, 770 insertions, 372 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 65ccb655dd..9d1b59cf66 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -51,7 +51,6 @@ set(llui_SOURCE_FILES llkeywords.cpp
lllayoutstack.cpp
lllineeditor.cpp
- lllistctrl.cpp
lllocalcliprect.cpp
llmenugl.cpp
llmodaldialog.cpp
@@ -88,6 +87,7 @@ set(llui_SOURCE_FILES lltextbox.cpp
lltexteditor.cpp
lltextparser.cpp
+ lltransientfloatermgr.cpp
lltransutil.cpp
lltooltip.cpp
llui.cpp
@@ -133,13 +133,12 @@ set(llui_HEADER_FILES llfocusmgr.h
llfunctorregistry.h
llhandle.h
- llhtmlhelp.h
+ llhelp.h
lliconctrl.h
llkeywords.h
lllayoutstack.h
lllazyvalue.h
lllineeditor.h
- lllistctrl.h
lllocalcliprect.h
llmenugl.h
llmodaldialog.h
@@ -177,6 +176,7 @@ set(llui_HEADER_FILES lltexteditor.h
lltextparser.h
lltooltip.h
+ lltransientfloatermgr.h
lltransutil.h
lluicolortable.h
lluiconstants.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index fa13ced037..b9613b502c 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -39,7 +39,6 @@ #include "llstring.h" // Project includes -#include "llhtmlhelp.h" #include "llkeyboard.h" #include "llui.h" #include "lluiconstants.h" @@ -49,8 +48,10 @@ #include "llfloaterreg.h" #include "llfocusmgr.h" #include "llwindow.h" +#include "llnotifications.h" #include "llrender.h" #include "lluictrlfactory.h" +#include "llhelp.h" static LLDefaultChildRegistry::Register<LLButton> r("button"); @@ -92,7 +93,6 @@ LLButton::Params::Params() mouse_held_callback("mouse_held_callback"), is_toggle("is_toggle", false), scale_image("scale_image", true), - help_url("help_url"), hover_glow_amount("hover_glow_amount"), commit_on_return("commit_on_return", true), picture_style("picture_style", false) @@ -173,11 +173,6 @@ LLButton::LLButton(const LLButton::Params& p) mMouseDownTimer.stop(); - if (p.help_url.isProvided()) - { - setHelpURLCallback(p.help_url); - } - // if custom unselected button image provided... if (p.image_unselected != default_params.image_unselected) { @@ -1034,24 +1029,6 @@ void LLButton::addImageAttributeToXML(LLXMLNodePtr node, } } -void clicked_help(void* data) -{ - LLButton* self = (LLButton*)data; - if (!self) return; - - if (!LLUI::sHtmlHelp) - { - return; - } - - LLUI::sHtmlHelp->show(self->getHelpURL()); -} - -void LLButton::setHelpURLCallback(const std::string &help_url) -{ - mHelpURL = help_url; - setClickedCallback(clicked_help,this); -} // static void LLButton::toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname) @@ -1077,6 +1054,24 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname) button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname)); } +// static +void LLButton::showHelp(LLUICtrl* ctrl, const LLSD& sdname) +{ + // search back through the button's parents for a panel + // with a help_topic string defined + std::string help_topic; + if (LLUI::sHelpImpl && + ctrl->findHelpTopic(help_topic)) + { + LLUI::sHelpImpl->showTopic(help_topic); + return; // success + } + + // display an error if we can't find a help_topic string. + // fix this by adding a help_topic attribute to the xui file + LLNotifications::instance().add("UnableToFindHelpTopic"); +} + void LLButton::resetMouseDownTimer() { mMouseDownTimer.stop(); diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 06e1dac914..04716d605b 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -118,7 +118,6 @@ public: commit_on_return, picture_style; //if true, don't display label - Optional<std::string> help_url; Optional<F32> hover_glow_amount; Optional<TimeIntervalParam> held_down_delay; @@ -230,12 +229,10 @@ public: void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; } BOOL getCommitOnReturn() const { return mCommitOnReturn; } - void setHelpURLCallback(const std::string &help_url); - const std::string& getHelpURL() const { return mHelpURL; } - static void onHeldDown(void *userdata); // to be called by gIdleCallbacks static void toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname); static void setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname); + static void showHelp(LLUICtrl* ctrl, const LLSD& sdname); protected: const LLPointer<LLUIImage>& getImageUnselected() const { return mImageUnselected; } @@ -314,8 +311,6 @@ private: BOOL mCommitOnReturn; BOOL mFadeWhenDisabled; - std::string mHelpURL; - LLFrameTimer mFlashingTimer; }; diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 58aeb61728..0170ac0c6a 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -483,7 +483,6 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p) params.max_length_bytes(mMaxChars); params.commit_callback.function(boost::bind(&LLComboBox::onTextCommit, this, _2)); params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1)); - params.focus_lost_callback(NULL); params.handle_edit_keys_directly(true); params.commit_on_focus_lost(false); params.follows.flags(FOLLOWS_ALL); diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index ed15d9d922..4525f0a45b 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -35,12 +35,21 @@ #include "lldockablefloater.h" //static -LLHandle<LLFloater> LLDockableFloater::instanceHandle; +LLHandle<LLFloater> LLDockableFloater::sInstanceHandle; LLDockableFloater::LLDockableFloater(LLDockControl* dockControl, const LLSD& key, const Params& params) : - LLFloater(key, params), mDockControl(dockControl) + LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(true) { + setDocked(mDockControl.get() != NULL && mDockControl.get()->isDockVisible()); + resetInstance(); +} + +LLDockableFloater::LLDockableFloater(LLDockControl* dockControl, bool uniqueDocking, + const LLSD& key, const Params& params) : + LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(uniqueDocking) +{ + setDocked(mDockControl.get() != NULL && mDockControl.get()->isDockVisible()); resetInstance(); } @@ -57,21 +66,13 @@ BOOL LLDockableFloater::postBuild() void LLDockableFloater::resetInstance() { - if (instanceHandle.get() != this) + if (mUniqueDocking && sInstanceHandle.get() != this) { - if (instanceHandle.get() != NULL && instanceHandle.get()->isDocked()) + if (sInstanceHandle.get() != NULL && sInstanceHandle.get()->isDocked()) { - //closeFloater() is not virtual - if (instanceHandle.get()->canClose()) - { - instanceHandle.get()->closeFloater(); - } - else - { - instanceHandle.get()->setVisible(FALSE); - } + sInstanceHandle.get()->setVisible(FALSE); } - instanceHandle = getHandle(); + sInstanceHandle = getHandle(); } } @@ -81,12 +82,18 @@ void LLDockableFloater::setVisible(BOOL visible) { resetInstance(); } + + if (visible && mDockControl.get() != NULL) + { + mDockControl.get()->repositionDockable(); + } + LLFloater::setVisible(visible); } void LLDockableFloater::setDocked(bool docked, bool pop_on_undock) { - if (mDockControl.get() != NULL) + if (mDockControl.get() != NULL && mDockControl.get()->isDockVisible()) { if (docked) { @@ -97,12 +104,16 @@ void LLDockableFloater::setDocked(bool docked, bool pop_on_undock) { mDockControl.get()->off(); } - } - if (!docked && pop_on_undock) + if (!docked && pop_on_undock) + { + // visually pop up a little bit to emphasize the undocking + translate(0, UNDOCK_LEAP_HEIGHT); + } + } + else { - // visually pop up a little bit to emphasize the undocking - translate(0, UNDOCK_LEAP_HEIGHT); + docked = false; } LLFloater::setDocked(docked, pop_on_undock); @@ -113,7 +124,10 @@ void LLDockableFloater::draw() if (mDockControl.get() != NULL) { mDockControl.get()->repositionDockable(); - mDockControl.get()->drawToungue(); + if (isDocked()) + { + mDockControl.get()->drawToungue(); + } } LLFloater::draw(); } @@ -121,7 +135,9 @@ void LLDockableFloater::draw() void LLDockableFloater::setDockControl(LLDockControl* dockControl) { mDockControl.reset(dockControl); + setDocked(mDockControl.get() != NULL && mDockControl.get()->isDockVisible()); } + const LLUIImagePtr& LLDockableFloater::getDockTongue() { return mDockTongue; diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h index 1d0e89cef5..ed90567ad3 100644 --- a/indra/llui/lldockablefloater.h +++ b/indra/llui/lldockablefloater.h @@ -46,12 +46,26 @@ class LLDockableFloater : public LLFloater static const U32 UNDOCK_LEAP_HEIGHT = 12; public: LOG_CLASS(LLDockableFloater); - LLDockableFloater(LLDockControl* dockControl, const LLSD& key, const Params& params = getDefaultParams()); + LLDockableFloater(LLDockControl* dockControl, const LLSD& key, + const Params& params = getDefaultParams()); + LLDockableFloater(LLDockControl* dockControl, bool uniqueDocking, + const LLSD& key, const Params& params = getDefaultParams()); virtual ~LLDockableFloater(); + static LLHandle<LLFloater> getInstanceHandle() { return sInstanceHandle; } + + /** + * If descendant class overrides postBuild() in order to perform specific + * construction then it must still invoke its superclass' implementation. + */ /* virtula */BOOL postBuild(); /* virtual */void setDocked(bool docked, bool pop_on_undock = true); /* virtual */void draw(); + + /** + * If descendant class overrides setVisible() then it must still invoke its + * superclass' implementation. + */ /*virtual*/ void setVisible(BOOL visible); private: @@ -69,7 +83,12 @@ protected: private: std::auto_ptr<LLDockControl> mDockControl; LLUIImagePtr mDockTongue; - static LLHandle<LLFloater> instanceHandle; + static LLHandle<LLFloater> sInstanceHandle; + /** + * Provides possibility to define that dockable floaters can be docked + * non exclusively. + */ + bool mUniqueDocking; }; #endif /* LL_DOCKABLEFLOATER_H */ diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp index d666f2be56..146c7a969a 100644 --- a/indra/llui/lldockcontrol.cpp +++ b/indra/llui/lldockcontrol.cpp @@ -35,12 +35,12 @@ #include "lldockcontrol.h" LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater, - const LLUIImagePtr& dockTongue, DocAt dockAt, bool enabled) : - mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue( - dockTongue) + const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) : + mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(dockTongue) { mDockAt = dockAt; - if (enabled) + + if (dockableFloater->isDocked()) { on(); } @@ -49,7 +49,17 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater, off(); } - if (dockWidget != NULL) { + if (!(get_allowed_rect_callback)) + { + mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1); + } + else + { + mGetAllowedRectCallback = get_allowed_rect_callback; + } + + if (dockWidget != NULL) + { repositionDockable(); } } @@ -67,65 +77,140 @@ void LLDockControl::setDock(LLView* dockWidget) } } +void LLDockControl::getAllowedRect(LLRect& rect) +{ + rect = mDockableFloater->getRootView()->getRect(); +} + void LLDockControl::repositionDockable() { - if (mEnabled) + LLRect dockRect = mDockWidget->calcScreenRect(); + LLRect rootRect; + mGetAllowedRectCallback(rootRect); + static BOOL prev_visibility = !mDockWidget->getVisible(); + + // recalculate dockable position if dock position changed, dock visibility changed, + // root view rect changed or recalculation is forced + if (mEnabled && (mPrevDockRect != dockRect || prev_visibility != mDockWidget->getVisible() + || mRootRect != rootRect || mRecalculateDocablePosition)) { - calculateDockablePosition(); + // undock dockable and off() if dock not visible + if (!isDockVisible()) + { + mDockableFloater->setDocked(false); + // force off() since dockable may not have dockControll at this time + off(); + } + else + { + moveDockable(); + } + + mPrevDockRect = dockRect; + mRootRect = rootRect; + mRecalculateDocablePosition = false; + prev_visibility = mDockWidget->getVisible(); } } -void LLDockControl::calculateDockablePosition() +bool LLDockControl::isDockVisible() { - LLRect dockRect = mDockWidget->calcScreenRect(); - LLRect rootRect = mDockableFloater->getRootView()->getRect(); + bool res = true; - // recalculate dockable position if dock position changed - // or root view rect changed or recalculation is forced - if (mPrevDockRect != dockRect || mRootRect != rootRect - || mRecalculateDocablePosition) + if (mDockWidget != NULL) { - LLRect dockableRect = mDockableFloater->calcScreenRect(); - S32 x = 0; - S32 y = 0; - switch (mDockAt) + //we should check all hierarchy + res = mDockWidget->isInVisibleChain(); + if (res) { - case TOP: - x = dockRect.getCenterX() - dockableRect.getWidth() / 2; - y = dockRect.mTop + mDockTongue->getHeight() - + dockableRect.getHeight(); - if (x < rootRect.mLeft) - { - x = rootRect.mLeft; - } - if (x + dockableRect.getWidth() > rootRect.mRight) + LLRect dockRect = mDockWidget->calcScreenRect(); + + switch (mDockAt) { - x = rootRect.mRight - dockableRect.getWidth(); + case TOP: + // check is dock inside parent rect + LLRect dockParentRect = + mDockWidget->getParent()->calcScreenRect(); + if (dockRect.mRight <= dockParentRect.mLeft + || dockRect.mLeft >= dockParentRect.mRight) + { + res = false; + } + break; } + } + } + + return res; +} + +void LLDockControl::moveDockable() +{ + // calculate new dockable position + LLRect dockRect = mDockWidget->calcScreenRect(); + LLRect rootRect; + mGetAllowedRectCallback(rootRect); + + LLRect dockableRect = mDockableFloater->calcScreenRect(); + S32 x = 0; + S32 y = 0; + switch (mDockAt) + { + case TOP: + x = dockRect.getCenterX() - dockableRect.getWidth() / 2; + y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight(); + // check is dockable inside root view rect + if (x < rootRect.mLeft) + { + x = rootRect.mLeft; + } + if (x + dockableRect.getWidth() > rootRect.mRight) + { + x = rootRect.mRight - dockableRect.getWidth(); + } + + + // calculate dock tongue position + LLRect dockParentRect = + mDockWidget->getParent()->calcScreenRect(); + if (dockRect.getCenterX() < dockParentRect.mLeft) + { + mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2; + } + else if (dockRect.getCenterX() > dockParentRect.mRight) + { + mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;; + } + else + { mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2; - mDockTongueY = dockRect.mTop; - break; } - dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), - dockableRect.getHeight()); - LLRect localDocableParentRect; - mDockableFloater->getParent()->screenRectToLocal(dockableRect, - &localDocableParentRect); - mDockableFloater->setRect(localDocableParentRect); - - mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY, - &mDockTongueX, &mDockTongueY); - mPrevDockRect = dockRect; - mRootRect = rootRect; - mRecalculateDocablePosition = false; + mDockTongueY = dockRect.mTop; + + break; } + + // move dockable + dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), + dockableRect.getHeight()); + LLRect localDocableParentRect; + mDockableFloater->getParent()->screenRectToLocal(dockableRect, + &localDocableParentRect); + mDockableFloater->setRect(localDocableParentRect); + + mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY, + &mDockTongueX, &mDockTongueY); + } void LLDockControl::on() { - mDockableFloater->setCanDrag(false); - mEnabled = true; - mRecalculateDocablePosition = true; + if (isDockVisible()) + { + mDockableFloater->setCanDrag(false); + mEnabled = true; + mRecalculateDocablePosition = true; + } } void LLDockControl::off() @@ -141,3 +226,4 @@ void LLDockControl::drawToungue() mDockTongue->draw(mDockTongueX, mDockTongueY); } } + diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h index 7d8d5c7653..e8ffcac0ac 100644 --- a/indra/llui/lldockcontrol.h +++ b/indra/llui/lldockcontrol.h @@ -51,10 +51,12 @@ public: }; public: + // callback for a function getting a rect valid for control's position + typedef boost::function<void (LLRect& )> get_allowed_rect_callback_t; + LOG_CLASS(LLDockControl); LLDockControl(LLView* dockWidget, LLFloater* dockableFloater, - const LLUIImagePtr& dockTongue, DocAt dockAt, - bool enabled); + const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_rect_callback = NULL); virtual ~LLDockControl(); public: @@ -63,9 +65,15 @@ public: void setDock(LLView* dockWidget); void repositionDockable(); void drawToungue(); -protected: - virtual void calculateDockablePosition(); + bool isDockVisible(); + + // gets a rect that bounds possible positions for a dockable control (EXT-1111) + void getAllowedRect(LLRect& rect); + +private: + virtual void moveDockable(); private: + get_allowed_rect_callback_t mGetAllowedRectCallback; bool mEnabled; bool mRecalculateDocablePosition; DocAt mDockAt; diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 75334acb39..e9df361472 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -33,13 +33,16 @@ #include "linden_common.h" #include "llpanel.h" +#include "lltextbox.h" #include "llflatlistview.h" static const LLDefaultChildRegistry::Register<LLFlatListView> flat_list_view("flat_list_view"); -const LLSD SELECTED_EVENT = LLSD().insert("selected", true); -const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false); +const LLSD SELECTED_EVENT = LLSD().insert("selected", true); +const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false); + +static const std::string COMMENT_TEXTBOX = "comment_text"; LLFlatListView::Params::Params() : item_pad("item_pad"), @@ -55,7 +58,12 @@ void LLFlatListView::reshape(S32 width, S32 height, BOOL called_from_parent /* = rearrangeItems(); } -bool LLFlatListView::addItem(LLPanel* item, LLSD value /* = LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/) +const LLRect& LLFlatListView::getItemsRect() const +{ + return mItemsPanel->getRect(); +} + +bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/) { if (!item) return false; if (value.isUndefined()) return false; @@ -84,11 +92,12 @@ bool LLFlatListView::addItem(LLPanel* item, LLSD value /* = LLUUID::null*/, EAdd item->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4)); rearrangeItems(); + notifyParentItemsRectChanged(); return true; } -bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, LLSD value /*= LLUUID::null*/) +bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value /*= LLUUID::null*/) { if (!after_item) return false; if (!item_to_add) return false; @@ -111,11 +120,11 @@ bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, else { pairs_iterator_t it = mItemPairs.begin(); - ++it; - while (it != mItemPairs.end()) + for (; it != mItemPairs.end(); ++it) { if (*it == after_pair) { + // insert new elements before the element at position of passed iterator. mItemPairs.insert(++it, new_pair); mItemsPanel->addChild(item_to_add); break; @@ -128,6 +137,7 @@ bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, item_to_add->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4)); rearrangeItems(); + notifyParentItemsRectChanged(); return true; } @@ -153,14 +163,14 @@ bool LLFlatListView::removeItemByValue(const LLSD& value) return removeItemPair(item_pair); } -bool LLFlatListView::removeItemByUUID(LLUUID& uuid) +bool LLFlatListView::removeItemByUUID(const LLUUID& uuid) { return removeItemByValue(LLSD(uuid)); } -LLPanel* LLFlatListView::getItemByValue(LLSD& value) const +LLPanel* LLFlatListView::getItemByValue(const LLSD& value) const { - if (value.isDefined()) return NULL; + if (value.isUndefined()) return NULL; item_pair_t* pair = getItemPair(value); if (pair) return pair->first; @@ -188,7 +198,7 @@ bool LLFlatListView::selectItemByValue(const LLSD& value, bool select /*= true*/ return selectItemPair(item_pair, select); } -bool LLFlatListView::selectItemByUUID(LLUUID& uuid, bool select /* = true*/) +bool LLFlatListView::selectItemByUUID(const LLUUID& uuid, bool select /* = true*/) { return selectItemByValue(LLSD(uuid), select); } @@ -252,7 +262,7 @@ void LLFlatListView::getSelectedItems(std::vector<LLPanel*>& selected_items) con } } -void LLFlatListView::resetSelection() +void LLFlatListView::resetSelection(bool no_commit_on_deselection /*= false*/) { if (mSelectedItemPairs.empty()) return; @@ -264,6 +274,29 @@ void LLFlatListView::resetSelection() } mSelectedItemPairs.clear(); + + if (mCommitOnSelectionChange && !no_commit_on_deselection) + { + onCommit(); + } +} + +void LLFlatListView::setNoItemsCommentText(const std::string& comment_text) +{ + if (NULL == mNoItemsCommentTextbox) + { + LLRect comment_rect = getRect(); + comment_rect.setOriginAndSize(0, 0, comment_rect.getWidth(), comment_rect.getHeight()); + comment_rect.stretch(-getBorderWidth()); + LLTextBox::Params text_p; + text_p.name(COMMENT_TEXTBOX); + text_p.border_visible(false); + text_p.rect(comment_rect); + text_p.follows.flags(FOLLOWS_ALL); + mNoItemsCommentTextbox = LLUICtrlFactory::create<LLTextBox>(text_p, this); + } + + mNoItemsCommentTextbox->setValue(comment_text); } void LLFlatListView::clear() @@ -272,11 +305,32 @@ void LLFlatListView::clear() for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it) { mItemsPanel->removeChild((*it)->first); - delete (*it)->first; + (*it)->first->die(); delete *it; } mItemPairs.clear(); mSelectedItemPairs.clear(); + + // also set items panel height to zero. Reshape it to allow reshaping of non-item children + LLRect rc = mItemsPanel->getRect(); + rc.mBottom = rc.mTop; + mItemsPanel->reshape(rc.getWidth(), rc.getHeight()); + mItemsPanel->setRect(rc); + + setNoItemsCommentVisible(true); + notifyParentItemsRectChanged(); +} + +void LLFlatListView::sort() +{ + if (!mItemComparator) + { + llwarns << "No comparator specified for sorting FlatListView items." << llendl; + return; + } + + mItemPairs.sort(ComparatorAdaptor(*mItemComparator)); + rearrangeItems(); } @@ -286,12 +340,16 @@ void LLFlatListView::clear() LLFlatListView::LLFlatListView(const LLFlatListView::Params& p) -: LLScrollContainer(p), - mItemsPanel(NULL), - mItemPad(p.item_pad), - mAllowSelection(p.allow_select), - mMultipleSelection(p.multi_select), - mKeepOneItemSelected(p.keep_one_selected) +: LLScrollContainer(p) + , mItemComparator(NULL) + , mItemsPanel(NULL) + , mItemPad(p.item_pad) + , mAllowSelection(p.allow_select) + , mMultipleSelection(p.multi_select) + , mKeepOneItemSelected(p.keep_one_selected) + , mCommitOnSelectionChange(false) + , mPrevNotifyParentRect(LLRect()) + , mNoItemsCommentTextbox(NULL) { mBorderThickness = getBorderWidth(); @@ -315,19 +373,32 @@ void LLFlatListView::rearrangeItems() { static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); + setNoItemsCommentVisible(mItemPairs.empty()); + if (mItemPairs.empty()) return; //calculating required height - assuming items can be of different height //list should accommodate all its items S32 height = 0; + S32 invisible_children_count = 0; pairs_iterator_t it = mItemPairs.begin(); for (; it != mItemPairs.end(); ++it) { LLPanel* item = (*it)->first; + + // skip invisible child + if (!item->getVisible()) + { + ++invisible_children_count; + continue; + } + height += item->getRect().getHeight(); } - height += mItemPad * (mItemPairs.size() - 1); + + // add paddings between items, excluding invisible ones + height += mItemPad * (mItemPairs.size() - invisible_children_count - 1); LLRect rc = mItemsPanel->getRect(); S32 width = mItemsNoScrollWidth; @@ -346,14 +417,18 @@ void LLFlatListView::rearrangeItems() for (it2 = first_it; it2 != mItemPairs.end(); ++it2) { LLPanel* item = (*it2)->first; + + // skip invisible child + if (!item->getVisible()) + continue; + LLRect rc = item->getRect(); - if(it2 != first_it) - { - item_new_top -= (rc.getHeight() + mItemPad); - } rc.setLeftTopAndSize(rc.mLeft, item_new_top, width, rc.getHeight()); item->reshape(rc.getWidth(), rc.getHeight()); item->setRect(rc); + + // move top for next item in list + item_new_top -= (rc.getHeight() + mItemPad); } } @@ -443,6 +518,12 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select) //a way of notifying panel of selection state changes LLPanel* item = item_pair->first; item->setValue(select ? SELECTED_EVENT : UNSELECTED_EVENT); + + if (mCommitOnSelectionChange) + { + onCommit(); + } + return true; } @@ -483,12 +564,82 @@ bool LLFlatListView::removeItemPair(item_pair_t* item_pair) } mItemsPanel->removeChild(item_pair->first); - delete item_pair->first; + item_pair->first->die(); delete item_pair; rearrangeItems(); + notifyParentItemsRectChanged(); return true; } +void LLFlatListView::notifyParentItemsRectChanged() +{ + S32 comment_height = 0; + + // take into account comment text height if exists + if (mNoItemsCommentTextbox && mNoItemsCommentTextbox->getVisible()) + { + comment_height = mNoItemsCommentTextbox->getTextPixelHeight(); + } + + LLRect req_rect = getItemsRect(); + + // get maximum of items total height and comment text height + req_rect.setOriginAndSize(req_rect.mLeft, req_rect.mBottom, req_rect.getWidth(), llmax(req_rect.getHeight(), comment_height)); + + // take into account border size. + req_rect.stretch(getBorderWidth()); + + if (req_rect == mPrevNotifyParentRect) + return; + + mPrevNotifyParentRect = req_rect; + + LLSD params; + params["action"] = "size_changes"; + params["width"] = req_rect.getWidth(); + params["height"] = req_rect.getHeight(); + + getParent()->notifyParent(params); +} + +void LLFlatListView::setNoItemsCommentVisible(bool visible) const +{ + if (mNoItemsCommentTextbox) + { + if (visible) + { + // We have to update child rect here because of issues with rect after reshaping while creating LLTextbox + // It is possible to have invalid LLRect if Flat List is in LLAccordionTab + LLRect comment_rect = getLocalRect(); + comment_rect.stretch(-getBorderWidth()); + mNoItemsCommentTextbox->setRect(comment_rect); + } + mNoItemsCommentTextbox->setVisible(visible); + } +} + +void LLFlatListView::getItems(std::vector<LLPanel*>& items) const +{ + if (mItemPairs.empty()) return; + + items.clear(); + for (pairs_const_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it) + { + items.push_back((*it)->first); + } +} + +void LLFlatListView::getValues(std::vector<LLSD>& values) const +{ + if (mItemPairs.empty()) return; + + values.clear(); + for (pairs_const_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it) + { + values.push_back((*it)->second); + } +} +//EOF diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index bd0b419f4f..af5a9cfa9b 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -33,10 +33,10 @@ #ifndef LL_LLFLATLISTVIEW_H #define LL_LLFLATLISTVIEW_H +#include "llpanel.h" #include "llscrollcontainer.h" - -class LLPanel; +class LLTextBox; /** * LLFlatListView represents a flat list ui control that operates on items in a form of LLPanel's. @@ -62,6 +62,38 @@ class LLFlatListView : public LLScrollContainer { public: + /** + * Abstract comparator for comparing flat list items in a form of LLPanel + */ + class ItemComparator + { + public: + ItemComparator() {}; + virtual ~ItemComparator() {}; + + /** Returns true if item1 < item2, false otherwise */ + virtual bool compare(const LLPanel* item1, const LLPanel* item2) const = 0; + }; + + /** + * Represents reverse comparator which acts as a decorator for a comparator that need to be reversed + */ + class ItemReverseComparator : public ItemComparator + { + public: + ItemReverseComparator(const ItemComparator& comparator) : mComparator(comparator) {}; + virtual ~ItemReverseComparator() {}; + + virtual bool compare(const LLPanel* item1, const LLPanel* item2) const + { + return mComparator.compare(item2, item1); + } + + private: + const ItemComparator& mComparator; + }; + + struct Params : public LLInitParam::Block<Params, LLScrollContainer::Params> { /** turning on/off selection support */ @@ -85,18 +117,23 @@ public: /** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */ virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + /** Returns full rect of child panel */ + const LLRect& getItemsRect() const; + + /** Returns distance between items */ + const S32 getItemsPad() { return mItemPad; } /** * Adds and item and LLSD value associated with it to the list at specified position * @return true if the item was added, false otherwise */ - virtual bool addItem(LLPanel* item, LLSD value = LLUUID::null, EAddPosition pos = ADD_BOTTOM); + virtual bool addItem(LLPanel * item, const LLSD& value = LLUUID::null, EAddPosition pos = ADD_BOTTOM); /** * Insert item_to_add along with associated value to the list right after the after_item. * @return true if the item was successfully added, false otherwise */ - virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, LLSD value = LLUUID::null); + virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value = LLUUID::null); /** * Remove specified item @@ -114,13 +151,19 @@ public: * Remove an item specified by uuid * @return true if the item was removed, false otherwise */ - virtual bool removeItemByUUID(LLUUID& uuid); + virtual bool removeItemByUUID(const LLUUID& uuid); /** * Get an item by value * @return the item as LLPanel if associated with value, NULL otherwise */ - virtual LLPanel* getItemByValue(LLSD& value) const; + virtual LLPanel* getItemByValue(const LLSD& value) const; + + template<class T> + T* getTypedItemByValue(const LLSD& value) const + { + return dynamic_cast<T*>(getItemByValue(value)); + } /** * Select or deselect specified item based on select @@ -138,9 +181,17 @@ public: * Select or deselect an item by associated uuid based on select * @return true if succeed, false otherwise */ - virtual bool selectItemByUUID(LLUUID& uuid, bool select = true); + virtual bool selectItemByUUID(const LLUUID& uuid, bool select = true); + /** + * Get all panels stored in the list. + */ + virtual void getItems(std::vector<LLPanel*>& items) const; + /** + * Get all items values. + */ + virtual void getValues(std::vector<LLSD>& values) const; /** * Get LLSD associated with the first selected item @@ -176,9 +227,23 @@ public: virtual void getSelectedItems(std::vector<LLPanel*>& selected_items) const; - /** Resets selection of items */ - virtual void resetSelection(); + /** + * Resets selection of items. + * + * It calls onCommit callback if setCommitOnSelectionChange(bool b) was called with "true" + * argument for current Flat List. + * @param no_commit_on_deselection - if true onCommit callback will not be called + */ + virtual void resetSelection(bool no_commit_on_deselection = false); + /** + * Sets comment text which will be shown in the list is it is empty. + * + * Textbox to hold passed text is created while this method is called at the first time. + * + * @param comment_text - string to be shown as a comment. + */ + void setNoItemsCommentText( const std::string& comment_text); /** Turn on/off multiple selection support */ void setAllowMultipleSelection(bool allow) { mMultipleSelection = allow; } @@ -186,6 +251,8 @@ public: /** Turn on/off selection support */ void setAllowSelection(bool can_select) { mAllowSelection = can_select; } + /** Sets flag whether onCommit should be fired if selection was changed */ + void setCommitOnSelectionChange(bool b) { mCommitOnSelectionChange = b; } /** Get number of selected items in the list */ U32 numSelected() const {return mSelectedItemPairs.size(); } @@ -197,6 +264,14 @@ public: /** Removes all items from the list */ virtual void clear(); + /** + * Set comparator to use for future sorts. + * + * This class does NOT manage lifetime of the comparator + * but assumes that the comparator is always alive. + */ + void setComparator(const ItemComparator* comp) { mItemComparator = comp; } + void sort(); protected: @@ -207,6 +282,19 @@ protected: typedef pairs_list_t::iterator pairs_iterator_t; typedef pairs_list_t::const_iterator pairs_const_iterator_t; + /** An adapter for a ItemComparator */ + struct ComparatorAdaptor + { + ComparatorAdaptor(const ItemComparator& comparator) : mComparator(comparator) {}; + + bool operator()(const item_pair_t* item_pair1, const item_pair_t* item_pair2) + { + return mComparator.compare(item_pair1->first, item_pair2->first); + } + + const ItemComparator& mComparator; + }; + friend class LLUICtrlFactory; LLFlatListView(const LLFlatListView::Params& p); @@ -214,7 +302,10 @@ protected: /** Manage selection on mouse events */ void onItemMouseClick(item_pair_t* item_pair, MASK mask); - /** Updates position of items */ + /** + * Updates position of items. + * It does not take into account invisible items. + */ virtual void rearrangeItems(); virtual item_pair_t* getItemPair(LLPanel* item) const; @@ -227,14 +318,27 @@ protected: virtual bool removeItemPair(item_pair_t* item_pair); + /** + * Notify parent about changed size of internal controls with "size_changes" action + * + * Size includes Items Rect width and either Items Rect height or comment text height. + * Comment text height is included if comment text is set and visible. + * List border size is also included into notified size. + */ + void notifyParentItemsRectChanged(); + private: void setItemsNoScrollWidth(S32 new_width) {mItemsNoScrollWidth = new_width - 2 * mBorderThickness;} + void setNoItemsCommentVisible(bool visible) const; private: + /** Comparator to use when sorting the list. */ + const ItemComparator* mItemComparator; + LLPanel* mItemsPanel; S32 mItemsNoScrollWidth; @@ -242,7 +346,7 @@ private: S32 mBorderThickness; /** Items padding */ - U32 mItemPad; + S32 mItemPad; /** Selection support flag */ bool mAllowSelection; @@ -250,6 +354,14 @@ private: /** Multiselection support flag, ignored if selection is not supported */ bool mMultipleSelection; + /** + * Flag specified whether onCommit be called if selection is changed in the list. + * + * Can be ignored in the resetSelection() method. + * @see resetSelection() + */ + bool mCommitOnSelectionChange; + bool mKeepOneItemSelected; /** All pairs of the list */ @@ -257,6 +369,14 @@ private: /** Selected pairs for faster access */ pairs_list_t mSelectedItemPairs; + + /** + * Rectangle contained previous size of items parent notified last time. + * Is used to reduce amount of parentNotify() calls if size was not changed. + */ + LLRect mPrevNotifyParentRect; + + LLTextBox* mNoItemsCommentTextbox; }; #endif diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index a57913683b..e0fe85ea01 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -59,6 +59,7 @@ #include "lltabcontainer.h" #include "v2math.h" #include "lltrans.h" +#include "llhelp.h" #include "llmultifloater.h" #include "llsdutil.h" @@ -67,48 +68,35 @@ const S32 TABBED_FLOATER_OFFSET = 0; std::string LLFloater::sButtonActiveImageNames[BUTTON_COUNT] = { - "Icon_Close_Foreground", //BUTTON_CLOSE - "restore.tga", //BUTTON_RESTORE - "minimize.tga", //BUTTON_MINIMIZE - "tearoffbox.tga", //BUTTON_TEAR_OFF - "closebox.tga", //BUTTON_EDIT - "Icon_Dock_Foreground", - "Icon_Undock_Foreground" -}; - -// Empty string means programmatic glow effect, achieved by -// not setting explicit image. -std::string LLFloater::sButtonHoveredImageNames[BUTTON_COUNT] = -{ - "", //BUTTON_CLOSE - "restore_pressed.tga", //BUTTON_RESTORE - "minimize_pressed.tga", //BUTTON_MINIMIZE - "tearoff_pressed.tga", //BUTTON_TEAR_OFF - "close_in_blue.tga", //BUTTON_EDIT - "", //BUTTON_DOCK - "", //BUTTON_UNDOCK + "Icon_Close_Foreground", //BUTTON_CLOSE + "Icon_Restore_Foreground", //BUTTON_RESTORE + "Icon_Minimize_Foreground", //BUTTON_MINIMIZE + "tearoffbox.tga", //BUTTON_TEAR_OFF + "Icon_Dock_Foreground", //BUTTON_DOCK + "Icon_Undock_Foreground", //BUTTON_UNDOCK + "Icon_Help_Foreground" //BUTTON_HELP }; std::string LLFloater::sButtonPressedImageNames[BUTTON_COUNT] = { - "Icon_Close_Press", //BUTTON_CLOSE - "restore_pressed.tga", //BUTTON_RESTORE - "minimize_pressed.tga", //BUTTON_MINIMIZE - "tearoff_pressed.tga", //BUTTON_TEAR_OFF - "close_in_blue.tga", //BUTTON_EDIT - "Icon_Dock_Press", - "Icon_Undock_Press" + "Icon_Close_Press", //BUTTON_CLOSE + "Icon_Restore_Press", //BUTTON_RESTORE + "Icon_Minimize_Press", //BUTTON_MINIMIZE + "tearoff_pressed.tga", //BUTTON_TEAR_OFF + "Icon_Dock_Press", //BUTTON_DOCK + "Icon_Undock_Press", //BUTTON_UNDOCK + "Icon_Help_Press" //BUTTON_HELP }; std::string LLFloater::sButtonNames[BUTTON_COUNT] = { - "llfloater_close_btn", //BUTTON_CLOSE + "llfloater_close_btn", //BUTTON_CLOSE "llfloater_restore_btn", //BUTTON_RESTORE "llfloater_minimize_btn", //BUTTON_MINIMIZE "llfloater_tear_off_btn", //BUTTON_TEAR_OFF - "llfloater_edit_btn", //BUTTON_EDIT - "llfloater_dock_btn", - "llfloater_undock_btn" + "llfloater_dock_btn", //BUTTON_DOCK + "llfloater_undock_btn", //BUTTON_UNDOCK + "llfloater_help_btn" //BUTTON_HELP }; std::string LLFloater::sButtonToolTips[BUTTON_COUNT]; @@ -123,9 +111,9 @@ std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]= "BUTTON_RESTORE", //"Restore", //BUTTON_RESTORE "BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE "BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF - "BUTTON_EDIT", //"Edit", //BUTTON_EDIT "BUTTON_DOCK", - "BUTTON_UNDOCK" + "BUTTON_UNDOCK", + "BUTTON_HELP" }; LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] = @@ -134,13 +122,12 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] = LLFloater::onClickMinimize, //BUTTON_RESTORE LLFloater::onClickMinimize, //BUTTON_MINIMIZE LLFloater::onClickTearOff, //BUTTON_TEAR_OFF - LLFloater::onClickEdit, //BUTTON_EDIT - LLFloater::onClickDock, - LLFloater::onClickDock + LLFloater::onClickDock, //BUTTON_DOCK + LLFloater::onClickDock, //BUTTON_UNDOCK + LLFloater::onClickHelp //BUTTON_HELP }; LLMultiFloater* LLFloater::sHostp = NULL; -BOOL LLFloater::sEditModeEnabled = FALSE; BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting LLFloater::handle_map_t LLFloater::sFloaterMap; @@ -249,7 +236,6 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) mMinimized(FALSE), mForeground(FALSE), mFirstLook(TRUE), - mEditing(FALSE), mButtonScale(1.0f), mAutoFocus(TRUE), // automatically take focus when opened mCanDock(false), @@ -304,6 +290,12 @@ void LLFloater::initFloater() mButtonsEnabled[BUTTON_CLOSE] = TRUE; } + // Help button: '?' + if ( !mHelpTopic.empty() ) + { + mButtonsEnabled[BUTTON_HELP] = TRUE; + } + // Minimize button only for top draggers if ( !mDragOnLeft && mCanMinimize ) { @@ -794,7 +786,7 @@ void LLFloater::setTitle( const std::string& title ) applyTitle(); } -std::string LLFloater::getTitle() +std::string LLFloater::getTitle() const { if (mTitle.empty()) { @@ -812,7 +804,7 @@ void LLFloater::setShortTitle( const std::string& short_title ) applyTitle(); } -std::string LLFloater::getShortTitle() +std::string LLFloater::getShortTitle() const { if (mShortTitle.empty()) { @@ -824,8 +816,6 @@ std::string LLFloater::getShortTitle() } } - - BOOL LLFloater::canSnapTo(const LLView* other_view) { if (NULL == other_view) @@ -1041,6 +1031,10 @@ void LLFloater::setMinimized(BOOL minimize) reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE ); } + // don't show the help button while minimized - it's + // not very useful when minimized and uses up space + mButtonsEnabled[BUTTON_HELP] = !minimize; + applyTitle (); make_ui_sound("UISndWindowClose"); @@ -1377,28 +1371,6 @@ void LLFloater::setDocked(bool docked, bool pop_on_undock) } } -//static -void LLFloater::setEditModeEnabled(BOOL enable) -{ - if (enable != sEditModeEnabled) - { - S32 count = 0; - for(handle_map_iter_t iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter) - { - LLFloater* floater = iter->second; - if (!floater->isDead()) - { - iter->second->mButtonsEnabled[BUTTON_EDIT] = enable; - iter->second->updateButtons(); - } - count++; - } - } - - sEditModeEnabled = enable; -} - - // static void LLFloater::onClickMinimize(LLFloater* self) { @@ -1446,19 +1418,20 @@ void LLFloater::onClickTearOff(LLFloater* self) } // static -void LLFloater::onClickEdit(LLFloater* self) +void LLFloater::onClickDock(LLFloater* self) { - if (!self) - return; - self->mEditing = self->mEditing ? FALSE : TRUE; + if(self && self->mCanDock) + { + self->setDocked(!self->mDocked, true); + } } // static -void LLFloater::onClickDock(LLFloater* self) +void LLFloater::onClickHelp( LLFloater* self ) { - if(self && self->mCanDock) + if (self && LLUI::sHelpImpl) { - self->setDocked(!self->mDocked, true); + LLUI::sHelpImpl->showTopic(self->getHelpTopic()); } } @@ -1797,17 +1770,9 @@ void LLFloater::buildButtons() // Selected, no matter if hovered or not, is "pressed" p.image_selected.name(sButtonPressedImageNames[i]); p.image_hover_selected.name(sButtonPressedImageNames[i]); - // Empty string means programmatic glow effect, achieved by - // not setting explicit image. - if (sButtonHoveredImageNames[i].empty()) - { - // These icons are really small, need glow amount increased - p.hover_glow_amount( 0.22f ); - } - else - { - p.image_hover_unselected.name(sButtonHoveredImageNames[i]); - } + // Use a glow effect when the user hovers over the button + // These icons are really small, need glow amount increased + p.hover_glow_amount( 0.33f ); p.click_callback.function(boost::bind(sButtonCallbacks[i], this)); p.tab_stop(false); p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT); diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 6208d52135..a320ba4a6f 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -103,9 +103,9 @@ public: BUTTON_RESTORE, BUTTON_MINIMIZE, BUTTON_TEAR_OFF, - BUTTON_EDIT, BUTTON_DOCK, BUTTON_UNDOCK, + BUTTON_HELP, BUTTON_COUNT }; @@ -175,9 +175,9 @@ public: void applyTitle(); const std::string& getCurrentTitle() const; void setTitle( const std::string& title); - std::string getTitle(); + std::string getTitle() const; void setShortTitle( const std::string& short_title ); - std::string getShortTitle(); + std::string getShortTitle() const; void setTitleVisible(bool visible); virtual void setMinimized(BOOL b); void moveResizeHandlesToFront(); @@ -258,12 +258,10 @@ public: static void onClickClose(LLFloater* floater); static void onClickMinimize(LLFloater* floater); static void onClickTearOff(LLFloater* floater); - static void onClickEdit(LLFloater* floater); static void onClickDock(LLFloater* floater); + static void onClickHelp(LLFloater* floater); static void setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; } - static void setEditModeEnabled(BOOL enable); - static BOOL getEditModeEnabled() { return sEditModeEnabled; } static LLMultiFloater* getFloaterHost() {return sHostp; } protected: @@ -333,7 +331,6 @@ private: BOOL mFirstLook; // TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible. - BOOL mEditing; typedef std::set<LLHandle<LLFloater> > handle_set_t; typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t; @@ -352,11 +349,8 @@ private: bool mDocked; static LLMultiFloater* sHostp; - static BOOL sEditModeEnabled; static BOOL sQuitting; static std::string sButtonActiveImageNames[BUTTON_COUNT]; - // Images to use when cursor hovered over an enabled button - static std::string sButtonHoveredImageNames[BUTTON_COUNT]; static std::string sButtonPressedImageNames[BUTTON_COUNT]; static std::string sButtonNames[BUTTON_COUNT]; static std::string sButtonToolTips[BUTTON_COUNT]; diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 60ddbc6cb3..279cbaa923 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -41,11 +41,6 @@ const F32 FOCUS_FADE_TIME = 0.3f; // NOTE: the LLFocusableElement implementation has been moved here from lluictrl.cpp. LLFocusableElement::LLFocusableElement() -: mFocusLostCallback(NULL), - mFocusReceivedCallback(NULL), - mFocusChangedCallback(NULL), - mTopLostCallback(NULL), - mFocusCallbackUserData(NULL) { } @@ -68,35 +63,19 @@ LLFocusableElement::~LLFocusableElement() void LLFocusableElement::onFocusReceived() { - if( mFocusReceivedCallback ) - { - mFocusReceivedCallback( this, mFocusCallbackUserData ); - } - if( mFocusChangedCallback ) - { - mFocusChangedCallback( this, mFocusCallbackUserData ); - } + mFocusReceivedCallback(this); + mFocusChangedCallback(this); } void LLFocusableElement::onFocusLost() { - if( mFocusLostCallback ) - { - mFocusLostCallback( this, mFocusCallbackUserData ); - } - - if( mFocusChangedCallback ) - { - mFocusChangedCallback( this, mFocusCallbackUserData ); - } + mFocusLostCallback(this); + mFocusChangedCallback(this); } void LLFocusableElement::onTopLost() { - if (mTopLostCallback) - { - mTopLostCallback(this, mFocusCallbackUserData); - } + mTopLostCallback(this); } BOOL LLFocusableElement::hasFocus() const @@ -188,12 +167,9 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL view_handle_list_t new_focus_list; // walk up the tree to root and add all views to the new_focus_list - for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl && ctrl != LLUI::getRootView(); ctrl = ctrl->getParent()) + for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl; ctrl = ctrl->getParent()) { - if (ctrl) - { - new_focus_list.push_back(ctrl->getHandle()); - } + new_focus_list.push_back(ctrl->getHandle()); } // remove all common ancestors since their focus is unchanged diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index d0adadd6d3..2fa4e124fb 100644 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -54,11 +54,12 @@ public: virtual void setFocus( BOOL b ); virtual BOOL hasFocus() const; - typedef boost::function<void(LLFocusableElement*, void*)> focus_callback_t; - void setFocusLostCallback(focus_callback_t cb, void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; } - void setFocusReceivedCallback(focus_callback_t cb, void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; } - void setFocusChangedCallback(focus_callback_t cb, void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; } - void setTopLostCallback(focus_callback_t cb, void* user_data = NULL ) { mTopLostCallback = cb; mFocusCallbackUserData = user_data; } + typedef boost::signals2::signal<void(LLFocusableElement*)> focus_signal_t; + + boost::signals2::connection setFocusLostCallback( const focus_signal_t::slot_type& cb) { return mFocusLostCallback.connect(cb);} + boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb) { return mFocusReceivedCallback.connect(cb);} + boost::signals2::connection setFocusChangedCallback(const focus_signal_t::slot_type& cb) { return mFocusChangedCallback.connect(cb);} + void setTopLostCallback(const focus_signal_t::slot_type& cb) { mTopLostCallback.connect(cb);} // These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus. virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); @@ -68,11 +69,10 @@ protected: virtual void onFocusReceived(); virtual void onFocusLost(); virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere - focus_callback_t mFocusLostCallback; - focus_callback_t mFocusReceivedCallback; - focus_callback_t mFocusChangedCallback; - focus_callback_t mTopLostCallback; - void* mFocusCallbackUserData; + focus_signal_t mFocusLostCallback; + focus_signal_t mFocusReceivedCallback; + focus_signal_t mFocusChangedCallback; + focus_signal_t mTopLostCallback; }; diff --git a/indra/llui/llhelp.h b/indra/llui/llhelp.h new file mode 100644 index 0000000000..c06d29a4bd --- /dev/null +++ b/indra/llui/llhelp.h @@ -0,0 +1,45 @@ +/** + * @file llhelp.h + * @brief Abstract interface to the Help system + * @author Tofu Linden + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, 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_LLHELP_H +#define LL_LLHELP_H + +class LLHelp +{ + public: + virtual void showTopic(const std::string &topic) = 0; + // return default (fallback) topic name suitable for showTopic() + virtual std::string defaultTopic() = 0; +}; + +#endif // headerguard diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index 01a3b5fdc7..0fbb7ced54 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -140,7 +140,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p) params.prevalidate_callback(&LLLineEditor::prevalidateFloat); params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM); mEditor = LLUICtrlFactory::create<LLLineEditor> (params); - mEditor->setFocusReceivedCallback( &LLMultiSliderCtrl::onEditorGainFocus ); + mEditor->setFocusReceivedCallback( boost::bind(LLMultiSliderCtrl::onEditorGainFocus, _1, this) ); // don't do this, as selecting the entire text is single clicking in some cases // and double clicking in others //mEditor->setSelectAllonFocusReceived(TRUE); diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 2b4aad5e83..a68b9cae57 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1446,8 +1446,8 @@ void LLNotifications::cancel(LLNotificationPtr pNotif) {
llerrs << "Attempted to delete nonexistent notification " << pNotif->getName() << llendl;
}
- updateItem(LLSD().insert("sigtype", "delete").insert("id", pNotif->id()), pNotif);
pNotif->cancel();
+ updateItem(LLSD().insert("sigtype", "delete").insert("id", pNotif->id()), pNotif);
}
void LLNotifications::update(const LLNotificationPtr pNotif)
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 26136e0a23..b9bbb4db22 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -80,6 +80,7 @@ LLPanel::Params::Params() strings("string"), filename("filename"), class_name("class"), + help_topic("help_topic"), visible_callback("visible_callback") { name = "panel"; @@ -98,6 +99,7 @@ LLPanel::LLPanel(const LLPanel::Params& p) mDefaultBtn(NULL), mBorder(NULL), mLabel(p.label), + mHelpTopic(p.help_topic), mCommitCallbackRegistrar(false), mEnableCallbackRegistrar(false), mXMLFilename(p.filename) @@ -416,6 +418,7 @@ void LLPanel::initFromParams(const LLPanel::Params& p) } setLabel(p.label()); + setHelpTopic(p.help_topic); setShape(p.rect); parseFollowsFlags(p); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index 81b5b68f05..8b23ea7030 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -83,6 +83,7 @@ public: Optional<std::string> filename; Optional<std::string> class_name; + Optional<std::string> help_topic; Multiple<LocalizedString> strings; @@ -139,10 +140,11 @@ public: void updateDefaultBtn(); void setLabel(const LLStringExplicit& label) { mLabel = label; } std::string getLabel() const { return mLabel; } + void setHelpTopic(const std::string& help_topic) { mHelpTopic = help_topic; } + std::string getHelpTopic() const { return mHelpTopic; } void setCtrlsEnabled(BOOL b); - LLHandle<LLPanel> getHandle() const { return mPanelHandle; } const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; } @@ -243,6 +245,8 @@ protected: EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar; commit_signal_t mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD() + + std::string mHelpTopic; // the name of this panel's help topic to display in the Help Viewer private: LLUIColor mBgColorAlpha; @@ -259,7 +263,7 @@ private: // for setting the xml filename when building panel in context dependent cases std::string mXMLFilename; - + }; // end class LLPanel #endif diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 172c4a9c65..ed150ac50c 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -66,7 +66,9 @@ LLScrollbar::Params::Params() up_button("up_button"), down_button("down_button"), left_button("left_button"), - right_button("right_button") + right_button("right_button"), + bg_visible("bg_visible", false), + bg_color("bg_color", LLColor4::black) { tab_stop = false; } @@ -92,7 +94,9 @@ LLScrollbar::LLScrollbar(const Params & p) mThumbImageH(p.thumb_image_horizontal), mTrackImageV(p.track_image_vertical), mTrackImageH(p.track_image_horizontal), - mThickness(p.thickness.isProvided() ? p.thickness : LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize")) + mThickness(p.thickness.isProvided() ? p.thickness : LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize")), + mBGVisible(p.bg_visible), + mBGColor(p.bg_color) { updateThumbRect(); @@ -482,6 +486,11 @@ void LLScrollbar::draw() { if (!getRect().isValid()) return; + if(mBGVisible) + { + gl_rect_2d(getLocalRect(), mBGColor.get(), TRUE); + } + S32 local_mouse_x; S32 local_mouse_y; LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y); diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index 30d906e04c..7e88b16561 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -66,8 +66,11 @@ public: track_image_horizontal, track_image_vertical; + Optional<bool> bg_visible; + Optional<LLUIColor> track_color, - thumb_color; + thumb_color, + bg_color; Optional<LLButton::Params> up_button; Optional<LLButton::Params> down_button; @@ -151,6 +154,9 @@ private: LLUIColor mTrackColor; LLUIColor mThumbColor; + LLUIColor mBGColor; + + bool mBGVisible; LLUIImagePtr mThumbImageV; LLUIImagePtr mThumbImageH; diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 30a042cff1..cd5926fb6b 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -67,12 +67,10 @@ static LLDefaultChildRegistry::Register<LLScrollContainer> r("scroll_container") #include "llscrollingpanellist.h" #include "llcontainerview.h" #include "llpanel.h" -#include "lllistctrl.h" static ScrollContainerRegistry::Register<LLScrollingPanelList> r1("scrolling_panel_list"); static ScrollContainerRegistry::Register<LLContainerView> r2("container_view"); static ScrollContainerRegistry::Register<LLPanel> r3("panel", &LLPanel::fromXML); -static ScrollContainerRegistry::Register<LLListCtrl> r4("list"); LLScrollContainer::Params::Params() : is_opaque("opaque"), diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 483106e857..54e42bf642 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -139,7 +139,9 @@ LLScrollListCtrl::Params::Params() bg_stripe_color("bg_stripe_color"), hovered_color("hovered_color"), highlighted_color("highlighted_color"), - contents("") + contents(""), + scroll_bar_bg_visible("scroll_bar_bg_visible"), + scroll_bar_bg_color("scroll_bar_bg_color") { name = "scroll_list"; mouse_opaque = true; @@ -220,6 +222,8 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) sbparams.change_callback(boost::bind(&LLScrollListCtrl::onScrollChange, this, _1, _2)); sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); sbparams.visible(false); + sbparams.bg_visible(p.scroll_bar_bg_visible); + sbparams.bg_color(p.scroll_bar_bg_color); mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams); addChild(mScrollbar); diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 49a49499ef..83b2f71037 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -83,7 +83,8 @@ public: Optional<bool> has_border, draw_heading, draw_stripes, - background_visible; + background_visible, + scroll_bar_bg_visible; // layout Optional<S32> column_padding, @@ -104,7 +105,8 @@ public: bg_readonly_color, bg_stripe_color, hovered_color, - highlighted_color; + highlighted_color, + scroll_bar_bg_color; Optional<Contents> contents; diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index 675a29a8b4..553b28ab87 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -143,7 +143,7 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p) line_p.prevalidate_callback(&LLLineEditor::prevalidateFloat); mEditor = LLUICtrlFactory::create<LLLineEditor>(line_p); - mEditor->setFocusReceivedCallback( &LLSliderCtrl::onEditorGainFocus, this ); + mEditor->setFocusReceivedCallback( boost::bind(&LLSliderCtrl::onEditorGainFocus, _1, this )); // don't do this, as selecting the entire text is single clicking in some cases // and double clicking in others //mEditor->setSelectAllonFocusReceived(TRUE); diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 3a96bc8f93..83d71006aa 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -142,7 +142,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) params.prevalidate_callback(&LLLineEditor::prevalidateFloat); params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM); mEditor = LLUICtrlFactory::create<LLLineEditor> (params); - mEditor->setFocusReceivedCallback( &LLSpinCtrl::onEditorGainFocus, this ); + mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onEditorGainFocus, _1, this )); //RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus // than when it doesn't. Instead, if you always have to double click to select all the text, // it's easier to understand diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index 291d1dc517..0517325e70 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -109,6 +109,7 @@ public: void setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ){ mClickedCallback = boost::bind(cb, userdata); } // mouse down and up within button const LLFontGL* getFont() const { return mDefaultFont; } + void setFont(const LLFontGL* font) { mDefaultFont = font; } void reshapeToFitText(); diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 8d5f277b59..39f09b297f 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -2001,6 +2001,8 @@ void LLTextEditor::cut() deleteSelection( FALSE ); needsReflow(); + + onKeyStroke(); } BOOL LLTextEditor::canCopy() const @@ -2105,6 +2107,8 @@ void LLTextEditor::pasteHelper(bool is_primary) deselect(); needsReflow(); + + onKeyStroke(); } @@ -2492,6 +2496,8 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask ) if(text_may_have_changed) { needsReflow(); + + onKeyStroke(); } needsScroll(); } @@ -2534,6 +2540,8 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char) deselect(); needsReflow(); + + onKeyStroke(); } return handled; @@ -2588,6 +2596,8 @@ void LLTextEditor::doDelete() setCursorPos(mCursorPos + 1); removeChar(); } + + onKeyStroke(); } needsReflow(); @@ -2634,6 +2644,8 @@ void LLTextEditor::undo() setCursorPos(pos); needsReflow(); + + onKeyStroke(); } BOOL LLTextEditor::canRedo() const @@ -2676,6 +2688,8 @@ void LLTextEditor::redo() setCursorPos(pos); needsReflow(); + + onKeyStroke(); } void LLTextEditor::onFocusReceived() @@ -4402,6 +4416,8 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string, // Update of the preedit should be caused by some key strokes. mKeystrokeTimer.reset(); + + onKeyStroke(); } BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const @@ -4648,3 +4664,30 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor) ed->addDocumentChild(mView); } } + +BOOL LLTextEditor::isDirty() const +{ + if(mReadOnly) + { + return FALSE; + } + + if( mPristineCmd ) + { + return ( mPristineCmd == mLastCmd ); + } + else + { + return ( NULL != mLastCmd ); + } +} + +void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& callback) +{ + mKeystrokeSignal.connect(callback); +} + +void LLTextEditor::onKeyStroke() +{ + mKeystrokeSignal(this); +} diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 68b8f2c3b1..a04261c4be 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -139,6 +139,10 @@ public: virtual ~LLTextEditor(); + typedef boost::signals2::signal<void (LLTextEditor* caller)> keystroke_signal_t; + + void setKeystrokeCallback(const keystroke_signal_t::slot_type& callback); + void setParseHighlights(BOOL parsing) {mParseHighlights=parsing;} // mousehandler overrides @@ -169,7 +173,7 @@ public: virtual void clear(); virtual void setFocus( BOOL b ); virtual BOOL acceptsTextInput() const; - virtual BOOL isDirty() const { return isPristine(); } + virtual BOOL isDirty() const; virtual void setValue(const LLSD& value); // LLEditMenuHandler interface @@ -503,6 +507,8 @@ private: S32 getFirstVisibleLine() const; + void onKeyStroke(); + // // Data // @@ -568,6 +574,8 @@ private: BOOL mHandleEditKeysDirectly; LLCoordGL mLastIMEPosition; // Last position of the IME editor + + keystroke_signal_t mKeystrokeSignal; }; // end class LLTextEditor diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 000e85f78c..d5b67f53b7 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -79,10 +79,10 @@ std::list<std::string> gUntranslated; /*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL; /*static*/ LLVector2 LLUI::sGLScaleFactor(1.f, 1.f); /*static*/ LLWindow* LLUI::sWindow = NULL; -/*static*/ LLHtmlHelp* LLUI::sHtmlHelp = NULL; /*static*/ LLView* LLUI::sRootView = NULL; -/*static*/ BOOL LLUI::sDirty = FALSE; -/*static*/ LLRect LLUI::sDirtyRect; +/*static*/ BOOL LLUI::sDirty = FALSE; +/*static*/ LLRect LLUI::sDirtyRect; +/*static*/ LLHelp* LLUI::sHelpImpl = NULL; /*static*/ std::vector<std::string> LLUI::sXUIPaths; /*static*/ LLFrameTimer LLUI::sMouseIdleTimer; @@ -695,44 +695,6 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre } -void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) -{ - if (NULL == image) - { - llwarns << "image == NULL; aborting function" << llendl; - return; - } - - LLGLSUIDefault gls_ui; - - gGL.pushMatrix(); - { - gGL.translatef((F32)x, (F32)y, 0.f); - - gGL.getTexUnit(0)->bind(image); - - gGL.color4fv(color.mV); - - gGL.begin(LLRender::QUADS); - { - gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); - gGL.vertex2i(width, height ); - - gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); - gGL.vertex2i(0, height ); - - gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); - gGL.vertex2i(0, 0); - - gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); - gGL.vertex2i(width, 0); - } - gGL.end(); - } - gGL.popMatrix(); -} - - void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase ) { phase = fmod(phase, 1.f); @@ -1592,6 +1554,9 @@ void LLUI::initClass(const settings_map_t& settings, // Button initialization callback for toggle buttons LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2)); + // Display the help topic for the current context + LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2)); + // Currently unused, but kept for reference: LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2)); @@ -1850,12 +1815,6 @@ LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name) return NULL; } -// static -void LLUI::setHtmlHelp(LLHtmlHelp* html_help) -{ - LLUI::sHtmlHelp = html_help; -} - LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname) { for (settings_map_t::iterator itor = sSettingGroups.begin(); diff --git a/indra/llui/llui.h b/indra/llui/llui.h index fddf8192ad..86cb516500 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -57,13 +57,13 @@ #include "llfontgl.h" class LLColor4; -class LLHtmlHelp; class LLVector3; class LLVector2; class LLUIImage; class LLUUID; class LLWindow; class LLView; +class LLHelp; // UI colors extern const LLColor4 UI_VERTEX_COLOR; @@ -104,8 +104,6 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LL void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -// Flip vertical, used for LLFloaterHTML -void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom); void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); @@ -203,7 +201,6 @@ public: static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y); static void screenRectToGL(const LLRect& screen, LLRect *gl); static void glRectToScreen(const LLRect& gl, LLRect *screen); - static void setHtmlHelp(LLHtmlHelp* html_help); // Returns the control group containing the control name, or the default group static LLControlGroup& getControlControlGroup (const std::string& controlname); static F32 getMouseIdleTime() { return sMouseIdleTimer.getElapsedTimeF32(); } @@ -223,8 +220,8 @@ public: static LLUIAudioCallback sAudioCallback; static LLVector2 sGLScaleFactor; static LLWindow* sWindow; - static LLHtmlHelp* sHtmlHelp; static LLView* sRootView; + static LLHelp* sHelpImpl; private: static LLImageProviderInterface* sImageProvider; static std::vector<std::string> sXUIPaths; diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 8807e26f6b..fe99d9c267 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -114,7 +114,6 @@ void LLUICtrl::initFromParams(const Params& p) } setTabStop(p.tab_stop); - setFocusLostCallback(p.focus_lost_callback()); if (p.initial_value.isProvided() && !p.control_name.isProvided()) @@ -763,6 +762,27 @@ LLUICtrl* LLUICtrl::getParentUICtrl() const return NULL; } +bool LLUICtrl::findHelpTopic(std::string& help_topic_out) +{ + LLUICtrl* ctrl = this; + + // search back through the control's parents for a panel + // with a help_topic string defined + while (ctrl) + { + LLPanel *panel = dynamic_cast<LLPanel *>(ctrl); + if (panel && !panel->getHelpTopic().empty()) + { + help_topic_out = panel->getHelpTopic(); + return true; // success + } + + ctrl = ctrl->getParentUICtrl(); + } + + return false; // no help topic found +} + // *TODO: Deprecate; for backwards compatability only: boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data) { @@ -800,14 +820,7 @@ namespace LLInitParam return false; } - template<> - bool ParamCompare<LLUICtrl::focus_callback_t>::equals( - const LLUICtrl::focus_callback_t &a, - const LLUICtrl::focus_callback_t &b) - { - return false; - } - + template<> bool ParamCompare<LLUICtrl::enable_callback_t>::equals( const LLUICtrl::enable_callback_t &a, diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 3add9393ea..c2502732f3 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -124,8 +124,6 @@ public: Optional<CommitCallbackParam> mouseenter_callback; Optional<CommitCallbackParam> mouseleave_callback; - Optional<focus_callback_t> focus_lost_callback; - Optional<std::string> control_name; Optional<EnableControls> enabled_controls; Optional<ControlVisibility> controls_visibility; @@ -225,6 +223,10 @@ public: LLUICtrl* getParentUICtrl() const; + // return true if help topic found by crawling through parents - + // topic then put in help_topic_out + bool findHelpTopic(std::string& help_topic_out); + boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ) { return mCommitSignal.connect(cb); } boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ) { return mValidateSignal.connect(cb); } @@ -309,11 +311,6 @@ namespace LLInitParam const LLUICtrl::enable_callback_t &a, const LLUICtrl::enable_callback_t &b); - template<> - bool ParamCompare<LLUICtrl::focus_callback_t>::equals( - const LLUICtrl::focus_callback_t &a, - const LLUICtrl::focus_callback_t &b); - template<> bool ParamCompare<LLLazyValue<LLColor4> >::equals( const LLLazyValue<LLColor4> &a, const LLLazyValue<LLColor4> &b); diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index 3b689b93c0..f3401f91f7 100644 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -134,4 +134,3 @@ void LLUrlAction::copyLabelToClipboard(std::string url) LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(match.getLabel())); } } - diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 256c776293..10cb3fb377 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -466,16 +466,6 @@ LLRect LLView::getRequiredRect() return mRect; } -//virtual -void LLView::onFocusLost() -{ -} - -//virtual -void LLView::onFocusReceived() -{ -} - BOOL LLView::focusNextRoot() { LLView::child_list_t result = LLView::getFocusRootsQuery().run(this); diff --git a/indra/llui/llview.h b/indra/llui/llview.h index bf3b5d0614..7a37d6f430 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -405,10 +405,6 @@ public: BOOL getSaveToXML() const { return mSaveToXML; } void setSaveToXML(BOOL b) { mSaveToXML = b; } - // inherited from LLFocusableElement - /* virtual */ void onFocusLost(); - /* virtual */ void onFocusReceived(); - typedef enum e_hit_test_type { HIT_TEST_USE_BOUNDING_RECT, |