diff options
Diffstat (limited to 'linden/indra/llui/llview.h')
-rw-r--r-- | linden/indra/llui/llview.h | 177 |
1 files changed, 144 insertions, 33 deletions
diff --git a/linden/indra/llui/llview.h b/linden/indra/llui/llview.h index 51c314a..9a04ed7 100644 --- a/linden/indra/llui/llview.h +++ b/linden/indra/llui/llview.h | |||
@@ -52,7 +52,6 @@ | |||
52 | #include "stdenums.h" | 52 | #include "stdenums.h" |
53 | #include "lluistring.h" | 53 | #include "lluistring.h" |
54 | 54 | ||
55 | |||
56 | const U32 FOLLOWS_NONE = 0x00; | 55 | const U32 FOLLOWS_NONE = 0x00; |
57 | const U32 FOLLOWS_LEFT = 0x01; | 56 | const U32 FOLLOWS_LEFT = 0x01; |
58 | const U32 FOLLOWS_RIGHT = 0x02; | 57 | const U32 FOLLOWS_RIGHT = 0x02; |
@@ -65,7 +64,6 @@ const BOOL NOT_MOUSE_OPAQUE = FALSE; | |||
65 | 64 | ||
66 | const U32 GL_NAME_UI_RESERVED = 2; | 65 | const U32 GL_NAME_UI_RESERVED = 2; |
67 | 66 | ||
68 | |||
69 | /* | 67 | /* |
70 | // virtual functions defined in LLView: | 68 | // virtual functions defined in LLView: |
71 | 69 | ||
@@ -120,9 +118,7 @@ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,EDragAndDropTy | |||
120 | * | 118 | * |
121 | virtual void draw(); | 119 | virtual void draw(); |
122 | * | 120 | * |
123 | virtual EWidgetType getWidgetType() const = 0; | 121 | |
124 | * | ||
125 | virtual LLString getWidgetTag() const = 0; | ||
126 | * | 122 | * |
127 | virtual LLXMLNodePtr getXML(bool save_children = true) const; | 123 | virtual LLXMLNodePtr getXML(bool save_children = true) const; |
128 | * | 124 | * |
@@ -132,7 +128,7 @@ virtual void onFocusLost() {} | |||
132 | LLUICtrl, LLScrollListCtrl, LLMenuGL, LLLineEditor, LLComboBox | 128 | LLUICtrl, LLScrollListCtrl, LLMenuGL, LLLineEditor, LLComboBox |
133 | virtual void onFocusReceived() {} | 129 | virtual void onFocusReceived() {} |
134 | LLUICtrl, LLTextEditor, LLScrollListVtrl, LLMenuGL, LLLineEditor | 130 | LLUICtrl, LLTextEditor, LLScrollListVtrl, LLMenuGL, LLLineEditor |
135 | virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; | 131 | virtual LLView* getChildView(const LLString& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; |
136 | LLTabContainer, LLPanel, LLMenuGL | 132 | LLTabContainer, LLPanel, LLMenuGL |
137 | virtual void setControlName(const LLString& control, LLView *context); | 133 | virtual void setControlName(const LLString& control, LLView *context); |
138 | LLSliderCtrl, LLCheckBoxCtrl | 134 | LLSliderCtrl, LLCheckBoxCtrl |
@@ -144,13 +140,72 @@ virtual void setValue(const LLSD& value); | |||
144 | * | 140 | * |
145 | 141 | ||
146 | protected: | 142 | protected: |
147 | virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); | 143 | virtual BOOL handleKeyHere(KEY key, MASK mask); |
148 | * | 144 | * |
149 | virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); | 145 | virtual BOOL handleUnicodeCharHere(llwchar uni_char); |
150 | * | 146 | * |
151 | */ | 147 | */ |
152 | 148 | ||
153 | class LLView : public LLMouseHandler, public LLMortician, public LLSimpleListenerObservable | 149 | class LLUICtrlFactory; |
150 | |||
151 | // maps xml strings to widget classes | ||
152 | class LLWidgetClassRegistry : public LLSingleton<LLWidgetClassRegistry> | ||
153 | { | ||
154 | friend class LLSingleton<LLWidgetClassRegistry>; | ||
155 | public: | ||
156 | typedef LLView* (*factory_func_t)(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); | ||
157 | typedef std::map<LLString, factory_func_t> factory_map_t; | ||
158 | |||
159 | void registerCtrl(const LLString& xml_tag, factory_func_t function); | ||
160 | BOOL isTagRegistered(const LLString& xml_tag); | ||
161 | factory_func_t getCreatorFunc(const LLString& xml_tag); | ||
162 | |||
163 | // get (first) xml tag for a given class | ||
164 | template <class T> std::string getTag() | ||
165 | { | ||
166 | factory_map_t::iterator it; | ||
167 | for(it = mCreatorFunctions.begin(); it != mCreatorFunctions.end(); ++it) | ||
168 | { | ||
169 | if (it->second == T::fromXML) | ||
170 | { | ||
171 | return it->first; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | return ""; | ||
176 | } | ||
177 | |||
178 | private: | ||
179 | LLWidgetClassRegistry(); | ||
180 | virtual ~LLWidgetClassRegistry() {}; | ||
181 | |||
182 | typedef std::set<LLString> ctrl_name_set_t; | ||
183 | ctrl_name_set_t mUICtrlNames; | ||
184 | |||
185 | // map of xml tags to widget creator functions | ||
186 | factory_map_t mCreatorFunctions; | ||
187 | }; | ||
188 | |||
189 | template<class T> | ||
190 | class LLRegisterWidget | ||
191 | { | ||
192 | public: | ||
193 | LLRegisterWidget(const std::string& tag) | ||
194 | { | ||
195 | LLWidgetClassRegistry* registry = LLWidgetClassRegistry::getInstance(); | ||
196 | if (registry->isTagRegistered(tag)) | ||
197 | { | ||
198 | //error! | ||
199 | llerrs << "Widget named " << tag << " already registered!" << llendl; | ||
200 | } | ||
201 | else | ||
202 | { | ||
203 | registry->registerCtrl(tag, T::fromXML); | ||
204 | } | ||
205 | } | ||
206 | }; | ||
207 | |||
208 | class LLView : public LLMouseHandler, public LLMortician | ||
154 | { | 209 | { |
155 | 210 | ||
156 | public: | 211 | public: |
@@ -294,7 +349,6 @@ public: | |||
294 | 349 | ||
295 | LLHandle<LLView> getHandle() { mHandle.bind(this); return mHandle; } | 350 | LLHandle<LLView> getHandle() { mHandle.bind(this); return mHandle; } |
296 | 351 | ||
297 | |||
298 | U32 getFollows() const { return mReshapeFlags; } | 352 | U32 getFollows() const { return mReshapeFlags; } |
299 | BOOL followsLeft() const { return mReshapeFlags & FOLLOWS_LEFT; } | 353 | BOOL followsLeft() const { return mReshapeFlags & FOLLOWS_LEFT; } |
300 | BOOL followsRight() const { return mReshapeFlags & FOLLOWS_RIGHT; } | 354 | BOOL followsRight() const { return mReshapeFlags & FOLLOWS_RIGHT; } |
@@ -355,10 +409,9 @@ public: | |||
355 | 409 | ||
356 | virtual void draw(); | 410 | virtual void draw(); |
357 | 411 | ||
358 | virtual EWidgetType getWidgetType() const = 0; | ||
359 | virtual LLString getWidgetTag() const = 0; | ||
360 | virtual LLXMLNodePtr getXML(bool save_children = true) const; | 412 | virtual LLXMLNodePtr getXML(bool save_children = true) const; |
361 | 413 | //FIXME: make LLView non-instantiable from XML | |
414 | static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); | ||
362 | virtual void initFromXML(LLXMLNodePtr node, LLView* parent); | 415 | virtual void initFromXML(LLXMLNodePtr node, LLView* parent); |
363 | void parseFollowsFlags(LLXMLNodePtr node); | 416 | void parseFollowsFlags(LLXMLNodePtr node); |
364 | 417 | ||
@@ -393,13 +446,13 @@ public: | |||
393 | void addListenerToControl(LLEventDispatcher *observer, const LLString& name, LLSD filter, LLSD userdata); | 446 | void addListenerToControl(LLEventDispatcher *observer, const LLString& name, LLSD filter, LLSD userdata); |
394 | 447 | ||
395 | void addBoolControl(LLString name, bool initial_value); | 448 | void addBoolControl(LLString name, bool initial_value); |
396 | LLControlBase *getControl(LLString name); | 449 | LLControlVariable *getControl(LLString name); |
397 | LLControlBase *findControl(LLString name); | 450 | LLControlVariable *findControl(LLString name); |
398 | 451 | ||
399 | void setControlValue(const LLSD& value); | 452 | bool setControlValue(const LLSD& value); |
400 | virtual void setControlName(const LLString& control, LLView *context); | 453 | virtual void setControlName(const LLString& control, LLView *context); |
401 | virtual LLString getControlName() const { return mControlName; } | 454 | virtual LLString getControlName() const { return mControlName; } |
402 | virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata); | 455 | // virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata); |
403 | virtual void setValue(const LLSD& value); | 456 | virtual void setValue(const LLSD& value); |
404 | virtual LLSD getValue() const; | 457 | virtual LLSD getValue() const; |
405 | 458 | ||
@@ -422,17 +475,74 @@ public: | |||
422 | /*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const; | 475 | /*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const; |
423 | /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const; | 476 | /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const; |
424 | 477 | ||
425 | template <class T> T* getChild(const LLString& name, BOOL recurse = TRUE) const | 478 | template <class T> T* getChild(const LLString& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const |
426 | { | 479 | { |
427 | T* result = dynamic_cast<T*>(getChildByName(name, TRUE)); | 480 | LLView* child = getChildView(name, recurse, FALSE); |
428 | //if (!result) | 481 | T* result = dynamic_cast<T*>(child); |
429 | //{ | 482 | if (!result) |
430 | // // create dummy widget instance here | 483 | { |
431 | // result = gUICtrlFactory->createDummyWidget<T>(name); | 484 | // did we find *something* with that name? |
432 | //} | 485 | if (child) |
486 | { | ||
487 | llwarns << "Found child named " << name << " but of wrong type" << llendl; | ||
488 | } | ||
489 | if (create_if_missing) | ||
490 | { | ||
491 | // create dummy widget instance here | ||
492 | result = createDummyWidget<T>(name); | ||
493 | } | ||
494 | } | ||
433 | return result; | 495 | return result; |
434 | } | 496 | } |
435 | 497 | ||
498 | virtual LLView* getChildView(const LLString& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; | ||
499 | |||
500 | template <class T> T* createDummyWidget(const LLString& name) const | ||
501 | { | ||
502 | T* widget = getDummyWidget<T>(name); | ||
503 | if (!widget) | ||
504 | { | ||
505 | // get xml tag name corresponding to requested widget type (e.g. "button") | ||
506 | LLString xml_tag = LLWidgetClassRegistry::getInstance()->getTag<T>(); | ||
507 | if (xml_tag.empty()) | ||
508 | { | ||
509 | llwarns << "No xml tag registered for this class " << llendl; | ||
510 | return NULL; | ||
511 | } | ||
512 | // create dummy xml node (<button name="foo"/>) | ||
513 | LLXMLNodePtr new_node_ptr = new LLXMLNode(xml_tag, FALSE); | ||
514 | new_node_ptr->createChild("name", TRUE)->setStringValue(name); | ||
515 | |||
516 | widget = dynamic_cast<T*>(createWidget(new_node_ptr)); | ||
517 | if (widget) | ||
518 | { | ||
519 | // need non-const to update private dummy widget cache | ||
520 | llwarns << "Making dummy " << xml_tag << " named " << name << " in " << getName() << llendl; | ||
521 | const_cast<LLView*>(this)->mDummyWidgets.insert(std::make_pair(name, widget)); | ||
522 | } | ||
523 | else | ||
524 | { | ||
525 | // dynamic cast will fail if T::fromXML only registered for base class | ||
526 | llwarns << "Failed to create dummy widget of requested type " << llendl; | ||
527 | return NULL; | ||
528 | } | ||
529 | } | ||
530 | return widget; | ||
531 | } | ||
532 | |||
533 | template <class T> T* getDummyWidget(const LLString& name) const | ||
534 | { | ||
535 | dummy_widget_map_t::const_iterator found_it = mDummyWidgets.find(name); | ||
536 | if (found_it == mDummyWidgets.end()) | ||
537 | { | ||
538 | return NULL; | ||
539 | } | ||
540 | return dynamic_cast<T*>(found_it->second); | ||
541 | } | ||
542 | |||
543 | LLView* createWidget(LLXMLNodePtr xml_node) const; | ||
544 | |||
545 | |||
436 | // statics | 546 | // statics |
437 | static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect()); | 547 | static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect()); |
438 | 548 | ||
@@ -471,8 +581,8 @@ public: | |||
471 | 581 | ||
472 | 582 | ||
473 | protected: | 583 | protected: |
474 | virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); | 584 | virtual BOOL handleKeyHere(KEY key, MASK mask); |
475 | virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); | 585 | virtual BOOL handleUnicodeCharHere(llwchar uni_char); |
476 | 586 | ||
477 | void drawDebugRect(); | 587 | void drawDebugRect(); |
478 | void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE); | 588 | void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE); |
@@ -494,10 +604,10 @@ protected: | |||
494 | LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); | 604 | LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); |
495 | LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask); | 605 | LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask); |
496 | 606 | ||
497 | typedef std::map<LLString, LLControlBase*> control_map_t; | 607 | static bool controlListener(const LLSD& newvalue, LLHandle<LLView> handle, std::string type); |
498 | control_map_t mFloaterControls; | ||
499 | 608 | ||
500 | virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; | 609 | typedef std::map<LLString, LLControlVariable*> control_map_t; |
610 | control_map_t mFloaterControls; | ||
501 | 611 | ||
502 | private: | 612 | private: |
503 | LLView* mParentView; | 613 | LLView* mParentView; |
@@ -538,8 +648,11 @@ private: | |||
538 | 648 | ||
539 | LLString mControlName; | 649 | LLString mControlName; |
540 | 650 | ||
651 | typedef std::map<LLString, LLView*> dummy_widget_map_t; | ||
652 | dummy_widget_map_t mDummyWidgets; | ||
541 | 653 | ||
542 | // Just debugging stuff? We should try to hide anything that's not. -MG | 654 | boost::signals::connection mControlConnection; |
655 | |||
543 | public: | 656 | public: |
544 | static BOOL sDebugRects; // Draw debug rects behind everything. | 657 | static BOOL sDebugRects; // Draw debug rects behind everything. |
545 | static BOOL sDebugKeys; | 658 | static BOOL sDebugKeys; |
@@ -554,9 +667,6 @@ public: | |||
554 | static BOOL sForceReshape; | 667 | static BOOL sForceReshape; |
555 | }; | 668 | }; |
556 | 669 | ||
557 | |||
558 | |||
559 | |||
560 | class LLCompareByTabOrder | 670 | class LLCompareByTabOrder |
561 | { | 671 | { |
562 | public: | 672 | public: |
@@ -568,4 +678,5 @@ private: | |||
568 | LLView::child_tab_order_t mTabOrder; | 678 | LLView::child_tab_order_t mTabOrder; |
569 | }; | 679 | }; |
570 | 680 | ||
681 | |||
571 | #endif //LL_LLVIEW_H | 682 | #endif //LL_LLVIEW_H |