lloutputmonitorctrl.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:10k
源码类别:

游戏引擎

开发平台:

C++ Builder

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