diff options
Diffstat (limited to 'indra/newview/llchiclet.cpp')
-rw-r--r-- | indra/newview/llchiclet.cpp | 900 |
1 files changed, 543 insertions, 357 deletions
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 4999d05e44..bd946a79d6 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -32,72 +32,58 @@ #include "llviewerprecompiledheaders.h" // must be first include #include "llchiclet.h" -#include "llvoiceclient.h" #include "llagent.h" -#include "lltextbox.h" -#include "lliconctrl.h" -#include "llvoicecontrolpanel.h" -#include "lloutputmonitorctrl.h" -#include "llimview.h" +#include "llavataractions.h" #include "llbottomtray.h" +#include "llgroupactions.h" +#include "lliconctrl.h" #include "llimpanel.h" +#include "llimview.h" +#include "llfloatergroupinfo.h" +#include "llmenugl.h" +#include "lloutputmonitorctrl.h" +#include "lltextbox.h" +#include "llvoiceclient.h" +#include "llvoicecontrolpanel.h" -static const S32 CHICLET_HEIGHT = 25; -static const S32 CHICLET_SPACING = 0; -static const S32 CHICLET_PADDING = 3; -static const S32 AVATAR_WIDTH = 25; -static const S32 SPEAKER_WIDTH = 20; -static const S32 COUNTER_WIDTH = 20; -static const S32 SCROLL_BUTTON_WIDTH = 19; -static const S32 SCROLL_BUTTON_HEIGHT = 20; -static const S32 NOTIFICATION_TEXT_TOP_PAD = 5; +static const std::string P2P_MENU_NAME = "IMChiclet P2P Menu"; +static const std::string GROUP_MENU_NAME = "IMChiclet Group Menu"; static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel"); static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk"); static LLDefaultChildRegistry::Register<LLNotificationChiclet> t3("chiclet_notification"); -static LLDefaultChildRegistry::Register<LLChicletPanel> t4("chiclet_panel"); +static LLDefaultChildRegistry::Register<LLIMChiclet> t4("chiclet_im"); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// LLNotificationChiclet::Params::Params() -: image_unselected("image_unselected") -, image_selected("image_selected") -, image_overlay("image_overlay") +: button("button") +, unread_notifications("unread_notifications") { + button.tab_stop(FALSE); + button.label(LLStringUtil::null); + + unread_notifications.font(LLFontGL::getFontSansSerif()); + unread_notifications.text_color=(LLColor4::white); + unread_notifications.font_halign(LLFontGL::HCENTER); + unread_notifications.mouse_opaque(FALSE); } LLNotificationChiclet::LLNotificationChiclet(const Params& p) : LLChiclet(p) , mButton(NULL) -, mCounterText(NULL) -{ - LLRect rc(p.rect); - - LLButton::Params button_params; - button_params.name("btn"); - button_params.label(LLStringUtil::null); - button_params.rect(LLRect(0,rc.getHeight(),rc.getWidth(),0)); - button_params.image_overlay(p.image_overlay); - button_params.image_unselected(p.image_unselected); - button_params.image_selected(p.image_selected); - button_params.tab_stop(false); +, mCounterCtrl(NULL) +{ + LLButton::Params button_params = p.button; + button_params.rect(p.rect()); mButton = LLUICtrlFactory::create<LLButton>(button_params); addChild(mButton); - LLTextBox::Params textbox_params; - textbox_params.name("txt"); - textbox_params.rect(LLRect(p.label_left,rc.getHeight(), - rc.getWidth()-p.label_left,0)); - textbox_params.mouse_opaque(false); - textbox_params.v_pad(NOTIFICATION_TEXT_TOP_PAD); - textbox_params.font.style("SansSerif"); - textbox_params.font_halign(LLFontGL::HCENTER); - mCounterText = LLUICtrlFactory::create<LLTextBox>(textbox_params); - addChild(mCounterText); - mCounterText->setColor(LLColor4::white); - mCounterText->setText(LLStringUtil::null); + LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; + mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params); + addChild(mCounterCtrl); } LLNotificationChiclet::~LLNotificationChiclet() @@ -105,18 +91,15 @@ LLNotificationChiclet::~LLNotificationChiclet() } -LLChiclet* LLNotificationChiclet::create(const Params& p) +void LLNotificationChiclet::setCounter(S32 counter) { - LLChiclet* chiclet = new LLNotificationChiclet(p); - return chiclet; + mCounterCtrl->setCounter(counter); } -void LLNotificationChiclet::setCounter(S32 counter) +void LLNotificationChiclet::setShowCounter(bool show) { - std::stringstream stream; - mCounter = counter; - stream << mCounter; - mCounterText->setText(stream.str()); + LLChiclet::setShowCounter(show); + mCounterCtrl->setVisible(getShowCounter()); } boost::signals2::connection LLNotificationChiclet::setClickCallback( @@ -129,10 +112,16 @@ boost::signals2::connection LLNotificationChiclet::setClickCallback( ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +LLChiclet::Params::Params() + : show_counter("show_counter") +{ + show_counter = true; +} + LLChiclet::LLChiclet(const Params& p) : LLUICtrl(p) -, mCounter(0) -, mShowCounter(true) +, mSessionId(LLUUID::null) +, mShowCounter(p.show_counter) { } @@ -155,91 +144,133 @@ BOOL LLChiclet::handleMouseDown(S32 x, S32 y, MASK mask) return TRUE; } +boost::signals2::connection LLChiclet::setChicletSizeChangedCallback( + const chiclet_size_changed_callback_t& cb) +{ + return mChicletSizeChangedSignal.connect(cb); +} + +void LLChiclet::onChicletSizeChanged() +{ + mChicletSizeChangedSignal(this, getValue()); +} + +LLSD LLChiclet::getValue() const +{ + return LLSD(getSessionId()); +} + +void LLChiclet::setValue(const LLSD& value) +{ + if(value.isUUID()) + setSessionId(value.asUUID()); +} + ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -LLIMChiclet::LLIMChiclet(const LLChiclet::Params& p) -: LLChiclet(p) -, mAvatar(NULL) -, mCounterText(NULL) -, mSpeaker(NULL) -, mIMSessionId(LLUUID::null) -, mShowSpeaker(false) -, mSpeakerStatus(SPEAKER_IDLE) -{ - LLAvatarIconCtrl::Params avatar_params; - avatar_params.control_name("avatar"); - avatar_params.draw_tooltip = FALSE; - mAvatar = LLUICtrlFactory::create<LLAvatarIconCtrl>(avatar_params); - - addChild(mAvatar); - - LLTextBox::Params unread_params; - unread_params.font.style("SansSerif"); - unread_params.font_halign(LLFontGL::HCENTER); - unread_params.v_pad(5); - mCounterText = LLUICtrlFactory::create<LLTextBox>(unread_params); - addChild(mCounterText); - mCounterText->setColor(LLColor4::white); - setCounter(getCounter()); +LLIMChiclet::Params::Params() +: avatar_icon("avatar_icon") +, unread_notifications("unread_notifications") +, speaker("speaker") +, show_speaker("show_speaker") +{ + rect(LLRect(0, 25, 45, 0)); + + avatar_icon.name("avatar_icon"); + avatar_icon.rect(LLRect(0, 25, 25, 0)); - LLIconCtrl::Params speaker_params; - speaker_params.image( LLUI::getUIImage("icn_voice_ptt-on-lvl2.tga") ); - mSpeaker = LLUICtrlFactory::create<LLIconCtrl>(speaker_params); - addChild(mSpeaker); - mSpeaker->setVisible(getShowSpeaker()); + unread_notifications.name("unread"); + unread_notifications.rect(LLRect(25, 25, 45, 0)); + unread_notifications.font(LLFontGL::getFontSansSerif()); + unread_notifications.font_halign(LLFontGL::HCENTER); + unread_notifications.v_pad(5); + unread_notifications.text_color(LLColor4::white); - S32 left = 0; - mAvatar->setRect(LLRect(left,CHICLET_HEIGHT,AVATAR_WIDTH,0)); - left += AVATAR_WIDTH + CHICLET_SPACING; - mCounterText->setRect(LLRect(left,CHICLET_HEIGHT,left + COUNTER_WIDTH,0)); - left += COUNTER_WIDTH + CHICLET_SPACING; - mSpeaker->setRect(LLRect(left,CHICLET_HEIGHT,left + SPEAKER_WIDTH,0)); + speaker.name("speaker"); + speaker.rect(LLRect(45, 25, 65, 0)); + + show_speaker = false; } -LLIMChiclet::~LLIMChiclet() +LLIMChiclet::LLIMChiclet(const Params& p) +: LLChiclet(p) +, mAvatarCtrl(NULL) +, mCounterCtrl(NULL) +, mSpeakerCtrl(NULL) +, mShowSpeaker(p.show_speaker) +, mPopupMenu(NULL) { + LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon; + mAvatarCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params); + addChild(mAvatarCtrl); + + LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; + mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params); + addChild(mCounterCtrl); + + setCounter(getCounter()); + setShowCounter(getShowCounter()); + + LLChicletSpeakerCtrl::Params speaker_params = p.speaker; + mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params); + addChild(mSpeakerCtrl); + setShowSpeaker(getShowSpeaker()); } -LLChiclet* LLIMChiclet::create(const LLUUID& im_session_id /* = LLUUID::null */) +LLIMChiclet::~LLIMChiclet() { - LLIMChiclet* chiclet = new LLIMChiclet(LLChiclet::Params()); - chiclet->setIMSessionId(im_session_id); - return chiclet; + } void LLIMChiclet::setCounter(S32 counter) { - mCounter = counter; - std::stringstream stream; - stream << mCounter; - mCounterText->setText(stream.str()); + mCounterCtrl->setCounter(counter); - LLRect rc = mCounterText->getRect(); - rc.mRight = rc.mLeft + calcCounterWidth(); - mCounterText->setRect(rc); + if(getShowCounter()) + { + LLRect counter_rect = mCounterCtrl->getRect(); + LLRect required_rect = mCounterCtrl->getRequiredRect(); + bool needs_resize = required_rect.getWidth() != counter_rect.getWidth(); + + if(needs_resize) + { + counter_rect.mRight = counter_rect.mLeft + required_rect.getWidth(); + mCounterCtrl->reshape(counter_rect.getWidth(), counter_rect.getHeight()); + mCounterCtrl->setRect(counter_rect); + + onChicletSizeChanged(); + } + } } LLRect LLIMChiclet::getRequiredRect() { - LLRect rect(0,CHICLET_HEIGHT,AVATAR_WIDTH,0); + LLRect rect(0, 0, mAvatarCtrl->getRect().getWidth(), 0); if(getShowCounter()) { - rect.mRight += CHICLET_SPACING + calcCounterWidth(); + rect.mRight += mCounterCtrl->getRequiredRect().getWidth(); } if(getShowSpeaker()) { - rect.mRight += CHICLET_SPACING + SPEAKER_WIDTH; + rect.mRight += mSpeakerCtrl->getRect().getWidth(); } return rect; } void LLIMChiclet::setShowCounter(bool show) { + bool needs_resize = getShowCounter() != show; + LLChiclet::setShowCounter(show); - mCounterText->setVisible(getShowCounter()); + mCounterCtrl->setVisible(getShowCounter()); + + if(needs_resize) + { + onChicletSizeChanged(); + } } void LLIMChiclet::setIMSessionName(const std::string& name) @@ -249,16 +280,39 @@ void LLIMChiclet::setIMSessionName(const std::string& name) void LLIMChiclet::setOtherParticipantId(const LLUUID& other_participant_id) { - if (mAvatar) + if (mAvatarCtrl) { - mAvatar->setValue(other_participant_id); + mAvatarCtrl->setValue(other_participant_id); + } +} + +void LLIMChiclet::updateMenuItems() +{ + if(!mPopupMenu) + return; + if(getSessionId().isNull()) + return; + + if(P2P_MENU_NAME == mPopupMenu->getName()) + { + bool is_friend = LLAvatarActions::isFriend(mAvatarCtrl->getAvatarId()); + + mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend); + mPopupMenu->getChild<LLUICtrl>("Remove Friend")->setEnabled(is_friend); } } void LLIMChiclet::setShowSpeaker(bool show) { + bool needs_resize = getShowSpeaker() != show; + mShowSpeaker = show; - mSpeaker->setVisible(getShowSpeaker()); + mSpeakerCtrl->setVisible(getShowSpeaker()); + + if(needs_resize) + { + onChicletSizeChanged(); + } } void LLIMChiclet::draw() @@ -267,45 +321,140 @@ void LLIMChiclet::draw() gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE); } -S32 LLIMChiclet::calcCounterWidth() +BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + if(!mPopupMenu) + createPopupMenu(); + + updateMenuItems(); + + mPopupMenu->arrangeAndClear(); + + LLMenuGL::showPopup(this, mPopupMenu, x, y); + + return TRUE; +} + +void LLIMChiclet::createPopupMenu() { - S32 font_width = mCounterText->getFont()->getWidth("0"); - S32 text_size = mCounterText->getText().size(); + if(mPopupMenu) + { + llwarns << "Menu already exists" << llendl; + return; + } + if(getSessionId().isNull()) + return; - return llmax(font_width * text_size, COUNTER_WIDTH); + LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId()); + if(!floater) + return; + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + registrar.add("IMChicletMenu.Action", boost::bind(&LLIMChiclet::onMenuItemClicked, this, _2)); + + switch(floater->getDialogType()) + { + case IM_SESSION_GROUP_START: + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> + ("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + break; + case IM_NOTHING_SPECIAL: + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> + ("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + break; + default: + llwarns << "Unexpected dialog type" << llendl; + break; + } +} + +void LLIMChiclet::onMenuItemClicked(const LLSD& user_data) +{ + std::string level = user_data.asString(); + LLUUID other_participant_id = mAvatarCtrl->getAvatarId(); + + if("profile" == level) + { + LLAvatarActions::showProfile(other_participant_id); + } + else if("im" == level) + { + LLAvatarActions::startIM(other_participant_id); + } + else if("add" == level) + { + std::string name; + gCacheName->getFullName(other_participant_id,name); + LLAvatarActions::requestFriendshipDialog(other_participant_id,name); + } + else if("remove" == level) + { + LLAvatarActions::removeFriendDialog(other_participant_id); + } + else if("group chat" == level) + { + LLGroupActions::startChat(other_participant_id); + } + else if("info" == level) + { + LLFloaterGroupInfo::showFromUUID(other_participant_id); + } } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +LLChicletPanel::Params::Params() +: chiclet_padding("chiclet_padding") +, scrolling_offset("scrolling_offset") +, left_scroll_button("left_scroll_button") +, right_scroll_button("right_scroll_button") +{ + chiclet_padding = 3; + scrolling_offset = 40; + + LLRect scroll_button_rect(0, 25, 19, 5); + + left_scroll_button.name("left_scroll"); + left_scroll_button.label(LLStringUtil::null); + left_scroll_button.rect(scroll_button_rect); + left_scroll_button.tab_stop(false); + left_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); + left_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); + left_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); + + right_scroll_button.name("right_scroll"); + right_scroll_button.label(LLStringUtil::null); + right_scroll_button.rect(scroll_button_rect); + right_scroll_button.tab_stop(false); + right_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); + right_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); + right_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); +}; + LLChicletPanel::LLChicletPanel(const Params&p) : LLPanel(p) , mScrollArea(NULL) -, mLeftScroll(NULL) -, mRightScroll(NULL) -{ - LLButton::Params params; - - params.name("scroll_left"); - params.label(LLStringUtil::null); - params.tab_stop(false); - params.image_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); - params.image_unselected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); - params.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); - mLeftScroll = LLUICtrlFactory::create<LLButton>(params); - addChild(mLeftScroll); - mLeftScroll->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this)); - mLeftScroll->setEnabled(false); - - params.name("scroll_right"); - params.image_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); - params.image_unselected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); - params.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); - mRightScroll = LLUICtrlFactory::create<LLButton>(params); - addChild(mRightScroll); - mRightScroll->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this)); - mRightScroll->setEnabled(false); +, mLeftScrollButton(NULL) +, mRightScrollButton(NULL) +, mChicletPadding(p.chiclet_padding) +, mScrollingOffset(p.scrolling_offset) +{ + LLButton::Params scroll_button_params = p.left_scroll_button; + + mLeftScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params); + addChild(mLeftScrollButton); + + mLeftScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this)); + mLeftScrollButton->setEnabled(false); + + scroll_button_params = p.right_scroll_button; + mRightScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params); + addChild(mRightScrollButton); + + mRightScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this)); + mRightScrollButton->setEnabled(false); LLPanel::Params panel_params; mScrollArea = LLUICtrlFactory::create<LLPanel>(panel_params,this); @@ -320,7 +469,7 @@ LLChicletPanel::~LLChicletPanel() void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){ LLUUID session_id = data["session_id"].asUUID(); - LLChiclet* chiclet = panel->findIMChiclet(session_id); + LLChiclet* chiclet = panel->findChiclet<LLChiclet>(session_id); if (chiclet) { @@ -341,38 +490,28 @@ BOOL LLChicletPanel::postBuild() return TRUE; } -LLChiclet* LLChicletPanel::createChiclet(const LLUUID& im_session_id /* = LLUUID::null */, S32 pos /* = 0 */) -{ - LLChiclet* chiclet = LLIMChiclet::create(im_session_id); - if(!chiclet) - { - assert(false); - return NULL; - } - - if(!addChiclet(chiclet, pos)) - { - assert(false); - return NULL; - } - - return chiclet; -} - -bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 pos) +bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index) { if(mScrollArea->addChild(chiclet)) { - // if first chiclet is scrolled left, the created one should be scrolled left too - if(0 == pos && canScrollLeft()) + S32 offset = 0; + // Do not scroll chiclets if chiclets are scrolled right and new + // chiclet is added to the beginning of the list + if(canScrollLeft()) { - LLRect first_chiclet_rect = getChiclet(0)->getRect(); - chiclet->setRect(first_chiclet_rect); + offset = - (chiclet->getRequiredRect().getWidth() + getChicletPadding()); + if(0 == index) + { + offset += getChiclet(0)->getRect().mLeft; + } } - mChicletList.insert(mChicletList.begin() + pos, chiclet); + mChicletList.insert(mChicletList.begin() + index, chiclet); + + getChiclet(0)->translate(offset, 0); chiclet->setLeftButtonClickCallback(boost::bind(&LLChicletPanel::onChicletClick, this, _1, _2)); + chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index)); arrange(); showScrollButtonsIfNeeded(); @@ -383,6 +522,29 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 pos) return false; } +void LLChicletPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param) +{ + S32 chiclet_width = ctrl->getRect().getWidth(); + S32 chiclet_new_width = ctrl->getRequiredRect().getWidth(); + + if(chiclet_new_width == chiclet_width) + { + return; + } + + LLRect chiclet_rect = ctrl->getRect(); + chiclet_rect.mRight = chiclet_rect.mLeft + chiclet_new_width; + + ctrl->setRect(chiclet_rect); + + S32 offset = chiclet_new_width - chiclet_width; + S32 index = getChicletIndex(ctrl); + + shiftChiclets(offset, index + 1); + trimChiclets(); + showScrollButtonsIfNeeded(); +} + void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD¶m) { LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(ctrl); @@ -391,66 +553,42 @@ void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD¶m) S32 x, y; LLRect rect = getRect(); localPointToScreen(rect.getCenterX(), 0, &x, &y); - LLIMFloater::show(chiclet->getIMSessionId(), x); + LLIMFloater::show(chiclet->getSessionId(), x); } mCommitSignal(ctrl,param); } -LLChiclet* LLChicletPanel::findIMChiclet(const LLUUID& im_session_id) -{ - chiclet_list_t::const_iterator it = mChicletList.begin(); - for( ; mChicletList.end() != it; ++it) - { - // Only IM Chiclets have session id, skip non IM Chiclets - LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it); - if(!chiclet) - { - continue; - } - - if(chiclet->getIMSessionId() == im_session_id) - { - return chiclet; - } - } - return NULL; -} - -LLChiclet* LLChicletPanel::getChiclet(S32 pos) -{ - return mChicletList[pos]; -} - void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it) { - // if possible, after deletion shift chiclets right - if(canScrollLeft() && !canScrollRight()) - { - LLChiclet* chiclet = *it; - LLRect first_chiclet_rect = getChiclet(0)->getRect(); - S32 deleted_chiclet_width = chiclet->getRect().getWidth(); - deleted_chiclet_width += CHICLET_PADDING; - - first_chiclet_rect.mLeft += deleted_chiclet_width; - first_chiclet_rect.mRight += deleted_chiclet_width; - - getChiclet(0)->setRect(first_chiclet_rect); - } - mScrollArea->removeChild(*it); mChicletList.erase(it); arrange(); + trimChiclets(); showScrollButtonsIfNeeded(); } -void LLChicletPanel::removeChiclet(S32 pos) +void LLChicletPanel::removeChiclet(S32 index) { - if(0 > pos || getChicletCount() <= pos) + if(index >= 0 && index < getChicletCount()) { - return; + removeChiclet(mChicletList.begin() + index); } - removeChiclet(mChicletList.begin() + pos); +} + +S32 LLChicletPanel::getChicletIndex(const LLChiclet* chiclet) +{ + if(mChicletList.empty()) + return -1; + + S32 size = getChicletCount(); + for(int n = 0; n < size; ++n) + { + if(chiclet == mChicletList[n]) + return n; + } + + return -1; } void LLChicletPanel::removeChiclet(LLChiclet*chiclet) @@ -467,19 +605,14 @@ void LLChicletPanel::removeChiclet(LLChiclet*chiclet) } } -void LLChicletPanel::removeIMChiclet(const LLUUID& im_session_id) +void LLChicletPanel::removeChiclet(const LLUUID& im_session_id) { chiclet_list_t::iterator it = mChicletList.begin(); for( ; mChicletList.end() != it; ++it) { - // Only IM Chiclets have session id, skip non IM Chiclets LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it); - if(!chiclet) - { - continue; - } - if(chiclet->getIMSessionId() == im_session_id) + if(chiclet->getSessionId() == im_session_id) { removeChiclet(it); return; @@ -489,7 +622,11 @@ void LLChicletPanel::removeIMChiclet(const LLUUID& im_session_id) void LLChicletPanel::removeAll() { - mScrollArea->deleteAllChildren(); + S32 size = getChicletCount(); + for(S32 n = 0; n < size; ++n) + { + mScrollArea->removeChild(mChicletList[n]); + } mChicletList.erase(mChicletList.begin(), mChicletList.end()); @@ -500,75 +637,67 @@ void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent ) { LLPanel::reshape(width,height,called_from_parent); - mLeftScroll->setRect(LLRect(0,CHICLET_HEIGHT,SCROLL_BUTTON_WIDTH, - CHICLET_HEIGHT - SCROLL_BUTTON_HEIGHT)); - mRightScroll->setRect(LLRect(width-SCROLL_BUTTON_WIDTH,CHICLET_HEIGHT, - width,CHICLET_HEIGHT - SCROLL_BUTTON_HEIGHT)); + static const S32 SCROLL_BUTTON_PAD = 5; - S32 old_scroll_width = mScrollArea->getRect().getWidth(); + LLRect scroll_button_rect = mLeftScrollButton->getRect(); + mLeftScrollButton->setRect(LLRect(0,height,scroll_button_rect.getWidth(), + height - scroll_button_rect.getHeight())); - mScrollArea->setRect(LLRect(SCROLL_BUTTON_WIDTH + 5,CHICLET_HEIGHT + 1, - width - SCROLL_BUTTON_WIDTH - 5, 0)); + scroll_button_rect = mRightScrollButton->getRect(); + mRightScrollButton->setRect(LLRect(width - scroll_button_rect.getWidth(),height, + width, height - scroll_button_rect.getHeight())); - S32 current_scroll_width = mScrollArea->getRect().getWidth(); - reshapeScrollArea(current_scroll_width - old_scroll_width); + mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD, + height + 1, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0)); + + trimChiclets(); showScrollButtonsIfNeeded(); } -void LLChicletPanel::reshapeScrollArea(S32 delta_width) +void LLChicletPanel::arrange() { if(mChicletList.empty()) return; - S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight; - S32 scroll_width = mScrollArea->getRect().getWidth(); + S32 chiclet_left = getChiclet(0)->getRect().mLeft; - // Align all chiclets to last chiclet - // if there is a gap between last chiclet and scroll area right side - // or last chiclet is at visible area right side - if( last_chiclet_right < scroll_width - || last_chiclet_right == scroll_width - delta_width) + S32 size = getChicletCount(); + for( int n = 0; n < size; ++n) { - LLRect first_chiclet_rect = getChiclet(0)->getRect(); - // if we can right shift all chiclets - if(first_chiclet_rect.mLeft < 0) - { - first_chiclet_rect.mLeft += delta_width; - first_chiclet_rect.mRight += delta_width; + LLChiclet* chiclet = getChiclet(n); - getChiclet(0)->setRect(first_chiclet_rect); + S32 chiclet_width = chiclet->getRequiredRect().getWidth(); + LLRect rect = chiclet->getRect(); + rect.set(chiclet_left, rect.mTop, chiclet_left + chiclet_width, rect.mBottom); - arrange(); - } + chiclet->setRect(rect); + + chiclet_left += chiclet_width + getChicletPadding(); } } -void LLChicletPanel::arrange() +void LLChicletPanel::trimChiclets() { - if(mChicletList.empty()) - return; - - LLRect first_chiclet_rect = getChiclet(0)->getRect(); - // don't allow gap between first chiclet and scroll area left side - if(first_chiclet_rect.mLeft > 0) + // trim right + if(canScrollLeft() && !canScrollRight()) { - first_chiclet_rect.mRight = first_chiclet_rect.getWidth(); - first_chiclet_rect.mLeft = 0; + S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight; + S32 scroll_width = mScrollArea->getRect().getWidth(); + if(last_chiclet_right < scroll_width) + { + shiftChiclets(scroll_width - last_chiclet_right); + } } - S32 left = first_chiclet_rect.mLeft; - - S32 size = getChicletCount(); - for( int n = 0; n < size; ++n) + // trim left + if(!mChicletList.empty()) { - LLChiclet* chiclet = getChiclet(n); - S32 chiclet_width = chiclet->getRequiredRect().getWidth(); - LLRect rc(left, CHICLET_HEIGHT, left + chiclet_width, 0); - - chiclet->setRect(rc); - - left += chiclet_width + CHICLET_PADDING; + LLRect first_chiclet_rect = getChiclet(0)->getRect(); + if(first_chiclet_rect.mLeft > 0) + { + shiftChiclets( - first_chiclet_rect.mLeft); + } } } @@ -577,13 +706,13 @@ void LLChicletPanel::showScrollButtonsIfNeeded() bool can_scroll_left = canScrollLeft(); bool can_scroll_right = canScrollRight(); - mLeftScroll->setEnabled(can_scroll_left); - mRightScroll->setEnabled(can_scroll_right); + mLeftScrollButton->setEnabled(can_scroll_left); + mRightScrollButton->setEnabled(can_scroll_right); bool show_scroll_buttons = can_scroll_left || can_scroll_right; - mLeftScroll->setVisible(show_scroll_buttons); - mRightScroll->setVisible(show_scroll_buttons); + mLeftScrollButton->setVisible(show_scroll_buttons); + mRightScrollButton->setVisible(show_scroll_buttons); } void LLChicletPanel::draw() @@ -626,42 +755,19 @@ bool LLChicletPanel::canScrollLeft() return getChiclet(0)->getRect().mLeft < 0; } -void LLChicletPanel::scroll(ScrollDirection direction) +void LLChicletPanel::scroll(S32 offset) { - S32 first_visible_chiclet = getFirstVisibleChiclet(); - if(-1 == first_visible_chiclet) - return; - - S32 offset = 0; + shiftChiclets(offset); +} - if(SCROLL_LEFT == direction) - { - if(0 == first_visible_chiclet) - { - // shift chiclets in case first chiclet is partially visible - offset = llabs(getChiclet(first_visible_chiclet)->getRect().mLeft); - } - else - { - offset = getChiclet(first_visible_chiclet - 1)->getRect().getWidth() + CHICLET_PADDING; - } - } - else if(SCROLL_RIGHT == direction) +void LLChicletPanel::shiftChiclets(S32 offset, S32 start_index /* = 0 */) +{ + if(start_index < 0 || start_index >= getChicletCount()) { - S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight; - S32 scroll_rect_width = mScrollArea->getRect().getWidth(); - - offset = getChiclet(first_visible_chiclet)->getRect().getWidth() + CHICLET_PADDING; - offset *= direction; - // if after scrolling, the last chiclet will not be aligned to - // scroll area right side - align it. - if( last_chiclet_right + offset < scroll_rect_width ) - { - offset = scroll_rect_width - last_chiclet_right; - } + return; } - chiclet_list_t::const_iterator it = mChicletList.begin(); + chiclet_list_t::const_iterator it = mChicletList.begin() + start_index; for(;mChicletList.end() != it; ++it) { LLChiclet* chiclet = *it; @@ -669,31 +775,20 @@ void LLChicletPanel::scroll(ScrollDirection direction) } } -S32 LLChicletPanel::getFirstVisibleChiclet() +void LLChicletPanel::scrollLeft() { - if(mChicletList.empty()) - return -1; - - for(int n = 0; n < getChicletCount(); ++n) + if(canScrollLeft()) { - LLRect rc = getChiclet(n)->getRect(); - if(n > 0) - rc.mLeft -= CHICLET_PADDING; - // bottom left of scroll area is first visible point - if(rc.pointInRect(0,0)) + S32 offset = getScrollingOffset(); + LLRect first_chiclet_rect = getChiclet(0)->getRect(); + + // shift chiclets in case first chiclet is partially visible + if(first_chiclet_rect.mLeft < 0 && first_chiclet_rect.mRight > 0) { - return n; + offset = llabs(first_chiclet_rect.mLeft); } - } - return -1; -} - -void LLChicletPanel::scrollLeft() -{ - if(canScrollLeft()) - { - scroll(SCROLL_LEFT); + scroll(offset); showScrollButtonsIfNeeded(); } @@ -703,7 +798,18 @@ void LLChicletPanel::scrollRight() { if(canScrollRight()) { - scroll(SCROLL_RIGHT); + S32 offset = - getScrollingOffset(); + + S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight; + S32 scroll_rect_width = mScrollArea->getRect().getWidth(); + // if after scrolling, the last chiclet will not be aligned to + // scroll area right side - align it. + if( last_chiclet_right + offset < scroll_rect_width ) + { + offset = scroll_rect_width - last_chiclet_right; + } + + scroll(offset); showScrollButtonsIfNeeded(); } @@ -719,7 +825,7 @@ void LLChicletPanel::onRightScrollClick() scrollRight(); } -boost::signals2::connection LLChicletPanel::setChicletClickCallback( +boost::signals2::connection LLChicletPanel::setChicletClickedCallback( const commit_callback_t& cb) { return mCommitSignal.connect(cb); @@ -742,62 +848,83 @@ BOOL LLChicletPanel::handleScrollWheel(S32 x, S32 y, S32 clicks) ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -LLTalkButton::LLTalkButton(const LLUICtrl::Params& p) +LLTalkButton::Params::Params() + : speak_button("speak_button") + , show_button("show_button") + , monitor("monitor") +{ + speak_button.name("left"); + speak_button.label("Speak"); + speak_button.label_selected("Speak"); + speak_button.font(LLFontGL::getFontSansSerifSmall()); + speak_button.tab_stop(false); + speak_button.is_toggle(true); + speak_button.picture_style(true); + speak_button.image_selected(LLUI::getUIImage("SegmentedBtn_Left_Selected")); + speak_button.image_unselected(LLUI::getUIImage("SegmentedBtn_Left_Off")); + + show_button.name("right"); + show_button.label(LLStringUtil::null); + show_button.rect(LLRect(0, 0, 20, 0)); + show_button.tab_stop(false); + show_button.is_toggle(true); + show_button.picture_style(true); + show_button.image_selected(LLUI::getUIImage("ComboButton_Selected")); + show_button.image_unselected(LLUI::getUIImage("ComboButton_Off")); + + monitor.name("monitor"); + monitor.rect(LLRect(0, 10, 16, 0)); +} + +LLTalkButton::LLTalkButton(const Params& p) : LLUICtrl(p) +, mPrivateCallPanel(NULL) +, mOutputMonitor(NULL) +, mSpeakBtn(NULL) +, mShowBtn(NULL) { - static S32 DROPDOWN_BTN_WIDTH = 20; - - LLRect rc(p.rect); - - LLButton::Params speak_params; - speak_params.name("left"); - speak_params.rect(LLRect(0,rc.getHeight(),rc.getWidth()-DROPDOWN_BTN_WIDTH,0)); - speak_params.label("Speak"); - speak_params.label_selected("Speak"); - speak_params.font(LLFontGL::getFontSansSerifSmall()); - speak_params.tab_stop(false); - speak_params.is_toggle(true); - speak_params.picture_style(true); - speak_params.image_selected(LLUI::getUIImage("SegmentedBtn_Left_Selected")); - speak_params.image_unselected(LLUI::getUIImage("SegmentedBtn_Left_Off")); + LLRect rect = p.rect(); + LLRect speak_rect(0, rect.getHeight(), rect.getWidth(), 0); + LLRect show_rect = p.show_button.rect(); + show_rect.set(0, rect.getHeight(), show_rect.getWidth(), 0); + + speak_rect.mRight -= show_rect.getWidth(); + show_rect.mLeft = speak_rect.getWidth(); + show_rect.mRight = rect.getWidth(); + + LLButton::Params speak_params = p.speak_button; + speak_params.rect(speak_rect); mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params); addChild(mSpeakBtn); mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this)); - mSpeakBtn->setToggleState(false); - - LLButton::Params show_params; - show_params.name("right"); - show_params.rect(LLRect(rc.getWidth()-DROPDOWN_BTN_WIDTH,rc.getHeight(),rc.getWidth(),0)); - show_params.label(""); - show_params.tab_stop(false); - show_params.is_toggle(true); - show_params.picture_style(true); - show_params.image_selected(LLUI::getUIImage("ComboButton_Selected")); - show_params.image_unselected(LLUI::getUIImage("ComboButton_Off")); + mSpeakBtn->setToggleState(FALSE); + + LLButton::Params show_params = p.show_button; + show_params.rect(show_rect); mShowBtn = LLUICtrlFactory::create<LLButton>(show_params); addChild(mShowBtn); mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this)); - mShowBtn->setToggleState(false); - - mSpeakBtn->setToggleState(FALSE); mShowBtn->setToggleState(FALSE); - rc = mSpeakBtn->getRect(); + static const S32 MONITOR_RIGHT_PAD = 2; - LLOutputMonitorCtrl::Params monitor_param; - monitor_param.name("monitor"); - monitor_param.draw_border(false); - monitor_param.rect(LLRect(rc.getWidth()-20,18,rc.getWidth()-3,2)); - monitor_param.visible(true); - mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_param); - // never show "muted" because you can't mute yourself - mOutputMonitor->setIsMuted(false); + LLRect monitor_rect = p.monitor.rect(); + S32 monitor_height = monitor_rect.getHeight(); + monitor_rect.mLeft = speak_rect.getWidth() - monitor_rect.getWidth() - MONITOR_RIGHT_PAD; + monitor_rect.mRight = speak_rect.getWidth() - MONITOR_RIGHT_PAD; + monitor_rect.mBottom = (rect.getHeight() / 2) - (monitor_height / 2); + monitor_rect.mTop = monitor_rect.mBottom + monitor_height; + LLOutputMonitorCtrl::Params monitor_params = p.monitor; + monitor_params.draw_border(false); + monitor_params.rect(monitor_rect); + mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params); mSpeakBtn->addChild(mOutputMonitor); - mPrivateCallPanel = NULL; + // never show "muted" because you can't mute yourself + mOutputMonitor->setIsMuted(false); } LLTalkButton::~LLTalkButton() @@ -838,8 +965,7 @@ void LLTalkButton::onClick_ShowBtn() mPrivateCallPanel = new LLVoiceControlPanel; getRootView()->addChild(mPrivateCallPanel); - if(gBottomTray) - y = gBottomTray->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight(); + y = LLBottomTray::getInstance()->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight(); LLRect rect; rect.setLeftTopAndSize(x, y, mPrivateCallPanel->getRect().getWidth(), mPrivateCallPanel->getRect().getHeight()); @@ -857,3 +983,63 @@ void LLTalkButton::onClick_ShowBtn() mShowBtn->setToggleState(TRUE); } + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p) + : LLTextBox(p) + , mCounter(0) + , mInitialWidth(0) +{ + mInitialWidth = getRect().getWidth(); +} + +void LLChicletNotificationCounterCtrl::setCounter(S32 counter) +{ + mCounter = counter; + + std::stringstream stream; + stream << getCounter(); + setText(stream.str()); +} + +LLRect LLChicletNotificationCounterCtrl::getRequiredRect() +{ + LLRect rc; + S32 text_width = getFont()->getWidth(getText()); + + rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth); + + return rc; +} + +void LLChicletNotificationCounterCtrl::setValue(const LLSD& value) +{ + if(value.isInteger()) + setCounter(value.asInteger()); +} + +LLSD LLChicletNotificationCounterCtrl::getValue() const +{ + return LLSD(getCounter()); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p) + : LLAvatarIconCtrl(p) +{ +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p) + : LLIconCtrl(p) +{ +} |