diff options
Diffstat (limited to 'indra')
-rwxr-xr-x | indra/llui/llfolderviewitem.h | 1 | ||||
-rw-r--r-- | indra/newview/llconversationmodel.cpp | 5 | ||||
-rwxr-xr-x | indra/newview/llconversationmodel.h | 5 | ||||
-rwxr-xr-x | indra/newview/llconversationview.cpp | 194 | ||||
-rwxr-xr-x | indra/newview/llconversationview.h | 33 | ||||
-rwxr-xr-x | indra/newview/llimfloatercontainer.cpp | 63 | ||||
-rw-r--r-- | indra/newview/llinventoryicon.h | 2 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_conversation_list_item.xml | 78 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml | 9 |
9 files changed, 339 insertions, 51 deletions
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index fab24e52d1..7025b94a9a 100755 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -114,7 +114,6 @@ protected: static LLFontGL* getLabelFontForStyle(U8 style); -private: BOOL mIsSelected; public: diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index e810bac1d9..c36c3cbc65 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -93,6 +93,11 @@ LLConversationItemSession::LLConversationItemSession(const LLUUID& uuid, LLFolde { } +bool LLConversationItemSession::hasChildren() const +{ + return getChildrenCount() > 0; +} + void LLConversationItemSession::addParticipant(LLConversationItemParticipant* participant) { addChild(participant); diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index e1713f9db7..c340194dd3 100755 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -104,7 +104,7 @@ public: // bool hasSameValues(std::string name, const LLUUID& uuid) { return ((name == mName) && (uuid == mUUID)); } bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); } - + void resetRefresh() { mNeedsRefresh = false; } bool needsRefresh() { return mNeedsRefresh; } @@ -121,6 +121,7 @@ public: LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model); virtual ~LLConversationItemSession() {} + /*virtual*/ bool hasChildren() const; LLPointer<LLUIImage> getIcon() const { return NULL; } void setSessionID(const LLUUID& session_id) { mUUID = session_id; mNeedsRefresh = true; } void addParticipant(LLConversationItemParticipant* participant); @@ -153,7 +154,7 @@ public: void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; } void onAvatarNameCache(const LLAvatarName& av_name); - + void dumpDebugData(); private: diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index bc85cd68bc..208a89cc8d 100755 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -39,6 +39,7 @@ // // Implementation of conversations list session widgets // +static LLDefaultChildRegistry::Register<LLConversationViewSession> r_conversation_view_session("conversation_view_session"); @@ -46,12 +47,196 @@ LLConversationViewSession::Params::Params() : container() {} -LLConversationViewSession::LLConversationViewSession( const LLConversationViewSession::Params& p ): +LLConversationViewSession::LLConversationViewSession(const LLConversationViewSession::Params& p): LLFolderViewFolder(p), - mContainer(p.container) + mContainer(p.container), + mItemPanel(NULL), + mSessionTitle(NULL) { } +BOOL LLConversationViewSession::postBuild() +{ + LLFolderViewItem::postBuild(); + + mItemPanel = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>("panel_conversation_list_item.xml", NULL, LLPanel::child_registry_t::instance()); + + addChild(mItemPanel); + + mSessionTitle = mItemPanel->getChild<LLTextBox>("conversation_title"); + + refresh(); + + 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 ***** + const LLColor4U DEFAULT_WHITE(255, 255, 255); + + 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 + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLColor4 bg_color = sHighlightBgColor; + if (!mIsCurSelection) + { + // 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 + { + // fading in + bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]); + } + } + gl_rect_2d(FOCUS_LEFT, + focus_top, + getRect().getWidth() - 2, + focus_bottom, + bg_color, filled); + if (mIsCurSelection) + { + gl_rect_2d(FOCUS_LEFT, + focus_top, + getRect().getWidth() - 2, + focus_bottom, + sFocusOutlineColor, FALSE); + } + if (folder_open) + { + gl_rect_2d(FOCUS_LEFT, + focus_bottom + 1, // overlap with bottom edge of above rect + getRect().getWidth() - 2, + 0, + sFocusOutlineColor, FALSE); + if (show_context) + { + gl_rect_2d(FOCUS_LEFT, + focus_bottom + 1, + getRect().getWidth() - 2, + 0, + sHighlightBgColor, TRUE); + } + } + } + else if (mIsMouseOverTitle) + { + gl_rect_2d(FOCUS_LEFT, + focus_top, + getRect().getWidth() - 2, + focus_bottom, + sMouseOverColor, FALSE); + } + + //--------------------------------------------------------------------------------// + // Draw DragNDrop highlight + // + if (mDragAndDropTarget) + { + 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; + } +// ***** LLFolderViewItem::draw() code end ***** + + // 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) + || isOpen() + || mCurHeight != mTargetHeight; + + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->setVisible(draw_children); + } + for (items_t::iterator iter = mItems.begin(); + iter != mItems.end();) + { + items_t::iterator iit = iter++; + (*iit)->setVisible(draw_children); + } + + LLView::draw(); +} + +// virtual +S32 LLConversationViewSession::arrange(S32* width, S32* height) +{ + LLRect rect(getIndentation() + ARROW_SIZE, + getLocalRect().mTop, + getLocalRect().mRight, + getLocalRect().mTop - getItemHeight()); + mItemPanel->setShape(rect); + + return LLFolderViewFolder::arrange(width, height); +} + void LLConversationViewSession::selectItem() { LLFolderViewItem::selectItem(); @@ -109,6 +294,11 @@ void LLConversationViewSession::refresh() LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem()); vmi->resetRefresh(); + if (mSessionTitle) + { + mSessionTitle->setText(vmi->getDisplayName()); + } + // Note: for the moment, all that needs to be done is done by LLFolderViewItem::refresh() // Do the regular upstream refresh diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index 686a79ad39..3dbc36e811 100755 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h @@ -32,6 +32,7 @@ #include "llbutton.h" #include "lloutputmonitorctrl.h" +class LLTextBox; class LLIMFloaterContainer; class LLConversationViewSession; class LLConversationViewParticipant; @@ -57,10 +58,20 @@ protected: public: virtual ~LLConversationViewSession( void ) { } virtual void selectItem(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void draw(); + + /*virtual*/ S32 arrange(S32* width, S32* height); + void setVisibleIfDetached(BOOL visible); LLConversationViewParticipant* findParticipant(const LLUUID& participant_id); virtual void refresh(); + +private: + LLPanel* mItemPanel; + LLTextBox* mSessionTitle; }; // Implementation of conversations list participant (avatar) widgets @@ -70,16 +81,16 @@ class LLConversationViewParticipant : public LLFolderViewItem public: - struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params> - { + struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params> + { Optional<LLIMFloaterContainer*> container; - Optional<LLUUID> participant_id; + Optional<LLUUID> participant_id; Optional<LLButton::Params> info_button; Optional<LLOutputMonitorCtrl::Params> output_monitor; - - Params(); - }; - + + Params(); + }; + virtual ~LLConversationViewParticipant( void ) { } bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); } virtual void refresh(); @@ -90,16 +101,16 @@ public: protected: friend class LLUICtrlFactory; - LLConversationViewParticipant( const Params& p ); + LLConversationViewParticipant( const Params& p ); void initFromParams(const Params& params); BOOL postBuild(); - - void onInfoBtnClick(); + void onInfoBtnClick(); + private: LLButton * mInfoBtn; LLOutputMonitorCtrl* mSpeakingIndicator; - LLUUID mUUID; // UUID of the participant + LLUUID mUUID; // UUID of the participant typedef enum e_avatar_item_child { ALIC_SPEAKER_INDICATOR, diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index 299d38298e..54a40627fb 100755 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -38,6 +38,7 @@ #include "llavataractions.h" #include "llavatariconctrl.h" #include "llavatarnamecache.h" +#include "llcallbacklist.h" #include "llgroupiconctrl.h" #include "llfloateravatarpicker.h" #include "llfloaterpreference.h" @@ -120,18 +121,31 @@ BOOL LLIMFloaterContainer::postBuild() // Create the root model and view for all conversation sessions LLConversationItem* base_item = new LLConversationItem(getRootViewModel()); - LLFolderView::Params p; - p.view_model = &mConversationViewModel; - p.parent_panel = mConversationsListPanel; - p.rect = mConversationsListPanel->getLocalRect(); - p.follows.flags = FOLLOWS_ALL; - p.listener = base_item; - p.root = NULL; + LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>()); + p.name = getName(); + p.title = getLabel(); + p.rect = LLRect(0, 0, getRect().getWidth(), 0); + p.parent_panel = mConversationsListPanel; + p.tool_tip = p.name; + p.listener = base_item; + p.view_model = &mConversationViewModel; + p.root = NULL; mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p); - mConversationsRoot->setVisible(TRUE); - - mConversationsListPanel->addChild(mConversationsRoot); + + // a scroller for folder view + LLRect scroller_view_rect = mConversationsListPanel->getRect(); + scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); + LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>()); + scroller_params.rect(scroller_view_rect); + + LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params); + scroller->setFollowsAll(); + mConversationsListPanel->addChild(scroller); + scroller->addChild(mConversationsRoot); + mConversationsRoot->setScrollContainer(scroller); + mConversationsRoot->setFollowsAll(); + mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox); addConversationListItem(LLUUID()); // manually add nearby chat @@ -154,6 +168,7 @@ BOOL LLIMFloaterContainer::postBuild() mConversationsPane->handleReshape(list_size, TRUE); } + mInitialized = true; // Add callback: we'll take care of view updates on idle @@ -310,11 +325,11 @@ void LLIMFloaterContainer::setMinimized(BOOL b) } } -//static +// static void LLIMFloaterContainer::idle(void* user_data) { - LLIMFloaterContainer* panel = (LLIMFloaterContainer*)user_data; - panel->mConversationsRoot->update(); + LLIMFloaterContainer* self = static_cast<LLIMFloaterContainer*>(user_data); + self->mConversationsRoot->update(); } void LLIMFloaterContainer::draw() @@ -354,7 +369,6 @@ void LLIMFloaterContainer::draw() { participant_view = createConversationViewParticipant(participant_model); participant_view->addToFolder(session_view); - mConversationsListPanel->addChild(participant_view); participant_view->setVisible(TRUE); } else @@ -372,13 +386,6 @@ void LLIMFloaterContainer::draw() } } - // CHUI-308 : Hack! We shouldn't have to do that but we have too as long as - // we don't have a scroll container. - // *TODO: Take those 3 lines out once we implement the scroll container. - repositioningWidgets(); - mConversationsRoot->setRect(mConversationsListPanel->getLocalRect()); - mConversationsRoot->setFollowsAll(); - if (mTabContainer->getTabCount() == 0) { // Do not close the container when every conversation is torn off because the user @@ -642,9 +649,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid) // Add a new conversation widget to the root folder of the folder view widget->addToFolder(mConversationsRoot); - - // Add it to the UI - widget->setVisible(TRUE); + widget->requestArrange(); // Create the participants widgets now // Note: usually, we do not get an updated avatar list at that point @@ -655,12 +660,8 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid) LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model); LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model); participant_view->addToFolder(widget); - mConversationsListPanel->addChild(participant_view); - participant_view->setVisible(TRUE); current_participant_model++; } - - repositioningWidgets(); return; } @@ -680,8 +681,6 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c // Suppress the conversation items and widgets from their respective maps mConversationsItems.erase(uuid); mConversationsWidgets.erase(uuid); - - repositioningWidgets(); // Don't let the focus fall IW, select and refocus on the first conversation in the list if (change_focus) @@ -701,12 +700,8 @@ LLConversationViewSession* LLIMFloaterContainer::createConversationItemWidget(LL LLConversationViewSession::Params params; params.name = item->getDisplayName(); - //params.icon = bridge->getIcon(); - //params.icon_open = bridge->getOpenIcon(); - //params.creation_date = bridge->getCreationDate(); params.root = mConversationsRoot; params.listener = item; - params.rect = LLRect (0, 0, 0, 0); params.tool_tip = params.name; params.container = this; diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h index c7e2998a20..5c8acf9e85 100644 --- a/indra/newview/llinventoryicon.h +++ b/indra/newview/llinventoryicon.h @@ -1,5 +1,5 @@ /** - * @file llinventoryfunctions.h + * @file llinventoryicon.h * @brief Miscellaneous inventory-related functions and classes * class definition * diff --git a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml new file mode 100644 index 0000000000..375ea79ebe --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="left|top|right" + height="24" + layout="topleft" + name="conversation_list_item" + mouse_opaque="false" + width="120"> + <avatar_icon + follows="top|left" + height="20" + default_icon_name="Generic_Person" + layout="topleft" + left="5" + top="2" + width="20" /> + <layout_stack + animate="false" + follows="all" + height="24" + layout="topleft" + left_pad="5" + mouse_opaque="false" + name="conversation_item_stack" + orientation="horizontal" + top="0" + width="90"> + <layout_panel + auto_resize="false" + user_resize="false" + height="24" + mouse_opaque="false" + name="call_icon_panel" + visible="false" + width="20"> + <icon + height="20" + follows="top|right|left" + image_name="Conv_toolbar_hang_up" + layout="topleft" + left="0" + name="selected_icon" + top="2" + width="20" /> + </layout_panel> + <layout_panel + auto_resize="true" + user_resize="false" + height="24" + mouse_opaque="false" + name="conversation_title_panel" + width="70"> + <text + follows="left|top|right" + font="SansSerifSmall" + height="15" + layout="topleft" + left="5" + name="conversation_title" + parse_urls="false" + top="6" + use_ellipses="true" + value="(loading)" + width="35" /> + <output_monitor + auto_update="true" + follows="top|right" + draw_border="false" + height="16" + layout="topleft" + left_pad="5" + mouse_opaque="true" + name="speaking_indicator" + visible="false" + width="20" /> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml new file mode 100644 index 0000000000..f44731ea3d --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<conversation_view_session + folder_arrow_image="Folder_Arrow" + folder_indentation="8" + item_height="24" + item_top_pad="4" + selection_image="Rounded_Square" + mouse_opaque="true" + follows="left|top|right"/> |