SL-20390 Emoji Completion floater - ignore symbols in shortcodes when searching by pattern
parent
9f8763cae1
commit
98214577c3
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,25 @@ struct LLEmojiGroup
|
|||
std::list<std::string> Categories;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// 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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue