public override bool requestChildRectangleOnScreen(android.view.View child, android.graphics.Rect rectangle, bool immediate) { // offset into coordinate space of this scroll view rectangle.offset(child.getLeft() - child.getScrollX(), child.getTop() - child.getScrollY ()); return scrollToChildRect(rectangle, immediate); }
/// <summary><p>Positions the popup window on screen.</summary> /// <remarks> /// <p>Positions the popup window on screen. When the popup window is too /// tall to fit under the anchor, a parent scroll view is seeked and scrolled /// up to reclaim space. If scrolling is not possible or not enough, the /// popup window gets moved on top of the anchor.</p> /// <p>The height must have been set on the layout parameters prior to /// calling this method.</p> /// </remarks> /// <param name="anchor">the view on which the popup window must be anchored</param> /// <param name="p">the layout parameters used to display the drop down</param> /// <returns>true if the popup is translated upwards to fit on screen</returns> private bool findDropDownPosition(android.view.View anchor, android.view.WindowManagerClass .LayoutParams p, int xoff, int yoff) { int anchorHeight = anchor.getHeight(); anchor.getLocationInWindow(mDrawingLocation); p.x = mDrawingLocation[0] + xoff; p.y = mDrawingLocation[1] + anchorHeight + yoff; bool onTop = false; p.gravity = android.view.Gravity.LEFT | android.view.Gravity.TOP; anchor.getLocationOnScreen(mScreenLocation); android.graphics.Rect displayFrame = new android.graphics.Rect(); anchor.getWindowVisibleDisplayFrame(displayFrame); int screenY = mScreenLocation[1] + anchorHeight + yoff; android.view.View root = anchor.getRootView(); if (screenY + mPopupHeight > displayFrame.bottom || p.x + mPopupWidth - root.getWidth () > 0) { // if the drop down disappears at the bottom of the screen. we try to // scroll a parent scrollview or move the drop down back up on top of // the edit box if (mAllowScrollingAnchorParent) { int scrollX = anchor.getScrollX(); int scrollY = anchor.getScrollY(); android.graphics.Rect r = new android.graphics.Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff, scrollY + mPopupHeight + anchor.getHeight() + yoff); anchor.requestRectangleOnScreen(r, true); } // now we re-evaluate the space available, and decide from that // whether the pop-up will go above or below the anchor. anchor.getLocationInWindow(mDrawingLocation); p.x = mDrawingLocation[0] + xoff; p.y = mDrawingLocation[1] + anchor.getHeight() + yoff; // determine whether there is more space above or below the anchor anchor.getLocationOnScreen(mScreenLocation); onTop = (displayFrame.bottom - mScreenLocation[1] - anchor.getHeight() - yoff) < (mScreenLocation[1] - yoff - displayFrame.top); if (onTop) { p.gravity = android.view.Gravity.LEFT | android.view.Gravity.BOTTOM; p.y = root.getHeight() - mDrawingLocation[1] + yoff; } else { p.y = mDrawingLocation[1] + anchor.getHeight() + yoff; } } if (mClipToScreen) { int displayFrameWidth = displayFrame.right - displayFrame.left; int right = p.x + p.width; if (right > displayFrameWidth) { p.x -= right - displayFrameWidth; } if (p.x < displayFrame.left) { p.x = displayFrame.left; p.width = System.Math.Min(p.width, displayFrameWidth); } if (onTop) { int popupTop = mScreenLocation[1] + yoff - mPopupHeight; if (popupTop < 0) { p.y += popupTop; } } else { p.y = System.Math.Max(p.y, displayFrame.top); } } p.gravity |= android.view.Gravity.DISPLAY_CLIP_VERTICAL; return onTop; }
/// <summary>Performs a scroll to line end action.</summary> /// <remarks> /// Performs a scroll to line end action. /// Scrolls to the end of the line. /// </remarks> /// <param name="widget">The text view.</param> /// <param name="buffer">The text buffer.</param> /// <returns>True if the event was handled.</returns> /// <hide></hide> protected internal virtual bool scrollLineEnd(android.widget.TextView widget, android.text.Spannable buffer) { int maxScrollX = getScrollBoundsRight(widget) - getInnerWidth(widget); int scrollX = widget.getScrollX(); if (scrollX < maxScrollX) { widget.scrollTo(maxScrollX, widget.getScrollY()); return true; } return false; }
public override bool onTouchEvent(android.widget.TextView widget, android.text.Spannable buffer, android.view.MotionEvent @event) { int initialScrollX = -1; int initialScrollY = -1; int action = @event.getAction(); if (action == android.view.MotionEvent.ACTION_UP) { initialScrollX = android.text.method.Touch.getInitialScrollX(widget, buffer); initialScrollY = android.text.method.Touch.getInitialScrollY(widget, buffer); } bool handled = android.text.method.Touch.onTouchEvent(widget, buffer, @event); if (widget.isFocused() && !widget.didTouchFocusSelect()) { if (action == android.view.MotionEvent.ACTION_DOWN) { if (isSelecting(buffer)) { int offset = widget.getOffsetForPosition(@event.getX(), @event.getY()); buffer.setSpan(LAST_TAP_DOWN, offset, offset, android.text.SpannedClass.SPAN_POINT_POINT ); // Disallow intercepting of the touch events, so that // users can scroll and select at the same time. // without this, users would get booted out of select // mode once the view detected it needed to scroll. widget.getParent().requestDisallowInterceptTouchEvent(true); } } else { if (action == android.view.MotionEvent.ACTION_MOVE) { if (isSelecting(buffer) && handled) { // Before selecting, make sure we've moved out of the "slop". // handled will be true, if we're in select mode AND we're // OUT of the slop // Turn long press off while we're selecting. User needs to // re-tap on the selection to enable long press widget.cancelLongPress(); // Update selection as we're moving the selection area. // Get the current touch position int offset = widget.getOffsetForPosition(@event.getX(), @event.getY()); android.text.Selection.extendSelection(buffer, offset); return true; } } else { if (action == android.view.MotionEvent.ACTION_UP) { // If we have scrolled, then the up shouldn't move the cursor, // but we do need to make sure the cursor is still visible at // the current scroll offset to avoid the scroll jumping later // to show it. if ((initialScrollY >= 0 && initialScrollY != widget.getScrollY()) || (initialScrollX >= 0 && initialScrollX != widget.getScrollX())) { widget.moveCursorToVisibleOffset(); return true; } int offset = widget.getOffsetForPosition(@event.getX(), @event.getY()); if (isSelecting(buffer)) { buffer.removeSpan(LAST_TAP_DOWN); android.text.Selection.extendSelection(buffer, offset); } else { if (!widget.shouldIgnoreActionUpEvent()) { android.text.Selection.setSelection(buffer, offset); } } android.text.method.MetaKeyKeyListener.adjustMetaAfterKeypress(buffer); android.text.method.MetaKeyKeyListener.resetLockedMeta(buffer); return true; } } } } return handled; }
/// <summary>Performs a scroll to bottom action.</summary> /// <remarks> /// Performs a scroll to bottom action. /// Scrolls to the bottom of the document. /// </remarks> /// <param name="widget">The text view.</param> /// <param name="buffer">The text buffer.</param> /// <returns>True if the event was handled.</returns> /// <hide></hide> protected internal virtual bool scrollBottom(android.widget.TextView widget, android.text.Spannable buffer) { android.text.Layout layout = widget.getLayout(); int lineCount = layout.getLineCount(); if (getBottomLine(widget) <= lineCount - 1) { android.text.method.Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop (lineCount) - getInnerHeight(widget)); return true; } return false; }
/// <summary>Performs a scroll to line start action.</summary> /// <remarks> /// Performs a scroll to line start action. /// Scrolls to the start of the line. /// </remarks> /// <param name="widget">The text view.</param> /// <param name="buffer">The text buffer.</param> /// <returns>True if the event was handled.</returns> /// <hide></hide> protected internal virtual bool scrollLineStart(android.widget.TextView widget, android.text.Spannable buffer) { int minScrollX = getScrollBoundsLeft(widget); int scrollX = widget.getScrollX(); if (scrollX > minScrollX) { widget.scrollTo(minScrollX, widget.getScrollY()); return true; } return false; }
/// <summary>Performs a scroll page up action.</summary> /// <remarks> /// Performs a scroll page up action. /// Scrolls down by one page. /// </remarks> /// <param name="widget">The text view.</param> /// <param name="buffer">The text buffer.</param> /// <returns>True if the event was handled.</returns> /// <hide></hide> protected internal virtual bool scrollPageDown(android.widget.TextView widget, android.text.Spannable buffer) { android.text.Layout layout = widget.getLayout(); int innerHeight = getInnerHeight(widget); int bottom_1 = widget.getScrollY() + innerHeight + innerHeight; int bottomLine = layout.getLineForVertical(bottom_1); if (bottomLine <= layout.getLineCount() - 1) { android.text.method.Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop (bottomLine + 1) - innerHeight); return true; } return false; }
/// <summary>Performs a scroll to top action.</summary> /// <remarks> /// Performs a scroll to top action. /// Scrolls to the top of the document. /// </remarks> /// <param name="widget">The text view.</param> /// <param name="buffer">The text buffer.</param> /// <returns>True if the event was handled.</returns> /// <hide></hide> protected internal virtual bool scrollTop(android.widget.TextView widget, android.text.Spannable buffer) { android.text.Layout layout = widget.getLayout(); if (getTopLine(widget) >= 0) { android.text.method.Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop (0)); return true; } return false; }
/// <summary>Performs a scroll page up action.</summary> /// <remarks> /// Performs a scroll page up action. /// Scrolls up by one page. /// </remarks> /// <param name="widget">The text view.</param> /// <param name="buffer">The text buffer.</param> /// <returns>True if the event was handled.</returns> /// <hide></hide> protected internal virtual bool scrollPageUp(android.widget.TextView widget, android.text.Spannable buffer) { android.text.Layout layout = widget.getLayout(); int top_1 = widget.getScrollY() - getInnerHeight(widget); int topLine = layout.getLineForVertical(top_1); if (topLine >= 0) { android.text.method.Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop (topLine)); return true; } return false; }
/// <summary>Performs a scroll down action.</summary> /// <remarks> /// Performs a scroll down action. /// Scrolls down by the specified number of lines. /// </remarks> /// <param name="widget">The text view.</param> /// <param name="buffer">The text buffer.</param> /// <param name="amount">The number of lines to scroll by. Must be at least 1.</param> /// <returns>True if the event was handled.</returns> /// <hide></hide> protected internal virtual bool scrollDown(android.widget.TextView widget, android.text.Spannable buffer, int amount) { android.text.Layout layout = widget.getLayout(); int innerHeight = getInnerHeight(widget); int bottom_1 = widget.getScrollY() + innerHeight; int bottomLine = layout.getLineForVertical(bottom_1); if (layout.getLineTop(bottomLine + 1) < bottom_1 + 1) { // Less than a pixel of this line is out of view, // so we must have tried to make it entirely in view // and now want the next line to be in view instead. bottomLine += 1; } int limit = layout.getLineCount() - 1; if (bottomLine <= limit) { bottomLine = System.Math.Min(bottomLine + amount - 1, limit); android.text.method.Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop (bottomLine + 1) - innerHeight); return true; } return false; }
/// <summary>Performs a scroll up action.</summary> /// <remarks> /// Performs a scroll up action. /// Scrolls up by the specified number of lines. /// </remarks> /// <param name="widget">The text view.</param> /// <param name="buffer">The text buffer.</param> /// <param name="amount">The number of lines to scroll by. Must be at least 1.</param> /// <returns>True if the event was handled.</returns> /// <hide></hide> protected internal virtual bool scrollUp(android.widget.TextView widget, android.text.Spannable buffer, int amount) { android.text.Layout layout = widget.getLayout(); int top_1 = widget.getScrollY(); int topLine = layout.getLineForVertical(top_1); if (layout.getLineTop(topLine) == top_1) { // If the top line is partially visible, bring it all the way // into view; otherwise, bring the previous line into view. topLine -= 1; } if (topLine >= 0) { topLine = System.Math.Max(topLine - amount + 1, 0); android.text.method.Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop (topLine)); return true; } return false; }
/// <summary>Performs a scroll right action.</summary> /// <remarks> /// Performs a scroll right action. /// Scrolls right by the specified number of characters. /// </remarks> /// <param name="widget">The text view.</param> /// <param name="buffer">The text buffer.</param> /// <param name="amount">The number of characters to scroll by. Must be at least 1.</param> /// <returns>True if the event was handled.</returns> /// <hide></hide> protected internal virtual bool scrollRight(android.widget.TextView widget, android.text.Spannable buffer, int amount) { int maxScrollX = getScrollBoundsRight(widget) - getInnerWidth(widget); int scrollX = widget.getScrollX(); if (scrollX < maxScrollX) { scrollX = System.Math.Min(scrollX + getCharacterWidth(widget) * amount, maxScrollX ); widget.scrollTo(scrollX, widget.getScrollY()); return true; } return false; }
/// <summary>Performs a scroll left action.</summary> /// <remarks> /// Performs a scroll left action. /// Scrolls left by the specified number of characters. /// </remarks> /// <param name="widget">The text view.</param> /// <param name="buffer">The text buffer.</param> /// <param name="amount">The number of characters to scroll by. Must be at least 1.</param> /// <returns>True if the event was handled.</returns> /// <hide></hide> protected internal virtual bool scrollLeft(android.widget.TextView widget, android.text.Spannable buffer, int amount) { int minScrollX = getScrollBoundsLeft(widget); int scrollX = widget.getScrollX(); if (scrollX > minScrollX) { scrollX = System.Math.Max(scrollX - getCharacterWidth(widget) * amount, minScrollX ); widget.scrollTo(scrollX, widget.getScrollY()); return true; } return false; }