PageRenderTime 45ms CodeModel.GetById 2ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/lltoolmgr.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 477 lines | 343 code | 74 blank | 60 comment | 55 complexity | f2e259a98159174937e4d815515d3afe MD5 | raw file
  1/** 
  2 * @file lltoolmgr.cpp
  3 * @brief LLToolMgr class implementation
  4 *
  5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "lltoolmgr.h"
 30
 31#include "lluictrl.h"
 32#include "llmenugl.h"
 33#include "llfloaterreg.h"
 34
 35//#include "llfirstuse.h"
 36// tools and manipulators
 37#include "lltool.h"
 38#include "llmanipscale.h"
 39#include "llselectmgr.h"
 40#include "lltoolbrush.h"
 41#include "lltoolcomp.h"
 42#include "lltooldraganddrop.h"
 43#include "lltoolface.h"
 44#include "lltoolfocus.h"
 45#include "lltoolgrab.h"
 46#include "lltoolindividual.h"
 47#include "lltoolmorph.h"
 48#include "lltoolpie.h"
 49#include "lltoolselectland.h"
 50#include "lltoolobjpicker.h"
 51#include "lltoolpipette.h"
 52#include "llagent.h"
 53#include "llagentcamera.h"
 54#include "llviewercontrol.h"
 55#include "llviewerjoystick.h"
 56#include "llviewermenu.h"
 57#include "llviewerparcelmgr.h"
 58
 59
 60// Used when app not active to avoid processing hover.
 61LLTool*			gToolNull	= NULL;
 62
 63LLToolset*		gBasicToolset		= NULL;
 64LLToolset*		gCameraToolset		= NULL;
 65//LLToolset*		gLandToolset		= NULL;
 66LLToolset*		gMouselookToolset	= NULL;
 67LLToolset*		gFaceEditToolset	= NULL;
 68
 69/////////////////////////////////////////////////////
 70// LLToolMgr
 71
 72LLToolMgr::LLToolMgr()
 73	:
 74	mBaseTool(NULL), 
 75	mSavedTool(NULL),
 76	mTransientTool( NULL ),
 77	mOverrideTool( NULL ),
 78	mSelectedTool( NULL ),
 79	mCurrentToolset( NULL )
 80{
 81	// Not a panel, register these callbacks globally.
 82	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Active", boost::bind(&LLToolMgr::inEdit, this));
 83	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Enabled", boost::bind(&LLToolMgr::canEdit, this));
 84	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Build.Toggle", boost::bind(&LLToolMgr::toggleBuildMode, this));
 85	
 86	gToolNull = new LLTool(LLStringUtil::null);  // Does nothing
 87	setCurrentTool(gToolNull);
 88
 89	gBasicToolset		= new LLToolset();
 90	gCameraToolset		= new LLToolset();
 91//	gLandToolset		= new LLToolset();
 92	gMouselookToolset	= new LLToolset();
 93	gFaceEditToolset	= new LLToolset();
 94}
 95
 96void LLToolMgr::initTools()
 97{
 98	static BOOL initialized = FALSE;
 99	if(initialized)
100	{
101		return;
102	}
103	initialized = TRUE;
104	gBasicToolset->addTool( LLToolPie::getInstance() );
105	gBasicToolset->addTool( LLToolCamera::getInstance() );
106	gCameraToolset->addTool( LLToolCamera::getInstance() );
107	gBasicToolset->addTool( LLToolGrab::getInstance() );
108	gBasicToolset->addTool( LLToolCompTranslate::getInstance() );
109	gBasicToolset->addTool( LLToolCompCreate::getInstance() );
110	gBasicToolset->addTool( LLToolBrushLand::getInstance() );
111	gMouselookToolset->addTool( LLToolCompGun::getInstance() );
112	gBasicToolset->addTool( LLToolCompInspect::getInstance() );
113	gFaceEditToolset->addTool( LLToolCamera::getInstance() );
114
115	// On startup, use "select" tool
116	setCurrentToolset(gBasicToolset);
117
118	gBasicToolset->selectTool( LLToolPie::getInstance() );
119}
120
121LLToolMgr::~LLToolMgr()
122{
123	delete gBasicToolset;
124	gBasicToolset = NULL;
125
126	delete gMouselookToolset;
127	gMouselookToolset = NULL;
128
129	delete gFaceEditToolset;
130	gFaceEditToolset = NULL;
131
132	delete gCameraToolset;
133	gCameraToolset = NULL;
134	
135	delete gToolNull;
136	gToolNull = NULL;
137}
138
139BOOL LLToolMgr::usingTransientTool()
140{
141	return mTransientTool ? TRUE : FALSE;
142}
143
144void LLToolMgr::setCurrentToolset(LLToolset* current)
145{
146	if (!current) return;
147
148	// switching toolsets?
149	if (current != mCurrentToolset)
150	{
151		// deselect current tool
152		if (mSelectedTool)
153		{
154			mSelectedTool->handleDeselect();
155		}
156		mCurrentToolset = current;
157		// select first tool of new toolset only if toolset changed
158		mCurrentToolset->selectFirstTool();
159	}
160	// update current tool based on new toolset
161	setCurrentTool( mCurrentToolset->getSelectedTool() );
162}
163
164LLToolset* LLToolMgr::getCurrentToolset()
165{
166	return mCurrentToolset;
167}
168
169void LLToolMgr::setCurrentTool( LLTool* tool )
170{
171	if (mTransientTool)
172	{
173		mTransientTool = NULL;
174	}
175
176	mBaseTool = tool;
177	updateToolStatus();
178
179	mSavedTool = NULL;
180}
181
182LLTool* LLToolMgr::getCurrentTool()
183{
184	MASK override_mask = gKeyboard ? gKeyboard->currentMask(TRUE) : 0;
185
186	LLTool* cur_tool = NULL;
187	// always use transient tools if available
188	if (mTransientTool)
189	{
190		mOverrideTool = NULL;
191		cur_tool = mTransientTool;
192	}
193	// tools currently grabbing mouse input will stay active
194	else if (mSelectedTool && mSelectedTool->hasMouseCapture())
195	{
196		cur_tool = mSelectedTool;
197	}
198	else
199	{
200		mOverrideTool = mBaseTool ? mBaseTool->getOverrideTool(override_mask) : NULL;
201
202		// use override tool if available otherwise drop back to base tool
203		cur_tool = mOverrideTool ? mOverrideTool : mBaseTool;
204	}
205
206	LLTool* prev_tool = mSelectedTool;
207	// Set the selected tool to avoid infinite recursion
208	mSelectedTool = cur_tool;
209	
210	//update tool selection status
211	if (prev_tool != cur_tool)
212	{
213		if (prev_tool)
214		{
215			prev_tool->handleDeselect();
216		}
217		if (cur_tool)
218		{
219			cur_tool->handleSelect();
220		}
221	}
222
223	return mSelectedTool;
224}
225
226LLTool* LLToolMgr::getBaseTool()
227{
228	return mBaseTool;
229}
230
231void LLToolMgr::updateToolStatus()
232{
233	// call getcurrenttool() to calculate active tool and call handleSelect() and handleDeselect() immediately
234	// when active tool changes
235	getCurrentTool();
236}
237
238bool LLToolMgr::inEdit()
239{
240	return mBaseTool != LLToolPie::getInstance() && mBaseTool != gToolNull;
241}
242
243bool LLToolMgr::canEdit()
244{
245	return LLViewerParcelMgr::getInstance()->allowAgentBuild();
246}
247
248void LLToolMgr::toggleBuildMode()
249{
250	LLFloaterReg::toggleInstanceOrBringToFront("build");
251
252	bool build_visible = LLFloaterReg::instanceVisible("build");
253	if (build_visible)
254	{
255		ECameraMode camMode = gAgentCamera.getCameraMode();
256		if (CAMERA_MODE_MOUSELOOK == camMode ||	CAMERA_MODE_CUSTOMIZE_AVATAR == camMode)
257		{
258			// pull the user out of mouselook or appearance mode when entering build mode
259			handle_reset_view();
260		}
261
262		if (gSavedSettings.getBOOL("EditCameraMovement"))
263		{
264			// camera should be set
265			if (LLViewerJoystick::getInstance()->getOverrideCamera())
266			{
267				handle_toggle_flycam();
268			}
269
270			if (gAgentCamera.getFocusOnAvatar())
271			{
272				// zoom in if we're looking at the avatar
273				gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
274				gAgentCamera.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis()));
275				gAgentCamera.cameraZoomIn(0.666f);
276				gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
277			}
278		}
279
280
281		setCurrentToolset(gBasicToolset);
282		getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );
283
284		// Could be first use
285		//LLFirstUse::useBuild();
286
287		gAgentCamera.resetView(false);
288
289		// avoid spurious avatar movements
290		LLViewerJoystick::getInstance()->setNeedsReset();
291
292	}
293	else
294	{
295		if (gSavedSettings.getBOOL("EditCameraMovement"))
296		{
297			// just reset the view, will pull us out of edit mode
298			handle_reset_view();
299		}
300		else
301		{
302			// manually disable edit mode, but do not affect the camera
303			gAgentCamera.resetView(false);
304			LLFloaterReg::hideInstance("build");
305			gViewerWindow->showCursor();			
306		}
307		// avoid spurious avatar movements pulling out of edit mode
308		LLViewerJoystick::getInstance()->setNeedsReset();
309	}
310
311}
312
313bool LLToolMgr::inBuildMode()
314{
315	// when entering mouselook inEdit() immediately returns true before 
316	// cameraMouselook() actually starts returning true.  Also, appearance edit
317	// sets build mode to true, so let's exclude that.
318	bool b=(inEdit() 
319			&& !gAgentCamera.cameraMouselook()
320			&& mCurrentToolset != gFaceEditToolset);
321	
322	return b;
323}
324
325void LLToolMgr::setTransientTool(LLTool* tool)
326{
327	if (!tool)
328	{
329		clearTransientTool();
330	}
331	else
332	{
333		if (mTransientTool)
334		{
335			mTransientTool = NULL;
336		}
337
338		mTransientTool = tool;
339	}
340
341	updateToolStatus();
342}
343
344void LLToolMgr::clearTransientTool()
345{
346	if (mTransientTool)
347	{
348		mTransientTool = NULL;
349		if (!mBaseTool)
350		{
351			llwarns << "mBaseTool is NULL" << llendl;
352		}
353	}
354	updateToolStatus();
355}
356
357
358void LLToolMgr::onAppFocusLost()
359{
360	if (mSelectedTool)
361	{
362		mSelectedTool->handleDeselect();
363	}
364	updateToolStatus();
365}
366
367void LLToolMgr::onAppFocusGained()
368{
369	if (mSelectedTool)
370	{
371		mSelectedTool->handleSelect();
372	}
373	updateToolStatus();
374}
375
376void LLToolMgr::clearSavedTool()
377{
378	mSavedTool = NULL;
379}
380
381/////////////////////////////////////////////////////
382// LLToolset
383
384void LLToolset::addTool(LLTool* tool)
385{
386	mToolList.push_back( tool );
387	if( !mSelectedTool )
388	{
389		mSelectedTool = tool;
390	}
391}
392
393
394void LLToolset::selectTool(LLTool* tool)
395{
396	mSelectedTool = tool;
397	LLToolMgr::getInstance()->setCurrentTool( mSelectedTool );
398}
399
400
401void LLToolset::selectToolByIndex( S32 index )
402{
403	LLTool *tool = (index >= 0 && index < (S32)mToolList.size()) ? mToolList[index] : NULL;
404	if (tool)
405	{
406		mSelectedTool = tool;
407		LLToolMgr::getInstance()->setCurrentTool( tool );
408	}
409}
410
411BOOL LLToolset::isToolSelected( S32 index )
412{
413	LLTool *tool = (index >= 0 && index < (S32)mToolList.size()) ? mToolList[index] : NULL;
414	return (tool == mSelectedTool);
415}
416
417
418void LLToolset::selectFirstTool()
419{
420	mSelectedTool = (0 < mToolList.size()) ? mToolList[0] : NULL;
421	LLToolMgr::getInstance()->setCurrentTool( mSelectedTool );
422}
423
424
425void LLToolset::selectNextTool()
426{
427	LLTool* next = NULL;
428	for( tool_list_t::iterator iter = mToolList.begin();
429		 iter != mToolList.end(); )
430	{
431		LLTool* cur = *iter++;
432		if( cur == mSelectedTool && iter != mToolList.end() )
433		{
434			next = *iter;
435			break;
436		}
437	}
438
439	if( next )
440	{
441		mSelectedTool = next;
442		LLToolMgr::getInstance()->setCurrentTool( mSelectedTool );
443	}
444	else
445	{
446		selectFirstTool();
447	}
448}
449
450void LLToolset::selectPrevTool()
451{
452	LLTool* prev = NULL;
453	for( tool_list_t::reverse_iterator iter = mToolList.rbegin();
454		 iter != mToolList.rend(); )
455	{
456		LLTool* cur = *iter++;
457		if( cur == mSelectedTool && iter != mToolList.rend() )
458		{
459			prev = *iter;
460			break;
461		}
462	}
463
464	if( prev )
465	{
466		mSelectedTool = prev;
467		LLToolMgr::getInstance()->setCurrentTool( mSelectedTool );
468	}
469	else if (mToolList.size() > 0)
470	{
471		selectToolByIndex((S32)mToolList.size()-1);
472	}
473}
474
475////////////////////////////////////////////////////////////////////////////
476
477