From 7d78c63c05579f72dc6998913245d793a2fbd87c Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 10 Nov 2011 17:10:47 -0800
Subject: EXP-1504 : Allow opening of tab in tab containers when drag and
 dropping things. Added new param to LLButton to handle this (off by default).
 Refactor lltabcontainer code a bit while at it.

---
 indra/llui/llbutton.cpp       | 28 +++++++++++++
 indra/llui/llbutton.h         |  7 ++++
 indra/llui/lltabcontainer.cpp | 94 ++++++++++++++-----------------------------
 3 files changed, 65 insertions(+), 64 deletions(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 74b8885e1f..be657dbb9b 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -104,6 +104,7 @@ LLButton::Params::Params()
 	use_draw_context_alpha("use_draw_context_alpha", true),
 	badge("badge"),
 	handle_right_mouse("handle_right_mouse"),
+	click_on_drag_and_drop("click_on_drag_and_drop", false),
 	held_down_delay("held_down_delay"),
 	button_flash_count("button_flash_count"),
 	button_flash_rate("button_flash_rate")
@@ -171,6 +172,7 @@ LLButton::LLButton(const LLButton::Params& p)
 	mHeldDownSignal(NULL),
 	mUseDrawContextAlpha(p.use_draw_context_alpha),
 	mHandleRightMouse(p.handle_right_mouse),
+	mClickOnDragAndDrop(p.click_on_drag_and_drop),		// if true, hovering on button while dragging -> click
 	mButtonFlashCount(p.button_flash_count),
 	mButtonFlashRate(p.button_flash_rate)
 {
@@ -1240,3 +1242,29 @@ BOOL LLButton::handleDoubleClick(S32 x, S32 y, MASK mask)
 	// just treat a double click as a second click
 	return handleMouseDown(x, y, mask);
 }
+
+// virtual
+BOOL LLButton::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType type, void* cargo_data, EAcceptance *accept, std::string	&tooltip)
+{
+	const F32 CLICK_ON_DAD_DELAY_TIME = 0.5f;
+	if (mClickOnDragAndDrop)
+	{
+		// In that case, though the button doesn't really handles drops, it'll "click" if hovering on it
+		// while dragging something. That allows for instance drilling into tabbed containers.
+		// Note: we use the same timer as mouse down just as convenience and to avoid duplication.
+		if (mMouseDownTimer.getStarted())
+		{
+			if (mMouseDownTimer.getElapsedTimeF32() > CLICK_ON_DAD_DELAY_TIME )
+			{
+				onCommit();
+				mMouseDownTimer.stop();
+			}
+		}
+		else 
+		{
+			mMouseDownTimer.start();
+		}
+	}
+	// The true DaD effect is handled at the View level if any.
+	return LLView::handleDragAndDrop(x,	y, mask, drop, type, cargo_data,  accept, tooltip);
+}
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index deaa0823c6..47aa675c5e 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -132,6 +132,7 @@ public:
 		Optional<LLBadge::Params>	badge;
 
 		Optional<bool>				handle_right_mouse;
+		Optional<bool>				click_on_drag_and_drop;
 
 		Optional<S32>				button_flash_count;
 		Optional<F32>				button_flash_rate;
@@ -159,6 +160,11 @@ public:
 	virtual BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleRightMouseUp(S32 x, S32 y, MASK mask);	
 	virtual BOOL	handleDoubleClick(S32 x, S32 y, MASK mask);
+	virtual BOOL	handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+									  EDragAndDropType cargo_type,
+									  void* cargo_data,
+									  EAcceptance* accept,
+									  std::string& tooltip_msg);
 	virtual void	draw();
 	/*virtual*/ BOOL postBuild();
 
@@ -376,6 +382,7 @@ protected:
 	LLFrameTimer				mFlashingTimer;
 
 	bool						mHandleRightMouse;
+	bool						mClickOnDragAndDrop;
 };
 
 // Build time optimization, generate once in .cpp file
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index ad1f3c504d..3b2751248b 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1025,85 +1025,51 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
 	}
 	else
 	{
+		LLButton::Params& p = (mCustomIconCtrlUsed ? custom_btn_params : normal_btn_params);
+		
+		p.rect(btn_rect);
+		p.font(mFont);
+		p.font_halign = mFontHalign;
+		p.label(trimmed_label);
+		p.click_callback.function(boost::bind(&LLTabContainer::onTabBtn, this, _2, child));
+		if (indent)
+		{
+			p.pad_left(indent);
+		}
+		p.pad_bottom( mLabelPadBottom );
+		p.scale_image(true);
+		p.tab_stop(false);
+		p.label_shadow(false);
+		p.follows.flags = FOLLOWS_LEFT;
+		p.click_on_drag_and_drop(true);
+		
 		if (mIsVertical)
 		{
-			LLButton::Params& p = (mCustomIconCtrlUsed)?
-					custom_btn_params:normal_btn_params;
-
 			p.name(std::string("vert tab button"));
-			p.rect(btn_rect);
-			p.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
-			p.click_callback.function(boost::bind(&LLTabContainer::onTabBtn, this, _2, child));
-			p.font(mFont);
-			p.label(trimmed_label);
 			p.image_unselected(mMiddleTabParams.tab_left_image_unselected);
 			p.image_selected(mMiddleTabParams.tab_left_image_selected);
-			p.scale_image(true);
-			p.font_halign = mFontHalign;
-			p.pad_bottom( mLabelPadBottom );
-			p.tab_stop(false);
-			p.label_shadow(false);
-			if (indent)
-			{
-				p.pad_left(indent);
-			}
-			
-			
-			if(mCustomIconCtrlUsed)
-			{
-				btn = LLUICtrlFactory::create<LLCustomButtonIconCtrl>(custom_btn_params);
-				
-			}
-			else
-			{
-				btn = LLUICtrlFactory::create<LLButton>(p);
-			}
+			p.follows.flags = p.follows.flags() | FOLLOWS_TOP;
 		}
 		else
 		{
-			LLButton::Params& p = (mCustomIconCtrlUsed)?
-					custom_btn_params:normal_btn_params;
 			p.name(std::string(child->getName()) + " tab");
-			p.rect(btn_rect);
-			p.click_callback.function(boost::bind(&LLTabContainer::onTabBtn, this, _2, child));
-			p.font(mFont);
-			p.label(trimmed_label);
 			p.visible(false);
-			p.scale_image(true);
 			p.image_unselected(tab_img);
 			p.image_selected(tab_selected_img);
-			p.tab_stop(false);
-			p.label_shadow(false);
+			p.follows.flags = p.follows.flags() | (getTabPosition() == TOP ? FOLLOWS_TOP : FOLLOWS_BOTTOM);
 			// Try to squeeze in a bit more text
 			p.pad_left( mLabelPadLeft );
 			p.pad_right(2);
-			p.pad_bottom( mLabelPadBottom );
-			p.font_halign = mFontHalign;
-			p.follows.flags = FOLLOWS_LEFT;
-			p.follows.flags = FOLLOWS_LEFT;
-	
-			if (indent)
-			{
-				p.pad_left(indent);
-			}
-
-			if( getTabPosition() == TOP )
-			{
-				p.follows.flags = p.follows.flags() | FOLLOWS_TOP;
-			}
-			else
-			{
-				p.follows.flags = p.follows.flags() | FOLLOWS_BOTTOM;
-			}
-
-			if(mCustomIconCtrlUsed)
-			{
-				btn = LLUICtrlFactory::create<LLCustomButtonIconCtrl>(custom_btn_params);
-			}
-			else
-			{
-				btn = LLUICtrlFactory::create<LLButton>(p);
-			}
+		}
+		
+		// *TODO : It seems wrong not to use p in both cases considering the way p is initialized
+		if (mCustomIconCtrlUsed)
+		{
+			btn = LLUICtrlFactory::create<LLCustomButtonIconCtrl>(custom_btn_params);
+		}
+		else
+		{
+			btn = LLUICtrlFactory::create<LLButton>(p);
 		}
 	}
 	
-- 
cgit v1.2.3