diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/llfloaterdeleteenvpreset.cpp | 37 | ||||
-rw-r--r-- | indra/newview/llfloaterdeleteenvpreset.h | 2 | ||||
-rw-r--r-- | indra/newview/llfloatereditsky.cpp | 843 | ||||
-rw-r--r-- | indra/newview/llfloatereditsky.h | 60 | ||||
-rw-r--r-- | indra/newview/llfloaterwindlight.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llwlparammanager.cpp | 230 | ||||
-rw-r--r-- | indra/newview/llwlparammanager.h | 32 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml | 17 |
8 files changed, 1045 insertions, 178 deletions
diff --git a/indra/newview/llfloaterdeleteenvpreset.cpp b/indra/newview/llfloaterdeleteenvpreset.cpp index d791c29a96..74c837af53 100644 --- a/indra/newview/llfloaterdeleteenvpreset.cpp +++ b/indra/newview/llfloaterdeleteenvpreset.cpp @@ -89,7 +89,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 +103,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 +113,20 @@ void LLFloaterDeleteEnvPreset::onBtnDelete() } else if (param == "sky") { - llwarns << "Deleting sky presets not implemented" << llendl; - 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)) @@ -167,16 +174,22 @@ void LLFloaterDeleteEnvPreset::populateSkyPresetsList() { 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; + if (key.scope == LLEnvKey::SCOPE_REGION) continue; // list only local presets + bool enabled = key.name != cur_preset && !sky_mgr.isSystemPreset(key.name); + mPresetCombo->add(key.name, ADD_BOTTOM, enabled); } } @@ -197,6 +210,12 @@ void LLFloaterDeleteEnvPreset::onDeleteDayCycleConfirmation() LLDayCycleManager::instance().deletePreset(mPresetCombo->getValue().asString()); } +void LLFloaterDeleteEnvPreset::onDeleteSkyPresetConfirmation() +{ + LLWLParamKey key(mPresetCombo->getValue().asString(), LLEnvKey::SCOPE_LOCAL); + LLWLParamManager::instance().removeParamSet(key, true); +} + void LLFloaterDeleteEnvPreset::onDayCycleListChange() { populateDayCyclesList(); diff --git a/indra/newview/llfloaterdeleteenvpreset.h b/indra/newview/llfloaterdeleteenvpreset.h index aaa4143233..26e3b0728e 100644 --- a/indra/newview/llfloaterdeleteenvpreset.h +++ b/indra/newview/llfloaterdeleteenvpreset.h @@ -50,6 +50,8 @@ private: void populateDayCyclesList(); void onDeleteDayCycleConfirmation(); + void onDeleteSkyPresetConfirmation(); + void onDayCycleListChange(); LLComboBox* mPresetCombo; diff --git a/indra/newview/llfloatereditsky.cpp b/indra/newview/llfloatereditsky.cpp index 312479951e..96dfb7a8a9 100644 --- a/indra/newview/llfloatereditsky.cpp +++ b/indra/newview/llfloatereditsky.cpp @@ -30,22 +30,41 @@ // 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 "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 +72,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 +84,823 @@ 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); + + 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); + } +} + +// 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)); + + //------------------------------------------------------------------------- + + 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); + } +} + +//================================================================================================= + +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) + { + item_title += " (" + region_name + ")"; + } + 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)) + { + llwarns << "No sky preset named " << key.toString() << llendl; + llassert(false); + 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); +} + +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(); } + +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(); +} diff --git a/indra/newview/llfloatereditsky.h b/indra/newview/llfloatereditsky.h index a78f049d84..9a8feb5188 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,59 @@ 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 ------------------------------------------------------ + + // 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); + + void syncControls(); /// sync up sliders with parameters + + //-- WL stuff ends -------------------------------------------------------- + + 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(); + + LLLineEditor* mSkyPresetNameEditor; + LLComboBox* mSkyPresetCombo; + LLCheckBoxCtrl* mMakeDefaultCheckBox; + LLButton* mSaveButton; }; #endif // LL_LLFLOATEREDITSKY_H 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/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index 5980410e64..01aed7c0f1 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); + // First, load system (coming out of the box) sky presets. + loadPresetsFromDir(getSysDir()); - // 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; - - 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. - - LLSD paramsData(LLSD::emptyMap()); - - std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", fileName)); + llifstream xml_file; + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true)); - 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(); @@ -718,6 +625,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()); @@ -746,6 +659,15 @@ bool LLWLParamManager::setParamSet(const LLWLParamKey& key, const LLSD & param) void LLWLParamManager::removeParamSet(const LLWLParamKey& key, bool delete_from_disk) { + // *TODO: notify interested parties that a sky preset has been removed. + + if (key.scope == LLEnvKey::SCOPE_REGION) + { + llwarns << "Removing region skies not supported" << llendl; + llassert(key.scope == LLEnvKey::SCOPE_LOCAL); + return; + } + // remove from param list std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.find(key); if(mIt != mParamList.end()) @@ -759,30 +681,30 @@ void LLWLParamManager::removeParamSet(const LLWLParamKey& key, bool delete_from_ mDay.removeReferencesTo(key); - if(delete_from_disk && key.scope == LLWLParamKey::SCOPE_LOCAL) + 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; } } } +bool LLWLParamManager::isSystemPreset(const std::string& preset_name) +{ + // *TODO: file system access is excessive here. + return gDirUtilp->fileExists(getSysDir() + escapeString(preset_name) + ".xml"); +} // 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 +735,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..06f56851b6 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -216,19 +216,6 @@ 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); /// save the parameter presets to file void savePreset(const LLWLParamKey key); @@ -281,12 +268,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 +284,9 @@ 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); + /// add all skies in LLSD using the given scope void addAllSkies(LLEnvKey::EScope scope, const LLSD& preset_map); @@ -307,6 +300,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,6 +358,14 @@ 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(); 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..fa51059d44 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" @@ -42,12 +43,13 @@ left_pad="10" 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 +63,6 @@ </text> <!--======== Controls panel ========--> <view_border - border="true" bevel_style="none" follows="top|left" height="225" @@ -1003,7 +1004,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 |