merge https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0@1868 https://svn.aws.productengine.com/secondlife/pe/stable-2@1876 -> viewer-2.0.0-3
* Bugs: EXT-1111 EXT-915 EXT-1131 EXT-1200 EXT-1202 EXT-1201 EXT-1205 EXT-1212 EXT-1173 EXT-1229 EXT-1218 EXT-1164 EXT-996 EXT-821 EXT-1030 EXT-1031 EXT-816 * Major Bugs: EXT-1142 (timeout during login due to processing group IMs) * Changes: EXT-1216 (minimize message well)master
parent
090977608d
commit
f05df68656
|
|
@ -85,6 +85,7 @@ set(llui_SOURCE_FILES
|
|||
lltextbox.cpp
|
||||
lltexteditor.cpp
|
||||
lltextparser.cpp
|
||||
lltransientfloatermgr.cpp
|
||||
lltransutil.cpp
|
||||
lltooltip.cpp
|
||||
llui.cpp
|
||||
|
|
@ -171,6 +172,7 @@ set(llui_HEADER_FILES
|
|||
lltexteditor.h
|
||||
lltextparser.h
|
||||
lltooltip.h
|
||||
lltransientfloatermgr.h
|
||||
lltransutil.h
|
||||
lluicolortable.h
|
||||
lluiconstants.h
|
||||
|
|
|
|||
|
|
@ -71,9 +71,9 @@ void LLDockableFloater::resetInstance()
|
|||
if (sInstanceHandle.get() != NULL && sInstanceHandle.get()->isDocked())
|
||||
{
|
||||
sInstanceHandle.get()->setVisible(FALSE);
|
||||
}
|
||||
}
|
||||
sInstanceHandle = getHandle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLDockableFloater::setVisible(BOOL visible)
|
||||
|
|
@ -105,11 +105,11 @@ void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
|
|||
mDockControl.get()->off();
|
||||
}
|
||||
|
||||
if (!docked && pop_on_undock)
|
||||
{
|
||||
// visually pop up a little bit to emphasize the undocking
|
||||
translate(0, UNDOCK_LEAP_HEIGHT);
|
||||
}
|
||||
if (!docked && pop_on_undock)
|
||||
{
|
||||
// visually pop up a little bit to emphasize the undocking
|
||||
translate(0, UNDOCK_LEAP_HEIGHT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -126,8 +126,8 @@ void LLDockableFloater::draw()
|
|||
mDockControl.get()->repositionDockable();
|
||||
if (isDocked())
|
||||
{
|
||||
mDockControl.get()->drawToungue();
|
||||
}
|
||||
mDockControl.get()->drawToungue();
|
||||
}
|
||||
}
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#include "lldockcontrol.h"
|
||||
|
||||
LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
|
||||
const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback) :
|
||||
const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
|
||||
mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(dockTongue)
|
||||
{
|
||||
mDockAt = dockAt;
|
||||
|
|
@ -49,13 +49,13 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
|
|||
off();
|
||||
}
|
||||
|
||||
if (!(get_rect_callback))
|
||||
if (!(get_allowed_rect_callback))
|
||||
{
|
||||
mGetRectCallback = boost::bind(&LLDockControl::getEnabledRect, this, _1);
|
||||
mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
|
||||
}
|
||||
else
|
||||
{
|
||||
mGetRectCallback = get_rect_callback;
|
||||
mGetAllowedRectCallback = get_allowed_rect_callback;
|
||||
}
|
||||
|
||||
if (dockWidget != NULL)
|
||||
|
|
@ -77,7 +77,7 @@ void LLDockControl::setDock(LLView* dockWidget)
|
|||
}
|
||||
}
|
||||
|
||||
void LLDockControl::getEnabledRect(LLRect& rect)
|
||||
void LLDockControl::getAllowedRect(LLRect& rect)
|
||||
{
|
||||
rect = mDockableFloater->getRootView()->getRect();
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ void LLDockControl::repositionDockable()
|
|||
{
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
LLRect rootRect;
|
||||
mGetRectCallback(rootRect);
|
||||
mGetAllowedRectCallback(rootRect);
|
||||
static BOOL prev_visibility = !mDockWidget->getVisible();
|
||||
|
||||
// recalculate dockable position if dock position changed, dock visibility changed,
|
||||
|
|
@ -100,7 +100,7 @@ void LLDockControl::repositionDockable()
|
|||
mDockableFloater->setDocked(false);
|
||||
// force off() since dockable may not have dockControll at this time
|
||||
off();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
moveDockable();
|
||||
|
|
@ -123,10 +123,10 @@ bool LLDockControl::isDockVisible()
|
|||
res = mDockWidget->isInVisibleChain();
|
||||
if (res)
|
||||
{
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
|
||||
switch (mDockAt)
|
||||
{
|
||||
{
|
||||
case TOP:
|
||||
// check is dock inside parent rect
|
||||
LLRect dockParentRect =
|
||||
|
|
@ -149,25 +149,25 @@ void LLDockControl::moveDockable()
|
|||
// calculate new dockable position
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
LLRect rootRect;
|
||||
mGetRectCallback(rootRect);
|
||||
mGetAllowedRectCallback(rootRect);
|
||||
|
||||
LLRect dockableRect = mDockableFloater->calcScreenRect();
|
||||
S32 x = 0;
|
||||
S32 y = 0;
|
||||
switch (mDockAt)
|
||||
{
|
||||
case TOP:
|
||||
x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
|
||||
LLRect dockableRect = mDockableFloater->calcScreenRect();
|
||||
S32 x = 0;
|
||||
S32 y = 0;
|
||||
switch (mDockAt)
|
||||
{
|
||||
case TOP:
|
||||
x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
|
||||
y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
|
||||
// check is dockable inside root view rect
|
||||
if (x < rootRect.mLeft)
|
||||
{
|
||||
x = rootRect.mLeft;
|
||||
}
|
||||
if (x + dockableRect.getWidth() > rootRect.mRight)
|
||||
{
|
||||
x = rootRect.mRight - dockableRect.getWidth();
|
||||
}
|
||||
if (x < rootRect.mLeft)
|
||||
{
|
||||
x = rootRect.mLeft;
|
||||
}
|
||||
if (x + dockableRect.getWidth() > rootRect.mRight)
|
||||
{
|
||||
x = rootRect.mRight - dockableRect.getWidth();
|
||||
}
|
||||
|
||||
|
||||
// calculate dock tongue position
|
||||
|
|
@ -185,21 +185,21 @@ void LLDockControl::moveDockable()
|
|||
{
|
||||
mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
|
||||
}
|
||||
mDockTongueY = dockRect.mTop;
|
||||
mDockTongueY = dockRect.mTop;
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// move dockable
|
||||
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
|
||||
dockableRect.getHeight());
|
||||
LLRect localDocableParentRect;
|
||||
mDockableFloater->getParent()->screenRectToLocal(dockableRect,
|
||||
&localDocableParentRect);
|
||||
mDockableFloater->setRect(localDocableParentRect);
|
||||
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
|
||||
dockableRect.getHeight());
|
||||
LLRect localDocableParentRect;
|
||||
mDockableFloater->getParent()->screenRectToLocal(dockableRect,
|
||||
&localDocableParentRect);
|
||||
mDockableFloater->setRect(localDocableParentRect);
|
||||
|
||||
mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
|
||||
&mDockTongueX, &mDockTongueY);
|
||||
mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
|
||||
&mDockTongueX, &mDockTongueY);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -207,9 +207,9 @@ void LLDockControl::on()
|
|||
{
|
||||
if (isDockVisible())
|
||||
{
|
||||
mDockableFloater->setCanDrag(false);
|
||||
mEnabled = true;
|
||||
mRecalculateDocablePosition = true;
|
||||
mDockableFloater->setCanDrag(false);
|
||||
mEnabled = true;
|
||||
mRecalculateDocablePosition = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@ public:
|
|||
|
||||
public:
|
||||
// callback for a function getting a rect valid for control's position
|
||||
typedef boost::function<void (LLRect& )> get_rect_callback_t;
|
||||
typedef boost::function<void (LLRect& )> get_allowed_rect_callback_t;
|
||||
|
||||
LOG_CLASS(LLDockControl);
|
||||
LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
|
||||
const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback = NULL);
|
||||
const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_rect_callback = NULL);
|
||||
virtual ~LLDockControl();
|
||||
|
||||
public:
|
||||
|
|
@ -67,13 +67,13 @@ public:
|
|||
void drawToungue();
|
||||
bool isDockVisible();
|
||||
|
||||
// gets a rect that bounds possible positions for a dockable control
|
||||
void getEnabledRect(LLRect& rect);
|
||||
// gets a rect that bounds possible positions for a dockable control (EXT-1111)
|
||||
void getAllowedRect(LLRect& rect);
|
||||
|
||||
private:
|
||||
virtual void moveDockable();
|
||||
private:
|
||||
get_rect_callback_t mGetRectCallback;
|
||||
get_allowed_rect_callback_t mGetAllowedRectCallback;
|
||||
bool mEnabled;
|
||||
bool mRecalculateDocablePosition;
|
||||
DocAt mDockAt;
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@
|
|||
|
||||
static const LLDefaultChildRegistry::Register<LLFlatListView> flat_list_view("flat_list_view");
|
||||
|
||||
const LLSD SELECTED_EVENT = LLSD().insert("selected", true);
|
||||
const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
|
||||
const LLSD SELECTED_EVENT = LLSD().insert("selected", true);
|
||||
const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
|
||||
|
||||
static const std::string COMMENT_TEXTBOX = "comment_text";
|
||||
|
||||
|
|
|
|||
|
|
@ -2001,6 +2001,8 @@ void LLTextEditor::cut()
|
|||
deleteSelection( FALSE );
|
||||
|
||||
needsReflow();
|
||||
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
BOOL LLTextEditor::canCopy() const
|
||||
|
|
@ -2105,6 +2107,8 @@ void LLTextEditor::pasteHelper(bool is_primary)
|
|||
deselect();
|
||||
|
||||
needsReflow();
|
||||
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2492,6 +2496,8 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
|
|||
if(text_may_have_changed)
|
||||
{
|
||||
needsReflow();
|
||||
|
||||
onKeyStroke();
|
||||
}
|
||||
needsScroll();
|
||||
}
|
||||
|
|
@ -2534,6 +2540,8 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
|
|||
deselect();
|
||||
|
||||
needsReflow();
|
||||
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
return handled;
|
||||
|
|
@ -2588,6 +2596,8 @@ void LLTextEditor::doDelete()
|
|||
setCursorPos(mCursorPos + 1);
|
||||
removeChar();
|
||||
}
|
||||
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
needsReflow();
|
||||
|
|
@ -2634,6 +2644,8 @@ void LLTextEditor::undo()
|
|||
setCursorPos(pos);
|
||||
|
||||
needsReflow();
|
||||
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
BOOL LLTextEditor::canRedo() const
|
||||
|
|
@ -2676,6 +2688,8 @@ void LLTextEditor::redo()
|
|||
setCursorPos(pos);
|
||||
|
||||
needsReflow();
|
||||
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
void LLTextEditor::onFocusReceived()
|
||||
|
|
@ -4402,6 +4416,8 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
|
|||
|
||||
// Update of the preedit should be caused by some key strokes.
|
||||
mKeystrokeTimer.reset();
|
||||
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
|
||||
|
|
@ -4648,3 +4664,30 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
|
|||
ed->addDocumentChild(mView);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLTextEditor::isDirty() const
|
||||
{
|
||||
if(mReadOnly)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( mPristineCmd )
|
||||
{
|
||||
return ( mPristineCmd == mLastCmd );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( NULL != mLastCmd );
|
||||
}
|
||||
}
|
||||
|
||||
void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& callback)
|
||||
{
|
||||
mKeystrokeSignal.connect(callback);
|
||||
}
|
||||
|
||||
void LLTextEditor::onKeyStroke()
|
||||
{
|
||||
mKeystrokeSignal(this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,6 +139,10 @@ public:
|
|||
|
||||
virtual ~LLTextEditor();
|
||||
|
||||
typedef boost::signals2::signal<void (LLTextEditor* caller)> keystroke_signal_t;
|
||||
|
||||
void setKeystrokeCallback(const keystroke_signal_t::slot_type& callback);
|
||||
|
||||
void setParseHighlights(BOOL parsing) {mParseHighlights=parsing;}
|
||||
|
||||
// mousehandler overrides
|
||||
|
|
@ -169,7 +173,7 @@ public:
|
|||
virtual void clear();
|
||||
virtual void setFocus( BOOL b );
|
||||
virtual BOOL acceptsTextInput() const;
|
||||
virtual BOOL isDirty() const { return isPristine(); }
|
||||
virtual BOOL isDirty() const;
|
||||
virtual void setValue(const LLSD& value);
|
||||
|
||||
// LLEditMenuHandler interface
|
||||
|
|
@ -503,6 +507,8 @@ private:
|
|||
|
||||
S32 getFirstVisibleLine() const;
|
||||
|
||||
void onKeyStroke();
|
||||
|
||||
//
|
||||
// Data
|
||||
//
|
||||
|
|
@ -568,6 +574,8 @@ private:
|
|||
BOOL mHandleEditKeysDirectly;
|
||||
|
||||
LLCoordGL mLastIMEPosition; // Last position of the IME editor
|
||||
|
||||
keystroke_signal_t mKeystrokeSignal;
|
||||
}; // end class LLTextEditor
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@
|
|||
|
||||
static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
|
||||
|
||||
// Maximum number of avatars that can be added to a list in one pass.
|
||||
// Used to limit time spent for avatar list update per frame.
|
||||
static const unsigned ADD_LIMIT = 50;
|
||||
|
||||
static bool findInsensitive(std::string haystack, const std::string& needle_upper)
|
||||
{
|
||||
LLStringUtil::toUpper(haystack);
|
||||
|
|
@ -65,6 +69,7 @@ LLAvatarList::LLAvatarList(const Params& p)
|
|||
: LLFlatListView(p)
|
||||
, mOnlineGoFirst(p.online_go_first)
|
||||
, mContextMenu(NULL)
|
||||
, mDirty(true) // to force initial update
|
||||
{
|
||||
setCommitOnSelectionChange(true);
|
||||
|
||||
|
|
@ -72,6 +77,138 @@ LLAvatarList::LLAvatarList(const Params& p)
|
|||
setComparator(&NAME_COMPARATOR);
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLAvatarList::draw()
|
||||
{
|
||||
if (mDirty)
|
||||
refresh();
|
||||
|
||||
LLFlatListView::draw();
|
||||
}
|
||||
|
||||
void LLAvatarList::setNameFilter(const std::string& filter)
|
||||
{
|
||||
if (mNameFilter != filter)
|
||||
{
|
||||
mNameFilter = filter;
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
void LLAvatarList::sortByName()
|
||||
{
|
||||
setComparator(&NAME_COMPARATOR);
|
||||
sort();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PROTECTED SECTION
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void LLAvatarList::refresh()
|
||||
{
|
||||
bool have_names = TRUE;
|
||||
bool add_limit_exceeded = false;
|
||||
bool modified = false;
|
||||
bool have_filter = !mNameFilter.empty();
|
||||
|
||||
// Save selection.
|
||||
std::vector<LLUUID> selected_ids;
|
||||
getSelectedUUIDs(selected_ids);
|
||||
LLUUID current_id = getSelectedUUID();
|
||||
|
||||
// Determine what to add and what to remove.
|
||||
std::vector<LLUUID> added, removed;
|
||||
LLAvatarList::computeDifference(getIDs(), added, removed);
|
||||
|
||||
// Handle added items.
|
||||
unsigned nadded = 0;
|
||||
for (std::vector<LLUUID>::const_iterator it=added.begin(); it != added.end(); it++)
|
||||
{
|
||||
std::string name;
|
||||
const LLUUID& buddy_id = *it;
|
||||
have_names &= (bool)gCacheName->getFullName(buddy_id, name);
|
||||
if (!have_filter || findInsensitive(name, mNameFilter))
|
||||
{
|
||||
if (nadded >= ADD_LIMIT)
|
||||
{
|
||||
add_limit_exceeded = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
|
||||
modified = true;
|
||||
nadded++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle removed items.
|
||||
for (std::vector<LLUUID>::const_iterator it=removed.begin(); it != removed.end(); it++)
|
||||
{
|
||||
removeItemByUUID(*it);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
// Handle filter.
|
||||
if (have_filter)
|
||||
{
|
||||
std::vector<LLSD> cur_values;
|
||||
getValues(cur_values);
|
||||
|
||||
for (std::vector<LLSD>::const_iterator it=cur_values.begin(); it != cur_values.end(); it++)
|
||||
{
|
||||
std::string name;
|
||||
const LLUUID& buddy_id = it->asUUID();
|
||||
have_names &= (bool)gCacheName->getFullName(buddy_id, name);
|
||||
if (!findInsensitive(name, mNameFilter))
|
||||
{
|
||||
removeItemByUUID(buddy_id);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Changed item in place, need to request sort and update columns
|
||||
// because we might have changed data in a column on which the user
|
||||
// has already sorted. JC
|
||||
sort();
|
||||
|
||||
// re-select items
|
||||
// selectMultiple(selected_ids); // TODO: implement in LLFlatListView if need
|
||||
selectItemByUUID(current_id);
|
||||
|
||||
// If the name filter is specified and the names are incomplete,
|
||||
// we need to re-update when the names are complete so that
|
||||
// the filter can be applied correctly.
|
||||
//
|
||||
// Otherwise, if we have no filter then no need to update again
|
||||
// because the items will update their names.
|
||||
bool dirty = add_limit_exceeded || (have_filter && !have_names);
|
||||
setDirty(dirty);
|
||||
|
||||
// Commit if we've added/removed items.
|
||||
if (modified)
|
||||
onCommit();
|
||||
}
|
||||
|
||||
|
||||
void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
|
||||
{
|
||||
LLAvatarListItem* item = new LLAvatarListItem();
|
||||
item->showStatus(false);
|
||||
item->showInfoBtn(true);
|
||||
item->showSpeakingIndicator(true);
|
||||
item->setName(name);
|
||||
item->setAvatarId(id);
|
||||
item->setContextMenu(mContextMenu);
|
||||
|
||||
item->childSetVisible("info_btn", false);
|
||||
|
||||
addItem(item, id, pos);
|
||||
}
|
||||
|
||||
void LLAvatarList::computeDifference(
|
||||
const std::vector<LLUUID>& vnew_unsorted,
|
||||
std::vector<LLUUID>& vadded,
|
||||
|
|
@ -106,97 +243,6 @@ void LLAvatarList::computeDifference(
|
|||
vadded.erase(it, vadded.end());
|
||||
}
|
||||
|
||||
BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
|
||||
{
|
||||
BOOL have_names = TRUE;
|
||||
bool have_filter = name_filter != LLStringUtil::null;
|
||||
|
||||
// Save selection.
|
||||
std::vector<LLUUID> selected_ids;
|
||||
getSelectedUUIDs(selected_ids);
|
||||
LLUUID current_id = getSelectedUUID();
|
||||
|
||||
// Determine what to add and what to remove.
|
||||
std::vector<LLUUID> added, removed;
|
||||
LLAvatarList::computeDifference(all_buddies, added, removed);
|
||||
|
||||
// Handle added items.
|
||||
for (std::vector<LLUUID>::const_iterator it=added.begin(); it != added.end(); it++)
|
||||
{
|
||||
std::string name;
|
||||
const LLUUID& buddy_id = *it;
|
||||
have_names &= gCacheName->getFullName(buddy_id, name);
|
||||
if (!have_filter || findInsensitive(name, name_filter))
|
||||
addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
|
||||
}
|
||||
|
||||
// Handle removed items.
|
||||
for (std::vector<LLUUID>::const_iterator it=removed.begin(); it != removed.end(); it++)
|
||||
{
|
||||
removeItemByUUID(*it);
|
||||
}
|
||||
|
||||
// Handle filter.
|
||||
if (have_filter)
|
||||
{
|
||||
std::vector<LLSD> cur_values;
|
||||
getValues(cur_values);
|
||||
|
||||
for (std::vector<LLSD>::const_iterator it=cur_values.begin(); it != cur_values.end(); it++)
|
||||
{
|
||||
std::string name;
|
||||
const LLUUID& buddy_id = it->asUUID();
|
||||
have_names &= gCacheName->getFullName(buddy_id, name);
|
||||
if (!findInsensitive(name, name_filter))
|
||||
removeItemByUUID(buddy_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Changed item in place, need to request sort and update columns
|
||||
// because we might have changed data in a column on which the user
|
||||
// has already sorted. JC
|
||||
sort();
|
||||
|
||||
// re-select items
|
||||
// selectMultiple(selected_ids); // TODO: implement in LLFlatListView if need
|
||||
selectItemByUUID(current_id);
|
||||
|
||||
// If the name filter is specified and the names are incomplete,
|
||||
// we need to re-update when the names are complete so that
|
||||
// the filter can be applied correctly.
|
||||
//
|
||||
// Otherwise, if we have no filter then no need to update again
|
||||
// because the items will update their names.
|
||||
return !have_filter || have_names;
|
||||
}
|
||||
|
||||
void LLAvatarList::sortByName()
|
||||
{
|
||||
setComparator(&NAME_COMPARATOR);
|
||||
sort();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PROTECTED SECTION
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
|
||||
{
|
||||
LLAvatarListItem* item = new LLAvatarListItem();
|
||||
item->showStatus(false);
|
||||
item->showInfoBtn(true);
|
||||
item->showSpeakingIndicator(true);
|
||||
item->setName(name);
|
||||
item->setAvatarId(id);
|
||||
item->setContextMenu(mContextMenu);
|
||||
|
||||
item->childSetVisible("info_btn", false);
|
||||
|
||||
addItem(item, id, pos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool LLAvatarItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
|
||||
{
|
||||
const LLAvatarListItem* avatar_item1 = dynamic_cast<const LLAvatarListItem*>(item1);
|
||||
|
|
|
|||
|
|
@ -37,10 +37,22 @@
|
|||
|
||||
#include "llavatarlistitem.h"
|
||||
|
||||
/**
|
||||
* Generic list of avatars.
|
||||
*
|
||||
* Updates itself when it's dirty, using optional name filter.
|
||||
* To initiate update, modify the UUID list and call setDirty().
|
||||
*
|
||||
* @see getIDs()
|
||||
* @see setDirty()
|
||||
* @see setNameFilter()
|
||||
*/
|
||||
class LLAvatarList : public LLFlatListView
|
||||
{
|
||||
LOG_CLASS(LLAvatarList);
|
||||
public:
|
||||
typedef std::vector<LLUUID> uuid_vector_t;
|
||||
|
||||
struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
|
||||
{
|
||||
Optional<S32> volume_column_width;
|
||||
|
|
@ -51,14 +63,19 @@ public:
|
|||
LLAvatarList(const Params&);
|
||||
virtual ~LLAvatarList() {}
|
||||
|
||||
BOOL update(const std::vector<LLUUID>& all_buddies,
|
||||
const std::string& name_filter = LLStringUtil::null);
|
||||
virtual void draw(); // from LLView
|
||||
|
||||
void setNameFilter(const std::string& filter);
|
||||
void setDirty(bool val = true) { mDirty = val; }
|
||||
uuid_vector_t& getIDs() { return mIDs; }
|
||||
|
||||
void setContextMenu(LLAvatarListItem::ContextMenu* menu) { mContextMenu = menu; }
|
||||
|
||||
void sortByName();
|
||||
|
||||
protected:
|
||||
void refresh();
|
||||
|
||||
void addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
|
||||
void computeDifference(
|
||||
const std::vector<LLUUID>& vnew,
|
||||
|
|
@ -68,6 +85,10 @@ protected:
|
|||
private:
|
||||
|
||||
bool mOnlineGoFirst;
|
||||
bool mDirty;
|
||||
|
||||
std::string mNameFilter;
|
||||
uuid_vector_t mIDs;
|
||||
|
||||
LLAvatarListItem::ContextMenu* mContextMenu;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ LLIMChiclet* LLBottomTray::createIMChiclet(const LLUUID& session_id)
|
|||
case LLIMChiclet::TYPE_IM:
|
||||
return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id);
|
||||
case LLIMChiclet::TYPE_GROUP:
|
||||
case LLIMChiclet::TYPE_AD_HOC:
|
||||
return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id);
|
||||
case LLIMChiclet::TYPE_UNKNOWN:
|
||||
break;
|
||||
|
|
@ -231,7 +232,7 @@ void LLBottomTray::showBottomTrayContextMenu(S32 x, S32 y, MASK mask)
|
|||
mBottomTrayContextMenu->updateParent(LLMenuGL::sMenuContainer);
|
||||
LLMenuGL::showPopup(this, mBottomTrayContextMenu, x, y);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLBottomTray::showGestureButton(BOOL visible)
|
||||
|
|
@ -243,7 +244,7 @@ void LLBottomTray::showGestureButton(BOOL visible)
|
|||
mGestureCombo->setVisible(visible);
|
||||
|
||||
if (!visible)
|
||||
{
|
||||
{
|
||||
LLFloaterReg::hideFloaterInstance("gestures");
|
||||
r.mRight -= mGestureCombo->getRect().getWidth();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ LLScreenChannel* LLChannelManager::createNotificationChannel()
|
|||
p.channel_align = CA_RIGHT;
|
||||
|
||||
// Getting a Channel for our notifications
|
||||
return LLChannelManager::getInstance()->getChannel(p);
|
||||
return dynamic_cast<LLScreenChannel*> (LLChannelManager::getInstance()->createChannel(p));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
@ -113,7 +113,7 @@ void LLChannelManager::onLoginCompleted()
|
|||
LLChannelManager::Params p;
|
||||
p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
|
||||
p.channel_align = CA_RIGHT;
|
||||
mStartUpChannel = getChannel(p);
|
||||
mStartUpChannel = createChannel(p);
|
||||
|
||||
if(!mStartUpChannel)
|
||||
{
|
||||
|
|
@ -147,22 +147,32 @@ void LLChannelManager::onStartUpToastClose()
|
|||
LLScreenChannel::setStartUpToastShown();
|
||||
|
||||
// force NEARBY CHAT CHANNEL to repost all toasts if present
|
||||
LLScreenChannel* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
|
||||
nearby_channel->loadStoredToastsToChannel();
|
||||
nearby_channel->setCanStoreToasts(false);
|
||||
//LLScreenChannelBase* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
|
||||
//!!!!!!!!!!!!!!
|
||||
//FIXME
|
||||
//nearby_channel->loadStoredToastsToChannel();
|
||||
//nearby_channel->setCanStoreToasts(false);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLScreenChannel* LLChannelManager::getChannel(LLChannelManager::Params& p)
|
||||
|
||||
LLScreenChannelBase* LLChannelManager::addChannel(LLScreenChannelBase* channel)
|
||||
{
|
||||
LLScreenChannel* new_channel = NULL;
|
||||
if(!channel)
|
||||
return 0;
|
||||
|
||||
new_channel = findChannelByID(p.id);
|
||||
ChannelElem new_elem;
|
||||
new_elem.id = channel->getChannelID();
|
||||
new_elem.channel = channel;
|
||||
|
||||
if(new_channel)
|
||||
return new_channel;
|
||||
mChannelList.push_back(new_elem);
|
||||
|
||||
new_channel = new LLScreenChannel(p.id);
|
||||
return channel;
|
||||
}
|
||||
|
||||
LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)
|
||||
{
|
||||
LLScreenChannel* new_channel = new LLScreenChannel(p.id);
|
||||
|
||||
if(!new_channel)
|
||||
{
|
||||
|
|
@ -172,20 +182,26 @@ LLScreenChannel* LLChannelManager::getChannel(LLChannelManager::Params& p)
|
|||
{
|
||||
new_channel->setToastAlignment(p.toast_align);
|
||||
new_channel->setChannelAlignment(p.channel_align);
|
||||
new_channel->setDisplayToastsAlways(p.display_toasts_always);
|
||||
new_channel->setDisplayToastsAlways(p.display_toasts_always);
|
||||
|
||||
ChannelElem new_elem;
|
||||
new_elem.id = p.id;
|
||||
new_elem.channel = new_channel;
|
||||
|
||||
mChannelList.push_back(new_elem);
|
||||
addChannel(new_channel);
|
||||
}
|
||||
|
||||
return new_channel;
|
||||
}
|
||||
|
||||
LLScreenChannelBase* LLChannelManager::getChannel(LLChannelManager::Params& p)
|
||||
{
|
||||
LLScreenChannelBase* new_channel = findChannelByID(p.id);
|
||||
|
||||
if(new_channel)
|
||||
return new_channel;
|
||||
|
||||
return createChannel(p);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLScreenChannel* LLChannelManager::findChannelByID(const LLUUID id)
|
||||
LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID id)
|
||||
{
|
||||
std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
|
||||
if(it != mChannelList.end())
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
|
|||
public:
|
||||
struct Params
|
||||
{
|
||||
LLUUID id;
|
||||
bool display_toasts_always;
|
||||
LLUUID id;
|
||||
bool display_toasts_always;
|
||||
EToastAlignment toast_align;
|
||||
EChannelAlignment channel_align;
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ public:
|
|||
struct ChannelElem
|
||||
{
|
||||
LLUUID id;
|
||||
LLScreenChannel* channel;
|
||||
LLScreenChannelBase* channel;
|
||||
|
||||
ChannelElem() : id(LLUUID("")), channel(NULL) { }
|
||||
|
||||
|
|
@ -89,19 +89,23 @@ public:
|
|||
void onStartUpToastClose();
|
||||
|
||||
// creates a new ScreenChannel according to the given parameters or returns existing if present
|
||||
LLScreenChannel* getChannel(LLChannelManager::Params& p);
|
||||
LLScreenChannelBase* getChannel(LLChannelManager::Params& p);
|
||||
|
||||
LLScreenChannelBase* addChannel(LLScreenChannelBase* channel);
|
||||
|
||||
// returns a channel by its ID
|
||||
LLScreenChannel* findChannelByID(const LLUUID id);
|
||||
LLScreenChannelBase* findChannelByID(const LLUUID id);
|
||||
|
||||
// creator of the Notification channel, that is used in more than one handler
|
||||
LLScreenChannel* createNotificationChannel();
|
||||
LLScreenChannel* createNotificationChannel();
|
||||
|
||||
// remove channel methods
|
||||
void removeChannelByID(const LLUUID id);
|
||||
|
||||
private:
|
||||
|
||||
LLScreenChannel* createChannel(LLChannelManager::Params& p);
|
||||
|
||||
LLScreenChannel* mStartUpChannel;
|
||||
std::vector<ChannelElem> mChannelList;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "llviewercontrol.h"
|
||||
#include "llagentdata.h"
|
||||
|
||||
/*
|
||||
static const S32 BORDER_MARGIN = 2;
|
||||
static const S32 PARENT_BORDER_MARGIN = 0;
|
||||
|
||||
|
|
@ -53,33 +54,27 @@ 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 const S32 msg_left_offset = 30;
|
||||
static const S32 msg_right_offset = 10;
|
||||
|
||||
#define MAX_CHAT_HISTORY 100
|
||||
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl> t2("chat_items_container");
|
||||
|
||||
|
||||
//static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl> t2("chat_items_container");
|
||||
|
||||
//*******************************************************************************************************************
|
||||
//LLChatItemCtrl
|
||||
//*******************************************************************************************************************
|
||||
|
||||
LLChatItemCtrl* LLChatItemCtrl::createInstance()
|
||||
LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance()
|
||||
{
|
||||
LLChatItemCtrl* item = new LLChatItemCtrl();
|
||||
LLNearbyChatToastPanel* item = new LLNearbyChatToastPanel();
|
||||
LLUICtrlFactory::getInstance()->buildPanel(item, "panel_chat_item.xml");
|
||||
item->setFollows(FOLLOWS_NONE);
|
||||
return item;
|
||||
}
|
||||
|
||||
void LLChatItemCtrl::draw()
|
||||
{
|
||||
LLPanel::draw();
|
||||
}
|
||||
|
||||
void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
|
||||
void LLNearbyChatToastPanel::reshape (S32 width, S32 height, BOOL called_from_parent )
|
||||
{
|
||||
LLPanel::reshape(width, height,called_from_parent);
|
||||
|
||||
|
|
@ -101,13 +96,13 @@ void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
|
|||
}
|
||||
}
|
||||
|
||||
BOOL LLChatItemCtrl::postBuild()
|
||||
BOOL LLNearbyChatToastPanel::postBuild()
|
||||
{
|
||||
return LLPanel::postBuild();
|
||||
}
|
||||
|
||||
|
||||
std::string LLChatItemCtrl::appendTime()
|
||||
std::string LLNearbyChatToastPanel::appendTime()
|
||||
{
|
||||
time_t utc_time;
|
||||
utc_time = time_corrected();
|
||||
|
|
@ -124,48 +119,63 @@ std::string LLChatItemCtrl::appendTime()
|
|||
|
||||
|
||||
|
||||
void LLChatItemCtrl::addText (const std::string& message)
|
||||
void LLNearbyChatToastPanel::addText (const std::string& message)
|
||||
{
|
||||
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
|
||||
msg_text->addText(message);
|
||||
mMessages.push_back(message);
|
||||
}
|
||||
|
||||
void LLChatItemCtrl::setMessage (const LLChat& msg)
|
||||
void LLNearbyChatToastPanel::init(LLSD& notification)
|
||||
{
|
||||
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
|
||||
|
||||
mText = notification["message"].asString(); // UTF-8 line of text
|
||||
mFromName = notification["from"].asString(); // agent or object name
|
||||
mFromID = notification["from_id"].asUUID(); // agent id or object id
|
||||
int sType = notification["source"].asInteger();
|
||||
mSourceType = (EChatSourceType)sType;
|
||||
|
||||
std::string str_sender;
|
||||
|
||||
|
||||
if(gAgentID != msg.mFromID)
|
||||
str_sender = msg.mFromName;
|
||||
if(gAgentID != mFromID)
|
||||
str_sender = mFromName;
|
||||
else
|
||||
str_sender = LLTrans::getString("You");;
|
||||
|
||||
caption->getChild<LLTextBox>("sender_name", false)->setText(str_sender);
|
||||
|
||||
std::string tt = appendTime();
|
||||
|
||||
caption->getChild<LLTextBox>("msg_time", false)->setText(tt);
|
||||
caption->getChild<LLTextBox>("msg_time", false)->setText(appendTime());
|
||||
|
||||
|
||||
caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(msg.mFromID);
|
||||
|
||||
mOriginalMessage = msg;
|
||||
|
||||
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
|
||||
msg_text->setText(msg.mText);
|
||||
msg_text->setText(mText);
|
||||
|
||||
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
|
||||
if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
|
||||
if(mSourceType != CHAT_SOURCE_AGENT)
|
||||
msg_inspector->setVisible(false);
|
||||
|
||||
mMessages.clear();
|
||||
|
||||
snapToMessageHeight ();
|
||||
|
||||
mIsDirty = true;//will set Avatar Icon in draw
|
||||
}
|
||||
|
||||
void LLChatItemCtrl::snapToMessageHeight ()
|
||||
void LLNearbyChatToastPanel::setMessage (const LLChat& chat_msg)
|
||||
{
|
||||
LLSD notification;
|
||||
notification["message"] = chat_msg.mText;
|
||||
notification["from"] = chat_msg.mFromName;
|
||||
notification["from_id"] = chat_msg.mFromID;
|
||||
notification["time"] = chat_msg.mTime;
|
||||
notification["source"] = (S32)chat_msg.mSourceType;
|
||||
|
||||
init(notification);
|
||||
|
||||
}
|
||||
|
||||
void LLNearbyChatToastPanel::snapToMessageHeight ()
|
||||
{
|
||||
LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
|
||||
S32 new_height = text_box->getTextPixelHeight();
|
||||
|
|
@ -184,14 +194,14 @@ void LLChatItemCtrl::snapToMessageHeight ()
|
|||
}
|
||||
|
||||
|
||||
void LLChatItemCtrl::setWidth(S32 width)
|
||||
void LLNearbyChatToastPanel::setWidth(S32 width)
|
||||
{
|
||||
LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
|
||||
text_box->reshape(width - msg_left_offset - msg_right_offset,100/*its not magic number, we just need any number*/);
|
||||
|
||||
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
|
||||
if(mOriginalMessage.mText.length())
|
||||
msg_text->setText(mOriginalMessage.mText);
|
||||
if(mText.length())
|
||||
msg_text->setText(mText);
|
||||
|
||||
for(size_t i=0;i<mMessages.size();++i)
|
||||
msg_text->addText(mMessages[i]);
|
||||
|
|
@ -200,25 +210,25 @@ void LLChatItemCtrl::setWidth(S32 width)
|
|||
snapToMessageHeight ();
|
||||
}
|
||||
|
||||
void LLChatItemCtrl::onMouseLeave (S32 x, S32 y, MASK mask)
|
||||
void LLNearbyChatToastPanel::onMouseLeave (S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
|
||||
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
|
||||
msg_inspector->setVisible(false);
|
||||
|
||||
}
|
||||
void LLChatItemCtrl::onMouseEnter (S32 x, S32 y, MASK mask)
|
||||
void LLNearbyChatToastPanel::onMouseEnter (S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
|
||||
if(mSourceType != CHAT_SOURCE_AGENT)
|
||||
return;
|
||||
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
|
||||
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
|
||||
msg_inspector->setVisible(true);
|
||||
}
|
||||
|
||||
BOOL LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
|
||||
BOOL LLNearbyChatToastPanel::handleMouseDown (S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
|
||||
if(mSourceType != CHAT_SOURCE_AGENT)
|
||||
return LLPanel::handleMouseDown(x,y,mask);
|
||||
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
|
||||
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
|
||||
|
|
@ -226,12 +236,16 @@ BOOL LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
|
|||
S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom;
|
||||
if(msg_inspector->pointInView(local_x, local_y))
|
||||
{
|
||||
LLFloaterReg::showInstance("inspect_avatar", mOriginalMessage.mFromID);
|
||||
LLFloaterReg::showInstance("inspect_avatar", mFromID);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLFloaterReg::showInstance("nearby_chat",LLSD());
|
||||
}
|
||||
return LLPanel::handleMouseDown(x,y,mask);
|
||||
}
|
||||
|
||||
void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
|
||||
void LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
|
||||
{
|
||||
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
|
||||
|
||||
|
|
@ -243,7 +257,7 @@ void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
|
|||
|
||||
}
|
||||
|
||||
bool LLChatItemCtrl::canAddText ()
|
||||
bool LLNearbyChatToastPanel::canAddText ()
|
||||
{
|
||||
LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
|
||||
if(!msg_text)
|
||||
|
|
@ -251,7 +265,7 @@ bool LLChatItemCtrl::canAddText ()
|
|||
return msg_text->getTextLinesNum()<10;
|
||||
}
|
||||
|
||||
BOOL LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
||||
BOOL LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
|
||||
LLUICtrl* avatar_icon = caption->getChild<LLUICtrl>("avatar_icon", false);
|
||||
|
|
@ -260,296 +274,20 @@ BOOL LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
|||
S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom;
|
||||
|
||||
//eat message for avatar icon if msg was from object
|
||||
if(avatar_icon->pointInView(local_x, local_y) && mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
|
||||
if(avatar_icon->pointInView(local_x, local_y) && mSourceType != CHAT_SOURCE_AGENT)
|
||||
return TRUE;
|
||||
return LLPanel::handleRightMouseDown(x,y,mask);
|
||||
}
|
||||
|
||||
|
||||
//*******************************************************************************************************************
|
||||
//LLChatItemsContainerCtrl
|
||||
//*******************************************************************************************************************
|
||||
|
||||
LLChatItemsContainerCtrl::LLChatItemsContainerCtrl(const Params& params):LLPanel(params)
|
||||
void LLNearbyChatToastPanel::draw()
|
||||
{
|
||||
mEShowItemHeader = CHATITEMHEADER_SHOW_BOTH;
|
||||
}
|
||||
|
||||
|
||||
void LLChatItemsContainerCtrl::addMessage(const LLChat& msg)
|
||||
{
|
||||
/*
|
||||
if(msg.mChatType == CHAT_TYPE_DEBUG_MSG)
|
||||
return;
|
||||
*/
|
||||
if(mItems.size() >= MAX_CHAT_HISTORY)
|
||||
if(mIsDirty)
|
||||
{
|
||||
LLChatItemCtrl* item = mItems[0];
|
||||
removeChild(item);
|
||||
delete item;
|
||||
mItems.erase(mItems.begin());
|
||||
}
|
||||
|
||||
|
||||
if(mItems.size() > 0
|
||||
&& msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID
|
||||
&& (msg.mTime-mItems[mItems.size()-1]->getMessage().mTime)<60
|
||||
&& mItems[mItems.size()-1]->canAddText()
|
||||
)
|
||||
{
|
||||
mItems[mItems.size()-1]->addText(msg.mText);
|
||||
mItems[mItems.size()-1]->snapToMessageHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
|
||||
mItems.push_back(item);
|
||||
addChild(item,0);
|
||||
item->setWidth(getRect().getWidth() - 16);
|
||||
item->setMessage(msg);
|
||||
item->snapToMessageHeight();
|
||||
|
||||
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 panels 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);
|
||||
LLPanel* caption = findChild<LLPanel>("msg_caption", false);
|
||||
if(caption)
|
||||
caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(mFromID);
|
||||
mIsDirty = false;
|
||||
}
|
||||
LLToastPanelBase::draw();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "llscrollbar.h"
|
||||
#include "string"
|
||||
#include "llchat.h"
|
||||
#include "lltoastpanel.h"
|
||||
|
||||
typedef enum e_show_item_header
|
||||
{
|
||||
|
|
@ -45,20 +46,18 @@ typedef enum e_show_item_header
|
|||
CHATITEMHEADER_SHOW_BOTH
|
||||
} EShowItemHeader;
|
||||
|
||||
class LLChatItemCtrl: public LLPanel
|
||||
class LLNearbyChatToastPanel: public LLToastPanelBase
|
||||
{
|
||||
protected:
|
||||
LLChatItemCtrl(){};
|
||||
LLNearbyChatToastPanel():mIsDirty(false){};
|
||||
public:
|
||||
|
||||
|
||||
~LLChatItemCtrl(){}
|
||||
~LLNearbyChatToastPanel(){}
|
||||
|
||||
static LLChatItemCtrl* createInstance();
|
||||
static LLNearbyChatToastPanel* createInstance();
|
||||
|
||||
void draw();
|
||||
|
||||
const LLChat& getMessage() const { return mOriginalMessage;}
|
||||
const LLUUID& getFromID() const { return mFromID;}
|
||||
|
||||
void addText (const std::string& message);
|
||||
void setMessage (const LLChat& msg);
|
||||
|
|
@ -77,77 +76,26 @@ public:
|
|||
|
||||
void setHeaderVisibility(EShowItemHeader e);
|
||||
BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
|
||||
|
||||
virtual void init(LLSD& data);
|
||||
|
||||
virtual void draw();
|
||||
private:
|
||||
|
||||
std::string appendTime ();
|
||||
|
||||
private:
|
||||
LLChat mOriginalMessage;
|
||||
std::string mText; // UTF-8 line of text
|
||||
std::string mFromName; // agent or object name
|
||||
LLUUID mFromID; // agent id or object id
|
||||
EChatSourceType mSourceType;
|
||||
|
||||
|
||||
std::vector<std::string> mMessages;
|
||||
|
||||
bool mIsDirty;
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ void LLChatMsgBox::drawText(S32 x, S32 y, const LLWString &text, const LLColor4
|
|||
|
||||
// iterate through each block of text that has been added
|
||||
y -= mLineSpacing;
|
||||
for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); true ;)
|
||||
for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); it != mSeparatorOffset.end() ;)
|
||||
{
|
||||
// display the text for this block
|
||||
S32 num_chars = *it - start;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "llvoicecontrolpanel.h"
|
||||
#include "llgroupmgr.h"
|
||||
#include "llnotificationmanager.h"
|
||||
#include "lltransientfloatermgr.h"
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
|
||||
static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");
|
||||
|
|
@ -243,26 +244,36 @@ void LLIMChiclet::draw()
|
|||
LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id)
|
||||
{
|
||||
EType type = TYPE_UNKNOWN;
|
||||
LLFloaterIMPanel* im = NULL;
|
||||
|
||||
if(session_id.isNull())
|
||||
return type;
|
||||
|
||||
if (!(im = LLIMMgr::getInstance()->findFloaterBySession(session_id)))
|
||||
EInstantMessage im_type = LLIMModel::getInstance()->getType(session_id);
|
||||
if (IM_COUNT == im_type)
|
||||
{
|
||||
llassert_always(0 && "IM session not found"); // should never happen
|
||||
return type;
|
||||
}
|
||||
|
||||
switch(im->getDialogType())
|
||||
switch(im_type)
|
||||
{
|
||||
case IM_NOTHING_SPECIAL:
|
||||
case IM_SESSION_P2P_INVITE:
|
||||
type = TYPE_IM;
|
||||
break;
|
||||
case IM_SESSION_GROUP_START:
|
||||
case IM_SESSION_INVITE:
|
||||
type = TYPE_GROUP;
|
||||
if (gAgent.isInGroup(session_id))
|
||||
{
|
||||
type = TYPE_GROUP;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = TYPE_AD_HOC;
|
||||
}
|
||||
break;
|
||||
case IM_SESSION_CONFERENCE_START:
|
||||
type = TYPE_AD_HOC;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -285,6 +296,11 @@ LLIMP2PChiclet::Params::Params()
|
|||
|
||||
avatar_icon.name("avatar_icon");
|
||||
avatar_icon.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
|
||||
|
||||
// *NOTE dzaporozhan
|
||||
// Changed icon height from 25 to 24 to fix ticket EXT-794.
|
||||
// In some cases(after changing UI scale) 25 pixel height icon was
|
||||
// drawn incorrectly, i'm not sure why.
|
||||
avatar_icon.rect(LLRect(0, 24, 25, 0));
|
||||
avatar_icon.mouse_opaque(false);
|
||||
|
||||
|
|
@ -458,6 +474,11 @@ LLIMGroupChiclet::Params::Params()
|
|||
rect(LLRect(0, 25, 45, 0));
|
||||
|
||||
group_icon.name("group_icon");
|
||||
|
||||
// *NOTE dzaporozhan
|
||||
// Changed icon height from 25 to 24 to fix ticket EXT-794.
|
||||
// In some cases(after changing UI scale) 25 pixel height icon was
|
||||
// drawn incorrectly, i'm not sure why.
|
||||
group_icon.rect(LLRect(0, 24, 25, 0));
|
||||
|
||||
unread_notifications.name("unread");
|
||||
|
|
@ -1164,6 +1185,7 @@ LLTalkButton::LLTalkButton(const Params& p)
|
|||
speak_params.rect(speak_rect);
|
||||
mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params);
|
||||
addChild(mSpeakBtn);
|
||||
LLTransientFloaterMgr::getInstance()->addControlView(mSpeakBtn);
|
||||
|
||||
mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this));
|
||||
mSpeakBtn->setToggleState(FALSE);
|
||||
|
|
@ -1172,6 +1194,7 @@ LLTalkButton::LLTalkButton(const Params& p)
|
|||
show_params.rect(show_rect);
|
||||
mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
|
||||
addChild(mShowBtn);
|
||||
LLTransientFloaterMgr::getInstance()->addControlView(mShowBtn);
|
||||
|
||||
mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this));
|
||||
mShowBtn->setToggleState(FALSE);
|
||||
|
|
|
|||
|
|
@ -275,7 +275,8 @@ public:
|
|||
enum EType {
|
||||
TYPE_UNKNOWN,
|
||||
TYPE_IM,
|
||||
TYPE_GROUP
|
||||
TYPE_GROUP,
|
||||
TYPE_AD_HOC
|
||||
};
|
||||
|
||||
/*virtual*/ ~LLIMChiclet() {};
|
||||
|
|
|
|||
|
|
@ -934,6 +934,17 @@ void LLFavoritesBarCtrl::onButtonRightClick( LLUUID item_id,LLView* fav_button,S
|
|||
LLMenuGL::showPopup(fav_button, menu, x, y);
|
||||
}
|
||||
|
||||
BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
BOOL handled = childrenHandleRightMouseDown( x, y, mask) != NULL;
|
||||
if(!handled && !gMenuHolder->hasVisibleMenu())
|
||||
{
|
||||
show_navbar_context_menu(this,x,y);
|
||||
handled = true;
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
void copy_slurl_to_clipboard_cb(std::string& slurl)
|
||||
{
|
||||
gClipboard.copyFromString(utf8str_to_wstring(slurl));
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ public:
|
|||
std::string& tooltip_msg);
|
||||
|
||||
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
|
||||
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
|
||||
// LLInventoryObserver observer trigger
|
||||
virtual void changed(U32 mask);
|
||||
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
|
|
|||
|
|
@ -363,7 +363,8 @@ LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater()
|
|||
{
|
||||
// only LLFloaterIMPanels are called "im_floater"
|
||||
LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)panelp;
|
||||
if (im_floaterp->getVoiceChannel() == LLVoiceChannel::getCurrentVoiceChannel())
|
||||
LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(im_floaterp->getSessionID());
|
||||
if (voice_channel == LLVoiceChannel::getCurrentVoiceChannel())
|
||||
{
|
||||
return im_floaterp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,11 @@ LLGroupList::Params::Params()
|
|||
|
||||
LLGroupList::LLGroupList(const Params& p)
|
||||
: LLFlatListView(p)
|
||||
, mDirty(true) // to force initial update
|
||||
{
|
||||
// Listen for agent group changes.
|
||||
gAgent.addListener(this, "new group");
|
||||
|
||||
mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");
|
||||
setCommitOnSelectionChange(true);
|
||||
// TODO: implement context menu
|
||||
|
|
@ -84,17 +88,41 @@ LLGroupList::LLGroupList(const Params& p)
|
|||
setComparator(&GROUP_COMPARATOR);
|
||||
}
|
||||
|
||||
LLGroupList::~LLGroupList()
|
||||
{
|
||||
gAgent.removeListener(this);
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLGroupList::draw()
|
||||
{
|
||||
if (mDirty)
|
||||
refresh();
|
||||
|
||||
LLFlatListView::draw();
|
||||
}
|
||||
|
||||
void LLGroupList::setNameFilter(const std::string& filter)
|
||||
{
|
||||
if (mNameFilter != filter)
|
||||
{
|
||||
mNameFilter = filter;
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
static bool findInsensitive(std::string haystack, const std::string& needle_upper)
|
||||
{
|
||||
LLStringUtil::toUpper(haystack);
|
||||
return haystack.find(needle_upper) != std::string::npos;
|
||||
}
|
||||
|
||||
BOOL LLGroupList::update(const std::string& name_filter)
|
||||
void LLGroupList::refresh()
|
||||
{
|
||||
const LLUUID& highlight_id = gAgent.getGroupID();
|
||||
S32 count = gAgent.mGroups.count();
|
||||
LLUUID id;
|
||||
bool have_filter = !mNameFilter.empty();
|
||||
|
||||
clear();
|
||||
|
||||
|
|
@ -102,7 +130,7 @@ BOOL LLGroupList::update(const std::string& name_filter)
|
|||
{
|
||||
id = gAgent.mGroups.get(i).mID;
|
||||
const LLGroupData& group_data = gAgent.mGroups.get(i);
|
||||
if (name_filter != LLStringUtil::null && !findInsensitive(group_data.mName, name_filter))
|
||||
if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
|
||||
continue;
|
||||
addNewItem(id, group_data.mName, group_data.mInsigniaID, highlight_id == id, ADD_BOTTOM);
|
||||
}
|
||||
|
|
@ -113,13 +141,14 @@ BOOL LLGroupList::update(const std::string& name_filter)
|
|||
// add "none" to list at top
|
||||
{
|
||||
std::string loc_none = LLTrans::getString("GroupsNone");
|
||||
if (name_filter == LLStringUtil::null || findInsensitive(loc_none, name_filter))
|
||||
if (have_filter || findInsensitive(loc_none, mNameFilter))
|
||||
addNewItem(LLUUID::null, loc_none, LLUUID::null, highlight_id.isNull(), ADD_TOP);
|
||||
}
|
||||
|
||||
selectItemByUUID(highlight_id);
|
||||
|
||||
return TRUE;
|
||||
setDirty(false);
|
||||
onCommit();
|
||||
}
|
||||
|
||||
void LLGroupList::toggleIcons()
|
||||
|
|
@ -158,6 +187,18 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
|
|||
// setCommentVisible(false);
|
||||
}
|
||||
|
||||
// virtual
|
||||
bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
// Why is "new group" sufficient?
|
||||
if (event->desc() == "new group")
|
||||
{
|
||||
setDirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* LLGroupListItem implementation */
|
||||
|
|
|
|||
|
|
@ -33,10 +33,19 @@
|
|||
#ifndef LL_LLGROUPLIST_H
|
||||
#define LL_LLGROUPLIST_H
|
||||
|
||||
#include "llevent.h"
|
||||
#include "llflatlistview.h"
|
||||
#include "llpanel.h"
|
||||
#include "llpointer.h"
|
||||
|
||||
class LLGroupList: public LLFlatListView
|
||||
/**
|
||||
* Auto-updating list of agent groups.
|
||||
*
|
||||
* Can use optional group name filter.
|
||||
*
|
||||
* @see setNameFilter()
|
||||
*/
|
||||
class LLGroupList: public LLFlatListView, public LLOldEvents::LLSimpleListener
|
||||
{
|
||||
LOG_CLASS(LLGroupList);
|
||||
public:
|
||||
|
|
@ -46,14 +55,23 @@ public:
|
|||
};
|
||||
|
||||
LLGroupList(const Params& p);
|
||||
BOOL update(const std::string& name_filter = LLStringUtil::null);
|
||||
virtual ~LLGroupList();
|
||||
|
||||
virtual void draw(); // from LLView
|
||||
|
||||
void setNameFilter(const std::string& filter);
|
||||
void toggleIcons();
|
||||
bool getIconsVisible() const { return mShowIcons; }
|
||||
|
||||
|
||||
private:
|
||||
void setDirty(bool val = true) { mDirty = val; }
|
||||
void refresh();
|
||||
void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
|
||||
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // called on agent group list changes
|
||||
|
||||
bool mShowIcons;
|
||||
bool mDirty;
|
||||
std::string mNameFilter;
|
||||
};
|
||||
|
||||
class LLButton;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include "lltrans.h"
|
||||
#include "llviewertexteditor.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "lltransientfloatermgr.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -62,33 +63,46 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
|
|||
mInputEditor(NULL),
|
||||
mPositioned(false)
|
||||
{
|
||||
LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
|
||||
if(session)
|
||||
EInstantMessage type = LLIMModel::getInstance()->getType(session_id);
|
||||
if(IM_COUNT != type)
|
||||
{
|
||||
mDialog = session->mType;
|
||||
}
|
||||
mDialog = type;
|
||||
|
||||
if (mDialog == IM_NOTHING_SPECIAL)
|
||||
{
|
||||
mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
|
||||
if (IM_NOTHING_SPECIAL == mDialog || IM_SESSION_P2P_INVITE == mDialog)
|
||||
{
|
||||
mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
|
||||
}
|
||||
// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml");
|
||||
|
||||
LLUI::getRootView()->setFocusLostCallback(boost::bind(&LLIMFloater::focusChangeCallback, this));
|
||||
|
||||
mCloseSignal.connect(boost::bind(&LLIMFloater::onClose, this));
|
||||
|
||||
LLTransientFloaterMgr::getInstance()->registerTransientFloater(this);
|
||||
}
|
||||
|
||||
void LLIMFloater::onClose()
|
||||
{
|
||||
LLIMModel::instance().sendLeaveSession(mSessionID, mOtherParticipantUUID);
|
||||
|
||||
//*TODO - move to the IMModel::sendLeaveSession() for the integrity (IB)
|
||||
gIMMgr->removeSession(mSessionID);
|
||||
}
|
||||
|
||||
void LLIMFloater::setMinimized(BOOL minimize)
|
||||
{
|
||||
if(!isDocked())
|
||||
{
|
||||
setVisible(!minimize);
|
||||
}
|
||||
|
||||
LLFloater::setMinimized(minimize);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void LLIMFloater::newIMCallback(const LLSD& data){
|
||||
|
||||
|
|
@ -152,16 +166,17 @@ void LLIMFloater::sendMsg()
|
|||
|
||||
LLIMFloater::~LLIMFloater()
|
||||
{
|
||||
LLTransientFloaterMgr::getInstance()->unregisterTransientFloater(this);
|
||||
}
|
||||
|
||||
//virtual
|
||||
BOOL LLIMFloater::postBuild()
|
||||
{
|
||||
LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
|
||||
if(session)
|
||||
const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
|
||||
if (other_party_id.notNull())
|
||||
{
|
||||
mOtherParticipantUUID = session->mOtherParticipantID;
|
||||
mControlPanel->setID(session->mOtherParticipantID);
|
||||
mOtherParticipantUUID = other_party_id;
|
||||
mControlPanel->setID(mOtherParticipantUUID);
|
||||
}
|
||||
|
||||
LLButton* slide_left = getChild<LLButton>("slide_left_btn");
|
||||
|
|
@ -216,17 +231,6 @@ void* LLIMFloater::createPanelGroupControl(void* userdata)
|
|||
return self->mControlPanel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLIMFloater::focusChangeCallback()
|
||||
{
|
||||
// hide docked floater if user clicked inside in-world area
|
||||
if (isDocked())
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void LLIMFloater::onSlide()
|
||||
{
|
||||
LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel");
|
||||
|
|
@ -271,13 +275,13 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
|
|||
}
|
||||
|
||||
floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(),
|
||||
LLDockControl::TOP, boost::bind(&LLIMFloater::getEnabledRect, floater, _1)));
|
||||
LLDockControl::TOP, boost::bind(&LLIMFloater::getAllowedRect, floater, _1)));
|
||||
}
|
||||
|
||||
return floater;
|
||||
}
|
||||
|
||||
void LLIMFloater::getEnabledRect(LLRect& rect)
|
||||
void LLIMFloater::getAllowedRect(LLRect& rect)
|
||||
{
|
||||
rect = gViewerWindow->getWorldViewRect();
|
||||
}
|
||||
|
|
@ -285,8 +289,10 @@ void LLIMFloater::getEnabledRect(LLRect& rect)
|
|||
void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
|
||||
{
|
||||
// update notification channel state
|
||||
LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->
|
||||
findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
|
||||
LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
|
||||
(LLNotificationsUI::LLChannelManager::getInstance()->
|
||||
findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
|
||||
|
||||
LLDockableFloater::setDocked(docked, pop_on_undock);
|
||||
|
||||
// update notification channel state
|
||||
|
|
@ -298,8 +304,9 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
|
|||
|
||||
void LLIMFloater::setVisible(BOOL visible)
|
||||
{
|
||||
LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->
|
||||
findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
|
||||
LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
|
||||
(LLNotificationsUI::LLChannelManager::getInstance()->
|
||||
findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
|
||||
LLDockableFloater::setVisible(visible);
|
||||
|
||||
// update notification channel state
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ public:
|
|||
|
||||
// LLFloater overrides
|
||||
/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
|
||||
// override LLFloater's minimization according to EXT-1216
|
||||
/*virtual*/ void setMinimized(BOOL minimize);
|
||||
|
||||
// Make IM conversion visible and update the message history
|
||||
static LLIMFloater* show(const LLUUID& session_id);
|
||||
|
|
@ -90,8 +92,8 @@ private:
|
|||
void onSlide();
|
||||
static void* createPanelIMControl(void* userdata);
|
||||
static void* createPanelGroupControl(void* userdata);
|
||||
void focusChangeCallback();
|
||||
void getEnabledRect(LLRect& rect);
|
||||
// gets a rect that bounds possible positions for the LLIMFloater on a screen (EXT-1111)
|
||||
void getAllowedRect(LLRect& rect);
|
||||
|
||||
LLPanelChatControlPanel* mControlPanel;
|
||||
LLUUID mSessionID;
|
||||
|
|
|
|||
|
|
@ -109,7 +109,9 @@ bool LLIMHandler::processNotification(const LLSD& notify)
|
|||
p.panel = im_box;
|
||||
p.can_be_stored = false;
|
||||
p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);
|
||||
mChannel->addToast(p);
|
||||
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
|
||||
if(channel)
|
||||
channel->addToast(p);
|
||||
|
||||
// send a signal to the counter manager;
|
||||
mNewNotificationSignal();
|
||||
|
|
|
|||
|
|
@ -940,7 +940,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
|
|||
mHistoryEditor(NULL),
|
||||
mSessionUUID(session_id),
|
||||
mSessionLabel(session_label),
|
||||
mVoiceChannel(NULL),
|
||||
mSessionInitialized(FALSE),
|
||||
mSessionStartMsgPos(0),
|
||||
mOtherParticipantUUID(other_participant_id),
|
||||
|
|
@ -956,7 +955,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
|
|||
mTextIMPossible(TRUE),
|
||||
mProfileButtonEnabled(TRUE),
|
||||
mCallBackEnabled(TRUE),
|
||||
mSpeakers(NULL),
|
||||
mSpeakerPanel(NULL),
|
||||
mFirstKeystrokeTimer(),
|
||||
mLastKeystrokeTimer()
|
||||
|
|
@ -967,7 +965,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
|
|||
case IM_SESSION_GROUP_START:
|
||||
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
|
||||
xml_filename = "floater_instant_message_group.xml";
|
||||
mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
|
||||
break;
|
||||
case IM_SESSION_INVITE:
|
||||
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
|
||||
|
|
@ -979,16 +976,13 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
|
|||
{
|
||||
xml_filename = "floater_instant_message_ad_hoc.xml";
|
||||
}
|
||||
mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
|
||||
break;
|
||||
case IM_SESSION_P2P_INVITE:
|
||||
xml_filename = "floater_instant_message.xml";
|
||||
mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
|
||||
break;
|
||||
case IM_SESSION_CONFERENCE_START:
|
||||
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
|
||||
xml_filename = "floater_instant_message_ad_hoc.xml";
|
||||
mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
|
||||
break;
|
||||
// just received text from another user
|
||||
case IM_NOTHING_SPECIAL:
|
||||
|
|
@ -998,8 +992,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
|
|||
mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionUUID);
|
||||
mProfileButtonEnabled = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionUUID);
|
||||
mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionUUID);
|
||||
|
||||
mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
|
||||
break;
|
||||
default:
|
||||
llwarns << "Unknown session type" << llendl;
|
||||
|
|
@ -1007,10 +999,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
|
|||
break;
|
||||
}
|
||||
|
||||
mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
|
||||
// All participants will be added to the list of people we've recently interacted with.
|
||||
mSpeakers->addListener(&LLRecentPeople::instance(), "add");
|
||||
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, xml_filename, NULL);
|
||||
|
||||
setTitle(mSessionLabel);
|
||||
|
|
@ -1058,33 +1046,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
|
|||
|
||||
LLFloaterIMPanel::~LLFloaterIMPanel()
|
||||
{
|
||||
delete mSpeakers;
|
||||
mSpeakers = NULL;
|
||||
|
||||
// End the text IM session if necessary
|
||||
if(gVoiceClient && mOtherParticipantUUID.notNull())
|
||||
{
|
||||
switch(mDialog)
|
||||
{
|
||||
case IM_NOTHING_SPECIAL:
|
||||
case IM_SESSION_P2P_INVITE:
|
||||
gVoiceClient->endUserIMSession(mOtherParticipantUUID);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Appease the compiler
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//kicks you out of the voice channel if it is currently active
|
||||
|
||||
// HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
|
||||
mVoiceChannel->deactivate();
|
||||
|
||||
delete mVoiceChannel;
|
||||
mVoiceChannel = NULL;
|
||||
|
||||
//delete focus lost callback
|
||||
mFocusCallbackConnection.disconnect();
|
||||
}
|
||||
|
|
@ -1152,7 +1113,8 @@ BOOL LLFloaterIMPanel::postBuild()
|
|||
void* LLFloaterIMPanel::createSpeakersPanel(void* data)
|
||||
{
|
||||
LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)data;
|
||||
floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(floaterp->mSpeakers, TRUE);
|
||||
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(floaterp->mSessionUUID);
|
||||
floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(speaker_mgr, TRUE);
|
||||
return floaterp->mSpeakerPanel;
|
||||
}
|
||||
|
||||
|
|
@ -1198,12 +1160,14 @@ void LLFloaterIMPanel::draw()
|
|||
&& mCallBackEnabled;
|
||||
|
||||
// hide/show start call and end call buttons
|
||||
childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
|
||||
childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
|
||||
LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionUUID);
|
||||
childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
|
||||
childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && voice_channel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
|
||||
childSetEnabled("start_call_btn", enable_connect);
|
||||
childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty());
|
||||
|
||||
LLPointer<LLSpeaker> self_speaker = mSpeakers->findSpeaker(gAgent.getID());
|
||||
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID);
|
||||
LLPointer<LLSpeaker> self_speaker = speaker_mgr->findSpeaker(gAgent.getID());
|
||||
if(!mTextIMPossible)
|
||||
{
|
||||
mInputEditor->setEnabled(FALSE);
|
||||
|
|
@ -1227,7 +1191,7 @@ void LLFloaterIMPanel::draw()
|
|||
}
|
||||
|
||||
// show speakers window when voice first connects
|
||||
if (mShowSpeakersOnConnect && mVoiceChannel->isActive())
|
||||
if (mShowSpeakersOnConnect && voice_channel->isActive())
|
||||
{
|
||||
childSetVisible("active_speakers_panel", TRUE);
|
||||
mShowSpeakersOnConnect = FALSE;
|
||||
|
|
@ -1263,11 +1227,11 @@ void LLFloaterIMPanel::draw()
|
|||
else
|
||||
{
|
||||
// refresh volume and mute checkbox
|
||||
childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
|
||||
childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && voice_channel->isActive());
|
||||
childSetValue("speaker_volume", gVoiceClient->getUserVolume(mOtherParticipantUUID));
|
||||
|
||||
childSetValue("mute_btn", LLMuteList::getInstance()->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat));
|
||||
childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
|
||||
childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && voice_channel->isActive());
|
||||
}
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
|
@ -1403,12 +1367,6 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
|
|||
{
|
||||
mNumUnreadMessages++;
|
||||
}
|
||||
|
||||
if (source != LLUUID::null)
|
||||
{
|
||||
mSpeakers->speakerChatted(source);
|
||||
mSpeakers->setSpeakerTyping(source, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1589,7 +1547,7 @@ void LLFloaterIMPanel::onClickStartCall(void* userdata)
|
|||
{
|
||||
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
|
||||
|
||||
self->mVoiceChannel->activate();
|
||||
LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->activate();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -1597,7 +1555,7 @@ void LLFloaterIMPanel::onClickEndCall(void* userdata)
|
|||
{
|
||||
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
|
||||
|
||||
self->getVoiceChannel()->deactivate();
|
||||
LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->deactivate();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -1671,7 +1629,8 @@ void LLFloaterIMPanel::onVisibilityChange(const LLSD& new_visibility)
|
|||
mNumUnreadMessages = 0;
|
||||
}
|
||||
|
||||
if (new_visibility.asBoolean() && mVoiceChannel->getState() == LLVoiceChannel::STATE_CONNECTED)
|
||||
LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionUUID);
|
||||
if (new_visibility.asBoolean() && voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
|
||||
LLFloaterReg::showInstance("voice_call", mSessionUUID);
|
||||
else
|
||||
LLFloaterReg::hideInstance("voice_call", mSessionUUID);
|
||||
|
|
@ -1723,11 +1682,6 @@ void LLFloaterIMPanel::sendMsg()
|
|||
mSentTypingState = TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterIMPanel::updateSpeakersList(const LLSD& speaker_updates)
|
||||
{
|
||||
mSpeakers->updateSpeakers(speaker_updates);
|
||||
}
|
||||
|
||||
void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
|
||||
{
|
||||
if (
|
||||
|
|
@ -1751,15 +1705,9 @@ void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterIMPanel::setSpeakers(const LLSD& speaker_list)
|
||||
{
|
||||
mSpeakers->setSpeakers(speaker_list);
|
||||
}
|
||||
|
||||
void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
|
||||
{
|
||||
mSessionUUID = session_id;
|
||||
mVoiceChannel->updateSessionID(session_id);
|
||||
mSessionInitialized = TRUE;
|
||||
|
||||
//we assume the history editor hasn't moved at all since
|
||||
|
|
@ -1790,6 +1738,7 @@ void LLFloaterIMPanel::requestAutoConnect()
|
|||
|
||||
void LLFloaterIMPanel::setTyping(BOOL typing)
|
||||
{
|
||||
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID);
|
||||
if (typing)
|
||||
{
|
||||
// Every time you type something, reset this timer
|
||||
|
|
@ -1804,7 +1753,7 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
|
|||
mSentTypingState = FALSE;
|
||||
}
|
||||
|
||||
mSpeakers->setSpeakerTyping(gAgent.getID(), TRUE);
|
||||
speaker_mgr->setSpeakerTyping(gAgent.getID(), TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1814,7 +1763,7 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
|
|||
sendTypingState(FALSE);
|
||||
mSentTypingState = TRUE;
|
||||
}
|
||||
mSpeakers->setSpeakerTyping(gAgent.getID(), FALSE);
|
||||
speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
|
||||
}
|
||||
|
||||
mTyping = typing;
|
||||
|
|
@ -1874,7 +1823,7 @@ void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info)
|
|||
mHistoryEditor->removeTextFromEnd(chars_to_remove);
|
||||
if (im_info)
|
||||
{
|
||||
mSpeakers->setSpeakerTyping(im_info->mFromID, FALSE);
|
||||
LLIMModel::getInstance()->getSpeakerManager(mSessionUUID)->setSpeakerTyping(im_info->mFromID, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#ifndef LL_IMPANEL_H
|
||||
#define LL_IMPANEL_H
|
||||
|
||||
#include "llimview.h" //for LLIMModel
|
||||
#include "lldockablefloater.h"
|
||||
#include "lllogchat.h"
|
||||
#include "lluuid.h"
|
||||
|
|
@ -245,11 +246,7 @@ public:
|
|||
|
||||
const LLUUID& getSessionID() const { return mSessionUUID; }
|
||||
const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; }
|
||||
LLIMSpeakerMgr* getSpeakerManager() const { return mSpeakers; }
|
||||
void updateSpeakersList(const LLSD& speaker_updates);
|
||||
void processSessionUpdate(const LLSD& update);
|
||||
void setSpeakers(const LLSD& speaker_list);
|
||||
LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
|
||||
EInstantMessage getDialogType() const { return mDialog; }
|
||||
void setDialogType(EInstantMessage dialog) { mDialog = dialog; }
|
||||
|
||||
|
|
@ -305,7 +302,6 @@ private:
|
|||
LLUUID mSessionUUID;
|
||||
|
||||
std::string mSessionLabel;
|
||||
LLVoiceChannel* mVoiceChannel;
|
||||
|
||||
BOOL mSessionInitialized;
|
||||
LLSD mQueuedMsgsForInit;
|
||||
|
|
@ -346,7 +342,6 @@ private:
|
|||
BOOL mProfileButtonEnabled;
|
||||
BOOL mCallBackEnabled;
|
||||
|
||||
LLIMSpeakerMgr* mSpeakers;
|
||||
LLPanelActiveSpeakers* mSpeakerPanel;
|
||||
|
||||
// Optimization: Don't send "User is typing..." until the
|
||||
|
|
|
|||
|
|
@ -114,11 +114,85 @@ void toast_callback(const LLSD& msg){
|
|||
|
||||
LLIMModel::LLIMModel()
|
||||
{
|
||||
addChangedCallback(toast_callback);
|
||||
addChangedCallback(LLIMFloater::newIMCallback);
|
||||
addChangedCallback(toast_callback);
|
||||
}
|
||||
|
||||
|
||||
LLIMModel::LLIMSession::LLIMSession( const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id )
|
||||
: mSessionID(session_id),
|
||||
mName(name),
|
||||
mType(type),
|
||||
mNumUnread(0),
|
||||
mOtherParticipantID(other_participant_id),
|
||||
mVoiceChannel(NULL),
|
||||
mSpeakers(NULL)
|
||||
{
|
||||
if (IM_NOTHING_SPECIAL == type || IM_SESSION_P2P_INVITE == type)
|
||||
{
|
||||
mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
mVoiceChannel = new LLVoiceChannelGroup(session_id, name);
|
||||
}
|
||||
mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
|
||||
|
||||
// All participants will be added to the list of people we've recently interacted with.
|
||||
mSpeakers->addListener(&LLRecentPeople::instance(), "add");
|
||||
}
|
||||
|
||||
LLIMModel::LLIMSession::~LLIMSession()
|
||||
{
|
||||
delete mSpeakers;
|
||||
mSpeakers = NULL;
|
||||
|
||||
// End the text IM session if necessary
|
||||
if(gVoiceClient && mOtherParticipantID.notNull())
|
||||
{
|
||||
switch(mType)
|
||||
{
|
||||
case IM_NOTHING_SPECIAL:
|
||||
case IM_SESSION_P2P_INVITE:
|
||||
gVoiceClient->endUserIMSession(mOtherParticipantID);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Appease the linux compiler
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
|
||||
mVoiceChannel->deactivate();
|
||||
|
||||
delete mVoiceChannel;
|
||||
mVoiceChannel = NULL;
|
||||
}
|
||||
|
||||
LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
|
||||
{
|
||||
return get_if_there(LLIMModel::instance().sSessionsMap, session_id,
|
||||
(LLIMModel::LLIMSession*) NULL);
|
||||
}
|
||||
|
||||
void LLIMModel::updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id)
|
||||
{
|
||||
if (new_session_id == old_session_id) return;
|
||||
|
||||
LLIMSession* session = findIMSession(old_session_id);
|
||||
if (session)
|
||||
{
|
||||
session->mSessionID = new_session_id;
|
||||
session->mVoiceChannel->updateSessionID(new_session_id);
|
||||
|
||||
//*TODO set session initialized flag here? (IB)
|
||||
|
||||
sSessionsMap.erase(old_session_id);
|
||||
sSessionsMap[new_session_id] = session;
|
||||
}
|
||||
}
|
||||
|
||||
void LLIMModel::testMessages()
|
||||
{
|
||||
LLUUID bot1_id("d0426ec6-6535-4c11-a5d9-526bb0c654d9");
|
||||
|
|
@ -153,7 +227,7 @@ bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage
|
|||
return false;
|
||||
}
|
||||
|
||||
LLIMSession* session = new LLIMSession(name, type, other_participant_id);
|
||||
LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id);
|
||||
sSessionsMap[session_id] = session;
|
||||
|
||||
LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, name, other_participant_id);
|
||||
|
|
@ -170,12 +244,12 @@ bool LLIMModel::clearSession(LLUUID session_id)
|
|||
return true;
|
||||
}
|
||||
|
||||
//*TODO remake it, instead of returing the list pass it as as parameter (IB)
|
||||
std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
|
||||
{
|
||||
std::list<LLSD> return_list;
|
||||
|
||||
LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
|
||||
|
||||
LLIMSession* session = findIMSession(session_id);
|
||||
if (!session)
|
||||
{
|
||||
llwarns << "session " << session_id << "does not exist " << llendl;
|
||||
|
|
@ -202,13 +276,14 @@ std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
|
|||
mChangedSignal(arg);
|
||||
|
||||
// TODO: in the future is there a more efficient way to return these
|
||||
//of course there is - return as parameter (IB)
|
||||
return return_list;
|
||||
|
||||
}
|
||||
|
||||
bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string utf8_text) {
|
||||
|
||||
LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
|
||||
LLIMSession* session = findIMSession(session_id);
|
||||
|
||||
if (!session)
|
||||
{
|
||||
|
|
@ -231,7 +306,7 @@ bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string ut
|
|||
|
||||
bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text) {
|
||||
|
||||
LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
|
||||
LLIMSession* session = findIMSession(session_id);
|
||||
|
||||
if (!session)
|
||||
{
|
||||
|
|
@ -260,9 +335,9 @@ bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id,
|
|||
}
|
||||
|
||||
|
||||
const std::string& LLIMModel::getName(LLUUID session_id)
|
||||
const std::string& LLIMModel::getName(const LLUUID& session_id) const
|
||||
{
|
||||
LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
|
||||
LLIMSession* session = findIMSession(session_id);
|
||||
|
||||
if (!session)
|
||||
{
|
||||
|
|
@ -273,6 +348,66 @@ const std::string& LLIMModel::getName(LLUUID session_id)
|
|||
return session->mName;
|
||||
}
|
||||
|
||||
const S32 LLIMModel::getNumUnread(const LLUUID& session_id) const
|
||||
{
|
||||
LLIMSession* session = findIMSession(session_id);
|
||||
if (!session)
|
||||
{
|
||||
llwarns << "session " << session_id << "does not exist " << llendl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return session->mNumUnread;
|
||||
}
|
||||
|
||||
const LLUUID& LLIMModel::getOtherParticipantID(const LLUUID& session_id) const
|
||||
{
|
||||
LLIMSession* session = findIMSession(session_id);
|
||||
if (!session)
|
||||
{
|
||||
llwarns << "session " << session_id << "does not exist " << llendl;
|
||||
return LLUUID::null;
|
||||
}
|
||||
|
||||
return session->mOtherParticipantID;
|
||||
}
|
||||
|
||||
EInstantMessage LLIMModel::getType(const LLUUID& session_id) const
|
||||
{
|
||||
LLIMSession* session = findIMSession(session_id);
|
||||
if (!session)
|
||||
{
|
||||
llwarns << "session " << session_id << "does not exist " << llendl;
|
||||
return IM_COUNT;
|
||||
}
|
||||
|
||||
return session->mType;
|
||||
}
|
||||
|
||||
LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id ) const
|
||||
{
|
||||
LLIMSession* session = findIMSession(session_id);
|
||||
if (!session)
|
||||
{
|
||||
llwarns << "session " << session_id << "does not exist " << llendl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return session->mVoiceChannel;
|
||||
}
|
||||
|
||||
LLIMSpeakerMgr* LLIMModel::getSpeakerManager( const LLUUID& session_id ) const
|
||||
{
|
||||
LLIMSession* session = findIMSession(session_id);
|
||||
if (!session)
|
||||
{
|
||||
llwarns << "session " << session_id << "does not exist " << llendl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return session->mSpeakers;
|
||||
}
|
||||
|
||||
|
||||
// TODO get rid of other participant ID
|
||||
void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing)
|
||||
|
|
@ -316,7 +451,7 @@ void LLIMModel::sendLeaveSession(LLUUID session_id, LLUUID other_participant_id)
|
|||
}
|
||||
|
||||
|
||||
|
||||
//*TODO update list of messages in a LLIMSession (IB)
|
||||
void LLIMModel::sendMessage(const std::string& utf8_text,
|
||||
const LLUUID& im_session_id,
|
||||
const LLUUID& other_participant_id,
|
||||
|
|
@ -415,9 +550,16 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
|
|||
LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(im_session_id);
|
||||
if (floater) floater->addHistoryLine(history_echo, LLUIColorTable::instance().getColor("IMChatColor"), true, gAgent.getID());
|
||||
|
||||
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(im_session_id);
|
||||
if (speaker_mgr)
|
||||
{
|
||||
speaker_mgr->speakerChatted(gAgentID);
|
||||
speaker_mgr->setSpeakerTyping(gAgentID, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the recipient to the recent people list.
|
||||
//*TODO should be deleted, because speaker manager updates through callback the recent list
|
||||
LLRecentPeople::instance().add(other_participant_id);
|
||||
}
|
||||
|
||||
|
|
@ -633,10 +775,8 @@ public:
|
|||
{
|
||||
if ( gIMMgr)
|
||||
{
|
||||
LLFloaterIMPanel* floaterp =
|
||||
gIMMgr->findFloaterBySession(mSessionID);
|
||||
|
||||
if (floaterp)
|
||||
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
|
||||
if (speaker_mgr)
|
||||
{
|
||||
//we've accepted our invitation
|
||||
//and received a list of agents that were
|
||||
|
|
@ -650,15 +790,20 @@ public:
|
|||
//but unfortunately, our base that we are receiving here
|
||||
//may not be the most up to date. It was accurate at
|
||||
//some point in time though.
|
||||
floaterp->setSpeakers(content);
|
||||
speaker_mgr->setSpeakers(content);
|
||||
|
||||
//we now have our base of users in the session
|
||||
//that was accurate at some point, but maybe not now
|
||||
//so now we apply all of the udpates we've received
|
||||
//in case of race conditions
|
||||
floaterp->updateSpeakersList(
|
||||
gIMMgr->getPendingAgentListUpdates(mSessionID));
|
||||
speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID));
|
||||
}
|
||||
|
||||
LLFloaterIMPanel* floaterp =
|
||||
gIMMgr->findFloaterBySession(mSessionID);
|
||||
|
||||
if (floaterp)
|
||||
{
|
||||
if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
|
||||
{
|
||||
floaterp->requestAutoConnect();
|
||||
|
|
@ -1104,6 +1249,12 @@ void LLIMMgr::addMessage(
|
|||
//no session ID...compute new one
|
||||
new_session_id = computeSessionID(dialog, other_participant_id);
|
||||
}
|
||||
|
||||
if (!LLIMModel::getInstance()->findIMSession(new_session_id))
|
||||
{
|
||||
LLIMModel::instance().newSession(session_id, session_name, dialog, other_participant_id);
|
||||
}
|
||||
|
||||
floater = findFloaterBySession(new_session_id);
|
||||
if (!floater)
|
||||
{
|
||||
|
|
@ -1169,6 +1320,14 @@ void LLIMMgr::addMessage(
|
|||
else
|
||||
{
|
||||
floater->addHistoryLine(msg, color, true, other_participant_id, from); // Insert linked name to front of message
|
||||
|
||||
//*TODO consider moving that speaker management stuff into model (IB)
|
||||
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(new_session_id);
|
||||
if (speaker_mgr)
|
||||
{
|
||||
speaker_mgr->speakerChatted(gAgentID);
|
||||
speaker_mgr->setSpeakerTyping(gAgentID, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
|
||||
|
|
@ -1273,11 +1432,10 @@ LLUUID LLIMMgr::addP2PSession(const std::string& name,
|
|||
{
|
||||
LLUUID session_id = addSession(name, IM_NOTHING_SPECIAL, other_participant_id);
|
||||
|
||||
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
|
||||
if(floater)
|
||||
LLVoiceChannelP2P* voice_channel = (LLVoiceChannelP2P*) LLIMModel::getInstance()->getSpeakerManager(session_id);
|
||||
if (voice_channel)
|
||||
{
|
||||
LLVoiceChannelP2P* voice_channelp = (LLVoiceChannelP2P*)floater->getVoiceChannel();
|
||||
voice_channelp->setSessionHandle(voice_session_handle, caller_uri);
|
||||
voice_channel->setSessionHandle(voice_session_handle, caller_uri);
|
||||
}
|
||||
|
||||
return session_id;
|
||||
|
|
@ -1312,6 +1470,11 @@ LLUUID LLIMMgr::addSession(
|
|||
|
||||
LLUUID session_id = computeSessionID(dialog,other_participant_id);
|
||||
|
||||
if (!LLIMModel::getInstance()->findIMSession(session_id))
|
||||
{
|
||||
LLIMModel::instance().newSession(session_id, name, dialog, other_participant_id);
|
||||
}
|
||||
|
||||
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
|
||||
if(!floater)
|
||||
{
|
||||
|
|
@ -1335,17 +1498,10 @@ LLUUID LLIMMgr::addSession(
|
|||
noteMutedUsers(floater, ids);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// *TODO: Remove this? Otherwise old communicate window opens on
|
||||
// second initiation of IM session from People panel?
|
||||
// floater->openFloater();
|
||||
}
|
||||
//mTabContainer->selectTabPanel(panel);
|
||||
floater->setInputFocus(TRUE);
|
||||
LLIMFloater::show(session_id);
|
||||
notifyObserverSessionAdded(floater->getSessionID(), name, other_participant_id);
|
||||
return floater->getSessionID();
|
||||
|
||||
return session_id;
|
||||
}
|
||||
|
||||
// This removes the panel referenced by the uuid, and then restores
|
||||
|
|
@ -1705,7 +1861,6 @@ LLFloaterIMPanel* LLIMMgr::createFloater(
|
|||
LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
|
||||
LLFloaterChatterBox::getInstance()->addFloater(floater, FALSE, i_pt);
|
||||
mFloaters.insert(floater->getHandle());
|
||||
LLIMModel::instance().newSession(session_id, session_label, dialog, other_participant_id);
|
||||
return floater;
|
||||
}
|
||||
|
||||
|
|
@ -1825,24 +1980,25 @@ public:
|
|||
gIMMgr->updateFloaterSessionID(
|
||||
temp_session_id,
|
||||
session_id);
|
||||
|
||||
LLIMModel::getInstance()->updateSessionID(temp_session_id, session_id);
|
||||
|
||||
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
|
||||
if (speaker_mgr)
|
||||
{
|
||||
speaker_mgr->setSpeakers(body);
|
||||
speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id));
|
||||
}
|
||||
|
||||
LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
|
||||
if (floaterp)
|
||||
{
|
||||
floaterp->setSpeakers(body);
|
||||
|
||||
//apply updates we've possibly received previously
|
||||
floaterp->updateSpeakersList(
|
||||
gIMMgr->getPendingAgentListUpdates(session_id));
|
||||
|
||||
if ( body.has("session_info") )
|
||||
{
|
||||
floaterp->processSessionUpdate(body["session_info"]);
|
||||
}
|
||||
|
||||
//aply updates we've possibly received previously
|
||||
floaterp->updateSpeakersList(
|
||||
gIMMgr->getPendingAgentListUpdates(session_id));
|
||||
}
|
||||
|
||||
gIMMgr->clearPendingAgentListUpdates(session_id);
|
||||
}
|
||||
else
|
||||
|
|
@ -1932,15 +2088,15 @@ public:
|
|||
const LLSD& context,
|
||||
const LLSD& input) const
|
||||
{
|
||||
LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID());
|
||||
if (floaterp)
|
||||
const LLUUID& session_id = input["body"]["session_id"].asUUID();
|
||||
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
|
||||
if (speaker_mgr)
|
||||
{
|
||||
floaterp->updateSpeakersList(
|
||||
input["body"]);
|
||||
speaker_mgr->updateSpeakers(input["body"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//we don't have a floater yet..something went wrong
|
||||
//we don't have a speaker manager yet..something went wrong
|
||||
//we are probably receiving an update here before
|
||||
//a start or an acceptance of an invitation. Race condition.
|
||||
gIMMgr->addPendingAgentListUpdates(
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
#define LL_LLIMVIEW_H
|
||||
|
||||
#include "lldarray.h"
|
||||
#include "llfloateractivespeakers.h" //for LLIMSpeakerMgr
|
||||
#include "llimpanel.h" //for voice channels
|
||||
#include "llmodaldialog.h"
|
||||
#include "llinstantmessage.h"
|
||||
#include "lluuid.h"
|
||||
|
|
@ -50,21 +52,40 @@ public:
|
|||
|
||||
struct LLIMSession
|
||||
{
|
||||
LLIMSession(std::string name, EInstantMessage type, LLUUID other_participant_id)
|
||||
:mName(name), mType(type), mNumUnread(0), mOtherParticipantID(other_participant_id) {}
|
||||
|
||||
LLIMSession(const LLUUID& session_id, const std::string& name,
|
||||
const EInstantMessage& type, const LLUUID& other_participant_id);
|
||||
virtual ~LLIMSession();
|
||||
|
||||
LLUUID mSessionID;
|
||||
std::string mName;
|
||||
EInstantMessage mType;
|
||||
LLUUID mOtherParticipantID;
|
||||
S32 mNumUnread;
|
||||
std::list<LLSD> mMsgs;
|
||||
|
||||
LLVoiceChannel* mVoiceChannel;
|
||||
LLIMSpeakerMgr* mSpeakers;
|
||||
};
|
||||
|
||||
|
||||
LLIMModel();
|
||||
|
||||
//*TODO make it non-static as LLIMMOdel is a singleton (IB)
|
||||
static std::map<LLUUID, LLIMSession*> sSessionsMap; //mapping session_id to session
|
||||
|
||||
boost::signals2::signal<void(const LLSD&)> mChangedSignal;
|
||||
|
||||
/**
|
||||
* Find an IM Session corresponding to session_id
|
||||
* Returns NULL if the session does not exist
|
||||
*/
|
||||
LLIMSession* findIMSession(const LLUUID& session_id) const;
|
||||
|
||||
/**
|
||||
* Rebind session data to a new session id.
|
||||
*/
|
||||
void updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id);
|
||||
|
||||
boost::signals2::connection addChangedCallback( boost::function<void (const LLSD& data)> cb );
|
||||
|
||||
bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id);
|
||||
|
|
@ -72,10 +93,42 @@ public:
|
|||
std::list<LLSD> getMessages(LLUUID session_id, int start_index = 0);
|
||||
bool addMessage(LLUUID session_id, std::string from, LLUUID other_participant_id, std::string utf8_text);
|
||||
bool addToHistory(LLUUID session_id, std::string from, std::string utf8_text);
|
||||
//used to get the name of the session, for use as the title
|
||||
//currently just the other avatar name
|
||||
const std::string& getName(LLUUID session_id);
|
||||
|
||||
//used to get the name of the session, for use as the title
|
||||
//currently just the other avatar name
|
||||
const std::string& getName(const LLUUID& session_id) const;
|
||||
|
||||
/**
|
||||
* Get number of unread messages in a session with session_id
|
||||
* Returns -1 if the session with session_id doesn't exist
|
||||
*/
|
||||
const S32 getNumUnread(const LLUUID& session_id) const;
|
||||
|
||||
/**
|
||||
* Get uuid of other participant in a session with session_id
|
||||
* Returns LLUUID::null if the session doesn't exist
|
||||
*
|
||||
* *TODO what to do with other participants in ad-hoc and group chats?
|
||||
*/
|
||||
const LLUUID& getOtherParticipantID(const LLUUID& session_id) const;
|
||||
|
||||
/**
|
||||
* Get type of a session specified by session_id
|
||||
* Returns EInstantMessage::IM_COUNT if the session does not exist
|
||||
*/
|
||||
EInstantMessage getType(const LLUUID& session_id) const;
|
||||
|
||||
/**
|
||||
* Get voice channel for the session specified by session_id
|
||||
* Returns NULL if the session does not exist
|
||||
*/
|
||||
LLVoiceChannel* getVoiceChannel(const LLUUID& session_id) const;
|
||||
|
||||
/**
|
||||
* Get im speaker manager for the session specified by session_id
|
||||
* Returns NULL if the session does not exist
|
||||
*/
|
||||
LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const;
|
||||
|
||||
static void sendLeaveSession(LLUUID session_id, LLUUID other_participant_id);
|
||||
static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
|
||||
const std::vector<LLUUID>& ids, EInstantMessage dialog);
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key) :
|
|||
mChatCaptionPanel(NULL),
|
||||
mChatHistoryEditor(NULL)
|
||||
{
|
||||
m_isDirty = false;
|
||||
}
|
||||
|
||||
LLNearbyChat::~LLNearbyChat()
|
||||
|
|
@ -181,7 +182,7 @@ LLColor4 nearbychat_get_text_color(const LLChat& chat)
|
|||
return text_color;
|
||||
}
|
||||
|
||||
void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color)
|
||||
void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& color)
|
||||
{
|
||||
std::string line = chat.mText;
|
||||
|
||||
|
|
@ -194,25 +195,28 @@ void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, cons
|
|||
bool prepend_newline = true;
|
||||
if (gSavedSettings.getBOOL("ChatShowTimestamps"))
|
||||
{
|
||||
edit->appendTime(prepend_newline);
|
||||
mChatHistoryEditor->appendTime(prepend_newline);
|
||||
prepend_newline = false;
|
||||
}
|
||||
|
||||
// If the msg is from an agent (not yourself though),
|
||||
// extract out the sender name and replace it with the hotlinked name.
|
||||
|
||||
std::string str_URL = chat.mURL;
|
||||
|
||||
if (chat.mSourceType == CHAT_SOURCE_AGENT &&
|
||||
chat.mFromID != LLUUID::null)
|
||||
{
|
||||
chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
|
||||
str_URL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
|
||||
}
|
||||
|
||||
// If the chat line has an associated url, link it up to the name.
|
||||
if (!chat.mURL.empty()
|
||||
if (!str_URL.empty()
|
||||
&& (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0))
|
||||
{
|
||||
std::string start_line = line.substr(0, chat.mFromName.length() + 1);
|
||||
line = line.substr(chat.mFromName.length() + 1);
|
||||
edit->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,chat.mURL));
|
||||
mChatHistoryEditor->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,str_URL));
|
||||
prepend_newline = false;
|
||||
}
|
||||
|
||||
|
|
@ -225,11 +229,9 @@ void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, cons
|
|||
else if (2 == font_size)
|
||||
font_name = "sansserifbig";
|
||||
|
||||
edit->appendColoredText(line, false, prepend_newline, color, font_name);
|
||||
mChatHistoryEditor->appendColoredText(line, false, prepend_newline, color, font_name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLNearbyChat::addMessage(const LLChat& chat)
|
||||
{
|
||||
LLColor4 color = nearbychat_get_text_color(chat);
|
||||
|
|
@ -254,7 +256,7 @@ void LLNearbyChat::addMessage(const LLChat& chat)
|
|||
mChatHistoryEditor->setParseHighlights(TRUE);
|
||||
|
||||
if (!chat.mMuted)
|
||||
nearbychat_add_timestamped_line(mChatHistoryEditor, chat, color);
|
||||
add_timestamped_line(chat, color);
|
||||
}
|
||||
|
||||
void LLNearbyChat::onNearbySpeakers()
|
||||
|
|
@ -482,9 +484,16 @@ BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
|||
|
||||
void LLNearbyChat::onOpen(const LLSD& key )
|
||||
{
|
||||
LLNotificationsUI::LLScreenChannel* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
|
||||
LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
|
||||
if(chat_channel)
|
||||
{
|
||||
chat_channel->removeToastsFromChannel();
|
||||
}
|
||||
}
|
||||
|
||||
void LLNearbyChat::draw ()
|
||||
{
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,10 @@ public:
|
|||
|
||||
virtual void onOpen (const LLSD& key);
|
||||
|
||||
virtual void draw ();
|
||||
|
||||
private:
|
||||
void add_timestamped_line(const LLChat& chat, const LLColor4& color);
|
||||
|
||||
void pinn_panel();
|
||||
void float_panel();
|
||||
|
|
@ -86,10 +89,11 @@ private:
|
|||
S32 mStart_X;
|
||||
S32 mStart_Y;
|
||||
|
||||
//LLResizeBar* mResizeBar[RESIZE_BAR_COUNT];
|
||||
LLHandle<LLView> mPopupMenuHandle;
|
||||
LLPanel* mChatCaptionPanel;
|
||||
LLViewerTextEditor* mChatHistoryEditor;
|
||||
|
||||
bool m_isDirty;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -41,30 +41,227 @@
|
|||
#include "llviewercontrol.h"
|
||||
|
||||
#include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
|
||||
#include "llviewerwindow.h"//for screen channel position
|
||||
|
||||
//add LLNearbyChatHandler to LLNotificationsUI namespace
|
||||
namespace LLNotificationsUI{
|
||||
using namespace LLNotificationsUI;
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
//LLNearbyChatScreenChannel
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
LLToastPanelBase* createToastPanel()
|
||||
{
|
||||
LLNearbyChatToastPanel* item = LLNearbyChatToastPanel::createInstance();
|
||||
static S32 chat_item_width = 304;
|
||||
item->setWidth(chat_item_width);
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
class LLNearbyChatScreenChannel: public LLScreenChannelBase
|
||||
{
|
||||
public:
|
||||
LLNearbyChatScreenChannel(const LLUUID& id):LLScreenChannelBase(id) { mActiveMessages = 0;};
|
||||
|
||||
void init (S32 channel_left, S32 channel_right);
|
||||
|
||||
void addNotification (LLSD& notification);
|
||||
void arrangeToasts ();
|
||||
void showToastsBottom ();
|
||||
|
||||
typedef boost::function<LLToastPanelBase* (void )> create_toast_panel_callback_t;
|
||||
void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;}
|
||||
|
||||
void onToastDestroyed (LLToast* toast);
|
||||
void onToastFade (LLToast* toast);
|
||||
|
||||
// hide all toasts from screen, but not remove them from a channel
|
||||
virtual void hideToastsFromScreen()
|
||||
{
|
||||
};
|
||||
// removes all toasts from a channel
|
||||
virtual void removeToastsFromChannel()
|
||||
{
|
||||
for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
|
||||
{
|
||||
LLToast* toast = (*it);
|
||||
toast->setVisible(FALSE);
|
||||
toast->stopTimer();
|
||||
m_toast_pool.push_back(toast);
|
||||
|
||||
}
|
||||
m_active_toasts.clear();
|
||||
};
|
||||
|
||||
protected:
|
||||
void createOverflowToast(S32 bottom, F32 timer);
|
||||
|
||||
create_toast_panel_callback_t m_create_toast_panel_callback_t;
|
||||
|
||||
bool createPoolToast();
|
||||
|
||||
std::vector<LLToast*> m_active_toasts;
|
||||
std::list<LLToast*> m_toast_pool;
|
||||
|
||||
S32 mActiveMessages;
|
||||
};
|
||||
|
||||
void LLNearbyChatScreenChannel::init(S32 channel_left, S32 channel_right)
|
||||
{
|
||||
S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
|
||||
S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom;
|
||||
setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
|
||||
setVisible(TRUE);
|
||||
}
|
||||
|
||||
|
||||
void LLNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer)
|
||||
{
|
||||
//we don't need overflow toast in nearby chat
|
||||
}
|
||||
|
||||
void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast)
|
||||
{
|
||||
}
|
||||
|
||||
void LLNearbyChatScreenChannel::onToastFade(LLToast* toast)
|
||||
{
|
||||
//fade mean we put toast to toast pool
|
||||
if(!toast)
|
||||
return;
|
||||
m_toast_pool.push_back(toast);
|
||||
|
||||
std::vector<LLToast*>::iterator pos = std::find(m_active_toasts.begin(),m_active_toasts.end(),toast);
|
||||
if(pos!=m_active_toasts.end())
|
||||
m_active_toasts.erase(pos);
|
||||
|
||||
arrangeToasts();
|
||||
}
|
||||
|
||||
|
||||
bool LLNearbyChatScreenChannel::createPoolToast()
|
||||
{
|
||||
LLToastPanelBase* panel= m_create_toast_panel_callback_t();
|
||||
if(!panel)
|
||||
return false;
|
||||
|
||||
LLToast::Params p;
|
||||
p.panel = panel;
|
||||
|
||||
LLToast* toast = new LLToast(p);
|
||||
|
||||
|
||||
toast->setOnFadeCallback(boost::bind(&LLNearbyChatScreenChannel::onToastFade, this, _1));
|
||||
toast->setOnToastDestroyedCallback(boost::bind(&LLNearbyChatScreenChannel::onToastDestroyed, this, _1));
|
||||
|
||||
m_toast_pool.push_back(toast);
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
|
||||
{
|
||||
//look in pool. if there is any message
|
||||
|
||||
|
||||
if(m_toast_pool.empty())
|
||||
{
|
||||
//"pool" is empty - create one more panel
|
||||
if(!createPoolToast())//created toast will go to pool. so next call will find it
|
||||
return;
|
||||
addNotification(notification);
|
||||
return;
|
||||
}
|
||||
|
||||
//take 1st element from pool, (re)initialize it, put it in active toasts
|
||||
|
||||
LLToast* toast = m_toast_pool.back();
|
||||
|
||||
m_toast_pool.pop_back();
|
||||
|
||||
|
||||
LLToastPanelBase* panel = dynamic_cast<LLToastPanelBase*>(toast->getPanel());
|
||||
if(!panel)
|
||||
return;
|
||||
panel->init(notification);
|
||||
|
||||
toast->reshapeToPanel();
|
||||
toast->resetTimer();
|
||||
|
||||
m_active_toasts.insert(m_active_toasts.begin(),toast);
|
||||
|
||||
arrangeToasts();
|
||||
}
|
||||
|
||||
void LLNearbyChatScreenChannel::arrangeToasts()
|
||||
{
|
||||
if(m_active_toasts.size() == 0 || mIsHovering)
|
||||
return;
|
||||
|
||||
hideToastsFromScreen();
|
||||
|
||||
showToastsBottom();
|
||||
}
|
||||
|
||||
void LLNearbyChatScreenChannel::showToastsBottom()
|
||||
{
|
||||
LLRect rect = getRect();
|
||||
|
||||
LLRect toast_rect;
|
||||
S32 bottom = getRect().mBottom;
|
||||
|
||||
for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
|
||||
{
|
||||
LLToast* toast = (*it);
|
||||
toast_rect = toast->getRect();
|
||||
toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight());
|
||||
|
||||
toast->setRect(toast_rect);
|
||||
|
||||
if(toast->getRect().mTop > getRect().getHeight())
|
||||
{
|
||||
while(it!=m_active_toasts.end())
|
||||
{
|
||||
(*it)->setVisible(FALSE);
|
||||
(*it)->stopTimer();
|
||||
m_toast_pool.push_back(*it);
|
||||
it=m_active_toasts.erase(it);
|
||||
}
|
||||
break;
|
||||
}
|
||||
toast->setVisible(TRUE);
|
||||
bottom = toast->getRect().mTop;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
//LLNearbyChatHandler
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id)
|
||||
{
|
||||
mType = type;
|
||||
LLChannelManager::Params p;
|
||||
p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
|
||||
|
||||
// Getting a Channel for our notifications
|
||||
mChannel = LLChannelManager::getInstance()->getChannel(p);
|
||||
LLNearbyChatScreenChannel* channel = new LLNearbyChatScreenChannel(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
|
||||
|
||||
LLNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
|
||||
|
||||
channel->setCreatePanelCallback(callback);
|
||||
|
||||
mChannel = LLChannelManager::getInstance()->addChannel(channel);
|
||||
mChannel->setOverflowFormatString("You have %d unread nearby chat messages");
|
||||
}
|
||||
|
||||
LLNearbyChatHandler::~LLNearbyChatHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LLNearbyChatHandler::initChannel()
|
||||
{
|
||||
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
|
||||
S32 channel_right_bound = nearby_chat->getRect().mRight;
|
||||
S32 channel_width = nearby_chat->getRect().mRight - 16; //HACK: 16 - ?
|
||||
S32 channel_width = nearby_chat->getRect().mRight;
|
||||
mChannel->init(channel_right_bound - channel_width, channel_right_bound);
|
||||
}
|
||||
|
||||
|
|
@ -77,41 +274,42 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
|
|||
|
||||
if(chat_msg.mText.empty())
|
||||
return;//don't process empty messages
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
// arrange a channel on a screen
|
||||
if(!mChannel->getVisible())
|
||||
{
|
||||
initChannel();
|
||||
}
|
||||
|
||||
|
||||
LLUUID id;
|
||||
id.generate();
|
||||
|
||||
LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
|
||||
LLNearbyChatScreenChannel* channel = dynamic_cast<LLNearbyChatScreenChannel*>(mChannel);
|
||||
|
||||
item->setMessage(chat_msg);
|
||||
//static S32 chat_item_width = nearby_chat->getRect().getWidth() - 16;
|
||||
static S32 chat_item_width = 304;
|
||||
item->setWidth(chat_item_width);
|
||||
item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
|
||||
|
||||
item->setVisible(true);
|
||||
|
||||
LLToast::Params p;
|
||||
p.notif_id = id;
|
||||
p.panel = item;
|
||||
p.on_delete_toast = boost::bind(&LLNearbyChatHandler::onDeleteToast, this, _1);
|
||||
mChannel->addToast(p);
|
||||
if(channel)
|
||||
{
|
||||
LLSD notification;
|
||||
notification["id"] = id;
|
||||
notification["message"] = chat_msg.mText;
|
||||
notification["from"] = chat_msg.mFromName;
|
||||
notification["from_id"] = chat_msg.mFromID;
|
||||
notification["time"] = chat_msg.mTime;
|
||||
notification["source"] = (S32)chat_msg.mSourceType;
|
||||
|
||||
channel->addNotification(notification);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLNearbyChatHandler::onDeleteToast(LLToast* toast)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -100,16 +100,23 @@ bool LLAlertHandler::processNotification(const LLSD& notify)
|
|||
p.can_fade = false;
|
||||
p.is_modal = mIsModal;
|
||||
p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
|
||||
mChannel->addToast(p);
|
||||
|
||||
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
|
||||
if(channel)
|
||||
channel->addToast(p);
|
||||
}
|
||||
else if (notify["sigtype"].asString() == "change")
|
||||
{
|
||||
LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
|
||||
mChannel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
|
||||
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
|
||||
if(channel)
|
||||
channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
|
||||
}
|
||||
else
|
||||
{
|
||||
mChannel->killToastByNotificationID(notification->getID());
|
||||
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
|
||||
if(channel)
|
||||
channel->killToastByNotificationID(notification->getID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,10 @@ bool LLGroupHandler::processNotification(const LLSD& notify)
|
|||
p.notification = notification;
|
||||
p.panel = notify_box;
|
||||
p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
|
||||
mChannel->addToast(p);
|
||||
|
||||
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
|
||||
if(channel)
|
||||
channel->addToast(p);
|
||||
|
||||
// send a signal to the counter manager
|
||||
mNewNotificationSignal();
|
||||
|
|
|
|||
|
|
@ -104,8 +104,8 @@ protected:
|
|||
// at the moment, when a handlers creates a channel.
|
||||
virtual void initChannel()=0;
|
||||
|
||||
LLScreenChannel* mChannel;
|
||||
e_notification_type mType;
|
||||
LLScreenChannelBase* mChannel;
|
||||
e_notification_type mType;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,11 @@ LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id)
|
|||
// Getting a Channel for our notifications
|
||||
mChannel = LLChannelManager::getInstance()->createNotificationChannel();
|
||||
mChannel->setControlHovering(true);
|
||||
mChannel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
|
||||
|
||||
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
|
||||
if(channel)
|
||||
channel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
@ -92,7 +96,10 @@ bool LLScriptHandler::processNotification(const LLSD& notify)
|
|||
p.notification = notification;
|
||||
p.panel = notify_box;
|
||||
p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
|
||||
mChannel->addToast(p);
|
||||
|
||||
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
|
||||
if(channel)
|
||||
channel->addToast(p);
|
||||
|
||||
// send a signal to the counter manager
|
||||
mNewNotificationSignal();
|
||||
|
|
|
|||
|
|
@ -93,8 +93,9 @@ bool LLTipHandler::processNotification(const LLSD& notify)
|
|||
p.is_tip = true;
|
||||
p.can_be_stored = false;
|
||||
|
||||
mChannel->addToast(p);
|
||||
|
||||
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
|
||||
if(channel)
|
||||
channel->addToast(p);
|
||||
}
|
||||
else if (notify["sigtype"].asString() == "delete")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ void LLPanelProfileTab::scrollToTop()
|
|||
{
|
||||
LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll");
|
||||
if (scrollContainer)
|
||||
scrollContainer->goToTop();
|
||||
scrollContainer->goToTop();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ BOOL LLPanelGroup::postBuild()
|
|||
if(panel_land) mTabs.push_back(panel_land);
|
||||
|
||||
if(panel_general)
|
||||
panel_general->setupCtrls(this);
|
||||
panel_general->setupCtrls(this);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -206,8 +206,8 @@ void LLPanelGroup::reposButton(const std::string& name)
|
|||
if(!button)
|
||||
return;
|
||||
LLRect btn_rect = button->getRect();
|
||||
btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
|
||||
button->setRect(btn_rect);
|
||||
btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
|
||||
button->setRect(btn_rect);
|
||||
}
|
||||
|
||||
void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent )
|
||||
|
|
@ -235,7 +235,14 @@ void LLPanelGroup::onBtnCreate()
|
|||
if(!panel_general)
|
||||
return;
|
||||
std::string apply_mesg;
|
||||
panel_general->apply(apply_mesg);//yes yes you need to call apply to create...
|
||||
if(panel_general->apply(apply_mesg))//yes yes you need to call apply to create...
|
||||
return;
|
||||
if ( !apply_mesg.empty() )
|
||||
{
|
||||
LLSD args;
|
||||
args["MESSAGE"] = apply_mesg;
|
||||
LLNotifications::instance().add("GenericAlert", args);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroup::onBtnRefresh(void* user_data)
|
||||
|
|
|
|||
|
|
@ -835,6 +835,7 @@ void LLPanelGroupGeneral::reset()
|
|||
{
|
||||
std::string empty_str = "";
|
||||
mEditCharter->setText(empty_str);
|
||||
mGroupNameEditor->setText(empty_str);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -850,6 +851,7 @@ void LLPanelGroupGeneral::reset()
|
|||
{
|
||||
mComboMature->setEnabled(true);
|
||||
mComboMature->setVisible( !gAgent.isTeen() );
|
||||
mComboMature->selectFirstItem();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -60,11 +60,8 @@
|
|||
#include "llvoiceclient.h"
|
||||
#include "llworld.h"
|
||||
|
||||
using namespace LLOldEvents;
|
||||
|
||||
#define FRIEND_LIST_UPDATE_TIMEOUT 0.5
|
||||
#define NEARBY_LIST_UPDATE_INTERVAL 1
|
||||
#define RECENT_LIST_UPDATE_DELAY 1
|
||||
|
||||
static const std::string NEARBY_TAB_NAME = "nearby_panel";
|
||||
static const std::string FRIENDS_TAB_NAME = "friends_panel";
|
||||
|
|
@ -102,7 +99,7 @@ static LLRegisterPanelClassWrapper<LLPanelPeople> t_people("panel_people");
|
|||
class LLPanelPeople::Updater
|
||||
{
|
||||
public:
|
||||
typedef boost::function<bool(U32)> callback_t;
|
||||
typedef boost::function<void()> callback_t;
|
||||
Updater(callback_t cb)
|
||||
: mCallback(cb)
|
||||
{
|
||||
|
|
@ -112,16 +109,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the list updates.
|
||||
*
|
||||
* This may start repeated updates until all names are complete.
|
||||
*/
|
||||
virtual void forceUpdate()
|
||||
{
|
||||
updateList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate/deactivate updater.
|
||||
*
|
||||
|
|
@ -130,9 +117,9 @@ public:
|
|||
virtual void setActive(bool) {}
|
||||
|
||||
protected:
|
||||
bool updateList(U32 mask = 0)
|
||||
void updateList()
|
||||
{
|
||||
return mCallback(mask);
|
||||
mCallback();
|
||||
}
|
||||
|
||||
callback_t mCallback;
|
||||
|
|
@ -147,6 +134,11 @@ public:
|
|||
{
|
||||
mEventTimer.stop();
|
||||
}
|
||||
|
||||
virtual BOOL tick() // from LLEventTimer
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -178,13 +170,6 @@ public:
|
|||
LLAvatarTracker::instance().removeObserver(this);
|
||||
}
|
||||
|
||||
/*virtual*/ void forceUpdate()
|
||||
{
|
||||
// Perform updates until all names are loaded.
|
||||
if (!updateList(LLFriendObserver::ADD))
|
||||
changed(LLFriendObserver::ADD);
|
||||
}
|
||||
|
||||
/*virtual*/ void changed(U32 mask)
|
||||
{
|
||||
// events can arrive quickly in bulk - we need not process EVERY one of them -
|
||||
|
|
@ -198,12 +183,12 @@ public:
|
|||
|
||||
/*virtual*/ BOOL tick()
|
||||
{
|
||||
if (updateList(mMask))
|
||||
{
|
||||
// Got all names, stop updates.
|
||||
mEventTimer.stop();
|
||||
mMask = 0;
|
||||
}
|
||||
if (mMask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
|
||||
updateList();
|
||||
|
||||
// Stop updates.
|
||||
mEventTimer.stop();
|
||||
mMask = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -329,68 +314,9 @@ class LLRecentListUpdater : public LLAvatarListUpdater, public boost::signals2::
|
|||
|
||||
public:
|
||||
LLRecentListUpdater(callback_t cb)
|
||||
: LLAvatarListUpdater(cb, RECENT_LIST_UPDATE_DELAY)
|
||||
: LLAvatarListUpdater(cb, 0)
|
||||
{
|
||||
LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::onRecentPeopleChanged, this));
|
||||
}
|
||||
|
||||
private:
|
||||
/*virtual*/ void forceUpdate()
|
||||
{
|
||||
onRecentPeopleChanged();
|
||||
}
|
||||
|
||||
/*virtual*/ BOOL tick()
|
||||
{
|
||||
// Update the list until we get all the names.
|
||||
if (updateList())
|
||||
{
|
||||
// Got all names, stop updates.
|
||||
mEventTimer.stop();
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void onRecentPeopleChanged()
|
||||
{
|
||||
if (!updateList())
|
||||
{
|
||||
// Some names are incomplete, schedule another update.
|
||||
mEventTimer.start();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the group list on events from LLAgent.
|
||||
*/
|
||||
class LLGroupListUpdater : public LLPanelPeople::Updater, public LLSimpleListener
|
||||
{
|
||||
LOG_CLASS(LLGroupListUpdater);
|
||||
|
||||
public:
|
||||
LLGroupListUpdater(callback_t cb)
|
||||
: LLPanelPeople::Updater(cb)
|
||||
{
|
||||
gAgent.addListener(this, "new group");
|
||||
}
|
||||
|
||||
~LLGroupListUpdater()
|
||||
{
|
||||
gAgent.removeListener(this);
|
||||
}
|
||||
|
||||
/*virtual*/ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
// Why is "new group" sufficient?
|
||||
if (event->desc() == "new group")
|
||||
{
|
||||
updateList();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::updateList, this));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -404,12 +330,12 @@ LLPanelPeople::LLPanelPeople()
|
|||
mOnlineFriendList(NULL),
|
||||
mAllFriendList(NULL),
|
||||
mNearbyList(NULL),
|
||||
mRecentList(NULL)
|
||||
mRecentList(NULL),
|
||||
mGroupList(NULL)
|
||||
{
|
||||
mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::onFriendListUpdate,this, _1));
|
||||
mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList, this));
|
||||
mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList, this));
|
||||
mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList, this));
|
||||
mGroupListUpdater = new LLGroupListUpdater (boost::bind(&LLPanelPeople::updateGroupList, this));
|
||||
}
|
||||
|
||||
LLPanelPeople::~LLPanelPeople()
|
||||
|
|
@ -417,7 +343,6 @@ LLPanelPeople::~LLPanelPeople()
|
|||
delete mNearbyListUpdater;
|
||||
delete mFriendListUpdater;
|
||||
delete mRecentListUpdater;
|
||||
delete mGroupListUpdater;
|
||||
|
||||
LLView::deleteViewByHandle(mGroupPlusMenuHandle);
|
||||
LLView::deleteViewByHandle(mNearbyViewSortMenuHandle);
|
||||
|
|
@ -512,7 +437,7 @@ BOOL LLPanelPeople::postBuild()
|
|||
buttonSetAction("share_btn", boost::bind(&LLPanelPeople::onShareButtonClicked, this));
|
||||
|
||||
getChild<LLPanel>(NEARBY_TAB_NAME)->childSetAction("nearby_view_sort_btn",boost::bind(&LLPanelPeople::onNearbyViewSortButtonClicked, this));
|
||||
getChild<LLPanel>(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked, this));
|
||||
getChild<LLPanel>(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked, this));
|
||||
getChild<LLPanel>(FRIENDS_TAB_NAME)->childSetAction("friends_viewsort_btn",boost::bind(&LLPanelPeople::onFriendsViewSortButtonClicked, this));
|
||||
getChild<LLPanel>(GROUP_TAB_NAME)->childSetAction("groups_viewsort_btn",boost::bind(&LLPanelPeople::onGroupsViewSortButtonClicked, this));
|
||||
|
||||
|
|
@ -547,137 +472,71 @@ BOOL LLPanelPeople::postBuild()
|
|||
if(recent_view_sort)
|
||||
mRecentViewSortMenuHandle = recent_view_sort->getHandle();
|
||||
|
||||
|
||||
|
||||
// Perform initial update.
|
||||
mFriendListUpdater->forceUpdate();
|
||||
mNearbyListUpdater->forceUpdate();
|
||||
mGroupListUpdater->forceUpdate();
|
||||
mRecentListUpdater->forceUpdate();
|
||||
|
||||
// call this method in case some list is empty and buttons can be in inconsistent state
|
||||
updateButtons();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelPeople::applyFilterToTab(const std::string& tab_name)
|
||||
{
|
||||
if (tab_name == FRIENDS_TAB_NAME) // this tab has two lists
|
||||
filterFriendList();
|
||||
else if (tab_name == NEARBY_TAB_NAME)
|
||||
filterNearbyList();
|
||||
else if (tab_name == RECENT_TAB_NAME)
|
||||
filterRecentList();
|
||||
else if (tab_name == GROUP_TAB_NAME)
|
||||
updateGroupList();
|
||||
}
|
||||
|
||||
bool LLPanelPeople::updateFriendList(U32 changed_mask)
|
||||
{
|
||||
// Refresh names.
|
||||
if (changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
|
||||
{
|
||||
// get all buddies we know about
|
||||
const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
|
||||
LLAvatarTracker::buddy_map_t all_buddies;
|
||||
av_tracker.copyBuddyList(all_buddies);
|
||||
|
||||
// *TODO: it's suboptimal to rebuild the whole lists on online status change.
|
||||
|
||||
// save them to the online and all friends vectors
|
||||
mOnlineFriendVec.clear();
|
||||
mAllFriendVec.clear();
|
||||
|
||||
LLFriendCardsManager::folderid_buddies_map_t listMap;
|
||||
|
||||
// *NOTE: For now collectFriendsLists returns data only for Friends/All folder. EXT-694.
|
||||
LLFriendCardsManager::instance().collectFriendsLists(listMap);
|
||||
if (listMap.size() > 0)
|
||||
{
|
||||
lldebugs << "Friends Cards were found, count: " << listMap.begin()->second.size() << llendl;
|
||||
mAllFriendVec = listMap.begin()->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
lldebugs << "Friends Cards were not found" << llendl;
|
||||
}
|
||||
|
||||
LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
|
||||
for (; buddy_it != all_buddies.end(); ++buddy_it)
|
||||
{
|
||||
LLUUID buddy_id = buddy_it->first;
|
||||
if (av_tracker.isBuddyOnline(buddy_id))
|
||||
mOnlineFriendVec.push_back(buddy_id);
|
||||
}
|
||||
|
||||
return filterFriendList();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLPanelPeople::updateNearbyList()
|
||||
{
|
||||
LLWorld::getInstance()->getAvatars(&mNearbyVec, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
|
||||
filterNearbyList();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLPanelPeople::updateRecentList()
|
||||
{
|
||||
LLRecentPeople::instance().get(mRecentVec);
|
||||
filterRecentList();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLPanelPeople::updateGroupList()
|
||||
{
|
||||
if (!mGroupList)
|
||||
return true; // there's no point in further updates
|
||||
|
||||
bool have_names = mGroupList->update(mFilterSubString);
|
||||
updateButtons();
|
||||
return have_names;
|
||||
}
|
||||
|
||||
bool LLPanelPeople::filterFriendList()
|
||||
void LLPanelPeople::updateFriendList()
|
||||
{
|
||||
if (!mOnlineFriendList || !mAllFriendList)
|
||||
return true; // there's no point in further updates
|
||||
return;
|
||||
|
||||
// We must always update Friends list to clear the latest removed friend.
|
||||
bool have_names =
|
||||
mOnlineFriendList->update(mOnlineFriendVec, mFilterSubString) &
|
||||
mAllFriendList->update(mAllFriendVec, mFilterSubString);
|
||||
// get all buddies we know about
|
||||
const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
|
||||
LLAvatarTracker::buddy_map_t all_buddies;
|
||||
av_tracker.copyBuddyList(all_buddies);
|
||||
|
||||
// save them to the online and all friends vectors
|
||||
LLAvatarList::uuid_vector_t& online_friendsp = mOnlineFriendList->getIDs();
|
||||
LLAvatarList::uuid_vector_t& all_friendsp = mAllFriendList->getIDs();
|
||||
|
||||
updateButtons();
|
||||
return have_names;
|
||||
}
|
||||
all_friendsp.clear();
|
||||
online_friendsp.clear();
|
||||
|
||||
bool LLPanelPeople::filterNearbyList()
|
||||
{
|
||||
bool have_names = mNearbyList->update(mNearbyVec, mFilterSubString);
|
||||
updateButtons();
|
||||
return have_names;
|
||||
}
|
||||
LLFriendCardsManager::folderid_buddies_map_t listMap;
|
||||
|
||||
bool LLPanelPeople::filterRecentList()
|
||||
{
|
||||
if (!mRecentList)
|
||||
return true;
|
||||
|
||||
if (mRecentVec.size() > 0)
|
||||
// *NOTE: For now collectFriendsLists returns data only for Friends/All folder. EXT-694.
|
||||
LLFriendCardsManager::instance().collectFriendsLists(listMap);
|
||||
if (listMap.size() > 0)
|
||||
{
|
||||
bool updated = mRecentList->update(mRecentVec, mFilterSubString);
|
||||
updateButtons();
|
||||
return updated;
|
||||
lldebugs << "Friends Cards were found, count: " << listMap.begin()->second.size() << llendl;
|
||||
all_friendsp = listMap.begin()->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
lldebugs << "Friends Cards were not found" << llendl;
|
||||
}
|
||||
|
||||
return true;
|
||||
LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
|
||||
for (; buddy_it != all_buddies.end(); ++buddy_it)
|
||||
{
|
||||
LLUUID buddy_id = buddy_it->first;
|
||||
if (av_tracker.isBuddyOnline(buddy_id))
|
||||
online_friendsp.push_back(buddy_id);
|
||||
}
|
||||
|
||||
mOnlineFriendList->setDirty();
|
||||
mAllFriendList->setDirty();
|
||||
}
|
||||
|
||||
void LLPanelPeople::updateNearbyList()
|
||||
{
|
||||
if (!mNearbyList)
|
||||
return;
|
||||
|
||||
LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
|
||||
mNearbyList->setDirty();
|
||||
}
|
||||
|
||||
void LLPanelPeople::updateRecentList()
|
||||
{
|
||||
if (!mRecentList)
|
||||
return;
|
||||
|
||||
LLRecentPeople::instance().get(mRecentList->getIDs());
|
||||
mRecentList->setDirty();
|
||||
}
|
||||
|
||||
void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible)
|
||||
|
|
@ -846,16 +705,19 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)
|
|||
LLStringUtil::toUpper(mFilterSubString);
|
||||
LLStringUtil::trimHead(mFilterSubString);
|
||||
|
||||
// Apply new filter to current tab.
|
||||
applyFilterToTab(getActiveTabName());
|
||||
// Apply new filter.
|
||||
mNearbyList->setNameFilter(mFilterSubString);
|
||||
mOnlineFriendList->setNameFilter(mFilterSubString);
|
||||
mAllFriendList->setNameFilter(mFilterSubString);
|
||||
mRecentList->setNameFilter(mFilterSubString);
|
||||
mGroupList->setNameFilter(mFilterSubString);
|
||||
}
|
||||
|
||||
void LLPanelPeople::onTabSelected(const LLSD& param)
|
||||
{
|
||||
std::string tab_name = getChild<LLPanel>(param.asString())->getName();
|
||||
mNearbyListUpdater->setActive(tab_name == NEARBY_TAB_NAME);
|
||||
applyFilterToTab(tab_name);
|
||||
// No need to call updateButtons() because applyFilterToTab() does that.
|
||||
updateButtons();
|
||||
|
||||
if (GROUP_TAB_NAME == tab_name)
|
||||
mFilterEditor->setLabel(getString("groups_filter_label"));
|
||||
|
|
@ -960,17 +822,6 @@ void LLPanelPeople::onAvatarPicked(
|
|||
LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);
|
||||
}
|
||||
|
||||
bool LLPanelPeople::onFriendListUpdate(U32 changed_mask)
|
||||
{
|
||||
bool have_names = updateFriendList(changed_mask);
|
||||
|
||||
// Update online status in the Recent tab.
|
||||
// *TODO: isn't it too much to update the whole list?
|
||||
// updateRecentList(); // mantipov: seems online status should be supported by LLAvatarListItem itself.
|
||||
|
||||
return have_names;
|
||||
}
|
||||
|
||||
void LLPanelPeople::onGroupPlusButtonClicked()
|
||||
{
|
||||
LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get();
|
||||
|
|
|
|||
|
|
@ -58,15 +58,10 @@ public:
|
|||
|
||||
private:
|
||||
// methods indirectly called by the updaters
|
||||
bool updateFriendList(U32 changed_mask);
|
||||
bool updateNearbyList();
|
||||
bool updateRecentList();
|
||||
bool updateGroupList();
|
||||
void updateFriendList();
|
||||
void updateNearbyList();
|
||||
void updateRecentList();
|
||||
|
||||
bool filterFriendList();
|
||||
bool filterNearbyList();
|
||||
bool filterRecentList();
|
||||
void applyFilterToTab(const std::string& tab_name);
|
||||
void updateButtons();
|
||||
const std::string& getActiveTabName() const;
|
||||
LLUUID getCurrentItemID() const;
|
||||
|
|
@ -110,7 +105,6 @@ private:
|
|||
void onRecentViewSortMenuItemClicked(const LLSD& userdata);
|
||||
|
||||
// misc callbacks
|
||||
bool onFriendListUpdate(U32 changed_mask);
|
||||
static void onAvatarPicked(
|
||||
const std::vector<std::string>& names,
|
||||
const std::vector<LLUUID>& ids,
|
||||
|
|
@ -135,21 +129,8 @@ private:
|
|||
Updater* mFriendListUpdater;
|
||||
Updater* mNearbyListUpdater;
|
||||
Updater* mRecentListUpdater;
|
||||
Updater* mGroupListUpdater;
|
||||
|
||||
std::string mFilterSubString;
|
||||
|
||||
// The vectors below contain up-to date avatar lists
|
||||
// for the corresponding tabs.
|
||||
// When the user enters a filter, it gets applied
|
||||
// to all the vectors and the result is shown in the tabs.
|
||||
// We don't need to have such a vector for the groups tab
|
||||
// since re-fetching the groups list is always fast.
|
||||
typedef std::vector<LLUUID> uuid_vector_t;
|
||||
uuid_vector_t mNearbyVec;
|
||||
uuid_vector_t mOnlineFriendVec;
|
||||
uuid_vector_t mAllFriendVec;
|
||||
uuid_vector_t mRecentVec;
|
||||
};
|
||||
|
||||
#endif //LL_LLPANELPEOPLE_H
|
||||
|
|
|
|||
|
|
@ -39,8 +39,10 @@
|
|||
#include "message.h"
|
||||
#include "llagent.h"
|
||||
#include "llbutton.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llparcel.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "lltexteditor.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "lluiconstants.h"
|
||||
#include "llworldmap.h"
|
||||
|
|
@ -73,7 +75,8 @@ LLPanelPick::LLPanelPick(BOOL edit_mode/* = FALSE */)
|
|||
mPickId(LLUUID::null),
|
||||
mCreatorId(LLUUID::null),
|
||||
mDataReceived(FALSE),
|
||||
mIsPickNew(false)
|
||||
mIsPickNew(false),
|
||||
mLocationChanged(false)
|
||||
{
|
||||
if (edit_mode)
|
||||
{
|
||||
|
|
@ -123,6 +126,16 @@ BOOL LLPanelPick::postBuild()
|
|||
|
||||
if (mEditMode)
|
||||
{
|
||||
enableSaveButton(FALSE);
|
||||
|
||||
mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1));
|
||||
|
||||
LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name");
|
||||
line_edit->setKeystrokeCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1), NULL);
|
||||
|
||||
LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc");
|
||||
text_edit->setKeystrokeCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1));
|
||||
|
||||
childSetAction("cancel_btn", boost::bind(&LLPanelPick::onClickCancel, this));
|
||||
childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPick::onClickSet, this));
|
||||
childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPick::onClickSave, this));
|
||||
|
|
@ -287,6 +300,26 @@ void LLPanelPick::setEditMode( BOOL edit_mode )
|
|||
updateButtons();
|
||||
}
|
||||
|
||||
void LLPanelPick::onPickChanged(LLUICtrl* ctrl)
|
||||
{
|
||||
if(mLocationChanged)
|
||||
{
|
||||
// Pick was enabled in onClickSet
|
||||
return;
|
||||
}
|
||||
|
||||
if( mSnapshotCtrl->isDirty()
|
||||
|| getChild<LLLineEditor>("pick_name")->isDirty()
|
||||
|| getChild<LLTextEditor>("pick_desc")->isDirty() )
|
||||
{
|
||||
enableSaveButton(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
enableSaveButton(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PROTECTED AREA
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -466,6 +499,9 @@ void LLPanelPick::onClickSet()
|
|||
mSimName = parcel->getName();
|
||||
}
|
||||
setPickLocation(createLocationText(std::string(""), SET_LOCATION_NOTICE, mSimName, mPosGlobal));
|
||||
|
||||
mLocationChanged = true;
|
||||
enableSaveButton(TRUE);
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -552,3 +588,12 @@ void LLPanelPick::processParcelInfo(const LLParcelData& parcel_data)
|
|||
|
||||
//*NOTE we don't removeObserver(...) ourselves cause LLRemoveParcelProcessor does it for us
|
||||
}
|
||||
|
||||
void LLPanelPick::enableSaveButton(bool enable)
|
||||
{
|
||||
if(!mEditMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
childSetEnabled(XML_BTN_SAVE, enable);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ public:
|
|||
// switches the panel to either View or Edit mode
|
||||
void setEditMode(BOOL edit_mode);
|
||||
|
||||
void onPickChanged(LLUICtrl* ctrl);
|
||||
|
||||
// because this panel works in two modes (edit/view) we are
|
||||
// free from managing two panel for editing and viewing picks and so
|
||||
// are free from controlling switching between them in the parent panel (e.g. Me Profile)
|
||||
|
|
@ -128,6 +130,8 @@ protected:
|
|||
void onClickSave();
|
||||
void onClickCancel();
|
||||
|
||||
void enableSaveButton(bool enable);
|
||||
|
||||
protected:
|
||||
BOOL mEditMode;
|
||||
LLTextureCtrl* mSnapshotCtrl;
|
||||
|
|
@ -146,6 +150,7 @@ protected:
|
|||
std::string mLocation;
|
||||
|
||||
commit_callback_t mBackCb;
|
||||
bool mLocationChanged;
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELPICK_H
|
||||
|
|
|
|||
|
|
@ -126,8 +126,7 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
|
|||
mPicksList->addItem(picture, pick_value);
|
||||
|
||||
picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickItem, this, _1));
|
||||
picture->setRightMouseDownCallback(boost::bind(&LLPanelPicks::onRightMouseDownItem, this, _1, _2, _3, _4));
|
||||
picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
|
||||
picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
|
||||
picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
|
||||
}
|
||||
|
||||
|
|
@ -260,8 +259,10 @@ void LLPanelPicks::onClickMap()
|
|||
}
|
||||
|
||||
|
||||
void LLPanelPicks::onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
|
||||
void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
|
||||
{
|
||||
updateButtons();
|
||||
|
||||
if (mPopupMenu)
|
||||
{
|
||||
mPopupMenu->buildDrawLabels();
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ private:
|
|||
void updateButtons();
|
||||
|
||||
virtual void onDoubleClickItem(LLUICtrl* item);
|
||||
virtual void onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
|
||||
virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
|
||||
|
||||
LLPanelProfile* getProfilePanel();
|
||||
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ void LLPanelPlaces::onFilterEdit(const std::string& search_string)
|
|||
LLStringUtil::trimHead(mFilterSubString);
|
||||
|
||||
if (mActivePanel)
|
||||
mActivePanel->onSearchEdit(mFilterSubString);
|
||||
mActivePanel->onSearchEdit(mFilterSubString);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -386,7 +386,7 @@ void LLPanelPlaces::onTeleportButtonClicked()
|
|||
else
|
||||
{
|
||||
if (mActivePanel)
|
||||
mActivePanel->onTeleport();
|
||||
mActivePanel->onTeleport();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -432,7 +432,7 @@ void LLPanelPlaces::onShowOnMapButtonClicked()
|
|||
else
|
||||
{
|
||||
if (mActivePanel)
|
||||
mActivePanel->onShowOnMap();
|
||||
mActivePanel->onShowOnMap();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -510,7 +510,7 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
|
|||
addChild(mPickPanel);
|
||||
|
||||
mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
|
||||
}
|
||||
}
|
||||
|
||||
togglePickPanel(TRUE);
|
||||
|
||||
|
|
@ -733,7 +733,7 @@ void LLPanelPlaces::updateVerbs()
|
|||
else
|
||||
{
|
||||
if (mActivePanel)
|
||||
mActivePanel->updateVerbs();
|
||||
mActivePanel->updateVerbs();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -306,12 +306,12 @@ void LLTeleportHistoryPanel::showTeleportHistory()
|
|||
|
||||
if (curr_tab <= tabs_cnt - 4)
|
||||
{
|
||||
curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
|
||||
curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
|
||||
}
|
||||
else if (curr_tab == tabs_cnt - 3) // 6 day and older, low boundary is 1 month
|
||||
{
|
||||
curr_date = LLDate::now();
|
||||
curr_date.split(&curr_year, &curr_month, &curr_day);
|
||||
curr_date.split(&curr_year, &curr_month, &curr_day);
|
||||
curr_month--;
|
||||
if (0 == curr_month)
|
||||
{
|
||||
|
|
@ -376,7 +376,7 @@ void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
|
|||
S32 tabs_cnt = mItemContainers.size();
|
||||
|
||||
for (S32 n = 0; n < tabs_cnt; n++)
|
||||
{
|
||||
{
|
||||
LLAccordionCtrlTab* tab = mItemContainers.get(n);
|
||||
|
||||
if (!tab->getVisible())
|
||||
|
|
@ -390,7 +390,7 @@ void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
|
|||
continue;
|
||||
|
||||
flv->resetSelection(true);
|
||||
}
|
||||
}
|
||||
|
||||
updateVerbs();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,36 +55,30 @@ using namespace LLNotificationsUI;
|
|||
bool LLScreenChannel::mWasStartUpToastShown = false;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLScreenChannel::LLScreenChannel(LLUUID& id): mOverflowToastPanel(NULL), mStartUpToastPanel(NULL),
|
||||
mToastAlignment(NA_BOTTOM), mCanStoreToasts(true),
|
||||
mHiddenToastsNum(0), mOverflowToastHidden(false),
|
||||
mIsHovering(false), mControlHovering(false),
|
||||
mShowToasts(true)
|
||||
//////////////////////
|
||||
// LLScreenChannelBase
|
||||
//////////////////////
|
||||
LLScreenChannelBase::LLScreenChannelBase(const LLUUID& id) :
|
||||
mOverflowToastPanel(NULL)
|
||||
,mToastAlignment(NA_BOTTOM)
|
||||
,mCanStoreToasts(true)
|
||||
,mHiddenToastsNum(0)
|
||||
,mOverflowToastHidden(false)
|
||||
,mIsHovering(false)
|
||||
,mControlHovering(false)
|
||||
,mShowToasts(false)
|
||||
{
|
||||
mID = id;
|
||||
mOverflowFormatString = LLTrans::getString("OverflowInfoChannelString");
|
||||
mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannel::updatePositionAndSize, this, _1, _2));
|
||||
mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannelBase::updatePositionAndSize, this, _1, _2));
|
||||
setMouseOpaque( false );
|
||||
setVisible(FALSE);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::init(S32 channel_left, S32 channel_right)
|
||||
{
|
||||
S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
|
||||
S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
|
||||
setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
|
||||
setVisible(TRUE);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLScreenChannel::~LLScreenChannel()
|
||||
LLScreenChannelBase::~LLScreenChannelBase()
|
||||
{
|
||||
mWorldViewRectConnection.disconnect();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
|
||||
void LLScreenChannelBase::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
|
||||
{
|
||||
S32 top_delta = old_world_rect.mTop - new_world_rect.mTop;
|
||||
S32 right_delta = old_world_rect.mRight - new_world_rect.mRight;
|
||||
|
|
@ -105,6 +99,42 @@ void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_wo
|
|||
}
|
||||
setRect(this_rect);
|
||||
redrawToasts();
|
||||
|
||||
}
|
||||
|
||||
void LLScreenChannelBase::init(S32 channel_left, S32 channel_right)
|
||||
{
|
||||
S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
|
||||
S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
|
||||
setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
|
||||
setVisible(TRUE);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//////////////////////
|
||||
// LLScreenChannel
|
||||
//////////////////////
|
||||
//--------------------------------------------------------------------------
|
||||
LLScreenChannel::LLScreenChannel(LLUUID& id): LLScreenChannelBase(id)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::init(S32 channel_left, S32 channel_right)
|
||||
{
|
||||
LLScreenChannelBase::init(channel_left, channel_right);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
LLScreenChannel::~LLScreenChannel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
|
||||
{
|
||||
LLScreenChannelBase::updatePositionAndSize(old_world_rect, new_world_rect);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
@ -561,7 +591,7 @@ void LLScreenChannel::removeAndStoreAllStorableToasts()
|
|||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
redrawToasts();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,10 +55,95 @@ typedef enum e_channel_alignment
|
|||
CA_RIGHT,
|
||||
} EChannelAlignment;
|
||||
|
||||
class LLScreenChannelBase : public LLUICtrl
|
||||
{
|
||||
friend class LLChannelManager;
|
||||
public:
|
||||
LLScreenChannelBase(const LLUUID& id);
|
||||
~LLScreenChannelBase();
|
||||
|
||||
// Channel's outfit-functions
|
||||
// update channel's size and position in the World View
|
||||
virtual void updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect);
|
||||
// initialization of channel's shape and position
|
||||
virtual void init(S32 channel_left, S32 channel_right);
|
||||
|
||||
|
||||
virtual void setToastAlignment(EToastAlignment align) {mToastAlignment = align;}
|
||||
|
||||
virtual void setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;}
|
||||
virtual void setOverflowFormatString ( const std::string& str) { mOverflowFormatString = str; }
|
||||
|
||||
// kill or modify a toast by its ID
|
||||
virtual void killToastByNotificationID(LLUUID id) {};
|
||||
virtual void modifyToastNotificationByID(LLUUID id, LLSD data) {};
|
||||
|
||||
// hide all toasts from screen, but not remove them from a channel
|
||||
virtual void hideToastsFromScreen() {};
|
||||
// removes all toasts from a channel
|
||||
virtual void removeToastsFromChannel() {};
|
||||
|
||||
// show all toasts in a channel
|
||||
virtual void redrawToasts() {};
|
||||
|
||||
virtual void closeOverflowToastPanel() {};
|
||||
virtual void hideOverflowToastPanel() {};
|
||||
|
||||
|
||||
// Channel's behavior-functions
|
||||
// set whether a channel will control hovering inside itself or not
|
||||
virtual void setControlHovering(bool control) { mControlHovering = control; }
|
||||
// set Hovering flag for a channel
|
||||
virtual void setHovering(bool hovering) { mIsHovering = hovering; }
|
||||
|
||||
void setCanStoreToasts(bool store) { mCanStoreToasts = store; }
|
||||
|
||||
void setDisplayToastsAlways(bool display_toasts) { mDisplayToastsAlways = display_toasts; }
|
||||
bool getDisplayToastsAlways() { return mDisplayToastsAlways; }
|
||||
|
||||
// get number of hidden notifications from a channel
|
||||
S32 getNumberOfHiddenToasts() { return mHiddenToastsNum;}
|
||||
|
||||
|
||||
void setShowToasts(bool show) { mShowToasts = show; }
|
||||
bool getShowToasts() { return mShowToasts; }
|
||||
|
||||
// get toast allignment preset for a channel
|
||||
e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
|
||||
|
||||
// get ID of a channel
|
||||
LLUUID getChannelID() { return mID; }
|
||||
|
||||
protected:
|
||||
// Channel's flags
|
||||
bool mControlHovering;
|
||||
bool mIsHovering;
|
||||
bool mCanStoreToasts;
|
||||
bool mDisplayToastsAlways;
|
||||
bool mOverflowToastHidden;
|
||||
// controls whether a channel shows toasts or not
|
||||
bool mShowToasts;
|
||||
//
|
||||
EToastAlignment mToastAlignment;
|
||||
EChannelAlignment mChannelAlignment;
|
||||
|
||||
// attributes for the Overflow Toast
|
||||
S32 mHiddenToastsNum;
|
||||
LLToast* mOverflowToastPanel;
|
||||
std::string mOverflowFormatString;
|
||||
|
||||
// channel's ID
|
||||
LLUUID mID;
|
||||
|
||||
// store a connection to prevent futher crash that is caused by sending a signal to a destroyed channel
|
||||
boost::signals2::connection mWorldViewRectConnection;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Screen channel manages toasts visibility and positioning on the screen.
|
||||
*/
|
||||
class LLScreenChannel : public LLUICtrl
|
||||
class LLScreenChannel : public LLScreenChannelBase
|
||||
{
|
||||
friend class LLChannelManager;
|
||||
public:
|
||||
|
|
@ -70,12 +155,6 @@ public:
|
|||
void updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect);
|
||||
// initialization of channel's shape and position
|
||||
void init(S32 channel_left, S32 channel_right);
|
||||
// set allignment of toasts inside a channel
|
||||
void setToastAlignment(EToastAlignment align) {mToastAlignment = align;}
|
||||
// set allignment of channel inside a world view
|
||||
void setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;}
|
||||
// set a template for a string in the OverflowToast
|
||||
void setOverflowFormatString ( std::string str) { mOverflowFormatString = str; }
|
||||
|
||||
// Operating with toasts
|
||||
// add a toast to a channel
|
||||
|
|
@ -104,37 +183,17 @@ public:
|
|||
// close the StartUp Toast
|
||||
void closeStartUpToast();
|
||||
|
||||
// Channel's behavior-functions
|
||||
// set whether a channel will control hovering inside itself or not
|
||||
void setControlHovering(bool control) { mControlHovering = control; }
|
||||
// set Hovering flag for a channel
|
||||
void setHovering(bool hovering) { mIsHovering = hovering; }
|
||||
// set whether a channel will store faded toasts or not
|
||||
void setCanStoreToasts(bool store) { mCanStoreToasts = store; }
|
||||
// tell all channels that the StartUp toast was shown and allow them showing of toasts
|
||||
static void setStartUpToastShown() { mWasStartUpToastShown = true; }
|
||||
// get StartUp Toast's state
|
||||
static bool getStartUpToastShown() { return mWasStartUpToastShown; }
|
||||
// set mode for dislaying of toasts
|
||||
void setDisplayToastsAlways(bool display_toasts) { mDisplayToastsAlways = display_toasts; }
|
||||
// get mode for dislaying of toasts
|
||||
bool getDisplayToastsAlways() { return mDisplayToastsAlways; }
|
||||
// tell a channel to show toasts or not
|
||||
void setShowToasts(bool show) { mShowToasts = show; }
|
||||
// determine whether channel shows toasts or not
|
||||
bool getShowToasts() { return mShowToasts; }
|
||||
// tell all channels that the StartUp toast was shown and allow them showing of toasts
|
||||
static void setStartUpToastShown() { mWasStartUpToastShown = true; }
|
||||
// let a channel update its ShowToast flag
|
||||
void updateShowToastsState();
|
||||
|
||||
|
||||
// Channel's other interface functions functions
|
||||
// get number of hidden notifications from a channel
|
||||
S32 getNumberOfHiddenToasts() { return mHiddenToastsNum;}
|
||||
// update number of notifications in the StartUp Toast
|
||||
void updateStartUpString(S32 num);
|
||||
// get toast allignment preset for a channel
|
||||
e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
|
||||
// get ID of a channel
|
||||
LLUUID getChannelID() { return mID; }
|
||||
|
||||
// Channel's signals
|
||||
// signal on storing of faded toasts event
|
||||
|
|
@ -201,30 +260,10 @@ private:
|
|||
|
||||
// Channel's flags
|
||||
static bool mWasStartUpToastShown;
|
||||
bool mControlHovering;
|
||||
bool mIsHovering;
|
||||
bool mCanStoreToasts;
|
||||
bool mDisplayToastsAlways;
|
||||
bool mOverflowToastHidden;
|
||||
// controls whether a channel shows toasts or not
|
||||
bool mShowToasts;
|
||||
//
|
||||
EToastAlignment mToastAlignment;
|
||||
EChannelAlignment mChannelAlignment;
|
||||
|
||||
// attributes for the Overflow Toast
|
||||
S32 mHiddenToastsNum;
|
||||
LLToast* mOverflowToastPanel;
|
||||
std::string mOverflowFormatString;
|
||||
|
||||
// attributes for the StartUp Toast
|
||||
LLToast* mStartUpToastPanel;
|
||||
|
||||
// channel's ID
|
||||
LLUUID mID;
|
||||
|
||||
// store a connection to prevent futher crash that is caused by sending a signal to a destroyed channel
|
||||
boost::signals2::connection mWorldViewRectConnection;
|
||||
|
||||
std::vector<ToastElem> mToastList;
|
||||
std::vector<ToastElem> mStoredToastList;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include "lliconctrl.h"//for Home tab icon
|
||||
#include "llsidetraypanelcontainer.h"
|
||||
#include "llwindow.h"//for SetCursor
|
||||
#include "lltransientfloatermgr.h"
|
||||
|
||||
//#include "llscrollcontainer.h"
|
||||
|
||||
|
|
@ -248,6 +249,7 @@ LLSideTray::LLSideTray(Params& params)
|
|||
// register handler function to process data from the xml.
|
||||
// panel_name should be specified via "parameter" attribute.
|
||||
commit.add("SideTray.ShowPanel", boost::bind(&LLSideTray::showPanel, this, _2, LLUUID::null));
|
||||
LLTransientFloaterMgr::getInstance()->addControlView(this);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -448,13 +450,17 @@ void LLSideTray::reflectCollapseChange()
|
|||
setPanelRect();
|
||||
|
||||
if(mCollapsed)
|
||||
{
|
||||
gFloaterView->setSnapOffsetRight(0);
|
||||
setFocus(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gFloaterView->setSnapOffsetRight(mMaxBarWidth);
|
||||
setFocus(TRUE);
|
||||
}
|
||||
|
||||
gFloaterView->refresh();
|
||||
|
||||
setFocus( FALSE );
|
||||
}
|
||||
|
||||
void LLSideTray::arrange ()
|
||||
|
|
|
|||
|
|
@ -225,22 +225,14 @@ void LLStatusBar::draw()
|
|||
|
||||
BOOL LLStatusBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if (mHideNavbarContextMenu)
|
||||
{
|
||||
mHideNavbarContextMenu->buildDrawLabels();
|
||||
mHideNavbarContextMenu->updateParent(LLMenuGL::sMenuContainer);
|
||||
LLMenuGL::showPopup(this, mHideNavbarContextMenu, x, y);
|
||||
}
|
||||
|
||||
show_navbar_context_menu(this,x,y);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLStatusBar::postBuild()
|
||||
{
|
||||
mHideNavbarContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
||||
gMenuHolder->addChild(mHideNavbarContextMenu);
|
||||
|
||||
gMenuBarView->setRightMouseDownCallback(boost::bind(&LLStatusBar::onMainMenuRightClicked, this, _1, _2, _3, _4));
|
||||
gMenuBarView->setRightMouseDownCallback(boost::bind(&show_navbar_context_menu, _1, _2, _3));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -560,11 +552,6 @@ void LLStatusBar::setupDate()
|
|||
}
|
||||
}
|
||||
|
||||
void LLStatusBar::onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
|
||||
{
|
||||
handleRightMouseDown(x, y, mask);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLStatusBar::onClickStatGraph(void* data)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -91,7 +91,6 @@ private:
|
|||
// simple method to setup the part that holds the date
|
||||
void setupDate();
|
||||
|
||||
void onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask);
|
||||
static void onCommitSearch(LLUICtrl*, void* data);
|
||||
static void onClickSearch(void* data);
|
||||
static void onClickStatGraph(void* data);
|
||||
|
|
@ -111,8 +110,7 @@ private:
|
|||
S32 mSquareMetersCommitted;
|
||||
LLFrameTimer* mBalanceTimer;
|
||||
LLFrameTimer* mHealthTimer;
|
||||
LLMenuGL* mHideNavbarContextMenu;
|
||||
|
||||
|
||||
static std::vector<std::string> sDays;
|
||||
static std::vector<std::string> sMonths;
|
||||
static const U32 MAX_DATE_STRING_LENGTH;
|
||||
|
|
|
|||
|
|
@ -108,6 +108,14 @@ BOOL LLSysWellWindow::postBuild()
|
|||
return LLDockableFloater::postBuild();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void LLSysWellWindow::setMinimized(BOOL minimize)
|
||||
{
|
||||
setVisible(!minimize);
|
||||
|
||||
LLFloater::setMinimized(minimize);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void LLSysWellWindow::connectListUpdaterToSignal(std::string notification_type)
|
||||
{
|
||||
|
|
@ -155,10 +163,10 @@ void LLSysWellWindow::addItem(LLSysWellItem::Params p)
|
|||
{
|
||||
handleItemAdded(IT_NOTIFICATION);
|
||||
|
||||
reshapeWindow();
|
||||
reshapeWindow();
|
||||
|
||||
new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
|
||||
new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
|
||||
new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
|
||||
new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -226,11 +234,11 @@ void LLSysWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
|
|||
//---------------------------------------------------------------------------------
|
||||
void LLSysWellWindow::initChannel()
|
||||
{
|
||||
LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
|
||||
LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
|
||||
LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
|
||||
if(channel)
|
||||
mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel);
|
||||
if(mChannel)
|
||||
{
|
||||
mChannel = channel;
|
||||
mChannel->setOnStoreToastCallback(boost::bind(&LLSysWellWindow::onStoreToast, this, _1, _2));
|
||||
}
|
||||
else
|
||||
|
|
@ -240,7 +248,7 @@ void LLSysWellWindow::initChannel()
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void LLSysWellWindow::getEnabledRect(LLRect& rect)
|
||||
void LLSysWellWindow::getAllowedRect(LLRect& rect)
|
||||
{
|
||||
rect = gViewerWindow->getWorldViewRect();
|
||||
}
|
||||
|
|
@ -252,7 +260,7 @@ void LLSysWellWindow::toggleWindow()
|
|||
{
|
||||
setDockControl(new LLDockControl(
|
||||
LLBottomTray::getInstance()->getSysWell(), this,
|
||||
getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getEnabledRect, this, _1)));
|
||||
getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getAllowedRect, this, _1)));
|
||||
}
|
||||
|
||||
if(!getVisible())
|
||||
|
|
@ -404,20 +412,18 @@ bool LLSysWellWindow::isWindowEmpty()
|
|||
|
||||
//---------------------------------------------------------------------------------
|
||||
//virtual
|
||||
void LLSysWellWindow::sessionAdded(const LLUUID& sessionId,
|
||||
const std::string& name, const LLUUID& otherParticipantId)
|
||||
void LLSysWellWindow::sessionAdded(const LLUUID& session_id,
|
||||
const std::string& name, const LLUUID& other_participant_id)
|
||||
{
|
||||
if (mMessageList->getItemByValue(get_session_value(sessionId)) == NULL)
|
||||
//*TODO get rid of get_session_value, session_id's are unique, cause performance degradation with lots chiclets (IB)
|
||||
if (mMessageList->getItemByValue(get_session_value(session_id)) == NULL)
|
||||
{
|
||||
S32 chicletCounter = 0;
|
||||
LLIMModel::LLIMSession* session = get_if_there(LLIMModel::sSessionsMap,
|
||||
sessionId, (LLIMModel::LLIMSession*) NULL);
|
||||
if (session != NULL)
|
||||
S32 chicletCounter = LLIMModel::getInstance()->getNumUnread(session_id);
|
||||
if (chicletCounter > -1)
|
||||
{
|
||||
chicletCounter = session->mNumUnread;
|
||||
addIMRow(session_id, chicletCounter, name, other_participant_id);
|
||||
reshapeWindow();
|
||||
}
|
||||
addIMRow(sessionId, chicletCounter, name, otherParticipantId);
|
||||
reshapeWindow();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -491,6 +497,7 @@ LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID&
|
|||
switch (im_chiclet_type)
|
||||
{
|
||||
case LLIMChiclet::TYPE_GROUP:
|
||||
case LLIMChiclet::TYPE_AD_HOC:
|
||||
mChiclet = getChild<LLIMChiclet>("group_chiclet");
|
||||
childSetVisible("p2p_chiclet", false);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ public:
|
|||
void toggleWindow();
|
||||
/*virtual*/ BOOL canClose() { return FALSE; }
|
||||
/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
|
||||
// override LLFloater's minimization according to EXT-1216
|
||||
/*virtual*/ void setMinimized(BOOL minimize);
|
||||
|
||||
// Handlers
|
||||
void onItemClick(LLSysWellItem* item);
|
||||
|
|
@ -86,8 +88,8 @@ private:
|
|||
IT_INSTANT_MESSAGE
|
||||
}EItemType;
|
||||
|
||||
// gets a rect valid for SysWellWindow's position on a screen (EXT-1111)
|
||||
void getEnabledRect(LLRect& rect);
|
||||
// gets a rect that bounds possible positions for the SysWellWindow on a screen (EXT-1111)
|
||||
void getAllowedRect(LLRect& rect);
|
||||
// connect counter and list updaters to the corresponding signals
|
||||
void connectListUpdaterToSignal(std::string notification_type);
|
||||
// init Window's channel
|
||||
|
|
|
|||
|
|
@ -167,15 +167,30 @@ void LLToast::tick()
|
|||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void LLToast::insertPanel(LLPanel* panel)
|
||||
|
||||
void LLToast::reshapeToPanel()
|
||||
{
|
||||
LLRect panel_rect, toast_rect;
|
||||
LLPanel* panel = getPanel();
|
||||
if(!panel)
|
||||
return;
|
||||
|
||||
LLRect panel_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);
|
||||
|
||||
LLRect toast_rect = getRect();
|
||||
toast_rect.setLeftTopAndSize(toast_rect.mLeft,toast_rect.mTop,panel_rect.getWidth(), panel_rect.getHeight());
|
||||
setRect(toast_rect);
|
||||
|
||||
}
|
||||
|
||||
void LLToast::insertPanel(LLPanel* panel)
|
||||
{
|
||||
addChild(panel);
|
||||
reshapeToPanel();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -99,6 +99,9 @@ public:
|
|||
// Operating with toasts
|
||||
// insert a panel to a toast
|
||||
void insertPanel(LLPanel* panel);
|
||||
|
||||
void reshapeToPanel();
|
||||
|
||||
// get toast's panel
|
||||
LLPanel* getPanel() { return mPanel; }
|
||||
// enable/disable Toast's Hide button
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
class LLToastPanelBase: public LLPanel
|
||||
{
|
||||
public:
|
||||
virtual void init(LLSD& data){};
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for all panels that can be added to the toast.
|
||||
* All toast panels should contain necessary logic for representing certain notification
|
||||
|
|
|
|||
|
|
@ -7666,6 +7666,19 @@ class LLHelpShowFirstTimeTip : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y)
|
||||
{
|
||||
static LLMenuGL* show_navbar_context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml",
|
||||
gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
||||
if(gMenuHolder->hasVisibleMenu())
|
||||
{
|
||||
gMenuHolder->hideMenus();
|
||||
}
|
||||
show_navbar_context_menu->buildDrawLabels();
|
||||
show_navbar_context_menu->updateParent(LLMenuGL::sMenuContainer);
|
||||
LLMenuGL::showPopup(ctrl, show_navbar_context_menu, x, y);
|
||||
}
|
||||
|
||||
void initialize_menus()
|
||||
{
|
||||
// A parameterized event handler used as ctrl-8/9/0 zoom controls below.
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ void show_debug_menus(); // checks for if menus should be shown first.
|
|||
void toggle_debug_menus(void*);
|
||||
void show_context_menu( S32 x, S32 y, MASK mask );
|
||||
void show_build_mode_context_menu(S32 x, S32 y, MASK mask);
|
||||
void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y);
|
||||
BOOL enable_save_into_inventory(void*);
|
||||
void handle_reset_view();
|
||||
void handle_cut(void*);
|
||||
|
|
|
|||
|
|
@ -3223,9 +3223,9 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_trans
|
|||
// assume that pickAsync put the results in the back of the mPicks list
|
||||
if(mPicks.size() != 0)
|
||||
{
|
||||
mLastPick = mPicks.back();
|
||||
mLastPick.fetchResults();
|
||||
mPicks.pop_back();
|
||||
mLastPick = mPicks.back();
|
||||
mLastPick.fetchResults();
|
||||
mPicks.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
width="320"
|
||||
min_width="320"
|
||||
height="23"
|
||||
can_minimize="false"
|
||||
can_minimize="true"
|
||||
can_tear_off="false"
|
||||
can_resize="false"
|
||||
can_drag_on_left="false"
|
||||
|
|
@ -22,10 +22,10 @@
|
|||
<flat_list_view
|
||||
color="FloaterDefaultBackgroundColor"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
name="notification_list"
|
||||
left="1"
|
||||
layout="topleft"
|
||||
name="notification_list"
|
||||
left="1"
|
||||
top="20"
|
||||
height="0"
|
||||
width="318"/>
|
||||
height="0"
|
||||
width="318"/>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -128,13 +128,13 @@
|
|||
function="World.SetAway" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"/>
|
||||
layout="topleft"/>
|
||||
<menu_item_call
|
||||
label="Set Busy"
|
||||
layout="topleft"
|
||||
name="Set Busy">
|
||||
<menu_item_call.on_click
|
||||
function="World.SetBusy"/>
|
||||
function="World.SetBusy"/>
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
<menu_item_separator
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@
|
|||
label="Move"
|
||||
layout="topleft"
|
||||
name="movement_btn"
|
||||
tab_stop="false"
|
||||
tool_tip="Shows/Hide Movement controls"
|
||||
top="6"
|
||||
width="70">
|
||||
|
|
@ -117,7 +116,6 @@
|
|||
label="View"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
tab_stop="false"
|
||||
tool_tip="Shows/Hide Camera controls"
|
||||
top="6"
|
||||
name="camera_btn"
|
||||
|
|
@ -133,7 +131,6 @@
|
|||
height="20"
|
||||
width="20"
|
||||
left_pad="0"
|
||||
tab_stop="false"
|
||||
is_toggle="true"
|
||||
picture_style="true"
|
||||
image_selected="toggle_button_selected"
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
width="25"
|
||||
height="25"
|
||||
label=""
|
||||
follows="top|left"
|
||||
follows="top|right"
|
||||
image_overlay="BackArrow_Off"
|
||||
tab_stop="false" />
|
||||
<text
|
||||
|
|
@ -41,6 +41,7 @@
|
|||
text_color="white"
|
||||
follows="top|left|right"
|
||||
mouse_opaque="true"
|
||||
use_ellipses="true"
|
||||
name="group_name">(Loading...)</text>
|
||||
<line_editor
|
||||
follows="left|top"
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
follows="right"
|
||||
height="20"
|
||||
speak_button.font="SansSerifMedium"
|
||||
speak_button.tab_stop="true"
|
||||
show_button.tab_stop="true"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
name="talk"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<panel
|
||||
bevel_style="in"
|
||||
follows="left|top|right|bottom"
|
||||
height="420"
|
||||
height="460"
|
||||
label="Notes & Privacy"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
layout="topleft"
|
||||
left="0"
|
||||
top="0"
|
||||
height="420"
|
||||
height="430"
|
||||
width="313"
|
||||
border_size="0">
|
||||
<panel
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
follows="left|top|right|bottom"
|
||||
height="515"
|
||||
height="555"
|
||||
label="Picks"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
<flat_list_view
|
||||
color="DkGray2"
|
||||
follows="left|top|right|bottom"
|
||||
height="495"
|
||||
height="465"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="picks_list"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
follows="all"
|
||||
height="515"
|
||||
height="560"
|
||||
label="Profile"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
<scroll_container
|
||||
color="DkGray2"
|
||||
follows="left|top|right|bottom"
|
||||
height="515"
|
||||
height="500"
|
||||
min_height="300"
|
||||
layout="topleft"
|
||||
name="profile_scroll"
|
||||
|
|
@ -265,6 +265,7 @@
|
|||
left="0"
|
||||
name="profile_buttons_panel"
|
||||
top_pad="0"
|
||||
height="25"
|
||||
width="313">
|
||||
<button
|
||||
follows="bottom|left"
|
||||
|
|
@ -316,6 +317,7 @@
|
|||
name="profile_me_buttons_panel"
|
||||
top_pad="0"
|
||||
visible="false"
|
||||
height="25"
|
||||
width="313">
|
||||
<button
|
||||
follows="bottom|left"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<panel
|
||||
background_visible="true"
|
||||
follows="all"
|
||||
height="660"
|
||||
height="570"
|
||||
layout="topleft"
|
||||
min_height="350"
|
||||
min_width="240"
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
width="25" />
|
||||
<tab_container
|
||||
follows="left|top|right|bottom"
|
||||
height="660"
|
||||
height="560"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="tabs"
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@
|
|||
width="380">
|
||||
</flat_list_view>
|
||||
</accordion_tab>
|
||||
|
||||
|
||||
<accordion_tab
|
||||
can_resize="false"
|
||||
layout="topleft"
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
highlighted_color="ScrollHighlightedColor"
|
||||
column_padding="5"
|
||||
draw_stripes="true"
|
||||
scroll_bar_bg_visible="false"
|
||||
scroll_bar_bg_color="black"
|
||||
background_visible="false"
|
||||
heading_height="23"
|
||||
draw_border="false"
|
||||
draw_heading="false"
|
||||
scroll_bar_bg_visible="false"
|
||||
scroll_bar_bg_color="black" />
|
||||
draw_heading="false" />
|
||||
|
|
|
|||
|
|
@ -12,17 +12,20 @@
|
|||
<combo_editor
|
||||
select_on_focus="true"
|
||||
text_pad_left="20"
|
||||
tool_tip="Search"
|
||||
background_image="TextField_Search_Off"
|
||||
background_image_disabled="TextField_Search_Disabled"
|
||||
background_image_focused="TextField_Search_Active"/>
|
||||
<combo_list
|
||||
multi_select="false"
|
||||
page_lines="10" />
|
||||
page_lines="10"
|
||||
scroll_bar_bg_visible="true" />
|
||||
<search_button label=""
|
||||
top_pad="4"
|
||||
left_pad="4"
|
||||
width="13"
|
||||
height="13"
|
||||
tool_tip="Search"
|
||||
image_unselected="Search"
|
||||
image_selected="Search" />
|
||||
</search_combo_box>
|
||||
Loading…
Reference in New Issue