diff options
-rw-r--r-- | indra/llui/llemojidictionary.cpp | 64 | ||||
-rw-r--r-- | indra/llui/llemojidictionary.h | 20 | ||||
-rw-r--r-- | indra/newview/llpanelemojicomplete.cpp | 72 | ||||
-rw-r--r-- | indra/newview/llpanelemojicomplete.h | 4 |
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; |