Merge branch 'DRTVWR-489' of https://github.com/secondlife/viewer
# Conflicts: # indra/llrender/llfontfreetype.cpp # indra/llui/llfloater.cpp # indra/llui/llfloater.h # indra/llui/lltextbase.cpp # indra/newview/llfloateremojipicker.cpp # indra/newview/llfloateremojipicker.h # indra/newview/llinventorygallery.cpp # indra/newview/llworldmapview.cpp # indra/newview/skins/default/xui/en/floater_emoji_picker.xmlmaster
commit
394c8e17d5
|
|
@ -339,8 +339,6 @@ S32 wchar_utf8_length(const llwchar wc)
|
|||
{
|
||||
if (wc < 0x80)
|
||||
{
|
||||
// This case will also catch negative values which are
|
||||
// technically invalid.
|
||||
return 1;
|
||||
}
|
||||
else if (wc < 0x800)
|
||||
|
|
|
|||
|
|
@ -762,12 +762,25 @@ void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) co
|
|||
load_flags |= FT_LOAD_COLOR;
|
||||
}
|
||||
|
||||
// <FS:ND> try to load given glyph, if that fails, fallback to ?. This can happen with invalid unicode codepoints.
|
||||
if( 0 != FT_Load_Glyph(mFTFace, glyph_index, load_flags) )
|
||||
glyph_index = FT_Get_Char_Index( mFTFace, L'?');
|
||||
// </FS:ND>
|
||||
FT_Error error = FT_Load_Glyph(mFTFace, glyph_index, load_flags);
|
||||
if (FT_Err_Ok != error)
|
||||
{
|
||||
std::string message = llformat(
|
||||
"Error %d (%s) loading glyph %u: bitmap_type=%u, load_flags=%d",
|
||||
error, FT_Error_String(error), glyph_index, bitmap_type, load_flags);
|
||||
LL_WARNS_ONCE() << message << LL_ENDL;
|
||||
error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR);
|
||||
|
||||
llassert_always(! FT_Load_Glyph(mFTFace, glyph_index, load_flags) );
|
||||
// <FS:ND> try to load given glyph, if that fails, fallback to ?. This can happen with invalid unicode codepoints.
|
||||
if (FT_Err_Ok != error)
|
||||
{
|
||||
glyph_index = FT_Get_Char_Index( mFTFace, L'?');
|
||||
error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR);
|
||||
}
|
||||
// </FS:ND>
|
||||
|
||||
llassert_always_msg(FT_Err_Ok == error, message.c_str());
|
||||
}
|
||||
|
||||
llassert_always(! FT_Render_Glyph(mFTFace->glyph, gFontRenderMode) );
|
||||
|
||||
|
|
|
|||
|
|
@ -446,7 +446,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||
|
||||
S32 LLFontGL::render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const
|
||||
{
|
||||
return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
|
||||
return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW);
|
||||
}
|
||||
|
||||
S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses, BOOL use_color) const
|
||||
|
|
@ -456,12 +456,12 @@ S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y
|
|||
|
||||
S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const
|
||||
{
|
||||
return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE, FALSE);
|
||||
return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW);
|
||||
}
|
||||
|
||||
S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow) const
|
||||
{
|
||||
return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow, S32_MAX, S32_MAX, NULL, FALSE, FALSE);
|
||||
return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow);
|
||||
}
|
||||
|
||||
// font metrics - override for LLFontFreetype that returns units of virtual pixels
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ public:
|
|||
S32 max_chars = S32_MAX,
|
||||
F32* right_x=NULL,
|
||||
BOOL use_ellipses = FALSE,
|
||||
BOOL use_color = FALSE) const;
|
||||
BOOL use_color = TRUE) const;
|
||||
|
||||
S32 render(const LLWString &text, S32 begin_offset,
|
||||
const LLRectf& rect,
|
||||
|
|
@ -109,7 +109,7 @@ public:
|
|||
S32 max_chars = S32_MAX,
|
||||
F32* right_x=NULL,
|
||||
BOOL use_ellipses = FALSE,
|
||||
BOOL use_color = FALSE) const;
|
||||
BOOL use_color = TRUE) const;
|
||||
|
||||
S32 render(const LLWString &text, S32 begin_offset,
|
||||
F32 x, F32 y,
|
||||
|
|
@ -119,12 +119,12 @@ public:
|
|||
S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX,
|
||||
F32* right_x=NULL,
|
||||
BOOL use_ellipses = FALSE,
|
||||
BOOL use_color = FALSE) const;
|
||||
BOOL use_color = TRUE) const;
|
||||
|
||||
S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const;
|
||||
|
||||
// renderUTF8 does a conversion, so is slower!
|
||||
S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses, BOOL use_color) const;
|
||||
S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x = NULL, BOOL use_ellipses = FALSE, BOOL use_color = TRUE) const;
|
||||
S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const;
|
||||
S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ LLButton::Params::Params()
|
|||
label_shadow("label_shadow", true),
|
||||
auto_resize("auto_resize", false),
|
||||
use_ellipses("use_ellipses", false),
|
||||
use_font_color("use_font_color", false),
|
||||
use_font_color("use_font_color", true),
|
||||
image_unselected("image_unselected"),
|
||||
image_selected("image_selected"),
|
||||
image_hover_selected("image_hover_selected"),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
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++]);
|
||||
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;
|
||||
std::map<llwchar, 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))
|
||||
if (!d.ShortCodes.empty())
|
||||
{
|
||||
results[begin].emplace_back(d.Character, shortCode, begin, end);
|
||||
const std::string& shortCode = d.ShortCodes.front();
|
||||
if (shortCode.size() >= needle.size() && shortCode.front() == needle.front())
|
||||
{
|
||||
std::size_t begin, end;
|
||||
if (searchInShortCode(begin, end, shortCode, needle))
|
||||
{
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -194,6 +194,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),
|
||||
|
|
@ -271,6 +272,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
|
|||
mCanSnooze(p.can_snooze), // <FS:Ansariel> FIRE-11724: Snooze group chat
|
||||
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),
|
||||
|
|
@ -539,6 +541,7 @@ void LLFloater::enableResizeCtrls(bool enable, bool width, bool height)
|
|||
|
||||
void LLFloater::destroy()
|
||||
{
|
||||
gFloaterView->onDestroyFloater(this);
|
||||
// LLFloaterReg should be synchronized with "dead" floater to avoid returning dead instance before
|
||||
// it was deleted via LLMortician::updateClass(). See EXT-8458.
|
||||
LLFloaterReg::removeInstance(mInstanceName, mKey);
|
||||
|
|
@ -737,7 +740,7 @@ void LLFloater::openFloater(const LLSD& key)
|
|||
if (getHost() != NULL)
|
||||
{
|
||||
getHost()->setMinimized(FALSE);
|
||||
getHost()->setVisibleAndFrontmost(mAutoFocus);
|
||||
getHost()->setVisibleAndFrontmost(mAutoFocus && !getIsChrome());
|
||||
getHost()->showFloater(this);
|
||||
// <FS:Zi> Make sure the floater knows it's not torn off
|
||||
mTornOff = false;
|
||||
|
|
@ -754,7 +757,7 @@ void LLFloater::openFloater(const LLSD& key)
|
|||
}
|
||||
applyControlsAndPosition(floater_to_stack);
|
||||
setMinimized(FALSE);
|
||||
setVisibleAndFrontmost(mAutoFocus);
|
||||
setVisibleAndFrontmost(mAutoFocus && !getIsChrome());
|
||||
}
|
||||
|
||||
mOpenSignal(this, key);
|
||||
|
|
@ -1638,7 +1641,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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1820,6 +1823,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))
|
||||
|
|
@ -1834,12 +1838,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)
|
||||
|
|
@ -2619,7 +2631,8 @@ LLFloaterView::LLFloaterView (const Params& p)
|
|||
mSnapOffsetBottom(0),
|
||||
mSnapOffsetChatBar(0),
|
||||
mSnapOffsetLeft(0),
|
||||
mSnapOffsetRight(0)
|
||||
mSnapOffsetRight(0),
|
||||
mFrontChild(NULL)
|
||||
{
|
||||
mSnapView = getHandle();
|
||||
}
|
||||
|
|
@ -2775,7 +2788,7 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus, BOOL restore
|
|||
if (!child)
|
||||
return;
|
||||
|
||||
if (mFrontChildHandle.get() == child)
|
||||
if (mFrontChild == child)
|
||||
{
|
||||
if (give_focus && child->canFocusStealFrontmost() && !gFocusMgr.childHasKeyboardFocus(child))
|
||||
{
|
||||
|
|
@ -2784,7 +2797,12 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus, BOOL restore
|
|||
return;
|
||||
}
|
||||
|
||||
mFrontChildHandle = child->getHandle();
|
||||
if (mFrontChild && !mFrontChild->isDead())
|
||||
{
|
||||
mFrontChild->goneFromFront();
|
||||
}
|
||||
|
||||
mFrontChild = child;
|
||||
|
||||
// *TODO: make this respect floater's mAutoFocus value, instead of
|
||||
// using parameter
|
||||
|
|
@ -3371,6 +3389,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)
|
||||
|
|
@ -3406,11 +3427,11 @@ void LLFloaterView::syncFloaterTabOrder()
|
|||
LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it);
|
||||
if (gFocusMgr.childHasKeyboardFocus(floaterp))
|
||||
{
|
||||
if (mFrontChildHandle.get() != floaterp)
|
||||
if (mFrontChild != floaterp)
|
||||
{
|
||||
// Grab a list of the top floaters that want to stay on top of the focused floater
|
||||
std::list<LLFloater*> listTop;
|
||||
if (mFrontChildHandle.get() && !mFrontChildHandle.get()->canFocusStealFrontmost())
|
||||
if (mFrontChild && !mFrontChild->canFocusStealFrontmost())
|
||||
{
|
||||
for (LLView* childp : *getChildList())
|
||||
{
|
||||
|
|
@ -3430,7 +3451,7 @@ void LLFloaterView::syncFloaterTabOrder()
|
|||
{
|
||||
sendChildToFront(childp);
|
||||
}
|
||||
mFrontChildHandle = listTop.back()->getHandle();
|
||||
mFrontChild = listTop.back();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3526,6 +3547,14 @@ void LLFloaterView::setToolbarRect(LLToolBarEnums::EToolBarLocation tb, const LL
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterView::onDestroyFloater(LLFloater* floater)
|
||||
{
|
||||
if (mFrontChild == floater)
|
||||
{
|
||||
mFrontChild = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
void LLFloaterView::setMainChatbarRect(LLLayoutPanel* panel, const LLRect& chatbar_rect)
|
||||
{
|
||||
|
|
@ -3650,6 +3679,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
|
|||
mDefaultRelativeY = p.rel_y;
|
||||
|
||||
mPositioning = p.positioning;
|
||||
mAutoClose = p.auto_close;
|
||||
|
||||
mHostedFloaterShowtitlebar = p.hosted_floater_show_titlebar; // <FS:Ansariel> MultiFloater without titlebar for hosted floater
|
||||
|
||||
|
|
|
|||
|
|
@ -168,7 +168,8 @@ public:
|
|||
save_visibility,
|
||||
save_dock_state,
|
||||
can_dock,
|
||||
show_title;
|
||||
show_title,
|
||||
auto_close;
|
||||
|
||||
Optional<LLFloaterEnums::EOpenPositioning> positioning;
|
||||
|
||||
|
|
@ -411,6 +412,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; }
|
||||
|
|
@ -515,6 +517,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;
|
||||
BOOL mCanSnooze; // <FS:Ansariel> FIRE-11724: Snooze group chat
|
||||
|
||||
LLFloaterEnums::EOpenPositioning mPositioning;
|
||||
|
|
@ -642,6 +645,7 @@ public:
|
|||
// </FS:KC> Fix for bad edge snapping
|
||||
|
||||
void setToolbarRect(LLToolBarEnums::EToolBarLocation tb, const LLRect& toolbar_rect);
|
||||
void onDestroyFloater(LLFloater* floater);
|
||||
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
void setMainChatbarRect(LLLayoutPanel* panel, const LLRect& chatbar_rect);
|
||||
|
|
@ -666,7 +670,7 @@ private:
|
|||
S32 mMinimizePositionVOffset;
|
||||
typedef std::vector<std::pair<LLHandle<LLFloater>, boost::signals2::connection> > hidden_floaters_t;
|
||||
hidden_floaters_t mHiddenFloaters;
|
||||
LLHandle<LLFloater> mFrontChildHandle;
|
||||
LLFloater * mFrontChild;
|
||||
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
LLRect mMainChatbarRect;
|
||||
|
|
|
|||
|
|
@ -959,7 +959,7 @@ void LLFolderViewItem::drawLabel(const LLFontGL * font, const F32 x, const F32 y
|
|||
//
|
||||
font->renderUTF8(mLabel, 0, x, y, color,
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
S32_MAX, getRect().getWidth() - (S32) x - mLabelPaddingRight, &right_x, /*use_ellipses*/TRUE, /*use_color*/FALSE);
|
||||
S32_MAX, getRect().getWidth() - (S32) x - mLabelPaddingRight, &right_x, /*use_ellipses*/TRUE);
|
||||
}
|
||||
|
||||
void LLFolderViewItem::draw()
|
||||
|
|
@ -1090,7 +1090,7 @@ void LLFolderViewItem::draw()
|
|||
{
|
||||
suffix_font->renderUTF8( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : (LLColor4)sSuffixColor,
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
S32_MAX, S32_MAX, &right_x, /*use_ellipses*/FALSE, /*use_color*/FALSE );
|
||||
S32_MAX, S32_MAX, &right_x);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------//
|
||||
|
|
@ -1104,7 +1104,7 @@ void LLFolderViewItem::draw()
|
|||
F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
|
||||
font->renderUTF8(combined_string, filter_offset, match_string_left, yy,
|
||||
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
filter_string_length, S32_MAX, &right_x, FALSE, FALSE);
|
||||
filter_string_length, S32_MAX, &right_x);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1115,7 +1115,7 @@ void LLFolderViewItem::draw()
|
|||
F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
|
||||
font->renderUTF8(mLabel, filter_offset, match_string_left, yy,
|
||||
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
label_filter_length, S32_MAX, &right_x, FALSE, FALSE);
|
||||
label_filter_length, S32_MAX, &right_x);
|
||||
}
|
||||
|
||||
S32 suffix_filter_length = label_filter_length > 0 ? filter_string_length - label_filter_length : filter_string_length;
|
||||
|
|
@ -1126,7 +1126,7 @@ void LLFolderViewItem::draw()
|
|||
F32 yy = (F32)getRect().getHeight() - suffix_font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
|
||||
suffix_font->renderUTF8(mLabelSuffix, suffix_offset, match_string_left, yy, sFilterTextColor,
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
suffix_filter_length, S32_MAX, &right_x, FALSE, FALSE);
|
||||
suffix_filter_length, S32_MAX, &right_x);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2190,7 +2190,7 @@ void LLLineEditor::draw()
|
|||
LLFontGL::NO_SHADOW,
|
||||
S32_MAX,
|
||||
mTextRightEdge - ll_round(rendered_pixels_right),
|
||||
&rendered_pixels_right, FALSE);
|
||||
&rendered_pixels_right);
|
||||
}
|
||||
// Draw children (border)
|
||||
LLView::draw();
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ LLTextBase::Params::Params()
|
|||
trusted_content("trusted_content", true),
|
||||
always_show_icons("always_show_icons", false),
|
||||
use_ellipses("use_ellipses", false),
|
||||
use_color("use_color", false),
|
||||
use_color("use_color", true),
|
||||
// <FS:Ansariel> Optional icon position
|
||||
icon_positioning("icon_positioning", LLTextBaseEnums::RIGHT),
|
||||
// </FS:Ansariel> Optional icon position
|
||||
|
|
|
|||
|
|
@ -558,7 +558,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);
|
||||
|
|
@ -1282,6 +1283,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)
|
||||
|
|
@ -1297,6 +1308,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)
|
||||
|
|
@ -2096,7 +2111,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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,6 +216,7 @@ public:
|
|||
void setShowContextMenu(bool show) { mShowContextMenu = show; }
|
||||
bool getShowContextMenu() const { return mShowContextMenu; }
|
||||
|
||||
void showEmojiHelper();
|
||||
void setShowEmojiHelper(bool show);
|
||||
bool getShowEmojiHelper() const { return mShowEmojiHelper; }
|
||||
|
||||
|
|
|
|||
|
|
@ -798,25 +798,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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1392,8 +1392,7 @@ void LLView::drawDebugRect()
|
|||
std::string debug_text = llformat("%s (%d x %d)", getName().c_str(),
|
||||
debug_rect.getWidth(), debug_rect.getHeight());
|
||||
LLFontGL::getFontSansSerifSmall()->renderUTF8(debug_text, 0, (F32)x, (F32)y, border_color,
|
||||
LLFontGL::HCENTER, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
LLFontGL::HCENTER, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW);
|
||||
}
|
||||
}
|
||||
LLUI::popMatrix();
|
||||
|
|
|
|||
|
|
@ -746,33 +746,49 @@ attributedStringInfo getSegments(NSAttributedString *str)
|
|||
// SL-19801 Special workaround for system emoji picker
|
||||
if ([aString length] == 2)
|
||||
{
|
||||
uint32_t b0 = [aString characterAtIndex:0];
|
||||
uint32_t b1 = [aString characterAtIndex:1];
|
||||
if (((b0 & 0xF000) == 0xD000) && ((b1 & 0xF000) == 0xD000))
|
||||
{
|
||||
uint32_t b = 0x10000 | ((b0 & 0x3F) << 10) | (b1 & 0x3FF);
|
||||
callUnicodeCallback(b, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mHasMarkedText)
|
||||
{
|
||||
for (NSInteger i = 0; i < [aString length]; i++)
|
||||
{
|
||||
callUnicodeCallback([aString characterAtIndex:i], mModifiers);
|
||||
}
|
||||
} else {
|
||||
resetPreedit();
|
||||
// We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text.
|
||||
// But just in case...
|
||||
|
||||
for (NSInteger i = 0; i < [aString length]; i++)
|
||||
{
|
||||
handleUnicodeCharacter([aString characterAtIndex:i]);
|
||||
}
|
||||
mHasMarkedText = FALSE;
|
||||
@try
|
||||
{
|
||||
uint32_t b0 = [aString characterAtIndex:0];
|
||||
uint32_t b1 = [aString characterAtIndex:1];
|
||||
if (((b0 & 0xF000) == 0xD000) && ((b1 & 0xF000) == 0xD000))
|
||||
{
|
||||
uint32_t b = 0x10000 | ((b0 & 0x3F) << 10) | (b1 & 0x3FF);
|
||||
callUnicodeCallback(b, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@catch(NSException * e)
|
||||
{
|
||||
// One of the characters is an attribute string?
|
||||
NSLog(@"Encountered an unsupported attributed character. Exception: %@ String: %@", e.name, aString);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@try
|
||||
{
|
||||
if (!mHasMarkedText)
|
||||
{
|
||||
for (NSInteger i = 0; i < [aString length]; i++)
|
||||
{
|
||||
callUnicodeCallback([aString characterAtIndex:i], mModifiers);
|
||||
}
|
||||
} else {
|
||||
resetPreedit();
|
||||
// We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text.
|
||||
// But just in case...
|
||||
|
||||
for (NSInteger i = 0; i < [aString length]; i++)
|
||||
{
|
||||
handleUnicodeCharacter([aString characterAtIndex:i]);
|
||||
}
|
||||
mHasMarkedText = FALSE;
|
||||
}
|
||||
}
|
||||
@catch(NSException * e)
|
||||
{
|
||||
NSLog(@"Failed to process an attributed string. Exception: %@ String: %@", e.name, aString);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) insertNewline:(id)sender
|
||||
|
|
|
|||
|
|
@ -536,8 +536,8 @@ void FSCommon::updateUsedEmojis(LLWString text)
|
|||
}
|
||||
}
|
||||
|
||||
if (emojiSent)
|
||||
{
|
||||
LLFloaterEmojiPicker::onRecentlyUsedChanged();
|
||||
}
|
||||
if (!emojiSent)
|
||||
return;
|
||||
|
||||
LLFloaterEmojiPicker::saveState();
|
||||
}
|
||||
|
|
@ -959,7 +959,7 @@ BOOL FSFloaterIM::postBuild()
|
|||
mInputEditor->setCommitCallback(boost::bind(&FSFloaterIM::sendMsgFromInputEditor, this, CHAT_TYPE_NORMAL));
|
||||
|
||||
mEmojiRecentPanelToggleBtn = getChild<LLButton>("emoji_recent_panel_toggle_btn");
|
||||
mEmojiRecentPanelToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiRecentPanelToggleBtnClicked(this); });
|
||||
mEmojiRecentPanelToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiRecentPanelToggleBtnClicked(); });
|
||||
|
||||
mEmojiRecentPanel = getChild<LLLayoutPanel>("emoji_recent_layout_panel");
|
||||
mEmojiRecentPanel->setVisible(false);
|
||||
|
|
@ -974,9 +974,9 @@ BOOL FSFloaterIM::postBuild()
|
|||
|
||||
mEmojiPickerToggleBtn = getChild<LLButton>("emoji_picker_toggle_btn");
|
||||
mEmojiPickerToggleBtn->setLabel(LLUIString(LLWString(1, 128512)));
|
||||
mEmojiPickerToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerToggleBtnClicked(this); });
|
||||
mEmojiPickerToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerToggleBtnClicked(); });
|
||||
|
||||
mRecentEmojisUpdatedCallbackConnection = LLFloaterEmojiPicker::setRecentEmojisUpdatedCallback([this](const std::list<llwchar>& recent_emojis_list) { initEmojiRecentPanel(false); });
|
||||
mRecentEmojisUpdatedCallbackConnection = LLFloaterEmojiPicker::setRecentEmojisUpdatedCallback([this](const std::list<llwchar>& recent_emojis_list) { initEmojiRecentPanel(); });
|
||||
|
||||
getChild<LLButton>("send_chat")->setCommitCallback(boost::bind(&FSFloaterIM::sendMsgFromInputEditor, this, CHAT_TYPE_NORMAL));
|
||||
getChild<LLButton>("chat_search_btn")->setCommitCallback(boost::bind(&FSFloaterIM::onChatSearchButtonClicked, this));
|
||||
|
|
@ -2472,26 +2472,19 @@ bool FSFloaterIM::applyRectControl()
|
|||
return res;
|
||||
}
|
||||
|
||||
void FSFloaterIM::onEmojiRecentPanelToggleBtnClicked(FSFloaterIM* self)
|
||||
void FSFloaterIM::onEmojiRecentPanelToggleBtnClicked()
|
||||
{
|
||||
bool show = !self->mEmojiRecentPanel->getVisible();
|
||||
bool restore_focus = !show || (gFocusMgr.getLastKeyboardFocus() == self->mInputEditor);
|
||||
|
||||
BOOL show = mEmojiRecentPanel->getVisible() ? FALSE : TRUE;
|
||||
if (show)
|
||||
{
|
||||
self->initEmojiRecentPanel(!restore_focus);
|
||||
initEmojiRecentPanel();
|
||||
}
|
||||
|
||||
self->mEmojiRecentPanel->setVisible(show ? TRUE : FALSE);
|
||||
self->mEmojiRecentPanelToggleBtn->setImageOverlay(show ? "Arrow_Up" : "Arrow_Down");
|
||||
|
||||
if (restore_focus)
|
||||
{
|
||||
self->mInputEditor->setFocus(true);
|
||||
}
|
||||
mEmojiRecentPanel->setVisible(show);
|
||||
mInputEditor->setFocus(TRUE);
|
||||
}
|
||||
|
||||
void FSFloaterIM::initEmojiRecentPanel(bool moveFocus)
|
||||
void FSFloaterIM::initEmojiRecentPanel()
|
||||
{
|
||||
std::list<llwchar>& recentlyUsed = LLFloaterEmojiPicker::getRecentlyUsed();
|
||||
if (recentlyUsed.empty())
|
||||
|
|
@ -2509,10 +2502,6 @@ void FSFloaterIM::initEmojiRecentPanel(bool moveFocus)
|
|||
mEmojiRecentIconsCtrl->setEmojis(emojis);
|
||||
mEmojiRecentEmptyText->setVisible(FALSE);
|
||||
mEmojiRecentIconsCtrl->setVisible(TRUE);
|
||||
if (moveFocus)
|
||||
{
|
||||
mEmojiRecentIconsCtrl->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2525,44 +2514,12 @@ void FSFloaterIM::onRecentEmojiPicked(const LLSD& value)
|
|||
if (wstr.size())
|
||||
{
|
||||
llwchar emoji = wstr[0];
|
||||
onEmojiPicked(emoji);
|
||||
mInputEditor->insertEmoji(emoji);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FSFloaterIM::onEmojiPickerToggleBtnClicked(FSFloaterIM* self)
|
||||
void FSFloaterIM::onEmojiPickerToggleBtnClicked()
|
||||
{
|
||||
if (LLFloaterEmojiPicker* picker = LLFloaterEmojiPicker::getInstance())
|
||||
{
|
||||
if (!picker->isShown() || (picker->isDependent() && picker->getDependee() && picker->getDependee() != self && picker->getDependee() != self->getHost()))
|
||||
{
|
||||
picker->show(
|
||||
[self](llwchar emoji) { self->onEmojiPicked(emoji); },
|
||||
[self]() { self->onEmojiPickerClosed(); });
|
||||
|
||||
if (self->getHost())
|
||||
{
|
||||
self->getHost()->addDependentFloater(picker, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->addDependentFloater(picker, TRUE, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
picker->closeFloater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FSFloaterIM::onEmojiPicked(llwchar emoji)
|
||||
{
|
||||
mInputEditor->insertEmoji(emoji);
|
||||
mInputEditor->setFocus(TRUE);
|
||||
}
|
||||
|
||||
void FSFloaterIM::onEmojiPickerClosed()
|
||||
{
|
||||
mInputEditor->setFocus(TRUE);
|
||||
mInputEditor->showEmojiHelper();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ public:
|
|||
|
||||
void timedUpdate();
|
||||
|
||||
static void onEmojiPickerToggleBtnClicked(FSFloaterIM* self);
|
||||
void onEmojiPickerToggleBtnClicked();
|
||||
|
||||
protected:
|
||||
/* virtual */
|
||||
|
|
@ -241,11 +241,9 @@ private:
|
|||
bool onChatOptionsVisibleContextMenuItem(const LLSD& userdata);
|
||||
bool onChatOptionsEnableContextMenuItem(const LLSD& userdata);
|
||||
|
||||
static void onEmojiRecentPanelToggleBtnClicked(FSFloaterIM* self);
|
||||
void initEmojiRecentPanel(bool moveFocus);
|
||||
void onEmojiRecentPanelToggleBtnClicked();
|
||||
void initEmojiRecentPanel();
|
||||
void onRecentEmojiPicked(const LLSD& value);
|
||||
void onEmojiPicked(llwchar emoji);
|
||||
void onEmojiPickerClosed();
|
||||
|
||||
FSPanelChatControlPanel* mControlPanel;
|
||||
LLUUID mSessionID;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include "llfloaterreg.h"
|
||||
#include "llchiclet.h"
|
||||
#include "llchicletbar.h"
|
||||
#include "llfloateremojipicker.h"
|
||||
#include "llemojihelper.h"
|
||||
#include "lltoolbarview.h"
|
||||
#include "llvoiceclient.h"
|
||||
|
||||
|
|
@ -583,8 +583,6 @@ void FSFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const
|
|||
|
||||
void FSFloaterIMContainer::tabOpen(LLFloater* opened_floater, bool from_click)
|
||||
{
|
||||
auto picker = LLFloaterEmojiPicker::getInstance();
|
||||
if (picker && picker->isShown() && picker->isDependent() && (picker->getDependee() == this || picker->getDependee() == opened_floater))
|
||||
picker->closeFloater();
|
||||
LLEmojiHelper::instance().hideHelper(nullptr, true);
|
||||
}
|
||||
// EOF
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ BOOL FSFloaterNearbyChat::postBuild()
|
|||
mInputEditorPad = mChatLayoutPanelHeight - mInputEditor->getRect().getHeight();
|
||||
|
||||
mEmojiRecentPanelToggleBtn = getChild<LLButton>("emoji_recent_panel_toggle_btn");
|
||||
mEmojiRecentPanelToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiRecentPanelToggleBtnClicked(this); });
|
||||
mEmojiRecentPanelToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiRecentPanelToggleBtnClicked(); });
|
||||
|
||||
mEmojiRecentPanel = getChild<LLLayoutPanel>("emoji_recent_layout_panel");
|
||||
mEmojiRecentPanel->setVisible(false);
|
||||
|
|
@ -163,9 +163,9 @@ BOOL FSFloaterNearbyChat::postBuild()
|
|||
|
||||
mEmojiPickerToggleBtn = getChild<LLButton>("emoji_picker_toggle_btn");
|
||||
mEmojiPickerToggleBtn->setLabel(LLUIString(LLWString(1, 128512)));
|
||||
mEmojiPickerToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerToggleBtnClicked(this); });
|
||||
mEmojiPickerToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerToggleBtnClicked(); });
|
||||
|
||||
mRecentEmojisUpdatedCallbackConnection = LLFloaterEmojiPicker::setRecentEmojisUpdatedCallback([this](const std::list<llwchar>& recent_emojis_list) { initEmojiRecentPanel(false); });
|
||||
mRecentEmojisUpdatedCallbackConnection = LLFloaterEmojiPicker::setRecentEmojisUpdatedCallback([this](const std::list<llwchar>& recent_emojis_list) { initEmojiRecentPanel(); });
|
||||
|
||||
getChild<LLButton>("chat_history_btn")->setCommitCallback(boost::bind(&FSFloaterNearbyChat::onHistoryButtonClicked, this));
|
||||
getChild<LLButton>("chat_search_btn")->setCommitCallback(boost::bind(&FSFloaterNearbyChat::onSearchButtonClicked, this));
|
||||
|
|
@ -970,26 +970,19 @@ void FSFloaterNearbyChat::handleMinimized(bool minimized)
|
|||
}
|
||||
}
|
||||
|
||||
void FSFloaterNearbyChat::onEmojiRecentPanelToggleBtnClicked(FSFloaterNearbyChat* self)
|
||||
void FSFloaterNearbyChat::onEmojiRecentPanelToggleBtnClicked()
|
||||
{
|
||||
bool show = !self->mEmojiRecentPanel->getVisible();
|
||||
bool restore_focus = !show || (gFocusMgr.getLastKeyboardFocus() == self->mInputEditor);
|
||||
|
||||
BOOL show = mEmojiRecentPanel->getVisible() ? FALSE : TRUE;
|
||||
if (show)
|
||||
{
|
||||
self->initEmojiRecentPanel(!restore_focus);
|
||||
initEmojiRecentPanel();
|
||||
}
|
||||
|
||||
self->mEmojiRecentPanel->setVisible(show ? TRUE : FALSE);
|
||||
self->mEmojiRecentPanelToggleBtn->setImageOverlay(show ? "Arrow_Up" : "Arrow_Down");
|
||||
|
||||
if (restore_focus)
|
||||
{
|
||||
self->mInputEditor->setFocus(true);
|
||||
}
|
||||
mEmojiRecentPanel->setVisible(show);
|
||||
mInputEditor->setFocus(TRUE);
|
||||
}
|
||||
|
||||
void FSFloaterNearbyChat::initEmojiRecentPanel(bool moveFocus)
|
||||
void FSFloaterNearbyChat::initEmojiRecentPanel()
|
||||
{
|
||||
std::list<llwchar>& recentlyUsed = LLFloaterEmojiPicker::getRecentlyUsed();
|
||||
if (recentlyUsed.empty())
|
||||
|
|
@ -1007,10 +1000,6 @@ void FSFloaterNearbyChat::initEmojiRecentPanel(bool moveFocus)
|
|||
mEmojiRecentIconsCtrl->setEmojis(emojis);
|
||||
mEmojiRecentEmptyText->setVisible(FALSE);
|
||||
mEmojiRecentIconsCtrl->setVisible(TRUE);
|
||||
if (moveFocus)
|
||||
{
|
||||
mEmojiRecentIconsCtrl->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1023,44 +1012,12 @@ void FSFloaterNearbyChat::onRecentEmojiPicked(const LLSD& value)
|
|||
if (wstr.size())
|
||||
{
|
||||
llwchar emoji = wstr[0];
|
||||
onEmojiPicked(emoji);
|
||||
mInputEditor->insertEmoji(emoji);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FSFloaterNearbyChat::onEmojiPickerToggleBtnClicked(FSFloaterNearbyChat* self)
|
||||
void FSFloaterNearbyChat::onEmojiPickerToggleBtnClicked()
|
||||
{
|
||||
if (LLFloaterEmojiPicker* picker = LLFloaterEmojiPicker::getInstance())
|
||||
{
|
||||
if (!picker->isShown() || (picker->isDependent() && picker->getDependee() && picker->getDependee() != self && picker->getDependee() != self->getHost()))
|
||||
{
|
||||
picker->show(
|
||||
[self](llwchar emoji) { self->onEmojiPicked(emoji); },
|
||||
[self]() { self->onEmojiPickerClosed(); });
|
||||
|
||||
if (self->getHost())
|
||||
{
|
||||
self->getHost()->addDependentFloater(picker, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->addDependentFloater(picker, TRUE, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
picker->closeFloater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FSFloaterNearbyChat::onEmojiPicked(llwchar emoji)
|
||||
{
|
||||
mInputEditor->insertEmoji(emoji);
|
||||
mInputEditor->setFocus(TRUE);
|
||||
}
|
||||
|
||||
void FSFloaterNearbyChat::onEmojiPickerClosed()
|
||||
{
|
||||
mInputEditor->setFocus(TRUE);
|
||||
mInputEditor->showEmojiHelper();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ public:
|
|||
|
||||
void handleMinimized(bool minimized);
|
||||
|
||||
static void onEmojiPickerToggleBtnClicked(FSFloaterNearbyChat* self);
|
||||
void onEmojiPickerToggleBtnClicked();
|
||||
|
||||
protected:
|
||||
void onChatBoxKeystroke();
|
||||
|
|
@ -123,11 +123,9 @@ private:
|
|||
bool onChatOptionsVisibleContextMenuItem(const LLSD& userdata);
|
||||
bool onChatOptionsEnableContextMenuItem(const LLSD& userdata);
|
||||
|
||||
static void onEmojiRecentPanelToggleBtnClicked(FSFloaterNearbyChat* self);
|
||||
void initEmojiRecentPanel(bool moveFocus);
|
||||
void onEmojiRecentPanelToggleBtnClicked();
|
||||
void initEmojiRecentPanel();
|
||||
void onRecentEmojiPicked(const LLSD& value);
|
||||
void onEmojiPicked(llwchar emoji);
|
||||
void onEmojiPickerClosed();
|
||||
|
||||
FSChatHistory* mChatHistory;
|
||||
FSChatHistory* mChatHistoryMuted;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -29,7 +29,10 @@
|
|||
|
||||
#include "llfloater.h"
|
||||
|
||||
class LLEmojiGridRow;
|
||||
class LLEmojiGridIcon;
|
||||
struct LLEmojiDescriptor;
|
||||
struct LLEmojiSearchResult;
|
||||
|
||||
class LLFloaterEmojiPicker : public LLFloater
|
||||
{
|
||||
|
|
@ -40,23 +43,17 @@ public:
|
|||
typedef boost::function<void (llwchar)> pick_callback_t;
|
||||
typedef boost::function<void ()> close_callback_t;
|
||||
|
||||
// Call this to select an emoji.
|
||||
static LLFloaterEmojiPicker* getInstance();
|
||||
static LLFloaterEmojiPicker* showInstance(pick_callback_t pick_callback = nullptr, close_callback_t close_callback = nullptr);
|
||||
|
||||
LLFloaterEmojiPicker(const LLSD& key);
|
||||
virtual ~LLFloaterEmojiPicker();
|
||||
|
||||
virtual BOOL postBuild() override;
|
||||
virtual void dirtyRect() override;
|
||||
virtual void goneFromFront() override;
|
||||
|
||||
void show(pick_callback_t pick_callback = nullptr, close_callback_t close_callback = nullptr);
|
||||
|
||||
virtual void closeFloater(bool app_quitting = false) override;
|
||||
void hideFloater() const;
|
||||
|
||||
static std::list<llwchar>& getRecentlyUsed();
|
||||
static void onEmojiUsed(llwchar emoji);
|
||||
static void onRecentlyUsedChanged();
|
||||
|
||||
static void loadState();
|
||||
static void saveState();
|
||||
|
||||
|
|
@ -69,15 +66,25 @@ public:
|
|||
// </FS:Ansariel>
|
||||
|
||||
private:
|
||||
void initialize();
|
||||
void fillGroups();
|
||||
void moveGroups();
|
||||
void showPreview(bool show);
|
||||
void fillCategoryRecentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats);
|
||||
void fillCategoryFrequentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats);
|
||||
void fillGroupEmojis(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats, U32 index);
|
||||
void createGroupButton(LLButton::Params& params, const LLRect& rect, llwchar emoji);
|
||||
void resizeGroupButtons();
|
||||
void selectEmojiGroup(U32 index);
|
||||
void fillEmojis(bool fromResize = false);
|
||||
void fillEmojisCategory(const std::vector<LLEmojiSearchResult>& emojis,
|
||||
const std::string& category, const LLPanel::Params& row_panel_params, const LLUICtrl::Params& row_list_params,
|
||||
const LLPanel::Params& icon_params, const LLRect& icon_rect, S32 max_icons, const LLColor4& bg);
|
||||
void createEmojiIcon(const LLEmojiSearchResult& emoji,
|
||||
const std::string& category, const LLPanel::Params& row_panel_params, const LLUICtrl::Params& row_list_params,
|
||||
const LLPanel::Params& icon_params, const LLRect& icon_rect, S32 max_icons, const LLColor4& bg,
|
||||
LLEmojiGridRow*& row, int& icon_index);
|
||||
void showPreview(bool show);
|
||||
|
||||
void onGroupButtonClick(LLUICtrl* ctrl);
|
||||
void onFilterChanged();
|
||||
void onGridMouseEnter();
|
||||
void onGridMouseLeave();
|
||||
void onGroupButtonMouseEnter(LLUICtrl* ctrl);
|
||||
void onGroupButtonMouseLeave(LLUICtrl* ctrl);
|
||||
void onEmojiMouseEnter(LLUICtrl* ctrl);
|
||||
|
|
@ -85,40 +92,37 @@ private:
|
|||
void onEmojiMouseDown(LLUICtrl* ctrl);
|
||||
void onEmojiMouseUp(LLUICtrl* ctrl);
|
||||
|
||||
bool enterArrowMode();
|
||||
void exitArrowMode();
|
||||
void selectFocusedIcon();
|
||||
bool moveFocusedIconUp();
|
||||
bool moveFocusedIconDown();
|
||||
bool moveFocusedIconLeft();
|
||||
bool moveFocusedIconRight();
|
||||
bool moveFocusedIconPrev();
|
||||
bool moveFocusedIconNext();
|
||||
|
||||
void selectGridIcon(LLUICtrl* ctrl);
|
||||
void unselectGridIcon(LLUICtrl* ctrl);
|
||||
void selectGridIcon(LLEmojiGridIcon* icon);
|
||||
void unselectGridIcon(LLEmojiGridIcon* icon);
|
||||
|
||||
void onOpen(const LLSD& key) override;
|
||||
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent) override;
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask) override;
|
||||
|
||||
class LLPanel* mGroups { nullptr };
|
||||
class LLPanel* mBadge { nullptr };
|
||||
class LLFilterEditor* mFilter { nullptr };
|
||||
class LLScrollContainer* mEmojiScroll { nullptr };
|
||||
class LLScrollingPanelList* mEmojiGrid { nullptr };
|
||||
class LLEmojiPreviewPanel* mPreview { nullptr };
|
||||
class LLTextBox* mDummy { nullptr };
|
||||
|
||||
pick_callback_t mEmojiPickCallback;
|
||||
close_callback_t mFloaterCloseCallback;
|
||||
|
||||
std::vector<S32> mFilteredEmojiGroups;
|
||||
std::vector<std::map<std::string, std::vector<LLEmojiSearchResult>>> mFilteredEmojis;
|
||||
std::vector<class LLButton*> mGroupButtons;
|
||||
|
||||
S32 mRecentBadgeWidth { 0 };
|
||||
S32 mRecentGridWidth { 0 };
|
||||
std::string mHint;
|
||||
std::string mFilterPattern;
|
||||
U32 mSelectedGroupIndex { 0 };
|
||||
S32 mRecentMaxIcons { 0 };
|
||||
S32 mFocusedIconRow { 0 };
|
||||
S32 mFocusedIconCol { 0 };
|
||||
LLUICtrl* mFocusedIcon { nullptr };
|
||||
LLUICtrl* mHoveredIcon { nullptr };
|
||||
LLEmojiGridIcon* mFocusedIcon { nullptr };
|
||||
LLEmojiGridIcon* mHoveredIcon { nullptr };
|
||||
|
||||
U64 mRecentReturnPressedMs { 0 };
|
||||
|
||||
// <FS:Ansariel> Live-update recently used emojis
|
||||
static recent_emojis_updated_callback_t sRecentEmojisUpdatedCallback;
|
||||
|
|
|
|||
|
|
@ -260,8 +260,7 @@ BOOL LLFloaterIMSessionTab::postBuild()
|
|||
mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this));
|
||||
|
||||
mEmojiRecentPanelToggleBtn = getChild<LLButton>("emoji_recent_panel_toggle_btn");
|
||||
mEmojiRecentPanelToggleBtn->setLabel(LLUIString(LLWString(1, 128512)));
|
||||
mEmojiRecentPanelToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiRecentPanelToggleBtnClicked(this); });
|
||||
mEmojiRecentPanelToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiRecentPanelToggleBtnClicked(); });
|
||||
|
||||
mEmojiRecentPanel = getChild<LLLayoutPanel>("emoji_recent_layout_panel");
|
||||
mEmojiRecentPanel->setVisible(false);
|
||||
|
|
@ -274,8 +273,8 @@ BOOL LLFloaterIMSessionTab::postBuild()
|
|||
mEmojiRecentIconsCtrl->setCommitCallback([this](LLUICtrl*, const LLSD& value) { onRecentEmojiPicked(value); });
|
||||
mEmojiRecentIconsCtrl->setVisible(false);
|
||||
|
||||
mEmojiPickerToggleBtn = getChild<LLButton>("emoji_picker_toggle_btn");
|
||||
mEmojiPickerToggleBtn->setClickedCallback([](LLUICtrl*, const LLSD&) { onEmojiPickerToggleBtnClicked(); });
|
||||
mEmojiPickerShowBtn = getChild<LLButton>("emoji_picker_show_btn");
|
||||
mEmojiPickerShowBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerShowBtnClicked(); });
|
||||
|
||||
mGearBtn = getChild<LLButton>("gear_btn");
|
||||
mAddBtn = getChild<LLButton>("add_btn");
|
||||
|
|
@ -454,56 +453,30 @@ void LLFloaterIMSessionTab::onInputEditorClicked()
|
|||
gToolBarView->flashCommand(LLCommandId("chat"), false);
|
||||
}
|
||||
|
||||
void LLFloaterIMSessionTab::onEmojiRecentPanelToggleBtnClicked(LLFloaterIMSessionTab* self)
|
||||
void LLFloaterIMSessionTab::onEmojiRecentPanelToggleBtnClicked()
|
||||
{
|
||||
bool show = !self->mEmojiRecentPanel->getVisible();
|
||||
bool restore_focus = !show || (gFocusMgr.getLastKeyboardFocus() == self->mInputEditor);
|
||||
|
||||
BOOL show = mEmojiRecentPanel->getVisible() ? FALSE : TRUE;
|
||||
if (show)
|
||||
{
|
||||
self->initEmojiRecentPanel(!restore_focus);
|
||||
initEmojiRecentPanel();
|
||||
}
|
||||
|
||||
self->mEmojiRecentPanel->setVisible(show ? TRUE : FALSE);
|
||||
|
||||
if (restore_focus)
|
||||
{
|
||||
self->mInputEditor->setFocus(true);
|
||||
}
|
||||
mEmojiRecentPanel->setVisible(show);
|
||||
mInputEditor->setFocus(TRUE);
|
||||
}
|
||||
|
||||
void LLFloaterIMSessionTab::onEmojiPickerToggleBtnClicked()
|
||||
void LLFloaterIMSessionTab::onEmojiPickerShowBtnClicked()
|
||||
{
|
||||
if (LLFloaterEmojiPicker* picker = LLFloaterEmojiPicker::getInstance())
|
||||
{
|
||||
if (!picker->isShown())
|
||||
{
|
||||
picker->show(
|
||||
[](llwchar emoji) { onEmojiPicked(emoji); },
|
||||
[]() { onEmojiPickerClosed(); });
|
||||
if (LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance())
|
||||
{
|
||||
im_box->addDependentFloater(picker, TRUE, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
picker->closeFloater();
|
||||
}
|
||||
}
|
||||
mInputEditor->showEmojiHelper();
|
||||
}
|
||||
|
||||
void LLFloaterIMSessionTab::initEmojiRecentPanel(bool moveFocus)
|
||||
void LLFloaterIMSessionTab::initEmojiRecentPanel()
|
||||
{
|
||||
std::list<llwchar>& recentlyUsed = LLFloaterEmojiPicker::getRecentlyUsed();
|
||||
if (recentlyUsed.empty())
|
||||
{
|
||||
mEmojiRecentEmptyText->setVisible(TRUE);
|
||||
mEmojiRecentIconsCtrl->setVisible(FALSE);
|
||||
if (moveFocus)
|
||||
{
|
||||
mEmojiPickerToggleBtn->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -515,10 +488,6 @@ void LLFloaterIMSessionTab::initEmojiRecentPanel(bool moveFocus)
|
|||
mEmojiRecentIconsCtrl->setEmojis(emojis);
|
||||
mEmojiRecentEmptyText->setVisible(FALSE);
|
||||
mEmojiRecentIconsCtrl->setVisible(TRUE);
|
||||
if (moveFocus)
|
||||
{
|
||||
mEmojiRecentIconsCtrl->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -536,31 +505,6 @@ void LLFloaterIMSessionTab::onRecentEmojiPicked(const LLSD& value)
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterIMSessionTab::onEmojiPicked(llwchar emoji)
|
||||
{
|
||||
if (LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance())
|
||||
{
|
||||
if (LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(im_box->getSelectedSession()))
|
||||
{
|
||||
session_floater->mInputEditor->insertEmoji(emoji);
|
||||
session_floater->mInputEditor->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterIMSessionTab::onEmojiPickerClosed()
|
||||
{
|
||||
if (LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance())
|
||||
{
|
||||
if (LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(im_box->getSelectedSession()))
|
||||
{
|
||||
session_floater->mInputEditor->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterIMSessionTab::closeFloater(bool app_quitting)
|
||||
{
|
||||
LLFloaterEmojiPicker::saveState();
|
||||
|
|
@ -626,11 +570,11 @@ void LLFloaterIMSessionTab::updateUsedEmojis(LLWString text)
|
|||
if (!emojiSent)
|
||||
return;
|
||||
|
||||
LLFloaterEmojiPicker::onRecentlyUsedChanged();
|
||||
LLFloaterEmojiPicker::saveState();
|
||||
|
||||
if (mEmojiRecentPanel->getVisible())
|
||||
{
|
||||
initEmojiRecentPanel(false);
|
||||
initEmojiRecentPanel();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ protected:
|
|||
LLButton* mExpandCollapseBtn;
|
||||
LLButton* mTearOffBtn;
|
||||
LLButton* mEmojiRecentPanelToggleBtn;
|
||||
LLButton* mEmojiPickerToggleBtn;
|
||||
LLButton* mEmojiPickerShowBtn;
|
||||
LLButton* mCloseBtn;
|
||||
LLButton* mGearBtn;
|
||||
LLButton* mAddBtn;
|
||||
|
|
@ -217,12 +217,10 @@ private:
|
|||
|
||||
void onInputEditorClicked();
|
||||
|
||||
static void onEmojiRecentPanelToggleBtnClicked(LLFloaterIMSessionTab* self);
|
||||
static void onEmojiPickerToggleBtnClicked();
|
||||
void initEmojiRecentPanel(bool moveFocus);
|
||||
void onEmojiRecentPanelToggleBtnClicked();
|
||||
void onEmojiPickerShowBtnClicked();
|
||||
void initEmojiRecentPanel();
|
||||
void onRecentEmojiPicked(const LLSD& value);
|
||||
static void onEmojiPicked(llwchar emoji);
|
||||
static void onEmojiPickerClosed();
|
||||
|
||||
bool checkIfTornOff();
|
||||
bool mIsHostAttached;
|
||||
|
|
|
|||
|
|
@ -1632,7 +1632,7 @@ void LLOverlapPanel::draw()
|
|||
LLUI::translate(5,getRect().getHeight()-20); // translate to top-5,left-5
|
||||
LLView::sDrawPreviewHighlights = FALSE;
|
||||
LLFontGL::getFontSansSerifSmall()->renderUTF8(current_selection_text, 0, 0, 0, text_color,
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1650,7 +1650,7 @@ void LLOverlapPanel::draw()
|
|||
std::string current_selection = std::string(current_selection_text + LLView::sPreviewClickedElement->getName() + " (no elements overlap)");
|
||||
S32 text_width = LLFontGL::getFontSansSerifSmall()->getWidth(current_selection) + 10;
|
||||
LLFontGL::getFontSansSerifSmall()->renderUTF8(current_selection, 0, 0, 0, text_color,
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW);
|
||||
// widen panel enough to fit this text
|
||||
LLRect rect = getRect();
|
||||
setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() < text_width ? rect.mLeft + text_width : rect.mRight,rect.mTop));
|
||||
|
|
@ -1716,7 +1716,7 @@ void LLOverlapPanel::draw()
|
|||
// draw currently-selected element at top of overlappers
|
||||
LLUI::translate(0,-mSpacing);
|
||||
LLFontGL::getFontSansSerifSmall()->renderUTF8(current_selection_text + LLView::sPreviewClickedElement->getName(), 0, 0, 0, text_color,
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW);
|
||||
LLUI::translate(0,-mSpacing-LLView::sPreviewClickedElement->getRect().getHeight()); // skip spacing distance + height
|
||||
LLView::sPreviewClickedElement->draw();
|
||||
|
||||
|
|
@ -1731,7 +1731,7 @@ void LLOverlapPanel::draw()
|
|||
// draw name
|
||||
LLUI::translate(0,-mSpacing);
|
||||
LLFontGL::getFontSansSerifSmall()->renderUTF8(overlapper_text + viewp->getName(), 0, 0, 0, text_color,
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW);
|
||||
|
||||
// draw element
|
||||
LLUI::translate(0,-mSpacing-viewp->getRect().getHeight()); // skip spacing distance + height
|
||||
|
|
|
|||
|
|
@ -2231,7 +2231,7 @@ bool LLMaterialEditor::canModifyObjectsMaterial()
|
|||
LLSelectedTEGetMatData func(true);
|
||||
LLPermissions permissions;
|
||||
LLViewerInventoryItem* item_out;
|
||||
return can_use_objects_material(func, std::vector({PERM_MODIFY}), ItemSource::OBJECT, permissions, item_out);
|
||||
return can_use_objects_material(func, std::vector<PermissionBit>({PERM_MODIFY}), ItemSource::OBJECT, permissions, item_out);
|
||||
}
|
||||
|
||||
bool LLMaterialEditor::canSaveObjectsMaterial()
|
||||
|
|
@ -2239,7 +2239,7 @@ bool LLMaterialEditor::canSaveObjectsMaterial()
|
|||
LLSelectedTEGetMatData func(true);
|
||||
LLPermissions permissions;
|
||||
LLViewerInventoryItem* item_out;
|
||||
return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item_out);
|
||||
return can_use_objects_material(func, std::vector<PermissionBit>({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item_out);
|
||||
}
|
||||
|
||||
bool LLMaterialEditor::canClipboardObjectsMaterial()
|
||||
|
|
@ -2265,7 +2265,7 @@ bool LLMaterialEditor::canClipboardObjectsMaterial()
|
|||
LLSelectedTEGetMatData func(true);
|
||||
LLPermissions permissions;
|
||||
LLViewerInventoryItem* item_out;
|
||||
return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY, PERM_TRANSFER}), ItemSource::OBJECT, permissions, item_out);
|
||||
return can_use_objects_material(func, std::vector<PermissionBit>({PERM_COPY, PERM_MODIFY, PERM_TRANSFER}), ItemSource::OBJECT, permissions, item_out);
|
||||
}
|
||||
|
||||
void LLMaterialEditor::saveObjectsMaterialAs()
|
||||
|
|
@ -2273,7 +2273,7 @@ void LLMaterialEditor::saveObjectsMaterialAs()
|
|||
LLSelectedTEGetMatData func(true);
|
||||
LLPermissions permissions;
|
||||
LLViewerInventoryItem* item = nullptr;
|
||||
bool allowed = can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item);
|
||||
bool allowed = can_use_objects_material(func, std::vector<PermissionBit>({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item);
|
||||
if (!allowed)
|
||||
{
|
||||
LL_WARNS("MaterialEditor") << "Failed to save GLTF material from object" << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void LLPanelEmojiComplete::draw()
|
|||
LLWString text(1, mEmojis[curIdx].Character);
|
||||
mIconFont->render(text, 0, iconCenterX, iconCenterY,
|
||||
LLColor4::white, LLFontGL::HCENTER, LLFontGL::VCENTER, LLFontGL::NORMAL,
|
||||
LLFontGL::DROP_SHADOW_SOFT, 1, S32_MAX, nullptr, false, true);
|
||||
LLFontGL::DROP_SHADOW_SOFT, 1);
|
||||
if (mVertical)
|
||||
{
|
||||
const std::string& shortCode = mEmojis[curIdx].String;
|
||||
|
|
@ -129,7 +129,7 @@ void LLPanelEmojiComplete::draw()
|
|||
std::string text = shortCode.substr(0, mEmojis[curIdx].Begin);
|
||||
mTextFont->renderUTF8(text, 0, x0, iconCenterY, LLColor4::white,
|
||||
LLFontGL::LEFT, LLFontGL::VCENTER, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
text.size(), x1, NULL, FALSE, FALSE);
|
||||
text.size(), x1);
|
||||
x0 += mTextFont->getWidthF32(text);
|
||||
x1 = textLeft + textWidth - x0;
|
||||
}
|
||||
|
|
@ -138,7 +138,7 @@ void LLPanelEmojiComplete::draw()
|
|||
std::string text = shortCode.substr(mEmojis[curIdx].Begin, mEmojis[curIdx].End - mEmojis[curIdx].Begin);
|
||||
mTextFont->renderUTF8(text, 0, x0, iconCenterY, LLColor4::yellow6,
|
||||
LLFontGL::LEFT, LLFontGL::VCENTER, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
text.size(), x1, NULL, FALSE, FALSE);
|
||||
text.size(), x1);
|
||||
x0 += mTextFont->getWidthF32(text);
|
||||
x1 = textLeft + textWidth - x0;
|
||||
}
|
||||
|
|
@ -147,7 +147,7 @@ void LLPanelEmojiComplete::draw()
|
|||
std::string text = shortCode.substr(mEmojis[curIdx].End);
|
||||
mTextFont->renderUTF8(text, 0, x0, iconCenterY, LLColor4::white,
|
||||
LLFontGL::LEFT, LLFontGL::VCENTER, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
text.size(), x1, NULL, FALSE, FALSE);
|
||||
text.size(), x1);
|
||||
}
|
||||
iconCenterY -= mEmojiHeight;
|
||||
}
|
||||
|
|
@ -264,7 +264,11 @@ BOOL LLPanelEmojiComplete::handleScrollWheel(S32 x, S32 y, S32 clicks)
|
|||
|
||||
if (mTotalEmojis > mVisibleEmojis)
|
||||
{
|
||||
mScrollPos = llclamp<size_t>(mScrollPos + clicks, 0, mTotalEmojis - mVisibleEmojis);
|
||||
// In case of wheel up (clicks < 0) we shouldn't subtract more than value of mScrollPos
|
||||
// Example: if mScrollPos = 0, clicks = -1 then (mScrollPos + clicks) becomes SIZE_MAX
|
||||
// As a result of llclamp<size_t>() mScrollPos becomes (mTotalEmojis - mVisibleEmojis)
|
||||
S32 newScrollPos = llmax(0, (S32)mScrollPos + clicks);
|
||||
mScrollPos = llclamp<size_t>((size_t)newScrollPos, 0, mTotalEmojis - mVisibleEmojis);
|
||||
mCurSelected = posToIndex(x, y);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -687,8 +687,7 @@ void LLGLTexMemBar::draw()
|
|||
x_right = 550.0;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP,
|
||||
LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX,
|
||||
&x_right, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &x_right);
|
||||
|
||||
// <FS:Ansariel> Move BW figures further to the right to prevent overlapping
|
||||
left = 575;
|
||||
|
|
|
|||
|
|
@ -1058,8 +1058,7 @@ public:
|
|||
{
|
||||
const Line& line = *iter;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor,
|
||||
LLFontGL::LEFT, LLFontGL::TOP,
|
||||
LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -608,8 +608,7 @@ void LLWorldMapView::draw()
|
|||
S32_MAX, //max_chars
|
||||
mMapScale, //max_pixels
|
||||
NULL,
|
||||
/*use_ellipses*/TRUE,
|
||||
/*use_color*/FALSE);
|
||||
/*use_ellipses*/TRUE);
|
||||
|
||||
if (drawAdvancedRegionInfo)
|
||||
{
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 921 B |
|
|
@ -222,6 +222,7 @@ with the same filename but different name
|
|||
|
||||
<texture name="DropTarget" file_name="widgets/DropTarget.png" preload="false" />
|
||||
|
||||
<texture name="Emoji_Picker_Icon" file_name="icons/emoji_picker_icon.png" preload="true" />
|
||||
<texture name="ExternalBrowser_Off" file_name="icons/ExternalBrowser_Off.png" preload="false" />
|
||||
<texture name="ExternalBrowser_Over" file_name="icons/ExternalBrowser_Over.png" preload="false" />
|
||||
<texture name="ExternalBrowser_Press" file_name="icons/ExternalBrowser_Press.png" preload="false" />
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
<layout_panel name="chat_layout_panel">
|
||||
<layout_stack name="input_panels">
|
||||
<layout_panel name="emoji_button_layout_panel">
|
||||
<button name="emoji_picker_toggle_btn" tool_tip="Emoji-Auswahl öffnen/schliessen"/>
|
||||
<button name="emoji_picker_toggle_btn" tool_tip="Emoji-Auswahl öffnen"/>
|
||||
<button name="emoji_recent_panel_toggle_btn" tool_tip="Zuletzt verwendete Emoji-Auswahl öffnen/schliessen"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="input_button_layout_panel">
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
<chat_editor name="chat_box"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="emoji_button_layout_panel">
|
||||
<button name="emoji_picker_toggle_btn" tool_tip="Emoji-Auswahl öffnen/schliessen"/>
|
||||
<button name="emoji_picker_toggle_btn" tool_tip="Emoji-Auswahl öffnen"/>
|
||||
<button name="emoji_recent_panel_toggle_btn" tool_tip="Zuletzt verwendete Emoji-Auswahl öffnen/schliessen"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="input_button_layout_panel">
|
||||
|
|
|
|||
|
|
@ -3,33 +3,26 @@
|
|||
name="emojipicker"
|
||||
title="Choose Emoji"
|
||||
help_topic="emojipicker"
|
||||
positioning="cascading"
|
||||
legacy_header_height="0"
|
||||
single_instance="true"
|
||||
can_minimize="false"
|
||||
can_tear_off="false"
|
||||
can_resize="true"
|
||||
auto_close="true"
|
||||
layout="topleft"
|
||||
min_width="250"
|
||||
height="400"
|
||||
width="250">
|
||||
chrome="true"
|
||||
height="350"
|
||||
width="304">
|
||||
<floater.string name="title_for_recently_used" value="Recently used"/>
|
||||
<floater.string name="title_for_frequently_used" value="Frequently used"/>
|
||||
<filter_editor
|
||||
name="Filter"
|
||||
label="Start typing to filter"
|
||||
layout="topleft"
|
||||
follows="top|left|right"
|
||||
top="27"
|
||||
left="5"
|
||||
height="23"
|
||||
right="-5" />
|
||||
<scroll_container
|
||||
name="EmojiGridContainer"
|
||||
layout="topleft"
|
||||
follows="all"
|
||||
ignore_arrow_keys="true"
|
||||
top="50"
|
||||
top="25"
|
||||
left="0"
|
||||
height="309"
|
||||
width="250">
|
||||
height="275">
|
||||
<scrolling_panel_list
|
||||
name="EmojiGrid"
|
||||
layout="topleft"
|
||||
|
|
@ -37,8 +30,7 @@
|
|||
padding="4"
|
||||
spacing="0"
|
||||
top="0"
|
||||
left="0"
|
||||
width="250"/>
|
||||
left="0"/>
|
||||
</scroll_container>
|
||||
<panel
|
||||
name="Groups"
|
||||
|
|
@ -46,8 +38,7 @@
|
|||
follows="top|left|right"
|
||||
top="0"
|
||||
left="0"
|
||||
height="25"
|
||||
width="250">
|
||||
height="25">
|
||||
<panel
|
||||
name="Badge"
|
||||
layout="bottomleft"
|
||||
|
|
@ -70,6 +61,5 @@
|
|||
valign="center"
|
||||
bottom="5"
|
||||
left="10"
|
||||
height="23"
|
||||
width="230">No emoji selected</text>
|
||||
height="25">No emoji selected</text>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -667,9 +667,11 @@
|
|||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
image_overlay="Emoji_Picker_Icon"
|
||||
right="-11"
|
||||
name="emoji_picker_toggle_btn"
|
||||
tool_tip="Show/hide emoji panel"
|
||||
tab_stop="false"
|
||||
tool_tip="Show emoji panel"
|
||||
width="24"/>
|
||||
<button
|
||||
follows="right|bottom"
|
||||
|
|
@ -683,6 +685,7 @@
|
|||
image_overlay="Arrow_Down"
|
||||
right="-1"
|
||||
name="emoji_recent_panel_toggle_btn"
|
||||
tab_stop="false"
|
||||
tool_tip="Shows/hides recent emojis"
|
||||
left_pad="0"
|
||||
width="10"/>
|
||||
|
|
@ -728,6 +731,7 @@
|
|||
follows="top|left|right"
|
||||
layout="topleft"
|
||||
max_visible="20"
|
||||
tab_stop="false"
|
||||
top="0"
|
||||
left="5"
|
||||
right="-1"
|
||||
|
|
|
|||
|
|
@ -281,14 +281,15 @@
|
|||
follows="right|bottom"
|
||||
bottom="-1"
|
||||
height="22"
|
||||
use_font_color="true"
|
||||
font="EmojiLarge"
|
||||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
image_overlay="Emoji_Picker_Icon"
|
||||
right="-11"
|
||||
name="emoji_picker_toggle_btn"
|
||||
tool_tip="Show/hide emoji panel"
|
||||
tab_stop="false"
|
||||
tool_tip="Show emoji panel"
|
||||
width="24"/>
|
||||
<button
|
||||
follows="right|bottom"
|
||||
|
|
@ -302,6 +303,7 @@
|
|||
image_overlay="Arrow_Down"
|
||||
right="-1"
|
||||
name="emoji_recent_panel_toggle_btn"
|
||||
tab_stop="false"
|
||||
tool_tip="Shows/hides recent emojis"
|
||||
left_pad="0"
|
||||
width="10"/>
|
||||
|
|
@ -419,6 +421,7 @@
|
|||
follows="top|left|right"
|
||||
layout="topleft"
|
||||
max_visible="20"
|
||||
tab_stop="false"
|
||||
top="0"
|
||||
left="5"
|
||||
right="-1"
|
||||
|
|
|
|||
|
|
@ -304,11 +304,12 @@
|
|||
name="emoji_recent_panel_toggle_btn"
|
||||
tool_tip="Shows/hides recent emojis"
|
||||
follows="right|bottom"
|
||||
use_font_color="true"
|
||||
font="EmojiLarge"
|
||||
tab_stop="false"
|
||||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
image_overlay="Emoji_Picker_Icon"
|
||||
bottom="-2"
|
||||
right="-1"
|
||||
height="25"
|
||||
|
|
@ -353,17 +354,19 @@
|
|||
name="emoji_recent_icons_ctrl"
|
||||
follows="top|left|right"
|
||||
layout="topleft"
|
||||
tab_stop="false"
|
||||
max_visible="20"
|
||||
top="0"
|
||||
left="1"
|
||||
right="-65"
|
||||
height="30"/>
|
||||
<button
|
||||
name="emoji_picker_toggle_btn"
|
||||
name="emoji_picker_show_btn"
|
||||
label="More"
|
||||
tool_tip="Shows/hides emoji picker"
|
||||
follows="right|bottom"
|
||||
layout="topleft"
|
||||
tab_stop="false"
|
||||
bottom="-5"
|
||||
right="-3"
|
||||
height="20"
|
||||
|
|
|
|||
Loading…
Reference in New Issue