Here is my solution, if you believe it is acceptable, as I hope, could you add it to Juce? I have tested it in iOS, but I've never touched Android, so I can only hope it is suitable for that OS.
1. Declare a VirtualKeyboardType enum inside TextInputTarget to provide a list of types as a reasonable intersection between those defined in iOS and those defined in Android.
2. Declare a VirtualKeyboardType member variable and set/get methods inside TextInputTarget.
class JUCE_API TextInputTarget
{
public:
//==============================================================================
enum VirtualKeyboardType
{
// iOS: UIKeyboardTypeDefault, Android: text
virtKbdTypeDefault,
// iOS: UIKeyboardTypeNumbersAndPunctuation, Android: number|numberSigned|numberDecimal
virtKbdTypeNumbers,
// iOS: UIKeyboardTypeURL, Android: textUri
virtKbdTypeURL,
// iOS: UIKeyboardTypePhonePad, Android: phone
virtKbdTypePhonePad,
// iOS: UIKeyboardTypeEmailAddress, Android: textEmailAddress
virtKbdTypeEmailAddress
};
/** */
TextInputTarget()
: virtualKeyboardType(virtKbdTypeDefault)
{}
/** Destructor. */
virtual ~TextInputTarget() {}
/** Returns true if this input target is currently accepting input.
For example, a text editor might return false if it's in read-only mode.
*/
virtual bool isTextInputActive() const = 0;
/** Returns the extents of the selected text region, or an empty range if
nothing is selected,
*/
virtual Range<int> getHighlightedRegion() const = 0;
/** Sets the currently-selected text region. */
virtual void setHighlightedRegion (const Range<int>& newRange) = 0;
/** Sets a number of temporarily underlined sections.
This is needed by MS Windows input method UI.
*/
virtual void setTemporaryUnderlining (const Array <Range<int> >& underlinedRegions) = 0;
/** Returns a specified sub-section of the text. */
virtual String getTextInRange (const Range<int>& range) const = 0;
/** Inserts some text, overwriting the selected text region, if there is one. */
virtual void insertTextAtCaret (const String& textToInsert) = 0;
/** Returns the position of the caret, relative to the component's origin. */
virtual Rectangle<int> getCaretRectangle() = 0;
/** Sets the current virtual keyboard type. */
virtual void setVirtualKeyboardType (VirtualKeyboardType type) { virtualKeyboardType = type; }
/** Gets the current virtual keyboard type. */
virtual VirtualKeyboardType getVirtualKeyboardType () { return virtualKeyboardType; }
private:
VirtualKeyboardType virtualKeyboardType;
};
3. Modify methods derived from ComponentPeer::textInputRequired() as needed, so that they can set the desired type of keyboard in the specific OS.
void UIViewComponentPeer::textInputRequired (const Point<int>&)
{
if (TextInputTarget* const target = findCurrentTextInputTarget())
{
switch(target->getVirtualKeyboardType())
{
case TextInputTarget::virtKbdTypeDefault:
view->hiddenTextView.keyboardType = UIKeyboardTypeDefault;
break;
case TextInputTarget::virtKbdTypeNumbers:
view->hiddenTextView.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
break;
case TextInputTarget::virtKbdTypeURL:
view->hiddenTextView.keyboardType = UIKeyboardTypeURL;
break;
case TextInputTarget::virtKbdTypePhonePad:
view->hiddenTextView.keyboardType = UIKeyboardTypePhonePad;
break;
case TextInputTarget::virtKbdTypeEmailAddress:
view->hiddenTextView.keyboardType = UIKeyboardTypeEmailAddress;
break;
}
}
}