510 lines
12 KiB
C++
Executable File
510 lines
12 KiB
C++
Executable File
/**
|
|
* @file lltoolmgr.cpp
|
|
* @brief LLToolMgr class implementation
|
|
*
|
|
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
|
* Second Life Viewer Source Code
|
|
* Copyright (C) 2010, Linden Research, Inc.
|
|
*
|
|
* 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 "lltoolmgr.h"
|
|
|
|
#include "lluictrl.h"
|
|
#include "llmenugl.h"
|
|
#include "llfloaterreg.h"
|
|
|
|
//#include "llfirstuse.h"
|
|
// tools and manipulators
|
|
#include "llfloaterinspect.h"
|
|
#include "lltool.h"
|
|
#include "llmanipscale.h"
|
|
#include "llselectmgr.h"
|
|
#include "lltoolbrush.h"
|
|
#include "lltoolcomp.h"
|
|
#include "lltooldraganddrop.h"
|
|
#include "lltoolface.h"
|
|
#include "lltoolfocus.h"
|
|
#include "lltoolgrab.h"
|
|
#include "lltoolindividual.h"
|
|
#include "lltoolmorph.h"
|
|
#include "lltoolpie.h"
|
|
#include "lltoolselectland.h"
|
|
#include "lltoolobjpicker.h"
|
|
#include "lltoolpipette.h"
|
|
#include "llagent.h"
|
|
#include "llagentcamera.h"
|
|
#include "llviewercontrol.h"
|
|
#include "llviewerjoystick.h"
|
|
#include "llviewermenu.h"
|
|
#include "llviewerparcelmgr.h"
|
|
// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e)
|
|
#include "rlvhandler.h"
|
|
#include "rlvui.h"
|
|
// [/RLVa:KB]
|
|
|
|
// Used when app not active to avoid processing hover.
|
|
LLTool* gToolNull = NULL;
|
|
|
|
LLToolset* gBasicToolset = NULL;
|
|
LLToolset* gCameraToolset = NULL;
|
|
//LLToolset* gLandToolset = NULL;
|
|
LLToolset* gMouselookToolset = NULL;
|
|
LLToolset* gFaceEditToolset = NULL;
|
|
|
|
/////////////////////////////////////////////////////
|
|
// LLToolMgr
|
|
|
|
LLToolMgr::LLToolMgr()
|
|
:
|
|
mBaseTool(NULL),
|
|
mSavedTool(NULL),
|
|
mTransientTool( NULL ),
|
|
mOverrideTool( NULL ),
|
|
mSelectedTool( NULL ),
|
|
mCurrentToolset( NULL )
|
|
{
|
|
// Not a panel, register these callbacks globally.
|
|
LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Active", boost::bind(&LLToolMgr::inEdit, this));
|
|
// LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Enabled", boost::bind(&LLToolMgr::canEdit, this));
|
|
// [RLVa:KB] - Checked: 2010-09-11 (RLVa-1.2.1d) | Added: RLVa-1.2.1d | Ansa: Changed because of FIRE-5552
|
|
LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Enabled", boost::bind(&RlvUIEnabler::isBuildEnabled));
|
|
// [/RLVa:KB]
|
|
LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Build.Toggle", boost::bind(&LLToolMgr::toggleBuildMode, this, _2));
|
|
|
|
gToolNull = new LLTool(LLStringUtil::null); // Does nothing
|
|
setCurrentTool(gToolNull);
|
|
|
|
gBasicToolset = new LLToolset();
|
|
gCameraToolset = new LLToolset();
|
|
// gLandToolset = new LLToolset();
|
|
gMouselookToolset = new LLToolset();
|
|
gFaceEditToolset = new LLToolset();
|
|
gMouselookToolset->setShowFloaterTools(false);
|
|
gFaceEditToolset->setShowFloaterTools(false);
|
|
}
|
|
|
|
void LLToolMgr::initTools()
|
|
{
|
|
static BOOL initialized = FALSE;
|
|
if(initialized)
|
|
{
|
|
return;
|
|
}
|
|
initialized = TRUE;
|
|
gBasicToolset->addTool( LLToolPie::getInstance() );
|
|
gBasicToolset->addTool( LLToolCamera::getInstance() );
|
|
gCameraToolset->addTool( LLToolCamera::getInstance() );
|
|
gBasicToolset->addTool( LLToolGrab::getInstance() );
|
|
gBasicToolset->addTool( LLToolCompTranslate::getInstance() );
|
|
gBasicToolset->addTool( LLToolCompCreate::getInstance() );
|
|
gBasicToolset->addTool( LLToolBrushLand::getInstance() );
|
|
gMouselookToolset->addTool( LLToolCompGun::getInstance() );
|
|
gBasicToolset->addTool( LLToolCompInspect::getInstance() );
|
|
gFaceEditToolset->addTool( LLToolCamera::getInstance() );
|
|
|
|
// On startup, use "select" tool
|
|
setCurrentToolset(gBasicToolset);
|
|
|
|
gBasicToolset->selectTool( LLToolPie::getInstance() );
|
|
}
|
|
|
|
LLToolMgr::~LLToolMgr()
|
|
{
|
|
delete gBasicToolset;
|
|
gBasicToolset = NULL;
|
|
|
|
delete gMouselookToolset;
|
|
gMouselookToolset = NULL;
|
|
|
|
delete gFaceEditToolset;
|
|
gFaceEditToolset = NULL;
|
|
|
|
delete gCameraToolset;
|
|
gCameraToolset = NULL;
|
|
|
|
delete gToolNull;
|
|
gToolNull = NULL;
|
|
}
|
|
|
|
BOOL LLToolMgr::usingTransientTool()
|
|
{
|
|
return mTransientTool ? TRUE : FALSE;
|
|
}
|
|
|
|
void LLToolMgr::setCurrentToolset(LLToolset* current)
|
|
{
|
|
if (!current) return;
|
|
|
|
// switching toolsets?
|
|
if (current != mCurrentToolset)
|
|
{
|
|
// deselect current tool
|
|
if (mSelectedTool)
|
|
{
|
|
mSelectedTool->handleDeselect();
|
|
}
|
|
mCurrentToolset = current;
|
|
// select first tool of new toolset only if toolset changed
|
|
mCurrentToolset->selectFirstTool();
|
|
}
|
|
// update current tool based on new toolset
|
|
setCurrentTool( mCurrentToolset->getSelectedTool() );
|
|
}
|
|
|
|
LLToolset* LLToolMgr::getCurrentToolset()
|
|
{
|
|
return mCurrentToolset;
|
|
}
|
|
|
|
void LLToolMgr::setCurrentTool( LLTool* tool )
|
|
{
|
|
if (mTransientTool)
|
|
{
|
|
mTransientTool = NULL;
|
|
}
|
|
|
|
mBaseTool = tool;
|
|
updateToolStatus();
|
|
|
|
mSavedTool = NULL;
|
|
}
|
|
|
|
LLTool* LLToolMgr::getCurrentTool()
|
|
{
|
|
MASK override_mask = gKeyboard ? gKeyboard->currentMask(TRUE) : 0;
|
|
|
|
LLTool* cur_tool = NULL;
|
|
// always use transient tools if available
|
|
if (mTransientTool)
|
|
{
|
|
mOverrideTool = NULL;
|
|
cur_tool = mTransientTool;
|
|
}
|
|
// tools currently grabbing mouse input will stay active
|
|
else if (mSelectedTool && mSelectedTool->hasMouseCapture())
|
|
{
|
|
cur_tool = mSelectedTool;
|
|
}
|
|
else
|
|
{
|
|
mOverrideTool = mBaseTool ? mBaseTool->getOverrideTool(override_mask) : NULL;
|
|
|
|
// use override tool if available otherwise drop back to base tool
|
|
cur_tool = mOverrideTool ? mOverrideTool : mBaseTool;
|
|
}
|
|
|
|
LLTool* prev_tool = mSelectedTool;
|
|
// Set the selected tool to avoid infinite recursion
|
|
mSelectedTool = cur_tool;
|
|
|
|
//update tool selection status
|
|
if (prev_tool != cur_tool)
|
|
{
|
|
if (prev_tool)
|
|
{
|
|
prev_tool->handleDeselect();
|
|
}
|
|
if (cur_tool)
|
|
{
|
|
if ( LLToolCompInspect::getInstance()->isToolCameraActive()
|
|
&& prev_tool == LLToolCamera::getInstance()
|
|
&& cur_tool == LLToolPie::getInstance() )
|
|
{
|
|
LLFloaterInspect * inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect");
|
|
if(inspect_instance && inspect_instance->getVisible())
|
|
{
|
|
setTransientTool(LLToolCompInspect::getInstance());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cur_tool->handleSelect();
|
|
}
|
|
}
|
|
}
|
|
|
|
return mSelectedTool;
|
|
}
|
|
|
|
LLTool* LLToolMgr::getBaseTool()
|
|
{
|
|
return mBaseTool;
|
|
}
|
|
|
|
void LLToolMgr::updateToolStatus()
|
|
{
|
|
// call getcurrenttool() to calculate active tool and call handleSelect() and handleDeselect() immediately
|
|
// when active tool changes
|
|
getCurrentTool();
|
|
}
|
|
|
|
bool LLToolMgr::inEdit()
|
|
{
|
|
return mBaseTool != LLToolPie::getInstance() && mBaseTool != gToolNull;
|
|
}
|
|
|
|
bool LLToolMgr::canEdit()
|
|
{
|
|
return LLViewerParcelMgr::getInstance()->allowAgentBuild();
|
|
}
|
|
|
|
void LLToolMgr::toggleBuildMode(const LLSD& sdname)
|
|
{
|
|
const std::string& param = sdname.asString();
|
|
|
|
// [RLVa:KB] - Checked: 2012-04-26 (RLVa-1.4.6) | Added: RLVa-1.4.6 | Ansa: Changed because of FIRE-5552
|
|
//if (param == "build" && !canEdit())
|
|
if (param == "build" && !RlvUIEnabler::isBuildEnabled())
|
|
// [/RLVa:KB]
|
|
{
|
|
return;
|
|
}
|
|
|
|
LLFloaterReg::toggleInstanceOrBringToFront("build");
|
|
|
|
bool build_visible = LLFloaterReg::instanceVisible("build");
|
|
if (build_visible)
|
|
{
|
|
ECameraMode camMode = gAgentCamera.getCameraMode();
|
|
if (CAMERA_MODE_MOUSELOOK == camMode || CAMERA_MODE_CUSTOMIZE_AVATAR == camMode)
|
|
{
|
|
// pull the user out of mouselook or appearance mode when entering build mode
|
|
handle_reset_view();
|
|
}
|
|
|
|
if (gSavedSettings.getBOOL("EditCameraMovement"))
|
|
{
|
|
// camera should be set
|
|
if (LLViewerJoystick::getInstance()->getOverrideCamera())
|
|
{
|
|
handle_toggle_flycam();
|
|
}
|
|
|
|
if (gAgentCamera.getFocusOnAvatar())
|
|
{
|
|
// zoom in if we're looking at the avatar
|
|
gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
|
|
gAgentCamera.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis()));
|
|
gAgentCamera.cameraZoomIn(0.666f);
|
|
gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
|
|
}
|
|
}
|
|
|
|
|
|
setCurrentToolset(gBasicToolset);
|
|
getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );
|
|
|
|
// Could be first use
|
|
//LLFirstUse::useBuild();
|
|
|
|
gAgentCamera.resetView(false);
|
|
|
|
// avoid spurious avatar movements
|
|
LLViewerJoystick::getInstance()->setNeedsReset();
|
|
|
|
}
|
|
else
|
|
{
|
|
if (gSavedSettings.getBOOL("EditCameraMovement"))
|
|
{
|
|
// just reset the view, will pull us out of edit mode
|
|
handle_reset_view();
|
|
}
|
|
else
|
|
{
|
|
// manually disable edit mode, but do not affect the camera
|
|
gAgentCamera.resetView(false);
|
|
LLFloaterReg::hideInstance("build");
|
|
gViewerWindow->showCursor();
|
|
}
|
|
// avoid spurious avatar movements pulling out of edit mode
|
|
LLViewerJoystick::getInstance()->setNeedsReset();
|
|
}
|
|
|
|
}
|
|
|
|
bool LLToolMgr::inBuildMode()
|
|
{
|
|
// when entering mouselook inEdit() immediately returns true before
|
|
// cameraMouselook() actually starts returning true. Also, appearance edit
|
|
// sets build mode to true, so let's exclude that.
|
|
bool b=(inEdit()
|
|
&& !gAgentCamera.cameraMouselook()
|
|
&& mCurrentToolset != gFaceEditToolset);
|
|
|
|
return b;
|
|
}
|
|
|
|
void LLToolMgr::setTransientTool(LLTool* tool)
|
|
{
|
|
if (!tool)
|
|
{
|
|
clearTransientTool();
|
|
}
|
|
else
|
|
{
|
|
if (mTransientTool)
|
|
{
|
|
mTransientTool = NULL;
|
|
}
|
|
|
|
mTransientTool = tool;
|
|
}
|
|
|
|
updateToolStatus();
|
|
}
|
|
|
|
void LLToolMgr::clearTransientTool()
|
|
{
|
|
if (mTransientTool)
|
|
{
|
|
mTransientTool = NULL;
|
|
if (!mBaseTool)
|
|
{
|
|
LL_WARNS() << "mBaseTool is NULL" << LL_ENDL;
|
|
}
|
|
}
|
|
updateToolStatus();
|
|
}
|
|
|
|
|
|
void LLToolMgr::onAppFocusLost()
|
|
{
|
|
if (mSelectedTool)
|
|
{
|
|
mSelectedTool->handleDeselect();
|
|
}
|
|
updateToolStatus();
|
|
}
|
|
|
|
void LLToolMgr::onAppFocusGained()
|
|
{
|
|
if (mSelectedTool)
|
|
{
|
|
mSelectedTool->handleSelect();
|
|
}
|
|
updateToolStatus();
|
|
}
|
|
|
|
void LLToolMgr::clearSavedTool()
|
|
{
|
|
mSavedTool = NULL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////
|
|
// LLToolset
|
|
|
|
void LLToolset::addTool(LLTool* tool)
|
|
{
|
|
mToolList.push_back( tool );
|
|
if( !mSelectedTool )
|
|
{
|
|
mSelectedTool = tool;
|
|
}
|
|
}
|
|
|
|
|
|
void LLToolset::selectTool(LLTool* tool)
|
|
{
|
|
mSelectedTool = tool;
|
|
LLToolMgr::getInstance()->setCurrentTool( mSelectedTool );
|
|
}
|
|
|
|
|
|
void LLToolset::selectToolByIndex( S32 index )
|
|
{
|
|
LLTool *tool = (index >= 0 && index < (S32)mToolList.size()) ? mToolList[index] : NULL;
|
|
if (tool)
|
|
{
|
|
mSelectedTool = tool;
|
|
LLToolMgr::getInstance()->setCurrentTool( tool );
|
|
}
|
|
}
|
|
|
|
BOOL LLToolset::isToolSelected( S32 index )
|
|
{
|
|
LLTool *tool = (index >= 0 && index < (S32)mToolList.size()) ? mToolList[index] : NULL;
|
|
return (tool == mSelectedTool);
|
|
}
|
|
|
|
|
|
void LLToolset::selectFirstTool()
|
|
{
|
|
mSelectedTool = (0 < mToolList.size()) ? mToolList[0] : NULL;
|
|
LLToolMgr::getInstance()->setCurrentTool( mSelectedTool );
|
|
}
|
|
|
|
|
|
void LLToolset::selectNextTool()
|
|
{
|
|
LLTool* next = NULL;
|
|
for( tool_list_t::iterator iter = mToolList.begin();
|
|
iter != mToolList.end(); )
|
|
{
|
|
LLTool* cur = *iter++;
|
|
if( cur == mSelectedTool && iter != mToolList.end() )
|
|
{
|
|
next = *iter;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( next )
|
|
{
|
|
mSelectedTool = next;
|
|
LLToolMgr::getInstance()->setCurrentTool( mSelectedTool );
|
|
}
|
|
else
|
|
{
|
|
selectFirstTool();
|
|
}
|
|
}
|
|
|
|
void LLToolset::selectPrevTool()
|
|
{
|
|
LLTool* prev = NULL;
|
|
for( tool_list_t::reverse_iterator iter = mToolList.rbegin();
|
|
iter != mToolList.rend(); )
|
|
{
|
|
LLTool* cur = *iter++;
|
|
if( cur == mSelectedTool && iter != mToolList.rend() )
|
|
{
|
|
prev = *iter;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( prev )
|
|
{
|
|
mSelectedTool = prev;
|
|
LLToolMgr::getInstance()->setCurrentTool( mSelectedTool );
|
|
}
|
|
else if (mToolList.size() > 0)
|
|
{
|
|
selectToolByIndex((S32)mToolList.size()-1);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|