Java Code Examples for android.widget.TextView#getTotalPaddingBottom()

The following examples show how to use android.widget.TextView#getTotalPaddingBottom() . These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
@Override
public void onTakeFocus(TextView widget, Spannable text, int dir) {
    Layout layout = widget.getLayout();

    if (layout != null && (dir & View.FOCUS_FORWARD) != 0) {
        widget.scrollTo(widget.getScrollX(),
                        layout.getLineTop(0));
    }
    if (layout != null && (dir & View.FOCUS_BACKWARD) != 0) {
        int padding = widget.getTotalPaddingTop() +
                      widget.getTotalPaddingBottom();
        int line = layout.getLineCount() - 1;

        widget.scrollTo(widget.getScrollX(),
                        layout.getLineTop(line+1) -
                        (widget.getHeight() - padding));
    }
}
 
Example 2
Source Project: TinyDancer   File: TinyCoach.java    License: MIT License 6 votes vote down vote up
public TinyCoach(Application context, FPSConfig config) {

        fpsConfig = config;

        //create meter view
        meterView = (TextView) LayoutInflater.from(context).inflate(R.layout.meter_view, null);

        //set initial fps value....might change...
        meterView.setText((int) fpsConfig.refreshRate + "");

        // grab window manager and add view to the window
        windowManager = (WindowManager) meterView.getContext().getSystemService(Service.WINDOW_SERVICE);

        int minWidth = meterView.getLineHeight()
                + meterView.getTotalPaddingTop()
                + meterView.getTotalPaddingBottom()
                + (int) meterView.getPaint().getFontMetrics().bottom;
        meterView.setMinWidth(minWidth);

        addViewToWindow(meterView);
    }
 
Example 3
Source Project: android_9.0.0_r45   File: Touch.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Scrolls the specified widget to the specified coordinates, except
 * constrains the X scrolling position to the horizontal regions of
 * the text that will be visible after scrolling to the specified
 * Y position.
 */
public static void scrollTo(TextView widget, Layout layout, int x, int y) {
    final int horizontalPadding = widget.getTotalPaddingLeft() + widget.getTotalPaddingRight();
    final int availableWidth = widget.getWidth() - horizontalPadding;

    final int top = layout.getLineForVertical(y);
    Alignment a = layout.getParagraphAlignment(top);
    boolean ltr = layout.getParagraphDirection(top) > 0;

    int left, right;
    if (widget.getHorizontallyScrolling()) {
        final int verticalPadding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom();
        final int bottom = layout.getLineForVertical(y + widget.getHeight() - verticalPadding);

        left = Integer.MAX_VALUE;
        right = 0;

        for (int i = top; i <= bottom; i++) {
            left = (int) Math.min(left, layout.getLineLeft(i));
            right = (int) Math.max(right, layout.getLineRight(i));
        }
    } else {
        left = 0;
        right = availableWidth;
    }

    final int actualWidth = right - left;

    if (actualWidth < availableWidth) {
        if (a == Alignment.ALIGN_CENTER) {
            x = left - ((availableWidth - actualWidth) / 2);
        } else if ((ltr && (a == Alignment.ALIGN_OPPOSITE)) ||
                   (!ltr && (a == Alignment.ALIGN_NORMAL)) ||
                   (a == Alignment.ALIGN_RIGHT)) {
            // align_opposite does NOT mean align_right, we need the paragraph
            // direction to resolve it to left or right
            x = left - (availableWidth - actualWidth);
        } else {
            x = left;
        }
    } else {
        x = Math.min(x, right - availableWidth);
        x = Math.max(x, left);
    }

    widget.scrollTo(x, y);
}
 
Example 4
Source Project: android_9.0.0_r45   File: Touch.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Handles touch events for dragging.  You may want to do other actions
 * like moving the cursor on touch as well.
 */
public static boolean onTouchEvent(TextView widget, Spannable buffer,
                                   MotionEvent event) {
    DragState[] ds;

    switch (event.getActionMasked()) {
    case MotionEvent.ACTION_DOWN:
        ds = buffer.getSpans(0, buffer.length(), DragState.class);

        for (int i = 0; i < ds.length; i++) {
            buffer.removeSpan(ds[i]);
        }

        buffer.setSpan(new DragState(event.getX(), event.getY(),
                        widget.getScrollX(), widget.getScrollY()),
                0, 0, Spannable.SPAN_MARK_MARK);
        return true;

    case MotionEvent.ACTION_UP:
        ds = buffer.getSpans(0, buffer.length(), DragState.class);

        for (int i = 0; i < ds.length; i++) {
            buffer.removeSpan(ds[i]);
        }

        if (ds.length > 0 && ds[0].mUsed) {
            return true;
        } else {
            return false;
        }

    case MotionEvent.ACTION_MOVE:
        ds = buffer.getSpans(0, buffer.length(), DragState.class);

        if (ds.length > 0) {
            if (ds[0].mFarEnough == false) {
                int slop = ViewConfiguration.get(widget.getContext()).getScaledTouchSlop();

                if (Math.abs(event.getX() - ds[0].mX) >= slop ||
                    Math.abs(event.getY() - ds[0].mY) >= slop) {
                    ds[0].mFarEnough = true;
                }
            }

            if (ds[0].mFarEnough) {
                ds[0].mUsed = true;
                boolean cap = (event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0
                        || MetaKeyKeyListener.getMetaState(buffer,
                                MetaKeyKeyListener.META_SHIFT_ON) == 1
                        || MetaKeyKeyListener.getMetaState(buffer,
                                MetaKeyKeyListener.META_SELECTING) != 0;

                float dx;
                float dy;
                if (cap) {
                    // if we're selecting, we want the scroll to go in
                    // the direction of the drag
                    dx = event.getX() - ds[0].mX;
                    dy = event.getY() - ds[0].mY;
                } else {
                    dx = ds[0].mX - event.getX();
                    dy = ds[0].mY - event.getY();
                }
                ds[0].mX = event.getX();
                ds[0].mY = event.getY();

                int nx = widget.getScrollX() + (int) dx;
                int ny = widget.getScrollY() + (int) dy;

                int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom();
                Layout layout = widget.getLayout();

                ny = Math.min(ny, layout.getHeight() - (widget.getHeight() - padding));
                ny = Math.max(ny, 0);

                int oldX = widget.getScrollX();
                int oldY = widget.getScrollY();

                scrollTo(widget, layout, nx, ny);

                // If we actually scrolled, then cancel the up action.
                if (oldX != widget.getScrollX() || oldY != widget.getScrollY()) {
                    widget.cancelLongPress();
                }

                return true;
            }
        }
    }

    return false;
}
 
Example 5
private int getInnerHeight(TextView widget) {
    return widget.getHeight() - widget.getTotalPaddingTop() - widget.getTotalPaddingBottom();
}
 
Example 6
Source Project: MHViewer   File: LinkMovementMethod2.java    License: Apache License 2.0 4 votes vote down vote up
private boolean action(int what, TextView widget, Spannable buffer) {
    Layout layout = widget.getLayout();

    int padding = widget.getTotalPaddingTop() +
            widget.getTotalPaddingBottom();
    int areatop = widget.getScrollY();
    int areabot = areatop + widget.getHeight() - padding;

    int linetop = layout.getLineForVertical(areatop);
    int linebot = layout.getLineForVertical(areabot);

    int first = layout.getLineStart(linetop);
    int last = layout.getLineEnd(linebot);

    ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class);

    int a = Selection.getSelectionStart(buffer);
    int b = Selection.getSelectionEnd(buffer);

    int selStart = Math.min(a, b);
    int selEnd = Math.max(a, b);

    if (selStart < 0) {
        if (buffer.getSpanStart(FROM_BELOW) >= 0) {
            selStart = selEnd = buffer.length();
        }
    }

    if (selStart > last)
        selStart = selEnd = Integer.MAX_VALUE;
    if (selEnd < first)
        selStart = selEnd = -1;

    switch (what) {
        case CLICK:
            if (selStart == selEnd) {
                return false;
            }

            ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class);

            if (link.length != 1)
                return false;

            link[0].onClick(widget);
            break;

        case UP:
            int beststart, bestend;

            beststart = -1;
            bestend = -1;

            for (int i = 0; i < candidates.length; i++) {
                int end = buffer.getSpanEnd(candidates[i]);

                if (end < selEnd || selStart == selEnd) {
                    if (end > bestend) {
                        beststart = buffer.getSpanStart(candidates[i]);
                        bestend = end;
                    }
                }
            }

            if (beststart >= 0) {
                Selection.setSelection(buffer, bestend, beststart);
                return true;
            }

            break;

        case DOWN:
            beststart = Integer.MAX_VALUE;
            bestend = Integer.MAX_VALUE;

            for (int i = 0; i < candidates.length; i++) {
                int start = buffer.getSpanStart(candidates[i]);

                if (start > selStart || selStart == selEnd) {
                    if (start < beststart) {
                        beststart = start;
                        bestend = buffer.getSpanEnd(candidates[i]);
                    }
                }
            }

            if (bestend < Integer.MAX_VALUE) {
                Selection.setSelection(buffer, beststart, bestend);
                return true;
            }

            break;
    }

    return false;
}
 
Example 7
Source Project: timecat   File: CountLinkMovementMethod.java    License: Apache License 2.0 4 votes vote down vote up
private boolean action(int what, TextView widget, Spannable buffer) {
    Layout layout = widget.getLayout();

    int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom();
    int areatop = widget.getScrollY();
    int areabot = areatop + widget.getHeight() - padding;

    int linetop = layout.getLineForVertical(areatop);
    int linebot = layout.getLineForVertical(areabot);

    int first = layout.getLineStart(linetop);
    int last = layout.getLineEnd(linebot);

    ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class);

    int a = Selection.getSelectionStart(buffer);
    int b = Selection.getSelectionEnd(buffer);

    int selStart = Math.min(a, b);
    int selEnd = Math.max(a, b);

    if (selStart < 0) {
        if (buffer.getSpanStart(FROM_BELOW) >= 0) {
            selStart = selEnd = buffer.length();
        }
    }

    if (selStart > last) selStart = selEnd = Integer.MAX_VALUE;
    if (selEnd < first) selStart = selEnd = -1;

    switch (what) {
        case CLICK:
            if (selStart == selEnd) {
                return false;
            }

            ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class);

            if (link.length != 1) return false;

            link[0].onClick(widget);
            break;

        case UP:
            int beststart, bestend;

            beststart = -1;
            bestend = -1;

            for (int i = 0; i < candidates.length; i++) {
                int end = buffer.getSpanEnd(candidates[i]);

                if (end < selEnd || selStart == selEnd) {
                    if (end > bestend) {
                        beststart = buffer.getSpanStart(candidates[i]);
                        bestend = end;
                    }
                }
            }

            if (beststart >= 0) {
                Selection.setSelection(buffer, bestend, beststart);
                return true;
            }

            break;

        case DOWN:
            beststart = Integer.MAX_VALUE;
            bestend = Integer.MAX_VALUE;

            for (int i = 0; i < candidates.length; i++) {
                int start = buffer.getSpanStart(candidates[i]);

                if (start > selStart || selStart == selEnd) {
                    if (start < beststart) {
                        beststart = start;
                        bestend = buffer.getSpanEnd(candidates[i]);
                    }
                }
            }

            if (bestend < Integer.MAX_VALUE) {
                Selection.setSelection(buffer, beststart, bestend);
                return true;
            }

            break;
    }

    return false;
}
 
Example 8
Source Project: FoldText_Java   File: MyLinkMovementMethod.java    License: MIT License 4 votes vote down vote up
private boolean action(int what, TextView widget, Spannable buffer) {
    Layout layout = widget.getLayout();

    int padding = widget.getTotalPaddingTop() +
                  widget.getTotalPaddingBottom();
    int areaTop = widget.getScrollY();
    int areaBot = areaTop + widget.getHeight() - padding;

    int lineTop = layout.getLineForVertical(areaTop);
    int lineBot = layout.getLineForVertical(areaBot);

    int first = layout.getLineStart(lineTop);
    int last = layout.getLineEnd(lineBot);

    ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class);

    int a = Selection.getSelectionStart(buffer);
    int b = Selection.getSelectionEnd(buffer);

    int selStart = Math.min(a, b);
    int selEnd = Math.max(a, b);

    if (selStart < 0) {
        if (buffer.getSpanStart(FROM_BELOW) >= 0) {
            selStart = selEnd = buffer.length();
        }
    }

    if (selStart > last)
        selStart = selEnd = Integer.MAX_VALUE;
    if (selEnd < first)
        selStart = selEnd = -1;

    switch (what) {
    case CLICK:
        if (selStart == selEnd) {
            return false;
        }

        ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class);

        if (link.length != 1)
            return false;

        link[0].onClick(widget);
        break;

    case UP:
        int bestStart, bestEnd;

        bestStart = -1;
        bestEnd = -1;

        for (int i = 0; i < candidates.length; i++) {
            int end = buffer.getSpanEnd(candidates[i]);

            if (end < selEnd || selStart == selEnd) {
                if (end > bestEnd) {
                    bestStart = buffer.getSpanStart(candidates[i]);
                    bestEnd = end;
                }
            }
        }

        if (bestStart >= 0) {
            Selection.setSelection(buffer, bestEnd, bestStart);
            return true;
        }

        break;

    case DOWN:
        bestStart = Integer.MAX_VALUE;
        bestEnd = Integer.MAX_VALUE;

        for (int i = 0; i < candidates.length; i++) {
            int start = buffer.getSpanStart(candidates[i]);

            if (start > selStart || selStart == selEnd) {
                if (start < bestStart) {
                    bestStart = start;
                    bestEnd = buffer.getSpanEnd(candidates[i]);
                }
            }
        }

        if (bestEnd < Integer.MAX_VALUE) {
            Selection.setSelection(buffer, bestStart, bestEnd);
            return true;
        }

        break;
    }

    return false;
}
 
Example 9
private boolean action(int what, TextView widget, Spannable buffer) {
    Layout layout = widget.getLayout();

    int padding = widget.getTotalPaddingTop() +
            widget.getTotalPaddingBottom();
    int areatop = widget.getScrollY();
    int areabot = areatop + widget.getHeight() - padding;

    int linetop = layout.getLineForVertical(areatop);
    int linebot = layout.getLineForVertical(areabot);

    int first = layout.getLineStart(linetop);
    int last = layout.getLineEnd(linebot);

    ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class);

    int a = Selection.getSelectionStart(buffer);
    int b = Selection.getSelectionEnd(buffer);

    int selStart = Math.min(a, b);
    int selEnd = Math.max(a, b);

    if (selStart < 0) {
        if (buffer.getSpanStart(FROM_BELOW) >= 0) {
            selStart = selEnd = buffer.length();
        }
    }

    if (selStart > last)
        selStart = selEnd = Integer.MAX_VALUE;
    if (selEnd < first)
        selStart = selEnd = -1;

    switch (what) {
        case CLICK:
            if (selStart == selEnd) {
                return false;
            }

            ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class);

            if (link.length != 1)
                return false;

            link[0].onClick(widget);
            break;

        case UP:
            int beststart, bestend;

            beststart = -1;
            bestend = -1;

            for (ClickableSpan candidate1 : candidates) {
                int end = buffer.getSpanEnd(candidate1);

                if (end < selEnd || selStart == selEnd) {
                    if (end > bestend) {
                        beststart = buffer.getSpanStart(candidate1);
                        bestend = end;
                    }
                }
            }

            if (beststart >= 0) {
                Selection.setSelection(buffer, bestend, beststart);
                return true;
            }

            break;

        case DOWN:
            beststart = Integer.MAX_VALUE;
            bestend = Integer.MAX_VALUE;

            for (ClickableSpan candidate : candidates) {
                int start = buffer.getSpanStart(candidate);

                if (start > selStart || selStart == selEnd) {
                    if (start < beststart) {
                        beststart = start;
                        bestend = buffer.getSpanEnd(candidate);
                    }
                }
            }

            if (bestend < Integer.MAX_VALUE) {
                Selection.setSelection(buffer, beststart, bestend);
                return true;
            }

            break;
    }

    return false;
}
 
Example 10
Source Project: Nimingban   File: LinkMovementMethod2.java    License: Apache License 2.0 4 votes vote down vote up
private boolean action(int what, TextView widget, Spannable buffer) {
    Layout layout = widget.getLayout();

    int padding = widget.getTotalPaddingTop() +
            widget.getTotalPaddingBottom();
    int areatop = widget.getScrollY();
    int areabot = areatop + widget.getHeight() - padding;

    int linetop = layout.getLineForVertical(areatop);
    int linebot = layout.getLineForVertical(areabot);

    int first = layout.getLineStart(linetop);
    int last = layout.getLineEnd(linebot);

    ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class);

    int a = Selection.getSelectionStart(buffer);
    int b = Selection.getSelectionEnd(buffer);

    int selStart = Math.min(a, b);
    int selEnd = Math.max(a, b);

    if (selStart < 0) {
        if (buffer.getSpanStart(FROM_BELOW) >= 0) {
            selStart = selEnd = buffer.length();
        }
    }

    if (selStart > last)
        selStart = selEnd = Integer.MAX_VALUE;
    if (selEnd < first)
        selStart = selEnd = -1;

    switch (what) {
        case CLICK:
            if (selStart == selEnd) {
                return false;
            }

            ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class);

            if (link.length != 1)
                return false;

            link[0].onClick(widget);
            break;

        case UP:
            int beststart, bestend;

            beststart = -1;
            bestend = -1;

            for (int i = 0; i < candidates.length; i++) {
                int end = buffer.getSpanEnd(candidates[i]);

                if (end < selEnd || selStart == selEnd) {
                    if (end > bestend) {
                        beststart = buffer.getSpanStart(candidates[i]);
                        bestend = end;
                    }
                }
            }

            if (beststart >= 0) {
                Selection.setSelection(buffer, bestend, beststart);
                return true;
            }

            break;

        case DOWN:
            beststart = Integer.MAX_VALUE;
            bestend = Integer.MAX_VALUE;

            for (int i = 0; i < candidates.length; i++) {
                int start = buffer.getSpanStart(candidates[i]);

                if (start > selStart || selStart == selEnd) {
                    if (start < beststart) {
                        beststart = start;
                        bestend = buffer.getSpanEnd(candidates[i]);
                    }
                }
            }

            if (bestend < Integer.MAX_VALUE) {
                Selection.setSelection(buffer, beststart, bestend);
                return true;
            }

            break;
    }

    return false;
}
 
Example 11
private boolean action(int what, TextView widget, Spannable buffer) {
    Layout layout = widget.getLayout();

    int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom();
    int areatop = widget.getScrollY();
    int areabot = areatop + widget.getHeight() - padding;

    int linetop = layout.getLineForVertical(areatop);
    int linebot = layout.getLineForVertical(areabot);

    int first = layout.getLineStart(linetop);
    int last = layout.getLineEnd(linebot);

    MyURLSpan[] candidates = buffer.getSpans(first, last, MyURLSpan.class);

    int a = Selection.getSelectionStart(buffer);
    int b = Selection.getSelectionEnd(buffer);

    int selStart = Math.min(a, b);
    int selEnd = Math.max(a, b);

    if (selStart < 0) {
        if (buffer.getSpanStart(FROM_BELOW) >= 0) {
            selStart = selEnd = buffer.length();
        }
    }

    if (selStart > last) {
        selStart = selEnd = Integer.MAX_VALUE;
    }
    if (selEnd < first) {
        selStart = selEnd = -1;
    }

    switch (what) {
        case CLICK:
            if (selStart == selEnd) {
                return false;
            }

            MyURLSpan[] link = buffer.getSpans(selStart, selEnd, MyURLSpan.class);

            if (link.length != 1) {
                return false;
            }

            link[0].onClick(widget);
            break;

        case UP:
            int best_start = -1;
            int best_end = -1;

            for (MyURLSpan candidate1 : candidates) {
                int end = buffer.getSpanEnd(candidate1);

                if (end < selEnd || selStart == selEnd) {
                    if (end > best_end) {
                        best_start = buffer.getSpanStart(candidate1);
                        best_end = end;
                    }
                }
            }

            if (best_start >= 0) {
                Selection.setSelection(buffer, best_end, best_start);
                return true;
            }

            break;

        case DOWN:
            best_start = Integer.MAX_VALUE;
            best_end = Integer.MAX_VALUE;

            for (MyURLSpan candidate : candidates) {
                int start = buffer.getSpanStart(candidate);

                if (start > selStart || selStart == selEnd) {
                    if (start < best_start) {
                        best_start = start;
                        best_end = buffer.getSpanEnd(candidate);
                    }
                }
            }

            if (best_end < Integer.MAX_VALUE) {
                Selection.setSelection(buffer, best_start, best_end);
                return true;
            }

            break;
    }

    return false;
}
 
Example 12
Source Project: EhViewer   File: LinkMovementMethod2.java    License: Apache License 2.0 4 votes vote down vote up
private boolean action(int what, TextView widget, Spannable buffer) {
    Layout layout = widget.getLayout();

    int padding = widget.getTotalPaddingTop() +
            widget.getTotalPaddingBottom();
    int areatop = widget.getScrollY();
    int areabot = areatop + widget.getHeight() - padding;

    int linetop = layout.getLineForVertical(areatop);
    int linebot = layout.getLineForVertical(areabot);

    int first = layout.getLineStart(linetop);
    int last = layout.getLineEnd(linebot);

    ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class);

    int a = Selection.getSelectionStart(buffer);
    int b = Selection.getSelectionEnd(buffer);

    int selStart = Math.min(a, b);
    int selEnd = Math.max(a, b);

    if (selStart < 0) {
        if (buffer.getSpanStart(FROM_BELOW) >= 0) {
            selStart = selEnd = buffer.length();
        }
    }

    if (selStart > last)
        selStart = selEnd = Integer.MAX_VALUE;
    if (selEnd < first)
        selStart = selEnd = -1;

    switch (what) {
        case CLICK:
            if (selStart == selEnd) {
                return false;
            }

            ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class);

            if (link.length != 1)
                return false;

            link[0].onClick(widget);
            break;

        case UP:
            int beststart, bestend;

            beststart = -1;
            bestend = -1;

            for (int i = 0; i < candidates.length; i++) {
                int end = buffer.getSpanEnd(candidates[i]);

                if (end < selEnd || selStart == selEnd) {
                    if (end > bestend) {
                        beststart = buffer.getSpanStart(candidates[i]);
                        bestend = end;
                    }
                }
            }

            if (beststart >= 0) {
                Selection.setSelection(buffer, bestend, beststart);
                return true;
            }

            break;

        case DOWN:
            beststart = Integer.MAX_VALUE;
            bestend = Integer.MAX_VALUE;

            for (int i = 0; i < candidates.length; i++) {
                int start = buffer.getSpanStart(candidates[i]);

                if (start > selStart || selStart == selEnd) {
                    if (start < beststart) {
                        beststart = start;
                        bestend = buffer.getSpanEnd(candidates[i]);
                    }
                }
            }

            if (bestend < Integer.MAX_VALUE) {
                Selection.setSelection(buffer, beststart, bestend);
                return true;
            }

            break;
    }

    return false;
}
 
Example 13
private boolean action(int what, TextView widget, Spannable buffer) {
    Layout layout = widget.getLayout();

    int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom();
    int areatop = widget.getScrollY();
    int areabot = areatop + widget.getHeight() - padding;

    int linetop = layout.getLineForVertical(areatop);
    int linebot = layout.getLineForVertical(areabot);

    int first = layout.getLineStart(linetop);
    int last = layout.getLineEnd(linebot);

    MyURLSpan[] candidates = buffer.getSpans(first, last, MyURLSpan.class);

    int a = Selection.getSelectionStart(buffer);
    int b = Selection.getSelectionEnd(buffer);

    int selStart = Math.min(a, b);
    int selEnd = Math.max(a, b);

    if (selStart < 0) {
        if (buffer.getSpanStart(FROM_BELOW) >= 0) {
            selStart = selEnd = buffer.length();
        }
    }

    if (selStart > last) {
        selStart = selEnd = Integer.MAX_VALUE;
    }
    if (selEnd < first) {
        selStart = selEnd = -1;
    }

    switch (what) {
        case CLICK:
            if (selStart == selEnd) {
                return false;
            }

            MyURLSpan[] link = buffer.getSpans(selStart, selEnd, MyURLSpan.class);

            if (link.length != 1) {
                return false;
            }

            link[0].onClick(widget);
            break;

        case UP:
            int best_start = -1;
            int best_end = -1;

            for (MyURLSpan candidate1 : candidates) {
                int end = buffer.getSpanEnd(candidate1);

                if (end < selEnd || selStart == selEnd) {
                    if (end > best_end) {
                        best_start = buffer.getSpanStart(candidate1);
                        best_end = end;
                    }
                }
            }

            if (best_start >= 0) {
                Selection.setSelection(buffer, best_end, best_start);
                return true;
            }

            break;

        case DOWN:
            best_start = Integer.MAX_VALUE;
            best_end = Integer.MAX_VALUE;

            for (MyURLSpan candidate : candidates) {
                int start = buffer.getSpanStart(candidate);

                if (start > selStart || selStart == selEnd) {
                    if (start < best_start) {
                        best_start = start;
                        best_end = buffer.getSpanEnd(candidate);
                    }
                }
            }

            if (best_end < Integer.MAX_VALUE) {
                Selection.setSelection(buffer, best_start, best_end);
                return true;
            }

            break;
    }

    return false;
}