PageRenderTime 56ms CodeModel.GetById 1ms app.highlight 49ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llfloatereditdaycycle.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 825 lines | 575 code | 155 blank | 95 comment | 78 complexity | c080fcd7edffb8e353e2294abcd8be4e MD5 | raw file
  1/** 
  2 * @file llfloatereditdaycycle.cpp
  3 * @brief Floater to create or edit a day cycle
  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 "llfloatereditdaycycle.h"
 30
 31// libs
 32#include "llbutton.h"
 33#include "llcheckboxctrl.h"
 34#include "llcombobox.h"
 35#include "llloadingindicator.h"
 36#include "llmultisliderctrl.h"
 37#include "llnotifications.h"
 38#include "llnotificationsutil.h"
 39#include "llspinctrl.h"
 40#include "lltimectrl.h"
 41
 42// newview
 43#include "llagent.h"
 44#include "lldaycyclemanager.h"
 45#include "llenvmanager.h"
 46#include "llregioninfomodel.h"
 47#include "llviewerregion.h"
 48#include "llwlparammanager.h"
 49
 50const F32 LLFloaterEditDayCycle::sHoursPerDay = 24.0f;
 51
 52LLFloaterEditDayCycle::LLFloaterEditDayCycle(const LLSD &key)
 53:	LLFloater(key)
 54,	mDayCycleNameEditor(NULL)
 55,	mDayCyclesCombo(NULL)
 56,	mTimeSlider(NULL)
 57,	mKeysSlider(NULL)
 58,	mSkyPresetsCombo(NULL)
 59,	mTimeCtrl(NULL)
 60,	mMakeDefaultCheckBox(NULL)
 61,	mSaveButton(NULL)
 62{
 63}
 64
 65// virtual
 66BOOL LLFloaterEditDayCycle::postBuild()
 67{
 68	mDayCycleNameEditor = getChild<LLLineEditor>("day_cycle_name");
 69	mDayCyclesCombo = getChild<LLComboBox>("day_cycle_combo");
 70
 71	mTimeSlider = getChild<LLMultiSliderCtrl>("WLTimeSlider");
 72	mKeysSlider = getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
 73	mSkyPresetsCombo = getChild<LLComboBox>("WLSkyPresets");
 74	mTimeCtrl = getChild<LLTimeCtrl>("time");
 75	mSaveButton = getChild<LLButton>("save");
 76	mMakeDefaultCheckBox = getChild<LLCheckBoxCtrl>("make_default_cb");
 77
 78	initCallbacks();
 79
 80	// add the time slider
 81	mTimeSlider->addSlider();
 82
 83	return TRUE;
 84}
 85
 86// virtual
 87void LLFloaterEditDayCycle::onOpen(const LLSD& key)
 88{
 89	bool new_day = isNewDay();
 90	std::string param = key.asString();
 91	std::string floater_title = getString(std::string("title_") + param);
 92	std::string hint = getString(std::string("hint_" + param));
 93
 94	// Update floater title.
 95	setTitle(floater_title);
 96
 97	// Update the hint at the top.
 98	getChild<LLUICtrl>("hint")->setValue(hint);
 99
100	// Hide the hint to the right of the combo if we're invoked to create a new preset.
101	getChildView("note")->setVisible(!new_day);
102
103	// Switch between the day cycle presets combobox and day cycle name input field.
104	mDayCyclesCombo->setVisible(!new_day);
105	mDayCycleNameEditor->setVisible(new_day);
106
107	// TODO: Make sure only one instance of the floater exists?
108
109	reset();
110}
111
112// virtual
113void LLFloaterEditDayCycle::onClose(bool app_quitting)
114{
115	if (!app_quitting) // there's no point to change environment if we're quitting
116	{
117		LLEnvManagerNew::instance().usePrefs(); // revert changes made to current day cycle
118	}
119}
120
121// virtual
122void LLFloaterEditDayCycle::draw()
123{
124	syncTimeSlider();
125	LLFloater::draw();
126}
127
128void LLFloaterEditDayCycle::initCallbacks(void)
129{
130	mDayCycleNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleNameEdited, this), NULL);
131	mDayCyclesCombo->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleSelected, this));
132	mDayCyclesCombo->setTextEntryCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleNameEdited, this));
133	mTimeSlider->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onTimeSliderMoved, this));
134	mKeysSlider->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onKeyTimeMoved, this));
135	mTimeCtrl->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onKeyTimeChanged, this));
136	mSkyPresetsCombo->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onKeyPresetChanged, this));
137
138	getChild<LLButton>("WLAddKey")->setClickedCallback(boost::bind(&LLFloaterEditDayCycle::onAddKey, this));
139	getChild<LLButton>("WLDeleteKey")->setClickedCallback(boost::bind(&LLFloaterEditDayCycle::onDeleteKey, this));
140
141	mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onBtnSave, this));
142	mSaveButton->setRightMouseDownCallback(boost::bind(&LLFloaterEditDayCycle::dumpTrack, this));
143	getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onBtnCancel, this));
144
145	// Connect to env manager events.
146	LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
147	env_mgr.setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsChange, this));
148	env_mgr.setRegionChangeCallback(boost::bind(&LLFloaterEditDayCycle::onRegionChange, this));
149	env_mgr.setRegionSettingsAppliedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsApplied, this, _1));
150
151	// Connect to day cycle manager events.
152	LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleListChange, this));
153
154	// Connect to sky preset list changes.
155	LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditDayCycle::onSkyPresetListChange, this));
156
157	// Connect to region info updates.
158	LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditDayCycle::onRegionInfoUpdate, this));
159}
160
161void LLFloaterEditDayCycle::syncTimeSlider()
162{
163	// set time
164	mTimeSlider->setCurSliderValue((F32)LLWLParamManager::getInstance()->mAnimator.getDayTime() * sHoursPerDay);
165}
166
167void LLFloaterEditDayCycle::loadTrack()
168{
169	// clear the slider
170	mKeysSlider->clear();
171	mSliderToKey.clear();
172
173	// add sliders
174
175	lldebugs << "Adding " << LLWLParamManager::getInstance()->mDay.mTimeMap.size() << " keys to slider" << llendl;
176
177	LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay;
178	for (std::map<F32, LLWLParamKey>::iterator it = cur_dayp.mTimeMap.begin(); it != cur_dayp.mTimeMap.end(); ++it)
179	{
180		addSliderKey(it->first * sHoursPerDay, it->second);
181	}
182
183	// set drop-down menu to match preset of currently-selected keyframe (one is automatically selected initially)
184	const std::string& cur_sldr = mKeysSlider->getCurSlider();
185	if (strlen(cur_sldr.c_str()) > 0)	// only do this if there is a curSldr, otherwise we put an invalid entry into the map
186	{
187		mSkyPresetsCombo->selectByValue(mSliderToKey[cur_sldr].keyframe.toStringVal());
188	}
189
190	syncTimeSlider();
191}
192
193void LLFloaterEditDayCycle::applyTrack()
194{
195	lldebugs << "Applying track (" << mSliderToKey.size() << ")" << llendl;
196
197	// if no keys, do nothing
198	if (mSliderToKey.size() == 0)
199	{
200		lldebugs << "No keys, not syncing" << llendl;
201		return;
202	}
203
204	llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size());
205
206	// create a new animation track
207	LLWLParamManager::getInstance()->mDay.clearKeyframes();
208
209	// add the keys one by one
210	for (std::map<std::string, SliderKey>::iterator it = mSliderToKey.begin();
211		it != mSliderToKey.end(); ++it)
212	{
213		LLWLParamManager::getInstance()->mDay.addKeyframe(it->second.time / sHoursPerDay,
214			it->second.keyframe);
215	}
216
217	// set the param manager's track to the new one
218	LLWLParamManager::getInstance()->resetAnimator(
219		mTimeSlider->getCurSliderValue() / sHoursPerDay, false);
220
221	LLWLParamManager::getInstance()->mAnimator.update(
222		LLWLParamManager::getInstance()->mCurParams);
223}
224
225void LLFloaterEditDayCycle::refreshSkyPresetsList()
226{
227	// Don't allow selecting region skies for a local day cycle,
228	// because thus we may end up with invalid day cycle.
229	bool include_region_skies = getSelectedDayCycle().scope == LLEnvKey::SCOPE_REGION;
230
231	mSkyPresetsCombo->removeall();
232
233	LLWLParamManager::preset_name_list_t region_presets;
234	LLWLParamManager::preset_name_list_t user_presets, sys_presets;
235	LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets);
236
237	if (include_region_skies)
238	{
239		// Add region presets.
240		for (LLWLParamManager::preset_name_list_t::const_iterator it = region_presets.begin(); it != region_presets.end(); ++it)
241		{
242			std::string preset_name = *it;
243			std::string item_title = preset_name + " (" + getRegionName() + ")";
244			mSkyPresetsCombo->add(preset_name, LLWLParamKey(*it, LLEnvKey::SCOPE_REGION).toStringVal());
245		}
246
247		if (!region_presets.empty())
248		{
249			mSkyPresetsCombo->addSeparator();
250		}
251	}
252
253	// Add user presets.
254	for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
255	{
256		mSkyPresetsCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal());
257	}
258
259	if (!user_presets.empty())
260	{
261		mSkyPresetsCombo->addSeparator();
262	}
263
264	// Add system presets.
265	for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it)
266	{
267		mSkyPresetsCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal());
268	}
269
270	// set defaults on combo boxes
271	mSkyPresetsCombo->selectFirstItem();
272}
273
274void LLFloaterEditDayCycle::refreshDayCyclesList()
275{
276	llassert(isNewDay() == false);
277
278	mDayCyclesCombo->removeall();
279
280#if 0 // Disable editing existing day cycle until the workflow is clear enough.
281	const LLSD& region_day = LLEnvManagerNew::instance().getRegionSettings().getWLDayCycle();
282	if (region_day.size() > 0)
283	{
284		LLWLParamKey key(getRegionName(), LLEnvKey::SCOPE_REGION);
285		mDayCyclesCombo->add(key.name, key.toLLSD());
286		mDayCyclesCombo->addSeparator();
287	}
288#endif
289
290	LLDayCycleManager::preset_name_list_t user_days, sys_days;
291	LLDayCycleManager::instance().getPresetNames(user_days, sys_days);
292
293	// Add user days.
294	for (LLDayCycleManager::preset_name_list_t::const_iterator it = user_days.begin(); it != user_days.end(); ++it)
295	{
296		mDayCyclesCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD());
297	}
298
299	if (user_days.size() > 0)
300	{
301		mDayCyclesCombo->addSeparator();
302	}
303
304	// Add system days.
305	for (LLDayCycleManager::preset_name_list_t::const_iterator it = sys_days.begin(); it != sys_days.end(); ++it)
306	{
307		mDayCyclesCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD());
308	}
309
310	mDayCyclesCombo->setLabel(getString("combo_label"));
311}
312
313void LLFloaterEditDayCycle::onTimeSliderMoved()
314{
315	/// get the slider value
316	F32 val = mTimeSlider->getCurSliderValue() / sHoursPerDay;
317
318	// set the value, turn off animation
319	LLWLParamManager::getInstance()->mAnimator.setDayTime((F64)val);
320	LLWLParamManager::getInstance()->mAnimator.deactivate();
321
322	// then call update once
323	LLWLParamManager::getInstance()->mAnimator.update(
324		LLWLParamManager::getInstance()->mCurParams);
325}
326
327void LLFloaterEditDayCycle::onKeyTimeMoved()
328{
329	if (mKeysSlider->getValue().size() == 0)
330	{
331		return;
332	}
333
334	// make sure we have a slider
335	const std::string& cur_sldr = mKeysSlider->getCurSlider();
336	if (cur_sldr == "")
337	{
338		return;
339	}
340
341	F32 time24 = mKeysSlider->getCurSliderValue();
342
343	// check to see if a key exists
344	LLWLParamKey key = mSliderToKey[cur_sldr].keyframe;
345	lldebugs << "Setting key time: " << time24 << LL_ENDL;
346	mSliderToKey[cur_sldr].time = time24;
347
348	// if it exists, turn on check box
349	mSkyPresetsCombo->selectByValue(key.toStringVal());
350
351	mTimeCtrl->setTime24(time24);
352
353	applyTrack();
354}
355
356void LLFloaterEditDayCycle::onKeyTimeChanged()
357{
358	// if no keys, skipped
359	if (mSliderToKey.size() == 0)
360	{
361		return;
362	}
363
364	F32 time24 = mTimeCtrl->getTime24();
365
366	const std::string& cur_sldr = mKeysSlider->getCurSlider();
367	mKeysSlider->setCurSliderValue(time24, TRUE);
368	F32 time = mKeysSlider->getCurSliderValue() / sHoursPerDay;
369
370	// now set the key's time in the sliderToKey map
371	lldebugs << "Setting key time: " << time << LL_ENDL;
372	mSliderToKey[cur_sldr].time = time;
373
374	applyTrack();
375}
376
377void LLFloaterEditDayCycle::onKeyPresetChanged()
378{
379	// do nothing if no sliders
380	if (mKeysSlider->getValue().size() == 0)
381	{
382		return;
383	}
384
385	// change the map
386
387	std::string stringVal = mSkyPresetsCombo->getSelectedValue().asString();
388	LLWLParamKey new_key(stringVal);
389	llassert(!new_key.name.empty());
390	const std::string& cur_sldr = mKeysSlider->getCurSlider();
391
392	// if null, don't use
393	if (cur_sldr == "")
394	{
395		return;
396	}
397
398	mSliderToKey[cur_sldr].keyframe = new_key;
399
400	// Apply changes to current day cycle.
401	applyTrack();
402}
403
404void LLFloaterEditDayCycle::onAddKey()
405{
406	llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size());
407
408	S32 max_sliders;
409	LLEnvKey::EScope scope = LLEnvKey::SCOPE_LOCAL; // *TODO: editing region day cycle
410	switch (scope)
411	{
412		case LLEnvKey::SCOPE_LOCAL:
413			max_sliders = 20; // *HACK this should be LLWLPacketScrubber::MAX_LOCAL_KEY_FRAMES;
414			break;
415		case LLEnvKey::SCOPE_REGION:
416			max_sliders = 12; // *HACK this should be LLWLPacketScrubber::MAX_REGION_KEY_FRAMES;
417			break;
418		default:
419			max_sliders = (S32) mKeysSlider->getMaxValue();
420			break;
421	}
422
423	if ((S32)mSliderToKey.size() >= max_sliders)
424	{
425		LLSD args;
426		args["SCOPE"] = LLEnvManagerNew::getScopeString(scope);
427		args["MAX"] = max_sliders;
428		LLNotificationsUtil::add("DayCycleTooManyKeyframes", args, LLSD(), LLNotificationFunctorRegistry::instance().DONOTHING);
429		return;
430	}
431
432	// add the slider key
433	std::string key_val = mSkyPresetsCombo->getSelectedValue().asString();
434	LLWLParamKey sky_params(key_val);
435	llassert(!sky_params.name.empty());
436
437	F32 time = mTimeSlider->getCurSliderValue();
438	addSliderKey(time, sky_params);
439
440	// apply the change to current day cycles
441	applyTrack();
442}
443
444void LLFloaterEditDayCycle::addSliderKey(F32 time, LLWLParamKey keyframe)
445{
446	// make a slider
447	const std::string& sldr_name = mKeysSlider->addSlider(time);
448	if (sldr_name.empty())
449	{
450		return;
451	}
452
453	// set the key
454	SliderKey newKey(keyframe, mKeysSlider->getCurSliderValue());
455
456	llassert_always(sldr_name != LLStringUtil::null);
457
458	// add to map
459	mSliderToKey.insert(std::pair<std::string, SliderKey>(sldr_name, newKey));
460
461	llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size());
462}
463
464LLWLParamKey LLFloaterEditDayCycle::getSelectedDayCycle()
465{
466	LLWLParamKey dc_key;
467
468	if (mDayCycleNameEditor->getVisible())
469	{
470		dc_key.name = mDayCycleNameEditor->getText();
471		dc_key.scope = LLEnvKey::SCOPE_LOCAL;
472	}
473	else
474	{
475		LLSD combo_val = mDayCyclesCombo->getValue();
476
477		if (!combo_val.isArray()) // manually typed text
478		{
479			dc_key.name = combo_val.asString();
480			dc_key.scope = LLEnvKey::SCOPE_LOCAL;
481		}
482		else
483		{
484			dc_key.fromLLSD(combo_val);
485		}
486	}
487
488	return dc_key;
489}
490
491bool LLFloaterEditDayCycle::isNewDay() const
492{
493	return mKey.asString() == "new";
494}
495
496void LLFloaterEditDayCycle::dumpTrack()
497{
498	LL_DEBUGS("Windlight") << "Dumping day cycle" << LL_ENDL;
499
500	LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay;
501	for (std::map<F32, LLWLParamKey>::iterator it = cur_dayp.mTimeMap.begin(); it != cur_dayp.mTimeMap.end(); ++it)
502	{
503		F32 time = it->first * 24.0f;
504		S32 h = (S32) time;
505		S32 m = (S32) ((time - h) * 60.0f);
506		LL_DEBUGS("Windlight") << llformat("(%.3f) %02d:%02d", time, h, m) << " => " << it->second.name << LL_ENDL;
507	}
508}
509
510void LLFloaterEditDayCycle::enableEditing(bool enable)
511{
512	mSkyPresetsCombo->setEnabled(enable);
513	mTimeCtrl->setEnabled(enable);
514	getChild<LLPanel>("day_cycle_slider_panel")->setCtrlsEnabled(enable);
515	mSaveButton->setEnabled(enable);
516	mMakeDefaultCheckBox->setEnabled(enable);
517}
518
519void LLFloaterEditDayCycle::reset()
520{
521	// clear the slider
522	mKeysSlider->clear();
523	mSliderToKey.clear();
524
525	refreshSkyPresetsList();
526
527	if (isNewDay())
528	{
529		mDayCycleNameEditor->setValue(LLSD());
530		F32 time = 0.5f * sHoursPerDay;
531		mSaveButton->setEnabled(FALSE); // will be enabled as soon as users enters a name
532		mTimeSlider->setCurSliderValue(time);
533
534		addSliderKey(time, LLWLParamKey("Default", LLEnvKey::SCOPE_LOCAL));
535		onKeyTimeMoved(); // update the time control and sky sky combo
536
537		applyTrack();
538	}
539	else
540	{
541		refreshDayCyclesList();
542
543		// Disable controls until a day cycle  to edit is selected.
544		enableEditing(false);
545	}
546}
547
548void LLFloaterEditDayCycle::saveRegionDayCycle()
549{
550	LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
551	LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay; // the day cycle being edited
552
553	// Get current day cycle and the sky preset it references.
554	LLSD day_cycle = cur_dayp.asLLSD();
555	LLSD sky_map;
556	cur_dayp.getSkyMap(sky_map);
557
558	// Apply it to the region.
559	LLEnvironmentSettings new_region_settings;
560	new_region_settings.saveParams(day_cycle, sky_map, env_mgr.getRegionSettings().getWaterParams(), 0.0f);
561
562#if 1
563	LLEnvManagerNew::instance().setRegionSettings(new_region_settings);
564#else // Temporary disabled ability to upload new region settings from the Day Cycle Editor.
565	if (!LLEnvManagerNew::instance().sendRegionSettings(new_region_settings))
566	{
567		llwarns << "Error applying region environment settings" << llendl;
568		return;
569	}
570
571	setApplyProgress(true);
572#endif
573}
574
575void LLFloaterEditDayCycle::setApplyProgress(bool started)
576{
577	LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("progress_indicator");
578
579	indicator->setVisible(started);
580
581	if (started)
582	{
583		indicator->start();
584	}
585	else
586	{
587		indicator->stop();
588	}
589}
590
591bool LLFloaterEditDayCycle::getApplyProgress() const
592{
593	return getChild<LLLoadingIndicator>("progress_indicator")->getVisible();
594}
595
596void LLFloaterEditDayCycle::onDeleteKey()
597{
598	if (mSliderToKey.size() == 0)
599	{
600		return;
601	}
602	else if (mSliderToKey.size() == 1)
603	{
604		LLNotifications::instance().add("EnvCannotDeleteLastDayCycleKey", LLSD(), LLSD());
605		return;
606	}
607
608	// delete from map
609	const std::string& sldr_name = mKeysSlider->getCurSlider();
610	std::map<std::string, SliderKey>::iterator mIt = mSliderToKey.find(sldr_name);
611	mSliderToKey.erase(mIt);
612
613	mKeysSlider->deleteCurSlider();
614
615	if (mSliderToKey.size() == 0)
616	{
617		return;
618	}
619
620	const std::string& name = mKeysSlider->getCurSlider();
621	mSkyPresetsCombo->selectByValue(mSliderToKey[name].keyframe.toStringVal());
622	F32 time24 = mSliderToKey[name].time;
623
624	mTimeCtrl->setTime24(time24);
625
626	applyTrack();
627}
628
629void LLFloaterEditDayCycle::onRegionSettingsChange()
630{
631	LL_DEBUGS("Windlight") << "Region settings changed" << LL_ENDL;
632
633	if (getApplyProgress()) // our region settings have being applied
634	{
635		setApplyProgress(false);
636
637		// Change preference if requested.
638		if (mMakeDefaultCheckBox->getValue())
639		{
640			LL_DEBUGS("Windlight") << "Changed environment preference to region settings" << llendl;
641			LLEnvManagerNew::instance().setUseRegionSettings(true);
642		}
643
644		closeFloater();
645	}
646}
647
648void LLFloaterEditDayCycle::onRegionChange()
649{
650	LL_DEBUGS("Windlight") << "Region changed" << LL_ENDL;
651
652	// If we're editing the region day cycle
653	if (getSelectedDayCycle().scope == LLEnvKey::SCOPE_REGION)
654	{
655		reset(); // undoes all unsaved changes
656	}
657}
658
659void LLFloaterEditDayCycle::onRegionSettingsApplied(bool success)
660{
661	LL_DEBUGS("Windlight") << "Region settings applied: " << success << LL_ENDL;
662
663	if (!success)
664	{
665		// stop progress indicator
666		setApplyProgress(false);
667	}
668}
669
670void LLFloaterEditDayCycle::onRegionInfoUpdate()
671{
672	LL_DEBUGS("Windlight") << "Region info updated" << LL_ENDL;
673	bool can_edit = true;
674
675	// If we've selected the region day cycle for editing.
676	if (getSelectedDayCycle().scope == LLEnvKey::SCOPE_REGION)
677	{
678		// check whether we have the access
679		can_edit = LLEnvManagerNew::canEditRegionSettings();
680	}
681
682	enableEditing(can_edit);
683}
684
685void LLFloaterEditDayCycle::onDayCycleNameEdited()
686{
687	// Disable saving a day cycle having empty name.
688	LLWLParamKey key = getSelectedDayCycle();
689	mSaveButton->setEnabled(!key.name.empty());
690}
691
692void LLFloaterEditDayCycle::onDayCycleSelected()
693{
694	LLSD day_data;
695	LLWLParamKey dc_key = getSelectedDayCycle();
696	bool can_edit = true;
697
698	if (dc_key.scope == LLEnvKey::SCOPE_LOCAL)
699	{
700		if (!LLDayCycleManager::instance().getPreset(dc_key.name, day_data))
701		{
702			llwarns << "No day cycle named " << dc_key.name << llendl;
703			return;
704		}
705	}
706	else
707	{
708		day_data = LLEnvManagerNew::instance().getRegionSettings().getWLDayCycle();
709		if (day_data.size() == 0)
710		{
711			llwarns << "Empty region day cycle" << llendl;
712			llassert(day_data.size() > 0);
713			return;
714		}
715
716		can_edit = LLEnvManagerNew::canEditRegionSettings();
717	}
718
719	// We may need to add or remove region skies from the list.
720	refreshSkyPresetsList();
721
722	F32 slider_time = mTimeSlider->getCurSliderValue() / sHoursPerDay;
723	LLWLParamManager::instance().applyDayCycleParams(day_data, dc_key.scope, slider_time);
724	loadTrack();
725
726	enableEditing(can_edit);
727}
728
729void LLFloaterEditDayCycle::onBtnSave()
730{
731	LLDayCycleManager& day_mgr = LLDayCycleManager::instance();
732	LLWLParamKey selected_day = getSelectedDayCycle();
733
734	if (selected_day.scope == LLEnvKey::SCOPE_REGION)
735	{
736		saveRegionDayCycle();
737		closeFloater();
738		return;
739	}
740
741	std::string name = selected_day.name;
742	if (name.empty())
743	{
744		// *TODO: show an alert
745		llwarns << "Empty day cycle name" << llendl;
746		return;
747	}
748
749	// Don't allow overwriting system presets.
750	if (day_mgr.isSystemPreset(name))
751	{
752		LLNotificationsUtil::add("WLNoEditDefault");
753		return;
754	}
755
756	// Save, ask for confirmation for overwriting an existing preset.
757	if (day_mgr.presetExists(name))
758	{
759		LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterEditDayCycle::onSaveAnswer, this, _1, _2));
760	}
761	else
762	{
763		// new preset, hence no confirmation needed
764		onSaveConfirmed();
765	}
766}
767
768void LLFloaterEditDayCycle::onBtnCancel()
769{
770	closeFloater();
771}
772
773bool LLFloaterEditDayCycle::onSaveAnswer(const LLSD& notification, const LLSD& response)
774{
775	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
776
777	// If they choose save, do it.  Otherwise, don't do anything
778	if (option == 0)
779	{
780		onSaveConfirmed();
781	}
782
783	return false;
784}
785
786void LLFloaterEditDayCycle::onSaveConfirmed()
787{
788	std::string name = getSelectedDayCycle().name;
789
790	// Save preset.
791	LLSD data = LLWLParamManager::instance().mDay.asLLSD();
792	LL_DEBUGS("Windlight") << "Saving day cycle " << name << ": " << data << LL_ENDL;
793	LLDayCycleManager::instance().savePreset(name, data);
794
795	// Change preference if requested.
796	if (mMakeDefaultCheckBox->getValue())
797	{
798		LL_DEBUGS("Windlight") << name << " is now the new preferred day cycle" << llendl;
799		LLEnvManagerNew::instance().setUseDayCycle(name);
800	}
801
802	closeFloater();
803}
804
805void LLFloaterEditDayCycle::onDayCycleListChange()
806{
807	if (!isNewDay())
808	{
809		refreshDayCyclesList();
810	}
811}
812
813void LLFloaterEditDayCycle::onSkyPresetListChange()
814{
815	refreshSkyPresetsList();
816
817	// Refresh sliders from the currently visible day cycle.
818	loadTrack();
819}
820
821// static
822std::string LLFloaterEditDayCycle::getRegionName()
823{
824	return gAgent.getRegion() ? gAgent.getRegion()->getName() : LLTrans::getString("Unknown");
825}