From 74429f2ed926362a2ec47d590fc862b55b26f0f8 Mon Sep 17 00:00:00 2001 From: Alexei Arabadji <aarabadji@productengine.com> Date: Fri, 22 Jan 2010 13:42:52 +0200 Subject: [PATCH] =?UTF-8?q?fixed=20EXT-3670=20=E2=80=9CClicking=20on=20IM?= =?UTF-8?q?=20session=20in=20IM=20session=20well=20closes=20IM=20floater?= =?UTF-8?q?=E2=80=9D,=20implemented=20exclude=20sets=20for=20groups=20of?= =?UTF-8?q?=20transient=20floaters,=20now=20transient=20floaters=20not=20c?= =?UTF-8?q?loses=20if=20user=20click=20on=20view=20from=20global=20exclude?= =?UTF-8?q?=20set=20or=20from=20floater=20group=20set;=20made=20IM=20float?= =?UTF-8?q?er=20goes=20foreground=20if=20it=20visible=20but=20not=20focuse?= =?UTF-8?q?d=20instead=20hide=20floater;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --HG-- branch : product-engine --- indra/newview/llchiclet.cpp | 2 + indra/newview/llimfloater.cpp | 7 +- indra/newview/llimfloater.h | 2 + indra/newview/lltransientdockablefloater.cpp | 2 +- indra/newview/lltransientdockablefloater.h | 4 +- indra/newview/lltransientfloatermgr.cpp | 69 +++++++++++++------- indra/newview/lltransientfloatermgr.h | 37 +++++++++-- 7 files changed, 90 insertions(+), 33 deletions(-) diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 8da207f887f..f1de4e29824 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -1272,6 +1272,7 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index) chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index)); arrange(); + LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, chiclet); return true; } @@ -1299,6 +1300,7 @@ void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it) mChicletList.erase(it); arrange(); + LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, chiclet); chiclet->die(); } diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index e06e0c94ec9..73597e7de33 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -110,6 +110,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) } } setOverlapsScreenChannel(true); + + LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this); } void LLIMFloater::onFocusLost() @@ -228,6 +230,7 @@ void LLIMFloater::sendMsg() LLIMFloater::~LLIMFloater() { + LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this); } //virtual @@ -513,14 +516,14 @@ bool LLIMFloater::toggle(const LLUUID& session_id) if(!isChatMultiTab()) { LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); - if (floater && floater->getVisible()) + if (floater && floater->getVisible() && floater->hasFocus()) { // clicking on chiclet to close floater just hides it to maintain existing // scroll/text entry state floater->setVisible(false); return false; } - else if(floater && !floater->isDocked()) + else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus())) { floater->setVisible(TRUE); floater->setFocus(TRUE); diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index d9db385d06a..0ca0325451b 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -116,6 +116,8 @@ class LLIMFloater : public LLTransientDockableFloater static void onIMChicletCreated(const LLUUID& session_id); + virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; } + private: // process focus events to set a currently active session /* virtual */ void onFocusLost(); diff --git a/indra/newview/lltransientdockablefloater.cpp b/indra/newview/lltransientdockablefloater.cpp index 7e4d4988d12..b830498cb0b 100644 --- a/indra/newview/lltransientdockablefloater.cpp +++ b/indra/newview/lltransientdockablefloater.cpp @@ -39,7 +39,7 @@ LLTransientDockableFloater::LLTransientDockableFloater(LLDockControl* dockControl, bool uniqueDocking, const LLSD& key, const Params& params) : - LLDockableFloater(dockControl, uniqueDocking, key, params) + LLDockableFloater(dockControl, uniqueDocking, key, params), LLTransientFloater(this) { LLTransientFloaterMgr::getInstance()->registerTransientFloater(this); } diff --git a/indra/newview/lltransientdockablefloater.h b/indra/newview/lltransientdockablefloater.h index 6e8a3afd221..e0541d65979 100644 --- a/indra/newview/lltransientdockablefloater.h +++ b/indra/newview/lltransientdockablefloater.h @@ -37,12 +37,13 @@ #include "llfloater.h" #include "lldockcontrol.h" #include "lldockablefloater.h" +#include "lltransientfloatermgr.h" /** * Represents floater that can dock and managed by transient floater manager. * Transient floaters should be hidden if user click anywhere except defined view list. */ -class LLTransientDockableFloater : public LLDockableFloater +class LLTransientDockableFloater : public LLDockableFloater, LLTransientFloater { public: LOG_CLASS(LLTransientDockableFloater); @@ -52,6 +53,7 @@ class LLTransientDockableFloater : public LLDockableFloater /*virtual*/ void setVisible(BOOL visible); /* virtual */void setDocked(bool docked, bool pop_on_undock = true); + virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; } }; #endif /* LL_TRANSIENTDOCKABLEFLOATER_H */ diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp index 347399f2391..f474f47eb79 100644 --- a/indra/newview/lltransientfloatermgr.cpp +++ b/indra/newview/lltransientfloatermgr.cpp @@ -44,57 +44,68 @@ LLTransientFloaterMgr::LLTransientFloaterMgr() { gViewerWindow->getRootView()->addMouseDownCallback(boost::bind( &LLTransientFloaterMgr::leftMouseClickCallback, this, _1, _2, _3)); + + mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(GLOBAL, std::set<LLView*>())); + mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(IM, std::set<LLView*>())); } -void LLTransientFloaterMgr::registerTransientFloater(LLFloater* floater) +void LLTransientFloaterMgr::registerTransientFloater(LLTransientFloater* floater) { mTransSet.insert(floater); } -void LLTransientFloaterMgr::unregisterTransientFloater(LLFloater* floater) +void LLTransientFloaterMgr::unregisterTransientFloater(LLTransientFloater* floater) { mTransSet.erase(floater); } +void LLTransientFloaterMgr::addControlView(ETransientGroup group, LLView* view) +{ + mGroupControls.find(group)->second.insert(view); +} + +void LLTransientFloaterMgr::removeControlView(ETransientGroup group, LLView* view) +{ + mGroupControls.find(group)->second.erase(view); +} + void LLTransientFloaterMgr::addControlView(LLView* view) { - mControlsSet.insert(view); + addControlView(GLOBAL, view); } void LLTransientFloaterMgr::removeControlView(LLView* view) { // we will still get focus lost callbacks on this view, but that's ok // since we run sanity checking logic every time - mControlsSet.erase(view); + removeControlView(GLOBAL, view); } -void LLTransientFloaterMgr::hideTransientFloaters() +void LLTransientFloaterMgr::hideTransientFloaters(S32 x, S32 y) { - for (std::set<LLFloater*>::iterator it = mTransSet.begin(); it + for (std::set<LLTransientFloater*>::iterator it = mTransSet.begin(); it != mTransSet.end(); it++) { - LLFloater* floater = *it; - if (floater->isDocked()) + LLTransientFloater* floater = *it; + if (floater->isTransientDocked()) { - floater->setVisible(FALSE); + ETransientGroup group = floater->getGroup(); + + bool hide = isControlClicked(mGroupControls.find(group)->second, x, y); + if (hide) + { + floater->setTransientVisible(FALSE); + } } } } -void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y, - MASK mask) +bool LLTransientFloaterMgr::isControlClicked(std::set<LLView*>& set, S32 x, S32 y) { - bool hide = true; - for (controls_set_t::iterator it = mControlsSet.begin(); it - != mControlsSet.end(); it++) + bool res = true; + for (controls_set_t::iterator it = set.begin(); it + != set.end(); it++) { - // don't hide transient floater if any context menu opened - if (LLMenuGL::sMenuContainer->getVisibleMenu() != NULL) - { - hide = false; - break; - } - LLView* control_view = *it; if (!control_view->getVisible()) { @@ -105,14 +116,26 @@ void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y, // if click inside view rect if (rect.pointInRect(x, y)) { - hide = false; + res = false; break; } } + return res; +} + +void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y, + MASK mask) +{ + // don't hide transient floater if any context menu opened + if (LLMenuGL::sMenuContainer->getVisibleMenu() != NULL) + { + return; + } + bool hide = isControlClicked(mGroupControls.find(GLOBAL)->second, x, y); if (hide) { - hideTransientFloaters(); + hideTransientFloaters(x, y); } } diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h index cef6e1fe456..95eba666a03 100644 --- a/indra/newview/lltransientfloatermgr.h +++ b/indra/newview/lltransientfloatermgr.h @@ -37,6 +37,7 @@ #include "llsingleton.h" #include "llfloater.h" +class LLTransientFloater; /** * Provides functionality to hide transient floaters. @@ -44,20 +45,44 @@ class LLTransientFloaterMgr: public LLSingleton<LLTransientFloaterMgr> { public: + enum ETransientGroup + { + GLOBAL, IM + }; + LLTransientFloaterMgr(); - void registerTransientFloater(LLFloater* floater); - void unregisterTransientFloater(LLFloater* floater); + void registerTransientFloater(LLTransientFloater* floater); + void unregisterTransientFloater(LLTransientFloater* floater); + void addControlView(ETransientGroup group, LLView* view); + void removeControlView(ETransientGroup group, LLView* view); void addControlView(LLView* view); void removeControlView(LLView* view); private: - void hideTransientFloaters(); + void hideTransientFloaters(S32 x, S32 y); void leftMouseClickCallback(S32 x, S32 y, MASK mask); - + bool isControlClicked(std::set<LLView*>& set, S32 x, S32 y); private: - std::set<LLFloater*> mTransSet; + std::set<LLTransientFloater*> mTransSet; + typedef std::set<LLView*> controls_set_t; - controls_set_t mControlsSet; + typedef std::map<ETransientGroup, std::set<LLView*> > group_controls_t; + group_controls_t mGroupControls; +}; + +/** + * An abstract class declares transient floater interfaces. + */ +class LLTransientFloater +{ +public: + LLTransientFloater(LLFloater* floater) : mFloater(floater) {} + virtual LLTransientFloaterMgr::ETransientGroup getGroup() = 0; + bool isTransientDocked() { return mFloater->isDocked(); }; + void setTransientVisible(BOOL visible) {mFloater->setVisible(visible); } + +private: + LLFloater* mFloater; }; #endif // LL_LLTRANSIENTFLOATERMGR_H -- GitLab