Imported existing code
This commit is contained in:
883
indra/newview/lljoystickbutton.cpp
Normal file
883
indra/newview/lljoystickbutton.cpp
Normal file
@@ -0,0 +1,883 @@
|
||||
/**
|
||||
* @file lljoystickbutton.cpp
|
||||
* @brief LLJoystick 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 "lljoystickbutton.h"
|
||||
|
||||
// Library includes
|
||||
#include "llcoord.h"
|
||||
#include "indra_constants.h"
|
||||
#include "llrender.h"
|
||||
|
||||
// Project includes
|
||||
#include "llui.h"
|
||||
#include "llagent.h"
|
||||
#include "llviewerimage.h"
|
||||
#include "llviewerimagelist.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llmoveview.h"
|
||||
|
||||
#include "llglheaders.h"
|
||||
|
||||
static LLRegisterWidget<LLJoystickAgentSlide> r1("joystick_slide");
|
||||
static LLRegisterWidget<LLJoystickAgentTurn> r2("joystick_turn");
|
||||
|
||||
|
||||
const F32 NUDGE_TIME = 0.25f; // in seconds
|
||||
const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed
|
||||
|
||||
//
|
||||
// Public Methods
|
||||
//
|
||||
LLJoystick::LLJoystick(
|
||||
const std::string& name,
|
||||
LLRect rect,
|
||||
const std::string &default_image,
|
||||
const std::string &selected_image,
|
||||
EJoystickQuadrant initial_quadrant )
|
||||
:
|
||||
LLButton(name, rect, default_image, selected_image, LLStringUtil::null, NULL, NULL),
|
||||
mInitialQuadrant(initial_quadrant),
|
||||
mInitialOffset(0, 0),
|
||||
mLastMouse(0, 0),
|
||||
mFirstMouse(0, 0),
|
||||
mVertSlopNear(0),
|
||||
mVertSlopFar(0),
|
||||
mHorizSlopNear(0),
|
||||
mHorizSlopFar(0),
|
||||
mHeldDown(FALSE),
|
||||
mHeldDownTimer()
|
||||
{
|
||||
setHeldDownCallback(&LLJoystick::onHeldDown);
|
||||
setCallbackUserData(this);
|
||||
}
|
||||
|
||||
|
||||
void LLJoystick::updateSlop()
|
||||
{
|
||||
mVertSlopNear = getRect().getHeight();
|
||||
mVertSlopFar = getRect().getHeight() * 2;
|
||||
|
||||
mHorizSlopNear = getRect().getWidth();
|
||||
mHorizSlopFar = getRect().getWidth() * 2;
|
||||
|
||||
// Compute initial mouse offset based on initial quadrant.
|
||||
// Place the mouse evenly between the near and far zones.
|
||||
switch (mInitialQuadrant)
|
||||
{
|
||||
case JQ_ORIGIN:
|
||||
mInitialOffset.set(0, 0);
|
||||
break;
|
||||
|
||||
case JQ_UP:
|
||||
mInitialOffset.mX = 0;
|
||||
mInitialOffset.mY = (mVertSlopNear + mVertSlopFar) / 2;
|
||||
break;
|
||||
|
||||
case JQ_DOWN:
|
||||
mInitialOffset.mX = 0;
|
||||
mInitialOffset.mY = - (mVertSlopNear + mVertSlopFar) / 2;
|
||||
break;
|
||||
|
||||
case JQ_LEFT:
|
||||
mInitialOffset.mX = - (mHorizSlopNear + mHorizSlopFar) / 2;
|
||||
mInitialOffset.mY = 0;
|
||||
break;
|
||||
|
||||
case JQ_RIGHT:
|
||||
mInitialOffset.mX = (mHorizSlopNear + mHorizSlopFar) / 2;
|
||||
mInitialOffset.mY = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
llerrs << "LLJoystick::LLJoystick() - bad switch case" << llendl;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLJoystick::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
//llinfos << "joystick mouse down " << x << ", " << y << llendl;
|
||||
|
||||
mLastMouse.set(x, y);
|
||||
mFirstMouse.set(x, y);
|
||||
|
||||
mMouseDownTimer.reset();
|
||||
return LLButton::handleMouseDown(x, y, mask);
|
||||
}
|
||||
|
||||
|
||||
BOOL LLJoystick::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
// llinfos << "joystick mouse up " << x << ", " << y << llendl;
|
||||
|
||||
if( hasMouseCapture() )
|
||||
{
|
||||
mLastMouse.set(x, y);
|
||||
mHeldDown = FALSE;
|
||||
onMouseUp();
|
||||
}
|
||||
|
||||
return LLButton::handleMouseUp(x, y, mask);
|
||||
}
|
||||
|
||||
|
||||
BOOL LLJoystick::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if( hasMouseCapture() )
|
||||
{
|
||||
mLastMouse.set(x, y);
|
||||
}
|
||||
|
||||
return LLButton::handleHover(x, y, mask);
|
||||
}
|
||||
|
||||
F32 LLJoystick::getElapsedHeldDownTime()
|
||||
{
|
||||
if( mHeldDown )
|
||||
{
|
||||
return getHeldDownTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLJoystick::onHeldDown(void *userdata)
|
||||
{
|
||||
LLJoystick *self = (LLJoystick *)userdata;
|
||||
|
||||
// somebody removed this function without checking the
|
||||
// build. Removed 2007-03-26.
|
||||
//llassert( gViewerWindow->hasMouseCapture( self ) );
|
||||
|
||||
self->mHeldDown = TRUE;
|
||||
self->onHeldDown();
|
||||
}
|
||||
|
||||
EJoystickQuadrant LLJoystick::selectQuadrant(LLXMLNodePtr node)
|
||||
{
|
||||
|
||||
EJoystickQuadrant quadrant = JQ_RIGHT;
|
||||
|
||||
if (node->hasAttribute("quadrant"))
|
||||
{
|
||||
std::string quadrant_name;
|
||||
node->getAttributeString("quadrant", quadrant_name);
|
||||
|
||||
quadrant = quadrantFromName(quadrant_name);
|
||||
}
|
||||
return quadrant;
|
||||
}
|
||||
|
||||
|
||||
std::string LLJoystick::nameFromQuadrant(EJoystickQuadrant quadrant)
|
||||
{
|
||||
if (quadrant == JQ_ORIGIN) return std::string("origin");
|
||||
else if (quadrant == JQ_UP) return std::string("up");
|
||||
else if (quadrant == JQ_DOWN) return std::string("down");
|
||||
else if (quadrant == JQ_LEFT) return std::string("left");
|
||||
else if (quadrant == JQ_RIGHT) return std::string("right");
|
||||
else return std::string();
|
||||
}
|
||||
|
||||
|
||||
EJoystickQuadrant LLJoystick::quadrantFromName(const std::string& sQuadrant)
|
||||
{
|
||||
EJoystickQuadrant quadrant = JQ_RIGHT;
|
||||
|
||||
if (sQuadrant == "origin")
|
||||
{
|
||||
quadrant = JQ_ORIGIN;
|
||||
}
|
||||
else if (sQuadrant == "up")
|
||||
{
|
||||
quadrant = JQ_UP;
|
||||
}
|
||||
else if (sQuadrant == "down")
|
||||
{
|
||||
quadrant = JQ_DOWN;
|
||||
}
|
||||
else if (sQuadrant == "left")
|
||||
{
|
||||
quadrant = JQ_LEFT;
|
||||
}
|
||||
else if (sQuadrant == "right")
|
||||
{
|
||||
quadrant = JQ_RIGHT;
|
||||
}
|
||||
|
||||
return quadrant;
|
||||
}
|
||||
|
||||
|
||||
LLXMLNodePtr LLJoystick::getXML(bool save_children) const
|
||||
{
|
||||
LLXMLNodePtr node = LLButton::getXML();
|
||||
|
||||
node->createChild("quadrant", TRUE)->setStringValue(nameFromQuadrant(mInitialQuadrant));
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// LLJoystickAgentTurn
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
void LLJoystickAgentTurn::onHeldDown()
|
||||
{
|
||||
F32 time = getElapsedHeldDownTime();
|
||||
updateSlop();
|
||||
|
||||
//llinfos << "move forward/backward (and/or turn)" << llendl;
|
||||
|
||||
S32 dx = mLastMouse.mX - mFirstMouse.mX + mInitialOffset.mX;
|
||||
S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY;
|
||||
|
||||
float m = (float) (dx)/abs(dy);
|
||||
|
||||
if (m > 1) {
|
||||
m = 1;
|
||||
}
|
||||
else if (m < -1) {
|
||||
m = -1;
|
||||
}
|
||||
gAgent.moveYaw(-LLFloaterMove::getYawRate(time)*m);
|
||||
|
||||
|
||||
// handle forward/back movement
|
||||
if (dy > mVertSlopFar)
|
||||
{
|
||||
// ...if mouse is forward of run region run forward
|
||||
gAgent.moveAt(1);
|
||||
}
|
||||
else if (dy > mVertSlopNear)
|
||||
{
|
||||
if( time < NUDGE_TIME )
|
||||
{
|
||||
gAgent.moveAtNudge(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...else if mouse is forward of walk region walk forward
|
||||
// JC 9/5/2002 - Always run / move quickly.
|
||||
gAgent.moveAt(1);
|
||||
}
|
||||
}
|
||||
else if (dy < -mVertSlopFar)
|
||||
{
|
||||
// ...else if mouse is behind run region run backward
|
||||
gAgent.moveAt(-1);
|
||||
}
|
||||
else if (dy < -mVertSlopNear)
|
||||
{
|
||||
if( time < NUDGE_TIME )
|
||||
{
|
||||
gAgent.moveAtNudge(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...else if mouse is behind walk region walk backward
|
||||
// JC 9/5/2002 - Always run / move quickly.
|
||||
gAgent.moveAt(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLXMLNodePtr LLJoystickAgentTurn::getXML(bool save_children) const
|
||||
{
|
||||
LLXMLNodePtr node = LLJoystick::getXML();
|
||||
|
||||
node->setName(LL_JOYSTICK_TURN);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
LLView* LLJoystickAgentTurn::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
|
||||
{
|
||||
std::string name("button");
|
||||
node->getAttributeString("name", name);
|
||||
|
||||
std::string image_unselected;
|
||||
if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected);
|
||||
|
||||
std::string image_selected;
|
||||
if (node->hasAttribute("image_selected")) node->getAttributeString("image_selected",image_selected);
|
||||
|
||||
EJoystickQuadrant quad = JQ_ORIGIN;
|
||||
if (node->hasAttribute("quadrant")) quad = selectQuadrant(node);
|
||||
|
||||
LLJoystickAgentTurn *button = new LLJoystickAgentTurn(name,
|
||||
LLRect(),
|
||||
image_unselected,
|
||||
image_selected,
|
||||
quad);
|
||||
|
||||
if (node->hasAttribute("halign"))
|
||||
{
|
||||
LLFontGL::HAlign halign = selectFontHAlign(node);
|
||||
button->setHAlign(halign);
|
||||
}
|
||||
|
||||
if (node->hasAttribute("scale_image"))
|
||||
{
|
||||
BOOL needsScale = FALSE;
|
||||
node->getAttributeBOOL("scale_image",needsScale);
|
||||
button->setScaleImage( needsScale );
|
||||
}
|
||||
|
||||
button->initFromXML(node, parent);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// LLJoystickAgentSlide
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
void LLJoystickAgentSlide::onMouseUp()
|
||||
{
|
||||
F32 time = getElapsedHeldDownTime();
|
||||
if( time < NUDGE_TIME )
|
||||
{
|
||||
switch (mInitialQuadrant)
|
||||
{
|
||||
case JQ_LEFT:
|
||||
gAgent.moveLeftNudge(1);
|
||||
break;
|
||||
|
||||
case JQ_RIGHT:
|
||||
gAgent.moveLeftNudge(-1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLJoystickAgentSlide::onHeldDown()
|
||||
{
|
||||
//llinfos << "slide left/right (and/or move forward/backward)" << llendl;
|
||||
|
||||
updateSlop();
|
||||
|
||||
S32 dx = mLastMouse.mX - mFirstMouse.mX + mInitialOffset.mX;
|
||||
S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY;
|
||||
|
||||
// handle left-right sliding
|
||||
if (dx > mHorizSlopNear)
|
||||
{
|
||||
gAgent.moveLeft(-1);
|
||||
}
|
||||
else if (dx < -mHorizSlopNear)
|
||||
{
|
||||
gAgent.moveLeft(1);
|
||||
}
|
||||
|
||||
// handle forward/back movement
|
||||
if (dy > mVertSlopFar)
|
||||
{
|
||||
// ...if mouse is forward of run region run forward
|
||||
gAgent.moveAt(1);
|
||||
}
|
||||
else if (dy > mVertSlopNear)
|
||||
{
|
||||
// ...else if mouse is forward of walk region walk forward
|
||||
gAgent.moveAtNudge(1);
|
||||
}
|
||||
else if (dy < -mVertSlopFar)
|
||||
{
|
||||
// ...else if mouse is behind run region run backward
|
||||
gAgent.moveAt(-1);
|
||||
}
|
||||
else if (dy < -mVertSlopNear)
|
||||
{
|
||||
// ...else if mouse is behind walk region walk backward
|
||||
gAgent.moveAtNudge(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LLXMLNodePtr LLJoystickAgentSlide::getXML(bool save_children) const
|
||||
{
|
||||
LLXMLNodePtr node = LLJoystick::getXML();
|
||||
|
||||
node->setName(LL_JOYSTICK_SLIDE);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// static
|
||||
LLView* LLJoystickAgentSlide::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
|
||||
{
|
||||
std::string name("button");
|
||||
node->getAttributeString("name", name);
|
||||
|
||||
std::string image_unselected;
|
||||
if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected);
|
||||
|
||||
std::string image_selected;
|
||||
if (node->hasAttribute("image_selected")) node->getAttributeString("image_selected",image_selected);
|
||||
|
||||
|
||||
EJoystickQuadrant quad = JQ_ORIGIN;
|
||||
if (node->hasAttribute("quadrant")) quad = selectQuadrant(node);
|
||||
|
||||
LLJoystickAgentSlide *button = new LLJoystickAgentSlide(name,
|
||||
LLRect(),
|
||||
image_unselected,
|
||||
image_selected,
|
||||
quad);
|
||||
|
||||
if (node->hasAttribute("halign"))
|
||||
{
|
||||
LLFontGL::HAlign halign = selectFontHAlign(node);
|
||||
button->setHAlign(halign);
|
||||
}
|
||||
|
||||
if (node->hasAttribute("scale_image"))
|
||||
{
|
||||
BOOL needsScale = FALSE;
|
||||
node->getAttributeBOOL("scale_image",needsScale);
|
||||
button->setScaleImage( needsScale );
|
||||
}
|
||||
|
||||
button->initFromXML(node, parent);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// LLJoystickCameraRotate
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
LLJoystickCameraRotate::LLJoystickCameraRotate(const std::string& name, LLRect rect, const std::string &out_img, const std::string &in_img)
|
||||
:
|
||||
LLJoystick(name, rect, out_img, in_img, JQ_ORIGIN),
|
||||
mInLeft( FALSE ),
|
||||
mInTop( FALSE ),
|
||||
mInRight( FALSE ),
|
||||
mInBottom( FALSE )
|
||||
{ }
|
||||
|
||||
|
||||
void LLJoystickCameraRotate::updateSlop()
|
||||
{
|
||||
// do the initial offset calculation based on mousedown location
|
||||
|
||||
// small fixed slop region
|
||||
mVertSlopNear = 16;
|
||||
mVertSlopFar = 32;
|
||||
|
||||
mHorizSlopNear = 16;
|
||||
mHorizSlopFar = 32;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLJoystickCameraRotate::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
updateSlop();
|
||||
|
||||
// Set initial offset based on initial click location
|
||||
S32 horiz_center = getRect().getWidth() / 2;
|
||||
S32 vert_center = getRect().getHeight() / 2;
|
||||
|
||||
S32 dx = x - horiz_center;
|
||||
S32 dy = y - vert_center;
|
||||
|
||||
if (dy > dx && dy > -dx)
|
||||
{
|
||||
// top
|
||||
mInitialOffset.mX = 0;
|
||||
mInitialOffset.mY = (mVertSlopNear + mVertSlopFar) / 2;
|
||||
mInitialQuadrant = JQ_UP;
|
||||
}
|
||||
else if (dy > dx && dy <= -dx)
|
||||
{
|
||||
// left
|
||||
mInitialOffset.mX = - (mHorizSlopNear + mHorizSlopFar) / 2;
|
||||
mInitialOffset.mY = 0;
|
||||
mInitialQuadrant = JQ_LEFT;
|
||||
}
|
||||
else if (dy <= dx && dy <= -dx)
|
||||
{
|
||||
// bottom
|
||||
mInitialOffset.mX = 0;
|
||||
mInitialOffset.mY = - (mVertSlopNear + mVertSlopFar) / 2;
|
||||
mInitialQuadrant = JQ_DOWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
// right
|
||||
mInitialOffset.mX = (mHorizSlopNear + mHorizSlopFar) / 2;
|
||||
mInitialOffset.mY = 0;
|
||||
mInitialQuadrant = JQ_RIGHT;
|
||||
}
|
||||
|
||||
return LLJoystick::handleMouseDown(x, y, mask);
|
||||
}
|
||||
|
||||
|
||||
void LLJoystickCameraRotate::onHeldDown()
|
||||
{
|
||||
updateSlop();
|
||||
|
||||
S32 dx = mLastMouse.mX - mFirstMouse.mX + mInitialOffset.mX;
|
||||
S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY;
|
||||
|
||||
// left-right rotation
|
||||
if (dx > mHorizSlopNear)
|
||||
{
|
||||
gAgent.unlockView();
|
||||
gAgent.setOrbitLeftKey(getOrbitRate());
|
||||
}
|
||||
else if (dx < -mHorizSlopNear)
|
||||
{
|
||||
gAgent.unlockView();
|
||||
gAgent.setOrbitRightKey(getOrbitRate());
|
||||
}
|
||||
|
||||
// over/under rotation
|
||||
if (dy > mVertSlopNear)
|
||||
{
|
||||
gAgent.unlockView();
|
||||
gAgent.setOrbitUpKey(getOrbitRate());
|
||||
}
|
||||
else if (dy < -mVertSlopNear)
|
||||
{
|
||||
gAgent.unlockView();
|
||||
gAgent.setOrbitDownKey(getOrbitRate());
|
||||
}
|
||||
}
|
||||
|
||||
F32 LLJoystickCameraRotate::getOrbitRate()
|
||||
{
|
||||
F32 time = getElapsedHeldDownTime();
|
||||
if( time < NUDGE_TIME )
|
||||
{
|
||||
F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME;
|
||||
//llinfos << rate << llendl;
|
||||
return rate;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Only used for drawing
|
||||
void LLJoystickCameraRotate::setToggleState( BOOL left, BOOL top, BOOL right, BOOL bottom )
|
||||
{
|
||||
mInLeft = left;
|
||||
mInTop = top;
|
||||
mInRight = right;
|
||||
mInBottom = bottom;
|
||||
}
|
||||
|
||||
void LLJoystickCameraRotate::draw()
|
||||
{
|
||||
LLGLSUIDefault gls_ui;
|
||||
|
||||
getImageUnselected()->draw( 0, 0 );
|
||||
|
||||
if( mInTop )
|
||||
{
|
||||
drawRotatedImage( getImageSelected()->getImage(), 0 );
|
||||
}
|
||||
|
||||
if( mInRight )
|
||||
{
|
||||
drawRotatedImage( getImageSelected()->getImage(), 1 );
|
||||
}
|
||||
|
||||
if( mInBottom )
|
||||
{
|
||||
drawRotatedImage( getImageSelected()->getImage(), 2 );
|
||||
}
|
||||
|
||||
if( mInLeft )
|
||||
{
|
||||
drawRotatedImage( getImageSelected()->getImage(), 3 );
|
||||
}
|
||||
|
||||
if (sDebugRects)
|
||||
{
|
||||
drawDebugRect();
|
||||
}
|
||||
}
|
||||
|
||||
// Draws image rotated by multiples of 90 degrees
|
||||
void LLJoystickCameraRotate::drawRotatedImage( LLImageGL* image, S32 rotations )
|
||||
{
|
||||
S32 width = image->getWidth();
|
||||
S32 height = image->getHeight();
|
||||
|
||||
F32 uv[][2] =
|
||||
{
|
||||
{ 1.f, 1.f },
|
||||
{ 0.f, 1.f },
|
||||
{ 0.f, 0.f },
|
||||
{ 1.f, 0.f }
|
||||
};
|
||||
|
||||
gGL.getTexUnit(0)->bind(image);
|
||||
|
||||
gGL.color4fv(UI_VERTEX_COLOR.mV);
|
||||
|
||||
gGL.begin(LLRender::QUADS);
|
||||
{
|
||||
gGL.texCoord2fv( uv[ (rotations + 0) % 4]);
|
||||
gGL.vertex2i(width, height );
|
||||
|
||||
gGL.texCoord2fv( uv[ (rotations + 1) % 4]);
|
||||
gGL.vertex2i(0, height );
|
||||
|
||||
gGL.texCoord2fv( uv[ (rotations + 2) % 4]);
|
||||
gGL.vertex2i(0, 0);
|
||||
|
||||
gGL.texCoord2fv( uv[ (rotations + 3) % 4]);
|
||||
gGL.vertex2i(width, 0);
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// LLJoystickCameraTrack
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
void LLJoystickCameraTrack::onHeldDown()
|
||||
{
|
||||
updateSlop();
|
||||
|
||||
S32 dx = mLastMouse.mX - mFirstMouse.mX + mInitialOffset.mX;
|
||||
S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY;
|
||||
|
||||
if (dx > mVertSlopNear)
|
||||
{
|
||||
gAgent.unlockView();
|
||||
gAgent.setPanRightKey(getOrbitRate());
|
||||
}
|
||||
else if (dx < -mVertSlopNear)
|
||||
{
|
||||
gAgent.unlockView();
|
||||
gAgent.setPanLeftKey(getOrbitRate());
|
||||
}
|
||||
|
||||
// over/under rotation
|
||||
if (dy > mVertSlopNear)
|
||||
{
|
||||
gAgent.unlockView();
|
||||
gAgent.setPanUpKey(getOrbitRate());
|
||||
}
|
||||
else if (dy < -mVertSlopNear)
|
||||
{
|
||||
gAgent.unlockView();
|
||||
gAgent.setPanDownKey(getOrbitRate());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// LLJoystickCameraZoom
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
LLJoystickCameraZoom::LLJoystickCameraZoom(const std::string& name, LLRect rect, const std::string &out_img, const std::string &plus_in_img, const std::string &minus_in_img)
|
||||
:
|
||||
LLJoystick(name, rect, out_img, LLStringUtil::null, JQ_ORIGIN),
|
||||
mInTop( FALSE ),
|
||||
mInBottom( FALSE )
|
||||
{
|
||||
mPlusInImage = LLUIImageList::getInstance()->getUIImage(plus_in_img);
|
||||
mMinusInImage = LLUIImageList::getInstance()->getUIImage(minus_in_img);
|
||||
}
|
||||
|
||||
|
||||
BOOL LLJoystickCameraZoom::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
BOOL handled = LLJoystick::handleMouseDown(x, y, mask);
|
||||
|
||||
if( handled )
|
||||
{
|
||||
if (mFirstMouse.mY > getRect().getHeight() / 2)
|
||||
{
|
||||
mInitialQuadrant = JQ_UP;
|
||||
}
|
||||
else
|
||||
{
|
||||
mInitialQuadrant = JQ_DOWN;
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
||||
void LLJoystickCameraZoom::onHeldDown()
|
||||
{
|
||||
updateSlop();
|
||||
|
||||
const F32 FAST_RATE = 2.5f; // two and a half times the normal rate
|
||||
|
||||
S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY;
|
||||
|
||||
if (dy > mVertSlopFar)
|
||||
{
|
||||
// Zoom in fast
|
||||
gAgent.unlockView();
|
||||
gAgent.setOrbitInKey(FAST_RATE);
|
||||
}
|
||||
else if (dy > mVertSlopNear)
|
||||
{
|
||||
// Zoom in slow
|
||||
gAgent.unlockView();
|
||||
gAgent.setOrbitInKey(getOrbitRate());
|
||||
}
|
||||
else if (dy < -mVertSlopFar)
|
||||
{
|
||||
// Zoom out fast
|
||||
gAgent.unlockView();
|
||||
gAgent.setOrbitOutKey(FAST_RATE);
|
||||
}
|
||||
else if (dy < -mVertSlopNear)
|
||||
{
|
||||
// Zoom out slow
|
||||
gAgent.unlockView();
|
||||
gAgent.setOrbitOutKey(getOrbitRate());
|
||||
}
|
||||
}
|
||||
|
||||
// Only used for drawing
|
||||
void LLJoystickCameraZoom::setToggleState( BOOL top, BOOL bottom )
|
||||
{
|
||||
mInTop = top;
|
||||
mInBottom = bottom;
|
||||
}
|
||||
|
||||
void LLJoystickCameraZoom::draw()
|
||||
{
|
||||
if( mInTop )
|
||||
{
|
||||
mPlusInImage->draw(0,0);
|
||||
}
|
||||
else
|
||||
if( mInBottom )
|
||||
{
|
||||
mMinusInImage->draw(0,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
getImageUnselected()->draw( 0, 0 );
|
||||
}
|
||||
|
||||
if (sDebugRects)
|
||||
{
|
||||
drawDebugRect();
|
||||
}
|
||||
}
|
||||
|
||||
void LLJoystickCameraZoom::updateSlop()
|
||||
{
|
||||
mVertSlopNear = getRect().getHeight() / 4;
|
||||
mVertSlopFar = getRect().getHeight() / 2;
|
||||
|
||||
mHorizSlopNear = getRect().getWidth() / 4;
|
||||
mHorizSlopFar = getRect().getWidth() / 2;
|
||||
|
||||
// Compute initial mouse offset based on initial quadrant.
|
||||
// Place the mouse evenly between the near and far zones.
|
||||
switch (mInitialQuadrant)
|
||||
{
|
||||
case JQ_ORIGIN:
|
||||
mInitialOffset.set(0, 0);
|
||||
break;
|
||||
|
||||
case JQ_UP:
|
||||
mInitialOffset.mX = 0;
|
||||
mInitialOffset.mY = (mVertSlopNear + mVertSlopFar) / 2;
|
||||
break;
|
||||
|
||||
case JQ_DOWN:
|
||||
mInitialOffset.mX = 0;
|
||||
mInitialOffset.mY = - (mVertSlopNear + mVertSlopFar) / 2;
|
||||
break;
|
||||
|
||||
case JQ_LEFT:
|
||||
mInitialOffset.mX = - (mHorizSlopNear + mHorizSlopFar) / 2;
|
||||
mInitialOffset.mY = 0;
|
||||
break;
|
||||
|
||||
case JQ_RIGHT:
|
||||
mInitialOffset.mX = (mHorizSlopNear + mHorizSlopFar) / 2;
|
||||
mInitialOffset.mY = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
llerrs << "LLJoystick::LLJoystick() - bad switch case" << llendl;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
F32 LLJoystickCameraZoom::getOrbitRate()
|
||||
{
|
||||
F32 time = getElapsedHeldDownTime();
|
||||
if( time < NUDGE_TIME )
|
||||
{
|
||||
F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME;
|
||||
// llinfos << "rate " << rate << " time " << time << llendl;
|
||||
return rate;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user