diff --git a/extras/Demo/Builds/Android/src/com/juce/jucedemo/JuceDemo.java b/extras/Demo/Builds/Android/src/com/juce/jucedemo/JuceDemo.java index 13ba3d0d72..c470402eee 100644 --- a/extras/Demo/Builds/Android/src/com/juce/jucedemo/JuceDemo.java +++ b/extras/Demo/Builds/Android/src/com/juce/jucedemo/JuceDemo.java @@ -399,16 +399,21 @@ public final class JuceDemo extends Activity private native void handleKeyDown (long host, int keycode, int textchar); private native void handleKeyUp (long host, int keycode, int textchar); - public void showKeyboard (boolean shouldShow) + public void showKeyboard (String type) { InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE); if (imm != null) { - if (shouldShow) - imm.showSoftInput (this, InputMethodManager.SHOW_FORCED); + if (! type.isEmpty()) + { + imm.showSoftInput (this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT); + imm.setInputMethod (getWindowToken(), type); + } else + { imm.hideSoftInputFromWindow (getWindowToken(), 0); + } } } diff --git a/modules/juce_core/native/java/JuceAppActivity.java b/modules/juce_core/native/java/JuceAppActivity.java index 418b032a48..b9077cc52e 100644 --- a/modules/juce_core/native/java/JuceAppActivity.java +++ b/modules/juce_core/native/java/JuceAppActivity.java @@ -399,16 +399,21 @@ public final class JuceAppActivity extends Activity private native void handleKeyDown (long host, int keycode, int textchar); private native void handleKeyUp (long host, int keycode, int textchar); - public void showKeyboard (boolean shouldShow) + public void showKeyboard (String type) { InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE); if (imm != null) { - if (shouldShow) - imm.showSoftInput (this, InputMethodManager.SHOW_FORCED); + if (! type.isEmpty()) + { + imm.showSoftInput (this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT); + imm.setInputMethod (getWindowToken(), type); + } else + { imm.hideSoftInputFromWindow (getWindowToken(), 0); + } } } diff --git a/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h b/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h index eaf4bb0421..9770f5dc36 100644 --- a/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h +++ b/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h @@ -71,6 +71,23 @@ public: /** Returns the position of the caret, relative to the component's origin. */ virtual Rectangle getCaretRectangle() = 0; + + /** A set of possible on-screen keyboard types, for use in the + getKeyboardType() method. + */ + enum VirtualKeyboardType + { + textKeyboard = 0, + numericKeyboard, + urlKeyboard, + emailAddressKeyboard, + phoneNumberKeyboard + }; + + /** Returns the target's preference for the type of keyboard that would be most appropriate. + This may be ignored, depending on the capabilities of the OS. + */ + virtual VirtualKeyboardType getKeyboardType() { return textKeyboard; } }; diff --git a/modules/juce_gui_basics/native/juce_android_Windowing.cpp b/modules/juce_gui_basics/native/juce_android_Windowing.cpp index 86864fc7ad..02353be730 100644 --- a/modules/juce_gui_basics/native/juce_android_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_android_Windowing.cpp @@ -91,7 +91,7 @@ DECLARE_JNI_CLASS (CanvasMinimal, "android/graphics/Canvas"); METHOD (hasFocus, "hasFocus", "()Z") \ METHOD (invalidate, "invalidate", "(IIII)V") \ METHOD (containsPoint, "containsPoint", "(II)Z") \ - METHOD (showKeyboard, "showKeyboard", "(Z)V") \ + METHOD (showKeyboard, "showKeyboard", "(Ljava/lang/String;)V") \ METHOD (createGLView, "createGLView", "()L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$OpenGLView;") \ DECLARE_JNI_CLASS (ComponentPeerView, JUCE_ANDROID_ACTIVITY_CLASSPATH "$ComponentPeerView"); @@ -378,14 +378,30 @@ public: handleFocusLoss(); } - void textInputRequired (const Point&) override + static const char* getVirtualKeyboardType (TextInputTarget::VirtualKeyboardType type) noexcept { - view.callVoidMethod (ComponentPeerView.showKeyboard, true); + switch (type) + { + case TextInputTarget::textKeyboard: return "text"; + case TextInputTarget::numericKeyboard: return "number"; + case TextInputTarget::urlKeyboard: return "textUri"; + case TextInputTarget::emailAddressKeyboard: return "textEmailAddress"; + case TextInputTarget::phoneNumberKeyboard: return "phone"; + default: jassertfalse; break; + } + + return "text"; + } + + void textInputRequired (Point, TextInputTarget& target) override + { + view.callVoidMethod (ComponentPeerView.showKeyboard, + javaString (getVirtualKeyboardType (target.getKeyboardType())).get()); } void dismissPendingTextInput() override { - view.callVoidMethod (ComponentPeerView.showKeyboard, false); + view.callVoidMethod (ComponentPeerView.showKeyboard, javaString ("").get()); } //============================================================================== diff --git a/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm index 5f1975999f..791958645a 100644 --- a/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm @@ -168,7 +168,7 @@ public: void viewFocusLoss(); bool isFocused() const override; void grabFocus() override; - void textInputRequired (const Point&) override; + void textInputRequired (Point, TextInputTarget&) override; BOOL textViewReplaceCharacters (Range, const String&); void updateHiddenTextContent (TextInputTarget*); @@ -702,10 +702,7 @@ void UIViewComponentPeer::toFront (bool makeActiveWindow) void UIViewComponentPeer::toBehind (ComponentPeer* other) { - UIViewComponentPeer* const otherPeer = dynamic_cast (other); - jassert (otherPeer != nullptr); // wrong type of window? - - if (otherPeer != nullptr) + if (UIViewComponentPeer* const otherPeer = dynamic_cast (other)) { if (isSharedWindow) { @@ -716,6 +713,10 @@ void UIViewComponentPeer::toBehind (ComponentPeer* other) // don't know how to do this } } + else + { + jassertfalse; // wrong type of window? + } } void UIViewComponentPeer::setIcon (const Image& /*newIcon*/) @@ -828,12 +829,28 @@ void UIViewComponentPeer::grabFocus() } } -void UIViewComponentPeer::textInputRequired (const Point&) +void UIViewComponentPeer::textInputRequired (Point, TextInputTarget&) +{ +} + +static UIKeyboardType getUIKeyboardType (TextInputTarget::VirtualKeyboardType type) noexcept { + switch (type) + { + case TextInputTarget::textKeyboard: return UIKeyboardTypeAlphabet; + case TextInputTarget::numericKeyboard: return UIKeyboardTypeNumbersAndPunctuation; + case TextInputTarget::urlKeyboard: return UIKeyboardTypeURL; + case TextInputTarget::emailAddressKeyboard: return UIKeyboardTypeEmailAddress; + case TextInputTarget::phoneNumberKeyboard: return UIKeyboardTypePhonePad; + default: jassertfalse; break; + } + + return UIKeyboardTypeDefault; } void UIViewComponentPeer::updateHiddenTextContent (TextInputTarget* target) { + view->hiddenTextView.keyboardType = getUIKeyboardType (target->getKeyboardType()); view->hiddenTextView.text = juceStringToNS (target->getTextInRange (Range (0, target->getHighlightedRegion().getStart()))); view->hiddenTextView.selectedRange = NSMakeRange (target->getHighlightedRegion().getStart(), 0); } diff --git a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp index 8ce9856135..91746d2b18 100644 --- a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp @@ -1217,7 +1217,7 @@ public: } } - void textInputRequired (const Point&) override {} + void textInputRequired (Point, TextInputTarget&) override {} void repaint (const Rectangle& area) override { diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index de062b2d44..2d030d71df 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -1151,7 +1151,7 @@ public: } } - void textInputRequired (const Point&) override {} + void textInputRequired (Point, TextInputTarget&) override {} //============================================================================== void repaint (const Rectangle& area) override diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index dcf9473a4c..f9568865ec 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -877,7 +877,7 @@ public: shouldDeactivateTitleBar = oldDeactivate; } - void textInputRequired (const Point&) override + void textInputRequired (Point, TextInputTarget&) override { if (! hasCreatedCaret) { diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp index abbc102056..4cfbb52356 100644 --- a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp +++ b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp @@ -2059,7 +2059,7 @@ void TextEditor::focusGained (FocusChangeType) if (ComponentPeer* const peer = getPeer()) if (! isReadOnly()) - peer->textInputRequired (peer->globalToLocal (getScreenPosition())); + peer->textInputRequired (peer->globalToLocal (getScreenPosition()), *this); } void TextEditor::focusLost (FocusChangeType) diff --git a/modules/juce_gui_basics/windows/juce_ComponentPeer.h b/modules/juce_gui_basics/windows/juce_ComponentPeer.h index 9cdc8075ba..4ffb7b0da7 100644 --- a/modules/juce_gui_basics/windows/juce_ComponentPeer.h +++ b/modules/juce_gui_basics/windows/juce_ComponentPeer.h @@ -276,7 +276,7 @@ public: This may cause things like a virtual on-screen keyboard to appear, depending on the OS. */ - virtual void textInputRequired (const Point& position) = 0; + virtual void textInputRequired (Point position, TextInputTarget&) = 0; /** If there's some kind of OS input-method in progress, this should dismiss it. */ virtual void dismissPendingTextInput();