merge https://svn.aws.productengine.com/secondlife/pe/stable-1/indra -r 1078-1091 -> viewer-2.0.0-3
parent
73a97010e6
commit
cef46d1645
|
|
@ -333,12 +333,13 @@ protected:
|
|||
open_signal_t mOpenSignal;
|
||||
close_signal_t mCloseSignal;
|
||||
LLSD mKey; // Key used for retrieving instances; set (for now) by LLFLoaterReg
|
||||
|
||||
private:
|
||||
LLRect mExpandedRect;
|
||||
|
||||
LLDragHandle* mDragHandle;
|
||||
LLResizeBar* mResizeBar[4];
|
||||
LLResizeHandle* mResizeHandle[4];
|
||||
|
||||
private:
|
||||
LLRect mExpandedRect;
|
||||
|
||||
LLUIString mTitle;
|
||||
LLUIString mShortTitle;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ include_directories(
|
|||
|
||||
set(viewer_SOURCE_FILES
|
||||
llaccordionctrltab.cpp
|
||||
llaccordionpanel.cpp
|
||||
llaccordionctrl.cpp
|
||||
llagent.cpp
|
||||
llagentaccess.cpp
|
||||
llagentdata.cpp
|
||||
|
|
@ -88,7 +88,9 @@ set(viewer_SOURCE_FILES
|
|||
llcallingcard.cpp
|
||||
llcapabilitylistener.cpp
|
||||
llcaphttpsender.cpp
|
||||
llchathistoryscroll.cpp
|
||||
llchannelmanager.cpp
|
||||
llchatitemscontainerctrl.cpp
|
||||
llchatmsgbox.cpp
|
||||
llchiclet.cpp
|
||||
llclassifiedinfo.cpp
|
||||
llclassifiedstatsresponder.cpp
|
||||
|
|
@ -104,7 +106,6 @@ set(viewer_SOURCE_FILES
|
|||
lldebugview.cpp
|
||||
lldelayedgestureerror.cpp
|
||||
lldirpicker.cpp
|
||||
lldraggerbar.cpp
|
||||
lldrawable.cpp
|
||||
lldrawpoolalpha.cpp
|
||||
lldrawpoolavatar.cpp
|
||||
|
|
@ -266,8 +267,13 @@ set(viewer_SOURCE_FILES
|
|||
llnameeditor.cpp
|
||||
llnamelistctrl.cpp
|
||||
llnavigationbar.cpp
|
||||
llnearbychathistory.cpp
|
||||
llnearbychat.cpp
|
||||
llnearbychathandler.cpp
|
||||
llnetmap.cpp
|
||||
llnotificationalerthandler.cpp
|
||||
llnotificationgrouphandler.cpp
|
||||
llnotificationinfohandler.cpp
|
||||
llnotificationmanager.cpp
|
||||
llnotify.cpp
|
||||
lloutputmonitorctrl.cpp
|
||||
lloverlaybar.cpp
|
||||
|
|
@ -329,6 +335,7 @@ set(viewer_SOURCE_FILES
|
|||
llregionposition.cpp
|
||||
llremoteparcelrequest.cpp
|
||||
llsavedsettingsglue.cpp
|
||||
llscreenchannel.cpp
|
||||
llselectmgr.cpp
|
||||
llsidetray.cpp
|
||||
llsky.cpp
|
||||
|
|
@ -349,6 +356,11 @@ set(viewer_SOURCE_FILES
|
|||
lltexturectrl.cpp
|
||||
lltexturefetch.cpp
|
||||
lltextureview.cpp
|
||||
lltoast.cpp
|
||||
lltoastalertpanel.cpp
|
||||
lltoastgroupnotifypanel.cpp
|
||||
lltoastnotifypanel.cpp
|
||||
lltoastpanel.cpp
|
||||
lltoggleablemenu.cpp
|
||||
lltoolbar.cpp
|
||||
lltoolbrush.cpp
|
||||
|
|
@ -484,7 +496,7 @@ set(viewer_HEADER_FILES
|
|||
CMakeLists.txt
|
||||
ViewerInstall.cmake
|
||||
llaccordionctrltab.h
|
||||
llaccordionpanel.h
|
||||
llaccordionctrl.h
|
||||
llagent.h
|
||||
llagentaccess.h
|
||||
llagentdata.h
|
||||
|
|
@ -510,7 +522,9 @@ set(viewer_HEADER_FILES
|
|||
llcapabilitylistener.h
|
||||
llcapabilityprovider.h
|
||||
llcaphttpsender.h
|
||||
llchathistoryscroll.h
|
||||
llchannelmanager.h
|
||||
llchatitemscontainerctrl.h
|
||||
llchatmsgbox.h
|
||||
llchiclet.h
|
||||
llclassifiedinfo.h
|
||||
llclassifiedstatsresponder.h
|
||||
|
|
@ -526,7 +540,6 @@ set(viewer_HEADER_FILES
|
|||
lldebugview.h
|
||||
lldelayedgestureerror.h
|
||||
lldirpicker.h
|
||||
lldraggerbar.h
|
||||
lldrawable.h
|
||||
lldrawpool.h
|
||||
lldrawpoolalpha.h
|
||||
|
|
@ -690,8 +703,11 @@ set(viewer_HEADER_FILES
|
|||
llnameeditor.h
|
||||
llnamelistctrl.h
|
||||
llnavigationbar.h
|
||||
llnearbychathistory.h
|
||||
llnearbychat.h
|
||||
llnearbychathandler.h
|
||||
llnetmap.h
|
||||
llnotificationhandler.h
|
||||
llnotificationmanager.h
|
||||
llnotify.h
|
||||
lloutputmonitorctrl.h
|
||||
lloverlaybar.h
|
||||
|
|
@ -754,6 +770,7 @@ set(viewer_HEADER_FILES
|
|||
llremoteparcelrequest.h
|
||||
llresourcedata.h
|
||||
llrootview.h
|
||||
llscreenchannel.h
|
||||
llsavedsettingsglue.h
|
||||
llselectmgr.h
|
||||
llsidetray.h
|
||||
|
|
@ -776,6 +793,11 @@ set(viewer_HEADER_FILES
|
|||
lltexturectrl.h
|
||||
lltexturefetch.h
|
||||
lltextureview.h
|
||||
lltoast.h
|
||||
lltoastalertpanel.h
|
||||
lltoastgroupnotifypanel.h
|
||||
lltoastnotifypanel.h
|
||||
lltoastpanel.h
|
||||
lltoggleablemenu.h
|
||||
lltool.h
|
||||
lltoolbar.h
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
#include "llselectmgr.h"
|
||||
#include "llvoavatarself.h"
|
||||
|
||||
S32 LLBottomTray::mLastSpecialChatChannel = 0;
|
||||
S32 LLBottomTray::sLastSpecialChatChannel = 0;
|
||||
|
||||
// legacy calllback glue
|
||||
void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
|
||||
|
|
@ -412,16 +412,6 @@ void LLBottomTray::refreshStandUp()
|
|||
moveChildToBackOfTabGroup(mStandUpBtn);
|
||||
}
|
||||
}
|
||||
void LLBottomTray::updateRightPosition(const S32 new_right_position)
|
||||
{
|
||||
LLRect rc = getRect();
|
||||
if (new_right_position != rc.mRight)
|
||||
{
|
||||
rc.mRight = new_right_position;
|
||||
reshape(rc.getWidth(), rc.getHeight(), FALSE);
|
||||
setRect(rc);
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME: temporary, for stand up proto
|
||||
void LLBottomTray::onCommitStandUp(LLUICtrl* ctrl)
|
||||
|
|
@ -624,7 +614,7 @@ LLWString LLBottomTray::stripChannelNumber(const LLWString &mesg, S32* channel)
|
|||
&& mesg[1] == '/')
|
||||
{
|
||||
// This is a "repeat channel send"
|
||||
*channel = mLastSpecialChatChannel;
|
||||
*channel = sLastSpecialChatChannel;
|
||||
return mesg.substr(2, mesg.length() - 2);
|
||||
}
|
||||
else if (mesg[0] == '/'
|
||||
|
|
@ -654,8 +644,8 @@ LLWString LLBottomTray::stripChannelNumber(const LLWString &mesg, S32* channel)
|
|||
pos++;
|
||||
}
|
||||
|
||||
mLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
|
||||
*channel = mLastSpecialChatChannel;
|
||||
sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
|
||||
*channel = sLastSpecialChatChannel;
|
||||
return mesg.substr(pos, mesg.length() - pos);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@ public:
|
|||
|
||||
/*virtual*/void draw();
|
||||
void refreshStandUp();
|
||||
void updateRightPosition(const S32 new_right_position);
|
||||
|
||||
void onCommitGesture(LLUICtrl* ctrl);
|
||||
void onCommitStandUp(LLUICtrl* ctrl);
|
||||
|
|
@ -118,7 +117,7 @@ protected:
|
|||
void setChicletPanelVisible(bool visible);
|
||||
|
||||
// Which non-zero channel did we last chat on?
|
||||
static S32 mLastSpecialChatChannel;
|
||||
static S32 sLastSpecialChatChannel;
|
||||
|
||||
LLLineEditor* mChatBox;
|
||||
LLChicletPanel* mChicletPanel;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
/**
|
||||
* @file llchannelmanager.cpp
|
||||
* @brief This class rules screen notification channels.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-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$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h" // must be first include
|
||||
|
||||
#include "llchannelmanager.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace LLNotificationsUI;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLChannelManager::LLChannelManager()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLChannelManager::~LLChannelManager()
|
||||
{
|
||||
//All channels are being deleted by Parent View
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)
|
||||
{
|
||||
LLScreenChannel* new_channel = NULL;
|
||||
|
||||
if(!p.chiclet)
|
||||
{
|
||||
new_channel = getChannelByID(p.id);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_channel = getChannelByChiclet(p.chiclet);
|
||||
}
|
||||
|
||||
if(new_channel)
|
||||
return new_channel;
|
||||
|
||||
new_channel = new LLScreenChannel();
|
||||
new_channel->init(p.channel_right_bound - p.channel_width, getRootView());
|
||||
new_channel->setToastAlignment(p.align);
|
||||
|
||||
ChannelElem new_elem;
|
||||
new_elem.id = p.id;
|
||||
new_elem.chiclet = p.chiclet;
|
||||
new_elem.channel = new_channel;
|
||||
|
||||
mChannelList.push_back(new_elem); //TODO: remove chiclet from ScreenChannel?
|
||||
|
||||
return new_channel;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLScreenChannel* LLChannelManager::getChannelByID(const LLUUID id)
|
||||
{
|
||||
std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
|
||||
if(it != mChannelList.end())
|
||||
{
|
||||
return (*it).channel;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLScreenChannel* LLChannelManager::getChannelByChiclet(const LLChiclet* chiclet)
|
||||
{
|
||||
std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), chiclet);
|
||||
if(it != mChannelList.end())
|
||||
{
|
||||
return (*it).channel;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLChannelManager::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it != mChannelList.end(); ++it)
|
||||
{
|
||||
if((*it).channel->getToastAlignment() == NA_CENTRE)
|
||||
{
|
||||
LLRect channel_rect = (*it).channel->getRect();
|
||||
S32 screen_width = getRootView()->getRect().getWidth();
|
||||
channel_rect.setLeftTopAndSize(screen_width/2, channel_rect.mTop, channel_rect.getWidth(), channel_rect.getHeight());
|
||||
(*it).channel->setRect(channel_rect);
|
||||
(*it).channel->showToasts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/**
|
||||
* @file llchannelmanager.h
|
||||
* @brief This class rules screen notification channels.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2003-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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLCHANNELMANAGER_H
|
||||
#define LL_LLCHANNELMANAGER_H
|
||||
|
||||
|
||||
#include "llchiclet.h"
|
||||
#include "llscreenchannel.h"
|
||||
|
||||
#include "lluuid.h"
|
||||
|
||||
#include <map>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace LLNotificationsUI
|
||||
{
|
||||
|
||||
/**
|
||||
* Manager for screen channels.
|
||||
* Responsible for instantiating and retrieving screen channels.
|
||||
*/
|
||||
class LLChannelManager : public LLUICtrl, public LLSingleton<LLChannelManager>
|
||||
{
|
||||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
|
||||
{
|
||||
Optional<LLUUID> id;
|
||||
Optional<LLChiclet*> chiclet;
|
||||
Optional<S32> channel_right_bound;
|
||||
Optional<S32> channel_width;
|
||||
Optional<EToastAlignment> align;
|
||||
|
||||
Params(): id("id", LLUUID("")),
|
||||
chiclet("chiclet", NULL),
|
||||
channel_right_bound("channel_right_bound", 0),
|
||||
channel_width("channel_width", 0),
|
||||
align("align", NA_BOTTOM)
|
||||
{}
|
||||
};
|
||||
|
||||
struct ChannelElem
|
||||
{
|
||||
LLUUID id;
|
||||
LLChiclet* chiclet;
|
||||
LLScreenChannel* channel;
|
||||
|
||||
ChannelElem() : id(LLUUID("")), chiclet(NULL), channel(NULL) { }
|
||||
|
||||
ChannelElem(const ChannelElem &elem)
|
||||
{
|
||||
id = elem.id;
|
||||
chiclet = elem.chiclet;
|
||||
channel = elem.channel;
|
||||
}
|
||||
|
||||
bool operator == (const LLUUID &id_op) const
|
||||
{
|
||||
return (id == id_op);
|
||||
}
|
||||
|
||||
bool operator == (const LLChiclet* chiclet_op) const
|
||||
{
|
||||
return (chiclet == chiclet_op);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LLChannelManager();
|
||||
virtual ~LLChannelManager();
|
||||
|
||||
//TODO: make protected? in order to be shure that channels are created only by notification handlers
|
||||
LLScreenChannel* createChannel(LLChannelManager::Params& p);
|
||||
|
||||
LLScreenChannel* getChannelByID(const LLUUID id);
|
||||
LLScreenChannel* getChannelByChiclet(const LLChiclet* chiclet);
|
||||
|
||||
void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
||||
private:
|
||||
|
||||
std::vector<ChannelElem> mChannelList;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,525 @@
|
|||
/**
|
||||
* @file llchatitemscontainer.cpp
|
||||
* @brief chat history scrolling panel implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 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$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llchatitemscontainerctrl.h"
|
||||
#include "lltextbox.h"
|
||||
|
||||
#include "llchatmsgbox.h"
|
||||
#include "llavatariconctrl.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
static const S32 BORDER_MARGIN = 2;
|
||||
static const S32 PARENT_BORDER_MARGIN = 0;
|
||||
|
||||
static const S32 HORIZONTAL_MULTIPLE = 8;
|
||||
static const S32 VERTICAL_MULTIPLE = 16;
|
||||
static const F32 MIN_AUTO_SCROLL_RATE = 120.f;
|
||||
static const F32 MAX_AUTO_SCROLL_RATE = 500.f;
|
||||
static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
|
||||
|
||||
#define MAX_CHAT_HISTORY 100
|
||||
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl> t2("chat_items_container");
|
||||
|
||||
|
||||
|
||||
//*******************************************************************************************************************
|
||||
//LLChatItemCtrl
|
||||
//*******************************************************************************************************************
|
||||
|
||||
LLChatItemCtrl* LLChatItemCtrl::createInstance()
|
||||
{
|
||||
LLChatItemCtrl* item = new LLChatItemCtrl();
|
||||
LLUICtrlFactory::getInstance()->buildPanel(item, "panel_chat_item.xml");
|
||||
return item;
|
||||
}
|
||||
|
||||
void LLChatItemCtrl::draw()
|
||||
{
|
||||
LLPanel::draw();
|
||||
}
|
||||
|
||||
void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
|
||||
{
|
||||
LLPanel::reshape(width, height,called_from_parent);
|
||||
|
||||
LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);
|
||||
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text",false,false);
|
||||
if(caption && msg_text)
|
||||
{
|
||||
LLRect caption_rect = caption->getRect();
|
||||
caption_rect.setLeftTopAndSize( 2, height, width - 4, caption_rect.getHeight());
|
||||
caption->reshape( width - 4, caption_rect.getHeight(), 1);
|
||||
caption->setRect(caption_rect);
|
||||
|
||||
|
||||
LLRect msg_text_rect = msg_text->getRect();
|
||||
msg_text_rect.setLeftTopAndSize( 10, height - caption_rect.getHeight() , width - 20, height - caption_rect.getHeight());
|
||||
msg_text->reshape( width - 20, height - caption_rect.getHeight(), 1);
|
||||
msg_text->setRect(msg_text_rect);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL LLChatItemCtrl::postBuild()
|
||||
{
|
||||
return LLPanel::postBuild();
|
||||
}
|
||||
|
||||
|
||||
std::string LLChatItemCtrl::appendTime()
|
||||
{
|
||||
time_t utc_time;
|
||||
utc_time = time_corrected();
|
||||
std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
|
||||
+LLTrans::getString("TimeMin")+"] ";
|
||||
|
||||
LLSD substitution;
|
||||
|
||||
substitution["datetime"] = (S32) utc_time;
|
||||
LLStringUtil::format (timeStr, substitution);
|
||||
|
||||
return timeStr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLChatItemCtrl::addText (const std::string& message)
|
||||
{
|
||||
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text",false,false);
|
||||
if(msg_text)
|
||||
msg_text->addText(message);
|
||||
mMessages.push_back(message);
|
||||
}
|
||||
|
||||
void LLChatItemCtrl::setMessage (const LLChat& msg)
|
||||
{
|
||||
LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);
|
||||
if(!caption)
|
||||
return;
|
||||
caption->getChild<LLTextBox>("sender_name",false,false)->setText(msg.mFromName);
|
||||
std::string tt = appendTime();
|
||||
|
||||
caption->getChild<LLTextBox>("msg_time",false,false)->setText(tt);
|
||||
|
||||
caption->getChild<LLAvatarIconCtrl>("avatar_icon",false,false)->setValue(msg.mFromID);
|
||||
|
||||
mOriginalMessage = msg;
|
||||
|
||||
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text",false,false);
|
||||
if(msg_text)
|
||||
msg_text->setText(msg.mText);
|
||||
|
||||
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
|
||||
if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
|
||||
msg_inspector->setVisible(false);
|
||||
|
||||
mMessages.clear();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LLChatItemCtrl::setWidth(S32 width)
|
||||
{
|
||||
LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text",false,false);
|
||||
if(!text_box)
|
||||
return;///actually assert fits better
|
||||
|
||||
text_box->reshape(width - 20,100/*its not magic number, we just need any number*/);
|
||||
|
||||
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text",false,false);
|
||||
if(msg_text && mOriginalMessage.mText.length())
|
||||
msg_text->setText(mOriginalMessage.mText);
|
||||
|
||||
for(size_t i=0;i<mMessages.size();++i)
|
||||
msg_text->addText(mMessages[i]);
|
||||
|
||||
S32 new_height = text_box->getTextPixelHeight();
|
||||
LLRect panel_rect = getRect();
|
||||
panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, width , 35 + new_height);
|
||||
|
||||
reshape( width, panel_rect.getHeight(), 1);
|
||||
|
||||
setRect(panel_rect);
|
||||
}
|
||||
|
||||
void LLChatItemCtrl::onMouseLeave (S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);
|
||||
if(!caption)
|
||||
return;
|
||||
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
|
||||
if(msg_inspector)
|
||||
msg_inspector->setVisible(false);
|
||||
|
||||
}
|
||||
void LLChatItemCtrl::onMouseEnter (S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);
|
||||
if(!caption)
|
||||
return;
|
||||
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
|
||||
if(msg_inspector)
|
||||
msg_inspector->setVisible(true);
|
||||
}
|
||||
|
||||
BOOL LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);
|
||||
if(mOriginalMessage.mSourceType == CHAT_SOURCE_AGENT && caption)
|
||||
{
|
||||
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
|
||||
if(msg_inspector)
|
||||
{
|
||||
S32 local_x = x - msg_inspector->getRect().mLeft - caption->getRect().mLeft;
|
||||
S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom;
|
||||
if(msg_inspector->pointInView(local_x, local_y))
|
||||
{
|
||||
LLFloaterReg::showInstance("mini_inspector", mOriginalMessage.mFromID);
|
||||
}
|
||||
}
|
||||
}
|
||||
return LLPanel::handleMouseDown(x,y,mask);
|
||||
}
|
||||
|
||||
void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
|
||||
{
|
||||
LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);
|
||||
if(!caption)
|
||||
return;
|
||||
|
||||
LLUICtrl* icon = caption->getChild<LLUICtrl>("avatar_icon",false,false);
|
||||
LLUICtrl* name = caption->getChild<LLUICtrl>("sender_name",false,false);
|
||||
|
||||
if(icon == 0 || name == 0)
|
||||
return;
|
||||
|
||||
icon->setVisible(e == CHATITEMHEADER_SHOW_ONLY_ICON || e==CHATITEMHEADER_SHOW_BOTH);
|
||||
name->setVisible(e == CHATITEMHEADER_SHOW_ONLY_NAME || e==CHATITEMHEADER_SHOW_BOTH);
|
||||
|
||||
}
|
||||
|
||||
bool LLChatItemCtrl::canAddText ()
|
||||
{
|
||||
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text",false,false);
|
||||
if(!msg_text )
|
||||
return false;
|
||||
return msg_text->getTextLinesNum()<10;
|
||||
}
|
||||
|
||||
|
||||
//*******************************************************************************************************************
|
||||
//LLChatItemsContainerCtrl
|
||||
//*******************************************************************************************************************
|
||||
|
||||
LLChatItemsContainerCtrl::LLChatItemsContainerCtrl(const Params& params):LLPanel(params)
|
||||
{
|
||||
mEShowItemHeader = CHATITEMHEADER_SHOW_BOTH;
|
||||
}
|
||||
|
||||
|
||||
void LLChatItemsContainerCtrl::addMessage(const LLChat& msg)
|
||||
{
|
||||
/*
|
||||
if(msg.mChatType == CHAT_TYPE_DEBUG_MSG)
|
||||
return;
|
||||
*/
|
||||
if(mItems.size() >= MAX_CHAT_HISTORY)
|
||||
{
|
||||
LLChatItemCtrl* item = mItems[0];
|
||||
removeChild(item);
|
||||
delete item;
|
||||
}
|
||||
|
||||
|
||||
if(mItems.size() > 0 && msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID && mItems[mItems.size()-1]->canAddText())
|
||||
{
|
||||
mItems[mItems.size()-1]->addText(msg.mText);
|
||||
mItems[mItems.size()-1]->setWidth(getRect().getWidth() - 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
|
||||
mItems.push_back(item);
|
||||
addChild(item,0);
|
||||
item->setWidth(getRect().getWidth() - 16);
|
||||
item->setMessage(msg);
|
||||
item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
|
||||
|
||||
item->setVisible(true);
|
||||
}
|
||||
|
||||
arrange(getRect().getWidth(),getRect().getHeight());
|
||||
updateLayout(getRect().getWidth(),getRect().getHeight());
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
void LLChatItemsContainerCtrl::scrollToBottom ()
|
||||
{
|
||||
if(mScrollbar->getVisible())
|
||||
{
|
||||
mScrollbar->setDocPos(mScrollbar->getDocPosMax());
|
||||
onScrollPosChangeCallback(0,0);
|
||||
}
|
||||
}
|
||||
|
||||
void LLChatItemsContainerCtrl::draw()
|
||||
{
|
||||
LLLocalClipRect clip(getRect());
|
||||
LLPanel::draw();
|
||||
}
|
||||
|
||||
void LLChatItemsContainerCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
|
||||
{
|
||||
S32 delta_width = width - getRect().getWidth();
|
||||
S32 delta_height = height - getRect().getHeight();
|
||||
|
||||
if (delta_width || delta_height || sForceReshape)
|
||||
{
|
||||
arrange(width, height);
|
||||
}
|
||||
|
||||
updateBoundingRect();
|
||||
}
|
||||
|
||||
void LLChatItemsContainerCtrl::arrange (S32 width, S32 height)
|
||||
{
|
||||
S32 delta_width = width - getRect().getWidth();
|
||||
if(delta_width)//width changed...too bad. now we need to reformat all items
|
||||
reformatHistoryScrollItems(width);
|
||||
|
||||
calcRecuiredHeight();
|
||||
|
||||
show_hide_scrollbar(width,height);
|
||||
|
||||
updateLayout(width,height);
|
||||
}
|
||||
|
||||
void LLChatItemsContainerCtrl::reformatHistoryScrollItems(S32 width)
|
||||
{
|
||||
for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
|
||||
{
|
||||
(*it)->setWidth(width);
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLChatItemsContainerCtrl::calcRecuiredHeight ()
|
||||
{
|
||||
S32 rec_height = 0;
|
||||
|
||||
std::vector<LLChatItemCtrl*>::iterator it;
|
||||
for(it=mItems.begin(); it!=mItems.end(); ++it)
|
||||
{
|
||||
rec_height += (*it)->getRect().getHeight();
|
||||
}
|
||||
|
||||
mInnerRect.setLeftTopAndSize(0,rec_height + BORDER_MARGIN*2,getRect().getWidth(),rec_height + BORDER_MARGIN);
|
||||
|
||||
return mInnerRect.getHeight();
|
||||
}
|
||||
|
||||
|
||||
void LLChatItemsContainerCtrl::updateLayout (S32 width, S32 height)
|
||||
{
|
||||
S32 panel_top = height - BORDER_MARGIN ;
|
||||
S32 panel_width = width;
|
||||
if(mScrollbar->getVisible())
|
||||
{
|
||||
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
|
||||
|
||||
panel_top+=mScrollbar->getDocPos();
|
||||
panel_width-=scrollbar_size;
|
||||
}
|
||||
|
||||
|
||||
//set sizes for first pannels and dragbars
|
||||
for(size_t i=0;i<mItems.size();++i)
|
||||
{
|
||||
LLRect panel_rect = mItems[i]->getRect();
|
||||
panelSetLeftTopAndSize(mItems[i],panel_rect.mLeft,panel_top,panel_width,panel_rect.getHeight());
|
||||
panel_top-=panel_rect.getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
void LLChatItemsContainerCtrl::show_hide_scrollbar (S32 width, S32 height)
|
||||
{
|
||||
calcRecuiredHeight();
|
||||
if(getRecuiredHeight() > height )
|
||||
showScrollbar(width, height);
|
||||
else
|
||||
hideScrollbar(width, height);
|
||||
}
|
||||
|
||||
void LLChatItemsContainerCtrl::showScrollbar (S32 width, S32 height)
|
||||
{
|
||||
bool was_visible = mScrollbar->getVisible();
|
||||
|
||||
mScrollbar->setVisible(true);
|
||||
|
||||
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
|
||||
|
||||
panelSetLeftTopAndSize(mScrollbar,width-scrollbar_size
|
||||
,height-PARENT_BORDER_MARGIN,scrollbar_size,height-2*PARENT_BORDER_MARGIN);
|
||||
|
||||
mScrollbar->setPageSize(height);
|
||||
mScrollbar->setDocParams(mInnerRect.getHeight(),mScrollbar->getDocPos());
|
||||
|
||||
if(was_visible)
|
||||
{
|
||||
S32 scroll_pos = llmin(mScrollbar->getDocPos(), getRecuiredHeight() - height - 1);
|
||||
mScrollbar->setDocPos(scroll_pos);
|
||||
updateLayout(width,height);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void LLChatItemsContainerCtrl::hideScrollbar (S32 width, S32 height)
|
||||
{
|
||||
if(mScrollbar->getVisible() == false)
|
||||
return;
|
||||
mScrollbar->setVisible(false);
|
||||
|
||||
mScrollbar->setDocPos(0);
|
||||
|
||||
if(mItems.size()>0)
|
||||
{
|
||||
S32 panel_top = height - BORDER_MARGIN; // Top coordinate of the first panel
|
||||
S32 diff = panel_top - mItems[0]->getRect().mTop;
|
||||
shiftPanels(diff);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void LLChatItemsContainerCtrl::panelSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S32 width, S32 height)
|
||||
{
|
||||
if(!panel)
|
||||
return;
|
||||
LLRect panel_rect = panel->getRect();
|
||||
panel_rect.setLeftTopAndSize( left, top, width, height);
|
||||
panel->reshape( width, height, 1);
|
||||
panel->setRect(panel_rect);
|
||||
}
|
||||
|
||||
void LLChatItemsContainerCtrl::panelShiftVertical(LLView* panel,S32 delta)
|
||||
{
|
||||
if(!panel)
|
||||
return;
|
||||
panel->translate(0,delta);
|
||||
}
|
||||
|
||||
void LLChatItemsContainerCtrl::shiftPanels(S32 delta)
|
||||
{
|
||||
//Arrange panels
|
||||
for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
|
||||
{
|
||||
panelShiftVertical((*it),delta);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
void LLChatItemsContainerCtrl::onScrollPosChangeCallback(S32, LLScrollbar*)
|
||||
{
|
||||
updateLayout(getRect().getWidth(),getRect().getHeight());
|
||||
}
|
||||
|
||||
BOOL LLChatItemsContainerCtrl::postBuild()
|
||||
{
|
||||
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
|
||||
|
||||
LLRect scroll_rect;
|
||||
scroll_rect.setOriginAndSize(
|
||||
getRect().getWidth() - scrollbar_size,
|
||||
1,
|
||||
scrollbar_size,
|
||||
getRect().getHeight() - 1);
|
||||
|
||||
|
||||
LLScrollbar::Params sbparams;
|
||||
sbparams.name("scrollable vertical");
|
||||
sbparams.rect(scroll_rect);
|
||||
sbparams.orientation(LLScrollbar::VERTICAL);
|
||||
sbparams.doc_size(mInnerRect.getHeight());
|
||||
sbparams.doc_pos(0);
|
||||
sbparams.page_size(mInnerRect.getHeight());
|
||||
sbparams.step_size(VERTICAL_MULTIPLE);
|
||||
sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
|
||||
sbparams.change_callback(boost::bind(&LLChatItemsContainerCtrl::onScrollPosChangeCallback, this, _1, _2));
|
||||
|
||||
mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams);
|
||||
LLView::addChild( mScrollbar );
|
||||
mScrollbar->setVisible( true );
|
||||
mScrollbar->setFollowsRight();
|
||||
mScrollbar->setFollowsTop();
|
||||
mScrollbar->setFollowsBottom();
|
||||
|
||||
reformatHistoryScrollItems(getRect().getWidth());
|
||||
arrange(getRect().getWidth(),getRect().getHeight());
|
||||
|
||||
return LLPanel::postBuild();
|
||||
}
|
||||
BOOL LLChatItemsContainerCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
|
||||
{
|
||||
return LLPanel::handleMouseDown(x,y,mask);
|
||||
}
|
||||
BOOL LLChatItemsContainerCtrl::handleKeyHere (KEY key, MASK mask)
|
||||
{
|
||||
if( mScrollbar->getVisible() && mScrollbar->handleKeyHere( key,mask ) )
|
||||
return TRUE;
|
||||
return LLPanel::handleKeyHere(key,mask);
|
||||
}
|
||||
BOOL LLChatItemsContainerCtrl::handleScrollWheel ( S32 x, S32 y, S32 clicks )
|
||||
{
|
||||
if( mScrollbar->getVisible() && mScrollbar->handleScrollWheel( 0, 0, clicks ) )
|
||||
return TRUE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLChatItemsContainerCtrl::setHeaderVisibility(EShowItemHeader e)
|
||||
{
|
||||
if(e == mEShowItemHeader)
|
||||
return;
|
||||
mEShowItemHeader = e;
|
||||
for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
|
||||
{
|
||||
(*it)->setHeaderVisibility(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
/**
|
||||
* @file llchatitemscontainer.h
|
||||
* @brief chat history scrolling panel implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLCHATITEMSCONTAINER_H_
|
||||
#define LL_LLCHATITEMSCONTAINER_H_
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llscrollbar.h"
|
||||
#include "string"
|
||||
#include "llchat.h"
|
||||
|
||||
typedef enum e_show_item_header
|
||||
{
|
||||
CHATITEMHEADER_SHOW_ONLY_NAME = 0,
|
||||
CHATITEMHEADER_SHOW_ONLY_ICON = 1,
|
||||
CHATITEMHEADER_SHOW_BOTH
|
||||
} EShowItemHeader;
|
||||
|
||||
class LLChatItemCtrl: public LLPanel
|
||||
{
|
||||
protected:
|
||||
LLChatItemCtrl(){};
|
||||
public:
|
||||
|
||||
|
||||
~LLChatItemCtrl(){}
|
||||
|
||||
static LLChatItemCtrl* createInstance();
|
||||
|
||||
void draw();
|
||||
|
||||
const LLChat& getMessage() const { return mOriginalMessage;}
|
||||
|
||||
void addText (const std::string& message);
|
||||
void setMessage (const LLChat& msg);
|
||||
void setWidth (S32 width);
|
||||
|
||||
bool canAddText ();
|
||||
|
||||
void onMouseLeave (S32 x, S32 y, MASK mask);
|
||||
void onMouseEnter (S32 x, S32 y, MASK mask);
|
||||
BOOL handleMouseDown (S32 x, S32 y, MASK mask);
|
||||
|
||||
virtual BOOL postBuild();
|
||||
|
||||
void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
||||
void setHeaderVisibility(EShowItemHeader e);
|
||||
private:
|
||||
|
||||
std::string appendTime ();
|
||||
|
||||
private:
|
||||
LLChat mOriginalMessage;
|
||||
|
||||
std::vector<std::string> mMessages;
|
||||
};
|
||||
|
||||
class LLChatItemsContainerCtrl: public LLPanel
|
||||
{
|
||||
public:
|
||||
struct Params
|
||||
: public LLInitParam::Block<Params, LLPanel::Params>
|
||||
{
|
||||
Params(){};
|
||||
};
|
||||
|
||||
LLChatItemsContainerCtrl(const Params& params);
|
||||
|
||||
|
||||
~LLChatItemsContainerCtrl(){}
|
||||
|
||||
void addMessage (const LLChat& msg);
|
||||
|
||||
void draw();
|
||||
|
||||
void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
||||
void onScrollPosChangeCallback(S32, LLScrollbar*);
|
||||
|
||||
virtual BOOL postBuild();
|
||||
|
||||
BOOL handleMouseDown (S32 x, S32 y, MASK mask);
|
||||
BOOL handleKeyHere (KEY key, MASK mask);
|
||||
BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
|
||||
|
||||
void scrollToBottom ();
|
||||
|
||||
void setHeaderVisibility(EShowItemHeader e);
|
||||
EShowItemHeader getHeaderVisibility() const { return mEShowItemHeader;};
|
||||
|
||||
|
||||
private:
|
||||
void reformatHistoryScrollItems(S32 width);
|
||||
void arrange (S32 width, S32 height);
|
||||
|
||||
S32 calcRecuiredHeight ();
|
||||
S32 getRecuiredHeight () const { return mInnerRect.getHeight(); }
|
||||
|
||||
void updateLayout (S32 width, S32 height);
|
||||
|
||||
void show_hide_scrollbar (S32 width, S32 height);
|
||||
|
||||
void showScrollbar (S32 width, S32 height);
|
||||
void hideScrollbar (S32 width, S32 height);
|
||||
|
||||
void panelSetLeftTopAndSize (LLView* panel, S32 left, S32 top, S32 width, S32 height);
|
||||
void panelShiftVertical (LLView* panel,S32 delta);
|
||||
void shiftPanels (S32 delta);
|
||||
|
||||
private:
|
||||
std::vector<LLChatItemCtrl*> mItems;
|
||||
|
||||
EShowItemHeader mEShowItemHeader;
|
||||
|
||||
LLRect mInnerRect;
|
||||
LLScrollbar* mScrollbar;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,390 @@
|
|||
/**
|
||||
* @file llchatmsgbox.cpp
|
||||
* @brief chat history text box, able to show array of strings with separator
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-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$
|
||||
*/
|
||||
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llchatmsgbox.h"
|
||||
#include "llwindow.h"
|
||||
#include "llfocusmgr.h"
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLChatMsgBox> r("text_chat");
|
||||
|
||||
LLChatMsgBox::Params::Params()
|
||||
: text_color("text_color"),
|
||||
highlight_on_hover("hover", false),
|
||||
border_visible("border_visible", false),
|
||||
border_drop_shadow_visible("border_drop_shadow_visible", false),
|
||||
bg_visible("bg_visible", false),
|
||||
use_ellipses("use_ellipses"),
|
||||
word_wrap("word_wrap", false),
|
||||
hover_color("hover_color"),
|
||||
disabled_color("disabled_color"),
|
||||
background_color("background_color"),
|
||||
border_color("border_color"),
|
||||
v_pad("v_pad", 0),
|
||||
h_pad("h_pad", 0),
|
||||
line_spacing("line_spacing", 0),
|
||||
text("text"),
|
||||
font_shadow("font_shadow", LLFontGL::NO_SHADOW)
|
||||
{}
|
||||
|
||||
LLChatMsgBox::LLChatMsgBox(const LLChatMsgBox::Params& p)
|
||||
: LLUICtrl(p),
|
||||
mFontGL(p.font),
|
||||
mHoverActive( p.highlight_on_hover ),
|
||||
mHasHover( FALSE ),
|
||||
mBackgroundVisible( p.bg_visible ),
|
||||
mBorderVisible( p.border_visible ),
|
||||
mShadowType( p.font_shadow ),
|
||||
mBorderDropShadowVisible( p.border_drop_shadow_visible ),
|
||||
mUseEllipses( p.use_ellipses ),
|
||||
mHPad(p.h_pad),
|
||||
mVPad(p.v_pad),
|
||||
mVAlign( LLFontGL::TOP ),
|
||||
mClickedCallback(NULL),
|
||||
mTextColor(p.text_color()),
|
||||
mDisabledColor(p.disabled_color()),
|
||||
mBackgroundColor(p.background_color()),
|
||||
mBorderColor(p.border_color()),
|
||||
mHoverColor(p.hover_color()),
|
||||
mHAlign(p.font_halign),
|
||||
mLineSpacing(p.line_spacing),
|
||||
mWordWrap( p.word_wrap ),
|
||||
mFontStyle(LLFontGL::getStyleFromString(p.font.style))
|
||||
{
|
||||
setText( p.text() );
|
||||
}
|
||||
|
||||
BOOL LLChatMsgBox::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
BOOL handled = FALSE;
|
||||
|
||||
// HACK: Only do this if there actually is a click callback, so that
|
||||
// overly large text boxes in the older UI won't start eating clicks.
|
||||
if (mClickedCallback)
|
||||
{
|
||||
handled = TRUE;
|
||||
|
||||
// Route future Mouse messages here preemptively. (Release on mouse up.)
|
||||
gFocusMgr.setMouseCapture( this );
|
||||
|
||||
if (getSoundFlags() & MOUSE_DOWN)
|
||||
{
|
||||
make_ui_sound("UISndClick");
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
BOOL LLChatMsgBox::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
BOOL handled = FALSE;
|
||||
|
||||
// We only handle the click if the click both started and ended within us
|
||||
|
||||
// HACK: Only do this if there actually is a click callback, so that
|
||||
// overly large text boxes in the older UI won't start eating clicks.
|
||||
if (mClickedCallback
|
||||
&& hasMouseCapture())
|
||||
{
|
||||
handled = TRUE;
|
||||
|
||||
// Release the mouse
|
||||
gFocusMgr.setMouseCapture( NULL );
|
||||
|
||||
if (getSoundFlags() & MOUSE_UP)
|
||||
{
|
||||
make_ui_sound("UISndClickRelease");
|
||||
}
|
||||
|
||||
// DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked.
|
||||
// If mouseup in the widget, it's been clicked
|
||||
if (mClickedCallback)
|
||||
{
|
||||
mClickedCallback();
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
BOOL LLChatMsgBox::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
BOOL handled = LLView::handleHover(x,y,mask);
|
||||
if(mHoverActive)
|
||||
{
|
||||
mHasHover = TRUE; // This should be set every frame during a hover.
|
||||
getWindow()->setCursor(UI_CURSOR_ARROW);
|
||||
}
|
||||
|
||||
return (handled || mHasHover);
|
||||
}
|
||||
|
||||
void LLChatMsgBox::addText( const LLStringExplicit& text )
|
||||
{
|
||||
boost::shared_ptr<text_block> t(new text_block());
|
||||
t->text = wrapText(text);
|
||||
setLineLengths(*t);
|
||||
mTextStrings.push_back(t);
|
||||
}
|
||||
|
||||
void LLChatMsgBox::setText(const LLStringExplicit& text)
|
||||
{
|
||||
mTextStrings.clear();
|
||||
|
||||
addText(text);
|
||||
|
||||
}
|
||||
|
||||
void LLChatMsgBox::resetLineLengths()
|
||||
{
|
||||
for(std::vector< boost::shared_ptr<text_block> >::iterator it = mTextStrings.begin();
|
||||
it!=mTextStrings.end();++it)
|
||||
{
|
||||
boost::shared_ptr<text_block> tblock = *it;
|
||||
setLineLengths(*tblock);
|
||||
}
|
||||
}
|
||||
|
||||
void LLChatMsgBox::setLineLengths(text_block& t)
|
||||
{
|
||||
t.lines.clear();
|
||||
|
||||
std::string::size_type cur = 0;
|
||||
std::string::size_type len = t.text.length();
|
||||
|
||||
while (cur < len)
|
||||
{
|
||||
std::string::size_type end = t.text.getWString().find('\n', cur);
|
||||
std::string::size_type runLen;
|
||||
|
||||
if (end == std::string::npos)
|
||||
{
|
||||
runLen = len - cur;
|
||||
cur = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
runLen = end - cur;
|
||||
cur = end + 1; // skip the new line character
|
||||
}
|
||||
|
||||
t.lines.push_back( (S32)runLen );
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLChatMsgBox::wrapText(const LLStringExplicit& in_text, F32 max_width)
|
||||
{
|
||||
if (max_width < 0.0f)
|
||||
{
|
||||
max_width = (F32)getRect().getWidth();
|
||||
}
|
||||
|
||||
LLWString wtext = utf8str_to_wstring(in_text);
|
||||
LLWString final_wtext;
|
||||
|
||||
LLWString::size_type cur = 0;;
|
||||
LLWString::size_type len = wtext.size();
|
||||
while (cur < len)
|
||||
{
|
||||
LLWString::size_type end = wtext.find('\n', cur);
|
||||
if (end == LLWString::npos)
|
||||
{
|
||||
end = len;
|
||||
}
|
||||
|
||||
LLWString::size_type runLen = end - cur;
|
||||
if (runLen > 0)
|
||||
{
|
||||
LLWString run(wtext, cur, runLen);
|
||||
LLWString::size_type useLen =
|
||||
mFontGL->maxDrawableChars(run.c_str(), max_width, runLen, TRUE);
|
||||
|
||||
final_wtext.append(wtext, cur, useLen);
|
||||
cur += useLen;
|
||||
// not enough room to add any more characters
|
||||
if (useLen == 0) break;
|
||||
}
|
||||
|
||||
if (cur < len)
|
||||
{
|
||||
if (wtext[cur] == '\n')
|
||||
cur += 1;
|
||||
else
|
||||
final_wtext += '\n';
|
||||
}
|
||||
}
|
||||
|
||||
std::string final_text = wstring_to_utf8str(final_wtext);
|
||||
return final_text;
|
||||
}
|
||||
|
||||
S32 LLChatMsgBox::getTextLinesNum()
|
||||
{
|
||||
S32 num_lines = 0;
|
||||
for(std::vector< boost::shared_ptr<text_block> >::iterator it = mTextStrings.begin();
|
||||
it!=mTextStrings.end();++it)
|
||||
{
|
||||
boost::shared_ptr<text_block> tblock = *it;
|
||||
num_lines+=tblock->lines.size();
|
||||
}
|
||||
|
||||
if( num_lines < 1 )
|
||||
{
|
||||
num_lines = 1;
|
||||
}
|
||||
|
||||
return num_lines;
|
||||
}
|
||||
|
||||
S32 LLChatMsgBox::getTextPixelHeight()
|
||||
{
|
||||
S32 num_lines = getTextLinesNum();
|
||||
return (S32)(num_lines * mFontGL->getLineHeight() + (num_lines-1)*4);
|
||||
}
|
||||
|
||||
void LLChatMsgBox::setValue(const LLSD& value )
|
||||
{
|
||||
setText(value.asString());
|
||||
}
|
||||
|
||||
|
||||
void LLChatMsgBox::draw()
|
||||
{
|
||||
if (mBorderVisible)
|
||||
{
|
||||
gl_rect_2d_offset_local(getLocalRect(), 2, FALSE);
|
||||
}
|
||||
|
||||
if( mBorderDropShadowVisible )
|
||||
{
|
||||
static LLUICachedControl<LLColor4> color_drop_shadow ("ColorDropShadow", *(new LLColor4));
|
||||
static LLUICachedControl<S32> drop_shadow_tooltip ("DropShadowTooltip", 0);
|
||||
gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
|
||||
color_drop_shadow, drop_shadow_tooltip);
|
||||
}
|
||||
|
||||
if (mBackgroundVisible)
|
||||
{
|
||||
LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 );
|
||||
gl_rect_2d( r, mBackgroundColor.get() );
|
||||
}
|
||||
|
||||
S32 text_x = 0;
|
||||
switch( mHAlign )
|
||||
{
|
||||
case LLFontGL::LEFT:
|
||||
text_x = mHPad;
|
||||
break;
|
||||
case LLFontGL::HCENTER:
|
||||
text_x = getRect().getWidth() / 2;
|
||||
break;
|
||||
case LLFontGL::RIGHT:
|
||||
text_x = getRect().getWidth() - mHPad;
|
||||
break;
|
||||
}
|
||||
|
||||
S32 text_y = getRect().getHeight() - mVPad;
|
||||
|
||||
if ( getEnabled() )
|
||||
{
|
||||
if(mHasHover)
|
||||
{
|
||||
drawText( text_x, text_y, mHoverColor.get() );
|
||||
}
|
||||
else
|
||||
{
|
||||
drawText( text_x, text_y, mTextColor.get() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
drawText( text_x, text_y, mDisabledColor.get() );
|
||||
}
|
||||
|
||||
if (sDebugRects)
|
||||
{
|
||||
drawDebugRect();
|
||||
}
|
||||
|
||||
//// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview)
|
||||
//std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this);
|
||||
//if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights))
|
||||
//{
|
||||
// drawDebugRect();
|
||||
//}
|
||||
|
||||
mHasHover = FALSE; // This is reset every frame.
|
||||
}
|
||||
|
||||
void LLChatMsgBox::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
// reparse line lengths
|
||||
LLView::reshape(width, height, called_from_parent);
|
||||
resetLineLengths();
|
||||
}
|
||||
|
||||
void LLChatMsgBox::drawText( S32 x, S32 y, const LLColor4& color )
|
||||
{
|
||||
S32 width = getRect().getWidth()-10;
|
||||
|
||||
for(std::vector< boost::shared_ptr<text_block> >::iterator it = mTextStrings.begin();
|
||||
it!=mTextStrings.end();++it)
|
||||
{
|
||||
boost::shared_ptr<text_block> tblock = *it;
|
||||
|
||||
S32 cur_pos = 0;
|
||||
for (std::vector<S32>::iterator iter = tblock->lines.begin();
|
||||
iter != tblock->lines.end(); ++iter)
|
||||
{
|
||||
S32 line_length = *iter;
|
||||
mFontGL->render(tblock->text, cur_pos, (F32)x, (F32)y, color,
|
||||
mHAlign, mVAlign,
|
||||
mFontStyle,
|
||||
mShadowType,
|
||||
line_length, getRect().getWidth(), NULL, TRUE, mUseEllipses );
|
||||
cur_pos += line_length + 1;
|
||||
y -= llfloor(mFontGL->getLineHeight()) + mLineSpacing;
|
||||
|
||||
}
|
||||
std::vector< boost::shared_ptr<text_block> >::iterator next = it;
|
||||
++next;
|
||||
if(next == mTextStrings.end())
|
||||
break;
|
||||
//separator
|
||||
gl_line_2d(5,y-2,width,y-2,LLColor4::grey);
|
||||
y-=4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/**
|
||||
* @file llchatmsgbox.h
|
||||
* @brief chat history text box, able to show array of strings with separator
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLCHATMSGBOX_H
|
||||
#define LL_LLCHATMSGBOX_H
|
||||
|
||||
|
||||
#include "lluictrl.h"
|
||||
#include "v4color.h"
|
||||
#include "llstring.h"
|
||||
#include "lluistring.h"
|
||||
|
||||
|
||||
class LLChatMsgBox
|
||||
: public LLUICtrl
|
||||
{
|
||||
protected:
|
||||
struct text_block
|
||||
{
|
||||
LLUIString text;
|
||||
std::vector<S32> lines;
|
||||
};
|
||||
public:
|
||||
typedef boost::function<void (void)> callback_t;
|
||||
|
||||
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
|
||||
{
|
||||
Optional<std::string> text;
|
||||
|
||||
Optional<bool> highlight_on_hover,
|
||||
border_visible,
|
||||
border_drop_shadow_visible,
|
||||
bg_visible,
|
||||
use_ellipses,
|
||||
word_wrap;
|
||||
|
||||
Optional<LLFontGL::ShadowType> font_shadow;
|
||||
|
||||
Optional<LLUIColor> text_color,
|
||||
hover_color,
|
||||
disabled_color,
|
||||
background_color,
|
||||
border_color;
|
||||
|
||||
Optional<S32> v_pad,
|
||||
h_pad,
|
||||
line_spacing;
|
||||
|
||||
Params();
|
||||
};
|
||||
protected:
|
||||
LLChatMsgBox(const Params&);
|
||||
friend class LLUICtrlFactory;
|
||||
public:
|
||||
virtual void draw();
|
||||
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
||||
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
|
||||
void setColor( const LLColor4& c ) { mTextColor = c; }
|
||||
void setDisabledColor( const LLColor4& c) { mDisabledColor = c; }
|
||||
void setBackgroundColor( const LLColor4& c) { mBackgroundColor = c; }
|
||||
void setBorderColor( const LLColor4& c) { mBorderColor = c; }
|
||||
|
||||
void setHoverColor( const LLColor4& c ) { mHoverColor = c; }
|
||||
void setHoverActive( BOOL active ) { mHoverActive = active; }
|
||||
|
||||
void setText( const LLStringExplicit& text );
|
||||
void addText( const LLStringExplicit& text );
|
||||
|
||||
void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; }
|
||||
|
||||
void setBackgroundVisible(BOOL visible) { mBackgroundVisible = visible; }
|
||||
void setBorderVisible(BOOL visible) { mBorderVisible = visible; }
|
||||
void setBorderDropshadowVisible(BOOL visible){ mBorderDropShadowVisible = visible; }
|
||||
void setHPad(S32 pixels) { mHPad = pixels; }
|
||||
void setVPad(S32 pixels) { mVPad = pixels; }
|
||||
void setRightAlign() { mHAlign = LLFontGL::RIGHT; }
|
||||
void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
|
||||
void setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ){ mClickedCallback = boost::bind(cb, userdata); } // mouse down and up within button
|
||||
|
||||
const LLFontGL* getFont() const { return mFontGL; }
|
||||
|
||||
S32 getTextPixelHeight();
|
||||
S32 getTextLinesNum();
|
||||
|
||||
virtual void setValue(const LLSD& value );
|
||||
|
||||
|
||||
|
||||
private:
|
||||
std::string wrapText (const LLStringExplicit& in_text, F32 max_width = -1.0);
|
||||
|
||||
void setLineLengths (text_block& t);
|
||||
void resetLineLengths ();
|
||||
void drawText (S32 x, S32 y, const LLColor4& color );
|
||||
|
||||
const LLFontGL* mFontGL;
|
||||
LLUIColor mTextColor;
|
||||
LLUIColor mDisabledColor;
|
||||
LLUIColor mBackgroundColor;
|
||||
LLUIColor mBorderColor;
|
||||
LLUIColor mHoverColor;
|
||||
|
||||
BOOL mHoverActive;
|
||||
BOOL mHasHover;
|
||||
BOOL mBackgroundVisible;
|
||||
BOOL mBorderVisible;
|
||||
BOOL mWordWrap;
|
||||
|
||||
U8 mFontStyle; // style bit flags for font
|
||||
LLFontGL::ShadowType mShadowType;
|
||||
BOOL mBorderDropShadowVisible;
|
||||
BOOL mUseEllipses;
|
||||
|
||||
S32 mLineSpacing;
|
||||
|
||||
S32 mHPad;
|
||||
S32 mVPad;
|
||||
LLFontGL::HAlign mHAlign;
|
||||
LLFontGL::VAlign mVAlign;
|
||||
|
||||
callback_t mClickedCallback;
|
||||
|
||||
|
||||
//same as mLineLengthList and mText in LLTextBox
|
||||
std::vector< boost::shared_ptr<text_block> > mTextStrings;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -62,9 +62,11 @@ LLNotificationChiclet::Params::Params()
|
|||
: button("button")
|
||||
, unread_notifications("unread_notifications")
|
||||
{
|
||||
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);
|
||||
|
|
@ -327,9 +329,12 @@ BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
|||
createPopupMenu();
|
||||
|
||||
updateMenuItems();
|
||||
|
||||
mPopupMenu->arrangeAndClear();
|
||||
|
||||
if (mPopupMenu)
|
||||
{
|
||||
mPopupMenu->arrangeAndClear();
|
||||
}
|
||||
|
||||
LLMenuGL::showPopup(this, mPopupMenu, x, y);
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,362 @@
|
|||
/**
|
||||
* @file LLNearbyChat.cpp
|
||||
* @brief Nearby chat history scrolling panel implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 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$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llnearbychat.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llrootview.h"
|
||||
#include "llchatitemscontainerctrl.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "llsidetray.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "llresizebar.h"
|
||||
#include "llresizehandle.h"
|
||||
#include "llmenugl.h"
|
||||
#include "llviewermenu.h"//for gMenuHolder
|
||||
|
||||
static const S32 RESIZE_BAR_THICKNESS = 3;
|
||||
|
||||
LLNearbyChat::LLNearbyChat(const LLSD& key) :
|
||||
LLFloater(key),
|
||||
mEChatTearofState(CHAT_PINNED)
|
||||
{
|
||||
}
|
||||
|
||||
LLNearbyChat::~LLNearbyChat()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLNearbyChat::postBuild()
|
||||
{
|
||||
//resize bars
|
||||
setCanResize(true);
|
||||
|
||||
mResizeBar[LLResizeBar::BOTTOM]->setVisible(false);
|
||||
mResizeBar[LLResizeBar::LEFT]->setVisible(false);
|
||||
mResizeBar[LLResizeBar::RIGHT]->setVisible(false);
|
||||
|
||||
mResizeHandle[0]->setVisible(false);
|
||||
mResizeHandle[1]->setVisible(false);
|
||||
mResizeHandle[2]->setVisible(false);
|
||||
mResizeHandle[3]->setVisible(false);
|
||||
|
||||
//menu
|
||||
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
|
||||
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
|
||||
|
||||
enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
|
||||
registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
|
||||
|
||||
|
||||
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
||||
|
||||
if(menu)
|
||||
mPopupMenuHandle = menu->getHandle();
|
||||
|
||||
gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true);
|
||||
|
||||
LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false);
|
||||
if(panel)
|
||||
{
|
||||
panel->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
|
||||
}
|
||||
|
||||
reshape(getRect().getWidth(), getRect().getHeight(), FALSE);
|
||||
|
||||
return LLFloater::postBuild();
|
||||
}
|
||||
|
||||
void LLNearbyChat::addMessage(const LLChat& message)
|
||||
{
|
||||
LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false);
|
||||
if(!panel)
|
||||
return;
|
||||
panel->addMessage(message);
|
||||
|
||||
}
|
||||
|
||||
void LLNearbyChat::onNearbySpeakers()
|
||||
{
|
||||
LLSD param = "nearby_panel";
|
||||
LLSideTray::getInstance()->showPanel("panel_people",param);
|
||||
}
|
||||
|
||||
void LLNearbyChat::onTearOff()
|
||||
{
|
||||
if(mEChatTearofState == CHAT_PINNED)
|
||||
float_panel();
|
||||
else
|
||||
pinn_panel();
|
||||
}
|
||||
|
||||
void LLNearbyChat::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
|
||||
LLFloater::reshape(width, height, called_from_parent);
|
||||
|
||||
LLPanel* caption = getChild<LLPanel>("chat_caption",false,false);
|
||||
|
||||
LLRect resize_rect;
|
||||
resize_rect.setLeftTopAndSize( 0, height, width, RESIZE_BAR_THICKNESS);
|
||||
if (mResizeBar[LLResizeBar::TOP])
|
||||
{
|
||||
mResizeBar[LLResizeBar::TOP]->reshape(width,RESIZE_BAR_THICKNESS);
|
||||
mResizeBar[LLResizeBar::TOP]->setRect(resize_rect);
|
||||
}
|
||||
|
||||
resize_rect.setLeftTopAndSize( 0, RESIZE_BAR_THICKNESS, width, RESIZE_BAR_THICKNESS);
|
||||
if (mResizeBar[LLResizeBar::BOTTOM])
|
||||
{
|
||||
mResizeBar[LLResizeBar::BOTTOM]->reshape(width,RESIZE_BAR_THICKNESS);
|
||||
mResizeBar[LLResizeBar::BOTTOM]->setRect(resize_rect);
|
||||
}
|
||||
|
||||
resize_rect.setLeftTopAndSize( 0, height, RESIZE_BAR_THICKNESS, height);
|
||||
if (mResizeBar[LLResizeBar::LEFT])
|
||||
{
|
||||
mResizeBar[LLResizeBar::LEFT]->reshape(RESIZE_BAR_THICKNESS,height);
|
||||
mResizeBar[LLResizeBar::LEFT]->setRect(resize_rect);
|
||||
}
|
||||
|
||||
resize_rect.setLeftTopAndSize( width - RESIZE_BAR_THICKNESS, height, RESIZE_BAR_THICKNESS, height);
|
||||
if (mResizeBar[LLResizeBar::RIGHT])
|
||||
{
|
||||
mResizeBar[LLResizeBar::RIGHT]->reshape(RESIZE_BAR_THICKNESS,height);
|
||||
mResizeBar[LLResizeBar::RIGHT]->setRect(resize_rect);
|
||||
}
|
||||
|
||||
|
||||
LLRect caption_rect;
|
||||
if (caption)
|
||||
{
|
||||
caption_rect = caption->getRect();
|
||||
caption_rect.setLeftTopAndSize( 2, height - RESIZE_BAR_THICKNESS, width - 4, caption_rect.getHeight());
|
||||
caption->reshape( width - 4, caption_rect.getHeight(), 1);
|
||||
caption->setRect(caption_rect);
|
||||
}
|
||||
|
||||
LLPanel* scroll_panel = getChild<LLPanel>("chat_history",false,false);
|
||||
if (scroll_panel)
|
||||
{
|
||||
LLRect scroll_rect = scroll_panel->getRect();
|
||||
scroll_rect.setLeftTopAndSize( 2, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS, width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2);
|
||||
scroll_panel->reshape( width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2, 1);
|
||||
scroll_panel->setRect(scroll_rect);
|
||||
}
|
||||
|
||||
//
|
||||
if(mEChatTearofState == CHAT_PINNED)
|
||||
{
|
||||
const LLRect& parent_rect = gViewerWindow->getRootView()->getRect();
|
||||
|
||||
LLRect panel_rect;
|
||||
panel_rect.setLeftTopAndSize( parent_rect.mLeft+2, parent_rect.mBottom+height+4, width, height);
|
||||
setRect(panel_rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLRect panel_rect;
|
||||
panel_rect.setLeftTopAndSize( getRect().mLeft, getRect().mTop, width, height);
|
||||
setRect(panel_rect);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL LLNearbyChat::handleMouseDown (S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel* caption = getChild<LLPanel>("chat_caption",false,false);
|
||||
if(caption)
|
||||
{
|
||||
LLUICtrl* nearby_speakers_btn = caption->getChild<LLUICtrl>("nearby_speakers_btn");
|
||||
LLUICtrl* tearoff_btn = caption->getChild<LLUICtrl>("tearoff_btn");
|
||||
LLUICtrl* close_btn = caption->getChild<LLUICtrl>("close_btn");
|
||||
|
||||
S32 caption_local_x = x - caption->getRect().mLeft;
|
||||
S32 caption_local_y = y - caption->getRect().mBottom;
|
||||
|
||||
if(nearby_speakers_btn && tearoff_btn)
|
||||
{
|
||||
S32 local_x = caption_local_x - nearby_speakers_btn->getRect().mLeft;
|
||||
S32 local_y = caption_local_y - nearby_speakers_btn->getRect().mBottom;
|
||||
if(nearby_speakers_btn->pointInView(local_x, local_y))
|
||||
{
|
||||
onNearbySpeakers();
|
||||
bringToFront( x, y );
|
||||
return true;
|
||||
}
|
||||
local_x = caption_local_x - tearoff_btn->getRect().mLeft;
|
||||
local_y = caption_local_y- tearoff_btn->getRect().mBottom;
|
||||
if(tearoff_btn->pointInView(local_x, local_y))
|
||||
{
|
||||
onTearOff();
|
||||
bringToFront( x, y );
|
||||
return true;
|
||||
}
|
||||
|
||||
if(close_btn)
|
||||
{
|
||||
local_x = caption_local_x - close_btn->getRect().mLeft;
|
||||
local_y = caption_local_y - close_btn->getRect().mBottom;
|
||||
if(close_btn->pointInView(local_x, local_y))
|
||||
{
|
||||
setVisible(false);
|
||||
bringToFront( x, y );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mEChatTearofState == CHAT_UNPINNED && caption->pointInView(caption_local_x, caption_local_y) )
|
||||
{
|
||||
//start draggind
|
||||
gFocusMgr.setMouseCapture(this);
|
||||
mStart_Y = y;
|
||||
mStart_X = x;
|
||||
bringToFront( x, y );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return LLFloater::handleMouseDown(x,y,mask);
|
||||
}
|
||||
|
||||
BOOL LLNearbyChat::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if( hasMouseCapture() )
|
||||
{
|
||||
// Release the mouse
|
||||
gFocusMgr.setMouseCapture( NULL );
|
||||
mStart_X = 0;
|
||||
mStart_Y = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
return LLFloater::handleMouseUp(x,y,mask);
|
||||
}
|
||||
|
||||
BOOL LLNearbyChat::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if( hasMouseCapture() )
|
||||
{
|
||||
translate(x-mStart_X,y-mStart_Y);
|
||||
return true;
|
||||
}
|
||||
return LLFloater::handleHover(x,y,mask);
|
||||
}
|
||||
|
||||
void LLNearbyChat::pinn_panel()
|
||||
{
|
||||
mEChatTearofState = CHAT_PINNED;
|
||||
LLPanel* caption = getChild<LLPanel>("chat_caption",false,false);
|
||||
LLIconCtrl* tearoff_btn = caption->getChild<LLIconCtrl>("tearoff_btn",false,false);
|
||||
|
||||
tearoff_btn->setValue("inv_item_landmark_visited.tga");
|
||||
|
||||
const LLRect& parent_rect = gViewerWindow->getRootView()->getRect();
|
||||
|
||||
LLRect panel_rect;
|
||||
panel_rect.setLeftTopAndSize( parent_rect.mLeft+2, parent_rect.mBottom+getRect().getHeight()+4, getRect().getWidth(), getRect().getHeight());
|
||||
setRect(panel_rect);
|
||||
|
||||
mResizeBar[LLResizeBar::BOTTOM]->setVisible(false);
|
||||
mResizeBar[LLResizeBar::LEFT]->setVisible(false);
|
||||
mResizeBar[LLResizeBar::RIGHT]->setVisible(false);
|
||||
|
||||
}
|
||||
|
||||
void LLNearbyChat::float_panel()
|
||||
{
|
||||
mEChatTearofState = CHAT_UNPINNED;
|
||||
LLPanel* caption = getChild<LLPanel>("chat_caption",false,false);
|
||||
LLIconCtrl* tearoff_btn = caption->getChild<LLIconCtrl>("tearoff_btn",false,false);
|
||||
|
||||
tearoff_btn->setValue("inv_item_landmark.tga");
|
||||
mResizeBar[LLResizeBar::BOTTOM]->setVisible(true);
|
||||
mResizeBar[LLResizeBar::LEFT]->setVisible(true);
|
||||
mResizeBar[LLResizeBar::RIGHT]->setVisible(true);
|
||||
}
|
||||
|
||||
void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
|
||||
{
|
||||
LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false);
|
||||
if(!panel)
|
||||
return;
|
||||
|
||||
std::string str = userdata.asString();
|
||||
if(str == "show_buddy_icons")
|
||||
panel->setHeaderVisibility(CHATITEMHEADER_SHOW_ONLY_ICON);
|
||||
else if(str == "show_names")
|
||||
panel->setHeaderVisibility(CHATITEMHEADER_SHOW_ONLY_NAME);
|
||||
else if(str == "show_icons_and_names")
|
||||
panel->setHeaderVisibility(CHATITEMHEADER_SHOW_BOTH);
|
||||
|
||||
gSavedSettings.setS32("nearbychat_showicons_and_names", (S32)panel->getHeaderVisibility());
|
||||
|
||||
|
||||
}
|
||||
bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
|
||||
{
|
||||
LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false);
|
||||
if(!panel)
|
||||
return false;
|
||||
std::string str = userdata.asString();
|
||||
if(str == "show_buddy_icons")
|
||||
return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_ONLY_ICON;
|
||||
else if(str == "show_names")
|
||||
return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_ONLY_NAME;
|
||||
else if(str == "show_icons_and_names")
|
||||
return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_BOTH;
|
||||
else if(str == "nearby_people")
|
||||
onNearbySpeakers();
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel* caption = getChild<LLPanel>("chat_caption",false,false);
|
||||
if(caption && caption->pointInView(x - caption->getRect().mLeft, y - caption->getRect().mBottom) )
|
||||
{
|
||||
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
|
||||
|
||||
if(menu)
|
||||
{
|
||||
menu->buildDrawLabels();
|
||||
menu->updateParent(LLMenuGL::sMenuContainer);
|
||||
LLMenuGL::showPopup(this, menu, x, y);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return LLFloater::handleRightMouseDown(x, y, mask);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/**
|
||||
* @file llnearbychat.h
|
||||
* @brief nearby chat history scrolling panel implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLNEARBYCHAT_H_
|
||||
#define LL_LLNEARBYCHAT_H_
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llscrollbar.h"
|
||||
#include "llchat.h"
|
||||
|
||||
class LLResizeBar;
|
||||
|
||||
class LLNearbyChat: public LLFloater
|
||||
{
|
||||
public:
|
||||
// enumerations used by the chat system
|
||||
typedef enum e_chat_tearof_state
|
||||
{
|
||||
CHAT_PINNED = 0,
|
||||
CHAT_UNPINNED = 1,
|
||||
} EChatTearofState;
|
||||
|
||||
enum { RESIZE_BAR_COUNT=4 };
|
||||
|
||||
LLNearbyChat(const LLSD& key);
|
||||
~LLNearbyChat();
|
||||
|
||||
LLNearbyChat():mEChatTearofState(CHAT_PINNED){};
|
||||
LLNearbyChat(const Params& params):mEChatTearofState(CHAT_PINNED){};
|
||||
|
||||
//static LLNearbyChat* createInstance();
|
||||
//static LLNearbyChat* getInstance ();
|
||||
|
||||
BOOL postBuild ();
|
||||
void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
||||
BOOL handleMouseDown (S32 x, S32 y, MASK mask);
|
||||
BOOL handleMouseUp (S32 x, S32 y, MASK mask);
|
||||
BOOL handleHover (S32 x, S32 y, MASK mask);
|
||||
|
||||
BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
|
||||
|
||||
void addMessage (const LLChat& message);
|
||||
|
||||
void onNearbySpeakers ();
|
||||
void onTearOff();
|
||||
|
||||
void onNearbyChatContextMenuItemClicked(const LLSD& userdata);
|
||||
bool onNearbyChatCheckContextMenuItem(const LLSD& userdata);
|
||||
|
||||
virtual void onClose(bool app_quitting) { if(app_quitting) destroy(); else setVisible(false); }
|
||||
|
||||
private:
|
||||
|
||||
void pinn_panel();
|
||||
void float_panel();
|
||||
|
||||
private:
|
||||
EChatTearofState mEChatTearofState;
|
||||
S32 mStart_X;
|
||||
S32 mStart_Y;
|
||||
|
||||
//LLResizeBar* mResizeBar[RESIZE_BAR_COUNT];
|
||||
LLHandle<LLView> mPopupMenuHandle;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* @file LLNearbyChatHandler.cpp
|
||||
* @brief Nearby chat notification managment
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 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$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llnearbychathandler.h"
|
||||
|
||||
#include "llchatitemscontainerctrl.h"
|
||||
#include "llnearbychat.h"
|
||||
#include "llrecentpeople.h"
|
||||
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
#include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
|
||||
|
||||
//add LLNearbyChatHandler to LLNotificationsUI namespace
|
||||
namespace LLNotificationsUI{
|
||||
|
||||
|
||||
LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id)
|
||||
{
|
||||
mType = type;
|
||||
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
|
||||
/////////////////////////////////////////////////////
|
||||
LLChannelManager::Params p; //TODO: check and correct
|
||||
p.id = LLUUID(NEARBY_CHAT_ID);
|
||||
p.channel_right_bound = nearby_chat->getRect().mRight;
|
||||
p.channel_width = nearby_chat->getRect().mRight - 16; //HACK: 16 - ?
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Getting a Channel for our notifications
|
||||
mChannel = LLChannelManager::getInstance()->createChannel(p);
|
||||
mChannel->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_TOP);
|
||||
mChannel->setStoreToasts(false);
|
||||
}
|
||||
LLNearbyChatHandler::~LLNearbyChatHandler()
|
||||
{
|
||||
}
|
||||
void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
|
||||
{
|
||||
if(chat_msg.mSourceType == CHAT_SOURCE_AGENT && chat_msg.mFromID.notNull())
|
||||
LLRecentPeople::instance().add(chat_msg.mFromID);
|
||||
|
||||
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
|
||||
nearby_chat->addMessage(chat_msg);
|
||||
if(nearby_chat->getVisible())
|
||||
return;//no need in toast if chat is visible
|
||||
|
||||
LLUUID id;
|
||||
id.generate();
|
||||
|
||||
LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
|
||||
|
||||
item->setMessage(chat_msg);
|
||||
item->setWidth(nearby_chat->getRect().getWidth() - 16);
|
||||
item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
|
||||
|
||||
item->setVisible(true);
|
||||
|
||||
|
||||
LLToast* toast = mChannel->addToast(id, item);
|
||||
|
||||
toast->setOnMouseEnterCallback(boost::bind(&LLNearbyChatHandler::onToastDestroy, this, toast));
|
||||
toast->setAndStartTimer(10); //TODO: set correct time
|
||||
}
|
||||
|
||||
void LLNearbyChatHandler::onToastDestroy(LLToast* toast)
|
||||
{
|
||||
//TODO: what should be done to toasts here? may be htey are to be destroyed?
|
||||
//toast->hide();
|
||||
if(mChannel)
|
||||
mChannel->removeToastsFromChannel();
|
||||
else if(toast)
|
||||
toast->hide();
|
||||
|
||||
LLFloaterReg::showTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
|
||||
}
|
||||
|
||||
void LLNearbyChatHandler::onChicletClick(void)
|
||||
{
|
||||
}
|
||||
void LLNearbyChatHandler::onChicletClose(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* @file llnearbychathandler.h
|
||||
* @brief nearby chat notify
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLNEARBYCHATHANDLER_H
|
||||
#define LL_LLNEARBYCHATHANDLER_H
|
||||
|
||||
#include "llnotificationhandler.h"
|
||||
|
||||
#define NEARBY_CHAT_ID "E1158BD6-661C-4981-9DAD-4DCBFF062502"
|
||||
|
||||
//add LLNearbyChatHandler to LLNotificationsUI namespace
|
||||
namespace LLNotificationsUI{
|
||||
|
||||
class LLNearbyChatHandler : public LLChatHandler
|
||||
{
|
||||
public:
|
||||
LLNearbyChatHandler(e_notification_type type,const LLSD& id);
|
||||
virtual ~LLNearbyChatHandler();
|
||||
|
||||
|
||||
virtual void processChat(const LLChat& chat_msg);
|
||||
virtual void onToastDestroy(LLToast* toast);
|
||||
virtual void onChicletClick(void);
|
||||
virtual void onChicletClose(void);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* LL_LLNEARBYCHATHANDLER_H */
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/**
|
||||
* @file llnotificationalerthandler.cpp
|
||||
* @brief Notification Handler Class for Alert Notifications
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-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$
|
||||
*/
|
||||
|
||||
|
||||
#include "llviewerprecompiledheaders.h" // must be first include
|
||||
|
||||
#include "llnotificationhandler.h"
|
||||
#include "lltoastnotifypanel.h"
|
||||
#include "llbottomtray.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
#include "lltoastalertpanel.h"
|
||||
|
||||
using namespace LLNotificationsUI;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsModal(false)
|
||||
{
|
||||
mType = type;
|
||||
|
||||
LLBottomTray* tray = LLBottomTray::getInstance();
|
||||
LLChannelManager::Params p;
|
||||
p.id = LLUUID("F3E07BC8-A973-476D-8C7F-F3B7293975D1");
|
||||
p.channel_right_bound = tray->getRect().getWidth() / 2;
|
||||
p.channel_width = 0;
|
||||
p.align = NA_CENTRE;
|
||||
|
||||
// Getting a Channel for our notifications
|
||||
mChannel = LLChannelManager::getInstance()->createChannel(p);
|
||||
mChannel->setFollows(FOLLOWS_BOTTOM | FOLLOWS_TOP);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLAlertHandler::~LLAlertHandler()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLAlertHandler::processNotification(const LLSD& notify)
|
||||
{
|
||||
LLToast* toast = NULL;
|
||||
|
||||
LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
|
||||
|
||||
if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load")
|
||||
{
|
||||
LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
|
||||
|
||||
toast = mChannel->addToast(notification->getID(), (LLToastPanel*)alert_dialog);
|
||||
if(!toast)
|
||||
return;
|
||||
toast->setHideButtonEnabled(false);
|
||||
toast->setOnToastDestroyCallback((boost::bind(&LLAlertHandler::onToastDestroy, this, toast)));
|
||||
toast->setCanFade(false);
|
||||
toast->setModal(mIsModal);
|
||||
}
|
||||
else if (notify["sigtype"].asString() == "change")
|
||||
{
|
||||
LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
|
||||
mChannel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
|
||||
}
|
||||
else
|
||||
{
|
||||
mChannel->killToastByNotificationID(notification->getID());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void LLAlertHandler::onToastDestroy(LLToast* toast)
|
||||
{
|
||||
toast->close();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLAlertHandler::onChicletClick(void)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLAlertHandler::onChicletClose(void)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* @file llnotificationgrouphandler.cpp
|
||||
* @brief Notification Handler Class for Group Notifications
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-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$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h" // must be first include
|
||||
|
||||
#include "llnotificationhandler.h"
|
||||
#include "lltoastgroupnotifypanel.h"
|
||||
#include "llagent.h"
|
||||
#include "llbottomtray.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
using namespace LLNotificationsUI;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id)
|
||||
{
|
||||
mType = type;
|
||||
|
||||
// getting a Chiclet and creating params for a channel
|
||||
LLBottomTray* tray = LLBottomTray::getInstance();
|
||||
mChiclet = tray->getSysWell();
|
||||
LLChannelManager::Params p;
|
||||
p.chiclet = mChiclet;
|
||||
p.channel_right_bound = tray->getRect().mRight - 10; //HACK: need to correctly resolve SysWell's position
|
||||
p.channel_width = gSavedSettings.getS32("NotifyBoxWidth");
|
||||
|
||||
// Getting a Channel for our notifications
|
||||
mChannel = LLChannelManager::getInstance()->createChannel(p);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLGroupHandler::~LLGroupHandler()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLGroupHandler::processNotification(const LLSD& notify)
|
||||
{
|
||||
LLToast* toast = NULL;
|
||||
|
||||
LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
|
||||
if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
|
||||
{
|
||||
LLPanel* notify_box = new LLToastGroupNotifyPanel(notification);
|
||||
toast = mChannel->addToast(notification->getID(), notify_box);
|
||||
if(!toast)
|
||||
return;
|
||||
toast->setAndStartTimer(5);
|
||||
toast->setOnToastDestroyCallback((boost::bind(&LLGroupHandler::onToastDestroy, this, toast)));
|
||||
mChiclet->setCounter(mChiclet->getCounter() + 1);
|
||||
}
|
||||
else if (notify["sigtype"].asString() == "delete")
|
||||
{
|
||||
mChannel->killToastByNotificationID(notification->getID());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLGroupHandler::onToastDestroy(LLToast* toast)
|
||||
{
|
||||
mChiclet->setCounter(mChiclet->getCounter() - 1);
|
||||
toast->close();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLGroupHandler::onChicletClick(void)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLGroupHandler::onChicletClose(void)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/**
|
||||
* @file llnotificationhandler.h
|
||||
* @brief Here are implemented Notification Handling Classes.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2003-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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLNOTIFICATIONHANDLER_H
|
||||
#define LL_LLNOTIFICATIONHANDLER_H
|
||||
|
||||
|
||||
#include "llwindow.h"
|
||||
|
||||
#include "llnotifications.h"
|
||||
#include "llchannelmanager.h"
|
||||
#include "llchat.h"
|
||||
|
||||
namespace LLNotificationsUI
|
||||
{
|
||||
|
||||
// ENotificationType enumerates all possible types of notifications that could be met
|
||||
//
|
||||
typedef enum e_notification_type
|
||||
{
|
||||
NT_NOTIFY,
|
||||
NT_NOTIFYTIP,
|
||||
NT_GROUPNOTIFY,
|
||||
NT_IMCHAT,
|
||||
NT_GROUPCHAT,
|
||||
NT_NEARBYCHAT,
|
||||
NT_ALERT,
|
||||
NT_ALERTMODAL
|
||||
} ENotificationType;
|
||||
|
||||
/**
|
||||
* Handler of notification events.
|
||||
* This handler manages events related to toasts and chicklets. This is base class
|
||||
* for chat and system notification handlers.
|
||||
*/
|
||||
|
||||
// LLEventHandler is a base class that specifies a common interface for all
|
||||
// notification handlers. It states, that every handler must react on the follofing
|
||||
// events:
|
||||
// - destroying of a toast;
|
||||
// - clicking on a correspondet chiclet;
|
||||
// - closing of a correspondent chiclet.
|
||||
// Also every handler must have the following attributes:
|
||||
// - type of the notification that this handler is responsible to;
|
||||
// - pointer to a correspondent chiclet;
|
||||
// - pointer to a correspondent screen channel, in which all toasts of the handled notification's
|
||||
// type should be displayed
|
||||
//
|
||||
class LLEventHandler
|
||||
{
|
||||
public:
|
||||
virtual ~LLEventHandler() {};
|
||||
|
||||
virtual void onToastDestroy(LLToast* toast)=0;
|
||||
virtual void onChicletClick(void)=0;
|
||||
virtual void onChicletClose(void)=0;
|
||||
|
||||
LLScreenChannel* mChannel;
|
||||
LLChiclet* mChiclet;
|
||||
e_notification_type mType;
|
||||
};
|
||||
|
||||
// LLSysHandler and LLChatHandler are more specific base classes
|
||||
// that divide all notification handlers on to groups:
|
||||
// - handlers for different system notifications (script dialogs, tips, group notices and alerts);
|
||||
// - handlers for different messaging notifications (nearby chat, IM chat, group chat etc.)
|
||||
/**
|
||||
* Handler for system notifications.
|
||||
*/
|
||||
class LLSysHandler : public LLEventHandler
|
||||
{
|
||||
public:
|
||||
virtual ~LLSysHandler() {};
|
||||
|
||||
virtual void processNotification(const LLSD& notify)=0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler for chat message notifications.
|
||||
*/
|
||||
class LLChatHandler : public LLEventHandler
|
||||
{
|
||||
public:
|
||||
virtual ~LLChatHandler() {};
|
||||
|
||||
virtual void processChat(const LLChat& chat_msg)=0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler for system informational notices.
|
||||
* It manages life time of tip and script notices.
|
||||
*/
|
||||
class LLInfoHandler : public LLSysHandler
|
||||
{
|
||||
public:
|
||||
LLInfoHandler(e_notification_type type, const LLSD& id);
|
||||
virtual ~LLInfoHandler();
|
||||
|
||||
|
||||
virtual void processNotification(const LLSD& notify);
|
||||
virtual void onToastDestroy(LLToast* toast);
|
||||
virtual void onChicletClick(void);
|
||||
virtual void onChicletClose(void);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for group system notices.
|
||||
*/
|
||||
class LLGroupHandler : public LLSysHandler
|
||||
{
|
||||
public:
|
||||
LLGroupHandler(e_notification_type type, const LLSD& id);
|
||||
virtual ~LLGroupHandler();
|
||||
|
||||
|
||||
virtual void processNotification(const LLSD& notify);
|
||||
virtual void onToastDestroy(LLToast* toast);
|
||||
virtual void onChicletClick(void);
|
||||
virtual void onChicletClose(void);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler for alert system notices.
|
||||
*/
|
||||
class LLAlertHandler : public LLSysHandler
|
||||
{
|
||||
public:
|
||||
LLAlertHandler(e_notification_type type, const LLSD& id);
|
||||
virtual ~LLAlertHandler();
|
||||
|
||||
void setAlertMode(bool is_modal) { mIsModal = is_modal; }
|
||||
|
||||
virtual void processNotification(const LLSD& notify);
|
||||
virtual void onToastDestroy(LLToast* toast);
|
||||
virtual void onChicletClick(void);
|
||||
virtual void onChicletClose(void);
|
||||
|
||||
protected:
|
||||
bool mIsModal;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
/**
|
||||
* @file llnotificationmanager.cpp
|
||||
* @brief Class implements a brige between the old and a new notification sistems
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-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$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "llviewerprecompiledheaders.h" // must be first include
|
||||
|
||||
|
||||
#include "llnotificationmanager.h"
|
||||
#include "llnearbychathandler.h"
|
||||
|
||||
#include "boost/bind.hpp"
|
||||
|
||||
using namespace LLNotificationsUI;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLNotificationManager::LLNotificationManager()
|
||||
{
|
||||
mNotifyHandlers.clear();
|
||||
init();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLNotificationManager::~LLNotificationManager()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLNotificationManager::init()
|
||||
{
|
||||
LLNotificationChannel::buildChannel("Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notify"));
|
||||
LLNotificationChannel::buildChannel("NotificationTips", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytip"));
|
||||
LLNotificationChannel::buildChannel("Group Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "groupnotify"));
|
||||
LLNotificationChannel::buildChannel("Alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
|
||||
LLNotificationChannel::buildChannel("AlertModal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
|
||||
|
||||
LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
|
||||
LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
|
||||
LLNotifications::instance().getChannel("Group Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
|
||||
LLNotifications::instance().getChannel("Alerts")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
|
||||
LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
|
||||
|
||||
mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLInfoHandler(NT_NOTIFY, LLSD()));
|
||||
mNotifyHandlers["notifytip"] = mNotifyHandlers["notify"];
|
||||
mNotifyHandlers["groupnotify"] = boost::shared_ptr<LLEventHandler>(new LLGroupHandler(NT_GROUPNOTIFY, LLSD()));
|
||||
mNotifyHandlers["alert"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD()));
|
||||
mNotifyHandlers["alertmodal"] = mNotifyHandlers["alert"];
|
||||
|
||||
mNotifyHandlers["nearbychat"] = boost::shared_ptr<LLEventHandler>(new LLNearbyChatHandler(NT_NEARBYCHAT, LLSD()));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool LLNotificationManager::onNotification(const LLSD& notify)
|
||||
{
|
||||
LLSysHandler* handle = NULL;
|
||||
|
||||
LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
|
||||
|
||||
if (!notification)
|
||||
return false;
|
||||
|
||||
std::string notification_type = notification->getType();
|
||||
handle = dynamic_cast<LLSysHandler*>(mNotifyHandlers[notification_type].get());
|
||||
|
||||
if(!handle)
|
||||
return false;
|
||||
|
||||
if( notification_type == "alertmodal" )
|
||||
dynamic_cast<LLAlertHandler*>(handle)->setAlertMode(true);
|
||||
|
||||
handle->processNotification(notify);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLNotificationManager::onChat(const LLChat& msg,ENotificationType type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case NT_NEARBYCHAT:
|
||||
{
|
||||
LLNearbyChatHandler* handle = dynamic_cast<LLNearbyChatHandler*>(mNotifyHandlers["nearbychat"].get());
|
||||
|
||||
if(handle)
|
||||
handle->processChat(msg);
|
||||
}
|
||||
break;
|
||||
default: //no need to handle all enum types
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
// Notification Manager Class
|
||||
/**
|
||||
* @file llnotificationmanager.h
|
||||
* @brief Class implements a brige between the old and a new notification sistems
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2003-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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLNOTIFICATIONMANAGER_H
|
||||
#define LL_LLNOTIFICATIONMANAGER_H
|
||||
|
||||
#include "lluictrl.h"
|
||||
#include "llnotificationhandler.h"
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace LLNotificationsUI {
|
||||
|
||||
class LLToast;
|
||||
|
||||
/**
|
||||
* Responsible for registering notification handlers.
|
||||
*/
|
||||
class LLNotificationManager : public LLUICtrl, public LLSingleton<LLNotificationManager>
|
||||
{
|
||||
typedef std::pair<std::string, LLEventHandler*> eventhandlers;
|
||||
public:
|
||||
LLNotificationManager();
|
||||
virtual ~LLNotificationManager();
|
||||
|
||||
//TODO: make private
|
||||
// this method initialize handlers' map for different types of notifications
|
||||
void init(void);
|
||||
//TODO: combine processing and storage (*)
|
||||
|
||||
// this method reacts on system notifications and calls an appropriate handler
|
||||
bool onNotification(const LLSD& notification);
|
||||
|
||||
// this method reacts on chat notifications and calls an appropriate handler
|
||||
void onChat(const LLChat& msg,ENotificationType type);
|
||||
|
||||
private:
|
||||
//TODO (*)
|
||||
std::map<std::string, boost::shared_ptr<LLEventHandler> > mNotifyHandlers;
|
||||
std::map<std::string, LLChatHandler*> mChatHandlers;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,357 @@
|
|||
/**
|
||||
* @file llscreenchannel.cpp
|
||||
* @brief Class implements a channel on a screen in which appropriate toasts may appear.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-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$
|
||||
*/
|
||||
|
||||
|
||||
#include "llviewerprecompiledheaders.h" // must be first include
|
||||
|
||||
#include "lliconctrl.h"
|
||||
#include "lltextbox.h"
|
||||
#include "llscreenchannel.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace LLNotificationsUI;
|
||||
|
||||
#define TOAST_MARGIN 5
|
||||
#define BOTTOMPANEL_MARGIN 35
|
||||
#define NAVBAR_MARGIN 60
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLScreenChannel::LLScreenChannel(): mUnreadToastsPanel(NULL),
|
||||
mToastAlignment(NA_BOTTOM),
|
||||
mStoreToasts(true),
|
||||
mOverflowToastHidden(false),
|
||||
mIsHovering(false),
|
||||
mControlHovering(false)
|
||||
{
|
||||
setFollows(FOLLOWS_RIGHT | FOLLOWS_BOTTOM | FOLLOWS_TOP);
|
||||
}
|
||||
|
||||
void LLScreenChannel::init(S32 channel_position, LLView* root_view)
|
||||
{
|
||||
root_view->addChild(this);
|
||||
setRect( LLRect(channel_position, root_view->getRect().getHeight() - NAVBAR_MARGIN,
|
||||
channel_position, root_view->getRect().mBottom + BOTTOMPANEL_MARGIN));
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLScreenChannel::~LLScreenChannel()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
LLUICtrl::reshape(width, height, called_from_parent);
|
||||
if(mToastAlignment != NA_CENTRE)
|
||||
showToasts();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLToast* LLScreenChannel::addToast(LLUUID id, LLPanel* panel)
|
||||
{
|
||||
ToastElem new_toast_elem(id, panel);
|
||||
|
||||
mOverflowToastHidden = false;
|
||||
|
||||
mToastList.push_back(new_toast_elem);
|
||||
getRootView()->addChild(new_toast_elem.toast);
|
||||
new_toast_elem.toast->setOnFadeCallback(boost::bind(&LLScreenChannel::onToastFade, this, new_toast_elem.toast));
|
||||
if(mControlHovering)
|
||||
{
|
||||
new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2));
|
||||
}
|
||||
showToasts();
|
||||
|
||||
return new_toast_elem.toast;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::onToastFade(LLToast* toast)
|
||||
{
|
||||
std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), static_cast<LLPanel*>(toast));
|
||||
|
||||
bool destroy_toast = toast->isViewed() || !mStoreToasts || !toast->getCanBeStored();
|
||||
if(destroy_toast)
|
||||
{
|
||||
mToastList.erase(it);
|
||||
toast->mOnToastDestroy(toast, LLSD());
|
||||
}
|
||||
else
|
||||
{
|
||||
storeToast((*it));
|
||||
mToastList.erase(it);
|
||||
}
|
||||
|
||||
showToasts();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void LLScreenChannel::storeToast(ToastElem& toast_elem)
|
||||
{
|
||||
mStoredToastList.push_back(toast_elem);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::loadStoredToastsToChannel()
|
||||
{
|
||||
std::vector<ToastElem>::iterator it;
|
||||
|
||||
if(mStoredToastList.size() == 0)
|
||||
return;
|
||||
|
||||
mOverflowToastHidden = false;
|
||||
|
||||
for(it = mStoredToastList.begin(); it != mStoredToastList.end(); ++it)
|
||||
{
|
||||
(*it).toast->resetTimer();
|
||||
mToastList.push_back((*it));
|
||||
}
|
||||
|
||||
mStoredToastList.clear();
|
||||
showToasts();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::killToastByNotificationID(LLUUID id)
|
||||
{
|
||||
std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
|
||||
|
||||
if( it != mToastList.end())
|
||||
{
|
||||
LLToast* toast = (*it).toast;
|
||||
mToastList.erase(it);
|
||||
toast->mOnToastDestroy(toast, LLSD());
|
||||
showToasts();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel)
|
||||
{
|
||||
std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
|
||||
|
||||
if( it != mToastList.end() && panel)
|
||||
{
|
||||
LLToast* toast = (*it).toast;
|
||||
LLPanel* old_panel = toast->getPanel();
|
||||
toast->removeChild(old_panel);
|
||||
delete old_panel;
|
||||
toast->arrange(panel);
|
||||
toast->resetTimer();
|
||||
showToasts();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::showToasts()
|
||||
{
|
||||
if(mToastList.size() == 0 || mIsHovering)
|
||||
return;
|
||||
|
||||
hideToastsFromScreen();
|
||||
|
||||
switch(mToastAlignment)
|
||||
{
|
||||
case NA_TOP :
|
||||
showToastsTop();
|
||||
break;
|
||||
|
||||
case NA_CENTRE :
|
||||
showToastsCentre();
|
||||
break;
|
||||
|
||||
case NA_BOTTOM :
|
||||
showToastsBottom();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::showToastsBottom()
|
||||
{
|
||||
LLRect toast_rect;
|
||||
S32 bottom = getRect().mBottom;
|
||||
std::vector<ToastElem>::reverse_iterator it;
|
||||
|
||||
for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
|
||||
{
|
||||
if(it != mToastList.rbegin())
|
||||
{
|
||||
bottom = (*(it-1)).toast->getRect().mTop;
|
||||
}
|
||||
|
||||
toast_rect = (*it).toast->getRect();
|
||||
toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+TOAST_MARGIN, toast_rect.getWidth() ,toast_rect.getHeight());
|
||||
(*it).toast->setRect(toast_rect);
|
||||
|
||||
if((*it).toast->getRect().mTop > getRect().getHeight())
|
||||
break;
|
||||
|
||||
(*it).toast->setVisible(TRUE);
|
||||
}
|
||||
|
||||
if(it != mToastList.rend() && !mOverflowToastHidden)
|
||||
{
|
||||
mHiddenToastsNum = 0;
|
||||
for(; it != mToastList.rend(); it++)
|
||||
{
|
||||
mHiddenToastsNum++;
|
||||
}
|
||||
createOverflowToast(bottom);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::showToastsCentre()
|
||||
{
|
||||
LLRect toast_rect;
|
||||
S32 bottom = (getRect().mTop - getRect().mBottom)/2 + mToastList[0].toast->getRect().getHeight()/2;
|
||||
std::vector<ToastElem>::reverse_iterator it;
|
||||
|
||||
for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
|
||||
{
|
||||
toast_rect = (*it).toast->getRect();
|
||||
toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + TOAST_MARGIN, toast_rect.getWidth() ,toast_rect.getHeight());
|
||||
(*it).toast->setRect(toast_rect);
|
||||
|
||||
(*it).toast->setVisible(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::showToastsTop()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::createOverflowToast(S32 bottom)
|
||||
{
|
||||
LLRect toast_rect;
|
||||
mUnreadToastsPanel = new LLToast(NULL);
|
||||
|
||||
if(!mUnreadToastsPanel)
|
||||
return;
|
||||
|
||||
mUnreadToastsPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onOverflowToastHide, this));
|
||||
|
||||
LLTextBox* text_box = mUnreadToastsPanel->getChild<LLTextBox>("text");
|
||||
LLIconCtrl* icon = mUnreadToastsPanel->getChild<LLIconCtrl>("icon");
|
||||
|
||||
std::string toastsNumStr = llformat("%d", mHiddenToastsNum);
|
||||
std::string text = "You have " + toastsNumStr + " new notifications.";
|
||||
|
||||
text_box->setText(text);
|
||||
text_box->setVisible(TRUE);
|
||||
icon->setVisible(TRUE);
|
||||
|
||||
toast_rect = mUnreadToastsPanel->getRect();
|
||||
toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+TOAST_MARGIN, toast_rect.getWidth() ,toast_rect.getHeight());
|
||||
mUnreadToastsPanel->setRect(toast_rect);
|
||||
mUnreadToastsPanel->setAndStartTimer(5);
|
||||
getRootView()->addChild(mUnreadToastsPanel);
|
||||
mUnreadToastsPanel->setVisible(TRUE);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::onOverflowToastHide()
|
||||
{
|
||||
mOverflowToastHidden = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::hideToastsFromScreen()
|
||||
{
|
||||
if(mUnreadToastsPanel)
|
||||
{
|
||||
mUnreadToastsPanel->close();
|
||||
delete mUnreadToastsPanel;
|
||||
mUnreadToastsPanel = NULL;
|
||||
}
|
||||
for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++)
|
||||
(*it).toast->setVisible(FALSE);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::removeToastsFromChannel()
|
||||
{
|
||||
hideToastsFromScreen();
|
||||
for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++)
|
||||
{
|
||||
(*it).toast->close();
|
||||
//toast->mOnToastDestroy(toast, LLSD()); //TODO: check OnToastDestroy handler for chat
|
||||
}
|
||||
mToastList.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::onToastHover(LLToast* toast, bool mouse_enter)
|
||||
{
|
||||
// because of LLViewerWindow::updateUI() that ALWAYS calls onMouseEnter BEFORE onMouseLeave
|
||||
// we must check this to prevent incorrect setting for hovering in a channel
|
||||
std::map<LLToast*, bool>::iterator it_first, it_second;
|
||||
S32 stack_size = mToastEventStack.size();
|
||||
mIsHovering = mouse_enter;
|
||||
|
||||
switch(stack_size)
|
||||
{
|
||||
case 0:
|
||||
mToastEventStack.insert(std::pair<LLToast*, bool>(toast, mouse_enter));
|
||||
break;
|
||||
case 1:
|
||||
it_first = mToastEventStack.begin();
|
||||
if((*it_first).second && !mouse_enter && ((*it_first).first != toast) )
|
||||
{
|
||||
mToastEventStack.clear();
|
||||
mIsHovering = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mToastEventStack.clear();
|
||||
mToastEventStack.insert(std::pair<LLToast*, bool>(toast, mouse_enter));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LL_ERRS ("LLScreenChannel::onToastHover: stack size error " ) << stack_size << llendl;
|
||||
}
|
||||
|
||||
if(!mIsHovering)
|
||||
showToasts();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* @file llscreenchannel.h
|
||||
* @brief Class implements a channel on a screen in which appropriate toasts may appear.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2003-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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLSCREENCHANNEL_H
|
||||
#define LL_LLSCREENCHANNEL_H
|
||||
|
||||
#include "lltoast.h"
|
||||
|
||||
#include <map>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace LLNotificationsUI
|
||||
{
|
||||
|
||||
typedef enum e_notification_toast_alignment
|
||||
{
|
||||
NA_TOP,
|
||||
NA_CENTRE,
|
||||
NA_BOTTOM,
|
||||
} EToastAlignment;
|
||||
|
||||
|
||||
/**
|
||||
* Screen channel manages toasts visibility and positioning on the screen.
|
||||
*/
|
||||
class LLScreenChannel : public LLUICtrl
|
||||
{
|
||||
public:
|
||||
LLScreenChannel();
|
||||
virtual ~LLScreenChannel();
|
||||
|
||||
void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
||||
LLToast* addToast(LLUUID id, LLPanel* panel);
|
||||
void init(S32 channel_position, LLView* root_view);
|
||||
|
||||
void killToastByNotificationID(LLUUID id);
|
||||
void modifyToastByNotificationID(LLUUID id, LLPanel* panel);
|
||||
|
||||
void setToastAlignment(e_notification_toast_alignment align) {mToastAlignment = align;}
|
||||
|
||||
void setControlHovering(bool control) { mControlHovering = control; }
|
||||
void setHovering(bool hovering) { mIsHovering = hovering; }
|
||||
|
||||
void removeToastsFromChannel();
|
||||
void hideToastsFromScreen();
|
||||
|
||||
void setStoreToasts(bool store) { mStoreToasts = store; }
|
||||
void loadStoredToastsToChannel();
|
||||
|
||||
void showToasts();
|
||||
|
||||
e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
|
||||
|
||||
private:
|
||||
struct ToastElem
|
||||
{
|
||||
LLUUID id;
|
||||
LLToast* toast;
|
||||
ToastElem(LLUUID lluuid, LLPanel* panel) : id(lluuid)
|
||||
{
|
||||
toast = new LLToast(panel);
|
||||
}
|
||||
|
||||
ToastElem(const ToastElem& toast_elem)
|
||||
{
|
||||
id = toast_elem.id;
|
||||
toast = toast_elem.toast;
|
||||
}
|
||||
|
||||
bool operator == (const LLUUID &id_op) const
|
||||
{
|
||||
return (id == id_op);
|
||||
}
|
||||
|
||||
bool operator == (LLPanel* panel_op) const
|
||||
{
|
||||
return (toast == panel_op);
|
||||
}
|
||||
};
|
||||
|
||||
void onToastHover(LLToast* toast, bool mouse_enter);
|
||||
|
||||
void onToastFade(LLToast* toast);
|
||||
void storeToast(ToastElem& toast_elem);
|
||||
|
||||
void showToastsBottom();
|
||||
void showToastsCentre();
|
||||
void showToastsTop();
|
||||
|
||||
void createOverflowToast(S32 bottom);
|
||||
void onOverflowToastHide();
|
||||
|
||||
bool mControlHovering;
|
||||
bool mIsHovering;
|
||||
bool mStoreToasts;
|
||||
bool mOverflowToastHidden;
|
||||
S32 mHiddenToastsNum;
|
||||
LLToast* mUnreadToastsPanel;
|
||||
std::vector<ToastElem> mToastList;
|
||||
std::vector<ToastElem> mStoredToastList;
|
||||
e_notification_toast_alignment mToastAlignment;
|
||||
std::map<LLToast*, bool> mToastEventStack;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
#include "llsidetray.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llaccordionpanel.h"
|
||||
#include "llaccordionctrl.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "llrootview.h"
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ bool LLSideTray::instanceCreated ()
|
|||
return sInstance!=0;
|
||||
}
|
||||
|
||||
LLSideTrayTab::LLSideTrayTab(const Params& params):mAccordionPanel(0)
|
||||
LLSideTrayTab::LLSideTrayTab(const Params& params):mAccordionCtrl(0)
|
||||
|
||||
{
|
||||
mImagePath = params.image_path;
|
||||
|
|
@ -131,18 +131,18 @@ void LLSideTrayTab::addPanel(LLPanel* panel)
|
|||
|
||||
bool LLSideTrayTab::addChild(LLView* view, S32 tab_group)
|
||||
{
|
||||
if(mAccordionPanel == 0)
|
||||
if(mAccordionCtrl == 0)
|
||||
{
|
||||
mAccordionPanel = new LLAccordionPanel();
|
||||
mAccordionPanel->setVisible(TRUE);
|
||||
LLPanel::addChild(mAccordionPanel,tab_group);
|
||||
mAccordionCtrl = new LLAccordionCtrl();
|
||||
mAccordionCtrl->setVisible(TRUE);
|
||||
LLPanel::addChild(mAccordionCtrl,tab_group);
|
||||
}
|
||||
|
||||
|
||||
bool res = true;
|
||||
if(TAB_PANEL_CAPTION_NAME != view->getName())//skip our caption panel
|
||||
{
|
||||
mAccordionPanel->addCollapsibleCtrl(view);
|
||||
mAccordionCtrl->addCollapsibleCtrl(view);
|
||||
}
|
||||
else
|
||||
res = LLPanel::addChild(view,tab_group);
|
||||
|
|
@ -185,17 +185,17 @@ void LLSideTrayTab::arrange(S32 width, S32 height )
|
|||
offset = title_panel->getRect().getHeight();
|
||||
}
|
||||
|
||||
LLRect sRect = mAccordionPanel->getRect();
|
||||
LLRect sRect = mAccordionCtrl->getRect();
|
||||
sRect.setLeftTopAndSize( splitter_margin, height - offset - splitter_margin, width - 2*splitter_margin, height - offset - 2*splitter_margin);
|
||||
mAccordionPanel->setRect(sRect);
|
||||
mAccordionCtrl->setRect(sRect);
|
||||
|
||||
mAccordionPanel->setMaxWidth(sRect.getWidth());
|
||||
mAccordionPanel->arrange();
|
||||
mAccordionCtrl->setMaxWidth(sRect.getWidth());
|
||||
mAccordionCtrl->arrange();
|
||||
}
|
||||
|
||||
void LLSideTrayTab::reshape (S32 width, S32 height, BOOL called_from_parent )
|
||||
{
|
||||
if(!mAccordionPanel)
|
||||
if(!mAccordionCtrl)
|
||||
return;
|
||||
S32 offset = 0;
|
||||
|
||||
|
|
@ -210,12 +210,12 @@ void LLSideTrayTab::reshape (S32 width, S32 height, BOOL called_from_parent )
|
|||
|
||||
|
||||
|
||||
LLRect sRect = mAccordionPanel->getRect();
|
||||
LLRect sRect = mAccordionCtrl->getRect();
|
||||
sRect.setLeftTopAndSize( splitter_margin, height - offset - splitter_margin, width - 2*splitter_margin, height - offset - 2*splitter_margin);
|
||||
mAccordionPanel->setMaxWidth(sRect.getWidth());
|
||||
mAccordionPanel->reshape(sRect.getWidth(), sRect.getHeight());
|
||||
mAccordionCtrl->setMaxWidth(sRect.getWidth());
|
||||
mAccordionCtrl->reshape(sRect.getWidth(), sRect.getHeight());
|
||||
|
||||
mAccordionPanel->setRect(sRect);
|
||||
mAccordionCtrl->setRect(sRect);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -231,7 +231,7 @@ void LLSideTrayTab::draw()
|
|||
|
||||
void LLSideTrayTab::onOpen (const LLSD& key)
|
||||
{
|
||||
mAccordionPanel->onOpen(key);
|
||||
mAccordionCtrl->onOpen(key);
|
||||
}
|
||||
|
||||
LLSideTrayTab* LLSideTrayTab::createInstance ()
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include "string"
|
||||
|
||||
class LLSideTray;
|
||||
class LLAccordionPanel;
|
||||
class LLAccordionCtrl;
|
||||
|
||||
class LLSideTrayTab: public LLPanel
|
||||
{
|
||||
|
|
@ -86,7 +86,7 @@ private:
|
|||
std::string mImagePath;
|
||||
std::string mDescription;
|
||||
|
||||
LLAccordionPanel* mAccordionPanel;
|
||||
LLAccordionCtrl* mAccordionCtrl;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,236 @@
|
|||
/**
|
||||
* @file lltoast.cpp
|
||||
* @brief This class implements a placeholder for any notification panel.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-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$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h" // must be first include
|
||||
|
||||
#include "llfocusmgr.h"
|
||||
#include "lltoast.h"
|
||||
|
||||
using namespace LLNotificationsUI;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLToast::LLToast(LLPanel* panel) :
|
||||
LLFloater(),
|
||||
mTimerValue(5),
|
||||
mIsViewed(false),
|
||||
mPanel(panel),
|
||||
mCanFade(true),
|
||||
mHideBtn(NULL),
|
||||
mIsModal(false),
|
||||
mCanBeStored(true)
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_toast.xml");
|
||||
|
||||
mHideBtn = getChild<LLButton>("hide_btn");
|
||||
if(mHideBtn)
|
||||
{
|
||||
mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this));
|
||||
}
|
||||
if(mPanel)
|
||||
{
|
||||
arrange(mPanel);
|
||||
}
|
||||
|
||||
// disable unnecessary Floater's functionality
|
||||
setTitleVisible(FALSE);
|
||||
setCanMinimize(FALSE);
|
||||
setCanClose(FALSE);
|
||||
setCanTearOff(FALSE);
|
||||
setCanResize(FALSE);
|
||||
setCanDrag(FALSE);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLToast::setHideButtonEnabled(bool enabled)
|
||||
{
|
||||
if(mHideBtn)
|
||||
mHideBtn->setEnabled(enabled);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLToast::~LLToast()
|
||||
{
|
||||
if(mIsModal)
|
||||
{
|
||||
gFocusMgr.unlockFocus();
|
||||
gFocusMgr.releaseFocusIfNeeded( this );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLToast::setAndStartTimer(F32 period)
|
||||
{
|
||||
if(mCanFade)
|
||||
{
|
||||
mTimerValue = period;
|
||||
mTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool LLToast::timerHasExpired()
|
||||
{
|
||||
if (mTimer.getStarted())
|
||||
{
|
||||
F32 elapsed_time = mTimer.getElapsedTimeF32();
|
||||
if (elapsed_time > 4)
|
||||
{
|
||||
setBackgroundOpaque(FALSE);
|
||||
}
|
||||
if (elapsed_time > mTimerValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLToast::hide()
|
||||
{
|
||||
setVisible(FALSE); //TODO: store in Chiclet's history
|
||||
mIsViewed = false;
|
||||
mTimer.stop();
|
||||
mOnFade(this, LLSD());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLToast::setCanFade(bool can_fade)
|
||||
{
|
||||
mCanFade = can_fade;
|
||||
if(!mCanFade)
|
||||
mTimer.stop();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLToast::tick()
|
||||
{
|
||||
if(mCanFade)
|
||||
{
|
||||
setVisible(FALSE);
|
||||
mTimer.stop();
|
||||
mOnFade(this, LLSD());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLToast::arrange(LLPanel* panel)
|
||||
{
|
||||
LLRect panel_rect, toast_rect;
|
||||
|
||||
panel_rect = panel->getRect();
|
||||
reshape(panel_rect.getWidth(), panel_rect.getHeight());
|
||||
panel_rect.setLeftTopAndSize(0, panel_rect.getHeight(), panel_rect.getWidth(), panel_rect.getHeight());
|
||||
panel->setRect(panel_rect);
|
||||
addChild(panel);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLToast::draw()
|
||||
{
|
||||
if(timerHasExpired())
|
||||
{
|
||||
tick();
|
||||
}
|
||||
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLToast::setModal(bool modal)
|
||||
{
|
||||
mIsModal = modal;
|
||||
if(mIsModal)
|
||||
{
|
||||
gFocusMgr.setMouseCapture( this );
|
||||
gFocusMgr.setTopCtrl( this );
|
||||
setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLToast::setVisible(BOOL show)
|
||||
{
|
||||
if(show)
|
||||
{
|
||||
setBackgroundOpaque(TRUE);
|
||||
}
|
||||
LLPanel::setVisible(show);
|
||||
if(mPanel)
|
||||
{
|
||||
if(!mPanel->isDead())
|
||||
{
|
||||
mPanel->setVisible(show);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLToast::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mOnToastHover(this, MOUSE_ENTER);
|
||||
|
||||
setVisibleAndFrontmost();
|
||||
setBackgroundOpaque(TRUE);
|
||||
if(mCanFade && !mIsViewed)
|
||||
{
|
||||
mTimer.stop();
|
||||
}
|
||||
|
||||
sendChildToFront(mHideBtn);
|
||||
if(mHideBtn && mHideBtn->getEnabled())
|
||||
mHideBtn->setVisible(TRUE);
|
||||
mOnMousEnter(this, LLSD());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLToast::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mOnToastHover(this, MOUSE_LEAVE);
|
||||
|
||||
if(mCanFade && !mIsViewed)
|
||||
{
|
||||
mTimer.start();
|
||||
}
|
||||
if(mHideBtn && mHideBtn->getEnabled())
|
||||
{
|
||||
if( mHideBtn->getRect().pointInRect(x, y) )
|
||||
return;
|
||||
mHideBtn->setVisible(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
* @file lltoast.h
|
||||
* @brief This class implements a placeholder for any notification panel.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2003-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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLTOAST_H
|
||||
#define LL_LLTOAST_H
|
||||
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llfloater.h"
|
||||
#include "lltimer.h"
|
||||
#include "lldate.h"
|
||||
|
||||
#define MOUSE_LEAVE false
|
||||
#define MOUSE_ENTER true
|
||||
|
||||
namespace LLNotificationsUI
|
||||
{
|
||||
|
||||
/**
|
||||
* Represents toast pop-up.
|
||||
* This is a parent view for all toast panels.
|
||||
*/
|
||||
class LLToast : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLToast(LLPanel* panel);
|
||||
virtual ~LLToast();
|
||||
|
||||
//
|
||||
bool isViewed() { return mIsViewed; }
|
||||
|
||||
void setCanFade(bool can_fade);
|
||||
|
||||
void setHideButtonEnabled(bool enabled);
|
||||
|
||||
void setCanBeStored(bool can_be_stored) { mCanBeStored = can_be_stored; }
|
||||
bool getCanBeStored() { return mCanBeStored; }
|
||||
//
|
||||
void setAndStartTimer(F32 period);
|
||||
//
|
||||
void resetTimer() { mTimer.start(); }
|
||||
void close() { die(); }
|
||||
virtual void draw();
|
||||
virtual void setVisible(BOOL show);
|
||||
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
virtual void hide();
|
||||
LLPanel* getPanel() { return mPanel; }
|
||||
void arrange(LLPanel* panel);
|
||||
void setModal(bool modal);
|
||||
|
||||
|
||||
// Registers callbacks for events
|
||||
boost::signals2::connection setOnFadeCallback(commit_callback_t cb) { return mOnFade.connect(cb); }
|
||||
boost::signals2::connection setOnMouseEnterCallback(commit_callback_t cb) { return mOnMousEnter.connect(cb); }
|
||||
boost::signals2::connection setOnToastDestroyCallback(commit_callback_t cb) { return mOnToastDestroy.connect(cb); }
|
||||
typedef boost::function<void (LLToast* toast, bool mouse_enter)> toast_hover_check_callback_t;
|
||||
typedef boost::signals2::signal<void (LLToast* toast, bool mouse_enter)> toast_hover_check_signal_t;
|
||||
toast_hover_check_signal_t mOnToastHover;
|
||||
boost::signals2::connection setOnToastHoverCallback(toast_hover_check_callback_t cb) { return mOnToastHover.connect(cb); }
|
||||
|
||||
commit_signal_t mOnFade;
|
||||
commit_signal_t mOnMousEnter;
|
||||
commit_signal_t mOnToastDestroy;
|
||||
|
||||
private:
|
||||
|
||||
bool timerHasExpired();
|
||||
void tick();
|
||||
|
||||
LLTimer mTimer;
|
||||
F32 mTimerValue;
|
||||
|
||||
LLPanel* mPanel;
|
||||
LLButton* mHideBtn;
|
||||
|
||||
LLColor4 mBgColor;
|
||||
bool mIsViewed;
|
||||
bool mCanFade;
|
||||
bool mIsModal;
|
||||
bool mCanBeStored;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,474 @@
|
|||
/**
|
||||
* @file lltoastalertpanel.cpp
|
||||
* @brief Panel for alert toasts.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-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$
|
||||
*/
|
||||
|
||||
|
||||
#include "llviewerprecompiledheaders.h" // must be first include
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llboost.h"
|
||||
|
||||
#include "lltoastalertpanel.h"
|
||||
#include "llfontgl.h"
|
||||
#include "lltextbox.h"
|
||||
#include "llbutton.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llkeyboard.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "llui.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llfunctorregistry.h"
|
||||
|
||||
const S32 MAX_ALLOWED_MSG_WIDTH = 400;
|
||||
const F32 DEFAULT_BUTTON_DELAY = 0.5f;
|
||||
const S32 MSG_PAD = 8;
|
||||
|
||||
/*static*/ LLControlGroup* LLToastAlertPanel::sSettings = NULL;
|
||||
/*static*/ LLToastAlertPanel::URLLoader* LLToastAlertPanel::sURLLoader;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Private methods
|
||||
|
||||
static const S32 VPAD = 16;
|
||||
static const S32 HPAD = 25;
|
||||
static const S32 BTN_HPAD = 8;
|
||||
|
||||
LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal)
|
||||
: LLToastPanel(notification),
|
||||
mDefaultOption( 0 ),
|
||||
mCheck(NULL),
|
||||
mCaution(notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH),
|
||||
mLabel(notification->getName()),
|
||||
mLineEditor(NULL)
|
||||
{
|
||||
const LLFontGL* font = LLFontGL::getFontSansSerif();
|
||||
const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f);
|
||||
const S32 EDITOR_HEIGHT = 20;
|
||||
|
||||
LLNotificationFormPtr form = mNotification->getForm();
|
||||
std::string edit_text_name;
|
||||
std::string edit_text_contents;
|
||||
bool is_password = false;
|
||||
|
||||
LLToastPanel::setBackgroundVisible(FALSE);
|
||||
LLToastPanel::setBackgroundOpaque(TRUE);
|
||||
|
||||
|
||||
typedef std::vector<std::pair<std::string, std::string> > options_t;
|
||||
options_t supplied_options;
|
||||
|
||||
// for now, get LLSD to iterator over form elements
|
||||
LLSD form_sd = form->asLLSD();
|
||||
|
||||
S32 option_index = 0;
|
||||
for (LLSD::array_const_iterator it = form_sd.beginArray(); it != form_sd.endArray(); ++it)
|
||||
{
|
||||
std::string type = (*it)["type"].asString();
|
||||
if (type == "button")
|
||||
{
|
||||
if((*it)["default"])
|
||||
{
|
||||
mDefaultOption = option_index;
|
||||
}
|
||||
|
||||
supplied_options.push_back(std::make_pair((*it)["name"].asString(), (*it)["text"].asString()));
|
||||
|
||||
ButtonData data;
|
||||
if (option_index == mNotification->getURLOption())
|
||||
{
|
||||
data.mURL = mNotification->getURL();
|
||||
data.mURLExternal = mNotification->getURLOpenExternally();
|
||||
}
|
||||
|
||||
mButtonData.push_back(data);
|
||||
option_index++;
|
||||
}
|
||||
else if (type == "text")
|
||||
{
|
||||
edit_text_contents = (*it)["value"].asString();
|
||||
edit_text_name = (*it)["name"].asString();
|
||||
}
|
||||
else if (type == "password")
|
||||
{
|
||||
edit_text_contents = (*it)["value"].asString();
|
||||
edit_text_name = (*it)["name"].asString();
|
||||
is_password = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Buttons
|
||||
options_t options;
|
||||
if (supplied_options.empty())
|
||||
{
|
||||
options.push_back(std::make_pair(std::string("close"), LLNotifications::instance().getGlobalString("implicitclosebutton")));
|
||||
|
||||
// add data for ok button.
|
||||
ButtonData ok_button;
|
||||
mButtonData.push_back(ok_button);
|
||||
mDefaultOption = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
options = supplied_options;
|
||||
}
|
||||
|
||||
S32 num_options = options.size();
|
||||
|
||||
// Calc total width of buttons
|
||||
S32 button_width = 0;
|
||||
S32 sp = font->getWidth(std::string("OO"));
|
||||
for( S32 i = 0; i < num_options; i++ )
|
||||
{
|
||||
S32 w = S32(font->getWidth( options[i].second ) + 0.99f) + sp + 2 * LLBUTTON_H_PAD;
|
||||
button_width = llmax( w, button_width );
|
||||
}
|
||||
S32 btn_total_width = button_width;
|
||||
if( num_options > 1 )
|
||||
{
|
||||
btn_total_width = (num_options * button_width) + ((num_options - 1) * BTN_HPAD);
|
||||
}
|
||||
|
||||
// Message: create text box using raw string, as text has been structure deliberately
|
||||
// Use size of created text box to generate dialog box size
|
||||
std::string msg = mNotification->getMessage();
|
||||
llwarns << "Alert: " << msg << llendl;
|
||||
LLTextBox::Params params;
|
||||
params.name("Alert message");
|
||||
params.font(font);
|
||||
params.tab_stop(false);
|
||||
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
|
||||
|
||||
LLTextBox * msg_box = LLUICtrlFactory::create<LLTextBox> (params);
|
||||
// Compute max allowable height for the dialog text, so we can allocate
|
||||
// space before wrapping the text to fit.
|
||||
S32 max_allowed_msg_height =
|
||||
gFloaterView->getRect().getHeight()
|
||||
- LINE_HEIGHT // title bar
|
||||
- 3*VPAD - BTN_HEIGHT;
|
||||
msg_box->reshape( MAX_ALLOWED_MSG_WIDTH, max_allowed_msg_height );
|
||||
msg_box->setWrappedText(msg, (F32)MAX_ALLOWED_MSG_WIDTH);
|
||||
msg_box->reshapeToFitText();
|
||||
|
||||
const LLRect& text_rect = msg_box->getRect();
|
||||
S32 dialog_width = llmax( btn_total_width, text_rect.getWidth() ) + 2 * HPAD;
|
||||
S32 dialog_height = text_rect.getHeight() + 3 * VPAD + BTN_HEIGHT;
|
||||
|
||||
if (hasTitleBar())
|
||||
{
|
||||
dialog_height += LINE_HEIGHT; // room for title bar
|
||||
}
|
||||
|
||||
// it's ok for the edit text body to be empty, but we want the name to exist if we're going to draw it
|
||||
if (!edit_text_name.empty())
|
||||
{
|
||||
dialog_height += EDITOR_HEIGHT + VPAD;
|
||||
dialog_width = llmax(dialog_width, (S32)(font->getWidth( edit_text_contents ) + 0.99f));
|
||||
}
|
||||
|
||||
if (mCaution)
|
||||
{
|
||||
// Make room for the caution icon.
|
||||
dialog_width += 32 + HPAD;
|
||||
}
|
||||
|
||||
LLToastPanel::reshape( dialog_width, dialog_height, FALSE );
|
||||
|
||||
S32 msg_y = LLToastPanel::getRect().getHeight() - VPAD;
|
||||
S32 msg_x = HPAD;
|
||||
if (hasTitleBar())
|
||||
{
|
||||
msg_y -= LINE_HEIGHT; // room for title
|
||||
}
|
||||
|
||||
static LLUIColor alert_caution_text_color = LLUIColorTable::instance().getColor("AlertCautionTextColor");
|
||||
static LLUIColor alert_text_color = LLUIColorTable::instance().getColor("AlertTextColor");
|
||||
if (mCaution)
|
||||
{
|
||||
LLIconCtrl::Params params;
|
||||
params.name("icon");
|
||||
params.rect(LLRect(msg_x, msg_y, msg_x+32, msg_y-32));
|
||||
params.mouse_opaque(false);
|
||||
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
|
||||
params.tab_stop(false);
|
||||
LLIconCtrl * icon = LLUICtrlFactory::create<LLIconCtrl> (params);
|
||||
icon->setValue ("notify_caution_icon.tga");
|
||||
icon->setMouseOpaque(FALSE);
|
||||
LLToastPanel::addChild(icon);
|
||||
msg_x += 32 + HPAD;
|
||||
msg_box->setColor( alert_caution_text_color );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg_box->setColor( alert_text_color );
|
||||
}
|
||||
|
||||
LLRect rect;
|
||||
rect.setLeftTopAndSize( msg_x, msg_y, text_rect.getWidth(), text_rect.getHeight() );
|
||||
msg_box->setRect( rect );
|
||||
LLToastPanel::addChild(msg_box);
|
||||
|
||||
// Buttons
|
||||
S32 button_left = (LLToastPanel::getRect().getWidth() - btn_total_width) / 2;
|
||||
|
||||
for( S32 i = 0; i < num_options; i++ )
|
||||
{
|
||||
LLRect button_rect;
|
||||
button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT );
|
||||
|
||||
LLButton::Params p;
|
||||
p.name(options[i].first);
|
||||
p.rect(button_rect);
|
||||
p.click_callback.function(boost::bind(&LLToastAlertPanel::onButtonPressed, this, _2, i));
|
||||
p.font(font);
|
||||
p.label(options[i].second);
|
||||
|
||||
LLButton* btn = LLUICtrlFactory::create<LLButton>(p);
|
||||
mButtonData[i].mButton = btn;
|
||||
|
||||
LLToastPanel::addChild(btn);
|
||||
|
||||
if( i == mDefaultOption )
|
||||
{
|
||||
btn->setFocus(TRUE);
|
||||
}
|
||||
|
||||
button_left += button_width + BTN_HPAD;
|
||||
}
|
||||
|
||||
// (Optional) Edit Box
|
||||
if (!edit_text_name.empty())
|
||||
{
|
||||
S32 y = VPAD + BTN_HEIGHT + VPAD/2;
|
||||
|
||||
LLLineEditor::Params params;
|
||||
params.name(edit_text_name);
|
||||
params.rect(LLRect( HPAD, y+EDITOR_HEIGHT, dialog_width-HPAD, y));
|
||||
params.default_text(edit_text_contents);
|
||||
params.max_length_bytes(STD_STRING_STR_LEN);
|
||||
mLineEditor = LLUICtrlFactory::create<LLLineEditor> (params);
|
||||
|
||||
// make sure all edit keys get handled properly (DEV-22396)
|
||||
mLineEditor->setHandleEditKeysDirectly(TRUE);
|
||||
|
||||
LLToastPanel::addChild(mLineEditor);
|
||||
}
|
||||
|
||||
if (mLineEditor)
|
||||
{
|
||||
mLineEditor->setDrawAsterixes(is_password);
|
||||
|
||||
setEditTextArgs(notification->getSubstitutions());
|
||||
}
|
||||
|
||||
std::string ignore_label;
|
||||
|
||||
if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
|
||||
{
|
||||
setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label);
|
||||
}
|
||||
else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
|
||||
{
|
||||
setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label);
|
||||
}
|
||||
|
||||
gFloaterView->adjustToFitScreen(this, FALSE);
|
||||
LLFloater::setFocus(TRUE);
|
||||
if (mLineEditor)
|
||||
{
|
||||
mLineEditor->setFocus(TRUE);
|
||||
mLineEditor->selectAll();
|
||||
}
|
||||
if(mDefaultOption >= 0)
|
||||
{
|
||||
// delay before enabling default button
|
||||
mDefaultBtnTimer.start();
|
||||
mDefaultBtnTimer.setTimerExpirySec(DEFAULT_BUTTON_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std::string& check_control )
|
||||
{
|
||||
const LLFontGL* font = LLFontGL::getFontSansSerif();
|
||||
const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f);
|
||||
|
||||
// Extend dialog for "check next time"
|
||||
S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * HPAD;
|
||||
S32 check_width = S32(font->getWidth(check_title) + 0.99f) + 16;
|
||||
max_msg_width = llmax(max_msg_width, check_width);
|
||||
S32 dialog_width = max_msg_width + 2 * HPAD;
|
||||
|
||||
S32 dialog_height = LLToastPanel::getRect().getHeight();
|
||||
dialog_height += LINE_HEIGHT;
|
||||
dialog_height += LINE_HEIGHT / 2;
|
||||
|
||||
LLToastPanel::reshape( dialog_width, dialog_height, FALSE );
|
||||
|
||||
S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2;
|
||||
|
||||
LLCheckBoxCtrl::Params p;
|
||||
p.name("check");
|
||||
p.rect.left(msg_x).bottom(VPAD+BTN_HEIGHT+LINE_HEIGHT/2).width(max_msg_width).height(LINE_HEIGHT);
|
||||
p.label(check_title);
|
||||
p.font(font);
|
||||
p.commit_callback.function(boost::bind(&LLToastAlertPanel::onClickIgnore, this, _1));
|
||||
mCheck = LLUICtrlFactory::create<LLCheckBoxCtrl>(p);
|
||||
LLToastPanel::addChild(mCheck);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLToastAlertPanel::setVisible( BOOL visible )
|
||||
{
|
||||
LLToastPanel::setVisible( visible );
|
||||
|
||||
if( visible )
|
||||
{
|
||||
make_ui_sound("UISndAlert");
|
||||
}
|
||||
}
|
||||
|
||||
void LLToastAlertPanel::onClose(bool app_quitting)
|
||||
{
|
||||
LLFloater::onClose(app_quitting);
|
||||
}
|
||||
|
||||
LLToastAlertPanel::~LLToastAlertPanel()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLToastAlertPanel::hasTitleBar() const
|
||||
{
|
||||
return (getCurrentTitle() != "" && getCurrentTitle() != " ") // has title
|
||||
|| isMinimizeable()
|
||||
|| isCloseable();
|
||||
}
|
||||
|
||||
BOOL LLToastAlertPanel::handleKeyHere(KEY key, MASK mask )
|
||||
{
|
||||
if( KEY_RETURN == key && mask == MASK_NONE )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if (KEY_RIGHT == key)
|
||||
{
|
||||
LLToastPanel::focusNextItem(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
else if (KEY_LEFT == key)
|
||||
{
|
||||
LLToastPanel::focusPrevItem(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
else if (KEY_TAB == key && mask == MASK_NONE)
|
||||
{
|
||||
LLToastPanel::focusNextItem(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
else if (KEY_TAB == key && mask == MASK_SHIFT)
|
||||
{
|
||||
LLToastPanel::focusPrevItem(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLToastAlertPanel::draw()
|
||||
{
|
||||
// if the default button timer has just expired, activate the default button
|
||||
if(mDefaultBtnTimer.hasExpired() && mDefaultBtnTimer.getStarted())
|
||||
{
|
||||
mDefaultBtnTimer.stop(); // prevent this block from being run more than once
|
||||
LLToastPanel::setDefaultBtn(mButtonData[mDefaultOption].mButton);
|
||||
}
|
||||
|
||||
static LLUIColor shadow_color = LLUIColorTable::instance().getColor("ColorDropShadow");
|
||||
static LLUICachedControl<S32> shadow_lines ("DropShadowFloater");
|
||||
|
||||
gl_drop_shadow( 0, LLToastPanel::getRect().getHeight(), LLToastPanel::getRect().getWidth(), 0,
|
||||
shadow_color, shadow_lines);
|
||||
|
||||
LLToastPanel::draw();
|
||||
}
|
||||
|
||||
void LLToastAlertPanel::setEditTextArgs(const LLSD& edit_args)
|
||||
{
|
||||
if (mLineEditor)
|
||||
{
|
||||
std::string msg = mLineEditor->getText();
|
||||
mLineEditor->setText(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "LLToastAlertPanel::setEditTextArgs called on dialog with no line editor" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
void LLToastAlertPanel::onButtonPressed( const LLSD& data, S32 button )
|
||||
{
|
||||
ButtonData* button_data = &mButtonData[button];
|
||||
|
||||
LLSD response = mNotification->getResponseTemplate();
|
||||
if (mLineEditor)
|
||||
{
|
||||
response[mLineEditor->getName()] = mLineEditor->getValue();
|
||||
}
|
||||
response[button_data->mButton->getName()] = true;
|
||||
|
||||
// If we declared a URL and chose the URL option, go to the url
|
||||
if (!button_data->mURL.empty() && sURLLoader != NULL)
|
||||
{
|
||||
sURLLoader->load(button_data->mURL, button_data->mURLExternal);
|
||||
}
|
||||
|
||||
mNotification->respond(response); // new notification reponse
|
||||
closeFloater(); // deletes self
|
||||
}
|
||||
|
||||
void LLToastAlertPanel::onClickIgnore(LLUICtrl* ctrl)
|
||||
{
|
||||
// checkbox sometimes means "hide and do the default" and
|
||||
// other times means "warn me again". Yuck. JC
|
||||
BOOL check = ctrl->getValue().asBoolean();
|
||||
if (mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
|
||||
{
|
||||
// question was "show again" so invert value to get "ignore"
|
||||
check = !check;
|
||||
}
|
||||
mNotification->setIgnored(check);
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/**
|
||||
* @file lltoastalertpanel.h
|
||||
* @brief Panel for alert toasts.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-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$
|
||||
*/
|
||||
|
||||
#ifndef LL_TOASTALERTPANEL_H
|
||||
#define LL_TOASTALERTPANEL_H
|
||||
|
||||
#include "lltoastpanel.h"
|
||||
#include "llfloater.h"
|
||||
#include "llui.h"
|
||||
#include "llnotifications.h"
|
||||
|
||||
class LLButton;
|
||||
class LLCheckBoxCtrl;
|
||||
class LLAlertDialogTemplate;
|
||||
class LLLineEditor;
|
||||
|
||||
/**
|
||||
* Toast panel for alert notification.
|
||||
* Alerts notifications doesn't require user interaction.
|
||||
*
|
||||
* Replaces class LLAlertDialog.
|
||||
* https://wiki.lindenlab.com/mediawiki/index.php?title=LLAlertDialog&oldid=81388
|
||||
*/
|
||||
|
||||
class LLToastAlertPanel
|
||||
: public LLToastPanel,
|
||||
public LLFloater
|
||||
{
|
||||
public:
|
||||
typedef bool (*display_callback_t)(S32 modal);
|
||||
|
||||
class URLLoader
|
||||
{
|
||||
public:
|
||||
virtual void load(const std::string& url, bool force_open_externally = 0 ) = 0;
|
||||
virtual ~URLLoader() {}
|
||||
};
|
||||
|
||||
static void setURLLoader(URLLoader* loader)
|
||||
{
|
||||
sURLLoader = loader;
|
||||
}
|
||||
|
||||
public:
|
||||
// User's responsibility to call show() after creating these.
|
||||
LLToastAlertPanel( LLNotificationPtr notep, bool is_modal );
|
||||
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask );
|
||||
|
||||
virtual void draw();
|
||||
virtual void setVisible( BOOL visible );
|
||||
virtual void onClose(bool app_quitting);
|
||||
|
||||
bool setCheckBox( const std::string&, const std::string& );
|
||||
void setCaution(BOOL val = TRUE) { mCaution = val; }
|
||||
// If mUnique==TRUE only one copy of this message should exist
|
||||
void setUnique(BOOL val = TRUE) { mUnique = val; }
|
||||
void setEditTextArgs(const LLSD& edit_args);
|
||||
|
||||
void onClickIgnore(LLUICtrl* ctrl);
|
||||
void onButtonPressed(const LLSD& data, S32 button);
|
||||
|
||||
private:
|
||||
static std::map<std::string, LLToastAlertPanel*> sUniqueActiveMap;
|
||||
|
||||
virtual ~LLToastAlertPanel();
|
||||
// No you can't kill it. It can only kill itself.
|
||||
|
||||
// Does it have a readable title label, or minimize or close buttons?
|
||||
BOOL hasTitleBar() const;
|
||||
|
||||
private:
|
||||
static URLLoader* sURLLoader;
|
||||
static LLControlGroup* sSettings;
|
||||
|
||||
struct ButtonData
|
||||
{
|
||||
LLButton* mButton;
|
||||
std::string mURL;
|
||||
U32 mURLExternal;
|
||||
};
|
||||
std::vector<ButtonData> mButtonData;
|
||||
|
||||
S32 mDefaultOption;
|
||||
LLCheckBoxCtrl* mCheck;
|
||||
BOOL mCaution;
|
||||
BOOL mUnique;
|
||||
LLUIString mLabel;
|
||||
LLFrameTimer mDefaultBtnTimer;
|
||||
// For Dialogs that take a line as text as input:
|
||||
LLLineEditor* mLineEditor;
|
||||
|
||||
};
|
||||
|
||||
#endif // LL_TOASTALERTPANEL_H
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* @file lltoastgroupnotifypanel.cpp
|
||||
* @brief Panel for group notify toasts.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-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$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "lltoastgroupnotifypanel.h"
|
||||
|
||||
#include "llfocusmgr.h"
|
||||
|
||||
#include "llbutton.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "llnotify.h"
|
||||
#include "lltextbox.h"
|
||||
#include "llviewertexteditor.h"
|
||||
#include "lluiconstants.h"
|
||||
#include "llui.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llfloatergroupinfo.h"
|
||||
#include "lltrans.h"
|
||||
#include "llinitparam.h"
|
||||
|
||||
#include "llglheaders.h"
|
||||
#include "llagent.h"
|
||||
#include "llavatariconctrl.h"
|
||||
|
||||
LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification)
|
||||
: LLToastPanel(notification),
|
||||
mInventoryOffer(NULL)
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_notify.xml");
|
||||
const LLSD& payload = notification->getPayload();
|
||||
LLGroupData groupData;
|
||||
if (!gAgent.getGroupData(payload["group_id"].asUUID(),groupData))
|
||||
{
|
||||
llwarns << "Group notice for unkown group: " << payload["group_id"].asUUID() << llendl;
|
||||
}
|
||||
|
||||
//group icon
|
||||
LLIconCtrl* pGroupIcon = getChild<LLIconCtrl>("group_icon", TRUE);
|
||||
pGroupIcon->setValue(groupData.mInsigniaID);
|
||||
|
||||
//header title
|
||||
const std::string& from_name = payload["sender_name"].asString();
|
||||
std::stringstream from;
|
||||
from << from_name << "/" << groupData.mName;
|
||||
LLTextBox* pTitleText = this->getChild<LLTextBox>("title", TRUE, FALSE);
|
||||
pTitleText->setValue(from.str());
|
||||
|
||||
//message body
|
||||
const std::string& message = payload["message"].asString();
|
||||
LLTextEditor* pMessageText = getChild< LLTextEditor>("message", TRUE, FALSE);
|
||||
pMessageText->setEnabled(FALSE);
|
||||
pMessageText->setTakesFocus(FALSE);
|
||||
pMessageText->setValue(message);
|
||||
|
||||
//attachment
|
||||
BOOL hasInventory = payload["inventory_offer"].isDefined();
|
||||
LLTextBox * pAttachLink = getChild<LLTextBox>("attachment", TRUE, FALSE);
|
||||
pAttachLink->setVisible(hasInventory);
|
||||
if (hasInventory) {
|
||||
pAttachLink->setValue(payload["inventory_name"]);
|
||||
mInventoryOffer = new LLOfferInfo(payload["inventory_offer"]);
|
||||
childSetActionTextbox("attachment", boost::bind(
|
||||
&LLToastGroupNotifyPanel::onClickAttachment, this));
|
||||
}
|
||||
|
||||
//ok button
|
||||
LLButton* pOkBtn = getChild<LLButton>("btn_ok", TRUE, FALSE);
|
||||
pOkBtn->setClickedCallback((boost::bind(&LLToastGroupNotifyPanel::onClickOk, this)));
|
||||
setDefaultBtn(pOkBtn);
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
LLToastGroupNotifyPanel::~LLToastGroupNotifyPanel()
|
||||
{
|
||||
}
|
||||
|
||||
void LLToastGroupNotifyPanel::close()
|
||||
{
|
||||
// The group notice dialog may be an inventory offer.
|
||||
// If it has an inventory save button and that button is still enabled
|
||||
// Then we need to send the inventory declined message
|
||||
if(mInventoryOffer != NULL)
|
||||
{
|
||||
mInventoryOffer->forceResponse(IOR_DECLINE);
|
||||
mInventoryOffer = NULL;
|
||||
}
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
void LLToastGroupNotifyPanel::onClickOk()
|
||||
{
|
||||
LLSD response = mNotification->getResponseTemplate();
|
||||
mNotification->respond(response);
|
||||
close();
|
||||
}
|
||||
|
||||
void LLToastGroupNotifyPanel::onClickAttachment()
|
||||
{
|
||||
mInventoryOffer->forceResponse(IOR_ACCEPT);
|
||||
|
||||
mInventoryOffer = NULL;
|
||||
|
||||
LLTextBox * pAttachLink = getChild<LLTextBox>("attachment", TRUE, FALSE);
|
||||
pAttachLink->setVisible(FALSE);
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* @file lltoastgroupnotifypanel.h
|
||||
* @brief Panel for group notify toasts.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLGROUPNOTIFY_H
|
||||
#define LL_LLGROUPNOTIFY_H
|
||||
|
||||
#include "llfontgl.h"
|
||||
#include "lltoastpanel.h"
|
||||
#include "lldarray.h"
|
||||
#include "lltimer.h"
|
||||
#include "llviewermessage.h"
|
||||
#include "llnotifications.h"
|
||||
|
||||
class LLButton;
|
||||
|
||||
/**
|
||||
* Toast panel for group notification.
|
||||
*
|
||||
* Replaces class LLGroupNotifyBox.
|
||||
*/
|
||||
class LLToastGroupNotifyPanel
|
||||
: public LLToastPanel
|
||||
{
|
||||
public:
|
||||
void close();
|
||||
|
||||
static bool onNewNotification(const LLSD& notification);
|
||||
|
||||
|
||||
// Non-transient messages. You can specify non-default button
|
||||
// layouts (like one for script dialogs) by passing various
|
||||
// numbers in for "layout".
|
||||
LLToastGroupNotifyPanel(LLNotificationPtr& notification);
|
||||
|
||||
/*virtual*/ ~LLToastGroupNotifyPanel();
|
||||
protected:
|
||||
void onClickOk();
|
||||
void onClickAttachment();
|
||||
private:
|
||||
|
||||
LLButton* mSaveInventoryBtn;
|
||||
|
||||
LLUUID mGroupID;
|
||||
LLOfferInfo* mInventoryOffer;
|
||||
};
|
||||
|
||||
// This view contains the stack of notification windows.
|
||||
//extern LLView* gGroupNotifyBoxView;
|
||||
|
||||
const S32 GROUP_LAYOUT_DEFAULT = 0;
|
||||
const S32 GROUP_LAYOUT_SCRIPT_DIALOG = 1;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,435 @@
|
|||
/**
|
||||
* @file lltoastnotifypanel.cpp
|
||||
* @brief Panel for notify toasts.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-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$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "lltoastnotifypanel.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "lluiconstants.h"
|
||||
#include "llrect.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "lltexteditor.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lldbstrings.h"
|
||||
#include "llchat.h"
|
||||
#include "llfloaterchat.h"
|
||||
#include "lltrans.h"
|
||||
#include "lloverlaybar.h"
|
||||
|
||||
|
||||
const S32 BOTTOM_PAD = VPAD * 3;
|
||||
|
||||
//static
|
||||
const LLFontGL* LLToastNotifyPanel::sFont = NULL;
|
||||
const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
|
||||
|
||||
LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification) : LLToastPanel(notification) {
|
||||
mIsTip = notification->getType() == "notifytip";
|
||||
mNumOptions = 0;
|
||||
mNumButtons = 0;
|
||||
mIsScriptDialog = (notification->getName() == "ScriptDialog"
|
||||
|| notification->getName() == "ScriptDialogGroup");
|
||||
mAddedDefaultBtn = false;
|
||||
|
||||
// clicking on a button does not steal current focus
|
||||
setIsChrome(TRUE);
|
||||
|
||||
// class init
|
||||
if (!sFont)
|
||||
{
|
||||
sFont = LLFontGL::getFontSansSerif();
|
||||
sFontSmall = LLFontGL::getFontSansSerifSmall();
|
||||
}
|
||||
|
||||
// setup paramaters
|
||||
mMessage = notification->getMessage();
|
||||
|
||||
// initialize
|
||||
setFocusRoot(!mIsTip);
|
||||
|
||||
// caution flag can be set explicitly by specifying it in the
|
||||
// notification payload, or it can be set implicitly if the
|
||||
// notify xml template specifies that it is a caution
|
||||
//
|
||||
// tip-style notification handle 'caution' differently -
|
||||
// they display the tip in a different color
|
||||
mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
|
||||
|
||||
LLNotificationFormPtr form(notification->getForm());
|
||||
|
||||
mNumOptions = form->getNumElements();
|
||||
|
||||
LLRect rect = mIsTip ? getNotifyTipRect(mMessage)
|
||||
: getNotifyRect(mNumOptions, mIsScriptDialog, mIsCaution);
|
||||
setRect(rect);
|
||||
setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT));
|
||||
setBackgroundVisible(FALSE);
|
||||
setBackgroundOpaque(TRUE);
|
||||
|
||||
LLIconCtrl* icon;
|
||||
LLTextEditor* text;
|
||||
|
||||
const S32 TOP = getRect().getHeight() - (mIsTip ? (S32)sFont->getLineHeight() : 32);
|
||||
const S32 BOTTOM = (S32)sFont->getLineHeight();
|
||||
S32 x = HPAD + HPAD;
|
||||
S32 y = TOP;
|
||||
|
||||
LLIconCtrl::Params common_params;
|
||||
common_params.rect(LLRect(x, y, x+32, TOP-32));
|
||||
common_params.mouse_opaque(false);
|
||||
common_params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
|
||||
common_params.tab_stop(false);
|
||||
|
||||
if (mIsTip)
|
||||
{
|
||||
// use the tip notification icon
|
||||
common_params.image(LLUI::getUIImage("notify_tip_icon.tga"));
|
||||
icon = LLUICtrlFactory::create<LLIconCtrl> (common_params);
|
||||
}
|
||||
else if (mIsCaution)
|
||||
{
|
||||
// use the caution notification icon
|
||||
common_params.image(LLUI::getUIImage("notify_caution_icon.tga"));
|
||||
icon = LLUICtrlFactory::create<LLIconCtrl> (common_params);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use the default notification icon
|
||||
common_params.image(LLUI::getUIImage("notify_box_icon.tga"));
|
||||
icon = LLUICtrlFactory::create<LLIconCtrl> (common_params);
|
||||
}
|
||||
|
||||
icon->setMouseOpaque(FALSE);
|
||||
addChild(icon);
|
||||
|
||||
x += HPAD + HPAD + 32;
|
||||
|
||||
// add a caution textbox at the top of a caution notification
|
||||
LLTextBox* caution_box = NULL;
|
||||
if (mIsCaution && !mIsTip)
|
||||
{
|
||||
S32 caution_height = ((S32)sFont->getLineHeight() * 2) + VPAD;
|
||||
LLTextBox::Params params;
|
||||
params.name("caution_box");
|
||||
params.rect(LLRect(x, y, getRect().getWidth() - 2, caution_height));
|
||||
params.font(sFont);
|
||||
params.mouse_opaque(false);
|
||||
params.font.style("BOLD");
|
||||
params.text_color(LLUIColorTable::instance().getColor("NotifyCautionWarnColor"));
|
||||
params.background_color(LLUIColorTable::instance().getColor("NotifyCautionBoxColor"));
|
||||
params.border_visible(false);
|
||||
caution_box = LLUICtrlFactory::create<LLTextBox> (params);
|
||||
caution_box->setWrappedText(notification->getMessage());
|
||||
|
||||
addChild(caution_box);
|
||||
|
||||
// adjust the vertical position of the next control so that
|
||||
// it appears below the caution textbox
|
||||
y = y - caution_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
const S32 BTN_TOP = BOTTOM_PAD + (((mNumOptions-1+2)/3)) * (BTN_HEIGHT+VPAD);
|
||||
|
||||
// Tokenization on \n is handled by LLTextBox
|
||||
|
||||
const S32 MAX_LENGTH = 512 + 20 +
|
||||
DB_FIRST_NAME_BUF_SIZE +
|
||||
DB_LAST_NAME_BUF_SIZE +
|
||||
DB_INV_ITEM_NAME_BUF_SIZE; // For script dialogs: add space for title.
|
||||
|
||||
LLTextEditor::Params params;
|
||||
params.name("box");
|
||||
params.rect(LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16));
|
||||
params.max_text_length(MAX_LENGTH);
|
||||
params.default_text(mMessage);
|
||||
params.font(sFont);
|
||||
params.allow_embedded_items(false);
|
||||
params.word_wrap(true);
|
||||
params.tab_stop(false);
|
||||
params.mouse_opaque(false);
|
||||
params.bg_readonly_color(LLColor4::transparent);
|
||||
params.text_readonly_color(LLUIColorTable::instance().getColor("NotifyTextColor"));
|
||||
params.takes_non_scroll_clicks(false);
|
||||
params.hide_scrollbar(true);
|
||||
params.enabled(false);
|
||||
params.hide_border(true);
|
||||
text = LLUICtrlFactory::create<LLTextEditor> (params);
|
||||
addChild(text);
|
||||
}
|
||||
|
||||
if (mIsTip)
|
||||
{
|
||||
// TODO: Make a separate archive for these.
|
||||
LLChat chat(mMessage);
|
||||
chat.mSourceType = CHAT_SOURCE_SYSTEM;
|
||||
LLFloaterChat::addChatHistory(chat);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLButton::Params p;
|
||||
p.name(std::string("next"));
|
||||
p.rect(LLRect(getRect().getWidth()-26, BOTTOM_PAD + 20, getRect().getWidth()-2, BOTTOM_PAD));
|
||||
p.image_selected.name("notify_next.png");
|
||||
p.image_unselected.name("notify_next.png");
|
||||
p.font(sFont);
|
||||
p.scale_image(true);
|
||||
p.tool_tip(LLTrans::getString("next").c_str());
|
||||
|
||||
for (S32 i = 0; i < mNumOptions; i++)
|
||||
{
|
||||
|
||||
LLSD form_element = form->getElement(i);
|
||||
if (form_element["type"].asString() != "button")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
addButton(form_element["name"].asString(), form_element["text"].asString(), TRUE, form_element["default"].asBoolean());
|
||||
}
|
||||
|
||||
if (mNumButtons == 0)
|
||||
{
|
||||
addButton("OK", LLTrans::getString("ok"), FALSE, TRUE);
|
||||
mAddedDefaultBtn = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
LLToastNotifyPanel::~LLToastNotifyPanel() {
|
||||
std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer());
|
||||
}
|
||||
|
||||
|
||||
LLRect LLToastNotifyPanel::getNotifyRect(S32 num_options, BOOL mIsScriptDialog, BOOL is_caution)
|
||||
{
|
||||
S32 notify_height = gSavedSettings.getS32("NotifyBoxHeight");
|
||||
if (is_caution)
|
||||
{
|
||||
// make caution-style dialog taller to accomodate extra text,
|
||||
// as well as causing the accept/decline buttons to be drawn
|
||||
// in a different position, to help prevent "quick-click-through"
|
||||
// of many permissions prompts
|
||||
notify_height = gSavedSettings.getS32("PermissionsCautionNotifyBoxHeight");
|
||||
}
|
||||
const S32 NOTIFY_WIDTH = gSavedSettings.getS32("NotifyBoxWidth");
|
||||
|
||||
const S32 TOP = getRect().getHeight();
|
||||
const S32 RIGHT =getRect().getWidth();
|
||||
const S32 LEFT = RIGHT - NOTIFY_WIDTH;
|
||||
|
||||
if (num_options < 1)
|
||||
{
|
||||
num_options = 1;
|
||||
}
|
||||
|
||||
// Add two "blank" option spaces.
|
||||
if (mIsScriptDialog)
|
||||
{
|
||||
num_options += 2;
|
||||
}
|
||||
|
||||
S32 additional_lines = (num_options-1) / 3;
|
||||
|
||||
notify_height += additional_lines * (BTN_HEIGHT + VPAD);
|
||||
|
||||
return LLRect(LEFT, TOP, RIGHT, TOP-notify_height);
|
||||
}
|
||||
|
||||
// static
|
||||
LLRect LLToastNotifyPanel::getNotifyTipRect(const std::string &utf8message)
|
||||
{
|
||||
S32 line_count = 1;
|
||||
LLWString message = utf8str_to_wstring(utf8message);
|
||||
S32 message_len = message.length();
|
||||
|
||||
const S32 NOTIFY_WIDTH = gSavedSettings.getS32("NotifyBoxWidth");
|
||||
// Make room for the icon area.
|
||||
const S32 text_area_width = NOTIFY_WIDTH - HPAD * 4 - 32;
|
||||
|
||||
const llwchar* wchars = message.c_str();
|
||||
const llwchar* start = wchars;
|
||||
const llwchar* end;
|
||||
S32 total_drawn = 0;
|
||||
BOOL done = FALSE;
|
||||
|
||||
do
|
||||
{
|
||||
line_count++;
|
||||
|
||||
for (end=start; *end != 0 && *end != '\n'; end++)
|
||||
;
|
||||
|
||||
if( *end == 0 )
|
||||
{
|
||||
end = wchars + message_len;
|
||||
done = TRUE;
|
||||
}
|
||||
|
||||
S32 remaining = end - start;
|
||||
while( remaining )
|
||||
{
|
||||
S32 drawn = sFont->maxDrawableChars( start, (F32)text_area_width, remaining, TRUE );
|
||||
|
||||
if( 0 == drawn )
|
||||
{
|
||||
drawn = 1; // Draw at least one character, even if it doesn't all fit. (avoids an infinite loop)
|
||||
}
|
||||
|
||||
total_drawn += drawn;
|
||||
start += drawn;
|
||||
remaining -= drawn;
|
||||
|
||||
if( total_drawn < message_len )
|
||||
{
|
||||
if( (wchars[ total_drawn ] != '\n') )
|
||||
{
|
||||
// wrap because line was too long
|
||||
line_count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
done = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
total_drawn++; // for '\n'
|
||||
end++;
|
||||
start = end;
|
||||
} while( !done );
|
||||
|
||||
const S32 MIN_NOTIFY_HEIGHT = 72;
|
||||
const S32 MAX_NOTIFY_HEIGHT = 600;
|
||||
S32 notify_height = llceil((F32) (line_count+1) * sFont->getLineHeight());
|
||||
if(gOverlayBar)
|
||||
{
|
||||
notify_height += gOverlayBar->getBoundingRect().mTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
// *FIX: this is derived from the padding caused by the
|
||||
// rounded rects, shouldn't be a const here.
|
||||
notify_height += 10;
|
||||
}
|
||||
notify_height += VPAD;
|
||||
notify_height = llclamp(notify_height, MIN_NOTIFY_HEIGHT, MAX_NOTIFY_HEIGHT);
|
||||
|
||||
const S32 RIGHT = getRect().getWidth();
|
||||
const S32 LEFT = RIGHT - NOTIFY_WIDTH;
|
||||
|
||||
return LLRect(LEFT, notify_height, RIGHT, 0);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLToastNotifyPanel::onClickButton(void* data)
|
||||
{
|
||||
InstanceAndS32* self_and_button = (InstanceAndS32*)data;
|
||||
LLToastNotifyPanel* self = self_and_button->mSelf;
|
||||
std::string button_name = self_and_button->mButtonName;
|
||||
|
||||
LLSD response = self->mNotification->getResponseTemplate();
|
||||
if (!self->mAddedDefaultBtn && !button_name.empty())
|
||||
{
|
||||
response[button_name] = true;
|
||||
}
|
||||
self->mNotification->respond(response);
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLButton* LLToastNotifyPanel::addButton(const std::string& name, const std::string& label, BOOL is_option, BOOL is_default)
|
||||
{
|
||||
// make caution notification buttons slightly narrower
|
||||
// so that 3 of them can fit without overlapping the "next" button
|
||||
S32 btn_width = mIsCaution? 84 : 90;
|
||||
|
||||
LLRect btn_rect;
|
||||
LLButton* btn;
|
||||
S32 btn_height= BTN_HEIGHT;
|
||||
const LLFontGL* font = sFont;
|
||||
S32 ignore_pad = 0;
|
||||
S32 button_index = mNumButtons;
|
||||
S32 index = button_index;
|
||||
S32 x = (HPAD * 4) + 32;
|
||||
|
||||
if (mIsScriptDialog)
|
||||
{
|
||||
// Add two "blank" option spaces, before the "Ignore" button
|
||||
index = button_index + 2;
|
||||
if (button_index == 0)
|
||||
{
|
||||
// Ignore button is smaller, less wide
|
||||
btn_height = BTN_HEIGHT_SMALL;
|
||||
font = sFontSmall;
|
||||
ignore_pad = 10;
|
||||
}
|
||||
}
|
||||
|
||||
btn_rect.setOriginAndSize(x + (index % 3) * (btn_width+HPAD+HPAD) + ignore_pad,
|
||||
BOTTOM_PAD + (index / 3) * (BTN_HEIGHT+VPAD),
|
||||
btn_width - 2*ignore_pad,
|
||||
btn_height);
|
||||
|
||||
InstanceAndS32* userdata = new InstanceAndS32;
|
||||
userdata->mSelf = this;
|
||||
userdata->mButtonName = is_option ? name : "";
|
||||
|
||||
mBtnCallbackData.push_back(userdata);
|
||||
|
||||
LLButton::Params p;
|
||||
p.name(name);
|
||||
p.label(label);
|
||||
p.rect(btn_rect);
|
||||
p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata));
|
||||
p.font(font);
|
||||
if (mIsCaution)
|
||||
{
|
||||
p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor"));
|
||||
p.image_color_disabled(LLUIColorTable::instance().getColor("ButtonCautionImageColor"));
|
||||
}
|
||||
btn = LLUICtrlFactory::create<LLButton>(p);
|
||||
|
||||
|
||||
addChild(btn, -1);
|
||||
|
||||
if (is_default)
|
||||
{
|
||||
setDefaultBtn(btn);
|
||||
}
|
||||
|
||||
mNumButtons++;
|
||||
return btn;
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* @file lltoastnotifypanel.h
|
||||
* @brief Panel for notify toasts.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-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$
|
||||
*/
|
||||
|
||||
#ifndef LLTOASTNOTIFYPANEL_H_
|
||||
#define LLTOASTNOTIFYPANEL_H_
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llfontgl.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llbutton.h"
|
||||
#include "lltoastpanel.h"
|
||||
|
||||
|
||||
/**
|
||||
* Toast panel for notification.
|
||||
* Notification panel should be used for notifications that require a response from the user.
|
||||
*
|
||||
* Replaces class LLNotifyBox.
|
||||
*/
|
||||
class LLToastNotifyPanel: public LLToastPanel {
|
||||
public:
|
||||
LLToastNotifyPanel(LLNotificationPtr&);
|
||||
virtual ~LLToastNotifyPanel();
|
||||
bool isTip() {return mIsTip;}
|
||||
static LLToastNotifyPanel * buildNotifyPanel(LLNotificationPtr notification);
|
||||
|
||||
protected:
|
||||
LLButton* addButton(std::string const &name, const std::string& label, BOOL is_option, BOOL is_default);
|
||||
// Used for callbacks
|
||||
struct InstanceAndS32
|
||||
{
|
||||
LLToastNotifyPanel* mSelf;
|
||||
std::string mButtonName;
|
||||
};
|
||||
std::vector<InstanceAndS32*> mBtnCallbackData;
|
||||
|
||||
private:
|
||||
|
||||
// Returns the rect, relative to gNotifyView, where this
|
||||
// notify box should be placed.
|
||||
LLRect getNotifyRect(S32 num_options, BOOL layout_script_dialog, BOOL is_caution);
|
||||
LLRect getNotifyTipRect(const std::string &message);
|
||||
// internal handler for button being clicked
|
||||
static void onClickButton(void* data);
|
||||
bool mIsTip;
|
||||
bool mAddedDefaultBtn;
|
||||
bool mIsScriptDialog;
|
||||
bool mIsCaution; // is this a caution notification?
|
||||
std::string mMessage;
|
||||
S32 mNumOptions;
|
||||
S32 mNumButtons;
|
||||
|
||||
static const LLFontGL* sFont;
|
||||
static const LLFontGL* sFontSmall;
|
||||
};
|
||||
|
||||
#endif /* LLTOASTNOTIFYPANEL_H_ */
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* @file lltoastpanel.cpp
|
||||
* @brief Creates a panel of a specific kind for a toast
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-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$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "lltoastpanel.h"
|
||||
|
||||
LLToastPanel::LLToastPanel(LLNotificationPtr& notification) {
|
||||
mNotification = notification;
|
||||
}
|
||||
|
||||
LLToastPanel::~LLToastPanel() {
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* @file lltoastpanel.h
|
||||
* @brief Creates a panel of a specific kind for a toast.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2003-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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLTOASTPANEL_H
|
||||
#define LL_LLTOASTPANEL_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llnotifications.h"
|
||||
|
||||
/**
|
||||
* Base class for all panels that can be added to the toast.
|
||||
* All toast panels should contain necessary logic for representing certain notification
|
||||
* but shouldn't contain logic related to this panel lifetime control and positioning
|
||||
* on the parent view.
|
||||
*/
|
||||
class LLToastPanel: public LLPanel {
|
||||
public:
|
||||
LLToastPanel(LLNotificationPtr&);
|
||||
virtual ~LLToastPanel() = 0;
|
||||
protected:
|
||||
LLNotificationPtr mNotification;
|
||||
};
|
||||
|
||||
#endif /* LL_TOASTPANEL_H */
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
#include "llfloaterinventory.h"
|
||||
#include "llmediaremotectrl.h"
|
||||
#include "llmoveview.h"
|
||||
#include "llnearbychathistory.h"
|
||||
#include "llnearbychat.h"
|
||||
|
||||
#include "llpreviewanim.h"
|
||||
#include "llpreviewgesture.h"
|
||||
|
|
@ -109,6 +109,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
|
||||
LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
|
||||
LLFloaterReg::add("chat", "floater_chat_history.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChat>);
|
||||
LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
|
||||
LLFloaterReg::add("communicate", "floater_chatterbox.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatterBox>);
|
||||
LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
|
||||
LLFloaterReg::add("contacts", "floater_my_friends.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMyFriends>);
|
||||
|
|
@ -134,7 +135,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("mini_inspector", "panel_mini_inspector.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMiniInspector>);
|
||||
|
||||
LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);
|
||||
LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChatHistory>);
|
||||
LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
|
||||
|
||||
LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
#include "llviewertexture.h"
|
||||
#include "llviewerparcelmedia.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llviewerparcelmedia.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llversionviewer.h"
|
||||
#include "llviewertexturelist.h"
|
||||
|
|
|
|||
|
|
@ -143,6 +143,9 @@
|
|||
#include "llwindebug.h" // For the invalid message handler
|
||||
#endif
|
||||
|
||||
//#include "llnearbychathistory.h"
|
||||
#include "llnotificationmanager.h"
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
|
|
@ -2370,15 +2373,15 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
|
|||
switch(chat.mChatType)
|
||||
{
|
||||
case CHAT_TYPE_WHISPER:
|
||||
verb = " " + LLTrans::getString("whisper") + " ";
|
||||
verb = "(" + LLTrans::getString("whisper") + ")";
|
||||
break;
|
||||
case CHAT_TYPE_DEBUG_MSG:
|
||||
case CHAT_TYPE_OWNER:
|
||||
case CHAT_TYPE_NORMAL:
|
||||
verb = ": ";
|
||||
verb = "";
|
||||
break;
|
||||
case CHAT_TYPE_SHOUT:
|
||||
verb = " " + LLTrans::getString("shout") + " ";
|
||||
verb = "(" + LLTrans::getString("shout") + ")";
|
||||
break;
|
||||
case CHAT_TYPE_START:
|
||||
case CHAT_TYPE_STOP:
|
||||
|
|
@ -2386,12 +2389,12 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
|
|||
break;
|
||||
default:
|
||||
LL_WARNS("Messaging") << "Unknown type " << chat.mChatType << " in chat!" << LL_ENDL;
|
||||
verb = " say, ";
|
||||
verb = "";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
chat.mText = from_name;
|
||||
chat.mText = "";
|
||||
chat.mText += verb;
|
||||
chat.mText += mesg;
|
||||
}
|
||||
|
|
@ -2419,12 +2422,14 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
|
|||
&& (is_linden || !is_busy || is_owned_by_me))
|
||||
{
|
||||
// show on screen and add to history
|
||||
LLFloaterChat::addChat(chat, FALSE, FALSE);
|
||||
LLNotificationsUI::LLNotificationManager::instance().onChat(
|
||||
chat, LLNotificationsUI::NT_NEARBYCHAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotificationsUI::LLNotificationManager::instance().onChat(
|
||||
chat, LLNotificationsUI::NT_NEARBYCHAT);
|
||||
// just add to chat history
|
||||
LLFloaterChat::addChatHistory(chat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,9 +184,11 @@
|
|||
#include "llpostprocess.h"
|
||||
#include "llbottomtray.h"
|
||||
|
||||
#include "llnotificationmanager.h"
|
||||
|
||||
#include "llfloaternotificationsconsole.h"
|
||||
|
||||
#include "llnearbychathistory.h"
|
||||
#include "llnearbychat.h"
|
||||
|
||||
#if LL_WINDOWS
|
||||
#include <tchar.h> // For Unicode conversion methods
|
||||
|
|
@ -1641,6 +1643,15 @@ void LLViewerWindow::initWorldUI()
|
|||
getRootView()->sendChildToFront(gNotifyBoxView);
|
||||
// menu holder appears on top to get first pass at all mouse events
|
||||
getRootView()->sendChildToFront(gMenuHolder);
|
||||
|
||||
//Channel Manager
|
||||
LLNotificationsUI::LLChannelManager * channel_manager
|
||||
= LLNotificationsUI::LLChannelManager::getInstance();
|
||||
getRootView()->addChild(channel_manager);
|
||||
//Notification Manager
|
||||
LLNotificationsUI::LLNotificationManager* notify_manager =
|
||||
LLNotificationsUI::LLNotificationManager::getInstance();
|
||||
getRootView()->addChild(notify_manager);
|
||||
}
|
||||
|
||||
// Destroy the UI
|
||||
|
|
@ -2384,6 +2395,29 @@ void LLViewerWindow::moveCursorToCenter()
|
|||
LLUI::setCursorPositionScreen(x, y);
|
||||
}
|
||||
|
||||
void LLViewerWindow::updateBottomTrayRect()
|
||||
{
|
||||
if(LLBottomTray::instanceExists() && LLSideTray::instanceCreated())
|
||||
{
|
||||
S32 side_tray_width = 0;
|
||||
if(LLSideTray::getInstance()->getVisible())
|
||||
{
|
||||
side_tray_width = LLSideTray::getInstance()->getTrayWidth();
|
||||
}
|
||||
|
||||
LLBottomTray* bottom_tray = LLBottomTray::getInstance();
|
||||
S32 right = llround((F32)mWindowRect.mRight / mDisplayScale.mV[VX]) - side_tray_width;
|
||||
|
||||
LLRect rc = bottom_tray->getRect();
|
||||
if (right != rc.mRight)
|
||||
{
|
||||
rc.mRight = right;
|
||||
bottom_tray->reshape(rc.getWidth(), rc.getHeight(), FALSE);
|
||||
bottom_tray->setRect(rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Hover handlers
|
||||
|
|
@ -2397,15 +2431,7 @@ void LLViewerWindow::updateUI()
|
|||
|
||||
updateWorldViewRect();
|
||||
|
||||
if(LLBottomTray::instanceExists() && LLSideTray::instanceCreated())
|
||||
{
|
||||
S32 delta = 0;
|
||||
if(LLSideTray::getInstance()->getVisible())
|
||||
{
|
||||
delta = llround((F32)LLSideTray::getInstance()->getTrayWidth() * mDisplayScale.mV[VX]);
|
||||
}
|
||||
LLBottomTray::getInstance()->updateRightPosition(mWindowRect.mRight - delta);
|
||||
}
|
||||
updateBottomTrayRect();
|
||||
|
||||
LLView::sMouseHandlerMessage.clear();
|
||||
|
||||
|
|
|
|||
|
|
@ -278,6 +278,7 @@ public:
|
|||
void updatePicking(S32 x, S32 y, MASK mask);
|
||||
|
||||
void updateWorldViewRect(bool use_full_window=false);
|
||||
void updateBottomTrayRect();
|
||||
|
||||
BOOL handleKey(KEY key, MASK mask);
|
||||
void handleScrollWheel (S32 clicks);
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@
|
|||
#include "llfloatertools.h"
|
||||
#include "llhudeffectlookat.h"
|
||||
#include "llhudmanager.h"
|
||||
#include "llinventoryview.h"
|
||||
#include "lljoystickbutton.h"
|
||||
#include "llmenugl.h"
|
||||
#include "llmorphview.h"
|
||||
|
|
|
|||
|
|
@ -28,5 +28,5 @@
|
|||
color="1 1 1 1" enabled="true" image_name="closebox.tga"
|
||||
name="close_btn"/>
|
||||
</panel>
|
||||
<chat_history_view bottom="0" width="250" height="320" follows="left|right|top|bottom" name="chat_scroll" />
|
||||
<chat_items_container bottom="0" width="250" height="320" follows="left|right|top|bottom" name="chat_history" />
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<menu bottom="100" color="MenuDefaultBgColor" drop_shadow="true" height="101" left="100"
|
||||
mouse_opaque="false" name="NearBy Chat Menu" opaque="true" width="128" visible="false">
|
||||
<menu_item_call bottom_delta="-18" height="18" label="Keep Visible" left="0" mouse_opaque="true"
|
||||
name="keep_visible" width="128">
|
||||
<menu_item_call.on_click function="NearbyChat.Action" userdata="keep_visible" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom_delta="-18" height="18" label="Show Nearby People..." left="0" mouse_opaque="true"
|
||||
name="nearby_people" width="128">
|
||||
<menu_item_call.on_click function="NearbyChat.Action" userdata="nearby_people" />
|
||||
|
|
|
|||
|
|
@ -301,9 +301,11 @@
|
|||
height="20"
|
||||
left="22"
|
||||
top="23"/>
|
||||
<!--
|
||||
<chiclet_notification.commit_callback
|
||||
function="Notification.Show"
|
||||
parameter="ClickUnimplemented" />
|
||||
-->
|
||||
</chiclet_notification>
|
||||
</layout_panel>
|
||||
<icon
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<!-- All our XML is utf-8 encoded. -->
|
||||
|
||||
<panel
|
||||
name="instant_message"
|
||||
width="300"
|
||||
height="180"
|
||||
background_opaque="false"
|
||||
background_visible="true"
|
||||
follows="left|top|right|bottom"
|
||||
bg_alpha_color="0.3 0.3 0.3 1.0">
|
||||
<panel width="250" height="30" background_visible="true" background_opaque="false" bg_alpha_color="0.0 0.0 0.0 1.0" name="msg_caption">
|
||||
<avatar_icon
|
||||
top="25" left="10" width="20" height="20" follows="left|top"
|
||||
color="1 1 1 1" enabled="true" name="avatar_icon"
|
||||
/>
|
||||
<text
|
||||
width="160" top="25" left="40" height="20" follows="left|right|top"
|
||||
font="SansSerifBigBold" text_color="white" word_wrap="true"
|
||||
mouse_opaque="true" name="sender_name" >
|
||||
Jerry Knight
|
||||
</text>
|
||||
<icon top="22" left="170" width="15" height="15" follows="top|right"
|
||||
image_name="icn_voice-pvtfocus.tga" visible="false" name="msg_inspector"/>
|
||||
<icon top="22" left="190" width="10" height="10" follows="top|right"
|
||||
image_name="speaking_indicator.tga" name="msg_icon"/>
|
||||
<text width="35" top="22" left="205" height="20" follows="right|top"
|
||||
text_color="white" word_wrap="true" mouse_opaque="true" name="msg_time" >
|
||||
10:32
|
||||
</text>
|
||||
</panel>
|
||||
<text_chat
|
||||
top="-35" left="10" right="-10" height="120" follows="left|right|bottom"
|
||||
font="SansSerifSmall" text_color="white" word_wrap="true"
|
||||
mouse_opaque="true" name="msg_text" >
|
||||
</text_chat>
|
||||
</panel>
|
||||
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel background_visible="true" bevel_style="in" bg_alpha_color="0 0 0 0"
|
||||
height="200" label="instant_message" layout="topleft" left="0"
|
||||
name="panel_group_notify" top="0" width="350">
|
||||
<panel background_visible="true" bevel_style="in" bg_alpha_color="black"
|
||||
height="50" label="header" layout="topleft" left="0" name="header"
|
||||
top="0" width="350">
|
||||
<icon follows="left|top|right|bottom" height="40" width="40" layout="topleft"
|
||||
top="5" left="5" mouse_opaque="true" name="group_icon"/>
|
||||
<text type="string" length="1" follows="left|top|right|bottom"
|
||||
font="SansSerifBigBold" height="20" layout="topleft" left="60" name="title"
|
||||
text_color="white" top="20" width="300">
|
||||
Sender Name / Group Name
|
||||
</text>
|
||||
</panel>
|
||||
<text_editor type="string" length="1" bg_readonly_color="0 0 0 0"
|
||||
follows="left|top|right|bottom" height="70" hide_scrollbar="true"
|
||||
hide_border="true" layout="topleft" top="55" left="25" name="message"
|
||||
text_color="white" text_readonly_color="white" width="300" word_wrap="true">
|
||||
Message
|
||||
Body
|
||||
</text_editor>
|
||||
<text font="SansSerif" font.style="UNDERLINE" font_shadow="hard"
|
||||
type="string" length="1" follows="left|top|right|bottom" layout="topleft"
|
||||
left="25" top="135" height="15" width="300" name="attachment"
|
||||
text_color="white">
|
||||
Attachment
|
||||
</text>
|
||||
<button label="OK" layout="topleft" top="170" left="140" height="20"
|
||||
width="70" name="btn_ok" />
|
||||
</panel>
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
top_delta="0"
|
||||
width="60" />
|
||||
<button
|
||||
enabled="false"
|
||||
enabled="true"
|
||||
follows="bottom|right"
|
||||
font="SansSerifSmallBold"
|
||||
height="25"
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
background_visible="true"
|
||||
bg_opaque_color="0.5 0.5 0.5 1.0"
|
||||
>
|
||||
<accordionctrl_tab
|
||||
<accordion_tab
|
||||
name="people_accordion"
|
||||
title="People"
|
||||
collapsable="true"
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
label="People"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
</accordion_tab>
|
||||
</sidetray_tab>
|
||||
<!-- *TODO Vadim: isn't the sidetray_tab "label" attribute redundant since we have "tab_title" ? -->
|
||||
<sidetray_tab
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
background_visible="true"
|
||||
bg_opaque_color="0.5 0.5 0.5 1.0"
|
||||
>
|
||||
<accordionctrl_tab
|
||||
<accordion_tab
|
||||
name="places_accordian"
|
||||
title="Places"
|
||||
collapsable="true"
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
label="Places"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
</accordion_tab>
|
||||
</sidetray_tab>
|
||||
|
||||
<sidetray_tab
|
||||
|
|
@ -75,7 +75,7 @@
|
|||
background_visible="true"
|
||||
bg_opaque_color="0.5 0.5 0.5 1.0"
|
||||
>
|
||||
<accordionctrl_tab
|
||||
<accordion_tab
|
||||
name="me_accordion"
|
||||
title="Me"
|
||||
collapsable="false"
|
||||
|
|
@ -90,7 +90,7 @@
|
|||
label="Me"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
</accordion_tab>
|
||||
</sidetray_tab>
|
||||
|
||||
<!--
|
||||
|
|
@ -103,7 +103,7 @@
|
|||
tab_title="Groups"
|
||||
description="Manage Groups."
|
||||
>
|
||||
<accordionctrl_tab
|
||||
<accordion_tab
|
||||
name="group_accordion"
|
||||
title="Group General"
|
||||
expanded="true"
|
||||
|
|
@ -119,8 +119,8 @@
|
|||
label="Group"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="groupland_accordion"
|
||||
title="Group Land and Money"
|
||||
expanded="false"
|
||||
|
|
@ -136,8 +136,8 @@
|
|||
label="Group"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="groupnotices_accordion"
|
||||
title="Group Notices"
|
||||
expanded="false"
|
||||
|
|
@ -153,8 +153,8 @@
|
|||
label="Group"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="grouproles_accordion"
|
||||
title="Group Roles"
|
||||
expanded="false"
|
||||
|
|
@ -170,7 +170,7 @@
|
|||
label="Group"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
</accordion_tab>
|
||||
</sidetray_tab>
|
||||
|
||||
|
||||
|
|
@ -184,7 +184,7 @@
|
|||
tab_title="Previews"
|
||||
description="Previews."
|
||||
>
|
||||
<accordionctrl_tab
|
||||
<accordion_tab
|
||||
name="floater_preview_animation"
|
||||
title="Preview Animation"
|
||||
collapsable="true"
|
||||
|
|
@ -202,8 +202,8 @@
|
|||
label="Preview_Animation"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="floater_preview_gesture"
|
||||
title="Preview Gesture"
|
||||
collapsable="true"
|
||||
|
|
@ -221,8 +221,8 @@
|
|||
label="Preview_Gesture"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="floater_preview_existing_landmark"
|
||||
title="Preview Existing Landmark"
|
||||
collapsable="true"
|
||||
|
|
@ -240,8 +240,8 @@
|
|||
label="Preview_Existing_Landmark"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="floater_preview_sound"
|
||||
title="Preview Sound"
|
||||
collapsable="true"
|
||||
|
|
@ -259,8 +259,8 @@
|
|||
label="Preview_Sound"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="floater_preview_url"
|
||||
title="Preview URL"
|
||||
collapsable="true"
|
||||
|
|
@ -278,8 +278,8 @@
|
|||
label="Preview_URL"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="floater_URL_entry"
|
||||
title="URL Entry"
|
||||
collapsable="true"
|
||||
|
|
@ -297,7 +297,7 @@
|
|||
label="URL_entry"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
</accordion_tab>
|
||||
</sidetray_tab>
|
||||
|
||||
<sidetray_tab
|
||||
|
|
@ -310,7 +310,7 @@
|
|||
tab_title="Region"
|
||||
description="Region."
|
||||
>
|
||||
<accordionctrl_tab
|
||||
<accordion_tab
|
||||
name="panel_region_covenant"
|
||||
title="Region Covenant"
|
||||
collapsable="true"
|
||||
|
|
@ -328,8 +328,8 @@
|
|||
label="Panel_Region_Covenant"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="panel_region_debug"
|
||||
title="Region Debug"
|
||||
collapsable="true"
|
||||
|
|
@ -347,8 +347,8 @@
|
|||
label="Panel_Region_Debug"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="panel_region_estate"
|
||||
title="Region Estate"
|
||||
collapsable="true"
|
||||
|
|
@ -366,8 +366,8 @@
|
|||
label="Panel_Region_Estate"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="panel_region_general"
|
||||
title="Region General"
|
||||
collapsable="true"
|
||||
|
|
@ -385,8 +385,8 @@
|
|||
label="Panel_Region_General"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="panel_region_terrain"
|
||||
title="Region Terrain"
|
||||
collapsable="true"
|
||||
|
|
@ -404,8 +404,8 @@
|
|||
label="Panel_Region_Terrain"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="panel_region_texture"
|
||||
title="Region Texture"
|
||||
collapsable="true"
|
||||
|
|
@ -423,8 +423,8 @@
|
|||
label="Panel_Region_Texture"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="floater_region_info"
|
||||
title="Region Info"
|
||||
collapsable="true"
|
||||
|
|
@ -442,7 +442,7 @@
|
|||
label="Floater_Region_Info"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
</accordion_tab>
|
||||
</sidetray_tab>
|
||||
|
||||
<sidetray_tab
|
||||
|
|
@ -455,7 +455,7 @@
|
|||
tab_title="Build"
|
||||
description="Build"
|
||||
>
|
||||
<accordionctrl_tab
|
||||
<accordion_tab
|
||||
name="floater_tools"
|
||||
title="Tools"
|
||||
collapsable="true"
|
||||
|
|
@ -473,8 +473,8 @@
|
|||
label="Tools"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="floater_bulk_perms"
|
||||
title="Bulk Perms"
|
||||
collapsable="true"
|
||||
|
|
@ -492,8 +492,8 @@
|
|||
label="Tools"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="floater_build_options"
|
||||
title="Build Options"
|
||||
collapsable="true"
|
||||
|
|
@ -511,7 +511,7 @@
|
|||
label="Tools"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
</accordion_tab>
|
||||
|
||||
</sidetray_tab>
|
||||
|
||||
|
|
@ -525,7 +525,7 @@
|
|||
tab_title="Other Tools"
|
||||
description="Other Tools"
|
||||
>
|
||||
<accordionctrl_tab
|
||||
<accordion_tab
|
||||
name="floater_gesture"
|
||||
title="Gestures"
|
||||
collapsable="true"
|
||||
|
|
@ -543,9 +543,9 @@
|
|||
label="Gesture"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
</accordion_tab>
|
||||
|
||||
<accordionctrl_tab
|
||||
<accordion_tab
|
||||
name="floater_buy_contents"
|
||||
title="Buy Contents"
|
||||
collapsable="true"
|
||||
|
|
@ -563,8 +563,8 @@
|
|||
label="buy_contents"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="floater_buy_object"
|
||||
title="Buy Object"
|
||||
collapsable="true"
|
||||
|
|
@ -583,7 +583,7 @@
|
|||
border="true"
|
||||
/>
|
||||
</collapsible_ctrl>
|
||||
<accordionctrl_tab
|
||||
<accordion_tab
|
||||
name="floater_inventory_view_finder"
|
||||
title="Inventory View Finder"
|
||||
collapsable="true"
|
||||
|
|
@ -601,8 +601,8 @@
|
|||
label="view_finder"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="floater_mute"
|
||||
title="Mute"
|
||||
collapsable="true"
|
||||
|
|
@ -620,8 +620,8 @@
|
|||
label="mute"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="floater_sell_land"
|
||||
title="Sell Land"
|
||||
collapsable="true"
|
||||
|
|
@ -639,8 +639,8 @@
|
|||
label="sell_land"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
<accordionctrl_tab
|
||||
</accordion_tab>
|
||||
<accordion_tab
|
||||
name="floater_telehub"
|
||||
title="Telehub"
|
||||
collapsable="true"
|
||||
|
|
@ -658,7 +658,7 @@
|
|||
label="telehub"
|
||||
border="true"
|
||||
/>
|
||||
</accordionctrl_tab>
|
||||
</accordion_tab>
|
||||
|
||||
</sidetray_tab>
|
||||
-->
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<!-- All our XML is utf-8 encoded. -->
|
||||
|
||||
<panel
|
||||
name="toast"
|
||||
title="toast"
|
||||
visible="false"
|
||||
layout="topleft"
|
||||
width="350"
|
||||
height="72"
|
||||
left="100"
|
||||
top="500"
|
||||
follows="right|bottom"
|
||||
background_opaque="true"
|
||||
background_visible="true"
|
||||
bevel_style="in"
|
||||
bg_alpha_color="0.3 0.3 0.3 1.0">
|
||||
|
||||
<text
|
||||
type="string"
|
||||
visible="false"
|
||||
follows="left|top|right|bottom"
|
||||
font="SansSerifBold"
|
||||
height="40"
|
||||
layout="topleft"
|
||||
left="60"
|
||||
name="text"
|
||||
text_color="white"
|
||||
top="30"
|
||||
width="290">
|
||||
Toast text;
|
||||
</text>
|
||||
<icon
|
||||
top="20"
|
||||
left="10"
|
||||
width="32"
|
||||
height="32"
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
visible="false"
|
||||
color="1 1 1 1"
|
||||
enabled="true"
|
||||
image_name="notify_tip_icon.tga"
|
||||
mouse_opaque="true"
|
||||
name="icon"
|
||||
/>
|
||||
<button
|
||||
layout="topleft"
|
||||
top="-5"
|
||||
left="335"
|
||||
width="20"
|
||||
height="20"
|
||||
follows="top|right"
|
||||
visible="false"
|
||||
enabled="true"
|
||||
mouse_opaque="true"
|
||||
name="hide_btn"
|
||||
label=""
|
||||
image_unselected="toast_hide_btn.tga"
|
||||
image_disabled="toast_hide_btn.tga"
|
||||
image_selected="toast_hide_btn.tga"
|
||||
image_hover_selected="toast_hide_btn.tga"
|
||||
image_disabled_selected="toast_hide_btn.tga"
|
||||
/>
|
||||
</panel>
|
||||
Loading…
Reference in New Issue