/* * Firetweet - Twitter client for Android * * Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.getlantern.firetweet.text.method; import android.text.Layout; import android.text.NoCopySpan; import android.text.Selection; import android.text.Spannable; import android.text.method.ArrowKeyMovementMethod; import android.text.method.MovementMethod; import android.text.style.ClickableSpan; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; /** * A movement method that traverses links in the text buffer and scrolls if * necessary. Supports clicking on links with DPad Center or Enter. */ public class StatusContentMovementMethod extends ArrowKeyMovementMethod { private static StatusContentMovementMethod sInstance; private static Object FROM_BELOW = new NoCopySpan.Concrete(); @Override public void initialize(final TextView widget, final Spannable text) { Selection.removeSelection(text); text.removeSpan(FROM_BELOW); } @Override public void onTakeFocus(final TextView view, final Spannable text, final int dir) { Selection.removeSelection(text); if ((dir & View.FOCUS_BACKWARD) != 0) { text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT); } else { text.removeSpan(FROM_BELOW); } } @Override public boolean onTouchEvent(final TextView widget, final Spannable buffer, final MotionEvent event) { final int action = event.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { int x = (int) event.getX(); int y = (int) event.getY(); x -= widget.getTotalPaddingLeft(); y -= widget.getTotalPaddingTop(); x += widget.getScrollX(); y += widget.getScrollY(); final Layout layout = widget.getLayout(); final int line = layout.getLineForVertical(y); final int off = layout.getOffsetForHorizontal(line, x); final ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); if (link.length != 0) { if (action == MotionEvent.ACTION_UP) { link[0].onClick(widget); } else if (action == MotionEvent.ACTION_DOWN) { Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); } return true; } else { Selection.removeSelection(buffer); } } return super.onTouchEvent(widget, buffer, event); } public static MovementMethod getInstance() { if (sInstance == null) { sInstance = new StatusContentMovementMethod(); } return sInstance; } }