diff options
Diffstat (limited to 'linden/indra/llui')
-rw-r--r-- | linden/indra/llui/llalertdialog.cpp | 9 | ||||
-rw-r--r-- | linden/indra/llui/llbutton.cpp | 78 | ||||
-rw-r--r-- | linden/indra/llui/llbutton.h | 7 | ||||
-rw-r--r-- | linden/indra/llui/llfloater.cpp | 73 | ||||
-rw-r--r-- | linden/indra/llui/llfloater.h | 10 | ||||
-rw-r--r-- | linden/indra/llui/lllineeditor.cpp | 81 | ||||
-rw-r--r-- | linden/indra/llui/lllineeditor.h | 10 | ||||
-rw-r--r-- | linden/indra/llui/llmemberlistener.h | 1 | ||||
-rw-r--r-- | linden/indra/llui/llpanel.cpp | 17 | ||||
-rw-r--r-- | linden/indra/llui/llpanel.h | 2 | ||||
-rw-r--r-- | linden/indra/llui/llscrolllistctrl.cpp | 51 | ||||
-rw-r--r-- | linden/indra/llui/llscrolllistctrl.h | 8 | ||||
-rw-r--r-- | linden/indra/llui/lltabcontainer.cpp | 54 | ||||
-rw-r--r-- | linden/indra/llui/lltabcontainer.h | 7 | ||||
-rw-r--r-- | linden/indra/llui/lltexteditor.cpp | 57 | ||||
-rw-r--r-- | linden/indra/llui/lltexteditor.h | 3 | ||||
-rw-r--r-- | linden/indra/llui/llui.h | 91 | ||||
-rw-r--r-- | linden/indra/llui/lluictrlfactory.cpp | 11 | ||||
-rw-r--r-- | linden/indra/llui/lluictrlfactory.h | 4 | ||||
-rw-r--r-- | linden/indra/llui/llview.cpp | 20 | ||||
-rw-r--r-- | linden/indra/llui/llview.h | 4 |
21 files changed, 517 insertions, 81 deletions
diff --git a/linden/indra/llui/llalertdialog.cpp b/linden/indra/llui/llalertdialog.cpp index 547efae..8950fcd 100644 --- a/linden/indra/llui/llalertdialog.cpp +++ b/linden/indra/llui/llalertdialog.cpp | |||
@@ -783,10 +783,11 @@ bool LLAlertDialog::parseAlerts(const LLString& xml_filename, LLControlGroup* se | |||
783 | // label= | 783 | // label= |
784 | LLString name; | 784 | LLString name; |
785 | child->getAttributeString("name", name); | 785 | child->getAttributeString("name", name); |
786 | if (name.empty()) | 786 | |
787 | { | 787 | //always set to alert_name for the sake of i18n |
788 | name = alert_name; | 788 | //if (name.empty()) |
789 | } | 789 | name = alert_name; |
790 | |||
790 | if (xml_template) | 791 | if (xml_template) |
791 | { | 792 | { |
792 | xml_template->mIgnorable = LLAlertDialog::IGNORE_USE_DEFAULT; | 793 | xml_template->mIgnorable = LLAlertDialog::IGNORE_USE_DEFAULT; |
diff --git a/linden/indra/llui/llbutton.cpp b/linden/indra/llui/llbutton.cpp index 1d44537..de8b82e 100644 --- a/linden/indra/llui/llbutton.cpp +++ b/linden/indra/llui/llbutton.cpp | |||
@@ -615,6 +615,56 @@ void LLButton::draw() | |||
615 | gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4::pink1, FALSE); | 615 | gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4::pink1, FALSE); |
616 | } | 616 | } |
617 | 617 | ||
618 | // draw overlay image | ||
619 | if (mImageOverlay.notNull()) | ||
620 | { | ||
621 | const S32 IMG_PAD = 4; | ||
622 | // get max width and height (discard level 0) | ||
623 | S32 overlay_width = mImageOverlay->getWidth(0); | ||
624 | S32 overlay_height = mImageOverlay->getHeight(0); | ||
625 | |||
626 | F32 scale_factor = llmin((F32)mRect.getWidth() / (F32)overlay_width, (F32)mRect.getHeight() / (F32)overlay_height, 1.f); | ||
627 | overlay_width = llround((F32)overlay_width * scale_factor); | ||
628 | overlay_height = llround((F32)overlay_height * scale_factor); | ||
629 | |||
630 | S32 center_x = getLocalRect().getCenterX(); | ||
631 | S32 center_y = getLocalRect().getCenterY(); | ||
632 | |||
633 | switch(mImageOverlayAlignment) | ||
634 | { | ||
635 | case LLFontGL::LEFT: | ||
636 | gl_draw_scaled_image( | ||
637 | IMG_PAD, | ||
638 | center_y - (overlay_height / 2), | ||
639 | overlay_width, | ||
640 | overlay_height, | ||
641 | mImageOverlay, | ||
642 | LLColor4::white); | ||
643 | break; | ||
644 | case LLFontGL::HCENTER: | ||
645 | gl_draw_scaled_image( | ||
646 | center_x - (overlay_width / 2), | ||
647 | center_y - (overlay_height / 2), | ||
648 | overlay_width, | ||
649 | overlay_height, | ||
650 | mImageOverlay, | ||
651 | LLColor4::white); | ||
652 | break; | ||
653 | case LLFontGL::RIGHT: | ||
654 | gl_draw_scaled_image( | ||
655 | mRect.getWidth() - IMG_PAD - overlay_width, | ||
656 | center_y - (overlay_height / 2), | ||
657 | overlay_width, | ||
658 | overlay_height, | ||
659 | mImageOverlay, | ||
660 | LLColor4::white); | ||
661 | break; | ||
662 | default: | ||
663 | // draw nothing | ||
664 | break; | ||
665 | } | ||
666 | } | ||
667 | |||
618 | // Draw label | 668 | // Draw label |
619 | if( !label.empty() ) | 669 | if( !label.empty() ) |
620 | { | 670 | { |
@@ -826,6 +876,21 @@ void LLButton::setHoverImages( const LLString& image_name, const LLString& selec | |||
826 | setImageHoverSelected(selected_name); | 876 | setImageHoverSelected(selected_name); |
827 | } | 877 | } |
828 | 878 | ||
879 | void LLButton::setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment) | ||
880 | { | ||
881 | if (image_name.empty()) | ||
882 | { | ||
883 | mImageOverlay = NULL; | ||
884 | } | ||
885 | else | ||
886 | { | ||
887 | LLUUID overlay_image_id = LLUI::findAssetUUIDByName(image_name); | ||
888 | mImageOverlay = LLUI::sImageProvider->getUIImageByID(overlay_image_id); | ||
889 | mImageOverlayAlignment = alignment; | ||
890 | } | ||
891 | } | ||
892 | |||
893 | |||
829 | void LLButton::onMouseCaptureLost() | 894 | void LLButton::onMouseCaptureLost() |
830 | { | 895 | { |
831 | mMouseDownTimer.stop(); | 896 | mMouseDownTimer.stop(); |
@@ -998,6 +1063,18 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa | |||
998 | LLString image_disabled; | 1063 | LLString image_disabled; |
999 | if (node->hasAttribute("image_disabled")) node->getAttributeString("image_disabled",image_disabled); | 1064 | if (node->hasAttribute("image_disabled")) node->getAttributeString("image_disabled",image_disabled); |
1000 | 1065 | ||
1066 | LLString image_overlay; | ||
1067 | node->getAttributeString("image_overlay", image_overlay); | ||
1068 | |||
1069 | LLFontGL::HAlign image_overlay_alignment = LLFontGL::HCENTER; | ||
1070 | LLString image_overlay_alignment_string; | ||
1071 | if (node->hasAttribute("image_overlay_alignment")) | ||
1072 | { | ||
1073 | node->getAttributeString("image_overlay_alignment", image_overlay_alignment_string); | ||
1074 | image_overlay_alignment = LLFontGL::hAlignFromName(image_overlay_alignment_string); | ||
1075 | } | ||
1076 | |||
1077 | |||
1001 | LLButton *button = new LLButton(name, | 1078 | LLButton *button = new LLButton(name, |
1002 | LLRect(), | 1079 | LLRect(), |
1003 | image_unselected, | 1080 | image_unselected, |
@@ -1020,6 +1097,7 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa | |||
1020 | 1097 | ||
1021 | if(image_disabled != LLString::null) button->setImageDisabled(image_disabled); | 1098 | if(image_disabled != LLString::null) button->setImageDisabled(image_disabled); |
1022 | 1099 | ||
1100 | if(image_overlay != LLString::null) button->setImageOverlay(image_overlay, image_overlay_alignment); | ||
1023 | 1101 | ||
1024 | if (node->hasAttribute("halign")) | 1102 | if (node->hasAttribute("halign")) |
1025 | { | 1103 | { |
diff --git a/linden/indra/llui/llbutton.h b/linden/indra/llui/llbutton.h index 44e8776..6e11779 100644 --- a/linden/indra/llui/llbutton.h +++ b/linden/indra/llui/llbutton.h | |||
@@ -142,6 +142,10 @@ public: | |||
142 | 142 | ||
143 | void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; } | 143 | void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; } |
144 | 144 | ||
145 | void setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER); | ||
146 | LLPointer<LLImageGL> getImageOverlay() { return mImageOverlay; } | ||
147 | |||
148 | |||
145 | virtual void setValue(const LLSD& value ); | 149 | virtual void setValue(const LLSD& value ); |
146 | virtual LLSD getValue() const; | 150 | virtual LLSD getValue() const; |
147 | 151 | ||
@@ -202,6 +206,9 @@ protected: | |||
202 | F32 mHeldDownDelay; // seconds, after which held-down callbacks get called | 206 | F32 mHeldDownDelay; // seconds, after which held-down callbacks get called |
203 | S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called | 207 | S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called |
204 | 208 | ||
209 | LLPointer<LLImageGL> mImageOverlay; | ||
210 | LLFontGL::HAlign mImageOverlayAlignment; | ||
211 | |||
205 | LLPointer<LLImageGL> mImageUnselected; | 212 | LLPointer<LLImageGL> mImageUnselected; |
206 | LLUIString mUnselectedLabel; | 213 | LLUIString mUnselectedLabel; |
207 | LLColor4 mUnselectedLabelColor; | 214 | LLColor4 mUnselectedLabelColor; |
diff --git a/linden/indra/llui/llfloater.cpp b/linden/indra/llui/llfloater.cpp index df44a58..6ab182f 100644 --- a/linden/indra/llui/llfloater.cpp +++ b/linden/indra/llui/llfloater.cpp | |||
@@ -575,17 +575,20 @@ void LLFloater::close(bool app_quitting) | |||
575 | cleanupHandles(); | 575 | cleanupHandles(); |
576 | gFocusMgr.clearLastFocusForGroup(this); | 576 | gFocusMgr.clearLastFocusForGroup(this); |
577 | 577 | ||
578 | // Do this early, so UI controls will commit before the | 578 | if (hasFocus()) |
579 | // window is taken down. | ||
580 | releaseFocus(); | ||
581 | |||
582 | // give focus to dependee floater if it exists, and we had focus first | ||
583 | if (isDependent()) | ||
584 | { | 579 | { |
585 | LLFloater* dependee = LLFloater::getFloaterByHandle(mDependeeHandle); | 580 | // Do this early, so UI controls will commit before the |
586 | if (dependee && !dependee->isDead()) | 581 | // window is taken down. |
582 | releaseFocus(); | ||
583 | |||
584 | // give focus to dependee floater if it exists, and we had focus first | ||
585 | if (isDependent()) | ||
587 | { | 586 | { |
588 | dependee->setFocus(TRUE); | 587 | LLFloater* dependee = LLFloater::getFloaterByHandle(mDependeeHandle); |
588 | if (dependee && !dependee->isDead()) | ||
589 | { | ||
590 | dependee->setFocus(TRUE); | ||
591 | } | ||
589 | } | 592 | } |
590 | } | 593 | } |
591 | 594 | ||
@@ -1170,6 +1173,28 @@ BOOL LLFloater::getEditModeEnabled() | |||
1170 | return sEditModeEnabled; | 1173 | return sEditModeEnabled; |
1171 | } | 1174 | } |
1172 | 1175 | ||
1176 | //static | ||
1177 | void LLFloater::show(LLFloater* floaterp) | ||
1178 | { | ||
1179 | if (floaterp) floaterp->open(); | ||
1180 | } | ||
1181 | |||
1182 | //static | ||
1183 | void LLFloater::hide(LLFloater* floaterp) | ||
1184 | { | ||
1185 | if (floaterp) floaterp->close(); | ||
1186 | } | ||
1187 | |||
1188 | //static | ||
1189 | BOOL LLFloater::visible(LLFloater* floaterp) | ||
1190 | { | ||
1191 | if (floaterp) | ||
1192 | { | ||
1193 | return floaterp->isInVisibleChain(); | ||
1194 | } | ||
1195 | return FALSE; | ||
1196 | } | ||
1197 | |||
1173 | // static | 1198 | // static |
1174 | void LLFloater::onClickMinimize(void *userdata) | 1199 | void LLFloater::onClickMinimize(void *userdata) |
1175 | { | 1200 | { |
@@ -2372,7 +2397,7 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) | |||
2372 | LLMultiFloater::LLMultiFloater() : | 2397 | LLMultiFloater::LLMultiFloater() : |
2373 | mTabContainer(NULL), | 2398 | mTabContainer(NULL), |
2374 | mTabPos(LLTabContainerCommon::TOP), | 2399 | mTabPos(LLTabContainerCommon::TOP), |
2375 | mAutoResize(FALSE) | 2400 | mAutoResize(TRUE) |
2376 | { | 2401 | { |
2377 | 2402 | ||
2378 | } | 2403 | } |
@@ -2380,7 +2405,7 @@ LLMultiFloater::LLMultiFloater() : | |||
2380 | LLMultiFloater::LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos) : | 2405 | LLMultiFloater::LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos) : |
2381 | mTabContainer(NULL), | 2406 | mTabContainer(NULL), |
2382 | mTabPos(tab_pos), | 2407 | mTabPos(tab_pos), |
2383 | mAutoResize(FALSE) | 2408 | mAutoResize(TRUE) |
2384 | { | 2409 | { |
2385 | 2410 | ||
2386 | } | 2411 | } |
@@ -2594,15 +2619,12 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, | |||
2594 | floaterp->setCanResize(FALSE); | 2619 | floaterp->setCanResize(FALSE); |
2595 | floaterp->setCanDrag(FALSE); | 2620 | floaterp->setCanDrag(FALSE); |
2596 | 2621 | ||
2597 | S32 new_width = llmax(mRect.getWidth(), floaterp->getRect().getWidth()); | ||
2598 | S32 new_height = llmax(mRect.getHeight(), floaterp->getRect().getHeight() + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT); | ||
2599 | |||
2600 | reshape(new_width, new_height); | ||
2601 | |||
2602 | //add the panel, add it to proper maps | 2622 | //add the panel, add it to proper maps |
2603 | mTabContainer->addTabPanel(floaterp, floaterp->getTitle(), FALSE, onTabSelected, this, 0, FALSE, insertion_point); | 2623 | mTabContainer->addTabPanel(floaterp, floaterp->getTitle(), FALSE, onTabSelected, this, 0, FALSE, insertion_point); |
2604 | mFloaterDataMap[floaterp->getHandle()] = floater_data; | 2624 | mFloaterDataMap[floaterp->getHandle()] = floater_data; |
2605 | 2625 | ||
2626 | resizeToContents(); | ||
2627 | |||
2606 | if ( select_added_floater ) | 2628 | if ( select_added_floater ) |
2607 | { | 2629 | { |
2608 | mTabContainer->selectLastTab(); | 2630 | mTabContainer->selectLastTab(); |
@@ -2676,10 +2698,7 @@ void LLMultiFloater::removeFloater(LLFloater* floaterp) | |||
2676 | floaterp->setBackgroundVisible(TRUE); | 2698 | floaterp->setBackgroundVisible(TRUE); |
2677 | floaterp->setHost(NULL); | 2699 | floaterp->setHost(NULL); |
2678 | 2700 | ||
2679 | if (mAutoResize) | 2701 | resizeToContents(); |
2680 | { | ||
2681 | resizeToContents(); | ||
2682 | } | ||
2683 | 2702 | ||
2684 | tabOpen((LLFloater*)mTabContainer->getCurrentPanel(), false); | 2703 | tabOpen((LLFloater*)mTabContainer->getCurrentPanel(), false); |
2685 | } | 2704 | } |
@@ -2729,7 +2748,8 @@ BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) | |||
2729 | if (key == 'W') | 2748 | if (key == 'W') |
2730 | { | 2749 | { |
2731 | LLFloater* floater = getActiveFloater(); | 2750 | LLFloater* floater = getActiveFloater(); |
2732 | if (floater && floater->canClose()) | 2751 | // is user closeable and is system closeable |
2752 | if (floater && floater->canClose() && floater->isCloseable()) | ||
2733 | { | 2753 | { |
2734 | floater->close(); | 2754 | floater->close(); |
2735 | } | 2755 | } |
@@ -2848,10 +2868,17 @@ void LLMultiFloater::resizeToContents() | |||
2848 | 2868 | ||
2849 | S32 cur_height = mRect.getHeight(); | 2869 | S32 cur_height = mRect.getHeight(); |
2850 | 2870 | ||
2851 | reshape(new_width, new_height); | 2871 | if (mAutoResize) |
2872 | { | ||
2873 | reshape(new_width, new_height); | ||
2874 | } | ||
2875 | else | ||
2876 | { | ||
2877 | reshape(llmax(new_min_width, mRect.getWidth()), llmax(new_min_height, mRect.getHeight())); | ||
2878 | } | ||
2852 | 2879 | ||
2853 | // make sure upper left corner doesn't move | 2880 | // make sure upper left corner doesn't move |
2854 | translate(0, cur_height - new_height); | 2881 | translate(0, cur_height - mRect.getHeight()); |
2855 | 2882 | ||
2856 | // Try to keep whole view onscreen, don't allow partial offscreen. | 2883 | // Try to keep whole view onscreen, don't allow partial offscreen. |
2857 | gFloaterView->adjustToFitScreen(this, FALSE); | 2884 | gFloaterView->adjustToFitScreen(this, FALSE); |
diff --git a/linden/indra/llui/llfloater.h b/linden/indra/llui/llfloater.h index cd45762..8b610e3 100644 --- a/linden/indra/llui/llfloater.h +++ b/linden/indra/llui/llfloater.h | |||
@@ -212,6 +212,10 @@ public: | |||
212 | static BOOL getEditModeEnabled(); | 212 | static BOOL getEditModeEnabled(); |
213 | static LLMultiFloater* getFloaterHost() {return sHostp; } | 213 | static LLMultiFloater* getFloaterHost() {return sHostp; } |
214 | 214 | ||
215 | static void show(LLFloater* floaterp); | ||
216 | static void hide(LLFloater* floaterp); | ||
217 | static BOOL visible(LLFloater* floaterp); | ||
218 | |||
215 | static LLFloater* getFloaterByHandle(LLViewHandle handle); | 219 | static LLFloater* getFloaterByHandle(LLViewHandle handle); |
216 | 220 | ||
217 | protected: | 221 | protected: |
@@ -279,7 +283,6 @@ protected: | |||
279 | std::vector<LLView*> mMinimizedHiddenChildren; | 283 | std::vector<LLView*> mMinimizedHiddenChildren; |
280 | }; | 284 | }; |
281 | 285 | ||
282 | |||
283 | ///////////////////////////////////////////////////////////// | 286 | ///////////////////////////////////////////////////////////// |
284 | // LLFloaterView | 287 | // LLFloaterView |
285 | // Parent of all floating panels | 288 | // Parent of all floating panels |
@@ -354,8 +357,8 @@ public: | |||
354 | LLMultiFloater(); | 357 | LLMultiFloater(); |
355 | LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos); | 358 | LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos); |
356 | LLMultiFloater(const LLString& name); | 359 | LLMultiFloater(const LLString& name); |
357 | LLMultiFloater(const LLString& name, const LLRect& rect, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = FALSE); | 360 | LLMultiFloater(const LLString& name, const LLRect& rect, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE); |
358 | LLMultiFloater(const LLString& name, const LLString& rect_control, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = FALSE); | 361 | LLMultiFloater(const LLString& name, const LLString& rect_control, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE); |
359 | virtual ~LLMultiFloater(); | 362 | virtual ~LLMultiFloater(); |
360 | 363 | ||
361 | virtual BOOL postBuild(); | 364 | virtual BOOL postBuild(); |
@@ -416,3 +419,4 @@ extern LLFloaterView* gFloaterView; | |||
416 | 419 | ||
417 | #endif // LL_FLOATER_H | 420 | #endif // LL_FLOATER_H |
418 | 421 | ||
422 | |||
diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index a2cd9af..44616b9 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp | |||
@@ -157,6 +157,14 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect, | |||
157 | { | 157 | { |
158 | llassert( max_length_bytes > 0 ); | 158 | llassert( max_length_bytes > 0 ); |
159 | 159 | ||
160 | // line history support: | ||
161 | // - initialize line history list | ||
162 | mLineHistory.insert( mLineHistory.end(), "" ); | ||
163 | // - disable line history by default | ||
164 | mHaveHistory = FALSE; | ||
165 | // - reset current history line pointer | ||
166 | mCurrentHistoryLine = 0; | ||
167 | |||
160 | if (font) | 168 | if (font) |
161 | { | 169 | { |
162 | mGLFont = font; | 170 | mGLFont = font; |
@@ -229,10 +237,33 @@ void LLLineEditor::onFocusLost() | |||
229 | 237 | ||
230 | void LLLineEditor::onCommit() | 238 | void LLLineEditor::onCommit() |
231 | { | 239 | { |
240 | // put current line into the line history | ||
241 | updateHistory(); | ||
242 | |||
232 | LLUICtrl::onCommit(); | 243 | LLUICtrl::onCommit(); |
233 | selectAll(); | 244 | selectAll(); |
234 | } | 245 | } |
235 | 246 | ||
247 | // line history support | ||
248 | void LLLineEditor::updateHistory() | ||
249 | { | ||
250 | // On history enabled line editors, remember committed line and | ||
251 | // reset current history line number. | ||
252 | // Be sure only to remember lines that are not empty and that are | ||
253 | // different from the last on the list. | ||
254 | if( mHaveHistory && mText.length() && ( mLineHistory.empty() || getText() != mLineHistory.back() ) ) | ||
255 | { | ||
256 | // discard possible empty line at the end of the history | ||
257 | // inserted by setText() | ||
258 | if( !mLineHistory.back().length() ) | ||
259 | { | ||
260 | mLineHistory.pop_back(); | ||
261 | } | ||
262 | mLineHistory.insert( mLineHistory.end(), getText() ); | ||
263 | mCurrentHistoryLine = mLineHistory.size() - 1; | ||
264 | } | ||
265 | } | ||
266 | |||
236 | void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent) | 267 | void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent) |
237 | { | 268 | { |
238 | LLUICtrl::reshape(width, height, called_from_parent ); | 269 | LLUICtrl::reshape(width, height, called_from_parent ); |
@@ -240,6 +271,10 @@ void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent) | |||
240 | mMaxHPixels = mRect.getWidth() - 2 * (mBorderThickness + UI_LINEEDITOR_H_PAD) + 1 - mBorderRight; | 271 | mMaxHPixels = mRect.getWidth() - 2 * (mBorderThickness + UI_LINEEDITOR_H_PAD) + 1 - mBorderRight; |
241 | } | 272 | } |
242 | 273 | ||
274 | void LLLineEditor::setEnableLineHistory( BOOL enabled ) | ||
275 | { | ||
276 | mHaveHistory = enabled; | ||
277 | } | ||
243 | 278 | ||
244 | void LLLineEditor::setEnabled(BOOL enabled) | 279 | void LLLineEditor::setEnabled(BOOL enabled) |
245 | { | 280 | { |
@@ -300,6 +335,13 @@ void LLLineEditor::setText(const LLString &new_text) | |||
300 | deselect(); | 335 | deselect(); |
301 | } | 336 | } |
302 | setCursor(llmin((S32)mText.length(), getCursor())); | 337 | setCursor(llmin((S32)mText.length(), getCursor())); |
338 | |||
339 | // Newly set text goes always in the last line of history. | ||
340 | // Possible empty strings (as with chat line) will be deleted later. | ||
341 | mLineHistory.insert( mLineHistory.end(), new_text ); | ||
342 | // Set current history line to end of history. | ||
343 | mCurrentHistoryLine = mLineHistory.size() - 1; | ||
344 | |||
303 | mPrevText = mText; | 345 | mPrevText = mText; |
304 | } | 346 | } |
305 | 347 | ||
@@ -1086,6 +1128,45 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) | |||
1086 | } | 1128 | } |
1087 | break; | 1129 | break; |
1088 | 1130 | ||
1131 | // handle ctrl-uparrow if we have a history enabled line editor. | ||
1132 | case KEY_UP: | ||
1133 | if( mHaveHistory && ( MASK_CONTROL & mask ) ) | ||
1134 | { | ||
1135 | if( mCurrentHistoryLine > 0 ) | ||
1136 | { | ||
1137 | mText.assign( mLineHistory[ --mCurrentHistoryLine ] ); | ||
1138 | setCursor(llmin((S32)mText.length(), getCursor())); | ||
1139 | } | ||
1140 | else | ||
1141 | { | ||
1142 | reportBadKeystroke(); | ||
1143 | } | ||
1144 | handled = TRUE; | ||
1145 | } | ||
1146 | break; | ||
1147 | |||
1148 | // handle ctrl-downarrow if we have a history enabled line editor | ||
1149 | case KEY_DOWN: | ||
1150 | if( mHaveHistory && ( MASK_CONTROL & mask ) ) | ||
1151 | { | ||
1152 | if( !mLineHistory.empty() && mCurrentHistoryLine < mLineHistory.size() - 1 ) | ||
1153 | { | ||
1154 | mText.assign( mLineHistory[ ++mCurrentHistoryLine ] ); | ||
1155 | setCursor(llmin((S32)mText.length(), getCursor())); | ||
1156 | } | ||
1157 | else | ||
1158 | { | ||
1159 | reportBadKeystroke(); | ||
1160 | } | ||
1161 | handled = TRUE; | ||
1162 | } | ||
1163 | break; | ||
1164 | |||
1165 | case KEY_RETURN: | ||
1166 | // store sent line in history | ||
1167 | updateHistory(); | ||
1168 | break; | ||
1169 | |||
1089 | case KEY_ESCAPE: | 1170 | case KEY_ESCAPE: |
1090 | if (mRevertOnEsc && mText.getString() != mPrevText) | 1171 | if (mRevertOnEsc && mText.getString() != mPrevText) |
1091 | { | 1172 | { |
diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h index 65c75ab..e715737 100644 --- a/linden/indra/llui/lllineeditor.h +++ b/linden/indra/llui/lllineeditor.h | |||
@@ -36,6 +36,7 @@ | |||
36 | // Clipboard (cut, copy, and paste) | 36 | // Clipboard (cut, copy, and paste) |
37 | // Horizontal scrolling to allow strings longer than widget size allows | 37 | // Horizontal scrolling to allow strings longer than widget size allows |
38 | // Pre-validation (limit which keys can be used) | 38 | // Pre-validation (limit which keys can be used) |
39 | // Optional line history so previous entries can be recalled by CTRL UP/DOWN | ||
39 | 40 | ||
40 | 41 | ||
41 | #ifndef LL_LLLINEEDITOR_H | 42 | #ifndef LL_LLLINEEDITOR_H |
@@ -206,6 +207,10 @@ public: | |||
206 | 207 | ||
207 | static BOOL postvalidateFloat(const LLString &str); | 208 | static BOOL postvalidateFloat(const LLString &str); |
208 | 209 | ||
210 | // line history support: | ||
211 | void setEnableLineHistory( BOOL enabled ); // switches line history on or off | ||
212 | void updateHistory(); // stores current line in history | ||
213 | |||
209 | protected: | 214 | protected: |
210 | void removeChar(); | 215 | void removeChar(); |
211 | void addChar(const llwchar c); | 216 | void addChar(const llwchar c); |
@@ -224,6 +229,11 @@ protected: | |||
224 | LLString mPrevText; // Saved string for 'ESC' revert | 229 | LLString mPrevText; // Saved string for 'ESC' revert |
225 | LLUIString mLabel; // text label that is visible when no user text provided | 230 | LLUIString mLabel; // text label that is visible when no user text provided |
226 | 231 | ||
232 | // line history support: | ||
233 | BOOL mHaveHistory; // flag for enabled line history | ||
234 | std::vector<LLString> mLineHistory; // line history storage | ||
235 | U32 mCurrentHistoryLine; // currently browsed history line | ||
236 | |||
227 | LLViewBorder* mBorder; | 237 | LLViewBorder* mBorder; |
228 | const LLFontGL* mGLFont; | 238 | const LLFontGL* mGLFont; |
229 | S32 mMaxLengthChars; // Max number of characters | 239 | S32 mMaxLengthChars; // Max number of characters |
diff --git a/linden/indra/llui/llmemberlistener.h b/linden/indra/llui/llmemberlistener.h index 92e7278..bc67519 100644 --- a/linden/indra/llui/llmemberlistener.h +++ b/linden/indra/llui/llmemberlistener.h | |||
@@ -37,7 +37,6 @@ class LLMemberListener : public LLSimpleListener | |||
37 | { | 37 | { |
38 | public: | 38 | public: |
39 | LLMemberListener() : mPtr(NULL), mRegisteredName("") { } | 39 | LLMemberListener() : mPtr(NULL), mRegisteredName("") { } |
40 | ~LLMemberListener() { } | ||
41 | 40 | ||
42 | void registerListener(T *pointer, const LLString& register_name) | 41 | void registerListener(T *pointer, const LLString& register_name) |
43 | { | 42 | { |
diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp index f0b5b25..dfa3f8a 100644 --- a/linden/indra/llui/llpanel.cpp +++ b/linden/indra/llui/llpanel.cpp | |||
@@ -589,7 +589,7 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parentp, LLUICtrlFactory *fa | |||
589 | return panelp; | 589 | return panelp; |
590 | } | 590 | } |
591 | 591 | ||
592 | void LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) | 592 | BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) |
593 | { | 593 | { |
594 | LLString name("panel"); | 594 | LLString name("panel"); |
595 | node->getAttributeString("name", name); | 595 | node->getAttributeString("name", name); |
@@ -605,12 +605,23 @@ void LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f | |||
605 | 605 | ||
606 | LLString xml_filename; | 606 | LLString xml_filename; |
607 | node->getAttributeString("filename", xml_filename); | 607 | node->getAttributeString("filename", xml_filename); |
608 | |||
609 | BOOL didPost; | ||
610 | |||
608 | if (!xml_filename.empty()) | 611 | if (!xml_filename.empty()) |
609 | { | 612 | { |
610 | factory->buildPanel(this, xml_filename, NULL); | 613 | didPost = factory->buildPanel(this, xml_filename, NULL); |
614 | } else { | ||
615 | didPost = FALSE; | ||
611 | } | 616 | } |
612 | 617 | ||
613 | postBuild(); | 618 | if (!didPost) |
619 | { | ||
620 | postBuild(); | ||
621 | didPost = TRUE; | ||
622 | } | ||
623 | |||
624 | return didPost; | ||
614 | } | 625 | } |
615 | 626 | ||
616 | void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parentp) | 627 | void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parentp) |
diff --git a/linden/indra/llui/llpanel.h b/linden/indra/llui/llpanel.h index 9da942e..fea3eee 100644 --- a/linden/indra/llui/llpanel.h +++ b/linden/indra/llui/llpanel.h | |||
@@ -135,7 +135,7 @@ public: | |||
135 | 135 | ||
136 | virtual LLXMLNodePtr getXML(bool save_children = true) const; | 136 | virtual LLXMLNodePtr getXML(bool save_children = true) const; |
137 | static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); | 137 | static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); |
138 | void initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); | 138 | BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); |
139 | void setPanelParameters(LLXMLNodePtr node, LLView *parentp); | 139 | void setPanelParameters(LLXMLNodePtr node, LLView *parentp); |
140 | 140 | ||
141 | // ** Wrappers for setting child properties by name ** -TomY | 141 | // ** Wrappers for setting child properties by name ** -TomY |
diff --git a/linden/indra/llui/llscrolllistctrl.cpp b/linden/indra/llui/llscrolllistctrl.cpp index 22987dc..fd98bd5 100644 --- a/linden/indra/llui/llscrolllistctrl.cpp +++ b/linden/indra/llui/llscrolllistctrl.cpp | |||
@@ -99,7 +99,7 @@ protected: | |||
99 | // LLScrollListIcon | 99 | // LLScrollListIcon |
100 | // | 100 | // |
101 | LLScrollListIcon::LLScrollListIcon(LLImageGL* icon, S32 width, LLUUID image_id) : | 101 | LLScrollListIcon::LLScrollListIcon(LLImageGL* icon, S32 width, LLUUID image_id) : |
102 | mIcon(icon), mImageUUID(image_id.asString()) | 102 | mIcon(icon), mColor(LLColor4::white), mImageUUID(image_id.asString()) |
103 | { | 103 | { |
104 | if (width) | 104 | if (width) |
105 | { | 105 | { |
@@ -115,6 +115,16 @@ LLScrollListIcon::~LLScrollListIcon() | |||
115 | { | 115 | { |
116 | } | 116 | } |
117 | 117 | ||
118 | void LLScrollListIcon::setColor(const LLColor4& color) | ||
119 | { | ||
120 | mColor = color; | ||
121 | } | ||
122 | |||
123 | void LLScrollListIcon::drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const | ||
124 | { | ||
125 | gl_draw_image(0, 0, mIcon, mColor); | ||
126 | } | ||
127 | |||
118 | // | 128 | // |
119 | // LLScrollListCheck | 129 | // LLScrollListCheck |
120 | // | 130 | // |
@@ -208,6 +218,15 @@ LLScrollListText::~LLScrollListText() | |||
208 | delete mColor; | 218 | delete mColor; |
209 | } | 219 | } |
210 | 220 | ||
221 | void LLScrollListText::setColor(const LLColor4& color) | ||
222 | { | ||
223 | if (!mColor) | ||
224 | { | ||
225 | mColor = new LLColor4(); | ||
226 | } | ||
227 | *mColor = color; | ||
228 | } | ||
229 | |||
211 | void LLScrollListText::setText(const LLString& text) | 230 | void LLScrollListText::setText(const LLString& text) |
212 | { | 231 | { |
213 | mText = text; | 232 | mText = text; |
@@ -2809,6 +2828,8 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p | |||
2809 | LLString fontname = (*itor)["font"].asString(); | 2828 | LLString fontname = (*itor)["font"].asString(); |
2810 | LLString fontstyle = (*itor)["font-style"].asString(); | 2829 | LLString fontstyle = (*itor)["font-style"].asString(); |
2811 | LLString type = (*itor)["type"].asString(); | 2830 | LLString type = (*itor)["type"].asString(); |
2831 | BOOL has_color = (*itor).has("color"); | ||
2832 | LLColor4 color = ((*itor)["color"]); | ||
2812 | 2833 | ||
2813 | const LLFontGL *font = gResMgr->getRes(fontname); | 2834 | const LLFontGL *font = gResMgr->getRes(fontname); |
2814 | if (!font) | 2835 | if (!font) |
@@ -2821,21 +2842,41 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p | |||
2821 | { | 2842 | { |
2822 | LLUUID image_id = value.asUUID(); | 2843 | LLUUID image_id = value.asUUID(); |
2823 | LLImageGL* icon = LLUI::sImageProvider->getUIImageByID(image_id); | 2844 | LLImageGL* icon = LLUI::sImageProvider->getUIImageByID(image_id); |
2824 | new_item->setColumn(index, new LLScrollListIcon(icon, width, image_id)); | 2845 | LLScrollListIcon* cell = new LLScrollListIcon(icon, width, image_id); |
2846 | if (has_color) | ||
2847 | { | ||
2848 | cell->setColor(color); | ||
2849 | } | ||
2850 | new_item->setColumn(index, cell); | ||
2825 | } | 2851 | } |
2826 | else if (type == "checkbox") | 2852 | else if (type == "checkbox") |
2827 | { | 2853 | { |
2828 | LLCheckBoxCtrl* ctrl = new LLCheckBoxCtrl(value.asString(), | 2854 | LLCheckBoxCtrl* ctrl = new LLCheckBoxCtrl(value.asString(), |
2829 | LLRect(0, 0, width, width), "label"); | 2855 | LLRect(0, 0, width, width), "label"); |
2830 | new_item->setColumn(index, new LLScrollListCheck(ctrl,width)); | 2856 | LLScrollListCheck* cell = new LLScrollListCheck(ctrl,width); |
2857 | if (has_color) | ||
2858 | { | ||
2859 | cell->setColor(color); | ||
2860 | } | ||
2861 | new_item->setColumn(index, cell); | ||
2831 | } | 2862 | } |
2832 | else if (type == "separator") | 2863 | else if (type == "separator") |
2833 | { | 2864 | { |
2834 | new_item->setColumn(index, new LLScrollListSeparator(width)); | 2865 | LLScrollListSeparator* cell = new LLScrollListSeparator(width); |
2866 | if (has_color) | ||
2867 | { | ||
2868 | cell->setColor(color); | ||
2869 | } | ||
2870 | new_item->setColumn(index, cell); | ||
2835 | } | 2871 | } |
2836 | else | 2872 | else |
2837 | { | 2873 | { |
2838 | new_item->setColumn(index, new LLScrollListText(value.asString(), font, width, font_style, font_alignment)); | 2874 | LLScrollListText* cell = new LLScrollListText(value.asString(), font, width, font_style, font_alignment); |
2875 | if (has_color) | ||
2876 | { | ||
2877 | cell->setColor(color); | ||
2878 | } | ||
2879 | new_item->setColumn(index, cell); | ||
2839 | if (columnp->mHeader && !value.asString().empty()) | 2880 | if (columnp->mHeader && !value.asString().empty()) |
2840 | { | 2881 | { |
2841 | columnp->mHeader->setHasResizableElement(TRUE); | 2882 | columnp->mHeader->setHasResizableElement(TRUE); |
diff --git a/linden/indra/llui/llscrolllistctrl.h b/linden/indra/llui/llscrolllistctrl.h index eed07b8..429985b 100644 --- a/linden/indra/llui/llscrolllistctrl.h +++ b/linden/indra/llui/llscrolllistctrl.h | |||
@@ -63,6 +63,7 @@ public: | |||
63 | virtual void setWidth(S32 width) = 0; | 63 | virtual void setWidth(S32 width) = 0; |
64 | virtual void highlightText(S32 offset, S32 num_chars) {} | 64 | virtual void highlightText(S32 offset, S32 num_chars) {} |
65 | virtual BOOL isText() = 0; | 65 | virtual BOOL isText() = 0; |
66 | virtual void setColor(const LLColor4&) = 0; | ||
66 | 67 | ||
67 | virtual BOOL handleClick() { return FALSE; } | 68 | virtual BOOL handleClick() { return FALSE; } |
68 | virtual void setEnabled(BOOL enable) { } | 69 | virtual void setEnabled(BOOL enable) { } |
@@ -77,6 +78,7 @@ public: | |||
77 | virtual S32 getWidth() const {return mWidth;} | 78 | virtual S32 getWidth() const {return mWidth;} |
78 | virtual S32 getHeight() const { return 5; }; | 79 | virtual S32 getHeight() const { return 5; }; |
79 | virtual void setWidth(S32 width) {mWidth = width; } | 80 | virtual void setWidth(S32 width) {mWidth = width; } |
81 | virtual void setColor(const LLColor4&) {}; | ||
80 | virtual BOOL isText() { return FALSE; } | 82 | virtual BOOL isText() { return FALSE; } |
81 | 83 | ||
82 | protected: | 84 | protected: |
@@ -97,6 +99,7 @@ public: | |||
97 | virtual const BOOL getVisible() const { return mVisible; } | 99 | virtual const BOOL getVisible() const { return mVisible; } |
98 | virtual void highlightText(S32 offset, S32 num_chars) {mHighlightOffset = offset; mHighlightCount = num_chars;} | 100 | virtual void highlightText(S32 offset, S32 num_chars) {mHighlightOffset = offset; mHighlightCount = num_chars;} |
99 | void setText(const LLString& text); | 101 | void setText(const LLString& text); |
102 | virtual void setColor(const LLColor4&); | ||
100 | virtual BOOL isText() { return TRUE; } | 103 | virtual BOOL isText() { return TRUE; } |
101 | 104 | ||
102 | private: | 105 | private: |
@@ -120,18 +123,20 @@ class LLScrollListIcon : public LLScrollListCell | |||
120 | public: | 123 | public: |
121 | LLScrollListIcon( LLImageGL* icon, S32 width = 0, LLUUID image_id = LLUUID::null); | 124 | LLScrollListIcon( LLImageGL* icon, S32 width = 0, LLUUID image_id = LLUUID::null); |
122 | /*virtual*/ ~LLScrollListIcon(); | 125 | /*virtual*/ ~LLScrollListIcon(); |
123 | virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const { gl_draw_image(0, 0, mIcon); } | 126 | virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const; |
124 | virtual S32 getWidth() const { return mWidth; } | 127 | virtual S32 getWidth() const { return mWidth; } |
125 | virtual S32 getHeight() const { return mIcon->getHeight(); } | 128 | virtual S32 getHeight() const { return mIcon->getHeight(); } |
126 | virtual const LLString& getText() const { return mImageUUID; } | 129 | virtual const LLString& getText() const { return mImageUUID; } |
127 | virtual const LLString& getTextLower() const { return mImageUUID; } | 130 | virtual const LLString& getTextLower() const { return mImageUUID; } |
128 | virtual void setWidth(S32 width) { mWidth = width; } | 131 | virtual void setWidth(S32 width) { mWidth = width; } |
132 | virtual void setColor(const LLColor4&); | ||
129 | virtual BOOL isText() { return FALSE; } | 133 | virtual BOOL isText() { return FALSE; } |
130 | 134 | ||
131 | private: | 135 | private: |
132 | LLPointer<LLImageGL> mIcon; | 136 | LLPointer<LLImageGL> mIcon; |
133 | LLString mImageUUID; | 137 | LLString mImageUUID; |
134 | S32 mWidth; | 138 | S32 mWidth; |
139 | LLColor4 mColor; | ||
135 | }; | 140 | }; |
136 | 141 | ||
137 | class LLScrollListCheck : public LLScrollListCell | 142 | class LLScrollListCheck : public LLScrollListCell |
@@ -146,6 +151,7 @@ public: | |||
146 | 151 | ||
147 | virtual BOOL handleClick(); | 152 | virtual BOOL handleClick(); |
148 | virtual void setEnabled(BOOL enable) { if (mCheckBox) mCheckBox->setEnabled(enable); } | 153 | virtual void setEnabled(BOOL enable) { if (mCheckBox) mCheckBox->setEnabled(enable); } |
154 | virtual void setColor(const LLColor4& color) {}; | ||
149 | 155 | ||
150 | LLCheckBoxCtrl* getCheckBox() { return mCheckBox; } | 156 | LLCheckBoxCtrl* getCheckBox() { return mCheckBox; } |
151 | virtual BOOL isText() { return FALSE; } | 157 | virtual BOOL isText() { return FALSE; } |
diff --git a/linden/indra/llui/lltabcontainer.cpp b/linden/indra/llui/lltabcontainer.cpp index 61cfde4..44940ae 100644 --- a/linden/indra/llui/lltabcontainer.cpp +++ b/linden/indra/llui/lltabcontainer.cpp | |||
@@ -77,7 +77,8 @@ LLTabContainerCommon::LLTabContainerCommon( | |||
77 | mCallbackUserdata( callback_userdata ), | 77 | mCallbackUserdata( callback_userdata ), |
78 | mTitleBox(NULL), | 78 | mTitleBox(NULL), |
79 | mTopBorderHeight(LLPANEL_BORDER_WIDTH), | 79 | mTopBorderHeight(LLPANEL_BORDER_WIDTH), |
80 | mTabPosition(pos) | 80 | mTabPosition(pos), |
81 | mLockedTabCount(0) | ||
81 | { | 82 | { |
82 | setMouseOpaque(FALSE); | 83 | setMouseOpaque(FALSE); |
83 | } | 84 | } |
@@ -142,6 +143,13 @@ void LLTabContainerCommon::addPlaceholder(LLPanel* child, const LLString& label) | |||
142 | addTabPanel(child, label, FALSE, NULL, NULL, 0, TRUE); | 143 | addTabPanel(child, label, FALSE, NULL, NULL, 0, TRUE); |
143 | } | 144 | } |
144 | 145 | ||
146 | void LLTabContainerCommon::lockTabs() | ||
147 | { | ||
148 | // count current tabs and ensure no new tabs get | ||
149 | // inserted between them | ||
150 | mLockedTabCount = getTabCount(); | ||
151 | } | ||
152 | |||
145 | void LLTabContainerCommon::removeTabPanel(LLPanel* child) | 153 | void LLTabContainerCommon::removeTabPanel(LLPanel* child) |
146 | { | 154 | { |
147 | BOOL has_focus = gFocusMgr.childHasKeyboardFocus(this); | 155 | BOOL has_focus = gFocusMgr.childHasKeyboardFocus(this); |
@@ -164,6 +172,10 @@ void LLTabContainerCommon::removeTabPanel(LLPanel* child) | |||
164 | break; | 172 | break; |
165 | } | 173 | } |
166 | } | 174 | } |
175 | |||
176 | // make sure we don't have more locked tabs than we have tabs | ||
177 | mLockedTabCount = llmin(getTabCount(), mLockedTabCount); | ||
178 | |||
167 | if (mCurrentTabIdx >= (S32)mTabList.size()) | 179 | if (mCurrentTabIdx >= (S32)mTabList.size()) |
168 | { | 180 | { |
169 | mCurrentTabIdx = mTabList.size()-1; | 181 | mCurrentTabIdx = mTabList.size()-1; |
@@ -526,6 +538,15 @@ void LLTabContainerCommon::setTabPanelFlashing(LLPanel* child, BOOL state ) | |||
526 | } | 538 | } |
527 | } | 539 | } |
528 | 540 | ||
541 | void LLTabContainerCommon::setTabImage(LLPanel* child, std::string img_name) | ||
542 | { | ||
543 | LLTabTuple* tuple = getTabByPanel(child); | ||
544 | if( tuple ) | ||
545 | { | ||
546 | tuple->mButton->setImageOverlay(img_name, LLFontGL::RIGHT); | ||
547 | } | ||
548 | } | ||
549 | |||
529 | void LLTabContainerCommon::setTitle(const LLString& title) | 550 | void LLTabContainerCommon::setTitle(const LLString& title) |
530 | { | 551 | { |
531 | if (mTitleBox) | 552 | if (mTitleBox) |
@@ -687,12 +708,12 @@ void LLTabContainerCommon::insertTuple(LLTabTuple * tuple, eInsertionPoint inser | |||
687 | { | 708 | { |
688 | case START: | 709 | case START: |
689 | // insert the new tab in the front of the list | 710 | // insert the new tab in the front of the list |
690 | mTabList.insert(mTabList.begin(), tuple); | 711 | mTabList.insert(mTabList.begin() + mLockedTabCount, tuple); |
691 | break; | 712 | break; |
692 | case RIGHT_OF_CURRENT: | 713 | case RIGHT_OF_CURRENT: |
693 | // insert the new tab after the current tab | 714 | // insert the new tab after the current tab (but not before mLockedTabCount) |
694 | { | 715 | { |
695 | tuple_list_t::iterator current_iter = mTabList.begin() + mCurrentTabIdx + 1; | 716 | tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx + 1); |
696 | mTabList.insert(current_iter, tuple); | 717 | mTabList.insert(current_iter, tuple); |
697 | } | 718 | } |
698 | break; | 719 | break; |
@@ -1249,6 +1270,7 @@ void LLTabContainer::draw() | |||
1249 | for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) | 1270 | for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) |
1250 | { | 1271 | { |
1251 | LLTabTuple* tuple = *iter; | 1272 | LLTabTuple* tuple = *iter; |
1273 | |||
1252 | tuple->mButton->translate( left - tuple->mButton->getRect().mLeft, 0 ); | 1274 | tuple->mButton->translate( left - tuple->mButton->getRect().mLeft, 0 ); |
1253 | left += tuple->mButton->getRect().getWidth(); | 1275 | left += tuple->mButton->getRect().getWidth(); |
1254 | 1276 | ||
@@ -1596,3 +1618,27 @@ BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDrag | |||
1596 | 1618 | ||
1597 | return LLView::handleDragAndDrop(x, y, mask, drop, type, cargo_data, accept, tooltip); | 1619 | return LLView::handleDragAndDrop(x, y, mask, drop, type, cargo_data, accept, tooltip); |
1598 | } | 1620 | } |
1621 | |||
1622 | void LLTabContainer::setTabImage(LLPanel* child, std::string image_name) | ||
1623 | { | ||
1624 | LLTabTuple* tuple = getTabByPanel(child); | ||
1625 | if( tuple ) | ||
1626 | { | ||
1627 | tuple->mButton->setImageOverlay(image_name, LLFontGL::RIGHT); | ||
1628 | |||
1629 | const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); | ||
1630 | // remove current width from total tab strip width | ||
1631 | mTotalTabWidth -= tuple->mButton->getRect().getWidth(); | ||
1632 | |||
1633 | S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? | ||
1634 | tuple->mButton->getImageOverlay()->getWidth(0) : | ||
1635 | 0; | ||
1636 | tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + image_overlay_width, mMinTabWidth, mMaxTabWidth), | ||
1637 | tuple->mButton->getRect().getHeight()); | ||
1638 | // add back in button width to total tab strip width | ||
1639 | mTotalTabWidth += tuple->mButton->getRect().getWidth(); | ||
1640 | |||
1641 | // tabs have changed size, might need to scroll to see current tab | ||
1642 | updateMaxScrollPos(); | ||
1643 | } | ||
1644 | } \ No newline at end of file | ||
diff --git a/linden/indra/llui/lltabcontainer.h b/linden/indra/llui/lltabcontainer.h index 5fe6bc5..7d501d2 100644 --- a/linden/indra/llui/lltabcontainer.h +++ b/linden/indra/llui/lltabcontainer.h | |||
@@ -87,7 +87,8 @@ public: | |||
87 | BOOL placeholder = FALSE, | 87 | BOOL placeholder = FALSE, |
88 | eInsertionPoint insertion_point = END) = 0; | 88 | eInsertionPoint insertion_point = END) = 0; |
89 | virtual void addPlaceholder(LLPanel* child, const LLString& label); | 89 | virtual void addPlaceholder(LLPanel* child, const LLString& label); |
90 | 90 | virtual void lockTabs(); | |
91 | |||
91 | virtual void enableTabButton(S32 which, BOOL enable); | 92 | virtual void enableTabButton(S32 which, BOOL enable); |
92 | 93 | ||
93 | virtual void removeTabPanel( LLPanel* child ); | 94 | virtual void removeTabPanel( LLPanel* child ); |
@@ -113,6 +114,7 @@ public: | |||
113 | 114 | ||
114 | BOOL getTabPanelFlashing(LLPanel* child); | 115 | BOOL getTabPanelFlashing(LLPanel* child); |
115 | void setTabPanelFlashing(LLPanel* child, BOOL state); | 116 | void setTabPanelFlashing(LLPanel* child, BOOL state); |
117 | virtual void setTabImage(LLPanel* child, std::string img_name); | ||
116 | void setTitle( const LLString& title ); | 118 | void setTitle( const LLString& title ); |
117 | const LLString getPanelTitle(S32 index); | 119 | const LLString getPanelTitle(S32 index); |
118 | 120 | ||
@@ -180,6 +182,7 @@ protected: | |||
180 | 182 | ||
181 | S32 mTopBorderHeight; | 183 | S32 mTopBorderHeight; |
182 | TabPosition mTabPosition; | 184 | TabPosition mTabPosition; |
185 | S32 mLockedTabCount; | ||
183 | 186 | ||
184 | protected: | 187 | protected: |
185 | void scrollPrev(); | 188 | void scrollPrev(); |
@@ -221,7 +224,7 @@ public: | |||
221 | /*virtual*/ void removeTabPanel( LLPanel* child ); | 224 | /*virtual*/ void removeTabPanel( LLPanel* child ); |
222 | 225 | ||
223 | /*virtual*/ void setPanelTitle(S32 index, const LLString& title); | 226 | /*virtual*/ void setPanelTitle(S32 index, const LLString& title); |
224 | 227 | /*virtual*/ void setTabImage(LLPanel* child, std::string img_name); | |
225 | /*virtual*/ void setRightTabBtnOffset( S32 offset ); | 228 | /*virtual*/ void setRightTabBtnOffset( S32 offset ); |
226 | 229 | ||
227 | /*virtual*/ void setMinTabWidth(S32 width); | 230 | /*virtual*/ void setMinTabWidth(S32 width); |
diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index ba991c2..80205d3 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp | |||
@@ -309,6 +309,9 @@ LLTextEditor::LLTextEditor( | |||
309 | { | 309 | { |
310 | mSourceID.generate(); | 310 | mSourceID.generate(); |
311 | 311 | ||
312 | // reset desired x cursor position | ||
313 | mDesiredXPixel = -1; | ||
314 | |||
312 | if (font) | 315 | if (font) |
313 | { | 316 | { |
314 | mGLFont = font; | 317 | mGLFont = font; |
@@ -348,7 +351,7 @@ LLTextEditor::LLTextEditor( | |||
348 | mBorder = new LLViewBorder( "text ed border", LLRect(0, mRect.getHeight(), mRect.getWidth(), 0), LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, UI_TEXTEDITOR_BORDER ); | 351 | mBorder = new LLViewBorder( "text ed border", LLRect(0, mRect.getHeight(), mRect.getWidth(), 0), LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, UI_TEXTEDITOR_BORDER ); |
349 | addChild( mBorder ); | 352 | addChild( mBorder ); |
350 | 353 | ||
351 | setText(default_text); | 354 | appendText(default_text, FALSE, FALSE); |
352 | 355 | ||
353 | mParseHTML=FALSE; | 356 | mParseHTML=FALSE; |
354 | mHTML=""; | 357 | mHTML=""; |
@@ -914,6 +917,8 @@ void LLTextEditor::setCursorPos(S32 offset) | |||
914 | { | 917 | { |
915 | mCursorPos = llclamp(offset, 0, (S32)getLength()); | 918 | mCursorPos = llclamp(offset, 0, (S32)getLength()); |
916 | updateScrollFromCursor(); | 919 | updateScrollFromCursor(); |
920 | // reset desired x cursor position | ||
921 | mDesiredXPixel = -1; | ||
917 | } | 922 | } |
918 | 923 | ||
919 | 924 | ||
@@ -2645,7 +2650,8 @@ void LLTextEditor::drawSelectionBackground() | |||
2645 | { | 2650 | { |
2646 | LLGLSNoTexture no_texture; | 2651 | LLGLSNoTexture no_texture; |
2647 | const LLColor4& color = mReadOnly ? mReadOnlyBgColor : mWriteableBgColor; | 2652 | const LLColor4& color = mReadOnly ? mReadOnlyBgColor : mWriteableBgColor; |
2648 | glColor3f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2] ); | 2653 | F32 alpha = hasFocus() ? 1.f : 0.5f; |
2654 | glColor4f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], alpha ); | ||
2649 | 2655 | ||
2650 | if( selection_left_y == selection_right_y ) | 2656 | if( selection_left_y == selection_right_y ) |
2651 | { | 2657 | { |
@@ -3098,6 +3104,9 @@ void LLTextEditor::changePage( S32 delta ) | |||
3098 | S32 line, offset; | 3104 | S32 line, offset; |
3099 | getLineAndOffset( mCursorPos, &line, &offset ); | 3105 | getLineAndOffset( mCursorPos, &line, &offset ); |
3100 | 3106 | ||
3107 | // get desired x position to remember previous position | ||
3108 | S32 desired_x_pixel = mDesiredXPixel; | ||
3109 | |||
3101 | // allow one line overlap | 3110 | // allow one line overlap |
3102 | S32 page_size = mScrollbar->getPageSize() - 1; | 3111 | S32 page_size = mScrollbar->getPageSize() - 1; |
3103 | if( delta == -1 ) | 3112 | if( delta == -1 ) |
@@ -3112,6 +3121,10 @@ void LLTextEditor::changePage( S32 delta ) | |||
3112 | setCursorPos(getPos( line + page_size, offset )); | 3121 | setCursorPos(getPos( line + page_size, offset )); |
3113 | mScrollbar->setDocPos( mScrollbar->getDocPos() + page_size ); | 3122 | mScrollbar->setDocPos( mScrollbar->getDocPos() + page_size ); |
3114 | } | 3123 | } |
3124 | |||
3125 | // put desired position into remember-buffer after setCursorPos() | ||
3126 | mDesiredXPixel = desired_x_pixel; | ||
3127 | |||
3115 | if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax())) | 3128 | if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax())) |
3116 | { | 3129 | { |
3117 | mOnScrollEndCallback(mOnScrollEndData); | 3130 | mOnScrollEndCallback(mOnScrollEndData); |
@@ -3127,9 +3140,13 @@ void LLTextEditor::changeLine( S32 delta ) | |||
3127 | 3140 | ||
3128 | S32 line_start = getLineStart(line); | 3141 | S32 line_start = getLineStart(line); |
3129 | 3142 | ||
3130 | S32 desired_x_pixel; | 3143 | // set desired x position to remembered previous position |
3131 | 3144 | S32 desired_x_pixel = mDesiredXPixel; | |
3132 | desired_x_pixel = mGLFont->getWidth(mWText.c_str(), line_start, offset, mAllowEmbeddedItems ); | 3145 | // if remembered position was reset (thus -1), calculate new one here |
3146 | if( desired_x_pixel == -1 ) | ||
3147 | { | ||
3148 | desired_x_pixel = mGLFont->getWidth(mWText.c_str(), line_start, offset, mAllowEmbeddedItems ); | ||
3149 | } | ||
3133 | 3150 | ||
3134 | S32 new_line = 0; | 3151 | S32 new_line = 0; |
3135 | if( (delta < 0) && (line > 0 ) ) | 3152 | if( (delta < 0) && (line > 0 ) ) |
@@ -3165,6 +3182,9 @@ void LLTextEditor::changeLine( S32 delta ) | |||
3165 | mAllowEmbeddedItems); | 3182 | mAllowEmbeddedItems); |
3166 | 3183 | ||
3167 | setCursorPos (getPos( new_line, new_offset )); | 3184 | setCursorPos (getPos( new_line, new_offset )); |
3185 | |||
3186 | // put desired position into remember-buffer after setCursorPos() | ||
3187 | mDesiredXPixel = desired_x_pixel; | ||
3168 | unbindEmbeddedChars( mGLFont ); | 3188 | unbindEmbeddedChars( mGLFont ); |
3169 | } | 3189 | } |
3170 | 3190 | ||
@@ -3358,6 +3378,14 @@ void LLTextEditor::appendColoredText(const LLString &new_text, | |||
3358 | style.setVisible(true); | 3378 | style.setVisible(true); |
3359 | style.setColor(color); | 3379 | style.setColor(color); |
3360 | style.setFontName(font_name); | 3380 | style.setFontName(font_name); |
3381 | appendStyledText(new_text, allow_undo, prepend_newline, &style); | ||
3382 | } | ||
3383 | |||
3384 | void LLTextEditor::appendStyledText(const LLString &new_text, | ||
3385 | bool allow_undo, | ||
3386 | bool prepend_newline, | ||
3387 | const LLStyle* style) | ||
3388 | { | ||
3361 | if(mParseHTML) | 3389 | if(mParseHTML) |
3362 | { | 3390 | { |
3363 | 3391 | ||
@@ -3368,10 +3396,13 @@ void LLTextEditor::appendColoredText(const LLString &new_text, | |||
3368 | LLStyle html; | 3396 | LLStyle html; |
3369 | html.setVisible(true); | 3397 | html.setVisible(true); |
3370 | html.setColor(mLinkColor); | 3398 | html.setColor(mLinkColor); |
3371 | html.setFontName(font_name); | 3399 | if (style) |
3400 | { | ||
3401 | html.setFontName(style->getFontString()); | ||
3402 | } | ||
3372 | html.mUnderline = TRUE; | 3403 | html.mUnderline = TRUE; |
3373 | 3404 | ||
3374 | if (start > 0) appendText(text.substr(0,start),allow_undo, prepend_newline, &style); | 3405 | if (start > 0) appendText(text.substr(0,start),allow_undo, prepend_newline, style); |
3375 | html.setLinkHREF(text.substr(start,end-start)); | 3406 | html.setLinkHREF(text.substr(start,end-start)); |
3376 | appendText(text.substr(start, end-start),allow_undo, prepend_newline, &html); | 3407 | appendText(text.substr(start, end-start),allow_undo, prepend_newline, &html); |
3377 | if (end < (S32)text.length()) | 3408 | if (end < (S32)text.length()) |
@@ -3384,22 +3415,14 @@ void LLTextEditor::appendColoredText(const LLString &new_text, | |||
3384 | break; | 3415 | break; |
3385 | } | 3416 | } |
3386 | } | 3417 | } |
3387 | if (end < (S32)text.length()) appendText(text,allow_undo, prepend_newline, &style); | 3418 | if (end < (S32)text.length()) appendText(text,allow_undo, prepend_newline, style); |
3388 | } | 3419 | } |
3389 | else | 3420 | else |
3390 | { | 3421 | { |
3391 | appendText(new_text, allow_undo, prepend_newline, &style); | 3422 | appendText(new_text, allow_undo, prepend_newline, style); |
3392 | } | 3423 | } |
3393 | } | 3424 | } |
3394 | 3425 | ||
3395 | void LLTextEditor::appendStyledText(const LLString &new_text, | ||
3396 | bool allow_undo, | ||
3397 | bool prepend_newline, | ||
3398 | const LLStyle &style) | ||
3399 | { | ||
3400 | appendText(new_text, allow_undo, prepend_newline, &style); | ||
3401 | } | ||
3402 | |||
3403 | // Appends new text to end of document | 3426 | // Appends new text to end of document |
3404 | void LLTextEditor::appendText(const LLString &new_text, bool allow_undo, bool prepend_newline, | 3427 | void LLTextEditor::appendText(const LLString &new_text, bool allow_undo, bool prepend_newline, |
3405 | const LLStyle* segment_style) | 3428 | const LLStyle* segment_style) |
diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h index 32375be..ebe8ac3 100644 --- a/linden/indra/llui/lltexteditor.h +++ b/linden/indra/llui/lltexteditor.h | |||
@@ -159,7 +159,7 @@ public: | |||
159 | // if styled text starts a line, you need to prepend a newline. | 159 | // if styled text starts a line, you need to prepend a newline. |
160 | void appendStyledText(const LLString &new_text, bool allow_undo, | 160 | void appendStyledText(const LLString &new_text, bool allow_undo, |
161 | bool prepend_newline, | 161 | bool prepend_newline, |
162 | const LLStyle &style); | 162 | const LLStyle* style); |
163 | 163 | ||
164 | // Removes text from the end of document | 164 | // Removes text from the end of document |
165 | // Does not change highlight or cursor position. | 165 | // Does not change highlight or cursor position. |
@@ -359,6 +359,7 @@ protected: | |||
359 | undo_stack_t mUndoStack; | 359 | undo_stack_t mUndoStack; |
360 | 360 | ||
361 | S32 mCursorPos; // I-beam is just after the mCursorPos-th character. | 361 | S32 mCursorPos; // I-beam is just after the mCursorPos-th character. |
362 | S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be | ||
362 | LLRect mTextRect; // The rect in which text is drawn. Excludes borders. | 363 | LLRect mTextRect; // The rect in which text is drawn. Excludes borders. |
363 | // List of offsets and segment index of the start of each line. Always has at least one node (0). | 364 | // List of offsets and segment index of the start of each line. Always has at least one node (0). |
364 | struct line_info | 365 | struct line_info |
diff --git a/linden/indra/llui/llui.h b/linden/indra/llui/llui.h index 6b8a86a..3085bd9 100644 --- a/linden/indra/llui/llui.h +++ b/linden/indra/llui/llui.h | |||
@@ -275,4 +275,95 @@ typedef enum e_widget_type | |||
275 | WIDGET_TYPE_COUNT | 275 | WIDGET_TYPE_COUNT |
276 | } EWidgetType; | 276 | } EWidgetType; |
277 | 277 | ||
278 | // Manages generation of UI elements by LLSD, such that there is | ||
279 | // only one instance per uniquely identified LLSD parameter | ||
280 | // Class T is the instance type being managed, and INSTANCE_ADDAPTOR | ||
281 | // wraps an instance of the class with handlers for show/hide semantics, etc. | ||
282 | template <class T, class INSTANCE_ADAPTOR = T> | ||
283 | class LLUIInstanceMgr | ||
284 | { | ||
285 | public: | ||
286 | LLUIInstanceMgr() | ||
287 | { | ||
288 | } | ||
289 | |||
290 | virtual ~LLUIInstanceMgr() | ||
291 | { | ||
292 | } | ||
293 | |||
294 | // default show and hide methods | ||
295 | static T* showInstance(const LLSD& seed) | ||
296 | { | ||
297 | T* instance = INSTANCE_ADAPTOR::getInstance(seed); | ||
298 | INSTANCE_ADAPTOR::show(instance); | ||
299 | return instance; | ||
300 | } | ||
301 | |||
302 | static void hideInstance(const LLSD& seed) | ||
303 | { | ||
304 | T* instance = INSTANCE_ADAPTOR::getInstance(seed); | ||
305 | INSTANCE_ADAPTOR::hide(instance); | ||
306 | } | ||
307 | |||
308 | static void toggleInstance(const LLSD& seed) | ||
309 | { | ||
310 | if (!INSTANCE_ADAPTOR::instanceVisible(seed)) | ||
311 | { | ||
312 | INSTANCE_ADAPTOR::showInstance(seed); | ||
313 | } | ||
314 | else | ||
315 | { | ||
316 | INSTANCE_ADAPTOR::hideInstance(seed); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | static BOOL instanceVisible(const LLSD& seed) | ||
321 | { | ||
322 | T* instance = INSTANCE_ADAPTOR::findInstance(seed); | ||
323 | return instance != NULL && INSTANCE_ADAPTOR::visible(instance); | ||
324 | } | ||
325 | |||
326 | static T* getInstance(const LLSD& seed) | ||
327 | { | ||
328 | T* instance = INSTANCE_ADAPTOR::findInstance(seed); | ||
329 | if (instance == NULL) | ||
330 | { | ||
331 | instance = INSTANCE_ADAPTOR::createInstance(seed); | ||
332 | } | ||
333 | return instance; | ||
334 | } | ||
335 | }; | ||
336 | |||
337 | // Creates a UI singleton by ignoring the identifying parameter | ||
338 | // and always generating the same instance via the LLUIInstanceMgr interface. | ||
339 | // Note that since UI elements can be destroyed by their hierarchy, this singleton | ||
340 | // pattern uses a static pointer to an instance that will be re-created as needed. | ||
341 | template <class T, class INSTANCE_ADAPTOR = T> | ||
342 | class LLUISingleton: public LLUIInstanceMgr<T, INSTANCE_ADAPTOR> | ||
343 | { | ||
344 | public: | ||
345 | // default constructor assumes T is derived from LLUISingleton (a true singleton) | ||
346 | LLUISingleton() : LLUIInstanceMgr<T, INSTANCE_ADAPTOR>() { sInstance = (T*)this; } | ||
347 | ~LLUISingleton() { sInstance = NULL; } | ||
348 | |||
349 | static T* findInstance(const LLSD& seed) | ||
350 | { | ||
351 | return sInstance; | ||
352 | } | ||
353 | |||
354 | static T* createInstance(const LLSD& seed) | ||
355 | { | ||
356 | if (sInstance == NULL) | ||
357 | { | ||
358 | sInstance = new T(seed); | ||
359 | } | ||
360 | return sInstance; | ||
361 | } | ||
362 | |||
363 | protected: | ||
364 | static T* sInstance; | ||
365 | }; | ||
366 | |||
367 | template <class T, class U> T* LLUISingleton<T,U>::sInstance = NULL; | ||
368 | |||
278 | #endif | 369 | #endif |
diff --git a/linden/indra/llui/lluictrlfactory.cpp b/linden/indra/llui/lluictrlfactory.cpp index 475ef2e..79f7313 100644 --- a/linden/indra/llui/lluictrlfactory.cpp +++ b/linden/indra/llui/lluictrlfactory.cpp | |||
@@ -370,21 +370,22 @@ S32 LLUICtrlFactory::saveToXML(LLView* viewp, const LLString& filename) | |||
370 | //----------------------------------------------------------------------------- | 370 | //----------------------------------------------------------------------------- |
371 | // buildPanel() | 371 | // buildPanel() |
372 | //----------------------------------------------------------------------------- | 372 | //----------------------------------------------------------------------------- |
373 | void LLUICtrlFactory::buildPanel(LLPanel* panelp, const LLString &filename, | 373 | BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const LLString &filename, |
374 | const LLCallbackMap::map_t* factory_map) | 374 | const LLCallbackMap::map_t* factory_map) |
375 | { | 375 | { |
376 | BOOL didPost = FALSE; | ||
376 | LLXMLNodePtr root; | 377 | LLXMLNodePtr root; |
377 | 378 | ||
378 | if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) | 379 | if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) |
379 | { | 380 | { |
380 | return; | 381 | return didPost; |
381 | } | 382 | } |
382 | 383 | ||
383 | // root must be called panel | 384 | // root must be called panel |
384 | if( !root->hasName("panel" ) ) | 385 | if( !root->hasName("panel" ) ) |
385 | { | 386 | { |
386 | llwarns << "Root node should be named panel in : " << filename << llendl; | 387 | llwarns << "Root node should be named panel in : " << filename << llendl; |
387 | return; | 388 | return didPost; |
388 | } | 389 | } |
389 | 390 | ||
390 | if (factory_map) | 391 | if (factory_map) |
@@ -392,7 +393,7 @@ void LLUICtrlFactory::buildPanel(LLPanel* panelp, const LLString &filename, | |||
392 | mFactoryStack.push_front(factory_map); | 393 | mFactoryStack.push_front(factory_map); |
393 | } | 394 | } |
394 | 395 | ||
395 | panelp->initPanelXML(root, NULL, this); | 396 | didPost = panelp->initPanelXML(root, NULL, this); |
396 | 397 | ||
397 | if (LLUI::sShowXUINames) | 398 | if (LLUI::sShowXUINames) |
398 | { | 399 | { |
@@ -406,6 +407,8 @@ void LLUICtrlFactory::buildPanel(LLPanel* panelp, const LLString &filename, | |||
406 | { | 407 | { |
407 | mFactoryStack.pop_front(); | 408 | mFactoryStack.pop_front(); |
408 | } | 409 | } |
410 | |||
411 | return didPost; | ||
409 | } | 412 | } |
410 | 413 | ||
411 | //----------------------------------------------------------------------------- | 414 | //----------------------------------------------------------------------------- |
diff --git a/linden/indra/llui/lluictrlfactory.h b/linden/indra/llui/lluictrlfactory.h index 18b0ba9..eaae754 100644 --- a/linden/indra/llui/lluictrlfactory.h +++ b/linden/indra/llui/lluictrlfactory.h | |||
@@ -80,8 +80,8 @@ public: | |||
80 | void buildFloater(LLFloater* floaterp, const LLString &filename, | 80 | void buildFloater(LLFloater* floaterp, const LLString &filename, |
81 | const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE); | 81 | const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE); |
82 | 82 | ||
83 | void buildPanel(LLPanel* panelp, const LLString &filename, | 83 | BOOL buildPanel(LLPanel* panelp, const LLString &filename, |
84 | const LLCallbackMap::map_t* factory_map = NULL); | 84 | const LLCallbackMap::map_t* factory_map = NULL); |
85 | 85 | ||
86 | LLMenuGL *buildMenu(const LLString &filename, LLView* parentp); | 86 | LLMenuGL *buildMenu(const LLString &filename, LLView* parentp); |
87 | 87 | ||
diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp index d150e10..22d426a 100644 --- a/linden/indra/llui/llview.cpp +++ b/linden/indra/llui/llview.cpp | |||
@@ -194,8 +194,10 @@ LLView::~LLView() | |||
194 | for (itor = mDispatchList.begin(); itor != mDispatchList.end(); ++itor) | 194 | for (itor = mDispatchList.begin(); itor != mDispatchList.end(); ++itor) |
195 | { | 195 | { |
196 | (*itor).second->clearDispatchers(); | 196 | (*itor).second->clearDispatchers(); |
197 | delete (*itor).second; | ||
198 | } | 197 | } |
198 | |||
199 | std::for_each(mFloaterControls.begin(), mFloaterControls.end(), | ||
200 | DeletePairedPointer()); | ||
199 | } | 201 | } |
200 | 202 | ||
201 | // virtual | 203 | // virtual |
@@ -367,22 +369,25 @@ void LLView::addChildAtEnd(LLView* child, S32 tab_group) | |||
367 | } | 369 | } |
368 | 370 | ||
369 | // remove the specified child from the view, and set it's parent to NULL. | 371 | // remove the specified child from the view, and set it's parent to NULL. |
370 | void LLView::removeChild( LLView* child ) | 372 | void LLView::removeChild(LLView* child, BOOL deleteIt) |
371 | { | 373 | { |
372 | if (child->mParentView == this) | 374 | if (child->mParentView == this) |
373 | { | 375 | { |
374 | mChildList.remove( child ); | 376 | mChildList.remove( child ); |
375 | child->mParentView = NULL; | 377 | child->mParentView = NULL; |
378 | if (child->isCtrl()) | ||
379 | { | ||
380 | removeCtrl((LLUICtrl*)child); | ||
381 | } | ||
382 | if (deleteIt) | ||
383 | { | ||
384 | delete child; | ||
385 | } | ||
376 | } | 386 | } |
377 | else | 387 | else |
378 | { | 388 | { |
379 | llerrs << "LLView::removeChild called with non-child" << llendl; | 389 | llerrs << "LLView::removeChild called with non-child" << llendl; |
380 | } | 390 | } |
381 | |||
382 | if (child->isCtrl()) | ||
383 | { | ||
384 | removeCtrl((LLUICtrl*)child); | ||
385 | } | ||
386 | } | 391 | } |
387 | 392 | ||
388 | void LLView::addCtrlAtEnd(LLUICtrl* ctrl, S32 tab_group) | 393 | void LLView::addCtrlAtEnd(LLUICtrl* ctrl, S32 tab_group) |
@@ -2507,7 +2512,6 @@ void LLView::deregisterEventListener(LLString name) | |||
2507 | dispatch_list_t::iterator itor = mDispatchList.find(name); | 2512 | dispatch_list_t::iterator itor = mDispatchList.find(name); |
2508 | if (itor != mDispatchList.end()) | 2513 | if (itor != mDispatchList.end()) |
2509 | { | 2514 | { |
2510 | delete itor->second; | ||
2511 | mDispatchList.erase(itor); | 2515 | mDispatchList.erase(itor); |
2512 | } | 2516 | } |
2513 | } | 2517 | } |
diff --git a/linden/indra/llui/llview.h b/linden/indra/llui/llview.h index cb9a35c..c7664eb 100644 --- a/linden/indra/llui/llview.h +++ b/linden/indra/llui/llview.h | |||
@@ -241,7 +241,7 @@ public: | |||
241 | void addChild(LLView* view, S32 tab_group = 0); | 241 | void addChild(LLView* view, S32 tab_group = 0); |
242 | void addChildAtEnd(LLView* view, S32 tab_group = 0); | 242 | void addChildAtEnd(LLView* view, S32 tab_group = 0); |
243 | // remove the specified child from the view, and set it's parent to NULL. | 243 | // remove the specified child from the view, and set it's parent to NULL. |
244 | void removeChild( LLView* view ); | 244 | void removeChild(LLView* view, BOOL deleteIt = FALSE); |
245 | 245 | ||
246 | virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group); | 246 | virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group); |
247 | virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group); | 247 | virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group); |
@@ -484,7 +484,7 @@ protected: | |||
484 | LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); | 484 | LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); |
485 | LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask); | 485 | LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask); |
486 | 486 | ||
487 | typedef std::map<LLString, LLSimpleListener*> dispatch_list_t; | 487 | typedef std::map<LLString, LLPointer<LLSimpleListener> > dispatch_list_t; |
488 | dispatch_list_t mDispatchList; | 488 | dispatch_list_t mDispatchList; |
489 | 489 | ||
490 | protected: | 490 | protected: |