summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llbutton.cpp5
-rw-r--r--indra/llui/llbutton.h5
-rw-r--r--indra/llui/llcheckboxctrl.cpp5
-rw-r--r--indra/llui/llcheckboxctrl.h5
-rw-r--r--indra/llui/llflatlistview.cpp109
-rw-r--r--indra/llui/llflatlistview.h6
-rw-r--r--indra/llui/llfloater.cpp19
-rw-r--r--indra/llui/llfloater.h5
-rw-r--r--indra/llui/llfloaterreglistener.cpp2
-rw-r--r--indra/llui/lllineeditor.cpp5
-rw-r--r--indra/llui/lllineeditor.h5
-rw-r--r--indra/llui/llmenugl.cpp9
-rw-r--r--indra/llui/llnotifications.cpp12
-rw-r--r--indra/llui/llnotificationsutil.cpp5
-rw-r--r--indra/llui/llnotificationsutil.h2
-rw-r--r--indra/llui/llpanel.cpp5
-rw-r--r--indra/llui/llpanel.h6
-rw-r--r--indra/llui/llscrollcontainer.cpp55
-rw-r--r--indra/llui/llscrollcontainer.h2
-rw-r--r--indra/llui/llsearcheditor.cpp9
-rw-r--r--indra/llui/llsearcheditor.h1
-rw-r--r--indra/llui/lltextbase.cpp110
-rw-r--r--indra/llui/lltextbase.h13
-rw-r--r--indra/llui/lltextbox.cpp7
-rw-r--r--indra/llui/lltextbox.h6
-rw-r--r--indra/llui/lltexteditor.cpp8
-rw-r--r--indra/llui/lltexteditor.h5
-rw-r--r--indra/llui/lltooltip.cpp5
-rw-r--r--indra/llui/llui.cpp6
-rw-r--r--indra/llui/lluictrl.cpp30
-rw-r--r--indra/llui/lluictrl.h28
-rw-r--r--indra/llui/lluictrlfactory.cpp4
-rw-r--r--indra/llui/lluictrlfactory.h5
-rw-r--r--indra/llui/lluiimage.cpp36
-rw-r--r--indra/llui/lluiimage.h9
-rw-r--r--indra/llui/llurlentry.cpp26
-rw-r--r--indra/llui/llurlregistry.cpp4
-rw-r--r--indra/llui/llview.cpp23
-rw-r--r--indra/llui/llview.h23
39 files changed, 433 insertions, 192 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index b91c614424..7721137e29 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -32,6 +32,7 @@
#include "linden_common.h"
+#define LLBUTTON_CPP
#include "llbutton.h"
// Linden library includes
@@ -56,6 +57,10 @@
static LLDefaultChildRegistry::Register<LLButton> r("button");
+// Compiler optimization, generate extern template
+template class LLButton* LLView::getChild<class LLButton>(
+ const std::string& name, BOOL recurse) const;
+
// globals loaded from settings.xml
S32 LLBUTTON_H_PAD = 0;
S32 LLBUTTON_V_PAD = 0;
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 8c3b4bd859..4c7400220d 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -322,5 +322,10 @@ private:
LLFrameTimer mFlashingTimer;
};
+// Build time optimization, generate once in .cpp file
+#ifndef LLBUTTON_CPP
+extern template class LLButton* LLView::getChild<class LLButton>(
+ const std::string& name, BOOL recurse) const;
+#endif
#endif // LL_LLBUTTON_H
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index 7f0f9751db..cd10dfdb1c 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -33,6 +33,7 @@
// The mutants are coming!
#include "linden_common.h"
+#define LLCHECKBOXCTRL_CPP
#include "llcheckboxctrl.h"
#include "llgl.h"
@@ -50,6 +51,10 @@ const U32 MAX_STRING_LENGTH = 10;
static LLDefaultChildRegistry::Register<LLCheckBoxCtrl> r("check_box");
+// Compiler optimization, generate extern template
+template class LLCheckBoxCtrl* LLView::getChild<class LLCheckBoxCtrl>(
+ const std::string& name, BOOL recurse) const;
+
LLCheckBoxCtrl::Params::Params()
: text_enabled_color("text_enabled_color"),
text_disabled_color("text_disabled_color"),
diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h
index b14e66b915..28d50f957d 100644
--- a/indra/llui/llcheckboxctrl.h
+++ b/indra/llui/llcheckboxctrl.h
@@ -126,5 +126,10 @@ protected:
LLUIColor mTextDisabledColor;
};
+// Build time optimization, generate once in .cpp file
+#ifndef LLCHECKBOXCTRL_CPP
+extern template class LLCheckBoxCtrl* LLView::getChild<class LLCheckBoxCtrl>(
+ const std::string& name, BOOL recurse) const;
+#endif
#endif // LL_LLCHECKBOXCTRL_H
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index ddfb0f8534..831ac66d06 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -39,8 +39,8 @@
static const LLDefaultChildRegistry::Register<LLFlatListView> flat_list_view("flat_list_view");
-const LLSD SELECTED_EVENT = LLSD().insert("selected", true);
-const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
+const LLSD SELECTED_EVENT = LLSD().with("selected", true);
+const LLSD UNSELECTED_EVENT = LLSD().with("selected", false);
static const std::string COMMENT_TEXTBOX = "comment_text";
@@ -530,7 +530,7 @@ BOOL LLFlatListView::handleKeyHere(KEY key, MASK mask)
if ( !selectNextItemPair(true, reset_selection) && reset_selection)
{
// If case we are in accordion tab notify parent to go to the previous accordion
- notifyParent(LLSD().insert("action","select_prev"));
+ notifyParent(LLSD().with("action","select_prev"));
}
break;
}
@@ -539,7 +539,7 @@ BOOL LLFlatListView::handleKeyHere(KEY key, MASK mask)
if ( !selectNextItemPair(false, reset_selection) && reset_selection)
{
// If case we are in accordion tab notify parent to go to the next accordion
- notifyParent(LLSD().insert("action","select_next"));
+ notifyParent(LLSD().with("action","select_next"));
}
break;
}
@@ -570,7 +570,7 @@ BOOL LLFlatListView::handleKeyHere(KEY key, MASK mask)
// In case we are in accordion tab notify parent to show selected rectangle
LLRect screen_rc;
localRectToScreen(selected_rc, &screen_rc);
- notifyParent(LLSD().insert("scrollToShowRect",screen_rc.getValue()));
+ notifyParent(LLSD().with("scrollToShowRect",screen_rc.getValue()));
handled = TRUE;
}
@@ -689,6 +689,17 @@ LLRect LLFlatListView::getSelectedItemsRect()
return rc;
}
+void LLFlatListView::selectFirstItem ()
+{
+ selectItemPair(mItemPairs.front(), true);
+}
+
+void LLFlatListView::selectLastItem ()
+{
+ selectItemPair(mItemPairs.back(), true);
+}
+
+
// virtual
bool LLFlatListView::selectNextItemPair(bool is_up_direction, bool reset_selection)
{
@@ -696,53 +707,53 @@ bool LLFlatListView::selectNextItemPair(bool is_up_direction, bool reset_selecti
if ( !mItemPairs.size() )
return false;
- item_pair_t* cur_sel_pair = NULL;
+
item_pair_t* to_sel_pair = NULL;
-
+ item_pair_t* cur_sel_pair = NULL;
if ( mSelectedItemPairs.size() )
{
// Take the last selected pair
cur_sel_pair = mSelectedItemPairs.back();
- }
- else
- {
- // If there weren't selected items then choose the first one bases on given direction
- cur_sel_pair = (is_up_direction) ? mItemPairs.back() : mItemPairs.front();
- // Force selection to first item
- to_sel_pair = cur_sel_pair;
- }
-
- // Bases on given direction choose next item to select
- if ( is_up_direction )
- {
- // Find current selected item position in mItemPairs list
- pairs_list_t::reverse_iterator sel_it = std::find(mItemPairs.rbegin(), mItemPairs.rend(), cur_sel_pair);
-
- for (;++sel_it != mItemPairs.rend();)
+ // Bases on given direction choose next item to select
+ if ( is_up_direction )
{
- // skip invisible items
- if ( (*sel_it)->first->getVisible() )
+ // Find current selected item position in mItemPairs list
+ pairs_list_t::reverse_iterator sel_it = std::find(mItemPairs.rbegin(), mItemPairs.rend(), cur_sel_pair);
+
+ for (;++sel_it != mItemPairs.rend();)
{
- to_sel_pair = *sel_it;
- break;
+ // skip invisible items
+ if ( (*sel_it)->first->getVisible() )
+ {
+ to_sel_pair = *sel_it;
+ break;
+ }
}
}
- }
- else
- {
- // Find current selected item position in mItemPairs list
- pairs_list_t::iterator sel_it = std::find(mItemPairs.begin(), mItemPairs.end(), cur_sel_pair);
-
- for (;++sel_it != mItemPairs.end();)
+ else
{
- // skip invisible items
- if ( (*sel_it)->first->getVisible() )
+ // Find current selected item position in mItemPairs list
+ pairs_list_t::iterator sel_it = std::find(mItemPairs.begin(), mItemPairs.end(), cur_sel_pair);
+
+ for (;++sel_it != mItemPairs.end();)
{
- to_sel_pair = *sel_it;
- break;
+ // skip invisible items
+ if ( (*sel_it)->first->getVisible() )
+ {
+ to_sel_pair = *sel_it;
+ break;
+ }
}
}
}
+ else
+ {
+ // If there weren't selected items then choose the first one bases on given direction
+ cur_sel_pair = (is_up_direction) ? mItemPairs.back() : mItemPairs.front();
+ // Force selection to first item
+ to_sel_pair = cur_sel_pair;
+ }
+
if ( to_sel_pair )
{
@@ -920,4 +931,26 @@ void LLFlatListView::onFocusLost()
mSelectedItemsBorder->setVisible(FALSE);
}
+//virtual
+S32 LLFlatListView::notify(const LLSD& info)
+{
+ if(info.has("action"))
+ {
+ std::string str_action = info["action"];
+ if(str_action == "select_first")
+ {
+ setFocus(true);
+ selectFirstItem();
+ return 1;
+ }
+ else if(str_action == "select_last")
+ {
+ setFocus(true);
+ selectLastItem();
+ return 1;
+ }
+ }
+ return 0;
+}
+
//EOF
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index 3867e910c0..ba824ff2df 100644
--- a/indra/llui/llflatlistview.h
+++ b/indra/llui/llflatlistview.h
@@ -279,6 +279,12 @@ public:
bool updateValue(const LLSD& old_value, const LLSD& new_value);
+
+ void selectFirstItem ();
+ void selectLastItem ();
+
+ virtual S32 notify(const LLSD& info) ;
+
protected:
/** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 8cf65fe76a..fd7b64af02 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -74,7 +74,6 @@ std::string LLFloater::sButtonNames[BUTTON_COUNT] =
"llfloater_minimize_btn", //BUTTON_MINIMIZE
"llfloater_tear_off_btn", //BUTTON_TEAR_OFF
"llfloater_dock_btn", //BUTTON_DOCK
- "llfloater_undock_btn", //BUTTON_UNDOCK
"llfloater_help_btn" //BUTTON_HELP
};
@@ -91,7 +90,6 @@ std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]=
"BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE
"BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF
"BUTTON_DOCK",
- "BUTTON_UNDOCK",
"BUTTON_HELP"
};
@@ -102,7 +100,6 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
LLFloater::onClickMinimize, //BUTTON_MINIMIZE
LLFloater::onClickTearOff, //BUTTON_TEAR_OFF
LLFloater::onClickDock, //BUTTON_DOCK
- LLFloater::onClickDock, //BUTTON_UNDOCK
LLFloater::onClickHelp //BUTTON_HELP
};
@@ -179,14 +176,12 @@ LLFloater::Params::Params()
minimize_image("minimize_image"),
tear_off_image("tear_off_image"),
dock_image("dock_image"),
- undock_image("undock_image"),
help_image("help_image"),
close_pressed_image("close_pressed_image"),
restore_pressed_image("restore_pressed_image"),
minimize_pressed_image("minimize_pressed_image"),
tear_off_pressed_image("tear_off_pressed_image"),
dock_pressed_image("dock_pressed_image"),
- undock_pressed_image("undock_pressed_image"),
help_pressed_image("help_pressed_image"),
open_callback("open_callback"),
close_callback("close_callback")
@@ -1395,12 +1390,10 @@ void LLFloater::setCanDock(bool b)
if(mCanDock)
{
mButtonsEnabled[BUTTON_DOCK] = !mDocked;
- mButtonsEnabled[BUTTON_UNDOCK] = mDocked;
}
else
{
mButtonsEnabled[BUTTON_DOCK] = FALSE;
- mButtonsEnabled[BUTTON_UNDOCK] = FALSE;
}
}
updateButtons();
@@ -1412,7 +1405,6 @@ void LLFloater::setDocked(bool docked, bool pop_on_undock)
{
mDocked = docked;
mButtonsEnabled[BUTTON_DOCK] = !mDocked;
- mButtonsEnabled[BUTTON_UNDOCK] = mDocked;
updateButtons();
storeDockStateControl();
@@ -1452,6 +1444,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
gFloaterView->adjustToFitScreen(self, FALSE);
// give focus to new window to keep continuity for the user
self->setFocus(TRUE);
+ self->setTornOff(true);
}
else //Attach to parent.
{
@@ -1463,6 +1456,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
// make sure host is visible
new_host->openFloater(new_host->getKey());
}
+ self->setTornOff(false);
}
}
@@ -1862,8 +1856,6 @@ LLUIImage* LLFloater::getButtonImage(const Params& p, EFloaterButton e)
return p.tear_off_image;
case BUTTON_DOCK:
return p.dock_image;
- case BUTTON_UNDOCK:
- return p.undock_image;
case BUTTON_HELP:
return p.help_image;
}
@@ -1885,8 +1877,6 @@ LLUIImage* LLFloater::getButtonPressedImage(const Params& p, EFloaterButton e)
return p.tear_off_pressed_image;
case BUTTON_DOCK:
return p.dock_pressed_image;
- case BUTTON_UNDOCK:
- return p.undock_pressed_image;
case BUTTON_HELP:
return p.help_pressed_image;
}
@@ -2347,8 +2337,7 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
}
LLRect::tCoordType screen_width = getSnapRect().getWidth();
LLRect::tCoordType screen_height = getSnapRect().getHeight();
- // convert to local coordinate frame
- LLRect snap_rect_local = getLocalSnapRect();
+
// only automatically resize non-minimized, resizable floaters
if( floater->isResizable() && !floater->isMinimized() )
@@ -2388,7 +2377,7 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
}
// move window fully onscreen
- if (floater->translateIntoRect( snap_rect_local, allow_partial_outside ))
+ if (floater->translateIntoRect( getLocalRect(), allow_partial_outside ))
{
floater->clearSnapTarget();
}
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index d7ec0aac00..daf558de24 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -90,7 +90,6 @@ public:
BUTTON_MINIMIZE,
BUTTON_TEAR_OFF,
BUTTON_DOCK,
- BUTTON_UNDOCK,
BUTTON_HELP,
BUTTON_COUNT
};
@@ -121,14 +120,12 @@ public:
minimize_image,
tear_off_image,
dock_image,
- undock_image,
help_image;
Optional<LLUIImage*> close_pressed_image,
restore_pressed_image,
minimize_pressed_image,
tear_off_pressed_image,
dock_pressed_image,
- undock_pressed_image,
help_pressed_image;
Optional<CommitCallbackParam> open_callback,
@@ -259,6 +256,8 @@ public:
bool isDocked() const { return mDocked; }
virtual void setDocked(bool docked, bool pop_on_undock = true);
+ virtual void setTornOff(bool torn_off) {}
+
// Return a closeable floater, if any, given the current focus.
static LLFloater* getClosableFloaterFromFocus();
diff --git a/indra/llui/llfloaterreglistener.cpp b/indra/llui/llfloaterreglistener.cpp
index 029d3b6810..082d7c1573 100644
--- a/indra/llui/llfloaterreglistener.cpp
+++ b/indra/llui/llfloaterreglistener.cpp
@@ -28,7 +28,7 @@ LLFloaterRegListener::LLFloaterRegListener():
add("getBuildMap",
"Return on [\"reply\"] data about all registered LLFloaterReg floater names",
&LLFloaterRegListener::getBuildMap,
- LLSD().insert("reply", LLSD()));
+ LLSD().with("reply", LLSD()));
LLSD requiredName;
requiredName["name"] = LLSD();
add("showInstance",
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 4ea30dbd4d..8a21155cc3 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -34,6 +34,7 @@
#include "linden_common.h"
+#define LLLINEEDITOR_CPP
#include "lllineeditor.h"
#include "lltexteditor.h"
@@ -71,6 +72,10 @@ const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click
static LLDefaultChildRegistry::Register<LLLineEditor> r1("line_editor");
+// Compiler optimization, generate extern template
+template class LLLineEditor* LLView::getChild<class LLLineEditor>(
+ const std::string& name, BOOL recurse) const;
+
//
// Member functions
//
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index b96220e020..49e9539b16 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -395,5 +395,10 @@ private:
}; // end class LLLineEditor
+// Build time optimization, generate once in .cpp file
+#ifndef LLLINEEDITOR_CPP
+extern template class LLLineEditor* LLView::getChild<class LLLineEditor>(
+ const std::string& name, BOOL recurse) const;
+#endif
#endif // LL_LINEEDITOR_
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index f8935d03ac..907f2352a0 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -590,12 +590,13 @@ BOOL LLMenuItemSeparatorGL::handleMouseDown(S32 x, S32 y, MASK mask)
LLMenuGL* parent_menu = getMenu();
if (y > getRect().getHeight() / 2)
{
- LLView* prev_menu_item = parent_menu->findPrevSibling(this);
+ // the menu items are in the child list in bottom up order
+ LLView* prev_menu_item = parent_menu->findNextSibling(this);
return prev_menu_item ? prev_menu_item->handleMouseDown(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
}
else
{
- LLView* next_menu_item = parent_menu->findNextSibling(this);
+ LLView* next_menu_item = parent_menu->findPrevSibling(this);
return next_menu_item ? next_menu_item->handleMouseDown(x, 0, mask) : FALSE;
}
}
@@ -605,12 +606,12 @@ BOOL LLMenuItemSeparatorGL::handleMouseUp(S32 x, S32 y, MASK mask)
LLMenuGL* parent_menu = getMenu();
if (y > getRect().getHeight() / 2)
{
- LLView* prev_menu_item = parent_menu->findPrevSibling(this);
+ LLView* prev_menu_item = parent_menu->findNextSibling(this);
return prev_menu_item ? prev_menu_item->handleMouseUp(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
}
else
{
- LLView* next_menu_item = parent_menu->findNextSibling(this);
+ LLView* next_menu_item = parent_menu->findPrevSibling(this);
return next_menu_item ? next_menu_item->handleMouseUp(x, 0, mask) : FALSE;
}
}
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 05f2d3a9cf..86989012ee 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -711,7 +711,7 @@ LLBoundListener LLNotificationChannelBase::connectChangedImpl(const LLEventListe
// only about new notifications
for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
{
- slot(LLSD().insert("sigtype", "load").insert("id", (*it)->id()));
+ slot(LLSD().with("sigtype", "load").with("id", (*it)->id()));
}
// and then connect the signal so that all future notifications will also be
// forwarded.
@@ -722,7 +722,7 @@ LLBoundListener LLNotificationChannelBase::connectAtFrontChangedImpl(const LLEve
{
for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
{
- slot(LLSD().insert("sigtype", "load").insert("id", (*it)->id()));
+ slot(LLSD().with("sigtype", "load").with("id", (*it)->id()));
}
return mChanged.connect(slot, boost::signals2::at_front);
}
@@ -907,7 +907,7 @@ void LLNotificationChannel::setComparator(LLNotificationComparator comparator)
mItems.swap(s2);
// notify clients that we've been resorted
- mChanged(LLSD().insert("sigtype", "sort"));
+ mChanged(LLSD().with("sigtype", "sort"));
}
bool LLNotificationChannel::isEmpty() const
@@ -1443,7 +1443,7 @@ void LLNotifications::add(const LLNotificationPtr pNotif)
llerrs << "Notification added a second time to the master notification channel." << llendl;
}
- updateItem(LLSD().insert("sigtype", "add").insert("id", pNotif->id()), pNotif);
+ updateItem(LLSD().with("sigtype", "add").with("id", pNotif->id()), pNotif);
}
void LLNotifications::cancel(LLNotificationPtr pNotif)
@@ -1454,7 +1454,7 @@ void LLNotifications::cancel(LLNotificationPtr pNotif)
llerrs << "Attempted to delete nonexistent notification " << pNotif->getName() << llendl;
}
pNotif->cancel();
- updateItem(LLSD().insert("sigtype", "delete").insert("id", pNotif->id()), pNotif);
+ updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif);
}
void LLNotifications::update(const LLNotificationPtr pNotif)
@@ -1462,7 +1462,7 @@ void LLNotifications::update(const LLNotificationPtr pNotif)
LLNotificationSet::iterator it=mItems.find(pNotif);
if (it != mItems.end())
{
- updateItem(LLSD().insert("sigtype", "change").insert("id", pNotif->id()), pNotif);
+ updateItem(LLSD().with("sigtype", "change").with("id", pNotif->id()), pNotif);
}
}
diff --git a/indra/llui/llnotificationsutil.cpp b/indra/llui/llnotificationsutil.cpp
index 2cd165f1b3..f343d27cb4 100644
--- a/indra/llui/llnotificationsutil.cpp
+++ b/indra/llui/llnotificationsutil.cpp
@@ -89,3 +89,8 @@ S32 LLNotificationsUtil::getSelectedOption(const LLSD& notification, const LLSD&
{
return LLNotification::getSelectedOption(notification, response);
}
+
+void LLNotificationsUtil::cancel(LLNotificationPtr pNotif)
+{
+ LLNotifications::instance().cancel(pNotif);
+}
diff --git a/indra/llui/llnotificationsutil.h b/indra/llui/llnotificationsutil.h
index a0801b338f..d552fa915b 100644
--- a/indra/llui/llnotificationsutil.h
+++ b/indra/llui/llnotificationsutil.h
@@ -63,6 +63,8 @@ namespace LLNotificationsUtil
boost::function<void (const LLSD&, const LLSD&)> functor);
S32 getSelectedOption(const LLSD& notification, const LLSD& response);
+
+ void cancel(LLNotificationPtr pNotif);
}
#endif
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 063822dd56..750b190953 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -34,6 +34,7 @@
#include "linden_common.h"
+#define LLPANEL_CPP
#include "llpanel.h"
#include "llalertdialog.h"
@@ -58,6 +59,10 @@
static LLDefaultChildRegistry::Register<LLPanel> r1("panel", &LLPanel::fromXML);
+// Compiler optimization, generate extern template
+template class LLPanel* LLView::getChild<class LLPanel>(
+ const std::string& name, BOOL recurse) const;
+
LLPanel::LocalizedString::LocalizedString()
: name("name"),
value("value")
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index 0a0fed82fb..a8bd5fd5e5 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -275,4 +275,10 @@ private:
}; // end class LLPanel
+// Build time optimization, generate once in .cpp file
+#ifndef LLPANEL_CPP
+extern template class LLPanel* LLView::getChild<class LLPanel>(
+ const std::string& name, BOOL recurse) const;
+#endif
+
#endif
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index d91b58b4ea..a5e47e8547 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -111,8 +111,7 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)
LLView::addChild( mBorder );
mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 );
- if ( mBorder->getVisible() )
- mInnerRect.stretch( -mBorder->getBorderWidth() );
+ mInnerRect.stretch( -getBorderWidth() );
LLRect vertical_scroll_rect = mInnerRect;
vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - scrollbar_size;
@@ -190,8 +189,7 @@ void LLScrollContainer::reshape(S32 width, S32 height,
LLUICtrl::reshape( width, height, called_from_parent );
mInnerRect = getLocalRect();
- if ( mBorder->getVisible() )
- mInnerRect.stretch( -mBorder->getBorderWidth() );
+ mInnerRect.stretch( -getBorderWidth() );
if (mScrolledView)
{
@@ -237,18 +235,37 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask)
BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks )
{
- if(LLUICtrl::handleScrollWheel(x,y,clicks))
+ // Give event to my child views - they may have scroll bars
+ // (Bad UI design, but technically possible.)
+ if (LLUICtrl::handleScrollWheel(x,y,clicks))
return TRUE;
- for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
- {
- // Note: tries vertical and then horizontal
+ // When the vertical scrollbar is visible, scroll wheel
+ // only affects vertical scrolling. It's confusing to have
+ // scroll wheel perform both vertical and horizontal in a
+ // single container.
+ LLScrollbar* vertical = mScrollbar[VERTICAL];
+ if (vertical->getVisible()
+ && vertical->getEnabled())
+ {
// Pretend the mouse is over the scrollbar
- if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) )
+ if (vertical->handleScrollWheel( 0, 0, clicks ) )
{
updateScroll();
- return TRUE;
}
+ // Always eat the event
+ return TRUE;
+ }
+
+ LLScrollbar* horizontal = mScrollbar[HORIZONTAL];
+ // Test enablement and visibility for consistency with
+ // LLView::childrenHandleScrollWheel().
+ if (horizontal->getVisible()
+ && horizontal->getEnabled()
+ && horizontal->handleScrollWheel( 0, 0, clicks ) )
+ {
+ updateScroll();
+ return TRUE;
}
return FALSE;
}
@@ -353,9 +370,9 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight();
- S32 border_width = (mBorder->getVisible() ? 2 * mBorder->getBorderWidth() : 0);
- *visible_width = getRect().getWidth() - border_width;
- *visible_height = getRect().getHeight() - border_width;
+ S32 border_width = getBorderWidth();
+ *visible_width = getRect().getWidth() - 2 * border_width;
+ *visible_height = getRect().getHeight() - 2 * border_width;
*show_v_scrollbar = FALSE;
*show_h_scrollbar = FALSE;
@@ -501,7 +518,7 @@ void LLScrollContainer::updateScroll()
BOOL show_h_scrollbar = FALSE;
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
- S32 border_width = mBorder->getBorderWidth();
+ S32 border_width = getBorderWidth();
if( show_v_scrollbar )
{
if( doc_rect.mTop < getRect().getHeight() - border_width )
@@ -575,6 +592,9 @@ void LLScrollContainer::updateScroll()
void LLScrollContainer::setBorderVisible(BOOL b)
{
mBorder->setVisible( b );
+ // Recompute inner rect, as border visibility changes it
+ mInnerRect = getLocalRect();
+ mInnerRect.stretch( -getBorderWidth() );
}
LLRect LLScrollContainer::getVisibleContentRect()
@@ -586,15 +606,16 @@ LLRect LLScrollContainer::getVisibleContentRect()
return visible_rect;
}
-LLRect LLScrollContainer::getContentWindowRect() const
+LLRect LLScrollContainer::getContentWindowRect()
{
+ updateScroll();
LLRect scroller_view_rect;
S32 visible_width = 0;
S32 visible_height = 0;
BOOL show_h_scrollbar = FALSE;
BOOL show_v_scrollbar = FALSE;
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
- S32 border_width = mBorder->getVisible() ? mBorder->getBorderWidth() : 0;
+ S32 border_width = getBorderWidth();
scroller_view_rect.setOriginAndSize(border_width,
show_h_scrollbar ? mScrollbar[HORIZONTAL]->getRect().mTop : border_width,
visible_width,
@@ -675,7 +696,7 @@ void LLScrollContainer::goToBottom()
S32 LLScrollContainer::getBorderWidth() const
{
- if (mBorder)
+ if (mBorder->getVisible())
{
return mBorder->getBorderWidth();
}
diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h
index ac8ffe5258..25dcd071ab 100644
--- a/indra/llui/llscrollcontainer.h
+++ b/indra/llui/llscrollcontainer.h
@@ -96,7 +96,7 @@ public:
void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; }
LLRect getVisibleContentRect();
- LLRect getContentWindowRect() const;
+ LLRect getContentWindowRect();
const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
void pageUp(S32 overlap = 0);
void pageDown(S32 overlap = 0);
diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp
index fad2b7bc99..6fa99df82e 100644
--- a/indra/llui/llsearcheditor.cpp
+++ b/indra/llui/llsearcheditor.cpp
@@ -141,6 +141,15 @@ void LLSearchEditor::clear()
}
}
+//virtual
+void LLSearchEditor::setFocus( BOOL b )
+{
+ if (mSearchEditor)
+ {
+ mSearchEditor->setFocus(b);
+ }
+}
+
void LLSearchEditor::onClearButtonClick(const LLSD& data)
{
setText(LLStringUtil::null);
diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h
index f395e7e816..bd2d595174 100644
--- a/indra/llui/llsearcheditor.h
+++ b/indra/llui/llsearcheditor.h
@@ -83,6 +83,7 @@ public:
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
virtual void setLabel( const LLStringExplicit &new_label );
virtual void clear();
+ virtual void setFocus( BOOL b );
void setKeystrokeCallback( commit_callback_t cb ) { mKeystrokeCallback = cb; }
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7bf10d774c..2a9515171a 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -156,6 +156,7 @@ LLTextBase::Params::Params()
read_only("read_only", false),
v_pad("v_pad", 0),
h_pad("h_pad", 0),
+ clip_partial("clip_partial", true),
line_spacing("line_spacing"),
max_text_length("max_length", 255),
font_shadow("font_shadow"),
@@ -193,6 +194,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mHAlign(p.font_halign),
mLineSpacingMult(p.line_spacing.multiple),
mLineSpacingPixels(p.line_spacing.pixels),
+ mClipPartial(p.clip_partial && !p.allow_scroll),
mTrackEnd( p.track_end ),
mScrollIndex(-1),
mSelectionStart( 0 ),
@@ -379,10 +381,10 @@ void LLTextBase::drawSelectionBackground()
// Draw the selection box (we're using a box instead of reversing the colors on the selected text).
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- const LLColor4& color = mReadOnly ? mReadOnlyBgColor.get() : mWriteableBgColor.get();
+ const LLColor4& color = mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get();
F32 alpha = hasFocus() ? 0.7f : 0.3f;
alpha *= getDrawContext().mAlpha;
- gGL.color4f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], alpha );
+ LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha);
for (std::vector<LLRect>::iterator rect_it = selection_rects.begin();
rect_it != selection_rects.end();
@@ -390,7 +392,7 @@ void LLTextBase::drawSelectionBackground()
{
LLRect selection_rect = *rect_it;
selection_rect.translate(mTextRect.mLeft - content_display_rect.mLeft, mTextRect.mBottom - content_display_rect.mBottom);
- gl_rect_2d(selection_rect);
+ gl_rect_2d(selection_rect, selection_color);
}
}
}
@@ -504,7 +506,7 @@ void LLTextBase::drawText()
}
LLRect scrolled_view_rect = getVisibleDocumentRect();
- std::pair<S32, S32> line_range = getVisibleLines();
+ std::pair<S32, S32> line_range = getVisibleLines(mClipPartial);
S32 first_line = line_range.first;
S32 last_line = line_range.second;
if (first_line >= last_line)
@@ -524,25 +526,21 @@ void LLTextBase::drawText()
for (S32 cur_line = first_line; cur_line < last_line; cur_line++)
{
+ S32 next_line = cur_line + 1;
line_info& line = mLineInfoList[cur_line];
- if ((line.mRect.mTop - scrolled_view_rect.mBottom) < mTextRect.mBottom)
- {
- break;
- }
-
S32 next_start = -1;
S32 line_end = text_len;
- if ((cur_line + 1) < getLineCount())
+ if (next_line < getLineCount())
{
- next_start = getLineStart(cur_line + 1);
+ next_start = getLineStart(next_line);
line_end = next_start;
}
LLRect text_rect(line.mRect.mLeft + mTextRect.mLeft - scrolled_view_rect.mLeft,
line.mRect.mTop - scrolled_view_rect.mBottom + mTextRect.mBottom,
- mDocumentView->getRect().getWidth() - scrolled_view_rect.mLeft,
+ llmin(mDocumentView->getRect().getWidth(), line.mRect.mRight) - scrolled_view_rect.mLeft,
line.mRect.mBottom - scrolled_view_rect.mBottom + mTextRect.mBottom);
// draw a single line of text
@@ -562,6 +560,17 @@ void LLTextBase::drawText()
}
S32 clipped_end = llmin( line_end, cur_segment->getEnd() ) - cur_segment->getStart();
+
+ if (mUseEllipses
+ && clipped_end == line_end
+ && next_line == last_line
+ && last_line < (S32)mLineInfoList.size())
+ {
+ // more text to go, but we can't fit it
+ // so attempt to draw one extra character to force ellipses
+ clipped_end++;
+ }
+
text_rect.mLeft = (S32)(cur_segment->draw(seg_start - cur_segment->getStart(), clipped_end, selection_left, selection_right, text_rect));
seg_start = clipped_end + cur_segment->getStart();
@@ -641,8 +650,6 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
if ( truncate() )
{
- // The user's not getting everything he's hoping for
- make_ui_sound("UISndBadKeystroke");
insert_len = getLength() - old_len;
}
@@ -1066,10 +1073,16 @@ void LLTextBase::reflow(S32 start_index)
{
mReflowNeeded = FALSE;
+ // shrink document to minimum size (visible portion of text widget)
+ // to force inlined widgets with follows set to shrink
+ mDocumentView->setShape(mTextRect);
+
bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false;
LLRect old_cursor_rect = getLocalRectFromDocIndex(mCursorPos);
bool follow_selection = mTextRect.overlaps(old_cursor_rect); // cursor is visible
+ old_cursor_rect.translate(-mTextRect.mLeft, -mTextRect.mBottom);
+
S32 first_line = getFirstVisibleLine();
// if scroll anchor not on first line, update it to first character of first line
@@ -1080,6 +1093,8 @@ void LLTextBase::reflow(S32 start_index)
mScrollIndex = mLineInfoList[first_line].mDocIndexStart;
}
LLRect first_char_rect = getLocalRectFromDocIndex(mScrollIndex);
+ // subtract off effect of horizontal scrollbar from local position of first char
+ first_char_rect.translate(-mTextRect.mLeft, -mTextRect.mBottom);
S32 cur_top = 0;
@@ -1178,6 +1193,10 @@ void LLTextBase::reflow(S32 start_index)
++seg_iter;
seg_offset = 0;
}
+ if (force_newline)
+ {
+ line_count++;
+ }
}
// calculate visible region for diplaying text
@@ -1195,7 +1214,6 @@ void LLTextBase::reflow(S32 start_index)
// apply scroll constraints after reflowing text
if (!hasMouseCapture() && mScroller)
{
- LLRect visible_content_rect = getVisibleDocumentRect();
if (scrolled_to_bottom && mTrackEnd)
{
// keep bottom of text buffer visible
@@ -1204,18 +1222,14 @@ void LLTextBase::reflow(S32 start_index)
else if (hasSelection() && follow_selection)
{
// keep cursor in same vertical position on screen when selecting text
- LLRect new_cursor_rect_doc = getLocalRectFromDocIndex(mCursorPos);
- new_cursor_rect_doc.translate(visible_content_rect.mLeft, visible_content_rect.mBottom);
+ LLRect new_cursor_rect_doc = getDocRectFromDocIndex(mCursorPos);
mScroller->scrollToShowRect(new_cursor_rect_doc, old_cursor_rect);
- //llassert_always(getLocalRectFromDocIndex(mCursorPos).mBottom == old_cursor_rect.mBottom);
}
else
{
// keep first line of text visible
- LLRect new_first_char_rect = getLocalRectFromDocIndex(mScrollIndex);
- new_first_char_rect.translate(visible_content_rect.mLeft, visible_content_rect.mBottom);
+ LLRect new_first_char_rect = getDocRectFromDocIndex(mScrollIndex);
mScroller->scrollToShowRect(new_first_char_rect, first_char_rect);
- //llassert_always(getLocalRectFromDocIndex(mScrollIndex).mBottom == first_char_rect.mBottom);
}
}
@@ -1325,13 +1339,11 @@ std::pair<S32, S32> LLTextBase::getVisibleLines(bool fully_visible)
if (fully_visible)
{
- // binary search for line that starts before top of visible buffer and starts before end of visible buffer
first_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mTop, compare_top());
last_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mBottom, compare_bottom());
}
else
{
- // binary search for line that starts before top of visible buffer and starts before end of visible buffer
first_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mTop, compare_bottom());
last_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mBottom, compare_top());
}
@@ -1464,14 +1476,16 @@ void LLTextBase::setText(const LLStringExplicit &utf8str ,const LLStyle::Params&
clearSegments();
// createDefaultSegment();
- startOfDoc();
deselect();
// append the new text (supports Url linking)
std::string text(utf8str);
LLStringUtil::removeCRLF(text);
+ // appendText modifies mCursorPos...
appendText(text, false, input_params);
+ // ...so move cursor to top after appending text
+ startOfDoc();
onValueChange(0, getLength());
}
@@ -2065,22 +2079,22 @@ void LLTextBase::updateRects()
mContentsRect.unionWith(line_iter->mRect);
}
- S32 delta_pos_x = -mContentsRect.mLeft;
mContentsRect.mTop += mVPad;
S32 delta_pos = -mContentsRect.mBottom;
// move line segments to fit new document rect
for (line_list_t::iterator it = mLineInfoList.begin(); it != mLineInfoList.end(); ++it)
{
- it->mRect.translate(delta_pos_x, delta_pos);
+ it->mRect.translate(0, delta_pos);
}
- mContentsRect.translate(delta_pos_x, delta_pos);
+ mContentsRect.translate(0, delta_pos);
}
// update document container dimensions according to text contents
LLRect doc_rect = mContentsRect;
// use old mTextRect constraint document to width of viewable region
- doc_rect.mRight = doc_rect.mLeft + mTextRect.getWidth();
+ doc_rect.mLeft = 0;
+ doc_rect.mRight = llmax(mTextRect.getWidth(), mContentsRect.mRight);
mDocumentView->setShape(doc_rect);
@@ -2100,7 +2114,7 @@ void LLTextBase::updateRects()
}
// update document container again, using new mTextRect
- doc_rect.mRight = doc_rect.mLeft + mTextRect.getWidth();
+ doc_rect.mRight = llmax(mTextRect.getWidth(), mContentsRect.mRight);
mDocumentView->setShape(doc_rect);
}
@@ -2193,6 +2207,12 @@ LLNormalTextSegment::LLNormalTextSegment( const LLStyleSP& style, S32 start, S32
mEditor(editor)
{
mFontHeight = llceil(mStyle->getFont()->getLineHeight());
+
+ LLUIImagePtr image = mStyle->getImage();
+ if (image.notNull())
+ {
+ mImageLoadedConnection = image->addLoadedCallback(boost::bind(&LLTextBase::needsReflow, &mEditor));
+ }
}
LLNormalTextSegment::LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible)
@@ -2205,6 +2225,12 @@ LLNormalTextSegment::LLNormalTextSegment( const LLColor4& color, S32 start, S32
mFontHeight = llceil(mStyle->getFont()->getLineHeight());
}
+LLNormalTextSegment::~LLNormalTextSegment()
+{
+ mImageLoadedConnection.disconnect();
+}
+
+
F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
{
if( end - start > 0 )
@@ -2218,7 +2244,7 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec
// Center the image vertically
S32 image_bottom = draw_rect.getCenterY() - (style_image_height/2);
image->draw(draw_rect.mLeft, image_bottom,
- style_image_width, style_image_height);
+ style_image_width, style_image_height, color);
}
return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect);
@@ -2281,7 +2307,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
LLFontGL::LEFT, LLFontGL::TOP,
0,
LLFontGL::NO_SHADOW,
- length, rect.mRight,
+ length, rect.getWidth(),
&right_x,
mEditor.getUseEllipses());
}
@@ -2298,7 +2324,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
LLFontGL::LEFT, LLFontGL::TOP,
0,
mStyle->getShadowType(),
- length, rect.mRight,
+ length, rect.getWidth(),
&right_x,
mEditor.getUseEllipses());
}
@@ -2380,12 +2406,20 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip)
bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
{
- LLWString text = mEditor.getWText();
-
height = mFontHeight;
- width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
- // if last character is a newline, then return true, forcing line break
- llwchar last_char = text[mStart + first_char + num_chars - 1];
+ bool force_newline = false;
+ if (num_chars > 0)
+ {
+ LLWString text = mEditor.getWText();
+ width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
+ // if last character is a newline, then return true, forcing line break
+ llwchar last_char = text[mStart + first_char + num_chars - 1];
+ force_newline = (last_char == '\n');
+ }
+ else
+ {
+ width = 0;
+ }
LLUIImagePtr image = mStyle->getImage();
if( image.notNull())
@@ -2394,7 +2428,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
height = llmax(height, image->getHeight());
}
- return num_chars >= 1 && last_char == '\n';
+ return force_newline;
}
S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index c376a73615..0138ca3704 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -84,11 +84,13 @@ public:
wrap,
use_ellipses,
allow_html,
- parse_highlights;
+ parse_highlights,
+ clip_partial;
Optional<S32> v_pad,
h_pad;
+
Optional<LineSpacingParams>
line_spacing;
@@ -134,7 +136,6 @@ public:
// TODO: move into LLTextSegment?
void createUrlContextMenu(S32 x, S32 y, const std::string &url); // create a popup context menu for the given Url
-
// Text accessors
// TODO: add optional style parameter
virtual void setText(const LLStringExplicit &utf8str , const LLStyle::Params& input_params = LLStyle::Params()); // uses default style
@@ -146,6 +147,8 @@ public:
LLWString getWText() const;
void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());
+ // force reflow of text
+ void needsReflow() { mReflowNeeded = TRUE; }
S32 getLength() const { return getWText().length(); }
S32 getLineCount() const { return mLineInfoList.size(); }
@@ -160,7 +163,6 @@ public:
S32 getVPad() { return mVPad; }
S32 getHPad() { return mHPad; }
-
S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
LLRect getLocalRectFromDocIndex(S32 pos) const;
LLRect getDocRectFromDocIndex(S32 pos) const;
@@ -178,6 +180,7 @@ public:
void changePage( S32 delta );
void changeLine( S32 delta );
+
const LLFontGL* getDefaultFont() const { return mDefaultFont; }
public:
@@ -301,7 +304,6 @@ protected:
// misc
void updateRects();
- void needsReflow() { mReflowNeeded = TRUE; }
void needsScroll() { mScrollNeeded = TRUE; }
void replaceUrlLabel(const std::string &url, const std::string &label);
@@ -347,6 +349,7 @@ protected:
bool mTrackEnd; // if true, keeps scroll position at end of document during resize
bool mReadOnly;
bool mBGVisible; // render background?
+ bool mClipPartial; // false if we show lines that are partially inside bounding rect
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
// support widgets
@@ -423,6 +426,7 @@ class LLNormalTextSegment : public LLTextSegment
public:
LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextBase& editor );
LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
+ ~LLNormalTextSegment();
/*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
/*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
@@ -454,6 +458,7 @@ protected:
S32 mFontHeight;
LLKeywordToken* mToken;
std::string mTooltip;
+ boost::signals2::connection mImageLoadedConnection;
};
class LLIndexSegment : public LLTextSegment
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 4c4123cf45..0bd0ab59fb 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -31,7 +31,10 @@
*/
#include "linden_common.h"
+
+#define LLTEXTBOX_CPP
#include "lltextbox.h"
+
#include "lluictrlfactory.h"
#include "llfocusmgr.h"
#include "llwindow.h"
@@ -40,6 +43,10 @@
static LLDefaultChildRegistry::Register<LLTextBox> r("text");
+// Compiler optimization, generate extern template
+template class LLTextBox* LLView::getChild<class LLTextBox>(
+ const std::string& name, BOOL recurse) const;
+
LLTextBox::LLTextBox(const LLTextBox::Params& p)
: LLTextBase(p),
mClickedCallback(NULL)
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index 01b4bfa5ed..3a045534d3 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -79,4 +79,10 @@ protected:
callback_t mClickedCallback;
};
+// Build time optimization, generate once in .cpp file
+#ifndef LLTEXTBOX_CPP
+extern template class LLTextBox* LLView::getChild<class LLTextBox>(
+ const std::string& name, BOOL recurse) const;
+#endif
+
#endif
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 3f4ef24f82..e68affc36c 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1,6 +1,5 @@
/**
* @file lltexteditor.cpp
- * @brief LLTextEditor base class
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
@@ -34,6 +33,7 @@
#include "linden_common.h"
+#define LLTEXTEDITOR_CPP
#include "lltexteditor.h"
#include "llfontfreetype.h" // for LLFontFreetype::FIRST_CHAR
@@ -73,6 +73,10 @@
//
static LLDefaultChildRegistry::Register<LLTextEditor> r("simple_text_editor");
+// Compiler optimization, generate extern template
+template class LLTextEditor* LLView::getChild<class LLTextEditor>(
+ const std::string& name, BOOL recurse) const;
+
//
// Constants
//
@@ -2158,7 +2162,7 @@ void LLTextEditor::drawLineNumbers()
return;
}
- S32 cursor_line = getLineNumFromDocIndex(mCursorPos);
+ S32 cursor_line = mLineInfoList[getLineNumFromDocIndex(mCursorPos)].mLineNum;
if (mShowLineNumbers)
{
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index fb014b86bf..043dda8fa6 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -334,5 +334,10 @@ private:
LLContextMenu* mContextMenu;
}; // end class LLTextEditor
+// Build time optimization, generate once in .cpp file
+#ifndef LLTEXTEDITOR_CPP
+extern template class LLTextEditor* LLView::getChild<class LLTextEditor>(
+ const std::string& name, BOOL recurse) const;
+#endif
#endif // LL_TEXTEDITOR_
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index d7228c78bd..01c7a81309 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -300,9 +300,8 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)
mTextBox->setText(p.message());
}
- LLRect text_contents_rect = mTextBox->getContentsRect();
- S32 text_width = llmin(p.max_width(), text_contents_rect.getWidth());
- S32 text_height = text_contents_rect.getHeight();
+ S32 text_width = llmin(p.max_width(), mTextBox->getTextPixelWidth());
+ S32 text_height = mTextBox->getTextPixelHeight();
mTextBox->reshape(text_width, text_height);
// reshape tooltip panel to fit text box
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 4cf503b413..6603887905 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -1847,8 +1847,8 @@ LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
// spawn_x and spawn_y are top left corner of view in screen GL coordinates
void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y)
{
- const S32 CURSOR_HEIGHT = 18; // Approximate "normal" cursor size
- const S32 CURSOR_WIDTH = 9;
+ const S32 CURSOR_HEIGHT = 16; // Approximate "normal" cursor size
+ const S32 CURSOR_WIDTH = 8;
LLView* parent = view->getParent();
@@ -1866,7 +1866,7 @@ void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y)
LLRect virtual_window_rect = parent->getLocalRect();
LLRect mouse_rect;
- const S32 MOUSE_CURSOR_PADDING = 5;
+ const S32 MOUSE_CURSOR_PADDING = 1;
mouse_rect.setLeftTopAndSize(mouse_x - MOUSE_CURSOR_PADDING,
mouse_y + MOUSE_CURSOR_PADDING,
CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2,
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index a30d5b4651..706712ec5e 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -31,15 +31,43 @@
* $/LicenseInfo$
*/
-//#include "llviewerprecompiledheaders.h"
#include "linden_common.h"
+
+#define LLUICTRL_CPP
#include "lluictrl.h"
+
#include "llfocusmgr.h"
#include "llpanel.h"
#include "lluictrlfactory.h"
static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl");
+// Compiler optimization, generate extern template
+template class LLUICtrl* LLView::getChild<class LLUICtrl>(
+ const std::string& name, BOOL recurse) const;
+
+LLUICtrl::CallbackParam::CallbackParam()
+: name("name"),
+ function_name("function"),
+ parameter("parameter"),
+ control_name("control") // Shortcut to control -> "control_name" for backwards compatability
+{
+ addSynonym(parameter, "userdata");
+}
+
+LLUICtrl::EnableControls::EnableControls()
+: enabled("enabled_control"),
+ disabled("disabled_control")
+{}
+
+LLUICtrl::ControlVisibility::ControlVisibility()
+: visible("visibility_control"),
+ invisible("invisibility_control")
+{
+ addSynonym(visible, "visiblity_control");
+ addSynonym(invisible, "invisiblity_control");
+}
+
LLUICtrl::Params::Params()
: tab_stop("tab_stop", true),
chrome("chrome", false),
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index aef1bcd519..b20ff5d798 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -75,14 +75,7 @@ public:
Optional<std::string> control_name;
- CallbackParam()
- : name("name"),
- function_name("function"),
- parameter("parameter"),
- control_name("control") // Shortcut to control -> "control_name" for backwards compatability
- {
- addSynonym(parameter, "userdata");
- }
+ CallbackParam();
};
struct CommitCallbackParam : public LLInitParam::Block<CommitCallbackParam, CallbackParam >
@@ -105,23 +98,14 @@ public:
Alternative<std::string> enabled;
Alternative<std::string> disabled;
- EnableControls()
- : enabled("enabled_control"),
- disabled("disabled_control")
- {}
+ EnableControls();
};
struct ControlVisibility : public LLInitParam::Choice<ControlVisibility>
{
Alternative<std::string> visible;
Alternative<std::string> invisible;
- ControlVisibility()
- : visible("visibility_control"),
- invisible("invisibility_control")
- {
- addSynonym(visible, "visiblity_control");
- addSynonym(invisible, "invisiblity_control");
- }
+ ControlVisibility();
};
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
@@ -328,4 +312,10 @@ private:
class DefaultTabGroupFirstSorter;
};
+// Build time optimization, generate once in .cpp file
+#ifndef LLUICTRL_CPP
+extern template class LLUICtrl* LLView::getChild<class LLUICtrl>(
+ const std::string& name, BOOL recurse) const;
+#endif
+
#endif // LL_LLUICTRL_H
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 1c1450d7e9..3643bf44f7 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -32,6 +32,7 @@
#include "linden_common.h"
+#define LLUICTRLFACTORY_CPP
#include "lluictrlfactory.h"
#include "llxmlnode.h"
@@ -75,6 +76,9 @@ public:
static LLDefaultChildRegistry::Register<LLUICtrlLocate> r1("locate");
+// Build time optimization, generate this once in .cpp file
+template class LLUICtrlFactory* LLSingleton<class LLUICtrlFactory>::getInstance();
+
//-----------------------------------------------------------------------------
// LLUICtrlFactory()
//-----------------------------------------------------------------------------
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 8a9c9e23c1..55d7d745eb 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -108,6 +108,11 @@ extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP;
extern LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION;
extern LLFastTimer::DeclareTimer FTM_INIT_FROM_PARAMS;
+// Build time optimization, generate this once in .cpp file
+#ifndef LLUICTRLFACTORY_CPP
+extern template class LLUICtrlFactory* LLSingleton<class LLUICtrlFactory>::getInstance();
+#endif
+
class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
{
private:
diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp
index a8683e55c3..f941f391eb 100644
--- a/indra/llui/lluiimage.cpp
+++ b/indra/llui/lluiimage.cpp
@@ -39,18 +39,20 @@
#include "lluiimage.h"
#include "llui.h"
-LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image) :
- mName(name),
- mImage(image),
- mScaleRegion(0.f, 1.f, 1.f, 0.f),
- mClipRegion(0.f, 1.f, 1.f, 0.f),
- mUniformScaling(TRUE),
- mNoClip(TRUE)
+LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
+: mName(name),
+ mImage(image),
+ mScaleRegion(0.f, 1.f, 1.f, 0.f),
+ mClipRegion(0.f, 1.f, 1.f, 0.f),
+ mUniformScaling(TRUE),
+ mNoClip(TRUE),
+ mImageLoaded(NULL)
{
}
LLUIImage::~LLUIImage()
{
+ delete mImageLoaded;
}
void LLUIImage::setClipRegion(const LLRectf& region)
@@ -138,6 +140,25 @@ S32 LLUIImage::getTextureHeight() const
return mImage->getHeight(0);
}
+boost::signals2::connection LLUIImage::addLoadedCallback( const image_loaded_signal_t::slot_type& cb )
+{
+ if (!mImageLoaded)
+ {
+ mImageLoaded = new image_loaded_signal_t();
+ }
+ return mImageLoaded->connect(cb);
+}
+
+
+void LLUIImage::onImageLoaded()
+{
+ if (mImageLoaded)
+ {
+ (*mImageLoaded)();
+ }
+}
+
+
namespace LLInitParam
{
LLUIImage* TypedParam<LLUIImage*>::getValueFromBlock() const
@@ -170,3 +191,4 @@ namespace LLInitParam
return (a == b);
}
}
+
diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h
index 9d734bcfdf..5fa9610ab2 100644
--- a/indra/llui/lluiimage.h
+++ b/indra/llui/lluiimage.h
@@ -39,6 +39,7 @@
#include "llrefcount.h"
#include "llrect.h"
#include <boost/function.hpp>
+#include <boost/signals2.hpp>
#include "llinitparam.h"
#include "lltexture.h"
@@ -47,6 +48,8 @@ extern const LLColor4 UI_VERTEX_COLOR;
class LLUIImage : public LLRefCount
{
public:
+ typedef boost::signals2::signal<void (void)> image_loaded_signal_t;
+
LLUIImage(const std::string& name, LLPointer<LLTexture> image);
virtual ~LLUIImage();
@@ -77,7 +80,13 @@ public:
S32 getTextureWidth() const;
S32 getTextureHeight() const;
+ boost::signals2::connection addLoadedCallback( const image_loaded_signal_t::slot_type& cb );
+
+ void onImageLoaded();
+
protected:
+ image_loaded_signal_t* mImageLoaded;
+
std::string mName;
LLRectf mScaleRegion;
LLRectf mClipRegion;
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index b51709e208..7694d02837 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -386,36 +386,24 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
//
// LLUrlEntryInventory Describes a Second Life inventory Url, e.g.,
-// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select
+// secondlife:///app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select
//
LLUrlEntryInventory::LLUrlEntryInventory()
{
- mPattern = boost::regex("secondlife:///app/inventory/[\\da-f-]+/\\w+",
+ //*TODO: add supporting of inventory item names with whitespaces
+ //this pattern cann't parse for example
+ //secondlife:///app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select?name=name with spaces&param2=value
+ mPattern = boost::regex("secondlife:///app/inventory/[\\da-f-]+/\\w+\\S*",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_inventory.xml";
}
std::string LLUrlEntryInventory::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
- return unescapeUrl(url);
- // TODO: Figure out if we can somehow access the inventory from here to get the actual item name
- /*
- std::string inventory_id_string = getIDStringFromUrl(url);
- if (inventory_id_string.empty())
- {
- // something went wrong, give raw url
- return unescapeUrl(url);
- }
- LLUUID inventory_id(inventory_id_string);
- LLInventoryItem* item = gInventory.getItem(inventory_id);
- if(!item)
- {
- return unescapeUrl(url);
- }
- return item->getName(); */
+ std::string label = getStringAfterToken(url, "name=");
+ return LLURI::unescape(label.empty() ? url : label);
}
-
///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index b2f084e5ac..f47db2db1a 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -53,9 +53,11 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryTeleport());
registerUrl(new LLUrlEntryWorldMap());
registerUrl(new LLUrlEntryPlace());
+ registerUrl(new LLUrlEntryInventory());
+ //LLUrlEntrySL and LLUrlEntrySLLabel have more common pattern,
+ //so it should be registered in the end of list
registerUrl(new LLUrlEntrySL());
registerUrl(new LLUrlEntrySLLabel());
- registerUrl(new LLUrlEntryInventory());
}
LLUrlRegistry::~LLUrlRegistry()
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index dba24ee165..8917e4b813 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -33,6 +33,7 @@
#include "linden_common.h"
+#define LLVIEW_CPP
#include "llview.h"
#include <cassert>
@@ -76,8 +77,17 @@ std::vector<LLViewDrawContext*> LLViewDrawContext::sDrawContextStack;
BOOL LLView::sIsDrawing = FALSE;
#endif
+// Compiler optimization, generate extern template
+template class LLView* LLView::getChild<class LLView>(
+ const std::string& name, BOOL recurse) const;
+
static LLDefaultChildRegistry::Register<LLView> r("view");
+LLView::Follows::Follows()
+: string(""),
+ flags("flags", FOLLOWS_LEFT | FOLLOWS_TOP)
+{}
+
LLView::Params::Params()
: name("name", std::string("unnamed")),
enabled("enabled", true),
@@ -2523,6 +2533,7 @@ void LLView::setupParams(LLView::Params& p, LLView* parent)
else
{
p.rect.left = p.rect.left + parent_rect.getWidth()/2 - p.rect.width/2;
+ p.rect.right.setProvided(false); // recalculate the right
}
}
else
@@ -2543,6 +2554,7 @@ void LLView::setupParams(LLView::Params& p, LLView* parent)
else
{
p.rect.bottom = p.rect.bottom + parent_rect.getHeight()/2 - p.rect.height/2;
+ p.rect.top.setProvided(false); // recalculate the top
}
}
else
@@ -2838,18 +2850,21 @@ LLView::default_widget_map_t& LLView::getDefaultWidgetMap() const
return *mDefaultWidgets;
}
-void LLView::notifyParent(const LLSD& info)
+S32 LLView::notifyParent(const LLSD& info)
{
LLView* parent = getParent();
if(parent)
- parent->notifyParent(info);
+ return parent->notifyParent(info);
+ return 0;
}
-void LLView::notifyChildren(const LLSD& info)
+bool LLView::notifyChildren(const LLSD& info)
{
+ bool ret = false;
for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
{
- (*child_it)->notifyChildren(info);
+ ret |= (*child_it)->notifyChildren(info);
}
+ return ret;
}
// convenient accessor for draw context
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 2607120e17..f8460f5361 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -111,10 +111,7 @@ public:
Alternative<std::string> string;
Alternative<U32> flags;
- Follows()
- : string(""),
- flags("flags", FOLLOWS_LEFT | FOLLOWS_TOP)
- {}
+ Follows();
};
struct Params : public LLInitParam::Block<Params>
@@ -514,8 +511,15 @@ public:
virtual void handleReshape(const LLRect& rect, bool by_user);
virtual void dirtyRect();
- virtual void notifyParent(const LLSD& info);
- virtual void notifyChildren(const LLSD& info);
+ //send custom notification to LLView parent
+ virtual S32 notifyParent(const LLSD& info);
+
+ //send custom notification to all view childrend
+ // return true if _any_ children return true. otherwise false.
+ virtual bool notifyChildren(const LLSD& info);
+
+ //send custom notification to current view
+ virtual S32 notify(const LLSD& info) { return 0;};
static const LLViewDrawContext& getDrawContext();
@@ -659,4 +663,11 @@ template <class T> T* LLView::getChild(const std::string& name, BOOL recurse) co
return result;
}
+// Compiler optimization - don't generate these specializations inline,
+// require explicit specialization. See llbutton.cpp for an example.
+#ifndef LLVIEW_CPP
+extern template class LLView* LLView::getChild<class LLView>(
+ const std::string& name, BOOL recurse) const;
+#endif
+
#endif //LL_LLVIEW_H