mirror of https://github.com/axmolengine/axmol.git
Merge branch 'master' of https://github.com/neokim/cocos2d-x into ios-editbox
This commit is contained in:
commit
cf999be928
|
@ -48,7 +48,7 @@ CCEditBox::~CCEditBox(void)
|
|||
|
||||
|
||||
void CCEditBox::touchDownAction(CCObject *sender, CCControlEvent controlEvent)
|
||||
{
|
||||
{
|
||||
m_pEditBoxImpl->openKeyboard();
|
||||
}
|
||||
|
||||
|
@ -118,10 +118,12 @@ const char* CCEditBox::getText(void)
|
|||
{
|
||||
if (m_pEditBoxImpl != NULL)
|
||||
{
|
||||
return m_pEditBoxImpl->getText();
|
||||
const char* pText = m_pEditBoxImpl->getText();
|
||||
if(pText != NULL)
|
||||
return pText;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return "";
|
||||
}
|
||||
|
||||
void CCEditBox::setFont(const char* pFontName, int fontSize)
|
||||
|
@ -268,6 +270,15 @@ void CCEditBox::visit(void)
|
|||
}
|
||||
}
|
||||
|
||||
void CCEditBox::onEnter(void)
|
||||
{
|
||||
CCControlButton::onEnter();
|
||||
if (m_pEditBoxImpl != NULL)
|
||||
{
|
||||
m_pEditBoxImpl->onEnter();
|
||||
}
|
||||
}
|
||||
|
||||
void CCEditBox::onExit(void)
|
||||
{
|
||||
CCControlButton::onExit();
|
||||
|
@ -280,7 +291,9 @@ void CCEditBox::onExit(void)
|
|||
|
||||
static CCRect getRect(CCNode * pNode)
|
||||
{
|
||||
return pNode->boundingBox();
|
||||
CCSize contentSize = pNode->getContentSize();
|
||||
CCRect rect = CCRectMake(0, 0, contentSize.width, contentSize.height);
|
||||
return CCRectApplyAffineTransform(rect, pNode->nodeToWorldTransform());
|
||||
}
|
||||
|
||||
void CCEditBox::keyboardWillShow(CCIMEKeyboardNotificationInfo& info)
|
||||
|
@ -312,7 +325,7 @@ void CCEditBox::keyboardWillShow(CCIMEKeyboardNotificationInfo& info)
|
|||
|
||||
void CCEditBox::keyboardDidShow(CCIMEKeyboardNotificationInfo& info)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CCEditBox::keyboardWillHide(CCIMEKeyboardNotificationInfo& info)
|
||||
|
@ -326,7 +339,7 @@ void CCEditBox::keyboardWillHide(CCIMEKeyboardNotificationInfo& info)
|
|||
|
||||
void CCEditBox::keyboardDidHide(CCIMEKeyboardNotificationInfo& info)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -290,6 +290,7 @@ public:
|
|||
virtual void setContentSize(const CCSize& size);
|
||||
virtual void setAnchorPoint(const CCPoint& anchorPoint);
|
||||
virtual void visit(void);
|
||||
virtual void onEnter(void);
|
||||
virtual void onExit(void);
|
||||
virtual void keyboardWillShow(CCIMEKeyboardNotificationInfo& info);
|
||||
virtual void keyboardDidShow(CCIMEKeyboardNotificationInfo& info);
|
||||
|
|
|
@ -64,6 +64,7 @@ public:
|
|||
virtual void setContentSize(const CCSize& size) = 0;
|
||||
virtual void setAnchorPoint(const CCPoint& anchorPoint) = 0;
|
||||
virtual void visit(void) = 0;
|
||||
virtual void onEnter(void) = 0;
|
||||
|
||||
|
||||
void setDelegate(CCEditBoxDelegate* pDelegate) { m_pDelegate = pDelegate; };
|
||||
|
|
|
@ -55,28 +55,30 @@ CCEditBoxImplAndroid::CCEditBoxImplAndroid(CCEditBox* pEditText)
|
|||
|
||||
CCEditBoxImplAndroid::~CCEditBoxImplAndroid()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CCEditBoxImplAndroid::doAnimationWhenKeyboardMove(float duration, float distance)
|
||||
{ // don't need to be implemented on android platform.
|
||||
|
||||
|
||||
}
|
||||
|
||||
static const int CC_EDIT_BOX_PADDING = 5;
|
||||
|
||||
bool CCEditBoxImplAndroid::initWithSize(const CCSize& size)
|
||||
{
|
||||
int fontSize = getFontSizeAccordingHeightJni(size.height-12);
|
||||
m_pLabel = CCLabelTTF::create("", "", size.height-12);
|
||||
// align the text vertically center
|
||||
m_pLabel->setAnchorPoint(ccp(0, 0.5f));
|
||||
m_pLabel->setPosition(ccp(5, size.height / 2.0f));
|
||||
m_pLabel->setPosition(ccp(CC_EDIT_BOX_PADDING, size.height / 2.0f));
|
||||
m_pLabel->setColor(m_colText);
|
||||
m_pEditBox->addChild(m_pLabel);
|
||||
|
||||
|
||||
m_pLabelPlaceHolder = CCLabelTTF::create("", "", size.height-12);
|
||||
// align the text vertically center
|
||||
m_pLabelPlaceHolder->setAnchorPoint(ccp(0, 0.5f));
|
||||
m_pLabelPlaceHolder->setPosition(ccp(5, size.height / 2.0f));
|
||||
m_pLabelPlaceHolder->setPosition(ccp(CC_EDIT_BOX_PADDING, size.height / 2.0f));
|
||||
m_pLabelPlaceHolder->setVisible(false);
|
||||
m_pLabelPlaceHolder->setColor(m_colPlaceHolder);
|
||||
m_pEditBox->addChild(m_pLabelPlaceHolder);
|
||||
|
@ -153,19 +155,19 @@ void CCEditBoxImplAndroid::setText(const char* pText)
|
|||
if (pText != NULL)
|
||||
{
|
||||
m_strText = pText;
|
||||
|
||||
|
||||
if (m_strText.length() > 0)
|
||||
{
|
||||
m_pLabelPlaceHolder->setVisible(false);
|
||||
|
||||
|
||||
std::string strToShow;
|
||||
|
||||
|
||||
if (kEditBoxInputFlagPassword == m_eEditBoxInputFlag)
|
||||
{
|
||||
long length = cc_utf8_strlen(m_strText.c_str(), -1);
|
||||
for (long i = 0; i < length; i++)
|
||||
{
|
||||
strToShow.append("*");
|
||||
strToShow.append("\u25CF");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -173,15 +175,23 @@ void CCEditBoxImplAndroid::setText(const char* pText)
|
|||
strToShow = m_strText;
|
||||
}
|
||||
|
||||
std::string strWithEllipsis = getStringWithEllipsisJni(strToShow.c_str(), m_EditSize.width, m_EditSize.height-12);
|
||||
m_pLabel->setString(strWithEllipsis.c_str());
|
||||
m_pLabel->setString(strToShow.c_str());
|
||||
|
||||
// Clip the text width to fit to the text box
|
||||
float fMaxWidth = m_EditSize.width - CC_EDIT_BOX_PADDING * 2;
|
||||
CCRect clippingRect = m_pLabel->getTextureRect();
|
||||
if(clippingRect.size.width > fMaxWidth) {
|
||||
clippingRect.size.width = fMaxWidth;
|
||||
m_pLabel->setTextureRect(clippingRect);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLabelPlaceHolder->setVisible(true);
|
||||
m_pLabel->setString("");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,14 +209,14 @@ void CCEditBoxImplAndroid::setPlaceHolder(const char* pText)
|
|||
{
|
||||
m_pLabelPlaceHolder->setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
m_pLabelPlaceHolder->setString(m_strPlaceHolder.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CCEditBoxImplAndroid::setPosition(const CCPoint& pos)
|
||||
{ // don't need to be implemented on android platform.
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CCEditBoxImplAndroid::setVisible(bool visible)
|
||||
|
@ -216,7 +226,7 @@ void CCEditBoxImplAndroid::setVisible(bool visible)
|
|||
|
||||
void CCEditBoxImplAndroid::setContentSize(const CCSize& size)
|
||||
{ // don't need to be implemented on android platform.
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CCEditBoxImplAndroid::setAnchorPoint(const CCPoint& anchorPoint)
|
||||
|
@ -229,11 +239,16 @@ void CCEditBoxImplAndroid::visit(void)
|
|||
|
||||
}
|
||||
|
||||
void CCEditBoxImplAndroid::onEnter(void)
|
||||
{ // don't need to be implemented on android platform.
|
||||
|
||||
}
|
||||
|
||||
static void editBoxCallbackFunc(const char* pText, void* ctx)
|
||||
{
|
||||
CCEditBoxImplAndroid* thiz = (CCEditBoxImplAndroid*)ctx;
|
||||
thiz->setText(pText);
|
||||
|
||||
|
||||
if (thiz->getDelegate() != NULL)
|
||||
{
|
||||
thiz->getDelegate()->editBoxTextChanged(thiz->getCCEditBox(), thiz->getText());
|
||||
|
@ -248,21 +263,21 @@ void CCEditBoxImplAndroid::openKeyboard()
|
|||
{
|
||||
m_pDelegate->editBoxEditingDidBegin(m_pEditBox);
|
||||
}
|
||||
|
||||
|
||||
showEditTextDialogJNI( m_strPlaceHolder.c_str(),
|
||||
m_strText.c_str(),
|
||||
m_eEditBoxInputMode,
|
||||
m_eEditBoxInputFlag,
|
||||
m_eKeyboardReturnType,
|
||||
m_nMaxLength,
|
||||
editBoxCallbackFunc,
|
||||
(void*)this );
|
||||
|
||||
m_strText.c_str(),
|
||||
m_eEditBoxInputMode,
|
||||
m_eEditBoxInputFlag,
|
||||
m_eKeyboardReturnType,
|
||||
m_nMaxLength,
|
||||
editBoxCallbackFunc,
|
||||
(void*)this );
|
||||
|
||||
}
|
||||
|
||||
void CCEditBoxImplAndroid::closeKeyboard()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
NS_CC_EXT_END
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
virtual void setContentSize(const CCSize& size);
|
||||
virtual void setAnchorPoint(const CCPoint& anchorPoint);
|
||||
virtual void visit(void);
|
||||
virtual void onEnter(void);
|
||||
virtual void doAnimationWhenKeyboardMove(float duration, float distance);
|
||||
virtual void openKeyboard();
|
||||
virtual void closeKeyboard();
|
||||
|
|
|
@ -94,11 +94,20 @@ public:
|
|||
virtual void setContentSize(const CCSize& size);
|
||||
virtual void setAnchorPoint(const CCPoint& anchorPoint);
|
||||
virtual void visit(void);
|
||||
virtual void onEnter(void);
|
||||
virtual void doAnimationWhenKeyboardMove(float duration, float distance);
|
||||
virtual void openKeyboard();
|
||||
virtual void closeKeyboard();
|
||||
|
||||
virtual void onEndEditing();
|
||||
|
||||
private:
|
||||
void initInactiveLabels(const CCSize& size);
|
||||
void setInactiveText(const char* pText);
|
||||
void adjustTextFieldPosition();
|
||||
|
||||
CCLabelTTF* m_pLabel;
|
||||
CCLabelTTF* m_pLabelPlaceHolder;
|
||||
CCSize m_tContentSize;
|
||||
CCPoint m_obPosition;
|
||||
CCPoint m_obAnchorPoint;
|
||||
|
|
|
@ -31,11 +31,12 @@
|
|||
|
||||
#define getEditBoxImplIOS() ((cocos2d::extension::CCEditBoxImplIOS*)editBox_)
|
||||
|
||||
static const int CC_EDIT_BOX_PADDING = 5;
|
||||
|
||||
@implementation CustomUITextField
|
||||
- (CGRect)textRectForBounds:(CGRect)bounds {
|
||||
float padding = 5.0f;
|
||||
return CGRectMake(bounds.origin.x + padding, bounds.origin.y + padding,
|
||||
bounds.size.width - padding*2, bounds.size.height - padding*2);
|
||||
return CGRectMake(bounds.origin.x + CC_EDIT_BOX_PADDING, bounds.origin.y + CC_EDIT_BOX_PADDING,
|
||||
bounds.size.width - CC_EDIT_BOX_PADDING*2, bounds.size.height - CC_EDIT_BOX_PADDING*2);
|
||||
}
|
||||
- (CGRect)editingRectForBounds:(CGRect)bounds {
|
||||
return [self textRectForBounds:bounds];
|
||||
|
@ -78,6 +79,7 @@
|
|||
self.editBox = editBox;
|
||||
|
||||
[[EAGLView sharedEGLView] addSubview:textField_];
|
||||
textField_.hidden = YES;
|
||||
|
||||
return self;
|
||||
}while(0);
|
||||
|
@ -116,7 +118,6 @@
|
|||
-(void) closeKeyboard
|
||||
{
|
||||
[textField_ resignFirstResponder];
|
||||
[textField_ removeFromSuperview];
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)sender
|
||||
|
@ -161,6 +162,11 @@
|
|||
pDelegate->editBoxEditingDidEnd(getEditBoxImplIOS()->getCCEditBox());
|
||||
pDelegate->editBoxReturn(getEditBoxImplIOS()->getCCEditBox());
|
||||
}
|
||||
|
||||
if(editBox_ != nil)
|
||||
{
|
||||
getEditBoxImplIOS()->onEndEditing();
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
@ -212,6 +218,8 @@ CCEditBoxImpl* __createSystemEditBox(CCEditBox* pEditBox)
|
|||
|
||||
CCEditBoxImplIOS::CCEditBoxImplIOS(CCEditBox* pEditText)
|
||||
: CCEditBoxImpl(pEditText)
|
||||
, m_pLabel(NULL)
|
||||
, m_pLabelPlaceHolder(NULL)
|
||||
, m_systemControl(NULL)
|
||||
, m_obAnchorPoint(ccp(0.5f, 0.5f))
|
||||
, m_nMaxTextLength(-1)
|
||||
|
@ -249,12 +257,55 @@ bool CCEditBoxImplIOS::initWithSize(const CCSize& size)
|
|||
m_systemControl = [[EditBoxImplIOS alloc] initWithFrame:rect editBox:this];
|
||||
if (!m_systemControl) break;
|
||||
|
||||
initInactiveLabels(size);
|
||||
|
||||
return true;
|
||||
}while (0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CCEditBoxImplIOS::initInactiveLabels(const CCSize& size)
|
||||
{
|
||||
const char* pDefaultFontName = [[m_systemControl.textField.font fontName] UTF8String];
|
||||
float fDefaultFontSize = [m_systemControl.textField.font pointSize];
|
||||
|
||||
m_pLabel = CCLabelTTF::create("", pDefaultFontName, fDefaultFontSize);
|
||||
m_pLabel->setAnchorPoint(ccp(0, 0.5f));
|
||||
m_pLabel->setPosition(ccp(CC_EDIT_BOX_PADDING, size.height / 2.0f + 1));
|
||||
m_pLabel->setColor(ccBLACK);
|
||||
m_pLabel->setVisible(false);
|
||||
m_pEditBox->addChild(m_pLabel);
|
||||
|
||||
m_pLabelPlaceHolder = CCLabelTTF::create("", pDefaultFontName, fDefaultFontSize);
|
||||
// align the text vertically center
|
||||
m_pLabelPlaceHolder->setAnchorPoint(ccp(0, 0.5f));
|
||||
m_pLabelPlaceHolder->setPosition(ccp(CC_EDIT_BOX_PADDING, size.height / 2.0f + 1));
|
||||
m_pLabelPlaceHolder->setColor(ccGRAY);
|
||||
m_pEditBox->addChild(m_pLabelPlaceHolder);
|
||||
}
|
||||
|
||||
void CCEditBoxImplIOS::setInactiveText(const char* pText)
|
||||
{
|
||||
if(m_systemControl.textField.secureTextEntry == YES)
|
||||
{
|
||||
std::string passwordString;
|
||||
for(int i = 0; i < strlen(pText); ++i)
|
||||
passwordString.append("\u25CF");
|
||||
m_pLabel->setString(passwordString.c_str());
|
||||
}
|
||||
else
|
||||
m_pLabel->setString(getText());
|
||||
|
||||
// Clip the text width to fit to the text box
|
||||
float fMaxWidth = m_pEditBox->getContentSize().width - CC_EDIT_BOX_PADDING * 2;
|
||||
CCRect clippingRect = m_pLabel->getTextureRect();
|
||||
if(clippingRect.size.width > fMaxWidth) {
|
||||
clippingRect.size.width = fMaxWidth;
|
||||
m_pLabel->setTextureRect(clippingRect);
|
||||
}
|
||||
}
|
||||
|
||||
void CCEditBoxImplIOS::setFont(const char* pFontName, int fontSize)
|
||||
{
|
||||
if(pFontName == NULL)
|
||||
|
@ -263,11 +314,17 @@ void CCEditBoxImplIOS::setFont(const char* pFontName, int fontSize)
|
|||
UIFont *textFont = [UIFont fontWithName:fntName size:fontSize];
|
||||
if(textFont != nil)
|
||||
[m_systemControl.textField setFont:textFont];
|
||||
|
||||
m_pLabel->setFontName(pFontName);
|
||||
m_pLabel->setFontSize(fontSize);
|
||||
m_pLabelPlaceHolder->setFontName(pFontName);
|
||||
m_pLabelPlaceHolder->setFontSize(fontSize);
|
||||
}
|
||||
|
||||
void CCEditBoxImplIOS::setFontColor(const ccColor3B& color)
|
||||
{
|
||||
m_systemControl.textField.textColor = [UIColor colorWithRed:color.r / 255.0f green:color.g / 255.0f blue:color.b / 255.0f alpha:1.0f];
|
||||
m_pLabel->setColor(color);
|
||||
}
|
||||
|
||||
void CCEditBoxImplIOS::setPlaceholderFont(const char* pFontName, int fontSize)
|
||||
|
@ -277,7 +334,7 @@ void CCEditBoxImplIOS::setPlaceholderFont(const char* pFontName, int fontSize)
|
|||
|
||||
void CCEditBoxImplIOS::setPlaceholderFontColor(const ccColor3B& color)
|
||||
{
|
||||
// TODO need to be implemented.
|
||||
m_pLabelPlaceHolder->setColor(color);
|
||||
}
|
||||
|
||||
void CCEditBoxImplIOS::setInputMode(EditBoxInputMode inputMode)
|
||||
|
@ -371,6 +428,19 @@ bool CCEditBoxImplIOS::isEditing()
|
|||
void CCEditBoxImplIOS::setText(const char* pText)
|
||||
{
|
||||
m_systemControl.textField.text = [NSString stringWithUTF8String:pText];
|
||||
if(m_systemControl.textField.hidden == YES) {
|
||||
setInactiveText(pText);
|
||||
if(strlen(pText) == 0)
|
||||
{
|
||||
m_pLabel->setVisible(false);
|
||||
m_pLabelPlaceHolder->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLabel->setVisible(true);
|
||||
m_pLabelPlaceHolder->setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* CCEditBoxImplIOS::getText(void)
|
||||
|
@ -381,6 +451,7 @@ const char* CCEditBoxImplIOS::getText(void)
|
|||
void CCEditBoxImplIOS::setPlaceHolder(const char* pText)
|
||||
{
|
||||
m_systemControl.textField.placeholder = [NSString stringWithUTF8String:pText];
|
||||
m_pLabelPlaceHolder->setString(pText);
|
||||
}
|
||||
|
||||
static CGPoint convertDesignCoordToScreenCoord(const CCPoint& designCoord, bool bInRetinaMode)
|
||||
|
@ -404,17 +475,13 @@ static CGPoint convertDesignCoordToScreenCoord(const CCPoint& designCoord, bool
|
|||
|
||||
void CCEditBoxImplIOS::setPosition(const CCPoint& pos)
|
||||
{
|
||||
if (!m_obPosition.equals(pos))
|
||||
{
|
||||
m_obPosition = pos;
|
||||
CCPoint designCoord = ccp(pos.x - m_tContentSize.width * m_obAnchorPoint.x, pos.y + m_tContentSize.height * (1 - m_obAnchorPoint.y));
|
||||
[m_systemControl setPosition:convertDesignCoordToScreenCoord(designCoord, m_bInRetinaMode)];
|
||||
}
|
||||
m_obPosition = pos;
|
||||
adjustTextFieldPosition();
|
||||
}
|
||||
|
||||
void CCEditBoxImplIOS::setVisible(bool visible)
|
||||
{
|
||||
m_systemControl.textField.hidden = !visible;
|
||||
// m_systemControl.textField.hidden = !visible;
|
||||
}
|
||||
|
||||
void CCEditBoxImplIOS::setContentSize(const CCSize& size)
|
||||
|
@ -432,16 +499,30 @@ void CCEditBoxImplIOS::setAnchorPoint(const CCPoint& anchorPoint)
|
|||
|
||||
void CCEditBoxImplIOS::visit(void)
|
||||
{
|
||||
if(getCCEditBox()->getParent()) {
|
||||
CCPoint p = getCCEditBox()->getParent()->convertToWorldSpace(getCCEditBox()->getPosition());
|
||||
setPosition(p);
|
||||
} else {
|
||||
setPosition(getCCEditBox()->getPosition());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CCEditBoxImplIOS::onEnter(void)
|
||||
{
|
||||
adjustTextFieldPosition();
|
||||
}
|
||||
|
||||
void CCEditBoxImplIOS::adjustTextFieldPosition()
|
||||
{
|
||||
CCSize contentSize = m_pEditBox->getContentSize();
|
||||
CCRect rect = CCRectMake(0, 0, contentSize.width, contentSize.height);
|
||||
rect = CCRectApplyAffineTransform(rect, m_pEditBox->nodeToWorldTransform());
|
||||
|
||||
CCPoint designCoord = ccp(rect.origin.x, rect.origin.y + rect.size.height);
|
||||
[m_systemControl setPosition:convertDesignCoordToScreenCoord(designCoord, m_bInRetinaMode)];
|
||||
}
|
||||
|
||||
void CCEditBoxImplIOS::openKeyboard()
|
||||
{
|
||||
m_pLabel->setVisible(false);
|
||||
m_pLabelPlaceHolder->setVisible(false);
|
||||
|
||||
m_systemControl.textField.hidden = NO;
|
||||
[m_systemControl openKeyboard];
|
||||
}
|
||||
|
||||
|
@ -450,6 +531,22 @@ void CCEditBoxImplIOS::closeKeyboard()
|
|||
[m_systemControl closeKeyboard];
|
||||
}
|
||||
|
||||
void CCEditBoxImplIOS::onEndEditing()
|
||||
{
|
||||
m_systemControl.textField.hidden = YES;
|
||||
if(strlen(getText()) == 0)
|
||||
{
|
||||
m_pLabel->setVisible(false);
|
||||
m_pLabelPlaceHolder->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLabel->setVisible(true);
|
||||
m_pLabelPlaceHolder->setVisible(false);
|
||||
setInactiveText(getText());
|
||||
}
|
||||
}
|
||||
|
||||
NS_CC_EXT_END
|
||||
|
||||
#endif /* #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) */
|
||||
|
|
Loading…
Reference in New Issue