First draft for a viewer side animation overrider. Still very rough code but almost feature-complete.

master
ZiRee 2011-04-20 05:41:33 +02:00
parent c20b66ea50
commit 54f218f68a
19 changed files with 3177 additions and 6 deletions

View File

@ -70,6 +70,9 @@ include_directories(
)
set(viewer_SOURCE_FILES
ao.cpp
aoengine.cpp
aoset.cpp
chatbar_as_cmdline.cpp
kcwlinterface.cpp
floatermedialists.cpp
@ -629,6 +632,9 @@ endif (LINUX)
set(viewer_HEADER_FILES
CMakeLists.txt
ViewerInstall.cmake
ao.h
aoengine.h
aoset.h
chatbar_as_cmdline.h
kcwlinterface.h
floatermedialists.h

487
indra/newview/ao.cpp Normal file
View File

@ -0,0 +1,487 @@
/**
* @file ao.cpp
* @brief Anything concerning the Viewer Side Animation Overrider GUI
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
* Copyright (C) 2011, Zi Ree @ Second Life
*
* 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 "ao.h"
#include "aoengine.h"
#include "aoset.h"
#include "llbottomtray.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "llnotificationsutil.h"
#include "llspinctrl.h"
#include "llviewerinventory.h"
FloaterAO::FloaterAO(const LLSD& key)
: LLTransientDockableFloater(NULL,true,key),
mSetList(0),
mSelectedSet(0),
mSelectedState(0),
mCanDragAndDrop(FALSE)
{
}
FloaterAO::~FloaterAO()
{
}
void FloaterAO::updateSetParameters()
{
mOverrideSitsCheckBox->setValue(mSelectedSet->getSitOverride());
mDisableMouselookCheckBox->setValue(mSelectedSet->getMouselookDisable());
BOOL isDefault=(mSelectedSet==AOEngine::instance().getDefaultSet()) ? TRUE : FALSE;
mDefaultCheckBox->setValue(isDefault);
mDefaultCheckBox->setEnabled(!isDefault);
}
void FloaterAO::updateAnimationList()
{
S32 currentStateSelected=mStateSelector->getCurrentIndex();
mStateSelector->removeall();
if(!mSelectedSet)
{
mStateSelector->setEnabled(FALSE);
mStateSelector->add("no_animations_loaded"); // getString("no_animations_loaded"));
return;
}
for(S32 index=0;index<mSelectedSet->mStateNames.size();index++)
{
std::string stateName=mSelectedSet->mStateNames[index];
AOSet::AOState* state=mSelectedSet->getStateByName(stateName);
mStateSelector->add(stateName,state,ADD_BOTTOM,TRUE);
}
enableStateControls(TRUE);
if(currentStateSelected==-1)
mStateSelector->selectFirstItem();
else
mStateSelector->selectNthItem(currentStateSelected);
onSelectState();
}
void FloaterAO::updateList()
{
std::string currentSetName=mSetSelector->getSelectedItemLabel();
if(currentSetName.empty())
currentSetName=AOEngine::instance().getCurrentSetName();
mSetList=AOEngine::instance().getSetList();
mSetSelector->removeall();
if(mSetList.empty())
{
mSetSelector->setEnabled(FALSE);
mSetSelector->add("no_sets_loaded"); // getString("no_sets_loaded"));
return;
}
for(S32 index=0;index<mSetList.size();index++)
{
std::string setName=mSetList[index]->getName();
mSetSelector->add(setName,&mSetList[index],ADD_BOTTOM,TRUE);
if(setName.compare(currentSetName)==0)
{
mSelectedSet=AOEngine::instance().selectSetByName(currentSetName);
mSetSelector->selectNthItem(index);
updateSetParameters();
updateAnimationList();
}
}
enableSetControls(TRUE);
}
BOOL FloaterAO::postBuild()
{
LLPanel* aoPanel=getChild<LLPanel>("animation_overrider_panel");
mSetSelector=aoPanel->getChild<LLComboBox>("ao_set_selection_combo");
mActivateSetButton=aoPanel->getChild<LLButton>("ao_activate");
mAddButton=aoPanel->getChild<LLButton>("ao_add");
mRemoveButton=aoPanel->getChild<LLButton>("ao_remove");
mDefaultCheckBox=aoPanel->getChild<LLCheckBoxCtrl>("ao_default");
mOverrideSitsCheckBox=aoPanel->getChild<LLCheckBoxCtrl>("ao_sit_override");
mDisableMouselookCheckBox=aoPanel->getChild<LLCheckBoxCtrl>("ao_disable_stands_in_mouselook");
mStateSelector=aoPanel->getChild<LLComboBox>("ao_state_selection_combo");
mAnimationList=aoPanel->getChild<LLScrollListCtrl>("ao_state_animation_list");
mMoveUpButton=aoPanel->getChild<LLButton>("ao_move_up");
mMoveDownButton=aoPanel->getChild<LLButton>("ao_move_down");
mTrashButton=aoPanel->getChild<LLButton>("ao_trash");
mRandomizeCheckBox=aoPanel->getChild<LLCheckBoxCtrl>("ao_randomize");
mCycleTimeTextLabel=aoPanel->getChild<LLTextBox>("ao_cycle_time_seconds_label");
mCycleTimeSpinner=aoPanel->getChild<LLSpinCtrl>("ao_cycle_time");
mSetSelector->setCommitCallback(boost::bind(&FloaterAO::onSelectSet,this));
mActivateSetButton->setCommitCallback(boost::bind(&FloaterAO::onClickActivate,this));
mAddButton->setCommitCallback(boost::bind(&FloaterAO::onClickAdd,this));
mRemoveButton->setCommitCallback(boost::bind(&FloaterAO::onClickRemove,this));
mDefaultCheckBox->setCommitCallback(boost::bind(&FloaterAO::onCheckDefault,this));
mOverrideSitsCheckBox->setCommitCallback(boost::bind(&FloaterAO::onCheckOverrideSits,this));
mDisableMouselookCheckBox->setCommitCallback(boost::bind(&FloaterAO::onCheckDisableStands,this));
mAnimationList->setCommitOnSelectionChange(TRUE);
mStateSelector->setCommitCallback(boost::bind(&FloaterAO::onSelectState,this));
mAnimationList->setCommitCallback(boost::bind(&FloaterAO::onChangeAnimationSelection,this));
mMoveUpButton->setCommitCallback(boost::bind(&FloaterAO::onClickMoveUp,this));
mMoveDownButton->setCommitCallback(boost::bind(&FloaterAO::onClickMoveDown,this));
mTrashButton->setCommitCallback(boost::bind(&FloaterAO::onClickTrash,this));
mRandomizeCheckBox->setCommitCallback(boost::bind(&FloaterAO::onCheckRandomize,this));
mCycleTimeSpinner->setCommitCallback(boost::bind(&FloaterAO::onChangeCycleTime,this));
aoPanel->getChild<LLButton>("ao_reload")->setCommitCallback(boost::bind(&FloaterAO::onClickReload,this));
aoPanel->getChild<LLButton>("ao_previous")->setCommitCallback(boost::bind(&FloaterAO::onClickPrevious,this));
aoPanel->getChild<LLButton>("ao_next")->setCommitCallback(boost::bind(&FloaterAO::onClickNext,this));
AOEngine::instance().setReloadCallback(boost::bind(&FloaterAO::updateList,this));
enableSetControls(FALSE);
updateList();
return LLDockableFloater::postBuild();
}
void FloaterAO::enableSetControls(BOOL yes)
{
mSetSelector->setEnabled(yes);
mActivateSetButton->setEnabled(yes);
mDefaultCheckBox->setEnabled(yes);
mOverrideSitsCheckBox->setEnabled(yes);
mDisableMouselookCheckBox->setEnabled(yes);
}
void FloaterAO::enableStateControls(BOOL yes)
{
mStateSelector->setEnabled(yes);
mAnimationList->setEnabled(yes);
mRandomizeCheckBox->setEnabled(yes);
mCycleTimeTextLabel->setEnabled(yes);
mCycleTimeSpinner->setEnabled(yes);
mCanDragAndDrop=yes;
}
void FloaterAO::onOpen(const LLSD& key)
{
LLButton* anchor_panel=LLBottomTray::instance().getChild<LLButton>("ao_toggle_btn");
if(anchor_panel)
setDockControl(new LLDockControl(anchor_panel,this,getDockTongue(),LLDockControl::TOP));
}
void FloaterAO::onSelectSet()
{
mSelectedSet=AOEngine::instance().getSetByName(mSetSelector->getSelectedItemLabel());
if(mSelectedSet)
{
updateSetParameters();
updateAnimationList();
}
}
void FloaterAO::onClickActivate()
{
llwarns << "Set activated: " << mSetSelector->getSelectedItemLabel() << llendl;
AOEngine::instance().selectSet(mSelectedSet);
}
LLScrollListItem* FloaterAO::addAnimation(const std::string name)
{
LLSD row;
row["columns"][0]["type"]="icon";
row["columns"][0]["value"]="Inv_Animation";
row["columns"][0]["width"]=20;
row["columns"][1]["type"]="text";
row["columns"][1]["value"]=name;
row["columns"][1]["width"]=120; // 170 later
return mAnimationList->addElement(row);
}
void FloaterAO::onSelectState()
{
mAnimationList->deleteAllItems();
onChangeAnimationSelection();
if(!mSelectedSet)
return;
mSelectedState=mSelectedSet->getStateByName(mStateSelector->getSelectedItemLabel());
if(!mSelectedState)
{
// mAnimationList->addSimpleElement("no_animations_loaded"); // getString("no_animations_loaded"));
mAnimationList->setEnabled(FALSE);
LLSD row;
/* row["columns"][0]["type"]="icon";
row["columns"][0]["value"]="";
row["columns"][0]["width"]=20;
*/
row["columns"][0]["type"]="text";
row["columns"][0]["value"]="no_animations_loaded"; // getString("no_animations_loaded"));
row["columns"][0]["width"]=190;
mAnimationList->addElement(row);
return;
}
mAnimationList->setEnabled(TRUE);
mSelectedState=(AOSet::AOState*) mStateSelector->getCurrentUserdata();
for(S32 index=0;index<mSelectedState->mAnimations.size();index++)
{
LLScrollListItem* item=addAnimation(mSelectedState->mAnimations[index].mName);
if(item)
item->setUserdata(&mSelectedState->mAnimations[index].mInventoryUUID);
}
mRandomizeCheckBox->setValue(mSelectedState->mRandom);
mCycleTimeSpinner->setValue(mSelectedState->mCycleTime);
}
void FloaterAO::onClickReload()
{
enableSetControls(FALSE);
enableStateControls(FALSE);
mSelectedSet=0;
mSelectedState=0;
AOEngine::instance().reload();
updateList();
}
void FloaterAO::onClickAdd()
{
LLNotificationsUtil::add("NewAOSet",LLSD(),LLSD(),boost::bind(&FloaterAO::newSetCallback,this,_1,_2));
}
BOOL FloaterAO::newSetCallback(const LLSD& notification,const LLSD& response)
{
std::string newSetName=response["message"].asString();
S32 option=LLNotificationsUtil::getSelectedOption(notification,response);
if(newSetName=="")
return FALSE;
else if(newSetName.find(":")!=std::string::npos)
{
LLNotificationsUtil::add("NewAOCantContainColon",LLSD());
return FALSE;
}
if(option==0)
{
if(AOEngine::instance().addSet(newSetName).notNull())
{
enableSetControls(FALSE);
enableStateControls(FALSE);
return TRUE;
}
}
return FALSE;
}
void FloaterAO::onClickRemove()
{
LLSD args;
args["AO_SET_NAME"]=mSelectedSet->getName();
LLNotificationsUtil::add("RemoveAOSet",args,LLSD(),boost::bind(&FloaterAO::removeSetCallback,this,_1,_2));
}
BOOL FloaterAO::removeSetCallback(const LLSD& notification,const LLSD& response)
{
std::string newSetName=response["message"].asString();
S32 option=LLNotificationsUtil::getSelectedOption(notification,response);
if(option==0)
{
if(AOEngine::instance().removeSet(mSelectedSet))
{
// to prevent snapping back to deleted set
mSetSelector->removeall();
enableSetControls(FALSE);
enableStateControls(FALSE);
return TRUE;
}
}
return FALSE;
}
void FloaterAO::onCheckDefault()
{
if(mSelectedSet)
AOEngine::instance().setDefaultSet(mSelectedSet);
}
void FloaterAO::onCheckOverrideSits()
{
if(mSelectedSet)
AOEngine::instance().setOverrideSits(mSelectedSet,mOverrideSitsCheckBox->getValue().asBoolean());
}
void FloaterAO::onCheckDisableStands()
{
if(mSelectedSet)
AOEngine::instance().setDisableStands(mSelectedSet,mDisableMouselookCheckBox->getValue().asBoolean());
}
void FloaterAO::onChangeAnimationSelection()
{
std::vector<LLScrollListItem*> list=mAnimationList->getAllSelected();
llwarns << "Selection count: " << list.size() << llendl;
BOOL resortEnable=FALSE;
BOOL trashEnable=FALSE;
if(list.size()>0)
{
if(list.size()==1)
resortEnable=TRUE;
trashEnable=TRUE;
}
mMoveDownButton->setEnabled(resortEnable);
mMoveUpButton->setEnabled(resortEnable);
mTrashButton->setEnabled(trashEnable);
}
void FloaterAO::onClickMoveUp()
{
if(!mSelectedState)
return;
std::vector<LLScrollListItem*> list=mAnimationList->getAllSelected();
if(list.size()!=1)
return;
S32 currentIndex=mAnimationList->getFirstSelectedIndex();
if(currentIndex==-1)
return;
if(AOEngine::instance().swapWithPrevious(mSelectedState,currentIndex))
mAnimationList->swapWithPrevious(currentIndex);
}
void FloaterAO::onClickMoveDown()
{
if(!mSelectedState)
return;
std::vector<LLScrollListItem*> list=mAnimationList->getAllSelected();
if(list.size()!=1)
return;
S32 currentIndex=mAnimationList->getFirstSelectedIndex();
if(currentIndex>=(mAnimationList->getItemCount()-1))
return;
if(AOEngine::instance().swapWithNext(mSelectedState,currentIndex))
mAnimationList->swapWithNext(currentIndex);
}
void FloaterAO::onClickTrash()
{
if(!mSelectedState)
return;
std::vector<LLScrollListItem*> list=mAnimationList->getAllSelected();
if(list.size()==0)
return;
for(S32 index=list.size()-1;index!=-1;index--)
AOEngine::instance().removeAnimation(mSelectedSet,mSelectedState,mAnimationList->getItemIndex(list[index]));
mAnimationList->deleteSelectedItems();
}
void FloaterAO::onCheckRandomize()
{
if(mSelectedState)
AOEngine::instance().setRandomize(mSelectedState,mRandomizeCheckBox->getValue().asBoolean());
}
void FloaterAO::onChangeCycleTime()
{
if(mSelectedState)
AOEngine::instance().setCycleTime(mSelectedState,mCycleTimeSpinner->getValueF32());
}
void FloaterAO::onClickPrevious()
{
AOEngine::instance().cycle(AOEngine::CyclePrevious);
}
void FloaterAO::onClickNext()
{
AOEngine::instance().cycle(AOEngine::CycleNext);
}
// virtual
BOOL FloaterAO::handleDragAndDrop(S32 x,S32 y,MASK mask,BOOL drop,EDragAndDropType type,void* data,
EAcceptance* accept,std::string& tooltipMsg)
{
if(!mSelectedSet || !mSelectedState || !mCanDragAndDrop)
{
*accept=ACCEPT_NO;
return TRUE;
}
LLInventoryItem* item=(LLInventoryItem*) data;
if(type==DAD_ANIMATION)
{
*accept=ACCEPT_YES_MULTI;
if(item && drop)
{
if(AOEngine::instance().addAnimation(mSelectedSet,mSelectedState,item))
{
addAnimation(item->getName());
enableSetControls(FALSE);
enableStateControls(FALSE);
}
}
}
else if(type==DAD_NOTECARD)
{
*accept=ACCEPT_YES_SINGLE;
if(item && drop)
{
llwarns << item->getUUID() << llendl;
if(AOEngine::instance().importNotecard(item))
{
enableSetControls(FALSE);
enableStateControls(FALSE);
}
}
}
else
*accept=ACCEPT_NO;
return TRUE;
}

112
indra/newview/ao.h Normal file
View File

@ -0,0 +1,112 @@
/**
* @file ao.h
* @brief Anything concerning the Viewer Side Animation Overrider GUI
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
* Copyright (C) 2011, Zi Ree @ Second Life
*
* 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 AO_H
#define AO_H
#include "lltransientdockablefloater.h"
#include "aoset.h"
class LLButton;
class LLComboBox;
class LLCheckBoxCtrl;
class LLScrollListCtrl;
class LLScrollListItem;
class LLSpinCtrl;
class LLTextBox;
class FloaterAO
: public LLTransientDockableFloater
{
friend class LLFloaterReg;
private:
FloaterAO(const LLSD& key);
~FloaterAO();
public:
/*virtual*/ BOOL postBuild();
virtual void onOpen(const LLSD& key);
void updateList();
void updateSetParameters();
void updateAnimationList();
BOOL handleDragAndDrop(S32 x,S32 y,MASK mask,BOOL drop,EDragAndDropType cargo_type,void* cargo_data,
EAcceptance* accept,std::string& tooltip_msg);
protected:
LLScrollListItem* addAnimation(const std::string name);
void onSelectSet();
void onSelectState();
void onChangeAnimationSelection();
void onClickReload();
void onClickAdd();
void onClickRemove();
void onClickActivate();
void onCheckDefault();
void onCheckOverrideSits();
void onCheckDisableStands();
void onClickMoveUp();
void onClickMoveDown();
void onClickTrash();
void onCheckRandomize();
void onChangeCycleTime();
void onClickPrevious();
void onClickNext();
void enableSetControls(BOOL yes);
void enableStateControls(BOOL yes);
BOOL newSetCallback(const LLSD& notification,const LLSD& response);
BOOL removeSetCallback(const LLSD& notification,const LLSD& response);
std::vector<AOSet*> mSetList;
AOSet* mSelectedSet;
AOSet::AOState* mSelectedState;
LLComboBox* mSetSelector;
LLButton* mActivateSetButton;
LLButton* mAddButton;
LLButton* mRemoveButton;
LLCheckBoxCtrl* mDefaultCheckBox;
LLCheckBoxCtrl* mOverrideSitsCheckBox;
LLCheckBoxCtrl* mDisableMouselookCheckBox;
LLComboBox* mStateSelector;
LLScrollListCtrl* mAnimationList;
LLButton* mMoveUpButton;
LLButton* mMoveDownButton;
LLButton* mTrashButton;
LLCheckBoxCtrl* mRandomizeCheckBox;
LLTextBox* mCycleTimeTextLabel;
LLSpinCtrl* mCycleTimeSpinner;
BOOL mCanDragAndDrop;
};
#endif // AO_H

1482
indra/newview/aoengine.cpp Normal file

File diff suppressed because it is too large Load Diff

188
indra/newview/aoengine.h Normal file
View File

@ -0,0 +1,188 @@
/**
* @file aoengine.h
* @brief The core Animation Overrider engine
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Zi Ree @ Second Life
*
* 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
*/
#ifndef AOENGINE_H
#define AOENGINE_H
#include <boost/signals2.hpp>
#include "aoset.h"
#include "llassettype.h"
#include "lleventtimer.h"
#include "llsingleton.h"
#include "lluuid.h"
class AOTimerCollection
: public LLEventTimer
{
public:
AOTimerCollection();
~AOTimerCollection();
virtual BOOL tick();
void enableInventoryTimer(BOOL yes);
void enableSettingsTimer(BOOL yes);
void enableReloadTimer(BOOL yes);
void enableImportTimer(BOOL yes);
protected:
void updateTimers();
BOOL mInventoryTimer;
BOOL mSettingsTimer;
BOOL mReloadTimer;
BOOL mImportTimer;
};
// ----------------------------------------------------
class AOSitCancelTimer
: public LLEventTimer
{
public:
AOSitCancelTimer();
~AOSitCancelTimer();
void oneShot();
void stop();
virtual BOOL tick();
protected:
S32 mTickCount;
};
// ----------------------------------------------------
class AOState;
class LLInventoryItem;
class LLVFS;
class AOEngine
: public LLSingleton<AOEngine>
{
friend class LLSingleton<AOEngine>;
private:
AOEngine();
~AOEngine();
public:
enum eCycleMode
{
CycleAny,
CycleNext,
CyclePrevious
};
void enable(BOOL yes);
const LLUUID override(const LLUUID motion,BOOL start);
void tick();
void update();
void reload();
void reloadStateAnimations(AOSet::AOState* state);
void clear();
LLUUID addSet(const std::string name,BOOL reload=TRUE);
BOOL removeSet(AOSet* set);
BOOL addAnimation(const AOSet* set,AOSet::AOState* state,const LLInventoryItem* item,BOOL reload=TRUE);
BOOL removeAnimation(const AOSet* set,AOSet::AOState* state,S32 index);
void checkSitCancel();
BOOL importNotecard(const LLInventoryItem* item);
void processImport();
BOOL swapWithPrevious(AOSet::AOState* state,S32 index);
BOOL swapWithNext(AOSet::AOState* state,S32 index);
void cycleTimeout(const AOSet* set);
void cycle(eCycleMode cycleMode);
void inMouselook(BOOL yes);
void selectSet(AOSet* set);
AOSet* selectSetByName(const std::string name);
AOSet* getSetByName(const std::string name);
// callback from LLAppViewer
static void onLoginComplete();
const std::vector<AOSet*> getSetList() const;
const std::string getCurrentSetName() const;
const AOSet* getDefaultSet() const;
void setDefaultSet(AOSet* set);
void setOverrideSits(AOSet* set,BOOL yes);
void setDisableStands(AOSet* set,BOOL yes);
void setRandomize(AOSet::AOState* state,BOOL yes);
void setCycleTime(AOSet::AOState* state,F32 time);
void saveSettings();
typedef boost::signals2::signal<void ()> updated_signal_t;
boost::signals2::connection setReloadCallback(const updated_signal_t::slot_type& cb) { return mUpdatedSignal.connect(cb); };
protected:
void init();
void setLastMotion(LLUUID motion);
void setLastOverriddenMotion(LLUUID motion);
void stopAllStandVariants();
void stopAllSitVariants();
BOOL foreignAnimations();
void updateSortOrder(AOSet::AOState* state);
void saveSet(const AOSet* set);
void saveState(const AOSet::AOState* state);
BOOL createAnimationLink(const AOSet* set,AOSet::AOState* state,const LLInventoryItem* item);
void purgeFolder(LLUUID uuid);
static void onNotecardLoadComplete( LLVFS* vfs,const LLUUID& assetUUID,LLAssetType::EType type,
void* userdata,S32 status,LLExtStat extStatus);
void parseNotecard(const char* buffer);
updated_signal_t mUpdatedSignal;
AOTimerCollection mTimerCollection;
AOSitCancelTimer mSitCancelTimer;
BOOL mEnabled;
BOOL mInMouselook;
LLUUID mAOFolder;
LLUUID mLastMotion;
LLUUID mLastOverriddenMotion;
std::vector<AOSet*> mSets;
AOSet* mCurrentSet;
AOSet* mDefaultSet;
AOSet* mImportSet;
LLUUID mImportCategory;
S32 mImportRetryCount;
};
#endif // AOENGINE_H

263
indra/newview/aoset.cpp Normal file
View File

@ -0,0 +1,263 @@
/**
* @file aoset.cpp
* @brief Implementation of an Animation Overrider set of animations
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Zi Ree @ Second Life
*
* 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
*/
#include "llviewerprecompiledheaders.h"
#include "aoengine.h"
#include "aoset.h"
#include "llanimationstates.h"
AOSet::AOSet(const LLUUID inventoryID)
: LLEventTimer(10000.0f),
mInventoryID(inventoryID),
mName("** New AO Set **"),
mSitOverride(FALSE),
mMouselookDisable(FALSE),
mComplete(FALSE),
mDirty(FALSE),
mCurrentMotion(LLUUID())
{
llwarns << "Creating new AO set: " << this << llendl;
// keep number and order in sync with the enum in the declaration
const std::string stateNames[AOSTATES_MAX]=
{
"Standing",
"Walking",
"Running",
"Sitting",
"Sitting On Ground",
"Crouching",
"Crouch Walking",
"Landing",
"Standing Up",
"Falling",
"Flying Down",
"Flying Up",
"Flying",
"Flying Slow",
"Hovering",
"Jumping",
"Pre Jumping",
"Turning Right",
"Turning Left",
"Typing",
"Floating",
"Swimming Forward",
"Swimming Up",
"Swimming Down"
};
// keep number and order in sync with the enum in the declaration
const LLUUID stateUUIDs[AOSTATES_MAX]=
{
ANIM_AGENT_STAND,
ANIM_AGENT_WALK,
ANIM_AGENT_RUN,
ANIM_AGENT_SIT,
ANIM_AGENT_SIT_GROUND,
ANIM_AGENT_CROUCH,
ANIM_AGENT_CROUCHWALK,
ANIM_AGENT_LAND,
ANIM_AGENT_STANDUP,
ANIM_AGENT_FALLDOWN,
ANIM_AGENT_HOVER_DOWN,
ANIM_AGENT_HOVER_UP,
ANIM_AGENT_FLY,
ANIM_AGENT_FLYSLOW,
ANIM_AGENT_HOVER,
ANIM_AGENT_JUMP,
ANIM_AGENT_PRE_JUMP,
ANIM_AGENT_TURNRIGHT,
ANIM_AGENT_TURNLEFT,
ANIM_AGENT_TYPE,
ANIM_AGENT_HOVER, // needs special treatment
ANIM_AGENT_FLY, // needs special treatment
ANIM_AGENT_HOVER_UP, // needs special treatment
ANIM_AGENT_HOVER_DOWN // needs special treatment
};
for(S32 index=0;index<AOSTATES_MAX;index++)
{
mStates[index].mName=stateNames[index];
mStates[index].mRemapID=stateUUIDs[index];
mStates[index].mInventoryUUID=LLUUID::null;
mStates[index].mCurrentAnimationID=LLUUID::null;
mStates[index].mCycleTime=0.0f;
mStates[index].mRandom=FALSE;
mStates[index].mDirty=FALSE;
mStateNames.push_back(stateNames[index]);
}
stopTimer();
}
AOSet::~AOSet()
{
llwarns << "Set deleted: " << this << llendl;
}
AOSet::AOState* AOSet::getState(S32 eName)
{
return &mStates[eName];
}
AOSet::AOState* AOSet::getStateByName(const std::string name)
{
for(S32 index=0;index<AOSTATES_MAX;index++)
{
if(mStates[index].mName.compare(name)==0)
{
return &mStates[index];
}
}
return NULL;
}
AOSet::AOState* AOSet::getStateByRemapID(const LLUUID id)
{
for(S32 index=0;index<AOSTATES_MAX;index++)
{
if(mStates[index].mRemapID==id)
{
return &mStates[index];
}
}
return NULL;
}
LLUUID AOSet::getAnimationForState(AOState* state)
{
if(state)
{
S32 numOfAnimations=state->mAnimations.size();
if(numOfAnimations)
{
if(state->mRandom)
{
state->mCurrentAnimation=ll_frand()*numOfAnimations;
llwarns << "randomly chosen " << state->mCurrentAnimation << " of " << numOfAnimations << llendl;
}
else
{
state->mCurrentAnimation++;
if(state->mCurrentAnimation>=state->mAnimations.size())
state->mCurrentAnimation=0;
llwarns << "cycle " << state->mCurrentAnimation << " of " << numOfAnimations << llendl;
}
return state->mAnimations[state->mCurrentAnimation].mAssetUUID;
}
else
llwarns << "animation state has no animations assigned" << llendl;
}
return LLUUID();
}
void AOSet::startTimer(F32 timeout)
{
mEventTimer.stop();
mPeriod=timeout;
mEventTimer.start();
lldebugs << "Starting state timer for " << getName() << " at " << timeout << llendl;
}
void AOSet::stopTimer()
{
lldebugs << "State timer for " << getName() << " stopped." << llendl;
mEventTimer.stop();
}
BOOL AOSet::tick()
{
AOEngine::instance().cycleTimeout(this);
return FALSE;
}
const LLUUID AOSet::getInventoryUUID() const
{
return mInventoryID;
}
void AOSet::setInventoryUUID(const LLUUID inventoryID)
{
mInventoryID=inventoryID;
}
const std::string AOSet::getName() const
{
return mName;
}
void AOSet::setName(std::string name)
{
mName=name;
}
BOOL AOSet::getSitOverride() const
{
return mSitOverride;
}
void AOSet::setSitOverride(BOOL yes)
{
mSitOverride=yes;
}
BOOL AOSet::getMouselookDisable() const
{
return mMouselookDisable;
}
void AOSet::setMouselookDisable(BOOL yes)
{
mMouselookDisable=yes;
}
BOOL AOSet::getComplete() const
{
return mComplete;
}
void AOSet::setComplete(BOOL yes)
{
mComplete=yes;
}
BOOL AOSet::getDirty() const
{
return mDirty;
}
void AOSet::setDirty(BOOL yes)
{
mDirty=yes;
}
void AOSet::setMotion(const LLUUID motion)
{
mCurrentMotion=motion;
}
LLUUID AOSet::getMotion() const
{
return mCurrentMotion;
}

134
indra/newview/aoset.h Normal file
View File

@ -0,0 +1,134 @@
/**
* @file aoset.h
* @brief Implementation of an Animation Overrider set of animations
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Zi Ree @ Second Life
*
* 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
*/
#ifndef AOSET_H
#define AOSET_H
#include "llcommon.h"
#include "lleventtimer.h"
class AOSet
: public LLEventTimer
{
public:
AOSet(const LLUUID inventoryID);
~AOSet();
// keep number and order in sync with list of names in the constructor
enum
{
Start=0, // convenience, so we don't have to know the name of the first state
Standing=0,
Walking,
Running,
Sitting,
SittingOnGround,
Crouching,
CrouchWalking,
Landing,
StandingUp,
Falling,
FlyingDown,
FlyingUp,
Flying,
FlyingSlow,
Hovering,
Jumping,
PreJumping,
TurningRight,
TurningLeft,
Typing,
Floating,
SwimmingForward,
SwimmingUp,
SwimmingDown,
AOSTATES_MAX
};
struct AOAnimation
{
std::string mName;
LLUUID mAssetUUID;
LLUUID mInventoryUUID;
S32 mSortOrder;
};
struct AOState
{
std::string mName;
LLUUID mRemapID;
BOOL mRandom;
S32 mCycleTime;
std::vector<AOAnimation> mAnimations;
S32 mCurrentAnimation;
LLUUID mCurrentAnimationID;
LLUUID mInventoryUUID;
BOOL mDirty;
};
const LLUUID getInventoryUUID() const;
void setInventoryUUID(const LLUUID inventoryID);
const std::string getName() const;
void setName(std::string name);
BOOL getSitOverride() const;
void setSitOverride(BOOL yes);
BOOL getMouselookDisable() const;
void setMouselookDisable(BOOL yes);
BOOL getComplete() const;
void setComplete(BOOL yes);
LLUUID getMotion() const;
void setMotion(const LLUUID motion);
BOOL getDirty() const;
void setDirty(BOOL yes);
AOState* getState(S32 eName);
AOState* getStateByName(const std::string name);
AOState* getStateByRemapID(const LLUUID id);
LLUUID getAnimationForState(AOState* state);
void startTimer(F32 timeout);
void stopTimer();
virtual BOOL tick();
std::vector<std::string> mStateNames;
protected:
LLUUID mInventoryID;
std::string mName;
BOOL mSitOverride;
BOOL mMouselookDisable;
BOOL mComplete;
LLUUID mCurrentMotion;
BOOL mDirty;
AOState mStates[AOSTATES_MAX];
};
#endif // AOSET_H

View File

@ -29,6 +29,7 @@
#include "pipeline.h"
#include "aoengine.h" // ## Zi: Animation Overrider
#include "llagent.h"
#include "llanimationstates.h"
#include "llfloatercamera.h"
@ -2096,6 +2097,7 @@ void LLAgentCamera::changeCameraToMouselook(BOOL animate)
updateLastCamera();
mCameraMode = CAMERA_MODE_MOUSELOOK;
AOEngine::getInstance()->inMouselook(TRUE); // ## Zi: Animation Overrider
const U32 old_flags = gAgent.getControlFlags();
gAgent.setControlFlags(AGENT_CONTROL_MOUSELOOK);
if (old_flags != gAgent.getControlFlags())
@ -2157,6 +2159,7 @@ void LLAgentCamera::changeCameraToFollow(BOOL animate)
updateLastCamera();
mCameraMode = CAMERA_MODE_FOLLOW;
AOEngine::getInstance()->inMouselook(FALSE); // ## Zi: Animation Overrider
// bang-in the current focus, position, and up vector of the follow cam
mFollowCam.reset(mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis);
@ -2235,6 +2238,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
}
updateLastCamera();
mCameraMode = CAMERA_MODE_THIRD_PERSON;
AOEngine::getInstance()->inMouselook(FALSE); // ## Zi: Animation Overrider
gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
}

View File

@ -29,6 +29,7 @@
#include "llappviewer.h"
// Viewer includes
#include "aoengine.h" // ## Zi: Animation Overrider
#include "llversioninfo.h"
#include "llfeaturemanager.h"
#include "lluictrlfactory.h"
@ -1017,7 +1018,10 @@ bool LLAppViewer::init()
LLAgentLanguage::init();
// ## Zi: Animation Overrider
setOnLoginCompletedCallback(boost::bind(&AOEngine::onLoginComplete));
llwarns << "AO on login callback set up." << llendl;
// ## Zi: Animation Overrider
return true;
}

View File

@ -38,6 +38,7 @@
#include "lltexteditor.h"
// newview includes
#include "aoengine.h" // ## Zi: Animation Overrider
#include "llagentcamera.h"
#include "llchiclet.h"
#include "llfloatercamera.h"
@ -539,6 +540,13 @@ void LLBottomTray::toggleCameraControls()
mCamButton->onCommit();
}
// ## Zi: Animation Overrider
void LLBottomTray::toggleAO()
{
AOEngine::getInstance()->enable(getChild<LLButton>("ao_toggle_btn")->getToggleState());
}
// ## Zi: Animation Overrider
BOOL LLBottomTray::postBuild()
{
LLHints::registerHintTarget("bottom_tray", LLView::getHandle());
@ -606,6 +614,12 @@ BOOL LLBottomTray::postBuild()
getChild<LLUICtrl>("sidebar_places_btn")->setCommitCallback(boost::bind(&LLBottomTray::showSidebarPanel, this, "panel_places"));
getChild<LLUICtrl>("sidebar_appearance_btn")->setCommitCallback(boost::bind(&LLBottomTray::showSidebarPanel, this, "sidepanel_appearance"));
getChild<LLUICtrl>("sidebar_inv_btn")->setCommitCallback(boost::bind(&LLBottomTray::showSidebarPanel, this, "sidepanel_inventory"));
// ## Zi: Animation Overrider
LLButton* aoToggleButton=getChild<LLButton>("ao_toggle_btn");
aoToggleButton->setCommitCallback(boost::bind(&LLBottomTray::toggleAO,this));
// this needs to become a preferences option
aoToggleButton->setToggleState(TRUE);
// ## Zi: Animation Overrider
return TRUE;
}

View File

@ -124,6 +124,7 @@ public:
void toggleMovementControls();
void toggleCameraControls();
void toggleAO(); // ## Zi: Animation Overrider
void onMouselookModeIn();
void onMouselookModeOut();

View File

@ -31,6 +31,7 @@
#include "llviewerfloaterreg.h"
#include "ao.h" // ## Zi: Animation Overrider
#include "kvfloaterflickrauth.h"
#include "kvfloaterflickrupload.h"
#include "llcompilequeue.h"
@ -141,6 +142,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterAboutUtil::registerFloater();
LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>);
LLFloaterReg::add("animation_overrider", "floater_ao.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FloaterAO>); // ## Zi: Animation Overrider
LLFloaterReg::add("area_search", "floater_fs_area_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSAreaSearch>);
LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>);
LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>);

View File

@ -42,6 +42,7 @@
#include "noise.h"
#include "sound_ids.h"
#include "aoengine.h" // ## Zi: Animation Overrider
#include "llagent.h" // Get state values from here
#include "llagentcamera.h"
#include "llagentwearables.h"
@ -4794,7 +4795,19 @@ BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset)
lldebugs << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << llendl;
LLUUID remap_id = remapMotionID(id);
// ## Zi: Animation Overrider
LLUUID remap_id;
if(isSelf())
{
remap_id=AOEngine::getInstance()->override(id,TRUE);
if(remap_id.isNull())
remap_id=remapMotionID(id);
else
gAgent.sendAnimationRequest(remap_id,ANIM_REQUEST_START);
}
else
remap_id=remapMotionID(id);
// ## Zi: Animation Overrider
if (remap_id != id)
{
@ -4816,8 +4829,20 @@ BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate)
{
lldebugs << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << llendl;
LLUUID remap_id = remapMotionID(id);
// ## Zi: Animation Overrider
LLUUID remap_id;
if(isSelf())
{
remap_id=AOEngine::getInstance()->override(id,FALSE);
if(remap_id.isNull())
remap_id=remapMotionID(id);
else
gAgent.sendAnimationRequest(remap_id,ANIM_REQUEST_STOP);
}
else
remap_id=remapMotionID(id);
// ## Zi: Animation Overrider
if (remap_id != id)
{
lldebugs << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << llendl;

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
can_resize="true"
can_dock="true"
can_close="false"
height="352"
min_height="320"
layout="topleft"
name="animation_overrider"
help_topic="animation_overrider"
save_rect="true"
save_visibility="true"
single_instance="true"
save_dock_state="true"
title="Animation Overrider"
width="200">
<floater.string
name="ao_no_sets_loaded">
No Sets Loaded
</floater.string>
<floater.string
name="ao_no_animations_loaded">
No Animations Loaded
</floater.string>
<panel
name="animation_overrider_panel"
filename="panel_ao.xml"
left="10"
top="20"
width="180"
height="330"
follows="all"
layout="topleft">
</panel>
</floater>

View File

@ -140,6 +140,17 @@
function="CheckControl"
parameter="ShowPlacesButton" />
</menu_item_check>
<menu_item_check
label="AO button"
layout="topleft"
name="ShowAOButton">
<menu_item_check.on_click
function="ToggleControl"
parameter="ShowAOButton" />
<menu_item_check.on_check
function="CheckControl"
parameter="ShowAOButton" />
</menu_item_check>
<menu_item_separator
name="Separator" />
<menu_item_call

View File

@ -7026,4 +7026,51 @@ Reset WL settings for &apos;[PARCEL_NAME]&apos; to region default?
yestext="Yes"/>
</notification>
<!-- ## Zi: Animation Overrider -->
<notification
icon="alertmodal.tga"
name="NewAOSet"
type="alertmodal">
Specify a name for the new AO set:
(The name may not contain a : character)
<form name="form">
<input name="message" type="text">
New AO Set
</input>
<button
default="true"
index="0"
name="OK"
text="OK"/>
<button
index="1"
name="Cancel"
text="Cancel"/>
</form>
</notification>
<notification
icon="alertmodal.tga"
name="NewAOCantContainColon"
type="alertmodal">
Could not create new AO set.
The name may not contain ":" characters.
<usetemplate
name="okbutton"
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="RemoveAOSet"
type="alertmodal">
Remove AO set [AO_SET_NAME] from the list?
<usetemplate
name="okcancelbuttons"
notext="Cancel"
yestext="Remove"/>
</notification>
<!-- ## Zi: Animation Overrider -->
</notifications>

View File

@ -0,0 +1,258 @@
<panel
name="animation_overrider_panel"
left="10"
top="4"
width="180"
height="306"
follows="all"
layout="topleft">
<combo_box
name="ao_set_selection_combo"
tool_tip="Select animation set to edit."
left="0"
top="4"
right="-24"
height="20"
allow_text_entry="true"
follows="left|right|top"
layout="topleft" />
<button
name="ao_activate"
tool_tip="Activate this animation set now."
left_pad="4"
width="20"
height="20"
follows="right|top"
layout="topleft" />
<icon
left_delta="4"
top_delta="4"
width="12"
height="12"
image_name="Activate_Checkmark"
follows="right|top"
layout="topleft" />
<panel
name="ao_more"
left="0"
top_pad="4"
right="-1"
height="252"
follows="all"
layout="topleft">
<check_box
name="ao_default"
label="Default"
tool_tip="Make this animation set the default."
left="0"
top_pad="4"
width="20"
height="20"
follows="left|top"
layout="topleft" />
<button
name="ao_add"
tool_tip="Create a new animation set."
top_delta="0"
right="-24"
width="20"
height="20"
image_overlay="AddItem_Press"
follows="right|top"
layout="topleft" />
<button
name="ao_remove"
tool_tip="Remove this animation set."
left_pad="4"
width="20"
height="20"
image_overlay="TrashItem_Press"
follows="right|top"
layout="topleft" />
<check_box
name="ao_sit_override"
label="Override Sits"
tool_tip="Check this if you want sit animation overrides."
left="0"
top_pad="4"
width="100"
height="16"
follows="left|top"
layout="topleft" />
<check_box
name="ao_disable_stands_in_mouselook"
label="Disable Stands in Mouselook"
tool_tip="If you need to preserve your custom stand animation in mouselook, check this box."
top_pad="4"
width="100"
height="16"
follows="left|top"
layout="topleft" />
<combo_box
name="ao_state_selection_combo"
tool_tip="Select animation state to edit."
left="0"
top_pad="4"
right="-1"
height="20"
follows="left|right|top"
layout="topleft" />
<scroll_list
name="ao_state_animation_list"
top_pad="4"
right="-24"
height="98"
multi_select="true"
follows="all"
layout="topleft" />
<panel
name="ao_animation_move_trash_panel"
left_pad="4"
right="-1"
height="98"
follows="right|top|bottom"
layout="topleft">
<button
name="ao_move_up"
tool_tip="Move the selected animation up in the list."
left="0"
top="0"
width="20"
height="32"
image_overlay="Arrow_Up"
follows="left|top"
layout="topleft" />
<button
name="ao_move_down"
tool_tip="Move the selected animation down in the list."
top_pad="4"
width="20"
height="32"
image_overlay="Arrow_Down"
follows="left|top"
layout="topleft" />
<button
name="ao_trash"
tool_tip="Remove the selected animation from the list."
left_delta="0"
bottom="-1"
width="20"
height="20"
image_overlay="TrashItem_Press"
follows="left|bottom"
layout="topleft" />
</panel>
<check_box
name="ao_randomize"
label="Randomize order"
tool_tip="Randomize order of animations in cycle mode."
left="0"
top_pad="4"
width="100"
height="16"
follows="left|bottom"
layout="topleft" />
<text
name="ao_cycle_time_seconds_label"
value="Cycle time (seconds):"
top_pad="4"
width="120"
follows="left|right|bottom"
layout="topleft" />
<spinner
name="ao_cycle_time"
tool_tip="Time before switching to the next animation in the list. Set this to 0 to disable automatic animation cycling."
top_delta="-6"
left_pad="8"
height="16"
right="-1"
decimal_digits="0"
initial_value="0"
min_val="0"
max_val="999"
increment="1"
follows="right|bottom"
layout="topleft" />
<button
name="ao_reload"
label="Reload"
tool_tip="Reload animation overrider configuration."
left="0"
top_pad="8"
right="-1"
height="20"
follows="left|right|bottom"
layout="topleft" />
</panel>
<layout_stack
name="next_previous_buttons_stack"
left="0"
top_pad="4"
right="-1"
height="20"
orientation="horizontal"
follows="left|right|bottom"
layout="topleft">
<layout_panel
width="90"
height="20"
user_resize="false"
follows="all"
layout="topleft">
<button
name="ao_previous"
label="&lt;&lt;"
tool_tip="Switch to previous animation of the current state."
left="0"
top="0"
width="88"
height="20"
follows="all"
layout="topleft" />
</layout_panel>
<layout_panel
width="90"
height="20"
user_resize="false"
follows="all"
layout="topleft">
<button
name="ao_next"
label="&gt;&gt;"
tool_tip="Switch to next animation of the current state."
left="2"
top="0"
width="88"
height="20"
follows="all"
layout="topleft" />
</layout_panel>
</layout_stack>
</panel>

View File

@ -5,7 +5,6 @@
bg_opaque_color="DkGray"
chrome="true"
follows="left|bottom|right"
focus_root="true"
height="33"
layout="topleft"
left="0"
@ -563,6 +562,54 @@
</bottomtray_button>
</layout_panel>
<!-- ## Zi: AO button -->
<layout_panel
auto_resize="false"
follows="left|right"
height="28"
layout="topleft"
min_height="28"
min_width="40"
mouse_opaque="false"
name="ao_btn_panel"
user_resize="false"
width="40">
<bottomtray_button
name="ao_toggle_btn"
tool_tip="Enables/Disables Animation Overrider"
follows="left|right"
height="23"
image_pressed="PushButton_Press"
image_pressed_selected="PushButton_Selected_Press"
image_selected="PushButton_Selected_Press"
is_toggle="true"
image_overlay="ao_toggle_18"
layout="topleft"
left="0"
top="5"
use_ellipses="true"
width="36">
</bottomtray_button>
<bottomtray_button
name="ao_btn"
tool_tip="Shows/hides Animation Overrider"
left_pad="0"
height="23"
width="16"
image_disabled="ComboButton_UpOff"
image_unselected="ComboButton_UpOff"
image_selected="ComboButton_Up_On_Selected"
image_pressed="ComboButton_UpSelected"
image_pressed_selected="ComboButton_Up_On_Selected"
is_toggle="true"
tab_stop="true">
<init_callback
function="Button.SetFloaterToggle"
parameter="animation_overrider" />
</bottomtray_button>
</layout_panel>
<!-- ## Zi: AO button -->
<icon
auto_resize="false"
color="Transparent"

View File

@ -5,7 +5,6 @@
bg_opaque_color="DkGray"
chrome="true"
follows="left|bottom|right"
focus_root="true"
height="33"
layout="topleft"
left="0"
@ -560,6 +559,54 @@
</bottomtray_button>
</layout_panel>
<!-- ## Zi: AO button -->
<layout_panel
auto_resize="false"
follows="left|right"
height="28"
layout="topleft"
min_height="28"
min_width="56"
mouse_opaque="false"
name="ao_btn_panel"
user_resize="false"
width="56">
<bottomtray_button
name="ao_toggle_btn"
tool_tip="Enables/Disables Animation Overrider"
follows="left|right"
height="23"
image_pressed="PushButton_Press"
image_pressed_selected="PushButton_Selected_Press"
image_selected="PushButton_Selected_Press"
is_toggle="true"
image_overlay="ao_toggle_18"
layout="topleft"
left="0"
top="5"
use_ellipses="true"
width="36">
</bottomtray_button>
<bottomtray_button
name="ao_btn"
tool_tip="Shows/hides Animation Overrider"
left_pad="0"
height="23"
width="16"
image_disabled="ComboButton_UpOff"
image_unselected="ComboButton_UpOff"
image_selected="ComboButton_Up_On_Selected"
image_pressed="ComboButton_UpSelected"
image_pressed_selected="ComboButton_Up_On_Selected"
is_toggle="true"
tab_stop="true">
<init_callback
function="Button.SetFloaterToggle"
parameter="animation_overrider" />
</bottomtray_button>
</layout_panel>
<!-- ## Zi: AO button -->
<icon
auto_resize="false"
color="Transparent"