Files
SingularityViewer/indra/newview/lltoolmgr.cpp
Inusaito Sayori f8520f9dd3 Em Dash wants build tools to focus properly when the build button is clicked.
If the world is in focus and build button is pressed without the build floater open, don't bother focusing.
If a floater is in focus and build button is pressed without the build floater open, focus the build floater
If the build floater is in the background and the button is pressed, focus the build floater.
If the build floater is in focus and the button is pressed, close the build floater.
If the build floater is  not in focus but nothing else is, close the build floater.
2014-09-03 19:41:07 -04:00

526 lines
12 KiB
C++

/**
* @file lltoolmgr.cpp
* @brief LLToolMgr class implementation
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "lltoolmgr.h"
#include "llfirstuse.h"
// tools and manipulators
#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 "lltoolplacer.h"
#include "lltoolselectland.h"
#include "lltoolobjpicker.h"
#include "lltoolpipette.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llviewercontrol.h"
#include "llmemberlistener.h"
#include "llevent.h"
#include "llviewerjoystick.h"
#include "llviewermenu.h"
#include "llviewerparcelmgr.h"
#include "llfloatertools.h"
#include "rlvhandler.h"
// 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
class LLViewBuildMode : public LLMemberListener<LLView>
{
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{
LLToolMgr::getInstance()->toggleBuildMode();
return true;
}
};
class LLViewCheckBuildMode : public LLMemberListener<LLView>
{
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{
bool new_value = LLToolMgr::getInstance()->inEdit();
gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
return true;
}
};
LLToolMgr::LLToolMgr()
:
mBaseTool(NULL),
mSavedTool(NULL),
mTransientTool( NULL ),
mOverrideTool( NULL ),
mSelectedTool( NULL ),
mCurrentToolset( NULL )
{
gToolNull = new LLTool(LLStringUtil::null); // Does nothing
setCurrentTool(gToolNull);
gBasicToolset = new LLToolset("Basic");
gCameraToolset = new LLToolset("Camera");
// gLandToolset = new LLToolset("Land");
gMouselookToolset = new LLToolset("MouseLook");
gFaceEditToolset = new LLToolset("FaceEdit");
}
void LLToolMgr::initMenu(std::vector<LLPointer<LLMemberListener<LLView> > >& menu_list)
{
menu_list.push_back(new LLViewBuildMode());
menu_list.back()->registerListener(gMenuHolder, "View.BuildMode");
menu_list.push_back(new LLViewCheckBuildMode());
menu_list.back()->registerListener(gMenuHolder, "View.CheckBuildMode");
}
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();
}
lldebugs << "Current tool set: " << current->getName() << llendl;
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(tool && mBaseTool!=tool)
lldebugs << "Current Tool: " << tool->getName() << llendl;
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
{
// don't override gToolNull
mOverrideTool = mBaseTool && (mBaseTool != gToolNull) ? 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)
{
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()
{
static const LLCachedControl<bool> freeze_time("FreezeTime",false);
return mBaseTool != LLToolPie::getInstance() && mBaseTool != gToolNull && (mCurrentToolset != gCameraToolset || !freeze_time);
}
bool LLToolMgr::canEdit()
{
return LLViewerParcelMgr::getInstance()->allowAgentBuild();
}
void LLToolMgr::toggleBuildMode()
{
if (!inBuildMode())
{
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 );
}
}
// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b)
bool fRlvCanEdit = (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ));
if (!fRlvCanEdit)
{
LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection();
RlvSelectIsEditable f;
if ((hSel.notNull()) && ((hSel->getFirstRootNode(&f, TRUE)) != NULL))
LLSelectMgr::getInstance()->deselectAll();
}
// [/RLVa:KB]
setCurrentToolset(gBasicToolset);
getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );
// Could be first use
LLFirstUse::useBuild();
gAgentCamera.resetView(false);
// avoid spurious avatar movements
LLViewerJoystick::getInstance()->setNeedsReset();
if (gFocusMgr.getKeyboardFocus()) gFloaterTools->setFocus(true); // Focus isn't on the world, give it to the build tools.
}
.. else if (gFloaterTools->getVisible() && !gFloaterTools->hasFocus() && gFocusMgr.getKeyboardFocus()) // Build tools is open, but not the focused floater, give it focus.
{
gFloaterTools->setFocus(true);
}
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);
gFloaterTools->close();
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.
static const LLCachedControl<bool> build_btn_state("BuildBtnState",false);
bool b=(inEdit()
&& build_btn_state
&& !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)
{
llwarns << "mBaseTool is NULL" << llendl;
}
}
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);
}
}
////////////////////////////////////////////////////////////////////////////