PageRenderTime 571ms CodeModel.GetById 110ms app.highlight 323ms RepoModel.GetById 130ms app.codeStats 1ms

/indra/newview/llfloatereditwater.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 772 lines | 513 code | 160 blank | 99 comment | 54 complexity | f68aa3ad4722d4531ebdea8c7a92df95 MD5 | raw file
  1/** 
  2 * @file llfloatereditwater.cpp
  3 * @brief Floater to create or edit a water preset
  4 *
  5 * $LicenseInfo:firstyear=2011&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2011, 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
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "llfloatereditwater.h"
 30
 31// libs
 32#include "llbutton.h"
 33#include "llcheckboxctrl.h"
 34#include "llcolorswatch.h"
 35#include "llcombobox.h"
 36//#include "llnotifications.h"
 37#include "llnotificationsutil.h"
 38#include "llsliderctrl.h"
 39#include "lltexturectrl.h"
 40
 41// newview
 42#include "llagent.h"
 43#include "llregioninfomodel.h"
 44#include "llviewerregion.h"
 45#include "llwaterparammanager.h"
 46
 47#undef max // Fixes a Windows compiler error
 48
 49LLFloaterEditWater::LLFloaterEditWater(const LLSD &key)
 50:	LLFloater(key)
 51,	mWaterPresetNameEditor(NULL)
 52,	mWaterPresetCombo(NULL)
 53,	mMakeDefaultCheckBox(NULL)
 54,	mSaveButton(NULL)
 55{
 56}
 57
 58// virtual
 59BOOL LLFloaterEditWater::postBuild()
 60{
 61	mWaterPresetNameEditor = getChild<LLLineEditor>("water_preset_name");
 62	mWaterPresetCombo = getChild<LLComboBox>("water_preset_combo");
 63	mMakeDefaultCheckBox = getChild<LLCheckBoxCtrl>("make_default_cb");
 64	mSaveButton = getChild<LLButton>("save");
 65
 66	initCallbacks();
 67	refreshWaterPresetsList();
 68	syncControls();
 69
 70	return TRUE;
 71}
 72
 73// virtual
 74void LLFloaterEditWater::onOpen(const LLSD& key)
 75{
 76	bool new_preset = isNewPreset();
 77	std::string param = key.asString();
 78	std::string floater_title = getString(std::string("title_") + param);
 79	std::string hint = getString(std::string("hint_" + param));
 80
 81	// Update floater title.
 82	setTitle(floater_title);
 83
 84	// Update the hint at the top.
 85	getChild<LLUICtrl>("hint")->setValue(hint);
 86
 87	// Hide the hint to the right of the combo if we're invoked to create a new preset.
 88	getChildView("note")->setVisible(!new_preset);
 89
 90	// Switch between the water presets combobox and preset name input field.
 91	mWaterPresetCombo->setVisible(!new_preset);
 92	mWaterPresetNameEditor->setVisible(new_preset);
 93
 94	reset();
 95}
 96
 97// virtual
 98void LLFloaterEditWater::onClose(bool app_quitting)
 99{
100	if (!app_quitting) // there's no point to change environment if we're quitting
101	{
102		LLEnvManagerNew::instance().usePrefs(); // revert changes made to current environment
103	}
104}
105
106// virtual
107void LLFloaterEditWater::draw()
108{
109	syncControls();
110	LLFloater::draw();
111}
112
113void LLFloaterEditWater::initCallbacks(void)
114{
115	mWaterPresetNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterEditWater::onWaterPresetNameEdited, this), NULL);
116	mWaterPresetCombo->setCommitCallback(boost::bind(&LLFloaterEditWater::onWaterPresetSelected, this));
117	mWaterPresetCombo->setTextEntryCallback(boost::bind(&LLFloaterEditWater::onWaterPresetNameEdited, this));
118
119	mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditWater::onBtnSave, this));
120	getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditWater::onBtnCancel, this));
121
122	LLEnvManagerNew::instance().setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditWater::onRegionSettingsChange, this));
123	LLWaterParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditWater::onWaterPresetListChange, this));
124
125	// Connect to region info updates.
126	LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditWater::onRegionInfoUpdate, this));
127
128	//-------------------------------------------------------------------------
129
130	LLWaterParamManager& water_mgr = LLWaterParamManager::instance();
131
132	getChild<LLUICtrl>("WaterFogColor")->setCommitCallback(boost::bind(&LLFloaterEditWater::onWaterFogColorMoved, this, _1, &water_mgr.mFogColor));
133	//getChild<LLUICtrl>("WaterGlow")->setCommitCallback(boost::bind(&LLFloaterEditWater::onColorControlAMoved, this, _1, &water_mgr.mFogColor));
134
135	// fog density
136	getChild<LLUICtrl>("WaterFogDensity")->setCommitCallback(boost::bind(&LLFloaterEditWater::onExpFloatControlMoved, this, _1, &water_mgr.mFogDensity));
137	getChild<LLUICtrl>("WaterUnderWaterFogMod")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mUnderWaterFogMod));
138
139	// blue density
140	getChild<LLUICtrl>("WaterNormalScaleX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlXMoved, this, _1, &water_mgr.mNormalScale));
141	getChild<LLUICtrl>("WaterNormalScaleY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlYMoved, this, _1, &water_mgr.mNormalScale));
142	getChild<LLUICtrl>("WaterNormalScaleZ")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlZMoved, this, _1, &water_mgr.mNormalScale));
143
144	// fresnel
145	getChild<LLUICtrl>("WaterFresnelScale")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mFresnelScale));
146	getChild<LLUICtrl>("WaterFresnelOffset")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mFresnelOffset));
147
148	// scale above/below
149	getChild<LLUICtrl>("WaterScaleAbove")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mScaleAbove));
150	getChild<LLUICtrl>("WaterScaleBelow")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mScaleBelow));
151
152	// blur mult
153	getChild<LLUICtrl>("WaterBlurMult")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mBlurMultiplier));
154
155	// wave direction
156	getChild<LLUICtrl>("WaterWave1DirX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlXMoved, this, _1, &water_mgr.mWave1Dir));
157	getChild<LLUICtrl>("WaterWave1DirY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlYMoved, this, _1, &water_mgr.mWave1Dir));
158	getChild<LLUICtrl>("WaterWave2DirX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlXMoved, this, _1, &water_mgr.mWave2Dir));
159	getChild<LLUICtrl>("WaterWave2DirY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlYMoved, this, _1, &water_mgr.mWave2Dir));
160
161	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("WaterNormalMap");
162	texture_ctrl->setDefaultImageAssetID(DEFAULT_WATER_NORMAL);
163	texture_ctrl->setCommitCallback(boost::bind(&LLFloaterEditWater::onNormalMapPicked, this, _1));
164}
165
166//=============================================================================
167
168void LLFloaterEditWater::syncControls()
169{
170	// *TODO: Eliminate slow getChild() calls.
171
172	bool err;
173
174	LLWaterParamManager& water_mgr = LLWaterParamManager::instance();
175
176	LLWaterParamSet& current_params = water_mgr.mCurParams;
177
178	// blue horizon
179	water_mgr.mFogColor = current_params.getVector4(water_mgr.mFogColor.mName, err);
180
181	LLColor4 col = water_mgr.getFogColor();
182	//getChild<LLUICtrl>("WaterGlow")->setValue(col.mV[3]);
183	col.mV[3] = 1.0f;
184	getChild<LLColorSwatchCtrl>("WaterFogColor")->set(col);
185
186	// fog and wavelets
187	water_mgr.mFogDensity.mExp =
188		log(current_params.getFloat(water_mgr.mFogDensity.mName, err)) /
189		log(water_mgr.mFogDensity.mBase);
190	water_mgr.setDensitySliderValue(water_mgr.mFogDensity.mExp);
191	getChild<LLUICtrl>("WaterFogDensity")->setValue(water_mgr.mFogDensity.mExp);
192
193	water_mgr.mUnderWaterFogMod.mX =
194		current_params.getFloat(water_mgr.mUnderWaterFogMod.mName, err);
195	getChild<LLUICtrl>("WaterUnderWaterFogMod")->setValue(water_mgr.mUnderWaterFogMod.mX);
196
197	water_mgr.mNormalScale = current_params.getVector3(water_mgr.mNormalScale.mName, err);
198	getChild<LLUICtrl>("WaterNormalScaleX")->setValue(water_mgr.mNormalScale.mX);
199	getChild<LLUICtrl>("WaterNormalScaleY")->setValue(water_mgr.mNormalScale.mY);
200	getChild<LLUICtrl>("WaterNormalScaleZ")->setValue(water_mgr.mNormalScale.mZ);
201
202	// Fresnel
203	water_mgr.mFresnelScale.mX = current_params.getFloat(water_mgr.mFresnelScale.mName, err);
204	getChild<LLUICtrl>("WaterFresnelScale")->setValue(water_mgr.mFresnelScale.mX);
205	water_mgr.mFresnelOffset.mX = current_params.getFloat(water_mgr.mFresnelOffset.mName, err);
206	getChild<LLUICtrl>("WaterFresnelOffset")->setValue(water_mgr.mFresnelOffset.mX);
207
208	// Scale Above/Below
209	water_mgr.mScaleAbove.mX = current_params.getFloat(water_mgr.mScaleAbove.mName, err);
210	getChild<LLUICtrl>("WaterScaleAbove")->setValue(water_mgr.mScaleAbove.mX);
211	water_mgr.mScaleBelow.mX = current_params.getFloat(water_mgr.mScaleBelow.mName, err);
212	getChild<LLUICtrl>("WaterScaleBelow")->setValue(water_mgr.mScaleBelow.mX);
213
214	// blur mult
215	water_mgr.mBlurMultiplier.mX = current_params.getFloat(water_mgr.mBlurMultiplier.mName, err);
216	getChild<LLUICtrl>("WaterBlurMult")->setValue(water_mgr.mBlurMultiplier.mX);
217
218	// wave directions
219	water_mgr.mWave1Dir = current_params.getVector2(water_mgr.mWave1Dir.mName, err);
220	getChild<LLUICtrl>("WaterWave1DirX")->setValue(water_mgr.mWave1Dir.mX);
221	getChild<LLUICtrl>("WaterWave1DirY")->setValue(water_mgr.mWave1Dir.mY);
222
223	water_mgr.mWave2Dir = current_params.getVector2(water_mgr.mWave2Dir.mName, err);
224	getChild<LLUICtrl>("WaterWave2DirX")->setValue(water_mgr.mWave2Dir.mX);
225	getChild<LLUICtrl>("WaterWave2DirY")->setValue(water_mgr.mWave2Dir.mY);
226
227	LLTextureCtrl* textCtrl = getChild<LLTextureCtrl>("WaterNormalMap");
228	textCtrl->setImageAssetID(water_mgr.getNormalMapID());
229}
230
231// color control callbacks
232void LLFloaterEditWater::onColorControlRMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl)
233{
234	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
235
236	color_ctrl->mR = sldr_ctrl->getValueF32();
237
238	// move i if it's the max
239	if (color_ctrl->mR >= color_ctrl->mG
240		&& color_ctrl->mR >= color_ctrl->mB
241		&& color_ctrl->mHasSliderName)
242	{
243		color_ctrl->mI = color_ctrl->mR;
244		std::string name = color_ctrl->mSliderName;
245		name.append("I");
246
247		getChild<LLUICtrl>(name)->setValue(color_ctrl->mR);
248	}
249
250	color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
251
252	LLWaterParamManager::getInstance()->propagateParameters();
253}
254
255void LLFloaterEditWater::onColorControlGMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl)
256{
257	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
258
259	color_ctrl->mG = sldr_ctrl->getValueF32();
260
261	// move i if it's the max
262	if (color_ctrl->mG >= color_ctrl->mR
263		&& color_ctrl->mG >= color_ctrl->mB
264		&& color_ctrl->mHasSliderName)
265	{
266		color_ctrl->mI = color_ctrl->mG;
267		std::string name = color_ctrl->mSliderName;
268		name.append("I");
269
270		getChild<LLUICtrl>(name)->setValue(color_ctrl->mG);
271
272	}
273
274	color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
275
276	LLWaterParamManager::getInstance()->propagateParameters();
277}
278
279void LLFloaterEditWater::onColorControlBMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl)
280{
281	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
282
283	color_ctrl->mB = sldr_ctrl->getValueF32();
284
285	// move i if it's the max
286	if (color_ctrl->mB >= color_ctrl->mR
287		&& color_ctrl->mB >= color_ctrl->mG
288		&& color_ctrl->mHasSliderName)
289	{
290		color_ctrl->mI = color_ctrl->mB;
291		std::string name = color_ctrl->mSliderName;
292		name.append("I");
293
294		getChild<LLUICtrl>(name)->setValue(color_ctrl->mB);
295	}
296
297	color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
298
299	LLWaterParamManager::getInstance()->propagateParameters();
300}
301
302void LLFloaterEditWater::onColorControlAMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl)
303{
304	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
305
306	color_ctrl->mA = sldr_ctrl->getValueF32();
307
308	color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
309
310	LLWaterParamManager::getInstance()->propagateParameters();
311}
312
313
314void LLFloaterEditWater::onColorControlIMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl)
315{
316	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
317
318	color_ctrl->mI = sldr_ctrl->getValueF32();
319
320	// only for sliders where we pass a name
321	if (color_ctrl->mHasSliderName)
322	{
323		// set it to the top
324		F32 maxVal = std::max(std::max(color_ctrl->mR, color_ctrl->mG), color_ctrl->mB);
325		F32 iVal;
326
327		iVal = color_ctrl->mI;
328
329		// get the names of the other sliders
330		std::string rName = color_ctrl->mSliderName;
331		rName.append("R");
332		std::string gName = color_ctrl->mSliderName;
333		gName.append("G");
334		std::string bName = color_ctrl->mSliderName;
335		bName.append("B");
336
337		// handle if at 0
338		if (iVal == 0)
339		{
340			color_ctrl->mR = 0;
341			color_ctrl->mG = 0;
342			color_ctrl->mB = 0;
343
344		// if all at the start
345		// set them all to the intensity
346		}
347		else if (maxVal == 0)
348		{
349			color_ctrl->mR = iVal;
350			color_ctrl->mG = iVal;
351			color_ctrl->mB = iVal;
352		}
353		else
354		{
355			// add delta amounts to each
356			F32 delta = (iVal - maxVal) / maxVal;
357			color_ctrl->mR *= (1.0f + delta);
358			color_ctrl->mG *= (1.0f + delta);
359			color_ctrl->mB *= (1.0f + delta);
360		}
361
362		// set the sliders to the new vals
363		getChild<LLUICtrl>(rName)->setValue(color_ctrl->mR);
364		getChild<LLUICtrl>(gName)->setValue(color_ctrl->mG);
365		getChild<LLUICtrl>(bName)->setValue(color_ctrl->mB);
366	}
367
368	// now update the current parameters and send them to shaders
369	color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
370	LLWaterParamManager::getInstance()->propagateParameters();
371}
372
373// vector control callbacks
374void LLFloaterEditWater::onVector3ControlXMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl)
375{
376	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
377
378	vector_ctrl->mX = sldr_ctrl->getValueF32();
379
380	vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
381
382	LLWaterParamManager::getInstance()->propagateParameters();
383}
384
385// vector control callbacks
386void LLFloaterEditWater::onVector3ControlYMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl)
387{
388	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
389
390	vector_ctrl->mY = sldr_ctrl->getValueF32();
391
392	vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
393
394	LLWaterParamManager::getInstance()->propagateParameters();
395}
396
397// vector control callbacks
398void LLFloaterEditWater::onVector3ControlZMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl)
399{
400	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
401
402	vector_ctrl->mZ = sldr_ctrl->getValueF32();
403
404	vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
405
406	LLWaterParamManager::getInstance()->propagateParameters();
407}
408
409
410// vector control callbacks
411void LLFloaterEditWater::onVector2ControlXMoved(LLUICtrl* ctrl, WaterVector2Control* vector_ctrl)
412{
413	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
414
415	vector_ctrl->mX = sldr_ctrl->getValueF32();
416
417	vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
418
419	LLWaterParamManager::getInstance()->propagateParameters();
420}
421
422// vector control callbacks
423void LLFloaterEditWater::onVector2ControlYMoved(LLUICtrl* ctrl, WaterVector2Control* vector_ctrl)
424{
425	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
426
427	vector_ctrl->mY = sldr_ctrl->getValueF32();
428
429	vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
430
431	LLWaterParamManager::getInstance()->propagateParameters();
432}
433
434void LLFloaterEditWater::onFloatControlMoved(LLUICtrl* ctrl, WaterFloatControl* floatControl)
435{
436	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
437
438	floatControl->mX = sldr_ctrl->getValueF32() / floatControl->mMult;
439
440	floatControl->update(LLWaterParamManager::getInstance()->mCurParams);
441	LLWaterParamManager::getInstance()->propagateParameters();
442}
443
444void LLFloaterEditWater::onExpFloatControlMoved(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl)
445{
446	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
447
448	F32 val = sldr_ctrl->getValueF32();
449	expFloatControl->mExp = val;
450	LLWaterParamManager::getInstance()->setDensitySliderValue(val);
451
452	expFloatControl->update(LLWaterParamManager::getInstance()->mCurParams);
453	LLWaterParamManager::getInstance()->propagateParameters();
454}
455
456void LLFloaterEditWater::onWaterFogColorMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl)
457{
458	LLColorSwatchCtrl* swatch = static_cast<LLColorSwatchCtrl*>(ctrl);
459	*color_ctrl = swatch->get();
460
461	color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
462	LLWaterParamManager::getInstance()->propagateParameters();
463}
464
465void LLFloaterEditWater::onNormalMapPicked(LLUICtrl* ctrl)
466{
467	LLTextureCtrl* textCtrl = static_cast<LLTextureCtrl*>(ctrl);
468	LLUUID textID = textCtrl->getImageAssetID();
469	LLWaterParamManager::getInstance()->setNormalMapID(textID);
470}
471
472//=============================================================================
473
474void LLFloaterEditWater::reset()
475{
476	if (isNewPreset())
477	{
478		mWaterPresetNameEditor->setValue(LLSD());
479		mSaveButton->setEnabled(FALSE); // will be enabled as soon as users enters a name
480	}
481	else
482	{
483		refreshWaterPresetsList();
484
485		// Disable controls until a water preset to edit is selected.
486		enableEditing(false);
487	}
488}
489
490bool LLFloaterEditWater::isNewPreset() const
491{
492	return mKey.asString() == "new";
493}
494
495void LLFloaterEditWater::refreshWaterPresetsList()
496{
497	mWaterPresetCombo->removeall();
498
499#if 0 // *TODO: enable when we have a clear workflow to edit existing region environment
500	// If the region already has water params, add them to the list.
501	const LLEnvironmentSettings& region_settings = LLEnvManagerNew::instance().getRegionSettings();
502	if (region_settings.getWaterParams().size() != 0)
503	{
504		const std::string& region_name = gAgent.getRegion()->getName();
505		mWaterPresetCombo->add(region_name, LLSD().with(0, region_name).with(1, LLEnvKey::SCOPE_REGION));
506		mWaterPresetCombo->addSeparator();
507	}
508#endif
509
510	std::list<std::string> user_presets, system_presets;
511	LLWaterParamManager::instance().getPresetNames(user_presets, system_presets);
512
513	// Add local user presets first.
514	for (std::list<std::string>::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
515	{
516		const std::string& name = *it;
517		mWaterPresetCombo->add(name, LLSD().with(0, name).with(1, LLEnvKey::SCOPE_LOCAL)); // [<name>, <scope>]
518	}
519
520	if (user_presets.size() > 0)
521	{
522		mWaterPresetCombo->addSeparator();
523	}
524
525	// Add local system presets.
526	for (std::list<std::string>::const_iterator it = system_presets.begin(); it != system_presets.end(); ++it)
527	{
528		const std::string& name = *it;
529		mWaterPresetCombo->add(name, LLSD().with(0, name).with(1, LLEnvKey::SCOPE_LOCAL)); // [<name>, <scope>]
530	}
531
532	mWaterPresetCombo->setLabel(getString("combo_label"));
533}
534
535void LLFloaterEditWater::enableEditing(bool enable)
536{
537	// Enable/disable water controls.
538	getChild<LLPanel>("panel_water_preset")->setCtrlsEnabled(enable);
539
540	// Enable/disable saving.
541	mSaveButton->setEnabled(enable);
542	mMakeDefaultCheckBox->setEnabled(enable);
543}
544
545void LLFloaterEditWater::saveRegionWater()
546{
547	llassert(getCurrentScope() == LLEnvKey::SCOPE_REGION); // make sure we're editing region water
548
549	LL_DEBUGS("Windlight") << "Saving region water preset" << llendl;
550
551	//LLWaterParamSet region_water = water_mgr.mCurParams;
552
553	// *TODO: save to cached region settings.
554	LL_WARNS("Windlight") << "Saving region water is not fully implemented yet" << LL_ENDL;
555}
556
557std::string LLFloaterEditWater::getCurrentPresetName() const
558{
559	std::string name;
560	LLEnvKey::EScope scope;
561	getSelectedPreset(name, scope);
562	return name;
563}
564
565LLEnvKey::EScope LLFloaterEditWater::getCurrentScope() const
566{
567	std::string name;
568	LLEnvKey::EScope scope;
569	getSelectedPreset(name, scope);
570	return scope;
571}
572
573void LLFloaterEditWater::getSelectedPreset(std::string& name, LLEnvKey::EScope& scope) const
574{
575	if (mWaterPresetNameEditor->getVisible())
576	{
577		name = mWaterPresetNameEditor->getText();
578		scope = LLEnvKey::SCOPE_LOCAL;
579	}
580	else
581	{
582		LLSD combo_val = mWaterPresetCombo->getValue();
583
584		if (!combo_val.isArray()) // manually typed text
585		{
586			name = combo_val.asString();
587			scope = LLEnvKey::SCOPE_LOCAL;
588		}
589		else
590		{
591			name = combo_val[0].asString();
592			scope = (LLEnvKey::EScope) combo_val[1].asInteger();
593		}
594	}
595}
596
597void LLFloaterEditWater::onWaterPresetNameEdited()
598{
599	// Disable saving a water preset having empty name.
600	mSaveButton->setEnabled(!getCurrentPresetName().empty());
601}
602
603void LLFloaterEditWater::onWaterPresetSelected()
604{
605	LLWaterParamSet water_params;
606	std::string name;
607	LLEnvKey::EScope scope;
608
609	getSelectedPreset(name, scope);
610
611	// Display selected preset.
612	if (scope == LLEnvKey::SCOPE_REGION)
613	{
614		water_params.setAll(LLEnvManagerNew::instance().getRegionSettings().getWaterParams());
615	}
616	else // local preset selected
617	{
618		if (!LLWaterParamManager::instance().getParamSet(name, water_params))
619		{
620			// Manually entered string?
621			LL_WARNS("Windlight") << "No water preset named " << name << LL_ENDL;
622			return;
623		}
624	}
625
626	LLEnvManagerNew::instance().useWaterParams(water_params.getAll());
627
628	bool can_edit = (scope == LLEnvKey::SCOPE_LOCAL || LLEnvManagerNew::canEditRegionSettings());
629	enableEditing(can_edit);
630
631	mMakeDefaultCheckBox->setEnabled(scope == LLEnvKey::SCOPE_LOCAL);
632}
633
634bool LLFloaterEditWater::onSaveAnswer(const LLSD& notification, const LLSD& response)
635{
636	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
637
638	// If they choose save, do it.  Otherwise, don't do anything
639	if (option == 0)
640	{
641		onSaveConfirmed();
642	}
643
644	return false;
645}
646
647void LLFloaterEditWater::onSaveConfirmed()
648{
649	// Save currently displayed water params to the selected preset.
650	std::string name = getCurrentPresetName();
651
652	LL_DEBUGS("Windlight") << "Saving sky preset " << name << LL_ENDL;
653	LLWaterParamManager& water_mgr = LLWaterParamManager::instance();
654	if (water_mgr.hasParamSet(name))
655	{
656		water_mgr.setParamSet(name, water_mgr.mCurParams);
657	}
658	else
659	{
660		water_mgr.addParamSet(name, water_mgr.mCurParams);
661	}
662
663	water_mgr.savePreset(name);
664
665	// Change preference if requested.
666	if (mMakeDefaultCheckBox->getEnabled() && mMakeDefaultCheckBox->getValue())
667	{
668		LL_DEBUGS("Windlight") << name << " is now the new preferred water preset" << llendl;
669		LLEnvManagerNew::instance().setUseWaterPreset(name);
670	}
671
672	closeFloater();
673}
674
675void LLFloaterEditWater::onBtnSave()
676{
677	LLEnvKey::EScope scope;
678	std::string name;
679	getSelectedPreset(name, scope);
680
681	if (scope == LLEnvKey::SCOPE_REGION)
682	{
683		saveRegionWater();
684		closeFloater();
685		return;
686	}
687
688	if (name.empty())
689	{
690		// *TODO: show an alert
691		llwarns << "Empty water preset name" << llendl;
692		return;
693	}
694
695	// Don't allow overwriting system presets.
696	LLWaterParamManager& water_mgr = LLWaterParamManager::instance();
697	if (water_mgr.isSystemPreset(name))
698	{
699		LLNotificationsUtil::add("WLNoEditDefault");
700		return;
701	}
702
703	// Save, ask for confirmation for overwriting an existing preset.
704	if (water_mgr.hasParamSet(name))
705	{
706		LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterEditWater::onSaveAnswer, this, _1, _2));
707	}
708	else
709	{
710		// new preset, hence no confirmation needed
711		onSaveConfirmed();
712	}
713}
714
715void LLFloaterEditWater::onBtnCancel()
716{
717	closeFloater();
718}
719
720void LLFloaterEditWater::onWaterPresetListChange()
721{
722	std::string name;
723	LLEnvKey::EScope scope;
724	getSelectedPreset(name, scope); // preset being edited
725
726	if (scope == LLEnvKey::SCOPE_LOCAL && !LLWaterParamManager::instance().hasParamSet(name))
727	{
728		// Preset we've been editing doesn't exist anymore. Close the floater.
729		closeFloater(false);
730	}
731	else
732	{
733		// A new preset has been added.
734		// Refresh the presets list, though it may not make sense as the floater is about to be closed.
735		refreshWaterPresetsList();
736	}
737}
738
739void LLFloaterEditWater::onRegionSettingsChange()
740{
741	// If creating a new preset, don't bother.
742	if (isNewPreset())
743	{
744		return;
745	}
746
747	if (getCurrentScope() == LLEnvKey::SCOPE_REGION) // if editing region water
748	{
749		// reset the floater to its initial state
750		reset();
751
752		// *TODO: Notify user?
753	}
754	else // editing a local preset
755	{
756		refreshWaterPresetsList();
757	}
758}
759
760void LLFloaterEditWater::onRegionInfoUpdate()
761{
762	bool can_edit = true;
763
764	// If we've selected the region water for editing.
765	if (getCurrentScope() == LLEnvKey::SCOPE_REGION)
766	{
767		// check whether we have the access
768		can_edit = LLEnvManagerNew::canEditRegionSettings();
769	}
770
771	enableEditing(can_edit);
772}