diff options
Diffstat (limited to 'linden/indra/llui/llbutton.cpp')
-rw-r--r-- | linden/indra/llui/llbutton.cpp | 63 |
1 files changed, 47 insertions, 16 deletions
diff --git a/linden/indra/llui/llbutton.cpp b/linden/indra/llui/llbutton.cpp index 41c2269..d35dd57 100644 --- a/linden/indra/llui/llbutton.cpp +++ b/linden/indra/llui/llbutton.cpp | |||
@@ -4,6 +4,7 @@ | |||
4 | * | 4 | * |
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | 5 | * Copyright (c) 2001-2007, Linden Research, Inc. |
6 | * | 6 | * |
7 | * Second Life Viewer Source Code | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | 8 | * 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 | * 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 | * ("GPL"), unless you have obtained a separate licensing agreement |
@@ -65,7 +66,9 @@ LLButton::LLButton( const LLString& name, const LLRect& rect, const LLString& co | |||
65 | mMouseUpCallback( NULL ), | 66 | mMouseUpCallback( NULL ), |
66 | mHeldDownCallback( NULL ), | 67 | mHeldDownCallback( NULL ), |
67 | mGLFont( NULL ), | 68 | mGLFont( NULL ), |
69 | mMouseDownFrame( 0 ), | ||
68 | mHeldDownDelay( 0.5f ), // seconds until held-down callback is called | 70 | mHeldDownDelay( 0.5f ), // seconds until held-down callback is called |
71 | mHeldDownFrameDelay( 0 ), | ||
69 | mImageUnselected( NULL ), | 72 | mImageUnselected( NULL ), |
70 | mImageSelected( NULL ), | 73 | mImageSelected( NULL ), |
71 | mImageHoverSelected( NULL ), | 74 | mImageHoverSelected( NULL ), |
@@ -118,7 +121,9 @@ LLButton::LLButton(const LLString& name, const LLRect& rect, | |||
118 | mMouseUpCallback( NULL ), | 121 | mMouseUpCallback( NULL ), |
119 | mHeldDownCallback( NULL ), | 122 | mHeldDownCallback( NULL ), |
120 | mGLFont( NULL ), | 123 | mGLFont( NULL ), |
124 | mMouseDownFrame( 0 ), | ||
121 | mHeldDownDelay( 0.5f ), // seconds until held-down callback is called | 125 | mHeldDownDelay( 0.5f ), // seconds until held-down callback is called |
126 | mHeldDownFrameDelay( 0 ), | ||
122 | mImageUnselected( NULL ), | 127 | mImageUnselected( NULL ), |
123 | mImageSelected( NULL ), | 128 | mImageSelected( NULL ), |
124 | mImageHoverSelected( NULL ), | 129 | mImageHoverSelected( NULL ), |
@@ -215,9 +220,9 @@ void LLButton::init(void (*click_callback)(void*), void *callback_data, const LL | |||
215 | 220 | ||
216 | LLButton::~LLButton() | 221 | LLButton::~LLButton() |
217 | { | 222 | { |
218 | if( this == gFocusMgr.getMouseCapture() ) | 223 | if( hasMouseCapture() ) |
219 | { | 224 | { |
220 | gFocusMgr.setMouseCapture( NULL, NULL ); | 225 | gFocusMgr.setMouseCapture( NULL ); |
221 | } | 226 | } |
222 | } | 227 | } |
223 | 228 | ||
@@ -303,7 +308,7 @@ BOOL LLButton::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) | |||
303 | BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) | 308 | BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) |
304 | { | 309 | { |
305 | // Route future Mouse messages here preemptively. (Release on mouse up.) | 310 | // Route future Mouse messages here preemptively. (Release on mouse up.) |
306 | gFocusMgr.setMouseCapture( this, &LLButton::onMouseCaptureLost ); | 311 | gFocusMgr.setMouseCapture( this ); |
307 | 312 | ||
308 | if (hasTabStop() && !getIsChrome()) | 313 | if (hasTabStop() && !getIsChrome()) |
309 | { | 314 | { |
@@ -316,6 +321,7 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) | |||
316 | } | 321 | } |
317 | 322 | ||
318 | mMouseDownTimer.start(); | 323 | mMouseDownTimer.start(); |
324 | mMouseDownFrame = LLFrameTimer::getFrameCount(); | ||
319 | 325 | ||
320 | if (mSoundFlags & MOUSE_DOWN) | 326 | if (mSoundFlags & MOUSE_DOWN) |
321 | { | 327 | { |
@@ -329,19 +335,17 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) | |||
329 | BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) | 335 | BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) |
330 | { | 336 | { |
331 | // We only handle the click if the click both started and ended within us | 337 | // We only handle the click if the click both started and ended within us |
332 | if( this == gFocusMgr.getMouseCapture() ) | 338 | if( hasMouseCapture() ) |
333 | { | 339 | { |
340 | // Always release the mouse | ||
341 | gFocusMgr.setMouseCapture( NULL ); | ||
342 | |||
334 | // Regardless of where mouseup occurs, handle callback | 343 | // Regardless of where mouseup occurs, handle callback |
335 | if (mMouseUpCallback) | 344 | if (mMouseUpCallback) |
336 | { | 345 | { |
337 | (*mMouseUpCallback)(mCallbackUserData); | 346 | (*mMouseUpCallback)(mCallbackUserData); |
338 | } | 347 | } |
339 | 348 | ||
340 | mMouseDownTimer.stop(); | ||
341 | |||
342 | // Always release the mouse | ||
343 | gFocusMgr.setMouseCapture( NULL, NULL ); | ||
344 | |||
345 | // DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked. | 349 | // DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked. |
346 | // If mouseup in the widget, it's been clicked | 350 | // If mouseup in the widget, it's been clicked |
347 | if (pointInView(x, y)) | 351 | if (pointInView(x, y)) |
@@ -356,6 +360,9 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) | |||
356 | (*mClickedCallback)( mCallbackUserData ); | 360 | (*mClickedCallback)( mCallbackUserData ); |
357 | } | 361 | } |
358 | } | 362 | } |
363 | |||
364 | mMouseDownTimer.stop(); | ||
365 | mMouseDownTimer.reset(); | ||
359 | } | 366 | } |
360 | 367 | ||
361 | return TRUE; | 368 | return TRUE; |
@@ -375,14 +382,14 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) | |||
375 | if (mMouseDownTimer.getStarted() && NULL != mHeldDownCallback) | 382 | if (mMouseDownTimer.getStarted() && NULL != mHeldDownCallback) |
376 | { | 383 | { |
377 | F32 elapsed = mMouseDownTimer.getElapsedTimeF32(); | 384 | F32 elapsed = mMouseDownTimer.getElapsedTimeF32(); |
378 | if( mHeldDownDelay < elapsed ) | 385 | if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= LLFrameTimer::getFrameCount() - mMouseDownFrame) |
379 | { | 386 | { |
380 | mHeldDownCallback( mCallbackUserData ); | 387 | mHeldDownCallback( mCallbackUserData ); |
381 | } | 388 | } |
382 | } | 389 | } |
383 | 390 | ||
384 | // We only handle the click if the click both started and ended within us | 391 | // We only handle the click if the click both started and ended within us |
385 | if( this == gFocusMgr.getMouseCapture() ) | 392 | if( hasMouseCapture() ) |
386 | { | 393 | { |
387 | handled = TRUE; | 394 | handled = TRUE; |
388 | } | 395 | } |
@@ -431,7 +438,7 @@ void LLButton::draw() | |||
431 | cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]); | 438 | cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]); |
432 | screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y); | 439 | screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y); |
433 | 440 | ||
434 | BOOL pressed = pressed_by_keyboard || (this == gFocusMgr.getMouseCapture() && pointInView(local_mouse_x, local_mouse_y)); | 441 | BOOL pressed = pressed_by_keyboard || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y)); |
435 | 442 | ||
436 | BOOL display_state = FALSE; | 443 | BOOL display_state = FALSE; |
437 | if( pressed ) | 444 | if( pressed ) |
@@ -819,11 +826,10 @@ void LLButton::setHoverImages( const LLString& image_name, const LLString& selec | |||
819 | setImageHoverSelected(selected_name); | 826 | setImageHoverSelected(selected_name); |
820 | } | 827 | } |
821 | 828 | ||
822 | // static | 829 | void LLButton::onMouseCaptureLost() |
823 | void LLButton::onMouseCaptureLost( LLMouseHandler* old_captor ) | ||
824 | { | 830 | { |
825 | LLButton* self = (LLButton*) old_captor; | 831 | mMouseDownTimer.stop(); |
826 | self->mMouseDownTimer.stop(); | 832 | mMouseDownTimer.reset(); |
827 | } | 833 | } |
828 | 834 | ||
829 | //------------------------------------------------------------------------- | 835 | //------------------------------------------------------------------------- |
@@ -947,6 +953,19 @@ LLXMLNodePtr LLButton::getXML(bool save_children) const | |||
947 | return node; | 953 | return node; |
948 | } | 954 | } |
949 | 955 | ||
956 | void clicked_help(void* data) | ||
957 | { | ||
958 | LLButton* self = (LLButton*)data; | ||
959 | if (!self) return; | ||
960 | |||
961 | if (!LLUI::sHtmlHelp) | ||
962 | { | ||
963 | return; | ||
964 | } | ||
965 | |||
966 | LLUI::sHtmlHelp->show(self->getHelpURL()); | ||
967 | } | ||
968 | |||
950 | // static | 969 | // static |
951 | LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) | 970 | LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) |
952 | { | 971 | { |
@@ -1023,9 +1042,21 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa | |||
1023 | { | 1042 | { |
1024 | button->setLabelSelected(node->getTextContents()); | 1043 | button->setLabelSelected(node->getTextContents()); |
1025 | } | 1044 | } |
1045 | |||
1046 | if (node->hasAttribute("help_url")) | ||
1047 | { | ||
1048 | LLString help_url; | ||
1049 | node->getAttributeString("help_url",help_url); | ||
1050 | button->setHelpURLCallback(help_url); | ||
1051 | } | ||
1026 | 1052 | ||
1027 | button->initFromXML(node, parent); | 1053 | button->initFromXML(node, parent); |
1028 | 1054 | ||
1029 | return button; | 1055 | return button; |
1030 | } | 1056 | } |
1031 | 1057 | ||
1058 | void LLButton::setHelpURLCallback(std::string help_url) | ||
1059 | { | ||
1060 | mHelpURL = help_url; | ||
1061 | setClickedCallback(clicked_help,this); | ||
1062 | } | ||