android - Select Text and show meaning as pop up in MUPDF -
i using mupdf library , added features manual zoom in, zoom out , rating, setting brightness. doing long press highlighted text , have show meaning database. trying 2 things 1 clipboard or emulateshiftheld below feature android ics , jellybean. can body suggest on whether 1 thing work feature trying. because on long press can't able capture text. suggestions helpful.
this id mupdf activity:
public void createui(bundle savedinstancestate) { if (core == null) return; // create ui. // first create document view making use of readerview's internal // gesture recognition mdocview = new readerview(this) { private boolean showbuttonsdisabled; public void onlongpress(motionevent e) { selectandcopytext(); //mdocview.getselecteditem(); //selecttext(mdocview); /*emulateshiftheld(layout); clipboard = (clipboardmanager) getsystemservice(clipboard_service); clipboard.settext(clipboard.gettext().tostring()); //layout.findall(clipboard.gettext().tostring()); //clipman.setprimaryclip(clipboard); //string s = (string) clipboard.gettext(); //system.out.println("fsfasd"+ s); charsequence pastedata=""; clipdata.item item = clipboard.getprimaryclip().getitemat(0); pastedata = item.gettext(); system.out.println("fsf"+pastedata);*/ //clipdata data = clipdata.newplaintext("", ""); ///system.out.println("sdf" + data); //copyclipboard(); } @suppresswarnings("deprecation") public void selectandcopytext() { try { method m = webview.class.getmethod("emulateshiftheld", boolean.type); m.invoke(mdocview, false); } catch (exception e) { e.printstacktrace(); // fallback keyevent shiftpressevent = new keyevent(0,0, keyevent.action_down,keyevent.keycode_shift_left,0,0); shiftpressevent.dispatch(this); } } public void starttextselection() { try { webview.class.getmethod("selecttext").invoke(this); } catch (exception e) { try { webview.class.getmethod("emulateshiftheld").invoke(this); } catch (exception e1) { keyevent shiftpressevent = new keyevent(0, 0, keyevent.action_down, keyevent.keycode_shift_left, 0, 0); shiftpressevent.dispatch(this); toast.maketext(getcontext(), r.string.app_name, toast.length_long).show(); } } } // stick document view , buttons overlay parent view //embedding reader view webview layout = new webview(this); layout.addview(mdocview); layout.addview(mbuttonsview); layout.setbackgroundresource(r.drawable.tiled_background); //layout.setbackgroundresource(r.color.canvas); setcontentview(layout);
}
this reader view:
public class readerview extends adapterview<adapter> implements gesturedetector.ongesturelistener, scalegesturedetector.onscalegesturelistener, runnable { private static final int moving_diagonally = 0; private static final int moving_left = 1; private static final int moving_right = 2; private static final int moving_up = 3; private static final int moving_down = 4; private static final int fling_margin = 100; private static final int gap = 20; private static final int scroll_speed = 2; private static final float min_scale = 1.0f; private static final float max_scale = 5.0f; private adapter madapter; private int mcurrent; // adapter's index current view private boolean mresetlayout; private final sparsearray<view> mchildviews = new sparsearray<view>(3); // shadows children of adapter view // more sensible indexing private final linkedlist<view> mviewcache = new linkedlist<view>(); private boolean muserinteracting; // whether user interacting private boolean mscaling; // whether user pinch zooming private float mscale = 1.0f; private int mxscroll; // scroll amounts recorded events. private int myscroll; // , accounted in onlayout private final gesturedetector mgesturedetector; private final scalegesturedetector mscalegesturedetector; private final scroller mscroller; private int mscrollerlastx; private int mscrollerlasty; private boolean mscrolldisabled; public readerview(context context) { super(context); mgesturedetector = new gesturedetector(this); mscalegesturedetector = new scalegesturedetector(context, this); mscroller = new scroller(context); } public readerview(context context, attributeset attrs) { super(context, attrs); mgesturedetector = new gesturedetector(this); mscalegesturedetector = new scalegesturedetector(context, this); mscroller = new scroller(context); } public readerview(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); mgesturedetector = new gesturedetector(this); mscalegesturedetector = new scalegesturedetector(context, this); mscroller = new scroller(context); } public int getdisplayedviewindex(togglebutton bookmark_page, string index_from) { if (index_from.equals("bookmark_button")) { system.out.println("view_if" + index_from); bookmark_page.setbackgroundresource(r.drawable.top3hover); } else { system.out.println("view_else" + index_from); bookmark_page.setbackgroundresource(r.drawable.top3); } return mcurrent; } public void setdisplayedviewindex(int i) { if (0 <= && < madapter.getcount()) { mcurrent = i; onmovetochild(i); mresetlayout = true; requestlayout(); } } public void movetonext() { view v = mchildviews.get(mcurrent+1); if (v != null) slideviewontoscreen(v); } public void movetoprevious() { view v = mchildviews.get(mcurrent-1); if (v != null) slideviewontoscreen(v); } public void resetupchildren() { (int = 0; < mchildviews.size(); i++) onchildsetup(mchildviews.keyat(i), mchildviews.valueat(i)); } protected void onchildsetup(int i, view v) {} protected void onmovetochild(int i) {} protected void onsettle(view v) {}; protected void onunsettle(view v) {}; protected void onnotinuse(view v) {}; public view getdisplayedview() { return mchildviews.get(mcurrent); } public void run() { if (!mscroller.isfinished()) { mscroller.computescrolloffset(); int x = mscroller.getcurrx(); int y = mscroller.getcurry(); mxscroll += x - mscrollerlastx; myscroll += y - mscrollerlasty; mscrollerlastx = x; mscrollerlasty = y; requestlayout(); post(this); } else if (!muserinteracting) { // end of inertial scroll , user not interacting. // layout stable view v = mchildviews.get(mcurrent); postsettle(v); } } public boolean ondown(motionevent arg0) { mscroller.forcefinished(true); return true; } public boolean onfling(motionevent e1, motionevent e2, float velocityx, float velocityy) { if (mscrolldisabled) return true; view v = mchildviews.get(mcurrent); if (v != null) { rect bounds = getscrollbounds(v); switch(directionoftravel(velocityx, velocityy)) { case moving_left: if (bounds.left >= 0) { // fling off left bring next view onto screen view vl = mchildviews.get(mcurrent+1); if (vl != null) { slideviewontoscreen(vl); return true; } } break; case moving_right: if (bounds.right <= 0) { // fling off right bring previous view onto screen view vr = mchildviews.get(mcurrent-1); if (vr != null) { slideviewontoscreen(vr); return true; } } break; } mscrollerlastx = mscrollerlasty = 0; // if page has been dragged out of bounds want spring // nicely. fling jumps bounds instantly, don't want use // fling in case. on other hand, don't want forgo fling // because of off-angle drag taking out of bounds other // in direction of drag, test out of bounds // in direction of travel. // // don't fling if out of bounds in direction more fling // margin rect expandedbounds = new rect(bounds); expandedbounds.inset(-fling_margin, -fling_margin); if(withinboundsindirectionoftravel(bounds, velocityx, velocityy) && expandedbounds.contains(0, 0)) { mscroller.fling(0, 0, (int)velocityx, (int)velocityy, bounds.left, bounds.right, bounds.top, bounds.bottom); post(this); } } return true; } public void onlongpress(motionevent e) { } public boolean onscroll(motionevent e1, motionevent e2, float distancex, float distancey) { if (!mscrolldisabled) { mxscroll -= distancex; myscroll -= distancey; requestlayout(); } return true; } public void onshowpress(motionevent e) { } public boolean onsingletapup(motionevent e) { return false; } public boolean onscale(scalegesturedetector detector) { float previousscale = mscale; mscale = math.min(math.max(mscale * detector.getscalefactor(), min_scale), max_scale); float factor = mscale/previousscale; view v = mchildviews.get(mcurrent); if (v != null) { // work out focus point relative view top left int viewfocusx = (int)detector.getfocusx() - (v.getleft() + mxscroll); int viewfocusy = (int)detector.getfocusy() - (v.gettop() + myscroll); // scroll maintain focus point mxscroll += viewfocusx - viewfocusx * factor; myscroll += viewfocusy - viewfocusy * factor; requestlayout(); } return true; } public boolean onscalebegin(scalegesturedetector detector) { mscaling = true; // ignore scroll amounts yet accounted for: // screen not showing effect of them, can // confuse user mxscroll = myscroll = 0; // avoid jump @ end of scaling disabling scrolling // until next start of gesture mscrolldisabled = true; return true; } public void onscaleend(scalegesturedetector detector) { mscaling = false; } @override public boolean ontouchevent(motionevent event) { //mscalegesturedetector.ontouchevent(event); if (!mscaling) mgesturedetector.ontouchevent(event); if (event.getactionmasked() == motionevent.action_down) { muserinteracting = true; } if (event.getactionmasked() == motionevent.action_up) { mscrolldisabled = false; muserinteracting = false; view v = mchildviews.get(mcurrent); if (v != null) { if (mscroller.isfinished()) { // if, @ end of user interaction, there no // current inertial scroll in operation animate // view onto screen if necessary slideviewontoscreen(v); } if (mscroller.isfinished()) { // if still there no inertial scroll in operation // layout stable postsettle(v); } } } requestlayout(); return true; } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); int n = getchildcount(); (int = 0; < n; i++) measureview(getchildat(i)); } @override protected void onlayout(boolean changed, int left, int top, int right, int bottom) { super.onlayout(changed, left, top, right, bottom); view cv = mchildviews.get(mcurrent); point cvoffset; if (!mresetlayout) { // move next or previous if current sufficiently off center if (cv != null) { cvoffset = subscreensizeoffset(cv); // cv.getright() may out of date current scale // add left measured width correct position if (cv.getleft() + cv.getmeasuredwidth() + cvoffset.x + gap/2 + mxscroll < getwidth()/2 && mcurrent + 1 < madapter.getcount()) { postunsettle(cv); // post invoke test end of animation // must set hq area new current view post(this); mcurrent++; onmovetochild(mcurrent); } if (cv.getleft() - cvoffset.x - gap/2 + mxscroll >= getwidth()/2 && mcurrent > 0) { postunsettle(cv); // post invoke test end of animation // must set hq area new current view post(this); mcurrent--; onmovetochild(mcurrent); } } // remove not needed children , hold them reuse int numchildren = mchildviews.size(); int childindices[] = new int[numchildren]; (int = 0; < numchildren; i++) childindices[i] = mchildviews.keyat(i); (int = 0; < numchildren; i++) { int ai = childindices[i]; if (ai < mcurrent - 1 || ai > mcurrent + 1) { view v = mchildviews.get(ai); onnotinuse(v); mviewcache.add(v); removeviewinlayout(v); mchildviews.remove(ai); } } } else { mresetlayout = false; mxscroll = myscroll = 0; // remove children , hold them reuse int numchildren = mchildviews.size(); (int = 0; < numchildren; i++) { view v = mchildviews.valueat(i); onnotinuse(v); mviewcache.add(v); removeviewinlayout(v); } mchildviews.clear(); // post ensure generation of hq area post(this); } // ensure current view present int cvleft, cvright, cvtop, cvbottom; boolean notpresent = (mchildviews.get(mcurrent) == null); cv = getorcreatechild(mcurrent); // when view sub-screen-size in either dimension // offset center within screen area, , keep // views spaced out cvoffset = subscreensizeoffset(cv); if (notpresent) { //main item not present. place top left cvleft = cvoffset.x; cvtop = cvoffset.y; } else { // main item present. adjust scroll offsets cvleft = cv.getleft() + mxscroll; cvtop = cv.gettop() + myscroll; } // scroll values have been accounted mxscroll = myscroll = 0; cvright = cvleft + cv.getmeasuredwidth(); cvbottom = cvtop + cv.getmeasuredheight(); if (!muserinteracting && mscroller.isfinished()) { point corr = getcorrection(getscrollbounds(cvleft, cvtop, cvright, cvbottom)); cvright += corr.x; cvleft += corr.x; cvtop += corr.y; cvbottom += corr.y; } else if (cv.getmeasuredheight() <= getheight()) { // when current view small screen in height, clamp // vertically point corr = getcorrection(getscrollbounds(cvleft, cvtop, cvright, cvbottom)); cvtop += corr.y; cvbottom += corr.y; } cv.layout(cvleft, cvtop, cvright, cvbottom); if (mcurrent > 0) { view lv = getorcreatechild(mcurrent - 1); point leftoffset = subscreensizeoffset(lv); int gap = leftoffset.x + gap + cvoffset.x; lv.layout(cvleft - lv.getmeasuredwidth() - gap, (cvbottom + cvtop - lv.getmeasuredheight())/2, cvleft - gap, (cvbottom + cvtop + lv.getmeasuredheight())/2); } if (mcurrent + 1 < madapter.getcount()) { view rv = getorcreatechild(mcurrent + 1); point rightoffset = subscreensizeoffset(rv); int gap = cvoffset.x + gap + rightoffset.x; rv.layout(cvright + gap, (cvbottom + cvtop - rv.getmeasuredheight())/2, cvright + rv.getmeasuredwidth() + gap, (cvbottom + cvtop + rv.getmeasuredheight())/2); } invalidate(); } @override public adapter getadapter() { return madapter; } @override public view getselectedview() { throw new unsupportedoperationexception("not supported"); } @override public void setadapter(adapter adapter) { madapter = adapter; mchildviews.clear(); removeallviewsinlayout(); requestlayout(); } @override public void setselection(int arg0) { throw new unsupportedoperationexception("not supported"); } private view getcached() { if (mviewcache.size() == 0) return null; else return mviewcache.removefirst(); } private view getorcreatechild(int i) { view v = mchildviews.get(i); if (v == null) { v = madapter.getview(i, getcached(), this); addandmeasurechild(i, v); } onchildsetup(i, v); return v; } private void addandmeasurechild(int i, view v) { layoutparams params = v.getlayoutparams(); if (params == null) { params = new layoutparams(layoutparams.match_parent, layoutparams.match_parent); } addviewinlayout(v, 0, params, true); mchildviews.append(i, v); // record view against it's adapter index measureview(v); } private void measureview(view v) { // see size view wants v.measure(view.measurespec.unspecified, view.measurespec.unspecified); // work out scale fit view float scale = math.min((float)getwidth()/(float)v.getmeasuredwidth(), (float)getheight()/(float)v.getmeasuredheight()); // use fitting values scaled our current scale factor v.measure(view.measurespec.exactly | (int)(v.getmeasuredwidth()*scale*mscale), view.measurespec.exactly | (int)(v.getmeasuredheight()*scale*mscale)); } private rect getscrollbounds(int left, int top, int right, int bottom) { int xmin = getwidth() - right; int xmax = -left; int ymin = getheight() - bottom; int ymax = -top; // in either dimension, if view smaller screen // constrain central if (xmin > xmax) xmin = xmax = (xmin + xmax)/2; if (ymin > ymax) ymin = ymax = (ymin + ymax)/2; return new rect(xmin, ymin, xmax, ymax); } private rect getscrollbounds(view v) { // there can scroll amounts not yet accounted in // onlayout, add mxscroll , myscroll current // positions when calculating bounds. return getscrollbounds(v.getleft() + mxscroll, v.gettop() + myscroll, v.getleft() + v.getmeasuredwidth() + mxscroll, v.gettop() + v.getmeasuredheight() + myscroll); } private point getcorrection(rect bounds) { return new point(math.min(math.max(0,bounds.left),bounds.right), math.min(math.max(0,bounds.top),bounds.bottom)); } private void postsettle(final view v) { // onsettle , onunsettle posted calls // wont executed until after system has performed // layout. post (new runnable() { public void run () { onsettle(v); } }); } private void postunsettle(final view v) { post (new runnable() { public void run () { onunsettle(v); } }); } private void slideviewontoscreen(view v) { point corr = getcorrection(getscrollbounds(v)); if (corr.x != 0 || corr.y != 0) { mscrollerlastx = mscrollerlasty = 0; mscroller.startscroll(0, 0, corr.x, corr.y, 400); post(this); } } private point subscreensizeoffset(view v) { return new point(math.max((getwidth() - v.getmeasuredwidth())/2, 0), math.max((getheight() - v.getmeasuredheight())/2, 0)); } private static int directionoftravel(float vx, float vy) { if (math.abs(vx) > 2 * math.abs(vy)) return (vx > 0) ? moving_right : moving_left; else if (math.abs(vy) > 2 * math.abs(vx)) return (vy > 0) ? moving_down : moving_up; else return moving_diagonally; } private static boolean withinboundsindirectionoftravel(rect bounds, float vx, float vy) { switch (directionoftravel(vx, vy)) { case moving_diagonally: return bounds.contains(0, 0); case moving_left: return bounds.left <= 0; case moving_right: return bounds.right >= 0; case moving_up: return bounds.top <= 0; case moving_down: return bounds.bottom >= 0; default: throw new nosuchelementexception(); } }
}
in reader class, make localbroadcast , implement in main activity public void onlongpress(motionevent e) {
intent next = new intent(stringconstant.search_word); next.putextra(stringconstant.double_tap_pdf, "true"); localbroadcastmanager.getinstance(mcontext).sendbroadcast(next); }
this broadcast reciever
private broadcastreceiver mpdfdoubleclickedreciever = new broadcastreceiver() {
@override public void onreceive(context context, intent intent) { if (intent != null) { log.e("", "mpdfdoubleclickedreciever called"); hideeditednotes(); mupdfview pageview = (mupdfview) mdocview.getdisplayedview(); boolean success = false; if (pageview != null) success = pageview.copyselection(); mtopbarmode = topbarmode.main; // showinfo(success ? // getstring(r.string.copied_to_clipboard) // : getstring(r.string.no_text_selected)); clipboardmanager clipboard = (clipboardmanager) getsystemservice(clipboard_service); selectedclipboardtext = ""; selectedclipboardtext = (string) clipboard.gettext(); // task here } } };
Comments
Post a Comment