diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 2174d952c..5d87bdfab 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -129,7 +129,9 @@ public: void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } LLFontGL::HAlign getHAlign() const { return mHAlign; } void setLeftHPad( S32 pad ) { mLeftHPad = pad; } + S32 getLeftHPad() const { return mLeftHPad; } void setRightHPad( S32 pad ) { mRightHPad = pad; } + S32 getRightHPad() const { return mRightHPad; } const std::string getLabelUnselected() const { return wstring_to_utf8str(mUnselectedLabel); } const std::string getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); } diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index fd4867b13..b1184ed4f 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -430,7 +430,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col switch(mFontAlignment) { case LLFontGL::LEFT: - start_x = 0.f; + start_x = (mFontStyle & LLFontGL::ITALIC) ? 2.f : 0.f; //Italic text seems need a little padding. break; case LLFontGL::RIGHT: start_x = (F32)getWidth(); @@ -1301,6 +1301,7 @@ void LLScrollListCtrl::swapWithPrevious(S32 index) if (index <= 0) { // At beginning of list, don't do anything + return; } LLScrollListItem *cur_itemp = mItemList[index]; @@ -1308,6 +1309,18 @@ void LLScrollListCtrl::swapWithPrevious(S32 index) mItemList[index - 1] = cur_itemp; } +void LLScrollListCtrl::moveToFront(S32 index) +{ + if(index == 0 || index >= (S32)mItemList.size()) + { + return; + } + + LLScrollListCtrl::item_list::iterator it = mItemList.begin(); + std::advance(it,index); + mItemList.push_front(*it); + mItemList.erase(it); +} void LLScrollListCtrl::deleteSingleItem(S32 target_index) { @@ -3002,6 +3015,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac std::string imagename; child->getAttributeString("image", imagename); + std::string imageoverlay; + child->getAttributeString("image_overlay", imageoverlay); + BOOL columndynamicwidth = FALSE; child->getAttributeBOOL("dynamicwidth", columndynamicwidth); @@ -3021,6 +3037,7 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac columns[index]["sort"] = sortname; columns[index]["sort_ascending"] = sort_ascending; columns[index]["image"] = imagename; + columns[index]["image_overlay"] = imageoverlay; columns[index]["label"] = labelname; columns[index]["width"] = columnwidth; columns[index]["relwidth"] = columnrelwidth; @@ -3229,6 +3246,10 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) //new_column->mHeader->setScaleImage(false); new_column->mHeader->setImage(column["image"].asString()); } + else if(column["image_overlay"].asString() != "") + { + new_column->mHeader->setImageOverlay(column["image_overlay"].asString()); + } else { new_column->mHeader->setLabel(new_column->mLabel); @@ -3683,6 +3704,9 @@ LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLS addChild(mResizeBar); mResizeBar->setEnabled(FALSE); + + mImageOverlayAlignment = LLFontGL::HCENTER; + mImageOverlayColor = LLColor4::white; } LLColumnHeader::~LLColumnHeader() @@ -3706,6 +3730,95 @@ void LLColumnHeader::draw() // Draw children LLComboBox::draw(); + if (mImageOverlay.notNull()) //Ugly dupe code from llbutton... + { + BOOL pressed_by_keyboard = FALSE; + if (mButton->hasFocus()) + { + pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mButton->getCommitOnReturn() && gKeyboard->getKeyDown(KEY_RETURN)); + } + + // Unselected image assignments + S32 local_mouse_x; + S32 local_mouse_y; + LLUI::getCursorPositionLocal(mButton, &local_mouse_x, &local_mouse_y); + + BOOL pressed = pressed_by_keyboard + || (mButton->hasMouseCapture() && mButton->pointInView(local_mouse_x, local_mouse_y)) + || mButton->getToggleState(); + + // Now draw special overlay.. + // let overlay image and text play well together + S32 button_width = mButton->getRect().getWidth(); + S32 button_height = mButton->getRect().getHeight(); + S32 text_left = mButton->getLeftHPad(); + S32 text_right = button_width - mButton->getRightHPad(); + S32 text_width = text_right - text_left; + + // draw overlay image + + // get max width and height (discard level 0) + S32 overlay_width = mImageOverlay->getWidth(); + S32 overlay_height = mImageOverlay->getHeight(); + + F32 scale_factor = llmin((F32)button_width / (F32)overlay_width, (F32)button_height / (F32)overlay_height, 1.f); + overlay_width = llround((F32)overlay_width * scale_factor); + overlay_height = llround((F32)overlay_height * scale_factor); + + S32 center_x = mButton->getLocalRect().getCenterX(); + S32 center_y = mButton->getLocalRect().getCenterY(); + + //FUGLY HACK FOR "DEPRESSED" BUTTONS + if (pressed) + { + center_y--; + center_x++; + } + + // fade out overlay images on disabled buttons + LLColor4 overlay_color = mImageOverlayColor; + if (!mButton->getEnabled()) + { + overlay_color.mV[VALPHA] = 0.5f; + } + + switch(mImageOverlayAlignment) + { + case LLFontGL::LEFT: + text_left += overlay_width + 1; + text_width -= overlay_width + 1; + mImageOverlay->draw( + text_left, + center_y - (overlay_height / 2), + overlay_width, + overlay_height, + overlay_color); + break; + case LLFontGL::HCENTER: + mImageOverlay->draw( + center_x - (overlay_width / 2), + center_y - (overlay_height / 2), + overlay_width, + overlay_height, + overlay_color); + break; + case LLFontGL::RIGHT: + text_right -= overlay_width + 1; + text_width -= overlay_width + 1; + mImageOverlay->draw( + text_right - overlay_width, + center_y - (overlay_height / 2), + overlay_width, + overlay_height, + overlay_color); + break; + default: + // draw nothing + break; + } + } + + if (mList->getVisible()) { // sync sort order with list selection every frame @@ -3738,6 +3851,20 @@ void LLColumnHeader::setImage(const std::string &image_name) } } +void LLColumnHeader::setImageOverlay(const std::string &image_name, LLFontGL::HAlign alignment, const LLColor4& color) +{ + if (image_name.empty()) + { + mImageOverlay = NULL; + } + else + { + mImageOverlay = LLUI::getUIImage(image_name); + mImageOverlayAlignment = alignment; + mImageOverlayColor = color; + } +} + //static void LLColumnHeader::onClick(void* user_data) { diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index bb0d87d67..7861bd536 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -274,6 +274,7 @@ public: /*virtual*/ void userSetShape(const LLRect& new_rect); void setImage(const std::string &image_name); + void setImageOverlay(const std::string &overlay_image, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white); LLScrollListColumn* getColumn() { return mColumn; } void setHasResizableElement(BOOL resizable); void updateResizeBars(); @@ -294,6 +295,10 @@ private: LLUIString mDescendingText; BOOL mShowSortOptions; BOOL mHasResizableElement; + + LLPointer mImageOverlay; + LLFontGL::HAlign mImageOverlayAlignment; + LLColor4 mImageOverlayColor; }; class LLScrollListItem @@ -467,6 +472,7 @@ public: void swapWithNext(S32 index); void swapWithPrevious(S32 index); + void moveToFront(S32 index); void setCanSelect(BOOL can_select) { mCanSelect = can_select; } virtual BOOL getCanSelect() const { return mCanSelect; } diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 97f21d5ef..000f4067e 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2488,8 +2488,6 @@ BOOL LLAgent::setGroupContribution(const LLUUID& group_id, S32 contribution) return FALSE; } -void update_group_floaters(const LLUUID& group_id); - BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile) { S32 count = mGroups.count(); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 37f52d643..ff109d2ea 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -873,4 +873,5 @@ extern std::string gAuthString; extern LLUUID gReSitTargetID; extern LLVector3 gReSitOffset; // +void update_group_floaters(const LLUUID& group_id); #endif diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index 31f1328aa..72455bb8b 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -67,6 +67,9 @@ std::map LLFloaterGroupPicker::sInstances; // helper functions void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const std::string& none_text, U64 powers_mask = GP_ALL_POWERS); +//callbacks +void onGroupSortChanged(void* user_data); + ///---------------------------------------------------------------------------- /// Class LLFloaterGroupPicker ///---------------------------------------------------------------------------- @@ -214,7 +217,9 @@ BOOL LLPanelGroups::postBuild() childSetTextArg("groupcount", "[MAX]", llformat("%d", gHippoLimits->getMaxAgentGroups())); const std::string none_text = getString("none"); - init_group_list(getChild("group list"), gAgent.getGroupID(), none_text); + LLScrollListCtrl *group_list = getChild("group list"); + init_group_list(group_list, gAgent.getGroupID(), none_text); + group_list->setSortChangedCallback(onGroupSortChanged); //Force 'none' to always be first entry. childSetAction("Activate", onBtnActivate, this); @@ -472,8 +477,97 @@ bool LLPanelGroups::callbackLeaveGroup(const LLSD& notification, const LLSD& res void LLPanelGroups::onGroupList(LLUICtrl* ctrl, void* userdata) { - LLPanelGroups* self = (LLPanelGroups*)userdata; - if(self) self->enableButtons(); + LLPanelGroups *self = (LLPanelGroups*)userdata; + if(!self) + return; + + self->enableButtons(); + + LLScrollListCtrl *group_list = (LLScrollListCtrl*)self->getChild("group list"); + if(!group_list) + return; + + LLScrollListItem *item = group_list->getFirstSelected(); + if(!item) + return; + + const LLUUID group_id = item->getValue().asUUID(); + if(group_id.isNull()) + return; + + LLGroupData group_data; + if(!gAgent.getGroupData(group_id,group_data)) + return; + + bool list_in_profile = item->getColumn(1)->getValue().asBoolean(); + bool receive_chat = item->getColumn(2)->getValue().asBoolean(); + bool recieve_notify = item->getColumn(3)->getValue().asBoolean(); + bool update_floaters = false; + if(gIMMgr->getIgnoreGroup(group_id) == receive_chat) + { + gIMMgr->updateIgnoreGroup(group_id, !receive_chat); + update_floaters = true; + } + if( (bool)group_data.mListInProfile != list_in_profile || + (bool)group_data.mAcceptNotices != recieve_notify ) + { + gAgent.setUserGroupFlags(group_id, recieve_notify, list_in_profile); + } + else if(update_floaters) //gAgent.setUserGroupFlags already calls update_group_floaters + update_group_floaters(group_id); +} + +LLSD create_group_element(const LLGroupData *group_datap, const LLUUID &active_group, const std::string& none_text, const U64 &powers_mask) +{ + if(group_datap && !((powers_mask == GP_ALL_POWERS) || ((group_datap->mPowers & powers_mask) != 0))) + return LLSD(); + const LLUUID &id = group_datap ? group_datap->mID : LLUUID::null; + const bool enabled = !!group_datap; + + std::string style = (group_datap && group_datap->mListInProfile) ? "BOLD" : "NORMAL"; + if(active_group == id) + { + style.append("|ITALIC"); + } + LLSD element; + element["id"] = id; + LLSD& name_column = element["columns"][0]; + name_column["column"] = "name"; + name_column["value"] = group_datap ? group_datap->mName : none_text; + name_column["font"] = "SANSSERIF"; + name_column["font-style"] = style; + + LLSD& show_column = element["columns"][1]; + show_column["column"] = "is_listed_group"; + show_column["type"] = "checkbox"; + show_column["enabled"] = enabled; + show_column["value"] = enabled && group_datap->mListInProfile; + + LLSD& chat_column = element["columns"][2]; + chat_column["column"] = "is_chattable_group"; + chat_column["type"] = "checkbox"; + chat_column["enabled"] = enabled; + chat_column["value"] = enabled && !gIMMgr->getIgnoreGroup(id); + + LLSD& notice_column = element["columns"][3]; + notice_column["column"] = "is_notice_group"; + notice_column["type"] = "checkbox"; + notice_column["enabled"] = enabled; + notice_column["value"] = enabled && group_datap->mAcceptNotices; + + return element; +} + +void onGroupSortChanged(void* user_data) +{ + LLPanelGroups *panel = (LLPanelGroups*)user_data; + if(!panel) + return; + LLScrollListCtrl *group_list = (LLScrollListCtrl*)panel->getChild("group list"); + if(!group_list) + return; + + group_list->moveToFront(group_list->getItemIndex(LLUUID::null)); } void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const std::string& none_text, U64 powers_mask) @@ -491,43 +585,13 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const s for(S32 i = 0; i < count; ++i) { - id = gAgent.mGroups.get(i).mID; - LLGroupData* group_datap = &gAgent.mGroups.get(i); - if ((powers_mask == GP_ALL_POWERS) || ((group_datap->mPowers & powers_mask) != 0)) - { - std::string style = group_datap->mListInProfile ? "BOLD" : "NORMAL"; - if(highlight_id == id) - { - style.append("|ITALIC"); - } - - LLSD element; - element["id"] = id; - element["columns"][0]["column"] = "name"; - element["columns"][0]["value"] = group_datap->mName; - element["columns"][0]["font"] = "SANSSERIF"; - element["columns"][0]["font-style"] = style; - + LLSD element = create_group_element(&gAgent.mGroups.get(i), highlight_id, none_text, powers_mask); + if(element.size()) group_list->addElement(element, ADD_SORTED); - } } // add "none" to list at top - { - std::string style = "NORMAL"; - if (highlight_id.isNull()) - { - style = "ITALIC"; - } - LLSD element; - element["id"] = LLUUID::null; - element["columns"][0]["column"] = "name"; - element["columns"][0]["value"] = none_text; - element["columns"][0]["font"] = "SANSSERIF"; - element["columns"][0]["font-style"] = style; - - group_list->addElement(element, ADD_TOP); - } + group_list->addElement(create_group_element(NULL, highlight_id, none_text, powers_mask), ADD_TOP); if(selected_id.notNull()) group_list->selectByValue(selected_id); diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index c7f8fc9d2..6e1f6de57 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -221,7 +221,6 @@ LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) : mOpenEnrollment(FALSE), mMembershipFee(0), mAllowPublish(FALSE), - mListInProfile(FALSE), mMaturePublish(FALSE), mChanged(FALSE), mMemberCount(0), diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index a0604be57..f3b32964b 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -255,7 +255,6 @@ public: BOOL mOpenEnrollment; S32 mMembershipFee; BOOL mAllowPublish; - BOOL mListInProfile; BOOL mMaturePublish; BOOL mChanged; S32 mMemberCount; diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index fd76249c7..1c05d340f 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -780,61 +780,80 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) mBtnInfo->setVisible(is_member && !mAllowEdit); } - if (mCtrlReceiveNotices) + if(gc == GC_ALL || gc == GC_PROPERTIES) { - mCtrlReceiveNotices->setVisible(is_member); - if (is_member) + if (mCtrlReceiveNotices) { - mCtrlReceiveNotices->setEnabled(mAllowEdit); + mCtrlReceiveNotices->setVisible(is_member); + if (is_member) + { + mCtrlReceiveNotices->setEnabled(mAllowEdit); + if(!mCtrlReceiveNotices->isDirty()) //If the user hasn't edited this then refresh it. Value may have changed in groups panel, etc. + { + mCtrlReceiveNotices->set(agent_gdatap.mAcceptNotices); + mCtrlReceiveNotices->resetDirty(); + } + } } - //mCtrlReceiveNotices->resetDirty(); Don't resetDirty. This ctrl is decoupled from update. - } - if (mCtrlListGroup) - { - mCtrlListGroup->setVisible(is_member); - if (is_member) - mCtrlListGroup->setEnabled(mAllowEdit); - //mCtrlReceiveChat->resetDirty(); Don't resetDirty. This ctrl is decoupled from update. - } + if (mCtrlListGroup) + { + mCtrlListGroup->setVisible(is_member); + if (is_member) + { + mCtrlListGroup->setEnabled(mAllowEdit); + if(!mCtrlListGroup->isDirty()) //If the user hasn't edited this then refresh it. Value may have changed in groups panel, etc. + { + mCtrlListGroup->set(agent_gdatap.mListInProfile); + mCtrlListGroup->resetDirty(); + } + } + } - if (mCtrlReceiveChat) - { - mCtrlReceiveChat->setVisible(is_member); - mCtrlReceiveChat->setEnabled(TRUE); - //mCtrlReceiveChat->resetDirty(); Don't resetDirty. This ctrl is decoupled from update. - } + if (mCtrlReceiveChat) + { + mCtrlReceiveChat->setVisible(is_member); + if (is_member) + { + mCtrlReceiveChat->setEnabled(mAllowEdit); + if(!mCtrlReceiveChat->isDirty()) //If the user hasn't edited this then refresh it. Value may have changed in groups panel, etc. + { + mCtrlReceiveChat->set(!gIMMgr->getIgnoreGroup(mGroupID)); + mCtrlReceiveChat->resetDirty(); + } + } + } - - if (mInsignia) mInsignia->setEnabled(mAllowEdit && can_change_ident); - if (mEditCharter) mEditCharter->setEnabled(mAllowEdit && can_change_ident); + if (mInsignia) mInsignia->setEnabled(mAllowEdit && can_change_ident); + if (mEditCharter) mEditCharter->setEnabled(mAllowEdit && can_change_ident); - if (mGroupName) mGroupName->setText(gdatap->mName); - if (mGroupNameEditor) mGroupNameEditor->setVisible(FALSE); - if (mFounderName) mFounderName->setNameID(gdatap->mFounderID,FALSE); + if (mGroupName) mGroupName->setText(gdatap->mName); + if (mGroupNameEditor) mGroupNameEditor->setVisible(FALSE); + if (mFounderName) mFounderName->setNameID(gdatap->mFounderID,FALSE); - LLNameEditor* key_edit = getChild("group_key"); - if(key_edit) - { - key_edit->setText(gdatap->getID().asString()); - } - - if (mInsignia) - { - if (gdatap->mInsigniaID.notNull()) + LLNameEditor* key_edit = getChild("group_key"); + if(key_edit) { - mInsignia->setImageAssetID(gdatap->mInsigniaID); + key_edit->setText(gdatap->getID().asString()); } - else - { - mInsignia->setImageAssetID(mDefaultIconID); - } - } - if (mEditCharter) - { - mEditCharter->setText(gdatap->mCharter); - mEditCharter->resetDirty(); + if (mInsignia) + { + if (gdatap->mInsigniaID.notNull()) + { + mInsignia->setImageAssetID(gdatap->mInsigniaID); + } + else + { + mInsignia->setImageAssetID(mDefaultIconID); + } + } + + if (mEditCharter) + { + mEditCharter->setText(gdatap->mCharter); + mEditCharter->resetDirty(); + } } if (mListVisibleMembers) diff --git a/indra/newview/skins/default/xui/en-us/panel_groups.xml b/indra/newview/skins/default/xui/en-us/panel_groups.xml index 75ad985fb..f4acca0af 100644 --- a/indra/newview/skins/default/xui/en-us/panel_groups.xml +++ b/indra/newview/skins/default/xui/en-us/panel_groups.xml @@ -1,18 +1,26 @@ - - + + + + + - Your currently active group is displayed in bold. + Your currently active group is displayed in italics.