1616package com .github .barteksc .pdfviewer ;
1717
1818import android .graphics .PointF ;
19+ import android .graphics .RectF ;
1920import android .view .GestureDetector ;
2021import android .view .MotionEvent ;
2122import android .view .ScaleGestureDetector ;
2223import android .view .View ;
2324
25+ import com .github .barteksc .pdfviewer .model .LinkTapEvent ;
2426import com .github .barteksc .pdfviewer .scroll .ScrollHandle ;
25- import com .github .barteksc .pdfviewer .listener .OnTapListener ;
27+ import com .shockwave .pdfium .PdfDocument ;
28+ import com .shockwave .pdfium .util .SizeF ;
2629
2730import static com .github .barteksc .pdfviewer .util .Constants .Pinch .MAXIMUM_ZOOM ;
2831import static com .github .barteksc .pdfviewer .util .Constants .Pinch .MINIMUM_ZOOM ;
@@ -39,51 +42,31 @@ class DragPinchManager implements GestureDetector.OnGestureListener, GestureDete
3942 private GestureDetector gestureDetector ;
4043 private ScaleGestureDetector scaleGestureDetector ;
4144
42- private boolean isSwipeEnabled ;
43-
44- private boolean swipeVertical ;
45-
4645 private boolean scrolling = false ;
4746 private boolean scaling = false ;
47+ private boolean enabled = false ;
4848
49- public DragPinchManager (PDFView pdfView , AnimationManager animationManager ) {
49+ DragPinchManager (PDFView pdfView , AnimationManager animationManager ) {
5050 this .pdfView = pdfView ;
5151 this .animationManager = animationManager ;
52- this .isSwipeEnabled = false ;
53- this .swipeVertical = pdfView .isSwipeVertical ();
5452 gestureDetector = new GestureDetector (pdfView .getContext (), this );
5553 scaleGestureDetector = new ScaleGestureDetector (pdfView .getContext (), this );
5654 pdfView .setOnTouchListener (this );
5755 }
5856
59- public void enableDoubletap (boolean enableDoubletap ) {
60- if (enableDoubletap ) {
61- gestureDetector .setOnDoubleTapListener (this );
62- } else {
63- gestureDetector .setOnDoubleTapListener (null );
64- }
65- }
66-
67- public boolean isZooming () {
68- return pdfView .isZooming ();
69- }
70-
71- private boolean isPageChange (float distance ) {
72- return Math .abs (distance ) > Math .abs (pdfView .toCurrentScale (swipeVertical ? pdfView .getOptimalPageHeight () : pdfView .getOptimalPageWidth ()) / 2 );
73- }
74-
75- public void setSwipeEnabled (boolean isSwipeEnabled ) {
76- this .isSwipeEnabled = isSwipeEnabled ;
57+ void enable () {
58+ enabled = true ;
7759 }
7860
79- public void setSwipeVertical ( boolean swipeVertical ) {
80- this . swipeVertical = swipeVertical ;
61+ void disable ( ) {
62+ enabled = false ;
8163 }
8264
8365 @ Override
8466 public boolean onSingleTapConfirmed (MotionEvent e ) {
85- OnTapListener onTapListener = pdfView .getOnTapListener ();
86- if (onTapListener == null || !onTapListener .onTap (e )) {
67+ boolean onTapHandled = pdfView .callbacks .callOnTap (e );
68+ boolean linkTapped = checkLinkTapped (e .getX (), e .getY ());
69+ if (!onTapHandled && !linkTapped ) {
8770 ScrollHandle ps = pdfView .getScrollHandle ();
8871 if (ps != null && !pdfView .documentFitsView ()) {
8972 if (!ps .shown ()) {
@@ -97,8 +80,47 @@ public boolean onSingleTapConfirmed(MotionEvent e) {
9780 return true ;
9881 }
9982
83+ private boolean checkLinkTapped (float x , float y ) {
84+ PdfFile pdfFile = pdfView .pdfFile ;
85+ float mappedX = -pdfView .getCurrentXOffset () + x ;
86+ float mappedY = -pdfView .getCurrentYOffset () + y ;
87+ int page = pdfFile .getPageAtOffset (pdfView .isSwipeVertical () ? mappedY : mappedX , pdfView .getZoom ());
88+ SizeF pageSize = pdfFile .getScaledPageSize (page , pdfView .getZoom ());
89+ int pageX , pageY ;
90+ if (pdfView .isSwipeVertical ()) {
91+ pageX = (int ) getSecondaryOffset (pageSize );
92+ pageY = (int ) pdfFile .getPageOffset (page , pdfView .getZoom ());
93+ } else {
94+ pageY = (int ) getSecondaryOffset (pageSize );
95+ pageX = (int ) pdfFile .getPageOffset (page , pdfView .getZoom ());
96+ }
97+ for (PdfDocument .Link link : pdfFile .getPageLinks (page )) {
98+ RectF mapped = pdfFile .mapRectToDevice (page , pageX , pageY , (int ) pageSize .getWidth (),
99+ (int ) pageSize .getHeight (), link .getBounds ());
100+ if (mapped .contains (mappedX , mappedY )) {
101+ pdfView .callbacks .callLinkHandler (new LinkTapEvent (x , y , mappedX , mappedY , mapped , link ));
102+ return true ;
103+ }
104+ }
105+ return false ;
106+ }
107+
108+ private float getSecondaryOffset (SizeF pageSize ) {
109+ if (pdfView .isSwipeVertical ()) {
110+ float maxWidth = pdfView .pdfFile .getMaxPageWidth ();
111+ return (pdfView .toCurrentScale (maxWidth ) - pageSize .getWidth ()) / 2 ; //x
112+ } else {
113+ float maxHeight = pdfView .pdfFile .getMaxPageHeight ();
114+ return (pdfView .toCurrentScale (maxHeight ) - pageSize .getHeight ()) / 2 ; //y
115+ }
116+ }
117+
100118 @ Override
101119 public boolean onDoubleTap (MotionEvent e ) {
120+ if (!pdfView .isDoubletapEnabled ()) {
121+ return false ;
122+ }
123+
102124 if (pdfView .getZoom () < pdfView .getMidZoom ()) {
103125 pdfView .zoomWithAnimation (e .getX (), e .getY (), pdfView .getMidZoom ());
104126 } else if (pdfView .getZoom () < pdfView .getMaxZoom ()) {
@@ -133,7 +155,7 @@ public boolean onSingleTapUp(MotionEvent e) {
133155 @ Override
134156 public boolean onScroll (MotionEvent e1 , MotionEvent e2 , float distanceX , float distanceY ) {
135157 scrolling = true ;
136- if (isZooming () || isSwipeEnabled ) {
158+ if (pdfView . isZooming () || pdfView . isSwipeEnabled () ) {
137159 pdfView .moveRelativeTo (-distanceX , -distanceY );
138160 }
139161 if (!scaling || pdfView .doRenderDuringScale ()) {
@@ -142,7 +164,7 @@ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float d
142164 return true ;
143165 }
144166
145- public void onScrollEnd (MotionEvent event ) {
167+ private void onScrollEnd (MotionEvent event ) {
146168 pdfView .loadPages ();
147169 hideHandle ();
148170 }
@@ -154,16 +176,20 @@ public void onLongPress(MotionEvent e) {
154176
155177 @ Override
156178 public boolean onFling (MotionEvent e1 , MotionEvent e2 , float velocityX , float velocityY ) {
179+ if (!pdfView .isSwipeEnabled ()) {
180+ return false ;
181+ }
157182 int xOffset = (int ) pdfView .getCurrentXOffset ();
158183 int yOffset = (int ) pdfView .getCurrentYOffset ();
159184
160185 float minX , minY ;
186+ PdfFile pdfFile = pdfView .pdfFile ;
161187 if (pdfView .isSwipeVertical ()) {
162- minX = -(pdfView .toCurrentScale (pdfView . getOptimalPageWidth ()) - pdfView .getWidth ());
163- minY = -(pdfView .calculateDocLength ( ) - pdfView .getHeight ());
188+ minX = -(pdfView .toCurrentScale (pdfFile . getMaxPageWidth ()) - pdfView .getWidth ());
189+ minY = -(pdfFile . getDocLen ( pdfView .getZoom () ) - pdfView .getHeight ());
164190 } else {
165- minX = -(pdfView .calculateDocLength ( ) - pdfView .getWidth ());
166- minY = -(pdfView .toCurrentScale (pdfView . getOptimalPageHeight ()) - pdfView .getHeight ());
191+ minX = -(pdfFile . getDocLen ( pdfView .getZoom () ) - pdfView .getWidth ());
192+ minY = -(pdfView .toCurrentScale (pdfFile . getMaxPageHeight ()) - pdfView .getHeight ());
167193 }
168194
169195 animationManager .startFlingAnimation (xOffset , yOffset , (int ) (velocityX ), (int ) (velocityY ),
@@ -200,6 +226,10 @@ public void onScaleEnd(ScaleGestureDetector detector) {
200226
201227 @ Override
202228 public boolean onTouch (View v , MotionEvent event ) {
229+ if (!enabled ) {
230+ return false ;
231+ }
232+
203233 boolean retVal = scaleGestureDetector .onTouchEvent (event );
204234 retVal = gestureDetector .onTouchEvent (event ) || retVal ;
205235
@@ -213,8 +243,9 @@ public boolean onTouch(View v, MotionEvent event) {
213243 }
214244
215245 private void hideHandle () {
216- if (pdfView .getScrollHandle () != null && pdfView .getScrollHandle ().shown ()) {
217- pdfView .getScrollHandle ().hideDelayed ();
246+ ScrollHandle scrollHandle = pdfView .getScrollHandle ();
247+ if (scrollHandle != null && scrollHandle .shown ()) {
248+ scrollHandle .hideDelayed ();
218249 }
219250 }
220251}
0 commit comments