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