Satisfy Issue 1916: Local Gesture Preview/Play

Adds a dropdown option to gesture preview button to preview locally.
Note that any chat commands in gestures will still work as they normally would!

Translators: do your thing or hold your peace. (floater_preview_gesture.xml)

These code changes will look nicer viewer without space changes~
This commit is contained in:
Inusaito Sayori
2015-05-14 23:55:20 -04:00
parent 8e05524027
commit 4e4dbd4012
8 changed files with 91 additions and 34 deletions

View File

@@ -49,6 +49,7 @@ LLMultiGesture::LLMultiGesture()
mReplaceText(),
mSteps(),
mPlaying(FALSE),
mLocal(false),
mCurrentStep(0),
mDoneCallback(NULL)
{
@@ -63,6 +64,7 @@ LLMultiGesture::~LLMultiGesture()
void LLMultiGesture::reset()
{
mPlaying = FALSE;
mLocal = false;
mCurrentStep = 0;
mWaitTimer.reset();
mWaitingTimer = FALSE;

View File

@@ -79,6 +79,9 @@ public:
// Is the gesture currently playing?
BOOL mPlaying;
// Is the gesture to be played locally?
bool mLocal;
// "instruction pointer" for steps
S32 mCurrentStep;

View File

@@ -667,3 +667,30 @@ void cmdline_printchat(const std::string& message)
LLFloaterChat::addChat(chat);
}
static void fake_local_chat(LLChat chat, const std::string& name)
{
chat.mFromName = name;
chat.mText = name + chat.mText;
LLFloaterChat::addChat(chat);
}
void fake_local_chat(std::string msg)
{
bool action(LLStringUtil::startsWith(msg, "/me") && (msg[3] == ' ' || msg[3] == '\''));
if (action) msg.erase(0, 4);
LLChat chat((action ? " " : ": ") + msg);
chat.mFromID = gAgentID;
chat.mSourceType = CHAT_SOURCE_SYSTEM;
if (rlv_handler_t::isEnabled()) chat.mRlvLocFiltered = chat.mRlvNamesFiltered = true;
chat.mPosAgent = gAgent.getPositionAgent();
chat.mURL = "secondlife:///app/agent/" + gAgentID.asString() + "/about";
if (action) chat.mChatStyle = CHAT_STYLE_IRC;
if (!LLAvatarNameCache::getNSName(gAgentID, chat.mFromName))
{
LLAvatarNameCache::get(gAgentID, boost::bind(fake_local_chat, chat, boost::bind(&LLAvatarName::getNSName, _2, main_name_system())));
}
else
{
chat.mText = chat.mFromName + chat.mText;
LLFloaterChat::addChat(chat);
}
}

View File

@@ -61,6 +61,8 @@
#include "shcommandhandler.h"
#endif //shy_mod
void fake_local_chat(std::string msg);
// Longest time, in seconds, to wait for all animations to stop playing
const F32 MAX_WAIT_ANIM_SECS = 30.f;
@@ -522,7 +524,7 @@ void LLGestureMgr::replaceGesture(const LLUUID& item_id, const LLUUID& new_asset
LLGestureMgr::instance().replaceGesture(base_item_id, gesture, new_asset_id);
}
void LLGestureMgr::playGesture(LLMultiGesture* gesture)
void LLGestureMgr::playGesture(LLMultiGesture* gesture, bool local)
{
if (!gesture) return;
@@ -531,6 +533,7 @@ void LLGestureMgr::playGesture(LLMultiGesture* gesture)
// Add to list of playing
gesture->mPlaying = TRUE;
gesture->mLocal = local;
mPlaying.push_back(gesture);
// Load all needed assets to minimize the delays
@@ -608,7 +611,7 @@ void LLGestureMgr::playGesture(LLMultiGesture* gesture)
// Convenience function that looks up the item_id for you.
void LLGestureMgr::playGesture(const LLUUID& item_id)
void LLGestureMgr::playGesture(const LLUUID& item_id, bool local)
{
const LLUUID& base_item_id = get_linked_uuid(item_id);
@@ -826,8 +829,7 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)
{
// look in signaled animations (simulator's view of what is
// currently playing.
LLVOAvatar::AnimIterator play_it = gAgentAvatarp->mSignaledAnimations.find(*gest_it);
if (play_it != gAgentAvatarp->mSignaledAnimations.end())
if (gesture->mLocal ? !!gAgentAvatarp->findMotion(*gest_it) : (gAgentAvatarp->mSignaledAnimations.find(*gest_it) != gAgentAvatarp->mSignaledAnimations.end()))
{
++gest_it;
}
@@ -970,21 +972,37 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
if (anim_step->mFlags & ANIM_FLAG_STOP)
{
gAgent.sendAnimationRequest(anim_step->mAnimAssetID, ANIM_REQUEST_STOP);
// remove it from our request set in case we just requested it
std::set<LLUUID>::iterator set_it = gesture->mRequestedAnimIDs.find(anim_step->mAnimAssetID);
if (set_it != gesture->mRequestedAnimIDs.end())
if (gesture->mLocal)
{
gesture->mRequestedAnimIDs.erase(set_it);
gAgentAvatarp->stopMotion(anim_step->mAnimAssetID);
}
else
{
gAgent.sendAnimationRequest(anim_step->mAnimAssetID, ANIM_REQUEST_STOP);
// remove it from our request set in case we just requested it
std::set<LLUUID>::iterator set_it = gesture->mRequestedAnimIDs.find(anim_step->mAnimAssetID);
if (set_it != gesture->mRequestedAnimIDs.end())
{
gesture->mRequestedAnimIDs.erase(set_it);
}
}
}
else
{
gAgent.sendAnimationRequest(anim_step->mAnimAssetID, ANIM_REQUEST_START);
// Indicate that we've requested this animation to play as
// part of this gesture (but it won't start playing for at
// least one round-trip to simulator).
gesture->mRequestedAnimIDs.insert(anim_step->mAnimAssetID);
if (gesture->mLocal)
{
gAgentAvatarp->startMotion(anim_step->mAnimAssetID);
// Indicate we're playing this animation now.
gesture->mPlayingAnimIDs.insert(anim_step->mAnimAssetID);
}
else
{
gAgent.sendAnimationRequest(anim_step->mAnimAssetID, ANIM_REQUEST_START);
// Indicate that we've requested this animation to play as
// part of this gesture (but it won't start playing for at
// least one round-trip to simulator).
gesture->mRequestedAnimIDs.insert(anim_step->mAnimAssetID);
}
}
gesture->mCurrentStep++;
break;
@@ -994,7 +1012,10 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
const LLUUID& sound_id = sound_step->mSoundAssetID;
const F32 volume = 1.f;
send_sound_trigger(sound_id, volume);
if (gesture->mLocal)
gAudiop->triggerSound(sound_id, gAgentID, volume, LLAudioEngine::AUDIO_TYPE_UI, gAgent.getPositionGlobal());
else
send_sound_trigger(sound_id, volume);
gesture->mCurrentStep++;
break;
}
@@ -1011,7 +1032,7 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
#if SHY_MOD //Command handler
if(!SHCommandHandler::handleCommand(true, chat_text, gAgentID, gAgentAvatarp))//returns true if handled
#endif //shy_mod
gChatBar->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
gesture->mLocal ? fake_local_chat(chat_text) : gChatBar->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
}
gesture->mCurrentStep++;
break;
@@ -1284,7 +1305,10 @@ void LLGestureMgr::stopGesture(LLMultiGesture* gesture)
for (set_it = gesture->mPlayingAnimIDs.begin(); set_it != gesture->mPlayingAnimIDs.end(); ++set_it)
{
const LLUUID& anim_id = *set_it;
gAgent.sendAnimationRequest(anim_id, ANIM_REQUEST_STOP);
if (gesture->mLocal)
gAgentAvatarp->stopMotion(anim_id, TRUE);
else
gAgent.sendAnimationRequest(anim_id, ANIM_REQUEST_STOP);
}
std::vector<LLMultiGesture*>::iterator it;

View File

@@ -103,8 +103,8 @@ public:
const item_map_t& getActiveGestures() const { return mActive; }
// Force a gesture to be played, for example, if it is being
// previewed.
void playGesture(LLMultiGesture* gesture);
void playGesture(const LLUUID& item_id);
void playGesture(LLMultiGesture* gesture, bool local = false);
void playGesture(const LLUUID& item_id, bool local = false);
// Stop all requested or playing anims for this gesture
// Also remove from playing list

View File

@@ -44,6 +44,7 @@
#include "lldatapacker.h"
#include "lldelayedgestureerror.h"
#include "llfloatergesture.h" // for some label constants
#include "llflyoutbutton.h"
#include "llgesturemgr.h"
#include "llinventorydefines.h"
#include "llinventoryfunctions.h"
@@ -493,17 +494,17 @@ BOOL LLPreviewGesture::postBuild()
mWaitTimeEditor = edit;
// Buttons at the bottom
check = getChild<LLCheckBoxCtrl>( "active_check");
check = getChild<LLCheckBoxCtrl>("active_check");
check->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitActive,this));
mActiveCheck = check;
btn = getChild<LLButton>( "save_btn");
btn = getChild<LLButton>("save_btn");
btn->setClickedCallback(boost::bind(&LLPreviewGesture::onClickSave,this));
mSaveBtn = btn;
btn = getChild<LLButton>( "preview_btn");
btn->setClickedCallback(boost::bind(&LLPreviewGesture::onClickPreview,this));
mPreviewBtn = btn;
LLFlyoutButton* flyout = getChild<LLFlyoutButton>("preview_btn");
flyout->setCommitCallback(boost::bind(&LLPreviewGesture::onClickPreview, this, _2));
mPreviewBtn = flyout;
// Populate the comboboxes
@@ -1740,7 +1741,7 @@ void LLPreviewGesture::onClickSave()
saveIfNeeded();
}
void LLPreviewGesture::onClickPreview()
void LLPreviewGesture::onClickPreview(bool local)
{
if (!mPreviewGesture)
{
@@ -1754,17 +1755,15 @@ void LLPreviewGesture::onClickPreview()
mPreviewBtn->setLabel(getString("stop_txt"));
// play it, and delete when done
LLGestureMgr::instance().playGesture(mPreviewGesture);
refresh();
LLGestureMgr::instance().playGesture(mPreviewGesture, local);
}
else
{
// Will call onDonePreview() below
LLGestureMgr::instance().stopGesture(mPreviewGesture);
refresh();
}
refresh();
}

View File

@@ -137,7 +137,7 @@ protected:
void onCommitActive();
void onClickSave();
void onClickPreview();
void onClickPreview(bool local);
void onDonePreview(LLMultiGesture* gesture);
@@ -170,7 +170,7 @@ protected:
LLCheckBoxCtrl* mActiveCheck;
LLButton* mSaveBtn;
LLButton* mPreviewBtn;
class LLFlyoutButton* mPreviewBtn;
LLMultiGesture* mPreviewGesture;
BOOL mDirty;

View File

@@ -101,8 +101,10 @@ unless you add wait steps.
name="active_check"
tool_tip="Active gestures can be triggered by chatting their trigger phrases or pressing their hot keys. Gestures usually become inactive when there is a key binding conflict."
width="100" />
<button bottom="5" follows="top|left" height="20" label="Preview" left_delta="80"
name="preview_btn" width="80" />
<flyout_button bottom="5" follows="top|left" height="20" label="Preview" left_delta="80"
name="preview_btn" width="90">
<flyout_button_item value="true" name="Local" label="Local Preview"/>
</flyout_button>
<button bottom="5" follows="top|left" height="20" label="Save" left_delta="90"
name="save_btn" width="80" />
</floater>