summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
authorMark Palange (Mani) <palange@lindenlab.com>2009-10-02 10:35:42 -0700
committerMark Palange (Mani) <palange@lindenlab.com>2009-10-02 10:35:42 -0700
commit4d53e235c2445b820bb0ae7303b269648dd86037 (patch)
treec1ab3643cf257099822e7a0e1e832d76813555f6 /indra/llui
parent80f27013b2d2a7ca6509db033c8f0c31562e04c7 (diff)
parentdde2153014cd7d7b8fa704f7067a41344bfbb1c2 (diff)
merge of latest viewer/viewer-20
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/CMakeLists.txt6
-rw-r--r--indra/llui/llbutton.cpp45
-rw-r--r--indra/llui/llbutton.h7
-rw-r--r--indra/llui/llcombobox.cpp1
-rw-r--r--indra/llui/lldockablefloater.cpp56
-rw-r--r--indra/llui/lldockablefloater.h23
-rw-r--r--indra/llui/lldockcontrol.cpp176
-rw-r--r--indra/llui/lldockcontrol.h16
-rw-r--r--indra/llui/llflatlistview.cpp199
-rw-r--r--indra/llui/llflatlistview.h142
-rw-r--r--indra/llui/llfloater.cpp129
-rw-r--r--indra/llui/llfloater.h14
-rw-r--r--indra/llui/llfocusmgr.cpp38
-rw-r--r--indra/llui/llfocusmgr.h20
-rw-r--r--indra/llui/llhelp.h45
-rw-r--r--indra/llui/llmultisliderctrl.cpp2
-rw-r--r--indra/llui/llnotifications.cpp2
-rw-r--r--indra/llui/llpanel.cpp3
-rw-r--r--indra/llui/llpanel.h8
-rw-r--r--indra/llui/llscrollbar.cpp13
-rw-r--r--indra/llui/llscrollbar.h8
-rw-r--r--indra/llui/llscrollcontainer.cpp2
-rw-r--r--indra/llui/llscrolllistctrl.cpp6
-rw-r--r--indra/llui/llscrolllistctrl.h6
-rw-r--r--indra/llui/llsliderctrl.cpp2
-rw-r--r--indra/llui/llspinctrl.cpp2
-rw-r--r--indra/llui/lltextbox.h1
-rw-r--r--indra/llui/lltexteditor.cpp43
-rw-r--r--indra/llui/lltexteditor.h10
-rw-r--r--indra/llui/llui.cpp53
-rw-r--r--indra/llui/llui.h7
-rw-r--r--indra/llui/lluictrl.cpp31
-rw-r--r--indra/llui/lluictrl.h11
-rw-r--r--indra/llui/llurlaction.cpp1
-rw-r--r--indra/llui/llview.cpp10
-rw-r--r--indra/llui/llview.h4
36 files changed, 770 insertions, 372 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 65ccb655dd..9d1b59cf66 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -51,7 +51,6 @@ set(llui_SOURCE_FILES
llkeywords.cpp
lllayoutstack.cpp
lllineeditor.cpp
- lllistctrl.cpp
lllocalcliprect.cpp
llmenugl.cpp
llmodaldialog.cpp
@@ -88,6 +87,7 @@ set(llui_SOURCE_FILES
lltextbox.cpp
lltexteditor.cpp
lltextparser.cpp
+ lltransientfloatermgr.cpp
lltransutil.cpp
lltooltip.cpp
llui.cpp
@@ -133,13 +133,12 @@ set(llui_HEADER_FILES
llfocusmgr.h
llfunctorregistry.h
llhandle.h
- llhtmlhelp.h
+ llhelp.h
lliconctrl.h
llkeywords.h
lllayoutstack.h
lllazyvalue.h
lllineeditor.h
- lllistctrl.h
lllocalcliprect.h
llmenugl.h
llmodaldialog.h
@@ -177,6 +176,7 @@ set(llui_HEADER_FILES
lltexteditor.h
lltextparser.h
lltooltip.h
+ lltransientfloatermgr.h
lltransutil.h
lluicolortable.h
lluiconstants.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index fa13ced037..b9613b502c 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -39,7 +39,6 @@
#include "llstring.h"
// Project includes
-#include "llhtmlhelp.h"
#include "llkeyboard.h"
#include "llui.h"
#include "lluiconstants.h"
@@ -49,8 +48,10 @@
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llwindow.h"
+#include "llnotifications.h"
#include "llrender.h"
#include "lluictrlfactory.h"
+#include "llhelp.h"
static LLDefaultChildRegistry::Register<LLButton> r("button");
@@ -92,7 +93,6 @@ LLButton::Params::Params()
mouse_held_callback("mouse_held_callback"),
is_toggle("is_toggle", false),
scale_image("scale_image", true),
- help_url("help_url"),
hover_glow_amount("hover_glow_amount"),
commit_on_return("commit_on_return", true),
picture_style("picture_style", false)
@@ -173,11 +173,6 @@ LLButton::LLButton(const LLButton::Params& p)
mMouseDownTimer.stop();
- if (p.help_url.isProvided())
- {
- setHelpURLCallback(p.help_url);
- }
-
// if custom unselected button image provided...
if (p.image_unselected != default_params.image_unselected)
{
@@ -1034,24 +1029,6 @@ void LLButton::addImageAttributeToXML(LLXMLNodePtr node,
}
}
-void clicked_help(void* data)
-{
- LLButton* self = (LLButton*)data;
- if (!self) return;
-
- if (!LLUI::sHtmlHelp)
- {
- return;
- }
-
- LLUI::sHtmlHelp->show(self->getHelpURL());
-}
-
-void LLButton::setHelpURLCallback(const std::string &help_url)
-{
- mHelpURL = help_url;
- setClickedCallback(clicked_help,this);
-}
// static
void LLButton::toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname)
@@ -1077,6 +1054,24 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname));
}
+// static
+void LLButton::showHelp(LLUICtrl* ctrl, const LLSD& sdname)
+{
+ // search back through the button's parents for a panel
+ // with a help_topic string defined
+ std::string help_topic;
+ if (LLUI::sHelpImpl &&
+ ctrl->findHelpTopic(help_topic))
+ {
+ LLUI::sHelpImpl->showTopic(help_topic);
+ return; // success
+ }
+
+ // 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");
+}
+
void LLButton::resetMouseDownTimer()
{
mMouseDownTimer.stop();
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 06e1dac914..04716d605b 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -118,7 +118,6 @@ public:
commit_on_return,
picture_style; //if true, don't display label
- Optional<std::string> help_url;
Optional<F32> hover_glow_amount;
Optional<TimeIntervalParam> held_down_delay;
@@ -230,12 +229,10 @@ public:
void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
BOOL getCommitOnReturn() const { return mCommitOnReturn; }
- void setHelpURLCallback(const std::string &help_url);
- const std::string& getHelpURL() const { return mHelpURL; }
-
static void onHeldDown(void *userdata); // to be called by gIdleCallbacks
static void toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname);
static void setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname);
+ static void showHelp(LLUICtrl* ctrl, const LLSD& sdname);
protected:
const LLPointer<LLUIImage>& getImageUnselected() const { return mImageUnselected; }
@@ -314,8 +311,6 @@ private:
BOOL mCommitOnReturn;
BOOL mFadeWhenDisabled;
- std::string mHelpURL;
-
LLFrameTimer mFlashingTimer;
};
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 58aeb61728..0170ac0c6a 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -483,7 +483,6 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p)
params.max_length_bytes(mMaxChars);
params.commit_callback.function(boost::bind(&LLComboBox::onTextCommit, this, _2));
params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1));
- params.focus_lost_callback(NULL);
params.handle_edit_keys_directly(true);
params.commit_on_focus_lost(false);
params.follows.flags(FOLLOWS_ALL);
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
index ed15d9d922..4525f0a45b 100644
--- a/indra/llui/lldockablefloater.cpp
+++ b/indra/llui/lldockablefloater.cpp
@@ -35,12 +35,21 @@
#include "lldockablefloater.h"
//static
-LLHandle<LLFloater> LLDockableFloater::instanceHandle;
+LLHandle<LLFloater> LLDockableFloater::sInstanceHandle;
LLDockableFloater::LLDockableFloater(LLDockControl* dockControl,
const LLSD& key, const Params& params) :
- LLFloater(key, params), mDockControl(dockControl)
+ LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(true)
{
+ setDocked(mDockControl.get() != NULL && mDockControl.get()->isDockVisible());
+ resetInstance();
+}
+
+LLDockableFloater::LLDockableFloater(LLDockControl* dockControl, bool uniqueDocking,
+ const LLSD& key, const Params& params) :
+ LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(uniqueDocking)
+{
+ setDocked(mDockControl.get() != NULL && mDockControl.get()->isDockVisible());
resetInstance();
}
@@ -57,21 +66,13 @@ BOOL LLDockableFloater::postBuild()
void LLDockableFloater::resetInstance()
{
- if (instanceHandle.get() != this)
+ if (mUniqueDocking && sInstanceHandle.get() != this)
{
- if (instanceHandle.get() != NULL && instanceHandle.get()->isDocked())
+ if (sInstanceHandle.get() != NULL && sInstanceHandle.get()->isDocked())
{
- //closeFloater() is not virtual
- if (instanceHandle.get()->canClose())
- {
- instanceHandle.get()->closeFloater();
- }
- else
- {
- instanceHandle.get()->setVisible(FALSE);
- }
+ sInstanceHandle.get()->setVisible(FALSE);
}
- instanceHandle = getHandle();
+ sInstanceHandle = getHandle();
}
}
@@ -81,12 +82,18 @@ void LLDockableFloater::setVisible(BOOL visible)
{
resetInstance();
}
+
+ if (visible && mDockControl.get() != NULL)
+ {
+ mDockControl.get()->repositionDockable();
+ }
+
LLFloater::setVisible(visible);
}
void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
{
- if (mDockControl.get() != NULL)
+ if (mDockControl.get() != NULL && mDockControl.get()->isDockVisible())
{
if (docked)
{
@@ -97,12 +104,16 @@ void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
{
mDockControl.get()->off();
}
- }
- if (!docked && pop_on_undock)
+ if (!docked && pop_on_undock)
+ {
+ // visually pop up a little bit to emphasize the undocking
+ translate(0, UNDOCK_LEAP_HEIGHT);
+ }
+ }
+ else
{
- // visually pop up a little bit to emphasize the undocking
- translate(0, UNDOCK_LEAP_HEIGHT);
+ docked = false;
}
LLFloater::setDocked(docked, pop_on_undock);
@@ -113,7 +124,10 @@ void LLDockableFloater::draw()
if (mDockControl.get() != NULL)
{
mDockControl.get()->repositionDockable();
- mDockControl.get()->drawToungue();
+ if (isDocked())
+ {
+ mDockControl.get()->drawToungue();
+ }
}
LLFloater::draw();
}
@@ -121,7 +135,9 @@ void LLDockableFloater::draw()
void LLDockableFloater::setDockControl(LLDockControl* dockControl)
{
mDockControl.reset(dockControl);
+ setDocked(mDockControl.get() != NULL && mDockControl.get()->isDockVisible());
}
+
const LLUIImagePtr& LLDockableFloater::getDockTongue()
{
return mDockTongue;
diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h
index 1d0e89cef5..ed90567ad3 100644
--- a/indra/llui/lldockablefloater.h
+++ b/indra/llui/lldockablefloater.h
@@ -46,12 +46,26 @@ class LLDockableFloater : public LLFloater
static const U32 UNDOCK_LEAP_HEIGHT = 12;
public:
LOG_CLASS(LLDockableFloater);
- LLDockableFloater(LLDockControl* dockControl, const LLSD& key, const Params& params = getDefaultParams());
+ LLDockableFloater(LLDockControl* dockControl, const LLSD& key,
+ const Params& params = getDefaultParams());
+ LLDockableFloater(LLDockControl* dockControl, bool uniqueDocking,
+ const LLSD& key, const Params& params = getDefaultParams());
virtual ~LLDockableFloater();
+ static LLHandle<LLFloater> getInstanceHandle() { return sInstanceHandle; }
+
+ /**
+ * If descendant class overrides postBuild() in order to perform specific
+ * construction then it must still invoke its superclass' implementation.
+ */
/* virtula */BOOL postBuild();
/* virtual */void setDocked(bool docked, bool pop_on_undock = true);
/* virtual */void draw();
+
+ /**
+ * If descendant class overrides setVisible() then it must still invoke its
+ * superclass' implementation.
+ */
/*virtual*/ void setVisible(BOOL visible);
private:
@@ -69,7 +83,12 @@ protected:
private:
std::auto_ptr<LLDockControl> mDockControl;
LLUIImagePtr mDockTongue;
- static LLHandle<LLFloater> instanceHandle;
+ static LLHandle<LLFloater> sInstanceHandle;
+ /**
+ * Provides possibility to define that dockable floaters can be docked
+ * non exclusively.
+ */
+ bool mUniqueDocking;
};
#endif /* LL_DOCKABLEFLOATER_H */
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index d666f2be56..146c7a969a 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -35,12 +35,12 @@
#include "lldockcontrol.h"
LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
- const LLUIImagePtr& dockTongue, DocAt dockAt, bool enabled) :
- mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(
- dockTongue)
+ const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
+ mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(dockTongue)
{
mDockAt = dockAt;
- if (enabled)
+
+ if (dockableFloater->isDocked())
{
on();
}
@@ -49,7 +49,17 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
off();
}
- if (dockWidget != NULL) {
+ if (!(get_allowed_rect_callback))
+ {
+ mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
+ }
+ else
+ {
+ mGetAllowedRectCallback = get_allowed_rect_callback;
+ }
+
+ if (dockWidget != NULL)
+ {
repositionDockable();
}
}
@@ -67,65 +77,140 @@ void LLDockControl::setDock(LLView* dockWidget)
}
}
+void LLDockControl::getAllowedRect(LLRect& rect)
+{
+ rect = mDockableFloater->getRootView()->getRect();
+}
+
void LLDockControl::repositionDockable()
{
- if (mEnabled)
+ LLRect dockRect = mDockWidget->calcScreenRect();
+ LLRect rootRect;
+ mGetAllowedRectCallback(rootRect);
+ static BOOL prev_visibility = !mDockWidget->getVisible();
+
+ // recalculate dockable position if dock position changed, dock visibility changed,
+ // root view rect changed or recalculation is forced
+ if (mEnabled && (mPrevDockRect != dockRect || prev_visibility != mDockWidget->getVisible()
+ || mRootRect != rootRect || mRecalculateDocablePosition))
{
- calculateDockablePosition();
+ // undock dockable and off() if dock not visible
+ if (!isDockVisible())
+ {
+ mDockableFloater->setDocked(false);
+ // force off() since dockable may not have dockControll at this time
+ off();
+ }
+ else
+ {
+ moveDockable();
+ }
+
+ mPrevDockRect = dockRect;
+ mRootRect = rootRect;
+ mRecalculateDocablePosition = false;
+ prev_visibility = mDockWidget->getVisible();
}
}
-void LLDockControl::calculateDockablePosition()
+bool LLDockControl::isDockVisible()
{
- LLRect dockRect = mDockWidget->calcScreenRect();
- LLRect rootRect = mDockableFloater->getRootView()->getRect();
+ bool res = true;
- // recalculate dockable position if dock position changed
- // or root view rect changed or recalculation is forced
- if (mPrevDockRect != dockRect || mRootRect != rootRect
- || mRecalculateDocablePosition)
+ if (mDockWidget != NULL)
{
- LLRect dockableRect = mDockableFloater->calcScreenRect();
- S32 x = 0;
- S32 y = 0;
- switch (mDockAt)
+ //we should check all hierarchy
+ res = mDockWidget->isInVisibleChain();
+ if (res)
{
- case TOP:
- x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
- y = dockRect.mTop + mDockTongue->getHeight()
- + dockableRect.getHeight();
- if (x < rootRect.mLeft)
- {
- x = rootRect.mLeft;
- }
- if (x + dockableRect.getWidth() > rootRect.mRight)
+ LLRect dockRect = mDockWidget->calcScreenRect();
+
+ switch (mDockAt)
{
- x = rootRect.mRight - dockableRect.getWidth();
+ case TOP:
+ // check is dock inside parent rect
+ LLRect dockParentRect =
+ mDockWidget->getParent()->calcScreenRect();
+ if (dockRect.mRight <= dockParentRect.mLeft
+ || dockRect.mLeft >= dockParentRect.mRight)
+ {
+ res = false;
+ }
+ break;
}
+ }
+ }
+
+ return res;
+}
+
+void LLDockControl::moveDockable()
+{
+ // calculate new dockable position
+ LLRect dockRect = mDockWidget->calcScreenRect();
+ LLRect rootRect;
+ mGetAllowedRectCallback(rootRect);
+
+ LLRect dockableRect = mDockableFloater->calcScreenRect();
+ S32 x = 0;
+ S32 y = 0;
+ switch (mDockAt)
+ {
+ case TOP:
+ x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+ y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
+ // check is dockable inside root view rect
+ if (x < rootRect.mLeft)
+ {
+ x = rootRect.mLeft;
+ }
+ if (x + dockableRect.getWidth() > rootRect.mRight)
+ {
+ x = rootRect.mRight - dockableRect.getWidth();
+ }
+
+
+ // calculate dock tongue position
+ LLRect dockParentRect =
+ mDockWidget->getParent()->calcScreenRect();
+ if (dockRect.getCenterX() < dockParentRect.mLeft)
+ {
+ mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
+ }
+ else if (dockRect.getCenterX() > dockParentRect.mRight)
+ {
+ mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
+ }
+ else
+ {
mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
- mDockTongueY = dockRect.mTop;
- break;
}
- dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
- dockableRect.getHeight());
- LLRect localDocableParentRect;
- mDockableFloater->getParent()->screenRectToLocal(dockableRect,
- &localDocableParentRect);
- mDockableFloater->setRect(localDocableParentRect);
-
- mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
- &mDockTongueX, &mDockTongueY);
- mPrevDockRect = dockRect;
- mRootRect = rootRect;
- mRecalculateDocablePosition = false;
+ mDockTongueY = dockRect.mTop;
+
+ break;
}
+
+ // move dockable
+ dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
+ dockableRect.getHeight());
+ LLRect localDocableParentRect;
+ mDockableFloater->getParent()->screenRectToLocal(dockableRect,
+ &localDocableParentRect);
+ mDockableFloater->setRect(localDocableParentRect);
+
+ mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
+ &mDockTongueX, &mDockTongueY);
+
}
void LLDockControl::on()
{
- mDockableFloater->setCanDrag(false);
- mEnabled = true;
- mRecalculateDocablePosition = true;
+ if (isDockVisible())
+ {
+ mDockableFloater->setCanDrag(false);
+ mEnabled = true;
+ mRecalculateDocablePosition = true;
+ }
}
void LLDockControl::off()
@@ -141,3 +226,4 @@ void LLDockControl::drawToungue()
mDockTongue->draw(mDockTongueX, mDockTongueY);
}
}
+
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index 7d8d5c7653..e8ffcac0ac 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -51,10 +51,12 @@ public:
};
public:
+ // callback for a function getting a rect valid for control's position
+ typedef boost::function<void (LLRect& )> get_allowed_rect_callback_t;
+
LOG_CLASS(LLDockControl);
LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
- const LLUIImagePtr& dockTongue, DocAt dockAt,
- bool enabled);
+ const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_rect_callback = NULL);
virtual ~LLDockControl();
public:
@@ -63,9 +65,15 @@ public:
void setDock(LLView* dockWidget);
void repositionDockable();
void drawToungue();
-protected:
- virtual void calculateDockablePosition();
+ bool isDockVisible();
+
+ // gets a rect that bounds possible positions for a dockable control (EXT-1111)
+ void getAllowedRect(LLRect& rect);
+
+private:
+ virtual void moveDockable();
private:
+ get_allowed_rect_callback_t mGetAllowedRectCallback;
bool mEnabled;
bool mRecalculateDocablePosition;
DocAt mDockAt;
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 75334acb39..e9df361472 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -33,13 +33,16 @@
#include "linden_common.h"
#include "llpanel.h"
+#include "lltextbox.h"
#include "llflatlistview.h"
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().insert("selected", true);
+const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
+
+static const std::string COMMENT_TEXTBOX = "comment_text";
LLFlatListView::Params::Params()
: item_pad("item_pad"),
@@ -55,7 +58,12 @@ void LLFlatListView::reshape(S32 width, S32 height, BOOL called_from_parent /* =
rearrangeItems();
}
-bool LLFlatListView::addItem(LLPanel* item, LLSD value /* = LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/)
+const LLRect& LLFlatListView::getItemsRect() const
+{
+ return mItemsPanel->getRect();
+}
+
+bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/)
{
if (!item) return false;
if (value.isUndefined()) return false;
@@ -84,11 +92,12 @@ bool LLFlatListView::addItem(LLPanel* item, LLSD value /* = LLUUID::null*/, EAdd
item->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
rearrangeItems();
+ notifyParentItemsRectChanged();
return true;
}
-bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, LLSD value /*= LLUUID::null*/)
+bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value /*= LLUUID::null*/)
{
if (!after_item) return false;
if (!item_to_add) return false;
@@ -111,11 +120,11 @@ bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add,
else
{
pairs_iterator_t it = mItemPairs.begin();
- ++it;
- while (it != mItemPairs.end())
+ for (; it != mItemPairs.end(); ++it)
{
if (*it == after_pair)
{
+ // insert new elements before the element at position of passed iterator.
mItemPairs.insert(++it, new_pair);
mItemsPanel->addChild(item_to_add);
break;
@@ -128,6 +137,7 @@ bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add,
item_to_add->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
rearrangeItems();
+ notifyParentItemsRectChanged();
return true;
}
@@ -153,14 +163,14 @@ bool LLFlatListView::removeItemByValue(const LLSD& value)
return removeItemPair(item_pair);
}
-bool LLFlatListView::removeItemByUUID(LLUUID& uuid)
+bool LLFlatListView::removeItemByUUID(const LLUUID& uuid)
{
return removeItemByValue(LLSD(uuid));
}
-LLPanel* LLFlatListView::getItemByValue(LLSD& value) const
+LLPanel* LLFlatListView::getItemByValue(const LLSD& value) const
{
- if (value.isDefined()) return NULL;
+ if (value.isUndefined()) return NULL;
item_pair_t* pair = getItemPair(value);
if (pair) return pair->first;
@@ -188,7 +198,7 @@ bool LLFlatListView::selectItemByValue(const LLSD& value, bool select /*= true*/
return selectItemPair(item_pair, select);
}
-bool LLFlatListView::selectItemByUUID(LLUUID& uuid, bool select /* = true*/)
+bool LLFlatListView::selectItemByUUID(const LLUUID& uuid, bool select /* = true*/)
{
return selectItemByValue(LLSD(uuid), select);
}
@@ -252,7 +262,7 @@ void LLFlatListView::getSelectedItems(std::vector<LLPanel*>& selected_items) con
}
}
-void LLFlatListView::resetSelection()
+void LLFlatListView::resetSelection(bool no_commit_on_deselection /*= false*/)
{
if (mSelectedItemPairs.empty()) return;
@@ -264,6 +274,29 @@ void LLFlatListView::resetSelection()
}
mSelectedItemPairs.clear();
+
+ if (mCommitOnSelectionChange && !no_commit_on_deselection)
+ {
+ onCommit();
+ }
+}
+
+void LLFlatListView::setNoItemsCommentText(const std::string& comment_text)
+{
+ if (NULL == mNoItemsCommentTextbox)
+ {
+ LLRect comment_rect = getRect();
+ comment_rect.setOriginAndSize(0, 0, comment_rect.getWidth(), comment_rect.getHeight());
+ comment_rect.stretch(-getBorderWidth());
+ LLTextBox::Params text_p;
+ text_p.name(COMMENT_TEXTBOX);
+ text_p.border_visible(false);
+ text_p.rect(comment_rect);
+ text_p.follows.flags(FOLLOWS_ALL);
+ mNoItemsCommentTextbox = LLUICtrlFactory::create<LLTextBox>(text_p, this);
+ }
+
+ mNoItemsCommentTextbox->setValue(comment_text);
}
void LLFlatListView::clear()
@@ -272,11 +305,32 @@ void LLFlatListView::clear()
for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it)
{
mItemsPanel->removeChild((*it)->first);
- delete (*it)->first;
+ (*it)->first->die();
delete *it;
}
mItemPairs.clear();
mSelectedItemPairs.clear();
+
+ // also set items panel height to zero. Reshape it to allow reshaping of non-item children
+ LLRect rc = mItemsPanel->getRect();
+ rc.mBottom = rc.mTop;
+ mItemsPanel->reshape(rc.getWidth(), rc.getHeight());
+ mItemsPanel->setRect(rc);
+
+ setNoItemsCommentVisible(true);
+ notifyParentItemsRectChanged();
+}
+
+void LLFlatListView::sort()
+{
+ if (!mItemComparator)
+ {
+ llwarns << "No comparator specified for sorting FlatListView items." << llendl;
+ return;
+ }
+
+ mItemPairs.sort(ComparatorAdaptor(*mItemComparator));
+ rearrangeItems();
}
@@ -286,12 +340,16 @@ void LLFlatListView::clear()
LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
-: LLScrollContainer(p),
- mItemsPanel(NULL),
- mItemPad(p.item_pad),
- mAllowSelection(p.allow_select),
- mMultipleSelection(p.multi_select),
- mKeepOneItemSelected(p.keep_one_selected)
+: LLScrollContainer(p)
+ , mItemComparator(NULL)
+ , mItemsPanel(NULL)
+ , mItemPad(p.item_pad)
+ , mAllowSelection(p.allow_select)
+ , mMultipleSelection(p.multi_select)
+ , mKeepOneItemSelected(p.keep_one_selected)
+ , mCommitOnSelectionChange(false)
+ , mPrevNotifyParentRect(LLRect())
+ , mNoItemsCommentTextbox(NULL)
{
mBorderThickness = getBorderWidth();
@@ -315,19 +373,32 @@ void LLFlatListView::rearrangeItems()
{
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+ setNoItemsCommentVisible(mItemPairs.empty());
+
if (mItemPairs.empty()) return;
//calculating required height - assuming items can be of different height
//list should accommodate all its items
S32 height = 0;
+ S32 invisible_children_count = 0;
pairs_iterator_t it = mItemPairs.begin();
for (; it != mItemPairs.end(); ++it)
{
LLPanel* item = (*it)->first;
+
+ // skip invisible child
+ if (!item->getVisible())
+ {
+ ++invisible_children_count;
+ continue;
+ }
+
height += item->getRect().getHeight();
}
- height += mItemPad * (mItemPairs.size() - 1);
+
+ // add paddings between items, excluding invisible ones
+ height += mItemPad * (mItemPairs.size() - invisible_children_count - 1);
LLRect rc = mItemsPanel->getRect();
S32 width = mItemsNoScrollWidth;
@@ -346,14 +417,18 @@ void LLFlatListView::rearrangeItems()
for (it2 = first_it; it2 != mItemPairs.end(); ++it2)
{
LLPanel* item = (*it2)->first;
+
+ // skip invisible child
+ if (!item->getVisible())
+ continue;
+
LLRect rc = item->getRect();
- if(it2 != first_it)
- {
- item_new_top -= (rc.getHeight() + mItemPad);
- }
rc.setLeftTopAndSize(rc.mLeft, item_new_top, width, rc.getHeight());
item->reshape(rc.getWidth(), rc.getHeight());
item->setRect(rc);
+
+ // move top for next item in list
+ item_new_top -= (rc.getHeight() + mItemPad);
}
}
@@ -443,6 +518,12 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select)
//a way of notifying panel of selection state changes
LLPanel* item = item_pair->first;
item->setValue(select ? SELECTED_EVENT : UNSELECTED_EVENT);
+
+ if (mCommitOnSelectionChange)
+ {
+ onCommit();
+ }
+
return true;
}
@@ -483,12 +564,82 @@ bool LLFlatListView::removeItemPair(item_pair_t* item_pair)
}
mItemsPanel->removeChild(item_pair->first);
- delete item_pair->first;
+ item_pair->first->die();
delete item_pair;
rearrangeItems();
+ notifyParentItemsRectChanged();
return true;
}
+void LLFlatListView::notifyParentItemsRectChanged()
+{
+ S32 comment_height = 0;
+
+ // take into account comment text height if exists
+ if (mNoItemsCommentTextbox && mNoItemsCommentTextbox->getVisible())
+ {
+ comment_height = mNoItemsCommentTextbox->getTextPixelHeight();
+ }
+
+ LLRect req_rect = getItemsRect();
+
+ // get maximum of items total height and comment text height
+ req_rect.setOriginAndSize(req_rect.mLeft, req_rect.mBottom, req_rect.getWidth(), llmax(req_rect.getHeight(), comment_height));
+
+ // take into account border size.
+ req_rect.stretch(getBorderWidth());
+
+ if (req_rect == mPrevNotifyParentRect)
+ return;
+
+ mPrevNotifyParentRect = req_rect;
+
+ LLSD params;
+ params["action"] = "size_changes";
+ params["width"] = req_rect.getWidth();
+ params["height"] = req_rect.getHeight();
+
+ getParent()->notifyParent(params);
+}
+
+void LLFlatListView::setNoItemsCommentVisible(bool visible) const
+{
+ if (mNoItemsCommentTextbox)
+ {
+ if (visible)
+ {
+ // We have to update child rect here because of issues with rect after reshaping while creating LLTextbox
+ // It is possible to have invalid LLRect if Flat List is in LLAccordionTab
+ LLRect comment_rect = getLocalRect();
+ comment_rect.stretch(-getBorderWidth());
+ mNoItemsCommentTextbox->setRect(comment_rect);
+ }
+ mNoItemsCommentTextbox->setVisible(visible);
+ }
+}
+
+void LLFlatListView::getItems(std::vector<LLPanel*>& items) const
+{
+ if (mItemPairs.empty()) return;
+
+ items.clear();
+ for (pairs_const_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it)
+ {
+ items.push_back((*it)->first);
+ }
+}
+
+void LLFlatListView::getValues(std::vector<LLSD>& values) const
+{
+ if (mItemPairs.empty()) return;
+
+ values.clear();
+ for (pairs_const_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it)
+ {
+ values.push_back((*it)->second);
+ }
+}
+//EOF
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index bd0b419f4f..af5a9cfa9b 100644
--- a/indra/llui/llflatlistview.h
+++ b/indra/llui/llflatlistview.h
@@ -33,10 +33,10 @@
#ifndef LL_LLFLATLISTVIEW_H
#define LL_LLFLATLISTVIEW_H
+#include "llpanel.h"
#include "llscrollcontainer.h"
-
-class LLPanel;
+class LLTextBox;
/**
* LLFlatListView represents a flat list ui control that operates on items in a form of LLPanel's.
@@ -62,6 +62,38 @@ class LLFlatListView : public LLScrollContainer
{
public:
+ /**
+ * Abstract comparator for comparing flat list items in a form of LLPanel
+ */
+ class ItemComparator
+ {
+ public:
+ ItemComparator() {};
+ virtual ~ItemComparator() {};
+
+ /** Returns true if item1 < item2, false otherwise */
+ virtual bool compare(const LLPanel* item1, const LLPanel* item2) const = 0;
+ };
+
+ /**
+ * Represents reverse comparator which acts as a decorator for a comparator that need to be reversed
+ */
+ class ItemReverseComparator : public ItemComparator
+ {
+ public:
+ ItemReverseComparator(const ItemComparator& comparator) : mComparator(comparator) {};
+ virtual ~ItemReverseComparator() {};
+
+ virtual bool compare(const LLPanel* item1, const LLPanel* item2) const
+ {
+ return mComparator.compare(item2, item1);
+ }
+
+ private:
+ const ItemComparator& mComparator;
+ };
+
+
struct Params : public LLInitParam::Block<Params, LLScrollContainer::Params>
{
/** turning on/off selection support */
@@ -85,18 +117,23 @@ public:
/** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ /** Returns full rect of child panel */
+ const LLRect& getItemsRect() const;
+
+ /** Returns distance between items */
+ const S32 getItemsPad() { return mItemPad; }
/**
* Adds and item and LLSD value associated with it to the list at specified position
* @return true if the item was added, false otherwise
*/
- virtual bool addItem(LLPanel* item, LLSD value = LLUUID::null, EAddPosition pos = ADD_BOTTOM);
+ virtual bool addItem(LLPanel * item, const LLSD& value = LLUUID::null, EAddPosition pos = ADD_BOTTOM);
/**
* Insert item_to_add along with associated value to the list right after the after_item.
* @return true if the item was successfully added, false otherwise
*/
- virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, LLSD value = LLUUID::null);
+ virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value = LLUUID::null);
/**
* Remove specified item
@@ -114,13 +151,19 @@ public:
* Remove an item specified by uuid
* @return true if the item was removed, false otherwise
*/
- virtual bool removeItemByUUID(LLUUID& uuid);
+ virtual bool removeItemByUUID(const LLUUID& uuid);
/**
* Get an item by value
* @return the item as LLPanel if associated with value, NULL otherwise
*/
- virtual LLPanel* getItemByValue(LLSD& value) const;
+ virtual LLPanel* getItemByValue(const LLSD& value) const;
+
+ template<class T>
+ T* getTypedItemByValue(const LLSD& value) const
+ {
+ return dynamic_cast<T*>(getItemByValue(value));
+ }
/**
* Select or deselect specified item based on select
@@ -138,9 +181,17 @@ public:
* Select or deselect an item by associated uuid based on select
* @return true if succeed, false otherwise
*/
- virtual bool selectItemByUUID(LLUUID& uuid, bool select = true);
+ virtual bool selectItemByUUID(const LLUUID& uuid, bool select = true);
+ /**
+ * Get all panels stored in the list.
+ */
+ virtual void getItems(std::vector<LLPanel*>& items) const;
+ /**
+ * Get all items values.
+ */
+ virtual void getValues(std::vector<LLSD>& values) const;
/**
* Get LLSD associated with the first selected item
@@ -176,9 +227,23 @@ public:
virtual void getSelectedItems(std::vector<LLPanel*>& selected_items) const;
- /** Resets selection of items */
- virtual void resetSelection();
+ /**
+ * Resets selection of items.
+ *
+ * It calls onCommit callback if setCommitOnSelectionChange(bool b) was called with "true"
+ * argument for current Flat List.
+ * @param no_commit_on_deselection - if true onCommit callback will not be called
+ */
+ virtual void resetSelection(bool no_commit_on_deselection = false);
+ /**
+ * Sets comment text which will be shown in the list is it is empty.
+ *
+ * Textbox to hold passed text is created while this method is called at the first time.
+ *
+ * @param comment_text - string to be shown as a comment.
+ */
+ void setNoItemsCommentText( const std::string& comment_text);
/** Turn on/off multiple selection support */
void setAllowMultipleSelection(bool allow) { mMultipleSelection = allow; }
@@ -186,6 +251,8 @@ public:
/** Turn on/off selection support */
void setAllowSelection(bool can_select) { mAllowSelection = can_select; }
+ /** Sets flag whether onCommit should be fired if selection was changed */
+ void setCommitOnSelectionChange(bool b) { mCommitOnSelectionChange = b; }
/** Get number of selected items in the list */
U32 numSelected() const {return mSelectedItemPairs.size(); }
@@ -197,6 +264,14 @@ public:
/** Removes all items from the list */
virtual void clear();
+ /**
+ * Set comparator to use for future sorts.
+ *
+ * This class does NOT manage lifetime of the comparator
+ * but assumes that the comparator is always alive.
+ */
+ void setComparator(const ItemComparator* comp) { mItemComparator = comp; }
+ void sort();
protected:
@@ -207,6 +282,19 @@ protected:
typedef pairs_list_t::iterator pairs_iterator_t;
typedef pairs_list_t::const_iterator pairs_const_iterator_t;
+ /** An adapter for a ItemComparator */
+ struct ComparatorAdaptor
+ {
+ ComparatorAdaptor(const ItemComparator& comparator) : mComparator(comparator) {};
+
+ bool operator()(const item_pair_t* item_pair1, const item_pair_t* item_pair2)
+ {
+ return mComparator.compare(item_pair1->first, item_pair2->first);
+ }
+
+ const ItemComparator& mComparator;
+ };
+
friend class LLUICtrlFactory;
LLFlatListView(const LLFlatListView::Params& p);
@@ -214,7 +302,10 @@ protected:
/** Manage selection on mouse events */
void onItemMouseClick(item_pair_t* item_pair, MASK mask);
- /** Updates position of items */
+ /**
+ * Updates position of items.
+ * It does not take into account invisible items.
+ */
virtual void rearrangeItems();
virtual item_pair_t* getItemPair(LLPanel* item) const;
@@ -227,14 +318,27 @@ protected:
virtual bool removeItemPair(item_pair_t* item_pair);
+ /**
+ * Notify parent about changed size of internal controls with "size_changes" action
+ *
+ * Size includes Items Rect width and either Items Rect height or comment text height.
+ * Comment text height is included if comment text is set and visible.
+ * List border size is also included into notified size.
+ */
+ void notifyParentItemsRectChanged();
+
private:
void setItemsNoScrollWidth(S32 new_width) {mItemsNoScrollWidth = new_width - 2 * mBorderThickness;}
+ void setNoItemsCommentVisible(bool visible) const;
private:
+ /** Comparator to use when sorting the list. */
+ const ItemComparator* mItemComparator;
+
LLPanel* mItemsPanel;
S32 mItemsNoScrollWidth;
@@ -242,7 +346,7 @@ private:
S32 mBorderThickness;
/** Items padding */
- U32 mItemPad;
+ S32 mItemPad;
/** Selection support flag */
bool mAllowSelection;
@@ -250,6 +354,14 @@ private:
/** Multiselection support flag, ignored if selection is not supported */
bool mMultipleSelection;
+ /**
+ * Flag specified whether onCommit be called if selection is changed in the list.
+ *
+ * Can be ignored in the resetSelection() method.
+ * @see resetSelection()
+ */
+ bool mCommitOnSelectionChange;
+
bool mKeepOneItemSelected;
/** All pairs of the list */
@@ -257,6 +369,14 @@ private:
/** Selected pairs for faster access */
pairs_list_t mSelectedItemPairs;
+
+ /**
+ * Rectangle contained previous size of items parent notified last time.
+ * Is used to reduce amount of parentNotify() calls if size was not changed.
+ */
+ LLRect mPrevNotifyParentRect;
+
+ LLTextBox* mNoItemsCommentTextbox;
};
#endif
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index a57913683b..e0fe85ea01 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -59,6 +59,7 @@
#include "lltabcontainer.h"
#include "v2math.h"
#include "lltrans.h"
+#include "llhelp.h"
#include "llmultifloater.h"
#include "llsdutil.h"
@@ -67,48 +68,35 @@ const S32 TABBED_FLOATER_OFFSET = 0;
std::string LLFloater::sButtonActiveImageNames[BUTTON_COUNT] =
{
- "Icon_Close_Foreground", //BUTTON_CLOSE
- "restore.tga", //BUTTON_RESTORE
- "minimize.tga", //BUTTON_MINIMIZE
- "tearoffbox.tga", //BUTTON_TEAR_OFF
- "closebox.tga", //BUTTON_EDIT
- "Icon_Dock_Foreground",
- "Icon_Undock_Foreground"
-};
-
-// Empty string means programmatic glow effect, achieved by
-// not setting explicit image.
-std::string LLFloater::sButtonHoveredImageNames[BUTTON_COUNT] =
-{
- "", //BUTTON_CLOSE
- "restore_pressed.tga", //BUTTON_RESTORE
- "minimize_pressed.tga", //BUTTON_MINIMIZE
- "tearoff_pressed.tga", //BUTTON_TEAR_OFF
- "close_in_blue.tga", //BUTTON_EDIT
- "", //BUTTON_DOCK
- "", //BUTTON_UNDOCK
+ "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
- "restore_pressed.tga", //BUTTON_RESTORE
- "minimize_pressed.tga", //BUTTON_MINIMIZE
- "tearoff_pressed.tga", //BUTTON_TEAR_OFF
- "close_in_blue.tga", //BUTTON_EDIT
- "Icon_Dock_Press",
- "Icon_Undock_Press"
+ "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] =
{
- "llfloater_close_btn", //BUTTON_CLOSE
+ "llfloater_close_btn", //BUTTON_CLOSE
"llfloater_restore_btn", //BUTTON_RESTORE
"llfloater_minimize_btn", //BUTTON_MINIMIZE
"llfloater_tear_off_btn", //BUTTON_TEAR_OFF
- "llfloater_edit_btn", //BUTTON_EDIT
- "llfloater_dock_btn",
- "llfloater_undock_btn"
+ "llfloater_dock_btn", //BUTTON_DOCK
+ "llfloater_undock_btn", //BUTTON_UNDOCK
+ "llfloater_help_btn" //BUTTON_HELP
};
std::string LLFloater::sButtonToolTips[BUTTON_COUNT];
@@ -123,9 +111,9 @@ std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]=
"BUTTON_RESTORE", //"Restore", //BUTTON_RESTORE
"BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE
"BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF
- "BUTTON_EDIT", //"Edit", //BUTTON_EDIT
"BUTTON_DOCK",
- "BUTTON_UNDOCK"
+ "BUTTON_UNDOCK",
+ "BUTTON_HELP"
};
LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
@@ -134,13 +122,12 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
LLFloater::onClickMinimize, //BUTTON_RESTORE
LLFloater::onClickMinimize, //BUTTON_MINIMIZE
LLFloater::onClickTearOff, //BUTTON_TEAR_OFF
- LLFloater::onClickEdit, //BUTTON_EDIT
- LLFloater::onClickDock,
- LLFloater::onClickDock
+ LLFloater::onClickDock, //BUTTON_DOCK
+ LLFloater::onClickDock, //BUTTON_UNDOCK
+ LLFloater::onClickHelp //BUTTON_HELP
};
LLMultiFloater* LLFloater::sHostp = NULL;
-BOOL LLFloater::sEditModeEnabled = FALSE;
BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting
LLFloater::handle_map_t LLFloater::sFloaterMap;
@@ -249,7 +236,6 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mMinimized(FALSE),
mForeground(FALSE),
mFirstLook(TRUE),
- mEditing(FALSE),
mButtonScale(1.0f),
mAutoFocus(TRUE), // automatically take focus when opened
mCanDock(false),
@@ -304,6 +290,12 @@ void LLFloater::initFloater()
mButtonsEnabled[BUTTON_CLOSE] = TRUE;
}
+ // Help button: '?'
+ if ( !mHelpTopic.empty() )
+ {
+ mButtonsEnabled[BUTTON_HELP] = TRUE;
+ }
+
// Minimize button only for top draggers
if ( !mDragOnLeft && mCanMinimize )
{
@@ -794,7 +786,7 @@ void LLFloater::setTitle( const std::string& title )
applyTitle();
}
-std::string LLFloater::getTitle()
+std::string LLFloater::getTitle() const
{
if (mTitle.empty())
{
@@ -812,7 +804,7 @@ void LLFloater::setShortTitle( const std::string& short_title )
applyTitle();
}
-std::string LLFloater::getShortTitle()
+std::string LLFloater::getShortTitle() const
{
if (mShortTitle.empty())
{
@@ -824,8 +816,6 @@ std::string LLFloater::getShortTitle()
}
}
-
-
BOOL LLFloater::canSnapTo(const LLView* other_view)
{
if (NULL == other_view)
@@ -1041,6 +1031,10 @@ void LLFloater::setMinimized(BOOL minimize)
reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
}
+ // don't show the help button while minimized - it's
+ // not very useful when minimized and uses up space
+ mButtonsEnabled[BUTTON_HELP] = !minimize;
+
applyTitle ();
make_ui_sound("UISndWindowClose");
@@ -1377,28 +1371,6 @@ void LLFloater::setDocked(bool docked, bool pop_on_undock)
}
}
-//static
-void LLFloater::setEditModeEnabled(BOOL enable)
-{
- if (enable != sEditModeEnabled)
- {
- S32 count = 0;
- for(handle_map_iter_t iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter)
- {
- LLFloater* floater = iter->second;
- if (!floater->isDead())
- {
- iter->second->mButtonsEnabled[BUTTON_EDIT] = enable;
- iter->second->updateButtons();
- }
- count++;
- }
- }
-
- sEditModeEnabled = enable;
-}
-
-
// static
void LLFloater::onClickMinimize(LLFloater* self)
{
@@ -1446,19 +1418,20 @@ void LLFloater::onClickTearOff(LLFloater* self)
}
// static
-void LLFloater::onClickEdit(LLFloater* self)
+void LLFloater::onClickDock(LLFloater* self)
{
- if (!self)
- return;
- self->mEditing = self->mEditing ? FALSE : TRUE;
+ if(self && self->mCanDock)
+ {
+ self->setDocked(!self->mDocked, true);
+ }
}
// static
-void LLFloater::onClickDock(LLFloater* self)
+void LLFloater::onClickHelp( LLFloater* self )
{
- if(self && self->mCanDock)
+ if (self && LLUI::sHelpImpl)
{
- self->setDocked(!self->mDocked, true);
+ LLUI::sHelpImpl->showTopic(self->getHelpTopic());
}
}
@@ -1797,17 +1770,9 @@ void LLFloater::buildButtons()
// Selected, no matter if hovered or not, is "pressed"
p.image_selected.name(sButtonPressedImageNames[i]);
p.image_hover_selected.name(sButtonPressedImageNames[i]);
- // Empty string means programmatic glow effect, achieved by
- // not setting explicit image.
- if (sButtonHoveredImageNames[i].empty())
- {
- // These icons are really small, need glow amount increased
- p.hover_glow_amount( 0.22f );
- }
- else
- {
- p.image_hover_unselected.name(sButtonHoveredImageNames[i]);
- }
+ // 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);
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 6208d52135..a320ba4a6f 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -103,9 +103,9 @@ public:
BUTTON_RESTORE,
BUTTON_MINIMIZE,
BUTTON_TEAR_OFF,
- BUTTON_EDIT,
BUTTON_DOCK,
BUTTON_UNDOCK,
+ BUTTON_HELP,
BUTTON_COUNT
};
@@ -175,9 +175,9 @@ public:
void applyTitle();
const std::string& getCurrentTitle() const;
void setTitle( const std::string& title);
- std::string getTitle();
+ std::string getTitle() const;
void setShortTitle( const std::string& short_title );
- std::string getShortTitle();
+ std::string getShortTitle() const;
void setTitleVisible(bool visible);
virtual void setMinimized(BOOL b);
void moveResizeHandlesToFront();
@@ -258,12 +258,10 @@ public:
static void onClickClose(LLFloater* floater);
static void onClickMinimize(LLFloater* floater);
static void onClickTearOff(LLFloater* floater);
- static void onClickEdit(LLFloater* floater);
static void onClickDock(LLFloater* floater);
+ static void onClickHelp(LLFloater* floater);
static void setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; }
- static void setEditModeEnabled(BOOL enable);
- static BOOL getEditModeEnabled() { return sEditModeEnabled; }
static LLMultiFloater* getFloaterHost() {return sHostp; }
protected:
@@ -333,7 +331,6 @@ private:
BOOL mFirstLook; // TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible.
- BOOL mEditing;
typedef std::set<LLHandle<LLFloater> > handle_set_t;
typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t;
@@ -352,11 +349,8 @@ private:
bool mDocked;
static LLMultiFloater* sHostp;
- static BOOL sEditModeEnabled;
static BOOL sQuitting;
static std::string sButtonActiveImageNames[BUTTON_COUNT];
- // Images to use when cursor hovered over an enabled button
- static std::string sButtonHoveredImageNames[BUTTON_COUNT];
static std::string sButtonPressedImageNames[BUTTON_COUNT];
static std::string sButtonNames[BUTTON_COUNT];
static std::string sButtonToolTips[BUTTON_COUNT];
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index 60ddbc6cb3..279cbaa923 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -41,11 +41,6 @@ const F32 FOCUS_FADE_TIME = 0.3f;
// NOTE: the LLFocusableElement implementation has been moved here from lluictrl.cpp.
LLFocusableElement::LLFocusableElement()
-: mFocusLostCallback(NULL),
- mFocusReceivedCallback(NULL),
- mFocusChangedCallback(NULL),
- mTopLostCallback(NULL),
- mFocusCallbackUserData(NULL)
{
}
@@ -68,35 +63,19 @@ LLFocusableElement::~LLFocusableElement()
void LLFocusableElement::onFocusReceived()
{
- if( mFocusReceivedCallback )
- {
- mFocusReceivedCallback( this, mFocusCallbackUserData );
- }
- if( mFocusChangedCallback )
- {
- mFocusChangedCallback( this, mFocusCallbackUserData );
- }
+ mFocusReceivedCallback(this);
+ mFocusChangedCallback(this);
}
void LLFocusableElement::onFocusLost()
{
- if( mFocusLostCallback )
- {
- mFocusLostCallback( this, mFocusCallbackUserData );
- }
-
- if( mFocusChangedCallback )
- {
- mFocusChangedCallback( this, mFocusCallbackUserData );
- }
+ mFocusLostCallback(this);
+ mFocusChangedCallback(this);
}
void LLFocusableElement::onTopLost()
{
- if (mTopLostCallback)
- {
- mTopLostCallback(this, mFocusCallbackUserData);
- }
+ mTopLostCallback(this);
}
BOOL LLFocusableElement::hasFocus() const
@@ -188,12 +167,9 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
view_handle_list_t new_focus_list;
// walk up the tree to root and add all views to the new_focus_list
- for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl && ctrl != LLUI::getRootView(); ctrl = ctrl->getParent())
+ for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl; ctrl = ctrl->getParent())
{
- if (ctrl)
- {
- new_focus_list.push_back(ctrl->getHandle());
- }
+ new_focus_list.push_back(ctrl->getHandle());
}
// remove all common ancestors since their focus is unchanged
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index d0adadd6d3..2fa4e124fb 100644
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -54,11 +54,12 @@ public:
virtual void setFocus( BOOL b );
virtual BOOL hasFocus() const;
- typedef boost::function<void(LLFocusableElement*, void*)> focus_callback_t;
- void setFocusLostCallback(focus_callback_t cb, void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; }
- void setFocusReceivedCallback(focus_callback_t cb, void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; }
- void setFocusChangedCallback(focus_callback_t cb, void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; }
- void setTopLostCallback(focus_callback_t cb, void* user_data = NULL ) { mTopLostCallback = cb; mFocusCallbackUserData = user_data; }
+ typedef boost::signals2::signal<void(LLFocusableElement*)> focus_signal_t;
+
+ boost::signals2::connection setFocusLostCallback( const focus_signal_t::slot_type& cb) { return mFocusLostCallback.connect(cb);}
+ boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb) { return mFocusReceivedCallback.connect(cb);}
+ boost::signals2::connection setFocusChangedCallback(const focus_signal_t::slot_type& cb) { return mFocusChangedCallback.connect(cb);}
+ void setTopLostCallback(const focus_signal_t::slot_type& cb) { mTopLostCallback.connect(cb);}
// These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus.
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
@@ -68,11 +69,10 @@ protected:
virtual void onFocusReceived();
virtual void onFocusLost();
virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere
- focus_callback_t mFocusLostCallback;
- focus_callback_t mFocusReceivedCallback;
- focus_callback_t mFocusChangedCallback;
- focus_callback_t mTopLostCallback;
- void* mFocusCallbackUserData;
+ focus_signal_t mFocusLostCallback;
+ focus_signal_t mFocusReceivedCallback;
+ focus_signal_t mFocusChangedCallback;
+ focus_signal_t mTopLostCallback;
};
diff --git a/indra/llui/llhelp.h b/indra/llui/llhelp.h
new file mode 100644
index 0000000000..c06d29a4bd
--- /dev/null
+++ b/indra/llui/llhelp.h
@@ -0,0 +1,45 @@
+/**
+ * @file llhelp.h
+ * @brief Abstract interface to the Help system
+ * @author Tofu Linden
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 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 LL_LLHELP_H
+#define LL_LLHELP_H
+
+class LLHelp
+{
+ public:
+ virtual void showTopic(const std::string &topic) = 0;
+ // return default (fallback) topic name suitable for showTopic()
+ virtual std::string defaultTopic() = 0;
+};
+
+#endif // headerguard
diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp
index 01a3b5fdc7..0fbb7ced54 100644
--- a/indra/llui/llmultisliderctrl.cpp
+++ b/indra/llui/llmultisliderctrl.cpp
@@ -140,7 +140,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p)
params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
- mEditor->setFocusReceivedCallback( &LLMultiSliderCtrl::onEditorGainFocus );
+ mEditor->setFocusReceivedCallback( boost::bind(LLMultiSliderCtrl::onEditorGainFocus, _1, this) );
// don't do this, as selecting the entire text is single clicking in some cases
// and double clicking in others
//mEditor->setSelectAllonFocusReceived(TRUE);
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 2b4aad5e83..a68b9cae57 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1446,8 +1446,8 @@ void LLNotifications::cancel(LLNotificationPtr pNotif)
{
llerrs << "Attempted to delete nonexistent notification " << pNotif->getName() << llendl;
}
- updateItem(LLSD().insert("sigtype", "delete").insert("id", pNotif->id()), pNotif);
pNotif->cancel();
+ updateItem(LLSD().insert("sigtype", "delete").insert("id", pNotif->id()), pNotif);
}
void LLNotifications::update(const LLNotificationPtr pNotif)
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 26136e0a23..b9bbb4db22 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -80,6 +80,7 @@ LLPanel::Params::Params()
strings("string"),
filename("filename"),
class_name("class"),
+ help_topic("help_topic"),
visible_callback("visible_callback")
{
name = "panel";
@@ -98,6 +99,7 @@ LLPanel::LLPanel(const LLPanel::Params& p)
mDefaultBtn(NULL),
mBorder(NULL),
mLabel(p.label),
+ mHelpTopic(p.help_topic),
mCommitCallbackRegistrar(false),
mEnableCallbackRegistrar(false),
mXMLFilename(p.filename)
@@ -416,6 +418,7 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
}
setLabel(p.label());
+ setHelpTopic(p.help_topic);
setShape(p.rect);
parseFollowsFlags(p);
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index 81b5b68f05..8b23ea7030 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -83,6 +83,7 @@ public:
Optional<std::string> filename;
Optional<std::string> class_name;
+ Optional<std::string> help_topic;
Multiple<LocalizedString> strings;
@@ -139,10 +140,11 @@ public:
void updateDefaultBtn();
void setLabel(const LLStringExplicit& label) { mLabel = label; }
std::string getLabel() const { return mLabel; }
+ void setHelpTopic(const std::string& help_topic) { mHelpTopic = help_topic; }
+ std::string getHelpTopic() const { return mHelpTopic; }
void setCtrlsEnabled(BOOL b);
-
LLHandle<LLPanel> getHandle() const { return mPanelHandle; }
const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
@@ -243,6 +245,8 @@ protected:
EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar;
commit_signal_t mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD()
+
+ std::string mHelpTopic; // the name of this panel's help topic to display in the Help Viewer
private:
LLUIColor mBgColorAlpha;
@@ -259,7 +263,7 @@ private:
// for setting the xml filename when building panel in context dependent cases
std::string mXMLFilename;
-
+
}; // end class LLPanel
#endif
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index 172c4a9c65..ed150ac50c 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -66,7 +66,9 @@ LLScrollbar::Params::Params()
up_button("up_button"),
down_button("down_button"),
left_button("left_button"),
- right_button("right_button")
+ right_button("right_button"),
+ bg_visible("bg_visible", false),
+ bg_color("bg_color", LLColor4::black)
{
tab_stop = false;
}
@@ -92,7 +94,9 @@ LLScrollbar::LLScrollbar(const Params & p)
mThumbImageH(p.thumb_image_horizontal),
mTrackImageV(p.track_image_vertical),
mTrackImageH(p.track_image_horizontal),
- mThickness(p.thickness.isProvided() ? p.thickness : LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize"))
+ mThickness(p.thickness.isProvided() ? p.thickness : LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize")),
+ mBGVisible(p.bg_visible),
+ mBGColor(p.bg_color)
{
updateThumbRect();
@@ -482,6 +486,11 @@ void LLScrollbar::draw()
{
if (!getRect().isValid()) return;
+ if(mBGVisible)
+ {
+ gl_rect_2d(getLocalRect(), mBGColor.get(), TRUE);
+ }
+
S32 local_mouse_x;
S32 local_mouse_y;
LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y);
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index 30d906e04c..7e88b16561 100644
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -66,8 +66,11 @@ public:
track_image_horizontal,
track_image_vertical;
+ Optional<bool> bg_visible;
+
Optional<LLUIColor> track_color,
- thumb_color;
+ thumb_color,
+ bg_color;
Optional<LLButton::Params> up_button;
Optional<LLButton::Params> down_button;
@@ -151,6 +154,9 @@ private:
LLUIColor mTrackColor;
LLUIColor mThumbColor;
+ LLUIColor mBGColor;
+
+ bool mBGVisible;
LLUIImagePtr mThumbImageV;
LLUIImagePtr mThumbImageH;
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 30a042cff1..cd5926fb6b 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -67,12 +67,10 @@ static LLDefaultChildRegistry::Register<LLScrollContainer> r("scroll_container")
#include "llscrollingpanellist.h"
#include "llcontainerview.h"
#include "llpanel.h"
-#include "lllistctrl.h"
static ScrollContainerRegistry::Register<LLScrollingPanelList> r1("scrolling_panel_list");
static ScrollContainerRegistry::Register<LLContainerView> r2("container_view");
static ScrollContainerRegistry::Register<LLPanel> r3("panel", &LLPanel::fromXML);
-static ScrollContainerRegistry::Register<LLListCtrl> r4("list");
LLScrollContainer::Params::Params()
: is_opaque("opaque"),
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 483106e857..54e42bf642 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -139,7 +139,9 @@ LLScrollListCtrl::Params::Params()
bg_stripe_color("bg_stripe_color"),
hovered_color("hovered_color"),
highlighted_color("highlighted_color"),
- contents("")
+ contents(""),
+ scroll_bar_bg_visible("scroll_bar_bg_visible"),
+ scroll_bar_bg_color("scroll_bar_bg_color")
{
name = "scroll_list";
mouse_opaque = true;
@@ -220,6 +222,8 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
sbparams.change_callback(boost::bind(&LLScrollListCtrl::onScrollChange, this, _1, _2));
sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
sbparams.visible(false);
+ sbparams.bg_visible(p.scroll_bar_bg_visible);
+ sbparams.bg_color(p.scroll_bar_bg_color);
mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams);
addChild(mScrollbar);
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 49a49499ef..83b2f71037 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -83,7 +83,8 @@ public:
Optional<bool> has_border,
draw_heading,
draw_stripes,
- background_visible;
+ background_visible,
+ scroll_bar_bg_visible;
// layout
Optional<S32> column_padding,
@@ -104,7 +105,8 @@ public:
bg_readonly_color,
bg_stripe_color,
hovered_color,
- highlighted_color;
+ highlighted_color,
+ scroll_bar_bg_color;
Optional<Contents> contents;
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index 675a29a8b4..553b28ab87 100644
--- a/indra/llui/llsliderctrl.cpp
+++ b/indra/llui/llsliderctrl.cpp
@@ -143,7 +143,7 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
line_p.prevalidate_callback(&LLLineEditor::prevalidateFloat);
mEditor = LLUICtrlFactory::create<LLLineEditor>(line_p);
- mEditor->setFocusReceivedCallback( &LLSliderCtrl::onEditorGainFocus, this );
+ mEditor->setFocusReceivedCallback( boost::bind(&LLSliderCtrl::onEditorGainFocus, _1, this ));
// don't do this, as selecting the entire text is single clicking in some cases
// and double clicking in others
//mEditor->setSelectAllonFocusReceived(TRUE);
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index 3a96bc8f93..83d71006aa 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -142,7 +142,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
- mEditor->setFocusReceivedCallback( &LLSpinCtrl::onEditorGainFocus, this );
+ mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onEditorGainFocus, _1, this ));
//RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus
// than when it doesn't. Instead, if you always have to double click to select all the text,
// it's easier to understand
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index 291d1dc517..0517325e70 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -109,6 +109,7 @@ public:
void setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ){ mClickedCallback = boost::bind(cb, userdata); } // mouse down and up within button
const LLFontGL* getFont() const { return mDefaultFont; }
+ void setFont(const LLFontGL* font) { mDefaultFont = font; }
void reshapeToFitText();
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 8d5f277b59..39f09b297f 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2001,6 +2001,8 @@ void LLTextEditor::cut()
deleteSelection( FALSE );
needsReflow();
+
+ onKeyStroke();
}
BOOL LLTextEditor::canCopy() const
@@ -2105,6 +2107,8 @@ void LLTextEditor::pasteHelper(bool is_primary)
deselect();
needsReflow();
+
+ onKeyStroke();
}
@@ -2492,6 +2496,8 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
if(text_may_have_changed)
{
needsReflow();
+
+ onKeyStroke();
}
needsScroll();
}
@@ -2534,6 +2540,8 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
deselect();
needsReflow();
+
+ onKeyStroke();
}
return handled;
@@ -2588,6 +2596,8 @@ void LLTextEditor::doDelete()
setCursorPos(mCursorPos + 1);
removeChar();
}
+
+ onKeyStroke();
}
needsReflow();
@@ -2634,6 +2644,8 @@ void LLTextEditor::undo()
setCursorPos(pos);
needsReflow();
+
+ onKeyStroke();
}
BOOL LLTextEditor::canRedo() const
@@ -2676,6 +2688,8 @@ void LLTextEditor::redo()
setCursorPos(pos);
needsReflow();
+
+ onKeyStroke();
}
void LLTextEditor::onFocusReceived()
@@ -4402,6 +4416,8 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
// Update of the preedit should be caused by some key strokes.
mKeystrokeTimer.reset();
+
+ onKeyStroke();
}
BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
@@ -4648,3 +4664,30 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
ed->addDocumentChild(mView);
}
}
+
+BOOL LLTextEditor::isDirty() const
+{
+ if(mReadOnly)
+ {
+ return FALSE;
+ }
+
+ if( mPristineCmd )
+ {
+ return ( mPristineCmd == mLastCmd );
+ }
+ else
+ {
+ return ( NULL != mLastCmd );
+ }
+}
+
+void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& callback)
+{
+ mKeystrokeSignal.connect(callback);
+}
+
+void LLTextEditor::onKeyStroke()
+{
+ mKeystrokeSignal(this);
+}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 68b8f2c3b1..a04261c4be 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -139,6 +139,10 @@ public:
virtual ~LLTextEditor();
+ typedef boost::signals2::signal<void (LLTextEditor* caller)> keystroke_signal_t;
+
+ void setKeystrokeCallback(const keystroke_signal_t::slot_type& callback);
+
void setParseHighlights(BOOL parsing) {mParseHighlights=parsing;}
// mousehandler overrides
@@ -169,7 +173,7 @@ public:
virtual void clear();
virtual void setFocus( BOOL b );
virtual BOOL acceptsTextInput() const;
- virtual BOOL isDirty() const { return isPristine(); }
+ virtual BOOL isDirty() const;
virtual void setValue(const LLSD& value);
// LLEditMenuHandler interface
@@ -503,6 +507,8 @@ private:
S32 getFirstVisibleLine() const;
+ void onKeyStroke();
+
//
// Data
//
@@ -568,6 +574,8 @@ private:
BOOL mHandleEditKeysDirectly;
LLCoordGL mLastIMEPosition; // Last position of the IME editor
+
+ keystroke_signal_t mKeystrokeSignal;
}; // end class LLTextEditor
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 000e85f78c..d5b67f53b7 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -79,10 +79,10 @@ std::list<std::string> gUntranslated;
/*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
/*static*/ LLVector2 LLUI::sGLScaleFactor(1.f, 1.f);
/*static*/ LLWindow* LLUI::sWindow = NULL;
-/*static*/ LLHtmlHelp* LLUI::sHtmlHelp = NULL;
/*static*/ LLView* LLUI::sRootView = NULL;
-/*static*/ BOOL LLUI::sDirty = FALSE;
-/*static*/ LLRect LLUI::sDirtyRect;
+/*static*/ BOOL LLUI::sDirty = FALSE;
+/*static*/ LLRect LLUI::sDirtyRect;
+/*static*/ LLHelp* LLUI::sHelpImpl = NULL;
/*static*/ std::vector<std::string> LLUI::sXUIPaths;
/*static*/ LLFrameTimer LLUI::sMouseIdleTimer;
@@ -695,44 +695,6 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
}
-void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
- if (NULL == image)
- {
- llwarns << "image == NULL; aborting function" << llendl;
- return;
- }
-
- LLGLSUIDefault gls_ui;
-
- gGL.pushMatrix();
- {
- gGL.translatef((F32)x, (F32)y, 0.f);
-
- gGL.getTexUnit(0)->bind(image);
-
- gGL.color4fv(color.mV);
-
- gGL.begin(LLRender::QUADS);
- {
- gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
- gGL.vertex2i(width, height );
-
- gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
- gGL.vertex2i(0, height );
-
- gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
- gGL.vertex2i(0, 0);
-
- gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
- gGL.vertex2i(width, 0);
- }
- gGL.end();
- }
- gGL.popMatrix();
-}
-
-
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
{
phase = fmod(phase, 1.f);
@@ -1592,6 +1554,9 @@ void LLUI::initClass(const settings_map_t& settings,
// Button initialization callback for toggle buttons
LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2));
+ // Display the help topic for the current context
+ LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2));
+
// Currently unused, but kept for reference:
LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2));
@@ -1850,12 +1815,6 @@ LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name)
return NULL;
}
-// static
-void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
-{
- LLUI::sHtmlHelp = html_help;
-}
-
LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
{
for (settings_map_t::iterator itor = sSettingGroups.begin();
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index fddf8192ad..86cb516500 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -57,13 +57,13 @@
#include "llfontgl.h"
class LLColor4;
-class LLHtmlHelp;
class LLVector3;
class LLVector2;
class LLUIImage;
class LLUUID;
class LLWindow;
class LLView;
+class LLHelp;
// UI colors
extern const LLColor4 UI_VERTEX_COLOR;
@@ -104,8 +104,6 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LL
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-// Flip vertical, used for LLFloaterHTML
-void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom);
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f );
@@ -203,7 +201,6 @@ public:
static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
static void screenRectToGL(const LLRect& screen, LLRect *gl);
static void glRectToScreen(const LLRect& gl, LLRect *screen);
- static void setHtmlHelp(LLHtmlHelp* html_help);
// Returns the control group containing the control name, or the default group
static LLControlGroup& getControlControlGroup (const std::string& controlname);
static F32 getMouseIdleTime() { return sMouseIdleTimer.getElapsedTimeF32(); }
@@ -223,8 +220,8 @@ public:
static LLUIAudioCallback sAudioCallback;
static LLVector2 sGLScaleFactor;
static LLWindow* sWindow;
- static LLHtmlHelp* sHtmlHelp;
static LLView* sRootView;
+ static LLHelp* sHelpImpl;
private:
static LLImageProviderInterface* sImageProvider;
static std::vector<std::string> sXUIPaths;
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 8807e26f6b..fe99d9c267 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -114,7 +114,6 @@ void LLUICtrl::initFromParams(const Params& p)
}
setTabStop(p.tab_stop);
- setFocusLostCallback(p.focus_lost_callback());
if (p.initial_value.isProvided()
&& !p.control_name.isProvided())
@@ -763,6 +762,27 @@ LLUICtrl* LLUICtrl::getParentUICtrl() const
return NULL;
}
+bool LLUICtrl::findHelpTopic(std::string& help_topic_out)
+{
+ LLUICtrl* ctrl = this;
+
+ // search back through the control's parents for a panel
+ // with a help_topic string defined
+ while (ctrl)
+ {
+ LLPanel *panel = dynamic_cast<LLPanel *>(ctrl);
+ if (panel && !panel->getHelpTopic().empty())
+ {
+ help_topic_out = panel->getHelpTopic();
+ return true; // success
+ }
+
+ ctrl = ctrl->getParentUICtrl();
+ }
+
+ return false; // no help topic found
+}
+
// *TODO: Deprecate; for backwards compatability only:
boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data)
{
@@ -800,14 +820,7 @@ namespace LLInitParam
return false;
}
- template<>
- bool ParamCompare<LLUICtrl::focus_callback_t>::equals(
- const LLUICtrl::focus_callback_t &a,
- const LLUICtrl::focus_callback_t &b)
- {
- return false;
- }
-
+
template<>
bool ParamCompare<LLUICtrl::enable_callback_t>::equals(
const LLUICtrl::enable_callback_t &a,
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 3add9393ea..c2502732f3 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -124,8 +124,6 @@ public:
Optional<CommitCallbackParam> mouseenter_callback;
Optional<CommitCallbackParam> mouseleave_callback;
- Optional<focus_callback_t> focus_lost_callback;
-
Optional<std::string> control_name;
Optional<EnableControls> enabled_controls;
Optional<ControlVisibility> controls_visibility;
@@ -225,6 +223,10 @@ public:
LLUICtrl* getParentUICtrl() const;
+ // return true if help topic found by crawling through parents -
+ // topic then put in help_topic_out
+ bool findHelpTopic(std::string& help_topic_out);
+
boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ) { return mCommitSignal.connect(cb); }
boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ) { return mValidateSignal.connect(cb); }
@@ -309,11 +311,6 @@ namespace LLInitParam
const LLUICtrl::enable_callback_t &a,
const LLUICtrl::enable_callback_t &b);
- template<>
- bool ParamCompare<LLUICtrl::focus_callback_t>::equals(
- const LLUICtrl::focus_callback_t &a,
- const LLUICtrl::focus_callback_t &b);
-
template<>
bool ParamCompare<LLLazyValue<LLColor4> >::equals(
const LLLazyValue<LLColor4> &a, const LLLazyValue<LLColor4> &b);
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index 3b689b93c0..f3401f91f7 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -134,4 +134,3 @@ void LLUrlAction::copyLabelToClipboard(std::string url)
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(match.getLabel()));
}
}
-
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 256c776293..10cb3fb377 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -466,16 +466,6 @@ LLRect LLView::getRequiredRect()
return mRect;
}
-//virtual
-void LLView::onFocusLost()
-{
-}
-
-//virtual
-void LLView::onFocusReceived()
-{
-}
-
BOOL LLView::focusNextRoot()
{
LLView::child_list_t result = LLView::getFocusRootsQuery().run(this);
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index bf3b5d0614..7a37d6f430 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -405,10 +405,6 @@ public:
BOOL getSaveToXML() const { return mSaveToXML; }
void setSaveToXML(BOOL b) { mSaveToXML = b; }
- // inherited from LLFocusableElement
- /* virtual */ void onFocusLost();
- /* virtual */ void onFocusReceived();
-
typedef enum e_hit_test_type
{
HIT_TEST_USE_BOUNDING_RECT,