Adding focus and keyboard support to the form plugin.
diff --git a/samples/BrowserPlugin/jni/form/FormPlugin.cpp b/samples/BrowserPlugin/jni/form/FormPlugin.cpp
index 278645c..0fdcfd0 100644
--- a/samples/BrowserPlugin/jni/form/FormPlugin.cpp
+++ b/samples/BrowserPlugin/jni/form/FormPlugin.cpp
@@ -81,6 +81,7 @@
FormPlugin::FormPlugin(NPP inst) : SubPlugin(inst) {
+ m_hasFocus = false;
m_activeInput = NULL;
memset(&m_usernameInput, 0, sizeof(m_usernameInput));
@@ -133,27 +134,26 @@
const int H = obj->window->height;
// color the plugin canvas
- gCanvasI.drawColor(canvas, 0xFFCDCDCD);
+ gCanvasI.drawColor(canvas, (m_hasFocus) ? 0xFFCDCDCD : 0xFF545454);
// draw the username box (5 px from the top edge)
- inval(instance, m_usernameInput.rect, true);
m_usernameInput.rect.left = 5;
m_usernameInput.rect.top = 5;
m_usernameInput.rect.right = W - 5;
m_usernameInput.rect.bottom = m_usernameInput.rect.top + inputHeight;
gCanvasI.drawRect(canvas, &m_usernameInput.rect, getPaint(&m_usernameInput));
drawText(canvas, m_usernameInput);
- inval(instance, m_usernameInput.rect, true);
// draw the password box (5 px from the bottom edge)
- inval(instance, m_passwordInput.rect, true);
m_passwordInput.rect.left = 5;
m_passwordInput.rect.top = H - (inputHeight + 5);
m_passwordInput.rect.right = W - 5;
m_passwordInput.rect.bottom = m_passwordInput.rect.top + inputHeight;
gCanvasI.drawRect(canvas, &m_passwordInput.rect, getPaint(&m_passwordInput));
drawPassword(canvas, m_passwordInput);
- inval(instance, m_passwordInput.rect, true);
+
+ //invalidate the canvas
+ //inval(instance);
}
ANPPaint* FormPlugin::getPaint(TextInput* input) {
@@ -173,7 +173,26 @@
void FormPlugin::drawPassword(ANPCanvas* canvas, TextInput passwordInput) {
- //TODO draw circles instead of the actual text
+ // get font metrics
+ ANPFontMetrics fontMetrics;
+ gPaintI.getFontMetrics(m_paintText, &fontMetrics);
+
+ // comput the circle dimensions and initial location
+ float initialX = passwordInput.rect.left + 5;
+ float ovalBottom = passwordInput.rect.bottom - 2;
+ float ovalTop = ovalBottom - (fontMetrics.fBottom - fontMetrics.fTop);
+ float ovalWidth = ovalBottom - ovalTop;
+ float ovalSpacing = 3;
+
+ // draw circles instead of the actual text
+ for (uint32_t x = 0; x < passwordInput.charPtr; x++) {
+ ANPRectF oval;
+ oval.left = initialX + ((ovalWidth + ovalSpacing) * (float) x);
+ oval.right = oval.left + ovalWidth;
+ oval.top = ovalTop;
+ oval.bottom = ovalBottom;
+ gCanvasI.drawOval(canvas, &oval, m_paintText);
+ }
}
int16 FormPlugin::handleEvent(const ANPEvent* evt) {
@@ -192,17 +211,23 @@
case kLifecycle_ANPEventType:
if (evt->data.lifecycle.action == kLooseFocus_ANPLifecycleAction) {
+ gLogI.log(instance, kDebug_ANPLogType, "----%p Loosing Focus", instance);
if (m_activeInput) {
-
// hide the keyboard
- //gWindowI.showKeyboard(instance, false);
- gLogI.log(instance, kDebug_ANPLogType, "----%p Hiding Keyboard2", instance);
+ gWindowI.showKeyboard(instance, false);
- //inval the plugin
+ //reset the activeInput
m_activeInput = NULL;
- inval(instance);
-
}
+
+ m_hasFocus = false;
+ inval(instance);
+ return 1;
+ }
+ else if (evt->data.lifecycle.action == kGainFocus_ANPLifecycleAction) {
+ gLogI.log(instance, kDebug_ANPLogType, "----%p Gaining Focus", instance);
+ m_hasFocus = true;
+ inval(instance);
return 1;
}
break;
@@ -217,21 +242,11 @@
if (currentInput)
gWindowI.showKeyboard(instance, true);
- else if (m_activeInput) {
+ else if (m_activeInput)
gWindowI.showKeyboard(instance, false);
- gLogI.log(instance, kDebug_ANPLogType, "----%p Hiding Keyboard", instance);
- }
-
- if (currentInput == m_activeInput)
- return 1;
-
- if (m_activeInput)
- inval(instance, m_activeInput->rect, true); // inval the old
-
- m_activeInput = currentInput; // set the new active input
- if (m_activeInput)
- inval(instance, m_activeInput->rect, true); // inval the new
+ if (currentInput != m_activeInput)
+ switchActiveInput(currentInput);
return 1;
}
@@ -244,8 +259,7 @@
//handle navigation keys
if (evt->data.key.nativeCode >= kDpadUp_ANPKeyCode
&& evt->data.key.nativeCode <= kDpadCenter_ANPKeyCode) {
- gLogI.log(instance, kDebug_ANPLogType, "----%p Recvd Nav Key", instance);
- return 0;
+ return handleNavigation(evt->data.key.nativeCode) ? 1 : 0;
}
if (m_activeInput) {
@@ -279,6 +293,46 @@
return 0; // unknown or unhandled event
}
+void FormPlugin::switchActiveInput(TextInput* newInput) {
+ NPP instance = this->inst();
+
+ if (m_activeInput)
+ inval(instance, m_activeInput->rect, true); // inval the old
+
+ m_activeInput = newInput; // set the new active input
+
+ if (m_activeInput)
+ inval(instance, m_activeInput->rect, true); // inval the new
+}
+
+bool FormPlugin::handleNavigation(ANPKeyCode keyCode) {
+ NPP instance = this->inst();
+
+ gLogI.log(instance, kDebug_ANPLogType, "----%p Recvd Nav Key %d", instance, keyCode);
+
+ if (!m_activeInput) {
+ switchActiveInput(&m_usernameInput);
+ scrollIntoView(m_activeInput);
+ return true;
+ }
+ else if (m_activeInput == &m_usernameInput) {
+ if (keyCode == kDpadDown_ANPKeyCode) {
+ switchActiveInput(&m_passwordInput);
+ scrollIntoView(m_activeInput);
+ return true;
+ }
+ }
+ else if (m_activeInput == &m_passwordInput) {
+ if (keyCode == kDpadUp_ANPKeyCode) {
+ switchActiveInput(&m_usernameInput);
+ scrollIntoView(m_activeInput);
+ return true;
+ }
+ }
+
+ return false;
+}
+
void FormPlugin::handleTextInput(TextInput* input, ANPKeyCode keyCode, int32_t unichar) {
NPP instance = this->inst();
@@ -316,8 +370,6 @@
inputRect.right = inputRect.left + (input->rect.right - input->rect.left);
inputRect.bottom = inputRect.top + (input->rect.bottom - input->rect.top);
- gLogI.log(instance, kDebug_ANPLogType, "----%p Checking Rect Visibility", instance);
-
// if the rect is contained within visible window then do nothing
if (inputRect.left > m_visibleRect.left
&& inputRect.right < m_visibleRect.right
diff --git a/samples/BrowserPlugin/jni/form/FormPlugin.h b/samples/BrowserPlugin/jni/form/FormPlugin.h
index 71964d5..4745b3b 100644
--- a/samples/BrowserPlugin/jni/form/FormPlugin.h
+++ b/samples/BrowserPlugin/jni/form/FormPlugin.h
@@ -43,6 +43,8 @@
virtual int16 handleEvent(const ANPEvent* evt);
private:
+ bool m_hasFocus;
+
TextInput* m_activeInput;
TextInput m_usernameInput;
TextInput m_passwordInput;
@@ -56,8 +58,10 @@
void drawText(ANPCanvas*, TextInput);
void drawPassword(ANPCanvas*, TextInput);
+ bool handleNavigation(ANPKeyCode keyCode);
void handleTextInput(TextInput* input, ANPKeyCode keyCode, int32_t unichar);
void scrollIntoView(TextInput* input);
+ void switchActiveInput(TextInput* input);
ANPPaint* getPaint(TextInput*);
TextInput* validTap(int x, int y);