summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/CMakeLists.txt4
-rw-r--r--indra/llui/llbutton.cpp29
-rw-r--r--indra/llui/llbutton.h1
-rw-r--r--indra/llui/llcombobox.cpp23
-rw-r--r--indra/llui/llcombobox.h2
-rw-r--r--indra/llui/llfloater.cpp85
-rw-r--r--indra/llui/llfloater.h3
-rw-r--r--indra/llui/lliconctrl.cpp10
-rw-r--r--indra/llui/lliconctrl.h2
-rw-r--r--indra/llui/lllayoutstack.cpp2
-rw-r--r--indra/llui/lllocalcliprect.cpp143
-rw-r--r--indra/llui/lllocalcliprect.h53
-rw-r--r--indra/llui/llmenugl.cpp2
-rw-r--r--indra/llui/llpanel.cpp28
-rw-r--r--indra/llui/llpanel.h13
-rw-r--r--indra/llui/llscrollbar.cpp2
-rw-r--r--indra/llui/llscrollcontainer.cpp1
-rw-r--r--indra/llui/llscrolllistctrl.cpp15
-rw-r--r--indra/llui/llscrolllistctrl.h2
-rw-r--r--indra/llui/llsdparam.cpp10
-rw-r--r--indra/llui/llslider.cpp16
-rw-r--r--indra/llui/lltabcontainer.cpp7
-rw-r--r--indra/llui/lltabcontainer.h2
-rw-r--r--indra/llui/lltextbase.cpp18
-rw-r--r--indra/llui/lltextbase.h2
-rw-r--r--indra/llui/lltextbox.cpp21
-rw-r--r--indra/llui/lltextbox.h6
-rw-r--r--indra/llui/lltexteditor.cpp18
-rw-r--r--indra/llui/lltexteditor.h2
-rw-r--r--indra/llui/lltooltip.cpp445
-rw-r--r--indra/llui/lltooltip.h127
-rw-r--r--indra/llui/llui.cpp121
-rw-r--r--indra/llui/llui.h73
-rw-r--r--indra/llui/lluictrl.cpp4
-rw-r--r--indra/llui/lluictrl.h1
-rw-r--r--indra/llui/lluictrlfactory.cpp14
-rw-r--r--indra/llui/llview.cpp312
-rw-r--r--indra/llui/llview.h122
-rw-r--r--indra/llui/llviewborder.cpp2
39 files changed, 1237 insertions, 506 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 95d693cdc4..cc9362a252 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -50,6 +50,7 @@ set(llui_SOURCE_FILES
lllayoutstack.cpp
lllineeditor.cpp
lllistctrl.cpp
+ lllocalcliprect.cpp
llmenugl.cpp
llmodaldialog.cpp
llmultifloater.cpp
@@ -85,6 +86,7 @@ set(llui_SOURCE_FILES
lltexteditor.cpp
lltextparser.cpp
lltransutil.cpp
+ lltooltip.cpp
llui.cpp
lluicolortable.cpp
lluictrl.cpp
@@ -133,6 +135,7 @@ set(llui_HEADER_FILES
lllazyvalue.h
lllineeditor.h
lllistctrl.h
+ lllocalcliprect.h
llmenugl.h
llmodaldialog.h
llmultifloater.h
@@ -167,6 +170,7 @@ set(llui_HEADER_FILES
lltextbox.h
lltexteditor.h
lltextparser.h
+ lltooltip.h
lltransutil.h
lluicolortable.h
lluiconstants.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index bf58e19949..fa13ced037 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -514,6 +514,7 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
// virtual
void LLButton::draw()
{
+ F32 alpha = getDrawContext().mAlpha;
bool flash = FALSE;
static LLUICachedControl<F32> button_flash_rate("ButtonFlashRate", 0);
static LLUICachedControl<S32> button_flash_count("ButtonFlashCount", 0);
@@ -535,7 +536,7 @@ void LLButton::draw()
// Unselected image assignments
S32 local_mouse_x;
S32 local_mouse_y;
- LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y);
+ LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y);
bool enabled = isInEnabledChain();
@@ -662,7 +663,7 @@ void LLButton::draw()
if (hasFocus())
{
F32 lerp_amt = gFocusMgr.getFocusFlashAmt();
- drawBorder(imagep, gFocusMgr.getFocusColor(), llround(lerp(1.f, 3.f, lerp_amt)));
+ drawBorder(imagep, gFocusMgr.getFocusColor() % alpha, llround(lerp(1.f, 3.f, lerp_amt)));
}
if (use_glow_effect)
@@ -685,21 +686,21 @@ void LLButton::draw()
LLColor4 disabled_color = mFadeWhenDisabled ? mDisabledImageColor.get() % 0.5f : mDisabledImageColor.get();
if ( mScaleImage)
{
- imagep->draw(getLocalRect(), enabled ? mImageColor.get() : disabled_color );
+ imagep->draw(getLocalRect(), (enabled ? mImageColor.get() : disabled_color) % alpha );
if (mCurGlowStrength > 0.01f)
{
gGL.setSceneBlendType(glow_type);
- imagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), glow_color % mCurGlowStrength);
+ imagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), glow_color % (mCurGlowStrength * alpha));
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
}
else
{
- imagep->draw(0, 0, enabled ? mImageColor.get() : disabled_color );
+ imagep->draw(0, 0, (enabled ? mImageColor.get() : disabled_color) % alpha );
if (mCurGlowStrength > 0.01f)
{
gGL.setSceneBlendType(glow_type);
- imagep->drawSolid(0, 0, glow_color % mCurGlowStrength);
+ imagep->drawSolid(0, 0, glow_color % (mCurGlowStrength * alpha));
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
}
@@ -709,7 +710,7 @@ void LLButton::draw()
// no image
lldebugs << "No image for button " << getName() << llendl;
// draw it in pink so we can find it
- gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4::pink1, FALSE);
+ gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4::pink1 % alpha, FALSE);
}
// let overlay image and text play well together
@@ -744,6 +745,7 @@ void LLButton::draw()
{
overlay_color.mV[VALPHA] = 0.5f;
}
+ overlay_color.mV[VALPHA] *= alpha;
switch(mImageOverlayAlignment)
{
@@ -815,7 +817,7 @@ void LLButton::draw()
// Due to U32_MAX is equal to S32 -1 value I have rest this value for non-ellipses mode.
// Not sure if it is really needed. Probably S32_MAX should be always passed as max_chars.
mGLFont->render(label, 0, (F32)x, (F32)(LLBUTTON_V_PAD + y_offset),
- label_color,
+ label_color % alpha,
mHAlign, LLFontGL::BOTTOM,
LLFontGL::NORMAL,
mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NO_SHADOW,
@@ -956,17 +958,6 @@ void LLButton::setColor(const LLColor4& color)
setImageColor(color);
}
-void LLButton::setAlpha(F32 alpha)
-{
- LLColor4 temp = mImageColor.get();
- temp.setAlpha(alpha);
- mImageColor.set(temp);
-
- temp = mDisabledImageColor.get();
- temp.setAlpha(alpha * 0.5f);
- mDisabledImageColor.set(temp);
-}
-
void LLButton::setImageDisabled(LLPointer<LLUIImage> image)
{
mImageDisabled = image;
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index e51cd443fa..06e1dac914 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -191,7 +191,6 @@ public:
void setImageColor(const std::string& color_control);
void setImageColor(const LLColor4& c);
/*virtual*/ void setColor(const LLColor4& c);
- /*virtual*/ void setAlpha(F32 alpha);
void setImages(const std::string &image_name, const std::string &selected_name);
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index ac56d15d1b..ef0d4c1c03 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -55,6 +55,7 @@
#include "lllineeditor.h"
#include "v2math.h"
#include "lluictrlfactory.h"
+#include "lltooltip.h"
// Globals
S32 LLCOMBOBOX_HEIGHT = 0;
@@ -704,7 +705,7 @@ void LLComboBox::onItemSelected(const LLSD& data)
}
}
-BOOL LLComboBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
+BOOL LLComboBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
{
std::string tool_tip;
@@ -713,25 +714,17 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_re
return TRUE;
}
- if (LLUI::sShowXUINames)
+ tool_tip = getToolTip();
+ if (tool_tip.empty())
{
- tool_tip = getShowNamesToolTip();
- }
- else
- {
- tool_tip = getToolTip();
- if (tool_tip.empty())
- {
- tool_tip = getSelectedItemLabel();
- }
+ tool_tip = getSelectedItemLabel();
}
if( !tool_tip.empty() )
{
- msg = tool_tip;
-
- // Convert rect local to screen coordinates
- *sticky_rect_screen = calcScreenRect();
+ LLToolTipMgr::instance().show(LLToolTipParams()
+ .message(tool_tip)
+ .sticky_rect(calcScreenRect()));
}
return TRUE;
}
diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
index 4becda195f..018d472d62 100644
--- a/indra/llui/llcombobox.h
+++ b/indra/llui/llcombobox.h
@@ -112,7 +112,7 @@ public:
// LLView interface
virtual void onFocusLost();
- virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect);
+ virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect);
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index ca3829e1bd..c027b59c71 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -218,9 +218,6 @@ LLFloater::Params::Params()
close_callback("close_callback"),
can_dock("can_dock", false)
{
- name = "floater";
- // defaults that differ from LLPanel:
- background_visible = true;
visible = false;
}
@@ -241,41 +238,39 @@ void LLFloater::initClass()
}
}
+// defaults for floater param block pulled from widgets/floater.xml
+static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(&typeid(LLFloater::Params), "floater");
+
LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
- : LLPanel(),
- mDragHandle(NULL),
- mTitle(p.title),
- mShortTitle(p.short_title),
- mSingleInstance(p.single_instance),
- mKey(key),
- mAutoTile(p.auto_tile),
- mCanTearOff(p.can_tear_off),
- mCanMinimize(p.can_minimize),
- mCanClose(p.can_close),
- mDragOnLeft(p.can_drag_on_left),
- mResizable(p.can_resize),
- mMinWidth(p.min_width),
- mMinHeight(p.min_height),
- mMinimized(FALSE),
- mForeground(FALSE),
- mFirstLook(TRUE),
- mEditing(FALSE),
- mButtonScale(1.0f),
- mAutoFocus(TRUE), // automatically take focus when opened
- mCanDock(false),
- mDocked(false),
- mHasBeenDraggedWhileMinimized(FALSE),
- mPreviousMinimizedBottom(0),
- mPreviousMinimizedLeft(0),
- mNotificationContext(NULL)
-{
- static LLUIColor default_background_color = LLUIColorTable::instance().getColor("FloaterDefaultBackgroundColor");
- static LLUIColor focus_background_color = LLUIColorTable::instance().getColor("FloaterFocusBackgroundColor");
-
+: LLPanel(),
+ mDragHandle(NULL),
+ mTitle(p.title),
+ mShortTitle(p.short_title),
+ mSingleInstance(p.single_instance),
+ mKey(key),
+ mAutoTile(p.auto_tile),
+ mCanTearOff(p.can_tear_off),
+ mCanMinimize(p.can_minimize),
+ mCanClose(p.can_close),
+ mDragOnLeft(p.can_drag_on_left),
+ mResizable(p.can_resize),
+ mMinWidth(p.min_width),
+ mMinHeight(p.min_height),
+ mMinimized(FALSE),
+ mForeground(FALSE),
+ mFirstLook(TRUE),
+ mEditing(FALSE),
+ mButtonScale(1.0f),
+ mAutoFocus(TRUE), // automatically take focus when opened
+ mCanDock(false),
+ mDocked(false),
+ mHasBeenDraggedWhileMinimized(FALSE),
+ mPreviousMinimizedBottom(0),
+ mPreviousMinimizedLeft(0),
+ mNotificationContext(NULL)
+{
mHandle.bind(this);
mNotificationContext = new LLFloaterNotificationContext(getHandle());
- mBgColorAlpha = default_background_color;
- mBgColorOpaque = focus_background_color;
// Clicks stop here.
setMouseOpaque(TRUE);
@@ -779,11 +774,6 @@ void LLFloater::applyRectControl()
void LLFloater::applyTitle()
{
- if (gNoRender)
- {
- return;
- }
-
if (!mDragHandle)
{
return;
@@ -1546,6 +1536,7 @@ void LLFloater::onClickClose( LLFloater* self )
// virtual
void LLFloater::draw()
{
+ F32 alpha = getDrawContext().mAlpha;
// draw background
if( isBackgroundVisible() )
{
@@ -1565,27 +1556,29 @@ void LLFloater::draw()
shadow_color.mV[VALPHA] *= 0.5f;
}
gl_drop_shadow(left, top, right, bottom,
- shadow_color,
+ shadow_color % alpha,
llround(shadow_offset));
// No transparent windows in simple UI
if (isBackgroundOpaque())
{
- gl_rect_2d( left, top, right, bottom, mBgColorOpaque );
+ gl_rect_2d( left, top, right, bottom, getBackgroundColor() % alpha );
}
else
{
- gl_rect_2d( left, top, right, bottom, mBgColorAlpha );
+ gl_rect_2d( left, top, right, bottom, getTransparentColor() % alpha );
}
- if(gFocusMgr.childHasKeyboardFocus(this) && !getIsChrome() && !getCurrentTitle().empty())
+ if(hasFocus()
+ && !getIsChrome()
+ && !getCurrentTitle().empty())
{
static LLUIColor titlebar_focus_color = LLUIColorTable::instance().getColor("TitleBarFocusColor");
// draw highlight on title bar to indicate focus. RDW
const LLFontGL* font = LLFontGL::getFontSansSerif();
LLRect r = getRect();
gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - (S32)font->getLineHeight() - 1,
- titlebar_focus_color, 0, TRUE);
+ titlebar_focus_color % alpha, 0, TRUE);
}
}
@@ -1643,7 +1636,7 @@ void LLFloater::draw()
static LLUIColor unfocus_border_color = LLUIColorTable::instance().getColor("FloaterUnfocusBorderColor");
LLUI::setLineWidth(1.5f);
LLColor4 outlineColor = gFocusMgr.childHasKeyboardFocus(this) ? focus_border_color : unfocus_border_color;
- gl_rect_2d_offset_local(0, getRect().getHeight() + 1, getRect().getWidth() + 1, 0, outlineColor, -LLPANEL_BORDER_WIDTH, FALSE);
+ gl_rect_2d_offset_local(0, getRect().getHeight() + 1, getRect().getWidth() + 1, 0, outlineColor % alpha, -LLPANEL_BORDER_WIDTH, FALSE);
LLUI::setLineWidth(1.f);
}
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index ee066317e0..513f6a6918 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -373,9 +373,6 @@ private:
S32 mPreviousMinimizedBottom;
S32 mPreviousMinimizedLeft;
- LLColor4 mBgColorAlpha;
- LLColor4 mBgColorOpaque;
-
LLFloaterNotificationContext* mNotificationContext;
LLRootHandle<LLFloater> mHandle;
};
diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp
index 673c742e7a..0330a2b374 100644
--- a/indra/llui/lliconctrl.cpp
+++ b/indra/llui/lliconctrl.cpp
@@ -74,20 +74,12 @@ void LLIconCtrl::draw()
{
if( mImagep.notNull() )
{
- mImagep->draw(getLocalRect(), mColor.get() );
+ mImagep->draw(getLocalRect(), mColor.get() % getDrawContext().mAlpha );
}
LLUICtrl::draw();
}
-// virtual
-void LLIconCtrl::setAlpha(F32 alpha)
-{
- LLColor4 temp = mColor.get();
- temp.setAlpha(alpha);
- mColor.set(temp);
-}
-
// virtual
// value might be a string or a UUID
void LLIconCtrl::setValue(const LLSD& value )
diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h
index aceb70b9d5..ff25b0d53e 100644
--- a/indra/llui/lliconctrl.h
+++ b/indra/llui/lliconctrl.h
@@ -71,8 +71,6 @@ public:
std::string getImageName() const;
- /*virtual*/ void setAlpha(F32 alpha);
-
void setColor(const LLColor4& color) { mColor = color; }
private:
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index f98edec1f3..2d582c0568 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -35,6 +35,7 @@
#include "linden_common.h"
#include "lllayoutstack.h"
+#include "lllocalcliprect.h"
#include "llresizebar.h"
#include "llcriticaldamp.h"
@@ -297,6 +298,7 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr o
FALSE, output_child);
LLPanel::Params p;
+ p.mouse_opaque(false);
LLPanel* panelp = LLUICtrlFactory::create<LLPanel>(p);
LLView* new_child = LLUICtrlFactory::getInstance()->createFromXML(child_node, panelp, LLStringUtil::null, LLPanel::child_registry_t::instance(), output_child);
if (new_child)
diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp
new file mode 100644
index 0000000000..058b6ae178
--- /dev/null
+++ b/indra/llui/lllocalcliprect.cpp
@@ -0,0 +1,143 @@
+/**
+* @file lllocalcliprect.cpp
+*
+* $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$
+*/
+#include "linden_common.h"
+
+#include "lllocalcliprect.h"
+
+#include "llfontgl.h"
+#include "llgl.h"
+#include "llui.h"
+
+#include <stack>
+
+//---------------------------------------------------------------------------
+// LLScreenClipRect
+// implementation class in screen space
+//---------------------------------------------------------------------------
+class LLScreenClipRect
+{
+public:
+ LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE);
+ virtual ~LLScreenClipRect();
+
+private:
+ static void pushClipRect(const LLRect& rect);
+ static void popClipRect();
+ static void updateScissorRegion();
+
+private:
+ LLGLState mScissorState;
+ BOOL mEnabled;
+
+ static std::stack<LLRect> sClipRectStack;
+};
+
+/*static*/ std::stack<LLRect> LLScreenClipRect::sClipRectStack;
+
+
+LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled)
+: mScissorState(GL_SCISSOR_TEST),
+ mEnabled(enabled)
+{
+ if (mEnabled)
+ {
+ pushClipRect(rect);
+ }
+ mScissorState.setEnabled(!sClipRectStack.empty());
+ updateScissorRegion();
+}
+
+LLScreenClipRect::~LLScreenClipRect()
+{
+ if (mEnabled)
+ {
+ popClipRect();
+ }
+ updateScissorRegion();
+}
+
+//static
+void LLScreenClipRect::pushClipRect(const LLRect& rect)
+{
+ LLRect combined_clip_rect = rect;
+ if (!sClipRectStack.empty())
+ {
+ LLRect top = sClipRectStack.top();
+ combined_clip_rect.intersectWith(top);
+
+ if(combined_clip_rect.isEmpty())
+ {
+ // avoid artifacts where zero area rects show up as lines
+ combined_clip_rect = LLRect::null;
+ }
+ }
+ sClipRectStack.push(combined_clip_rect);
+}
+
+//static
+void LLScreenClipRect::popClipRect()
+{
+ sClipRectStack.pop();
+}
+
+//static
+void LLScreenClipRect::updateScissorRegion()
+{
+ if (sClipRectStack.empty()) return;
+
+ LLRect rect = sClipRectStack.top();
+ stop_glerror();
+ S32 x,y,w,h;
+ x = llfloor(rect.mLeft * LLUI::sGLScaleFactor.mV[VX]);
+ y = llfloor(rect.mBottom * LLUI::sGLScaleFactor.mV[VY]);
+ w = llmax(0, llceil(rect.getWidth() * LLUI::sGLScaleFactor.mV[VX])) + 1;
+ h = llmax(0, llceil(rect.getHeight() * LLUI::sGLScaleFactor.mV[VY])) + 1;
+ glScissor( x,y,w,h );
+ stop_glerror();
+}
+
+//---------------------------------------------------------------------------
+// LLLocalClipRect
+//---------------------------------------------------------------------------
+LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */)
+{
+ LLRect screen(rect.mLeft + LLFontGL::sCurOrigin.mX,
+ rect.mTop + LLFontGL::sCurOrigin.mY,
+ rect.mRight + LLFontGL::sCurOrigin.mX,
+ rect.mBottom + LLFontGL::sCurOrigin.mY);
+ mScreenClipRect = new LLScreenClipRect(screen, enabled);
+}
+
+LLLocalClipRect::~LLLocalClipRect()
+{
+ delete mScreenClipRect;
+ mScreenClipRect = NULL;
+}
diff --git a/indra/llui/lllocalcliprect.h b/indra/llui/lllocalcliprect.h
new file mode 100644
index 0000000000..cd0c55ca72
--- /dev/null
+++ b/indra/llui/lllocalcliprect.h
@@ -0,0 +1,53 @@
+/**
+* @file lllocalcliprect.h
+*
+* $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 LLLOCALCLIPRECT_H
+#define LLLOCALCLIPRECT_H
+
+#include "llrect.h" // can't forward declare, it's templated
+
+// Clip rendering to a specific rectangle using GL scissor
+// Just create one of these on the stack:
+// {
+// LLLocalClipRect(rect);
+// draw();
+// }
+class LLLocalClipRect
+{
+public:
+ LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE);
+ ~LLLocalClipRect();
+
+private:
+ // implementation class
+ class LLScreenClipRect* mScreenClipRect;
+};
+
+#endif
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index d6dfe6c198..2bc4f009cc 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -2929,7 +2929,7 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
// If the mouse doesn't move, the menu will stay open ala the Mac.
// See also LLContextMenu::show()
S32 mouse_x, mouse_y;
- LLUI::getCursorPositionLocal(menu->getParent(), &mouse_x, &mouse_y);
+ LLUI::getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y);
LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y);
const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect();
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index c81be6086a..26136e0a23 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -91,8 +91,8 @@ LLPanel::Params::Params()
LLPanel::LLPanel(const LLPanel::Params& p)
: LLUICtrl(p),
- mBgColorAlpha(p.bg_alpha_color().get()),
- mBgColorOpaque(p.bg_opaque_color().get()),
+ mBgColorAlpha(p.bg_alpha_color()),
+ mBgColorOpaque(p.bg_opaque_color()),
mBgVisible(p.background_visible),
mBgOpaque(p.background_opaque),
mDefaultBtn(NULL),
@@ -100,7 +100,7 @@ LLPanel::LLPanel(const LLPanel::Params& p)
mLabel(p.label),
mCommitCallbackRegistrar(false),
mEnableCallbackRegistrar(false),
- mXMLFilename("")
+ mXMLFilename(p.filename)
{
setIsChrome(FALSE);
@@ -171,6 +171,8 @@ void LLPanel::setCtrlsEnabled( BOOL b )
void LLPanel::draw()
{
+ F32 alpha = getDrawContext().mAlpha;
+
// draw background
if( mBgVisible )
{
@@ -182,11 +184,11 @@ void LLPanel::draw()
if (mBgOpaque )
{
- gl_rect_2d( left, top, right, bottom, mBgColorOpaque );
+ gl_rect_2d( left, top, right, bottom, mBgColorOpaque.get() % alpha);
}
else
{
- gl_rect_2d( left, top, right, bottom, mBgColorAlpha );
+ gl_rect_2d( left, top, right, bottom, mBgColorAlpha.get() % alpha);
}
}
@@ -195,12 +197,6 @@ void LLPanel::draw()
LLView::draw();
}
-/*virtual*/
-void LLPanel::setAlpha(F32 alpha)
-{
- mBgColorOpaque.setAlpha(alpha);
-}
-
void LLPanel::updateDefaultBtn()
{
if( mDefaultBtn)
@@ -403,6 +399,8 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
setVisible(p.visible);
setEnabled(p.enabled);
+ setSoundFlags(p.sound_flags);
+
// control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible
LLUICtrl::initFromParams(p);
@@ -709,14 +707,6 @@ void LLPanel::childSetColor(const std::string& id, const LLColor4& color)
child->setColor(color);
}
}
-void LLPanel::childSetAlpha(const std::string& id, F32 alpha)
-{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setAlpha(alpha);
- }
-}
LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const std::string& id) const
{
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index 3f1d1fdc5d..81b5b68f05 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -114,8 +114,6 @@ public:
// From LLFocusableElement
/*virtual*/ void setFocus( BOOL b );
- virtual void setAlpha(F32 alpha);
-
// New virtuals
virtual void refresh(); // called in setFocus()
@@ -190,7 +188,6 @@ public:
void childSetValidate(const std::string& id, boost::function<bool (const LLSD& data)> cb );
void childSetColor(const std::string& id, const LLColor4& color);
- void childSetAlpha(const std::string& id, F32 alpha);
LLCtrlSelectionInterface* childGetSelectionInterface(const std::string& id) const;
LLCtrlListInterface* childGetListInterface(const std::string& id) const;
@@ -236,6 +233,7 @@ public:
virtual void onOpen(const LLSD& key) {}
void setXMLFilename(std::string filename) { mXMLFilename = filename; };
+ std::string getXMLFilename() { return mXMLFilename; };
protected:
// Override to set not found list
@@ -247,13 +245,8 @@ protected:
commit_signal_t mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD()
private:
- // Unified error reporting for the child* functions
- typedef std::set<std::string> expected_members_list_t;
- mutable expected_members_list_t mExpectedMembers;
- mutable expected_members_list_t mNewExpectedMembers;
-
- LLColor4 mBgColorAlpha;
- LLColor4 mBgColorOpaque;
+ LLUIColor mBgColorAlpha;
+ LLUIColor mBgColorOpaque;
BOOL mBgVisible;
BOOL mBgOpaque;
LLViewBorder* mBorder;
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index b46915b379..172c4a9c65 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -484,7 +484,7 @@ void LLScrollbar::draw()
S32 local_mouse_x;
S32 local_mouse_y;
- LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y);
+ LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y);
BOOL other_captor = gFocusMgr.getMouseCapture() && gFocusMgr.getMouseCapture() != this;
BOOL hovered = getEnabled() && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y));
if (hovered)
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 556ff80991..30a042cff1 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -37,6 +37,7 @@
#include "llrender.h"
#include "llcontainerview.h"
+#include "lllocalcliprect.h"
// #include "llfolderview.h"
#include "llscrollingpanellist.h"
#include "llscrollbar.h"
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 36a3b007b6..483106e857 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -44,6 +44,8 @@
#include "llcheckboxctrl.h"
#include "llclipboard.h"
#include "llfocusmgr.h"
+#include "llgl.h" // LLGLSUIDefault()
+#include "lllocalcliprect.h"
//#include "llrender.h"
#include "llresmgr.h"
#include "llscrollbar.h"
@@ -60,6 +62,7 @@
#include "llcachename.h"
#include "llmenugl.h"
#include "llurlaction.h"
+#include "lltooltip.h"
#include <boost/bind.hpp>
@@ -1522,7 +1525,7 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks)
return handled;
}
-BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
+BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
{
S32 column_index = getColumnIndexFromOffset(x);
LLScrollListColumn* columnp = getColumn(column_index);
@@ -1545,8 +1548,11 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti
LLRect cell_rect;
cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->getWidth(), mLineHeight);
// Convert rect local to screen coordinates
- localRectToScreen(cell_rect, sticky_rect_screen);
- msg = hit_cell->getValue().asString();
+ LLRect sticky_rect;
+ localRectToScreen(cell_rect, &sticky_rect);
+ LLToolTipMgr::instance().show(LLToolTipParams()
+ .message(hit_cell->getValue().asString())
+ .sticky_rect(sticky_rect));
}
handled = TRUE;
}
@@ -1555,8 +1561,7 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti
LLScrollColumnHeader* headerp = columnp->mHeader;
if (headerp && !handled)
{
- headerp->handleToolTip(x, y, msg, sticky_rect_screen);
- handled = !msg.empty();
+ handled = headerp->handleToolTip(x, y, msg, sticky_rect_screen);
}
return handled;
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 5c18f85160..bbf8e86660 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -286,7 +286,7 @@ public:
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
- /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect);
+ /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect);
/*virtual*/ void setEnabled(BOOL enabled);
/*virtual*/ void setFocus( BOOL b );
/*virtual*/ void onFocusReceived();
diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 1b0f3c9885..4bb45a3065 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -90,15 +90,7 @@ void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool
mNameStack.clear();
setParseSilently(silent);
- // must have named elements at top level to submit for parsing
- if (sd.isMap())
- {
- readSDValues(sd, block);
- }
- else
- {
- parserWarning("Top level map required for LLSD->Block conversion");
- }
+ readSDValues(sd, block);
}
void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block)
diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp
index 1c394a71dd..07b6895378 100644
--- a/indra/llui/llslider.cpp
+++ b/indra/llui/llslider.cpp
@@ -239,6 +239,8 @@ BOOL LLSlider::handleKeyHere(KEY key, MASK mask)
void LLSlider::draw()
{
+ F32 alpha = getDrawContext().mAlpha;
+
// since thumb image might still be decoding, need thumb to accomodate image size
updateThumbRect();
@@ -253,14 +255,14 @@ void LLSlider::draw()
getRect().getWidth() - mThumbImage->getWidth() / 2,
getLocalRect().getCenterY() - (mTrackImage->getHeight() / 2) );
LLRect highlight_rect(track_rect.mLeft, track_rect.mTop, mThumbRect.getCenterX(), track_rect.mBottom);
- mTrackImage->draw(track_rect);
- mTrackHighlightImage->draw(highlight_rect);
+ mTrackImage->draw(track_rect, LLColor4::white % alpha);
+ mTrackHighlightImage->draw(highlight_rect, LLColor4::white % alpha);
// Thumb
if (hasFocus())
{
// Draw focus highlighting.
- mThumbImage->drawBorder(mThumbRect, gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
+ mThumbImage->drawBorder(mThumbRect, gFocusMgr.getFocusColor() % alpha, gFocusMgr.getFocusFlashWidth());
}
if( hasMouseCapture() ) // currently clicking on slider
@@ -268,25 +270,25 @@ void LLSlider::draw()
// Show ghost where thumb was before dragging began.
if (mThumbImage.notNull())
{
- mThumbImage->draw(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
+ mThumbImage->draw(mDragStartThumbRect, mThumbCenterColor.get() % (0.3f * alpha));
}
if (mThumbImagePressed.notNull())
{
- mThumbImagePressed->draw(mThumbRect, mThumbOutlineColor);
+ mThumbImagePressed->draw(mThumbRect, mThumbOutlineColor % alpha);
}
}
else if (!isInEnabledChain())
{
if (mThumbImageDisabled.notNull())
{
- mThumbImageDisabled->draw(mThumbRect, mThumbCenterColor);
+ mThumbImageDisabled->draw(mThumbRect, mThumbCenterColor % alpha);
}
}
else
{
if (mThumbImage.notNull())
{
- mThumbImage->draw(mThumbRect, mThumbCenterColor);
+ mThumbImage->draw(mThumbRect, mThumbCenterColor % alpha);
}
}
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index e379954b4f..cabd0be522 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -31,9 +31,12 @@
*/
#include "linden_common.h"
+
#include "lltabcontainer.h"
+
#include "llfocusmgr.h"
#include "llbutton.h"
+#include "lllocalcliprect.h"
#include "llrect.h"
#include "llresizehandle.h"
#include "lltextbox.h"
@@ -590,7 +593,7 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask )
}
// virtual
-BOOL LLTabContainer::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rect )
+BOOL LLTabContainer::handleToolTip( S32 x, S32 y, std::string& msg, LLRect& sticky_rect )
{
static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
BOOL handled = LLPanel::handleToolTip( x, y, msg, sticky_rect );
@@ -731,7 +734,7 @@ BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDrag
{
BOOL has_scroll_arrows = (getMaxScrollPos() > 0);
- if( mDragAndDropDelayTimer.getElapsedTimeF32() > SCROLL_DELAY_TIME )
+ if( mDragAndDropDelayTimer.getStarted() && mDragAndDropDelayTimer.getElapsedTimeF32() > SCROLL_DELAY_TIME )
{
if (has_scroll_arrows)
{
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index ebe76af966..89a0346896 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -99,7 +99,7 @@ public:
/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
/*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
/*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask );
- /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect );
+ /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect );
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType type, void* cargo_data,
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 038ea2188f..cb60b4fe36 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -38,6 +38,7 @@
#include "llview.h"
#include "llwindow.h"
#include "llmenugl.h"
+#include "lltooltip.h"
#include "lluictrl.h"
#include "llurlaction.h"
#include "llurlregistry.h"
@@ -402,18 +403,23 @@ BOOL LLTextBase::handleRightMouseDownOverUrl(LLView *view, S32 x, S32 y)
return FALSE;
}
-BOOL LLTextBase::handleToolTipForUrl(LLView *view, S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
+BOOL LLTextBase::handleToolTipForUrl(LLView *view, S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
{
+ std::string tooltip_msg;
const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
- if (cur_segment && cur_segment->getToolTip( msg ) && view)
+ if (cur_segment && cur_segment->getToolTip( tooltip_msg ) && view)
{
// Use a slop area around the cursor
const S32 SLOP = 8;
// Convert rect local to screen coordinates
- view->localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect_screen->mLeft),
- &(sticky_rect_screen->mBottom));
- sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP;
- sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP;
+ view->localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect_screen.mLeft),
+ &(sticky_rect_screen.mBottom));
+ sticky_rect_screen.mRight = sticky_rect_screen.mLeft + 2 * SLOP;
+ sticky_rect_screen.mTop = sticky_rect_screen.mBottom + 2 * SLOP;
+
+ LLToolTipMgr::instance().show(LLToolTipParams()
+ .message(tooltip_msg)
+ .sticky_rect(sticky_rect_screen));
}
return TRUE;
}
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 27b88761a8..82b9f6a43f 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -90,7 +90,7 @@ protected:
BOOL handleHoverOverUrl(S32 x, S32 y);
BOOL handleMouseUpOverUrl(S32 x, S32 y);
BOOL handleRightMouseDownOverUrl(LLView *view, S32 x, S32 y);
- BOOL handleToolTipForUrl(LLView *view, S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen);
+ BOOL handleToolTipForUrl(LLView *view, S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen);
// pure virtuals that have to be implemented by any subclasses
virtual S32 getLineCount() const = 0;
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 30bf182deb..810626268f 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -52,7 +52,6 @@ LLTextBox::Params::Params()
drop_shadow_visible("drop_shadow_visible"),
disabled_color("disabled_color"),
background_color("background_color"),
- border_color("border_color"),
v_pad("v_pad", 0),
h_pad("h_pad", 0),
line_spacing("line_spacing", 0),
@@ -75,7 +74,6 @@ LLTextBox::LLTextBox(const LLTextBox::Params& p)
mTextColor(p.text_color()),
mDisabledColor(p.disabled_color()),
mBackgroundColor(p.background_color()),
- mBorderColor(p.border_color()),
mHAlign(p.font_halign),
mLineSpacing(p.line_spacing),
mDidWordWrap(FALSE)
@@ -161,7 +159,7 @@ BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask)
return LLView::handleHover(x,y,mask);
}
-BOOL LLTextBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
+BOOL LLTextBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
{
return handleToolTipForUrl(this, x, y, msg, sticky_rect_screen);
}
@@ -387,6 +385,8 @@ BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text
void LLTextBox::draw()
{
+ F32 alpha = getDrawContext().mAlpha;
+
if (mBorderVisible)
{
gl_rect_2d_offset_local(getLocalRect(), 2, FALSE);
@@ -397,13 +397,13 @@ void LLTextBox::draw()
static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow");
static LLUICachedControl<S32> drop_shadow_tooltip ("DropShadowTooltip", 0);
gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
- color_drop_shadow, drop_shadow_tooltip);
+ color_drop_shadow % alpha, drop_shadow_tooltip);
}
if (mBackgroundVisible)
{
LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 );
- gl_rect_2d( r, mBackgroundColor.get() );
+ gl_rect_2d( r, mBackgroundColor.get() % alpha );
}
S32 text_x = 0;
@@ -453,6 +453,7 @@ void LLTextBox::reshape(S32 width, S32 height, BOOL called_from_parent)
void LLTextBox::drawText( S32 x, S32 y, const LLWString &text, const LLColor4& color )
{
+ F32 alpha = getDrawContext().mAlpha;
if (mSegments.size() > 1)
{
// we have Urls (or other multi-styled segments)
@@ -461,7 +462,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLWString &text, const LLColor4& c
else if( mLineLengthList.empty() )
{
// simple case of 1 line of text in one style
- mDefaultFont->render(text, 0, (F32)x, (F32)y, color,
+ mDefaultFont->render(text, 0, (F32)x, (F32)y, color % alpha,
mHAlign, mVAlign,
0,
mShadowType,
@@ -475,7 +476,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLWString &text, const LLColor4& c
iter != mLineLengthList.end(); ++iter)
{
S32 line_length = *iter;
- mDefaultFont->render(text, cur_pos, (F32)x, (F32)y, color,
+ mDefaultFont->render(text, cur_pos, (F32)x, (F32)y, color % alpha,
mHAlign, mVAlign,
0,
mShadowType,
@@ -491,6 +492,9 @@ void LLTextBox::drawText( S32 x, S32 y, const LLWString &text, const LLColor4& c
void LLTextBox::reshapeToFitText()
{
+ // wrap remaining lines that did not fit on call to setWrappedText()
+ setLineLengths();
+
S32 width = getTextPixelWidth();
S32 height = getTextPixelHeight();
reshape( width + 2 * mHPad, height + 2 * mVPad );
@@ -665,6 +669,8 @@ bool LLTextBox::isClickable() const
void LLTextBox::drawTextSegments(S32 init_x, S32 init_y, const LLWString &text)
{
+ F32 alpha = getDrawContext().mAlpha;
+
const S32 text_len = text.length();
if (text_len <= 0)
{
@@ -729,6 +735,7 @@ void LLTextBox::drawTextSegments(S32 init_x, S32 init_y, const LLWString &text)
{
color = mDisabledColor.get();
}
+ color = color % alpha;
// render a single line worth for this segment
mDefaultFont->render(text, seg_start, text_x, text_y, color,
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index 940b820004..291d1dc517 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -66,8 +66,7 @@ public:
Optional<LLUIColor> text_color,
disabled_color,
- background_color,
- border_color;
+ background_color;
Optional<S32> v_pad,
h_pad,
@@ -90,12 +89,11 @@ public:
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen);
+ virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen);
void setColor( const LLColor4& c ) { mTextColor = c; }
void setDisabledColor( const LLColor4& c) { mDisabledColor = c; }
void setBackgroundColor( const LLColor4& c) { mBackgroundColor = c; }
- void setBorderColor( const LLColor4& c) { mBorderColor = c; }
void setText( const LLStringExplicit& text );
void setWrappedText(const LLStringExplicit& text, F32 max_width = -1.f); // -1 means use existing control width
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 51c259ff53..983777b747 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -38,6 +38,8 @@
#include "llfontfreetype.h" // for LLFontFreetype::FIRST_CHAR
#include "llfontgl.h"
+#include "llgl.h" // LLGLSUIDefault()
+#include "lllocalcliprect.h"
#include "llrender.h"
#include "llui.h"
#include "lluictrlfactory.h"
@@ -60,6 +62,7 @@
#include "llscrollcontainer.h"
#include "llpanel.h"
#include "llurlregistry.h"
+#include "lltooltip.h"
#include <queue>
#include "llcombobox.h"
@@ -1341,18 +1344,11 @@ void LLTextEditor::selectAll()
}
-BOOL LLTextEditor::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
+BOOL LLTextEditor::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
{
- for ( child_list_const_iter_t child_it = getChildList()->begin();
- child_it != getChildList()->end(); ++child_it)
+ if (childrenHandleToolTip(x, y, msg, sticky_rect_screen))
{
- LLView* viewp = *child_it;
- S32 local_x = x - viewp->getRect().mLeft;
- S32 local_y = y - viewp->getRect().mBottom;
- if( viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen ) )
- {
- return TRUE;
- }
+ return TRUE;
}
return handleToolTipForUrl(this, x, y, msg, sticky_rect_screen);
@@ -3193,7 +3189,7 @@ void LLTextEditor::draw()
mDocumentPanel->setBackgroundColor(bg_color);
- drawChildren();
+ LLView::draw();
drawBackground(); //overlays scrolling panel bg
drawLineNumbers();
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index d537751130..68b8f2c3b1 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -151,7 +151,7 @@ public:
virtual BOOL handleKeyHere(KEY key, MASK mask );
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
- virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect);
+ virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect);
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type, void *cargo_data,
EAcceptance *accept, std::string& tooltip_msg);
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
new file mode 100644
index 0000000000..5c017dabd7
--- /dev/null
+++ b/indra/llui/lltooltip.cpp
@@ -0,0 +1,445 @@
+/**
+ * @file lltooltip.cpp
+ * @brief LLToolTipMgr class implementation and related classes
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-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"
+
+// self include
+#include "lltooltip.h"
+
+// Library includes
+#include "llpanel.h"
+#include "lltextbox.h"
+#include "lliconctrl.h"
+#include "llui.h" // positionViewNearMouse()
+#include "llwindow.h"
+
+//
+// Constants
+//
+const F32 DELAY_BEFORE_SHOW_TIP = 0.35f;
+
+//
+// Local globals
+//
+
+LLToolTipView *gToolTipView = NULL;
+
+//
+// Member functions
+//
+
+LLToolTipView::LLToolTipView(const LLToolTipView::Params& p)
+: LLView(p)
+{
+}
+
+void LLToolTipView::draw()
+{
+ if (LLUI::getWindow()->isCursorHidden() )
+ {
+ LLToolTipMgr::instance().hideToolTips();
+ }
+
+ // do the usual thing
+ LLView::draw();
+}
+
+BOOL LLToolTipView::handleHover(S32 x, S32 y, MASK mask)
+{
+ static S32 last_x = x;
+ static S32 last_y = y;
+
+ LLToolTipMgr& tooltip_mgr = LLToolTipMgr::instance();
+
+ // hide existing tooltips when mouse moves out of sticky rect
+ if (tooltip_mgr.toolTipVisible()
+ && !tooltip_mgr.getStickyRect().pointInRect(x, y))
+ {
+ tooltip_mgr.hideToolTips();
+ }
+
+ // allow new tooltips whenever mouse moves
+ if (x != last_x && y != last_y)
+ {
+ tooltip_mgr.enableToolTips();
+ }
+
+ last_x = x;
+ last_y = y;
+ return LLView::handleHover(x, y, mask);
+}
+
+BOOL LLToolTipView::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLToolTipMgr::instance().hideToolTips();
+ return LLView::handleMouseDown(x, y, mask);
+}
+
+BOOL LLToolTipView::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLToolTipMgr::instance().hideToolTips();
+ return LLView::handleMiddleMouseDown(x, y, mask);
+}
+
+BOOL LLToolTipView::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLToolTipMgr::instance().hideToolTips();
+ return LLView::handleRightMouseDown(x, y, mask);
+}
+
+
+BOOL LLToolTipView::handleScrollWheel( S32 x, S32 y, S32 clicks )
+{
+ LLToolTipMgr::instance().hideToolTips();
+ return FALSE;
+}
+
+void LLToolTipView::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ LLToolTipMgr::instance().hideToolTips();
+}
+
+
+void LLToolTipView::drawStickyRect()
+{
+ gl_rect_2d(LLToolTipMgr::instance().getStickyRect(), LLColor4::white, false);
+}
+//
+// LLToolTip
+//
+class LLToolTip : public LLPanel
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ Mandatory<F32> visible_time;
+
+ Optional<LLToolTipParams::click_callback_t> click_callback;
+ Optional<LLUIImage*> image;
+
+ Params()
+ {
+ //use_bounding_rect = true;
+ }
+ };
+ /*virtual*/ void draw();
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
+
+ /*virtual*/ void setValue(const LLSD& value);
+ /*virtual*/ void setVisible(BOOL visible);
+
+ bool isFading() { return mFadeTimer.getStarted(); }
+
+ LLToolTip(const Params& p);
+
+private:
+ LLTextBox* mTextBox;
+ LLFrameTimer mFadeTimer;
+ F32 mVisibleTime;
+ bool mHasClickCallback;
+};
+
+static LLDefaultChildRegistry::Register<LLToolTip> r("tool_tip");
+
+const S32 TOOLTIP_PADDING = 4;
+
+LLToolTip::LLToolTip(const LLToolTip::Params& p)
+: LLPanel(p),
+ mVisibleTime(p.visible_time),
+ mHasClickCallback(p.click_callback.isProvided())
+{
+ LLTextBox::Params params;
+ params.text = "tip_text";
+ params.name = params.text;
+ // bake textbox padding into initial rect
+ params.rect = LLRect (TOOLTIP_PADDING, TOOLTIP_PADDING + 1, TOOLTIP_PADDING + 1, TOOLTIP_PADDING);
+ params.follows.flags = FOLLOWS_ALL;
+ params.h_pad = 4;
+ params.v_pad = 2;
+ params.mouse_opaque = false;
+ params.text_color = LLUIColorTable::instance().getColor( "ToolTipTextColor" );
+ params.bg_visible = false;
+ params.font.style = "NORMAL";
+ //params.border_drop_shadow_visible = true;
+ mTextBox = LLUICtrlFactory::create<LLTextBox> (params);
+ addChild(mTextBox);
+
+ if (p.image.isProvided())
+ {
+ LLIconCtrl::Params icon_params;
+ icon_params.name = "tooltip_icon";
+ LLRect icon_rect;
+ const S32 TOOLTIP_ICON_SIZE = 18;
+ icon_rect.setOriginAndSize(TOOLTIP_PADDING, TOOLTIP_PADDING, TOOLTIP_ICON_SIZE, TOOLTIP_ICON_SIZE);
+ icon_params.rect = icon_rect;
+ icon_params.follows.flags = FOLLOWS_LEFT | FOLLOWS_BOTTOM;
+ icon_params.image = p.image;
+ icon_params.mouse_opaque = false;
+ addChild(LLUICtrlFactory::create<LLIconCtrl>(icon_params));
+
+ // move text over to fit image in
+ mTextBox->translate(TOOLTIP_ICON_SIZE,0);
+ }
+
+ if (p.click_callback.isProvided())
+ {
+ setMouseUpCallback(boost::bind(p.click_callback()));
+ }
+}
+
+void LLToolTip::setValue(const LLSD& value)
+{
+ mTextBox->setWrappedText(value.asString());
+ mTextBox->reshapeToFitText();
+
+ // reshape tooltip panel to fit text box
+ LLRect tooltip_rect = calcBoundingRect();
+ tooltip_rect.mTop += TOOLTIP_PADDING;
+ tooltip_rect.mRight += TOOLTIP_PADDING;
+ tooltip_rect.mBottom = 0;
+ tooltip_rect.mLeft = 0;
+
+ setRect(tooltip_rect);
+}
+
+void LLToolTip::setVisible(BOOL visible)
+{
+ // fade out tooltip over time
+ if (!visible)
+ {
+ // don't actually change mVisible state, start fade out transition instead
+ if (!mFadeTimer.getStarted())
+ {
+ mFadeTimer.start();
+ }
+ }
+ else
+ {
+ mFadeTimer.stop();
+ LLPanel::setVisible(TRUE);
+ }
+}
+
+BOOL LLToolTip::handleHover(S32 x, S32 y, MASK mask)
+{
+ LLPanel::handleHover(x, y, mask);
+ if (mHasClickCallback)
+ {
+ getWindow()->setCursor(UI_CURSOR_HAND);
+ }
+ return TRUE;
+}
+
+void LLToolTip::draw()
+{
+ F32 alpha = 1.f;
+
+ if (LLUI::getMouseIdleTime() > mVisibleTime)
+ {
+ LLToolTipMgr::instance().hideToolTips();
+ }
+
+ if (mFadeTimer.getStarted())
+ {
+ F32 tool_tip_fade_time = LLUI::sSettingGroups["config"]->getF32("ToolTipFadeTime");
+ alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time, 1.f, 0.f);
+ if (alpha == 0.f)
+ {
+ // finished fading out, so hide ourselves
+ mFadeTimer.stop();
+ LLPanel::setVisible(false);
+ }
+ }
+
+ // draw tooltip contents with appropriate alpha
+ {
+ LLViewDrawContext context(alpha);
+ LLPanel::draw();
+ }
+}
+
+
+
+//
+// LLToolTipMgr
+//
+LLToolTipParams::LLToolTipParams()
+: pos("pos"),
+ message("message"),
+ delay_time("delay_time", LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" )),
+ visible_time("visible_time", LLUI::sSettingGroups["config"]->getF32( "ToolTipVisibleTime" )),
+ sticky_rect("sticky_rect"),
+ width("width", 200),
+ image("image")
+{}
+
+LLToolTipMgr::LLToolTipMgr()
+: mToolTip(NULL)
+{
+}
+
+LLToolTip* LLToolTipMgr::createToolTip(const LLToolTipParams& params)
+{
+ S32 mouse_x;
+ S32 mouse_y;
+ LLUI::getMousePositionLocal(gToolTipView->getParent(), &mouse_x, &mouse_y);
+
+
+ LLToolTip::Params tooltip_params;
+ tooltip_params.name = "tooltip";
+ tooltip_params.mouse_opaque = true;
+ tooltip_params.rect = LLRect (0, 1, 1, 0);
+ tooltip_params.bg_opaque_color = LLUIColorTable::instance().getColor( "ToolTipBgColor" );
+ tooltip_params.background_visible = true;
+ tooltip_params.visible_time = params.visible_time;
+ if (params.image.isProvided())
+ {
+ tooltip_params.image = params.image;
+ }
+ if (params.click_callback.isProvided())
+ {
+ tooltip_params.click_callback = params.click_callback;
+ }
+
+ LLToolTip* tooltip = LLUICtrlFactory::create<LLToolTip> (tooltip_params);
+
+ // make tooltip fixed width and tall enough to fit text
+ tooltip->reshape(params.width, 2000);
+ tooltip->setValue(params.message());
+ gToolTipView->addChild(tooltip);
+
+ if (params.pos.isProvided())
+ {
+ // try to spawn at requested position
+ LLUI::positionViewNearMouse(tooltip, params.pos.x, params.pos.y);
+ }
+ else
+ {
+ // just spawn at mouse location
+ LLUI::positionViewNearMouse(tooltip);
+ }
+
+ //...update "sticky" rect and tooltip position
+ if (params.sticky_rect.isProvided())
+ {
+ mToolTipStickyRect = params.sticky_rect;
+ }
+ else
+ {
+ // otherwise just use one pixel rect around mouse cursor
+ mToolTipStickyRect.setOriginAndSize(mouse_x, mouse_y, 1, 1);
+ }
+
+ if (params.click_callback.isProvided())
+ {
+ // keep tooltip up when we mouse over it
+ mToolTipStickyRect.unionWith(tooltip->getRect());
+ }
+
+ return tooltip;
+}
+
+
+void LLToolTipMgr::show(const std::string& msg)
+{
+ show(LLToolTipParams().message(msg));
+}
+
+void LLToolTipMgr::show(const LLToolTipParams& params)
+{
+ if (!params.validateBlock())
+ {
+ llwarns << "Could not display tooltip!" << llendl;
+ return;
+ }
+
+ bool tooltip_shown = mToolTip
+ && mToolTip->getVisible()
+ && !mToolTip->isFading();
+
+ // if tooltip contents change, hide existing tooltip
+ if (tooltip_shown && mLastToolTipMessage != params.message())
+ {
+ hideToolTips();
+ }
+
+ if (!mToolTipsBlocked // we haven't hit a key, moved the mouse, etc.
+ && LLUI::getMouseIdleTime() > params.delay_time // the mouse has been still long enough
+ && !tooltip_shown) // tooltip not visible
+ {
+ // create new tooltip at mouse cursor position
+ delete mToolTip;
+ mToolTip = createToolTip(params);
+
+ // remember this tooltip so we know when it changes
+ mLastToolTipMessage = params.message();
+ }
+}
+
+// allow new tooltips to be created, e.g. after mouse has moved
+void LLToolTipMgr::enableToolTips()
+{
+ mToolTipsBlocked = false;
+}
+
+void LLToolTipMgr::hideToolTips()
+{
+ mToolTipsBlocked = true;
+ if (mToolTip)
+ {
+ mToolTip->setVisible(FALSE);
+ }
+}
+
+bool LLToolTipMgr::toolTipVisible()
+{
+ return mToolTip ? mToolTip->getVisible() : false;
+}
+
+LLRect LLToolTipMgr::getToolTipRect()
+{
+ if (mToolTip && mToolTip->getVisible())
+ {
+ return mToolTip->getRect();
+ }
+ return LLRect();
+}
+
+
+LLRect LLToolTipMgr::getStickyRect()
+{
+ if (!mToolTip) return LLRect();
+
+ return mToolTip->isInVisibleChain() ? mToolTipStickyRect : LLRect();
+}
+
+// EOF
diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h
new file mode 100644
index 0000000000..fb7f942099
--- /dev/null
+++ b/indra/llui/lltooltip.h
@@ -0,0 +1,127 @@
+/**
+ * @file lltooltip.h
+ * @brief LLToolTipMgr class definition and related classes
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-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_LLTOOLTIP_H
+#define LL_LLTOOLTIP_H
+
+// Library includes
+#include "llsingleton.h"
+#include "llinitparam.h"
+#include "llview.h"
+
+//
+// Classes
+//
+class LLToolTipView : public LLView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Params()
+ {
+ mouse_opaque = false;
+ }
+ };
+ LLToolTipView(const LLToolTipView::Params&);
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
+
+ /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
+
+ void drawStickyRect();
+
+ /*virtual*/ void draw();
+};
+
+struct LLToolTipPosParams : public LLInitParam::Block<LLToolTipPosParams>
+{
+ Mandatory<S32> x,
+ y;
+ LLToolTipPosParams()
+ : x("x"),
+ y("y")
+ {}
+};
+
+struct LLToolTipParams : public LLInitParam::Block<LLToolTipParams>
+{
+ typedef boost::function<void(void)> click_callback_t;
+
+ Mandatory<std::string> message;
+
+ Optional<LLToolTipPosParams> pos;
+ Optional<F32> delay_time,
+ visible_time;
+ Optional<LLRect> sticky_rect;
+ Optional<S32> width;
+ Optional<LLUIImage*> image;
+
+ Optional<click_callback_t> click_callback;
+
+ LLToolTipParams();
+ LLToolTipParams(const std::string& message);
+};
+
+class LLToolTipMgr : public LLSingleton<LLToolTipMgr>
+{
+ LOG_CLASS(LLToolTipMgr);
+public:
+ LLToolTipMgr();
+ void show(const LLToolTipParams& params);
+ void show(const std::string& message);
+
+ void enableToolTips();
+ void hideToolTips();
+ bool toolTipVisible();
+ LLRect getToolTipRect();
+
+ LLRect getStickyRect();
+
+private:
+ class LLToolTip* createToolTip(const LLToolTipParams& params);
+
+ bool mToolTipsBlocked;
+ class LLToolTip* mToolTip;
+ std::string mLastToolTipMessage;
+ LLRect mToolTipStickyRect;
+};
+
+//
+// Globals
+//
+
+extern LLToolTipView *gToolTipView;
+
+#endif
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 1d62ed93f9..950eaf2ea7 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -44,6 +44,7 @@
#include "llrect.h"
#include "lldir.h"
#include "llfontgl.h"
+#include "llgl.h"
// Project includes
#include "llcontrol.h"
@@ -80,10 +81,9 @@ std::list<std::string> gUntranslated;
/*static*/ LLWindow* LLUI::sWindow = NULL;
/*static*/ LLHtmlHelp* LLUI::sHtmlHelp = NULL;
/*static*/ LLView* LLUI::sRootView = NULL;
-/*static*/ BOOL LLUI::sShowXUINames = FALSE;
-/*static*/ std::stack<LLRect> LLScreenClipRect::sClipRectStack;
/*static*/ std::vector<std::string> LLUI::sXUIPaths;
+/*static*/ LLFrameTimer LLUI::sMouseIdleTimer;
// register filtereditor here
static LLDefaultChildRegistry::Register<LLFilterEditor> register_filter_editor("filter_editor");
@@ -1561,12 +1561,6 @@ void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3
gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP);
}
-bool handleShowXUINamesChanged(const LLSD& newvalue)
-{
- LLUI::sShowXUINames = newvalue.asBoolean();
- return true;
-}
-
void LLUI::initClass(const settings_map_t& settings,
LLImageProviderInterface* image_provider,
LLUIAudioCallback audio_callback,
@@ -1588,10 +1582,6 @@ void LLUI::initClass(const settings_map_t& settings,
sWindow = NULL; // set later in startup
LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow");
- static LLUICachedControl<bool> show_xui_names ("ShowXUINames", false);
- LLUI::sShowXUINames = show_xui_names;
- LLUI::sSettingGroups["config"]->getControl("ShowXUINames")->getSignal()->connect(boost::bind(&handleShowXUINamesChanged, _2));
-
// Callbacks for associating controls with floater visibilty:
LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleFloaterInstance, _2));
LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Show", boost::bind(&LLFloaterReg::showFloaterInstance, _2));
@@ -1661,7 +1651,7 @@ void LLUI::setLineWidth(F32 width)
}
//static
-void LLUI::setCursorPositionScreen(S32 x, S32 y)
+void LLUI::setMousePositionScreen(S32 x, S32 y)
{
S32 screen_x, screen_y;
screen_x = llround((F32)x * sGLScaleFactor.mV[VX]);
@@ -1674,16 +1664,16 @@ void LLUI::setCursorPositionScreen(S32 x, S32 y)
}
//static
-void LLUI::setCursorPositionLocal(const LLView* viewp, S32 x, S32 y)
+void LLUI::setMousePositionLocal(const LLView* viewp, S32 x, S32 y)
{
S32 screen_x, screen_y;
viewp->localPointToScreen(x, y, &screen_x, &screen_y);
- setCursorPositionScreen(screen_x, screen_y);
+ setMousePositionScreen(screen_x, screen_y);
}
//static
-void LLUI::getCursorPositionLocal(const LLView* viewp, S32 *x, S32 *y)
+void LLUI::getMousePositionLocal(const LLView* viewp, S32 *x, S32 *y)
{
LLCoordWindow cursor_pos_window;
LLView::getWindow()->getCursorPosition(&cursor_pos_window);
@@ -1867,74 +1857,46 @@ LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
return *sSettingGroups["config"]; // default group
}
-LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled) : mScissorState(GL_SCISSOR_TEST), mEnabled(enabled)
+//static
+// spawn_x and spawn_y are top left corner of view in screen GL coordinates
+void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y)
{
- if (mEnabled)
- {
- pushClipRect(rect);
- }
- mScissorState.setEnabled(!sClipRectStack.empty());
- updateScissorRegion();
-}
+ const S32 CURSOR_HEIGHT = 22; // Approximate "normal" cursor size
+ const S32 CURSOR_WIDTH = 12;
-LLScreenClipRect::~LLScreenClipRect()
-{
- if (mEnabled)
- {
- popClipRect();
- }
- updateScissorRegion();
-}
+ LLView* parent = view->getParent();
-//static
-void LLScreenClipRect::pushClipRect(const LLRect& rect)
-{
- LLRect combined_clip_rect = rect;
- if (!sClipRectStack.empty())
- {
- LLRect top = sClipRectStack.top();
- combined_clip_rect.intersectWith(top);
+ S32 mouse_x;
+ S32 mouse_y;
+ LLUI::getMousePositionLocal(parent, &mouse_x, &mouse_y);
- if(combined_clip_rect.isEmpty())
- {
- // avoid artifacts where zero area rects show up as lines
- combined_clip_rect = LLRect::null;
- }
+ // If no spawn location provided, use mouse position
+ if (spawn_x == S32_MAX || spawn_y == S32_MAX)
+ {
+ spawn_x = mouse_x + CURSOR_WIDTH;
+ spawn_y = mouse_y - CURSOR_HEIGHT;
}
- sClipRectStack.push(combined_clip_rect);
-}
-//static
-void LLScreenClipRect::popClipRect()
-{
- sClipRectStack.pop();
-}
+ LLRect virtual_window_rect = parent->getLocalRect();
-//static
-void LLScreenClipRect::updateScissorRegion()
-{
- if (sClipRectStack.empty()) return;
+ LLRect mouse_rect;
+ const S32 MOUSE_CURSOR_PADDING = 5;
+ mouse_rect.setLeftTopAndSize(mouse_x - MOUSE_CURSOR_PADDING,
+ mouse_y + MOUSE_CURSOR_PADDING,
+ CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2,
+ CURSOR_HEIGHT + MOUSE_CURSOR_PADDING * 2);
- LLRect rect = sClipRectStack.top();
- stop_glerror();
- S32 x,y,w,h;
- x = llfloor(rect.mLeft * LLUI::sGLScaleFactor.mV[VX]);
- y = llfloor(rect.mBottom * LLUI::sGLScaleFactor.mV[VY]);
- w = llmax(0, llceil(rect.getWidth() * LLUI::sGLScaleFactor.mV[VX])) + 1;
- h = llmax(0, llceil(rect.getHeight() * LLUI::sGLScaleFactor.mV[VY])) + 1;
- glScissor( x,y,w,h );
- stop_glerror();
+ S32 local_x, local_y;
+ view->getParent()->screenPointToLocal(spawn_x, spawn_y, &local_x, &local_y);
+
+ // Start at spawn position (using left/top)
+ view->setOrigin( local_x, local_y - view->getRect().getHeight());
+ // Make sure we're onscreen and not overlapping the mouse
+ view->translateIntoRectWithExclusion( virtual_window_rect, mouse_rect, FALSE );
}
-LLLocalClipRect::LLLocalClipRect(const LLRect &rect, BOOL enabled)
-: LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX,
- rect.mTop + LLFontGL::sCurOrigin.mY,
- rect.mRight + LLFontGL::sCurOrigin.mX,
- rect.mBottom + LLFontGL::sCurOrigin.mY),
- enabled)
-{
-}
+// LLLocalClipRect and LLScreenClipRect moved to lllocalcliprect.h/cpp
namespace LLInitParam
{
@@ -2084,6 +2046,19 @@ namespace LLInitParam
return rect;
}
+ TypedParam<LLCoordGL>::TypedParam(BlockDescriptor& descriptor, const char* name, LLCoordGL value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
+ : super_t(descriptor, name, value, func, min_count, max_count),
+ x("x"),
+ y("y")
+ {
+ }
+
+ LLCoordGL TypedParam<LLCoordGL>::getValueFromBlock() const
+ {
+ return LLCoordGL(x, y);
+ }
+
+
void TypeValues<LLFontGL::HAlign>::declareValues()
{
declare("left", LLFontGL::LEFT);
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 1f9b0b2dbc..33338f30f9 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -39,8 +39,6 @@
#include "llrect.h"
#include "llcontrol.h"
#include "llcoord.h"
-#include "llgl.h" // *TODO: break this dependency
-#include <stack>
#include "lluiimage.h" // *TODO: break this dependency, need to add #include "lluiimage.h" to all widgets that hold an Optional<LLUIImage*> in their paramblocks
#include "llinitparam.h"
#include "llregistry.h"
@@ -50,6 +48,7 @@
#include "lllazyvalue.h"
#include "llhandle.h" // *TODO: remove this dependency, added as a
// convenience when LLHandle moved to llhandle.h
+#include "llframetimer.h"
// LLUIFactory
#include "llsd.h"
@@ -188,9 +187,9 @@ public:
static LLView* getRootView() { return sRootView; }
static void setRootView(LLView* view) { sRootView = view; }
static std::string locateSkin(const std::string& filename);
- static void setCursorPositionScreen(S32 x, S32 y);
- static void setCursorPositionLocal(const LLView* viewp, S32 x, S32 y);
- static void getCursorPositionLocal(const LLView* viewp, S32 *x, S32 *y);
+ static void setMousePositionScreen(S32 x, S32 y);
+ static void setMousePositionLocal(const LLView* viewp, S32 x, S32 y);
+ static void getMousePositionLocal(const LLView* viewp, S32 *x, S32 *y);
static void setScaleFactor(const LLVector2& scale_factor);
static void setLineWidth(F32 width);
static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id);
@@ -203,7 +202,16 @@ public:
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(); }
+ static void resetMouseIdleTimer() { sMouseIdleTimer.reset(); }
+ static LLWindow* getWindow() { return sWindow; }
+
+ // Ensures view does not overlap mouse cursor, but is inside
+ // the view's parent rectangle. Used for tooltips, inspectors.
+ // Optionally override the view's default X/Y, which are relative to the
+ // view's parent.
+ static void positionViewNearMouse(LLView* view, S32 spawn_x = S32_MAX, S32 spawn_y = S32_MAX);
+
//
// Data
//
@@ -211,38 +219,16 @@ public:
static LLUIAudioCallback sAudioCallback;
static LLVector2 sGLScaleFactor;
static LLWindow* sWindow;
- static BOOL sShowXUINames;
static LLHtmlHelp* sHtmlHelp;
static LLView* sRootView;
private:
static LLImageProviderInterface* sImageProvider;
static std::vector<std::string> sXUIPaths;
+ static LLFrameTimer sMouseIdleTimer;
};
-class LLScreenClipRect
-{
-public:
- LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE);
- virtual ~LLScreenClipRect();
-
-private:
- static void pushClipRect(const LLRect& rect);
- static void popClipRect();
- static void updateScissorRegion();
-
-private:
- LLGLState mScissorState;
- BOOL mEnabled;
-
- static std::stack<LLRect> sClipRectStack;
-};
-
-class LLLocalClipRect : public LLScreenClipRect
-{
-public:
- LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE);
-};
+// Moved LLLocalClipRect to lllocalcliprect.h
// Moved all LLHandle-related code to llhandle.h
@@ -406,10 +392,10 @@ namespace LLInitParam
{
typedef BlockValue<LLUIColor> super_t;
public:
- Optional<F32> red;
- Optional<F32> green;
- Optional<F32> blue;
- Optional<F32> alpha;
+ Optional<F32> red,
+ green,
+ blue,
+ alpha;
Optional<std::string> control;
TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
@@ -422,9 +408,9 @@ namespace LLInitParam
{
typedef BlockValue<const LLFontGL*> super_t;
public:
- Optional<std::string> name;
- Optional<std::string> size;
- Optional<std::string> style;
+ Optional<std::string> name,
+ size,
+ style;
TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
const LLFontGL* getValueFromBlock() const;
@@ -447,6 +433,19 @@ namespace LLInitParam
{
static void declareValues();
};
+
+ template<>
+ class TypedParam<LLCoordGL>
+ : public BlockValue<LLCoordGL>
+ {
+ typedef BlockValue<LLCoordGL> super_t;
+ public:
+ Optional<S32> x,
+ y;
+
+ TypedParam(BlockDescriptor& descriptor, const char* name, LLCoordGL value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
+ LLCoordGL getValueFromBlock() const;
+ };
}
#endif
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 1ab04054ff..28cdb1ac27 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -839,10 +839,6 @@ BOOL LLUICtrl::getTentative() const
void LLUICtrl::setColor(const LLColor4& color)
{ }
-// virtual
-void LLUICtrl::setAlpha(F32 alpha)
-{ }
-
namespace LLInitParam
{
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 5011adcfe9..4030230684 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -213,7 +213,6 @@ public:
virtual void onTabInto();
virtual void clear();
virtual void setColor(const LLColor4& color);
- virtual void setAlpha(F32 alpha);
BOOL focusNextItem(BOOL text_entry_only);
BOOL focusPrevItem(BOOL text_entry_only);
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 1161101f90..538e1ec492 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -200,10 +200,7 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen
floaterp->initFloaterXML(root, floaterp->getParent(), output_node);
- if (LLUI::sShowXUINames)
- {
- floaterp->setToolTip(filename);
- }
+ floaterp->setXMLFilename(filename);
floaterp->getCommitCallbackRegistrar().popScope();
floaterp->getEnableCallbackRegistrar().popScope();
@@ -276,10 +273,7 @@ BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename, L
panelp->getCommitCallbackRegistrar().popScope();
panelp->getEnableCallbackRegistrar().popScope();
- if (LLUI::sShowXUINames)
- {
- panelp->setToolTip(filename);
- }
+ panelp->setXMLFilename(filename);
if (!panelp->getFactoryMap().empty())
{
@@ -317,10 +311,6 @@ LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const
parent = mDummyPanel;
}
LLView *view = (*funcp)(node, parent, output_node);
- if (LLUI::sShowXUINames && view && !filename.empty())
- {
- view->setToolTip(filename);
- }
return view;
}
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 55d94b325f..46510804f8 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -49,6 +49,7 @@
#include "llwindow.h"
#include "v3color.h"
#include "lluictrlfactory.h"
+#include "lltooltip.h"
// for ui edit hack
#include "llbutton.h"
@@ -70,6 +71,8 @@ LLView* LLView::sPreviewClickedElement = NULL;
BOOL LLView::sDrawPreviewHighlights = FALSE;
S32 LLView::sLastLeftXML = S32_MIN;
S32 LLView::sLastBottomXML = S32_MIN;
+std::vector<LLViewDrawContext*> LLViewDrawContext::sDrawContextStack;
+
#if LL_DEBUG
BOOL LLView::sIsDrawing = FALSE;
@@ -662,86 +665,52 @@ void LLView::onMouseLeave(S32 x, S32 y, MASK mask)
}
-std::string LLView::getShowNamesToolTip()
+LLView* LLView::childrenHandleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
{
- LLView* view = getParent();
- std::string name;
- std::string tool_tip = mName;
-
- while (view)
+ LLView* handled_view = NULL;
+ for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
{
- name = view->getName();
-
- if (name == "root") break;
-
- if (view->getToolTip().find(".xml") != std::string::npos)
+ LLView* viewp = *child_it;
+ S32 local_x = x - viewp->getRect().mLeft;
+ S32 local_y = y - viewp->getRect().mBottom;
+ if(viewp->pointInView(local_x, local_y) &&
+ viewp->getVisible() &&
+ viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen) )
{
- tool_tip = view->getToolTip() + "/" + tool_tip;
+ if (sDebugMouseHandling)
+ {
+ sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage;
+ }
+
+ handled_view = viewp;
break;
}
- else
- {
- tool_tip = view->getName() + "/" + tool_tip;
- }
-
- view = view->getParent();
}
-
- return "/" + tool_tip;
+ return handled_view;
}
-
-BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
+BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
{
- BOOL handled = FALSE;
-
- std::string tool_tip;
+ LLView* child_handler = childrenHandleToolTip(x, y, msg, sticky_rect_screen);
+ BOOL handled = child_handler != NULL;
- for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
+ // child widgets get priority on tooltips
+ if (!handled && !mToolTipMsg.empty())
{
- LLView* viewp = *child_it;
- S32 local_x = x - viewp->mRect.mLeft;
- S32 local_y = y - viewp->mRect.mBottom;
- // Allow tooltips for disabled views so we can explain to the user why
- // the view is disabled. JC
- if( viewp->pointInView(local_x, local_y)
- && viewp->getVisible()
- // && viewp->getEnabled()
- && viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen ))
- {
- // child provided a tooltip, just return
- if (!msg.empty()) return TRUE;
-
- // otherwise, one of our children ate the event so don't traverse
- // siblings however, our child did not actually provide a tooltip
- // so we might want to
- handled = TRUE;
- break;
- }
- }
+ // allow "scrubbing" over ui by showing next tooltip immediately
+ // if previous one was still visible
+ F32 timeout = LLToolTipMgr::instance().toolTipVisible()
+ ? 0.f
+ : LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" );
+ LLToolTipMgr::instance().show(LLToolTipParams()
+ .message(mToolTipMsg)
+ .sticky_rect(calcScreenRect())
+ .delay_time(timeout));
- // get our own tooltip
- tool_tip = mToolTipMsg.getString();
-
- if (LLUI::sShowXUINames
- && (tool_tip.find(".xml", 0) == std::string::npos)
- && (mName.find("Drag", 0) == std::string::npos))
- {
- tool_tip = getShowNamesToolTip();
+ handled = TRUE;
}
- if(!tool_tip.empty())
- {
- msg = tool_tip;
-
- // Convert rect local to screen coordinates
- *sticky_rect_screen = calcScreenRect();
- }
- // don't allow any siblings to handle this event
- // even if we don't have a tooltip
- if (getMouseOpaque() ||
- (!tool_tip.empty() &&
- (!LLUI::sShowXUINames || dynamic_cast<LLTextBox*>(this))))
+ if( blockMouseEvent(x, y) )
{
handled = TRUE;
}
@@ -1518,45 +1487,51 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent)
updateBoundingRect();
}
-void LLView::updateBoundingRect()
+LLRect LLView::calcBoundingRect()
{
- if (isDead()) return;
+ LLRect local_bounding_rect = LLRect::null;
- if (mUseBoundingRect)
+ child_list_const_iter_t child_it;
+ for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
{
- LLRect local_bounding_rect = LLRect::null;
-
- child_list_const_iter_t child_it;
- for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
+ LLView* childp = *child_it;
+ // ignore invisible and "top" children when calculating bounding rect
+ // such as combobox popups
+ if (!childp->getVisible() || childp == gFocusMgr.getTopCtrl())
{
- LLView* childp = *child_it;
- // ignore invisible and "top" children when calculating bounding rect
- // such as combobox popups
- if (!childp->getVisible() || childp == gFocusMgr.getTopCtrl())
- {
- continue;
- }
+ continue;
+ }
- LLRect child_bounding_rect = childp->getBoundingRect();
+ LLRect child_bounding_rect = childp->getBoundingRect();
- if (local_bounding_rect.isEmpty())
- {
- // start out with bounding rect equal to first visible child's bounding rect
- local_bounding_rect = child_bounding_rect;
- }
- else
+ if (local_bounding_rect.isEmpty())
+ {
+ // start out with bounding rect equal to first visible child's bounding rect
+ local_bounding_rect = child_bounding_rect;
+ }
+ else
+ {
+ // accumulate non-null children rectangles
+ if (!child_bounding_rect.isEmpty())
{
- // accumulate non-null children rectangles
- if (!child_bounding_rect.isEmpty())
- {
- local_bounding_rect.unionWith(child_bounding_rect);
- }
+ local_bounding_rect.unionWith(child_bounding_rect);
}
}
+ }
+
+ // convert to parent-relative coordinates
+ local_bounding_rect.translate(mRect.mLeft, mRect.mBottom);
+ return local_bounding_rect;
+}
+
+
+void LLView::updateBoundingRect()
+{
+ if (isDead()) return;
- mBoundingRect = local_bounding_rect;
- // translate into parent-relative coordinates
- mBoundingRect.translate(mRect.mLeft, mRect.mBottom);
+ if (mUseBoundingRect)
+ {
+ mBoundingRect = calcBoundingRect();
}
else
{
@@ -1817,73 +1792,123 @@ void LLView::deleteViewByHandle(LLHandle<LLView> handle)
}
-// Moves the view so that it is entirely inside of constraint.
-// If the view will not fit because it's too big, aligns with the top and left.
-// (Why top and left? That's where the drag bars are for floaters.)
-BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outside )
+LLCoordGL getNeededTranslation(const LLRect& input, const LLRect& constraint, BOOL allow_partial_outside)
{
- S32 delta_x = 0;
- S32 delta_y = 0;
+ LLCoordGL delta;
if (allow_partial_outside)
{
const S32 KEEP_ONSCREEN_PIXELS = 16;
- if( getRect().mRight - KEEP_ONSCREEN_PIXELS < constraint.mLeft )
+ if( input.mRight - KEEP_ONSCREEN_PIXELS < constraint.mLeft )
{
- delta_x = constraint.mLeft - (getRect().mRight - KEEP_ONSCREEN_PIXELS);
+ delta.mX = constraint.mLeft - (input.mRight - KEEP_ONSCREEN_PIXELS);
}
else
- if( getRect().mLeft + KEEP_ONSCREEN_PIXELS > constraint.mRight )
+ if( input.mLeft + KEEP_ONSCREEN_PIXELS > constraint.mRight )
{
- delta_x = constraint.mRight - (getRect().mLeft + KEEP_ONSCREEN_PIXELS);
+ delta.mX = constraint.mRight - (input.mLeft + KEEP_ONSCREEN_PIXELS);
}
- if( getRect().mTop > constraint.mTop )
+ if( input.mTop > constraint.mTop )
{
- delta_y = constraint.mTop - getRect().mTop;
+ delta.mY = constraint.mTop - input.mTop;
}
else
- if( getRect().mTop - KEEP_ONSCREEN_PIXELS < constraint.mBottom )
+ if( input.mTop - KEEP_ONSCREEN_PIXELS < constraint.mBottom )
{
- delta_y = constraint.mBottom - (getRect().mTop - KEEP_ONSCREEN_PIXELS);
+ delta.mY = constraint.mBottom - (input.mTop - KEEP_ONSCREEN_PIXELS);
}
}
else
{
- if( getRect().mLeft < constraint.mLeft )
+ if( input.mLeft < constraint.mLeft )
{
- delta_x = constraint.mLeft - getRect().mLeft;
+ delta.mX = constraint.mLeft - input.mLeft;
}
else
- if( getRect().mRight > constraint.mRight )
+ if( input.mRight > constraint.mRight )
{
- delta_x = constraint.mRight - getRect().mRight;
+ delta.mX = constraint.mRight - input.mRight;
// compensate for left edge possible going off screen
- delta_x += llmax( 0, getRect().getWidth() - constraint.getWidth() );
+ delta.mX += llmax( 0, input.getWidth() - constraint.getWidth() );
}
- if( getRect().mTop > constraint.mTop )
+ if( input.mTop > constraint.mTop )
{
- delta_y = constraint.mTop - getRect().mTop;
+ delta.mY = constraint.mTop - input.mTop;
}
else
- if( getRect().mBottom < constraint.mBottom )
+ if( input.mBottom < constraint.mBottom )
{
- delta_y = constraint.mBottom - getRect().mBottom;
+ delta.mY = constraint.mBottom - input.mBottom;
// compensate for top edge possible going off screen
- delta_y -= llmax( 0, getRect().getHeight() - constraint.getHeight() );
+ delta.mY -= llmax( 0, input.getHeight() - constraint.getHeight() );
}
}
- if (delta_x != 0 || delta_y != 0)
+ return delta;
+}
+
+// Moves the view so that it is entirely inside of constraint.
+// If the view will not fit because it's too big, aligns with the top and left.
+// (Why top and left? That's where the drag bars are for floaters.)
+BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outside )
+{
+ LLCoordGL translation = getNeededTranslation(getRect(), constraint, allow_partial_outside);
+
+ if (translation.mX != 0 || translation.mY != 0)
+ {
+ translate(translation.mX, translation.mY);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// move this view into "inside" but not onto "exclude"
+// NOTE: if this view is already contained in "inside", we ignore the "exclude" rect
+BOOL LLView::translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, BOOL allow_partial_outside )
+{
+ LLCoordGL translation = getNeededTranslation(getRect(), inside, allow_partial_outside);
+
+ if (translation.mX != 0 || translation.mY != 0)
{
- translate(delta_x, delta_y);
+ // translate ourselves into constraint rect
+ translate(translation.mX, translation.mY);
+
+ // do we overlap with exclusion area?
+ // keep moving in the same direction to the other side of the exclusion rect
+ if (exclude.overlaps(getRect()))
+ {
+ // moving right
+ if (translation.mX > 0)
+ {
+ translate(exclude.mRight - getRect().mLeft, 0);
+ }
+ // moving left
+ else if (translation.mX < 0)
+ {
+ translate(exclude.mLeft - getRect().mRight, 0);
+ }
+
+ // moving up
+ if (translation.mY > 0)
+ {
+ translate(0, exclude.mTop - getRect().mBottom);
+ }
+ // moving down
+ else if (translation.mY < 0)
+ {
+ translate(0, exclude.mBottom - getRect().mTop);
+ }
+ }
+
return TRUE;
}
return FALSE;
}
+
void LLView::centerWithin(const LLRect& bounds)
{
S32 left = bounds.mLeft + (bounds.getWidth() - getRect().getWidth()) / 2;
@@ -2712,19 +2737,44 @@ void LLView::setupParamsForExport(Params& p, LLView* parent)
convert_coords_to_top_left(p, parent);
}
-LLView::tree_iterator_t LLView::beginTree()
+LLView::tree_iterator_t LLView::beginTreeDFS()
{
return tree_iterator_t(this,
boost::bind(boost::mem_fn(&LLView::beginChild), _1),
boost::bind(boost::mem_fn(&LLView::endChild), _1));
}
-LLView::tree_iterator_t LLView::endTree()
+LLView::tree_iterator_t LLView::endTreeDFS()
{
// an empty iterator is an "end" iterator
return tree_iterator_t();
}
+LLView::tree_post_iterator_t LLView::beginTreeDFSPost()
+{
+ return tree_post_iterator_t(this,
+ boost::bind(boost::mem_fn(&LLView::beginChild), _1),
+ boost::bind(boost::mem_fn(&LLView::endChild), _1));
+}
+
+LLView::tree_post_iterator_t LLView::endTreeDFSPost()
+{
+ // an empty iterator is an "end" iterator
+ return tree_post_iterator_t();
+}
+
+
+LLView::root_to_view_iterator_t LLView::beginRootToView()
+{
+ return root_to_view_iterator_t(this, boost::bind(&LLView::getParent, _1));
+}
+
+LLView::root_to_view_iterator_t LLView::endRootToView()
+{
+ return root_to_view_iterator_t();
+}
+
+
// only create maps on demand, as they incur heap allocation/deallocation cost
// when a view is constructed/deconstructed
LLView::default_widget_map_t& LLView::getDefaultWidgetMap() const
@@ -2735,6 +2785,7 @@ LLView::default_widget_map_t& LLView::getDefaultWidgetMap() const
}
return *mDefaultWidgets;
}
+
void LLView::notifyParent(const LLSD& info)
{
LLView* parent = getParent();
@@ -2749,3 +2800,18 @@ void LLView::notifyChildren(const LLSD& info)
}
}
+// convenient accessor for draw context
+const LLViewDrawContext& LLView::getDrawContext()
+{
+ return LLViewDrawContext::getCurrentContext();
+}
+
+const LLViewDrawContext& LLViewDrawContext::getCurrentContext()
+{
+ static LLViewDrawContext default_context;
+
+ if (sDrawContextStack.empty())
+ return default_context;
+
+ return *sDrawContextStack.back();
+}
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 1d48378081..d80c2af568 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -70,74 +70,35 @@ const BOOL NOT_MOUSE_OPAQUE = FALSE;
const U32 GL_NAME_UI_RESERVED = 2;
-/*
-// virtual functions defined in LLView:
-
-virtual BOOL isCtrl() const;
- LLUICtrl
-virtual BOOL isPanel();
- LLPanel
-virtual void setRect(const LLRect &rect);
- LLLineEditor
- LLPanel
-virtual BOOL canFocusChildren() const { return TRUE; }
- LLFolderView
-virtual void deleteAllChildren();
- LLFolderView, LLPanelInventory
-virtual void setTentative(BOOL b) {}
- LLUICtrl, LLSliderCtrl, LLSpinCtrl
-virtual BOOL getTentative() const { return FALSE; }
- LLUICtrl, LLCheckBoxCtrl
-virtual void setVisible(BOOL visible);
- LLFloater, LLAlertDialog, LLMenuItemGL, LLModalDialog
-virtual void setEnabled(BOOL enabled) { mEnabled = enabled; }
- LLCheckBoxCtrl, LLComboBox, LLLineEditor, LLMenuGL, LLRadioGroup, etc
-virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ) { return FALSE; }
- LLUICtrl, LLButton, LLCheckBoxCtrl, LLLineEditor, LLMenuGL, LLSliderCtrl
-virtual void handleVisibilityChange ( BOOL curVisibilityIn );
- LLMenuGL
-virtual LLRect getSnapRect() const { return mRect; } *TODO: Make non virtual
- LLFloater
-virtual LLRect getRequiredRect() { return mRect; }
- LLScrolllistCtrl
-virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- LLUICtrl, et. al.
-virtual void translate( S32 x, S32 y );
- LLMenuGL
-virtual void setShape(const LLRect& new_rect, bool by_user);
- LLFloater, LLScrollLIstVtrl
-virtual LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0);
-virtual LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0);
- LLScrollListCtrl
-virtual BOOL canSnapTo(const LLView* other_view) { return other_view != this && other_view->getVisible(); }
- LLFloater
-virtual void snappedTo(const LLView* snap_view) {}
- LLFloater
-virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
- *
-virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
- *
-virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,EDragAndDropType cargo_type,void* cargo_data,EAcceptance* accept,std::string& tooltip_msg);
- *
-virtual void draw();
- *
-
- *
-virtual void onFocusLost() {}
- LLUICtrl, LLScrollListCtrl, LLMenuGL, LLLineEditor, LLComboBox
-virtual void onFocusReceived() {}
- LLUICtrl, LLTextEditor, LLScrollListVtrl, LLMenuGL, LLLineEditor
-virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
- LLTabContainer, LLPanel, LLMenuGL
-virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata);
- LLMenuItem
-protected:
-virtual BOOL handleKeyHere(KEY key, MASK mask);
- *
-virtual BOOL handleUnicodeCharHere(llwchar uni_char);
- *
-*/
+// maintains render state during traversal of UI tree
+class LLViewDrawContext
+{
+public:
+ F32 mAlpha;
+
+ LLViewDrawContext(F32 alpha = 1.f)
+ : mAlpha(alpha)
+ {
+ if (!sDrawContextStack.empty())
+ {
+ LLViewDrawContext* context_top = sDrawContextStack.back();
+ // merge with top of stack
+ mAlpha *= context_top->mAlpha;
+ }
+ sDrawContextStack.push_back(this);
+ }
+
+ ~LLViewDrawContext()
+ {
+ sDrawContextStack.pop_back();
+ }
+
+ static const LLViewDrawContext& getCurrentContext();
+
+private:
+ static std::vector<LLViewDrawContext*> sDrawContextStack;
+};
class LLViewWidgetRegistry : public LLChildRegistry<LLViewWidgetRegistry>
{};
@@ -380,6 +341,7 @@ public:
// Override and return required size for this object. 0 for width/height means don't care.
virtual LLRect getRequiredRect();
+ LLRect calcBoundingRect();
void updateBoundingRect();
LLView* getRootView();
@@ -393,9 +355,19 @@ public:
BOOL hasChild(const std::string& childname, BOOL recurse = FALSE) const;
BOOL childHasKeyboardFocus( const std::string& childname ) const;
+ // these iterators are used for collapsing various tree traversals into for loops
typedef LLTreeDFSIter<LLView, child_list_const_iter_t> tree_iterator_t;
- tree_iterator_t beginTree();
- tree_iterator_t endTree();
+ tree_iterator_t beginTreeDFS();
+ tree_iterator_t endTreeDFS();
+
+ typedef LLTreeDFSPostIter<LLView, child_list_const_iter_t> tree_post_iterator_t;
+ tree_post_iterator_t beginTreeDFSPost();
+ tree_post_iterator_t endTreeDFSPost();
+
+
+ typedef LLTreeDownIter<LLView> root_to_view_iterator_t;
+ root_to_view_iterator_t beginRootToView();
+ root_to_view_iterator_t endRootToView();
//
// UTILITIES
@@ -406,6 +378,7 @@ public:
virtual void translate( S32 x, S32 y );
void setOrigin( S32 x, S32 y ) { mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); }
BOOL translateIntoRect( const LLRect& constraint, BOOL allow_partial_outside );
+ BOOL translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, BOOL allow_partial_outside );
void centerWithin(const LLRect& bounds);
void setShape(const LLRect& new_rect, bool by_user = false);
@@ -424,10 +397,7 @@ public:
EAcceptance* accept,
std::string& tooltip_msg);
- virtual std::string getShowNamesToolTip();
-
virtual void draw();
- void drawChildren();
void parseFollowsFlags(const LLView::Params& params);
@@ -477,7 +447,8 @@ public:
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
- /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); // Display mToolTipMsg if no child handles it.
+ /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect); // Display mToolTipMsg if no child handles it.
+
/*virtual*/ const std::string& getName() const;
/*virtual*/ void onMouseCaptureLost();
/*virtual*/ BOOL hasMouseCapture();
@@ -552,9 +523,12 @@ public:
virtual void notifyParent(const LLSD& info);
virtual void notifyChildren(const LLSD& info);
+ static const LLViewDrawContext& getDrawContext();
+
protected:
void drawDebugRect();
void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE);
+ void drawChildren();
LLView* childrenHandleKey(KEY key, MASK mask);
LLView* childrenHandleUnicodeChar(llwchar uni_char);
@@ -574,10 +548,12 @@ protected:
LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks);
LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask);
LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask);
+ LLView* childrenHandleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect);
ECursorType mHoverCursor;
private:
+
LLView* mParentView;
child_list_t mChildList;
diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp
index f41c98f7b3..30717f87de 100644
--- a/indra/llui/llviewborder.cpp
+++ b/indra/llui/llviewborder.cpp
@@ -134,7 +134,7 @@ void LLViewBorder::draw()
}
}
- drawChildren();
+ LLView::draw();
}
void LLViewBorder::drawOnePixelLines()