1 /*
2 * Copyright 2010, 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 "NavigationPlugin.h"
27
28 #include <stdio.h>
29 #include <sys/time.h>
30 #include <time.h>
31 #include <math.h>
32 #include <string.h>
33
34 extern NPNetscapeFuncs* browser;
35 extern ANPLogInterfaceV0 gLogI;
36 extern ANPCanvasInterfaceV0 gCanvasI;
37 extern ANPPaintInterfaceV0 gPaintI;
38 extern ANPTypefaceInterfaceV0 gTypefaceI;
39 extern ANPWindowInterfaceV0 gWindowI;
40
41
inval(NPP instance)42 static void inval(NPP instance) {
43 browser->invalidaterect(instance, NULL);
44 }
45
rnd16(float x,int inset)46 static uint16_t rnd16(float x, int inset) {
47 int ix = (int)roundf(x) + inset;
48 if (ix < 0) {
49 ix = 0;
50 }
51 return static_cast<uint16_t>(ix);
52 }
53
inval(NPP instance,const ANPRectF & r,bool doAA)54 static void inval(NPP instance, const ANPRectF& r, bool doAA) {
55 const int inset = doAA ? -1 : 0;
56
57 PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
58 NPRect inval;
59 inval.left = rnd16(r.left, inset);
60 inval.top = rnd16(r.top, inset);
61 inval.right = rnd16(r.right, -inset);
62 inval.bottom = rnd16(r.bottom, -inset);
63 browser->invalidaterect(instance, &inval);
64 }
65
66 ///////////////////////////////////////////////////////////////////////////////
67
NavigationPlugin(NPP inst)68 NavigationPlugin::NavigationPlugin(NPP inst) : SubPlugin(inst) {
69
70 m_hasFocus = false;
71 m_activeNav = NULL;
72
73 m_paintDisabled = gPaintI.newPaint();
74 gPaintI.setFlags(m_paintDisabled, gPaintI.getFlags(m_paintDisabled) | kAntiAlias_ANPPaintFlag);
75 gPaintI.setColor(m_paintDisabled, 0xFFFFFFFF);
76
77 m_paintActive = gPaintI.newPaint();
78 gPaintI.setFlags(m_paintActive, gPaintI.getFlags(m_paintActive) | kAntiAlias_ANPPaintFlag);
79 gPaintI.setColor(m_paintActive, 0xFFFFFF00);
80
81 //register for key events
82 ANPEventFlags flags = kKey_ANPEventFlag;
83 NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
84 if (err != NPERR_NO_ERROR) {
85 gLogI.log(kError_ANPLogType, "Error selecting input events.");
86 }
87 }
88
~NavigationPlugin()89 NavigationPlugin::~NavigationPlugin() {
90 gPaintI.deletePaint(m_paintDisabled);
91 gPaintI.deletePaint(m_paintActive);
92 }
93
supportsDrawingModel(ANPDrawingModel model)94 bool NavigationPlugin::supportsDrawingModel(ANPDrawingModel model) {
95 return (model == kBitmap_ANPDrawingModel);
96 }
97
drawPlugin(const ANPBitmap & bitmap,const ANPRectI & clip)98 void NavigationPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
99 ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
100
101 ANPRectF clipR;
102 clipR.left = clip.left;
103 clipR.top = clip.top;
104 clipR.right = clip.right;
105 clipR.bottom = clip.bottom;
106 gCanvasI.clipRect(canvas, &clipR);
107
108 draw(canvas);
109 gCanvasI.deleteCanvas(canvas);
110 }
111
draw(ANPCanvas * canvas)112 void NavigationPlugin::draw(ANPCanvas* canvas) {
113 NPP instance = this->inst();
114 PluginObject *obj = (PluginObject*) instance->pdata;
115
116 const int W = obj->window->width;
117 const int H = obj->window->height;
118 const int Wm = W/2;
119 const int Hm = H/2;
120
121 // color the plugin canvas
122 gCanvasI.drawColor(canvas, (m_hasFocus) ? 0xFFCDCDCD : 0xFF545454);
123
124 // draw the nav up box (5 px from the top edge)
125 m_navUp.left = Wm - 15;
126 m_navUp.top = 5;
127 m_navUp.right = m_navUp.left + 30;
128 m_navUp.bottom = m_navUp.top + 30;
129 gCanvasI.drawRect(canvas, &m_navUp, getPaint(&m_navUp));
130
131 // draw the nav down box (5 px from the bottom edge)
132 m_navDown.left = Wm - 15;
133 m_navDown.top = H - (30 + 5);
134 m_navDown.right = m_navDown.left + 30;
135 m_navDown.bottom = m_navDown.top + 30;
136 gCanvasI.drawRect(canvas, &m_navDown, getPaint(&m_navDown));
137
138 // draw the nav left box (5 px from the left edge)
139 m_navLeft.left = 5;
140 m_navLeft.top = Hm - 15;
141 m_navLeft.right = m_navLeft.left + 30;
142 m_navLeft.bottom = m_navLeft.top + 30;
143 gCanvasI.drawRect(canvas, &m_navLeft, getPaint(&m_navLeft));
144
145 // draw the nav right box (5 px from the right edge)
146 m_navRight.left = W - (30 + 5);
147 m_navRight.top = Hm - 15;
148 m_navRight.right = m_navRight.left + 30;
149 m_navRight.bottom = m_navRight.top + 30;
150 gCanvasI.drawRect(canvas, &m_navRight, getPaint(&m_navRight));
151
152 // draw the nav center box
153 m_navCenter.left = Wm - 15;
154 m_navCenter.top = Hm - 15;
155 m_navCenter.right = m_navCenter.left + 30;
156 m_navCenter.bottom = m_navCenter.top + 30;
157 gCanvasI.drawRect(canvas, &m_navCenter, getPaint(&m_navCenter));
158
159 gLogI.log(kDebug_ANPLogType, "----%p Drawing Plugin", inst());
160 }
161
getPaint(ANPRectF * input)162 ANPPaint* NavigationPlugin::getPaint(ANPRectF* input) {
163 return (input == m_activeNav) ? m_paintActive : m_paintDisabled;
164 }
165
handleEvent(const ANPEvent * evt)166 int16_t NavigationPlugin::handleEvent(const ANPEvent* evt) {
167 NPP instance = this->inst();
168
169 switch (evt->eventType) {
170 case kDraw_ANPEventType:
171 switch (evt->data.draw.model) {
172 case kBitmap_ANPDrawingModel:
173 drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
174 return 1;
175 default:
176 break; // unknown drawing model
177 }
178 break;
179
180 case kLifecycle_ANPEventType:
181 if (evt->data.lifecycle.action == kLoseFocus_ANPLifecycleAction) {
182 gLogI.log(kDebug_ANPLogType, "----%p Loosing Focus", instance);
183 m_hasFocus = false;
184 inval(instance);
185 return 1;
186 }
187 else if (evt->data.lifecycle.action == kGainFocus_ANPLifecycleAction) {
188 gLogI.log(kDebug_ANPLogType, "----%p Gaining Focus", instance);
189 m_hasFocus = true;
190 inval(instance);
191 return 1;
192 }
193 break;
194
195 case kMouse_ANPEventType:
196 return 1;
197
198 case kKey_ANPEventType:
199 if (evt->data.key.action == kDown_ANPKeyAction) {
200 bool result = handleNavigation(evt->data.key.nativeCode);
201 inval(instance);
202 return result;
203 }
204 return 1;
205
206 default:
207 break;
208 }
209 return 0; // unknown or unhandled event
210 }
211
handleNavigation(ANPKeyCode keyCode)212 bool NavigationPlugin::handleNavigation(ANPKeyCode keyCode) {
213 NPP instance = this->inst();
214
215 gLogI.log(kDebug_ANPLogType, "----%p Received Key %d", instance, keyCode);
216
217 switch (keyCode) {
218 case kDpadUp_ANPKeyCode:
219 m_activeNav = &m_navUp;
220 break;
221 case kDpadDown_ANPKeyCode:
222 m_activeNav = &m_navDown;
223 break;
224 case kDpadLeft_ANPKeyCode:
225 m_activeNav = &m_navLeft;
226 break;
227 case kDpadRight_ANPKeyCode:
228 m_activeNav = &m_navRight;
229 break;
230 case kDpadCenter_ANPKeyCode:
231 m_activeNav = &m_navCenter;
232 break;
233 case kQ_ANPKeyCode:
234 case kDel_ANPKeyCode:
235 m_activeNav = NULL;
236 return false;
237 default:
238 m_activeNav = NULL;
239 break;
240 }
241 return true;
242 }
243