コード例 #1
0
// static
void LLPreviewGesture::onCommitWait(LLUICtrl* ctrl, void* data)
{
	LLPreviewGesture* self = (LLPreviewGesture*)data;

	LLScrollListItem* step_item = self->mStepList->getFirstSelected();
	if (!step_item) return;

	LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
	if (step->getType() != STEP_WAIT) return;

	LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
	U32 flags = 0x0;
	if (self->mWaitAnimCheck->get()) flags |= WAIT_FLAG_ALL_ANIM;
	if (self->mWaitTimeCheck->get()) flags |= WAIT_FLAG_TIME;
	wait_step->mFlags = flags;

	{
		LLLocale locale(LLLocale::USER_LOCALE);

		F32 wait_seconds = (F32)atof(self->mWaitTimeEditor->getText().c_str());
		if (wait_seconds < 0.f) wait_seconds = 0.f;
		if (wait_seconds > 3600.f) wait_seconds = 3600.f;
		wait_step->mWaitSeconds = wait_seconds;
	}

	// Enable the input area if necessary
	self->mWaitTimeEditor->setEnabled(self->mWaitTimeCheck->get());

	// Update the UI label in the list
	updateLabel(step_item);

	self->mDirty = TRUE;
	self->refresh();
}
コード例 #2
0
// static
void LLPreviewGesture::onCommitAnimation(LLUICtrl* ctrl, void* data)
{
	LLPreviewGesture* self = (LLPreviewGesture*)data;

	LLScrollListItem* step_item = self->mStepList->getFirstSelected();
	if (step_item)
	{
		LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
		if (step->getType() == STEP_ANIMATION)
		{
			// Assign the animation name
			LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
			if (self->mAnimationCombo->getCurrentIndex() == 0)
			{
				anim_step->mAnimName.clear();
				anim_step->mAnimAssetID.setNull();
			}
			else
			{
				anim_step->mAnimName = self->mAnimationCombo->getSimple();
				anim_step->mAnimAssetID = self->mAnimationCombo->getCurrentID();
			}
			//anim_step->mFlags = 0x0;

			// Update the UI label in the list
			updateLabel(step_item);

			self->mDirty = TRUE;
			self->refresh();
		}
	}
}
コード例 #3
0
// static
void LLPreviewGesture::onCommitAnimationTrigger(LLUICtrl* ctrl, void *data)
{
	LLPreviewGesture* self = (LLPreviewGesture*)data;

	LLScrollListItem* step_item = self->mStepList->getFirstSelected();
	if (step_item)
	{
		LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
		if (step->getType() == STEP_ANIMATION)
		{
			LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
			if (self->mAnimationRadio->getSelectedIndex() == 0)
			{
				// start
				anim_step->mFlags &= ~ANIM_FLAG_STOP;
			}
			else
			{
				// stop
				anim_step->mFlags |= ANIM_FLAG_STOP;
			}
			// Update the UI label in the list
			updateLabel(step_item);

			self->mDirty = TRUE;
			self->refresh();
		}
	}
}
コード例 #4
0
// static
void LLPreviewGesture::updateLabel(LLScrollListItem* item)
{
	LLGestureStep* step = (LLGestureStep*)item->getUserdata();

	LLScrollListCell* cell = item->getColumn(0);
	LLScrollListText* text_cell = (LLScrollListText*)cell;
	std::string label = step->getLabel();
	text_cell->setText(label);
}
コード例 #5
0
void LLPreviewGesture::onCommitWaitTime()
{
	LLScrollListItem* step_item = mStepList->getFirstSelected();
	if (!step_item) return;

	LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
	if (step->getType() != STEP_WAIT) return;

	mWaitTimeCheck->set(TRUE);
	onCommitWait();
}
コード例 #6
0
// static
void LLPreviewGesture::onCommitWaitTime(LLUICtrl* ctrl, void* data)
{
	LLPreviewGesture* self = (LLPreviewGesture*)data;

	LLScrollListItem* step_item = self->mStepList->getFirstSelected();
	if (!step_item) return;

	LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
	if (step->getType() != STEP_WAIT) return;

	self->mWaitTimeCheck->set(TRUE);
	onCommitWait(ctrl, data);
}
コード例 #7
0
ファイル: llmultigesture.cpp プロジェクト: HizWylder/GIS
void LLMultiGesture::dump()
{
	llinfos << "key " << S32(mKey) << " mask " << U32(mMask) 
		<< " trigger " << mTrigger
		<< " replace " << mReplaceText
		<< llendl;
	U32 i;
	for (i = 0; i < mSteps.size(); ++i)
	{
		LLGestureStep* step = mSteps[i];
		step->dump();
	}
}
コード例 #8
0
// static
bool LLGestureMgr::hasLoadingAssets(LLMultiGesture* gesture)
{
	LLGestureMgr& self = LLGestureMgr::instance();

	for (std::vector<LLGestureStep*>::iterator steps_it = gesture->mSteps.begin();
		 steps_it != gesture->mSteps.end();
		 ++steps_it)
	{
		LLGestureStep* step = *steps_it;
		switch(step->getType())
		{
		case STEP_ANIMATION:
			{
				LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
				const LLUUID& anim_id = anim_step->mAnimAssetID;

				if (!(anim_id.isNull()
					  || anim_step->mFlags & ANIM_FLAG_STOP
					  || self.mLoadingAssets.find(anim_id) == self.mLoadingAssets.end()))
				{
					return true;
				}
				break;
			}
		case STEP_SOUND:
			{
				LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
				const LLUUID& sound_id = sound_step->mSoundAssetID;

				if (!(sound_id.isNull()
					  || self.mLoadingAssets.find(sound_id) == self.mLoadingAssets.end()))
				{
					return true;
				}
				break;
			}
		case STEP_CHAT:
		case STEP_WAIT:
		case STEP_EOF:
			{
				break;
			}
		default:
			{
				LL_WARNS() << "Unknown gesture step type: " << step->getType() << LL_ENDL;
			}
		}
	}

	return false;
}
コード例 #9
0
void LLPreviewGesture::onCommitChat()
{
	LLScrollListItem* step_item = mStepList->getFirstSelected();
	if (!step_item) return;

	LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
	if (step->getType() != STEP_CHAT) return;

	LLGestureStepChat* chat_step = (LLGestureStepChat*)step;
	chat_step->mChatText = mChatEditor->getText();
	chat_step->mFlags = 0x0;

	// Update the UI label in the list
	updateLabel(step_item);

	mDirty = TRUE;
	refresh();
}
コード例 #10
0
ファイル: llmultigesture.cpp プロジェクト: HizWylder/GIS
S32 LLMultiGesture::getMaxSerialSize() const
{
	S32 max_size = 0;

	// ascii format, being very conservative about possible
	// label lengths.
	max_size += 64;		// version S32
	max_size += 64;		// key U8
	max_size += 64;		// mask U32
	max_size += 256;	// trigger string
	max_size += 256;	// replace string

	max_size += 64;		// step count S32

	std::vector<LLGestureStep*>::const_iterator it;
	for (it = mSteps.begin(); it != mSteps.end(); ++it)
	{
		LLGestureStep* step = *it;
		max_size += 64;	// type S32
		max_size += step->getMaxSerialSize();
	}

	/* binary format
	max_size += sizeof(S32);	// version
	max_size += sizeof(mKey);
	max_size += sizeof(mMask);
	max_size += mTrigger.length() + 1;	// for null

	max_size += sizeof(S32);	// step count

	std::vector<LLGestureStep*>::const_iterator it;
	for (it = mSteps.begin(); it != mSteps.end(); ++it)
	{
		LLGestureStep* step = *it;
		max_size += sizeof(S32);	// type
		max_size += step->getMaxSerialSize();
	}
	*/
	
	return max_size;
}
コード例 #11
0
void LLPreviewGesture::onCommitSound()
{
	LLScrollListItem* step_item = mStepList->getFirstSelected();
	if (step_item)
	{
		LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
		if (step->getType() == STEP_SOUND)
		{
			// Assign the sound name
			LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
			sound_step->mSoundName = mSoundCombo->getSimple();
			sound_step->mSoundAssetID = mSoundCombo->getCurrentID();
			sound_step->mFlags = 0x0;

			// Update the UI label in the list
			updateLabel(step_item);

			mDirty = TRUE;
			refresh();
		}
	}
}
コード例 #12
0
LLScrollListItem* LLPreviewGesture::addStep( const EStepType step_type )
{
	// Order of enum EStepType MUST match the library_list element in floater_preview_gesture.xml

	LLGestureStep* step = NULL;
	switch( step_type)
	{
		case STEP_ANIMATION:
			step = new LLGestureStepAnimation();
			break;
		case STEP_SOUND:
			step = new LLGestureStepSound();
			break;
		case STEP_CHAT:
			step = new LLGestureStepChat();
			break;
		case STEP_WAIT:
			step = new LLGestureStepWait();
			break;
		default:
			llerrs << "Unknown step type: " << (S32)step_type << llendl;
			return NULL;
	}

	// Create an enabled item with this step
	LLSD row;
	row["columns"][0]["value"] = step->getLabel();
	row["columns"][0]["font"] = "SANSSERIF_SMALL";
	LLScrollListItem* step_item = mStepList->addElement(row);
	step_item->setUserdata(step);

	// And move selection to the list on the right
	mLibraryList->deselectAllItems();
	mStepList->deselectAllItems();

	step_item->setSelected(TRUE);

	return step_item;
}
コード例 #13
0
ファイル: llmultigesture.cpp プロジェクト: HizWylder/GIS
BOOL LLMultiGesture::serialize(LLDataPacker& dp) const
{
	dp.packS32(GESTURE_VERSION, "version");
	dp.packU8(mKey, "key");
	dp.packU32(mMask, "mask");
	dp.packString(mTrigger, "trigger");
	dp.packString(mReplaceText, "replace");

	S32 count = (S32)mSteps.size();
	dp.packS32(count, "step_count");
	S32 i;
	for (i = 0; i < count; ++i)
	{
		LLGestureStep* step = mSteps[i];

		dp.packS32(step->getType(), "step_type");
		BOOL ok = step->serialize(dp);
		if (!ok)
		{
			return FALSE;
		}
	}
	return TRUE;
}
コード例 #14
0
void LLPreviewGesture::loadUIFromGesture(LLMultiGesture* gesture)
{
	/*LLInventoryItem* item = getItem();


	
	if (item)
	{
		LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc");
		descEditor->setText(item->getDescription());
	}*/

	mTriggerEditor->setText(gesture->mTrigger);

	mReplaceEditor->setText(gesture->mReplaceText);

	switch (gesture->mMask)
	{
	default:
	case MASK_NONE:
		mModifierCombo->setSimple( NONE_LABEL );
		break;
	case MASK_SHIFT:
		mModifierCombo->setSimple( SHIFT_LABEL );
		break;
	case MASK_CONTROL:
		mModifierCombo->setSimple( CTRL_LABEL );
		break;
	}

	mKeyCombo->setCurrentByIndex(0);
	if (gesture->mKey != KEY_NONE)
	{
		mKeyCombo->setSimple(LLKeyboard::stringFromKey(gesture->mKey));
	}

	// Make UI steps for each gesture step
	S32 i;
	S32 count = gesture->mSteps.size();
	for (i = 0; i < count; ++i)
	{
		LLGestureStep* step = gesture->mSteps[i];

		LLGestureStep* new_step = NULL;

		switch(step->getType())
		{
		case STEP_ANIMATION:
			{
				LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
				LLGestureStepAnimation* new_anim_step =
					new LLGestureStepAnimation(*anim_step);
				new_step = new_anim_step;
				break;
			}
		case STEP_SOUND:
			{
				LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
				LLGestureStepSound* new_sound_step =
					new LLGestureStepSound(*sound_step);
				new_step = new_sound_step;
				break;
			}
		case STEP_CHAT:
			{
				LLGestureStepChat* chat_step = (LLGestureStepChat*)step;
				LLGestureStepChat* new_chat_step =
					new LLGestureStepChat(*chat_step);
				new_step = new_chat_step;
				break;
			}
		case STEP_WAIT:
			{
				LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
				LLGestureStepWait* new_wait_step =
					new LLGestureStepWait(*wait_step);
				new_step = new_wait_step;
				break;
			}
		default:
			{
				break;
			}
		}

		if (!new_step) continue;

		// Create an enabled item with this step
		LLSD row;
		row["columns"][0]["value"] = new_step->getLabel();
		row["columns"][0]["font"] = "SANSSERIF_SMALL";
		LLScrollListItem* item = mStepList->addElement(row);
		item->setUserdata(new_step);
	}
}
コード例 #15
0
void LLPreviewGesture::refresh()
{
	// If previewing or item is incomplete, all controls are disabled
	LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem();
	bool is_complete = (item && item->isComplete()) ? true : false;
	if (mPreviewGesture || !is_complete)
	{
		
		childSetEnabled("desc", FALSE);
		//mDescEditor->setEnabled(FALSE);
		mTriggerEditor->setEnabled(FALSE);
		mReplaceText->setEnabled(FALSE);
		mReplaceEditor->setEnabled(FALSE);
		mModifierCombo->setEnabled(FALSE);
		mKeyCombo->setEnabled(FALSE);
		mLibraryList->setEnabled(FALSE);
		mAddBtn->setEnabled(FALSE);
		mUpBtn->setEnabled(FALSE);
		mDownBtn->setEnabled(FALSE);
		mDeleteBtn->setEnabled(FALSE);
		mStepList->setEnabled(FALSE);
		mOptionsText->setEnabled(FALSE);
		mAnimationCombo->setEnabled(FALSE);
		mAnimationRadio->setEnabled(FALSE);
		mSoundCombo->setEnabled(FALSE);
		mChatEditor->setEnabled(FALSE);
		mWaitAnimCheck->setEnabled(FALSE);
		mWaitTimeCheck->setEnabled(FALSE);
		mWaitTimeEditor->setEnabled(FALSE);
		mActiveCheck->setEnabled(FALSE);
		mSaveBtn->setEnabled(FALSE);

		// Make sure preview button is enabled, so we can stop it
		mPreviewBtn->setEnabled(TRUE);
		return;
	}

	BOOL modifiable = item->getPermissions().allowModifyBy(gAgent.getID());

	childSetEnabled("desc", modifiable);
	mTriggerEditor->setEnabled(TRUE);
	mLibraryList->setEnabled(modifiable);
	mStepList->setEnabled(modifiable);
	mOptionsText->setEnabled(modifiable);
	mAnimationCombo->setEnabled(modifiable);
	mAnimationRadio->setEnabled(modifiable);
	mSoundCombo->setEnabled(modifiable);
	mChatEditor->setEnabled(modifiable);
	mWaitAnimCheck->setEnabled(modifiable);
	mWaitTimeCheck->setEnabled(modifiable);
	mWaitTimeEditor->setEnabled(modifiable);
	mActiveCheck->setEnabled(TRUE);

	const std::string& trigger = mTriggerEditor->getText();
	BOOL have_trigger = !trigger.empty();

	const std::string& replace = mReplaceEditor->getText();
	BOOL have_replace = !replace.empty();

	LLScrollListItem* library_item = mLibraryList->getFirstSelected();
	BOOL have_library = (library_item != NULL);

	LLScrollListItem* step_item = mStepList->getFirstSelected();
	S32 step_index = mStepList->getFirstSelectedIndex();
	S32 step_count = mStepList->getItemCount();
	BOOL have_step = (step_item != NULL);

	mReplaceText->setEnabled(have_trigger || have_replace);
	mReplaceEditor->setEnabled(have_trigger || have_replace);

	mModifierCombo->setEnabled(TRUE);
	mKeyCombo->setEnabled(TRUE);

	mAddBtn->setEnabled(modifiable && have_library);
	mUpBtn->setEnabled(modifiable && have_step && step_index > 0);
	mDownBtn->setEnabled(modifiable && have_step && step_index < step_count-1);
	mDeleteBtn->setEnabled(modifiable && have_step);

	// Assume all not visible
	mAnimationCombo->setVisible(FALSE);
	mAnimationRadio->setVisible(FALSE);
	mSoundCombo->setVisible(FALSE);
	mChatEditor->setVisible(FALSE);
	mWaitAnimCheck->setVisible(FALSE);
	mWaitTimeCheck->setVisible(FALSE);
	mWaitTimeEditor->setVisible(FALSE);

	if (have_step)
	{
		// figure out the type, show proper options, update text
		LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
		EStepType type = step->getType();
		switch(type)
		{
		case STEP_ANIMATION:
			{
				LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
				mOptionsText->setText("Animation to play:");
				mAnimationCombo->setVisible(TRUE);
				mAnimationRadio->setVisible(TRUE);
				mAnimationRadio->setSelectedIndex((anim_step->mFlags & ANIM_FLAG_STOP) ? 1 : 0);
				mAnimationCombo->setCurrentByID(anim_step->mAnimAssetID);
				break;
			}
		case STEP_SOUND:
			{
				LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
				mOptionsText->setText("Sound to play:");
				mSoundCombo->setVisible(TRUE);
				mSoundCombo->setCurrentByID(sound_step->mSoundAssetID);
				break;
			}
		case STEP_CHAT:
			{
				LLGestureStepChat* chat_step = (LLGestureStepChat*)step;
				mOptionsText->setText("Chat to say:");
				mChatEditor->setVisible(TRUE);
				mChatEditor->setText(chat_step->mChatText);
				break;
			}
		case STEP_WAIT:
			{
				LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
				mOptionsText->setText("Wait:");
				mWaitAnimCheck->setVisible(TRUE);
				mWaitAnimCheck->set(wait_step->mFlags & WAIT_FLAG_ALL_ANIM);
				mWaitTimeCheck->setVisible(TRUE);
				mWaitTimeCheck->set(wait_step->mFlags & WAIT_FLAG_TIME);
				mWaitTimeEditor->setVisible(TRUE);
				char buffer[16];		/*Flawfinder: ignore*/
				snprintf(buffer, sizeof(buffer),  "%.1f", (double)wait_step->mWaitSeconds);			/* Flawfinder: ignore */
				mWaitTimeEditor->setText(buffer);
				break;
			}
		default:
			break;
		}
	}
	else
	{
		// no gesture
		mOptionsText->setText("");
	}

	BOOL active = gGestureManager.isGestureActive(mItemUUID);
	mActiveCheck->set(active);

	// Can only preview if there are steps
	mPreviewBtn->setEnabled(step_count > 0);

	// And can only save if changes have been made
	mSaveBtn->setEnabled(mDirty);
	addAnimations();
	addSounds();
}
コード例 #16
0
LLMultiGesture* LLPreviewGesture::createGesture()
{
	LLMultiGesture* gesture = new LLMultiGesture();

	gesture->mTrigger = mTriggerEditor->getText();
	gesture->mReplaceText = mReplaceEditor->getText();

	const std::string& modifier = mModifierCombo->getSimple();
	if (modifier == CTRL_LABEL)
	{
		gesture->mMask = MASK_CONTROL;
	}
	else if (modifier == SHIFT_LABEL)
	{
		gesture->mMask = MASK_SHIFT;
	}
	else
	{
		gesture->mMask = MASK_NONE;
	}

	if (mKeyCombo->getCurrentIndex() == 0)
	{
		gesture->mKey = KEY_NONE;
	}
	else
	{
		const std::string& key_string = mKeyCombo->getSimple();
		LLKeyboard::keyFromString(key_string, &(gesture->mKey));
	}

	std::vector<LLScrollListItem*> data_list = mStepList->getAllData();
	std::vector<LLScrollListItem*>::iterator data_itor;
	for (data_itor = data_list.begin(); data_itor != data_list.end(); ++data_itor)
	{
		LLScrollListItem* item = *data_itor;
		LLGestureStep* step = (LLGestureStep*)item->getUserdata();

		switch(step->getType())
		{
		case STEP_ANIMATION:
			{
				// Copy UI-generated step into actual gesture step
				LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
				LLGestureStepAnimation* new_anim_step =
					new LLGestureStepAnimation(*anim_step);
				gesture->mSteps.push_back(new_anim_step);
				break;
			}
		case STEP_SOUND:
			{
				// Copy UI-generated step into actual gesture step
				LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
				LLGestureStepSound* new_sound_step =
					new LLGestureStepSound(*sound_step);
				gesture->mSteps.push_back(new_sound_step);
				break;
			}
		case STEP_CHAT:
			{
				// Copy UI-generated step into actual gesture step
				LLGestureStepChat* chat_step = (LLGestureStepChat*)step;
				LLGestureStepChat* new_chat_step =
					new LLGestureStepChat(*chat_step);
				gesture->mSteps.push_back(new_chat_step);
				break;
			}
		case STEP_WAIT:
			{
				// Copy UI-generated step into actual gesture step
				LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
				LLGestureStepWait* new_wait_step =
					new LLGestureStepWait(*wait_step);
				gesture->mSteps.push_back(new_wait_step);
				break;
			}
		default:
			{
				break;
			}
		}
	}

	return gesture;
}
コード例 #17
0
void LLGestureMgr::playGesture(LLMultiGesture* gesture, bool local)
{
	if (!gesture) return;

	// Reset gesture to first step
	gesture->mCurrentStep = 0;

	// Add to list of playing
	gesture->mPlaying = TRUE;
	gesture->mLocal = local;
	mPlaying.push_back(gesture);

	// Load all needed assets to minimize the delays
	// when gesture is playing.
	for (std::vector<LLGestureStep*>::iterator steps_it = gesture->mSteps.begin();
		 steps_it != gesture->mSteps.end();
		 ++steps_it)
	{
		LLGestureStep* step = *steps_it;
		switch(step->getType())
		{
		case STEP_ANIMATION:
			{
				LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
				const LLUUID& anim_id = anim_step->mAnimAssetID;

				// Don't request the animation if this step stops it or if it is already in Static VFS
				if (!(anim_id.isNull()
					  || anim_step->mFlags & ANIM_FLAG_STOP
					  || gAssetStorage->hasLocalAsset(anim_id, LLAssetType::AT_ANIMATION)))
				{
					//Singu note: Don't attempt to fetch expressions/emotes.
					const char* emote_name = gAnimLibrary.animStateToString(anim_id);
					if(emote_name && strstr(emote_name,"express_")==emote_name)
					{
						break;
					}

					mLoadingAssets.insert(anim_id);

					LLUUID* id = new LLUUID(gAgentID);
					gAssetStorage->getAssetData(anim_id,
									LLAssetType::AT_ANIMATION,
									onAssetLoadComplete,
									(void *)id,
									TRUE);
				}
				break;
			}
		case STEP_SOUND:
			{
				LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
				const LLUUID& sound_id = sound_step->mSoundAssetID;
				if (!(sound_id.isNull()
					  || gAssetStorage->hasLocalAsset(sound_id, LLAssetType::AT_SOUND)))
				{
					mLoadingAssets.insert(sound_id);

					gAssetStorage->getAssetData(sound_id,
									LLAssetType::AT_SOUND,
									onAssetLoadComplete,
									NULL,
									TRUE);
				}
				break;
			}
		case STEP_CHAT:
		case STEP_WAIT:
		case STEP_EOF:
			{
				break;
			}
		default:
			{
				LL_WARNS() << "Unknown gesture step type: " << step->getType() << LL_ENDL;
			}
		}
	}

	// And get it going
	stepGesture(gesture);

	notifyObservers();
}