| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 | /* * 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 * */#include "StdInc.h"#include "CIntObject.h"#include "CGuiHandler.h"#include "WindowHandler.h"#include "EventDispatcher.h"#include "Shortcut.h"#include "../render/Canvas.h"#include "../windows/CMessage.h"#include "../CMT.h"CIntObject::CIntObject(int used_, Point pos_):	parent_m(nullptr),	parent(parent_m),	redrawParent(false),	inputEnabled(true),	used(used_),	recActions(GH.defActionsDef),	defActions(GH.defActionsDef),	pos(pos_, Point()){	if(GH.captureChildren)		GH.createdObj.front()->addChild(this, true);}CIntObject::~CIntObject(){	if(isActive())		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);}void CIntObject::show(Canvas & to){	if(defActions & UPDATE)		for(auto & elem : children)			if(elem->recActions & UPDATE)				elem->show(to);}void CIntObject::showAll(Canvas & to){	if(defActions & SHOWALL)	{		for(auto & elem : children)			if(elem->recActions & SHOWALL)				elem->showAll(to);	}}void CIntObject::activate(){	if (isActive())		return;	if (inputEnabled)		activateEvents(used | GENERAL);	else		activateEvents(GENERAL);	assert(isActive());	if(defActions & ACTIVATE)		for(auto & elem : children)			if(elem->recActions & ACTIVATE)				elem->activate();}void CIntObject::deactivate(){	if (!isActive())		return;	deactivateEvents(used | GENERAL);	assert(!isActive());	if(defActions & DEACTIVATE)		for(auto & elem : children)			if(elem->recActions & DEACTIVATE)				elem->deactivate();}void CIntObject::addUsedEvents(ui16 newActions){	if (isActive() && inputEnabled)		activateEvents(~used & newActions);	used |= newActions;}void CIntObject::removeUsedEvents(ui16 newActions){	if (isActive())		deactivateEvents(used & newActions);	used &= ~newActions;}void CIntObject::disable(){	if(isActive())		deactivate();	recActions = DISPOSE;}void CIntObject::enable(){	if(!isActive() && (!parent_m || parent_m->isActive()))	{		activate();		redraw();	}	recActions = 255;}void CIntObject::setEnabled(bool on){	if (on)		enable();	else		disable();}void CIntObject::setInputEnabled(bool on){	if (inputEnabled == on)		return;	inputEnabled = on;	if (isActive())	{		assert((used & GENERAL) == 0);		if (on)			activateEvents(used);		else			deactivateEvents(used);	}	for(auto & elem : children)		elem->setInputEnabled(on);}void CIntObject::setRedrawParent(bool on){	redrawParent = on;}void CIntObject::fitToScreen(int borderWidth, bool propagate){	Point newPos = pos.topLeft();	vstd::amax(newPos.x, borderWidth);	vstd::amax(newPos.y, borderWidth);	vstd::amin(newPos.x, GH.screenDimensions().x - borderWidth - pos.w);	vstd::amin(newPos.y, GH.screenDimensions().y - borderWidth - pos.h);	if (newPos != pos.topLeft())		moveTo(newPos, propagate);}void CIntObject::moveBy(const Point & p, bool propagate){	pos.x += p.x;	pos.y += p.y;	if(propagate)		for(auto & elem : children)			elem->moveBy(p, propagate);}void CIntObject::moveTo(const Point & p, bool propagate){	moveBy(Point(p.x - pos.x, p.y - pos.y), propagate);}void CIntObject::addChild(CIntObject * child, bool adjustPosition){	if (vstd::contains(children, child))	{		return;	}	if (child->parent_m)	{		child->parent_m->removeChild(child, adjustPosition);	}	children.push_back(child);	child->parent_m = this;	if(adjustPosition)		child->moveBy(pos.topLeft(), adjustPosition);	if (inputEnabled != child->inputEnabled)		child->setInputEnabled(inputEnabled);	if (!isActive() && child->isActive())		child->deactivate();	if (isActive()&& !child->isActive())		child->activate();}void CIntObject::removeChild(CIntObject * child, bool adjustPosition){	if (!child)		return;	if(!vstd::contains(children, child))		throw std::runtime_error("Wrong child object");	if(child->parent_m != this)		throw std::runtime_error("Wrong child object");	children -= child;	child->parent_m = nullptr;	if(adjustPosition)		child->pos -= pos.topLeft();}void CIntObject::redraw(){	//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	if (isActive())	{		if (parent_m && redrawParent)		{			parent_m->redraw();		}		else		{			Canvas buffer = Canvas::createFromSurface(screenBuf);			showAll(buffer);			if(screenBuf != screen)			{				Canvas screenBuffer = Canvas::createFromSurface(screen);				showAll(screenBuffer);			}		}	}}bool CIntObject::receiveEvent(const Point & position, int eventType) const{	return pos.isInside(position);}void CIntObject::onScreenResize(){	center(pos, true);}bool CIntObject::isPopupWindow() const{	return false;}const Rect & CIntObject::center( const Rect &r, bool propagate ){	pos.w = r.w;	pos.h = r.h;	return center(Point(GH.screenDimensions().x/2, GH.screenDimensions().y/2), propagate);}const Rect & CIntObject::center( bool propagate ){	return center(pos, propagate);}const Rect & CIntObject::center(const Point & p, bool propagate){	moveBy(Point(p.x - pos.w/2 - pos.x,		p.y - pos.h/2 - pos.y),		propagate);	return pos;}bool CIntObject::captureThisKey(EShortcut key){	return false;}CKeyShortcut::CKeyShortcut()	: assignedKey(EShortcut::NONE)	, shortcutPressed(false){}CKeyShortcut::CKeyShortcut(EShortcut key)	: assignedKey(key){}void CKeyShortcut::keyPressed(EShortcut key){	if( assignedKey == key && assignedKey != EShortcut::NONE && !shortcutPressed)	{		shortcutPressed = true;		clickLeft(true, false);	}}void CKeyShortcut::keyReleased(EShortcut key){	if( assignedKey == key && assignedKey != EShortcut::NONE && shortcutPressed)	{		shortcutPressed = false;		clickLeft(false, true);	}}WindowBase::WindowBase(int used_, Point pos_)	: CIntObject(used_, pos_){}void WindowBase::close(){	if(!GH.windows().isTopWindow(this))		logGlobal->error("Only top interface must be closed");	GH.windows().popWindows(1);}
 |