summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavriliuk <alexandrgproductengine@lindenlab.com>2023-04-14 07:44:56 +0200
committerAlexander Gavriliuk <alexandrgproductengine@lindenlab.com>2023-04-14 17:27:30 +0200
commitff7ebf08922293c1623b7bdb8c9923c14fc9db48 (patch)
tree0ea63b12ec8cbd8d495c85c141fc783306d7dde1
parent638a45cbb1aeb228a0cf910571f1af8759c003a9 (diff)
SL-19575 Create emoji gallery access icon
-rw-r--r--indra/llui/llemojidictionary.h2
-rw-r--r--indra/llui/llemojihelper.cpp10
-rw-r--r--indra/llui/llemojihelper.h6
-rw-r--r--indra/llui/llscrolllistctrl.cpp2
-rw-r--r--indra/llui/lltexteditor.cpp22
-rw-r--r--indra/llui/lltexteditor.h3
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llfloateremojipicker.cpp143
-rw-r--r--indra/newview/llfloateremojipicker.h59
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp30
-rw-r--r--indra/newview/llfloaterimsessiontab.h4
-rw-r--r--indra/newview/llviewerfloaterreg.cpp20
-rw-r--r--indra/newview/skins/default/textures/icons/emoji_picker_icon.pngbin0 -> 316 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml5
-rw-r--r--indra/newview/skins/default/xui/en/floater_emoji_picker.xml39
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml14
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml10
17 files changed, 335 insertions, 36 deletions
diff --git a/indra/llui/llemojidictionary.h b/indra/llui/llemojidictionary.h
index 46a61f1cd7..adc22ced58 100644
--- a/indra/llui/llemojidictionary.h
+++ b/indra/llui/llemojidictionary.h
@@ -61,6 +61,8 @@ public:
const LLEmojiDescriptor* getDescriptorFromShortCode(const std::string& short_code) const;
std::string getNameFromEmoji(llwchar ch) const;
+ const std::map<llwchar, const LLEmojiDescriptor*>& getEmoji2Descr() const { return mEmoji2Descr; }
+
private:
void addEmoji(LLEmojiDescriptor&& descr);
diff --git a/indra/llui/llemojihelper.cpp b/indra/llui/llemojihelper.cpp
index 1e4c19a183..fb660a9e5b 100644
--- a/indra/llui/llemojihelper.cpp
+++ b/indra/llui/llemojihelper.cpp
@@ -82,12 +82,12 @@ bool LLEmojiHelper::isCursorInEmojiCode(const LLWString& wtext, S32 cursorPos, S
return isShortCode;
}
-void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, const std::string& short_code, std::function<void(LLWString)> cb)
+void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, const std::string& short_code, std::function<void(llwchar)> cb)
{
// Commit immediately if the user already typed a full shortcode
if (const auto* emojiDescrp = LLEmojiDictionary::instance().getDescriptorFromShortCode(short_code))
{
- cb(LLWString(1, emojiDescrp->Character));
+ cb(emojiDescrp->Character);
hideHelper();
return;
}
@@ -96,7 +96,7 @@ void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, c
{
LLFloater* pHelperFloater = LLFloaterReg::getInstance(DEFAULT_EMOJI_HELPER_FLOATER);
mHelperHandle = pHelperFloater->getHandle();
- mHelperCommitConn = pHelperFloater->setCommitCallback(std::bind([&](const LLSD& sdValue) { onCommitEmoji(utf8str_to_wstring(sdValue.asStringRef())); }, std::placeholders::_2));
+ mHelperCommitConn = pHelperFloater->setCommitCallback(std::bind([&](const LLSD& sdValue) { onCommitEmoji(utf8str_to_wstring(sdValue.asStringRef())[0]); }, std::placeholders::_2));
}
setHostCtrl(hostctrl_p);
mEmojiCommitCb = cb;
@@ -135,11 +135,11 @@ bool LLEmojiHelper::handleKey(const LLUICtrl* ctrl_p, KEY key, MASK mask)
return mHelperHandle.get()->handleKey(key, mask, true);
}
-void LLEmojiHelper::onCommitEmoji(const LLWString& wstr)
+void LLEmojiHelper::onCommitEmoji(llwchar emoji)
{
if (!mHostHandle.isDead() && mEmojiCommitCb)
{
- mEmojiCommitCb(wstr);
+ mEmojiCommitCb(emoji);
}
}
diff --git a/indra/llui/llemojihelper.h b/indra/llui/llemojihelper.h
index 63f5c640c9..58f68d12a4 100644
--- a/indra/llui/llemojihelper.h
+++ b/indra/llui/llemojihelper.h
@@ -44,12 +44,12 @@ public:
std::string getToolTip(llwchar ch) const;
bool isActive(const LLUICtrl* ctrl_p) const;
static bool isCursorInEmojiCode(const LLWString& wtext, S32 cursor_pos, S32* short_code_pos_p = nullptr);
- void showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, const std::string& short_code, std::function<void(LLWString)> commit_cb);
+ void showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, const std::string& short_code, std::function<void(llwchar)> commit_cb);
void hideHelper(const LLUICtrl* ctrl_p = nullptr);
// Eventing
bool handleKey(const LLUICtrl* ctrl_p, KEY key, MASK mask);
- void onCommitEmoji(const LLWString& wstr);
+ void onCommitEmoji(llwchar emoji);
protected:
LLUICtrl* getHostCtrl() const { return mHostHandle.get(); }
@@ -60,5 +60,5 @@ private:
LLHandle<LLFloater> mHelperHandle;
boost::signals2::connection mHostCtrlFocusLostConn;
boost::signals2::connection mHelperCommitConn;
- std::function<void(LLWString)> mEmojiCommitCb;
+ std::function<void(llwchar)> mEmojiCommitCb;
};
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 219667f766..2a6e8a6b76 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -411,7 +411,7 @@ void LLScrollListCtrl::clearRows()
LLScrollListItem* LLScrollListCtrl::getFirstSelected() const
{
item_list::const_iterator iter;
- for(iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
{
LLScrollListItem* item = *iter;
if (item->getSelected())
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index a85ac2a5a3..95d8b666ab 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -680,18 +680,24 @@ void LLTextEditor::selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_p
endSelection();
}
-void LLTextEditor::handleEmojiCommit(const LLWString& wstr)
+void LLTextEditor::insertEmoji(llwchar emoji)
{
- LLWString wtext(getWText()); S32 shortCodePos;
- if (LLEmojiHelper::isCursorInEmojiCode(wtext, mCursorPos, &shortCodePos))
+ auto styleParams = LLStyle::Params();
+ styleParams.font = LLFontGL::getFontEmoji();
+ auto segment = new LLEmojiTextSegment(new LLStyle(styleParams), mCursorPos, mCursorPos + 1, *this);
+ insert(mCursorPos, LLWString(1, emoji), false, segment);
+ setCursorPos(mCursorPos + 1);
+}
+
+void LLTextEditor::handleEmojiCommit(llwchar emoji)
+{
+ S32 shortCodePos;
+ if (LLEmojiHelper::isCursorInEmojiCode(getWText(), mCursorPos, &shortCodePos))
{
remove(shortCodePos, mCursorPos - shortCodePos, true);
+ setCursorPos(shortCodePos);
- auto styleParams = LLStyle::Params();
- styleParams.font = LLFontGL::getFontEmoji();
- insert(shortCodePos, wstr, false, new LLEmojiTextSegment(new LLStyle(styleParams), shortCodePos, shortCodePos + wstr.size(), *this));
-
- setCursorPos(shortCodePos + 1);
+ insertEmoji(emoji);
}
}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index dabd0460c6..f830732cb8 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -92,7 +92,8 @@ public:
static S32 spacesPerTab();
- void handleEmojiCommit(const LLWString& wstr);
+ void insertEmoji(llwchar emoji);
+ void handleEmojiCommit(llwchar emoji);
// mousehandler overrides
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ab0c60a402..1f8b937965 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -205,6 +205,7 @@ set(viewer_SOURCE_FILES
llfloaterdisplayname.cpp
llfloatereditenvironmentbase.cpp
llfloatereditextdaycycle.cpp
+ llfloateremojipicker.cpp
llfloaterenvironmentadjust.cpp
llfloaterevent.cpp
llfloaterexperiencepicker.cpp
@@ -845,6 +846,7 @@ set(viewer_HEADER_FILES
llfloaterdisplayname.h
llfloatereditenvironmentbase.h
llfloatereditextdaycycle.h
+ llfloateremojipicker.h
llfloaterenvironmentadjust.h
llfloaterevent.h
llfloaterexperiencepicker.h
diff --git a/indra/newview/llfloateremojipicker.cpp b/indra/newview/llfloateremojipicker.cpp
new file mode 100644
index 0000000000..c828a95a59
--- /dev/null
+++ b/indra/newview/llfloateremojipicker.cpp
@@ -0,0 +1,143 @@
+/**
+ * @file llfloateremojipicker.cpp
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloateremojipicker.h"
+
+#include "llfloaterreg.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llemojidictionary.h"
+
+class LLEmojiScrollListItem : public LLScrollListItem
+{
+public:
+ LLEmojiScrollListItem(const llwchar emoji, const LLScrollListItem::Params& params)
+ : LLScrollListItem(params)
+ , mEmoji(emoji)
+ {
+ }
+
+ llwchar getEmoji() const { return mEmoji; }
+
+ virtual void draw(const LLRect& rect,
+ const LLColor4& fg_color,
+ const LLColor4& hover_color, // highlight/hover selection of whole item or cell
+ const LLColor4& select_color, // highlight/hover selection of whole item or cell
+ const LLColor4& highlight_color, // highlights contents of cells (ex: text)
+ S32 column_padding) override
+ {
+ LLScrollListItem::draw(rect, fg_color, hover_color, select_color, highlight_color, column_padding);
+
+ S32 width = getColumn(0)->getWidth();
+ LLFontGL::getFontEmoji()->render(LLWString(1, mEmoji), 0, rect.mLeft + width / 2, rect.getCenterY(), LLColor4::white,
+ LLFontGL::HCENTER, LLFontGL::VCENTER, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW_SOFT, 1, S32_MAX, nullptr, false, true);
+ }
+
+private:
+ llwchar mEmoji;
+};
+
+LLFloaterEmojiPicker* LLFloaterEmojiPicker::getInstance()
+{
+ LLFloaterEmojiPicker* floater = LLFloaterReg::getTypedInstance<LLFloaterEmojiPicker>("emoji_picker");
+ if (!floater)
+ LL_WARNS() << "Cannot instantiate emoji picker" << LL_ENDL;
+ return floater;
+}
+
+LLFloaterEmojiPicker* LLFloaterEmojiPicker::showInstance(select_callback_t callback)
+{
+ LLFloaterEmojiPicker* floater = getInstance();
+ if (LLFloaterEmojiPicker* floater = getInstance())
+ floater->show(callback);
+ return floater;
+}
+
+void LLFloaterEmojiPicker::show(select_callback_t callback)
+{
+ mSelectCallback = callback;
+ openFloater(mKey);
+ setFocus(TRUE);
+}
+
+LLFloaterEmojiPicker::LLFloaterEmojiPicker(const LLSD& key)
+: LLFloater(key)
+{
+}
+
+BOOL LLFloaterEmojiPicker::postBuild()
+{
+ if (mEmojis = getChild<LLScrollListCtrl>("Emojis"))
+ {
+ mEmojis->setDoubleClickCallback(boost::bind(&LLFloaterEmojiPicker::onSelect, this));
+
+ mEmojis->clearRows();
+
+ const std::map<llwchar, const LLEmojiDescriptor*>& emoji2Descr = LLEmojiDictionary::instance().getEmoji2Descr();
+ for (const std::pair<llwchar, const LLEmojiDescriptor*>& it : emoji2Descr)
+ {
+ LLScrollListItem::Params params;
+ params.columns.add().column("name").value(it.second->Name);
+ mEmojis->addRow(new LLEmojiScrollListItem(it.first, params), params);
+ }
+ }
+
+ return TRUE;
+}
+
+LLFloaterEmojiPicker::~LLFloaterEmojiPicker()
+{
+ gFocusMgr.releaseFocusIfNeeded( this );
+}
+
+void LLFloaterEmojiPicker::onSelect()
+{
+ if (mEmojis && mSelectCallback)
+ {
+ if (LLEmojiScrollListItem* item = dynamic_cast<LLEmojiScrollListItem*>(mEmojis->getFirstSelected()))
+ {
+ mSelectCallback(item->getEmoji());
+ }
+ }
+}
+
+// virtual
+BOOL LLFloaterEmojiPicker::handleKeyHere(KEY key, MASK mask)
+{
+ if (key == KEY_RETURN && mask == MASK_NONE)
+ {
+ onSelect();
+ return TRUE;
+ }
+ else if (key == KEY_ESCAPE && mask == MASK_NONE)
+ {
+ closeFloater();
+ return TRUE;
+ }
+
+ return LLFloater::handleKeyHere(key, mask);
+}
diff --git a/indra/newview/llfloateremojipicker.h b/indra/newview/llfloateremojipicker.h
new file mode 100644
index 0000000000..9b442064d0
--- /dev/null
+++ b/indra/newview/llfloateremojipicker.h
@@ -0,0 +1,59 @@
+/**
+ * @file llfloateremojipicker.h
+ * @brief Header file for llfloateremojipicker
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLFLOATEREMOJIPICKER_H
+#define LLFLOATEREMOJIPICKER_H
+
+#include "llfloater.h"
+
+class LLFloaterEmojiPicker : public LLFloater
+{
+public:
+ // The callback function will be called with an emoji char.
+ typedef boost::function<void (llwchar)> select_callback_t;
+
+ // Call this to select an emoji.
+ static LLFloaterEmojiPicker* getInstance();
+ static LLFloaterEmojiPicker* showInstance(select_callback_t callback);
+
+ LLFloaterEmojiPicker(const LLSD& key);
+ virtual ~LLFloaterEmojiPicker();
+
+ virtual BOOL postBuild();
+
+ void show(select_callback_t callback);
+
+private:
+ void onSelect();
+
+ virtual BOOL handleKeyHere(KEY key, MASK mask);
+
+ class LLScrollListCtrl* mEmojis;
+ select_callback_t mSelectCallback;
+ std::string mEmojiName;
+};
+
+#endif
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 78271369d2..3d9751dd35 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -40,6 +40,7 @@
#include "llchicletbar.h"
#include "lldraghandle.h"
#include "llfloaterreg.h"
+#include "llfloateremojipicker.h"
#include "llfloaterimsession.h"
#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
#include "lllayoutstack.h"
@@ -250,10 +251,13 @@ BOOL LLFloaterIMSessionTab::postBuild()
mTearOffBtn = getChild<LLButton>("tear_off_btn");
mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this));
+ mEmojiBtn = getChild<LLButton>("emoji_panel_btn");
+ mEmojiBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onEmojiPanelBtnClicked, this));
+
mGearBtn = getChild<LLButton>("gear_btn");
mAddBtn = getChild<LLButton>("add_btn");
mVoiceButton = getChild<LLButton>("voice_call_btn");
-
+
mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
mRightPartPanel = getChild<LLLayoutPanel>("right_part_holder");
@@ -424,6 +428,30 @@ void LLFloaterIMSessionTab::onInputEditorClicked()
gToolBarView->flashCommand(LLCommandId("chat"), false);
}
+void LLFloaterIMSessionTab::onEmojiPanelBtnClicked(LLFloaterIMSessionTab* self)
+{
+ if (LLFloaterEmojiPicker* picker = LLFloaterEmojiPicker::getInstance())
+ {
+ if (!picker->isShown())
+ {
+ picker->show(boost::bind(&LLFloaterIMSessionTab::onEmojiSelected, self, _1));
+ if (LLFloater* root_floater = gFloaterView->getParentFloater(self))
+ {
+ root_floater->addDependentFloater(picker);
+ }
+ }
+ else
+ {
+ picker->closeFloater();
+ }
+ }
+}
+
+void LLFloaterIMSessionTab::onEmojiSelected(llwchar emoji)
+{
+ mInputEditor->insertEmoji(emoji);
+}
+
std::string LLFloaterIMSessionTab::appendTime()
{
time_t utc_time;
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 9f00917647..cd5065420d 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -181,6 +181,7 @@ protected:
LLButton* mExpandCollapseLineBtn;
LLButton* mExpandCollapseBtn;
LLButton* mTearOffBtn;
+ LLButton* mEmojiBtn;
LLButton* mCloseBtn;
LLButton* mGearBtn;
LLButton* mAddBtn;
@@ -206,6 +207,9 @@ private:
void onInputEditorClicked();
+ static void onEmojiPanelBtnClicked(LLFloaterIMSessionTab* self);
+ void onEmojiSelected(llwchar emoji);
+
bool checkIfTornOff();
bool mIsHostAttached;
bool mHasVisibleBeenInitialized;
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 1c1aa9ea47..483b22adc8 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -65,6 +65,7 @@
#include "llfloaterdestinations.h"
#include "llfloaterdisplayname.h"
#include "llfloatereditextdaycycle.h"
+#include "llfloateremojipicker.h"
#include "llfloaterenvironmentadjust.h"
#include "llfloaterexperienceprofile.h"
#include "llfloaterexperiences.h"
@@ -329,7 +330,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>);
LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
- LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>);
+ LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>);
LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>);
@@ -337,19 +338,20 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("delete_pref_preset", "floater_delete_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeletePrefPreset>);
LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>);
- LLFloaterReg::add("emoji_complete", "floater_emoji_complete.xml", &LLFloaterReg::build<LLFloaterEmojiComplete>);
+ LLFloaterReg::add("emoji_picker", "floater_emoji_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEmojiPicker>);
+ LLFloaterReg::add("emoji_complete", "floater_emoji_complete.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEmojiComplete>);
LLFloaterReg::add("env_post_process", "floater_post_process.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPostProcess>);
- LLFloaterReg::add("env_fixed_environmentent_water", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentWater>);
- LLFloaterReg::add("env_fixed_environmentent_sky", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentSky>);
+ LLFloaterReg::add("env_fixed_environmentent_water", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentWater>);
+ LLFloaterReg::add("env_fixed_environmentent_sky", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentSky>);
- LLFloaterReg::add("env_adjust_snapshot", "floater_adjust_environment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEnvironmentAdjust>);
+ LLFloaterReg::add("env_adjust_snapshot", "floater_adjust_environment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEnvironmentAdjust>);
- LLFloaterReg::add("env_edit_extdaycycle", "floater_edit_ext_day_cycle.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditExtDayCycle>);
- LLFloaterReg::add("my_environments", "floater_my_environments.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMyEnvironment>);
+ LLFloaterReg::add("env_edit_extdaycycle", "floater_edit_ext_day_cycle.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditExtDayCycle>);
+ LLFloaterReg::add("my_environments", "floater_my_environments.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMyEnvironment>);
- LLFloaterReg::add("event", "floater_event.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEvent>);
- LLFloaterReg::add("experiences", "floater_experiences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiences>);
+ LLFloaterReg::add("event", "floater_event.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEvent>);
+ LLFloaterReg::add("experiences", "floater_experiences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiences>);
LLFloaterReg::add("experience_profile", "floater_experienceprofile.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperienceProfile>);
LLFloaterReg::add("experience_search", "floater_experience_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiencePicker>);
diff --git a/indra/newview/skins/default/textures/icons/emoji_picker_icon.png b/indra/newview/skins/default/textures/icons/emoji_picker_icon.png
new file mode 100644
index 0000000000..668dcaf193
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/emoji_picker_icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 1f2c0867c4..f69f1df71a 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -205,6 +205,7 @@ with the same filename but different name
<texture name="DropTarget" file_name="widgets/DropTarget.png" preload="false" />
+ <texture name="Emoji_Picker_Icon" file_name="icons/emoji_picker_icon.png" preload="true" />
<texture name="ExternalBrowser_Off" file_name="icons/ExternalBrowser_Off.png" preload="false" />
<texture name="Edit_Wrench" file_name="icons/Edit_Wrench.png" preload="false" />
@@ -212,7 +213,7 @@ with the same filename but different name
<texture name="Presets_Icon" file_name="icons/Presets_Icon.png" preload="true" />
<texture name="Presets_Icon_Graphic" file_name="icons/Presets_Icon_Graphic.png" preload="true" />
- <texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" />
+ <texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" />
<texture name="Favorite_Star_Off" file_name="navbar/Favorite_Star_Off.png" preload="false" />
<texture name="Favorite_Star_Press" file_name="navbar/Favorite_Star_Press.png" preload="false" />
<texture name="Favorite_Star_Over" file_name="navbar/Favorite_Star_Over.png" preload="false" />
@@ -328,7 +329,7 @@ with the same filename but different name
<texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" />
<texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" />
<texture name="Inv_Link" file_name="icons/Inv_Link.png" preload="false" />
- <texture name="Inv_Settings" file_name="icons/Inv_Settings.png" preload="false" />
+ <texture name="Inv_Settings" file_name="icons/Inv_Settings.png" preload="false" />
<texture name="Inv_SettingsSky" file_name="icons/Inv_SettingsSky.png" preload="false" />
<texture name="Inv_SettingsWater" file_name="icons/Inv_SettingsWater.png" preload="false" />
<texture name="Inv_SettingsDay" file_name="icons/Inv_SettingsDay.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/floater_emoji_picker.xml b/indra/newview/skins/default/xui/en/floater_emoji_picker.xml
new file mode 100644
index 0000000000..a3e504cc31
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_emoji_picker.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ name="emojipicker"
+ title="CHOOSE EMOJI"
+ help_topic="emojipicker"
+ positioning="cascading"
+ legacy_header_height="10"
+ can_resize="false"
+ layout="topleft"
+ height="419"
+ width="200">
+ <panel
+ label="Emojis"
+ name="EmojiPanel"
+ help_topic="emojipicker"
+ layout="topleft"
+ top="4"
+ left="2"
+ height="410"
+ width="196">
+ <scroll_list
+ draw_heading="true"
+ heading_height="28"
+ follows="all"
+ layout="topleft"
+ name="Emojis"
+ sort_column="0"
+ height="410">
+ <columns
+ label="Look"
+ name="look"
+ width="40" />
+ <columns
+ label="Name"
+ name="name"
+ width="150" />
+ </scroll_list>
+ </panel>
+</floater>
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 da84fbeea6..1592352d1b 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -297,8 +297,20 @@
tab_group="3"
bottom="-8"
left_pad="5"
- right="-5"
+ right="-30"
wrap="true" />
+ <button
+ follows="right|bottom"
+ bottom="-7"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Emoji_Picker_Icon"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ right="-1"
+ name="emoji_panel_btn"
+ tool_tip="Shows/hides emoji panel"
+ width="25"/>
</layout_panel>
<layout_panel
auto_resize="false"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 2fd2028c6b..5687fe55a5 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -485,9 +485,9 @@ http://secondlife.com/support for help fixing this problem.
<!-- build floater -->
<string name="multiple_textures">Multiple</string>
-<string name="use_texture">Use texture</string>
- <string name="manip_hint1">Move mouse cursor over ruler</string>
- <string name="manip_hint2">to snap to grid</string>
+ <string name="use_texture">Use texture</string>
+ <string name="manip_hint1">Move mouse cursor over ruler</string>
+ <string name="manip_hint2">to snap to grid</string>
<!-- world map -->
<string name="texture_loading">Loading...</string>
@@ -502,14 +502,14 @@ http://secondlife.com/support for help fixing this problem.
<!-- Chat -->
<string name="NearbyChatTitle">Nearby chat</string>
- <string name="NearbyChatLabel">(Nearby chat)</string>
+ <string name="NearbyChatLabel">(Nearby chat)</string>
<string name="whisper">whispers:</string>
<string name="shout">shouts:</string>
<string name="ringing">Connecting to in-world Voice Chat...</string>
<string name="connected">Connected</string>
<string name="unavailable">Voice not available at your current location</string>
<string name="hang_up">Disconnected from in-world Voice Chat</string>
- <string name="reconnect_nearby">You will now be reconnected to Nearby Voice Chat</string>
+ <string name="reconnect_nearby">You will now be reconnected to Nearby Voice Chat</string>
<string name="ScriptQuestionCautionChatGranted">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS].</string>
<string name="ScriptQuestionCautionChatDenied">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS].</string>
<string name="AdditionalPermissionsRequestHeader">If you allow access to your account, you will also be allowing the object to:</string>