summaryrefslogtreecommitdiff
path: root/indra/newview/llfloatereditextdaycycle.cpp
diff options
context:
space:
mode:
authorAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 19:04:52 +0200
committerAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 19:04:52 +0200
commit1b67dd855c41f5a0cda7ec2a68d98071986ca703 (patch)
treeab243607f74f78200787bba5b9b88f07ef1b966f /indra/newview/llfloatereditextdaycycle.cpp
parent6d6eabca44d08d5b97bfe3e941d2b9687c2246ea (diff)
parente1623bb276f83a43ce7a197e388720c05bdefe61 (diff)
Merge remote-tracking branch 'origin/main' into DRTVWR-600-maint-A
# Conflicts: # autobuild.xml # indra/cmake/CMakeLists.txt # indra/cmake/GoogleMock.cmake # indra/llaudio/llaudioengine_fmodstudio.cpp # indra/llaudio/llaudioengine_fmodstudio.h # indra/llaudio/lllistener_fmodstudio.cpp # indra/llaudio/lllistener_fmodstudio.h # indra/llaudio/llstreamingaudio_fmodstudio.cpp # indra/llaudio/llstreamingaudio_fmodstudio.h # indra/llcharacter/llmultigesture.cpp # indra/llcharacter/llmultigesture.h # indra/llimage/llimage.cpp # indra/llimage/llimagepng.cpp # indra/llimage/llimageworker.cpp # indra/llimage/tests/llimageworker_test.cpp # indra/llmessage/tests/llmockhttpclient.h # indra/llprimitive/llgltfmaterial.h # indra/llrender/llfontfreetype.cpp # indra/llui/llcombobox.cpp # indra/llui/llfolderview.cpp # indra/llui/llfolderviewmodel.h # indra/llui/lllineeditor.cpp # indra/llui/lllineeditor.h # indra/llui/lltextbase.cpp # indra/llui/lltextbase.h # indra/llui/lltexteditor.cpp # indra/llui/lltextvalidate.cpp # indra/llui/lltextvalidate.h # indra/llui/lluictrl.h # indra/llui/llview.cpp # indra/llwindow/llwindowmacosx.cpp # indra/newview/app_settings/settings.xml # indra/newview/llappearancemgr.cpp # indra/newview/llappearancemgr.h # indra/newview/llavatarpropertiesprocessor.cpp # indra/newview/llavatarpropertiesprocessor.h # indra/newview/llbreadcrumbview.cpp # indra/newview/llbreadcrumbview.h # indra/newview/llbreastmotion.cpp # indra/newview/llbreastmotion.h # indra/newview/llconversationmodel.h # indra/newview/lldensityctrl.cpp # indra/newview/lldensityctrl.h # indra/newview/llface.inl # indra/newview/llfloatereditsky.cpp # indra/newview/llfloatereditwater.cpp # indra/newview/llfloateremojipicker.h # indra/newview/llfloaterimsessiontab.cpp # indra/newview/llfloaterprofiletexture.cpp # indra/newview/llfloaterprofiletexture.h # indra/newview/llgesturemgr.cpp # indra/newview/llgesturemgr.h # indra/newview/llimpanel.cpp # indra/newview/llimpanel.h # indra/newview/llinventorybridge.cpp # indra/newview/llinventorybridge.h # indra/newview/llinventoryclipboard.cpp # indra/newview/llinventoryclipboard.h # indra/newview/llinventoryfunctions.cpp # indra/newview/llinventoryfunctions.h # indra/newview/llinventorygallery.cpp # indra/newview/lllistbrowser.cpp # indra/newview/lllistbrowser.h # indra/newview/llpanelobjectinventory.cpp # indra/newview/llpanelprofile.cpp # indra/newview/llpanelprofile.h # indra/newview/llpreviewgesture.cpp # indra/newview/llsavedsettingsglue.cpp # indra/newview/llsavedsettingsglue.h # indra/newview/lltooldraganddrop.cpp # indra/newview/llurllineeditorctrl.cpp # indra/newview/llvectorperfoptions.cpp # indra/newview/llvectorperfoptions.h # indra/newview/llviewerparceloverlay.cpp # indra/newview/llviewertexlayer.cpp # indra/newview/llviewertexturelist.cpp # indra/newview/macmain.h # indra/test/test.cpp
Diffstat (limited to 'indra/newview/llfloatereditextdaycycle.cpp')
-rw-r--r--indra/newview/llfloatereditextdaycycle.cpp3708
1 files changed, 1854 insertions, 1854 deletions
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
index befc765cb0..aaaeab4b04 100644
--- a/indra/newview/llfloatereditextdaycycle.cpp
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -1,1854 +1,1854 @@
-/**
- * @file llfloatereditextdaycycle.cpp
- * @brief Floater to create or edit a day cycle
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloatereditextdaycycle.h"
-
-// libs
-#include "llbutton.h"
-#include "llcallbacklist.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "llloadingindicator.h"
-#include "lllocalbitmaps.h"
-#include "llmultisliderctrl.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
-#include "llspinctrl.h"
-#include "lltimectrl.h"
-#include "lltabcontainer.h"
-#include "llfilepicker.h"
-
-#include "llsettingsvo.h"
-#include "llinventorymodel.h"
-#include "llviewerparcelmgr.h"
-
-#include "llsettingspicker.h"
-#include "lltrackpicker.h"
-
-// newview
-#include "llagent.h"
-#include "llappviewer.h" //gDisconected
-#include "llparcel.h"
-#include "llflyoutcombobtn.h" //Todo: make a proper UI element/button/panel instead
-#include "llregioninfomodel.h"
-#include "llviewermenufile.h" // LLFilePickerReplyThread
-#include "llviewerregion.h"
-#include "llpaneleditwater.h"
-#include "llpaneleditsky.h"
-
-#include "llui.h"
-
-#include "llenvironment.h"
-#include "lltrans.h"
-
-extern LLControlGroup gSavedSettings;
-
-//=========================================================================
-namespace {
- const std::string track_tabs[] = {
- "water_track",
- "sky1_track",
- "sky2_track",
- "sky3_track",
- "sky4_track",
- };
-
- const std::string ICN_LOCK_EDIT("icn_lock_edit");
- const std::string BTN_SAVE("save_btn");
- const std::string BTN_FLYOUT("btn_flyout");
- const std::string BTN_CANCEL("cancel_btn");
- const std::string BTN_ADDFRAME("add_frame");
- const std::string BTN_DELFRAME("delete_frame");
- const std::string BTN_IMPORT("btn_import");
- const std::string BTN_LOADFRAME("btn_load_frame");
- const std::string BTN_CLONETRACK("copy_track");
- const std::string BTN_LOADTRACK("load_track");
- const std::string BTN_CLEARTRACK("clear_track");
- const std::string SLDR_TIME("WLTimeSlider");
- const std::string SLDR_KEYFRAMES("WLDayCycleFrames");
- const std::string VIEW_SKY_SETTINGS("frame_settings_sky");
- const std::string VIEW_WATER_SETTINGS("frame_settings_water");
- const std::string LBL_CURRENT_TIME("current_time");
- const std::string TXT_DAY_NAME("day_cycle_name");
- const std::string TABS_SKYS("sky_tabs");
- const std::string TABS_WATER("water_tabs");
-
- // 'Play' buttons
- const std::string BTN_PLAY("play_btn");
- const std::string BTN_SKIP_BACK("skip_back_btn");
- const std::string BTN_SKIP_FORWARD("skip_forward_btn");
-
- const std::string EVNT_DAYTRACK("DayCycle.Track");
- const std::string EVNT_PLAY("DayCycle.PlayActions");
-
- const std::string ACTION_PLAY("play");
- const std::string ACTION_PAUSE("pause");
- const std::string ACTION_FORWARD("forward");
- const std::string ACTION_BACK("back");
-
- // For flyout
- const std::string XML_FLYOUTMENU_FILE("menu_save_settings.xml");
- // From menu_save_settings.xml, consider moving into flyout since it should be supported by flyout either way
- const std::string ACTION_SAVE("save_settings");
- const std::string ACTION_SAVEAS("save_as_new_settings");
- const std::string ACTION_COMMIT("commit_changes");
- const std::string ACTION_APPLY_LOCAL("apply_local");
- const std::string ACTION_APPLY_PARCEL("apply_parcel");
- const std::string ACTION_APPLY_REGION("apply_region");
-
- const F32 DAY_CYCLE_PLAY_TIME_SECONDS = 60;
-
- const std::string STR_COMMIT_PARCEL("commit_parcel");
- const std::string STR_COMMIT_REGION("commit_region");
- //---------------------------------------------------------------------
-
-}
-
-//=========================================================================
-const std::string LLFloaterEditExtDayCycle::KEY_EDIT_CONTEXT("edit_context");
-const std::string LLFloaterEditExtDayCycle::KEY_DAY_LENGTH("day_length");
-const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod");
-
-const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_INVENTORY("inventory");
-const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_PARCEL("parcel");
-const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_REGION("region");
-/*
-//=========================================================================
-
-class LLDaySettingCopiedCallback : public LLInventoryCallback
-{
-public:
- LLDaySettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {}
-
- virtual void fire(const LLUUID& inv_item_id)
- {
- if (!mHandle.isDead())
- {
- LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
- if (item)
- {
- LLFloaterEditExtDayCycle* floater = (LLFloaterEditExtDayCycle*)mHandle.get();
- floater->onInventoryCreated(item->getAssetUUID(), inv_item_id);
- }
- }
- }
-
-private:
- LLHandle<LLFloater> mHandle;
-};*/
-
-//=========================================================================
-
-LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) :
- LLFloaterEditEnvironmentBase(key),
- mFlyoutControl(nullptr),
- mDayLength(0),
- mCurrentTrack(1),
- mShiftCopyEnabled(false),
- mTimeSlider(nullptr),
- mFramesSlider(nullptr),
- mCurrentTimeLabel(nullptr),
- mImportButton(nullptr),
- mLoadFrame(nullptr),
- mSkyBlender(),
- mWaterBlender(),
- mScratchSky(),
- mScratchWater(),
- mIsPlaying(false),
- mCloneTrack(nullptr),
- mLoadTrack(nullptr),
- mClearTrack(nullptr)
-{
-
- mCommitCallbackRegistrar.add(EVNT_DAYTRACK, [this](LLUICtrl *ctrl, const LLSD &data) { onTrackSelectionCallback(data); });
- mCommitCallbackRegistrar.add(EVNT_PLAY, [this](LLUICtrl *ctrl, const LLSD &data) { onPlayActionCallback(data); });
-
- mScratchSky = LLSettingsVOSky::buildDefaultSky();
- mScratchWater = LLSettingsVOWater::buildDefaultWater();
-
- mEditSky = mScratchSky;
- mEditWater = mScratchWater;
-}
-
-LLFloaterEditExtDayCycle::~LLFloaterEditExtDayCycle()
-{
- // Todo: consider remaking mFlyoutControl into full view class that initializes intself with floater,
- // complete with postbuild, e t c...
- delete mFlyoutControl;
-}
-
-// virtual
-bool LLFloaterEditExtDayCycle::postBuild()
-{
- getChild<LLLineEditor>(TXT_DAY_NAME)->setKeystrokeCallback(boost::bind(&LLFloaterEditExtDayCycle::onCommitName, this, _1, _2), NULL);
-
- mAddFrameButton = getChild<LLButton>(BTN_ADDFRAME, true);
- mDeleteFrameButton = getChild<LLButton>(BTN_DELFRAME, true);
- mTimeSlider = getChild<LLMultiSliderCtrl>(SLDR_TIME);
- mFramesSlider = getChild<LLMultiSliderCtrl>(SLDR_KEYFRAMES);
- mSkyTabLayoutContainer = getChild<LLView>(VIEW_SKY_SETTINGS, true);
- mWaterTabLayoutContainer = getChild<LLView>(VIEW_WATER_SETTINGS, true);
- mCurrentTimeLabel = getChild<LLTextBox>(LBL_CURRENT_TIME, true);
- mImportButton = getChild<LLButton>(BTN_IMPORT, true);
- mLoadFrame = getChild<LLButton>(BTN_LOADFRAME, true);
- mCloneTrack = getChild<LLButton>(BTN_CLONETRACK, true);
- mLoadTrack = getChild<LLButton>(BTN_LOADTRACK, true);
- mClearTrack = getChild<LLButton>(BTN_CLEARTRACK, true);
-
- mFlyoutControl = new LLFlyoutComboBtnCtrl(this, BTN_SAVE, BTN_FLYOUT, XML_FLYOUTMENU_FILE, false);
- mFlyoutControl->setAction([this](LLUICtrl *ctrl, const LLSD &data) { onButtonApply(ctrl, data); });
-
- getChild<LLButton>(BTN_CANCEL, true)->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onClickCloseBtn(); });
- mTimeSlider->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onTimeSliderCallback(); });
- mAddFrameButton->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onAddFrame(); });
- mDeleteFrameButton->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onRemoveFrame(); });
- mImportButton->setCommitCallback([this](LLUICtrl *, const LLSD &){ onButtonImport(); });
- mLoadFrame->setCommitCallback([this](LLUICtrl *, const LLSD &){ onButtonLoadFrame(); });
-
- mCloneTrack->setCommitCallback([this](LLUICtrl *, const LLSD&){ onCloneTrack(); });
- mLoadTrack->setCommitCallback([this](LLUICtrl *, const LLSD&){ onLoadTrack();});
- mClearTrack->setCommitCallback([this](LLUICtrl *, const LLSD&){ onClearTrack(); });
-
-
- mFramesSlider->setCommitCallback([this](LLUICtrl *, const LLSD &data) { onFrameSliderCallback(data); });
- mFramesSlider->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderDoubleClick(x, y, mask); });
- mFramesSlider->setMouseDownCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderMouseDown(x, y, mask); });
- mFramesSlider->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderMouseUp(x, y, mask); });
-
- mTimeSlider->addSlider(0);
-
- LLTabContainer* tab_container = mSkyTabLayoutContainer->getChild<LLTabContainer>("sky_tabs");
- S32 tab_count = tab_container->getTabCount();
-
- LLSettingsEditPanel *panel = nullptr;
-
- for (S32 idx = 0; idx < tab_count; ++idx)
- {
- panel = static_cast<LLSettingsEditPanel *>(tab_container->getPanelByIndex(idx));
- if (panel)
- panel->setOnDirtyFlagChanged([this](LLPanel *, bool val) { onPanelDirtyFlagChanged(val); });
- }
-
- tab_container = mWaterTabLayoutContainer->getChild<LLTabContainer>("water_tabs");
- tab_count = tab_container->getTabCount();
-
- for (S32 idx = 0; idx < tab_count; ++idx)
- {
- LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tab_container->getPanelByIndex(idx));
- if (panel)
- panel->setOnDirtyFlagChanged([this](LLPanel *, bool val) { onPanelDirtyFlagChanged(val); });
- }
-
- return true;
-}
-
-void LLFloaterEditExtDayCycle::onOpen(const LLSD& key)
-{
- if (!mEditDay)
- {
- LLEnvironment::instance().saveBeaconsState();
- }
- mEditDay.reset();
- mEditContext = CONTEXT_UNKNOWN;
- if (key.has(KEY_EDIT_CONTEXT))
- {
- std::string context = key[KEY_EDIT_CONTEXT].asString();
-
- if (context == VALUE_CONTEXT_INVENTORY)
- mEditContext = CONTEXT_INVENTORY;
- else if (context == VALUE_CONTEXT_PARCEL)
- mEditContext = CONTEXT_PARCEL;
- else if (context == VALUE_CONTEXT_REGION)
- mEditContext = CONTEXT_REGION;
- }
-
- if (key.has(KEY_CANMOD))
- {
- mCanMod = key[KEY_CANMOD].asBoolean();
- }
-
- if (mEditContext == CONTEXT_UNKNOWN)
- {
- LL_WARNS("ENVDAYEDIT") << "Unknown editing context!" << LL_ENDL;
- }
-
- if (key.has(KEY_INVENTORY_ID))
- {
- loadInventoryItem(key[KEY_INVENTORY_ID].asUUID());
- }
- else
- {
- mCanSave = true;
- mCanCopy = true;
- mCanMod = true;
- mCanTrans = true;
- setEditDefaultDayCycle();
- }
-
- mDayLength.value(0);
- if (key.has(KEY_DAY_LENGTH))
- {
- mDayLength.value(key[KEY_DAY_LENGTH].asReal());
- }
-
- // Time&Percentage labels
- mCurrentTimeLabel->setTextArg("[PRCNT]", std::string("0"));
- const S32 max_elm = 5;
- if (mDayLength.value() != 0)
- {
- S32Hours hrs;
- S32Minutes minutes;
- LLSettingsDay::Seconds total;
- LLUIString formatted_label = getString("time_label");
- for (int i = 0; i < max_elm; i++)
- {
- total = ((mDayLength / (max_elm - 1)) * i);
- hrs = total;
- minutes = total - hrs;
-
- formatted_label.setArg("[HH]", llformat("%d", hrs.value()));
- formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value())));
- getChild<LLTextBox>("p" + llformat("%d", i), true)->setTextArg("[DSC]", formatted_label.getString());
- }
- hrs = mDayLength;
- minutes = mDayLength - hrs;
- formatted_label.setArg("[HH]", llformat("%d", hrs.value()));
- formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value())));
- mCurrentTimeLabel->setTextArg("[DSC]", formatted_label.getString());
- }
- else
- {
- for (int i = 0; i < max_elm; i++)
- {
- getChild<LLTextBox>("p" + llformat("%d", i), true)->setTextArg("[DSC]", std::string());
- }
- mCurrentTimeLabel->setTextArg("[DSC]", std::string());
- }
-
- // Adjust Time&Percentage labels' location according to length
- LLRect label_rect = getChild<LLTextBox>("p0", true)->getRect();
- F32 slider_width = mFramesSlider->getRect().getWidth();
- for (int i = 1; i < max_elm; i++)
- {
- LLTextBox *pcnt_label = getChild<LLTextBox>("p" + llformat("%d", i), true);
- LLRect new_rect = pcnt_label->getRect();
- new_rect.mLeft = label_rect.mLeft + (S32)(slider_width * (F32)i / (F32)(max_elm - 1)) - (S32)(pcnt_label->getTextPixelWidth() / 2);
- pcnt_label->setRect(new_rect);
- }
-
- // Altitudes&Track labels
- LLUIString formatted_label = getString("sky_track_label");
- const LLEnvironment::altitude_list_t &altitudes = LLEnvironment::instance().getRegionAltitudes();
- bool extended_env = LLEnvironment::instance().isExtendedEnvironmentEnabled();
- bool use_altitudes = extended_env
- && altitudes.size() > 0
- && ((mEditContext == CONTEXT_PARCEL) || (mEditContext == CONTEXT_REGION));
- for (S32 idx = 1; idx < 4; ++idx)
- {
- std::ostringstream convert;
- if (use_altitudes)
- {
- convert << altitudes[idx] << "m";
- }
- else
- {
- convert << (idx + 1);
- }
- formatted_label.setArg("[ALT]", convert.str());
- getChild<LLButton>(track_tabs[idx + 1], true)->setLabel(formatted_label.getString());
- }
-
- for (U32 i = 2; i < LLSettingsDay::TRACK_MAX; i++) //skies #2 through #4
- {
- getChild<LLButton>(track_tabs[i])->setEnabled(extended_env);
- }
-
- if (mEditContext == CONTEXT_INVENTORY)
- {
- mFlyoutControl->setShownBtnEnabled(true);
- mFlyoutControl->setSelectedItem(ACTION_SAVE);
- }
- else if ((mEditContext == CONTEXT_REGION) || (mEditContext == CONTEXT_PARCEL))
- {
- std::string commit_str = (mEditContext == CONTEXT_PARCEL) ? STR_COMMIT_PARCEL : STR_COMMIT_REGION;
- mFlyoutControl->setMenuItemLabel(ACTION_COMMIT, getString(commit_str));
- mFlyoutControl->setShownBtnEnabled(true);
- mFlyoutControl->setSelectedItem(ACTION_COMMIT);
- }
- else
- {
- mFlyoutControl->setShownBtnEnabled(false);
- }
-}
-
-void LLFloaterEditExtDayCycle::onClose(bool app_quitting)
-{
- doCloseInventoryFloater(app_quitting);
- doCloseTrackFloater(app_quitting);
- // there's no point to change environment if we're quitting
- // or if we already restored environment
- stopPlay();
- LLEnvironment::instance().revertBeaconsState();
- if (!app_quitting)
- {
- LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_FAST);
- LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
- mEditDay.reset();
- }
-}
-
-
-void LLFloaterEditExtDayCycle::onVisibilityChange(bool new_visibility)
-{
-}
-
-void LLFloaterEditExtDayCycle::refresh()
-{
- if (mEditDay)
- {
- LLLineEditor* name_field = getChild<LLLineEditor>(TXT_DAY_NAME);
- name_field->setText(mEditDay->getName());
- name_field->setEnabled(mCanMod);
- }
-
-
- bool is_inventory_avail = canUseInventory();
-
- bool show_commit = ((mEditContext == CONTEXT_PARCEL) || (mEditContext == CONTEXT_REGION));
- bool show_apply = (mEditContext == CONTEXT_INVENTORY);
-
- if (show_commit)
- {
- std::string commit_text;
- if (mEditContext == CONTEXT_PARCEL)
- commit_text = getString(STR_COMMIT_PARCEL);
- else
- commit_text = getString(STR_COMMIT_REGION);
-
- mFlyoutControl->setMenuItemLabel(ACTION_COMMIT, commit_text);
- }
-
- mFlyoutControl->setMenuItemVisible(ACTION_COMMIT, show_commit);
- mFlyoutControl->setMenuItemVisible(ACTION_SAVE, is_inventory_avail);
- mFlyoutControl->setMenuItemVisible(ACTION_SAVEAS, is_inventory_avail);
- mFlyoutControl->setMenuItemVisible(ACTION_APPLY_LOCAL, true);
- mFlyoutControl->setMenuItemVisible(ACTION_APPLY_PARCEL, show_apply);
- mFlyoutControl->setMenuItemVisible(ACTION_APPLY_REGION, show_apply);
-
- mFlyoutControl->setMenuItemEnabled(ACTION_COMMIT, show_commit && !mCommitSignal.empty());
- mFlyoutControl->setMenuItemEnabled(ACTION_SAVE, is_inventory_avail && mCanMod && !mInventoryId.isNull() && mCanSave);
- mFlyoutControl->setMenuItemEnabled(ACTION_SAVEAS, is_inventory_avail && mCanCopy && mCanSave);
- mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_LOCAL, true);
- mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_PARCEL, canApplyParcel() && show_apply);
- mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_REGION, canApplyRegion() && show_apply);
-
- mImportButton->setEnabled(mCanMod);
-
- LLFloater::refresh();
-}
-
-void LLFloaterEditExtDayCycle::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings)
-{
- setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings));
-
- showHDRNotification(std::dynamic_pointer_cast<LLSettingsDay>(settings));
-}
-
-void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday)
-{
- mExpectingAssetId.setNull();
- mEditDay = pday->buildDeepCloneAndUncompress();
-
- if (mEditDay->isTrackEmpty(LLSettingsDay::TRACK_WATER))
- {
- LL_WARNS("ENVDAYEDIT") << "No water frames found, generating replacement" << LL_ENDL;
- mEditDay->setWaterAtKeyframe(LLSettingsVOWater::buildDefaultWater(), .5f);
- }
-
- if (mEditDay->isTrackEmpty(LLSettingsDay::TRACK_GROUND_LEVEL))
- {
- LL_WARNS("ENVDAYEDIT") << "No sky frames found, generating replacement" << LL_ENDL;
- mEditDay->setSkyAtKeyframe(LLSettingsVOSky::buildDefaultSky(), .5f, LLSettingsDay::TRACK_GROUND_LEVEL);
- }
-
- mCanSave = !pday->getFlag(LLSettingsBase::FLAG_NOSAVE);
- mCanCopy = !pday->getFlag(LLSettingsBase::FLAG_NOCOPY) && mCanSave;
- mCanMod = !pday->getFlag(LLSettingsBase::FLAG_NOMOD) && mCanSave;
- mCanTrans = !pday->getFlag(LLSettingsBase::FLAG_NOTRANS) && mCanSave;
-
- updateEditEnvironment();
- LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);
- LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
- synchronizeTabs();
- updateTabs();
- refresh();
-}
-
-
-void LLFloaterEditExtDayCycle::setEditDefaultDayCycle()
-{
- mInventoryItem = nullptr;
- mInventoryId.setNull();
- mExpectingAssetId = LLSettingsDay::GetDefaultAssetId();
- LLSettingsVOBase::getSettingsAsset(LLSettingsDay::GetDefaultAssetId(),
- [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
-}
-
-std::string LLFloaterEditExtDayCycle::getEditName() const
-{
- if (mEditDay)
- return mEditDay->getName();
- return "new";
-}
-
-void LLFloaterEditExtDayCycle::setEditName(const std::string &name)
-{
- if (mEditDay)
- mEditDay->setName(name);
- getChild<LLLineEditor>(TXT_DAY_NAME)->setText(name);
-}
-
-/* virtual */
-bool LLFloaterEditExtDayCycle::handleKeyUp(KEY key, MASK mask, bool called_from_parent)
-{
- if (!mEditDay)
- {
- mShiftCopyEnabled = false;
- }
- else if (mask == MASK_SHIFT && mShiftCopyEnabled)
- {
- mShiftCopyEnabled = false;
- std::string curslider = mFramesSlider->getCurSlider();
- if (!curslider.empty())
- {
- F32 sliderpos = mFramesSlider->getCurSliderValue();
-
- keymap_t::iterator it = mSliderKeyMap.find(curslider);
- if (it != mSliderKeyMap.end())
- {
- if (mEditDay->moveTrackKeyframe(mCurrentTrack, (*it).second.mFrame, sliderpos))
- {
- (*it).second.mFrame = sliderpos;
- }
- else
- {
- mFramesSlider->setCurSliderValue((*it).second.mFrame);
- }
- }
- else
- {
- LL_WARNS("ENVDAYEDIT") << "Failed to find frame " << sliderpos << " for slider " << curslider << LL_ENDL;
- }
- }
- }
- return LLFloater::handleKeyUp(key, mask, called_from_parent);
-}
-
-void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
-{
- std::string ctrl_action = ctrl->getName();
-
- if (!mEditDay)
- {
- LL_WARNS("ENVDAYEDIT") << "mEditDay is null! This should never happen! Something is very very wrong" << LL_ENDL;
- LLNotificationsUtil::add("EnvironmentApplyFailed");
- closeFloater();
- return;
- }
-
- LLSettingsDay::ptr_t dayclone = mEditDay->buildClone(); // create a compressed copy
-
- if (!dayclone)
- {
- LL_WARNS("ENVDAYEDIT") << "Unable to clone daycylce from editor." << LL_ENDL;
- return;
- }
-
- // brute-force local texture scan
- for (U32 i = 0; i <= LLSettingsDay::TRACK_MAX; i++)
- {
- LLSettingsDay::CycleTrack_t &day_track = dayclone->getCycleTrack(i);
-
- LLSettingsDay::CycleTrack_t::iterator iter = day_track.begin();
- LLSettingsDay::CycleTrack_t::iterator end = day_track.end();
- S32 frame_num = 0;
-
- while (iter != end)
- {
- frame_num++;
- std::string desc;
- bool is_local = false; // because getString can be empty
- if (i == LLSettingsDay::TRACK_WATER)
- {
- LLSettingsWater::ptr_t water = std::static_pointer_cast<LLSettingsWater>(iter->second);
- if (water)
- {
- // LLViewerFetchedTexture and check for FTT_LOCAL_FILE or check LLLocalBitmapMgr
- if (LLLocalBitmapMgr::getInstance()->isLocal(water->getNormalMapID()))
- {
- desc = LLTrans::getString("EnvironmentNormalMap");
- is_local = true;
- }
- else if (LLLocalBitmapMgr::getInstance()->isLocal(water->getTransparentTextureID()))
- {
- desc = LLTrans::getString("EnvironmentTransparent");
- is_local = true;
- }
- }
- }
- else
- {
- LLSettingsSky::ptr_t sky = std::static_pointer_cast<LLSettingsSky>(iter->second);
- if (sky)
- {
- if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getSunTextureId()))
- {
- desc = LLTrans::getString("EnvironmentSun");
- is_local = true;
- }
- else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getMoonTextureId()))
- {
- desc = LLTrans::getString("EnvironmentMoon");
- is_local = true;
- }
- else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getCloudNoiseTextureId()))
- {
- desc = LLTrans::getString("EnvironmentCloudNoise");
- is_local = true;
- }
- else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getBloomTextureId()))
- {
- desc = LLTrans::getString("EnvironmentBloom");
- is_local = true;
- }
- }
- }
-
- if (is_local)
- {
- LLSD args;
- LLButton* button = getChild<LLButton>(track_tabs[i], true);
- args["TRACK"] = button->getCurrentLabel();
- args["FRAME"] = iter->first * 100; // %
- args["FIELD"] = desc;
- args["FRAMENO"] = frame_num;
- LLNotificationsUtil::add("WLLocalTextureDayBlock", args);
- return;
- }
- iter++;
- }
- }
-
- if (ctrl_action == ACTION_SAVE)
- {
- doApplyUpdateInventory(dayclone);
- clearDirtyFlag();
- }
- else if (ctrl_action == ACTION_SAVEAS)
- {
- LLSD args;
- args["DESC"] = dayclone->getName();
- LLNotificationsUtil::add("SaveSettingAs", args, LLSD(), boost::bind(&LLFloaterEditExtDayCycle::onSaveAsCommit, this, _1, _2, dayclone));
- }
- else if ((ctrl_action == ACTION_APPLY_LOCAL) ||
- (ctrl_action == ACTION_APPLY_PARCEL) ||
- (ctrl_action == ACTION_APPLY_REGION))
- {
- doApplyEnvironment(ctrl_action, dayclone);
- }
- else if (ctrl_action == ACTION_COMMIT)
- {
- doApplyCommit(dayclone);
- }
- else
- {
- LL_WARNS("ENVDAYEDIT") << "Unknown settings action '" << ctrl_action << "'" << LL_ENDL;
- }
-}
-
-void LLFloaterEditExtDayCycle::onButtonLoadFrame()
-{
- doOpenInventoryFloater((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLSettingsType::ST_WATER : LLSettingsType::ST_SKY, LLUUID::null);
-}
-
-void LLFloaterEditExtDayCycle::onAddFrame()
-{
- LLSettingsBase::Seconds frame(mTimeSlider->getCurSliderValue());
- LLSettingsBase::ptr_t setting;
- if (!mEditDay)
- {
- LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame while waiting for day(asset) to load." << LL_ENDL;
- return;
- }
- if ((mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
- {
- LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame too close to existing frame." << LL_ENDL;
- return;
- }
- if (!mFramesSlider->canAddSliders())
- {
- // Shouldn't happen, button should be disabled
- LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame when slider is full." << LL_ENDL;
- return;
- }
-
- if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
- {
- // scratch water should always have the current water settings.
- LLSettingsWater::ptr_t water(mScratchWater->buildClone());
- setting = water;
- mEditDay->setWaterAtKeyframe( std::static_pointer_cast<LLSettingsWater>(setting), frame);
- }
- else
- {
- // scratch sky should always have the current sky settings.
- LLSettingsSky::ptr_t sky(mScratchSky->buildClone());
- setting = sky;
- mEditDay->setSkyAtKeyframe(sky, frame, mCurrentTrack);
- }
- setDirtyFlag();
- addSliderFrame(frame, setting);
- updateTabs();
-}
-
-void LLFloaterEditExtDayCycle::onRemoveFrame()
-{
- std::string sldr_key = mFramesSlider->getCurSlider();
- if (sldr_key.empty())
- {
- return;
- }
- setDirtyFlag();
- removeCurrentSliderFrame();
- updateTabs();
-}
-
-
-void LLFloaterEditExtDayCycle::onCloneTrack()
-{
- if (!mEditDay)
- {
- LL_WARNS("ENVDAYEDIT") << "Attempt to copy track while waiting for day(asset) to load." << LL_ENDL;
- return;
- }
- const LLEnvironment::altitude_list_t &altitudes = LLEnvironment::instance().getRegionAltitudes();
- bool use_altitudes = altitudes.size() > 0 && ((mEditContext == CONTEXT_PARCEL) || (mEditContext == CONTEXT_REGION));
-
- LLSD args = LLSD::emptyArray();
-
- S32 populated_counter = 0;
- for (U32 i = 1; i < LLSettingsDay::TRACK_MAX; i++)
- {
- LLSD track;
- track["id"] = LLSD::Integer(i);
- bool populated = (!mEditDay->isTrackEmpty(i)) && (i != mCurrentTrack);
- track["enabled"] = populated;
- if (populated)
- {
- populated_counter++;
- }
- if (use_altitudes)
- {
- track["altitude"] = altitudes[i - 1];
- }
- args.append(track);
- }
-
- if (populated_counter > 0)
- {
- doOpenTrackFloater(args);
- }
- else
- {
- // Should not happen
- LL_WARNS("ENVDAYEDIT") << "Tried to copy tracks, but there are no available sources" << LL_ENDL;
- }
-}
-
-
-void LLFloaterEditExtDayCycle::onLoadTrack()
-{
- LLUUID curitemId = mInventoryId;
-
- if (mCurrentEdit && curitemId.notNull())
- {
- curitemId = LLFloaterSettingsPicker::findItemID(mCurrentEdit->getAssetId(), false, false);
- }
-
- doOpenInventoryFloater(LLSettingsType::ST_DAYCYCLE, curitemId);
-}
-
-
-void LLFloaterEditExtDayCycle::onClearTrack()
-{
- if (!mEditDay)
- {
- LL_WARNS("ENVDAYEDIT") << "Attempt to clear track while waiting for day(asset) to load." << LL_ENDL;
- return;
- }
-
- if (mCurrentTrack > 1)
- mEditDay->getCycleTrack(mCurrentTrack).clear();
- else
- {
- LLSettingsDay::CycleTrack_t &track(mEditDay->getCycleTrack(mCurrentTrack));
-
- auto first = track.begin();
- auto last = track.end();
- ++first;
- track.erase(first, last);
- }
-
- updateEditEnvironment();
- LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);
- LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
- synchronizeTabs();
- updateTabs();
- refresh();
-}
-
-void LLFloaterEditExtDayCycle::onCommitName(class LLLineEditor* caller, void* user_data)
-{
- if (!mEditDay)
- {
- LL_WARNS("ENVDAYEDIT") << "Attempt to rename day while waiting for day(asset) to load." << LL_ENDL;
- return;
- }
-
- mEditDay->setName(caller->getText());
-}
-
-void LLFloaterEditExtDayCycle::onTrackSelectionCallback(const LLSD& user_data)
-{
- U32 track_index = user_data.asInteger(); // 1-5
- selectTrack(track_index);
-}
-
-void LLFloaterEditExtDayCycle::onPlayActionCallback(const LLSD& user_data)
-{
- std::string action = user_data.asString();
-
- F32 frame = mTimeSlider->getCurSliderValue();
-
- if (action == ACTION_PLAY)
- {
- startPlay();
- }
- else if (action == ACTION_PAUSE)
- {
- stopPlay();
- }
- else if (mSliderKeyMap.size() != 0)
- {
- F32 new_frame = 0;
- if (action == ACTION_FORWARD)
- {
- new_frame = mEditDay->getUpperBoundFrame(mCurrentTrack, frame + (mTimeSlider->getIncrement() / 2));
- }
- else if (action == ACTION_BACK)
- {
- new_frame = mEditDay->getLowerBoundFrame(mCurrentTrack, frame - (mTimeSlider->getIncrement() / 2));
- }
- selectFrame(new_frame, 0.0f);
- stopPlay();
- }
-}
-
-void LLFloaterEditExtDayCycle::onFrameSliderCallback(const LLSD &data)
-{
- std::string curslider = mFramesSlider->getCurSlider();
-
- if (!curslider.empty() && mEditDay)
- {
- F32 sliderpos = mFramesSlider->getCurSliderValue();
-
- keymap_t::iterator it = mSliderKeyMap.find(curslider);
- if (it != mSliderKeyMap.end())
- {
- if (gKeyboard->currentMask(true) == MASK_SHIFT && mShiftCopyEnabled && mCanMod)
- {
- // don't move the point/frame as long as shift is pressed and user is attempting to copy
- // handleKeyUp will do the move if user releases key too early.
- if (!(mEditDay->getSettingsNearKeyframe(sliderpos, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
- {
- LL_DEBUGS("ENVDAYEDIT") << "Copying frame from " << it->second.mFrame << " to " << sliderpos << LL_ENDL;
- LLSettingsBase::ptr_t new_settings;
-
- // mEditDay still remembers old position, add copy at new position
- if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
- {
- LLSettingsWaterPtr_t water_ptr = std::dynamic_pointer_cast<LLSettingsWater>(it->second.pSettings)->buildClone();
- mEditDay->setWaterAtKeyframe(water_ptr, sliderpos);
- new_settings = water_ptr;
- }
- else
- {
- LLSettingsSkyPtr_t sky_ptr = std::dynamic_pointer_cast<LLSettingsSky>(it->second.pSettings)->buildClone();
- mEditDay->setSkyAtKeyframe(sky_ptr, sliderpos, mCurrentTrack);
- new_settings = sky_ptr;
- }
- // mSliderKeyMap still remembers old position, for simplicity, just move it to be identical to slider
- F32 old_frame = it->second.mFrame;
- it->second.mFrame = sliderpos;
- // slider already moved old frame, create new one in old place
- addSliderFrame(old_frame, new_settings, false /*because we are going to reselect new one*/);
- // reselect new frame
- mFramesSlider->setCurSlider(it->first);
- mShiftCopyEnabled = false;
- setDirtyFlag();
- }
- }
- else
- {
- // slider rounds values to nearest increments, changes can be substanntial (half increment)
- if (abs(mFramesSlider->getNearestIncrement((*it).second.mFrame) - sliderpos) < F_APPROXIMATELY_ZERO)
- {
- // same value
- mFramesSlider->setCurSliderValue((*it).second.mFrame);
- }
- else if (mEditDay->moveTrackKeyframe(mCurrentTrack, (*it).second.mFrame, sliderpos) && mCanMod)
- {
- (*it).second.mFrame = sliderpos;
- setDirtyFlag();
- }
- else
- {
- // same value, wrong track, no such value, no mod
- mFramesSlider->setCurSliderValue((*it).second.mFrame);
- }
-
- mShiftCopyEnabled = false;
- }
- }
- }
-}
-
-void LLFloaterEditExtDayCycle::onFrameSliderDoubleClick(S32 x, S32 y, MASK mask)
-{
- stopPlay();
- onAddFrame();
-}
-
-void LLFloaterEditExtDayCycle::onFrameSliderMouseDown(S32 x, S32 y, MASK mask)
-{
- stopPlay();
- F32 sliderpos = mFramesSlider->getSliderValueFromPos(x, y);
-
- std::string slidername = mFramesSlider->getCurSlider();
-
- mShiftCopyEnabled = !slidername.empty() && gKeyboard->currentMask(true) == MASK_SHIFT;
-
- if (!slidername.empty())
- {
- LLRect thumb_rect = mFramesSlider->getSliderThumbRect(slidername);
- if ((x >= thumb_rect.mRight) || (x <= thumb_rect.mLeft))
- {
- mFramesSlider->resetCurSlider();
- }
- }
-
- mTimeSlider->setCurSliderValue(sliderpos);
-
- updateTabs();
- LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
-}
-
-void LLFloaterEditExtDayCycle::onFrameSliderMouseUp(S32 x, S32 y, MASK mask)
-{
- // Only happens when clicking on empty space of frameslider, not on specific frame
- F32 sliderpos = mFramesSlider->getSliderValueFromPos(x, y);
-
- mTimeSlider->setCurSliderValue(sliderpos);
- selectFrame(sliderpos, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
-}
-
-void LLFloaterEditExtDayCycle::onTimeSliderCallback()
-{
- stopPlay();
- selectFrame(mTimeSlider->getCurSliderValue(), LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
-}
-
-void LLFloaterEditExtDayCycle::cloneTrack(U32 source_index, U32 dest_index)
-{
- cloneTrack(mEditDay, source_index, dest_index);
-}
-
-void LLFloaterEditExtDayCycle::cloneTrack(const LLSettingsDay::ptr_t &source_day, U32 source_index, U32 dest_index)
-{
- if ((source_index == LLSettingsDay::TRACK_WATER || dest_index == LLSettingsDay::TRACK_WATER) && (source_index != dest_index))
- { // one of the tracks is a water track, the other is not
- LLSD args;
-
- LL_WARNS() << "Can not import water track into sky track or vice versa" << LL_ENDL;
-
- LLButton* button = getChild<LLButton>(track_tabs[source_index], true);
- args["TRACK1"] = button->getCurrentLabel();
- button = getChild<LLButton>(track_tabs[dest_index], true);
- args["TRACK2"] = button->getCurrentLabel();
-
- LLNotificationsUtil::add("TrackLoadMismatch", args);
- return;
- }
-
- // don't use replaceCycleTrack because we will end up with references, but we need to clone
-
- // hold on to a backup of the
- LLSettingsDay::CycleTrack_t backup_track = mEditDay->getCycleTrack(dest_index);
-
- mEditDay->clearCycleTrack(dest_index); // because source can be empty
- LLSettingsDay::CycleTrack_t source_track = source_day->getCycleTrack(source_index);
- S32 addcount(0);
- for (auto &track_frame : source_track)
- {
- LLSettingsBase::ptr_t pframe = track_frame.second;
- LLSettingsBase::ptr_t pframeclone = pframe->buildDerivedClone();
- if (pframeclone)
- {
- ++addcount;
- mEditDay->setSettingsAtKeyframe(pframeclone, track_frame.first, dest_index);
- }
- }
-
- if (!addcount)
- { // nothing was actually added. Restore the old track and issue a warning.
- mEditDay->replaceCycleTrack(dest_index, backup_track);
-
- LLSD args;
- LLButton* button = getChild<LLButton>(track_tabs[dest_index], true);
- args["TRACK"] = button->getCurrentLabel();
-
- LLNotificationsUtil::add("TrackLoadFailed", args);
- }
- setDirtyFlag();
-
- updateSlider();
- updateTabs();
- updateButtons();
-}
-
-void LLFloaterEditExtDayCycle::selectTrack(U32 track_index, bool force )
-{
- if (track_index < LLSettingsDay::TRACK_MAX)
- mCurrentTrack = track_index;
-
- LLButton* button = getChild<LLButton>(track_tabs[mCurrentTrack], true);
- if (button->getToggleState() && !force)
- {
- return;
- }
-
- for (U32 i = 0; i < LLSettingsDay::TRACK_MAX; i++) // use max value
- {
- getChild<LLButton>(track_tabs[i], true)->setToggleState(i == mCurrentTrack);
- }
-
- bool show_water = (mCurrentTrack == LLSettingsDay::TRACK_WATER);
- mSkyTabLayoutContainer->setVisible(!show_water);
- mWaterTabLayoutContainer->setVisible(show_water);
-
- updateSlider();
- updateLabels();
-}
-
-void LLFloaterEditExtDayCycle::selectFrame(F32 frame, F32 slop_factor)
-{
- mFramesSlider->resetCurSlider();
-
- keymap_t::iterator iter = mSliderKeyMap.begin();
- keymap_t::iterator end_iter = mSliderKeyMap.end();
- while (iter != end_iter)
- {
- F32 keyframe = iter->second.mFrame;
- F32 frame_dif = fabs(keyframe - frame);
- if (frame_dif <= slop_factor)
- {
- keymap_t::iterator next_iter = std::next(iter);
- if ((frame_dif != 0) && (next_iter != end_iter))
- {
- if (fabs(next_iter->second.mFrame - frame) < frame_dif)
- {
- mFramesSlider->setCurSlider(next_iter->first);
- frame = next_iter->second.mFrame;
- break;
- }
- }
- mFramesSlider->setCurSlider(iter->first);
- frame = iter->second.mFrame;
- break;
- }
- iter++;
- }
-
- mTimeSlider->setCurSliderValue(frame);
- // block or update tabs according to new selection
- updateTabs();
-// LLEnvironment::instance().updateEnvironment();
-}
-
-void LLFloaterEditExtDayCycle::clearTabs()
-{
- // Note: If this doesn't look good, init panels with default settings. It might be better looking
- if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
- {
- const LLSettingsWaterPtr_t p_water = LLSettingsWaterPtr_t(NULL);
- updateWaterTabs(p_water);
- }
- else
- {
- const LLSettingsSkyPtr_t p_sky = LLSettingsSkyPtr_t(NULL);
- updateSkyTabs(p_sky);
- }
- updateButtons();
- updateTimeAndLabel();
-}
-
-void LLFloaterEditExtDayCycle::updateTabs()
-{
- reblendSettings();
- synchronizeTabs();
-
- updateButtons();
- updateTimeAndLabel();
-}
-
-void LLFloaterEditExtDayCycle::updateWaterTabs(const LLSettingsWaterPtr_t &p_water)
-{
- LLView* tab_container = mWaterTabLayoutContainer->getChild<LLView>(TABS_WATER); //can't extract panels directly, since it is in 'tuple'
- LLPanelSettingsWaterMainTab* panel = dynamic_cast<LLPanelSettingsWaterMainTab*>(tab_container->findChildView("water_panel"));
- if (panel)
- {
- panel->setWater(p_water);
- }
-}
-
-void LLFloaterEditExtDayCycle::updateSkyTabs(const LLSettingsSkyPtr_t &p_sky)
-{
- LLTabContainer* tab_container = mSkyTabLayoutContainer->getChild<LLTabContainer>(TABS_SKYS); //can't extract panels directly, since they are in 'tuple'
-
- LLPanelSettingsSky* panel;
- panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->findChildView("atmosphere_panel"));
- if (panel)
- {
- panel->setSky(p_sky);
- }
- panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->findChildView("clouds_panel"));
- if (panel)
- {
- panel->setSky(p_sky);
- }
- panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->findChildView("moon_panel"));
- if (panel)
- {
- panel->setSky(p_sky);
- }
-}
-
-void LLFloaterEditExtDayCycle::updateLabels()
-{
- std::string label_arg = (mCurrentTrack == LLSettingsDay::TRACK_WATER) ? "water_label" : "sky_label";
-
- mAddFrameButton->setLabelArg("[FRAME]", getString(label_arg));
- mDeleteFrameButton->setLabelArg("[FRAME]", getString(label_arg));
- mLoadFrame->setLabelArg("[FRAME]", getString(label_arg));
-}
-
-void LLFloaterEditExtDayCycle::updateButtons()
-{
- // This logic appears to work in reverse, the add frame button
- // is only enabled when you're on an existing frame and disabled
- // in all the interim positions where you'd want to add a frame...
-
- bool can_manipulate = mEditDay && !mIsPlaying && mCanMod;
- bool can_clone(false);
- bool can_clear(false);
-
- if (can_manipulate)
- {
- if (mCurrentTrack == 0)
- {
- can_clone = false;
- }
- else
- {
- for (S32 track = 1; track < LLSettingsDay::TRACK_MAX; ++track)
- {
- if (track == mCurrentTrack)
- continue;
- can_clone |= !mEditDay->getCycleTrack(track).empty();
- }
- }
-
- can_clear = (mCurrentTrack > 1) ? (!mEditDay->getCycleTrack(mCurrentTrack).empty()) : (mEditDay->getCycleTrack(mCurrentTrack).size() > 1);
- }
-
- mCloneTrack->setEnabled(can_clone);
- mLoadTrack->setEnabled(can_manipulate);
- mClearTrack->setEnabled(can_clear);
- mAddFrameButton->setEnabled(can_manipulate && isAddingFrameAllowed());
- mDeleteFrameButton->setEnabled(can_manipulate && isRemovingFrameAllowed());
- mLoadFrame->setEnabled(can_manipulate);
-
- bool enable_play = (bool)mEditDay;
- childSetEnabled(BTN_PLAY, enable_play);
- childSetEnabled(BTN_SKIP_BACK, enable_play);
- childSetEnabled(BTN_SKIP_FORWARD, enable_play);
-
- // update track buttons
- bool extended_env = LLEnvironment::instance().isExtendedEnvironmentEnabled();
- for (S32 track = 0; track < LLSettingsDay::TRACK_MAX; ++track)
- {
- LLButton* button = getChild<LLButton>(track_tabs[track], true);
- button->setEnabled(extended_env);
- button->setToggleState(track == mCurrentTrack);
- }
-}
-
-void LLFloaterEditExtDayCycle::updateSlider()
-{
- F32 frame_position = mTimeSlider->getCurSliderValue();
- mFramesSlider->clear();
- mSliderKeyMap.clear();
-
- if (!mEditDay)
- {
- // floater is waiting for asset
- return;
- }
-
- LLSettingsDay::CycleTrack_t track = mEditDay->getCycleTrack(mCurrentTrack);
- for (auto &track_frame : track)
- {
- addSliderFrame(track_frame.first, track_frame.second, false);
- }
-
- if (mSliderKeyMap.size() > 0)
- {
- // update positions
- mLastFrameSlider = mFramesSlider->getCurSlider();
- }
- else
- {
- // disable panels
- clearTabs();
- mLastFrameSlider.clear();
- }
-
- selectFrame(frame_position, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
-}
-
-void LLFloaterEditExtDayCycle::updateTimeAndLabel()
-{
- F32 time = mTimeSlider->getCurSliderValue();
- mCurrentTimeLabel->setTextArg("[PRCNT]", llformat("%.0f", time * 100));
- if (mDayLength.value() != 0)
- {
- LLUIString formatted_label = getString("time_label");
-
- LLSettingsDay::Seconds total = (mDayLength * time);
- S32Hours hrs = total;
- S32Minutes minutes = total - hrs;
-
- formatted_label.setArg("[HH]", llformat("%d", hrs.value()));
- formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value())));
- mCurrentTimeLabel->setTextArg("[DSC]", formatted_label.getString());
- }
- else
- {
- mCurrentTimeLabel->setTextArg("[DSC]", std::string());
- }
-
- // Update blender here:
-}
-
-void LLFloaterEditExtDayCycle::addSliderFrame(F32 frame, const LLSettingsBase::ptr_t &setting, bool update_ui)
-{
- // multi slider distinguishes elements by key/name in string format
- // store names to map to be able to recall dependencies
- std::string new_slider = mFramesSlider->addSlider(frame);
- if (!new_slider.empty())
- {
- mSliderKeyMap[new_slider] = FrameData(frame, setting);
-
- if (update_ui)
- {
- mLastFrameSlider = new_slider;
- mTimeSlider->setCurSliderValue(frame);
- updateTabs();
- }
- }
-}
-
-void LLFloaterEditExtDayCycle::removeCurrentSliderFrame()
-{
- std::string sldr = mFramesSlider->getCurSlider();
- if (sldr.empty())
- {
- return;
- }
- mFramesSlider->deleteCurSlider();
- keymap_t::iterator iter = mSliderKeyMap.find(sldr);
- if (iter != mSliderKeyMap.end())
- {
- LL_DEBUGS("ENVDAYEDIT") << "Removing frame from " << iter->second.mFrame << LL_ENDL;
- LLSettingsBase::Seconds seconds(iter->second.mFrame);
- mEditDay->removeTrackKeyframe(mCurrentTrack, seconds);
- mSliderKeyMap.erase(iter);
- }
-
- mLastFrameSlider = mFramesSlider->getCurSlider();
- mTimeSlider->setCurSliderValue(mFramesSlider->getCurSliderValue());
- updateTabs();
-}
-
-void LLFloaterEditExtDayCycle::removeSliderFrame(F32 frame)
-{
- keymap_t::iterator it = std::find_if(mSliderKeyMap.begin(), mSliderKeyMap.end(),
- [frame](const keymap_t::value_type &value) { return fabs(value.second.mFrame - frame) < LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR; });
-
- if (it != mSliderKeyMap.end())
- {
- mFramesSlider->deleteSlider((*it).first);
- mSliderKeyMap.erase(it);
- }
-
-}
-
-//-------------------------------------------------------------------------
-
-LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSignal(LLFloaterEditExtDayCycle::edit_commit_signal_t::slot_type cb)
-{
- return mCommitSignal.connect(cb);
-}
-
-void LLFloaterEditExtDayCycle::updateEditEnvironment(void)
-{
- if (!mEditDay)
- return;
- S32 skytrack = (mCurrentTrack) ? mCurrentTrack : 1;
- mSkyBlender = std::make_shared<LLTrackBlenderLoopingManual>(mScratchSky, mEditDay, skytrack);
- mWaterBlender = std::make_shared<LLTrackBlenderLoopingManual>(mScratchWater, mEditDay, LLSettingsDay::TRACK_WATER);
-
- if (LLEnvironment::instance().isExtendedEnvironmentEnabled())
- {
- selectTrack(LLSettingsDay::TRACK_MAX, true);
- }
- else
- {
- selectTrack(1, true);
- }
-
- reblendSettings();
-
- LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mEditSky, mEditWater);
- LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
-}
-
-void LLFloaterEditExtDayCycle::synchronizeTabs()
-{
- // This should probably get moved into "updateTabs"
- std::string curslider = mFramesSlider->getCurSlider();
- bool canedit(false);
-
- LLSettingsWater::ptr_t psettingW;
- LLTabContainer * tabs = mWaterTabLayoutContainer->getChild<LLTabContainer>(TABS_WATER);
- if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
- {
- if (!mEditDay)
- {
- canedit = false;
- }
- else if (!curslider.empty())
- {
- canedit = !mIsPlaying;
- // either search mEditDay or retrieve from mSliderKeyMap
- keymap_t::iterator slider_it = mSliderKeyMap.find(curslider);
- if (slider_it != mSliderKeyMap.end())
- {
- psettingW = std::static_pointer_cast<LLSettingsWater>(slider_it->second.pSettings);
- }
- }
- mCurrentEdit = psettingW;
- if (!psettingW)
- {
- canedit = false;
- psettingW = mScratchWater;
- }
-
- getChild<LLUICtrl>(ICN_LOCK_EDIT)->setVisible(!canedit);
- }
- else
- {
- psettingW = mScratchWater;
- }
- mEditWater = psettingW;
-
- setTabsData(tabs, psettingW, canedit);
-
- LLSettingsSky::ptr_t psettingS;
- canedit = false;
- tabs = mSkyTabLayoutContainer->getChild<LLTabContainer>(TABS_SKYS);
- if (mCurrentTrack != LLSettingsDay::TRACK_WATER)
- {
- if (!mEditDay)
- {
- canedit = false;
- }
- else if (!curslider.empty())
- {
- canedit = !mIsPlaying;
- // either search mEditDay or retrieve from mSliderKeyMap
- keymap_t::iterator slider_it = mSliderKeyMap.find(curslider);
- if (slider_it != mSliderKeyMap.end())
- {
- psettingS = std::static_pointer_cast<LLSettingsSky>(slider_it->second.pSettings);
- }
- }
- mCurrentEdit = psettingS;
- if (!psettingS)
- {
- canedit = false;
- psettingS = mScratchSky;
- }
-
- getChild<LLUICtrl>(ICN_LOCK_EDIT)->setVisible(!canedit);
- }
- else
- {
- psettingS = mScratchSky;
- }
- mEditSky = psettingS;
-
- doCloseInventoryFloater();
- doCloseTrackFloater();
-
- setTabsData(tabs, psettingS, canedit);
- LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mEditSky, mEditWater);
- LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
-}
-
-void LLFloaterEditExtDayCycle::setTabsData(LLTabContainer * tabcontainer, const LLSettingsBase::ptr_t &settings, bool editable)
-{
- S32 count = tabcontainer->getTabCount();
- for (S32 idx = 0; idx < count; ++idx)
- {
- LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tabcontainer->getPanelByIndex(idx));
- if (panel)
- {
- panel->setCanChangeSettings(editable & mCanMod);
- panel->setSettings(settings);
- }
- }
-}
-
-
-void LLFloaterEditExtDayCycle::reblendSettings()
-{
- F64 position = mTimeSlider->getCurSliderValue();
-
- if (mSkyBlender)
- {
- if ((mSkyBlender->getTrack() != mCurrentTrack) && (mCurrentTrack != LLSettingsDay::TRACK_WATER))
- {
- mSkyBlender->switchTrack(mCurrentTrack, position);
- }
- else
- {
- mSkyBlender->setPosition(position);
- }
- }
-
- if (mWaterBlender)
- {
- mWaterBlender->setPosition(position);
- }
-}
-
-void LLFloaterEditExtDayCycle::doApplyCommit(LLSettingsDay::ptr_t day)
-{
- if (!mCommitSignal.empty())
- {
- mCommitSignal(day);
-
- closeFloater();
- }
-}
-
-bool LLFloaterEditExtDayCycle::isRemovingFrameAllowed()
-{
- if (mFramesSlider->getCurSlider().empty()) return false;
-
- if (mCurrentTrack <= LLSettingsDay::TRACK_GROUND_LEVEL)
- {
- return (mSliderKeyMap.size() > 1);
- }
- else
- {
- return (mSliderKeyMap.size() > 0);
- }
-}
-
-bool LLFloaterEditExtDayCycle::isAddingFrameAllowed()
-{
- if (!mFramesSlider->getCurSlider().empty() || !mEditDay) return false;
-
- LLSettingsBase::Seconds frame(mTimeSlider->getCurSliderValue());
- if ((mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
- {
- return false;
- }
- return mFramesSlider->canAddSliders();
-}
-
-void LLFloaterEditExtDayCycle::doImportFromDisk()
-{ // Load a a legacy Windlight XML from disk.
- LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
-}
-
-void LLFloaterEditExtDayCycle::loadSettingFromFile(const std::vector<std::string>& filenames)
-{
- LLSD messages;
- if (filenames.size() < 1) return;
- std::string filename = filenames[0];
- LL_DEBUGS("ENVDAYEDIT") << "Selected file: " << filename << LL_ENDL;
- LLSettingsDay::ptr_t legacyday = LLEnvironment::createDayCycleFromLegacyPreset(filename, messages);
-
- if (!legacyday)
- {
- LLNotificationsUtil::add("WLImportFail", messages);
- return;
- }
-
- loadInventoryItem(LLUUID::null);
-
- mCurrentTrack = 1;
- setDirtyFlag();
- setEditDayCycle(legacyday);
-}
-
-void LLFloaterEditExtDayCycle::startPlay()
-{
- doCloseInventoryFloater();
- doCloseTrackFloater();
-
- mIsPlaying = true;
- mFramesSlider->resetCurSlider();
- mPlayTimer.reset();
- mPlayTimer.start();
- gIdleCallbacks.addFunction(onIdlePlay, this);
- mPlayStartFrame = mTimeSlider->getCurSliderValue();
-
- getChild<LLView>("play_layout", true)->setVisible(false);
- getChild<LLView>("pause_layout", true)->setVisible(true);
-}
-
-void LLFloaterEditExtDayCycle::stopPlay()
-{
- if (!mIsPlaying)
- return;
-
- mIsPlaying = false;
- gIdleCallbacks.deleteFunction(onIdlePlay, this);
- mPlayTimer.stop();
- F32 frame = mTimeSlider->getCurSliderValue();
- selectFrame(frame, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
-
- getChild<LLView>("play_layout", true)->setVisible(true);
- getChild<LLView>("pause_layout", true)->setVisible(false);
-}
-
-//static
-void LLFloaterEditExtDayCycle::onIdlePlay(void* user_data)
-{
- if (!gDisconnected)
- {
- LLFloaterEditExtDayCycle* self = (LLFloaterEditExtDayCycle*)user_data;
-
- if (self->mSkyBlender == nullptr || self->mWaterBlender == nullptr)
- {
- self->stopPlay();
- }
- else
- {
-
- F32 prcnt_played = self->mPlayTimer.getElapsedTimeF32() / DAY_CYCLE_PLAY_TIME_SECONDS;
- F32 new_frame = fmod(self->mPlayStartFrame + prcnt_played, 1.f);
-
- self->mTimeSlider->setCurSliderValue(new_frame); // will do the rounding
- self->mSkyBlender->setPosition(new_frame);
- self->mWaterBlender->setPosition(new_frame);
- self->synchronizeTabs();
- self->updateTimeAndLabel();
- self->updateButtons();
- }
- }
-}
-
-
-void LLFloaterEditExtDayCycle::clearDirtyFlag()
-{
- mIsDirty = false;
-
- LLTabContainer* tab_container = mSkyTabLayoutContainer->getChild<LLTabContainer>("sky_tabs");
- S32 tab_count = tab_container->getTabCount();
-
- for (S32 idx = 0; idx < tab_count; ++idx)
- {
- LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tab_container->getPanelByIndex(idx));
- if (panel)
- panel->clearIsDirty();
- }
-
- tab_container = mWaterTabLayoutContainer->getChild<LLTabContainer>("water_tabs");
- tab_count = tab_container->getTabCount();
-
- for (S32 idx = 0; idx < tab_count; ++idx)
- {
- LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tab_container->getPanelByIndex(idx));
- if (panel)
- panel->clearIsDirty();
- }
-
-}
-
-void LLFloaterEditExtDayCycle::doOpenTrackFloater(const LLSD &args)
-{
- LLFloaterTrackPicker *picker = static_cast<LLFloaterTrackPicker *>(mTrackFloater.get());
-
- // Show the dialog
- if (!picker)
- {
- picker = new LLFloaterTrackPicker(this);
-
- mTrackFloater = picker->getHandle();
-
- picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitTrackId(data.asInteger()); });
- }
-
- picker->showPicker(args);
-}
-
-void LLFloaterEditExtDayCycle::doCloseTrackFloater(bool quitting)
-{
- LLFloater* floaterp = mTrackFloater.get();
-
- if (floaterp)
- {
- floaterp->closeFloater(quitting);
- }
-}
-
-LLFloaterSettingsPicker * LLFloaterEditExtDayCycle::getSettingsPicker()
-{
- LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(mInventoryFloater.get());
-
- // Show the dialog
- if (!picker)
- {
- picker = new LLFloaterSettingsPicker(this,
- LLUUID::null);
-
- mInventoryFloater = picker->getHandle();
-
- picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data["ItemId"].asUUID(), data["Track"].asInteger()); });
- }
- return picker;
-}
-
-void LLFloaterEditExtDayCycle::onPickerCommitTrackId(U32 track_id)
-{
- cloneTrack(track_id, mCurrentTrack);
-}
-
-void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem)
-{
- LLFloaterSettingsPicker *picker = getSettingsPicker();
- picker->setSettingsFilter(type);
- picker->setSettingsItemId(curritem);
- if (type == LLSettingsType::ST_DAYCYCLE)
- {
- picker->setTrackMode((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLFloaterSettingsPicker::TRACK_WATER : LLFloaterSettingsPicker::TRACK_SKY);
- }
- else
- {
- picker->setTrackMode(LLFloaterSettingsPicker::TRACK_NONE);
- }
- picker->openFloater();
- picker->setFocus(true);
-}
-
-void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID item_id, S32 track)
-{
- LLSettingsBase::TrackPosition frame(mTimeSlider->getCurSliderValue());
- LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
- if (itemp)
- {
- LLSettingsVOBase::getSettingsAsset(itemp->getAssetUUID(),
- [this, track, frame, item_id](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoadedForInsertion(item_id, asset_id, settings, status, track, mCurrentTrack, frame); });
- }
-}
-
-void LLFloaterEditExtDayCycle::showHDRNotification(const LLSettingsDay::ptr_t &pday)
-{
- for (U32 i = LLSettingsDay::TRACK_GROUND_LEVEL; i <= LLSettingsDay::TRACK_MAX; i++)
- {
- LLSettingsDay::CycleTrack_t &day_track = pday->getCycleTrack(i);
-
- LLSettingsDay::CycleTrack_t::iterator iter = day_track.begin();
- LLSettingsDay::CycleTrack_t::iterator end = day_track.end();
-
- while (iter != end)
- {
- LLSettingsSky::ptr_t sky = std::static_pointer_cast<LLSettingsSky>(iter->second);
- if (sky
- && sky->canAutoAdjust()
- && sky->getReflectionProbeAmbiance(true) != 0.f)
- {
- LLNotificationsUtil::add("AutoAdjustHDRSky");
- return;
- }
- iter++;
- }
- }
-}
-
-void LLFloaterEditExtDayCycle::onAssetLoadedForInsertion(LLUUID item_id, LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 source_track, S32 dest_track, LLSettingsBase::TrackPosition frame)
-{
- std::function<void()> cb = [this, settings, frame, source_track, dest_track]()
- {
- if (settings->getSettingsType() == "daycycle")
- {
- // Load full track
- LLSettingsDay::ptr_t pday = std::dynamic_pointer_cast<LLSettingsDay>(settings);
- if (dest_track == LLSettingsDay::TRACK_WATER)
- {
- cloneTrack(pday, LLSettingsDay::TRACK_WATER, LLSettingsDay::TRACK_WATER);
- }
- else
- {
- cloneTrack(pday, source_track, dest_track);
- }
- }
- else
- {
- if (!mFramesSlider->canAddSliders())
- {
- LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame when slider is full." << LL_ENDL;
- return;
- }
-
- // load or replace single frame
- LLSettingsDay::CycleTrack_t::value_type nearest = mEditDay->getSettingsNearKeyframe(frame, dest_track, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
- if (nearest.first != LLSettingsDay::INVALID_TRACKPOS)
- { // There is already a frame near the target location. Remove it so we can put the new one in its place.
- mEditDay->removeTrackKeyframe(dest_track, nearest.first);
- removeSliderFrame(nearest.first);
- }
-
- // Don't forget to clone (we might reuse/load it couple times)
- if (settings->getSettingsType() == "sky")
- {
- // Load sky to frame
- if (dest_track != LLSettingsDay::TRACK_WATER)
- {
- mEditDay->setSettingsAtKeyframe(settings->buildDerivedClone(), frame, dest_track);
- addSliderFrame(frame, settings, false);
- }
- else
- {
- LL_WARNS("ENVDAYEDIT") << "Trying to load day settings as sky" << LL_ENDL;
- }
- }
- else if (settings->getSettingsType() == "water")
- {
- // Load water to frame
- if (dest_track == LLSettingsDay::TRACK_WATER)
- {
- mEditDay->setSettingsAtKeyframe(settings->buildDerivedClone(), frame, dest_track);
- addSliderFrame(frame, settings, false);
- }
- else
- {
- LL_WARNS("ENVDAYEDIT") << "Trying to load water settings as sky" << LL_ENDL;
- }
- }
- }
- reblendSettings();
- synchronizeTabs();
- };
-
- if (!settings || status)
- {
- LL_WARNS("ENVDAYEDIT") << "Could not load asset " << asset_id << " into frame. status=" << status << LL_ENDL;
- return;
- }
-
- if (!mEditDay)
- {
- // day got reset while we were waiting for response
- return;
- }
-
- LLInventoryItem *inv_item = gInventory.getItem(item_id);
-
- if (inv_item
- && (!inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())
- || !inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())))
- {
- // Need to check if item is already no-transfer, otherwise make it no-transfer
- bool no_transfer = false;
- if (mInventoryItem)
- {
- no_transfer = !mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
- }
- else
- {
- no_transfer = mEditDay->getFlag(LLSettingsBase::FLAG_NOTRANS);
- }
-
- if (!no_transfer)
- {
- LLSD args;
-
- // create and show confirmation textbox
- LLNotificationsUtil::add("SettingsMakeNoTrans", args, LLSD(),
- [this, cb](const LLSD&notif, const LLSD&resp)
- {
- S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
- if (opt == 0)
- {
- mCanTrans = false;
- mEditDay->setFlag(LLSettingsBase::FLAG_NOTRANS);
- cb();
- }
- });
- return;
- }
- }
-
- cb();
-}
+/**
+ * @file llfloatereditextdaycycle.cpp
+ * @brief Floater to create or edit a day cycle
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatereditextdaycycle.h"
+
+// libs
+#include "llbutton.h"
+#include "llcallbacklist.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llloadingindicator.h"
+#include "lllocalbitmaps.h"
+#include "llmultisliderctrl.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llspinctrl.h"
+#include "lltimectrl.h"
+#include "lltabcontainer.h"
+#include "llfilepicker.h"
+
+#include "llsettingsvo.h"
+#include "llinventorymodel.h"
+#include "llviewerparcelmgr.h"
+
+#include "llsettingspicker.h"
+#include "lltrackpicker.h"
+
+// newview
+#include "llagent.h"
+#include "llappviewer.h" //gDisconected
+#include "llparcel.h"
+#include "llflyoutcombobtn.h" //Todo: make a proper UI element/button/panel instead
+#include "llregioninfomodel.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
+#include "llviewerregion.h"
+#include "llpaneleditwater.h"
+#include "llpaneleditsky.h"
+
+#include "llui.h"
+
+#include "llenvironment.h"
+#include "lltrans.h"
+
+extern LLControlGroup gSavedSettings;
+
+//=========================================================================
+namespace {
+ const std::string track_tabs[] = {
+ "water_track",
+ "sky1_track",
+ "sky2_track",
+ "sky3_track",
+ "sky4_track",
+ };
+
+ const std::string ICN_LOCK_EDIT("icn_lock_edit");
+ const std::string BTN_SAVE("save_btn");
+ const std::string BTN_FLYOUT("btn_flyout");
+ const std::string BTN_CANCEL("cancel_btn");
+ const std::string BTN_ADDFRAME("add_frame");
+ const std::string BTN_DELFRAME("delete_frame");
+ const std::string BTN_IMPORT("btn_import");
+ const std::string BTN_LOADFRAME("btn_load_frame");
+ const std::string BTN_CLONETRACK("copy_track");
+ const std::string BTN_LOADTRACK("load_track");
+ const std::string BTN_CLEARTRACK("clear_track");
+ const std::string SLDR_TIME("WLTimeSlider");
+ const std::string SLDR_KEYFRAMES("WLDayCycleFrames");
+ const std::string VIEW_SKY_SETTINGS("frame_settings_sky");
+ const std::string VIEW_WATER_SETTINGS("frame_settings_water");
+ const std::string LBL_CURRENT_TIME("current_time");
+ const std::string TXT_DAY_NAME("day_cycle_name");
+ const std::string TABS_SKYS("sky_tabs");
+ const std::string TABS_WATER("water_tabs");
+
+ // 'Play' buttons
+ const std::string BTN_PLAY("play_btn");
+ const std::string BTN_SKIP_BACK("skip_back_btn");
+ const std::string BTN_SKIP_FORWARD("skip_forward_btn");
+
+ const std::string EVNT_DAYTRACK("DayCycle.Track");
+ const std::string EVNT_PLAY("DayCycle.PlayActions");
+
+ const std::string ACTION_PLAY("play");
+ const std::string ACTION_PAUSE("pause");
+ const std::string ACTION_FORWARD("forward");
+ const std::string ACTION_BACK("back");
+
+ // For flyout
+ const std::string XML_FLYOUTMENU_FILE("menu_save_settings.xml");
+ // From menu_save_settings.xml, consider moving into flyout since it should be supported by flyout either way
+ const std::string ACTION_SAVE("save_settings");
+ const std::string ACTION_SAVEAS("save_as_new_settings");
+ const std::string ACTION_COMMIT("commit_changes");
+ const std::string ACTION_APPLY_LOCAL("apply_local");
+ const std::string ACTION_APPLY_PARCEL("apply_parcel");
+ const std::string ACTION_APPLY_REGION("apply_region");
+
+ const F32 DAY_CYCLE_PLAY_TIME_SECONDS = 60;
+
+ const std::string STR_COMMIT_PARCEL("commit_parcel");
+ const std::string STR_COMMIT_REGION("commit_region");
+ //---------------------------------------------------------------------
+
+}
+
+//=========================================================================
+const std::string LLFloaterEditExtDayCycle::KEY_EDIT_CONTEXT("edit_context");
+const std::string LLFloaterEditExtDayCycle::KEY_DAY_LENGTH("day_length");
+const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod");
+
+const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_INVENTORY("inventory");
+const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_PARCEL("parcel");
+const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_REGION("region");
+/*
+//=========================================================================
+
+class LLDaySettingCopiedCallback : public LLInventoryCallback
+{
+public:
+ LLDaySettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {}
+
+ virtual void fire(const LLUUID& inv_item_id)
+ {
+ if (!mHandle.isDead())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+ if (item)
+ {
+ LLFloaterEditExtDayCycle* floater = (LLFloaterEditExtDayCycle*)mHandle.get();
+ floater->onInventoryCreated(item->getAssetUUID(), inv_item_id);
+ }
+ }
+ }
+
+private:
+ LLHandle<LLFloater> mHandle;
+};*/
+
+//=========================================================================
+
+LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) :
+ LLFloaterEditEnvironmentBase(key),
+ mFlyoutControl(nullptr),
+ mDayLength(0),
+ mCurrentTrack(1),
+ mShiftCopyEnabled(false),
+ mTimeSlider(nullptr),
+ mFramesSlider(nullptr),
+ mCurrentTimeLabel(nullptr),
+ mImportButton(nullptr),
+ mLoadFrame(nullptr),
+ mSkyBlender(),
+ mWaterBlender(),
+ mScratchSky(),
+ mScratchWater(),
+ mIsPlaying(false),
+ mCloneTrack(nullptr),
+ mLoadTrack(nullptr),
+ mClearTrack(nullptr)
+{
+
+ mCommitCallbackRegistrar.add(EVNT_DAYTRACK, [this](LLUICtrl *ctrl, const LLSD &data) { onTrackSelectionCallback(data); });
+ mCommitCallbackRegistrar.add(EVNT_PLAY, [this](LLUICtrl *ctrl, const LLSD &data) { onPlayActionCallback(data); });
+
+ mScratchSky = LLSettingsVOSky::buildDefaultSky();
+ mScratchWater = LLSettingsVOWater::buildDefaultWater();
+
+ mEditSky = mScratchSky;
+ mEditWater = mScratchWater;
+}
+
+LLFloaterEditExtDayCycle::~LLFloaterEditExtDayCycle()
+{
+ // Todo: consider remaking mFlyoutControl into full view class that initializes intself with floater,
+ // complete with postbuild, e t c...
+ delete mFlyoutControl;
+}
+
+// virtual
+bool LLFloaterEditExtDayCycle::postBuild()
+{
+ getChild<LLLineEditor>(TXT_DAY_NAME)->setKeystrokeCallback(boost::bind(&LLFloaterEditExtDayCycle::onCommitName, this, _1, _2), NULL);
+
+ mAddFrameButton = getChild<LLButton>(BTN_ADDFRAME, true);
+ mDeleteFrameButton = getChild<LLButton>(BTN_DELFRAME, true);
+ mTimeSlider = getChild<LLMultiSliderCtrl>(SLDR_TIME);
+ mFramesSlider = getChild<LLMultiSliderCtrl>(SLDR_KEYFRAMES);
+ mSkyTabLayoutContainer = getChild<LLView>(VIEW_SKY_SETTINGS, true);
+ mWaterTabLayoutContainer = getChild<LLView>(VIEW_WATER_SETTINGS, true);
+ mCurrentTimeLabel = getChild<LLTextBox>(LBL_CURRENT_TIME, true);
+ mImportButton = getChild<LLButton>(BTN_IMPORT, true);
+ mLoadFrame = getChild<LLButton>(BTN_LOADFRAME, true);
+ mCloneTrack = getChild<LLButton>(BTN_CLONETRACK, true);
+ mLoadTrack = getChild<LLButton>(BTN_LOADTRACK, true);
+ mClearTrack = getChild<LLButton>(BTN_CLEARTRACK, true);
+
+ mFlyoutControl = new LLFlyoutComboBtnCtrl(this, BTN_SAVE, BTN_FLYOUT, XML_FLYOUTMENU_FILE, false);
+ mFlyoutControl->setAction([this](LLUICtrl *ctrl, const LLSD &data) { onButtonApply(ctrl, data); });
+
+ getChild<LLButton>(BTN_CANCEL, true)->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onClickCloseBtn(); });
+ mTimeSlider->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onTimeSliderCallback(); });
+ mAddFrameButton->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onAddFrame(); });
+ mDeleteFrameButton->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onRemoveFrame(); });
+ mImportButton->setCommitCallback([this](LLUICtrl *, const LLSD &){ onButtonImport(); });
+ mLoadFrame->setCommitCallback([this](LLUICtrl *, const LLSD &){ onButtonLoadFrame(); });
+
+ mCloneTrack->setCommitCallback([this](LLUICtrl *, const LLSD&){ onCloneTrack(); });
+ mLoadTrack->setCommitCallback([this](LLUICtrl *, const LLSD&){ onLoadTrack();});
+ mClearTrack->setCommitCallback([this](LLUICtrl *, const LLSD&){ onClearTrack(); });
+
+
+ mFramesSlider->setCommitCallback([this](LLUICtrl *, const LLSD &data) { onFrameSliderCallback(data); });
+ mFramesSlider->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderDoubleClick(x, y, mask); });
+ mFramesSlider->setMouseDownCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderMouseDown(x, y, mask); });
+ mFramesSlider->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderMouseUp(x, y, mask); });
+
+ mTimeSlider->addSlider(0);
+
+ LLTabContainer* tab_container = mSkyTabLayoutContainer->getChild<LLTabContainer>("sky_tabs");
+ S32 tab_count = tab_container->getTabCount();
+
+ LLSettingsEditPanel *panel = nullptr;
+
+ for (S32 idx = 0; idx < tab_count; ++idx)
+ {
+ panel = static_cast<LLSettingsEditPanel *>(tab_container->getPanelByIndex(idx));
+ if (panel)
+ panel->setOnDirtyFlagChanged([this](LLPanel *, bool val) { onPanelDirtyFlagChanged(val); });
+ }
+
+ tab_container = mWaterTabLayoutContainer->getChild<LLTabContainer>("water_tabs");
+ tab_count = tab_container->getTabCount();
+
+ for (S32 idx = 0; idx < tab_count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tab_container->getPanelByIndex(idx));
+ if (panel)
+ panel->setOnDirtyFlagChanged([this](LLPanel *, bool val) { onPanelDirtyFlagChanged(val); });
+ }
+
+ return true;
+}
+
+void LLFloaterEditExtDayCycle::onOpen(const LLSD& key)
+{
+ if (!mEditDay)
+ {
+ LLEnvironment::instance().saveBeaconsState();
+ }
+ mEditDay.reset();
+ mEditContext = CONTEXT_UNKNOWN;
+ if (key.has(KEY_EDIT_CONTEXT))
+ {
+ std::string context = key[KEY_EDIT_CONTEXT].asString();
+
+ if (context == VALUE_CONTEXT_INVENTORY)
+ mEditContext = CONTEXT_INVENTORY;
+ else if (context == VALUE_CONTEXT_PARCEL)
+ mEditContext = CONTEXT_PARCEL;
+ else if (context == VALUE_CONTEXT_REGION)
+ mEditContext = CONTEXT_REGION;
+ }
+
+ if (key.has(KEY_CANMOD))
+ {
+ mCanMod = key[KEY_CANMOD].asBoolean();
+ }
+
+ if (mEditContext == CONTEXT_UNKNOWN)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Unknown editing context!" << LL_ENDL;
+ }
+
+ if (key.has(KEY_INVENTORY_ID))
+ {
+ loadInventoryItem(key[KEY_INVENTORY_ID].asUUID());
+ }
+ else
+ {
+ mCanSave = true;
+ mCanCopy = true;
+ mCanMod = true;
+ mCanTrans = true;
+ setEditDefaultDayCycle();
+ }
+
+ mDayLength.value(0);
+ if (key.has(KEY_DAY_LENGTH))
+ {
+ mDayLength.value(key[KEY_DAY_LENGTH].asReal());
+ }
+
+ // Time&Percentage labels
+ mCurrentTimeLabel->setTextArg("[PRCNT]", std::string("0"));
+ const S32 max_elm = 5;
+ if (mDayLength.value() != 0)
+ {
+ S32Hours hrs;
+ S32Minutes minutes;
+ LLSettingsDay::Seconds total;
+ LLUIString formatted_label = getString("time_label");
+ for (int i = 0; i < max_elm; i++)
+ {
+ total = ((mDayLength / (max_elm - 1)) * i);
+ hrs = total;
+ minutes = total - hrs;
+
+ formatted_label.setArg("[HH]", llformat("%d", hrs.value()));
+ formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value())));
+ getChild<LLTextBox>("p" + llformat("%d", i), true)->setTextArg("[DSC]", formatted_label.getString());
+ }
+ hrs = mDayLength;
+ minutes = mDayLength - hrs;
+ formatted_label.setArg("[HH]", llformat("%d", hrs.value()));
+ formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value())));
+ mCurrentTimeLabel->setTextArg("[DSC]", formatted_label.getString());
+ }
+ else
+ {
+ for (int i = 0; i < max_elm; i++)
+ {
+ getChild<LLTextBox>("p" + llformat("%d", i), true)->setTextArg("[DSC]", std::string());
+ }
+ mCurrentTimeLabel->setTextArg("[DSC]", std::string());
+ }
+
+ // Adjust Time&Percentage labels' location according to length
+ LLRect label_rect = getChild<LLTextBox>("p0", true)->getRect();
+ F32 slider_width = mFramesSlider->getRect().getWidth();
+ for (int i = 1; i < max_elm; i++)
+ {
+ LLTextBox *pcnt_label = getChild<LLTextBox>("p" + llformat("%d", i), true);
+ LLRect new_rect = pcnt_label->getRect();
+ new_rect.mLeft = label_rect.mLeft + (S32)(slider_width * (F32)i / (F32)(max_elm - 1)) - (S32)(pcnt_label->getTextPixelWidth() / 2);
+ pcnt_label->setRect(new_rect);
+ }
+
+ // Altitudes&Track labels
+ LLUIString formatted_label = getString("sky_track_label");
+ const LLEnvironment::altitude_list_t &altitudes = LLEnvironment::instance().getRegionAltitudes();
+ bool extended_env = LLEnvironment::instance().isExtendedEnvironmentEnabled();
+ bool use_altitudes = extended_env
+ && altitudes.size() > 0
+ && ((mEditContext == CONTEXT_PARCEL) || (mEditContext == CONTEXT_REGION));
+ for (S32 idx = 1; idx < 4; ++idx)
+ {
+ std::ostringstream convert;
+ if (use_altitudes)
+ {
+ convert << altitudes[idx] << "m";
+ }
+ else
+ {
+ convert << (idx + 1);
+ }
+ formatted_label.setArg("[ALT]", convert.str());
+ getChild<LLButton>(track_tabs[idx + 1], true)->setLabel(formatted_label.getString());
+ }
+
+ for (U32 i = 2; i < LLSettingsDay::TRACK_MAX; i++) //skies #2 through #4
+ {
+ getChild<LLButton>(track_tabs[i])->setEnabled(extended_env);
+ }
+
+ if (mEditContext == CONTEXT_INVENTORY)
+ {
+ mFlyoutControl->setShownBtnEnabled(true);
+ mFlyoutControl->setSelectedItem(ACTION_SAVE);
+ }
+ else if ((mEditContext == CONTEXT_REGION) || (mEditContext == CONTEXT_PARCEL))
+ {
+ std::string commit_str = (mEditContext == CONTEXT_PARCEL) ? STR_COMMIT_PARCEL : STR_COMMIT_REGION;
+ mFlyoutControl->setMenuItemLabel(ACTION_COMMIT, getString(commit_str));
+ mFlyoutControl->setShownBtnEnabled(true);
+ mFlyoutControl->setSelectedItem(ACTION_COMMIT);
+ }
+ else
+ {
+ mFlyoutControl->setShownBtnEnabled(false);
+ }
+}
+
+void LLFloaterEditExtDayCycle::onClose(bool app_quitting)
+{
+ doCloseInventoryFloater(app_quitting);
+ doCloseTrackFloater(app_quitting);
+ // there's no point to change environment if we're quitting
+ // or if we already restored environment
+ stopPlay();
+ LLEnvironment::instance().revertBeaconsState();
+ if (!app_quitting)
+ {
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_FAST);
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
+ mEditDay.reset();
+ }
+}
+
+
+void LLFloaterEditExtDayCycle::onVisibilityChange(bool new_visibility)
+{
+}
+
+void LLFloaterEditExtDayCycle::refresh()
+{
+ if (mEditDay)
+ {
+ LLLineEditor* name_field = getChild<LLLineEditor>(TXT_DAY_NAME);
+ name_field->setText(mEditDay->getName());
+ name_field->setEnabled(mCanMod);
+ }
+
+
+ bool is_inventory_avail = canUseInventory();
+
+ bool show_commit = ((mEditContext == CONTEXT_PARCEL) || (mEditContext == CONTEXT_REGION));
+ bool show_apply = (mEditContext == CONTEXT_INVENTORY);
+
+ if (show_commit)
+ {
+ std::string commit_text;
+ if (mEditContext == CONTEXT_PARCEL)
+ commit_text = getString(STR_COMMIT_PARCEL);
+ else
+ commit_text = getString(STR_COMMIT_REGION);
+
+ mFlyoutControl->setMenuItemLabel(ACTION_COMMIT, commit_text);
+ }
+
+ mFlyoutControl->setMenuItemVisible(ACTION_COMMIT, show_commit);
+ mFlyoutControl->setMenuItemVisible(ACTION_SAVE, is_inventory_avail);
+ mFlyoutControl->setMenuItemVisible(ACTION_SAVEAS, is_inventory_avail);
+ mFlyoutControl->setMenuItemVisible(ACTION_APPLY_LOCAL, true);
+ mFlyoutControl->setMenuItemVisible(ACTION_APPLY_PARCEL, show_apply);
+ mFlyoutControl->setMenuItemVisible(ACTION_APPLY_REGION, show_apply);
+
+ mFlyoutControl->setMenuItemEnabled(ACTION_COMMIT, show_commit && !mCommitSignal.empty());
+ mFlyoutControl->setMenuItemEnabled(ACTION_SAVE, is_inventory_avail && mCanMod && !mInventoryId.isNull() && mCanSave);
+ mFlyoutControl->setMenuItemEnabled(ACTION_SAVEAS, is_inventory_avail && mCanCopy && mCanSave);
+ mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_LOCAL, true);
+ mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_PARCEL, canApplyParcel() && show_apply);
+ mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_REGION, canApplyRegion() && show_apply);
+
+ mImportButton->setEnabled(mCanMod);
+
+ LLFloater::refresh();
+}
+
+void LLFloaterEditExtDayCycle::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings)
+{
+ setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings));
+
+ showHDRNotification(std::dynamic_pointer_cast<LLSettingsDay>(settings));
+}
+
+void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday)
+{
+ mExpectingAssetId.setNull();
+ mEditDay = pday->buildDeepCloneAndUncompress();
+
+ if (mEditDay->isTrackEmpty(LLSettingsDay::TRACK_WATER))
+ {
+ LL_WARNS("ENVDAYEDIT") << "No water frames found, generating replacement" << LL_ENDL;
+ mEditDay->setWaterAtKeyframe(LLSettingsVOWater::buildDefaultWater(), .5f);
+ }
+
+ if (mEditDay->isTrackEmpty(LLSettingsDay::TRACK_GROUND_LEVEL))
+ {
+ LL_WARNS("ENVDAYEDIT") << "No sky frames found, generating replacement" << LL_ENDL;
+ mEditDay->setSkyAtKeyframe(LLSettingsVOSky::buildDefaultSky(), .5f, LLSettingsDay::TRACK_GROUND_LEVEL);
+ }
+
+ mCanSave = !pday->getFlag(LLSettingsBase::FLAG_NOSAVE);
+ mCanCopy = !pday->getFlag(LLSettingsBase::FLAG_NOCOPY) && mCanSave;
+ mCanMod = !pday->getFlag(LLSettingsBase::FLAG_NOMOD) && mCanSave;
+ mCanTrans = !pday->getFlag(LLSettingsBase::FLAG_NOTRANS) && mCanSave;
+
+ updateEditEnvironment();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ synchronizeTabs();
+ updateTabs();
+ refresh();
+}
+
+
+void LLFloaterEditExtDayCycle::setEditDefaultDayCycle()
+{
+ mInventoryItem = nullptr;
+ mInventoryId.setNull();
+ mExpectingAssetId = LLSettingsDay::GetDefaultAssetId();
+ LLSettingsVOBase::getSettingsAsset(LLSettingsDay::GetDefaultAssetId(),
+ [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
+}
+
+std::string LLFloaterEditExtDayCycle::getEditName() const
+{
+ if (mEditDay)
+ return mEditDay->getName();
+ return "new";
+}
+
+void LLFloaterEditExtDayCycle::setEditName(const std::string &name)
+{
+ if (mEditDay)
+ mEditDay->setName(name);
+ getChild<LLLineEditor>(TXT_DAY_NAME)->setText(name);
+}
+
+/* virtual */
+bool LLFloaterEditExtDayCycle::handleKeyUp(KEY key, MASK mask, bool called_from_parent)
+{
+ if (!mEditDay)
+ {
+ mShiftCopyEnabled = false;
+ }
+ else if (mask == MASK_SHIFT && mShiftCopyEnabled)
+ {
+ mShiftCopyEnabled = false;
+ std::string curslider = mFramesSlider->getCurSlider();
+ if (!curslider.empty())
+ {
+ F32 sliderpos = mFramesSlider->getCurSliderValue();
+
+ keymap_t::iterator it = mSliderKeyMap.find(curslider);
+ if (it != mSliderKeyMap.end())
+ {
+ if (mEditDay->moveTrackKeyframe(mCurrentTrack, (*it).second.mFrame, sliderpos))
+ {
+ (*it).second.mFrame = sliderpos;
+ }
+ else
+ {
+ mFramesSlider->setCurSliderValue((*it).second.mFrame);
+ }
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Failed to find frame " << sliderpos << " for slider " << curslider << LL_ENDL;
+ }
+ }
+ }
+ return LLFloater::handleKeyUp(key, mask, called_from_parent);
+}
+
+void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
+{
+ std::string ctrl_action = ctrl->getName();
+
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "mEditDay is null! This should never happen! Something is very very wrong" << LL_ENDL;
+ LLNotificationsUtil::add("EnvironmentApplyFailed");
+ closeFloater();
+ return;
+ }
+
+ LLSettingsDay::ptr_t dayclone = mEditDay->buildClone(); // create a compressed copy
+
+ if (!dayclone)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Unable to clone daycylce from editor." << LL_ENDL;
+ return;
+ }
+
+ // brute-force local texture scan
+ for (U32 i = 0; i <= LLSettingsDay::TRACK_MAX; i++)
+ {
+ LLSettingsDay::CycleTrack_t &day_track = dayclone->getCycleTrack(i);
+
+ LLSettingsDay::CycleTrack_t::iterator iter = day_track.begin();
+ LLSettingsDay::CycleTrack_t::iterator end = day_track.end();
+ S32 frame_num = 0;
+
+ while (iter != end)
+ {
+ frame_num++;
+ std::string desc;
+ bool is_local = false; // because getString can be empty
+ if (i == LLSettingsDay::TRACK_WATER)
+ {
+ LLSettingsWater::ptr_t water = std::static_pointer_cast<LLSettingsWater>(iter->second);
+ if (water)
+ {
+ // LLViewerFetchedTexture and check for FTT_LOCAL_FILE or check LLLocalBitmapMgr
+ if (LLLocalBitmapMgr::getInstance()->isLocal(water->getNormalMapID()))
+ {
+ desc = LLTrans::getString("EnvironmentNormalMap");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(water->getTransparentTextureID()))
+ {
+ desc = LLTrans::getString("EnvironmentTransparent");
+ is_local = true;
+ }
+ }
+ }
+ else
+ {
+ LLSettingsSky::ptr_t sky = std::static_pointer_cast<LLSettingsSky>(iter->second);
+ if (sky)
+ {
+ if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getSunTextureId()))
+ {
+ desc = LLTrans::getString("EnvironmentSun");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getMoonTextureId()))
+ {
+ desc = LLTrans::getString("EnvironmentMoon");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getCloudNoiseTextureId()))
+ {
+ desc = LLTrans::getString("EnvironmentCloudNoise");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getBloomTextureId()))
+ {
+ desc = LLTrans::getString("EnvironmentBloom");
+ is_local = true;
+ }
+ }
+ }
+
+ if (is_local)
+ {
+ LLSD args;
+ LLButton* button = getChild<LLButton>(track_tabs[i], true);
+ args["TRACK"] = button->getCurrentLabel();
+ args["FRAME"] = iter->first * 100; // %
+ args["FIELD"] = desc;
+ args["FRAMENO"] = frame_num;
+ LLNotificationsUtil::add("WLLocalTextureDayBlock", args);
+ return;
+ }
+ iter++;
+ }
+ }
+
+ if (ctrl_action == ACTION_SAVE)
+ {
+ doApplyUpdateInventory(dayclone);
+ clearDirtyFlag();
+ }
+ else if (ctrl_action == ACTION_SAVEAS)
+ {
+ LLSD args;
+ args["DESC"] = dayclone->getName();
+ LLNotificationsUtil::add("SaveSettingAs", args, LLSD(), boost::bind(&LLFloaterEditExtDayCycle::onSaveAsCommit, this, _1, _2, dayclone));
+ }
+ else if ((ctrl_action == ACTION_APPLY_LOCAL) ||
+ (ctrl_action == ACTION_APPLY_PARCEL) ||
+ (ctrl_action == ACTION_APPLY_REGION))
+ {
+ doApplyEnvironment(ctrl_action, dayclone);
+ }
+ else if (ctrl_action == ACTION_COMMIT)
+ {
+ doApplyCommit(dayclone);
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Unknown settings action '" << ctrl_action << "'" << LL_ENDL;
+ }
+}
+
+void LLFloaterEditExtDayCycle::onButtonLoadFrame()
+{
+ doOpenInventoryFloater((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLSettingsType::ST_WATER : LLSettingsType::ST_SKY, LLUUID::null);
+}
+
+void LLFloaterEditExtDayCycle::onAddFrame()
+{
+ LLSettingsBase::Seconds frame(mTimeSlider->getCurSliderValue());
+ LLSettingsBase::ptr_t setting;
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame while waiting for day(asset) to load." << LL_ENDL;
+ return;
+ }
+ if ((mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame too close to existing frame." << LL_ENDL;
+ return;
+ }
+ if (!mFramesSlider->canAddSliders())
+ {
+ // Shouldn't happen, button should be disabled
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame when slider is full." << LL_ENDL;
+ return;
+ }
+
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ // scratch water should always have the current water settings.
+ LLSettingsWater::ptr_t water(mScratchWater->buildClone());
+ setting = water;
+ mEditDay->setWaterAtKeyframe( std::static_pointer_cast<LLSettingsWater>(setting), frame);
+ }
+ else
+ {
+ // scratch sky should always have the current sky settings.
+ LLSettingsSky::ptr_t sky(mScratchSky->buildClone());
+ setting = sky;
+ mEditDay->setSkyAtKeyframe(sky, frame, mCurrentTrack);
+ }
+ setDirtyFlag();
+ addSliderFrame(frame, setting);
+ updateTabs();
+}
+
+void LLFloaterEditExtDayCycle::onRemoveFrame()
+{
+ std::string sldr_key = mFramesSlider->getCurSlider();
+ if (sldr_key.empty())
+ {
+ return;
+ }
+ setDirtyFlag();
+ removeCurrentSliderFrame();
+ updateTabs();
+}
+
+
+void LLFloaterEditExtDayCycle::onCloneTrack()
+{
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to copy track while waiting for day(asset) to load." << LL_ENDL;
+ return;
+ }
+ const LLEnvironment::altitude_list_t &altitudes = LLEnvironment::instance().getRegionAltitudes();
+ bool use_altitudes = altitudes.size() > 0 && ((mEditContext == CONTEXT_PARCEL) || (mEditContext == CONTEXT_REGION));
+
+ LLSD args = LLSD::emptyArray();
+
+ S32 populated_counter = 0;
+ for (U32 i = 1; i < LLSettingsDay::TRACK_MAX; i++)
+ {
+ LLSD track;
+ track["id"] = LLSD::Integer(i);
+ bool populated = (!mEditDay->isTrackEmpty(i)) && (i != mCurrentTrack);
+ track["enabled"] = populated;
+ if (populated)
+ {
+ populated_counter++;
+ }
+ if (use_altitudes)
+ {
+ track["altitude"] = altitudes[i - 1];
+ }
+ args.append(track);
+ }
+
+ if (populated_counter > 0)
+ {
+ doOpenTrackFloater(args);
+ }
+ else
+ {
+ // Should not happen
+ LL_WARNS("ENVDAYEDIT") << "Tried to copy tracks, but there are no available sources" << LL_ENDL;
+ }
+}
+
+
+void LLFloaterEditExtDayCycle::onLoadTrack()
+{
+ LLUUID curitemId = mInventoryId;
+
+ if (mCurrentEdit && curitemId.notNull())
+ {
+ curitemId = LLFloaterSettingsPicker::findItemID(mCurrentEdit->getAssetId(), false, false);
+ }
+
+ doOpenInventoryFloater(LLSettingsType::ST_DAYCYCLE, curitemId);
+}
+
+
+void LLFloaterEditExtDayCycle::onClearTrack()
+{
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to clear track while waiting for day(asset) to load." << LL_ENDL;
+ return;
+ }
+
+ if (mCurrentTrack > 1)
+ mEditDay->getCycleTrack(mCurrentTrack).clear();
+ else
+ {
+ LLSettingsDay::CycleTrack_t &track(mEditDay->getCycleTrack(mCurrentTrack));
+
+ auto first = track.begin();
+ auto last = track.end();
+ ++first;
+ track.erase(first, last);
+ }
+
+ updateEditEnvironment();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ synchronizeTabs();
+ updateTabs();
+ refresh();
+}
+
+void LLFloaterEditExtDayCycle::onCommitName(class LLLineEditor* caller, void* user_data)
+{
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to rename day while waiting for day(asset) to load." << LL_ENDL;
+ return;
+ }
+
+ mEditDay->setName(caller->getText());
+}
+
+void LLFloaterEditExtDayCycle::onTrackSelectionCallback(const LLSD& user_data)
+{
+ U32 track_index = user_data.asInteger(); // 1-5
+ selectTrack(track_index);
+}
+
+void LLFloaterEditExtDayCycle::onPlayActionCallback(const LLSD& user_data)
+{
+ std::string action = user_data.asString();
+
+ F32 frame = mTimeSlider->getCurSliderValue();
+
+ if (action == ACTION_PLAY)
+ {
+ startPlay();
+ }
+ else if (action == ACTION_PAUSE)
+ {
+ stopPlay();
+ }
+ else if (mSliderKeyMap.size() != 0)
+ {
+ F32 new_frame = 0;
+ if (action == ACTION_FORWARD)
+ {
+ new_frame = mEditDay->getUpperBoundFrame(mCurrentTrack, frame + (mTimeSlider->getIncrement() / 2));
+ }
+ else if (action == ACTION_BACK)
+ {
+ new_frame = mEditDay->getLowerBoundFrame(mCurrentTrack, frame - (mTimeSlider->getIncrement() / 2));
+ }
+ selectFrame(new_frame, 0.0f);
+ stopPlay();
+ }
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderCallback(const LLSD &data)
+{
+ std::string curslider = mFramesSlider->getCurSlider();
+
+ if (!curslider.empty() && mEditDay)
+ {
+ F32 sliderpos = mFramesSlider->getCurSliderValue();
+
+ keymap_t::iterator it = mSliderKeyMap.find(curslider);
+ if (it != mSliderKeyMap.end())
+ {
+ if (gKeyboard->currentMask(true) == MASK_SHIFT && mShiftCopyEnabled && mCanMod)
+ {
+ // don't move the point/frame as long as shift is pressed and user is attempting to copy
+ // handleKeyUp will do the move if user releases key too early.
+ if (!(mEditDay->getSettingsNearKeyframe(sliderpos, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
+ {
+ LL_DEBUGS("ENVDAYEDIT") << "Copying frame from " << it->second.mFrame << " to " << sliderpos << LL_ENDL;
+ LLSettingsBase::ptr_t new_settings;
+
+ // mEditDay still remembers old position, add copy at new position
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ LLSettingsWaterPtr_t water_ptr = std::dynamic_pointer_cast<LLSettingsWater>(it->second.pSettings)->buildClone();
+ mEditDay->setWaterAtKeyframe(water_ptr, sliderpos);
+ new_settings = water_ptr;
+ }
+ else
+ {
+ LLSettingsSkyPtr_t sky_ptr = std::dynamic_pointer_cast<LLSettingsSky>(it->second.pSettings)->buildClone();
+ mEditDay->setSkyAtKeyframe(sky_ptr, sliderpos, mCurrentTrack);
+ new_settings = sky_ptr;
+ }
+ // mSliderKeyMap still remembers old position, for simplicity, just move it to be identical to slider
+ F32 old_frame = it->second.mFrame;
+ it->second.mFrame = sliderpos;
+ // slider already moved old frame, create new one in old place
+ addSliderFrame(old_frame, new_settings, false /*because we are going to reselect new one*/);
+ // reselect new frame
+ mFramesSlider->setCurSlider(it->first);
+ mShiftCopyEnabled = false;
+ setDirtyFlag();
+ }
+ }
+ else
+ {
+ // slider rounds values to nearest increments, changes can be substanntial (half increment)
+ if (abs(mFramesSlider->getNearestIncrement((*it).second.mFrame) - sliderpos) < F_APPROXIMATELY_ZERO)
+ {
+ // same value
+ mFramesSlider->setCurSliderValue((*it).second.mFrame);
+ }
+ else if (mEditDay->moveTrackKeyframe(mCurrentTrack, (*it).second.mFrame, sliderpos) && mCanMod)
+ {
+ (*it).second.mFrame = sliderpos;
+ setDirtyFlag();
+ }
+ else
+ {
+ // same value, wrong track, no such value, no mod
+ mFramesSlider->setCurSliderValue((*it).second.mFrame);
+ }
+
+ mShiftCopyEnabled = false;
+ }
+ }
+ }
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderDoubleClick(S32 x, S32 y, MASK mask)
+{
+ stopPlay();
+ onAddFrame();
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderMouseDown(S32 x, S32 y, MASK mask)
+{
+ stopPlay();
+ F32 sliderpos = mFramesSlider->getSliderValueFromPos(x, y);
+
+ std::string slidername = mFramesSlider->getCurSlider();
+
+ mShiftCopyEnabled = !slidername.empty() && gKeyboard->currentMask(true) == MASK_SHIFT;
+
+ if (!slidername.empty())
+ {
+ LLRect thumb_rect = mFramesSlider->getSliderThumbRect(slidername);
+ if ((x >= thumb_rect.mRight) || (x <= thumb_rect.mLeft))
+ {
+ mFramesSlider->resetCurSlider();
+ }
+ }
+
+ mTimeSlider->setCurSliderValue(sliderpos);
+
+ updateTabs();
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderMouseUp(S32 x, S32 y, MASK mask)
+{
+ // Only happens when clicking on empty space of frameslider, not on specific frame
+ F32 sliderpos = mFramesSlider->getSliderValueFromPos(x, y);
+
+ mTimeSlider->setCurSliderValue(sliderpos);
+ selectFrame(sliderpos, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+}
+
+void LLFloaterEditExtDayCycle::onTimeSliderCallback()
+{
+ stopPlay();
+ selectFrame(mTimeSlider->getCurSliderValue(), LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+}
+
+void LLFloaterEditExtDayCycle::cloneTrack(U32 source_index, U32 dest_index)
+{
+ cloneTrack(mEditDay, source_index, dest_index);
+}
+
+void LLFloaterEditExtDayCycle::cloneTrack(const LLSettingsDay::ptr_t &source_day, U32 source_index, U32 dest_index)
+{
+ if ((source_index == LLSettingsDay::TRACK_WATER || dest_index == LLSettingsDay::TRACK_WATER) && (source_index != dest_index))
+ { // one of the tracks is a water track, the other is not
+ LLSD args;
+
+ LL_WARNS() << "Can not import water track into sky track or vice versa" << LL_ENDL;
+
+ LLButton* button = getChild<LLButton>(track_tabs[source_index], true);
+ args["TRACK1"] = button->getCurrentLabel();
+ button = getChild<LLButton>(track_tabs[dest_index], true);
+ args["TRACK2"] = button->getCurrentLabel();
+
+ LLNotificationsUtil::add("TrackLoadMismatch", args);
+ return;
+ }
+
+ // don't use replaceCycleTrack because we will end up with references, but we need to clone
+
+ // hold on to a backup of the
+ LLSettingsDay::CycleTrack_t backup_track = mEditDay->getCycleTrack(dest_index);
+
+ mEditDay->clearCycleTrack(dest_index); // because source can be empty
+ LLSettingsDay::CycleTrack_t source_track = source_day->getCycleTrack(source_index);
+ S32 addcount(0);
+ for (auto &track_frame : source_track)
+ {
+ LLSettingsBase::ptr_t pframe = track_frame.second;
+ LLSettingsBase::ptr_t pframeclone = pframe->buildDerivedClone();
+ if (pframeclone)
+ {
+ ++addcount;
+ mEditDay->setSettingsAtKeyframe(pframeclone, track_frame.first, dest_index);
+ }
+ }
+
+ if (!addcount)
+ { // nothing was actually added. Restore the old track and issue a warning.
+ mEditDay->replaceCycleTrack(dest_index, backup_track);
+
+ LLSD args;
+ LLButton* button = getChild<LLButton>(track_tabs[dest_index], true);
+ args["TRACK"] = button->getCurrentLabel();
+
+ LLNotificationsUtil::add("TrackLoadFailed", args);
+ }
+ setDirtyFlag();
+
+ updateSlider();
+ updateTabs();
+ updateButtons();
+}
+
+void LLFloaterEditExtDayCycle::selectTrack(U32 track_index, bool force )
+{
+ if (track_index < LLSettingsDay::TRACK_MAX)
+ mCurrentTrack = track_index;
+
+ LLButton* button = getChild<LLButton>(track_tabs[mCurrentTrack], true);
+ if (button->getToggleState() && !force)
+ {
+ return;
+ }
+
+ for (U32 i = 0; i < LLSettingsDay::TRACK_MAX; i++) // use max value
+ {
+ getChild<LLButton>(track_tabs[i], true)->setToggleState(i == mCurrentTrack);
+ }
+
+ bool show_water = (mCurrentTrack == LLSettingsDay::TRACK_WATER);
+ mSkyTabLayoutContainer->setVisible(!show_water);
+ mWaterTabLayoutContainer->setVisible(show_water);
+
+ updateSlider();
+ updateLabels();
+}
+
+void LLFloaterEditExtDayCycle::selectFrame(F32 frame, F32 slop_factor)
+{
+ mFramesSlider->resetCurSlider();
+
+ keymap_t::iterator iter = mSliderKeyMap.begin();
+ keymap_t::iterator end_iter = mSliderKeyMap.end();
+ while (iter != end_iter)
+ {
+ F32 keyframe = iter->second.mFrame;
+ F32 frame_dif = fabs(keyframe - frame);
+ if (frame_dif <= slop_factor)
+ {
+ keymap_t::iterator next_iter = std::next(iter);
+ if ((frame_dif != 0) && (next_iter != end_iter))
+ {
+ if (fabs(next_iter->second.mFrame - frame) < frame_dif)
+ {
+ mFramesSlider->setCurSlider(next_iter->first);
+ frame = next_iter->second.mFrame;
+ break;
+ }
+ }
+ mFramesSlider->setCurSlider(iter->first);
+ frame = iter->second.mFrame;
+ break;
+ }
+ iter++;
+ }
+
+ mTimeSlider->setCurSliderValue(frame);
+ // block or update tabs according to new selection
+ updateTabs();
+// LLEnvironment::instance().updateEnvironment();
+}
+
+void LLFloaterEditExtDayCycle::clearTabs()
+{
+ // Note: If this doesn't look good, init panels with default settings. It might be better looking
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ const LLSettingsWaterPtr_t p_water = LLSettingsWaterPtr_t(NULL);
+ updateWaterTabs(p_water);
+ }
+ else
+ {
+ const LLSettingsSkyPtr_t p_sky = LLSettingsSkyPtr_t(NULL);
+ updateSkyTabs(p_sky);
+ }
+ updateButtons();
+ updateTimeAndLabel();
+}
+
+void LLFloaterEditExtDayCycle::updateTabs()
+{
+ reblendSettings();
+ synchronizeTabs();
+
+ updateButtons();
+ updateTimeAndLabel();
+}
+
+void LLFloaterEditExtDayCycle::updateWaterTabs(const LLSettingsWaterPtr_t &p_water)
+{
+ LLView* tab_container = mWaterTabLayoutContainer->getChild<LLView>(TABS_WATER); //can't extract panels directly, since it is in 'tuple'
+ LLPanelSettingsWaterMainTab* panel = dynamic_cast<LLPanelSettingsWaterMainTab*>(tab_container->findChildView("water_panel"));
+ if (panel)
+ {
+ panel->setWater(p_water);
+ }
+}
+
+void LLFloaterEditExtDayCycle::updateSkyTabs(const LLSettingsSkyPtr_t &p_sky)
+{
+ LLTabContainer* tab_container = mSkyTabLayoutContainer->getChild<LLTabContainer>(TABS_SKYS); //can't extract panels directly, since they are in 'tuple'
+
+ LLPanelSettingsSky* panel;
+ panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->findChildView("atmosphere_panel"));
+ if (panel)
+ {
+ panel->setSky(p_sky);
+ }
+ panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->findChildView("clouds_panel"));
+ if (panel)
+ {
+ panel->setSky(p_sky);
+ }
+ panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->findChildView("moon_panel"));
+ if (panel)
+ {
+ panel->setSky(p_sky);
+ }
+}
+
+void LLFloaterEditExtDayCycle::updateLabels()
+{
+ std::string label_arg = (mCurrentTrack == LLSettingsDay::TRACK_WATER) ? "water_label" : "sky_label";
+
+ mAddFrameButton->setLabelArg("[FRAME]", getString(label_arg));
+ mDeleteFrameButton->setLabelArg("[FRAME]", getString(label_arg));
+ mLoadFrame->setLabelArg("[FRAME]", getString(label_arg));
+}
+
+void LLFloaterEditExtDayCycle::updateButtons()
+{
+ // This logic appears to work in reverse, the add frame button
+ // is only enabled when you're on an existing frame and disabled
+ // in all the interim positions where you'd want to add a frame...
+
+ bool can_manipulate = mEditDay && !mIsPlaying && mCanMod;
+ bool can_clone(false);
+ bool can_clear(false);
+
+ if (can_manipulate)
+ {
+ if (mCurrentTrack == 0)
+ {
+ can_clone = false;
+ }
+ else
+ {
+ for (S32 track = 1; track < LLSettingsDay::TRACK_MAX; ++track)
+ {
+ if (track == mCurrentTrack)
+ continue;
+ can_clone |= !mEditDay->getCycleTrack(track).empty();
+ }
+ }
+
+ can_clear = (mCurrentTrack > 1) ? (!mEditDay->getCycleTrack(mCurrentTrack).empty()) : (mEditDay->getCycleTrack(mCurrentTrack).size() > 1);
+ }
+
+ mCloneTrack->setEnabled(can_clone);
+ mLoadTrack->setEnabled(can_manipulate);
+ mClearTrack->setEnabled(can_clear);
+ mAddFrameButton->setEnabled(can_manipulate && isAddingFrameAllowed());
+ mDeleteFrameButton->setEnabled(can_manipulate && isRemovingFrameAllowed());
+ mLoadFrame->setEnabled(can_manipulate);
+
+ bool enable_play = (bool)mEditDay;
+ childSetEnabled(BTN_PLAY, enable_play);
+ childSetEnabled(BTN_SKIP_BACK, enable_play);
+ childSetEnabled(BTN_SKIP_FORWARD, enable_play);
+
+ // update track buttons
+ bool extended_env = LLEnvironment::instance().isExtendedEnvironmentEnabled();
+ for (S32 track = 0; track < LLSettingsDay::TRACK_MAX; ++track)
+ {
+ LLButton* button = getChild<LLButton>(track_tabs[track], true);
+ button->setEnabled(extended_env);
+ button->setToggleState(track == mCurrentTrack);
+ }
+}
+
+void LLFloaterEditExtDayCycle::updateSlider()
+{
+ F32 frame_position = mTimeSlider->getCurSliderValue();
+ mFramesSlider->clear();
+ mSliderKeyMap.clear();
+
+ if (!mEditDay)
+ {
+ // floater is waiting for asset
+ return;
+ }
+
+ LLSettingsDay::CycleTrack_t track = mEditDay->getCycleTrack(mCurrentTrack);
+ for (auto &track_frame : track)
+ {
+ addSliderFrame(track_frame.first, track_frame.second, false);
+ }
+
+ if (mSliderKeyMap.size() > 0)
+ {
+ // update positions
+ mLastFrameSlider = mFramesSlider->getCurSlider();
+ }
+ else
+ {
+ // disable panels
+ clearTabs();
+ mLastFrameSlider.clear();
+ }
+
+ selectFrame(frame_position, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+}
+
+void LLFloaterEditExtDayCycle::updateTimeAndLabel()
+{
+ F32 time = mTimeSlider->getCurSliderValue();
+ mCurrentTimeLabel->setTextArg("[PRCNT]", llformat("%.0f", time * 100));
+ if (mDayLength.value() != 0)
+ {
+ LLUIString formatted_label = getString("time_label");
+
+ LLSettingsDay::Seconds total = (mDayLength * time);
+ S32Hours hrs = total;
+ S32Minutes minutes = total - hrs;
+
+ formatted_label.setArg("[HH]", llformat("%d", hrs.value()));
+ formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value())));
+ mCurrentTimeLabel->setTextArg("[DSC]", formatted_label.getString());
+ }
+ else
+ {
+ mCurrentTimeLabel->setTextArg("[DSC]", std::string());
+ }
+
+ // Update blender here:
+}
+
+void LLFloaterEditExtDayCycle::addSliderFrame(F32 frame, const LLSettingsBase::ptr_t &setting, bool update_ui)
+{
+ // multi slider distinguishes elements by key/name in string format
+ // store names to map to be able to recall dependencies
+ std::string new_slider = mFramesSlider->addSlider(frame);
+ if (!new_slider.empty())
+ {
+ mSliderKeyMap[new_slider] = FrameData(frame, setting);
+
+ if (update_ui)
+ {
+ mLastFrameSlider = new_slider;
+ mTimeSlider->setCurSliderValue(frame);
+ updateTabs();
+ }
+ }
+}
+
+void LLFloaterEditExtDayCycle::removeCurrentSliderFrame()
+{
+ std::string sldr = mFramesSlider->getCurSlider();
+ if (sldr.empty())
+ {
+ return;
+ }
+ mFramesSlider->deleteCurSlider();
+ keymap_t::iterator iter = mSliderKeyMap.find(sldr);
+ if (iter != mSliderKeyMap.end())
+ {
+ LL_DEBUGS("ENVDAYEDIT") << "Removing frame from " << iter->second.mFrame << LL_ENDL;
+ LLSettingsBase::Seconds seconds(iter->second.mFrame);
+ mEditDay->removeTrackKeyframe(mCurrentTrack, seconds);
+ mSliderKeyMap.erase(iter);
+ }
+
+ mLastFrameSlider = mFramesSlider->getCurSlider();
+ mTimeSlider->setCurSliderValue(mFramesSlider->getCurSliderValue());
+ updateTabs();
+}
+
+void LLFloaterEditExtDayCycle::removeSliderFrame(F32 frame)
+{
+ keymap_t::iterator it = std::find_if(mSliderKeyMap.begin(), mSliderKeyMap.end(),
+ [frame](const keymap_t::value_type &value) { return fabs(value.second.mFrame - frame) < LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR; });
+
+ if (it != mSliderKeyMap.end())
+ {
+ mFramesSlider->deleteSlider((*it).first);
+ mSliderKeyMap.erase(it);
+ }
+
+}
+
+//-------------------------------------------------------------------------
+
+LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSignal(LLFloaterEditExtDayCycle::edit_commit_signal_t::slot_type cb)
+{
+ return mCommitSignal.connect(cb);
+}
+
+void LLFloaterEditExtDayCycle::updateEditEnvironment(void)
+{
+ if (!mEditDay)
+ return;
+ S32 skytrack = (mCurrentTrack) ? mCurrentTrack : 1;
+ mSkyBlender = std::make_shared<LLTrackBlenderLoopingManual>(mScratchSky, mEditDay, skytrack);
+ mWaterBlender = std::make_shared<LLTrackBlenderLoopingManual>(mScratchWater, mEditDay, LLSettingsDay::TRACK_WATER);
+
+ if (LLEnvironment::instance().isExtendedEnvironmentEnabled())
+ {
+ selectTrack(LLSettingsDay::TRACK_MAX, true);
+ }
+ else
+ {
+ selectTrack(1, true);
+ }
+
+ reblendSettings();
+
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mEditSky, mEditWater);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+}
+
+void LLFloaterEditExtDayCycle::synchronizeTabs()
+{
+ // This should probably get moved into "updateTabs"
+ std::string curslider = mFramesSlider->getCurSlider();
+ bool canedit(false);
+
+ LLSettingsWater::ptr_t psettingW;
+ LLTabContainer * tabs = mWaterTabLayoutContainer->getChild<LLTabContainer>(TABS_WATER);
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ if (!mEditDay)
+ {
+ canedit = false;
+ }
+ else if (!curslider.empty())
+ {
+ canedit = !mIsPlaying;
+ // either search mEditDay or retrieve from mSliderKeyMap
+ keymap_t::iterator slider_it = mSliderKeyMap.find(curslider);
+ if (slider_it != mSliderKeyMap.end())
+ {
+ psettingW = std::static_pointer_cast<LLSettingsWater>(slider_it->second.pSettings);
+ }
+ }
+ mCurrentEdit = psettingW;
+ if (!psettingW)
+ {
+ canedit = false;
+ psettingW = mScratchWater;
+ }
+
+ getChild<LLUICtrl>(ICN_LOCK_EDIT)->setVisible(!canedit);
+ }
+ else
+ {
+ psettingW = mScratchWater;
+ }
+ mEditWater = psettingW;
+
+ setTabsData(tabs, psettingW, canedit);
+
+ LLSettingsSky::ptr_t psettingS;
+ canedit = false;
+ tabs = mSkyTabLayoutContainer->getChild<LLTabContainer>(TABS_SKYS);
+ if (mCurrentTrack != LLSettingsDay::TRACK_WATER)
+ {
+ if (!mEditDay)
+ {
+ canedit = false;
+ }
+ else if (!curslider.empty())
+ {
+ canedit = !mIsPlaying;
+ // either search mEditDay or retrieve from mSliderKeyMap
+ keymap_t::iterator slider_it = mSliderKeyMap.find(curslider);
+ if (slider_it != mSliderKeyMap.end())
+ {
+ psettingS = std::static_pointer_cast<LLSettingsSky>(slider_it->second.pSettings);
+ }
+ }
+ mCurrentEdit = psettingS;
+ if (!psettingS)
+ {
+ canedit = false;
+ psettingS = mScratchSky;
+ }
+
+ getChild<LLUICtrl>(ICN_LOCK_EDIT)->setVisible(!canedit);
+ }
+ else
+ {
+ psettingS = mScratchSky;
+ }
+ mEditSky = psettingS;
+
+ doCloseInventoryFloater();
+ doCloseTrackFloater();
+
+ setTabsData(tabs, psettingS, canedit);
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mEditSky, mEditWater);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+}
+
+void LLFloaterEditExtDayCycle::setTabsData(LLTabContainer * tabcontainer, const LLSettingsBase::ptr_t &settings, bool editable)
+{
+ S32 count = tabcontainer->getTabCount();
+ for (S32 idx = 0; idx < count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tabcontainer->getPanelByIndex(idx));
+ if (panel)
+ {
+ panel->setCanChangeSettings(editable & mCanMod);
+ panel->setSettings(settings);
+ }
+ }
+}
+
+
+void LLFloaterEditExtDayCycle::reblendSettings()
+{
+ F64 position = mTimeSlider->getCurSliderValue();
+
+ if (mSkyBlender)
+ {
+ if ((mSkyBlender->getTrack() != mCurrentTrack) && (mCurrentTrack != LLSettingsDay::TRACK_WATER))
+ {
+ mSkyBlender->switchTrack(mCurrentTrack, position);
+ }
+ else
+ {
+ mSkyBlender->setPosition(position);
+ }
+ }
+
+ if (mWaterBlender)
+ {
+ mWaterBlender->setPosition(position);
+ }
+}
+
+void LLFloaterEditExtDayCycle::doApplyCommit(LLSettingsDay::ptr_t day)
+{
+ if (!mCommitSignal.empty())
+ {
+ mCommitSignal(day);
+
+ closeFloater();
+ }
+}
+
+bool LLFloaterEditExtDayCycle::isRemovingFrameAllowed()
+{
+ if (mFramesSlider->getCurSlider().empty()) return false;
+
+ if (mCurrentTrack <= LLSettingsDay::TRACK_GROUND_LEVEL)
+ {
+ return (mSliderKeyMap.size() > 1);
+ }
+ else
+ {
+ return (mSliderKeyMap.size() > 0);
+ }
+}
+
+bool LLFloaterEditExtDayCycle::isAddingFrameAllowed()
+{
+ if (!mFramesSlider->getCurSlider().empty() || !mEditDay) return false;
+
+ LLSettingsBase::Seconds frame(mTimeSlider->getCurSliderValue());
+ if ((mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
+ {
+ return false;
+ }
+ return mFramesSlider->canAddSliders();
+}
+
+void LLFloaterEditExtDayCycle::doImportFromDisk()
+{ // Load a a legacy Windlight XML from disk.
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
+}
+
+void LLFloaterEditExtDayCycle::loadSettingFromFile(const std::vector<std::string>& filenames)
+{
+ LLSD messages;
+ if (filenames.size() < 1) return;
+ std::string filename = filenames[0];
+ LL_DEBUGS("ENVDAYEDIT") << "Selected file: " << filename << LL_ENDL;
+ LLSettingsDay::ptr_t legacyday = LLEnvironment::createDayCycleFromLegacyPreset(filename, messages);
+
+ if (!legacyday)
+ {
+ LLNotificationsUtil::add("WLImportFail", messages);
+ return;
+ }
+
+ loadInventoryItem(LLUUID::null);
+
+ mCurrentTrack = 1;
+ setDirtyFlag();
+ setEditDayCycle(legacyday);
+}
+
+void LLFloaterEditExtDayCycle::startPlay()
+{
+ doCloseInventoryFloater();
+ doCloseTrackFloater();
+
+ mIsPlaying = true;
+ mFramesSlider->resetCurSlider();
+ mPlayTimer.reset();
+ mPlayTimer.start();
+ gIdleCallbacks.addFunction(onIdlePlay, this);
+ mPlayStartFrame = mTimeSlider->getCurSliderValue();
+
+ getChild<LLView>("play_layout", true)->setVisible(false);
+ getChild<LLView>("pause_layout", true)->setVisible(true);
+}
+
+void LLFloaterEditExtDayCycle::stopPlay()
+{
+ if (!mIsPlaying)
+ return;
+
+ mIsPlaying = false;
+ gIdleCallbacks.deleteFunction(onIdlePlay, this);
+ mPlayTimer.stop();
+ F32 frame = mTimeSlider->getCurSliderValue();
+ selectFrame(frame, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+
+ getChild<LLView>("play_layout", true)->setVisible(true);
+ getChild<LLView>("pause_layout", true)->setVisible(false);
+}
+
+//static
+void LLFloaterEditExtDayCycle::onIdlePlay(void* user_data)
+{
+ if (!gDisconnected)
+ {
+ LLFloaterEditExtDayCycle* self = (LLFloaterEditExtDayCycle*)user_data;
+
+ if (self->mSkyBlender == nullptr || self->mWaterBlender == nullptr)
+ {
+ self->stopPlay();
+ }
+ else
+ {
+
+ F32 prcnt_played = self->mPlayTimer.getElapsedTimeF32() / DAY_CYCLE_PLAY_TIME_SECONDS;
+ F32 new_frame = fmod(self->mPlayStartFrame + prcnt_played, 1.f);
+
+ self->mTimeSlider->setCurSliderValue(new_frame); // will do the rounding
+ self->mSkyBlender->setPosition(new_frame);
+ self->mWaterBlender->setPosition(new_frame);
+ self->synchronizeTabs();
+ self->updateTimeAndLabel();
+ self->updateButtons();
+ }
+ }
+}
+
+
+void LLFloaterEditExtDayCycle::clearDirtyFlag()
+{
+ mIsDirty = false;
+
+ LLTabContainer* tab_container = mSkyTabLayoutContainer->getChild<LLTabContainer>("sky_tabs");
+ S32 tab_count = tab_container->getTabCount();
+
+ for (S32 idx = 0; idx < tab_count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tab_container->getPanelByIndex(idx));
+ if (panel)
+ panel->clearIsDirty();
+ }
+
+ tab_container = mWaterTabLayoutContainer->getChild<LLTabContainer>("water_tabs");
+ tab_count = tab_container->getTabCount();
+
+ for (S32 idx = 0; idx < tab_count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tab_container->getPanelByIndex(idx));
+ if (panel)
+ panel->clearIsDirty();
+ }
+
+}
+
+void LLFloaterEditExtDayCycle::doOpenTrackFloater(const LLSD &args)
+{
+ LLFloaterTrackPicker *picker = static_cast<LLFloaterTrackPicker *>(mTrackFloater.get());
+
+ // Show the dialog
+ if (!picker)
+ {
+ picker = new LLFloaterTrackPicker(this);
+
+ mTrackFloater = picker->getHandle();
+
+ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitTrackId(data.asInteger()); });
+ }
+
+ picker->showPicker(args);
+}
+
+void LLFloaterEditExtDayCycle::doCloseTrackFloater(bool quitting)
+{
+ LLFloater* floaterp = mTrackFloater.get();
+
+ if (floaterp)
+ {
+ floaterp->closeFloater(quitting);
+ }
+}
+
+LLFloaterSettingsPicker * LLFloaterEditExtDayCycle::getSettingsPicker()
+{
+ LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(mInventoryFloater.get());
+
+ // Show the dialog
+ if (!picker)
+ {
+ picker = new LLFloaterSettingsPicker(this,
+ LLUUID::null);
+
+ mInventoryFloater = picker->getHandle();
+
+ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data["ItemId"].asUUID(), data["Track"].asInteger()); });
+ }
+ return picker;
+}
+
+void LLFloaterEditExtDayCycle::onPickerCommitTrackId(U32 track_id)
+{
+ cloneTrack(track_id, mCurrentTrack);
+}
+
+void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem)
+{
+ LLFloaterSettingsPicker *picker = getSettingsPicker();
+ picker->setSettingsFilter(type);
+ picker->setSettingsItemId(curritem);
+ if (type == LLSettingsType::ST_DAYCYCLE)
+ {
+ picker->setTrackMode((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLFloaterSettingsPicker::TRACK_WATER : LLFloaterSettingsPicker::TRACK_SKY);
+ }
+ else
+ {
+ picker->setTrackMode(LLFloaterSettingsPicker::TRACK_NONE);
+ }
+ picker->openFloater();
+ picker->setFocus(true);
+}
+
+void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID item_id, S32 track)
+{
+ LLSettingsBase::TrackPosition frame(mTimeSlider->getCurSliderValue());
+ LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
+ if (itemp)
+ {
+ LLSettingsVOBase::getSettingsAsset(itemp->getAssetUUID(),
+ [this, track, frame, item_id](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoadedForInsertion(item_id, asset_id, settings, status, track, mCurrentTrack, frame); });
+ }
+}
+
+void LLFloaterEditExtDayCycle::showHDRNotification(const LLSettingsDay::ptr_t &pday)
+{
+ for (U32 i = LLSettingsDay::TRACK_GROUND_LEVEL; i <= LLSettingsDay::TRACK_MAX; i++)
+ {
+ LLSettingsDay::CycleTrack_t &day_track = pday->getCycleTrack(i);
+
+ LLSettingsDay::CycleTrack_t::iterator iter = day_track.begin();
+ LLSettingsDay::CycleTrack_t::iterator end = day_track.end();
+
+ while (iter != end)
+ {
+ LLSettingsSky::ptr_t sky = std::static_pointer_cast<LLSettingsSky>(iter->second);
+ if (sky
+ && sky->canAutoAdjust()
+ && sky->getReflectionProbeAmbiance(true) != 0.f)
+ {
+ LLNotificationsUtil::add("AutoAdjustHDRSky");
+ return;
+ }
+ iter++;
+ }
+ }
+}
+
+void LLFloaterEditExtDayCycle::onAssetLoadedForInsertion(LLUUID item_id, LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 source_track, S32 dest_track, LLSettingsBase::TrackPosition frame)
+{
+ std::function<void()> cb = [this, settings, frame, source_track, dest_track]()
+ {
+ if (settings->getSettingsType() == "daycycle")
+ {
+ // Load full track
+ LLSettingsDay::ptr_t pday = std::dynamic_pointer_cast<LLSettingsDay>(settings);
+ if (dest_track == LLSettingsDay::TRACK_WATER)
+ {
+ cloneTrack(pday, LLSettingsDay::TRACK_WATER, LLSettingsDay::TRACK_WATER);
+ }
+ else
+ {
+ cloneTrack(pday, source_track, dest_track);
+ }
+ }
+ else
+ {
+ if (!mFramesSlider->canAddSliders())
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame when slider is full." << LL_ENDL;
+ return;
+ }
+
+ // load or replace single frame
+ LLSettingsDay::CycleTrack_t::value_type nearest = mEditDay->getSettingsNearKeyframe(frame, dest_track, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+ if (nearest.first != LLSettingsDay::INVALID_TRACKPOS)
+ { // There is already a frame near the target location. Remove it so we can put the new one in its place.
+ mEditDay->removeTrackKeyframe(dest_track, nearest.first);
+ removeSliderFrame(nearest.first);
+ }
+
+ // Don't forget to clone (we might reuse/load it couple times)
+ if (settings->getSettingsType() == "sky")
+ {
+ // Load sky to frame
+ if (dest_track != LLSettingsDay::TRACK_WATER)
+ {
+ mEditDay->setSettingsAtKeyframe(settings->buildDerivedClone(), frame, dest_track);
+ addSliderFrame(frame, settings, false);
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Trying to load day settings as sky" << LL_ENDL;
+ }
+ }
+ else if (settings->getSettingsType() == "water")
+ {
+ // Load water to frame
+ if (dest_track == LLSettingsDay::TRACK_WATER)
+ {
+ mEditDay->setSettingsAtKeyframe(settings->buildDerivedClone(), frame, dest_track);
+ addSliderFrame(frame, settings, false);
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Trying to load water settings as sky" << LL_ENDL;
+ }
+ }
+ }
+ reblendSettings();
+ synchronizeTabs();
+ };
+
+ if (!settings || status)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Could not load asset " << asset_id << " into frame. status=" << status << LL_ENDL;
+ return;
+ }
+
+ if (!mEditDay)
+ {
+ // day got reset while we were waiting for response
+ return;
+ }
+
+ LLInventoryItem *inv_item = gInventory.getItem(item_id);
+
+ if (inv_item
+ && (!inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())
+ || !inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())))
+ {
+ // Need to check if item is already no-transfer, otherwise make it no-transfer
+ bool no_transfer = false;
+ if (mInventoryItem)
+ {
+ no_transfer = !mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
+ }
+ else
+ {
+ no_transfer = mEditDay->getFlag(LLSettingsBase::FLAG_NOTRANS);
+ }
+
+ if (!no_transfer)
+ {
+ LLSD args;
+
+ // create and show confirmation textbox
+ LLNotificationsUtil::add("SettingsMakeNoTrans", args, LLSD(),
+ [this, cb](const LLSD&notif, const LLSD&resp)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+ if (opt == 0)
+ {
+ mCanTrans = false;
+ mEditDay->setFlag(LLSettingsBase::FLAG_NOTRANS);
+ cb();
+ }
+ });
+ return;
+ }
+ }
+
+ cb();
+}