123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- /*
- * 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 "SDL_Extensions.h"
- #include "../CMessage.h"
- #include <SDL_pixels.h>
- #include <SDL_surface.h>
- #include <SDL_events.h>
- IShowActivatable::IShowActivatable()
- {
- type = 0;
- }
- CIntObject::CIntObject(int used_, Point pos_):
- parent_m(nullptr),
- active_m(0),
- parent(parent_m),
- active(active_m)
- {
- hovered = captureAllKeys = strongInterest = false;
- toNextTick = timerDelay = 0;
- used = used_;
- recActions = defActions = GH.defActionsDef;
- pos.x = pos_.x;
- pos.y = pos_.y;
- pos.w = 0;
- pos.h = 0;
- if(GH.captureChildren)
- GH.createdObj.front()->addChild(this, true);
- }
- CIntObject::~CIntObject()
- {
- if(active_m)
- 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::setTimer(int msToTrigger)
- {
- if (!(active & TIME))
- activate(TIME);
- toNextTick = timerDelay = msToTrigger;
- used |= TIME;
- }
- void CIntObject::onTimer(int timePassed)
- {
- toNextTick -= timePassed;
- if (toNextTick < 0)
- {
- toNextTick += timerDelay;
- tick();
- }
- }
- void CIntObject::show(SDL_Surface * to)
- {
- if(defActions & UPDATE)
- for(auto & elem : children)
- if(elem->recActions & UPDATE)
- elem->show(to);
- }
- void CIntObject::showAll(SDL_Surface * to)
- {
- if(defActions & SHOWALL)
- {
- for(auto & elem : children)
- if(elem->recActions & SHOWALL)
- elem->showAll(to);
- }
- }
- void CIntObject::activate()
- {
- if (active_m)
- {
- if ((used | GENERAL) == active_m)
- return;
- else
- {
- logGlobal->warn("Warning: IntObject re-activated with mismatching used and active");
- deactivate(); //FIXME: better to avoid such possibility at all
- }
- }
- active_m |= GENERAL;
- activate(used);
- if(defActions & ACTIVATE)
- for(auto & elem : children)
- if(elem->recActions & ACTIVATE)
- elem->activate();
- }
- void CIntObject::activate(ui16 what)
- {
- GH.handleElementActivate(this, what);
- }
- void CIntObject::deactivate()
- {
- if (!active_m)
- return;
- active_m &= ~ GENERAL;
- deactivate(active_m);
- assert(!active_m);
- if(defActions & DEACTIVATE)
- for(auto & elem : children)
- if(elem->recActions & DEACTIVATE)
- elem->deactivate();
- }
- void CIntObject::deactivate(ui16 what)
- {
- GH.handleElementDeActivate(this, what);
- }
- void CIntObject::click(EIntObjMouseBtnType btn, tribool down, bool previousState)
- {
- switch(btn)
- {
- default:
- case EIntObjMouseBtnType::LEFT:
- clickLeft(down, previousState);
- break;
- case EIntObjMouseBtnType::MIDDLE:
- clickMiddle(down, previousState);
- break;
- case EIntObjMouseBtnType::RIGHT:
- clickRight(down, previousState);
- break;
- }
- }
- void CIntObject::printAtLoc(const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst)
- {
- graphics->fonts[font]->renderTextLeft(dst, text, kolor, Point(pos.x + x, pos.y + y));
- }
- void CIntObject::printAtMiddleLoc(const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst)
- {
- printAtMiddleLoc(text, Point(x,y), font, kolor, dst);
- }
- void CIntObject::printAtMiddleLoc(const std::string & text, const Point &p, EFonts font, SDL_Color kolor, SDL_Surface * dst)
- {
- graphics->fonts[font]->renderTextCenter(dst, text, kolor, pos.topLeft() + p);
- }
- void CIntObject::blitAtLoc( SDL_Surface * src, int x, int y, SDL_Surface * dst )
- {
- CSDL_Ext::blitAt(src, pos.x + x, pos.y + y, dst);
- }
- void CIntObject::blitAtLoc(SDL_Surface * src, const Point &p, SDL_Surface * dst)
- {
- blitAtLoc(src, p.x, p.y, dst);
- }
- void CIntObject::printAtMiddleWBLoc( const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor, SDL_Surface * dst)
- {
- graphics->fonts[font]->renderTextLinesCenter(dst, CMessage::breakText(text, charpr, font), kolor, Point(pos.x + x, pos.y + y));
- }
- void CIntObject::addUsedEvents(ui16 newActions)
- {
- if (active_m)
- activate(~used & newActions);
- used |= newActions;
- }
- void CIntObject::removeUsedEvents(ui16 newActions)
- {
- if (active_m)
- deactivate(used & newActions);
- used &= ~newActions;
- }
- void CIntObject::disable()
- {
- if(active)
- deactivate();
- recActions = DISPOSE;
- }
- void CIntObject::enable()
- {
- if(!active_m && (!parent_m || parent_m->active))
- activate();
- recActions = 255;
- }
- 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, screen->w - borderWidth - pos.w);
- vstd::amin(newPos.y, screen->h - 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->pos += pos.topLeft();
- if (!active && child->active)
- child->deactivate();
- if (active && !child->active)
- 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 (active)
- {
- if (parent_m && (type & REDRAW_PARENT))
- {
- parent_m->redraw();
- }
- else
- {
- showAll(screenBuf);
- if(screenBuf != screen)
- showAll(screen);
- }
- }
- }
- const Rect & CIntObject::center( const Rect &r, bool propagate )
- {
- pos.w = r.w;
- pos.h = r.h;
- return center(Point(screen->w/2, screen->h/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::captureThisEvent(const SDL_KeyboardEvent & key)
- {
- return captureAllKeys;
- }
- CKeyShortcut::CKeyShortcut()
- {}
- CKeyShortcut::CKeyShortcut(int key)
- {
- if (key != SDLK_UNKNOWN)
- assignedKeys.insert(key);
- }
- CKeyShortcut::CKeyShortcut(std::set<int> Keys)
- :assignedKeys(Keys)
- {}
- void CKeyShortcut::keyPressed(const SDL_KeyboardEvent & key)
- {
- if(vstd::contains(assignedKeys,key.keysym.sym)
- || vstd::contains(assignedKeys, CGuiHandler::numToDigit(key.keysym.sym)))
- {
- bool prev = mouseState(EIntObjMouseBtnType::LEFT);
- updateMouseState(EIntObjMouseBtnType::LEFT, key.state == SDL_PRESSED);
- clickLeft(key.state == SDL_PRESSED, prev);
- }
- }
- WindowBase::WindowBase(int used_, Point pos_)
- : CIntObject(used_, pos_)
- {
- }
- void WindowBase::close()
- {
- if(GH.topInt().get() != this)
- logGlobal->error("Only top interface must be closed");
- GH.popInts(1);
- }
- IStatusBar::~IStatusBar()
- {}
|