You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
641 lines
26 KiB
641 lines
26 KiB
/****************************************************************************
|
|
Copyright (c) 2018-2022 Xiamen Yaji Software Co., Ltd.
|
|
|
|
http://www.cocos.com
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated engine source code (the "Software"), a limited,
|
|
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
|
to use Cocos Creator solely to develop games on your target platforms. You shall
|
|
not use Cocos Creator software for developing other software or tools that's
|
|
used for developing games. You are not granted to publish, distribute,
|
|
sublicense, and/or sell copies of Cocos Creator.
|
|
|
|
The software or tools in this License Agreement are licensed, not sold.
|
|
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
****************************************************************************/
|
|
|
|
/************************************************************
|
|
TODO: New implementation of iOS inputbox
|
|
UI Structure:
|
|
==[| ][done]== >>> inputAccessoryView
|
|
= q w e r t y u i o p =
|
|
= a s d f g h j k l ; '' =
|
|
= virtual [ ] keyboard = >>> inputView
|
|
|
|
Further needs:
|
|
Customization of inputbox, developer DIY toolbar.
|
|
==[Camera][| ][done]== >>> inputoopeAccessoryView
|
|
= q w e r t y u i o p =
|
|
= a s d f g h j k l ; '' =
|
|
= virtual [ ] keyboard = >>> inputView
|
|
The principle idea is to set inputAccessoryView from JS where developer can bind selector with js callback.
|
|
JS API:
|
|
jsb.InputBox customizeIBox = new jsb.InputBox();
|
|
ibox.addComponent(sendBtn, (ClickEvent: event)=>{...}); automatically set as the last element.
|
|
ibox.addComponent(inputFld, (InputEvent: event)=>{...});
|
|
ibox.setLayout(sendBtn, inputFld);
|
|
JSB binding:
|
|
jsb_addComponent(se::Value){
|
|
...
|
|
inputBox.addComponent(cpt);
|
|
}
|
|
************************************************************/
|
|
|
|
#include "EditBox.h"
|
|
#include "cocos/bindings/jswrapper/SeApi.h"
|
|
#include "cocos/bindings/manual/jsb_global.h"
|
|
#include "engine/EngineEvents.h"
|
|
#import <UIKit/UIKit.h>
|
|
#include "cocos/platform/ios/WarpCocosContent.h"
|
|
|
|
|
|
#define ITEM_MARGIN_WIDTH 10
|
|
#define ITEM_MARGIN_HEIGHT 10
|
|
#define TEXT_LINE_HEIGHT 40
|
|
#define TEXT_VIEW_MAX_LINE_SHOWN 1.5
|
|
#define BUTTON_HEIGHT (TEXT_LINE_HEIGHT - ITEM_MARGIN_HEIGHT)
|
|
#define BUTTON_WIDTH 60
|
|
//TODO: change the proccedure of showing inputbox, possibly become a property
|
|
const bool INPUTBOX_HIDDEN = true; // Toggle if Inputbox is visible
|
|
/*************************************************************************
|
|
Inner class declarations.
|
|
************************************************************************/
|
|
@interface EditboxManager : NSObject
|
|
+ (instancetype)sharedInstance;
|
|
- (void) show:(const cc::EditBox::ShowInfo*)showInfo;
|
|
- (void) hide;
|
|
- (UIView*) getCurrentViewInUse;
|
|
- (NSString*) getCurrentText;
|
|
@end
|
|
|
|
@interface ButtonHandler : NSObject
|
|
- (IBAction) buttonTapped:(UIButton *)button;
|
|
@end
|
|
|
|
@interface TextFieldDelegate : NSObject <UITextFieldDelegate>
|
|
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
|
|
- (void) textFieldDidChange:(UITextField *)textField;
|
|
- (BOOL) textFieldShouldReturn:(UITextField *)textField;
|
|
@end
|
|
|
|
@interface TextViewDelegate : NSObject <UITextViewDelegate> //Multiline
|
|
- (BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
|
|
- (void) textViewDidChange:(UITextView *)textView;
|
|
@end
|
|
|
|
/*************************************************************************
|
|
Global variables and functions relative to script engine.
|
|
************************************************************************/
|
|
namespace {
|
|
static bool g_isMultiline{false};
|
|
static bool g_confirmHold{false};
|
|
static int g_maxLength{INT_MAX};
|
|
se::Value textInputCallback;
|
|
|
|
void getTextInputCallback() {
|
|
if (!textInputCallback.isUndefined())
|
|
return;
|
|
|
|
auto global = se::ScriptEngine::getInstance()->getGlobalObject();
|
|
se::Value jsbVal;
|
|
if (global->getProperty("jsb", &jsbVal) && jsbVal.isObject()) {
|
|
jsbVal.toObject()->getProperty("onTextInput", &textInputCallback);
|
|
// free globle se::Value before ScriptEngine clean up
|
|
se::ScriptEngine::getInstance()->addBeforeCleanupHook([]() {
|
|
textInputCallback.setUndefined();
|
|
});
|
|
}
|
|
}
|
|
|
|
void callJSFunc(const ccstd::string &type, const ccstd::string &text) {
|
|
getTextInputCallback();
|
|
|
|
se::AutoHandleScope scope;
|
|
se::ValueArray args;
|
|
args.push_back(se::Value(type));
|
|
args.push_back(se::Value(text));
|
|
textInputCallback.toObject()->call(args, nullptr);
|
|
}
|
|
|
|
/*************************************************************************
|
|
Global functions as tools to set values
|
|
************************************************************************/
|
|
|
|
int getTextInputHeight(bool isMultiLine) {
|
|
if (isMultiLine)
|
|
return TEXT_LINE_HEIGHT * TEXT_VIEW_MAX_LINE_SHOWN;
|
|
else
|
|
return TEXT_LINE_HEIGHT;
|
|
}
|
|
|
|
void setTextFieldKeyboardType(UITextField *textField, const ccstd::string &inputType) {
|
|
if (0 == inputType.compare("password")) {
|
|
textField.secureTextEntry = TRUE;
|
|
textField.keyboardType = UIKeyboardTypeDefault;
|
|
} else {
|
|
textField.secureTextEntry = FALSE;
|
|
if (0 == inputType.compare("email"))
|
|
textField.keyboardType = UIKeyboardTypeEmailAddress;
|
|
else if (0 == inputType.compare("number"))
|
|
textField.keyboardType = UIKeyboardTypeDecimalPad;
|
|
else if (0 == inputType.compare("url"))
|
|
textField.keyboardType = UIKeyboardTypeURL;
|
|
else if (0 == inputType.compare("text"))
|
|
textField.keyboardType = UIKeyboardTypeDefault;
|
|
}
|
|
}
|
|
|
|
void setTextFieldReturnType(UITextField *textField, const ccstd::string &returnType) {
|
|
if (0 == returnType.compare("done"))
|
|
textField.returnKeyType = UIReturnKeyDone;
|
|
else if (0 == returnType.compare("next"))
|
|
textField.returnKeyType = UIReturnKeyNext;
|
|
else if (0 == returnType.compare("search"))
|
|
textField.returnKeyType = UIReturnKeySearch;
|
|
else if (0 == returnType.compare("go"))
|
|
textField.returnKeyType = UIReturnKeyGo;
|
|
else if (0 == returnType.compare("send"))
|
|
textField.returnKeyType = UIReturnKeySend;
|
|
}
|
|
|
|
NSString *getConfirmButtonTitle(const ccstd::string &returnType) {
|
|
NSString *titleKey = [NSString stringWithUTF8String:returnType.c_str()];
|
|
return NSLocalizedString(titleKey, nil); // get i18n string to be the title
|
|
}
|
|
//
|
|
CGRect getSafeAreaRect() {
|
|
//UIView *view = UIApplication.sharedApplication.delegate.window.rootViewController.view;
|
|
UIView *view = WarpCocosContent.shareInstance.renderView;
|
|
|
|
CGRect viewRect = view.frame;
|
|
|
|
// safeAreaInsets is avaible since iOS 11.
|
|
if (@available(iOS 11.0, *)) {
|
|
auto safeAreaInsets = view.safeAreaInsets;
|
|
|
|
UIInterfaceOrientation orient = [UIApplication sharedApplication].statusBarOrientation;
|
|
if (UIInterfaceOrientationLandscapeLeft == orient) {
|
|
viewRect.origin.x = 0;
|
|
viewRect.size.width -= safeAreaInsets.left;
|
|
viewRect.size.width -= safeAreaInsets.right;
|
|
} else {
|
|
viewRect.origin.x += safeAreaInsets.left;
|
|
viewRect.size.width -= safeAreaInsets.left;
|
|
viewRect.size.width -= safeAreaInsets.right;
|
|
}
|
|
}
|
|
|
|
return viewRect;
|
|
}
|
|
|
|
//TODO: Get hash with different type of showInfo, for example different inputAccessoryView
|
|
NSString* getTextInputType(const cc::EditBox::ShowInfo* showInfo) {
|
|
return showInfo->isMultiline?@"textView":@"textField";
|
|
}
|
|
void onParentViewTouched(const cc::CustomEvent &touchEvent){
|
|
[[EditboxManager sharedInstance] hide];
|
|
}
|
|
} // namespace
|
|
|
|
/*************************************************************************
|
|
Class implementations.
|
|
************************************************************************/
|
|
@implementation TextViewDelegate {
|
|
UITextView* tViewOnView;
|
|
UITextView* tViewOnToolbar;
|
|
}
|
|
- (id) initWithPairs:(UITextView*) inputOnView and:(UITextView*) inputOnToolbar {
|
|
if (self = [super init]) {
|
|
tViewOnView = inputOnView;
|
|
tViewOnToolbar = inputOnToolbar;
|
|
}
|
|
return self;
|
|
}
|
|
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
|
|
// REFINE: check length limit before text changed
|
|
return YES;
|
|
}
|
|
- (void)textViewDidChange:(UITextView *)textView {
|
|
if (textView.markedTextRange != nil)
|
|
return;
|
|
|
|
// check length limit after text changed, a little rude
|
|
if (textView.text.length > g_maxLength) {
|
|
NSRange rangeIndex = [textView.text rangeOfComposedCharacterSequenceAtIndex:g_maxLength];
|
|
textView.text = [textView.text substringToIndex:rangeIndex.location];
|
|
}
|
|
tViewOnView.text = textView.text;
|
|
tViewOnToolbar.text = textView.text;
|
|
callJSFunc("input", [textView.text UTF8String]);
|
|
}
|
|
@end
|
|
@implementation TextFieldDelegate {
|
|
UITextField* textFieldOnView;
|
|
UITextField* textFieldOntoolbar;
|
|
}
|
|
|
|
- (id) initWithPairs:(UITextField*) inputOnView and:(UITextField*) inputOnToolbar {
|
|
if (self = [super init]) {
|
|
textFieldOnView = inputOnView;
|
|
textFieldOntoolbar = inputOnToolbar;
|
|
|
|
}
|
|
return self;
|
|
}
|
|
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
|
|
// REFINE: check length limit before text changed
|
|
return YES;
|
|
}
|
|
|
|
- (void)textFieldDidChange:(UITextField *)textField {
|
|
if (textField.markedTextRange != nil)
|
|
return;
|
|
|
|
// check length limit after text changed, a little rude
|
|
if (textField.text.length > g_maxLength) {
|
|
NSRange rangeIndex = [textField.text rangeOfComposedCharacterSequenceAtIndex:g_maxLength];
|
|
textField.text = [textField.text substringToIndex:rangeIndex.location];
|
|
}
|
|
textFieldOnView.text = textField.text;
|
|
textFieldOntoolbar.text = textField.text;
|
|
callJSFunc("input", [textField.text UTF8String]);
|
|
}
|
|
|
|
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
|
|
cc::EditBox::complete();
|
|
return YES;
|
|
}
|
|
@end
|
|
|
|
|
|
static ButtonHandler* btnHandler = nil;
|
|
@interface InputBoxPair : NSObject
|
|
@property(readwrite) id inputOnView;
|
|
@property(readwrite) id inputOnToolbar;
|
|
@property(readwrite) id inputDelegate;
|
|
@end
|
|
@implementation InputBoxPair
|
|
- (void)dealloc {
|
|
[super dealloc];
|
|
[_inputOnView release];
|
|
[_inputOnToolbar release];
|
|
[_inputDelegate release];
|
|
}
|
|
@end
|
|
|
|
@implementation EditboxManager
|
|
{
|
|
//recently there'ill be only 2 elements
|
|
NSMutableDictionary<NSString*, InputBoxPair*>* textInputDictionnary;
|
|
InputBoxPair* curView;
|
|
|
|
cc::events::Resize::Listener resizeListener;
|
|
cc::events::Touch::Listener touchListener;
|
|
cc::events::Close::Listener closeListener;
|
|
}
|
|
static EditboxManager *instance = nil;
|
|
|
|
+ (instancetype) sharedInstance {
|
|
static dispatch_once_t pred = 0;
|
|
dispatch_once(&pred, ^{
|
|
instance = [[super allocWithZone:NULL] init];
|
|
if (instance == nil) {
|
|
CC_LOG_ERROR("Editbox manager init failed, plz check if you have enough space left");
|
|
}
|
|
});
|
|
return instance;
|
|
}
|
|
+ (id)allocWithZone:(struct _NSZone*)zone {
|
|
return [EditboxManager sharedInstance];
|
|
}
|
|
|
|
- (id)copyWithZone:(struct _NSZone*)zone {
|
|
return [EditboxManager sharedInstance];
|
|
}
|
|
|
|
- (void)onOrientationChanged{
|
|
cc::EditBox::complete();
|
|
}
|
|
- (id)init {
|
|
if (self = [super init]) {
|
|
|
|
textInputDictionnary = [NSMutableDictionary new];
|
|
if (textInputDictionnary == nil) {
|
|
[self release];
|
|
return nil;
|
|
}
|
|
|
|
resizeListener.bind([&](int /*width*/, int /*height*/ , uint32_t /*windowId*/) {
|
|
[[EditboxManager sharedInstance] onOrientationChanged];
|
|
});
|
|
//"onTouchStart" is a sub event for TouchEvent, so we can only add listener for this sub event rather than TouchEvent itself.
|
|
touchListener.bind([&](const cc::TouchEvent& event) {
|
|
if(event.type == cc::TouchEvent::Type::BEGAN) {
|
|
cc::EditBox::complete();
|
|
}
|
|
});
|
|
|
|
closeListener.bind([&]() {
|
|
[[EditboxManager sharedInstance] dealloc];
|
|
});
|
|
}
|
|
return self;
|
|
}
|
|
- (void)dealloc {
|
|
[textInputDictionnary release];
|
|
[super dealloc];
|
|
}
|
|
- (UIBarButtonItem*) setInputWidthOf: (UIToolbar*)toolbar{
|
|
CGFloat totalItemsWidth = ITEM_MARGIN_WIDTH;
|
|
UIBarButtonItem *textViewBarButtonItem;
|
|
UIView *view;
|
|
for (UIBarButtonItem *barButtonItem in toolbar.items) {
|
|
if ((view = [barButtonItem valueForKey:@"view"])) {
|
|
if ([view isKindOfClass:[UITextView class]] || [view isKindOfClass:[UITextField class]]) {
|
|
textViewBarButtonItem = barButtonItem;
|
|
} else if ([view isKindOfClass:[UIButton class]]) {
|
|
// Docs say width can be negative for variable size items
|
|
totalItemsWidth += BUTTON_WIDTH + ITEM_MARGIN_WIDTH;
|
|
}
|
|
} else {
|
|
totalItemsWidth += barButtonItem.width + ITEM_MARGIN_WIDTH;
|
|
}
|
|
totalItemsWidth += ITEM_MARGIN_WIDTH;
|
|
}
|
|
[[textViewBarButtonItem customView]
|
|
setFrame:CGRectMake(0,
|
|
0,
|
|
getSafeAreaRect().size.width - totalItemsWidth,
|
|
getTextInputHeight(g_isMultiline))];
|
|
return textViewBarButtonItem;
|
|
}
|
|
- (void) addInputAccessoryViewForTextView: (InputBoxPair*)inputbox
|
|
with:(const cc::EditBox::ShowInfo*)showInfo{
|
|
CGRect safeView = getSafeAreaRect();
|
|
UIToolbar* toolbar = [[UIToolbar alloc]
|
|
initWithFrame:CGRectMake(0,
|
|
0,
|
|
safeView.size.width,
|
|
getTextInputHeight(g_isMultiline) + ITEM_MARGIN_HEIGHT)];
|
|
[toolbar setBackgroundColor:[UIColor darkGrayColor]];
|
|
|
|
UITextView* textView = [[UITextView alloc] init];
|
|
textView.textColor = [UIColor blackColor];
|
|
textView.backgroundColor = [UIColor whiteColor];
|
|
textView.layer.cornerRadius = 5.0;
|
|
textView.clipsToBounds = YES;
|
|
textView.text = [NSString stringWithUTF8String:showInfo->defaultValue.c_str()];
|
|
TextViewDelegate* delegate = [[TextViewDelegate alloc] initWithPairs:[inputbox inputOnView] and:textView];
|
|
inputbox.inputDelegate = delegate;
|
|
textView.delegate = delegate;
|
|
UIBarButtonItem *textViewItem = [[UIBarButtonItem alloc] initWithCustomView:textView];
|
|
|
|
if (!btnHandler){
|
|
btnHandler = [[ButtonHandler alloc] init];
|
|
}
|
|
UIButton *confirmBtn = [[UIButton alloc]
|
|
initWithFrame:CGRectMake(0,
|
|
0,
|
|
BUTTON_WIDTH,
|
|
BUTTON_HEIGHT)];
|
|
[confirmBtn addTarget:btnHandler
|
|
action:@selector(buttonTapped:)
|
|
forControlEvents:UIControlEventTouchUpInside];
|
|
[confirmBtn setTitle:[NSString stringWithUTF8String:showInfo->confirmType.c_str()]
|
|
forState:UIControlStateNormal];
|
|
[confirmBtn setTitleColor:[UIColor systemBlueColor]
|
|
forState:UIControlStateNormal];
|
|
[confirmBtn setTitleColor:[UIColor darkTextColor]
|
|
forState:UIControlStateHighlighted]; // Hight light state triggered when the button is tapped.
|
|
UIBarButtonItem *confirm = [[UIBarButtonItem alloc]initWithCustomView:confirmBtn];
|
|
|
|
[toolbar setItems:@[textViewItem, confirm] animated:YES];
|
|
UIBarButtonItem* textViewBarButtonItem = [self setInputWidthOf:toolbar];
|
|
((UITextView*)[inputbox inputOnView]).inputAccessoryView = toolbar;
|
|
|
|
[inputbox setInputOnToolbar:textViewBarButtonItem.customView];
|
|
//release for NON ARC ENV
|
|
[toolbar release];
|
|
[textView release];
|
|
[confirmBtn release];
|
|
[textViewItem release];
|
|
[confirm release];
|
|
|
|
}
|
|
- (void) addInputAccessoryViewForTextField: (InputBoxPair*)inputbox
|
|
with: (const cc::EditBox::ShowInfo*)showInfo{
|
|
CGRect safeView = getSafeAreaRect();
|
|
UIToolbar* toolbar = [[UIToolbar alloc]
|
|
initWithFrame:CGRectMake(0,
|
|
0,
|
|
safeView.size.width,
|
|
TEXT_LINE_HEIGHT + ITEM_MARGIN_HEIGHT)];
|
|
[toolbar setBackgroundColor:[UIColor darkGrayColor]];
|
|
|
|
UITextField* textField = [[UITextField alloc] init];
|
|
textField.borderStyle = UITextBorderStyleRoundedRect;
|
|
textField.textColor = [UIColor blackColor];
|
|
textField.backgroundColor = [UIColor whiteColor];
|
|
textField.text = [NSString stringWithUTF8String:showInfo->defaultValue.c_str()];
|
|
TextFieldDelegate* delegate = [[TextFieldDelegate alloc] initWithPairs:[inputbox inputOnView] and:textField];
|
|
textField.delegate = delegate;
|
|
inputbox.inputDelegate = delegate;
|
|
[textField addTarget:delegate action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
|
|
UIBarButtonItem *textFieldItem = [[UIBarButtonItem alloc] initWithCustomView:textField];
|
|
|
|
if (!btnHandler){
|
|
btnHandler = [[ButtonHandler alloc] init];
|
|
}
|
|
UIButton *confirmBtn = [[UIButton alloc]
|
|
initWithFrame:CGRectMake(0,
|
|
0,
|
|
BUTTON_WIDTH,
|
|
BUTTON_HEIGHT)];
|
|
[confirmBtn addTarget:btnHandler
|
|
action:@selector(buttonTapped:)
|
|
forControlEvents:UIControlEventTouchUpInside];
|
|
[confirmBtn setTitle:[NSString stringWithUTF8String:showInfo->confirmType.c_str()]
|
|
forState:UIControlStateNormal];
|
|
[confirmBtn setTitleColor:[UIColor systemBlueColor]
|
|
forState:UIControlStateNormal];
|
|
[confirmBtn setTitleColor:[UIColor darkTextColor]
|
|
forState:UIControlStateHighlighted]; // Hight light state triggered when the button is tapped.
|
|
UIBarButtonItem *confirm = [[UIBarButtonItem alloc]initWithCustomView:confirmBtn];
|
|
|
|
[toolbar setItems:@[textFieldItem, confirm] animated:YES];
|
|
|
|
|
|
UIBarButtonItem* textFieldBarButtonItem = [self setInputWidthOf:toolbar];
|
|
((UITextField*)[inputbox inputOnView]).inputAccessoryView = toolbar;
|
|
[inputbox setInputOnToolbar:textFieldBarButtonItem.customView];
|
|
|
|
//release for NON ARC ENV
|
|
[toolbar release];
|
|
[textField release];
|
|
[confirmBtn release];
|
|
[textFieldItem release];
|
|
[confirm release];
|
|
}
|
|
|
|
- (id) createTextView: (const cc::EditBox::ShowInfo *)showInfo {
|
|
InputBoxPair* ret;
|
|
// Visible view rect size of phone
|
|
//CGRect viewRect = UIApplication.sharedApplication.delegate.window.rootViewController.view.frame;
|
|
CGRect viewRect = WarpCocosContent.shareInstance.renderView.frame;
|
|
|
|
//TODO: object for key with real hash value
|
|
NSString* inputType = getTextInputType(showInfo);
|
|
|
|
if ((ret = [textInputDictionnary objectForKey:inputType])) {
|
|
[[ret inputOnView] setFrame:CGRectMake(showInfo->x,
|
|
viewRect.size.height - showInfo->y - showInfo->height,
|
|
showInfo->width,
|
|
showInfo->height)];
|
|
CGRect safeArea = getSafeAreaRect();
|
|
[[[ret inputOnView] inputAccessoryView] setFrame:CGRectMake(0,
|
|
0,
|
|
safeArea.size.width,
|
|
getTextInputHeight(g_isMultiline) + ITEM_MARGIN_HEIGHT)];
|
|
[self setInputWidthOf:[[ret inputOnView] inputAccessoryView] ];
|
|
} else {
|
|
ret = [[InputBoxPair alloc] init];
|
|
[ret setInputOnView:[[UITextView alloc]
|
|
initWithFrame:CGRectMake(showInfo->x,
|
|
viewRect.size.height - showInfo->y - showInfo->height,
|
|
showInfo->width,
|
|
showInfo->height)]];
|
|
[textInputDictionnary setValue:ret forKey:inputType];
|
|
[self addInputAccessoryViewForTextView:ret with:showInfo];
|
|
}
|
|
((UITextView*)[ret inputOnToolbar]).text = [NSString stringWithUTF8String:showInfo->defaultValue.c_str()];
|
|
((UITextView*)[ret inputOnView]).text = [NSString stringWithUTF8String:showInfo->defaultValue.c_str()];
|
|
return ret;
|
|
}
|
|
- (id) createTextField: (const cc::EditBox::ShowInfo*)showInfo {
|
|
InputBoxPair* ret;
|
|
CGRect viewRect = UIApplication.sharedApplication.delegate.window.rootViewController.view.frame;
|
|
|
|
//TODO: object for key with real hash value
|
|
NSString* inputType = getTextInputType(showInfo);
|
|
|
|
if ((ret = [textInputDictionnary objectForKey:inputType])) {
|
|
[[ret inputOnView] setFrame:CGRectMake(showInfo->x,
|
|
viewRect.size.height - showInfo->y - showInfo->height,
|
|
showInfo->width,
|
|
showInfo->height)];
|
|
CGRect safeArea = getSafeAreaRect();
|
|
[[[ret inputOnView] inputAccessoryView] setFrame:CGRectMake(0,
|
|
0,
|
|
safeArea.size.width,
|
|
getTextInputHeight(g_isMultiline) + ITEM_MARGIN_HEIGHT)];
|
|
[self setInputWidthOf:[[ret inputOnView] inputAccessoryView] ];
|
|
} else {
|
|
ret = [[InputBoxPair alloc] init];
|
|
[ret setInputOnView:[[UITextField alloc]
|
|
initWithFrame:CGRectMake(showInfo->x,
|
|
viewRect.size.height - showInfo->y - showInfo->height,
|
|
showInfo->width,
|
|
showInfo->height)]];
|
|
[textInputDictionnary setValue:ret forKey:inputType];
|
|
[self addInputAccessoryViewForTextField:ret with:showInfo];
|
|
}
|
|
((UITextField*)[ret inputOnToolbar]).text = [NSString stringWithUTF8String:showInfo->defaultValue.c_str()];
|
|
((UITextField*)[ret inputOnView]).text = [NSString stringWithUTF8String:showInfo->defaultValue.c_str()];
|
|
setTextFieldReturnType((UITextField*)[ret inputOnToolbar], showInfo->confirmType);
|
|
setTextFieldReturnType((UITextField*)[ret inputOnView], showInfo->confirmType);
|
|
setTextFieldKeyboardType((UITextField*)[ret inputOnToolbar], showInfo->inputType);
|
|
setTextFieldKeyboardType((UITextField*)[ret inputOnView], showInfo->inputType);
|
|
return ret;
|
|
}
|
|
|
|
//TODO: show inputbox with width modified.
|
|
- (void) show: (const cc::EditBox::ShowInfo*)showInfo {
|
|
g_maxLength = showInfo->maxLength;
|
|
g_isMultiline = showInfo->isMultiline;
|
|
g_confirmHold = showInfo->confirmHold;
|
|
|
|
if (g_isMultiline) {
|
|
curView = [self createTextView:showInfo];
|
|
} else {
|
|
curView = [self createTextField:showInfo];
|
|
}
|
|
[[curView inputOnView] setHidden:INPUTBOX_HIDDEN];
|
|
//UIView *view = UIApplication.sharedApplication.delegate.window.rootViewController.view;
|
|
UIView *view = WarpCocosContent.shareInstance.renderView;
|
|
|
|
[view addSubview:[curView inputOnView]];
|
|
[[curView inputOnView] becomeFirstResponder];
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
if(![[curView inputOnToolbar] becomeFirstResponder]) {
|
|
CC_LOG_ERROR("inputOnToolbar becomeFirstResponder error!");
|
|
}
|
|
});
|
|
|
|
}
|
|
// Change the focus point to the TextField or TextView on the toolbar.
|
|
- (void) hide {
|
|
if ([[curView inputOnToolbar] isFirstResponder]) {
|
|
[[curView inputOnToolbar] resignFirstResponder];
|
|
}
|
|
if ([[curView inputOnView] isFirstResponder]) {
|
|
[[curView inputOnView] resignFirstResponder];
|
|
}
|
|
[[curView inputOnView] removeFromSuperview];
|
|
}
|
|
|
|
- (InputBoxPair*) getCurrentViewInUse {
|
|
return curView;
|
|
}
|
|
- (NSString*) getCurrentText {
|
|
if (g_isMultiline)
|
|
return [(UITextView*)[curView inputOnToolbar] text];
|
|
return [(UITextField*)[curView inputOnToolbar] text];
|
|
}
|
|
|
|
|
|
@end
|
|
@implementation ButtonHandler
|
|
- (IBAction)buttonTapped:(UIButton *)button {
|
|
const ccstd::string text([[[EditboxManager sharedInstance]getCurrentText] UTF8String]);
|
|
callJSFunc("confirm", text);
|
|
if (!g_confirmHold)
|
|
cc::EditBox::complete();
|
|
}
|
|
@end
|
|
/*************************************************************************
|
|
Implementation of EditBox.
|
|
************************************************************************/
|
|
|
|
// MARK: EditBox
|
|
|
|
namespace cc{
|
|
bool EditBox::_isShown = false;
|
|
void EditBox::show(const cc::EditBox::ShowInfo &showInfo) {
|
|
[[EditboxManager sharedInstance] show:&showInfo];
|
|
EditBox::_isShown = true;
|
|
}
|
|
|
|
void EditBox::hide() {
|
|
[[EditboxManager sharedInstance] hide];
|
|
EditBox::_isShown = false;
|
|
}
|
|
|
|
bool EditBox::complete() {
|
|
if(!EditBox::_isShown)
|
|
return false;
|
|
NSString *text = [[EditboxManager sharedInstance] getCurrentText];
|
|
callJSFunc("complete", [text UTF8String]);
|
|
EditBox::hide();
|
|
|
|
return true;
|
|
}
|
|
} // namespace cc
|
|
|