diff options
author | Aaron Brashears <aaronb@lindenlab.com> | 2007-06-13 18:02:37 +0000 |
---|---|---|
committer | Aaron Brashears <aaronb@lindenlab.com> | 2007-06-13 18:02:37 +0000 |
commit | f118e7c80b95d8c0a0c8abb14ff379b6697e01b6 (patch) | |
tree | db55a74f8d18b3c366608a537e2a32f6d089d56f /indra/llui | |
parent | 680667d4bdca7e2a6df15cd6f16f34c12c97da8e (diff) |
result of merge manually performed through diff and patch. svn diff svn+ssh://svn/svn/linden/release@63615 svn+ssh://svn/svn/linden/branches/release-candidate@63637 | patch -p0 in release
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/llbutton.cpp | 78 | ||||
-rw-r--r-- | indra/llui/llbutton.h | 7 | ||||
-rw-r--r-- | indra/llui/llfloater.cpp | 73 | ||||
-rw-r--r-- | indra/llui/llfloater.h | 10 | ||||
-rw-r--r-- | indra/llui/llscrolllistctrl.cpp | 51 | ||||
-rw-r--r-- | indra/llui/llscrolllistctrl.h | 8 | ||||
-rw-r--r-- | indra/llui/lltabcontainer.cpp | 54 | ||||
-rw-r--r-- | indra/llui/lltabcontainer.h | 7 | ||||
-rw-r--r-- | indra/llui/lltexteditor.cpp | 32 | ||||
-rw-r--r-- | indra/llui/lltexteditor.h | 2 | ||||
-rw-r--r-- | indra/llui/llui.h | 91 |
11 files changed, 360 insertions, 53 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index ddd81e77b3..d28cf96fa0 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -595,6 +595,56 @@ void LLButton::draw() gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4::pink1, FALSE); } + // draw overlay image + if (mImageOverlay.notNull()) + { + const S32 IMG_PAD = 4; + // get max width and height (discard level 0) + S32 overlay_width = mImageOverlay->getWidth(0); + S32 overlay_height = mImageOverlay->getHeight(0); + + F32 scale_factor = llmin((F32)mRect.getWidth() / (F32)overlay_width, (F32)mRect.getHeight() / (F32)overlay_height, 1.f); + overlay_width = llround((F32)overlay_width * scale_factor); + overlay_height = llround((F32)overlay_height * scale_factor); + + S32 center_x = getLocalRect().getCenterX(); + S32 center_y = getLocalRect().getCenterY(); + + switch(mImageOverlayAlignment) + { + case LLFontGL::LEFT: + gl_draw_scaled_image( + IMG_PAD, + center_y - (overlay_height / 2), + overlay_width, + overlay_height, + mImageOverlay, + LLColor4::white); + break; + case LLFontGL::HCENTER: + gl_draw_scaled_image( + center_x - (overlay_width / 2), + center_y - (overlay_height / 2), + overlay_width, + overlay_height, + mImageOverlay, + LLColor4::white); + break; + case LLFontGL::RIGHT: + gl_draw_scaled_image( + mRect.getWidth() - IMG_PAD - overlay_width, + center_y - (overlay_height / 2), + overlay_width, + overlay_height, + mImageOverlay, + LLColor4::white); + break; + default: + // draw nothing + break; + } + } + // Draw label if( !label.empty() ) { @@ -806,6 +856,21 @@ void LLButton::setHoverImages( const LLString& image_name, const LLString& selec setImageHoverSelected(selected_name); } +void LLButton::setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment) +{ + if (image_name.empty()) + { + mImageOverlay = NULL; + } + else + { + LLUUID overlay_image_id = LLUI::findAssetUUIDByName(image_name); + mImageOverlay = LLUI::sImageProvider->getUIImageByID(overlay_image_id); + mImageOverlayAlignment = alignment; + } +} + + void LLButton::onMouseCaptureLost() { mMouseDownTimer.stop(); @@ -978,6 +1043,18 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa LLString image_disabled; if (node->hasAttribute("image_disabled")) node->getAttributeString("image_disabled",image_disabled); + LLString image_overlay; + node->getAttributeString("image_overlay", image_overlay); + + LLFontGL::HAlign image_overlay_alignment = LLFontGL::HCENTER; + LLString image_overlay_alignment_string; + if (node->hasAttribute("image_overlay_alignment")) + { + node->getAttributeString("image_overlay_alignment", image_overlay_alignment_string); + image_overlay_alignment = LLFontGL::hAlignFromName(image_overlay_alignment_string); + } + + LLButton *button = new LLButton(name, LLRect(), image_unselected, @@ -1000,6 +1077,7 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa if(image_disabled != LLString::null) button->setImageDisabled(image_disabled); + if(image_overlay != LLString::null) button->setImageOverlay(image_overlay, image_overlay_alignment); if (node->hasAttribute("halign")) { diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 9048358bd8..470c34fb64 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -122,6 +122,10 @@ public: void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; } + void setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER); + LLPointer<LLImageGL> getImageOverlay() { return mImageOverlay; } + + virtual void setValue(const LLSD& value ); virtual LLSD getValue() const; @@ -182,6 +186,9 @@ protected: F32 mHeldDownDelay; // seconds, after which held-down callbacks get called S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called + LLPointer<LLImageGL> mImageOverlay; + LLFontGL::HAlign mImageOverlayAlignment; + LLPointer<LLImageGL> mImageUnselected; LLUIString mUnselectedLabel; LLColor4 mUnselectedLabelColor; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index fd8947c594..66642d8f34 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -555,17 +555,20 @@ void LLFloater::close(bool app_quitting) cleanupHandles(); gFocusMgr.clearLastFocusForGroup(this); - // Do this early, so UI controls will commit before the - // window is taken down. - releaseFocus(); - - // give focus to dependee floater if it exists, and we had focus first - if (isDependent()) + if (hasFocus()) { - LLFloater* dependee = LLFloater::getFloaterByHandle(mDependeeHandle); - if (dependee && !dependee->isDead()) + // Do this early, so UI controls will commit before the + // window is taken down. + releaseFocus(); + + // give focus to dependee floater if it exists, and we had focus first + if (isDependent()) { - dependee->setFocus(TRUE); + LLFloater* dependee = LLFloater::getFloaterByHandle(mDependeeHandle); + if (dependee && !dependee->isDead()) + { + dependee->setFocus(TRUE); + } } } @@ -1150,6 +1153,28 @@ BOOL LLFloater::getEditModeEnabled() return sEditModeEnabled; } +//static +void LLFloater::show(LLFloater* floaterp) +{ + if (floaterp) floaterp->open(); +} + +//static +void LLFloater::hide(LLFloater* floaterp) +{ + if (floaterp) floaterp->close(); +} + +//static +BOOL LLFloater::visible(LLFloater* floaterp) +{ + if (floaterp) + { + return floaterp->isInVisibleChain(); + } + return FALSE; +} + // static void LLFloater::onClickMinimize(void *userdata) { @@ -2352,7 +2377,7 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) LLMultiFloater::LLMultiFloater() : mTabContainer(NULL), mTabPos(LLTabContainerCommon::TOP), - mAutoResize(FALSE) + mAutoResize(TRUE) { } @@ -2360,7 +2385,7 @@ LLMultiFloater::LLMultiFloater() : LLMultiFloater::LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos) : mTabContainer(NULL), mTabPos(tab_pos), - mAutoResize(FALSE) + mAutoResize(TRUE) { } @@ -2574,15 +2599,12 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, floaterp->setCanResize(FALSE); floaterp->setCanDrag(FALSE); - S32 new_width = llmax(mRect.getWidth(), floaterp->getRect().getWidth()); - S32 new_height = llmax(mRect.getHeight(), floaterp->getRect().getHeight() + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT); - - reshape(new_width, new_height); - //add the panel, add it to proper maps mTabContainer->addTabPanel(floaterp, floaterp->getTitle(), FALSE, onTabSelected, this, 0, FALSE, insertion_point); mFloaterDataMap[floaterp->getHandle()] = floater_data; + resizeToContents(); + if ( select_added_floater ) { mTabContainer->selectLastTab(); @@ -2656,10 +2678,7 @@ void LLMultiFloater::removeFloater(LLFloater* floaterp) floaterp->setBackgroundVisible(TRUE); floaterp->setHost(NULL); - if (mAutoResize) - { - resizeToContents(); - } + resizeToContents(); tabOpen((LLFloater*)mTabContainer->getCurrentPanel(), false); } @@ -2709,7 +2728,8 @@ BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) if (key == 'W') { LLFloater* floater = getActiveFloater(); - if (floater && floater->canClose()) + // is user closeable and is system closeable + if (floater && floater->canClose() && floater->isCloseable()) { floater->close(); } @@ -2828,10 +2848,17 @@ void LLMultiFloater::resizeToContents() S32 cur_height = mRect.getHeight(); - reshape(new_width, new_height); + if (mAutoResize) + { + reshape(new_width, new_height); + } + else + { + reshape(llmax(new_min_width, mRect.getWidth()), llmax(new_min_height, mRect.getHeight())); + } // make sure upper left corner doesn't move - translate(0, cur_height - new_height); + translate(0, cur_height - mRect.getHeight()); // Try to keep whole view onscreen, don't allow partial offscreen. gFloaterView->adjustToFitScreen(this, FALSE); diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 90063108f5..c71f3df3e8 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -192,6 +192,10 @@ public: static BOOL getEditModeEnabled(); static LLMultiFloater* getFloaterHost() {return sHostp; } + static void show(LLFloater* floaterp); + static void hide(LLFloater* floaterp); + static BOOL visible(LLFloater* floaterp); + static LLFloater* getFloaterByHandle(LLViewHandle handle); protected: @@ -259,7 +263,6 @@ protected: std::vector<LLView*> mMinimizedHiddenChildren; }; - ///////////////////////////////////////////////////////////// // LLFloaterView // Parent of all floating panels @@ -334,8 +337,8 @@ public: LLMultiFloater(); LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos); LLMultiFloater(const LLString& name); - LLMultiFloater(const LLString& name, const LLRect& rect, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = FALSE); - LLMultiFloater(const LLString& name, const LLString& rect_control, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = FALSE); + LLMultiFloater(const LLString& name, const LLRect& rect, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE); + LLMultiFloater(const LLString& name, const LLString& rect_control, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE); virtual ~LLMultiFloater(); virtual BOOL postBuild(); @@ -396,3 +399,4 @@ extern LLFloaterView* gFloaterView; #endif // LL_FLOATER_H + diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 94d5d7ae75..4c01387941 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -79,7 +79,7 @@ protected: // LLScrollListIcon // LLScrollListIcon::LLScrollListIcon(LLImageGL* icon, S32 width, LLUUID image_id) : -mIcon(icon), mImageUUID(image_id.asString()) +mIcon(icon), mColor(LLColor4::white), mImageUUID(image_id.asString()) { if (width) { @@ -95,6 +95,16 @@ LLScrollListIcon::~LLScrollListIcon() { } +void LLScrollListIcon::setColor(const LLColor4& color) +{ + mColor = color; +} + +void LLScrollListIcon::drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const +{ + gl_draw_image(0, 0, mIcon, mColor); +} + // // LLScrollListCheck // @@ -188,6 +198,15 @@ LLScrollListText::~LLScrollListText() delete mColor; } +void LLScrollListText::setColor(const LLColor4& color) +{ + if (!mColor) + { + mColor = new LLColor4(); + } + *mColor = color; +} + void LLScrollListText::setText(const LLString& text) { mText = text; @@ -2789,6 +2808,8 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p LLString fontname = (*itor)["font"].asString(); LLString fontstyle = (*itor)["font-style"].asString(); LLString type = (*itor)["type"].asString(); + BOOL has_color = (*itor).has("color"); + LLColor4 color = ((*itor)["color"]); const LLFontGL *font = gResMgr->getRes(fontname); if (!font) @@ -2801,21 +2822,41 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p { LLUUID image_id = value.asUUID(); LLImageGL* icon = LLUI::sImageProvider->getUIImageByID(image_id); - new_item->setColumn(index, new LLScrollListIcon(icon, width, image_id)); + LLScrollListIcon* cell = new LLScrollListIcon(icon, width, image_id); + if (has_color) + { + cell->setColor(color); + } + new_item->setColumn(index, cell); } else if (type == "checkbox") { LLCheckBoxCtrl* ctrl = new LLCheckBoxCtrl(value.asString(), LLRect(0, 0, width, width), "label"); - new_item->setColumn(index, new LLScrollListCheck(ctrl,width)); + LLScrollListCheck* cell = new LLScrollListCheck(ctrl,width); + if (has_color) + { + cell->setColor(color); + } + new_item->setColumn(index, cell); } else if (type == "separator") { - new_item->setColumn(index, new LLScrollListSeparator(width)); + LLScrollListSeparator* cell = new LLScrollListSeparator(width); + if (has_color) + { + cell->setColor(color); + } + new_item->setColumn(index, cell); } else { - new_item->setColumn(index, new LLScrollListText(value.asString(), font, width, font_style, font_alignment)); + LLScrollListText* cell = new LLScrollListText(value.asString(), font, width, font_style, font_alignment); + if (has_color) + { + cell->setColor(color); + } + new_item->setColumn(index, cell); if (columnp->mHeader && !value.asString().empty()) { columnp->mHeader->setHasResizableElement(TRUE); diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index de9b58bd1e..dff522bc0b 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -43,6 +43,7 @@ public: virtual void setWidth(S32 width) = 0; virtual void highlightText(S32 offset, S32 num_chars) {} virtual BOOL isText() = 0; + virtual void setColor(const LLColor4&) = 0; virtual BOOL handleClick() { return FALSE; } virtual void setEnabled(BOOL enable) { } @@ -57,6 +58,7 @@ public: virtual S32 getWidth() const {return mWidth;} virtual S32 getHeight() const { return 5; }; virtual void setWidth(S32 width) {mWidth = width; } + virtual void setColor(const LLColor4&) {}; virtual BOOL isText() { return FALSE; } protected: @@ -77,6 +79,7 @@ public: virtual const BOOL getVisible() const { return mVisible; } virtual void highlightText(S32 offset, S32 num_chars) {mHighlightOffset = offset; mHighlightCount = num_chars;} void setText(const LLString& text); + virtual void setColor(const LLColor4&); virtual BOOL isText() { return TRUE; } private: @@ -100,18 +103,20 @@ class LLScrollListIcon : public LLScrollListCell public: LLScrollListIcon( LLImageGL* icon, S32 width = 0, LLUUID image_id = LLUUID::null); /*virtual*/ ~LLScrollListIcon(); - virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const { gl_draw_image(0, 0, mIcon); } + virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const; virtual S32 getWidth() const { return mWidth; } virtual S32 getHeight() const { return mIcon->getHeight(); } virtual const LLString& getText() const { return mImageUUID; } virtual const LLString& getTextLower() const { return mImageUUID; } virtual void setWidth(S32 width) { mWidth = width; } + virtual void setColor(const LLColor4&); virtual BOOL isText() { return FALSE; } private: LLPointer<LLImageGL> mIcon; LLString mImageUUID; S32 mWidth; + LLColor4 mColor; }; class LLScrollListCheck : public LLScrollListCell @@ -126,6 +131,7 @@ public: virtual BOOL handleClick(); virtual void setEnabled(BOOL enable) { if (mCheckBox) mCheckBox->setEnabled(enable); } + virtual void setColor(const LLColor4& color) {}; LLCheckBoxCtrl* getCheckBox() { return mCheckBox; } virtual BOOL isText() { return FALSE; } diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index a5bad91670..2844640291 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -57,7 +57,8 @@ LLTabContainerCommon::LLTabContainerCommon( mCallbackUserdata( callback_userdata ), mTitleBox(NULL), mTopBorderHeight(LLPANEL_BORDER_WIDTH), - mTabPosition(pos) + mTabPosition(pos), + mLockedTabCount(0) { setMouseOpaque(FALSE); } @@ -122,6 +123,13 @@ void LLTabContainerCommon::addPlaceholder(LLPanel* child, const LLString& label) addTabPanel(child, label, FALSE, NULL, NULL, 0, TRUE); } +void LLTabContainerCommon::lockTabs() +{ + // count current tabs and ensure no new tabs get + // inserted between them + mLockedTabCount = getTabCount(); +} + void LLTabContainerCommon::removeTabPanel(LLPanel* child) { BOOL has_focus = gFocusMgr.childHasKeyboardFocus(this); @@ -144,6 +152,10 @@ void LLTabContainerCommon::removeTabPanel(LLPanel* child) break; } } + + // make sure we don't have more locked tabs than we have tabs + mLockedTabCount = llmin(getTabCount(), mLockedTabCount); + if (mCurrentTabIdx >= (S32)mTabList.size()) { mCurrentTabIdx = mTabList.size()-1; @@ -506,6 +518,15 @@ void LLTabContainerCommon::setTabPanelFlashing(LLPanel* child, BOOL state ) } } +void LLTabContainerCommon::setTabImage(LLPanel* child, std::string img_name) +{ + LLTabTuple* tuple = getTabByPanel(child); + if( tuple ) + { + tuple->mButton->setImageOverlay(img_name, LLFontGL::RIGHT); + } +} + void LLTabContainerCommon::setTitle(const LLString& title) { if (mTitleBox) @@ -667,12 +688,12 @@ void LLTabContainerCommon::insertTuple(LLTabTuple * tuple, eInsertionPoint inser { case START: // insert the new tab in the front of the list - mTabList.insert(mTabList.begin(), tuple); + mTabList.insert(mTabList.begin() + mLockedTabCount, tuple); break; case RIGHT_OF_CURRENT: - // insert the new tab after the current tab + // insert the new tab after the current tab (but not before mLockedTabCount) { - tuple_list_t::iterator current_iter = mTabList.begin() + mCurrentTabIdx + 1; + tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx + 1); mTabList.insert(current_iter, tuple); } break; @@ -1229,6 +1250,7 @@ void LLTabContainer::draw() for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { LLTabTuple* tuple = *iter; + tuple->mButton->translate( left - tuple->mButton->getRect().mLeft, 0 ); left += tuple->mButton->getRect().getWidth(); @@ -1576,3 +1598,27 @@ BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDrag return LLView::handleDragAndDrop(x, y, mask, drop, type, cargo_data, accept, tooltip); } + +void LLTabContainer::setTabImage(LLPanel* child, std::string image_name) +{ + LLTabTuple* tuple = getTabByPanel(child); + if( tuple ) + { + tuple->mButton->setImageOverlay(image_name, LLFontGL::RIGHT); + + const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); + // remove current width from total tab strip width + mTotalTabWidth -= tuple->mButton->getRect().getWidth(); + + S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? + tuple->mButton->getImageOverlay()->getWidth(0) : + 0; + tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + image_overlay_width, mMinTabWidth, mMaxTabWidth), + tuple->mButton->getRect().getHeight()); + // add back in button width to total tab strip width + mTotalTabWidth += tuple->mButton->getRect().getWidth(); + + // tabs have changed size, might need to scroll to see current tab + updateMaxScrollPos(); + } +}
\ No newline at end of file diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index aa4c1c608a..fbb73b951b 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -67,7 +67,8 @@ public: BOOL placeholder = FALSE, eInsertionPoint insertion_point = END) = 0; virtual void addPlaceholder(LLPanel* child, const LLString& label); - + virtual void lockTabs(); + virtual void enableTabButton(S32 which, BOOL enable); virtual void removeTabPanel( LLPanel* child ); @@ -93,6 +94,7 @@ public: BOOL getTabPanelFlashing(LLPanel* child); void setTabPanelFlashing(LLPanel* child, BOOL state); + virtual void setTabImage(LLPanel* child, std::string img_name); void setTitle( const LLString& title ); const LLString getPanelTitle(S32 index); @@ -160,6 +162,7 @@ protected: S32 mTopBorderHeight; TabPosition mTabPosition; + S32 mLockedTabCount; protected: void scrollPrev(); @@ -201,7 +204,7 @@ public: /*virtual*/ void removeTabPanel( LLPanel* child ); /*virtual*/ void setPanelTitle(S32 index, const LLString& title); - + /*virtual*/ void setTabImage(LLPanel* child, std::string img_name); /*virtual*/ void setRightTabBtnOffset( S32 offset ); /*virtual*/ void setMinTabWidth(S32 width); diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 9363415dc2..f8e1e33cad 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -331,7 +331,7 @@ LLTextEditor::LLTextEditor( mBorder = new LLViewBorder( "text ed border", LLRect(0, mRect.getHeight(), mRect.getWidth(), 0), LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, UI_TEXTEDITOR_BORDER ); addChild( mBorder ); - setText(default_text); + appendText(default_text, FALSE, FALSE); mParseHTML=FALSE; mHTML=""; @@ -2630,7 +2630,8 @@ void LLTextEditor::drawSelectionBackground() { LLGLSNoTexture no_texture; const LLColor4& color = mReadOnly ? mReadOnlyBgColor : mWriteableBgColor; - glColor3f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2] ); + F32 alpha = hasFocus() ? 1.f : 0.5f; + glColor4f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], alpha ); if( selection_left_y == selection_right_y ) { @@ -3357,6 +3358,14 @@ void LLTextEditor::appendColoredText(const LLString &new_text, style.setVisible(true); style.setColor(color); style.setFontName(font_name); + appendStyledText(new_text, allow_undo, prepend_newline, &style); +} + +void LLTextEditor::appendStyledText(const LLString &new_text, + bool allow_undo, + bool prepend_newline, + const LLStyle* style) +{ if(mParseHTML) { @@ -3367,10 +3376,13 @@ void LLTextEditor::appendColoredText(const LLString &new_text, LLStyle html; html.setVisible(true); html.setColor(mLinkColor); - html.setFontName(font_name); + if (style) + { + html.setFontName(style->getFontString()); + } html.mUnderline = TRUE; - if (start > 0) appendText(text.substr(0,start),allow_undo, prepend_newline, &style); + if (start > 0) appendText(text.substr(0,start),allow_undo, prepend_newline, style); html.setLinkHREF(text.substr(start,end-start)); appendText(text.substr(start, end-start),allow_undo, prepend_newline, &html); if (end < (S32)text.length()) @@ -3383,22 +3395,14 @@ void LLTextEditor::appendColoredText(const LLString &new_text, break; } } - if (end < (S32)text.length()) appendText(text,allow_undo, prepend_newline, &style); + if (end < (S32)text.length()) appendText(text,allow_undo, prepend_newline, style); } else { - appendText(new_text, allow_undo, prepend_newline, &style); + appendText(new_text, allow_undo, prepend_newline, style); } } -void LLTextEditor::appendStyledText(const LLString &new_text, - bool allow_undo, - bool prepend_newline, - const LLStyle &style) -{ - appendText(new_text, allow_undo, prepend_newline, &style); -} - // Appends new text to end of document void LLTextEditor::appendText(const LLString &new_text, bool allow_undo, bool prepend_newline, const LLStyle* segment_style) diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 7454b192fd..1a82d3e8c8 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -139,7 +139,7 @@ public: // if styled text starts a line, you need to prepend a newline. void appendStyledText(const LLString &new_text, bool allow_undo, bool prepend_newline, - const LLStyle &style); + const LLStyle* style); // Removes text from the end of document // Does not change highlight or cursor position. diff --git a/indra/llui/llui.h b/indra/llui/llui.h index c8c244072e..dbe79338e5 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -255,4 +255,95 @@ typedef enum e_widget_type WIDGET_TYPE_COUNT } EWidgetType; +// Manages generation of UI elements by LLSD, such that there is +// only one instance per uniquely identified LLSD parameter +// Class T is the instance type being managed, and INSTANCE_ADDAPTOR +// wraps an instance of the class with handlers for show/hide semantics, etc. +template <class T, class INSTANCE_ADAPTOR = T> +class LLUIInstanceMgr +{ +public: + LLUIInstanceMgr() + { + } + + virtual ~LLUIInstanceMgr() + { + } + + // default show and hide methods + static T* showInstance(const LLSD& seed) + { + T* instance = INSTANCE_ADAPTOR::getInstance(seed); + INSTANCE_ADAPTOR::show(instance); + return instance; + } + + static void hideInstance(const LLSD& seed) + { + T* instance = INSTANCE_ADAPTOR::getInstance(seed); + INSTANCE_ADAPTOR::hide(instance); + } + + static void toggleInstance(const LLSD& seed) + { + if (!INSTANCE_ADAPTOR::instanceVisible(seed)) + { + INSTANCE_ADAPTOR::showInstance(seed); + } + else + { + INSTANCE_ADAPTOR::hideInstance(seed); + } + } + + static BOOL instanceVisible(const LLSD& seed) + { + T* instance = INSTANCE_ADAPTOR::findInstance(seed); + return instance != NULL && INSTANCE_ADAPTOR::visible(instance); + } + + static T* getInstance(const LLSD& seed) + { + T* instance = INSTANCE_ADAPTOR::findInstance(seed); + if (instance == NULL) + { + instance = INSTANCE_ADAPTOR::createInstance(seed); + } + return instance; + } +}; + +// Creates a UI singleton by ignoring the identifying parameter +// and always generating the same instance via the LLUIInstanceMgr interface. +// Note that since UI elements can be destroyed by their hierarchy, this singleton +// pattern uses a static pointer to an instance that will be re-created as needed. +template <class T, class INSTANCE_ADAPTOR = T> +class LLUISingleton: public LLUIInstanceMgr<T, INSTANCE_ADAPTOR> +{ +public: + // default constructor assumes T is derived from LLUISingleton (a true singleton) + LLUISingleton() : LLUIInstanceMgr<T, INSTANCE_ADAPTOR>() { sInstance = (T*)this; } + ~LLUISingleton() { sInstance = NULL; } + + static T* findInstance(const LLSD& seed) + { + return sInstance; + } + + static T* createInstance(const LLSD& seed) + { + if (sInstance == NULL) + { + sInstance = new T(seed); + } + return sInstance; + } + +protected: + static T* sInstance; +}; + +template <class T, class U> T* LLUISingleton<T,U>::sInstance = NULL; + #endif |