summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavriliuk <alexandrgproductengine@lindenlab.com>2023-10-04 22:30:48 +0200
committerAlexander Gavriliuk <alexandrgproductengine@lindenlab.com>2023-10-05 12:10:34 +0200
commit9f8763cae1ccb3577a2cd148ffc5cee564a2df65 (patch)
tree0a9f2bfe2cc449d301821ec1152bc8aeacdd11a4
parent66aee79e3e9ca9b45e7c61d843caadb8469580e5 (diff)
SL-20402 Emoji Completion floater - use vertical scrollbar when needed
-rw-r--r--indra/llui/llscrollbar.cpp6
-rw-r--r--indra/newview/llpanelemojicomplete.cpp449
-rw-r--r--indra/newview/llpanelemojicomplete.h125
-rw-r--r--indra/newview/skins/default/xui/en/floater_emoji_complete.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml2
-rw-r--r--indra/newview/skins/default/xui/en/widgets/emoji_complete.xml2
6 files changed, 350 insertions, 240 deletions
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index fde6de4921..d5d0d97b55 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -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();
}
diff --git a/indra/newview/llpanelemojicomplete.cpp b/indra/newview/llpanelemojicomplete.cpp
index 732531691b..b03f16899e 100644
--- a/indra/newview/llpanelemojicomplete.cpp
+++ b/indra/newview/llpanelemojicomplete.cpp
@@ -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;
- }
-
- return TRUE;
+ if (mScrollbar && mScrollbar->getVisible() && childrenHandleHover(x, y, mask))
+ 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;
- }
- }
-
- if (handled)
- {
- return TRUE;
- }
- return LLUICtrl::handleKey(key, mask, called_from_parent);
+ bool handled = false;
+ if (mTotalEmojis && MASK_NONE == mask)
+ {
+ switch (key)
+ {
+ case KEY_HOME:
+ select(0);
+ handled = true;
+ break;
+
+ 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;
+
+ mCurSelected = posToIndex(x, y);
+ mLastHover = LLVector2(x, y);
- return TRUE;
+ 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;
+
+ mCurSelected = posToIndex(x, y);
+ onCommit();
+
+ return TRUE;
+}
+
+BOOL LLPanelEmojiComplete::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+ if (mNoScroll)
+ return FALSE;
- return TRUE;
+ 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;
- }
- }
-
- if (handled)
- return TRUE;
-
- return LLFloater::handleKey(key, mask, called_from_parent);
+ bool handled = false;
+ if (MASK_NONE == mask)
+ {
+ switch (key)
+ {
+ case KEY_ESCAPE:
+ LLEmojiHelper::instance().hideHelper();
+ handled = true;
+ break;
+ }
+ }
+
+ if (handled)
+ return TRUE;
+
+ 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();
-
- return LLFloater::postBuild();
+ mEmojiCtrl = findChild<LLPanelEmojiComplete>("emoji_complete_ctrl");
+ mEmojiCtrl->setCommitCallback(
+ [this](LLUICtrl* ctrl, const LLSD& param)
+ {
+ setValue(param);
+ onCommit();
+ });
+
+ 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);
+ }
}
// ============================================================================
diff --git a/indra/newview/llpanelemojicomplete.h b/indra/newview/llpanelemojicomplete.h
index 20d3413765..1af923bda2 100644
--- a/indra/newview/llpanelemojicomplete.h
+++ b/indra/newview/llpanelemojicomplete.h
@@ -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 = 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;
+ 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;
+
+ 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;
};
// ============================================================================
diff --git a/indra/newview/skins/default/xui/en/floater_emoji_complete.xml b/indra/newview/skins/default/xui/en/floater_emoji_complete.xml
index 207a8af118..d290d647e8 100644
--- a/indra/newview/skins/default/xui/en/floater_emoji_complete.xml
+++ b/indra/newview/skins/default/xui/en/floater_emoji_complete.xml
@@ -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"
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index fa65842c28..eb5d88bba6 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -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"
diff --git a/indra/newview/skins/default/xui/en/widgets/emoji_complete.xml b/indra/newview/skins/default/xui/en/widgets/emoji_complete.xml
index f9db441815..6cc8d7118f 100644
--- a/indra/newview/skins/default/xui/en/widgets/emoji_complete.xml
+++ b/indra/newview/skins/default/xui/en/widgets/emoji_complete.xml
@@ -3,7 +3,7 @@
autosize="false"
hover_image="ListItem_Over"
selected_image="ListItem_Select"
- max_emoji="7"
+ max_visible="7"
padding="8"
>
</emoji_complete>