diff options
Diffstat (limited to 'indra')
23 files changed, 1277 insertions, 275 deletions
diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp index 960879c32c..ab442d7c83 100644 --- a/indra/newview/lldaycyclemanager.cpp +++ b/indra/newview/lldaycyclemanager.cpp @@ -88,19 +88,40 @@ bool LLDayCycleManager::savePreset(const std::string& name, const LLSD& data) bool LLDayCycleManager::deletePreset(const std::string& name) { - std::string path; - std::string filename = LLURI::escape(name) + ".xml"; + // Remove it from the map. + dc_map_t::iterator it = mDayCycleMap.find(name); + if (it == mDayCycleMap.end()) + { + LL_WARNS("Windlight") << "No day cycle named " << name << LL_ENDL; + return false; + } + mDayCycleMap.erase(it); - // Try removing specified user preset. - path = getUserDir() + filename; - if (gDirUtilp->fileExists(path)) + // Remove from the filesystem. + std::string filename = LLURI::escape(name) + ".xml"; + if (gDirUtilp->fileExists(getUserDir() + filename)) { gDirUtilp->deleteFilesInDir(getUserDir(), filename); - mModifySignal(); - return true; } - // Invalid or system preset. + // Signal interested parties. + mModifySignal(); + return true; +} + +bool LLDayCycleManager::isSkyPresetReferenced(const std::string& preset_name) const +{ + // We're traversing local day cycles, they can only reference local skies. + LLWLParamKey key(preset_name, LLEnvKey::SCOPE_LOCAL); + + for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it) + { + if (it->second.hasReferencesTo(key)) + { + return true; + } + } + return false; } @@ -144,7 +165,7 @@ bool LLDayCycleManager::loadPreset(const std::string& path) LLSD data = LLWLDayCycle::loadDayCycleFromPath(path); if (data.isUndefined()) { - LL_WARNS("Windlight") << "Error loading day cycle from " << path << LL_ENDL; + llwarns << "Error loading day cycle from " << path << llendl; return false; } diff --git a/indra/newview/lldaycyclemanager.h b/indra/newview/lldaycyclemanager.h index 0d4a474ac6..032e336491 100644 --- a/indra/newview/lldaycyclemanager.h +++ b/indra/newview/lldaycyclemanager.h @@ -54,6 +54,9 @@ public: bool savePreset(const std::string& name, const LLSD& data); bool deletePreset(const std::string& name); + /// @return true if there is a day cycle that refers to the sky preset. + bool isSkyPresetReferenced(const std::string& preset_name) const; + /// Emitted when a preset gets added or deleted. boost::signals2::connection setModifyCallback(const modify_signal_t::slot_type& cb); diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp index 8e4b7197d6..58d1349a63 100644 --- a/indra/newview/llenvmanager.cpp +++ b/indra/newview/llenvmanager.cpp @@ -923,6 +923,17 @@ boost::signals2::connection LLEnvManagerNew::setRegionSettingsAppliedCallback(co return mRegionSettingsAppliedSignal.connect(cb); } +// static +bool LLEnvManagerNew::canEditRegionSettings() +{ + LLViewerRegion* region = gAgent.getRegion(); + BOOL owner_or_god = gAgent.isGodlike() || (region && region->getOwner() == gAgent.getID()); + BOOL owner_or_god_or_manager = owner_or_god || (region && region->isEstateManager()); + + LL_DEBUGS("Windlight") << "Can edit region settings: " << (bool) owner_or_god_or_manager << LL_ENDL; + return owner_or_god_or_manager; +} + void LLEnvManagerNew::onRegionCrossing() { LL_DEBUGS("Windlight") << "Crossed region" << LL_ENDL; diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h index 7d4e647e90..de82787a08 100644 --- a/indra/newview/llenvmanager.h +++ b/indra/newview/llenvmanager.h @@ -328,6 +328,8 @@ public: boost::signals2::connection setRegionChangeCallback(const region_change_signal_t::slot_type& cb); boost::signals2::connection setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb); + static bool canEditRegionSettings(); /// @return true if we have access to editing region environment + // Public callbacks. void onRegionCrossing(); void onTeleport(); diff --git a/indra/newview/llfloaterdeleteenvpreset.cpp b/indra/newview/llfloaterdeleteenvpreset.cpp index d791c29a96..4fed5b9d5a 100644 --- a/indra/newview/llfloaterdeleteenvpreset.cpp +++ b/indra/newview/llfloaterdeleteenvpreset.cpp @@ -62,7 +62,9 @@ BOOL LLFloaterDeleteEnvPreset::postBuild() getChild<LLButton>("delete")->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::onBtnDelete, this)); getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::onBtnCancel, this)); - LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterDeleteEnvPreset::onDayCycleListChange, this)); + // Listen to presets addition/removal. + LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateDayCyclesList, this)); + LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateSkyPresetsList, this)); return TRUE; } @@ -89,7 +91,6 @@ void LLFloaterDeleteEnvPreset::onOpen(const LLSD& key) else if (param == "sky") { populateSkyPresetsList(); - getChild<LLButton>("delete")->setEnabled(FALSE); // not implemented yet } else if (param == "day_cycle") { @@ -104,6 +105,7 @@ void LLFloaterDeleteEnvPreset::onOpen(const LLSD& key) void LLFloaterDeleteEnvPreset::onBtnDelete() { std::string param = mKey.asString(); + std::string preset_name = mPresetCombo->getValue().asString(); boost::function<void()> confirm_cb; if (param == "water") @@ -113,13 +115,27 @@ void LLFloaterDeleteEnvPreset::onBtnDelete() } else if (param == "sky") { - llwarns << "Deleting sky presets not implemented" << llendl; - return; + // Don't allow deleting presets referenced by local day cycles. + if (LLDayCycleManager::instance().isSkyPresetReferenced(preset_name)) + { + LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", getString("msg_sky_is_referenced"))); + return; + } + + LLWLParamManager& wl_mgr = LLWLParamManager::instance(); + + // Don't allow deleting system presets. + if (wl_mgr.isSystemPreset(preset_name)) + { + LLNotificationsUtil::add("WLNoEditDefault"); + return; + } + + confirm_cb = boost::bind(&LLFloaterDeleteEnvPreset::onDeleteSkyPresetConfirmation, this); } else if (param == "day_cycle") { LLDayCycleManager& day_mgr = LLDayCycleManager::instance(); - std::string preset_name = mPresetCombo->getValue().asString(); // Don't allow deleting system presets. if (day_mgr.isSystemPreset(preset_name)) @@ -148,6 +164,8 @@ void LLFloaterDeleteEnvPreset::onBtnCancel() void LLFloaterDeleteEnvPreset::populateWaterPresetsList() { + if (mKey.asString() != "water") return; + mPresetCombo->removeall(); // *TODO: Reload the list when user preferences change. @@ -161,35 +179,76 @@ void LLFloaterDeleteEnvPreset::populateWaterPresetsList() bool enabled = (name != water_mgr.mCurParams.mName); // don't allow deleting current preset mPresetCombo->add(name, ADD_BOTTOM, enabled); } + + postPopulate(); } void LLFloaterDeleteEnvPreset::populateSkyPresetsList() { + if (mKey.asString() != "sky") return; + mPresetCombo->removeall(); + std::string cur_preset; + LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance(); + if (!env_mgr.getUseRegionSettings() && env_mgr.getUseFixedSky()) + { + cur_preset = env_mgr.getSkyPresetName(); + } + // *TODO: Reload the list when user preferences change. LLWLParamManager& sky_mgr = LLWLParamManager::instance(); - LL_DEBUGS("Windlight") << "Current sky preset: " << sky_mgr.mCurParams.mName << LL_ENDL; - const std::map<LLWLParamKey, LLWLParamSet> &sky_params_map = sky_mgr.mParamList; for (std::map<LLWLParamKey, LLWLParamSet>::const_iterator it = sky_params_map.begin(); it != sky_params_map.end(); it++) { - if (it->first.scope == LLEnvKey::SCOPE_REGION) continue; // list only local presets - bool enabled = (it->first.name != sky_mgr.mCurParams.mName); - mPresetCombo->add(it->first.name, ADD_BOTTOM, enabled); + const LLWLParamKey& key = it->first; + + // list only local user presets + if (key.scope == LLEnvKey::SCOPE_REGION || sky_mgr.isSystemPreset(key.name)) + { + continue; + } + + bool enabled = (key.name != cur_preset); + mPresetCombo->add(key.name, ADD_BOTTOM, enabled); } + + postPopulate(); } void LLFloaterDeleteEnvPreset::populateDayCyclesList() { + if (mKey.asString() != "day_cycle") return; + mPresetCombo->removeall(); - // *TODO: Disable current day cycle. + std::string cur_day; + LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance(); + if (!env_mgr.getUseRegionSettings() && env_mgr.getUseDayCycle()) + { + cur_day = env_mgr.getDayCycleName(); + } + const LLDayCycleManager::dc_map_t& map = LLDayCycleManager::instance().getPresets(); for (LLDayCycleManager::dc_map_t::const_iterator it = map.begin(); it != map.end(); ++it) { - mPresetCombo->add(it->first); + mPresetCombo->add(it->first, ADD_BOTTOM, it->first != cur_day); } + + postPopulate(); +} + +void LLFloaterDeleteEnvPreset::postPopulate() +{ + // Handle empty list. + S32 n_items = mPresetCombo->getItemCount(); + + if (n_items == 0) + { + mPresetCombo->setLabel(getString("combo_label")); + } + + getChild<LLButton>("delete")->setEnabled(n_items > 0); } void LLFloaterDeleteEnvPreset::onDeleteDayCycleConfirmation() @@ -197,7 +256,8 @@ void LLFloaterDeleteEnvPreset::onDeleteDayCycleConfirmation() LLDayCycleManager::instance().deletePreset(mPresetCombo->getValue().asString()); } -void LLFloaterDeleteEnvPreset::onDayCycleListChange() +void LLFloaterDeleteEnvPreset::onDeleteSkyPresetConfirmation() { - populateDayCyclesList(); + LLWLParamKey key(mPresetCombo->getValue().asString(), LLEnvKey::SCOPE_LOCAL); + LLWLParamManager::instance().removeParamSet(key, true); } diff --git a/indra/newview/llfloaterdeleteenvpreset.h b/indra/newview/llfloaterdeleteenvpreset.h index aaa4143233..63f80d89d8 100644 --- a/indra/newview/llfloaterdeleteenvpreset.h +++ b/indra/newview/llfloaterdeleteenvpreset.h @@ -49,8 +49,10 @@ private: void populateSkyPresetsList(); void populateDayCyclesList(); + void postPopulate(); + void onDeleteDayCycleConfirmation(); - void onDayCycleListChange(); + void onDeleteSkyPresetConfirmation(); LLComboBox* mPresetCombo; }; diff --git a/indra/newview/llfloatereditdaycycle.cpp b/indra/newview/llfloatereditdaycycle.cpp index 28ff353369..ebb8369c8f 100644 --- a/indra/newview/llfloatereditdaycycle.cpp +++ b/indra/newview/llfloatereditdaycycle.cpp @@ -150,6 +150,9 @@ void LLFloaterEditDayCycle::initCallbacks(void) // Connect to day cycle manager events. LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleListChange, this)); + // Connect to sky preset list changes. + LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditDayCycle::onSkyPresetListChange, this)); + // Connect to region info updates. LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditDayCycle::onRegionInfoUpdate, this)); } @@ -454,24 +457,6 @@ LLWLParamKey LLFloaterEditDayCycle::getSelectedDayCycle() return dc_key; } -void LLFloaterEditDayCycle::deletePreset(LLWLParamKey keyframe) -{ - // *TODO: This should be called when a sky preset gets deleted. - - /// delete any reference - std::map<std::string, SliderKey>::iterator curr_preset, next_preset; - for (curr_preset = mSliderToKey.begin(); curr_preset != mSliderToKey.end(); curr_preset = next_preset) - { - next_preset = curr_preset; - ++next_preset; - if (curr_preset->second.keyframe == keyframe) - { - mKeysSlider->deleteSlider(curr_preset->first); - mSliderToKey.erase(curr_preset); - } - } -} - bool LLFloaterEditDayCycle::isNewDay() const { return mKey.asString() == "new"; @@ -660,7 +645,7 @@ void LLFloaterEditDayCycle::onRegionInfoUpdate() if (getSelectedDayCycle().scope == LLEnvKey::SCOPE_REGION) { // check whether we have the access - can_edit = canEditRegionSettings(); + can_edit = LLEnvManagerNew::canEditRegionSettings(); } enableEditing(can_edit); @@ -697,7 +682,7 @@ void LLFloaterEditDayCycle::onDayCycleSelected() return; } - can_edit = canEditRegionSettings(); + can_edit = LLEnvManagerNew::canEditRegionSettings(); } // We may need to add or remove region skies from the list. @@ -794,19 +779,16 @@ void LLFloaterEditDayCycle::onDayCycleListChange() } } -// static -std::string LLFloaterEditDayCycle::getRegionName() +void LLFloaterEditDayCycle::onSkyPresetListChange() { - return gAgent.getRegion() ? gAgent.getRegion()->getName() : LLTrans::getString("Unknown"); + refreshSkyPresetsList(); + + // Refresh sliders from the currently visible day cycle. + loadTrack(); } // static -bool LLFloaterEditDayCycle::canEditRegionSettings() +std::string LLFloaterEditDayCycle::getRegionName() { - LLViewerRegion* region = gAgent.getRegion(); - BOOL owner_or_god = gAgent.isGodlike() || (region && region->getOwner() == gAgent.getID()); - BOOL owner_or_god_or_manager = owner_or_god || (region && region->isEstateManager()); - - LL_DEBUGS("Windlight") << "Can edit region settings: " << owner_or_god_or_manager << LL_ENDL; - return owner_or_god_or_manager; + return gAgent.getRegion() ? gAgent.getRegion()->getName() : LLTrans::getString("Unknown"); } diff --git a/indra/newview/llfloatereditdaycycle.h b/indra/newview/llfloatereditdaycycle.h index 3b467b2939..e6e4fe39c1 100644 --- a/indra/newview/llfloatereditdaycycle.h +++ b/indra/newview/llfloatereditdaycycle.h @@ -37,8 +37,9 @@ class LLLineEditor; class LLMultiSliderCtrl; class LLTimeCtrl; -/// Menu for all of windlight's functionality. -/// Menuing system for adjusting the atmospheric settings of the world. +/** + * Floater for creating or editing a day cycle. + */ class LLFloaterEditDayCycle : public LLFloater { LOG_CLASS(LLFloaterEditDayCycle); @@ -73,7 +74,6 @@ private: void initCallbacks(); LLWLParamKey getSelectedDayCycle(); - void deletePreset(LLWLParamKey keyframe); bool isNewDay() const; void dumpTrack(); void enableEditing(bool enable); @@ -104,9 +104,9 @@ private: void onSaveConfirmed(); void onDayCycleListChange(); + void onSkyPresetListChange(); static std::string getRegionName(); - static bool canEditRegionSettings(); /// convenience class for holding keyframes mapped to sliders struct SliderKey diff --git a/indra/newview/llfloatereditsky.cpp b/indra/newview/llfloatereditsky.cpp index 312479951e..7b8e3b89ca 100644 --- a/indra/newview/llfloatereditsky.cpp +++ b/indra/newview/llfloatereditsky.cpp @@ -30,22 +30,40 @@ // libs #include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llsliderctrl.h" +#include "lltabcontainer.h" // newview +#include "llagent.h" +#include "llregioninfomodel.h" +#include "llviewerregion.h" + +#undef max + +static const F32 WL_SUN_AMBIENT_SLIDER_SCALE = 3.0f; LLFloaterEditSky::LLFloaterEditSky(const LLSD &key) : LLFloater(key) +, mSkyPresetNameEditor(NULL) +, mSkyPresetCombo(NULL) +, mMakeDefaultCheckBox(NULL) +, mSaveButton(NULL) { } // virtual BOOL LLFloaterEditSky::postBuild() { - getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnCancel, this)); + mSkyPresetNameEditor = getChild<LLLineEditor>("sky_preset_name"); + mSkyPresetCombo = getChild<LLComboBox>("sky_preset_combo"); + mMakeDefaultCheckBox = getChild<LLCheckBoxCtrl>("make_default_cb"); + mSaveButton = getChild<LLButton>("save"); - // Disable some non-functional controls. - getChildView("sky_preset_combo")->setEnabled(FALSE); - getChildView("save")->setEnabled(FALSE); + initCallbacks(); return TRUE; } @@ -53,6 +71,7 @@ BOOL LLFloaterEditSky::postBuild() // virtual void LLFloaterEditSky::onOpen(const LLSD& key) { + bool new_preset = isNewPreset(); std::string param = key.asString(); std::string floater_title = getString(std::string("title_") + param); std::string hint = getString(std::string("hint_" + param)); @@ -64,10 +83,891 @@ void LLFloaterEditSky::onOpen(const LLSD& key) getChild<LLUICtrl>("hint")->setValue(hint); // Hide the hint to the right of the combo if we're invoked to create a new preset. - getChildView("note")->setVisible(param == "edit"); + getChildView("note")->setVisible(!new_preset); + + // Switch between the sky presets combobox and preset name input field. + mSkyPresetCombo->setVisible(!new_preset); + mSkyPresetNameEditor->setVisible(new_preset); + + reset(); +} + +// virtual +void LLFloaterEditSky::onClose(bool app_quitting) +{ + if (!app_quitting) // there's no point to change environment if we're quitting + { + LLEnvManagerNew::instance().usePrefs(); // revert changes made to current environment + } +} + +// virtual +void LLFloaterEditSky::draw() +{ + syncControls(); + LLFloater::draw(); +} + +void LLFloaterEditSky::initCallbacks(void) +{ + // *TODO: warn user if a region environment update comes while we're editing a region sky preset. + + mSkyPresetNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterEditSky::onSkyPresetNameEdited, this), NULL); + mSkyPresetCombo->setCommitCallback(boost::bind(&LLFloaterEditSky::onSkyPresetSelected, this)); + mSkyPresetCombo->setTextEntryCallback(boost::bind(&LLFloaterEditSky::onSkyPresetNameEdited, this)); + + mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnSave, this)); + getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnCancel, this)); + + LLEnvManagerNew::instance().setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditSky::onRegionSettingsChange, this)); + LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditSky::onSkyPresetListChange, this)); + + // Connect to region info updates. + LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditSky::onRegionInfoUpdate, this)); + + //------------------------------------------------------------------------- + + LLWLParamManager& param_mgr = LLWLParamManager::instance(); + + // blue horizon + getChild<LLUICtrl>("WLBlueHorizonR")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mBlueHorizon)); + getChild<LLUICtrl>("WLBlueHorizonR")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mBlueHorizon)); + getChild<LLUICtrl>("WLBlueHorizonG")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, ¶m_mgr.mBlueHorizon)); + getChild<LLUICtrl>("WLBlueHorizonB")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, ¶m_mgr.mBlueHorizon)); + getChild<LLUICtrl>("WLBlueHorizonI")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlIMoved, this, _1, ¶m_mgr.mBlueHorizon)); + + // haze density, horizon, mult, and altitude + getChild<LLUICtrl>("WLHazeDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mHazeDensity)); + getChild<LLUICtrl>("WLHazeHorizon")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mHazeHorizon)); + getChild<LLUICtrl>("WLDensityMult")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mDensityMult)); + getChild<LLUICtrl>("WLMaxAltitude")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mMaxAlt)); + + // blue density + getChild<LLUICtrl>("WLBlueDensityR")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mBlueDensity)); + getChild<LLUICtrl>("WLBlueDensityG")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, ¶m_mgr.mBlueDensity)); + getChild<LLUICtrl>("WLBlueDensityB")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, ¶m_mgr.mBlueDensity)); + getChild<LLUICtrl>("WLBlueDensityI")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlIMoved, this, _1, ¶m_mgr.mBlueDensity)); + + // Lighting + + // sunlight + getChild<LLUICtrl>("WLSunlightR")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mSunlight)); + getChild<LLUICtrl>("WLSunlightG")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, ¶m_mgr.mSunlight)); + getChild<LLUICtrl>("WLSunlightB")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, ¶m_mgr.mSunlight)); + getChild<LLUICtrl>("WLSunlightI")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlIMoved, this, _1, ¶m_mgr.mSunlight)); + + // glow + getChild<LLUICtrl>("WLGlowR")->setCommitCallback(boost::bind(&LLFloaterEditSky::onGlowRMoved, this, _1, ¶m_mgr.mGlow)); + getChild<LLUICtrl>("WLGlowB")->setCommitCallback(boost::bind(&LLFloaterEditSky::onGlowBMoved, this, _1, ¶m_mgr.mGlow)); + + // ambient + getChild<LLUICtrl>("WLAmbientR")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mAmbient)); + getChild<LLUICtrl>("WLAmbientG")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, ¶m_mgr.mAmbient)); + getChild<LLUICtrl>("WLAmbientB")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, ¶m_mgr.mAmbient)); + getChild<LLUICtrl>("WLAmbientI")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlIMoved, this, _1, ¶m_mgr.mAmbient)); + + // time of day + getChild<LLUICtrl>("WLSunAngle")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunMoved, this, _1, ¶m_mgr.mLightnorm)); + getChild<LLUICtrl>("WLEastAngle")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunMoved, this, _1, ¶m_mgr.mLightnorm)); + + // Clouds + + // Cloud Color + getChild<LLUICtrl>("WLCloudColorR")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mCloudColor)); + getChild<LLUICtrl>("WLCloudColorG")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, ¶m_mgr.mCloudColor)); + getChild<LLUICtrl>("WLCloudColorB")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, ¶m_mgr.mCloudColor)); + getChild<LLUICtrl>("WLCloudColorI")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlIMoved, this, _1, ¶m_mgr.mCloudColor)); + + // Cloud + getChild<LLUICtrl>("WLCloudX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mCloudMain)); + getChild<LLUICtrl>("WLCloudY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, ¶m_mgr.mCloudMain)); + getChild<LLUICtrl>("WLCloudDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, ¶m_mgr.mCloudMain)); + + // Cloud Detail + getChild<LLUICtrl>("WLCloudDetailX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mCloudDetail)); + getChild<LLUICtrl>("WLCloudDetailY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, ¶m_mgr.mCloudDetail)); + getChild<LLUICtrl>("WLCloudDetailDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, ¶m_mgr.mCloudDetail)); + + // Cloud extras + getChild<LLUICtrl>("WLCloudCoverage")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mCloudCoverage)); + getChild<LLUICtrl>("WLCloudScale")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mCloudScale)); + getChild<LLUICtrl>("WLCloudLockX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollXToggled, this, _1)); + getChild<LLUICtrl>("WLCloudLockY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollYToggled, this, _1)); + getChild<LLUICtrl>("WLCloudScrollX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollXMoved, this, _1)); + getChild<LLUICtrl>("WLCloudScrollY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollYMoved, this, _1)); + getChild<LLUICtrl>("WLDistanceMult")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mDistanceMult)); + + // Dome + getChild<LLUICtrl>("WLGamma")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mWLGamma)); + getChild<LLUICtrl>("WLStarAlpha")->setCommitCallback(boost::bind(&LLFloaterEditSky::onStarAlphaMoved, this, _1)); +} + +//================================================================================================= + +void LLFloaterEditSky::syncControls() +{ + bool err; + + LLWLParamManager * param_mgr = LLWLParamManager::getInstance(); + + LLWLParamSet& cur_params = param_mgr->mCurParams; + + // blue horizon + param_mgr->mBlueHorizon = cur_params.getVector(param_mgr->mBlueHorizon.mName, err); + childSetValue("WLBlueHorizonR", param_mgr->mBlueHorizon.r / 2.0); + childSetValue("WLBlueHorizonG", param_mgr->mBlueHorizon.g / 2.0); + childSetValue("WLBlueHorizonB", param_mgr->mBlueHorizon.b / 2.0); + childSetValue("WLBlueHorizonI", + std::max(param_mgr->mBlueHorizon.r / 2.0, + std::max(param_mgr->mBlueHorizon.g / 2.0, + param_mgr->mBlueHorizon.b / 2.0))); + + // haze density, horizon, mult, and altitude + param_mgr->mHazeDensity = cur_params.getVector(param_mgr->mHazeDensity.mName, err); + childSetValue("WLHazeDensity", param_mgr->mHazeDensity.r); + param_mgr->mHazeHorizon = cur_params.getVector(param_mgr->mHazeHorizon.mName, err); + childSetValue("WLHazeHorizon", param_mgr->mHazeHorizon.r); + param_mgr->mDensityMult = cur_params.getVector(param_mgr->mDensityMult.mName, err); + childSetValue("WLDensityMult", param_mgr->mDensityMult.x * + param_mgr->mDensityMult.mult); + param_mgr->mMaxAlt = cur_params.getVector(param_mgr->mMaxAlt.mName, err); + childSetValue("WLMaxAltitude", param_mgr->mMaxAlt.x); + + // blue density + param_mgr->mBlueDensity = cur_params.getVector(param_mgr->mBlueDensity.mName, err); + childSetValue("WLBlueDensityR", param_mgr->mBlueDensity.r / 2.0); + childSetValue("WLBlueDensityG", param_mgr->mBlueDensity.g / 2.0); + childSetValue("WLBlueDensityB", param_mgr->mBlueDensity.b / 2.0); + childSetValue("WLBlueDensityI", + std::max(param_mgr->mBlueDensity.r / 2.0, + std::max(param_mgr->mBlueDensity.g / 2.0, param_mgr->mBlueDensity.b / 2.0))); + + // Lighting + + // sunlight + param_mgr->mSunlight = cur_params.getVector(param_mgr->mSunlight.mName, err); + childSetValue("WLSunlightR", param_mgr->mSunlight.r / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLSunlightG", param_mgr->mSunlight.g / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLSunlightB", param_mgr->mSunlight.b / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLSunlightI", + std::max(param_mgr->mSunlight.r / WL_SUN_AMBIENT_SLIDER_SCALE, + std::max(param_mgr->mSunlight.g / WL_SUN_AMBIENT_SLIDER_SCALE, param_mgr->mSunlight.b / WL_SUN_AMBIENT_SLIDER_SCALE))); + + // glow + param_mgr->mGlow = cur_params.getVector(param_mgr->mGlow.mName, err); + childSetValue("WLGlowR", 2 - param_mgr->mGlow.r / 20.0f); + childSetValue("WLGlowB", -param_mgr->mGlow.b / 5.0f); + + // ambient + param_mgr->mAmbient = cur_params.getVector(param_mgr->mAmbient.mName, err); + childSetValue("WLAmbientR", param_mgr->mAmbient.r / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLAmbientG", param_mgr->mAmbient.g / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLAmbientB", param_mgr->mAmbient.b / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLAmbientI", + std::max(param_mgr->mAmbient.r / WL_SUN_AMBIENT_SLIDER_SCALE, + std::max(param_mgr->mAmbient.g / WL_SUN_AMBIENT_SLIDER_SCALE, param_mgr->mAmbient.b / WL_SUN_AMBIENT_SLIDER_SCALE))); + + childSetValue("WLSunAngle", param_mgr->mCurParams.getFloat("sun_angle",err) / F_TWO_PI); + childSetValue("WLEastAngle", param_mgr->mCurParams.getFloat("east_angle",err) / F_TWO_PI); + + // Clouds + + // Cloud Color + param_mgr->mCloudColor = cur_params.getVector(param_mgr->mCloudColor.mName, err); + childSetValue("WLCloudColorR", param_mgr->mCloudColor.r); + childSetValue("WLCloudColorG", param_mgr->mCloudColor.g); + childSetValue("WLCloudColorB", param_mgr->mCloudColor.b); + childSetValue("WLCloudColorI", + std::max(param_mgr->mCloudColor.r, + std::max(param_mgr->mCloudColor.g, param_mgr->mCloudColor.b))); + + // Cloud + param_mgr->mCloudMain = cur_params.getVector(param_mgr->mCloudMain.mName, err); + childSetValue("WLCloudX", param_mgr->mCloudMain.r); + childSetValue("WLCloudY", param_mgr->mCloudMain.g); + childSetValue("WLCloudDensity", param_mgr->mCloudMain.b); + + // Cloud Detail + param_mgr->mCloudDetail = cur_params.getVector(param_mgr->mCloudDetail.mName, err); + childSetValue("WLCloudDetailX", param_mgr->mCloudDetail.r); + childSetValue("WLCloudDetailY", param_mgr->mCloudDetail.g); + childSetValue("WLCloudDetailDensity", param_mgr->mCloudDetail.b); + + // Cloud extras + param_mgr->mCloudCoverage = cur_params.getVector(param_mgr->mCloudCoverage.mName, err); + param_mgr->mCloudScale = cur_params.getVector(param_mgr->mCloudScale.mName, err); + childSetValue("WLCloudCoverage", param_mgr->mCloudCoverage.x); + childSetValue("WLCloudScale", param_mgr->mCloudScale.x); + + // cloud scrolling + bool lockX = !param_mgr->mCurParams.getEnableCloudScrollX(); + bool lockY = !param_mgr->mCurParams.getEnableCloudScrollY(); + childSetValue("WLCloudLockX", lockX); + childSetValue("WLCloudLockY", lockY); + + // disable if locked, enable if not + if (lockX) + { + childDisable("WLCloudScrollX"); + } + else + { + childEnable("WLCloudScrollX"); + } + if (lockY) + { + childDisable("WLCloudScrollY"); + } + else + { + childEnable("WLCloudScrollY"); + } + + // *HACK cloud scrolling is off my an additive of 10 + childSetValue("WLCloudScrollX", param_mgr->mCurParams.getCloudScrollX() - 10.0f); + childSetValue("WLCloudScrollY", param_mgr->mCurParams.getCloudScrollY() - 10.0f); + + param_mgr->mDistanceMult = cur_params.getVector(param_mgr->mDistanceMult.mName, err); + childSetValue("WLDistanceMult", param_mgr->mDistanceMult.x); + + // Tweak extras + + param_mgr->mWLGamma = cur_params.getVector(param_mgr->mWLGamma.mName, err); + childSetValue("WLGamma", param_mgr->mWLGamma.x); + + childSetValue("WLStarAlpha", param_mgr->mCurParams.getStarBrightness()); +} + + +// color control callbacks +void LLFloaterEditSky::onColorControlRMoved(LLUICtrl* ctrl, void* userdata) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + color_ctrl->r = sldr_ctrl->getValueF32(); + if (color_ctrl->isSunOrAmbientColor) + { + color_ctrl->r *= 3; + } + if (color_ctrl->isBlueHorizonOrDensity) + { + color_ctrl->r *= 2; + } + + // move i if it's the max + if (color_ctrl->r >= color_ctrl->g && color_ctrl->r >= color_ctrl->b && color_ctrl->hasSliderName) + { + color_ctrl->i = color_ctrl->r; + std::string name = color_ctrl->mSliderName; + name.append("I"); + + if (color_ctrl->isSunOrAmbientColor) + { + childSetValue(name, color_ctrl->r / 3); + } + else if (color_ctrl->isBlueHorizonOrDensity) + { + childSetValue(name, color_ctrl->r / 2); + } + else + { + childSetValue(name, color_ctrl->r); + } + } + + color_ctrl->update(LLWLParamManager::getInstance()->mCurParams); + + LLWLParamManager::getInstance()->propagateParameters(); +} + +void LLFloaterEditSky::onColorControlGMoved(LLUICtrl* ctrl, void* userdata) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + color_ctrl->g = sldr_ctrl->getValueF32(); + if (color_ctrl->isSunOrAmbientColor) + { + color_ctrl->g *= 3; + } + if (color_ctrl->isBlueHorizonOrDensity) + { + color_ctrl->g *= 2; + } + + // move i if it's the max + if (color_ctrl->g >= color_ctrl->r && color_ctrl->g >= color_ctrl->b && color_ctrl->hasSliderName) + { + color_ctrl->i = color_ctrl->g; + std::string name = color_ctrl->mSliderName; + name.append("I"); + + if (color_ctrl->isSunOrAmbientColor) + { + childSetValue(name, color_ctrl->g / 3); + } + else if (color_ctrl->isBlueHorizonOrDensity) + { + childSetValue(name, color_ctrl->g / 2); + } + else + { + childSetValue(name, color_ctrl->g); + } + } + + color_ctrl->update(LLWLParamManager::getInstance()->mCurParams); + + LLWLParamManager::getInstance()->propagateParameters(); +} + +void LLFloaterEditSky::onColorControlBMoved(LLUICtrl* ctrl, void* userdata) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + color_ctrl->b = sldr_ctrl->getValueF32(); + if (color_ctrl->isSunOrAmbientColor) + { + color_ctrl->b *= 3; + } + if (color_ctrl->isBlueHorizonOrDensity) + { + color_ctrl->b *= 2; + } + + // move i if it's the max + if (color_ctrl->b >= color_ctrl->r && color_ctrl->b >= color_ctrl->g && color_ctrl->hasSliderName) + { + color_ctrl->i = color_ctrl->b; + std::string name = color_ctrl->mSliderName; + name.append("I"); + + if (color_ctrl->isSunOrAmbientColor) + { + childSetValue(name, color_ctrl->b / 3); + } + else if (color_ctrl->isBlueHorizonOrDensity) + { + childSetValue(name, color_ctrl->b / 2); + } + else + { + childSetValue(name, color_ctrl->b); + } + } + + color_ctrl->update(LLWLParamManager::getInstance()->mCurParams); + + LLWLParamManager::getInstance()->propagateParameters(); +} + +void LLFloaterEditSky::onColorControlIMoved(LLUICtrl* ctrl, void* userdata) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + color_ctrl->i = sldr_ctrl->getValueF32(); + + // only for sliders where we pass a name + if (color_ctrl->hasSliderName) + { + // set it to the top + F32 maxVal = std::max(std::max(color_ctrl->r, color_ctrl->g), color_ctrl->b); + F32 iVal; + + if (color_ctrl->isSunOrAmbientColor) + { + iVal = color_ctrl->i * 3; + } + else if (color_ctrl->isBlueHorizonOrDensity) + { + iVal = color_ctrl->i * 2; + } + else + { + iVal = color_ctrl->i; + } + + // get the names of the other sliders + std::string rName = color_ctrl->mSliderName; + rName.append("R"); + std::string gName = color_ctrl->mSliderName; + gName.append("G"); + std::string bName = color_ctrl->mSliderName; + bName.append("B"); + + // handle if at 0 + if (iVal == 0) + { + color_ctrl->r = 0; + color_ctrl->g = 0; + color_ctrl->b = 0; + + // if all at the start + // set them all to the intensity + } + else if (maxVal == 0) + { + color_ctrl->r = iVal; + color_ctrl->g = iVal; + color_ctrl->b = iVal; + + } + else + { + // add delta amounts to each + F32 delta = (iVal - maxVal) / maxVal; + color_ctrl->r *= (1.0f + delta); + color_ctrl->g *= (1.0f + delta); + color_ctrl->b *= (1.0f + delta); + } + + // divide sun color vals by three + if (color_ctrl->isSunOrAmbientColor) + { + childSetValue(rName, color_ctrl->r/3); + childSetValue(gName, color_ctrl->g/3); + childSetValue(bName, color_ctrl->b/3); + } + else if (color_ctrl->isBlueHorizonOrDensity) + { + childSetValue(rName, color_ctrl->r/2); + childSetValue(gName, color_ctrl->g/2); + childSetValue(bName, color_ctrl->b/2); + } + else + { + // set the sliders to the new vals + childSetValue(rName, color_ctrl->r); + childSetValue(gName, color_ctrl->g); + childSetValue(bName, color_ctrl->b); + } + } + + // now update the current parameters and send them to shaders + color_ctrl->update(LLWLParamManager::getInstance()->mCurParams); + LLWLParamManager::getInstance()->propagateParameters(); +} + +/// GLOW SPECIFIC CODE +void LLFloaterEditSky::onGlowRMoved(LLUICtrl* ctrl, void* userdata) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + // scaled by 20 + color_ctrl->r = (2 - sldr_ctrl->getValueF32()) * 20; + + color_ctrl->update(LLWLParamManager::getInstance()->mCurParams); + LLWLParamManager::getInstance()->propagateParameters(); +} + +/// \NOTE that we want NEGATIVE (-) B +void LLFloaterEditSky::onGlowBMoved(LLUICtrl* ctrl, void* userdata) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + /// \NOTE that we want NEGATIVE (-) B and NOT by 20 as 20 is too big + color_ctrl->b = -sldr_ctrl->getValueF32() * 5; + + color_ctrl->update(LLWLParamManager::getInstance()->mCurParams); + LLWLParamManager::getInstance()->propagateParameters(); +} + +void LLFloaterEditSky::onFloatControlMoved(LLUICtrl* ctrl, void* userdata) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + WLFloatControl * floatControl = static_cast<WLFloatControl *>(userdata); + + floatControl->x = sldr_ctrl->getValueF32() / floatControl->mult; + + floatControl->update(LLWLParamManager::getInstance()->mCurParams); + LLWLParamManager::getInstance()->propagateParameters(); +} + + +// Lighting callbacks + +// time of day +void LLFloaterEditSky::onSunMoved(LLUICtrl* ctrl, void* userdata) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLSliderCtrl* sun_sldr = getChild<LLSliderCtrl>("WLSunAngle"); + LLSliderCtrl* east_sldr = getChild<LLSliderCtrl>("WLEastAngle"); + + WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); + + // get the two angles + LLWLParamManager * param_mgr = LLWLParamManager::getInstance(); + + param_mgr->mCurParams.setSunAngle(F_TWO_PI * sun_sldr->getValueF32()); + param_mgr->mCurParams.setEastAngle(F_TWO_PI * east_sldr->getValueF32()); + + // set the sun vector + color_ctrl->r = -sin(param_mgr->mCurParams.getEastAngle()) * + cos(param_mgr->mCurParams.getSunAngle()); + color_ctrl->g = sin(param_mgr->mCurParams.getSunAngle()); + color_ctrl->b = cos(param_mgr->mCurParams.getEastAngle()) * + cos(param_mgr->mCurParams.getSunAngle()); + color_ctrl->i = 1.f; + + color_ctrl->update(param_mgr->mCurParams); + param_mgr->propagateParameters(); +} + +void LLFloaterEditSky::onStarAlphaMoved(LLUICtrl* ctrl) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + + LLWLParamManager::getInstance()->mCurParams.setStarBrightness(sldr_ctrl->getValueF32()); +} + +// Clouds +void LLFloaterEditSky::onCloudScrollXMoved(LLUICtrl* ctrl) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + // *HACK all cloud scrolling is off by an additive of 10. + LLWLParamManager::getInstance()->mCurParams.setCloudScrollX(sldr_ctrl->getValueF32() + 10.0f); +} + +void LLFloaterEditSky::onCloudScrollYMoved(LLUICtrl* ctrl) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); + + // *HACK all cloud scrolling is off by an additive of 10. + LLWLParamManager::getInstance()->mCurParams.setCloudScrollY(sldr_ctrl->getValueF32() + 10.0f); +} + +void LLFloaterEditSky::onCloudScrollXToggled(LLUICtrl* ctrl) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLCheckBoxCtrl* cb_ctrl = static_cast<LLCheckBoxCtrl*>(ctrl); + + bool lock = cb_ctrl->get(); + LLWLParamManager::getInstance()->mCurParams.setEnableCloudScrollX(!lock); + + LLSliderCtrl* sldr = getChild<LLSliderCtrl>("WLCloudScrollX"); + + if (cb_ctrl->get()) + { + sldr->setEnabled(false); + } + else + { + sldr->setEnabled(true); + } + +} + +void LLFloaterEditSky::onCloudScrollYToggled(LLUICtrl* ctrl) +{ + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLCheckBoxCtrl* cb_ctrl = static_cast<LLCheckBoxCtrl*>(ctrl); + bool lock = cb_ctrl->get(); + LLWLParamManager::getInstance()->mCurParams.setEnableCloudScrollY(!lock); + + LLSliderCtrl* sldr = getChild<LLSliderCtrl>("WLCloudScrollY"); + + if (cb_ctrl->get()) + { + sldr->setEnabled(false); + } + else + { + sldr->setEnabled(true); + } +} + +//================================================================================================= + +void LLFloaterEditSky::reset() +{ + if (isNewPreset()) + { + mSkyPresetNameEditor->setValue(LLSD()); + mSaveButton->setEnabled(FALSE); // will be enabled as soon as users enters a name + } + else + { + refreshSkyPresetsList(); + + // Disable controls until a sky preset to edit is selected. + enableEditing(false); + } +} + +bool LLFloaterEditSky::isNewPreset() const +{ + return mKey.asString() == "new"; +} + +void LLFloaterEditSky::refreshSkyPresetsList() +{ + mSkyPresetCombo->removeall(); + + std::string region_name = gAgent.getRegion() ? gAgent.getRegion()->getName() : LLTrans::getString("Unknown"); + const std::map<LLWLParamKey, LLWLParamSet> &sky_params_map = LLWLParamManager::getInstance()->mParamList; + for (std::map<LLWLParamKey, LLWLParamSet>::const_iterator it = sky_params_map.begin(); it != sky_params_map.end(); it++) + { + const LLWLParamKey& key = it->first; + std::string item_title = key.name; + if (key.scope == LLEnvKey::SCOPE_REGION) + { +#if 1 // Disable editing region skies until the workflow is clear enough. + continue; +#else + item_title += " (" + region_name + ")"; +#endif + } + mSkyPresetCombo->add(item_title, key.toLLSD()); + } + + mSkyPresetCombo->setLabel(getString("combo_label")); +} + +void LLFloaterEditSky::enableEditing(bool enable) +{ + // Enable/disable the tab and their contents. + LLTabContainer* tab_container = getChild<LLTabContainer>("WindLight Tabs"); + tab_container->setEnabled(enable); + for (S32 i = 0; i < tab_container->getTabCount(); ++i) + { + tab_container->enableTabButton(i, enable); + tab_container->getPanelByIndex(i)->setCtrlsEnabled(enable); + } + + // Enable/disable saving. + mSaveButton->setEnabled(enable); + mMakeDefaultCheckBox->setEnabled(enable); +} + +void LLFloaterEditSky::saveRegionSky() +{ + LLWLParamKey key(getSelectedSkyPreset()); + llassert(key.scope == LLEnvKey::SCOPE_REGION); + + LL_DEBUGS("Windlight") << "Saving region sky preset: " << key.name << llendl; + LLWLParamManager& wl_mgr = LLWLParamManager::instance(); + wl_mgr.mCurParams.mName = key.name; + wl_mgr.setParamSet(key, wl_mgr.mCurParams); + + // *TODO: save to cached region settings. + LL_WARNS("Windlight") << "Saving region sky is not fully implemented yet" << LL_ENDL; +} + +LLWLParamKey LLFloaterEditSky::getSelectedSkyPreset() +{ + LLWLParamKey key; + + if (mSkyPresetNameEditor->getVisible()) + { + key.name = mSkyPresetNameEditor->getText(); + key.scope = LLEnvKey::SCOPE_LOCAL; + } + else + { + LLSD combo_val = mSkyPresetCombo->getValue(); + + if (!combo_val.isArray()) // manually typed text + { + key.name = combo_val.asString(); + key.scope = LLEnvKey::SCOPE_LOCAL; + } + else + { + key.fromLLSD(combo_val); + } + } + + return key; +} + +void LLFloaterEditSky::onSkyPresetNameEdited() +{ + // Disable saving a sky preset having empty name. + LLWLParamKey key = getSelectedSkyPreset(); + mSaveButton->setEnabled(!key.name.empty()); +} + +void LLFloaterEditSky::onSkyPresetSelected() +{ + LLWLParamKey key = getSelectedSkyPreset(); + LLWLParamSet sky_params; + + if (!LLWLParamManager::instance().getParamSet(key, sky_params)) + { + // Manually entered string? + LL_WARNS("Windlight") << "No sky preset named " << key.toString() << LL_ENDL; + return; + } + + LLEnvManagerNew::instance().useSkyParams(sky_params.getAll()); + //syncControls(); + + bool can_edit = (key.scope == LLEnvKey::SCOPE_LOCAL || LLEnvManagerNew::canEditRegionSettings()); + enableEditing(can_edit); + + mMakeDefaultCheckBox->setEnabled(key.scope == LLEnvKey::SCOPE_LOCAL); +} + +bool LLFloaterEditSky::onSaveAnswer(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + // If they choose save, do it. Otherwise, don't do anything + if (option == 0) + { + onSaveConfirmed(); + } + + return false; +} + +void LLFloaterEditSky::onSaveConfirmed() +{ + // Save current params to the selected preset. + LLWLParamKey key(getSelectedSkyPreset()); + + LL_DEBUGS("Windlight") << "Saving sky preset " << key.name << LL_ENDL; + LLWLParamManager& wl_mgr = LLWLParamManager::instance(); + if (wl_mgr.hasParamSet(key)) + { + wl_mgr.setParamSet(key, wl_mgr.mCurParams); + } + else + { + wl_mgr.addParamSet(key, wl_mgr.mCurParams); + } + + wl_mgr.savePreset(key); + + // Change preference if requested. + if (mMakeDefaultCheckBox->getValue()) + { + LL_DEBUGS("Windlight") << key.name << " is now the new preferred sky preset" << llendl; + LLEnvManagerNew::instance().setUseSkyPreset(key.name); + } + + closeFloater(); +} + +void LLFloaterEditSky::onBtnSave() +{ + LLWLParamKey selected_sky = getSelectedSkyPreset(); + LLWLParamManager& wl_mgr = LLWLParamManager::instance(); + + if (selected_sky.scope == LLEnvKey::SCOPE_REGION) + { + saveRegionSky(); + closeFloater(); + return; + } + + std::string name = selected_sky.name; + if (name.empty()) + { + // *TODO: show an alert + llwarns << "Empty sky preset name" << llendl; + return; + } + + // Don't allow overwriting system presets. + if (wl_mgr.isSystemPreset(name)) + { + LLNotificationsUtil::add("WLNoEditDefault"); + return; + } + + // Save, ask for confirmation for overwriting an existing preset. + if (wl_mgr.hasParamSet(selected_sky)) + { + LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterEditSky::onSaveAnswer, this, _1, _2)); + } + else + { + // new preset, hence no confirmation needed + onSaveConfirmed(); + } } void LLFloaterEditSky::onBtnCancel() { closeFloater(); } + +void LLFloaterEditSky::onSkyPresetListChange() +{ + LLWLParamKey key = getSelectedSkyPreset(); // preset being edited + if (!LLWLParamManager::instance().hasParamSet(key)) + { + // Preset we've been editing doesn't exist anymore. Close the floater. + closeFloater(false); + } + else + { + // A new preset has been added. + // Refresh the presets list, though it may not make sense as the floater is about to be closed. + refreshSkyPresetsList(); + } +} + +void LLFloaterEditSky::onRegionSettingsChange() +{ + // If creating a new sky, don't bother. + if (isNewPreset()) + { + return; + } + + if (getSelectedSkyPreset().scope == LLEnvKey::SCOPE_REGION) // if editing a region sky + { + // reset the floater to its initial state + reset(); + + // *TODO: Notify user? + } + else // editing a local sky + { + refreshSkyPresetsList(); + } +} + +void LLFloaterEditSky::onRegionInfoUpdate() +{ + bool can_edit = true; + + // If we've selected the region day cycle for editing. + if (getSelectedSkyPreset().scope == LLEnvKey::SCOPE_REGION) + { + // check whether we have the access + can_edit = LLEnvManagerNew::canEditRegionSettings(); + } + + enableEditing(can_edit); +} diff --git a/indra/newview/llfloatereditsky.h b/indra/newview/llfloatereditsky.h index a78f049d84..0ad4217a43 100644 --- a/indra/newview/llfloatereditsky.h +++ b/indra/newview/llfloatereditsky.h @@ -28,7 +28,16 @@ #define LL_LLFLOATEREDITSKY_H #include "llfloater.h" +#include "llwlparammanager.h" +class LLButton; +class LLCheckBoxCtrl; +class LLComboBox; +class LLLineEditor; + +/** + * Floater for creating or editing a sky preset. + */ class LLFloaterEditSky : public LLFloater { LOG_CLASS(LLFloaterEditSky); @@ -38,8 +47,64 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void onClose(bool app_quitting); + /*virtual*/ void draw(); + +private: + void initCallbacks(void); + + //-- WL stuff begins ------------------------------------------------------ + + void syncControls(); /// sync up sliders with parameters + + // general purpose callbacks for dealing with color controllers + void onColorControlRMoved(LLUICtrl* ctrl, void* userdata); + void onColorControlGMoved(LLUICtrl* ctrl, void* userdata); + void onColorControlBMoved(LLUICtrl* ctrl, void* userdata); + void onColorControlIMoved(LLUICtrl* ctrl, void* userdata); + void onFloatControlMoved(LLUICtrl* ctrl, void* userdata); + + // lighting callbacks for glow + void onGlowRMoved(LLUICtrl* ctrl, void* userdata); + void onGlowBMoved(LLUICtrl* ctrl, void* userdata); + + // lighting callbacks for sun + void onSunMoved(LLUICtrl* ctrl, void* userdata); + // for handling when the star slider is moved to adjust the alpha + void onStarAlphaMoved(LLUICtrl* ctrl); + + // handle cloud scrolling + void onCloudScrollXMoved(LLUICtrl* ctrl); + void onCloudScrollYMoved(LLUICtrl* ctrl); + void onCloudScrollXToggled(LLUICtrl* ctrl); + void onCloudScrollYToggled(LLUICtrl* ctrl); + + //-- WL stuff ends -------------------------------------------------------- + + void reset(); /// reset the floater to its initial state + bool isNewPreset() const; + void refreshSkyPresetsList(); + void enableEditing(bool enable); + void saveRegionSky(); + LLWLParamKey getSelectedSkyPreset(); + + void onSkyPresetNameEdited(); + void onSkyPresetSelected(); + bool onSaveAnswer(const LLSD& notification, const LLSD& response); + void onSaveConfirmed(); + + void onBtnSave(); void onBtnCancel(); + + void onSkyPresetListChange(); + void onRegionSettingsChange(); + void onRegionInfoUpdate(); + + LLLineEditor* mSkyPresetNameEditor; + LLComboBox* mSkyPresetCombo; + LLCheckBoxCtrl* mMakeDefaultCheckBox; + LLButton* mSaveButton; }; #endif // LL_LLFLOATEREDITSKY_H diff --git a/indra/newview/llfloaterenvironmentsettings.cpp b/indra/newview/llfloaterenvironmentsettings.cpp index 15dba80b61..0ec6d1c6c8 100644 --- a/indra/newview/llfloaterenvironmentsettings.cpp +++ b/indra/newview/llfloaterenvironmentsettings.cpp @@ -76,7 +76,8 @@ BOOL LLFloaterEnvironmentSettings::postBuild() setCloseCallback(boost::bind(&LLFloaterEnvironmentSettings::cancel, this)); - LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterEnvironmentSettings::onDayCycleListChange, this)); + LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterEnvironmentSettings::populateDayCyclePresetsList, this)); + LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEnvironmentSettings::populateSkyPresetsList, this)); return TRUE; } @@ -164,11 +165,6 @@ void LLFloaterEnvironmentSettings::onSelectDayCyclePreset() mDirty = true; } -void LLFloaterEnvironmentSettings::onDayCycleListChange() -{ - populateDayCyclePresetsList(); -} - void LLFloaterEnvironmentSettings::onBtnOK() { mDirty = false; diff --git a/indra/newview/llfloaterenvironmentsettings.h b/indra/newview/llfloaterenvironmentsettings.h index 6d29a5d4d5..0953ab4a65 100644 --- a/indra/newview/llfloaterenvironmentsettings.h +++ b/indra/newview/llfloaterenvironmentsettings.h @@ -50,8 +50,6 @@ private: void onSelectSkyPreset(); void onSelectDayCyclePreset(); - void onDayCycleListChange(); - void onBtnOK(); void onBtnCancel(); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index ab164e7db0..567183b955 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -3300,7 +3300,8 @@ BOOL LLPanelEnvironmentInfo::postBuild() LLEnvManagerNew::instance().setRegionSettingsChangeCallback(boost::bind(&LLPanelEnvironmentInfo::onRegionSettingschange, this)); LLEnvManagerNew::instance().setRegionSettingsAppliedCallback(boost::bind(&LLPanelEnvironmentInfo::onRegionSettingsApplied, this, _1)); - LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLPanelEnvironmentInfo::onDayCycleListChange, this)); + LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLPanelEnvironmentInfo::populateDayCyclesList, this)); + LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLPanelEnvironmentInfo::populateSkyPresetsList, this)); return TRUE; } @@ -3756,8 +3757,3 @@ void LLPanelEnvironmentInfo::onRegionSettingsApplied(bool ok) LLEnvManagerNew::instance().requestRegionSettings(); } } - -void LLPanelEnvironmentInfo::onDayCycleListChange() -{ - populateDayCyclesList(); -} diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 4f5222eb34..6075842e76 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -471,8 +471,6 @@ private: void onRegionSettingschange(); void onRegionSettingsApplied(bool ok); - void onDayCycleListChange(); - bool mEnableEditing; LLRadioGroup* mRegionSettingsRadioGroup; diff --git a/indra/newview/llfloaterwindlight.cpp b/indra/newview/llfloaterwindlight.cpp index 16cb0f5e57..f78fada155 100644 --- a/indra/newview/llfloaterwindlight.cpp +++ b/indra/newview/llfloaterwindlight.cpp @@ -57,6 +57,8 @@ #undef max +// *TODO: Remove this class in favor of LLFloaterEditSky + LLFloaterWindLight* LLFloaterWindLight::sWindLight = NULL; std::set<LLWLParamKey> LLFloaterWindLight::sDefaultPresets; LLEnvKey::EScope LLFloaterWindLight::sScope; diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp index 80001525f8..e646b605a9 100644 --- a/indra/newview/llwldaycycle.cpp +++ b/indra/newview/llwldaycycle.cpp @@ -270,10 +270,10 @@ bool LLWLDayCycle::removeKeyframe(F32 time) return false; } -bool LLWLDayCycle::getKeytime(LLWLParamKey frame, F32& key_time) +bool LLWLDayCycle::getKeytime(LLWLParamKey frame, F32& key_time) const { // scroll through till we find the correct value in the map - std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.begin(); + std::map<F32, LLWLParamKey>::const_iterator mIt = mTimeMap.begin(); for(; mIt != mTimeMap.end(); ++mIt) { if(frame == mIt->second) @@ -315,6 +315,12 @@ bool LLWLDayCycle::getKeyedParamName(F32 time, std::string & name) return false; } +bool LLWLDayCycle::hasReferencesTo(const LLWLParamKey& keyframe) const +{ + F32 dummy; + return getKeytime(keyframe, dummy); +} + void LLWLDayCycle::removeReferencesTo(const LLWLParamKey& keyframe) { lldebugs << "Removing references to key frame " << keyframe.toLLSD() << llendl; diff --git a/indra/newview/llwldaycycle.h b/indra/newview/llwldaycycle.h index 9dbfad294a..c8585564ed 100644 --- a/indra/newview/llwldaycycle.h +++ b/indra/newview/llwldaycycle.h @@ -106,7 +106,7 @@ public: /// get the first key time for a parameter /// returns false if not there - bool getKeytime(LLWLParamKey keyFrame, F32& keyTime); + bool getKeytime(LLWLParamKey keyFrame, F32& keyTime) const; /// get the param set at a given time /// returns true if found one @@ -116,6 +116,9 @@ public: /// returns true if it found one bool getKeyedParamName(F32 time, std::string & name); + /// @return true if there are references to the given sky + bool hasReferencesTo(const LLWLParamKey& keyframe) const; + /// removes all references to the sky (paramkey) /// does nothing if the sky doesn't exist in the day void removeReferencesTo(const LLWLParamKey& keyframe); diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index 5980410e64..df52f3328f 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -265,167 +265,74 @@ void LLWLParamManager::refreshRegionPresets() addAllSkies(LLEnvKey::SCOPE_REGION, LLEnvManagerNew::instance().getRegionSettings().getSkyMap()); } -void LLWLParamManager::loadPresets(const std::string& file_name) +void LLWLParamManager::loadAllPresets() { - std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", "")); - LL_INFOS2("AppInit", "Shaders") << "Loading Default WindLight settings from " << path_name << LL_ENDL; - - bool found = true; - LLDirIterator app_settings_iter(path_name, "*.xml"); - while(found) - { - std::string name; - found = app_settings_iter.next(name); - if(found) - { - name=name.erase(name.length()-4); - - // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_unescape(name.c_str(), name.size()); - std::string unescaped_name(curl_str); - curl_free(curl_str); - curl_str = NULL; + // First, load system (coming out of the box) sky presets. + loadPresetsFromDir(getSysDir()); - LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL; - loadPreset(LLWLParamKey(unescaped_name, LLWLParamKey::SCOPE_LOCAL),FALSE); - } - } + // Then load user presets. Note that user day presets will modify any system ones already loaded. + loadPresetsFromDir(getUserDir()); +} - // And repeat for user presets, note the user presets will modify any system presets already loaded +void LLWLParamManager::loadPresetsFromDir(const std::string& dir) +{ + LL_INFOS2("AppInit", "Shaders") << "Loading sky presets from " << dir << LL_ENDL; - std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", "")); - LL_INFOS2("AppInit", "Shaders") << "Loading User WindLight settings from " << path_name2 << LL_ENDL; - - found = true; - LLDirIterator user_settings_iter(path_name2, "*.xml"); - while(found) + LLDirIterator dir_iter(dir, "*.xml"); + while (1) { - std::string name; - found = user_settings_iter.next(name); - if(found) + std::string file; + if (!dir_iter.next(file)) { - name=name.erase(name.length()-4); - - // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_unescape(name.c_str(), name.size()); - std::string unescaped_name(curl_str); - curl_free(curl_str); - curl_str = NULL; + break; // no more files + } - LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL; - loadPreset(LLWLParamKey(unescaped_name,LLWLParamKey::SCOPE_LOCAL),FALSE); + std::string path = dir + file; + if (!loadPreset(path)) + { + llwarns << "Error loading sky preset from " << path << llendl; } } - } -// untested and unmaintained! sanity-check me before using -/* -void LLWLParamManager::savePresets(const std::string & fileName) +bool LLWLParamManager::loadPreset(const std::string& path) { - //Nobody currently calls me, but if they did, then its reasonable to write the data out to the user's folder - //and not over the RO system wide version. + llifstream xml_file; + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true)); - LLSD paramsData(LLSD::emptyMap()); - - std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", fileName)); - - for(std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.begin(); - mIt != mParamList.end(); - ++mIt) + xml_file.open(path.c_str()); + if (!xml_file) { - paramsData[mIt->first.name] = mIt->second.getAll(); + return false; } - llofstream presetsXML(pathName); - - LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter(); - - formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY); + LL_DEBUGS2("AppInit", "Shaders") << "Loading sky " << name << LL_ENDL; - presetsXML.close(); -} -*/ + LLSD params_data; + LLPointer<LLSDParser> parser = new LLSDXMLParser(); + parser->parse(xml_file, params_data, LLSDSerialize::SIZE_UNLIMITED); + xml_file.close(); -void LLWLParamManager::loadPreset(const LLWLParamKey key, bool propagate) -{ - if(mParamList.find(key) == mParamList.end()) // key does not already exist in mapping + LLWLParamKey key(name, LLEnvKey::SCOPE_LOCAL); + if (hasParamSet(key)) { - if(key.scope == LLWLParamKey::SCOPE_LOCAL) // local scope, so try to load from file - { - // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_escape(key.name.c_str(), key.name.size()); - std::string escaped_filename(curl_str); - curl_free(curl_str); - curl_str = NULL; - - escaped_filename += ".xml"; - - std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename)); - llinfos << "Loading WindLight sky setting from " << pathName << llendl; - - llifstream presetsXML; - presetsXML.open(pathName.c_str()); - - // That failed, try loading from the users area instead. - if(!presetsXML) - { - pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", escaped_filename); - llinfos << "Loading User WindLight sky setting from " << pathName << llendl; - presetsXML.open(pathName.c_str()); - } - - if (presetsXML) - { - loadPresetFromXML(key, presetsXML); - presetsXML.close(); - } - else - { - llwarns << "Could not load local WindLight sky setting " << key.toString() << llendl; - return; - } - } - else - { - llwarns << "Attempted to load non-local WindLight sky settings " << key.toString() << "; not found in parameter mapping." << llendl; - return; - } + setParamSet(key, params_data); } - - if(propagate) + else { - getParamSet(key, mCurParams); - propagateParameters(); + addParamSet(key, params_data); } -} - -void LLWLParamManager::loadPresetFromXML(LLWLParamKey key, std::istream & presetsXML) -{ - LLSD paramsData(LLSD::emptyMap()); - LLPointer<LLSDParser> parser = new LLSDXMLParser(); - - parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED); - - std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.find(key); - if(mIt == mParamList.end()) addParamSet(key, paramsData); - else setParamSet(key, paramsData); + return true; } void LLWLParamManager::savePreset(LLWLParamKey key) { - // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_escape(key.name.c_str(), key.name.size()); - std::string escaped_filename(curl_str); - curl_free(curl_str); - curl_str = NULL; - - escaped_filename += ".xml"; + llassert(key.scope == LLEnvKey::SCOPE_LOCAL && !key.name.empty()); // make an empty llsd LLSD paramsData(LLSD::emptyMap()); - std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", escaped_filename)); + std::string pathName(getUserDir() + escapeString(key.name) + ".xml"); // fill it with LLSD windlight params paramsData = mParamList[key].getAll(); @@ -681,6 +588,7 @@ bool LLWLParamManager::addParamSet(const LLWLParamKey& key, LLWLParamSet& param) llassert(!key.name.empty()); // *TODO: validate params mParamList[key] = param; + mPresetListChangeSignal(); return true; } @@ -689,19 +597,9 @@ bool LLWLParamManager::addParamSet(const LLWLParamKey& key, LLWLParamSet& param) BOOL LLWLParamManager::addParamSet(const LLWLParamKey& key, LLSD const & param) { - // add a new one if not one there already - std::map<LLWLParamKey, LLWLParamSet>::const_iterator finder = mParamList.find(key); - if(finder == mParamList.end()) - { - llassert(!key.name.empty()); - // *TODO: validate params - mParamList[key].setAll(param); - return TRUE; - } - else - { - return FALSE; - } + LLWLParamSet param_set; + param_set.setAll(param); + return addParamSet(key, param_set); } bool LLWLParamManager::getParamSet(const LLWLParamKey& key, LLWLParamSet& param) @@ -718,6 +616,12 @@ bool LLWLParamManager::getParamSet(const LLWLParamKey& key, LLWLParamSet& param) return false; } +bool LLWLParamManager::hasParamSet(const LLWLParamKey& key) +{ + LLWLParamSet dummy; + return getParamSet(key, dummy); +} + bool LLWLParamManager::setParamSet(const LLWLParamKey& key, LLWLParamSet& param) { llassert(!key.name.empty()); @@ -739,50 +643,66 @@ bool LLWLParamManager::setParamSet(const LLWLParamKey& key, const LLSD & param) return false; } - mParamList[key].setAll(param); - - return true; + LLWLParamSet param_set; + param_set.setAll(param); + return setParamSet(key, param_set); } void LLWLParamManager::removeParamSet(const LLWLParamKey& key, bool delete_from_disk) { - // remove from param list - std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.find(key); - if(mIt != mParamList.end()) + // *NOTE: Removing a sky preset invalidates day cycles that refer to it. + + if (key.scope == LLEnvKey::SCOPE_REGION) { - mParamList.erase(mIt); + llwarns << "Removing region skies not supported" << llendl; + llassert(key.scope == LLEnvKey::SCOPE_LOCAL); + return; } - else + + // remove from param list + std::map<LLWLParamKey, LLWLParamSet>::iterator it = mParamList.find(key); + if (it == mParamList.end()) { - LL_WARNS("WindLight") << "Unable to delete key " << key.toString() << "; not found." << LL_ENDL; + LL_WARNS("WindLight") << "No sky preset named " << key.name << LL_ENDL; + return; } + mParamList.erase(it); mDay.removeReferencesTo(key); - if(delete_from_disk && key.scope == LLWLParamKey::SCOPE_LOCAL) + // remove from file system if requested + if (delete_from_disk) { - std::string path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", "")); - - // use full curl escaped name - char * curl_str = curl_escape(key.name.c_str(), key.name.size()); - std::string escaped_name(curl_str); - curl_free(curl_str); - curl_str = NULL; - + std::string path_name(getUserDir()); + std::string escaped_name = escapeString(key.name); + if(gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml") < 1) { - LL_WARNS("WindLight") << "Unable to delete key " << key.toString() << " from disk; not found." << LL_ENDL; + LL_WARNS("WindLight") << "Error removing sky preset " << key.name << " from disk" << LL_ENDL; } } + + // signal interested parties + mPresetListChangeSignal(); +} + +bool LLWLParamManager::isSystemPreset(const std::string& preset_name) +{ + // *TODO: file system access is excessive here. + return gDirUtilp->fileExists(getSysDir() + escapeString(preset_name) + ".xml"); } +boost::signals2::connection LLWLParamManager::setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb) +{ + return mPresetListChangeSignal.connect(cb); +} // virtual static void LLWLParamManager::initSingleton() { LL_DEBUGS("Windlight") << "Initializing sky" << LL_ENDL; - loadPresets(LLStringUtil::null); + loadAllPresets(); // load the day std::string preferred_day = LLEnvManagerNew::instance().getDayCycleName(); @@ -813,3 +733,27 @@ void LLWLParamManager::initSingleton() applyUserPrefs(false); } + +// static +std::string LLWLParamManager::getSysDir() +{ + return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""); +} + +// static +std::string LLWLParamManager::getUserDir() +{ + return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS , "windlight/skies", ""); +} + +// static +std::string LLWLParamManager::escapeString(const std::string& str) +{ + // Don't use LLURI::escape() because it doesn't encode '-' characters + // which may break handling of some system presets like "A-12AM". + char* curl_str = curl_escape(str.c_str(), str.size()); + std::string escaped_str(curl_str); + curl_free(curl_str); + + return escaped_str; +} diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h index 30fc8cd68f..73bf97f392 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -215,20 +215,9 @@ public: class LLWLParamManager : public LLSingleton<LLWLParamManager> { LOG_CLASS(LLWLParamManager); -public: - /// load a preset file - void loadPresets(const std::string & fileName); - - /// save the preset file - // the implementation of this method was unmaintained and is commented out - // *NOTE test and sanity-check before uncommenting and using! - void savePresets(const std::string & fileName); - /// load an individual preset into the sky - void loadPreset(const LLWLParamKey key, bool propogate=true); - - /// load an individual preset from a stream of XML - void loadPresetFromXML(const LLWLParamKey key, std::istream & presetXML); +public: + typedef boost::signals2::signal<void()> preset_list_signal_t; /// save the parameter presets to file void savePreset(const LLWLParamKey key); @@ -281,12 +270,15 @@ public: /// get a param set (preset) from the list bool getParamSet(const LLWLParamKey& key, LLWLParamSet& param); + /// get a param set (preset) from the list + bool hasParamSet(const LLWLParamKey& key); + /// set the param in the list with a new param bool setParamSet(const LLWLParamKey& key, LLWLParamSet& param); /// set the param in the list with a new param bool setParamSet(const LLWLParamKey& key, LLSD const & param); - + /// gets rid of a parameter and any references to it /// ignores "delete_from_disk" if the scope is not local void removeParamSet(const LLWLParamKey& key, bool delete_from_disk); @@ -294,6 +286,12 @@ public: /// clear parameter mapping of a given scope void clearParamSetsOfScope(LLEnvKey::EScope scope); + /// @return true if the preset comes out of the box + bool isSystemPreset(const std::string& preset_name); + + /// Emitted when a preset gets added or deleted. + boost::signals2::connection setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb); + /// add all skies in LLSD using the given scope void addAllSkies(LLEnvKey::EScope scope, const LLSD& preset_map); @@ -307,6 +305,9 @@ public: // returns all skies in map (intended to be called with output from a finalize) static LLSD createSkyMap(std::map<LLWLParamKey, LLWLParamSet> map); + /// escape string in a way different from LLURI::escape() + static std::string escapeString(const std::string& str); + // helper variables LLWLAnimator mAnimator; @@ -362,10 +363,20 @@ public: std::map<LLWLParamKey, LLWLParamSet> mParamList; private: + + void loadAllPresets(); + void loadPresetsFromDir(const std::string& dir); + bool loadPreset(const std::string& path); + + static std::string getSysDir(); + static std::string getUserDir(); + friend class LLSingleton<LLWLParamManager>; /*virtual*/ void initSingleton(); LLWLParamManager(); ~LLWLParamManager(); + + preset_list_signal_t mPresetListChangeSignal; }; inline F32 LLWLParamManager::getDomeOffset(void) const diff --git a/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml index 82a541d40d..b5de4166f6 100644 --- a/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml +++ b/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml @@ -17,7 +17,10 @@ <string name="label_sky">Preset:</string> <string name="label_day_cycle">Day cycle:</string> - <string name="msg_confirm_deletion">Are you sure you want to delete the selected preset?</string> + <string name="msg_confirm_deletion">Are you sure you want to delete the selected preset?</string> + <string name="msg_sky_is_referenced">Cannot remove a preset that is referenced by some day cycle(s).</string> + + <string name="combo_label">-Select a preset-</string> <text follows="top|left|right" @@ -36,12 +39,7 @@ left_pad="10" name="preset_combo" top_delta="-5" - width="200"> - <combo_box.item - label="-Select a preset-" - name="item0" - value="any" /> - </combo_box> + width="200"/> <button follows="bottom|right" height="23" diff --git a/indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml index b93406053c..2c78d51c9f 100644 --- a/indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml +++ b/indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml @@ -39,6 +39,7 @@ follows="top|left" layout="topleft" left_pad="10" + max_chars="100" name="day_cycle_combo" top_delta="-5" width="200" /> diff --git a/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml index 6ffb3480ad..64fbaf6b99 100644 --- a/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml +++ b/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml @@ -13,6 +13,7 @@ <string name="title_edit">Edit Sky Preset</string> <string name="hint_new">Name your preset, adjust the controls to create it, and click "Save".</string> <string name="hint_edit">To edit your sky preset, adjust the controls and click "Save".</string> + <string name="combo_label">-Select a preset-</string> <text follows="top|left|right" @@ -40,14 +41,16 @@ follows="top|left" layout="topleft" left_pad="10" + max_chars="100" name="sky_preset_combo" top_delta="-5" - width="200"> - <combo_box.item - label="-Select a preset-" - name="item0" - value="any" /> - </combo_box> + width="200"/> + <line_editor + height="20" + left_delta="0" + name="sky_preset_name" + top_delta="0" + width="200" /> <text follows="top|left|right" height="40" @@ -61,7 +64,6 @@ </text> <!--======== Controls panel ========--> <view_border - border="true" bevel_style="none" follows="top|left" height="225" @@ -1003,7 +1005,7 @@ label="Make this preset my new sky setting" layout="topleft" left="430" - name="new_water_preset_chb" + name="make_default_cb" top_pad="30" width="280"/> <button diff --git a/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml index f107e67f74..77484bcfea 100644 --- a/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml +++ b/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml @@ -42,6 +42,7 @@ follows="top|left" layout="topleft" left_pad="10" + max_chars="100" name="water_preset_combo" top_delta="-5" width="200"> |