summaryrefslogtreecommitdiff
path: root/indra/newview/llconversationview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llconversationview.cpp')
-rwxr-xr-xindra/newview/llconversationview.cpp319
1 files changed, 181 insertions, 138 deletions
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 721abd5892..d4eb551f7a 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -30,10 +30,12 @@
#include "llconversationview.h"
#include <boost/bind.hpp>
+#include "llagentdata.h"
#include "llconversationmodel.h"
#include "llimconversation.h"
#include "llimfloatercontainer.h"
#include "llfloaterreg.h"
+#include "llgroupiconctrl.h"
#include "lluictrlfactory.h"
//
@@ -43,6 +45,30 @@ static LLDefaultChildRegistry::Register<LLConversationViewSession> r_conversatio
const LLColor4U DEFAULT_WHITE(255, 255, 255);
+class LLNearbyVoiceClientStatusObserver : public LLVoiceClientStatusObserver
+{
+public:
+
+ LLNearbyVoiceClientStatusObserver(LLConversationViewSession* conv)
+ : conversation(conv)
+ {}
+
+ virtual void onChange(EStatusType status, const std::string &channelURI, bool proximal)
+ {
+ if (conversation
+ && status != STATUS_JOINING
+ && status != STATUS_LEFT_CHANNEL
+ && LLVoiceClient::getInstance()->voiceEnabled()
+ && LLVoiceClient::getInstance()->isVoiceWorking())
+ {
+ conversation->showVoiceIndicator();
+ }
+ }
+
+private:
+ LLConversationViewSession* conversation;
+};
+
LLConversationViewSession::Params::Params() :
container()
{}
@@ -51,157 +77,109 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes
LLFolderViewFolder(p),
mContainer(p.container),
mItemPanel(NULL),
- mSessionTitle(NULL)
+ mCallIconLayoutPanel(NULL),
+ mSessionTitle(NULL),
+ mSpeakingIndicator(NULL),
+ mVoiceClientObserver(NULL),
+ mMinimizedMode(false)
{
}
+LLConversationViewSession::~LLConversationViewSession()
+{
+ mActiveVoiceChannelConnection.disconnect();
+
+ if(LLVoiceClient::instanceExists() && mVoiceClientObserver)
+ {
+ LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
+ }
+}
+
BOOL LLConversationViewSession::postBuild()
{
LLFolderViewItem::postBuild();
mItemPanel = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>("panel_conversation_list_item.xml", NULL, LLPanel::child_registry_t::instance());
-
addChild(mItemPanel);
+ mCallIconLayoutPanel = mItemPanel->getChild<LLPanel>("call_icon_panel");
mSessionTitle = mItemPanel->getChild<LLTextBox>("conversation_title");
- refresh();
+ mActiveVoiceChannelConnection = LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLConversationViewSession::onCurrentVoiceSessionChanged, this, _1));
+ mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicatorn");
- return TRUE;
-}
-
-void LLConversationViewSession::draw()
-{
-// *TODO Seth PE: remove the code duplicated from LLFolderViewFolder::draw()
-// ***** LLFolderViewFolder::draw() code begin *****
- if (mAutoOpenCountdown != 0.f)
- {
- mControlLabelRotation = mAutoOpenCountdown * -90.f;
- }
- else if (isOpen())
- {
- mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
- }
- else
- {
- mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
- }
-// ***** LLFolderViewFolder::draw() code end *****
-
-// *TODO Seth PE: remove the code duplicated from LLFolderViewItem::draw()
-// ***** LLFolderViewItem::draw() code begin *****
-
- static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
- static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
- static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
- static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
-
- const LLFolderViewItem::Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
- const S32 TOP_PAD = default_params.item_top_pad;
- const S32 FOCUS_LEFT = 1;
-
- getViewModelItem()->update();
-
- //--------------------------------------------------------------------------------//
- // Draw open folder arrow
- //
- if (hasVisibleChildren() || getViewModelItem()->hasChildren())
- {
- LLUIImage* arrow_image = default_params.folder_arrow_image;
- gl_draw_scaled_rotated_image(
- mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD - TOP_PAD,
- ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, arrow_image->getImage(), sFgColor);
- }
-
-
- //--------------------------------------------------------------------------------//
- // Draw highlight for selected items
- //
- const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
- const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
- const S32 focus_top = getRect().getHeight();
- const S32 focus_bottom = getRect().getHeight() - mItemHeight;
- const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
- if (mIsSelected) // always render "current" item. Only render other selected items if mShowSingleSelection is FALSE
+ LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+ if (vmi)
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLColor4 bg_color = sHighlightBgColor;
- if (!mIsCurSelection)
+ switch(vmi->getType())
{
- // do time-based fade of extra objects
- F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
- if (getRoot() && getRoot()->getShowSingleSelection())
- {
- // fading out
- bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
- }
- else
+ case LLConversationItem::CONV_PARTICIPANT:
+ case LLConversationItem::CONV_SESSION_1_ON_1:
+ {
+ LLIMModel::LLIMSession* session= LLIMModel::instance().findIMSession(vmi->getUUID());
+ if (session)
{
- // fading in
- bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
+ LLAvatarIconCtrl* icon = mItemPanel->getChild<LLAvatarIconCtrl>("avatar_icon");
+ icon->setVisible(true);
+ icon->setValue(session->mOtherParticipantID);
+ mSpeakingIndicator->setSpeakerId(gAgentID, session->mSessionID, true);
}
+ break;
}
- gl_rect_2d(FOCUS_LEFT,
- focus_top,
- getRect().getWidth() - 2,
- focus_bottom,
- bg_color, filled);
- if (mIsCurSelection)
+ case LLConversationItem::CONV_SESSION_AD_HOC:
{
- gl_rect_2d(FOCUS_LEFT,
- focus_top,
- getRect().getWidth() - 2,
- focus_bottom,
- sFocusOutlineColor, FALSE);
+ LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon");
+ icon->setVisible(true);
+ mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID(), true);
}
- if (folder_open)
+ case LLConversationItem::CONV_SESSION_GROUP:
{
- gl_rect_2d(FOCUS_LEFT,
- focus_bottom + 1, // overlap with bottom edge of above rect
- getRect().getWidth() - 2,
- 0,
- sFocusOutlineColor, FALSE);
- if (show_context)
+ LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon");
+ icon->setVisible(true);
+ icon->setValue(vmi->getUUID());
+ mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID(), true);
+ break;
+ }
+ case LLConversationItem::CONV_SESSION_NEARBY:
+ {
+ LLIconCtrl* icon = mItemPanel->getChild<LLIconCtrl>("nearby_chat_icon");
+ icon->setVisible(true);
+ mSpeakingIndicator->setSpeakerId(gAgentID, LLUUID::null, true);
+ if(LLVoiceClient::instanceExists())
{
- gl_rect_2d(FOCUS_LEFT,
- focus_bottom + 1,
- getRect().getWidth() - 2,
- 0,
- sHighlightBgColor, TRUE);
+ LLNearbyVoiceClientStatusObserver* mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this);
+ LLVoiceClient::getInstance()->addObserver(mVoiceClientObserver);
}
+ break;
+ }
+ default:
+ break;
}
- }
- else if (mIsMouseOverTitle)
- {
- gl_rect_2d(FOCUS_LEFT,
- focus_top,
- getRect().getWidth() - 2,
- focus_bottom,
- sMouseOverColor, FALSE);
}
- //--------------------------------------------------------------------------------//
- // Draw DragNDrop highlight
- //
- if (mDragAndDropTarget)
+ refresh();
+
+ return TRUE;
+}
+
+void LLConversationViewSession::draw()
+{
+ getViewModelItem()->update();
+
+ const LLFolderViewItem::Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
+ const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
+
+ // we don't draw the open folder arrow in minimized mode
+ if (!mMinimizedMode)
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gl_rect_2d(FOCUS_LEFT,
- focus_top,
- getRect().getWidth() - 2,
- focus_bottom,
- sHighlightBgColor, FALSE);
- if (folder_open)
- {
- gl_rect_2d(FOCUS_LEFT,
- focus_bottom + 1, // overlap with bottom edge of above rect
- getRect().getWidth() - 2,
- 0,
- sHighlightBgColor, FALSE);
- }
- mDragAndDropTarget = FALSE;
+ // update the rotation angle of open folder arrow
+ updateLabelRotation();
+
+ drawOpenFolderArrow(default_params, sFgColor);
}
-// ***** LLFolderViewItem::draw() code end *****
+
+ // draw highlight for selected items
+ drawHighlight(show_context, true, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
// draw children if root folder, or any other folder that is open or animating to closed state
bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this)
@@ -227,7 +205,8 @@ void LLConversationViewSession::draw()
// virtual
S32 LLConversationViewSession::arrange(S32* width, S32* height)
{
- LLRect rect(getIndentation() + ARROW_SIZE,
+ S32 h_pad = getIndentation() + mArrowSize;
+ LLRect rect(mMinimizedMode ? getLocalRect().mLeft : h_pad,
getLocalRect().mTop,
getLocalRect().mRight,
getLocalRect().mTop - getItemHeight());
@@ -236,6 +215,16 @@ S32 LLConversationViewSession::arrange(S32* width, S32* height)
return LLFolderViewFolder::arrange(width, height);
}
+// virtual
+void LLConversationViewSession::toggleOpen()
+{
+ // conversations should not be opened while in minimized mode
+ if (!mMinimizedMode)
+ {
+ LLFolderViewFolder::toggleOpen();
+ }
+}
+
void LLConversationViewSession::selectItem()
{
@@ -257,6 +246,18 @@ void LLConversationViewSession::selectItem()
LLFolderViewItem::selectItem();
}
+void LLConversationViewSession::toggleMinimizedMode(bool is_minimized)
+{
+ mMinimizedMode = is_minimized;
+
+ // hide the layout stack which contains all item's child widgets
+ // except for the icon which we display in minimized mode
+ getChild<LLView>("conversation_item_stack")->setVisible(!mMinimizedMode);
+
+ S32 h_pad = getIndentation() + mArrowSize;
+ mItemPanel->translate(mMinimizedMode ? -h_pad : h_pad, 0);
+}
+
void LLConversationViewSession::setVisibleIfDetached(BOOL visible)
{
// Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized
@@ -288,6 +289,14 @@ LLConversationViewParticipant* LLConversationViewSession::findParticipant(const
return (iter == getItemsEnd() ? NULL : participant);
}
+void LLConversationViewSession::showVoiceIndicator()
+{
+ if (LLVoiceChannel::getCurrentVoiceChannel()->getSessionID().isNull())
+ {
+ mCallIconLayoutPanel->setVisible(true);
+ }
+}
+
void LLConversationViewSession::refresh()
{
// Refresh the session view from its model data
@@ -305,6 +314,25 @@ void LLConversationViewSession::refresh()
LLFolderViewFolder::refresh();
}
+void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& session_id)
+{
+ LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+
+ if (vmi)
+ {
+ bool is_active = vmi->getUUID() == session_id;
+ bool is_nearby = vmi->getType() == LLConversationItem::CONV_SESSION_NEARBY;
+
+ if (is_nearby)
+ {
+ mSpeakingIndicator->setSpeakerId(is_active ? gAgentID : LLUUID::null);
+ }
+
+ mSpeakingIndicator->switchIndicator(is_active);
+ mCallIconLayoutPanel->setVisible(is_active);
+ }
+}
+
//
// Implementation of conversations list participant (avatar) widgets
//
@@ -336,7 +364,7 @@ void LLConversationViewParticipant::initFromParams(const LLConversationViewParti
applyXUILayout(avatar_icon_params, this);
LLAvatarIconCtrl * avatarIcon = LLUICtrlFactory::create<LLAvatarIconCtrl>(avatar_icon_params);
addChild(avatarIcon);
-
+
LLButton::Params info_button_params(params.info_button());
applyXUILayout(info_button_params, this);
LLButton * button = LLUICtrlFactory::create<LLButton>(info_button_params);
@@ -366,7 +394,7 @@ BOOL LLConversationViewParticipant::postBuild()
sStaticInitialized = true;
}
- computeLabelRightPadding();
+ updateChildren();
return LLFolderViewItem::postBuild();
}
@@ -381,16 +409,11 @@ void LLConversationViewParticipant::draw()
const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
- const LLFolderViewItem::Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
- const S32 TOP_PAD = default_params.item_top_pad;
-
const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
F32 right_x = 0;
- //TEXT_PAD, TOP_PAD, ICON_PAD and mIndentation are temporary values and will non-const eventually since they don't
- //apply to every single layout
- F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
- F32 text_left = (F32)(mAvatarIcon->getRect().mRight + ICON_PAD + mIndentation);
+ F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad;
+ F32 text_left = (F32)getLabelXPos();
LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
drawHighlight(show_context, filled, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
@@ -437,15 +460,20 @@ void LLConversationViewParticipant::onInfoBtnClick()
void LLConversationViewParticipant::onMouseEnter(S32 x, S32 y, MASK mask)
{
mInfoBtn->setVisible(true);
- computeLabelRightPadding();
+ updateChildren();
LLFolderViewItem::onMouseEnter(x, y, mask);
}
void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask)
{
mInfoBtn->setVisible(false);
- computeLabelRightPadding();
- LLFolderViewItem::onMouseEnter(x, y, mask);
+ updateChildren();
+ LLFolderViewItem::onMouseLeave(x, y, mask);
+}
+
+S32 LLConversationViewParticipant::getLabelXPos()
+{
+ return mAvatarIcon->getRect().mRight + mIconPad;
}
// static
@@ -463,12 +491,14 @@ void LLConversationViewParticipant::initChildrenWidths(LLConversationViewPartici
llassert(index == 0);
}
-void LLConversationViewParticipant::computeLabelRightPadding()
+void LLConversationViewParticipant::updateChildren()
{
- mLabelPaddingRight = DEFAULT_TEXT_PADDING_RIGHT;
+ mLabelPaddingRight = DEFAULT_LABEL_PADDING_RIGHT;
LLView* control;
S32 ctrl_width;
+ LLRect controlRect;
+ //Cycles through controls starting from right to left
for (S32 i = 0; i < ALIC_COUNT; ++i)
{
control = getItemChildView((EAvatarListItemChildIndex)i);
@@ -476,9 +506,22 @@ void LLConversationViewParticipant::computeLabelRightPadding()
// skip invisible views
if (!control->getVisible()) continue;
+ //Get current pos/dimensions
+ controlRect = control->getRect();
+
ctrl_width = sChildrenWidths[i]; // including space between current & left controls
// accumulate the amount of space taken by the controls
mLabelPaddingRight += ctrl_width;
+
+ //Reposition visible controls in case adjacent controls to the right are hidden.
+ controlRect.setLeftTopAndSize(
+ getLocalRect().getWidth() - mLabelPaddingRight,
+ controlRect.mTop,
+ controlRect.getWidth(),
+ controlRect.getHeight());
+
+ //Sets the new position
+ control->setShape(controlRect);
}
}