diff options
author | AndreyL ProductEngine <alihatskiy@productengine.com> | 2019-11-27 23:20:03 +0200 |
---|---|---|
committer | AndreyL ProductEngine <alihatskiy@productengine.com> | 2019-11-27 23:20:03 +0200 |
commit | 56056aa198fc31a14cb4320762033958e96558cc (patch) | |
tree | d274000fb53dc1234cff8cddd8b3d3b756bf3681 /indra/llui | |
parent | 78bdf57ad6610b34389226bf941ba736ca0c2225 (diff) | |
parent | 191c1791f4f83fee1be6e71aa9e3f246206b2e80 (diff) |
Upstream merge from viewer-neko
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/llfloater.cpp | 69 | ||||
-rw-r--r-- | indra/llui/llfloater.h | 13 | ||||
-rw-r--r-- | indra/llui/llmenugl.cpp | 48 | ||||
-rw-r--r-- | indra/llui/llmenugl.h | 18 | ||||
-rw-r--r-- | indra/llui/llnotifications.cpp | 17 | ||||
-rw-r--r-- | indra/llui/llnotifications.h | 4 | ||||
-rw-r--r-- | indra/llui/llscrollbar.cpp | 10 | ||||
-rw-r--r-- | indra/llui/llscrollbar.h | 1 | ||||
-rw-r--r-- | indra/llui/llscrollcontainer.cpp | 19 | ||||
-rw-r--r-- | indra/llui/llscrollcontainer.h | 1 | ||||
-rw-r--r-- | indra/llui/llscrolllistcell.cpp | 149 | ||||
-rw-r--r-- | indra/llui/llscrolllistcell.h | 31 | ||||
-rw-r--r-- | indra/llui/llscrolllistctrl.cpp | 191 | ||||
-rw-r--r-- | indra/llui/llscrolllistctrl.h | 22 | ||||
-rw-r--r-- | indra/llui/llscrolllistitem.cpp | 56 | ||||
-rw-r--r-- | indra/llui/llscrolllistitem.h | 21 | ||||
-rw-r--r-- | indra/llui/lltextbase.cpp | 1 | ||||
-rw-r--r-- | indra/llui/lltextbase.h | 1 | ||||
-rw-r--r-- | indra/llui/lluictrl.cpp | 37 | ||||
-rw-r--r-- | indra/llui/lluictrlfactory.h | 4 | ||||
-rw-r--r-- | indra/llui/llurlentry.cpp | 10 | ||||
-rw-r--r-- | indra/llui/llview.cpp | 24 | ||||
-rw-r--r-- | indra/llui/llview.h | 2 | ||||
-rw-r--r-- | indra/llui/tests/llurlentry_test.cpp | 5 |
24 files changed, 677 insertions, 77 deletions
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 42802cd339..e3bb36192c 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -37,6 +37,7 @@ #include "lluictrlfactory.h" #include "llbutton.h" #include "llcheckboxctrl.h" +#include "llcriticaldamp.h" // LLSmoothInterpolation #include "lldir.h" #include "lldraghandle.h" #include "llfloaterreg.h" @@ -64,6 +65,10 @@ // use this to control "jumping" behavior when Ctrl-Tabbing const S32 TABBED_FLOATER_OFFSET = 0; +const F32 LLFloater::CONTEXT_CONE_IN_ALPHA = 0.0f; +const F32 LLFloater::CONTEXT_CONE_OUT_ALPHA = 1.f; +const F32 LLFloater::CONTEXT_CONE_FADE_TIME = 0.08f; + namespace LLInitParam { void TypeValues<LLFloaterEnums::EOpenPositioning>::declareValues() @@ -2116,6 +2121,70 @@ void LLFloater::updateTitleButtons() } } +void LLFloater::drawConeToOwner(F32 &context_cone_opacity, + F32 max_cone_opacity, + LLView *owner_view, + F32 fade_time, + F32 contex_cone_in_alpha, + F32 contex_cone_out_alpha) +{ + if (owner_view + && owner_view->isInVisibleChain() + && hasFocus() + && context_cone_opacity > 0.001f + && gFocusMgr.childHasKeyboardFocus(this)) + { + // draw cone of context pointing back to owner (e.x. texture swatch) + LLRect owner_rect; + owner_view->localRectToOtherView(owner_view->getLocalRect(), &owner_rect, this); + LLRect local_rect = getLocalRect(); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLEnable(GL_CULL_FACE); + gGL.begin(LLRender::QUADS); + { + gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop); + gGL.vertex2i(owner_rect.mRight, owner_rect.mTop); + gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); + gGL.vertex2i(local_rect.mRight, local_rect.mTop); + gGL.vertex2i(local_rect.mLeft, local_rect.mTop); + + gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); + gGL.vertex2i(local_rect.mLeft, local_rect.mTop); + gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop); + + gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); + gGL.vertex2i(local_rect.mRight, local_rect.mBottom); + gGL.vertex2i(local_rect.mRight, local_rect.mTop); + gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); + gGL.vertex2i(owner_rect.mRight, owner_rect.mTop); + gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom); + + + gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); + gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); + gGL.vertex2i(local_rect.mRight, local_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); + gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom); + } + gGL.end(); + } + + if (gFocusMgr.childHasMouseCapture(getDragHandle())) + { + context_cone_opacity = lerp(context_cone_opacity, max_cone_opacity, LLSmoothInterpolation::getInterpolant(fade_time)); + } + else + { + context_cone_opacity = lerp(context_cone_opacity, 0.f, LLSmoothInterpolation::getInterpolant(fade_time)); + } +} + void LLFloater::buildButtons(const Params& floater_params) { static LLUICachedControl<S32> floater_close_box_size ("UIFloaterCloseBoxSize", 0); diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 165f67499b..f8c04e8a2f 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -395,6 +395,15 @@ protected: virtual void updateTitleButtons(); + // Draws a cone from this floater to parent floater or view (owner) + // Modifies context_cone_opacity (interpolates according to fade time and returns new value) + void drawConeToOwner(F32 &context_cone_opacity, + F32 max_cone_opacity, + LLView *owner_view, + F32 context_fade_time = CONTEXT_CONE_FADE_TIME, + F32 contex_cone_in_alpha = CONTEXT_CONE_IN_ALPHA, + F32 contex_cone_out_alpha = CONTEXT_CONE_OUT_ALPHA); + private: void setForeground(BOOL b); // called only by floaterview void cleanupHandles(); // remove handles to dead floaters @@ -424,6 +433,10 @@ private: void updateTransparency(LLView* view, ETypeTransparency transparency_type); public: + static const F32 CONTEXT_CONE_IN_ALPHA; + static const F32 CONTEXT_CONE_OUT_ALPHA; + static const F32 CONTEXT_CONE_FADE_TIME; + // Called when floater is opened, passes mKey // Public so external views or floaters can watch for this floater opening commit_signal_t mOpenSignal; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 200dd2fdca..1e18396184 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -213,6 +213,12 @@ LLSD LLMenuItemGL::getValue() const } //virtual +bool LLMenuItemGL::hasAccelerator(const KEY &key, const MASK &mask) const +{ + return (mAcceleratorKey == key) && (mAcceleratorMask == mask); +} + +//virtual BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask) { if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) @@ -263,13 +269,13 @@ BOOL LLMenuItemGL::handleRightMouseUp(S32 x, S32 y, MASK mask) // This function checks to see if the accelerator key is already in use; // if not, it will be added to the list -BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp) +BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLMenuKeyboardBinding*> *listp) { - LLKeyBinding *accelerator = NULL; + LLMenuKeyboardBinding *accelerator = NULL; if (mAcceleratorKey != KEY_NONE) { - std::list<LLKeyBinding*>::iterator list_it; + std::list<LLMenuKeyboardBinding*>::iterator list_it; for (list_it = listp->begin(); list_it != listp->end(); ++list_it) { accelerator = *list_it; @@ -293,7 +299,7 @@ BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp) } if (!accelerator) { - accelerator = new LLKeyBinding; + accelerator = new LLMenuKeyboardBinding; if (accelerator) { accelerator->mKey = mAcceleratorKey; @@ -788,6 +794,12 @@ void LLMenuItemCallGL::initFromParams(const Params& p) { setEnabledControlVariable(control); } + else + { + LL_WARNS() << "Failed to assign 'enabled' control variable to menu " << getName() + << ": control " << p.on_enable.control_name() + << " does not exist." << LL_ENDL; + } } } if (p.on_click.isProvided()) @@ -1011,6 +1023,11 @@ BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask) return TRUE; } +bool LLMenuItemBranchGL::hasAccelerator(const KEY &key, const MASK &mask) const +{ + return getBranch() && getBranch()->hasAccelerator(key, mask); +} + BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask) { return getBranch() && getBranch()->handleAcceleratorKey(key, mask); @@ -1018,7 +1035,7 @@ BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask) // This function checks to see if the accelerator key is already in use; // if not, it will be added to the list -BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list<LLKeyBinding*> *listp) +BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list<LLMenuKeyboardBinding*> *listp) { LLMenuGL* branch = getBranch(); if (!branch) @@ -2995,6 +3012,27 @@ void LLMenuGL::updateParent(LLView* parentp) } } +bool LLMenuGL::hasAccelerator(const KEY &key, const MASK &mask) const +{ + if (key == KEY_NONE) + { + return false; + } + // Note: checking this way because mAccelerators seems to be broken + // mAccelerators probably needs to be cleaned up or fixed + // It was used for dupplicate accelerator avoidance. + item_list_t::const_iterator item_iter; + for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) + { + LLMenuItemGL* itemp = *item_iter; + if (itemp->hasAccelerator(key, mask)) + { + return true; + } + } + return false; +} + BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask) { // don't handle if not enabled diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 78f688642e..f3844af507 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -42,6 +42,13 @@ extern S32 MENU_BAR_HEIGHT; extern S32 MENU_BAR_WIDTH; +class LLMenuKeyboardBinding +{ +public: + KEY mKey; + MASK mMask; +}; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuItemGL // @@ -91,6 +98,7 @@ public: /*virtual*/ void setValue(const LLSD& value); /*virtual*/ LLSD getValue() const; + virtual bool hasAccelerator(const KEY &key, const MASK &mask) const; virtual BOOL handleAcceleratorKey(KEY key, MASK mask); LLColor4 getHighlightBgColor() { return mHighlightBackground.get(); } @@ -109,7 +117,7 @@ public: virtual void setBriefItem(BOOL brief); virtual BOOL isBriefItem() const; - virtual BOOL addToAcceleratorList(std::list<LLKeyBinding*> *listp); + virtual BOOL addToAcceleratorList(std::list<LLMenuKeyboardBinding*> *listp); void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; } BOOL getAllowKeyRepeat() const { return mAllowKeyRepeat; } @@ -436,7 +444,8 @@ public: /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0); /*virtual*/ void removeChild( LLView* ctrl); /*virtual*/ BOOL postBuild(); - + + virtual bool hasAccelerator(const KEY &key, const MASK &mask) const; virtual BOOL handleAcceleratorKey(KEY key, MASK mask); LLMenuGL* findChildMenuByName(const std::string& name, BOOL recurse) const; @@ -625,10 +634,11 @@ public: virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + virtual bool hasAccelerator(const KEY &key, const MASK &mask) const; virtual BOOL handleAcceleratorKey(KEY key, MASK mask); // check if we've used these accelerators already - virtual BOOL addToAcceleratorList(std::list <LLKeyBinding*> *listp); + virtual BOOL addToAcceleratorList(std::list <LLMenuKeyboardBinding*> *listp); // called to rebuild the draw label virtual void buildDrawLabel( void ); @@ -794,7 +804,7 @@ private: void checkMenuTrigger(); - std::list <LLKeyBinding*> mAccelerators; + std::list <LLMenuKeyboardBinding*> mAccelerators; BOOL mAltKeyTrigger; }; diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 9fc6c05ead..6a7075301b 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -68,7 +68,8 @@ LLNotificationForm::FormIgnore::FormIgnore() control("control"), invert_control("invert_control", false), save_option("save_option", false), - session_only("session_only", false) + session_only("session_only", false), + checkbox_only("checkbox_only", false) {} LLNotificationForm::FormButton::FormButton() @@ -195,10 +196,15 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica { if (p.ignore.isProvided()) { + // For all cases but IGNORE_CHECKBOX_ONLY this is name for use in preferences mIgnoreMsg = p.ignore.text; LLUI *ui_inst = LLUI::getInstance(); - if (!p.ignore.save_option) + if (p.ignore.checkbox_only) + { + mIgnore = IGNORE_CHECKBOX_ONLY; + } + else if (!p.ignore.save_option) { mIgnore = p.ignore.session_only ? IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY : IGNORE_WITH_DEFAULT_RESPONSE; } @@ -215,7 +221,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica mIgnoreSetting = ui_inst->mSettingGroups["config"]->getControl(p.ignore.control); mInvertSetting = p.ignore.invert_control; } - else + else if (mIgnore > IGNORE_NO) { ui_inst->mSettingGroups["ignores"]->declareBOOL(name, show_notification, "Show notification with this name", LLControlVariable::PERSIST_NONDFT); mIgnoreSetting = ui_inst->mSettingGroups["ignores"]->getControl(name); @@ -389,13 +395,12 @@ LLControlVariablePtr LLNotificationForm::getIgnoreSetting() bool LLNotificationForm::getIgnored() { bool show = true; - if (mIgnore != LLNotificationForm::IGNORE_NO + if (mIgnore > LLNotificationForm::IGNORE_NO && mIgnoreSetting) { show = mIgnoreSetting->getValue().asBoolean(); if (mInvertSetting) show = !show; } - return !show; } @@ -696,7 +701,7 @@ void LLNotification::respond(const LLSD& response) mTemporaryResponder = false; } - if (mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO) + if (mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO) { mForm->setIgnored(mIgnored); if (mIgnored && mForm->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE) diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 1509446920..62cf41256b 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -180,6 +180,7 @@ public: Optional<std::string> control; Optional<bool> invert_control; Optional<bool> session_only; + Optional<bool> checkbox_only; FormIgnore(); }; @@ -232,7 +233,8 @@ public: typedef enum e_ignore_type { - IGNORE_NO, + IGNORE_CHECKBOX_ONLY = -1, // ignore won't be handled, will set value/checkbox only + IGNORE_NO = 0, IGNORE_WITH_DEFAULT_RESPONSE, IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY, IGNORE_WITH_LAST_RESPONSE, diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index b3a79bc1eb..fde6de4921 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -408,6 +408,16 @@ BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks) return handled; } +BOOL LLScrollbar::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + BOOL handled = FALSE; + if (LLScrollbar::HORIZONTAL == mOrientation) + { + handled = changeLine(clicks * mStepSize, TRUE); + } + return handled; +} + BOOL LLScrollbar::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/llscrollbar.h b/indra/llui/llscrollbar.h index e2bf52c14b..5f2f490d81 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -88,6 +88,7 @@ public: virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); 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/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 6135cc56ad..3db38bbfac 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -272,6 +272,25 @@ BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks ) return FALSE; } +BOOL LLScrollContainer::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + if (LLUICtrl::handleScrollHWheel(x,y,clicks)) + { + return TRUE; + } + + LLScrollbar* horizontal = mScrollbar[HORIZONTAL]; + if (horizontal->getVisible() + && horizontal->getEnabled() + && horizontal->handleScrollHWheel( 0, 0, clicks ) ) + { + updateScroll(); + return TRUE; + } + + return FALSE; +} + BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index e6c7891397..c14099dbd5 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -107,6 +107,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 handleScrollHWheel( S32 x, S32 y, S32 clicks ); virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 8000efad0e..13839da400 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -50,6 +50,10 @@ LLScrollListCell* LLScrollListCell::create(const LLScrollListCell::Params& cell_ { cell = new LLScrollListDate(cell_p); } + else if (cell_p.type() == "icontext") + { + cell = new LLScrollListIconText(cell_p); + } else // default is "text" { cell = new LLScrollListText(cell_p); @@ -168,7 +172,7 @@ U32 LLScrollListText::sCount = 0; LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p) : LLScrollListCell(p), - mText(p.value().asString()), + mText(p.label.isProvided() ? p.label() : p.value().asString()), mFont(p.font), mColor(p.color), mUseColor(p.color.isProvided()), @@ -192,7 +196,7 @@ LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p) void LLScrollListText::highlightText(S32 offset, S32 num_chars) { mHighlightOffset = offset; - mHighlightCount = num_chars; + mHighlightCount = llmax(0, num_chars); } //virtual @@ -292,11 +296,12 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col if (mHighlightCount > 0) { + // Highlight text S32 left = 0; switch(mFontAlignment) { case LLFontGL::LEFT: - left = mFont->getWidth(mText.getString(), 0, mHighlightOffset); + left = mFont->getWidth(mText.getString(), 1, mHighlightOffset); break; case LLFontGL::RIGHT: left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX); @@ -319,7 +324,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col switch(mFontAlignment) { case LLFontGL::LEFT: - start_x = 0.f; + start_x = 1.f; break; case LLFontGL::RIGHT: start_x = (F32)getWidth(); @@ -435,3 +440,139 @@ const LLSD LLScrollListDate::getValue() const { return mDate; } + +// +// LLScrollListIconText +// +LLScrollListIconText::LLScrollListIconText(const LLScrollListCell::Params& p) + : LLScrollListText(p), + mIcon(p.value().isUUID() ? LLUI::getUIImageByID(p.value().asUUID()) : LLUI::getUIImage(p.value().asString())), + mPad(4) +{ + mTextWidth = getWidth() - mPad /*padding*/ - mFont->getLineHeight(); +} + +LLScrollListIconText::~LLScrollListIconText() +{ +} + +const LLSD LLScrollListIconText::getValue() const +{ + if (mIcon.isNull()) + { + return LLStringUtil::null; + } + return mIcon->getName(); +} + +void LLScrollListIconText::setValue(const LLSD& value) +{ + if (value.isUUID()) + { + // don't use default image specified by LLUUID::null, use no image in that case + LLUUID image_id = value.asUUID(); + mIcon = image_id.notNull() ? LLUI::getUIImageByID(image_id) : LLUIImagePtr(NULL); + } + else + { + std::string value_string = value.asString(); + if (LLUUID::validate(value_string)) + { + setValue(LLUUID(value_string)); + } + else if (!value_string.empty()) + { + mIcon = LLUI::getUIImage(value.asString()); + } + else + { + mIcon = NULL; + } + } +} + +void LLScrollListIconText::setWidth(S32 width) +{ + LLScrollListCell::setWidth(width); + // Assume that iamge height and width is identical to font height and width + mTextWidth = width - mPad /*padding*/ - mFont->getLineHeight(); +} + + +void LLScrollListIconText::draw(const LLColor4& color, const LLColor4& highlight_color) const +{ + LLColor4 display_color; + if (mUseColor) + { + display_color = mColor; + } + else + { + display_color = color; + } + + S32 icon_height = mFont->getLineHeight(); + S32 icon_space = mIcon ? (icon_height + mPad) : 0; + + if (mHighlightCount > 0) + { + S32 left = 0; + switch (mFontAlignment) + { + case LLFontGL::LEFT: + left = mFont->getWidth(mText.getString(), icon_space + 1, mHighlightOffset); + break; + case LLFontGL::RIGHT: + left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX) - icon_space; + break; + case LLFontGL::HCENTER: + left = (getWidth() - mFont->getWidth(mText.getString()) - icon_space) / 2; + break; + } + LLRect highlight_rect(left - 2, + mFont->getLineHeight() + 1, + left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1, + 1); + mRoundedRectImage->draw(highlight_rect, highlight_color); + } + + // Try to draw the entire string + F32 right_x; + U32 string_chars = mText.length(); + F32 start_text_x = 0.f; + S32 start_icon_x = 0; + switch (mFontAlignment) + { + case LLFontGL::LEFT: + start_text_x = icon_space + 1; + start_icon_x = 1; + break; + case LLFontGL::RIGHT: + start_text_x = (F32)getWidth(); + start_icon_x = getWidth() - mFont->getWidth(mText.getString()) - icon_space; + break; + case LLFontGL::HCENTER: + F32 center = (F32)getWidth()* 0.5f; + start_text_x = center + ((F32)icon_space * 0.5f); + start_icon_x = center - (((F32)icon_space + mFont->getWidth(mText.getString())) * 0.5f); + break; + } + mFont->render(mText.getWString(), 0, + start_text_x, 0.f, + display_color, + mFontAlignment, + LLFontGL::BOTTOM, + 0, + LLFontGL::NO_SHADOW, + string_chars, + getTextWidth(), + &right_x, + TRUE); + + if (mIcon) + { + mIcon->draw(start_icon_x, 0, icon_height, icon_height, mColor); + } +} + + diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index d625ebddcc..19576fb247 100644 --- a/indra/llui/llscrolllistcell.h +++ b/indra/llui/llscrolllistcell.h @@ -59,7 +59,8 @@ public: visible; Optional<void*> userdata; - Optional<LLSD> value; + Optional<LLSD> value; // state of checkbox, icon id/name, date + Optional<std::string> label; // description or text Optional<std::string> tool_tip; Optional<const LLFontGL*> font; @@ -75,6 +76,7 @@ public: enabled("enabled", true), visible("visible", true), value("value"), + label("label"), tool_tip("tool_tip", ""), font("font", LLFontGL::getFontSansSerifSmall()), font_color("font_color", LLColor4::black), @@ -152,11 +154,12 @@ public: void setText(const LLStringExplicit& text); void setFontStyle(const U8 font_style); -private: +protected: LLUIString mText; S32 mTextWidth; const LLFontGL* mFont; LLColor4 mColor; + LLColor4 mHighlightColor; U8 mUseColor; LLFontGL::HAlign mFontAlignment; BOOL mVisible; @@ -169,7 +172,7 @@ private: }; /* - * Cell displaying an image. + * Cell displaying an image. AT the moment, this is specifically UI image */ class LLScrollListIcon : public LLScrollListCell { @@ -223,4 +226,26 @@ private: LLDate mDate; }; +/* +* Cell displaying icon and text. +*/ + +class LLScrollListIconText : public LLScrollListText +{ +public: + LLScrollListIconText(const LLScrollListCell::Params& p); + /*virtual*/ ~LLScrollListIconText(); + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ const LLSD getValue() const; + /*virtual*/ void setValue(const LLSD& value); + + + S32 getIconWidth() const; + /*virtual*/ void setWidth(S32 width);/* { LLScrollListCell::setWidth(width); mTextWidth = width - ; }*/ + +private: + LLPointer<LLUIImage> mIcon; + S32 mPad; +}; + #endif diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index f4028057e8..94b130e28d 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -115,6 +115,13 @@ struct SortScrollListItem // LLScrollListCtrl //--------------------------------------------------------------------------- +void LLScrollListCtrl::SelectionTypeNames::declareValues() +{ + declare("row", LLScrollListCtrl::ROW); + declare("cell", LLScrollListCtrl::CELL); + declare("header", LLScrollListCtrl::HEADER); +} + LLScrollListCtrl::Contents::Contents() : columns("column"), rows("row") @@ -128,8 +135,10 @@ LLScrollListCtrl::Params::Params() has_border("draw_border"), draw_heading("draw_heading"), search_column("search_column", 0), + selection_type("selection_type", ROW), sort_column("sort_column", -1), sort_ascending("sort_ascending", true), + can_sort("can_sort", true), mouse_wheel_opaque("mouse_wheel_opaque", false), commit_on_keyboard_movement("commit_on_keyboard_movement", true), heading_height("heading_height"), @@ -163,8 +172,10 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mCommitOnKeyboardMovement(p.commit_on_keyboard_movement), mCommitOnSelectionChange(false), mSelectionChanged(false), + mSelectionType(p.selection_type), mNeedsScroll(false), mCanSelect(true), + mCanSort(p.can_sort), mColumnsDirty(false), mMaxItemCount(INT_MAX), mBorderThickness( 2 ), @@ -819,7 +830,15 @@ BOOL LLScrollListCtrl::selectFirstItem() { if (!itemp->getSelected()) { - selectItem(itemp); + switch (mSelectionType) + { + case CELL: + selectItem(itemp, 0); + break; + case HEADER: + case ROW: + selectItem(itemp, -1); + } } success = TRUE; mOriginalSelection = 0; @@ -878,7 +897,8 @@ BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index ) { if( itemp->getEnabled() ) { - selectItem(itemp, FALSE); + // TODO: support range selection for cells + selectItem(itemp, -1, FALSE); success = TRUE; } } @@ -1004,10 +1024,14 @@ void LLScrollListCtrl::clearHighlightedItems() void LLScrollListCtrl::mouseOverHighlightNthItem(S32 target_index) { - if (mHighlightedItem != target_index) - { - mHighlightedItem = target_index; - } + if (mHighlightedItem != target_index) + { + if (mHighlightedItem >= 0 && mHighlightedItem < mItemList.size()) + { + mItemList[mHighlightedItem]->setHoverCell(-1); + } + mHighlightedItem = target_index; + } } S32 LLScrollListCtrl::selectMultiple( uuid_vec_t ids ) @@ -1022,7 +1046,8 @@ S32 LLScrollListCtrl::selectMultiple( uuid_vec_t ids ) { if (item->getEnabled() && (item->getUUID() == (*iditr))) { - selectItem(item,FALSE); + // TODO: support multiple selection for cells + selectItem(item, -1, FALSE); ++count; break; } @@ -1095,7 +1120,7 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection) { if (prev_item) { - selectItem(prev_item, !extend_selection); + selectItem(prev_item, cur_item->getSelectedCell(), !extend_selection); } else { @@ -1139,7 +1164,7 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection) { if (next_item) { - selectItem(next_item, !extend_selection); + selectItem(next_item, cur_item->getSelectedCell(), !extend_selection); } else { @@ -1210,7 +1235,7 @@ BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sen bool found = NULL != item; if(found) { - selectItem(item); + selectItem(item, -1); } if (mCommitOnSelectionChange) @@ -1278,7 +1303,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE; if (select) { - selectItem(item); + selectItem(item, -1); found = TRUE; break; } @@ -1318,7 +1343,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen // find offset of matching text (might have leading whitespace) S32 offset = item_label.find(target_trimmed); cellp->highlightText(offset, target_trimmed.size()); - selectItem(item); + selectItem(item, -1); found = TRUE; break; } @@ -1384,7 +1409,7 @@ BOOL LLScrollListCtrl::setSelectedByValue(const LLSD& value, BOOL selected) { if (selected) { - selectItem(item); + selectItem(item, -1); } else { @@ -1464,7 +1489,7 @@ void LLScrollListCtrl::drawItems() S32 max_columns = 0; - LLColor4 highlight_color = LLColor4::white; + LLColor4 highlight_color = LLColor4::white; // ex: text inside cells static LLUICachedControl<F32> type_ahead_timeout ("TypeAheadTimeout", 0); highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout(), 0.4f, 0.f); @@ -1490,7 +1515,8 @@ void LLScrollListCtrl::drawItems() max_columns = llmax(max_columns, item->getNumColumns()); LLColor4 fg_color; - LLColor4 bg_color(LLColor4::transparent); + LLColor4 hover_color(LLColor4::transparent); + LLColor4 select_color(LLColor4::transparent); if( mScrollLines <= line && line < mScrollLines + num_page_lines ) { @@ -1499,44 +1525,44 @@ void LLScrollListCtrl::drawItems() { if(item->getHighlighted()) // if it's highlighted, average the colors { - bg_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f); + select_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f); } else // otherwise just select-highlight it { - bg_color = mBgSelectedColor.get(); + select_color = mBgSelectedColor.get(); } fg_color = (item->getEnabled() ? mFgSelectedColor.get() : mFgDisabledColor.get()); } - else if (mHighlightedItem == line && mCanSelect) + if (mHighlightedItem == line && mCanSelect) { if(item->getHighlighted()) // if it's highlighted, average the colors { - bg_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f); + hover_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f); } else // otherwise just hover-highlight it { - bg_color = mHoveredColor.get(); + hover_color = mHoveredColor.get(); } } else if (item->getHighlighted()) { - bg_color = mHighlightedColor.get(); + hover_color = mHighlightedColor.get(); } else { if (mDrawStripes && (line % 2 == 0) && (max_columns > 1)) { - bg_color = mBgStripeColor.get(); + hover_color = mBgStripeColor.get(); } } if (!item->getEnabled()) { - bg_color = mBgReadOnlyColor.get(); + hover_color = mBgReadOnlyColor.get(); } - item->draw(item_rect, fg_color % alpha, bg_color% alpha, highlight_color % alpha, mColumnPadding); + item->draw(item_rect, fg_color % alpha, hover_color% alpha, select_color% alpha, highlight_color % alpha, mColumnPadding); cur_y -= mLineHeight; } @@ -1601,6 +1627,20 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks) return handled; } +BOOL LLScrollListCtrl::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + BOOL handled = FALSE; + // Pretend the mouse is over the scrollbar + handled = mScrollbar->handleScrollHWheel( 0, 0, clicks ); + + if (mMouseWheelOpaque) + { + return TRUE; + } + + return handled; +} + // *NOTE: Requires a valid row_index and column_index LLRect LLScrollListCtrl::getCellRect(S32 row_index, S32 column_index) { @@ -1674,7 +1714,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) { if (mLastSelected == NULL) { - selectItem(hit_item); + selectItem(hit_item, getColumnIndexFromOffset(x)); } else { @@ -1698,7 +1738,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) LLScrollListItem *item = *itor; if (item == hit_item || item == lastSelected) { - selectItem(item, FALSE); + selectItem(item, getColumnIndexFromOffset(x), FALSE); selecting = !selecting; if (hit_item == lastSelected) { @@ -1708,7 +1748,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) } if (selecting) { - selectItem(item, FALSE); + selectItem(item, getColumnIndexFromOffset(x), FALSE); } } } @@ -1723,7 +1763,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) { if(!(mMaxSelectable > 0 && getAllSelected().size() >= mMaxSelectable)) { - selectItem(hit_item, FALSE); + selectItem(hit_item, getColumnIndexFromOffset(x), FALSE); } else { @@ -1737,12 +1777,12 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) else { deselectAllItems(TRUE); - selectItem(hit_item); + selectItem(hit_item, getColumnIndexFromOffset(x)); } } else { - selectItem(hit_item); + selectItem(hit_item, getColumnIndexFromOffset(x)); } selection_changed = mSelectionChanged; @@ -2110,8 +2150,29 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) { LLScrollListItem* item = hitItem(x, y); if (item) - { - mouseOverHighlightNthItem(getItemIndex(item)); + { + mouseOverHighlightNthItem(getItemIndex(item)); + switch (mSelectionType) + { + case CELL: + item->setHoverCell(getColumnIndexFromOffset(x)); + break; + case HEADER: + { + S32 cell = getColumnIndexFromOffset(x); + if (cell > 0) + { + item->setHoverCell(cell); + } + else + { + item->setHoverCell(-1); + } + break; + } + case ROW: + break; + } } else { @@ -2159,6 +2220,52 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) handled = TRUE; } break; + case KEY_LEFT: + if (mAllowKeyboardMovement || hasFocus()) + { + // TODO: support multi-select + LLScrollListItem *item = getFirstSelected(); + S32 cell = item->getSelectedCell(); + switch (mSelectionType) + { + case CELL: + if (cell < mColumns.size()) cell++; + break; + case HEADER: + if (cell == -1) cell = 1; + else if (cell > 1 && cell < mColumns.size()) cell++; // skip header + break; + case ROW: + cell = -1; + break; + } + item->setSelectedCell(cell); + handled = TRUE; + } + break; + case KEY_RIGHT: + if (mAllowKeyboardMovement || hasFocus()) + { + // TODO: support multi-select + LLScrollListItem *item = getFirstSelected(); + S32 cell = item->getSelectedCell(); + switch (mSelectionType) + { + case CELL: + if (cell >= 0) cell--; + break; + case HEADER: + if (cell > 1) cell--; + else if (cell == 1) cell = -1; // skip header + break; + case ROW: + cell = -1; + break; + } + item->setSelectedCell(cell); + handled = TRUE; + } + break; case KEY_PAGE_UP: if (mAllowKeyboardMovement || hasFocus()) { @@ -2327,7 +2434,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char) LLWString item_label = utf8str_to_wstring(cellp->getValue().asString()); if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char) { - selectItem(item); + selectItem(item, -1); mNeedsScroll = true; cellp->highlightText(0, 1); mSearchTimer.reset(); @@ -2379,7 +2486,7 @@ BOOL LLScrollListCtrl::isRepeatedChars(const LLWString& string) const return TRUE; } -void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_item) +void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, S32 cell, BOOL select_single_item) { if (!itemp) return; @@ -2398,6 +2505,18 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it deselectAllItems(TRUE); } itemp->setSelected(TRUE); + switch (mSelectionType) + { + case CELL: + itemp->setSelectedCell(cell); + break; + case HEADER: + itemp->setSelectedCell(cell <= 0 ? -1 : cell); + break; + case ROW: + itemp->setSelectedCell(-1); + break; + } mLastSelected = itemp; mSelectionChanged = true; } @@ -2658,7 +2777,7 @@ void LLScrollListCtrl::selectAll() LLScrollListItem *itemp = *iter; if( itemp->getEnabled() ) { - selectItem(itemp, FALSE); + selectItem(itemp, -1, FALSE); } } @@ -2787,6 +2906,8 @@ void LLScrollListCtrl::onClickColumn(void *userdata) LLScrollListCtrl *parent = info->mParentCtrl; if (!parent) return; + if (!parent->mCanSort) return; + S32 column_index = info->mIndex; LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex]; diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index b35a8608e7..bf1055c8dc 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -54,6 +54,18 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, public LLCtrlListInterface, public LLCtrlScrollInterface { public: + typedef enum e_selection_type + { + ROW, // default + CELL, // does not support multi-selection + HEADER, // when pointing to cells in column 0 will highlight whole row, otherwise cell, no multi-select + } ESelectionType; + + struct SelectionTypeNames : public LLInitParam::TypeValuesHelper<LLScrollListCtrl::ESelectionType, SelectionTypeNames> + { + static void declareValues(); + }; + struct Contents : public LLInitParam::Block<Contents> { Multiple<LLScrollListColumn::Params> columns; @@ -99,6 +111,8 @@ public: commit_on_keyboard_movement, mouse_wheel_opaque; + Optional<ESelectionType, SelectionTypeNames> selection_type; + // display flags Optional<bool> has_border, draw_heading, @@ -114,7 +128,8 @@ public: // sort and search behavior Optional<S32> search_column, sort_column; - Optional<bool> sort_ascending; + Optional<bool> sort_ascending, + can_sort; // whether user is allowed to sort // colors Optional<LLUIColor> fg_unselected_color, @@ -317,6 +332,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 handleScrollHWheel(S32 x, S32 y, S32 clicks); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); /*virtual*/ void setEnabled(BOOL enabled); /*virtual*/ void setFocus( BOOL b ); @@ -428,7 +444,7 @@ private: void updateLineHeightInsert(LLScrollListItem* item); void reportInvalidInput(); BOOL isRepeatedChars(const LLWString& string) const; - void selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE); + void selectItem(LLScrollListItem* itemp, S32 cell, BOOL single_select = TRUE); void deselectItem(LLScrollListItem* itemp); void commitIfChanged(); BOOL setSort(S32 column, BOOL ascending); @@ -453,9 +469,11 @@ private: bool mCommitOnKeyboardMovement; bool mCommitOnSelectionChange; bool mSelectionChanged; + ESelectionType mSelectionType; bool mNeedsScroll; bool mMouseWheelOpaque; bool mCanSelect; + bool mCanSort; // Whether user is allowed to sort bool mDisplayColumnHeaders; bool mColumnsDirty; bool mColumnWidthsDirty; diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp index df22c88afb..51c615dd00 100644 --- a/indra/llui/llscrolllistitem.cpp +++ b/indra/llui/llscrolllistitem.cpp @@ -40,6 +40,8 @@ LLScrollListItem::LLScrollListItem( const Params& p ) : mSelected(FALSE), mHighlighted(FALSE), + mHoverIndex(-1), + mSelectedIndex(-1), mEnabled(p.enabled), mUserdata(p.userdata), mItemValue(p.value) @@ -53,6 +55,28 @@ LLScrollListItem::~LLScrollListItem() mColumns.clear(); } +void LLScrollListItem::setSelected(BOOL b) +{ + mSelected = b; + mSelectedIndex = -1; +} + +void LLScrollListItem::setHighlighted(BOOL b) +{ + mHighlighted = b; + mHoverIndex = -1; +} + +void LLScrollListItem::setHoverCell(S32 cell) +{ + mHoverIndex = cell; +} + +void LLScrollListItem::setSelectedCell(S32 cell) +{ + mSelectedIndex = cell; +} + void LLScrollListItem::addColumn(const LLScrollListCell::Params& p) { mColumns.push_back(LLScrollListCell::create(p)); @@ -120,12 +144,21 @@ std::string LLScrollListItem::getContentsCSV() const } -void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) +void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& hover_color, const LLColor4& select_color, const LLColor4& highlight_color, S32 column_padding) { // draw background rect gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLRect bg_rect = rect; - gl_rect_2d( bg_rect, bg_color ); + if (mSelectedIndex < 0 && getSelected()) + { + // Whole item is highlighted/selected + gl_rect_2d(bg_rect, select_color); + } + else if (mHoverIndex < 0) + { + // Whole item is highlighted/selected + gl_rect_2d(bg_rect, hover_color); + } S32 cur_x = rect.mLeft; S32 num_cols = getNumColumns(); @@ -141,6 +174,25 @@ void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const { LLUI::translate((F32) cur_x, (F32) rect.mBottom); + if (mSelectedIndex == cur_col) + { + // select specific cell + LLRect highlight_rect(0, + cell->getHeight(), + cell->getWidth(), + 0); + gl_rect_2d(highlight_rect, select_color); + } + else if (mHoverIndex == cur_col) + { + // highlight specific cell + LLRect highlight_rect(0, + cell->getHeight(), + cell->getWidth() , + 0); + gl_rect_2d(highlight_rect, hover_color); + } + cell->draw( fg_color, highlight_color ); } LLUI::popMatrix(); diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h index 13655b5873..d2c3dd7721 100644 --- a/indra/llui/llscrolllistitem.h +++ b/indra/llui/llscrolllistitem.h @@ -77,15 +77,21 @@ public: virtual ~LLScrollListItem(); - void setSelected( BOOL b ) { mSelected = b; } + void setSelected( BOOL b ); BOOL getSelected() const { return mSelected; } void setEnabled( BOOL b ) { mEnabled = b; } BOOL getEnabled() const { return mEnabled; } - void setHighlighted( BOOL b ) { mHighlighted = b; } + void setHighlighted( BOOL b ); BOOL getHighlighted() const { return mHighlighted; } + void setSelectedCell( S32 cell ); + S32 getSelectedCell() const { return mSelectedIndex; } + + void setHoverCell( S32 cell ); + S32 getHoverCell() const { return mHoverIndex; } + void setUserdata( void* userdata ) { mUserdata = userdata; } void* getUserdata() const { return mUserdata; } @@ -107,14 +113,21 @@ public: std::string getContentsCSV() const; - virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); + virtual void draw(const LLRect& rect, + const LLColor4& fg_color, + const LLColor4& hover_color, // highlight/hover selection of whole item or cell + const LLColor4& select_color, // highlight/hover selection of whole item or cell + const LLColor4& highlight_color, // highlights contents of cells (ex: text) + S32 column_padding); protected: LLScrollListItem( const Params& ); private: BOOL mSelected; - BOOL mHighlighted; + BOOL mHighlighted; + S32 mHoverIndex; + S32 mSelectedIndex; BOOL mEnabled; void* mUserdata; LLSD mItemValue; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 22635f734e..e64078828b 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -3113,6 +3113,7 @@ BOOL LLTextSegment::handleRightMouseUp(S32 x, S32 y, MASK mask) { return FALSE; BOOL LLTextSegment::handleDoubleClick(S32 x, S32 y, MASK mask) { return FALSE; } BOOL LLTextSegment::handleHover(S32 x, S32 y, MASK mask) { return FALSE; } BOOL LLTextSegment::handleScrollWheel(S32 x, S32 y, S32 clicks) { return FALSE; } +BOOL LLTextSegment::handleScrollHWheel(S32 x, S32 y, S32 clicks) { return FALSE; } BOOL LLTextSegment::handleToolTip(S32 x, S32 y, MASK mask) { return FALSE; } const std::string& LLTextSegment::getName() const { diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 9831c35858..4239cdf43c 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -103,6 +103,7 @@ public: /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); /*virtual*/ const std::string& getName() const; /*virtual*/ void onMouseCaptureLost(); diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index df74e113e9..c98da0d410 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -137,13 +137,29 @@ void LLUICtrl::initFromParams(const Params& p) { LLControlVariable* control = findControl(p.enabled_controls.enabled); if (control) + { setEnabledControlVariable(control); + } + else + { + LL_WARNS() << "Failed to assign 'enabled' control variable to " << getName() + << ": control " << p.enabled_controls.enabled() + << " does not exist." << LL_ENDL; + } } else if(p.enabled_controls.disabled.isChosen()) { LLControlVariable* control = findControl(p.enabled_controls.disabled); if (control) + { setDisabledControlVariable(control); + } + else + { + LL_WARNS() << "Failed to assign 'disabled' control variable to " << getName() + << ": control " << p.enabled_controls.disabled() + << " does not exist." << LL_ENDL; + } } } if(p.controls_visibility.isProvided()) @@ -152,13 +168,29 @@ void LLUICtrl::initFromParams(const Params& p) { LLControlVariable* control = findControl(p.controls_visibility.visible); if (control) + { setMakeVisibleControlVariable(control); + } + else + { + LL_WARNS() << "Failed to assign visibility control variable to " << getName() + << ": control " << p.controls_visibility.visible() + << " does not exist." << LL_ENDL; + } } else if (p.controls_visibility.invisible.isChosen()) { LLControlVariable* control = findControl(p.controls_visibility.invisible); if (control) + { setMakeInvisibleControlVariable(control); + } + else + { + LL_WARNS() << "Failed to assign invisibility control variable to " << getName() + << ": control " << p.controls_visibility.invisible() + << " does not exist." << LL_ENDL; + } } } @@ -497,6 +529,11 @@ void LLUICtrl::setControlName(const std::string& control_name, LLView *context) if (!control_name.empty()) { LLControlVariable* control = context->findControl(control_name); + if (!control) + { + LL_WARNS() << "Failed to assign control variable to " << getName() + << ": control "<< control_name << " does not exist." << LL_ENDL; + } setControlVariable(control); } } diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 03d946f1b7..f740f14e4d 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -160,8 +160,8 @@ public: LLXMLNodePtr root_node; if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node)) - { - LL_WARNS() << "Couldn't parse XUI file: " << instance().getCurFileName() << LL_ENDL; + { + LL_WARNS() << "Couldn't parse XUI from path: " << instance().getCurFileName() << ", from filename: " << filename << LL_ENDL; goto fail; } diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 63ed427ab5..333d03f208 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -454,13 +454,13 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const } // -// LLUrlEntrySeconlifeURL Describes *secondlife.com/ and *lindenlab.com/ urls to substitute icon 'hand.png' before link +// LLUrlEntrySeconlifeURL Describes *secondlife.com/ *lindenlab.com/ and *tilia-inc.com/ urls to substitute icon 'hand.png' before link // LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL() { - mPattern = boost::regex("((http://([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com)" + mPattern = boost::regex("((http://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com)" "|" - "(https://([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(:\\d{1,5})?))" + "(https://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(:\\d{1,5})?))" "\\/\\S*", boost::regex::perl|boost::regex::icase); @@ -495,11 +495,11 @@ std::string LLUrlEntrySecondlifeURL::getTooltip(const std::string &url) const } // -// LLUrlEntrySimpleSecondlifeURL Describes *secondlife.com and *lindenlab.com urls to substitute icon 'hand.png' before link +// LLUrlEntrySimpleSecondlifeURL Describes *secondlife.com *lindenlab.com and *tilia-inc.com urls to substitute icon 'hand.png' before link // LLUrlEntrySimpleSecondlifeURL::LLUrlEntrySimpleSecondlifeURL() { - mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(?!\\S)", + mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(?!\\S)", boost::regex::perl|boost::regex::icase); mIcon = "Hand"; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 2a190365b3..771d32d2fc 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -875,10 +875,16 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask) F32 timeout = LLToolTipMgr::instance().toolTipVisible() ? LLUI::getInstance()->mSettingGroups["config"]->getF32( "ToolTipFastDelay" ) : LLUI::getInstance()->mSettingGroups["config"]->getF32( "ToolTipDelay" ); - LLToolTipMgr::instance().show(LLToolTip::Params() - .message(tooltip) - .sticky_rect(calcScreenRect()) - .delay_time(timeout)); + + // Even if we don't show tooltips, consume the event, nothing below should show tooltip + bool allow_ui_tooltips = LLUI::sSettingGroups["config"]->getBOOL( "BasicUITooltips" ); + if (allow_ui_tooltips) + { + LLToolTipMgr::instance().show(LLToolTip::Params() + .message(tooltip) + .sticky_rect(calcScreenRect()) + .delay_time(timeout)); + } handled = TRUE; } @@ -1054,6 +1060,11 @@ BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks) return childrenHandleScrollWheel( x, y, clicks ) != NULL; } +BOOL LLView::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + return childrenHandleScrollHWheel( x, y, clicks ) != NULL; +} + BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask) { return childrenHandleRightMouseDown( x, y, mask ) != NULL; @@ -1079,6 +1090,11 @@ LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) return childrenHandleMouseEvent(&LLView::handleScrollWheel, x, y, clicks, false); } +LLView* LLView::childrenHandleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + return childrenHandleMouseEvent(&LLView::handleScrollHWheel, x, y, clicks, false); +} + // Called during downward traversal LLView* LLView::childrenHandleKey(KEY key, MASK mask) { diff --git a/indra/llui/llview.h b/indra/llui/llview.h index e36ca7c8c6..db81900aaf 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -426,6 +426,7 @@ public: /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ BOOL handleScrollHWheel(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, MASK mask); @@ -556,6 +557,7 @@ protected: LLView* childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask); LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask); LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks); + LLView* childrenHandleScrollHWheel(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, MASK mask); diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 119cbebc81..3c34fd269e 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -36,6 +36,11 @@ #include <boost/regex.hpp> +#if LL_WINDOWS +// because something pulls in window and lldxdiag dependencies which in turn need wbemuuid.lib + #pragma comment(lib, "wbemuuid.lib") +#endif + // namespace LLExperienceCache // { |