SL-20402 Emoji Completion floater - use vertical scrollbar when needed

master
Alexander Gavriliuk 2023-10-04 22:30:48 +02:00
parent 66aee79e3e
commit 9f8763cae1
6 changed files with 344 additions and 234 deletions

View File

@ -475,13 +475,15 @@ void LLScrollbar::reshape(S32 width, S32 height, BOOL called_from_parent)
{
up_button->reshape(up_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, mThickness));
down_button->reshape(down_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, mThickness));
up_button->setOrigin(up_button->getRect().mLeft, getRect().getHeight() - up_button->getRect().getHeight());
up_button->setOrigin(0, getRect().getHeight() - up_button->getRect().getHeight());
down_button->setOrigin(0, 0);
}
else
{
up_button->reshape(llmin(getRect().getWidth() / 2, mThickness), up_button->getRect().getHeight());
down_button->reshape(llmin(getRect().getWidth() / 2, mThickness), down_button->getRect().getHeight());
down_button->setOrigin(getRect().getWidth() - down_button->getRect().getWidth(), down_button->getRect().mBottom);
up_button->setOrigin(0, 0);
down_button->setOrigin(getRect().getWidth() - down_button->getRect().getWidth(), 0);
}
updateThumbRect();
}

View File

@ -29,10 +29,12 @@
#include "llemojidictionary.h"
#include "llemojihelper.h"
#include "llpanelemojicomplete.h"
#include "llscrollbar.h"
#include "lluictrlfactory.h"
constexpr U32 MIN_MOUSE_MOVE_DELTA = 4;
constexpr U32 MIN_SHORT_CODE_WIDTH = 100;
constexpr U32 DEF_PADDING = 8;
// ============================================================================
// LLPanelEmojiComplete
@ -41,26 +43,35 @@ constexpr U32 MIN_SHORT_CODE_WIDTH = 100;
static LLDefaultChildRegistry::Register<LLPanelEmojiComplete> r("emoji_complete");
LLPanelEmojiComplete::Params::Params()
: autosize("autosize")
, noscroll("noscroll")
, vertical("vertical")
, max_emoji("max_emoji")
, padding("padding")
, selected_image("selected_image")
: autosize("autosize")
, noscroll("noscroll")
, vertical("vertical")
, max_visible("max_visible")
, padding("padding", DEF_PADDING)
, selected_image("selected_image")
{
}
LLPanelEmojiComplete::LLPanelEmojiComplete(const LLPanelEmojiComplete::Params& p)
: LLUICtrl(p)
, mAutoSize(p.autosize)
, mNoScroll(p.noscroll)
, mVertical(p.vertical)
, mMaxVisible(p.max_emoji)
, mPadding(p.padding)
, mSelectedImage(p.selected_image)
, mIconFont(LLFontGL::getFontEmojiHuge())
, mTextFont(LLFontGL::getFontSansSerifBig())
: LLUICtrl(p)
, mAutoSize(p.autosize)
, mNoScroll(p.noscroll)
, mVertical(p.vertical)
, mMaxVisible(p.max_visible)
, mPadding(p.padding)
, mSelectedImage(p.selected_image)
, mIconFont(LLFontGL::getFontEmojiHuge())
, mTextFont(LLFontGL::getFontSansSerifBig())
, mScrollbar(nullptr)
{
if (mVertical)
{
LLScrollbar::Params sbparams;
sbparams.orientation(LLScrollbar::VERTICAL);
sbparams.change_callback([this](S32 index, LLScrollbar*) { onScrollbarChange(index); });
mScrollbar = LLUICtrlFactory::create<LLScrollbar>(sbparams);
addChild(mScrollbar);
}
}
LLPanelEmojiComplete::~LLPanelEmojiComplete()
@ -69,13 +80,15 @@ LLPanelEmojiComplete::~LLPanelEmojiComplete()
void LLPanelEmojiComplete::draw()
{
LLUICtrl::draw();
if (mEmojis.empty())
return;
const size_t firstVisibleIdx = mScrollPos;
const size_t lastVisibleIdx = llmin(mScrollPos + mVisibleEmojis, mEmojis.size()) - 1;
const size_t lastVisibleIdx = llmin(mScrollPos + mVisibleEmojis, mTotalEmojis);
if (mCurSelected >= firstVisibleIdx && mCurSelected <= lastVisibleIdx)
if (mCurSelected >= firstVisibleIdx && mCurSelected < lastVisibleIdx)
{
S32 x, y, width, height;
if (mVertical)
@ -100,7 +113,7 @@ void LLPanelEmojiComplete::draw()
S32 textLeft = mVertical ? mRenderRect.mLeft + mEmojiWidth + mPadding : 0;
S32 textWidth = mVertical ? getRect().getWidth() - textLeft - mPadding : 0;
for (U32 curIdx = firstVisibleIdx; curIdx <= lastVisibleIdx; curIdx++)
for (U32 curIdx = firstVisibleIdx; curIdx < lastVisibleIdx; curIdx++)
{
mIconFont->render(mEmojis, curIdx, iconCenterX, iconCenterY,
LLColor4::white, LLFontGL::HCENTER, LLFontGL::VCENTER, LLFontGL::NORMAL,
@ -128,100 +141,154 @@ void LLPanelEmojiComplete::draw()
BOOL LLPanelEmojiComplete::handleHover(S32 x, S32 y, MASK mask)
{
LLVector2 curHover(x, y);
if ((mLastHover - curHover).lengthSquared() > MIN_MOUSE_MOVE_DELTA)
{
mCurSelected = posToIndex(x, y);
mLastHover = curHover;
}
if (mScrollbar && mScrollbar->getVisible() && childrenHandleHover(x, y, mask))
return TRUE;
return TRUE;
LLVector2 curHover(x, y);
if ((mLastHover - curHover).lengthSquared() > MIN_MOUSE_MOVE_DELTA)
{
size_t index = posToIndex(x, y);
if (index < mTotalEmojis)
mCurSelected = index;
mLastHover = curHover;
}
return TRUE;
}
BOOL LLPanelEmojiComplete::handleKey(KEY key, MASK mask, BOOL called_from_parent)
{
bool handled = false;
if (MASK_NONE == mask)
{
switch (key)
{
case KEY_LEFT:
case KEY_UP:
selectPrevious();
handled = true;
break;
case KEY_RIGHT:
case KEY_DOWN:
selectNext();
handled = true;
break;
case KEY_RETURN:
if (!mEmojis.empty())
{
onCommit();
handled = true;
}
break;
}
}
bool handled = false;
if (mTotalEmojis && MASK_NONE == mask)
{
switch (key)
{
case KEY_HOME:
select(0);
handled = true;
break;
if (handled)
{
return TRUE;
}
return LLUICtrl::handleKey(key, mask, called_from_parent);
case KEY_END:
select(mTotalEmojis - 1);
handled = true;
break;
case KEY_PAGE_DOWN:
select(mCurSelected + mVisibleEmojis - 1);
handled = true;
break;
case KEY_PAGE_UP:
select(mCurSelected - llmin(mCurSelected, mVisibleEmojis + 1));
handled = true;
break;
case KEY_LEFT:
case KEY_UP:
selectPrevious();
handled = true;
break;
case KEY_RIGHT:
case KEY_DOWN:
selectNext();
handled = true;
break;
case KEY_RETURN:
onCommit();
handled = true;
break;
}
}
if (handled)
{
return TRUE;
}
return LLUICtrl::handleKey(key, mask, called_from_parent);
}
BOOL LLPanelEmojiComplete::handleMouseDown(S32 x, S32 y, MASK mask)
{
mCurSelected = posToIndex(x, y);
mLastHover = LLVector2(x, y);
if (mScrollbar && mScrollbar->getVisible() && childrenHandleMouseDown(x, y, mask))
return TRUE;
return TRUE;
mCurSelected = posToIndex(x, y);
mLastHover = LLVector2(x, y);
return TRUE;
}
BOOL LLPanelEmojiComplete::handleMouseUp(S32 x, S32 y, MASK mask)
{
mCurSelected = posToIndex(x, y);
onCommit();
if (mScrollbar && mScrollbar->getVisible() && childrenHandleMouseUp(x, y, mask))
return TRUE;
return TRUE;
mCurSelected = posToIndex(x, y);
onCommit();
return TRUE;
}
BOOL LLPanelEmojiComplete::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
if (mNoScroll)
return FALSE;
if (mScrollbar && mScrollbar->getVisible() && mScrollbar->handleScrollWheel(x, y, clicks))
{
mCurSelected = posToIndex(x, y);
return TRUE;
}
if (mTotalEmojis > mVisibleEmojis)
{
mScrollPos = llclamp<size_t>(mScrollPos + clicks, 0, mTotalEmojis - mVisibleEmojis);
mCurSelected = posToIndex(x, y);
return TRUE;
}
return FALSE;
}
void LLPanelEmojiComplete::onCommit()
{
if (mCurSelected < mEmojis.size())
{
LLWString wstr;
wstr.push_back(mEmojis.at(mCurSelected));
setValue(wstring_to_utf8str(wstr));
LLUICtrl::onCommit();
}
if (mCurSelected < mTotalEmojis)
{
LLWString wstr;
wstr.push_back(mEmojis.at(mCurSelected));
setValue(wstring_to_utf8str(wstr));
LLUICtrl::onCommit();
}
}
void LLPanelEmojiComplete::reshape(S32 width, S32 height, BOOL called_from_parent)
{
LLUICtrl::reshape(width, height, called_from_parent);
updateConstraints();
LLUICtrl::reshape(width, height, called_from_parent);
updateConstraints();
}
void LLPanelEmojiComplete::setEmojis(const LLWString& emojis)
{
mEmojis = emojis;
mCurSelected = 0;
mEmojis = emojis;
mTotalEmojis = mEmojis.size();
mCurSelected = 0;
onEmojisChanged();
onEmojisChanged();
}
void LLPanelEmojiComplete::setEmojiHint(const std::string& hint)
{
llwchar curEmoji = (mCurSelected < mEmojis.size()) ? mEmojis.at(mCurSelected) : 0;
llwchar curEmoji = mCurSelected < mTotalEmojis ? mEmojis.at(mCurSelected) : 0;
mEmojis = LLEmojiDictionary::instance().findMatchingEmojis(hint);
size_t curEmojiIdx = curEmoji ? mEmojis.find(curEmoji) : std::string::npos;
mCurSelected = (std::string::npos != curEmojiIdx) ? curEmojiIdx : 0;
mEmojis = LLEmojiDictionary::instance().findMatchingEmojis(hint);
mTotalEmojis = mEmojis.size();
size_t curEmojiIdx = curEmoji ? mEmojis.find(curEmoji) : std::string::npos;
mCurSelected = std::string::npos != curEmojiIdx ? curEmojiIdx : 0;
onEmojisChanged();
onEmojisChanged();
}
U32 LLPanelEmojiComplete::getMaxShortCodeWidth() const
@ -246,79 +313,104 @@ U32 LLPanelEmojiComplete::getMaxShortCodeWidth() const
void LLPanelEmojiComplete::onEmojisChanged()
{
if (mAutoSize)
{
mVisibleEmojis = std::min(mEmojis.size(), mMaxVisible);
if (mAutoSize)
{
S32 width, height;
mVisibleEmojis = llmin(mTotalEmojis, mMaxVisible);
if (mVertical)
{
U32 maxShortCodeWidth = getMaxShortCodeWidth();
U32 shortCodeWidth = std::max(maxShortCodeWidth, MIN_SHORT_CODE_WIDTH);
S32 width = mEmojiWidth + shortCodeWidth + mPadding * 2;
reshape(width, mVisibleEmojis * mEmojiHeight, false);
U32 shortCodeWidth = llmax(maxShortCodeWidth, MIN_SHORT_CODE_WIDTH);
width = mEmojiWidth + shortCodeWidth + mPadding * 2;
if (!mNoScroll && mVisibleEmojis < mTotalEmojis)
{
width += mScrollbar->getThickness();
}
height = mVisibleEmojis * mEmojiHeight;
}
else
{
S32 height = getRect().getHeight();
reshape(mVisibleEmojis * mEmojiWidth, height, false);
width = mVisibleEmojis * mEmojiWidth;
height = getRect().getHeight();
}
}
else
{
updateConstraints();
}
LLUICtrl::reshape(width, height, false);
}
else
{
mVisibleEmojis = mVertical ? getRect().getHeight() / mEmojiHeight : getRect().getWidth() / mEmojiWidth;
}
mScrollPos = llmin(mScrollPos, mEmojis.size());
updateConstraints();
}
void LLPanelEmojiComplete::onScrollbarChange(S32 index)
{
mScrollPos = llclamp<size_t>(index, 0, mTotalEmojis - mVisibleEmojis);
}
size_t LLPanelEmojiComplete::posToIndex(S32 x, S32 y) const
{
if (mRenderRect.pointInRect(x, y))
{
U32 pos = mVertical ? (U32)(mRenderRect.mTop - y) / mEmojiHeight : x / mEmojiWidth;
return mScrollPos + llmin((size_t)pos, mEmojis.size() - 1);
}
return npos;
if (mRenderRect.pointInRect(x, y))
{
U32 pos = mVertical ? (U32)(mRenderRect.mTop - y) / mEmojiHeight : x / mEmojiWidth;
return llmin(mScrollPos + pos, mTotalEmojis - 1);
}
return std::string::npos;
}
void LLPanelEmojiComplete::select(size_t emoji_idx)
{
mCurSelected = llclamp<size_t>(emoji_idx, 0, mEmojis.size());
updateScrollPos();
mCurSelected = llclamp<size_t>(emoji_idx, 0, mTotalEmojis - 1);
updateScrollPos();
}
void LLPanelEmojiComplete::selectNext()
{
select(mCurSelected + 1 < mEmojis.size() ? mCurSelected + 1 : 0);
if (!mTotalEmojis)
return;
mCurSelected = (mCurSelected < mTotalEmojis - 1) ? mCurSelected + 1 : 0;
updateScrollPos();
}
void LLPanelEmojiComplete::selectPrevious()
{
select(mCurSelected - 1 >= 0 ? mCurSelected - 1 : mEmojis.size() - 1);
if (!mTotalEmojis)
return;
mCurSelected = (mCurSelected && mCurSelected < mTotalEmojis) ? mCurSelected - 1 : mTotalEmojis - 1;
updateScrollPos();
}
void LLPanelEmojiComplete::updateConstraints()
{
mRenderRect = getLocalRect();
S32 ctrlWidth = mRenderRect.getWidth();
S32 ctrlHeight = mRenderRect.getHeight();
mEmojiHeight = mIconFont->getLineHeight() + mPadding * 2;
mEmojiWidth = mIconFont->getWidthF32(u8"\U0001F431") + mPadding * 2;
if (mVertical)
{
mVisibleEmojis = ctrlHeight / mEmojiHeight;
mRenderRect.mBottom = mRenderRect.mTop - mVisibleEmojis * mEmojiHeight;
mEmojiHeight = mIconFont->getLineHeight() + mPadding * 2;
if (!mNoScroll && mVisibleEmojis < mTotalEmojis)
{
mRenderRect.mRight -= mScrollbar->getThickness();
mScrollbar->setDocSize(mTotalEmojis);
mScrollbar->setPageSize(mVisibleEmojis);
mScrollbar->setOrigin(mRenderRect.mRight, 0);
mScrollbar->reshape(mScrollbar->getThickness(), mRenderRect.mTop, TRUE);
mScrollbar->setVisible(TRUE);
}
else
{
mScrollbar->setVisible(FALSE);
}
}
else
{
mVisibleEmojis = ctrlWidth / mEmojiWidth;
S32 padding = (ctrlWidth - mVisibleEmojis * mEmojiWidth) / 2;
mRenderRect.mLeft += padding;
mRenderRect.mRight -= padding;
if (mEmojiHeight > ctrlHeight)
{
mEmojiHeight = ctrlHeight;
}
mEmojiHeight = mRenderRect.getHeight();
mRenderRect.stretch((mRenderRect.getWidth() - mVisibleEmojis * mEmojiWidth) / -2, 0);
}
updateScrollPos();
@ -326,23 +418,27 @@ void LLPanelEmojiComplete::updateConstraints()
void LLPanelEmojiComplete::updateScrollPos()
{
const size_t cntEmoji = mEmojis.size();
if (mNoScroll || 0 == cntEmoji || cntEmoji < mVisibleEmojis || 0 == mCurSelected)
{
mScrollPos = 0;
if (mCurSelected >= mVisibleEmojis)
{
mCurSelected = mVisibleEmojis ? mVisibleEmojis - 1 : 0;
}
}
else if (cntEmoji - 1 == mCurSelected)
{
mScrollPos = mCurSelected - mVisibleEmojis + 1;
}
else
{
mScrollPos = mCurSelected - ((float)mCurSelected / (cntEmoji - 2) * (mVisibleEmojis - 2));
}
if (mNoScroll || 0 == mTotalEmojis || mTotalEmojis < mVisibleEmojis || 0 == mCurSelected)
{
mScrollPos = 0;
if (mCurSelected >= mVisibleEmojis)
{
mCurSelected = mVisibleEmojis ? mVisibleEmojis - 1 : 0;
}
}
else if (mTotalEmojis - 1 == mCurSelected)
{
mScrollPos = mTotalEmojis - mVisibleEmojis;
}
else
{
mScrollPos = mCurSelected - ((float)mCurSelected / (mTotalEmojis - 2) * (mVisibleEmojis - 2));
}
if (mScrollbar && mScrollbar->getVisible())
{
mScrollbar->setDocPos(mScrollPos);
}
}
// ============================================================================
@ -350,33 +446,33 @@ void LLPanelEmojiComplete::updateScrollPos()
//
LLFloaterEmojiComplete::LLFloaterEmojiComplete(const LLSD& sdKey)
: LLFloater(sdKey)
: LLFloater(sdKey)
{
// This floater should hover on top of our dependent (with the dependent having the focus)
setFocusStealsFrontmost(false);
setAutoFocus(false);
setBackgroundVisible(false);
setIsChrome(true);
// This floater should hover on top of our dependent (with the dependent having the focus)
setFocusStealsFrontmost(false);
setAutoFocus(false);
setBackgroundVisible(false);
setIsChrome(true);
}
BOOL LLFloaterEmojiComplete::handleKey(KEY key, MASK mask, BOOL called_from_parent)
{
bool handled = false;
if (MASK_NONE == mask)
{
switch (key)
{
case KEY_ESCAPE:
LLEmojiHelper::instance().hideHelper();
handled = true;
break;
}
}
bool handled = false;
if (MASK_NONE == mask)
{
switch (key)
{
case KEY_ESCAPE:
LLEmojiHelper::instance().hideHelper();
handled = true;
break;
}
}
if (handled)
return TRUE;
if (handled)
return TRUE;
return LLFloater::handleKey(key, mask, called_from_parent);
return LLFloater::handleKey(key, mask, called_from_parent);
}
void LLFloaterEmojiComplete::onOpen(const LLSD& key)
@ -402,30 +498,33 @@ void LLFloaterEmojiComplete::onOpen(const LLSD& key)
BOOL LLFloaterEmojiComplete::postBuild()
{
mEmojiCtrl = findChild<LLPanelEmojiComplete>("emoji_complete_ctrl");
mEmojiCtrl->setCommitCallback(
std::bind([&](const LLSD& sdValue)
{
setValue(sdValue);
onCommit();
}, std::placeholders::_2));
mEmojiCtrlHorz = getRect().getWidth() - mEmojiCtrl->getRect().getWidth();
mEmojiCtrl = findChild<LLPanelEmojiComplete>("emoji_complete_ctrl");
mEmojiCtrl->setCommitCallback(
[this](LLUICtrl* ctrl, const LLSD& param)
{
setValue(param);
onCommit();
});
return LLFloater::postBuild();
mEmojiCtrlHorz = getRect().getWidth() - mEmojiCtrl->getRect().getWidth();
mEmojiCtrlVert = getRect().getHeight() - mEmojiCtrl->getRect().getHeight();
return LLFloater::postBuild();
}
void LLFloaterEmojiComplete::reshape(S32 width, S32 height, BOOL called_from_parent)
{
if (!called_from_parent)
{
LLRect rctFloater = getRect(), rctCtrl = mEmojiCtrl->getRect();
rctFloater.mRight = rctFloater.mLeft + rctCtrl.getWidth() + mEmojiCtrlHorz;
setRect(rctFloater);
return;
}
LLFloater::reshape(width, height, called_from_parent);
if (called_from_parent)
{
LLFloater::reshape(width, height, called_from_parent);
}
else
{
LLRect outer(getRect()), inner(mEmojiCtrl->getRect());
outer.mRight = outer.mLeft + inner.getWidth() + mEmojiCtrlHorz;
outer.mTop = outer.mBottom + inner.getHeight() + mEmojiCtrlVert;
setRect(outer);
}
}
// ============================================================================

View File

@ -29,79 +29,83 @@
#include "llfloater.h"
#include "lluictrl.h"
class LLScrollbar;
// ============================================================================
// LLPanelEmojiComplete
//
class LLPanelEmojiComplete : public LLUICtrl
{
friend class LLUICtrlFactory;
friend class LLUICtrlFactory;
public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Optional<bool> autosize;
Optional<bool> noscroll;
Optional<bool> vertical;
Optional<S32> max_emoji,
padding;
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Optional<bool> autosize;
Optional<bool> noscroll;
Optional<bool> vertical;
Optional<S32> max_visible,
padding;
Optional<LLUIImage*> selected_image;
Optional<LLUIImage*> selected_image;
Params();
};
Params();
};
protected:
LLPanelEmojiComplete(const LLPanelEmojiComplete::Params&);
LLPanelEmojiComplete(const LLPanelEmojiComplete::Params&);
public:
virtual ~LLPanelEmojiComplete();
virtual ~LLPanelEmojiComplete();
void draw() override;
BOOL handleHover(S32 x, S32 y, MASK mask) override;
BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent) override;
BOOL handleMouseDown(S32 x, S32 y, MASK mask) override;
BOOL handleMouseUp(S32 x, S32 y, MASK mask) override;
void onCommit() override;
void reshape(S32 width, S32 height, BOOL called_from_parent) override;
void draw() override;
BOOL handleHover(S32 x, S32 y, MASK mask) override;
BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent) override;
BOOL handleMouseDown(S32 x, S32 y, MASK mask) override;
BOOL handleMouseUp(S32 x, S32 y, MASK mask) override;
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) override;
void onCommit() override;
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);
bool isAutoSize() const { return mAutoSize; }
U32 getMaxShortCodeWidth() const;
const LLWString& getEmojis() const { return mEmojis; }
size_t getEmojiCount() const { return mEmojis.size(); }
void setEmojis(const LLWString& emojis);
void setEmojiHint(const std::string& hint);
bool isAutoSize() const { return mAutoSize; }
U32 getMaxShortCodeWidth() const;
protected:
void onEmojisChanged();
size_t posToIndex(S32 x, S32 y) const;
void select(size_t emoji_idx);
void selectNext();
void selectPrevious();
void updateConstraints();
void updateScrollPos();
void onEmojisChanged();
void onScrollbarChange(S32 index);
size_t posToIndex(S32 x, S32 y) const;
void select(size_t emoji_idx);
void selectNext();
void selectPrevious();
void updateConstraints();
void updateScrollPos();
protected:
static constexpr auto npos = std::numeric_limits<size_t>::max();
const bool mAutoSize;
const bool mNoScroll;
const bool mVertical;
const size_t mMaxVisible;
const S32 mPadding;
const LLUIImagePtr mSelectedImage;
const LLFontGL* mIconFont;
const LLFontGL* mTextFont;
const bool mAutoSize = false;
const bool mNoScroll = false;
const bool mVertical = false;
const size_t mMaxVisible = 0;
const S32 mPadding = 8;
const LLUIImagePtr mSelectedImage;
const LLFontGL* mIconFont;
const LLFontGL* mTextFont;
LLWString mEmojis;
LLRect mRenderRect;
U16 mEmojiWidth = 0;
U16 mEmojiHeight = 0;
size_t mVisibleEmojis = 0;
size_t mFirstVisible = 0;
size_t mScrollPos = 0;
size_t mCurSelected = 0;
LLVector2 mLastHover;
LLWString mEmojis;
LLScrollbar* mScrollbar;
LLRect mRenderRect;
U16 mEmojiWidth = 0;
U16 mEmojiHeight = 0;
size_t mTotalEmojis = 0;
size_t mVisibleEmojis = 0;
size_t mFirstVisible = 0;
size_t mScrollPos = 0;
size_t mCurSelected = 0;
LLVector2 mLastHover;
};
// ============================================================================
@ -111,17 +115,18 @@ protected:
class LLFloaterEmojiComplete : public LLFloater
{
public:
LLFloaterEmojiComplete(const LLSD& sdKey);
LLFloaterEmojiComplete(const LLSD& sdKey);
public:
BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent) override;
void onOpen(const LLSD& key) override;
BOOL postBuild() override;
void reshape(S32 width, S32 height, BOOL called_from_parent) override;
BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent) override;
void onOpen(const LLSD& key) override;
BOOL postBuild() override;
void reshape(S32 width, S32 height, BOOL called_from_parent) override;
protected:
LLPanelEmojiComplete* mEmojiCtrl = nullptr;
S32 mEmojiCtrlHorz = 0;
LLPanelEmojiComplete* mEmojiCtrl = nullptr;
S32 mEmojiCtrlHorz = 0;
S32 mEmojiCtrlVert = 0;
};
// ============================================================================

View File

@ -3,6 +3,8 @@
name="emoji_complete"
single_instance="true"
layout="topleft"
bg_opaque_image="Window_NoTitle_Foreground"
bg_alpha_image="Window_NoTitle_Background"
can_close="false"
can_dock="false"
can_drag_on_left="false"
@ -11,6 +13,7 @@
can_tear_off="false"
header_height="0"
legacy_header_height="0"
show_title="false"
width="240"
height="40"
>
@ -20,7 +23,8 @@
layout="topleft"
autosize="true"
vertical="true"
max_emoji="7"
max_visible="7"
padding="4"
width="230"
height="30"
left="5"

View File

@ -353,7 +353,7 @@
name="emoji_recent_icons_ctrl"
follows="top|left|right"
layout="topleft"
max_emoji="20"
max_visible="20"
top="0"
left="1"
right="-65"

View File

@ -3,7 +3,7 @@
autosize="false"
hover_image="ListItem_Over"
selected_image="ListItem_Select"
max_emoji="7"
max_visible="7"
padding="8"
>
</emoji_complete>