2017-07-13 10:26:03 +02:00
|
|
|
/*
|
|
|
|
* CGuiHandler.cpp, part of VCMI engine
|
|
|
|
*
|
|
|
|
* Authors: listed in file AUTHORS in main folder
|
|
|
|
*
|
|
|
|
* License: GNU General Public License v2.0 or later
|
|
|
|
* Full text of license available in license.txt file, in main folder
|
|
|
|
*
|
|
|
|
*/
|
2011-12-17 21:59:59 +03:00
|
|
|
#include "StdInc.h"
|
|
|
|
#include "CGuiHandler.h"
|
2015-06-22 20:53:47 +02:00
|
|
|
#include "../lib/CondSh.h"
|
2011-12-17 21:59:59 +03:00
|
|
|
|
|
|
|
#include "CIntObject.h"
|
2023-01-05 19:34:37 +02:00
|
|
|
#include "CursorHandler.h"
|
2023-04-27 19:21:06 +02:00
|
|
|
#include "ShortcutHandler.h"
|
2023-05-12 23:15:48 +02:00
|
|
|
#include "FramerateManager.h"
|
2023-05-16 14:10:26 +02:00
|
|
|
#include "WindowHandler.h"
|
2023-05-18 12:31:26 +02:00
|
|
|
#include "EventDispatcher.h"
|
2023-05-18 19:32:29 +02:00
|
|
|
#include "../eventsSDL/InputHandler.h"
|
2014-07-13 20:53:37 +03:00
|
|
|
|
|
|
|
#include "../CGameInfo.h"
|
2023-02-02 21:15:13 +02:00
|
|
|
#include "../render/Colors.h"
|
2023-07-31 18:50:55 +02:00
|
|
|
#include "../render/Graphics.h"
|
|
|
|
#include "../render/IFont.h"
|
|
|
|
#include "../render/EFont.h"
|
2023-05-08 12:22:01 +02:00
|
|
|
#include "../renderSDL/ScreenHandler.h"
|
2013-04-04 17:58:54 +03:00
|
|
|
#include "../CMT.h"
|
2014-05-23 22:39:10 +03:00
|
|
|
#include "../CPlayerInterface.h"
|
2022-12-09 13:38:46 +02:00
|
|
|
#include "../battle/BattleInterface.h"
|
2011-12-17 21:59:59 +03:00
|
|
|
|
2023-02-01 20:42:06 +02:00
|
|
|
#include "../../lib/CThreadHelper.h"
|
|
|
|
#include "../../lib/CConfigHandler.h"
|
|
|
|
|
2023-01-30 00:12:43 +02:00
|
|
|
#include <SDL_render.h>
|
2023-02-02 19:10:29 +02:00
|
|
|
|
2023-04-30 00:38:28 +02:00
|
|
|
CGuiHandler GH;
|
|
|
|
|
2023-08-20 22:45:41 +02:00
|
|
|
static thread_local bool inGuiThread = false;
|
2012-04-08 04:15:18 +03:00
|
|
|
|
2016-10-22 16:22:00 +02:00
|
|
|
SObjectConstruction::SObjectConstruction(CIntObject *obj)
|
2011-12-17 21:59:59 +03:00
|
|
|
:myObj(obj)
|
|
|
|
{
|
|
|
|
GH.createdObj.push_front(obj);
|
|
|
|
GH.captureChildren = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
SObjectConstruction::~SObjectConstruction()
|
|
|
|
{
|
|
|
|
assert(GH.createdObj.size());
|
|
|
|
assert(GH.createdObj.front() == myObj);
|
|
|
|
GH.createdObj.pop_front();
|
|
|
|
GH.captureChildren = GH.createdObj.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
SSetCaptureState::SSetCaptureState(bool allow, ui8 actions)
|
|
|
|
{
|
|
|
|
previousCapture = GH.captureChildren;
|
|
|
|
GH.captureChildren = false;
|
|
|
|
prevActions = GH.defActionsDef;
|
|
|
|
GH.defActionsDef = actions;
|
|
|
|
}
|
|
|
|
|
|
|
|
SSetCaptureState::~SSetCaptureState()
|
|
|
|
{
|
|
|
|
GH.captureChildren = previousCapture;
|
|
|
|
GH.defActionsDef = prevActions;
|
|
|
|
}
|
|
|
|
|
2023-01-16 12:26:43 +02:00
|
|
|
void CGuiHandler::init()
|
|
|
|
{
|
2023-08-20 22:45:41 +02:00
|
|
|
inGuiThread = true;
|
|
|
|
|
2023-05-18 19:32:29 +02:00
|
|
|
inputHandlerInstance = std::make_unique<InputHandler>();
|
2023-05-18 12:31:26 +02:00
|
|
|
eventDispatcherInstance = std::make_unique<EventDispatcher>();
|
2023-05-16 14:10:26 +02:00
|
|
|
windowHandlerInstance = std::make_unique<WindowHandler>();
|
2023-05-08 12:22:01 +02:00
|
|
|
screenHandlerInstance = std::make_unique<ScreenHandler>();
|
2023-04-28 13:22:03 +02:00
|
|
|
shortcutsHandlerInstance = std::make_unique<ShortcutHandler>();
|
2023-05-12 23:15:48 +02:00
|
|
|
framerateManagerInstance = std::make_unique<FramerateManager>(settings["video"]["targetfps"].Integer());
|
2023-01-16 12:26:43 +02:00
|
|
|
}
|
|
|
|
|
2011-12-17 21:59:59 +03:00
|
|
|
void CGuiHandler::handleEvents()
|
|
|
|
{
|
2023-05-18 19:32:29 +02:00
|
|
|
events().dispatchTimer(framerate().getElapsedMilliseconds());
|
2023-05-18 01:09:42 +02:00
|
|
|
|
2016-11-27 16:48:18 +02:00
|
|
|
//player interface may want special event handling
|
2014-06-18 13:31:11 +03:00
|
|
|
if(nullptr != LOCPLINT && LOCPLINT->capturedAllEvents())
|
|
|
|
return;
|
2016-11-27 16:48:18 +02:00
|
|
|
|
2023-05-18 19:32:29 +02:00
|
|
|
input().processEvents();
|
2023-01-16 12:26:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CGuiHandler::fakeMouseMove()
|
|
|
|
{
|
2023-06-26 20:51:10 +02:00
|
|
|
dispatchMainThread([](){
|
2023-08-10 20:19:12 +02:00
|
|
|
assert(CPlayerInterface::pim);
|
|
|
|
boost::unique_lock lock(*CPlayerInterface::pim);
|
2023-06-26 20:51:10 +02:00
|
|
|
GH.events().dispatchMouseMoved(Point(0, 0), GH.getCursorPosition());
|
|
|
|
});
|
2023-01-16 12:26:43 +02:00
|
|
|
}
|
|
|
|
|
2023-02-02 16:15:39 +02:00
|
|
|
void CGuiHandler::startTextInput(const Rect & whereInput)
|
|
|
|
{
|
2023-05-18 19:32:29 +02:00
|
|
|
input().startTextInput(whereInput);
|
2023-02-02 16:15:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CGuiHandler::stopTextInput()
|
|
|
|
{
|
2023-05-18 19:32:29 +02:00
|
|
|
input().stopTextInput();
|
2023-05-17 16:16:09 +02:00
|
|
|
}
|
2017-06-07 20:16:18 +02:00
|
|
|
|
2014-06-01 18:31:37 +03:00
|
|
|
void CGuiHandler::renderFrame()
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
2015-08-22 15:47:40 +02:00
|
|
|
{
|
2023-08-20 23:54:40 +02:00
|
|
|
boost::recursive_mutex::scoped_lock un(*CPlayerInterface::pim);
|
2015-06-22 20:53:47 +02:00
|
|
|
|
|
|
|
if(nullptr != curInt)
|
|
|
|
curInt->update();
|
2016-11-27 16:48:18 +02:00
|
|
|
|
2023-03-05 21:06:52 +02:00
|
|
|
if(settings["video"]["showfps"].Bool())
|
2016-11-27 16:48:18 +02:00
|
|
|
drawFPSCounter();
|
|
|
|
|
2018-07-25 00:36:48 +02:00
|
|
|
SDL_UpdateTexture(screenTexture, nullptr, screen->pixels, screen->pitch);
|
2014-07-03 21:05:59 +03:00
|
|
|
|
2022-06-13 15:11:53 +02:00
|
|
|
SDL_RenderClear(mainRenderer);
|
2016-10-28 12:39:16 +02:00
|
|
|
SDL_RenderCopy(mainRenderer, screenTexture, nullptr, nullptr);
|
2014-07-03 21:05:59 +03:00
|
|
|
|
2018-07-25 00:36:48 +02:00
|
|
|
CCS->curh->render();
|
|
|
|
|
2016-11-27 16:48:18 +02:00
|
|
|
SDL_RenderPresent(mainRenderer);
|
2018-07-25 00:36:48 +02:00
|
|
|
|
2023-05-16 14:10:26 +02:00
|
|
|
windows().onFrameRendered();
|
2016-11-27 16:48:18 +02:00
|
|
|
}
|
2022-06-05 15:20:01 +02:00
|
|
|
|
2023-05-18 19:32:29 +02:00
|
|
|
framerate().framerateDelay(); // holds a constant FPS
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
CGuiHandler::CGuiHandler()
|
2023-05-18 01:09:42 +02:00
|
|
|
: defActionsDef(0)
|
2023-02-02 15:49:23 +02:00
|
|
|
, captureChildren(false)
|
|
|
|
, curInt(nullptr)
|
2023-05-16 17:34:23 +02:00
|
|
|
, fakeStatusBar(std::make_shared<EmptyStatusBar>())
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2023-08-20 23:54:40 +02:00
|
|
|
CGuiHandler::~CGuiHandler() = default;
|
2011-12-17 21:59:59 +03:00
|
|
|
|
2023-05-18 19:32:29 +02:00
|
|
|
ShortcutHandler & CGuiHandler::shortcuts()
|
2023-04-27 19:21:06 +02:00
|
|
|
{
|
2023-05-13 00:12:11 +02:00
|
|
|
assert(shortcutsHandlerInstance);
|
2023-04-28 13:22:03 +02:00
|
|
|
return *shortcutsHandlerInstance;
|
2023-04-27 19:21:06 +02:00
|
|
|
}
|
2023-02-02 16:15:39 +02:00
|
|
|
|
2023-05-18 19:32:29 +02:00
|
|
|
FramerateManager & CGuiHandler::framerate()
|
2023-05-12 23:15:48 +02:00
|
|
|
{
|
2023-05-13 00:12:11 +02:00
|
|
|
assert(framerateManagerInstance);
|
2023-05-12 23:15:48 +02:00
|
|
|
return *framerateManagerInstance;
|
|
|
|
}
|
|
|
|
|
2023-02-02 16:15:39 +02:00
|
|
|
bool CGuiHandler::isKeyboardCtrlDown() const
|
|
|
|
{
|
2023-05-18 19:32:29 +02:00
|
|
|
return inputHandlerInstance->isKeyboardCtrlDown();
|
2023-02-02 16:15:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CGuiHandler::isKeyboardAltDown() const
|
|
|
|
{
|
2023-05-18 19:32:29 +02:00
|
|
|
return inputHandlerInstance->isKeyboardAltDown();
|
2023-02-02 16:15:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CGuiHandler::isKeyboardShiftDown() const
|
|
|
|
{
|
2023-05-18 19:32:29 +02:00
|
|
|
return inputHandlerInstance->isKeyboardShiftDown();
|
2023-02-02 16:15:39 +02:00
|
|
|
}
|
|
|
|
|
2023-01-27 00:27:06 +02:00
|
|
|
const Point & CGuiHandler::getCursorPosition() const
|
|
|
|
{
|
2023-05-18 19:32:29 +02:00
|
|
|
return inputHandlerInstance->getCursorPosition();
|
2023-01-27 00:27:06 +02:00
|
|
|
}
|
|
|
|
|
2023-02-03 18:23:53 +02:00
|
|
|
Point CGuiHandler::screenDimensions() const
|
|
|
|
{
|
2023-02-03 18:55:25 +02:00
|
|
|
return Point(screen->w, screen->h);
|
2023-02-03 18:23:53 +02:00
|
|
|
}
|
|
|
|
|
2011-12-17 21:59:59 +03:00
|
|
|
void CGuiHandler::drawFPSCounter()
|
|
|
|
{
|
2023-08-28 13:09:15 +02:00
|
|
|
static SDL_Rect overlay = { 0, 0, 24, 24};
|
2023-01-30 19:55:32 +02:00
|
|
|
uint32_t black = SDL_MapRGB(screen->format, 10, 10, 10);
|
2011-12-17 21:59:59 +03:00
|
|
|
SDL_FillRect(screen, &overlay, black);
|
2023-05-18 19:32:29 +02:00
|
|
|
std::string fps = std::to_string(framerate().getFramerate());
|
2023-08-28 13:09:15 +02:00
|
|
|
graphics->fonts[FONT_BIG]->renderTextLeft(screen, fps, Colors::YELLOW, Point(4, 2));
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
2012-04-08 04:15:18 +03:00
|
|
|
bool CGuiHandler::amIGuiThread()
|
|
|
|
{
|
2023-08-20 22:45:41 +02:00
|
|
|
return inGuiThread;
|
2012-04-08 04:15:18 +03:00
|
|
|
}
|
2011-12-22 16:05:19 +03:00
|
|
|
|
2023-06-26 20:51:10 +02:00
|
|
|
void CGuiHandler::dispatchMainThread(const std::function<void()> & functor)
|
2023-02-02 18:35:01 +02:00
|
|
|
{
|
2023-06-26 20:51:10 +02:00
|
|
|
inputHandlerInstance->dispatchMainThread(functor);
|
2012-09-11 17:25:19 +03:00
|
|
|
}
|
|
|
|
|
2023-05-08 12:22:01 +02:00
|
|
|
IScreenHandler & CGuiHandler::screenHandler()
|
2023-04-30 00:03:50 +02:00
|
|
|
{
|
2023-05-08 12:22:01 +02:00
|
|
|
return *screenHandlerInstance;
|
2023-04-30 00:03:50 +02:00
|
|
|
}
|
|
|
|
|
2023-05-18 19:32:29 +02:00
|
|
|
EventDispatcher & CGuiHandler::events()
|
2023-05-17 22:22:45 +02:00
|
|
|
{
|
|
|
|
return *eventDispatcherInstance;
|
|
|
|
}
|
|
|
|
|
2023-05-18 19:32:29 +02:00
|
|
|
InputHandler & CGuiHandler::input()
|
|
|
|
{
|
|
|
|
return *inputHandlerInstance;
|
|
|
|
}
|
|
|
|
|
2023-05-16 14:10:26 +02:00
|
|
|
WindowHandler & CGuiHandler::windows()
|
2023-05-04 21:33:25 +02:00
|
|
|
{
|
2023-05-16 14:10:26 +02:00
|
|
|
assert(windowHandlerInstance);
|
|
|
|
return *windowHandlerInstance;
|
|
|
|
}
|
2023-05-04 21:33:25 +02:00
|
|
|
|
2023-05-16 17:34:23 +02:00
|
|
|
std::shared_ptr<IStatusBar> CGuiHandler::statusbar()
|
|
|
|
{
|
|
|
|
auto locked = currentStatusBar.lock();
|
|
|
|
|
|
|
|
if (!locked)
|
|
|
|
return fakeStatusBar;
|
|
|
|
|
|
|
|
return locked;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CGuiHandler::setStatusbar(std::shared_ptr<IStatusBar> newStatusBar)
|
|
|
|
{
|
|
|
|
currentStatusBar = newStatusBar;
|
|
|
|
}
|
|
|
|
|
2023-05-16 14:10:26 +02:00
|
|
|
void CGuiHandler::onScreenResize()
|
|
|
|
{
|
|
|
|
screenHandler().onScreenResize();
|
|
|
|
windows().onScreenResize();
|
2023-05-04 21:33:25 +02:00
|
|
|
}
|