diff options
Diffstat (limited to 'indra/newview/lljoystickbutton.cpp')
-rw-r--r-- | indra/newview/lljoystickbutton.cpp | 507 |
1 files changed, 138 insertions, 369 deletions
diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp index 0027036b36..3d1f186bba 100644 --- a/indra/newview/lljoystickbutton.cpp +++ b/indra/newview/lljoystickbutton.cpp @@ -2,30 +2,25 @@ * @file lljoystickbutton.cpp * @brief LLJoystick class implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * 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://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * 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://secondlife.com/developers/opensource/flossexception + * 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. * - * 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. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -36,33 +31,44 @@ // Library includes #include "llcoord.h" #include "indra_constants.h" -#include "llglimmediate.h" +#include "llrender.h" // Project includes #include "llui.h" #include "llagent.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llagentcamera.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llmoveview.h" #include "llglheaders.h" +static LLDefaultChildRegistry::Register<LLJoystickAgentSlide> r1("joystick_slide"); +static LLDefaultChildRegistry::Register<LLJoystickAgentTurn> r2("joystick_turn"); +static LLDefaultChildRegistry::Register<LLJoystickCameraRotate> r3("joystick_rotate"); +static LLDefaultChildRegistry::Register<LLJoystickCameraTrack> r5("joystick_track"); + + + const F32 NUDGE_TIME = 0.25f; // in seconds const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed // // Public Methods // -LLJoystick::LLJoystick( - const LLString& name, - LLRect rect, - const LLString &default_image, - const LLString &selected_image, - EJoystickQuadrant initial_quadrant ) - : - LLButton(name, rect, default_image, selected_image, NULL, NULL), - mInitialQuadrant(initial_quadrant), +void QuadrantNames::declareValues() +{ + declare("origin", JQ_ORIGIN); + declare("up", JQ_UP); + declare("down", JQ_DOWN); + declare("left", JQ_LEFT); + declare("right", JQ_RIGHT); +} + + +LLJoystick::LLJoystick(const LLJoystick::Params& p) +: LLButton(p), mInitialOffset(0, 0), mLastMouse(0, 0), mFirstMouse(0, 0), @@ -71,10 +77,10 @@ LLJoystick::LLJoystick( mHorizSlopNear(0), mHorizSlopFar(0), mHeldDown(FALSE), - mHeldDownTimer() + mHeldDownTimer(), + mInitialQuadrant(p.quadrant) { - setHeldDownCallback(&LLJoystick::onHeldDown); - setCallbackUserData(this); + setHeldDownCallback(&LLJoystick::onBtnHeldDown, this); } @@ -122,16 +128,33 @@ void LLJoystick::updateSlop() return; } +bool LLJoystick::pointInCircle(S32 x, S32 y) const +{ + if(this->getLocalRect().getHeight() != this->getLocalRect().getWidth()) + { + llwarns << "Joystick shape is not square"<<llendl; + return true; + } + //center is x and y coordinates of center of joystick circle, and also its radius + int center = this->getLocalRect().getHeight()/2; + bool in_circle = (x - center) * (x - center) + (y - center) * (y - center) <= center * center; + return in_circle; +} BOOL LLJoystick::handleMouseDown(S32 x, S32 y, MASK mask) { //llinfos << "joystick mouse down " << x << ", " << y << llendl; + bool handles = false; - mLastMouse.set(x, y); - mFirstMouse.set(x, y); + if(pointInCircle(x, y)) + { + mLastMouse.set(x, y); + mFirstMouse.set(x, y); + mMouseDownTimer.reset(); + handles = LLButton::handleMouseDown(x, y, mask); + } - mMouseDownTimer.reset(); - return LLButton::handleMouseDown(x, y, mask); + return handles; } @@ -173,16 +196,14 @@ F32 LLJoystick::getElapsedHeldDownTime() } // static -void LLJoystick::onHeldDown(void *userdata) +void LLJoystick::onBtnHeldDown(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(); + if (self) + { + self->mHeldDown = TRUE; + self->onHeldDown(); + } } EJoystickQuadrant LLJoystick::selectQuadrant(LLXMLNodePtr node) @@ -192,27 +213,27 @@ EJoystickQuadrant LLJoystick::selectQuadrant(LLXMLNodePtr node) if (node->hasAttribute("quadrant")) { - LLString quadrant_name; + std::string quadrant_name; node->getAttributeString("quadrant", quadrant_name); - quadrant = quadrantFromName(quadrant_name.c_str()); + quadrant = quadrantFromName(quadrant_name); } return quadrant; } -LLString LLJoystick::nameFromQuadrant(EJoystickQuadrant quadrant) +std::string LLJoystick::nameFromQuadrant(EJoystickQuadrant quadrant) { - if (quadrant == JQ_ORIGIN) return LLString("origin"); - else if (quadrant == JQ_UP) return LLString("up"); - else if (quadrant == JQ_DOWN) return LLString("down"); - else if (quadrant == JQ_LEFT) return LLString("left"); - else if (quadrant == JQ_RIGHT) return LLString("right"); - else return LLString(); + 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 LLString& sQuadrant) +EJoystickQuadrant LLJoystick::quadrantFromName(const std::string& sQuadrant) { EJoystickQuadrant quadrant = JQ_RIGHT; @@ -241,23 +262,6 @@ EJoystickQuadrant LLJoystick::quadrantFromName(const LLString& sQuadrant) } -LLXMLNodePtr LLJoystick::getXML(bool save_children) const -{ - LLXMLNodePtr node = LLUICtrl::getXML(); - - node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(getHAlign())); - node->createChild("quadrant", TRUE)->setStringValue(nameFromQuadrant(mInitialQuadrant)); - - addImageAttributeToXML(node,getImageUnselectedName(),getImageUnselectedID(),"image_unselected"); - addImageAttributeToXML(node,getImageSelectedName(),getImageSelectedID(),"image_selected"); - - node->createChild("scale_image", TRUE)->setBoolValue(getScaleImage()); - - return node; -} - - - //------------------------------------------------------------------------------- // LLJoystickAgentTurn //------------------------------------------------------------------------------- @@ -322,46 +326,6 @@ void LLJoystickAgentTurn::onHeldDown() } } -LLView* LLJoystickAgentTurn::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) -{ - LLString name("button"); - node->getAttributeString("name", name); - - LLString image_unselected; - if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected); - - LLString 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 //------------------------------------------------------------------------------- @@ -430,54 +394,12 @@ void LLJoystickAgentSlide::onHeldDown() } -// static -LLView* LLJoystickAgentSlide::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) -{ - LLString name("button"); - node->getAttributeString("name", name); - - LLString image_unselected; - if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected); - - LLString 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 LLString& name, LLRect rect, const LLString &out_img, const LLString &in_img) - : - LLJoystick(name, rect, out_img, in_img, JQ_ORIGIN), +LLJoystickCameraRotate::LLJoystickCameraRotate(const LLJoystickCameraRotate::Params& p) +: LLJoystick(p), mInLeft( FALSE ), mInTop( FALSE ), mInRight( FALSE ), @@ -554,25 +476,25 @@ void LLJoystickCameraRotate::onHeldDown() // left-right rotation if (dx > mHorizSlopNear) { - gAgent.unlockView(); - gAgent.setOrbitLeftKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitLeftKey(getOrbitRate()); } else if (dx < -mHorizSlopNear) { - gAgent.unlockView(); - gAgent.setOrbitRightKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitRightKey(getOrbitRate()); } // over/under rotation if (dy > mVertSlopNear) { - gAgent.unlockView(); - gAgent.setOrbitUpKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitUpKey(getOrbitRate()); } else if (dy < -mVertSlopNear) { - gAgent.unlockView(); - gAgent.setOrbitDownKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitDownKey(getOrbitRate()); } } @@ -603,59 +525,59 @@ void LLJoystickCameraRotate::setToggleState( BOOL left, BOOL top, BOOL right, BO void LLJoystickCameraRotate::draw() { - - if( getVisible() ) - { - LLGLSUIDefault gls_ui; - - getImageUnselected()->draw( 0, 0 ); + LLGLSUIDefault gls_ui; - if( mInTop ) - { - drawRotatedImage( getImageSelected()->getImage(), 0 ); - } + getImageUnselected()->draw( 0, 0 ); + LLPointer<LLUIImage> image = getImageSelected(); - if( mInRight ) - { - drawRotatedImage( getImageSelected()->getImage(), 1 ); - } + if( mInTop ) + { + drawRotatedImage( getImageSelected(), 0 ); + } - if( mInBottom ) - { - drawRotatedImage( getImageSelected()->getImage(), 2 ); - } + if( mInRight ) + { + drawRotatedImage( getImageSelected(), 1 ); + } - if( mInLeft ) - { - drawRotatedImage( getImageSelected()->getImage(), 3 ); - } + if( mInBottom ) + { + drawRotatedImage( getImageSelected(), 2 ); + } - if (sDebugRects) - { - drawDebugRect(); - } + if( mInLeft ) + { + drawRotatedImage( getImageSelected(), 3 ); } } // Draws image rotated by multiples of 90 degrees -void LLJoystickCameraRotate::drawRotatedImage( const LLImageGL* image, S32 rotations ) +void LLJoystickCameraRotate::drawRotatedImage( LLPointer<LLUIImage> image, S32 rotations ) { S32 width = image->getWidth(); S32 height = image->getHeight(); - + LLTexture* texture = image->getImage(); + + /* + * Scale texture coordinate system + * to handle the different between image size and size of texture. + * If we will use default matrix, + * it may break texture mapping after rotation. + * see EXT-2023 Camera floater: arrows became shifted when pressed. + */ F32 uv[][2] = { - { 1.f, 1.f }, - { 0.f, 1.f }, + { (F32)width/texture->getWidth(), (F32)height/texture->getHeight() }, + { 0.f, (F32)height/texture->getHeight() }, { 0.f, 0.f }, - { 1.f, 0.f } + { (F32)width/texture->getWidth(), 0.f } }; - image->bind(); + gGL.getTexUnit(0)->bind(texture); gGL.color4fv(UI_VERTEX_COLOR.mV); - gGL.begin(GL_QUADS); + gGL.begin(LLRender::QUADS); { gGL.texCoord2fv( uv[ (rotations + 0) % 4]); gGL.vertex2i(width, height ); @@ -678,6 +600,15 @@ void LLJoystickCameraRotate::drawRotatedImage( const LLImageGL* image, S32 rotat // LLJoystickCameraTrack //------------------------------------------------------------------------------- +LLJoystickCameraTrack::Params::Params() +{ + held_down_delay.seconds(0.0); +} + +LLJoystickCameraTrack::LLJoystickCameraTrack(const LLJoystickCameraTrack::Params& p) +: LLJoystickCameraRotate(p) +{} + void LLJoystickCameraTrack::onHeldDown() { @@ -688,186 +619,24 @@ void LLJoystickCameraTrack::onHeldDown() if (dx > mVertSlopNear) { - gAgent.unlockView(); - gAgent.setPanRightKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setPanRightKey(getOrbitRate()); } else if (dx < -mVertSlopNear) { - gAgent.unlockView(); - gAgent.setPanLeftKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setPanLeftKey(getOrbitRate()); } // over/under rotation if (dy > mVertSlopNear) { - gAgent.unlockView(); - gAgent.setPanUpKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setPanUpKey(getOrbitRate()); } else if (dy < -mVertSlopNear) { - gAgent.unlockView(); - gAgent.setPanDownKey(getOrbitRate()); - } -} - - - -//------------------------------------------------------------------------------- -// LLJoystickCameraZoom -//------------------------------------------------------------------------------- - -LLJoystickCameraZoom::LLJoystickCameraZoom(const LLString& name, LLRect rect, const LLString &out_img, const LLString &plus_in_img, const LLString &minus_in_img) - : - LLJoystick(name, rect, out_img, "", JQ_ORIGIN), - mInTop( FALSE ), - mInBottom( FALSE ) -{ - mPlusInImage = gImageList.getImage(LLUI::findAssetUUIDByName(plus_in_img), MIPMAP_FALSE, TRUE); - mMinusInImage = gImageList.getImage(LLUI::findAssetUUIDByName(minus_in_img), MIPMAP_FALSE, TRUE); -} - - -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( getVisible() ) - { - if( mInTop ) - { - gl_draw_image( 0, 0, mPlusInImage ); - } - else - if( mInBottom ) - { - gl_draw_image( 0, 0, mMinusInImage ); - } - 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; + gAgentCamera.unlockView(); + gAgentCamera.setPanDownKey(getOrbitRate()); } } |