mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
Android: make keyboard appear and disappear only on demand
This commit is contained in:
parent
6da233c387
commit
2710d1df50
@ -268,10 +268,14 @@ void SelectionTab::clickLeft(tribool down, bool previousState)
|
|||||||
if(down)
|
if(down)
|
||||||
{
|
{
|
||||||
int line = getLine();
|
int line = getLine();
|
||||||
|
|
||||||
if(line != -1)
|
if(line != -1)
|
||||||
|
{
|
||||||
select(line);
|
select(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SelectionTab::keyPressed(const SDL_KeyboardEvent & key)
|
void SelectionTab::keyPressed(const SDL_KeyboardEvent & key)
|
||||||
{
|
{
|
||||||
if(key.state != SDL_PRESSED)
|
if(key.state != SDL_PRESSED)
|
||||||
|
@ -175,15 +175,15 @@ void CTextContainer::blitLine(SDL_Surface *to, Rect destRect, std::string what)
|
|||||||
where.x += (int)f->getStringWidth(toPrint);
|
where.x += (int)f->getStringWidth(toPrint);
|
||||||
}
|
}
|
||||||
currDelimeter++;
|
currDelimeter++;
|
||||||
}
|
} while(begin++ != std::string::npos);
|
||||||
while (begin++ != std::string::npos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CTextContainer::CTextContainer(EAlignment alignment, EFonts font, SDL_Color color) :
|
CTextContainer::CTextContainer(EAlignment alignment, EFonts font, SDL_Color color) :
|
||||||
alignment(alignment),
|
alignment(alignment),
|
||||||
font(font),
|
font(font),
|
||||||
color(color)
|
color(color)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void CMultiLineLabel::showAll(SDL_Surface * to)
|
void CMultiLineLabel::showAll(SDL_Surface * to)
|
||||||
{
|
{
|
||||||
@ -410,33 +410,41 @@ void CGStatusBar::lock(bool shouldLock)
|
|||||||
|
|
||||||
CTextInput::CTextInput(const Rect & Pos, EFonts font, const CFunctionList<void(const std::string &)> & CB)
|
CTextInput::CTextInput(const Rect & Pos, EFonts font, const CFunctionList<void(const std::string &)> & CB)
|
||||||
: CLabel(Pos.x, Pos.y, font, CENTER),
|
: CLabel(Pos.x, Pos.y, font, CENTER),
|
||||||
cb(CB)
|
cb(CB),
|
||||||
|
CFocusable(std::make_shared<CKeyboardFocusListener>(this))
|
||||||
{
|
{
|
||||||
type |= REDRAW_PARENT;
|
type |= REDRAW_PARENT;
|
||||||
focus = false;
|
|
||||||
pos.h = Pos.h;
|
pos.h = Pos.h;
|
||||||
pos.w = Pos.w;
|
pos.w = Pos.w;
|
||||||
captureAllKeys = true;
|
captureAllKeys = true;
|
||||||
background.reset();
|
background.reset();
|
||||||
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
|
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
|
||||||
|
|
||||||
|
#ifndef VCMI_ANDROID
|
||||||
giveFocus();
|
giveFocus();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CTextInput::CTextInput(const Rect & Pos, const Point & bgOffset, const std::string & bgName, const CFunctionList<void(const std::string &)> & CB)
|
CTextInput::CTextInput(const Rect & Pos, const Point & bgOffset, const std::string & bgName, const CFunctionList<void(const std::string &)> & CB)
|
||||||
:cb(CB)
|
:cb(CB), CFocusable(std::make_shared<CKeyboardFocusListener>(this))
|
||||||
{
|
{
|
||||||
focus = false;
|
|
||||||
pos += Pos;
|
pos += Pos;
|
||||||
|
pos.h = Pos.h;
|
||||||
|
pos.w = Pos.w;
|
||||||
|
|
||||||
captureAllKeys = true;
|
captureAllKeys = true;
|
||||||
OBJ_CONSTRUCTION;
|
OBJ_CONSTRUCTION;
|
||||||
background = std::make_shared<CPicture>(bgName, bgOffset.x, bgOffset.y);
|
background = std::make_shared<CPicture>(bgName, bgOffset.x, bgOffset.y);
|
||||||
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
|
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
|
||||||
|
|
||||||
|
#ifndef VCMI_ANDROID
|
||||||
giveFocus();
|
giveFocus();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CTextInput::CTextInput(const Rect & Pos, SDL_Surface * srf)
|
CTextInput::CTextInput(const Rect & Pos, SDL_Surface * srf)
|
||||||
|
:CFocusable(std::make_shared<CKeyboardFocusListener>(this))
|
||||||
{
|
{
|
||||||
focus = false;
|
|
||||||
pos += Pos;
|
pos += Pos;
|
||||||
captureAllKeys = true;
|
captureAllKeys = true;
|
||||||
OBJ_CONSTRUCTION;
|
OBJ_CONSTRUCTION;
|
||||||
@ -450,22 +458,35 @@ CTextInput::CTextInput(const Rect & Pos, SDL_Surface * srf)
|
|||||||
pos.h = background->pos.h;
|
pos.h = background->pos.h;
|
||||||
background->pos = pos;
|
background->pos = pos;
|
||||||
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
|
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
|
||||||
giveFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CTextInput::focusGot()
|
#ifndef VCMI_ANDROID
|
||||||
{
|
giveFocus();
|
||||||
CSDL_Ext::startTextInput(&pos);
|
|
||||||
#ifdef VCMI_ANDROID
|
|
||||||
notifyAndroidTextInputChanged(text);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTextInput::focusLost()
|
std::atomic<int> CKeyboardFocusListener::usageIndex(0);
|
||||||
|
|
||||||
|
CKeyboardFocusListener::CKeyboardFocusListener(CTextInput * textInput)
|
||||||
|
:textInput(textInput)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKeyboardFocusListener::focusGot()
|
||||||
|
{
|
||||||
|
CSDL_Ext::startTextInput(&textInput->pos);
|
||||||
|
#ifdef VCMI_ANDROID
|
||||||
|
textInput->notifyAndroidTextInputChanged(textInput->text);
|
||||||
|
#endif
|
||||||
|
usageIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKeyboardFocusListener::focusLost()
|
||||||
|
{
|
||||||
|
if(0 == --usageIndex)
|
||||||
{
|
{
|
||||||
CSDL_Ext::stopTextInput();
|
CSDL_Ext::stopTextInput();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string CTextInput::visibleText()
|
std::string CTextInput::visibleText()
|
||||||
{
|
{
|
||||||
@ -641,6 +662,12 @@ void CTextInput::notifyAndroidTextInputChanged(std::string & text)
|
|||||||
#endif //VCMI_ANDROID
|
#endif //VCMI_ANDROID
|
||||||
|
|
||||||
CFocusable::CFocusable()
|
CFocusable::CFocusable()
|
||||||
|
:CFocusable(std::make_shared<IFocusListener>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CFocusable::CFocusable(std::shared_ptr<IFocusListener> focusListener)
|
||||||
|
: focusListener(focusListener)
|
||||||
{
|
{
|
||||||
focus = false;
|
focus = false;
|
||||||
focusables.push_back(this);
|
focusables.push_back(this);
|
||||||
@ -648,24 +675,30 @@ CFocusable::CFocusable()
|
|||||||
|
|
||||||
CFocusable::~CFocusable()
|
CFocusable::~CFocusable()
|
||||||
{
|
{
|
||||||
if(inputWithFocus == this)
|
if(hasFocus())
|
||||||
{
|
{
|
||||||
focusLost();
|
|
||||||
inputWithFocus = nullptr;
|
inputWithFocus = nullptr;
|
||||||
|
focusListener->focusLost();
|
||||||
}
|
}
|
||||||
|
|
||||||
focusables -= this;
|
focusables -= this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CFocusable::hasFocus() const
|
||||||
|
{
|
||||||
|
return inputWithFocus == this;
|
||||||
|
}
|
||||||
|
|
||||||
void CFocusable::giveFocus()
|
void CFocusable::giveFocus()
|
||||||
{
|
{
|
||||||
focus = true;
|
focus = true;
|
||||||
focusGot();
|
focusListener->focusGot();
|
||||||
redraw();
|
redraw();
|
||||||
|
|
||||||
if(inputWithFocus)
|
if(inputWithFocus)
|
||||||
{
|
{
|
||||||
inputWithFocus->focus = false;
|
inputWithFocus->focus = false;
|
||||||
|
inputWithFocus->focusListener->focusLost();
|
||||||
inputWithFocus->redraw();
|
inputWithFocus->redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,24 +140,50 @@ public:
|
|||||||
void lock(bool shouldLock); //If true, current text cannot be changed until lock(false) is called
|
void lock(bool shouldLock); //If true, current text cannot be changed until lock(false) is called
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CFocusable;
|
||||||
|
|
||||||
|
class IFocusListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void focusGot() {};
|
||||||
|
virtual void focusLost() {};
|
||||||
|
virtual ~IFocusListener() = default;
|
||||||
|
};
|
||||||
|
|
||||||
/// UIElement which can get input focus
|
/// UIElement which can get input focus
|
||||||
class CFocusable : public virtual CIntObject
|
class CFocusable : public virtual CIntObject
|
||||||
{
|
{
|
||||||
protected:
|
private:
|
||||||
virtual void focusGot(){};
|
std::shared_ptr<IFocusListener> focusListener;
|
||||||
virtual void focusLost(){};
|
|
||||||
public:
|
public:
|
||||||
bool focus; //only one focusable control can have focus at one moment
|
bool focus; //only one focusable control can have focus at one moment
|
||||||
|
|
||||||
void giveFocus(); //captures focus
|
void giveFocus(); //captures focus
|
||||||
void moveFocus(); //moves focus to next active control (may be used for tab switching)
|
void moveFocus(); //moves focus to next active control (may be used for tab switching)
|
||||||
|
bool hasFocus() const;
|
||||||
|
|
||||||
static std::list<CFocusable *> focusables; //all existing objs
|
static std::list<CFocusable *> focusables; //all existing objs
|
||||||
static CFocusable * inputWithFocus; //who has focus now
|
static CFocusable * inputWithFocus; //who has focus now
|
||||||
|
|
||||||
CFocusable();
|
CFocusable();
|
||||||
|
CFocusable(std::shared_ptr<IFocusListener> focusListener);
|
||||||
~CFocusable();
|
~CFocusable();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CTextInput;
|
||||||
|
class CKeyboardFocusListener : public IFocusListener
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static std::atomic<int> usageIndex;
|
||||||
|
CTextInput * textInput;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CKeyboardFocusListener(CTextInput * textInput);
|
||||||
|
void focusGot() override;
|
||||||
|
void focusLost() override;
|
||||||
|
};
|
||||||
|
|
||||||
/// Text input box where players can enter text
|
/// Text input box where players can enter text
|
||||||
class CTextInput : public CLabel, public CFocusable
|
class CTextInput : public CLabel, public CFocusable
|
||||||
{
|
{
|
||||||
@ -165,9 +191,6 @@ class CTextInput : public CLabel, public CFocusable
|
|||||||
protected:
|
protected:
|
||||||
std::string visibleText() override;
|
std::string visibleText() override;
|
||||||
|
|
||||||
void focusGot() override;
|
|
||||||
void focusLost() override;
|
|
||||||
|
|
||||||
#ifdef VCMI_ANDROID
|
#ifdef VCMI_ANDROID
|
||||||
void notifyAndroidTextInputChanged(std::string & text);
|
void notifyAndroidTextInputChanged(std::string & text);
|
||||||
#endif
|
#endif
|
||||||
@ -192,4 +215,6 @@ public:
|
|||||||
//Filter that will allow only input of numbers in range min-max (min-max are allowed)
|
//Filter that will allow only input of numbers in range min-max (min-max are allowed)
|
||||||
//min-max should be set via something like std::bind
|
//min-max should be set via something like std::bind
|
||||||
static void numberFilter(std::string & text, const std::string & oldText, int minValue, int maxValue);
|
static void numberFilter(std::string & text, const std::string & oldText, int minValue, int maxValue);
|
||||||
|
|
||||||
|
friend class CKeyboardFocusListener;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user