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/newview/skins/default') 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 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/newview/skins/default') 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.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/newview/skins/default') 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.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/newview/skins/default') 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.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/newview/skins/default') 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.3