diff options
| author | Dave Parks <davep@lindenlab.com> | 2022-11-02 12:17:28 -0500 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2022-11-02 12:17:28 -0500 | 
| commit | 32cc9a71d0e71bba96555558275a684501493e83 (patch) | |
| tree | b61f7b91ea7b6a0cee649da734413b265ebab6ac | |
| parent | c3f94ab9a1da2c0c5304ff624b54fad6a43506ae (diff) | |
| parent | 734e3fcb21228d07038da952820fa371e3c8af14 (diff) | |
Merge branch 'DRTVWR-559' of ssh://bitbucket.org/lindenlab/viewer into DRTVWR-559
| -rw-r--r-- | indra/llui/llfloater.h | 1 | ||||
| -rw-r--r-- | indra/newview/lllogininstance.cpp | 86 | ||||
| -rw-r--r-- | indra/newview/lllogininstance.h | 1 | ||||
| -rw-r--r-- | indra/newview/llmaterialeditor.cpp | 319 | ||||
| -rw-r--r-- | indra/newview/llmaterialeditor.h | 2 | ||||
| -rw-r--r-- | indra/newview/llpanelface.cpp | 20 | ||||
| -rw-r--r-- | indra/newview/llviewerfloaterreg.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_live_material_editor.xml | 37 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_material_editor.xml | 433 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/panel_gltf_material.xml | 382 | 
10 files changed, 632 insertions, 650 deletions
| diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 668cd208a9..3d15708295 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -225,6 +225,7 @@ public:  	/*virtual*/ void setIsChrome(BOOL is_chrome);  	/*virtual*/ void setRect(const LLRect &rect);                  void setIsSingleInstance(BOOL is_single_instance); +                BOOL getIsSingleInstance() { return mSingleInstance; }  	void 			initFloater(const Params& p); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 82ecfbd4dc..dd8c9b2dde 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -451,26 +451,8 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)          LLSD args(llsd::map( "MESSAGE", LLTrans::getString(response["message_id"]) ));          LLSD payload; -        LLNotificationsUtil::add("PromptMFAToken", args, payload, [=](LLSD const & notif, LLSD const & response) { -            bool continue_clicked = response["continue"].asBoolean(); -            std::string token = response["token"].asString(); -            LL_DEBUGS("LLLogin") << "PromptMFAToken: response: " << response << " continue_clicked" << continue_clicked << LL_ENDL; - -            // strip out whitespace - SL-17034/BUG-231938 -            token = boost::regex_replace(token, boost::regex("\\s"), ""); - -            if (continue_clicked && !token.empty()) -            { -                LL_INFOS("LLLogin") << "PromptMFAToken: token submitted" << LL_ENDL; - -                // Set the request data to true and retry login. -                mRequestData["params"]["token"] = token; -                reconnect(); -            } else { -                LL_INFOS("LLLogin") << "PromptMFAToken: no token, attemptComplete" << LL_ENDL; -                attemptComplete(); -            } -        }); +        LLNotificationsUtil::add("PromptMFAToken", args, payload, +            boost::bind(&LLLoginInstance::handleMFAChallenge, this, _1, _2));      }      else if(   reason_response == "key"              || reason_response == "presence" @@ -547,23 +529,59 @@ void LLLoginInstance::handleIndeterminate(const LLSD& event)  bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)  { -	if(accepted) -	{	 -		LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: accepted" << LL_ENDL; +    if(accepted) +    { +        LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: accepted " << LL_ENDL; -		// Set the request data to true and retry login. -		mRequestData["params"][key] = true;  -		reconnect(); -	} -	else -	{ -		LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: attemptComplete" << LL_ENDL; +        // Set the request data to true and retry login. +        mRequestData["params"][key] = true; -		attemptComplete(); -	} +        if (!mRequestData["params"]["token"].asString().empty()) +        { +            // SL-18511 this TOS failure happened while we are in the middle of an MFA challenge/response. +            // the previously entered token is very likely expired, so prompt again +            LLSD args(llsd::map( "MESSAGE", LLTrans::getString("LoginFailedAuthenticationMFARequired") )); +            LLSD payload; +            LLNotificationsUtil::add("PromptMFAToken", args, payload, +                boost::bind(&LLLoginInstance::handleMFAChallenge, this, _1, _2)); +        } +        else +        { +            reconnect(); +        } +    } +    else +    { +        LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: attemptComplete" << LL_ENDL; + +        attemptComplete(); +    } + +    LLEventPumps::instance().obtain(TOS_REPLY_PUMP).stopListening(TOS_LISTENER_NAME); +    return true; +} -	LLEventPumps::instance().obtain(TOS_REPLY_PUMP).stopListening(TOS_LISTENER_NAME); -	return true; +bool LLLoginInstance::handleMFAChallenge(LLSD const & notif, LLSD const & response) +{ +    bool continue_clicked = response["continue"].asBoolean(); +    std::string token = response["token"].asString(); +    LL_DEBUGS("LLLogin") << "PromptMFAToken: response: " << response << " continue_clicked" << continue_clicked << LL_ENDL; + +    // strip out whitespace - SL-17034/BUG-231938 +    token = boost::regex_replace(token, boost::regex("\\s"), ""); + +    if (continue_clicked && !token.empty()) +    { +        LL_INFOS("LLLogin") << "PromptMFAToken: token submitted" << LL_ENDL; + +        // Set the request data to true and retry login. +        mRequestData["params"]["token"] = token; +        reconnect(); +    } else { +        LL_INFOS("LLLogin") << "PromptMFAToken: no token, attemptComplete" << LL_ENDL; +        attemptComplete(); +    } +    return true;  }  std::string construct_start_string() diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index b759b43474..ee3ef0e4b1 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -84,6 +84,7 @@ private:  	void syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response);  	bool handleTOSResponse(bool v, const std::string& key); +    bool handleMFAChallenge(LLSD const & notif, LLSD const & response);  	void attemptComplete() { mAttemptComplete = true; } // In the future an event? diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 004d61a2ec..792a916e6b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -65,9 +65,6 @@ const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal";  const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness";  const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; -// Don't use ids here, LLPreview will attempt to use it as an inventory item -static const std::string LIVE_MATERIAL_EDITOR_KEY = "Live Editor"; -  // Dirty flags  static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0;  static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 1; @@ -326,8 +323,6 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key)      {          mAssetID = item->getAssetUUID();      } -    // if this is a 'live editor' instance, it uses live overrides -    mIsOverride = key.asString() == LIVE_MATERIAL_EDITOR_KEY;  }  void LLMaterialEditor::setObjectID(const LLUUID& object_id) @@ -351,6 +346,10 @@ void LLMaterialEditor::setAuxItem(const LLInventoryItem* item)  BOOL LLMaterialEditor::postBuild()  { +    // if this is a 'live editor' instance, it is also +    // single instacne and uses live overrides +    mIsOverride = getIsSingleInstance(); +      mBaseColorTextureCtrl = getChild<LLTextureCtrl>("base_color_texture");      mMetallicTextureCtrl = getChild<LLTextureCtrl>("metallic_roughness_texture");      mEmissiveTextureCtrl = getChild<LLTextureCtrl>("emissive_texture"); @@ -361,15 +360,28 @@ BOOL LLMaterialEditor::postBuild()      mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitEmissiveTexture, this, _1, _2));      mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitNormalTexture, this, _1, _2)); -    childSetAction("save", boost::bind(&LLMaterialEditor::onClickSave, this)); -    childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this)); -    childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this)); +    if (!mIsOverride) +    { +        childSetAction("save", boost::bind(&LLMaterialEditor::onClickSave, this)); +        childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this)); +        childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this)); +    } -    S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); -    getChild<LLUICtrl>("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); -    getChild<LLUICtrl>("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); -    getChild<LLUICtrl>("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); -    getChild<LLUICtrl>("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); +    if (mIsOverride) +    { +        childSetVisible("base_color_upload_fee", FALSE); +        childSetVisible("metallic_upload_fee", FALSE); +        childSetVisible("emissive_upload_fee", FALSE); +        childSetVisible("normal_upload_fee", FALSE); +    } +    else +    { +        S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); +        getChild<LLUICtrl>("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); +        getChild<LLUICtrl>("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); +        getChild<LLUICtrl>("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); +        getChild<LLUICtrl>("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); +    }      boost::function<void(LLUICtrl*, void*)> changes_callback = [this](LLUICtrl * ctrl, void* userData)      { @@ -394,9 +406,14 @@ BOOL LLMaterialEditor::postBuild()      // Emissive      childSetCommitCallback("emissive color", changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY); -    childSetVisible("unsaved_changes", mUnsavedChanges && !mIsOverride); +    if (!mIsOverride) +    { +        // "unsaved_changes" doesn't exist in live editor +        childSetVisible("unsaved_changes", mUnsavedChanges); -    getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", 0)); +        // Doesn't exist in live editor +        getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", 0)); +    }      // Todo:      // Disable/enable setCanApplyImmediately() based on @@ -407,7 +424,7 @@ BOOL LLMaterialEditor::postBuild()  void LLMaterialEditor::onClickCloseBtn(bool app_quitting)  { -    if (app_quitting) +    if (app_quitting || mIsOverride)      {          closeFloater(app_quitting);      } @@ -618,18 +635,27 @@ void LLMaterialEditor::setDoubleSided(bool double_sided)  void LLMaterialEditor::resetUnsavedChanges()  {      mUnsavedChanges = 0; -    childSetVisible("unsaved_changes", false); -    setCanSave(false); +    if (!mIsOverride) +    { +        childSetVisible("unsaved_changes", false); +        setCanSave(false); -    mExpectedUploadCost = 0; -    getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost)); +        mExpectedUploadCost = 0; +        getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost)); +    }  }  void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag)  {      mUnsavedChanges |= dirty_flag; -    // at the moment live editing (mIsOverride) applies everything 'live' -    childSetVisible("unsaved_changes", mUnsavedChanges && !mIsOverride); +    if (!mIsOverride) +    { +        // at the moment live editing (mIsOverride) applies everything 'live' +        // and "unsaved_changes", save/cancel buttons don't exist there +        return; +    } + +    childSetVisible("unsaved_changes", mUnsavedChanges);      if (mUnsavedChanges)      { @@ -673,12 +699,18 @@ void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag)  void LLMaterialEditor::setCanSaveAs(bool value)  { -    childSetEnabled("save_as", value); +    if (!mIsOverride) +    { +        childSetEnabled("save_as", value); +    }  }  void LLMaterialEditor::setCanSave(bool value)  { -    childSetEnabled("save", value); +    if (!mIsOverride) +    { +        childSetEnabled("save", value); +    }  }  void LLMaterialEditor::setEnableEditing(bool can_modify) @@ -710,21 +742,24 @@ void LLMaterialEditor::setEnableEditing(bool can_modify)  void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & data)  { -    // might be better to use arrays, to have a single callback -    // and not to repeat the same thing for each tecture control -    LLUUID new_val = mBaseColorTextureCtrl->getValue().asUUID(); -    if (new_val == mBaseColorTextureUploadId && mBaseColorTextureUploadId.notNull()) -    { -        childSetValue("base_color_upload_fee", getString("upload_fee_string")); -    } -    else +    if (!mIsOverride)      { -        // Texture picker has 'apply now' with 'cancel' support. -        // Keep mBaseColorJ2C and mBaseColorFetched, it's our storage in -        // case user decides to cancel changes. -        // Without mBaseColorFetched, viewer will eventually cleanup -        // the texture that is not in use -        childSetValue("base_color_upload_fee", getString("no_upload_fee_string")); +        // might be better to use arrays, to have a single callback +        // and not to repeat the same thing for each tecture control +        LLUUID new_val = mBaseColorTextureCtrl->getValue().asUUID(); +        if (new_val == mBaseColorTextureUploadId && mBaseColorTextureUploadId.notNull()) +        { +            childSetValue("base_color_upload_fee", getString("upload_fee_string")); +        } +        else +        { +            // Texture picker has 'apply now' with 'cancel' support. +            // Keep mBaseColorJ2C and mBaseColorFetched, it's our storage in +            // case user decides to cancel changes. +            // Without mBaseColorFetched, viewer will eventually cleanup +            // the texture that is not in use +            childSetValue("base_color_upload_fee", getString("no_upload_fee_string")); +        }      }      markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY);      applyToSelection(); @@ -732,14 +767,17 @@ void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & da  void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & data)  { -    LLUUID new_val = mMetallicTextureCtrl->getValue().asUUID(); -    if (new_val == mMetallicTextureUploadId && mMetallicTextureUploadId.notNull()) -    { -        childSetValue("metallic_upload_fee", getString("upload_fee_string")); -    } -    else +    if (!mIsOverride)      { -        childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); +        LLUUID new_val = mMetallicTextureCtrl->getValue().asUUID(); +        if (new_val == mMetallicTextureUploadId && mMetallicTextureUploadId.notNull()) +        { +            childSetValue("metallic_upload_fee", getString("upload_fee_string")); +        } +        else +        { +            childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); +        }      }      markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);      applyToSelection(); @@ -747,14 +785,17 @@ void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & dat  void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & data)  { -    LLUUID new_val = mEmissiveTextureCtrl->getValue().asUUID(); -    if (new_val == mEmissiveTextureUploadId && mEmissiveTextureUploadId.notNull()) -    { -        childSetValue("emissive_upload_fee", getString("upload_fee_string")); -    } -    else +    if (!mIsOverride)      { -        childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); +        LLUUID new_val = mEmissiveTextureCtrl->getValue().asUUID(); +        if (new_val == mEmissiveTextureUploadId && mEmissiveTextureUploadId.notNull()) +        { +            childSetValue("emissive_upload_fee", getString("upload_fee_string")); +        } +        else +        { +            childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); +        }      }      markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY);      applyToSelection(); @@ -762,14 +803,17 @@ void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & dat  void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data)  { -    LLUUID new_val = mNormalTextureCtrl->getValue().asUUID(); -    if (new_val == mNormalTextureUploadId && mNormalTextureUploadId.notNull()) -    { -        childSetValue("normal_upload_fee", getString("upload_fee_string")); -    } -    else +    if (!mIsOverride)      { -        childSetValue("normal_upload_fee", getString("no_upload_fee_string")); +        LLUUID new_val = mNormalTextureCtrl->getValue().asUUID(); +        if (new_val == mNormalTextureUploadId && mNormalTextureUploadId.notNull()) +        { +            childSetValue("normal_upload_fee", getString("upload_fee_string")); +        } +        else +        { +            childSetValue("normal_upload_fee", getString("no_upload_fee_string")); +        }      }      markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY);      applyToSelection(); @@ -1414,73 +1458,6 @@ void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD&      S32 option = LLNotificationsUtil::getSelectedOption(notification, response);      if (0 == option)      { -        if (mIsOverride && !mObjectOverridesSavedValues.empty()) -        { -            // Reapply ids back onto selection. -            // TODO: monitor selection changes and resave on selection changes -            struct g : public LLSelectedObjectFunctor -            { -                g(LLMaterialEditor* me) : mEditor(me) {} -                virtual bool apply(LLViewerObject* objectp) -                { -                    if (!objectp || !objectp->permModify()) -                    { -                        return false; -                    } - -                    U32 local_id = objectp->getLocalID(); -                    if (mEditor->mObjectOverridesSavedValues.find(local_id) == mEditor->mObjectOverridesSavedValues.end()) -                    { -                        return false; -                    } - -                    S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); -                    for (U8 te = 0; te < num_tes; te++) -                    { -                        if (mEditor->mObjectOverridesSavedValues[local_id].size() > te -                            && objectp->getTE(te)->isSelected()) -                        { -                            objectp->setRenderMaterialID( -                                te, -                                mEditor->mObjectOverridesSavedValues[local_id][te], -                                false /*wait for bulk update*/); -                        } -                    } -                    return true; -                } -                LLMaterialEditor* mEditor; -            } restorefunc(this); -            LLSelectMgr::getInstance()->getSelection()->applyToObjects(&restorefunc); - -            struct f : public LLSelectedObjectFunctor -            { -                virtual bool apply(LLViewerObject* object) -                { -                    if (object && !object->permModify()) -                    { -                        return false; -                    } - -                    LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); -                    if (param_block) -                    { -                        if (param_block->isEmpty()) -                        { -                            object->setHasRenderMaterialParams(false); -                        } -                        else -                        { -                            object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true); -                        } -                    } - -                    object->sendTEUpdate(); -                    return true; -                } -            } sendfunc; -            LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); -        } -          closeFloater();      }  } @@ -1630,46 +1607,11 @@ void LLMaterialEditor::onSelectionChanged()          clearTextures();          setFromSelection();      } - -    // At the moment all cahges are 'live' so don't reset dirty flags -    // saveLiveValues(); todo -} - -void LLMaterialEditor::saveLiveValues() -{ -    // Collect ids to be able to revert overrides. -    // TODO: monitor selection changes and resave on selection changes -    mObjectOverridesSavedValues.clear(); -    struct g : public LLSelectedObjectFunctor -    { -        g(LLMaterialEditor* me) : mEditor(me) {} -        virtual bool apply(LLViewerObject* objectp) -        { -            if (!objectp) -            { -                return false; -            } - -            U32 local_id = objectp->getLocalID(); -            S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); -            for (U8 te = 0; te < num_tes; te++) -            { -                // Todo: fix this, overrides don't care about ids, -                // we will have to save actual values or materials -                LLUUID mat_id = objectp->getRenderMaterialID(te); -                mEditor->mObjectOverridesSavedValues[local_id].push_back(mat_id); -            } -            return true; -        } -        LLMaterialEditor* mEditor; -    } savefunc(this); -    LLSelectMgr::getInstance()->getSelection()->applyToObjects(&savefunc);  }  void LLMaterialEditor::updateLive()  { -    const LLSD floater_key(LIVE_MATERIAL_EDITOR_KEY); -    LLFloater* instance = LLFloaterReg::findInstance("material_editor", floater_key); +    LLFloater* instance = LLFloaterReg::findInstance("live_material_editor");      if (instance && LLFloater::isVisible(instance))      {          LLMaterialEditor* me = (LLMaterialEditor*)instance; @@ -1690,8 +1632,7 @@ void LLMaterialEditor::updateLive(const LLUUID &object_id, S32 te)          // Not an update we are waiting for          return;      } -    const LLSD floater_key(LIVE_MATERIAL_EDITOR_KEY); -    LLFloater* instance = LLFloaterReg::findInstance("material_editor", floater_key); +    LLFloater* instance = LLFloaterReg::findInstance("live_material_editor");      if (instance && LLFloater::isVisible(instance))      {          LLMaterialEditor* me = (LLMaterialEditor*)instance; @@ -1706,26 +1647,19 @@ void LLMaterialEditor::updateLive(const LLUUID &object_id, S32 te)  void LLMaterialEditor::loadLive()  { -    // Allow only one 'live' instance -    const LLSD floater_key(LIVE_MATERIAL_EDITOR_KEY); -    LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", floater_key); +    LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("live_material_editor");      if (me)      {          me->mOverrideInProgress = false;          me->setFromSelection(); -        me->setTitle(me->getString("material_override_title")); -        me->childSetVisible("save", false); -        me->childSetVisible("save_as", false);          // Set up for selection changes updates          if (!me->mSelectionUpdateSlot.connected())          {              me->mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLMaterialEditor::onSelectionChanged, me));          } -        // Collect ids to be able to revert overrides on cancel. -        me->saveLiveValues(); -        me->openFloater(floater_key); +        me->openFloater();          me->setFocus(TRUE);      }  } @@ -2226,10 +2160,17 @@ private:  class LLRenderMaterialOverrideFunctor : public LLSelectedTEFunctor  {  public: -    LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url) -    : mEditor(me), mCapUrl(url) +    LLRenderMaterialOverrideFunctor( +        LLMaterialEditor * me, +        std::string const & url, +        const LLUUID &report_on_object_id, +        S32 report_on_te) +    : mEditor(me) +    , mCapUrl(url) +    , mSuccess(false) +    , mObjectId(report_on_object_id) +    , mObjectTE(report_on_te)      { -      }      bool apply(LLViewerObject* objectp, S32 te) override @@ -2262,7 +2203,6 @@ public:              // Override object's values with values from editor where appropriate              if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY)              { -                LLColor4 baseColor = mEditor->getBaseColor();                  material->setBaseColorFactor(mEditor->getBaseColor(), true);              }              if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY) @@ -2324,7 +2264,17 @@ public:                  "side", te,                  "gltf_json", overrides_json              ); -            LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLGLTFMaterialList::modifyMaterialCoro, mCapUrl, overrides, modifyCallback)); + +            void(*done_callback)(bool) = nullptr; +            if (mObjectTE == te +                && mObjectId == objectp->getID()) +            { +                mSuccess = true; +                // We only want callback for face we are displayig material from +                // even if we are setting all of them +                done_callback = modifyCallback; +            } +            LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLGLTFMaterialList::modifyMaterialCoro, mCapUrl, overrides, done_callback));          }          return true;      } @@ -2336,12 +2286,17 @@ public:              // something went wrong update selection              LLMaterialEditor::updateLive();          } -        // else we will get updateLive(obj, id) from aplied overrides +        // else we will get updateLive(obj, id) from applied overrides      } +    bool getResult() { return mSuccess; } +  private:      LLMaterialEditor * mEditor;      std::string mCapUrl; +    LLUUID mObjectId; +    S32 mObjectTE; +    bool mSuccess;  };  void LLMaterialEditor::applyToSelection() @@ -2365,9 +2320,11 @@ void LLMaterialEditor::applyToSelection()          {              mOverrideInProgress = true;              LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); -            LLRenderMaterialOverrideFunctor override_func(this, url); -            if (!selected_objects->applyToTEs(&override_func)) +            LLRenderMaterialOverrideFunctor override_func(this, url, mOverrideObjectId, mOverrideObjectTE); +            selected_objects->applyToTEs(&override_func); +            if (!override_func.getResult())              { +                // OverrideFunctor didn't find expected object or face                  mOverrideInProgress = false;              } diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 49f3baf0c7..0ffad5f54a 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -104,7 +104,6 @@ public:      static void loadMaterialFromFile(const std::string& filename, S32 index = -1);      void onSelectionChanged(); // live overrides selection changes -    void saveLiveValues(); // for restoration on cancel      static void updateLive();      static void updateLive(const LLUUID &object_id, S32 te); @@ -293,7 +292,6 @@ private:      // for "cancel" support      static LLUUID mOverrideObjectId; // static to avoid searching for the floater      static S32 mOverrideObjectTE; -    std::map<U32, uuid_vec_t> mObjectOverridesSavedValues;      boost::signals2::connection mSelectionUpdateSlot;  }; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f884cfe842..04957729ed 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2658,11 +2658,11 @@ void LLPanelFace::updateVisibility()  	{  		updateShinyControls();  	} -	getChildView("shinyScaleU")->setVisible(show_shininess || show_pbr_normal); -	getChildView("shinyScaleV")->setVisible(show_shininess || show_pbr_normal); -	getChildView("shinyRot")->setVisible(show_shininess || show_pbr_normal); -	getChildView("shinyOffsetU")->setVisible(show_shininess || show_pbr_normal); -	getChildView("shinyOffsetV")->setVisible(show_shininess || show_pbr_normal); +	getChildView("shinyScaleU")->setVisible(show_shininess || show_pbr_metallic); +	getChildView("shinyScaleV")->setVisible(show_shininess || show_pbr_metallic); +	getChildView("shinyRot")->setVisible(show_shininess || show_pbr_metallic); +	getChildView("shinyOffsetU")->setVisible(show_shininess || show_pbr_metallic); +	getChildView("shinyOffsetV")->setVisible(show_shininess || show_pbr_metallic);  	// Normal map controls  	if (show_bumpiness) @@ -2672,11 +2672,11 @@ void LLPanelFace::updateVisibility()  	getChildView("bumpytexture control")->setVisible(show_bumpiness);  	getChildView("combobox bumpiness")->setVisible(show_bumpiness);  	getChildView("label bumpiness")->setVisible(show_bumpiness); -	getChildView("bumpyScaleU")->setVisible(show_bumpiness || show_pbr_metallic); -	getChildView("bumpyScaleV")->setVisible(show_bumpiness || show_pbr_metallic); -	getChildView("bumpyRot")->setVisible(show_bumpiness || show_pbr_metallic); -	getChildView("bumpyOffsetU")->setVisible(show_bumpiness || show_pbr_metallic); -	getChildView("bumpyOffsetV")->setVisible(show_bumpiness || show_pbr_metallic); +	getChildView("bumpyScaleU")->setVisible(show_bumpiness || show_pbr_normal); +	getChildView("bumpyScaleV")->setVisible(show_bumpiness || show_pbr_normal); +	getChildView("bumpyRot")->setVisible(show_bumpiness || show_pbr_normal); +	getChildView("bumpyOffsetU")->setVisible(show_bumpiness || show_pbr_normal); +	getChildView("bumpyOffsetV")->setVisible(show_bumpiness || show_pbr_normal);      // PBR controls      getChildView("pbr_control")->setVisible(show_pbr); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index f5ccc238c0..962e3e2cf0 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -337,6 +337,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("script_colors", "floater_script_ed_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptEdPrefs>);      LLFloaterReg::add("material_editor", "floater_material_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLMaterialEditor>); +    LLFloaterReg::add("live_material_editor", "floater_live_material_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLMaterialEditor>);  	LLFloaterReg::add("telehubs", "floater_telehub.xml",&LLFloaterReg::build<LLFloaterTelehub>);  	LLFloaterReg::add("test_inspectors", "floater_test_inspectors.xml", &LLFloaterReg::build<LLFloaterTestInspectors>); diff --git a/indra/newview/skins/default/xui/en/floater_live_material_editor.xml b/indra/newview/skins/default/xui/en/floater_live_material_editor.xml new file mode 100644 index 0000000000..317783f794 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_live_material_editor.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + can_resize="true" + default_tab_group="1" + height="786" + width="256" + min_height="500" + min_width="256" + layout="topleft" + name="material editor" + help_topic="material_editor" + single_instance="true" + title="Editing Material"> +  <scroll_container +   name="materials_scroll" +   top="14" +   left="4" +   height="768" +   width="247" +   follows="all" +   layout="topleft" +   color="DkGray2" +   opaque="true" +   reserve_scroll_corner="false"> +    <panel +     name="panel_material" +     filename="panel_gltf_material.xml" +     border="false" +     visible="true" +     layout="topleft" +     top="0" +     left="0" +     height="768" +     width="247" /> +  </scroll_container> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_material_editor.xml b/indra/newview/skins/default/xui/en/floater_material_editor.xml index 84264cd2e6..29def9bd53 100644 --- a/indra/newview/skins/default/xui/en/floater_material_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml @@ -27,430 +27,17 @@     layout="topleft"     color="DkGray2"     opaque="true" -   reserve_scroll_corner="false" -      > +   reserve_scroll_corner="false">      <panel -      border="false" -      name="scroll_panel" -      top="0" -      left="0" -      height="768" -      width="247" -        > -      <check_box -              follows="left|top" -              label="Double Sided" -              left="10" -              top="0" -              name="double sided" -              height="25" -              width="120" /> -      <panel -        border="true" -             follows="left|top" -             width="246" -             height="196" -             layout="topleft" -             left="1" -             mouse_opaque="false" -             name="base_color_texture_pnl" -             top_pad="5" -         > -        <text -                   type="string" -                   font.style="BOLD" -                   length="1" -                   follows="left|top" -                   height="10" -                   layout="topleft" -                   left="10" -                   top="5" -                   width="128"> -          Base Color: -        </text> -        <texture_picker -                 can_apply_immediately="true" -                 default_image_name="Default" -                 fallback_image="materials_ui_x_24.png" -                 allow_no_texture="true" -                 follows="left|top" -                 top_pad="8" -                 height="151" -                 layout="topleft" -                 left="10" -                 name="base_color_texture" -                 tool_tip="Base Color map.  Alpha channel is optional and used for transparency." -                 width="128" /> -        <text -                   type="string" -                   font.style="BOLD" -                   length="1" -                   follows="left|top" -                   height="10" -                   width="128" -                   layout="topleft" -                   left="10" -                   top_pad="-17" -                   name="base_color_upload_fee" -             > -          No upload fee -        </text> -        <text -                   type="string" -                   length="1" -                   follows="left|top" -                   height="10" -                   layout="topleft" -                   left_pad="5" -                   top="8" -             > -          Tint -        </text> -        <color_swatch -                          can_apply_immediately="true" -                          follows="left|top" -                          height="40" -                          label_height="0" -                          layout="topleft" -                          left_delta="0" -                          top_pad="5" -                          name="base color" -                          width="40" /> -        <text -                 type="string" -                 length="1" -                 follows="left|top" -                 height="10" -                 layout="topleft" -                 left_delta="0" -                 top_pad="5" -                 width="96" -             > -          Transparency -        </text> -        <spinner -                   decimal_digits="3" -                   follows="left|top" -                   height="19" -                   increment="0.01" -                   initial_value="1" -                   layout="topleft" -                   left_delta="0" -                   top_pad="5" -                   min_val="0" -                   max_val="1" -                   name="transparency" -                  width="64" -             /> -        <text -                 type="string" -                 length="1" -                 follows="left|top" -                 height="10" -                 layout="topleft" -                 left_delta="0" -                 name="label alphamode" -                 text_readonly_color="LabelDisabledColor" -                 top_pad="5" -                 width="90"> -          Alpha mode -        </text> -        <combo_box -         height="23" -         layout="topleft" -         left_delta="0" -         name="alpha mode" -         top_pad="4" -         width="96"> -          <combo_box.item -           label="None" -           name="None" -           value="OPAQUE" /> -          <combo_box.item -           label="Alpha blending" -           name="Alpha blending" -           value="BLEND" /> -          <combo_box.item -           label="Alpha masking" -           name="Alpha masking" -           value="MASK" /> -        </combo_box> -        <text -                 type="string" -                 length="1" -                 follows="left|top" -                 height="10" -                 layout="topleft" -                 left_delta="0" -                 top_pad="5" -                 width="96" -             > -          Alpha Cutoff -        </text> -        <spinner -                   decimal_digits="3" -                   follows="left|top" -                   height="19" -                   increment="0.01" -                   initial_value="1" -                   layout="topleft" -                   left_delta="0" -                   top_pad="5" -                   min_val="0" -                   max_val="1" -                   name="alpha cutoff" -                  width="64" -             /> -      </panel> -      <panel -        border="true" -             follows="left|top" -             width="246" -             height="175" -             layout="topleft" -             left="1" -             mouse_opaque="false" -             name="metallic_texture_pnl" -             top_pad="5" -         > -        <text -                 type="string" -                 font.style="BOLD" -                 length="1" -                 follows="left|top" -                 height="10" -                 layout="topleft" -                 left="10" -                 top="5" -             > -          Metallic-Roughness: -        </text> -        <texture_picker -                 can_apply_immediately="true" -                 default_image_name="Default" -                 fallback_image="materials_ui_x_24.png" -                 allow_no_texture="true" -                 follows="left|top" -                 width="128" -                 height="151" -                 layout="topleft" -                 left="10" -                 name="metallic_roughness_texture" -                 tool_tip="GLTF metallic-roughness map with optional occlusion.  Red channel is occlusion, green channel is roughness, blue channel is metalness." -                 top_pad="8" -             /> -        <text -                   type="string" -                   font.style="BOLD" -                   length="1" -                   follows="left|top" -                   height="10" -                   width="128" -                   layout="topleft" -                   left="10" -                   top_pad="-17" -                   name="metallic_upload_fee" -           > -          No upload fee -        </text> -        <text -                   type="string" -                   length="1" -                   follows="left|top" -                   height="10" -                   layout="topleft" -                   left_pad="5" -                   top="8" -             > -          Metallic Factor -        </text> -        <spinner -                   decimal_digits="3" -                   follows="left|top" -                   height="19" -                   increment="0.01" -                   initial_value="0" -                   layout="topleft" -                   left_delta="0" -                   top_pad="5" -                   min_val="0" -                   max_val="1" -                   name="metalness factor" -                  width="64" -             /> -        <text -                 type="string" -                 length="1" -                 follows="left|top" -                 height="10" -                 layout="topleft" -                 left_delta="0" -                 top_pad="5" -                 width="96" -             > -          Roughness Factor -        </text> -        <spinner -                   decimal_digits="3" -                   follows="left|top" -                   height="19" -                   increment="0.01" -                   initial_value="0" -                   layout="topleft" -                   left_delta="0" -                   top_pad="5" -                   min_val="0" -                   max_val="1" -                   name="roughness factor" -                  width="64" -             /> -      </panel> -      <panel -        border="true" -             follows="left|top" -             width="246" -             height="175" -             layout="topleft" -             left="1" -             mouse_opaque="false" -             name="emissive_texture_pnl" -             top_pad="5" -         > -        <text -                   type="string" -                   font.style="BOLD" -                   length="1" -                   follows="left|top" -                   height="10" -                   layout="topleft" -                   left="10" -                   top="5" -                   width="64"> -          Emissive: -        </text> -        <texture_picker -                   can_apply_immediately="true" -                   default_image_name="Default" -                   fallback_image="materials_ui_x_24.png" -                   allow_no_texture="true" -                   follows="left|top" -                   top_pad="8" -                   height="151" -                   layout="topleft" -                   left="10" -                   name="emissive_texture" -                   width="128" /> -        <text -                   type="string" -                   font.style="BOLD" -                   length="1" -                   follows="left|top" -                   height="10" -                   width="128" -                   layout="topleft" -                   left="10" -                   top_pad="-17" -                   name="emissive_upload_fee" -           > -          No upload fee -        </text> -        <text -                   type="string" -                   length="1" -                   follows="left|top" -                   height="10" -                   layout="topleft" -                   left_pad="5" -                   top="8" -             > -          Tint -        </text> -        <color_swatch -                          can_apply_immediately="true" -                          follows="left|top" -                          height="40" -                          label_height="0" -                          layout="topleft" -                          left_delta="0" -                          top_pad="5" -                          name="emissive color" -                          width="40" /> -        <!--<text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             width="64" -             layout="topleft" -             left_delta="0" -             top_pad="5" -             > -      Intensity -    </text> -    <spinner -               decimal_digits="3" -               follows="left|top" -               height="19" -               increment="0.01" -               initial_value="0" -               layout="topleft" -               left_delta="0" -               top_pad="5" -               max_val="100" -              width="64" -             />--> -      </panel> -      <panel -        border="true" -             follows="left|top" -             width="246" -             height="175" -             layout="topleft" -             left="1" -             mouse_opaque="false" -             top_pad="5" -             name="normal_texture_pnl" -         > -        <text -                   type="string" -                   font.style="BOLD" -                   length="1" -                   follows="left|top" -                   height="10" -                   layout="topleft" -                   left="10" -                   top="5" -                   width="64"> -          Normal: -        </text> -        <texture_picker -                   can_apply_immediately="true" -                   default_image_name="Default" -                   fallback_image="materials_ui_x_24.png" -                   allow_no_texture="true" -                   follows="left|top" -                   top_pad="8" -                   height="151" -                   layout="topleft" -                   left="10" -                   name="normal_texture" -                   width="128" /> -        <text -                   type="string" -                   font.style="BOLD" -                   length="1" -                   follows="left|top" -                   height="10" -                   width="128" -                   layout="topleft" -                   left="10" -                   top_pad="-17" -                   name="normal_upload_fee" -           > -          No upload fee -        </text> -      </panel> -    </panel> +     name="panel_material" +     filename="panel_gltf_material.xml" +     border="false" +     visible="true" +     layout="topleft" +     top="0" +     left="0" +     height="768" +     width="247" />    </scroll_container>    <panel diff --git a/indra/newview/skins/default/xui/en/panel_gltf_material.xml b/indra/newview/skins/default/xui/en/panel_gltf_material.xml new file mode 100644 index 0000000000..f4060648b9 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_gltf_material.xml @@ -0,0 +1,382 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + layout="topleft" + follows="all" + border="false" + name="panel_gltf_material" + top="0" + left="0" + height="768" + width="247"> +  <check_box +    follows="left|top" +    layout="topleft" +    label="Double Sided" +    left="10" +    top="0" +    name="double sided" +    height="25" +    width="120" /> +  <panel +    border="true" +    follows="left|top" +    width="246" +    height="196" +    layout="topleft" +    left="1" +    mouse_opaque="false" +    name="base_color_texture_pnl" +    top_pad="5" +         > +    <text +      type="string" +      font.style="BOLD" +      length="1" +      follows="left|top" +      height="10" +      layout="topleft" +      left="10" +      top="5" +      width="128"> +      Base Color: +    </text> +    <texture_picker +      can_apply_immediately="true" +      default_image_name="Default" +      fallback_image="materials_ui_x_24.png" +      allow_no_texture="true" +      follows="left|top" +      top_pad="8" +      height="151" +      layout="topleft" +      left="10" +      name="base_color_texture" +      tool_tip="Base Color map.  Alpha channel is optional and used for transparency." +      width="128" /> +    <text +      type="string" +      font.style="BOLD" +      length="1" +      follows="left|top" +      height="10" +      width="128" +      layout="topleft" +      left="10" +      top_pad="-17" +      name="base_color_upload_fee"> +      No upload fee +    </text> +    <text +      type="string" +      length="1" +      follows="left|top" +      height="10" +      layout="topleft" +      left_pad="5" +      top="8"> +      Tint +    </text> +    <color_swatch +      can_apply_immediately="true" +      follows="left|top" +      height="40" +      label_height="0" +      layout="topleft" +      left_delta="0" +      top_pad="5" +      name="base color" +      width="40" /> +    <text +      type="string" +      length="1" +      follows="left|top" +      height="10" +      layout="topleft" +      left_delta="0" +      top_pad="5" +      width="96"> +      Transparency +    </text> +    <spinner +      decimal_digits="3" +      follows="left|top" +      height="19" +      increment="0.01" +      initial_value="1" +      layout="topleft" +      left_delta="0" +      top_pad="5" +      min_val="0" +      max_val="1" +      name="transparency" +      width="64"/> +    <text +      type="string" +      length="1" +      follows="left|top" +      height="10" +      layout="topleft" +      left_delta="0" +      name="label alphamode" +      text_readonly_color="LabelDisabledColor" +      top_pad="5" +      width="90"> +      Alpha mode +    </text> +    <combo_box +     height="23" +     layout="topleft" +     left_delta="0" +     name="alpha mode" +     top_pad="4" +     width="96"> +      <combo_box.item +       label="Opaque" +       name="None" +       value="OPAQUE" /> +      <combo_box.item +       label="Blend" +       name="Alpha blending" +       value="BLEND" /> +      <combo_box.item +       label="Mask" +       name="Alpha masking" +       value="MASK" /> +    </combo_box> +    <text +      type="string" +      length="1" +      follows="left|top" +      height="10" +      layout="topleft" +      left_delta="0" +      top_pad="5" +      width="96"> +      Alpha Cutoff +    </text> +    <spinner +      decimal_digits="3" +      follows="left|top" +      height="19" +      increment="0.01" +      initial_value="1" +      layout="topleft" +      left_delta="0" +      top_pad="5" +      min_val="0" +      max_val="1" +      name="alpha cutoff" +      width="64"/> +  </panel> +  <panel +    border="true" +    follows="left|top" +    width="246" +    height="175" +    layout="topleft" +    left="1" +    mouse_opaque="false" +    name="metallic_texture_pnl" +    top_pad="5"> +    <text +      type="string" +      font.style="BOLD" +      length="1" +      follows="left|top" +      height="10" +      layout="topleft" +      left="10" +      top="5"> +      Metallic-Roughness: +    </text> +    <texture_picker +      can_apply_immediately="true" +      default_image_name="Default" +      fallback_image="materials_ui_x_24.png" +      allow_no_texture="true" +      follows="left|top" +      width="128" +      height="151" +      layout="topleft" +      left="10" +      name="metallic_roughness_texture" +      tool_tip="GLTF metallic-roughness map with optional occlusion.  Red channel is occlusion, green channel is roughness, blue channel is metalness." +      top_pad="8"/> +    <text +      type="string" +      font.style="BOLD" +      length="1" +      follows="left|top" +      height="10" +      width="128" +      layout="topleft" +      left="10" +      top_pad="-17" +      name="metallic_upload_fee"> +      No upload fee +    </text> +    <text +      type="string" +      length="1" +      follows="left|top" +      height="10" +      layout="topleft" +      left_pad="5" +      top="8"> +      Metallic Factor +    </text> +    <spinner +      decimal_digits="3" +      follows="left|top" +      height="19" +      increment="0.01" +      initial_value="0" +      layout="topleft" +      left_delta="0" +      top_pad="5" +      min_val="0" +      max_val="1" +      name="metalness factor" +      width="64"/> +    <text +      type="string" +      length="1" +      follows="left|top" +      height="10" +      layout="topleft" +      left_delta="0" +      top_pad="5" +      width="96"> +      Roughness Factor +    </text> +    <spinner +      decimal_digits="3" +      follows="left|top" +      height="19" +      increment="0.01" +      initial_value="0" +      layout="topleft" +      left_delta="0" +      top_pad="5" +      min_val="0" +      max_val="1" +      name="roughness factor" +      width="64"/> +  </panel> +  <panel +    border="true" +    follows="left|top" +    width="246" +    height="175" +    layout="topleft" +    left="1" +    mouse_opaque="false" +    name="emissive_texture_pnl" +    top_pad="5"> +    <text +      type="string" +      font.style="BOLD" +      length="1" +      follows="left|top" +      height="10" +      layout="topleft" +      left="10" +      top="5" +      width="64"> +      Emissive: +    </text> +    <texture_picker +      can_apply_immediately="true" +      default_image_name="Default" +      fallback_image="materials_ui_x_24.png" +      allow_no_texture="true" +      follows="left|top" +      top_pad="8" +      height="151" +      layout="topleft" +      left="10" +      name="emissive_texture" +      width="128" /> +    <text +      type="string" +      font.style="BOLD" +      length="1" +      follows="left|top" +      height="10" +      width="128" +      layout="topleft" +      left="10" +      top_pad="-17" +      name="emissive_upload_fee"> +      No upload fee +    </text> +    <text +      type="string" +      length="1" +      follows="left|top" +      height="10" +      layout="topleft" +      left_pad="5" +      top="8"> +      Tint +    </text> +    <color_swatch +     can_apply_immediately="true" +     follows="left|top" +     height="40" +     label_height="0" +     layout="topleft" +     left_delta="0" +     top_pad="5" +     name="emissive color" +     width="40" /> +  </panel> +  <panel +    border="true" +    follows="left|top" +    width="246" +    height="175" +    layout="topleft" +    left="1" +    mouse_opaque="false" +    top_pad="5" +    name="normal_texture_pnl"> +    <text +      type="string" +      font.style="BOLD" +      length="1" +      follows="left|top" +      height="10" +      layout="topleft" +      left="10" +      top="5" +      width="64"> +      Normal: +    </text> +    <texture_picker +      can_apply_immediately="true" +      default_image_name="Default" +      fallback_image="materials_ui_x_24.png" +      allow_no_texture="true" +      follows="left|top" +      top_pad="8" +      height="151" +      layout="topleft" +      left="10" +      name="normal_texture" +      width="128" /> +    <text +      type="string" +      font.style="BOLD" +      length="1" +      follows="left|top" +      height="10" +      width="128" +      layout="topleft" +      left="10" +      top_pad="-17" +      name="normal_upload_fee"> +      No upload fee +    </text> +  </panel> +</panel> | 
