diff options
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/llemojidictionary.cpp | 132 | ||||
-rw-r--r-- | indra/llui/llemojidictionary.h | 1 | ||||
-rw-r--r-- | indra/llui/llemojihelper.cpp | 7 | ||||
-rw-r--r-- | indra/llui/llemojihelper.h | 4 | ||||
-rw-r--r-- | indra/llui/llfloater.cpp | 28 | ||||
-rw-r--r-- | indra/llui/llfloater.h | 5 | ||||
-rw-r--r-- | indra/llui/lltexteditor.cpp | 24 | ||||
-rw-r--r-- | indra/llui/lltexteditor.h | 1 | ||||
-rw-r--r-- | indra/llui/lluictrl.cpp | 25 |
9 files changed, 132 insertions, 95 deletions
diff --git a/indra/llui/llemojidictionary.cpp b/indra/llui/llemojidictionary.cpp index e29f3436cf..f16c38a11a 100644 --- a/indra/llui/llemojidictionary.cpp +++ b/indra/llui/llemojidictionary.cpp @@ -41,9 +41,9 @@ static const std::string SKINNED_EMOJI_FILENAME("emoji_characters.xml"); static const std::string SKINNED_CATEGORY_FILENAME("emoji_categories.xml"); static const std::string COMMON_GROUP_FILENAME("emoji_groups.xml"); -static const std::string GROUP_NAME_ALL("all"); -static const std::string GROUP_NAME_OTHERS("others"); static const std::string GROUP_NAME_SKIP("skip"); +// https://www.compart.com/en/unicode/U+1F302 +static const S32 GROUP_OTHERS_IMAGE_INDEX = 0x1F302; // ============================================================================ // Helper functions @@ -143,68 +143,76 @@ LLWString LLEmojiDictionary::findMatchingEmojis(const std::string& needle) const return result; } -void LLEmojiDictionary::findByShortCode(std::vector<LLEmojiSearchResult>& result, const std::string& needle) const +// static +bool LLEmojiDictionary::searchInShortCode(std::size_t& begin, std::size_t& end, const std::string& shortCode, const std::string& needle) +{ + 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++]); + if (!d) + return true; + 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; +} + +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 + std::map<llwchar, std::vector<LLEmojiSearchResult>> results; + + for (const LLEmojiDescriptor& d : mEmojis) + { + if (!d.ShortCodes.empty()) { - begin = 0; - end = 1; - std::size_t index = 1; - // Search for begin - char d = tolower(needle[index++]); - while (end < shortCode.size()) + const std::string& shortCode = d.ShortCodes.front(); + if (shortCode.size() >= needle.size() && shortCode.front() == needle.front()) { - char s = tolower(shortCode[end++]); - if (s == d) + std::size_t begin, end; + if (searchInShortCode(begin, end, shortCode, needle)) { - begin = end - 1; - break; + results[begin].emplace_back(d.Character, shortCode, begin, end); } } - 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; - }; - - std::map<std::size_t, std::vector<LLEmojiSearchResult>> results; - - 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)) - { - results[begin].emplace_back(d.Character, shortCode, begin, end); } } @@ -312,27 +320,13 @@ void LLEmojiDictionary::loadGroups() } mGroups.clear(); - // Add group "all" - mGroups.emplace_back(); - // https://www.compart.com/en/unicode/U+1F50D - mGroups.front().Character = 0x1F50D; - // https://www.compart.com/en/unicode/U+1F302 - llwchar iconOthers = 0x1F302; // Register all groups for (LLSD::array_const_iterator it = data.beginArray(), end = data.endArray(); it != end; ++it) { const LLSD& sd = *it; const std::string& name = sd["Name"].asStringRef(); - if (name == GROUP_NAME_ALL) - { - mGroups.front().Character = loadIcon(sd); - } - else if (name == GROUP_NAME_OTHERS) - { - iconOthers = loadIcon(sd); - } - else if (name == GROUP_NAME_SKIP) + if (name == GROUP_NAME_SKIP) { mSkipCategories = loadCategories(sd); translateCategories(mSkipCategories); @@ -355,7 +349,7 @@ void LLEmojiDictionary::loadGroups() // Add group "others" mGroups.emplace_back(); - mGroups.back().Character = iconOthers; + mGroups.back().Character = GROUP_OTHERS_IMAGE_INDEX; } void LLEmojiDictionary::loadEmojis() diff --git a/indra/llui/llemojidictionary.h b/indra/llui/llemojidictionary.h index 66b564b70a..4af376df64 100644 --- a/indra/llui/llemojidictionary.h +++ b/indra/llui/llemojidictionary.h @@ -89,6 +89,7 @@ public: static void initClass(); LLWString findMatchingEmojis(const std::string& needle) const; + static bool searchInShortCode(std::size_t& begin, std::size_t& end, const std::string& shortCode, const std::string& needle); 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; diff --git a/indra/llui/llemojihelper.cpp b/indra/llui/llemojihelper.cpp index 9411f7cac5..89e6ddf987 100644 --- a/indra/llui/llemojihelper.cpp +++ b/indra/llui/llemojihelper.cpp @@ -36,7 +36,7 @@ // Constants // -constexpr char DEFAULT_EMOJI_HELPER_FLOATER[] = "emoji_complete"; +constexpr char DEFAULT_EMOJI_HELPER_FLOATER[] = "emoji_picker"; constexpr S32 HELPER_FLOATER_OFFSET_X = 0; constexpr S32 HELPER_FLOATER_OFFSET_Y = 0; @@ -117,9 +117,10 @@ void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, c pHelperFloater->openFloater(LLSD().with("hint", short_code)); } -void LLEmojiHelper::hideHelper(const LLUICtrl* ctrl_p) +void LLEmojiHelper::hideHelper(const LLUICtrl* ctrl_p, bool strict) { - if (ctrl_p && !isActive(ctrl_p)) + mIsHideDisabled &= !strict; + if (mIsHideDisabled || (ctrl_p && !isActive(ctrl_p))) { return; } diff --git a/indra/llui/llemojihelper.h b/indra/llui/llemojihelper.h index 58f68d12a4..e826ff93e6 100644 --- a/indra/llui/llemojihelper.h +++ b/indra/llui/llemojihelper.h @@ -45,7 +45,8 @@ public: bool isActive(const LLUICtrl* ctrl_p) const; static bool isCursorInEmojiCode(const LLWString& wtext, S32 cursor_pos, S32* short_code_pos_p = nullptr); void showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, const std::string& short_code, std::function<void(llwchar)> commit_cb); - void hideHelper(const LLUICtrl* ctrl_p = nullptr); + void hideHelper(const LLUICtrl* ctrl_p = nullptr, bool strict = false); + void setIsHideDisabled(bool disabled) { mIsHideDisabled = disabled; }; // Eventing bool handleKey(const LLUICtrl* ctrl_p, KEY key, MASK mask); @@ -61,4 +62,5 @@ private: boost::signals2::connection mHostCtrlFocusLostConn; boost::signals2::connection mHelperCommitConn; std::function<void(llwchar)> mEmojiCommitCb; + bool mIsHideDisabled; }; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 23d3a66631..31019f6c33 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -182,6 +182,7 @@ LLFloater::Params::Params() save_visibility("save_visibility", false), can_dock("can_dock", false), show_title("show_title", true), + auto_close("auto_close", false), positioning("positioning", LLFloaterEnums::POSITIONING_RELATIVE), header_height("header_height", 0), legacy_header_height("legacy_header_height", 0), @@ -254,6 +255,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) mCanClose(p.can_close), mDragOnLeft(p.can_drag_on_left), mResizable(p.can_resize), + mAutoClose(p.auto_close), mPositioning(p.positioning), mMinWidth(p.min_width), mMinHeight(p.min_height), @@ -681,7 +683,7 @@ void LLFloater::openFloater(const LLSD& key) if (getHost() != NULL) { getHost()->setMinimized(FALSE); - getHost()->setVisibleAndFrontmost(mAutoFocus); + getHost()->setVisibleAndFrontmost(mAutoFocus && !getIsChrome()); getHost()->showFloater(this); } else @@ -693,7 +695,7 @@ void LLFloater::openFloater(const LLSD& key) } applyControlsAndPosition(floater_to_stack); setMinimized(FALSE); - setVisibleAndFrontmost(mAutoFocus); + setVisibleAndFrontmost(mAutoFocus && !getIsChrome()); } mOpenSignal(this, key); @@ -1551,7 +1553,7 @@ void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition, BOOL r if (floaterp->isFrontmost()) { // make sure to bring self and sibling floaters to front - gFloaterView->bringToFront(floaterp); + gFloaterView->bringToFront(floaterp, floaterp->getAutoFocus() && !getIsChrome()); } } @@ -1696,6 +1698,7 @@ BOOL LLFloater::handleDoubleClick(S32 x, S32 y, MASK mask) return was_minimized || LLPanel::handleDoubleClick(x, y, mask); } +// virtual void LLFloater::bringToFront( S32 x, S32 y ) { if (getVisible() && pointInView(x, y)) @@ -1710,12 +1713,20 @@ void LLFloater::bringToFront( S32 x, S32 y ) LLFloaterView* parent = dynamic_cast<LLFloaterView*>( getParent() ); if (parent) { - parent->bringToFront( this ); + parent->bringToFront(this, !getIsChrome()); } } } } +// virtual +void LLFloater::goneFromFront() +{ + if (mAutoClose) + { + closeFloater(); + } +} // virtual void LLFloater::setVisibleAndFrontmost(BOOL take_focus,const LLSD& key) @@ -2561,6 +2572,11 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus, BOOL restore return; } + if (mFrontChild && !mFrontChild->isDead()) + { + mFrontChild->goneFromFront(); + } + mFrontChild = child; // *TODO: make this respect floater's mAutoFocus value, instead of @@ -3060,6 +3076,9 @@ LLFloater *LLFloaterView::getBackmost() const void LLFloaterView::syncFloaterTabOrder() { + if (mFrontChild && !mFrontChild->isDead() && mFrontChild->getIsChrome()) + return; + // look for a visible modal dialog, starting from first LLModalDialog* modal_dialog = NULL; for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) @@ -3307,6 +3326,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p) mDefaultRelativeY = p.rel_y; mPositioning = p.positioning; + mAutoClose = p.auto_close; mSaveRect = p.save_rect; if (p.save_visibility) diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 860a6f9e2a..5f4e1a2cad 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -163,7 +163,8 @@ public: save_visibility, save_dock_state, can_dock, - show_title; + show_title, + auto_close; Optional<LLFloaterEnums::EOpenPositioning> positioning; @@ -390,6 +391,7 @@ protected: void setInstanceName(const std::string& name); virtual void bringToFront(S32 x, S32 y); + virtual void goneFromFront(); void setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized const LLRect& getExpandedRect() const { return mExpandedRect; } @@ -488,6 +490,7 @@ private: bool mFocusStealsFrontmost = true; // FALSE if we don't want the currently focused floater to cover this floater without user interaction BOOL mDragOnLeft; BOOL mResizable; + BOOL mAutoClose; LLFloaterEnums::EOpenPositioning mPositioning; LLCoordFloater mPosition; diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 3910be1443..092739a538 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -508,7 +508,8 @@ void LLTextEditor::getSegmentsInRange(LLTextEditor::segment_vec_t& segments_out, } } -void LLTextEditor::setShowEmojiHelper(bool show) { +void LLTextEditor::setShowEmojiHelper(bool show) +{ if (!mShowEmojiHelper) { LLEmojiHelper::instance().hideHelper(this); @@ -1192,6 +1193,16 @@ void LLTextEditor::addChar(llwchar wc) } } +void LLTextEditor::showEmojiHelper() +{ + if (mReadOnly || !mShowEmojiHelper) + return; + + const LLRect cursorRect(getLocalRectFromDocIndex(mCursorPos)); + auto cb = [this](llwchar emoji) { insertEmoji(emoji); }; + LLEmojiHelper::instance().showHelper(this, cursorRect.mLeft, cursorRect.mTop, LLStringUtil::null, cb); +} + void LLTextEditor::tryToShowEmojiHelper() { if (mReadOnly || !mShowEmojiHelper) @@ -1207,6 +1218,10 @@ void LLTextEditor::tryToShowEmojiHelper() auto cb = [this](llwchar emoji) { handleEmojiCommit(emoji); }; LLEmojiHelper::instance().showHelper(this, cursorRect.mLeft, cursorRect.mTop, part, cb); } + else + { + LLEmojiHelper::instance().hideHelper(); + } } void LLTextEditor::addLineBreakChar(BOOL group_together) @@ -1911,7 +1926,12 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char) // Handle most keys only if the text editor is writeable. if( !mReadOnly ) { - if( mAutoIndent && '}' == uni_char ) + if (mShowEmojiHelper && uni_char < 0x80 && LLEmojiHelper::instance().handleKey(this, (KEY)uni_char, MASK_NONE)) + { + return TRUE; + } + + if( mAutoIndent && '}' == uni_char ) { unindentLineBeforeCloseBrace(); } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 7a96e17899..521405ec25 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -206,6 +206,7 @@ public: void setShowContextMenu(bool show) { mShowContextMenu = show; } bool getShowContextMenu() const { return mShowContextMenu; } + void showEmojiHelper(); void setShowEmojiHelper(bool show); bool getShowEmojiHelper() const { return mShowEmojiHelper; } diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 21afcae7c3..7eb9ae69fb 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -768,25 +768,20 @@ void LLUICtrl::setIsChrome(BOOL is_chrome) // virtual BOOL LLUICtrl::getIsChrome() const -{ +{ + if (mIsChrome) + return TRUE; + LLView* parent_ctrl = getParent(); - while(parent_ctrl) + while (parent_ctrl) { - if(parent_ctrl->isCtrl()) - { - break; - } + if (parent_ctrl->isCtrl()) + return ((LLUICtrl*)parent_ctrl)->getIsChrome(); + parent_ctrl = parent_ctrl->getParent(); } - - if(parent_ctrl) - { - return mIsChrome || ((LLUICtrl*)parent_ctrl)->getIsChrome(); - } - else - { - return mIsChrome ; - } + + return FALSE; } |