PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/lloutputmonitorctrl.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 321 lines | 166 code | 37 blank | 118 comment | 31 complexity | 865fd8c3ab95df93be1a466bb03acdb9 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lloutputmonitorctrl.cpp
  3. * @brief LLOutputMonitorCtrl base class
  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 "lloutputmonitorctrl.h"
  28. // library includes
  29. #include "llui.h"
  30. // viewer includes
  31. #include "llvoiceclient.h"
  32. #include "llmutelist.h"
  33. #include "llagent.h"
  34. // default options set in output_monitor.xml
  35. static LLDefaultChildRegistry::Register<LLOutputMonitorCtrl> r("output_monitor");
  36. // The defaults will be initialized in the constructor.
  37. //LLColor4 LLOutputMonitorCtrl::sColorMuted;
  38. //LLColor4 LLOutputMonitorCtrl::sColorOverdriven;
  39. //LLColor4 LLOutputMonitorCtrl::sColorNormal;
  40. LLColor4 LLOutputMonitorCtrl::sColorBound;
  41. //S32 LLOutputMonitorCtrl::sRectsNumber = 0;
  42. //F32 LLOutputMonitorCtrl::sRectWidthRatio = 0.f;
  43. //F32 LLOutputMonitorCtrl::sRectHeightRatio = 0.f;
  44. LLOutputMonitorCtrl::Params::Params()
  45. : draw_border("draw_border"),
  46. image_mute("image_mute"),
  47. image_off("image_off"),
  48. image_on("image_on"),
  49. image_level_1("image_level_1"),
  50. image_level_2("image_level_2"),
  51. image_level_3("image_level_3"),
  52. auto_update("auto_update"),
  53. speaker_id("speaker_id")
  54. {
  55. };
  56. LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
  57. : LLView(p),
  58. mPower(0),
  59. mImageMute(p.image_mute),
  60. mImageOff(p.image_off),
  61. mImageOn(p.image_on),
  62. mImageLevel1(p.image_level_1),
  63. mImageLevel2(p.image_level_2),
  64. mImageLevel3(p.image_level_3),
  65. mAutoUpdate(p.auto_update),
  66. mSpeakerId(p.speaker_id),
  67. mIsAgentControl(false),
  68. mIsSwitchDirty(false),
  69. mShouldSwitchOn(false)
  70. {
  71. //static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange);
  72. //static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red);
  73. //static LLUIColor output_monitor_normal_color = LLUIColorTable::instance().getColor("OutputMonitorNotmalColor", LLColor4::green);
  74. static LLUIColor output_monitor_bound_color = LLUIColorTable::instance().getColor("OutputMonitorBoundColor", LLColor4::white);
  75. //static LLUICachedControl<S32> output_monitor_rects_number("OutputMonitorRectanglesNumber", 20);
  76. //static LLUICachedControl<F32> output_monitor_rect_width_ratio("OutputMonitorRectangleWidthRatio", 0.5f);
  77. //static LLUICachedControl<F32> output_monitor_rect_height_ratio("OutputMonitorRectangleHeightRatio", 0.8f);
  78. // IAN BUG compare to existing pattern where these are members - some will change per-widget and need to be anyway
  79. // sent feedback to PE
  80. // *TODO: it looks suboptimal to load the defaults every time an output monitor is constructed.
  81. //sColorMuted = output_monitor_muted_color;
  82. //sColorOverdriven = output_monitor_overdriven_color;
  83. //sColorNormal = output_monitor_normal_color;
  84. sColorBound = output_monitor_bound_color;
  85. //sRectsNumber = output_monitor_rects_number;
  86. //sRectWidthRatio = output_monitor_rect_width_ratio;
  87. //sRectHeightRatio = output_monitor_rect_height_ratio;
  88. mBorder = p.draw_border;
  89. //with checking mute state
  90. setSpeakerId(mSpeakerId);
  91. }
  92. LLOutputMonitorCtrl::~LLOutputMonitorCtrl()
  93. {
  94. LLMuteList::getInstance()->removeObserver(this);
  95. LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
  96. }
  97. void LLOutputMonitorCtrl::setPower(F32 val)
  98. {
  99. mPower = llmax(0.f, llmin(1.f, val));
  100. }
  101. void LLOutputMonitorCtrl::draw()
  102. {
  103. // see also switchIndicator()
  104. if (mIsSwitchDirty)
  105. {
  106. mIsSwitchDirty = false;
  107. if (mShouldSwitchOn)
  108. {
  109. // just notify parent visibility may have changed
  110. notifyParentVisibilityChanged();
  111. }
  112. else
  113. {
  114. // make itself invisible and notify parent about this
  115. setVisible(FALSE);
  116. notifyParentVisibilityChanged();
  117. // no needs to render for invisible element
  118. return;
  119. }
  120. }
  121. // Copied from llmediaremotectrl.cpp
  122. // *TODO: Give the LLOutputMonitorCtrl an agent-id to monitor, then
  123. // call directly into LLVoiceClient::getInstance() to ask if that agent-id is muted, is
  124. // speaking, and what power. This avoids duplicating data, which can get
  125. // out of sync.
  126. const F32 LEVEL_0 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL / 3.f;
  127. const F32 LEVEL_1 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL * 2.f / 3.f;
  128. const F32 LEVEL_2 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
  129. if (getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull())
  130. {
  131. setPower(LLVoiceClient::getInstance()->getCurrentPower(mSpeakerId));
  132. if(mIsAgentControl)
  133. {
  134. setIsTalking(LLVoiceClient::getInstance()->getUserPTTState());
  135. }
  136. else
  137. {
  138. setIsTalking(LLVoiceClient::getInstance()->getIsSpeaking(mSpeakerId));
  139. }
  140. }
  141. LLPointer<LLUIImage> icon;
  142. if (mIsMuted)
  143. {
  144. icon = mImageMute;
  145. }
  146. else if (mPower == 0.f && !mIsTalking)
  147. {
  148. // only show off if PTT is not engaged
  149. icon = mImageOff;
  150. }
  151. else if (mPower < LEVEL_0)
  152. {
  153. // PTT is on, possibly with quiet background noise
  154. icon = mImageOn;
  155. }
  156. else if (mPower < LEVEL_1)
  157. {
  158. icon = mImageLevel1;
  159. }
  160. else if (mPower < LEVEL_2)
  161. {
  162. icon = mImageLevel2;
  163. }
  164. else
  165. {
  166. // overdriven
  167. icon = mImageLevel3;
  168. }
  169. if (icon)
  170. {
  171. icon->draw(0, 0);
  172. }
  173. //
  174. // Fill the monitor with a bunch of small rectangles.
  175. // The rectangles will be filled with gradient color,
  176. // beginning with sColorNormal and ending with sColorOverdriven.
  177. //
  178. // *TODO: would using a (partially drawn) pixmap instead be faster?
  179. //
  180. const int monh = getRect().getHeight();
  181. const int monw = getRect().getWidth();
  182. //int maxrects = sRectsNumber;
  183. //const int period = llmax(1, monw / maxrects, 0, 0); // "1" - min value for the period
  184. //const int rectw = llmax(1, llfloor(period * sRectWidthRatio), 0, 0); // "1" - min value for the rect's width
  185. //const int recth = llfloor(monh * sRectHeightRatio);
  186. //if(period == 1 && rectw == 1) //if we have so small control, then "maxrects = monitor's_width - 2*monitor_border's_width
  187. // maxrects = monw-2;
  188. //const int nrects = mIsMuted ? maxrects : llfloor(mPower * maxrects); // how many rects to draw?
  189. //const int rectbtm = (monh - recth) / 2;
  190. //const int recttop = rectbtm + recth;
  191. //
  192. //LLColor4 rect_color;
  193. //
  194. //for (int i=1, xpos = 0; i <= nrects; i++)
  195. //{
  196. // // Calculate color to use for the current rectangle.
  197. // if (mIsMuted)
  198. // {
  199. // rect_color = sColorMuted;
  200. // }
  201. // else
  202. // {
  203. // F32 frac = (mPower * i/nrects) / LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
  204. // // Use overdriven color if the power exceeds overdriven level.
  205. // if (frac > 1.0f)
  206. // frac = 1.0f;
  207. // rect_color = lerp(sColorNormal, sColorOverdriven, frac);
  208. // }
  209. // // Draw rectangle filled with the color.
  210. // gl_rect_2d(xpos, recttop, xpos+rectw, rectbtm, rect_color, TRUE);
  211. // xpos += period;
  212. //}
  213. //
  214. // Draw bounding box.
  215. //
  216. if(mBorder)
  217. gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE);
  218. }
  219. void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/)
  220. {
  221. if (speaker_id.isNull() && mSpeakerId.notNull())
  222. {
  223. LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
  224. }
  225. if (speaker_id.isNull() || speaker_id == mSpeakerId) return;
  226. if (mSpeakerId.notNull())
  227. {
  228. // Unregister previous registration to avoid crash. EXT-4782.
  229. LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
  230. }
  231. mSpeakerId = speaker_id;
  232. LLSpeakingIndicatorManager::registerSpeakingIndicator(mSpeakerId, this, session_id);
  233. //mute management
  234. if (mAutoUpdate)
  235. {
  236. if (speaker_id == gAgentID)
  237. {
  238. setIsMuted(false);
  239. }
  240. else
  241. {
  242. // check only blocking on voice. EXT-3542
  243. setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat));
  244. LLMuteList::getInstance()->addObserver(this);
  245. }
  246. }
  247. }
  248. void LLOutputMonitorCtrl::onChange()
  249. {
  250. // check only blocking on voice. EXT-3542
  251. setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat));
  252. }
  253. // virtual
  254. void LLOutputMonitorCtrl::switchIndicator(bool switch_on)
  255. {
  256. // ensure indicator is visible in case it is not in visible chain
  257. // to be called when parent became visible next time to notify parent that visibility is changed.
  258. setVisible(TRUE);
  259. // if parent is in visible chain apply switch_on state and notify it immediately
  260. if (getParent() && getParent()->isInVisibleChain())
  261. {
  262. LL_DEBUGS("SpeakingIndicator") << "Indicator is in visible chain, notifying parent: " << mSpeakerId << LL_ENDL;
  263. setVisible((BOOL)switch_on);
  264. notifyParentVisibilityChanged();
  265. }
  266. // otherwise remember necessary state and mark itself as dirty.
  267. // State will be applied in next draw when parents chain becomes visible.
  268. else
  269. {
  270. LL_DEBUGS("SpeakingIndicator") << "Indicator is not in visible chain, parent won't be notified: " << mSpeakerId << LL_ENDL;
  271. mIsSwitchDirty = true;
  272. mShouldSwitchOn = switch_on;
  273. }
  274. }
  275. //////////////////////////////////////////////////////////////////////////
  276. // PRIVATE SECTION
  277. //////////////////////////////////////////////////////////////////////////
  278. void LLOutputMonitorCtrl::notifyParentVisibilityChanged()
  279. {
  280. LL_DEBUGS("SpeakingIndicator") << "Notify parent that visibility was changed: " << mSpeakerId << ", new_visibility: " << getVisible() << LL_ENDL;
  281. LLSD params = LLSD().with("visibility_changed", getVisible());
  282. notifyParent(params);
  283. }
  284. // EOF