#pragma once #include "../widgets/CArtifactHolder.h" #include "../widgets/CGarrisonInt.h" class CButton; class CAnimImage; class CToggleGroup; class CResDataBar; class CSlider; class CTownInfo; class CCreaInfo; class HeroSlots; class LRClickableAreaOpenTown; class CComponent; class CHeroArea; class MoraleLuckBox; class CListBox; class CTabbedInt; class CGStatusBar; /* * CKingdomInterface.h, 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 * */ class CKingdHeroList; class CKingdTownList; class IInfoBoxData; /* * Several classes to display basically any data. * Main part - class InfoBox which controls how data will be formatted\positioned * InfoBox have image and 0-2 labels * In constructor it should receive object that implements IInfoBoxData interface * * interface IInfoBoxData defines way to get data for use in InfoBox * have several implementations: * InfoBoxHeroData - to display one of fields from hero (e.g. absolute value of primary skills) * InfoBoxCustomHeroData - to display one of hero fields without hero (e.g. bonuses from objects) * InfoBoxTownData - data from town * InfoBoxCustom - user-defined data */ /// Displays one of object propertries with image and optional labels class InfoBox : public CIntObject { public: enum InfoPos { POS_UP_DOWN, POS_DOWN, POS_RIGHT, POS_INSIDE, POS_CORNER, POS_NONE }; enum InfoSize { SIZE_TINY, SIZE_SMALL, SIZE_MEDIUM, SIZE_BIG, SIZE_HUGE }; private: InfoSize size; InfoPos infoPos; IInfoBoxData *data; CLabel * value; CLabel * name; CAnimImage * image; CHoverableArea *hover; public: InfoBox(Point position, InfoPos Pos, InfoSize Size, IInfoBoxData *Data); ~InfoBox(); void clickRight(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override; //Update object if data may have changed //void update(); }; class IInfoBoxData { public: enum InfoType { HERO_PRIMARY_SKILL, HERO_MANA, HERO_EXPERIENCE, HERO_SPECIAL, HERO_SECONDARY_SKILL, //TODO: Luck? Morale? Artifact? ARMY_SLOT,//TODO TOWN_GROWTH, TOWN_AVAILABLE, TOWN_BUILDING,//TODO CUSTOM }; protected: InfoType type; IInfoBoxData(InfoType Type); public: //methods that generate values for displaying virtual std::string getValueText()=0; virtual std::string getNameText()=0; virtual std::string getImageName(InfoBox::InfoSize size)=0; virtual std::string getHoverText()=0; virtual size_t getImageIndex()=0; //TODO: replace with something better virtual bool prepareMessage(std::string &text, CComponent **comp)=0; virtual ~IInfoBoxData(){}; }; class InfoBoxAbstractHeroData : public IInfoBoxData { protected: virtual int getSubID()=0; virtual si64 getValue()=0; public: InfoBoxAbstractHeroData(InfoType Type); std::string getValueText() override; std::string getNameText() override; std::string getImageName(InfoBox::InfoSize size) override; std::string getHoverText() override; size_t getImageIndex() override; bool prepareMessage(std::string &text, CComponent **comp) override; }; class InfoBoxHeroData : public InfoBoxAbstractHeroData { const CGHeroInstance * hero; int index;//index of data in hero (0-7 for sec. skill, 0-3 for pr. skill) int getSubID() override; si64 getValue() override; public: InfoBoxHeroData(InfoType Type, const CGHeroInstance *Hero, int Index=0); //To get a bit different texts for hero window std::string getHoverText() override; std::string getValueText() override; bool prepareMessage(std::string &text, CComponent **comp) override; }; class InfoBoxCustomHeroData : public InfoBoxAbstractHeroData { int subID;//subID of data (0=attack...) si64 value;//actual value of data, 64-bit to fit experience and negative values int getSubID() override; si64 getValue() override; public: InfoBoxCustomHeroData(InfoType Type, int subID, si64 value); }; class InfoBoxCustom : public IInfoBoxData { public: std::string valueText; std::string nameText; std::string imageName; std::string hoverText; size_t imageIndex; InfoBoxCustom(std::string ValueText, std::string NameText, std::string ImageName, size_t ImageIndex, std::string HoverText=""); std::string getValueText() override; std::string getNameText() override; std::string getImageName(InfoBox::InfoSize size) override; std::string getHoverText() override; size_t getImageIndex() override; bool prepareMessage(std::string &text, CComponent **comp) override; }; //TODO!!! class InfoBoxTownData : public IInfoBoxData { const CGTownInstance * town; int index;//index of data in town int value;//actual value of data public: InfoBoxTownData(InfoType Type, const CGTownInstance * Town, int Index); InfoBoxTownData(InfoType Type, int SubID, int Value); std::string getValueText() override; std::string getNameText() override; std::string getImageName(InfoBox::InfoSize size) override; std::string getHoverText() override; size_t getImageIndex() override; }; //////////////////////////////////////////////////////////////////////////////// /// Class which holds all parts of kingdom overview window class CKingdomInterface : public CWindowObject, public CGarrisonHolder, public CArtifactHolder { private: struct OwnedObjectInfo { int imageID; ui32 count; std::string hoverText; OwnedObjectInfo(): imageID(0), count(0) {} }; std::vector objects; CListBox * dwellingsList; CTabbedInt * tabArea; //Main buttons CButton *btnTowns; CButton *btnHeroes; CButton *btnExit; //Buttons for scrolling dwellings list CButton *dwellUp, *dwellDown; CButton *dwellTop, *dwellBottom; InfoBox * minesBox[7]; CHoverableArea * incomeArea; CLabel * incomeAmount; CGStatusBar * statusbar; CResDataBar *resdatabar; void activateTab(size_t which); //Internal functions used during construction void generateButtons(); void generateObjectsList(const std::vector &ownedObjects); void generateMinesList(const std::vector &ownedObjects); CIntObject* createOwnedObject(size_t index); CIntObject* createMainTab(size_t index); public: CKingdomInterface(); void townChanged(const CGTownInstance *town); void updateGarrisons() override; void artifactRemoved(const ArtifactLocation &artLoc) override; void artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc) override; void artifactDisassembled(const ArtifactLocation &artLoc) override; void artifactAssembled(const ArtifactLocation &artLoc) override; }; /// List item with town class CTownItem : public CIntObject, public CGarrisonHolder { CAnimImage *background; CAnimImage *picture; CLabel *name; CLabel *income; CGarrisonInt *garr; LRClickableAreaOpenTown *townArea; HeroSlots *heroes; CTownInfo *hall, *fort; std::vector available; std::vector growth; public: const CGTownInstance * town; CTownItem(const CGTownInstance* town); void updateGarrisons() override; void update(); }; /// List item with hero class CHeroItem : public CIntObject, public CWindowWithGarrison { const CGHeroInstance * hero; std::vector artTabs; CAnimImage *portrait; CLabel *name; CHeroArea *heroArea; CLabel *artsText; CTabbedInt *artsTabs; CToggleGroup *artButtons; std::vector heroInfo; MoraleLuckBox * morale, * luck; void onArtChange(int tabIndex); CIntObject * onTabSelected(size_t index); void onTabDeselected(CIntObject *object); public: CArtifactsOfHero *heroArts; CHeroItem(const CGHeroInstance* hero); }; /// Tab with all hero-specific data class CKingdHeroList : public CIntObject, public CGarrisonHolder, public CWindowWithArtifacts { private: std::vector heroItems; CListBox * heroes; CPicture * title; CLabel * heroLabel; CLabel * skillsLabel; CIntObject* createHeroItem(size_t index); void destroyHeroItem(CIntObject *item); public: CKingdHeroList(size_t maxSize); void updateGarrisons() override; }; /// Tab with all town-specific data class CKingdTownList : public CIntObject, public CGarrisonHolder { private: std::vector townItems; CListBox * towns; CPicture * title; CLabel * townLabel; CLabel * garrHeroLabel; CLabel * visitHeroLabel; CIntObject* createTownItem(size_t index); public: CKingdTownList(size_t maxSize); void townChanged(const CGTownInstance *town); void updateGarrisons() override; };