summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorAlexander Gavriliuk <alexandrgproductengine@lindenlab.com>2023-08-29 15:31:03 +0200
committerGuru <alexandrgproductengine@lindenlab.com>2023-08-30 03:14:32 +0200
commitf18746a1753fc8d5338fcaeb839540a071c68b13 (patch)
treeb608bcc7728dfe12ed309d5d0b4722c9d9965a03 /indra/newview
parentb9de65d2750c0f5632116864af792c40078830ab (diff)
SL-20209 EmojiPicker - Show 'Recent' panel instead of the floater on click the button
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp299
-rw-r--r--indra/newview/llfloaterimsessiontab.h44
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml41
3 files changed, 251 insertions, 133 deletions
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index bacfd8ca33..61722a823f 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -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 "llfloaterimnearbychat.h"
+#include "llgroupiconctrl.h"
#include "lllayoutstack.h"
+#include "llpanelemojicomplete.h"
#include "lltoolbarview.h"
-#include "llfloaterimnearbychat.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()) ;
}
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 7babc92897..5f8ba44e48 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -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.
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index fc54710941..56965ba7bc 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -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>