summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llgltfmateriallist.cpp40
-rw-r--r--indra/newview/llgltfmateriallist.h2
-rw-r--r--indra/newview/llpanelface.cpp227
-rw-r--r--indra/newview/llpanelface.h67
4 files changed, 262 insertions, 74 deletions
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index 45de0b71ae..cff2d22f18 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -147,6 +147,11 @@ public:
LLGLTFMaterialOverrideDispatchHandler() = default;
~LLGLTFMaterialOverrideDispatchHandler() override = default;
+ void addCallback(void(*callback)(const LLUUID& object_id, S32 side))
+ {
+ mCallbacks.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 +215,7 @@ public:
return true;
}
- static void applyData(const LLGLTFOverrideCacheEntry &object_override)
+ void applyData(const LLGLTFOverrideCacheEntry &object_override)
{
// Parse the data
@@ -225,6 +230,8 @@ public:
bool mSuccess;
};
+ std::vector<void(*)(const LLUUID& object_id, S32 side)> callbacks = mCallbacks;
+
// fromJson() is performance heavy offload to a thread.
main_queue->postTo(
general_queue,
@@ -264,7 +271,7 @@ public:
}
return results;
},
- [object_override](std::vector<ReturnData> results) // Callback to main thread
+ [object_override, callbacks](std::vector<ReturnData> results) // Callback to main thread
{
LLViewerObject * obj = gObjectList.findObject(object_override.mObjectId);
@@ -288,6 +295,10 @@ public:
else if (obj && obj->isAnySelected())
{
LLMaterialEditor::updateLive(object_override.mObjectId, results[i].mSide);
+ for (auto& override_update_callback : callbacks)
+ {
+ override_update_callback(object_override.mObjectId, results[i].mSide);
+ }
}
}
else
@@ -296,6 +307,10 @@ public:
if (obj && obj->isAnySelected())
{
LLMaterialEditor::updateLive(object_override.mObjectId, results[i].mSide);
+ for (auto& override_update_callback : callbacks)
+ {
+ override_update_callback(object_override.mObjectId, results[i].mSide);
+ }
}
}
}
@@ -311,6 +326,10 @@ public:
if (object_has_selection)
{
LLMaterialEditor::updateLive(object_override.mObjectId, i);
+ for (auto& override_update_callback : callbacks)
+ {
+ override_update_callback(object_override.mObjectId, i);
+ }
}
}
}
@@ -325,11 +344,17 @@ public:
if (object_has_selection)
{
LLMaterialEditor::updateLive(obj->getID(), i);
+ for (auto& override_update_callback : callbacks)
+ {
+ override_update_callback(obj->getID(), i);
+ }
}
}
}
});
}
+
+ std::vector<void(*)(const LLUUID& object_id, S32 side)> mCallbacks;
};
namespace
@@ -371,6 +396,10 @@ void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj)
if (object_has_selection)
{
LLMaterialEditor::updateLive(id, i);
+ for (auto& override_update_callback : handle_gltf_override_message.mCallbacks)
+ {
+ override_update_callback(id, i);
+ }
}
}
}
@@ -459,6 +488,11 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
}
}
+void LLGLTFMaterialList::addUpdateCallback(void(*update_callback)(const LLUUID& object_id, S32 side))
+{
+ handle_gltf_override_message.addCallback(update_callback);
+}
+
class AssetLoadUserData
{
public:
@@ -713,5 +747,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);
}
diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h
index 0f0edf7414..5a184f5e94 100644
--- a/indra/newview/llgltfmateriallist.h
+++ b/indra/newview/llgltfmateriallist.h
@@ -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 addUpdateCallback(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:
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 84b1ff63f4..b7e92bf315 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -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::addUpdateCallback(&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.onObjectUpdated(object_id, side);
+}
+
//////////////////////////////////////////////////////////////////////////////
//
void LLPanelFace::navigateToTitleMedia( const std::string url )
@@ -4677,7 +4652,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 +4674,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::onObjectUpdated(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)
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 69744689b5..520b399d42 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -49,6 +49,8 @@ class LLFloater;
class LLMaterialID;
class LLMediaCtrl;
class LLMenuButton;
+class LLGLTFMaterial;
+struct LLGLTFMaterial::TextureTransform;
// Represents an edit for use in replicating the op across one or more materials in the selection set.
//
@@ -102,7 +104,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 +178,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 +230,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 +294,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 +453,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 onObjectUpdated(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