summaryrefslogtreecommitdiff
path: root/indra/newview/llchiclet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llchiclet.cpp')
-rwxr-xr-x[-rw-r--r--]indra/newview/llchiclet.cpp1347
1 files changed, 575 insertions, 772 deletions
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 340b0fa22c..46b7679915 100644..100755
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -1,65 +1,45 @@
/**
-* @file llchiclet.cpp
-* @brief LLChiclet class implementation
-*
-* $LicenseInfo:firstyear=2002&license=viewergpl$
-*
-* Copyright (c) 2002-2009, Linden Research, Inc.
-*
-* Second Life Viewer Source Code
-* The source code in this file ("Source Code") is provided by Linden Lab
-* to you under the terms of the GNU General Public License, version 2.0
-* ("GPL"), unless you have obtained a separate licensing agreement
-* ("Other License"), formally executed by you and Linden Lab. Terms of
-* the GPL can be found in doc/GPL-license.txt in this distribution, or
-* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
-*
-* There are special exceptions to the terms and conditions of the GPL as
-* it is applied to this Source Code. View the full text of the exception
-* in the file doc/FLOSS-exception.txt in this software distribution, or
-* online at
-* http://secondlifegrid.net/programs/open_source/licensing/flossexception
-*
-* By copying, modifying or distributing this software, you acknowledge
-* that you have read and understood your obligations described above,
-* and agree to abide by those obligations.
-*
-* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
-* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
-* COMPLETENESS OR PERFORMANCE.
-* $/LicenseInfo$
-*/
+ * @file llchiclet.cpp
+ * @brief LLChiclet class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
#include "llviewerprecompiledheaders.h" // must be first include
#include "llchiclet.h"
-#include "llagent.h"
-#include "llavataractions.h"
-#include "llbottomtray.h"
-#include "llgroupactions.h"
-#include "lliconctrl.h"
-#include "llimpanel.h" // LLFloaterIMPanel
-#include "llimfloater.h"
-#include "llimview.h"
+
+#include "llchicletbar.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h"
#include "llfloaterreg.h"
#include "lllocalcliprect.h"
-#include "llmenugl.h"
-#include "lloutputmonitorctrl.h"
-#include "lltextbox.h"
-#include "llvoiceclient.h"
-#include "llvoicecontrolpanel.h"
-#include "llgroupmgr.h"
-#include "llnotificationmanager.h"
-#include "lltransientfloatermgr.h"
+#include "llscriptfloater.h"
+#include "llsingleton.h"
+#include "llsyswellwindow.h"
static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
-static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");
-static LLDefaultChildRegistry::Register<LLNotificationChiclet> t3("chiclet_notification");
-static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t4("chiclet_im_p2p");
-static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t5("chiclet_im_group");
-
-S32 LLNotificationChiclet::mUreadSystemNotifications = 0;
-S32 LLNotificationChiclet::mUreadIMNotifications = 0;
-
+static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
+static LLDefaultChildRegistry::Register<LLScriptChiclet> t6("chiclet_script");
+static LLDefaultChildRegistry::Register<LLInvOfferChiclet> t7("chiclet_offer");
boost::signals2::signal<LLChiclet* (const LLUUID&),
LLIMChiclet::CollectChicletCombiner<std::list<LLChiclet*> > >
@@ -68,399 +48,251 @@ boost::signals2::signal<LLChiclet* (const LLUUID&),
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-LLNotificationChiclet::Params::Params()
-: button("button")
-, unread_notifications("unread_notifications")
+LLSysWellChiclet::Params::Params()
+ : button("button")
+ , unread_notifications("unread_notifications")
+ , max_displayed_count("max_displayed_count", 99)
{
- button.name("button");
- button.tab_stop(FALSE);
- button.label(LLStringUtil::null);
-
- unread_notifications.name("unread");
- unread_notifications.font(LLFontGL::getFontSansSerif());
- unread_notifications.text_color=(LLColor4::white);
- unread_notifications.font_halign(LLFontGL::HCENTER);
- unread_notifications.mouse_opaque(FALSE);
+ button.name = "button";
+ button.tab_stop = FALSE;
+ button.label = LLStringUtil::null;
}
-LLNotificationChiclet::LLNotificationChiclet(const Params& p)
-: LLChiclet(p)
-, mButton(NULL)
-, mCounterCtrl(NULL)
+LLSysWellChiclet::LLSysWellChiclet(const Params& p)
+ : LLChiclet(p)
+ , mButton(NULL)
+ , mCounter(0)
+ , mMaxDisplayedCount(p.max_displayed_count)
+ , mIsNewMessagesState(false)
+ , mFlashToLitTimer(NULL)
+ , mContextMenu(NULL)
{
LLButton::Params button_params = p.button;
- button_params.rect(p.rect());
mButton = LLUICtrlFactory::create<LLButton>(button_params);
addChild(mButton);
- LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
- mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
- addChild(mCounterCtrl);
-
- // connect counter handlers to the signals
- connectCounterUpdatersToSignal("notify");
- connectCounterUpdatersToSignal("groupnotify");
- connectCounterUpdatersToSignal("notifytoast");
+ mFlashToLitTimer = new LLFlashTimer(boost::bind(&LLSysWellChiclet::changeLitState, this, _1));
}
-LLNotificationChiclet::~LLNotificationChiclet()
+LLSysWellChiclet::~LLSysWellChiclet()
{
-
+ mFlashToLitTimer->unset();
}
-void LLNotificationChiclet::connectCounterUpdatersToSignal(std::string notification_type)
+void LLSysWellChiclet::setCounter(S32 counter)
{
- LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
- LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
- if(n_handler)
+ // do nothing if the same counter is coming. EXT-3678.
+ if (counter == mCounter) return;
+
+ // note same code in LLChicletNotificationCounterCtrl::setCounter(S32 counter)
+ std::string s_count;
+ if(counter != 0)
{
- if(notification_type == "notifytoast")
- {
- n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::updateUreadIMNotifications, this));
- n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::updateUreadIMNotifications, this));
- }
- else
- {
- n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::incUreadSystemNotifications, this));
- n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::decUreadSystemNotifications, this));
- }
+ static std::string more_messages_exist("+");
+ std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : "");
+ s_count = llformat("%d%s"
+ , llmin(counter, mMaxDisplayedCount)
+ , more_messages.c_str()
+ );
}
-}
-void LLNotificationChiclet::setCounter(S32 counter)
-{
- mCounterCtrl->setCounter(counter);
-}
+ mButton->setLabel(s_count);
-void LLNotificationChiclet::setShowCounter(bool show)
-{
- LLChiclet::setShowCounter(show);
- mCounterCtrl->setVisible(getShowCounter());
+ mCounter = counter;
}
-boost::signals2::connection LLNotificationChiclet::setClickCallback(
+boost::signals2::connection LLSysWellChiclet::setClickCallback(
const commit_callback_t& cb)
{
return mButton->setClickedCallback(cb);
}
-void LLNotificationChiclet::setToggleState(BOOL toggled) {
+void LLSysWellChiclet::setToggleState(BOOL toggled) {
mButton->setToggleState(toggled);
}
-void LLNotificationChiclet::updateUreadIMNotifications()
+void LLSysWellChiclet::changeLitState(bool blink)
{
- mUreadIMNotifications = gIMMgr->getNumberOfUnreadIM();
- setCounter(mUreadSystemNotifications + mUreadIMNotifications);
+ setNewMessagesState(!mIsNewMessagesState);
}
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLChiclet::Params::Params()
- : show_counter("show_counter")
-{
- show_counter = true;
-}
-
-LLChiclet::LLChiclet(const Params& p)
-: LLUICtrl(p)
-, mSessionId(LLUUID::null)
-, mShowCounter(p.show_counter)
+void LLSysWellChiclet::setNewMessagesState(bool new_messages)
{
+ /*
+ Emulate 4 states of button by background images, see detains in EXT-3147
+ xml attribute Description
+ image_unselected "Unlit" - there are no new messages
+ image_selected "Unlit" + "Selected" - there are no new messages and the Well is open
+ image_pressed "Lit" - there are new messages
+ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well is open
+ */
+ mButton->setForcePressedState(new_messages);
+ mIsNewMessagesState = new_messages;
}
-LLChiclet::~LLChiclet()
+void LLSysWellChiclet::updateWidget(bool is_window_empty)
{
+ mButton->setEnabled(!is_window_empty);
+ if (LLChicletBar::instanceExists())
+ {
+ LLChicletBar::getInstance()->showWellButton(getName(), !is_window_empty);
+ }
}
-
-boost::signals2::connection LLChiclet::setLeftButtonClickCallback(
- const commit_callback_t& cb)
-{
- return mCommitSignal.connect(cb);
-}
-
-BOOL LLChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
+// virtual
+BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
- onCommit();
- childrenHandleMouseDown(x,y,mask);
+ if(!mContextMenu)
+ {
+ createMenu();
+ }
+ if (mContextMenu)
+ {
+ mContextMenu->show(x, y);
+ LLMenuGL::showPopup(this, mContextMenu, x, y);
+ }
return TRUE;
}
-boost::signals2::connection LLChiclet::setChicletSizeChangedCallback(
- const chiclet_size_changed_callback_t& cb)
+/************************************************************************/
+/* LLNotificationChiclet implementation */
+/************************************************************************/
+LLNotificationChiclet::LLNotificationChiclet(const Params& p)
+: LLSysWellChiclet(p),
+ mUreadSystemNotifications(0)
{
- return mChicletSizeChangedSignal.connect(cb);
+ mNotificationChannel.reset(new ChicletNotificationChannel(this));
+ // ensure that notification well window exists, to synchronously
+ // handle toast add/delete events.
+ LLNotificationWellWindow::getInstance()->setSysWellChiclet(this);
}
-void LLChiclet::onChicletSizeChanged()
+void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
{
- mChicletSizeChangedSignal(this, getValue());
+ std::string action = user_data.asString();
+ if("close all" == action)
+ {
+ LLNotificationWellWindow::getInstance()->closeAll();
+ LLIMWellWindow::getInstance()->closeAll();
+ }
}
-LLSD LLChiclet::getValue() const
+bool LLNotificationChiclet::enableMenuItem(const LLSD& user_data)
{
- return LLSD(getSessionId());
+ std::string item = user_data.asString();
+ if (item == "can close all")
+ {
+ return mUreadSystemNotifications != 0;
+ }
+ return true;
}
-void LLChiclet::setValue(const LLSD& value)
+void LLNotificationChiclet::createMenu()
{
- if(value.isUUID())
- setSessionId(value.asUUID());
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
+ if(mContextMenu)
+ {
+ LL_WARNS() << "Menu already exists" << LL_ENDL;
+ return;
+ }
-LLIMChiclet::LLIMChiclet(const LLChiclet::Params& p)
-: LLChiclet(p)
-{
-}
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ registrar.add("NotificationWellChicletMenu.Action",
+ boost::bind(&LLNotificationChiclet::onMenuItemClicked, this, _2));
-void LLIMChiclet::onMouseDown()
-{
- LLIMFloater::toggle(getSessionId());
- setCounter(0);
-}
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+ enable_registrar.add("NotificationWellChicletMenu.EnableItem",
+ boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2));
-BOOL LLIMChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
-{
- onMouseDown();
- return LLChiclet::handleMouseDown(x, y, mask);
+ llassert(LLMenuGL::sMenuContainer != NULL);
+ mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
+ ("menu_notification_well_button.xml",
+ LLMenuGL::sMenuContainer,
+ LLViewerMenuHolderGL::child_registry_t::instance());
}
-void LLIMChiclet::draw()
+/*virtual*/
+void LLNotificationChiclet::setCounter(S32 counter)
{
- LLUICtrl::draw();
-
- gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE);
+ LLSysWellChiclet::setCounter(counter);
+ updateWidget(getCounter() == 0);
+
}
-// static
-LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id)
+bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification )
{
- EType type = TYPE_UNKNOWN;
-
- if(session_id.isNull())
- return type;
-
- EInstantMessage im_type = LLIMModel::getInstance()->getType(session_id);
- if (IM_COUNT == im_type)
+ bool displayNotification;
+ if ( (notification->getName() == "ScriptDialog") // special case for scripts
+ // if there is no toast window for the notification, filter it
+ || (!LLNotificationWellWindow::getInstance()->findItemByID(notification->getID()))
+ )
{
- llassert_always(0 && "IM session not found"); // should never happen
- return type;
+ displayNotification = false;
}
-
- switch(im_type)
+ else if( !(notification->canLogToIM() && notification->hasFormElements())
+ && (!notification->getPayload().has("give_inventory_notification")
+ || notification->getPayload()["give_inventory_notification"]))
{
- case IM_NOTHING_SPECIAL:
- case IM_SESSION_P2P_INVITE:
- type = TYPE_IM;
- break;
- case IM_SESSION_GROUP_START:
- case IM_SESSION_INVITE:
- if (gAgent.isInGroup(session_id))
- {
- type = TYPE_GROUP;
- }
- else
- {
- type = TYPE_AD_HOC;
- }
- break;
- case IM_SESSION_CONFERENCE_START:
- type = TYPE_AD_HOC;
- default:
- break;
+ displayNotification = true;
}
-
- return type;
+ else
+ {
+ displayNotification = false;
+ }
+ return displayNotification;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-LLIMP2PChiclet::Params::Params()
-: avatar_icon("avatar_icon")
-, unread_notifications("unread_notifications")
-, speaker("speaker")
-, show_speaker("show_speaker")
-{
- // *TODO Vadim: Get rid of hardcoded values.
- rect(LLRect(0, 25, 45, 0));
-
- avatar_icon.name("avatar_icon");
- avatar_icon.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
-
- // *NOTE dzaporozhan
- // Changed icon height from 25 to 24 to fix ticket EXT-794.
- // In some cases(after changing UI scale) 25 pixel height icon was
- // drawn incorrectly, i'm not sure why.
- avatar_icon.rect(LLRect(0, 24, 25, 0));
- avatar_icon.mouse_opaque(false);
-
- 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);
- unread_notifications.mouse_opaque(false);
-
- speaker.name("speaker");
- speaker.rect(LLRect(45, 25, 65, 0));
-
- show_speaker = false;
-}
-
-LLIMP2PChiclet::LLIMP2PChiclet(const Params& p)
-: LLIMChiclet(p)
-, mChicletIconCtrl(NULL)
-, mCounterCtrl(NULL)
-, mSpeakerCtrl(NULL)
-, mPopupMenu(NULL)
+LLChiclet::Params::Params()
+ : show_counter("show_counter", true)
+ , enable_counter("enable_counter", false)
{
- LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
- mChicletIconCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
- addChild(mChicletIconCtrl);
-
- 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(p.show_speaker);
}
-void LLIMP2PChiclet::setCounter(S32 counter)
-{
- mCounterCtrl->setCounter(counter);
-
- 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 LLIMP2PChiclet::getRequiredRect()
+LLChiclet::LLChiclet(const Params& p)
+: LLUICtrl(p)
+, mSessionId(LLUUID::null)
+, mShowCounter(p.show_counter)
{
- LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0);
- if(getShowCounter())
- {
- rect.mRight += mCounterCtrl->getRequiredRect().getWidth();
- }
- if(getShowSpeaker())
- {
- rect.mRight += mSpeakerCtrl->getRect().getWidth();
- }
- return rect;
}
-void LLIMP2PChiclet::setOtherParticipantId(const LLUUID& other_participant_id)
+boost::signals2::connection LLChiclet::setLeftButtonClickCallback(
+ const commit_callback_t& cb)
{
- LLIMChiclet::setOtherParticipantId(other_participant_id);
- mChicletIconCtrl->setValue(getOtherParticipantId());
+ return setCommitCallback(cb);
}
-void LLIMP2PChiclet::updateMenuItems()
+BOOL LLChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
{
- if(!mPopupMenu)
- return;
- if(getSessionId().isNull())
- return;
-
- bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId());
-
- mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend);
- mPopupMenu->getChild<LLUICtrl>("Remove Friend")->setEnabled(is_friend);
+ onCommit();
+ childrenHandleMouseDown(x,y,mask);
+ return TRUE;
}
-BOOL LLIMP2PChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
+boost::signals2::connection LLChiclet::setChicletSizeChangedCallback(
+ const chiclet_size_changed_callback_t& cb)
{
- if(!mPopupMenu)
- {
- createPopupMenu();
- }
-
- if (mPopupMenu)
- {
- updateMenuItems();
- mPopupMenu->arrangeAndClear();
- LLMenuGL::showPopup(this, mPopupMenu, x, y);
- }
-
- return TRUE;
+ return mChicletSizeChangedSignal.connect(cb);
}
-void LLIMP2PChiclet::createPopupMenu()
+void LLChiclet::onChicletSizeChanged()
{
- if(mPopupMenu)
- {
- llwarns << "Menu already exists" << llendl;
- return;
- }
- if(getSessionId().isNull())
- {
- return;
- }
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
- ("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mChicletSizeChangedSignal(this, getValue());
}
-void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data)
+LLSD LLChiclet::getValue() const
{
- std::string level = user_data.asString();
- LLUUID other_participant_id = getOtherParticipantId();
-
- if("profile" == level)
- {
- LLAvatarActions::showProfile(other_participant_id);
- }
- else if("im" == level)
- {
- LLAvatarActions::startIM(other_participant_id);
- }
- else if("add" == level)
- {
- LLAvatarActions::requestFriendshipDialog(other_participant_id);
- }
+ return LLSD(getSessionId());
}
-void LLIMP2PChiclet::setShowSpeaker(bool show)
+void LLChiclet::setValue(const LLSD& value)
{
- LLIMChiclet::setShowSpeaker(show);
-
- bool needs_resize = getShowSpeaker() != show;
- mSpeakerCtrl->setVisible(getShowSpeaker());
- if(needs_resize)
+ if(value.isUUID())
{
- onChicletSizeChanged();
+ setSessionId(value.asUUID());
}
}
@@ -468,133 +300,66 @@ void LLIMP2PChiclet::setShowSpeaker(bool show)
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-LLIMGroupChiclet::Params::Params()
-: group_icon("group_icon")
-{
- rect(LLRect(0, 25, 45, 0));
-
- group_icon.name("group_icon");
-
- // *NOTE dzaporozhan
- // Changed icon height from 25 to 24 to fix ticket EXT-794.
- // In some cases(after changing UI scale) 25 pixel height icon was
- // drawn incorrectly, i'm not sure why.
- group_icon.rect(LLRect(0, 24, 25, 0));
-
- 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);
-
- speaker.name("speaker");
- speaker.rect(LLRect(45, 25, 65, 0));
-
- show_speaker = false;
-}
-
-LLIMGroupChiclet::LLIMGroupChiclet(const Params& p)
-: LLIMChiclet(p)
-, LLGroupMgrObserver(LLUUID::null)
-, mChicletIconCtrl(NULL)
-, mCounterCtrl(NULL)
-, mSpeakerCtrl(NULL)
+LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p)
+: LLChiclet(p)
+, mShowSpeaker(false)
+, mDefaultWidth(p.rect().getWidth())
+, mNewMessagesIcon(NULL)
+, mChicletButton(NULL)
, mPopupMenu(NULL)
{
- LLChicletGroupIconCtrl::Params avatar_params = p.group_icon;
- mChicletIconCtrl = LLUICtrlFactory::create<LLChicletGroupIconCtrl>(avatar_params);
- addChild(mChicletIconCtrl);
-
- 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(p.show_speaker);
}
-LLIMGroupChiclet::~LLIMGroupChiclet()
+/* virtual*/
+BOOL LLIMChiclet::postBuild()
{
- LLGroupMgr::getInstance()->removeObserver(this);
+ mChicletButton = getChild<LLButton>("chiclet_button");
+ mChicletButton->setCommitCallback(boost::bind(&LLIMChiclet::onMouseDown, this));
+ mChicletButton->setDoubleClickCallback(boost::bind(&LLIMChiclet::onMouseDown, this));
+ return TRUE;
}
-void LLIMGroupChiclet::setCounter(S32 counter)
+void LLIMChiclet::enableCounterControl(bool enable)
{
- mCounterCtrl->setCounter(counter);
-
- if(getShowCounter())
+ mCounterEnabled = enable;
+ if(!enable)
{
- 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();
- }
+ LLChiclet::setShowCounter(false);
}
}
-LLRect LLIMGroupChiclet::getRequiredRect()
+void LLIMChiclet::setRequiredWidth()
{
- LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0);
- if(getShowCounter())
- {
- rect.mRight += mCounterCtrl->getRequiredRect().getWidth();
- }
- if(getShowSpeaker())
+ S32 required_width = mDefaultWidth;
+ reshape(required_width, getRect().getHeight());
+ onChicletSizeChanged();
+}
+
+void LLIMChiclet::setShowNewMessagesIcon(bool show)
+{
+ if(mNewMessagesIcon)
{
- rect.mRight += mSpeakerCtrl->getRect().getWidth();
+ mNewMessagesIcon->setVisible(show);
}
- return rect;
+ setRequiredWidth();
}
-void LLIMGroupChiclet::setSessionId(const LLUUID& session_id)
+bool LLIMChiclet::getShowNewMessagesIcon()
{
- LLChiclet::setSessionId(session_id);
+ return mNewMessagesIcon->getVisible();
+}
- LLGroupMgr* grp_mgr = LLGroupMgr::getInstance();
- LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id);
- if (group_data && group_data->mInsigniaID.notNull())
- {
- mChicletIconCtrl->setValue(group_data->mInsigniaID);
- }
- else
- {
- if(getSessionId() != mID)
- {
- grp_mgr->removeObserver(this);
- mID = getSessionId();
- grp_mgr->addObserver(this);
- }
- grp_mgr->sendGroupPropertiesRequest(session_id);
- }
+void LLIMChiclet::onMouseDown()
+{
+ LLFloaterIMSession::toggle(getSessionId());
}
-void LLIMGroupChiclet::changed(LLGroupChange gc)
+void LLIMChiclet::setToggleState(bool toggle)
{
- if (GC_PROPERTIES == gc)
- {
- LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId());
- if (group_data)
- {
- mChicletIconCtrl->setValue(group_data->mInsigniaID);
- }
- }
+ mChicletButton->setToggleState(toggle);
}
-BOOL LLIMGroupChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
+BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if(!mPopupMenu)
{
@@ -603,6 +368,7 @@ BOOL LLIMGroupChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
if (mPopupMenu)
{
+ updateMenuItems();
mPopupMenu->arrangeAndClear();
LLMenuGL::showPopup(this, mPopupMenu, x, y);
}
@@ -610,50 +376,26 @@ BOOL LLIMGroupChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
return TRUE;
}
-void LLIMGroupChiclet::createPopupMenu()
+void LLIMChiclet::hidePopupMenu()
{
- if(mPopupMenu)
- {
- llwarns << "Menu already exists" << llendl;
- return;
- }
- if(getSessionId().isNull())
+ if (mPopupMenu)
{
- return;
+ mPopupMenu->setVisible(FALSE);
}
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
- ("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
}
-void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data)
+bool LLIMChiclet::canCreateMenu()
{
- std::string level = user_data.asString();
- LLUUID group_id = getSessionId();
-
- if("group chat" == level)
- {
- LLGroupActions::startChat(group_id);
- }
- else if("info" == level)
+ if(mPopupMenu)
{
- LLGroupActions::show(group_id);
+ LL_WARNS() << "Menu already exists" << LL_ENDL;
+ return false;
}
-}
-
-void LLIMGroupChiclet::setShowSpeaker(bool show)
-{
- LLIMChiclet::setShowSpeaker(show);
-
- bool needs_resize = getShowSpeaker() != show;
- mSpeakerCtrl->setVisible(getShowSpeaker());
- if(needs_resize)
+ if(getSessionId().isNull())
{
- onChicletSizeChanged();
+ return false;
}
+ return true;
}
//////////////////////////////////////////////////////////////////////////
@@ -663,31 +405,10 @@ void LLIMGroupChiclet::setShowSpeaker(bool show)
LLChicletPanel::Params::Params()
: chiclet_padding("chiclet_padding")
, scrolling_offset("scrolling_offset")
-, left_scroll_button("left_scroll_button")
-, right_scroll_button("right_scroll_button")
+, scroll_button_hpad("scroll_button_hpad")
+, scroll_ratio("scroll_ratio")
, min_width("min_width")
{
- chiclet_padding = 3;
- scrolling_offset = 40;
- min_width = 70;
-
- 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)
@@ -697,25 +418,13 @@ LLChicletPanel::LLChicletPanel(const Params&p)
, mRightScrollButton(NULL)
, mChicletPadding(p.chiclet_padding)
, mScrollingOffset(p.scrolling_offset)
+, mScrollButtonHPad(p.scroll_button_hpad)
+, mScrollRatio(p.scroll_ratio)
, mMinWidth(p.min_width)
, mShowControls(true)
{
- 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;
+ panel_params.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT);
mScrollArea = LLUICtrlFactory::create<LLPanel>(panel_params,this);
// important for Show/Hide Camera and Move controls menu in bottom tray to work properly
@@ -726,62 +435,134 @@ LLChicletPanel::LLChicletPanel(const Params&p)
LLChicletPanel::~LLChicletPanel()
{
+ if(LLTransientFloaterMgr::instanceExists())
+ {
+ LLTransientFloaterMgr::getInstance()->removeControlView(mLeftScrollButton);
+ LLTransientFloaterMgr::getInstance()->removeControlView(mRightScrollButton);
+ }
+}
+
+void LLChicletPanel::onMessageCountChanged(const LLSD& data)
+{
+ // *TODO : we either suppress this method or return a value. Right now, it servers no purpose.
+ /*
+ //LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
+ //if (im_floater && im_floater->getVisible() && im_floater->hasFocus())
+ //{
+ // unread = 0;
+ //}
+ */
}
-void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){
-
- LLUUID session_id = data["session_id"].asUUID();
- std::list<LLChiclet*> chiclets = LLIMChiclet::sFindChicletsSignal(session_id);
+void LLChicletPanel::objectChicletCallback(const LLSD& data)
+{
+ LLUUID notification_id = data["notification_id"];
+ bool new_message = data["new_message"];
+
+ std::list<LLChiclet*> chiclets = LLIMChiclet::sFindChicletsSignal(notification_id);
std::list<LLChiclet *>::iterator iter;
- for (iter = chiclets.begin(); iter != chiclets.end(); iter++) {
- LLChiclet* chiclet = *iter;
+ for (iter = chiclets.begin(); iter != chiclets.end(); iter++)
+ {
+ LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*iter);
if (chiclet != NULL)
{
- chiclet->setCounter(data["num_unread"].asInteger());
+ chiclet->setShowNewMessagesIcon(new_message);
}
- else
- {
- llwarns << "Unable to set counter for chiclet " << session_id << llendl;
- }
}
-
}
-
BOOL LLChicletPanel::postBuild()
{
LLPanel::postBuild();
- LLIMModel::instance().addChangedCallback(boost::bind(im_chiclet_callback, this, _1));
+ LLIMModel::instance().addNewMsgCallback(boost::bind(&LLChicletPanel::onMessageCountChanged, this, _1));
+ LLIMModel::instance().addNoUnreadMsgsCallback(boost::bind(&LLChicletPanel::onMessageCountChanged, this, _1));
+ LLScriptFloaterManager::getInstance()->addNewObjectCallback(boost::bind(&LLChicletPanel::objectChicletCallback, this, _1));
+ LLScriptFloaterManager::getInstance()->addToggleObjectFloaterCallback(boost::bind(&LLChicletPanel::objectChicletCallback, this, _1));
LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLChicletPanel::findChiclet<LLChiclet>, this, _1));
+ LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLChicletPanel::onCurrentVoiceChannelChanged, this, _1));
+
+ mLeftScrollButton=getChild<LLButton>("chicklet_left_scroll_button");
+ LLTransientFloaterMgr::getInstance()->addControlView(mLeftScrollButton);
+ mLeftScrollButton->setMouseDownCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this));
+ mLeftScrollButton->setHeldDownCallback(boost::bind(&LLChicletPanel::onLeftScrollHeldDown,this));
+ mLeftScrollButton->setEnabled(false);
+
+ mRightScrollButton=getChild<LLButton>("chicklet_right_scroll_button");
+ LLTransientFloaterMgr::getInstance()->addControlView(mRightScrollButton);
+ mRightScrollButton->setMouseDownCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this));
+ mRightScrollButton->setHeldDownCallback(boost::bind(&LLChicletPanel::onRightScrollHeldDown,this));
+ mRightScrollButton->setEnabled(false);
return TRUE;
}
+void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id)
+{
+ static LLUUID s_previous_active_voice_session_id;
+
+ std::list<LLChiclet*> chiclets = LLIMChiclet::sFindChicletsSignal(session_id);
+
+ for(std::list<LLChiclet *>::iterator it = chiclets.begin(); it != chiclets.end(); ++it)
+ {
+ LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
+ if(chiclet)
+ {
+ if (gSavedSettings.getBOOL("OpenIMOnVoice"))
+ {
+ LLFloaterIMContainer::getInstance()->showConversation(session_id);
+ }
+ }
+ }
+
+ s_previous_active_voice_session_id = session_id;
+}
+
bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)
{
if(mScrollArea->addChild(chiclet))
{
- S32 offset = 0;
+ // chiclets should be aligned to right edge of scroll panel
+ S32 left_shift = 0;
- // if index == 0 and chickelt list isn't empty insert chiclet before first in the list
- // without scrolling, so other visible chicklets aren't change screen position
- if (0 == index && !mChicletList.empty())
+ if (!canScrollLeft())
{
- offset = getChiclet(0)->getRect().mLeft
- - (chiclet->getRequiredRect().getWidth()
- + getChicletPadding());
+ // init left shift for the first chiclet in the list...
+ if (mChicletList.empty())
+ {
+ // ...start from the right border of the scroll area for the first added chiclet
+ left_shift = mScrollArea->getRect().getWidth();
+ }
+ else
+ {
+ // ... start from the left border of the first chiclet minus padding
+ left_shift = getChiclet(0)->getRect().mLeft - getChicletPadding();
+ }
+
+ // take into account width of the being added chiclet
+ left_shift -= chiclet->getRequiredRect().getWidth();
+
+ // if we overflow the scroll area we do not need to shift chiclets
+ if (left_shift < 0)
+ {
+ left_shift = 0;
+ }
}
mChicletList.insert(mChicletList.begin() + index, chiclet);
- getChiclet(0)->translate(offset, 0);
+ // shift first chiclet to place it in correct position.
+ // rest ones will be placed in arrange()
+ if (!canScrollLeft())
+ {
+ getChiclet(0)->translate(left_shift - getChiclet(0)->getRect().mLeft, 0);
+ }
chiclet->setLeftButtonClickCallback(boost::bind(&LLChicletPanel::onChicletClick, this, _1, _2));
chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index));
arrange();
- showScrollButtonsIfNeeded();
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, chiclet);
return true;
}
@@ -791,40 +572,26 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)
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();
+ arrange();
}
void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD&param)
{
- mCommitSignal(ctrl,param);
+ if (mCommitSignal)
+ {
+ (*mCommitSignal)(ctrl,param);
+ }
}
void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it)
{
- mScrollArea->removeChild(*it);
+ LLChiclet* chiclet = *it;
+ mScrollArea->removeChild(chiclet);
mChicletList.erase(it);
arrange();
- trimChiclets();
- showScrollButtonsIfNeeded();
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, chiclet);
+ chiclet->die();
}
void LLChicletPanel::removeChiclet(S32 index)
@@ -917,25 +684,76 @@ void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent )
{
LLPanel::reshape(width,height,called_from_parent);
- static const S32 SCROLL_BUTTON_PAD = 5;
-
+ //Needed once- to avoid error at first call of reshape() before postBuild()
+ if(!mLeftScrollButton||!mRightScrollButton)
+ return;
+
LLRect scroll_button_rect = mLeftScrollButton->getRect();
- mLeftScrollButton->setRect(LLRect(0,height,scroll_button_rect.getWidth(),
- height - scroll_button_rect.getHeight()));
-
+ mLeftScrollButton->setRect(LLRect(0,scroll_button_rect.mTop,scroll_button_rect.getWidth(),
+ scroll_button_rect.mBottom));
scroll_button_rect = mRightScrollButton->getRect();
- mRightScrollButton->setRect(LLRect(width - scroll_button_rect.getWidth(),height,
- width, height - scroll_button_rect.getHeight()));
-
- mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD,
- height, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0));
+ mRightScrollButton->setRect(LLRect(width - scroll_button_rect.getWidth(),scroll_button_rect.mTop,
+ width, scroll_button_rect.mBottom));
+
- mShowControls = width > mMinWidth;
+ bool need_show_scroll = needShowScroll();
+ if(need_show_scroll)
+ {
+ mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + mScrollButtonHPad,
+ height, width - scroll_button_rect.getWidth() - mScrollButtonHPad, 0));
+ }
+ else
+ {
+ mScrollArea->setRect(LLRect(0,height, width, 0));
+ }
+
+ mShowControls = width >= mMinWidth;
+
mScrollArea->setVisible(mShowControls);
trimChiclets();
-
showScrollButtonsIfNeeded();
+
+}
+
+S32 LLChicletPanel::notifyParent(const LLSD& info)
+{
+ if(info.has("notification"))
+ {
+ std::string str_notification = info["notification"];
+ if(str_notification == "size_changes")
+ {
+ arrange();
+ return 1;
+ }
+ }
+ return LLPanel::notifyParent(info);
+}
+
+void LLChicletPanel::setChicletToggleState(const LLUUID& session_id, bool toggle)
+{
+ if(session_id.isNull())
+ {
+ LL_WARNS() << "Null Session ID" << LL_ENDL;
+ }
+
+ // toggle off all chiclets, except specified
+ S32 size = getChicletCount();
+ for(int n = 0; n < size; ++n)
+ {
+ LLIMChiclet* chiclet = getChiclet<LLIMChiclet>(n);
+ if(chiclet && chiclet->getSessionId() != session_id)
+ {
+ chiclet->setToggleState(false);
+ }
+ }
+
+ // toggle specified chiclet
+ LLIMChiclet* chiclet = findChiclet<LLIMChiclet>(session_id);
+ if(chiclet)
+ {
+ chiclet->setToggleState(toggle);
+ }
}
void LLChicletPanel::arrange()
@@ -943,8 +761,8 @@ void LLChicletPanel::arrange()
if(mChicletList.empty())
return;
+ //initial arrange of chicklets positions
S32 chiclet_left = getChiclet(0)->getRect().mLeft;
-
S32 size = getChicletCount();
for( int n = 0; n < size; ++n)
{
@@ -958,32 +776,52 @@ void LLChicletPanel::arrange()
chiclet_left += chiclet_width + getChicletPadding();
}
+
+ //reset size and pos on mScrollArea
+ LLRect rect = getRect();
+ LLRect scroll_button_rect = mLeftScrollButton->getRect();
+
+ bool need_show_scroll = needShowScroll();
+ if(need_show_scroll)
+ {
+ mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + mScrollButtonHPad,
+ rect.getHeight(), rect.getWidth() - scroll_button_rect.getWidth() - mScrollButtonHPad, 0));
+ }
+ else
+ {
+ mScrollArea->setRect(LLRect(0,rect.getHeight(), rect.getWidth(), 0));
+ }
+
+ trimChiclets();
+ showScrollButtonsIfNeeded();
}
void LLChicletPanel::trimChiclets()
{
// trim right
- if(canScrollLeft() && !canScrollRight())
+ if(!mChicletList.empty())
{
S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
+ S32 first_chiclet_left = getChiclet(0)->getRect().mLeft;
S32 scroll_width = mScrollArea->getRect().getWidth();
- if(last_chiclet_right < scroll_width)
+ if(last_chiclet_right < scroll_width || first_chiclet_left > 0)
{
shiftChiclets(scroll_width - last_chiclet_right);
}
}
+}
- // trim left
- if(!mChicletList.empty())
- {
- LLRect first_chiclet_rect = getChiclet(0)->getRect();
- if(first_chiclet_rect.mLeft > 0)
- {
- shiftChiclets( - first_chiclet_rect.mLeft);
- }
- }
+bool LLChicletPanel::needShowScroll()
+{
+ if(mChicletList.empty())
+ return false;
+
+ S32 chicklet_width = (*mChicletList.rbegin())->getRect().mRight - (*mChicletList.begin())->getRect().mLeft;
+
+ return chicklet_width>getRect().getWidth();
}
+
void LLChicletPanel::showScrollButtonsIfNeeded()
{
bool can_scroll_left = canScrollLeft();
@@ -1108,10 +946,26 @@ void LLChicletPanel::onRightScrollClick()
scrollRight();
}
+void LLChicletPanel::onLeftScrollHeldDown()
+{
+ S32 offset = mScrollingOffset;
+ mScrollingOffset = mScrollingOffset / mScrollRatio;
+ scrollLeft();
+ mScrollingOffset = offset;
+}
+
+void LLChicletPanel::onRightScrollHeldDown()
+{
+ S32 offset = mScrollingOffset;
+ mScrollingOffset = mScrollingOffset / mScrollRatio;
+ scrollRight();
+ mScrollingOffset = offset;
+}
+
boost::signals2::connection LLChicletPanel::setChicletClickedCallback(
const commit_callback_t& cb)
{
- return mCommitSignal.connect(cb);
+ return setCommitCallback(cb);
}
BOOL LLChicletPanel::handleScrollWheel(S32 x, S32 y, S32 clicks)
@@ -1133,7 +987,7 @@ bool LLChicletPanel::isAnyIMFloaterDoked()
for (chiclet_list_t::iterator it = mChicletList.begin(); it
!= mChicletList.end(); it++)
{
- LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>(
+ LLFloaterIMSession* im_floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>(
"impanel", (*it)->getSessionId());
if (im_floater != NULL && im_floater->getVisible()
&& !im_floater->isMinimized() && im_floater->isDocked())
@@ -1149,234 +1003,183 @@ bool LLChicletPanel::isAnyIMFloaterDoked()
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-
-// *TODO Vadim: Move this out of llchiclet.cpp.
-
-LLTalkButton::Params::Params()
- : speak_button("speak_button")
- , show_button("show_button")
- , monitor("monitor")
-{
- // *TODO Vadim: move hardcoded labels (!) and other params to XUI.
- 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);
- // Use default button art. JC
- //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");
- // *TODO: Make this data driven.
- monitor.rect(LLRect(0, 18, 18, 0));
-}
-
-LLTalkButton::LLTalkButton(const Params& p)
-: LLUICtrl(p)
-, mPrivateCallPanel(NULL)
-, mOutputMonitor(NULL)
-, mSpeakBtn(NULL)
-, mShowBtn(NULL)
+LLChicletNotificationCounterCtrl::Params::Params()
+ : max_displayed_count("max_displayed_count", 99)
{
- 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);
- LLTransientFloaterMgr::getInstance()->addControlView(mSpeakBtn);
-
- mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this));
- mSpeakBtn->setToggleState(FALSE);
-
- LLButton::Params show_params = p.show_button;
- show_params.rect(show_rect);
- mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
- addChild(mShowBtn);
- LLTransientFloaterMgr::getInstance()->addControlView(mShowBtn);
-
- mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this));
- mShowBtn->setToggleState(FALSE);
-
- static const S32 MONITOR_RIGHT_PAD = 2;
-
- 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);
- monitor_params.auto_update(true);
- monitor_params.speaker_id(gAgentID);
- mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params);
- mSpeakBtn->addChild(mOutputMonitor);
-
- // never show "muted" because you can't mute yourself
- mOutputMonitor->setIsMuted(false);
}
-LLTalkButton::~LLTalkButton()
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
+ : LLAvatarIconCtrl(p)
{
}
-void LLTalkButton::setSpeakBtnToggleState(bool state)
-{
- mSpeakBtn->setToggleState(state);
-}
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
-void LLTalkButton::onClick_SpeakBtn()
+LLChicletInvOfferIconCtrl::LLChicletInvOfferIconCtrl(const Params& p)
+: LLChicletAvatarIconCtrl(p)
+ , mDefaultIcon(p.default_icon)
{
- bool speaking = mSpeakBtn->getToggleState();
- gVoiceClient->setUserPTTState(speaking);
}
-void LLTalkButton::onClick_ShowBtn()
+void LLChicletInvOfferIconCtrl::setValue(const LLSD& value )
{
- if(!mShowBtn->getToggleState())
+ if(value.asUUID().isNull())
{
- mPrivateCallPanel->onClickClose(mPrivateCallPanel);
- delete mPrivateCallPanel;
- mPrivateCallPanel = NULL;
- mShowBtn->setToggleState(FALSE);
- return;
+ LLIconCtrl::setValue(mDefaultIcon);
}
+ else
+ {
+ LLChicletAvatarIconCtrl::setValue(value);
+ }
+}
- S32 x = mSpeakBtn->getRect().mLeft;
- S32 y = 0;
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
- localPointToScreen(x, y, &x, &y);
+LLScriptChiclet::Params::Params()
+ : icon("icon")
+ , chiclet_button("chiclet_button")
+ , new_message_icon("new_message_icon")
+{
+}
- mPrivateCallPanel = new LLVoiceControlPanel;
- getRootView()->addChild(mPrivateCallPanel);
+LLScriptChiclet::LLScriptChiclet(const Params&p)
+ : LLIMChiclet(p)
+ , mChicletIconCtrl(NULL)
+{
+ LLButton::Params button_params = p.chiclet_button;
+ mChicletButton = LLUICtrlFactory::create<LLButton>(button_params);
+ addChild(mChicletButton);
- y = LLBottomTray::getInstance()->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight();
+ LLIconCtrl::Params new_msg_params = p.new_message_icon;
+ mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params);
+ addChild(mNewMessagesIcon);
- LLRect rect;
- rect.setLeftTopAndSize(x, y, mPrivateCallPanel->getRect().getWidth(), mPrivateCallPanel->getRect().getHeight());
- mPrivateCallPanel->setRect(rect);
+ LLIconCtrl::Params icon_params = p.icon;
+ mChicletIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
+ addChild(mChicletIconCtrl);
+ sendChildToFront(mNewMessagesIcon);
+}
- LLAvatarListItem* item = new LLAvatarListItem();
- item->showStatus(true);
- item->showInfoBtn(true);
- item->showSpeakingIndicator(true);
- item->reshape(mPrivateCallPanel->getRect().getWidth(), item->getRect().getHeight(), FALSE);
+void LLScriptChiclet::setSessionId(const LLUUID& session_id)
+{
+ setShowNewMessagesIcon( getSessionId() != session_id );
- mPrivateCallPanel->addItem(item);
- mPrivateCallPanel->setVisible(TRUE);
- mPrivateCallPanel->setFrontmost(TRUE);
+ LLIMChiclet::setSessionId(session_id);
- mShowBtn->setToggleState(TRUE);
+ setToolTip(LLScriptFloaterManager::getObjectName(session_id));
}
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p)
- : LLTextBox(p)
- , mCounter(0)
- , mInitialWidth(0)
+void LLScriptChiclet::onMouseDown()
{
- mInitialWidth = getRect().getWidth();
+ LLScriptFloaterManager::getInstance()->toggleScriptFloater(getSessionId());
}
-void LLChicletNotificationCounterCtrl::setCounter(S32 counter)
+void LLScriptChiclet::onMenuItemClicked(const LLSD& user_data)
{
- mCounter = counter;
+ std::string action = user_data.asString();
- std::stringstream stream;
- stream << getCounter();
- if(mCounter != 0)
- {
- setText(stream.str());
- }
- else
+ if("end" == action)
{
- setText(std::string(""));
+ LLScriptFloaterManager::instance().removeNotification(getSessionId());
}
}
-LLRect LLChicletNotificationCounterCtrl::getRequiredRect()
+void LLScriptChiclet::createPopupMenu()
{
- LLRect rc;
- S32 text_width = getContentsRect().getWidth();
-
- rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth);
-
- return rc;
-}
+ if(!canCreateMenu())
+ return;
-void LLChicletNotificationCounterCtrl::setValue(const LLSD& value)
-{
- if(value.isInteger())
- setCounter(value.asInteger());
-}
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ registrar.add("ScriptChiclet.Action", boost::bind(&LLScriptChiclet::onMenuItemClicked, this, _2));
-LLSD LLChicletNotificationCounterCtrl::getValue() const
-{
- return LLSD(getCounter());
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
+ ("menu_script_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
- : LLAvatarIconCtrl(p)
+static const std::string INVENTORY_USER_OFFER ("UserGiveItem");
+
+LLInvOfferChiclet::Params::Params()
+ : icon("icon")
+ , chiclet_button("chiclet_button")
+ , new_message_icon("new_message_icon")
{
}
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLChicletGroupIconCtrl::LLChicletGroupIconCtrl(const Params& p)
-: LLIconCtrl(p)
-, mDefaultIcon(p.default_icon)
+LLInvOfferChiclet::LLInvOfferChiclet(const Params&p)
+ : LLIMChiclet(p)
+ , mChicletIconCtrl(NULL)
{
+ LLButton::Params button_params = p.chiclet_button;
+ mChicletButton = LLUICtrlFactory::create<LLButton>(button_params);
+ addChild(mChicletButton);
+
+ LLIconCtrl::Params new_msg_params = p.new_message_icon;
+ mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params);
+ addChild(mNewMessagesIcon);
+
+ LLChicletInvOfferIconCtrl::Params icon_params = p.icon;
+ mChicletIconCtrl = LLUICtrlFactory::create<LLChicletInvOfferIconCtrl>(icon_params);
+ addChild(mChicletIconCtrl);
+
+ sendChildToFront(mNewMessagesIcon);
}
-void LLChicletGroupIconCtrl::setValue(const LLSD& value )
+void LLInvOfferChiclet::setSessionId(const LLUUID& session_id)
{
- if(value.asUUID().isNull())
+ setShowNewMessagesIcon( getSessionId() != session_id );
+
+ setToolTip(LLScriptFloaterManager::getObjectName(session_id));
+
+ LLIMChiclet::setSessionId(session_id);
+ LLNotificationPtr notification = LLNotifications::getInstance()->find(session_id);
+
+ if ( notification && notification->getName() == INVENTORY_USER_OFFER )
{
- LLIconCtrl::setValue(mDefaultIcon);
+ mChicletIconCtrl->setValue(notification->getPayload()["from_id"]);
}
else
{
- LLIconCtrl::setValue(value);
+ mChicletIconCtrl->setValue(LLUUID::null);
}
}
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
+void LLInvOfferChiclet::onMouseDown()
+{
+ LLScriptFloaterManager::instance().toggleScriptFloater(getSessionId());
+}
+
+void LLInvOfferChiclet::onMenuItemClicked(const LLSD& user_data)
+{
+ std::string action = user_data.asString();
+
+ if("end" == action)
+ {
+ LLScriptFloaterManager::instance().removeNotification(getSessionId());
+ }
+}
-LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)
- : LLIconCtrl(p)
+void LLInvOfferChiclet::createPopupMenu()
{
+ if(!canCreateMenu())
+ return;
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ registrar.add("InvOfferChiclet.Action", boost::bind(&LLInvOfferChiclet::onMenuItemClicked, this, _2));
+
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
+ ("menu_inv_offer_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
}
+
+// EOF