diff options
| author | Graham Linden <graham@lindenlab.com> | 2018-12-06 12:52:14 -0800 | 
|---|---|---|
| committer | Graham Linden <graham@lindenlab.com> | 2018-12-06 12:52:14 -0800 | 
| commit | 13d1f84bf6c3c408704901cb3aad6cffaa8ef6da (patch) | |
| tree | 666d1588918fc003947d348834b1a6026b297d65 | |
| parent | 7e9033821a96a9d6e80b58fafb4c7da63807b9d4 (diff) | |
| parent | cf7658ca3b7731e83ebf424b9c4b7a4c36ce328f (diff) | |
Merge
| -rw-r--r-- | indra/newview/lldrawpoolwlsky.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llenvironment.cpp | 61 | ||||
| -rw-r--r-- | indra/newview/llenvironment.h | 23 | ||||
| -rw-r--r-- | indra/newview/llfloatereditextdaycycle.cpp | 81 | ||||
| -rw-r--r-- | indra/newview/llfloatereditextdaycycle.h | 2 | ||||
| -rw-r--r-- | indra/newview/llfloaterfixedenvironment.cpp | 16 | ||||
| -rw-r--r-- | indra/newview/llfloaterland.cpp | 16 | ||||
| -rw-r--r-- | indra/newview/llfloaterregioninfo.cpp | 22 | ||||
| -rw-r--r-- | indra/newview/llpanelenvironment.cpp | 83 | ||||
| -rw-r--r-- | indra/newview/llpanelenvironment.h | 4 | ||||
| -rw-r--r-- | indra/newview/llsettingsvo.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/llsettingsvo.h | 3 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml | 8 | 
13 files changed, 234 insertions, 101 deletions
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 9ce7912c45..8904020ab9 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -395,8 +395,11 @@ void LLDrawPoolWLSky::renderStarsDeferred(void) const  void LLDrawPoolWLSky::renderSkyCloudsAdvanced(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const  {     -	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex()) -	{		 +	if (gPipeline.canUseWindLightShaders() +		&& gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) +		&& gSky.mVOSkyp->getCloudNoiseTex() +		&& gAtmosphere) +	{          LLGLSPipelineBlendSkyBox pipeline(true, true);          LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 3a030bb09d..20021fb075 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -76,6 +76,7 @@ namespace      const std::string KEY_DAYNAME("day_name");      const std::string KEY_DAYNAMES("day_names");      const std::string KEY_DAYOFFSET("day_offset"); +    const std::string KEY_ENVVERSION("env_version");      const std::string KEY_ISDEFAULT("is_default");      const std::string KEY_PARCELID("parcel_id");      const std::string KEY_REGIONID("region_id"); @@ -329,6 +330,8 @@ const LLUUID LLEnvironment::KNOWN_SKY_SUNSET("95882e1b-7741-f082-d9d6-3a34ec644c  const LLUUID LLEnvironment::KNOWN_SKY_MIDNIGHT("d8e50d02-a15b-17a7-3425-523bc20f67b8");  const S32 LLEnvironment::NO_TRACK(-1); +const S32 LLEnvironment::NO_VERSION(-3); // For viewer sided change, like ENV_LOCAL. -3 since -1 and -2 are taken by parcel initial server/viewer version +const S32 LLEnvironment::VERSION_CLEANUP(-4); // for cleanups  const F32 LLEnvironment::SUN_DELTA_YAW(F_PI);   // 180deg  @@ -360,6 +363,7 @@ void LLEnvironment::initSingleton()      gAgent.addParcelChangedCallback([this]() { onParcelChange(); });      //TODO: This frequently results in one more request than we need.  It isn't breaking, but should be nicer. +    // We need to know new env version to fix this, without it we can only do full re-request      LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); });      gAgent.addRegionChangedCallback([this]() { onRegionChange(); }); @@ -551,7 +555,7 @@ LLEnvironment::DayInstance::ptr_t LLEnvironment::getEnvironmentInstance(LLEnviro  } -void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset) +void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version)  {      if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))      {    @@ -567,11 +571,11 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe      environment->animate();      if (!mSignalEnvChanged.empty()) -        mSignalEnvChanged(env); +        mSignalEnvChanged(env, env_version);  } -void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironment::fixedEnvironment_t fixed) +void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironment::fixedEnvironment_t fixed, S32 env_version)  {      if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))      { @@ -595,12 +599,12 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm      if (!mSignalEnvChanged.empty()) -        mSignalEnvChanged(env); +        mSignalEnvChanged(env, env_version);      /*TODO: readjust environment*/  } -void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsBase::ptr_t &settings) +void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version)  {      DayInstance::ptr_t environment = getEnvironmentInstance(env); @@ -647,22 +651,33 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe      }  } -void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId) +void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version)  {      setEnvironment(env, assetId, LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET);  } -void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset) +void LLEnvironment::setEnvironment(EnvSelection_t env, +                                   const LLUUID &assetId, +                                   LLSettingsDay::Seconds daylength, +                                   LLSettingsDay::Seconds dayoffset, +                                   S32 env_version)  {      LLSettingsVOBase::getSettingsAsset(assetId, -        [this, env, daylength, dayoffset](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)  +        [this, env, daylength, dayoffset, env_version](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)          { -            onSetEnvAssetLoaded(env, asset_id, settings, daylength, dayoffset, TRANSITION_DEFAULT, status);  +            onSetEnvAssetLoaded(env, asset_id, settings, daylength, dayoffset, TRANSITION_DEFAULT, status, env_version);          });  } -void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 status) +void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env, +                                        LLUUID asset_id, +                                        LLSettingsBase::ptr_t settings, +                                        LLSettingsDay::Seconds daylength, +                                        LLSettingsDay::Seconds dayoffset, +                                        LLSettingsBase::Seconds transition, +                                        S32 status, +                                        S32 env_version)  {      if (!settings || status)      { @@ -687,7 +702,7 @@ void LLEnvironment::clearEnvironment(LLEnvironment::EnvSelection_t env)      mEnvironments[env].reset();      if (!mSignalEnvChanged.empty()) -        mSignalEnvChanged(env); +        mSignalEnvChanged(env, VERSION_CLEANUP);      /*TODO: readjust environment*/  } @@ -1055,7 +1070,7 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI          if (!envinfo->mDayCycle)          {              clearEnvironment(ENV_PARCEL); -            setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET); +            setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion);              updateEnvironment();          }          else if (envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_WATER) @@ -1063,13 +1078,13 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI          {              LL_WARNS("LAPRAS") << "Invalid day cycle for region" << LL_ENDL;              clearEnvironment(ENV_PARCEL); -            setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET); +            setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion);              updateEnvironment();          }          else          {              LL_INFOS("LAPRAS") << "Setting Region environment" << LL_ENDL; -            setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset); +            setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);              mTrackAltitudes = envinfo->mAltitudes;          } @@ -1098,7 +1113,7 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI          }          else          { -            setEnvironment(ENV_PARCEL, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset); +            setEnvironment(ENV_PARCEL, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);          }      } @@ -1470,7 +1485,8 @@ LLEnvironment::EnvironmentInfo::EnvironmentInfo():      mIsDefault(false),      mIsLegacy(false),      mDayCycleName(), -    mNameList() +    mNameList(), +    mEnvVersion(INVALID_PARCEL_ENVIRONMENT_VERSION)  {  } @@ -1526,6 +1542,17 @@ LLEnvironment::EnvironmentInfo::ptr_t LLEnvironment::EnvironmentInfo::extract(LL          }      } +    if (environment.has(KEY_ENVVERSION)) +    { +        LLSD version = environment[KEY_ENVVERSION]; +        pinfo->mEnvVersion = version.asInteger(); +    } +    else +    { +        // can be used for region, but versions should be same +        pinfo->mEnvVersion = pinfo->mIsDefault ? UNSET_PARCEL_ENVIRONMENT_VERSION : INVALID_PARCEL_ENVIRONMENT_VERSION; +    } +      return pinfo;  } @@ -1746,7 +1773,7 @@ void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLUUID asset_          mPushEnvironmentExpId = experience_id;          onSetEnvAssetLoaded(ENV_PUSH, asset_id, settings,               LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET,  -            LLSettingsBase::Seconds(transition_time), status); +            LLSettingsBase::Seconds(transition_time), status, NO_VERSION);      }); diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 7e35fdcfac..c5ac43704a 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -64,6 +64,8 @@ public:      static const LLUUID         KNOWN_SKY_MIDNIGHT;      static const S32            NO_TRACK; +    static const S32            NO_VERSION; +    static const S32            VERSION_CLEANUP;      struct EnvironmentInfo      { @@ -84,6 +86,7 @@ public:          bool                    mIsLegacy;          std::string             mDayCycleName;          namelist_t              mNameList; +        S32                     mEnvVersion;          static ptr_t            extract(LLSD);          static ptr_t            extractLegacy(LLSD); @@ -106,7 +109,7 @@ public:      typedef std::pair<LLSettingsSky::ptr_t, LLSettingsWater::ptr_t> fixedEnvironment_t;      typedef std::function<void(S32, EnvironmentInfo::ptr_t)>        environment_apply_fn; -    typedef boost::signals2::signal<void(EnvSelection_t)>           env_changed_signal_t; +    typedef boost::signals2::signal<void(EnvSelection_t, S32)>           env_changed_signal_t;      typedef env_changed_signal_t::slot_type                         env_changed_fn;      typedef std::array<F32, 4>                                      altitude_list_t;      typedef std::vector<F32>                                        altitudes_vect_t; @@ -135,14 +138,14 @@ public:      EnvSelection_t              getSelectedEnvironment() const                  { return mSelectedEnvironment; }      bool                        hasEnvironment(EnvSelection_t env); -    void                        setEnvironment(EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset); -    void                        setEnvironment(EnvSelection_t env, fixedEnvironment_t fixed); -    void                        setEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &fixed);  -    void                        setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixed) { setEnvironment(env, fixedEnvironment_t(fixed, LLSettingsWater::ptr_t())); } -    void                        setEnvironment(EnvSelection_t env, const LLSettingsWater::ptr_t & fixed) { setEnvironment(env, fixedEnvironment_t(LLSettingsSky::ptr_t(), fixed)); } -    void                        setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixeds, const LLSettingsWater::ptr_t & fixedw) { setEnvironment(env, fixedEnvironment_t(fixeds, fixedw)); } -    void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset); -    void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId); +    void                        setEnvironment(EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version = NO_VERSION); +    void                        setEnvironment(EnvSelection_t env, fixedEnvironment_t fixed, S32 env_version = NO_VERSION); +    void                        setEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &fixed, S32 env_version = NO_VERSION); +    void                        setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixed, LLSettingsWater::ptr_t()), env_version); } +    void                        setEnvironment(EnvSelection_t env, const LLSettingsWater::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(LLSettingsSky::ptr_t(), fixed), env_version); } +    void                        setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixeds, const LLSettingsWater::ptr_t & fixedw, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixeds, fixedw), env_version); } +    void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version = NO_VERSION); +    void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version = NO_VERSION);      void                        setSharedEnvironment(); @@ -381,7 +384,7 @@ private:      void                        onAgentPositionHasChanged(const LLVector3 &localpos); -    void                        onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 status); +    void                        onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 status, S32 env_version);      void                        onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 parcel_id, S32 day_length, S32 day_offset, altitudes_vect_t altitudes);      void                        handleEnvironmentPushClear(LLUUID experience_id, LLSD &message, F32 transition); diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index a30e16ab2b..f9b25c1977 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -430,7 +430,6 @@ void LLFloaterEditExtDayCycle::refresh()      mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_REGION, canApplyRegion() && show_apply);      mImportButton->setEnabled(mCanMod); -    mLoadFrame->setEnabled(mCanMod);      LLFloater::refresh();  } @@ -903,6 +902,7 @@ void LLFloaterEditExtDayCycle::selectTrack(U32 track_index, bool force )      mSkyTabLayoutContainer->setVisible(!show_water);      mWaterTabLayoutContainer->setVisible(show_water);      updateSlider(); +    updateLabels();  }  void LLFloaterEditExtDayCycle::selectFrame(F32 frame, F32 slop_factor) @@ -1010,6 +1010,15 @@ void LLFloaterEditExtDayCycle::updateSkyTabs(const LLSettingsSkyPtr_t &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 @@ -1020,8 +1029,9 @@ void LLFloaterEditExtDayCycle::updateButtons()      //bool can_add = static_cast<bool>(settings);      //mAddFrameButton->setEnabled(can_add);      //mDeleteFrameButton->setEnabled(!can_add); -    mAddFrameButton->setEnabled(mCanMod && mFramesSlider->canAddSliders()); +    mAddFrameButton->setEnabled(isAddingFrameAllowed() && mCanMod);      mDeleteFrameButton->setEnabled(isRemovingFrameAllowed() && mCanMod); +    mLoadFrame->setEnabled(!mIsPlaying && mCanMod);  }  void LLFloaterEditExtDayCycle::updateSlider() @@ -1327,11 +1337,20 @@ void LLFloaterEditExtDayCycle::reblendSettings()  void LLFloaterEditExtDayCycle::doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name)  { -    // This method knows what sort of settings object to create. -    LLUUID parent_id = mInventoryItem ? mInventoryItem->getParentUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); - -    LLSettingsVOBase::createInventoryItem(day, parent_id, settings_name, +    if (mInventoryItem) +    { +        LLUUID parent_id = mInventoryItem->getParentUUID(); +        U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); +        LLSettingsVOBase::createInventoryItem(day, next_owner_perm, parent_id, settings_name, +            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); +    } +    else +    { +        LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); +        // This method knows what sort of settings object to create. +        LLSettingsVOBase::createInventoryItem(day, parent_id, settings_name,              [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); +    }  }  void LLFloaterEditExtDayCycle::doApplyUpdateInventory(const LLSettingsDay::ptr_t &day) @@ -1401,6 +1420,8 @@ void LLFloaterEditExtDayCycle::doApplyCommit(LLSettingsDay::ptr_t day)  bool LLFloaterEditExtDayCycle::isRemovingFrameAllowed()  { +    if (mFramesSlider->getCurSlider().empty()) return false; +      if (mCurrentTrack <= LLSettingsDay::TRACK_GROUND_LEVEL)      {          return (mSliderKeyMap.size() > 1); @@ -1411,6 +1432,18 @@ bool LLFloaterEditExtDayCycle::isRemovingFrameAllowed()      }  } +bool LLFloaterEditExtDayCycle::isAddingFrameAllowed() +{ +    if (!mFramesSlider->getCurSlider().empty()) 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::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)  {      LL_INFOS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; @@ -1536,6 +1569,7 @@ void LLFloaterEditExtDayCycle::onIdlePlay(void* user_data)          self->mWaterBlender->setPosition(new_frame);          self->synchronizeTabs();          self->updateTimeAndLabel(); +        self->updateButtons();      }  } @@ -1614,20 +1648,35 @@ void LLFloaterEditExtDayCycle::onAssetLoadedForFrame(LLUUID item_id, LLUUID asse  {      std::function<void()> cb = [this, settings, frame, track]()      { -        if ((mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second) +        if (mFramesSlider->getCurSlider().empty())          { -            LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame too close to existing frame." << 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()) +            { +                LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame when slider is full." << LL_ENDL; +                return; +            } +            mEditDay->setSettingsAtKeyframe(settings, frame, track); +            addSliderFrame(frame, settings, false); +            reblendSettings(); +            synchronizeTabs();          } -        if (!mFramesSlider->canAddSliders()) +        else          { -            LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame when slider is full." << LL_ENDL; -            return; +            if (mCurrentTrack == LLSettingsDay::TRACK_WATER) +            { +                mEditDay->setWaterAtKeyframe(std::static_pointer_cast<LLSettingsWater>(settings), frame); +            } +            else +            { +                mEditDay->setSkyAtKeyframe(std::static_pointer_cast<LLSettingsSky>(settings), frame, track); +            } +            updateTabs();          } -        mEditDay->setSettingsAtKeyframe(settings, frame, track); -        addSliderFrame(frame, settings, false); -        reblendSettings(); -        synchronizeTabs();      };      if (!settings || status) diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h index fd5fb67837..a9b5c8a3f0 100644 --- a/indra/newview/llfloatereditextdaycycle.h +++ b/indra/newview/llfloatereditextdaycycle.h @@ -131,6 +131,7 @@ private:  	void                        updateWaterTabs(const LLSettingsWaterPtr_t &p_water);  	void                        updateSkyTabs(const LLSettingsSkyPtr_t &p_sky);  	void                        updateButtons(); +	void                        updateLabels();  	void                        updateSlider(); //generate sliders from current track  	void                        updateTimeAndLabel();  	void                        addSliderFrame(const F32 frame, const LLSettingsBase::ptr_t &setting, bool update_ui = true); @@ -173,6 +174,7 @@ private:      virtual void                clearDirtyFlag();      bool                        isRemovingFrameAllowed(); +    bool                        isAddingFrameAllowed();      LLSettingsDay::ptr_t        mEditDay; // edited copy      LLSettingsDay::Seconds      mDayLength; diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index d35dd5ec98..b9e23fb245 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -448,10 +448,20 @@ void LLFloaterFixedEnvironment::onButtonLoad()  void LLFloaterFixedEnvironment::doApplyCreateNewInventory(std::string settings_name)  { -    LLUUID parent_id = mInventoryItem ? mInventoryItem->getParentUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); -    // This method knows what sort of settings object to create. -    LLSettingsVOBase::createInventoryItem(mSettings, parent_id, settings_name, +    if (mInventoryItem) +    { +        LLUUID parent_id = mInventoryItem->getParentUUID(); +        U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); +        LLSettingsVOBase::createInventoryItem(mSettings, next_owner_perm, parent_id, settings_name,              [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); +    } +    else +    { +        LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); +        // This method knows what sort of settings object to create. +        LLSettingsVOBase::createInventoryItem(mSettings, parent_id, settings_name, +            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); +    }  }  void LLFloaterFixedEnvironment::doApplyUpdateInventory() diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 25cbf2f576..b20911edc5 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -3281,16 +3281,18 @@ void LLPanelLandEnvironment::refresh()          setCrossRegion(true);          mCurrentEnvironment.reset();          mLastParcelId = INVALID_PARCEL_ID; +        mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;          setControlsEnabled(false);          return;      }      if (mLastParcelId != getParcelId())      { +        mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;          mCurrentEnvironment.reset();      } -    if (!mCurrentEnvironment) +    if (!mCurrentEnvironment && mCurEnvVersion <= INVALID_PARCEL_ENVIRONMENT_VERSION)      {          refreshFromSource();          return; @@ -3307,6 +3309,7 @@ void LLPanelLandEnvironment::refreshFromSource()      {          setNoEnvironmentSupport(true);          setControlsEnabled(false); +        mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;          return;      }      setNoEnvironmentSupport(false); @@ -3315,17 +3318,25 @@ void LLPanelLandEnvironment::refreshFromSource()      {          setNoSelection(true);          setControlsEnabled(false); +        mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;          return;      }      setNoSelection(false);      if (isSameRegion())      { +        LL_DEBUGS("ENVIRONMENT") << "Requesting environment for parcel " << parcel->getLocalID() << ", known version " << mCurEnvVersion << LL_ENDL;          setCrossRegion(false);          LLHandle<LLPanel> that_h = getHandle(); -        mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION; +        if (mCurEnvVersion < UNSET_PARCEL_ENVIRONMENT_VERSION) +        { +            // to mark as requesting +            mCurEnvVersion = parcel->getParcelEnvironmentVersion(); +        } +        mLastParcelId = parcel->getLocalID(); +          LLEnvironment::instance().requestParcel(parcel->getLocalID(),              [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo)               {   @@ -3340,6 +3351,7 @@ void LLPanelLandEnvironment::refreshFromSource()          setCrossRegion(true);          mCurrentEnvironment.reset();          mLastParcelId = INVALID_PARCEL_ID; +        mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;      }      setControlsEnabled(false);  } diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 671f5aca9d..d7d114ca41 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -300,8 +300,7 @@ void LLFloaterRegionInfo::onOpen(const LLSD& key)  		disableTabCtrls();  		return;  	} -	refreshFromRegion(gAgent.getRegion()); -	requestRegionInfo(); +	requestRegionInfo(); // will cause refreshFromRegion()  	requestMeshRezInfo();  } @@ -484,6 +483,8 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)  	panel->setCtrlsEnabled(allow_modify); +	// Note: region info also causes LLRegionInfoModel::instance().update(msg); -> requestRegion(); -> changed message +	// we need to know env version here and in update(msg) to know when to request and when not to, when to filter 'changed'  	floater->refreshFromRegion( gAgent.getRegion() );  } @@ -3410,7 +3411,10 @@ void LLPanelRegionEnvironment::refresh()  {      if (!mCurrentEnvironment)      { -        refreshFromSource(); +        if (mCurEnvVersion <= INVALID_PARCEL_ENVIRONMENT_VERSION) +        { +            refreshFromSource(); // will immediately set mCurEnvVersion +        } // else - already requesting          return;      } @@ -3426,15 +3430,17 @@ bool LLPanelRegionEnvironment::refreshFromRegion(LLViewerRegion* region)      {          setNoSelection(true);          setControlsEnabled(false); +        mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;      }      setNoSelection(false);      if (gAgent.getRegion()->getRegionID() != region->getRegionID())      {          setCrossRegion(true); +        mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;      }      setCrossRegion(false); -         +      refreshFromSource();      return true;  } @@ -3448,9 +3454,15 @@ void LLPanelRegionEnvironment::refreshFromEstate()  void LLPanelRegionEnvironment::refreshFromSource()  { +    LL_DEBUGS("ENVIRONMENT") << "Requesting environment for region, known version " << mCurEnvVersion << LL_ENDL;      LLHandle<LLPanel> that_h = getHandle(); -    mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION; +    if (mCurEnvVersion < UNSET_PARCEL_ENVIRONMENT_VERSION) +    { +        // to mark as requesting +        mCurEnvVersion = UNSET_PARCEL_ENVIRONMENT_VERSION; +    } +      LLEnvironment::instance().requestRegion(          [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); }); diff --git a/indra/newview/llpanelenvironment.cpp b/indra/newview/llpanelenvironment.cpp index 8c86e3e8e4..04f281a40c 100644 --- a/indra/newview/llpanelenvironment.cpp +++ b/indra/newview/llpanelenvironment.cpp @@ -151,7 +151,7 @@ BOOL LLPanelEnvironmentInfo::postBuild()      getChild<LLMultiSliderCtrl>(SLD_ALTITUDES)->setCommitCallback([this](LLUICtrl *cntrl, const LLSD &value) { onAltSliderCallback(cntrl, value); }); -    mChangeMonitor = LLEnvironment::instance().setEnvironmentChanged([this](LLEnvironment::EnvSelection_t env) { onEnvironmentChanged(env); }); +    mChangeMonitor = LLEnvironment::instance().setEnvironmentChanged([this](LLEnvironment::EnvSelection_t env, S32 version) { onEnvironmentChanged(env, version); });      getChild<LLSettingsDropTarget>(SDT_DROP_TARGET)->setPanel(this); @@ -389,7 +389,7 @@ bool LLPanelEnvironmentInfo::setControlsEnabled(bool enabled)      S32 rdo_selection = getChild<LLRadioGroup>(RDG_ENVIRONMENT_SELECT)->getSelectedIndex(); -    bool can_enable = enabled && mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION; +    bool can_enable = enabled && mCurrentEnvironment && mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION;      getChild<LLUICtrl>(RDG_ENVIRONMENT_SELECT)->setEnabled(can_enable);      getChild<LLUICtrl>(RDO_USEDEFAULT)->setEnabled(can_enable && !is_legacy);      getChild<LLUICtrl>(RDO_USEINV)->setEnabled(false);      // these two are selected automatically based on  @@ -431,16 +431,16 @@ void LLPanelEnvironmentInfo::setDirtyFlag(U32 flag)  {      bool can_edit = canEdit();      mDirtyFlag |= flag; -    getChildView(BTN_APPLY)->setEnabled((mDirtyFlag != 0) && mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION && can_edit); -    getChildView(BTN_CANCEL)->setEnabled((mDirtyFlag != 0) && can_edit); +    getChildView(BTN_APPLY)->setEnabled((mDirtyFlag != 0) && mCurrentEnvironment && mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION && can_edit); +    getChildView(BTN_CANCEL)->setEnabled((mDirtyFlag != 0) && mCurrentEnvironment && can_edit);  }  void LLPanelEnvironmentInfo::clearDirtyFlag(U32 flag)  {      bool can_edit = canEdit();      mDirtyFlag &= ~flag; -    getChildView(BTN_APPLY)->setEnabled((mDirtyFlag != 0) && mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION && can_edit); -    getChildView(BTN_CANCEL)->setEnabled((mDirtyFlag != 0) && can_edit); +    getChildView(BTN_APPLY)->setEnabled((mDirtyFlag != 0) && mCurrentEnvironment && mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION && can_edit); +    getChildView(BTN_CANCEL)->setEnabled((mDirtyFlag != 0) && mCurrentEnvironment && can_edit);  }  void LLPanelEnvironmentInfo::updateAltLabel(const std::string &alt_name, U32 sky_index, F32 alt_value) @@ -663,7 +663,6 @@ void LLPanelEnvironmentInfo::doApply()          if (rdo_selection == 0)          { -            mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;              LLEnvironment::instance().resetParcel(parcel_id,                  [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });          } @@ -675,7 +674,6 @@ void LLPanelEnvironmentInfo::doApply()                  LL_WARNS("ENVPANEL") << "Failed to apply changes from editor! Dirty state: " << mDirtyFlag << " update state: " << mCurEnvVersion << LL_ENDL;                  return;              } -            mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;              LLEnvironment::instance().updateParcel(parcel_id,                  mCurrentEnvironment->mDayCycle->getAssetId(), std::string(), mCurrentEnvironment->mDayLength.value(),                   mCurrentEnvironment->mDayOffset.value(), alts, @@ -689,7 +687,6 @@ void LLPanelEnvironmentInfo::doApply()                  LL_WARNS("ENVPANEL") << "Failed to apply changes from editor! Dirty state: " << mDirtyFlag << " update state: " << mCurEnvVersion << LL_ENDL;                  return;              } -            mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;              LLEnvironment::instance().updateParcel(parcel_id,                  mCurrentEnvironment->mDayCycle, mCurrentEnvironment->mDayLength.value(), mCurrentEnvironment->mDayOffset.value(), alts,                  [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); }); @@ -780,36 +777,55 @@ void LLPanelEnvironmentInfo::onEditCommitted(LLSettingsDay::ptr_t newday)      }  } -void LLPanelEnvironmentInfo::onEnvironmentChanged(LLEnvironment::EnvSelection_t env) +void LLPanelEnvironmentInfo::onEnvironmentChanged(LLEnvironment::EnvSelection_t env, S32 new_version)  { +    if (new_version < INVALID_PARCEL_ENVIRONMENT_VERSION) +    { +        // cleanups and local changes, we are only interested in changes sent by server +        return; +    } + +    LL_DEBUGS("ENVPANEL") << "Received environment update " << mCurEnvVersion << " " << new_version << LL_ENDL; + +    // Environment comes from different sources, from environment update callbacks, +    // from hovers (causes callbacks on version change) and from personal requests +    // filter out duplicates and out of order packets by checking parcel environment version. +      if (isRegion())      { -        // Note: at the moment mCurEnvVersion is only applyable to parcels, we might need separate version control for regions -        // but mCurEnvVersion still acts like indicator that update is pending -        if (env == LLEnvironment::ENV_REGION) +        // Note: region uses same init versions as parcel +        if (env == LLEnvironment::ENV_REGION +            // version should be always growing, UNSET_PARCEL_ENVIRONMENT_VERSION is backup case +            && (mCurEnvVersion < new_version || mCurEnvVersion <= UNSET_PARCEL_ENVIRONMENT_VERSION))          { +            if (new_version >= UNSET_PARCEL_ENVIRONMENT_VERSION) +            { +                // 'pending state' to prevent re-request on following onEnvironmentChanged if there will be any +                mCurEnvVersion = new_version; +            }              mCurrentEnvironment.reset();              refreshFromSource();          }      } -    else if ((env == LLEnvironment::ENV_PARCEL) && (getParcelId() == LLViewerParcelMgr::instance().getAgentParcelId())) +    else if ((env == LLEnvironment::ENV_PARCEL) +             && (getParcelId() == LLViewerParcelMgr::instance().getAgentParcelId()))      { -        // Panel receives environment from different sources, from environment update callbacks, -        // from hovers (causes callbacks on version change) and from personal requests -        // filter out dupplicates and out of order packets by checking parcel environment version.          LLParcel *parcel = getParcel();          if (parcel)          { -            S32 new_version = parcel->getParcelEnvironmentVersion(); -            LL_DEBUGS("ENVPANEL") << "Received environment update " << mCurEnvVersion << " " << new_version << LL_ENDL; +            // first for parcel own settings, second is for case when parcel uses region settings              if (mCurEnvVersion < new_version                  || (mCurEnvVersion != new_version && new_version == UNSET_PARCEL_ENVIRONMENT_VERSION))              { +                // 'pending state' to prevent re-request on following onEnvironmentChanged if there will be any +                mCurEnvVersion = new_version;                  mCurrentEnvironment.reset(); +                  refreshFromSource();              } -            else +            else if (mCurrentEnvironment)              { +                // update controls                  refresh();              }          } @@ -839,30 +855,21 @@ void LLPanelEnvironmentInfo::onEnvironmentReceived(S32 parcel_id, LLEnvironment:      }      mCurrentEnvironment = envifo;      clearDirtyFlag(DIRTY_FLAG_MASK); -    if (parcel_id == INVALID_PARCEL_ID) +    if (mCurrentEnvironment->mEnvVersion > INVALID_PARCEL_ENVIRONMENT_VERSION)      { -        // region, no version -        // -2 for invalid version viewer -1 for invalid version from server -        mCurEnvVersion = UNSET_PARCEL_ENVIRONMENT_VERSION; +        // Server provided version, use it +        mCurEnvVersion = mCurrentEnvironment->mEnvVersion; +        LL_DEBUGS("ENVPANEL") << " Setting environment version: " << mCurEnvVersion << " for parcel id: " << parcel_id << LL_ENDL;      } +    // Backup: Version was not provided for some reason      else      { -        LLParcel* parcel = getParcel(); -        if (parcel -            && mCurrentEnvironment->mDayCycle -            && mCurrentEnvironment->mDayCycle->getAssetId() != LLSettingsDay::GetDefaultAssetId()) -        { -            // not always up to date, we will get onEnvironmentChanged() update in such case. -            mCurEnvVersion = parcel->getParcelEnvironmentVersion(); -        } -        else -        { -            // When using 'region' as parcel environment -            mCurEnvVersion = UNSET_PARCEL_ENVIRONMENT_VERSION; -        } -        LL_DEBUGS("ENVPANEL") << " Setting environment version: " << mCurEnvVersion << LL_ENDL; +        LL_WARNS("ENVPANEL") << " Environment version was not provided for " << parcel_id << ", old env version: " << mCurEnvVersion << LL_ENDL;      } +      refresh(); + +    // todo: we have envifo and parcel env version, should we just setEnvironment() and parcel's property to prevent dupplicate requests?  }  void LLPanelEnvironmentInfo::_onEnvironmentReceived(LLHandle<LLPanel> that_h, S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) diff --git a/indra/newview/llpanelenvironment.h b/indra/newview/llpanelenvironment.h index bca7743145..05f25fa78f 100644 --- a/indra/newview/llpanelenvironment.h +++ b/indra/newview/llpanelenvironment.h @@ -142,7 +142,7 @@ protected:      LLEnvironment::EnvironmentInfo::ptr_t   mCurrentEnvironment; -    void                        onEnvironmentChanged(LLEnvironment::EnvSelection_t env); +    void                        onEnvironmentChanged(LLEnvironment::EnvSelection_t env, S32 version);      class AltitudeData      { @@ -160,7 +160,7 @@ protected:      };      typedef std::map<std::string, AltitudeData>      altitudes_data_t;      altitudes_data_t                        mAltitudes; -    S32                                     mCurEnvVersion; +    S32                                     mCurEnvVersion; // used to filter duplicate callbacks/refreshes  private: diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 3925f37703..0def17b32d 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -121,8 +121,13 @@ void LLSettingsVOBase::createNewInventoryItem(LLSettingsType::type_e stype, cons  void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback)  { +    U32 nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner(); +    createInventoryItem(settings, nextOwnerPerm, parent_id, settings_name, callback); +} + +void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings, U32 next_owner_perm, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback) +{      LLTransactionID tid; -    U32             nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner();      if (!LLEnvironment::instance().isInventoryEnabled())      { @@ -144,7 +149,7 @@ void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings      create_inventory_settings(gAgent.getID(), gAgent.getSessionID(),          parent_id, tid,          settings_name, "", -        settings->getSettingsTypeValue(), nextOwnerPerm, cb); +        settings->getSettingsTypeValue(), next_owner_perm, cb);  }  void LLSettingsVOBase::onInventoryItemCreated(const LLUUID &inventoryId, LLSettingsBase::ptr_t settings, inventory_result_fn callback) diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h index 0e8312b849..1ad0091871 100644 --- a/indra/newview/llsettingsvo.h +++ b/indra/newview/llsettingsvo.h @@ -51,7 +51,8 @@ public:      static void     createNewInventoryItem(LLSettingsType::type_e stype, const LLUUID &parent_id, inventory_result_fn callback = inventory_result_fn());      static void     createInventoryItem(const LLSettingsBase::ptr_t &settings, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback = inventory_result_fn()); -     +    static void     createInventoryItem(const LLSettingsBase::ptr_t &settings, U32 next_owner_perm, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback = inventory_result_fn()); +      static void     updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID inv_item_id, inventory_result_fn callback = inventory_result_fn(), bool update_name = true);      static void     updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID object_id, LLUUID inv_item_id, inventory_result_fn callback = inventory_result_fn()); diff --git a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml index 9aa7c6f499..cac6f334c7 100644 --- a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml +++ b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml @@ -21,6 +21,8 @@      <!-- Substitutions -->      <string name="time_label"> ([HH]:[MM])</string>      <string name="sky_track_label">Sky [ALT]</string> +    <string name="sky_label">Sky</string> +    <string name="water_label">Water</string>      <!-- Layout -->      <layout_stack name="outer_stack" @@ -400,7 +402,7 @@                                  follows="top|left"                                  height="23"                                  width="90" -                                label="Add Frame" +                                label="Add [FRAME]"                                  left_pad="175"                                  top_delta="-20"                                  name="add_frame" /> @@ -408,7 +410,7 @@                                  follows="top|left"                                  height="23"                                  width="90" -                                label="Load Frame" +                                label="Load [FRAME]"                                  top_pad="0"                                  left_delta="0"                                  name="btn_load_frame" /> @@ -416,7 +418,7 @@                                  follows="left|top"                                  height="23"                                  width="90" -                                label="Delete Frame" +                                label="Delete [FRAME]"                                  top_pad="0"                                  left_delta="0"                                  name="delete_frame" />  | 
