summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAlexander Gavriliuk <alexandrgproductengine@lindenlab.com>2023-10-05 11:28:54 +0200
committerGuru <alexandrgproductengine@lindenlab.com>2023-10-05 12:24:20 +0200
commit98214577c36d9c8dd0e13c7b678a399b35450bd3 (patch)
treeab40df03d066327daa36ba5a0fcd18065eca541f /indra
parent9f8763cae1ccb3577a2cd148ffc5cee564a2df65 (diff)
SL-20390 Emoji Completion floater - ignore symbols in shortcodes when searching by pattern
Diffstat (limited to 'indra')
-rw-r--r--indra/llui/llemojidictionary.cpp64
-rw-r--r--indra/llui/llemojidictionary.h20
-rw-r--r--indra/newview/llpanelemojicomplete.cpp72
-rw-r--r--indra/newview/llpanelemojicomplete.h4
4 files changed, 128 insertions, 32 deletions
diff --git a/indra/llui/llemojidictionary.cpp b/indra/llui/llemojidictionary.cpp
index 1ee97ea2d2..bf7e53701d 100644
--- a/indra/llui/llemojidictionary.cpp
+++ b/indra/llui/llemojidictionary.cpp
@@ -143,6 +143,70 @@ LLWString LLEmojiDictionary::findMatchingEmojis(const std::string& needle) const
return result;
}
+void LLEmojiDictionary::findByShortCode(std::vector<LLEmojiSearchResult>& result, const std::string& needle) const
+{
+ result.clear();
+
+ if (needle.empty() || needle.front() != ':')
+ return;
+
+ auto search = [needle](std::size_t& begin, std::size_t& end, const std::string& shortCode) -> bool
+ {
+ begin = 0;
+ end = 1;
+ std::size_t index = 1;
+ // Search for begin
+ char d = tolower(needle[index++]);
+ while (end < shortCode.size())
+ {
+ char s = tolower(shortCode[end++]);
+ if (s == d)
+ {
+ begin = end - 1;
+ break;
+ }
+ }
+ if (!begin)
+ return false;
+ // Search for end
+ d = tolower(needle[index++]);
+ while (end < shortCode.size() && index <= needle.size())
+ {
+ char s = tolower(shortCode[end++]);
+ if (s == d)
+ {
+ if (index == needle.size())
+ return true;
+ d = tolower(needle[index++]);
+ continue;
+ }
+ switch (s)
+ {
+ case L'-':
+ case L'_':
+ case L'+':
+ continue;
+ }
+ break;
+ }
+ return false;
+ };
+
+ for (const LLEmojiDescriptor& d : mEmojis)
+ {
+ if (d.ShortCodes.empty())
+ continue;
+ const std::string& shortCode = d.ShortCodes.front();
+ if (shortCode.size() < needle.size() || shortCode.front() != needle.front())
+ continue;
+ std::size_t begin, end;
+ if (search(begin, end, shortCode))
+ {
+ result.emplace_back(d.Character, shortCode, begin, end);
+ }
+ }
+}
+
const LLEmojiDescriptor* LLEmojiDictionary::getDescriptorFromEmoji(llwchar emoji) const
{
const auto it = mEmoji2Descr.find(emoji);
diff --git a/indra/llui/llemojidictionary.h b/indra/llui/llemojidictionary.h
index f6442684a7..66b564b70a 100644
--- a/indra/llui/llemojidictionary.h
+++ b/indra/llui/llemojidictionary.h
@@ -53,6 +53,25 @@ struct LLEmojiGroup
};
// ============================================================================
+// LLEmojiSearchResult class
+//
+
+struct LLEmojiSearchResult
+{
+ llwchar Character;
+ std::string String;
+ std::size_t Begin, End;
+
+ LLEmojiSearchResult(llwchar character, const std::string& string, std::size_t begin, std::size_t end)
+ : Character(character)
+ , String(string)
+ , Begin(begin)
+ , End(end)
+ {
+ }
+};
+
+// ============================================================================
// LLEmojiDictionary class
//
@@ -70,6 +89,7 @@ public:
static void initClass();
LLWString findMatchingEmojis(const std::string& needle) const;
+ void findByShortCode(std::vector<LLEmojiSearchResult>& result, const std::string& needle) const;
const LLEmojiDescriptor* getDescriptorFromEmoji(llwchar emoji) const;
const LLEmojiDescriptor* getDescriptorFromShortCode(const std::string& short_code) const;
std::string getNameFromEmoji(llwchar ch) const;
diff --git a/indra/newview/llpanelemojicomplete.cpp b/indra/newview/llpanelemojicomplete.cpp
index b03f16899e..22cac8ad88 100644
--- a/indra/newview/llpanelemojicomplete.cpp
+++ b/indra/newview/llpanelemojicomplete.cpp
@@ -82,7 +82,7 @@ void LLPanelEmojiComplete::draw()
{
LLUICtrl::draw();
- if (mEmojis.empty())
+ if (!mTotalEmojis)
return;
const size_t firstVisibleIdx = mScrollPos;
@@ -115,21 +115,16 @@ void LLPanelEmojiComplete::draw()
for (U32 curIdx = firstVisibleIdx; curIdx < lastVisibleIdx; curIdx++)
{
- mIconFont->render(mEmojis, curIdx, iconCenterX, iconCenterY,
+ LLWString text(1, mEmojis[curIdx].Character);
+ mIconFont->render(text, 0, iconCenterX, iconCenterY,
LLColor4::white, LLFontGL::HCENTER, LLFontGL::VCENTER, LLFontGL::NORMAL,
LLFontGL::DROP_SHADOW_SOFT, 1, S32_MAX, nullptr, false, true);
if (mVertical)
{
- llwchar emoji = mEmojis[curIdx];
- auto& emoji2descr = LLEmojiDictionary::instance().getEmoji2Descr();
- auto it = emoji2descr.find(emoji);
- if (it != emoji2descr.end())
- {
- const std::string& shortCode = it->second->ShortCodes.front();
- mTextFont->renderUTF8(shortCode, 0, textLeft, iconCenterY, LLColor4::white,
- LLFontGL::LEFT, LLFontGL::VCENTER, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
- shortCode.size(), textWidth, NULL, FALSE, FALSE);
- }
+ const std::string& shortCode = mEmojis[curIdx].String;
+ mTextFont->renderUTF8(shortCode, 0, textLeft, iconCenterY, LLColor4::white,
+ LLFontGL::LEFT, LLFontGL::VCENTER, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+ shortCode.size(), textWidth, NULL, FALSE, FALSE);
iconCenterY -= mEmojiHeight;
}
else
@@ -257,9 +252,8 @@ void LLPanelEmojiComplete::onCommit()
{
if (mCurSelected < mTotalEmojis)
{
- LLWString wstr;
- wstr.push_back(mEmojis.at(mCurSelected));
- setValue(wstring_to_utf8str(wstr));
+ LLSD value(wstring_to_utf8str(LLWString(1, mEmojis[mCurSelected].Character)));
+ setValue(value);
LLUICtrl::onCommit();
}
}
@@ -272,7 +266,23 @@ void LLPanelEmojiComplete::reshape(S32 width, S32 height, BOOL called_from_paren
void LLPanelEmojiComplete::setEmojis(const LLWString& emojis)
{
- mEmojis = emojis;
+ mEmojis.clear();
+
+ auto& emoji2descr = LLEmojiDictionary::instance().getEmoji2Descr();
+ for (const llwchar& emoji : emojis)
+ {
+ std::string shortCode;
+ if (mVertical)
+ {
+ auto it = emoji2descr.find(emoji);
+ if (it != emoji2descr.end() && !it->second->ShortCodes.empty())
+ {
+ shortCode = it->second->ShortCodes.front();
+ }
+ }
+ mEmojis.emplace_back(emoji, shortCode, 0, 0);
+ }
+
mTotalEmojis = mEmojis.size();
mCurSelected = 0;
@@ -281,12 +291,20 @@ void LLPanelEmojiComplete::setEmojis(const LLWString& emojis)
void LLPanelEmojiComplete::setEmojiHint(const std::string& hint)
{
- llwchar curEmoji = mCurSelected < mTotalEmojis ? mEmojis.at(mCurSelected) : 0;
+ llwchar curEmoji = mCurSelected < mTotalEmojis ? mEmojis[mCurSelected].Character : 0;
- mEmojis = LLEmojiDictionary::instance().findMatchingEmojis(hint);
+ LLEmojiDictionary::instance().findByShortCode(mEmojis, hint);
mTotalEmojis = mEmojis.size();
- size_t curEmojiIdx = curEmoji ? mEmojis.find(curEmoji) : std::string::npos;
- mCurSelected = std::string::npos != curEmojiIdx ? curEmojiIdx : 0;
+
+ mCurSelected = 0;
+ for (size_t i = 1; i < mTotalEmojis; ++i)
+ {
+ if (mEmojis[i].Character == curEmoji)
+ {
+ mCurSelected = i;
+ break;
+ }
+ }
onEmojisChanged();
}
@@ -294,18 +312,12 @@ void LLPanelEmojiComplete::setEmojiHint(const std::string& hint)
U32 LLPanelEmojiComplete::getMaxShortCodeWidth() const
{
U32 max_width = 0;
- auto& emoji2descr = LLEmojiDictionary::instance().getEmoji2Descr();
- for (llwchar emoji : mEmojis)
+ for (const LLEmojiSearchResult& result : mEmojis)
{
- auto it = emoji2descr.find(emoji);
- if (it != emoji2descr.end())
+ S32 width = mTextFont->getWidth(result.String);
+ if (width > max_width)
{
- const std::string& shortCode = it->second->ShortCodes.front();
- S32 width = mTextFont->getWidth(shortCode);
- if (width > max_width)
- {
- max_width = width;
- }
+ max_width = width;
}
}
return max_width;
diff --git a/indra/newview/llpanelemojicomplete.h b/indra/newview/llpanelemojicomplete.h
index 1af923bda2..36a965202e 100644
--- a/indra/newview/llpanelemojicomplete.h
+++ b/indra/newview/llpanelemojicomplete.h
@@ -26,6 +26,7 @@
#pragma once
+#include "llemojidictionary.h"
#include "llfloater.h"
#include "lluictrl.h"
@@ -68,7 +69,6 @@ public:
void reshape(S32 width, S32 height, BOOL called_from_parent) override;
public:
- const LLWString& getEmojis() const { return mEmojis; }
size_t getEmojiCount() const { return mEmojis.size(); }
void setEmojis(const LLWString& emojis);
void setEmojiHint(const std::string& hint);
@@ -95,7 +95,7 @@ protected:
const LLFontGL* mIconFont;
const LLFontGL* mTextFont;
- LLWString mEmojis;
+ std::vector<LLEmojiSearchResult> mEmojis;
LLScrollbar* mScrollbar;
LLRect mRenderRect;
U16 mEmojiWidth = 0;