diff options
Diffstat (limited to 'indra/llui')
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() |