llfloater.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. /**
  2. * @file llfloater.h
  3. * @brief LLFloater base class
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewergpl$
  6. *
  7. * Copyright (c) 2002-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. // Floating "windows" within the GL display, like the inventory floater,
  33. // mini-map floater, etc.
  34. #ifndef LL_FLOATER_H
  35. #define LL_FLOATER_H
  36. #include <set>
  37. #include "llnotifications.h"
  38. #include "llpanel.h"
  39. #include "lltabcontainer.h"
  40. class LLButton;
  41. class LLDragHandle;
  42. class LLFloater;
  43. class LLMultiFloater;
  44. class LLResizeBar;
  45. class LLResizeHandle;
  46. constexpr S32 LLFLOATER_VPAD = 6;
  47. constexpr S32 LLFLOATER_HPAD = 6;
  48. constexpr S32 LLFLOATER_CLOSE_BOX_SIZE = 16;
  49. constexpr S32 LLFLOATER_HEADER_SIZE = 18;
  50. constexpr bool RESIZE_YES = true;
  51. constexpr bool RESIZE_NO = false;
  52. constexpr S32 DEFAULT_MIN_WIDTH = 100;
  53. constexpr S32 DEFAULT_MIN_HEIGHT = 100;
  54. constexpr bool DRAG_ON_TOP = false;
  55. constexpr bool DRAG_ON_LEFT = true;
  56. constexpr bool MINIMIZE_YES = true;
  57. constexpr bool MINIMIZE_NO = false;
  58. constexpr bool CLOSE_YES = true;
  59. constexpr bool CLOSE_NO = false;
  60. constexpr bool ADJUST_VERTICAL_YES = true;
  61. constexpr bool ADJUST_VERTICAL_NO = false;
  62. // Associates a given notification instance with a particular floater
  63. class LLFloaterNotificationContext : public LLNotificationContext
  64. {
  65. public:
  66. LLFloaterNotificationContext(LLHandle<LLFloater> handle)
  67. : mFloaterHandle(handle)
  68. {
  69. }
  70. LL_INLINE LLFloater* getFloater() { return mFloaterHandle.get(); }
  71. private:
  72. LLHandle<LLFloater> mFloaterHandle;
  73. };
  74. class LLFloater : public LLPanel
  75. {
  76. friend class LLFloaterView;
  77. friend class LLHostFloater;
  78. protected:
  79. LOG_CLASS(LLFloater);
  80. public:
  81. enum EFloaterButtons
  82. {
  83. BUTTON_CLOSE,
  84. BUTTON_RESTORE,
  85. BUTTON_MINIMIZE,
  86. BUTTON_TEAR_OFF,
  87. BUTTON_COUNT
  88. };
  89. LLFloater();
  90. // Simple constructor for data-driven initialization
  91. LLFloater(const std::string& name);
  92. LLFloater(const std::string& name, const LLRect& rect,
  93. const std::string& title, bool resizable = false,
  94. S32 min_width = DEFAULT_MIN_WIDTH,
  95. S32 min_height = DEFAULT_MIN_HEIGHT,
  96. bool drag_on_left = false, bool minimizable = true,
  97. bool close_btn = true, bool bordered = BORDER_NO);
  98. LLFloater(const std::string& name, const std::string& rect_control,
  99. const std::string& title, bool resizable = false,
  100. S32 min_width = DEFAULT_MIN_WIDTH,
  101. S32 min_height = DEFAULT_MIN_HEIGHT,
  102. bool drag_on_left = false, bool minimizable = true,
  103. bool close_btn = true, bool bordered = BORDER_NO);
  104. ~LLFloater() override;
  105. LL_INLINE LLFloater* asFloater() override { return this; }
  106. const std::string& getTag() const override;
  107. LLXMLNodePtr getXML(bool save_children = true) const override;
  108. static LLView* fromXML(LLXMLNodePtr node, LLView* parent,
  109. LLUICtrlFactory* factory);
  110. void initFloaterXML(LLXMLNodePtr node, LLView* parent,
  111. LLUICtrlFactory* factory, bool open_it = true);
  112. void userSetShape(const LLRect& new_rect) override;
  113. bool canSnapTo(LLView* other_view) override;
  114. void snappedTo(LLView* snap_view) override;
  115. void setFocus(bool b) override;
  116. void setIsChrome(bool is_chrome) override;
  117. // Can be called multiple times to reset floater parameters.
  118. // Deletes all children of the floater.
  119. virtual void initFloater(const std::string& title, bool resizable,
  120. S32 min_width, S32 min_height, bool drag_on_left,
  121. bool minimizable, bool close_btn);
  122. virtual void open();
  123. // If allowed, close the floater cleanly, releasing focus. 'app_quitting'
  124. // is passed to onClose() below.
  125. virtual void close(bool app_quitting = false);
  126. // Overridden to return false for the Edit UI floater. HB
  127. LL_INLINE virtual bool canEditUI() const { return true; }
  128. void reshape(S32 width, S32 height, bool call_from_parent = true) override;
  129. // Release keyboard and mouse focus
  130. void releaseFocus();
  131. // Moves to center of gFloaterViewp
  132. void center();
  133. // Applies rectangle stored in mRectControl, if any
  134. void applyRectControl();
  135. LL_INLINE LLMultiFloater* getHost() { return (LLMultiFloater*)mHostHandle.get(); }
  136. void applyTitle();
  137. const std::string& getCurrentTitle() const;
  138. void setTitle(const std::string& title);
  139. std::string getTitle();
  140. // 'false' after the floater title has been changed via setTitle(). HB
  141. LL_INLINE bool isTitlePristine() const { return mTitleIsPristine; }
  142. void setTitleVisible(bool visible);
  143. virtual void setMinimized(bool b);
  144. void moveResizeHandlesToFront();
  145. void addDependentFloater(LLFloater* dependent, bool reposition = true);
  146. void addDependentFloater(LLHandle<LLFloater> dependent_handle,
  147. bool reposition = true);
  148. LL_INLINE LLFloater* getDependee() { return (LLFloater*)mDependeeHandle.get(); }
  149. void removeDependentFloater(LLFloater* dependent);
  150. LL_INLINE bool isMinimized() { return mMinimized; }
  151. bool isFrontmost();
  152. LL_INLINE bool isDependent() { return !mDependeeHandle.isDead(); }
  153. void setCanMinimize(bool can_minimize);
  154. void setCanClose(bool can_close);
  155. void setCanTearOff(bool can_tear_off);
  156. virtual void setCanResize(bool can_resize);
  157. void setCanDrag(bool can_drag);
  158. void setHost(LLMultiFloater* host);
  159. LL_INLINE bool isResizable() const { return mResizable; }
  160. void setResizeLimits(S32 min_width, S32 min_height);
  161. LL_INLINE void getResizeLimits(S32* min_width, S32* min_height)
  162. {
  163. *min_width = mMinWidth;
  164. *min_height = mMinHeight;
  165. }
  166. LL_INLINE bool isMinimizeable() const { return mButtonsEnabled[BUTTON_MINIMIZE]; }
  167. // Does this window have a close button, NOT can we close it right now.
  168. LL_INLINE bool isCloseable() const { return mButtonsEnabled[BUTTON_CLOSE]; }
  169. LL_INLINE bool isDragOnLeft() const { return mDragOnLeft; }
  170. LL_INLINE S32 getMinWidth() const { return mMinWidth; }
  171. LL_INLINE S32 getMinHeight() const { return mMinHeight; }
  172. bool handleMouseDown(S32 x, S32 y, MASK mask) override;
  173. bool handleRightMouseDown(S32 x, S32 y, MASK mask) override;
  174. bool handleDoubleClick(S32 x, S32 y, MASK mask) override;
  175. bool handleMiddleMouseDown(S32 x, S32 y, MASK mask) override;
  176. void draw() override;
  177. virtual void onOpen() {}
  178. // Call destroy() to free memory, or setVisible(false) to keep it
  179. // If app_quitting, you might not want to save your visibility.
  180. // Defaults to destroy().
  181. virtual void onClose(bool app_quitting) { destroy(); }
  182. // This cannot be "const" until all derived floater canClose() methods are
  183. // const as well. JC
  184. virtual bool canClose() { return true; }
  185. void setVisible(bool visible) override;
  186. void setFrontmost(bool take_focus = true);
  187. // Must default to false. Used by the texture preview floater and tested in
  188. // the viewer menu.
  189. virtual bool canSaveAs() const { return false; }
  190. virtual void saveAs() {}
  191. LL_INLINE void setSnapTarget(LLHandle<LLFloater> h) { mSnappedTo = h; }
  192. LL_INLINE void clearSnapTarget() { mSnappedTo.markDead(); }
  193. LL_INLINE LLHandle<LLFloater> getSnapTarget() const { return mSnappedTo; }
  194. LL_INLINE LLHandle<LLFloater> getHandle() const { return getDerivedHandle<LLFloater>(); }
  195. LL_INLINE U32 getId() const { return mId; }
  196. // Return a closeable floater, if any, given the current focus.
  197. static LLFloater* getClosableFloaterFromFocus();
  198. // Close the floater returned by getClosableFloaterFromFocus() and
  199. // handle refocusing.
  200. static void closeFocusedFloater();
  201. LL_INLINE LLNotification::Params contextualNotification(const std::string& name)
  202. {
  203. return LLNotification::Params(name).context(mNotificationContext);
  204. }
  205. static void onClickClose(void* userdata);
  206. static void onClickMinimize(void* userdata);
  207. static void onClickTearOff(void* userdata);
  208. // Returns true (and updated size) when a floater resizing is in progress,
  209. // or false (and untouched size) otherwise. Resets the resizing state as
  210. // well (will be re-evaluated on next frame only), so this is only to be
  211. // called once per frame (currently only used in llviewerwindow.cpp, to
  212. // display the resizing floater size. HB
  213. static bool resizing(S32& size_x, S32& size_y);
  214. LL_INLINE static LLMultiFloater* getFloaterHost() { return sHostp; }
  215. protected:
  216. virtual void bringToFront(S32 x, S32 y);
  217. virtual void setVisibleAndFrontmost(bool take_focus = true);
  218. // Size when not minimized
  219. LL_INLINE void setExpandedRect(const LLRect& rect) { mExpandedRect = rect; }
  220. LL_INLINE const LLRect& getExpandedRect() const { return mExpandedRect; }
  221. // Returns true while the floater is being resized via its resize handles
  222. // (or resize bars). HB
  223. bool resizedFromHandles() const;
  224. // Whether to automatically take focus when opened
  225. LL_INLINE void setAutoFocus(bool focus) { mAutoFocus = focus; }
  226. LL_INLINE LLDragHandle* getDragHandle() const { return mDragHandle; }
  227. // Do not call this directly. You probably want to call close(). JC
  228. LL_INLINE void destroy() { die(); }
  229. private:
  230. void setForeground(bool b); // Called only by floaterview
  231. void cleanupHandles(); // Removes handles to dead floaters
  232. void createMinimizeButton();
  233. void updateButtons();
  234. void buildButtons();
  235. bool offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index);
  236. protected:
  237. LLButton* mButtons[BUTTON_COUNT];
  238. private:
  239. LLRect mExpandedRect;
  240. LLDragHandle* mDragHandle;
  241. LLResizeBar* mResizeBar[4];
  242. LLResizeHandle* mResizeHandle[4];
  243. LLButton* mMinimizeButton;
  244. LLFloaterNotificationContext* mNotificationContext;
  245. LLHandle<LLFloater> mDependeeHandle;
  246. LLHandle<LLFloater> mSnappedTo;
  247. LLHandle<LLFloater> mHostHandle;
  248. LLHandle<LLFloater> mLastHostHandle;
  249. typedef std::set<LLHandle<LLFloater> > handle_set_t;
  250. typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t;
  251. handle_set_t mDependents;
  252. std::vector<LLHandle<LLView> > mMinimizedHiddenChildren;
  253. std::string mTitle;
  254. U32 mId; // Unique number. HB
  255. S32 mMinWidth;
  256. S32 mMinHeight;
  257. S32 mPreviousMinimizedBottom;
  258. S32 mPreviousMinimizedLeft;
  259. F32 mButtonScale;
  260. bool mButtonsEnabled[BUTTON_COUNT];
  261. bool mAutoFocus;
  262. bool mHasBeenDraggedWhileMinimized;
  263. bool mResizable;
  264. bool mCanTearOff;
  265. bool mMinimized;
  266. bool mForeground;
  267. bool mDragOnLeft;
  268. bool mTitleIsPristine;
  269. typedef void (*click_callback)(void*);
  270. static click_callback sButtonCallbacks[BUTTON_COUNT];
  271. static LLMultiFloater* sHostp;
  272. static std::string sButtonActiveImageNames[BUTTON_COUNT];
  273. static std::string sButtonInactiveImageNames[BUTTON_COUNT];
  274. static std::string sButtonPressedImageNames[BUTTON_COUNT];
  275. static std::string sButtonNames[BUTTON_COUNT];
  276. static std::string sButtonToolTipNames[BUTTON_COUNT];
  277. // Used to affect an unique number (Id) to each new floater. HB
  278. static U32 sLastFloaterId;
  279. };
  280. // Use this class in a scope to set the host of floaters you want to open
  281. // inside a multi-floater.
  282. // Declare an instance of the class in a scope, passing it a multi-floater
  283. // pointer or nothing, possibly using the set() method to change your host
  284. // floater. Then, once done opening your children floaters, make sure the
  285. // scope is closed so that the instance gets deleted: the former host will be
  286. // automatically restored. Do make sure you exited the scope before calling
  287. // open() on your host floater. HB
  288. class LLHostFloater
  289. {
  290. public:
  291. LL_INLINE LLHostFloater(LLMultiFloater* host = NULL)
  292. : mPreviousHost(LLFloater::sHostp)
  293. {
  294. LLFloater::sHostp = host;
  295. }
  296. LL_INLINE ~LLHostFloater()
  297. {
  298. LLFloater::sHostp = mPreviousHost;
  299. }
  300. LL_INLINE void set(LLMultiFloater* host)
  301. {
  302. LLFloater::sHostp = host;
  303. }
  304. private:
  305. LLMultiFloater* mPreviousHost;
  306. };
  307. ///////////////////////////////////////////////////////////////////////////////
  308. // LLFloaterView class: parent of all floating panels
  309. class LLFloaterView : public LLUICtrl
  310. {
  311. public:
  312. LLFloaterView(const std::string& name, const LLRect& rect);
  313. void reshape(S32 width, S32 height, bool call_from_parent = true) override;
  314. void reshapeFloater(S32 width, S32 height, bool called_from_parent,
  315. bool adjust_vertical);
  316. void draw() override;
  317. void refresh();
  318. LLRect getSnapRect() const override;
  319. void getNewFloaterPosition(S32* left, S32* top);
  320. void resetStartingFloaterPosition();
  321. LLRect findNeighboringPosition(LLFloater* reference_floater,
  322. LLFloater* neighbor);
  323. // Given a child of gFloaterViewp, make sure this view can fit entirely
  324. // onscreen.
  325. void adjustToFitScreen(LLFloater* floater,
  326. bool allow_partial_outside = false);
  327. void getMinimizePosition(S32* left, S32* bottom);
  328. void restoreAll(); // Un-minimize all floaters
  329. typedef std::set<LLView*> skip_list_t;
  330. void pushVisibleAll(bool visible,
  331. const skip_list_t& skip_list = skip_list_t());
  332. void popVisibleAll(const skip_list_t& skip_list = skip_list_t());
  333. // Causes all open and "visible" floaters to be adjusted to fit screen. HB
  334. void fitAllToScreen();
  335. LL_INLINE void setCycleMode(bool mode) { mFocusCycleMode = mode; }
  336. LL_INLINE bool getCycleMode() const { return mFocusCycleMode; }
  337. bool bringToFront(LLFloater* child, bool give_focus = true);
  338. void highlightFocusedFloater();
  339. void unhighlightFocusedFloater();
  340. void focusFrontFloater();
  341. void destroyAllChildren();
  342. // Attempts to close all floaters:
  343. void closeAllChildren(bool app_quitting);
  344. bool allChildrenClosed();
  345. LLFloater* getFrontmost();
  346. LLFloater* getBackmost();
  347. LLFloater* getParentFloater(LLView* viewp);
  348. LLFloater* getFocusedFloater();
  349. void syncFloaterTabOrder();
  350. // Returns z order of child provided. 0 is closest, larger numbers are
  351. // deeper in the screen. If there is no such child, the return value is not
  352. // defined.
  353. S32 getZOrder(LLFloater* child);
  354. LL_INLINE void setSnapOffsetBottom(S32 offset) { mSnapOffsetBottom = offset; }
  355. LL_INLINE static void setStackMinimizedTopToBottom(bool b)
  356. {
  357. sStackMinimizedTopToBottom = b;
  358. }
  359. LL_INLINE static void setStackMinimizedRightToLeft(bool b)
  360. {
  361. sStackMinimizedRightToLeft = b;
  362. }
  363. LL_INLINE static void setStackScreenWidthFraction(U32 f)
  364. {
  365. if (f > 0)
  366. {
  367. sStackScreenWidthFraction = f;
  368. }
  369. }
  370. private:
  371. S32 mColumn;
  372. S32 mNextLeft;
  373. S32 mNextTop;
  374. S32 mSnapOffsetBottom;
  375. bool mFocusCycleMode;
  376. static U32 sStackScreenWidthFraction;
  377. static bool sStackMinimizedTopToBottom;
  378. static bool sStackMinimizedRightToLeft;
  379. };
  380. ///////////////////////////////////////////////////////////////////////////////
  381. // LLMultiFloater class
  382. class LLMultiFloater : public LLFloater
  383. {
  384. public:
  385. LLMultiFloater();
  386. LLMultiFloater(LLTabContainer::TabPosition tab_pos);
  387. LLMultiFloater(const std::string& name);
  388. LLMultiFloater(const std::string& name, const LLRect& rect,
  389. LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP,
  390. bool auto_resize = true);
  391. LLMultiFloater(const std::string& name, const std::string& rect_control,
  392. LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP,
  393. bool auto_resize = true);
  394. const std::string& getTag() const override;
  395. LLXMLNodePtr getXML(bool save_children = true) const override;
  396. bool postBuild() override;
  397. void open() override;
  398. void onClose(bool app_quitting) override;
  399. void draw() override;
  400. void setVisible(bool visible) override;
  401. bool handleKeyHere(KEY key, MASK mask) override;
  402. void setCanResize(bool can_resize) override;
  403. // New virtual methods
  404. virtual void growToFit(S32 content_width, S32 content_height);
  405. virtual void addFloater(LLFloater* floaterp, bool select_added_floater,
  406. LLTabContainer::eInsertionPoint pos =
  407. LLTabContainer::END);
  408. virtual void updateResizeLimits();
  409. virtual void showFloater(LLFloater* floaterp);
  410. virtual void removeFloater(LLFloater* floaterp);
  411. virtual void tabOpen(LLFloater* opened_floater, bool from_click);
  412. virtual void tabClose();
  413. virtual bool selectFloater(LLFloater* floaterp);
  414. virtual void selectNextFloater();
  415. virtual void selectPrevFloater();
  416. virtual LLFloater* getActiveFloater();
  417. virtual bool isFloaterFlashing(LLFloater* floaterp);
  418. virtual S32 getFloaterCount();
  419. virtual void setFloaterFlashing(LLFloater* floaterp, bool flashing);
  420. // Returns false if the floater could not be closed due to pending
  421. // confirmation dialogs
  422. virtual bool closeAllFloaters();
  423. LL_INLINE void setTabContainer(LLTabContainer* tab_container)
  424. {
  425. if (!mTabContainer)
  426. {
  427. mTabContainer = tab_container;
  428. }
  429. }
  430. static void onTabSelected(void* userdata, bool);
  431. protected:
  432. struct LLFloaterData
  433. {
  434. S32 mWidth;
  435. S32 mHeight;
  436. bool mCanMinimize;
  437. bool mCanResize;
  438. };
  439. LLTabContainer* mTabContainer;
  440. typedef std::map<LLHandle<LLFloater>, LLFloaterData> floater_data_map_t;
  441. floater_data_map_t mFloaterDataMap;
  442. // Logically const but initialized late
  443. S32 mOrigMinWidth;
  444. S32 mOrigMinHeight;
  445. LLTabContainer::TabPosition mTabPos;
  446. bool mAutoResize;
  447. };
  448. // Visibility policy specialized for floaters
  449. template<>
  450. class VisibilityPolicy<LLFloater>
  451. {
  452. public:
  453. // Visibility methods
  454. LL_INLINE static bool visible(LLFloater* instance, const LLSD& key)
  455. {
  456. if (instance)
  457. {
  458. return !instance->isMinimized() && instance->isInVisibleChain();
  459. }
  460. return false;
  461. }
  462. LL_INLINE static void show(LLFloater* instance, const LLSD& key)
  463. {
  464. if (instance)
  465. {
  466. instance->open();
  467. if (instance->getHost())
  468. {
  469. instance->getHost()->open();
  470. }
  471. }
  472. }
  473. LL_INLINE static void hide(LLFloater* instance, const LLSD& key)
  474. {
  475. if (instance)
  476. {
  477. instance->close();
  478. }
  479. }
  480. };
  481. // Singleton implementation for floaters (provides visibility policy)
  482. template <class T> class LLFloaterSingleton
  483. : public LLUISingleton<T, VisibilityPolicy<LLFloater> >
  484. {
  485. };
  486. extern LLFloaterView* gFloaterViewp;
  487. extern S32 gMenuBarHeight;
  488. #endif // LL_FLOATER_H