PageRenderTime 125ms CodeModel.GetById 18ms app.highlight 99ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llfloatereditsky.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 923 lines | 629 code | 179 blank | 115 comment | 65 complexity | 44ac92f6f0f218c8a5e39935fdbb7588 MD5 | raw file
  1/** 
  2 * @file llfloatereditsky.cpp
  3 * @brief Floater to create or edit a sky 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 "llfloatereditsky.h"
 30
 31// libs
 32#include "llbutton.h"
 33#include "llcheckboxctrl.h"
 34#include "llcombobox.h"
 35#include "llmultisliderctrl.h"
 36#include "llnotifications.h"
 37#include "llnotificationsutil.h"
 38#include "llsliderctrl.h"
 39#include "lltabcontainer.h"
 40#include "lltimectrl.h"
 41
 42// newview
 43#include "llagent.h"
 44#include "llcolorswatch.h"
 45#include "llregioninfomodel.h"
 46#include "llviewerregion.h"
 47
 48static const F32 WL_SUN_AMBIENT_SLIDER_SCALE = 3.0f;
 49static const F32 WL_BLUE_HORIZON_DENSITY_SCALE = 2.0f;
 50static const F32 WL_CLOUD_SLIDER_SCALE = 1.0f;
 51
 52static F32 sun_pos_to_time24(F32 sun_pos)
 53{
 54	return fmodf(sun_pos * 24.0f + 6, 24.0f);
 55}
 56
 57static F32 time24_to_sun_pos(F32 time24)
 58{
 59	F32 sun_pos = fmodf((time24 - 6) / 24.0f, 1.0f);
 60	if (sun_pos < 0) ++sun_pos;
 61	return sun_pos;
 62}
 63
 64LLFloaterEditSky::LLFloaterEditSky(const LLSD &key)
 65:	LLFloater(key)
 66,	mSkyPresetNameEditor(NULL)
 67,	mSkyPresetCombo(NULL)
 68,	mMakeDefaultCheckBox(NULL)
 69,	mSaveButton(NULL)
 70{
 71}
 72
 73// virtual
 74BOOL LLFloaterEditSky::postBuild()
 75{
 76	mSkyPresetNameEditor = getChild<LLLineEditor>("sky_preset_name");
 77	mSkyPresetCombo = getChild<LLComboBox>("sky_preset_combo");
 78	mMakeDefaultCheckBox = getChild<LLCheckBoxCtrl>("make_default_cb");
 79	mSaveButton = getChild<LLButton>("save");
 80
 81	initCallbacks();
 82
 83	// Create the sun position scrubber on the slider.
 84	getChild<LLMultiSliderCtrl>("WLSunPos")->addSlider(12.f);
 85
 86	return TRUE;
 87}
 88
 89// virtual
 90void LLFloaterEditSky::onOpen(const LLSD& key)
 91{
 92	bool new_preset = isNewPreset();
 93	std::string param = key.asString();
 94	std::string floater_title = getString(std::string("title_") + param);
 95	std::string hint = getString(std::string("hint_" + param));
 96
 97	// Update floater title.
 98	setTitle(floater_title);
 99
100	// Update the hint at the top.
101	getChild<LLUICtrl>("hint")->setValue(hint);
102
103	// Hide the hint to the right of the combo if we're invoked to create a new preset.
104	getChildView("note")->setVisible(!new_preset);
105
106	// Switch between the sky presets combobox and preset name input field.
107	mSkyPresetCombo->setVisible(!new_preset);
108	mSkyPresetNameEditor->setVisible(new_preset);
109
110	reset();
111}
112
113// virtual
114void LLFloaterEditSky::onClose(bool app_quitting)
115{
116	if (!app_quitting) // there's no point to change environment if we're quitting
117	{
118		LLEnvManagerNew::instance().usePrefs(); // revert changes made to current environment
119	}
120}
121
122// virtual
123void LLFloaterEditSky::draw()
124{
125	syncControls();
126	LLFloater::draw();
127}
128
129void LLFloaterEditSky::initCallbacks(void)
130{
131	// *TODO: warn user if a region environment update comes while we're editing a region sky preset.
132
133	mSkyPresetNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterEditSky::onSkyPresetNameEdited, this), NULL);
134	mSkyPresetCombo->setCommitCallback(boost::bind(&LLFloaterEditSky::onSkyPresetSelected, this));
135	mSkyPresetCombo->setTextEntryCallback(boost::bind(&LLFloaterEditSky::onSkyPresetNameEdited, this));
136
137	mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnSave, this));
138	getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnCancel, this));
139
140	LLEnvManagerNew::instance().setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditSky::onRegionSettingsChange, this));
141	LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditSky::onSkyPresetListChange, this));
142
143	// Connect to region info updates.
144	LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditSky::onRegionInfoUpdate, this));
145
146	//-------------------------------------------------------------------------
147
148	LLWLParamManager& param_mgr = LLWLParamManager::instance();
149
150	// blue horizon
151	getChild<LLUICtrl>("WLBlueHorizon")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &param_mgr.mBlueHorizon));
152
153	// haze density, horizon, mult, and altitude
154	getChild<LLUICtrl>("WLHazeDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, &param_mgr.mHazeDensity));
155	getChild<LLUICtrl>("WLHazeHorizon")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, &param_mgr.mHazeHorizon));
156	getChild<LLUICtrl>("WLDensityMult")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mDensityMult));
157	getChild<LLUICtrl>("WLMaxAltitude")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mMaxAlt));
158
159	// blue density
160	getChild<LLUICtrl>("WLBlueDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &param_mgr.mBlueDensity));
161
162	// Lighting
163
164	// sunlight
165	getChild<LLUICtrl>("WLSunlight")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &param_mgr.mSunlight));
166
167	// glow
168	getChild<LLUICtrl>("WLGlowR")->setCommitCallback(boost::bind(&LLFloaterEditSky::onGlowRMoved, this, _1, &param_mgr.mGlow));
169	getChild<LLUICtrl>("WLGlowB")->setCommitCallback(boost::bind(&LLFloaterEditSky::onGlowBMoved, this, _1, &param_mgr.mGlow));
170
171	// ambient
172	getChild<LLUICtrl>("WLAmbient")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &param_mgr.mAmbient));
173
174	// time of day
175	getChild<LLUICtrl>("WLSunPos")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunMoved, this, _1, &param_mgr.mLightnorm));     // multi-slider
176	getChild<LLTimeCtrl>("WLDayTime")->setCommitCallback(boost::bind(&LLFloaterEditSky::onTimeChanged, this));                          // time ctrl
177	getChild<LLUICtrl>("WLEastAngle")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunMoved, this, _1, &param_mgr.mLightnorm));
178
179	// Clouds
180
181	// Cloud Color
182	getChild<LLUICtrl>("WLCloudColor")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &param_mgr.mCloudColor));
183
184	// Cloud
185	getChild<LLUICtrl>("WLCloudX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, &param_mgr.mCloudMain));
186	getChild<LLUICtrl>("WLCloudY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, &param_mgr.mCloudMain));
187	getChild<LLUICtrl>("WLCloudDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, &param_mgr.mCloudMain));
188
189	// Cloud Detail
190	getChild<LLUICtrl>("WLCloudDetailX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, &param_mgr.mCloudDetail));
191	getChild<LLUICtrl>("WLCloudDetailY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, &param_mgr.mCloudDetail));
192	getChild<LLUICtrl>("WLCloudDetailDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, &param_mgr.mCloudDetail));
193
194	// Cloud extras
195	getChild<LLUICtrl>("WLCloudCoverage")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mCloudCoverage));
196	getChild<LLUICtrl>("WLCloudScale")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mCloudScale));
197	getChild<LLUICtrl>("WLCloudLockX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollXToggled, this, _1));
198	getChild<LLUICtrl>("WLCloudLockY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollYToggled, this, _1));
199	getChild<LLUICtrl>("WLCloudScrollX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollXMoved, this, _1));
200	getChild<LLUICtrl>("WLCloudScrollY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollYMoved, this, _1));
201	getChild<LLUICtrl>("WLDistanceMult")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mDistanceMult));
202
203	// Dome
204	getChild<LLUICtrl>("WLGamma")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mWLGamma));
205	getChild<LLUICtrl>("WLStarAlpha")->setCommitCallback(boost::bind(&LLFloaterEditSky::onStarAlphaMoved, this, _1));
206}
207
208//=================================================================================================
209
210void LLFloaterEditSky::syncControls()
211{
212	bool err;
213
214	LLWLParamManager * param_mgr = LLWLParamManager::getInstance();
215
216	LLWLParamSet& cur_params = param_mgr->mCurParams;
217
218	// blue horizon
219	param_mgr->mBlueHorizon = cur_params.getVector(param_mgr->mBlueHorizon.mName, err);
220	setColorSwatch("WLBlueHorizon", param_mgr->mBlueHorizon, WL_BLUE_HORIZON_DENSITY_SCALE);
221
222	// haze density, horizon, mult, and altitude
223	param_mgr->mHazeDensity = cur_params.getVector(param_mgr->mHazeDensity.mName, err);
224	childSetValue("WLHazeDensity", param_mgr->mHazeDensity.r);
225	param_mgr->mHazeHorizon = cur_params.getVector(param_mgr->mHazeHorizon.mName, err);
226	childSetValue("WLHazeHorizon", param_mgr->mHazeHorizon.r);
227	param_mgr->mDensityMult = cur_params.getVector(param_mgr->mDensityMult.mName, err);
228	childSetValue("WLDensityMult", param_mgr->mDensityMult.x *
229		param_mgr->mDensityMult.mult);
230	param_mgr->mMaxAlt = cur_params.getVector(param_mgr->mMaxAlt.mName, err);
231	childSetValue("WLMaxAltitude", param_mgr->mMaxAlt.x);
232
233	// blue density
234	param_mgr->mBlueDensity = cur_params.getVector(param_mgr->mBlueDensity.mName, err);
235	setColorSwatch("WLBlueDensity", param_mgr->mBlueDensity, WL_BLUE_HORIZON_DENSITY_SCALE);
236
237	// Lighting
238
239	// sunlight
240	param_mgr->mSunlight = cur_params.getVector(param_mgr->mSunlight.mName, err);
241	setColorSwatch("WLSunlight", param_mgr->mSunlight, WL_SUN_AMBIENT_SLIDER_SCALE);
242
243	// glow
244	param_mgr->mGlow = cur_params.getVector(param_mgr->mGlow.mName, err);
245	childSetValue("WLGlowR", 2 - param_mgr->mGlow.r / 20.0f);
246	childSetValue("WLGlowB", -param_mgr->mGlow.b / 5.0f);
247
248	// ambient
249	param_mgr->mAmbient = cur_params.getVector(param_mgr->mAmbient.mName, err);
250	setColorSwatch("WLAmbient", param_mgr->mAmbient, WL_SUN_AMBIENT_SLIDER_SCALE);
251
252	F32 time24 = sun_pos_to_time24(param_mgr->mCurParams.getFloat("sun_angle",err) / F_TWO_PI);
253	getChild<LLMultiSliderCtrl>("WLSunPos")->setCurSliderValue(time24, TRUE);
254	getChild<LLTimeCtrl>("WLDayTime")->setTime24(time24);
255	childSetValue("WLEastAngle", param_mgr->mCurParams.getFloat("east_angle",err) / F_TWO_PI);
256
257	// Clouds
258
259	// Cloud Color
260	param_mgr->mCloudColor = cur_params.getVector(param_mgr->mCloudColor.mName, err);
261	setColorSwatch("WLCloudColor", param_mgr->mCloudColor, WL_CLOUD_SLIDER_SCALE);
262
263	// Cloud
264	param_mgr->mCloudMain = cur_params.getVector(param_mgr->mCloudMain.mName, err);
265	childSetValue("WLCloudX", param_mgr->mCloudMain.r);
266	childSetValue("WLCloudY", param_mgr->mCloudMain.g);
267	childSetValue("WLCloudDensity", param_mgr->mCloudMain.b);
268
269	// Cloud Detail
270	param_mgr->mCloudDetail = cur_params.getVector(param_mgr->mCloudDetail.mName, err);
271	childSetValue("WLCloudDetailX", param_mgr->mCloudDetail.r);
272	childSetValue("WLCloudDetailY", param_mgr->mCloudDetail.g);
273	childSetValue("WLCloudDetailDensity", param_mgr->mCloudDetail.b);
274
275	// Cloud extras
276	param_mgr->mCloudCoverage = cur_params.getVector(param_mgr->mCloudCoverage.mName, err);
277	param_mgr->mCloudScale = cur_params.getVector(param_mgr->mCloudScale.mName, err);
278	childSetValue("WLCloudCoverage", param_mgr->mCloudCoverage.x);
279	childSetValue("WLCloudScale", param_mgr->mCloudScale.x);
280
281	// cloud scrolling
282	bool lockX = !param_mgr->mCurParams.getEnableCloudScrollX();
283	bool lockY = !param_mgr->mCurParams.getEnableCloudScrollY();
284	childSetValue("WLCloudLockX", lockX);
285	childSetValue("WLCloudLockY", lockY);
286
287	// disable if locked, enable if not
288	if (lockX)
289	{
290		childDisable("WLCloudScrollX");
291	}
292	else
293	{
294		childEnable("WLCloudScrollX");
295	}
296	if (lockY)
297	{
298		childDisable("WLCloudScrollY");
299	}
300	else
301	{
302		childEnable("WLCloudScrollY");
303	}
304
305	// *HACK cloud scrolling is off my an additive of 10
306	childSetValue("WLCloudScrollX", param_mgr->mCurParams.getCloudScrollX() - 10.0f);
307	childSetValue("WLCloudScrollY", param_mgr->mCurParams.getCloudScrollY() - 10.0f);
308
309	param_mgr->mDistanceMult = cur_params.getVector(param_mgr->mDistanceMult.mName, err);
310	childSetValue("WLDistanceMult", param_mgr->mDistanceMult.x);
311
312	// Tweak extras
313
314	param_mgr->mWLGamma = cur_params.getVector(param_mgr->mWLGamma.mName, err);
315	childSetValue("WLGamma", param_mgr->mWLGamma.x);
316
317	childSetValue("WLStarAlpha", param_mgr->mCurParams.getStarBrightness());
318}
319
320void LLFloaterEditSky::setColorSwatch(const std::string& name, const WLColorControl& from_ctrl, F32 k)
321{
322	// Set the value, dividing it by <k> first.
323	LLVector4 color_vec = from_ctrl;
324	getChild<LLColorSwatchCtrl>(name)->set(LLColor4(color_vec / k));
325}
326
327// color control callbacks
328void LLFloaterEditSky::onColorControlMoved(LLUICtrl* ctrl, WLColorControl* color_ctrl)
329{
330	LLWLParamManager::getInstance()->mAnimator.deactivate();
331
332	LLColorSwatchCtrl* swatch = static_cast<LLColorSwatchCtrl*>(ctrl);
333	LLVector4 color_vec(swatch->get().mV);
334
335	// Set intensity to maximum of the RGB values.
336	color_vec.mV[3] = llmax(color_vec.mV[0], llmax(color_vec.mV[1], color_vec.mV[2]));
337
338	// Multiply RGB values by the appropriate factor.
339	F32 k = WL_CLOUD_SLIDER_SCALE;
340	if (color_ctrl->isSunOrAmbientColor)
341	{
342		k = WL_SUN_AMBIENT_SLIDER_SCALE;
343	}
344	if (color_ctrl->isBlueHorizonOrDensity)
345	{
346		k = WL_BLUE_HORIZON_DENSITY_SCALE;
347	}
348
349	color_vec *= k; // intensity isn't affected by the multiplication
350
351	// Apply the new RGBI value.
352	*color_ctrl = color_vec;
353	color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);
354	LLWLParamManager::getInstance()->propagateParameters();
355}
356
357void LLFloaterEditSky::onColorControlRMoved(LLUICtrl* ctrl, void* userdata)
358{
359	LLWLParamManager::getInstance()->mAnimator.deactivate();
360
361	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
362	WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
363
364	color_ctrl->r = sldr_ctrl->getValueF32();
365	if (color_ctrl->isSunOrAmbientColor)
366	{
367		color_ctrl->r *= WL_SUN_AMBIENT_SLIDER_SCALE;
368	}
369	if (color_ctrl->isBlueHorizonOrDensity)
370	{
371		color_ctrl->r *= WL_BLUE_HORIZON_DENSITY_SCALE;
372	}
373
374	// move i if it's the max
375	if (color_ctrl->r >= color_ctrl->g && color_ctrl->r >= color_ctrl->b && color_ctrl->hasSliderName)
376	{
377		color_ctrl->i = color_ctrl->r;
378		std::string name = color_ctrl->mSliderName;
379		name.append("I");
380
381		if (color_ctrl->isSunOrAmbientColor)
382		{
383			childSetValue(name, color_ctrl->r / WL_SUN_AMBIENT_SLIDER_SCALE);
384		}
385		else if	(color_ctrl->isBlueHorizonOrDensity)
386		{
387			childSetValue(name, color_ctrl->r / WL_BLUE_HORIZON_DENSITY_SCALE);
388		}
389		else
390		{
391			childSetValue(name, color_ctrl->r);
392		}
393	}
394
395	color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);
396
397	LLWLParamManager::getInstance()->propagateParameters();
398}
399
400void LLFloaterEditSky::onColorControlGMoved(LLUICtrl* ctrl, void* userdata)
401{
402	LLWLParamManager::getInstance()->mAnimator.deactivate();
403
404	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
405	WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
406
407	color_ctrl->g = sldr_ctrl->getValueF32();
408	if (color_ctrl->isSunOrAmbientColor)
409	{
410		color_ctrl->g *= WL_SUN_AMBIENT_SLIDER_SCALE;
411	}
412	if (color_ctrl->isBlueHorizonOrDensity)
413	{
414		color_ctrl->g *= WL_BLUE_HORIZON_DENSITY_SCALE;
415	}
416
417	// move i if it's the max
418	if (color_ctrl->g >= color_ctrl->r && color_ctrl->g >= color_ctrl->b && color_ctrl->hasSliderName)
419	{
420		color_ctrl->i = color_ctrl->g;
421		std::string name = color_ctrl->mSliderName;
422		name.append("I");
423
424		if (color_ctrl->isSunOrAmbientColor)
425		{
426			childSetValue(name, color_ctrl->g / WL_SUN_AMBIENT_SLIDER_SCALE);
427		}
428		else if (color_ctrl->isBlueHorizonOrDensity)
429		{
430			childSetValue(name, color_ctrl->g / WL_BLUE_HORIZON_DENSITY_SCALE);
431		}
432		else
433		{
434			childSetValue(name, color_ctrl->g);
435		}
436	}
437
438	color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);
439
440	LLWLParamManager::getInstance()->propagateParameters();
441}
442
443void LLFloaterEditSky::onColorControlBMoved(LLUICtrl* ctrl, void* userdata)
444{
445	LLWLParamManager::getInstance()->mAnimator.deactivate();
446
447	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
448	WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
449
450	color_ctrl->b = sldr_ctrl->getValueF32();
451	if (color_ctrl->isSunOrAmbientColor)
452	{
453		color_ctrl->b *= WL_SUN_AMBIENT_SLIDER_SCALE;
454	}
455	if (color_ctrl->isBlueHorizonOrDensity)
456	{
457		color_ctrl->b *= WL_BLUE_HORIZON_DENSITY_SCALE;
458	}
459
460	// move i if it's the max
461	if (color_ctrl->b >= color_ctrl->r && color_ctrl->b >= color_ctrl->g && color_ctrl->hasSliderName)
462	{
463		color_ctrl->i = color_ctrl->b;
464		std::string name = color_ctrl->mSliderName;
465		name.append("I");
466
467		if (color_ctrl->isSunOrAmbientColor)
468		{
469			childSetValue(name, color_ctrl->b / WL_SUN_AMBIENT_SLIDER_SCALE);
470		}
471		else if (color_ctrl->isBlueHorizonOrDensity)
472		{
473			childSetValue(name, color_ctrl->b / WL_BLUE_HORIZON_DENSITY_SCALE);
474		}
475		else
476		{
477			childSetValue(name, color_ctrl->b);
478		}
479	}
480
481	color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);
482
483	LLWLParamManager::getInstance()->propagateParameters();
484}
485
486/// GLOW SPECIFIC CODE
487void LLFloaterEditSky::onGlowRMoved(LLUICtrl* ctrl, void* userdata)
488{
489	LLWLParamManager::getInstance()->mAnimator.deactivate();
490
491	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
492	WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
493
494	// scaled by 20
495	color_ctrl->r = (2 - sldr_ctrl->getValueF32()) * 20;
496
497	color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);
498	LLWLParamManager::getInstance()->propagateParameters();
499}
500
501/// \NOTE that we want NEGATIVE (-) B
502void LLFloaterEditSky::onGlowBMoved(LLUICtrl* ctrl, void* userdata)
503{
504	LLWLParamManager::getInstance()->mAnimator.deactivate();
505
506	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
507	WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
508
509	/// \NOTE that we want NEGATIVE (-) B and NOT by 20 as 20 is too big
510	color_ctrl->b = -sldr_ctrl->getValueF32() * 5;
511
512	color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);
513	LLWLParamManager::getInstance()->propagateParameters();
514}
515
516void LLFloaterEditSky::onFloatControlMoved(LLUICtrl* ctrl, void* userdata)
517{
518	LLWLParamManager::getInstance()->mAnimator.deactivate();
519
520	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
521	WLFloatControl * floatControl = static_cast<WLFloatControl *>(userdata);
522
523	floatControl->x = sldr_ctrl->getValueF32() / floatControl->mult;
524
525	floatControl->update(LLWLParamManager::getInstance()->mCurParams);
526	LLWLParamManager::getInstance()->propagateParameters();
527}
528
529
530// Lighting callbacks
531
532// time of day
533void LLFloaterEditSky::onSunMoved(LLUICtrl* ctrl, void* userdata)
534{
535	LLWLParamManager::getInstance()->mAnimator.deactivate();
536
537	LLMultiSliderCtrl* sun_msldr = getChild<LLMultiSliderCtrl>("WLSunPos");
538	LLSliderCtrl* east_sldr = getChild<LLSliderCtrl>("WLEastAngle");
539	LLTimeCtrl* time_ctrl = getChild<LLTimeCtrl>("WLDayTime");
540	WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
541
542	F32 time24  = sun_msldr->getCurSliderValue();
543	time_ctrl->setTime24(time24); // sync the time ctrl with the new sun position
544
545	// get the two angles
546	LLWLParamManager * param_mgr = LLWLParamManager::getInstance();
547
548	param_mgr->mCurParams.setSunAngle(F_TWO_PI * time24_to_sun_pos(time24));
549	param_mgr->mCurParams.setEastAngle(F_TWO_PI * east_sldr->getValueF32());
550
551	// set the sun vector
552	color_ctrl->r = -sin(param_mgr->mCurParams.getEastAngle()) *
553		cos(param_mgr->mCurParams.getSunAngle());
554	color_ctrl->g = sin(param_mgr->mCurParams.getSunAngle());
555	color_ctrl->b = cos(param_mgr->mCurParams.getEastAngle()) *
556		cos(param_mgr->mCurParams.getSunAngle());
557	color_ctrl->i = 1.f;
558
559	color_ctrl->update(param_mgr->mCurParams);
560	param_mgr->propagateParameters();
561}
562
563void LLFloaterEditSky::onTimeChanged()
564{
565	F32 time24 = getChild<LLTimeCtrl>("WLDayTime")->getTime24();
566	getChild<LLMultiSliderCtrl>("WLSunPos")->setCurSliderValue(time24, TRUE);
567	onSunMoved(getChild<LLUICtrl>("WLSunPos"), &LLWLParamManager::instance().mLightnorm);
568}
569
570void LLFloaterEditSky::onStarAlphaMoved(LLUICtrl* ctrl)
571{
572	LLWLParamManager::getInstance()->mAnimator.deactivate();
573
574	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
575
576	LLWLParamManager::getInstance()->mCurParams.setStarBrightness(sldr_ctrl->getValueF32());
577}
578
579// Clouds
580void LLFloaterEditSky::onCloudScrollXMoved(LLUICtrl* ctrl)
581{
582	LLWLParamManager::getInstance()->mAnimator.deactivate();
583
584	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
585	// *HACK  all cloud scrolling is off by an additive of 10.
586	LLWLParamManager::getInstance()->mCurParams.setCloudScrollX(sldr_ctrl->getValueF32() + 10.0f);
587}
588
589void LLFloaterEditSky::onCloudScrollYMoved(LLUICtrl* ctrl)
590{
591	LLWLParamManager::getInstance()->mAnimator.deactivate();
592
593	LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
594
595	// *HACK  all cloud scrolling is off by an additive of 10.
596	LLWLParamManager::getInstance()->mCurParams.setCloudScrollY(sldr_ctrl->getValueF32() + 10.0f);
597}
598
599void LLFloaterEditSky::onCloudScrollXToggled(LLUICtrl* ctrl)
600{
601	LLWLParamManager::getInstance()->mAnimator.deactivate();
602
603	LLCheckBoxCtrl* cb_ctrl = static_cast<LLCheckBoxCtrl*>(ctrl);
604
605	bool lock = cb_ctrl->get();
606	LLWLParamManager::getInstance()->mCurParams.setEnableCloudScrollX(!lock);
607
608	LLSliderCtrl* sldr = getChild<LLSliderCtrl>("WLCloudScrollX");
609
610	if (cb_ctrl->get())
611	{
612		sldr->setEnabled(false);
613	}
614	else
615	{
616		sldr->setEnabled(true);
617	}
618
619}
620
621void LLFloaterEditSky::onCloudScrollYToggled(LLUICtrl* ctrl)
622{
623	LLWLParamManager::getInstance()->mAnimator.deactivate();
624
625	LLCheckBoxCtrl* cb_ctrl = static_cast<LLCheckBoxCtrl*>(ctrl);
626	bool lock = cb_ctrl->get();
627	LLWLParamManager::getInstance()->mCurParams.setEnableCloudScrollY(!lock);
628
629	LLSliderCtrl* sldr = getChild<LLSliderCtrl>("WLCloudScrollY");
630
631	if (cb_ctrl->get())
632	{
633		sldr->setEnabled(false);
634	}
635	else
636	{
637		sldr->setEnabled(true);
638	}
639}
640
641//=================================================================================================
642
643void LLFloaterEditSky::reset()
644{
645	if (isNewPreset())
646	{
647		mSkyPresetNameEditor->setValue(LLSD());
648		mSaveButton->setEnabled(FALSE); // will be enabled as soon as users enters a name
649	}
650	else
651	{
652		refreshSkyPresetsList();
653
654		// Disable controls until a sky preset to edit is selected.
655		enableEditing(false);
656	}
657}
658
659bool LLFloaterEditSky::isNewPreset() const
660{
661	return mKey.asString() == "new";
662}
663
664void LLFloaterEditSky::refreshSkyPresetsList()
665{
666	mSkyPresetCombo->removeall();
667
668	LLWLParamManager::preset_name_list_t region_presets, user_presets, sys_presets;
669	LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets);
670
671#if 0 // Disable editing region skies until the workflow is clear enough.
672	// Add region presets.
673	std::string region_name = gAgent.getRegion() ? gAgent.getRegion()->getName() : LLTrans::getString("Unknown");
674	for (LLWLParamManager::preset_name_list_t::const_iterator it = region_presets.begin(); it != region_presets.end(); ++it)
675	{
676		std::string item_title = *it + " (" + region_name + ")";
677		mSkyPresetCombo->add(item_title, LLWLParamKey(*it, LLEnvKey::SCOPE_REGION).toLLSD());
678	}
679	if (region_presets.size() > 0)
680	{
681		mSkyPresetCombo->addSeparator();
682	}
683#endif
684
685	// Add user presets.
686	for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
687	{
688		mSkyPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD());
689	}
690	if (user_presets.size() > 0)
691	{
692		mSkyPresetCombo->addSeparator();
693	}
694
695	// Add system presets.
696	for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it)
697	{
698		mSkyPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD());
699	}
700
701	mSkyPresetCombo->setLabel(getString("combo_label"));
702}
703
704void LLFloaterEditSky::enableEditing(bool enable)
705{
706	// Enable/disable the tab and their contents.
707	LLTabContainer* tab_container = getChild<LLTabContainer>("WindLight Tabs");
708	tab_container->setEnabled(enable);
709	for (S32 i = 0; i < tab_container->getTabCount(); ++i)
710	{
711		tab_container->enableTabButton(i, enable);
712		tab_container->getPanelByIndex(i)->setCtrlsEnabled(enable);
713	}
714
715	// Enable/disable saving.
716	mSaveButton->setEnabled(enable);
717	mMakeDefaultCheckBox->setEnabled(enable);
718}
719
720void LLFloaterEditSky::saveRegionSky()
721{
722	LLWLParamKey key(getSelectedSkyPreset());
723	llassert(key.scope == LLEnvKey::SCOPE_REGION);
724
725	LL_DEBUGS("Windlight") << "Saving region sky preset: " << key.name  << llendl;
726	LLWLParamManager& wl_mgr = LLWLParamManager::instance();
727	wl_mgr.mCurParams.mName = key.name;
728	wl_mgr.setParamSet(key, wl_mgr.mCurParams);
729
730	// *TODO: save to cached region settings.
731	LL_WARNS("Windlight") << "Saving region sky is not fully implemented yet" << LL_ENDL;
732}
733
734LLWLParamKey LLFloaterEditSky::getSelectedSkyPreset()
735{
736	LLWLParamKey key;
737
738	if (mSkyPresetNameEditor->getVisible())
739	{
740		key.name = mSkyPresetNameEditor->getText();
741		key.scope = LLEnvKey::SCOPE_LOCAL;
742	}
743	else
744	{
745		LLSD combo_val = mSkyPresetCombo->getValue();
746
747		if (!combo_val.isArray()) // manually typed text
748		{
749			key.name = combo_val.asString();
750			key.scope = LLEnvKey::SCOPE_LOCAL;
751		}
752		else
753		{
754			key.fromLLSD(combo_val);
755		}
756	}
757
758	return key;
759}
760
761void LLFloaterEditSky::onSkyPresetNameEdited()
762{
763	// Disable saving a sky preset having empty name.
764	LLWLParamKey key = getSelectedSkyPreset();
765	mSaveButton->setEnabled(!key.name.empty());
766}
767
768void LLFloaterEditSky::onSkyPresetSelected()
769{
770	LLWLParamKey key = getSelectedSkyPreset();
771	LLWLParamSet sky_params;
772
773	if (!LLWLParamManager::instance().getParamSet(key, sky_params))
774	{
775		// Manually entered string?
776		LL_WARNS("Windlight") << "No sky preset named " << key.toString() << LL_ENDL;
777		return;
778	}
779
780	LLEnvManagerNew::instance().useSkyParams(sky_params.getAll());
781	//syncControls();
782
783	bool can_edit = (key.scope == LLEnvKey::SCOPE_LOCAL || LLEnvManagerNew::canEditRegionSettings());
784	enableEditing(can_edit);
785
786	mMakeDefaultCheckBox->setEnabled(key.scope == LLEnvKey::SCOPE_LOCAL);
787}
788
789bool LLFloaterEditSky::onSaveAnswer(const LLSD& notification, const LLSD& response)
790{
791	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
792
793	// If they choose save, do it.  Otherwise, don't do anything
794	if (option == 0)
795	{
796		onSaveConfirmed();
797	}
798
799	return false;
800}
801
802void LLFloaterEditSky::onSaveConfirmed()
803{
804	// Save current params to the selected preset.
805	LLWLParamKey key(getSelectedSkyPreset());
806
807	LL_DEBUGS("Windlight") << "Saving sky preset " << key.name << LL_ENDL;
808	LLWLParamManager& wl_mgr = LLWLParamManager::instance();
809	if (wl_mgr.hasParamSet(key))
810	{
811		wl_mgr.setParamSet(key, wl_mgr.mCurParams);
812	}
813	else
814	{
815		wl_mgr.addParamSet(key, wl_mgr.mCurParams);
816	}
817
818	wl_mgr.savePreset(key);
819
820	// Change preference if requested.
821	if (mMakeDefaultCheckBox->getValue())
822	{
823		LL_DEBUGS("Windlight") << key.name << " is now the new preferred sky preset" << llendl;
824		LLEnvManagerNew::instance().setUseSkyPreset(key.name);
825	}
826
827	closeFloater();
828}
829
830void LLFloaterEditSky::onBtnSave()
831{
832	LLWLParamKey selected_sky = getSelectedSkyPreset();
833	LLWLParamManager& wl_mgr = LLWLParamManager::instance();
834
835	if (selected_sky.scope == LLEnvKey::SCOPE_REGION)
836	{
837		saveRegionSky();
838		closeFloater();
839		return;
840	}
841
842	std::string name = selected_sky.name;
843	if (name.empty())
844	{
845		// *TODO: show an alert
846		llwarns << "Empty sky preset name" << llendl;
847		return;
848	}
849
850	// Don't allow overwriting system presets.
851	if (wl_mgr.isSystemPreset(name))
852	{
853		LLNotificationsUtil::add("WLNoEditDefault");
854		return;
855	}
856
857	// Save, ask for confirmation for overwriting an existing preset.
858	if (wl_mgr.hasParamSet(selected_sky))
859	{
860		LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterEditSky::onSaveAnswer, this, _1, _2));
861	}
862	else
863	{
864		// new preset, hence no confirmation needed
865		onSaveConfirmed();
866	}
867}
868
869void LLFloaterEditSky::onBtnCancel()
870{
871	closeFloater();
872}
873
874void LLFloaterEditSky::onSkyPresetListChange()
875{
876	LLWLParamKey key = getSelectedSkyPreset(); // preset being edited
877	if (!LLWLParamManager::instance().hasParamSet(key))
878	{
879		// Preset we've been editing doesn't exist anymore. Close the floater.
880		closeFloater(false);
881	}
882	else
883	{
884		// A new preset has been added.
885		// Refresh the presets list, though it may not make sense as the floater is about to be closed.
886		refreshSkyPresetsList();
887	}
888}
889
890void LLFloaterEditSky::onRegionSettingsChange()
891{
892	// If creating a new sky, don't bother.
893	if (isNewPreset())
894	{
895		return;
896	}
897
898	if (getSelectedSkyPreset().scope == LLEnvKey::SCOPE_REGION) // if editing a region sky
899	{
900		// reset the floater to its initial state
901		reset();
902
903		// *TODO: Notify user?
904	}
905	else // editing a local sky
906	{
907		refreshSkyPresetsList();
908	}
909}
910
911void LLFloaterEditSky::onRegionInfoUpdate()
912{
913	bool can_edit = true;
914
915	// If we've selected a region sky preset for editing.
916	if (getSelectedSkyPreset().scope == LLEnvKey::SCOPE_REGION)
917	{
918		// check whether we have the access
919		can_edit = LLEnvManagerNew::canEditRegionSettings();
920	}
921
922	enableEditing(can_edit);
923}