aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Scroggo <Scroggo@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-06-15 16:49:08 +0000
committerGravatar Scroggo <Scroggo@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-06-15 16:49:08 +0000
commit2c8208f3a444098aee562f5a1ef620142807eda2 (patch)
tree2cec47af682b4db690439fcb02e569f501074244
parent25e92838a9af4885670fe7ff6950da0994cfb958 (diff)
Improvements to the SampleApp (primarily Android).
Reviewed at http://codereview.appspot.com/4587042/ Android - Added buttons for interaction without a keyboard. - Added the ability to zoom in to a specific point (roughly). - Added event handling (for showing a slideshow, for example). - Allow changing screen orientation - Updated README file, explaining how to build Multiplatform changes - Added SampleApp header file - Remove FPS when turning off measure FPS mode git-svn-id: http://skia.googlecode.com/svn/trunk@1596 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--android_sample/SampleApp/Android.mk3
-rw-r--r--android_sample/SampleApp/AndroidManifest.xml3
-rw-r--r--android_sample/SampleApp/README.txt23
-rw-r--r--android_sample/SampleApp/jni/sample-jni.cpp117
-rw-r--r--android_sample/SampleApp/res/menu/sample.xml19
-rw-r--r--android_sample/SampleApp/res/values/strings.xml4
-rw-r--r--android_sample/SampleApp/src/com/skia/sampleapp/SampleApp.java69
-rw-r--r--android_sample/SampleApp/src/com/skia/sampleapp/SampleView.java36
-rw-r--r--include/views/SkOSWindow_Android.h8
-rw-r--r--samplecode/SampleApp.cpp188
-rw-r--r--samplecode/SampleApp.h145
11 files changed, 425 insertions, 190 deletions
diff --git a/android_sample/SampleApp/Android.mk b/android_sample/SampleApp/Android.mk
index 59f69936b0..f2fd860684 100644
--- a/android_sample/SampleApp/Android.mk
+++ b/android_sample/SampleApp/Android.mk
@@ -14,6 +14,8 @@ LOCAL_PACKAGE_NAME := SampleApp
LOCAL_JNI_SHARED_LIBRARIES := libskia-sample
+LOCAL_PROGUARD_ENABLED := disabled
+
include $(BUILD_PACKAGE)
######################################
@@ -37,6 +39,7 @@ LOCAL_C_INCLUDES += \
external/skia/include/gpu \
external/skia/src/core \
external/skia/gpu/include \
+ frameworks/base/opengl/include/GLES2 \
$(LOCAL_PATH)/jni
LOCAL_SHARED_LIBRARIES := \
diff --git a/android_sample/SampleApp/AndroidManifest.xml b/android_sample/SampleApp/AndroidManifest.xml
index 071ae03390..5980d298d0 100644
--- a/android_sample/SampleApp/AndroidManifest.xml
+++ b/android_sample/SampleApp/AndroidManifest.xml
@@ -22,6 +22,7 @@
android:debuggable="true">
<activity android:name=".SampleApp"
android:theme="@android:style/Theme.Holo.Light"
+ android:configChanges="orientation|screenSize"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -29,4 +30,4 @@
</intent-filter>
</activity>
</application>
-</manifest>
+</manifest>
diff --git a/android_sample/SampleApp/README.txt b/android_sample/SampleApp/README.txt
index a7d8e54d2e..31e649291b 100644
--- a/android_sample/SampleApp/README.txt
+++ b/android_sample/SampleApp/README.txt
@@ -1,25 +1,6 @@
Building the sample app for Android using an Android tree:
-Copy this folder into an Android tree in packages/apps. In addition to jni,
-res, and src, there needs to be a fourth folder named "skia_extra". This
-will include the skia files which are not part of an Android checkout. It
-should have three folders: include, samplecode, and src.
-
-skia/trunk/include/views -> skia_extra/include/views
-skia/trunk/include/xml -> skia_extra/include/xml
-
-skia/trunk/samplecode -> skia_extra/samplecode
-
-skia/trunk/src/views -> skia_extra/src/views
-skia/trunk/src/ports/SkXMLParser_empty.cpp -> skia_extra/src/ports/
-skia/trunk/src/xml -> skia_extra/src/xml
-
-skia/trunk/include/utils/android/AndroidKeyToSkKey.h -> jni/
-
-From packages/apps/SampleApp, type "mm" to build, and install the
-resulting apk.
-
-(It may be necessary to remove samples that do not build from
-skia_extra/samplecode/samplecode_files.mk)
+cd into external/skia/android_sample/SampleApp.
+Type "mm" to build, and install the resulting apk.
TODO: Instructions for building from SDK/NDK
diff --git a/android_sample/SampleApp/jni/sample-jni.cpp b/android_sample/SampleApp/jni/sample-jni.cpp
index 86d07a85b8..be4e4d4a68 100644
--- a/android_sample/SampleApp/jni/sample-jni.cpp
+++ b/android_sample/SampleApp/jni/sample-jni.cpp
@@ -15,17 +15,18 @@
*
*/
-#include <jni.h>
-
+#include "GrContext.h"
+#include "SampleApp.h"
+#include "SkApplication.h"
#include "SkCanvas.h"
+#include "SkDevice.h"
#include "SkEvent.h"
+#include "SkGpuCanvas.h"
#include "SkWindow.h"
-#include "SkApplication.h"
+
+#include <jni.h>
#include "utils/android/AndroidKeyToSkKey.h"
-#include "SkDevice.h"
-#include "SkGpuCanvas.h"
-#include "GrContext.h"
///////////////////////////////////////////
///////////////// Globals /////////////////
@@ -35,23 +36,27 @@ struct ActivityGlue {
JNIEnv* m_env;
jweak m_obj;
jmethodID m_setTitle;
+ jmethodID m_startTimer;
ActivityGlue() {
m_env = NULL;
m_obj = NULL;
m_setTitle = NULL;
+ m_startTimer = NULL;
}
} gActivityGlue;
struct WindowGlue {
jweak m_obj;
jmethodID m_inval;
+ jmethodID m_queueSkEvent;
WindowGlue() {
m_obj = NULL;
m_inval = NULL;
+ m_queueSkEvent = NULL;
}
} gWindowGlue;
-SkOSWindow* gWindow;
+SampleWindow* gWindow;
///////////////////////////////////////////
///////////// SkOSWindow impl /////////////
@@ -80,9 +85,25 @@ void SkOSWindow::onHandleInval(const SkIRect& rect)
/////////////// SkEvent impl //////////////
///////////////////////////////////////////
-void SkEvent::SignalQueueTimer(SkMSec) {}
+void SkEvent::SignalQueueTimer(SkMSec ms)
+{
+ if (!gActivityGlue.m_env || !gActivityGlue.m_startTimer
+ || !gActivityGlue.m_obj || !ms) {
+ return;
+ }
+ gActivityGlue.m_env->CallVoidMethod(gActivityGlue.m_obj,
+ gActivityGlue.m_startTimer, ms);
+}
-void SkEvent::SignalNonEmptyQueue() {}
+void SkEvent::SignalNonEmptyQueue()
+{
+ if (!gActivityGlue.m_env || !gWindowGlue.m_queueSkEvent
+ || !gWindowGlue.m_obj) {
+ return;
+ }
+ gActivityGlue.m_env->CallVoidMethod(gWindowGlue.m_obj,
+ gWindowGlue.m_queueSkEvent);
+}
///////////////////////////////////////////
////////////////// JNI ////////////////////
@@ -113,8 +134,22 @@ JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_handleClick(
JNIEnv* env, jobject thiz, jint x, jint y, jint state);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_createOSWindow(
JNIEnv* env, jobject thiz, jobject jsampleView);
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_setZoomCenter(
+ JNIEnv* env, jobject thiz, jfloat x, jfloat y);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_zoom(
JNIEnv* env, jobject thiz, jfloat factor);
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_nextSample(
+ JNIEnv* env, jobject thiz, jboolean fprevious);
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleRendering(
+ JNIEnv* env, jobject thiz);
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleSlideshow(
+ JNIEnv* env, jobject thiz);
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleFps(
+ JNIEnv* env, jobject thiz);
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_processSkEvent(
+ JNIEnv* env, jobject thiz);
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_serviceQueueTimer(
+ JNIEnv* env, jobject thiz);
};
JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyDown(
@@ -162,12 +197,14 @@ JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_updateSize(JNIEnv* env,
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_createOSWindow(
JNIEnv* env, jobject thiz, jobject jsampleView)
{
- gWindow = create_sk_window(NULL);
- // Only using a method on View.
- jclass clazz = gActivityGlue.m_env->FindClass("android/opengl/GLSurfaceView");
+ gWindow = new SampleWindow(NULL);
+ jclass clazz = gActivityGlue.m_env->FindClass(
+ "com/skia/sampleapp/SampleView");
gWindowGlue.m_obj = gActivityGlue.m_env->NewWeakGlobalRef(jsampleView);
- gWindowGlue.m_inval = GetJMethod(gActivityGlue.m_env, clazz, "requestRender",
- "()V");
+ gWindowGlue.m_inval = GetJMethod(gActivityGlue.m_env, clazz,
+ "requestRender", "()V");
+ gWindowGlue.m_queueSkEvent = GetJMethod(gActivityGlue.m_env, clazz,
+ "queueSkEvent", "()V");
gActivityGlue.m_env->DeleteLocalRef(clazz);
}
@@ -175,11 +212,12 @@ JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_init(JNIEnv* env,
jobject thiz)
{
gActivityGlue.m_env = env;
- // Only using a method on Activity.
- jclass clazz = env->FindClass("android/app/Activity");
+ jclass clazz = env->FindClass("com/skia/sampleapp/SampleApp");
gActivityGlue.m_obj = env->NewWeakGlobalRef(thiz);
gActivityGlue.m_setTitle = GetJMethod(env, clazz, "setTitle",
"(Ljava/lang/CharSequence;)V");
+ gActivityGlue.m_startTimer = GetJMethod(gActivityGlue.m_env, clazz,
+ "startTimer", "(I)V");
env->DeleteLocalRef(clazz);
application_init();
@@ -235,9 +273,56 @@ JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_draw(
}
}
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_setZoomCenter(
+ JNIEnv* env, jobject thiz, jfloat x, jfloat y)
+{
+ gWindow->setZoomCenter(x, y);
+}
+
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_zoom(
JNIEnv* env, jobject thiz, jfloat factor)
{
gWindow->changeZoomLevel(factor);
}
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_nextSample(
+ JNIEnv* env, jobject thiz, jboolean fprevious)
+{
+ if (fprevious) {
+ gWindow->previousSample();
+ } else {
+ gWindow->nextSample();
+ }
+}
+
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleRendering(
+ JNIEnv* env, jobject thiz)
+{
+ gWindow->toggleRendering();
+}
+
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleSlideshow(
+ JNIEnv* env, jobject thiz)
+{
+ gWindow->toggleSlideshow();
+}
+
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleFps(
+ JNIEnv* env, jobject thiz)
+{
+ gWindow->toggleFPS();
+}
+
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_processSkEvent(
+ JNIEnv* env, jobject thiz)
+{
+ if (SkEvent::ProcessEvent()) {
+ SkEvent::SignalNonEmptyQueue();
+ }
+}
+
+JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_serviceQueueTimer(
+ JNIEnv* env, jobject thiz)
+{
+ SkEvent::ServiceQueueTimer();
+}
diff --git a/android_sample/SampleApp/res/menu/sample.xml b/android_sample/SampleApp/res/menu/sample.xml
index 49f7ebb091..193f277762 100644
--- a/android_sample/SampleApp/res/menu/sample.xml
+++ b/android_sample/SampleApp/res/menu/sample.xml
@@ -16,6 +16,21 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
+ android:id="@+id/fps"
+ android:title="@string/fps"
+ android:showAsAction="always"
+ />
+ <item
+ android:id="@+id/toggle_rendering"
+ android:title="@string/toggle_rendering"
+ android:showAsAction="always"
+ />
+ <item
+ android:id="@+id/prev"
+ android:showAsAction="always"
+ android:icon="@*android:drawable/ic_btn_find_prev"
+ />
+ <item
android:id="@+id/next"
android:showAsAction="always"
android:icon="@*android:drawable/ic_btn_find_next"
@@ -24,6 +39,10 @@
android:id="@+id/overview"
android:title="@string/overview"
/>
+ <item
+ android:id="@+id/slideshow"
+ android:title="@string/slideshow"
+ />
<!--
android:icon="@drawable/ic_menu_new_window"
-->
diff --git a/android_sample/SampleApp/res/values/strings.xml b/android_sample/SampleApp/res/values/strings.xml
index 72d3bc8596..810ff41386 100644
--- a/android_sample/SampleApp/res/values/strings.xml
+++ b/android_sample/SampleApp/res/values/strings.xml
@@ -15,4 +15,8 @@
-->
<resources>
<string name="app_name">SampleApp</string>
+ <string name="overview">Overview</string>
+ <string name="toggle_rendering">Toggle rendering</string>
+ <string name="slideshow">Slideshow</string>
+ <string name="fps">FPS</string>
</resources>
diff --git a/android_sample/SampleApp/src/com/skia/sampleapp/SampleApp.java b/android_sample/SampleApp/src/com/skia/sampleapp/SampleApp.java
index fe733603eb..b1160104aa 100644
--- a/android_sample/SampleApp/src/com/skia/sampleapp/SampleApp.java
+++ b/android_sample/SampleApp/src/com/skia/sampleapp/SampleApp.java
@@ -53,10 +53,9 @@ public class SampleApp extends Activity
holder.addView(mView, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
-
+
mTitle.setVisibility(View.GONE);
getActionBar().setDisplayShowHomeEnabled(false);
-
}
@Override
@@ -87,11 +86,43 @@ public class SampleApp extends Activity
}
});
return true;
+ case R.id.prev:
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ nextSample(true);
+ }
+ });
+ return true;
case R.id.next:
mView.queueEvent(new Runnable() {
@Override
public void run() {
- handleKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, 0);
+ nextSample(false);
+ }
+ });
+ return true;
+ case R.id.toggle_rendering:
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ toggleRendering();
+ }
+ });
+ return true;
+ case R.id.slideshow:
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ toggleSlideshow();
+ }
+ });
+ return true;
+ case R.id.fps:
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ toggleFps();
}
});
return true;
@@ -118,7 +149,6 @@ public class SampleApp extends Activity
handleKeyDown(keycode, uni);
}
});
-
return true;
case KeyEvent.ACTION_UP:
mView.queueEvent(new Runnable() {
@@ -134,7 +164,7 @@ public class SampleApp extends Activity
}
private static final int SET_TITLE = 1;
-
+
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -148,22 +178,47 @@ public class SampleApp extends Activity
}
}
};
-
+
@Override
public void setTitle(CharSequence title) {
mHandler.obtainMessage(SET_TITLE, title).sendToTarget();
}
+ // Called by JNI
+ @SuppressWarnings("unused")
+ private void startTimer(int ms) {
+ // After the delay, queue an event to the Renderer's thread
+ // to handle the event on the timer queue
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ serviceQueueTimer();
+ }
+ });
+ }
+ }, ms);
+ }
+
native void draw();
native void init();
native void term();
// Currently depends on init having already been called.
- native void createOSWindow(GLSurfaceView view);
+ native void createOSWindow(SampleView view);
native void updateSize(int w, int h);
native void handleClick(int x, int y, int state);
native boolean handleKeyDown(int key, int uni);
native boolean handleKeyUp(int key);
native void zoom(float factor);
+ native void setZoomCenter(float x, float y);
+ native void nextSample(boolean previous);
+ native void toggleRendering();
+ native void toggleSlideshow();
+ native void toggleFps();
+ native void processSkEvent();
+ native void serviceQueueTimer();
static {
System.loadLibrary("skia-sample");
diff --git a/android_sample/SampleApp/src/com/skia/sampleapp/SampleView.java b/android_sample/SampleApp/src/com/skia/sampleapp/SampleView.java
index 0d76dcea93..5ea36a864d 100644
--- a/android_sample/SampleApp/src/com/skia/sampleapp/SampleView.java
+++ b/android_sample/SampleApp/src/com/skia/sampleapp/SampleView.java
@@ -33,9 +33,10 @@ import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class SampleView extends GLSurfaceView implements OnScaleGestureListener {
-
+
private final SampleApp mApp;
private ScaleGestureDetector mDetector;
+
public SampleView(SampleApp app) {
super(app);
mApp = app;
@@ -46,6 +47,17 @@ public class SampleView extends GLSurfaceView implements OnScaleGestureListener
mDetector = new ScaleGestureDetector(app, this);
}
+ // Called by JNI
+ @SuppressWarnings("unused")
+ private void queueSkEvent() {
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ mApp.processSkEvent();
+ }
+ });
+ }
+
@Override
public boolean onTouchEvent(MotionEvent event) {
mDetector.onTouchEvent(event);
@@ -62,23 +74,33 @@ public class SampleView extends GLSurfaceView implements OnScaleGestureListener
mApp.handleClick(x, y, action);
}
});
-
+
return true;
}
+
// ScaleGestureDetector.OnScaleGestureListener implementation
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
+ final float x = detector.getFocusX();
+ final float y = detector.getFocusY();
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ mApp.setZoomCenter(x, y);
+ }
+ });
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
if (detector.getScaleFactor() != 1) {
- final float difference = detector.getCurrentSpan() - detector.getPreviousSpan();
+ final float difference = detector.getCurrentSpan()
+ - detector.getPreviousSpan();
queueEvent(new Runnable() {
@Override
public void run() {
- mApp.zoom(difference * .03f);
+ mApp.zoom(difference * .01f);
}
});
@@ -96,11 +118,11 @@ public class SampleView extends GLSurfaceView implements OnScaleGestureListener
public void onDrawFrame(GL10 gl) {
mApp.draw();
}
-
+
public void onSurfaceChanged(GL10 gl, int width, int height) {
mApp.updateSize(width, height);
}
-
+
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearStencil(0);
gl.glClear(gl.GL_STENCIL_BUFFER_BIT);
@@ -108,4 +130,4 @@ public class SampleView extends GLSurfaceView implements OnScaleGestureListener
mApp.createOSWindow(SampleView.this);
}
}
-} \ No newline at end of file
+}
diff --git a/include/views/SkOSWindow_Android.h b/include/views/SkOSWindow_Android.h
index 569f3f7f91..e547609e73 100644
--- a/include/views/SkOSWindow_Android.h
+++ b/include/views/SkOSWindow_Android.h
@@ -18,9 +18,8 @@
#define SkOSWindow_Android_DEFINED
#include "SkWindow.h"
-#include "SkEvent.h"
-class GrContext;
+class SkIRect;
class SkOSWindow : public SkWindow {
public:
@@ -29,10 +28,7 @@ public:
bool attachGL() { return true; }
void detachGL() {}
void presentGL() {}
- virtual bool drawsToHardware() { return false; }
- virtual bool setGrContext(GrContext*) { return false; }
- virtual GrContext* getGrContext() { return NULL; }
- virtual void changeZoomLevel(float delta) {}
+
protected:
// overrides from SkWindow
virtual void onHandleInval(const SkIRect&);
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index aba105b3f7..c457ef68a8 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -1,3 +1,5 @@
+#include "SampleApp.h"
+
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkGpuCanvas.h"
@@ -11,9 +13,12 @@
#include "SampleCode.h"
#include "GrContext.h"
-#include "SkTouchGesture.h"
#include "SkTypeface.h"
+#ifdef ANDROID
+ #include "gl2.h"
+#endif
+
#define TEST_GPIPEx
#ifdef TEST_GPIPE
@@ -111,12 +116,6 @@ enum FlipAxisEnum {
kFlipAxis_Y = (1 << 1)
};
-enum SkTriState {
- kFalse_SkTriState,
- kTrue_SkTriState,
- kUnknown_SkTriState,
-};
-
static SkTriState cycle_tristate(SkTriState state) {
static const SkTriState gCycle[] = {
/* kFalse_SkTriState -> */ kUnknown_SkTriState,
@@ -244,121 +243,12 @@ static SkView* curr_view(SkWindow* wind) {
return iter.next();
}
-class SampleWindow : public SkOSWindow {
- SkTDArray<SkViewFactory> fSamples;
-public:
- SampleWindow(void* hwnd);
- virtual ~SampleWindow();
-
- virtual void draw(SkCanvas* canvas);
-#ifdef ANDROID
- virtual bool drawsToHardware() { return fCanvasType == kGPU_CanvasType; }
- virtual bool setGrContext(GrContext*);
- virtual GrContext* getGrContext();
-#endif
-
-protected:
- virtual void onDraw(SkCanvas* canvas);
- virtual bool onHandleKey(SkKey key);
- virtual bool onHandleChar(SkUnichar);
- virtual void onSizeChange();
-
- virtual SkCanvas* beforeChildren(SkCanvas*);
- virtual void afterChildren(SkCanvas*);
- virtual void beforeChild(SkView* child, SkCanvas* canvas);
- virtual void afterChild(SkView* child, SkCanvas* canvas);
-
- virtual bool onEvent(const SkEvent& evt);
- virtual bool onQuery(SkEvent* evt);
-
- virtual bool onDispatchClick(int x, int y, Click::State);
- virtual bool onClick(Click* click);
- virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
-
-#if 0
- virtual bool handleChar(SkUnichar uni);
- virtual bool handleEvent(const SkEvent& evt);
- virtual bool handleKey(SkKey key);
- virtual bool handleKeyUp(SkKey key);
- virtual bool onHandleKeyUp(SkKey key);
-#endif
-
-private:
- int fCurrIndex;
-
- SkPicture* fPicture;
- SkGpuCanvas* fGpuCanvas;
- GrContext* fGrContext;
- SkPath fClipPath;
-
- SkTouchGesture fGesture;
- SkScalar fZoomLevel;
- SkScalar fZoomScale;
-
- enum CanvasType {
- kRaster_CanvasType,
- kPicture_CanvasType,
- kGPU_CanvasType
- };
- CanvasType fCanvasType;
-
- bool fUseClip;
- bool fNClip;
- bool fRepeatDrawing;
- bool fAnimating;
- bool fRotate;
- bool fScale;
- bool fRequestGrabImage;
- bool fUsePipe;
- bool fMeasureFPS;
- SkMSec fMeasureFPS_Time;
-
- // The following are for the 'fatbits' drawing
- // Latest position of the mouse.
- int fMouseX, fMouseY;
- int fFatBitsScale;
- // Used by the text showing position and color values.
- SkTypeface* fTypeface;
- bool fShowZoomer;
-
- SkTriState fLCDState;
- SkTriState fAAState;
- SkTriState fFilterState;
- SkTriState fHintingState;
- unsigned fFlipAxis;
-
- int fScrollTestX, fScrollTestY;
-
- bool make3DReady();
-#ifdef ANDROID
- virtual
-#endif
- void changeZoomLevel(float delta);
-
- void loadView(SkView*);
- void updateTitle();
- bool nextSample();
-
- void toggleZoomer();
- bool zoomIn();
- bool zoomOut();
- void updatePointer(int x, int y);
- void showZoomer(SkCanvas* canvas);
-
- void postAnimatingEvent() {
- if (fAnimating) {
- SkEvent* evt = new SkEvent(ANIMATING_EVENTTYPE);
- evt->post(this->getSinkID(), ANIMATING_DELAY);
- }
- }
-
-
- static CanvasType cycle_canvastype(CanvasType);
-
- typedef SkOSWindow INHERITED;
-};
+void SampleWindow::setZoomCenter(float x, float y)
+{
+ fZoomCenterX = SkFloatToScalar(x);
+ fZoomCenterY = SkFloatToScalar(y);
+}
-#ifdef ANDROID
bool SampleWindow::setGrContext(GrContext* context)
{
if (fGrContext) {
@@ -373,7 +263,6 @@ GrContext* SampleWindow::getGrContext()
{
return fGrContext;
}
-#endif
bool SampleWindow::zoomIn()
{
@@ -577,8 +466,8 @@ void SampleWindow::draw(SkCanvas* canvas) {
gAnimTimePrev = gAnimTime;
gAnimTime = SkTime::GetMSecs();
- SkScalar cx = SkScalarHalf(this->width());
- SkScalar cy = SkScalarHalf(this->height());
+ SkScalar cx = fZoomCenterX;
+ SkScalar cy = fZoomCenterY;
if (fZoomLevel) {
SkMatrix m;
@@ -970,12 +859,25 @@ void SampleWindow::changeZoomLevel(float delta) {
this->inval(NULL);
}
+bool SampleWindow::previousSample() {
+ fCurrIndex = (fCurrIndex - 1) % fSamples.count();
+ this->loadView(fSamples[fCurrIndex]());
+ return true;
+}
+
bool SampleWindow::nextSample() {
fCurrIndex = (fCurrIndex + 1) % fSamples.count();
this->loadView(fSamples[fCurrIndex]());
return true;
}
+void SampleWindow::postAnimatingEvent() {
+ if (fAnimating) {
+ SkEvent* evt = new SkEvent(ANIMATING_EVENTTYPE);
+ evt->post(this->getSinkID(), ANIMATING_DELAY);
+ }
+}
+
bool SampleWindow::onEvent(const SkEvent& evt) {
if (evt.isType(ANIMATING_EVENTTYPE)) {
if (fAnimating) {
@@ -1072,9 +974,7 @@ bool SampleWindow::onHandleChar(SkUnichar uni) {
switch (uni) {
case 'a':
- fAnimating = !fAnimating;
- this->postAnimatingEvent();
- this->updateTitle();
+ this->toggleSlideshow();
return true;
case 'b':
fAAState = cycle_tristate(fAAState);
@@ -1090,8 +990,7 @@ bool SampleWindow::onHandleChar(SkUnichar uni) {
SkGraphics::SetFontCacheUsed(0);
return true;
case 'f':
- fMeasureFPS = !fMeasureFPS;
- this->inval(NULL);
+ this->toggleFPS();
break;
case 'g':
fRequestGrabImage = true;
@@ -1153,6 +1052,24 @@ bool SampleWindow::onHandleChar(SkUnichar uni) {
return this->INHERITED::onHandleChar(uni);
}
+void SampleWindow::toggleFPS() {
+ fMeasureFPS = !fMeasureFPS;
+ this->inval(NULL);
+ this->updateTitle();
+}
+
+void SampleWindow::toggleSlideshow() {
+ fAnimating = !fAnimating;
+ this->postAnimatingEvent();
+ this->updateTitle();
+}
+
+void SampleWindow::toggleRendering() {
+ fCanvasType = cycle_canvastype(fCanvasType);
+ this->updateTitle();
+ this->inval(NULL);
+}
+
#include "SkDumpCanvas.h"
bool SampleWindow::onHandleKey(SkKey key) {
@@ -1174,9 +1091,7 @@ bool SampleWindow::onHandleKey(SkKey key) {
}
break;
case kLeft_SkKey:
- fCanvasType = cycle_canvastype(fCanvasType);
- this->updateTitle();
- this->inval(NULL);
+ toggleRendering();
return true;
case kUp_SkKey:
if (USE_ARROWS_FOR_ZOOM) {
@@ -1405,6 +1320,15 @@ void SampleWindow::onSizeChange() {
#endif
}
+ fZoomCenterX = SkScalarHalf(this->width());
+ fZoomCenterY = SkScalarHalf(this->height());
+
+ if (fGrContext) {
+ glViewport(0, 0, SkScalarRound(this->width()),
+ SkScalarRound(this->height()));
+ fGrContext->resetContext();
+ }
+
this->updateTitle(); // to refresh our config
}
diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h
new file mode 100644
index 0000000000..37a3d0959a
--- /dev/null
+++ b/samplecode/SampleApp.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2011 Skia
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SampleWindow_DEFINED
+#define SampleWindow_DEFINED
+
+#include "SkWindow.h"
+
+#include "SampleCode.h"
+#include "SkPath.h"
+#include "SkScalar.h"
+#include "SkTDArray.h"
+#include "SkTouchGesture.h"
+#include "SkWindow.h"
+
+class GrContext;
+
+class SkEvent;
+class SkCanvas;
+class SkGpuCanvas;
+class SkPicture;
+class SkTypeface;
+
+enum SkTriState {
+ kFalse_SkTriState,
+ kTrue_SkTriState,
+ kUnknown_SkTriState,
+};
+
+class SampleWindow : public SkOSWindow {
+ SkTDArray<SkViewFactory> fSamples;
+public:
+ SampleWindow(void* hwnd);
+ virtual ~SampleWindow();
+
+ virtual void draw(SkCanvas* canvas);
+
+ void toggleRendering();
+ void toggleSlideshow();
+ void toggleFPS();
+ bool drawsToHardware() { return fCanvasType == kGPU_CanvasType; }
+ bool setGrContext(GrContext*);
+ GrContext* getGrContext();
+ void setZoomCenter(float x, float y);
+ void changeZoomLevel(float delta);
+ bool nextSample();
+ bool previousSample();
+
+protected:
+ virtual void onDraw(SkCanvas* canvas);
+ virtual bool onHandleKey(SkKey key);
+ virtual bool onHandleChar(SkUnichar);
+ virtual void onSizeChange();
+
+ virtual SkCanvas* beforeChildren(SkCanvas*);
+ virtual void afterChildren(SkCanvas*);
+ virtual void beforeChild(SkView* child, SkCanvas* canvas);
+ virtual void afterChild(SkView* child, SkCanvas* canvas);
+
+ virtual bool onEvent(const SkEvent& evt);
+ virtual bool onQuery(SkEvent* evt);
+
+ virtual bool onDispatchClick(int x, int y, Click::State);
+ virtual bool onClick(Click* click);
+ virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
+
+private:
+ int fCurrIndex;
+
+ SkPicture* fPicture;
+ SkGpuCanvas* fGpuCanvas;
+ GrContext* fGrContext;
+ SkPath fClipPath;
+
+ SkTouchGesture fGesture;
+ SkScalar fZoomLevel;
+ SkScalar fZoomScale;
+
+ enum CanvasType {
+ kRaster_CanvasType,
+ kPicture_CanvasType,
+ kGPU_CanvasType
+ };
+ CanvasType fCanvasType;
+
+ bool fUseClip;
+ bool fNClip;
+ bool fRepeatDrawing;
+ bool fAnimating;
+ bool fRotate;
+ bool fScale;
+ bool fRequestGrabImage;
+ bool fUsePipe;
+ bool fMeasureFPS;
+ SkMSec fMeasureFPS_Time;
+
+ // The following are for the 'fatbits' drawing
+ // Latest position of the mouse.
+ int fMouseX, fMouseY;
+ int fFatBitsScale;
+ // Used by the text showing position and color values.
+ SkTypeface* fTypeface;
+ bool fShowZoomer;
+
+ SkTriState fLCDState;
+ SkTriState fAAState;
+ SkTriState fFilterState;
+ SkTriState fHintingState;
+ unsigned fFlipAxis;
+
+ int fScrollTestX, fScrollTestY;
+ SkScalar fZoomCenterX, fZoomCenterY;
+
+ bool make3DReady();
+
+ void loadView(SkView*);
+ void updateTitle();
+
+ void toggleZoomer();
+ bool zoomIn();
+ bool zoomOut();
+ void updatePointer(int x, int y);
+ void showZoomer(SkCanvas* canvas);
+
+ void postAnimatingEvent();
+
+ static CanvasType cycle_canvastype(CanvasType);
+
+ typedef SkOSWindow INHERITED;
+};
+
+#endif