From d0d9d4a9b0bd61e9be98e1e20719b79a9fa58970 Mon Sep 17 00:00:00 2001 From: Denis Serdjuk Date: Fri, 23 Oct 2009 23:28:04 +0300 Subject: fixed normal bug EXT-1630 Edit Landmark: Current landmark place should be selected by default in the \"Place Landmark In\" picklist --HG-- branch : product-engine --- indra/newview/llpanelplaceinfo.cpp | 15 +++++++-------- indra/newview/llpanelplaceinfo.h | 3 +++ indra/newview/llpanelplaces.cpp | 11 ++++++++++- 3 files changed, 20 insertions(+), 9 deletions(-) (limited to 'indra') diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index cb9f7184f0..2edb2bba06 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -76,7 +76,6 @@ typedef std::pair folder_pair_t; static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right); -static std::string getFullFolderName(const LLViewerInventoryCategory* cat); static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats); static LLRegisterPanelClassWrapper t_place_info("panel_place_info"); @@ -1028,14 +1027,9 @@ void LLPanelPlaceInfo::onForSaleBannerClick() } - -static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right) -{ - return left.second < right.second; -} - -static std::string getFullFolderName(const LLViewerInventoryCategory* cat) +/*static*/ +std::string LLPanelPlaceInfo::getFullFolderName(const LLViewerInventoryCategory* cat) { std::string name = cat->getName(); LLUUID parent_id; @@ -1057,6 +1051,11 @@ static std::string getFullFolderName(const LLViewerInventoryCategory* cat) return name; } +static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right) +{ + return left.second < right.second; +} + static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats) { LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 7b3a8f050b..aa2485cbb4 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -52,6 +52,7 @@ class LLTextBox; class LLTextEditor; class LLTextureCtrl; class LLViewerRegion; +class LLViewerInventoryCategory; class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver { @@ -131,6 +132,8 @@ public: /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); /*virtual*/ void handleVisibilityChange (BOOL new_visibility); + + static std::string getFullFolderName(const LLViewerInventoryCategory* cat); private: diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 5ab823b6e5..b2e9110e96 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -351,7 +351,16 @@ void LLPanelPlaces::setItem(LLInventoryItem* item) if (is_landmark_editable) { - mPlaceInfo->setLandmarkFolder(mItem->getParentUUID()); + if(!mPlaceInfo->setLandmarkFolder(mItem->getParentUUID()) && !mItem->getParentUUID().isNull()) + { + const LLViewerInventoryCategory* cat = gInventory.getCategory(mItem->getParentUUID()); + if(cat) + { + std::string cat_fullname = LLPanelPlaceInfo::getFullFolderName(cat); + LLComboBox* folderList = mPlaceInfo->getChild("folder_combo"); + folderList->add(cat_fullname, cat->getUUID(),ADD_TOP); + } + } } mPlaceInfo->displayItemInfo(mItem); -- cgit v1.2.3 From 7a7bc8d33bba19530bf71c210d996a3faf711cd1 Mon Sep 17 00:00:00 2001 From: Leyla Farazha Date: Fri, 23 Oct 2009 14:10:42 -0700 Subject: EXT-1742 Navbar should have a dropshadow that covers the sidepanel EXT-1563 I18N: Alt-arrow instructions in tab tooltips wont honor their translation reviewed by james --- indra/llui/lltabcontainer.cpp | 5 +++-- indra/newview/llnavigationbar.cpp | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 3ca05ff0ff..10d89dc78d 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -44,6 +44,7 @@ #include "lluictrlfactory.h" #include "llrender.h" #include "llfloater.h" +#include "lltrans.h" //---------------------------------------------------------------------------- @@ -940,8 +941,8 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel) else { std::string tooltip = trimmed_label; - tooltip += "\nAlt-Left arrow for previous tab"; - tooltip += "\nAlt-Right arrow for next tab"; + tooltip += "\n" + LLTrans::getString("TooltipAltLeft"); + tooltip += "\n" + LLTrans::getString("TooltipAltRight"); LLButton::Params p; p.name(std::string(child->getName()) + " tab"); diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index b77415dfee..992e244ed9 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -272,6 +272,15 @@ void LLNavigationBar::draw() onTeleportHistoryChanged(); mPurgeTPHistoryItems = false; } + + if (isBackgroundVisible()) + { + static LLUICachedControl drop_shadow_floater ("DropShadowFloater", 0); + static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow"); + gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, + color_drop_shadow, drop_shadow_floater ); + } + LLPanel::draw(); } -- cgit v1.2.3 From b544e125a4015550faf274904ac6d049e5fe5760 Mon Sep 17 00:00:00 2001 From: Igor Borovkov Date: Mon, 26 Oct 2009 08:16:20 +0200 Subject: IM minor refactoring: removed unused LLIMMgr::isIMSessionOpen(...) - duplicate of LLIMMgr::hasSession(...) --HG-- branch : product-engine --- indra/newview/llimview.cpp | 9 --------- indra/newview/llimview.h | 5 ----- 2 files changed, 14 deletions(-) (limited to 'indra') diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index b631c991ae..8d72ffdfcc 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1458,15 +1458,6 @@ BOOL LLIMMgr::getIMReceived() const return mIMReceived; } -// This method returns TRUE if the local viewer has a session -// currently open keyed to the uuid. -BOOL LLIMMgr::isIMSessionOpen(const LLUUID& uuid) -{ - LLFloaterIMPanel* floater = findFloaterBySession(uuid); - if(floater) return TRUE; - return FALSE; -} - LLUUID LLIMMgr::addP2PSession(const std::string& name, const LLUUID& other_participant_id, const std::string& voice_session_handle, diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 68beb29034..79513fb7d5 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -200,11 +200,6 @@ public: void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args); - // This method returns TRUE if the local viewer has a session - // currently open keyed to the uuid. The uuid can be keyed by - // either session id or agent id. - BOOL isIMSessionOpen(const LLUUID& uuid); - // This adds a session to the talk view. The name is the local // name of the session, dialog specifies the type of // session. Since sessions can be keyed off of first recipient or -- cgit v1.2.3 From 88f2d107c0a757b9cc6dee7c30a9482c02a05c08 Mon Sep 17 00:00:00 2001 From: "Yuri Chebotarev ychebotarev@productengine.com" Date: Mon, 26 Oct 2009 11:14:13 +0200 Subject: no ticket set single_instance for nearby_chat floater --HG-- branch : product-engine --- indra/newview/skins/default/xui/en/floater_nearby_chat.xml | 1 + 1 file changed, 1 insertion(+) (limited to 'indra') diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml index 25d337ccec..d24d1b7064 100644 --- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml @@ -14,6 +14,7 @@ save_rect="true" title="Nearby Chat" save_visibility="true" + single_instance="true" width="320"> Date: Mon, 26 Oct 2009 13:05:08 +0200 Subject: IM: removed unused & empty methods and classes, added TODO marks --HG-- branch : product-engine --- indra/newview/llagent.cpp | 6 ------ indra/newview/llimview.cpp | 38 -------------------------------------- indra/newview/llimview.h | 13 ++++--------- indra/newview/llviewermenu.cpp | 1 - 4 files changed, 4 insertions(+), 54 deletions(-) (limited to 'indra') diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index f62606cc50..5800db482f 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -5391,12 +5391,6 @@ void update_group_floaters(const LLUUID& group_id) //*TODO Implement group update for Profile View // still actual as of July 31, 2009 (DZ) - if (gIMMgr) - { - // update the talk view - gIMMgr->refresh(); - } - gAgent.fireEvent(new LLOldEvents::LLEvent(&gAgent, "new group"), ""); } diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 8d72ffdfcc..fa7e1170be 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1114,29 +1114,6 @@ void LLIncomingCallDialog::processCallResponse(S32 response) } } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLIMViewFriendObserver -// -// Bridge to suport knowing when the inventory has changed. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLIMViewFriendObserver : public LLFriendObserver -{ -public: - LLIMViewFriendObserver(LLIMMgr* tv) : mTV(tv) {} - virtual ~LLIMViewFriendObserver() {} - virtual void changed(U32 mask) - { - if(mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE)) - { - mTV->refresh(); - } - } -protected: - LLIMMgr* mTV; -}; - - bool inviteUserResponse(const LLSD& notification, const LLSD& response) { const LLSD& payload = notification["payload"]; @@ -1237,7 +1214,6 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response) // LLIMMgr::LLIMMgr() : - mFriendObserver(NULL), mIMReceived(FALSE) { static bool registered_dialog = false; @@ -1246,21 +1222,11 @@ LLIMMgr::LLIMMgr() : LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); registered_dialog = true; } - - mFriendObserver = new LLIMViewFriendObserver(this); - LLAvatarTracker::instance().addObserver(mFriendObserver); mPendingInvitations = LLSD::emptyMap(); mPendingAgentListUpdates = LLSD::emptyMap(); } -LLIMMgr::~LLIMMgr() -{ - LLAvatarTracker::instance().removeObserver(mFriendObserver); - delete mFriendObserver; - // Children all cleaned up by default view destructor. -} - // Add a message to a session. void LLIMMgr::addMessage( const LLUUID& session_id, @@ -1714,10 +1680,6 @@ void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const std::stri } } -void LLIMMgr::refresh() -{ -} - void LLIMMgr::disconnectAllSessions() { LLFloaterIMPanel* floater = NULL; diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 79513fb7d5..6991017e8f 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -183,7 +183,7 @@ public: }; LLIMMgr(); - virtual ~LLIMMgr(); + virtual ~LLIMMgr() {}; // Add a message to a session. The session can keyed to sesion id // or agent id. @@ -245,9 +245,6 @@ public: void processIMTypingStart(const LLIMInfo* im_info); void processIMTypingStop(const LLIMInfo* im_info); - // Rebuild stuff - void refresh(); - void notifyNewIM(); void clearNewIMNotification(); @@ -263,10 +260,6 @@ public: // good connection. void disconnectAllSessions(); - // This is a helper function to determine what kind of im session - // should be used for the given agent. - static EInstantMessage defaultIMTypeForAgent(const LLUUID& agent_id); - BOOL hasSession(const LLUUID& session_id); // This method returns the im panel corresponding to the uuid @@ -285,6 +278,7 @@ public: void clearPendingAgentListUpdates(const LLUUID& session_id); //HACK: need a better way of enumerating existing session, or listening to session create/destroy events + //@deprecated, is used only by LLToolBox, which is not used anywhere, right? (IB) const std::set >& getIMFloaterHandles() { return mFloaters; } void addSessionObserver(LLIMSessionObserver *); @@ -335,8 +329,9 @@ private: void notifyObserverSessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id); private: + + //*TODO should be deleted when Communicate Floater is being deleted std::set > mFloaters; - LLFriendObserver* mFriendObserver; typedef std::list session_observers_list_t; session_observers_list_t mSessionObservers; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index a1c15d9d0f..d46f155ad6 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3511,7 +3511,6 @@ void set_god_level(U8 god_level) { U8 old_god_level = gAgent.getGodLevel(); gAgent.setGodLevel( god_level ); - gIMMgr->refresh(); LLViewerParcelMgr::getInstance()->notifyObservers(); // God mode changes sim visibility -- cgit v1.2.3 From d81b8884109cbeacf211282b0a08aa3aea425294 Mon Sep 17 00:00:00 2001 From: Igor Borovkov Date: Mon, 26 Oct 2009 16:41:47 +0200 Subject: IM: fixed remove session logic, got rid of "being session removed" field --HG-- branch : product-engine --- indra/newview/llimview.cpp | 35 ++++++++--------------------------- indra/newview/llimview.h | 12 +++++------- 2 files changed, 13 insertions(+), 34 deletions(-) (limited to 'indra') diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index fa7e1170be..593f3a1e82 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1405,10 +1405,7 @@ S32 LLIMMgr::getNumberOfUnreadIM() S32 num = 0; for(it = LLIMModel::sSessionsMap.begin(); it != LLIMModel::sSessionsMap.end(); ++it) { - if((*it).first != mBeingRemovedSessionID) - { - num += (*it).second->mNumUnread; - } + num += (*it).second->mNumUnread; } return num; @@ -1517,41 +1514,25 @@ bool LLIMMgr::leaveSession(const LLUUID& session_id) return true; } -// This removes the panel referenced by the uuid, and then restores -// internal consistency. The internal pointer is not deleted? Did you mean -// a pointer to the corresponding LLIMSession? Session data is cleared now. -// Put a copy of UUID to avoid problem when passed reference becames invalid -// if it has been come from the object removed in observer. -void LLIMMgr::removeSession(LLUUID session_id) +// Removes data associated with a particular session specified by session_id +void LLIMMgr::removeSession(const LLUUID& session_id) { - if (mBeingRemovedSessionID == session_id) - { - return; - } + llassert_always(hasSession(session_id)); + //*TODO remove this floater thing when Communicate Floater is being deleted (IB) LLFloaterIMPanel* floater = findFloaterBySession(session_id); if(floater) { mFloaters.erase(floater->getHandle()); LLFloaterChatterBox::getInstance()->removeFloater(floater); - //mTabContainer->removeTabPanel(floater); - - clearPendingInvitation(session_id); - clearPendingAgentListUpdates(session_id); } - // for some purposes storing ID of a sessios that is being removed - mBeingRemovedSessionID = session_id; - notifyObserverSessionRemoved(session_id); + clearPendingInvitation(session_id); + clearPendingAgentListUpdates(session_id); - //if we don't clear session data on removing the session - //we can't use LLBottomTray as observer of session creation/delettion and - //creating chiclets only on session created even, we need to handle chiclets creation - //the same way as LLFloaterIMPanels were managed. LLIMModel::getInstance()->clearSession(session_id); - // now this session is completely removed - mBeingRemovedSessionID.setNull(); + notifyObserverSessionRemoved(session_id); } void LLIMMgr::inviteToSession( diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 6991017e8f..5ba54d30c3 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -297,10 +297,11 @@ public: bool endCall(const LLUUID& session_id); private: - // This removes the panel referenced by the uuid, and then - // restores internal consistency. The internal pointer is not - // deleted. - void removeSession(LLUUID session_id); + + /** + * Remove data associated with a particular session specified by session_id + */ + void removeSession(const LLUUID& session_id); // create a panel and update internal representation for // consistency. Returns the pointer, caller (the class instance @@ -341,9 +342,6 @@ private: LLSD mPendingInvitations; LLSD mPendingAgentListUpdates; - // ID of a session that is being removed: observers are already told - // that this session is being removed, but it is still present in the sessions' map - LLUUID mBeingRemovedSessionID; }; class LLIncomingCallDialog : public LLModalDialog -- cgit v1.2.3 From f22f829b8642d59cb5953eb33f5297a1da90fadd Mon Sep 17 00:00:00 2001 From: Eugene Mutavchi Date: Mon, 26 Oct 2009 17:14:32 +0200 Subject: Fixed normal bugs EXT-1628 ([BSI] - New IM system isn't sending typing notifications anymore) and EXT-1629 ([BSI] - add hint in IM window when Resident is typing) --HG-- branch : product-engine --- indra/newview/llimfloater.cpp | 135 +++++++++++++++++++++++-- indra/newview/llimfloater.h | 18 +++- indra/newview/llimview.cpp | 6 ++ indra/newview/skins/default/xui/en/strings.xml | 10 +- 4 files changed, 157 insertions(+), 12 deletions(-) (limited to 'indra') diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index a20b5ea66c..97af96847c 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -61,7 +61,14 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) mLastMessageIndex(-1), mDialog(IM_NOTHING_SPECIAL), mChatHistory(NULL), - mInputEditor(NULL), + mInputEditor(NULL), + mSavedTitle(), + mTypingStart(), + mShouldSendTypingState(false), + mMeTyping(false), + mOtherTyping(false), + mTypingTimer(), + mTypingTimeoutTimer(), mPositioned(false), mSessionInitialized(false) { @@ -95,6 +102,7 @@ void LLIMFloater::onFocusReceived() // virtual void LLIMFloater::onClose(bool app_quitting) { + setTyping(false); gIMMgr->leaveSession(mSessionID); } @@ -141,6 +149,7 @@ void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata ) { LLIMFloater* self = (LLIMFloater*) userdata; self->sendMsg(); + self->setTyping(false); } void LLIMFloater::sendMsg() @@ -228,12 +237,27 @@ BOOL LLIMFloater::postBuild() LLLogChat::loadHistory(getTitle(), &chatFromLogFile, (void *)this); } + mTypingStart = LLTrans::getString("IM_typing_start_string"); + //*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla" //see LLFloaterIMPanel for how it is done (IB) return LLDockableFloater::postBuild(); } +// virtual +void LLIMFloater::draw() +{ + if ( mMeTyping ) + { + // Time out if user hasn't typed for a while. + if ( mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS ) + { + setTyping(false); + } + } + LLFloater::draw(); +} // static @@ -450,7 +474,7 @@ void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) { LLIMFloater* self = (LLIMFloater*) userdata; - self->setTyping(FALSE); + self->setTyping(false); } // static @@ -460,19 +484,118 @@ void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata) std::string text = self->mInputEditor->getText(); if (!text.empty()) { - self->setTyping(TRUE); + self->setTyping(true); } else { // Deleting all text counts as stopping typing. - self->setTyping(FALSE); + self->setTyping(false); + } +} + +void LLIMFloater::setTyping(bool typing) +{ + if ( typing ) + { + // Started or proceeded typing, reset the typing timeout timer + mTypingTimeoutTimer.reset(); + } + + if ( mMeTyping != typing ) + { + // Typing state is changed + mMeTyping = typing; + // So, should send current state + mShouldSendTypingState = true; + // In case typing is started, send state after some delay + mTypingTimer.reset(); + } + + // Don't want to send typing indicators to multiple people, potentially too + // much network traffic. Only send in person-to-person IMs. + if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL ) + { + if ( mMeTyping ) + { + if ( mTypingTimer.getElapsedTimeF32() > 1.f ) + { + // Still typing, send 'start typing' notification + LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, TRUE); + mShouldSendTypingState = false; + } + } + else + { + // Send 'stop typing' notification immediately + LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, FALSE); + mShouldSendTypingState = false; + } + } + + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE); + +} + +void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing) +{ + if ( typing ) + { + // other user started typing + addTypingIndicator(im_info); + } + else + { + // other user stopped typing + removeTypingIndicator(im_info); } } +void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info) +{ + // We may have lost a "stop-typing" packet, don't add it twice + if ( im_info && !mOtherTyping ) + { + mOtherTyping = true; -//just a stub for now -void LLIMFloater::setTyping(BOOL typing) + // Create typing is started title string + LLUIString typing_start(mTypingStart); + typing_start.setArg("[NAME]", im_info->mName); + + // Save and set new title + mSavedTitle = getTitle(); + setTitle (typing_start); + + // Update speaker + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if ( speaker_mgr ) + { + speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE); + } + } +} + +void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info) { + if ( mOtherTyping ) + { + mOtherTyping = false; + + // Revert the title to saved one + setTitle(mSavedTitle); + + if ( im_info ) + { + // Update speaker + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if ( speaker_mgr ) + { + speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE); + } + } + + } } void LLIMFloater::chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata) diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index 99810b6d6d..3559e14c89 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -55,6 +55,8 @@ public: // LLView overrides /*virtual*/ BOOL postBuild(); /*virtual*/ void setVisible(BOOL visible); + // Check typing timeout timer. + /*virtual*/ void draw(); // LLFloater overrides /*virtual*/ void onClose(bool app_quitting); @@ -85,6 +87,7 @@ public: void setPositioned(bool b) { mPositioned = b; }; void onVisibilityChange(const LLSD& new_visibility); + void processIMTyping(const LLIMInfo* im_info, BOOL typing); private: // process focus events to set a currently active session @@ -94,7 +97,7 @@ private: static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ); static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata); static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata); - void setTyping(BOOL typing); + void setTyping(bool typing); void onSlide(); static void* createPanelIMControl(void* userdata); static void* createPanelGroupControl(void* userdata); @@ -103,6 +106,11 @@ private: static void chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata); + // Add the "User is typing..." indicator. + void addTypingIndicator(const LLIMInfo* im_info); + + // Remove the "User is typing..." indicator. + void removeTypingIndicator(const LLIMInfo* im_info = NULL); LLPanelChatControlPanel* mControlPanel; LLUUID mSessionID; @@ -114,6 +122,14 @@ private: LLLineEditor* mInputEditor; bool mPositioned; + std::string mSavedTitle; + LLUIString mTypingStart; + bool mMeTyping; + bool mOtherTyping; + bool mShouldSendTypingState; + LLFrameTimer mTypingTimer; + LLFrameTimer mTypingTimeoutTimer; + bool mSessionInitialized; LLSD mQueuedMsgsForInit; }; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index fa7e1170be..f8d794e967 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1991,6 +1991,12 @@ void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing) { floater->processIMTyping(im_info, typing); } + + LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + if ( im_floater ) + { + im_floater->processIMTyping(im_info, typing); + } } class LLViewerChatterBoxSessionStartReply : public LLHTTPNode diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 4c19b22ac5..7efda2b882 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -264,10 +264,6 @@ Track your camera Control your camera - - -- Instant message logging enabled -- - (Unnamed) - PG Mature @@ -2884,7 +2880,11 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. Failed to start viewer - + + -- Instant message logging enabled -- + [NAME] is typing... + (Unnamed) + Joining Voice Chat... -- cgit v1.2.3 From e931d2d6f1a7d981bebf07b1d089fa4751096830 Mon Sep 17 00:00:00 2001 From: Igor Borovkov Date: Mon, 26 Oct 2009 17:33:28 +0200 Subject: IM refac.: replaced passing copies by passing references, moved some IMModel private, added documentation --HG-- branch : product-engine --- indra/newview/llimfloater.cpp | 3 ++- indra/newview/llimview.cpp | 27 ++++++++------------- indra/newview/llimview.h | 48 ++++++++++++++++++++++++++++++------- indra/newview/llviewerinventory.cpp | 1 - indra/newview/llviewerwindow.cpp | 1 - 5 files changed, 51 insertions(+), 29 deletions(-) (limited to 'indra') diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index a20b5ea66c..57e3fba3f5 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -402,7 +402,8 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id) void LLIMFloater::updateMessages() { - std::list messages = LLIMModel::instance().getMessages(mSessionID, mLastMessageIndex+1); + std::list messages; + LLIMModel::instance().getMessages(mSessionID, messages, mLastMessageIndex+1); std::string agent_name; gCacheName->getFullName(gAgentID, agent_name); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 593f3a1e82..439f0b3d1e 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -272,7 +272,8 @@ void LLIMModel::testMessages() } -bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id, const std::vector& ids) +bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, + const LLUUID& other_participant_id, const std::vector& ids) { if (is_in_map(sSessionsMap, session_id)) { @@ -289,7 +290,7 @@ bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage } -bool LLIMModel::clearSession(LLUUID session_id) +bool LLIMModel::clearSession(const LLUUID& session_id) { if (sSessionsMap.find(session_id) == sSessionsMap.end()) return false; delete (sSessionsMap[session_id]); @@ -297,16 +298,13 @@ bool LLIMModel::clearSession(LLUUID session_id) return true; } -//*TODO remake it, instead of returing the list pass it as as parameter (IB) -std::list LLIMModel::getMessages(LLUUID session_id, int start_index) +void LLIMModel::getMessages(const LLUUID& session_id, std::list& messages, int start_index) { - std::list return_list; - LLIMSession* session = findIMSession(session_id); if (!session) { llwarns << "session " << session_id << "does not exist " << llendl; - return return_list; + return; } int i = session->mMsgs.size() - start_index; @@ -317,7 +315,7 @@ std::list LLIMModel::getMessages(LLUUID session_id, int start_index) { LLSD msg; msg = *iter; - return_list.push_back(*iter); + messages.push_back(*iter); i--; } @@ -327,14 +325,9 @@ std::list LLIMModel::getMessages(LLUUID session_id, int start_index) arg["session_id"] = session_id; arg["num_unread"] = 0; mNoUnreadMsgsSignal(arg); - - // TODO: in the future is there a more efficient way to return these - //of course there is - return as parameter (IB) - return return_list; - } -bool LLIMModel::addToHistory(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text) { +bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) { LLIMSession* session = findIMSession(session_id); @@ -383,8 +376,8 @@ bool LLIMModel::logToFile(const LLUUID& session_id, const std::string& from, con return false; } -//*TODO add const qualifier and pass by references (IB) -bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text, bool log2file /* = true */) { +bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, + const std::string& utf8_text, bool log2file /* = true */) { LLIMSession* session = findIMSession(session_id); if (!session) @@ -506,7 +499,7 @@ void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, gAgent.sendReliableMessage(); } -void LLIMModel::sendLeaveSession(LLUUID session_id, LLUUID other_participant_id) +void LLIMModel::sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id) { if(session_id.notNull()) { diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 5ba54d30c3..e3d0a50557 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -104,18 +104,35 @@ public: boost::signals2::connection addNewMsgCallback( session_callback_t cb ) { return mNewMsgSignal.connect(cb); } boost::signals2::connection addNoUnreadMsgsCallback( session_callback_t cb ) { return mNoUnreadMsgsSignal.connect(cb); } - bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id, + /** + * Create new session object in a model + */ + bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const std::vector& ids = std::vector()); - bool clearSession(LLUUID session_id); - std::list getMessages(LLUUID session_id, int start_index = 0); - bool addMessage(LLUUID session_id, std::string from, LLUUID other_participant_id, std::string utf8_text, bool log2file = true); - bool addToHistory(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text); + /** + * Remove all session data associated with a session specified by session_id + */ + bool clearSession(const LLUUID& session_id); - bool logToFile(const LLUUID& session_id, const std::string& from, const std::string& utf8_text); + /** + * Populate supplied std::list with messages starting from index specified by start_index + */ + void getMessages(const LLUUID& session_id, std::list& messages, int start_index = 0); - //used to get the name of the session, for use as the title - //currently just the other avatar name + /** + * Add a message to an IM Model - the message is saved in a message store associated with a session specified by session_id + * and also saved into a file if log2file is specified. + * It sends new message signal for each added message. + */ + bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true); + + /** + * Get a session's name. + * For a P2P chat - it's an avatar's name, + * For a group chat - it's a group's name + * For an ad-hoc chat - is received from the server and is in a from of " conference" + */ const std::string& getName(const LLUUID& session_id) const; /** @@ -150,7 +167,7 @@ public: */ LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const; - static void sendLeaveSession(LLUUID session_id, LLUUID other_participant_id); + static void sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id); static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id, const std::vector& ids, EInstantMessage dialog); static void sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing); @@ -158,6 +175,19 @@ public: const LLUUID& other_participant_id, EInstantMessage dialog); void testMessages(); + +private: + + /** + * Add message to a list of message associated with session specified by session_id + */ + bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); + + /** + * Save an IM message into a file + */ + //*TODO should also save uuid of a sender + bool logToFile(const LLUUID& session_id, const std::string& from, const std::string& utf8_text); }; class LLIMSessionObserver diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 57a4117d5d..366e5602bd 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -42,7 +42,6 @@ #include "llconsole.h" #include "llinventorymodel.h" #include "llnotify.h" -#include "llimview.h" #include "llgesturemgr.h" #include "llinventorybridge.h" diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index c659e58e47..f3c1cf191a 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -142,7 +142,6 @@ #include "llstatview.h" #include "llsurface.h" #include "llsurfacepatch.h" -#include "llimview.h" #include "lltexlayer.h" #include "lltextbox.h" #include "lltexturecache.h" -- cgit v1.2.3 From e874fbc8f052e3a7a16d4b4d61a35a4c49dab1cd Mon Sep 17 00:00:00 2001 From: Igor Borovkov Date: Mon, 26 Oct 2009 18:05:00 +0200 Subject: IM: got rid of old im floater dependency in LLIMMgr::addMessage(...) --HG-- branch : product-engine --- indra/newview/llimview.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 7414ebbbad..59cd9cec86 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1258,7 +1258,8 @@ void LLIMMgr::addMessage( fixed_session_name = session_name; } - if (!LLIMModel::getInstance()->findIMSession(new_session_id)) + bool new_session = !hasSession(session_id); + if (new_session) { LLIMModel::getInstance()->newSession(session_id, fixed_session_name, dialog, other_participant_id); } @@ -1277,15 +1278,16 @@ void LLIMMgr::addMessage( // create IM window as necessary if(!floater) { - - floater = createFloater( new_session_id, other_participant_id, fixed_session_name, dialog, FALSE); + } + if (new_session) + { // When we get a new IM, and if you are a god, display a bit // of information about the source. This is to help liaisons // when answering questions. @@ -1295,7 +1297,7 @@ void LLIMMgr::addMessage( std::ostringstream bonus_info; bonus_info << LLTrans::getString("***")+ " "+ LLTrans::getString("IMParentEstate") + ":" + " " << parent_estate_id - << ((parent_estate_id == 1) ? "," + LLTrans::getString("IMMainland") : "") + << ((parent_estate_id == 1) ? "," + LLTrans::getString("IMMainland") : "") << ((parent_estate_id == 5) ? "," + LLTrans::getString ("IMTeen") : ""); // once we have web-services (or something) which returns -- cgit v1.2.3 From fa13628e9d56d473ae1fd8f4aa53afaf6a229e7b Mon Sep 17 00:00:00 2001 From: Dmitry Oleshko Date: Mon, 26 Oct 2009 18:51:31 +0200 Subject: Fixed normal bug [BSI] The "X notifications arrived while you were away" toast on login is not clickable --HG-- branch : product-engine --- indra/newview/llchannelmanager.cpp | 4 +++- indra/newview/llscreenchannel.cpp | 1 + indra/newview/llsyswellwindow.cpp | 6 ++++++ indra/newview/llsyswellwindow.h | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index 77f941eef0..6427422572 100644 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -40,6 +40,8 @@ #include "llbottomtray.h" #include "llviewerwindow.h" #include "llrootview.h" +#include "llsyswellwindow.h" +#include "llfloaterreg.h" #include @@ -128,7 +130,7 @@ void LLChannelManager::onLoginCompleted() S32 channel_right_bound = gViewerWindow->getWorldViewRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound); - mStartUpChannel->setShowToasts(true); + mStartUpChannel->setMouseDownCallback(boost::bind(&LLSysWellWindow::onStartUpToastClick, LLFloaterReg::getTypedInstance("syswell_window"), _2, _3, _4)); mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this)); mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime")); diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 1683d113a9..383e540394 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -519,6 +519,7 @@ void LLScreenChannel::createStartUpToast(S32 notif_num, F32 timer) LLRect toast_rect; LLToast::Params p; p.lifetime_secs = timer; + p.enable_hide_btn = false; mStartUpToastPanel = new LLToast(p); if(!mStartUpToastPanel) diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 86290e6695..93a931dc78 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -112,6 +112,12 @@ void LLSysWellWindow::connectListUpdaterToSignal(std::string notification_type) } } +//--------------------------------------------------------------------------------- +void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask) +{ + onChicletClick(); +} + //--------------------------------------------------------------------------------- void LLSysWellWindow::onChicletClick() { diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index fa6a1abea4..cbc5f7358f 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -76,6 +76,7 @@ public: void onItemClose(LLSysWellItem* item); void onStoreToast(LLPanel* info_panel, LLUUID id); void onChicletClick(); + void onStartUpToastClick(S32 x, S32 y, MASK mask); // size constants for the window and for its elements static const S32 MAX_WINDOW_HEIGHT = 200; -- cgit v1.2.3 From b07f5e6c4d5c5ff9e3f58b98565e548d1e2563a5 Mon Sep 17 00:00:00 2001 From: Neal Orman Date: Mon, 26 Oct 2009 17:14:12 +0000 Subject: EXT-1816 Wearable changes do not persist issue was in the isDirty() function - one case where images in the wearable get added caused the function to return FALSE when it should have returned TRUE. Now wearables that you change the images of will be detected as dirty and will save properly. Code reviewed by Bigpapi. --- indra/newview/llwearable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 3bbf4c2c47..3fe02088c4 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -544,7 +544,7 @@ BOOL LLWearable::isDirty() const else { // image found in current image list but not saved image list - return FALSE; + return TRUE; } } } -- cgit v1.2.3 From ff37134a405e81899b4d9e7d07be7e3da85c8278 Mon Sep 17 00:00:00 2001 From: Andrew Dyukov Date: Mon, 26 Oct 2009 19:30:46 +0200 Subject: Implemented low task EXT-1156(Implement option to show/hide avatar icon in the friend list) --HG-- branch : product-engine --- indra/newview/app_settings/settings.xml | 33 ++++++++++++++++++++++ indra/newview/llavatarlist.cpp | 23 +++++++++++++++ indra/newview/llavatarlist.h | 6 ++++ indra/newview/llavatarlistitem.cpp | 22 +++++++++++++++ indra/newview/llavatarlistitem.h | 4 ++- indra/newview/llpanelpeople.cpp | 9 +++++- .../xui/en/menu_people_friends_view_sort.xml | 11 ++++++-- .../xui/en/menu_people_nearby_view_sort.xml | 11 ++++++-- .../xui/en/menu_people_recent_view_sort.xml | 11 ++++++-- 9 files changed, 119 insertions(+), 11 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index eb045349c2..b113a35ea1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7731,6 +7731,39 @@ Value 1 + FriendsListShowIcons + + Comment + Show/hide online and all friends icons in the friend list + Persist + 1 + Type + Boolean + Value + 1 + + NearbyListShowIcons + + Comment + Show/hide people icons in nearby list + Persist + 1 + Type + Boolean + Value + 1 + + RecentListShowIcons + + Comment + Show/hide people icons in recent list + Persist + 1 + Type + Boolean + Value + 1 + FriendsSortOrder Comment diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 3a07c6e5ef..1d07caee53 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -38,6 +38,7 @@ #include "llcallingcard.h" // for LLAvatarTracker #include "llcachename.h" #include "llvoiceclient.h" +#include "llviewercontrol.h" // for gSavedSettings static LLDefaultChildRegistry::Register r("avatar_list"); @@ -45,6 +46,21 @@ static LLDefaultChildRegistry::Register r("avatar_list"); // Used to limit time spent for avatar list update per frame. static const unsigned ADD_LIMIT = 50; +void LLAvatarList::toggleIcons() +{ + // Save the new value for new items to use. + mShowIcons = !mShowIcons; + gSavedSettings.setBOOL(mIconParamName, mShowIcons); + + // Show/hide icons for all existing items. + std::vector items; + getItems(items); + for( std::vector::const_iterator it = items.begin(); it != items.end(); it++) + { + static_cast(*it)->setAvatarIconVisible(mShowIcons); + } +} + static bool findInsensitive(std::string haystack, const std::string& needle_upper) { LLStringUtil::toUpper(haystack); @@ -73,6 +89,12 @@ LLAvatarList::LLAvatarList(const Params& p) setComparator(&NAME_COMPARATOR); } +void LLAvatarList::setShowIcons(std::string param_name) +{ + mIconParamName= param_name; + mShowIcons = gSavedSettings.getBOOL(mIconParamName); +} + // virtual void LLAvatarList::draw() { @@ -202,6 +224,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is item->setContextMenu(mContextMenu); item->childSetVisible("info_btn", false); + item->setAvatarIconVisible(mShowIcons); addItem(item, id, pos); } diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index a83a72b26c..f60f1f00f3 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -70,7 +70,11 @@ public: void setContextMenu(LLAvatarListItem::ContextMenu* menu) { mContextMenu = menu; } + void toggleIcons(); void sortByName(); + void setShowIcons(std::string param_name); + bool getIconsVisible() const { return mShowIcons; } + const std::string getIconParamName() const{return mIconParamName;} virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); protected: @@ -86,7 +90,9 @@ private: bool mIgnoreOnlineStatus; bool mDirty; + bool mShowIcons; + std::string mIconParamName; std::string mNameFilter; uuid_vector_t mIDs; diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index ebc79aae48..4ecb9537ba 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -42,6 +42,7 @@ #include "llavatariconctrl.h" #include "llbutton.h" +S32 LLAvatarListItem::sIconWidth = 0; LLAvatarListItem::LLAvatarListItem() : LLPanel(), @@ -55,6 +56,12 @@ LLAvatarListItem::LLAvatarListItem() mOnlineStatus(E_UNKNOWN) { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_list_item.xml"); + // Remember avatar icon width including its padding from the name text box, + // so that we can hide and show the icon again later. + if (!sIconWidth) + { + sIconWidth = mAvatarName->getRect().mLeft - mAvatarIcon->getRect().mLeft; + } } LLAvatarListItem::~LLAvatarListItem() @@ -188,6 +195,21 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, bool ignore_status_changes) gCacheName->get(id, FALSE, boost::bind(&LLAvatarListItem::onNameCache, this, _2, _3)); } +void LLAvatarListItem::setAvatarIconVisible(bool visible) +{ + // Already done? Then do nothing. + if (mAvatarIcon->getVisible() == (BOOL)visible) + return; + + // Show/hide avatar icon. + mAvatarIcon->setVisible(visible); + + // Move the avatar name horizontally by icon size + its distance from the avatar name. + LLRect name_rect = mAvatarName->getRect(); + name_rect.mLeft += visible ? sIconWidth : -sIconWidth; + mAvatarName->setRect(name_rect); +} + void LLAvatarListItem::onInfoBtnClick() { LLFloaterReg::showInstance("inspect_avatar", LLSD().insert("avatar_id", mAvatarId)); diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index b9cfed4b7b..a8d3919217 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -64,6 +64,7 @@ public: void setOnline(bool online); void setName(const std::string& name); void setAvatarId(const LLUUID& id, bool ignore_status_changes = false); + void setAvatarIconVisible(bool visible); const LLUUID& getAvatarId() const; const std::string getAvatarName() const; @@ -87,7 +88,7 @@ private: void onNameCache(const std::string& first_name, const std::string& last_name); - LLAvatarIconCtrl*mAvatarIcon; + LLAvatarIconCtrl* mAvatarIcon; LLTextBox* mAvatarName; LLTextBox* mStatus; @@ -98,6 +99,7 @@ private: LLUUID mAvatarId; EOnlineStatus mOnlineStatus; + static S32 sIconWidth; // icon width + padding }; #endif //LL_LLAVATARLISTITEM_H diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 61d66873ea..dc0df5f1f5 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -413,13 +413,17 @@ BOOL LLPanelPeople::postBuild() mOnlineFriendList = getChild(FRIENDS_TAB_NAME)->getChild("avatars_online"); mAllFriendList = getChild(FRIENDS_TAB_NAME)->getChild("avatars_all"); mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online")); + mOnlineFriendList->setShowIcons("FriendsListShowIcons"); mAllFriendList->setNoItemsCommentText(getString("no_friends")); + mAllFriendList->setShowIcons("FriendsListShowIcons"); mNearbyList = getChild(NEARBY_TAB_NAME)->getChild("avatar_list"); mNearbyList->setNoItemsCommentText(getString("no_one_near")); + mNearbyList->setShowIcons("NearbyListShowIcons"); mRecentList = getChild(RECENT_TAB_NAME)->getChild("avatar_list"); mRecentList->setNoItemsCommentText(getString("no_people")); + mRecentList->setShowIcons("RecentListShowIcons"); mGroupList = getChild("group_list"); mGroupList->setNoItemsCommentText(getString("no_groups")); @@ -963,6 +967,8 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata) } else if (chosen_item == "view_icons") { + mAllFriendList->toggleIcons(); + mOnlineFriendList->toggleIcons(); } else if (chosen_item == "organize_offline") { @@ -992,6 +998,7 @@ void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata) } else if (chosen_item == "view_icons") { + mNearbyList->toggleIcons(); } else if (chosen_item == "sort_distance") { @@ -1011,7 +1018,7 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata) } else if (chosen_item == "view_icons") { - // *TODO: implement showing/hiding icons + mRecentList->toggleIcons(); } } diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml index cc17e9dd4b..eedb4383bb 100644 --- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml @@ -23,9 +23,14 @@ parameter="sort_status" /> - - - + + + + diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml index f91a961388..c002cd078f 100644 --- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml @@ -12,9 +12,14 @@ - - - + + + + diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml index d09871cff3..cfd6dc78b6 100644 --- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml @@ -23,9 +23,14 @@ parameter="sort_name" /> - - - + + + + -- cgit v1.2.3 From c27d0874bc292738fc5efb8c90a6379a7829a646 Mon Sep 17 00:00:00 2001 From: Eric Tulla Date: Mon, 26 Oct 2009 18:41:26 +0000 Subject: Fix for DEV-39996 / EXT-942. Avatar hair and eyelashes had lost partial transparency. -Reviewed by nyx (simpler xml fix for hair suggested by him as well) --- indra/newview/character/avatar_lad.xml | 7 +++++++ indra/newview/lltexlayer.cpp | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index f3bfa37cea..c43ba27984 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -5588,6 +5588,13 @@ local_texture="hair_grain" /> + + + + diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 17547cae39..5d9046ac90 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -804,8 +804,9 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, gGL.setColorMask(false, true); gGL.setSceneBlendType(LLRender::BT_REPLACE); + // (Optionally) replace alpha with a single component image from a tga file. - if (!info->mStaticAlphaFileName.empty() && mMaskLayerList.empty()) + if (!info->mStaticAlphaFileName.empty()) { LLGLSNoAlphaTest gls_no_alpha_test; gGL.flush(); -- cgit v1.2.3 From bdddca899b3967a614000b814cf98796c7a371a8 Mon Sep 17 00:00:00 2001 From: Sergey Borushevsky Date: Mon, 26 Oct 2009 21:16:23 +0200 Subject: Fixed normal bug EXT-1450 (Set max height on Gestures tray). --HG-- branch : product-engine --- indra/newview/llnearbychatbar.cpp | 26 ++++++++++++++++++++++++++ indra/newview/llnearbychatbar.h | 3 +++ 2 files changed, 29 insertions(+) (limited to 'indra') diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 5fa97926a5..217007fb15 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -45,6 +45,7 @@ #include "llviewerstats.h" #include "llcommandhandler.h" #include "llviewercontrol.h" +#include "llnavigationbar.h" S32 LLNearbyChatBar::sLastSpecialChatChannel = 0; @@ -177,6 +178,31 @@ void LLGestureComboBox::draw() LLComboBox::draw(); } +//virtual +void LLGestureComboBox::showList() +{ + LLComboBox::showList(); + + // Calculating amount of space between the navigation bar and gestures combo + LLNavigationBar* nb = LLNavigationBar::getInstance(); + S32 x, nb_bottom; + nb->localPointToScreen(0, 0, &x, &nb_bottom); + + S32 list_bottom; + mList->localPointToScreen(0, 0, &x, &list_bottom); + + S32 max_height = nb_bottom - list_bottom; + + LLRect rect = mList->getRect(); + // List overlapped navigation bar, downsize it + if (rect.getHeight() > max_height) + { + rect.setOriginAndSize(rect.mLeft, rect.mBottom, rect.getWidth(), max_height); + mList->setRect(rect); + mList->reshape(rect.getWidth(), rect.getHeight()); + } +} + LLNearbyChatBar::LLNearbyChatBar() : LLPanel() , mChatBox(NULL) diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index b902ff86cc..d495a10193 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -62,6 +62,9 @@ public: virtual void changed() { refreshGestures(); } protected: + + virtual void showList(); + LLFrameTimer mGestureLabelTimer; std::vector mGestures; std::string mLabel; -- cgit v1.2.3 From b5ee0673661b37fbd6243d70c1d2c968e3186374 Mon Sep 17 00:00:00 2001 From: Eugene Kondrashev Date: Mon, 26 Oct 2009 20:46:36 +0200 Subject: Fixed major bug EXT-1850-Crash after open of group-chat (ProductEngine) --HG-- branch : product-engine --- indra/newview/llparticipantlist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 25e773e8b8..534c69a2a3 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -87,7 +87,7 @@ bool LLParticipantList::SpeakerAddListener::handleEvent(LLPointer event, const LLSD& userdata) { LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs(); - group_members.erase(std::find(group_members.begin(), group_members.end(), event->getValue().asUUID())); + group_members.erase(std::find(group_members.begin(), group_members.end(), event->getValue().asUUID()), group_members.end()); mAvatarList->setDirty(); return true; } -- cgit v1.2.3 From d0d208fbf6e156c73b83b780a73f4613769a381d Mon Sep 17 00:00:00 2001 From: Eugene Mutavchi Date: Mon, 26 Oct 2009 20:58:04 +0200 Subject: Fixed low bug EXT-1851 (Unable to process multiple selected friends) --HG-- branch : product-engine --- indra/newview/llpanelpeople.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'indra') diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index dc0df5f1f5..4580eeb336 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -615,6 +615,10 @@ void LLPanelPeople::updateButtons() bool recent_tab_active = (cur_tab == RECENT_TAB_NAME); LLUUID selected_id; + std::vector selected_uuids; + getCurrentItemIDs(selected_uuids); + bool item_selected = (selected_uuids.size() == 1); + buttonSetVisible("group_info_btn", group_tab_active); buttonSetVisible("chat_btn", group_tab_active); buttonSetVisible("add_friend_btn", nearby_tab_active || recent_tab_active); @@ -625,7 +629,6 @@ void LLPanelPeople::updateButtons() if (group_tab_active) { - bool item_selected = mGroupList->getSelectedItem() != NULL; bool cur_group_active = true; if (item_selected) @@ -633,7 +636,7 @@ void LLPanelPeople::updateButtons() selected_id = mGroupList->getSelectedUUID(); cur_group_active = (gAgent.getGroupID() == selected_id); } - + LLPanel* groups_panel = mTabContainer->getCurrentPanel(); groups_panel->childSetEnabled("activate_btn", item_selected && !cur_group_active); // "none" or a non-active group selected groups_panel->childSetEnabled("plus_btn", item_selected); @@ -644,18 +647,18 @@ void LLPanelPeople::updateButtons() bool is_friend = true; // Check whether selected avatar is our friend. - if ((selected_id = getCurrentItemID()).notNull()) + if (item_selected) { + selected_id = selected_uuids.front(); is_friend = LLAvatarTracker::instance().getBuddyInfo(selected_id) != NULL; } childSetEnabled("add_friend_btn", !is_friend); } - bool item_selected = selected_id.notNull(); buttonSetEnabled("teleport_btn", friends_tab_active && item_selected); buttonSetEnabled("view_profile_btn", item_selected); - buttonSetEnabled("im_btn", item_selected); + buttonSetEnabled("im_btn", (selected_uuids.size() >= 1)); // allow starting the friends conference for multiple selection buttonSetEnabled("call_btn", item_selected && false); // not implemented yet buttonSetEnabled("share_btn", item_selected && false); // not implemented yet buttonSetEnabled("group_info_btn", item_selected); @@ -881,7 +884,17 @@ void LLPanelPeople::onAddFriendWizButtonClicked() void LLPanelPeople::onDeleteFriendButtonClicked() { - LLAvatarActions::removeFriendDialog(getCurrentItemID()); + std::vector selected_uuids; + getCurrentItemIDs(selected_uuids); + + if (selected_uuids.size() == 1) + { + LLAvatarActions::removeFriendDialog( selected_uuids.front() ); + } + else if (selected_uuids.size() > 1) + { + LLAvatarActions::removeFriendsDialog( selected_uuids ); + } } void LLPanelPeople::onGroupInfoButtonClicked() -- cgit v1.2.3 From 62c8f55e3e49f55bc76dbcaba797ca02b3072c3f Mon Sep 17 00:00:00 2001 From: "Yuri Chebotarev ychebotarev@productengine.com" Date: Tue, 27 Oct 2009 11:28:46 +0200 Subject: working on EXT-1713,EXT-1712,EXT-1711,EXT-1709 EXT-1713 Nearby Chat: Objects have tooltips (???)(???) EXT-1712 Nearby Chat: change context menu for objects EXT-1711 Nearby Chat: context menu isn't applicable for system messages EXT-1709 Nearby Chat: Avatar context menu can be triggered on avatar's icon only initial commit - panel for message headers --HG-- branch : product-engine --- indra/newview/llchathistory.cpp | 227 +++++++++++++++++++++++++++++++++++++--- indra/newview/llchathistory.h | 7 +- indra/newview/llimfloater.cpp | 6 +- indra/newview/llnearbychat.cpp | 20 +--- 4 files changed, 220 insertions(+), 40 deletions(-) (limited to 'indra') diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index ebf46a6e3f..8d16f8e1f9 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -38,9 +38,210 @@ #include "llscrollcontainer.h" #include "llavatariconctrl.h" +#include "llimview.h" +#include "llcallingcard.h" //for LLAvatarTracker +#include "llagentdata.h" +#include "llavataractions.h" +#include "lltrans.h" + static LLDefaultChildRegistry::Register r("chat_history"); static const std::string MESSAGE_USERNAME_DATE_SEPARATOR(" ----- "); +std::string formatCurrentTime() +{ + time_t utc_time; + utc_time = time_corrected(); + std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" + +LLTrans::getString("TimeMin")+"] "; + + LLSD substitution; + + substitution["datetime"] = (S32) utc_time; + LLStringUtil::format (timeStr, substitution); + + return timeStr; +} + +class LLChatHistoryHeader: public LLPanel +{ +public: + static LLChatHistoryHeader* createInstance(const std::string& file_name) + { + LLChatHistoryHeader* pInstance = new LLChatHistoryHeader; + LLUICtrlFactory::getInstance()->buildPanel(pInstance, file_name); + return pInstance; + } + + BOOL handleMouseUp(S32 x, S32 y, MASK mask) + { + return LLPanel::handleMouseUp(x,y,mask); + } + + void onAvatarIconContextMenuItemClicked(const LLSD& userdata) + { + std::string level = userdata.asString(); + + if (level == "profile") + { + LLAvatarActions::showProfile(getAvatarId()); + } + else if (level == "im") + { + LLAvatarActions::startIM(getAvatarId()); + } + else if (level == "add") + { + std::string name; + name.assign(getFirstName()); + name.append(" "); + name.append(getLastName()); + + LLAvatarActions::requestFriendshipDialog(getAvatarId(), name); + } + else if (level == "remove") + { + LLAvatarActions::removeFriendDialog(getAvatarId()); + } + } + + BOOL postBuild() + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + + registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2)); + + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + + mPopupMenuHandleAvatar = menu->getHandle(); + + return LLPanel::postBuild(); + } + + bool pointInChild(const std::string& name,S32 x,S32 y) + { + LLUICtrl* child = findChild(name); + if(!child) + return false; + S32 local_x = x - child->getRect().mLeft ; + S32 local_y = y - child->getRect().mBottom ; + return child->pointInView(local_x, local_y); + } + + BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) + { + if(pointInChild("avatar_icon",x,y) || pointInChild("user_name",x,y)) + { + showContextMenu(x,y); + return TRUE; + } + + return LLPanel::handleRightMouseDown(x,y,mask); + } + const LLUUID& getAvatarId () const { return mAvatarID;} + const std::string& getFirstName() const { return mFirstName; } + const std::string& getLastName () const { return mLastName; } + + void setup(const LLChat& chat) + { + mAvatarID = chat.mFromID; + mSourceType = chat.mSourceType; + gCacheName->get(mAvatarID, FALSE, boost::bind(&LLChatHistoryHeader::nameUpdatedCallback, this, _1, _2, _3, _4)); + if(chat.mFromID.isNull()) + { + mSourceType = CHAT_SOURCE_SYSTEM; + } + + LLTextBox* userName = getChild("user_name"); + + if(!chat.mFromName.empty()) + userName->setValue(chat.mFromName); + else + { + std::string SL = LLTrans::getString("SECOND_LIFE"); + userName->setValue(SL); + } + + LLTextBox* timeBox = getChild("time_box"); + timeBox->setValue(formatCurrentTime()); + + LLAvatarIconCtrl* icon = getChild("avatar_icon"); + + + if(!chat.mFromID.isNull()) + { + icon->setValue(chat.mFromID); + } + else + { + + } + + if(mSourceType != CHAT_SOURCE_AGENT) + icon->setToolTip(std::string("")); + } + + void nameUpdatedCallback(const LLUUID& id,const std::string& first,const std::string& last,BOOL is_group) + { + if (id != mAvatarID) + return; + mFirstName = first; + mLastName = last; + } +protected: + void showContextMenu(S32 x,S32 y) + { + if(mSourceType == CHAT_SOURCE_SYSTEM) + showSystemContextMenu(x,y); + if(mSourceType == CHAT_SOURCE_AGENT) + showAvatarContextMenu(x,y); + if(mSourceType == CHAT_SOURCE_OBJECT) + showObjectContextMenu(x,y); + } + + void showSystemContextMenu(S32 x,S32 y) + { + } + void showObjectContextMenu(S32 x,S32 y) + { + } + + void showAvatarContextMenu(S32 x,S32 y) + { + LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleAvatar.get(); + + if(menu) + { + bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL; + + menu->setItemEnabled("Add Friend", !is_friend); + menu->setItemEnabled("Remove Friend", is_friend); + + if(gAgentID == mAvatarID) + { + menu->setItemEnabled("Add Friend", false); + menu->setItemEnabled("Send IM", false); + menu->setItemEnabled("Remove Friend", false); + } + + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(this, menu, x, y); + } + } + + + +protected: + LLHandle mPopupMenuHandleAvatar; + + LLUUID mAvatarID; + EChatSourceType mSourceType; + std::string mFirstName; + std::string mLastName; + +}; + + LLChatHistory::LLChatHistory(const LLChatHistory::Params& p) : LLTextEditor(p), mMessageHeaderFilename(p.message_header), @@ -78,35 +279,27 @@ LLView* LLChatHistory::getSeparator() return separator; } -LLView* LLChatHistory::getHeader(const LLUUID& avatar_id, std::string& from, std::string& time) +LLView* LLChatHistory::getHeader(const LLChat& chat) { - LLPanel* header = LLUICtrlFactory::getInstance()->createFromFile(mMessageHeaderFilename, NULL, LLPanel::child_registry_t::instance()); - LLTextBox* userName = header->getChild("user_name"); - userName->setValue(from); - LLTextBox* timeBox = header->getChild("time_box"); - timeBox->setValue(time); - if(!avatar_id.isNull()) - { - LLAvatarIconCtrl* icon = header->getChild("avatar_icon"); - icon->setValue(avatar_id); - } + LLChatHistoryHeader* header = LLChatHistoryHeader::createInstance(mMessageHeaderFilename); + header->setup(chat); return header; } -void LLChatHistory::appendWidgetMessage(const LLUUID& avatar_id, std::string& from, std::string& time, std::string& message, LLStyle::Params& style_params) +void LLChatHistory::appendWidgetMessage(const LLChat& chat, LLStyle::Params& style_params) { LLView* view = NULL; std::string view_text; - if (mLastFromName == from) + if (mLastFromName == chat.mFromName) { view = getSeparator(); view_text = " "; } else { - view = getHeader(avatar_id, from, time); - view_text = "\n" + from + MESSAGE_USERNAME_DATE_SEPARATOR + time; + view = getHeader(chat); + view_text = "\n" + chat.mFromName + MESSAGE_USERNAME_DATE_SEPARATOR + formatCurrentTime(); } //Prepare the rect for the view LLRect target_rect = getDocumentView()->getRect(); @@ -118,9 +311,9 @@ void LLChatHistory::appendWidgetMessage(const LLUUID& avatar_id, std::string& fr appendWidget(view, view_text, FALSE, TRUE, mLeftWidgetPad, 0); //Append the text message - appendText(message, TRUE, style_params); + appendText(chat.mText, TRUE, style_params); - mLastFromName = from; + mLastFromName = chat.mFromName; blockUndo(); setCursorAndScrollToEnd(); } diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h index d6eccf896a..f13e974a9c 100644 --- a/indra/newview/llchathistory.h +++ b/indra/newview/llchathistory.h @@ -34,6 +34,7 @@ #define LLCHATHISTORY_H_ #include "lltexteditor.h" +#include "llchat.h" //Chat log widget allowing addition of a message as a widget class LLChatHistory : public LLTextEditor @@ -85,7 +86,7 @@ class LLChatHistory : public LLTextEditor * @param time time of a message. * @return pointer to LLView header object. */ - LLView* getHeader(const LLUUID& avatar_id, std::string& from, std::string& time); + LLView* getHeader(const LLChat& chat); public: ~LLChatHistory(); @@ -94,11 +95,11 @@ class LLChatHistory : public LLTextEditor * Appends a widget message. * If last user appended message, concurs with current user, * separator is added before the message, otherwise header is added. - * @param from owner of a message. + * @param chat - base chat message. * @param time time of a message. * @param message message itself. */ - void appendWidgetMessage(const LLUUID& avatar_id, std::string& from, std::string& time, std::string& message, LLStyle::Params& style_params); + void appendWidgetMessage(const LLChat& chat, LLStyle::Params& style_params); private: std::string mLastFromName; diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index a20b5ea66c..d0d176766d 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -428,7 +428,11 @@ void LLIMFloater::updateMessages() if (from == agent_name) from = LLTrans::getString("You"); - mChatHistory->appendWidgetMessage(from_id, from, time, message, style_params); + LLChat chat(message); + chat.mFromID = from_id; + chat.mFromName = from; + + mChatHistory->appendWidgetMessage(chat, style_params); mLastMessageIndex = msg["index"].asInteger(); } diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index bbab9944f3..8e297c5d95 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -170,22 +170,6 @@ LLColor4 nearbychat_get_text_color(const LLChat& chat) return text_color; } -std::string formatCurrentTime() -{ - time_t utc_time; - utc_time = time_corrected(); - std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" - +LLTrans::getString("TimeMin")+"] "; - - LLSD substitution; - - substitution["datetime"] = (S32) utc_time; - LLStringUtil::format (timeStr, substitution); - - return timeStr; -} - - void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& color) { S32 font_size = gSavedSettings.getS32("ChatFontSize"); @@ -210,16 +194,14 @@ void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& colo style_params.font(fontp); LLUUID uuid = chat.mFromID; std::string from = chat.mFromName; - std::string time = formatCurrentTime(); std::string message = chat.mText; - mChatHistory->appendWidgetMessage(uuid, from, time, message, style_params); + mChatHistory->appendWidgetMessage(chat, style_params); } void LLNearbyChat::addMessage(const LLChat& chat) { LLColor4 color = nearbychat_get_text_color(chat); - if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) { LLFloaterScriptDebug::addScriptLine(chat.mText, -- cgit v1.2.3 From e39ec1e0423646edae2c3b659705af53bfe5d61c Mon Sep 17 00:00:00 2001 From: Dmitry Oleshko Date: Tue, 27 Oct 2009 12:39:50 +0200 Subject: fixed normal bug (EXT-1805) Noninteractive notification toast is redundant if local chat floater is open --HG-- branch : product-engine --- indra/newview/llnotificationtiphandler.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'indra') diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index 7239f49b7f..543198c1d2 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -86,6 +86,20 @@ bool LLTipHandler::processNotification(const LLSD& notify) if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") { + // archive message in nearby chat + LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); + if(nearby_chat) + { + LLChat chat_msg(notification->getMessage()); + nearby_chat->addMessage(chat_msg); + + // don't show toast if Nearby Chat is opened + if (nearby_chat->getVisible()) + { + return true; + } + } + LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification); LLToast::Params p; @@ -99,14 +113,6 @@ bool LLTipHandler::processNotification(const LLSD& notify) LLScreenChannel* channel = dynamic_cast(mChannel); if(channel) channel->addToast(p); - - // archive message in nearby chat - LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); - if(nearby_chat) - { - LLChat chat_msg(notification->getMessage()); - nearby_chat->addMessage(chat_msg); - } } else if (notify["sigtype"].asString() == "delete") { -- cgit v1.2.3 From 6222149487d7e241ad7b009dae1f2fa6f69adc5d Mon Sep 17 00:00:00 2001 From: Igor Borovkov Date: Tue, 27 Oct 2009 13:16:44 +0200 Subject: IM refactoring: moved voice channel related classes to its own llvoicechannel.* files from dying llimpanel.* files --HG-- branch : product-engine --- indra/newview/CMakeLists.txt | 2 + indra/newview/llappviewer.cpp | 2 +- indra/newview/llfloaterchatterbox.cpp | 2 +- indra/newview/llfloatervoicedevicesettings.cpp | 2 +- indra/newview/llimfloater.cpp | 2 +- indra/newview/llimpanel.cpp | 830 +---------------------- indra/newview/llimpanel.h | 127 ---- indra/newview/llimview.cpp | 1 + indra/newview/llvoicechannel.cpp | 872 +++++++++++++++++++++++++ indra/newview/llvoicechannel.h | 167 +++++ indra/newview/llvoiceclient.cpp | 2 +- 11 files changed, 1051 insertions(+), 958 deletions(-) create mode 100644 indra/newview/llvoicechannel.cpp create mode 100644 indra/newview/llvoicechannel.h (limited to 'indra') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index dd3937a6ef..d81ce0c4db 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -484,6 +484,7 @@ set(viewer_SOURCE_FILES llvoclouds.cpp llvograss.cpp llvoground.cpp + llvoicechannel.cpp llvoiceclient.cpp llvoiceremotectrl.cpp llvoicevisualizer.cpp @@ -960,6 +961,7 @@ set(viewer_HEADER_FILES llvoclouds.h llvograss.h llvoground.h + llvoicechannel.h llvoiceclient.h llvoiceremotectrl.h llvoicevisualizer.h diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 923a66ee8e..2ff414344a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -49,7 +49,6 @@ #include "llviewerstats.h" #include "llmd5.h" #include "llpumpio.h" -#include "llimpanel.h" #include "llmimetypes.h" #include "llslurl.h" #include "llstartup.h" @@ -76,6 +75,7 @@ #include "llteleporthistory.h" #include "lllocationhistory.h" #include "llfasttimerview.h" +#include "llvoicechannel.h" #include "llweb.h" #include "llsecondlifeurls.h" diff --git a/indra/newview/llfloaterchatterbox.cpp b/indra/newview/llfloaterchatterbox.cpp index dea656b0e4..fbf09207fe 100644 --- a/indra/newview/llfloaterchatterbox.cpp +++ b/indra/newview/llfloaterchatterbox.cpp @@ -42,7 +42,7 @@ #include "llfloaterfriends.h" #include "llfloatergroups.h" #include "llviewercontrol.h" -#include "llimview.h" +#include "llvoicechannel.h" #include "llimpanel.h" // diff --git a/indra/newview/llfloatervoicedevicesettings.cpp b/indra/newview/llfloatervoicedevicesettings.cpp index b64257b11d..aca9198f59 100644 --- a/indra/newview/llfloatervoicedevicesettings.cpp +++ b/indra/newview/llfloatervoicedevicesettings.cpp @@ -43,7 +43,7 @@ #include "llsliderctrl.h" #include "llviewercontrol.h" #include "llvoiceclient.h" -#include "llimpanel.h" +#include "llvoicechannel.h" // Library includes (after viewer) #include "lluictrlfactory.h" diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 91e383eb14..0e9d7b070a 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -42,7 +42,6 @@ #include "llchiclet.h" #include "llfloaterchat.h" #include "llfloaterreg.h" -#include "llimview.h" #include "lllineeditor.h" #include "lllogchat.h" #include "llpanelimcontrolpanel.h" @@ -50,6 +49,7 @@ #include "lltrans.h" #include "llchathistory.h" #include "llviewerwindow.h" +#include "llvoicechannel.h" #include "lltransientfloatermgr.h" diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 163984f740..2d8372db04 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -77,6 +77,7 @@ #include "llviewercontrol.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" +#include "llvoicechannel.h" #include "lllogchat.h" #include "llweb.h" #include "llhttpclient.h" @@ -90,7 +91,6 @@ const S32 LINE_HEIGHT = 16; const S32 MIN_WIDTH = 200; const S32 MIN_HEIGHT = 130; -const U32 DEFAULT_RETRIES_COUNT = 3; // // Statics @@ -100,831 +100,6 @@ static std::string sTitleString = "Instant Message with [NAME]"; static std::string sTypingStartString = "[NAME]: ..."; static std::string sSessionStartString = "Starting session with [NAME] please wait."; -LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap; -LLVoiceChannel::voice_channel_map_uri_t LLVoiceChannel::sVoiceChannelURIMap; -LLVoiceChannel* LLVoiceChannel::sCurrentVoiceChannel = NULL; -LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL; - -BOOL LLVoiceChannel::sSuspended = FALSE; - - - -class LLVoiceCallCapResponder : public LLHTTPClient::Responder -{ -public: - LLVoiceCallCapResponder(const LLUUID& session_id) : mSessionID(session_id) {}; - - virtual void error(U32 status, const std::string& reason); // called with bad status codes - virtual void result(const LLSD& content); - -private: - LLUUID mSessionID; -}; - - -void LLVoiceCallCapResponder::error(U32 status, const std::string& reason) -{ - llwarns << "LLVoiceCallCapResponder::error(" - << status << ": " << reason << ")" - << llendl; - LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID); - if ( channelp ) - { - if ( 403 == status ) - { - //403 == no ability - LLNotifications::instance().add( - "VoiceNotAllowed", - channelp->getNotifyArgs()); - } - else - { - LLNotifications::instance().add( - "VoiceCallGenericError", - channelp->getNotifyArgs()); - } - channelp->deactivate(); - } -} - -void LLVoiceCallCapResponder::result(const LLSD& content) -{ - LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID); - if (channelp) - { - //*TODO: DEBUG SPAM - LLSD::map_const_iterator iter; - for(iter = content.beginMap(); iter != content.endMap(); ++iter) - { - llinfos << "LLVoiceCallCapResponder::result got " - << iter->first << llendl; - } - - channelp->setChannelInfo( - content["voice_credentials"]["channel_uri"].asString(), - content["voice_credentials"]["channel_credentials"].asString()); - } -} - -// -// LLVoiceChannel -// -LLVoiceChannel::LLVoiceChannel(const LLUUID& session_id, const std::string& session_name) : - mSessionID(session_id), - mState(STATE_NO_CHANNEL_INFO), - mSessionName(session_name), - mIgnoreNextSessionLeave(FALSE) -{ - mNotifyArgs["VOICE_CHANNEL_NAME"] = mSessionName; - - if (!sVoiceChannelMap.insert(std::make_pair(session_id, this)).second) - { - // a voice channel already exists for this session id, so this instance will be orphaned - // the end result should simply be the failure to make voice calls - llwarns << "Duplicate voice channels registered for session_id " << session_id << llendl; - } - - LLVoiceClient::getInstance()->addObserver(this); -} - -LLVoiceChannel::~LLVoiceChannel() -{ - // Don't use LLVoiceClient::getInstance() here -- this can get called during atexit() time and that singleton MAY have already been destroyed. - if(gVoiceClient) - { - gVoiceClient->removeObserver(this); - } - - sVoiceChannelMap.erase(mSessionID); - sVoiceChannelURIMap.erase(mURI); -} - -void LLVoiceChannel::setChannelInfo( - const std::string& uri, - const std::string& credentials) -{ - setURI(uri); - - mCredentials = credentials; - - if (mState == STATE_NO_CHANNEL_INFO) - { - if (mURI.empty()) - { - LLNotifications::instance().add("VoiceChannelJoinFailed", mNotifyArgs); - llwarns << "Received empty URI for channel " << mSessionName << llendl; - deactivate(); - } - else if (mCredentials.empty()) - { - LLNotifications::instance().add("VoiceChannelJoinFailed", mNotifyArgs); - llwarns << "Received empty credentials for channel " << mSessionName << llendl; - deactivate(); - } - else - { - setState(STATE_READY); - - // if we are supposed to be active, reconnect - // this will happen on initial connect, as we request credentials on first use - if (sCurrentVoiceChannel == this) - { - // just in case we got new channel info while active - // should move over to new channel - activate(); - } - } - } -} - -void LLVoiceChannel::onChange(EStatusType type, const std::string &channelURI, bool proximal) -{ - if (channelURI != mURI) - { - return; - } - - if (type < BEGIN_ERROR_STATUS) - { - handleStatusChange(type); - } - else - { - handleError(type); - } -} - -void LLVoiceChannel::handleStatusChange(EStatusType type) -{ - // status updates - switch(type) - { - case STATUS_LOGIN_RETRY: - //mLoginNotificationHandle = LLNotifyBox::showXml("VoiceLoginRetry")->getHandle(); - LLNotifications::instance().add("VoiceLoginRetry"); - break; - case STATUS_LOGGED_IN: - //if (!mLoginNotificationHandle.isDead()) - //{ - // LLNotifyBox* notifyp = (LLNotifyBox*)mLoginNotificationHandle.get(); - // if (notifyp) - // { - // notifyp->close(); - // } - // mLoginNotificationHandle.markDead(); - //} - break; - case STATUS_LEFT_CHANNEL: - if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended) - { - // if forceably removed from channel - // update the UI and revert to default channel - LLNotifications::instance().add("VoiceChannelDisconnected", mNotifyArgs); - deactivate(); - } - mIgnoreNextSessionLeave = FALSE; - break; - case STATUS_JOINING: - if (callStarted()) - { - setState(STATE_RINGING); - } - break; - case STATUS_JOINED: - if (callStarted()) - { - setState(STATE_CONNECTED); - } - default: - break; - } -} - -// default behavior is to just deactivate channel -// derived classes provide specific error messages -void LLVoiceChannel::handleError(EStatusType type) -{ - deactivate(); - setState(STATE_ERROR); -} - -BOOL LLVoiceChannel::isActive() -{ - // only considered active when currently bound channel matches what our channel - return callStarted() && LLVoiceClient::getInstance()->getCurrentChannel() == mURI; -} - -BOOL LLVoiceChannel::callStarted() -{ - return mState >= STATE_CALL_STARTED; -} - -void LLVoiceChannel::deactivate() -{ - if (mState >= STATE_RINGING) - { - // ignore session leave event - mIgnoreNextSessionLeave = TRUE; - } - - if (callStarted()) - { - setState(STATE_HUNG_UP); - // mute the microphone if required when returning to the proximal channel - if (gSavedSettings.getBOOL("AutoDisengageMic") && sCurrentVoiceChannel == this) - { - gSavedSettings.setBOOL("PTTCurrentlyEnabled", true); - } - } - - if (sCurrentVoiceChannel == this) - { - // default channel is proximal channel - sCurrentVoiceChannel = LLVoiceChannelProximal::getInstance(); - sCurrentVoiceChannel->activate(); - } -} - -void LLVoiceChannel::activate() -{ - if (callStarted()) - { - return; - } - - // deactivate old channel and mark ourselves as the active one - if (sCurrentVoiceChannel != this) - { - // mark as current before deactivating the old channel to prevent - // activating the proximal channel between IM calls - LLVoiceChannel* old_channel = sCurrentVoiceChannel; - sCurrentVoiceChannel = this; - if (old_channel) - { - old_channel->deactivate(); - } - } - - if (mState == STATE_NO_CHANNEL_INFO) - { - // responsible for setting status to active - getChannelInfo(); - } - else - { - setState(STATE_CALL_STARTED); - } -} - -void LLVoiceChannel::getChannelInfo() -{ - // pretend we have everything we need - if (sCurrentVoiceChannel == this) - { - setState(STATE_CALL_STARTED); - } -} - -//static -LLVoiceChannel* LLVoiceChannel::getChannelByID(const LLUUID& session_id) -{ - voice_channel_map_t::iterator found_it = sVoiceChannelMap.find(session_id); - if (found_it == sVoiceChannelMap.end()) - { - return NULL; - } - else - { - return found_it->second; - } -} - -//static -LLVoiceChannel* LLVoiceChannel::getChannelByURI(std::string uri) -{ - voice_channel_map_uri_t::iterator found_it = sVoiceChannelURIMap.find(uri); - if (found_it == sVoiceChannelURIMap.end()) - { - return NULL; - } - else - { - return found_it->second; - } -} - -void LLVoiceChannel::updateSessionID(const LLUUID& new_session_id) -{ - sVoiceChannelMap.erase(sVoiceChannelMap.find(mSessionID)); - mSessionID = new_session_id; - sVoiceChannelMap.insert(std::make_pair(mSessionID, this)); -} - -void LLVoiceChannel::setURI(std::string uri) -{ - sVoiceChannelURIMap.erase(mURI); - mURI = uri; - sVoiceChannelURIMap.insert(std::make_pair(mURI, this)); -} - -void LLVoiceChannel::setState(EState state) -{ - switch(state) - { - case STATE_RINGING: - gIMMgr->addSystemMessage(mSessionID, "ringing", mNotifyArgs); - break; - case STATE_CONNECTED: - gIMMgr->addSystemMessage(mSessionID, "connected", mNotifyArgs); - break; - case STATE_HUNG_UP: - gIMMgr->addSystemMessage(mSessionID, "hang_up", mNotifyArgs); - break; - default: - break; - } - - mState = state; -} - -void LLVoiceChannel::toggleCallWindowIfNeeded(EState state) -{ - if (state == STATE_CONNECTED) - { - LLFloaterReg::showInstance("voice_call", mSessionID); - } - // By checking that current state is CONNECTED we make sure that the call window - // has been shown, hence there's something to hide. This helps when user presses - // the "End call" button right after initiating the call. - // *TODO: move this check to LLFloaterCall? - else if (state == STATE_HUNG_UP && mState == STATE_CONNECTED) - { - LLFloaterReg::hideInstance("voice_call", mSessionID); - } -} - -//static -void LLVoiceChannel::initClass() -{ - sCurrentVoiceChannel = LLVoiceChannelProximal::getInstance(); -} - - -//static -void LLVoiceChannel::suspend() -{ - if (!sSuspended) - { - sSuspendedVoiceChannel = sCurrentVoiceChannel; - sSuspended = TRUE; - } -} - -//static -void LLVoiceChannel::resume() -{ - if (sSuspended) - { - if (gVoiceClient->voiceEnabled()) - { - if (sSuspendedVoiceChannel) - { - sSuspendedVoiceChannel->activate(); - } - else - { - LLVoiceChannelProximal::getInstance()->activate(); - } - } - sSuspended = FALSE; - } -} - - -// -// LLVoiceChannelGroup -// - -LLVoiceChannelGroup::LLVoiceChannelGroup(const LLUUID& session_id, const std::string& session_name) : - LLVoiceChannel(session_id, session_name) -{ - mRetries = DEFAULT_RETRIES_COUNT; - mIsRetrying = FALSE; -} - -void LLVoiceChannelGroup::deactivate() -{ - if (callStarted()) - { - LLVoiceClient::getInstance()->leaveNonSpatialChannel(); - } - LLVoiceChannel::deactivate(); -} - -void LLVoiceChannelGroup::activate() -{ - if (callStarted()) return; - - LLVoiceChannel::activate(); - - if (callStarted()) - { - // we have the channel info, just need to use it now - LLVoiceClient::getInstance()->setNonSpatialChannel( - mURI, - mCredentials); - -#if 0 // *TODO - if (!gAgent.isInGroup(mSessionID)) // ad-hoc channel - { - // Add the party to the list of people with which we've recently interacted. - for (/*people in the chat*/) - LLRecentPeople::instance().add(buddy_id); - } -#endif - } -} - -void LLVoiceChannelGroup::getChannelInfo() -{ - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - std::string url = region->getCapability("ChatSessionRequest"); - LLSD data; - data["method"] = "call"; - data["session-id"] = mSessionID; - LLHTTPClient::post(url, - data, - new LLVoiceCallCapResponder(mSessionID)); - } -} - -void LLVoiceChannelGroup::setChannelInfo( - const std::string& uri, - const std::string& credentials) -{ - setURI(uri); - - mCredentials = credentials; - - if (mState == STATE_NO_CHANNEL_INFO) - { - if(!mURI.empty() && !mCredentials.empty()) - { - setState(STATE_READY); - - // if we are supposed to be active, reconnect - // this will happen on initial connect, as we request credentials on first use - if (sCurrentVoiceChannel == this) - { - // just in case we got new channel info while active - // should move over to new channel - activate(); - } - } - else - { - //*TODO: notify user - llwarns << "Received invalid credentials for channel " << mSessionName << llendl; - deactivate(); - } - } - else if ( mIsRetrying ) - { - // we have the channel info, just need to use it now - LLVoiceClient::getInstance()->setNonSpatialChannel( - mURI, - mCredentials); - } -} - -void LLVoiceChannelGroup::handleStatusChange(EStatusType type) -{ - // status updates - switch(type) - { - case STATUS_JOINED: - mRetries = 3; - mIsRetrying = FALSE; - default: - break; - } - - LLVoiceChannel::handleStatusChange(type); -} - -void LLVoiceChannelGroup::handleError(EStatusType status) -{ - std::string notify; - switch(status) - { - case ERROR_CHANNEL_LOCKED: - case ERROR_CHANNEL_FULL: - notify = "VoiceChannelFull"; - break; - case ERROR_NOT_AVAILABLE: - //clear URI and credentials - //set the state to be no info - //and activate - if ( mRetries > 0 ) - { - mRetries--; - mIsRetrying = TRUE; - mIgnoreNextSessionLeave = TRUE; - - getChannelInfo(); - return; - } - else - { - notify = "VoiceChannelJoinFailed"; - mRetries = DEFAULT_RETRIES_COUNT; - mIsRetrying = FALSE; - } - - break; - - case ERROR_UNKNOWN: - default: - break; - } - - // notification - if (!notify.empty()) - { - LLNotificationPtr notification = LLNotifications::instance().add(notify, mNotifyArgs); - // echo to im window - gIMMgr->addMessage(mSessionID, LLUUID::null, SYSTEM_FROM, notification->getMessage()); - } - - LLVoiceChannel::handleError(status); -} - -void LLVoiceChannelGroup::setState(EState state) -{ - // HACK: Open/close the call window if needed. - toggleCallWindowIfNeeded(state); - - switch(state) - { - case STATE_RINGING: - if ( !mIsRetrying ) - { - gIMMgr->addSystemMessage(mSessionID, "ringing", mNotifyArgs); - } - - mState = state; - break; - default: - LLVoiceChannel::setState(state); - } -} - -// -// LLVoiceChannelProximal -// -LLVoiceChannelProximal::LLVoiceChannelProximal() : - LLVoiceChannel(LLUUID::null, LLStringUtil::null) -{ - activate(); -} - -BOOL LLVoiceChannelProximal::isActive() -{ - return callStarted() && LLVoiceClient::getInstance()->inProximalChannel(); -} - -void LLVoiceChannelProximal::activate() -{ - if (callStarted()) return; - - LLVoiceChannel::activate(); - - if (callStarted()) - { - // this implicitly puts you back in the spatial channel - LLVoiceClient::getInstance()->leaveNonSpatialChannel(); - } -} - -void LLVoiceChannelProximal::onChange(EStatusType type, const std::string &channelURI, bool proximal) -{ - if (!proximal) - { - return; - } - - if (type < BEGIN_ERROR_STATUS) - { - handleStatusChange(type); - } - else - { - handleError(type); - } -} - -void LLVoiceChannelProximal::handleStatusChange(EStatusType status) -{ - // status updates - switch(status) - { - case STATUS_LEFT_CHANNEL: - // do not notify user when leaving proximal channel - return; - case STATUS_VOICE_DISABLED: - gIMMgr->addSystemMessage(LLUUID::null, "unavailable", mNotifyArgs); - return; - default: - break; - } - LLVoiceChannel::handleStatusChange(status); -} - - -void LLVoiceChannelProximal::handleError(EStatusType status) -{ - std::string notify; - switch(status) - { - case ERROR_CHANNEL_LOCKED: - case ERROR_CHANNEL_FULL: - notify = "ProximalVoiceChannelFull"; - break; - default: - break; - } - - // notification - if (!notify.empty()) - { - LLNotifications::instance().add(notify, mNotifyArgs); - } - - LLVoiceChannel::handleError(status); -} - -void LLVoiceChannelProximal::deactivate() -{ - if (callStarted()) - { - setState(STATE_HUNG_UP); - } -} - - -// -// LLVoiceChannelP2P -// -LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const std::string& session_name, const LLUUID& other_user_id) : - LLVoiceChannelGroup(session_id, session_name), - mOtherUserID(other_user_id), - mReceivedCall(FALSE) -{ - // make sure URI reflects encoded version of other user's agent id - setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id)); -} - -void LLVoiceChannelP2P::handleStatusChange(EStatusType type) -{ - // status updates - switch(type) - { - case STATUS_LEFT_CHANNEL: - if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended) - { - if (mState == STATE_RINGING) - { - // other user declined call - LLNotifications::instance().add("P2PCallDeclined", mNotifyArgs); - } - else - { - // other user hung up - LLNotifications::instance().add("VoiceChannelDisconnectedP2P", mNotifyArgs); - } - deactivate(); - } - mIgnoreNextSessionLeave = FALSE; - return; - default: - break; - } - - LLVoiceChannel::handleStatusChange(type); -} - -void LLVoiceChannelP2P::handleError(EStatusType type) -{ - switch(type) - { - case ERROR_NOT_AVAILABLE: - LLNotifications::instance().add("P2PCallNoAnswer", mNotifyArgs); - break; - default: - break; - } - - LLVoiceChannel::handleError(type); -} - -void LLVoiceChannelP2P::activate() -{ - if (callStarted()) return; - - LLVoiceChannel::activate(); - - if (callStarted()) - { - // no session handle yet, we're starting the call - if (mSessionHandle.empty()) - { - mReceivedCall = FALSE; - LLVoiceClient::getInstance()->callUser(mOtherUserID); - } - // otherwise answering the call - else - { - LLVoiceClient::getInstance()->answerInvite(mSessionHandle); - - // using the session handle invalidates it. Clear it out here so we can't reuse it by accident. - mSessionHandle.clear(); - } - - // Add the party to the list of people with which we've recently interacted. - LLRecentPeople::instance().add(mOtherUserID); - } -} - -void LLVoiceChannelP2P::getChannelInfo() -{ - // pretend we have everything we need, since P2P doesn't use channel info - if (sCurrentVoiceChannel == this) - { - setState(STATE_CALL_STARTED); - } -} - -// receiving session from other user who initiated call -void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::string &inURI) -{ - BOOL needs_activate = FALSE; - if (callStarted()) - { - // defer to lower agent id when already active - if (mOtherUserID < gAgent.getID()) - { - // pretend we haven't started the call yet, so we can connect to this session instead - deactivate(); - needs_activate = TRUE; - } - else - { - // we are active and have priority, invite the other user again - // under the assumption they will join this new session - mSessionHandle.clear(); - LLVoiceClient::getInstance()->callUser(mOtherUserID); - return; - } - } - - mSessionHandle = handle; - - // The URI of a p2p session should always be the other end's SIP URI. - if(!inURI.empty()) - { - setURI(inURI); - } - else - { - setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID)); - } - - mReceivedCall = TRUE; - - if (needs_activate) - { - activate(); - } -} - -void LLVoiceChannelP2P::setState(EState state) -{ - // HACK: Open/close the call window if needed. - toggleCallWindowIfNeeded(state); - - // you only "answer" voice invites in p2p mode - // so provide a special purpose message here - if (mReceivedCall && state == STATE_RINGING) - { - gIMMgr->addSystemMessage(mSessionID, "answering", mNotifyArgs); - mState = state; - return; - } - LLVoiceChannel::setState(state); -} - // // LLFloaterIMPanel @@ -1905,6 +1080,9 @@ bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const session_id); if ( floaterp ) floaterp->closeFloater(FALSE); + + + } return false; } diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index 4e306c7fab..31b5c5c127 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -50,133 +50,6 @@ class LLIMSpeakerMgr; class LLPanelActiveSpeakers; class LLPanelChatControlPanel; -class LLVoiceChannel : public LLVoiceClientStatusObserver -{ -public: - typedef enum e_voice_channel_state - { - STATE_NO_CHANNEL_INFO, - STATE_ERROR, - STATE_HUNG_UP, - STATE_READY, - STATE_CALL_STARTED, - STATE_RINGING, - STATE_CONNECTED - } EState; - - LLVoiceChannel(const LLUUID& session_id, const std::string& session_name); - virtual ~LLVoiceChannel(); - - /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); - - virtual void handleStatusChange(EStatusType status); - virtual void handleError(EStatusType status); - virtual void deactivate(); - virtual void activate(); - virtual void setChannelInfo( - const std::string& uri, - const std::string& credentials); - virtual void getChannelInfo(); - virtual BOOL isActive(); - virtual BOOL callStarted(); - const std::string& getSessionName() const { return mSessionName; } - - const LLUUID getSessionID() { return mSessionID; } - EState getState() { return mState; } - - void updateSessionID(const LLUUID& new_session_id); - const LLSD& getNotifyArgs() { return mNotifyArgs; } - - static LLVoiceChannel* getChannelByID(const LLUUID& session_id); - static LLVoiceChannel* getChannelByURI(std::string uri); - static LLVoiceChannel* getCurrentVoiceChannel() { return sCurrentVoiceChannel; } - static void initClass(); - - static void suspend(); - static void resume(); - -protected: - virtual void setState(EState state); - void toggleCallWindowIfNeeded(EState state); - void setURI(std::string uri); - - std::string mURI; - std::string mCredentials; - LLUUID mSessionID; - EState mState; - std::string mSessionName; - LLSD mNotifyArgs; - BOOL mIgnoreNextSessionLeave; - LLHandle mLoginNotificationHandle; - - typedef std::map voice_channel_map_t; - static voice_channel_map_t sVoiceChannelMap; - - typedef std::map voice_channel_map_uri_t; - static voice_channel_map_uri_t sVoiceChannelURIMap; - - static LLVoiceChannel* sCurrentVoiceChannel; - static LLVoiceChannel* sSuspendedVoiceChannel; - static BOOL sSuspended; -}; - -class LLVoiceChannelGroup : public LLVoiceChannel -{ -public: - LLVoiceChannelGroup(const LLUUID& session_id, const std::string& session_name); - - /*virtual*/ void handleStatusChange(EStatusType status); - /*virtual*/ void handleError(EStatusType status); - /*virtual*/ void activate(); - /*virtual*/ void deactivate(); - /*vritual*/ void setChannelInfo( - const std::string& uri, - const std::string& credentials); - /*virtual*/ void getChannelInfo(); - -protected: - virtual void setState(EState state); - -private: - U32 mRetries; - BOOL mIsRetrying; -}; - -class LLVoiceChannelProximal : public LLVoiceChannel, public LLSingleton -{ -public: - LLVoiceChannelProximal(); - - /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); - /*virtual*/ void handleStatusChange(EStatusType status); - /*virtual*/ void handleError(EStatusType status); - /*virtual*/ BOOL isActive(); - /*virtual*/ void activate(); - /*virtual*/ void deactivate(); - -}; - -class LLVoiceChannelP2P : public LLVoiceChannelGroup -{ -public: - LLVoiceChannelP2P(const LLUUID& session_id, const std::string& session_name, const LLUUID& other_user_id); - - /*virtual*/ void handleStatusChange(EStatusType status); - /*virtual*/ void handleError(EStatusType status); - /*virtual*/ void activate(); - /*virtual*/ void getChannelInfo(); - - void setSessionHandle(const std::string& handle, const std::string &inURI); - -protected: - virtual void setState(EState state); - -private: - std::string mSessionHandle; - LLUUID mOtherUserID; - BOOL mReceivedCall; -}; - class LLFloaterIMPanel : public LLFloater { public: diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 59cd9cec86..164da4136f 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -70,6 +70,7 @@ #include "llviewerwindow.h" #include "llnotify.h" #include "llviewerregion.h" +#include "llvoicechannel.h" #include "lltrans.h" #include "llrecentpeople.h" diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp new file mode 100644 index 0000000000..96fcf61e62 --- /dev/null +++ b/indra/newview/llvoicechannel.cpp @@ -0,0 +1,872 @@ +/** + * @file llvoicechannel.cpp + * @brief Voice Channel related classes + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-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$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llagent.h" +#include "llfloaterreg.h" +#include "llimview.h" +#include "llnotifications.h" +#include "llpanel.h" +#include "llrecentpeople.h" +#include "llviewercontrol.h" +#include "llvoicechannel.h" + + +LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap; +LLVoiceChannel::voice_channel_map_uri_t LLVoiceChannel::sVoiceChannelURIMap; +LLVoiceChannel* LLVoiceChannel::sCurrentVoiceChannel = NULL; +LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL; + +BOOL LLVoiceChannel::sSuspended = FALSE; + +// +// Constants +// +const U32 DEFAULT_RETRIES_COUNT = 3; + + +class LLVoiceCallCapResponder : public LLHTTPClient::Responder +{ +public: + LLVoiceCallCapResponder(const LLUUID& session_id) : mSessionID(session_id) {}; + + virtual void error(U32 status, const std::string& reason); // called with bad status codes + virtual void result(const LLSD& content); + +private: + LLUUID mSessionID; +}; + + +void LLVoiceCallCapResponder::error(U32 status, const std::string& reason) +{ + llwarns << "LLVoiceCallCapResponder::error(" + << status << ": " << reason << ")" + << llendl; + LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID); + if ( channelp ) + { + if ( 403 == status ) + { + //403 == no ability + LLNotifications::instance().add( + "VoiceNotAllowed", + channelp->getNotifyArgs()); + } + else + { + LLNotifications::instance().add( + "VoiceCallGenericError", + channelp->getNotifyArgs()); + } + channelp->deactivate(); + } +} + +void LLVoiceCallCapResponder::result(const LLSD& content) +{ + LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID); + if (channelp) + { + //*TODO: DEBUG SPAM + LLSD::map_const_iterator iter; + for(iter = content.beginMap(); iter != content.endMap(); ++iter) + { + llinfos << "LLVoiceCallCapResponder::result got " + << iter->first << llendl; + } + + channelp->setChannelInfo( + content["voice_credentials"]["channel_uri"].asString(), + content["voice_credentials"]["channel_credentials"].asString()); + } +} + +// +// LLVoiceChannel +// +LLVoiceChannel::LLVoiceChannel(const LLUUID& session_id, const std::string& session_name) : + mSessionID(session_id), + mState(STATE_NO_CHANNEL_INFO), + mSessionName(session_name), + mIgnoreNextSessionLeave(FALSE) +{ + mNotifyArgs["VOICE_CHANNEL_NAME"] = mSessionName; + + if (!sVoiceChannelMap.insert(std::make_pair(session_id, this)).second) + { + // a voice channel already exists for this session id, so this instance will be orphaned + // the end result should simply be the failure to make voice calls + llwarns << "Duplicate voice channels registered for session_id " << session_id << llendl; + } + + LLVoiceClient::getInstance()->addObserver(this); +} + +LLVoiceChannel::~LLVoiceChannel() +{ + // Don't use LLVoiceClient::getInstance() here -- this can get called during atexit() time and that singleton MAY have already been destroyed. + if(gVoiceClient) + { + gVoiceClient->removeObserver(this); + } + + sVoiceChannelMap.erase(mSessionID); + sVoiceChannelURIMap.erase(mURI); +} + +void LLVoiceChannel::setChannelInfo( + const std::string& uri, + const std::string& credentials) +{ + setURI(uri); + + mCredentials = credentials; + + if (mState == STATE_NO_CHANNEL_INFO) + { + if (mURI.empty()) + { + LLNotifications::instance().add("VoiceChannelJoinFailed", mNotifyArgs); + llwarns << "Received empty URI for channel " << mSessionName << llendl; + deactivate(); + } + else if (mCredentials.empty()) + { + LLNotifications::instance().add("VoiceChannelJoinFailed", mNotifyArgs); + llwarns << "Received empty credentials for channel " << mSessionName << llendl; + deactivate(); + } + else + { + setState(STATE_READY); + + // if we are supposed to be active, reconnect + // this will happen on initial connect, as we request credentials on first use + if (sCurrentVoiceChannel == this) + { + // just in case we got new channel info while active + // should move over to new channel + activate(); + } + } + } +} + +void LLVoiceChannel::onChange(EStatusType type, const std::string &channelURI, bool proximal) +{ + if (channelURI != mURI) + { + return; + } + + if (type < BEGIN_ERROR_STATUS) + { + handleStatusChange(type); + } + else + { + handleError(type); + } +} + +void LLVoiceChannel::handleStatusChange(EStatusType type) +{ + // status updates + switch(type) + { + case STATUS_LOGIN_RETRY: + //mLoginNotificationHandle = LLNotifyBox::showXml("VoiceLoginRetry")->getHandle(); + LLNotifications::instance().add("VoiceLoginRetry"); + break; + case STATUS_LOGGED_IN: + //if (!mLoginNotificationHandle.isDead()) + //{ + // LLNotifyBox* notifyp = (LLNotifyBox*)mLoginNotificationHandle.get(); + // if (notifyp) + // { + // notifyp->close(); + // } + // mLoginNotificationHandle.markDead(); + //} + break; + case STATUS_LEFT_CHANNEL: + if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended) + { + // if forceably removed from channel + // update the UI and revert to default channel + LLNotifications::instance().add("VoiceChannelDisconnected", mNotifyArgs); + deactivate(); + } + mIgnoreNextSessionLeave = FALSE; + break; + case STATUS_JOINING: + if (callStarted()) + { + setState(STATE_RINGING); + } + break; + case STATUS_JOINED: + if (callStarted()) + { + setState(STATE_CONNECTED); + } + default: + break; + } +} + +// default behavior is to just deactivate channel +// derived classes provide specific error messages +void LLVoiceChannel::handleError(EStatusType type) +{ + deactivate(); + setState(STATE_ERROR); +} + +BOOL LLVoiceChannel::isActive() +{ + // only considered active when currently bound channel matches what our channel + return callStarted() && LLVoiceClient::getInstance()->getCurrentChannel() == mURI; +} + +BOOL LLVoiceChannel::callStarted() +{ + return mState >= STATE_CALL_STARTED; +} + +void LLVoiceChannel::deactivate() +{ + if (mState >= STATE_RINGING) + { + // ignore session leave event + mIgnoreNextSessionLeave = TRUE; + } + + if (callStarted()) + { + setState(STATE_HUNG_UP); + // mute the microphone if required when returning to the proximal channel + if (gSavedSettings.getBOOL("AutoDisengageMic") && sCurrentVoiceChannel == this) + { + gSavedSettings.setBOOL("PTTCurrentlyEnabled", true); + } + } + + if (sCurrentVoiceChannel == this) + { + // default channel is proximal channel + sCurrentVoiceChannel = LLVoiceChannelProximal::getInstance(); + sCurrentVoiceChannel->activate(); + } +} + +void LLVoiceChannel::activate() +{ + if (callStarted()) + { + return; + } + + // deactivate old channel and mark ourselves as the active one + if (sCurrentVoiceChannel != this) + { + // mark as current before deactivating the old channel to prevent + // activating the proximal channel between IM calls + LLVoiceChannel* old_channel = sCurrentVoiceChannel; + sCurrentVoiceChannel = this; + if (old_channel) + { + old_channel->deactivate(); + } + } + + if (mState == STATE_NO_CHANNEL_INFO) + { + // responsible for setting status to active + getChannelInfo(); + } + else + { + setState(STATE_CALL_STARTED); + } +} + +void LLVoiceChannel::getChannelInfo() +{ + // pretend we have everything we need + if (sCurrentVoiceChannel == this) + { + setState(STATE_CALL_STARTED); + } +} + +//static +LLVoiceChannel* LLVoiceChannel::getChannelByID(const LLUUID& session_id) +{ + voice_channel_map_t::iterator found_it = sVoiceChannelMap.find(session_id); + if (found_it == sVoiceChannelMap.end()) + { + return NULL; + } + else + { + return found_it->second; + } +} + +//static +LLVoiceChannel* LLVoiceChannel::getChannelByURI(std::string uri) +{ + voice_channel_map_uri_t::iterator found_it = sVoiceChannelURIMap.find(uri); + if (found_it == sVoiceChannelURIMap.end()) + { + return NULL; + } + else + { + return found_it->second; + } +} + +void LLVoiceChannel::updateSessionID(const LLUUID& new_session_id) +{ + sVoiceChannelMap.erase(sVoiceChannelMap.find(mSessionID)); + mSessionID = new_session_id; + sVoiceChannelMap.insert(std::make_pair(mSessionID, this)); +} + +void LLVoiceChannel::setURI(std::string uri) +{ + sVoiceChannelURIMap.erase(mURI); + mURI = uri; + sVoiceChannelURIMap.insert(std::make_pair(mURI, this)); +} + +void LLVoiceChannel::setState(EState state) +{ + switch(state) + { + case STATE_RINGING: + gIMMgr->addSystemMessage(mSessionID, "ringing", mNotifyArgs); + break; + case STATE_CONNECTED: + gIMMgr->addSystemMessage(mSessionID, "connected", mNotifyArgs); + break; + case STATE_HUNG_UP: + gIMMgr->addSystemMessage(mSessionID, "hang_up", mNotifyArgs); + break; + default: + break; + } + + mState = state; +} + +void LLVoiceChannel::toggleCallWindowIfNeeded(EState state) +{ + if (state == STATE_CONNECTED) + { + LLFloaterReg::showInstance("voice_call", mSessionID); + } + // By checking that current state is CONNECTED we make sure that the call window + // has been shown, hence there's something to hide. This helps when user presses + // the "End call" button right after initiating the call. + // *TODO: move this check to LLFloaterCall? + else if (state == STATE_HUNG_UP && mState == STATE_CONNECTED) + { + LLFloaterReg::hideInstance("voice_call", mSessionID); + } +} + +//static +void LLVoiceChannel::initClass() +{ + sCurrentVoiceChannel = LLVoiceChannelProximal::getInstance(); +} + + +//static +void LLVoiceChannel::suspend() +{ + if (!sSuspended) + { + sSuspendedVoiceChannel = sCurrentVoiceChannel; + sSuspended = TRUE; + } +} + +//static +void LLVoiceChannel::resume() +{ + if (sSuspended) + { + if (gVoiceClient->voiceEnabled()) + { + if (sSuspendedVoiceChannel) + { + sSuspendedVoiceChannel->activate(); + } + else + { + LLVoiceChannelProximal::getInstance()->activate(); + } + } + sSuspended = FALSE; + } +} + + +// +// LLVoiceChannelGroup +// + +LLVoiceChannelGroup::LLVoiceChannelGroup(const LLUUID& session_id, const std::string& session_name) : + LLVoiceChannel(session_id, session_name) +{ + mRetries = DEFAULT_RETRIES_COUNT; + mIsRetrying = FALSE; +} + +void LLVoiceChannelGroup::deactivate() +{ + if (callStarted()) + { + LLVoiceClient::getInstance()->leaveNonSpatialChannel(); + } + LLVoiceChannel::deactivate(); +} + +void LLVoiceChannelGroup::activate() +{ + if (callStarted()) return; + + LLVoiceChannel::activate(); + + if (callStarted()) + { + // we have the channel info, just need to use it now + LLVoiceClient::getInstance()->setNonSpatialChannel( + mURI, + mCredentials); + +#if 0 // *TODO + if (!gAgent.isInGroup(mSessionID)) // ad-hoc channel + { + // Add the party to the list of people with which we've recently interacted. + for (/*people in the chat*/) + LLRecentPeople::instance().add(buddy_id); + } +#endif + } +} + +void LLVoiceChannelGroup::getChannelInfo() +{ + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + std::string url = region->getCapability("ChatSessionRequest"); + LLSD data; + data["method"] = "call"; + data["session-id"] = mSessionID; + LLHTTPClient::post(url, + data, + new LLVoiceCallCapResponder(mSessionID)); + } +} + +void LLVoiceChannelGroup::setChannelInfo( + const std::string& uri, + const std::string& credentials) +{ + setURI(uri); + + mCredentials = credentials; + + if (mState == STATE_NO_CHANNEL_INFO) + { + if(!mURI.empty() && !mCredentials.empty()) + { + setState(STATE_READY); + + // if we are supposed to be active, reconnect + // this will happen on initial connect, as we request credentials on first use + if (sCurrentVoiceChannel == this) + { + // just in case we got new channel info while active + // should move over to new channel + activate(); + } + } + else + { + //*TODO: notify user + llwarns << "Received invalid credentials for channel " << mSessionName << llendl; + deactivate(); + } + } + else if ( mIsRetrying ) + { + // we have the channel info, just need to use it now + LLVoiceClient::getInstance()->setNonSpatialChannel( + mURI, + mCredentials); + } +} + +void LLVoiceChannelGroup::handleStatusChange(EStatusType type) +{ + // status updates + switch(type) + { + case STATUS_JOINED: + mRetries = 3; + mIsRetrying = FALSE; + default: + break; + } + + LLVoiceChannel::handleStatusChange(type); +} + +void LLVoiceChannelGroup::handleError(EStatusType status) +{ + std::string notify; + switch(status) + { + case ERROR_CHANNEL_LOCKED: + case ERROR_CHANNEL_FULL: + notify = "VoiceChannelFull"; + break; + case ERROR_NOT_AVAILABLE: + //clear URI and credentials + //set the state to be no info + //and activate + if ( mRetries > 0 ) + { + mRetries--; + mIsRetrying = TRUE; + mIgnoreNextSessionLeave = TRUE; + + getChannelInfo(); + return; + } + else + { + notify = "VoiceChannelJoinFailed"; + mRetries = DEFAULT_RETRIES_COUNT; + mIsRetrying = FALSE; + } + + break; + + case ERROR_UNKNOWN: + default: + break; + } + + // notification + if (!notify.empty()) + { + LLNotificationPtr notification = LLNotifications::instance().add(notify, mNotifyArgs); + // echo to im window + gIMMgr->addMessage(mSessionID, LLUUID::null, SYSTEM_FROM, notification->getMessage()); + } + + LLVoiceChannel::handleError(status); +} + +void LLVoiceChannelGroup::setState(EState state) +{ + // HACK: Open/close the call window if needed. + toggleCallWindowIfNeeded(state); + + switch(state) + { + case STATE_RINGING: + if ( !mIsRetrying ) + { + gIMMgr->addSystemMessage(mSessionID, "ringing", mNotifyArgs); + } + + mState = state; + break; + default: + LLVoiceChannel::setState(state); + } +} + +// +// LLVoiceChannelProximal +// +LLVoiceChannelProximal::LLVoiceChannelProximal() : + LLVoiceChannel(LLUUID::null, LLStringUtil::null) +{ + activate(); +} + +BOOL LLVoiceChannelProximal::isActive() +{ + return callStarted() && LLVoiceClient::getInstance()->inProximalChannel(); +} + +void LLVoiceChannelProximal::activate() +{ + if (callStarted()) return; + + LLVoiceChannel::activate(); + + if (callStarted()) + { + // this implicitly puts you back in the spatial channel + LLVoiceClient::getInstance()->leaveNonSpatialChannel(); + } +} + +void LLVoiceChannelProximal::onChange(EStatusType type, const std::string &channelURI, bool proximal) +{ + if (!proximal) + { + return; + } + + if (type < BEGIN_ERROR_STATUS) + { + handleStatusChange(type); + } + else + { + handleError(type); + } +} + +void LLVoiceChannelProximal::handleStatusChange(EStatusType status) +{ + // status updates + switch(status) + { + case STATUS_LEFT_CHANNEL: + // do not notify user when leaving proximal channel + return; + case STATUS_VOICE_DISABLED: + gIMMgr->addSystemMessage(LLUUID::null, "unavailable", mNotifyArgs); + return; + default: + break; + } + LLVoiceChannel::handleStatusChange(status); +} + + +void LLVoiceChannelProximal::handleError(EStatusType status) +{ + std::string notify; + switch(status) + { + case ERROR_CHANNEL_LOCKED: + case ERROR_CHANNEL_FULL: + notify = "ProximalVoiceChannelFull"; + break; + default: + break; + } + + // notification + if (!notify.empty()) + { + LLNotifications::instance().add(notify, mNotifyArgs); + } + + LLVoiceChannel::handleError(status); +} + +void LLVoiceChannelProximal::deactivate() +{ + if (callStarted()) + { + setState(STATE_HUNG_UP); + } +} + + +// +// LLVoiceChannelP2P +// +LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const std::string& session_name, const LLUUID& other_user_id) : + LLVoiceChannelGroup(session_id, session_name), + mOtherUserID(other_user_id), + mReceivedCall(FALSE) +{ + // make sure URI reflects encoded version of other user's agent id + setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id)); +} + +void LLVoiceChannelP2P::handleStatusChange(EStatusType type) +{ + // status updates + switch(type) + { + case STATUS_LEFT_CHANNEL: + if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended) + { + if (mState == STATE_RINGING) + { + // other user declined call + LLNotifications::instance().add("P2PCallDeclined", mNotifyArgs); + } + else + { + // other user hung up + LLNotifications::instance().add("VoiceChannelDisconnectedP2P", mNotifyArgs); + } + deactivate(); + } + mIgnoreNextSessionLeave = FALSE; + return; + default: + break; + } + + LLVoiceChannel::handleStatusChange(type); +} + +void LLVoiceChannelP2P::handleError(EStatusType type) +{ + switch(type) + { + case ERROR_NOT_AVAILABLE: + LLNotifications::instance().add("P2PCallNoAnswer", mNotifyArgs); + break; + default: + break; + } + + LLVoiceChannel::handleError(type); +} + +void LLVoiceChannelP2P::activate() +{ + if (callStarted()) return; + + LLVoiceChannel::activate(); + + if (callStarted()) + { + // no session handle yet, we're starting the call + if (mSessionHandle.empty()) + { + mReceivedCall = FALSE; + LLVoiceClient::getInstance()->callUser(mOtherUserID); + } + // otherwise answering the call + else + { + LLVoiceClient::getInstance()->answerInvite(mSessionHandle); + + // using the session handle invalidates it. Clear it out here so we can't reuse it by accident. + mSessionHandle.clear(); + } + + // Add the party to the list of people with which we've recently interacted. + LLRecentPeople::instance().add(mOtherUserID); + } +} + +void LLVoiceChannelP2P::getChannelInfo() +{ + // pretend we have everything we need, since P2P doesn't use channel info + if (sCurrentVoiceChannel == this) + { + setState(STATE_CALL_STARTED); + } +} + +// receiving session from other user who initiated call +void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::string &inURI) +{ + BOOL needs_activate = FALSE; + if (callStarted()) + { + // defer to lower agent id when already active + if (mOtherUserID < gAgent.getID()) + { + // pretend we haven't started the call yet, so we can connect to this session instead + deactivate(); + needs_activate = TRUE; + } + else + { + // we are active and have priority, invite the other user again + // under the assumption they will join this new session + mSessionHandle.clear(); + LLVoiceClient::getInstance()->callUser(mOtherUserID); + return; + } + } + + mSessionHandle = handle; + + // The URI of a p2p session should always be the other end's SIP URI. + if(!inURI.empty()) + { + setURI(inURI); + } + else + { + setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID)); + } + + mReceivedCall = TRUE; + + if (needs_activate) + { + activate(); + } +} + +void LLVoiceChannelP2P::setState(EState state) +{ + // HACK: Open/close the call window if needed. + toggleCallWindowIfNeeded(state); + + // you only "answer" voice invites in p2p mode + // so provide a special purpose message here + if (mReceivedCall && state == STATE_RINGING) + { + gIMMgr->addSystemMessage(mSessionID, "answering", mNotifyArgs); + mState = state; + return; + } + LLVoiceChannel::setState(state); +} diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h new file mode 100644 index 0000000000..4a9100fba6 --- /dev/null +++ b/indra/newview/llvoicechannel.h @@ -0,0 +1,167 @@ +/** + * @file llvoicechannel.h + * @brief Voice channel related classes + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-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_VOICECHANNEL_H +#define LL_VOICECHANNEL_H + +#include "llvoiceclient.h" + +class LLPanel; + +class LLVoiceChannel : public LLVoiceClientStatusObserver +{ +public: + typedef enum e_voice_channel_state + { + STATE_NO_CHANNEL_INFO, + STATE_ERROR, + STATE_HUNG_UP, + STATE_READY, + STATE_CALL_STARTED, + STATE_RINGING, + STATE_CONNECTED + } EState; + + LLVoiceChannel(const LLUUID& session_id, const std::string& session_name); + virtual ~LLVoiceChannel(); + + /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); + + virtual void handleStatusChange(EStatusType status); + virtual void handleError(EStatusType status); + virtual void deactivate(); + virtual void activate(); + virtual void setChannelInfo( + const std::string& uri, + const std::string& credentials); + virtual void getChannelInfo(); + virtual BOOL isActive(); + virtual BOOL callStarted(); + const std::string& getSessionName() const { return mSessionName; } + + const LLUUID getSessionID() { return mSessionID; } + EState getState() { return mState; } + + void updateSessionID(const LLUUID& new_session_id); + const LLSD& getNotifyArgs() { return mNotifyArgs; } + + static LLVoiceChannel* getChannelByID(const LLUUID& session_id); + static LLVoiceChannel* getChannelByURI(std::string uri); + static LLVoiceChannel* getCurrentVoiceChannel() { return sCurrentVoiceChannel; } + static void initClass(); + + static void suspend(); + static void resume(); + +protected: + virtual void setState(EState state); + void toggleCallWindowIfNeeded(EState state); + void setURI(std::string uri); + + std::string mURI; + std::string mCredentials; + LLUUID mSessionID; + EState mState; + std::string mSessionName; + LLSD mNotifyArgs; + BOOL mIgnoreNextSessionLeave; + LLHandle mLoginNotificationHandle; + + typedef std::map voice_channel_map_t; + static voice_channel_map_t sVoiceChannelMap; + + typedef std::map voice_channel_map_uri_t; + static voice_channel_map_uri_t sVoiceChannelURIMap; + + static LLVoiceChannel* sCurrentVoiceChannel; + static LLVoiceChannel* sSuspendedVoiceChannel; + static BOOL sSuspended; +}; + +class LLVoiceChannelGroup : public LLVoiceChannel +{ +public: + LLVoiceChannelGroup(const LLUUID& session_id, const std::string& session_name); + + /*virtual*/ void handleStatusChange(EStatusType status); + /*virtual*/ void handleError(EStatusType status); + /*virtual*/ void activate(); + /*virtual*/ void deactivate(); + /*vritual*/ void setChannelInfo( + const std::string& uri, + const std::string& credentials); + /*virtual*/ void getChannelInfo(); + +protected: + virtual void setState(EState state); + +private: + U32 mRetries; + BOOL mIsRetrying; +}; + +class LLVoiceChannelProximal : public LLVoiceChannel, public LLSingleton +{ +public: + LLVoiceChannelProximal(); + + /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); + /*virtual*/ void handleStatusChange(EStatusType status); + /*virtual*/ void handleError(EStatusType status); + /*virtual*/ BOOL isActive(); + /*virtual*/ void activate(); + /*virtual*/ void deactivate(); + +}; + +class LLVoiceChannelP2P : public LLVoiceChannelGroup +{ +public: + LLVoiceChannelP2P(const LLUUID& session_id, const std::string& session_name, const LLUUID& other_user_id); + + /*virtual*/ void handleStatusChange(EStatusType status); + /*virtual*/ void handleError(EStatusType status); + /*virtual*/ void activate(); + /*virtual*/ void getChannelInfo(); + + void setSessionHandle(const std::string& handle, const std::string &inURI); + +protected: + virtual void setState(EState state); + +private: + std::string mSessionHandle; + LLUUID mOtherUserID; + BOOL mReceivedCall; +}; + +#endif // LL_VOICECHANNEL_H diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 02f63a848b..2834284a9b 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -57,13 +57,13 @@ #include "llagent.h" #include "llcachename.h" #include "llimview.h" // for LLIMMgr -#include "llimpanel.h" // for LLVoiceChannel #include "llparcel.h" #include "llviewerparcelmgr.h" #include "llfirstuse.h" #include "llviewerwindow.h" #include "llviewercamera.h" #include "llvoavatarself.h" +#include "llvoicechannel.h" #include "llfloaterfriends.h" //VIVOX, inorder to refresh communicate panel #include "llfloaterchat.h" // for LLFloaterChat::addChat() -- cgit v1.2.3 From 3b40f9052bdd22ca26610becaa8c37fba07cc1f2 Mon Sep 17 00:00:00 2001 From: Denis Serdjuk Date: Tue, 27 Oct 2009 13:49:06 +0200 Subject: fixed Bug EXT-1602 'Add new folder' and 'Add new landmark' has same icons that is deceitful New menubutton has been implemented according to Viewer 2.0 Design Specification:Places Task Panel. It generates a menu for AddLandmark and AddFolder options --HG-- branch : product-engine --- indra/newview/llpanellandmarks.cpp | 95 ++++++++++++---------- indra/newview/llpanellandmarks.h | 5 +- .../skins/default/xui/en/menu_place_add_button.xml | 27 ++++++ .../skins/default/xui/en/panel_landmarks.xml | 14 +--- 4 files changed, 81 insertions(+), 60 deletions(-) create mode 100644 indra/newview/skins/default/xui/en/menu_place_add_button.xml (limited to 'indra') diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 83fb147a49..4650c0eab4 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -56,7 +56,7 @@ //static LLRegisterPanelClassWrapper t_landmarks("panel_landmarks"); static const std::string OPTIONS_BUTTON_NAME = "options_gear_btn"; -static const std::string ADD_LANDMARK_BUTTON_NAME = "add_landmark_btn"; +static const std::string ADD_BUTTON_NAME = "add_btn"; static const std::string ADD_FOLDER_BUTTON_NAME = "add_folder_btn"; static const std::string TRASH_BUTTON_NAME = "trash_btn"; @@ -300,6 +300,8 @@ void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data) panel_pick, panel_places,params)); panel_pick->setSaveCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this, panel_pick, panel_places,params)); + panel_pick->setCancelCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this, + panel_pick, panel_places,params)); } } } @@ -433,11 +435,11 @@ void LLLandmarksPanel::initListCommandsHandlers() mListCommands = getChild("bottom_panel"); mListCommands->childSetAction(OPTIONS_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onActionsButtonClick, this)); - mListCommands->childSetAction(ADD_LANDMARK_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onAddLandmarkButtonClick, this)); - mListCommands->childSetAction(ADD_FOLDER_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onAddFolderButtonClick, this)); mListCommands->childSetAction(TRASH_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onTrashButtonClick, this)); + mListCommands->getChild(ADD_BUTTON_NAME)->setHeldDownCallback(boost::bind(&LLLandmarksPanel::onAddButtonHeldDown, this)); + static const LLSD add_landmark_command("add_landmark"); + mListCommands->childSetAction(ADD_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onAddAction, this, add_landmark_command)); - LLDragAndDropButton* trash_btn = mListCommands->getChild(TRASH_BUTTON_NAME); trash_btn->setDragAndDropHandler(boost::bind(&LLLandmarksPanel::handleDragAndDropToTrash, this , _4 // BOOL drop @@ -453,6 +455,7 @@ void LLLandmarksPanel::initListCommandsHandlers() mEnableCallbackRegistrar.add("Places.LandmarksGear.Enable", boost::bind(&LLLandmarksPanel::isActionEnabled, this, _2)); mGearLandmarkMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_places_gear_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mGearFolderMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_places_gear_folder.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); } @@ -488,52 +491,26 @@ void LLLandmarksPanel::onActionsButtonClick() mGearFolderMenu->getChild("collapse")->setVisible(cur_item->isOpen()); menu = mGearFolderMenu; } - if(menu) - { - menu->buildDrawLabels(); - menu->updateParent(LLMenuGL::sMenuContainer); - LLView* actions_btn = getChild(OPTIONS_BUTTON_NAME); - S32 menu_x, menu_y; - actions_btn->localPointToOtherView(0,actions_btn->getRect().getHeight(),&menu_x,&menu_y, this); - menu_y += menu->getRect().getHeight(); - LLMenuGL::showPopup(this, menu, menu_x,menu_y); - } + showActionMenu(menu,OPTIONS_BUTTON_NAME); } -void LLLandmarksPanel::onAddLandmarkButtonClick() const +void LLLandmarksPanel::onAddButtonHeldDown() { - if(LLLandmarkActions::landmarkAlreadyExists()) - { - std::string location; - LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_FULL); - llwarns<<" Landmark already exists at location: "<< location<showPanel("panel_places", LLSD().insert("type", "create_landmark")); + showActionMenu(mMenuAdd,ADD_BUTTON_NAME); } -void LLLandmarksPanel::onAddFolderButtonClick() const +void LLLandmarksPanel::showActionMenu(LLMenuGL* menu, std::string spawning_view_name) { - LLFolderViewItem* item = getCurSelectedItem(); - if(item && mCurrentSelectedList == mLandmarksInventoryPanel) + if (menu) { - LLFolderViewEventListener* folder_bridge = NULL; - if(item-> getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) - { - // for a landmark get parent folder bridge - folder_bridge = item->getParentFolder()->getListener(); - } - else if (item-> getListener()->getInventoryType() == LLInventoryType::IT_CATEGORY) - { - // for a folder get its own bridge - folder_bridge = item->getListener(); - } - - menu_create_inventory_item(mCurrentSelectedList->getRootFolder() - , dynamic_cast(folder_bridge) - , LLSD("category") - , gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK) - ); + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); + LLView* spawning_view = getChild (spawning_view_name); + S32 menu_x, menu_y; + //show menu in co-ordinates of panel + spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this); + menu_y += menu->getRect().getHeight(); + LLMenuGL::showPopup(this, menu, menu_x, menu_y); } } @@ -547,11 +524,39 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const std::string command_name = userdata.asString(); if("add_landmark" == command_name) { - onAddLandmarkButtonClick(); + if(LLLandmarkActions::landmarkAlreadyExists()) + { + std::string location; + LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_FULL); + llwarns<<" Landmark already exists at location: "<< location<showPanel("panel_places", LLSD().insert("type", "create_landmark")); } else if ("category" == command_name) { - onAddFolderButtonClick(); + LLFolderViewItem* item = getCurSelectedItem(); + if (item && mCurrentSelectedList == mLandmarksInventoryPanel) + { + LLFolderViewEventListener* folder_bridge = NULL; + if (item-> getListener()->getInventoryType() + == LLInventoryType::IT_LANDMARK) + { + // for a landmark get parent folder bridge + folder_bridge = item->getParentFolder()->getListener(); + } + else if (item-> getListener()->getInventoryType() + == LLInventoryType::IT_CATEGORY) + { + // for a folder get its own bridge + folder_bridge = item->getListener(); + } + + menu_create_inventory_item(mCurrentSelectedList->getRootFolder(), + dynamic_cast (folder_bridge), LLSD( + "category"), gInventory.findCategoryUUIDForType( + LLAssetType::AT_LANDMARK)); + } } } diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 47c9f7647c..958850134d 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -90,8 +90,8 @@ private: void initListCommandsHandlers(); void updateListCommands(); void onActionsButtonClick(); - void onAddLandmarkButtonClick() const; - void onAddFolderButtonClick() const; + void showActionMenu(LLMenuGL* menu, std::string spawning_view_name); + void onAddButtonHeldDown(); void onTrashButtonClick() const; void onAddAction(const LLSD& command_name) const; void onClipboardAction(const LLSD& command_name) const; @@ -121,6 +121,7 @@ private: LLInventorySubTreePanel* mLibraryInventoryPanel; LLMenuGL* mGearLandmarkMenu; LLMenuGL* mGearFolderMenu; + LLMenuGL* mMenuAdd; LLInventorySubTreePanel* mCurrentSelectedList; LLPanel* mListCommands; diff --git a/indra/newview/skins/default/xui/en/menu_place_add_button.xml b/indra/newview/skins/default/xui/en/menu_place_add_button.xml new file mode 100644 index 0000000000..e3a39a1242 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_place_add_button.xml @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml index c33f68eaf7..5293043ba7 100644 --- a/indra/newview/skins/default/xui/en/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml @@ -114,22 +114,10 @@ image_disabled="AddItem_Disabled" layout="topleft" left_pad="5" - name="add_landmark_btn" + name="add_btn" picture_style="true" tool_tip="Add new landmark" width="18" /> - - -- cgit v1.2.3 From 6a9de7c8ee7d3be289fbd42741a327d42b6ea9eb Mon Sep 17 00:00:00 2001 From: Leyla Farazha Date: Wed, 28 Oct 2009 18:00:39 -0700 Subject: merge fix --- indra/llui/lltabcontainer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 08f16a12d4..cde4c75518 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -155,7 +155,7 @@ LLTabContainer::LLTabContainer(const LLTabContainer::Params& p) mTotalTabWidth(0), mTabPosition(p.tab_position), mFontHalign(p.font_halign), - mFont(p.font.isProvided() ? p.font() : (mIsVertical ? LLFontGL::getFontSansSerif() : LLFontGL::getFontSansSerifSmall())) + mFont(p.font.isProvided() ? p.font() : (mIsVertical ? LLFontGL::getFontSansSerif() : LLFontGL::getFontSansSerifSmall())), mFirstTabParams(p.first_tab), mMiddleTabParams(p.middle_tab), mLastTabParams(p.last_tab) -- cgit v1.2.3 From 67879996cab7f5fbe2538db6e656a32a7bac2b20 Mon Sep 17 00:00:00 2001 From: Rick Pasetto Date: Wed, 28 Oct 2009 18:53:43 -0700 Subject: rename llpanelmediahud to llpanelprimmediacontrols --- indra/newview/CMakeLists.txt | 86 +- indra/newview/llpanelprimmediacontrols.cpp | 1095 ++++++++++++++++++++ indra/newview/llpanelprimmediacontrols.h | 148 +++ indra/newview/llviewermediafocus.cpp | 2 +- .../default/xui/en/panel_prim_media_controls.xml | 594 +++++++++++ 5 files changed, 1881 insertions(+), 44 deletions(-) create mode 100644 indra/newview/llpanelprimmediacontrols.cpp create mode 100644 indra/newview/llpanelprimmediacontrols.h create mode 100644 indra/newview/skins/default/xui/en/panel_prim_media_controls.xml (limited to 'indra') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5210ff66ed..a7681e4a1d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -63,13 +63,13 @@ include_directories( ) set(viewer_SOURCE_FILES - llaccordionctrltab.cpp llaccordionctrl.cpp + llaccordionctrltab.cpp llagent.cpp - llagentlistener.cpp llagentaccess.cpp llagentdata.cpp llagentlanguage.cpp + llagentlistener.cpp llagentpicksinfo.cpp llagentpilot.cpp llagentui.cpp @@ -78,8 +78,8 @@ set(viewer_SOURCE_FILES llappearancemgr.cpp llappviewer.cpp llappviewerlistener.cpp - llassetuploadresponders.cpp llassetuploadqueue.cpp + llassetuploadresponders.cpp llaudiosourcevo.cpp llavataractions.cpp llavatariconctrl.cpp @@ -95,8 +95,8 @@ set(viewer_SOURCE_FILES llcaphttpsender.cpp llchannelmanager.cpp llchatbar.cpp - llchatitemscontainerctrl.cpp llchathistory.cpp + llchatitemscontainerctrl.cpp llchatmsgbox.cpp llchiclet.cpp llclassifiedinfo.cpp @@ -116,10 +116,10 @@ set(viewer_SOURCE_FILES lldirpicker.cpp lldndbutton.cpp lldrawable.cpp + lldrawpool.cpp lldrawpoolalpha.cpp lldrawpoolavatar.cpp lldrawpoolbump.cpp - lldrawpool.cpp lldrawpoolground.cpp lldrawpoolsimple.cpp lldrawpoolsky.cpp @@ -151,8 +151,8 @@ set(viewer_SOURCE_FILES llfloaterbuildoptions.cpp llfloaterbulkpermission.cpp llfloaterbump.cpp - llfloaterbuycontents.cpp llfloaterbuy.cpp + llfloaterbuycontents.cpp llfloaterbuycurrency.cpp llfloaterbuyland.cpp llfloatercall.cpp @@ -163,8 +163,8 @@ set(viewer_SOURCE_FILES llfloatercustomize.cpp llfloaterdaycycle.cpp llfloaterenvsettings.cpp - llfloaterfriends.cpp llfloaterfonttest.cpp + llfloaterfriends.cpp llfloatergesture.cpp llfloatergodtools.cpp llfloatergroupinvite.cpp @@ -172,8 +172,6 @@ set(viewer_SOURCE_FILES llfloaterhandler.cpp llfloaterhardwaresettings.cpp llfloaterhelpbrowser.cpp - llfloatermediabrowser.cpp - llfloatermediasettings.cpp llfloaterhud.cpp llfloaterimagepreview.cpp llfloaterinspect.cpp @@ -183,6 +181,8 @@ set(viewer_SOURCE_FILES llfloaterland.cpp llfloaterlandholdings.cpp llfloatermap.cpp + llfloatermediabrowser.cpp + llfloatermediasettings.cpp llfloatermemleak.cpp llfloaternamedesc.cpp llfloaternotificationsconsole.cpp @@ -227,8 +227,8 @@ set(viewer_SOURCE_FILES llgroupmgr.cpp llgroupnotify.cpp llhomelocationresponder.cpp - llhudeffectbeam.cpp llhudeffect.cpp + llhudeffectbeam.cpp llhudeffectlookat.cpp llhudeffectpointat.cpp llhudeffecttrail.cpp @@ -238,11 +238,11 @@ set(viewer_SOURCE_FILES llhudrender.cpp llhudtext.cpp llhudview.cpp + llimcontrolpanel.cpp llimfloater.cpp llimhandler.cpp llimpanel.cpp llimview.cpp - llimcontrolpanel.cpp llinspect.cpp llinspectavatar.cpp llinspectgroup.cpp @@ -260,7 +260,6 @@ set(viewer_SOURCE_FILES lllocaltextureobject.cpp lllocationhistory.cpp lllocationinputctrl.cpp - llurllineeditorctrl.cpp lllogchat.cpp llloginhandler.cpp lllogininstance.cpp @@ -312,8 +311,8 @@ set(viewer_SOURCE_FILES llpanelgrouplandmoney.cpp llpanelgroupnotices.cpp llpanelgrouproles.cpp - llpanelinventory.cpp llpanelimcontrolpanel.cpp + llpanelinventory.cpp llpanelland.cpp llpanellandaudio.cpp llpanellandmarks.cpp @@ -322,11 +321,10 @@ set(viewer_SOURCE_FILES llpanellookinfo.cpp llpanellooks.cpp llpanelmedia.cpp - llpanelmediahud.cpp - llpanelmeprofile.cpp llpanelmediasettingsgeneral.cpp - llpanelmediasettingssecurity.cpp llpanelmediasettingspermissions.cpp + llpanelmediasettingssecurity.cpp + llpanelmeprofile.cpp llpanelobject.cpp llpanelpeople.cpp llpanelpeoplemenus.cpp @@ -335,11 +333,12 @@ set(viewer_SOURCE_FILES llpanelpicks.cpp llpanelplace.cpp llpanelplaceinfo.cpp - llpanelshower.cpp llpanelplaces.cpp llpanelplacestab.cpp + llpanelprimmediacontrols.cpp llpanelprofile.cpp llpanelprofileview.cpp + llpanelshower.cpp llpanelteleporthistory.cpp llpanelvolume.cpp llparcelselection.cpp @@ -348,8 +347,8 @@ set(viewer_SOURCE_FILES llplacesinventorybridge.cpp llpolymesh.cpp llpolymorph.cpp - llpreviewanim.cpp llpreview.cpp + llpreviewanim.cpp llpreviewgesture.cpp llpreviewnotecard.cpp llpreviewscript.cpp @@ -398,10 +397,10 @@ set(viewer_SOURCE_FILES lltoastimpanel.cpp lltoastnotifypanel.cpp lltoastpanel.cpp + lltool.cpp lltoolbar.cpp lltoolbrush.cpp lltoolcomp.cpp - lltool.cpp lltooldraganddrop.cpp lltoolface.cpp lltoolfocus.cpp @@ -425,6 +424,7 @@ set(viewer_SOURCE_FILES llurl.cpp llurldispatcher.cpp llurlhistory.cpp + llurllineeditorctrl.cpp llurlsimstring.cpp llurlwhitelist.cpp llvectorperfoptions.cpp @@ -441,18 +441,18 @@ set(viewer_SOURCE_FILES llviewerhelp.cpp llviewerhelputil.cpp llviewerinventory.cpp - llviewerjointattachment.cpp llviewerjoint.cpp + llviewerjointattachment.cpp llviewerjointmesh.cpp - llviewerjointmesh_sse2.cpp llviewerjointmesh_sse.cpp + llviewerjointmesh_sse2.cpp llviewerjointmesh_vec.cpp llviewerjoystick.cpp llviewerkeyboard.cpp llviewerlayer.cpp llviewermedia.cpp - llviewermediafocus.cpp llviewermedia_streamingaudio.cpp + llviewermediafocus.cpp llviewermenu.cpp llviewermenufile.cpp llviewermessage.cpp @@ -487,9 +487,9 @@ set(viewer_SOURCE_FILES llvoground.cpp llvoicechannel.cpp llvoiceclient.cpp + llvoicecontrolpanel.cpp llvoiceremotectrl.cpp llvoicevisualizer.cpp - llvoicecontrolpanel.cpp llvoinventorylistener.cpp llvopartgroup.cpp llvosky.cpp @@ -540,25 +540,25 @@ endif (LINUX) set(viewer_HEADER_FILES CMakeLists.txt ViewerInstall.cmake - llaccordionctrltab.h llaccordionctrl.h + llaccordionctrltab.h llagent.h - llagentlistener.h llagentaccess.h llagentdata.h llagentlanguage.h + llagentlistener.h llagentpicksinfo.h llagentpilot.h llagentui.h llagentwearables.h llanimstatelabels.h llappearance.h + llappearancemgr.h llappviewer.h llappviewerlistener.h - llassetuploadresponders.h llassetuploadqueue.h + llassetuploadresponders.h llaudiosourcevo.h - llappearancemgr.h llavataractions.h llavatariconctrl.h llavatarlist.h @@ -574,8 +574,8 @@ set(viewer_HEADER_FILES llcaphttpsender.h llchannelmanager.h llchatbar.h - llchatitemscontainerctrl.h llchathistory.h + llchatitemscontainerctrl.h llchatmsgbox.h llchiclet.h llclassifiedinfo.h @@ -652,8 +652,6 @@ set(viewer_HEADER_FILES llfloaterhandler.h llfloaterhardwaresettings.h llfloaterhelpbrowser.h - llfloatermediabrowser.h - llfloatermediasettings.h llfloaterhud.h llfloaterimagepreview.h llfloaterinspect.h @@ -663,16 +661,18 @@ set(viewer_HEADER_FILES llfloaterland.h llfloaterlandholdings.h llfloatermap.h + llfloatermediabrowser.h + llfloatermediasettings.h llfloatermemleak.h llfloaternamedesc.h llfloaternotificationsconsole.h llfloateropenobject.h llfloaterparcel.h llfloaterpay.h + llfloaterperms.h llfloaterpostcard.h llfloaterpostprocess.h llfloaterpreference.h - llfloaterperms.h llfloaterproperties.h llfloaterregioninfo.h llfloaterreporter.h @@ -718,12 +718,12 @@ set(viewer_HEADER_FILES llhudrender.h llhudtext.h llhudview.h + llimcontrolpanel.h llimfloater.h llimpanel.h llimview.h - llimcontrolpanel.h - llinspectavatar.h llinspect.h + llinspectavatar.h llinspectgroup.h llinspectobject.h llinventorybridge.h @@ -740,7 +740,6 @@ set(viewer_HEADER_FILES lllocaltextureobject.h lllocationhistory.h lllocationinputctrl.h - llurllineeditorctrl.h lllogchat.h llloginhandler.h lllogininstance.h @@ -749,6 +748,7 @@ set(viewer_HEADER_FILES llmanipscale.h llmaniptranslate.h llmapresponders.h + llmediactrl.h llmediadataclient.h llmediaremotectrl.h llmemoryview.h @@ -788,8 +788,8 @@ set(viewer_HEADER_FILES llpanelgrouplandmoney.h llpanelgroupnotices.h llpanelgrouproles.h - llpanelinventory.h llpanelimcontrolpanel.h + llpanelinventory.h llpanelland.h llpanellandaudio.h llpanellandmarks.h @@ -798,11 +798,10 @@ set(viewer_HEADER_FILES llpanellookinfo.h llpanellooks.h llpanelmedia.h - llpanelmediahud.h - llpanelmeprofile.h llpanelmediasettingsgeneral.h - llpanelmediasettingssecurity.h llpanelmediasettingspermissions.h + llpanelmediasettingssecurity.h + llpanelmeprofile.h llpanelobject.h llpanelpeople.h llpanelpeoplemenus.h @@ -811,11 +810,12 @@ set(viewer_HEADER_FILES llpanelpicks.h llpanelplace.h llpanelplaceinfo.h - llpanelshower.h llpanelplaces.h llpanelplacestab.h + llpanelprimmediacontrols.h llpanelprofile.h llpanelprofileview.h + llpanelshower.h llpanelteleporthistory.h llpanelvolume.h llparcelselection.h @@ -838,9 +838,9 @@ set(viewer_HEADER_FILES llremoteparcelrequest.h llresourcedata.h llrootview.h + llsavedsettingsglue.h llscreenchannel.h llscrollingpanelparam.h - llsavedsettingsglue.h llsearchcombobox.h llsearchhistory.h llselectmgr.h @@ -905,6 +905,7 @@ set(viewer_HEADER_FILES llurl.h llurldispatcher.h llurlhistory.h + llurllineeditorctrl.h llurlsimstring.h llurlwhitelist.h llvectorperfoptions.h @@ -928,8 +929,8 @@ set(viewer_HEADER_FILES llviewerkeyboard.h llviewerlayer.h llviewermedia.h - llviewermediaobserver.h llviewermediafocus.h + llviewermediaobserver.h llviewermenu.h llviewermenufile.h llviewermessage.h @@ -965,9 +966,9 @@ set(viewer_HEADER_FILES llvoground.h llvoicechannel.h llvoiceclient.h + llvoicecontrolpanel.h llvoiceremotectrl.h llvoicevisualizer.h - llvoicecontrolpanel.h llvoinventorylistener.h llvopartgroup.h llvosky.h @@ -985,7 +986,6 @@ set(viewer_HEADER_FILES llwearabledictionary.h llwearablelist.h llweb.h - llmediactrl.h llwind.h llwindebug.h llwlanimator.h diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp new file mode 100644 index 0000000000..8a202dabef --- /dev/null +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -0,0 +1,1095 @@ +/** + * @file llpanelmediahud.cpp + * @brief media controls popup panel + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +//LLPanelMediaControls +#include "llagent.h" +#include "llparcel.h" +#include "llpanel.h" +#include "llselectmgr.h" +#include "llmediaentry.h" +#include "llrender.h" +#include "lldrawable.h" +#include "llviewerwindow.h" +#include "lluictrlfactory.h" +#include "llbutton.h" +#include "llface.h" +#include "llcombobox.h" +#include "llslider.h" +#include "llhudview.h" +#include "lliconctrl.h" +#include "lltoolpie.h" +#include "llviewercamera.h" +#include "llviewerobjectlist.h" +#include "llpanelprimmediacontrols.h" +#include "llpluginclassmedia.h" +#include "llprogressbar.h" +#include "llviewercontrol.h" +#include "llviewerparcelmgr.h" +#include "llviewermedia.h" +#include "llviewermediafocus.h" +#include "llvovolume.h" +#include "llweb.h" +#include "llwindow.h" + +glh::matrix4f glh_get_current_modelview(); +glh::matrix4f glh_get_current_projection(); + +const F32 ZOOM_NEAR_PADDING = 1.0f; +const F32 ZOOM_MEDIUM_PADDING = 1.15f; +const F32 ZOOM_FAR_PADDING = 1.5f; + +// Warning: make sure these two match! +const LLPanelMediaControls::EZoomLevel LLPanelMediaControls::kZoomLevels[] = { ZOOM_NONE, ZOOM_MEDIUM }; +const int LLPanelMediaControls::kNumZoomLevels = 2; + +// +// LLPanelMediaControls +// + +LLPanelMediaControls::LLPanelMediaControls() : + mAlpha(1.f), + mCurrentURL(""), + mPreviousURL(""), + mPauseFadeout(false), + mUpdateSlider(true), + mClearFaceOnFade(false), + mCurrentRate(0.0), + mMovieDuration(0.0), + mUpdatePercent(0) +{ + mCommitCallbackRegistrar.add("MediaCtrl.Close", boost::bind(&LLPanelMediaControls::onClickClose, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Back", boost::bind(&LLPanelMediaControls::onClickBack, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Forward", boost::bind(&LLPanelMediaControls::onClickForward, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Home", boost::bind(&LLPanelMediaControls::onClickHome, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Stop", boost::bind(&LLPanelMediaControls::onClickStop, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Reload", boost::bind(&LLPanelMediaControls::onClickReload, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Play", boost::bind(&LLPanelMediaControls::onClickPlay, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Pause", boost::bind(&LLPanelMediaControls::onClickPause, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Open", boost::bind(&LLPanelMediaControls::onClickOpen, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Zoom", boost::bind(&LLPanelMediaControls::onClickZoom, this)); + mCommitCallbackRegistrar.add("MediaCtrl.CommitURL", boost::bind(&LLPanelMediaControls::onCommitURL, this)); + mCommitCallbackRegistrar.add("MediaCtrl.JumpProgress", boost::bind(&LLPanelMediaControls::onCommitSlider, this)); + mCommitCallbackRegistrar.add("MediaCtrl.CommitVolumeUp", boost::bind(&LLPanelMediaControls::onCommitVolumeUp, this)); + mCommitCallbackRegistrar.add("MediaCtrl.CommitVolumeDown", boost::bind(&LLPanelMediaControls::onCommitVolumeDown, this)); + mCommitCallbackRegistrar.add("MediaCtrl.ToggleMute", boost::bind(&LLPanelMediaControls::onToggleMute, this)); + + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_hud.xml"); + mInactivityTimer.reset(); + mFadeTimer.stop(); + mCurrentZoom = ZOOM_NONE; + mScrollState = SCROLL_NONE; + + mPanelHandle.bind(this); +} +LLPanelMediaControls::~LLPanelMediaControls() +{ +} + +BOOL LLPanelMediaControls::postBuild() +{ + LLButton* scroll_up_ctrl = getChild("scrollup"); + scroll_up_ctrl->setClickedCallback(onScrollUp, this); + scroll_up_ctrl->setHeldDownCallback(onScrollUpHeld, this); + scroll_up_ctrl->setMouseUpCallback(onScrollStop, this); + LLButton* scroll_left_ctrl = getChild("scrollleft"); + scroll_left_ctrl->setClickedCallback(onScrollLeft, this); + scroll_left_ctrl->setHeldDownCallback(onScrollLeftHeld, this); + scroll_left_ctrl->setMouseUpCallback(onScrollStop, this); + LLButton* scroll_right_ctrl = getChild("scrollright"); + scroll_right_ctrl->setClickedCallback(onScrollRight, this); + scroll_right_ctrl->setHeldDownCallback(onScrollLeftHeld, this); + scroll_right_ctrl->setMouseUpCallback(onScrollStop, this); + LLButton* scroll_down_ctrl = getChild("scrolldown"); + scroll_down_ctrl->setClickedCallback(onScrollDown, this); + scroll_down_ctrl->setHeldDownCallback(onScrollDownHeld, this); + scroll_down_ctrl->setMouseUpCallback(onScrollStop, this); + + LLUICtrl* media_address = getChild("media_address"); + media_address->setFocusReceivedCallback(boost::bind(&LLPanelMediaControls::onInputURL, _1, this )); + mInactiveTimeout = gSavedSettings.getF32("MediaControlTimeout"); + mControlFadeTime = gSavedSettings.getF32("MediaControlFadeTime"); + + mCurrentZoom = ZOOM_NONE; + // clicks on HUD buttons do not remove keyboard focus from media + setIsChrome(TRUE); + return TRUE; +} + +void LLPanelMediaControls::setMediaFace(LLPointer objectp, S32 face, viewer_media_t media_impl, LLVector3 pick_normal) +{ + if (media_impl.notNull() && objectp.notNull()) + { + mTargetImplID = media_impl->getMediaTextureID(); + mTargetObjectID = objectp->getID(); + mTargetObjectFace = face; + mTargetObjectNormal = pick_normal; + mClearFaceOnFade = false; + } + else + { + // This happens on a timer now. +// mTargetImplID = LLUUID::null; +// mTargetObjectID = LLUUID::null; +// mTargetObjectFace = 0; + mClearFaceOnFade = true; + } + + updateShape(); +} + +void LLPanelMediaControls::focusOnTarget() +{ + // Sets the media focus to the current target of the LLPanelMediaControls. + // This is how we transition from hover to focus when the user clicks on a control. + LLViewerMediaImpl* media_impl = getTargetMediaImpl(); + if(media_impl) + { + if(!media_impl->hasFocus()) + { + // The current target doesn't have media focus -- focus on it. + LLViewerObject* objectp = getTargetObject(); + LLViewerMediaFocus::getInstance()->setFocusFace(objectp, mTargetObjectFace, media_impl, mTargetObjectNormal); + } + } +} + +LLViewerMediaImpl* LLPanelMediaControls::getTargetMediaImpl() +{ + return LLViewerMedia::getMediaImplFromTextureID(mTargetImplID); +} + +LLViewerObject* LLPanelMediaControls::getTargetObject() +{ + return gObjectList.findObject(mTargetObjectID); +} + +LLPluginClassMedia* LLPanelMediaControls::getTargetMediaPlugin() +{ + LLViewerMediaImpl* impl = getTargetMediaImpl(); + if(impl && impl->hasMedia()) + { + return impl->getMediaPlugin(); + } + + return NULL; +} + +void LLPanelMediaControls::updateShape() +{ + const S32 MIN_HUD_WIDTH=400; + const S32 MIN_HUD_HEIGHT=120; + + LLViewerMediaImpl* media_impl = getTargetMediaImpl(); + LLViewerObject* objectp = getTargetObject(); + + if(!media_impl) + { + setVisible(FALSE); + return; + } + + LLPluginClassMedia* media_plugin = NULL; + if(media_impl->hasMedia()) + { + media_plugin = media_impl->getMediaPlugin(); + } + + LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + + bool can_navigate = parcel->getMediaAllowNavigate(); + bool enabled = false; + bool has_focus = media_impl->hasFocus(); + setVisible(enabled); + + if (objectp) + { + bool mini_controls = false; + LLMediaEntry *media_data = objectp->getTE(mTargetObjectFace)->getMediaData(); + if (media_data && NULL != dynamic_cast(objectp)) + { + // Don't show the media HUD if we do not have permissions + enabled = dynamic_cast(objectp)->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL); + mini_controls = (LLMediaEntry::MINI == media_data->getControls()); + } + + // + // Set the state of the buttons + // + LLUICtrl* back_ctrl = getChild("back"); + LLUICtrl* fwd_ctrl = getChild("fwd"); + LLUICtrl* reload_ctrl = getChild("reload"); + LLUICtrl* play_ctrl = getChild("play"); + LLUICtrl* pause_ctrl = getChild("pause"); + LLUICtrl* stop_ctrl = getChild("stop"); + LLUICtrl* media_stop_ctrl = getChild("media_stop"); + LLUICtrl* home_ctrl = getChild("home"); + LLUICtrl* close_ctrl = getChild("close"); + LLUICtrl* open_ctrl = getChild("new_window"); + LLUICtrl* zoom_ctrl = getChild("zoom_frame"); + LLPanel* media_loading_panel = getChild("media_progress_indicator"); + LLUICtrl* media_address_ctrl = getChild("media_address"); + LLUICtrl* media_play_slider_ctrl = getChild("media_play_position"); + LLUICtrl* volume_ctrl = getChild("media_volume"); + LLButton* volume_btn = getChild("media_volume_button"); + LLUICtrl* volume_up_ctrl = getChild("volume_up"); + LLUICtrl* volume_down_ctrl = getChild("volume_down"); + LLIconCtrl* whitelist_icon = getChild("media_whitelist_flag"); + LLIconCtrl* secure_lock_icon = getChild("media_secure_lock_flag"); + + LLUICtrl* media_panel_scroll = getChild("media_panel_scroll"); + LLUICtrl* scroll_up_ctrl = getChild("scrollup"); + LLUICtrl* scroll_left_ctrl = getChild("scrollleft"); + LLUICtrl* scroll_right_ctrl = getChild("scrollright"); + LLUICtrl* scroll_down_ctrl = getChild("scrolldown"); + + // XXX RSP: TODO: FIXME: clean this up so that it is clearer what mode we are in, + // and that only the proper controls get made visible/enabled according to that mode. + back_ctrl->setVisible(has_focus); + fwd_ctrl->setVisible(has_focus); + reload_ctrl->setVisible(has_focus); + stop_ctrl->setVisible(false); + home_ctrl->setVisible(has_focus); + close_ctrl->setVisible(has_focus); + open_ctrl->setVisible(true); + media_address_ctrl->setVisible(has_focus && !mini_controls); + media_play_slider_ctrl->setVisible(has_focus && !mini_controls); + volume_ctrl->setVisible(false); + volume_up_ctrl->setVisible(false); + volume_down_ctrl->setVisible(false); + + whitelist_icon->setVisible(!mini_controls && (media_data)?media_data->getWhiteListEnable():false); + // Disable zoom if HUD + zoom_ctrl->setEnabled(!objectp->isHUDAttachment()); + secure_lock_icon->setVisible(false); + mCurrentURL = media_impl->getMediaURL(); + + back_ctrl->setEnabled((media_impl != NULL) && media_impl->canNavigateBack() && can_navigate); + fwd_ctrl->setEnabled((media_impl != NULL) && media_impl->canNavigateForward() && can_navigate); + stop_ctrl->setEnabled(has_focus && can_navigate); + home_ctrl->setEnabled(has_focus && can_navigate); + LLPluginClassMediaOwner::EMediaStatus result = ((media_impl != NULL) && media_impl->hasMedia()) ? media_plugin->getStatus() : LLPluginClassMediaOwner::MEDIA_NONE; + + if(media_plugin && media_plugin->pluginSupportsMediaTime()) + { + reload_ctrl->setEnabled(FALSE); + reload_ctrl->setVisible(FALSE); + media_stop_ctrl->setVisible(has_focus); + home_ctrl->setVisible(FALSE); + back_ctrl->setEnabled(has_focus); + fwd_ctrl->setEnabled(has_focus); + media_address_ctrl->setVisible(false); + media_address_ctrl->setEnabled(false); + media_play_slider_ctrl->setVisible(!mini_controls); + media_play_slider_ctrl->setEnabled(!mini_controls); + + volume_ctrl->setVisible(has_focus); + volume_up_ctrl->setVisible(has_focus); + volume_down_ctrl->setVisible(has_focus); + volume_ctrl->setEnabled(has_focus); + + whitelist_icon->setVisible(false); + secure_lock_icon->setVisible(false); + scroll_up_ctrl->setVisible(false); + scroll_left_ctrl->setVisible(false); + scroll_right_ctrl->setVisible(false); + scroll_down_ctrl->setVisible(false); + media_panel_scroll->setVisible(false); + + F32 volume = media_impl->getVolume(); + // movie's url changed + if(mCurrentURL!=mPreviousURL) + { + mMovieDuration = media_plugin->getDuration(); + mPreviousURL = mCurrentURL; + } + + if(mMovieDuration == 0) + { + mMovieDuration = media_plugin->getDuration(); + media_play_slider_ctrl->setValue(0); + media_play_slider_ctrl->setEnabled(false); + } + // TODO: What if it's not fully loaded + + if(mUpdateSlider && mMovieDuration!= 0) + { + F64 current_time = media_plugin->getCurrentTime(); + F32 percent = current_time / mMovieDuration; + media_play_slider_ctrl->setValue(percent); + media_play_slider_ctrl->setEnabled(true); + } + + // video vloume + if(volume <= 0.0) + { + volume_up_ctrl->setEnabled(TRUE); + volume_down_ctrl->setEnabled(FALSE); + media_impl->setVolume(0.0); + volume_btn->setToggleState(true); + } + else if (volume >= 1.0) + { + volume_up_ctrl->setEnabled(FALSE); + volume_down_ctrl->setEnabled(TRUE); + media_impl->setVolume(1.0); + volume_btn->setToggleState(false); + } + else + { + volume_up_ctrl->setEnabled(TRUE); + volume_down_ctrl->setEnabled(TRUE); + } + + switch(result) + { + case LLPluginClassMediaOwner::MEDIA_PLAYING: + play_ctrl->setEnabled(FALSE); + play_ctrl->setVisible(FALSE); + pause_ctrl->setEnabled(TRUE); + pause_ctrl->setVisible(has_focus); + media_stop_ctrl->setEnabled(TRUE); + + break; + case LLPluginClassMediaOwner::MEDIA_PAUSED: + default: + pause_ctrl->setEnabled(FALSE); + pause_ctrl->setVisible(FALSE); + play_ctrl->setEnabled(TRUE); + play_ctrl->setVisible(has_focus); + media_stop_ctrl->setEnabled(FALSE); + break; + } + } + else // web based + { + if(media_plugin) + { + mCurrentURL = media_plugin->getLocation(); + } + else + { + mCurrentURL.clear(); + } + + play_ctrl->setVisible(FALSE); + pause_ctrl->setVisible(FALSE); + media_stop_ctrl->setVisible(FALSE); + media_address_ctrl->setVisible(has_focus && !mini_controls); + media_address_ctrl->setEnabled(has_focus && !mini_controls); + media_play_slider_ctrl->setVisible(FALSE); + media_play_slider_ctrl->setEnabled(FALSE); + + volume_ctrl->setVisible(FALSE); + volume_up_ctrl->setVisible(FALSE); + volume_down_ctrl->setVisible(FALSE); + volume_ctrl->setEnabled(FALSE); + volume_up_ctrl->setEnabled(FALSE); + volume_down_ctrl->setEnabled(FALSE); + + scroll_up_ctrl->setVisible(has_focus); + scroll_left_ctrl->setVisible(has_focus); + scroll_right_ctrl->setVisible(has_focus); + scroll_down_ctrl->setVisible(has_focus); + media_panel_scroll->setVisible(has_focus); + // TODO: get the secure lock bool from media plug in + std::string prefix = std::string("https://"); + std::string test_prefix = mCurrentURL.substr(0, prefix.length()); + LLStringUtil::toLower(test_prefix); + if(test_prefix == prefix) + { + secure_lock_icon->setVisible(has_focus); + } + + if(mCurrentURL!=mPreviousURL) + { + setCurrentURL(); + mPreviousURL = mCurrentURL; + } + + if(result == LLPluginClassMediaOwner::MEDIA_LOADING) + { + reload_ctrl->setEnabled(FALSE); + reload_ctrl->setVisible(FALSE); + stop_ctrl->setEnabled(TRUE); + stop_ctrl->setVisible(has_focus); + } + else + { + reload_ctrl->setEnabled(TRUE); + reload_ctrl->setVisible(has_focus); + stop_ctrl->setEnabled(FALSE); + stop_ctrl->setVisible(FALSE); + } + } + + + if(media_plugin) + { + // + // Handle progress bar + // + mUpdatePercent = media_plugin->getProgressPercent(); + if(mUpdatePercent<100.0f) + { + media_loading_panel->setVisible(true); + getChild("media_progress_bar")->setPercent(mUpdatePercent); + gFocusMgr.setTopCtrl(media_loading_panel); + } + else + { + media_loading_panel->setVisible(false); + gFocusMgr.setTopCtrl(NULL); + } + } + + if(media_plugin) + { + // + // Handle Scrolling + // + switch (mScrollState) + { + case SCROLL_UP: + media_plugin->scrollEvent(0, -1, MASK_NONE); + break; + case SCROLL_DOWN: + media_plugin->scrollEvent(0, 1, MASK_NONE); + break; + case SCROLL_LEFT: + media_impl->handleKeyHere(KEY_LEFT, MASK_NONE); + break; + case SCROLL_RIGHT: + media_impl->handleKeyHere(KEY_RIGHT, MASK_NONE); + break; + case SCROLL_NONE: + default: + break; + } + } + + setVisible(enabled); + + // + // Calculate position and shape of the controls + // + glh::matrix4f mat = glh_get_current_projection()*glh_get_current_modelview(); + std::vector::iterator vert_it; + std::vector::iterator vert_end; + std::vector vect_face; + + LLVolume* volume = objectp->getVolume(); + + if (volume) + { + const LLVolumeFace& vf = volume->getVolumeFace(mTargetObjectFace); + + const LLVector3* ext = vf.mExtents; + + LLVector3 center = (ext[0]+ext[1])*0.5f; + LLVector3 size = (ext[1]-ext[0])*0.5f; + LLVector3 vert[] = + { + center + size.scaledVec(LLVector3(1,1,1)), + center + size.scaledVec(LLVector3(-1,1,1)), + center + size.scaledVec(LLVector3(1,-1,1)), + center + size.scaledVec(LLVector3(-1,-1,1)), + center + size.scaledVec(LLVector3(1,1,-1)), + center + size.scaledVec(LLVector3(-1,1,-1)), + center + size.scaledVec(LLVector3(1,-1,-1)), + center + size.scaledVec(LLVector3(-1,-1,-1)), + }; + + LLVOVolume* vo = (LLVOVolume*) objectp; + + for (U32 i = 0; i < 8; i++) + { + vect_face.push_back(vo->volumePositionToAgent(vert[i])); + } + } + vert_it = vect_face.begin(); + vert_end = vect_face.end(); + + LLVector3 min = LLVector3(1,1,1); + LLVector3 max = LLVector3(-1,-1,-1); + for(; vert_it != vert_end; ++vert_it) + { + // project silhouette vertices into screen space + glh::vec3f screen_vert = glh::vec3f(vert_it->mV); + mat.mult_matrix_vec(screen_vert); + + // add to screenspace bounding box + update_min_max(min, max, LLVector3(screen_vert.v)); + } + + LLCoordGL screen_min; + screen_min.mX = llround((F32)gViewerWindow->getWorldViewWidth() * (min.mV[VX] + 1.f) * 0.5f); + screen_min.mY = llround((F32)gViewerWindow->getWorldViewHeight() * (min.mV[VY] + 1.f) * 0.5f); + + LLCoordGL screen_max; + screen_max.mX = llround((F32)gViewerWindow->getWorldViewWidth() * (max.mV[VX] + 1.f) * 0.5f); + screen_max.mY = llround((F32)gViewerWindow->getWorldViewHeight() * (max.mV[VY] + 1.f) * 0.5f); + + // grow panel so that screenspace bounding box fits inside "media_region" element of HUD + LLRect media_hud_rect; + getParent()->screenRectToLocal(LLRect(screen_min.mX, screen_max.mY, screen_max.mX, screen_min.mY), &media_hud_rect); + LLView* media_region = getChild("media_region"); + media_hud_rect.mLeft -= media_region->getRect().mLeft; + media_hud_rect.mBottom -= media_region->getRect().mBottom; + media_hud_rect.mTop += getRect().getHeight() - media_region->getRect().mTop; + media_hud_rect.mRight += getRect().getWidth() - media_region->getRect().mRight; + + LLRect old_hud_rect = media_hud_rect; + // keep all parts of HUD on-screen + media_hud_rect.intersectWith(getParent()->getLocalRect()); + + // clamp to minimum size, keeping centered + media_hud_rect.setCenterAndSize(media_hud_rect.getCenterX(), media_hud_rect.getCenterY(), + llmax(MIN_HUD_WIDTH, media_hud_rect.getWidth()), llmax(MIN_HUD_HEIGHT, media_hud_rect.getHeight())); + + setShape(media_hud_rect, true); + + // Test mouse position to see if the cursor is stationary + LLCoordWindow cursor_pos_window; + getWindow()->getCursorPosition(&cursor_pos_window); + + // If last pos is not equal to current pos, the mouse has moved + // We need to reset the timer, and make sure the panel is visible + if(cursor_pos_window.mX != mLastCursorPos.mX || + cursor_pos_window.mY != mLastCursorPos.mY || + mScrollState != SCROLL_NONE) + { + mInactivityTimer.start(); + mLastCursorPos = cursor_pos_window; + } + + if(isMouseOver()) + { + // Never fade the controls if the mouse is over them. + mFadeTimer.stop(); + } + else if(!mClearFaceOnFade && (mInactivityTimer.getElapsedTimeF32() < mInactiveTimeout)) + { + // Mouse is over the object, but has not been stationary for long enough to fade the UI + mFadeTimer.stop(); + } + else if(! mFadeTimer.getStarted() ) + { + // we need to start fading the UI (and we have not already started) + mFadeTimer.reset(); + mFadeTimer.start(); + } + else + { + // I don't think this is correct anymore. This is done in draw() after the fade has completed. +// setVisible(FALSE); + } + } +} + +/*virtual*/ +void LLPanelMediaControls::draw() +{ + F32 alpha = 1.f; + if(mFadeTimer.getStarted()) + { + F32 time = mFadeTimer.getElapsedTimeF32(); + alpha = llmax(lerp(1.0, 0.0, time / mControlFadeTime), 0.0f); + + if(mFadeTimer.getElapsedTimeF32() >= mControlFadeTime) + { + setVisible(FALSE); + if(mClearFaceOnFade) + { + mClearFaceOnFade = false; + mTargetImplID = LLUUID::null; + mTargetObjectID = LLUUID::null; + mTargetObjectFace = 0; + } + } + } + + { + LLViewDrawContext context(alpha); + LLPanel::draw(); + } +} + +BOOL LLPanelMediaControls::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ + mInactivityTimer.start(); + return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks); +} + +BOOL LLPanelMediaControls::handleMouseDown(S32 x, S32 y, MASK mask) +{ + mInactivityTimer.start(); + return LLPanel::handleMouseDown(x, y, mask); +} + +BOOL LLPanelMediaControls::handleMouseUp(S32 x, S32 y, MASK mask) +{ + mInactivityTimer.start(); + return LLPanel::handleMouseUp(x, y, mask); +} + +BOOL LLPanelMediaControls::handleKeyHere( KEY key, MASK mask ) +{ + mInactivityTimer.start(); + return LLPanel::handleKeyHere(key, mask); +} + +bool LLPanelMediaControls::isMouseOver() +{ + bool result = false; + + if( getVisible() ) + { + LLCoordWindow cursor_pos_window; + LLCoordScreen cursor_pos_screen; + LLCoordGL cursor_pos_gl; + S32 x, y; + getWindow()->getCursorPosition(&cursor_pos_window); + getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl); + + LLPanel* controls_panel = NULL; + controls_panel = getChild("media_hover_controls"); + if(controls_panel && !controls_panel->getVisible()) + { + // The hover controls aren't visible -- use the focused controls instead. + controls_panel = getChild("media_focused_controls"); + } + + if(controls_panel && controls_panel->getVisible()) + { + controls_panel->screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &x, &y); + + LLView *hit_child = controls_panel->childFromPoint(x, y); + if(hit_child) + { + // This was useful for debugging both coordinate translation and view hieararchy problems... +// llinfos << "mouse coords: " << x << ", " << y << " hit child " << hit_child->getName() << llendl; + result = true; + } + } + } + + return result; +} + + +void LLPanelMediaControls::onClickClose() +{ + close(); +} + +void LLPanelMediaControls::close() +{ + LLViewerMediaFocus::getInstance()->clearFocus(); + resetZoomLevel(); + setVisible(FALSE); +} + + +void LLPanelMediaControls::onClickBack() +{ + focusOnTarget(); + + LLViewerMediaImpl* impl =getTargetMediaImpl(); + + if (impl) + { + impl->navigateBack(); + } +} + +void LLPanelMediaControls::onClickForward() +{ + focusOnTarget(); + + LLViewerMediaImpl* impl = getTargetMediaImpl(); + + if (impl) + { + impl->navigateForward(); + } +} + +void LLPanelMediaControls::onClickHome() +{ + focusOnTarget(); + + LLViewerMediaImpl* impl = getTargetMediaImpl(); + + if(impl) + { + impl->navigateHome(); + } +} + +void LLPanelMediaControls::onClickOpen() +{ + LLViewerMediaImpl* impl =getTargetMediaImpl(); + if(impl) + { + if(impl->getMediaPlugin()) + { + if(impl->getMediaPlugin()->getLocation().empty()) + { + LLWeb::loadURL(impl->getMediaURL()); + } + else + { + LLWeb::loadURL( impl->getMediaPlugin()->getLocation()); + } + } + } +} + +void LLPanelMediaControls::onClickReload() +{ + focusOnTarget(); + + //LLViewerMedia::navigateHome(); + LLViewerMediaImpl* impl = getTargetMediaImpl(); + + if(impl) + { + impl->navigateReload(); + } +} + +void LLPanelMediaControls::onClickPlay() +{ + focusOnTarget(); + + LLViewerMediaImpl* impl = getTargetMediaImpl(); + + if(impl) + { + impl->play(); + } +} + +void LLPanelMediaControls::onClickPause() +{ + focusOnTarget(); + + LLViewerMediaImpl* impl = getTargetMediaImpl(); + + if(impl) + { + impl->pause(); + } +} + +void LLPanelMediaControls::onClickStop() +{ + focusOnTarget(); + + LLViewerMediaImpl* impl = getTargetMediaImpl(); + + if(impl) + { + impl->stop(); + } +} + +void LLPanelMediaControls::onClickZoom() +{ + focusOnTarget(); + + nextZoomLevel(); +} +void LLPanelMediaControls::nextZoomLevel() +{ + int index = 0; + while (index < kNumZoomLevels) + { + if (kZoomLevels[index] == mCurrentZoom) + { + index++; + break; + } + index++; + } + mCurrentZoom = kZoomLevels[index % kNumZoomLevels]; + updateZoom(); +} + +void LLPanelMediaControls::resetZoomLevel() +{ + if(mCurrentZoom != ZOOM_NONE) + { + mCurrentZoom = ZOOM_NONE; + updateZoom(); + } +} + +void LLPanelMediaControls::updateZoom() +{ + F32 zoom_padding = 0.0f; + switch (mCurrentZoom) + { + case ZOOM_NONE: + { + gAgent.setFocusOnAvatar(TRUE, ANIMATE); + break; + } + case ZOOM_FAR: + { + zoom_padding = ZOOM_FAR_PADDING; + break; + } + case ZOOM_MEDIUM: + { + zoom_padding = ZOOM_MEDIUM_PADDING; + break; + } + case ZOOM_NEAR: + { + zoom_padding = ZOOM_NEAR_PADDING; + break; + } + default: + { + gAgent.setFocusOnAvatar(TRUE, ANIMATE); + break; + } + } + + if (zoom_padding > 0.0f) + LLViewerMediaFocus::setCameraZoom(getTargetObject(), mTargetObjectNormal, zoom_padding); +} +void LLPanelMediaControls::onScrollUp(void* user_data) +{ + LLPanelMediaControls* this_panel = static_cast (user_data); + this_panel->focusOnTarget(); + + LLPluginClassMedia* plugin = this_panel->getTargetMediaPlugin(); + + if(plugin) + { + plugin->scrollEvent(0, -1, MASK_NONE); + } +} +void LLPanelMediaControls::onScrollUpHeld(void* user_data) +{ + LLPanelMediaControls* this_panel = static_cast (user_data); + this_panel->mScrollState = SCROLL_UP; +} +void LLPanelMediaControls::onScrollRight(void* user_data) +{ + LLPanelMediaControls* this_panel = static_cast (user_data); + this_panel->focusOnTarget(); + + LLViewerMediaImpl* impl = this_panel->getTargetMediaImpl(); + + if(impl) + { + impl->handleKeyHere(KEY_RIGHT, MASK_NONE); + } +} +void LLPanelMediaControls::onScrollRightHeld(void* user_data) +{ + LLPanelMediaControls* this_panel = static_cast (user_data); + this_panel->mScrollState = SCROLL_RIGHT; +} + +void LLPanelMediaControls::onScrollLeft(void* user_data) +{ + LLPanelMediaControls* this_panel = static_cast (user_data); + this_panel->focusOnTarget(); + + LLViewerMediaImpl* impl = this_panel->getTargetMediaImpl(); + + if(impl) + { + impl->handleKeyHere(KEY_LEFT, MASK_NONE); + } +} +void LLPanelMediaControls::onScrollLeftHeld(void* user_data) +{ + LLPanelMediaControls* this_panel = static_cast (user_data); + this_panel->mScrollState = SCROLL_LEFT; +} + +void LLPanelMediaControls::onScrollDown(void* user_data) +{ + LLPanelMediaControls* this_panel = static_cast (user_data); + this_panel->focusOnTarget(); + + LLPluginClassMedia* plugin = this_panel->getTargetMediaPlugin(); + + if(plugin) + { + plugin->scrollEvent(0, 1, MASK_NONE); + } +} +void LLPanelMediaControls::onScrollDownHeld(void* user_data) +{ + LLPanelMediaControls* this_panel = static_cast (user_data); + this_panel->mScrollState = SCROLL_DOWN; +} + +void LLPanelMediaControls::onScrollStop(void* user_data) +{ + LLPanelMediaControls* this_panel = static_cast (user_data); + this_panel->mScrollState = SCROLL_NONE; +} + +void LLPanelMediaControls::onCommitURL() +{ + focusOnTarget(); + + LLUICtrl *media_address_ctrl = getChild("media_address_url"); + std::string url = media_address_ctrl->getValue().asString(); + if(getTargetMediaImpl() && !url.empty()) + { + getTargetMediaImpl()->navigateTo( url, "", true); + + // Make sure keyboard focus is set to the media focus object. + gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance()); + + } + mPauseFadeout = false; + mFadeTimer.start(); +} + + +void LLPanelMediaControls::onInputURL(LLFocusableElement* caller, void *userdata) +{ + + LLPanelMediaControls* this_panel = static_cast (userdata); + this_panel->focusOnTarget(); + + this_panel->mPauseFadeout = true; + this_panel->mFadeTimer.stop(); + this_panel->mFadeTimer.reset(); + +} + +void LLPanelMediaControls::setCurrentURL() +{ + LLComboBox* media_address_combo = getChild("media_address_combo"); + // redirects will navigate momentarily to about:blank, don't add to history + if (media_address_combo && mCurrentURL != "about:blank") + { + media_address_combo->remove(mCurrentURL); + media_address_combo->add(mCurrentURL, ADD_SORTED); + media_address_combo->selectByValue(mCurrentURL); + } +} + +void LLPanelMediaControls::onCommitSlider() +{ + focusOnTarget(); + + LLSlider* media_play_slider_ctrl = getChild("media_play_slider"); + LLViewerMediaImpl* media_impl = getTargetMediaImpl(); + if (media_impl) + { + // get slider value + F64 slider_value = media_play_slider_ctrl->getValue().asReal(); + if(slider_value <= 0.0) + { + media_impl->stop(); + } + else + { + media_impl->seek(slider_value*mMovieDuration); + //mUpdateSlider= false; + } + } +} + +void LLPanelMediaControls::onCommitVolumeUp() +{ + focusOnTarget(); + + LLViewerMediaImpl* media_impl = getTargetMediaImpl(); + if (media_impl) + { + F32 volume = media_impl->getVolume(); + + volume += 0.1f; + if(volume >= 1.0f) + { + volume = 1.0f; + } + + media_impl->setVolume(volume); + getChild("media_volume")->setToggleState(false); + } +} + +void LLPanelMediaControls::onCommitVolumeDown() +{ + focusOnTarget(); + + LLViewerMediaImpl* media_impl = getTargetMediaImpl(); + if (media_impl) + { + F32 volume = media_impl->getVolume(); + + volume -= 0.1f; + if(volume <= 0.0f) + { + volume = 0.0f; + } + + media_impl->setVolume(volume); + getChild("media_volume")->setToggleState(false); + } +} + + +void LLPanelMediaControls::onToggleMute() +{ + focusOnTarget(); + + LLViewerMediaImpl* media_impl = getTargetMediaImpl(); + if (media_impl) + { + F32 volume = media_impl->getVolume(); + + if(volume > 0.0) + { + media_impl->setVolume(0.0); + } + else + { + media_impl->setVolume(0.5); + } + } +} + diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h new file mode 100644 index 0000000000..b605c08a55 --- /dev/null +++ b/indra/newview/llpanelprimmediacontrols.h @@ -0,0 +1,148 @@ +/** + * @file llpanelmediahud.h + * @brief Pop-up media controls panel + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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_PANELMEDIAHUD_H +#define LL_PANELMEDIAHUD_H + +#include "llpanel.h" +#include "llviewermedia.h" + +class LLCoordWindow; +class LLViewerMediaImpl; + +class LLPanelMediaControls : public LLPanel +{ +public: + LLPanelMediaControls(); + virtual ~LLPanelMediaControls(); + /*virtual*/ BOOL postBuild(); + virtual void draw(); + virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + virtual BOOL handleKeyHere(KEY key, MASK mask); + + void updateShape(); + bool isMouseOver(); + void nextZoomLevel(); + void resetZoomLevel(); + void close(); + + LLHandle getHandle() const { return mPanelHandle; } + void setMediaFace(LLPointer objectp, S32 face, viewer_media_t media_impl, LLVector3 pick_normal = LLVector3::zero); + + + enum EZoomLevel + { + ZOOM_NONE = 0, + ZOOM_FAR, + ZOOM_MEDIUM, + ZOOM_NEAR + }; + static const EZoomLevel kZoomLevels[]; + static const int kNumZoomLevels; + + enum EScrollDir + { + SCROLL_UP = 0, + SCROLL_DOWN, + SCROLL_LEFT, + SCROLL_RIGHT, + SCROLL_NONE + }; + +private: + void onClickClose(); + void onClickBack(); + void onClickForward(); + void onClickHome(); + void onClickOpen(); + void onClickReload(); + void onClickPlay(); + void onClickPause(); + void onClickStop(); + void onClickZoom(); + void onCommitURL(); + + void updateZoom(); + void setCurrentURL(); + void onCommitSlider(); + + void onCommitVolumeUp(); + void onCommitVolumeDown(); + void onToggleMute(); + + static void onScrollUp(void* user_data); + static void onScrollUpHeld(void* user_data); + static void onScrollLeft(void* user_data); + static void onScrollLeftHeld(void* user_data); + static void onScrollRight(void* user_data); + static void onScrollRightHeld(void* user_data); + static void onScrollDown(void* user_data); + static void onScrollDownHeld(void* user_data); + static void onScrollStop(void* user_data); + + static void onInputURL(LLFocusableElement* caller, void *userdata); + static bool hasControlsPermission(LLViewerObject *obj, const LLMediaEntry *media_entry); + + void focusOnTarget(); + + LLViewerMediaImpl* getTargetMediaImpl(); + LLViewerObject* getTargetObject(); + LLPluginClassMedia* getTargetMediaPlugin(); + bool mPauseFadeout; + bool mUpdateSlider; + bool mClearFaceOnFade; + + LLMatrix4 mLastCameraMat; + EZoomLevel mCurrentZoom; + EScrollDir mScrollState; + LLCoordWindow mLastCursorPos; + LLFrameTimer mInactivityTimer; + LLFrameTimer mFadeTimer; + F32 mInactiveTimeout; + F32 mControlFadeTime; + LLRootHandle mPanelHandle; + F32 mAlpha; + std::string mCurrentURL; + std::string mPreviousURL; + F64 mCurrentRate; + F64 mMovieDuration; + int mUpdatePercent; + + LLUUID mTargetObjectID; + S32 mTargetObjectFace; + LLUUID mTargetImplID; + LLVector3 mTargetObjectNormal; +}; + +#endif // LL_PANELMEDIAHUD_H diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index 174dcb3410..cb5637a5bc 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -35,7 +35,7 @@ //LLViewerMediaFocus #include "llviewerobjectlist.h" -#include "llpanelmediahud.h" +#include "llpanelprimmediacontrols.h" #include "llpluginclassmedia.h" #include "llagent.h" #include "lltoolpie.h" diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml new file mode 100644 index 0000000000..b21fbc1795 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml @@ -0,0 +1,594 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 64c2cb6ba1c089c15df6c8ef5ec5313ed5f1897f Mon Sep 17 00:00:00 2001 From: Rick Pasetto Date: Wed, 28 Oct 2009 19:20:30 -0700 Subject: Completion of rename of llpanelmediahud to llpanelprimmediacontrols --- indra/newview/llpanelprimmediacontrols.cpp | 178 ++++++++++++++--------------- indra/newview/llpanelprimmediacontrols.h | 18 +-- indra/newview/llviewermediafocus.cpp | 24 ++-- indra/newview/llviewermediafocus.h | 4 +- 4 files changed, 112 insertions(+), 112 deletions(-) (limited to 'indra') diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 8a202dabef..ca7ebb1ad8 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -1,5 +1,5 @@ /** - * @file llpanelmediahud.cpp + * @file llpanelprimmediacontrols.cpp * @brief media controls popup panel * * $LicenseInfo:firstyear=2003&license=viewergpl$ @@ -31,7 +31,7 @@ #include "llviewerprecompiledheaders.h" -//LLPanelMediaControls +//LLPanelPrimMediaControls #include "llagent.h" #include "llparcel.h" #include "llpanel.h" @@ -69,14 +69,14 @@ const F32 ZOOM_MEDIUM_PADDING = 1.15f; const F32 ZOOM_FAR_PADDING = 1.5f; // Warning: make sure these two match! -const LLPanelMediaControls::EZoomLevel LLPanelMediaControls::kZoomLevels[] = { ZOOM_NONE, ZOOM_MEDIUM }; -const int LLPanelMediaControls::kNumZoomLevels = 2; +const LLPanelPrimMediaControls::EZoomLevel LLPanelPrimMediaControls::kZoomLevels[] = { ZOOM_NONE, ZOOM_MEDIUM }; +const int LLPanelPrimMediaControls::kNumZoomLevels = 2; // -// LLPanelMediaControls +// LLPanelPrimMediaControls // -LLPanelMediaControls::LLPanelMediaControls() : +LLPanelPrimMediaControls::LLPanelPrimMediaControls() : mAlpha(1.f), mCurrentURL(""), mPreviousURL(""), @@ -87,23 +87,23 @@ LLPanelMediaControls::LLPanelMediaControls() : mMovieDuration(0.0), mUpdatePercent(0) { - mCommitCallbackRegistrar.add("MediaCtrl.Close", boost::bind(&LLPanelMediaControls::onClickClose, this)); - mCommitCallbackRegistrar.add("MediaCtrl.Back", boost::bind(&LLPanelMediaControls::onClickBack, this)); - mCommitCallbackRegistrar.add("MediaCtrl.Forward", boost::bind(&LLPanelMediaControls::onClickForward, this)); - mCommitCallbackRegistrar.add("MediaCtrl.Home", boost::bind(&LLPanelMediaControls::onClickHome, this)); - mCommitCallbackRegistrar.add("MediaCtrl.Stop", boost::bind(&LLPanelMediaControls::onClickStop, this)); - mCommitCallbackRegistrar.add("MediaCtrl.Reload", boost::bind(&LLPanelMediaControls::onClickReload, this)); - mCommitCallbackRegistrar.add("MediaCtrl.Play", boost::bind(&LLPanelMediaControls::onClickPlay, this)); - mCommitCallbackRegistrar.add("MediaCtrl.Pause", boost::bind(&LLPanelMediaControls::onClickPause, this)); - mCommitCallbackRegistrar.add("MediaCtrl.Open", boost::bind(&LLPanelMediaControls::onClickOpen, this)); - mCommitCallbackRegistrar.add("MediaCtrl.Zoom", boost::bind(&LLPanelMediaControls::onClickZoom, this)); - mCommitCallbackRegistrar.add("MediaCtrl.CommitURL", boost::bind(&LLPanelMediaControls::onCommitURL, this)); - mCommitCallbackRegistrar.add("MediaCtrl.JumpProgress", boost::bind(&LLPanelMediaControls::onCommitSlider, this)); - mCommitCallbackRegistrar.add("MediaCtrl.CommitVolumeUp", boost::bind(&LLPanelMediaControls::onCommitVolumeUp, this)); - mCommitCallbackRegistrar.add("MediaCtrl.CommitVolumeDown", boost::bind(&LLPanelMediaControls::onCommitVolumeDown, this)); - mCommitCallbackRegistrar.add("MediaCtrl.ToggleMute", boost::bind(&LLPanelMediaControls::onToggleMute, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Close", boost::bind(&LLPanelPrimMediaControls::onClickClose, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Back", boost::bind(&LLPanelPrimMediaControls::onClickBack, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Forward", boost::bind(&LLPanelPrimMediaControls::onClickForward, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Home", boost::bind(&LLPanelPrimMediaControls::onClickHome, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Stop", boost::bind(&LLPanelPrimMediaControls::onClickStop, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Reload", boost::bind(&LLPanelPrimMediaControls::onClickReload, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Play", boost::bind(&LLPanelPrimMediaControls::onClickPlay, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Pause", boost::bind(&LLPanelPrimMediaControls::onClickPause, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Open", boost::bind(&LLPanelPrimMediaControls::onClickOpen, this)); + mCommitCallbackRegistrar.add("MediaCtrl.Zoom", boost::bind(&LLPanelPrimMediaControls::onClickZoom, this)); + mCommitCallbackRegistrar.add("MediaCtrl.CommitURL", boost::bind(&LLPanelPrimMediaControls::onCommitURL, this)); + mCommitCallbackRegistrar.add("MediaCtrl.JumpProgress", boost::bind(&LLPanelPrimMediaControls::onCommitSlider, this)); + mCommitCallbackRegistrar.add("MediaCtrl.CommitVolumeUp", boost::bind(&LLPanelPrimMediaControls::onCommitVolumeUp, this)); + mCommitCallbackRegistrar.add("MediaCtrl.CommitVolumeDown", boost::bind(&LLPanelPrimMediaControls::onCommitVolumeDown, this)); + mCommitCallbackRegistrar.add("MediaCtrl.ToggleMute", boost::bind(&LLPanelPrimMediaControls::onToggleMute, this)); - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_hud.xml"); + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_prim_media_controls.xml"); mInactivityTimer.reset(); mFadeTimer.stop(); mCurrentZoom = ZOOM_NONE; @@ -111,11 +111,11 @@ LLPanelMediaControls::LLPanelMediaControls() : mPanelHandle.bind(this); } -LLPanelMediaControls::~LLPanelMediaControls() +LLPanelPrimMediaControls::~LLPanelPrimMediaControls() { } -BOOL LLPanelMediaControls::postBuild() +BOOL LLPanelPrimMediaControls::postBuild() { LLButton* scroll_up_ctrl = getChild("scrollup"); scroll_up_ctrl->setClickedCallback(onScrollUp, this); @@ -135,7 +135,7 @@ BOOL LLPanelMediaControls::postBuild() scroll_down_ctrl->setMouseUpCallback(onScrollStop, this); LLUICtrl* media_address = getChild("media_address"); - media_address->setFocusReceivedCallback(boost::bind(&LLPanelMediaControls::onInputURL, _1, this )); + media_address->setFocusReceivedCallback(boost::bind(&LLPanelPrimMediaControls::onInputURL, _1, this )); mInactiveTimeout = gSavedSettings.getF32("MediaControlTimeout"); mControlFadeTime = gSavedSettings.getF32("MediaControlFadeTime"); @@ -145,7 +145,7 @@ BOOL LLPanelMediaControls::postBuild() return TRUE; } -void LLPanelMediaControls::setMediaFace(LLPointer objectp, S32 face, viewer_media_t media_impl, LLVector3 pick_normal) +void LLPanelPrimMediaControls::setMediaFace(LLPointer objectp, S32 face, viewer_media_t media_impl, LLVector3 pick_normal) { if (media_impl.notNull() && objectp.notNull()) { @@ -167,9 +167,9 @@ void LLPanelMediaControls::setMediaFace(LLPointer objectp, S32 f updateShape(); } -void LLPanelMediaControls::focusOnTarget() +void LLPanelPrimMediaControls::focusOnTarget() { - // Sets the media focus to the current target of the LLPanelMediaControls. + // Sets the media focus to the current target of the LLPanelPrimMediaControls. // This is how we transition from hover to focus when the user clicks on a control. LLViewerMediaImpl* media_impl = getTargetMediaImpl(); if(media_impl) @@ -183,17 +183,17 @@ void LLPanelMediaControls::focusOnTarget() } } -LLViewerMediaImpl* LLPanelMediaControls::getTargetMediaImpl() +LLViewerMediaImpl* LLPanelPrimMediaControls::getTargetMediaImpl() { return LLViewerMedia::getMediaImplFromTextureID(mTargetImplID); } -LLViewerObject* LLPanelMediaControls::getTargetObject() +LLViewerObject* LLPanelPrimMediaControls::getTargetObject() { return gObjectList.findObject(mTargetObjectID); } -LLPluginClassMedia* LLPanelMediaControls::getTargetMediaPlugin() +LLPluginClassMedia* LLPanelPrimMediaControls::getTargetMediaPlugin() { LLViewerMediaImpl* impl = getTargetMediaImpl(); if(impl && impl->hasMedia()) @@ -204,7 +204,7 @@ LLPluginClassMedia* LLPanelMediaControls::getTargetMediaPlugin() return NULL; } -void LLPanelMediaControls::updateShape() +void LLPanelPrimMediaControls::updateShape() { const S32 MIN_HUD_WIDTH=400; const S32 MIN_HUD_HEIGHT=120; @@ -560,23 +560,23 @@ void LLPanelMediaControls::updateShape() screen_max.mY = llround((F32)gViewerWindow->getWorldViewHeight() * (max.mV[VY] + 1.f) * 0.5f); // grow panel so that screenspace bounding box fits inside "media_region" element of HUD - LLRect media_hud_rect; - getParent()->screenRectToLocal(LLRect(screen_min.mX, screen_max.mY, screen_max.mX, screen_min.mY), &media_hud_rect); + LLRect media_controls_rect; + getParent()->screenRectToLocal(LLRect(screen_min.mX, screen_max.mY, screen_max.mX, screen_min.mY), &media_controls_rect); LLView* media_region = getChild("media_region"); - media_hud_rect.mLeft -= media_region->getRect().mLeft; - media_hud_rect.mBottom -= media_region->getRect().mBottom; - media_hud_rect.mTop += getRect().getHeight() - media_region->getRect().mTop; - media_hud_rect.mRight += getRect().getWidth() - media_region->getRect().mRight; + media_controls_rect.mLeft -= media_region->getRect().mLeft; + media_controls_rect.mBottom -= media_region->getRect().mBottom; + media_controls_rect.mTop += getRect().getHeight() - media_region->getRect().mTop; + media_controls_rect.mRight += getRect().getWidth() - media_region->getRect().mRight; - LLRect old_hud_rect = media_hud_rect; + LLRect old_hud_rect = media_controls_rect; // keep all parts of HUD on-screen - media_hud_rect.intersectWith(getParent()->getLocalRect()); + media_controls_rect.intersectWith(getParent()->getLocalRect()); // clamp to minimum size, keeping centered - media_hud_rect.setCenterAndSize(media_hud_rect.getCenterX(), media_hud_rect.getCenterY(), - llmax(MIN_HUD_WIDTH, media_hud_rect.getWidth()), llmax(MIN_HUD_HEIGHT, media_hud_rect.getHeight())); + media_controls_rect.setCenterAndSize(media_controls_rect.getCenterX(), media_controls_rect.getCenterY(), + llmax(MIN_HUD_WIDTH, media_controls_rect.getWidth()), llmax(MIN_HUD_HEIGHT, media_controls_rect.getHeight())); - setShape(media_hud_rect, true); + setShape(media_controls_rect, true); // Test mouse position to see if the cursor is stationary LLCoordWindow cursor_pos_window; @@ -617,7 +617,7 @@ void LLPanelMediaControls::updateShape() } /*virtual*/ -void LLPanelMediaControls::draw() +void LLPanelPrimMediaControls::draw() { F32 alpha = 1.f; if(mFadeTimer.getStarted()) @@ -644,31 +644,31 @@ void LLPanelMediaControls::draw() } } -BOOL LLPanelMediaControls::handleScrollWheel(S32 x, S32 y, S32 clicks) +BOOL LLPanelPrimMediaControls::handleScrollWheel(S32 x, S32 y, S32 clicks) { mInactivityTimer.start(); return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks); } -BOOL LLPanelMediaControls::handleMouseDown(S32 x, S32 y, MASK mask) +BOOL LLPanelPrimMediaControls::handleMouseDown(S32 x, S32 y, MASK mask) { mInactivityTimer.start(); return LLPanel::handleMouseDown(x, y, mask); } -BOOL LLPanelMediaControls::handleMouseUp(S32 x, S32 y, MASK mask) +BOOL LLPanelPrimMediaControls::handleMouseUp(S32 x, S32 y, MASK mask) { mInactivityTimer.start(); return LLPanel::handleMouseUp(x, y, mask); } -BOOL LLPanelMediaControls::handleKeyHere( KEY key, MASK mask ) +BOOL LLPanelPrimMediaControls::handleKeyHere( KEY key, MASK mask ) { mInactivityTimer.start(); return LLPanel::handleKeyHere(key, mask); } -bool LLPanelMediaControls::isMouseOver() +bool LLPanelPrimMediaControls::isMouseOver() { bool result = false; @@ -707,12 +707,12 @@ bool LLPanelMediaControls::isMouseOver() } -void LLPanelMediaControls::onClickClose() +void LLPanelPrimMediaControls::onClickClose() { close(); } -void LLPanelMediaControls::close() +void LLPanelPrimMediaControls::close() { LLViewerMediaFocus::getInstance()->clearFocus(); resetZoomLevel(); @@ -720,7 +720,7 @@ void LLPanelMediaControls::close() } -void LLPanelMediaControls::onClickBack() +void LLPanelPrimMediaControls::onClickBack() { focusOnTarget(); @@ -732,7 +732,7 @@ void LLPanelMediaControls::onClickBack() } } -void LLPanelMediaControls::onClickForward() +void LLPanelPrimMediaControls::onClickForward() { focusOnTarget(); @@ -744,7 +744,7 @@ void LLPanelMediaControls::onClickForward() } } -void LLPanelMediaControls::onClickHome() +void LLPanelPrimMediaControls::onClickHome() { focusOnTarget(); @@ -756,7 +756,7 @@ void LLPanelMediaControls::onClickHome() } } -void LLPanelMediaControls::onClickOpen() +void LLPanelPrimMediaControls::onClickOpen() { LLViewerMediaImpl* impl =getTargetMediaImpl(); if(impl) @@ -775,7 +775,7 @@ void LLPanelMediaControls::onClickOpen() } } -void LLPanelMediaControls::onClickReload() +void LLPanelPrimMediaControls::onClickReload() { focusOnTarget(); @@ -788,7 +788,7 @@ void LLPanelMediaControls::onClickReload() } } -void LLPanelMediaControls::onClickPlay() +void LLPanelPrimMediaControls::onClickPlay() { focusOnTarget(); @@ -800,7 +800,7 @@ void LLPanelMediaControls::onClickPlay() } } -void LLPanelMediaControls::onClickPause() +void LLPanelPrimMediaControls::onClickPause() { focusOnTarget(); @@ -812,7 +812,7 @@ void LLPanelMediaControls::onClickPause() } } -void LLPanelMediaControls::onClickStop() +void LLPanelPrimMediaControls::onClickStop() { focusOnTarget(); @@ -824,13 +824,13 @@ void LLPanelMediaControls::onClickStop() } } -void LLPanelMediaControls::onClickZoom() +void LLPanelPrimMediaControls::onClickZoom() { focusOnTarget(); nextZoomLevel(); } -void LLPanelMediaControls::nextZoomLevel() +void LLPanelPrimMediaControls::nextZoomLevel() { int index = 0; while (index < kNumZoomLevels) @@ -846,7 +846,7 @@ void LLPanelMediaControls::nextZoomLevel() updateZoom(); } -void LLPanelMediaControls::resetZoomLevel() +void LLPanelPrimMediaControls::resetZoomLevel() { if(mCurrentZoom != ZOOM_NONE) { @@ -855,7 +855,7 @@ void LLPanelMediaControls::resetZoomLevel() } } -void LLPanelMediaControls::updateZoom() +void LLPanelPrimMediaControls::updateZoom() { F32 zoom_padding = 0.0f; switch (mCurrentZoom) @@ -890,9 +890,9 @@ void LLPanelMediaControls::updateZoom() if (zoom_padding > 0.0f) LLViewerMediaFocus::setCameraZoom(getTargetObject(), mTargetObjectNormal, zoom_padding); } -void LLPanelMediaControls::onScrollUp(void* user_data) +void LLPanelPrimMediaControls::onScrollUp(void* user_data) { - LLPanelMediaControls* this_panel = static_cast (user_data); + LLPanelPrimMediaControls* this_panel = static_cast (user_data); this_panel->focusOnTarget(); LLPluginClassMedia* plugin = this_panel->getTargetMediaPlugin(); @@ -902,14 +902,14 @@ void LLPanelMediaControls::onScrollUp(void* user_data) plugin->scrollEvent(0, -1, MASK_NONE); } } -void LLPanelMediaControls::onScrollUpHeld(void* user_data) +void LLPanelPrimMediaControls::onScrollUpHeld(void* user_data) { - LLPanelMediaControls* this_panel = static_cast (user_data); + LLPanelPrimMediaControls* this_panel = static_cast (user_data); this_panel->mScrollState = SCROLL_UP; } -void LLPanelMediaControls::onScrollRight(void* user_data) +void LLPanelPrimMediaControls::onScrollRight(void* user_data) { - LLPanelMediaControls* this_panel = static_cast (user_data); + LLPanelPrimMediaControls* this_panel = static_cast (user_data); this_panel->focusOnTarget(); LLViewerMediaImpl* impl = this_panel->getTargetMediaImpl(); @@ -919,15 +919,15 @@ void LLPanelMediaControls::onScrollRight(void* user_data) impl->handleKeyHere(KEY_RIGHT, MASK_NONE); } } -void LLPanelMediaControls::onScrollRightHeld(void* user_data) +void LLPanelPrimMediaControls::onScrollRightHeld(void* user_data) { - LLPanelMediaControls* this_panel = static_cast (user_data); + LLPanelPrimMediaControls* this_panel = static_cast (user_data); this_panel->mScrollState = SCROLL_RIGHT; } -void LLPanelMediaControls::onScrollLeft(void* user_data) +void LLPanelPrimMediaControls::onScrollLeft(void* user_data) { - LLPanelMediaControls* this_panel = static_cast (user_data); + LLPanelPrimMediaControls* this_panel = static_cast (user_data); this_panel->focusOnTarget(); LLViewerMediaImpl* impl = this_panel->getTargetMediaImpl(); @@ -937,15 +937,15 @@ void LLPanelMediaControls::onScrollLeft(void* user_data) impl->handleKeyHere(KEY_LEFT, MASK_NONE); } } -void LLPanelMediaControls::onScrollLeftHeld(void* user_data) +void LLPanelPrimMediaControls::onScrollLeftHeld(void* user_data) { - LLPanelMediaControls* this_panel = static_cast (user_data); + LLPanelPrimMediaControls* this_panel = static_cast (user_data); this_panel->mScrollState = SCROLL_LEFT; } -void LLPanelMediaControls::onScrollDown(void* user_data) +void LLPanelPrimMediaControls::onScrollDown(void* user_data) { - LLPanelMediaControls* this_panel = static_cast (user_data); + LLPanelPrimMediaControls* this_panel = static_cast (user_data); this_panel->focusOnTarget(); LLPluginClassMedia* plugin = this_panel->getTargetMediaPlugin(); @@ -955,19 +955,19 @@ void LLPanelMediaControls::onScrollDown(void* user_data) plugin->scrollEvent(0, 1, MASK_NONE); } } -void LLPanelMediaControls::onScrollDownHeld(void* user_data) +void LLPanelPrimMediaControls::onScrollDownHeld(void* user_data) { - LLPanelMediaControls* this_panel = static_cast (user_data); + LLPanelPrimMediaControls* this_panel = static_cast (user_data); this_panel->mScrollState = SCROLL_DOWN; } -void LLPanelMediaControls::onScrollStop(void* user_data) +void LLPanelPrimMediaControls::onScrollStop(void* user_data) { - LLPanelMediaControls* this_panel = static_cast (user_data); + LLPanelPrimMediaControls* this_panel = static_cast (user_data); this_panel->mScrollState = SCROLL_NONE; } -void LLPanelMediaControls::onCommitURL() +void LLPanelPrimMediaControls::onCommitURL() { focusOnTarget(); @@ -986,10 +986,10 @@ void LLPanelMediaControls::onCommitURL() } -void LLPanelMediaControls::onInputURL(LLFocusableElement* caller, void *userdata) +void LLPanelPrimMediaControls::onInputURL(LLFocusableElement* caller, void *userdata) { - LLPanelMediaControls* this_panel = static_cast (userdata); + LLPanelPrimMediaControls* this_panel = static_cast (userdata); this_panel->focusOnTarget(); this_panel->mPauseFadeout = true; @@ -998,7 +998,7 @@ void LLPanelMediaControls::onInputURL(LLFocusableElement* caller, void *userdata } -void LLPanelMediaControls::setCurrentURL() +void LLPanelPrimMediaControls::setCurrentURL() { LLComboBox* media_address_combo = getChild("media_address_combo"); // redirects will navigate momentarily to about:blank, don't add to history @@ -1010,7 +1010,7 @@ void LLPanelMediaControls::setCurrentURL() } } -void LLPanelMediaControls::onCommitSlider() +void LLPanelPrimMediaControls::onCommitSlider() { focusOnTarget(); @@ -1032,7 +1032,7 @@ void LLPanelMediaControls::onCommitSlider() } } -void LLPanelMediaControls::onCommitVolumeUp() +void LLPanelPrimMediaControls::onCommitVolumeUp() { focusOnTarget(); @@ -1052,7 +1052,7 @@ void LLPanelMediaControls::onCommitVolumeUp() } } -void LLPanelMediaControls::onCommitVolumeDown() +void LLPanelPrimMediaControls::onCommitVolumeDown() { focusOnTarget(); @@ -1073,7 +1073,7 @@ void LLPanelMediaControls::onCommitVolumeDown() } -void LLPanelMediaControls::onToggleMute() +void LLPanelPrimMediaControls::onToggleMute() { focusOnTarget(); diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index b605c08a55..3ec7aa2356 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -1,5 +1,5 @@ /** - * @file llpanelmediahud.h + * @file llpanelprimmediacontrols.h * @brief Pop-up media controls panel * * $LicenseInfo:firstyear=2003&license=viewergpl$ @@ -29,8 +29,8 @@ * $/LicenseInfo$ */ -#ifndef LL_PANELMEDIAHUD_H -#define LL_PANELMEDIAHUD_H +#ifndef LL_PANELPRIMMEDIACONTROLS_H +#define LL_PANELPRIMMEDIACONTROLS_H #include "llpanel.h" #include "llviewermedia.h" @@ -38,11 +38,11 @@ class LLCoordWindow; class LLViewerMediaImpl; -class LLPanelMediaControls : public LLPanel +class LLPanelPrimMediaControls : public LLPanel { public: - LLPanelMediaControls(); - virtual ~LLPanelMediaControls(); + LLPanelPrimMediaControls(); + virtual ~LLPanelPrimMediaControls(); /*virtual*/ BOOL postBuild(); virtual void draw(); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); @@ -57,7 +57,7 @@ public: void resetZoomLevel(); void close(); - LLHandle getHandle() const { return mPanelHandle; } + LLHandle getHandle() const { return mPanelHandle; } void setMediaFace(LLPointer objectp, S32 face, viewer_media_t media_impl, LLVector3 pick_normal = LLVector3::zero); @@ -131,7 +131,7 @@ private: LLFrameTimer mFadeTimer; F32 mInactiveTimeout; F32 mControlFadeTime; - LLRootHandle mPanelHandle; + LLRootHandle mPanelHandle; F32 mAlpha; std::string mCurrentURL; std::string mPreviousURL; @@ -145,4 +145,4 @@ private: LLVector3 mTargetObjectNormal; }; -#endif // LL_PANELMEDIAHUD_H +#endif // LL_PANELPRIMMEDIACONTROLS_H diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index cb5637a5bc..5d0b77d4fb 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -106,19 +106,19 @@ void LLViewerMediaFocus::setFocusFace(LLPointer objectp, S32 fac // We must do this before processing the media HUD zoom, or it may zoom to the wrong face. update(); - if(mMediaHUD.get() && face_auto_zoom && ! parcel->getMediaPreventCameraZoom()) + if(mMediaControls.get() && face_auto_zoom && ! parcel->getMediaPreventCameraZoom()) { - mMediaHUD.get()->resetZoomLevel(); - mMediaHUD.get()->nextZoomLevel(); + mMediaControls.get()->resetZoomLevel(); + mMediaControls.get()->nextZoomLevel(); } } else { if(mFocusedImplID != LLUUID::null) { - if(mMediaHUD.get()) + if(mMediaControls.get()) { - mMediaHUD.get()->resetZoomLevel(); + mMediaControls.get()->resetZoomLevel(); } gFocusMgr.setKeyboardFocus(NULL); @@ -327,20 +327,20 @@ void LLViewerMediaFocus::update() // We have an object and impl to point at. // Make sure the media HUD object exists. - if(! mMediaHUD.get()) + if(! mMediaControls.get()) { - LLPanelMediaControls* media_hud = new LLPanelMediaControls(); - mMediaHUD = media_hud->getHandle(); - gHUDView->addChild(media_hud); + LLPanelPrimMediaControls* media_controls = new LLPanelPrimMediaControls(); + mMediaControls = media_controls->getHandle(); + gHUDView->addChild(media_controls); } - mMediaHUD.get()->setMediaFace(viewer_object, face, media_impl, normal); + mMediaControls.get()->setMediaFace(viewer_object, face, media_impl, normal); } else { // The media HUD is no longer needed. - if(mMediaHUD.get()) + if(mMediaControls.get()) { - mMediaHUD.get()->setMediaFace(NULL, 0, NULL); + mMediaControls.get()->setMediaFace(NULL, 0, NULL); } } } diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h index 959b2381e4..c1179de39d 100644 --- a/indra/newview/llviewermediafocus.h +++ b/indra/newview/llviewermediafocus.h @@ -40,7 +40,7 @@ #include "llselectmgr.h" class LLViewerMediaImpl; -class LLPanelMediaControls; +class LLPanelPrimMediaControls; class LLViewerMediaFocus : public LLFocusableElement, @@ -88,7 +88,7 @@ protected: private: - LLHandle mMediaHUD; + LLHandle mMediaControls; LLUUID mFocusedObjectID; S32 mFocusedObjectFace; -- cgit v1.2.3