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