void LLScrollbar::updateThumbRect() { // llassert( 0 <= mDocSize ); // llassert( 0 <= mDocPos && mDocPos <= getDocPosMax() ); const S32 THUMB_MIN_LENGTH = 16; S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? getRect().getWidth() : getRect().getHeight(); S32 thumb_bg_length = llmax(0, window_length - 2 * SCROLLBAR_SIZE); S32 visible_lines = llmin( mDocSize, mPageSize ); S32 thumb_length = mDocSize ? llmin(llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH), thumb_bg_length) : thumb_bg_length; S32 variable_lines = mDocSize - visible_lines; if( mOrientation == LLScrollbar::VERTICAL ) { S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE; S32 thumb_start_min = SCROLLBAR_SIZE + THUMB_MIN_LENGTH; S32 thumb_start = variable_lines ? llmin( llmax(thumb_start_max - (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_max; mThumbRect.mLeft = 0; mThumbRect.mTop = thumb_start; mThumbRect.mRight = SCROLLBAR_SIZE; mThumbRect.mBottom = thumb_start - thumb_length; } else { // Horizontal S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE - thumb_length; S32 thumb_start_min = SCROLLBAR_SIZE; S32 thumb_start = variable_lines ? llmin(llmax( thumb_start_min + (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_min; mThumbRect.mLeft = thumb_start; mThumbRect.mTop = SCROLLBAR_SIZE; mThumbRect.mRight = thumb_start + thumb_length; mThumbRect.mBottom = 0; } if (mOnScrollEndCallback && mOnScrollEndData && (mDocPos == getDocPosMax())) { mOnScrollEndCallback(mOnScrollEndData); } }
BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; if( hasMouseCapture() ) { if (mDragItem) { // mouse down was on an item S32 dx = x - mMouseDownX; S32 dy = y - mMouseDownY; if (-2 < dx && dx < 2 && -2 < dy && dy < 2) { if(mDragItemSaved) { openEmbeddedItem(mDragItem, mDragItemChar); } else { showUnsavedAlertDialog(mDragItem); } } } mDragItem = NULL; } handled = LLTextEditor::handleMouseUp(x,y,mask); // Used to enable I Agree checkbox if the user scrolled through entire text BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); if (mOnScrollEndCallback && was_scrolled_to_bottom) { mOnScrollEndCallback(mOnScrollEndData); } return handled; }
BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; // Let scrollbar have first dibs handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL; // enable I Agree checkbox if the user scrolled through entire text BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); if (mOnScrollEndCallback && was_scrolled_to_bottom) { mOnScrollEndCallback(mOnScrollEndData); } if( !handled && mTakesNonScrollClicks) { if (!(mask & MASK_SHIFT)) { deselect(); } BOOL start_select = TRUE; if( allowsEmbeddedItems() ) { setCursorAtLocalPos( x, y, FALSE ); llwchar wc = 0; if (mCursorPos < getLength()) { wc = getWChar(mCursorPos); } LLInventoryItem* item_at_pos = LLEmbeddedItems::getEmbeddedItem(wc); if (item_at_pos) { mDragItem = item_at_pos; mDragItemChar = wc; mDragItemSaved = LLEmbeddedItems::getEmbeddedItemSaved(wc); gFocusMgr.setMouseCapture( this ); mMouseDownX = x; mMouseDownY = y; S32 screen_x; S32 screen_y; localPointToScreen(x, y, &screen_x, &screen_y ); LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y ); start_select = FALSE; } else { mDragItem = NULL; } } if( start_select ) { // If we're not scrolling (handled by child), then we're selecting if (mask & MASK_SHIFT) { S32 old_cursor_pos = mCursorPos; setCursorAtLocalPos( x, y, TRUE ); if (hasSelection()) { /* Mac-like behavior - extend selection towards the cursor if (mCursorPos < mSelectionStart && mCursorPos < mSelectionEnd) { // ...left of selection mSelectionStart = llmax(mSelectionStart, mSelectionEnd); mSelectionEnd = mCursorPos; } else if (mCursorPos > mSelectionStart && mCursorPos > mSelectionEnd) { // ...right of selection mSelectionStart = llmin(mSelectionStart, mSelectionEnd); mSelectionEnd = mCursorPos; } else { mSelectionEnd = mCursorPos; } */ // Windows behavior mSelectionEnd = mCursorPos; } else { mSelectionStart = old_cursor_pos; mSelectionEnd = mCursorPos; } // assume we're starting a drag select mIsSelecting = TRUE; } else { setCursorAtLocalPos( x, y, TRUE ); startSelection(); } gFocusMgr.setMouseCapture( this ); } handled = TRUE; } if (hasTabStop()) { setFocus(TRUE); handled = TRUE; } // Delay cursor flashing resetKeystrokeTimer(); return handled; }
void LLScrollbar::draw() { if (!getRect().isValid()) return; S32 local_mouse_x; S32 local_mouse_y; LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y); BOOL other_captor = gFocusMgr.getMouseCapture() && gFocusMgr.getMouseCapture() != this; BOOL hovered = getEnabled() && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y)); if (hovered) { mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f)); } else { mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f)); } // Draw background and thumb. LLUIImage* rounded_rect_imagep = LLUI::sImageProvider->getUIImage("rounded_square.tga"); if (!rounded_rect_imagep) { gl_rect_2d(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0, mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(), mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(), mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, mTrackColor, TRUE); gl_rect_2d(mThumbRect, mThumbColor, TRUE); } else { // Background rounded_rect_imagep->drawSolid(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0, mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(), mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(), mTrackColor); // Thumb LLRect outline_rect = mThumbRect; outline_rect.stretch(2); if (gFocusMgr.getKeyboardFocus() == this) { rounded_rect_imagep->draw(outline_rect, gFocusMgr.getFocusColor()); } rounded_rect_imagep->draw(mThumbRect, mThumbColor); if (mCurGlowStrength > 0.01f) { gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); rounded_rect_imagep->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); gGL.setSceneBlendType(LLRender::BT_ALPHA); } } BOOL was_scrolled_to_bottom = (getDocPos() == getDocPosMax()); if (mOnScrollEndCallback && was_scrolled_to_bottom) { mOnScrollEndCallback(mOnScrollEndData); } // Draw children LLView::draw(); } // end draw
BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; // let scrollbar have first dibs handled = LLView::childrenHandleMouseUp(x, y, mask) != NULL; // Used to enable I Agree checkbox if the user scrolled through entire text BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); if (mOnScrollEndCallback && was_scrolled_to_bottom) { mOnScrollEndCallback(mOnScrollEndData); } if( !handled && mTakesNonScrollClicks) { if( mIsSelecting ) { // Finish selection if( y > getTextRect().mTop ) { mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 ); } else if( y < getTextRect().mBottom ) { mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 ); } setCursorAtLocalPos( x, y, TRUE ); endSelection(); updateScrollFromCursor(); } if( !hasSelection() ) { handleMouseUpOverSegment( x, y, mask ); } handled = TRUE; } // Delay cursor flashing resetKeystrokeTimer(); if( hasMouseCapture() ) { if (mDragItem) { // mouse down was on an item S32 dx = x - mMouseDownX; S32 dy = y - mMouseDownY; if (-2 < dx && dx < 2 && -2 < dy && dy < 2) { if(mDragItemSaved) { openEmbeddedItem(mDragItem); }else { showUnsavedAlertDialog(mDragItem); } } } mDragItem = NULL; gFocusMgr.setMouseCapture( NULL ); handled = TRUE; } return handled; }