aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lljoystickbutton.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/lljoystickbutton.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/lljoystickbutton.cpp866
1 files changed, 866 insertions, 0 deletions
diff --git a/linden/indra/newview/lljoystickbutton.cpp b/linden/indra/newview/lljoystickbutton.cpp
new file mode 100644
index 0000000..a280ca8
--- /dev/null
+++ b/linden/indra/newview/lljoystickbutton.cpp
@@ -0,0 +1,866 @@
1/**
2 * @file lljoystickbutton.cpp
3 * @brief LLJoystick class implementation
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29
30#include "lljoystickbutton.h"
31
32// Library includes
33#include "llcoord.h"
34#include "indra_constants.h"
35
36// Project includes
37#include "llui.h"
38#include "llagent.h"
39#include "llviewerimage.h"
40#include "llviewerimagelist.h"
41#include "llviewerwindow.h"
42#include "llmoveview.h"
43
44#include "llglheaders.h"
45
46const F32 NUDGE_TIME = 0.25f; // in seconds
47const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed
48
49//
50// Public Methods
51//
52LLJoystick::LLJoystick(
53 const LLString& name,
54 LLRect rect,
55 const LLString &default_image,
56 const LLString &selected_image,
57 EJoystickQuadrant initial_quadrant )
58 :
59 LLButton(name, rect, default_image, selected_image, NULL, NULL),
60 mInitialQuadrant(initial_quadrant),
61 mInitialOffset(0, 0),
62 mLastMouse(0, 0),
63 mFirstMouse(0, 0),
64 mVertSlopNear(0),
65 mVertSlopFar(0),
66 mHorizSlopNear(0),
67 mHorizSlopFar(0),
68 mHeldDown(FALSE),
69 mHeldDownTimer()
70{
71 mHeldDownCallback = &LLJoystick::onHeldDown;
72 mCallbackUserData = this;
73}
74
75
76void LLJoystick::updateSlop()
77{
78 mVertSlopNear = mRect.getHeight();
79 mVertSlopFar = mRect.getHeight() * 2;
80
81 mHorizSlopNear = mRect.getWidth();
82 mHorizSlopFar = mRect.getWidth() * 2;
83
84 // Compute initial mouse offset based on initial quadrant.
85 // Place the mouse evenly between the near and far zones.
86 switch (mInitialQuadrant)
87 {
88 case JQ_ORIGIN:
89 mInitialOffset.set(0, 0);
90 break;
91
92 case JQ_UP:
93 mInitialOffset.mX = 0;
94 mInitialOffset.mY = (mVertSlopNear + mVertSlopFar) / 2;
95 break;
96
97 case JQ_DOWN:
98 mInitialOffset.mX = 0;
99 mInitialOffset.mY = - (mVertSlopNear + mVertSlopFar) / 2;
100 break;
101
102 case JQ_LEFT:
103 mInitialOffset.mX = - (mHorizSlopNear + mHorizSlopFar) / 2;
104 mInitialOffset.mY = 0;
105 break;
106
107 case JQ_RIGHT:
108 mInitialOffset.mX = (mHorizSlopNear + mHorizSlopFar) / 2;
109 mInitialOffset.mY = 0;
110 break;
111
112 default:
113 llerrs << "LLJoystick::LLJoystick() - bad switch case" << llendl;
114 break;
115 }
116
117 return;
118}
119
120
121BOOL LLJoystick::handleMouseDown(S32 x, S32 y, MASK mask)
122{
123 //llinfos << "joystick mouse down " << x << ", " << y << llendl;
124
125 mLastMouse.set(x, y);
126 mFirstMouse.set(x, y);
127
128 mMouseDownTimer.reset();
129 return LLButton::handleMouseDown(x, y, mask);
130}
131
132
133BOOL LLJoystick::handleMouseUp(S32 x, S32 y, MASK mask)
134{
135 // llinfos << "joystick mouse up " << x << ", " << y << llendl;
136
137 if( gViewerWindow->hasMouseCapture( this ) )
138 {
139 mLastMouse.set(x, y);
140 mHeldDown = FALSE;
141 onMouseUp();
142 }
143
144 return LLButton::handleMouseUp(x, y, mask);
145}
146
147
148BOOL LLJoystick::handleHover(S32 x, S32 y, MASK mask)
149{
150 if( gViewerWindow->hasMouseCapture( this ) )
151 {
152 mLastMouse.set(x, y);
153 }
154
155 return LLButton::handleHover(x, y, mask);
156}
157
158F32 LLJoystick::getElapsedHeldDownTime()
159{
160 if( mHeldDown )
161 {
162 return mMouseDownTimer.getElapsedTimeF32();
163 }
164 else
165 {
166 return 0.f;
167 }
168}
169
170// static
171void LLJoystick::onHeldDown(void *userdata)
172{
173 LLJoystick *self = (LLJoystick *)userdata;
174
175 llassert( gViewerWindow->hasMouseCapture( self ) );
176
177 self->mHeldDown = TRUE;
178 self->onHeldDown();
179}
180
181EJoystickQuadrant LLJoystick::selectQuadrant(LLXMLNodePtr node)
182{
183
184 EJoystickQuadrant quadrant = JQ_RIGHT;
185
186 if (node->hasAttribute("quadrant"))
187 {
188 LLString quadrant_name;
189 node->getAttributeString("quadrant", quadrant_name);
190
191 quadrant = quadrantFromName(quadrant_name.c_str());
192 }
193 return quadrant;
194}
195
196
197LLString LLJoystick::nameFromQuadrant(EJoystickQuadrant quadrant)
198{
199 if (quadrant == JQ_ORIGIN) return LLString("origin");
200 else if (quadrant == JQ_UP) return LLString("up");
201 else if (quadrant == JQ_DOWN) return LLString("down");
202 else if (quadrant == JQ_LEFT) return LLString("left");
203 else if (quadrant == JQ_RIGHT) return LLString("right");
204 else return LLString();
205}
206
207
208EJoystickQuadrant LLJoystick::quadrantFromName(const LLString& sQuadrant)
209{
210 EJoystickQuadrant quadrant = JQ_RIGHT;
211
212 if (sQuadrant == "origin")
213 {
214 quadrant = JQ_ORIGIN;
215 }
216 else if (sQuadrant == "up")
217 {
218 quadrant = JQ_UP;
219 }
220 else if (sQuadrant == "down")
221 {
222 quadrant = JQ_DOWN;
223 }
224 else if (sQuadrant == "left")
225 {
226 quadrant = JQ_LEFT;
227 }
228 else if (sQuadrant == "right")
229 {
230 quadrant = JQ_RIGHT;
231 }
232
233 return quadrant;
234}
235
236
237LLXMLNodePtr LLJoystick::getXML(bool save_children) const
238{
239 LLXMLNodePtr node = LLUICtrl::getXML();
240
241 node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(mHAlign));
242 node->createChild("quadrant", TRUE)->setStringValue(nameFromQuadrant(mInitialQuadrant));
243
244 addImageAttributeToXML(node,mImageUnselectedName,mImageUnselectedID,"image_unselected");
245 addImageAttributeToXML(node,mImageSelectedName,mImageSelectedID,"image_selected");
246
247 node->createChild("scale_image", TRUE)->setBoolValue(mScaleImage);
248
249 return node;
250}
251
252
253
254//-------------------------------------------------------------------------------
255// LLJoystickAgentTurn
256//-------------------------------------------------------------------------------
257
258void LLJoystickAgentTurn::onHeldDown()
259{
260 F32 time = getElapsedHeldDownTime();
261 updateSlop();
262
263 //llinfos << "move forward/backward (and/or turn)" << llendl;
264
265 S32 dx = mLastMouse.mX - mFirstMouse.mX + mInitialOffset.mX;
266 S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY;
267
268 float m = (float) (dx)/abs(dy);
269
270 if (m > 1) {
271 m = 1;
272 }
273 else if (m < -1) {
274 m = -1;
275 }
276 gAgent.moveYaw(-LLFloaterMove::getYawRate(time)*m);
277
278
279 // handle forward/back movement
280 if (dy > mVertSlopFar)
281 {
282 // ...if mouse is forward of run region run forward
283 gAgent.moveAt(1);
284 }
285 else if (dy > mVertSlopNear)
286 {
287 if( time < NUDGE_TIME )
288 {
289 gAgent.moveAtNudge(1);
290 }
291 else
292 {
293 // ...else if mouse is forward of walk region walk forward
294 // JC 9/5/2002 - Always run / move quickly.
295 gAgent.moveAt(1);
296 }
297 }
298 else if (dy < -mVertSlopFar)
299 {
300 // ...else if mouse is behind run region run backward
301 gAgent.moveAt(-1);
302 }
303 else if (dy < -mVertSlopNear)
304 {
305 if( time < NUDGE_TIME )
306 {
307 gAgent.moveAtNudge(-1);
308 }
309 else
310 {
311 // ...else if mouse is behind walk region walk backward
312 // JC 9/5/2002 - Always run / move quickly.
313 gAgent.moveAt(-1);
314 }
315 }
316}
317
318LLView* LLJoystickAgentTurn::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
319{
320 LLString name("button");
321 node->getAttributeString("name", name);
322
323 LLString image_unselected;
324 if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected);
325
326 LLString image_selected;
327 if (node->hasAttribute("image_selected")) node->getAttributeString("image_selected",image_selected);
328
329 EJoystickQuadrant quad = JQ_ORIGIN;
330 if (node->hasAttribute("quadrant")) quad = selectQuadrant(node);
331
332 LLJoystickAgentTurn *button = new LLJoystickAgentTurn(name,
333 LLRect(),
334 image_unselected,
335 image_selected,
336 quad);
337
338 if (node->hasAttribute("halign"))
339 {
340 LLFontGL::HAlign halign = selectFontHAlign(node);
341 button->setHAlign(halign);
342 }
343
344 if (node->hasAttribute("scale_image"))
345 {
346 BOOL needsScale = FALSE;
347 node->getAttributeBOOL("scale_image",needsScale);
348 button->setScaleImage( needsScale );
349 }
350
351 button->initFromXML(node, parent);
352
353 return button;
354}
355
356
357
358//-------------------------------------------------------------------------------
359// LLJoystickAgentSlide
360//-------------------------------------------------------------------------------
361
362void LLJoystickAgentSlide::onMouseUp()
363{
364 F32 time = getElapsedHeldDownTime();
365 if( time < NUDGE_TIME )
366 {
367 switch (mInitialQuadrant)
368 {
369 case JQ_LEFT:
370 gAgent.moveLeftNudge(1);
371 break;
372
373 case JQ_RIGHT:
374 gAgent.moveLeftNudge(-1);
375 break;
376
377 default:
378 break;
379 }
380 }
381}
382
383void LLJoystickAgentSlide::onHeldDown()
384{
385 //llinfos << "slide left/right (and/or move forward/backward)" << llendl;
386
387 updateSlop();
388
389 S32 dx = mLastMouse.mX - mFirstMouse.mX + mInitialOffset.mX;
390 S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY;
391
392 // handle left-right sliding
393 if (dx > mHorizSlopNear)
394 {
395 gAgent.moveLeft(-1);
396 }
397 else if (dx < -mHorizSlopNear)
398 {
399 gAgent.moveLeft(1);
400 }
401
402 // handle forward/back movement
403 if (dy > mVertSlopFar)
404 {
405 // ...if mouse is forward of run region run forward
406 gAgent.moveAt(1);
407 }
408 else if (dy > mVertSlopNear)
409 {
410 // ...else if mouse is forward of walk region walk forward
411 gAgent.moveAtNudge(1);
412 }
413 else if (dy < -mVertSlopFar)
414 {
415 // ...else if mouse is behind run region run backward
416 gAgent.moveAt(-1);
417 }
418 else if (dy < -mVertSlopNear)
419 {
420 // ...else if mouse is behind walk region walk backward
421 gAgent.moveAtNudge(-1);
422 }
423}
424
425
426// static
427LLView* LLJoystickAgentSlide::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
428{
429 LLString name("button");
430 node->getAttributeString("name", name);
431
432 LLString image_unselected;
433 if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected);
434
435 LLString image_selected;
436 if (node->hasAttribute("image_selected")) node->getAttributeString("image_selected",image_selected);
437
438
439 EJoystickQuadrant quad = JQ_ORIGIN;
440 if (node->hasAttribute("quadrant")) quad = selectQuadrant(node);
441
442 LLJoystickAgentSlide *button = new LLJoystickAgentSlide(name,
443 LLRect(),
444 image_unselected,
445 image_selected,
446 quad);
447
448 if (node->hasAttribute("halign"))
449 {
450 LLFontGL::HAlign halign = selectFontHAlign(node);
451 button->setHAlign(halign);
452 }
453
454 if (node->hasAttribute("scale_image"))
455 {
456 BOOL needsScale = FALSE;
457 node->getAttributeBOOL("scale_image",needsScale);
458 button->setScaleImage( needsScale );
459 }
460
461 button->initFromXML(node, parent);
462
463 return button;
464}
465
466
467//-------------------------------------------------------------------------------
468// LLJoystickCameraRotate
469//-------------------------------------------------------------------------------
470
471LLJoystickCameraRotate::LLJoystickCameraRotate(const LLString& name, LLRect rect, const LLString &out_img, const LLString &in_img)
472 :
473 LLJoystick(name, rect, out_img, in_img, JQ_ORIGIN),
474 mInLeft( FALSE ),
475 mInTop( FALSE ),
476 mInRight( FALSE ),
477 mInBottom( FALSE )
478{ }
479
480
481void LLJoystickCameraRotate::updateSlop()
482{
483 // do the initial offset calculation based on mousedown location
484
485 // small fixed slop region
486 mVertSlopNear = 16;
487 mVertSlopFar = 32;
488
489 mHorizSlopNear = 16;
490 mHorizSlopFar = 32;
491
492 return;
493}
494
495
496BOOL LLJoystickCameraRotate::handleMouseDown(S32 x, S32 y, MASK mask)
497{
498 updateSlop();
499
500 // Set initial offset based on initial click location
501 S32 horiz_center = mRect.getWidth() / 2;
502 S32 vert_center = mRect.getHeight() / 2;
503
504 S32 dx = x - horiz_center;
505 S32 dy = y - vert_center;
506
507 if (dy > dx && dy > -dx)
508 {
509 // top
510 mInitialOffset.mX = 0;
511 mInitialOffset.mY = (mVertSlopNear + mVertSlopFar) / 2;
512 mInitialQuadrant = JQ_UP;
513 }
514 else if (dy > dx && dy <= -dx)
515 {
516 // left
517 mInitialOffset.mX = - (mHorizSlopNear + mHorizSlopFar) / 2;
518 mInitialOffset.mY = 0;
519 mInitialQuadrant = JQ_LEFT;
520 }
521 else if (dy <= dx && dy <= -dx)
522 {
523 // bottom
524 mInitialOffset.mX = 0;
525 mInitialOffset.mY = - (mVertSlopNear + mVertSlopFar) / 2;
526 mInitialQuadrant = JQ_DOWN;
527 }
528 else
529 {
530 // right
531 mInitialOffset.mX = (mHorizSlopNear + mHorizSlopFar) / 2;
532 mInitialOffset.mY = 0;
533 mInitialQuadrant = JQ_RIGHT;
534 }
535
536 return LLJoystick::handleMouseDown(x, y, mask);
537}
538
539
540void LLJoystickCameraRotate::onHeldDown()
541{
542 updateSlop();
543
544 S32 dx = mLastMouse.mX - mFirstMouse.mX + mInitialOffset.mX;
545 S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY;
546
547 // left-right rotation
548 if (dx > mHorizSlopNear)
549 {
550 gAgent.unlockView();
551 gAgent.setOrbitLeftKey(getOrbitRate());
552 }
553 else if (dx < -mHorizSlopNear)
554 {
555 gAgent.unlockView();
556 gAgent.setOrbitRightKey(getOrbitRate());
557 }
558
559 // over/under rotation
560 if (dy > mVertSlopNear)
561 {
562 gAgent.unlockView();
563 gAgent.setOrbitUpKey(getOrbitRate());
564 }
565 else if (dy < -mVertSlopNear)
566 {
567 gAgent.unlockView();
568 gAgent.setOrbitDownKey(getOrbitRate());
569 }
570}
571
572F32 LLJoystickCameraRotate::getOrbitRate()
573{
574 F32 time = getElapsedHeldDownTime();
575 if( time < NUDGE_TIME )
576 {
577 F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME;
578 //llinfos << rate << llendl;
579 return rate;
580 }
581 else
582 {
583 return 1;
584 }
585}
586
587
588// Only used for drawing
589void LLJoystickCameraRotate::setToggleState( BOOL left, BOOL top, BOOL right, BOOL bottom )
590{
591 mInLeft = left;
592 mInTop = top;
593 mInRight = right;
594 mInBottom = bottom;
595}
596
597void LLJoystickCameraRotate::draw()
598{
599
600 if( getVisible() )
601 {
602 LLGLSUIDefault gls_ui;
603
604 gl_draw_image( 0, 0, mImageUnselected );
605
606 if( mInTop )
607 {
608 drawRotatedImage( mImageSelected, 0 );
609 }
610
611 if( mInRight )
612 {
613 drawRotatedImage( mImageSelected, 1 );
614 }
615
616 if( mInBottom )
617 {
618 drawRotatedImage( mImageSelected, 2 );
619 }
620
621 if( mInLeft )
622 {
623 drawRotatedImage( mImageSelected, 3 );
624 }
625
626 if (sDebugRects)
627 {
628 drawDebugRect();
629 }
630 }
631}
632
633// Draws image rotated by multiples of 90 degrees
634void LLJoystickCameraRotate::drawRotatedImage( LLImageGL* image, S32 rotations )
635{
636 S32 width = image->getWidth();
637 S32 height = image->getHeight();
638
639 F32 uv[][2] =
640 {
641 { 1.f, 1.f },
642 { 0.f, 1.f },
643 { 0.f, 0.f },
644 { 1.f, 0.f }
645 };
646
647 image->bind();
648
649 glColor4fv(UI_VERTEX_COLOR.mV);
650
651 glBegin(GL_QUADS);
652 {
653 glTexCoord2fv( uv[ (rotations + 0) % 4]);
654 glVertex2i(width, height );
655
656 glTexCoord2fv( uv[ (rotations + 1) % 4]);
657 glVertex2i(0, height );
658
659 glTexCoord2fv( uv[ (rotations + 2) % 4]);
660 glVertex2i(0, 0);
661
662 glTexCoord2fv( uv[ (rotations + 3) % 4]);
663 glVertex2i(width, 0);
664 }
665 glEnd();
666}
667
668
669
670//-------------------------------------------------------------------------------
671// LLJoystickCameraTrack
672//-------------------------------------------------------------------------------
673
674
675void LLJoystickCameraTrack::onHeldDown()
676{
677 updateSlop();
678
679 S32 dx = mLastMouse.mX - mFirstMouse.mX + mInitialOffset.mX;
680 S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY;
681
682 if (dx > mVertSlopNear)
683 {
684 gAgent.unlockView();
685 gAgent.setPanRightKey(getOrbitRate());
686 }
687 else if (dx < -mVertSlopNear)
688 {
689 gAgent.unlockView();
690 gAgent.setPanLeftKey(getOrbitRate());
691 }
692
693 // over/under rotation
694 if (dy > mVertSlopNear)
695 {
696 gAgent.unlockView();
697 gAgent.setPanUpKey(getOrbitRate());
698 }
699 else if (dy < -mVertSlopNear)
700 {
701 gAgent.unlockView();
702 gAgent.setPanDownKey(getOrbitRate());
703 }
704}
705
706
707
708//-------------------------------------------------------------------------------
709// LLJoystickCameraZoom
710//-------------------------------------------------------------------------------
711
712LLJoystickCameraZoom::LLJoystickCameraZoom(const LLString& name, LLRect rect, const LLString &out_img, const LLString &plus_in_img, const LLString &minus_in_img)
713 :
714 LLJoystick(name, rect, out_img, "", JQ_ORIGIN),
715 mInTop( FALSE ),
716 mInBottom( FALSE )
717{
718 mPlusInImage = gImageList.getImage(LLUI::findAssetUUIDByName(plus_in_img), MIPMAP_FALSE, TRUE);
719 mMinusInImage = gImageList.getImage(LLUI::findAssetUUIDByName(minus_in_img), MIPMAP_FALSE, TRUE);
720}
721
722
723BOOL LLJoystickCameraZoom::handleMouseDown(S32 x, S32 y, MASK mask)
724{
725 BOOL handled = LLJoystick::handleMouseDown(x, y, mask);
726
727 if( handled )
728 {
729 if (mFirstMouse.mY > mRect.getHeight() / 2)
730 {
731 mInitialQuadrant = JQ_UP;
732 }
733 else
734 {
735 mInitialQuadrant = JQ_DOWN;
736 }
737 }
738 return handled;
739}
740
741
742void LLJoystickCameraZoom::onHeldDown()
743{
744 updateSlop();
745
746 const F32 FAST_RATE = 2.5f; // two and a half times the normal rate
747
748 S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY;
749
750 if (dy > mVertSlopFar)
751 {
752 // Zoom in fast
753 gAgent.unlockView();
754 gAgent.setOrbitInKey(FAST_RATE);
755 }
756 else if (dy > mVertSlopNear)
757 {
758 // Zoom in slow
759 gAgent.unlockView();
760 gAgent.setOrbitInKey(getOrbitRate());
761 }
762 else if (dy < -mVertSlopFar)
763 {
764 // Zoom out fast
765 gAgent.unlockView();
766 gAgent.setOrbitOutKey(FAST_RATE);
767 }
768 else if (dy < -mVertSlopNear)
769 {
770 // Zoom out slow
771 gAgent.unlockView();
772 gAgent.setOrbitOutKey(getOrbitRate());
773 }
774}
775
776// Only used for drawing
777void LLJoystickCameraZoom::setToggleState( BOOL top, BOOL bottom )
778{
779 mInTop = top;
780 mInBottom = bottom;
781}
782
783void LLJoystickCameraZoom::draw()
784{
785 if( getVisible() )
786 {
787 if( mInTop )
788 {
789 gl_draw_image( 0, 0, mPlusInImage );
790 }
791 else
792 if( mInBottom )
793 {
794 gl_draw_image( 0, 0, mMinusInImage );
795 }
796 else
797 {
798 gl_draw_image( 0, 0, mImageUnselected );
799 }
800
801 if (sDebugRects)
802 {
803 drawDebugRect();
804 }
805 }
806}
807
808void LLJoystickCameraZoom::updateSlop()
809{
810 mVertSlopNear = mRect.getHeight() / 4;
811 mVertSlopFar = mRect.getHeight() / 2;
812
813 mHorizSlopNear = mRect.getWidth() / 4;
814 mHorizSlopFar = mRect.getWidth() / 2;
815
816 // Compute initial mouse offset based on initial quadrant.
817 // Place the mouse evenly between the near and far zones.
818 switch (mInitialQuadrant)
819 {
820 case JQ_ORIGIN:
821 mInitialOffset.set(0, 0);
822 break;
823
824 case JQ_UP:
825 mInitialOffset.mX = 0;
826 mInitialOffset.mY = (mVertSlopNear + mVertSlopFar) / 2;
827 break;
828
829 case JQ_DOWN:
830 mInitialOffset.mX = 0;
831 mInitialOffset.mY = - (mVertSlopNear + mVertSlopFar) / 2;
832 break;
833
834 case JQ_LEFT:
835 mInitialOffset.mX = - (mHorizSlopNear + mHorizSlopFar) / 2;
836 mInitialOffset.mY = 0;
837 break;
838
839 case JQ_RIGHT:
840 mInitialOffset.mX = (mHorizSlopNear + mHorizSlopFar) / 2;
841 mInitialOffset.mY = 0;
842 break;
843
844 default:
845 llerrs << "LLJoystick::LLJoystick() - bad switch case" << llendl;
846 break;
847 }
848
849 return;
850}
851
852
853F32 LLJoystickCameraZoom::getOrbitRate()
854{
855 F32 time = getElapsedHeldDownTime();
856 if( time < NUDGE_TIME )
857 {
858 F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME;
859// llinfos << "rate " << rate << " time " << time << llendl;
860 return rate;
861 }
862 else
863 {
864 return 1;
865 }
866}