diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llui/llui.h | 330 |
1 files changed, 281 insertions, 49 deletions
diff --git a/linden/indra/llui/llui.h b/linden/indra/llui/llui.h index 9d98620..c419cb6 100644 --- a/linden/indra/llui/llui.h +++ b/linden/indra/llui/llui.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /** | 1 | /** |
2 | * @file llui.h | 2 | * @file llui.h |
3 | * @brief UI implementation | 3 | * @brief GL function declarations and other general static UI services. |
4 | * | 4 | * |
5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | 5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ |
6 | * | 6 | * |
@@ -43,7 +43,10 @@ | |||
43 | #include <stack> | 43 | #include <stack> |
44 | #include "llimagegl.h" | 44 | #include "llimagegl.h" |
45 | 45 | ||
46 | class LLColor4; | 46 | // LLUIFactory |
47 | #include "llsd.h" | ||
48 | |||
49 | class LLColor4; | ||
47 | class LLVector3; | 50 | class LLVector3; |
48 | class LLVector2; | 51 | class LLVector2; |
49 | class LLUUID; | 52 | class LLUUID; |
@@ -147,11 +150,15 @@ inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL | |||
147 | extern BOOL gShowTextEditCursor; | 150 | extern BOOL gShowTextEditCursor; |
148 | 151 | ||
149 | class LLImageProviderInterface; | 152 | class LLImageProviderInterface; |
153 | |||
150 | typedef void (*LLUIAudioCallback)(const LLUUID& uuid); | 154 | typedef void (*LLUIAudioCallback)(const LLUUID& uuid); |
151 | 155 | ||
152 | class LLUI | 156 | class LLUI |
153 | { | 157 | { |
154 | public: | 158 | public: |
159 | // | ||
160 | // Methods | ||
161 | // | ||
155 | static void initClass(LLControlGroup* config, | 162 | static void initClass(LLControlGroup* config, |
156 | LLControlGroup* colors, | 163 | LLControlGroup* colors, |
157 | LLControlGroup* assets, | 164 | LLControlGroup* assets, |
@@ -169,10 +176,10 @@ public: | |||
169 | //helper functions (should probably move free standing rendering helper functions here) | 176 | //helper functions (should probably move free standing rendering helper functions here) |
170 | static LLString locateSkin(const LLString& filename); | 177 | static LLString locateSkin(const LLString& filename); |
171 | static void setCursorPositionScreen(S32 x, S32 y); | 178 | static void setCursorPositionScreen(S32 x, S32 y); |
172 | static void setCursorPositionLocal(LLView* viewp, S32 x, S32 y); | 179 | static void setCursorPositionLocal(const LLView* viewp, S32 x, S32 y); |
173 | static void setScaleFactor(const LLVector2& scale_factor); | 180 | static void setScaleFactor(const LLVector2& scale_factor); |
174 | static void setLineWidth(F32 width); | 181 | static void setLineWidth(F32 width); |
175 | static LLUUID findAssetUUIDByName(const LLString& name); | 182 | static LLUUID findAssetUUIDByName(const LLString& name); |
176 | static LLUIImage* getUIImageByName(const LLString& name); | 183 | static LLUIImage* getUIImageByName(const LLString& name); |
177 | static LLVector2 getWindowSize(); | 184 | static LLVector2 getWindowSize(); |
178 | static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y); | 185 | static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y); |
@@ -181,7 +188,9 @@ public: | |||
181 | static void glRectToScreen(const LLRect& gl, LLRect *screen); | 188 | static void glRectToScreen(const LLRect& gl, LLRect *screen); |
182 | static void setHtmlHelp(LLHtmlHelp* html_help); | 189 | static void setHtmlHelp(LLHtmlHelp* html_help); |
183 | 190 | ||
184 | public: | 191 | // |
192 | // Data | ||
193 | // | ||
185 | static LLControlGroup* sConfigGroup; | 194 | static LLControlGroup* sConfigGroup; |
186 | static LLControlGroup* sColorsGroup; | 195 | static LLControlGroup* sColorsGroup; |
187 | static LLControlGroup* sAssetsGroup; | 196 | static LLControlGroup* sAssetsGroup; |
@@ -215,6 +224,8 @@ typedef enum e_widget_type | |||
215 | WIDGET_TYPE_SLIDER, // actually LLSliderCtrl | 224 | WIDGET_TYPE_SLIDER, // actually LLSliderCtrl |
216 | WIDGET_TYPE_SLIDER_BAR, // actually LLSlider | 225 | WIDGET_TYPE_SLIDER_BAR, // actually LLSlider |
217 | WIDGET_TYPE_VOLUME_SLIDER,//actually LLVolumeSliderCtrl | 226 | WIDGET_TYPE_VOLUME_SLIDER,//actually LLVolumeSliderCtrl |
227 | WIDGET_TYPE_MULTI_SLIDER, // actually LLMultiSliderCtrl | ||
228 | WIDGET_TYPE_MULTI_SLIDER_BAR, // actually LLMultiSlider | ||
218 | WIDGET_TYPE_SPINNER, | 229 | WIDGET_TYPE_SPINNER, |
219 | WIDGET_TYPE_TEXT_EDITOR, | 230 | WIDGET_TYPE_TEXT_EDITOR, |
220 | WIDGET_TYPE_TEXTURE_PICKER, | 231 | WIDGET_TYPE_TEXTURE_PICKER, |
@@ -287,93 +298,179 @@ typedef enum e_widget_type | |||
287 | WIDGET_TYPE_COUNT | 298 | WIDGET_TYPE_COUNT |
288 | } EWidgetType; | 299 | } EWidgetType; |
289 | 300 | ||
290 | // Manages generation of UI elements by LLSD, such that there is | 301 | // FactoryPolicy is a static class that controls the creation and lookup of UI elements, |
291 | // only one instance per uniquely identified LLSD parameter | 302 | // such as floaters. |
292 | // Class T is the instance type being managed, and INSTANCE_ADDAPTOR | 303 | // The key parameter is used to provide a unique identifier and/or associated construction |
293 | // wraps an instance of the class with handlers for show/hide semantics, etc. | 304 | // parameters for a given UI instance |
294 | template <class T, class INSTANCE_ADAPTOR = T> | 305 | // |
295 | class LLUIInstanceMgr | 306 | // Specialize this traits for different types, or provide a class with an identical interface |
307 | // in the place of the traits parameter | ||
308 | // | ||
309 | // For example: | ||
310 | // | ||
311 | // template <> | ||
312 | // class FactoryPolicy<MyClass> /* FactoryPolicy specialized for MyClass */ | ||
313 | // { | ||
314 | // public: | ||
315 | // static MyClass* findInstance(const LLSD& key = LLSD()) | ||
316 | // { | ||
317 | // /* return instance of MyClass associated with key */ | ||
318 | // } | ||
319 | // | ||
320 | // static MyClass* createInstance(const LLSD& key = LLSD()) | ||
321 | // { | ||
322 | // /* create new instance of MyClass using key for construction parameters */ | ||
323 | // } | ||
324 | // } | ||
325 | // | ||
326 | // class MyClass : public LLUIFactory<MyClass> | ||
327 | // { | ||
328 | // /* uses FactoryPolicy<MyClass> by default */ | ||
329 | // } | ||
330 | |||
331 | template <class T> | ||
332 | class FactoryPolicy | ||
333 | { | ||
334 | public: | ||
335 | // basic factory methods | ||
336 | static T* findInstance(const LLSD& key); // unimplemented, provide specialiation | ||
337 | static T* createInstance(const LLSD& key); // unimplemented, provide specialiation | ||
338 | }; | ||
339 | |||
340 | // VisibilityPolicy controls the visibility of UI elements, such as floaters. | ||
341 | // The key parameter is used to store the unique identifier of a given UI instance | ||
342 | // | ||
343 | // Specialize this traits for different types, or duplicate this interface for specific instances | ||
344 | // (see above) | ||
345 | |||
346 | template <class T> | ||
347 | class VisibilityPolicy | ||
348 | { | ||
349 | public: | ||
350 | // visibility methods | ||
351 | static bool visible(T* instance, const LLSD& key); // unimplemented, provide specialiation | ||
352 | static void show(T* instance, const LLSD& key); // unimplemented, provide specialiation | ||
353 | static void hide(T* instance, const LLSD& key); // unimplemented, provide specialiation | ||
354 | }; | ||
355 | |||
356 | // Manages generation of UI elements by LLSD, such that (generally) there is | ||
357 | // a unique instance per distinct LLSD parameter | ||
358 | // Class T is the instance type being managed, and the FACTORY_POLICY and VISIBILITY_POLICY | ||
359 | // classes provide static methods for creating, accessing, showing and hiding the associated | ||
360 | // element T | ||
361 | template <class T, class FACTORY_POLICY = FactoryPolicy<T>, class VISIBILITY_POLICY = VisibilityPolicy<T> > | ||
362 | class LLUIFactory | ||
296 | { | 363 | { |
297 | public: | 364 | public: |
298 | LLUIInstanceMgr() | 365 | // give names to the template parameters so derived classes can refer to them |
366 | // except this doesn't work in gcc | ||
367 | typedef FACTORY_POLICY factory_policy_t; | ||
368 | typedef VISIBILITY_POLICY visibility_policy_t; | ||
369 | |||
370 | LLUIFactory() | ||
299 | { | 371 | { |
300 | } | 372 | } |
301 | 373 | ||
302 | virtual ~LLUIInstanceMgr() | 374 | virtual ~LLUIFactory() |
303 | { | 375 | { |
304 | } | 376 | } |
305 | 377 | ||
306 | // default show and hide methods | 378 | // default show and hide methods |
307 | static T* showInstance(const LLSD& seed = LLSD()) | 379 | static T* showInstance(const LLSD& key = LLSD()) |
308 | { | 380 | { |
309 | T* instance = INSTANCE_ADAPTOR::getInstance(seed); | 381 | T* instance = getInstance(key); |
310 | INSTANCE_ADAPTOR::show(instance); | 382 | if (instance != NULL) |
383 | { | ||
384 | VISIBILITY_POLICY::show(instance, key); | ||
385 | } | ||
311 | return instance; | 386 | return instance; |
312 | } | 387 | } |
313 | 388 | ||
314 | static void hideInstance(const LLSD& seed = LLSD()) | 389 | static void hideInstance(const LLSD& key = LLSD()) |
315 | { | 390 | { |
316 | T* instance = INSTANCE_ADAPTOR::getInstance(seed); | 391 | T* instance = getInstance(key); |
317 | INSTANCE_ADAPTOR::hide(instance); | 392 | if (instance != NULL) |
393 | { | ||
394 | VISIBILITY_POLICY::hide(instance, key); | ||
395 | } | ||
318 | } | 396 | } |
319 | 397 | ||
320 | static void toggleInstance(const LLSD& seed = LLSD()) | 398 | static void toggleInstance(const LLSD& key = LLSD()) |
321 | { | 399 | { |
322 | if (INSTANCE_ADAPTOR::instanceVisible(seed)) | 400 | if (instanceVisible(key)) |
323 | { | 401 | { |
324 | INSTANCE_ADAPTOR::hideInstance(seed); | 402 | hideInstance(key); |
325 | } | 403 | } |
326 | else | 404 | else |
327 | { | 405 | { |
328 | INSTANCE_ADAPTOR::showInstance(seed); | 406 | showInstance(key); |
329 | } | 407 | } |
330 | } | 408 | } |
331 | 409 | ||
332 | static BOOL instanceVisible(const LLSD& seed = LLSD()) | 410 | static bool instanceVisible(const LLSD& key = LLSD()) |
333 | { | 411 | { |
334 | T* instance = INSTANCE_ADAPTOR::findInstance(seed); | 412 | T* instance = FACTORY_POLICY::findInstance(key); |
335 | return instance != NULL && INSTANCE_ADAPTOR::visible(instance); | 413 | return instance != NULL && VISIBILITY_POLICY::visible(instance, key); |
336 | } | 414 | } |
337 | 415 | ||
338 | static T* getInstance(const LLSD& seed = LLSD()) | 416 | static T* getInstance(const LLSD& key = LLSD()) |
339 | { | 417 | { |
340 | T* instance = INSTANCE_ADAPTOR::findInstance(seed); | 418 | T* instance = FACTORY_POLICY::findInstance(key); |
341 | if (instance == NULL) | 419 | if (instance == NULL) |
342 | { | 420 | { |
343 | instance = INSTANCE_ADAPTOR::createInstance(seed); | 421 | instance = FACTORY_POLICY::createInstance(key); |
344 | } | 422 | } |
345 | return instance; | 423 | return instance; |
346 | } | 424 | } |
347 | 425 | ||
348 | }; | 426 | }; |
349 | 427 | ||
350 | // Creates a UI singleton by ignoring the identifying parameter | 428 | |
351 | // and always generating the same instance via the LLUIInstanceMgr interface. | 429 | // Creates a UI singleton by ignoring the identifying parameter |
352 | // Note that since UI elements can be destroyed by their hierarchy, this singleton | 430 | // and always generating the same instance via the LLUIFactory interface. |
353 | // pattern uses a static pointer to an instance that will be re-created as needed. | 431 | // Note that since UI elements can be destroyed by their hierarchy, this singleton |
354 | template <class T, class INSTANCE_ADAPTOR = T> | 432 | // pattern uses a static pointer to an instance that will be re-created as needed. |
355 | class LLUISingleton: public LLUIInstanceMgr<T, INSTANCE_ADAPTOR> | 433 | // |
434 | // Usage Pattern: | ||
435 | // | ||
436 | // class LLFloaterFoo : public LLFloater, public LLUISingleton<LLFloaterFoo> | ||
437 | // { | ||
438 | // friend class LLUISingleton<LLFloaterFoo>; | ||
439 | // private: | ||
440 | // LLFloaterFoo(const LLSD& key); | ||
441 | // }; | ||
442 | // | ||
443 | // Note that LLUISingleton takes an option VisibilityPolicy parameter that defines | ||
444 | // how showInstance(), hideInstance(), etc. work. | ||
445 | // | ||
446 | // https://wiki.lindenlab.com/mediawiki/index.php?title=LLUISingleton&oldid=79352 | ||
447 | |||
448 | template <class T, class VISIBILITY_POLICY = VisibilityPolicy<T> > | ||
449 | class LLUISingleton: public LLUIFactory<T, LLUISingleton<T, VISIBILITY_POLICY>, VISIBILITY_POLICY> | ||
356 | { | 450 | { |
357 | public: | 451 | protected: |
358 | // default constructor assumes T is derived from LLUISingleton (a true singleton) | 452 | |
359 | LLUISingleton() : LLUIInstanceMgr<T, INSTANCE_ADAPTOR>() { sInstance = (T*)this; } | 453 | // T must derive from LLUISingleton<T> |
454 | LLUISingleton() { sInstance = static_cast<T*>(this); } | ||
455 | |||
360 | ~LLUISingleton() { sInstance = NULL; } | 456 | ~LLUISingleton() { sInstance = NULL; } |
361 | 457 | ||
362 | static T* findInstance(const LLSD& seed = LLSD()) | 458 | public: |
459 | static T* findInstance(const LLSD& key = LLSD()) | ||
363 | { | 460 | { |
364 | return sInstance; | 461 | return sInstance; |
365 | } | 462 | } |
366 | 463 | ||
367 | static T* createInstance(const LLSD& seed = LLSD()) | 464 | static T* createInstance(const LLSD& key = LLSD()) |
368 | { | 465 | { |
369 | if (sInstance == NULL) | 466 | if (sInstance == NULL) |
370 | { | 467 | { |
371 | sInstance = new T(seed); | 468 | sInstance = new T(key); |
372 | } | 469 | } |
373 | return sInstance; | 470 | return sInstance; |
374 | } | 471 | } |
375 | 472 | ||
376 | protected: | 473 | private: |
377 | static T* sInstance; | 474 | static T* sInstance; |
378 | }; | 475 | }; |
379 | 476 | ||
@@ -412,14 +509,15 @@ public: | |||
412 | void setScaleRegion(const LLRectf& region); | 509 | void setScaleRegion(const LLRectf& region); |
413 | 510 | ||
414 | LLPointer<LLImageGL> getImage() { return mImage; } | 511 | LLPointer<LLImageGL> getImage() { return mImage; } |
512 | const LLPointer<LLImageGL>& getImage() const { return mImage; } | ||
415 | 513 | ||
416 | void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR); | 514 | void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const; |
417 | void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR); | 515 | void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const; |
418 | void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color); | 516 | void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const; |
419 | void drawSolid(S32 x, S32 y, const LLColor4& color); | 517 | void drawSolid(S32 x, S32 y, const LLColor4& color) const; |
420 | 518 | ||
421 | S32 getWidth(); | 519 | S32 getWidth() const; |
422 | S32 getHeight(); | 520 | S32 getHeight() const; |
423 | 521 | ||
424 | protected: | 522 | protected: |
425 | LLRectf mScaleRegion; | 523 | LLRectf mScaleRegion; |
@@ -429,6 +527,140 @@ protected: | |||
429 | BOOL mNoClip; | 527 | BOOL mNoClip; |
430 | }; | 528 | }; |
431 | 529 | ||
530 | |||
531 | template <typename T> | ||
532 | class LLTombStone : public LLRefCount | ||
533 | { | ||
534 | public: | ||
535 | LLTombStone(T* target = NULL) : mTarget(target) {} | ||
536 | |||
537 | void setTarget(T* target) { mTarget = target; } | ||
538 | T* getTarget() const { return mTarget; } | ||
539 | private: | ||
540 | T* mTarget; | ||
541 | }; | ||
542 | |||
543 | // LLHandles are used to refer to objects whose lifetime you do not control or influence. | ||
544 | // Calling get() on a handle will return a pointer to the referenced object or NULL, | ||
545 | // if the object no longer exists. Note that during the lifetime of the returned pointer, | ||
546 | // you are assuming that the object will not be deleted by any action you perform, | ||
547 | // or any other thread, as normal when using pointers, so avoid using that pointer outside of | ||
548 | // the local code block. | ||
549 | // | ||
550 | // https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 | ||
551 | |||
552 | template <typename T> | ||
553 | class LLHandle | ||
554 | { | ||
555 | public: | ||
556 | LLHandle() : mTombStone(sDefaultTombStone) {} | ||
557 | const LLHandle<T>& operator =(const LLHandle<T>& other) | ||
558 | { | ||
559 | mTombStone = other.mTombStone; | ||
560 | return *this; | ||
561 | } | ||
562 | |||
563 | bool isDead() const | ||
564 | { | ||
565 | return mTombStone->getTarget() == NULL; | ||
566 | } | ||
567 | |||
568 | void markDead() | ||
569 | { | ||
570 | mTombStone = sDefaultTombStone; | ||
571 | } | ||
572 | |||
573 | T* get() const | ||
574 | { | ||
575 | return mTombStone->getTarget(); | ||
576 | } | ||
577 | |||
578 | friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs) | ||
579 | { | ||
580 | return lhs.mTombStone == rhs.mTombStone; | ||
581 | } | ||
582 | friend bool operator!= (const LLHandle<T>& lhs, const LLHandle<T>& rhs) | ||
583 | { | ||
584 | return !(lhs == rhs); | ||
585 | } | ||
586 | friend bool operator< (const LLHandle<T>& lhs, const LLHandle<T>& rhs) | ||
587 | { | ||
588 | return lhs.mTombStone < rhs.mTombStone; | ||
589 | } | ||
590 | friend bool operator> (const LLHandle<T>& lhs, const LLHandle<T>& rhs) | ||
591 | { | ||
592 | return lhs.mTombStone > rhs.mTombStone; | ||
593 | } | ||
594 | protected: | ||
595 | |||
596 | protected: | ||
597 | LLPointer<LLTombStone<T> > mTombStone; | ||
598 | |||
599 | private: | ||
600 | static LLPointer<LLTombStone<T> > sDefaultTombStone; | ||
601 | }; | ||
602 | |||
603 | // initialize static "empty" tombstone pointer | ||
604 | template <typename T> LLPointer<LLTombStone<T> > LLHandle<T>::sDefaultTombStone = new LLTombStone<T>(); | ||
605 | |||
606 | |||
607 | template <typename T> | ||
608 | class LLRootHandle : public LLHandle<T> | ||
609 | { | ||
610 | public: | ||
611 | LLRootHandle(T* object) { bind(object); } | ||
612 | LLRootHandle() {}; | ||
613 | ~LLRootHandle() { unbind(); } | ||
614 | |||
615 | // this is redundant, since a LLRootHandle *is* an LLHandle | ||
616 | LLHandle<T> getHandle() { return LLHandle<T>(*this); } | ||
617 | |||
618 | void bind(T* object) | ||
619 | { | ||
620 | // unbind existing tombstone | ||
621 | if (LLHandle<T>::mTombStone.notNull()) | ||
622 | { | ||
623 | if (LLHandle<T>::mTombStone->getTarget() == object) return; | ||
624 | LLHandle<T>::mTombStone->setTarget(NULL); | ||
625 | } | ||
626 | // tombstone reference counted, so no paired delete | ||
627 | LLHandle<T>::mTombStone = new LLTombStone<T>(object); | ||
628 | } | ||
629 | |||
630 | void unbind() | ||
631 | { | ||
632 | LLHandle<T>::mTombStone->setTarget(NULL); | ||
633 | } | ||
634 | |||
635 | //don't allow copying of root handles, since there should only be one | ||
636 | private: | ||
637 | LLRootHandle(const LLRootHandle& other) {}; | ||
638 | }; | ||
639 | |||
640 | // Use this as a mixin for simple classes that need handles and when you don't | ||
641 | // want handles at multiple points of the inheritance hierarchy | ||
642 | template <typename T> | ||
643 | class LLHandleProvider | ||
644 | { | ||
645 | protected: | ||
646 | typedef LLHandle<T> handle_type_t; | ||
647 | LLHandleProvider() | ||
648 | { | ||
649 | // provided here to enforce T deriving from LLHandleProvider<T> | ||
650 | } | ||
651 | |||
652 | LLHandle<T> getHandle() | ||
653 | { | ||
654 | // perform lazy binding to avoid small tombstone allocations for handle | ||
655 | // providers whose handles are never referenced | ||
656 | mHandle.bind(static_cast<T*>(this)); | ||
657 | return mHandle; | ||
658 | } | ||
659 | |||
660 | private: | ||
661 | LLRootHandle<T> mHandle; | ||
662 | }; | ||
663 | |||
432 | //RN: maybe this needs to moved elsewhere? | 664 | //RN: maybe this needs to moved elsewhere? |
433 | class LLImageProviderInterface | 665 | class LLImageProviderInterface |
434 | { | 666 | { |