summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/CMakeLists.txt3
-rw-r--r--indra/llui/llbutton.cpp9
-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.cpp127
-rw-r--r--indra/llui/llflatlistview.h6
-rw-r--r--indra/llui/llfloater.cpp134
-rw-r--r--indra/llui/llfloater.h63
-rw-r--r--indra/llui/llfloaterreglistener.cpp2
-rw-r--r--indra/llui/lllineeditor.cpp56
-rw-r--r--indra/llui/lllineeditor.h9
-rw-r--r--indra/llui/llmenugl.cpp9
-rw-r--r--indra/llui/llnotificationptr.h41
-rw-r--r--indra/llui/llnotifications.cpp26
-rw-r--r--indra/llui/llnotifications.h11
-rw-r--r--indra/llui/llnotificationsutil.cpp91
-rw-r--r--indra/llui/llnotificationsutil.h68
-rw-r--r--indra/llui/llpanel.cpp5
-rw-r--r--indra/llui/llpanel.h6
-rw-r--r--indra/llui/llprogressbar.cpp9
-rw-r--r--indra/llui/llresizebar.cpp5
-rw-r--r--indra/llui/llscrollcontainer.cpp22
-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.cpp91
-rw-r--r--indra/llui/lltextbase.h5
-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.cpp7
-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/llview.cpp12
-rw-r--r--indra/llui/llview.h14
39 files changed, 706 insertions, 245 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index f0b4436df5..74b49b846e 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -60,6 +60,7 @@ set(llui_SOURCE_FILES
llmultisliderctrl.cpp
llnotifications.cpp
llnotificationslistener.cpp
+ llnotificationsutil.cpp
llpanel.cpp
llprogressbar.cpp
llradiogroup.cpp
@@ -147,8 +148,10 @@ set(llui_HEADER_FILES
llmultifloater.h
llmultisliderctrl.h
llmultislider.h
+ llnotificationptr.h
llnotifications.h
llnotificationslistener.h
+ llnotificationsutil.h
llpanel.h
llprogressbar.h
llradiogroup.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 8930e32055..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
@@ -48,7 +49,7 @@
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llwindow.h"
-#include "llnotifications.h"
+#include "llnotificationsutil.h"
#include "llrender.h"
#include "lluictrlfactory.h"
#include "llhelp.h"
@@ -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;
@@ -1106,7 +1111,7 @@ void LLButton::showHelp(LLUICtrl* ctrl, const LLSD& sdname)
// display an error if we can't find a help_topic string.
// fix this by adding a help_topic attribute to the xui file
- LLNotifications::instance().add("UnableToFindHelpTopic");
+ LLNotificationsUtil::add("UnableToFindHelpTopic");
}
void LLButton::resetMouseDownTimer()
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 8de3a8a96f..d4c3cfb7b6 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";
@@ -484,6 +484,8 @@ void LLFlatListView::rearrangeItems()
void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
{
if (!item_pair) return;
+
+ setFocus(TRUE);
bool select_item = !isSelected(item_pair);
@@ -528,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;
}
@@ -537,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;
}
@@ -554,12 +556,21 @@ BOOL LLFlatListView::handleKeyHere(KEY key, MASK mask)
break;
}
- if ( key == KEY_UP || key == KEY_DOWN )
+ if ( ( key == KEY_UP || key == KEY_DOWN ) && mSelectedItemPairs.size() )
{
- LLRect selcted_rect = getLastSelectedItemRect().stretch(1);
- LLRect visible_rect = getVisibleContentRect();
- if ( !visible_rect.contains (selcted_rect) )
- scrollToShowRect(selcted_rect);
+ LLRect visible_rc = getVisibleContentRect();
+ LLRect selected_rc = getLastSelectedItemRect();
+
+ if ( !visible_rc.contains (selected_rc) )
+ {
+ // But scroll in Items panel coordinates
+ scrollToShowRect(selected_rc);
+ }
+
+ // In case we are in accordion tab notify parent to show selected rectangle
+ LLRect screen_rc;
+ localRectToScreen(selected_rc, &screen_rc);
+ notifyParent(LLSD().with("scrollToShowRect",screen_rc.getValue()));
handled = TRUE;
}
@@ -645,8 +656,6 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select)
onCommit();
}
- setFocus(TRUE);
-
// Stretch selected items rect to ensure it won't be clipped
mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1));
@@ -680,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)
{
@@ -687,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 )
{
@@ -911,4 +931,23 @@ void LLFlatListView::onFocusLost()
mSelectedItemsBorder->setVisible(FALSE);
}
+//virtual
+void LLFlatListView::notify(const LLSD& info)
+{
+ if(info.has("action"))
+ {
+ std::string str_action = info["action"];
+ if(str_action == "select_first")
+ {
+ setFocus(true);
+ selectFirstItem();
+ }
+ else if(str_action == "select_last")
+ {
+ setFocus(true);
+ selectLastItem();
+ }
+ }
+}
+
//EOF
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index 3867e910c0..9e1e0f90fc 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 void 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 262afbe661..a63187678e 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -66,27 +66,6 @@
// use this to control "jumping" behavior when Ctrl-Tabbing
const S32 TABBED_FLOATER_OFFSET = 0;
-std::string LLFloater::sButtonActiveImageNames[BUTTON_COUNT] =
-{
- "Icon_Close_Foreground", //BUTTON_CLOSE
- "Icon_Restore_Foreground", //BUTTON_RESTORE
- "Icon_Minimize_Foreground", //BUTTON_MINIMIZE
- "tearoffbox.tga", //BUTTON_TEAR_OFF
- "Icon_Dock_Foreground", //BUTTON_DOCK
- "Icon_Undock_Foreground", //BUTTON_UNDOCK
- "Icon_Help_Foreground" //BUTTON_HELP
-};
-
-std::string LLFloater::sButtonPressedImageNames[BUTTON_COUNT] =
-{
- "Icon_Close_Press", //BUTTON_CLOSE
- "Icon_Restore_Press", //BUTTON_RESTORE
- "Icon_Minimize_Press", //BUTTON_MINIMIZE
- "tearoff_pressed.tga", //BUTTON_TEAR_OFF
- "Icon_Dock_Press", //BUTTON_DOCK
- "Icon_Undock_Press", //BUTTON_UNDOCK
- "Icon_Help_Press" //BUTTON_HELP
-};
std::string LLFloater::sButtonNames[BUTTON_COUNT] =
{
@@ -195,6 +174,20 @@ LLFloater::Params::Params()
can_dock("can_dock", false),
header_height("header_height", 0),
legacy_header_height("legacy_header_height", 0),
+ close_image("close_image"),
+ restore_image("restore_image"),
+ 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")
{
@@ -247,11 +240,11 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mDocked(false),
mHasBeenDraggedWhileMinimized(FALSE),
mPreviousMinimizedBottom(0),
- mPreviousMinimizedLeft(0),
- mNotificationContext(NULL)
+ mPreviousMinimizedLeft(0)
+// mNotificationContext(NULL)
{
mHandle.bind(this);
- mNotificationContext = new LLFloaterNotificationContext(getHandle());
+// mNotificationContext = new LLFloaterNotificationContext(getHandle());
// Clicks stop here.
setMouseOpaque(TRUE);
@@ -263,11 +256,9 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
// prior rectangle to be used on restore.
mExpandedRect.set(0,0,0,0);
- for (S32 i = 0; i < BUTTON_COUNT; i++)
- {
- mButtonsEnabled[i] = FALSE;
- mButtons[i] = NULL;
- }
+ memset(mButtonsEnabled, 0, BUTTON_COUNT * sizeof(bool));
+ memset(mButtons, 0, BUTTON_COUNT * sizeof(LLButton*));
+
addDragHandle();
addResizeCtrls();
@@ -276,11 +267,11 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
// chrome floaters don't take focus at all
setFocusRoot(!getIsChrome());
- initFloater();
+ initFloater(p);
}
// Note: Floaters constructed from XML call init() twice!
-void LLFloater::initFloater()
+void LLFloater::initFloater(const Params& p)
{
// Close button.
if (mCanClose)
@@ -305,7 +296,7 @@ void LLFloater::initFloater()
mButtonsEnabled[BUTTON_DOCK] = TRUE;
}
- buildButtons();
+ buildButtons(p);
// Floaters are created in the invisible state
setVisible(FALSE);
@@ -468,8 +459,8 @@ LLFloater::~LLFloater()
{
LLFloaterReg::removeInstance(mInstanceName, mKey);
- delete mNotificationContext;
- mNotificationContext = NULL;
+// delete mNotificationContext;
+// mNotificationContext = NULL;
//// am I not hosted by another floater?
//if (mHostHandle.isDead())
@@ -1280,7 +1271,7 @@ void LLFloater::removeDependentFloater(LLFloater* floaterp)
floaterp->mDependeeHandle = LLHandle<LLFloater>();
}
-BOOL LLFloater::offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index)
+BOOL LLFloater::offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButton index)
{
if( mButtonsEnabled[index] )
{
@@ -1461,6 +1452,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.
{
@@ -1472,6 +1464,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
// make sure host is visible
new_host->openFloater(new_host->getKey());
}
+ self->setTornOff(false);
}
}
@@ -1798,7 +1791,7 @@ void LLFloater::updateButtons()
mDragHandle->setMaxTitleWidth(getRect().getWidth() - (button_count * (floater_close_box_size + 1)));
}
-void LLFloater::buildButtons()
+void LLFloater::buildButtons(const Params& floater_params)
{
static LLUICachedControl<S32> floater_close_box_size ("UIFloaterCloseBoxSize", 0);
static LLUICachedControl<S32> close_box_from_top ("UICloseBoxFromTop", 0);
@@ -1832,17 +1825,18 @@ void LLFloater::buildButtons()
LLButton::Params p;
p.name(sButtonNames[i]);
p.rect(btn_rect);
- p.image_unselected.name(sButtonActiveImageNames[i]);
+ p.image_unselected = getButtonImage(floater_params, (EFloaterButton)i);
// Selected, no matter if hovered or not, is "pressed"
- p.image_selected.name(sButtonPressedImageNames[i]);
- p.image_hover_selected.name(sButtonPressedImageNames[i]);
+ LLUIImage* pressed_image = getButtonPressedImage(floater_params, (EFloaterButton)i);
+ p.image_selected = pressed_image;
+ p.image_hover_selected = pressed_image;
// Use a glow effect when the user hovers over the button
// These icons are really small, need glow amount increased
p.hover_glow_amount( 0.33f );
p.click_callback.function(boost::bind(sButtonCallbacks[i], this));
p.tab_stop(false);
p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT);
- p.tool_tip(sButtonToolTips[i]);
+ p.tool_tip = getButtonTooltip(floater_params, (EFloaterButton)i);
p.scale_image(true);
p.chrome(true);
@@ -1854,6 +1848,59 @@ void LLFloater::buildButtons()
updateButtons();
}
+// static
+LLUIImage* LLFloater::getButtonImage(const Params& p, EFloaterButton e)
+{
+ switch(e)
+ {
+ default:
+ case BUTTON_CLOSE:
+ return p.close_image;
+ case BUTTON_RESTORE:
+ return p.restore_image;
+ case BUTTON_MINIMIZE:
+ return p.minimize_image;
+ case BUTTON_TEAR_OFF:
+ 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;
+ }
+}
+
+// static
+LLUIImage* LLFloater::getButtonPressedImage(const Params& p, EFloaterButton e)
+{
+ switch(e)
+ {
+ default:
+ case BUTTON_CLOSE:
+ return p.close_pressed_image;
+ case BUTTON_RESTORE:
+ return p.restore_pressed_image;
+ case BUTTON_MINIMIZE:
+ return p.minimize_pressed_image;
+ case BUTTON_TEAR_OFF:
+ 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;
+ }
+}
+
+// static
+std::string LLFloater::getButtonTooltip(const Params& p, EFloaterButton e)
+{
+ // TODO: per-floater localizable tooltips set in XML
+ return sButtonToolTips[e];
+}
+
/////////////////////////////////////////////////////
// LLFloaterView
@@ -2302,8 +2349,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() )
@@ -2343,7 +2389,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();
}
@@ -2672,7 +2718,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr o
setupParams(params, parent);
initFromParams(params);
- initFloater();
+ initFloater(params);
LLMultiFloater* last_host = LLFloater::getFloaterHost();
if (node->hasName("multi_floater"))
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 1b98dddddc..b5c835cb47 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -39,7 +39,7 @@
#include "llpanel.h"
#include "lluuid.h"
-#include "llnotifications.h"
+//#include "llnotificationsutil.h"
#include <set>
class LLDragHandle;
@@ -65,20 +65,6 @@ const BOOL CLOSE_NO = FALSE;
const BOOL ADJUST_VERTICAL_YES = TRUE;
const BOOL ADJUST_VERTICAL_NO = FALSE;
-// associates a given notification instance with a particular floater
-class LLFloaterNotificationContext :
- public LLNotificationContext
-{
-public:
- LLFloaterNotificationContext(LLHandle<LLFloater> floater_handle) :
- mFloaterHandle(floater_handle)
- {}
-
- LLFloater* getFloater() { return mFloaterHandle.get(); }
-private:
- LLHandle<LLFloater> mFloaterHandle;
-};
-
class LLFloater : public LLPanel
{
friend class LLFloaterView;
@@ -97,7 +83,7 @@ public:
|*==========================================================================*/
};
- enum EFloaterButtons
+ enum EFloaterButton
{
BUTTON_CLOSE = 0,
BUTTON_RESTORE,
@@ -128,6 +114,22 @@ public:
can_dock;
Optional<S32> header_height,
legacy_header_height; // HACK see initFromXML()
+
+ // Images for top-right controls
+ Optional<LLUIImage*> close_image,
+ restore_image,
+ 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,
close_callback;
@@ -158,7 +160,7 @@ public:
/*virtual*/ void setIsChrome(BOOL is_chrome);
/*virtual*/ void setRect(const LLRect &rect);
- void initFloater();
+ void initFloater(const Params& p);
void openFloater(const LLSD& key = LLSD());
@@ -257,6 +259,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();
@@ -264,10 +268,10 @@ public:
// handle refocusing.
static void closeFocusedFloater();
- LLNotification::Params contextualNotification(const std::string& name)
- {
- return LLNotification::Params(name).context(mNotificationContext);
- }
+// LLNotification::Params contextualNotification(const std::string& name)
+// {
+// return LLNotification::Params(name).context(mNotificationContext);
+// }
static void onClickClose(LLFloater* floater);
static void onClickMinimize(LLFloater* floater);
@@ -309,8 +313,15 @@ private:
void cleanupHandles(); // remove handles to dead floaters
void createMinimizeButton();
void updateButtons();
- void buildButtons();
- BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index);
+ void buildButtons(const Params& p);
+
+ // Images and tooltips are named in the XML, but we want to look them
+ // up by index.
+ static LLUIImage* getButtonImage(const Params& p, EFloaterButton e);
+ static LLUIImage* getButtonPressedImage(const Params& p, EFloaterButton e);
+ static std::string getButtonTooltip(const Params& p, EFloaterButton e);
+
+ BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButton index);
void addResizeCtrls();
void layoutResizeCtrls();
void enableResizeCtrls(bool enable);
@@ -368,7 +379,7 @@ private:
typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t;
handle_set_t mDependents;
- BOOL mButtonsEnabled[BUTTON_COUNT];
+ bool mButtonsEnabled[BUTTON_COUNT];
LLButton* mButtons[BUTTON_COUNT];
F32 mButtonScale;
BOOL mAutoFocus;
@@ -382,8 +393,6 @@ private:
static LLMultiFloater* sHostp;
static BOOL sQuitting;
- static std::string sButtonActiveImageNames[BUTTON_COUNT];
- static std::string sButtonPressedImageNames[BUTTON_COUNT];
static std::string sButtonNames[BUTTON_COUNT];
static std::string sButtonToolTips[BUTTON_COUNT];
static std::string sButtonToolTipsIndex[BUTTON_COUNT];
@@ -401,7 +410,7 @@ private:
S32 mPreviousMinimizedBottom;
S32 mPreviousMinimizedLeft;
- LLFloaterNotificationContext* mNotificationContext;
+// LLFloaterNotificationContext* mNotificationContext;
LLRootHandle<LLFloater> mHandle;
};
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 bd5734312a..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
//
@@ -125,8 +130,8 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
mScrollHPos( 0 ),
mTextPadLeft(p.text_pad_left),
mTextPadRight(p.text_pad_right),
- mMinHPixels(0), // computed in updateTextPadding() below
- mMaxHPixels(0), // computed in updateTextPadding() below
+ mTextLeftEdge(0), // computed in updateTextPadding() below
+ mTextRightEdge(0), // computed in updateTextPadding() below
mCommitOnFocusLost( p.commit_on_focus_lost ),
mRevertOnEsc( p.revert_on_esc ),
mKeystrokeCallback( p.keystroke_callback() ),
@@ -338,9 +343,8 @@ void LLLineEditor::setTextPadding(S32 left, S32 right)
void LLLineEditor::updateTextPadding()
{
- static LLUICachedControl<S32> line_editor_hpad ("UILineEditorHPad", 0);
- mMinHPixels = line_editor_hpad + llclamp(mTextPadLeft, 0, getRect().getWidth());;
- mMaxHPixels = getRect().getWidth() - mMinHPixels - llclamp(mTextPadRight, 0, getRect().getWidth());
+ mTextLeftEdge = llclamp(mTextPadLeft, 0, getRect().getWidth());
+ mTextRightEdge = getRect().getWidth() - llclamp(mTextPadRight, 0, getRect().getWidth());
}
@@ -406,8 +410,8 @@ void LLLineEditor::setCursorAtLocalPos( S32 local_mouse_x )
mScrollHPos +
mGLFont->charFromPixelOffset(
wtext, mScrollHPos,
- (F32)(local_mouse_x - mMinHPixels),
- (F32)(mMaxHPixels - mMinHPixels + 1)); // min-max range is inclusive
+ (F32)(local_mouse_x - mTextLeftEdge),
+ (F32)(mTextRightEdge - mTextLeftEdge + 1)); // min-max range is inclusive
setCursor(cursor_pos);
}
@@ -417,11 +421,11 @@ void LLLineEditor::setCursor( S32 pos )
mCursorPos = llclamp( pos, 0, mText.length());
S32 pixels_after_scroll = findPixelNearestPos();
- if( pixels_after_scroll > mMaxHPixels )
+ if( pixels_after_scroll > mTextRightEdge )
{
S32 width_chars_to_left = mGLFont->getWidth(mText.getWString().c_str(), 0, mScrollHPos);
- S32 last_visible_char = mGLFont->maxDrawableChars(mText.getWString().c_str(), llmax(0.f, (F32)(mMaxHPixels - mMinHPixels + width_chars_to_left)));
- S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mMaxHPixels - mMinHPixels), mText.length(), getCursor());
+ S32 last_visible_char = mGLFont->maxDrawableChars(mText.getWString().c_str(), llmax(0.f, (F32)(mTextRightEdge - mTextLeftEdge + width_chars_to_left)));
+ S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mTextRightEdge - mTextLeftEdge), mText.length(), getCursor());
if (old_cursor_pos == last_visible_char)
{
mScrollHPos = llmin(mText.length(), llmax(min_scroll, mScrollHPos + SCROLL_INCREMENT_ADD));
@@ -682,17 +686,17 @@ BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask)
S32 increment = llround(mScrollTimer.getElapsedTimeF32() / AUTO_SCROLL_TIME);
mScrollTimer.reset();
mScrollTimer.setTimerExpirySec(AUTO_SCROLL_TIME);
- if( (x < mMinHPixels) && (mScrollHPos > 0 ) )
+ if( (x < mTextLeftEdge) && (mScrollHPos > 0 ) )
{
// Scroll to the left
mScrollHPos = llclamp(mScrollHPos - increment, 0, mText.length());
}
else
- if( (x > mMaxHPixels) && (mCursorPos < (S32)mText.length()) )
+ if( (x > mTextRightEdge) && (mCursorPos < (S32)mText.length()) )
{
// If scrolling one pixel would make a difference...
S32 pixels_after_scrolling_one_char = findPixelNearestPos(1);
- if( pixels_after_scrolling_one_char >= mMaxHPixels )
+ if( pixels_after_scrolling_one_char >= mTextRightEdge )
{
// ...scroll to the right
mScrollHPos = llclamp(mScrollHPos + increment, 0, mText.length());
@@ -1671,7 +1675,7 @@ void LLLineEditor::draw()
}
S32 rendered_text = 0;
- F32 rendered_pixels_right = (F32)mMinHPixels;
+ F32 rendered_pixels_right = (F32)mTextLeftEdge;
F32 text_bottom = (F32)background.mBottom + (F32)lineeditor_v_pad;
if( (gFocusMgr.getKeyboardFocus() == this) && hasSelection() )
@@ -1700,17 +1704,17 @@ void LLLineEditor::draw()
0,
LLFontGL::NO_SHADOW,
select_left - mScrollHPos,
- mMaxHPixels - llround(rendered_pixels_right),
+ mTextRightEdge - llround(rendered_pixels_right),
&rendered_pixels_right);
}
- if( (rendered_pixels_right < (F32)mMaxHPixels) && (rendered_text < text_len) )
+ if( (rendered_pixels_right < (F32)mTextRightEdge) && (rendered_text < text_len) )
{
LLColor4 color = mHighlightColor;
color.setAlpha(alpha);
// selected middle
S32 width = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos + rendered_text, select_right - mScrollHPos - rendered_text);
- width = llmin(width, mMaxHPixels - llround(rendered_pixels_right));
+ width = llmin(width, mTextRightEdge - llround(rendered_pixels_right));
gl_rect_2d(llround(rendered_pixels_right), cursor_top, llround(rendered_pixels_right)+width, cursor_bottom, color);
LLColor4 tmp_color( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], alpha );
@@ -1722,11 +1726,11 @@ void LLLineEditor::draw()
0,
LLFontGL::NO_SHADOW,
select_right - mScrollHPos - rendered_text,
- mMaxHPixels - llround(rendered_pixels_right),
+ mTextRightEdge - llround(rendered_pixels_right),
&rendered_pixels_right);
}
- if( (rendered_pixels_right < (F32)mMaxHPixels) && (rendered_text < text_len) )
+ if( (rendered_pixels_right < (F32)mTextRightEdge) && (rendered_text < text_len) )
{
// unselected, right side
mGLFont->render(
@@ -1737,7 +1741,7 @@ void LLLineEditor::draw()
0,
LLFontGL::NO_SHADOW,
S32_MAX,
- mMaxHPixels - llround(rendered_pixels_right),
+ mTextRightEdge - llround(rendered_pixels_right),
&rendered_pixels_right);
}
}
@@ -1751,7 +1755,7 @@ void LLLineEditor::draw()
0,
LLFontGL::NO_SHADOW,
S32_MAX,
- mMaxHPixels - llround(rendered_pixels_right),
+ mTextRightEdge - llround(rendered_pixels_right),
&rendered_pixels_right);
}
#if 1 // for when we're ready for image art.
@@ -1809,14 +1813,14 @@ void LLLineEditor::draw()
if (0 == mText.length() && mReadOnly)
{
mGLFont->render(mLabel.getWString(), 0,
- mMinHPixels, (F32)text_bottom,
+ mTextLeftEdge, (F32)text_bottom,
label_color,
LLFontGL::LEFT,
LLFontGL::BOTTOM,
0,
LLFontGL::NO_SHADOW,
S32_MAX,
- mMaxHPixels - llround(rendered_pixels_right),
+ mTextRightEdge - llround(rendered_pixels_right),
&rendered_pixels_right, FALSE);
}
@@ -1834,14 +1838,14 @@ void LLLineEditor::draw()
if (0 == mText.length())
{
mGLFont->render(mLabel.getWString(), 0,
- mMinHPixels, (F32)text_bottom,
+ mTextLeftEdge, (F32)text_bottom,
label_color,
LLFontGL::LEFT,
LLFontGL::BOTTOM,
0,
LLFontGL::NO_SHADOW,
S32_MAX,
- mMaxHPixels - llround(rendered_pixels_right),
+ mTextRightEdge - llround(rendered_pixels_right),
&rendered_pixels_right, FALSE);
}
// Draw children (border)
@@ -1859,7 +1863,7 @@ void LLLineEditor::draw()
S32 LLLineEditor::findPixelNearestPos(const S32 cursor_offset) const
{
S32 dpos = getCursor() - mScrollHPos + cursor_offset;
- S32 result = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos, dpos) + mMinHPixels;
+ S32 result = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos, dpos) + mTextLeftEdge;
return result;
}
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 4c4b00094d..49e9539b16 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -303,8 +303,8 @@ protected:
LLFrameTimer mScrollTimer;
S32 mTextPadLeft; // Used to reserve space before the beginning of the text for children.
S32 mTextPadRight; // Used to reserve space after the end of the text for children.
- S32 mMinHPixels;
- S32 mMaxHPixels;
+ S32 mTextLeftEdge; // Pixels, cached left edge of text based on left padding and width
+ S32 mTextRightEdge; // Pixels, cached right edge of text based on right padding and width
BOOL mCommitOnFocusLost;
BOOL mRevertOnEsc;
@@ -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/llnotificationptr.h b/indra/llui/llnotificationptr.h
new file mode 100644
index 0000000000..0718f7d182
--- /dev/null
+++ b/indra/llui/llnotificationptr.h
@@ -0,0 +1,41 @@
+/**
+ * @file llnotificationptr.h
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLNOTIFICATIONPTR_H
+#define LLNOTIFICATIONPTR_H
+
+// Many classes just store a single LLNotificationPtr
+// and llnotifications.h is very large, so define this ligher header.
+#include <boost/shared_ptr.hpp>
+
+class LLNotification;
+typedef boost::shared_ptr<LLNotification> LLNotificationPtr;
+
+#endif
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index eb8cc3e2c5..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
@@ -1395,10 +1395,9 @@ void LLNotifications::addFromCallback(const LLSD& name)
add(LLNotification::Params().name(name.asString()));
}
-// we provide a couple of simple add notification functions so that it's reasonable to create notifications in one line
LLNotificationPtr LLNotifications::add(const std::string& name,
- const LLSD& substitutions,
- const LLSD& payload)
+ const LLSD& substitutions,
+ const LLSD& payload)
{
LLNotification::Params::Functor functor_p;
functor_p.name = name;
@@ -1406,15 +1405,16 @@ LLNotificationPtr LLNotifications::add(const std::string& name,
}
LLNotificationPtr LLNotifications::add(const std::string& name,
- const LLSD& substitutions,
- const LLSD& payload,
- const std::string& functor_name)
+ const LLSD& substitutions,
+ const LLSD& payload,
+ const std::string& functor_name)
{
LLNotification::Params::Functor functor_p;
functor_p.name = functor_name;
return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
}
-
+
+//virtual
LLNotificationPtr LLNotifications::add(const std::string& name,
const LLSD& substitutions,
const LLSD& payload,
@@ -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/llnotifications.h b/indra/llui/llnotifications.h
index 0d7cb74f70..aeb4cebf1b 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -103,9 +103,7 @@
#include "llpointer.h"
#include "llinitparam.h"
#include "llnotificationslistener.h"
-
-class LLNotification;
-typedef boost::shared_ptr<LLNotification> LLNotificationPtr;
+#include "llnotificationptr.h"
typedef enum e_notification_priority
@@ -841,10 +839,11 @@ public:
// Add a simple notification (from XUI)
void addFromCallback(const LLSD& name);
- // we provide a collection of simple add notification functions so that it's reasonable to create notifications in one line
+ // *NOTE: To add simple notifications, #include "llnotificationsutil.h"
+ // and use LLNotificationsUtil::add("MyNote") or add("MyNote", args)
LLNotificationPtr add(const std::string& name,
- const LLSD& substitutions = LLSD(),
- const LLSD& payload = LLSD());
+ const LLSD& substitutions,
+ const LLSD& payload);
LLNotificationPtr add(const std::string& name,
const LLSD& substitutions,
const LLSD& payload,
diff --git a/indra/llui/llnotificationsutil.cpp b/indra/llui/llnotificationsutil.cpp
new file mode 100644
index 0000000000..2cd165f1b3
--- /dev/null
+++ b/indra/llui/llnotificationsutil.cpp
@@ -0,0 +1,91 @@
+/**
+ * @file llnotificationsutil.cpp
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+
+#include "llnotificationsutil.h"
+
+#include "llnotifications.h"
+#include "llsd.h"
+#include "llxmlnode.h" // apparently needed to call LLNotifications::instance()
+
+LLNotificationPtr LLNotificationsUtil::add(const std::string& name)
+{
+ LLNotification::Params::Functor functor_p;
+ functor_p.name = name;
+ return LLNotifications::instance().add(
+ LLNotification::Params().name(name).substitutions(LLSD()).payload(LLSD()).functor(functor_p));
+}
+
+LLNotificationPtr LLNotificationsUtil::add(const std::string& name,
+ const LLSD& substitutions)
+{
+ LLNotification::Params::Functor functor_p;
+ functor_p.name = name;
+ return LLNotifications::instance().add(
+ LLNotification::Params().name(name).substitutions(substitutions).payload(LLSD()).functor(functor_p));
+}
+
+LLNotificationPtr LLNotificationsUtil::add(const std::string& name,
+ const LLSD& substitutions,
+ const LLSD& payload)
+{
+ LLNotification::Params::Functor functor_p;
+ functor_p.name = name;
+ return LLNotifications::instance().add(
+ LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
+}
+
+LLNotificationPtr LLNotificationsUtil::add(const std::string& name,
+ const LLSD& substitutions,
+ const LLSD& payload,
+ const std::string& functor_name)
+{
+ LLNotification::Params::Functor functor_p;
+ functor_p.name = functor_name;
+ return LLNotifications::instance().add(
+ LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
+}
+
+LLNotificationPtr LLNotificationsUtil::add(const std::string& name,
+ const LLSD& substitutions,
+ const LLSD& payload,
+ boost::function<void (const LLSD&, const LLSD&)> functor)
+{
+ LLNotification::Params::Functor functor_p;
+ functor_p.function = functor;
+ return LLNotifications::instance().add(
+ LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
+}
+
+S32 LLNotificationsUtil::getSelectedOption(const LLSD& notification, const LLSD& response)
+{
+ return LLNotification::getSelectedOption(notification, response);
+}
diff --git a/indra/llui/llnotificationsutil.h b/indra/llui/llnotificationsutil.h
new file mode 100644
index 0000000000..a0801b338f
--- /dev/null
+++ b/indra/llui/llnotificationsutil.h
@@ -0,0 +1,68 @@
+/**
+ * @file llnotificationsutil.h
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLNOTIFICATIONSUTIL_H
+#define LLNOTIFICATIONSUTIL_H
+
+// The vast majority of clients of the notifications system just want to add
+// a notification to the screen, so define this lightweight public interface
+// to avoid including the heavyweight llnotifications.h
+
+#include "llnotificationptr.h"
+
+#include <boost/function.hpp>
+
+class LLSD;
+
+namespace LLNotificationsUtil
+{
+ LLNotificationPtr add(const std::string& name);
+
+ LLNotificationPtr add(const std::string& name,
+ const LLSD& substitutions);
+
+ LLNotificationPtr add(const std::string& name,
+ const LLSD& substitutions,
+ const LLSD& payload);
+
+ LLNotificationPtr add(const std::string& name,
+ const LLSD& substitutions,
+ const LLSD& payload,
+ const std::string& functor_name);
+
+ LLNotificationPtr add(const std::string& name,
+ const LLSD& substitutions,
+ const LLSD& payload,
+ boost::function<void (const LLSD&, const LLSD&)> functor);
+
+ S32 getSelectedOption(const LLSD& notification, const LLSD& response);
+}
+
+#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/llprogressbar.cpp b/indra/llui/llprogressbar.cpp
index c8b6e814e1..62ca569e6c 100644
--- a/indra/llui/llprogressbar.cpp
+++ b/indra/llui/llprogressbar.cpp
@@ -72,12 +72,13 @@ LLProgressBar::~LLProgressBar()
void LLProgressBar::draw()
{
static LLTimer timer;
-
- LLUIImagePtr bar_fg_imagep = LLUI::getUIImage("progressbar_fill.tga");
+ F32 alpha = getDrawContext().mAlpha;
- mImageBar->draw(getLocalRect(), mColorBackground.get());
+ LLColor4 image_bar_color = mColorBackground.get();
+ image_bar_color.setAlpha(alpha);
+ mImageBar->draw(getLocalRect(), image_bar_color);
- F32 alpha = 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32()));
+ alpha *= 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32()));
LLColor4 bar_color = mColorBar.get();
bar_color.mV[VALPHA] *= alpha; // modulate alpha
LLRect progress_rect = getLocalRect();
diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp
index a7cf9be277..0c46edf300 100644
--- a/indra/llui/llresizebar.cpp
+++ b/indra/llui/llresizebar.cpp
@@ -144,9 +144,10 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
if( valid_rect.localPointInRect( screen_x, screen_y ) && mResizingView )
{
// undock floater when user resize it
- if (((LLFloater*)getParent())->isDocked())
+ LLFloater* parent = dynamic_cast<LLFloater*>( getParent());
+ if (parent && parent->isDocked())
{
- ((LLFloater*)getParent())->setDocked(false, false);
+ parent->setDocked( false, false);
}
// Resize the parent
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 5e17372fe9..f6caed4617 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -111,7 +111,7 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)
LLView::addChild( mBorder );
mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 );
- mInnerRect.stretch( -mBorder->getBorderWidth() );
+ mInnerRect.stretch( -getBorderWidth() );
LLRect vertical_scroll_rect = mInnerRect;
vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - scrollbar_size;
@@ -189,7 +189,7 @@ void LLScrollContainer::reshape(S32 width, S32 height,
LLUICtrl::reshape( width, height, called_from_parent );
mInnerRect = getLocalRect();
- mInnerRect.stretch( -mBorder->getBorderWidth() );
+ mInnerRect.stretch( -getBorderWidth() );
if (mScrolledView)
{
@@ -351,9 +351,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;
@@ -499,7 +499,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 )
@@ -573,6 +573,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()
@@ -584,15 +587,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,
@@ -673,7 +677,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..82a3c5cf47 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),
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,6 +526,7 @@ 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)
@@ -534,15 +537,23 @@ void LLTextBase::drawText()
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;
}
+ // A patch for EXT-1944 "Implement ellipses in message well"
+ // introduced a regression where text in SansSerif ending in the
+ // letter "r" is clipped. This may be due to an off-by-one in
+ // font width information out of FreeType with our fractional font
+ // sizes. For now, just make an extra pixel of space to resolve
+ // EXT-2971 "Letter R doesn't show when it's the last letter in a
+ // text block". See James/Richard for details.
+ const S32 FIX_CLIPPING_HACK = 1;
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 + FIX_CLIPPING_HACK,
line.mRect.mBottom - scrolled_view_rect.mBottom + mTextRect.mBottom);
// draw a single line of text
@@ -562,6 +573,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 +663,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;
}
@@ -1070,6 +1090,8 @@ void LLTextBase::reflow(S32 start_index)
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 +1102,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 +1202,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 +1223,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 +1231,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);
}
}
@@ -1464,14 +1487,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 +2090,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 = mTextRect.getWidth();
mDocumentView->setShape(doc_rect);
@@ -2281,7 +2306,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 +2323,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 +2405,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 +2427,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..c60b040655 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;
@@ -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
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 959313a5b6..01c7a81309 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -228,7 +228,7 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)
{
LLButton::Params p_button;
p_button.name(std::string("play_media"));
- p_button.label(""); // provid label but set to empty so name does not overwrite it -angela
+ p_button.label(""); // provide label but set to empty so name does not overwrite it -angela
TOOLTIP_PLAYBUTTON_SIZE = 16;
LLRect button_rect;
button_rect.setOriginAndSize((mPadding +TOOLTIP_ICON_SIZE+ mPadding ), mPadding, TOOLTIP_ICON_SIZE, TOOLTIP_ICON_SIZE);
@@ -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/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 e5647970f1..f9e134e1e5 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/llview.cpp b/indra/llui/llview.cpp
index dba24ee165..6f8455774d 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
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 2607120e17..c611e4c85f 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>
@@ -517,6 +514,8 @@ public:
virtual void notifyParent(const LLSD& info);
virtual void notifyChildren(const LLSD& info);
+ virtual void notify(const LLSD& info) {};
+
static const LLViewDrawContext& getDrawContext();
protected:
@@ -659,4 +658,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