# Conflicts:
#	autobuild.xml
#	indra/llcommon/CMakeLists.txt
#	indra/llui/llscrolllistctrl.h
#	indra/newview/CMakeLists.txt
#	indra/newview/llviewerfloaterreg.cpp
#	indra/newview/skins/default/textures/textures.xml
master
Ansariel 2023-04-22 12:02:23 +02:00
commit 719a2d31dc
32 changed files with 721 additions and 11042 deletions

1
.gitignore vendored
View File

@ -57,6 +57,7 @@ indra/newview/teleport_history.txt
indra/newview/typed_locations.txt
indra/newview/vivox-runtime
indra/newview/skins/default/html/common/equirectangular/js
emoji_characters.xml
indra/server-linux-*
indra/temp
indra/test/linden_file.dat

View File

@ -672,9 +672,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>7b4aceaed511d44c4d1354b2162b59c7</string>
<string>878eaf654926e400d67680100cb780c9</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107398/936936/bugsplat-1.0.7.576560-darwin64-576560.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113512/981912/bugsplat-1.0.7.579546-darwin64-579546.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -684,9 +684,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>53918c7c74b943cdc0bb90caf9657a84</string>
<string>5b32c47ae8e8cf0d4106f08e8db18044</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107400/936949/bugsplat-4.0.3.0.576560-windows-576560.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113878/983697/bugsplat-4.0.3.0.579696-windows-579696.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -696,16 +696,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>19d6a55db101f02e7eb531daf3e8cfd1</string>
<string>79c005fd8a660f8551b3c9ede64fa4ef</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107401/936948/bugsplat-.576560-windows64-576560.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113879/983696/bugsplat-4.0.3.0.579696-windows64-579696.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>4.0.3.0.576560</string>
<string>4.0.3.0.579696</string>
</map>
<key>colladadom</key>
<map>
@ -999,6 +999,62 @@
<key>version</key>
<string>1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
</map>
<key>emoji_shortcodes</key>
<map>
<key>canonical_repo</key>
<string>https://github.com/secondlife/3p-emoji-shortcodes</string>
<key>copyright</key>
<string>Copyright 2017-2019 Miles Johnson.</string>
<key>description</key>
<string>Emoji shortcodes</string>
<key>license</key>
<string>MIT</string>
<key>license_file</key>
<string>LICENSES/emojibase-license.txt</string>
<key>name</key>
<string>emoji_shortcodes</string>
<key>platforms</key>
<map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>7ac35da9b1b5c9a05954edeef3fe8e54</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113242/980233/emoji_shortcodes-6.1.0.579438-darwin64-579438.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>3c5c4c7e3bb2eeef61e605b6690a63f3</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113244/980245/emoji_shortcodes-6.1.0.579438-windows-579438.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
<key>windows64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>087ce7e6d93dcd88b477b10d8e1ab259</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113243/980244/emoji_shortcodes-6.1.0.579438-windows64-579438.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>6.1.0.579438</string>
</map>
<key>expat</key>
<map>
<key>copyright</key>
@ -3304,7 +3360,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>viewer-fonts</key>
<map>
<key>copyright</key>
<string>Copyright various</string>
<string>Copyright 2016-2022 Brad Erickson CC-BY-4.0/MIT, Copyright 2016-2022 Twitter, Inc. CC-BY-4.0, Copyright 2013 Joe Loughry and Terence Eden MIT</string>
<key>description</key>
<string>Viewer fonts</string>
<key>license</key>
@ -3320,9 +3376,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>d47e0ed35dad11f0a5dc821758e2ae46</string>
<string>6041bbd4001e3951f96ac3456c7906da</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/109658/953998/viewer_fonts-1.577782-darwin64-577782.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113314/980656/viewer_fonts-1.579464-darwin64-579464.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -3332,9 +3388,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>7dc39bb7cd8133d251eaff9c9e16bdfd</string>
<string>19c48abc168a1c4e0f0ec6d471b2e1bd</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/109660/954010/viewer_fonts-1.577782-windows-577782.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113308/980632/viewer_fonts-1.579464-windows-579464.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -3344,16 +3400,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>86134368c16c7d685156403e15a7cbcd</string>
<string>1745ba6eec0108250446fe01d4aa065c</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/109659/954009/viewer_fonts-1.577782-windows64-577782.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113307/980631/viewer_fonts-1.579464-windows64-579464.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>1.577782</string>
<string>1.579464</string>
</map>
<key>viewer-manager</key>
<map>

View File

@ -239,6 +239,7 @@ Ansariel Hiller
SL-15227
SL-15398
SL-18432
SL-19623
Aralara Rajal
Arare Chantilly
CHUIBUG-191
@ -891,6 +892,7 @@ Kitty Barnett
STORM-2149
MAINT-7581
MAINT-7081
DRTVWR-489 (Internal JIRA that tracks Kitty's sizeable, epic contribution: support for Emoji characters in the Viewer [April 2023])
Kolor Fall
Komiko Okamoto
Korvel Noh

View File

@ -20,3 +20,4 @@ endif()
use_prebuilt_binary(slvoice)
use_prebuilt_binary(nanosvg)
use_prebuilt_binary(viewer-fonts)
use_prebuilt_binary(emoji_shortcodes)

View File

@ -303,7 +303,6 @@ endif(NOT WORD_SIZE EQUAL 32)
target_link_libraries(
llcommon
ll::icu4c
ll::apr
ll::expat
ll::jsoncpp
@ -312,6 +311,7 @@ target_link_libraries(
ll::uriparser
ll::oslibraries
ll::tracy
ll::icu4c
)
target_include_directories(llcommon INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

View File

@ -366,6 +366,7 @@ public:
static void replaceNonstandardASCII( string_type& string, T replacement );
static void replaceChar( string_type& string, T target, T replacement );
static void replaceString( string_type& string, string_type target, string_type replacement );
static void capitalize(string_type& str);
static BOOL containsNonprintable(const string_type& string);
static void stripNonprintable(string_type& string);
@ -1609,6 +1610,20 @@ void LLStringUtilBase<T>::replaceTabsWithSpaces( string_type& str, size_type spa
str = out_str;
}
//static
template<class T>
void LLStringUtilBase<T>::capitalize(string_type& str)
{
if (str.size())
{
auto last = str[0] = toupper(str[0]);
for (U32 i = 1; i < str.size(); ++i)
{
last = (last == ' ' || last == '-' || last == '_') ? str[i] = toupper(str[i]) : str[i];
}
}
}
//static
template<class T>
BOOL LLStringUtilBase<T>::containsNonprintable(const string_type& string)

View File

@ -70,6 +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),
image_unselected("image_unselected"),
image_selected("image_selected"),
image_hover_selected("image_hover_selected"),
@ -167,6 +168,7 @@ LLButton::LLButton(const LLButton::Params& p)
mDropShadowedText(p.label_shadow),
mAutoResize(p.auto_resize),
mUseEllipses( p.use_ellipses ),
mUseFontColor( p.use_font_color),
mHAlign(p.font_halign),
mLeftHPad(p.pad_left),
mRightHPad(p.pad_right),
@ -1026,7 +1028,7 @@ void LLButton::draw()
LLFontGL::NORMAL,
mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NO_SHADOW,
S32_MAX, text_width,
NULL, mUseEllipses);
NULL, mUseEllipses, mUseFontColor);
}
// <FS:Zi> Add checkbox control toggle
@ -1095,6 +1097,16 @@ BOOL LLButton::toggleState()
return flipped;
}
void LLButton::setLabel( const std::string& label )
{
mUnselectedLabel = mSelectedLabel = label;
}
void LLButton::setLabel( const LLUIString& label )
{
mUnselectedLabel = mSelectedLabel = label;
}
void LLButton::setLabel( const LLStringExplicit& label )
{
setLabelUnselected(label);
@ -1126,14 +1138,7 @@ bool LLButton::labelIsTruncated() const
const LLUIString& LLButton::getCurrentLabel() const
{
if( getToggleState() )
{
return mSelectedLabel;
}
else
{
return mUnselectedLabel;
}
return getToggleState() ? mSelectedLabel : mUnselectedLabel;
}
void LLButton::setImageUnselected(LLPointer<LLUIImage> image)

View File

@ -73,6 +73,7 @@ public:
Optional<bool> label_shadow;
Optional<bool> auto_resize;
Optional<bool> use_ellipses;
Optional<bool> use_font_color;
// images
Optional<LLUIImage*> image_unselected,
@ -178,6 +179,7 @@ public:
void setUnselectedLabelColor( const LLColor4& c ) { mUnselectedLabelColor = c; }
void setSelectedLabelColor( const LLColor4& c ) { mSelectedLabelColor = c; }
void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; }
void setUseFontColor( BOOL use_font_color) { mUseFontColor = use_font_color; }
boost::signals2::connection setClickedCallback(const CommitCallbackParam& cb);
@ -248,6 +250,8 @@ public:
void autoResize(); // resize with label of current btn state
void resize(LLUIString label); // resize with label input
void setLabel(const std::string& label);
void setLabel(const LLUIString& label);
void setLabel( const LLStringExplicit& label);
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
void setLabelUnselected(const LLStringExplicit& label);
@ -370,6 +374,7 @@ protected:
bool mDropShadowedText;
bool mAutoResize;
bool mUseEllipses;
bool mUseFontColor;
bool mBorderEnabled;
bool mFlashing;

View File

@ -175,6 +175,12 @@ LLWString LLEmojiDictionary::findMatchingEmojis(const std::string& needle) const
return result;
}
const LLEmojiDescriptor* LLEmojiDictionary::getDescriptorFromEmoji(llwchar emoji) const
{
const auto it = mEmoji2Descr.find(emoji);
return (mEmoji2Descr.end() != it) ? it->second : nullptr;
}
const LLEmojiDescriptor* LLEmojiDictionary::getDescriptorFromShortCode(const std::string& short_code) const
{
const auto it = mShortCode2Descr.find(short_code);
@ -195,6 +201,10 @@ void LLEmojiDictionary::addEmoji(LLEmojiDescriptor&& descr)
{
mShortCode2Descr.insert(std::make_pair(shortCode, &mEmojis.back()));
}
for (const std::string& category : descr.Categories)
{
mCategory2Descrs[category].push_back(&mEmojis.back());
}
}
// ============================================================================

View File

@ -56,18 +56,28 @@ class LLEmojiDictionary : public LLParamSingleton<LLEmojiDictionary>, public LLI
~LLEmojiDictionary() override {};
public:
typedef std::map<llwchar, const LLEmojiDescriptor*> emoji2descr_map_t;
typedef std::map<std::string, const LLEmojiDescriptor*> code2descr_map_t;
typedef std::map<std::string, std::vector<const LLEmojiDescriptor*>> cat2descrs_map_t;
static void initClass();
LLWString findMatchingEmojis(const std::string& needle) const;
const LLEmojiDescriptor* getDescriptorFromEmoji(llwchar emoji) const;
const LLEmojiDescriptor* getDescriptorFromShortCode(const std::string& short_code) const;
std::string getNameFromEmoji(llwchar ch) const;
const emoji2descr_map_t& getEmoji2Descr() const { return mEmoji2Descr; }
const code2descr_map_t& getShortCode2Descr() const { return mShortCode2Descr; }
const cat2descrs_map_t& getCategory2Descrs() const { return mCategory2Descrs; }
private:
void addEmoji(LLEmojiDescriptor&& descr);
private:
std::list<LLEmojiDescriptor> mEmojis;
std::map<llwchar, const LLEmojiDescriptor*> mEmoji2Descr;
std::map<std::string, const LLEmojiDescriptor*> mShortCode2Descr;
emoji2descr_map_t mEmoji2Descr;
code2descr_map_t mShortCode2Descr;
cat2descrs_map_t mCategory2Descrs;
};
// ============================================================================

View File

@ -82,12 +82,12 @@ bool LLEmojiHelper::isCursorInEmojiCode(const LLWString& wtext, S32 cursorPos, S
return isShortCode;
}
void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, const std::string& short_code, std::function<void(LLWString)> cb)
void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, const std::string& short_code, std::function<void(llwchar)> cb)
{
// Commit immediately if the user already typed a full shortcode
if (const auto* emojiDescrp = LLEmojiDictionary::instance().getDescriptorFromShortCode(short_code))
{
cb(LLWString(1, emojiDescrp->Character));
cb(emojiDescrp->Character);
hideHelper();
return;
}
@ -96,7 +96,7 @@ void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, c
{
LLFloater* pHelperFloater = LLFloaterReg::getInstance(DEFAULT_EMOJI_HELPER_FLOATER);
mHelperHandle = pHelperFloater->getHandle();
mHelperCommitConn = pHelperFloater->setCommitCallback(std::bind([&](const LLSD& sdValue) { onCommitEmoji(utf8str_to_wstring(sdValue.asStringRef())); }, std::placeholders::_2));
mHelperCommitConn = pHelperFloater->setCommitCallback(std::bind([&](const LLSD& sdValue) { onCommitEmoji(utf8str_to_wstring(sdValue.asStringRef())[0]); }, std::placeholders::_2));
}
setHostCtrl(hostctrl_p);
mEmojiCommitCb = cb;
@ -135,11 +135,11 @@ bool LLEmojiHelper::handleKey(const LLUICtrl* ctrl_p, KEY key, MASK mask)
return mHelperHandle.get()->handleKey(key, mask, true);
}
void LLEmojiHelper::onCommitEmoji(const LLWString& wstr)
void LLEmojiHelper::onCommitEmoji(llwchar emoji)
{
if (!mHostHandle.isDead() && mEmojiCommitCb)
{
mEmojiCommitCb(wstr);
mEmojiCommitCb(emoji);
}
}

View File

@ -44,12 +44,12 @@ public:
std::string getToolTip(llwchar ch) const;
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(LLWString)> commit_cb);
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);
// Eventing
bool handleKey(const LLUICtrl* ctrl_p, KEY key, MASK mask);
void onCommitEmoji(const LLWString& wstr);
void onCommitEmoji(llwchar emoji);
protected:
LLUICtrl* getHostCtrl() const { return mHostHandle.get(); }
@ -60,5 +60,5 @@ private:
LLHandle<LLFloater> mHelperHandle;
boost::signals2::connection mHostCtrlFocusLostConn;
boost::signals2::connection mHelperCommitConn;
std::function<void(LLWString)> mEmojiCommitCb;
std::function<void(llwchar)> mEmojiCommitCb;
};

View File

@ -1597,14 +1597,24 @@ BOOL LLFloater::isFrontmost()
&& floater_view->getFrontmost() == this);
}
void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition)
void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition, BOOL resize)
{
mDependents.insert(floaterp->getHandle());
floaterp->mDependeeHandle = getHandle();
if (reposition)
{
floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp));
LLRect rect = gFloaterView->findNeighboringPosition(this, floaterp);
if (resize)
{
const LLRect& base = getRect();
if (rect.mTop == base.mTop)
rect.mBottom = base.mBottom;
else if (rect.mLeft == base.mLeft)
rect.mRight = base.mRight;
floaterp->reshape(rect.getWidth(), rect.getHeight(), FALSE);
}
floaterp->setRect(rect);
floaterp->setSnapTarget(getHandle());
}
gFloaterView->adjustToFitScreen(floaterp, FALSE, TRUE);
@ -1615,12 +1625,12 @@ void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition)
}
}
void LLFloater::addDependentFloater(LLHandle<LLFloater> dependent, BOOL reposition)
void LLFloater::addDependentFloater(LLHandle<LLFloater> dependent, BOOL reposition, BOOL resize)
{
LLFloater* dependent_floaterp = dependent.get();
if(dependent_floaterp)
{
addDependentFloater(dependent_floaterp, reposition);
addDependentFloater(dependent_floaterp, reposition, resize);
}
}

View File

@ -265,8 +265,8 @@ public:
std::string getShortTitle() const;
virtual void setMinimized(BOOL b);
void moveResizeHandlesToFront();
void addDependentFloater(LLFloater* dependent, BOOL reposition = TRUE);
void addDependentFloater(LLHandle<LLFloater> dependent_handle, BOOL reposition = TRUE);
void addDependentFloater(LLFloater* dependent, BOOL reposition = TRUE, BOOL resize = FALSE);
void addDependentFloater(LLHandle<LLFloater> dependent_handle, BOOL reposition = TRUE, BOOL resize = FALSE);
LLFloater* getDependee() { return (LLFloater*)mDependeeHandle.get(); }
void removeDependentFloater(LLFloater* dependent);
BOOL isMinimized() const { return mMinimized; }

View File

@ -495,7 +495,7 @@ void LLScrollListCtrl::clearRows()
LLScrollListItem* LLScrollListCtrl::getFirstSelected() const
{
item_list::const_iterator iter;
for(iter = mItemList.begin(); iter != mItemList.end(); iter++)
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
{
LLScrollListItem* item = *iter;
if (item->getSelected())
@ -1385,7 +1385,7 @@ BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sen
LLScrollListItem* item = getItemByLabel(label, case_sensitive, column);
bool found = NULL != item;
if(found)
if (found)
{
selectItem(item, -1);
}
@ -3161,7 +3161,7 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending)
S32 LLScrollListCtrl::getLinesPerPage()
{
//if mPageLines is NOT provided display all item
if(mPageLines)
if (mPageLines)
{
return mPageLines;
}

View File

@ -259,7 +259,7 @@ public:
S32 getItemIndex( LLScrollListItem* item ) const;
S32 getItemIndex( const LLUUID& item_id ) const;
void setCommentText( const std::string& comment_text);
void setCommentText( const std::string& comment_text);
// <FS:Ansariel> Allow appending of comment text
void addCommentText( const std::string& comment_text);
// </FS:Ansariel> Allow appending of comment text
@ -277,7 +277,7 @@ public:
BOOL selectItemBySubstring(const LLWString& target, BOOL case_sensitive = TRUE);
BOOL selectItemByStringMatch(const LLWString& target, bool prefix_match, BOOL case_sensitive = TRUE, S32 column = -1);
// </FS:Ansariel>
LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 );
LLScrollListItem* getItemByLabel(const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0);
const std::string getSelectedItemLabel(S32 column = 0) const;
LLSD getSelectedValue();
@ -339,7 +339,7 @@ public:
virtual S32 getScrollPos() const;
virtual void setScrollPos( S32 pos );
S32 getSearchColumn();
S32 getSearchColumn();
void setSearchColumn(S32 column) { mSearchColumn = column; }
S32 getColumnIndexFromOffset(S32 x);
S32 getColumnOffsetFromIndex(S32 index);
@ -394,13 +394,13 @@ public:
// Used "internally" by the scroll bar.
void onScrollChange( S32 new_pos, LLScrollbar* src );
static void onClickColumn(void *userdata);
static void onClickColumn(void *userdata);
virtual void updateColumns(bool force_update = false);
S32 calcMaxContentWidth();
bool updateColumnWidths();
virtual void updateColumns(bool force_update = false);
S32 calcMaxContentWidth();
bool updateColumnWidths();
void setHeadingHeight(S32 heading_height);
void setHeadingHeight(S32 heading_height);
/**
* Sets max visible lines without scroolbar, if this value equals to 0,
* then display all items.
@ -421,18 +421,20 @@ public:
virtual void deselect();
virtual BOOL canDeselect() const;
void setNumDynamicColumns(S32 num) { mNumDynamicWidthColumns = num; }
void updateStaticColumnWidth(LLScrollListColumn* col, S32 new_width);
S32 getTotalStaticColumnWidth() { return mTotalStaticColumnWidth; }
void setNumDynamicColumns(S32 num) { mNumDynamicWidthColumns = num; }
void updateStaticColumnWidth(LLScrollListColumn* col, S32 new_width);
S32 getTotalStaticColumnWidth() { return mTotalStaticColumnWidth; }
std::string getSortColumnName();
BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; }
BOOL hasSortOrder() const;
void clearSortOrder();
void setAlternateSort() { mAlternateSort = true; }
void setAlternateSort() { mAlternateSort = TRUE; }
S32 selectMultiple( uuid_vec_t ids );
void selectPrevItem(BOOL extend_selection = FALSE);
void selectNextItem(BOOL extend_selection = FALSE);
S32 selectMultiple(uuid_vec_t ids);
// conceptually const, but mutates mItemList
void updateSort() const;
// sorts a list without affecting the permanent sort order (so further list insertions can be unsorted, for example)
@ -487,8 +489,6 @@ public:
mutable U32 mLastUpdateFrame;
private:
void selectPrevItem(BOOL extend_selection);
void selectNextItem(BOOL extend_selection);
void drawItems();
void updateLineHeightInsert(LLScrollListItem* item);

View File

@ -731,18 +731,24 @@ void LLTextEditor::selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_p
endSelection();
}
void LLTextEditor::handleEmojiCommit(const LLWString& wstr)
void LLTextEditor::insertEmoji(llwchar emoji)
{
LLWString wtext(getWText()); S32 shortCodePos;
if (LLEmojiHelper::isCursorInEmojiCode(wtext, mCursorPos, &shortCodePos))
auto styleParams = LLStyle::Params();
styleParams.font = LLFontGL::getFontEmoji();
auto segment = new LLEmojiTextSegment(new LLStyle(styleParams), mCursorPos, mCursorPos + 1, *this);
insert(mCursorPos, LLWString(1, emoji), false, segment);
setCursorPos(mCursorPos + 1);
}
void LLTextEditor::handleEmojiCommit(llwchar emoji)
{
S32 shortCodePos;
if (LLEmojiHelper::isCursorInEmojiCode(getWText(), mCursorPos, &shortCodePos))
{
remove(shortCodePos, mCursorPos - shortCodePos, true);
setCursorPos(shortCodePos);
auto styleParams = LLStyle::Params();
styleParams.font = LLFontGL::getFontEmoji();
insert(shortCodePos, wstr, false, new LLEmojiTextSegment(new LLStyle(styleParams), shortCodePos, shortCodePos + wstr.size(), *this));
setCursorPos(shortCodePos + 1);
insertEmoji(emoji);
}
}

View File

@ -93,7 +93,8 @@ public:
static S32 spacesPerTab();
void handleEmojiCommit(const LLWString& wstr);
void insertEmoji(llwchar emoji);
void handleEmojiCommit(llwchar emoji);
// mousehandler overrides
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);

View File

@ -315,6 +315,7 @@ set(viewer_SOURCE_FILES
llfloaterdisplayname.cpp
llfloatereditenvironmentbase.cpp
llfloatereditextdaycycle.cpp
llfloateremojipicker.cpp
llfloaterenvironmentadjust.cpp
llfloaterevent.cpp
llfloaterexperiencepicker.cpp
@ -1097,6 +1098,7 @@ set(viewer_HEADER_FILES
llfloaterdisplayname.h
llfloatereditenvironmentbase.h
llfloatereditextdaycycle.h
llfloateremojipicker.h
llfloaterenvironmentadjust.h
llfloaterevent.h
llfloaterexperiencepicker.h
@ -2430,6 +2432,22 @@ set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
#file(COPY ${FONT_FILE_GLOB_LIST} DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/fonts")
# </FS:Ansariel>
# Copy over the Emoji/shortcodes mapping XML files (and create dependency
# if they are changed, CMake will run again and copy over new versions)
message("Copying Emoji/shortcode mappings")
set(emoji_mapping_src_folder ${AUTOBUILD_INSTALL_DIR}/xui)
set(emoji_mapping_dst_folder ${CMAKE_CURRENT_SOURCE_DIR}/skins/default/xui)
# Note Turkey is missing from this set (not available in Emoji package yet)
set(country_codes "da;de;en;es;fr;it;ja;pl;pt;ru;zh")
foreach(elem ${country_codes})
set(emoji_mapping_src_file
"${emoji_mapping_src_folder}/${elem}/emoji_characters.xml")
set(emoji_mapping_dst_file
"${emoji_mapping_dst_folder}/${elem}/emoji_characters.xml")
configure_file(${emoji_mapping_src_file} ${emoji_mapping_dst_file} COPYONLY)
endforeach()
if (LINUX)
set(product Firestorm-${ARCH}-${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION})

View File

@ -930,7 +930,6 @@ void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD&
}
}
//static
void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller, void* user_data)
{
getChildView("Find")->setEnabled(caller->getText().size() > 0);

View File

@ -0,0 +1,296 @@
/**
* @file llfloateremojipicker.cpp
*
* $LicenseInfo:firstyear=2003&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloateremojipicker.h"
#include "llcombobox.h"
#include "llemojidictionary.h"
#include "llfloaterreg.h"
#include "lllineeditor.h"
#include "llscrolllistctrl.h"
#include "llscrolllistitem.h"
#include "lltextbox.h"
#include "llviewerchat.h"
std::string LLFloaterEmojiPicker::mSelectedCategory;
std::string LLFloaterEmojiPicker::mSearchPattern;
int LLFloaterEmojiPicker::mSelectedEmojiIndex;
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);
S32 width = getColumn(0)->getWidth();
LLFontGL::getFontEmoji()->render(LLWString(1, mEmoji), 0, rect.mLeft + width / 2, rect.getCenterY(), LLColor4::white,
LLFontGL::HCENTER, LLFontGL::VCENTER, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW_SOFT, 1, S32_MAX, nullptr, false, true);
}
private:
llwchar mEmoji;
};
LLFloaterEmojiPicker* LLFloaterEmojiPicker::getInstance()
{
LLFloaterEmojiPicker* floater = LLFloaterReg::getTypedInstance<LLFloaterEmojiPicker>("emoji_picker");
if (!floater)
LL_WARNS() << "Cannot instantiate emoji picker" << LL_ENDL;
return floater;
}
LLFloaterEmojiPicker* LLFloaterEmojiPicker::showInstance(pick_callback_t pick_callback, close_callback_t close_callback)
{
LLFloaterEmojiPicker* floater = getInstance();
if (LLFloaterEmojiPicker* floater = getInstance())
floater->show(pick_callback, close_callback);
return floater;
}
void LLFloaterEmojiPicker::show(pick_callback_t pick_callback, close_callback_t close_callback)
{
mEmojiPickCallback = pick_callback;
mFloaterCloseCallback = close_callback;
openFloater(mKey);
setFocus(TRUE);
}
LLFloaterEmojiPicker::LLFloaterEmojiPicker(const LLSD& key)
: LLFloater(key)
{
}
BOOL LLFloaterEmojiPicker::postBuild()
{
// Should be initialized first
if ((mPreviewEmoji = getChild<LLButton>("PreviewEmoji")))
{
mPreviewEmoji->setClickedCallback(boost::bind(&LLFloaterEmojiPicker::onPreviewEmojiClick, this));
}
if ((mCategory = getChild<LLComboBox>("Category")))
{
mCategory->setCommitCallback(boost::bind(&LLFloaterEmojiPicker::onCategoryCommit, this));
mCategory->setLabel(LLStringExplicit("Choose a category"));
const auto& cat2Descrs = LLEmojiDictionary::instance().getCategory2Descrs();
mCategory->clearRows();
for (const auto& item : cat2Descrs)
{
std::string value = item.first;
std::string name = value;
LLStringUtil::capitalize(name);
mCategory->add(name, value);
}
mCategory->setSelectedByValue(mSelectedCategory, true);
}
if ((mSearch = getChild<LLLineEditor>("Search")))
{
mSearch->setKeystrokeCallback(boost::bind(&LLFloaterEmojiPicker::onSearchKeystroke, this, _1, _2), NULL);
mSearch->setLabel(LLStringExplicit("Type to search an emoji"));
mSearch->setFont(LLViewerChat::getChatFont());
mSearch->setText(mSearchPattern);
}
if ((mEmojis = getChild<LLScrollListCtrl>("Emojis")))
{
mEmojis->setCommitCallback(boost::bind(&LLFloaterEmojiPicker::onEmojiSelect, this));
mEmojis->setDoubleClickCallback(boost::bind(&LLFloaterEmojiPicker::onEmojiPick, this));
fillEmojis();
}
return TRUE;
}
LLFloaterEmojiPicker::~LLFloaterEmojiPicker()
{
gFocusMgr.releaseFocusIfNeeded( this );
}
void LLFloaterEmojiPicker::fillEmojis()
{
mEmojis->clearRows();
const auto& emoji2Descr = LLEmojiDictionary::instance().getEmoji2Descr();
for (const std::pair<const llwchar, const LLEmojiDescriptor*>& it : emoji2Descr)
{
const LLEmojiDescriptor* descr = it.second;
if (!mSelectedCategory.empty() && !matchesCategory(descr))
continue;
if (!mSearchPattern.empty() && !matchesPattern(descr))
continue;
LLScrollListItem::Params params;
params.columns.add().column("name").value(descr->Name);
mEmojis->addRow(new LLEmojiScrollListItem(it.first, params), params);
}
if (mEmojis->getItemCount())
{
if (mSelectedEmojiIndex > 0 && mSelectedEmojiIndex < mEmojis->getItemCount())
mEmojis->selectNthItem(mSelectedEmojiIndex);
else
mEmojis->selectFirstItem();
mEmojis->scrollToShowSelected();
}
else
{
onEmojiEmpty();
}
}
bool LLFloaterEmojiPicker::matchesCategory(const LLEmojiDescriptor* descr)
{
return std::find(descr->Categories.begin(), descr->Categories.end(), mSelectedCategory) != descr->Categories.end();
}
bool LLFloaterEmojiPicker::matchesPattern(const LLEmojiDescriptor* descr)
{
if (descr->Name.find(mSearchPattern) != std::string::npos)
return true;
for (auto shortCode : descr->ShortCodes)
if (shortCode.find(mSearchPattern) != std::string::npos)
return true;
for (auto category : descr->Categories)
if (category.find(mSearchPattern) != std::string::npos)
return true;
return false;
}
void LLFloaterEmojiPicker::onCategoryCommit()
{
mSelectedCategory = mCategory->getSelectedValue().asString();
mSelectedEmojiIndex = 0;
fillEmojis();
}
void LLFloaterEmojiPicker::onSearchKeystroke(LLLineEditor* caller, void* user_data)
{
mSearchPattern = mSearch->getText();
mSelectedEmojiIndex = 0;
fillEmojis();
}
void LLFloaterEmojiPicker::onPreviewEmojiClick()
{
if (mEmojis && mEmojiPickCallback)
{
if (LLEmojiScrollListItem* item = dynamic_cast<LLEmojiScrollListItem*>(mEmojis->getFirstSelected()))
{
mEmojiPickCallback(item->getEmoji());
}
}
}
void LLFloaterEmojiPicker::onEmojiSelect()
{
const LLEmojiScrollListItem* item = dynamic_cast<LLEmojiScrollListItem*>(mEmojis->getFirstSelected());
if (item)
{
mSelectedEmojiIndex = mEmojis->getFirstSelectedIndex();
LLUIString text;
text.insert(0, LLWString(1, item->getEmoji()));
if (mPreviewEmoji)
mPreviewEmoji->setLabel(text);
return;
}
onEmojiEmpty();
}
void LLFloaterEmojiPicker::onEmojiEmpty()
{
mSelectedEmojiIndex = 0;
if (mPreviewEmoji)
mPreviewEmoji->setLabel(LLUIString());
}
void LLFloaterEmojiPicker::onEmojiPick()
{
if (mEmojis && mEmojiPickCallback)
{
if (LLEmojiScrollListItem* item = dynamic_cast<LLEmojiScrollListItem*>(mEmojis->getFirstSelected()))
{
mEmojiPickCallback(item->getEmoji());
closeFloater();
}
}
}
// virtual
BOOL LLFloaterEmojiPicker::handleKeyHere(KEY key, MASK mask)
{
if (mask == MASK_NONE)
{
switch (key)
{
case KEY_RETURN:
if (mCategory->hasFocus())
break;
onEmojiPick();
return TRUE;
case KEY_ESCAPE:
closeFloater();
return TRUE;
case KEY_UP:
mEmojis->selectPrevItem();
mEmojis->scrollToShowSelected();
return TRUE;
case KEY_DOWN:
mEmojis->selectNextItem();
mEmojis->scrollToShowSelected();
return TRUE;
}
}
return LLFloater::handleKeyHere(key, mask);
}
// virtual
void LLFloaterEmojiPicker::closeFloater(bool app_quitting)
{
LLFloater::closeFloater(app_quitting);
if (mFloaterCloseCallback)
mFloaterCloseCallback();
}

View File

@ -0,0 +1,81 @@
/**
* @file llfloateremojipicker.h
* @brief Header file for llfloateremojipicker
*
* $LicenseInfo:firstyear=2003&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LLFLOATEREMOJIPICKER_H
#define LLFLOATEREMOJIPICKER_H
#include "llfloater.h"
struct LLEmojiDescriptor;
class LLFloaterEmojiPicker : public LLFloater
{
public:
// The callback function will be called with an emoji char.
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();
void show(pick_callback_t pick_callback = nullptr, close_callback_t close_callback = nullptr);
virtual void closeFloater(bool app_quitting = false);
private:
void fillEmojis();
bool matchesCategory(const LLEmojiDescriptor* descr);
bool matchesPattern(const LLEmojiDescriptor* descr);
void onCategoryCommit();
void onSearchKeystroke(class LLLineEditor* caller, void* user_data);
void onPreviewEmojiClick();
void onEmojiSelect();
void onEmojiEmpty();
void onEmojiPick();
virtual BOOL handleKeyHere(KEY key, MASK mask);
class LLComboBox* mCategory { nullptr };
class LLLineEditor* mSearch { nullptr };
class LLScrollListCtrl* mEmojis { nullptr };
class LLButton* mPreviewEmoji { nullptr };
pick_callback_t mEmojiPickCallback;
close_callback_t mFloaterCloseCallback;
static std::string mSelectedCategory;
static std::string mSearchPattern;
static int mSelectedEmojiIndex;
};
#endif

View File

@ -42,6 +42,7 @@
#include "llchicletbar.h"
#include "lldraghandle.h"
#include "llfloaterreg.h"
#include "llfloateremojipicker.h"
#include "llfloaterimsession.h"
#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
#include "lllayoutstack.h"
@ -252,10 +253,13 @@ BOOL LLFloaterIMSessionTab::postBuild()
mTearOffBtn = getChild<LLButton>("tear_off_btn");
mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this));
mEmojiBtn = getChild<LLButton>("emoji_panel_btn");
mEmojiBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onEmojiPanelBtnClicked, this));
mGearBtn = getChild<LLButton>("gear_btn");
mAddBtn = getChild<LLButton>("add_btn");
mVoiceButton = getChild<LLButton>("voice_call_btn");
mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
mRightPartPanel = getChild<LLLayoutPanel>("right_part_holder");
@ -426,6 +430,37 @@ void LLFloaterIMSessionTab::onInputEditorClicked()
gToolBarView->flashCommand(LLCommandId("chat"), false);
}
void LLFloaterIMSessionTab::onEmojiPanelBtnClicked(LLFloaterIMSessionTab* self)
{
if (LLFloaterEmojiPicker* picker = LLFloaterEmojiPicker::getInstance())
{
if (!picker->isShown())
{
picker->show(
boost::bind(&LLFloaterIMSessionTab::onEmojiPicked, self, _1),
boost::bind(&LLFloaterIMSessionTab::onEmojiPickerClosed, self));
if (LLFloater* root_floater = gFloaterView->getParentFloater(self))
{
root_floater->addDependentFloater(picker, TRUE, TRUE);
}
}
else
{
picker->closeFloater();
}
}
}
void LLFloaterIMSessionTab::onEmojiPicked(llwchar emoji)
{
mInputEditor->insertEmoji(emoji);
}
void LLFloaterIMSessionTab::onEmojiPickerClosed()
{
mInputEditor->setFocus(TRUE);
}
std::string LLFloaterIMSessionTab::appendTime()
{
time_t utc_time;

View File

@ -183,6 +183,7 @@ protected:
LLButton* mExpandCollapseLineBtn;
LLButton* mExpandCollapseBtn;
LLButton* mTearOffBtn;
LLButton* mEmojiBtn;
LLButton* mCloseBtn;
LLButton* mGearBtn;
LLButton* mAddBtn;
@ -208,6 +209,10 @@ private:
void onInputEditorClicked();
static void onEmojiPanelBtnClicked(LLFloaterIMSessionTab* self);
void onEmojiPicked(llwchar emoji);
void onEmojiPickerClosed();
bool checkIfTornOff();
bool mIsHostAttached;
bool mHasVisibleBeenInitialized;

View File

@ -25,7 +25,7 @@
*/
#include "llviewerprecompiledheaders.h"
#include "llviewerchat.h"
#include "llviewerchat.h"
// newview includes
#include "llagent.h" // gAgent

View File

@ -65,6 +65,7 @@
#include "llfloaterdestinations.h"
#include "llfloaterdisplayname.h"
#include "llfloatereditextdaycycle.h"
#include "llfloateremojipicker.h"
#include "llfloaterenvironmentadjust.h"
#include "llfloaterexperienceprofile.h"
#include "llfloaterexperiences.h"
@ -400,7 +401,7 @@ void LLViewerFloaterReg::registerFloaters()
//LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
LLFloaterReg::add("fs_nearby_chat", "floater_fs_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterNearbyChat>);
// </FS:Ansariel> [FS communication UI]
LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>);
LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>);
LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>);
@ -408,19 +409,20 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("delete_pref_preset", "floater_delete_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeletePrefPreset>);
LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>);
LLFloaterReg::add("emoji_complete", "floater_emoji_complete.xml", &LLFloaterReg::build<LLFloaterEmojiComplete>);
LLFloaterReg::add("emoji_picker", "floater_emoji_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEmojiPicker>);
LLFloaterReg::add("emoji_complete", "floater_emoji_complete.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEmojiComplete>);
LLFloaterReg::add("env_post_process", "floater_post_process.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPostProcess>);
LLFloaterReg::add("env_fixed_environmentent_water", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentWater>);
LLFloaterReg::add("env_fixed_environmentent_sky", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentSky>);
LLFloaterReg::add("env_fixed_environmentent_water", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentWater>);
LLFloaterReg::add("env_fixed_environmentent_sky", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentSky>);
LLFloaterReg::add("env_adjust_snapshot", "floater_adjust_environment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEnvironmentAdjust>);
LLFloaterReg::add("env_adjust_snapshot", "floater_adjust_environment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEnvironmentAdjust>);
LLFloaterReg::add("env_edit_extdaycycle", "floater_edit_ext_day_cycle.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditExtDayCycle>);
LLFloaterReg::add("my_environments", "floater_my_environments.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMyEnvironment>);
LLFloaterReg::add("env_edit_extdaycycle", "floater_edit_ext_day_cycle.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditExtDayCycle>);
LLFloaterReg::add("my_environments", "floater_my_environments.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMyEnvironment>);
LLFloaterReg::add("event", "floater_event.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEvent>);
LLFloaterReg::add("experiences", "floater_experiences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiences>);
LLFloaterReg::add("event", "floater_event.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEvent>);
LLFloaterReg::add("experiences", "floater_experiences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiences>);
LLFloaterReg::add("experience_profile", "floater_experienceprofile.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperienceProfile>);
LLFloaterReg::add("experience_search", "floater_experience_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiencePicker>);

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

View File

@ -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" />
@ -229,7 +230,6 @@ with the same filename but different name
<texture name="Presets_Icon" file_name="icons/Presets_Icon.png" preload="true" />
<texture name="Presets_Icon_Graphic" file_name="icons/Presets_Icon_Graphic.png" preload="true" />
<texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" />
<texture name="Favorite_Star_Off" file_name="navbar/Favorite_Star_Off.png" preload="false" />
<texture name="Favorite_Star_Press" file_name="navbar/Favorite_Star_Press.png" preload="false" />

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
name="emojipicker"
title="CHOOSE EMOJI"
help_topic="emojipicker"
positioning="cascading"
legacy_header_height="0"
can_resize="true"
layout="topleft"
height="400"
width="200">
<line_editor
name="Search"
layout="bottomleft"
follows="bottom|left|right"
text_tentative_color="TextFgTentativeColor"
max_length_bytes="63"
left_pad="5"
bottom="14"
left="34"
height="29"
width="162" />
<button
name="PreviewEmoji"
layout="bottomleft"
follows="bottom|left"
font="EmojiHuge"
use_font_color="true"
bottom="14"
left="0"
height="29"
width="29" />
<scroll_list
name="Emojis"
layout="topleft"
follows="all"
sort_column="0"
max_chars="63"
commit_on_selection_change="true"
draw_heading="true"
heading_height="25"
row_padding="0"
top="25"
height="330"
width="200">
<columns
label="Look"
name="look"
width="40" />
<columns
label="Name"
name="name" />
</scroll_list>
<combo_box
name="Category"
layout="topleft"
follows="top|left|right"
allow_text_entry="true"
left_pad="4"
top="0"
left="4"
height="27"
width="192" />
</floater>

View File

@ -297,8 +297,20 @@
tab_group="3"
bottom="-8"
left_pad="5"
right="-5"
right="-30"
wrap="true" />
<button
follows="right|bottom"
bottom="-7"
height="25"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="Emoji_Picker_Icon"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
right="-1"
name="emoji_panel_btn"
tool_tip="Shows/hides emoji panel"
width="25"/>
</layout_panel>
<layout_panel
auto_resize="false"

View File

@ -559,9 +559,9 @@ https://www.firestormviewer.org/support for help fixing this problem.
<!-- build floater -->
<string name="multiple_textures">Multiple</string>
<string name="use_texture">Use texture</string>
<string name="manip_hint1">Move mouse cursor over ruler</string>
<string name="manip_hint2">to snap to grid</string>
<string name="use_texture">Use texture</string>
<string name="manip_hint1">Move mouse cursor over ruler</string>
<string name="manip_hint2">to snap to grid</string>
<!-- world map -->
<string name="texture_loading">Loading...</string>
@ -582,14 +582,14 @@ https://www.firestormviewer.org/support for help fixing this problem.
<!-- Chat -->
<string name="no_name_object">(no name)</string>
<string name="NearbyChatTitle">Nearby chat</string>
<string name="NearbyChatLabel">(Nearby chat)</string>
<string name="NearbyChatLabel">(Nearby chat)</string>
<string name="whisper">whispers:</string>
<string name="shout">shouts:</string>
<string name="ringing">Connecting to in-world Voice Chat...</string>
<string name="connected">Connected</string>
<string name="unavailable">Voice not available at your current location</string>
<string name="hang_up">Disconnected from in-world Voice Chat</string>
<string name="reconnect_nearby">You will now be reconnected to Nearby Voice Chat</string>
<string name="reconnect_nearby">You will now be reconnected to Nearby Voice Chat</string>
<string name="ScriptQuestionCautionChatGranted">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS].</string>
<string name="ScriptQuestionCautionChatDenied">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS].</string>
<string name="AdditionalPermissionsRequestHeader">If you allow access to your account, you will also be allowing the object to:</string>