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
This commit is contained in:
Scroggo 2011-06-15 16:49:08 +00:00
parent 25e92838a9
commit 2c8208f3a4
11 changed files with 427 additions and 192 deletions

View File

@ -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 := \

View File

@ -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>

View File

@ -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

View File

@ -15,17 +15,18 @@
*
*/
#include <jni.h>
#include "SkCanvas.h"
#include "SkEvent.h"
#include "SkWindow.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 <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();
}

View File

@ -15,6 +15,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"
@ -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"
-->

View File

@ -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>

View File

@ -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");

View File

@ -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);
}
}
}
}

View File

@ -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&);

View File

@ -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();
void SampleWindow::setZoomCenter(float x, float y)
{
fZoomCenterX = SkFloatToScalar(x);
fZoomCenterY = SkFloatToScalar(y);
}
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;
};
#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
}

145
samplecode/SampleApp.h Normal file
View File

@ -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