From 039c50f2b4831a4caad3313b3e8e1c992793ae90 Mon Sep 17 00:00:00 2001
From: Jonathan Yap <none@none>
Date: Wed, 8 Feb 2012 15:41:27 -0500
Subject: [PATCH] STORM-1807 Play animation floater 2nd play button active
 while animation is playing

---
 doc/contributions.txt                         |   1 +
 indra/newview/llinventorybridge.cpp           |   8 +-
 indra/newview/llpreviewanim.cpp               | 140 ++++++++----------
 indra/newview/llpreviewanim.h                 |  20 +--
 .../xui/en/floater_preview_animation.xml      |  16 +-
 5 files changed, 86 insertions(+), 99 deletions(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index c5db396c972..434e7626fcc 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -610,6 +610,7 @@ Jonathan Yap
 	STORM-1788
 	STORM-1799
 	STORM-1796
+	STORM-1807
 Kadah Coba
 	STORM-1060
 Jondan Lundquist
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index cebe93f0422..654ebe78fa7 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4633,14 +4633,14 @@ void LLAnimationBridge::performAction(LLInventoryModel* model, std::string actio
 	{
 		if (getItem())
 		{
-			LLPreviewAnim::e_activation_type activate = LLPreviewAnim::NONE;
-			if ("playworld" == action) activate = LLPreviewAnim::PLAY;
-			if ("playlocal" == action) activate = LLPreviewAnim::AUDITION;
+			LLSD::String activate = "NONE";
+			if ("playworld" == action) activate = "Inworld";
+			if ("playlocal" == action) activate = "Locally";
 
 			LLPreviewAnim* preview = LLFloaterReg::showTypedInstance<LLPreviewAnim>("preview_anim", LLSD(mUUID));
 			if (preview)
 			{
-				preview->activate(activate);
+				preview->play(activate);
 			}
 		}
 	}
diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp
index 8e8b530e135..dcb8bca5126 100644
--- a/indra/newview/llpreviewanim.cpp
+++ b/indra/newview/llpreviewanim.cpp
@@ -43,19 +43,7 @@ extern LLAgent gAgent;
 LLPreviewAnim::LLPreviewAnim(const LLSD& key)
 	: LLPreview( key )
 {
-}
-
-// static
-void LLPreviewAnim::endAnimCallback( void *userdata )
-{
-	LLHandle<LLFloater>* handlep = ((LLHandle<LLFloater>*)userdata);
-	LLFloater* self = handlep->get();
-	delete handlep; // done with the handle
-	if (self)
-	{
-		self->getChild<LLUICtrl>("Anim play btn")->setValue(FALSE);
-		self->getChild<LLUICtrl>("Anim audition btn")->setValue(FALSE);
-	}
+	mCommitCallbackRegistrar.add("PreviewAnim.Play", boost::bind(&LLPreviewAnim::play, this, _2));
 }
 
 // virtual
@@ -68,105 +56,108 @@ BOOL LLPreviewAnim::postBuild()
 		getChild<LLUICtrl>("desc")->setValue(item->getDescription());
 	}
 
-	childSetAction("Anim play btn",playAnim, this);
-	childSetAction("Anim audition btn",auditionAnim, this);
-
 	childSetCommitCallback("desc", LLPreview::onText, this);
 	getChild<LLLineEditor>("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
-	
+
 	return LLPreview::postBuild();
 }
 
-void LLPreviewAnim::activate(e_activation_type type)
+// static
+// llinventorybridge also calls into here
+void LLPreviewAnim::play(const LLSD& param)
 {
-	switch ( type ) 
+	const LLInventoryItem *item = getItem();
+
+	if(item)
 	{
-		case PLAY:
+		LLUUID itemID=item->getAssetUUID();
+
+		std::string btn_name = param.asString();
+		LLButton* btn_inuse;
+		LLButton* btn_other;
+
+		if ("Inworld" == btn_name)
 		{
-			playAnim( (void *) this );
-			break;
+			btn_inuse = getChild<LLButton>("Inworld");
+			btn_other = getChild<LLButton>("Locally");
 		}
-		case AUDITION:
+		else if ("Locally" == btn_name)
 		{
-			auditionAnim( (void *) this );
-			break;
+			btn_inuse = getChild<LLButton>("Locally");
+			btn_other = getChild<LLButton>("Inworld");
 		}
-		default:
+		else
 		{
-		//do nothing
+			return;
 		}
-	}
-}
 
-// static
-void LLPreviewAnim::playAnim( void *userdata )
-{
-	LLPreviewAnim* self = (LLPreviewAnim*) userdata;
-	const LLInventoryItem *item = self->getItem();
-
-	if(item)
-	{
-		LLUUID itemID=item->getAssetUUID();
+		if (btn_inuse)
+		{
+			btn_inuse->toggleState();
+		}
 
-		LLButton* btn = self->getChild<LLButton>("Anim play btn");
-		if (btn)
+		if (btn_other)
 		{
-			btn->toggleState();
+			btn_other->setEnabled(false);
 		}
 		
-		if (self->getChild<LLUICtrl>("Anim play btn")->getValue().asBoolean() ) 
+		if (getChild<LLUICtrl>(btn_name)->getValue().asBoolean() ) 
 		{
-			self->mPauseRequest = NULL;
-			gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_START);
+			"Inworld" == btn_name ? gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_START) :
+									gAgentAvatarp->startMotion(item->getAssetUUID());
+
 			LLMotion* motion = gAgentAvatarp->findMotion(itemID);
 			if (motion)
 			{
-				motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLHandle<LLFloater>(self->getHandle())));
+				mItemID = itemID;
+				mDidStart = false;
 			}
 		}
 		else
 		{
 			gAgentAvatarp->stopMotion(itemID);
 			gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_STOP);
+
+			if (btn_other)
+			{
+				btn_other->setEnabled(true);
+			}
 		}
 	}
 }
 
-// static
-void LLPreviewAnim::auditionAnim( void *userdata )
+// virtual
+void LLPreviewAnim::draw()
 {
-	LLPreviewAnim* self = (LLPreviewAnim*) userdata;
-	const LLInventoryItem *item = self->getItem();
-
-	if(item)
+	LLPreview::draw();
+	if (!this->mItemID.isNull())
 	{
-		LLUUID itemID=item->getAssetUUID();
-
-		LLButton* btn = self->getChild<LLButton>("Anim audition btn");
-		if (btn)
-		{
-			btn->toggleState();
-		}
-		
-		if (self->getChild<LLUICtrl>("Anim audition btn")->getValue().asBoolean() ) 
+		LLMotion* motion = gAgentAvatarp->findMotion(this->mItemID);
+		if (motion)
 		{
-			self->mPauseRequest = NULL;
-			gAgentAvatarp->startMotion(item->getAssetUUID());
-			LLMotion* motion = gAgentAvatarp->findMotion(itemID);
-			
-			if (motion)
+			if (motion->isStopped() && this->mDidStart)
 			{
-				motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLHandle<LLFloater>(self->getHandle())));
+				cleanup();
+			}
+			if(gAgentAvatarp->isMotionActive(this->mItemID) && !this->mDidStart)
+			{
+				this->mDidStart = true;
 			}
-		}
-		else
-		{
-			gAgentAvatarp->stopMotion(itemID);
-			gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_STOP);
 		}
 	}
 }
 
+// virtual
+void LLPreviewAnim::cleanup()
+{
+	this->mItemID = LLUUID::null;
+	this->mDidStart = false;
+	getChild<LLUICtrl>("Inworld")->setValue(FALSE);
+	getChild<LLUICtrl>("Locally")->setValue(FALSE);
+	getChild<LLUICtrl>("Inworld")->setEnabled(true);
+	getChild<LLUICtrl>("Locally")->setEnabled(true);
+}
+
 // virtual
 void LLPreviewAnim::onClose(bool app_quitting)
 {
@@ -176,12 +167,5 @@ void LLPreviewAnim::onClose(bool app_quitting)
 	{
 		gAgentAvatarp->stopMotion(item->getAssetUUID());
 		gAgent.sendAnimationRequest(item->getAssetUUID(), ANIM_REQUEST_STOP);
-		LLMotion* motion = gAgentAvatarp->findMotion(item->getAssetUUID());
-		
-		if (motion)
-		{
-			// *TODO: minor memory leak here, user data is never deleted (Use real callbacks)
-			motion->setDeactivateCallback(NULL, (void *)NULL);
-		}
 	}
 }
diff --git a/indra/newview/llpreviewanim.h b/indra/newview/llpreviewanim.h
index 32e07ee33a0..8eaed6ca1f9 100644
--- a/indra/newview/llpreviewanim.h
+++ b/indra/newview/llpreviewanim.h
@@ -33,24 +33,18 @@
 class LLPreviewAnim : public LLPreview
 {
 public:
-	enum e_activation_type { NONE = 0, PLAY = 1, AUDITION = 2 };
-	LLPreviewAnim(const LLSD& key);
 
-	static void playAnim( void* userdata );
-	static void auditionAnim( void* userdata );
-	static void endAnimCallback( void *userdata );
+	LLPreviewAnim(const LLSD& key);
 	/*virtual*/	BOOL postBuild();
 	/*virtual*/ void onClose(bool app_quitting);
-	void activate(e_activation_type type);
+	void draw();
+	void cleanup();
+	void play(const LLSD& param);
 	
 protected:
 	
-	LLAnimPauseRequest	mPauseRequest;
-	LLUUID		mItemID;
-	std::string	mTitle;
-	LLUUID		mObjectID;
-	LLButton*	mPlayBtn;
-	LLButton*	mAuditionBtn;
+	LLUUID	mItemID;
+	bool	mDidStart;
 };
 
-#endif  // LL_LLPREVIEWSOUND_H
+#endif  // LL_LLPREVIEWANIM_H
diff --git a/indra/newview/skins/default/xui/en/floater_preview_animation.xml b/indra/newview/skins/default/xui/en/floater_preview_animation.xml
index 8427c7b06f2..3ea5f54f2cb 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_animation.xml
@@ -41,18 +41,26 @@
      label_selected="Stop"
      layout="topleft"
      left="10"
-     name="Anim play btn"
+     name="Inworld"
      tool_tip="Play this animation so that others can see it"
      top="47"
-     width="125" />
+     width="125">
+       <button.commit_callback
+        function="PreviewAnim.Play"
+        parameter="Inworld" /> 
+    </button>
     <button
      height="20"
      label="Play Locally"
      label_selected="Stop"
      layout="topleft"
      left_pad="5"
-     name="Anim audition btn"
+     name="Locally"
      tool_tip="Play this animation so that only you can see it"
      top_delta="0"
-     width="125" />
+     width="125">
+       <button.commit_callback
+        function="PreviewAnim.Play"
+        parameter="Locally" /> 
+    </button>
 </floater>
-- 
GitLab