summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/CMakeLists.txt2
-rw-r--r--indra/llui/llaccordionctrl.cpp40
-rw-r--r--indra/llui/llaccordionctrl.h6
-rw-r--r--indra/llui/llaccordionctrltab.cpp54
-rw-r--r--indra/llui/llaccordionctrltab.h2
-rw-r--r--indra/llui/llbutton.cpp2
-rw-r--r--indra/llui/llbutton.h2
-rw-r--r--indra/llui/llcallbackmap.h8
-rw-r--r--indra/llui/llclipboard.h2
-rw-r--r--indra/llui/llcombobox.cpp6
-rw-r--r--indra/llui/llcombobox.h1
-rw-r--r--indra/llui/lldockablefloater.cpp2
-rw-r--r--indra/llui/lldockablefloater.h2
-rw-r--r--indra/llui/lldockcontrol.h4
-rw-r--r--indra/llui/llemojidictionary.cpp11
-rw-r--r--indra/llui/llemojihelper.cpp10
-rw-r--r--indra/llui/llflashtimer.cpp2
-rw-r--r--indra/llui/llflashtimer.h6
-rw-r--r--indra/llui/llflatlistview.cpp19
-rw-r--r--indra/llui/llflatlistview.h9
-rw-r--r--indra/llui/llfloater.cpp2
-rw-r--r--indra/llui/llfloaterreg.h4
-rw-r--r--indra/llui/llfocusmgr.cpp10
-rw-r--r--indra/llui/llfolderview.cpp1
-rw-r--r--indra/llui/llfolderview.h1
-rw-r--r--indra/llui/llfolderviewitem.cpp269
-rw-r--r--indra/llui/llfolderviewitem.h31
-rw-r--r--indra/llui/llfolderviewmodel.h78
-rw-r--r--indra/llui/llfunctorregistry.h2
-rw-r--r--indra/llui/lllazyvalue.h7
-rw-r--r--indra/llui/lllineeditor.cpp3
-rw-r--r--indra/llui/lllineeditor.h4
-rw-r--r--indra/llui/llmenugl.cpp16
-rw-r--r--indra/llui/llmenugl.h5
-rw-r--r--indra/llui/llmodaldialog.cpp12
-rw-r--r--indra/llui/llnotifications.cpp16
-rw-r--r--indra/llui/llnotifications.h25
-rw-r--r--indra/llui/llnotificationslistener.cpp2
-rw-r--r--indra/llui/llnotificationsutil.cpp2
-rw-r--r--indra/llui/llnotificationsutil.h4
-rw-r--r--indra/llui/llpanel.cpp8
-rw-r--r--indra/llui/llpanel.h6
-rw-r--r--indra/llui/llresizebar.h4
-rw-r--r--indra/llui/llscrollbar.h2
-rw-r--r--indra/llui/llscrolllistcell.cpp32
-rw-r--r--indra/llui/llscrolllistcell.h2
-rw-r--r--indra/llui/llscrolllistctrl.cpp16
-rw-r--r--indra/llui/llscrolllistctrl.h4
-rw-r--r--indra/llui/llsearcheditor.cpp8
-rw-r--r--indra/llui/lltextbase.cpp69
-rw-r--r--indra/llui/lltextbase.h10
-rw-r--r--indra/llui/lltextbox.cpp6
-rw-r--r--indra/llui/lltextbox.h4
-rw-r--r--indra/llui/lltexteditor.cpp32
-rw-r--r--indra/llui/lltexteditor.h6
-rw-r--r--indra/llui/lltextutil.cpp2
-rw-r--r--indra/llui/lltextutil.h2
-rw-r--r--indra/llui/lltextvalidate.h1
-rw-r--r--indra/llui/lltoolbar.cpp38
-rw-r--r--indra/llui/lltoolbar.h8
-rw-r--r--indra/llui/lltooltip.h4
-rw-r--r--indra/llui/llui.cpp10
-rw-r--r--indra/llui/llui.h6
-rw-r--r--indra/llui/lluictrl.cpp9
-rw-r--r--indra/llui/lluictrl.h11
-rw-r--r--indra/llui/lluictrlfactory.cpp15
-rw-r--r--indra/llui/lluictrlfactory.h2
-rw-r--r--indra/llui/llurlaction.cpp38
-rw-r--r--indra/llui/llurlaction.h14
-rw-r--r--indra/llui/llurlentry.cpp22
-rw-r--r--indra/llui/llurlentry.h6
-rw-r--r--indra/llui/llview.h11
-rw-r--r--indra/llui/llviewereventrecorder.cpp2
-rw-r--r--indra/llui/llxuiparser.cpp2
-rw-r--r--indra/llui/llxuiparser.h4
75 files changed, 862 insertions, 238 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 908e94b24c..83b3a220a0 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -272,6 +272,8 @@ target_link_libraries(llui
llcommon
)
+include(LibraryInstall)
+
# Add tests
if(LL_TESTS)
include(LLAddBuildTest)
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index 495ba2f40f..ac8f7c2126 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -47,6 +47,8 @@ static constexpr F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
static LLDefaultChildRegistry::Register<LLAccordionCtrl> t2("accordion");
+std::set<LLAccordionCtrl*> LLAccordionCtrl::sPendingArrange;
+
LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
, mFitParent(params.fit_parent)
, mNoVisibleTabsOrigString(params.no_visible_tabs_text.initial_value().asString())
@@ -163,7 +165,11 @@ bool LLAccordionCtrl::postBuild()
//---------------------------------------------------------------------------------
LLAccordionCtrl::~LLAccordionCtrl()
{
- mAccordionTabs.clear();
+ if (mArrangePending)
+ {
+ sPendingArrange.erase(this);
+ }
+ mAccordionTabs.clear();
}
//---------------------------------------------------------------------------------
@@ -184,7 +190,7 @@ void LLAccordionCtrl::reshape(S32 width, S32 height, bool called_from_parent)
// necessary text paddings can be set via h_pad and v_pad
mNoVisibleTabsHelpText->setRect(getLocalRect());
- arrange();
+ scheduleArrange();
}
//---------------------------------------------------------------------------------
@@ -325,7 +331,7 @@ void LLAccordionCtrl::addCollapsibleCtrl(LLAccordionCtrlTab* accordion_tab)
mAccordionTabs.push_back(accordion_tab);
accordion_tab->setDropDownStateChangedCallback( boost::bind(&LLAccordionCtrl::onCollapseCtrlCloseOpen, this, (S16)(mAccordionTabs.size() - 1)) );
- arrange();
+ scheduleArrange();
}
void LLAccordionCtrl::removeCollapsibleCtrl(LLAccordionCtrlTab* accordion_tab)
@@ -494,6 +500,7 @@ void LLAccordionCtrl::arrangeMultiple()
void LLAccordionCtrl::arrange()
{
+ LL_PROFILE_ZONE_SCOPED;
updateNoTabsHelpTextVisibility();
if (mAccordionTabs.empty())
@@ -681,8 +688,9 @@ S32 LLAccordionCtrl::notifyParent(const LLSD& info)
std::string str_action = info["action"];
if (str_action == "size_changes")
{
- //
- arrange();
+ // Multiple children can request an arrange,
+ // but only need to do it once so schedule it for later.
+ scheduleArrange();
return 1;
}
if (str_action == "select_next")
@@ -924,3 +932,25 @@ void LLAccordionCtrl::collapseAllTabs()
arrange();
}
}
+
+void LLAccordionCtrl::scheduleArrange()
+{
+ if (!mArrangePending)
+ {
+ mArrangePending = true;
+ sPendingArrange.insert(this);
+ }
+}
+
+void LLAccordionCtrl::updateClass()
+{
+ for (LLAccordionCtrl* inst : sPendingArrange)
+ {
+ if (inst)
+ {
+ inst->mArrangePending = false;
+ inst->arrange();
+ }
+ }
+ sPendingArrange.clear();
+}
diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h
index 43a33a2b3c..c7bb8bc9ff 100644
--- a/indra/llui/llaccordionctrl.h
+++ b/indra/llui/llaccordionctrl.h
@@ -142,6 +142,9 @@ public:
void setSkipScrollToChild(bool skip) { mSkipScrollToChild = skip; }
+ void scheduleArrange();
+ static void updateClass();
+
private:
void initNoTabsWidget(const LLTextBox::Params& tb_params);
void updateNoTabsHelpTextVisibility();
@@ -188,12 +191,15 @@ private:
LLTextBox* mNoVisibleTabsHelpText = nullptr;
bool mSkipScrollToChild = false;
+ bool mArrangePending = false;
std::string mNoMatchedTabsOrigString;
std::string mNoVisibleTabsOrigString;
LLAccordionCtrlTab* mSelectedTab = nullptr;
const LLTabComparator* mTabComparator = nullptr;
+
+ static std::set<LLAccordionCtrl*> sPendingArrange;
};
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index ac66525030..828bfb289b 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -248,10 +248,22 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::reshape(S32 width, S32 height, bool called_from_parent /* = true */)
{
S32 header_height = mHeaderTextbox->getTextPixelHeight();
+ LLRect old_header_rect = mHeaderTextbox->getRect();
LLRect textboxRect(HEADER_TEXT_LEFT_OFFSET, (height + header_height) / 2, width, (height - header_height) / 2);
- mHeaderTextbox->reshape(textboxRect.getWidth(), textboxRect.getHeight());
- mHeaderTextbox->setRect(textboxRect);
+ if (old_header_rect.getHeight() != textboxRect.getHeight()
+ || old_header_rect.mLeft != textboxRect.mLeft
+ || old_header_rect.mTop != textboxRect.mTop
+ || old_header_rect.getWidth() > textboxRect.getWidth() // reducing header's width
+ || (old_header_rect.getWidth() < textboxRect.getWidth() && old_header_rect.getWidth() < mHeaderTextbox->getTextPixelWidth()))
+ {
+ // Expensive text reflow
+ // Update if position or height changes
+ // Update if width reduces
+ // But do not update if text already fits and width increases (arguably LLTextBox::reshape should be smarter, not Accordion)
+ mHeaderTextbox->reshape(textboxRect.getWidth(), textboxRect.getHeight());
+ mHeaderTextbox->setRect(textboxRect);
+ }
if (mHeaderTextbox->getTextPixelWidth() > mHeaderTextbox->getRect().getWidth())
{
@@ -416,8 +428,11 @@ void LLAccordionCtrlTab::reshape(S32 width, S32 height, bool called_from_parent
LLRect headerRect;
headerRect.setLeftTopAndSize(0, height, width, HEADER_HEIGHT);
- mHeader->setRect(headerRect);
- mHeader->reshape(headerRect.getWidth(), headerRect.getHeight());
+ if (mHeader->getRect() != headerRect)
+ {
+ mHeader->setRect(headerRect);
+ mHeader->reshape(headerRect.getWidth(), headerRect.getHeight());
+ }
if (!mDisplayChildren)
return;
@@ -464,7 +479,34 @@ void LLAccordionCtrlTab::onUpdateScrollToChild(const LLUICtrl *cntrl)
// Translate to parent coordinatess to check if we are in visible rectangle
rect.translate(getRect().mLeft, getRect().mBottom);
- if (!getRect().contains(rect))
+ bool needs_to_scroll = false;
+ const LLRect &acc_rect = getRect();
+ if (!acc_rect.contains(rect))
+ {
+ if (acc_rect.mTop < rect.mBottom || acc_rect.mBottom > rect.mTop)
+ {
+ // Content fully not in view
+ needs_to_scroll = true;
+ }
+ else if (acc_rect.getHeight() >= rect.getHeight())
+ {
+ // Content can be displayed fully, but only partially in view
+ needs_to_scroll = true;
+ }
+ else if (acc_rect.mTop <= rect.mTop || acc_rect.mBottom >= rect.mBottom)
+ {
+ // Intersects, but too big to be displayed fully
+ S32 covered_height = acc_rect.mTop > rect.mTop ? rect.mTop - acc_rect.mBottom : acc_rect.mTop - rect.mBottom;
+ constexpr F32 covered_ratio = 0.7f;
+ if (covered_height < covered_ratio * acc_rect.getHeight())
+ {
+ // Try to show bigger portion of the content
+ needs_to_scroll = true;
+ }
+ }
+ // else too big and in the middle of the view as is
+ }
+ if (needs_to_scroll)
{
// for accordition's scroll, height is in pixels
// Back to local coords and calculate position for scroller
@@ -932,7 +974,7 @@ void LLAccordionCtrlTab::adjustContainerPanel(const LLRect& child_rect)
show_hide_scrollbar(child_rect);
updateLayout(child_rect);
}
- else
+ else if (mContainerPanel->getRect() != child_rect)
{
mContainerPanel->reshape(child_rect.getWidth(), child_rect.getHeight());
mContainerPanel->setRect(child_rect);
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index 3fdcf9f7f2..bb0b8ce04f 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -140,7 +140,7 @@ public:
S32 notify(const LLSD& info);
bool notifyChildren(const LLSD& info);
- void draw();
+ virtual void draw();
void storeOpenCloseState();
void restoreOpenCloseState();
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index d2534b3939..0048c44189 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -190,7 +190,7 @@ LLButton::LLButton(const LLButton::Params& p)
// Note: flashing should be allowed in settings.xml (boolean key "EnableButtonFlashing").
S32 flash_count = p.button_flash_count.isProvided()? p.button_flash_count : 0;
F32 flash_rate = p.button_flash_rate.isProvided()? p.button_flash_rate : 0.0f;
- mFlashingTimer = new LLFlashTimer ((LLFlashTimer::callback_t)NULL, flash_count, flash_rate);
+ mFlashingTimer = new LLFlashTimer((LLFlashTimer::callback_t) nullptr, flash_count, flash_rate);
}
else
{
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 890e7c2d1e..f530eceb4b 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -153,7 +153,7 @@ public:
~LLButton();
// For backward compatability only
- typedef boost::function<void(void*)> button_callback_t;
+ typedef std::function<void(void*)> button_callback_t;
void addImageAttributeToXML(LLXMLNodePtr node, const std::string& imageName,
const LLUUID& imageID,const std::string& xmlTagName) const;
diff --git a/indra/llui/llcallbackmap.h b/indra/llui/llcallbackmap.h
index 07775dc30f..3115606d91 100644
--- a/indra/llui/llcallbackmap.h
+++ b/indra/llui/llcallbackmap.h
@@ -29,13 +29,13 @@
#include <map>
#include <string>
-#include <boost/function.hpp>
+#include <functional>
class LLCallbackMap
{
public:
// callback definition.
- typedef boost::function<void* (void* data)> callback_t;
+ typedef std::function<void* (void* data)> callback_t;
typedef std::map<std::string, LLCallbackMap> map_t;
typedef map_t::iterator map_iter_t;
@@ -48,8 +48,8 @@ public:
return (void*)panel;
}
- LLCallbackMap() : mCallback(NULL), mData(NULL) { }
- LLCallbackMap(callback_t callback, void* data = NULL) : mCallback(callback), mData(data) { }
+ LLCallbackMap() : mCallback(nullptr), mData(nullptr) {}
+ LLCallbackMap(callback_t callback, void* data = nullptr) : mCallback(callback), mData(data) {}
callback_t mCallback;
void* mData;
diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h
index 12d8233e0a..9f9cc3e54d 100644
--- a/indra/llui/llclipboard.h
+++ b/indra/llui/llclipboard.h
@@ -27,8 +27,6 @@
#ifndef LL_LLCLIPBOARD_H
#define LL_LLCLIPBOARD_H
-#include <boost/function.hpp>
-
#include "llstring.h"
#include "lluuid.h"
#include "llsingleton.h"
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index f3876ef695..ae676251ff 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -1009,7 +1009,7 @@ void LLComboBox::setKeystrokeOnEsc(bool enable)
void LLComboBox::onTextEntry(LLLineEditor* line_editor)
{
- if (mTextEntryCallback != NULL)
+ if (mTextEntryCallback != nullptr)
{
(mTextEntryCallback)(line_editor, LLSD());
}
@@ -1029,7 +1029,7 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor)
mList->deselectAllItems();
mLastSelectedIndex = -1;
}
- if (mTextChangedCallback != NULL)
+ if (mTextChangedCallback != nullptr)
{
(mTextChangedCallback)(line_editor, LLSD());
}
@@ -1077,7 +1077,7 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor)
// RN: presumably text entry
updateSelection();
}
- if (mTextChangedCallback != NULL)
+ if (mTextChangedCallback != nullptr)
{
(mTextChangedCallback)(line_editor, LLSD());
}
diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
index 8be3eb57e4..d6ea1202d3 100644
--- a/indra/llui/llcombobox.h
+++ b/indra/llui/llcombobox.h
@@ -36,7 +36,6 @@
#include "llrect.h"
#include "llscrolllistctrl.h"
#include "lllineeditor.h"
-#include <boost/function.hpp>
// Classes
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
index 19ae03cdf9..c20e5a806c 100644
--- a/indra/llui/lldockablefloater.cpp
+++ b/indra/llui/lldockablefloater.cpp
@@ -77,7 +77,7 @@ LLDockableFloater::~LLDockableFloater()
bool LLDockableFloater::postBuild()
{
// Remember we should force docking when the floater is opened for the first time
- if (mIsDockedStateForcedCallback != NULL && mIsDockedStateForcedCallback())
+ if (mIsDockedStateForcedCallback != nullptr && mIsDockedStateForcedCallback())
{
mForceDocking = true;
}
diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h
index 9c516e23a4..accd9fddfc 100644
--- a/indra/llui/lldockablefloater.h
+++ b/indra/llui/lldockablefloater.h
@@ -129,7 +129,7 @@ protected:
// Checks if docking should be forced.
// It may be useful e.g. if floater created in mouselook mode (see EXT-5609)
- boost::function<bool ()> mIsDockedStateForcedCallback;
+ std::function<bool()> mIsDockedStateForcedCallback;
private:
std::unique_ptr<LLDockControl> mDockControl;
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index b6ac9c19dd..1f6c3b9f57 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -49,11 +49,11 @@ public:
public:
// callback for a function getting a rect valid for control's position
- typedef boost::function<void (LLRect& )> get_allowed_rect_callback_t;
+ typedef std::function<void (LLRect& )> get_allowed_rect_callback_t;
LOG_CLASS(LLDockControl);
LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
- const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_rect_callback = NULL);
+ const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_rect_callback = nullptr);
virtual ~LLDockControl();
public:
diff --git a/indra/llui/llemojidictionary.cpp b/indra/llui/llemojidictionary.cpp
index 925608e47e..16e6f0591a 100644
--- a/indra/llui/llemojidictionary.cpp
+++ b/indra/llui/llemojidictionary.cpp
@@ -390,14 +390,17 @@ void LLEmojiDictionary::loadEmojis()
continue;
}
+ std::string category;
std::list<std::string> categories = loadCategories(sd);
if (categories.empty())
{
- LL_WARNS() << "Skipping invalid emoji descriptor (no categories)" << LL_ENDL;
- continue;
+ // Should already have a localization for "other symbols"
+ category = "other symbols";
+ }
+ else
+ {
+ category = categories.front();
}
-
- std::string category = categories.front();
if (std::find(mSkipCategories.begin(), mSkipCategories.end(), category) != mSkipCategories.end())
{
diff --git a/indra/llui/llemojihelper.cpp b/indra/llui/llemojihelper.cpp
index b2c59ce775..7cdd19bebc 100644
--- a/indra/llui/llemojihelper.cpp
+++ b/indra/llui/llemojihelper.cpp
@@ -117,7 +117,17 @@ void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, c
S32 top = floater_y - HELPER_FLOATER_OFFSET_Y + rect.getHeight();
rect.setLeftTopAndSize(left, top, rect.getWidth(), rect.getHeight());
pHelperFloater->setRect(rect);
+
+ // Hack: Trying to open floater, search for a match,
+ // and hide floater immediately if no match found,
+ // instead of checking prior to opening
+ //
+ // Supress sounds in case floater won't be shown.
+ // Todo: add some kind of shouldShow(short_code)
+ U8 sound_flags = pHelperFloater->getSoundFlags();
+ pHelperFloater->setSoundFlags(LLView::SILENT);
pHelperFloater->openFloater(LLSD().with("hint", short_code));
+ pHelperFloater->setSoundFlags(sound_flags);
}
void LLEmojiHelper::hideHelper(const LLUICtrl* ctrl_p, bool strict)
diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp
index 54f54653e2..addc3375b3 100644
--- a/indra/llui/llflashtimer.cpp
+++ b/indra/llui/llflashtimer.cpp
@@ -50,7 +50,7 @@ LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
void LLFlashTimer::unset()
{
mUnset = true;
- mCallback = NULL;
+ mCallback = nullptr;
}
bool LLFlashTimer::tick()
diff --git a/indra/llui/llflashtimer.h b/indra/llui/llflashtimer.h
index 4ef70faf2d..1cd1df392b 100644
--- a/indra/llui/llflashtimer.h
+++ b/indra/llui/llflashtimer.h
@@ -28,13 +28,13 @@
#define LL_FLASHTIMER_H
#include "lleventtimer.h"
-#include "boost/function.hpp"
+#include <functional>
class LLFlashTimer : public LLEventTimer
{
public:
- typedef boost::function<void (bool)> callback_t;
+ typedef std::function<void (bool)> callback_t;
/**
* Constructor.
@@ -43,7 +43,7 @@ public:
* @param period - how frequently callback should be called
* @param cb - callback to be called each tick
*/
- LLFlashTimer(callback_t cb = NULL, S32 count = 0, F32 period = 0.0);
+ LLFlashTimer(callback_t cb = nullptr, S32 count = 0, F32 period = 0.0);
~LLFlashTimer() {};
/*virtual*/ bool tick();
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 8178bada42..34eb1ea3fc 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -69,7 +69,7 @@ const LLRect& LLFlatListView::getItemsRect() const
bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/,bool rearrange /*= true*/)
{
if (!item) return false;
- if (value.isUndefined()) return false;
+ if (value.isUndefined()) return false; // item stays an orphan?!!!
//force uniqueness of items, easiest check but unreliable
if (item->getParent() == mItemsPanel) return false;
@@ -537,6 +537,7 @@ bool LLFlatListView::postBuild()
void LLFlatListView::rearrangeItems()
{
+ LL_PROFILE_ZONE_SCOPED;
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
setNoItemsCommentVisible(0==size());
@@ -1132,6 +1133,7 @@ bool LLFlatListView::removeItemPair(item_pair_t* item_pair, bool rearrange)
void LLFlatListView::notifyParentItemsRectChanged()
{
+ LL_PROFILE_ZONE_SCOPED;
S32 comment_height = 0;
// take into account comment text height if exists
@@ -1346,9 +1348,17 @@ bool LLFlatListViewEx::getForceShowingUnmatchedItems() const
return mForceShowingUnmatchedItems;
}
-void LLFlatListViewEx::setForceShowingUnmatchedItems(bool show)
+void LLFlatListViewEx::setForceShowingUnmatchedItems(bool show, bool notify_parent)
+{
+ if (mForceShowingUnmatchedItems != show)
{
mForceShowingUnmatchedItems = show;
+ if (!mFilterSubString.empty())
+ {
+ updateNoItemsMessage(mFilterSubString);
+ filterItems(false, true);
+ }
+ }
}
void LLFlatListViewEx::setFilterSubString(const std::string& filter_str, bool notify_parent)
@@ -1393,7 +1403,7 @@ bool LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
return false;
}
-void LLFlatListViewEx::filterItems(bool re_sort, bool notify_parent)
+bool LLFlatListViewEx::filterItems(bool re_sort, bool notify_parent)
{
std::string cur_filter = mFilterSubString;
LLStringUtil::toUpper(cur_filter);
@@ -1416,8 +1426,11 @@ void LLFlatListViewEx::filterItems(bool re_sort, bool notify_parent)
if (visibility_changed && notify_parent)
{
+ rearrangeItems();
notifyParentItemsRectChanged();
+ return true;
}
+ return false;
}
bool LLFlatListViewEx::hasMatchedItems()
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index 6271231183..39afa33be8 100644
--- a/indra/llui/llflatlistview.h
+++ b/indra/llui/llflatlistview.h
@@ -484,7 +484,11 @@ public:
bool getForceShowingUnmatchedItems() const;
- void setForceShowingUnmatchedItems(bool show);
+ /**
+ * Sets filtered out items to stay visible. Can result in rect changes,
+ * so can notify_parent if rect changes
+ */
+ void setForceShowingUnmatchedItems(bool show, bool notify_parent);
/**
* Sets up new filter string and filters the list.
@@ -495,8 +499,9 @@ public:
/**
* Filters the list, rearranges and notifies parent about shape changes.
* Derived classes may want to overload rearrangeItems() to exclude repeated separators after filtration.
+ * Returns true in case of changes
*/
- void filterItems(bool re_sort, bool notify_parent);
+ bool filterItems(bool re_sort, bool notify_parent);
/**
* Returns true if last call of filterItems() found at least one matching item
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index fd07b2ec5d..52a5e3dbd6 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2274,7 +2274,7 @@ void LLFloater::drawConeToOwner(F32 &context_cone_opacity,
LLRect local_rect = getLocalRect();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLEnable(GL_CULL_FACE);
+ LLGLEnable cull_face(GL_CULL_FACE);
gGL.begin(LLRender::TRIANGLE_STRIP);
{
gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity);
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index 94a67c8d8b..24d1476dda 100644
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
@@ -30,8 +30,8 @@
#include "llrect.h"
#include "llsd.h"
+#include <functional>
#include <list>
-#include <boost/function.hpp>
//*******************************************************
//
@@ -41,7 +41,7 @@
class LLFloater;
class LLUICtrl;
-typedef boost::function<LLFloater* (const LLSD& key)> LLFloaterBuildFunc;
+typedef std::function<LLFloater* (const LLSD& key)> LLFloaterBuildFunc;
class LLFloaterReg
{
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index 0d7c98294f..7544a44478 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -32,11 +32,11 @@
const F32 FOCUS_FADE_TIME = 0.3f;
-LLFocusableElement::LLFocusableElement()
-: mFocusLostCallback(NULL),
- mFocusReceivedCallback(NULL),
- mFocusChangedCallback(NULL),
- mTopLostCallback(NULL)
+LLFocusableElement::LLFocusableElement() :
+ mFocusLostCallback(nullptr),
+ mFocusReceivedCallback(nullptr),
+ mFocusChangedCallback(nullptr),
+ mTopLostCallback(nullptr)
{
}
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index b664065532..db4ab8487e 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1510,6 +1510,7 @@ bool LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
&& ( count > 0 && (hasVisibleChildren()) ))) && // show menu only if selected items are visible
!hide_folder_menu)
{
+ LL_INFOS("Inventory") << "Opening inventory menu from path: " << getPathname() << LL_ENDL;
if (mCallbackRegistrar)
{
mCallbackRegistrar->pushScope();
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index bdce9dec54..368a86ea84 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -221,6 +221,7 @@ public:
void scrollToShowSelection();
void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; }
+ LLScrollContainer* getScrollContainer() { return mScrollContainer; }
LLRect getVisibleRect();
bool search(LLFolderViewItem* first_item, const std::string &search_string, bool backward);
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 6d0cfcba95..878f1cb856 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -31,11 +31,12 @@
#include "llfolderviewitem.h"
#include "llfolderview.h"
#include "llfolderviewmodel.h"
-#include "llpanel.h"
#include "llcallbacklist.h"
#include "llcriticaldamp.h"
#include "llclipboard.h"
#include "llfocusmgr.h" // gFocusMgr
+#include "llnotificationsutil.h"
+#include "llpanel.h"
#include "lltrans.h"
#include "llwindow.h"
@@ -60,7 +61,11 @@ LLUIColor LLFolderViewItem::sSearchStatusColor;
S32 LLFolderViewItem::sTopPad = 0;
LLUIImagePtr LLFolderViewItem::sFolderArrowImg;
LLUIImagePtr LLFolderViewItem::sSelectionImg;
+LLUIImagePtr LLFolderViewItem::sFavoriteImg;
+LLUIImagePtr LLFolderViewItem::sFavoriteContentImg;
LLFontGL* LLFolderViewItem::sSuffixFont = nullptr;
+LLUIColor LLFolderViewItem::sFavoriteColor;
+bool LLFolderViewItem::sColorSetInitialized = false;
// only integers can be initialized in header
const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
@@ -68,6 +73,9 @@ const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
const LLColor4U DEFAULT_WHITE(255, 255, 255);
+constexpr S32 FAVORITE_IMAGE_SIZE = 14;
+constexpr S32 FAVORITE_IMAGE_PAD = 3;
+
//static
LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
@@ -102,6 +110,8 @@ void LLFolderViewItem::initClass()
sTopPad = default_params.item_top_pad;
sFolderArrowImg = default_params.folder_arrow_image;
sSelectionImg = default_params.selection_image;
+ sFavoriteImg = default_params.favorite_image;
+ sFavoriteContentImg = default_params.favorite_content_image;
sSuffixFont = getLabelFontForStyle(LLFontGL::NORMAL);
sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
@@ -121,6 +131,8 @@ void LLFolderViewItem::cleanupClass()
sFonts.clear();
sFolderArrowImg = nullptr;
sSelectionImg = nullptr;
+ sFavoriteImg = nullptr;
+ sFavoriteContentImg = nullptr;
sSuffixFont = nullptr;
}
@@ -129,13 +141,15 @@ void LLFolderViewItem::cleanupClass()
LLFolderViewItem::Params::Params()
: root(),
listener(),
+ favorite_image("favorite_image"),
+ favorite_content_image("favorite_content_image"),
folder_arrow_image("folder_arrow_image"),
folder_indentation("folder_indentation"),
selection_image("selection_image"),
item_height("item_height"),
item_top_pad("item_top_pad"),
creation_date(),
- allow_wear("allow_wear", true),
+ marketplace_item("marketplace_item", false),
allow_drop("allow_drop", true),
font_color("font_color"),
font_highlight_color("font_highlight_color"),
@@ -155,6 +169,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
: LLView(p),
mLabelWidth(0),
mLabelWidthDirty(false),
+ mIsFavorite(false),
+ mHasFavorites(false),
mSuffixNeedsRefresh(false),
mLabelPaddingRight(DEFAULT_LABEL_PADDING_RIGHT),
mParentFolder( NULL ),
@@ -175,7 +191,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mRoot(p.root),
mViewModelItem(p.listener),
mIsMouseOverTitle(false),
- mAllowWear(p.allow_wear),
+ mMarketplaceItem(p.marketplace_item),
mAllowDrop(p.allow_drop),
mFontColor(p.font_color),
mFontHighlightColor(p.font_highlight_color),
@@ -189,6 +205,21 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mMaxFolderItemOverlap(p.max_folder_item_overlap),
mDoubleClickOverride(p.double_click_override)
{
+ if (!sColorSetInitialized)
+ {
+ sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+ sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+ sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
+ sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+ sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+ sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
+ sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
+ sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
+ sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
+ sFavoriteColor = LLUIColorTable::instance().getColor("InventoryFavoriteColor", DEFAULT_WHITE);
+ sColorSetInitialized = true;
+ }
+
if (mViewModelItem)
{
mViewModelItem->setFolderViewItem(this);
@@ -211,6 +242,7 @@ bool LLFolderViewItem::postBuild()
// getDisplayName() is expensive (due to internal getLabelSuffix() and name building)
// it also sets search strings so it requires a filter reset
mLabel = utf8str_to_wstring(vmi->getDisplayName());
+ mIsFavorite = vmi->isFavorite() && !vmi->isItemInTrash();
setToolTip(vmi->getName());
// Dirty the filter flag of the model from the view (CHUI-849)
@@ -325,6 +357,7 @@ void LLFolderViewItem::refresh()
mLabel = utf8str_to_wstring(vmi.getDisplayName());
mLabelFontBuffer.reset();
+ mIsFavorite = vmi.isFavorite() && !vmi.isItemInTrash();
setToolTip(vmi.getName());
// icons are slightly expensive to get, can be optimized
// see LLInventoryIcon::getIcon()
@@ -359,6 +392,8 @@ void LLFolderViewItem::refreshSuffix()
mIconOpen = vmi->getIconOpen();
mIconOverlay = vmi->getIconOverlay();
+ mIsFavorite = vmi->isFavorite() && !vmi->isItemInTrash();
+
if (mRoot->useLabelSuffix())
{
// Very Expensive!
@@ -428,6 +463,10 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height )
}
mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel.c_str()) + getLabelFontForStyle(LLFontGL::NORMAL)->getWidth(mLabelSuffix.c_str()) + mLabelPaddingRight;
mLabelWidthDirty = false;
+ if (mIsFavorite)
+ {
+ mLabelWidth += FAVORITE_IMAGE_SIZE + FAVORITE_IMAGE_PAD;
+ }
}
*width = llmax(*width, mLabelWidth);
@@ -554,10 +593,15 @@ void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
void LLFolderViewItem::openItem( void )
{
- if (mAllowWear || !getViewModelItem()->isItemWearable())
+ if (!mMarketplaceItem || !getViewModelItem()->isItemWearable())
{
getViewModelItem()->openItem();
}
+ else if (mMarketplaceItem)
+ {
+ // Wearing an object from any listing, active or not, is verbotten
+ LLNotificationsUtil::add("AlertMerchantListingCannotWear");
+ }
}
void LLFolderViewItem::rename(const std::string& new_name)
@@ -771,6 +815,45 @@ void LLFolderViewItem::drawOpenFolderArrow()
}
}
+void LLFolderViewItem::drawFavoriteIcon()
+{
+ static LLUICachedControl<bool> draw_star("InventoryFavoritesUseStar", true);
+ static LLUICachedControl<bool> draw_hollow_star("InventoryFavoritesUseHollowStar", true);
+
+ LLUIImage* favorite_image = nullptr;
+ if (draw_star && mIsFavorite)
+ {
+ favorite_image = sFavoriteImg;
+ }
+ else if (draw_hollow_star && mHasFavorites && !isOpen())
+ {
+ favorite_image = sFavoriteContentImg;
+ }
+
+ if (favorite_image)
+ {
+ S32 x_offset = 0;
+ LLScrollContainer* scroll = mRoot->getScrollContainer();
+ if (scroll)
+ {
+ S32 width = scroll->getVisibleContentRect().getWidth();
+ S32 offset = scroll->getDocPosHorizontal();
+ x_offset = width + offset;
+ }
+ else
+ {
+ x_offset = getRect().getWidth();
+ }
+ gl_draw_scaled_image(
+ x_offset - FAVORITE_IMAGE_SIZE - FAVORITE_IMAGE_PAD,
+ getRect().getHeight() - mItemHeight + FAVORITE_IMAGE_PAD,
+ FAVORITE_IMAGE_SIZE,
+ FAVORITE_IMAGE_SIZE,
+ favorite_image->getImage(),
+ sFgColor);
+ }
+}
+
/*virtual*/ bool LLFolderViewItem::isHighlightAllowed()
{
return mIsSelected;
@@ -928,6 +1011,7 @@ void LLFolderViewItem::draw()
{
drawOpenFolderArrow();
}
+ drawFavoriteIcon();
drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
@@ -999,7 +1083,20 @@ void LLFolderViewItem::draw()
}
}
- LLColor4 color = (mIsSelected && filled) ? mFontHighlightColor : mFontColor;
+ static LLUICachedControl<bool> highlight_color("InventoryFavoritesColorText", true);
+ LLColor4 color;
+ if (mIsSelected && filled)
+ {
+ color = mFontHighlightColor;
+ }
+ else if (mIsFavorite && highlight_color)
+ {
+ color = sFavoriteColor;
+ }
+ else
+ {
+ color = mFontColor;
+ }
if (isFadeItem())
{
@@ -1093,7 +1190,8 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
mIsFolderComplete(false), // folder might have children that are not loaded yet.
mAreChildrenInited(false), // folder might have children that are not built yet.
mLastArrangeGeneration( -1 ),
- mLastCalculatedWidth(0)
+ mLastCalculatedWidth(0),
+ mFavoritesDirtyFlags(0)
{
}
@@ -1119,6 +1217,11 @@ LLFolderViewFolder::~LLFolderViewFolder( void )
// The LLView base class takes care of object destruction. make sure that we
// don't have mouse or keyboard focus
gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
+
+ if (mFavoritesDirtyFlags)
+ {
+ gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, this);
+ }
}
// addToFolder() returns true if it succeeds. false otherwise
@@ -1762,6 +1865,148 @@ bool LLFolderViewFolder::isMovable()
return true;
}
+void LLFolderViewFolder::updateHasFavorites(bool new_childs_value)
+{
+ if (mFavoritesDirtyFlags == 0)
+ {
+ gIdleCallbacks.addFunction(&LLFolderViewFolder::onIdleUpdateFavorites, this);
+ }
+ if (new_childs_value)
+ {
+ mFavoritesDirtyFlags |= FAVORITE_ADDED;
+ }
+ else
+ {
+ mFavoritesDirtyFlags |= FAVORITE_REMOVED;
+ }
+}
+
+void LLFolderViewFolder::onIdleUpdateFavorites(void* data)
+{
+ LLFolderViewFolder* self = reinterpret_cast<LLFolderViewFolder*>(data);
+ if (self->mFavoritesDirtyFlags == FAVORITE_CLEANUP)
+ {
+ // parent or child already processed the update, clean the callback
+ self->mFavoritesDirtyFlags = 0;
+ gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, data);
+ return;
+ }
+
+ if (self->mFavoritesDirtyFlags == 0)
+ {
+ llassert(false); // should not happen, everything that sets to 0 should clean callback
+ gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, data);
+ return;
+ }
+
+ if (self->getViewModelItem()->isItemInTrash())
+ {
+ // do not display favorite-stars in trash
+ self->mFavoritesDirtyFlags = 0;
+ gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, self);
+ return;
+ }
+
+ if (self->mFavoritesDirtyFlags == FAVORITE_ADDED)
+ {
+ if (!self->mHasFavorites)
+ {
+ // propagate up, exclude root
+ LLFolderViewFolder* parent = self;
+ while (parent
+ && (!parent->hasFavorites() || parent->mFavoritesDirtyFlags)
+ && !parent->getViewModelItem()->isAgentInventoryRoot())
+ {
+ parent->setHasFavorites(true);
+ if (parent->mFavoritesDirtyFlags)
+ {
+ // Parent will remove onIdleUpdateFavorites later, don't remove now,
+ // We are inside gIdleCallbacks. Removing 'self' callback is safe,
+ // but removing 'parent' can invalidate following iterator
+ parent->mFavoritesDirtyFlags = FAVORITE_CLEANUP;
+ }
+ parent = parent->getParentFolder();
+ }
+ }
+ else
+ {
+ // already up to date
+ self->mFavoritesDirtyFlags = 0;
+ gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, self);
+ }
+ }
+ else if (self->mFavoritesDirtyFlags > FAVORITE_ADDED)
+ {
+ // full check
+ LLFolderViewFolder* parent = self;
+ while (parent && !parent->getViewModelItem()->isAgentInventoryRoot())
+ {
+ bool has_favorites = false;
+ for (items_t::iterator iter = parent->mItems.begin();
+ iter != parent->mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ if ((*iit)->isFavorite())
+ {
+ has_favorites = true;
+ break;
+ }
+ }
+
+ for (folders_t::iterator iter = parent->mFolders.begin();
+ iter != parent->mFolders.end() && !has_favorites;)
+ {
+ folders_t::iterator fit = iter++;
+ if ((*fit)->isFavorite() || (*fit)->hasFavorites())
+ {
+ has_favorites = true;
+ break;
+ }
+ }
+
+ if (!has_favorites)
+ {
+ if (parent->hasFavorites())
+ {
+ parent->setHasFavorites(false);
+ }
+ else
+ {
+ // Nothing changed
+ break;
+ }
+ }
+ else
+ {
+ // propagate up, exclude root
+ while (parent
+ && (!parent->hasFavorites() || parent->mFavoritesDirtyFlags)
+ && !parent->getViewModelItem()->isAgentInventoryRoot())
+ {
+ parent->setHasFavorites(true);
+ if (parent->mFavoritesDirtyFlags)
+ {
+ // Parent will remove onIdleUpdateFavorites later, don't remove now,
+ // We are inside gIdleCallbacks. Removing 'self' callback is safe,
+ // but removing 'parent' can invalidate following iterator
+ parent->mFavoritesDirtyFlags = FAVORITE_CLEANUP;
+ }
+ parent = parent->getParentFolder();
+ }
+ break;
+ }
+ if (parent->mFavoritesDirtyFlags)
+ {
+ // Parent will remove onIdleUpdateFavorites later, don't remove now.
+ // We are inside gIdleCallbacks. Removing 'self' callback is safe,
+ // but removing 'parent' can invalidate following iterator
+ parent->mFavoritesDirtyFlags = FAVORITE_CLEANUP;
+ }
+ parent = parent->getParentFolder();
+ }
+ }
+}
+
bool LLFolderViewFolder::isRemovable()
{
@@ -1869,10 +2114,14 @@ void LLFolderViewFolder::setOpen(bool openitem)
{
// navigateToFolder can destroy this view
// delay it in case setOpen was called from click or key processing
- doOnIdleOneTime([this]()
- {
- getViewModelItem()->navigateToFolder();
- });
+ LLPointer<LLFolderViewModelItem> view_model_item = mViewModelItem;
+ doOnIdleOneTime([view_model_item]()
+ {
+ if (view_model_item.notNull())
+ {
+ view_model_item.get()->navigateToFolder();
+ }
+ });
}
else
{
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 2ee018a90a..23d794bf26 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -50,7 +50,9 @@ class LLFolderViewItem : public LLView
public:
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
- Optional<LLUIImage*> folder_arrow_image,
+ Optional<LLUIImage*> favorite_image,
+ favorite_content_image,
+ folder_arrow_image,
selection_image;
Mandatory<LLFolderView*> root;
Mandatory<LLFolderViewModelItem*> listener;
@@ -60,7 +62,7 @@ public:
item_top_pad;
Optional<time_t> creation_date;
- Optional<bool> allow_wear;
+ Optional<bool> marketplace_item;
Optional<bool> allow_drop;
Optional<LLUIColor> font_color;
@@ -93,6 +95,8 @@ protected:
LLWString mLabel;
S32 mLabelWidth;
bool mLabelWidthDirty;
+ bool mIsFavorite;
+ bool mHasFavorites;
S32 mLabelPaddingRight;
LLFolderViewFolder* mParentFolder;
LLPointer<LLFolderViewModelItem> mViewModelItem;
@@ -122,7 +126,7 @@ protected:
mIsCurSelection,
mDragAndDropTarget,
mIsMouseOverTitle,
- mAllowWear,
+ mMarketplaceItem,
mAllowDrop,
mSingleFolderMode,
mDoubleClickOverride,
@@ -133,6 +137,7 @@ protected:
LLUIColor mFontColor;
LLUIColor mFontHighlightColor;
+ static bool sColorSetInitialized;
// For now assuming all colors are the same in derived classes.
static LLUIColor sFgColor;
@@ -145,6 +150,8 @@ protected:
static LLUIColor sFilterTextColor;
static LLUIColor sSuffixColor;
static LLUIColor sSearchStatusColor;
+ static LLUIColor sFavoriteColor;
+
// this is an internal method used for adding items to folders. A
// no-op at this level, but reimplemented in derived classes.
@@ -208,6 +215,8 @@ public:
// Returns true is this object and all of its children can be moved
virtual bool isMovable();
+ bool isFavorite() const { return mIsFavorite; }
+
// destroys this item recursively
virtual void destroyView();
@@ -298,6 +307,7 @@ public:
// virtual void handleDropped();
virtual void draw();
void drawOpenFolderArrow();
+ void drawFavoriteIcon();
void drawHighlight(bool showContent, bool hasKeyboardFocus, const LLUIColor& selectColor, const LLUIColor& flashColor, const LLUIColor& outlineColor, const LLUIColor& mouseOverColor);
void drawLabel(const LLFontGL* font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x);
virtual bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
@@ -311,6 +321,8 @@ private:
static S32 sTopPad;
static LLUIImagePtr sFolderArrowImg;
static LLUIImagePtr sSelectionImg;
+ static LLUIImagePtr sFavoriteImg;
+ static LLUIImagePtr sFavoriteContentImg;
static LLFontGL* sSuffixFont;
LLFontVertexBuffer mLabelFontBuffer;
@@ -400,6 +412,19 @@ public:
// Returns true is this object and all of its children can be moved
virtual bool isMovable();
+ bool isFavorite() const { return mIsFavorite; }
+ bool hasFavorites() const { return mHasFavorites; }
+ void setHasFavorites(bool val) { mHasFavorites = val; }
+ void updateHasFavorites(bool new_childs_value);
+private:
+ static void onIdleUpdateFavorites(void* data);
+
+ constexpr static S32 FAVORITE_ADDED = 1;
+ constexpr static S32 FAVORITE_REMOVED = 2;
+ constexpr static S32 FAVORITE_CLEANUP = 4;
+ S32 mFavoritesDirtyFlags { 0 };
+public:
+
// destroys this folder, and all children
virtual void destroyView();
void destroyRoot();
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 9372818ca5..07e8b890b8 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -162,6 +162,7 @@ public:
virtual void navigateToFolder(bool new_window = false, bool change_mode = false) = 0;
+ virtual bool isFavorite() const = 0;
virtual bool isItemWearable() const { return false; }
virtual bool isItemRenameable() const = 0;
@@ -170,7 +171,8 @@ public:
virtual bool isItemMovable( void ) const = 0; // Can be moved to another folder
virtual void move( LLFolderViewModelItem* parent_listener ) = 0;
- virtual bool isItemRemovable( bool check_worn = true ) const = 0; // Can be destroyed
+ virtual bool isItemRemovable( bool check_worn = true) const = 0; // Can be destroyed
+ virtual bool isItemInTrash(void) const = 0;
virtual bool removeItem() = 0;
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
@@ -183,6 +185,9 @@ public:
virtual void pasteFromClipboard() = 0;
virtual void pasteLinkFromClipboard() = 0;
+ virtual bool isAgentInventory() const = 0;
+ virtual bool isAgentInventoryRoot() const = 0;
+
virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
virtual bool potentiallyVisible() = 0; // is the item definitely visible or we haven't made up our minds yet?
@@ -219,6 +224,7 @@ public:
virtual S32 getSortVersion() = 0;
virtual void setSortVersion(S32 version) = 0;
virtual void setParent(LLFolderViewModelItem* parent) = 0;
+ virtual const LLFolderViewModelItem* getParent() = 0;
virtual bool hasParent() = 0;
protected:
@@ -249,14 +255,14 @@ public:
mChildren.clear();
}
- void requestSort() { mSortVersion = -1; }
- S32 getSortVersion() { return mSortVersion; }
- void setSortVersion(S32 version) { mSortVersion = version;}
+ void requestSort() override { mSortVersion = -1; }
+ S32 getSortVersion() override { return mSortVersion; }
+ void setSortVersion(S32 version) override { mSortVersion = version;}
- S32 getLastFilterGeneration() const { return mLastFilterGeneration; }
+ S32 getLastFilterGeneration() const override { return mLastFilterGeneration; }
S32 getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; }
- S32 getMarkedDirtyGeneration() const { return mMarkedDirtyGeneration; }
- void dirtyFilter()
+ S32 getMarkedDirtyGeneration() const override { return mMarkedDirtyGeneration; }
+ void dirtyFilter() override
{
if(mMarkedDirtyGeneration < 0)
{
@@ -271,7 +277,7 @@ public:
mParent->dirtyFilter();
}
}
- void dirtyDescendantsFilter()
+ void dirtyDescendantsFilter() override
{
mMostFilteredDescendantGeneration = -1;
if (mParent)
@@ -279,13 +285,13 @@ public:
mParent->dirtyDescendantsFilter();
}
}
- bool hasFilterStringMatch();
- std::string::size_type getFilterStringOffset();
- std::string::size_type getFilterStringSize();
+ bool hasFilterStringMatch() override;
+ std::string::size_type getFilterStringOffset() override;
+ std::string::size_type getFilterStringSize() override;
- typedef std::list<LLFolderViewModelItem*> child_list_t;
+ typedef std::list<LLPointer<LLFolderViewModelItem> > child_list_t;
- virtual void addChild(LLFolderViewModelItem* child)
+ virtual void addChild(LLFolderViewModelItem* child) override
{
mChildren.push_back(child);
child->setParent(this);
@@ -293,15 +299,15 @@ public:
requestSort();
}
- virtual void removeChild(LLFolderViewModelItem* child)
+ virtual void removeChild(LLFolderViewModelItem* child) override final
{
- mChildren.remove(child);
child->setParent(NULL);
+ mChildren.remove(child);
dirtyDescendantsFilter();
dirtyFilter();
}
- virtual void clearChildren()
+ virtual void clearChildren() override
{
// We are working with models that belong to views as LLPointers, clean the list, let poiters handle the rest
std::for_each(mChildren.begin(), mChildren.end(), [](LLFolderViewModelItem* c) {c->setParent(NULL); });
@@ -314,7 +320,7 @@ public:
child_list_t::const_iterator getChildrenEnd() const { return mChildren.end(); }
child_list_t::size_type getChildrenCount() const { return mChildren.size(); }
- void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0)
+ void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) override
{
mPassedFilter = passed;
mLastFilterGeneration = filter_generation;
@@ -323,20 +329,20 @@ public:
mMarkedDirtyGeneration = -1;
}
- void setPassedFolderFilter(bool passed, S32 filter_generation)
+ void setPassedFolderFilter(bool passed, S32 filter_generation) override
{
mPassedFolderFilter = passed;
mLastFolderFilterGeneration = filter_generation;
}
- virtual bool potentiallyVisible()
+ virtual bool potentiallyVisible() override
{
return passedFilter() // we've passed the filter
|| (getLastFilterGeneration() < mRootViewModel.getFilter().getFirstSuccessGeneration()) // or we don't know yet
|| descendantsPassedFilter();
}
- virtual bool passedFilter(S32 filter_generation = -1)
+ virtual bool passedFilter(S32 filter_generation = -1) override
{
if (filter_generation < 0)
{
@@ -347,7 +353,7 @@ public:
return passed_folder_filter && (passed_filter || descendantsPassedFilter(filter_generation));
}
- virtual bool descendantsPassedFilter(S32 filter_generation = -1)
+ virtual bool descendantsPassedFilter(S32 filter_generation = -1) override
{
if (filter_generation < 0)
{
@@ -356,10 +362,10 @@ public:
return mMostFilteredDescendantGeneration >= filter_generation;
}
-
protected:
- virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; }
- virtual bool hasParent() { return mParent != NULL; }
+ virtual void setParent(LLFolderViewModelItem* parent) override final { mParent = parent; }
+ virtual const LLFolderViewModelItem* getParent() override { return mParent; };
+ virtual bool hasParent() override { return mParent != NULL; }
S32 mSortVersion;
bool mPassedFilter;
@@ -376,7 +382,7 @@ protected:
LLFolderViewModelItem* mParent;
LLFolderViewModelInterface& mRootViewModel;
- void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
+ void setFolderViewItem(LLFolderViewItem* folder_view_item) override { mFolderViewItem = folder_view_item;}
LLFolderViewItem* mFolderViewItem;
};
@@ -390,15 +396,15 @@ public:
mFolderView(NULL)
{}
- virtual void requestSortAll()
+ virtual void requestSortAll() override
{
// sort everything
mTargetSortVersion++;
}
- virtual std::string getStatusText(bool is_empty_folder = false);
- virtual void filter();
+ virtual std::string getStatusText(bool is_empty_folder = false) override;
+ virtual void filter() override;
- void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;}
+ void setFolderView(LLFolderView* folder_view) override { mFolderView = folder_view;}
protected:
bool needsSort(class LLFolderViewModelItem* item);
@@ -426,16 +432,16 @@ public:
virtual SortType& getSorter() { return *mSorter; }
virtual const SortType& getSorter() const { return *mSorter; }
- virtual void setSorter(const SortType& sorter) { mSorter.reset(new SortType(sorter)); requestSortAll(); }
+ virtual void setSorter(const SortType& sorter) { mSorter = std::make_unique<SortType>(sorter); requestSortAll(); }
- virtual FilterType& getFilter() { return *mFilter; }
- virtual const FilterType& getFilter() const { return *mFilter; }
- virtual void setFilter(const FilterType& filter) { mFilter.reset(new FilterType(filter)); }
+ virtual FilterType& getFilter() override { return *mFilter; }
+ virtual const FilterType& getFilter() const override { return *mFilter; }
+ virtual void setFilter(const FilterType& filter) { mFilter = std::make_unique<FilterType>(filter); }
// By default, we assume the content is available. If a network fetch mechanism is implemented for the model,
// this method needs to be overloaded and return the relevant fetch status.
- virtual bool contentsReady() { return true; }
- virtual bool isFolderComplete(LLFolderViewFolder* folder) { return true; }
+ virtual bool contentsReady() override { return true; }
+ virtual bool isFolderComplete(LLFolderViewFolder* folder) override { return true; }
struct ViewModelCompare
{
@@ -456,7 +462,7 @@ public:
const SortType& mSorter;
};
- void sort(LLFolderViewFolder* folder)
+ void sort(LLFolderViewFolder* folder) override
{
if (needsSort(folder->getViewModelItem()))
{
diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h
index da5570d922..953963b683 100644
--- a/indra/llui/llfunctorregistry.h
+++ b/indra/llui/llfunctorregistry.h
@@ -31,8 +31,6 @@
#include <string>
#include <map>
-#include <boost/function.hpp>
-
#include "llsd.h"
#include "llsingleton.h"
diff --git a/indra/llui/lllazyvalue.h b/indra/llui/lllazyvalue.h
index 622e69ce95..fc15ead032 100644
--- a/indra/llui/lllazyvalue.h
+++ b/indra/llui/lllazyvalue.h
@@ -28,15 +28,16 @@
#ifndef LL_LAZY_VALUE_H
#define LL_LAZY_VALUE_H
-#include <boost/function.hpp>
+#include <functional>
+#include <type_traits>
// Holds on to a value of type T *or* calls a functor to generate a value of type T
template<typename T>
class LLLazyValue
{
public:
- typedef typename boost::add_reference<typename boost::add_const<T>::type>::type T_const_ref;
- typedef typename boost::function<T_const_ref (void)> function_type;
+ typedef typename std::add_lvalue_reference<typename std::add_const<T>::type>::type T_const_ref;
+ typedef typename std::function<T_const_ref (void)> function_type;
public:
LLLazyValue(const function_type& value)
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 45dab88e87..b534c8d4e8 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -2230,6 +2230,9 @@ void LLLineEditor::clear()
{
mText.clear();
setCursor(0);
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
}
//virtual
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 7533f76f1d..3f762822ee 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -60,7 +60,7 @@ class LLLineEditor
{
public:
- typedef boost::function<void (LLLineEditor* caller)> keystroke_callback_t;
+ typedef std::function<void (LLLineEditor* caller)> keystroke_callback_t;
struct MaxLength : public LLInitParam::ChoiceBlock<MaxLength>
{
@@ -259,7 +259,7 @@ public:
void setSelectAllonCommit(bool b) { mSelectAllonCommit = b; }
void onKeystroke();
- typedef boost::function<void (LLLineEditor* caller, void* user_data)> callback_t;
+ typedef std::function<void (LLLineEditor* caller, void* user_data)> callback_t;
void setKeystrokeCallback(callback_t callback, void* user_data);
void setMaxTextLength(S32 max_text_length);
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index c11b42a348..6ba31c251e 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -46,6 +46,7 @@
#include "llfocusmgr.h"
#include "llcoord.h"
#include "llwindow.h"
+#include "llemojihelper.h"
#include "llcriticaldamp.h"
#include "lluictrlfactory.h"
@@ -1411,6 +1412,7 @@ void LLMenuItemBranchDownGL::openMenu( void )
}
else
{
+ LLEmojiHelper::instance().hideHelper(nullptr, true);
if (branch->getTornOff())
{
LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent());
@@ -4402,3 +4404,17 @@ bool LLContextMenu::addChild(LLView* view, S32 tab_group)
return addContextChild(view, tab_group);
}
+void LLContextMenu::deleteAllChildren()
+{
+ mHoverItem = nullptr;
+ LLMenuGL::deleteAllChildren();
+}
+
+void LLContextMenu::removeChild(LLView* ctrl)
+{
+ if (ctrl == mHoverItem)
+ {
+ mHoverItem = nullptr;
+ }
+ LLMenuGL::removeChild(ctrl);
+}
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index ff9456acc6..bca0a731fc 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -37,7 +37,8 @@
#include "llfloater.h"
#include "lluistring.h"
#include "llview.h"
-#include <boost/function.hpp>
+
+#include <boost/bind.hpp>
extern S32 MENU_BAR_HEIGHT;
extern S32 MENU_BAR_WIDTH;
@@ -729,6 +730,8 @@ public:
virtual bool handleRightMouseUp ( S32 x, S32 y, MASK mask );
virtual bool addChild (LLView* view, S32 tab_group = 0);
+ /*virtual*/ void deleteAllChildren();
+ /*virtual*/ void removeChild(LLView* ctrl);
LLHandle<LLContextMenu> getHandle() { return getDerivedHandle<LLContextMenu>(); }
diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp
index c5c31f7252..225ff607ad 100644
--- a/indra/llui/llmodaldialog.cpp
+++ b/indra/llui/llmodaldialog.cpp
@@ -28,6 +28,7 @@
#include "llmodaldialog.h"
+#include "llemojihelper.h"
#include "llfocusmgr.h"
#include "v4color.h"
#include "v2math.h"
@@ -35,6 +36,7 @@
#include "llwindow.h"
#include "llkeyboard.h"
#include "llmenugl.h"
+
// static
std::list<LLModalDialog*> LLModalDialog::sModalStack;
@@ -98,7 +100,7 @@ void LLModalDialog::onOpen(const LLSD& key)
{
if (mModal)
{
- // If Modal, Hide the active modal dialog
+ // If Modal, hide the active modal dialog
if (!sModalStack.empty())
{
LLModalDialog* front = sModalStack.front();
@@ -155,6 +157,12 @@ void LLModalDialog::setVisible( bool visible )
{
if( visible )
{
+ // Hide all menus currently shown
+ LLMenuGL::sMenuContainer->hideMenus();
+
+ // Hide EmojiPicker if it is shown
+ LLEmojiHelper::instance().hideHelper(nullptr, true);
+
// This is a modal dialog. It sucks up all mouse and keyboard operations.
gFocusMgr.setMouseCapture( this );
@@ -301,7 +309,6 @@ void LLModalDialog::centerOnScreen()
centerWithin(LLRect(0, 0, ll_round(window_size.mV[VX]), ll_round(window_size.mV[VY])));
}
-
// static
void LLModalDialog::onAppFocusLost()
{
@@ -333,6 +340,7 @@ void LLModalDialog::onAppFocusGained()
}
}
+// static
void LLModalDialog::shutdownModals()
{
// This method is only for use during app shutdown. ~LLModalDialog()
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index a05feab1d9..0ffe6cff5e 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -457,7 +457,7 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
mTags.push_back(tag.value);
}
- mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form));
+ mForm = std::make_shared<LLNotificationForm>(p.name, p.form_ref.form);
}
LLNotificationVisibilityRule::LLNotificationVisibilityRule(const LLNotificationVisibilityRule::Rule &p)
@@ -875,7 +875,7 @@ void LLNotification::init(const std::string& template_name, const LLSD& form_ele
// TODO: something like this so that a missing alert is sensible:
//mSubstitutions["_ARGS"] = get_all_arguments_as_text(mSubstitutions);
- mForm = LLNotificationFormPtr(new LLNotificationForm(*mTemplatep->mForm));
+ mForm = std::make_shared<LLNotificationForm>(*mTemplatep->mForm);
mForm->append(form_elements);
// apply substitution to form labels
@@ -1249,7 +1249,7 @@ LLNotifications::LLNotifications()
: LLNotificationChannelBase(LLNotificationFilters::includeEverything),
mIgnoreAllNotifications(false)
{
- mListener.reset(new LLNotificationsListener(*this));
+ mListener = std::make_unique<LLNotificationsListener>(*this);
LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
// touch the instance tracker for notification channels, so that it will still be around in our destructor
@@ -1487,7 +1487,7 @@ bool LLNotifications::templateExists(std::string_view name)
void LLNotifications::forceResponse(const LLNotification::Params& params, S32 option)
{
- LLNotificationPtr temp_notify(new LLNotification(params));
+ LLNotificationPtr temp_notify = std::make_shared<LLNotification>(params);
if (!temp_notify->getForm())
{
@@ -1653,7 +1653,7 @@ bool LLNotifications::loadTemplates()
replaceFormText(notification.form_ref.form, "$ignoretext", notification.form_ref.form_template.ignore_text);
}
}
- mTemplates[notification.name] = LLNotificationTemplatePtr(new LLNotificationTemplate(notification));
+ mTemplates[notification.name] = std::make_shared<LLNotificationTemplate>(notification);
}
LL_INFOS("Notifications") << "...done" << LL_ENDL;
@@ -1683,7 +1683,7 @@ bool LLNotifications::loadVisibilityRules()
for (const LLNotificationVisibilityRule::Rule& rule : params.rules)
{
- mVisibilityRules.push_back(LLNotificationVisibilityRulePtr(new LLNotificationVisibilityRule(rule)));
+ mVisibilityRules.push_back(std::make_shared<LLNotificationVisibilityRule>(rule));
}
return true;
@@ -1726,7 +1726,7 @@ LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& subs
// generalized add function that takes a parameter block object for more complex instantiations
LLNotificationPtr LLNotifications::add(const LLNotification::Params& p)
{
- LLNotificationPtr pNotif(new LLNotification(p));
+ LLNotificationPtr pNotif = std::make_shared<LLNotification>(p);
add(pNotif);
return pNotif;
}
@@ -1834,7 +1834,7 @@ void LLNotifications::update(const LLNotificationPtr pNotif)
LLNotificationPtr LLNotifications::find(LLUUID uuid)
{
- LLNotificationPtr target = LLNotificationPtr(new LLNotification(LLNotification::Params().id(uuid)));
+ LLNotificationPtr target = std::make_shared<LLNotification>(LLNotification::Params().id(uuid));
LLNotificationSet::iterator it=mItems.find(target);
if (it == mItems.end())
{
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 3c8e1e85fa..d56c459560 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -75,6 +75,7 @@
*
*/
+#include <functional>
#include <string>
#include <list>
#include <vector>
@@ -83,8 +84,6 @@
#include <iomanip>
#include <sstream>
-#include <boost/utility.hpp>
-#include <boost/type_traits.hpp>
#include <boost/signals2.hpp>
#include <boost/range.hpp>
#include <boost/intrusive_ptr.hpp>
@@ -129,7 +128,7 @@ public:
virtual void fromLLSD(const LLSD& params) = 0;
};
-typedef boost::function<void (const LLSD&, const LLSD&)> LLNotificationResponder;
+typedef std::function<void (const LLSD&, const LLSD&)> LLNotificationResponder;
typedef std::shared_ptr<LLNotificationResponderInterface> LLNotificationResponderPtr;
@@ -303,7 +302,6 @@ typedef std::shared_ptr<LLNotificationVisibilityRule> LLNotificationVisibilityRu
* shared pointer.
*/
class LLNotification :
- boost::noncopyable,
public std::enable_shared_from_this<LLNotification>
{
LOG_CLASS(LLNotification);
@@ -429,6 +427,10 @@ private:
public:
LLNotification(const LLSDParamAdapter<Params>& p);
+ // Non-copyable
+ LLNotification(const LLNotification&) = delete;
+ LLNotification& operator=(const LLNotification&) = delete;
+
void setResponseFunctor(std::string const &responseFunctorName);
void setResponseFunctor(const LLNotificationFunctorRegistry::ResponseFunctor& cb);
@@ -666,8 +668,8 @@ namespace LLNotificationFilters
template<typename T>
struct filterBy
{
- typedef boost::function<T (LLNotificationPtr)> field_t;
- typedef typename boost::remove_reference<T>::type value_t;
+ typedef std::function<T (LLNotificationPtr)> field_t;
+ typedef typename std::remove_reference<T>::type value_t;
filterBy(field_t field, value_t value, EComparison comparison = EQUAL)
: mField(field),
@@ -712,7 +714,7 @@ namespace LLNotificationComparators
};
};
-typedef boost::function<bool (LLNotificationPtr)> LLNotificationFilter;
+typedef std::function<bool (LLNotificationPtr)> LLNotificationFilter;
typedef std::set<LLNotificationPtr, LLNotificationComparators::orderByUUID> LLNotificationSet;
typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
@@ -817,10 +819,9 @@ typedef boost::intrusive_ptr<LLNotificationChannel> LLNotificationChannelPtr;
// manages a list of notifications
// Note that if this is ever copied around, we might find ourselves with multiple copies
// of a queue with notifications being added to different nonequivalent copies. So we
-// make it inherit from boost::noncopyable, and then create a map of LLPointer to manage it.
+// delete the copy operator and constructor, and then create a map of LLPointer to manage it.
//
class LLNotificationChannel :
- boost::noncopyable,
public LLNotificationChannelBase,
public LLInstanceTracker<LLNotificationChannel, std::string>
{
@@ -843,6 +844,10 @@ public:
virtual ~LLNotificationChannel();
typedef LLNotificationSet::iterator Iterator;
+ // Non-copyable
+ LLNotificationChannel(const LLNotificationChannel&) = delete;
+ LLNotificationChannel& operator=(const LLNotificationChannel&) = delete;
+
std::string getName() const { return mName; }
typedef std::vector<std::string>::const_iterator parents_iter;
boost::iterator_range<parents_iter> getParents() const
@@ -854,7 +859,7 @@ public:
S32 size() const;
size_t size();
- typedef boost::function<void(LLNotificationPtr)> NotificationProcess;
+ typedef std::function<void(LLNotificationPtr)> NotificationProcess;
void forEachNotification(NotificationProcess process);
std::string summarize();
diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp
index 9c1fc27c51..d07d42bdba 100644
--- a/indra/llui/llnotificationslistener.cpp
+++ b/indra/llui/llnotificationslistener.cpp
@@ -266,7 +266,7 @@ void LLNotificationsListener::forward(const LLSD& params)
entry(mForwarders.insert(ForwarderMap::value_type(channel, ForwarderMap::mapped_type())).first);
if (! entry->second)
{
- entry->second.reset(new Forwarder(mNotifications, channel));
+ entry->second = std::make_shared<Forwarder>(mNotifications, channel);
}
// Now, whether this Forwarder is brand-new or not, update it with the new
// request info.
diff --git a/indra/llui/llnotificationsutil.cpp b/indra/llui/llnotificationsutil.cpp
index c1cad431c5..6b570d043f 100644
--- a/indra/llui/llnotificationsutil.cpp
+++ b/indra/llui/llnotificationsutil.cpp
@@ -71,7 +71,7 @@ LLNotificationPtr LLNotificationsUtil::add(const std::string& name,
LLNotificationPtr LLNotificationsUtil::add(const std::string& name,
const LLSD& substitutions,
const LLSD& payload,
- boost::function<void (const LLSD&, const LLSD&)> functor)
+ std::function<void (const LLSD&, const LLSD&)> functor)
{
LLNotification::Params::Functor functor_p;
functor_p.function = functor;
diff --git a/indra/llui/llnotificationsutil.h b/indra/llui/llnotificationsutil.h
index f21d93a50e..73e64e47ba 100644
--- a/indra/llui/llnotificationsutil.h
+++ b/indra/llui/llnotificationsutil.h
@@ -32,7 +32,7 @@
#include "llnotificationptr.h"
#include "lluuid.h"
-#include <boost/function.hpp>
+#include <functional>
class LLSD;
@@ -55,7 +55,7 @@ namespace LLNotificationsUtil
LLNotificationPtr add(const std::string& name,
const LLSD& substitutions,
const LLSD& payload,
- boost::function<void (const LLSD&, const LLSD&)> functor);
+ std::function<void (const LLSD&, const LLSD&)> functor);
S32 getSelectedOption(const LLSD& notification, const LLSD& response);
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index db314cae0f..2100b23783 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -662,12 +662,12 @@ bool LLPanel::childHasFocus(std::string_view id)
// Prefer getChild<LLUICtrl>("foo")->setCommitCallback(boost:bind(...)),
// which takes a generic slot. Or use mCommitCallbackRegistrar.add() with
// a named callback and reference it in XML.
-void LLPanel::childSetCommitCallback(std::string_view id, boost::function<void (LLUICtrl*,void*)> cb, void* data)
+void LLPanel::childSetCommitCallback(std::string_view id, std::function<void (LLUICtrl*,void*)> cb, void* data)
{
LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
- child->setCommitCallback(boost::bind(cb, child, data));
+ child->setCommitCallback(std::bind(cb, child, data));
}
}
@@ -759,12 +759,12 @@ void LLPanel::childSetAction(std::string_view id, const commit_signal_t::slot_ty
}
}
-void LLPanel::childSetAction(std::string_view id, boost::function<void(void*)> function, void* value)
+void LLPanel::childSetAction(std::string_view id, std::function<void(void*)> function, void* value)
{
LLButton* button = findChild<LLButton>(id);
if (button)
{
- button->setClickedCallback(boost::bind(function, value));
+ button->setClickedCallback(std::bind(function, value));
}
}
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index f085c123c1..fe861dc719 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -191,7 +191,7 @@ public:
// Prefer getChild<LLUICtrl>("foo")->setCommitCallback(boost:bind(...)),
// which takes a generic slot. Or use mCommitCallbackRegistrar.add() with
// a named callback and reference it in XML.
- void childSetCommitCallback(std::string_view id, boost::function<void (LLUICtrl*,void*)> cb, void* data);
+ void childSetCommitCallback(std::string_view id, std::function<void (LLUICtrl*,void*)> cb, void* data);
void childSetColor(std::string_view id, const LLUIColor& color);
LLCtrlSelectionInterface* childGetSelectionInterface(std::string_view id) const;
@@ -208,7 +208,7 @@ public:
bool childSetLabelArg(std::string_view id, const std::string& key, const LLStringExplicit& text);
// LLButton
- void childSetAction(std::string_view id, boost::function<void(void*)> function, void* value);
+ void childSetAction(std::string_view id, std::function<void(void*)> function, void* value);
void childSetAction(std::string_view id, const commit_signal_t::slot_type& function);
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL);
@@ -262,7 +262,7 @@ extern template class LLPanel* LLView::getChild<class LLPanel>(
std::string_view name, bool recurse) const;
#endif
-typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc;
+typedef std::function<LLPanel* (void)> LLPanelClassCreatorFunc;
// local static instance for registering a particular panel class
diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h
index 68bf0fd95e..d95536c360 100644
--- a/indra/llui/llresizebar.h
+++ b/indra/llui/llresizebar.h
@@ -62,7 +62,7 @@ public:
void setEnableSnapping(bool enable) { mSnappingEnabled = enable; }
void setAllowDoubleClickSnapping(bool allow) { mAllowDoubleClickSnapping = allow; }
bool canResize() const { return getEnabled() && mMaxSize > mMinSize; }
- void setResizeListener(boost::function<void(void*)> listener) {mResizeListener = listener;}
+ void setResizeListener(std::function<void(void*)> listener) { mResizeListener = listener; }
void setImagePanel(LLPanel * panelp);
LLPanel * getImagePanel() const;
@@ -78,7 +78,7 @@ private:
bool mSnappingEnabled,
mAllowDoubleClickSnapping;
LLView* mResizingView;
- boost::function<void(void*)> mResizeListener;
+ std::function<void(void*)> mResizeListener;
LLPointer<LLUIImage> mDragHandleImage;
LLPanel * mImagePanel;
};
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index 9607355a9d..c49d2b534a 100644
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -40,7 +40,7 @@ class LLScrollbar
{
public:
- typedef boost::function<void (S32, LLScrollbar*)> callback_t;
+ typedef std::function<void (S32, LLScrollbar*)> callback_t;
struct Params
: public LLInitParam::Block<Params, LLUICtrl::Params>
{
diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
index a3108d77e8..bdf88768c3 100644
--- a/indra/llui/llscrolllistcell.cpp
+++ b/indra/llui/llscrolllistcell.cpp
@@ -98,6 +98,7 @@ const LLSD LLScrollListCell::getAltValue() const
LLScrollListIcon::LLScrollListIcon(const LLScrollListCell::Params& p)
: LLScrollListCell(p),
mIcon(LLUI::getUIImage(p.value().asString())),
+ mIconSize(0),
mColor(p.color),
mAlignment(p.font_halign)
{}
@@ -140,20 +141,32 @@ void LLScrollListIcon::setValue(const LLSD& value)
}
}
-
void LLScrollListIcon::setColor(const LLColor4& color)
{
mColor = color;
}
+void LLScrollListIcon::setIconSize(S32 size)
+{
+ mIconSize = size;
+}
+
S32 LLScrollListIcon::getWidth() const
{
// if no specified fix width, use width of icon
- if (LLScrollListCell::getWidth() == 0 && mIcon.notNull())
+ if (LLScrollListCell::getWidth() != 0)
+ {
+ return LLScrollListCell::getWidth();
+ }
+ if (mIconSize != 0)
+ {
+ return mIconSize;
+ }
+ if (mIcon.notNull())
{
return mIcon->getWidth();
}
- return LLScrollListCell::getWidth();
+ return 0;
}
@@ -161,16 +174,23 @@ void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_col
{
if (mIcon)
{
+ S32 draw_width = mIcon->getWidth();
+ S32 draw_height = mIcon->getHeight();
+ if (mIconSize != 0)
+ {
+ draw_width = mIconSize;
+ draw_height = mIconSize;
+ } // else will draw full icon even if cell is smaller
switch(mAlignment)
{
case LLFontGL::LEFT:
- mIcon->draw(0, 0, mColor);
+ mIcon->draw(0, 0, draw_width, draw_height, mColor);
break;
case LLFontGL::RIGHT:
- mIcon->draw(getWidth() - mIcon->getWidth(), 0, mColor);
+ mIcon->draw(getWidth() - draw_width, 0, draw_width, draw_height, mColor);
break;
case LLFontGL::HCENTER:
- mIcon->draw((getWidth() - mIcon->getWidth()) / 2, 0, mColor);
+ mIcon->draw((getWidth() - draw_width) / 2, 0, draw_width, draw_height, mColor);
break;
default:
break;
diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
index 7dded3c0b7..f0a0f216b4 100644
--- a/indra/llui/llscrolllistcell.h
+++ b/indra/llui/llscrolllistcell.h
@@ -197,11 +197,13 @@ public:
/*virtual*/ const LLSD getValue() const;
/*virtual*/ void setColor(const LLColor4&);
/*virtual*/ void setValue(const LLSD& value);
+ void setIconSize(S32 size);
private:
LLPointer<LLUIImage> mIcon;
LLColor4 mColor;
LLFontGL::HAlign mAlignment;
+ S32 mIconSize;
};
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 245339b107..b459c67dad 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -190,19 +190,19 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mColumnsDirty(false),
mMaxItemCount(INT_MAX),
mBorderThickness( 2 ),
- mOnDoubleClickCallback( NULL ),
- mOnMaximumSelectCallback( NULL ),
- mOnSortChangedCallback( NULL ),
+ mOnDoubleClickCallback(nullptr),
+ mOnMaximumSelectCallback(nullptr),
+ mOnSortChangedCallback(nullptr),
mHighlightedItem(-1),
- mBorder(NULL),
- mSortCallback(NULL),
+ mBorder(nullptr),
+ mSortCallback(nullptr),
mNumDynamicWidthColumns(0),
mTotalStaticColumnWidth(0),
mTotalColumnPadding(0),
mSorted(false),
mDirty(false),
mOriginalSelection(-1),
- mLastSelected(NULL),
+ mLastSelected(nullptr),
mHeadingHeight(p.heading_height),
mAllowMultipleSelection(p.multi_select),
mDisplayColumnHeaders(p.draw_heading),
@@ -222,7 +222,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mRowPadding(p.row_padding),
mAlternateSort(false),
mContextMenuType(MENU_NONE),
- mIsFriendSignal(NULL)
+ mIsFriendSignal(nullptr)
{
mItemListRect.setOriginAndSize(
mBorderThickness,
@@ -1007,7 +1007,7 @@ void LLScrollListCtrl::deleteItems(const LLSD& sd)
void LLScrollListCtrl::deleteSelectedItems()
{
item_list::iterator iter;
- for (iter = mItemList.begin(); iter < mItemList.end(); )
+ for (iter = mItemList.begin(); iter != mItemList.end(); )
{
LLScrollListItem* itemp = *iter;
if (itemp->getSelected())
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 1f04100306..d3735c5052 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -77,7 +77,7 @@ public:
};
// *TODO: Add callbacks to Params
- typedef boost::function<void (void)> callback_t;
+ typedef std::function<void (void)> callback_t;
template<typename T> struct maximum
{
@@ -241,7 +241,7 @@ public:
void setMaximumSelectCallback( callback_t cb) { mOnMaximumSelectCallback = cb; }
void setSortChangedCallback( callback_t cb) { mOnSortChangedCallback = cb; }
// Convenience function; *TODO: replace with setter above + boost::bind() in calling code
- void setDoubleClickCallback( boost::function<void (void* userdata)> cb, void* userdata) { mOnDoubleClickCallback = boost::bind(cb, userdata); }
+ void setDoubleClickCallback( std::function<void (void* userdata)> cb, void* userdata) { mOnDoubleClickCallback = std::bind(cb, userdata); }
void swapWithNext(S32 index);
void swapWithPrevious(S32 index);
diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp
index a0c1e9d0c0..244faf8fe9 100644
--- a/indra/llui/llsearcheditor.cpp
+++ b/indra/llui/llsearcheditor.cpp
@@ -106,12 +106,12 @@ LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
LLSearchEditor::~LLSearchEditor()
{
- mKeystrokeCallback = NULL;
- mTextChangedCallback = NULL;
+ mKeystrokeCallback = nullptr;
+ mTextChangedCallback = nullptr;
setCommitOnFocusLost(false);
- mSearchButton = NULL;
- mClearButton = NULL;
+ mSearchButton = nullptr;
+ mClearButton = nullptr;
mSearchEditor->deleteAllChildren();
deleteAllChildren();
}
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 778b253c3c..2079ff17fc 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -185,6 +185,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mURLClickSignal(NULL),
mIsFriendSignal(NULL),
mIsObjectBlockedSignal(NULL),
+ mIsObjectReachableSignal(NULL),
mMaxTextByteLength( p.max_text_length ),
mFont(p.font),
mFontShadow(p.font_shadow),
@@ -290,6 +291,7 @@ LLTextBase::~LLTextBase()
delete mURLClickSignal;
delete mIsFriendSignal;
delete mIsObjectBlockedSignal;
+ delete mIsObjectReachableSignal;
}
void LLTextBase::initFromParams(const LLTextBase::Params& p)
@@ -1036,8 +1038,37 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
{
LLStyleSP emoji_style;
LLEmojiDictionary* ed = LLEmojiDictionary::instanceExists() ? LLEmojiDictionary::getInstance() : NULL;
+ LLTextSegment* segmentp = nullptr;
+ segment_vec_t::iterator seg_iter;
+ if (segments && segments->size() > 0)
+ {
+ seg_iter = segments->begin();
+ segmentp = *seg_iter;
+ }
for (S32 text_kitty = 0, text_len = static_cast<S32>(wstr.size()); text_kitty < text_len; text_kitty++)
{
+ if (segmentp)
+ {
+ if (segmentp->getEnd() <= pos + text_kitty)
+ {
+ seg_iter++;
+ if (seg_iter != segments->end())
+ {
+ segmentp = *seg_iter;
+ }
+ else
+ {
+ segmentp = nullptr;
+ }
+ }
+ if (segmentp && !segmentp->getPermitsEmoji())
+ {
+ // Some segments, like LLInlineViewSegment do not permit splitting
+ // and should not be interrupted by emoji segments
+ continue;
+ }
+ }
+
llwchar code = wstr[text_kitty];
bool isEmoji = ed ? ed->isEmoji(code) : LLStringOps::isEmoji(code);
if (isEmoji)
@@ -1069,6 +1100,14 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
{
+ S32 text_length = (S32)getLength();
+ if (pos >= text_length || pos < 0)
+ {
+ return 0; // nothing to remove
+ }
+ // Clamp length to not go past the end of the text
+ length = std::min(length, text_length - pos);
+
beforeValueChange();
segment_set_t::iterator seg_iter = getSegIterContaining(pos);
while(seg_iter != mSegments.end())
@@ -1438,6 +1477,8 @@ void LLTextBase::reshape(S32 width, S32 height, bool called_from_parent)
// up-to-date mVisibleTextRect
updateRects();
+ // Todo: This might be wrong. updateRects already sets needsReflow conditionaly.
+ // Reflow is expensive and doing it at any twith can be too much.
needsReflow();
}
}
@@ -2227,7 +2268,9 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url));
registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url));
registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
+ registrar.add("Url.ZoomInObject", boost::bind(&LLUrlAction::zoomInObject, url));
registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
+ registrar.add("Url.ShowParcelOnMap", boost::bind(&LLUrlAction::showParcelOnMap, url));
registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));
@@ -2271,6 +2314,15 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
unblockButton->setVisible(is_blocked);
}
}
+
+ if (mIsObjectReachableSignal)
+ {
+ bool is_reachable = *(*mIsObjectReachableSignal)(LLUUID(LLUrlAction::getObjectId(url)));
+ if (LLView* zoom_btn = menu->getChild<LLView>("zoom_in"))
+ {
+ zoom_btn->setEnabled(is_reachable);
+ }
+ }
menu->show(x, y);
LLMenuGL::showPopup(this, menu, x, y);
}
@@ -3377,6 +3429,15 @@ boost::signals2::connection LLTextBase::setIsObjectBlockedCallback(const is_bloc
return mIsObjectBlockedSignal->connect(cb);
}
+boost::signals2::connection LLTextBase::setIsObjectReachableCallback(const is_obj_reachable_signal_t::slot_type& cb)
+{
+ if (!mIsObjectReachableSignal)
+ {
+ mIsObjectReachableSignal = new is_obj_reachable_signal_t();
+ }
+ return mIsObjectReachableSignal->connect(cb);
+}
+
//
// LLTextSegment
//
@@ -3459,6 +3520,11 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e
{
mFontHeight = mStyle->getFont()->getLineHeight();
mCanEdit = !mStyle->getDrawHighlightBg();
+ if (!mCanEdit)
+ {
+ // Emoji shouldn't split the segment with the mention.
+ mPermitsEmoji = false;
+ }
LLUIImagePtr image = mStyle->getImage();
if (image.notNull())
@@ -3755,7 +3821,7 @@ bool LLNormalTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& w
{
height = 0;
width = 0;
- if (num_chars > 0)
+ if (num_chars > 0 && (mStart + first_char >= 0))
{
height = mFontHeight;
const LLWString &text = getWText();
@@ -3979,6 +4045,7 @@ LLInlineViewSegment::LLInlineViewSegment(const Params& p, S32 start, S32 end)
mTopPad(p.top_pad),
mBottomPad(p.bottom_pad)
{
+ mPermitsEmoji = false;
}
LLInlineViewSegment::~LLInlineViewSegment()
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 8ca653acb9..3ab5e905e3 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -61,13 +61,15 @@ class LLTextSegment
public:
LLTextSegment(S32 start, S32 end)
: mStart(start),
- mEnd(end)
+ mEnd(end),
+ mPermitsEmoji(true)
{}
virtual ~LLTextSegment();
virtual LLTextSegmentPtr clone(LLTextBase& terget) const { return new LLTextSegment(mStart, mEnd); }
static LLStyleSP cloneStyle(LLTextBase& target, const LLStyle* source);
bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
+ bool getPermitsEmoji() const { return mPermitsEmoji; };
virtual bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
virtual S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
@@ -125,6 +127,8 @@ public:
protected:
S32 mStart;
S32 mEnd;
+
+ bool mPermitsEmoji;
};
class LLNormalTextSegment : public LLTextSegment
@@ -255,6 +259,7 @@ public:
/*virtual*/ void updateLayout(const class LLTextBase& editor);
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
/*virtual*/ bool canEdit() const { return false; }
+ /*virtual*/ bool getPermitsEmoji() const { return false; }
/*virtual*/ void unlinkFromDocument(class LLTextBase* editor);
/*virtual*/ void linkToDocument(class LLTextBase* editor);
@@ -325,6 +330,7 @@ public:
typedef boost::signals2::signal<bool (const LLUUID& user_id)> is_friend_signal_t;
typedef boost::signals2::signal<bool (const LLUUID& blocked_id, const std::string from)> is_blocked_signal_t;
+ typedef boost::signals2::signal<bool (const LLUUID& obj_id)> is_obj_reachable_signal_t;
struct LineSpacingParams : public LLInitParam::ChoiceBlock<LineSpacingParams>
{
@@ -535,6 +541,7 @@ public:
boost::signals2::connection setURLClickedCallback(const commit_signal_t::slot_type& cb);
boost::signals2::connection setIsFriendCallback(const is_friend_signal_t::slot_type& cb);
boost::signals2::connection setIsObjectBlockedCallback(const is_blocked_signal_t::slot_type& cb);
+ boost::signals2::connection setIsObjectReachableCallback(const is_obj_reachable_signal_t::slot_type& cb);
void setWordWrap(bool wrap);
LLScrollContainer* getScrollContainer() const { return mScroller; }
@@ -783,6 +790,7 @@ protected:
// Used to check if user with given ID is avatar's friend
is_friend_signal_t* mIsFriendSignal;
is_blocked_signal_t* mIsObjectBlockedSignal;
+ is_obj_reachable_signal_t* mIsObjectReachableSignal;
LLUIString mLabel; // text label that is visible when no user text provided
};
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 9f945d3735..d2a21998a6 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -43,7 +43,7 @@ template class LLTextBox* LLView::getChild<class LLTextBox>(
LLTextBox::LLTextBox(const LLTextBox::Params& p)
: LLTextBase(p),
- mClickedCallback(NULL),
+ mClickedCallback(nullptr),
mShowCursorHand(true)
{
mSkipTripleClick = true;
@@ -135,9 +135,9 @@ void LLTextBox::setText(const LLStringExplicit& text , const LLStyle::Params& in
LLTextBase::setText(mText.getString(), input_params );
}
-void LLTextBox::setClickedCallback( boost::function<void (void*)> cb, void* userdata /*= NULL */ )
+void LLTextBox::setClickedCallback(std::function<void (void*)> cb, void* userdata /*= nullptr */)
{
- mClickedCallback = boost::bind(cb, userdata);
+ mClickedCallback = std::bind(cb, userdata);
}
S32 LLTextBox::getTextPixelWidth()
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index 507d8f3ee6..8716917ced 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -36,7 +36,7 @@ class LLTextBox :
public:
// *TODO: Add callback to Params
- typedef boost::function<void (void)> callback_t;
+ typedef std::function<void (void)> callback_t;
struct Params : public LLInitParam::Block<Params, LLTextBase::Params>
{};
@@ -58,7 +58,7 @@ public:
void setRightAlign() { mHAlign = LLFontGL::RIGHT; }
void setHAlign(LLFontGL::HAlign align) { mHAlign = align; }
- void setClickedCallback(boost::function<void(void*)> cb, void* userdata = NULL);
+ void setClickedCallback(std::function<void(void*)> cb, void* userdata = nullptr);
void reshapeToFitText(bool called_from_parent = false);
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index cfe729be06..fcdf3782ae 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -274,7 +274,9 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
mShowChatMentionPicker(false),
mEnableTooltipPaste(p.enable_tooltip_paste),
mPassDelete(false),
- mKeepSelectionOnReturn(false)
+ mKeepSelectionOnReturn(false),
+ mSelectAllOnFocusReceived(false),
+ mSelectedOnFocusReceived(false)
{
mSourceID.generate();
@@ -398,6 +400,7 @@ void LLTextEditor::selectNext(const std::string& search_text_in, bool case_insen
setCursorPos(loc);
mIsSelecting = true;
+ mSelectedOnFocusReceived = false;
mSelectionEnd = mCursorPos;
mSelectionStart = llmin((S32)getLength(), (S32)(mCursorPos + search_text.size()));
}
@@ -677,6 +680,13 @@ bool LLTextEditor::canSelectAll() const
return true;
}
+//virtual
+void LLTextEditor::deselect()
+{
+ LLTextBase::deselect();
+ mSelectedOnFocusReceived = false;
+}
+
// virtual
void LLTextEditor::selectAll()
{
@@ -694,6 +704,11 @@ void LLTextEditor::selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_p
endSelection();
}
+void LLTextEditor::setSelectAllOnFocusReceived(bool b)
+{
+ mSelectAllOnFocusReceived = b;
+}
+
void LLTextEditor::insertEmoji(llwchar emoji)
{
LL_INFOS() << "LLTextEditor::insertEmoji(" << wchar_utf8_preview(emoji) << ")" << LL_ENDL;
@@ -795,8 +810,16 @@ bool LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
// Delay cursor flashing
resetCursorBlink();
+ mSelectedOnFocusReceived = false;
if (handled && !gFocusMgr.getMouseCapture())
{
+ if (!mask && mSelectAllOnFocusReceived)
+ {
+ mIsSelecting = false;
+ mSelectionStart = getLength();
+ mSelectionEnd = 0;
+ mSelectedOnFocusReceived = true;
+ }
gFocusMgr.setMouseCapture( this );
}
return handled;
@@ -1219,7 +1242,7 @@ void LLTextEditor::addChar(llwchar wc)
tryToShowEmojiHelper();
tryToShowMentionHelper();
- if (!mReadOnly && mAutoreplaceCallback != NULL)
+ if (!mReadOnly && mAutoreplaceCallback != nullptr)
{
// autoreplace the text, if necessary
S32 replacement_start;
@@ -2200,6 +2223,11 @@ void LLTextEditor::focusLostHelper()
gEditMenuHandler = NULL;
}
+ if (mSelectedOnFocusReceived)
+ {
+ deselect();
+ }
+
if (mCommitOnFocusLost)
{
onCommit();
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 882bb145df..d9742db34d 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -144,8 +144,10 @@ public:
virtual bool canDoDelete() const;
virtual void selectAll();
virtual bool canSelectAll() const;
+ virtual void deselect();
void selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_pos);
+ void setSelectAllOnFocusReceived(bool b);
virtual bool canLoadOrSaveToFile();
@@ -162,7 +164,7 @@ public:
bool allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
// Autoreplace (formerly part of LLLineEditor)
- typedef boost::function<void(S32&, S32&, LLWString&, S32&, const LLWString&)> autoreplace_callback_t;
+ typedef std::function<void(S32&, S32&, LLWString&, S32&, const LLWString&)> autoreplace_callback_t;
autoreplace_callback_t mAutoreplaceCallback;
void setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
@@ -336,6 +338,8 @@ private:
bool mEnableTooltipPaste;
bool mPassDelete;
bool mKeepSelectionOnReturn; // disabling of removing selected text after pressing of Enter
+ bool mSelectAllOnFocusReceived;
+ bool mSelectedOnFocusReceived;
LLUUID mSourceID;
diff --git a/indra/llui/lltextutil.cpp b/indra/llui/lltextutil.cpp
index 8ffce1b8b4..1454de34c7 100644
--- a/indra/llui/lltextutil.cpp
+++ b/indra/llui/lltextutil.cpp
@@ -30,7 +30,7 @@
#include "lltextbox.h"
#include "llurlmatch.h"
-boost::function<bool(LLUrlMatch*,LLTextBase*)> LLTextUtil::TextHelpers::iconCallbackCreationFunction = 0;
+std::function<bool(LLUrlMatch*, LLTextBase*)> LLTextUtil::TextHelpers::iconCallbackCreationFunction = nullptr;
void LLTextUtil::textboxSetHighlightedVal(LLTextBox *txtbox, const LLStyle::Params& normal_style, const std::string& text, const std::string& hl)
{
diff --git a/indra/llui/lltextutil.h b/indra/llui/lltextutil.h
index f3838e59fa..6328ff133f 100644
--- a/indra/llui/lltextutil.h
+++ b/indra/llui/lltextutil.h
@@ -74,7 +74,7 @@ namespace LLTextUtil
//we need this special callback since we need to create LLAvataIconCtrls while parsing
//avatar/group url but can't create LLAvataIconCtrl from LLUI
public:
- static boost::function<bool(LLUrlMatch*,LLTextBase*)> iconCallbackCreationFunction;
+ static std::function<bool(LLUrlMatch*,LLTextBase*)> iconCallbackCreationFunction;
};
diff --git a/indra/llui/lltextvalidate.h b/indra/llui/lltextvalidate.h
index a4ff144d82..096c28b448 100644
--- a/indra/llui/lltextvalidate.h
+++ b/indra/llui/lltextvalidate.h
@@ -30,7 +30,6 @@
#include "llstring.h"
#include "llinitparam.h"
-#include <boost/function.hpp>
namespace LLTextValidate
{
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 5955a28fa3..785dc85448 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -99,8 +99,8 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
mWrap(p.wrap),
mNeedsLayout(false),
mModified(false),
- mButtonPanel(NULL),
- mCenteringStack(NULL),
+ mButtonPanel(nullptr),
+ mCenteringStack(nullptr),
mPadLeft(p.pad_left),
mPadRight(p.pad_right),
mPadTop(p.pad_top),
@@ -108,17 +108,17 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
mPadBetween(p.pad_between),
mMinGirth(p.min_girth),
mPopupMenuHandle(),
- mRightMouseTargetButton(NULL),
- mStartDragItemCallback(NULL),
- mHandleDragItemCallback(NULL),
- mHandleDropCallback(NULL),
- mButtonAddSignal(NULL),
- mButtonEnterSignal(NULL),
- mButtonLeaveSignal(NULL),
- mButtonRemoveSignal(NULL),
+ mRightMouseTargetButton(nullptr),
+ mStartDragItemCallback(nullptr),
+ mHandleDragItemCallback(nullptr),
+ mHandleDropCallback(nullptr),
+ mButtonAddSignal(nullptr),
+ mButtonEnterSignal(nullptr),
+ mButtonLeaveSignal(nullptr),
+ mButtonRemoveSignal(nullptr),
mDragAndDropTarget(false),
- mCaretIcon(NULL),
- mCenterPanel(NULL)
+ mCaretIcon(nullptr),
+ mCenterPanel(nullptr)
{
mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_WITH_TEXT] = p.button_icon_and_text;
mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_ONLY] = p.button_icon;
@@ -1054,7 +1054,7 @@ bool LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
// if drop is set, it's time to call the callback to get the operation done
if (handled && drop)
{
- handled = mHandleDropCallback(cargo_data, x, y, this);
+ handled = mHandleDropCallback(cargo_data, cargo_type, x, y, this);
}
// We accept only single tool drop on toolbars
@@ -1097,12 +1097,12 @@ LLToolBarButton::LLToolBarButton(const Params& p)
mWidthRange(p.button_width),
mDesiredHeight(p.desired_height),
mId(""),
- mIsEnabledSignal(NULL),
- mIsRunningSignal(NULL),
- mIsStartingSignal(NULL),
+ mIsEnabledSignal(nullptr),
+ mIsRunningSignal(nullptr),
+ mIsStartingSignal(nullptr),
mIsDragged(false),
- mStartDragItemCallback(NULL),
- mHandleDragItemCallback(NULL),
+ mStartDragItemCallback(nullptr),
+ mHandleDragItemCallback(nullptr),
mOriginalImageSelected(p.image_selected),
mOriginalImageUnselected(p.image_unselected),
mOriginalImagePressed(p.image_pressed),
@@ -1256,7 +1256,7 @@ void LLToolBar::LLCenterLayoutPanel::handleReshape(const LLRect& rect, bool by_u
{
LLLayoutPanel::handleReshape(rect, by_user);
- if (!mReshapeCallback.empty())
+ if (mReshapeCallback != nullptr)
{
LLRect r;
localRectToOtherView(mButtonPanel->getRect(), &r, gFloaterView);
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 5556406fbd..abf44f259a 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -39,9 +39,9 @@ class LLToolBar;
class LLToolBarButton;
class LLIconCtrl;
-typedef boost::function<void (S32 x, S32 y, LLToolBarButton* button)> tool_startdrag_callback_t;
-typedef boost::function<bool (S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type)> tool_handledrag_callback_t;
-typedef boost::function<bool (void* data, S32 x, S32 y, LLToolBar* toolbar)> tool_handledrop_callback_t;
+typedef std::function<void (S32 x, S32 y, LLToolBarButton* button)> tool_startdrag_callback_t;
+typedef std::function<bool (S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type)> tool_handledrag_callback_t;
+typedef std::function<bool (void* data, EDragAndDropType cargo_type, S32 x, S32 y, LLToolBar* toolbar)> tool_handledrop_callback_t;
class LLToolBarButton : public LLButton
{
@@ -167,7 +167,7 @@ public:
class LLCenterLayoutPanel : public LLLayoutPanel
{
public:
- typedef boost::function<void(LLToolBarEnums::EToolBarLocation tb, const LLRect& rect)> reshape_callback_t;
+ typedef std::function<void(LLToolBarEnums::EToolBarLocation tb, const LLRect& rect)> reshape_callback_t;
virtual ~LLCenterLayoutPanel() {}
/*virtual*/ void handleReshape(const LLRect& rect, bool by_user);
diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h
index 760acddd6f..c9d6937c1a 100644
--- a/indra/llui/lltooltip.h
+++ b/indra/llui/lltooltip.h
@@ -67,8 +67,8 @@ public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
- typedef boost::function<void(void)> click_callback_t;
- typedef boost::function<LLToolTip*(LLToolTip::Params)> create_callback_t;
+ typedef std::function<void(void)> click_callback_t;
+ typedef std::function<LLToolTip*(LLToolTip::Params)> create_callback_t;
Optional<std::string> message;
Multiple<StyledText> styled_message;
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index e36dae3955..179d1dcaff 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -213,13 +213,8 @@ void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& rem
void LLUI::setMousePositionScreen(S32 x, S32 y)
{
-#if defined(LL_DARWIN)
- S32 screen_x = ll_round(((F32)x * getScaleFactor().mV[VX]) / LLView::getWindow()->getSystemUISize());
- S32 screen_y = ll_round(((F32)y * getScaleFactor().mV[VY]) / LLView::getWindow()->getSystemUISize());
-#else
S32 screen_x = ll_round((F32)x * getScaleFactor().mV[VX]);
S32 screen_y = ll_round((F32)y * getScaleFactor().mV[VY]);
-#endif
LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert());
}
@@ -231,6 +226,11 @@ void LLUI::getMousePositionScreen(S32 *x, S32 *y)
LLCoordGL cursor_pos_gl(cursor_pos_window.convert());
*x = ll_round((F32)cursor_pos_gl.mX / getScaleFactor().mV[VX]);
*y = ll_round((F32)cursor_pos_gl.mY / getScaleFactor().mV[VY]);
+#if defined(LL_SDL)
+ *x = *x * LLView::getWindow()->getSystemUISize();
+ *y = *y * LLView::getWindow()->getSystemUISize();
+#endif
+
}
void LLUI::setMousePositionLocal(const LLView* viewp, S32 x, S32 y)
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index b2dcb6dc88..2ef64baaf6 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -241,9 +241,9 @@ public:
//
// Methods
//
- typedef boost::function<void(LLView*)> add_popup_t;
- typedef boost::function<void(LLView*)> remove_popup_t;
- typedef boost::function<void(void)> clear_popups_t;
+ typedef std::function<void(LLView*)> add_popup_t;
+ typedef std::function<void(LLView*)> remove_popup_t;
+ typedef std::function<void(void)> clear_popups_t;
void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index cbabb5a933..05461edd82 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -999,15 +999,16 @@ bool LLUICtrl::findHelpTopic(std::string& help_topic_out)
}
// *TODO: Deprecate; for backwards compatability only:
-boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data)
+boost::signals2::connection LLUICtrl::setCommitCallback( std::function<void (LLUICtrl*,void*)> cb, void* data)
{
- return setCommitCallback( boost::bind(cb, _1, data));
+ return setCommitCallback( std::bind(cb, std::placeholders::_1, data));
}
-boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb )
+
+boost::signals2::connection LLUICtrl::setValidateBeforeCommit( std::function<bool (const LLSD& data)> cb )
{
if (!mValidateSignal) mValidateSignal = new enable_signal_t();
- return mValidateSignal->connect(boost::bind(cb, _2));
+ return mValidateSignal->connect(std::bind(cb, std::placeholders::_2));
}
// virtual
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index bcaf479b0f..749999bbfe 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -31,7 +31,8 @@
//#include "llboost.h"
#include "llrect.h"
#include "llsd.h"
-#include <boost/function.hpp>
+#include <functional>
+#include <boost/bind.hpp>
#include <boost/signals2.hpp>
#include "llinitparam.h"
@@ -47,12 +48,12 @@ class LLUICtrl
: public LLView, public boost::signals2::trackable
{
public:
- typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param)> commit_callback_t;
+ typedef std::function<void (LLUICtrl* ctrl, const LLSD& param)> commit_callback_t;
typedef boost::signals2::signal<void (LLUICtrl* ctrl, const LLSD& param)> commit_signal_t;
// *TODO: add xml support for this type of signal in the future
typedef boost::signals2::signal<void (LLUICtrl* ctrl, S32 x, S32 y, MASK mask)> mouse_signal_t;
- typedef boost::function<bool (LLUICtrl* ctrl, const LLSD& param)> enable_callback_t;
+ typedef std::function<bool (LLUICtrl* ctrl, const LLSD& param)> enable_callback_t;
typedef boost::signals2::signal<bool (LLUICtrl* ctrl, const LLSD& param), boost_boolean_combiner> enable_signal_t;
struct CallbackParam : public LLInitParam::Block<CallbackParam>
@@ -258,8 +259,8 @@ public:
boost::signals2::connection setDoubleClickCallback( const mouse_signal_t::slot_type& cb );
// *TODO: Deprecate; for backwards compatability only:
- boost::signals2::connection setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data);
- boost::signals2::connection setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb );
+ boost::signals2::connection setCommitCallback( std::function<void (LLUICtrl*,void*)> cb, void* data);
+ boost::signals2::connection setValidateBeforeCommit( std::function<bool (const LLSD& data)> cb );
LLUICtrl* findRootMostFocusRoot();
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index a2a6d661ff..9abccfd9a0 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -100,16 +100,19 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa
std::string base_filename = search_paths.front();
if (!base_filename.empty())
{
- LLUICtrlFactory::instance().pushFileName(base_filename);
+ LLUICtrlFactory *factory = LLUICtrlFactory::getInstance();
+ factory->mFileNames.push_back(base_filename);
- if (!LLXMLNode::getLayeredXMLNode(root_node, search_paths))
+ if (LLXMLNode::getLayeredXMLNode(root_node, search_paths))
+ {
+ LLXUIParser parser;
+ parser.readXUI(root_node, block, base_filename);
+ }
+ else
{
LL_WARNS() << "Couldn't parse widget from: " << base_filename << LL_ENDL;
- return;
}
- LLXUIParser parser;
- parser.readXUI(root_node, block, base_filename);
- LLUICtrlFactory::instance().popFileName();
+ factory->mFileNames.pop_back();
}
}
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 91221dc7f3..fc069c078f 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -311,7 +311,7 @@ LLUICtrlFactory::ParamDefaults<LLInitParam::BaseBlock, DUMMY>::ParamDefaults() {
template<typename DERIVED>
template<typename T>
LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreatorFunc func)
-: LLChildRegistry<DERIVED>::StaticRegistrar(tag, func.empty() ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T> : func)
+: LLChildRegistry<DERIVED>::StaticRegistrar(tag, func == nullptr ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T> : func)
{
// add this widget to various registries
LLUICtrlFactory::instance().registerWidget(&typeid(T), &typeid(typename T::Params), tag);
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index b6b450c2a1..8b320b59cc 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -30,6 +30,7 @@
#include "llview.h"
#include "llwindow.h"
#include "llurlregistry.h"
+#include "v3dmath.h"
// global state for the callback functions
@@ -116,6 +117,16 @@ void LLUrlAction::teleportToLocation(std::string url)
}
}
+void LLUrlAction::zoomInObject(std::string url)
+{
+ LLUrlMatch match;
+ std::string object_id = getObjectId(url);
+ if (LLUUID::validate(object_id) && LLUrlRegistry::instance().findUrl(url, match))
+ {
+ executeSLURL("secondlife:///app/object/" + object_id + "/zoomin/" + match.getLocation());
+ }
+}
+
void LLUrlAction::showLocationOnMap(std::string url)
{
LLUrlMatch match;
@@ -128,6 +139,23 @@ void LLUrlAction::showLocationOnMap(std::string url)
}
}
+void LLUrlAction::showParcelOnMap(std::string url)
+{
+ LLSD path_array = LLURI(url).pathArray();
+ auto path_parts = path_array.size();
+
+ if (path_parts < 3) // no parcel id
+ {
+ LL_WARNS() << "Global coordinates are missing in url: [" << url << "]" << LL_ENDL;
+ return;
+ }
+
+ LLVector3d parcel_pos = LLUrlEntryParcel::getParcelPos(LLUUID(LLURI::unescape(path_array[2])));
+ std::ostringstream pos;
+ pos << parcel_pos.mdV[VX] << '/' << parcel_pos.mdV[VY] << '/' << parcel_pos.mdV[VZ];
+ executeSLURL("secondlife:///app/worldmap_global/" + pos.str());
+}
+
void LLUrlAction::copyURLToClipboard(std::string url)
{
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(url));
@@ -142,6 +170,16 @@ void LLUrlAction::copyLabelToClipboard(std::string url)
}
}
+std::string LLUrlAction::getURLLabel(std::string url)
+{
+ LLUrlMatch match;
+ if (LLUrlRegistry::instance().findUrl(url, match))
+ {
+ return match.getLabel();
+ }
+ return "";
+}
+
void LLUrlAction::showProfile(std::string url)
{
// Get id from 'secondlife:///app/{cmd}/{id}/{action}'
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index ac9741a7ad..c4cfd0f3fb 100644
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -28,8 +28,8 @@
#ifndef LL_LLURLACTION_H
#define LL_LLURLACTION_H
+#include <functional>
#include <string>
-#include <boost/function.hpp>
///
/// The LLUrlAction class provides a number of static functions that
@@ -60,9 +60,15 @@ public:
/// if the Url specifies an SL location, teleport there
static void teleportToLocation(std::string url);
+ /// If the Url specifies an object id, attempt to zoom in.
+ /// If not possible to zoom in, show on map
+ static void zoomInObject(std::string url);
+
/// if the Url specifies an SL location, show it on a map
static void showLocationOnMap(std::string url);
+ static void showParcelOnMap(std::string url);
+
/// perform the appropriate action for left-clicking on a Url
static void clickAction(std::string url, bool trusted_content);
@@ -72,6 +78,8 @@ public:
/// copy a Url to the clipboard
static void copyURLToClipboard(std::string url);
+ static std::string getURLLabel(std::string url);
+
/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile
static void showProfile(std::string url);
static std::string getUserID(std::string url);
@@ -85,8 +93,8 @@ public:
static void unblockObject(std::string url);
/// specify the callbacks to enable this class's functionality
- typedef boost::function<void (const std::string&)> url_callback_t;
- typedef boost::function<bool(const std::string& url, bool trusted_content)> execute_url_callback_t;
+ typedef std::function<void (const std::string&)> url_callback_t;
+ typedef std::function<bool(const std::string& url, bool trusted_content)> execute_url_callback_t;
static void setOpenURLCallback(url_callback_t cb);
static void setOpenURLInternalCallback(url_callback_t cb);
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index bcd13b7f0b..bba80dd20e 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -41,8 +41,7 @@
#include "lluicolortable.h"
#include "message.h"
#include "llexperiencecache.h"
-
-#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
+#include "v3dmath.h"
// Utility functions
std::string localize_slapp_label(const std::string& url, const std::string& full_name);
@@ -235,7 +234,7 @@ bool LLUrlEntryBase::isWikiLinkCorrect(const std::string &labeled_url) const
|| label.find("www.") != std::string::npos)
&& label.find("://") == std::string::npos)
{
- label = "http://" + label;
+ label = "https://" + label;
}
return !LLUrlRegistry::instance().hasUrl(label);
@@ -316,7 +315,7 @@ std::string LLUrlEntryHTTP::getUrl(const std::string &string) const
{
if (string.find("://") == std::string::npos)
{
- return "http://" + escapeUrl(string);
+ return "https://" + escapeUrl(string);
}
return escapeUrl(string);
}
@@ -1084,6 +1083,7 @@ LLUUID LLUrlEntryParcel::sSessionID(LLUUID::null);
LLHost LLUrlEntryParcel::sRegionHost;
bool LLUrlEntryParcel::sDisconnected(false);
std::set<LLUrlEntryParcel*> LLUrlEntryParcel::sParcelInfoObservers;
+std::map<LLUUID, LLVector3d> LLUrlEntryParcel::sParcelPos;
///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
@@ -1176,6 +1176,20 @@ void LLUrlEntryParcel::processParcelInfo(const LLParcelData& parcel_data)
url_entry->onParcelInfoReceived(parcel_data.parcel_id.asString(), label);
}
}
+ if (sParcelPos.find(parcel_data.parcel_id) == sParcelPos.end())
+ {
+ sParcelPos[parcel_data.parcel_id] = LLVector3d(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z);
+ }
+}
+
+// static
+LLVector3d LLUrlEntryParcel::getParcelPos(const LLUUID& parcel_id)
+{
+ if (sParcelPos.find(parcel_id) != sParcelPos.end())
+ {
+ return sParcelPos[parcel_id];
+ }
+ return LLVector3d();
}
//
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 6e7d2fc80f..efb5081103 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -41,6 +41,9 @@
#include <map>
class LLAvatarName;
+class LLVector3d;
+
+#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
typedef boost::signals2::signal<void (const std::string& url,
const std::string& label,
@@ -434,6 +437,8 @@ public:
// Processes parcel label and triggers notifying observers.
static void processParcelInfo(const LLParcelData& parcel_data);
+ static LLVector3d getParcelPos(const LLUUID& parcel_id);
+
// Next setters are used to update agent and viewer connection information
// upon events like user login, viewer disconnect and user changing region host.
// These setters are made public to be accessible from newview and should not be
@@ -447,6 +452,7 @@ private:
static LLHost sRegionHost;
static bool sDisconnected;
static std::set<LLUrlEntryParcel*> sParcelInfoObservers;
+ static std::map<LLUUID, LLVector3d> sParcelPos;
};
///
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 97212a9d2d..d747ef9555 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -48,9 +48,8 @@
#include "lltreeiterators.h"
#include "llfocusmgr.h"
+#include <functional>
#include <list>
-#include <boost/function.hpp>
-#include <boost/noncopyable.hpp>
class LLSD;
@@ -627,7 +626,7 @@ private:
LLView& getDefaultWidgetContainer() const;
// This allows special mouse-event targeting logic for testing.
- typedef boost::function<bool(const LLView*, S32 x, S32 y)> DrilldownFunc;
+ typedef std::function<bool(const LLView*, S32 x, S32 y)> DrilldownFunc;
static DrilldownFunc sDrilldown;
public:
@@ -637,7 +636,7 @@ public:
// LLView::TemporaryDrilldownFunc scoped_func(myfunctor);
// // ... test with myfunctor ...
// } // exiting block restores original LLView::sDrilldown
- class TemporaryDrilldownFunc: public boost::noncopyable
+ class TemporaryDrilldownFunc
{
public:
TemporaryDrilldownFunc(const DrilldownFunc& func):
@@ -651,6 +650,10 @@ public:
sDrilldown = mOldDrilldown;
}
+ // Non-copyable
+ TemporaryDrilldownFunc(const TemporaryDrilldownFunc&) = delete;
+ TemporaryDrilldownFunc& operator=(const TemporaryDrilldownFunc&) = delete;
+
private:
DrilldownFunc mOldDrilldown;
};
diff --git a/indra/llui/llviewereventrecorder.cpp b/indra/llui/llviewereventrecorder.cpp
index 6d907d7e45..9eefba1390 100644
--- a/indra/llui/llviewereventrecorder.cpp
+++ b/indra/llui/llviewereventrecorder.cpp
@@ -34,8 +34,6 @@ LLViewerEventRecorder::LLViewerEventRecorder() {
logEvents = false;
// Remove any previous event log file
std::string old_log_ui_events_to_llsd_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.old");
- LLFile::remove(old_log_ui_events_to_llsd_file, ENOENT);
-
mLogFilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.llsd");
LLFile::rename(mLogFilename, old_log_ui_events_to_llsd_file, ENOENT);
diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp
index 8fd85a89a1..8cd11b86b3 100644
--- a/indra/llui/llxuiparser.cpp
+++ b/indra/llui/llxuiparser.cpp
@@ -30,7 +30,7 @@
#include "llxmlnode.h"
#include "llfasttimer.h"
-#ifdef LL_USESYSTEMLIBS
+#if 1
#include <expat.h>
#else
#include "expat/expat.h"
diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h
index f755c12cbf..2179ae54d3 100644
--- a/indra/llui/llxuiparser.h
+++ b/indra/llui/llxuiparser.h
@@ -31,7 +31,7 @@
#include "llregistry.h"
#include "llxmlnode.h"
-#include <boost/function.hpp>
+#include <functional>
#include <iosfwd>
#include <stack>
#include <set>
@@ -47,7 +47,7 @@ class LLWidgetTypeRegistry
// global static instance for registering all widget types
-typedef boost::function<LLView* (LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)> LLWidgetCreatorFunc;
+typedef std::function<LLView* (LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)> LLWidgetCreatorFunc;
typedef LLRegistry<std::string, LLWidgetCreatorFunc> widget_registry_t;