ManaPlus
textfield.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2018 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 /* _______ __ __ __ ______ __ __ _______ __ __
24  * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
25  * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
26  * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
27  * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
28  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
29  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
30  *
31  * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
32  *
33  *
34  * Per Larsson a.k.a finalman
35  * Olof Naessén a.k.a jansem/yakslem
36  *
37  * Visit: http://guichan.sourceforge.net
38  *
39  * License: (BSD)
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  * 1. Redistributions of source code must retain the above copyright
44  * notice, this list of conditions and the following disclaimer.
45  * 2. Redistributions in binary form must reproduce the above copyright
46  * notice, this list of conditions and the following disclaimer in
47  * the documentation and/or other materials provided with the
48  * distribution.
49  * 3. Neither the name of Guichan nor the names of its contributors may
50  * be used to endorse or promote products derived from this software
51  * without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
54  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
55  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
56  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
57  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
58  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
59  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
60  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
61  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
62  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64  */
65 
66 #include "gui/widgets/textfield.h"
67 
68 #include "settings.h"
69 
70 #ifdef USE_SDL2
71 #include "enums/input/keyvalue.h"
72 #endif // USE_SDL2
73 
74 #include "gui/gui.h"
75 #include "gui/skin.h"
76 #ifdef ANDROID
77 #include "gui/windowmanager.h"
78 #endif // ANDROID
79 
80 #include "gui/fonts/font.h"
81 
82 #include "gui/popups/popupmenu.h"
83 
84 #include "input/inputmanager.h"
85 
86 #include "utils/copynpaste.h"
87 #include "utils/stringutils.h"
88 
89 #ifndef USE_SDL2
90 #include "utils/timer.h"
91 #endif // USE_SDL2
92 
93 #include "render/graphics.h"
94 
95 #include "resources/imagerect.h"
96 
97 #include "resources/image/image.h"
98 
99 #undef DELETE // Win32 compatibility hack
100 
101 #include "debug.h"
102 
104 int TextField::instances = 0;
105 float TextField::mAlpha = 1.0;
107 
109  const std::string &restrict text,
110  const LoseFocusOnTab loseFocusOnTab,
112  const std::string &restrict eventId,
113  const bool sendAlwaysEvents) :
114  Widget(widget),
115  FocusListener(),
116  KeyListener(),
117  MouseListener(),
118  WidgetListener(),
119  mText(text),
120  mTextChunk(),
121  mCaretPosition(0),
122  mXScroll(0),
123  mCaretColor(&getThemeColor(ThemeColorId::CARET, 255U)),
124  mMinimum(0),
125  mMaximum(0),
126  mLastEventPaste(0),
127  mPadding(1),
128  mNumeric(false),
129  mLoseFocusOnTab(loseFocusOnTab),
130  mAllowSpecialActions(true),
131  mSendAlwaysEvents(sendAlwaysEvents),
132  mTextChanged(true)
133 {
134  mAllowLogic = false;
135  setFocusable(true);
136  addMouseListener(this);
137  addKeyListener(this);
138 
139  setFrameSize(2);
142 
143  addFocusListener(this);
144 
145  if (instances == 0)
146  {
147  if (theme != nullptr)
148  {
150  "textfield.xml",
151  "textfield_background.xml",
152  0,
153  8);
154  }
155  }
156 
157  instances++;
158 
159  if (mSkin != nullptr)
160  {
162  mFrameSize = mSkin->getOption("frameSize", 2);
163  }
164 
165  adjustSize();
166  if (!eventId.empty())
167  setActionEventId(eventId);
168 
169  if (listener != nullptr)
170  addActionListener(listener);
171 }
172 
174 {
175  if (mWindow != nullptr)
177 
178  if (gui != nullptr)
179  gui->removeDragged(this);
180 
181  instances--;
182  if (instances == 0)
183  {
184  if (theme != nullptr)
185  {
186  theme->unload(mSkin);
187  Theme::unloadRect(skin, 0, 8);
188  }
189  }
191 }
192 
194 {
195  const float alpha = std::max(settings.guiAlpha,
197 
198  if (alpha != mAlpha)
199  {
200  mAlpha = alpha;
201  for (int a = 0; a < 9; a++)
202  {
203  if (skin.grid[a] != nullptr)
204  skin.grid[a]->setAlpha(mAlpha);
205  }
206  }
207 }
208 
209 void TextField::draw(Graphics *const graphics)
210 {
211  BLOCK_START("TextField::draw")
212  updateAlpha();
213 
214  Font *const font = getFont();
215  if (isFocused())
216  {
217  drawCaret(graphics,
218  font->getWidth(mText.substr(0, mCaretPosition)) - mXScroll);
219  }
220 
221  if (mTextChanged)
222  {
228  font->generate(mTextChunk);
229  mTextChanged = false;
230  }
231 
232  const Image *const image = mTextChunk.img;
233  if (image != nullptr)
234  graphics->drawImage(image, mPadding - mXScroll, mPadding);
235 
236  BLOCK_END("TextField::draw")
237 }
238 
239 void TextField::safeDraw(Graphics *const graphics)
240 {
241  TextField::draw(graphics);
242 }
243 
244 void TextField::drawFrame(Graphics *const graphics)
245 {
246  BLOCK_START("TextField::drawFrame")
247  const int bs = 2 * mFrameSize;
248  graphics->drawImageRect(0,
249  0,
250  mDimension.width + bs,
251  mDimension.height + bs,
252  skin);
253  BLOCK_END("TextField::drawFrame")
254 }
255 
256 void TextField::safeDrawFrame(Graphics *const graphics)
257 {
258  BLOCK_START("TextField::drawFrame")
259  const int bs = 2 * mFrameSize;
260  graphics->drawImageRect(0,
261  0,
262  mDimension.width + bs,
263  mDimension.height + bs,
264  skin);
265  BLOCK_END("TextField::drawFrame")
266 }
267 
268 void TextField::setNumeric(const bool numeric)
269 {
270  mNumeric = numeric;
271  if (!numeric)
272  return;
273 
274  const char *const text = mText.c_str();
275  for (const char *textPtr = text; *textPtr != 0; ++textPtr)
276  {
277  if (*textPtr < '0' || *textPtr > '9')
278  {
279  setText(mText.substr(0, textPtr - text));
280  return;
281  }
282  }
283 }
284 
286 {
287  if (!mNumeric)
288  return 0;
289 
290  const int value = atoi(mText.c_str());
291  if (value < mMinimum)
292  return mMinimum;
293 
294  if (value > mMaximum)
295  return mMaximum;
296 
297  return value;
298 }
299 
301 {
302  const int val = event.getKey().getValue();
303 
304 #ifdef USE_SDL2
305  if (val == KeyValue::TEXTINPUT)
306  {
307  std::string str = event.getText();
308  mText.insert(mCaretPosition, str);
309  mTextChanged = true;
310  mCaretPosition += CAST_U32(str.size());
311  event.consume();
312  fixScroll();
313  if (mSendAlwaysEvents)
315  return;
316  }
317  bool consumed(false);
318 #else // USE_SDL2
319 
320  if (val >= 32)
321  {
322  if (mNumeric)
323  {
324  if ((val >= '0' && val <= '9') ||
325  (val == '-' && mCaretPosition == 0u))
326  {
327  char buf[2];
328  buf[0] = CAST_8(val);
329  buf[1] = 0;
330  mText.insert(mCaretPosition, std::string(buf));
331  mTextChanged = true;
332  mCaretPosition += 1;
333  event.consume();
334  fixScroll();
335  if (mSendAlwaysEvents)
337  return;
338  }
339  }
340  else if ((mMaximum == 0) ||
341  CAST_S32(mText.size()) < mMaximum)
342  {
343  int len;
344  if (val < 128)
345  len = 1; // 0xxxxxxx
346  else if (val < 0x800)
347  len = 2; // 110xxxxx 10xxxxxx
348  else if (val < 0x10000)
349  len = 3; // 1110xxxx 10xxxxxx 10xxxxxx
350  else
351  len = 4; // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
352 
353  char buf[4];
354  for (int i = 0; i < len; ++ i)
355  {
356  buf[i] = CAST_8(val >> (6 * (len - i - 1)));
357  if (i > 0)
358  buf[i] = CAST_8((buf[i] & 63) | 128);
359  }
360 
361  if (len > 1)
362  buf[0] |= CAST_8(255U << (8 - len));
363 
364  mText.insert(mCaretPosition, std::string(buf, buf + len));
365  mCaretPosition += len;
366  mTextChanged = true;
367  event.consume();
368  fixScroll();
369  if (mSendAlwaysEvents)
371  return;
372  }
373  }
374 
375  /* In UTF-8, 10xxxxxx is only used for inner parts of characters. So skip
376  them when processing key presses. */
377 
378  // unblock past key
379  if (val != 22)
380  mLastEventPaste = 0;
381 
382  bool consumed(false);
383 #endif // USE_SDL2
384 
385  const InputActionT action = event.getActionId();
387  {
388  if (!handleNormalKeys(action, consumed))
389  {
390  if (consumed)
391  event.consume();
392  return;
393  }
394  }
395  else
396  {
397  handleCtrlKeys(action, consumed);
398  }
399 
400  if (mSendAlwaysEvents)
402 
403  if (consumed)
404  event.consume();
405  fixScroll();
406 }
407 
408 bool TextField::handleNormalKeys(const InputActionT action, bool &consumed)
409 {
410  PRAGMA45(GCC diagnostic push)
411  PRAGMA45(GCC diagnostic ignored "-Wswitch-enum")
412  switch (action)
413  {
415  {
416  consumed = true;
417  while (mCaretPosition > 0)
418  {
419  --mCaretPosition;
420  if ((mText[mCaretPosition] & 192) != 128)
421  break;
422  }
423  break;
424  }
425 
427  {
428  consumed = true;
429  const unsigned sz = CAST_U32(mText.size());
430  while (mCaretPosition < sz)
431  {
432  ++mCaretPosition;
433  if (mCaretPosition == sz ||
434  (mText[mCaretPosition] & 192) != 128)
435  {
436  break;
437  }
438  }
439  break;
440  }
441 
443  {
444  consumed = true;
445  unsigned sz = CAST_U32(mText.size());
446  while (mCaretPosition < sz)
447  {
448  --sz;
449  mText.erase(mCaretPosition, 1);
450  mTextChanged = true;
451  if (mCaretPosition == sz ||
452  (mText[mCaretPosition] & 192) != 128)
453  {
454  break;
455  }
456  }
457  break;
458  }
459 
461  consumed = true;
463  mTextChanged = true;
464  break;
465 
468  consumed = true;
469  fixScroll();
470  return false;
471 
473  mCaretPosition = 0;
474  consumed = true;
475  break;
476 
478  mCaretPosition = CAST_U32(mText.size());
479  consumed = true;
480  break;
481 
484  return false;
485  consumed = true;
486  break;
487 
488  default:
489  break;
490  }
491  PRAGMA45(GCC diagnostic pop)
492  return true;
493 }
494 
495 void TextField::handleCtrlKeys(const InputActionT action, bool &consumed)
496 {
497  PRAGMA45(GCC diagnostic push)
498  PRAGMA45(GCC diagnostic ignored "-Wswitch-enum")
499  switch (action)
500  {
502  {
504  consumed = true;
505  break;
506  }
508  {
510  consumed = true;
511  break;
512  }
513  case InputAction::GUI_B:
514  {
516  {
517  moveCaretBack();
518  consumed = true;
519  }
520  break;
521  }
522  case InputAction::GUI_F:
523  {
525  consumed = true;
526  break;
527  }
528  case InputAction::GUI_D:
529  {
530  caretDelete();
531  consumed = true;
532  break;
533  }
534  case InputAction::GUI_E:
535  {
536  mCaretPosition = CAST_S32(mText.size());
537  consumed = true;
538  break;
539  }
540  case InputAction::GUI_H:
541  {
543  mTextChanged = true;
544  consumed = true;
545  break;
546  }
547  case InputAction::GUI_K:
548  {
549  mText = mText.substr(0, mCaretPosition);
550  mTextChanged = true;
551  consumed = true;
552  break;
553  }
554  case InputAction::GUI_U:
555  {
557  consumed = true;
558  break;
559  }
560  case InputAction::GUI_C:
561  {
562  handleCopy();
563  consumed = true;
564  break;
565  }
566  case InputAction::GUI_V:
567  {
568 #ifdef USE_SDL2
569  handlePaste();
570 #else // USE_SDL2
571 
572  // hack to prevent paste key sticking
573  if ((mLastEventPaste != 0) && mLastEventPaste > cur_time)
574  break;
575  handlePaste();
577 #endif // USE_SDL2
578 
579  consumed = true;
580  break;
581  }
582  case InputAction::GUI_W:
583  {
584  caretDeleteWord();
585  consumed = true;
586  break;
587  }
588  default:
589  break;
590  }
591  PRAGMA45(GCC diagnostic pop)
592 }
593 
595 {
596  while (mCaretPosition > 0)
597  {
598  --mCaretPosition;
599  if ((mText[mCaretPosition] & 192) != 128)
600  break;
601  }
602 }
603 
605 {
606  const unsigned sz = CAST_U32(mText.size());
607  while (mCaretPosition < sz)
608  {
609  ++mCaretPosition;
610  if (mCaretPosition == sz || (mText[mCaretPosition] & 192) != 128)
611  break;
612  }
613 }
614 
616 {
617  unsigned sz = CAST_U32(mText.size());
618  while (mCaretPosition < sz)
619  {
620  --sz;
621  mText.erase(mCaretPosition, 1);
622  if (mCaretPosition == sz || (mText[mCaretPosition] & 192) != 128)
623  break;
624  }
625  mTextChanged = true;
626 }
627 
629 {
630  std::string text = getText();
631  size_t caretPos = CAST_SIZE(getCaretPosition());
632 
633  if (retrieveBuffer(text, caretPos))
634  {
635  setText(text);
636  setCaretPosition(CAST_U32(caretPos));
637  }
638 }
639 
641 {
642  if (mCaretPosition > 0)
643  {
644  mText = mText.substr(mCaretPosition);
645  mCaretPosition = 0;
646  }
647  mTextChanged = true;
648 }
649 
651 {
652  const unsigned int oldCaret = mCaretPosition;
653  while (mCaretPosition > 0)
654  {
656  break;
657  mCaretPosition --;
658  }
659  if (oldCaret != mCaretPosition)
660  return;
661  while (mCaretPosition > 0)
662  {
664  break;
665  mCaretPosition --;
666  }
667 }
668 
670 {
671  const unsigned sz = CAST_U32(mText.size());
672  const unsigned int oldCaret = mCaretPosition;
673  while (mCaretPosition < sz)
674  {
676  break;
677  mCaretPosition ++;
678  }
679  if (oldCaret != mCaretPosition)
680  return;
681  while (mCaretPosition < sz)
682  {
684  break;
685  mCaretPosition ++;
686  }
687 }
688 
690 {
691  while (mCaretPosition > 0)
692  {
695  break;
696  }
697  mTextChanged = true;
698 }
699 
701 {
702  std::string text = getText();
703  sendBuffer(text);
704 }
705 
706 void TextField::drawCaret(Graphics* graphics, int x)
707 {
708  const ClipRect &clipArea = graphics->getTopClip();
709 
710  graphics->setColor(*mCaretColor);
711  graphics->drawLine(x + mPadding, clipArea.height - mPadding,
712  x + mPadding, mPadding);
713 }
714 
716 {
717  setWidth(getFont()->getWidth(mText) + 2 * mPadding + 1);
718  adjustHeight();
719 
720  fixScroll();
721 }
722 
724 {
725  setHeight(getFont()->getHeight() + 2 * mPadding);
726 }
727 
729 {
730  if (isFocused())
731  {
732  const int caretX = getFont()->getWidth(
733  mText.substr(0, mCaretPosition));
734 
735  const int width = mDimension.width;
736  const int pad = 2 * mPadding;
737  if (caretX - mXScroll >= width - pad)
738  {
739  mXScroll = caretX - width + pad;
740  }
741  else if (caretX - mXScroll <= 0)
742  {
743  mXScroll = caretX - width / 2;
744 
745  if (mXScroll < 0)
746  mXScroll = 0;
747  }
748  }
749 }
750 
751 void TextField::setCaretPosition(unsigned int position)
752 {
753  const unsigned int sz = CAST_U32(mText.size());
754  if (position > sz)
755  mCaretPosition = CAST_S32(sz);
756  else
757  mCaretPosition = position;
758 
759  fixScroll();
760 }
761 
763 {
764  fixScroll();
765 }
766 
768 {
769 #ifdef ANDROID
772 #endif // ANDROID
773 
774  event.consume();
775  if (event.getButton() == MouseButton::RIGHT)
776  {
777 #ifndef DYECMD
778  if (popupMenu != nullptr)
780 #endif // DYECMD
781  }
782  else if (event.getButton() == MouseButton::LEFT)
783  {
785  mText, event.getX() + mXScroll);
786  fixScroll();
787  }
788 }
789 
791 {
792 #ifdef ANDROID
795 #endif // ANDROID
796 }
797 
799 {
800 }
801 
802 void TextField::setText(const std::string& text)
803 {
804  const unsigned int sz = CAST_U32(text.size());
805  if (sz < mCaretPosition)
806  mCaretPosition = sz;
807  mText = text;
808  mTextChanged = true;
809 }
810 
812 {
813  event.consume();
814 }
815 
817 {
818  mTextChanged = true;
820 }
821 
823 {
824  if (mWindow != nullptr)
825  mWindow->addWidgetListener(this);
826  Widget::setParent(widget);
827 }
828 
829 void TextField::setWindow(Widget *const widget)
830 {
831  if ((widget == nullptr) && (mWindow != nullptr))
832  {
834  mWindow = nullptr;
835  }
836  else
837  {
838  Widget2::setWindow(widget);
839  }
840 }
841 
843 {
845 }
static Skin * mSkin
Definition: textfield.h:257
#define CAST_U32
Definition: cast.h:30
Font * getFont() const
Definition: widget.cpp:330
void safeDrawFrame(Graphics *const graphics)
Definition: textfield.cpp:256
bool sendBuffer(const std::string &text)
Definition: copynpaste.cpp:517
const Color * mCaretColor
Definition: textfield.h:278
LoseFocusOnTab mLoseFocusOnTab
Definition: textfield.h:287
int width
Definition: rect.h:218
std::string text
Definition: textchunk.h:64
int getWidth() const
Definition: widget.h:220
int mMaximum
Definition: textfield.h:283
const bool LoseFocusOnTab_true
Definition: skin.h:35
void fontChanged()
Definition: textfield.cpp:762
void setWidth(const int width)
Definition: widget.cpp:132
void unload(Skin *const skin)
Definition: theme.cpp:249
ClipRect & getTopClip() const
Definition: graphics.h:280
Gui * gui
Definition: gui.cpp:110
Definition: font.h:88
void handlePaste()
Definition: textfield.cpp:628
void adjustSize()
Definition: textfield.cpp:715
int mXScroll
Definition: textfield.h:276
PRAGMA45(GCC diagnostic push) PRAGMA45(GCC diagnostic ignored "-Wunused-result") int TestLauncher
virtual void drawImageRect(const int x, const int y, const int w, const int h, const ImageRect &imgRect)=0
void caretDeleteWord()
Definition: textfield.cpp:689
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:251
void showTextFieldPopup(TextField *const input)
Definition: popupmenu.cpp:2172
bool mNumeric
Definition: textfield.h:286
MouseButtonT getButton() const
Definition: mouseevent.h:115
float getMinimumOpacity() const
Definition: theme.h:123
#define BLOCK_START(name)
Definition: perfomance.h:78
void addFocusListener(FocusListener *const focusListener)
Definition: widget.cpp:281
void moveCaretBack()
Definition: textfield.cpp:594
void setCaretPosition(unsigned int position)
Definition: textfield.cpp:751
#define BLOCK_END(name)
Definition: perfomance.h:79
void setNumeric(const bool numeric)
Definition: textfield.cpp:268
void focusLost(const Event &event)
Definition: textfield.cpp:798
time_t mLastEventPaste
Definition: textfield.h:284
void mousePressed(MouseEvent &event)
Definition: textfield.cpp:767
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:595
unsigned int mCaretPosition
Definition: textfield.h:269
void updateAlpha()
Definition: textfield.cpp:193
Color mForegroundColor
Definition: widget.h:1085
Font * textFont
Definition: textchunk.h:63
void keyPressed(KeyEvent &event)
Definition: textfield.cpp:300
void drawCaret(Graphics *graphics, int x)
Definition: textfield.cpp:706
bool isActionActive(const InputActionT index) const
int getOption(const std::string &name) const
Definition: skin.h:105
virtual bool isFocused() const
Definition: widget.cpp:183
void setText(const std::string &text)
Definition: textfield.cpp:802
int getValue() const
Definition: textfield.cpp:285
bool isWordSeparator(const signed char chr) A_CONST
Definition: stringutils.h:141
TextField(const Widget2 *const widget, const std::string &text, const LoseFocusOnTab loseFocusOnTab, ActionListener *const listener, const std::string &eventId, const bool sendAlwaysEvents)
Definition: textfield.cpp:108
void handleCopy() const
Definition: textfield.cpp:700
int getStringIndexAt(const std::string &text, const int x) const
Definition: font.cpp:411
void distributeActionEvent()
Definition: widget.cpp:492
void drawFrame(Graphics *const graphics)
Definition: textfield.cpp:244
Settings settings
Definition: settings.cpp:31
virtual void setAlpha(const float alpha)
Definition: image.cpp:286
#define CAST_8
Definition: cast.h:24
int getPadding() const
Definition: skin.h:99
void moveCaretWordBack()
Definition: textfield.cpp:650
virtual void setColor(const Color &color)
Definition: graphics.h:319
void widgetHidden(const Event &event)
Definition: textfield.cpp:816
virtual void setWindow(Widget *const window)
Definition: widget2.h:96
#define CAST_S32
Definition: cast.h:29
Image * grid[9]
Definition: imagerect.h:41
Widget * mWindow
Definition: widget2.h:111
void deleteCharLeft(std::string &str, unsigned *const pos)
void handleCtrlKeys(const InputActionT action, bool &consumed)
Definition: textfield.cpp:495
unsigned int getCaretPosition() const
Definition: textfield.h:233
void draw(Graphics *const graphics)
Definition: textfield.cpp:209
std::string mText
Definition: textfield.h:262
Skin * loadSkinRect(ImageRect &image, const std::string &name, const std::string &name2, const int start, const int end)
Definition: theme.cpp:899
void safeDraw(Graphics *const graphics)
Definition: textfield.cpp:239
unsigned int mFrameSize
Definition: widget.h:1137
PopupMenu * popupMenu
Definition: popupmenu.cpp:102
void setFrameSize(const unsigned int frameSize)
Definition: widget.h:167
bool retrieveBuffer(std::string &text, size_t &pos)
Definition: copynpaste.cpp:512
static ImageRect skin
Definition: textfield.h:281
InputAction ::T InputActionT
Definition: inputaction.h:715
void setWindow(Widget *const widget)
Definition: textfield.cpp:829
bool mAllowLogic
Definition: widget.h:1159
void addMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:291
int height
Definition: rect.h:223
void addKeyListener(KeyListener *const keyListener)
Definition: widget.cpp:271
void caretDelete()
Definition: textfield.cpp:615
volatile time_t cur_time
Definition: timer.cpp:57
virtual void setParent(Widget *parent)
Definition: widget.h:625
bool isKeyboardVisible()
void setHeight(const int height)
Definition: widget.cpp:139
void addWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:301
void mouseDragged(MouseEvent &event)
Definition: textfield.cpp:811
Theme * theme
Definition: theme.cpp:61
#define A_UNUSED
Definition: localconsts.h:171
void setFocusable(const bool focusable)
Definition: widget.cpp:191
Color mForegroundColor2
Definition: widget2.h:112
Image * img
Definition: textchunk.h:62
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
void removeDragged(const Widget *const widget)
Definition: gui.cpp:1160
Definition: widget.h:97
virtual void drawLine(int x1, int y1, int x2, int y2)=0
void removeWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:306
void fixScroll()
Definition: textfield.cpp:728
int getWidth(const std::string &text) const
Definition: font.cpp:333
Definition: event.h:77
Definition: image.h:61
int getHeight() const
Definition: widget.h:239
void moveCaretWordForward()
Definition: textfield.cpp:669
Color color
Definition: textchunk.h:65
void focusGained(const Event &event)
Definition: textfield.cpp:790
#define restrict
Definition: localconsts.h:176
#define CAST_SIZE
Definition: cast.h:33
bool mTextChanged
Definition: textfield.h:290
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:44
void caretDeleteToStart()
Definition: textfield.cpp:640
int getX() const
Definition: mouseevent.h:126
InputManager inputManager
bool mSendAlwaysEvents
Definition: textfield.h:289
static int instances
Definition: textfield.h:279
void setParent(Widget *widget)
Definition: textfield.cpp:822
void signalEvent()
Definition: textfield.cpp:842
TextChunk mTextChunk
Definition: textfield.h:264
void deleteImage()
Definition: textchunk.cpp:192
static void unloadRect(const ImageRect &rect, const int start, const int end)
Definition: theme.cpp:914
float guiAlpha
Definition: settings.h:128
static float mAlpha
Definition: textfield.h:280
Color color2
Definition: textchunk.h:66
Rect mDimension
Definition: widget.h:1100
int mMinimum
Definition: textfield.h:282
void executeAction(const InputActionT keyNum)
const std::string & getText() const
Definition: textfield.h:223
int mPadding
Definition: textfield.h:285
void adjustHeight()
Definition: textfield.cpp:723
void moveCaretForward()
Definition: textfield.cpp:604
bool mAllowSpecialActions
Definition: textfield.h:288
bool handleNormalKeys(const InputActionT action, bool &consumed)
Definition: textfield.cpp:408
void generate(TextChunk &chunk)
Definition: font.cpp:428