diff options
Diffstat (limited to 'indra/newview')
89 files changed, 3010 insertions, 564 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 9a0c9d9c7b..899d0a8293 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -130,13 +130,13 @@ set(viewer_SOURCE_FILES llfeaturemanager.cpp llfilepicker.cpp llfirstuse.cpp + llfirsttimetipmanager.cpp llflexibleobject.cpp llfloaterabout.cpp llfloateractivespeakers.cpp llfloateraddlandmark.cpp llfloateranimpreview.cpp llfloaterauction.cpp - llfloateravatarinfo.cpp llfloateravatarpicker.cpp llfloateravatartextures.cpp llfloaterbeacons.cpp @@ -158,6 +158,7 @@ set(viewer_SOURCE_FILES llfloaterdirectory.cpp llfloaterenvsettings.cpp llfloaterevent.cpp + llfloaterfirsttimetip.cpp llfloaterfriends.cpp llfloaterfonttest.cpp llfloatergesture.cpp @@ -283,6 +284,7 @@ set(viewer_SOURCE_FILES llpanelavatar.cpp llpanelavatarrow.cpp llpanelclassified.cpp + llsidetraypanelcontainer.cpp llpanelcontents.cpp llpaneldirbrowser.cpp llpaneldirclassified.cpp @@ -308,6 +310,7 @@ set(viewer_SOURCE_FILES llpanellogin.cpp llpanelmedia.cpp llpanelmeprofile.cpp + llpanelmovetip.cpp llpanelobject.cpp llpanelpeople.cpp llpanelpermissions.cpp @@ -345,6 +348,7 @@ set(viewer_SOURCE_FILES llsky.cpp llslurl.cpp llspatialpartition.cpp + llsplitbutton.cpp llsprite.cpp llsrv.cpp llstartup.cpp @@ -569,13 +573,13 @@ set(viewer_HEADER_FILES llfeaturemanager.h llfilepicker.h llfirstuse.h + llfirsttimetipmanager.h llflexibleobject.h llfloaterabout.h llfloateractivespeakers.h llfloateraddlandmark.h llfloateranimpreview.h llfloaterauction.h - llfloateravatarinfo.h llfloateravatarpicker.h llfloateravatartextures.h llfloaterbeacons.h @@ -597,6 +601,7 @@ set(viewer_HEADER_FILES llfloaterdirectory.h llfloaterenvsettings.h llfloaterevent.h + llfloaterfirsttimetip.h llfloaterfonttest.h llfloaterfriends.h llfloatergesture.h @@ -721,6 +726,7 @@ set(viewer_HEADER_FILES llpanelavatar.h llpanelavatarrow.h llpanelclassified.h + llsidetraypanelcontainer.h llpanelcontents.h llpaneldirbrowser.h llpaneldirclassified.h @@ -746,6 +752,7 @@ set(viewer_HEADER_FILES llpanellogin.h llpanelmedia.h llpanelmeprofile.h + llpanelmovetip.h llpanelobject.h llpanelpeople.h llpanelpermissions.h @@ -785,6 +792,7 @@ set(viewer_HEADER_FILES llsky.h llslurl.h llspatialpartition.h + llsplitbutton.h llsprite.h llsrv.h llstartup.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index edcd288b7d..3baf37826f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4760,6 +4760,17 @@ <key>Value</key> <integer>5</integer> </map> + <key>ToastOpaqueTime</key> + <map> + <key>Comment</key> + <string>Width of notification messages</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>4</integer> + </map> <key>StartUpToastTime</key> <map> <key>Comment</key> @@ -4769,7 +4780,7 @@ <key>Type</key> <string>S32</string> <key>Value</key> - <integer>10</integer> + <integer>5</integer> </map> <key>ToastMargin</key> <map> @@ -6765,6 +6776,17 @@ <key>ShowCrosshairs</key> <map> <key>Comment</key> + <string>Show Coordinates in Location Input Field</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>ShowCoordinatesOption</key> + <map> + <key>Comment</key> <string>Display crosshairs when in mouselook mode</string> <key>Persist</key> <integer>1</integer> @@ -9623,5 +9645,16 @@ <key>Value</key> <integer>0</integer> </map> + <key>GroupTeleportMembersLimit</key> + <map> + <key>Comment</key> + <string>Max number of members of group to offer teleport</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>100</integer> + </map> </map> </llsd> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index f527719a7a..ce8b05d97a 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -42,7 +42,6 @@ #include "llfirstuse.h" #include "llfloaterreg.h" #include "llfloateractivespeakers.h" -#include "llfloateravatarinfo.h" #include "llfloatercamera.h" #include "llfloatercustomize.h" #include "llfloaterdirectory.h" @@ -499,12 +498,16 @@ void LLAgent::resetView(BOOL reset_camera, BOOL change_camera) LLViewerJoystick::getInstance()->moveAvatar(true); } - LLFloaterReg::hideInstance("build"); + //Camera Tool is needed for Free Camera Control Mode + if (!LLFloaterCamera::inFreeCameraMode()) + { + LLFloaterReg::hideInstance("build"); + + // Switch back to basic toolset + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + } gViewerWindow->showCursor(); - - // Switch back to basic toolset - LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); } @@ -755,7 +758,7 @@ void LLAgent::setFlying(BOOL fly) } // don't allow taking off while sitting - if (fly && mAvatarObject->mIsSitting) + if (fly && mAvatarObject->isSitting()) { return; } @@ -784,6 +787,11 @@ void LLAgent::setFlying(BOOL fly) clearControlFlags(AGENT_CONTROL_FLY); gSavedSettings.setBOOL("FlyBtnState", FALSE); } + + + // Update Movement Controls according to Fly mode + LLFloaterMove::setFlyingMode(fly); + mbFlagsDirty = TRUE; } @@ -807,11 +815,16 @@ bool LLAgent::enableFlying() BOOL sitting = FALSE; if (gAgent.getAvatarObject()) { - sitting = gAgent.getAvatarObject()->mIsSitting; + sitting = gAgent.getAvatarObject()->isSitting(); } return !sitting; } +void LLAgent::standUp() +{ + setControlFlags(AGENT_CONTROL_STAND_UP); +} + //----------------------------------------------------------------------------- // setRegion() @@ -1242,7 +1255,7 @@ F32 LLAgent::clampPitchToLimits(F32 angle) F32 angle_from_skyward = acos( mFrameAgent.getAtAxis() * skyward ); - if (mAvatarObject.notNull() && mAvatarObject->mIsSitting) + if (mAvatarObject.notNull() && mAvatarObject->isSitting()) { look_down_limit = 130.f * DEG_TO_RAD; } @@ -2488,13 +2501,11 @@ void LLAgent::autoPilot(F32 *delta_yaw) void LLAgent::propagate(const F32 dt) { // Update UI based on agent motion - LLFloaterMove *floater_move = LLFloaterReg::getTypedInstance<LLFloaterMove>("moveview"); + LLFloaterMove *floater_move = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview"); if (floater_move) { floater_move->mForwardButton ->setToggleState( mAtKey > 0 || mWalkKey > 0 ); floater_move->mBackwardButton ->setToggleState( mAtKey < 0 || mWalkKey < 0 ); - floater_move->mSlideLeftButton ->setToggleState( mLeftKey > 0 ); - floater_move->mSlideRightButton->setToggleState( mLeftKey < 0 ); floater_move->mTurnLeftButton ->setToggleState( mYawKey > 0.f ); floater_move->mTurnRightButton ->setToggleState( mYawKey < 0.f ); floater_move->mMoveUpButton ->setToggleState( mUpKey > 0 ); @@ -2579,7 +2590,7 @@ void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y) else { // *FIX: rotate mframeagent by sit object's rotation? - LLQuaternion look_rotation = mAvatarObject->mIsSitting ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); // use camera's current rotation + LLQuaternion look_rotation = mAvatarObject->isSitting() ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); // use camera's current rotation LLVector3 look_offset = LLVector3(2.f, 0.f, 0.f) * look_rotation * av_inv_rot; setLookAt(LOOKAT_TARGET_IDLE, mAvatarObject, look_offset); } @@ -2815,6 +2826,8 @@ void LLAgent::endAnimationUpdateUI() LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + LLFloaterCamera::toPrevModeIfInAvatarViewMode(); + // Only pop if we have pushed... if (TRUE == mViewsPushed) { @@ -2909,6 +2922,10 @@ void LLAgent::endAnimationUpdateUI() // JC - Added for always chat in third person option gFocusMgr.setKeyboardFocus(NULL); + //Making sure Camera Controls floater is in the right state + //when entering Mouse Look using wheel scrolling + LLFloaterCamera::updateIfNotInAvatarViewMode(); + LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset); mViewsPushed = TRUE; @@ -3019,7 +3036,7 @@ void LLAgent::updateCamera() validateFocusObject(); if (mAvatarObject.notNull() && - mAvatarObject->mIsSitting && + mAvatarObject->isSitting() && camera_mode == CAMERA_MODE_MOUSELOOK) { //Ventrella @@ -3050,24 +3067,24 @@ void LLAgent::updateCamera() } // Update UI with our camera inputs - LLFloaterCamera* camera_instance = LLFloaterReg::getTypedInstance<LLFloaterCamera>("camera"); - if(camera_instance) + LLFloaterCamera* camera_floater = LLFloaterReg::findTypedInstance<LLFloaterCamera>("camera"); + if (camera_floater) { - camera_instance->mRotate->setToggleState( - mOrbitRightKey > 0.f, // left - mOrbitUpKey > 0.f, // top - mOrbitLeftKey > 0.f, // right - mOrbitDownKey > 0.f); // bottom + camera_floater->mRotate->setToggleState( + mOrbitRightKey > 0.f, // left + mOrbitUpKey > 0.f, // top + mOrbitLeftKey > 0.f, // right + mOrbitDownKey > 0.f); // bottom - camera_instance->mZoom->setToggleState( - mOrbitInKey > 0.f, // top - mOrbitOutKey > 0.f); // bottom + camera_floater->mZoom->setToggleState( + mOrbitInKey > 0.f, // top + mOrbitOutKey > 0.f); // bottom - camera_instance->mTrack->setToggleState( - mPanLeftKey > 0.f, // left - mPanUpKey > 0.f, // top - mPanRightKey > 0.f, // right - mPanDownKey > 0.f); // bottom + camera_floater->mTrack->setToggleState( + mPanLeftKey > 0.f, // left + mPanUpKey > 0.f, // top + mPanRightKey > 0.f, // right + mPanDownKey > 0.f); // bottom } // Handle camera movement based on keyboard. @@ -3144,7 +3161,7 @@ void LLAgent::updateCamera() // (2) focus, and (3) upvector. They can then be queried elsewhere in llAgent. //-------------------------------------------------------------------------------- // *TODO: use combined rotation of frameagent and sit object - LLQuaternion avatarRotationForFollowCam = mAvatarObject->mIsSitting ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); + LLQuaternion avatarRotationForFollowCam = mAvatarObject->isSitting() ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); LLFollowCamParams* current_cam = LLFollowCamMgr::getActiveFollowCamParams(); if (current_cam) @@ -3324,7 +3341,7 @@ void LLAgent::updateCamera() } mLastPositionGlobal = global_pos; - if (LLVOAvatar::sVisibleInFirstPerson && mAvatarObject.notNull() && !mAvatarObject->mIsSitting && cameraMouselook()) + if (LLVOAvatar::sVisibleInFirstPerson && mAvatarObject.notNull() && !mAvatarObject->isSitting() && cameraMouselook()) { LLVector3 head_pos = mAvatarObject->mHeadp->getWorldPosition() + LLVector3(0.08f, 0.f, 0.05f) * mAvatarObject->mHeadp->getWorldRotation() + @@ -3504,7 +3521,7 @@ LLVector3d LLAgent::calcFocusPositionTargetGlobal() } return mFocusTargetGlobal; } - else if (mSitCameraEnabled && mAvatarObject.notNull() && mAvatarObject->mIsSitting && mSitCameraReferenceObject.notNull()) + else if (mSitCameraEnabled && mAvatarObject.notNull() && mAvatarObject->isSitting() && mSitCameraReferenceObject.notNull()) { // sit camera LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition(); @@ -3628,7 +3645,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) return LLVector3d::zero; } head_offset.clearVec(); - if (mAvatarObject->mIsSitting && mAvatarObject->getParent()) + if (mAvatarObject->isSitting() && mAvatarObject->getParent()) { mAvatarObject->updateHeadOffset(); head_offset.mdV[VX] = mAvatarObject->mHeadOffset.mV[VX]; @@ -3642,7 +3659,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) else { head_offset.mdV[VZ] = mAvatarObject->mHeadOffset.mV[VZ]; - if (mAvatarObject->mIsSitting) + if (mAvatarObject->isSitting()) { head_offset.mdV[VZ] += 0.1; } @@ -3658,7 +3675,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) if (mSitCameraEnabled && mAvatarObject.notNull() - && mAvatarObject->mIsSitting + && mAvatarObject->isSitting() && mSitCameraReferenceObject.notNull()) { // sit camera @@ -3690,7 +3707,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) local_camera_offset = mFrameAgent.rotateToAbsolute( local_camera_offset ); } - if (!mCameraCollidePlane.isExactlyZero() && (mAvatarObject.isNull() || !mAvatarObject->mIsSitting)) + if (!mCameraCollidePlane.isExactlyZero() && (mAvatarObject.isNull() || !mAvatarObject->isSitting())) { LLVector3 plane_normal; plane_normal.setVec(mCameraCollidePlane.mV); @@ -4116,7 +4133,7 @@ void LLAgent::changeCameraToThirdPerson(BOOL animate) if (mAvatarObject.notNull()) { - if (!mAvatarObject->mIsSitting) + if (!mAvatarObject->isSitting()) { mAvatarObject->mPelvisp->setPosition(LLVector3::zero); } @@ -4198,7 +4215,7 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani return; } - setControlFlags(AGENT_CONTROL_STAND_UP); // force stand up + standUp(); // force stand up gViewerWindow->getWindow()->resetBusyCount(); if (gFaceEditToolset) @@ -5478,13 +5495,8 @@ void update_group_floaters(const LLUUID& group_id) { LLFloaterGroupInfo::refreshGroup(group_id); - //*TODO Implement group update for Profile View - // update avatar info -// LLFloaterAvatarInfo* fa = LLFloaterReg::findTypedInstance<LLFloaterAvatarInfo>("preview_avatar", LLSD(gAgent.getID())); -// if(fa) -// { -// fa->resetGroupList(); -// } + //*TODO Implement group update for Profile View + // still actual as of July 31, 2009 (DZ) if (gIMMgr) { diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index e25bb0a578..0b1ff2e76b 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -374,6 +374,12 @@ private: bool mbRunning; // Is the avatar trying to run right now? //-------------------------------------------------------------------- + // Sit and stand + //-------------------------------------------------------------------- +public: + void standUp(); + + //-------------------------------------------------------------------- // Busy //-------------------------------------------------------------------- public: diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 245e358d80..7834e7b2ef 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3997,8 +3997,6 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) void LLAppViewer::handleLoginComplete() { - gViewerWindow->handleLoginComplete(); - initMainloopTimeout("Mainloop Init"); // Store some data to DebugInfo in case of a freeze. diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index a85f8710c7..40dd20dfa4 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -117,6 +117,24 @@ void LLAvatarList::draw() } } +//virtual +BOOL LLAvatarList::handleMouseDown(S32 x, S32 y, MASK mask) +{ + LLScrollListItem* hit_item = hitItem(x, y); + if (NULL == hit_item) + { + std::vector<LLScrollListItem*> selectedItems = getAllSelected(); + std::vector<LLScrollListItem*>::const_iterator it = selectedItems.begin(); + + for (; it != selectedItems.end(); ++it) + { + (*it)->setSelected(FALSE); + } + return TRUE; + } + return LLScrollListCtrl::handleMouseDown(x, y, mask); +} + std::vector<LLUUID> LLAvatarList::getSelectedIDs() { LLUUID selected_id; diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index 8b419dbb57..991e9fa145 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -59,6 +59,14 @@ public: virtual ~LLAvatarList() {} /*virtual*/ void draw(); + /** + * Overrides base-class behavior of Mouse Down Event. + * + * LLScrollListCtrl::handleMouseDown version calls setFocus which select the first item if nothing selected. + * We need to deselect all items if perform click not over the any item. Otherwise calls base method. + * See EXT-246 + */ + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); BOOL update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter = LLStringUtil::null); diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 1781e6b3f1..8e1ae7d4f2 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -38,17 +38,14 @@ #include "llfloaterreg.h" #include "llflyoutbutton.h" #include "llnearbychatbar.h" - -//FIXME: temporary, for stand up proto -#include "llselectmgr.h" -#include "llvoavatarself.h" +#include "llsplitbutton.h" +#include "llfloatercamera.h" LLBottomTray::LLBottomTray(const LLSD&) : mChicletPanel(NULL) , mIMWell(NULL) , mSysWell(NULL) , mTalkBtn(NULL) - , mStandUpBtn(NULL) ////FIXME: temporary, for stand up proto , mNearbyChatBar(NULL) { mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL); @@ -61,13 +58,9 @@ LLBottomTray::LLBottomTray(const LLSD&) mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1)); - ////FIXME: temporary, for stand up proto - mStandUpBtn = getChild<LLButton> ("stand", TRUE, FALSE); - if (mStandUpBtn) - { - mStandUpBtn->setCommitCallback(boost::bind(&LLBottomTray::onCommitStandUp, this, _1)); - } - + LLSplitButton* presets = getChild<LLSplitButton>("presets", TRUE, FALSE); + if (presets) presets->setSelectionCallback(LLFloaterCamera::onClickCameraPresets); + LLIMMgr::getInstance()->addSessionObserver(this); //this is to fix a crash that occurs because LLBottomTray is a singleton @@ -99,6 +92,7 @@ void LLBottomTray::onChicletClick(LLUICtrl* ctrl) //// Show after comm window so it is frontmost (and hence will not //// auto-hide) //LLIMFloater::show(chiclet->getSessionId()); + chiclet->setCounter(0); } } @@ -114,37 +108,6 @@ void* LLBottomTray::createNearbyChatBar(void* userdata) } //virtual -void LLBottomTray::draw() -{ - refreshStandUp(); - LLPanel::draw(); -} - -void LLBottomTray::refreshStandUp() -{ - //FIXME: temporary, for stand up proto - BOOL sitting = FALSE; - if (gAgent.getAvatarObject()) - { - sitting = gAgent.getAvatarObject()->mIsSitting; - } - - if (mStandUpBtn && mStandUpBtn->getVisible() != sitting) - { - mStandUpBtn->setVisible(sitting); - sendChildToFront(mStandUpBtn); - moveChildToBackOfTabGroup(mStandUpBtn); - } -} - -//FIXME: temporary, for stand up proto -void LLBottomTray::onCommitStandUp(LLUICtrl* ctrl) -{ - LLSelectMgr::getInstance()->deselectAllForStandingUp(); - gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); -} - -//virtual void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) { if(getChicletPanel()) diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index e5848f72dc..a100124e02 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -56,11 +56,7 @@ public: LLNotificationChiclet* getSysWell() {return mSysWell;} LLNearbyChatBar* getNearbyChatBar() {return mNearbyChatBar;} - /*virtual*/void draw(); - void refreshStandUp(); - void onCommitGesture(LLUICtrl* ctrl); - void onCommitStandUp(LLUICtrl* ctrl); void refreshGestures(); // LLIMSessionObserver observe triggers @@ -82,7 +78,6 @@ protected: LLNotificationChiclet* mIMWell; LLNotificationChiclet* mSysWell; LLTalkButton* mTalkBtn; - LLButton* mStandUpBtn; LLNearbyChatBar* mNearbyChatBar; }; diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index 0eb0801a2c..118385ab58 100644 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -45,6 +45,8 @@ using namespace LLNotificationsUI; LLChannelManager::LLChannelManager() { LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLChannelManager::onLoginCompleted, this)); + mChannelList.clear(); + mStartUpChannel = NULL; } //-------------------------------------------------------------------------- @@ -74,7 +76,6 @@ void LLChannelManager::onLoginCompleted() p.id = LLUUID(STARTUP_CHANNEL_ID); p.channel_right_bound = getRootView()->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); p.channel_width = gSavedSettings.getS32("NotifyBoxWidth"); - mStartUpChannel = NULL; mStartUpChannel = createChannel(p); if(!mStartUpChannel) @@ -90,6 +91,7 @@ void LLChannelManager::enableShowToasts() { LLScreenChannel::setStartUpToastShown(); delete mStartUpChannel; + mStartUpChannel = NULL; } //-------------------------------------------------------------------------- @@ -166,6 +168,10 @@ void LLChannelManager::reshape(S32 width, S32 height, BOOL called_from_parent) //-------------------------------------------------------------------------- +LLScreenChannel* LLChannelManager::getStartUpChannel() +{ + return mStartUpChannel; +} //-------------------------------------------------------------------------- diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h index 3914d20ebc..ac8e81d7ef 100644 --- a/indra/newview/llchannelmanager.h +++ b/indra/newview/llchannelmanager.h @@ -112,6 +112,8 @@ public: void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + LLScreenChannel* getStartUpChannel(); + private: LLScreenChannel* mStartUpChannel; diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index ee3e465832..81f1beb40d 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -35,24 +35,143 @@ #include "llfloatercamera.h" // Library includes -#include "lluictrlfactory.h" +#include "llfloaterreg.h" // Viewer includes #include "lljoystickbutton.h" +#include "llfirsttimetipmanager.h" #include "llviewercontrol.h" +#include "llbottomtray.h" +#include "llagent.h" +#include "lltoolmgr.h" +#include "lltoolfocus.h" // Constants const F32 CAMERA_BUTTON_DELAY = 0.0f; +#define ORBIT "cam_rotate_stick" +#define PAN "cam_track_stick" +#define CONTROLS "controls" + // // Member functions // + +/*static*/ bool LLFloaterCamera::inFreeCameraMode() +{ + LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance(); + if (floater_camera && floater_camera->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA) + { + return true; + } + return false; +} + +bool LLFloaterCamera::inAvatarViewMode() +{ + return mCurrMode == CAMERA_CTRL_MODE_AVATAR_VIEW; +} + +void LLFloaterCamera::resetFreeCameraMode() +{ + if (mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA) + { + /* Camera Tool can be deselected when we are mouse wheel scrolling into Mouse Look + In such case we are unable to determine that we will be into Mouse Look view */ + if (mPrevMode == CAMERA_CTRL_MODE_AVATAR_VIEW) + { + setMode(CAMERA_CTRL_MODE_ORBIT); + } + else + { + setMode(mPrevMode); + } + } +} + +void LLFloaterCamera::update() +{ + ECameraControlMode mode = determineMode(); + if (mode != mCurrMode) setMode(mode); + LLFirstTimeTipsManager::showTipsFor(mMode2TipType[mode], this); +} + + +/*static*/ void LLFloaterCamera::updateIfNotInAvatarViewMode() +{ + LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance(); + if (floater_camera && !floater_camera->inAvatarViewMode()) + { + floater_camera->update(); + } +} + + +void LLFloaterCamera::toPrevMode() +{ + switchMode(mPrevMode); +} + +/*static*/ void LLFloaterCamera::toPrevModeIfInAvatarViewMode() +{ + LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance(); + if (floater_camera && floater_camera->inAvatarViewMode()) + { + floater_camera->toPrevMode(); + } +} + +LLFloaterCamera* LLFloaterCamera::findInstance() +{ + return LLFloaterReg::findTypedInstance<LLFloaterCamera>("camera"); +} + +/*static*/ +void LLFloaterCamera::onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param) +{ + std::string name = param.asString(); + + if ("rear_view" == name) + { + LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_REAR, ctrl); + gAgent.resetView(TRUE, TRUE); + } + else if ("3/4_view" == name) + { + LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_GROUP); + //*TODO implement 3/4 view + } + else if ("front_view" == name) + { + LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_FRONT); + //*TODO implement front view + } + +} + +void LLFloaterCamera::onOpen(const LLSD& key) +{ + updatePosition(); +} + +void LLFloaterCamera::updatePosition() +{ + LLBottomTray* tray = LLBottomTray::getInstance(); + if (!tray) return; + + LLButton* camera_button = tray->getChild<LLButton>("camera_btn", TRUE, FALSE); + if (!camera_button) return; + + //align centers of a button and a floater + S32 x = camera_button->calcScreenRect().getCenterX() - getRect().getWidth()/2; + setOrigin(x, 0); +} + LLFloaterCamera::LLFloaterCamera(const LLSD& val) -: LLFloater(val) +: LLFloater(val), + mCurrMode(CAMERA_CTRL_MODE_ORBIT), + mPrevMode(CAMERA_CTRL_MODE_ORBIT) { - //// For now, only used for size and tooltip strings - //const BOOL DONT_OPEN = FALSE; - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_camera.xml", DONT_OPEN); } // virtual @@ -60,10 +179,163 @@ BOOL LLFloaterCamera::postBuild() { setIsChrome(TRUE); - mRotate = getChild<LLJoystickCameraRotate>("cam_rotate_stick"); + mRotate = getChild<LLJoystickCameraRotate>(ORBIT); mZoom = getChild<LLJoystickCameraZoom>("zoom"); - mTrack = getChild<LLJoystickCameraTrack>("cam_track_stick"); + mTrack = getChild<LLJoystickCameraTrack>(PAN); + + initMode2TipTypeMap(); + + assignButton2Mode(CAMERA_CTRL_MODE_ORBIT, "orbit_btn"); + assignButton2Mode(CAMERA_CTRL_MODE_PAN, "pan_btn"); + assignButton2Mode(CAMERA_CTRL_MODE_FREE_CAMERA, "freecamera_btn"); + assignButton2Mode(CAMERA_CTRL_MODE_AVATAR_VIEW, "avatarview_btn"); + + update(); return TRUE; } +ECameraControlMode LLFloaterCamera::determineMode() +{ + LLTool* curr_tool = LLToolMgr::getInstance()->getCurrentTool(); + if (curr_tool == LLToolCamera::getInstance()) + { + return CAMERA_CTRL_MODE_FREE_CAMERA; + } + + if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK) + { + return CAMERA_CTRL_MODE_AVATAR_VIEW; + } + + return CAMERA_CTRL_MODE_ORBIT; +} + + +void clear_camera_tool() +{ + LLToolMgr* tool_mgr = LLToolMgr::getInstance(); + if (tool_mgr->usingTransientTool() && + tool_mgr->getCurrentTool() == LLToolCamera::getInstance()) + { + tool_mgr->clearTransientTool(); + } +} + + +void LLFloaterCamera::setMode(ECameraControlMode mode) +{ + if (mode != mCurrMode) + { + mPrevMode = mCurrMode; + mCurrMode = mode; + } + + updateState(); +} + +void LLFloaterCamera::switchMode(ECameraControlMode mode) +{ + setMode(mode); + + switch (mode) + { + case CAMERA_CTRL_MODE_ORBIT: + clear_camera_tool(); + break; + + case CAMERA_CTRL_MODE_PAN: + clear_camera_tool(); + break; + + case CAMERA_CTRL_MODE_FREE_CAMERA: + LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance()); + break; + + case CAMERA_CTRL_MODE_AVATAR_VIEW: + gAgent.changeCameraToMouselook(); + break; + + default: + //normally we won't occur here + llassert_always(FALSE); + } +} + + +void LLFloaterCamera::onClickBtn(ECameraControlMode mode) +{ + // check for a click on active button + if (mCurrMode == mode) mMode2Button[mode]->setToggleState(TRUE); + + switchMode(mode); + + LLFirstTimeTipsManager::showTipsFor(mMode2TipType[mode], mMode2Button[mode]); +} + +void LLFloaterCamera::assignButton2Mode(ECameraControlMode mode, const std::string& button_name) +{ + LLButton* button = getChild<LLButton>(button_name, TRUE, FALSE); + llassert_always(button); + + if (button) + { + button->setClickedCallback(boost::bind(&LLFloaterCamera::onClickBtn, this, mode)); + mMode2Button[mode] = button; + } +} + +void LLFloaterCamera::initMode2TipTypeMap() +{ + mMode2TipType[CAMERA_CTRL_MODE_ORBIT] = LLFirstTimeTipsManager::FTT_CAMERA_ORBIT_MODE; + mMode2TipType[CAMERA_CTRL_MODE_PAN] = LLFirstTimeTipsManager::FTT_CAMERA_PAN_MODE; + mMode2TipType[CAMERA_CTRL_MODE_FREE_CAMERA] = LLFirstTimeTipsManager::FTT_CAMERA_FREE_MODE; + mMode2TipType[CAMERA_CTRL_MODE_AVATAR_VIEW] = LLFirstTimeTipsManager::FTT_AVATAR_FREE_MODE; +} + + +void LLFloaterCamera::updateState() +{ + //updating buttons + std::map<ECameraControlMode, LLButton*>::const_iterator iter = mMode2Button.begin(); + for (; iter != mMode2Button.end(); ++iter) + { + iter->second->setToggleState(iter->first == mCurrMode); + } + + //updating controls + bool isOrbitMode = CAMERA_CTRL_MODE_ORBIT == mCurrMode; + bool isPanMode = CAMERA_CTRL_MODE_PAN == mCurrMode; + + childSetVisible(ORBIT, isOrbitMode); + childSetVisible(PAN, isPanMode); + + //hiding or showing the panel with controls by reshaping the floater + bool showControls = isOrbitMode || isPanMode; + if (showControls == childIsVisible(CONTROLS)) return; + + childSetVisible(CONTROLS, showControls); + + LLRect rect = getRect(); + LLRect controls_rect; + if (childGetRect(CONTROLS, controls_rect)) + { + static S32 height = controls_rect.getHeight(); + S32 newHeight = rect.getHeight(); + + if (showControls) + { + newHeight += height; + } + else + { + newHeight -= height; + } + + rect.setOriginAndSize(rect.mLeft, rect.mBottom, rect.getWidth(), newHeight); + reshape(rect.getWidth(), rect.getHeight()); + setRect(rect); + + } +} + diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index fabe8f577e..04554c6493 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -35,26 +35,94 @@ #include "llfloater.h" +#include "llfirsttimetipmanager.h" + class LLJoystickCameraRotate; class LLJoystickCameraZoom; class LLJoystickCameraTrack; +class LLFloaterReg; + +enum ECameraControlMode +{ + CAMERA_CTRL_MODE_ORBIT, + CAMERA_CTRL_MODE_PAN, + CAMERA_CTRL_MODE_FREE_CAMERA, + CAMERA_CTRL_MODE_AVATAR_VIEW +}; class LLFloaterCamera : public LLFloater { friend class LLFloaterReg; -private: - - LLFloaterCamera(const LLSD& val); - ~LLFloaterCamera() {}; - - /*virtual*/ BOOL postBuild(); public: + + /* whether in free camera mode */ + static bool inFreeCameraMode(); + + static void toPrevModeIfInAvatarViewMode(); + + /* resets free camera mode to the previous mode */ + //*TODO remove, if it won't be used by LLToolCamera::handleDeselect() + void resetFreeCameraMode(); + + /* determines actual mode and updates ui */ + void update(); + static void updateIfNotInAvatarViewMode(); + + static void onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param); + + virtual void onOpen(const LLSD& key); + + // *HACK: due to hard enough to have this control aligned with "Camera" button while resizing + // let update its position in each frame + /*virtual*/ void draw(){updatePosition(); LLFloater::draw();} + LLJoystickCameraRotate* mRotate; LLJoystickCameraZoom* mZoom; LLJoystickCameraTrack* mTrack; + +private: + + LLFloaterCamera(const LLSD& val); + ~LLFloaterCamera() {}; + + /* return instance if it exists - created by LLFloaterReg */ + static LLFloaterCamera* findInstance(); + + /*virtual*/ BOOL postBuild(); + + ECameraControlMode determineMode(); + + /* whether in avatar view (first person) mode */ + bool inAvatarViewMode(); + + /* resets to the previous mode */ + void toPrevMode(); + + /* sets a new mode and performs related actions */ + void switchMode(ECameraControlMode mode); + + /* sets a new mode preserving previous one and updates ui*/ + void setMode(ECameraControlMode mode); + + /* updates the state (UI) according to the current mode */ + void updateState(); + + void onClickBtn(ECameraControlMode mode); + void assignButton2Mode(ECameraControlMode mode, const std::string& button_name); + void initMode2TipTypeMap(); + + /*Updates position of the floater to be center aligned with "Camera" button.*/ + void updatePosition(); + + + ECameraControlMode mPrevMode; + ECameraControlMode mCurrMode; + std::map<ECameraControlMode, LLButton*> mMode2Button; + std::map<ECameraControlMode, LLFirstTimeTipsManager::EFirstTimeTipType> mMode2TipType; + }; #endif diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index cf78d7d34f..1118dd8f69 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -50,7 +50,6 @@ // newview includes #include "llappviewer.h" #include "llfirstuse.h" -#include "llfloateravatarinfo.h" #include "llfloaterchat.h" #include "llfloatercustomize.h" #include "llfocusmgr.h" diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index cda30d8900..30f4447283 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -39,6 +39,127 @@ #include "llfloatergroupinfo.h" #include "llfloaterreg.h" #include "llimview.h" // for gIMMgr +#include "llgroupmgr.h" +#include "llavataractions.h" +#include "llviewercontrol.h" + +// LLGroupActions::teleport helper +// +// Method is offerTeleport should be called. +// First it checks, whether LLGroupMgr contains LLGroupMgrGroupData for this group already. +// If it's there, processMembersList can be called, which builds vector of ID's for online members and +// calls LLAvatarActions::offerTeleport. +// If LLGroupMgr doesn't contain LLGroupMgrGroupData, then ID of group should be saved in +// mID or queue, if mID is not empty. After that processQueue uses ID from mID or queue, +// registers LLGroupTeleporter as observer at LLGroupMgr and sends request for group members. +// LLGroupMgr notifies about response on this request by calling method 'changed'. +// It calls processMembersList, sets mID to null, to indicate that current group is processed, +// and calls processQueue to process remaining groups. +// The reason of calling of LLGroupMgr::addObserver and LLGroupMgr::removeObserver in +// processQueue and 'changed' methods is that LLGroupMgr notifies observers of only particular group, +// so, for each group mID should be updated and addObserver/removeObserver is called. + +class LLGroupTeleporter : public LLGroupMgrObserver +{ +public: + LLGroupTeleporter() : LLGroupMgrObserver(LLUUID()) {} + + void offerTeleport(const LLUUID& group_id); + + // LLGroupMgrObserver trigger + virtual void changed(LLGroupChange gc); +private: + void processQueue(); + void processMembersList(LLGroupMgrGroupData* gdatap); + + std::queue<LLUUID> mGroupsQueue; +}; + +void LLGroupTeleporter::offerTeleport(const LLUUID& group_id) +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id); + + if (!gdatap || !gdatap->isMemberDataComplete()) + { + if (mID.isNull()) + mID = group_id; + else + // Not null mID means that user requested next group teleport before + // previous group is processed, so this group goes to queue + mGroupsQueue.push(group_id); + + processQueue(); + } + else + { + processMembersList(gdatap); + } +} + +// Sends request for group in mID or one group in queue +void LLGroupTeleporter::processQueue() +{ + // Get group from queue, if mID is empty + if (mID.isNull() && !mGroupsQueue.empty()) + { + mID = mGroupsQueue.front(); + mGroupsQueue.pop(); + } + + if (mID.notNull()) + { + LLGroupMgr::getInstance()->addObserver(this); + LLGroupMgr::getInstance()->sendGroupMembersRequest(mID); + } +} + +// Collects all online members of group and offers teleport to them +void LLGroupTeleporter::processMembersList(LLGroupMgrGroupData* gdatap) +{ + U32 limit = gSavedSettings.getU32("GroupTeleportMembersLimit"); + + LLDynamicArray<LLUUID> ids; + for (LLGroupMgrGroupData::member_list_t::iterator iter = gdatap->mMembers.begin(); iter != gdatap->mMembers.end(); iter++) + { + LLGroupMemberData* member = iter->second; + if (!member) + continue; + + if (member->getID() == gAgent.getID()) + // No need to teleport own avatar + continue; + + if (member->getOnlineStatus() == "Online") + ids.push_back(member->getID()); + + if ((U32)ids.size() >= limit) + break; + } + + LLAvatarActions::offerTeleport(ids); +} + +// LLGroupMgrObserver trigger +void LLGroupTeleporter::changed(LLGroupChange gc) +{ + if (gc == GC_MEMBER_DATA) + { + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); + + if (gdatap && gdatap->isMemberDataComplete()) + processMembersList(gdatap); + + LLGroupMgr::getInstance()->removeObserver(this); + + // group in mID is processed + mID.setNull(); + + // process other groups in queue, if any + processQueue(); + } +} + +static LLGroupTeleporter sGroupTeleporter; // static void LLGroupActions::search() @@ -119,6 +240,12 @@ void LLGroupActions::startChat(const LLUUID& group_id) } } +// static +void LLGroupActions::offerTeleport(const LLUUID& group_id) +{ + sGroupTeleporter.offerTeleport(group_id); +} + //-- Private methods ---------------------------------------------------------- // static diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h index 1e6caea17c..b6ddb4511a 100644 --- a/indra/newview/llgroupactions.h +++ b/indra/newview/llgroupactions.h @@ -71,6 +71,11 @@ public: * Start group instant messaging session. */ static void startChat(const LLUUID& group_id); + + /** + * Offers teleport for online members of group + */ + static void offerTeleport(const LLUUID& group_id); private: static bool onLeaveGroup(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/lllocationhistory.cpp b/indra/newview/lllocationhistory.cpp index 471a0868bc..68143fd1e3 100644 --- a/indra/newview/lllocationhistory.cpp +++ b/indra/newview/lllocationhistory.cpp @@ -47,6 +47,12 @@ void LLLocationHistory::addItem(std::string item) { static LLUICachedControl<S32> max_items("LocationHistoryMaxSize", 100); + std::vector<std::string>::iterator item_iter = std::find(mItems.begin(), mItems.end(), item); + + if (item_iter != mItems.end()) { + mItems.erase(item_iter); + } + mItems.push_back(item); // If the vector size exceeds the maximum, purge the oldest items. @@ -56,7 +62,7 @@ void LLLocationHistory::addItem(std::string item) void LLLocationHistory::removeItems() { - mItems.erase(mItems.begin(), mItems.end()); + mItems.clear(); } diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 94abd128c4..3880ea91eb 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -54,6 +54,7 @@ #include "llsidetray.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" +#include "llviewercontrol.h" //============================================================================ /* @@ -330,6 +331,13 @@ void LLLocationInputCtrl::onFocusLost() LLUICtrl::onFocusLost(); refreshLocation(); } +void LLLocationInputCtrl::draw(){ + + if(!hasFocus()){ + refreshLocation(); + } + LLComboBox::draw(); +} void LLLocationInputCtrl::onInfoButtonClicked() { @@ -341,8 +349,7 @@ void LLLocationInputCtrl::onAddLandmarkButtonClicked() LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); // Floater "Add Landmark" functionality moved to Side Tray - // TODO* Disable floater "Add Landmark" call - LLFloaterReg::showInstance("add_landmark"); + //LLFloaterReg::showInstance("add_landmark"); } void LLLocationInputCtrl::onAgentParcelChange() @@ -387,8 +394,10 @@ void LLLocationInputCtrl::refreshLocation() // Update location field. std::string location_name; + LLAgent::ELocationFormat format = (gSavedSettings.getBOOL("ShowCoordinatesOption") ? + LLAgent::LOCATION_FORMAT_FULL: LLAgent::LOCATION_FORMAT_NORMAL); - if (!gAgent.buildLocationString(location_name, LLAgent::LOCATION_FORMAT_NORMAL)) + if (!gAgent.buildLocationString(location_name,format)) location_name = "Unknown"; setText(location_name); diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index 2cc63a33b7..bda67fd313 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -71,6 +71,7 @@ public: /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); /*virtual*/ void onFocusReceived(); /*virtual*/ void onFocusLost(); + /*virtual*/ void draw(); //======================================================================== // LLUICtrl interface diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 963be61d93..124a2def7f 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -40,12 +40,17 @@ // Viewer includes #include "llagent.h" +#include "llvoavatarself.h" // to check gAgent.getAvatarObject()->isSitting() +#include "llbottomtray.h" #include "llbutton.h" +#include "llfirsttimetipmanager.h" #include "llfloaterreg.h" +#include "llfloaterfirsttimetip.h" #include "lljoystickbutton.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" #include "llviewercontrol.h" +#include "llselectmgr.h" // // Constants @@ -55,17 +60,24 @@ const F32 MOVE_BUTTON_DELAY = 0.0f; const F32 YAW_NUDGE_RATE = 0.05f; // fraction of normal speed const F32 NUDGE_TIME = 0.25f; // in seconds +const std::string BOTTOM_TRAY_BUTTON_NAME = "movement_btn"; + // // Member functions // // protected LLFloaterMove::LLFloaterMove(const LLSD& key) -: LLFloater(key) +: LLFloater(key), + mForwardButton(NULL), + mBackwardButton(NULL), + mTurnLeftButton(NULL), + mTurnRightButton(NULL), + mMoveUpButton(NULL), + mMoveDownButton(NULL), + mStopFlyingButton(NULL), + mModeActionsPanel(NULL) { - -// LLUICtrlFactory::getInstance()->buildFloater(this,"floater_moveview.xml", DONT_OPEN); - } // virtual @@ -80,36 +92,55 @@ BOOL LLFloaterMove::postBuild() mBackwardButton = getChild<LLJoystickAgentTurn>("backward btn"); mBackwardButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - mSlideLeftButton = getChild<LLJoystickAgentSlide>("slide left btn"); - mSlideLeftButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - - mSlideRightButton = getChild<LLJoystickAgentSlide>("slide right btn"); - mSlideRightButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - mTurnLeftButton = getChild<LLButton>("turn left btn"); mTurnLeftButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - mTurnLeftButton->setHeldDownCallback( turnLeft, NULL ); - + mTurnLeftButton->setHeldDownCallback(boost::bind(&LLFloaterMove::turnLeft, this)); mTurnRightButton = getChild<LLButton>("turn right btn"); mTurnRightButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - mTurnRightButton->setHeldDownCallback( turnRight, NULL ); + mTurnRightButton->setHeldDownCallback(boost::bind(&LLFloaterMove::turnRight, this)); mMoveUpButton = getChild<LLButton>("move up btn"); - childSetAction("move up btn",moveUp,NULL); mMoveUpButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - mMoveUpButton->setHeldDownCallback( moveUp, NULL ); + mMoveUpButton->setHeldDownCallback(boost::bind(&LLFloaterMove::moveUp, this)); mMoveDownButton = getChild<LLButton>("move down btn"); - childSetAction("move down btn",moveDown,NULL); mMoveDownButton->setHeldDownDelay(MOVE_BUTTON_DELAY); - mMoveDownButton->setHeldDownCallback( moveDown, NULL ); + mMoveDownButton->setHeldDownCallback(boost::bind(&LLFloaterMove::moveDown, this)); + + + mStopFlyingButton = getChild<LLButton>("stop_fly_btn"); + + mModeActionsPanel = getChild<LLPanel>("panel_modes"); + + LLButton* btn; + btn = getChild<LLButton>("mode_walk_btn"); + btn->setCommitCallback(boost::bind(&LLFloaterMove::onWalkButtonClick, this)); + + btn = getChild<LLButton>("mode_run_btn"); + btn->setCommitCallback(boost::bind(&LLFloaterMove::onRunButtonClick, this)); + + btn = getChild<LLButton>("mode_fly_btn"); + btn->setCommitCallback(boost::bind(&LLFloaterMove::onFlyButtonClick, this)); + + btn = getChild<LLButton>("stop_fly_btn"); + btn->setCommitCallback(boost::bind(&LLFloaterMove::onStopFlyingButtonClick, this)); + + + + showFlyControls(false); + + initModeTooltips(); + + updatePosition(); + + initModeButtonMap(); + + initMovementMode(); + return TRUE; } -// -// Static member functions -// -// protected static +// static F32 LLFloaterMove::getYawRate( F32 time ) { if( time < NUDGE_TIME ) @@ -123,38 +154,431 @@ F32 LLFloaterMove::getYawRate( F32 time ) } } -// protected static -void LLFloaterMove::turnLeft(void *) + +// static +void LLFloaterMove::setFlyingMode(BOOL fly) { - LLFloaterMove* instance = LLFloaterReg::getTypedInstance<LLFloaterMove>("moveview"); - if(!instance) return; - - F32 time = instance->mTurnLeftButton->getHeldDownTime(); + LLFloaterMove* instance = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview"); + if (instance) + { + instance->setFlyingModeImpl(fly); + instance->showModeButtons(!fly); + } + if (fly) + { + LLPanelStandStopFlying::setStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STOP_FLYING); + } + else + { + LLPanelStandStopFlying::clearStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STOP_FLYING); + } +} +//static +void LLFloaterMove::setAlwaysRunMode(bool run) +{ + LLFloaterMove* instance = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview"); + if (instance) + { + instance->setAlwaysRunModeImpl(run); + } +} + +void LLFloaterMove::setFlyingModeImpl(BOOL fly) +{ + updateButtonsWithMovementMode(fly ? MM_FLY : (gAgent.getAlwaysRun() ? MM_RUN : MM_WALK)); +} + +void LLFloaterMove::setAlwaysRunModeImpl(bool run) +{ + if (!gAgent.getFlying()) + { + updateButtonsWithMovementMode(run ? MM_RUN : MM_WALK); + } +} + +//static +void LLFloaterMove::setSittingMode(BOOL bSitting) +{ + if (bSitting) + { + LLPanelStandStopFlying::setStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STAND); + } + else + { + LLPanelStandStopFlying::clearStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STAND); + } + enableInstance(!bSitting); +} + +// protected +void LLFloaterMove::turnLeft() +{ + F32 time = mTurnLeftButton->getHeldDownTime(); gAgent.moveYaw( getYawRate( time ) ); } -// protected static -void LLFloaterMove::turnRight(void *) +// protected +void LLFloaterMove::turnRight() { - LLFloaterMove* instance = LLFloaterReg::getTypedInstance<LLFloaterMove>("moveview"); - if(!instance) return; - - F32 time = instance->mTurnRightButton->getHeldDownTime(); + F32 time = mTurnRightButton->getHeldDownTime(); gAgent.moveYaw( -getYawRate( time ) ); } -// protected static -void LLFloaterMove::moveUp(void *) +// protected +void LLFloaterMove::moveUp() { // Jumps or flys up, depending on fly state gAgent.moveUp(1); } -// protected static -void LLFloaterMove::moveDown(void *) +// protected +void LLFloaterMove::moveDown() { // Crouches or flys down, depending on fly state gAgent.moveUp(-1); } +////////////////////////////////////////////////////////////////////////// +// Private Section: +////////////////////////////////////////////////////////////////////////// + +void LLFloaterMove::onWalkButtonClick() +{ + setMovementMode(MM_WALK); +} +void LLFloaterMove::onRunButtonClick() +{ + setMovementMode(MM_RUN); +} +void LLFloaterMove::onFlyButtonClick() +{ + setMovementMode(MM_FLY); +} +void LLFloaterMove::onStopFlyingButtonClick() +{ + setMovementMode(gAgent.getAlwaysRun() ? MM_RUN : MM_WALK); +} + +void LLFloaterMove::setMovementMode(const EMovementMode mode) +{ + gAgent.setFlying(MM_FLY == mode); + + switch (mode) + { + case MM_RUN: + gAgent.setAlwaysRun(); + gAgent.setRunning(); + break; + case MM_WALK: + gAgent.clearAlwaysRun(); + gAgent.clearRunning(); + break; + default: + //do nothing for other modes (MM_FLY) + break; + } + // tell the simulator. + gAgent.sendWalkRun(gAgent.getAlwaysRun()); + + updateButtonsWithMovementMode(mode); + + bool bHideModeButtons = MM_FLY == mode + || (gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting()); + + showModeButtons(!bHideModeButtons); + + showQuickTips(mode); +} + +void LLFloaterMove::updateButtonsWithMovementMode(const EMovementMode newMode) +{ + showFlyControls(MM_FLY == newMode); + setModeTooltip(newMode); + setModeButtonToggleState(newMode); +} + +void LLFloaterMove::showFlyControls(bool bShow) +{ + mMoveUpButton->setVisible(bShow); + mMoveDownButton->setVisible(bShow); + + // *TODO: mantipov: mStopFlyingButton from the FloaterMove is not used now. + // It was not completly removed until functionality is reviewed by LL + mStopFlyingButton->setVisible(FALSE); +} + +void LLFloaterMove::initModeTooltips() +{ + control_tooltip_map_t walkTipMap; + walkTipMap.insert(std::make_pair(mForwardButton, getString("walk_forward_tooltip"))); + walkTipMap.insert(std::make_pair(mBackwardButton, getString("walk_back_tooltip"))); + mModeControlTooltipsMap[MM_WALK] = walkTipMap; + + control_tooltip_map_t runTipMap; + runTipMap.insert(std::make_pair(mForwardButton, getString("run_forward_tooltip"))); + runTipMap.insert(std::make_pair(mBackwardButton, getString("run_back_tooltip"))); + mModeControlTooltipsMap[MM_RUN] = runTipMap; + + control_tooltip_map_t flyTipMap; + flyTipMap.insert(std::make_pair(mForwardButton, getString("fly_forward_tooltip"))); + flyTipMap.insert(std::make_pair(mBackwardButton, getString("fly_back_tooltip"))); + mModeControlTooltipsMap[MM_FLY] = flyTipMap; + + setModeTooltip(MM_WALK); +} + +void LLFloaterMove::initModeButtonMap() +{ + mModeControlButtonMap[MM_WALK] = getChild<LLButton>("mode_walk_btn"); + mModeControlButtonMap[MM_RUN] = getChild<LLButton>("mode_run_btn"); + mModeControlButtonMap[MM_FLY] = getChild<LLButton>("mode_fly_btn"); +} + +void LLFloaterMove::initMovementMode() +{ + EMovementMode initMovementMode = gAgent.getAlwaysRun() ? MM_RUN : MM_WALK; + if (gAgent.getFlying()) + { + initMovementMode = MM_FLY; + } + setMovementMode(initMovementMode); + + if (gAgent.getAvatarObject()) + { + setEnabled(!gAgent.getAvatarObject()->isSitting()); + } +} + +void LLFloaterMove::setModeTooltip(const EMovementMode mode) +{ + llassert_always(mModeControlTooltipsMap.end() != mModeControlTooltipsMap.find(mode)); + control_tooltip_map_t controlsTipMap = mModeControlTooltipsMap[mode]; + control_tooltip_map_t::const_iterator it = controlsTipMap.begin(); + for (; it != controlsTipMap.end(); ++it) + { + LLView* ctrl = it->first; + std::string tooltip = it->second; + ctrl->setToolTip(tooltip); + } +} + +/** + * Updates position of the floater to be center aligned with Move button. + * + * Because Tip floater created as dependent floater this method + * must be called before "showQuickTips()" to get Tip floater be positioned at the right side of the floater + */ +void LLFloaterMove::updatePosition() +{ + LLBottomTray* tray = LLBottomTray::getInstance(); + if (!tray) return; + + LLButton* movement_btn = tray->getChild<LLButton>(BOTTOM_TRAY_BUTTON_NAME, TRUE, FALSE); + if (!movement_btn) return; + + //align centers of a button and a floater + S32 x = movement_btn->calcScreenRect().getCenterX() - getRect().getWidth()/2; + + S32 y = 0; + if (!mModeActionsPanel->getVisible()) + { + y = mModeActionsPanel->getRect().getHeight(); + } + setOrigin(x, y); +} +void LLFloaterMove::showModeButtons(BOOL bShow) +{ + if (mModeActionsPanel->getVisible() == bShow) + return; + mModeActionsPanel->setVisible(bShow); + + LLRect rect = getRect(); + + static S32 height = mModeActionsPanel->getRect().getHeight(); + S32 newHeight = getRect().getHeight(); + if (!bShow) + { + newHeight -= height; + } + else + { + newHeight += height; + } + rect.setLeftTopAndSize(rect.mLeft, rect.mTop, rect.getWidth(), newHeight); + reshape(rect.getWidth(), rect.getHeight()); + setRect(rect); +} +//static +void LLFloaterMove::enableInstance(BOOL bEnable) +{ + LLFloaterMove* instance = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview"); + if (instance) + { + instance->setEnabled(bEnable); + instance->showModeButtons(bEnable); + } +} + +void LLFloaterMove::onOpen(const LLSD& key) +{ + updatePosition(); +} + +void LLFloaterMove::showQuickTips(const EMovementMode mode) +{ + LLFirstTimeTipsManager::EFirstTimeTipType tipType = LLFirstTimeTipsManager::FTT_MOVE_WALK; + switch (mode) + { + case MM_FLY: tipType = LLFirstTimeTipsManager::FTT_MOVE_FLY; break; + case MM_RUN: tipType = LLFirstTimeTipsManager::FTT_MOVE_RUN; break; + case MM_WALK: tipType = LLFirstTimeTipsManager::FTT_MOVE_WALK; break; + default: llwarns << "Quick Tip type was not detected, FTT_MOVE_WALK will be used" << llendl; + } + + LLFirstTimeTipsManager::showTipsFor(tipType, this); +} + +void LLFloaterMove::setModeButtonToggleState(const EMovementMode mode) +{ + llassert_always(mModeControlButtonMap.end() != mModeControlButtonMap.find(mode)); + + mode_control_button_map_t::const_iterator it = mModeControlButtonMap.begin(); + for (; it != mModeControlButtonMap.end(); ++it) + { + it->second->setToggleState(FALSE); + } + + mModeControlButtonMap[mode]->setToggleState(TRUE); +} + + + +/************************************************************************/ +/* LLPanelStandStopFlying */ +/************************************************************************/ +LLPanelStandStopFlying::LLPanelStandStopFlying() : + mStandButton(NULL), + mStopFlyingButton(NULL) +{ + // make sure we have the only instance of this class + static bool b = true; + llassert_always(b); + b=false; +} + +// static +inline LLPanelStandStopFlying* LLPanelStandStopFlying::getInstance() +{ + static LLPanelStandStopFlying* panel = getStandStopFlyingPanel(); + return panel; +} + +//static +void LLPanelStandStopFlying::setStandStopFlyingMode(EStandStopFlyingMode mode) +{ + LLPanelStandStopFlying* panel = getInstance(); + panel->setVisible(TRUE); + + BOOL standVisible = SSFM_STAND == mode; + panel->mStandButton->setVisible(standVisible); + panel->mStopFlyingButton->setVisible(!standVisible); +} + +//static +void LLPanelStandStopFlying::clearStandStopFlyingMode(EStandStopFlyingMode mode) +{ + LLPanelStandStopFlying* panel = getInstance(); + switch(mode) { + case SSFM_STAND: + panel->mStandButton->setVisible(FALSE); + break; + case SSFM_STOP_FLYING: + panel->mStopFlyingButton->setVisible(FALSE); + break; + default: + llerrs << "Unexpected EStandStopFlyingMode is passed: " << mode << llendl; + } + +} + +BOOL LLPanelStandStopFlying::postBuild() +{ + mStandButton = getChild<LLButton>("stand_btn"); + mStandButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStandButtonClick, this)); + mStandButton->setCommitCallback(boost::bind(&LLFloaterMove::enableInstance, TRUE)); + + mStopFlyingButton = getChild<LLButton>("stop_fly_btn"); + mStopFlyingButton->setCommitCallback(boost::bind(&LLFloaterMove::setFlyingMode, FALSE)); + mStopFlyingButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStopFlyingButtonClick, this)); + + + return TRUE; +} + +//virtual +void LLPanelStandStopFlying::setVisible(BOOL visible) +{ + if (visible) + { + updatePosition(); + } + + LLPanel::setVisible(visible); +} + +////////////////////////////////////////////////////////////////////////// +// Private Section +////////////////////////////////////////////////////////////////////////// + +//static +LLPanelStandStopFlying* LLPanelStandStopFlying::getStandStopFlyingPanel() +{ + LLPanelStandStopFlying* panel = new LLPanelStandStopFlying(); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_stand_stop_flying.xml"); + + panel->setVisible(FALSE); + LLUI::getRootView()->addChild(panel); + + llinfos << "Build LLPanelStandStopFlying panel" << llendl; + + panel->updatePosition(); + return panel; +} + +void LLPanelStandStopFlying::onStandButtonClick() +{ + LLSelectMgr::getInstance()->deselectAllForStandingUp(); + gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + + setVisible(FALSE); +} + +void LLPanelStandStopFlying::onStopFlyingButtonClick() +{ + gAgent.setFlying(FALSE); + + setVisible(FALSE); +} + +/** + * Updates position of the Stand & Stop Flying panel to be center aligned with Move button. + */ +void LLPanelStandStopFlying::updatePosition() +{ + + LLBottomTray* tray = LLBottomTray::getInstance(); + if (!tray) return; + + LLButton* movement_btn = tray->getChild<LLButton>(BOTTOM_TRAY_BUTTON_NAME, TRUE, FALSE); + if (!movement_btn) return; + + //align centers of a button and a floater + S32 x = movement_btn->calcScreenRect().getCenterX() - getRect().getWidth()/2; + + S32 y = tray->getRect().getHeight(); + + setOrigin(x, y); +} + + // EOF diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h index 250315b9f2..fd9cf9f4c1 100644 --- a/indra/newview/llmoveview.h +++ b/indra/newview/llmoveview.h @@ -55,26 +55,106 @@ public: /*virtual*/ BOOL postBuild(); static F32 getYawRate(F32 time); + static void setFlyingMode(BOOL fly); + void setFlyingModeImpl(BOOL fly); + static void setAlwaysRunMode(bool run); + void setAlwaysRunModeImpl(bool run); + static void setSittingMode(BOOL bSitting); + static void enableInstance(BOOL bEnable); + /*virtual*/ void onOpen(const LLSD& key); + + // *HACK: due to hard enough to have this control aligned with "Move" button while resizing + // let update its position in each frame + /*virtual*/ void draw(){updatePosition(); LLFloater::draw();} + protected: - static void turnLeftNudge(void* userdata); - static void turnLeft(void* userdata); - - static void turnRightNudge(void* userdata); - static void turnRight(void* userdata); + void turnLeft(); + void turnRight(); - static void moveUp(void* userdata); - static void moveDown(void* userdata); + void moveUp(); + void moveDown(); + +private: + typedef enum movement_mode_t + { + MM_WALK, + MM_RUN, + MM_FLY + } EMovementMode; + void onWalkButtonClick(); + void onRunButtonClick(); + void onFlyButtonClick(); + void onStopFlyingButtonClick(); + void initMovementMode(); + void setMovementMode(const EMovementMode mode); + void showFlyControls(bool bShow); + void initModeTooltips(); + void setModeTooltip(const EMovementMode mode); + void showQuickTips(const EMovementMode mode); + void initModeButtonMap(); + void setModeButtonToggleState(const EMovementMode mode); + void updateButtonsWithMovementMode(const EMovementMode newMode); + void updatePosition(); + void showModeButtons(BOOL bShow); public: + LLJoystickAgentTurn* mForwardButton; LLJoystickAgentTurn* mBackwardButton; - LLJoystickAgentSlide* mSlideLeftButton; - LLJoystickAgentSlide* mSlideRightButton; LLButton* mTurnLeftButton; LLButton* mTurnRightButton; LLButton* mMoveUpButton; LLButton* mMoveDownButton; +private: + LLButton* mStopFlyingButton; + LLPanel* mModeActionsPanel; + + typedef std::map<LLView*, std::string> control_tooltip_map_t; + typedef std::map<EMovementMode, control_tooltip_map_t> mode_control_tooltip_map_t; + mode_control_tooltip_map_t mModeControlTooltipsMap; + + typedef std::map<EMovementMode, LLButton*> mode_control_button_map_t; + mode_control_button_map_t mModeControlButtonMap; + +}; + + +/** + * This class contains Stand Up and Stop Flying buttons displayed above Move button in bottom tray + */ +class LLPanelStandStopFlying : public LLPanel +{ +public: + typedef enum stand_stop_flying_mode_t + { + SSFM_STAND, + SSFM_STOP_FLYING + } EStandStopFlyingMode; + + static LLPanelStandStopFlying* getInstance(); + static void setStandStopFlyingMode(EStandStopFlyingMode mode); + static void clearStandStopFlyingMode(EStandStopFlyingMode mode); + /*virtual*/ BOOL postBuild(); + /*virtual*/ void setVisible(BOOL visible); + + // *HACK: due to hard enough to have this control aligned with "Move" button while resizing + // let update its position in each frame + /*virtual*/ void draw(){updatePosition(); LLPanel::draw();} + + +protected: + LLPanelStandStopFlying(); + + +private: + static LLPanelStandStopFlying* getStandStopFlyingPanel(); + void onStandButtonClick(); + void onStopFlyingButtonClick(); + void updatePosition(); + + LLButton* mStandButton; + LLButton* mStopFlyingButton; }; diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 58ec2d24a8..06cab9afb0 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -47,12 +47,15 @@ #include "lllocationinputctrl.h" #include "llteleporthistory.h" #include "llsearcheditor.h" +#include "llsidetray.h" #include "llslurl.h" #include "llurlsimstring.h" #include "llviewerinventory.h" #include "llviewermenu.h" #include "llviewerparcelmgr.h" #include "llworldmap.h" +#include "llappviewer.h" +#include "llviewercontrol.h" //-- LLTeleportHistoryMenuItem ----------------------------------------------- @@ -190,6 +193,9 @@ LLNavigationBar::LLNavigationBar() // navigation bar can never get a tab setFocusRoot(FALSE); + + // set a listener function for LoginComplete event + LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLNavigationBar::handleLoginComplete, this)); } LLNavigationBar::~LLNavigationBar() @@ -253,7 +259,7 @@ void LLNavigationBar::draw() LLPanel::draw(); } -BOOL LLNavigationBar::handleRightMouseDown(S32 x, S32 y, MASK mask) +BOOL LLNavigationBar::handleRightMouseUp(S32 x, S32 y, MASK mask) { // *HACK. We should use mCmbLocation's right click callback instead. @@ -271,7 +277,7 @@ BOOL LLNavigationBar::handleRightMouseDown(S32 x, S32 y, MASK mask) } return TRUE; } - return LLPanel:: handleRightMouseDown(x, y, mask); + return LLPanel:: handleRightMouseUp(x, y, mask); } void LLNavigationBar::onBackButtonClicked() @@ -410,21 +416,26 @@ void LLNavigationBar::onRegionNameResponse( } // Location is valid. Add it to the typed locations history. + // If user has typed text this variable will contain -1. S32 selected_item = mCmbLocation->getCurrentIndex(); - if (selected_item == -1) // user has typed text - { - LLLocationHistory* lh = LLLocationHistory::getInstance(); - mCmbLocation->add(typed_location); - lh->addItem(typed_location); - lh->save(); - } + + /* + LLLocationHistory* lh = LLLocationHistory::getInstance(); + lh->addItem(selected_item == -1 ? typed_location : mCmbLocation->getSelectedItemLabel()); + lh->save(); + */ // Teleport to the location. LLVector3d region_pos = from_region_handle(region_handle); LLVector3d global_pos = region_pos + (LLVector3d) local_coords; + llinfos << "Teleporting to: " << global_pos << llendl; gAgent.teleportViaLocation(global_pos); + + LLLocationHistory* lh = LLLocationHistory::getInstance(); + lh->addItem(selected_item == -1 ? typed_location : mCmbLocation->getSelectedItemLabel()); + lh->save(); } void LLNavigationBar::showTeleportHistoryMenu() @@ -456,18 +467,16 @@ void LLNavigationBar::onLocationContextMenuItemClicked(const LLSD& userdata) std::string item = userdata.asString(); LLLineEditor* location_entry = mCmbLocation->getTextEntry(); - if (item == std::string("copy_url")) + if (item == std::string("show_coordinates")) { - std::string sl_url = gAgent.getSLURL(); - LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(sl_url)); - - LLSD args; - args["SLURL"] = sl_url; - LLNotifications::instance().add("CopySLURL", args); + gSavedSettings.setBOOL("ShowCoordinatesOption",!gSavedSettings.getBOOL("ShowCoordinatesOption")); } else if (item == std::string("landmark")) { - LLFloaterReg::showInstance("add_landmark"); + LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); + + // Floater "Add Landmark" functionality moved to Side Tray + //LLFloaterReg::showInstance("add_landmark"); } else if (item == std::string("cut")) { @@ -519,6 +528,9 @@ bool LLNavigationBar::onLocationContextMenuItemEnabled(const LLSD& userdata) else if(item == std::string("can_landmark")) { return !LLLandmarkActions::landmarkAlreadyExists(); + }else if(item == std::string("show_coordinates")){ + + return gSavedSettings.getBOOL("ShowCoordinatesOption"); } return false; diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index a46c59306d..17a1438912 100644 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -56,7 +56,7 @@ public: /*virtual*/ void draw(); /*virtual*/ BOOL postBuild(); - /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); void handleLoginComplete(); void clearHistoryCache(); diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 847262ddfd..1fa1e2a09d 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -252,7 +252,8 @@ void LLNearbyChat::addMessage(const LLChat& chat) void LLNearbyChat::onNearbySpeakers() { - LLSD param = "nearby_panel"; + LLSD param; + param["people_panel_tab_name"] = "nearby_panel"; LLSideTray::getInstance()->showPanel("panel_people",param); } diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 7b67ae645c..a3100f65ca 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -50,6 +50,16 @@ void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 static LLDefaultChildRegistry::Register<LLGestureComboBox> r("gesture_combo_box"); +struct LLChatTypeTrigger { + std::string name; + EChatType type; +}; + +static LLChatTypeTrigger sChatTypeTriggers[] = { + { "/whisper" , CHAT_TYPE_WHISPER}, + { "/shout" , CHAT_TYPE_SHOUT} +}; + LLGestureComboBox::LLGestureComboBox(const LLComboBox::Params& p) : LLComboBox(p) , mGestureLabelTimer() @@ -219,12 +229,38 @@ BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask ) return handled; } +BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::string* out_str) +{ + U32 in_len = in_str.length(); + S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); + + for (S32 n = 0; n < cnt; n++) + { + if (in_len > sChatTypeTriggers[n].name.length()) + continue; + + std::string trigger_trunc = sChatTypeTriggers[n].name; + LLStringUtil::truncate(trigger_trunc, in_len); + + if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc)) + { + *out_str = sChatTypeTriggers[n].name; + return TRUE; + } + } + + return FALSE; +} + void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata) { + LLNearbyChatBar* self = (LLNearbyChatBar *)userdata; - LLWString raw_text; - if (self->mChatBox) raw_text = self->mChatBox->getWText(); + if (!self->mChatBox) + return; + + LLWString raw_text = self->mChatBox->getWText(); // Can't trim the end, because that will cause autocompletion // to eat trailing spaces that might be part of a gesture. @@ -270,16 +306,19 @@ void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata) if (gGestureManager.matchPrefix(utf8_trigger, &utf8_out_str)) { - if (self->mChatBox) - { - std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); - self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part - S32 outlength = self->mChatBox->getLength(); // in characters - - // Select to end of line, starting from the character - // after the last one the user typed. - self->mChatBox->setSelection(length, outlength); - } + std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); + self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part + S32 outlength = self->mChatBox->getLength(); // in characters + + // Select to end of line, starting from the character + // after the last one the user typed. + self->mChatBox->setSelection(length, outlength); + } + else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str)) + { + std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); + self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part + self->mChatBox->setCursorToEnd(); } //llinfos << "GESTUREDEBUG " << trigger @@ -296,6 +335,38 @@ void LLNearbyChatBar::onChatBoxFocusLost(LLFocusableElement* caller, void* userd gAgent.stopTyping(); } +EChatType LLNearbyChatBar::processChatTypeTriggers(EChatType type, std::string &str) +{ + U32 length = str.length(); + S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); + + for (S32 n = 0; n < cnt; n++) + { + if (length >= sChatTypeTriggers[n].name.length()) + { + std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length()); + + if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name)) + { + U32 trigger_length = sChatTypeTriggers[n].name.length(); + + // It's to remove space after trigger name + if (length > trigger_length && str[trigger_length] == ' ') + trigger_length++; + + str = str.substr(trigger_length, length); + + if (CHAT_TYPE_NORMAL == type) + return sChatTypeTriggers[n].type; + else + break; + } + } + } + + return type; +} + void LLNearbyChatBar::sendChat( EChatType type ) { if (mChatBox) @@ -324,6 +395,8 @@ void LLNearbyChatBar::sendChat( EChatType type ) utf8_revised_text = utf8str_trim(utf8_revised_text); + type = processChatTypeTriggers(type, utf8_revised_text); + if (!utf8_revised_text.empty()) { // Chat with animation diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index d1f5fbff6b..9c2a72aaf3 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -86,6 +86,7 @@ public: static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); protected: + static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str); static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata); static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata); @@ -93,6 +94,7 @@ protected: void onChatBoxCommit(); static LLWString stripChannelNumber(const LLWString &mesg, S32* channel); + EChatType processChatTypeTriggers(EChatType type, std::string &str); // Which non-zero channel did we last chat on? static S32 sLastSpecialChatChannel; diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index a24d1ed54a..0eb96f992a 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -231,7 +231,7 @@ void LLOverlayBar::refresh() BOOL sitting = FALSE; if (gAgent.getAvatarObject()) { - sitting = gAgent.getAvatarObject()->mIsSitting; + sitting = gAgent.getAvatarObject()->isSitting(); } button = getChild<LLButton>("Stand Up"); diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index f57489934a..91156ae542 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -269,7 +269,7 @@ void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType ty childSetValue("sl_description_edit", avatar_data->about_text); childSetValue("fl_description_edit",avatar_data->fl_about_text); childSetValue("2nd_life_pic", avatar_data->image_id); - childSetValue("1st_life_pic", avatar_data->fl_image_id); + childSetValue("real_world_pic", avatar_data->fl_image_id); childSetValue("homepage_edit", avatar_data->profile_url); if (!isEditMode()) @@ -365,7 +365,7 @@ void LLPanelAvatarProfile::clear() void LLPanelAvatarProfile::clearControls() { childSetValue("2nd_life_pic",LLUUID::null); - childSetValue("1st_life_pic",LLUUID::null); + childSetValue("real_world_pic",LLUUID::null); childSetValue("online_status",LLStringUtil::null); childSetValue("status_message",LLStringUtil::null); childSetValue("sl_description_edit",LLStringUtil::null); @@ -489,7 +489,7 @@ void LLPanelAvatarProfile::onShareButtonClick() { pic->setFallbackImageName("default_land_picture.j2c"); } - pic = getChild<LLTextureCtrl>("1st_life_pic",TRUE,FALSE); + pic = getChild<LLTextureCtrl>("real_world_pic",TRUE,FALSE); if(pic) { pic->setFallbackImageName("default_land_picture.j2c"); @@ -510,13 +510,13 @@ void LLPanelAvatarProfile::onOpen(const LLSD& key) void LLPanelAvatarProfile::updateChildrenList() { - if (mUpdated || isEditMode()) - { - return; - } switch (mProfileType) { case PT_OWN: + if (mUpdated || isEditMode()) + { + return; + } childSetVisible("user_name", true); childSetVisible("status_panel", false); childSetVisible("profile_buttons_panel", false); diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 92a8653252..2f63033437 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -539,7 +539,7 @@ void LLPanelPeople::updateButtons() } bool item_selected = selected_id.notNull(); - buttonSetEnabled("teleport_btn", friends_tab_active && item_selected); + buttonSetEnabled("teleport_btn", (friends_tab_active || group_tab_active) && item_selected); buttonSetEnabled("view_profile_btn", item_selected); buttonSetEnabled("im_btn", item_selected); buttonSetEnabled("call_btn", item_selected && false); // not implemented yet @@ -771,7 +771,16 @@ void LLPanelPeople::onCallButtonClicked() void LLPanelPeople::onTeleportButtonClicked() { - LLAvatarActions::offerTeleport(getCurrentItemID()); + std::string cur_tab = mTabContainer->getCurrentPanel()->getName(); + + if (cur_tab == FRIENDS_TAB_NAME) + { + LLAvatarActions::offerTeleport(getCurrentItemID()); + } + else if (cur_tab == GROUP_TAB_NAME) + { + LLGroupActions::offerTeleport(getCurrentItemID()); + } } void LLPanelPeople::onShareButtonClicked() @@ -786,22 +795,10 @@ void LLPanelPeople::onMoreButtonClicked() void LLPanelPeople::onOpen(const LLSD& key) { - // Profile View is activated through LLSideTray::showPanel(), - // hide Profile View to be able to see Panel People content - hideProfileView(); - - std::string tab_name = key.asString(); + std::string tab_name = key["people_panel_tab_name"]; if (!tab_name.empty()) mTabContainer->selectTabByName(tab_name); else reSelectedCurrentTab(); } -void LLPanelPeople::hideProfileView() -{ - LLView* view = getChildView("panel_profile_view",true,false); - if(view && view->getVisible()) - { - view->setVisible(false); - } -} diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 2ac1bf424c..6c3b5e0664 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -104,8 +104,6 @@ private: const std::vector<LLUUID>& ids, void*); - void hideProfileView(); - LLFilterEditor* mFilterEditor; LLTabContainer* mTabContainer; LLAvatarList* mFriendList; diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index ea05b666db..40275be82f 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -51,6 +51,7 @@ #include "llagent.h" #include "llfloaterworldmap.h" #include "llinventorymodel.h" +#include "lllandmarkactions.h" #include "lltexturectrl.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" @@ -487,6 +488,26 @@ void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type) } } +void LLPanelPlaceInfo::createLandmark(const LLUUID& folder_id) +{ + std::string name = mTitleEditor->getText(); + std::string desc = mNotesEditor->getText(); + + LLStringUtil::trim(name); + LLStringUtil::trim(desc); + + // If typed name is empty use the parcel name instead. + if (name.empty()) + { + name = mParcelName->getText() + "; " + mRegionName->getText(); + } + + LLStringUtil::replaceChar(desc, '\n', ' '); + // If no folder chosen use the "Landmarks" folder. + LLLandmarkActions::createLandmarkHere(name, desc, + folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK)); +} + void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent) { if (mMinHeight > 0) diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index f06a2d1fb7..e7b81dc3e6 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -79,6 +79,10 @@ public: // sets a corresponding title and contents. void setInfoType(INFO_TYPE type); + // Create a landmark for the current location + // in a folder specified by folder_id + void createLandmark(const LLUUID& folder_id); + BOOL isMediaPanelVisible(); void toggleMediaPanel(BOOL visible); void displayItemInfo(const LLInventoryItem* pItem); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index b443cc4d5e..1fb3eb8b71 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -39,6 +39,7 @@ #include "llnotifications.h" #include "llfiltereditor.h" #include "lltabcontainer.h" +#include "lltrans.h" #include "lluictrlfactory.h" #include "llagent.h" @@ -48,11 +49,15 @@ #include "llpanellandmarks.h" #include "llpanelteleporthistory.h" #include "llsidetray.h" +#include "lltoggleablemenu.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" -// Helper function to get local position from global -const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global); +// Helper functions +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 const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global); static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places"); @@ -63,6 +68,7 @@ LLPanelPlaces::LLPanelPlaces() mFilterEditor(NULL), mPlaceInfo(NULL), mItem(NULL), + mLandmarkFoldersMenuHandle(), mPosGlobal() { gInventory.addObserver(this); @@ -77,17 +83,25 @@ LLPanelPlaces::~LLPanelPlaces() { if (gInventory.containsObserver(this)) gInventory.removeObserver(this); + + LLView::deleteViewByHandle(mLandmarkFoldersMenuHandle); } BOOL LLPanelPlaces::postBuild() { + mCreateLandmarkBtn = getChild<LLButton>("create_landmark_btn"); + mCreateLandmarkBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onCreateLandmarkButtonClicked, this, LLUUID())); + + mFolderMenuBtn = getChild<LLButton>("folder_menu_btn"); + mFolderMenuBtn->setClickedCallback(boost::bind(&LLPanelPlaces::showLandmarkFoldersMenu, this)); + mTeleportBtn = getChild<LLButton>("teleport_btn"); mTeleportBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this)); mShowOnMapBtn = getChild<LLButton>("map_btn"); mShowOnMapBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this)); - //mShareBtn = getChild<LLButton>("share_btn"); + mShareBtn = getChild<LLButton>("share_btn"); //mShareBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShareButtonClicked, this)); mOverflowBtn = getChild<LLButton>("overflow_btn"); @@ -155,6 +169,11 @@ void LLPanelPlaces::onOpen(const LLSD& key) } else if (mPlaceInfoType == "remote_place") { + if (mPlaceInfo->isMediaPanelVisible()) + { + toggleMediaPanel(); + } + mPosGlobal = LLVector3d(key["x"].asReal(), key["y"].asReal(), key["z"].asReal()); @@ -323,20 +342,31 @@ void LLPanelPlaces::onShowOnMapButtonClicked() } } +void LLPanelPlaces::onCreateLandmarkButtonClicked(const LLUUID& folder_id) +{ + if (!mPlaceInfo) + return; + + mPlaceInfo->createLandmark(folder_id); + + onBackButtonClicked(); + LLSideTray::getInstance()->collapseSideBar(); +} + void LLPanelPlaces::onBackButtonClicked() { togglePlaceInfoPanel(FALSE); // Resetting mPlaceInfoType when Place Info panel is closed. mPlaceInfoType = LLStringUtil::null; - + updateVerbs(); } void LLPanelPlaces::toggleMediaPanel() { if (!mPlaceInfo) - return; + return; mPlaceInfo->toggleMediaPanel(!mPlaceInfo->isMediaPanelVisible()); } @@ -403,7 +433,7 @@ void LLPanelPlaces::onAgentParcelChange() { if (mPlaceInfo->getVisible() && (mPlaceInfoType == "agent" || mPlaceInfoType == "create_landmark")) { - LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", mPlaceInfoType)); + onOpen(LLSD().insert("type", mPlaceInfoType)); } else { @@ -415,9 +445,20 @@ void LLPanelPlaces::updateVerbs() { bool is_place_info_visible = mPlaceInfo->getVisible(); bool is_agent_place_info_visible = mPlaceInfoType == "agent"; + bool is_create_landmark_visible = mPlaceInfoType == "create_landmark"; + + mTeleportBtn->setVisible(!is_create_landmark_visible); + mShareBtn->setVisible(!is_create_landmark_visible); + mCreateLandmarkBtn->setVisible(is_create_landmark_visible); + mFolderMenuBtn->setVisible(is_create_landmark_visible); + + // Enable overflow button only when showing the information + // about agent's current location. + mOverflowBtn->setEnabled(is_agent_place_info_visible); + if (is_place_info_visible) { - if (is_agent_place_info_visible || mPlaceInfoType == "create_landmark") + if (is_agent_place_info_visible) { // We don't need to teleport to the current location so disable the button mTeleportBtn->setEnabled(FALSE); @@ -433,9 +474,205 @@ void LLPanelPlaces::updateVerbs() { mActivePanel->updateVerbs(); } +} + +void LLPanelPlaces::showLandmarkFoldersMenu() +{ + if (mLandmarkFoldersMenuHandle.isDead()) + { + LLMenuGL::Params menu_p; + menu_p.name("landmarks_folders_menu"); + menu_p.can_tear_off(false); + menu_p.visible(false); + menu_p.scrollable(true); + + LLToggleableMenu* menu = LLUICtrlFactory::create<LLToggleableMenu>(menu_p); + + mLandmarkFoldersMenuHandle = menu->getHandle(); + } + + LLToggleableMenu* menu = (LLToggleableMenu*)mLandmarkFoldersMenuHandle.get(); + if(!menu) + return; + + if (menu->getClosedByButtonClick()) + { + menu->resetClosedByButtonClick(); + return; + } + + if (menu->getVisible()) + { + menu->setVisible(FALSE); + menu->resetClosedByButtonClick(); + return; + } + + // Collect all folders that can contain landmarks. + LLInventoryModel::cat_array_t cats; + collectLandmarkFolders(cats); + + // Sort the folders by their full name. + folder_vec_t folders; + S32 count = cats.count(); + for (S32 i = 0; i < count; i++) + { + const LLViewerInventoryCategory* cat = cats.get(i); + std::string cat_full_name = getFullFolderName(cat); + folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name)); + } + sort(folders.begin(), folders.end(), cmp_folders); + + LLRect btn_rect = mFolderMenuBtn->getRect(); + + LLRect root_rect = getRootView()->getRect(); + + // Check it there are changed items or viewer dimensions + // have changed since last call + if (mLandmarkFoldersCache.size() == count && + mRootViewWidth == root_rect.getWidth() && + mRootViewHeight == root_rect.getHeight()) + { + S32 i; + for (i = 0; i < count; i++) + { + if (mLandmarkFoldersCache[i].second != folders[i].second) + { + break; + } + } + + // Check passed, just show the menu + if (i == count) + { + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); - // Enable overflow button only when showing the information about agent's current location. - mOverflowBtn->setEnabled(is_place_info_visible && is_agent_place_info_visible); + menu->setButtonRect(btn_rect, this); + LLMenuGL::showPopup(this, menu, btn_rect.mRight, btn_rect.mTop); + return; + } + } + + // If there are changes, store the new viewer dimensions + // and a list of folders + mRootViewWidth = root_rect.getWidth(); + mRootViewHeight = root_rect.getHeight(); + mLandmarkFoldersCache = folders; + + menu->empty(); + U32 max_width = 0; + + // Menu width must not exceed the root view limits, + // so we assume the space between the left edge of + // the root view and + LLRect screen_btn_rect; + localRectToScreen(btn_rect, &screen_btn_rect); + S32 free_space = screen_btn_rect.mRight; + + for(folder_vec_t::const_iterator it = mLandmarkFoldersCache.begin(); it != mLandmarkFoldersCache.end(); it++) + { + const std::string& item_name = it->second; + + LLMenuItemCallGL::Params item_params; + item_params.name(item_name); + item_params.label(item_name); + + item_params.on_click.function(boost::bind(&LLPanelPlaces::onCreateLandmarkButtonClicked, this, it->first)); + + LLMenuItemCallGL *menu_item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params); + + // Check whether item name wider than menu + if ((S32) menu_item->getNominalWidth() > free_space) + { + S32 chars_total = item_name.length(); + S32 chars_fitted = 1; + menu_item->setLabel(LLStringExplicit("")); + S32 label_space = free_space - menu_item->getFont()->getWidth("...") - + menu_item->getNominalWidth(); // This returns width of menu item with empty label (pad pixels) + + while (chars_fitted < chars_total && menu_item->getFont()->getWidth(item_name, 0, chars_fitted) < label_space) + { + chars_fitted++; + } + chars_fitted--; // Rolling back one char, that doesn't fit + + menu_item->setLabel(item_name.substr(0, chars_fitted) + "..."); + } + + max_width = llmax(max_width, menu_item->getNominalWidth()); + + menu->addChild(menu_item); + } + + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); + menu->setButtonRect(btn_rect, this); + LLMenuGL::showPopup(this, menu, btn_rect.mRight, btn_rect.mTop); +} + +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) +{ + std::string name = cat->getName(); + LLUUID parent_id; + + // translate category name, if it's right below the root + // FIXME: it can throw notification about non existent string in strings.xml + if (cat->getParentUUID().notNull() && cat->getParentUUID() == gInventory.getRootFolderID()) + { + name = LLTrans::getString("InvFolder " + name); + } + + // we don't want "My Inventory" to appear in the name + while ((parent_id = cat->getParentUUID()).notNull() && parent_id != gInventory.getRootFolderID()) + { + cat = gInventory.getCategory(parent_id); + name = cat->getName() + "/" + name; + } + + return name; +} + +static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats) +{ + // Add the "Landmarks" category itself. + LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); + LLViewerInventoryCategory* landmarks_cat = gInventory.getCategory(landmarks_id); + if (!landmarks_cat) + { + llwarns << "Cannot find the landmarks folder" << llendl; + } + else + { + cats.put(landmarks_cat); + } + + // Add descendent folders of the "Landmarks" category. + LLInventoryModel::item_array_t items; // unused + LLIsType is_category(LLAssetType::AT_CATEGORY); + gInventory.collectDescendentsIf( + landmarks_id, + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + is_category); + + // Add the "My Favorites" category. + LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE); + LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id); + if (!favorites_cat) + { + llwarns << "Cannot find the favorites folder" << llendl; + } + else + { + cats.put(favorites_cat); + } } const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global) @@ -445,4 +682,4 @@ const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global) LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]); return pos_local; -} +} diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index c100ace8cc..695c78cfba 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -47,6 +47,8 @@ class LLPanelPlacesTab; class LLFilterEditor; class LLTabContainer; +typedef std::pair<LLUUID, std::string> folder_pair_t; + class LLPanelPlaces : public LLPanel, LLInventoryObserver { public: @@ -69,6 +71,7 @@ private: //void onShareButtonClicked(); void onTeleportButtonClicked(); void onShowOnMapButtonClicked(); + void onCreateLandmarkButtonClicked(const LLUUID& folder_id); void onBackButtonClicked(); void toggleMediaPanel(); @@ -76,15 +79,19 @@ private: void onAgentParcelChange(); void updateVerbs(); + + void showLandmarkFoldersMenu(); LLFilterEditor* mFilterEditor; LLPanelPlacesTab* mActivePanel; LLTabContainer* mTabContainer; LLPanelPlaceInfo* mPlaceInfo; - //LLButton* mShareBtn; + LLButton* mCreateLandmarkBtn; + LLButton* mFolderMenuBtn; LLButton* mTeleportBtn; LLButton* mShowOnMapBtn; + LLButton* mShareBtn; LLButton* mOverflowBtn; // Pointer to a landmark item or to a linked landmark @@ -100,6 +107,20 @@ private: // Information type currently shown in Place Information panel std::string mPlaceInfoType; + + // Menu handle for pop-up menu to chose a landmark saving + // folder when creating a new landmark + LLHandle<LLView> mLandmarkFoldersMenuHandle; + + typedef std::vector<folder_pair_t> folder_vec_t; + + // List of folders to choose from when creating a landmark + folder_vec_t mLandmarkFoldersCache; + + // If root view width or height is changed + // the pop-up menu must be updated + S32 mRootViewWidth; + S32 mRootViewHeight; }; #endif //LL_LLPANELPLACES_H diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index deca08050b..f97105caa8 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -35,6 +35,8 @@ #include "lltabcontainer.h" #include "llpanelpicks.h" #include "llagent.h" +#include "llcommandhandler.h" +#include "llavataractions.h" static const std::string PANEL_PICKS = "panel_picks"; static const std::string PANEL_NOTES = "panel_notes"; @@ -44,6 +46,33 @@ static LLRegisterPanelClassWrapper<LLPanelAvatarProfile> t_panel_profile(PANEL_P static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks(PANEL_PICKS); +class LLAgentHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLAgentHandler() : LLCommandHandler("agent", true) { } + + bool handle(const LLSD& params, const LLSD& query_map, + LLWebBrowserCtrl* web) + { + if (params.size() < 2) return false; + LLUUID agent_id; + if (!agent_id.set(params[0], FALSE)) + { + return false; + } + + if (params[1].asString() == "about") + { + LLAvatarActions::showProfile(agent_id); + return true; + } + return false; + } +}; +LLAgentHandler gAgentHandler; + + LLPanelProfile::LLPanelProfile() : LLPanel(), mTabContainer(NULL) @@ -68,25 +97,6 @@ BOOL LLPanelProfile::postBuild() return TRUE; } -void LLPanelProfile::onOpen(const LLSD& key) -{ - //*NOTE LLUUID::null in this context means Agent related stuff - LLUUID id(key.has("id") ? key["id"].asUUID() : gAgentID); - if (key.has("open_tab_name")) - mTabContainer->selectTabByName(key["open_tab_name"]); - - if(id.notNull() && mAvatarId.notNull() && mAvatarId != id) - { - mTabs[PANEL_PROFILE]->clear(); - mTabs[PANEL_PICKS]->clear(); - mTabs[PANEL_NOTES]->clear(); - } - - mAvatarId = id; - - mTabContainer->getCurrentPanel()->onOpen(mAvatarId); -} - //*TODO redo panel toggling void LLPanelProfile::togglePanel(LLPanel* panel) { diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index e8aea849df..2f6d53a859 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -46,7 +46,7 @@ class LLPanelProfile : public LLPanel public: virtual BOOL postBuild(); - virtual void onOpen(const LLSD& key); + virtual void onOpen(const LLSD& key) {}; virtual void togglePanel(LLPanel*); diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp index 7d02c8ff0b..00254ee8ee 100644 --- a/indra/newview/llpanelprofileview.cpp +++ b/indra/newview/llpanelprofileview.cpp @@ -35,6 +35,7 @@ #include "llpanelavatar.h" #include "llpanelpicks.h" +#include "llsidetraypanelcontainer.h" #include "llpanelprofile.h" static LLRegisterPanelClassWrapper<LLPanelProfileView> t_panel_target_profile("panel_profile_view"); @@ -56,15 +57,23 @@ LLPanelProfileView::~LLPanelProfileView(void) /*virtual*/ void LLPanelProfileView::onOpen(const LLSD& key) { - LLPanelProfile::onOpen(key); - - //*NOTE profile view panel doesn't have own side tray tab and - //is usually opened over People side tray tab. By Back button - // Profile View panel just becomes invisible, see onBackBtnClick() - setVisible(TRUE); + LLUUID id = key["id"]; + if (key.has("open_tab_name")) + mTabContainer->selectTabByName(key["open_tab_name"]); + + if(id.notNull() && mAvatarId != id) + { + mAvatarId = id; + + mTabs[PANEL_PROFILE]->clear(); + mTabs[PANEL_PICKS]->clear(); + mTabs[PANEL_NOTES]->clear(); + } + + mTabContainer->getCurrentPanel()->onOpen(mAvatarId); std::string full_name; - gCacheName->getFullName(key["id"],full_name); + gCacheName->getFullName(mAvatarId,full_name); childSetValue("user_name",full_name); } @@ -85,5 +94,9 @@ BOOL LLPanelProfileView::postBuild() void LLPanelProfileView::onBackBtnClick() { - setVisible(FALSE); + LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent()); + if(parent) + { + parent->openPreviousPanel(); + } } diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 5dca12e06b..5ae79f6c63 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -59,6 +59,7 @@ LLScreenChannel::LLScreenChannel(): mUnreadToastsPanel(NULL), //TODO: load as a resource string mOverflowFormatString = "You have %d more notification"; + mToastList.clear(); setMouseOpaque( false ); } @@ -266,7 +267,7 @@ void LLScreenChannel::showToastsBottom() { mHiddenToastsNum++; } - createOverflowToast(bottom); + createOverflowToast(bottom, gSavedSettings.getS32("NotificationToastTime")); } } @@ -319,7 +320,7 @@ void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer) mUnreadToastsPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true); toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), getRect().getWidth(), toast_rect.getHeight()); mUnreadToastsPanel->setRect(toast_rect); - mUnreadToastsPanel->setAndStartTimer(timer ? timer : gSavedSettings.getS32("NotificationToastTime")); + mUnreadToastsPanel->setAndStartTimer(timer); getRootView()->addChild(mUnreadToastsPanel); text_box->setValue(text); @@ -337,14 +338,19 @@ void LLScreenChannel::onOverflowToastHide() } //-------------------------------------------------------------------------- -void LLScreenChannel::hideToastsFromScreen() +void LLScreenChannel::closeUnreadToastsPanel() { - if(mUnreadToastsPanel) + if(mUnreadToastsPanel != NULL) { mUnreadToastsPanel->close(); - delete mUnreadToastsPanel; mUnreadToastsPanel = NULL; } +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::hideToastsFromScreen() +{ + closeUnreadToastsPanel(); for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++) (*it).toast->setVisible(FALSE); } diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h index f05c205e2a..a205b913ab 100644 --- a/indra/newview/llscreenchannel.h +++ b/indra/newview/llscreenchannel.h @@ -73,6 +73,7 @@ public: void setHovering(bool hovering) { mIsHovering = hovering; } void removeToastsFromChannel(); + void closeUnreadToastsPanel(); void hideToastsFromScreen(); void setStoreToasts(bool store) { mStoreToasts = store; } @@ -125,7 +126,7 @@ private: void showToastsCentre(); void showToastsTop(); - void createOverflowToast(S32 bottom, F32 timer = 0); + void createOverflowToast(S32 bottom, F32 timer); void onOverflowToastHide(); static bool mWasStartUpToastShown; diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 2688399139..5f0fbe6ee5 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -44,6 +44,7 @@ #include "llfloater.h" //for gFloaterView #include "lliconctrl.h"//for Home tab icon +#include "llsidetraypanelcontainer.h" #include "llwindow.h"//for SetCursor //#include "llscrollcontainer.h" @@ -609,9 +610,22 @@ LLPanel* LLSideTray::showPanel (const std::string& panel_name, const LLSD& para if(view) { onTabButtonClick((*child_it)->getName()); + + LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(view->getParent()); + if(container) + { + LLSD new_params = params; + new_params[LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME] = panel_name; + container->onOpen(new_params); + + return container->getCurrentPanel(); + } + LLPanel* panel = dynamic_cast<LLPanel*>(view); if(panel) + { panel->onOpen(params); + } return panel; } } diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index 99e84f8141..1f8b6b402f 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -163,6 +163,7 @@ public: /** * Activate tab with "panel_name" panel * if no such tab - return NULL, otherwise a pointer to the panel + * Pass params as array, or they may be overwritten(example - params["name"]="nearby") */ LLPanel* showPanel (const std::string& panel_name, const LLSD& params); diff --git a/indra/newview/llsidetraypanelcontainer.cpp b/indra/newview/llsidetraypanelcontainer.cpp new file mode 100644 index 0000000000..21061a802a --- /dev/null +++ b/indra/newview/llsidetraypanelcontainer.cpp @@ -0,0 +1,89 @@ +/** +* @file llsidetraypanelcontainer.cpp +* @brief LLSideTrayPanelContainer implementation +* +* $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 "llsidetraypanelcontainer.h" + +static LLDefaultChildRegistry::Register<LLSideTrayPanelContainer> r2("panel_container"); + +std::string LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME = "sub_panel_name"; + +LLSideTrayPanelContainer::Params::Params() +{ + // Always hide tabs. + hide_tabs(true); +} + +LLSideTrayPanelContainer::LLSideTrayPanelContainer(const Params& p) + : LLTabContainer(p) +{ +} + +void LLSideTrayPanelContainer::onOpen(const LLSD& key) +{ + // Select specified panel and save navigation history. + if(key.has(PARAM_SUB_PANEL_NAME)) + { + // Save panel navigation history + std::string panel_name = key[PARAM_SUB_PANEL_NAME]; + S32 old_index = getCurrentPanelIndex(); + + selectTabByName(panel_name); + + S32 new_index = getCurrentPanelIndex(); + + // Don't update navigation history if we are opening same panel again. + if(old_index != new_index) + { + mPanelHistory[panel_name] = old_index; + } + } + // Will reopen current panel if no panel name was passed. + getCurrentPanel()->onOpen(key); +} + +void LLSideTrayPanelContainer::openPreviousPanel() +{ + std::string current_panel_name = getCurrentPanel()->getName(); + panel_navigation_history_t::const_iterator it = mPanelHistory.find(current_panel_name); + if(mPanelHistory.end() != it) + { + selectTab(it->second); + } +} + +BOOL LLSideTrayPanelContainer::handleKeyHere(KEY key, MASK mask) +{ + // No key press handling code for Panel Container - this disables + // Tab Container's Alt + Left/Right Button tab switching. + return TRUE; +} diff --git a/indra/newview/llsidetraypanelcontainer.h b/indra/newview/llsidetraypanelcontainer.h new file mode 100644 index 0000000000..3f3cb552f8 --- /dev/null +++ b/indra/newview/llsidetraypanelcontainer.h @@ -0,0 +1,95 @@ +/** +* @file llsidetraypanelcontainer.h +* @brief LLSideTrayPanelContainer class declaration +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#ifndef LL_LLSIDETRAY_PANEL_CONTAINER_H +#define LL_LLSIDETRAY_PANEL_CONTAINER_H + +#include "lltabcontainer.h" + +/** +* LLSideTrayPanelContainer class acts like LLTabContainer with invisible tabs. +* It is designed to make panel switching easier, avoid setVisible(TRUE) setVisible(FALSE) +* calls and related workarounds. +* use onOpen to open sub panel, pass the name of panel to open +* in key[PARAM_SUB_PANEL_NAME]. +* LLSideTrayPanelContainer also implements panel navigation history - it allows to +* open previous or next panel if navigation history is available(after user +* has opened two or more panels). *NOTE - only back navigation is implemented so far. +*/ +class LLSideTrayPanelContainer : public LLTabContainer +{ +public: + + struct Params : public LLInitParam::Block<Params, LLTabContainer::Params> + { + Params(); + }; + + /** + * Opens sub panel + * @param key - params to be passed to panel, use key[PARAM_SUB_PANEL_NAME] + * to specify panel name to be opened. + */ + /*virtual*/ void onOpen(const LLSD& key); + + /** + * Opens previous panel from panel navigation history. + */ + void openPreviousPanel(); + + /** + * Overrides LLTabContainer::handleKeyHere to disable panel switch on + * Alt + Left/Right button press. + */ + BOOL handleKeyHere(KEY key, MASK mask); + + /** + * Name of parameter that stores panel name to open. + */ + static std::string PARAM_SUB_PANEL_NAME; + +protected: + LLSideTrayPanelContainer(const Params& p); + friend class LLUICtrlFactory; + + /** + * std::string - name of panel + * S32 - index of previous panel + * *NOTE - no forward navigation implemented yet + */ + typedef std::map<std::string, S32> panel_navigation_history_t; + + // Navigation history + panel_navigation_history_t mPanelHistory; +}; + +#endif //LL_LLSIDETRAY_PANEL_CONTAINER_H diff --git a/indra/newview/llsplitbutton.cpp b/indra/newview/llsplitbutton.cpp new file mode 100644 index 0000000000..ffd9bc7624 --- /dev/null +++ b/indra/newview/llsplitbutton.cpp @@ -0,0 +1,275 @@ +/** + * @file llsplitbutton.cpp + * @brief LLSplitButton base class + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +// A control that consolidates several buttons as options + +#include "llviewerprecompiledheaders.h" + +#include "llsplitbutton.h" + +#include "llinitparam.h" +#include "llpanel.h" +#include "llfocusmgr.h" +#include "llviewerwindow.h" +#include "llrootview.h" + + +S32 BUTTON_PAD = 2; //pad between buttons on an items panel + + +static LLDefaultChildRegistry::Register<LLSplitButton> split_button("split_button"); + +void LLSplitButton::ArrowPositionValues::declareValues() +{ + declare("left", LEFT); + declare("right", RIGHT); +} + +LLSplitButton::ItemParams::ItemParams() +{ +} + +LLSplitButton::Params::Params() +: arrow_position("arrow_position", LEFT), + items("item"), + arrow_button("arrow_button"), + items_panel("items_panel") +{ +} + + +void LLSplitButton::onFocusLost() +{ + hideButtons(); + LLUICtrl::onFocusLost(); +} + +void LLSplitButton::setFocus(BOOL b) +{ + LLUICtrl::setFocus(b); + + if (b) + { + if (mItemsPanel && mItemsPanel->getVisible()) + { + mItemsPanel->setFocus(TRUE); + } + } +} + +void LLSplitButton::setEnabled(BOOL enabled) +{ + LLView::setEnabled(enabled); + mArrowBtn->setEnabled(enabled); +} + + +void LLSplitButton::onArrowBtnDown() +{ + if (!mItemsPanel->getVisible()) + { + showButtons(); + + setFocus(TRUE); + + if (mArrowBtn->hasMouseCapture() || mShownItem->hasMouseCapture()) + { + gFocusMgr.setMouseCapture(this); + } + } + else + { + hideButtons(); + } +} + +void LLSplitButton::onHeldDownShownButton() +{ + if (!mItemsPanel->getVisible()) onArrowBtnDown(); +} + +void LLSplitButton::onItemSelected(LLUICtrl* ctrl) +{ + if (!ctrl) return; + + hideButtons(); + + // call the callback if it exists + if(!mSelectionCallback.empty()) + { + mSelectionCallback(this, ctrl->getName()); + } + + gFocusMgr.setKeyboardFocus(NULL); +} + +BOOL LLSplitButton::handleMouseUp(S32 x, S32 y, MASK mask) +{ + gFocusMgr.setMouseCapture(NULL); + + if (mShownItem->parentPointInView(x, y)) + { + onItemSelected(mShownItem); + return TRUE; + } + + for (std::list<LLButton*>::const_iterator it = mHidenItems.begin(); it != mHidenItems.end(); ++it) + { + LLButton* item = *it; + + S32 panel_x = 0; + S32 panel_y = 0; + localPointToOtherView(x, y, &panel_x, &panel_y, mItemsPanel); + + if (item->parentPointInView(panel_x, panel_y)) + { + onItemSelected(item); + return TRUE; + } + } + return TRUE; +} + +void LLSplitButton::showButtons() +{ + mItemsPanel->setOrigin(0, getRect().getHeight()); + + // register ourselves as a "top" control + // effectively putting us into a special draw layer + gFocusMgr.setTopCtrl(this); + + mItemsPanel->setFocus(TRUE); + + //push arrow button down and show the item buttons + mArrowBtn->setToggleState(TRUE); + mItemsPanel->setVisible(TRUE); + + setUseBoundingRect(TRUE); +} + +void LLSplitButton::hideButtons() +{ + mItemsPanel->setVisible(FALSE); + mArrowBtn->setToggleState(FALSE); + + setUseBoundingRect(FALSE); + if(gFocusMgr.getTopCtrl() == this) + { + gFocusMgr.setTopCtrl(NULL); + } +} + + +// protected/private + +LLSplitButton::LLSplitButton(const LLSplitButton::Params& p) +: LLUICtrl(p), + mArrowBtn(NULL), + mShownItem(NULL), + mItemsPanel(NULL), + mArrowPosition(p.arrow_position) +{ + LLRect rc(p.rect); + + LLButton::Params arrow_params = p.arrow_button; + S32 arrow_width = p.arrow_button.rect.width; + + //Default arrow rect values for LEFT arrow position + S32 arrow_left = 0; + S32 arrow_right = arrow_width; + S32 btn_left = arrow_width; + S32 btn_right = rc.getWidth(); + + if (mArrowPosition == RIGHT) + { + arrow_left = rc.getWidth()- arrow_width; + arrow_right = rc.getWidth(); + btn_left = 0; + btn_right = arrow_left; + } + + arrow_params.rect(LLRect(arrow_left, rc.getHeight(), arrow_right, 0)); + arrow_params.label(""); + arrow_params.mouse_down_callback.function(boost::bind(&LLSplitButton::onArrowBtnDown, this)); + mArrowBtn = LLUICtrlFactory::create<LLButton>(arrow_params); + addChild(mArrowBtn); + + //a panel for hidden item buttons + LLPanel::Params panel_params = p.items_panel; + mItemsPanel= prepareItemsPanel(panel_params, p.items.numValidElements()); + addChild(mItemsPanel); + + + LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items().begin(); + + //processing shown item button + mShownItem = prepareItemButton(*it); + mShownItem->setHeldDownCallback(boost::bind(&LLSplitButton::onHeldDownShownButton, this)); + mShownItem->setMouseUpCallback(boost::bind(&LLSplitButton::onItemSelected, this, _1)); + mShownItem->setRect(LLRect(btn_left, rc.getHeight(), btn_right, 0)); + addChild(mShownItem); + + //processing hidden item buttons + S32 item_top = mItemsPanel->getRect().getHeight(); + for (++it; it != p.items().end(); ++it) + { + LLButton* hidden_button = prepareItemButton(*it); + hidden_button->setRect(LLRect(btn_left, item_top, btn_right, item_top - rc.getHeight())); + hidden_button->setMouseDownCallback(boost::bind(&LLSplitButton::onItemSelected, this, _1)); + mHidenItems.push_back(hidden_button); + mItemsPanel->addChild(hidden_button); + + //calculate next button's top + item_top -= (rc.getHeight() + BUTTON_PAD); + } + + setTopLostCallback(boost::bind(&LLSplitButton::hideButtons, this)); +} + + +LLButton* LLSplitButton::prepareItemButton(LLButton::Params params) +{ + params.label(""); + params.is_toggle(false); + return LLUICtrlFactory::create<LLButton>(params); +} + +LLPanel* LLSplitButton::prepareItemsPanel(LLPanel::Params params, S32 items_count) +{ + S32 num_hiden_btns = items_count - 1; + S32 panel_height = num_hiden_btns * (getRect().getHeight() + BUTTON_PAD); + params.visible(false); + params.rect.width(getRect().getWidth()); + params.rect.height(panel_height); + return LLUICtrlFactory::create<LLPanel>(params); +} + diff --git a/indra/newview/llsplitbutton.h b/indra/newview/llsplitbutton.h new file mode 100644 index 0000000000..0fb5f6594e --- /dev/null +++ b/indra/newview/llsplitbutton.h @@ -0,0 +1,112 @@ +/** + * @file llsplitbutton.h + * @brief LLSplitButton base class + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +// A control that displays the name of the chosen item, which when clicked +// shows a scrolling box of choices. + + +#include "llbutton.h" +#include "llpanel.h" +#include "lluictrl.h" + + +#ifndef LL_LLSPLITBUTTON_H +#define LL_LLSPLITBUTTON_H + +class LLSplitButton + : public LLUICtrl +{ +public: + typedef enum e_arrow_position + { + LEFT, + RIGHT + } EArrowPosition; + + struct ArrowPositionValues : public LLInitParam::TypeValuesHelper<EArrowPosition, ArrowPositionValues> + { + static void declareValues(); + }; + + struct ItemParams : public LLInitParam::Block<ItemParams, LLButton::Params> + { + ItemParams(); + }; + + struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> + { + Optional<EArrowPosition, ArrowPositionValues> arrow_position; + Optional<LLButton::Params> arrow_button; + Optional<LLPanel::Params> items_panel; + Multiple<ItemParams> items; + + Params(); + }; + + + virtual ~LLSplitButton() {}; + + //Overridden + virtual void onFocusLost(); + virtual void setFocus(BOOL b); + virtual void setEnabled(BOOL enabled); + + //Callbacks + void onArrowBtnDown(); + void onHeldDownShownButton(); + void onItemSelected(LLUICtrl* ctrl); + void setSelectionCallback(commit_callback_t cb) { mSelectionCallback = cb; } + + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + + virtual void showButtons(); + virtual void hideButtons(); + + +protected: + friend class LLUICtrlFactory; + LLSplitButton(const LLSplitButton::Params& p); + + LLButton* prepareItemButton(LLButton::Params params); + LLPanel* prepareItemsPanel(LLPanel::Params params, S32 items_count); + + LLPanel* mItemsPanel; + std::list<LLButton*> mHidenItems; + LLButton* mArrowBtn; + LLButton* mShownItem; + EArrowPosition mArrowPosition; + + commit_callback_t mSelectionCallback; +}; + + +#endif diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 6f5b25214e..0d4c75b507 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -36,6 +36,7 @@ #include "llbutton.h" #include "llfocusmgr.h" +#include "llviewercontrol.h" using namespace LLNotificationsUI; @@ -48,7 +49,8 @@ LLToast::LLToast(LLPanel* panel) : mCanFade(true), mHideBtn(NULL), mIsModal(false), - mCanBeStored(true) + mCanBeStored(true), + mHideBtnPressed(false) { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_toast.xml"); @@ -104,8 +106,7 @@ bool LLToast::timerHasExpired() if (mTimer.getStarted()) { F32 elapsed_time = mTimer.getElapsedTimeF32(); - // after 4 seconds a toast should start fade - if (elapsed_time > 4) + if (elapsed_time > gSavedSettings.getS32("ToastOpaqueTime")) { setBackgroundOpaque(FALSE); } @@ -218,6 +219,7 @@ void LLToast::onMouseEnter(S32 x, S32 y, MASK mask) //-------------------------------------------------------------------------- void LLToast::onMouseLeave(S32 x, S32 y, MASK mask) { + llinfos << "MOUSE LEAVE: x = " << x << "y = " << y << llendl; mOnToastHover(this, MOUSE_LEAVE); if(mCanFade && !mIsViewed) @@ -226,14 +228,26 @@ void LLToast::onMouseLeave(S32 x, S32 y, MASK mask) } if(mHideBtn && mHideBtn->getEnabled()) { - if( mHideBtn->getRect().pointInRect(x, y) ) + if( mHideBtnPressed ) + { + mHideBtnPressed = false; return; - mHideBtn->setVisible(FALSE); + } + mHideBtn->setVisible(FALSE); } } //-------------------------------------------------------------------------- +BOOL LLToast::handleMouseDown(S32 x, S32 y, MASK mask) +{ + if(mHideBtn && mHideBtn->getEnabled()) + { + mHideBtnPressed = mHideBtn->getRect().pointInRect(x, y); + } + + return LLFloater::handleMouseDown(x, y, mask); +} diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index 018664f3d1..f998754585 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -55,6 +55,7 @@ public: LLToast(LLPanel* panel); virtual ~LLToast(); + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); // bool isViewed() { return mIsViewed; } @@ -109,6 +110,7 @@ private: bool mCanFade; bool mIsModal; bool mCanBeStored; + bool mHideBtnPressed; }; } diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index 477e452907..5478e0005a 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -253,7 +253,7 @@ void LLToolBar::refresh() BOOL sitting = FALSE; if (gAgent.getAvatarObject()) { - sitting = gAgent.getAvatarObject()->mIsSitting; + sitting = gAgent.getAvatarObject()->isSitting(); } if (!gAgent.canFly()) diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index ee6e36518f..297cf2c667 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -56,6 +56,8 @@ #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llmorphview.h" +#include "llfloaterreg.h" +#include "llfloatercamera.h" // Globals BOOL gCameraBtnZoom = TRUE; @@ -254,7 +256,11 @@ void LLToolCamera::releaseMouse() gViewerWindow->showCursor(); - LLToolMgr::getInstance()->clearTransientTool(); + //for the situation when left click was performed on the Agent + if (!LLFloaterCamera::inFreeCameraMode()) + { + LLToolMgr::getInstance()->clearTransientTool(); + } mMouseSteering = FALSE; mValidClickPoint = FALSE; diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 350657538b..fab336f17d 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -42,7 +42,6 @@ #include "llagent.h" #include "llviewercontrol.h" #include "llfirstuse.h" -#include "llfloateravatarinfo.h" #include "llfloaterland.h" #include "llfloaterreg.h" #include "llfloaterscriptdebug.h" @@ -190,7 +189,7 @@ BOOL LLToolPie::pickLeftMouseDownCallback() // touch behavior down below... break; case CLICK_ACTION_SIT: - if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->mIsSitting)) // agent not already sitting + if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->isSitting())) // agent not already sitting { handle_sit_or_stand(); return TRUE; @@ -362,7 +361,7 @@ ECursorType cursor_from_object(LLViewerObject* object) switch(click_action) { case CLICK_ACTION_SIT: - if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->mIsSitting)) // not already sitting? + if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->isSitting())) // not already sitting? { cursor = UI_CURSOR_TOOLSIT; } diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 5c38be86d5..034bb9b88d 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -42,7 +42,6 @@ #include "llfloateractivespeakers.h" #include "llfloaterauction.h" #include "llfloateraddlandmark.h" -#include "llfloateravatarinfo.h" #include "llfloaterbeacons.h" #include "llfloaterbulkpermission.h" #include "llfloaterbuildoptions.h" @@ -51,6 +50,7 @@ #include "llfloaterchat.h" #include "llfloaterchatterbox.h" #include "llfloaterdirectory.h" +#include "llfloaterfirsttimetip.h" #include "llfloaterfonttest.h" #include "llfloatergodtools.h" #include "llfloaterhtmlcurrency.h" @@ -114,6 +114,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>); LLFloaterReg::add("contacts", "floater_my_friends.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMyFriends>); + LLFloaterReg::add("first_time_tip", "floater_first_time_tip.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFirstTimeTip>); LLFloaterReg::add("font_test", "floater_font_test.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFontTest>); LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>); @@ -127,7 +128,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>); LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>); - LLFloaterReg::add("me_profile", "floater_me.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarInfo>); LLFloaterReg::add("media_browser", "floater_media_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaBrowser>); LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>); LLFloaterReg::add("mute", "floater_mute.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMute>); @@ -144,7 +144,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("preview_url", "floater_preview_url.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterURLDisplay>); LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>); LLFloaterReg::add("pref_voicedevicesettings", "floater_device_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceDeviceSettings>); - LLFloaterReg::add("preview_avatar", "floater_profile.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarInfo>); LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview"); LLFloaterReg::add("preview_gesture", "floater_preview_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewGesture>, "preview"); LLFloaterReg::add("preview_landmark", "floater_preview_existing_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewLandmark>, "preview"); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 66da7d89fb..75d9321313 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -201,10 +201,19 @@ void LLViewerInventoryItem::fetchFromServer(void) const { std::string url; - if( ALEXANDRIA_LINDEN_ID.getString() == mPermissions.getOwner().getString()) - url = gAgent.getRegion()->getCapability("FetchLib"); - else - url = gAgent.getRegion()->getCapability("FetchInventory"); + LLViewerRegion* region = gAgent.getRegion(); + // we have to check region. It can be null after region was destroyed. See EXT-245 + if (region) + { + if( ALEXANDRIA_LINDEN_ID.getString() == mPermissions.getOwner().getString()) + url = region->getCapability("FetchLib"); + else + url = region->getCapability("FetchInventory"); + } + else + { + llwarns << "Agent Region is absent" << llendl; + } if (!url.empty()) { diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 4e0c4023fd..6bb302727d 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -44,6 +44,7 @@ #include "lltoolfocus.h" #include "llviewerwindow.h" #include "llvoavatarself.h" +#include "llfloatercamera.h" // // Constants @@ -135,14 +136,29 @@ static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDo } } +void camera_move_forward( EKeystate s ); + void agent_push_forward( EKeystate s ) { + //in free camera control mode we need to intercept keyboard events for avatar movements + if (LLFloaterCamera::inFreeCameraMode()) + { + camera_move_forward(s); + return; + } agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD); } +void camera_move_backward( EKeystate s ); void agent_push_backward( EKeystate s ) { + //in free camera control mode we need to intercept keyboard events for avatar movements + if (LLFloaterCamera::inFreeCameraMode()) + { + camera_move_backward(s); + return; + } agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD); } @@ -175,8 +191,17 @@ void agent_slide_right( EKeystate s ) agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT); } +void camera_spin_around_cw( EKeystate s ); + void agent_turn_left( EKeystate s ) { + //in free camera control mode we need to intercept keyboard events for avatar movements + if (LLFloaterCamera::inFreeCameraMode()) + { + camera_spin_around_cw(s); + return; + } + if (LLToolCamera::getInstance()->mouseSteerMode()) { agent_slide_left(s); @@ -189,9 +214,17 @@ void agent_turn_left( EKeystate s ) } } +void camera_spin_around_ccw( EKeystate s ); void agent_turn_right( EKeystate s ) { + //in free camera control mode we need to intercept keyboard events for avatar movements + if (LLFloaterCamera::inFreeCameraMode()) + { + camera_spin_around_ccw(s); + return; + } + if (LLToolCamera::getInstance()->mouseSteerMode()) { agent_slide_right(s); @@ -842,7 +875,7 @@ EKeyboardMode LLViewerKeyboard::getMode() { return MODE_EDIT_AVATAR; } - else if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting) + else if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting()) { return MODE_SITTING; } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 7071b65228..d4cbe580a9 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -81,6 +81,7 @@ #include "lldrawpooltree.h" #include "llface.h" #include "llfirstuse.h" +#include "llfirsttimetipmanager.h" #include "llfloater.h" #include "llfloaterabout.h" #include "llfloaterbuycurrency.h" @@ -3439,7 +3440,7 @@ class LLSelfStandUp : public view_listener_t { bool handleEvent(const LLSD& userdata) { - gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + gAgent.standUp(); return true; } }; @@ -3448,7 +3449,7 @@ class LLSelfEnableStandUp : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting; + bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting(); return new_value; } }; @@ -3676,7 +3677,7 @@ bool handle_sit_or_stand() if (sitting_on_selection()) { - gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + gAgent.standUp(); return true; } @@ -3722,7 +3723,7 @@ class LLLandSit : public view_listener_t { bool handleEvent(const LLSD& userdata) { - gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + gAgent.standUp(); LLViewerParcelMgr::getInstance()->deselectLand(); LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal; @@ -4630,7 +4631,7 @@ BOOL sitting_on_selection() return FALSE; } - return (avatar->mIsSitting && avatar->getRoot() == root_object); + return (avatar->isSitting() && avatar->getRoot() == root_object); } class LLToolsSaveToInventory : public view_listener_t @@ -5225,6 +5226,9 @@ class LLWorldAlwaysRun : public view_listener_t // tell the simulator. gAgent.sendWalkRun(gAgent.getAlwaysRun()); + // Update Movement Controls according to AlwaysRun mode + LLFloaterMove::setAlwaysRunMode(gAgent.getAlwaysRun()); + return true; } }; @@ -5275,7 +5279,10 @@ class LLWorldCreateLandmark : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLFloaterReg::showInstance("add_landmark"); + LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); + + // Floater "Add Landmark" functionality moved to Side Tray + //LLFloaterReg::showInstance("add_landmark"); return true; } }; @@ -7623,7 +7630,23 @@ class LLWorldDayCycle : public view_listener_t } }; +/// Show First Time Tips calbacks +class LLHelpCheckShowFirstTimeTip : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return LLFirstTimeTipsManager::tipsEnabled(); + } +}; +class LLHelpShowFirstTimeTip : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLFirstTimeTipsManager::enabledTip(!userdata.asBoolean()); + return true; + } +}; void initialize_menus() { @@ -7728,6 +7751,9 @@ void initialize_menus() view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess"); view_listener_t::addMenu(new LLWorldDayCycle(), "World.DayCycle"); + view_listener_t::addMenu(new LLHelpCheckShowFirstTimeTip(), "Help.CheckShowFirstTimeTip"); + view_listener_t::addMenu(new LLHelpShowFirstTimeTip(), "Help.ShowQuickTips"); + // Tools menu view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool"); view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 25c00bb816..129cd5aab9 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -96,6 +96,7 @@ #include "llinventorymodel.h" #include "llfloaterinventory.h" #include "llmenugl.h" +#include "llmoveview.h" #include "llmutelist.h" #include "llnotifications.h" #include "llnotify.h" @@ -1184,9 +1185,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& { opener = open_agent_offer; } - - // add buddy to recent people list - LLRecentPeople::instance().add(mFromID); } break; case IM_TASK_INVENTORY_OFFERED: @@ -1259,6 +1257,12 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& break; } + if(IM_INVENTORY_OFFERED == mIM) + { + // add buddy to recent people list + LLRecentPeople::instance().add(mFromID); + } + if(opener) { gInventory.addObserver(opener); @@ -3850,7 +3854,7 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data) if (object) { LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation()); - if (!use_autopilot || (avatar && avatar->mIsSitting && avatar->getRoot() == object->getRoot())) + if (!use_autopilot || (avatar && avatar->isSitting() && avatar->getRoot() == object->getRoot())) { //we're already sitting on this object, so don't autopilot } diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 0fadba1364..afee30293a 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -44,7 +44,6 @@ #include "llviewertexteditor.h" #include "llfloaterchat.h" -#include "llfloateravatarinfo.h" #include "llfloaterworldmap.h" #include "llnotify.h" #include "llpanelplaces.h" @@ -64,6 +63,7 @@ #include "llnotecard.h" #include "llmemorystream.h" #include "llmenugl.h" +#include "llavataractions.h" #include "llappviewer.h" // for gPacificDaylightTime @@ -1394,9 +1394,7 @@ void LLViewerTextEditor::openEmbeddedCallingcard( LLInventoryItem* item, llwchar { if(item && !item->getCreatorUUID().isNull()) { - BOOL online; - online = LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID()); - LLFloaterAvatarInfo::showFromFriend(item->getCreatorUUID(), online); + LLAvatarActions::showProfile(item->getCreatorUUID()); } } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index f312cc0f63..e44112fb8f 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4254,30 +4254,19 @@ void LLViewerWindow::destroyWindow() void LLViewerWindow::drawMouselookInstructions() { - // Draw instructions for mouselook ("Press ESC to leave Mouselook" in a box at the top of the screen.) + // Draw instructions for mouselook ("Press ESC to return to World View" partially transparent at the bottom of the screen.) const std::string instructions = LLTrans::getString("LeaveMouselook"); - const LLFontGL* font = LLFontGL::getFontSansSerif(); - - const S32 INSTRUCTIONS_PAD = 5; - LLRect instructions_rect; - instructions_rect.setLeftTopAndSize( - mWorldViewRect.mLeft + INSTRUCTIONS_PAD, - mWorldViewRect.mTop - INSTRUCTIONS_PAD, - font->getWidth( instructions ) + 2 * INSTRUCTIONS_PAD, - llround(font->getLineHeight() + 2 * INSTRUCTIONS_PAD)); - - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color4f( 0.9f, 0.9f, 0.9f, 1.0f ); - gl_rect_2d( instructions_rect ); - } + const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Huge", LLFontGL::BOLD)); + //to be on top of Bottom bar when it is opened + const S32 INSTRUCTIONS_PAD = 50; + font->renderUTF8( instructions, 0, - instructions_rect.mLeft + INSTRUCTIONS_PAD, - instructions_rect.mTop - INSTRUCTIONS_PAD, - LLColor4( 0.0f, 0.0f, 0.0f, 1.f ), - LLFontGL::LEFT, LLFontGL::TOP); + mWorldViewRect.getCenterX(), + mWorldViewRect.mBottom + INSTRUCTIONS_PAD, + LLColor4( 0.0f, 0.0f, 0.0f, 0.6f ), + LLFontGL::HCENTER, LLFontGL::TOP); } @@ -4396,11 +4385,6 @@ BOOL LLViewerWindow::getShowProgress() const return (mProgressView && mProgressView->getVisible()); } -void LLViewerWindow::handleLoginComplete() -{ - LLNavigationBar::getInstance()->handleLoginComplete(); -} - void LLViewerWindow::moveProgressViewToFront() { if( mProgressView && mRootView ) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 35173c8922..62769fe343 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -267,7 +267,6 @@ public: void setProgressMessage(const std::string& msg); void setProgressCancelButtonVisible( BOOL b, const std::string& label = LLStringUtil::null ); LLProgressView *getProgressView() const; - void handleLoginComplete(); void updateObjectUnderCursor(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 714145ce14..6658227aaf 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -57,6 +57,7 @@ #include "llkeyframestandmotion.h" #include "llkeyframewalkmotion.h" #include "llmutelist.h" +#include "llmoveview.h" #include "llnotify.h" #include "llquantize.h" #include "llregionhandle.h" @@ -4244,7 +4245,7 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL } else if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED) { - mIsSitting = TRUE; + sitDown(TRUE); } @@ -4261,7 +4262,7 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL { if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED) { - mIsSitting = FALSE; + sitDown(FALSE); } stopMotion(anim_id); result = TRUE; @@ -5484,6 +5485,19 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) } //----------------------------------------------------------------------------- +// sitDown() +//----------------------------------------------------------------------------- +void LLVOAvatar::sitDown(BOOL bSitting) +{ + mIsSitting = bSitting; + if (isSelf()) + { + // Update Movement Controls according to own Sitting mode + LLFloaterMove::setSittingMode(bSitting); + } +} + +//----------------------------------------------------------------------------- // sitOnObject() //----------------------------------------------------------------------------- void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) @@ -5502,7 +5516,7 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) mDrawable->mXform.setRotation(mDrawable->getWorldRotation() * inv_obj_rot); gPipeline.markMoved(mDrawable, TRUE); - mIsSitting = TRUE; + sitDown(TRUE); mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject mRoot.setPosition(getPosition()); mRoot.updateWorldMatrixChildren(); @@ -5566,7 +5580,8 @@ void LLVOAvatar::getOffObject() gPipeline.markMoved(mDrawable, TRUE); - mIsSitting = FALSE; + sitDown(FALSE); + mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject mRoot.setPosition(cur_position_world); mRoot.setRotation(cur_rotation_world); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index f36d64aa8e..59be38a1b0 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -784,8 +784,13 @@ public: // Sitting //-------------------------------------------------------------------- public: + void sitDown(BOOL bSitting); + BOOL isSitting(){return mIsSitting;} void sitOnObject(LLViewerObject *sit_object); void getOffObject(); + +private: + // set this property only with LLVOAvatar::sitDown method BOOL mIsSitting; /** Hierarchy diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 4a6bb6facb..9df25bdb11 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1006,6 +1006,15 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr ETextureIndex index = data->mIndex; if (!isIndexLocalTexture(index)) return; LLLocalTextureObject *local_tex_obj = getLocalTextureObject(index, 0); + + // fix for EXT-268. Preventing using of NULL pointer + if(NULL == local_tex_obj) + { + LL_WARNS("TAG") << "There is no Local Texture Object with index: " << index + << ", final: " << final + << LL_ENDL; + return; + } if (success) { if (!local_tex_obj->getBakedReady() && diff --git a/indra/newview/macview_Prefix.h b/indra/newview/macview_Prefix.h index a273320b3d..0fcdf2da4f 100644 --- a/indra/newview/macview_Prefix.h +++ b/indra/newview/macview_Prefix.h @@ -63,7 +63,6 @@ #include "lldrawable.h" #include "llfirstuse.h" #include "llfloater.h" -#include "llfloateravatarinfo.h" #include "llfloaterbuildoptions.h" #include "llfloaterchat.h" #include "llfloatercustomize.h" diff --git a/indra/newview/skins/default/textures/quick_tips/avatar_free_mode.png b/indra/newview/skins/default/textures/quick_tips/avatar_free_mode.png Binary files differnew file mode 100644 index 0000000000..be7c87efb6 --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/avatar_free_mode.png diff --git a/indra/newview/skins/default/textures/quick_tips/camera_free_mode.png b/indra/newview/skins/default/textures/quick_tips/camera_free_mode.png Binary files differnew file mode 100644 index 0000000000..9a3f3703b2 --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/camera_free_mode.png diff --git a/indra/newview/skins/default/textures/quick_tips/camera_orbit_mode.png b/indra/newview/skins/default/textures/quick_tips/camera_orbit_mode.png Binary files differnew file mode 100644 index 0000000000..dd72cc0162 --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/camera_orbit_mode.png diff --git a/indra/newview/skins/default/textures/quick_tips/camera_pan_mode.png b/indra/newview/skins/default/textures/quick_tips/camera_pan_mode.png Binary files differnew file mode 100644 index 0000000000..b537dcbe46 --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/camera_pan_mode.png diff --git a/indra/newview/skins/default/textures/quick_tips/camera_preset_front_view.png b/indra/newview/skins/default/textures/quick_tips/camera_preset_front_view.png Binary files differnew file mode 100644 index 0000000000..7674a75ac3 --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/camera_preset_front_view.png diff --git a/indra/newview/skins/default/textures/quick_tips/camera_preset_group_view.png b/indra/newview/skins/default/textures/quick_tips/camera_preset_group_view.png Binary files differnew file mode 100644 index 0000000000..9c9b923a5a --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/camera_preset_group_view.png diff --git a/indra/newview/skins/default/textures/quick_tips/camera_preset_rear_view.png b/indra/newview/skins/default/textures/quick_tips/camera_preset_rear_view.png Binary files differnew file mode 100644 index 0000000000..15c3053491 --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/camera_preset_rear_view.png diff --git a/indra/newview/skins/default/textures/quick_tips/move_fly_first.png b/indra/newview/skins/default/textures/quick_tips/move_fly_first.png Binary files differnew file mode 100644 index 0000000000..b6e2ce60e4 --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/move_fly_first.png diff --git a/indra/newview/skins/default/textures/quick_tips/move_fly_second.png b/indra/newview/skins/default/textures/quick_tips/move_fly_second.png Binary files differnew file mode 100644 index 0000000000..84b63cc338 --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/move_fly_second.png diff --git a/indra/newview/skins/default/textures/quick_tips/move_run_first.png b/indra/newview/skins/default/textures/quick_tips/move_run_first.png Binary files differnew file mode 100644 index 0000000000..16093dc683 --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/move_run_first.png diff --git a/indra/newview/skins/default/textures/quick_tips/move_run_second.png b/indra/newview/skins/default/textures/quick_tips/move_run_second.png Binary files differnew file mode 100644 index 0000000000..19fa43ec32 --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/move_run_second.png diff --git a/indra/newview/skins/default/textures/quick_tips/move_walk_first.png b/indra/newview/skins/default/textures/quick_tips/move_walk_first.png Binary files differnew file mode 100644 index 0000000000..92d120d53e --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/move_walk_first.png diff --git a/indra/newview/skins/default/textures/quick_tips/move_walk_second.png b/indra/newview/skins/default/textures/quick_tips/move_walk_second.png Binary files differnew file mode 100644 index 0000000000..f8e28722be --- /dev/null +++ b/indra/newview/skins/default/textures/quick_tips/move_walk_second.png diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml index 343ff893e8..1501f39b67 100644 --- a/indra/newview/skins/default/xui/en/floater_camera.xml +++ b/indra/newview/skins/default/xui/en/floater_camera.xml @@ -1,14 +1,15 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater can_minimize="false" + can_close="false" center_horiz="true" follows="top" - height="64" + height="95" layout="topleft" name="camera_floater" save_rect="true" save_visibility="true" - width="176"> + width="105"> <floater.string name="rotate_tooltip"> Rotate Camera Around Focus @@ -21,50 +22,121 @@ name="move_tooltip"> Move Camera Up and Down, Left and Right </floater.string> - <joystick_rotate - follows="top|left" + <panel + border="true" height="64" - image_selected="cam_rotate_in.tga" - image_unselected="cam_rotate_out.tga" layout="topleft" - left="16" - name="cam_rotate_stick" - picture_style="true" - quadrant="left" - scale_image="false" - sound_flags="3" - tool_tip="rotate_tooltip" + left="0" top="0" - width="64" /> - <joystick_zoom - follows="top|left" - height="64" - image_unselected="cam_zoom_out.tga" - layout="topleft" - left_delta="64" - minus_image="cam_zoom_minus_in.tga" - name="zoom" - picture_style="true" - plus_image="cam_zoom_plus_in.tga" - quadrant="left" - scale_image="false" - sound_flags="3" - tool_tip="zoom_tooltip" - top_delta="0" - width="16" /> - <joystick_track - follows="top|left" - height="64" - image_selected="cam_tracking_in.tga" - image_unselected="cam_tracking_out.tga" + name="controls" + width="105"> + <joystick_rotate + follows="top|left" + height="64" + image_selected="cam_rotate_in.tga" + image_unselected="cam_rotate_out.tga" + layout="topleft" + left="2" + name="cam_rotate_stick" + picture_style="true" + quadrant="left" + scale_image="false" + sound_flags="3" + tool_tip="Orbit Camera Around Focus" + top="0" + width="64" /> + <joystick_track + follows="top|left" + height="64" + image_selected="cam_tracking_in.tga" + image_unselected="cam_tracking_out.tga" + layout="topleft" + left="2" + name="cam_track_stick" + picture_style="true" + quadrant="left" + scale_image="false" + sound_flags="3" + tool_tip="Move Camera Up and Down, Left and Right" + top="0" + visible="false" + width="64" /> + <joystick_zoom + follows="top|left" + height="64" + image_unselected="cam_zoom_out.tga" + layout="topleft" + left_delta="74" + minus_image="cam_zoom_minus_in.tga" + name="zoom" + picture_style="true" + plus_image="cam_zoom_plus_in.tga" + quadrant="left" + scale_image="false" + sound_flags="3" + tool_tip="Zoom Camera Towards Focus" + top_delta="0" + width="16" /> + </panel> + <panel + border="true" + height="30" layout="topleft" - left_delta="16" - name="cam_track_stick" - picture_style="true" - quadrant="left" - scale_image="false" - sound_flags="3" - tool_tip="move_tooltip" - top_delta="0" - width="64" /> + left="0" + top_pad="1" + name="buttons" + width="105"> + <button + height="25" + label="" + layout="topleft" + left="0" + is_toggle="true" + image_selected="btn_orbit_selected.png" + image_unselected="btn_orbit_unselected.png" + name="orbit_btn" + tab_stop="false" + tool_tip="Orbit Camera" + value="true" + width="25"> + </button> + <button + height="25" + label="" + layout="topleft" + left_pad="1" + is_toggle="true" + image_selected="btn_pan_selected.png" + image_unselected="btn_pan_unselected.png" + name="pan_btn" + tab_stop="false" + tool_tip="Pan Camera" + width="25"> + </button> + <button + height="25" + label="" + layout="topleft" + left_pad="1" + is_toggle="true" + image_selected="btn_freecamera_selected.png" + image_unselected="btn_freecamera_unselected.png" + name="freecamera_btn" + tab_stop="false" + tool_tip="View Object" + width="25"> + </button> + <button + height="25" + label="" + layout="topleft" + left_pad="2" + image_selected="btn_firstperson_selected.png" + image_unselected="btn_firstperson_unselected.png" + name="avatarview_btn" + tab_stop="false" + tool_tip="See as Avatar" + width="25"> + </button> + </panel> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_first_time_tip.xml b/indra/newview/skins/default/xui/en/floater_first_time_tip.xml new file mode 100644 index 0000000000..c16373ba3c --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_first_time_tip.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_close="true" + can_minimize="false" + height="250" + layout="topleft" + name="set_name_in_the_cladd" + save_rect="true" + width="300"> + <check_box + height="20" + follows="left|bottom|right" + label="Turn off Quick Tips" + layout="topleft" + left="5" + name="DontShowFirstTimeTip_checkbox" + text_enabled_color="white" + top="225" + width="200" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml index 7666a2494d..17d12c89b7 100644 --- a/indra/newview/skins/default/xui/en/floater_moveview.xml +++ b/indra/newview/skins/default/xui/en/floater_moveview.xml @@ -1,128 +1,184 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater + can_close="false" can_minimize="false" center_horiz="true" follows="bottom" - height="58" + height="95" layout="topleft" name="move_floater" save_rect="true" save_visibility="true" - width="135"> - <button - follows="left|bottom" - height="25" - image_disabled="move_turn_left_out.tga" - image_disabled_selected="move_turn_left_in.tga" - image_selected="move_turn_left_in.tga" - image_unselected="move_turn_left_out.tga" - layout="topleft" - left="20" - name="turn left btn" - picture_style="true" - scale_image="false" - tool_tip="Turn Left" - top="29" - width="25" /> - <button - follows="left|bottom" - height="25" - image_disabled="move_turn_right_out.tga" - image_disabled_selected="move_turn_right_in.tga" - image_selected="move_turn_right_in.tga" - image_unselected="move_turn_right_out.tga" - layout="topleft" - left_pad="21" - name="turn right btn" - picture_style="true" - scale_image="false" - tool_tip="Turn Right" - top_delta="0" - width="25" /> - <button - follows="left|bottom" - height="25" - image_disabled="move_up_out.tga" - image_disabled_selected="move_up_in.tga" - image_selected="move_up_in.tga" - image_unselected="move_up_out.tga" - layout="topleft" - left="91" - name="move up btn" - picture_style="true" - scale_image="false" - tool_tip="Jump or Fly Up" - top="4" - width="25" /> - <button - follows="left|bottom" - height="25" - image_disabled="move_down_out.tga" - image_disabled_selected="move_down_in.tga" - image_selected="move_down_in.tga" - image_unselected="move_down_out.tga" - layout="topleft" - left_delta="0" - name="move down btn" - picture_style="true" - scale_image="false" - tool_tip="Crouch or Fly Down" - top_delta="25" - width="25" /> - <joystick_slide - follows="left|bottom" - height="25" - image_selected="move_left_in.tga" - image_unselected="move_left_out.tga" - layout="topleft" - left="20" - name="slide left btn" - picture_style="true" - quadrant="left" - scale_image="false" - tool_tip="Move Left" - top="4" - width="25" /> - <joystick_slide - follows="left|bottom" - height="25" - image_selected="move_right_in.tga" - image_unselected="move_right_out.tga" - layout="topleft" - left_pad="21" - name="slide right btn" - picture_style="true" - quadrant="right" - scale_image="false" - tool_tip="Move Right" - top_delta="0" - width="25" /> - <joystick_turn - follows="left|bottom" - height="25" - image_selected="move_forward_in.tga" - image_unselected="move_forward_out.tga" + width="115"> + <string + name="walk_forward_tooltip"> + Walk Forward (press Up Arrow or W) + </string> + <string + name="walk_back_tooltip"> + Walk Backwards (press Down Arrow or S) + </string> + <string + name="run_forward_tooltip"> + Run Forward (press Up Arrow or W) + </string> + <string + name="run_back_tooltip"> + Run Backwards (press Down Arrow or S) + </string> + <string + name="fly_forward_tooltip"> + Fly Forward (press Up Arrow or W) + </string> + <string + name="fly_back_tooltip"> + Fly Backwards (press Down Arrow or S) + </string> + <panel + border="true" + height="70" + follows="left|top" layout="topleft" - left_delta="-21" - name="forward btn" - picture_style="true" - quadrant="up" - scale_image="false" - tool_tip="Move Forward" - top_delta="0" - width="21" /> - <joystick_turn - follows="left|bottom" + left="0" + name="panel_actions" + top="0" + width="115"> + <button + follows="left|bottom" + height="25" + image_selected="move_turn_left_in.tga" + image_unselected="move_turn_left_out.tga" + layout="topleft" + left="10" + name="turn left btn" + picture_style="true" + scale_image="false" + tool_tip="Turn Left (press Left Arrow or A)" + top="35" + width="25" /> + <button + follows="left|bottom" + height="25" + image_selected="move_turn_right_in.tga" + image_unselected="move_turn_right_out.tga" + layout="topleft" + left_pad="45" + name="turn right btn" + picture_style="true" + scale_image="false" + tool_tip="Turn Right (press Right Arrow or D)" + top_delta="0" + width="25" /> + <button + follows="left|bottom" + height="25" + image_selected="move_up_in.tga" + image_unselected="move_up_out.tga" + layout="topleft" + left="10" + name="move up btn" + picture_style="true" + scale_image="false" + tool_tip="Fly Up, Press "E"" + top="4" + width="25" /> + <button + follows="left|bottom" + height="25" + image_selected="move_down_in.tga" + image_unselected="move_down_out.tga" + layout="topleft" + left_pad="45" + name="move down btn" + picture_style="true" + scale_image="false" + tool_tip="Fly Down, Press "C"" + top_delta="0" + width="25" /> + <joystick_turn + follows="left|bottom" + height="25" + image_selected="move_forward_in.tga" + image_unselected="move_forward_out.tga" + layout="topleft" + left="47" + name="forward btn" + picture_style="true" + quadrant="up" + scale_image="false" + tool_tip="Walk Forward (press Up Arrow or W)" + top_delta="10" + width="21" /> + <joystick_turn + follows="left|bottom" + height="25" + image_selected="move_backward_in.tga" + image_unselected="move_backward_out.tga" + layout="topleft" + left_delta="0" + name="backward btn" + picture_style="true" + quadrant="down" + scale_image="false" + tool_tip="Walk Backward (press Down Arrow or S)" + top_delta="30" + width="21" /> + </panel> +<!-- Width and height of this panel should be synchronized with panel_stand_stop_flying.xml --> + <panel + border="true" height="25" - image_selected="move_backward_in.tga" - image_unselected="move_backward_out.tga" layout="topleft" - left_delta="0" - name="backward btn" - picture_style="true" - quadrant="down" - scale_image="false" - tool_tip="Move Backward" - top_delta="25" - width="21" /> + left="0" + name="panel_modes" + top_pad="1" + width="115"> + <button + follows="left|bottom" + height="20" + label="Walk" + layout="topleft" + name="mode_walk_btn" + pad_left="0" + pad_right="0" + tool_tip="Walking Mode" + top="2" + width="43" /> + <button + follows="left|bottom" + font="SansSerifSmall" + height="20" + label="Run" + layout="topleft" + left_pad="0" + name="mode_run_btn" + pad_left="0" + pad_right="0" + tool_tip="Running Mode" + top="2" + width="37" /> + <button + follows="left|bottom" + height="20" + label="Fly" + layout="topleft" + left_pad="0" + name="mode_fly_btn" + pad_left="0" + pad_right="0" + tool_tip="Flying Mode" + top="2" + width="35" /> + <button + visible="false" + follows="left|bottom" + height="20" + label="Stop Flying" + layout="topleft" + left="0" + name="stop_fly_btn" + tool_tip="Stop Flying" + top="2" + width="115" /> + </panel> </floater> diff --git a/indra/newview/skins/default/xui/en/menu_navbar.xml b/indra/newview/skins/default/xui/en/menu_navbar.xml index 013136a593..435d928f00 100644 --- a/indra/newview/skins/default/xui/en/menu_navbar.xml +++ b/indra/newview/skins/default/xui/en/menu_navbar.xml @@ -8,14 +8,17 @@ top="624" visible="false" width="128"> - <menu_item_call - label="Copy SLurl to Clipboard" - layout="topleft" - name="Copy SLURL"> - <menu_item_call.on_click - function="Navbar.Action" - parameter="copy_url" /> - </menu_item_call> + <menu_item_check + label="Show Coordinates" + layout="topleft" + name="Show Coordinates"> + <menu_item_check.on_click + function="Navbar.Action" + parameter="show_coordinates" /> + <menu_item_check.on_check + function="Navbar.EnableMenuItem" + parameter="show_coordinates" /> + </menu_item_check> <menu_item_call label="Add Landmark..." layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index fe1baf22d0..4d1572e4a5 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -405,6 +405,15 @@ function="Floater.Show" parameter="hud" /> </menu_item_call> + <menu_item_check + label="Show Quick Tips" + layout="topleft" + name="Show Quick Tips"> + <menu_item_check.on_check + function="Help.CheckShowFirstTimeTip" /> + <menu_item_check.on_click + function="Help.ShowQuickTips" /> + </menu_item_check> <menu_item_separator layout="topleft" /> <menu_item_call diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index d42943d225..4c880f6dc0 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -55,8 +55,8 @@ left="0" name="DUMMY" top="0" - width="5" - min_width="5"/> + width="3" + min_width="3"/> <layout_panel auto_resize="false" follows="right" @@ -64,19 +64,116 @@ layout="topleft" left="5" min_height="28" - width="90" + width="70" top_delta="-10" - min_width="90" + min_width="70" user_resize="false"> <button - bottom="22" follows="right" height="20" - label="Stand Up" + is_toggle="true" + label="Move" + layout="topleft" + name="movement_btn" + tab_stop="false" + tool_tip="Shows/Hide Movement controls" + top="6" + width="70"> + <button.init_callback + function="Button.SetFloaterToggle" + parameter="moveview" /> + </button> + </layout_panel> + <icon + auto_resize="false" + color="0 0 0 0" + follows="left|right" + height="10" + image_name="spacer24.tga" + layout="topleft" + left="0" + name="DUMMY" + top="0" + width="8" + min_width="8"/> + <layout_panel + auto_resize="false" + follows="right" + height="28" + layout="topleft" + min_height="28" + min_width="150" + top_delta="-10" + width="150"> + <split_button + follows="right" + height="18" + name="presets" + top="6" + width="35"> + <split_button.arrow_button + image_selected="camera_presets/camera_presets_arrow.png" + image_unselected="camera_presets/camera_presets_arrow.png" + image_disabled_selected="camera_presets/camera_presets_arrow.png" + image_disabled="camera_presets/camera_presets_arrow.png" + tool_tip="Camera Presets" + /> + <split_button.item + image_selected="camera_presets/camera_presets_rear_view.png" + image_unselected="camera_presets/camera_presets_rear_view.png" + name="rear_view" + tool_tip="Rear View" + /> + <split_button.item + image_selected="camera_presets/camera_presets_34_view.png" + image_unselected="camera_presets/camera_presets_34_view.png" + name="3/4_view" + tool_tip="3/4 View" + /> + <split_button.item + image_selected="camera_presets/camera_presets_fron_view.png" + image_unselected="camera_presets/camera_presets_fron_view.png" + name="front_view" + tool_tip="Front View" + /> + </split_button> + <button + follows="right" + height="20" + is_toggle="true" + label="Camera" layout="topleft" - name="stand" - top="3" - width="90" /> + left_pad="0" + tab_stop="false" + tool_tip="Shows/Hide Camera controls" + top="6" + name="camera_btn" + width="70"> + <button.init_callback + function="Button.SetFloaterToggle" + parameter="camera" /> + </button> + <split_button + arrow_position="right" + follows="right" + height="18" + left_pad="0" + name="snapshots" + top="6" + width="35"> + <split_button.arrow_button + image_selected="camera_presets/camera_presets_arrow_right.png" + image_unselected="camera_presets/camera_presets_arrow_right.png" + image_disabled_selected="camera_presets/camera_presets_arrow_right.png" + image_disabled="camera_presets/camera_presets_arrow_right.png" + tool_tip="Snapshot Settings" /> + /> + <split_button.item + image_selected="camera_presets/camera_presets_snapshot.png" + image_unselected="camera_presets/camera_presets_snapshot.png" + name="snapshot" + tool_tip="Take Snapshot" /> + </split_button> </layout_panel> <icon auto_resize="false" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index f7b2481f1c..55ac14ed46 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -492,16 +492,4 @@ <string name="no_groups"> No groups </string> - <panel - layout="topleft" - name="panel_profile_view" - class="panel_profile_view" - filename="panel_profile_view.xml" - top="0" - left="0" - width="355" - height="465" - follows="left|right|top|bottom" - visible="false" - /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index c91cb2394c..1a88cc55ec 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -1,52 +1,48 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel background_visible="true" - follows="left|top|right|bottom" + follows="all" height="400" label="Places" layout="topleft" - left="0" min_height="350" min_width="240" name="places panel" - top="400" width="305"> - <panel.string - name="landmarks_tab_title"> - Landmarks - </panel.string> - <panel.string - name="teleport_history_tab_title"> - Teleport History - </panel.string> + <string + name="landmarks_tab_title" + value="Landmarks" /> + <string + name="teleport_history_tab_title" + value="Teleport History" /> <filter_editor + background_image="TextField_Search_Off" follows="left|top|right" + font="SansSerif" height="20" label="Filter" layout="topleft" left="15" name="Filter" - top="3" - width="270" - font="SansSerif" - background_image="TextField_Search_Off" + text_color="black" text_pad_left="23" - text_color="black"/> + top="3" + width="270" /> <button - name="landmark_search" - layout="topleft" - top="5" - left="23" - width="13" - height="13" - scale_image="false" - follows="left|top|right" - font="SansSerifBigBold" - image_selected="Search" - image_unselected="Search" - picture_style="true"/> + follows="left|top|right" + font="SansSerifBigBold" + height="13" + image_selected="Search" + image_unselected="Search" + layout="topleft" + left="23" + name="landmark_search" + picture_style="true" + scale_image="false" + top="5" + width="13" /> <tab_container - follows="left|top|right|bottom" + follows="all" height="326" layout="topleft" left="10" @@ -54,26 +50,42 @@ tab_position="top" top_pad="19" width="280" /> - <panel - class="panel_place_info" - filename="panel_place_info.xml" - follows="left|top|right|bottom" - height="675" + <button + follows="bottom|left" + font="SansSerifSmallBold" + height="25" + image_disabled="widgets/SegmentedBtn_Left_Disabled.png" + image_selected="widgets/SegmentedBtn_Left_Selected.png" + image_unselected="widgets/SegmentedBtn_Left_Off.png" + label="Create" layout="topleft" - left="0" - name="panel_place_info" - top="-310" + left="10" + name="create_landmark_btn" + top_pad="5" visible="false" - width="280" /> + width="60" /> + <button + follows="bottom|left" + font="SansSerifSmallBold" + height="25" + image_disabled="widgets/ComboButton_Disabled.png" + image_selected="widgets/ComboButton_Selected.png" + image_unselected="widgets/ComboButton_Off.png" + label="▼" + layout="topleft" + left_pad="0" + name="folder_menu_btn" + visible="false" + width="20" /> <button follows="bottom|left" font="SansSerifSmallBold" height="25" label="Teleport" layout="topleft" - left_delta="10" + left="10" name="teleport_btn" - top_pad="5" + top_delta="0" width="80" /> <button follows="bottom|left" @@ -97,7 +109,6 @@ top_delta="0" width="60" /> <button - enabled="true" follows="bottom|right" font="SansSerifSmallBold" height="25" @@ -107,4 +118,13 @@ name="overflow_btn" top_delta="0" width="30" /> + <panel + class="panel_place_info" + filename="panel_place_info.xml" + follows="all" + layout="topleft" + left="0" + name="panel_place_info" + top="-200" + visible="false" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml index 4f559394a6..2b21c05283 100644 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_profile.xml @@ -438,7 +438,7 @@ left="0" name="status_me_panel" top_pad="20" - width="125"> + width="250"> <text type="string" follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml index cd46ccb0bc..2466480d16 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_view.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml @@ -3,12 +3,12 @@ background_visible="true" follows="left|top|right|bottom" height="660" - label="Me" + label="Profile" layout="topleft" left="0" name="panel_target_profile" top="0" - width="305"> + width="250"> <button layout="topleft" name="back" @@ -17,6 +17,7 @@ width="20" height="20" label="" + tab_stop="false" follows="top|left" image_selected="navbar_bg_button.tga" image_unselected="navbar_bg_button.tga" diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml index 096b60adb1..73b06a3e41 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml @@ -20,8 +20,6 @@ <panel name="panel_home" filename="panel_sidetray_home_tab.xml" - width="355" - height="465" label="home" border="true" /> @@ -37,15 +35,22 @@ background_visible="true" bg_opaque_color="0.5 0.5 0.5 1.0" > + <panel_container + name="panel_container" + > <panel class="panel_people" name="panel_people" filename="panel_people.xml" - width="280" - height="465" - label="People" border="true" /> + <panel + class="panel_profile_view" + name="panel_profile_view" + filename="panel_profile_view.xml" + border="true" + /> + </panel_container> </sidetray_tab> <!-- *TODO Vadim: isn't the sidetray_tab "label" attribute redundant since we have "tab_title" ? --> <sidetray_tab diff --git a/indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml new file mode 100644 index 0000000000..445c9cc288 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<!-- Width and height of this panel should be synchronized with "panel_modes" in the floater_moveview.xml--> +<panel + height="25" + layout="topleft" + name="panel_stand_stop_flying" + mouse_opaque="false" + visible="false" + width="115"> + <button + follows="left|bottom" + height="20" + label="Stand" + layout="topleft" + name="stand_btn" + tool_tip="Click here to stand up." + top="2" + width="115" /> + <button + follows="left|bottom" + height="20" + label="Stop Flying" + layout="topleft" + name="stop_fly_btn" + tool_tip="Stop Flying" + top="2" + width="115" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index e5665b0194..c64316e305 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -335,7 +335,7 @@ <string name="GraphicsQualityHigh">High</string> <!-- mouselook --> - <string name="LeaveMouselook">Press ESC to leave Mouselook.</string> + <string name="LeaveMouselook">Press ESC to return to World View</string> <!-- inventory --> <string name="InventoryNoMatchingItems">No matching items found in inventory.</string> diff --git a/indra/newview/skins/default/xui/en/widgets/split_button.xml b/indra/newview/skins/default/xui/en/widgets/split_button.xml new file mode 100644 index 0000000000..b0367b599b --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/split_button.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<split_button
+ font="SansSerifSmall"
+ arrow_position="left"
+ follows="right|top">
+ <split_button.arrow_button
+ name="Arrow Button"
+ label=""
+ font="SansSerifSmall"
+ scale_image="true"
+ image_selected="camera_presets/camera_presets_arrow.png"
+ image_unselected="camera_presets/camera_presets_arrow.png"
+ image_disabled_selected="camera_presets/camera_presets_arrow.png"
+ image_disabled="camera_presets/camera_presets_arrow.png"
+ width="10"/>
+ <split_button.items_panel
+ background_visible="true"
+ border="true"
+ bg_alpha_color="1 1 1 1"
+ bg_opaq_color="1 1 1 1"
+ layout="topleft"
+ name="item_buttons"
+ />
+</split_button>
|