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-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/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  false,
756  false);
757  }
758  else
759  {
760  Widget *const sourceWidget = getMouseEventSource(mouseX, mouseY);
761  distributeMouseEvent(sourceWidget,
763  button,
764  mouseX,
765  mouseY,
766  false,
767  false);
768  }
770 }
771 
772 void Gui::handleMousePressed(const MouseInput &mouseInput)
773 {
774  const int x = mouseInput.getX();
775  const int y = mouseInput.getY();
776  const MouseButtonT button = mouseInput.getButton();
777  const unsigned int timeStamp = mouseInput.getTimeStamp();
778 
779  Widget *sourceWidget = getMouseEventSource(x, y);
780 
781  if (mFocusHandler->getDraggedWidget() != nullptr)
782  sourceWidget = mFocusHandler->getDraggedWidget();
783 
784  if (sourceWidget == nullptr)
785  return;
786  int sourceWidgetX;
787  int sourceWidgetY;
788  sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY);
789 
790  if (((mFocusHandler->getModalFocused() != nullptr)
791  && sourceWidget->isModalFocused())
792  || (mFocusHandler->getModalFocused() == nullptr))
793  {
794  sourceWidget->requestFocus();
795  }
796 
797  if (mDoubleClick &&
798  timeStamp - mLastMousePressTimeStamp < 250U &&
799  mLastMousePressButton == button)
800  {
801  mClickCount ++;
802  }
803  else
804  {
805  mClickCount = 1;
806  }
807 
808  distributeMouseEvent(sourceWidget,
810  button,
811  x,
812  y,
813  false,
814  false);
815  mFocusHandler->setLastWidgetPressed(sourceWidget);
816  mFocusHandler->setDraggedWidget(sourceWidget);
817  mLastMouseDragButton = button;
818  mLastMousePressButton = button;
819  mLastMousePressTimeStamp = timeStamp;
820 }
821 
823 {
824  const int fontSize = config.getIntValue("fontSize");
825  std::string fontFile = config.getValue("font", "");
826  if (fontFile.empty())
827  fontFile = branding.getStringValue("font");
828 
829  mGuiFont->loadFont(fontFile, fontSize, TTF_STYLE_NORMAL);
830 
831  fontFile = config.getValue("particleFont", "");
832  if (fontFile.empty())
833  fontFile = branding.getStringValue("particleFont");
834 
835  mInfoParticleFont->loadFont(fontFile, fontSize, TTF_STYLE_BOLD);
836 
837  fontFile = config.getValue("boldFont", "");
838  if (fontFile.empty())
839  fontFile = branding.getStringValue("boldFont");
840 
841  boldFont->loadFont(fontFile, fontSize, TTF_STYLE_NORMAL);
842 
843  const int npcFontSize = config.getIntValue("npcfontSize");
844 
845  fontFile = config.getValue("npcFont", "");
846  if (fontFile.empty())
847  fontFile = branding.getStringValue("npcFont");
848 
849  mNpcFont->loadFont(fontFile, npcFontSize, TTF_STYLE_NORMAL);
850 }
851 
853  const MouseEventTypeT type,
854  const MouseButtonT button,
855  const int x, const int y,
856  const bool force,
857  const bool toSourceOnly)
858 {
859  if ((source == nullptr) || (mFocusHandler == nullptr))
860  return;
861 
862  Widget *widget = source;
863 
864  if (!force)
865  {
866  if (mFocusHandler->getModalFocused() != nullptr
867  && !widget->isModalFocused())
868  {
869  return;
870  }
871  if (mFocusHandler->getModalMouseInputFocused() != nullptr
872  && !widget->isModalMouseInputFocused())
873  {
874  return;
875  }
876  }
877 
878  MouseEvent event(source,
879  type, button,
880  x, y, mClickCount);
881 
882  Widget* parent = source;
883  while (parent != nullptr)
884  {
885  // If the widget has been removed due to input
886  // cancel the distribution.
887  if (!Widget::widgetExists(widget))
888  break;
889 
890  parent = widget->getParent();
891 
892  if (widget->isEnabled() || force)
893  {
894  int widgetX;
895  int widgetY;
896  widget->getAbsolutePosition(widgetX, widgetY);
897 
898  event.setX(x - widgetX);
899  event.setY(y - widgetY);
900 
901  std::list<MouseListener*> mouseListeners
902  = widget->getMouseListeners();
903 
904  const MouseEventTypeT mouseType = event.getType();
905  // Send the event to all mouse listeners of the widget.
906  FOR_EACH (std::list<MouseListener*>::const_iterator,
907  it, mouseListeners)
908  {
909  switch (mouseType)
910  {
912  (*it)->mouseEntered(event);
913  break;
915  (*it)->mouseExited(event);
916  break;
918  (*it)->mouseMoved(event);
919  break;
921  (*it)->mousePressed(event);
922  break;
925  (*it)->mouseReleased(event);
926  break;
928  (*it)->mouseWheelMovedUp(event);
929  break;
931  (*it)->mouseWheelMovedDown(event);
932  break;
934  (*it)->mouseDragged(event);
935  break;
937  (*it)->mouseClicked(event);
938  break;
939  default:
940  break;
941  }
942  }
943 
944  if (toSourceOnly)
945  break;
946  }
947 
948  const Widget *const swap = widget;
949  widget = parent;
950  parent = swap->getParent();
951 
952 #ifndef DYECMD
953  if (type == MouseEventType::RELEASED)
954  dragDrop.clear();
955 #endif // DYECMD
956 
957  if ((widget == nullptr) || event.isConsumed())
958  break;
959 
960  // If a non modal focused widget has been reach
961  // and we have modal focus cancel the distribution.
962  if ((mFocusHandler->getModalFocused() != nullptr)
963  && !widget->isModalFocused())
964  {
965  break;
966  }
967 
968  // If a non modal mouse input focused widget has been reach
969  // and we have modal mouse input focus cancel the distribution.
970  if ((mFocusHandler->getModalMouseInputFocused() != nullptr)
971  && !widget->isModalMouseInputFocused())
972  {
973  break;
974  }
975  }
976 }
977 
979 {
980  mClickCount = 1;
982 }
983 
985 {
986  if ((viewport == nullptr) || (widget == nullptr))
987  return nullptr;
988 
989  int x = 0;
990  int y = 0;
991  int mouseX = 0;
992  int mouseY = 0;
993 
994  getAbsolutePosition(widget, x, y);
995  getMouseState(mouseX, mouseY);
996 
997  return new MouseEvent(widget,
1000  mouseX - x,
1001  mouseY - y,
1002  mClickCount);
1003 }
1004 
1006  int &restrict x,
1007  int &restrict y)
1008 {
1009  if (widget == nullptr)
1010  return;
1011  x = 0;
1012  y = 0;
1013  while (widget->getParent() != nullptr)
1014  {
1015  x += widget->getX();
1016  y += widget->getY();
1017  widget = widget->getParent();
1018  }
1019 }
1020 
1022 {
1023  BLOCK_START("Gui::handleMouseInput")
1024  while (!mInput->isMouseQueueEmpty())
1025  {
1026  const MouseInput mouseInput = guiInput->dequeueMouseInput();
1027 
1028  if (touchManager.processEvent(mouseInput))
1029  {
1030 #ifdef ANDROID
1031 #ifndef USE_SDL2
1032  SDL_WarpMouse(mLastMouseX, mLastMouseY,
1033  mLastMouseRealX, mLastMouseRealY);
1034 #endif // USE_SDL2
1035 #endif // ANDROID
1036 
1038  continue;
1039  }
1040 
1041  // Save the current mouse state. It will be needed if modal focus
1042  // changes or modal mouse input focus changes.
1043  mLastMouseX = mouseInput.getX();
1044  mLastMouseY = mouseInput.getY();
1045 #ifdef ANDROID
1046  mLastMouseRealX = mouseInput.getRealX();
1047  mLastMouseRealY = mouseInput.getRealY();
1048 #endif // ANDROID
1049 
1050  switch (mouseInput.getType())
1051  {
1053  handleMousePressed(mouseInput);
1054  break;
1056  handleMouseReleased(mouseInput);
1057  break;
1058  case MouseEventType::MOVED:
1059  handleMouseMoved(mouseInput);
1060  break;
1062  handleMouseWheelMovedDown(mouseInput);
1063  break;
1065  handleMouseWheelMovedUp(mouseInput);
1066  break;
1072  default:
1073  break;
1074  }
1075  }
1076  BLOCK_END("Gui::handleMouseInput")
1077 }
1078 
1079 void Gui::handleMouseReleased(const MouseInput &mouseInput)
1080 {
1081  Widget *sourceWidget = getMouseEventSource(
1082  mouseInput.getX(), mouseInput.getY());
1083 
1084  int sourceWidgetX;
1085  int sourceWidgetY;
1086  if (mFocusHandler->getDraggedWidget() != nullptr)
1087  {
1088  if (sourceWidget != mFocusHandler->getLastWidgetPressed())
1090 
1091  Widget *const oldWidget = sourceWidget;
1092  sourceWidget = mFocusHandler->getDraggedWidget();
1093  if ((oldWidget != nullptr) && oldWidget != sourceWidget)
1094  {
1095  oldWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY);
1096  distributeMouseEvent(oldWidget,
1098  mouseInput.getButton(),
1099  mouseInput.getX(),
1100  mouseInput.getY(),
1101  false,
1102  false);
1103  }
1104  }
1105 
1106  if (sourceWidget == nullptr)
1107  return;
1108  sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY);
1109  distributeMouseEvent(sourceWidget,
1111  mouseInput.getButton(),
1112  mouseInput.getX(),
1113  mouseInput.getY(),
1114  false,
1115  false);
1116 
1117  if (mouseInput.getButton() == mLastMousePressButton
1118  && mFocusHandler->getLastWidgetPressed() == sourceWidget)
1119  {
1120  distributeMouseEvent(sourceWidget,
1122  mouseInput.getButton(),
1123  mouseInput.getX(),
1124  mouseInput.getY(),
1125  false,
1126  false);
1127 
1129  }
1130  else
1131  {
1133  mClickCount = 0;
1134  }
1135 
1136  if (mFocusHandler->getDraggedWidget() != nullptr)
1137  mFocusHandler->setDraggedWidget(nullptr);
1138 }
1139 
1141 {
1142  mFocusListeners.push_back(focusListener);
1143 }
1144 
1146 {
1147  mFocusListeners.remove(focusListener);
1148 }
1149 
1151 {
1152  for (FocusListenerIterator iter = mFocusListeners.begin();
1153  iter != mFocusListeners.end();
1154  ++ iter)
1155  {
1156  (*iter)->focusGained(focusEvent);
1157  }
1158 }
1159 
1160 void Gui::removeDragged(const Widget *const widget)
1161 {
1162  if (mFocusHandler == nullptr)
1163  return;
1164 
1165  if (mFocusHandler->getDraggedWidget() == widget)
1166  mFocusHandler->setDraggedWidget(nullptr);
1167 }
1168 
1170 {
1171  const MouseStateType res = SDL_GetMouseState(&x, &y);
1172  const int scale = mainGraphics->getScale();
1173  x /= scale;
1174  y /= scale;
1175  return res;
1176 }
1177 
1178 void Gui::setTop(Widget *const top)
1179 {
1180  if (mTop != nullptr)
1181  mTop->setFocusHandler(nullptr);
1182  if (top != nullptr)
1184 
1185  mTop = top;
1186 }
1187 
1188 void Gui::setGraphics(Graphics *const graphics)
1189 {
1190  mGraphics = graphics;
1191 }
1192 
1194 {
1195  return mGraphics;
1196 }
1197 
1198 void Gui::setInput(SDLInput *const input)
1199 {
1200  mInput = input;
1201 }
1202 
1204 {
1205  return mInput;
1206 }
1207 
1208 void Gui::addGlobalKeyListener(KeyListener *const keyListener)
1209 {
1210  mKeyListeners.push_back(keyListener);
1211 }
1212 
1214 {
1215  mKeyListeners.remove(keyListener);
1216 }
1217 
1219 {
1220  Widget* sourceWidget = getMouseEventSource(
1221  mouseInput.getX(), mouseInput.getY());
1222 
1223  if (mFocusHandler->getDraggedWidget() != nullptr)
1224  sourceWidget = mFocusHandler->getDraggedWidget();
1225 
1226  if (sourceWidget != nullptr)
1227  {
1228  int sourceWidgetX = 0;
1229  int sourceWidgetY = 0;
1230 
1231  sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY);
1232  distributeMouseEvent(sourceWidget,
1234  mouseInput.getButton(),
1235  mouseInput.getX(),
1236  mouseInput.getY(),
1237  false,
1238  false);
1239  }
1240 }
1241 
1243 {
1244  Widget* sourceWidget = getMouseEventSource(
1245  mouseInput.getX(), mouseInput.getY());
1246 
1247  if (mFocusHandler->getDraggedWidget() != nullptr)
1248  sourceWidget = mFocusHandler->getDraggedWidget();
1249 
1250  if (sourceWidget != nullptr)
1251  {
1252  int sourceWidgetX;
1253  int sourceWidgetY;
1254 
1255  sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY);
1256  distributeMouseEvent(sourceWidget,
1258  mouseInput.getButton(),
1259  mouseInput.getX(),
1260  mouseInput.getY(),
1261  false,
1262  false);
1263  }
1264 }
1265 
1266 Widget* Gui::getWidgetAt(const int x, const int y) const
1267 {
1268  // If the widget's parent has no child then we have found the widget..
1269  Widget* parent = mTop;
1270  Widget* child = mTop;
1271  Widget* selectable = mTop;
1272 
1273  while (child != nullptr)
1274  {
1275  Widget *const swap = child;
1276  int parentX, parentY;
1277  parent->getAbsolutePosition(parentX, parentY);
1278  child = parent->getWidgetAt(x - parentX, y - parentY);
1279  parent = swap;
1280  if (parent->isSelectable())
1281  selectable = parent;
1282  }
1283 
1284  return selectable;
1285 }
1286 
1287 Widget* Gui::getMouseEventSource(const int x, const int y) const
1288 {
1289  Widget *const widget = getWidgetAt(x, y);
1290  if (widget == nullptr)
1291  return nullptr;
1292 
1293  if (mFocusHandler != nullptr &&
1294  mFocusHandler->getModalMouseInputFocused() != nullptr &&
1295  !widget->isModalMouseInputFocused())
1296  {
1298  }
1299 
1300  return widget;
1301 }
1302 
1304 {
1305  Widget* widget = mFocusHandler->getFocused();
1306 
1307  while (widget != nullptr &&
1308  widget->getInternalFocusHandler() != nullptr &&
1309  widget->getInternalFocusHandler()->getFocused() != nullptr)
1310  {
1311  widget = widget->getInternalFocusHandler()->getFocused();
1312  }
1313 
1314  return widget;
1315 }
1316 
1318 {
1319  Widget* parent = event.getSource();
1320  Widget* widget = parent;
1321 
1322  if (parent == nullptr)
1323  return;
1324  if (mFocusHandler->getModalFocused() != nullptr &&
1325  !widget->isModalFocused())
1326  {
1327  return;
1328  }
1329  if (mFocusHandler->getModalMouseInputFocused() != nullptr &&
1330  !widget->isModalMouseInputFocused())
1331  {
1332  return;
1333  }
1334 
1335  while (parent != nullptr)
1336  {
1337  // If the widget has been removed due to input
1338  // cancel the distribution.
1339  if (!Widget::widgetExists(widget))
1340  break;
1341 
1342  parent = widget->getParent();
1343 
1344  if (widget->isEnabled())
1345  {
1346  std::list<KeyListener*> keyListeners
1347  = widget->getKeyListeners();
1348 
1349  const KeyEventTypeT eventType = event.getType();
1350  // Send the event to all key listeners of the source widget.
1351  FOR_EACH (std::list<KeyListener*>::const_iterator,
1352  it, keyListeners)
1353  {
1354  switch (eventType)
1355  {
1356  case KeyEventType::PRESSED:
1357  (*it)->keyPressed(event);
1358  break;
1360  (*it)->keyReleased(event);
1361  break;
1362  default:
1363  break;
1364  }
1365  }
1366  }
1367 
1368  const Widget *const swap = widget;
1369  widget = parent;
1370  parent = swap->getParent();
1371 
1372  // If a non modal focused widget has been reach
1373  // and we have modal focus cancel the distribution.
1374  if ((widget != nullptr) &&
1375  (mFocusHandler->getModalFocused() != nullptr) &&
1376  !widget->isModalFocused())
1377  {
1378  break;
1379  }
1380  }
1381 }
1382 
1384 {
1385  BLOCK_START("Gui::distributeKeyEventToGlobalKeyListeners")
1386  const KeyEventTypeT eventType = event.getType();
1388  {
1389  switch (eventType)
1390  {
1391  case KeyEventType::PRESSED:
1392  (*it)->keyPressed(event);
1393  break;
1395  (*it)->keyReleased(event);
1396  break;
1397  default:
1398  break;
1399  }
1400 
1401  if (event.isConsumed())
1402  break;
1403  }
1404  BLOCK_END("Gui::distributeKeyEventToGlobalKeyListeners")
1405 }
1406 
1408 {
1409  BLOCK_START("Gui::handleModalMouseInputFocus")
1410  Widget *const lastModalWidget
1412  Widget *const modalWidget = mFocusHandler->getModalMouseInputFocused();
1413  if (lastModalWidget != modalWidget)
1414  {
1415  // Check if modal mouse input focus has been gained by a widget.
1416  if (lastModalWidget == nullptr)
1417  {
1420  }
1421  // Check if modal mouse input focus has been released.
1422  else
1423  {
1426  }
1427  }
1428  BLOCK_END("Gui::handleModalMouseInputFocus")
1429 }
1430 
1432 {
1433  BLOCK_START("Gui::handleModalFocus")
1434  Widget *const lastModalWidget
1436  Widget *const modalWidget = mFocusHandler->getModalFocused();
1437 
1438  if (lastModalWidget != modalWidget)
1439  {
1440  // Check if modal focus has been gained by a widget.
1441  if (lastModalWidget == nullptr)
1442  {
1445  }
1446  // Check if modal focus has been released.
1447  else
1448  {
1451  }
1452  }
1453  BLOCK_END("Gui::handleModalFocus")
1454 }
1455 
1457 {
1458  // Distribute an event to all widgets in the "widget with mouse" queue.
1459  while (!mWidgetWithMouseQueue.empty())
1460  {
1461  Widget *const widget = mWidgetWithMouseQueue.front();
1462 
1463  if (Widget::widgetExists(widget))
1464  {
1465  distributeMouseEvent(widget,
1468  mLastMouseX,
1469  mLastMouseY,
1470  true,
1471  true);
1472  }
1473 
1474  mWidgetWithMouseQueue.pop_front();
1475  }
1476 
1479 }
1480 
1482 {
1483  // Check all widgets below the mouse to see if they are
1484  // present in the "widget with mouse" queue. If a widget
1485  // is not then it should be added and an entered event should
1486  // be sent to it.
1488  Widget* parent = widget;
1489 
1490  while (parent != nullptr &&
1491  widget != nullptr)
1492  {
1493  parent = widget->getParent();
1494 
1495  // Check if the widget is present in the "widget with mouse" queue.
1496  bool widgetIsPresentInQueue = false;
1497  FOR_EACH (std::deque<Widget*>::const_iterator,
1498  iter, mWidgetWithMouseQueue)
1499  {
1500  if (*iter == widget)
1501  {
1502  widgetIsPresentInQueue = true;
1503  break;
1504  }
1505  }
1506 
1507  // Widget is not present, send an entered event and add
1508  // it to the "widget with mouse" queue.
1509  if (!widgetIsPresentInQueue && Widget::widgetExists(widget))
1510  {
1511  distributeMouseEvent(widget,
1514  mLastMouseX,
1515  mLastMouseY,
1516  false,
1517  true);
1518  mWidgetWithMouseQueue.push_front(widget);
1519  }
1520 
1521  const Widget *const swap = widget;
1522  widget = parent;
1523  parent = swap->getParent();
1524  }
1525 }
1526 
1528 {
1529  if (mLastMousePressTimeStamp == 0u)
1530  return 0;
1531  unsigned int ticks = SDL_GetTicks();
1532  if (ticks > mLastMousePressTimeStamp)
1533  return ticks - mLastMousePressTimeStamp;
1534  return mLastMousePressTimeStamp - ticks;
1535 }
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:1317
Configuration branding
Color mForegroundColor
Definition: gui.h:512
void removeGlobalFocusListener(FocusListener *focusListener)
Definition: gui.cpp:1145
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
MouseEvent * createMouseEvent(Window *const widget)
Definition: gui.cpp:984
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:822
void logic()
Definition: gui.cpp:301
int getWidth() const
Definition: widget.h:220
void log1(const char *const log_text)
Definition: logger.cpp:233
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:1193
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:1481
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:1213
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:1456
#define BLOCK_END(name)
Definition: perfomance.h:79
RenderType openGLMode
IPC * ipc
Definition: ipc.cpp:36
void addGlobalKeyListener(KeyListener *const keyListener)
Definition: gui.cpp:1208
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:1287
Definition: gui.h:115
static void finalCleanup()
Definition: label.cpp:294
GuiConfigListener * mConfigListener
Definition: gui.h:488
MouseButtonT mLastMousePressButton
Definition: gui.h:452
void addGlobalFocusListener(FocusListener *focusListener)
Definition: gui.cpp:1140
void addListener(const std::string &key, ConfigListener *const listener)
bool isActionActive(const InputActionT index) const
Widget * getLastWidgetWithModalMouseInputFocus() const
void flush()
Definition: logger.cpp:413
int mMouseInactivityTimer
Definition: gui.h:502
void handleMouseMoved(const MouseInput &mouseInput)
Definition: gui.cpp:592
Logger * logger
Definition: logger.cpp:88
void distributeMouseEvent(Widget *const source, const MouseEventTypeT type, const MouseButtonT button, const int x, const int y, const bool force, const bool toSourceOnly)
Definition: gui.cpp:852
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:1242
void distributeGlobalFocusGainedEvent(const Event &focusEvent)
Definition: gui.cpp:1150
#define new
Definition: debug_new.h:147
Settings settings
Definition: settings.cpp:31
virtual void setAlpha(const float alpha)
Definition: image.cpp:286
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:1198
unsigned int mLastMousePressTimeStamp
Definition: gui.h:457
InputActionT getActionId() const
Definition: keyinput.h:142
void handleModalMouseInputFocus()
Definition: gui.cpp:1407
void handleMousePressed(const MouseInput &mouseInput)
Definition: gui.cpp:772
~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:978
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:1303
const bool Opaque_false
Definition: opaque.h:29
bool isEnabled() const
Definition: widget.cpp:374
static void finalCleanup()
Definition: tab.cpp:487
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:1266
virtual void getAbsolutePosition(int &x, int &y) const
Definition: widget.cpp:311
static uint8_t getMouseState(int &x, int &y)
Definition: gui.cpp:1169
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:1021
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:1218
int mClickCount
Definition: gui.h:473
void setTop(Widget *const top)
Definition: gui.cpp:1178
int getScale() const
Definition: graphics.h:365
void setGraphics(Graphics *const graphics)
Definition: gui.cpp:1188
static void getAbsolutePosition(Widget *widget, int &x, int &y)
Definition: gui.cpp:1005
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:1160
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:1079
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:156
float mMouseCursorAlpha
Definition: gui.h:501
Widget * getLastWidgetPressed() const
int getMousePressLength() const
Definition: gui.cpp:1527
#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:305
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:264
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:1383
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:1203
void setLastWidgetWithModalMouseInputFocus(Widget *const widget)
void handleModalFocus()
Definition: gui.cpp:1431
bool mouseFocused
Definition: settings.h:153
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