diff options
Diffstat (limited to 'linden/indra/llui/llview.cpp')
-rw-r--r-- | linden/indra/llui/llview.cpp | 215 |
1 files changed, 145 insertions, 70 deletions
diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp index e5415f8..c9828dd 100644 --- a/linden/indra/llui/llview.cpp +++ b/linden/indra/llui/llview.cpp | |||
@@ -49,7 +49,16 @@ | |||
49 | #include "lluictrl.h" | 49 | #include "lluictrl.h" |
50 | #include "llwindow.h" | 50 | #include "llwindow.h" |
51 | #include "v3color.h" | 51 | #include "v3color.h" |
52 | #include "lluictrlfactory.h" | ||
52 | 53 | ||
54 | // for ui edit hack | ||
55 | #include "llbutton.h" | ||
56 | #include "lllineeditor.h" | ||
57 | #include "lltexteditor.h" | ||
58 | #include "lltextbox.h" | ||
59 | |||
60 | //HACK: this allows you to instantiate LLView from xml with "<view/>" which we don't want | ||
61 | static LLRegisterWidget<LLView> r("view"); | ||
53 | 62 | ||
54 | BOOL LLView::sDebugRects = FALSE; | 63 | BOOL LLView::sDebugRects = FALSE; |
55 | BOOL LLView::sDebugKeys = FALSE; | 64 | BOOL LLView::sDebugKeys = FALSE; |
@@ -153,6 +162,8 @@ LLView::~LLView() | |||
153 | 162 | ||
154 | std::for_each(mFloaterControls.begin(), mFloaterControls.end(), | 163 | std::for_each(mFloaterControls.begin(), mFloaterControls.end(), |
155 | DeletePairedPointer()); | 164 | DeletePairedPointer()); |
165 | std::for_each(mDummyWidgets.begin(), mDummyWidgets.end(), | ||
166 | DeletePairedPointer()); | ||
156 | } | 167 | } |
157 | 168 | ||
158 | // virtual | 169 | // virtual |
@@ -716,7 +727,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_scre | |||
716 | tool_tip = getShowNamesToolTip(); | 727 | tool_tip = getShowNamesToolTip(); |
717 | } | 728 | } |
718 | 729 | ||
719 | BOOL showNamesTextBox = LLUI::sShowXUINames && (getWidgetType() == WIDGET_TYPE_TEXT_BOX); | 730 | BOOL showNamesTextBox = LLUI::sShowXUINames && dynamic_cast<LLTextBox*>(this) != NULL; |
720 | 731 | ||
721 | if( !handled && (blockMouseEvent(x, y) || showNamesTextBox) && !tool_tip.empty()) | 732 | if( !handled && (blockMouseEvent(x, y) || showNamesTextBox) && !tool_tip.empty()) |
722 | { | 733 | { |
@@ -741,23 +752,21 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent) | |||
741 | { | 752 | { |
742 | BOOL handled = FALSE; | 753 | BOOL handled = FALSE; |
743 | 754 | ||
744 | if( called_from_parent ) | 755 | if (getVisible() && getEnabled()) |
745 | { | 756 | { |
746 | // Downward traversal | 757 | if( called_from_parent ) |
747 | if (getVisible() && getEnabled()) | ||
748 | { | 758 | { |
759 | // Downward traversal | ||
749 | handled = childrenHandleKey( key, mask ) != NULL; | 760 | handled = childrenHandleKey( key, mask ) != NULL; |
750 | } | 761 | } |
751 | } | ||
752 | 762 | ||
753 | // JC: Must pass to disabled views, since they could have | 763 | if (!handled) |
754 | // keyboard focus, which requires the escape key to exit. | ||
755 | if (!handled && getVisible()) | ||
756 | { | ||
757 | handled = handleKeyHere( key, mask, called_from_parent ); | ||
758 | if (handled && LLView::sDebugKeys) | ||
759 | { | 764 | { |
760 | llinfos << "Key handled by " << getName() << llendl; | 765 | handled = handleKeyHere( key, mask ); |
766 | if (handled && LLView::sDebugKeys) | ||
767 | { | ||
768 | llinfos << "Key handled by " << getName() << llendl; | ||
769 | } | ||
761 | } | 770 | } |
762 | } | 771 | } |
763 | 772 | ||
@@ -771,7 +780,7 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent) | |||
771 | 780 | ||
772 | // Called from handleKey() | 781 | // Called from handleKey() |
773 | // Handles key in this object. Checking parents and children happens in handleKey() | 782 | // Handles key in this object. Checking parents and children happens in handleKey() |
774 | BOOL LLView::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) | 783 | BOOL LLView::handleKeyHere(KEY key, MASK mask) |
775 | { | 784 | { |
776 | return FALSE; | 785 | return FALSE; |
777 | } | 786 | } |
@@ -780,25 +789,24 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) | |||
780 | { | 789 | { |
781 | BOOL handled = FALSE; | 790 | BOOL handled = FALSE; |
782 | 791 | ||
783 | if( called_from_parent ) | 792 | if (getVisible() && getEnabled()) |
784 | { | 793 | { |
785 | // Downward traversal | 794 | if( called_from_parent ) |
786 | if (getVisible() && getEnabled()) | ||
787 | { | 795 | { |
796 | // Downward traversal | ||
788 | handled = childrenHandleUnicodeChar( uni_char ) != NULL; | 797 | handled = childrenHandleUnicodeChar( uni_char ) != NULL; |
789 | } | 798 | } |
790 | } | ||
791 | 799 | ||
792 | if (!handled && getVisible()) | 800 | if (!handled) |
793 | { | ||
794 | handled = handleUnicodeCharHere(uni_char, called_from_parent); | ||
795 | if (handled && LLView::sDebugKeys) | ||
796 | { | 801 | { |
797 | llinfos << "Unicode key handled by " << getName() << llendl; | 802 | handled = handleUnicodeCharHere(uni_char); |
803 | if (handled && LLView::sDebugKeys) | ||
804 | { | ||
805 | llinfos << "Unicode key handled by " << getName() << llendl; | ||
806 | } | ||
798 | } | 807 | } |
799 | } | 808 | } |
800 | 809 | ||
801 | |||
802 | if (!handled && !called_from_parent && mParentView) | 810 | if (!handled && !called_from_parent && mParentView) |
803 | { | 811 | { |
804 | // Upward traversal | 812 | // Upward traversal |
@@ -809,7 +817,7 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) | |||
809 | } | 817 | } |
810 | 818 | ||
811 | 819 | ||
812 | BOOL LLView::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent ) | 820 | BOOL LLView::handleUnicodeCharHere(llwchar uni_char ) |
813 | { | 821 | { |
814 | return FALSE; | 822 | return FALSE; |
815 | } | 823 | } |
@@ -903,11 +911,14 @@ BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask) | |||
903 | if (sEditingUI && handled_view) | 911 | if (sEditingUI && handled_view) |
904 | { | 912 | { |
905 | // need to find leaf views, big hack | 913 | // need to find leaf views, big hack |
906 | EWidgetType type = handled_view->getWidgetType(); | 914 | LLButton* buttonp = dynamic_cast<LLButton*>(handled_view); |
907 | if (type == WIDGET_TYPE_BUTTON | 915 | LLLineEditor* line_editorp = dynamic_cast<LLLineEditor*>(handled_view); |
908 | || type == WIDGET_TYPE_LINE_EDITOR | 916 | LLTextEditor* text_editorp = dynamic_cast<LLTextEditor*>(handled_view); |
909 | || type == WIDGET_TYPE_TEXT_EDITOR | 917 | LLTextBox* text_boxp = dynamic_cast<LLTextBox*>(handled_view); |
910 | || type == WIDGET_TYPE_TEXT_BOX) | 918 | if (buttonp |
919 | || line_editorp | ||
920 | || text_editorp | ||
921 | || text_boxp) | ||
911 | { | 922 | { |
912 | sEditingUIView = handled_view; | 923 | sEditingUIView = handled_view; |
913 | } | 924 | } |
@@ -971,8 +982,10 @@ LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) | |||
971 | LLView* viewp = *child_it; | 982 | LLView* viewp = *child_it; |
972 | S32 local_x = x - viewp->getRect().mLeft; | 983 | S32 local_x = x - viewp->getRect().mLeft; |
973 | S32 local_y = y - viewp->getRect().mBottom; | 984 | S32 local_y = y - viewp->getRect().mBottom; |
974 | if (viewp->pointInView(local_x, local_y) && | 985 | if (viewp->pointInView(local_x, local_y) |
975 | viewp->handleScrollWheel( local_x, local_y, clicks )) | 986 | && viewp->getVisible() |
987 | && viewp->getEnabled() | ||
988 | && viewp->handleScrollWheel( local_x, local_y, clicks )) | ||
976 | { | 989 | { |
977 | if (sDebugMouseHandling) | 990 | if (sDebugMouseHandling) |
978 | { | 991 | { |
@@ -1528,7 +1541,7 @@ BOOL LLView::hasAncestor(const LLView* parentp) const | |||
1528 | 1541 | ||
1529 | BOOL LLView::childHasKeyboardFocus( const LLString& childname ) const | 1542 | BOOL LLView::childHasKeyboardFocus( const LLString& childname ) const |
1530 | { | 1543 | { |
1531 | LLView *child = getChildByName(childname); | 1544 | LLView *child = getChildView(childname, TRUE, FALSE); |
1532 | if (child) | 1545 | if (child) |
1533 | { | 1546 | { |
1534 | return gFocusMgr.childHasKeyboardFocus(child); | 1547 | return gFocusMgr.childHasKeyboardFocus(child); |
@@ -1543,16 +1556,17 @@ BOOL LLView::childHasKeyboardFocus( const LLString& childname ) const | |||
1543 | 1556 | ||
1544 | BOOL LLView::hasChild(const LLString& childname, BOOL recurse) const | 1557 | BOOL LLView::hasChild(const LLString& childname, BOOL recurse) const |
1545 | { | 1558 | { |
1546 | return getChildByName(childname, recurse) != NULL; | 1559 | return getChildView(childname, recurse, FALSE) != NULL; |
1547 | } | 1560 | } |
1548 | 1561 | ||
1549 | //----------------------------------------------------------------------------- | 1562 | //----------------------------------------------------------------------------- |
1550 | // getChildByName() | 1563 | // getChildView() |
1551 | //----------------------------------------------------------------------------- | 1564 | //----------------------------------------------------------------------------- |
1552 | LLView* LLView::getChildByName(const LLString& name, BOOL recurse) const | 1565 | LLView* LLView::getChildView(const LLString& name, BOOL recurse, BOOL create_if_missing) const |
1553 | { | 1566 | { |
1554 | if(name.empty()) | 1567 | //richard: should we allow empty names? |
1555 | return NULL; | 1568 | //if(name.empty()) |
1569 | // return NULL; | ||
1556 | child_list_const_iter_t child_it; | 1570 | child_list_const_iter_t child_it; |
1557 | // Look for direct children *first* | 1571 | // Look for direct children *first* |
1558 | for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) | 1572 | for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) |
@@ -1569,13 +1583,18 @@ LLView* LLView::getChildByName(const LLString& name, BOOL recurse) const | |||
1569 | for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) | 1583 | for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) |
1570 | { | 1584 | { |
1571 | LLView* childp = *child_it; | 1585 | LLView* childp = *child_it; |
1572 | LLView* viewp = childp->getChildByName(name, recurse); | 1586 | LLView* viewp = childp->getChildView(name, recurse, FALSE); |
1573 | if ( viewp ) | 1587 | if ( viewp ) |
1574 | { | 1588 | { |
1575 | return viewp; | 1589 | return viewp; |
1576 | } | 1590 | } |
1577 | } | 1591 | } |
1578 | } | 1592 | } |
1593 | |||
1594 | if (create_if_missing) | ||
1595 | { | ||
1596 | return createDummyWidget<LLView>(name); | ||
1597 | } | ||
1579 | return NULL; | 1598 | return NULL; |
1580 | } | 1599 | } |
1581 | 1600 | ||
@@ -1692,7 +1711,6 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs | |||
1692 | if( getRect().mLeft + KEEP_ONSCREEN_PIXELS > constraint.mRight ) | 1711 | if( getRect().mLeft + KEEP_ONSCREEN_PIXELS > constraint.mRight ) |
1693 | { | 1712 | { |
1694 | delta_x = constraint.mRight - (getRect().mLeft + KEEP_ONSCREEN_PIXELS); | 1713 | delta_x = constraint.mRight - (getRect().mLeft + KEEP_ONSCREEN_PIXELS); |
1695 | delta_x += llmax( 0, getRect().getWidth() - constraint.getWidth() ); | ||
1696 | } | 1714 | } |
1697 | 1715 | ||
1698 | if( getRect().mTop > constraint.mTop ) | 1716 | if( getRect().mTop > constraint.mTop ) |
@@ -1703,7 +1721,6 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs | |||
1703 | if( getRect().mTop - KEEP_ONSCREEN_PIXELS < constraint.mBottom ) | 1721 | if( getRect().mTop - KEEP_ONSCREEN_PIXELS < constraint.mBottom ) |
1704 | { | 1722 | { |
1705 | delta_y = constraint.mBottom - (getRect().mTop - KEEP_ONSCREEN_PIXELS); | 1723 | delta_y = constraint.mBottom - (getRect().mTop - KEEP_ONSCREEN_PIXELS); |
1706 | delta_y -= llmax( 0, getRect().getHeight() - constraint.getHeight() ); | ||
1707 | } | 1724 | } |
1708 | } | 1725 | } |
1709 | else | 1726 | else |
@@ -1716,6 +1733,7 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs | |||
1716 | if( getRect().mRight > constraint.mRight ) | 1733 | if( getRect().mRight > constraint.mRight ) |
1717 | { | 1734 | { |
1718 | delta_x = constraint.mRight - getRect().mRight; | 1735 | delta_x = constraint.mRight - getRect().mRight; |
1736 | // compensate for left edge possible going off screen | ||
1719 | delta_x += llmax( 0, getRect().getWidth() - constraint.getWidth() ); | 1737 | delta_x += llmax( 0, getRect().getWidth() - constraint.getWidth() ); |
1720 | } | 1738 | } |
1721 | 1739 | ||
@@ -1727,6 +1745,7 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs | |||
1727 | if( getRect().mBottom < constraint.mBottom ) | 1745 | if( getRect().mBottom < constraint.mBottom ) |
1728 | { | 1746 | { |
1729 | delta_y = constraint.mBottom - getRect().mBottom; | 1747 | delta_y = constraint.mBottom - getRect().mBottom; |
1748 | // compensate for top edge possible going off screen | ||
1730 | delta_y -= llmax( 0, getRect().getHeight() - constraint.getHeight() ); | 1749 | delta_y -= llmax( 0, getRect().getHeight() - constraint.getHeight() ); |
1731 | } | 1750 | } |
1732 | } | 1751 | } |
@@ -1832,9 +1851,8 @@ BOOL LLView::localRectToOtherView( const LLRect& local, LLRect* other, LLView* o | |||
1832 | // virtual | 1851 | // virtual |
1833 | LLXMLNodePtr LLView::getXML(bool save_children) const | 1852 | LLXMLNodePtr LLView::getXML(bool save_children) const |
1834 | { | 1853 | { |
1835 | const LLString& type_name = getWidgetTag(); | 1854 | //FIXME: need to provide actual derived type tag, probably outside this method |
1836 | 1855 | LLXMLNodePtr node = new LLXMLNode("view", FALSE); | |
1837 | LLXMLNodePtr node = new LLXMLNode(type_name, FALSE); | ||
1838 | 1856 | ||
1839 | node->createChild("name", TRUE)->setStringValue(getName()); | 1857 | node->createChild("name", TRUE)->setStringValue(getName()); |
1840 | node->createChild("width", TRUE)->setIntValue(getRect().getWidth()); | 1858 | node->createChild("width", TRUE)->setIntValue(getRect().getWidth()); |
@@ -1897,6 +1915,14 @@ LLXMLNodePtr LLView::getXML(bool save_children) const | |||
1897 | return node; | 1915 | return node; |
1898 | } | 1916 | } |
1899 | 1917 | ||
1918 | //static | ||
1919 | LLView* LLView::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) | ||
1920 | { | ||
1921 | LLView* viewp = new LLView(); | ||
1922 | viewp->initFromXML(node, parent); | ||
1923 | return viewp; | ||
1924 | } | ||
1925 | |||
1900 | // static | 1926 | // static |
1901 | void LLView::addColorXML(LLXMLNodePtr node, const LLColor4& color, | 1927 | void LLView::addColorXML(LLXMLNodePtr node, const LLColor4& color, |
1902 | const LLString& xml_name, const LLString& control_name) | 1928 | const LLString& xml_name, const LLString& control_name) |
@@ -2426,16 +2452,7 @@ LLSimpleListener* LLView::getListenerByName(const LLString& callback_name) | |||
2426 | return callback; | 2452 | return callback; |
2427 | } | 2453 | } |
2428 | 2454 | ||
2429 | void LLView::addListenerToControl(LLEventDispatcher *dispatcher, const LLString& name, LLSD filter, LLSD userdata) | 2455 | LLControlVariable *LLView::findControl(LLString name) |
2430 | { | ||
2431 | LLSimpleListener* listener = getListenerByName(name); | ||
2432 | if (listener) | ||
2433 | { | ||
2434 | dispatcher->addListener(listener, filter, userdata); | ||
2435 | } | ||
2436 | } | ||
2437 | |||
2438 | LLControlBase *LLView::findControl(LLString name) | ||
2439 | { | 2456 | { |
2440 | control_map_t::iterator itor = mFloaterControls.find(name); | 2457 | control_map_t::iterator itor = mFloaterControls.find(name); |
2441 | if (itor != mFloaterControls.end()) | 2458 | if (itor != mFloaterControls.end()) |
@@ -2791,9 +2808,15 @@ LLFontGL::StyleFlags LLView::selectFontStyle(LLXMLNodePtr node) | |||
2791 | return gl_font_style; | 2808 | return gl_font_style; |
2792 | } | 2809 | } |
2793 | 2810 | ||
2794 | void LLView::setControlValue(const LLSD& value) | 2811 | bool LLView::setControlValue(const LLSD& value) |
2795 | { | 2812 | { |
2796 | LLUI::sConfigGroup->setValue(getControlName(), value); | 2813 | LLString ctrlname = getControlName(); |
2814 | if (!ctrlname.empty()) | ||
2815 | { | ||
2816 | LLUI::sConfigGroup->setValue(ctrlname, value); | ||
2817 | return true; | ||
2818 | } | ||
2819 | return false; | ||
2797 | } | 2820 | } |
2798 | 2821 | ||
2799 | //virtual | 2822 | //virtual |
@@ -2804,43 +2827,57 @@ void LLView::setControlName(const LLString& control_name, LLView *context) | |||
2804 | context = this; | 2827 | context = this; |
2805 | } | 2828 | } |
2806 | 2829 | ||
2807 | // Unregister from existing listeners | ||
2808 | if (!mControlName.empty()) | 2830 | if (!mControlName.empty()) |
2809 | { | 2831 | { |
2810 | clearDispatchers(); | 2832 | llwarns << "setControlName called twice on same control!" << llendl; |
2833 | mControlConnection.disconnect(); // disconnect current signal | ||
2834 | mControlName.clear(); | ||
2811 | } | 2835 | } |
2812 | 2836 | ||
2813 | // Register new listener | 2837 | // Register new listener |
2814 | if (!control_name.empty()) | 2838 | if (!control_name.empty()) |
2815 | { | 2839 | { |
2816 | LLControlBase *control = context->findControl(control_name); | 2840 | LLControlVariable *control = context->findControl(control_name); |
2817 | if (control) | 2841 | if (control) |
2818 | { | 2842 | { |
2819 | mControlName = control_name; | 2843 | mControlName = control_name; |
2820 | LLSD state = control->registerListener(this, "DEFAULT"); | 2844 | mControlConnection = control->getSignal()->connect(boost::bind(&controlListener, _1, getHandle(), std::string("value"))); |
2821 | setValue(state); | 2845 | setValue(control->getValue()); |
2822 | } | 2846 | } |
2823 | } | 2847 | } |
2824 | } | 2848 | } |
2825 | 2849 | ||
2826 | // virtual | 2850 | // static |
2827 | bool LLView::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 2851 | bool LLView::controlListener(const LLSD& newvalue, LLHandle<LLView> handle, std::string type) |
2828 | { | 2852 | { |
2829 | if (userdata.asString() == "DEFAULT" && event->desc() == "value_changed") | 2853 | LLView* view = handle.get(); |
2854 | if (view) | ||
2830 | { | 2855 | { |
2831 | LLSD state = event->getValue(); | 2856 | if (type == "value") |
2832 | setValue(state); | 2857 | { |
2833 | return TRUE; | 2858 | view->setValue(newvalue); |
2859 | return true; | ||
2860 | } | ||
2861 | else if (type == "enabled") | ||
2862 | { | ||
2863 | view->setEnabled(newvalue.asBoolean()); | ||
2864 | return true; | ||
2865 | } | ||
2866 | else if (type == "visible") | ||
2867 | { | ||
2868 | view->setVisible(newvalue.asBoolean()); | ||
2869 | return true; | ||
2870 | } | ||
2834 | } | 2871 | } |
2835 | return FALSE; | 2872 | return false; |
2836 | } | 2873 | } |
2837 | 2874 | ||
2838 | void LLView::addBoolControl(LLString name, bool initial_value) | 2875 | void LLView::addBoolControl(LLString name, bool initial_value) |
2839 | { | 2876 | { |
2840 | mFloaterControls[name] = new LLControl(name, TYPE_BOOLEAN, initial_value, "Internal floater control"); | 2877 | mFloaterControls[name] = new LLControlVariable(name, TYPE_BOOLEAN, initial_value, "Internal floater control"); |
2841 | } | 2878 | } |
2842 | 2879 | ||
2843 | LLControlBase *LLView::getControl(LLString name) | 2880 | LLControlVariable *LLView::getControl(LLString name) |
2844 | { | 2881 | { |
2845 | control_map_t::iterator itor = mFloaterControls.find(name); | 2882 | control_map_t::iterator itor = mFloaterControls.find(name); |
2846 | if (itor != mFloaterControls.end()) | 2883 | if (itor != mFloaterControls.end()) |
@@ -2860,3 +2897,41 @@ LLSD LLView::getValue() const | |||
2860 | { | 2897 | { |
2861 | return LLSD(); | 2898 | return LLSD(); |
2862 | } | 2899 | } |
2900 | |||
2901 | LLView* LLView::createWidget(LLXMLNodePtr xml_node) const | ||
2902 | { | ||
2903 | // forward requests to ui ctrl factory | ||
2904 | return LLUICtrlFactory::getInstance()->createCtrlWidget(NULL, xml_node); | ||
2905 | } | ||
2906 | |||
2907 | // | ||
2908 | // LLWidgetClassRegistry | ||
2909 | // | ||
2910 | |||
2911 | LLWidgetClassRegistry::LLWidgetClassRegistry() | ||
2912 | { | ||
2913 | } | ||
2914 | |||
2915 | void LLWidgetClassRegistry::registerCtrl(const LLString& tag, LLWidgetClassRegistry::factory_func_t function) | ||
2916 | { | ||
2917 | LLString lower_case_tag = tag; | ||
2918 | LLString::toLower(lower_case_tag); | ||
2919 | |||
2920 | mCreatorFunctions[lower_case_tag] = function; | ||
2921 | } | ||
2922 | |||
2923 | BOOL LLWidgetClassRegistry::isTagRegistered(const LLString &tag) | ||
2924 | { | ||
2925 | return mCreatorFunctions.find(tag) != mCreatorFunctions.end(); | ||
2926 | } | ||
2927 | |||
2928 | LLWidgetClassRegistry::factory_func_t LLWidgetClassRegistry::getCreatorFunc(const LLString& ctrl_type) | ||
2929 | { | ||
2930 | factory_map_t::const_iterator found_it = mCreatorFunctions.find(ctrl_type); | ||
2931 | if (found_it == mCreatorFunctions.end()) | ||
2932 | { | ||
2933 | return NULL; | ||
2934 | } | ||
2935 | return found_it->second; | ||
2936 | } | ||
2937 | |||