Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
df433a70
Kaydet (Commit)
df433a70
authored
Eyl 24, 2014
tarafından
Tomaž Vajngerl
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
android: upgrade PanZoomController - add configurable zoom limits
Change-Id: I19815f58af4d060cffe515829a2a5472d32bf83c
üst
0455b3d4
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
285 additions
and
167 deletions
+285
-167
LibreOfficeMainActivity.java
...id3/src/java/org/libreoffice/LibreOfficeMainActivity.java
+1
-0
DisplayPortCalculator.java
...src/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java
+1
-1
GeckoLayerClient.java
...oid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+4
-4
LayerController.java
...roid3/src/java/org/mozilla/gecko/gfx/LayerController.java
+60
-46
LayerView.java
.../LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java
+6
-40
TouchEventHandler.java
...id3/src/java/org/mozilla/gecko/gfx/TouchEventHandler.java
+48
-6
PanZoomController.java
...oid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
+165
-70
No files found.
android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
Dosyayı görüntüle @
df433a70
...
@@ -118,6 +118,7 @@ public class LibreOfficeMainActivity extends Activity {
...
@@ -118,6 +118,7 @@ public class LibreOfficeMainActivity extends Activity {
}
}
mLayerController
=
new
LayerController
(
this
);
mLayerController
=
new
LayerController
(
this
);
mLayerController
.
setAllowZoom
(
true
);
mLayerClient
=
new
GeckoLayerClient
(
this
);
mLayerClient
=
new
GeckoLayerClient
(
this
);
mLayerController
.
setLayerClient
(
mLayerClient
);
mLayerController
.
setLayerClient
(
mLayerClient
);
mGeckoLayout
.
addView
(
mLayerController
.
getView
(),
0
);
mGeckoLayout
.
addView
(
mLayerController
.
getView
(),
0
);
...
...
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java
Dosyayı görüntüle @
df433a70
...
@@ -36,7 +36,7 @@ final class DisplayPortCalculator {
...
@@ -36,7 +36,7 @@ final class DisplayPortCalculator {
private
static
final
String
PREF_DISPLAYPORT_VB_DANGER_Y_INCR
=
"gfx.displayport.strategy_vb.danger_y_incr"
;
private
static
final
String
PREF_DISPLAYPORT_VB_DANGER_Y_INCR
=
"gfx.displayport.strategy_vb.danger_y_incr"
;
private
static
final
String
PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD
=
"gfx.displayport.strategy_pb.threshold"
;
private
static
final
String
PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD
=
"gfx.displayport.strategy_pb.threshold"
;
private
static
DisplayPortStrategy
sStrategy
=
new
NoMargi
nStrategy
(
null
);
private
static
DisplayPortStrategy
sStrategy
=
new
DynamicResolutio
nStrategy
(
null
);
static
DisplayPortMetrics
calculate
(
ImmutableViewportMetrics
metrics
,
PointF
velocity
)
{
static
DisplayPortMetrics
calculate
(
ImmutableViewportMetrics
metrics
,
PointF
velocity
)
{
return
sStrategy
.
calculate
(
metrics
,
(
velocity
==
null
?
ZERO_VELOCITY
:
velocity
));
return
sStrategy
.
calculate
(
metrics
,
(
velocity
==
null
?
ZERO_VELOCITY
:
velocity
));
...
...
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
Dosyayı görüntüle @
df433a70
...
@@ -172,7 +172,7 @@ public class GeckoLayerClient implements LayerView.Listener {
...
@@ -172,7 +172,7 @@ public class GeckoLayerClient implements LayerView.Listener {
// Don't adjust page size when zooming unless zoom levels are
// Don't adjust page size when zooming unless zoom levels are
// approximately equal.
// approximately equal.
if
(
FloatUtils
.
fuzzyEquals
(
mLayerController
.
getZoomFactor
(),
mGeckoViewport
.
getZoomFactor
()))
{
if
(
FloatUtils
.
fuzzyEquals
(
mLayerController
.
getZoomFactor
(),
mGeckoViewport
.
getZoomFactor
()))
{
mLayerController
.
setPageSize
(
mGeckoViewport
.
getPageSize
());
mLayerController
.
setPageSize
(
mGeckoViewport
.
getPageSize
()
,
mGeckoViewport
.
getPageSize
()
);
}
}
}
else
{
}
else
{
mLayerController
.
setViewportMetrics
(
mGeckoViewport
);
mLayerController
.
setViewportMetrics
(
mGeckoViewport
);
...
@@ -254,7 +254,7 @@ public class GeckoLayerClient implements LayerView.Listener {
...
@@ -254,7 +254,7 @@ public class GeckoLayerClient implements LayerView.Listener {
float
ourZoom
=
mLayerController
.
getZoomFactor
();
float
ourZoom
=
mLayerController
.
getZoomFactor
();
pageWidth
=
pageWidth
*
ourZoom
/
zoom
;
pageWidth
=
pageWidth
*
ourZoom
/
zoom
;
pageHeight
=
pageHeight
*
ourZoom
/
zoom
;
pageHeight
=
pageHeight
*
ourZoom
/
zoom
;
mLayerController
.
setPageSize
(
new
FloatSize
(
pageWidth
,
pageHeight
));
mLayerController
.
setPageSize
(
new
FloatSize
(
pageWidth
,
pageHeight
)
,
new
FloatSize
(
pageWidth
,
pageHeight
)
);
// Here the page size of the document has changed, but the document being displayed
// Here the page size of the document has changed, but the document being displayed
// is still the same. Therefore, we don't need to send anything to browser.js; any
// is still the same. Therefore, we don't need to send anything to browser.js; any
// changes we need to make to the display port will get sent the next time we call
// changes we need to make to the display port will get sent the next time we call
...
@@ -296,13 +296,13 @@ public class GeckoLayerClient implements LayerView.Listener {
...
@@ -296,13 +296,13 @@ public class GeckoLayerClient implements LayerView.Listener {
}
}
@Override
@Override
public
void
compositionResumeRequested
()
{
public
void
compositionResumeRequested
(
int
width
,
int
height
)
{
}
}
@Override
@Override
public
void
surfaceChanged
(
int
width
,
int
height
)
{
public
void
surfaceChanged
(
int
width
,
int
height
)
{
compositionResumeRequested
();
compositionResumeRequested
(
width
,
height
);
renderRequested
();
renderRequested
();
}
}
...
...
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
Dosyayı görüntüle @
df433a70
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* This Source Code Form is subject to the terms of the Mozilla Public
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
* License, v. 2.0. If a copy of the MPL was not distributed with this
*
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
* Chris Lord <chrislord.net@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package
org
.
mozilla
.
gecko
.
gfx
;
package
org
.
mozilla
.
gecko
.
gfx
;
...
@@ -42,6 +9,7 @@ import android.content.Context;
...
@@ -42,6 +9,7 @@ import android.content.Context;
import
android.content.res.Resources
;
import
android.content.res.Resources
;
import
android.graphics.Bitmap
;
import
android.graphics.Bitmap
;
import
android.graphics.BitmapFactory
;
import
android.graphics.BitmapFactory
;
import
android.graphics.Color
;
import
android.graphics.PointF
;
import
android.graphics.PointF
;
import
android.graphics.RectF
;
import
android.graphics.RectF
;
import
android.view.GestureDetector
;
import
android.view.GestureDetector
;
...
@@ -49,8 +17,6 @@ import android.view.GestureDetector;
...
@@ -49,8 +17,6 @@ import android.view.GestureDetector;
import
org.mozilla.gecko.ui.PanZoomController
;
import
org.mozilla.gecko.ui.PanZoomController
;
import
org.mozilla.gecko.ui.SimpleScaleGestureDetector
;
import
org.mozilla.gecko.ui.SimpleScaleGestureDetector
;
import
java.util.regex.Pattern
;
/**
/**
* The layer controller manages a tile that represents the visible page. It does panning and
* The layer controller manages a tile that represents the visible page. It does panning and
* zooming natively by delegating to a panning/zooming controller. Touch events can be dispatched
* zooming natively by delegating to a panning/zooming controller. Touch events can be dispatched
...
@@ -87,12 +53,15 @@ public class LayerController {
...
@@ -87,12 +53,15 @@ public class LayerController {
private
GeckoLayerClient
mLayerClient
;
/* The layer client. */
private
GeckoLayerClient
mLayerClient
;
/* The layer client. */
/* The new color for the checkerboard. */
/* The new color for the checkerboard. */
private
int
mCheckerboardColor
;
private
int
mCheckerboardColor
=
Color
.
WHITE
;
private
boolean
mCheckerboardShouldShowChecks
;
private
boolean
mCheckerboardShouldShowChecks
;
private
boolean
mForceRedraw
;
private
boolean
mAllowZoom
;
private
float
mDefaultZoom
;
private
float
mMinZoom
;
private
float
mMaxZoom
;
private
static
Pattern
sColorPattern
;
private
boolean
mForceRedraw
;
public
LayerController
(
Context
context
)
{
public
LayerController
(
Context
context
)
{
mContext
=
context
;
mContext
=
context
;
...
@@ -124,6 +93,10 @@ public class LayerController {
...
@@ -124,6 +93,10 @@ public class LayerController {
return
mViewportMetrics
.
getViewport
();
return
mViewportMetrics
.
getViewport
();
}
}
public
RectF
getCssViewport
()
{
return
mViewportMetrics
.
getCssViewport
();
}
public
FloatSize
getViewportSize
()
{
public
FloatSize
getViewportSize
()
{
return
mViewportMetrics
.
getSize
();
return
mViewportMetrics
.
getSize
();
}
}
...
@@ -132,6 +105,10 @@ public class LayerController {
...
@@ -132,6 +105,10 @@ public class LayerController {
return
mViewportMetrics
.
getPageSize
();
return
mViewportMetrics
.
getPageSize
();
}
}
public
FloatSize
getCssPageSize
()
{
return
mViewportMetrics
.
getCssPageSize
();
}
public
PointF
getOrigin
()
{
public
PointF
getOrigin
()
{
return
mViewportMetrics
.
getOrigin
();
return
mViewportMetrics
.
getOrigin
();
}
}
...
@@ -189,12 +166,12 @@ public class LayerController {
...
@@ -189,12 +166,12 @@ public class LayerController {
}
}
/** Sets the current page size. You must hold the monitor while calling this. */
/** Sets the current page size. You must hold the monitor while calling this. */
public
void
setPageSize
(
FloatSize
size
)
{
public
void
setPageSize
(
FloatSize
size
,
FloatSize
cssSize
)
{
if
(
mViewportMetrics
.
get
PageSize
().
fuzzyEquals
(
s
ize
))
if
(
mViewportMetrics
.
get
CssPageSize
().
equals
(
cssS
ize
))
return
;
return
;
ViewportMetrics
viewportMetrics
=
new
ViewportMetrics
(
mViewportMetrics
);
ViewportMetrics
viewportMetrics
=
new
ViewportMetrics
(
mViewportMetrics
);
viewportMetrics
.
setPageSize
(
size
,
s
ize
);
viewportMetrics
.
setPageSize
(
size
,
cssS
ize
);
mViewportMetrics
=
new
ImmutableViewportMetrics
(
viewportMetrics
);
mViewportMetrics
=
new
ImmutableViewportMetrics
(
viewportMetrics
);
// Page size is owned by the layer client, so no need to notify it of
// Page size is owned by the layer client, so no need to notify it of
...
@@ -294,8 +271,9 @@ public class LayerController {
...
@@ -294,8 +271,9 @@ public class LayerController {
* correct.
* correct.
*/
*/
public
PointF
convertViewPointToLayerPoint
(
PointF
viewPoint
)
{
public
PointF
convertViewPointToLayerPoint
(
PointF
viewPoint
)
{
if
(
m
RootLayer
==
null
)
if
(
m
LayerClient
==
null
)
{
return
null
;
return
null
;
}
ImmutableViewportMetrics
viewportMetrics
=
mViewportMetrics
;
ImmutableViewportMetrics
viewportMetrics
=
mViewportMetrics
;
PointF
origin
=
viewportMetrics
.
getOrigin
();
PointF
origin
=
viewportMetrics
.
getOrigin
();
...
@@ -337,5 +315,41 @@ public class LayerController {
...
@@ -337,5 +315,41 @@ public class LayerController {
mCheckerboardColor
=
newColor
;
mCheckerboardColor
=
newColor
;
mView
.
requestRender
();
mView
.
requestRender
();
}
}
}
public
void
setAllowZoom
(
final
boolean
aValue
)
{
mAllowZoom
=
aValue
;
mView
.
post
(
new
Runnable
()
{
public
void
run
()
{
mView
.
getTouchEventHandler
().
setDoubleTapEnabled
(
aValue
);
}
});
}
public
boolean
getAllowZoom
()
{
return
mAllowZoom
;
}
public
void
setDefaultZoom
(
float
aValue
)
{
mDefaultZoom
=
aValue
;
}
public
float
getDefaultZoom
()
{
return
mDefaultZoom
;
}
public
void
setMinZoom
(
float
aValue
)
{
mMinZoom
=
aValue
;
}
public
float
getMinZoom
()
{
return
mMinZoom
;
}
public
void
setMaxZoom
(
float
aValue
)
{
mMaxZoom
=
aValue
;
}
public
float
getMaxZoom
()
{
return
mMaxZoom
;
}
}
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java
Dosyayı görüntüle @
df433a70
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* This Source Code Form is subject to the terms of the Mozilla Public
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
* License, v. 2.0. If a copy of the MPL was not distributed with this
*
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
* Arkady Blyakher <rkadyb@mit.edu>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package
org
.
mozilla
.
gecko
.
gfx
;
package
org
.
mozilla
.
gecko
.
gfx
;
...
@@ -42,7 +9,6 @@ package org.mozilla.gecko.gfx;
...
@@ -42,7 +9,6 @@ package org.mozilla.gecko.gfx;
import
android.content.Context
;
import
android.content.Context
;
import
android.graphics.Bitmap
;
import
android.graphics.Bitmap
;
import
android.graphics.PixelFormat
;
import
android.graphics.PixelFormat
;
import
android.opengl.GLSurfaceView
;
import
android.util.Log
;
import
android.util.Log
;
import
android.view.KeyEvent
;
import
android.view.KeyEvent
;
import
android.view.MotionEvent
;
import
android.view.MotionEvent
;
...
@@ -227,7 +193,7 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback {
...
@@ -227,7 +193,7 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback {
}
}
public
GLSurfaceView
.
Renderer
getRenderer
()
{
public
Layer
Renderer
getRenderer
()
{
return
mRenderer
;
return
mRenderer
;
}
}
...
@@ -235,7 +201,7 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback {
...
@@ -235,7 +201,7 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback {
mListener
=
listener
;
mListener
=
listener
;
}
}
public
synchronized
GLController
getGLController
()
{
public
GLController
getGLController
()
{
return
mGLController
;
return
mGLController
;
}
}
...
@@ -288,7 +254,7 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback {
...
@@ -288,7 +254,7 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback {
public
interface
Listener
{
public
interface
Listener
{
void
renderRequested
();
void
renderRequested
();
void
compositionPauseRequested
();
void
compositionPauseRequested
();
void
compositionResumeRequested
();
void
compositionResumeRequested
(
int
width
,
int
height
);
void
surfaceChanged
(
int
width
,
int
height
);
void
surfaceChanged
(
int
width
,
int
height
);
}
}
...
...
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TouchEventHandler.java
Dosyayı görüntüle @
df433a70
...
@@ -10,8 +10,8 @@ import android.os.SystemClock;
...
@@ -10,8 +10,8 @@ import android.os.SystemClock;
import
android.view.GestureDetector
;
import
android.view.GestureDetector
;
import
android.view.MotionEvent
;
import
android.view.MotionEvent
;
import
android.view.View.OnTouchListener
;
import
android.view.View.OnTouchListener
;
import
android.view.ViewConfiguration
;
import
org.mozilla.gecko.ui.PanZoomController
;
import
org.mozilla.gecko.ui.SimpleScaleGestureDetector
;
import
org.mozilla.gecko.ui.SimpleScaleGestureDetector
;
import
java.util.LinkedList
;
import
java.util.LinkedList
;
...
@@ -41,18 +41,24 @@ import java.util.Queue;
...
@@ -41,18 +41,24 @@ import java.util.Queue;
* at some point after the first or second event in the block is processed in Gecko.
* at some point after the first or second event in the block is processed in Gecko.
* This code assumes we get EXACTLY ONE default-prevented notification for each block
* This code assumes we get EXACTLY ONE default-prevented notification for each block
* of events.
* of events.
*
* Note that even if all events are default-prevented, we still send specific types
* of notifications to the pan/zoom controller. The notifications are needed
* to respond to user actions a timely manner regardless of default-prevention,
* and fix issues like bug 749384.
*/
*/
public
final
class
TouchEventHandler
{
public
final
class
TouchEventHandler
{
private
static
final
String
LOGTAG
=
"GeckoTouchEventHandler"
;
private
static
final
String
LOGTAG
=
"GeckoTouchEventHandler"
;
// The time limit for listeners to respond with preventDefault on touchevents
// The time limit for listeners to respond with preventDefault on touchevents
// before we begin panning the page
// before we begin panning the page
private
final
int
EVENT_LISTENER_TIMEOUT
=
ViewConfiguration
.
getLongPressTimeout
()
;
private
final
int
EVENT_LISTENER_TIMEOUT
=
200
;
private
final
LayerView
mView
;
private
final
LayerView
mView
;
private
final
LayerController
mController
;
private
final
GestureDetector
mGestureDetector
;
private
final
GestureDetector
mGestureDetector
;
private
final
SimpleScaleGestureDetector
mScaleGestureDetector
;
private
final
SimpleScaleGestureDetector
mScaleGestureDetector
;
private
final
PanZoomController
mPanZoomController
;
private
final
GestureDetector
.
OnDoubleTapListener
mDoubleTapListener
;
// the queue of events that we are holding on to while waiting for a preventDefault
// the queue of events that we are holding on to while waiting for a preventDefault
// notification
// notification
...
@@ -119,15 +125,16 @@ public final class TouchEventHandler {
...
@@ -119,15 +125,16 @@ public final class TouchEventHandler {
TouchEventHandler
(
Context
context
,
LayerView
view
,
LayerController
controller
)
{
TouchEventHandler
(
Context
context
,
LayerView
view
,
LayerController
controller
)
{
mView
=
view
;
mView
=
view
;
mController
=
controller
;
mEventQueue
=
new
LinkedList
<
MotionEvent
>();
mEventQueue
=
new
LinkedList
<
MotionEvent
>();
mGestureDetector
=
new
GestureDetector
(
context
,
controller
.
getGestureListener
());
mGestureDetector
=
new
GestureDetector
(
context
,
controller
.
getGestureListener
());
mScaleGestureDetector
=
new
SimpleScaleGestureDetector
(
controller
.
getScaleGestureListener
());
mScaleGestureDetector
=
new
SimpleScaleGestureDetector
(
controller
.
getScaleGestureListener
());
mPanZoomController
=
controller
.
getPanZoomController
();
mListenerTimeoutProcessor
=
new
ListenerTimeoutProcessor
();
mListenerTimeoutProcessor
=
new
ListenerTimeoutProcessor
();
mDispatchEvents
=
true
;
mDispatchEvents
=
true
;
mGestureDetector
.
setOnDoubleTapListener
(
controller
.
getDoubleTapListener
());
mDoubleTapListener
=
controller
.
getDoubleTapListener
();
setDoubleTapEnabled
(
true
);
}
}
/* This function MUST be called on the UI thread */
/* This function MUST be called on the UI thread */
...
@@ -142,7 +149,18 @@ public final class TouchEventHandler {
...
@@ -142,7 +149,18 @@ public final class TouchEventHandler {
if
(
isDownEvent
(
event
))
{
if
(
isDownEvent
(
event
))
{
// this is the start of a new block of events! whee!
// this is the start of a new block of events! whee!
mHoldInQueue
=
mWaitForTouchListeners
;
mHoldInQueue
=
mWaitForTouchListeners
;
// Set mDispatchEvents to true so that we are guaranteed to either queue these
// events or dispatch them. The only time we should not do either is once we've
// heard back from content to preventDefault this block.
mDispatchEvents
=
true
;
if
(
mHoldInQueue
)
{
if
(
mHoldInQueue
)
{
// if the new block we are starting is the current block (i.e. there are no
// other blocks waiting in the queue, then we should let the pan/zoom controller
// know we are waiting for the touch listeners to run
if
(
mEventQueue
.
isEmpty
())
{
mPanZoomController
.
waitingForTouchListeners
(
event
);
}
// if we're holding the events in the queue, set the timeout so that
// if we're holding the events in the queue, set the timeout so that
// we dispatch these events if we don't get a default-prevented notification
// we dispatch these events if we don't get a default-prevented notification
mView
.
postDelayed
(
mListenerTimeoutProcessor
,
EVENT_LISTENER_TIMEOUT
);
mView
.
postDelayed
(
mListenerTimeoutProcessor
,
EVENT_LISTENER_TIMEOUT
);
...
@@ -164,6 +182,8 @@ public final class TouchEventHandler {
...
@@ -164,6 +182,8 @@ public final class TouchEventHandler {
mEventQueue
.
add
(
MotionEvent
.
obtain
(
event
));
mEventQueue
.
add
(
MotionEvent
.
obtain
(
event
));
}
else
if
(
mDispatchEvents
)
{
}
else
if
(
mDispatchEvents
)
{
dispatchEvent
(
event
);
dispatchEvent
(
event
);
}
else
if
(
touchFinished
(
event
))
{
mPanZoomController
.
preventedTouchFinished
();
}
}
// notify gecko of the event
// notify gecko of the event
...
@@ -192,6 +212,11 @@ public final class TouchEventHandler {
...
@@ -192,6 +212,11 @@ public final class TouchEventHandler {
mProcessingBalance
--;
mProcessingBalance
--;
}
}
/* This function MUST be called on the UI thread. */
public
void
setDoubleTapEnabled
(
boolean
aValue
)
{
mGestureDetector
.
setOnDoubleTapListener
(
aValue
?
mDoubleTapListener
:
null
);
}
/* This function MUST be called on the UI thread. */
/* This function MUST be called on the UI thread. */
public
void
setWaitForTouchListeners
(
boolean
aValue
)
{
public
void
setWaitForTouchListeners
(
boolean
aValue
)
{
mWaitForTouchListeners
=
aValue
;
mWaitForTouchListeners
=
aValue
;
...
@@ -207,18 +232,32 @@ public final class TouchEventHandler {
...
@@ -207,18 +232,32 @@ public final class TouchEventHandler {
return
(
action
==
MotionEvent
.
ACTION_DOWN
||
action
==
MotionEvent
.
ACTION_POINTER_DOWN
);
return
(
action
==
MotionEvent
.
ACTION_DOWN
||
action
==
MotionEvent
.
ACTION_POINTER_DOWN
);
}
}
private
boolean
touchFinished
(
MotionEvent
event
)
{
int
action
=
(
event
.
getAction
()
&
MotionEvent
.
ACTION_MASK
);
return
(
action
==
MotionEvent
.
ACTION_UP
||
action
==
MotionEvent
.
ACTION_CANCEL
);
}
/**
/**
* Dispatch the event to the gesture detectors and the pan/zoom controller.
* Dispatch the event to the gesture detectors and the pan/zoom controller.
*/
*/
private
void
dispatchEvent
(
MotionEvent
event
)
{
private
void
dispatchEvent
(
MotionEvent
event
)
{
if
(
mGestureDetector
.
onTouchEvent
(
event
))
{
if
(
mGestureDetector
.
onTouchEvent
(
event
))
{
// An up/cancel event should get passed to both detectors, in
// case it comes from a pointer the scale detector is tracking.
switch
(
event
.
getAction
()
&
MotionEvent
.
ACTION_MASK
)
{
case
MotionEvent
.
ACTION_POINTER_UP
:
case
MotionEvent
.
ACTION_UP
:
case
MotionEvent
.
ACTION_CANCEL
:
break
;
default
:
return
;
return
;
}
}
}
mScaleGestureDetector
.
onTouchEvent
(
event
);
mScaleGestureDetector
.
onTouchEvent
(
event
);
if
(
mScaleGestureDetector
.
isInProgress
())
{
if
(
mScaleGestureDetector
.
isInProgress
())
{
return
;
return
;
}
}
m
Controller
.
getPanZoomController
()
.
onTouchEvent
(
event
);
m
PanZoomController
.
onTouchEvent
(
event
);
}
}
/**
/**
...
@@ -244,6 +283,8 @@ public final class TouchEventHandler {
...
@@ -244,6 +283,8 @@ public final class TouchEventHandler {
// default-prevented.
// default-prevented.
if
(
allowDefaultAction
)
{
if
(
allowDefaultAction
)
{
dispatchEvent
(
event
);
dispatchEvent
(
event
);
}
else
if
(
touchFinished
(
event
))
{
mPanZoomController
.
preventedTouchFinished
();
}
}
event
=
mEventQueue
.
peek
();
event
=
mEventQueue
.
peek
();
if
(
event
==
null
)
{
if
(
event
==
null
)
{
...
@@ -259,6 +300,7 @@ public final class TouchEventHandler {
...
@@ -259,6 +300,7 @@ public final class TouchEventHandler {
if
(
isDownEvent
(
event
))
{
if
(
isDownEvent
(
event
))
{
// we have finished processing the block we were interested in.
// we have finished processing the block we were interested in.
// now we wait for the next call to processEventBlock
// now we wait for the next call to processEventBlock
mPanZoomController
.
waitingForTouchListeners
(
event
);
break
;
break
;
}
}
// pop the event we peeked above, as it is still part of the block and
// pop the event we peeked above, as it is still part of the block and
...
...
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
Dosyayı görüntüle @
df433a70
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* This Source Code Form is subject to the terms of the Mozilla Public
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
* License, v. 2.0. If a copy of the MPL was not distributed with this
*
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
* Kartikaya Gupta <kgupta@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package
org
.
mozilla
.
gecko
.
ui
;
package
org
.
mozilla
.
gecko
.
ui
;
...
@@ -52,6 +19,8 @@ import org.mozilla.gecko.gfx.LayerController;
...
@@ -52,6 +19,8 @@ import org.mozilla.gecko.gfx.LayerController;
import
org.mozilla.gecko.gfx.ViewportMetrics
;
import
org.mozilla.gecko.gfx.ViewportMetrics
;
import
org.mozilla.gecko.util.FloatUtils
;
import
org.mozilla.gecko.util.FloatUtils
;
import
java.util.Arrays
;
import
java.util.StringTokenizer
;
import
java.util.Timer
;
import
java.util.Timer
;
import
java.util.TimerTask
;
import
java.util.TimerTask
;
...
@@ -85,7 +54,7 @@ public class PanZoomController
...
@@ -85,7 +54,7 @@ public class PanZoomController
private
static
final
float
MAX_ZOOM
=
4.0f
;
private
static
final
float
MAX_ZOOM
=
4.0f
;
/* 16 precomputed frames of the _ease-out_ animation from the CSS Transitions specification. */
/* 16 precomputed frames of the _ease-out_ animation from the CSS Transitions specification. */
private
static
f
inal
float
[]
EASE_OUT_ANIMATION_FRAMES
=
{
private
static
f
loat
[]
ZOOM_ANIMATION_FRAMES
=
new
float
[]
{
0.00000f
,
/* 0 */
0.00000f
,
/* 0 */
0.10211f
,
/* 1 */
0.10211f
,
/* 1 */
0.19864f
,
/* 2 */
0.19864f
,
/* 2 */
...
@@ -115,7 +84,11 @@ public class PanZoomController
...
@@ -115,7 +84,11 @@ public class PanZoomController
PANNING_HOLD_LOCKED
,
/* like PANNING_HOLD, but axis lock still in effect */
PANNING_HOLD_LOCKED
,
/* like PANNING_HOLD, but axis lock still in effect */
PINCHING
,
/* nth touch-start, where n > 1. this mode allows pan and zoom */
PINCHING
,
/* nth touch-start, where n > 1. this mode allows pan and zoom */
ANIMATED_ZOOM
,
/* animated zoom to a new rect */
ANIMATED_ZOOM
,
/* animated zoom to a new rect */
BOUNCE
/* in a bounce animation */
BOUNCE
,
/* in a bounce animation */
WAITING_LISTENERS
,
/* a state halfway between NOTHING and TOUCHING - the user has
put a finger down, but we don't yet know if a touch listener has
prevented the default actions yet. we still need to abort animations. */
}
}
private
final
LayerController
mController
;
private
final
LayerController
mController
;
...
@@ -156,6 +129,23 @@ public class PanZoomController
...
@@ -156,6 +129,23 @@ public class PanZoomController
}
}
}
}
private
void
setZoomAnimationFrames
(
String
frames
)
{
try
{
if
(
frames
.
length
()
>
0
)
{
StringTokenizer
st
=
new
StringTokenizer
(
frames
,
","
);
float
[]
values
=
new
float
[
st
.
countTokens
()];
for
(
int
i
=
0
;
i
<
values
.
length
;
i
++)
{
values
[
i
]
=
Float
.
parseFloat
(
st
.
nextToken
());
}
ZOOM_ANIMATION_FRAMES
=
values
;
}
}
catch
(
NumberFormatException
e
)
{
Log
.
e
(
LOGTAG
,
"Error setting zoom animation frames"
,
e
);
}
finally
{
Log
.
i
(
LOGTAG
,
"Zoom animation frames: "
+
Arrays
.
toString
(
ZOOM_ANIMATION_FRAMES
));
}
}
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
switch
(
event
.
getAction
()
&
MotionEvent
.
ACTION_MASK
)
{
switch
(
event
.
getAction
()
&
MotionEvent
.
ACTION_MASK
)
{
case
MotionEvent
.
ACTION_DOWN
:
return
onTouchStart
(
event
);
case
MotionEvent
.
ACTION_DOWN
:
return
onTouchStart
(
event
);
...
@@ -195,6 +185,30 @@ public class PanZoomController
...
@@ -195,6 +185,30 @@ public class PanZoomController
}
}
}
}
/** This function must be called on the UI thread. */
public
void
waitingForTouchListeners
(
MotionEvent
event
)
{
checkMainThread
();
if
((
event
.
getAction
()
&
MotionEvent
.
ACTION_MASK
)
==
MotionEvent
.
ACTION_DOWN
)
{
// this is the first touch point going down, so we enter the pending state
mSubscroller
.
cancel
();
// seting the state will kill any animations in progress, possibly leaving
// the page in overscroll
mState
=
PanZoomState
.
WAITING_LISTENERS
;
}
}
/** This function must be called on the UI thread. */
public
void
preventedTouchFinished
()
{
checkMainThread
();
if
(
mState
==
PanZoomState
.
WAITING_LISTENERS
)
{
// if we enter here, we just finished a block of events whose default actions
// were prevented by touch listeners. Now there are no touch points left, so
// we need to reset our state and re-bounce because we might be in overscroll
mState
=
PanZoomState
.
NOTHING
;
bounce
();
}
}
/** This must be called on the UI thread. */
/** This must be called on the UI thread. */
public
void
pageSizeUpdated
()
{
public
void
pageSizeUpdated
()
{
if
(
mState
==
PanZoomState
.
NOTHING
)
{
if
(
mState
==
PanZoomState
.
NOTHING
)
{
...
@@ -222,10 +236,16 @@ public class PanZoomController
...
@@ -222,10 +236,16 @@ public class PanZoomController
switch
(
mState
)
{
switch
(
mState
)
{
case
ANIMATED_ZOOM:
case
ANIMATED_ZOOM:
return
false
;
// We just interrupted a double-tap animation, so force a redraw in
// case this touchstart is just a tap that doesn't end up triggering
// a redraw
mController
.
setForceRedraw
();
mController
.
notifyLayerClientOfGeometryChange
();
// fall through
case
FLING:
case
FLING:
case
BOUNCE:
case
BOUNCE:
case
NOTHING:
case
NOTHING:
case
WAITING_LISTENERS:
startTouch
(
event
.
getX
(
0
),
event
.
getY
(
0
),
event
.
getEventTime
());
startTouch
(
event
.
getX
(
0
),
event
.
getY
(
0
),
event
.
getEventTime
());
return
false
;
return
false
;
case
TOUCHING:
case
TOUCHING:
...
@@ -244,11 +264,16 @@ public class PanZoomController
...
@@ -244,11 +264,16 @@ public class PanZoomController
private
boolean
onTouchMove
(
MotionEvent
event
)
{
private
boolean
onTouchMove
(
MotionEvent
event
)
{
switch
(
mState
)
{
switch
(
mState
)
{
case
NOTHING:
case
FLING:
case
FLING:
case
BOUNCE:
case
BOUNCE:
case
WAITING_LISTENERS:
// should never happen
// should never happen
Log
.
e
(
LOGTAG
,
"Received impossible touch move while in "
+
mState
);
Log
.
e
(
LOGTAG
,
"Received impossible touch move while in "
+
mState
);
// fall through
case
ANIMATED_ZOOM:
case
NOTHING:
// may happen if user double-taps and drags without lifting after the
// second tap. ignore the move if this happens.
return
false
;
return
false
;
case
TOUCHING:
case
TOUCHING:
...
@@ -274,7 +299,6 @@ public class PanZoomController
...
@@ -274,7 +299,6 @@ public class PanZoomController
track
(
event
);
track
(
event
);
return
true
;
return
true
;
case
ANIMATED_ZOOM:
case
PINCHING:
case
PINCHING:
// scale gesture listener will handle this
// scale gesture listener will handle this
return
false
;
return
false
;
...
@@ -286,12 +310,18 @@ public class PanZoomController
...
@@ -286,12 +310,18 @@ public class PanZoomController
private
boolean
onTouchEnd
(
MotionEvent
event
)
{
private
boolean
onTouchEnd
(
MotionEvent
event
)
{
switch
(
mState
)
{
switch
(
mState
)
{
case
NOTHING:
case
FLING:
case
FLING:
case
BOUNCE:
case
BOUNCE:
case
WAITING_LISTENERS:
// should never happen
// should never happen
Log
.
e
(
LOGTAG
,
"Received impossible touch end while in "
+
mState
);
Log
.
e
(
LOGTAG
,
"Received impossible touch end while in "
+
mState
);
// fall through
case
ANIMATED_ZOOM:
case
NOTHING:
// may happen if user double-taps and drags without lifting after the
// second tap. ignore if this happens.
return
false
;
return
false
;
case
TOUCHING:
case
TOUCHING:
mState
=
PanZoomState
.
NOTHING
;
mState
=
PanZoomState
.
NOTHING
;
// the switch into TOUCHING might have happened while the page was
// the switch into TOUCHING might have happened while the page was
...
@@ -299,6 +329,7 @@ public class PanZoomController
...
@@ -299,6 +329,7 @@ public class PanZoomController
// was the case
// was the case
bounce
();
bounce
();
return
false
;
return
false
;
case
PANNING:
case
PANNING:
case
PANNING_LOCKED:
case
PANNING_LOCKED:
case
PANNING_HOLD:
case
PANNING_HOLD:
...
@@ -306,19 +337,28 @@ public class PanZoomController
...
@@ -306,19 +337,28 @@ public class PanZoomController
mState
=
PanZoomState
.
FLING
;
mState
=
PanZoomState
.
FLING
;
fling
();
fling
();
return
true
;
return
true
;
case
PINCHING:
case
PINCHING:
mState
=
PanZoomState
.
NOTHING
;
mState
=
PanZoomState
.
NOTHING
;
return
true
;
return
true
;
case
ANIMATED_ZOOM:
return
false
;
}
}
Log
.
e
(
LOGTAG
,
"Unhandled case "
+
mState
+
" in onTouchEnd"
);
Log
.
e
(
LOGTAG
,
"Unhandled case "
+
mState
+
" in onTouchEnd"
);
return
false
;
return
false
;
}
}
private
boolean
onTouchCancel
(
MotionEvent
event
)
{
private
boolean
onTouchCancel
(
MotionEvent
event
)
{
mState
=
PanZoomState
.
NOTHING
;
if
(
mState
==
PanZoomState
.
WAITING_LISTENERS
)
{
// we might get a cancel event from the TouchEventHandler while in the
// WAITING_LISTENERS state if the touch listeners prevent-default the
// block of events. at this point being in WAITING_LISTENERS is equivalent
// to being in NOTHING with the exception of possibly being in overscroll.
// so here we don't want to do anything right now; the overscroll will be
// corrected in preventedTouchFinished().
return
false
;
}
cancelTouch
();
cancelTouch
();
mState
=
PanZoomState
.
NOTHING
;
// ensure we snap back if we're overscrolled
// ensure we snap back if we're overscrolled
bounce
();
bounce
();
return
false
;
return
false
;
...
@@ -423,16 +463,17 @@ public class PanZoomController
...
@@ -423,16 +463,17 @@ public class PanZoomController
return
;
return
;
}
}
mState
=
PanZoomState
.
BOUNCE
;
// At this point we have already set mState to BOUNCE or ANIMATED_ZOOM, so
//
set the animation target *after* setting state BOUNCE, so that
//
getRedrawHint() is returning false. This means we can safely call
//
the getRedrawHint() is returning false and we don't clobber the display
//
setAnimationTarget to set the new final display port and not have it get
//
port we set as a result of this animation target call
.
//
clobbered by display ports from intermediate animation frames
.
mController
.
setAnimationTarget
(
metrics
);
mController
.
setAnimationTarget
(
metrics
);
startAnimationTimer
(
new
BounceRunnable
(
bounceStartMetrics
,
metrics
));
startAnimationTimer
(
new
BounceRunnable
(
bounceStartMetrics
,
metrics
));
}
}
/* Performs a bounce-back animation to the nearest valid viewport metrics. */
/* Performs a bounce-back animation to the nearest valid viewport metrics. */
private
void
bounce
()
{
private
void
bounce
()
{
mState
=
PanZoomState
.
BOUNCE
;
bounce
(
getValidViewportMetrics
());
bounce
(
getValidViewportMetrics
());
}
}
...
@@ -477,14 +518,14 @@ public class PanZoomController
...
@@ -477,14 +518,14 @@ public class PanZoomController
return
getVelocity
()
<
STOPPED_THRESHOLD
;
return
getVelocity
()
<
STOPPED_THRESHOLD
;
}
}
PointF
g
etDisplacement
()
{
PointF
res
etDisplacement
()
{
return
new
PointF
(
mX
.
resetDisplacement
(),
mY
.
resetDisplacement
());
return
new
PointF
(
mX
.
resetDisplacement
(),
mY
.
resetDisplacement
());
}
}
private
void
updatePosition
()
{
private
void
updatePosition
()
{
mX
.
displace
();
mX
.
displace
();
mY
.
displace
();
mY
.
displace
();
PointF
displacement
=
g
etDisplacement
();
PointF
displacement
=
res
etDisplacement
();
if
(
FloatUtils
.
fuzzyEquals
(
displacement
.
x
,
0.0f
)
&&
FloatUtils
.
fuzzyEquals
(
displacement
.
y
,
0.0f
))
{
if
(
FloatUtils
.
fuzzyEquals
(
displacement
.
x
,
0.0f
)
&&
FloatUtils
.
fuzzyEquals
(
displacement
.
y
,
0.0f
))
{
return
;
return
;
}
}
...
@@ -542,13 +583,13 @@ public class PanZoomController
...
@@ -542,13 +583,13 @@ public class PanZoomController
* animation by setting the state to PanZoomState.NOTHING. Handle this case and bail
* animation by setting the state to PanZoomState.NOTHING. Handle this case and bail
* out.
* out.
*/
*/
if
(
mState
!=
PanZoomState
.
BOUNCE
)
{
if
(
!(
mState
==
PanZoomState
.
BOUNCE
||
mState
==
PanZoomState
.
ANIMATED_ZOOM
)
)
{
finishAnimation
();
finishAnimation
();
return
;
return
;
}
}
/* Perform the next frame of the bounce-back animation. */
/* Perform the next frame of the bounce-back animation. */
if
(
mBounceFrame
<
EASE_OUT
_ANIMATION_FRAMES
.
length
)
{
if
(
mBounceFrame
<
ZOOM
_ANIMATION_FRAMES
.
length
)
{
advanceBounce
();
advanceBounce
();
return
;
return
;
}
}
...
@@ -562,7 +603,7 @@ public class PanZoomController
...
@@ -562,7 +603,7 @@ public class PanZoomController
/* Performs one frame of a bounce animation. */
/* Performs one frame of a bounce animation. */
private
void
advanceBounce
()
{
private
void
advanceBounce
()
{
synchronized
(
mController
)
{
synchronized
(
mController
)
{
float
t
=
EASE_OUT
_ANIMATION_FRAMES
[
mBounceFrame
];
float
t
=
ZOOM
_ANIMATION_FRAMES
[
mBounceFrame
];
ViewportMetrics
newMetrics
=
mBounceStartMetrics
.
interpolate
(
mBounceEndMetrics
,
t
);
ViewportMetrics
newMetrics
=
mBounceStartMetrics
.
interpolate
(
mBounceEndMetrics
,
t
);
mController
.
setViewportMetrics
(
newMetrics
);
mController
.
setViewportMetrics
(
newMetrics
);
mController
.
notifyLayerClientOfGeometryChange
();
mController
.
notifyLayerClientOfGeometryChange
();
...
@@ -655,19 +696,37 @@ public class PanZoomController
...
@@ -655,19 +696,37 @@ public class PanZoomController
float
focusX
=
viewport
.
width
()
/
2.0f
;
float
focusX
=
viewport
.
width
()
/
2.0f
;
float
focusY
=
viewport
.
height
()
/
2.0f
;
float
focusY
=
viewport
.
height
()
/
2.0f
;
float
minZoomFactor
=
0.0f
;
float
minZoomFactor
=
0.0f
;
if
(
viewport
.
width
()
>
pageSize
.
width
&&
pageSize
.
width
>
0
)
{
float
maxZoomFactor
=
MAX_ZOOM
;
if
(
mController
.
getMinZoom
()
>
0
)
minZoomFactor
=
mController
.
getMinZoom
();
if
(
mController
.
getMaxZoom
()
>
0
)
maxZoomFactor
=
mController
.
getMaxZoom
();
if
(!
mController
.
getAllowZoom
())
{
// If allowZoom is false, clamp to the default zoom level.
maxZoomFactor
=
minZoomFactor
=
mController
.
getDefaultZoom
();
}
// Ensure minZoomFactor keeps the page at least as big as the viewport.
if
(
pageSize
.
width
>
0
)
{
float
scaleFactor
=
viewport
.
width
()
/
pageSize
.
width
;
float
scaleFactor
=
viewport
.
width
()
/
pageSize
.
width
;
minZoomFactor
=
Math
.
max
(
minZoomFactor
,
zoomFactor
*
scaleFactor
);
minZoomFactor
=
Math
.
max
(
minZoomFactor
,
zoomFactor
*
scaleFactor
);
if
(
viewport
.
width
()
>
pageSize
.
width
)
focusX
=
0.0f
;
focusX
=
0.0f
;
}
}
if
(
viewport
.
height
()
>
pageSize
.
height
&&
pageSize
.
height
>
0
)
{
if
(
pageSize
.
height
>
0
)
{
float
scaleFactor
=
viewport
.
height
()
/
pageSize
.
height
;
float
scaleFactor
=
viewport
.
height
()
/
pageSize
.
height
;
minZoomFactor
=
Math
.
max
(
minZoomFactor
,
zoomFactor
*
scaleFactor
);
minZoomFactor
=
Math
.
max
(
minZoomFactor
,
zoomFactor
*
scaleFactor
);
if
(
viewport
.
height
()
>
pageSize
.
height
)
focusY
=
0.0f
;
focusY
=
0.0f
;
}
}
if
(!
FloatUtils
.
fuzzyEquals
(
minZoomFactor
,
0.0f
))
{
maxZoomFactor
=
Math
.
max
(
maxZoomFactor
,
minZoomFactor
);
if
(
zoomFactor
<
minZoomFactor
)
{
// if one (or both) of the page dimensions is smaller than the viewport,
// if one (or both) of the page dimensions is smaller than the viewport,
// zoom using the top/left as the focus on that axis. this prevents the
// zoom using the top/left as the focus on that axis. this prevents the
// scenario where, if both dimensions are smaller than the viewport, but
// scenario where, if both dimensions are smaller than the viewport, but
...
@@ -675,9 +734,9 @@ public class PanZoomController
...
@@ -675,9 +734,9 @@ public class PanZoomController
// after applying the scale
// after applying the scale
PointF
center
=
new
PointF
(
focusX
,
focusY
);
PointF
center
=
new
PointF
(
focusX
,
focusY
);
viewportMetrics
.
scaleTo
(
minZoomFactor
,
center
);
viewportMetrics
.
scaleTo
(
minZoomFactor
,
center
);
}
else
if
(
zoomFactor
>
MAX_ZOOM
)
{
}
else
if
(
zoomFactor
>
maxZoomFactor
)
{
PointF
center
=
new
PointF
(
viewport
.
width
()
/
2.0f
,
viewport
.
height
()
/
2.0f
);
PointF
center
=
new
PointF
(
viewport
.
width
()
/
2.0f
,
viewport
.
height
()
/
2.0f
);
viewportMetrics
.
scaleTo
(
MAX_ZOOM
,
center
);
viewportMetrics
.
scaleTo
(
maxZoomFactor
,
center
);
}
}
/* Now we pan to the right origin. */
/* Now we pan to the right origin. */
...
@@ -717,9 +776,11 @@ public class PanZoomController
...
@@ -717,9 +776,11 @@ public class PanZoomController
if
(
mState
==
PanZoomState
.
ANIMATED_ZOOM
)
if
(
mState
==
PanZoomState
.
ANIMATED_ZOOM
)
return
false
;
return
false
;
if
(!
mController
.
getAllowZoom
())
return
false
;
mState
=
PanZoomState
.
PINCHING
;
mState
=
PanZoomState
.
PINCHING
;
mLastZoomFocus
=
new
PointF
(
detector
.
getFocusX
(),
detector
.
getFocusY
());
mLastZoomFocus
=
new
PointF
(
detector
.
getFocusX
(),
detector
.
getFocusY
());
cancelTouch
();
cancelTouch
();
return
true
;
return
true
;
...
@@ -729,7 +790,8 @@ public class PanZoomController
...
@@ -729,7 +790,8 @@ public class PanZoomController
public
boolean
onScale
(
SimpleScaleGestureDetector
detector
)
{
public
boolean
onScale
(
SimpleScaleGestureDetector
detector
)
{
Log
.
d
(
LOGTAG
,
"onScale in state "
+
mState
);
Log
.
d
(
LOGTAG
,
"onScale in state "
+
mState
);
if
(
mState
==
PanZoomState
.
ANIMATED_ZOOM
)
if
(
mState
!=
PanZoomState
.
PINCHING
)
return
false
;
return
false
;
float
prevSpan
=
detector
.
getPreviousSpan
();
float
prevSpan
=
detector
.
getPreviousSpan
();
...
@@ -752,13 +814,31 @@ public class PanZoomController
...
@@ -752,13 +814,31 @@ public class PanZoomController
synchronized
(
mController
)
{
synchronized
(
mController
)
{
float
newZoomFactor
=
mController
.
getZoomFactor
()
*
spanRatio
;
float
newZoomFactor
=
mController
.
getZoomFactor
()
*
spanRatio
;
if
(
newZoomFactor
>=
MAX_ZOOM
)
{
float
minZoomFactor
=
0.0f
;
// apply resistance when zooming past MAX_ZOOM,
float
maxZoomFactor
=
MAX_ZOOM
;
// such that it asymptotically reaches MAX_ZOOM + 1.0
if
(
mController
.
getMinZoom
()
>
0
)
minZoomFactor
=
mController
.
getMinZoom
();
if
(
mController
.
getMaxZoom
()
>
0
)
maxZoomFactor
=
mController
.
getMaxZoom
();
if
(
newZoomFactor
<
minZoomFactor
)
{
// apply resistance when zooming past minZoomFactor,
// such that it asymptotically reaches minZoomFactor / 2.0
// but never exceeds that
// but never exceeds that
float
excessZoom
=
newZoomFactor
-
MAX_ZOOM
;
final
float
rate
=
0.5f
;
// controls how quickly we approach the limit
float
excessZoom
=
minZoomFactor
-
newZoomFactor
;
excessZoom
=
1.0f
-
(
float
)
Math
.
exp
(-
excessZoom
*
rate
);
newZoomFactor
=
minZoomFactor
*
(
1.0f
-
excessZoom
/
2.0f
);
}
if
(
newZoomFactor
>
maxZoomFactor
)
{
// apply resistance when zooming past maxZoomFactor,
// such that it asymptotically reaches maxZoomFactor + 1.0
// but never exceeds that
float
excessZoom
=
newZoomFactor
-
maxZoomFactor
;
excessZoom
=
1.0f
-
(
float
)
Math
.
exp
(-
excessZoom
);
excessZoom
=
1.0f
-
(
float
)
Math
.
exp
(-
excessZoom
);
newZoomFactor
=
MAX_ZOOM
+
excessZoom
;
newZoomFactor
=
maxZoomFactor
+
excessZoom
;
}
}
mController
.
scrollBy
(
new
PointF
(
mLastZoomFocus
.
x
-
detector
.
getFocusX
(),
mController
.
scrollBy
(
new
PointF
(
mLastZoomFocus
.
x
-
detector
.
getFocusX
(),
...
@@ -807,23 +887,37 @@ public class PanZoomController
...
@@ -807,23 +887,37 @@ public class PanZoomController
}
}
@Override
@Override
public
boolean
onDown
(
MotionEvent
motionEvent
)
{
public
boolean
onSingleTapUp
(
MotionEvent
motionEvent
)
{
// When zooming is enabled, wait to see if there's a double-tap.
if
(
mController
.
getAllowZoom
())
return
false
;
return
false
;
return
true
;
}
}
@Override
@Override
public
boolean
onSingleTapConfirmed
(
MotionEvent
motionEvent
)
{
public
boolean
onSingleTapConfirmed
(
MotionEvent
motionEvent
)
{
// When zooming is disabled, we handle this in onSingleTapUp.
if
(!
mController
.
getAllowZoom
())
return
false
;
return
true
;
return
true
;
}
}
@Override
@Override
public
boolean
onDoubleTap
(
MotionEvent
motionEvent
)
{
public
boolean
onDoubleTap
(
MotionEvent
motionEvent
)
{
if
(!
mController
.
getAllowZoom
())
return
false
;
return
true
;
return
true
;
}
}
p
ublic
void
cancelTouch
()
{
p
rivate
void
cancelTouch
()
{
}
}
/**
* Zoom to a specified rect IN CSS PIXELS.
*
* While we usually use device pixels, @zoomToRect must be specified in CSS
* pixels.
*/
private
boolean
animatedZoomTo
(
RectF
zoomToRect
)
{
private
boolean
animatedZoomTo
(
RectF
zoomToRect
)
{
mState
=
PanZoomState
.
ANIMATED_ZOOM
;
mState
=
PanZoomState
.
ANIMATED_ZOOM
;
final
float
startZoom
=
mController
.
getZoomFactor
();
final
float
startZoom
=
mController
.
getZoomFactor
();
...
@@ -849,10 +943,11 @@ public class PanZoomController
...
@@ -849,10 +943,11 @@ public class PanZoomController
zoomToRect
.
right
=
zoomToRect
.
left
+
newWidth
;
zoomToRect
.
right
=
zoomToRect
.
left
+
newWidth
;
}
}
float
finalZoom
=
viewport
.
width
()
*
startZoom
/
zoomToRect
.
width
();
float
finalZoom
=
viewport
.
width
()
/
zoomToRect
.
width
();
ViewportMetrics
finalMetrics
=
new
ViewportMetrics
(
mController
.
getViewportMetrics
());
ViewportMetrics
finalMetrics
=
new
ViewportMetrics
(
mController
.
getViewportMetrics
());
finalMetrics
.
setOrigin
(
new
PointF
(
zoomToRect
.
left
,
zoomToRect
.
top
));
finalMetrics
.
setOrigin
(
new
PointF
(
zoomToRect
.
left
*
finalMetrics
.
getZoomFactor
(),
zoomToRect
.
top
*
finalMetrics
.
getZoomFactor
()));
finalMetrics
.
scaleTo
(
finalZoom
,
new
PointF
(
0.0f
,
0.0f
));
finalMetrics
.
scaleTo
(
finalZoom
,
new
PointF
(
0.0f
,
0.0f
));
// 2. now run getValidViewportMetrics on it, so that the target viewport is
// 2. now run getValidViewportMetrics on it, so that the target viewport is
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment