diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llui/llbutton.cpp | 14 | ||||
-rw-r--r-- | indra/llui/llbutton.h | 1 | ||||
-rw-r--r-- | indra/llui/lltabcontainer.cpp | 31 | ||||
-rw-r--r-- | indra/llui/lltabcontainer.h | 1 | ||||
-rw-r--r-- | indra/newview/llchiclet.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llimfloater.cpp | 7 | ||||
-rw-r--r-- | indra/newview/llimfloater.h | 2 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.cpp | 84 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.h | 21 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 12 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.h | 1 | ||||
-rw-r--r-- | indra/newview/lllocationinputctrl.cpp | 52 | ||||
-rw-r--r-- | indra/newview/lllocationinputctrl.h | 23 | ||||
-rw-r--r-- | indra/newview/llparticipantlist.cpp | 11 | ||||
-rw-r--r-- | indra/newview/lltransientdockablefloater.cpp | 2 | ||||
-rw-r--r-- | indra/newview/lltransientdockablefloater.h | 4 | ||||
-rw-r--r-- | indra/newview/lltransientfloatermgr.cpp | 69 | ||||
-rw-r--r-- | indra/newview/lltransientfloatermgr.h | 37 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_im_container.xml | 3 |
19 files changed, 306 insertions, 71 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index e9f6288f44..9ce8ce8d55 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -1022,6 +1022,20 @@ void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign a } } +void LLButton::setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment, const LLColor4& color) +{ + if (image_id.isNull()) + { + mImageOverlay = NULL; + } + else + { + mImageOverlay = LLUI::getUIImageByID(image_id); + mImageOverlayAlignment = alignment; + mImageOverlayColor = color; + } +} + void LLButton::onMouseCaptureLost() { resetMouseDownTimer(); diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 5e28b8cdff..cd149e3113 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -200,6 +200,7 @@ public: void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; } void setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white); + void setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white); LLPointer<LLUIImage> getImageOverlay() { return mImageOverlay; } void autoResize(); // resize with label of current btn state diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 327dd01612..43c44f2253 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -1507,6 +1507,37 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const L } } +void LLTabContainer::setTabImage(LLPanel* child, const LLUUID& image_id, const LLColor4& color) +{ + static LLUICachedControl<S32> tab_padding ("UITabPadding", 0); + LLTabTuple* tuple = getTabByPanel(child); + if( tuple ) + { + tuple->mButton->setImageOverlay(image_id, LLFontGL::RIGHT, color); + + if (!mIsVertical) + { + // remove current width from total tab strip width + mTotalTabWidth -= tuple->mButton->getRect().getWidth(); + + S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? + tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : + 0; + + tuple->mPadding = image_overlay_width; + + tuple->mButton->setRightHPad(6); + tuple->mButton->reshape(llclamp(mFont->getWidth(tuple->mButton->getLabelSelected()) + tab_padding + tuple->mPadding, mMinTabWidth, mMaxTabWidth), + tuple->mButton->getRect().getHeight()); + // add back in button width to total tab strip width + mTotalTabWidth += tuple->mButton->getRect().getWidth(); + + // tabs have changed size, might need to scroll to see current tab + updateMaxScrollPos(); + } + } +} + void LLTabContainer::setTitle(const std::string& title) { if (mTitleBox) diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 5d0f194bf9..33c49e0d6f 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -172,6 +172,7 @@ public: BOOL getTabPanelFlashing(LLPanel* child); void setTabPanelFlashing(LLPanel* child, BOOL state); void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white); + void setTabImage(LLPanel* child, const LLUUID& img_id, const LLColor4& color = LLColor4::white); void setTitle( const std::string& title ); const std::string getPanelTitle(S32 index); diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 8da207f887..f1de4e2982 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 e06e0c94ec..73597e7de3 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 d9db385d06..0ca0325451 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -116,6 +116,8 @@ public: 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/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index 6cc985aef4..06a7b4a29c 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -35,19 +35,22 @@ #include "llimfloatercontainer.h" #include "llfloaterreg.h" +#include "llimview.h" +#include "llavatariconctrl.h" +#include "llagent.h" // // LLIMFloaterContainer // LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed) -: LLMultiFloater(seed), - mActiveVoiceFloater(NULL) +: LLMultiFloater(seed) { mAutoResize = FALSE; } LLIMFloaterContainer::~LLIMFloaterContainer() { + LLGroupMgr::getInstance()->removeObserver(this); } BOOL LLIMFloaterContainer::postBuild() @@ -87,13 +90,84 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp, LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point); - // make sure active voice icon shows up for new tab - if (floaterp == mActiveVoiceFloater) + LLUUID session_id = floaterp->getKey(); + + if(gAgent.isInGroup(session_id)) + { + mSessions[session_id] = floaterp; + mID = session_id; + mGroupID.push_back(session_id); + LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(session_id); + LLGroupMgr* gm = LLGroupMgr::getInstance(); + gm->addObserver(this); + + if (group_data && group_data->mInsigniaID.notNull()) + { + mTabContainer->setTabImage(get_ptr_in_map(mSessions, session_id), group_data->mInsigniaID); + } + else + { + gm->sendGroupPropertiesRequest(session_id); + } + } + else + { + LLUUID avatar_id = LLIMModel::getInstance()->getOtherParticipantID(session_id); + LLAvatarPropertiesProcessor& app = LLAvatarPropertiesProcessor::instance(); + app.addObserver(avatar_id, this); + floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, avatar_id)); + mSessions[avatar_id] = floaterp; + + LLUUID* icon_id_ptr = LLAvatarIconIDCache::getInstance()->get(avatar_id); + if(!icon_id_ptr) + { + app.sendAvatarPropertiesRequest(avatar_id); + } + else + { + mTabContainer->setTabImage(floaterp, *icon_id_ptr); + } + } +} + +void LLIMFloaterContainer::processProperties(void* data, enum EAvatarProcessorType type) +{ + if (APT_PROPERTIES == type) + { + LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data); + if (avatar_data) + { + LLUUID avatar_id = avatar_data->avatar_id; + if(avatar_data->image_id != *LLAvatarIconIDCache::getInstance()->get(avatar_id)) + { + LLAvatarIconIDCache::getInstance()->add(avatar_id,avatar_data->image_id); + } + mTabContainer->setTabImage(get_ptr_in_map(mSessions, avatar_id), avatar_data->image_id); + } + } +} + +void LLIMFloaterContainer::changed(LLGroupChange gc) +{ + if (GC_PROPERTIES == gc) { - mTabContainer->setTabImage(floaterp, "active_voice_tab.tga"); + for(groupIDs_t::iterator it = mGroupID.begin(); it!=mGroupID.end(); it++) + { + LLUUID group_id = *it; + LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(group_id); + if (group_data && group_data->mInsigniaID.notNull()) + { + mTabContainer->setTabImage(get_ptr_in_map(mSessions, group_id), group_data->mInsigniaID); + } + } } } +void LLIMFloaterContainer::onCloseFloater(LLUUID id) +{ + LLAvatarPropertiesProcessor::instance().removeObserver(id, this); +} + LLIMFloaterContainer* LLIMFloaterContainer::findInstance() { return LLFloaterReg::findTypedInstance<LLIMFloaterContainer>("im_container"); diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h index d4a542dfc2..1333b098bc 100644 --- a/indra/newview/llimfloatercontainer.h +++ b/indra/newview/llimfloatercontainer.h @@ -33,12 +33,17 @@ #ifndef LL_LLIMFLOATERCONTAINER_H #define LL_LLIMFLOATERCONTAINER_H +#include <map> +#include <vector> + #include "llfloater.h" #include "llmultifloater.h" +#include "llavatarpropertiesprocessor.h" +#include "llgroupmgr.h" class LLTabContainer; -class LLIMFloaterContainer : public LLMultiFloater +class LLIMFloaterContainer : public LLMultiFloater, public LLAvatarPropertiesObserver, public LLGroupMgrObserver { public: LLIMFloaterContainer(const LLSD& seed); @@ -51,15 +56,23 @@ public: BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); + void processProperties(void* data, EAvatarProcessorType type); + void changed(LLGroupChange gc); + static LLFloater* getCurrentVoiceFloater(); static LLIMFloaterContainer* findInstance(); static LLIMFloaterContainer* getInstance(); -protected: - - LLFloater* mActiveVoiceFloater; +private: + typedef std::map<LLUUID,LLPanel*> avatarID_panel_map_t; + avatarID_panel_map_t mSessions; + + typedef std::vector<LLUUID> groupIDs_t; + groupIDs_t mGroupID; + + void onCloseFloater(LLUUID avatar_id); }; #endif // LL_LLIMFLOATERCONTAINER_H diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 099f863dc9..2f4f285065 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3687,18 +3687,6 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, return rv; } -BOOL LLCallingCardBridge::removeItem() -{ - if (LLFriendCardsManager::instance().isItemInAnyFriendsList(getItem())) - { - LLAvatarActions::removeFriendDialog(getItem()->getCreatorUUID()); - return FALSE; - } - else - { - return LLItemBridge::removeItem(); - } -} // +=================================================+ // | LLNotecardBridge | // +=================================================+ diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index fced0047e8..759d0cba18 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -448,7 +448,6 @@ public: EDragAndDropType cargo_type, void* cargo_data); void refreshFolderViewItem(); - BOOL removeItem(); protected: LLCallingCardBridge( LLInventoryPanel* inventory, const LLUUID& uuid ); diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 404e266806..7f49a7defb 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -43,8 +43,11 @@ #include "lltrans.h" #include "lluictrlfactory.h" #include "lltooltip.h" +#include "llnotificationsutil.h" +#include "llregionflags.h" // newview includes +#include "llagent.h" #include "llinventoryobserver.h" #include "lllandmarkactions.h" #include "lllandmarklist.h" @@ -56,6 +59,7 @@ #include "lltrans.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" +#include "llviewerregion.h" #include "llviewercontrol.h" #include "llviewermenu.h" #include "llurllineeditorctrl.h" @@ -256,36 +260,42 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) voice_icon.tool_tip = LLTrans::getString("LocationCtrlVoiceTooltip"); voice_icon.mouse_opaque = true; mParcelIcon[VOICE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(voice_icon); + mParcelIcon[VOICE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, VOICE_ICON)); addChild(mParcelIcon[VOICE_ICON]); LLIconCtrl::Params fly_icon = p.fly_icon; fly_icon.tool_tip = LLTrans::getString("LocationCtrlFlyTooltip"); fly_icon.mouse_opaque = true; mParcelIcon[FLY_ICON] = LLUICtrlFactory::create<LLIconCtrl>(fly_icon); + mParcelIcon[FLY_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, FLY_ICON)); addChild(mParcelIcon[FLY_ICON]); LLIconCtrl::Params push_icon = p.push_icon; push_icon.tool_tip = LLTrans::getString("LocationCtrlPushTooltip"); push_icon.mouse_opaque = true; mParcelIcon[PUSH_ICON] = LLUICtrlFactory::create<LLIconCtrl>(push_icon); + mParcelIcon[PUSH_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PUSH_ICON)); addChild(mParcelIcon[PUSH_ICON]); LLIconCtrl::Params build_icon = p.build_icon; build_icon.tool_tip = LLTrans::getString("LocationCtrlBuildTooltip"); build_icon.mouse_opaque = true; mParcelIcon[BUILD_ICON] = LLUICtrlFactory::create<LLIconCtrl>(build_icon); + mParcelIcon[BUILD_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, BUILD_ICON)); addChild(mParcelIcon[BUILD_ICON]); LLIconCtrl::Params scripts_icon = p.scripts_icon; scripts_icon.tool_tip = LLTrans::getString("LocationCtrlScriptsTooltip"); scripts_icon.mouse_opaque = true; mParcelIcon[SCRIPTS_ICON] = LLUICtrlFactory::create<LLIconCtrl>(scripts_icon); + mParcelIcon[SCRIPTS_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, SCRIPTS_ICON)); addChild(mParcelIcon[SCRIPTS_ICON]); LLIconCtrl::Params damage_icon = p.damage_icon; damage_icon.tool_tip = LLTrans::getString("LocationCtrlDamageTooltip"); damage_icon.mouse_opaque = true; mParcelIcon[DAMAGE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(damage_icon); + mParcelIcon[DAMAGE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, DAMAGE_ICON)); addChild(mParcelIcon[DAMAGE_ICON]); LLTextBox::Params damage_text = p.damage_text; @@ -918,3 +928,45 @@ bool LLLocationInputCtrl::onLocationContextMenuItemEnabled(const LLSD& userdata) return false; } + +void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon) +{ + switch (icon) + { + case VOICE_ICON: + LLNotificationsUtil::add("NoVoice"); + break; + case FLY_ICON: + LLNotificationsUtil::add("NoFly"); + break; + case PUSH_ICON: + LLNotificationsUtil::add("PushRestricted"); + break; + case BUILD_ICON: + LLNotificationsUtil::add("NoBuild"); + break; + case SCRIPTS_ICON: + { + LLViewerRegion* region = gAgent.getRegion(); + if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) + { + LLNotificationsUtil::add("ScriptsStopped"); + } + else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) + { + LLNotificationsUtil::add("ScriptsNotRunning"); + } + else + { + LLNotificationsUtil::add("NoOutsideScripts"); + } + break; + } + case DAMAGE_ICON: + LLNotificationsUtil::add("NotSafe"); + break; + case ICON_COUNT: + break; + // no default to get compiler warning when a new icon gets added + } +} diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index 7959fab2de..607ccd4da6 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -102,6 +102,18 @@ public: void handleLoginComplete(); private: + + enum EParcelIcon + { + VOICE_ICON = 0, + FLY_ICON, + PUSH_ICON, + BUILD_ICON, + SCRIPTS_ICON, + DAMAGE_ICON, + ICON_COUNT + }; + friend class LLUICtrlFactory; LLLocationInputCtrl(const Params&); virtual ~LLLocationInputCtrl(); @@ -138,6 +150,7 @@ private: // callbacks bool onLocationContextMenuItemEnabled(const LLSD& userdata); void onLocationContextMenuItemClicked(const LLSD& userdata); + void onParcelIconClick(EParcelIcon icon); LLMenuGL* mLocationContextMenu; LLButton* mAddLandmarkBtn; @@ -146,16 +159,6 @@ private: S32 mIconHPad; // pad between all icons S32 mAddLandmarkHPad; // pad to left of landmark star - enum EParcelIcon - { - VOICE_ICON = 0, - FLY_ICON, - PUSH_ICON, - BUILD_ICON, - SCRIPTS_ICON, - DAMAGE_ICON, - ICON_COUNT - }; LLIconCtrl* mParcelIcon[ICON_COUNT]; LLTextBox* mDamageText; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index b049f914ad..88b706fb6b 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -125,6 +125,8 @@ LLParticipantList::~LLParticipantList() delete mParticipantListMenu; mParticipantListMenu = NULL; } + + mAvatarList->setContextMenu(NULL); } void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible) @@ -431,6 +433,10 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu() LLContextMenu* main_menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( "menu_participant_list.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + // Don't show sort options for P2P chat + bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1); + main_menu->setItemVisible("SortByName", is_sort_visible); + main_menu->setItemVisible("SortByRecentSpeakers", is_sort_visible); main_menu->setItemVisible("Moderator Options", isGroupModerator()); main_menu->arrangeAndClear(); @@ -456,11 +462,6 @@ void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteSelected", false); LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteOthers", false); } - - // Don't show sort options for P2P chat - bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1); - LLMenuGL::sMenuContainer->childSetVisible("SortByName", is_sort_visible); - LLMenuGL::sMenuContainer->childSetVisible("SortByRecentSpeakers", is_sort_visible); } void LLParticipantList::LLParticipantListMenu::sortParticipantList(const LLSD& userdata) diff --git a/indra/newview/lltransientdockablefloater.cpp b/indra/newview/lltransientdockablefloater.cpp index 7e4d4988d1..b830498cb0 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 6e8a3afd22..e0541d6597 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 @@ public: /*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 347399f239..f474f47eb7 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 cef6e1fe45..95eba666a0 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 diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml index 1d51d19a4a..bd25288a9e 100644 --- a/indra/newview/skins/default/xui/en/floater_im_container.xml +++ b/indra/newview/skins/default/xui/en/floater_im_container.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <multi_floater - can_minimize="false" + can_close="false" + can_minimize="true" can_resize="true" height="390" layout="topleft" |