master
Ansariel 2024-02-14 18:05:08 +01:00
commit dd3b29d82c
7 changed files with 141 additions and 23 deletions

View File

@ -23,3 +23,4 @@ jobs:
path-to-signatures: signatures.json
remote-organization-name: secondlife
remote-repository-name: cla-signatures
allowlist: callum@mbp.localdomain

View File

@ -717,49 +717,114 @@ std::string utf8str_removeCRLF(const std::string& utf8str)
return out;
}
llwchar utf8str_to_wchar(const std::string& utf8str, size_t offset, size_t length)
{
switch (length)
{
case 2:
return ((utf8str[offset] & 0x1F) << 6) +
(utf8str[offset + 1] & 0x3F);
case 3:
return ((utf8str[offset] & 0x0F) << 12) +
((utf8str[offset + 1] & 0x3F) << 6) +
(utf8str[offset + 2] & 0x3F);
case 4:
return ((utf8str[offset] & 0x07) << 18) +
((utf8str[offset + 1] & 0x3F) << 12) +
((utf8str[offset + 2] & 0x3F) << 6) +
(utf8str[offset + 3] & 0x3F);
case 5:
return ((utf8str[offset] & 0x03) << 24) +
((utf8str[offset + 1] & 0x3F) << 18) +
((utf8str[offset + 2] & 0x3F) << 12) +
((utf8str[offset + 3] & 0x3F) << 6) +
(utf8str[offset + 4] & 0x3F);
case 6:
return ((utf8str[offset] & 0x01) << 30) +
((utf8str[offset + 1] & 0x3F) << 24) +
((utf8str[offset + 2] & 0x3F) << 18) +
((utf8str[offset + 3] & 0x3F) << 12) +
((utf8str[offset + 4] & 0x3F) << 6) +
(utf8str[offset + 5] & 0x3F);
case 7:
return ((utf8str[offset + 1] & 0x03) << 30) +
((utf8str[offset + 2] & 0x3F) << 24) +
((utf8str[offset + 3] & 0x3F) << 18) +
((utf8str[offset + 4] & 0x3F) << 12) +
((utf8str[offset + 5] & 0x3F) << 6) +
(utf8str[offset + 6] & 0x3F);
}
return LL_UNKNOWN_CHAR;
}
std::string utf8str_showBytesUTF8(const std::string& utf8str)
{
std::string result;
bool in_sequence = false;
for (U8 byte : utf8str)
size_t sequence_size = 0;
size_t byte_index = 0;
size_t source_length = utf8str.size();
auto open_sequence = [&]()
{
if (!result.empty() && result.back() != '\n')
result += '\n'; // Use LF as a separator before new UTF-8 sequence
result += '[';
in_sequence = true;
};
auto close_sequence = [&]()
{
llwchar unicode = utf8str_to_wchar(utf8str, byte_index - sequence_size, sequence_size);
if (unicode != LL_UNKNOWN_CHAR)
{
result += llformat("+%04X", unicode);
}
result += ']';
in_sequence = false;
sequence_size = 0;
};
while (byte_index < source_length)
{
U8 byte = utf8str[byte_index];
if (byte >= 0x80) // Part of an UTF-8 sequence
{
if (!in_sequence) // Start new UTF-8 sequence
{
if (!result.empty() && result.back() != ' ')
result += ' '; // Use space as separator between ASCII and UTF-8
result += '[';
open_sequence();
}
else if (byte >= 0xC0) // Start another UTF-8 sequence
{
result += "] ["; // Use space as separator between UTF-8 and UTF-8
close_sequence();
open_sequence();
}
else // Continue the same UTF-8 sequence
{
result += '.';
}
result += llformat("%02X", byte); // The byte is represented in hexadecimal form
in_sequence = true;
++sequence_size;
}
else // ASCII symbol is represented as a character
{
if (in_sequence) // End of UTF-8 sequence
{
result += ']';
if (byte != ' ')
close_sequence();
if (byte != '\n')
{
result += ' '; // Use space as separator between UTF-8 and ASCII
result += '\n'; // Use LF as a separator between UTF-8 and ASCII
}
}
result += byte;
in_sequence = false;
}
++byte_index;
}
if (in_sequence) // End of UTF-8 sequence
{
result += ']';
close_sequence();
}
return result;

View File

@ -757,6 +757,8 @@ LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str);
LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str);
LL_COMMON_API llwchar utf8str_to_wchar(const std::string& utf8str, size_t offset, size_t length);
LL_COMMON_API std::string utf8str_showBytesUTF8(const std::string& utf8str);
#if LL_WINDOWS

View File

@ -958,6 +958,43 @@ void LLFloaterEmojiPicker::selectFocusedIcon()
}
}
bool LLFloaterEmojiPicker::moveFocusedIconUp()
{
for (S32 i = mFocusedIconRow - 1; i >= 0; --i)
{
LLScrollingPanel* panel = mEmojiGrid->getPanelList()[i];
LLEmojiGridRow* row = dynamic_cast<LLEmojiGridRow*>(panel);
if (row && row->mList->getPanelList().size() > mFocusedIconCol)
{
mEmojiScroll->scrollToShowRect(row->getBoundingRect());
mFocusedIconRow = i;
selectFocusedIcon();
return true;
}
}
return false;
}
bool LLFloaterEmojiPicker::moveFocusedIconDown()
{
S32 rowCount = mEmojiGrid->getPanelList().size();
for (S32 i = mFocusedIconRow + 1; i < rowCount; ++i)
{
LLScrollingPanel* panel = mEmojiGrid->getPanelList()[i];
LLEmojiGridRow* row = dynamic_cast<LLEmojiGridRow*>(panel);
if (row && row->mList->getPanelList().size() > mFocusedIconCol)
{
mEmojiScroll->scrollToShowRect(row->getBoundingRect());
mFocusedIconRow = i;
selectFocusedIcon();
return true;
}
}
return false;
}
bool LLFloaterEmojiPicker::moveFocusedIconPrev()
{
if (mHoveredIcon)
@ -1036,6 +1073,28 @@ void LLFloaterEmojiPicker::unselectGridIcon(LLEmojiGridIcon* icon)
BOOL LLFloaterEmojiPicker::handleKey(KEY key, MASK mask, BOOL called_from_parent)
{
if (mask == MASK_NONE)
{
switch (key)
{
case KEY_UP:
moveFocusedIconUp();
return TRUE;
case KEY_DOWN:
moveFocusedIconDown();
return TRUE;
case KEY_LEFT:
moveFocusedIconPrev();
return TRUE;
case KEY_RIGHT:
moveFocusedIconNext();
return TRUE;
case KEY_ESCAPE:
hideFloater();
return TRUE;
}
}
if (mask == MASK_ALT)
{
switch (key)
{
@ -1045,15 +1104,6 @@ BOOL LLFloaterEmojiPicker::handleKey(KEY key, MASK mask, BOOL called_from_parent
case KEY_RIGHT:
selectEmojiGroup((mSelectedGroupIndex + 1) % mGroupButtons.size());
return TRUE;
case KEY_UP:
moveFocusedIconPrev();
return TRUE;
case KEY_DOWN:
moveFocusedIconNext();
return TRUE;
case KEY_ESCAPE:
hideFloater();
return TRUE;
}
}

View File

@ -93,6 +93,8 @@ private:
void onEmojiMouseUp(LLUICtrl* ctrl);
void selectFocusedIcon();
bool moveFocusedIconUp();
bool moveFocusedIconDown();
bool moveFocusedIconPrev();
bool moveFocusedIconNext();

View File

@ -467,6 +467,7 @@ void LLFloaterIMSessionTab::onEmojiRecentPanelToggleBtnClicked()
void LLFloaterIMSessionTab::onEmojiPickerShowBtnClicked()
{
mInputEditor->setFocus(TRUE);
mInputEditor->showEmojiHelper();
}

View File

@ -305,7 +305,6 @@
tool_tip="Shows/hides recent emojis"
follows="right|bottom"
font="EmojiLarge"
tab_stop="false"
image_hover_unselected="Toolbar_Middle_Over"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
@ -354,7 +353,6 @@
name="emoji_recent_icons_ctrl"
follows="top|left|right"
layout="topleft"
tab_stop="false"
max_visible="20"
top="0"
left="1"
@ -366,7 +364,6 @@
tool_tip="Shows/hides emoji picker"
follows="right|bottom"
layout="topleft"
tab_stop="false"
bottom="-5"
right="-3"
height="20"