diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index e5748ce4a5ab4709a954da7f83669264bc771518..c62fe1a82d47eb99f360e49453a815aa8cdd6ae9 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -495,6 +495,7 @@ set(viewer_SOURCE_FILES
     llpaneltiptoast.cpp
     llpanelvoiceeffect.cpp
     llpaneltopinfobar.cpp
+    llpanelpulldown.cpp
     llpanelvoicedevicesettings.cpp
     llpanelvolume.cpp
     llpanelvolumepulldown.cpp
@@ -1111,6 +1112,7 @@ set(viewer_HEADER_FILES
     llpanelsnapshot.h
     llpanelteleporthistory.h
     llpaneltiptoast.h
+    llpanelpulldown.h
     llpanelvoicedevicesettings.h
     llpanelvoiceeffect.h
     llpaneltopinfobar.h
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
index b654e928e2effb2ae4cd04f0c10a71d648bab450..a8887eb9363b09098606c84c9ae9cdc2e2170b2a 100644
--- a/indra/newview/llpanelnearbymedia.cpp
+++ b/indra/newview/llpanelnearbymedia.cpp
@@ -82,8 +82,6 @@ LLPanelNearByMedia::LLPanelNearByMedia()
 	  mParcelMediaItem(NULL),
 	  mParcelAudioItem(NULL)
 {
-	mHoverTimer.stop();
-
     // This is just an initial value, mParcelAudioAutoStart does not affect ParcelMediaAutoPlayEnable
     mParcelAudioAutoStart = gSavedSettings.getS32("ParcelMediaAutoPlayEnable") != 0
                             && gSavedSettings.getBOOL("MediaTentativeAutoPlay");
@@ -111,7 +109,7 @@ LLPanelNearByMedia::~LLPanelNearByMedia()
 
 BOOL LLPanelNearByMedia::postBuild()
 {
-	LLPanel::postBuild();
+	LLPanelPulldown::postBuild();
 
 	const S32 RESIZE_BAR_THICKNESS = 6;
 	LLResizeBar::Params p;
@@ -193,45 +191,10 @@ void LLPanelNearByMedia::handleMediaAutoPlayChanged(const LLSD& newvalue)
     inst->cancelNotification();
 }
 
-/*virtual*/
-void LLPanelNearByMedia::onMouseEnter(S32 x, S32 y, MASK mask)
-{
-	mHoverTimer.stop();
-	LLPanel::onMouseEnter(x,y,mask);
-}
-
-
-/*virtual*/
-void LLPanelNearByMedia::onMouseLeave(S32 x, S32 y, MASK mask)
-{
-	mHoverTimer.start();
-	LLPanel::onMouseLeave(x,y,mask);
-}
-
-/*virtual*/ 
-void LLPanelNearByMedia::onTopLost()
-{
-	setVisible(FALSE);
-}
-
-
-/*virtual*/ 
-void LLPanelNearByMedia::onVisibilityChange ( BOOL new_visibility )
-{
-	if (new_visibility)	
-	{
-		mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
-	}
-	else
-	{
-		mHoverTimer.stop();
-	}
-}
-
 /*virtual*/
 void LLPanelNearByMedia::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
-	LLPanel::reshape(width, height, called_from_parent);
+	LLPanelPulldown::reshape(width, height, called_from_parent);
 
 	LLButton* more_btn = findChild<LLButton>("more_btn");
 	if (more_btn && more_btn->getValue().asBoolean())
@@ -255,24 +218,14 @@ void LLPanelNearByMedia::draw()
 
 	refreshList();
 	updateControls();
-	
-	F32 alpha = mHoverTimer.getStarted() 
-		? clamp_rescale(mHoverTimer.getElapsedTimeF32(), AUTO_CLOSE_FADE_TIME_START, AUTO_CLOSE_FADE_TIME_END, 1.f, 0.f)
-		: 1.0f;
-	LLViewDrawContext context(alpha);
 
-	LLPanel::draw();
-
-	if (alpha == 0.f)
-	{
-		setVisible(false);
-	}
+	LLPanelPulldown::draw();
 }
 
 /*virtual*/
 BOOL LLPanelNearByMedia::handleHover(S32 x, S32 y, MASK mask)
 {
-	LLPanel::handleHover(x, y, mask);
+	LLPanelPulldown::handleHover(x, y, mask);
 	
 	// If we are hovering over this panel, make sure to clear any hovered media
 	// ID.  Note that the more general solution would be to clear this ID when
diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h
index a9c1b190cfb1ae0c6f7cde07c0d7648bd087ad30..2d898d0aa1e08f8a8a788b03dbac336fb3d761bf 100644
--- a/indra/newview/llpanelnearbymedia.h
+++ b/indra/newview/llpanelnearbymedia.h
@@ -27,7 +27,7 @@
 #ifndef LL_LLPANELNEARBYMEDIA_H
 #define LL_LLPANELNEARBYMEDIA_H
 
-#include "llpanel.h"
+#include "llpanelpulldown.h"
 
 class LLPanelNearbyMedia;
 class LLButton;
@@ -39,16 +39,12 @@ class LLTextBox;
 class LLComboBox;
 class LLViewerMediaImpl;
 
-class LLPanelNearByMedia : public LLPanel
+class LLPanelNearByMedia : public LLPanelPulldown
 {
 public:
 	
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void draw();
-	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
-	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
-	/*virtual*/ void onTopLost();
-	/*virtual*/ void onVisibilityChange ( BOOL new_visibility );
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
 	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
 
@@ -173,7 +169,6 @@ class LLPanelNearByMedia : public LLPanel
 	
 	LLRect				mMoreRect;
 	LLRect				mLessRect;
-	LLFrameTimer		mHoverTimer;
 	LLScrollListItem*	mParcelMediaItem;
 	LLScrollListItem*	mParcelAudioItem;
 };
diff --git a/indra/newview/llpanelpresetscamerapulldown.cpp b/indra/newview/llpanelpresetscamerapulldown.cpp
index fdf73e069e33cc772e1a551c226d5e396bc3a38f..183123e534e8a333472d94117ae9475e3d203c12 100644
--- a/indra/newview/llpanelpresetscamerapulldown.cpp
+++ b/indra/newview/llpanelpresetscamerapulldown.cpp
@@ -41,9 +41,6 @@
 #include "llscrolllistctrl.h"
 #include "lltrans.h"
 
-/* static */ const F32 LLPanelPresetsCameraPulldown::sAutoCloseFadeStartTimeSec = 2.0f;
-/* static */ const F32 LLPanelPresetsCameraPulldown::sAutoCloseTotalTimeSec = 3.0f;
-
 ///----------------------------------------------------------------------------
 /// Class LLPanelPresetsCameraPulldown
 ///----------------------------------------------------------------------------
@@ -51,8 +48,6 @@
 // Default constructor
 LLPanelPresetsCameraPulldown::LLPanelPresetsCameraPulldown()
 {
-	mHoverTimer.stop();
-
 	mCommitCallbackRegistrar.add("Presets.toggleCameraFloater", boost::bind(&LLPanelPresetsCameraPulldown::onViewButtonClick, this, _2));
 	mCommitCallbackRegistrar.add("PresetsCamera.RowClick", boost::bind(&LLPanelPresetsCameraPulldown::onRowClick, this, _2));
 
@@ -74,7 +69,7 @@ BOOL LLPanelPresetsCameraPulldown::postBuild()
 
 	populatePanel();
 
-	return LLPanel::postBuild();
+	return LLPanelPulldown::postBuild();
 }
 
 void LLPanelPresetsCameraPulldown::populatePanel()
@@ -118,61 +113,6 @@ void LLPanelPresetsCameraPulldown::populatePanel()
 	}
 }
 
-/*virtual*/
-void LLPanelPresetsCameraPulldown::onMouseEnter(S32 x, S32 y, MASK mask)
-{
-	mHoverTimer.stop();
-	LLPanel::onMouseEnter(x,y,mask);
-}
-
-/*virtual*/
-void LLPanelPresetsCameraPulldown::onTopLost()
-{
-	setVisible(FALSE);
-}
-
-/*virtual*/
-BOOL LLPanelPresetsCameraPulldown::handleMouseDown(S32 x, S32 y, MASK mask)
-{
-    LLPanel::handleMouseDown(x,y,mask);
-    return TRUE;
-}
-
-/*virtual*/
-BOOL LLPanelPresetsCameraPulldown::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
-    LLPanel::handleRightMouseDown(x, y, mask);
-    return TRUE;
-}
-
-/*virtual*/
-BOOL LLPanelPresetsCameraPulldown::handleDoubleClick(S32 x, S32 y, MASK mask)
-{
-    LLPanel::handleDoubleClick(x, y, mask);
-    return TRUE;
-}
-
-/*virtual*/
-void LLPanelPresetsCameraPulldown::onMouseLeave(S32 x, S32 y, MASK mask)
-{
-	mHoverTimer.start();
-	LLPanel::onMouseLeave(x,y,mask);
-}
-
-/*virtual*/ 
-void LLPanelPresetsCameraPulldown::onVisibilityChange ( BOOL new_visibility )
-{
-	if (new_visibility)	
-	{
-		mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
-	}
-	else
-	{
-		mHoverTimer.stop();
-
-	}
-}
-
 void LLPanelPresetsCameraPulldown::onRowClick(const LLSD& user_data)
 {
 	LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("preset_camera_list");
@@ -207,19 +147,3 @@ void LLPanelPresetsCameraPulldown::onViewButtonClick(const LLSD& user_data)
 
 	LLFloaterReg::toggleInstanceOrBringToFront("camera");
 }
-
-//virtual
-void LLPanelPresetsCameraPulldown::draw()
-{
-	F32 alpha = mHoverTimer.getStarted() 
-		? clamp_rescale(mHoverTimer.getElapsedTimeF32(), sAutoCloseFadeStartTimeSec, sAutoCloseTotalTimeSec, 1.f, 0.f)
-		: 1.0f;
-	LLViewDrawContext context(alpha);
-
-	LLPanel::draw();
-
-	if (alpha == 0.f)
-	{
-		setVisible(FALSE);
-	}
-}
diff --git a/indra/newview/llpanelpresetscamerapulldown.h b/indra/newview/llpanelpresetscamerapulldown.h
index 12d9bc26ecfb3a2b35a5d5e291a9a68e6eb2644c..c49bab042e22d8ba89871471865c7b7a53d10b0d 100644
--- a/indra/newview/llpanelpresetscamerapulldown.h
+++ b/indra/newview/llpanelpresetscamerapulldown.h
@@ -29,22 +29,12 @@
 
 #include "linden_common.h"
 
-#include "llpanel.h"
+#include "llpanelpulldown.h"
 
-class LLFrameTimer;
-
-class LLPanelPresetsCameraPulldown : public LLPanel
+class LLPanelPresetsCameraPulldown : public LLPanelPulldown
 {
  public:
 	LLPanelPresetsCameraPulldown();
-	/*virtual*/ void draw();
-	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
-	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
-    /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
-    /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
-    /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
-	/*virtual*/ void onTopLost();
-	/*virtual*/ void onVisibilityChange ( BOOL new_visibility );
 	/*virtual*/ BOOL postBuild();
 	void populatePanel();
 	
@@ -53,9 +43,6 @@ class LLPanelPresetsCameraPulldown : public LLPanel
 	void onRowClick(const LLSD& user_data);
 
 	std::list<std::string> mPresetNames;
-	LLFrameTimer mHoverTimer;
-	static const F32 sAutoCloseFadeStartTimeSec;
-	static const F32 sAutoCloseTotalTimeSec;
     LOG_CLASS(LLPanelPresetsCameraPulldown);
 };
 
diff --git a/indra/newview/llpanelpresetspulldown.cpp b/indra/newview/llpanelpresetspulldown.cpp
index 332fd9969d107728ef5bb4545af74aad578078ef..aa5ba3f210ea5ccef5052e366ec59db0a6b6d934 100644
--- a/indra/newview/llpanelpresetspulldown.cpp
+++ b/indra/newview/llpanelpresetspulldown.cpp
@@ -40,9 +40,6 @@
 #include "llscrolllistctrl.h"
 #include "lltrans.h"
 
-/* static */ const F32 LLPanelPresetsPulldown::sAutoCloseFadeStartTimeSec = 2.0f;
-/* static */ const F32 LLPanelPresetsPulldown::sAutoCloseTotalTimeSec = 3.0f;
-
 ///----------------------------------------------------------------------------
 /// Class LLPanelPresetsPulldown
 ///----------------------------------------------------------------------------
@@ -67,7 +64,7 @@ BOOL LLPanelPresetsPulldown::postBuild()
 
 	populatePanel();
 
-	return LLPanel::postBuild();
+	return LLPanelPulldown::postBuild();
 }
 
 void LLPanelPresetsPulldown::populatePanel()
@@ -111,61 +108,6 @@ void LLPanelPresetsPulldown::populatePanel()
 	}
 }
 
-/*virtual*/
-void LLPanelPresetsPulldown::onMouseEnter(S32 x, S32 y, MASK mask)
-{
-	mHoverTimer.stop();
-	LLPanel::onMouseEnter(x,y,mask);
-}
-
-/*virtual*/
-void LLPanelPresetsPulldown::onTopLost()
-{
-	setVisible(FALSE);
-}
-
-/*virtual*/
-BOOL LLPanelPresetsPulldown::handleMouseDown(S32 x, S32 y, MASK mask)
-{
-    LLPanel::handleMouseDown(x,y,mask);
-    return TRUE;
-}
-
-/*virtual*/
-BOOL LLPanelPresetsPulldown::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
-    LLPanel::handleRightMouseDown(x, y, mask);
-    return TRUE;
-}
-
-/*virtual*/
-BOOL LLPanelPresetsPulldown::handleDoubleClick(S32 x, S32 y, MASK mask)
-{
-    LLPanel::handleDoubleClick(x, y, mask);
-    return TRUE;
-}
-
-/*virtual*/
-void LLPanelPresetsPulldown::onMouseLeave(S32 x, S32 y, MASK mask)
-{
-	mHoverTimer.start();
-	LLPanel::onMouseLeave(x,y,mask);
-}
-
-/*virtual*/ 
-void LLPanelPresetsPulldown::onVisibilityChange ( BOOL new_visibility )
-{
-	if (new_visibility)	
-	{
-		mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
-	}
-	else
-	{
-		mHoverTimer.stop();
-
-	}
-}
-
 void LLPanelPresetsPulldown::onRowClick(const LLSD& user_data)
 {
 	LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("preset_list");
@@ -212,19 +154,3 @@ void LLPanelPresetsPulldown::onGraphicsButtonClick(const LLSD& user_data)
 		}
 	}
 }
-
-//virtual
-void LLPanelPresetsPulldown::draw()
-{
-	F32 alpha = mHoverTimer.getStarted() 
-		? clamp_rescale(mHoverTimer.getElapsedTimeF32(), sAutoCloseFadeStartTimeSec, sAutoCloseTotalTimeSec, 1.f, 0.f)
-		: 1.0f;
-	LLViewDrawContext context(alpha);
-
-	LLPanel::draw();
-
-	if (alpha == 0.f)
-	{
-		setVisible(FALSE);
-	}
-}
diff --git a/indra/newview/llpanelpresetspulldown.h b/indra/newview/llpanelpresetspulldown.h
index 322bf5a58f5414bf54624677d3d6d7aae825daa3..c0d32b9b21a4df5300efc26c9cf24f19ece191fb 100644
--- a/indra/newview/llpanelpresetspulldown.h
+++ b/indra/newview/llpanelpresetspulldown.h
@@ -29,22 +29,13 @@
 
 #include "linden_common.h"
 
-#include "llpanel.h"
+#include "llpanelpulldown.h"
 
-class LLFrameTimer;
 
-class LLPanelPresetsPulldown : public LLPanel
+class LLPanelPresetsPulldown : public LLPanelPulldown
 {
  public:
 	LLPanelPresetsPulldown();
-	/*virtual*/ void draw();
-	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
-	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
-    /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
-    /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
-    /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
-	/*virtual*/ void onTopLost();
-	/*virtual*/ void onVisibilityChange ( BOOL new_visibility );
 	/*virtual*/ BOOL postBuild();
 	void populatePanel();
 	
@@ -53,9 +44,6 @@ class LLPanelPresetsPulldown : public LLPanel
 	void onRowClick(const LLSD& user_data);
 
 	std::list<std::string> mPresetNames;
-	LLFrameTimer mHoverTimer;
-	static const F32 sAutoCloseFadeStartTimeSec;
-	static const F32 sAutoCloseTotalTimeSec;
     LOG_CLASS(LLPanelPresetsPulldown);
 };
 
diff --git a/indra/newview/llpanelpulldown.cpp b/indra/newview/llpanelpulldown.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4de6ee81829eadd0910a13d049d02035a70bbbba
--- /dev/null
+++ b/indra/newview/llpanelpulldown.cpp
@@ -0,0 +1,118 @@
+/**
+* @file llpanelpulldown.cpp
+* @brief A panel that serves as a basis for multiple toolbar pulldown panels
+*
+* $LicenseInfo:firstyear=2020&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2020, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelpulldown.h"
+
+const F32 AUTO_CLOSE_FADE_TIME_START_SEC = 2.0f;
+const F32 AUTO_CLOSE_FADE_TIME_END_SEC = 3.0f;
+
+///----------------------------------------------------------------------------
+/// Class LLPanelPresetsCameraPulldown
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLPanelPulldown::LLPanelPulldown()
+{
+    mHoverTimer.stop();
+}
+
+/*virtual*/
+void LLPanelPulldown::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+    mHoverTimer.stop();
+    LLPanel::onMouseEnter(x, y, mask);
+}
+
+/*virtual*/
+void LLPanelPulldown::onTopLost()
+{
+    setVisible(FALSE);
+}
+
+/*virtual*/
+BOOL LLPanelPulldown::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+    LLPanel::handleMouseDown(x, y, mask);
+    return TRUE;
+}
+
+/*virtual*/
+BOOL LLPanelPulldown::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+    LLPanel::handleRightMouseDown(x, y, mask);
+    return TRUE;
+}
+
+/*virtual*/
+BOOL LLPanelPulldown::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+    LLPanel::handleDoubleClick(x, y, mask);
+    return TRUE;
+}
+
+BOOL LLPanelPulldown::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+    LLPanel::handleScrollWheel(x, y, clicks);
+    return TRUE; //If we got here, then we are in Pulldown's rect, consume the event.
+}
+
+/*virtual*/
+void LLPanelPulldown::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+    mHoverTimer.start();
+    LLPanel::onMouseLeave(x, y, mask);
+}
+
+/*virtual*/
+void LLPanelPulldown::onVisibilityChange(BOOL new_visibility)
+{
+    if (new_visibility)
+    {
+        mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
+    }
+    else
+    {
+        mHoverTimer.stop();
+    }
+}
+
+//virtual
+void LLPanelPulldown::draw()
+{
+    F32 alpha = mHoverTimer.getStarted()
+        ? clamp_rescale(mHoverTimer.getElapsedTimeF32(), AUTO_CLOSE_FADE_TIME_START_SEC, AUTO_CLOSE_FADE_TIME_END_SEC, 1.f, 0.f)
+        : 1.0f;
+    LLViewDrawContext context(alpha);
+
+    LLPanel::draw();
+
+    if (alpha == 0.f)
+    {
+        setVisible(FALSE);
+    }
+}
diff --git a/indra/newview/llpanelpulldown.h b/indra/newview/llpanelpulldown.h
new file mode 100644
index 0000000000000000000000000000000000000000..705e76d0ab2556771806218d07aa790b731b429b
--- /dev/null
+++ b/indra/newview/llpanelpulldown.h
@@ -0,0 +1,55 @@
+/** 
+ * @file llpanelpulldown.h
+ * @brief A panel that serves as a basis for multiple toolbar pulldown panels
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELPULLDOWN_H
+#define LL_LLPANELPULLDOWN_H
+
+#include "linden_common.h"
+
+#include "llpanel.h"
+
+class LLFrameTimer;
+
+class LLPanelPulldown : public LLPanel
+{
+public:
+    LLPanelPulldown();
+    /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
+    /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
+    /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+    /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+    /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+    /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+    /*virtual*/ void onTopLost();
+    /*virtual*/ void onVisibilityChange(BOOL new_visibility);
+
+    /*virtual*/ void draw();
+
+protected:
+    LLFrameTimer mHoverTimer;
+};
+
+#endif // LL_LLPANELPULLDOWN_H
diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp
index f063d8427283b670a1f732f8691b9947e3040de3..6f11e76a72d304fa5923bd5fcf20371ac5a04552 100644
--- a/indra/newview/llpanelvolumepulldown.cpp
+++ b/indra/newview/llpanelvolumepulldown.cpp
@@ -41,9 +41,6 @@
 #include "llfloaterpreference.h"
 #include "llsliderctrl.h"
 
-/* static */ const F32 LLPanelVolumePulldown::sAutoCloseFadeStartTimeSec = 2.0f;
-/* static */ const F32 LLPanelVolumePulldown::sAutoCloseTotalTimeSec = 3.0f;
-
 ///----------------------------------------------------------------------------
 /// Class LLPanelVolumePulldown
 ///----------------------------------------------------------------------------
@@ -51,8 +48,6 @@
 // Default constructor
 LLPanelVolumePulldown::LLPanelVolumePulldown()
 {
-	mHoverTimer.stop();
-
 	mCommitCallbackRegistrar.add("Vol.setControlFalse", boost::bind(&LLPanelVolumePulldown::setControlFalse, this, _2));
 	mCommitCallbackRegistrar.add("Vol.SetSounds", boost::bind(&LLPanelVolumePulldown::onClickSetSounds, this));
 	mCommitCallbackRegistrar.add("Vol.updateMediaAutoPlayCheckbox",	boost::bind(&LLPanelVolumePulldown::updateMediaAutoPlayCheckbox, this, _1));
@@ -62,41 +57,7 @@ LLPanelVolumePulldown::LLPanelVolumePulldown()
 
 BOOL LLPanelVolumePulldown::postBuild()
 {
-	return LLPanel::postBuild();
-}
-
-/*virtual*/
-void LLPanelVolumePulldown::onMouseEnter(S32 x, S32 y, MASK mask)
-{
-	mHoverTimer.stop();
-	LLPanel::onMouseEnter(x,y,mask);
-}
-
-/*virtual*/
-void LLPanelVolumePulldown::onTopLost()
-{
-	setVisible(FALSE);
-}
-
-/*virtual*/
-void LLPanelVolumePulldown::onMouseLeave(S32 x, S32 y, MASK mask)
-{
-	mHoverTimer.start();
-	LLPanel::onMouseLeave(x,y,mask);
-}
-
-/*virtual*/ 
-void LLPanelVolumePulldown::onVisibilityChange ( BOOL new_visibility )
-{
-	if (new_visibility)	
-	{
-		mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
-	}
-	else
-	{
-		mHoverTimer.stop();
-
-	}
+	return LLPanelPulldown::postBuild();
 }
 
 void LLPanelVolumePulldown::onAdvancedButtonClick(const LLSD& user_data)
@@ -150,20 +111,3 @@ void LLPanelVolumePulldown::onClickSetSounds()
 	// or if sound effects are disabled.
 	getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds"));
 }
-
-//virtual
-void LLPanelVolumePulldown::draw()
-{
-	F32 alpha = mHoverTimer.getStarted() 
-		? clamp_rescale(mHoverTimer.getElapsedTimeF32(), sAutoCloseFadeStartTimeSec, sAutoCloseTotalTimeSec, 1.f, 0.f)
-		: 1.0f;
-	LLViewDrawContext context(alpha);
-
-	LLPanel::draw();
-
-	if (alpha == 0.f)
-	{
-		setVisible(FALSE);
-	}
-}
-
diff --git a/indra/newview/llpanelvolumepulldown.h b/indra/newview/llpanelvolumepulldown.h
index 4f23112f5000112a43a4206dd7679cb35201237f..e907bb0c78fa36dbd4623c8187a14bc39d2e0799 100644
--- a/indra/newview/llpanelvolumepulldown.h
+++ b/indra/newview/llpanelvolumepulldown.h
@@ -30,19 +30,12 @@
 
 #include "linden_common.h"
 
-#include "llpanel.h"
+#include "llpanelpulldown.h"
 
-class LLFrameTimer;
-
-class LLPanelVolumePulldown : public LLPanel
+class LLPanelVolumePulldown : public LLPanelPulldown
 {
  public:
 	LLPanelVolumePulldown();
-	/*virtual*/ void draw();
-	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
-	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
-	/*virtual*/ void onTopLost();
-	/*virtual*/ void onVisibilityChange ( BOOL new_visibility );
 	/*virtual*/ BOOL postBuild();
 	
  private:
@@ -52,10 +45,6 @@ class LLPanelVolumePulldown : public LLPanel
 	// "Streaming Music" and "Media" are unchecked. Otherwise enables it.
 	void updateMediaAutoPlayCheckbox(LLUICtrl* ctrl);
 	void onAdvancedButtonClick(const LLSD& user_data);
-
-	LLFrameTimer mHoverTimer;
-	static const F32 sAutoCloseFadeStartTimeSec;
-	static const F32 sAutoCloseTotalTimeSec;
 };