Browse Source

- all windows except for pregame\battles are now CWindowObject-based
- added simple scaling algorithm that works with indexed surfaces

Ivan Savenko 13 years ago
parent
commit
2d8a15f27c

+ 1 - 0
client/AdventureMapClasses.cpp

@@ -592,6 +592,7 @@ void CMinimap::update()
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	vstd::clear_pointer(minimap);
 	minimap = new CMinimapInstance(this, level);
+	redraw();
 }
 
 void CMinimap::setLevel(int newLevel)

+ 2 - 3
client/CAdvmapInterface.cpp

@@ -505,8 +505,7 @@ void CAdvMapInt::fadventureOPtions()
 
 void CAdvMapInt::fsystemOptions()
 {
-	CSystemOptionsWindow * sysopWindow = new CSystemOptionsWindow(Rect::createCentered(487, 481), LOCPLINT);
-	GH.pushInt(sysopWindow);
+	GH.pushInt(new CSystemOptionsWindow());
 }
 
 void CAdvMapInt::fnextHero()
@@ -1498,7 +1497,7 @@ void CAdvMapInt::adjustActiveness(bool aiTurnStart)
 }
 
 CAdventureOptions::CAdventureOptions():
-    CWindowObject("ADVOPTS", PLAYER_COLORED)
+    CWindowObject(PLAYER_COLORED, "ADVOPTS")
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 

+ 10 - 21
client/CCastleInterface.cpp

@@ -246,15 +246,10 @@ void CBuildingRect::mouseMoved (const SDL_MouseMotionEvent & sEvent)
 	}
 }
 
-CDwellingInfoBox::CDwellingInfoBox(int centerX, int centerY, const CGTownInstance *Town, int level)
+CDwellingInfoBox::CDwellingInfoBox(int centerX, int centerY, const CGTownInstance *Town, int level):
+    CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "CRTOINFO", Point(centerX, centerY))
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
-	addUsedEvents(RCLICK);
-	background = new CPicture("CRTOINFO");
-	background->colorize(LOCPLINT->playerID);
-	pos.w = background->pos.w;
-	pos.h = background->pos.h;
-	moveTo(Point(centerX - pos.w/2, centerY - pos.h/2));
 
 	const CCreature * creature = CGI->creh->creatures[Town->creatures[level].second.back()];
 
@@ -284,12 +279,6 @@ CDwellingInfoBox::CDwellingInfoBox(int centerX, int centerY, const CGTownInstanc
 	}
 }
 
-void CDwellingInfoBox::clickRight(tribool down, bool previousState)
-{
-	if((!down || indeterminate(down)))
-		GH.popIntTotally(this);
-}
-
 void CHeroGSlot::hover (bool on)
 {
 	if(!on)
@@ -919,7 +908,7 @@ void CCastleBuildings::openTownHall()
 }
 
 CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInstance * from):
-    CWindowObject("", PLAYER_COLORED | BORDERED),
+    CWindowObject(PLAYER_COLORED | BORDERED),
 	hall(NULL),
 	fort(NULL),
 	town(Town)
@@ -981,7 +970,7 @@ void CCastleInterface::close()
 		else
 			adventureInt->select(town);
 	}
-	GH.popIntTotally(this);
+	CWindowObject::close();
 }
 
 void CCastleInterface::castleTeleport(int where)
@@ -996,7 +985,7 @@ void CCastleInterface::townChange()
 	const CGTownInstance * town = this->town;// "this" is going to be deleted
 	if ( dest == town )
 		return;
-	GH.popIntTotally(this);
+	close();
 	GH.pushInt(new CCastleInterface(dest, town));
 }
 
@@ -1330,7 +1319,7 @@ CHallInterface::CBuildingBox::CBuildingBox(int x, int y, const CGTownInstance *
 }
 
 CHallInterface::CHallInterface(const CGTownInstance *Town):
-    CWindowObject(CGI->buildh->hall[Town->subID].first, PLAYER_COLORED | BORDERED),
+    CWindowObject(PLAYER_COLORED | BORDERED, CGI->buildh->hall[Town->subID].first),
 	town(Town)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
@@ -1416,7 +1405,7 @@ std::string CBuildWindow::getTextForState(int state)
 }
 
 CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Building, int State, bool rightClick):
-    CWindowObject("TPUBUILD", PLAYER_COLORED | (rightClick ? RCLICK_POPUP : 0)),
+    CWindowObject(PLAYER_COLORED | (rightClick ? RCLICK_POPUP : 0), "TPUBUILD"),
 	town(Town),
     building(Building),
     state(State)
@@ -1500,7 +1489,7 @@ std::string CFortScreen::getBgName(const CGTownInstance *town)
 }
 
 CFortScreen::CFortScreen(const CGTownInstance * town):
-    CWindowObject(getBgName(town), PLAYER_COLORED | BORDERED)
+    CWindowObject(PLAYER_COLORED | BORDERED, getBgName(town))
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	ui32 fortSize = town->creatures.size();
@@ -1678,7 +1667,7 @@ void CFortScreen::RecruitArea::clickRight(tribool down, bool previousState)
 }
 
 CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner):
-    CWindowObject("TPMAGE", BORDERED)
+    CWindowObject(BORDERED, "TPMAGE")
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	
@@ -1762,7 +1751,7 @@ void CMageGuildScreen::Scroll::hover(bool on)
 }
 
 CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid):
-    CWindowObject("TPSMITH", PLAYER_COLORED)
+    CWindowObject(PLAYER_COLORED, "TPSMITH")
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 

+ 1 - 3
client/CCastleInterface.h

@@ -58,9 +58,8 @@ public:
 };
 
 /// Dwelling info box - right-click screen for dwellings
-class CDwellingInfoBox : public CIntObject
+class CDwellingInfoBox : public CWindowObject
 {
-	CPicture *background;
 	CLabel *title;
 	CCreaturePic *animation;
 	CLabel *available;
@@ -70,7 +69,6 @@ class CDwellingInfoBox : public CIntObject
 	std::vector<CLabel *> resAmount;
 public:
 	CDwellingInfoBox(int centerX, int centerY, const CGTownInstance *Town, int level);
-	void clickRight(tribool down, bool previousState);
 };
 
 class HeroSlots;

+ 43 - 54
client/CCreatureWindow.cpp

@@ -40,8 +40,9 @@ class CCreatureArtifactInstance;
  *
  */
 
-CCreatureWindow::CCreatureWindow (const CStack &stack, int Type)
-	: type(Type)
+CCreatureWindow::CCreatureWindow (const CStack &stack, int Type):
+    CWindowObject(PLAYER_COLORED | (Type < 3 ? RCLICK_POPUP : 0 ) ),
+    type(Type)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	if (stack.base)
@@ -54,16 +55,18 @@ CCreatureWindow::CCreatureWindow (const CStack &stack, int Type)
 	}
 }
 
-CCreatureWindow::CCreatureWindow (const CStackInstance &stack, int Type)
-	: type(Type)
+CCreatureWindow::CCreatureWindow (const CStackInstance &stack, int Type):
+    CWindowObject(PLAYER_COLORED | (Type < 3 ? RCLICK_POPUP : 0 ) ),
+    type(Type)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 
 	init(&stack, &stack, dynamic_cast<const CGHeroInstance*>(stack.armyObj));
 }
 
-CCreatureWindow::CCreatureWindow(int Cid, int Type, int creatureCount)
-	:type(Type)
+CCreatureWindow::CCreatureWindow(int Cid, int Type, int creatureCount):
+   CWindowObject(PLAYER_COLORED | (Type < 3 ? RCLICK_POPUP : 0 ) ),
+    type(Type)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 
@@ -72,8 +75,13 @@ CCreatureWindow::CCreatureWindow(int Cid, int Type, int creatureCount)
 	delete stack;
 }
 
-CCreatureWindow::CCreatureWindow(const CStackInstance &st, int Type, boost::function<void()> Upg, boost::function<void()> Dsm, UpgradeInfo *ui)
-	: type(Type), dismiss(0), upgrade(0), ok(0), dsm(Dsm)
+CCreatureWindow::CCreatureWindow(const CStackInstance &st, int Type, boost::function<void()> Upg, boost::function<void()> Dsm, UpgradeInfo *ui):
+    CWindowObject(PLAYER_COLORED | (Type < 3 ? RCLICK_POPUP : 0 ) ),
+    type(Type),
+    dismiss(0),
+    upgrade(0),
+    ok(0),
+    dsm(Dsm)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	init(&st, &st,dynamic_cast<const CGHeroInstance*>(st.armyObj));
@@ -120,8 +128,10 @@ CCreatureWindow::CCreatureWindow(const CStackInstance &st, int Type, boost::func
 	}
 }
 
-CCreatureWindow::CCreatureWindow (const CCommanderInstance * Commander)
-	:type (COMMANDER), commander (Commander)
+CCreatureWindow::CCreatureWindow (const CCommanderInstance * Commander):
+    CWindowObject(PLAYER_COLORED),
+    type(COMMANDER),
+	commander (Commander)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	init(commander, commander, dynamic_cast<const CGHeroInstance*>(commander->armyObj));
@@ -218,11 +228,9 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
 	vstd::amax(bonusRows, 1);
 
 	if (type >= COMMANDER)
-		bitmap = new CPicture("CommWin" + boost::lexical_cast<std::string>(bonusRows) + ".pcx");
+		setBackground("CommWin" + boost::lexical_cast<std::string>(bonusRows) + ".pcx");
 	else
-		bitmap = new CPicture("CreWin" + boost::lexical_cast<std::string>(bonusRows) + ".pcx"); //1 to 4 rows for now
-	bitmap->colorizeAndConvert(LOCPLINT->playerID);
-	pos = bitmap->center();
+		setBackground("CreWin" + boost::lexical_cast<std::string>(bonusRows) + ".pcx"); //1 to 4 rows for now
 
 	//Buttons
 	ok = new CAdventureMapButton("",CGI->generaltexth->zelp[445].second, boost::bind(&CCreatureWindow::close,this), 489, 148, "hsbtns.def", SDLK_RETURN);
@@ -247,8 +255,9 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
 		if (GameConstants::STACK_EXP && type < COMMANDER)
 		{
 			int rank = std::min(stack->getExpRank(), 10); //hopefully nobody adds more
-			printAtMiddle(boost::lexical_cast<std::string>(stack->experience), 488, 82, FONT_SMALL, Colors::Cornsilk,*bitmap);
-			printAtMiddle(CGI->generaltexth->zcrexp[rank] + " [" + boost::lexical_cast<std::string>(rank) + "]", 488, 62, FONT_MEDIUM, Colors::Jasmine,*bitmap);
+			new CLabel(488, 82, FONT_SMALL, CENTER, Colors::Cornsilk, boost::lexical_cast<std::string>(stack->experience));
+			new CLabel(488, 62, FONT_MEDIUM, CENTER, Colors::Jasmine,
+			           CGI->generaltexth->zcrexp[rank] + " [" + boost::lexical_cast<std::string>(rank) + "]");
 
 			if (type > BATTLE) //we need it only on adv. map
 			{
@@ -340,8 +349,11 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
 			}
 		}
 		//print commander level
-		printAtMiddle(boost::lexical_cast<std::string>((ui16)(commander->level)), 488, 62, FONT_MEDIUM, Colors::Jasmine,*bitmap);
-		printAtMiddle(boost::lexical_cast<std::string>(stack->experience), 488, 82, FONT_SMALL, Colors::Cornsilk,*bitmap);
+		new CLabel(488, 62, FONT_MEDIUM, CENTER, Colors::Jasmine,
+		           boost::lexical_cast<std::string>((ui16)(commander->level)));
+
+		new CLabel(488, 82, FONT_SMALL, CENTER, Colors::Cornsilk,
+		           boost::lexical_cast<std::string>(stack->experience));
 	}
 	if (creArt) //stack or commander artifacts
 	{
@@ -370,7 +382,8 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
 				boost::replace_first (spellText, "%s", CGI->spellh->spells[effect]->name);
 				int duration = battleStack->getBonus(Selector::source(Bonus::SPELL_EFFECT,effect))->turnsRemain;
 				boost::replace_first (spellText, "%d", boost::lexical_cast<std::string>(duration));
-				blitAt(graphics->spellEffectsPics->ourImages[effect + 1].bitmap, 20 + 52 * printed, 184, *bitmap);
+
+				new CAnimImage("SpellInt", effect + 1, 0, 20 + 52 * printed, 184);
 				spellEffects.push_back(new LRClickableAreaWText(Rect(20 + 52 * printed, 184, 50, 38), spellText, spellText));
 				if (++printed >= 10) //we can fit only 10 effects
 					break;
@@ -395,7 +408,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
 
 void CCreatureWindow::printLine(int nr, const std::string &text, int baseVal, int val/*=-1*/, bool range/*=false*/)
 {
-	printAt(text, 162, 48 + nr*19, FONT_SMALL, Colors::Cornsilk, *bitmap);
+	new CLabel(162, 48 + nr*19, FONT_SMALL, TOPLEFT, Colors::Cornsilk, text);
 
 	std::string hlp;
 	if(range && baseVal != val)
@@ -405,7 +418,7 @@ void CCreatureWindow::printLine(int nr, const std::string &text, int baseVal, in
 	else
 		hlp = boost::lexical_cast<std::string>(baseVal);
 
-	printTo(hlp, 325, 64 + nr*19, FONT_SMALL, Colors::Cornsilk, *bitmap);
+	new CLabel(325, 64 + nr*19, FONT_SMALL, BOTTOMRIGHT, Colors::Cornsilk, hlp);
 }
 
 void CCreatureWindow::recreateSkillList(int Pos)
@@ -445,7 +458,7 @@ void CCreatureWindow::showAll(SDL_Surface * to)
 {
 	CIntObject::showAll(to);
 
-	printAtMiddle ((type >= COMMANDER? c->nameSing : c->namePl), 180, 30, FONT_SMALL, Colors::Jasmine, *bitmap); //creature name
+	printAtMiddleLoc((type >= COMMANDER ? c->nameSing : c->namePl), 180, 30, FONT_SMALL, Colors::Jasmine, to); //creature name
 
 	printLine(0, CGI->generaltexth->primarySkillNames[0], c->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK), stackNode->Attack());
 	printLine(1, CGI->generaltexth->primarySkillNames[1], c->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE), stackNode->Defense());
@@ -459,13 +472,13 @@ void CCreatureWindow::showAll(SDL_Surface * to)
 	}
 	if (stackNode->valOfBonuses(Bonus::CASTS))
 	{
-		printAtMiddle(CGI->generaltexth->allTexts[399], 356, 62, FONT_SMALL, Colors::Cornsilk,*bitmap);
+		printAtMiddleLoc(CGI->generaltexth->allTexts[399], 356, 62, FONT_SMALL, Colors::Cornsilk, to);
 		std::string casts;
 		if (type == BATTLE)
 			casts = boost::lexical_cast<std::string>((ui16)dynamic_cast<const CStack*>(stackNode)->casts); //ui8 is converted to char :(
 		else
 			casts = boost::lexical_cast<std::string>(stackNode->valOfBonuses(Bonus::CASTS));
-		printAtMiddle(casts, 356, 82, FONT_SMALL, Colors::Cornsilk,*bitmap);
+		printAtMiddleLoc(casts, 356, 82, FONT_SMALL, Colors::Cornsilk, to);
 	}
 
 	//TODO
@@ -549,19 +562,6 @@ void CCreatureWindow::artifactMoved (const ArtifactLocation &artLoc, const Artif
 	artifactRemoved (artLoc); //same code
 }
 
-void CCreatureWindow::clickRight(tribool down, bool previousState)
-{
-	if(down)
-		return;
-	if (type < 3)
-		close();
-}
-
-void CCreatureWindow::close()
-{
-	GH.popIntTotally(this);
-}
-
 CCreatureWindow::~CCreatureWindow()
 {
  	for (int i=0; i<upgResCost.size(); ++i)
@@ -611,7 +611,8 @@ void CCreInfoWindow::show(SDL_Surface * to)
 	creatureCount->showAll(to);
 }
 
-CCreInfoWindow::CCreInfoWindow(const CStackInstance &stack, bool LClicked, boost::function<void()> upgradeFunc, boost::function<void()> dismissFunc, UpgradeInfo *upgradeInfo)
+CCreInfoWindow::CCreInfoWindow(const CStackInstance &stack, bool LClicked, boost::function<void()> upgradeFunc, boost::function<void()> dismissFunc, UpgradeInfo *upgradeInfo):
+    CWindowObject(PLAYER_COLORED | (LClicked ? 0 : RCLICK_POPUP), "CRSTKPU")
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	init(stack.type, &stack, dynamic_cast<const CGHeroInstance*>(stack.armyObj), stack.count, LClicked);
@@ -660,14 +661,16 @@ CCreInfoWindow::CCreInfoWindow(const CStackInstance &stack, bool LClicked, boost
 	}
 }
 
-CCreInfoWindow::CCreInfoWindow(int creatureID, bool LClicked, int creatureCount)
+CCreInfoWindow::CCreInfoWindow(int creatureID, bool LClicked, int creatureCount):
+    CWindowObject(PLAYER_COLORED | (LClicked ? 0 : RCLICK_POPUP), "CRSTKPU")
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	const CCreature *creature = CGI->creh->creatures[creatureID];
 	init(creature, NULL, NULL, creatureCount, LClicked);
 }
 
-CCreInfoWindow::CCreInfoWindow(const CStack &stack, bool LClicked)
+CCreInfoWindow::CCreInfoWindow(const CStack &stack, bool LClicked):
+    CWindowObject(PLAYER_COLORED | (LClicked ? 0 : RCLICK_POPUP), "CRSTKPU")
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	init(stack.getCreature(), &stack, stack.getMyHero(), stack.count, LClicked);
@@ -705,10 +708,6 @@ void CCreInfoWindow::init(const CCreature *creature, const CBonusSystemNode *sta
 	if(!stackNode)
 		stackNode = creature;
 
-	background = new CPicture("CRSTKPU");
-	background->colorize(LOCPLINT->playerID);
-	pos = background->center();
-
 	animation = new CCreaturePic(21, 48, creature);
 
 	std::string countStr = boost::lexical_cast<std::string>(count);
@@ -763,16 +762,6 @@ void CCreInfoWindow::init(const CCreature *creature, const CBonusSystemNode *sta
 	}
 }
 
-void CCreInfoWindow::close()
-{
-	GH.popIntTotally(this);
-}
-
-void CCreInfoWindow::clickRight(tribool down, bool previousState)
-{
-	close();
-}
-
 CIntObject * createCreWindow(
 	const CStack *s, bool lclick/* = false*/)
 {

+ 2 - 8
client/CCreatureWindow.h

@@ -37,7 +37,7 @@ class CLabel;
 class CAnimImage;
 
 // New creature window
-class CCreatureWindow : public CArtifactHolder
+class CCreatureWindow : public CWindowObject, public CArtifactHolder
 {
 public:
 	enum CreWinType {OTHER = 0, BATTLE = 1, ARMY = 2, HERO = 3, COMMANDER = 4, COMMANDER_LEVEL_UP = 5}; // > 3 are opened permanently
@@ -57,7 +57,6 @@ public:
 	std::vector<CBonusItem*> bonusItems;
 	std::vector<LRClickableAreaWText*> spellEffects;
 
-	CPicture *bitmap; //background
 	CCreaturePic *anim; //related creature's animation
 	MoraleLuckBox *luck, *morale;
 	LRClickableAreaWTextComp * expArea; //displays exp details
@@ -87,8 +86,6 @@ public:
 	void showAll(SDL_Surface * to);
 	void show(SDL_Surface * to);
 	void printLine(int nr, const std::string &text, int baseVal, int val=-1, bool range=false);
-	void close();
-	void clickRight(tribool down, bool previousState); //call-in
 	void sliderMoved(int newpos);
 	~CCreatureWindow(); //d-tor
 
@@ -113,10 +110,9 @@ public:
 };
 
 /// original creature info window
-class CCreInfoWindow : public CIntObject
+class CCreInfoWindow : public CWindowObject
 {
 public:
-	CPicture * background;
 	CLabel * creatureCount;
 	CLabel * creatureName;
 	CLabel * abilityText;
@@ -138,8 +134,6 @@ public:
 	void init(const CCreature * cre, const CBonusSystemNode * stackNode, const CGHeroInstance * heroOwner, int creatureCount, bool LClicked);
 	void printLine(int nr, const std::string & text, int baseVal, int val = -1, bool range = false);
 
-	void clickRight(tribool down, bool previousState);
-	void close();
 	void show(SDL_Surface * to);
 };
 

+ 5 - 13
client/CHeroWindow.cpp

@@ -90,24 +90,21 @@ CHeroSwitcher::CHeroSwitcher(Point _pos, const CGHeroInstance * _hero):
 	pos.h = image->pos.h;
 }
 
-CHeroWindow::CHeroWindow(const CGHeroInstance *hero)
-	:  heroWArt(this, hero)
+CHeroWindow::CHeroWindow(const CGHeroInstance *hero):
+    CWindowObject(PLAYER_COLORED, "HeroScr4"),
+	heroWArt(this, hero)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	garr = nullptr;
 	curHero = hero;
 	listSelection = nullptr;
 
-	background = new CPicture("HeroScr4.BMP");
-	background->colorize(LOCPLINT->playerID);
-	pos = background->center();
-
 	new CAnimImage("CREST58", LOCPLINT->playerID, 0, 606, 8);
 
 	//artifs = new CArtifactsOfHero(pos.topLeft(), true);
 	ourBar = new CGStatusBar(7, 559, "ADROLLVR.bmp", 660); // new CStatusBar(pos.x+72, pos.y+567, "ADROLLVR.bmp", 660);
 
-	quitButton = new CAdventureMapButton(CGI->generaltexth->heroscrn[17], std::string(),boost::bind(&CHeroWindow::quit,this), 609, 516, "hsbtns.def", SDLK_RETURN);
+	quitButton = new CAdventureMapButton(CGI->generaltexth->heroscrn[17], std::string(),boost::bind(&CHeroWindow::close,this), 609, 516, "hsbtns.def", SDLK_RETURN);
 	quitButton->assignedKeys.insert(SDLK_ESCAPE);
 	dismissButton = new CAdventureMapButton(std::string(), CGI->generaltexth->heroscrn[28], boost::bind(&CHeroWindow::dismissCurrent,this), 454, 429, "hsbtns2.def", SDLK_d);
 	questlogButton = new CAdventureMapButton(CGI->generaltexth->heroscrn[0], std::string(), boost::bind(&CHeroWindow::questlog,this), 314, 429, "hsbtns4.def", SDLK_q);
@@ -281,14 +278,9 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals
 		redraw();
 }
 
-void CHeroWindow::quit()
-{
-	GH.popIntTotally(this);
-}
-
 void CHeroWindow::dismissCurrent()
 {
-	CFunctionList<void()> ony = boost::bind(&CHeroWindow::quit,this);
+	CFunctionList<void()> ony = boost::bind(&CHeroWindow::close,this);
 	ony += boost::bind(&CCallback::dismissHero,LOCPLINT->cb,curHero);
 	LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[22], ony, 0, false);
 }

+ 3 - 4
client/CHeroWindow.h

@@ -1,7 +1,8 @@
 #pragma once
 
 #include "../lib/HeroBonus.h"
-
+#include "UIFramework/CIntObjectClasses.h"
+#include "GUIClasses.h"
 
 //#include "CPlayerInterface.h"
 
@@ -48,9 +49,8 @@ public:
 	const TBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL, const std::string &cachingStr = "") const OVERRIDE;
 };
 
-class CHeroWindow: public CWindowWithGarrison, public CWindowWithArtifacts
+class CHeroWindow: public CWindowObject, public CWindowWithGarrison, public CWindowWithArtifacts
 {
-	CPicture *background;
 	CGStatusBar * ourBar; //heroWindow's statusBar
 
 	//buttons
@@ -85,7 +85,6 @@ public:
 	void update(const CGHeroInstance * hero, bool redrawNeeded = false); //sets main displayed hero
 	void showAll(SDL_Surface * to);
 
-	void quit(); //stops displaying hero window and disposes
 	void dismissCurrent(); //dissmissed currently displayed hero (curHero)
 	void questlog(); //show quest log in hero window
 	void commanderWindow();

+ 3 - 5
client/CKingdomInterface.cpp

@@ -462,12 +462,10 @@ bool InfoBoxCustom::prepareMessage(std::string &text, CComponent **comp)
 	return false;
 }
 
-CKingdomInterface::CKingdomInterface()
+CKingdomInterface::CKingdomInterface():
+    CWindowObject(PLAYER_COLORED | BORDERED, conf.go()->ac.overviewBg)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
-	background = new CPicture(conf.go()->ac.overviewBg);
-	background->colorize(LOCPLINT->playerID);
-	pos = background->center();
 	ui32 footerPos = conf.go()->ac.overviewSize * 116;
 
 	tabArea = new CTabbedInt(boost::bind(&CKingdomInterface::createMainTab, this, _1), CTabbedInt::DestroyFunc(), Point(4,4));
@@ -618,7 +616,7 @@ void CKingdomInterface::generateButtons()
 	                                   boost::bind(&CKingdomInterface::activateTab, this, 1),748,64+footerPos,"OVBUTN6.DEF", SDLK_t);
 
 	btnExit = new CAdventureMapButton (CGI->generaltexth->allTexts[600],"",
-	                                  boost::bind(&CGuiHandler::popIntTotally,&GH, this),748,99+footerPos,"OVBUTN1.DEF", SDLK_RETURN);
+	                                  boost::bind(&CKingdomInterface::close, this),748,99+footerPos,"OVBUTN1.DEF", SDLK_RETURN);
 	btnExit->assignedKeys.insert(SDLK_ESCAPE);
 	btnExit->setOffset(3);
 

+ 2 - 3
client/CKingdomInterface.h

@@ -194,7 +194,7 @@ public:
 ////////////////////////////////////////////////////////////////////////////////
 
 /// Class which holds all parts of kingdom overview window
-class CKingdomInterface : public CGarrisonHolder, public CArtifactHolder
+class CKingdomInterface : public CWindowObject, public CGarrisonHolder, public CArtifactHolder
 {
 private:
 	struct OwnedObjectInfo
@@ -207,7 +207,6 @@ private:
 
 	CListBox * dwellingsList;
 	CTabbedInt * tabArea;
-	CPicture * background;
 
 	//Main buttons
 	CAdventureMapButton *btnTowns;
@@ -302,7 +301,7 @@ public:
 };
 
 /// Tab with all hero-specific data
-class CKingdHeroList : public CGarrisonHolder, public CWindowWithArtifacts
+class CKingdHeroList : public CIntObject, public CGarrisonHolder, public CWindowWithArtifacts
 {
 private:
 	CArtifactsOfHero::SCommonPart artsCommonPart;

+ 16 - 22
client/CPlayerInterface.cpp

@@ -382,7 +382,7 @@ void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
 void CPlayerInterface::openTownWindow(const CGTownInstance * town)
 {
 	if (castleInt)
-		GH.popIntTotally(castleInt);
+		castleInt->close();
 	castleInt = new CCastleInterface(town);
 	GH.pushInt(castleInt);
 }
@@ -1295,11 +1295,9 @@ void CPlayerInterface::showArtifactAssemblyDialog (ui32 artifactID, ui32 assembl
 		text += boost::str(boost::format(CGI->generaltexth->allTexts[732]) % assembledArtifact.Name());
 
 		// Picture of assembled artifact at bottom.
-		CComponent* sc = new CComponent;
-		sc->type = CComponent::artifact;
-		sc->subtype = assembledArtifact.id;
-		sc->description = assembledArtifact.Description();
-		sc->subtitle = assembledArtifact.Name();
+		CComponent* sc = new CComponent(CComponent::artifact, assembledArtifact.id, 0);
+		//sc->description = assembledArtifact.Description();
+		//sc->subtitle = assembledArtifact.Name();
 		scs.push_back(sc);
 	} else {
 		// Do you wish to disassemble this artifact?
@@ -2314,10 +2312,9 @@ void CPlayerInterface::artifactRemoved(const ArtifactLocation &al)
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	BOOST_FOREACH(IShowActivatable *isa, GH.listInt)
 	{
-		if(isa->type & IShowActivatable::WITH_ARTIFACTS)
-		{
-			(dynamic_cast<CArtifactHolder*>(isa))->artifactRemoved(al);
-		}
+		auto artWin = dynamic_cast<CArtifactHolder*>(isa);
+		if(artWin)
+			artWin->artifactRemoved(al);
 	}
 }
 
@@ -2326,10 +2323,9 @@ void CPlayerInterface::artifactMoved(const ArtifactLocation &src, const Artifact
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	BOOST_FOREACH(IShowActivatable *isa, GH.listInt)
 	{
-		if(isa->type & IShowActivatable::WITH_ARTIFACTS)
-		{
-			(dynamic_cast<CArtifactHolder*>(isa))->artifactMoved(src, dst);
-		}
+		auto artWin = dynamic_cast<CArtifactHolder*>(isa);
+		if(artWin)
+			artWin->artifactMoved(src, dst);
 	}
 }
 
@@ -2338,10 +2334,9 @@ void CPlayerInterface::artifactAssembled(const ArtifactLocation &al)
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	BOOST_FOREACH(IShowActivatable *isa, GH.listInt)
 	{
-		if(isa->type & IShowActivatable::WITH_ARTIFACTS)
-		{
-			(dynamic_cast<CArtifactHolder*>(isa))->artifactAssembled(al);
-		}
+		auto artWin = dynamic_cast<CArtifactHolder*>(isa);
+		if(artWin)
+			artWin->artifactAssembled(al);
 	}
 }
 
@@ -2350,10 +2345,9 @@ void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	BOOST_FOREACH(IShowActivatable *isa, GH.listInt)
 	{
-		if(isa->type & IShowActivatable::WITH_ARTIFACTS)
-		{
-			(dynamic_cast<CArtifactHolder*>(isa))->artifactDisassembled(al);
-		}
+		auto artWin = dynamic_cast<CArtifactHolder*>(isa);
+		if(artWin)
+			artWin->artifactDisassembled(al);
 	}
 }
 

+ 3 - 7
client/CSpellWindow.cpp

@@ -70,7 +70,8 @@ void SpellbookInteractiveArea::hover(bool on)
 	}
 }
 
-CSpellWindow::CSpellWindow(const SDL_Rect & myRect, const CGHeroInstance * _myHero, CPlayerInterface * _myInt, bool openOnBattleSpells):
+CSpellWindow::CSpellWindow(const SDL_Rect &, const CGHeroInstance * _myHero, CPlayerInterface * _myInt, bool openOnBattleSpells):
+    CWindowObject(PLAYER_COLORED, "SpelBack"),
 	battleSpellsOnly(openOnBattleSpells),
 	selectedTab(4),
 	currentPage(0),
@@ -145,10 +146,6 @@ CSpellWindow::CSpellWindow(const SDL_Rect & myRect, const CGHeroInstance * _myHe
 
 	//numbers of spell pages computed
 
-	pos = myRect;
-	background = BitmapHandler::loadBitmap("SpelBack.bmp");
-	graphics->blueToPlayersAdv(background, myHero->tempOwner);
-
 	leftCorner = BitmapHandler::loadBitmap("SpelTrnL.bmp", true);
 	rightCorner = BitmapHandler::loadBitmap("SpelTrnR.bmp", true);
 	spells = CDefHandler::giveDef("Spells.def");
@@ -221,7 +218,6 @@ CSpellWindow::CSpellWindow(const SDL_Rect & myRect, const CGHeroInstance * _myHe
 
 CSpellWindow::~CSpellWindow()
 {
-	SDL_FreeSurface(background);
 	SDL_FreeSurface(leftCorner);
 	SDL_FreeSurface(rightCorner);
 	delete spells;
@@ -320,7 +316,7 @@ void CSpellWindow::fRcornerb()
 
 void CSpellWindow::showAll(SDL_Surface * to)
 {
-	CSDL_Ext::blitSurface(background, NULL, to, &pos);
+	CWindowObject::showAll(to);
 	blitAt(spellTab->ourImages[selectedTab].bitmap, 524 + pos.x, 88 + pos.y, to);
 
 	std::ostringstream mana;

+ 3 - 2
client/CSpellWindow.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include "UIFramework/CIntObject.h"
+#include "UIFramework/CIntObjectClasses.h"
 
 /*
  * CSpellWindow.h, part of VCMI engine
@@ -38,7 +39,7 @@ public:
 };
 
 /// The spell window
-class CSpellWindow : public CIntObject
+class CSpellWindow : public CWindowObject
 {
 private:
 	class SpellArea : public CIntObject
@@ -60,7 +61,7 @@ private:
 		void showAll(SDL_Surface * to);
 	};
 
-	SDL_Surface * background, * leftCorner, * rightCorner;
+	SDL_Surface * leftCorner, * rightCorner;
 	CDefHandler * spells, //pictures of spells
 		* spellTab, //school select
 		* schools, //schools' pictures

File diff suppressed because it is too large
+ 229 - 360
client/GUIClasses.cpp


+ 25 - 59
client/GUIClasses.h

@@ -196,7 +196,6 @@ public:
 	void init(Etype Type, int Subtype, int Val);
 	CComponent(Etype Type, int Subtype, int Val); //c-tor
 	CComponent(const Component &c); //c-tor
-	CComponent(); //c-tor
 
 	void clickRight(tribool down, bool previousState); //call-in
 };
@@ -324,16 +323,15 @@ public:
 class CCreaturePic : public CIntObject
 {
 private:
-	CPicture *bg; //background
+	CPicture *bg;
 	CCreatureAnim *anim; //displayed animation
 
 public:
 	CCreaturePic(int x, int y, const CCreature *cre, bool Big=true, bool Animated=true); //c-tor
-	~CCreaturePic(); //d-tor
 };
 
 /// Recruitment window where you can recruit creatures
-class CRecruitmentWindow : public CIntObject
+class CRecruitmentWindow : public CWindowObject
 {
 public:
 	static const int SPACE_BETWEEN = 18;
@@ -352,7 +350,6 @@ public:
 	boost::function<void(int,int)> recruit; //void (int ID, int amount) <-- call to recruit creatures
 	CSlider *slider; //for selecting amount
 	CAdventureMapButton *max, *buy, *cancel;
-	CPicture *bitmap; //background
 	CGStatusBar *bar;
 	int which; //which creature is active
 
@@ -360,7 +357,6 @@ public:
 	int level;
 	const CArmedInstance *dst;
 
-	void close();
 	void Max();
 	void Buy();
 	void Cancel();
@@ -370,7 +366,6 @@ public:
 	void showAll(SDL_Surface * to);
 	void initCres();
 	CRecruitmentWindow(const CGDwelling *Dwelling, int Level, const CArmedInstance *Dst, const boost::function<void(int,int)> & Recruit, int y_offset = 0); //creatures - pairs<creature_ID,amount> //c-tor
-	~CRecruitmentWindow(); //d-tor
 };
 
 /// Split window where creatures can be splitted up into two single unit stacks
@@ -405,22 +400,15 @@ public:
 };
 
 /// Raised up level windowe where you can select one out of two skills
-class CLevelWindow : public CIntObject
+class CLevelWindow : public CWindowObject
 {
 public:
-	int heroPortrait;
-	SDL_Surface *bitmap; //background
 	std::vector<CSelectableComponent *> comps; //skills to select
-	CAdventureMapButton *ok;
 	boost::function<void(ui32)> cb;
 
-	void close();
 	CLevelWindow(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback); //c-tor
 	~CLevelWindow(); //d-tor
-	void activate();
-	void deactivate();
 	void selectionChanged(unsigned to);
-	void show(SDL_Surface * to);
 };
 
 /// Resource bar like that at the bottom of the adventure map screen
@@ -435,7 +423,7 @@ public:
 };
 
 /// Town portal, castle gate window
-class CObjectListWindow : public CIntObject
+class CObjectListWindow : public CWindowObject
 {
 	class CItem : public CIntObject
 	{
@@ -455,7 +443,6 @@ class CObjectListWindow : public CIntObject
 	CLabel * descr;
 
 	CListBox *list;
-	CPicture *bg; //background
 	CPicture *titleImage;//title image (castle gate\town portal picture)
 	CAdventureMapButton *ok, *exit;
 
@@ -478,7 +465,7 @@ public:
 	void keyPressed (const SDL_KeyboardEvent & key);
 };
 
-class CArtifactHolder : public virtual CIntObject
+class CArtifactHolder
 {
 public:
 	CArtifactHolder();
@@ -500,7 +487,7 @@ public:
 	void artifactAssembled(const ArtifactLocation &artLoc);
 };
 
-class CTradeWindow : public CWindowWithArtifacts //base for markets and altar of sacrifice
+class CTradeWindow : public CWindowObject, public CWindowWithArtifacts //base for markets and altar of sacrifice
 {
 public:
 	enum EType
@@ -538,7 +525,6 @@ public:
 
 	const IMarket *market;
 	const CGHeroInstance *hero;
-	CPicture *bg; //background
 
 	CArtifactsOfHero *arts;
 	//all indexes: 1 = left, 0 = right
@@ -551,7 +537,7 @@ public:
 	CSlider *slider; //for choosing amount to be exchanged
 	bool readyToTrade;
 
-	CTradeWindow(const IMarket *Market, const CGHeroInstance *Hero, EMarketMode::EMarketMode Mode); //c
+	CTradeWindow(std::string bgName, const IMarket *Market, const CGHeroInstance *Hero, EMarketMode::EMarketMode Mode); //c
 
 	void showAll(SDL_Surface * to);
 
@@ -578,6 +564,8 @@ public:
 class CMarketplaceWindow : public CTradeWindow
 {
 	bool printButtonFor(EMarketMode::EMarketMode M) const;
+
+	std::string getBackgroundForMode(EMarketMode::EMarketMode mode);
 public:
 	int r1, r2; //suggested amounts of traded resources
 	bool madeTransaction; //if player made at least one transaction
@@ -644,13 +632,12 @@ public:
 	void moveFromSlotToAltar(int slotID, CTradeableItem* altarSlot, const CArtifactInstance *art);
 };
 
-class CSystemOptionsWindow : public CIntObject
+class CSystemOptionsWindow : public CWindowObject
 {
 private:
 	CLabel *title;
 	CLabelGroup *leftGroup;
 	CLabelGroup *rightGroup;
-	CPicture * bg; //background of window
 	CAdventureMapButton *load, *save, *restart, *mainMenu, *quitGame, *backToMap; //load and restart are not used yet
 	CHighlightableButtonsGroup * heroMoveSpeed;
 	CHighlightableButtonsGroup * mapScrollSpeed;
@@ -689,10 +676,10 @@ private:
 	void pushSDLEvent(int type, int usercode);
 
 public:
-	CSystemOptionsWindow(const SDL_Rect & pos, CPlayerInterface * owner); //c-tor
+	CSystemOptionsWindow(); //c-tor
 };
 
-class CTavernWindow : public CIntObject
+class CTavernWindow : public CWindowObject
 {
 public:
 	class HeroPortrait : public CIntObject
@@ -714,7 +701,6 @@ public:
 
 	} *h1, *h2; //recruitable heroes
 
-	CPicture *bg; //background
 	CGStatusBar *bar; //tavern's internal status bar
 	int selected;//0 (left) or 1 (right)
 	int oldSelected;//0 (left) or 1 (right)
@@ -726,7 +712,6 @@ public:
 	~CTavernWindow(); //d-tor
 
 	void recruitb();
-	void close();
 	void thievesguildb();
 	void show(SDL_Surface * to);
 };
@@ -924,9 +909,8 @@ public:
 	~CGarrisonWindow(); //d-tor
 };
 
-class CExchangeWindow : public CWindowWithGarrison, public CWindowWithArtifacts
+class CExchangeWindow : public CWindowObject, public CWindowWithGarrison, public CWindowWithArtifacts
 {
-	CPicture *background;
 	CGStatusBar * ourBar; //internal statusbar
 
 	CAdventureMapButton * quit, * questlogButton[2];
@@ -945,7 +929,6 @@ public:
 	const CGHeroInstance* heroInst[2];
 	CArtifactsOfHero * artifs[2];
 
-	void close();
 	void showAll(SDL_Surface * to);
 
 	void questlog(int whichHero); //questlog button callback; whichHero: 0 - left, 1 - right
@@ -957,11 +940,10 @@ public:
 };
 
 /// Here you can buy ships
-class CShipyardWindow : public CIntObject
+class CShipyardWindow : public CWindowObject
 {
 public:
 	CGStatusBar *bar;
-	CPicture *bg; //background
 	CPicture *bgWater;
 
 	CLabel *title;
@@ -979,27 +961,25 @@ public:
 };
 
 /// Puzzle screen which gets uncovered when you visit obilisks
-class CPuzzleWindow : public CIntObject
+class CPuzzleWindow : public CWindowObject
 {
 private:
-	SDL_Surface * background;
+	int3 grailPos;
+
 	CAdventureMapButton * quitb;
-	CResDataBar * resdatabar;
 
-	std::vector<std::pair<SDL_Surface *, const SPuzzleInfo *> > puzzlesToPullBack;
-	ui8 animCount;
+	std::vector<CPicture * > piecesToRemove;
+	ui8 currentAlpha;
 
 public:
-	void activate();
-	void deactivate();
+	void showAll(SDL_Surface * to);
 	void show(SDL_Surface * to);
 
 	CPuzzleWindow(const int3 &grailPos, double discoveredRatio);
-	~CPuzzleWindow();
 };
 
 /// Creature transformer window
-class CTransformerWindow : public CIntObject
+class CTransformerWindow : public CWindowObject
 {
 public:
 	class CItem : public CIntObject
@@ -1015,13 +995,11 @@ public:
 		void showAll(SDL_Surface * to);
 		void clickLeft(tribool down, bool previousState);
 		CItem(CTransformerWindow * _parent, int _size, int _id);
-		~CItem();
 	};
 
 	const CArmedInstance *army;//object with army for transforming (hero or town)
 	const CGHeroInstance *hero;//only if we have hero in town
 	const CGTownInstance *town;//market, town garrison is used if hero == NULL
-	CPicture *bg; //background
 	std::vector<CItem*> items;
 
 	CAdventureMapButton *all, *convert, *cancel;
@@ -1030,10 +1008,9 @@ public:
 	void makeDeal();
 	void addAll();
 	CTransformerWindow(const CGHeroInstance * _hero, const CGTownInstance * _town); //c-tor
-	~CTransformerWindow(); //d-tor
 };
 
-class CUniversityWindow : public CIntObject
+class CUniversityWindow : public CWindowObject
 {
 	class CItem : public CAnimImage
 	{
@@ -1054,22 +1031,19 @@ public:
 	const IMarket * market;
 
 	CPicture * green, * yellow, * red;//colored bars near skills
-	CPicture *bg; //background
 	std::vector<CItem*> items;
 
 	CAdventureMapButton *cancel;
 	CGStatusBar *bar;
 
 	CUniversityWindow(const CGHeroInstance * _hero, const IMarket * _market); //c-tor
-	~CUniversityWindow(); //d-tor
 };
 
 /// Confirmation window for University
-class CUnivConfirmWindow : public CIntObject
+class CUnivConfirmWindow : public CWindowObject
 {
 public:
 	CUniversityWindow * parent;
-	CPicture * bg;
 	CGStatusBar *bar;
 	CAdventureMapButton *confirm, *cancel;
 
@@ -1078,14 +1052,13 @@ public:
 };
 
 /// Hill fort is the building where you can upgrade units
-class CHillFortWindow : public CIntObject, public CWindowWithGarrison
+class CHillFortWindow : public CWindowObject, public CWindowWithGarrison
 {
 public:
 
 	int slotsCount;//=7;
 	CGStatusBar * bar;
 	CDefEssential *resources;
-	CPicture *bg; //background surface
 	CHeroArea *heroPic;//clickable hero image
 	CAdventureMapButton *quit,//closes window
 	                   *upgradeAll,//upgrade all creatures
@@ -1098,7 +1071,6 @@ public:
 	TResources totalSumm; // totalSum[resource ID] = value
 
 	CHillFortWindow(const CGHeroInstance *visitor, const CGObjectInstance *object); //c-tor
-	~CHillFortWindow(); //d-tor
 
 	void activate();
 	void showAll (SDL_Surface *to);
@@ -1109,21 +1081,15 @@ public:
 	void updateGarrisons();//update buttons after garrison changes
 };
 
-class CThievesGuildWindow : public CIntObject
+class CThievesGuildWindow : public CWindowObject
 {
 	const CGObjectInstance * owner;
 
 	CGStatusBar * statusBar;
 	CAdventureMapButton * exitb;
-	SDL_Surface * background;
 	CMinorResDataBar * resdatabar;
 
 public:
 	void activate();
-	void show(SDL_Surface * to);
-
-	void bexitf();
-
 	CThievesGuildWindow(const CGObjectInstance * _owner);
-	~CThievesGuildWindow();
 };

+ 1 - 1
client/UIFramework/CIntObject.h

@@ -53,7 +53,7 @@ class IShowActivatable : public IShowable, public IActivatable
 {
 public:
 	//redraw parent flag - this int may be semi-transparent and require redraw of parent window
-	enum {WITH_GARRISON = 1, BLOCK_ADV_HOTKEYS = 2, WITH_ARTIFACTS = 4, REDRAW_PARENT=8};
+	enum {BLOCK_ADV_HOTKEYS = 2, REDRAW_PARENT=8};
 	int type; //bin flags using etype
 	IShowActivatable();
 	virtual ~IShowActivatable(){}; //d-tor

+ 23 - 3
client/UIFramework/CIntObjectClasses.cpp

@@ -131,6 +131,11 @@ void CPicture::convertToScreenBPP()
 	SDL_FreeSurface(hlp);
 }
 
+void CPicture::setAlpha(int value)
+{
+	SDL_SetAlpha(bg, SDL_SRCALPHA, value);
+}
+
 void CPicture::scaleTo(Point size)
 {
 	SDL_Surface * scaled = CSDL_Ext::scaleSurface(bg, size.x, size.y);
@@ -1239,7 +1244,7 @@ CTextBox::CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts F
 	pos.h = rect.h;
 	pos.w = rect.w;
 	assert(Align == TOPLEFT || Align == CENTER); //TODO: support for other alignments
-	assert(pos.w >= 80); //we need some space
+	assert(pos.w >= 40); //we need some space
 	setTxt(Text);
 }
 
@@ -1590,7 +1595,7 @@ void CFocusable::moveFocus()
 	}
 }
 
-CWindowObject::CWindowObject(std::string imageName, int options_, Point centerAt):
+CWindowObject::CWindowObject(int options_, std::string imageName, Point centerAt):
     CIntObject(getUsedEvents(options_), Point()),
     options(options_),
     background(createBg(imageName, options & PLAYER_COLORED))
@@ -1602,9 +1607,11 @@ CWindowObject::CWindowObject(std::string imageName, int options_, Point centerAt
 
 	if (background)
 		pos = background->center(centerAt);
+	else
+		center(centerAt);
 }
 
-CWindowObject::CWindowObject(std::string imageName, int options_):
+CWindowObject::CWindowObject(int options_, std::string imageName):
     CIntObject(getUsedEvents(options_), Point()),
     options(options_),
     background(createBg(imageName, options & PLAYER_COLORED))
@@ -1616,6 +1623,8 @@ CWindowObject::CWindowObject(std::string imageName, int options_):
 
 	if (background)
 		pos = background->center();
+	else
+		center(Point(screen->w/2, screen->h/2));
 }
 
 CPicture * CWindowObject::createBg(std::string imageName, bool playerColored)
@@ -1631,6 +1640,17 @@ CPicture * CWindowObject::createBg(std::string imageName, bool playerColored)
 	return image;
 }
 
+void CWindowObject::setBackground(std::string filename)
+{
+	OBJ_CONSTRUCTION_CAPTURING_ALL;
+
+	delete background;
+	background = createBg(filename, options & PLAYER_COLORED);
+
+	if (background)
+		pos = background->center(Point(pos.w/2 + pos.x, pos.h/2 + pos.y));
+}
+
 int CWindowObject::getUsedEvents(int options)
 {
 	if (options & RCLICK_POPUP)

+ 9 - 4
client/UIFramework/CIntObjectClasses.h

@@ -54,6 +54,10 @@ public:
 	~CPicture();
 	void init();
 
+	//set alpha value for whole surface. Note: may be messed up if surface is shared
+	// 0=transparent, 255=opaque
+	void setAlpha(int value);
+
 	void scaleTo(Point size);
 	void createSimpleRect(const Rect &r, bool screenFormat, ui32 color);
 	void show(SDL_Surface * to);
@@ -463,7 +467,6 @@ public:
 };
 
 /// Basic class for windows
-// TODO: status bar?
 class CWindowObject : public CIntObject
 {
 	CPicture * createBg(std::string imageName, bool playerColored);
@@ -480,6 +483,8 @@ protected:
 	void clickRight(tribool down, bool previousState);
 	//To display border
 	void showAll(SDL_Surface *to);
+	//change or set background image
+	void setBackground(std::string filename);
 public:
 	enum EOptions
 	{
@@ -489,10 +494,10 @@ public:
 	};
 
 	/*
-	 * imageName - name for background image, can be empty
 	 * options - EOpions enum
+	 * imageName - name for background image, can be empty
 	 * centerAt - position of window center. Default - center of the screen
 	*/
-	CWindowObject(std::string imageName, int options, Point centerAt);
-	CWindowObject(std::string imageName, int options);
+	CWindowObject(int options, std::string imageName, Point centerAt);
+	CWindowObject(int options, std::string imageName = "");
 };

+ 55 - 8
client/UIFramework/SDL_Extensions.cpp

@@ -26,7 +26,14 @@ SDL_Color Colors::createColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a /*= 0*/)
 
 SDL_Surface * CSDL_Ext::newSurface(int w, int h, SDL_Surface * mod) //creates new surface, with flags/format same as in surface given
 {
-	return SDL_CreateRGBSurface(mod->flags,w,h,mod->format->BitsPerPixel,mod->format->Rmask,mod->format->Gmask,mod->format->Bmask,mod->format->Amask);
+	SDL_Surface * ret = SDL_CreateRGBSurface(mod->flags,w,h,mod->format->BitsPerPixel,mod->format->Rmask,mod->format->Gmask,mod->format->Bmask,mod->format->Amask);
+	if (mod->format->palette)
+	{
+		assert(ret->format->palette);
+		assert(ret->format->palette->ncolors == mod->format->palette->ncolors);
+		memcpy(ret->format->palette->colors, mod->format->palette->colors, mod->format->palette->ncolors * sizeof(SDL_Color));
+	}
+	return ret;
 }
 
 SDL_Surface * CSDL_Ext::copySurface(SDL_Surface * mod) //returns copy of given surface
@@ -1112,6 +1119,50 @@ void CSDL_Ext::applyEffect( SDL_Surface * surf, const SDL_Rect * rect, int mode
 	}
 }
 
+template<int bpp>
+void scaleSurfaceFastInternal(SDL_Surface *surf, SDL_Surface *ret)
+{
+	const float factorX = float(surf->w) / float(ret->w),
+	            factorY = float(surf->h) / float(ret->h);
+
+	for(int y = 0; y < ret->h; y++)
+	{
+		for(int x = 0; x < ret->w; x++)
+		{
+			//coordinates we want to calculate
+			int origX = floor(factorX * x),
+			    origY = floor(factorY * y);
+
+			// Get pointers to source pixels
+			Uint8 *srcPtr = (Uint8*)surf->pixels + origY * surf->pitch + origX * bpp;
+			Uint8 *destPtr = (Uint8*)ret->pixels + y * ret->pitch + x * bpp;
+
+			memcpy(destPtr, srcPtr, bpp);
+		}
+	}
+}
+
+SDL_Surface * CSDL_Ext::scaleSurfaceFast(SDL_Surface *surf, int width, int height)
+{
+	if (!surf || !width || !height)
+		return nullptr;
+
+	//Same size? return copy - this should more be faster
+	if (width == surf->w && height == surf->h)
+		return copySurface(surf);
+
+	SDL_Surface *ret = newSurface(width, height, surf);
+
+	switch(surf->format->BytesPerPixel)
+	{
+		case 1: scaleSurfaceFastInternal<1>(surf, ret); break;
+		case 2: scaleSurfaceFastInternal<2>(surf, ret); break;
+		case 3: scaleSurfaceFastInternal<3>(surf, ret); break;
+		case 4: scaleSurfaceFastInternal<4>(surf, ret); break;
+	}
+	return ret;
+}
+
 template<int bpp>
 void scaleSurfaceInternal(SDL_Surface *surf, SDL_Surface *ret)
 {
@@ -1123,8 +1174,8 @@ void scaleSurfaceInternal(SDL_Surface *surf, SDL_Surface *ret)
 		for(int x = 0; x < ret->w; x++)
 		{
 			//coordinates we want to interpolate
-			float origX = x * factorX,
-			      origY = y * factorY;
+			float origX = factorX * x,
+			      origY = factorY * y;
 
 			float x1 = floor(origX), x2 = floor(origX+1),
 			      y1 = floor(origY), y2 = floor(origY+1);
@@ -1168,11 +1219,7 @@ SDL_Surface * CSDL_Ext::scaleSurface(SDL_Surface *surf, int width, int height)
 		return nullptr;
 
 	if (surf->format->palette)
-	{
-		//it is possible implement but only to power of 2 sizes. May be needed for view world spells
-		tlog0 << "scale surface error: Can't scale indexed surface!\n";
-		return nullptr;
-	}
+		return scaleSurfaceFast(surf, width, height);
 
 	//Same size? return copy - this should more be faster
 	if (width == surf->w && height == surf->h)

+ 4 - 1
client/UIFramework/SDL_Extensions.h

@@ -174,7 +174,10 @@ namespace CSDL_Ext
 	SDL_Surface * createSurfaceWithBpp(int width, int height); //create surface with give bits per pixels value
 	void VflipSurf(SDL_Surface * surf); //fluipis given surface by vertical axis
 
-	//scale surface to required size. Won't work with indexed surfaces
+	//scale surface to required size.
+	//nearest neighbour algorithm
+	SDL_Surface * scaleSurfaceFast(SDL_Surface *surf, int width, int height);
+	// bilinear filtering. Uses fallback to scaleSurfaceFast in case of indexed surfaces
 	SDL_Surface * scaleSurface(SDL_Surface *surf, int width, int height);
 
 	template<int bpp>

+ 4 - 4
lib/CGameState.cpp

@@ -2118,13 +2118,13 @@ struct statsHLP
 {
 	typedef std::pair< ui8, si64 > TStat;
 	//converts [<player's color, value>] to vec[place] -> platers
-	static std::vector< std::list< ui8 > > getRank( std::vector<TStat> stats )
+	static std::vector< std::vector< ui8 > > getRank( std::vector<TStat> stats )
 	{
 		std::sort(stats.begin(), stats.end(), statsHLP());
 
 		//put first element
-		std::vector< std::list<ui8> > ret;
-		std::list<ui8> tmp;
+		std::vector< std::vector<ui8> > ret;
+		std::vector<ui8> tmp;
 		tmp.push_back( stats[0].first );
 		ret.push_back( tmp );
 
@@ -2138,7 +2138,7 @@ struct statsHLP
 			else
 			{
 				//create next occupied rank
-				std::list<ui8> tmp;
+				std::vector<ui8> tmp;
 				tmp.push_back(stats[g].first);
 				ret.push_back(tmp);
 			}

+ 1 - 1
lib/CGameState.h

@@ -143,7 +143,7 @@ struct DLL_LINKAGE SThievesGuildInfo
 {
 	std::vector<ui8> playerColors; //colors of players that are in-game
 
-	std::vector< std::list< ui8 > > numOfTowns, numOfHeroes, gold, woodOre, mercSulfCrystGems, obelisks, artifacts, army, income; // [place] -> [colours of players]
+	std::vector< std::vector< ui8 > > numOfTowns, numOfHeroes, gold, woodOre, mercSulfCrystGems, obelisks, artifacts, army, income; // [place] -> [colours of players]
 
 	std::map<ui8, InfoAboutHero> colorToBestHero; //maps player's color to his best heros' 
 

Some files were not shown because too many files changed in this diff