/indra/newview/llpopupview.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 271 lines · 206 code · 35 blank · 30 comment · 29 complexity · f30b59a060c7015d51ee9e81ae34d200 MD5 · raw file

  1. /**
  2. * @file llpopupview.cpp
  3. * @brief Holds transient popups
  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. #include "llviewerprecompiledheaders.h"
  27. #include "llpopupview.h"
  28. static LLRegisterPanelClassWrapper<LLPopupView> r("popup_holder");
  29. bool view_visible_and_enabled(LLView* viewp)
  30. {
  31. return viewp->getVisible() && viewp->getEnabled();
  32. }
  33. bool view_visible(LLView* viewp)
  34. {
  35. return viewp->getVisible();
  36. }
  37. LLPopupView::LLPopupView(const LLPopupView::Params& p)
  38. : LLPanel(p)
  39. {
  40. // register ourself as handler of UI popups
  41. LLUI::setPopupFuncs(boost::bind(&LLPopupView::addPopup, this, _1), boost::bind(&LLPopupView::removePopup, this, _1), boost::bind(&LLPopupView::clearPopups, this));
  42. }
  43. LLPopupView::~LLPopupView()
  44. {
  45. // set empty callback function so we can't handle popups anymore
  46. LLUI::setPopupFuncs(LLUI::add_popup_t(), LLUI::remove_popup_t(), LLUI::clear_popups_t());
  47. }
  48. void LLPopupView::draw()
  49. {
  50. S32 screen_x, screen_y;
  51. // remove dead popups
  52. for (popup_list_t::iterator popup_it = mPopups.begin();
  53. popup_it != mPopups.end();)
  54. {
  55. if (!popup_it->get())
  56. {
  57. mPopups.erase(popup_it++);
  58. }
  59. else
  60. {
  61. popup_it++;
  62. }
  63. }
  64. // draw in reverse order (most recent is on top)
  65. for (popup_list_t::reverse_iterator popup_it = mPopups.rbegin();
  66. popup_it != mPopups.rend();)
  67. {
  68. LLView* popup = popup_it->get();
  69. if (popup->getVisible())
  70. {
  71. popup->localPointToScreen(0, 0, &screen_x, &screen_y);
  72. LLUI::pushMatrix();
  73. {
  74. LLUI::translate( (F32) screen_x, (F32) screen_y, 0.f);
  75. popup->draw();
  76. }
  77. LLUI::popMatrix();
  78. }
  79. ++popup_it;
  80. }
  81. LLPanel::draw();
  82. }
  83. BOOL LLPopupView::handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)> func,
  84. boost::function<bool(LLView*)> predicate,
  85. S32 x, S32 y,
  86. bool close_popups)
  87. {
  88. BOOL handled = FALSE;
  89. // make a copy of list of popups, in case list is modified during mouse event handling
  90. popup_list_t popups(mPopups);
  91. for (popup_list_t::iterator popup_it = popups.begin(), popup_end = popups.end();
  92. popup_it != popup_end;
  93. ++popup_it)
  94. {
  95. LLView* popup = popup_it->get();
  96. if (!popup
  97. || !predicate(popup))
  98. {
  99. continue;
  100. }
  101. S32 popup_x, popup_y;
  102. if (localPointToOtherView(x, y, &popup_x, &popup_y, popup)
  103. && popup->pointInView(popup_x, popup_y))
  104. {
  105. if (func(popup, popup_x, popup_y))
  106. {
  107. handled = TRUE;
  108. break;
  109. }
  110. }
  111. if (close_popups)
  112. {
  113. mPopups.remove(*popup_it);
  114. popup->onTopLost();
  115. }
  116. }
  117. return handled;
  118. }
  119. BOOL LLPopupView::handleMouseDown(S32 x, S32 y, MASK mask)
  120. {
  121. BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true);
  122. if (!handled)
  123. {
  124. handled = LLPanel::handleMouseDown(x, y, mask);
  125. }
  126. return handled;
  127. }
  128. BOOL LLPopupView::handleMouseUp(S32 x, S32 y, MASK mask)
  129. {
  130. BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
  131. if (!handled)
  132. {
  133. handled = LLPanel::handleMouseUp(x, y, mask);
  134. }
  135. return handled;
  136. }
  137. BOOL LLPopupView::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
  138. {
  139. BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true);
  140. if (!handled)
  141. {
  142. handled = LLPanel::handleMiddleMouseDown(x, y, mask);
  143. }
  144. return handled;
  145. }
  146. BOOL LLPopupView::handleMiddleMouseUp(S32 x, S32 y, MASK mask)
  147. {
  148. BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
  149. if (!handled)
  150. {
  151. handled = LLPanel::handleMiddleMouseUp(x, y, mask);
  152. }
  153. return handled;
  154. }
  155. BOOL LLPopupView::handleRightMouseDown(S32 x, S32 y, MASK mask)
  156. {
  157. BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true);
  158. if (!handled)
  159. {
  160. handled = LLPanel::handleRightMouseDown(x, y, mask);
  161. }
  162. return handled;
  163. }
  164. BOOL LLPopupView::handleRightMouseUp(S32 x, S32 y, MASK mask)
  165. {
  166. BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
  167. if (!handled)
  168. {
  169. handled = LLPanel::handleRightMouseUp(x, y, mask);
  170. }
  171. return handled;
  172. }
  173. BOOL LLPopupView::handleDoubleClick(S32 x, S32 y, MASK mask)
  174. {
  175. BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleDoubleClick, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
  176. if (!handled)
  177. {
  178. handled = LLPanel::handleDoubleClick(x, y, mask);
  179. }
  180. return handled;
  181. }
  182. BOOL LLPopupView::handleHover(S32 x, S32 y, MASK mask)
  183. {
  184. BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleHover, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
  185. if (!handled)
  186. {
  187. handled = LLPanel::handleHover(x, y, mask);
  188. }
  189. return handled;
  190. }
  191. BOOL LLPopupView::handleScrollWheel(S32 x, S32 y, S32 clicks)
  192. {
  193. BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleScrollWheel, _1, _2, _3, clicks), view_visible_and_enabled, x, y, false);
  194. if (!handled)
  195. {
  196. handled = LLPanel::handleScrollWheel(x, y, clicks);
  197. }
  198. return handled;
  199. }
  200. BOOL LLPopupView::handleToolTip(S32 x, S32 y, MASK mask)
  201. {
  202. BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleToolTip, _1, _2, _3, mask), view_visible, x, y, false);
  203. if (!handled)
  204. {
  205. handled = LLPanel::handleToolTip(x, y, mask);
  206. }
  207. return handled;
  208. }
  209. void LLPopupView::addPopup(LLView* popup)
  210. {
  211. if (popup)
  212. {
  213. mPopups.remove(popup->getHandle());
  214. mPopups.push_front(popup->getHandle());
  215. }
  216. }
  217. void LLPopupView::removePopup(LLView* popup)
  218. {
  219. if (popup)
  220. {
  221. mPopups.remove(popup->getHandle());
  222. popup->onTopLost();
  223. }
  224. }
  225. void LLPopupView::clearPopups()
  226. {
  227. for (popup_list_t::iterator popup_it = mPopups.begin();
  228. popup_it != mPopups.end();)
  229. {
  230. LLView* popup = popup_it->get();
  231. popup_list_t::iterator cur_popup_it = popup_it;
  232. ++popup_it;
  233. mPopups.erase(cur_popup_it);
  234. popup->onTopLost();
  235. }
  236. }