Merge pull request #16 from secondlife/SL-18732

Sl 18732: Fix responsiveness of GLTF texture transform controls in build floater
meow-7.2.2
cosmic-linden 2022-11-30 09:27:22 -08:00 committed by GitHub
commit c99c24939a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 264 additions and 89 deletions

View File

@ -32,7 +32,6 @@
#include "lldispatcher.h"
#include "llfetchedgltfmaterial.h"
#include "llfilesystem.h"
#include "llmaterialeditor.h"
#include "llsdserialize.h"
#include "lltinygltfhelper.h"
#include "llviewercontrol.h"
@ -147,6 +146,11 @@ public:
LLGLTFMaterialOverrideDispatchHandler() = default;
~LLGLTFMaterialOverrideDispatchHandler() override = default;
void addCallback(void(*callback)(const LLUUID& object_id, S32 side))
{
mSelectionCallbacks.push_back(callback);
}
bool operator()(const LLDispatcher* dispatcher, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override
{
LL_PROFILE_ZONE_SCOPED;
@ -210,7 +214,15 @@ public:
return true;
}
static void applyData(const LLGLTFOverrideCacheEntry &object_override)
void doSelectionCallbacks(const LLUUID& object_id, S32 side)
{
for (auto& callback : mSelectionCallbacks)
{
callback(object_id, side);
}
}
void applyData(const LLGLTFOverrideCacheEntry &object_override)
{
// Parse the data
@ -264,7 +276,7 @@ public:
}
return results;
},
[object_override](std::vector<ReturnData> results) // Callback to main thread
[object_override, this](std::vector<ReturnData> results) // Callback to main thread
{
LLViewerObject * obj = gObjectList.findObject(object_override.mObjectId);
@ -285,32 +297,31 @@ public:
// object not ready to receive override data, queue for later
gGLTFMaterialList.queueOverrideUpdate(object_override.mObjectId, results[i].mSide, results[i].mMaterial);
}
else if (obj && obj->isAnySelected())
else if (obj && obj->getTE(i) && obj->getTE(i)->isSelected())
{
LLMaterialEditor::updateLive(object_override.mObjectId, results[i].mSide);
doSelectionCallbacks(object_override.mObjectId, results[i].mSide);
}
}
else
{
// unblock material editor
if (obj && obj->isAnySelected())
if (obj && obj->getTE(i) && obj->getTE(i)->isSelected())
{
LLMaterialEditor::updateLive(object_override.mObjectId, results[i].mSide);
doSelectionCallbacks(object_override.mObjectId, results[i].mSide);
}
}
}
if (obj && side_set.size() != obj->getNumTEs())
{ // object exists and at least one texture entry needs to have its override data nulled out
bool object_has_selection = obj->isAnySelected();
for (int i = 0; i < obj->getNumTEs(); ++i)
{
if (side_set.find(i) == side_set.end())
{
obj->setTEGLTFMaterialOverride(i, nullptr);
if (object_has_selection)
if (obj->getTE(i) && obj->getTE(i)->isSelected())
{
LLMaterialEditor::updateLive(object_override.mObjectId, i);
doSelectionCallbacks(object_override.mObjectId, i);
}
}
}
@ -318,18 +329,21 @@ public:
}
else if (obj)
{ // override list was empty or an error occurred, null out all overrides for this object
bool object_has_selection = obj->isAnySelected();
for (int i = 0; i < obj->getNumTEs(); ++i)
{
obj->setTEGLTFMaterialOverride(i, nullptr);
if (object_has_selection)
if (obj->getTE(i) && obj->getTE(i)->isSelected())
{
LLMaterialEditor::updateLive(obj->getID(), i);
doSelectionCallbacks(obj->getID(), i);
}
}
}
});
}
private:
std::vector<void(*)(const LLUUID& object_id, S32 side)> mSelectionCallbacks;
};
namespace
@ -357,20 +371,19 @@ void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj)
if (iter != mQueuedOverrides.end())
{
bool object_has_selection = obj->isAnySelected();
override_list_t& overrides = iter->second;
for (int i = 0; i < overrides.size(); ++i)
{
if (overrides[i].notNull())
{
if (!obj->getTE(i)->getGLTFMaterial())
if (!obj->getTE(i) || !obj->getTE(i)->getGLTFMaterial())
{ // object doesn't have its base GLTF material yet, don't apply override (yet)
return;
}
obj->setTEGLTFMaterialOverride(i, overrides[i]);
if (object_has_selection)
if (obj->getTE(i)->isSelected())
{
LLMaterialEditor::updateLive(id, i);
handle_gltf_override_message.doSelectionCallbacks(id, i);
}
}
}
@ -459,6 +472,11 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
}
}
void LLGLTFMaterialList::addSelectionUpdateCallback(void(*update_callback)(const LLUUID& object_id, S32 side))
{
handle_gltf_override_message.addCallback(update_callback);
}
class AssetLoadUserData
{
public:
@ -713,5 +731,5 @@ void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides,
void LLGLTFMaterialList::loadCacheOverrides(const LLGLTFOverrideCacheEntry& override)
{
LLGLTFMaterialOverrideDispatchHandler::applyData(override);
handle_gltf_override_message.applyData(override);
}

View File

@ -74,6 +74,8 @@ public:
// Automatically called once per frame, but may be called explicitly
// for cases that care about the done_callback forwarded to LLCoros::instance().launch
static void flushUpdates(void(*done_callback)(bool) = nullptr);
static void addSelectionUpdateCallback(void(*update_callback)(const LLUUID& object_id, S32 side));
// Queue an explicit LLSD ModifyMaterialParams update apply given override data
// overrides -- LLSD map (or array of maps) in the format:

View File

@ -408,6 +408,9 @@ BOOL LLMaterialEditor::postBuild()
if (mIsOverride)
{
// Material override change success callback
LLGLTFMaterialList::addSelectionUpdateCallback(&LLMaterialEditor::updateLive);
// Live editing needs a recovery mechanism on cancel
mBaseColorTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY));
mMetallicTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY));

View File

@ -32,7 +32,6 @@
// library includes
#include "llcalc.h"
#include "llerror.h"
#include "llfocusmgr.h"
#include "llrect.h"
#include "llstring.h"
#include "llfontgl.h"
@ -95,6 +94,8 @@
using namespace std::literals;
LLPanelFace::Selection LLPanelFace::sMaterialOverrideSelection;
//
// Constant definitions for comboboxes
// Must match the commbobox definitions in panel_tools_texture.xml
@ -136,7 +137,7 @@ LLGLTFMaterial::TextureInfo texture_info_from_pbrtype(S32 pbr_type)
}
}
void updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*)> func)
void LLPanelFace::updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*)> func)
{
struct LLSelectedTEGLTFMaterialFunctor : public LLSelectedTEFunctor
{
@ -158,6 +159,7 @@ void updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*)> func)
std::function<void(LLGLTFMaterial*)> mFunc;
} select_func(func);
LLSelectMgr::getInstance()->getSelection()->applyToTEs(&select_func);
}
@ -268,11 +270,14 @@ BOOL LLPanelFace::postBuild()
childSetCommitCallback("add_media", &LLPanelFace::onClickBtnAddMedia, this);
childSetCommitCallback("delete_media", &LLPanelFace::onClickBtnDeleteMedia, this);
childSetCommitCallback("gltfTextureScaleU", boost::bind(&LLPanelFace::onCommitGLTFTextureScaleU, this, _1), nullptr);
childSetCommitCallback("gltfTextureScaleV", boost::bind(&LLPanelFace::onCommitGLTFTextureScaleV, this, _1), nullptr);
childSetCommitCallback("gltfTextureRotation", boost::bind(&LLPanelFace::onCommitGLTFRotation, this, _1), nullptr);
childSetCommitCallback("gltfTextureOffsetU", boost::bind(&LLPanelFace::onCommitGLTFTextureOffsetU, this, _1), nullptr);
childSetCommitCallback("gltfTextureOffsetV", boost::bind(&LLPanelFace::onCommitGLTFTextureOffsetV, this, _1), nullptr);
getChild<LLUICtrl>("gltfTextureScaleU")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureScaleU, this, _1), nullptr);
getChild<LLUICtrl>("gltfTextureScaleV")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureScaleV, this, _1), nullptr);
getChild<LLUICtrl>("gltfTextureRotation")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFRotation, this, _1), nullptr);
getChild<LLUICtrl>("gltfTextureOffsetU")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureOffsetU, this, _1), nullptr);
getChild<LLUICtrl>("gltfTextureOffsetV")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureOffsetV, this, _1), nullptr);
LLGLTFMaterialList::addSelectionUpdateCallback(&LLPanelFace::onMaterialOverrideReceived);
sMaterialOverrideSelection.connect();
childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
childSetAction("button align textures", &LLPanelFace::onAlignTexture, this);
@ -486,6 +491,11 @@ void LLPanelFace::draw()
updateMediaTitle();
LLPanel::draw();
if (sMaterialOverrideSelection.update())
{
setMaterialOverridesFromSelection();
}
}
void LLPanelFace::sendTexture()
@ -1773,7 +1783,7 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
{
has_pbr_material = false;
BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
const bool editable = objectp->permModify() && !objectp->isPermanentEnforced();
bool has_pbr_capabilities = LLMaterialEditor::capabilitiesAvailable();
// pbr material
@ -1784,10 +1794,11 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
bool identical_pbr;
LLSelectedTE::getPbrMaterialId(pbr_id, identical_pbr);
has_pbr_material = pbr_id.notNull();
pbr_ctrl->setTentative(identical_pbr ? FALSE : TRUE);
pbr_ctrl->setEnabled(editable && has_pbr_capabilities);
pbr_ctrl->setImageAssetID(pbr_id);
has_pbr_material = pbr_id.notNull();
}
getChildView("pbr_from_inventory")->setEnabled(editable && has_pbr_capabilities);
@ -1797,14 +1808,13 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
const bool show_pbr = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR && mComboMatMedia->getEnabled();
if (show_pbr)
{
const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex();
const LLGLTFMaterial::TextureInfo texture_info = texture_info_from_pbrtype(pbr_type);
const bool show_texture_info = texture_info != LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT;
LLUICtrl* gltfCtrlTextureScaleU = getChild<LLUICtrl>("gltfTextureScaleU");
LLUICtrl* gltfCtrlTextureScaleV = getChild<LLUICtrl>("gltfTextureScaleV");
LLUICtrl* gltfCtrlTextureRotation = getChild<LLUICtrl>("gltfTextureRotation");
LLUICtrl* gltfCtrlTextureScaleV = getChild<LLUICtrl>("gltfTextureScaleV");
LLUICtrl* gltfCtrlTextureRotation = getChild<LLUICtrl>("gltfTextureRotation");
LLUICtrl* gltfCtrlTextureOffsetU = getChild<LLUICtrl>("gltfTextureOffsetU");
LLUICtrl* gltfCtrlTextureOffsetV = getChild<LLUICtrl>("gltfTextureOffsetV");
@ -1814,48 +1824,7 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
gltfCtrlTextureOffsetU->setEnabled(show_texture_info && has_pbr_capabilities);
gltfCtrlTextureOffsetV->setEnabled(show_texture_info && has_pbr_capabilities);
if (show_texture_info)
{
LLGLTFMaterial::TextureTransform transform;
bool scale_u_same = true;
bool scale_v_same = true;
bool rotation_same = true;
bool offset_u_same = true;
bool offset_v_same = true;
readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
{
return mat ? mat->mTextureTransform[texture_info].mScale[VX] : 0.f;
}, transform.mScale[VX], scale_u_same, true, 1e-3f);
readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
{
return mat ? mat->mTextureTransform[texture_info].mScale[VY] : 0.f;
}, transform.mScale[VY], scale_v_same, true, 1e-3f);
readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
{
return mat ? mat->mTextureTransform[texture_info].mRotation : 0.f;
}, transform.mRotation, rotation_same, true, 1e-3f);
readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
{
return mat ? mat->mTextureTransform[texture_info].mOffset[VX] : 0.f;
}, transform.mOffset[VX], offset_u_same, true, 1e-3f);
readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
{
return mat ? mat->mTextureTransform[texture_info].mOffset[VY] : 0.f;
}, transform.mOffset[VY], offset_v_same, true, 1e-3f);
gltfCtrlTextureScaleU->setValue(transform.mScale[VX]);
gltfCtrlTextureScaleV->setValue(transform.mScale[VY]);
gltfCtrlTextureRotation->setValue(transform.mRotation * RAD_TO_DEG);
gltfCtrlTextureOffsetU->setValue(transform.mOffset[VX]);
gltfCtrlTextureOffsetV->setValue(transform.mOffset[VY]);
gltfCtrlTextureScaleU->setTentative(!scale_u_same);
gltfCtrlTextureScaleV->setTentative(!scale_v_same);
gltfCtrlTextureRotation->setTentative(!rotation_same);
gltfCtrlTextureOffsetU->setTentative(!offset_u_same);
gltfCtrlTextureOffsetV->setTentative(!offset_v_same);
}
// Control values are set in setMaterialOverridesFromSelection
}
}
@ -2084,6 +2053,12 @@ void LLPanelFace::unloadMedia()
mTitleMedia->unloadMediaSource();
}
// static
void LLPanelFace::onMaterialOverrideReceived(const LLUUID& object_id, S32 side)
{
sMaterialOverrideSelection.onSelectedObjectUpdated(object_id, side);
}
//////////////////////////////////////////////////////////////////////////////
//
void LLPanelFace::navigateToTitleMedia( const std::string url )
@ -2828,6 +2803,7 @@ void LLPanelFace::onCommitPbrType(LLUICtrl* ctrl, void* userdata)
// and generally reflecting old state when switching tabs or objects
//
self->updateUI();
self->setMaterialOverridesFromSelection();
}
// static
@ -4677,7 +4653,7 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
self->sendTextureInfo();
}
void updateGLTFTextureTransform(float value, U32 pbr_type, std::function<void(LLGLTFMaterial::TextureTransform*)> edit)
void LLPanelFace::updateGLTFTextureTransform(float value, U32 pbr_type, std::function<void(LLGLTFMaterial::TextureTransform*)> edit)
{
U32 texture_info_start;
U32 texture_info_end;
@ -4699,6 +4675,148 @@ void updateGLTFTextureTransform(float value, U32 pbr_type, std::function<void(LL
edit(&new_transform);
}
});
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
if (node)
{
LLViewerObject* object = node->getObject();
sMaterialOverrideSelection.setObjectUpdatePending(object->getID(), node->getLastSelectedTE());
}
}
void LLPanelFace::setMaterialOverridesFromSelection()
{
const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex();
const LLGLTFMaterial::TextureInfo texture_info = texture_info_from_pbrtype(pbr_type);
if (texture_info == LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_COUNT)
{
return;
}
LLGLTFMaterial::TextureTransform transform;
bool scale_u_same = true;
bool scale_v_same = true;
bool rotation_same = true;
bool offset_u_same = true;
bool offset_v_same = true;
readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
{
return mat ? mat->mTextureTransform[texture_info].mScale[VX] : 0.f;
}, transform.mScale[VX], scale_u_same, true, 1e-3f);
readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
{
return mat ? mat->mTextureTransform[texture_info].mScale[VY] : 0.f;
}, transform.mScale[VY], scale_v_same, true, 1e-3f);
readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
{
return mat ? mat->mTextureTransform[texture_info].mRotation : 0.f;
}, transform.mRotation, rotation_same, true, 1e-3f);
readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
{
return mat ? mat->mTextureTransform[texture_info].mOffset[VX] : 0.f;
}, transform.mOffset[VX], offset_u_same, true, 1e-3f);
readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
{
return mat ? mat->mTextureTransform[texture_info].mOffset[VY] : 0.f;
}, transform.mOffset[VY], offset_v_same, true, 1e-3f);
LLUICtrl* gltfCtrlTextureScaleU = getChild<LLUICtrl>("gltfTextureScaleU");
LLUICtrl* gltfCtrlTextureScaleV = getChild<LLUICtrl>("gltfTextureScaleV");
LLUICtrl* gltfCtrlTextureRotation = getChild<LLUICtrl>("gltfTextureRotation");
LLUICtrl* gltfCtrlTextureOffsetU = getChild<LLUICtrl>("gltfTextureOffsetU");
LLUICtrl* gltfCtrlTextureOffsetV = getChild<LLUICtrl>("gltfTextureOffsetV");
gltfCtrlTextureScaleU->setValue(transform.mScale[VX]);
gltfCtrlTextureScaleV->setValue(transform.mScale[VY]);
gltfCtrlTextureRotation->setValue(transform.mRotation * RAD_TO_DEG);
gltfCtrlTextureOffsetU->setValue(transform.mOffset[VX]);
gltfCtrlTextureOffsetV->setValue(transform.mOffset[VY]);
gltfCtrlTextureScaleU->setTentative(!scale_u_same);
gltfCtrlTextureScaleV->setTentative(!scale_v_same);
gltfCtrlTextureRotation->setTentative(!rotation_same);
gltfCtrlTextureOffsetU->setTentative(!offset_u_same);
gltfCtrlTextureOffsetV->setTentative(!offset_v_same);
}
void LLPanelFace::Selection::connect()
{
if (!mSelectConnection.connected())
{
mSelectConnection = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLPanelFace::Selection::onSelectionChanged, this));
}
}
bool LLPanelFace::Selection::update()
{
const bool selection_changed = compareSelection();
if (selection_changed)
{
clearObjectUpdatePending();
}
else if (isObjectUpdatePending())
{
return false;
}
const bool changed = mChanged;
mChanged = false;
return changed;
}
void LLPanelFace::Selection::setObjectUpdatePending(const LLUUID &object_id, S32 side)
{
mPendingObjectID = object_id;
mPendingSide = side;
}
void LLPanelFace::Selection::onSelectedObjectUpdated(const LLUUID& object_id, S32 side)
{
if (object_id == mSelectedObjectID && side == mSelectedSide)
{
mChanged = true;
clearObjectUpdatePending();
}
}
void LLPanelFace::Selection::clearObjectUpdatePending()
{
mPendingObjectID = LLUUID::null;
mPendingSide = -1;
}
bool LLPanelFace::Selection::compareSelection()
{
if (!mNeedsSelectionCheck)
{
return false;
}
mNeedsSelectionCheck = false;
const S32 old_object_count = mSelectedObjectCount;
const LLUUID old_object_id = mSelectedObjectID;
const S32 old_side = mSelectedSide;
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
LLSelectNode* node = selection->getFirstNode();
if (node)
{
LLViewerObject* object = node->getObject();
mSelectedObjectCount = selection->getObjectCount();
mSelectedObjectID = object->getID();
mSelectedSide = node->getLastSelectedTE();
}
else
{
mSelectedObjectCount = 0;
mSelectedObjectID = LLUUID::null;
mSelectedSide = -1;
}
const bool selection_changed = old_object_count != mSelectedObjectCount || old_object_id != mSelectedObjectID || old_side != mSelectedSide;
mChanged = mChanged || selection_changed;
return selection_changed;
}
void LLPanelFace::onCommitGLTFTextureScaleU(LLUICtrl* ctrl)

View File

@ -29,6 +29,7 @@
#include "v4color.h"
#include "llpanel.h"
#include "llgltfmaterial.h"
#include "llmaterial.h"
#include "llmaterialmgr.h"
#include "lltextureentry.h"
@ -102,7 +103,7 @@ public:
void refreshMedia();
void unloadMedia();
static void onGLTFMaterialUpdate(const LLUUID& object_id, S32 side);
static void onMaterialOverrideReceived(const LLUUID& object_id, S32 side);
/*virtual*/ void draw();
@ -176,7 +177,6 @@ protected:
//
// @param force_set_values forces spinners to set value even if they are focused
void updateUI(bool force_set_values = false);
void updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool force_set_values);
// Convenience func to determine if all faces in selection have
// identical planar texgen settings during edits
@ -229,11 +229,13 @@ protected:
static void onCommitGlow( LLUICtrl* ctrl, void *userdata);
static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata);
static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo);
void onCommitGLTFTextureScaleU(LLUICtrl* ctrl);
void onCommitGLTFTextureScaleV(LLUICtrl* ctrl);
void onCommitGLTFRotation(LLUICtrl* ctrl);
void onCommitGLTFTextureOffsetU(LLUICtrl* ctrl);
void onCommitGLTFTextureOffsetV(LLUICtrl* ctrl);
static void onClickAutoFix(void*);
static void onAlignTexture(void*);
static void onClickBtnLoadInvPBR(void* userdata);
@ -291,7 +293,6 @@ private:
// Do NOT call updateUI from within this function.
//
void updateVisibility();
void updateVisibilityGLTF();
// Hey look everyone, a type-safe alternative to copy and paste! :)
//
@ -451,29 +452,62 @@ private:
void onTextureSelectionChanged(LLInventoryItem* itemp);
void onPbrSelectionChanged(LLInventoryItem* itemp);
void updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool force_set_values);
void updateVisibilityGLTF();
void updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*)> func);
void updateGLTFTextureTransform(float value, U32 pbr_type, std::function<void(LLGLTFMaterial::TextureTransform*)> edit);
void setMaterialOverridesFromSelection();
LLMenuButton* mMenuClipboardColor;
LLMenuButton* mMenuClipboardTexture;
bool mIsAlpha;
/* These variables interlock processing of materials updates sent to
* the sim. mUpdateInFlight is set to flag that an update has been
* sent to the sim and not acknowledged yet, and cleared when an
* update is received from the sim. mUpdatePending is set when
* there's an update in flight and another UI change has been made
* that needs to be sent as a materials update, and cleared when the
* update is sent. This prevents the sim from getting spammed with
* update messages when, for example, the user holds down the
* up-arrow on a spinner, and avoids running afoul of its throttle.
*/
bool mUpdateInFlight;
bool mUpdatePending;
LLSD mClipboardParams;
LLSD mMediaSettings;
bool mNeedMediaTitle;
class Selection
{
public:
void connect();
// Returns true if the selected objects or sides have changed since
// this was last called, and no object update is pending
bool update();
// Prevents update() returning true until the provided object is
// updated. Necessary to prevent controls updating when the mouse is
// held down.
void setObjectUpdatePending(const LLUUID &object_id, S32 side);
// Callbacks
void onSelectionChanged() { mNeedsSelectionCheck = true; }
void onSelectedObjectUpdated(const LLUUID &object_id, S32 side);
protected:
void clearObjectUpdatePending();
bool isObjectUpdatePending() { return mPendingSide != -1; }
bool compareSelection();
bool mChanged = false;
boost::signals2::scoped_connection mSelectConnection;
bool mNeedsSelectionCheck = true;
S32 mSelectedObjectCount = 0;
LLUUID mSelectedObjectID;
S32 mSelectedSide = -1;
LLUUID mPendingObjectID;
S32 mPendingSide = -1;
};
static Selection sMaterialOverrideSelection;
public:
#if defined(DEF_GET_MAT_STATE)
#undef DEF_GET_MAT_STATE