blob: abe6805cee2e9bba547e8d64c7328a3f66fd7a9b [file] [log] [blame]
Derek Sollenberger4fb83e62009-07-27 16:40:13 -04001/*
2 * Copyright 2009, The Android Open Source Project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "PaintPlugin.h"
27
28#include <fcntl.h>
29#include <math.h>
30#include <string.h>
31
32extern NPNetscapeFuncs* browser;
33extern ANPLogInterfaceV0 gLogI;
34extern ANPCanvasInterfaceV0 gCanvasI;
35extern ANPPaintInterfaceV0 gPaintI;
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -040036extern ANPPathInterfaceV0 gPathI;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040037extern ANPSurfaceInterfaceV0 gSurfaceI;
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -050038extern ANPSystemInterfaceV0 gSystemI;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040039extern ANPTypefaceInterfaceV0 gTypefaceI;
Derek Sollenberger7364d2b2010-03-01 08:18:02 -050040extern ANPWindowInterfaceV0 gWindowI;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040041
42///////////////////////////////////////////////////////////////////////////////
43
Derek Sollenberger08581f12009-09-08 18:36:29 -040044PaintPlugin::PaintPlugin(NPP inst) : SurfaceSubPlugin(inst) {
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040045
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040046 m_isTouchActive = false;
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -040047 m_isTouchCurrentInput = true;
48 m_activePaintColor = s_redColor;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040049
50 memset(&m_drawingSurface, 0, sizeof(m_drawingSurface));
51 memset(&m_inputToggle, 0, sizeof(m_inputToggle));
52 memset(&m_colorToggle, 0, sizeof(m_colorToggle));
Derek Sollenberger7364d2b2010-03-01 08:18:02 -050053 memset(&m_fullScreenToggle, 0, sizeof(m_fullScreenToggle));
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040054 memset(&m_clearSurface, 0, sizeof(m_clearSurface));
55
56 // initialize the drawing surface
Derek Sollenberger08581f12009-09-08 18:36:29 -040057 m_surface = NULL;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040058
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -040059 // initialize the path
60 m_touchPath = gPathI.newPath();
61 if(!m_touchPath)
Derek Sollenbergere62ce172009-11-30 11:52:06 -050062 gLogI.log(kError_ANPLogType, "----%p Unable to create the touch path", inst);
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -040063
64 // initialize the paint colors
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040065 m_paintSurface = gPaintI.newPaint();
66 gPaintI.setFlags(m_paintSurface, gPaintI.getFlags(m_paintSurface) | kAntiAlias_ANPPaintFlag);
67 gPaintI.setColor(m_paintSurface, 0xFFC0C0C0);
68 gPaintI.setTextSize(m_paintSurface, 18);
69
70 m_paintButton = gPaintI.newPaint();
71 gPaintI.setFlags(m_paintButton, gPaintI.getFlags(m_paintButton) | kAntiAlias_ANPPaintFlag);
72 gPaintI.setColor(m_paintButton, 0xFFA8A8A8);
73
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -040074 // initialize the typeface (set the colors)
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040075 ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
76 gPaintI.setTypeface(m_paintSurface, tf);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040077 gTypefaceI.unref(tf);
78
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040079 //register for touch events
80 ANPEventFlags flags = kTouch_ANPEventFlag;
81 NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
82 if (err != NPERR_NO_ERROR) {
Derek Sollenbergere62ce172009-11-30 11:52:06 -050083 gLogI.log(kError_ANPLogType, "Error selecting input events.");
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040084 }
85}
86
87PaintPlugin::~PaintPlugin() {
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -040088 gPathI.deletePath(m_touchPath);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040089 gPaintI.deletePaint(m_paintSurface);
90 gPaintI.deletePaint(m_paintButton);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040091
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -050092 setContext(NULL);
93 destroySurface();
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040094}
95
96ANPCanvas* PaintPlugin::getCanvas(ANPRectI* dirtyRect) {
97
98 ANPBitmap bitmap;
Derek Sollenberger08581f12009-09-08 18:36:29 -040099 JNIEnv* env = NULL;
Derek Sollenbergerb8947ee2009-10-05 14:40:18 -0400100 if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
Derek Sollenberger08581f12009-09-08 18:36:29 -0400101 !gSurfaceI.lock(env, m_surface, &bitmap, dirtyRect)) {
102 return NULL;
103 }
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400104
105 ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
106
107 // clip the canvas to the dirty rect b/c the surface is only required to
108 // copy a minimum of the dirty rect and may copy more. The clipped canvas
109 // however will never write to pixels outside of the clipped area.
110 if (dirtyRect) {
111 ANPRectF clipR;
112 clipR.left = dirtyRect->left;
113 clipR.top = dirtyRect->top;
114 clipR.right = dirtyRect->right;
115 clipR.bottom = dirtyRect->bottom;
116 gCanvasI.clipRect(canvas, &clipR);
117 }
118
119 return canvas;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400120}
121
122ANPCanvas* PaintPlugin::getCanvas(ANPRectF* dirtyRect) {
123
124 ANPRectI newRect;
125 newRect.left = (int) dirtyRect->left;
126 newRect.top = (int) dirtyRect->top;
127 newRect.right = (int) dirtyRect->right;
128 newRect.bottom = (int) dirtyRect->bottom;
129
130 return getCanvas(&newRect);
131}
132
133void PaintPlugin::releaseCanvas(ANPCanvas* canvas) {
Derek Sollenberger08581f12009-09-08 18:36:29 -0400134 JNIEnv* env = NULL;
Derek Sollenbergerb8947ee2009-10-05 14:40:18 -0400135 if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
Derek Sollenberger08581f12009-09-08 18:36:29 -0400136 gSurfaceI.unlock(env, m_surface);
137 }
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400138 gCanvasI.deleteCanvas(canvas);
139}
140
141void PaintPlugin::drawCleanPlugin(ANPCanvas* canvas) {
142 NPP instance = this->inst();
143 PluginObject *obj = (PluginObject*) instance->pdata;
144
145 // if no canvas get a locked canvas
146 if (!canvas)
147 canvas = getCanvas();
148
149 if (!canvas)
150 return;
151
152 const float buttonWidth = 60;
153 const float buttonHeight = 30;
154 const int W = obj->window->width;
155 const int H = obj->window->height;
156
157 // color the plugin canvas
158 gCanvasI.drawColor(canvas, 0xFFCDCDCD);
159
160 // get font metrics
161 ANPFontMetrics fontMetrics;
162 gPaintI.getFontMetrics(m_paintSurface, &fontMetrics);
163
164 // draw the input toggle button
165 m_inputToggle.left = 5;
166 m_inputToggle.top = H - buttonHeight - 5;
167 m_inputToggle.right = m_inputToggle.left + buttonWidth;
168 m_inputToggle.bottom = m_inputToggle.top + buttonHeight;
169 gCanvasI.drawRect(canvas, &m_inputToggle, m_paintButton);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400170 const char* inputText = m_isTouchCurrentInput ? "Touch" : "Mouse";
171 gCanvasI.drawText(canvas, inputText, strlen(inputText), m_inputToggle.left + 5,
172 m_inputToggle.top - fontMetrics.fTop, m_paintSurface);
173
174 // draw the color selector button
Derek Sollenberger7364d2b2010-03-01 08:18:02 -0500175 m_colorToggle.left = (W/3) - (buttonWidth/2);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400176 m_colorToggle.top = H - buttonHeight - 5;
177 m_colorToggle.right = m_colorToggle.left + buttonWidth;
178 m_colorToggle.bottom = m_colorToggle.top + buttonHeight;
179 gCanvasI.drawRect(canvas, &m_colorToggle, m_paintButton);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400180 const char* colorText = getColorText();
181 gCanvasI.drawText(canvas, colorText, strlen(colorText), m_colorToggle.left + 5,
182 m_colorToggle.top - fontMetrics.fTop, m_paintSurface);
183
Derek Sollenberger7364d2b2010-03-01 08:18:02 -0500184 // draw the full-screen toggle button
185 m_fullScreenToggle.left = ((W*2)/3) - (buttonWidth/2);
186 m_fullScreenToggle.top = H - buttonHeight - 5;
187 m_fullScreenToggle.right = m_fullScreenToggle.left + buttonWidth;
188 m_fullScreenToggle.bottom = m_fullScreenToggle.top + buttonHeight;
189 gCanvasI.drawRect(canvas, &m_fullScreenToggle, m_paintButton);
190 const char* fullScreenText = "Full";
191 gCanvasI.drawText(canvas, fullScreenText, strlen(fullScreenText),
192 m_fullScreenToggle.left + 5,
193 m_fullScreenToggle.top - fontMetrics.fTop, m_paintSurface);
194
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400195 // draw the clear canvas button
196 m_clearSurface.left = W - buttonWidth - 5;
197 m_clearSurface.top = H - buttonHeight - 5;
198 m_clearSurface.right = m_clearSurface.left + buttonWidth;
199 m_clearSurface.bottom = m_clearSurface.top + buttonHeight;
200 gCanvasI.drawRect(canvas, &m_clearSurface, m_paintButton);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400201 const char* clearText = "Clear";
202 gCanvasI.drawText(canvas, clearText, strlen(clearText), m_clearSurface.left + 5,
203 m_clearSurface.top - fontMetrics.fTop, m_paintSurface);
204
205 // draw the drawing surface box (5 px from the edge)
206 m_drawingSurface.left = 5;
207 m_drawingSurface.top = 5;
208 m_drawingSurface.right = W - 5;
209 m_drawingSurface.bottom = m_colorToggle.top - 5;
210 gCanvasI.drawRect(canvas, &m_drawingSurface, m_paintSurface);
211
212 // release the canvas
213 releaseCanvas(canvas);
214}
215
216const char* PaintPlugin::getColorText() {
217
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400218 if (m_activePaintColor == s_blueColor)
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400219 return "Blue";
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400220 else if (m_activePaintColor == s_greenColor)
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400221 return "Green";
222 else
223 return "Red";
224}
225
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500226jobject PaintPlugin::getSurface() {
227 if (m_surface) {
228 return m_surface;
229 }
Derek Sollenberger08581f12009-09-08 18:36:29 -0400230
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500231 // load the appropriate java class and instantiate it
232 JNIEnv* env = NULL;
233 if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
234 gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
235 return NULL;
236 }
Derek Sollenberger08581f12009-09-08 18:36:29 -0400237
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500238 const char* className = "com.android.sampleplugin.PaintSurface";
239 jclass paintClass = gSystemI.loadJavaClass(inst(), className);
240
241 if(!paintClass) {
242 gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
243 return NULL;
244 }
245
Derek Sollenberger08581f12009-09-08 18:36:29 -0400246 PluginObject *obj = (PluginObject*) inst()->pdata;
247 const int pW = obj->window->width;
248 const int pH = obj->window->height;
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500249
250 jmethodID constructor = env->GetMethodID(paintClass, "<init>", "(Landroid/content/Context;III)V");
251 jobject paintSurface = env->NewObject(paintClass, constructor, m_context, (int)inst(), pW, pH);
252
253 if(!paintSurface) {
254 gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
255 return NULL;
256 }
257
258 m_surface = env->NewGlobalRef(paintSurface);
259 return m_surface;
Derek Sollenberger08581f12009-09-08 18:36:29 -0400260}
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500261
262void PaintPlugin::destroySurface() {
Derek Sollenberger08581f12009-09-08 18:36:29 -0400263 JNIEnv* env = NULL;
Derek Sollenbergerb8947ee2009-10-05 14:40:18 -0400264 if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500265
266 // detach the native code from the object
267 jclass javaClass = env->GetObjectClass(m_surface);
268 jmethodID invalMethod = env->GetMethodID(javaClass, "invalidateNPP", "()V");
269 env->CallVoidMethod(m_surface, invalMethod);
270
Derek Sollenberger08581f12009-09-08 18:36:29 -0400271 env->DeleteGlobalRef(m_surface);
272 m_surface = NULL;
273 }
274}
275
Ben Murdoch3b6f45d2010-05-12 14:09:26 +0100276int16_t PaintPlugin::handleEvent(const ANPEvent* evt) {
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400277 switch (evt->eventType) {
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400278 case kTouch_ANPEventType: {
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400279 float x = (float) evt->data.touch.x;
280 float y = (float) evt->data.touch.y;
281 if (kDown_ANPTouchAction == evt->data.touch.action && m_isTouchCurrentInput) {
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400282
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400283 ANPRectF* rect = validTouch(evt->data.touch.x, evt->data.touch.y);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400284 if(rect == &m_drawingSurface) {
285 m_isTouchActive = true;
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400286 gPathI.moveTo(m_touchPath, x, y);
287 paintTouch();
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400288 return 1;
289 }
290
291 } else if (kMove_ANPTouchAction == evt->data.touch.action && m_isTouchActive) {
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400292 gPathI.lineTo(m_touchPath, x, y);
293 paintTouch();
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400294 return 1;
295 } else if (kUp_ANPTouchAction == evt->data.touch.action && m_isTouchActive) {
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400296 gPathI.lineTo(m_touchPath, x, y);
297 paintTouch();
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400298 m_isTouchActive = false;
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400299 gPathI.reset(m_touchPath);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400300 return 1;
301 } else if (kCancel_ANPTouchAction == evt->data.touch.action) {
302 m_isTouchActive = false;
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400303 gPathI.reset(m_touchPath);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400304 return 1;
Bart Sears33638a72010-03-15 15:52:54 -0700305 } else if (kDoubleTap_ANPTouchAction == evt->data.touch.action) {
306 gWindowI.requestCenterFitZoom(inst());
307 return 1;
Grace Kloba103e5762010-03-12 18:35:23 -0800308
Bart Sears33638a72010-03-15 15:52:54 -0700309 }
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400310 break;
311 }
312 case kMouse_ANPEventType: {
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400313
314 if (m_isTouchActive)
Derek Sollenbergere62ce172009-11-30 11:52:06 -0500315 gLogI.log(kError_ANPLogType, "----%p Received unintended mouse event", inst());
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400316
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400317 if (kDown_ANPMouseAction == evt->data.mouse.action) {
318 ANPRectF* rect = validTouch(evt->data.mouse.x, evt->data.mouse.y);
319 if (rect == &m_drawingSurface)
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400320 paintMouse(evt->data.mouse.x, evt->data.mouse.y);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400321 else if (rect == &m_inputToggle)
322 toggleInputMethod();
323 else if (rect == &m_colorToggle)
324 togglePaintColor();
Derek Sollenberger7364d2b2010-03-01 08:18:02 -0500325 else if (rect == &m_fullScreenToggle)
326 gWindowI.requestFullScreen(inst());
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400327 else if (rect == &m_clearSurface)
328 drawCleanPlugin();
329 }
330 return 1;
331 }
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500332 case kCustom_ANPEventType: {
333
334 switch (evt->data.other[0]) {
335 case kSurfaceCreated_CustomEvent:
336 gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceCreated");
Derek Sollenberger7364d2b2010-03-01 08:18:02 -0500337 /* The second draw call is added to cover up a problem in this
338 plugin and is not a recommended usage pattern. This plugin
339 does not correctly make partial updates to the double
340 buffered surface and this second call hides that problem.
341 */
342 drawCleanPlugin();
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500343 drawCleanPlugin();
344 break;
345 case kSurfaceChanged_CustomEvent: {
346 gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceChanged");
347
348 int width = evt->data.other[1];
349 int height = evt->data.other[2];
350
351 PluginObject *obj = (PluginObject*) inst()->pdata;
352 const int pW = obj->window->width;
353 const int pH = obj->window->height;
354 // compare to the plugin's surface dimensions
355 if (pW != width || pH != height)
356 gLogI.log(kError_ANPLogType,
357 "----%p Invalid Surface Dimensions (%d,%d):(%d,%d)",
358 inst(), pW, pH, width, height);
359 break;
360 }
361 case kSurfaceDestroyed_CustomEvent:
362 gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceDestroyed");
363 break;
364 }
365 break; // end KCustom_ANPEventType
366 }
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400367 default:
368 break;
369 }
370 return 0; // unknown or unhandled event
371}
372
373ANPRectF* PaintPlugin::validTouch(int x, int y) {
374
375 //convert to float
376 float fx = (int) x;
377 float fy = (int) y;
378
379 if (fx > m_drawingSurface.left && fx < m_drawingSurface.right && fy > m_drawingSurface.top && fy < m_drawingSurface.bottom)
380 return &m_drawingSurface;
381 else if (fx > m_inputToggle.left && fx < m_inputToggle.right && fy > m_inputToggle.top && fy < m_inputToggle.bottom)
382 return &m_inputToggle;
383 else if (fx > m_colorToggle.left && fx < m_colorToggle.right && fy > m_colorToggle.top && fy < m_colorToggle.bottom)
384 return &m_colorToggle;
Derek Sollenberger7364d2b2010-03-01 08:18:02 -0500385 else if (fx > m_fullScreenToggle.left && fx < m_fullScreenToggle.right && fy > m_fullScreenToggle.top && fy < m_fullScreenToggle.bottom)
386 return &m_fullScreenToggle;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400387 else if (fx > m_clearSurface.left && fx < m_clearSurface.right && fy > m_clearSurface.top && fy < m_clearSurface.bottom)
388 return &m_clearSurface;
389 else
390 return NULL;
391}
392
393void PaintPlugin::toggleInputMethod() {
394 m_isTouchCurrentInput = !m_isTouchCurrentInput;
395
396 // lock only the input toggle and redraw the canvas
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400397 ANPCanvas* lockedCanvas = getCanvas(&m_inputToggle);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400398 drawCleanPlugin(lockedCanvas);
399}
400
401void PaintPlugin::togglePaintColor() {
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400402 if (m_activePaintColor == s_blueColor)
403 m_activePaintColor = s_redColor;
404 else if (m_activePaintColor == s_greenColor)
405 m_activePaintColor = s_blueColor;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400406 else
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400407 m_activePaintColor = s_greenColor;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400408
409 // lock only the color toggle and redraw the canvas
410 ANPCanvas* lockedCanvas = getCanvas(&m_colorToggle);
411 drawCleanPlugin(lockedCanvas);
412}
413
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400414void PaintPlugin::paintMouse(int x, int y) {
415 //TODO do not paint outside the drawing surface
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400416
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400417 //create the paint color
418 ANPPaint* fillPaint = gPaintI.newPaint();
419 gPaintI.setFlags(fillPaint, gPaintI.getFlags(fillPaint) | kAntiAlias_ANPPaintFlag);
420 gPaintI.setStyle(fillPaint, kFill_ANPPaintStyle);
421 gPaintI.setColor(fillPaint, m_activePaintColor);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400422
423 // handle the simple "mouse" paint (draw a point)
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400424 ANPRectF point;
425 point.left = (float) x-3;
426 point.top = (float) y-3;
427 point.right = (float) x+3;
428 point.bottom = (float) y+3;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400429
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400430 // get a canvas that is only locked around the point and draw it
431 ANPCanvas* canvas = getCanvas(&point);
432 gCanvasI.drawOval(canvas, &point, fillPaint);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400433
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400434 // clean up
435 releaseCanvas(canvas);
436 gPaintI.deletePaint(fillPaint);
437}
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400438
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400439void PaintPlugin::paintTouch() {
440 //TODO do not paint outside the drawing surface
441
442 //create the paint color
443 ANPPaint* strokePaint = gPaintI.newPaint();
444 gPaintI.setFlags(strokePaint, gPaintI.getFlags(strokePaint) | kAntiAlias_ANPPaintFlag);
445 gPaintI.setColor(strokePaint, m_activePaintColor);
446 gPaintI.setStyle(strokePaint, kStroke_ANPPaintStyle);
447 gPaintI.setStrokeWidth(strokePaint, 6.0);
448 gPaintI.setStrokeCap(strokePaint, kRound_ANPPaintCap);
449 gPaintI.setStrokeJoin(strokePaint, kRound_ANPPaintJoin);
450
451 // handle the complex "touch" paint (draw a line)
452 ANPRectF bounds;
453 gPathI.getBounds(m_touchPath, &bounds);
454
455 // get a canvas that is only locked around the point and draw the path
456 ANPCanvas* canvas = getCanvas(&bounds);
457 gCanvasI.drawPath(canvas, m_touchPath, strokePaint);
458
459 // clean up
460 releaseCanvas(canvas);
461 gPaintI.deletePaint(strokePaint);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400462}