2017-07-13 10:26:03 +02:00
|
|
|
/*
|
|
|
|
* CIntObject.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
|
|
|
|
*
|
|
|
|
*/
|
2012-06-13 17:11:18 +03:00
|
|
|
#include "StdInc.h"
|
2011-12-17 21:59:59 +03:00
|
|
|
#include "CIntObject.h"
|
2014-07-13 20:53:37 +03:00
|
|
|
|
2011-12-17 21:59:59 +03:00
|
|
|
#include "CGuiHandler.h"
|
2023-05-16 14:10:26 +02:00
|
|
|
#include "WindowHandler.h"
|
2023-04-27 19:21:06 +02:00
|
|
|
#include "Shortcut.h"
|
2023-02-01 20:42:06 +02:00
|
|
|
#include "../renderSDL/SDL_Extensions.h"
|
|
|
|
#include "../windows/CMessage.h"
|
2023-02-03 18:23:53 +02:00
|
|
|
#include "../CMT.h"
|
2011-12-17 21:59:59 +03:00
|
|
|
|
2012-06-02 18:16:54 +03:00
|
|
|
CIntObject::CIntObject(int used_, Point pos_):
|
|
|
|
parent_m(nullptr),
|
|
|
|
parent(parent_m),
|
2023-05-17 22:22:45 +02:00
|
|
|
type(0)
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
2023-05-17 22:22:45 +02:00
|
|
|
captureAllKeys = false;
|
2012-06-02 18:16:54 +03:00
|
|
|
used = used_;
|
2011-12-17 21:59:59 +03:00
|
|
|
|
|
|
|
recActions = defActions = GH.defActionsDef;
|
|
|
|
|
2012-06-02 18:16:54 +03:00
|
|
|
pos.x = pos_.x;
|
|
|
|
pos.y = pos_.y;
|
2011-12-17 21:59:59 +03:00
|
|
|
pos.w = 0;
|
|
|
|
pos.h = 0;
|
|
|
|
|
|
|
|
if(GH.captureChildren)
|
2012-06-02 18:16:54 +03:00
|
|
|
GH.createdObj.front()->addChild(this, true);
|
|
|
|
}
|
2011-12-17 21:59:59 +03:00
|
|
|
|
2018-04-07 13:34:11 +02:00
|
|
|
CIntObject::~CIntObject()
|
|
|
|
{
|
2023-05-17 22:22:45 +02:00
|
|
|
if(isActive())
|
2018-04-07 13:34:11 +02:00
|
|
|
deactivate();
|
|
|
|
|
|
|
|
while(!children.empty())
|
|
|
|
{
|
|
|
|
if((defActions & DISPOSE) && (children.front()->recActions & DISPOSE))
|
|
|
|
delete children.front();
|
|
|
|
else
|
|
|
|
removeChild(children.front());
|
|
|
|
}
|
|
|
|
|
|
|
|
if(parent_m)
|
|
|
|
parent_m->removeChild(this);
|
|
|
|
}
|
|
|
|
|
2011-12-22 16:05:19 +03:00
|
|
|
void CIntObject::show(SDL_Surface * to)
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
|
|
|
if(defActions & UPDATE)
|
2013-06-29 16:05:48 +03:00
|
|
|
for(auto & elem : children)
|
|
|
|
if(elem->recActions & UPDATE)
|
|
|
|
elem->show(to);
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
2011-12-22 16:05:19 +03:00
|
|
|
void CIntObject::showAll(SDL_Surface * to)
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
|
|
|
if(defActions & SHOWALL)
|
|
|
|
{
|
2013-06-29 16:05:48 +03:00
|
|
|
for(auto & elem : children)
|
|
|
|
if(elem->recActions & SHOWALL)
|
|
|
|
elem->showAll(to);
|
2012-06-13 16:04:06 +03:00
|
|
|
}
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void CIntObject::activate()
|
|
|
|
{
|
2023-05-17 22:22:45 +02:00
|
|
|
if (isActive())
|
|
|
|
return;
|
2012-06-02 18:16:54 +03:00
|
|
|
|
2023-05-17 22:22:45 +02:00
|
|
|
activateEvents(used | GENERAL);
|
|
|
|
assert(isActive());
|
2011-12-17 21:59:59 +03:00
|
|
|
|
|
|
|
if(defActions & ACTIVATE)
|
2013-06-29 16:05:48 +03:00
|
|
|
for(auto & elem : children)
|
|
|
|
if(elem->recActions & ACTIVATE)
|
|
|
|
elem->activate();
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void CIntObject::deactivate()
|
|
|
|
{
|
2023-05-17 22:22:45 +02:00
|
|
|
if (!isActive())
|
2012-06-02 18:16:54 +03:00
|
|
|
return;
|
2011-12-17 21:59:59 +03:00
|
|
|
|
2023-05-17 22:22:45 +02:00
|
|
|
deactivateEvents(ALL);
|
2012-06-02 18:16:54 +03:00
|
|
|
|
2023-05-17 22:22:45 +02:00
|
|
|
assert(!isActive());
|
2011-12-17 21:59:59 +03:00
|
|
|
|
|
|
|
if(defActions & DEACTIVATE)
|
2013-06-29 16:05:48 +03:00
|
|
|
for(auto & elem : children)
|
|
|
|
if(elem->recActions & DEACTIVATE)
|
|
|
|
elem->deactivate();
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
2023-05-18 12:59:09 +02:00
|
|
|
void CIntObject::printAtMiddleLoc(const std::string & text, const Point &p, EFonts font, const SDL_Color & kolor, SDL_Surface * dst)
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
2012-12-19 20:24:53 +03:00
|
|
|
graphics->fonts[font]->renderTextCenter(dst, text, kolor, pos.topLeft() + p);
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
2023-05-18 12:59:09 +02:00
|
|
|
void CIntObject::printAtMiddleWBLoc( const std::string & text, const Point &p, EFonts font, int charpr, const SDL_Color & kolor, SDL_Surface * dst)
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
2023-05-18 01:09:42 +02:00
|
|
|
graphics->fonts[font]->renderTextLinesCenter(dst, CMessage::breakText(text, charpr, font), kolor, pos.topLeft() + p);
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
2012-06-02 18:16:54 +03:00
|
|
|
void CIntObject::addUsedEvents(ui16 newActions)
|
|
|
|
{
|
2023-05-17 22:22:45 +02:00
|
|
|
if (isActive())
|
|
|
|
activateEvents(~used & newActions);
|
2012-06-02 18:16:54 +03:00
|
|
|
used |= newActions;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CIntObject::removeUsedEvents(ui16 newActions)
|
|
|
|
{
|
2023-05-17 22:22:45 +02:00
|
|
|
if (isActive())
|
|
|
|
deactivateEvents(used & newActions);
|
2012-06-02 18:16:54 +03:00
|
|
|
used &= ~newActions;
|
|
|
|
}
|
|
|
|
|
2011-12-17 21:59:59 +03:00
|
|
|
void CIntObject::disable()
|
|
|
|
{
|
2023-05-17 22:22:45 +02:00
|
|
|
if(isActive())
|
2011-12-17 21:59:59 +03:00
|
|
|
deactivate();
|
|
|
|
|
|
|
|
recActions = DISPOSE;
|
|
|
|
}
|
|
|
|
|
2012-06-02 18:16:54 +03:00
|
|
|
void CIntObject::enable()
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
2023-05-17 22:22:45 +02:00
|
|
|
if(!isActive() && (!parent_m || parent_m->isActive()))
|
2023-05-05 14:48:43 +02:00
|
|
|
{
|
2011-12-17 21:59:59 +03:00
|
|
|
activate();
|
2023-05-05 14:48:43 +02:00
|
|
|
redraw();
|
|
|
|
}
|
2011-12-17 21:59:59 +03:00
|
|
|
|
|
|
|
recActions = 255;
|
|
|
|
}
|
|
|
|
|
2023-05-04 18:04:36 +02:00
|
|
|
void CIntObject::setEnabled(bool on)
|
|
|
|
{
|
|
|
|
if (on)
|
|
|
|
enable();
|
|
|
|
else
|
|
|
|
disable();
|
|
|
|
}
|
|
|
|
|
2011-12-17 21:59:59 +03:00
|
|
|
void CIntObject::fitToScreen(int borderWidth, bool propagate)
|
|
|
|
{
|
2011-12-22 16:05:19 +03:00
|
|
|
Point newPos = pos.topLeft();
|
2011-12-17 21:59:59 +03:00
|
|
|
vstd::amax(newPos.x, borderWidth);
|
|
|
|
vstd::amax(newPos.y, borderWidth);
|
2023-02-03 18:23:53 +02:00
|
|
|
vstd::amin(newPos.x, GH.screenDimensions().x - borderWidth - pos.w);
|
|
|
|
vstd::amin(newPos.y, GH.screenDimensions().y - borderWidth - pos.h);
|
2011-12-17 21:59:59 +03:00
|
|
|
if (newPos != pos.topLeft())
|
|
|
|
moveTo(newPos, propagate);
|
|
|
|
}
|
|
|
|
|
2017-07-15 13:08:20 +02:00
|
|
|
void CIntObject::moveBy(const Point & p, bool propagate)
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
|
|
|
pos.x += p.x;
|
|
|
|
pos.y += p.y;
|
|
|
|
if(propagate)
|
2013-06-29 16:05:48 +03:00
|
|
|
for(auto & elem : children)
|
|
|
|
elem->moveBy(p, propagate);
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
2017-07-15 13:08:20 +02:00
|
|
|
void CIntObject::moveTo(const Point & p, bool propagate)
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
2011-12-22 16:05:19 +03:00
|
|
|
moveBy(Point(p.x - pos.x, p.y - pos.y), propagate);
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
2017-07-15 13:08:20 +02:00
|
|
|
void CIntObject::addChild(CIntObject * child, bool adjustPosition)
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
2012-06-02 18:16:54 +03:00
|
|
|
if (vstd::contains(children, child))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (child->parent_m)
|
|
|
|
{
|
|
|
|
child->parent_m->removeChild(child, adjustPosition);
|
|
|
|
}
|
2011-12-17 21:59:59 +03:00
|
|
|
children.push_back(child);
|
2012-06-02 18:16:54 +03:00
|
|
|
child->parent_m = this;
|
2011-12-17 21:59:59 +03:00
|
|
|
if(adjustPosition)
|
2023-05-05 20:50:20 +02:00
|
|
|
child->moveBy(pos.topLeft(), adjustPosition);
|
2012-06-02 18:16:54 +03:00
|
|
|
|
2023-05-17 22:22:45 +02:00
|
|
|
if (!isActive() && child->isActive())
|
2012-06-02 18:16:54 +03:00
|
|
|
child->deactivate();
|
2023-05-17 22:22:45 +02:00
|
|
|
if (isActive()&& !child->isActive())
|
2012-06-02 18:16:54 +03:00
|
|
|
child->activate();
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
2017-07-15 13:08:20 +02:00
|
|
|
void CIntObject::removeChild(CIntObject * child, bool adjustPosition)
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
2012-06-02 18:16:54 +03:00
|
|
|
if (!child)
|
|
|
|
return;
|
|
|
|
|
2018-04-07 13:34:11 +02:00
|
|
|
if(!vstd::contains(children, child))
|
|
|
|
throw std::runtime_error("Wrong child object");
|
|
|
|
|
|
|
|
if(child->parent_m != this)
|
|
|
|
throw std::runtime_error("Wrong child object");
|
|
|
|
|
2011-12-17 21:59:59 +03:00
|
|
|
children -= child;
|
2013-06-26 14:18:27 +03:00
|
|
|
child->parent_m = nullptr;
|
2011-12-17 21:59:59 +03:00
|
|
|
if(adjustPosition)
|
2022-12-15 23:24:03 +02:00
|
|
|
child->pos -= pos.topLeft();
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void CIntObject::redraw()
|
|
|
|
{
|
2012-06-13 16:04:06 +03:00
|
|
|
//currently most of calls come from active objects so this check won't affect them
|
|
|
|
//it should fix glitches when called by inactive elements located below active window
|
2023-05-17 22:22:45 +02:00
|
|
|
if (isActive())
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
2012-06-13 16:04:06 +03:00
|
|
|
if (parent_m && (type & REDRAW_PARENT))
|
|
|
|
{
|
|
|
|
parent_m->redraw();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
showAll(screenBuf);
|
|
|
|
if(screenBuf != screen)
|
|
|
|
showAll(screen);
|
|
|
|
}
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-17 22:22:45 +02:00
|
|
|
bool CIntObject::isInside(const Point & position)
|
|
|
|
{
|
|
|
|
return pos.isInside(position);
|
|
|
|
}
|
|
|
|
|
2023-05-04 21:33:25 +02:00
|
|
|
void CIntObject::onScreenResize()
|
|
|
|
{
|
|
|
|
center(pos, true);
|
|
|
|
}
|
|
|
|
|
2011-12-22 16:05:19 +03:00
|
|
|
const Rect & CIntObject::center( const Rect &r, bool propagate )
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
|
|
|
pos.w = r.w;
|
|
|
|
pos.h = r.h;
|
2023-02-03 18:23:53 +02:00
|
|
|
return center(Point(GH.screenDimensions().x/2, GH.screenDimensions().y/2), propagate);
|
2011-12-17 21:59:59 +03:00
|
|
|
}
|
|
|
|
|
2011-12-22 16:05:19 +03:00
|
|
|
const Rect & CIntObject::center( bool propagate )
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
|
|
|
return center(pos, propagate);
|
|
|
|
}
|
|
|
|
|
2017-07-15 13:08:20 +02:00
|
|
|
const Rect & CIntObject::center(const Point & p, bool propagate)
|
2011-12-17 21:59:59 +03:00
|
|
|
{
|
2015-01-13 21:57:41 +02:00
|
|
|
moveBy(Point(p.x - pos.w/2 - pos.x,
|
|
|
|
p.y - pos.h/2 - pos.y),
|
2011-12-17 21:59:59 +03:00
|
|
|
propagate);
|
|
|
|
return pos;
|
2011-12-22 16:05:19 +03:00
|
|
|
}
|
|
|
|
|
2023-04-27 19:21:06 +02:00
|
|
|
bool CIntObject::captureThisKey(EShortcut key)
|
2012-03-11 19:29:01 +03:00
|
|
|
{
|
|
|
|
return captureAllKeys;
|
|
|
|
}
|
|
|
|
|
2014-08-03 14:16:19 +03:00
|
|
|
CKeyShortcut::CKeyShortcut()
|
2023-04-27 19:21:06 +02:00
|
|
|
: assignedKey(EShortcut::NONE)
|
2023-05-18 01:09:42 +02:00
|
|
|
, shortcutPressed(false)
|
2014-08-03 14:16:19 +03:00
|
|
|
{}
|
|
|
|
|
2023-04-27 19:21:06 +02:00
|
|
|
CKeyShortcut::CKeyShortcut(EShortcut key)
|
|
|
|
: assignedKey(key)
|
2014-08-03 14:16:19 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2023-04-27 19:21:06 +02:00
|
|
|
void CKeyShortcut::keyPressed(EShortcut key)
|
2011-12-22 16:05:19 +03:00
|
|
|
{
|
2023-05-18 01:09:42 +02:00
|
|
|
if( assignedKey == key && assignedKey != EShortcut::NONE && !shortcutPressed)
|
|
|
|
{
|
|
|
|
shortcutPressed = true;
|
2023-05-17 22:22:45 +02:00
|
|
|
clickLeft(true, false);
|
2023-05-18 01:09:42 +02:00
|
|
|
}
|
2023-02-02 18:02:25 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 19:21:06 +02:00
|
|
|
void CKeyShortcut::keyReleased(EShortcut key)
|
2023-02-02 18:02:25 +02:00
|
|
|
{
|
2023-05-18 01:09:42 +02:00
|
|
|
if( assignedKey == key && assignedKey != EShortcut::NONE && shortcutPressed)
|
|
|
|
{
|
|
|
|
shortcutPressed = false;
|
2023-05-17 22:22:45 +02:00
|
|
|
clickLeft(false, true);
|
2023-05-18 01:09:42 +02:00
|
|
|
}
|
2012-06-02 18:16:54 +03:00
|
|
|
}
|
2018-07-25 00:36:48 +02:00
|
|
|
|
|
|
|
WindowBase::WindowBase(int used_, Point pos_)
|
|
|
|
: CIntObject(used_, pos_)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void WindowBase::close()
|
|
|
|
{
|
2023-05-16 17:34:23 +02:00
|
|
|
if(!GH.windows().isTopWindow(this))
|
2018-07-25 00:36:48 +02:00
|
|
|
logGlobal->error("Only top interface must be closed");
|
2023-05-16 15:20:35 +02:00
|
|
|
GH.windows().popWindows(1);
|
2018-07-25 00:36:48 +02:00
|
|
|
}
|