ManaPlus
gui.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-2017 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/gui.h"
67 
68 #include "gui/focushandler.h"
69 #include "gui/sdlinput.h"
70 #include "gui/viewport.h"
71 
72 #include "gui/fonts/font.h"
73 
74 #include "gui/widgets/label.h"
75 #include "gui/widgets/window.h"
76 
77 #include "gui/widgets/tabs/tab.h"
78 
79 #ifndef DYECMD
80 #include "dragdrop.h"
81 #else // DYECMD
82 #include "resources/image/image.h"
83 #endif // DYECMD
84 #include "settings.h"
85 
88 #include "listeners/keylistener.h"
89 
90 #include "input/inputmanager.h"
91 
93 
94 #include "render/renderers.h"
95 
96 #include "resources/imageset.h"
97 
99 
100 #include "utils/delete2.h"
101 #include "utils/foreach.h"
102 #include "utils/langs.h"
103 #include "utils/sdlsharedhelper.h"
104 #include "utils/timer.h"
105 
106 #include "net/ipc.h"
107 
108 #include "debug.h"
109 
110 Gui *gui = nullptr;
111 Font *boldFont = nullptr;
112 
114  mTop(nullptr),
115  mGraphics(nullptr),
116  mInput(nullptr),
117  mFocusHandler(new FocusHandler),
118  mKeyListeners(),
119  mLastMousePressButton(MouseButton::EMPTY),
120  mLastMousePressTimeStamp(0U),
121  mLastMouseX(0),
122  mLastMouseY(0),
123  mClickCount(1),
124  mLastMouseDragButton(MouseButton::EMPTY),
125  mWidgetWithMouseQueue(),
126  mConfigListener(new GuiConfigListener(this)),
127  mGuiFont(nullptr),
128  mInfoParticleFont(nullptr),
129  mHelpFont(nullptr),
130  mSecureFont(nullptr),
131  mNpcFont(nullptr),
132  mMouseCursors(nullptr),
133  mMouseCursorAlpha(1.0F),
134  mMouseInactivityTimer(0),
135  mCursorType(Cursor::CURSOR_POINTER),
136 #ifdef ANDROID
137  mLastMouseRealX(0),
138  mLastMouseRealY(0),
139 #endif // ANDROID
140  mFocusListeners(),
141  mForegroundColor(theme->getColor(ThemeColorId::TEXT, 255)),
142  mForegroundColor2(theme->getColor(ThemeColorId::TEXT_OUTLINE, 255)),
143  mTime(0),
144  mTime10(0),
145  mCustomCursor(false),
146  mDoubleClick(true)
147 {
148 }
149 
150 void Gui::postInit(Graphics *const graphics)
151 {
152  logger->log1("Initializing GUI...");
153  // Set graphics
154  setGraphics(graphics);
155 
156  // Set input
157  guiInput = new SDLInput;
159 
160  // Set focus handler
161  delete mFocusHandler;
163 
164  // Initialize top GUI widget
165  WindowContainer *const guiTop = new WindowContainer(nullptr);
166  guiTop->setFocusable(true);
167  guiTop->setSize(graphics->mWidth, graphics->mHeight);
168  guiTop->setOpaque(Opaque_false);
170  setTop(guiTop);
171 
172  const StringVect langs = getLang();
173  const bool isJapan = (!langs.empty() && langs[0].size() > 3
174  && langs[0].substr(0, 3) == "ja_");
175  const bool isChinese = (!langs.empty() && langs[0].size() > 3
176  && langs[0].substr(0, 3) == "zh_");
177 
178  // Set global font
179  const int fontSize = config.getIntValue("fontSize");
180  std::string fontFile = config.getValue("font", "");
181  if (isJapan)
182  {
183  fontFile = config.getValue("japanFont", "");
184  if (fontFile.empty())
185  fontFile = branding.getStringValue("japanFont");
186  }
187  else if (isChinese)
188  {
189  fontFile = config.getValue("chinaFont", "");
190  if (fontFile.empty())
191  fontFile = branding.getStringValue("chinaFont");
192  }
193  if (fontFile.empty())
194  fontFile = branding.getStringValue("font");
195 
196  mGuiFont = new Font(fontFile, fontSize, TTF_STYLE_NORMAL);
197 
198  // Set particle font
199  fontFile = config.getValue("particleFont", "");
200  if (isJapan)
201  {
202  fontFile = config.getValue("japanFont", "");
203  if (fontFile.empty())
204  fontFile = branding.getStringValue("japanFont");
205  }
206  else if (isChinese)
207  {
208  fontFile = config.getValue("chinaFont", "");
209  if (fontFile.empty())
210  fontFile = branding.getStringValue("chinaFont");
211  }
212  if (fontFile.empty())
213  fontFile = branding.getStringValue("particleFont");
214 
215  mInfoParticleFont = new Font(fontFile, fontSize, TTF_STYLE_BOLD);
216 
217  // Set bold font
218  fontFile = config.getValue("boldFont", "");
219  if (fontFile.empty())
220  fontFile = branding.getStringValue("boldFont");
221 
222  boldFont = new Font(fontFile, fontSize, TTF_STYLE_NORMAL);
223 
224  // Set help font
225  fontFile = config.getValue("helpFont", "");
226  if (fontFile.empty())
227  fontFile = branding.getStringValue("helpFont");
228 
229  mHelpFont = new Font(fontFile, fontSize, TTF_STYLE_NORMAL);
230 
231  // Set secure font
232  fontFile = config.getValue("secureFont", "");
233  if (fontFile.empty())
234  fontFile = branding.getStringValue("secureFont");
235 
236  mSecureFont = new Font(fontFile, fontSize, TTF_STYLE_NORMAL);
237 
238  // Set npc font
239  const int npcFontSize = config.getIntValue("npcfontSize");
240  fontFile = config.getValue("npcFont", "");
241  if (isJapan)
242  {
243  fontFile = config.getValue("japanFont", "");
244  if (fontFile.empty())
245  fontFile = branding.getStringValue("japanFont");
246  }
247  else if (isChinese)
248  {
249  fontFile = config.getValue("chinaFont", "");
250  if (fontFile.empty())
251  fontFile = branding.getStringValue("chinaFont");
252  }
253  if (fontFile.empty())
254  fontFile = branding.getStringValue("npcFont");
255 
256  mNpcFont = new Font(fontFile, npcFontSize, TTF_STYLE_NORMAL);
257 
259 
260  // Initialize mouse cursor and listen for changes to the option
261  setUseCustomCursor(config.getBoolValue("customcursor"));
262  setDoubleClick(config.getBoolValue("doubleClick"));
263  config.addListener("customcursor", mConfigListener);
264  config.addListener("doubleClick", mConfigListener);
265 }
266 
268 {
271 
272  if (mMouseCursors != nullptr)
273  {
275  mMouseCursors = nullptr;
276  }
277 
278  if (windowContainer != nullptr)
280  Widget *top = mTop;
282  setTop(nullptr);
284  delete top;
285 
286  delete2(mGuiFont);
287  delete2(boldFont);
291  delete2(mNpcFont);
292  delete2(guiInput);
293  delete2(theme);
294 
299 }
300 
302 {
303  BLOCK_START("Gui::logic")
305 
306  if (mTop == nullptr)
307  {
308  BLOCK_END("Gui::logic")
309  return;
310  }
311 
314 
315  if (guiInput != nullptr)
317 
318  mTop->logic();
319  BLOCK_END("Gui::logic")
320 }
321 
323 {
324  BLOCK_START("Gui::slowLogic")
326 
327  // Fade out mouse cursor after extended inactivity
328  if (mMouseInactivityTimer < 100 * 15)
329  {
331  mMouseCursorAlpha = std::min(1.0F, mMouseCursorAlpha + 0.05F);
332  }
333  else
334  {
335  mMouseCursorAlpha = std::max(0.0F, mMouseCursorAlpha - 0.005F);
336  }
337  if (mGuiFont != nullptr)
338  mGuiFont->slowLogic(0);
339  if (mInfoParticleFont != nullptr)
341  if (mHelpFont != nullptr)
342  mHelpFont->slowLogic(2);
343  if (mSecureFont != nullptr)
345  if (boldFont != nullptr)
346  boldFont->slowLogic(4);
347  if (mNpcFont != nullptr)
348  mNpcFont->slowLogic(5);
349  if (windowContainer != nullptr)
351 
352  const time_t time = cur_time;
353  if (mTime != time)
354  {
355  logger->flush();
356  if (ipc != nullptr)
357  ipc->flush();
358  mTime = time;
359 
360  if (time > mTime10 || mTime10 - time > 10)
361  {
362  mTime10 = time + 10;
365  }
366  }
367 
368  BLOCK_END("Gui::slowLogic")
369 }
370 
372 {
373  if (mGuiFont != nullptr)
374  mGuiFont->clear();
375  if (mInfoParticleFont != nullptr)
377  if (mHelpFont != nullptr)
378  mHelpFont->clear();
379  if (mSecureFont != nullptr)
380  mSecureFont->clear();
381  if (boldFont != nullptr)
382  boldFont->clear();
383  if (mNpcFont != nullptr)
384  mNpcFont->clear();
385 }
386 
388 {
389  if (mInput != nullptr)
390  return handleKeyInput();
391  return false;
392 }
393 
395 {
396  if (guiInput == nullptr)
397  return false;
398 
399  BLOCK_START("Gui::handleKeyInput")
400  bool consumed(false);
401 
402  while (!mInput->isKeyQueueEmpty())
403  {
404  const KeyInput keyInput = guiInput->dequeueKeyInput();
405 
406  KeyEvent eventToGlobalKeyListeners(nullptr,
407  keyInput.getType(),
408  keyInput.getActionId(), keyInput.getKey());
409 
410 #ifdef USE_SDL2
411  if (!keyInput.getText().empty())
412  eventToGlobalKeyListeners.setText(keyInput.getText());
413 #endif // USE_SDL2
414 
416  eventToGlobalKeyListeners);
417 
418  // If a global key listener consumes the event it will not be
419  // sent further to the source of the event.
420  if (eventToGlobalKeyListeners.isConsumed())
421  {
422  consumed = true;
423  continue;
424  }
425 
426  if (mFocusHandler != nullptr)
427  {
428  bool eventConsumed = false;
429 
430  // Send key inputs to the focused widgets
431  if (mFocusHandler->getFocused() != nullptr)
432  {
433  KeyEvent event(getKeyEventSource(),
434  keyInput.getType(),
435  keyInput.getActionId(), keyInput.getKey());
436 #ifdef USE_SDL2
437  if (!keyInput.getText().empty())
438  event.setText(keyInput.getText());
439 #endif // USE_SDL2
440 
443  else
444  distributeKeyEvent(event);
445 
446  eventConsumed = event.isConsumed();
447  if (eventConsumed)
448  consumed = true;
449  }
450 
451  // If the key event hasn't been consumed and
452  // tabbing is enable check for tab press and
453  // change focus.
454  if (!eventConsumed && keyInput.getActionId()
456  keyInput.getType() == KeyEventType::PRESSED)
457  {
460  else
462  }
463  }
464  } // end while
465  BLOCK_END("Gui::handleKeyInput")
466  return consumed;
467 }
468 
469 void Gui::draw()
470 {
471  BLOCK_START("Gui::draw 1")
472  Widget *const top = getTop();
473  if (top == nullptr)
474  return;
476 
478  {
479  top->draw(mGraphics);
480  touchManager.draw();
481  }
482  else
483  {
484  top->safeDraw(mGraphics);
486  }
487 
488  int mouseX;
489  int mouseY;
490  const MouseStateType button = getMouseState(mouseX, mouseY);
491 
492  if ((settings.mouseFocused ||
493  ((button & SDL_BUTTON(1)) != 0)) &&
494  mMouseCursors != nullptr &&
495  mCustomCursor &&
496  mMouseCursorAlpha > 0.0F)
497  {
498 #ifndef DYECMD
499  const Image *const image = dragDrop.getItemImage();
500  if (mGuiFont != nullptr)
501  {
502  const std::string &str = dragDrop.getText();
503  if (!str.empty())
504  {
505  const int posX = mouseX - mGuiFont->getWidth(str) / 2;
506  const int posY = mouseY +
507  (image != nullptr ? image->mBounds.h / 2 : 0);
510  str,
511  posX, posY);
512  }
513  }
514  if (image != nullptr)
515  {
516  const int posX = mouseX - (image->mBounds.w / 2);
517  const int posY = mouseY - (image->mBounds.h / 2);
518  mGraphics->drawImage(image, posX, posY);
519  }
520 #endif // DYECMD
521 
522  Image *const mouseCursor = mMouseCursors->get(
524  if (mouseCursor != nullptr)
525  {
526  mouseCursor->setAlpha(mMouseCursorAlpha);
527  mGraphics->drawImage(mouseCursor, mouseX - 15, mouseY - 17);
528  }
529  }
530 
532  BLOCK_END("Gui::draw 1")
533 }
534 
535 void Gui::videoResized() const
536 {
537  WindowContainer *const top = static_cast<WindowContainer *>(getTop());
538 
539  if (top != nullptr)
540  {
541  const int oldWidth = top->getWidth();
542  const int oldHeight = top->getHeight();
543 
545  top->adjustAfterResize(oldWidth, oldHeight);
546  }
547 
548  if (viewport != nullptr)
551 }
552 
553 void Gui::setUseCustomCursor(const bool customCursor)
554 {
556  {
557  SDL::showCursor(false);
558  return;
559  }
560  if (customCursor != mCustomCursor)
561  {
562  mCustomCursor = customCursor;
563 
564  if (mCustomCursor)
565  {
566  // Hide the SDL mouse cursor
567  SDL::showCursor(false);
568 
569  // Load the mouse cursor
570  if (mMouseCursors != nullptr)
572  mMouseCursors = Theme::getImageSetFromTheme("mouse.png", 40, 40);
573 
574  if (mMouseCursors == nullptr)
575  logger->log("Error: Unable to load mouse cursors.");
576  }
577  else
578  {
579  // Show the SDL mouse cursor
580  SDL::showCursor(true);
581 
582  // Unload the mouse cursor
583  if (mMouseCursors != nullptr)
584  {
586  mMouseCursors = nullptr;
587  }
588  }
589  }
590 }
591 
592 void Gui::handleMouseMoved(const MouseInput &mouseInput)
593 {
594  // Check if the mouse leaves the application window.
595  if (mTop != nullptr &&
596  !mWidgetWithMouseQueue.empty() &&
597  (mouseInput.getX() < 0 ||
598  mouseInput.getY() < 0 ||
599  !mTop->getDimension().isPointInRect(mouseInput.getX(),
600  mouseInput.getY())))
601  {
602  // Distribute an event to all widgets in the
603  // "widget with mouse" queue.
604  while (!mWidgetWithMouseQueue.empty())
605  {
606  Widget *const widget = mWidgetWithMouseQueue.front();
607 
608  if (Widget::widgetExists(widget))
609  {
610  distributeMouseEvent(widget,
612  mouseInput.getButton(),
613  mouseInput.getX(),
614  mouseInput.getY(),
615  true,
616  true);
617  }
618 
619  mWidgetWithMouseQueue.pop_front();
620  }
621 
623  return;
624  }
625 
626  const int mouseX = mouseInput.getX();
627  const int mouseY = mouseInput.getY();
628  const MouseButtonT button = mouseInput.getButton();
629 
630  // Check if there is a need to send mouse exited events by
631  // traversing the "widget with mouse" queue.
632  bool widgetWithMouseQueueCheckDone = mWidgetWithMouseQueue.empty();
633  while (!widgetWithMouseQueueCheckDone)
634  {
635  unsigned int iterations = 0;
636  for (std::deque<Widget*>::iterator
637  iter = mWidgetWithMouseQueue.begin();
638  iter != mWidgetWithMouseQueue.end();
639  ++ iter)
640  {
641  Widget *const widget = *iter;
642 
643  // If a widget in the "widget with mouse queue" doesn't
644  // exists anymore it should be removed from the queue.
645  if (!Widget::widgetExists(widget))
646  {
647  mWidgetWithMouseQueue.erase(iter);
648  break;
649  }
650  else
651  {
652  int x;
653  int y;
654  widget->getAbsolutePosition(x, y);
655 
656  if (x > mouseX
657  || y > mouseY
658  || x + widget->getWidth() <= mouseX
659  || y + widget->getHeight() <= mouseY
660  || !widget->isVisible())
661  {
662  distributeMouseEvent(widget,
664  button,
665  mouseX,
666  mouseY,
667  true,
668  true);
669  mClickCount = 1;
671  mWidgetWithMouseQueue.erase(iter);
672  break;
673  }
674  }
675 
676  iterations++;
677  }
678 
679  widgetWithMouseQueueCheckDone =
680  (CAST_SIZE(iterations) == mWidgetWithMouseQueue.size());
681  }
682 
683  // Check all widgets below the mouse to see if they are
684  // present in the "widget with mouse" queue. If a widget
685  // is not then it should be added and an entered event should
686  // be sent to it.
687  Widget* parent = getMouseEventSource(mouseX, mouseY);
688  Widget* widget = parent;
689 
690  // If a widget has modal mouse input focus then it will
691  // always be returned from getMouseEventSource, but we only wan't to
692  // send mouse entered events if the mouse has actually entered the
693  // widget with modal mouse input focus, hence we need to check if
694  // that's the case. If it's not we should simply ignore to send any
695  // mouse entered events.
696  if ((mFocusHandler->getModalMouseInputFocused() != nullptr)
698  && Widget::widgetExists(widget) &&
699  (widget != nullptr))
700  {
701  int x, y;
702  widget->getAbsolutePosition(x, y);
703 
704  if (x > mouseX || y > mouseY
705  || x + widget->getWidth() <= mouseX
706  || y + widget->getHeight() <= mouseY)
707  {
708  parent = nullptr;
709  }
710  }
711 
712  while (parent != nullptr)
713  {
714  parent = widget->getParent();
715 
716  // Check if the widget is present in the "widget with mouse" queue.
717  bool widgetIsPresentInQueue = false;
718  FOR_EACH (std::deque<Widget*>::const_iterator,
719  iter, mWidgetWithMouseQueue)
720  {
721  if (*iter == widget)
722  {
723  widgetIsPresentInQueue = true;
724  break;
725  }
726  }
727 
728  // Widget is not present, send an entered event and add
729  // it to the "widget with mouse" queue.
730  if (!widgetIsPresentInQueue
731  && Widget::widgetExists(widget))
732  {
733  distributeMouseEvent(widget,
735  button,
736  mouseX,
737  mouseY,
738  true,
739  true);
740  mWidgetWithMouseQueue.push_front(widget);
741  }
742 
743  const Widget *const swap = widget;
744  widget = parent;
745  parent = swap->getParent();
746  }
747 
748  if (mFocusHandler->getDraggedWidget() != nullptr)
749  {
753  mouseX,
754  mouseY);
755  }
756  else
757  {
758  Widget *const sourceWidget = getMouseEventSource(mouseX, mouseY);
759  distributeMouseEvent(sourceWidget,
761  button,
762  mouseX,
763  mouseY);
764  }
766 }
767 
768 void Gui::handleMousePressed(const MouseInput &mouseInput)
769 {
770  const int x = mouseInput.getX();
771  const int y = mouseInput.getY();
772  const MouseButtonT button = mouseInput.getButton();
773  const unsigned int timeStamp = mouseInput.getTimeStamp();
774 
775  Widget *sourceWidget = getMouseEventSource(x, y);
776 
777  if (mFocusHandler->getDraggedWidget() != nullptr)
778  sourceWidget = mFocusHandler->getDraggedWidget();
779 
780  if (sourceWidget == nullptr)
781  return;
782  int sourceWidgetX;
783  int sourceWidgetY;
784  sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY);
785 
786  if (((mFocusHandler->getModalFocused() != nullptr)
787  && sourceWidget->isModalFocused())
788  || (mFocusHandler->getModalFocused() == nullptr))
789  {
790  sourceWidget->requestFocus();
791  }
792 
793  if (mDoubleClick &&
794  timeStamp - mLastMousePressTimeStamp < 250U &&
795  mLastMousePressButton == button)
796  {
797  mClickCount ++;
798  }
799  else
800  {
801  mClickCount = 1;
802  }
803 
804  distributeMouseEvent(sourceWidget, MouseEventType::PRESSED, button, x, y);
805  mFocusHandler->setLastWidgetPressed(sourceWidget);
806  mFocusHandler->setDraggedWidget(sourceWidget);
807  mLastMouseDragButton = button;
808  mLastMousePressButton = button;
809  mLastMousePressTimeStamp = timeStamp;
810 }
811 
813 {
814  const int fontSize = config.getIntValue("fontSize");
815  std::string fontFile = config.getValue("font", "");
816  if (fontFile.empty())
817  fontFile = branding.getStringValue("font");
818 
819  mGuiFont->loadFont(fontFile, fontSize, TTF_STYLE_NORMAL);
820 
821  fontFile = config.getValue("particleFont", "");
822  if (fontFile.empty())
823  fontFile = branding.getStringValue("particleFont");
824 
825  mInfoParticleFont->loadFont(fontFile, fontSize, TTF_STYLE_BOLD);
826 
827  fontFile = config.getValue("boldFont", "");
828  if (fontFile.empty())
829  fontFile = branding.getStringValue("boldFont");
830 
831  boldFont->loadFont(fontFile, fontSize, TTF_STYLE_NORMAL);
832 
833  const int npcFontSize = config.getIntValue("npcfontSize");
834 
835  fontFile = config.getValue("npcFont", "");
836  if (fontFile.empty())
837  fontFile = branding.getStringValue("npcFont");
838 
839  mNpcFont->loadFont(fontFile, npcFontSize, TTF_STYLE_NORMAL);
840 }
841 
843  const MouseEventTypeT type,
844  const MouseButtonT button,
845  const int x, const int y,
846  const bool force,
847  const bool toSourceOnly)
848 {
849  if ((source == nullptr) || (mFocusHandler == nullptr))
850  return;
851 
852  Widget *widget = source;
853 
854  if (!force)
855  {
856  if (mFocusHandler->getModalFocused() != nullptr
857  && !widget->isModalFocused())
858  {
859  return;
860  }
861  if (mFocusHandler->getModalMouseInputFocused() != nullptr
862  && !widget->isModalMouseInputFocused())
863  {
864  return;
865  }
866  }
867 
868  MouseEvent event(source,
869  type, button,
870  x, y, mClickCount);
871 
872  Widget* parent = source;
873  while (parent != nullptr)
874  {
875  // If the widget has been removed due to input
876  // cancel the distribution.
877  if (!Widget::widgetExists(widget))
878  break;
879 
880  parent = widget->getParent();
881 
882  if (widget->isEnabled() || force)
883  {
884  int widgetX;
885  int widgetY;
886  widget->getAbsolutePosition(widgetX, widgetY);
887 
888  event.setX(x - widgetX);
889  event.setY(y - widgetY);
890 
891  std::list<MouseListener*> mouseListeners
892  = widget->getMouseListeners();
893 
894  const MouseEventTypeT mouseType = event.getType();
895  // Send the event to all mouse listeners of the widget.
896  FOR_EACH (std::list<MouseListener*>::const_iterator,
897  it, mouseListeners)
898  {
899  switch (mouseType)
900  {
902  (*it)->mouseEntered(event);
903  break;
905  (*it)->mouseExited(event);
906  break;
908  (*it)->mouseMoved(event);
909  break;
911  (*it)->mousePressed(event);
912  break;
915  (*it)->mouseReleased(event);
916  break;
918  (*it)->mouseWheelMovedUp(event);
919  break;
921  (*it)->mouseWheelMovedDown(event);
922  break;
924  (*it)->mouseDragged(event);
925  break;
927  (*it)->mouseClicked(event);
928  break;
929  default:
930  break;
931  }
932  }
933 
934  if (toSourceOnly)
935  break;
936  }
937 
938  const Widget *const swap = widget;
939  widget = parent;
940  parent = swap->getParent();
941 
942 #ifndef DYECMD
943  if (type == MouseEventType::RELEASED)
944  dragDrop.clear();
945 #endif // DYECMD
946 
947  if ((widget == nullptr) || event.isConsumed())
948  break;
949 
950  // If a non modal focused widget has been reach
951  // and we have modal focus cancel the distribution.
952  if ((mFocusHandler->getModalFocused() != nullptr)
953  && !widget->isModalFocused())
954  {
955  break;
956  }
957 
958  // If a non modal mouse input focused widget has been reach
959  // and we have modal mouse input focus cancel the distribution.
960  if ((mFocusHandler->getModalMouseInputFocused() != nullptr)
961  && !widget->isModalMouseInputFocused())
962  {
963  break;
964  }
965  }
966 }
967 
969 {
970  mClickCount = 1;
972 }
973 
975 {
976  if ((viewport == nullptr) || (widget == nullptr))
977  return nullptr;
978 
979  int x = 0;
980  int y = 0;
981  int mouseX = 0;
982  int mouseY = 0;
983 
984  getAbsolutePosition(widget, x, y);
985  getMouseState(mouseX, mouseY);
986 
987  return new MouseEvent(widget,
990  mouseX - x,
991  mouseY - y,
992  mClickCount);
993 }
994 
996  int &restrict x,
997  int &restrict y)
998 {
999  if (widget == nullptr)
1000  return;
1001  x = 0;
1002  y = 0;
1003  while (widget->getParent() != nullptr)
1004  {
1005  x += widget->getX();
1006  y += widget->getY();
1007  widget = widget->getParent();
1008  }
1009 }
1010 
1012 {
1013  BLOCK_START("Gui::handleMouseInput")
1014  while (!mInput->isMouseQueueEmpty())
1015  {
1016  const MouseInput mouseInput = guiInput->dequeueMouseInput();
1017 
1018  if (touchManager.processEvent(mouseInput))
1019  {
1020 #ifdef ANDROID
1021 #ifndef USE_SDL2
1022  SDL_WarpMouse(mLastMouseX, mLastMouseY,
1023  mLastMouseRealX, mLastMouseRealY);
1024 #endif // USE_SDL2
1025 #endif // ANDROID
1026 
1028  continue;
1029  }
1030 
1031  // Save the current mouse state. It will be needed if modal focus
1032  // changes or modal mouse input focus changes.
1033  mLastMouseX = mouseInput.getX();
1034  mLastMouseY = mouseInput.getY();
1035 #ifdef ANDROID
1036  mLastMouseRealX = mouseInput.getRealX();
1037  mLastMouseRealY = mouseInput.getRealY();
1038 #endif // ANDROID
1039 
1040  switch (mouseInput.getType())
1041  {
1043  handleMousePressed(mouseInput);
1044  break;
1046  handleMouseReleased(mouseInput);
1047  break;
1048  case MouseEventType::MOVED:
1049  handleMouseMoved(mouseInput);
1050  break;
1052  handleMouseWheelMovedDown(mouseInput);
1053  break;
1055  handleMouseWheelMovedUp(mouseInput);
1056  break;
1062  default:
1063  break;
1064  }
1065  }
1066  BLOCK_END("Gui::handleMouseInput")
1067 }
1068 
1069 void Gui::handleMouseReleased(const MouseInput &mouseInput)
1070 {
1071  Widget *sourceWidget = getMouseEventSource(
1072  mouseInput.getX(), mouseInput.getY());
1073 
1074  int sourceWidgetX;
1075  int sourceWidgetY;
1076  if (mFocusHandler->getDraggedWidget() != nullptr)
1077  {
1078  if (sourceWidget != mFocusHandler->getLastWidgetPressed())
1080 
1081  Widget *const oldWidget = sourceWidget;
1082  sourceWidget = mFocusHandler->getDraggedWidget();
1083  if ((oldWidget != nullptr) && oldWidget != sourceWidget)
1084  {
1085  oldWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY);
1086  distributeMouseEvent(oldWidget,
1088  mouseInput.getButton(),
1089  mouseInput.getX(),
1090  mouseInput.getY());
1091  }
1092  }
1093 
1094  if (sourceWidget == nullptr)
1095  return;
1096  sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY);
1097  distributeMouseEvent(sourceWidget,
1099  mouseInput.getButton(),
1100  mouseInput.getX(),
1101  mouseInput.getY());
1102 
1103  if (mouseInput.getButton() == mLastMousePressButton
1104  && mFocusHandler->getLastWidgetPressed() == sourceWidget)
1105  {
1106  distributeMouseEvent(sourceWidget,
1108  mouseInput.getButton(),
1109  mouseInput.getX(),
1110  mouseInput.getY());
1111 
1113  }
1114  else
1115  {
1117  mClickCount = 0;
1118  }
1119 
1120  if (mFocusHandler->getDraggedWidget() != nullptr)
1121  mFocusHandler->setDraggedWidget(nullptr);
1122 }
1123 
1125 {
1126  mFocusListeners.push_back(focusListener);
1127 }
1128 
1130 {
1131  mFocusListeners.remove(focusListener);
1132 }
1133 
1135 {
1136  for (FocusListenerIterator iter = mFocusListeners.begin();
1137  iter != mFocusListeners.end();
1138  ++ iter)
1139  {
1140  (*iter)->focusGained(focusEvent);
1141  }
1142 }
1143 
1144 void Gui::removeDragged(const Widget *const widget)
1145 {
1146  if (mFocusHandler == nullptr)
1147  return;
1148 
1149  if (mFocusHandler->getDraggedWidget() == widget)
1150  mFocusHandler->setDraggedWidget(nullptr);
1151 }
1152 
1154 {
1155  const MouseStateType res = SDL_GetMouseState(&x, &y);
1156  const int scale = mainGraphics->getScale();
1157  x /= scale;
1158  y /= scale;
1159  return res;
1160 }
1161 
1162 void Gui::setTop(Widget *const top)
1163 {
1164  if (mTop != nullptr)
1165  mTop->setFocusHandler(nullptr);
1166  if (top != nullptr)
1168 
1169  mTop = top;
1170 }
1171 
1172 void Gui::setGraphics(Graphics *const graphics)
1173 {
1174  mGraphics = graphics;
1175 }
1176 
1178 {
1179  return mGraphics;
1180 }
1181 
1182 void Gui::setInput(SDLInput *const input)
1183 {
1184  mInput = input;
1185 }
1186 
1188 {
1189  return mInput;
1190 }
1191 
1192 void Gui::addGlobalKeyListener(KeyListener *const keyListener)
1193 {
1194  mKeyListeners.push_back(keyListener);
1195 }
1196 
1198 {
1199  mKeyListeners.remove(keyListener);
1200 }
1201 
1203 {
1204  Widget* sourceWidget = getMouseEventSource(
1205  mouseInput.getX(), mouseInput.getY());
1206 
1207  if (mFocusHandler->getDraggedWidget() != nullptr)
1208  sourceWidget = mFocusHandler->getDraggedWidget();
1209 
1210  if (sourceWidget != nullptr)
1211  {
1212  int sourceWidgetX = 0;
1213  int sourceWidgetY = 0;
1214 
1215  sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY);
1216  distributeMouseEvent(sourceWidget,
1218  mouseInput.getButton(),
1219  mouseInput.getX(),
1220  mouseInput.getY());
1221  }
1222 }
1223 
1225 {
1226  Widget* sourceWidget = getMouseEventSource(
1227  mouseInput.getX(), mouseInput.getY());
1228 
1229  if (mFocusHandler->getDraggedWidget() != nullptr)
1230  sourceWidget = mFocusHandler->getDraggedWidget();
1231 
1232  if (sourceWidget != nullptr)
1233  {
1234  int sourceWidgetX;
1235  int sourceWidgetY;
1236 
1237  sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY);
1238  distributeMouseEvent(sourceWidget,
1240  mouseInput.getButton(),
1241  mouseInput.getX(),
1242  mouseInput.getY());
1243  }
1244 }
1245 
1246 Widget* Gui::getWidgetAt(const int x, const int y) const
1247 {
1248  // If the widget's parent has no child then we have found the widget..
1249  Widget* parent = mTop;
1250  Widget* child = mTop;
1251  Widget* selectable = mTop;
1252 
1253  while (child != nullptr)
1254  {
1255  Widget *const swap = child;
1256  int parentX, parentY;
1257  parent->getAbsolutePosition(parentX, parentY);
1258  child = parent->getWidgetAt(x - parentX, y - parentY);
1259  parent = swap;
1260  if (parent->isSelectable())
1261  selectable = parent;
1262  }
1263 
1264  return selectable;
1265 }
1266 
1267 Widget* Gui::getMouseEventSource(const int x, const int y) const
1268 {
1269  Widget *const widget = getWidgetAt(x, y);
1270  if (widget == nullptr)
1271  return nullptr;
1272 
1273  if (mFocusHandler != nullptr &&
1274  mFocusHandler->getModalMouseInputFocused() != nullptr &&
1275  !widget->isModalMouseInputFocused())
1276  {
1278  }
1279 
1280  return widget;
1281 }
1282 
1284 {
1285  Widget* widget = mFocusHandler->getFocused();
1286 
1287  while (widget != nullptr &&
1288  widget->getInternalFocusHandler() != nullptr &&
1289  widget->getInternalFocusHandler()->getFocused() != nullptr)
1290  {
1291  widget = widget->getInternalFocusHandler()->getFocused();
1292  }
1293 
1294  return widget;
1295 }
1296 
1298 {
1299  Widget* parent = event.getSource();
1300  Widget* widget = parent;
1301 
1302  if (parent == nullptr)
1303  return;
1304  if (mFocusHandler->getModalFocused() != nullptr &&
1305  !widget->isModalFocused())
1306  {
1307  return;
1308  }
1309  if (mFocusHandler->getModalMouseInputFocused() != nullptr &&
1310  !widget->isModalMouseInputFocused())
1311  {
1312  return;
1313  }
1314 
1315  while (parent != nullptr)
1316  {
1317  // If the widget has been removed due to input
1318  // cancel the distribution.
1319  if (!Widget::widgetExists(widget))
1320  break;
1321 
1322  parent = widget->getParent();
1323 
1324  if (widget->isEnabled())
1325  {
1326  std::list<KeyListener*> keyListeners
1327  = widget->getKeyListeners();
1328 
1329  const KeyEventTypeT eventType = event.getType();
1330  // Send the event to all key listeners of the source widget.
1331  FOR_EACH (std::list<KeyListener*>::const_iterator,
1332  it, keyListeners)
1333  {
1334  switch (eventType)
1335  {
1336  case KeyEventType::PRESSED:
1337  (*it)->keyPressed(event);
1338  break;
1340  (*it)->keyReleased(event);
1341  break;
1342  default:
1343  break;
1344  }
1345  }
1346  }
1347 
1348  const Widget *const swap = widget;
1349  widget = parent;
1350  parent = swap->getParent();
1351 
1352  // If a non modal focused widget has been reach
1353  // and we have modal focus cancel the distribution.
1354  if ((widget != nullptr) &&
1355  (mFocusHandler->getModalFocused() != nullptr) &&
1356  !widget->isModalFocused())
1357  {
1358  break;
1359  }
1360  }
1361 }
1362 
1364 {
1365  BLOCK_START("Gui::distributeKeyEventToGlobalKeyListeners")
1366  const KeyEventTypeT eventType = event.getType();
1368  {
1369  switch (eventType)
1370  {
1371  case KeyEventType::PRESSED:
1372  (*it)->keyPressed(event);
1373  break;
1375  (*it)->keyReleased(event);
1376  break;
1377  default:
1378  break;
1379  }
1380 
1381  if (event.isConsumed())
1382  break;
1383  }
1384  BLOCK_END("Gui::distributeKeyEventToGlobalKeyListeners")
1385 }
1386 
1388 {
1389  BLOCK_START("Gui::handleModalMouseInputFocus")
1390  Widget *const lastModalWidget
1392  Widget *const modalWidget = mFocusHandler->getModalMouseInputFocused();
1393  if (lastModalWidget != modalWidget)
1394  {
1395  // Check if modal mouse input focus has been gained by a widget.
1396  if (lastModalWidget == nullptr)
1397  {
1400  }
1401  // Check if modal mouse input focus has been released.
1402  else
1403  {
1406  }
1407  }
1408  BLOCK_END("Gui::handleModalMouseInputFocus")
1409 }
1410 
1412 {
1413  BLOCK_START("Gui::handleModalFocus")
1414  Widget *const lastModalWidget
1416  Widget *const modalWidget = mFocusHandler->getModalFocused();
1417 
1418  if (lastModalWidget != modalWidget)
1419  {
1420  // Check if modal focus has been gained by a widget.
1421  if (lastModalWidget == nullptr)
1422  {
1425  }
1426  // Check if modal focus has been released.
1427  else
1428  {
1431  }
1432  }
1433  BLOCK_END("Gui::handleModalFocus")
1434 }
1435 
1437 {
1438  // Distribute an event to all widgets in the "widget with mouse" queue.
1439  while (!mWidgetWithMouseQueue.empty())
1440  {
1441  Widget *const widget = mWidgetWithMouseQueue.front();
1442 
1443  if (Widget::widgetExists(widget))
1444  {
1445  distributeMouseEvent(widget,
1448  mLastMouseX,
1449  mLastMouseY,
1450  true,
1451  true);
1452  }
1453 
1454  mWidgetWithMouseQueue.pop_front();
1455  }
1456 
1459 }
1460 
1462 {
1463  // Check all widgets below the mouse to see if they are
1464  // present in the "widget with mouse" queue. If a widget
1465  // is not then it should be added and an entered event should
1466  // be sent to it.
1468  Widget* parent = widget;
1469 
1470  while (parent != nullptr &&
1471  widget != nullptr)
1472  {
1473  parent = widget->getParent();
1474 
1475  // Check if the widget is present in the "widget with mouse" queue.
1476  bool widgetIsPresentInQueue = false;
1477  FOR_EACH (std::deque<Widget*>::const_iterator,
1478  iter, mWidgetWithMouseQueue)
1479  {
1480  if (*iter == widget)
1481  {
1482  widgetIsPresentInQueue = true;
1483  break;
1484  }
1485  }
1486 
1487  // Widget is not present, send an entered event and add
1488  // it to the "widget with mouse" queue.
1489  if (!widgetIsPresentInQueue && Widget::widgetExists(widget))
1490  {
1491  distributeMouseEvent(widget,
1494  mLastMouseX,
1495  mLastMouseY,
1496  false,
1497  true);
1498  mWidgetWithMouseQueue.push_front(widget);
1499  }
1500 
1501  const Widget *const swap = widget;
1502  widget = parent;
1503  parent = swap->getParent();
1504  }
1505 }
1506 
1508 {
1509  if (mLastMousePressTimeStamp == 0u)
1510  return 0;
1511  unsigned int ticks = SDL_GetTicks();
1512  if (ticks > mLastMousePressTimeStamp)
1513  return ticks - mLastMousePressTimeStamp;
1514  return mLastMousePressTimeStamp - ticks;
1515 }
void setSize(const int width, const int height)
Definition: widget.cpp:366
CursorT mCursorType
Definition: gui.h:503
void distributeKeyEvent(KeyEvent &event) const
Definition: gui.cpp:1297
Configuration branding
Color mForegroundColor
Definition: gui.h:512
void removeGlobalFocusListener(FocusListener *focusListener)
Definition: gui.cpp:1129
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
MouseEvent * createMouseEvent(Window *const widget)
Definition: gui.cpp:974
int mLastMouseY
Definition: gui.h:467
std::string getStringValue(const std::string &key) const
void slowLogic()
Definition: gui.cpp:322
void setLastWidgetPressed(Widget *const lastWidgetPressed)
MouseInput dequeueMouseInput()
Definition: sdlinput.cpp:118
void updateFonts()
Definition: gui.cpp:812
void logic()
Definition: gui.cpp:301
int getWidth() const
Definition: widget.h:220
void log1(const char *const log_text)
Definition: logger.cpp:222
Font * boldFont
Definition: gui.cpp:111
void videoResized() const
Definition: gui.cpp:535
Image * get(const size_type i) const
Definition: imageset.cpp:66
MouseButtonT getButton() const
Definition: mouseinput.h:128
bool isKeyQueueEmpty() const
Definition: sdlinput.h:123
Gui * gui
Definition: gui.cpp:110
#define MouseStateType
Definition: gui.h:99
Definition: font.h:88
static void cleanGlobalFont()
Definition: widget.h:649
const std::string & getText() const
Definition: dragdrop.h:231
virtual void draw(Graphics *const graphics)=0
WindowContainer * windowContainer
Graphics * getGraphics() const
Definition: gui.cpp:1177
void setDoubleClick(const bool b)
Definition: gui.h:198
FocusListenerList mFocusListeners
Definition: gui.h:511
FocusListenerList::iterator FocusListenerIterator
Definition: gui.h:510
void handleModalFocusReleased()
Definition: gui.cpp:1461
void clearFonts()
Definition: gui.cpp:371
Options options
Definition: settings.h:128
KeyEventType ::T KeyEventTypeT
Definition: keyeventtype.h:74
virtual void decRef()
Definition: resource.cpp:49
void clear()
Definition: dragdrop.h:182
static void advanceGradients()
Definition: palette.cpp:78
void removeGlobalKeyListener(KeyListener *const keyListener)
Definition: gui.cpp:1197
Widget * getLastWidgetWithModalFocus() const
int getTimeStamp() const
Definition: mouseinput.h:133
static void setGlobalFont(Font *const font)
Definition: widget.cpp:337
Definition: window.h:98
virtual bool isSelectable() const
Definition: widget.h:944
int mWidth
Definition: graphics.h:483
Image * getItemImage()
Definition: dragdrop.h:74
virtual void safeDraw(Graphics *const graphics)=0
#define BLOCK_START(name)
Definition: perfomance.h:78
ImageSet * mMouseCursors
Definition: gui.h:500
Color mForegroundColor2
Definition: gui.h:513
Configuration config
void simulateMouseMove()
Definition: sdlinput.cpp:361
virtual FocusHandler * getInternalFocusHandler()
Definition: widget.cpp:455
Widget * getModalMouseInputFocused() const
bool isPointInRect(const int x_, const int y_) const
Definition: rect.h:196
KeyEventTypeT getType() const
Definition: keyinput.h:122
Widget * mTop
Definition: gui.h:417
Definition: cursor.h:26
DragDrop dragDrop
void clear()
Definition: font.cpp:247
void handleModalFocusGained()
Definition: gui.cpp:1436
#define BLOCK_END(name)
Definition: perfomance.h:79
RenderType openGLMode
IPC * ipc
Definition: ipc.cpp:36
void addGlobalKeyListener(KeyListener *const keyListener)
Definition: gui.cpp:1192
int getIntValue(const std::string &key) const
void draw()
Definition: gui.cpp:469
virtual void popClipArea()
Definition: graphics.cpp:738
LangVect getLang()
Definition: langs.cpp:41
std::vector< std::string > StringVect
Definition: stringvector.h:28
#define delete2(var)
Definition: delete2.h:24
const Image *restrict const top
Widget * getMouseEventSource(const int x, const int y) const
Definition: gui.cpp:1267
Definition: gui.h:115
static void finalCleanup()
Definition: label.cpp:289
GuiConfigListener * mConfigListener
Definition: gui.h:488
MouseButtonT mLastMousePressButton
Definition: gui.h:452
void addGlobalFocusListener(FocusListener *focusListener)
Definition: gui.cpp:1124
void addListener(const std::string &key, ConfigListener *const listener)
bool isActionActive(const InputActionT index) const
Widget * getLastWidgetWithModalMouseInputFocus() const
void flush()
Definition: logger.cpp:365
int mMouseInactivityTimer
Definition: gui.h:502
void handleMouseMoved(const MouseInput &mouseInput)
Definition: gui.cpp:592
Logger * logger
Definition: logger.cpp:95
Graphics * mGraphics
Definition: gui.h:422
void postInit(Graphics *const graphics)
Definition: gui.cpp:150
MouseEventTypeT getType() const
Definition: mouseinput.h:118
void tabPrevious()
void handleMouseWheelMovedUp(const MouseInput &mouseInput)
Definition: gui.cpp:1224
void distributeGlobalFocusGainedEvent(const Event &focusEvent)
Definition: gui.cpp:1134
#define new
Definition: debug_new.h:147
Settings settings
Definition: settings.cpp:31
virtual void setAlpha(const float alpha)
Definition: image.cpp:285
virtual bool isModalFocused() const
Definition: widget.cpp:407
static ImageSet * getImageSetFromTheme(const std::string &path, const int w, const int h)
Definition: theme.cpp:659
bool getBoolValue(const std::string &key) const
bool hideCursor
Definition: options.h:100
bool handleInput()
Definition: gui.cpp:387
Font * mInfoParticleFont
Definition: gui.h:492
Widget * getDraggedWidget() const
Gui()
Definition: gui.cpp:113
virtual void requestFocus()
Definition: widget.cpp:203
void setInput(SDLInput *const input)
Definition: gui.cpp:1182
unsigned int mLastMousePressTimeStamp
Definition: gui.h:457
InputActionT getActionId() const
Definition: keyinput.h:142
void handleModalMouseInputFocus()
Definition: gui.cpp:1387
void handleMousePressed(const MouseInput &mouseInput)
Definition: gui.cpp:768
~Gui()
Definition: gui.cpp:267
int getRealY() const
Definition: mouseinput.h:169
int getX() const
Definition: mouseinput.h:148
void videoResized()
Definition: viewport.cpp:270
void loadFont(std::string filename, const int size, const int style)
Definition: font.cpp:218
void adjustAfterResize(const int oldScreenWidth, const int oldScreenHeight)
static void distributeWindowResizeEvent()
Definition: widget.cpp:354
virtual void logic()
Definition: widget.h:192
void drawString(Graphics *const graphics, Color col, const Color &col2, const std::string &text, const int x, const int y)
Definition: font.cpp:253
const Key & getKey() const
Definition: keyinput.h:132
void resetClickCount()
Definition: gui.cpp:968
FocusHandler * mFocusHandler
Definition: gui.h:432
Font * mNpcFont
Definition: gui.h:498
void flush()
Definition: ipc.cpp:189
std::deque< Widget * > mWidgetWithMouseQueue
Definition: gui.h:486
#define nullptr
Definition: localconsts.h:44
Graphics * mainGraphics
Definition: graphics.cpp:108
Widget * getKeyEventSource() const
Definition: gui.cpp:1283
const bool Opaque_false
Definition: opaque.h:29
bool isEnabled() const
Definition: widget.cpp:374
static void finalCleanup()
Definition: tab.cpp:482
int mHeight
Definition: graphics.h:484
volatile time_t cur_time
Definition: timer.cpp:57
Widget * getWidgetAt(const int x, const int y) const
Definition: gui.cpp:1246
virtual void getAbsolutePosition(int &x, int &y) const
Definition: widget.cpp:311
static uint8_t getMouseState(int &x, int &y)
Definition: gui.cpp:1153
const DyeColor * getColor(const std::string &name)
Definition: palettedb.cpp:108
int getRealX() const
Definition: mouseinput.h:166
bool isConsumed() const
KeyInput dequeueKeyInput()
Definition: sdlinput.cpp:107
const Rect & getDimension() const
Definition: widget.h:316
virtual bool isModalMouseInputFocused() const
Definition: widget.cpp:421
void handleMouseInput()
Definition: gui.cpp:1011
void setOpaque(Opaque opaque)
time_t mTime10
Definition: gui.h:515
KeyListenerList::iterator KeyListenerListIterator
Definition: gui.h:442
void handleMouseWheelMovedDown(const MouseInput &mouseInput)
Definition: gui.cpp:1202
int mClickCount
Definition: gui.h:473
void setTop(Widget *const top)
Definition: gui.cpp:1162
int getScale() const
Definition: graphics.h:365
void setGraphics(Graphics *const graphics)
Definition: gui.cpp:1172
static void getAbsolutePosition(Widget *widget, int &x, int &y)
Definition: gui.cpp:995
Widget * getParent() const
Definition: widget.h:201
void showCursor(const bool show)
Widget * getFocused() const
std::string getValue(const std::string &key, const std::string &deflt) const
Theme * theme
Definition: theme.cpp:61
void setFocusable(const bool focusable)
Definition: widget.cpp:191
bool isVisible() const
Definition: widget.h:377
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
SDLInput * mInput
Definition: gui.h:427
void removeDragged(const Widget *const widget)
Definition: gui.cpp:1144
Widget * getTop() const
Definition: gui.h:247
Definition: widget.h:97
void slowLogic(const int rnd)
Definition: font.cpp:318
void removeListeners(ConfigListener *const listener)
static bool widgetExists(const Widget *const widget)
Definition: widget.cpp:360
bool isMouseQueueEmpty() const
Definition: sdlinput.h:126
void setUseCustomCursor(const bool customCursor)
Definition: gui.cpp:553
int getWidth(const std::string &text) const
Definition: font.cpp:333
Widget * getModalFocused() const
Definition: event.h:77
bool processEvent(const MouseInput &mouseInput)
Font * mGuiFont
Definition: gui.h:490
MouseEventType ::T MouseEventTypeT
time_t mTime
Definition: gui.h:514
void handleMouseReleased(const MouseInput &mouseInput)
Definition: gui.cpp:1069
Definition: image.h:61
bool isFocusable() const
Definition: widget.cpp:198
int getHeight() const
Definition: widget.h:239
void setDraggedWidget(Widget *const draggedWidget)
virtual void pushClipArea(const Rect &area)
Definition: graphics.cpp:676
#define restrict
Definition: localconsts.h:176
float mMouseCursorAlpha
Definition: gui.h:501
Widget * getLastWidgetPressed() const
int getMousePressLength() const
Definition: gui.cpp:1507
#define CAST_SIZE
Definition: cast.h:33
int mLastMouseX
Definition: gui.h:462
SDL_Rect mBounds
Definition: image.h:210
void setLastWidgetWithModalFocus(Widget *const widget)
static void setWindowContainer(WindowContainer *const windowContainer)
Definition: window.cpp:298
Font * mHelpFont
Definition: gui.h:494
InputManager inputManager
TouchManager touchManager
bool cleanOrphans(const bool always)
const std::list< KeyListener * > & getKeyListeners() const A_CONST
Definition: widget.cpp:440
void log(const char *const log_text,...)
Definition: logger.cpp:243
virtual void setFocusHandler(FocusHandler *const focusHandler)
Definition: widget.cpp:237
bool mDoubleClick
Definition: gui.h:517
bool handleKeyInput()
Definition: gui.cpp:394
void distributeKeyEventToGlobalKeyListeners(KeyEvent &event)
Definition: gui.cpp:1363
MouseButton ::T MouseButtonT
Definition: mousebutton.h:77
int getY() const
Definition: mouseinput.h:158
#define isBatchDrawRenders(val)
Definition: renderers.h:30
SDLInput * guiInput
Definition: sdlinput.cpp:96
SDLInput * getInput() const
Definition: gui.cpp:1187
void setLastWidgetWithModalMouseInputFocus(Widget *const widget)
void handleModalFocus()
Definition: gui.cpp:1411
bool mouseFocused
Definition: settings.h:153
void distributeMouseEvent(Widget *const source, const MouseEventTypeT type, const MouseButtonT button, const int x, const int y, const bool force=false, const bool toSourceOnly=false)
Definition: gui.cpp:842
MouseButtonT mLastMouseDragButton
Definition: gui.h:480
bool mCustomCursor
Definition: gui.h:516
Font * mSecureFont
Definition: gui.h:496
virtual Widget * getWidgetAt(int x, int y)
Definition: widget.h:791
Viewport * viewport
Definition: viewport.cpp:35
const std::list< MouseListener * > & getMouseListeners() const A_CONST
Definition: widget.cpp:435
KeyListenerList mKeyListeners
Definition: gui.h:447