diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llfloatervoicewizard.cpp | 444 |
1 files changed, 444 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloatervoicewizard.cpp b/linden/indra/newview/llfloatervoicewizard.cpp new file mode 100644 index 0000000..879cb6d --- /dev/null +++ b/linden/indra/newview/llfloatervoicewizard.cpp | |||
@@ -0,0 +1,444 @@ | |||
1 | /** | ||
2 | * @file llfloatervoicewizard.cpp | ||
3 | * @author Richard Nelson | ||
4 | * @brief Voice communication set-up wizard | ||
5 | * | ||
6 | * Copyright (c) 2007-2007, Linden Research, Inc. | ||
7 | * | ||
8 | * Second Life Viewer Source Code | ||
9 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
10 | * to you under the terms of the GNU General Public License, version 2.0 | ||
11 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
12 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
13 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
14 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
15 | * | ||
16 | * There are special exceptions to the terms and conditions of the GPL as | ||
17 | * it is applied to this Source Code. View the full text of the exception | ||
18 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
19 | * online at http://secondlife.com/developers/opensource/flossexception | ||
20 | * | ||
21 | * By copying, modifying or distributing this software, you acknowledge | ||
22 | * that you have read and understood your obligations described above, | ||
23 | * and agree to abide by those obligations. | ||
24 | * | ||
25 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
26 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
27 | * COMPLETENESS OR PERFORMANCE. | ||
28 | */ | ||
29 | |||
30 | #include "llviewerprecompiledheaders.h" | ||
31 | |||
32 | #include "llfloatervoicewizard.h" | ||
33 | |||
34 | #include "llagent.h" | ||
35 | #include "llbutton.h" | ||
36 | #include "llcombobox.h" | ||
37 | #include "llfocusmgr.h" | ||
38 | #include "lliconctrl.h" | ||
39 | #include "llprefsvoice.h" | ||
40 | #include "llsliderctrl.h" | ||
41 | #include "llviewercontrol.h" | ||
42 | #include "llvieweruictrlfactory.h" | ||
43 | #include "llvoiceclient.h" | ||
44 | #include "llimpanel.h" | ||
45 | |||
46 | LLFloaterVoiceWizard::LLFloaterVoiceWizard(const LLSD& seed) : LLFloater("floater_voice_wizard"), mDevicePanel(NULL) | ||
47 | { | ||
48 | mFactoryMap["device_settings"] = LLCallbackMap(createPanelDeviceSettings, this); | ||
49 | // do not automatically open singleton floaters (as result of getInstance()) | ||
50 | BOOL no_open = FALSE; | ||
51 | gUICtrlFactory->buildFloater(this, "floater_voice_wizard.xml", &mFactoryMap, no_open); | ||
52 | |||
53 | mLogic = new LLPrefsVoiceLogic(this); | ||
54 | center(); | ||
55 | } | ||
56 | |||
57 | LLFloaterVoiceWizard::~LLFloaterVoiceWizard() | ||
58 | { | ||
59 | delete mLogic; | ||
60 | mLogic = NULL; | ||
61 | } | ||
62 | |||
63 | BOOL LLFloaterVoiceWizard::postBuild() | ||
64 | { | ||
65 | childSetAction("next_btn", onClickNext, this); | ||
66 | childSetAction("back_btn", onClickBack, this); | ||
67 | childSetAction("ok_btn", onClickOK, this); | ||
68 | childSetAction("cancel_btn", onClickCancel, this); | ||
69 | |||
70 | childSetCommitCallback("voice_enable", onCommitVoiceEnable, this); | ||
71 | |||
72 | return TRUE; | ||
73 | } | ||
74 | |||
75 | void LLFloaterVoiceWizard::draw() | ||
76 | { | ||
77 | mLogic->refresh(); | ||
78 | if (mDevicePanel) | ||
79 | { | ||
80 | mDevicePanel->refresh(); | ||
81 | } | ||
82 | |||
83 | LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName(this, "wizard_tabs"); | ||
84 | |||
85 | if (tabs) | ||
86 | { | ||
87 | // if on first tab, disable back button, etc | ||
88 | if (tabs->getCurrentPanelIndex() == 0) | ||
89 | { | ||
90 | if (gSavedSettings.getBOOL("EnableVoiceChat")) | ||
91 | { | ||
92 | childSetEnabled("next_btn", TRUE); | ||
93 | setDefaultBtn(gUICtrlFactory->getButtonByName(this, "next_btn")); | ||
94 | } | ||
95 | else | ||
96 | { | ||
97 | childSetEnabled("next_btn", FALSE); | ||
98 | setDefaultBtn(gUICtrlFactory->getButtonByName(this, "ok_btn")); | ||
99 | } | ||
100 | childSetEnabled("back_btn", FALSE); | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | // if on any tab but the last, enable the next button | ||
105 | if (tabs->getCurrentPanelIndex() < tabs->getTabCount() - 1) | ||
106 | { | ||
107 | childSetEnabled("next_btn", TRUE); | ||
108 | setDefaultBtn(gUICtrlFactory->getButtonByName(this, "next_btn")); | ||
109 | } | ||
110 | else | ||
111 | { | ||
112 | childSetEnabled("next_btn", FALSE); | ||
113 | setDefaultBtn(gUICtrlFactory->getButtonByName(this, "ok_btn")); | ||
114 | } | ||
115 | childSetEnabled("back_btn", TRUE); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | // because we can simultaneously change voice settings from the preferences UI | ||
120 | // we need to stay in sync | ||
121 | childSetValue("voice_enable", gSavedSettings.getBOOL("EnableVoiceChat") ? "1" : "0"); | ||
122 | |||
123 | // show appropriate text on first tab | ||
124 | childSetVisible("voice_intro_text3", !gSavedSettings.getBOOL("EnableVoiceChat")); | ||
125 | childSetVisible("voice_intro_text4", gSavedSettings.getBOOL("EnableVoiceChat")); | ||
126 | |||
127 | LLFloater::draw(); | ||
128 | } | ||
129 | |||
130 | void LLFloaterVoiceWizard::onOpen() | ||
131 | { | ||
132 | // put voice client in "tuning" mode | ||
133 | gVoiceClient->tuningStart(); | ||
134 | //LLVoiceChannel::suspend(); | ||
135 | LLFloater::onOpen(); | ||
136 | } | ||
137 | |||
138 | void LLFloaterVoiceWizard::onClose(bool app_quitting) | ||
139 | { | ||
140 | gVoiceClient->tuningStop(); | ||
141 | //LLVoiceChannel::resume(); | ||
142 | LLFloater::onClose(app_quitting); | ||
143 | } | ||
144 | |||
145 | |||
146 | // static | ||
147 | void LLFloaterVoiceWizard::onClickNext(void *user_data) | ||
148 | { | ||
149 | LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName((LLFloater*)user_data, "wizard_tabs"); | ||
150 | if (tabs) | ||
151 | { | ||
152 | tabs->selectNextTab(); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | // static | ||
157 | void LLFloaterVoiceWizard::onClickBack(void *user_data) | ||
158 | { | ||
159 | LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName((LLFloater*)user_data, "wizard_tabs"); | ||
160 | if (tabs) | ||
161 | { | ||
162 | tabs->selectPrevTab(); | ||
163 | } | ||
164 | } | ||
165 | |||
166 | // static | ||
167 | void LLFloaterVoiceWizard::onClickOK(void *user_data) | ||
168 | { | ||
169 | LLFloaterVoiceWizard* self = (LLFloaterVoiceWizard*)user_data; | ||
170 | |||
171 | // propagate tuning mic volume to actual mic volume | ||
172 | self->mLogic->apply(); | ||
173 | if (self->mDevicePanel) | ||
174 | { | ||
175 | self->mDevicePanel->apply(); | ||
176 | } | ||
177 | self->close(); | ||
178 | } | ||
179 | |||
180 | // static | ||
181 | void LLFloaterVoiceWizard::onClickCancel(void *user_data) | ||
182 | { | ||
183 | LLFloaterVoiceWizard* self = (LLFloaterVoiceWizard*)user_data; | ||
184 | |||
185 | self->mLogic->cancel(); | ||
186 | if (self->mDevicePanel) | ||
187 | { | ||
188 | self->mDevicePanel->cancel(); | ||
189 | } | ||
190 | self->close(); | ||
191 | } | ||
192 | |||
193 | // static | ||
194 | void LLFloaterVoiceWizard::onCommitVoiceEnable(LLUICtrl* ctrl, void* user_data) | ||
195 | { | ||
196 | gSavedSettings.setBOOL("EnableVoiceChat", ctrl->getValue().asInteger()); | ||
197 | } | ||
198 | |||
199 | // static | ||
200 | void* LLFloaterVoiceWizard::createPanelDeviceSettings(void* user_data) | ||
201 | { | ||
202 | LLFloaterVoiceWizard* floaterp = (LLFloaterVoiceWizard*)user_data; | ||
203 | floaterp->mDevicePanel = new LLPanelDeviceSettings(); | ||
204 | return floaterp->mDevicePanel; | ||
205 | } | ||
206 | |||
207 | |||
208 | // | ||
209 | // LLPanelDeviceSettings | ||
210 | // | ||
211 | |||
212 | LLPanelDeviceSettings::LLPanelDeviceSettings() | ||
213 | { | ||
214 | mCtrlInputDevices = NULL; | ||
215 | mCtrlOutputDevices = NULL; | ||
216 | mInputDevice = gSavedSettings.getString("VoiceInputAudioDevice"); | ||
217 | mOutputDevice = gSavedSettings.getString("VoiceOutputAudioDevice"); | ||
218 | mDevicesUpdated = FALSE; | ||
219 | |||
220 | // grab "live" mic volume level | ||
221 | mMicVolume = gSavedSettings.getF32("AudioLevelMic"); | ||
222 | |||
223 | // ask for new device enumeration | ||
224 | gVoiceClient->refreshDeviceLists(); | ||
225 | } | ||
226 | |||
227 | LLPanelDeviceSettings::~LLPanelDeviceSettings() | ||
228 | { | ||
229 | } | ||
230 | |||
231 | BOOL LLPanelDeviceSettings::postBuild() | ||
232 | { | ||
233 | LLSlider* volume_slider = gUICtrlFactory->getSliderBarByName(this, "mic_volume_slider"); | ||
234 | if (volume_slider) | ||
235 | { | ||
236 | // set mic volume tuning slider based on last mic volume setting | ||
237 | volume_slider->setValue(mMicVolume); | ||
238 | } | ||
239 | |||
240 | return TRUE; | ||
241 | } | ||
242 | |||
243 | void LLPanelDeviceSettings::draw() | ||
244 | { | ||
245 | // let user know that volume indicator is not yet available | ||
246 | childSetVisible("wait_text", !gVoiceClient->inTuningMode()); | ||
247 | |||
248 | LLPanel::draw(); | ||
249 | |||
250 | F32 voice_power = gVoiceClient->tuningGetEnergy(); | ||
251 | S32 discrete_power = 0; | ||
252 | |||
253 | if (!gVoiceClient->inTuningMode()) | ||
254 | { | ||
255 | discrete_power = 0; | ||
256 | } | ||
257 | else | ||
258 | { | ||
259 | discrete_power = llmin(4, llfloor((voice_power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 4.f)); | ||
260 | } | ||
261 | |||
262 | if (gVoiceClient->inTuningMode()) | ||
263 | { | ||
264 | const S32 GAP = 5; | ||
265 | S32 cur_x = 100; | ||
266 | S32 cur_y = 15; | ||
267 | |||
268 | for(S32 power_bar_idx = 0; power_bar_idx < 5; power_bar_idx++) | ||
269 | { | ||
270 | if (power_bar_idx < discrete_power) | ||
271 | { | ||
272 | LLColor4 color = (power_bar_idx >= 3) ? gSavedSettings.getColor4("OverdrivenColor") : gSavedSettings.getColor4("SpeakingColor"); | ||
273 | gl_rect_2d(cur_x, cur_y + 20, cur_x + 20, cur_y, color, TRUE); | ||
274 | } | ||
275 | gl_rect_2d(cur_x, cur_y + 20, cur_x + 20, cur_y, LLColor4::grey, FALSE); | ||
276 | cur_x += 20 + GAP; | ||
277 | } | ||
278 | } | ||
279 | } | ||
280 | |||
281 | void LLPanelDeviceSettings::apply() | ||
282 | { | ||
283 | std::string s; | ||
284 | if(mCtrlInputDevices) | ||
285 | { | ||
286 | s = mCtrlInputDevices->getSimple(); | ||
287 | gSavedSettings.setString("VoiceInputAudioDevice", s); | ||
288 | } | ||
289 | |||
290 | if(mCtrlOutputDevices) | ||
291 | { | ||
292 | s = mCtrlOutputDevices->getSimple(); | ||
293 | gSavedSettings.setString("VoiceOutputAudioDevice", s); | ||
294 | } | ||
295 | |||
296 | // assume we are being destroyed by closing our embedding window | ||
297 | gSavedSettings.setF32("AudioLevelMic", mMicVolume); | ||
298 | } | ||
299 | |||
300 | void LLPanelDeviceSettings::cancel() | ||
301 | { | ||
302 | gSavedSettings.setString("VoiceInputAudioDevice", mInputDevice); | ||
303 | gSavedSettings.setString("VoiceOutputAudioDevice", mOutputDevice); | ||
304 | |||
305 | if(mCtrlInputDevices) | ||
306 | mCtrlInputDevices->setSimple(mInputDevice); | ||
307 | |||
308 | if(mCtrlOutputDevices) | ||
309 | mCtrlOutputDevices->setSimple(mOutputDevice); | ||
310 | } | ||
311 | |||
312 | void LLPanelDeviceSettings::refresh() | ||
313 | { | ||
314 | //grab current volume | ||
315 | LLSlider* volume_slider = gUICtrlFactory->getSliderBarByName(this, "mic_volume_slider"); | ||
316 | if (volume_slider) | ||
317 | { | ||
318 | // set mic volume tuning slider based on last mic volume setting | ||
319 | mMicVolume = (F32)volume_slider->getValue().asReal(); | ||
320 | gVoiceClient->tuningSetMicVolume(mMicVolume); | ||
321 | } | ||
322 | |||
323 | // Fill in popup menus | ||
324 | mCtrlInputDevices = LLUICtrlFactory::getComboBoxByName(this, "voice_input_device"); | ||
325 | mCtrlOutputDevices = LLUICtrlFactory::getComboBoxByName(this, "voice_output_device"); | ||
326 | |||
327 | if(!gVoiceClient->deviceSettingsAvailable()) | ||
328 | { | ||
329 | // The combo boxes are disabled, since we can't get the device settings from the daemon just now. | ||
330 | // Put the currently set default (ONLY) in the box, and select it. | ||
331 | if(mCtrlInputDevices) | ||
332 | { | ||
333 | mCtrlInputDevices->removeall(); | ||
334 | mCtrlInputDevices->add( mInputDevice, ADD_BOTTOM ); | ||
335 | mCtrlInputDevices->setSimple(mInputDevice); | ||
336 | } | ||
337 | if(mCtrlOutputDevices) | ||
338 | { | ||
339 | mCtrlOutputDevices->removeall(); | ||
340 | mCtrlOutputDevices->add( mOutputDevice, ADD_BOTTOM ); | ||
341 | mCtrlOutputDevices->setSimple(mOutputDevice); | ||
342 | } | ||
343 | } | ||
344 | else if (!mDevicesUpdated) | ||
345 | { | ||
346 | LLVoiceClient::deviceList *devices; | ||
347 | |||
348 | LLVoiceClient::deviceList::iterator iter; | ||
349 | |||
350 | if(mCtrlInputDevices) | ||
351 | { | ||
352 | mCtrlInputDevices->removeall(); | ||
353 | mCtrlInputDevices->add( "Default", ADD_BOTTOM ); | ||
354 | |||
355 | devices = gVoiceClient->getCaptureDevices(); | ||
356 | for(iter=devices->begin(); iter != devices->end(); iter++) | ||
357 | { | ||
358 | mCtrlInputDevices->add( *iter, ADD_BOTTOM ); | ||
359 | } | ||
360 | |||
361 | if(!mCtrlInputDevices->setSimple(mInputDevice)) | ||
362 | { | ||
363 | mCtrlInputDevices->setSimple("Default"); | ||
364 | } | ||
365 | } | ||
366 | |||
367 | if(mCtrlOutputDevices) | ||
368 | { | ||
369 | mCtrlOutputDevices->removeall(); | ||
370 | mCtrlOutputDevices->add( "Default", ADD_BOTTOM ); | ||
371 | |||
372 | devices = gVoiceClient->getRenderDevices(); | ||
373 | for(iter=devices->begin(); iter != devices->end(); iter++) | ||
374 | { | ||
375 | mCtrlOutputDevices->add( *iter, ADD_BOTTOM ); | ||
376 | } | ||
377 | |||
378 | if(!mCtrlOutputDevices->setSimple(mOutputDevice)) | ||
379 | { | ||
380 | mCtrlOutputDevices->setSimple("Default"); | ||
381 | } | ||
382 | } | ||
383 | mDevicesUpdated = TRUE; | ||
384 | } | ||
385 | } | ||
386 | |||
387 | // | ||
388 | // LLFloaterDeviceSettings | ||
389 | // | ||
390 | |||
391 | LLFloaterDeviceSettings::LLFloaterDeviceSettings(const LLSD& seed) : LLFloater("floater_device_settings"), mDevicePanel(NULL) | ||
392 | { | ||
393 | mFactoryMap["device_settings"] = LLCallbackMap(createPanelDeviceSettings, this); | ||
394 | gUICtrlFactory->buildFloater(this, "floater_device_settings.xml", &mFactoryMap); | ||
395 | center(); | ||
396 | } | ||
397 | |||
398 | void LLFloaterDeviceSettings::onOpen() | ||
399 | { | ||
400 | // put voice client in "tuning" mode | ||
401 | gVoiceClient->tuningStart(); | ||
402 | //LLVoiceChannel::suspend(); | ||
403 | LLFloater::onOpen(); | ||
404 | } | ||
405 | |||
406 | void LLFloaterDeviceSettings::onClose(bool app_quitting) | ||
407 | { | ||
408 | gVoiceClient->tuningStop(); | ||
409 | //LLVoiceChannel::resume(); | ||
410 | setVisible(FALSE); | ||
411 | } | ||
412 | |||
413 | void LLFloaterDeviceSettings::apply() | ||
414 | { | ||
415 | if (mDevicePanel) | ||
416 | { | ||
417 | mDevicePanel->apply(); | ||
418 | } | ||
419 | } | ||
420 | |||
421 | void LLFloaterDeviceSettings::cancel() | ||
422 | { | ||
423 | if (mDevicePanel) | ||
424 | { | ||
425 | mDevicePanel->cancel(); | ||
426 | } | ||
427 | } | ||
428 | |||
429 | void LLFloaterDeviceSettings::draw() | ||
430 | { | ||
431 | if (mDevicePanel) | ||
432 | { | ||
433 | mDevicePanel->refresh(); | ||
434 | } | ||
435 | LLFloater::draw(); | ||
436 | } | ||
437 | |||
438 | // static | ||
439 | void* LLFloaterDeviceSettings::createPanelDeviceSettings(void* user_data) | ||
440 | { | ||
441 | LLFloaterDeviceSettings* floaterp = (LLFloaterDeviceSettings*)user_data; | ||
442 | floaterp->mDevicePanel = new LLPanelDeviceSettings(); | ||
443 | return floaterp->mDevicePanel; | ||
444 | } | ||