diff options
Diffstat (limited to 'indra/newview')
55 files changed, 1065 insertions, 370 deletions
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 2034f98517..3a07c6e5ef 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -206,6 +206,19 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is addItem(item, id, pos); } +// virtual +BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask); + if ( mContextMenu ) + { + std::vector<LLUUID> selected_uuids; + getSelectedUUIDs(selected_uuids); + mContextMenu->show(this, selected_uuids, x, y); + } + return handled; +} + void LLAvatarList::computeDifference( const std::vector<LLUUID>& vnew_unsorted, std::vector<LLUUID>& vadded, diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index 7372538006..a83a72b26c 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -71,6 +71,7 @@ public: void setContextMenu(LLAvatarListItem::ContextMenu* menu) { mContextMenu = menu; } void sortByName(); + virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); protected: void refresh(); diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 732db90cdb..ebc79aae48 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -130,15 +130,6 @@ void LLAvatarListItem::onMouseLeave(S32 x, S32 y, MASK mask) LLPanel::onMouseLeave(x, y, mask); } -// virtual -BOOL LLAvatarListItem::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ - if (mContextMenu) - mContextMenu->show(this, const_cast<const LLUUID&>(mAvatarId), x, y); - - return LLPanel::handleRightMouseDown(x, y, mask); -} - void LLAvatarListItem::setStatus(const std::string& status) { mStatus->setValue(status); diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index ca75e3898f..b9cfed4b7b 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -48,7 +48,7 @@ public: class ContextMenu { public: - virtual void show(LLView* spawning_view, const LLUUID& id, S32 x, S32 y) = 0; + virtual void show(LLView* spawning_view, const std::vector<LLUUID>& selected_uuids, S32 x, S32 y) = 0; }; LLAvatarListItem(); @@ -57,7 +57,6 @@ public: virtual BOOL postBuild(); virtual void onMouseLeave(S32 x, S32 y, MASK mask); virtual void onMouseEnter(S32 x, S32 y, MASK mask); - virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); virtual void setValue(const LLSD& value); virtual void changed(U32 mask); // from LLFriendObserver diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index da84303863..ddcee5f453 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -65,7 +65,7 @@ LLBottomTray::LLBottomTray(const LLSD&) mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1)); - LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("CameraPresets.ChangeView",&LLFloaterCameraPresets::onClickCameraPresets); + LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("CameraPresets.ChangeView", boost::bind(&LLFloaterCamera::onClickCameraPresets, _2)); LLIMMgr::getInstance()->addSessionObserver(this); //this is to fix a crash that occurs because LLBottomTray is a singleton @@ -77,22 +77,6 @@ LLBottomTray::LLBottomTray(const LLSD&) setFocusRoot(TRUE); } -BOOL LLBottomTray::postBuild() -{ - mBottomTrayContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_bottomtray.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - gMenuHolder->addChild(mBottomTrayContextMenu); - - mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar"); - mToolbarStack = getChild<LLLayoutStack>("toolbar_stack"); - mMovementPanel = getChild<LLPanel>("movement_panel"); - mGestureCombo = getChild<LLComboBox>("Gesture"); - mCamPanel = getChild<LLPanel>("cam_panel"); - mSnapshotPanel = getChild<LLPanel>("snapshot_panel"); - setRightMouseDownCallback(boost::bind(&LLBottomTray::showBottomTrayContextMenu,this, _2, _3,_4)); - - return TRUE; -} - LLBottomTray::~LLBottomTray() { if (!LLSingleton<LLIMMgr>::destroyed()) @@ -251,24 +235,7 @@ void LLBottomTray::showBottomTrayContextMenu(S32 x, S32 y, MASK mask) void LLBottomTray::showGestureButton(BOOL visible) { - if (visible != mGestureCombo->getVisible()) - { - LLRect r = mNearbyChatBar->getRect(); - - mGestureCombo->setVisible(visible); - - if (!visible) - { - LLFloaterReg::hideFloaterInstance("gestures"); - r.mRight -= mGestureCombo->getRect().getWidth(); - } - else - { - r.mRight += mGestureCombo->getRect().getWidth(); - } - - mNearbyChatBar->setRect(r); - } + mGesturePanel->setVisible(visible); } void LLBottomTray::showMoveButton(BOOL visible) @@ -285,3 +252,191 @@ void LLBottomTray::showSnapshotButton(BOOL visible) { mSnapshotPanel->setVisible(visible); } + +namespace +{ + const std::string& PANEL_CHICLET_NAME = "chiclet_list_panel"; + const std::string& PANEL_CHATBAR_NAME = "chat_bar"; + const std::string& PANEL_MOVEMENT_NAME = "movement_panel"; + const std::string& PANEL_CAMERA_NAME = "cam_panel"; +} + +BOOL LLBottomTray::postBuild() +{ + mBottomTrayContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_bottomtray.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + gMenuHolder->addChild(mBottomTrayContextMenu); + + mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar"); + mToolbarStack = getChild<LLLayoutStack>("toolbar_stack"); + mMovementPanel = getChild<LLPanel>("movement_panel"); + mMovementButton = mMovementPanel->getChild<LLButton>("movement_btn"); + mGesturePanel = getChild<LLPanel>("gesture_panel"); + mCamPanel = getChild<LLPanel>("cam_panel"); + mCamButton = mCamPanel->getChild<LLButton>("camera_btn"); + mSnapshotPanel = getChild<LLPanel>("snapshot_panel"); + setRightMouseDownCallback(boost::bind(&LLBottomTray::showBottomTrayContextMenu,this, _2, _3,_4)); + + if (mChicletPanel && mToolbarStack && mNearbyChatBar) + { + verifyChildControlsSizes(); + } + + return TRUE; +} + +void LLBottomTray::verifyChildControlsSizes() +{ + LLRect rect = mChicletPanel->getRect(); + if (rect.getWidth() < mChicletPanel->getMinWidth()) + { + mChicletPanel->reshape(mChicletPanel->getMinWidth(), rect.getHeight()); + } + + rect = mNearbyChatBar->getRect(); + if (rect.getWidth() < mNearbyChatBar->getMinWidth()) + { + mNearbyChatBar->reshape(mNearbyChatBar->getMinWidth(), rect.getHeight()); + } + else if (rect.getWidth() > mNearbyChatBar->getMaxWidth()) + { + rect.setLeftTopAndSize(rect.mLeft, rect.mTop, mNearbyChatBar->getMaxWidth(), rect.getHeight()); + mNearbyChatBar->reshape(mNearbyChatBar->getMaxWidth(), rect.getHeight()); + mNearbyChatBar->setRect(rect); + } +} + +void LLBottomTray::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + + if (mChicletPanel && mToolbarStack && mNearbyChatBar) + { +#ifdef __FEATURE_EXT_991__ + BOOL shrink = width < getRect().getWidth(); + const S32 MIN_RENDERED_CHARS = 3; +#endif + + verifyChildControlsSizes(); + updateResizeState(width, height); + + switch (mResizeState) + { + case STATE_CHICLET_PANEL: + mToolbarStack->updatePanelAutoResize(PANEL_CHICLET_NAME, TRUE); + + mToolbarStack->updatePanelAutoResize(PANEL_CHATBAR_NAME, FALSE); + mToolbarStack->updatePanelAutoResize(PANEL_CAMERA_NAME, FALSE); + mToolbarStack->updatePanelAutoResize(PANEL_MOVEMENT_NAME, FALSE); + + break; + case STATE_CHATBAR_INPUT: + mToolbarStack->updatePanelAutoResize(PANEL_CHATBAR_NAME, TRUE); + + mToolbarStack->updatePanelAutoResize(PANEL_CHICLET_NAME, FALSE); + mToolbarStack->updatePanelAutoResize(PANEL_CAMERA_NAME, FALSE); + mToolbarStack->updatePanelAutoResize(PANEL_MOVEMENT_NAME, FALSE); + + break; + +#ifdef __FEATURE_EXT_991__ + + case STATE_BUTTONS: + mToolbarStack->updatePanelAutoResize(PANEL_CAMERA_NAME, TRUE); + mToolbarStack->updatePanelAutoResize(PANEL_MOVEMENT_NAME, TRUE); + + mToolbarStack->updatePanelAutoResize(PANEL_CHICLET_NAME, FALSE); + mToolbarStack->updatePanelAutoResize(PANEL_CHATBAR_NAME, FALSE); + + if (shrink) + { + + if (mSnapshotPanel->getVisible()) + { + showSnapshotButton(FALSE); + } + + if (mCamPanel->getVisible() && mCamButton->getLastDrawCharsCount() < MIN_RENDERED_CHARS) + { + showCameraButton(FALSE); + } + + if (mMovementPanel->getVisible() && mMovementButton->getLastDrawCharsCount() < MIN_RENDERED_CHARS) + { + showMoveButton(FALSE); + } + + } + else + { + showMoveButton(TRUE); + mMovementPanel->draw(); + + if (mMovementButton->getLastDrawCharsCount() >= MIN_RENDERED_CHARS) + { + showMoveButton(TRUE); + } + else + { + showMoveButton(FALSE); + } + } + break; +#endif + + default: + break; + } + } + + LLPanel::reshape(width, height, called_from_parent); +} + +void LLBottomTray::updateResizeState(S32 width, S32 height) +{ + mResizeState = STATE_BUTTONS; + + const S32 chiclet_panel_width = mChicletPanel->getRect().getWidth(); + const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth(); + + const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth(); + const S32 chatbar_panel_min_width = mNearbyChatBar->getMinWidth(); + const S32 chatbar_panel_max_width = mNearbyChatBar->getMaxWidth(); + + // bottom tray is narrowed + if (width < getRect().getWidth()) + { + if (chiclet_panel_width > chiclet_panel_min_width) + { + mResizeState = STATE_CHICLET_PANEL; + } + else if (chatbar_panel_width > chatbar_panel_min_width) + { + mResizeState = STATE_CHATBAR_INPUT; + } + else + { + mResizeState = STATE_BUTTONS; + } + } + // bottom tray is widen + else + { +#ifdef __FEATURE_EXT_991__ + if (!mMovementPanel->getVisible()) + { + mResizeState = STATE_BUTTONS; + } + else +#endif + if (chatbar_panel_width < chatbar_panel_max_width) + { + mResizeState = STATE_CHATBAR_INPUT; + } + else + { + mResizeState = STATE_CHICLET_PANEL; + } + } + + + // TODO: finish implementation +} diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index cc35e63524..a28f1e42ec 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -69,6 +69,8 @@ public: virtual void sessionRemoved(const LLUUID& session_id); void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id); + virtual void reshape(S32 width, S32 height, BOOL called_from_parent); + virtual void onFocusLost(); virtual void setVisible(BOOL visible); @@ -81,6 +83,18 @@ public: private: + enum EResizeState + { + STATE_CHICLET_PANEL = 1, + STATE_CHATBAR_INPUT, + STATE_BUTTONS + }; + + void updateResizeState(S32 width, S32 height); + void verifyChildControlsSizes(); + + EResizeState mResizeState; + protected: LLBottomTray(const LLSD& key = LLSD()); @@ -103,7 +117,9 @@ protected: LLPanel* mMovementPanel; LLPanel* mCamPanel; LLPanel* mSnapshotPanel; - LLComboBox* mGestureCombo; + LLPanel* mGesturePanel; + LLButton* mCamButton; + LLButton* mMovementButton; }; #endif // LL_LLBOTTOMPANEL_H diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 2ebbae33ad..61a60a24be 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -778,7 +778,12 @@ LLChicletPanel::Params::Params() { chiclet_padding = 3; scrolling_offset = 40; - min_width = 70; + + if (!min_width.isProvided()) + { + // min_width = 4 chiclets + 3 paddings + min_width = 179 + 3*chiclet_padding; + } LLRect scroll_button_rect(0, 25, 19, 5); @@ -813,6 +818,7 @@ LLChicletPanel::LLChicletPanel(const Params&p) mLeftScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params); addChild(mLeftScrollButton); + LLTransientFloaterMgr::getInstance()->addControlView(mLeftScrollButton); mLeftScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this)); mLeftScrollButton->setEnabled(false); @@ -820,6 +826,7 @@ LLChicletPanel::LLChicletPanel(const Params&p) scroll_button_params = p.right_scroll_button; mRightScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params); addChild(mRightScrollButton); + LLTransientFloaterMgr::getInstance()->addControlView(mRightScrollButton); mRightScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this)); mRightScrollButton->setEnabled(false); diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 1713c0258d..d1153a075d 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -724,6 +724,8 @@ public: /*virtual*/ void draw(); + S32 getMinWidth() const { return mMinWidth; } + protected: LLChicletPanel(const Params&p); friend class LLUICtrlFactory; diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 76ece9d165..3b5b7f570e 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -626,8 +626,6 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) buttonXMLNode->getAttributeS32("width", buttonWidth); S32 buttonHGap = 2; // default value buttonXMLNode->getAttributeS32("left", buttonHGap); - - const S32 buttonVGap = 2; S32 count = mItems.count(); @@ -713,7 +711,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) if (chevron_button) { LLRect rect; - rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap); + rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, 0, chevron_button_width, getRect().getHeight()); chevron_button->setRect(rect); chevron_button->setVisible(TRUE); mChevronRect = rect; @@ -728,7 +726,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) LLButton::Params bparams; LLRect rect; - rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap); + rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, 0, chevron_button_width, getRect().getHeight()); bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM); bparams.image_unselected.name(flat_icon); diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index fc661772a6..dca0773139 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -50,6 +50,8 @@ const F32 CAMERA_BUTTON_DELAY = 0.0f; #define ORBIT "cam_rotate_stick" #define PAN "cam_track_stick" +#define ZOOM "zoom" +#define PRESETS "camera_presets" #define CONTROLS "controls" @@ -145,7 +147,7 @@ BOOL LLFloaterCamera::postBuild() setIsChrome(TRUE); mRotate = getChild<LLJoystickCameraRotate>(ORBIT); - mZoom = getChild<LLJoystickCameraZoom>("zoom"); + mZoom = getChild<LLJoystickCameraZoom>(ZOOM); mTrack = getChild<LLJoystickCameraTrack>(PAN); assignButton2Mode(CAMERA_CTRL_MODE_ORBIT, "orbit_btn"); @@ -216,7 +218,6 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode) break; case CAMERA_CTRL_MODE_AVATAR_VIEW: - gAgent.changeCameraToMouselook(); break; default: @@ -252,15 +253,13 @@ void LLFloaterCamera::updateState() 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); + childSetVisible(ORBIT, CAMERA_CTRL_MODE_ORBIT == mCurrMode); + childSetVisible(PAN, CAMERA_CTRL_MODE_PAN == mCurrMode); + childSetVisible(ZOOM, CAMERA_CTRL_MODE_AVATAR_VIEW != mCurrMode); + childSetVisible(PRESETS, CAMERA_CTRL_MODE_AVATAR_VIEW == mCurrMode); //hiding or showing the panel with controls by reshaping the floater - bool showControls = isOrbitMode || isPanMode; + bool showControls = CAMERA_CTRL_MODE_FREE_CAMERA != mCurrMode; if (showControls == childIsVisible(CONTROLS)) return; childSetVisible(CONTROLS, showControls); @@ -289,29 +288,7 @@ void LLFloaterCamera::updateState() } } -//-------------LLFloaterCameraPresets------------------------ - -LLFloaterCameraPresets::LLFloaterCameraPresets(const LLSD& key): -LLTransientDockableFloater(NULL, true, key) -{} - -BOOL LLFloaterCameraPresets::postBuild() -{ - setIsChrome(TRUE); - - //build dockTongue - LLDockableFloater::postBuild(); - - LLButton *anchor_btn = LLBottomTray::getInstance()->getChild<LLButton>("camera_presets_btn"); - - setDockControl(new LLDockControl( - anchor_btn, this, - getDockTongue(), LLDockControl::TOP)); - return TRUE; -} - -/*static*/ -void LLFloaterCameraPresets::onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param) +void LLFloaterCamera::onClickCameraPresets(const LLSD& param) { std::string name = param.asString(); @@ -327,5 +304,9 @@ void LLFloaterCameraPresets::onClickCameraPresets(LLUICtrl* ctrl, const LLSD& pa { gAgent.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW); } + else if ("mouselook_view" == name) + { + gAgent.changeCameraToMouselook(); + } } diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index ba943e66ed..583f279e62 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -57,6 +57,8 @@ public: /* whether in free camera mode */ static bool inFreeCameraMode(); + /* callback for camera presets changing */ + static void onClickCameraPresets(const LLSD& param); static void toPrevModeIfInAvatarViewMode(); @@ -112,15 +114,4 @@ private: }; -class LLFloaterCameraPresets : public LLTransientDockableFloater -{ - friend class LLFloaterReg; -public: - static void onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param); -private: - LLFloaterCameraPresets(const LLSD&); - ~LLFloaterCameraPresets(){} - /*virtual*/ BOOL postBuild(); - -}; #endif diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index 27e31d4edd..2e2b2d5101 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -43,6 +43,7 @@ // newview #include "llagent.h" #include "llgroupactions.h" +#include "llfloaterreg.h" #include "llviewercontrol.h" // for gSavedSettings static LLDefaultChildRegistry::Register<LLGroupList> r("group_list"); @@ -231,6 +232,8 @@ BOOL LLGroupListItem::postBuild() mInfoBtn = getChild<LLButton>("info_btn"); mInfoBtn->setClickedCallback(boost::bind(&LLGroupListItem::onInfoBtnClick, this)); + childSetAction("profile_btn", boost::bind(&LLGroupListItem::onProfileBtnClick, this)); + return TRUE; } @@ -321,6 +324,12 @@ void LLGroupListItem::setActive(bool active) void LLGroupListItem::onInfoBtnClick() { + LLFloaterReg::showInstance("inspect_group", LLSD().insert("group_id", mGroupID)); +} + +void LLGroupListItem::onProfileBtnClick() +{ LLGroupActions::show(mGroupID); } + //EOF diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h index 9c3ab88901..8dbc13997c 100644 --- a/indra/newview/llgrouplist.h +++ b/indra/newview/llgrouplist.h @@ -98,6 +98,7 @@ public: private: void setActive(bool active); void onInfoBtnClick(); + void onProfileBtnClick(); LLTextBox* mGroupNameBox; LLUUID mGroupID; diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 8f0186ce24..a20b5ea66c 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -48,7 +48,7 @@ #include "llpanelimcontrolpanel.h" #include "llscreenchannel.h" #include "lltrans.h" -#include "llviewertexteditor.h" +#include "llchathistory.h" #include "llviewerwindow.h" #include "lltransientfloatermgr.h" @@ -59,9 +59,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) mControlPanel(NULL), mSessionID(session_id), mLastMessageIndex(-1), - mLastFromName(), mDialog(IM_NOTHING_SPECIAL), - mHistoryEditor(NULL), + mChatHistory(NULL), mInputEditor(NULL), mPositioned(false), mSessionInitialized(false) @@ -219,7 +218,7 @@ BOOL LLIMFloater::postBuild() childSetCommitCallback("chat_editor", onSendMsg, this); - mHistoryEditor = getChild<LLViewerTextEditor>("im_text"); + mChatHistory = getChild<LLChatHistory>("chat_history"); setTitle(LLIMModel::instance().getName(mSessionID)); setDocked(true); @@ -251,7 +250,7 @@ void* LLIMFloater::createPanelIMControl(void* userdata) void* LLIMFloater::createPanelGroupControl(void* userdata) { LLIMFloater *self = (LLIMFloater*)userdata; - self->mControlPanel = new LLPanelGroupControlPanel(); + self->mControlPanel = new LLPanelGroupControlPanel(self->mSessionID); self->mControlPanel->setXMLFilename("panel_group_control_panel.xml"); return self->mControlPanel; } @@ -317,6 +316,8 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock) LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*> (LLNotificationsUI::LLChannelManager::getInstance()-> findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + + setCanResize(!docked); LLTransientDockableFloater::setDocked(docked, pop_on_undock); @@ -408,7 +409,6 @@ void LLIMFloater::updateMessages() if (messages.size()) { - LLUIColor divider_color = LLUIColorTable::instance().getColor("LtGray_50"); LLUIColor chat_color = LLUIColorTable::instance().getColor("IMChatColor"); std::ostringstream message; @@ -418,30 +418,20 @@ void LLIMFloater::updateMessages() { LLSD msg = *iter; - const bool prepend_newline = true; std::string from = msg["from"].asString(); + std::string time = msg["time"].asString(); + LLUUID from_id = msg["from_id"].asUUID(); + std::string message = msg["message"].asString(); + LLStyle::Params style_params; + style_params.color(chat_color); + if (from == agent_name) from = LLTrans::getString("You"); - if (mLastFromName != from) - { - message << from << " ----- " << msg["time"].asString(); - mHistoryEditor->appendText(message.str(), - prepend_newline, LLStyle::Params().color(divider_color) ); - message.str(""); - mLastFromName = from; - } - message << msg["message"].asString(); - mHistoryEditor->appendText(message.str(), - prepend_newline, - LLStyle::Params().color(chat_color) ); - message.str(""); + mChatHistory->appendWidgetMessage(from_id, from, time, message, style_params); mLastMessageIndex = msg["index"].asInteger(); } - mHistoryEditor->blockUndo(); - - mHistoryEditor->setCursorAndScrollToEnd(); } } @@ -453,7 +443,7 @@ void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* //in disconnected state IM input editor should be disabled self->mInputEditor->setEnabled(!gDisconnected); - self->mHistoryEditor->setCursorAndScrollToEnd(); + self->mChatHistory->setCursorAndScrollToEnd(); } // static @@ -516,7 +506,7 @@ void LLIMFloater::chatFromLogFile(LLLogChat::ELogLineType type, std::string line break; } - self->mHistoryEditor->appendText(message, true, LLStyle::Params().color(LLUIColorTable::instance().getColor("ChatHistoryTextColor"))); - self->mHistoryEditor->blockUndo(); + self->mChatHistory->appendText(message, true, LLStyle::Params().color(LLUIColorTable::instance().getColor("ChatHistoryTextColor"))); + self->mChatHistory->blockUndo(); } diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index 8fd0c7cde9..99810b6d6d 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -38,7 +38,7 @@ class LLLineEditor; class LLPanelChatControlPanel; -class LLViewerTextEditor; +class LLChatHistory; /** @@ -108,13 +108,9 @@ private: LLUUID mSessionID; S32 mLastMessageIndex; - // username of last user who added text to this conversation, used to - // suppress duplicate username divider bars - std::string mLastFromName; - EInstantMessage mDialog; LLUUID mOtherParticipantUUID; - LLViewerTextEditor* mHistoryEditor; + LLChatHistory* mChatHistory; LLLineEditor* mInputEditor; bool mPositioned; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 9486698c89..b631c991ae 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -334,7 +334,7 @@ std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index) } -bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string utf8_text) { +bool LLIMModel::addToHistory(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text) { LLIMSession* session = findIMSession(session_id); @@ -346,6 +346,7 @@ bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string ut LLSD message; message["from"] = from; + message["from_id"] = from_id; message["message"] = utf8_text; message["time"] = LLLogChat::timestamp(false); //might want to add date separately message["index"] = (LLSD::Integer)session->mMsgs.size(); @@ -392,7 +393,7 @@ bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, return false; } - addToHistory(session_id, from, utf8_text); + addToHistory(session_id, from, from_id, utf8_text); if (log2file) logToFile(session_id, from, utf8_text); session->mNumUnread++; diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index f9db6d8ed2..68beb29034 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -110,7 +110,7 @@ public: std::list<LLSD> getMessages(LLUUID session_id, int start_index = 0); bool addMessage(LLUUID session_id, std::string from, LLUUID other_participant_id, std::string utf8_text, bool log2file = true); - bool addToHistory(LLUUID session_id, std::string from, std::string utf8_text); + bool addToHistory(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text); bool logToFile(const LLUUID& session_id, const std::string& from, const std::string& utf8_text); diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 4fc552c8b1..2b4e35208a 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -498,7 +498,11 @@ void LLFloaterMove::setDocked(bool docked, bool pop_on_undock/* = true*/) { LLDockableFloater::setDocked(docked, pop_on_undock); bool show_mode_buttons = isDocked() || !gAgent.getFlying(); - updateHeight(show_mode_buttons); + + if (!isMinimized()) + { + updateHeight(show_mode_buttons); + } LLTransientDockableFloater::setDocked(docked, pop_on_undock); } diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index b77415dfee..b91e23eace 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -613,6 +613,9 @@ void LLNavigationBar::showNavigationPanel(BOOL visible) } } + childSetVisible("bg_icon", fpVisible); + childSetVisible("bg_icon_no_fav", !fpVisible); + if(LLSideTray::instanceCreated()) { LLSideTray::getInstance()->resetPanelRect(); @@ -677,6 +680,9 @@ void LLNavigationBar::showFavoritesPanel(BOOL visible) setRect(nbRect); } + childSetVisible("bg_icon", visible); + childSetVisible("bg_icon_no_fav", !visible); + fb->setVisible(visible); if(LLSideTray::instanceCreated()) { diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 6e90d22d89..bbab9944f3 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -55,11 +55,13 @@ #include "lldraghandle.h" #include "lltrans.h" +#include "llbottomtray.h" +#include "llnearbychatbar.h" static const S32 RESIZE_BAR_THICKNESS = 3; -LLNearbyChat::LLNearbyChat(const LLSD& key) : - LLFloater(key) +LLNearbyChat::LLNearbyChat(const LLSD& key) + : LLDockableFloater(NULL, key) ,mChatHistory(NULL) { @@ -89,7 +91,17 @@ BOOL LLNearbyChat::postBuild() setCanResize(true); - return LLFloater::postBuild(); + if(!LLDockableFloater::postBuild()) + return false; + + if (getDockControl() == NULL) + { + setDockControl(new LLDockControl( + LLBottomTray::getInstance()->getNearbyChatBar(), this, + getDockTongue(), LLDockControl::LEFT, boost::bind(&LLNearbyChat::getAllowedRect, this, _1))); + } + + return true; } @@ -255,13 +267,25 @@ void LLNearbyChat::onOpen(const LLSD& key ) void LLNearbyChat::setDocked (bool docked, bool pop_on_undock) { - LLFloater::setDocked(docked, pop_on_undock); + LLDockableFloater::setDocked(docked, pop_on_undock); - if(docked) - { - //move nearby_chat to right bottom - LLRect rect = gFloaterView->getRect(); - setRect(LLRect(rect.mLeft,getRect().getHeight(),rect.mLeft+getRect().getWidth(),0)); - } + setCanResize(!docked); +} + +void LLNearbyChat::setRect (const LLRect &rect) +{ + LLDockableFloater::setRect(rect); +} + +void LLNearbyChat::getAllowedRect(LLRect& rect) +{ + rect = gViewerWindow->getWorldViewRect(); +} +void LLNearbyChat::setVisible (BOOL visible) +{ + LLDockableFloater::setVisible(visible); +} +void LLNearbyChat::toggleWindow() +{ } diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 63e780c4bf..20cbf7537d 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -33,14 +33,14 @@ #ifndef LL_LLNEARBYCHAT_H_ #define LL_LLNEARBYCHAT_H_ -#include "llfloater.h" +#include "lldockablefloater.h" #include "llscrollbar.h" #include "llchat.h" class LLResizeBar; class LLChatHistory; -class LLNearbyChat: public LLFloater +class LLNearbyChat: public LLDockableFloater { public: LLNearbyChat(const LLSD& key); @@ -53,10 +53,17 @@ public: bool onNearbyChatCheckContextMenuItem(const LLSD& userdata); void setDocked (bool docked, bool pop_on_undock); + void toggleWindow (); /*virtual*/ void onOpen (const LLSD& key); + virtual void setVisible (BOOL visible); + + virtual void setRect (const LLRect &rect); + private: + void getAllowedRect (LLRect& rect); + void onNearbySpeakers (); void add_timestamped_line(const LLChat& chat, const LLColor4& color); diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 4f3bca50ff..5fa97926a5 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -203,7 +203,7 @@ BOOL LLNearbyChatBar::postBuild() mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator"); mOutputMonitor->setVisible(FALSE); - mTalkBtn = getChild<LLTalkButton>("talk"); + mTalkBtn = getParent()->getChild<LLTalkButton>("talk"); // Speak button should be initially disabled because // it takes some time between logging in to world and connecting to voice channel. @@ -229,6 +229,16 @@ bool LLNearbyChatBar::instanceExists() void LLNearbyChatBar::draw() { + LLRect rect = getRect(); + S32 max_width = getMaxWidth(); + + if (rect.getWidth() > max_width) + { + rect.setLeftTopAndSize(rect.mLeft, rect.mTop, max_width, rect.getHeight()); + reshape(rect.getWidth(), rect.getHeight(), FALSE); + setRect(rect); + } + displaySpeakingIndicator(); LLPanel::draw(); } @@ -254,6 +264,32 @@ BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask ) return handled; } +S32 LLNearbyChatBar::getMinWidth() const +{ + static S32 min_width = -1; + + if (min_width < 0) + { + const std::string& s = getString("min_width"); + min_width = !s.empty() ? atoi(s.c_str()) : 300; + } + + return min_width; +} + +S32 LLNearbyChatBar::getMaxWidth() const +{ + static S32 max_width = -1; + + if (max_width < 0) + { + const std::string& s = getString("max_width"); + max_width = !s.empty() ? atoi(s.c_str()) : 510; + } + + return max_width; +} + BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::string* out_str) { U32 in_len = in_str.length(); diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index d6827315f2..b902ff86cc 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -97,6 +97,9 @@ public: static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate); static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); + S32 getMinWidth() const; + S32 getMaxWidth() const; + /** * Implements LLVoiceClientStatusObserver::onChange() */ diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 1a2ef8e1bb..6413d939f0 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -351,6 +351,8 @@ void LLPanelAvatarProfile::onOpen(const LLSD& key) { LLPanelProfileTab::onOpen(key); + mGroups.erase(); + //Disable "Add Friend" button for friends. childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId())); } @@ -381,6 +383,7 @@ void LLPanelAvatarProfile::resetControls() void LLPanelAvatarProfile::resetData() { + mGroups.erase(); childSetValue("2nd_life_pic",LLUUID::null); childSetValue("real_world_pic",LLUUID::null); childSetValue("online_status",LLStringUtil::null); @@ -428,11 +431,15 @@ void LLPanelAvatarProfile::processProfileProperties(const LLAvatarData* avatar_d void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_groups) { - std::string groups; + // *NOTE dzaporozhan + // Group properties may arrive in two callbacks, we need to save them across + // different calls. We can't do that in textbox as textbox may change the text. + + std::string groups = mGroups; LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end(); - if(it_end != it) + if(groups.empty() && it_end != it) { groups = (*it).group_name; ++it; @@ -443,7 +450,8 @@ void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_g groups += ", "; groups += group_data.group_name; } - childSetValue("sl_groups",groups); + mGroups = groups; + childSetValue("sl_groups",mGroups); } void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data) diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index a03902caba..ae0b8e9844 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -173,6 +173,10 @@ protected: void onCallButtonClick(); void onTeleportButtonClick(); void onShareButtonClick(); + +private: + + std::string mGroups; }; /** diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index a7590ac1dd..6eed956eb8 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -38,6 +38,9 @@ #include "llavatariconctrl.h" #include "llbutton.h" #include "llgroupactions.h" +#include "llavatarlist.h" +#include "llparticipantlist.h" +#include "llimview.h" LLPanelIMControlPanel::LLPanelIMControlPanel() { @@ -89,15 +92,35 @@ void LLPanelIMControlPanel::setID(const LLUUID& avatar_id) } +LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id) +{ + mSpeakerManager = LLIMModel::getInstance()->getSpeakerManager(session_id); +} BOOL LLPanelGroupControlPanel::postBuild() { childSetAction("group_info_btn", boost::bind(&LLPanelGroupControlPanel::onGroupInfoButtonClicked, this)); childSetAction("call_btn", boost::bind(&LLPanelGroupControlPanel::onCallButtonClicked, this)); + mAvatarList = getChild<LLAvatarList>("speakers_list"); + mParticipantList = new LLParticipantList(mSpeakerManager, mAvatarList); + return TRUE; } +LLPanelGroupControlPanel::~LLPanelGroupControlPanel() +{ + delete mParticipantList; + mParticipantList = NULL; +} + +// virtual +void LLPanelGroupControlPanel::draw() +{ + mSpeakerManager->update(true); + LLPanelChatControlPanel::draw(); +} + void LLPanelGroupControlPanel::onGroupInfoButtonClicked() { LLGroupActions::show(mGroupID); diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index e82942a31d..138b1630c4 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -35,6 +35,9 @@ #include "llpanel.h" +class LLSpeakerMgr; +class LLAvatarList; +class LLParticipantList; class LLPanelChatControlPanel : public LLPanel { @@ -68,18 +71,22 @@ private: class LLPanelGroupControlPanel : public LLPanelChatControlPanel { public: - LLPanelGroupControlPanel() {}; - ~LLPanelGroupControlPanel() {}; + LLPanelGroupControlPanel(const LLUUID& session_id); + ~LLPanelGroupControlPanel(); BOOL postBuild(); void setID(const LLUUID& id); + /*virtual*/ void draw(); private: void onGroupInfoButtonClicked(); void onCallButtonClicked(); LLUUID mGroupID; + LLSpeakerMgr* mSpeakerManager; + LLAvatarList* mAvatarList; + LLParticipantList* mParticipantList; }; diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index d81cbb3e5d..83fb147a49 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -449,6 +449,7 @@ void LLLandmarksPanel::initListCommandsHandlers() mCommitCallbackRegistrar.add("Places.LandmarksGear.CopyPaste.Action", boost::bind(&LLLandmarksPanel::onClipboardAction, this, _2)); mCommitCallbackRegistrar.add("Places.LandmarksGear.Custom.Action", boost::bind(&LLLandmarksPanel::onCustomAction, this, _2)); mCommitCallbackRegistrar.add("Places.LandmarksGear.Folding.Action", boost::bind(&LLLandmarksPanel::onFoldingAction, this, _2)); + mEnableCallbackRegistrar.add("Places.LandmarksGear.Check", boost::bind(&LLLandmarksPanel::isActionChecked, this, _2)); mEnableCallbackRegistrar.add("Places.LandmarksGear.Enable", boost::bind(&LLLandmarksPanel::isActionEnabled, this, _2)); mGearLandmarkMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_places_gear_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mGearFolderMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_places_gear_folder.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); @@ -598,7 +599,6 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata) else if ( "sort_by_date" == command_name) { mSortByDate = !mSortByDate; - updateSortOrder(mFavoritesInventoryPanel, mSortByDate); updateSortOrder(mLandmarksInventoryPanel, mSortByDate); updateSortOrder(mMyInventoryPanel, mSortByDate); updateSortOrder(mLibraryInventoryPanel, mSortByDate); @@ -609,15 +609,54 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata) } } +bool LLLandmarksPanel::isActionChecked(const LLSD& userdata) const +{ + const std::string command_name = userdata.asString(); + + if ( "sort_by_date" == command_name) + { + return mSortByDate; + } + + return false; +} + bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const { std::string command_name = userdata.asString(); + LLPlacesFolderView* rootFolderView = mCurrentSelectedList ? static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder()) : NULL; if (NULL == rootFolderView) return false; + // disable some commands for multi-selection. EXT-1757 + if (rootFolderView->getSelectedCount() > 1) + { + if ( "teleport" == command_name + || "more_info" == command_name + || "rename" == command_name + || "show_on_map" == command_name + || "copy_slurl" == command_name + ) + { + return false; + } + + } + + // disable some commands for Favorites accordion. EXT-1758 + if (mCurrentSelectedList == mFavoritesInventoryPanel) + { + if ( "expand_all" == command_name + || "collapse_all" == command_name + || "sort_by_date" == command_name + ) + return false; + } + + if("category" == command_name) { // we can add folder only in Landmarks Accordion @@ -636,11 +675,6 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const { return mSortByDate; } - // do not allow teleport and more info for multi-selections - else if ("teleport" == command_name || "more_info" == command_name) - { - return rootFolderView->getSelectedCount() == 1; - } else if("create_pick" == command_name) { return !LLAgentPicksInfo::getInstance()->isPickLimitReached(); diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 11d703dcde..47c9f7647c 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -96,6 +96,7 @@ private: void onAddAction(const LLSD& command_name) const; void onClipboardAction(const LLSD& command_name) const; void onFoldingAction(const LLSD& command_name); + bool isActionChecked(const LLSD& userdata) const; bool isActionEnabled(const LLSD& command_name) const; void onCustomAction(const LLSD& command_name); diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 9dc80c0515..61d66873ea 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -690,6 +690,27 @@ LLUUID LLPanelPeople::getCurrentItemID() const return LLUUID::null; } +void LLPanelPeople::getCurrentItemIDs(std::vector<LLUUID>& selected_uuids) const +{ + std::string cur_tab = getActiveTabName(); + + if (cur_tab == FRIENDS_TAB_NAME) + { + // friends tab has two lists + mOnlineFriendList->getSelectedUUIDs(selected_uuids); + mAllFriendList->getSelectedUUIDs(selected_uuids); + } + else if (cur_tab == NEARBY_TAB_NAME) + mNearbyList->getSelectedUUIDs(selected_uuids); + else if (cur_tab == RECENT_TAB_NAME) + mRecentList->getSelectedUUIDs(selected_uuids); + else if (cur_tab == GROUP_TAB_NAME) + mGroupList->getSelectedUUIDs(selected_uuids); + else + llassert(0 && "unknown tab selected"); + +} + void LLPanelPeople::showGroupMenu(LLMenuGL* menu) { // Shows the menu at the top of the button bar. @@ -873,10 +894,17 @@ void LLPanelPeople::onChatButtonClicked() void LLPanelPeople::onImButtonClicked() { - LLUUID id = getCurrentItemID(); - if (id.notNull()) + std::vector<LLUUID> selected_uuids; + getCurrentItemIDs(selected_uuids); + if ( selected_uuids.size() == 1 ) + { + // if selected only one person then start up IM + LLAvatarActions::startIM(selected_uuids.at(0)); + } + else if ( selected_uuids.size() > 1 ) { - LLAvatarActions::startIM(id); + // for multiple selection start up friends conference + LLAvatarActions::startConference(selected_uuids); } } diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index aa78080d7e..dc0aaeb70f 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -72,6 +72,7 @@ private: void updateButtons(); std::string getActiveTabName() const; LLUUID getCurrentItemID() const; + void getCurrentItemIDs(std::vector<LLUUID>& selected_uuids) const; void buttonSetVisible(std::string btn_name, BOOL visible); void buttonSetEnabled(const std::string& btn_name, bool enabled); void buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb); diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index 0e88058bb1..aaf6849fe9 100644 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -55,7 +55,7 @@ ContextMenu::ContextMenu() { } -void ContextMenu::show(LLView* spawning_view, const LLUUID& id, S32 x, S32 y) +void ContextMenu::show(LLView* spawning_view, const std::vector<LLUUID>& uuids, S32 x, S32 y) { if (mMenu) { @@ -67,9 +67,16 @@ void ContextMenu::show(LLView* spawning_view, const LLUUID& id, S32 x, S32 y) mMenu->setParent(NULL); } delete mMenu; + mMenu = NULL; + mUUIDs.clear(); } - mID = id; + if ( uuids.empty() ) + return; + + mUUIDs.resize(uuids.size()); + std::copy(uuids.begin(), uuids.end(), mUUIDs.begin()); + mMenu = createMenu(); mMenu->show(x, y); LLMenuGL::showPopup(spawning_view, mMenu, x, y); @@ -80,47 +87,92 @@ void ContextMenu::show(LLView* spawning_view, const LLUUID& id, S32 x, S32 y) LLContextMenu* NearbyMenu::createMenu() { // set up the callbacks for all of the avatar menu items - // (N.B. callbacks don't take const refs as mID is local scope) LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - registrar.add("Avatar.Profile", boost::bind(&LLAvatarActions::showProfile, mID)); - registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mID)); - registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startIM, mID)); - registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startIM, mID)); // *TODO: unimplemented - registrar.add("Avatar.OfferTeleport", boost::bind(&NearbyMenu::offerTeleport, this)); - registrar.add("Avatar.ShowOnMap", boost::bind(&LLAvatarActions::startIM, mID)); // *TODO: unimplemented - registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::startIM, mID)); // *TODO: unimplemented - registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, mID)); - registrar.add("Avatar.BlockUnblock", boost::bind(&LLAvatarActions::toggleBlock, mID)); - - enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem, this, _2)); - enable_registrar.add("Avatar.CheckItem", boost::bind(&NearbyMenu::checkContextMenuItem, this, _2)); - - // create the context menu from the XUI - return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( - "menu_people_nearby.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + if ( mUUIDs.size() == 1 ) + { + // Set up for one person selected menu + + const LLUUID& id = mUUIDs.front(); + registrar.add("Avatar.Profile", boost::bind(&LLAvatarActions::showProfile, id)); + registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, id)); + registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startIM, id)); + registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startIM, id)); // *TODO: unimplemented + registrar.add("Avatar.OfferTeleport", boost::bind(&NearbyMenu::offerTeleport, this)); + registrar.add("Avatar.ShowOnMap", boost::bind(&LLAvatarActions::startIM, id)); // *TODO: unimplemented + registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::startIM, id)); // *TODO: unimplemented + registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, id)); + registrar.add("Avatar.BlockUnblock", boost::bind(&LLAvatarActions::toggleBlock, id)); + + enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem, this, _2)); + enable_registrar.add("Avatar.CheckItem", boost::bind(&NearbyMenu::checkContextMenuItem, this, _2)); + + // create the context menu from the XUI + return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( + "menu_people_nearby.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + } + else + { + // Set up for multi-selected People + + // registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mUUIDs)); // *TODO: unimplemented + registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startConference, mUUIDs)); + // registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startConference, mUUIDs)); // *TODO: unimplemented + // registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::startIM, mUUIDs)); // *TODO: unimplemented + // registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, mUUIDs)); // *TODO: unimplemented + enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem, this, _2)); + + // create the context menu from the XUI + return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu> + ("menu_people_nearby_multiselect.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + + } } bool NearbyMenu::enableContextMenuItem(const LLSD& userdata) { std::string item = userdata.asString(); + // Note: can_block and can_delete is used only for one person selected menu + // so we don't need to go over all uuids. + if (item == std::string("can_block")) { + const LLUUID& id = mUUIDs.front(); std::string firstname, lastname; - gCacheName->getName(mID, firstname, lastname); + gCacheName->getName(id, firstname, lastname); bool is_linden = !LLStringUtil::compareStrings(lastname, "Linden"); - bool is_self = mID == gAgentID; + bool is_self = id == gAgentID; return !is_self && !is_linden; } else if (item == std::string("can_add")) { - return !LLAvatarActions::isFriend(mID); + // We can add friends if: + // - there are selected people + // - and there are no friends among selection yet. + + bool result = (mUUIDs.size() > 0); + + std::vector<LLUUID>::const_iterator + id = mUUIDs.begin(), + uuids_end = mUUIDs.end(); + + for (;id != uuids_end; ++id) + { + if ( LLAvatarActions::isFriend(*id) ) + { + result = false; + break; + } + } + + return result; } else if (item == std::string("can_delete")) { - return LLAvatarActions::isFriend(mID); + const LLUUID& id = mUUIDs.front(); + return LLAvatarActions::isFriend(id); } return false; @@ -129,10 +181,11 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata) bool NearbyMenu::checkContextMenuItem(const LLSD& userdata) { std::string item = userdata.asString(); + const LLUUID& id = mUUIDs.front(); if (item == std::string("is_blocked")) { - return LLAvatarActions::isBlocked(mID); + return LLAvatarActions::isBlocked(id); } return false; @@ -142,7 +195,8 @@ void NearbyMenu::offerTeleport() { // boost::bind cannot recognize overloaded method LLAvatarActions::offerTeleport(), // so we have to use a wrapper. - LLAvatarActions::offerTeleport(mID); + const LLUUID& id = mUUIDs.front(); + LLAvatarActions::offerTeleport(id); } } // namespace LLPanelPeopleMenus diff --git a/indra/newview/llpanelpeoplemenus.h b/indra/newview/llpanelpeoplemenus.h index 0012ac38f8..ed0f8208f6 100644 --- a/indra/newview/llpanelpeoplemenus.h +++ b/indra/newview/llpanelpeoplemenus.h @@ -49,17 +49,17 @@ public: /** * Show the menu at specified coordinates. - * - * @param id either avatar or group id + * + * @param uuids - an array of avatar or group ids */ - /*virtual*/ void show(LLView* spawning_view, const LLUUID& id, S32 x, S32 y); + /*virtual*/ void show(LLView* spawning_view, const std::vector<LLUUID>& uuids, S32 x, S32 y); protected: virtual LLContextMenu* createMenu() = 0; - LLUUID mID; - LLContextMenu* mMenu; + std::vector<LLUUID> mUUIDs; + LLContextMenu* mMenu; }; /** diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index cb9f641bf8..e725479abb 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -46,6 +46,7 @@ #include "lltexteditor.h" #include "lltexturectrl.h" #include "lluiconstants.h" +#include "llviewerregion.h" #include "llworldmap.h" #include "llfloaterworldmap.h" #include "llfloaterreg.h" @@ -348,6 +349,15 @@ void LLPanelPickEdit::onOpen(const LLSD& key) snapshot_id = parcel->getSnapshotID(); } + if(pick_name.empty()) + { + LLViewerRegion* region = gAgent.getRegion(); + if(region) + { + pick_name = region->getName(); + } + } + setParcelID(parcel_id); childSetValue("pick_name", pick_name); childSetValue("pick_desc", pick_desc); diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index 1219a08c6c..aa6909560d 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -39,6 +39,7 @@ #include "llfloaterreg.h" #include "llfloaterworldmap.h" #include "lltexturectrl.h" +#include "lltoggleablemenu.h" #include "llviewergenericmessage.h" // send_generic_message #include "llmenugl.h" #include "llviewermenu.h" @@ -55,6 +56,7 @@ static const std::string XML_BTN_DELETE = "trash_btn"; static const std::string XML_BTN_INFO = "info_btn"; static const std::string XML_BTN_TELEPORT = "teleport_btn"; static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn"; +static const std::string XML_BTN_OVERFLOW = "overflow_btn"; static const std::string PICK_ID("pick_id"); static const std::string PICK_CREATOR_ID("pick_creator_id"); @@ -74,6 +76,7 @@ LLPanelPicks::LLPanelPicks() mPicksList(NULL) , mPanelPickInfo(NULL) , mPanelPickEdit(NULL) + , mOverflowMenu(NULL) { } @@ -159,25 +162,56 @@ BOOL LLPanelPicks::postBuild() { mPicksList = getChild<LLFlatListView>("picks_list"); + childSetAction(XML_BTN_NEW, boost::bind(&LLPanelPicks::onClickNew, this)); childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this)); - - childSetAction("teleport_btn", boost::bind(&LLPanelPicks::onClickTeleport, this)); - childSetAction("show_on_map_btn", boost::bind(&LLPanelPicks::onClickMap, this)); - - childSetAction("info_btn", boost::bind(&LLPanelPicks::onClickInfo, this)); - childSetAction("new_btn", boost::bind(&LLPanelPicks::onClickNew, this)); + childSetAction(XML_BTN_TELEPORT, boost::bind(&LLPanelPicks::onClickTeleport, this)); + childSetAction(XML_BTN_SHOW_ON_MAP, boost::bind(&LLPanelPicks::onClickMap, this)); + childSetAction(XML_BTN_INFO, boost::bind(&LLPanelPicks::onClickInfo, this)); + childSetAction(XML_BTN_OVERFLOW, boost::bind(&LLPanelPicks::onOverflowButtonClicked, this)); - CommitCallbackRegistry::ScopedRegistrar registar; + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar; registar.add("Pick.Info", boost::bind(&LLPanelPicks::onClickInfo, this)); registar.add("Pick.Edit", boost::bind(&LLPanelPicks::onClickMenuEdit, this)); registar.add("Pick.Teleport", boost::bind(&LLPanelPicks::onClickTeleport, this)); registar.add("Pick.Map", boost::bind(&LLPanelPicks::onClickMap, this)); registar.add("Pick.Delete", boost::bind(&LLPanelPicks::onClickDelete, this)); mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar overflow_registar; + overflow_registar.add("PicksList.Overflow", boost::bind(&LLPanelPicks::onOverflowMenuItemClicked, this, _2)); + mOverflowMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_overflow.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); return TRUE; } +void LLPanelPicks::onOverflowMenuItemClicked(const LLSD& param) +{ + std::string value = param.asString(); + + if("info" == value) + { + onClickInfo(); + } + else if("teleport" == value) + { + onClickTeleport(); + } + else if("map" == value) + { + onClickMap(); + } +} + +void LLPanelPicks::onOverflowButtonClicked() +{ + LLRect rect; + childGetRect(XML_BTN_OVERFLOW, rect); + + mOverflowMenu->updateParent(LLMenuGL::sMenuContainer); + mOverflowMenu->setButtonRect(rect, this); + LLMenuGL::showPopup(this, mOverflowMenu, rect.mRight, rect.mTop); +} + void LLPanelPicks::onOpen(const LLSD& key) { const LLUUID id(key.asUUID()); @@ -305,8 +339,6 @@ void LLPanelPicks::updateButtons() { bool has_selected = mPicksList->numSelected(); - childSetEnabled(XML_BTN_INFO, has_selected); - if (getAvatarId() == gAgentID) { childSetEnabled(XML_BTN_NEW, !LLAgentPicksInfo::getInstance()->isPickLimitReached()); @@ -316,6 +348,7 @@ void LLPanelPicks::updateButtons() childSetEnabled(XML_BTN_INFO, has_selected); childSetEnabled(XML_BTN_TELEPORT, has_selected); childSetEnabled(XML_BTN_SHOW_ON_MAP, has_selected); + childSetEnabled(XML_BTN_OVERFLOW, has_selected); } void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel) diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h index 7cf8f2de2a..06a0f0a0fd 100644 --- a/indra/newview/llpanelpicks.h +++ b/indra/newview/llpanelpicks.h @@ -50,6 +50,7 @@ class LLPickItem; class LLFlatListView; class LLPanelPickInfo; class LLPanelPickEdit; +class LLToggleableMenu; class LLPanelPicks : public LLPanelProfileTab @@ -80,6 +81,9 @@ private: void onClickTeleport(); void onClickMap(); + void onOverflowMenuItemClicked(const LLSD& param); + void onOverflowButtonClicked(); + //------------------------------------------------ // Callbacks which require panel toggling //------------------------------------------------ @@ -113,6 +117,7 @@ private: LLFlatListView* mPicksList; LLPanelPickInfo* mPanelPickInfo; LLPanelPickEdit* mPanelPickEdit; + LLToggleableMenu* mOverflowMenu; }; class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index f1e585f285..25e773e8b8 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -1,10 +1,10 @@ /** * @file llparticipantlist.cpp - * @brief LLParticipantList implementing LLSimpleListener listener + * @brief LLParticipantList intended to update view(LLAvatarList) according to incoming messages * - * $LicenseInfo:firstyear=2005&license=viewergpl$ + * $LicenseInfo:firstyear=2009&license=viewergpl$ * - * Copyright (c) 2005-2009, Linden Research, Inc. + * Copyright (c) 2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -36,21 +36,70 @@ #include "llavatarlist.h" #include "llfloateractivespeakers.h" - +//LLParticipantList retrieves add, clear and remove events and updates view accordingly LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list): mSpeakerMgr(data_source), mAvatarList(avatar_list) { - mSpeakerMgr->addListener(this, "add"); - mSpeakerMgr->addListener(this, "remove"); - mSpeakerMgr->addListener(this, "clear"); - std::string str = "test"; - mAvatarList->setNoItemsCommentText(str); + mSpeakerAddListener = new SpeakerAddListener(mAvatarList); + mSpeakerRemoveListener = new SpeakerRemoveListener(mAvatarList); + mSpeakerClearListener = new SpeakerClearListener(mAvatarList); + + mSpeakerMgr->addListener(mSpeakerAddListener, "add"); + mSpeakerMgr->addListener(mSpeakerRemoveListener, "remove"); + mSpeakerMgr->addListener(mSpeakerClearListener, "clear"); +} - //LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs(); +LLParticipantList::~LLParticipantList() +{ + delete mSpeakerAddListener; + delete mSpeakerRemoveListener; + delete mSpeakerClearListener; + mSpeakerAddListener = NULL; + mSpeakerRemoveListener = NULL; + mSpeakerClearListener = NULL; } -bool LLParticipantList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) +// +// LLParticipantList::SpeakerAddListener +// +bool LLParticipantList::SpeakerAddListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) { + LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs(); + LLUUID uu_id = event->getValue().asUUID(); + + LLAvatarList::uuid_vector_t::iterator found = std::find(group_members.begin(), group_members.end(), uu_id); + if(found != group_members.end()) + { + llinfos << "Already got a buddy" << llendl; + return true; + } + + group_members.push_back(uu_id); + mAvatarList->setDirty(); + mAvatarList->sortByName(); return true; } + +// +// LLParticipantList::SpeakerRemoveListener +// +bool LLParticipantList::SpeakerRemoveListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) +{ + LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs(); + group_members.erase(std::find(group_members.begin(), group_members.end(), event->getValue().asUUID())); + mAvatarList->setDirty(); + return true; +} + +// +// LLParticipantList::SpeakerClearListener +// +bool LLParticipantList::SpeakerClearListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) +{ + LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs(); + group_members.clear(); + mAvatarList->setDirty(); + return true; +} + diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index 2ec563a356..68aae0aee5 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -1,10 +1,10 @@ /** * @file llparticipantlist.h - * @brief LLParticipantList implementing LLSimpleListener listener + * @brief LLParticipantList intended to update view(LLAvatarList) according to incoming messages * - * $LicenseInfo:firstyear=2005&license=viewergpl$ + * $LicenseInfo:firstyear=2009&license=viewergpl$ * - * Copyright (c) 2005-2009, Linden Research, Inc. + * Copyright (c) 2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -36,13 +36,48 @@ class LLSpeakerMgr; class LLAvatarList; -class LLParticipantList: public LLOldEvents::LLSimpleListener +class LLParticipantList { public: LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list); - /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); + ~LLParticipantList(); + protected: + + //List of listeners implementing LLOldEvents::LLSimpleListener. + //There is no way to handle all the events in one listener as LLSpeakerMgr registers listeners in such a way + //that one listener can handle only one type of event + class SpeakerAddListener : public LLOldEvents::LLSimpleListener + { + public: + SpeakerAddListener(LLAvatarList* avatar_list) : mAvatarList(avatar_list) {} + + /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); + LLAvatarList* mAvatarList; + }; + + class SpeakerRemoveListener : public LLOldEvents::LLSimpleListener + { + public: + SpeakerRemoveListener(LLAvatarList* avatar_list) : mAvatarList(avatar_list) {} + + /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); + LLAvatarList* mAvatarList; + }; + + class SpeakerClearListener : public LLOldEvents::LLSimpleListener + { + public: + SpeakerClearListener(LLAvatarList* avatar_list) : mAvatarList(avatar_list) {} + + /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); + LLAvatarList* mAvatarList; + }; private: LLSpeakerMgr* mSpeakerMgr; LLAvatarList* mAvatarList; + + SpeakerAddListener* mSpeakerAddListener; + SpeakerRemoveListener* mSpeakerRemoveListener; + SpeakerClearListener* mSpeakerClearListener; }; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 9ccff0c44e..dace3f875f 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -147,7 +147,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>); LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>); - LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>); LLFloaterReg::add("chat", "floater_chat_history.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChat>); LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>); LLFloaterReg::add("communicate", "floater_chatterbox.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatterBox>); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index b268413d36..791ec07349 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1947,52 +1947,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { return; } - chat.mText = name + separator_string + message.substr(message_offset); - chat.mFromName = name; - - // Build a link to open the object IM info window. - std::string location = ll_safe_string((char*)binary_bucket,binary_bucket_size); - - LLSD query_string; - query_string["owner"] = from_id; - query_string["slurl"] = location.c_str(); - query_string["name"] = name; - if (from_group) - { - query_string["groupowned"] = "true"; - } - - if (session_id.notNull()) - { - chat.mFromID = session_id; - } - else - { - // This message originated on a region without the updated code for task id and slurl information. - // We just need a unique ID for this object that isn't the owner ID. - // If it is the owner ID it will overwrite the style that contains the link to that owner's profile. - // This isn't ideal - it will make 1 style for all objects owned by the the same person/group. - // This works because the only thing we can really do in this case is show the owner name and link to their profile. - chat.mFromID = from_id ^ gAgent.getSessionID(); - } - - std::ostringstream link; - link << "secondlife:///app/objectim/" << session_id - << LLURI::mapToQueryString(query_string); - - chat.mURL = link.str(); - chat.mText = name + separator_string + message.substr(message_offset); - - // Note: lie to LLFloaterChat::addChat(), pretending that this is NOT an IM, because - // IMs from objcts don't open IM sessions. - chat.mSourceType = CHAT_SOURCE_OBJECT; - LLFloaterChat::addChat(chat, FALSE, FALSE); - - // archive message in nearby chat - LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD()); - if(nearby_chat) - nearby_chat->addMessage(chat); + LLSD substitutions; + substitutions["MSG"] = message.substr(message_offset); + LLNotifications::instance().add("ServerObjectMessage", substitutions); } break; case IM_FROM_TASK_AS_ALERT: diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index eca5130426..01976c9a5c 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -54,6 +54,11 @@ <texture name="CameraView_Off" file_name="bottomtray/CameraView_Off.png" preload="false" /> <texture name="CameraView_Over" file_name="bottomtray/CameraView_Over.png" preload="false" /> + <texture name="CameraPreset_Rear" file_name="camera_presets/camera_presets_rear.png" preload="false" /> + <texture name="CameraPreset_3_4" file_name="camera_presets/camera_presets_3_4.png" preload="false" /> + <texture name="CameraPreset_Front" file_name="camera_presets/camera_presets_front.png" preload="false" /> + <texture name="CameraPreset_Mouselook" file_name="camera_presets/camera_presets_mouselook.png" preload="false" /> + <texture name="Checkbox_Off_Disabled" file_name="widgets/Checkbox_Disabled.png" preload="true" /> <texture name="Checkbox_On_Disabled" file_name="widgets/Checkbox_On_Disabled.png" preload="true" /> <texture name="Checkbox_Off" file_name="widgets/Checkbox_Off.png" preload="true" /> diff --git a/indra/newview/skins/default/xui/en/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml index 9cd7056866..c35cbb1539 100644 --- a/indra/newview/skins/default/xui/en/favorites_bar_button.xml +++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml @@ -4,7 +4,7 @@ <button follows="left|bottom" halign="center" - height="23" + height="15" image_disabled="transparent.j2c" image_disabled_selected="transparent.j2c" image_selected="transparent.j2c" diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml index a5c73a7ca4..520249c2a2 100644 --- a/indra/newview/skins/default/xui/en/floater_camera.xml +++ b/indra/newview/skins/default/xui/en/floater_camera.xml @@ -80,6 +80,75 @@ tool_tip="Zoom camera toward focus" top_delta="0" width="16" /> + <panel + height="70" + layout="topleft" + left="15" + name="camera_presets" + top="15" + visible="false" + width="75"> + <button + height="30" + image_selected="CameraPreset_Rear" + image_unselected="CameraPreset_Rear" + layout="topleft" + left="5" + name="rear_view" + picture_style="true" + tool_tip="Rear View" + top="2" + width="30"> + <click_callback + function="CameraPresets.ChangeView" + parameter="rear_view" /> + </button> + <button + height="30" + image_selected="CameraPreset_3_4" + image_unselected="CameraPreset_3_4" + layout="topleft" + left_pad="5" + name="group_view" + picture_style="true" + tool_tip="Group View" + top="2" + width="30"> + <click_callback + function="CameraPresets.ChangeView" + parameter="group_view" /> + </button> + <button + height="30" + image_selected="CameraPreset_Front" + image_unselected="CameraPreset_Front" + layout="topleft" + left="5" + name="front_view" + picture_style="true" + tool_tip="Front View" + top_pad="2" + width="30"> + <click_callback + function="CameraPresets.ChangeView" + parameter="front_view" /> + </button> + <button + height="30" + image_selected="CameraPreset_Mouselook" + image_unselected="CameraPreset_Mouselook" + layout="topleft" + left_pad="5" + name="mouselook_view" + picture_style="true" + tool_tip="Mouselook View" + top_pad="-30" + width="30"> + <click_callback + function="CameraPresets.ChangeView" + parameter="mouselook_view" /> + </button> + </panel> </panel> <panel border="true" diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 611c51ad11..0037c6ef04 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -11,7 +11,10 @@ can_dock="true" can_minimize="true" visible="true" - width="365"> + width="365" + can_resize="true" + min_width="200" + min_height="150"> <layout_stack follows="left|top|right|bottom" height="235" width="365" @@ -24,9 +27,9 @@ name="panel_im_control_panel" layout="topleft" top_delta="-3" - min_width="96" width="146" height="225" + follows="left" label="IM Control Panel" user_resize="false" /> <layout_panel height="235" @@ -35,33 +38,30 @@ top="0" user_resize="false"> <button height="12" + follows="left|top" top="8" label="<<" layout="topleft" width="35" name="slide_left_btn" /> <button height="12" + follows="left|top" top="8" label=">>" layout="topleft" width="35" name="slide_right_btn" /> - <text_editor - enabled="false" - type="string" + <chat_history length="1" - follows="left|top|right" + follows="left|top|right|bottom" font="SansSerif" height="185" layout="topleft" - max_length="2147483647" - name="im_text" + name="chat_history" parse_highlights="true" allow_html="true" - track_bottom="true" - width="195" - word_wrap="true"> - </text_editor> + width="195"> + </chat_history> <line_editor follows="left|right" name="chat_editor" height="20" layout="topleft" width="190"> </line_editor> </layout_panel> diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml index 90c5463aa7..25d337ccec 100644 --- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml @@ -1,9 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater - can_dock="true" can_minimize="true" - can_close="true" - center_horiz="true" + can_tear_off="false" + can_resize="false" + can_drag_on_left="false" + can_close="false" + can_dock="true" + bevel_style="in" height="300" layout="topleft" name="nearby_chat" @@ -17,8 +20,8 @@ bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor" follows="all" - left="0" - top="15" + left="1" + top="20" font="SansSerif" layout="topleft" height="280" diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml new file mode 100644 index 0000000000..df74d2dcd4 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<context_menu + layout="topleft" + name="Multi-Selected People Context Menu"> + <menu_item_call + enabled="false" + label="Add Friends" + layout="topleft" + name="Add Friends"> + <on_click + function="Avatar.AddFriends" /> + <on_enable + function="Avatar.EnableItem" + parameter="can_add" /> + </menu_item_call> + <menu_item_call + label="IM" + layout="topleft" + name="IM"> + <on_click + function="Avatar.IM" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Call" + layout="topleft" + name="Call"> + <on_click + function="Avatar.Call" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Share" + layout="topleft" + name="Share"> + <on_click + function="Avatar.Share" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Pay" + layout="topleft" + name="Pay"> + <on_click + function="Avatar.Pay" /> + </menu_item_call> +</context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml index 29fb4990d0..c849188699 100644 --- a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml +++ b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml @@ -118,7 +118,7 @@ layout="topleft" name="sort_by_date"> <on_check - function="Places.LandmarksGear.Enable" + function="Places.LandmarksGear.Check" parameter="sort_by_date" /> <on_click function="Places.LandmarksGear.Folding.Action" diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml index c60f670fa6..63d1a67d0f 100644 --- a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml +++ b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml @@ -35,6 +35,9 @@ <on_click function="Places.LandmarksGear.Custom.Action" parameter="show_on_map" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="show_on_map" /> </menu_item_call> <menu_item_separator layout="topleft" /> @@ -85,6 +88,9 @@ <on_click function="Places.LandmarksGear.CopyPaste.Action" parameter="copy_slurl" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="copy_slurl" /> </menu_item_call> <menu_item_call label="Paste" @@ -128,6 +134,9 @@ <on_click function="Places.LandmarksGear.Folding.Action" parameter="expand_all" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="expand_all" /> </menu_item_call> <menu_item_call label="Collapse all folders" @@ -136,17 +145,23 @@ <on_click function="Places.LandmarksGear.Folding.Action" parameter="collapse_all" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="collapse_all" /> </menu_item_call> <menu_item_check label="Sort by Date" layout="topleft" name="sort_by_date"> <on_check - function="Places.LandmarksGear.Enable" + function="Places.LandmarksGear.Check" parameter="sort_by_date" /> <on_click function="Places.LandmarksGear.Folding.Action" parameter="sort_by_date" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="sort_by_date" /> </menu_item_check> <menu_item_call label="Create Pick" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 7c5925550a..7d2ef4923e 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -5523,6 +5523,13 @@ The objects on the selected parcel that are NOT owned by you have been returned <notification icon="notify.tga" + name="ServerObjectMessage" + type="notify"> +[MSG] + </notification> + + <notification + icon="notify.tga" name="NotSafe" type="notify"> This land has damage enabled. diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index 100b2d7aaa..1196d788e4 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -36,15 +36,15 @@ width="5"/> <layout_panel mouse_opaque="false" - auto_resize="true" + auto_resize="false" follows="left|right" height="28" layout="topleft" left="5" min_height="28" - width="450" + width="310" top="0" - min_width="305" + min_width="300" name="chat_bar" user_resize="false" filename="panel_nearby_chat_bar.xml"/> @@ -60,21 +60,88 @@ top="0" width="3"/> <layout_panel + mouse_opaque="false" + auto_resize="false" + follows="right" + height="28" + layout="topleft" + min_height="28" + width="100" + top_delta="-10" + min_width="100" + name="speak_panel" + user_resize="false"> + <chiclet_talk + follows="right" + height="20" + speak_button.font="SansSerifMedium" + speak_button.tab_stop="true" + show_button.tab_stop="true" + layout="topleft" + left="0" + name="talk" + top="6" + width="100" /> + </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="5"/> + <layout_panel + mouse_opaque="false" + auto_resize="false" + follows="right" + height="28" + layout="topleft" + min_height="28" + width="90" + top_delta="-10" + min_width="90" + name="gesture_panel" + user_resize="false"> + <gesture_combo_box + follows="right" + height="20" + label="Gestures" + layout="topleft" + name="Gesture" + left="0" + top="6" + width="90" /> + </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="5"/> + <layout_panel mouse_opaque="false" auto_resize="false" follows="right" height="28" layout="topleft" - left="5" min_height="28" + name="movement_panel" width="70" top_delta="-10" - min_width="70" - name="movement_panel" - user_resize="false"> + min_width="70"> <button - follows="right" + follows="left|right" height="20" + use_ellipses="true" is_toggle="true" label="Move" layout="topleft" @@ -101,7 +168,7 @@ <layout_panel mouse_opaque="false" auto_resize="false" - follows="right" + follows="left|right" height="28" layout="topleft" min_height="28" @@ -110,8 +177,9 @@ top_delta="-10" width="100"> <button - follows="right" + follows="left|right" height="20" + use_ellipses="true" is_toggle="true" label="View" layout="topleft" @@ -124,22 +192,6 @@ function="Button.SetDockableFloaterToggle" parameter="camera" /> </button> - <button - follows="right" - name="camera_presets_btn" - top="6" - height="20" - width="20" - left_pad="0" - is_toggle="true" - picture_style="true" - image_selected="toggle_button_selected" - image_unselected="toggle_button_off"> - <button.init_callback - function="Button.SetDockableFloaterToggle" - parameter="camera_presets" - /> - </button> </layout_panel> <layout_panel mouse_opaque="false" @@ -183,8 +235,10 @@ min_height="28" top="0" name="chiclet_list_panel" - width="150" - user_resize="false"> + width="189" + min_width="189" + user_resize="false" + auto_resize="true"> <chiclet_panel mouse_opaque="false" follows="left|right" @@ -195,7 +249,7 @@ top="1" chiclet_padding="3" scrolling_offset="40" - width="150" /> + width="189" /> </layout_panel> <icon auto_resize="false" @@ -282,4 +336,4 @@ top="0" width="5"/> </layout_stack> -</panel> +</panel>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml index be38492c82..9767a673f6 100644 --- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml @@ -4,7 +4,7 @@ width="146" height="215" border="false"> - <avatar_list_tmp + <avatar_list color="DkGray2" follows="left|top|right|bottom" height="150" diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index 4e1ea0f490..4175d21639 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -8,10 +8,33 @@ layout="topleft" name="navigation_bar" width="600"> + <icon + follows="all" + image_name="NavBar_BG" + mouse_opaque="true" + name="bg_icon" + scale_image="true" + visible="true" + left="0" + top="0" + height="65" + width="600"/> + <icon + follows="all" + image_name="NavBar_BG_NoFav" + mouse_opaque="true" + name="bg_icon_no_fav" + scale_image="true" + visible="false" + left="0" + top="0" + height="65" + width="600"/> <panel background_visible="false" follows="left|top|right" - height="60" + top="5" + height="23" layout="topleft" name="navigation_panel" width="600"> @@ -131,12 +154,12 @@ <favorites_bar follows="left|right|top" - height="25" + height="15" layout="topleft" left="0" name="favorite" image_drag_indication="Arrow_Down" chevron_button_tool_tip="Show more of My Favorites" - bottom="65" + bottom="62" width="590" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml index 4219d9f58f..2fd82d8f3d 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml @@ -7,7 +7,13 @@ left="0" name="chat_bar" top="24" - width="510"> + width="310"> + <string name="min_width"> + 310 + </string> + <string name="max_width"> + 320 + </string> <line_editor border_style="line" border_thickness="1" @@ -45,27 +51,4 @@ tool_tip="Shows/hides nearby chat log"> <button.commit_callback function="Floater.Toggle" parameter="nearby_chat"/> </button> - <chiclet_talk - follows="right" - height="20" - speak_button.font="SansSerifMedium" - speak_button.tab_stop="true" - show_button.tab_stop="true" - layout="topleft" - left_pad="5" - name="talk" - top="3" - width="100" - speak_button.tool_tip="Turns microphone on/off" - show_button.tool_tip="Shows/hides voice control panel" /> - <gesture_combo_box - follows="right" - height="20" - label="Gestures" - layout="topleft" - name="Gesture" - left_pad="5" - top="3" - width="90" - tool_tip="Shows/hides gestures" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 085b732473..7b19ab1a1c 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -66,11 +66,13 @@ background_visible="true" top="0" width="313"> <avatar_list + allow_select="true" follows="all" height="470" ignore_online_status="true" layout="topleft" left="0" + multi_select="true" name="avatar_list" top="0" volume_column_width="20" @@ -124,10 +126,12 @@ background_visible="true" name="tab_online" title="Online"> <avatar_list + allow_select="true" follows="all" height="150" layout="topleft" left="0" + multi_select="true" name="avatars_online" top="0" width="313" /> @@ -139,10 +143,12 @@ background_visible="true" name="tab_all" title="All"> <avatar_list + allow_select="true" follows="all" height="230" layout="topleft" left="0" + multi_select="true" name="avatars_all" top="0" width="313" /> @@ -288,10 +294,12 @@ background_visible="true" name="recent_panel" width="313"> <avatar_list + allow_select="true" follows="all" height="470" layout="topleft" left="0" + multi_select="true" name="avatar_list" top="2" width="313" /> diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml index ac2cf19a96..cbe1f11e3d 100644 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_picks.xml @@ -71,59 +71,60 @@ width="18" /> </panel> <panel - follows="bottom" - auto_resize="false" layout="topleft" - height="19" + left="0" + height="25" + top_pad="10" name="buttons_cucks" + help_topic="picks_button_tab" width="313"> <button + enabled="false" follows="bottom|left" - height="19" - label="Add" + font="SansSerifSmallBold" + height="25" + label="Info" layout="topleft" - left="0" - mouse_opaque="false" - name="add_friend" - top="5" + left="5" + name="info_btn" + tab_stop="false" + top="0" width="55" /> <button - follows="bottom|left" - height="19" - label="IM" - layout="topleft" - name="im" - top="5" - left_pad="5" - width="40" /> - <button enabled="false" follows="bottom|left" - height="19" - label="Call" + font="SansSerifSmallBold" + height="25" + label="Teleport" layout="topleft" - name="call" left_pad="5" - top="5" - width="55" /> + name="teleport_btn" + tab_stop="false" + top="0" + width="77" /> <button enabled="false" follows="bottom|left" - height="19" + font="SansSerifSmallBold" + height="25" label="Map" layout="topleft" - name="show_on_map_btn" - top="5" left_pad="5" + name="show_on_map_btn" + tab_stop="false" + top="0" width="50" /> <button - follows="bottom|left" - height="19" - label="Teleport" + enabled="false" + follows="bottom|right" + font="SansSerifSmallBold" + height="25" + label="▼" layout="topleft" - name="teleport" - left_pad="5" - top="5" - width="90" /> + name="overflow_btn" + right="-10" + tab_stop="false" + top="0" + width="30" /> </panel> </panel> |