/indra/llui/llui.h

https://bitbucket.org/lindenlab/viewer-beta/ · C++ Header · 609 lines · 421 code · 95 blank · 93 comment · 6 complexity · 0a72def31c7205c5e55a613bde9c9504 MD5 · raw file

  1. /**
  2. * @file llui.h
  3. * @brief GL function declarations and other general static UI services.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. // All immediate-mode gl drawing should happen here.
  27. #ifndef LL_LLUI_H
  28. #define LL_LLUI_H
  29. #include "llpointer.h" // LLPointer<>
  30. #include "llrect.h"
  31. #include "llcontrol.h"
  32. #include "llcoord.h"
  33. #include "llglslshader.h"
  34. #include "llinitparam.h"
  35. #include "llregistry.h"
  36. #include "lluicolor.h"
  37. #include "lluicolortable.h"
  38. #include <boost/signals2.hpp>
  39. #include "lllazyvalue.h"
  40. #include "llframetimer.h"
  41. #include <limits>
  42. // LLUIFactory
  43. #include "llsd.h"
  44. // for initparam specialization
  45. #include "llfontgl.h"
  46. class LLColor4;
  47. class LLVector3;
  48. class LLVector2;
  49. class LLUIImage;
  50. class LLUUID;
  51. class LLWindow;
  52. class LLView;
  53. class LLHelp;
  54. // UI colors
  55. extern const LLColor4 UI_VERTEX_COLOR;
  56. void make_ui_sound(const char* name);
  57. BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
  58. void gl_state_for_2d(S32 width, S32 height);
  59. void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2);
  60. void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color );
  61. void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled);
  62. void gl_rect_2d_simple( S32 width, S32 height );
  63. void gl_draw_x(const LLRect& rect, const LLColor4& color);
  64. void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE );
  65. void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE );
  66. void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE );
  67. void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
  68. void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
  69. void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
  70. void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
  71. void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
  72. void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled);
  73. void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle);
  74. void gl_deep_circle( F32 radius, F32 depth );
  75. void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center );
  76. void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
  77. void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
  78. void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
  79. void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
  80. void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
  81. void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
  82. void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
  83. void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
  84. void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
  85. void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f );
  86. void gl_rect_2d_simple_tex( S32 width, S32 height );
  87. // segmented rectangles
  88. /*
  89. TL |______TOP_________| TR
  90. /| |\
  91. _/_|__________________|_\_
  92. L| | MIDDLE | |R
  93. _|_|__________________|_|_
  94. \ | BOTTOM | /
  95. BL\|__________________|/ BR
  96. | |
  97. */
  98. typedef enum e_rounded_edge
  99. {
  100. ROUNDED_RECT_LEFT = 0x1,
  101. ROUNDED_RECT_TOP = 0x2,
  102. ROUNDED_RECT_RIGHT = 0x4,
  103. ROUNDED_RECT_BOTTOM = 0x8,
  104. ROUNDED_RECT_ALL = 0xf
  105. }ERoundedEdge;
  106. void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
  107. void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
  108. void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL);
  109. void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec);
  110. inline void gl_rect_2d( const LLRect& rect, BOOL filled )
  111. {
  112. gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
  113. }
  114. inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
  115. {
  116. gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
  117. }
  118. class LLImageProviderInterface;
  119. typedef void (*LLUIAudioCallback)(const LLUUID& uuid);
  120. class LLUI
  121. {
  122. LOG_CLASS(LLUI);
  123. public:
  124. //
  125. // Classes
  126. //
  127. struct RangeS32
  128. {
  129. struct Params : public LLInitParam::Block<Params>
  130. {
  131. Optional<S32> minimum,
  132. maximum;
  133. Params()
  134. : minimum("min", 0),
  135. maximum("max", S32_MAX)
  136. {}
  137. };
  138. // correct for inverted params
  139. RangeS32(const Params& p = Params())
  140. : mMin(p.minimum),
  141. mMax(p.maximum)
  142. {
  143. sanitizeRange();
  144. }
  145. RangeS32(S32 minimum, S32 maximum)
  146. : mMin(minimum),
  147. mMax(maximum)
  148. {
  149. sanitizeRange();
  150. }
  151. S32 clamp(S32 input)
  152. {
  153. if (input < mMin) return mMin;
  154. if (input > mMax) return mMax;
  155. return input;
  156. }
  157. void setRange(S32 minimum, S32 maximum)
  158. {
  159. mMin = minimum;
  160. mMax = maximum;
  161. sanitizeRange();
  162. }
  163. S32 getMin() { return mMin; }
  164. S32 getMax() { return mMax; }
  165. bool operator==(const RangeS32& other) const
  166. {
  167. return mMin == other.mMin
  168. && mMax == other.mMax;
  169. }
  170. private:
  171. void sanitizeRange()
  172. {
  173. if (mMin > mMax)
  174. {
  175. llwarns << "Bad interval range (" << mMin << ", " << mMax << ")" << llendl;
  176. // since max is usually the most dangerous one to ignore (buffer overflow, etc), prefer it
  177. // in the case of a malformed range
  178. mMin = mMax;
  179. }
  180. }
  181. S32 mMin,
  182. mMax;
  183. };
  184. struct ClampedS32 : public RangeS32
  185. {
  186. struct Params : public LLInitParam::Block<Params, RangeS32::Params>
  187. {
  188. Mandatory<S32> value;
  189. Params()
  190. : value("", 0)
  191. {
  192. addSynonym(value, "value");
  193. }
  194. };
  195. ClampedS32(const Params& p)
  196. : RangeS32(p)
  197. {}
  198. ClampedS32(const RangeS32& range)
  199. : RangeS32(range)
  200. {
  201. // set value here, after range has been sanitized
  202. mValue = clamp(0);
  203. }
  204. ClampedS32(S32 value, const RangeS32& range = RangeS32())
  205. : RangeS32(range)
  206. {
  207. mValue = clamp(value);
  208. }
  209. S32 get()
  210. {
  211. return mValue;
  212. }
  213. void set(S32 value)
  214. {
  215. mValue = clamp(value);
  216. }
  217. private:
  218. S32 mValue;
  219. };
  220. //
  221. // Methods
  222. //
  223. typedef std::map<std::string, LLControlGroup*> settings_map_t;
  224. typedef boost::function<void(LLView*)> add_popup_t;
  225. typedef boost::function<void(LLView*)> remove_popup_t;
  226. typedef boost::function<void(void)> clear_popups_t;
  227. static void initClass(const settings_map_t& settings,
  228. LLImageProviderInterface* image_provider,
  229. LLUIAudioCallback audio_callback = NULL,
  230. const LLVector2 *scale_factor = NULL,
  231. const std::string& language = LLStringUtil::null);
  232. static void cleanupClass();
  233. static void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );
  234. static void pushMatrix();
  235. static void popMatrix();
  236. static void loadIdentity();
  237. static void translate(F32 x, F32 y, F32 z = 0.0f);
  238. static LLRect sDirtyRect;
  239. static BOOL sDirty;
  240. static void dirtyRect(LLRect rect);
  241. // Return the ISO639 language name ("en", "ko", etc.) for the viewer UI.
  242. // http://www.loc.gov/standards/iso639-2/php/code_list.php
  243. static std::string getLanguage();
  244. static void setupPaths();
  245. static const std::vector<std::string>& getXUIPaths() { return sXUIPaths; }
  246. static std::string getSkinPath() { return sXUIPaths.front(); }
  247. static std::string getLocalizedSkinPath() { return sXUIPaths.back(); } //all files may not exist at the localized path
  248. //helper functions (should probably move free standing rendering helper functions here)
  249. static LLView* getRootView() { return sRootView; }
  250. static void setRootView(LLView* view) { sRootView = view; }
  251. /**
  252. * Walk the LLView tree to resolve a path
  253. * Paths can be discovered using Develop > XUI > Show XUI Paths
  254. *
  255. * A leading "/" indicates the root of the tree is the starting
  256. * position of the search, (otherwise the context node is used)
  257. *
  258. * Adjacent "//" mean that the next level of the search is done
  259. * recursively ("descendant" rather than "child").
  260. *
  261. * Return values: If no match is found, NULL is returned,
  262. * otherwise the matching LLView* is returned.
  263. *
  264. * Examples:
  265. *
  266. * "/" -> return the root view
  267. * "/foo" -> find "foo" as a direct child of the root
  268. * "foo" -> find "foo" as a direct child of the context node
  269. * "//foo" -> find the first "foo" child anywhere in the tree
  270. * "/foo/bar" -> find "foo" as direct child of the root, and
  271. * "bar" as a direct child of "foo"
  272. * "//foo//bar/baz" -> find the first "foo" anywhere in the
  273. * tree, the first "bar" anywhere under it, and "baz"
  274. * as a direct child of that
  275. */
  276. static const LLView* resolvePath(const LLView* context, const std::string& path);
  277. static LLView* resolvePath(LLView* context, const std::string& path);
  278. static std::string locateSkin(const std::string& filename);
  279. static void setMousePositionScreen(S32 x, S32 y);
  280. static void getMousePositionScreen(S32 *x, S32 *y);
  281. static void setMousePositionLocal(const LLView* viewp, S32 x, S32 y);
  282. static void getMousePositionLocal(const LLView* viewp, S32 *x, S32 *y);
  283. static void setScaleFactor(const LLVector2& scale_factor);
  284. static void setLineWidth(F32 width);
  285. static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
  286. static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
  287. static LLVector2 getWindowSize();
  288. static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y);
  289. static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
  290. static void screenRectToGL(const LLRect& screen, LLRect *gl);
  291. static void glRectToScreen(const LLRect& gl, LLRect *screen);
  292. // Returns the control group containing the control name, or the default group
  293. static LLControlGroup& getControlControlGroup (const std::string& controlname);
  294. static F32 getMouseIdleTime() { return sMouseIdleTimer.getElapsedTimeF32(); }
  295. static void resetMouseIdleTimer() { sMouseIdleTimer.reset(); }
  296. static LLWindow* getWindow() { return sWindow; }
  297. static void addPopup(LLView*);
  298. static void removePopup(LLView*);
  299. static void clearPopups();
  300. static void reportBadKeystroke();
  301. // Ensures view does not overlap mouse cursor, but is inside
  302. // the view's parent rectangle. Used for tooltips, inspectors.
  303. // Optionally override the view's default X/Y, which are relative to the
  304. // view's parent.
  305. static void positionViewNearMouse(LLView* view, S32 spawn_x = S32_MAX, S32 spawn_y = S32_MAX);
  306. //
  307. // Data
  308. //
  309. static settings_map_t sSettingGroups;
  310. static LLUIAudioCallback sAudioCallback;
  311. static LLVector2 sGLScaleFactor;
  312. static LLWindow* sWindow;
  313. static LLView* sRootView;
  314. static LLHelp* sHelpImpl;
  315. private:
  316. static LLImageProviderInterface* sImageProvider;
  317. static std::vector<std::string> sXUIPaths;
  318. static LLFrameTimer sMouseIdleTimer;
  319. static add_popup_t sAddPopupFunc;
  320. static remove_popup_t sRemovePopupFunc;
  321. static clear_popups_t sClearPopupsFunc;
  322. };
  323. // Moved LLLocalClipRect to lllocalcliprect.h
  324. //RN: maybe this needs to moved elsewhere?
  325. class LLImageProviderInterface
  326. {
  327. protected:
  328. LLImageProviderInterface() {};
  329. virtual ~LLImageProviderInterface() {};
  330. public:
  331. virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
  332. virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
  333. virtual void cleanUp() = 0;
  334. };
  335. class LLCallbackRegistry
  336. {
  337. public:
  338. typedef boost::signals2::signal<void()> callback_signal_t;
  339. void registerCallback(const callback_signal_t::slot_type& slot)
  340. {
  341. mCallbacks.connect(slot);
  342. }
  343. void fireCallbacks()
  344. {
  345. mCallbacks();
  346. }
  347. private:
  348. callback_signal_t mCallbacks;
  349. };
  350. class LLInitClassList :
  351. public LLCallbackRegistry,
  352. public LLSingleton<LLInitClassList>
  353. {
  354. friend class LLSingleton<LLInitClassList>;
  355. private:
  356. LLInitClassList() {}
  357. };
  358. class LLDestroyClassList :
  359. public LLCallbackRegistry,
  360. public LLSingleton<LLDestroyClassList>
  361. {
  362. friend class LLSingleton<LLDestroyClassList>;
  363. private:
  364. LLDestroyClassList() {}
  365. };
  366. template<typename T>
  367. class LLRegisterWith
  368. {
  369. public:
  370. LLRegisterWith(boost::function<void ()> func)
  371. {
  372. T::instance().registerCallback(func);
  373. }
  374. // this avoids a MSVC bug where non-referenced static members are "optimized" away
  375. // even if their constructors have side effects
  376. void reference()
  377. {
  378. S32 dummy;
  379. dummy = 0;
  380. }
  381. };
  382. template<typename T>
  383. class LLInitClass
  384. {
  385. public:
  386. LLInitClass() { sRegister.reference(); }
  387. static LLRegisterWith<LLInitClassList> sRegister;
  388. private:
  389. static void initClass()
  390. {
  391. llerrs << "No static initClass() method defined for " << typeid(T).name() << llendl;
  392. }
  393. };
  394. template<typename T>
  395. class LLDestroyClass
  396. {
  397. public:
  398. LLDestroyClass() { sRegister.reference(); }
  399. static LLRegisterWith<LLDestroyClassList> sRegister;
  400. private:
  401. static void destroyClass()
  402. {
  403. llerrs << "No static destroyClass() method defined for " << typeid(T).name() << llendl;
  404. }
  405. };
  406. template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(&T::initClass);
  407. template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass);
  408. // useful parameter blocks
  409. struct TimeIntervalParam : public LLInitParam::ChoiceBlock<TimeIntervalParam>
  410. {
  411. Alternative<F32> seconds;
  412. Alternative<S32> frames;
  413. TimeIntervalParam()
  414. : seconds("seconds"),
  415. frames("frames")
  416. {}
  417. };
  418. template <class T>
  419. class LLUICachedControl : public LLCachedControl<T>
  420. {
  421. public:
  422. // This constructor will declare a control if it doesn't exist in the contol group
  423. LLUICachedControl(const std::string& name,
  424. const T& default_value,
  425. const std::string& comment = "Declared In Code")
  426. : LLCachedControl<T>(LLUI::getControlControlGroup(name), name, default_value, comment)
  427. {}
  428. // This constructor will signal an error if the control doesn't exist in the control group
  429. LLUICachedControl(const std::string& name)
  430. : LLCachedControl<T>(LLUI::getControlControlGroup(name), name)
  431. {}
  432. };
  433. namespace LLInitParam
  434. {
  435. template<>
  436. class ParamValue<LLRect, TypeValues<LLRect> >
  437. : public CustomParamValue<LLRect>
  438. {
  439. typedef CustomParamValue<LLRect> super_t;
  440. public:
  441. Optional<S32> left,
  442. top,
  443. right,
  444. bottom,
  445. width,
  446. height;
  447. ParamValue(const LLRect& value);
  448. void updateValueFromBlock();
  449. void updateBlockFromValue(bool make_block_authoritative);
  450. };
  451. template<>
  452. class ParamValue<LLUIColor, TypeValues<LLUIColor> >
  453. : public CustomParamValue<LLUIColor>
  454. {
  455. typedef CustomParamValue<LLUIColor> super_t;
  456. public:
  457. Optional<F32> red,
  458. green,
  459. blue,
  460. alpha;
  461. Optional<std::string> control;
  462. ParamValue(const LLUIColor& color);
  463. void updateValueFromBlock();
  464. void updateBlockFromValue(bool make_block_authoritative);
  465. };
  466. template<>
  467. class ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >
  468. : public CustomParamValue<const LLFontGL* >
  469. {
  470. typedef CustomParamValue<const LLFontGL*> super_t;
  471. public:
  472. Optional<std::string> name,
  473. size,
  474. style;
  475. ParamValue(const LLFontGL* value);
  476. void updateValueFromBlock();
  477. void updateBlockFromValue(bool make_block_authoritative);
  478. };
  479. template<>
  480. struct TypeValues<LLFontGL::HAlign> : public TypeValuesHelper<LLFontGL::HAlign>
  481. {
  482. static void declareValues();
  483. };
  484. template<>
  485. struct TypeValues<LLFontGL::VAlign> : public TypeValuesHelper<LLFontGL::VAlign>
  486. {
  487. static void declareValues();
  488. };
  489. template<>
  490. struct TypeValues<LLFontGL::ShadowType> : public TypeValuesHelper<LLFontGL::ShadowType>
  491. {
  492. static void declareValues();
  493. };
  494. template<>
  495. struct ParamCompare<const LLFontGL*, false>
  496. {
  497. static bool equals(const LLFontGL* a, const LLFontGL* b);
  498. };
  499. template<>
  500. class ParamValue<LLCoordGL, TypeValues<LLCoordGL> >
  501. : public CustomParamValue<LLCoordGL>
  502. {
  503. typedef CustomParamValue<LLCoordGL> super_t;
  504. public:
  505. Optional<S32> x,
  506. y;
  507. ParamValue(const LLCoordGL& val);
  508. void updateValueFromBlock();
  509. void updateBlockFromValue(bool make_block_authoritative);
  510. };
  511. }
  512. extern LLGLSLShader gSolidColorProgram;
  513. extern LLGLSLShader gUIProgram;
  514. #endif