/** * @file llfloaterwater.cpp * @brief LLFloaterWater class definition * * $LicenseInfo:firstyear=2007&license=viewergpl$ * * Copyright (c) 2007-2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at * http://secondlifegrid.net/programs/open_source/licensing/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, * and agree to abide by those obligations. * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" #include "llfloaterwater.h" #include "pipeline.h" #include "llsky.h" #include "llsliderctrl.h" #include "llspinctrl.h" #include "llcolorswatch.h" #include "llcheckboxctrl.h" #include "lltexturectrl.h" #include "lluictrlfactory.h" #include "llviewercamera.h" #include "llcombobox.h" #include "lllineeditor.h" #include "llfloaterdaycycle.h" #include "llboost.h" #include "llmultisliderctrl.h" #include "llagent.h" #include "llinventorymodel.h" #include "llviewerinventory.h" #include "v4math.h" #include "llviewerdisplay.h" #include "llviewercontrol.h" #include "llviewerwindow.h" #include "llsavedsettingsglue.h" #include "llwaterparamset.h" #include "llwaterparammanager.h" #include "llpostprocess.h" #include "wlfloaterwindlightsend.h" #undef max LLFloaterWater* LLFloaterWater::sWaterMenu = NULL; std::set LLFloaterWater::sDefaultPresets; LLFloaterWater::LLFloaterWater() : LLFloater(std::string("water floater")) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_water.xml"); // add the combo boxes LLComboBox* comboBox = getChild("WaterPresetsCombo"); if(comboBox != NULL) { std::map::iterator mIt = LLWaterParamManager::instance()->mParamList.begin(); for(; mIt != LLWaterParamManager::instance()->mParamList.end(); mIt++) { comboBox->add(mIt->first); } // set defaults on combo boxes comboBox->selectByValue(LLSD("Default")); } std::string def_water = getString("WLDefaultWaterNames"); // no editing or deleting of the blank string sDefaultPresets.insert(""); boost_tokenizer tokens(def_water, boost::char_separator(":")); for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) { std::string tok(*token_iter); sDefaultPresets.insert(tok); } // load it up initCallbacks(); } LLFloaterWater::~LLFloaterWater() { } void LLFloaterWater::initCallbacks(void) { // help buttons initHelpBtn("WaterFogColorHelp", "HelpWaterFogColor"); initHelpBtn("WaterFogDensityHelp", "HelpWaterFogDensity"); initHelpBtn("WaterUnderWaterFogModHelp", "HelpUnderWaterFogMod"); initHelpBtn("WaterGlowHelp", "HelpWaterGlow"); initHelpBtn("WaterNormalScaleHelp", "HelpWaterNormalScale"); initHelpBtn("WaterFresnelScaleHelp", "HelpWaterFresnelScale"); initHelpBtn("WaterFresnelOffsetHelp", "HelpWaterFresnelOffset"); initHelpBtn("WaterBlurMultiplierHelp", "HelpWaterBlurMultiplier"); initHelpBtn("WaterScaleBelowHelp", "HelpWaterScaleBelow"); initHelpBtn("WaterScaleAboveHelp", "HelpWaterScaleAbove"); initHelpBtn("WaterNormalMapHelp", "HelpWaterNormalMap"); initHelpBtn("WaterWave1Help", "HelpWaterWave1"); initHelpBtn("WaterWave2Help", "HelpWaterWave2"); LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); childSetCommitCallback("WaterFogColor", onWaterFogColorMoved, ¶m_mgr->mFogColor); // childSetCommitCallback("WaterGlow", onColorControlAMoved, ¶m_mgr->mFogColor); // fog density childSetCommitCallback("WaterFogDensity", onExpFloatControlMoved, ¶m_mgr->mFogDensity); childSetCommitCallback("WaterUnderWaterFogMod", onFloatControlMoved, ¶m_mgr->mUnderWaterFogMod); // blue density childSetCommitCallback("WaterNormalScaleX", onVector3ControlXMoved, ¶m_mgr->mNormalScale); childSetCommitCallback("WaterNormalScaleY", onVector3ControlYMoved, ¶m_mgr->mNormalScale); childSetCommitCallback("WaterNormalScaleZ", onVector3ControlZMoved, ¶m_mgr->mNormalScale); // fresnel childSetCommitCallback("WaterFresnelScale", onFloatControlMoved, ¶m_mgr->mFresnelScale); childSetCommitCallback("WaterFresnelOffset", onFloatControlMoved, ¶m_mgr->mFresnelOffset); // scale above/below childSetCommitCallback("WaterScaleAbove", onFloatControlMoved, ¶m_mgr->mScaleAbove); childSetCommitCallback("WaterScaleBelow", onFloatControlMoved, ¶m_mgr->mScaleBelow); // blur mult childSetCommitCallback("WaterBlurMult", onFloatControlMoved, ¶m_mgr->mBlurMultiplier); // Load/save LLComboBox* comboBox = getChild("WaterPresetsCombo"); //childSetAction("WaterLoadPreset", onLoadPreset, comboBox); childSetAction("WaterNewPreset", onNewPreset, comboBox); childSetAction("WaterDeletePreset", onDeletePreset, comboBox); childSetCommitCallback("WaterSavePreset", onSavePreset, this); // wave direction childSetCommitCallback("WaterWave1DirX", onVector2ControlXMoved, ¶m_mgr->mWave1Dir); childSetCommitCallback("WaterWave1DirY", onVector2ControlYMoved, ¶m_mgr->mWave1Dir); childSetCommitCallback("WaterWave2DirX", onVector2ControlXMoved, ¶m_mgr->mWave2Dir); childSetCommitCallback("WaterWave2DirY", onVector2ControlYMoved, ¶m_mgr->mWave2Dir); comboBox->setCommitCallback(onChangePresetName); LLTextureCtrl* textCtrl = getChild("WaterNormalMap"); textCtrl->setDefaultImageAssetID(DEFAULT_WATER_NORMAL); childSetCommitCallback("WaterNormalMap", onNormalMapPicked, NULL); // next/prev buttons childSetAction("next", onClickNext, this); childSetAction("prev", onClickPrev, this); } void LLFloaterWater::onClickHelp(void* data) { LLFloaterWater* self = LLFloaterWater::instance(); const std::string* xml_alert = (std::string*)data; LLNotifications::instance().add(self->contextualNotification(*xml_alert)); } void LLFloaterWater::initHelpBtn(const std::string& name, const std::string& xml_alert) { childSetAction(name, onClickHelp, new std::string(xml_alert)); } bool LLFloaterWater::newPromptCallback(const LLSD& notification, const LLSD& response) { std::string text = response["message"].asString(); S32 option = LLNotification::getSelectedOption(notification, response); if(text == "") { return false; } if(option == 0) { LLComboBox* comboBox = sWaterMenu->getChild( "WaterPresetsCombo"); LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); // add the current parameters to the list // see if it's there first std::map::iterator mIt = param_mgr->mParamList.find(text); // if not there, add a new one if(mIt == param_mgr->mParamList.end()) { param_mgr->addParamSet(text, param_mgr->mCurParams); comboBox->add(text); comboBox->sortByName(); comboBox->setSelectedByValue(text, true); param_mgr->savePreset(text); // otherwise, send a message to the user } else { LLNotifications::instance().add("ExistsWaterPresetAlert"); } } return false; } void LLFloaterWater::syncMenu() { bool err; LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); LLWaterParamSet & current_params = param_mgr->mCurParams; LLComboBox* comboBox = getChild("WaterPresetsCombo"); if (comboBox->getSelectedItemLabel() != current_params.mName) { comboBox->setSimple(current_params.mName); } // blue horizon param_mgr->mFogColor = current_params.getVector4(param_mgr->mFogColor.mName, err); LLColor4 col = param_mgr->getFogColor(); childSetValue("WaterGlow", col.mV[3]); col.mV[3] = 1.0f; LLColorSwatchCtrl* colCtrl = sWaterMenu->getChild("WaterFogColor"); colCtrl->set(col); // fog and wavelets param_mgr->mFogDensity.mExp = log(current_params.getFloat(param_mgr->mFogDensity.mName, err)) / log(param_mgr->mFogDensity.mBase); param_mgr->setDensitySliderValue(param_mgr->mFogDensity.mExp); childSetValue("WaterFogDensity", param_mgr->mFogDensity.mExp); param_mgr->mUnderWaterFogMod.mX = current_params.getFloat(param_mgr->mUnderWaterFogMod.mName, err); childSetValue("WaterUnderWaterFogMod", param_mgr->mUnderWaterFogMod.mX); param_mgr->mNormalScale = current_params.getVector3(param_mgr->mNormalScale.mName, err); childSetValue("WaterNormalScaleX", param_mgr->mNormalScale.mX); childSetValue("WaterNormalScaleY", param_mgr->mNormalScale.mY); childSetValue("WaterNormalScaleZ", param_mgr->mNormalScale.mZ); // Fresnel param_mgr->mFresnelScale.mX = current_params.getFloat(param_mgr->mFresnelScale.mName, err); childSetValue("WaterFresnelScale", param_mgr->mFresnelScale.mX); param_mgr->mFresnelOffset.mX = current_params.getFloat(param_mgr->mFresnelOffset.mName, err); childSetValue("WaterFresnelOffset", param_mgr->mFresnelOffset.mX); // Scale Above/Below param_mgr->mScaleAbove.mX = current_params.getFloat(param_mgr->mScaleAbove.mName, err); childSetValue("WaterScaleAbove", param_mgr->mScaleAbove.mX); param_mgr->mScaleBelow.mX = current_params.getFloat(param_mgr->mScaleBelow.mName, err); childSetValue("WaterScaleBelow", param_mgr->mScaleBelow.mX); // blur mult param_mgr->mBlurMultiplier.mX = current_params.getFloat(param_mgr->mBlurMultiplier.mName, err); childSetValue("WaterBlurMult", param_mgr->mBlurMultiplier.mX); // wave directions param_mgr->mWave1Dir = current_params.getVector2(param_mgr->mWave1Dir.mName, err); childSetValue("WaterWave1DirX", param_mgr->mWave1Dir.mX); childSetValue("WaterWave1DirY", param_mgr->mWave1Dir.mY); param_mgr->mWave2Dir = current_params.getVector2(param_mgr->mWave2Dir.mName, err); childSetValue("WaterWave2DirX", param_mgr->mWave2Dir.mX); childSetValue("WaterWave2DirY", param_mgr->mWave2Dir.mY); LLTextureCtrl* textCtrl = sWaterMenu->getChild("WaterNormalMap"); textCtrl->setImageAssetID(param_mgr->getNormalMapID()); } // static LLFloaterWater* LLFloaterWater::instance() { if (!sWaterMenu) { sWaterMenu = new LLFloaterWater(); sWaterMenu->open(); sWaterMenu->setFocus(TRUE); } return sWaterMenu; } void LLFloaterWater::show() { if (!sWaterMenu) { LLFloaterWater* water = instance(); water->syncMenu(); // comment in if you want the menu to rebuild each time //LLUICtrlFactory::getInstance()->buildFloater(water, "floater_water.xml"); //water->initCallbacks(); } else { if (sWaterMenu->getVisible()) { sWaterMenu->close(); } else { sWaterMenu->open(); } } } bool LLFloaterWater::isOpen() { if (sWaterMenu != NULL) { return true; } return false; } // virtual void LLFloaterWater::onClose(bool app_quitting) { if (sWaterMenu) { sWaterMenu->setVisible(FALSE); } } // vector control callbacks void LLFloaterWater::onVector3ControlXMoved(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); WaterVector3Control * vectorControl = static_cast(userData); vectorControl->mX = sldrCtrl->getValueF32(); vectorControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } // vector control callbacks void LLFloaterWater::onVector3ControlYMoved(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); WaterVector3Control * vectorControl = static_cast(userData); vectorControl->mY = sldrCtrl->getValueF32(); vectorControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } // vector control callbacks void LLFloaterWater::onVector3ControlZMoved(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); WaterVector3Control * vectorControl = static_cast(userData); vectorControl->mZ = sldrCtrl->getValueF32(); vectorControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } // vector control callbacks void LLFloaterWater::onVector2ControlXMoved(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); WaterVector2Control * vectorControl = static_cast(userData); vectorControl->mX = sldrCtrl->getValueF32(); vectorControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } // vector control callbacks void LLFloaterWater::onVector2ControlYMoved(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); WaterVector2Control * vectorControl = static_cast(userData); vectorControl->mY = sldrCtrl->getValueF32(); vectorControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } // color control callbacks void LLFloaterWater::onColorControlRMoved(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); WaterColorControl * colorControl = static_cast(userData); colorControl->mR = sldrCtrl->getValueF32(); // move i if it's the max if(colorControl->mR >= colorControl->mG && colorControl->mR >= colorControl->mB && colorControl->mHasSliderName) { colorControl->mI = colorControl->mR; std::string name = colorControl->mSliderName; name.append("I"); sWaterMenu->childSetValue(name, colorControl->mR); } colorControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } void LLFloaterWater::onColorControlGMoved(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); WaterColorControl * colorControl = static_cast(userData); colorControl->mG = sldrCtrl->getValueF32(); // move i if it's the max if(colorControl->mG >= colorControl->mR && colorControl->mG >= colorControl->mB && colorControl->mHasSliderName) { colorControl->mI = colorControl->mG; std::string name = colorControl->mSliderName; name.append("I"); sWaterMenu->childSetValue(name, colorControl->mG); } colorControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } void LLFloaterWater::onColorControlBMoved(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); WaterColorControl * colorControl = static_cast(userData); colorControl->mB = sldrCtrl->getValueF32(); // move i if it's the max if(colorControl->mB >= colorControl->mR && colorControl->mB >= colorControl->mG && colorControl->mHasSliderName) { colorControl->mI = colorControl->mB; std::string name = colorControl->mSliderName; name.append("I"); sWaterMenu->childSetValue(name, colorControl->mB); } colorControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } void LLFloaterWater::onColorControlAMoved(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); WaterColorControl * colorControl = static_cast(userData); colorControl->mA = sldrCtrl->getValueF32(); colorControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } void LLFloaterWater::onColorControlIMoved(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); WaterColorControl * colorControl = static_cast(userData); colorControl->mI = sldrCtrl->getValueF32(); // only for sliders where we pass a name if(colorControl->mHasSliderName) { // set it to the top F32 maxVal = std::max(std::max(colorControl->mR, colorControl->mG), colorControl->mB); F32 iVal; iVal = colorControl->mI; // get the names of the other sliders std::string rName = colorControl->mSliderName; rName.append("R"); std::string gName = colorControl->mSliderName; gName.append("G"); std::string bName = colorControl->mSliderName; bName.append("B"); // handle if at 0 if(iVal == 0) { colorControl->mR = 0; colorControl->mG = 0; colorControl->mB = 0; // if all at the start // set them all to the intensity } else if (maxVal == 0) { colorControl->mR = iVal; colorControl->mG = iVal; colorControl->mB = iVal; } else { // add delta amounts to each F32 delta = (iVal - maxVal) / maxVal; colorControl->mR *= (1.0f + delta); colorControl->mG *= (1.0f + delta); colorControl->mB *= (1.0f + delta); } // set the sliders to the new vals sWaterMenu->childSetValue(rName, colorControl->mR); sWaterMenu->childSetValue(gName, colorControl->mG); sWaterMenu->childSetValue(bName, colorControl->mB); } // now update the current parameters and send them to shaders colorControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } void LLFloaterWater::onExpFloatControlMoved(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); WaterExpFloatControl * expFloatControl = static_cast(userData); F32 val = sldrCtrl->getValueF32(); expFloatControl->mExp = val; LLWaterParamManager::instance()->setDensitySliderValue(val); expFloatControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } void LLFloaterWater::onFloatControlMoved(LLUICtrl* ctrl, void* userData) { LLSliderCtrl* sldrCtrl = static_cast(ctrl); WaterFloatControl * floatControl = static_cast(userData); floatControl->mX = sldrCtrl->getValueF32() / floatControl->mMult; floatControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } void LLFloaterWater::onWaterFogColorMoved(LLUICtrl* ctrl, void* userData) { LLColorSwatchCtrl* swatch = static_cast(ctrl); WaterColorControl * colorControl = static_cast(userData); *colorControl = swatch->get(); colorControl->update(LLWaterParamManager::instance()->mCurParams); LLWaterParamManager::instance()->propagateParameters(); } void LLFloaterWater::onBoolToggle(LLUICtrl* ctrl, void* userData) { LLCheckBoxCtrl* cbCtrl = static_cast(ctrl); bool value = cbCtrl->get(); (*(static_cast(userData))) = value; } void LLFloaterWater::onNormalMapPicked(LLUICtrl* ctrl, void* userData) { LLTextureCtrl* textCtrl = static_cast(ctrl); LLUUID textID = textCtrl->getImageAssetID(); LLWaterParamManager::instance()->setNormalMapID(textID); } void LLFloaterWater::onNewPreset(void* userData) { LLNotifications::instance().add("NewWaterPreset", LLSD(), LLSD(), newPromptCallback); } class KVFloaterWaterNotecardCreatedCallback : public LLInventoryCallback { public: void fire(const LLUUID& inv_item); }; void KVFloaterWaterNotecardCreatedCallback::fire(const LLUUID& inv_item) { LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); param_mgr->setParamSet(param_mgr->mCurParams.mName, param_mgr->mCurParams); param_mgr->mParamList[param_mgr->mCurParams.mName].mInventoryID = inv_item; param_mgr->mCurParams.mInventoryID = inv_item; LL_INFOS("WindLight") << "Created inventory item " << inv_item << LL_ENDL; param_mgr->savePresetToNotecard(param_mgr->mCurParams.mName); } void LLFloaterWater::onSavePreset(LLUICtrl* ctrl, void* userData) { // get the name LLComboBox* comboBox = sWaterMenu->getChild("WaterPresetsCombo"); // don't save the empty name if(comboBox->getSelectedItemLabel() == "") { return; } if (ctrl->getValue().asString() == "save_inventory_item") { // Check if this is already a notecard. if(LLWaterParamManager::instance()->mCurParams.mInventoryID.notNull()) { LLNotifications::instance().add("KittyWLSaveNotecardAlert", LLSD(), LLSD(), saveNotecardCallback); } else { // Make sure we have a ".ww" extension. std::string name = comboBox->getSelectedItemLabel(); if(name.length() > 2 && name.compare(name.length() - 3, 3, ".ww") != 0) { name += ".ww"; } LLPointer cb = new KVFloaterWaterNotecardCreatedCallback(); // Create a notecard and then save it. create_inventory_item(gAgent.getID(), gAgent.getSessionID(), LLUUID::null, LLTransactionID::tnull, name, "Water settings (Imprudence compatible)", LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, NOT_WEARABLE, PERM_ITEM_UNRESTRICTED, cb); } } else if (ctrl->getValue().asString() == "send_to_server_item") { //Open the other box WLFloaterWindLightSend::instance(); WLFloaterWindLightSend::instance()->open(); } else { LLWaterParamManager::instance()->mCurParams.mName = comboBox->getSelectedItemLabel(); // check to see if it's a default and shouldn't be overwritten std::set::iterator sIt = sDefaultPresets.find( comboBox->getSelectedItemLabel()); if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("WaterEditPresets")) { LLNotifications::instance().add("WLNoEditDefault"); return; } LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback); } } bool LLFloaterWater::saveNotecardCallback(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); // if they choose save, do it. Otherwise, don't do anything if(option == 0) { LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); param_mgr->setParamSet(param_mgr->mCurParams.mName, param_mgr->mCurParams); param_mgr->savePresetToNotecard(param_mgr->mCurParams.mName); } return false; } bool LLFloaterWater::saveAlertCallback(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); // if they choose save, do it. Otherwise, don't do anything if(option == 0) { LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); param_mgr->setParamSet( param_mgr->mCurParams.mName, param_mgr->mCurParams); // comment this back in to save to file param_mgr->savePreset(param_mgr->mCurParams.mName); } return false; } void LLFloaterWater::onDeletePreset(void* userData) { LLComboBox* combo_box = sWaterMenu->getChild("WaterPresetsCombo"); if(combo_box->getSelectedValue().asString() == "") { return; } LLSD args; args["SKY"] = combo_box->getSelectedValue().asString(); LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(), deleteAlertCallback); } bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); // if they choose delete, do it. Otherwise, don't do anything if(option == 0) { LLComboBox* combo_box = sWaterMenu->getChild("WaterPresetsCombo"); LLFloaterDayCycle* day_cycle = NULL; LLComboBox* key_combo = NULL; if(LLFloaterDayCycle::isOpen()) { day_cycle = LLFloaterDayCycle::instance(); key_combo = day_cycle->getChild("WaterKeyPresets"); } std::string name = combo_box->getSelectedValue().asString(); // check to see if it's a default and shouldn't be deleted std::set::iterator sIt = sDefaultPresets.find(name); if(sIt != sDefaultPresets.end()) { LLNotifications::instance().add("WaterNoEditDefault"); return false; } LLWaterParamManager::instance()->removeParamSet(name, true); // remove and choose another S32 new_index = combo_box->getCurrentIndex(); combo_box->remove(name); if(key_combo != NULL) { key_combo->remove(name); // remove from slider, as well day_cycle->deletePreset(name); } // pick the previously selected index after delete if(new_index > 0) { new_index--; } if(combo_box->getItemCount() > 0) { combo_box->setCurrentByIndex(new_index); } } return false; } void LLFloaterWater::onChangePresetName(LLUICtrl* ctrl, void * userData) { LLComboBox * combo_box = static_cast(ctrl); if(combo_box->getSimple() == "") { return; } LLWaterParamManager::instance()->loadPreset( combo_box->getSelectedValue().asString()); sWaterMenu->syncMenu(); } void LLFloaterWater::onClickNext(void* user_data) { LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); LLWaterParamSet& currentParams = param_mgr->mCurParams; // find place of current param std::map::iterator mIt = param_mgr->mParamList.find(currentParams.mName); // if at the end, loop std::map::iterator last = param_mgr->mParamList.end(); --last; if(mIt == last) { mIt = param_mgr->mParamList.begin(); } else { mIt++; } /*param_mgr->mAnimator.mIsRunning = false; param_mgr->mAnimator.mUseLindenTime = false;*/ param_mgr->loadPreset(mIt->first, true); } void LLFloaterWater::onClickPrev(void* user_data) { LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); LLWaterParamSet & currentParams = param_mgr->mCurParams; // find place of current param std::map::iterator mIt = param_mgr->mParamList.find(currentParams.mName); // if at the beginning, loop if(mIt == param_mgr->mParamList.begin()) { std::map::iterator last = param_mgr->mParamList.end(); --last; mIt = last; } else { mIt--; } /*param_mgr->mAnimator.mIsRunning = false; param_mgr->mAnimator.mUseLindenTime = false;*/ param_mgr->loadPreset(mIt->first, true); }