diff options
-rw-r--r-- | indra/newview/app_settings/commands.xml | 6 | ||||
-rw-r--r-- | indra/newview/llfolderviewitem.cpp | 38 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.cpp | 150 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.h | 88 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/strings.xml | 2 |
5 files changed, 265 insertions, 19 deletions
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index 73df064ab2..51211a8ce5 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -46,11 +46,11 @@ available_in_toybox="true" icon="Command_Chat_Icon" label_ref="Command_Chat_Label" - tooltip_ref="Command_Chat_Tooltip" + tooltip_ref="Command_Conversations_Tooltip" execute_function="Floater.ToggleOrBringToFront" - execute_parameters="chat_bar" + execute_parameters="im_container" is_running_function="Floater.IsOpen" - is_running_parameters="chat_bar" + is_running_parameters="im_container" /> <command name="compass" available_in_toybox="false" diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index f40f051537..8ae779326c 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -293,7 +293,7 @@ void LLFolderViewItem::refreshFromListener() setCreationDate(creation_date); dirtyFilter(); } - if (mRoot->useLabelSuffix()) + if (mRoot && mRoot->useLabelSuffix()) { mLabelStyle = mListener->getLabelStyle(); mLabelSuffix = mListener->getLabelSuffix(); @@ -383,7 +383,14 @@ void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus) { - getRoot()->setSelection(selection, openitem, take_keyboard_focus); + if (getRoot()) + { + getRoot()->setSelection(selection, openitem, take_keyboard_focus); + } + else if (mListener) + { + mListener->selectItem(); + } } // helper function to change the selection from the root. @@ -760,7 +767,10 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask ) } else { - getRoot()->setShowSelectionContext(FALSE); + if (getRoot()) + { + getRoot()->setShowSelectionContext(FALSE); + } gViewerWindow->setCursor(UI_CURSOR_ARROW); // let parent handle this then... return FALSE; @@ -803,7 +813,10 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask ) if( hasMouseCapture() ) { - getRoot()->setShowSelectionContext(FALSE); + if (getRoot()) + { + getRoot()->setShowSelectionContext(FALSE); + } gFocusMgr.setMouseCapture( NULL ); } return TRUE; @@ -870,8 +883,9 @@ void LLFolderViewItem::draw() const S32 FOCUS_LEFT = 1; const LLFontGL* font = getLabelFontForStyle(mLabelStyle); - const BOOL in_inventory = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getRootFolderID()); - const BOOL in_library = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getLibraryRootFolderID()); + const LLUUID uuid = (getListener() ? getListener()->getUUID() : LLUUID::null); + const BOOL in_inventory = (uuid.notNull() ? gInventory.isObjectDescendentOf(uuid, gInventory.getRootFolderID()) : FALSE); + const BOOL in_library = (uuid.notNull() ? gInventory.isObjectDescendentOf(uuid, gInventory.getLibraryRootFolderID()) : FALSE); //--------------------------------------------------------------------------------// // Draw open folder arrow @@ -891,8 +905,8 @@ void LLFolderViewItem::draw() //--------------------------------------------------------------------------------// // Draw highlight for selected items // - const BOOL show_context = getRoot()->getShowSelectionContext(); - const BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus()); // If we have keyboard focus, draw selection filled + 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); @@ -903,8 +917,8 @@ void LLFolderViewItem::draw() if (!mIsCurSelection) { // do time-based fade of extra objects - F32 fade_time = getRoot()->getSelectionFadeElapsedTime(); - if (getRoot()->getShowSingleSelection()) + 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); @@ -1015,7 +1029,7 @@ void LLFolderViewItem::draw() //--------------------------------------------------------------------------------// // Highlight filtered text // - if (getRoot()->getDebugFilters()) + if (getRoot() && getRoot()->getDebugFilters()) { if (!getFiltered() && !possibly_has_children) { @@ -1076,7 +1090,7 @@ void LLFolderViewItem::draw() if (mStringMatchOffset != std::string::npos) { // don't draw backgrounds for zero-length strings - S32 filter_string_length = getRoot()->getFilterSubString().size(); + S32 filter_string_length = (getRoot() ? getRoot()->getFilterSubString().size() : 0); if (filter_string_length > 0) { std::string combined_string = mLabel + mLabelSuffix; diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index 3b6240de44..af5d587f20 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" +#include "llimfloater.h" #include "llimfloatercontainer.h" #include "llfloaterreg.h" @@ -34,8 +35,10 @@ #include "llnearbychat.h" #include "llagent.h" +#include "llavataractions.h" #include "llavatariconctrl.h" #include "llgroupiconctrl.h" +#include "llfloateravatarpicker.h" #include "llimview.h" #include "lltransientfloatermgr.h" #include "llviewercontrol.h" @@ -71,10 +74,14 @@ BOOL LLIMFloaterContainer::postBuild() mConversationsStack = getChild<LLLayoutStack>("conversations_stack"); mConversationsPane = getChild<LLLayoutPanel>("conversations_layout_panel"); mMessagesPane = getChild<LLLayoutPanel>("messages_layout_panel"); + + mConversationsListPanel = getChild<LLPanel>("conversations_list_panel"); mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn"); mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloaterContainer::onExpandCollapseButtonClicked, this)); + childSetAction("add_btn", boost::bind(&LLIMFloaterContainer::onAddButtonClicked, this)); + collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed")); collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed")); @@ -84,7 +91,15 @@ BOOL LLIMFloaterContainer::postBuild() void LLIMFloaterContainer::onOpen(const LLSD& key) { LLMultiFloater::onOpen(key); -/* + if (getFloaterCount() == 0) + { + // If there's *no* conversation open so far, we force the opening of the nearby chat conversation + // *TODO: find a way to move this to XML as a default panel or something like that + LLSD name("chat_bar"); + LLSD key(""); + LLFloaterReg::toggleInstanceOrBringToFront(name,key); + } + /* if (key.isDefined()) { LLIMFloater* im_floater = LLIMFloater::findInstance(key.asUUID()); @@ -93,7 +108,7 @@ void LLIMFloaterContainer::onOpen(const LLSD& key) im_floater->openFloater(); } } -*/ + */ } // virtual @@ -112,14 +127,33 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp, LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point); + LLUUID session_id = floaterp->getKey(); + + // CHUI-137 : Temporary implementation of conversations list + // Create a conversation item + LLConversationItem* item = new LLConversationItem(floaterp->getTitle(),session_id, floaterp, this); + mConversationsItems[session_id] = item; + // Create a widget from it + LLFolderViewItem* widget = createConversationItemWidget(item); + mConversationsWidgets[session_id] = widget; + // Add it to the UI + widget->setVisible(TRUE); + mConversationsListPanel->addChild(widget); + LLRect panel_rect = mConversationsListPanel->getRect(); + S32 item_height = 16; + S32 index = mConversationsWidgets.size() - 1; + widget->setRect(LLRect(0, + panel_rect.getHeight() - item_height*index, + panel_rect.getWidth(), + panel_rect.getHeight() - item_height*(index+1))); + // CHUI-137 : end + LLView* floater_contents = floaterp->getChild<LLView>("contents_view"); // we don't show the header when the floater is hosted, // so reshape floater contents to occupy the header space floater_contents->setShape(floaterp->getRect()); - LLUUID session_id = floaterp->getKey(); - LLIconCtrl* icon = 0; if(gAgent.isInGroup(session_id, TRUE)) @@ -150,6 +184,35 @@ void LLIMFloaterContainer::removeFloater(LLFloater* floaterp) { LLMultiFloater::removeFloater(floaterp); + // CHUI-137 : Temporary implementation of conversations list + // Clean up the conversations list + LLUUID session_id = floaterp->getKey(); + // Delete the widget and the associated conversation item + // Note : since the mConversationsItems is also the listener to the widget, deleting + // the widget will also delete its listener + conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(session_id); + if (widget_it != mConversationsWidgets.end()) + { + LLFolderViewItem* widget = widget_it->second; + delete widget; + } + // Suppress the conversation items and widgets from their respective maps + mConversationsItems.erase(session_id); + mConversationsWidgets.erase(session_id); + // Reposition the leftover conversation items + LLRect panel_rect = mConversationsListPanel->getRect(); + S32 item_height = 16; + int index = 0; + for (widget_it = mConversationsWidgets.begin(); widget_it != mConversationsWidgets.end(); ++widget_it, ++index) + { + LLFolderViewItem* widget = widget_it->second; + widget->setRect(LLRect(0, + panel_rect.getHeight() - item_height*index, + panel_rect.getWidth(), + panel_rect.getHeight() - item_height*(index+1))); + } + // CHUI-137 : end + LLRect contents_rect = floaterp->getRect(); // reduce the floater contents height by header height @@ -313,4 +376,83 @@ void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width) setCanMinimize(is_left_pane_expanded || is_right_pane_expanded); } +void LLIMFloaterContainer::onAddButtonClicked() +{ + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloaterContainer::onAvatarPicked, this, _1), TRUE, TRUE); + LLFloater* root_floater = gFloaterView->getParentFloater(this); + if (picker && root_floater) + { + root_floater->addDependentFloater(picker); + } +} + +void LLIMFloaterContainer::onAvatarPicked(const uuid_vec_t& ids) +{ + if (ids.size() == 1) + { + LLAvatarActions::startIM(ids.back()); + } + else + { + LLAvatarActions::startConference(ids); + } +} + +// CHUI-137 : Temporary implementation of conversations list +LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item) +{ + LLFolderViewItem::Params params; + + params.name = item->getDisplayName(); + //params.icon = bridge->getIcon(); + //params.icon_open = bridge->getOpenIcon(); + //params.creation_date = bridge->getCreationDate(); + //params.root = mFolderRoot; + params.listener = item; + params.rect = LLRect (0, 0, 0, 0); + params.tool_tip = params.name; + + return LLUICtrlFactory::create<LLFolderViewItem>(params); +} + +// Conversation items +LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp) : + mName(name), + mUUID(uuid), + mFloater(floaterp), + mContainer(containerp) +{ + // Hack: the nearby chat has no name so we catch that case and impose one + // Of course, we won't be doing this in the final code + if (name == "") + mName = "Nearby Chat"; +} + +// Virtual action callbacks +void LLConversationItem::selectItem(void) +{ + // Switch to the conversation floater that is being selected + mContainer->selectFloater(mFloater); +} + +void LLConversationItem::performAction(LLInventoryModel* model, std::string action) +{ +} + +void LLConversationItem::openItem( void ) +{ +} + +void LLConversationItem::closeItem( void ) +{ +} + +void LLConversationItem::previewItem( void ) +{ +} + +void LLConversationItem::showProperties(void) +{ +} + // EOF diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h index 92938ff405..b5b60615b3 100644 --- a/indra/newview/llimfloatercontainer.h +++ b/indra/newview/llimfloatercontainer.h @@ -35,10 +35,87 @@ #include "llavatarpropertiesprocessor.h" #include "llgroupmgr.h" +#include "llfolderviewitem.h" +#include "llfoldervieweventlistener.h" + class LLButton; class LLLayoutPanel; class LLLayoutStack; class LLTabContainer; +class LLIMFloaterContainer; + +// CHUI-137 : Temporary implementation of conversations list +class LLConversationItem; + +typedef std::map<LLUUID, LLConversationItem*> conversations_items_map; +typedef std::map<LLUUID, LLFolderViewItem*> conversations_widgets_map; + +// Conversation items: we hold a list of those and create an LLFolderViewItem widget for each +// that we tuck into the mConversationsListPanel. +class LLConversationItem : public LLFolderViewEventListener +{ +public: + LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp); + virtual ~LLConversationItem() {} + + // Stub those things we won't really be using in this conversation context + virtual const std::string& getName() const { return mName; } + virtual const std::string& getDisplayName() const { return mName; } + virtual const LLUUID& getUUID() const { return mUUID; } + virtual time_t getCreationDate() const { return 0; } + virtual PermissionMask getPermissionMask() const { return PERM_ALL; } + virtual LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; } + virtual LLPointer<LLUIImage> getIcon() const { return NULL; } + virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); } + virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; } + virtual std::string getLabelSuffix() const { return LLStringUtil::null; } + virtual BOOL isItemRenameable() const { return FALSE; } + virtual BOOL renameItem(const std::string& new_name) { return FALSE; } + virtual BOOL isItemMovable( void ) const { return FALSE; } + virtual BOOL isItemRemovable( void ) const { return FALSE; } + virtual BOOL isItemInTrash( void) const { return FALSE; } + virtual BOOL removeItem() { return FALSE; } + virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) { } + virtual void move( LLFolderViewEventListener* parent_listener ) { } + virtual BOOL isItemCopyable() const { return FALSE; } + virtual BOOL copyToClipboard() const { return FALSE; } + virtual BOOL cutToClipboard() const { return FALSE; } + virtual BOOL isClipboardPasteable() const { return FALSE; } + virtual void pasteFromClipboard() { } + virtual void pasteLinkFromClipboard() { } + virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { } + virtual BOOL isUpToDate() const { return TRUE; } + virtual BOOL hasChildren() const { return FALSE; } + virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; } + virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; } + + // The action callbacks + virtual void performAction(LLInventoryModel* model, std::string action); + virtual void openItem( void ); + virtual void closeItem( void ); + virtual void previewItem( void ); + virtual void selectItem(void); + virtual void showProperties(void); + + // This method should be called when a drag begins. + // Returns TRUE if the drag can begin, FALSE otherwise. + virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const { return FALSE; } + + // This method will be called to determine if a drop can be + // performed, and will set drop to TRUE if a drop is + // requested. + // Returns TRUE if a drop is possible/happened, FALSE otherwise. + virtual BOOL dragOrDrop(MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + std::string& tooltip_msg) { return FALSE; } +private: + std::string mName; + const LLUUID mUUID; + LLFloater* mFloater; + LLIMFloaterContainer* mContainer; +}; +// CHUI-137 : End class LLIMFloaterContainer : public LLMultiFloater { @@ -64,6 +141,8 @@ public: virtual void setMinimized(BOOL b); void collapseMessagesPane(bool collapse); + + LLFolderViewItem* createConversationItemWidget(LLConversationItem* item); private: typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t; @@ -80,10 +159,19 @@ private: void updateState(bool collapse, S32 delta_width); + void onAddButtonClicked(); + void onAvatarPicked(const uuid_vec_t& ids); + LLButton* mExpandCollapseBtn; LLLayoutPanel* mMessagesPane; LLLayoutPanel* mConversationsPane; LLLayoutStack* mConversationsStack; + + // CHUI-137 : Temporary implementation of conversations list + // Conversation list data + LLPanel* mConversationsListPanel; // This is the widget we add items to (i.e. clickable title for each conversation) + conversations_items_map mConversationsItems; + conversations_widgets_map mConversationsWidgets; }; #endif // LL_LLIMFLOATERCONTAINER_H diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 0a2fc13aff..7790a382d9 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3692,6 +3692,7 @@ Try enclosing path to the editor with double quotes. <string name="Command_Avatar_Label">Avatar</string> <string name="Command_Build_Label">Build</string> <string name="Command_Chat_Label">Chat</string> + <string name="Command_Conversations_Label">Conversations</string> <string name="Command_Compass_Label">Compass</string> <string name="Command_Destinations_Label">Destinations</string> <string name="Command_Gestures_Label">Gestures</string> @@ -3718,6 +3719,7 @@ Try enclosing path to the editor with double quotes. <string name="Command_Avatar_Tooltip">Choose a complete avatar</string> <string name="Command_Build_Tooltip">Building objects and reshaping terrain</string> <string name="Command_Chat_Tooltip">Chat with people nearby using text</string> + <string name="Command_Conversations_Tooltip">Converse with everyone</string> <string name="Command_Compass_Tooltip">Compass</string> <string name="Command_Destinations_Tooltip">Destinations of interest</string> <string name="Command_Gestures_Tooltip">Gestures for your avatar</string> |