SL-20209 EmojiPicker - Show 'Recent' panel instead of the floater on click the button

master
Alexander Gavriliuk 2023-08-29 15:31:03 +02:00 committed by Guru
parent b9de65d275
commit f18746a175
3 changed files with 252 additions and 134 deletions

View File

@ -33,7 +33,6 @@
#include "llagentcamera.h"
#include "llavataractions.h"
#include "llavatariconctrl.h"
#include "llgroupiconctrl.h"
#include "llchatentry.h"
#include "llchathistory.h"
#include "llchiclet.h"
@ -43,9 +42,11 @@
#include "llfloateremojipicker.h"
#include "llfloaterimsession.h"
#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
#include "lllayoutstack.h"
#include "lltoolbarview.h"
#include "llfloaterimnearbychat.h"
#include "llgroupiconctrl.h"
#include "lllayoutstack.h"
#include "llpanelemojicomplete.h"
#include "lltoolbarview.h"
const F32 REFRESH_INTERVAL = 1.0f;
const std::string ICN_GROUP("group_chat_icon");
@ -57,7 +58,7 @@ void cb_group_do_nothing()
}
LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
: LLTransientDockableFloater(NULL, false, session_id),
: super(NULL, false, session_id),
mIsP2PChat(false),
mExpandCollapseBtn(NULL),
mTearOffBtn(NULL),
@ -76,7 +77,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
mInputPanels(NULL),
mChatLayoutPanelHeight(0)
{
setAutoFocus(FALSE);
setAutoFocus(FALSE);
mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
mCommitCallbackRegistrar.add("IMSession.Menu.Action",
@ -89,12 +90,12 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable, this, _2));
// Right click menu handling
mEnableCallbackRegistrar.add("Avatar.CheckItem", boost::bind(&LLFloaterIMSessionTab::checkContextMenuItem, this, _2));
mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMSessionTab::enableContextMenuItem, this, _2));
mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2));
mCommitCallbackRegistrar.add("Group.DoToSelected", boost::bind(&cb_group_do_nothing));
mEnableCallbackRegistrar.add("Avatar.CheckItem", boost::bind(&LLFloaterIMSessionTab::checkContextMenuItem, this, _2));
mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMSessionTab::enableContextMenuItem, this, _2));
mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2));
mCommitCallbackRegistrar.add("Group.DoToSelected", boost::bind(&cb_group_do_nothing));
mMinFloaterHeight = getMinHeight();
mMinFloaterHeight = getMinHeight();
}
LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
@ -102,7 +103,7 @@ LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
delete mRefreshTimer;
}
//static
// static
LLFloaterIMSessionTab* LLFloaterIMSessionTab::findConversation(const LLUUID& uuid)
{
LLFloaterIMSessionTab* conv;
@ -119,7 +120,7 @@ LLFloaterIMSessionTab* LLFloaterIMSessionTab::findConversation(const LLUUID& uui
return conv;
};
//static
// static
LLFloaterIMSessionTab* LLFloaterIMSessionTab::getConversation(const LLUUID& uuid)
{
LLFloaterIMSessionTab* conv;
@ -135,14 +136,16 @@ LLFloaterIMSessionTab* LLFloaterIMSessionTab::getConversation(const LLUUID& uuid
}
return conv;
};
// virtual
void LLFloaterIMSessionTab::setVisible(BOOL visible)
{
if(visible && !mHasVisibleBeenInitialized)
if (visible && !mHasVisibleBeenInitialized)
{
mHasVisibleBeenInitialized = true;
if(!gAgentCamera.cameraMouselook())
if (!gAgentCamera.cameraMouselook())
{
LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->setVisible(true);
}
@ -156,27 +159,26 @@ void LLFloaterIMSessionTab::setVisible(BOOL visible)
mInputButtonPanel->setVisible(isTornOff());
}
LLTransientDockableFloater::setVisible(visible);
super::setVisible(visible);
}
/*virtual*/
// virtual
void LLFloaterIMSessionTab::setFocus(BOOL focus)
{
LLTransientDockableFloater::setFocus(focus);
super::setFocus(focus);
//Redirect focus to input editor
if (focus)
// Redirect focus to input editor
if (focus)
{
updateMessages();
updateMessages();
if (mInputEditor)
{
mInputEditor->setFocus(TRUE);
}
if (mInputEditor)
{
mInputEditor->setFocus(TRUE);
}
}
}
void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
{
if ((session_id.notNull() && !gIMMgr->hasSession(session_id))
@ -221,44 +223,58 @@ void LLFloaterIMSessionTab::assignResizeLimits()
{
bool is_participants_pane_collapsed = mParticipantListPanel->isCollapsed();
// disable a layoutstack's functionality when participant list panel is collapsed
// disable a layoutstack's functionality when participant list panel is collapsed
mRightPartPanel->setIgnoreReshape(is_participants_pane_collapsed);
S32 participants_pane_target_width = is_participants_pane_collapsed?
0 : (mParticipantListPanel->getRect().getWidth() + mParticipantListAndHistoryStack->getPanelSpacing());
S32 participants_pane_target_width = is_participants_pane_collapsed?
0 : (mParticipantListPanel->getRect().getWidth() + mParticipantListAndHistoryStack->getPanelSpacing());
S32 new_min_width = participants_pane_target_width + mRightPartPanel->getExpandedMinDim() + mFloaterExtraWidth;
S32 new_min_width = participants_pane_target_width + mRightPartPanel->getExpandedMinDim() + mFloaterExtraWidth;
setResizeLimits(new_min_width, getMinHeight());
this->mParticipantListAndHistoryStack->updateLayout();
}
// virtual
BOOL LLFloaterIMSessionTab::postBuild()
{
BOOL result;
mBodyStack = getChild<LLLayoutStack>("main_stack");
mParticipantListAndHistoryStack = getChild<LLLayoutStack>("im_panels");
mParticipantListAndHistoryStack = getChild<LLLayoutStack>("im_panels");
mCloseBtn = getChild<LLButton>("close_btn");
mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
mCloseBtn->setCommitCallback([this](LLUICtrl*, const LLSD&) { onClickClose(this); });
mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onSlide, this));
mExpandCollapseBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onSlide(this); });
mExpandCollapseLineBtn = getChild<LLButton>("minz_btn");
mExpandCollapseLineBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onCollapseToLine, this));
mExpandCollapseLineBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onCollapseToLine(this); });
mTearOffBtn = getChild<LLButton>("tear_off_btn");
mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this));
mEmojiBtn = getChild<LLButton>("emoji_panel_btn");
mEmojiBtn->setLabel(LLUIString(LLWString(1, 128512)));
mEmojiBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onEmojiPanelBtnClicked, this));
mEmojiRecentPanelToggleBtn = getChild<LLButton>("emoji_recent_panel_toggle_btn");
mEmojiRecentPanelToggleBtn->setLabel(LLUIString(LLWString(1, 128512)));
mEmojiRecentPanelToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiRecentPanelToggleBtnClicked(this); });
mEmojiRecentPanel = getChild<LLLayoutPanel>("emoji_recent_layout_panel");
mEmojiRecentPanel->setVisible(false);
mEmojiRecentEmptyText = getChildView("emoji_recent_empty_text");
mEmojiRecentEmptyText->setVisible(false);
mEmojiRecentIconsCtrl = getChild<LLPanelEmojiComplete>("emoji_recent_icons_ctrl");
mEmojiRecentIconsCtrl->setCommitCallback([this](LLUICtrl*, const LLSD& value) { onRecentEmojiPicked(value); });
mEmojiRecentIconsCtrl->setVisible(false);
mEmojiPickerToggleBtn = getChild<LLButton>("emoji_picker_toggle_btn");
mEmojiPickerToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerToggleBtnClicked(this); });
mGearBtn = getChild<LLButton>("gear_btn");
mAddBtn = getChild<LLButton>("add_btn");
mAddBtn = getChild<LLButton>("add_btn");
mVoiceButton = getChild<LLButton>("voice_call_btn");
mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
@ -312,17 +328,17 @@ BOOL LLFloaterIMSessionTab::postBuild()
// Create the root using an ad-hoc base item
LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
p.rect = LLRect(0, 0, getRect().getWidth(), 0);
p.parent_panel = mParticipantListPanel;
p.listener = base_item;
p.view_model = &mConversationViewModel;
p.root = NULL;
p.use_ellipses = true;
p.options_menu = "menu_conversation.xml";
p.name = "root";
LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
p.rect = LLRect(0, 0, getRect().getWidth(), 0);
p.parent_panel = mParticipantListPanel;
p.listener = base_item;
p.view_model = &mConversationViewModel;
p.root = NULL;
p.use_ellipses = true;
p.options_menu = "menu_conversation.xml";
p.name = "root";
mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
mConversationsRoot->setEnableRegistrar(&mEnableCallbackRegistrar);
// Attach that root to the scroller
mScroller->addChild(mConversationsRoot);
@ -362,6 +378,7 @@ LLParticipantList* LLFloaterIMSessionTab::getParticipantList()
return dynamic_cast<LLParticipantList*>(LLFloaterIMContainer::getInstance()->getSessionModel(mSessionID));
}
// virtual
void LLFloaterIMSessionTab::draw()
{
if (mRefreshTimer->hasExpired())
@ -386,23 +403,24 @@ void LLFloaterIMSessionTab::draw()
mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);
}
LLTransientDockableFloater::draw();
super::draw();
}
void LLFloaterIMSessionTab::enableDisableCallBtn()
{
if (LLVoiceClient::instanceExists() && mVoiceButton)
{
mVoiceButton->setEnabled(
mSessionID.notNull()
&& mSession
&& mSession->mSessionInitialized
&& LLVoiceClient::getInstance()->voiceEnabled()
&& LLVoiceClient::getInstance()->isVoiceWorking()
&& mSession->mCallBackEnabled);
}
if (LLVoiceClient::instanceExists() && mVoiceButton)
{
mVoiceButton->setEnabled(
mSessionID.notNull()
&& mSession
&& mSession->mSessionInitialized
&& LLVoiceClient::getInstance()->voiceEnabled()
&& LLVoiceClient::getInstance()->isVoiceWorking()
&& mSession->mCallBackEnabled);
}
}
// virtual
void LLFloaterIMSessionTab::onFocusReceived()
{
setBackgroundOpaque(true);
@ -412,13 +430,14 @@ void LLFloaterIMSessionTab::onFocusReceived()
LLIMModel::instance().sendNoUnreadMessages(mSessionID);
}
LLTransientDockableFloater::onFocusReceived();
super::onFocusReceived();
}
// virtual
void LLFloaterIMSessionTab::onFocusLost()
{
setBackgroundOpaque(false);
LLTransientDockableFloater::onFocusLost();
super::onFocusLost();
}
void LLFloaterIMSessionTab::onInputEditorClicked()
@ -431,7 +450,17 @@ void LLFloaterIMSessionTab::onInputEditorClicked()
gToolBarView->flashCommand(LLCommandId("chat"), false);
}
void LLFloaterIMSessionTab::onEmojiPanelBtnClicked(LLFloaterIMSessionTab* self)
void LLFloaterIMSessionTab::onEmojiRecentPanelToggleBtnClicked(LLFloaterIMSessionTab* self)
{
BOOL show = !self->mEmojiRecentPanel->getVisible();
if (show)
{
self->onEmojiRecentPanelOpening();
}
self->mEmojiRecentPanel->setVisible(show);
}
void LLFloaterIMSessionTab::onEmojiPickerToggleBtnClicked(LLFloaterIMSessionTab* self)
{
if (LLFloaterEmojiPicker* picker = LLFloaterEmojiPicker::getInstance())
{
@ -452,6 +481,44 @@ void LLFloaterIMSessionTab::onEmojiPanelBtnClicked(LLFloaterIMSessionTab* self)
}
}
void LLFloaterIMSessionTab::onEmojiRecentPanelOpening()
{
std::list<llwchar>& recentlyUsed = LLFloaterEmojiPicker::getRecentlyUsed();
if (recentlyUsed.empty())
{
mEmojiRecentEmptyText->setVisible(true);
mEmojiRecentIconsCtrl->setVisible(false);
mEmojiPickerToggleBtn->setFocus(true);
}
else
{
LLWString emojis;
for (llwchar emoji : recentlyUsed)
{
emojis += emoji;
}
mEmojiRecentIconsCtrl->setEmojis(emojis);
mEmojiRecentEmptyText->setVisible(false);
mEmojiRecentIconsCtrl->setVisible(true);
mEmojiRecentIconsCtrl->setFocus(true);
}
}
void LLFloaterIMSessionTab::onRecentEmojiPicked(const LLSD& value)
{
LLSD::String str = value.asString();
if (str.size())
{
LLWString wstr = utf8string_to_wstring(str);
if (wstr.size())
{
llwchar emoji = wstr[0];
LLFloaterEmojiPicker::onEmojiUsed(emoji);
onEmojiPicked(emoji);
}
}
}
void LLFloaterIMSessionTab::onEmojiPicked(llwchar emoji)
{
mInputEditor->insertEmoji(emoji);
@ -462,6 +529,12 @@ void LLFloaterIMSessionTab::onEmojiPickerClosed()
mInputEditor->setFocus(TRUE);
}
void LLFloaterIMSessionTab::closeFloater(bool app_quitting)
{
LLFloaterEmojiPicker::saveState();
super::closeFloater(app_quitting);
}
std::string LLFloaterIMSessionTab::appendTime()
{
std::string timeStr = "[" + LLTrans::getString("TimeHour") + "]:"
@ -530,10 +603,10 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
while (current_participant_model != end_participant_model)
{
LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
if (participant_model)
{
addConversationViewParticipant(participant_model);
}
if (participant_model)
{
addConversationViewParticipant(participant_model);
}
current_participant_model++;
}
}
@ -553,10 +626,10 @@ void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* p
// If not already present, create the participant view and attach it to the root, otherwise, just refresh it
if (widget)
{
if (update_view)
{
updateConversationViewParticipant(uuid); // overkill?
}
if (update_view)
{
updateConversationViewParticipant(uuid); // overkill?
}
}
else
{
@ -606,11 +679,11 @@ void LLFloaterIMSessionTab::refreshConversation()
{
participants_uuids.push_back(widget_it->first);
}
if (widget_it->second->getViewModelItem())
{
widget_it->second->refresh();
widget_it->second->setVisible(TRUE);
}
if (widget_it->second->getViewModelItem())
{
widget_it->second->refresh();
widget_it->second->setVisible(TRUE);
}
++widget_it;
}
if (is_ad_hoc || mIsP2PChat)
@ -666,7 +739,7 @@ void LLFloaterIMSessionTab::refreshConversation()
// Copied from LLFloaterIMContainer::createConversationViewParticipant(). Refactor opportunity!
LLConversationViewParticipant* LLFloaterIMSessionTab::createConversationViewParticipant(LLConversationItem* item)
{
LLRect panel_rect = mParticipantListPanel->getRect();
LLRect panel_rect = mParticipantListPanel->getRect();
LLConversationViewParticipant::Params params;
params.name = item->getDisplayName();
@ -794,7 +867,7 @@ void LLFloaterIMSessionTab::hideAllStandardButtons()
void LLFloaterIMSessionTab::updateHeaderAndToolbar()
{
// prevent start conversation before its container
LLFloaterIMContainer::getInstance();
LLFloaterIMContainer::getInstance();
bool is_not_torn_off = !checkIfTornOff();
if (is_not_torn_off)
@ -811,12 +884,12 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
&& !mIsP2PChat;
mParticipantListAndHistoryStack->collapsePanel(mParticipantListPanel, !is_participant_list_visible);
mParticipantListPanel->setVisible(is_participant_list_visible);
mParticipantListPanel->setVisible(is_participant_list_visible);
// Display collapse image (<<) if the floater is hosted
// or if it is torn off but has an open control panel.
bool is_expanded = is_not_torn_off || is_participant_list_visible;
mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
mExpandCollapseBtn->setToolTip(
is_not_torn_off?
@ -845,10 +918,10 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
void LLFloaterIMSessionTab::forceReshape()
{
LLRect floater_rect = getRect();
reshape(llmax(floater_rect.getWidth(), this->getMinWidth()),
llmax(floater_rect.getHeight(), this->getMinHeight()),
true);
LLRect floater_rect = getRect();
reshape(llmax(floater_rect.getWidth(), this->getMinWidth()),
llmax(floater_rect.getHeight(), this->getMinHeight()),
true);
}
@ -874,7 +947,7 @@ void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/*
LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
if (nearby_chat)
{
nearby_chat->reloadMessages(clean_messages);
nearby_chat->reloadMessages(clean_messages);
}
}
@ -920,15 +993,15 @@ void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)
{
if (!self->mIsP2PChat)
{
// The state must toggle the collapsed state of the panel
should_be_expanded = self->mParticipantListPanel->isCollapsed();
// The state must toggle the collapsed state of the panel
should_be_expanded = self->mParticipantListPanel->isCollapsed();
// Update the expand/collapse flag of the participant list panel and save it
gSavedSettings.setBOOL("IMShowControlPanel", should_be_expanded);
self->mIsParticipantListExpanded = should_be_expanded;
// Refresh for immediate feedback
self->refreshConversation();
gSavedSettings.setBOOL("IMShowControlPanel", should_be_expanded);
self->mIsParticipantListExpanded = should_be_expanded;
// Refresh for immediate feedback
self->refreshConversation();
}
}
@ -965,12 +1038,12 @@ void LLFloaterIMSessionTab::reshapeFloater(bool collapse)
+ mChatLayoutPanel->getRect().getHeight() - mChatLayoutPanelHeight + 2;
floater_rect.mTop -= height;
setResizeLimits(getMinWidth(), floater_rect.getHeight());
setResizeLimits(getMinWidth(), floater_rect.getHeight());
}
else
{
floater_rect.mTop = floater_rect.mBottom + mFloaterHeight;
setResizeLimits(getMinWidth(), mMinFloaterHeight);
setResizeLimits(getMinWidth(), mMinFloaterHeight);
}
enableResizeCtrls(true, true, !collapse);
@ -995,7 +1068,7 @@ void LLFloaterIMSessionTab::restoreFloater()
setShape(floater_rect, true);
mBodyStack->updateLayout();
mExpandCollapseLineBtn->setImageOverlay(getString("expandline_icon"));
setResizeLimits(getMinWidth(), mMinFloaterHeight);
setResizeLimits(getMinWidth(), mMinFloaterHeight);
setMessagePaneExpanded(true);
saveCollapsedState();
mInputEditor->enableSingleLineMode(false);
@ -1021,8 +1094,8 @@ void LLFloaterIMSessionTab::onTearOffClicked()
{
restoreFloater();
setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE);
mSaveRect = isTornOff();
initRectControl();
mSaveRect = isTornOff();
initRectControl();
LLFloater::onClickTearOff(this);
LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
@ -1112,8 +1185,8 @@ bool LLFloaterIMSessionTab::checkIfTornOff()
void LLFloaterIMSessionTab::doToSelected(const LLSD& userdata)
{
// Get the list of selected items in the tab
std::string command = userdata.asString();
uuid_vec_t selected_uuids;
std::string command = userdata.asString();
uuid_vec_t selected_uuids;
getSelectedUUIDs(selected_uuids);
// Perform the command (IM, profile, etc...) on the list using the general conversation container method
@ -1125,8 +1198,8 @@ void LLFloaterIMSessionTab::doToSelected(const LLSD& userdata)
bool LLFloaterIMSessionTab::enableContextMenuItem(const LLSD& userdata)
{
// Get the list of selected items in the tab
std::string command = userdata.asString();
uuid_vec_t selected_uuids;
std::string command = userdata.asString();
uuid_vec_t selected_uuids;
getSelectedUUIDs(selected_uuids);
// Perform the item enable test on the list using the general conversation container method
@ -1137,8 +1210,8 @@ bool LLFloaterIMSessionTab::enableContextMenuItem(const LLSD& userdata)
bool LLFloaterIMSessionTab::checkContextMenuItem(const LLSD& userdata)
{
// Get the list of selected items in the tab
std::string command = userdata.asString();
uuid_vec_t selected_uuids;
std::string command = userdata.asString();
uuid_vec_t selected_uuids;
getSelectedUUIDs(selected_uuids);
// Perform the item check on the list using the general conversation container method
@ -1148,19 +1221,19 @@ bool LLFloaterIMSessionTab::checkContextMenuItem(const LLSD& userdata)
void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids)
{
const std::set<LLFolderViewItem*> selected_items = mConversationsRoot->getSelectionList();
const std::set<LLFolderViewItem*> selected_items = mConversationsRoot->getSelectionList();
std::set<LLFolderViewItem*>::const_iterator it = selected_items.begin();
const std::set<LLFolderViewItem*>::const_iterator it_end = selected_items.end();
std::set<LLFolderViewItem*>::const_iterator it = selected_items.begin();
const std::set<LLFolderViewItem*>::const_iterator it_end = selected_items.end();
for (; it != it_end; ++it)
{
LLConversationItem* conversation_item = static_cast<LLConversationItem *>((*it)->getViewModelItem());
if (conversation_item)
{
selected_uuids.push_back(conversation_item->getUUID());
}
}
for (; it != it_end; ++it)
{
LLConversationItem* conversation_item = static_cast<LLConversationItem *>((*it)->getViewModelItem());
if (conversation_item)
{
selected_uuids.push_back(conversation_item->getUUID());
}
}
}
LLConversationItem* LLFloaterIMSessionTab::getCurSelectedViewModelItem()
@ -1168,8 +1241,8 @@ LLConversationItem* LLFloaterIMSessionTab::getCurSelectedViewModelItem()
LLConversationItem *conversationItem = NULL;
if(mConversationsRoot &&
mConversationsRoot->getCurSelectedItem() &&
mConversationsRoot->getCurSelectedItem()->getViewModelItem())
mConversationsRoot->getCurSelectedItem() &&
mConversationsRoot->getCurSelectedItem()->getViewModelItem())
{
conversationItem = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem()) ;
}

View File

@ -41,10 +41,12 @@
class LLPanelChatControlPanel;
class LLChatEntry;
class LLChatHistory;
class LLPanelEmojiComplete;
class LLFloaterIMSessionTab
: public LLTransientDockableFloater
{
using super = LLTransientDockableFloater;
public:
LOG_CLASS(LLFloaterIMSessionTab);
@ -68,9 +70,8 @@ public:
bool isHostAttached() {return mIsHostAttached;}
void setHostAttached(bool is_attached) {mIsHostAttached = is_attached;}
static LLFloaterIMSessionTab* findConversation(const LLUUID& uuid);
static LLFloaterIMSessionTab* getConversation(const LLUUID& uuid);
static LLFloaterIMSessionTab* findConversation(const LLUUID& uuid);
static LLFloaterIMSessionTab* getConversation(const LLUUID& uuid);
bool isNearbyChat() {return mIsNearbyChat;}
@ -80,6 +81,7 @@ public:
/*virtual*/ void draw();
/*virtual*/ void setVisible(BOOL visible);
/*virtual*/ void setFocus(BOOL focus);
/*virtual*/ void closeFloater(bool app_quitting = false);
// Handle the left hand participant list widgets
void addConversationViewParticipant(LLConversationItem* item, bool update_view = true);
@ -136,8 +138,8 @@ protected:
virtual void enableDisableCallBtn();
// process focus events to set a currently active session
/* virtual */ void onFocusLost();
/* virtual */ void onFocusReceived();
/* virtual */ void onFocusLost();
// prepare chat's params and out one message to chatHistory
void appendMessage(const LLChat& chat, const LLSD& args = LLSD());
@ -152,8 +154,7 @@ protected:
bool mMessagePaneExpanded;
bool mIsParticipantListExpanded;
S32 mMinFloaterHeight;
S32 mMinFloaterHeight;
LLIMModel::LLIMSession* mSession;
@ -168,33 +169,37 @@ protected:
LLLayoutPanel* mContentPanel;
LLLayoutPanel* mToolbarPanel;
LLLayoutPanel* mInputButtonPanel;
LLLayoutPanel* mEmojiRecentPanel;
LLView* mEmojiRecentEmptyText;
LLPanelEmojiComplete* mEmojiRecentIconsCtrl;
LLParticipantList* getParticipantList();
conversations_widgets_map mConversationsWidgets;
LLConversationViewModel mConversationViewModel;
LLFolderView* mConversationsRoot;
LLScrollContainer* mScroller;
LLChatHistory* mChatHistory;
LLChatHistory* mChatHistory;
LLChatEntry* mInputEditor;
LLLayoutPanel * mChatLayoutPanel;
LLLayoutStack * mInputPanels;
LLLayoutPanel* mChatLayoutPanel;
LLLayoutStack* mInputPanels;
LLButton* mExpandCollapseLineBtn;
LLButton* mExpandCollapseBtn;
LLButton* mTearOffBtn;
LLButton* mEmojiBtn;
LLButton* mEmojiRecentPanelToggleBtn;
LLButton* mEmojiPickerToggleBtn;
LLButton* mCloseBtn;
LLButton* mGearBtn;
LLButton* mAddBtn;
LLButton* mVoiceButton;
LLButton* mVoiceButton;
private:
// Handling selection and contextual menu
void doToSelected(const LLSD& userdata);
bool enableContextMenuItem(const LLSD& userdata);
bool checkContextMenuItem(const LLSD& userdata);
void doToSelected(const LLSD& userdata);
bool enableContextMenuItem(const LLSD& userdata);
bool checkContextMenuItem(const LLSD& userdata);
void getSelectedUUIDs(uuid_vec_t& selected_uuids);
void getSelectedUUIDs(uuid_vec_t& selected_uuids);
/// Refreshes the floater at a constant rate.
virtual void refresh() = 0;
@ -208,13 +213,16 @@ private:
void onInputEditorClicked();
static void onEmojiPanelBtnClicked(LLFloaterIMSessionTab* self);
static void onEmojiRecentPanelToggleBtnClicked(LLFloaterIMSessionTab* self);
static void onEmojiPickerToggleBtnClicked(LLFloaterIMSessionTab* self);
void onEmojiRecentPanelOpening();
void onRecentEmojiPicked(const LLSD& value);
void onEmojiPicked(llwchar emoji);
void onEmojiPickerClosed();
bool checkIfTornOff();
bool mIsHostAttached;
bool mHasVisibleBeenInitialized;
bool mIsHostAttached;
bool mHasVisibleBeenInitialized;
LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.

View File

@ -300,8 +300,8 @@
right="-30"
wrap="true" />
<button
name="emoji_panel_btn"
tool_tip="Shows/hides emoji picker"
name="emoji_recent_panel_toggle_btn"
tool_tip="Shows/hides recent emojis"
follows="right|bottom"
use_font_color="true"
font="EmojiLarge"
@ -332,6 +332,43 @@
</layout_panel>
</layout_stack>
</layout_panel>
<layout_panel
name="emoji_recent_layout_panel"
height="35"
auto_resize="false">
<text
name="emoji_recent_empty_text"
follows="top|left|right"
layout="topleft"
auto_resize="false"
h_pad="20"
v_pad="10"
top="0"
left="5"
right="-60"
height="30"
>Recently used emojis will appear here</text>
<emoji_complete
name="emoji_recent_icons_ctrl"
follows="top|left|right"
layout="topleft"
noscroll="true"
max_emoji="20"
top="0"
left="5"
right="-60"
height="30"/>
<button
name="emoji_picker_toggle_btn"
label="More"
tool_tip="Shows/hides emoji picker"
follows="right|bottom"
layout="topleft"
bottom="-5"
right="-5"
height="30"
width="60"/>
</layout_panel>
</layout_stack>
</view>
</floater>