diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 1df8838738689ac40908934e79293b02aa4d3fa7..2be8b8c17db0b16aaca81cd5cf3a79770aa9a0e9 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -438,6 +438,18 @@ void LLView::setEnabled(BOOL enabled)
 	mEnabled = enabled;
 }
 
+//virtual
+bool LLView::isAvailable() const
+{
+    return isInEnabledChain() && isInVisibleChain();
+}
+
+//static
+bool LLView::isAvailable(const LLView* view)
+{
+    return view && view->isAvailable();
+}
+
 //virtual
 BOOL LLView::setLabelArg( const std::string& key, const LLStringExplicit& text )
 {
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 7ddff2bd9efc47bf7729f27e600a5fbaf1157e7d..f630932317069a69041f80e39f27fe040e230e29 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -304,6 +304,11 @@ class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElem
 	BOOL			getVisible() const			{ return mVisible; }
 	virtual void	setEnabled(BOOL enabled);
 	BOOL			getEnabled() const			{ return mEnabled; }
+	/// 'available' in this context means 'visible and enabled': in other
+	/// words, can a user actually interact with this?
+	virtual bool	isAvailable() const;
+	/// The static isAvailable() tests an LLView* that could be NULL.
+	static bool		isAvailable(const LLView* view);
 	U8              getSoundFlags() const       { return mSoundFlags; }
 
 	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );