diff options
author | Alexander Gavriliuk <alexandrgproductengine@lindenlab.com> | 2023-07-13 21:18:22 +0200 |
---|---|---|
committer | Guru <alexandrgproductengine@lindenlab.com> | 2023-07-13 22:13:31 +0200 |
commit | 1fe007abef6eeceefb0dc720b4a5ecb4505ede88 (patch) | |
tree | 52bd2189940592af109c81734c0ab452193ee79c /indra/newview | |
parent | 8b718cbc2edc1f18bfa0cc0a76899fcade149813 (diff) |
SL-20001 EmojiPicker - make the preview to be a panel instead of a button
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llfloateremojipicker.cpp | 286 | ||||
-rw-r--r-- | indra/newview/llfloateremojipicker.h | 11 | ||||
-rw-r--r-- | indra/newview/llfloaterimnearbychat.cpp | 5 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_emoji_picker.xml | 32 |
4 files changed, 176 insertions, 158 deletions
diff --git a/indra/newview/llfloateremojipicker.cpp b/indra/newview/llfloateremojipicker.cpp index 08929b05f5..808aca4bf4 100644 --- a/indra/newview/llfloateremojipicker.cpp +++ b/indra/newview/llfloateremojipicker.cpp @@ -48,63 +48,18 @@ namespace { // Floater state related variables static U32 sSelectedGroupIndex = 0; -static std::string sSearchPattern; +static std::string sFilterPattern; static std::list<llwchar> sRecentlyUsed; static std::list<std::pair<llwchar, U32>> sFrequentlyUsed; // State file related values static std::string sStateFileName; static const std::string sKeySelectedGroupIndex("SelectedGroupIndex"); -static const std::string sKeySearchPattern("SearchPattern"); +static const std::string sKeyFilterPattern("FilterPattern"); static const std::string sKeyRecentlyUsed("RecentlyUsed"); static const std::string sKeyFrequentlyUsed("FrequentlyUsed"); } -class LLEmojiScrollListItem : public LLScrollListItem -{ -public: - LLEmojiScrollListItem(const llwchar emoji, const LLScrollListItem::Params& params) - : LLScrollListItem(params) - , mEmoji(emoji) - { - } - - llwchar getEmoji() const { return mEmoji; } - - virtual void draw(const LLRect& rect, - const LLColor4& fg_color, - const LLColor4& hover_color, // highlight/hover selection of whole item or cell - const LLColor4& select_color, // highlight/hover selection of whole item or cell - const LLColor4& highlight_color, // highlights contents of cells (ex: text) - S32 column_padding) override - { - LLScrollListItem::draw(rect, fg_color, hover_color, select_color, highlight_color, column_padding); - - LLWString wstr(1, mEmoji); - S32 width = getColumn(0)->getWidth(); - F32 x = rect.mLeft + width / 2; - F32 y = rect.getCenterY(); - LLFontGL::getFontEmoji()->render( - wstr, // wstr - 0, // begin_offset - x, // x - y, // y - LLColor4::white, // color - LLFontGL::HCENTER, // halign - LLFontGL::VCENTER, // valign - LLFontGL::NORMAL, // style - LLFontGL::DROP_SHADOW_SOFT, // shadow - 1, // max_chars - S32_MAX, // max_pixels - nullptr, // right_x - false, // use_ellipses - true); // use_color - } - -private: - llwchar mEmoji; -}; - class LLEmojiGridRow : public LLScrollingPanel { public: @@ -137,7 +92,7 @@ public: F32 x = 4; // padding-left F32 y = getRect().getHeight() / 2; - LLFontGL::getFontSansSerifBold()->render( + LLFontGL::getFontSansSerif()->render( mText, // wstr 0, // begin_offset x, // x @@ -168,10 +123,8 @@ public: , const LLEmojiDescriptor* descr , std::string category) : LLScrollingPanel(panel_params) - , mEmoji(descr->Character) - , mText(LLWString(1, mEmoji)) - , mDescr(descr->getShortCodes()) - , mCategory(category) + , mDescr(descr) + , mText(LLWString(1, descr->Character)) { } @@ -200,16 +153,106 @@ public: virtual void updatePanel(BOOL allow_modify) override {} - llwchar getEmoji() const { return mEmoji; } + const LLEmojiDescriptor* getDescr() const { return mDescr; } + llwchar getEmoji() const { return mDescr->Character; } LLWString getText() const { return mText; } - std::string getDescr() const { return mDescr; } - std::string getCategory() const { return mCategory; } private: - const llwchar mEmoji; + const LLEmojiDescriptor* mDescr; const LLWString mText; - const std::string mDescr; - const std::string mCategory; +}; + +class LLEmojiPreviewPanel : public LLPanel +{ +public: + LLEmojiPreviewPanel() + : LLPanel() + { + } + + void setEmoji(const LLEmojiDescriptor* descr) + { + mDescr = descr; + + if (!mDescr) + return; + + mEmojiText = LLWString(1, descr->Character); + } + + virtual void draw() override + { + LLPanel::draw(); + + if (!mDescr) + return; + + S32 clientHeight = getRect().getHeight(); + S32 clientWidth = getRect().getWidth(); + S32 iconWidth = clientHeight; + + F32 centerX = 0.5f * iconWidth; + F32 centerY = 0.5f * clientHeight; + drawIcon(centerX, centerY, iconWidth); + + static LLColor4 defaultColor(0.75f, 0.75f, 0.75f, 1.0f); + LLColor4 textColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", defaultColor); + S32 max_pixels = clientWidth - iconWidth; + size_t count = mDescr->ShortCodes.size(); + if (count == 1) + { + drawName(mDescr->ShortCodes.front(), iconWidth, centerY, max_pixels, textColor); + } + else if (count > 1) + { + F32 quarterY = 0.5f * centerY; + drawName(mDescr->ShortCodes.front(), iconWidth, centerY + quarterY, max_pixels, textColor); + drawName(*++mDescr->ShortCodes.begin(), iconWidth, quarterY, max_pixels, textColor); + } + } + +protected: + void drawIcon(F32 x, F32 y, S32 max_pixels) + { + LLFontGL::getFontEmojiHuge()->render( + mEmojiText, // wstr + 0, // begin_offset + x, // x + y, // y + LLColor4::white, // color + LLFontGL::HCENTER, // halign + LLFontGL::VCENTER, // valign + LLFontGL::NORMAL, // style + LLFontGL::DROP_SHADOW_SOFT, // shadow + 1, // max_chars + max_pixels, // max_pixels + nullptr, // right_x + false, // use_ellipses + true); // use_color + } + + void drawName(std::string name, F32 x, F32 y, S32 max_pixels, LLColor4& color) + { + LLFontGL::getFontEmoji()->renderUTF8( + name, // wstr + 0, // begin_offset + x, // x + y, // y + color, // color + LLFontGL::LEFT, // halign + LLFontGL::VCENTER, // valign + LLFontGL::NORMAL, // style + LLFontGL::DROP_SHADOW_SOFT, // shadow + -1, // max_chars + max_pixels, // max_pixels + nullptr, // right_x + true, // use_ellipses + false); // use_color + } + +private: + const LLEmojiDescriptor* mDescr { nullptr }; + LLWString mEmojiText; }; LLFloaterEmojiPicker* LLFloaterEmojiPicker::getInstance() @@ -244,19 +287,17 @@ LLFloaterEmojiPicker::LLFloaterEmojiPicker(const LLSD& key) BOOL LLFloaterEmojiPicker::postBuild() { // Should be initialized first - mPreviewEmoji = getChild<LLButton>("PreviewEmoji"); - mPreviewEmoji->setClickedCallback([this](LLUICtrl*, const LLSD&) { onPreviewEmojiClick(); }); - - mDescription = getChild<LLTextBox>("Description"); - mDescription->setVisible(FALSE); + mPreview = new LLEmojiPreviewPanel(); + mPreview->setVisible(FALSE); + addChild(mPreview); mGroups = getChild<LLPanel>("Groups"); mBadge = getChild<LLPanel>("Badge"); - mSearch = getChild<LLLineEditor>("Search"); - mSearch->setKeystrokeCallback([this](LLLineEditor*, void*) { onSearchKeystroke(); }, NULL); - mSearch->setFont(LLViewerChat::getChatFont()); - mSearch->setText(sSearchPattern); + mFilter = getChild<LLLineEditor>("Filter"); + mFilter->setKeystrokeCallback([this](LLLineEditor*, void*) { onSearchKeystroke(); }, NULL); + mFilter->setFont(LLViewerChat::getChatFont()); + mFilter->setText(sFilterPattern); mEmojiScroll = getChild<LLScrollContainer>("EmojiGridContainer"); mEmojiScroll->setMouseEnterCallback([this](LLUICtrl*, const LLSD&) { onGridMouseEnter(); }); @@ -274,6 +315,16 @@ void LLFloaterEmojiPicker::dirtyRect() { super::dirtyRect(); + if (!mFilter) + return; + + const S32 PADDING = 4; + LLRect rect(PADDING, mFilter->getRect().mTop, getRect().getWidth() - PADDING * 2, PADDING); + if (mPreview->getRect() != rect) + { + mPreview->setRect(rect); + } + if (mEmojiScroll && mEmojiScroll->getRect().getWidth() != mRecentGridWidth) { moveGroups(); @@ -374,7 +425,7 @@ void LLFloaterEmojiPicker::fillEmojis(bool fromResize) mHoveredIcon = nullptr; mEmojiGrid->clearPanels(); - mPreviewEmoji->setLabel(LLUIString()); + mPreview->setEmoji(nullptr); if (mEmojiGrid->getRect().getWidth() != clientWidth) { @@ -395,18 +446,17 @@ void LLFloaterEmojiPicker::fillEmojis(bool fromResize) LLPanel::Params icon_params; LLRect icon_rect(0, iconSize, iconSize, 0); - static const LLColor4 bgcolors[] = + static LLColor4 defaultColor(0.75f, 0.75f, 0.75f, 1.0f); + LLColor4 bgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", defaultColor); + + auto matchesPattern = [](const LLEmojiDescriptor* descr) -> bool { - LLColor4(0.8f, 0.6f, 0.8f, 1.0f), - LLColor4(0.8f, 0.8f, 0.4f, 1.0f), - LLColor4(0.6f, 0.6f, 0.8f, 1.0f), - LLColor4(0.4f, 0.7f, 0.4f, 1.0f), - LLColor4(0.5f, 0.7f, 0.9f, 1.0f), - LLColor4(0.7f, 0.8f, 0.2f, 1.0f) + for (const std::string& shortCode : descr->ShortCodes) + if (shortCode.find(sFilterPattern) != std::string::npos) + return true; + return false; }; - static constexpr U32 bgcolorCount = sizeof(bgcolors) / sizeof(*bgcolors); - auto listCategory = [&](std::string category, const std::vector<const LLEmojiDescriptor*>& emojis, int maxRows = 0) { int rowCount = 0; @@ -418,9 +468,10 @@ void LLFloaterEmojiPicker::fillEmojis(bool fromResize) { LLStringUtil::capitalize(category); } + for (const LLEmojiDescriptor* descr : emojis) { - if (sSearchPattern.empty() || matchesPattern(descr)) + if (sFilterPattern.empty() || matchesPattern(descr)) { // Place a category title if needed if (showDivider) @@ -443,8 +494,9 @@ void LLFloaterEmojiPicker::fillEmojis(bool fromResize) LLEmojiGridIcon* icon = new LLEmojiGridIcon(icon_params, descr, mixedFolder ? LLStringUtil::capitalize(descr->Category) : category); icon->setMouseEnterCallback([this](LLUICtrl* ctrl, const LLSD&) { onEmojiMouseEnter(ctrl); }); icon->setMouseLeaveCallback([this](LLUICtrl* ctrl, const LLSD&) { onEmojiMouseLeave(ctrl); }); - icon->setMouseUpCallback([this](LLUICtrl* ctrl, S32, S32, MASK mask) { onEmojiMouseClick(ctrl, mask); }); - icon->setBackgroundColor(bgcolors[iconIndex % bgcolorCount]); + icon->setMouseDownCallback([this](LLUICtrl* ctrl, S32, S32, MASK) { onEmojiMouseDown(ctrl); }); + icon->setMouseUpCallback([this](LLUICtrl* ctrl, S32, S32, MASK) { onEmojiMouseUp(ctrl); }); + icon->setBackgroundColor(bgColor); icon->setBackgroundOpaque(1); icon->setRect(icon_rect); row->mList->addPanel(icon, true); @@ -511,14 +563,6 @@ void LLFloaterEmojiPicker::fillEmojis(bool fromResize) } } -bool LLFloaterEmojiPicker::matchesPattern(const LLEmojiDescriptor* descr) -{ - for (const std::string& shortCode : descr->ShortCodes) - if (shortCode.find(sSearchPattern) != std::string::npos) - return true; - return false; -} - void LLFloaterEmojiPicker::onGroupButtonClick(LLUICtrl* ctrl) { if (LLButton* button = dynamic_cast<LLButton*>(ctrl)) @@ -541,7 +585,7 @@ void LLFloaterEmojiPicker::onGroupButtonClick(LLUICtrl* ctrl) rect.mRight = button->getRect().mRight; mBadge->setRect(rect); - mSearch->setFocus(TRUE); + mFilter->setFocus(TRUE); fillEmojis(); } @@ -549,34 +593,22 @@ void LLFloaterEmojiPicker::onGroupButtonClick(LLUICtrl* ctrl) void LLFloaterEmojiPicker::onSearchKeystroke() { - sSearchPattern = mSearch->getText(); + sFilterPattern = mFilter->getText(); fillEmojis(); } -void LLFloaterEmojiPicker::onPreviewEmojiClick() -{ - if (mEmojiPickCallback) - { - if (LLEmojiGridIcon* icon = dynamic_cast<LLEmojiGridIcon*>(mHoveredIcon)) - { - mEmojiPickCallback(icon->getEmoji()); - } - } -} - void LLFloaterEmojiPicker::onGridMouseEnter() { - mSearch->setVisible(FALSE); - mDescription->setText(LLStringExplicit(""), LLStyle::Params()); - mDescription->setVisible(TRUE); + mFilter->setVisible(FALSE); + mPreview->setEmoji(nullptr); + mPreview->setVisible(TRUE); } void LLFloaterEmojiPicker::onGridMouseLeave() { - mDescription->setVisible(FALSE); - mDescription->setText(LLStringExplicit(""), LLStyle::Params()); - mSearch->setVisible(TRUE); - mSearch->setFocus(TRUE); + mPreview->setVisible(FALSE); + mFilter->setVisible(TRUE); + mFilter->setFocus(TRUE); } void LLFloaterEmojiPicker::onGroupButtonMouseEnter(LLUICtrl* ctrl) @@ -621,18 +653,29 @@ void LLFloaterEmojiPicker::onEmojiMouseLeave(LLUICtrl* ctrl) } } -void LLFloaterEmojiPicker::onEmojiMouseClick(LLUICtrl* ctrl, MASK mask) +void LLFloaterEmojiPicker::onEmojiMouseDown(LLUICtrl* ctrl) +{ + if (getSoundFlags() & MOUSE_DOWN) + { + make_ui_sound("UISndClick"); + } +} + +void LLFloaterEmojiPicker::onEmojiMouseUp(LLUICtrl* ctrl) { + if (getSoundFlags() & MOUSE_UP) + { + make_ui_sound("UISndClickRelease"); + } + if (mEmojiPickCallback) { if (LLEmojiGridIcon* icon = dynamic_cast<LLEmojiGridIcon*>(ctrl)) { onEmojiUsed(icon->getEmoji()); - mPreviewEmoji->handleAnyMouseClick(0, 0, 0, EMouseClickType::CLICK_LEFT, TRUE); - mPreviewEmoji->handleAnyMouseClick(0, 0, 0, EMouseClickType::CLICK_LEFT, FALSE); - if (!(mask & 4)) + if (mEmojiPickCallback) { - closeFloater(); + mEmojiPickCallback(icon->getEmoji()); } } } @@ -643,13 +686,7 @@ void LLFloaterEmojiPicker::selectGridIcon(LLUICtrl* ctrl) if (LLEmojiGridIcon* icon = dynamic_cast<LLEmojiGridIcon*>(ctrl)) { icon->setBackgroundVisible(TRUE); - - LLUIString text; - text.insert(0, icon->getText()); - mPreviewEmoji->setLabel(text); - - std::string descr = icon->getDescr() + "\n" + icon->getCategory(); - mDescription->setText(LLStringExplicit(descr), LLStyle::Params()); + mPreview->setEmoji(icon->getDescr()); } } @@ -658,8 +695,7 @@ void LLFloaterEmojiPicker::unselectGridIcon(LLUICtrl* ctrl) if (LLEmojiGridIcon* icon = dynamic_cast<LLEmojiGridIcon*>(ctrl)) { icon->setBackgroundVisible(FALSE); - mPreviewEmoji->setLabel(LLUIString()); - mDescription->setText(LLStringExplicit(""), LLStyle::Params()); + mPreview->setEmoji(nullptr); } } @@ -754,7 +790,7 @@ void LLFloaterEmojiPicker::loadState() sSelectedGroupIndex = state[sKeySelectedGroupIndex].asInteger(); - sSearchPattern = state[sKeySearchPattern].asString(); + sFilterPattern = state[sKeyFilterPattern].asString(); // Load and parse sRecentlyUsed std::string recentlyUsed = state[sKeyRecentlyUsed]; @@ -826,9 +862,9 @@ void LLFloaterEmojiPicker::saveState() state[sKeySelectedGroupIndex] = (int)sSelectedGroupIndex; } - if (!sSearchPattern.empty()) + if (!sFilterPattern.empty()) { - state[sKeySearchPattern] = sSearchPattern; + state[sKeyFilterPattern] = sFilterPattern; } if (!sRecentlyUsed.empty()) diff --git a/indra/newview/llfloateremojipicker.h b/indra/newview/llfloateremojipicker.h index d00391c61f..e4b1216ce6 100644 --- a/indra/newview/llfloateremojipicker.h +++ b/indra/newview/llfloateremojipicker.h @@ -59,18 +59,16 @@ private: void moveGroups(); void fillEmojis(bool fromResize = false); - bool matchesPattern(const LLEmojiDescriptor* descr); - void onGroupButtonClick(LLUICtrl* ctrl); void onSearchKeystroke(); - void onPreviewEmojiClick(); void onGridMouseEnter(); void onGridMouseLeave(); void onGroupButtonMouseEnter(LLUICtrl* ctrl); void onGroupButtonMouseLeave(LLUICtrl* ctrl); void onEmojiMouseEnter(LLUICtrl* ctrl); void onEmojiMouseLeave(LLUICtrl* ctrl); - void onEmojiMouseClick(LLUICtrl* ctrl, MASK mask); + void onEmojiMouseDown(LLUICtrl* ctrl); + void onEmojiMouseUp(LLUICtrl* ctrl); void selectGridIcon(LLUICtrl* ctrl); void unselectGridIcon(LLUICtrl* ctrl); @@ -83,11 +81,10 @@ private: class LLPanel* mGroups { nullptr }; class LLPanel* mBadge { nullptr }; - class LLLineEditor* mSearch { nullptr }; + class LLLineEditor* mFilter { nullptr }; class LLScrollContainer* mEmojiScroll { nullptr }; class LLScrollingPanelList* mEmojiGrid { nullptr }; - class LLButton* mPreviewEmoji { nullptr }; - class LLTextBox* mDescription { nullptr }; + class LLEmojiPreviewPanel* mPreview { nullptr }; pick_callback_t mEmojiPickCallback; close_callback_t mFloaterCloseCallback; diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index f1807f1c5b..df780f152a 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -128,11 +128,12 @@ BOOL LLFloaterIMNearbyChat::postBuild() mInputEditor->setKeystrokeCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxKeystroke, this)); mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusLost, this)); mInputEditor->setFocusReceivedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusReceived, this)); - mInputEditor->setLabel(LLTrans::getString("NearbyChatTitle")); + std::string nearbyChatTitle(LLTrans::getString("NearbyChatTitle")); + mInputEditor->setLabel(nearbyChatTitle); // Title must be defined BEFORE call to addConversationListItem() because // it is used to show the item's name in the conversations list - setTitle(LLTrans::getString("NearbyChatTitle")); + setTitle(nearbyChatTitle); // obsolete, but may be needed for backward compatibility? gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", LLControlVariable::PERSIST_NONDFT); diff --git a/indra/newview/skins/default/xui/en/floater_emoji_picker.xml b/indra/newview/skins/default/xui/en/floater_emoji_picker.xml index 4b4bf0c5a3..a2a290c306 100644 --- a/indra/newview/skins/default/xui/en/floater_emoji_picker.xml +++ b/indra/newview/skins/default/xui/en/floater_emoji_picker.xml @@ -13,42 +13,26 @@ <floater.string name="title_for_recently_used" value="Recently used"/> <floater.string name="title_for_frequently_used" value="Frequently used"/> <line_editor - name="Search" - label="Type to search" + name="Filter" + label="Start typing to filter" layout="bottomleft" follows="bottom|left|right" text_tentative_color="TextFgTentativeColor" + show_label_focused="true" max_length_bytes="63" + text_pad_right="5" + text_pad_left="5" bottom="14" - left="34" + left="10" height="29" - width="212" /> - <text - name="Description" - layout="bottomleft" - follows="bottom|left|right" - font="SansSerifMedium" - bottom="14" - left="42" - height="29" - width="200" /> - <button - name="PreviewEmoji" - layout="bottomleft" - follows="bottom|left" - font="EmojiHuge" - use_font_color="true" - bottom="14" - left="2" - height="29" - width="29" /> + width="230" /> <scroll_container name="EmojiGridContainer" layout="topleft" follows="all" top="25" left="0" - height="330" + height="325" width="250"> <scrolling_panel_list name="EmojiGrid" |