浏览代码

Started making hot-seat GUI. Accompanying changes to rest of GUI.

Michał W. Urbańczyk 15 年之前
父节点
当前提交
da87d25d21

+ 6 - 6
client/AdventureMapButton.cpp

@@ -178,9 +178,9 @@ void AdventureMapButton::hover (bool on)
 	std::string *name = (vstd::contains(hoverTexts,state)) 
 							? (&hoverTexts[state]) 
 							: (vstd::contains(hoverTexts,0) ? (&hoverTexts[0]) : NULL);
-	if(LOCPLINT && name && name->size() && blocked!=1) //if there is no name, there is nohing to display also
+	if(name && name->size() && blocked!=1) //if there is no name, there is nohing to display also
 	{
-		if (LOCPLINT->battleInt) //for battle buttons
+		if (LOCPLINT && LOCPLINT->battleInt) //for battle buttons
 		{
 			if(on && LOCPLINT->battleInt->console->alterTxt == "")
 			{
@@ -193,12 +193,12 @@ void AdventureMapButton::hover (bool on)
 				LOCPLINT->battleInt->console->whoSetAlter = 0;
 			}
 		}
-		else //for other buttons
+		else if(GH.statusbar) //for other buttons
 		{
 			if (on)
-				LOCPLINT->statusbar->print(*name);
-			else if ( LOCPLINT->statusbar->getCurrent()==(*name) )
-				LOCPLINT->statusbar->clear();
+				GH.statusbar->print(*name);
+			else if ( GH.statusbar->getCurrent()==(*name) )
+				GH.statusbar->clear();
 		}
 	}
 }

+ 1 - 1
client/CAdvmapInterface.cpp

@@ -1649,7 +1649,7 @@ void CAdvMapInt::activate()
 		return;
 	}
 	screenBuf = screen;
-	LOCPLINT->statusbar = &statusbar;
+	GH.statusbar = &statusbar;
 	activateMouseMove();
 
 	kingOverview.activate();

+ 20 - 20
client/CCastleInterface.cpp

@@ -129,7 +129,7 @@ void CBuildingRect::hover(bool on)
 		if(LOCPLINT->castleInt->hBuild == this)
 		{
 			LOCPLINT->castleInt->hBuild = NULL;
-			LOCPLINT->statusbar->clear();
+			GH.statusbar->clear();
 
 			//call mouseMoved in other buildings, cursor might have been moved while they were inactive (eg. because of r-click popup)
 			for(size_t i = 0; i < LOCPLINT->castleInt->buildings.size(); i++)
@@ -176,7 +176,7 @@ void CBuildingRect::mouseMoved (const SDL_MouseMotionEvent & sEvent)
 			if(LOCPLINT->castleInt->hBuild == this)
 			{
 				LOCPLINT->castleInt->hBuild = NULL;
-				LOCPLINT->statusbar->clear();
+				GH.statusbar->clear();
 			}
 		}
 		else //inside the area of this building
@@ -187,18 +187,18 @@ void CBuildingRect::mouseMoved (const SDL_MouseMotionEvent & sEvent)
 				{
 					LOCPLINT->castleInt->hBuild = this;
 					if(CGI->buildh->buildings[str->townID][str->ID] && CGI->buildh->buildings[str->townID][str->ID]->Name().length())
-						LOCPLINT->statusbar->print(CGI->buildh->buildings[str->townID][str->ID]->Name());
+						GH.statusbar->print(CGI->buildh->buildings[str->townID][str->ID]->Name());
 					else
-						LOCPLINT->statusbar->print(str->name);
+						GH.statusbar->print(str->name);
 				}
 			}
 			else //no building hovered
 			{
 				LOCPLINT->castleInt->hBuild = this;
 				if(CGI->buildh->buildings[str->townID][str->ID] && CGI->buildh->buildings[str->townID][str->ID]->Name().length())
-					LOCPLINT->statusbar->print(CGI->buildh->buildings[str->townID][str->ID]->Name());
+					GH.statusbar->print(CGI->buildh->buildings[str->townID][str->ID]->Name());
 				else
-					LOCPLINT->statusbar->print(str->name);
+					GH.statusbar->print(str->name);
 			}
 		}
 	}
@@ -209,7 +209,7 @@ void CHeroGSlot::hover (bool on)
 {
 	if(!on) 
 	{
-		LOCPLINT->statusbar->clear();
+		GH.statusbar->clear();
 		return;
 	}
 	CHeroGSlot *other = upg  ?  &owner->hslotup :  &owner->hslotdown;
@@ -254,7 +254,7 @@ void CHeroGSlot::hover (bool on)
 		}
 	}
 	if(temp.size())
-		LOCPLINT->statusbar->print(temp);
+		GH.statusbar->print(temp);
 }
 
 void CHeroGSlot::clickRight(tribool down, bool previousState)
@@ -836,7 +836,7 @@ void CCastleInterface::activate()
 	showing = true;
 	townlist->activate();
 	garr->activate();
-	LOCPLINT->statusbar = statusbar;
+	GH.statusbar = statusbar;
 	exit->activate();
 	fort->activate();
 	hall->activate();
@@ -1094,10 +1094,10 @@ void CCastleInterface::CCreaInfo::hover(bool on)
 	{
 		std::string descr=CGI->generaltexth->allTexts[588];
 		boost::algorithm::replace_first(descr,"%s",CGI->creh->creatures[crid].namePl);
-		LOCPLINT->statusbar->print(descr);
+		GH.statusbar->print(descr);
 	}
 	else
-		LOCPLINT->statusbar->clear();
+		GH.statusbar->clear();
 }
 void CCastleInterface::CCreaInfo::clickLeft(tribool down, bool previousState)
 {
@@ -1233,10 +1233,10 @@ void CCastleInterface::CTownInfo::hover(bool on)
 			descr = CGI->generaltexth->allTexts[255];
 		else
 			descr = CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][bid]->Name();
-		LOCPLINT->statusbar->print(descr);
+		GH.statusbar->print(descr);
 	}
 	else
-		LOCPLINT->statusbar->clear();
+		GH.statusbar->clear();
 }
 void CCastleInterface::CTownInfo::clickLeft(tribool down, bool previousState)
 {
@@ -1368,10 +1368,10 @@ void CHallInterface::CBuildingBox::hover(bool on)
 			toPrint = CGI->generaltexth->hcommands[state];
 		std::vector<std::string> name;
 		name.push_back(CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][BID]->Name());
-		LOCPLINT->statusbar->print(CSDL_Ext::processStr(toPrint,name));
+		GH.statusbar->print(CSDL_Ext::processStr(toPrint,name));
 	}
 	else
-		LOCPLINT->statusbar->clear();
+		GH.statusbar->clear();
 }
 void CHallInterface::CBuildingBox::clickLeft(tribool down, bool previousState)
 {
@@ -1732,12 +1732,12 @@ void CFortScreen::show( SDL_Surface * to)
 	anim++;
 	exit->show(to);
 	resdatabar->show(to);
-	LOCPLINT->statusbar->show(to);
+	GH.statusbar->show(to);
 }
 
 void CFortScreen::activate()
 {
-	LOCPLINT->statusbar = LOCPLINT->castleInt->statusbar;
+	GH.statusbar = LOCPLINT->castleInt->statusbar;
 	exit->activate();
 	for (size_t i=0;i<recAreas.size(); ++i)
 	{
@@ -1929,7 +1929,7 @@ void CMageGuildScreen::show(SDL_Surface * to)
 {
 	blitAt(bg,pos,to);
 	resdatabar->show(to);
-	LOCPLINT->statusbar->show(to);
+	GH.statusbar->show(to);
 	exit->show(to);
 }
 
@@ -1982,9 +1982,9 @@ void CMageGuildScreen::Scroll::hover(bool on)
 {
 	//Hoverable::hover(on);
 	if(on)
-		LOCPLINT->statusbar->print(spell->name);
+		GH.statusbar->print(spell->name);
 	else
-		LOCPLINT->statusbar->clear();
+		GH.statusbar->clear();
 
 }
 

+ 1 - 1
client/CHeroWindow.cpp

@@ -321,7 +321,7 @@ void CHeroWindow::activate()
 	luck->activate();
 
 	garr->activate();
-	LOCPLINT->statusbar = ourBar;
+	GH.statusbar = ourBar;
 
 	for(size_t v=0; v<primSkillAreas.size(); ++v)
 	{

+ 1 - 1
client/CKingdomInterface.cpp

@@ -314,7 +314,7 @@ void CKingdomInterface::show(SDL_Surface * to)
 
 void CKingdomInterface::activate()
 {
-	LOCPLINT->statusbar = statusbar;
+	GH.statusbar = statusbar;
 	exit->activate();
 	toTowns->activate();
 	toHeroes->activate();

+ 36 - 62
client/CPreGame.cpp

@@ -123,7 +123,7 @@ CMenuScreen::CMenuScreen( EState which )
 		{
 			buttons[0] = new AdventureMapButton("", CGI->generaltexth->zelp[3].second, bind(&CMenuScreen::moveTo, this, ref(CGP->scrs[newGame])), 540, 10, "ZMENUNG.DEF", SDLK_n);
 			buttons[1] = new AdventureMapButton("", CGI->generaltexth->zelp[4].second, bind(&CMenuScreen::moveTo, this, ref(CGP->scrs[loadGame])), 532, 132, "ZMENULG.DEF", SDLK_l);
-			buttons[2] = new AdventureMapButton("", CGI->generaltexth->zelp[5].second, 0 /*cb*/, 524, 251, "ZMENUHS.DEF", SDLK_h);
+			buttons[2] = new AdventureMapButton("", CGI->generaltexth->zelp[5].second, 0, 524, 251, "ZMENUHS.DEF", SDLK_h);
 			buttons[3] = new AdventureMapButton("", CGI->generaltexth->zelp[6].second, 0 /*cb*/, 557, 359, "ZMENUCR.DEF", SDLK_c);
 			boost::function<void()> confWindow = bind(CInfoWindow::showYesNoDialog, ref(CGI->generaltexth->allTexts[69]), (const std::vector<SComponent*>*)0, do_quit, 0, false, 1);
 			buttons[4] = new AdventureMapButton("", CGI->generaltexth->zelp[7].second, confWindow, 586, 468, "ZMENUQT.DEF", SDLK_ESCAPE);
@@ -133,7 +133,7 @@ CMenuScreen::CMenuScreen( EState which )
 		{
 			bgAd = new CPicture(BitmapHandler::loadBitmap("ZNEWGAM.bmp"), 114, 312, true);
 			buttons[0] = new AdventureMapButton("", CGI->generaltexth->zelp[10].second, bind(&CGPreGame::openSel, CGP, newGame), 545, 4, "ZTSINGL.DEF", SDLK_s);
-			buttons[1] = new AdventureMapButton("", CGI->generaltexth->zelp[11].second, 0 /*cb*/, 568, 120, "ZTMULTI.DEF", SDLK_m);
+			buttons[1] = new AdventureMapButton("", CGI->generaltexth->zelp[11].second, &pushIntT<CMultiMode>, 568, 120, "ZTMULTI.DEF", SDLK_m);
 			buttons[2] = new AdventureMapButton("", CGI->generaltexth->zelp[12].second, bind(&CMenuScreen::moveTo, this, ref(CGP->scrs[campaignMain])), 541, 233, "ZTCAMPN.DEF", SDLK_c);
 			buttons[3] = new AdventureMapButton("", CGI->generaltexth->zelp[13].second, 0 /*cb*/, 545, 358, "ZTTUTOR.DEF", SDLK_t);
 			buttons[4] = new AdventureMapButton("", CGI->generaltexth->zelp[14].second, bind(&CMenuScreen::moveTo, this, CGP->scrs[mainMenu]), 582, 464, "ZTBACK.DEF", SDLK_ESCAPE);
@@ -1823,66 +1823,6 @@ CScenarioInfo::~CScenarioInfo()
 {
 }
 
-CTextInput::CTextInput()
-{
-	bg = NULL;
-	used = 0;
-}
-
-CTextInput::CTextInput( const Rect &Pos, const Point &bgOffset, const std::string &bgName, const CFunctionList<void(const std::string &)> &CB )
-:cb(CB)
-{
-	pos += Pos;
-	OBJ_CONSTRUCTION;
-	bg = new CPicture(bgName, bgOffset.x, bgOffset.y);
-	used = LCLICK | KEYBOARD;
-}
-
-CTextInput::~CTextInput()
-{
-
-}
-
-void CTextInput::showAll( SDL_Surface * to )
-{
-	CIntObject::showAll(to);
-	CSDL_Ext::printAt(text + "_", pos.x, pos.y, FONT_SMALL, zwykly, to);
-}
-
-void CTextInput::clickLeft( tribool down, bool previousState )
-{
-	//TODO
-
-}
-
-void CTextInput::keyPressed( const SDL_KeyboardEvent & key )
-{
-	if(key.state != SDL_PRESSED) return;
-	switch(key.keysym.sym)
-	{
-	case SDLK_BACKSPACE:
-		if(text.size())
-			text.resize(text.size()-1);
-		break;
-	default:
-		char c = key.keysym.unicode; //TODO 16-/>8
-		static const std::string forbiddenChars = "<>:\"/\\|?*"; //if we are entering a filename, some special characters won't be allowed
-		if(!vstd::contains(forbiddenChars,c) && std::isprint(c))
-			text += c;
-		break;
-	}
-	redraw();
-	cb(text);
-}
-
-void CTextInput::setText( const std::string &nText, bool callCb )
-{
-	text = nText;
-	redraw();
-	if(callCb)
-		cb(text);
-}
-
 bool mapSorter::operator()(const CMapInfo *aaa, const CMapInfo *bbb)
 {
 	const CMapHeader * a = aaa->mapHeader,
@@ -1930,4 +1870,38 @@ bool mapSorter::operator()(const CMapInfo *aaa, const CMapInfo *bbb)
 	{
 		return aaa->campaignHeader->name < bbb->campaignHeader->name; //sort by names
 	}
+}
+
+CMultiMode::CMultiMode()
+{
+	OBJ_CONSTRUCTION;
+	bg = new CPicture("MUPOPUP.bmp");
+	bg->convertToScreenBPP(); //so we could draw without problems
+	blitAt(CPicture("MUMAP.bmp"), 16, 77, *bg); //blit img
+	pos = bg->center(); //center, window has size of bg graphic
+
+	CGStatusBar *bar = new CGStatusBar(new CPicture(Rect(7, 465, 440, 18), 0), FONT_SMALL, CLabel::CENTER);//226, 472
+	txt = new CTextInput(Rect(19, 436, 334, 16), *bg);
+	txt->setText(CGI->generaltexth->allTexts[434]); //Player
+
+	btns[0] = new AdventureMapButton(CGI->generaltexth->zelp[266], bind(&CMultiMode::openHotseat, this), 373, 78, "MUBHOT.DEF");
+	btns[6] = new AdventureMapButton(CGI->generaltexth->zelp[288], bind(&CGuiHandler::popInt, ref(GH), this), 373, 424, "MUBCANC.DEF");
+}
+
+void CMultiMode::openHotseat()
+{
+	GH.pushInt(new CHotSeatPlayers(txt->text));
+}
+
+CHotSeatPlayers::CHotSeatPlayers(const std::string &firstPlayer)
+{
+	OBJ_CONSTRUCTION;
+	bg = new CPicture("MUHOTSEA.bmp");
+	bg->convertToScreenBPP(); //so we could draw without problems
+	bg->printAtMiddleWBLoc(CGI->generaltexth->allTexts[446], 185, 55, FONT_BIG, 50, zwykly, *bg); //HOTSEAT	Please enter names
+	pos = bg->center(); //center, window has size of bg graphic
+
+	for(int i = 0; i < ARRAY_COUNT(txt); i++)
+		txt[i] = new CTextInput(Rect(60, 85 + i*30, 280, 16), *bg);
+
 }

+ 22 - 17
client/CPreGame.h

@@ -20,6 +20,7 @@
 struct CMusicHandler;
 class CMapHeader;
 class CCampaignHeader;
+class CTextInput;
 
 class CMapInfo
 {
@@ -48,23 +49,6 @@ public:
 	mapSorter(ESortBy es):sortBy(es){};
 };
 
-class CTextInput : public CIntObject
-{
-public:
-	CPicture *bg;
-	std::string text;
-	CFunctionList<void(const std::string &)> cb;
-
-	void setText(const std::string &nText, bool callCb = false);
-
-	CTextInput();
-	CTextInput(const Rect &Pos, const Point &bgOffset, const std::string &bgName, const CFunctionList<void(const std::string &)> &CB);
-	~CTextInput();
-	void showAll(SDL_Surface * to);
-	void clickLeft(tribool down, bool previousState);
-	void keyPressed(const SDL_KeyboardEvent & key);
-};
-
 class CMenuScreen : public CIntObject
 {
 public:
@@ -241,6 +225,27 @@ public:
 	~CScenarioInfo();
 };
 
+class CMultiMode : public CIntObject
+{
+public:
+	CPicture *bg;
+	CTextInput *txt;
+	AdventureMapButton *btns[7]; //0 - hotseat, 6 - cancel
+
+	CMultiMode();
+	void openHotseat();
+};
+
+class CHotSeatPlayers : public CIntObject
+{
+public:
+	CPicture *bg;
+	CTextInput *txt[8];
+	AdventureMapButton *ok, *cancel;
+
+	CHotSeatPlayers(const std::string &firstPlayer);
+};
+
 class CGPreGame : public CIntObject, public IUpdateable
 {
 public:

+ 47 - 0
client/GUIBase.cpp

@@ -350,6 +350,7 @@ CGuiHandler::CGuiHandler()
 	curInt = NULL;
 	current = NULL;
 	terminate = false;
+	statusbar = NULL;
 }
 
 CGuiHandler::~CGuiHandler()
@@ -577,6 +578,9 @@ CIntObject::~CIntObject()
 		for(size_t i = 0; i < children.size(); i++)
 			if(children[i]->recActions & DISPOSE)
 				delete children[i];
+
+	if(parent)
+		parent->children -= this;
 }
 
 void CIntObject::printAtLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=zwykly*/, SDL_Surface * dst/*=screen*/, bool refresh /*= false*/ )
@@ -721,6 +725,16 @@ CPicture::CPicture( const std::string &bmpname, int x, int y )
 	}
 }
 
+CPicture::CPicture(const Rect &r, const SDL_Color &color, bool screenFormat /*= false*/)
+{
+	createSimpleRect(r, screenFormat, SDL_MapRGB(bg->format, color.r, color.g,color.b));
+}
+
+CPicture::CPicture(const Rect &r, ui32 color, bool screenFormat /*= false*/)
+{
+	createSimpleRect(r, screenFormat, color);
+}
+
 CPicture::~CPicture()
 {
 	if(freeSurf)
@@ -733,6 +747,27 @@ void CPicture::showAll( SDL_Surface * to )
 		blitAt(bg, pos, to);
 }
 
+void CPicture::convertToScreenBPP()
+{
+	SDL_Surface *hlp = bg;
+	bg = SDL_ConvertSurface(hlp,screen->format,0);
+	SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
+	SDL_FreeSurface(hlp);
+}
+
+void CPicture::createSimpleRect(const Rect &r, bool screenFormat, ui32 color)
+{
+	pos += r;
+	pos.w = r.w;
+	pos.h = r.h;
+	if(screenFormat)
+		bg = CSDL_Ext::newSurface(r.w, r.h);
+	else
+		bg = SDL_CreateRGBSurface(SDL_SWSURFACE, r.w, r.h, 8, 0, 0, 0, 0);
+
+	SDL_FillRect(bg, NULL, color);
+}
+
 ObjectConstruction::ObjectConstruction( CIntObject *obj )
 	:myObj(obj)
 {
@@ -805,6 +840,18 @@ bool isArrowKey( SDLKey key )
 	return key >= SDLK_UP && key <= SDLK_LEFT;
 }
 
+CIntObject * moveChildren(CIntObject *obj, CIntObject *from, CIntObject *to, bool adjustPos)
+{
+	assert(vstd::contains(from->children, obj));
+	assert(obj->parent == from);
+	from->children -= obj;
+	to->children.push_back(obj);
+	obj->parent = to;
+	if(adjustPos)
+		obj->pos -= from->pos - to->pos;
+
+	return obj;
+}
 Rect Rect::createCentered( int w, int h )
 {
 	return Rect(screen->w/2 - w/2, screen->h/2 - h/2, w, h);

+ 17 - 2
client/GUIBase.h

@@ -61,7 +61,10 @@ struct Point
 	int x, y;
 
 	//constructors
-	Point(){};
+	Point()
+	{
+		x = y = 0;
+	};
 	Point(int X, int Y)
 		:x(X),y(Y)
 	{};
@@ -426,10 +429,15 @@ public:
 		return bg;
 	}
 
+	CPicture(const Rect &r, const SDL_Color &color, bool screenFormat = false);
+	CPicture(const Rect &r, ui32 color, bool screenFormat = false);
 	CPicture(SDL_Surface *BG, int x, int y, bool Free = true);
-	CPicture(const std::string &bmpname, int x, int y);
+	CPicture(const std::string &bmpname, int x=0, int y=0);
+
+	void createSimpleRect(const Rect &r, bool screenFormat, ui32 color);
 	~CPicture();
 	void showAll(SDL_Surface * to);
+	void convertToScreenBPP();
 };
 
 class CGuiHandler
@@ -437,6 +445,7 @@ class CGuiHandler
 public:
 	timeHandler th;
 	std::list<IShowActivable *> listInt; //list of interfaces - front=foreground; back = background (includes adventure map, window interfaces, all kind of active dialogs, and so on)
+	IStatusBar * statusbar;
 
 	//active GUI elements (listening for events
 	std::list<CIntObject*> lclickable;
@@ -483,6 +492,12 @@ SDLKey arrowToNum(SDLKey key); //converts arrow key to according numpad key
 SDLKey numToDigit(SDLKey key);//converts numpad digit key to normal digit key
 bool isNumKey(SDLKey key, bool number = true); //checks if key is on numpad (numbers - check only for numpad digits)
 bool isArrowKey(SDLKey key); 
+CIntObject *  moveChildren(CIntObject *obj, CIntObject *from, CIntObject *to, bool adjustPos = false);
+
+template <typename T> void pushIntT()
+{
+	GH.pushInt(new T());
+}
 
 extern CGuiHandler GH; //global gui handler
 

+ 170 - 20
client/GUIClasses.cpp

@@ -156,11 +156,11 @@ void CGarrisonSlot::hover (bool on)
 				temp = CGI->generaltexth->tcommands[11]; //Empty
 			}
 		}
-		LOCPLINT->statusbar->print(temp);
+		GH.statusbar->print(temp);
 	}
 	else
 	{
-		LOCPLINT->statusbar->clear();
+		GH.statusbar->clear();
 	}
 }
 
@@ -1571,17 +1571,17 @@ void CTownList::mouseMoved (const SDL_MouseMotionEvent & sEvent)
 	if(isItIn(&arrupp,GH.current->motion.x,GH.current->motion.y))
 	{
 		if (from>0)
-			LOCPLINT->statusbar->print(CGI->generaltexth->zelp[306].first);
+			GH.statusbar->print(CGI->generaltexth->zelp[306].first);
 		else
-			LOCPLINT->statusbar->clear();
+			GH.statusbar->clear();
 		return;
 	}
 	else if(isItIn(&arrdop,GH.current->motion.x,GH.current->motion.y))
 	{
 		if ((items.size()-from)  >  SIZE)
-			LOCPLINT->statusbar->print(CGI->generaltexth->zelp[307].first);
+			GH.statusbar->print(CGI->generaltexth->zelp[307].first);
 		else
-			LOCPLINT->statusbar->clear();
+			GH.statusbar->clear();
 		return;
 	}
 	//if not buttons then towns
@@ -1591,13 +1591,13 @@ void CTownList::mouseMoved (const SDL_MouseMotionEvent & sEvent)
 	int ny = hy/32;
 	if ((ny>=SIZE || ny<0) || (from+ny>=items.size()))
 	{
-		LOCPLINT->statusbar->clear();
+		GH.statusbar->clear();
 		return;
 	};
 	std::string temp = CGI->generaltexth->tcommands[4];
 	boost::algorithm::replace_first(temp,"%s",items[from+ny]->name);
 	temp += ", "+items[from+ny]->town->Name();
-	LOCPLINT->statusbar->print(temp);
+	GH.statusbar->print(temp);
 }
 
 void CTownList::clickLeft(tribool down, bool previousState)
@@ -1891,7 +1891,7 @@ void CRecruitmentWindow::activate()
 	max->activate();
 	cancel->activate();
 	slider->activate();
-	LOCPLINT->statusbar = bar;
+	GH.statusbar = bar;
 }
 
 void CRecruitmentWindow::deactivate()
@@ -3140,7 +3140,7 @@ void CTavernWindow::activate()
 	if(h2.h)
 		h2.activate();
 	recruit->activate();
-	LOCPLINT->statusbar = bar;
+	GH.statusbar = bar;
 }
 
 void CTavernWindow::deactivate()
@@ -3254,9 +3254,9 @@ void CTavernWindow::HeroPortrait::hover( bool on )
 {
 	//Hoverable::hover(on);
 	if(on)
-		LOCPLINT->statusbar->print(hoverName);
+		GH.statusbar->print(hoverName);
 	else
-		LOCPLINT->statusbar->clear();
+		GH.statusbar->clear();
 }
 
 void CInGameConsole::activate()
@@ -3431,7 +3431,7 @@ void CInGameConsole::startEnteringText()
 	enteredText = "_";
 	if(GH.topInt() == LOCPLINT->adventureInt)
 	{
-		LOCPLINT->statusbar->print(enteredText);
+		GH.statusbar->print(enteredText);
 	}
 	else if(LOCPLINT->battleInt)
 	{
@@ -3452,7 +3452,7 @@ void CInGameConsole::endEnteringText(bool printEnteredText)
 	enteredText = "";
 	if(GH.topInt() == LOCPLINT->adventureInt)
 	{
-		LOCPLINT->statusbar->clear();
+		GH.statusbar->clear();
 	}
 	else if(LOCPLINT->battleInt)
 	{
@@ -3465,7 +3465,7 @@ void CInGameConsole::refreshEnteredText()
 {
 	if(GH.topInt() == LOCPLINT->adventureInt)
 	{
-		LOCPLINT->statusbar->print(enteredText);
+		GH.statusbar->print(enteredText);
 	}
 	else if(LOCPLINT->battleInt)
 	{
@@ -3804,9 +3804,9 @@ CArtPlace::~CArtPlace()
 void HoverableArea::hover (bool on)
 {
 	if (on)
-		LOCPLINT->statusbar->print(hoverText);
-	else if (LOCPLINT->statusbar->getCurrent()==hoverText)
-		LOCPLINT->statusbar->clear();
+		GH.statusbar->print(hoverText);
+	else if (GH.statusbar->getCurrent()==hoverText)
+		GH.statusbar->clear();
 }
 
 void HoverableArea::activate()
@@ -4285,7 +4285,7 @@ void CExchangeWindow::activate()
 	for(int b=0; b<primSkillAreas.size(); ++b)
 		primSkillAreas[b]->activate();
 
-	LOCPLINT->statusbar = ourBar;
+	GH.statusbar = ourBar;
 
 	for(int g=0; g<ARRAY_COUNT(questlogButton); g++)
 		questlogButton[g]->activate();
@@ -4847,7 +4847,7 @@ void CArtMerchantWindow::Buy() {}
 void CThievesGuildWindow::activate()
 {
 	CIntObject::activate();
-	LOCPLINT->statusbar = statusBar;
+	GH.statusbar = statusBar;
 }
 
 void CThievesGuildWindow::show(SDL_Surface * to)
@@ -5066,3 +5066,153 @@ void MoraleLuckBox::set( bool morale, const CGHeroInstance *hero, int slot /*= -
 				text += "\n" + mrl[it].second;
 	}
 }
+
+void CLabel::showAll(SDL_Surface * to)
+{
+	CIntObject::showAll(to);
+	if(!text.length())
+		return;
+
+	static void (*printer[3])(const std::string &, int, int, EFonts, SDL_Color, SDL_Surface *, bool) = {&CSDL_Ext::printAt, &CSDL_Ext::printAtMiddle, &CSDL_Ext::printTo}; //array of printing functions
+	printer[alignment](text, pos.x + textOffset.x, pos.y + textOffset.y, font, color, to, false);
+}
+
+CLabel::CLabel(int x, int y, EFonts Font /*= FONT_SMALL*/, EAlignment Align, const SDL_Color &Color /*= zwykly*/, const std::string &Text /*= ""*/)
+:font(Font), color(Color), text(Text), alignment(Align)
+{
+	autoRedraw = true;
+	pos.x += x;
+	pos.y += y;
+	pos.w = pos.h = 0;
+	bg = NULL;
+}
+
+void CLabel::setTxt(const std::string &Txt)
+{
+	text = Txt;
+	if(autoRedraw)
+	{
+		if(bg || !parent)
+			redraw();
+		else
+			parent->redraw();
+	}
+}
+
+void CGStatusBar::print(const std::string & Text)
+{
+	setTxt(Text);
+}
+
+void CGStatusBar::clear()
+{
+	setTxt("");
+}
+
+std::string CGStatusBar::getCurrent()
+{
+	return text;
+}
+
+CGStatusBar::CGStatusBar(int x, int y, EFonts Font /*= FONT_SMALL*/, EAlignment Align, const SDL_Color &Color /*= zwykly*/, const std::string &Text /*= ""*/)
+	: CLabel(x, y, Font, Align, Color, Text)
+{
+	init();
+}
+
+CGStatusBar::CGStatusBar(CPicture *BG, EFonts Font /*= FONT_SMALL*/, EAlignment Align /*= TOPLEFT*/, const SDL_Color &Color /*= zwykly*/)
+	: CLabel(BG->pos.x, BG->pos.y, Font, Align, Color, "")
+{
+	init();
+	bg = BG;
+	moveChildren(bg, bg->parent, this);
+	pos = bg->pos;
+
+	switch(Align)
+	{
+	case CENTER:
+		textOffset = Point(pos.w/2, pos.h/2);
+		break;
+	case BOTTOMRIGHT:
+		textOffset = Point(pos.w, pos.h);
+		break;
+	}
+}
+
+CGStatusBar::~CGStatusBar()
+{
+	GH.statusbar = oldStatusBar;
+}
+
+void CGStatusBar::show(SDL_Surface * to)
+{
+
+}
+
+void CGStatusBar::init()
+{
+	oldStatusBar = GH.statusbar;
+	GH.statusbar = this;
+}
+
+CTextInput::CTextInput( const Rect &Pos, const Point &bgOffset, const std::string &bgName, const CFunctionList<void(const std::string &)> &CB )
+:cb(CB)
+{
+	pos += Pos;
+	OBJ_CONSTRUCTION;
+	bg = new CPicture(bgName, bgOffset.x, bgOffset.y);
+	used = LCLICK | KEYBOARD;
+}
+
+CTextInput::CTextInput(const Rect &Pos, SDL_Surface *srf)
+{
+	pos += Pos;
+	OBJ_CONSTRUCTION;
+	bg = new CPicture(Pos, 0, true);
+	Rect hlp = Pos;
+	SDL_BlitSurface(srf, &hlp, *bg, NULL);
+	pos.w = bg->pos.w;
+	pos.h = bg->pos.h;
+	bg->pos = pos;
+	used = LCLICK | KEYBOARD;
+}
+
+void CTextInput::showAll( SDL_Surface * to )
+{
+	CIntObject::showAll(to);
+	CSDL_Ext::printAt(text + "_", pos.x, pos.y, FONT_SMALL, zwykly, to);
+}
+
+void CTextInput::clickLeft( tribool down, bool previousState )
+{
+	//TODO
+}
+
+void CTextInput::keyPressed( const SDL_KeyboardEvent & key )
+{
+	if(key.state != SDL_PRESSED) return;
+	switch(key.keysym.sym)
+	{
+	case SDLK_BACKSPACE:
+		if(text.size())
+			text.resize(text.size()-1);
+		break;
+	default:
+		char c = key.keysym.unicode; //TODO 16-/>8
+		static const std::string forbiddenChars = "<>:\"/\\|?*"; //if we are entering a filename, some special characters won't be allowed
+		if(!vstd::contains(forbiddenChars,c) && std::isprint(c))
+			text += c;
+		break;
+	}
+	redraw();
+	cb(text);
+}
+
+void CTextInput::setText( const std::string &nText, bool callCb )
+{
+	text = nText;
+	redraw();
+	if(callCb)
+		cb(text);
+}
+

+ 53 - 0
client/GUIClasses.h

@@ -64,6 +64,8 @@ class CArtifactsOfHero;
 class CResDataBar;
 struct SPuzzleInfo;
 
+extern SDL_Color tytulowy, tlo, zwykly ;
+
 class CInfoWindow : public CSimpleWindow //text + comp. + ok button
 { //window able to delete its components when closed
 public:
@@ -258,6 +260,57 @@ public:
 	std::string getCurrent(); //getter for current
 };
 
+class CLabel
+	: public CIntObject
+{
+public:
+	enum EAlignment {TOPLEFT, CENTER, BOTTOMRIGHT} alignment;
+	EFonts font;
+	SDL_Color color;
+	std::string text;
+	CPicture *bg;
+	bool autoRedraw;
+	Point textOffset; //text will be blitted at pos + textOffset with appropriate alignment
+
+	void setTxt(const std::string &Txt);
+	void showAll(SDL_Surface * to); //shows statusbar (with current text)
+	CLabel(int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = zwykly, const std::string &Text =  "");
+};
+
+class CGStatusBar
+	: public CLabel, public IStatusBar
+{
+	void init();
+public:
+	IStatusBar *oldStatusBar;
+
+	//statusbar interface overloads
+	void print(const std::string & Text); //prints text and refreshes statusbar
+	void clear();//clears statusbar and refreshes
+	std::string getCurrent(); //returns currently displayed text
+	void show(SDL_Surface * to); //shows statusbar (with current text)
+
+	CGStatusBar(int x, int y, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = zwykly, const std::string &Text =  "");
+	CGStatusBar(CPicture *BG, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = zwykly); //given CPicture will be captured by created sbar and it's pos will be used as pos for sbar
+
+	~CGStatusBar();
+};
+
+
+class CTextInput : public CLabel
+{
+public:
+	CFunctionList<void(const std::string &)> cb;
+
+	void setText(const std::string &nText, bool callCb = false);
+
+	CTextInput(const Rect &Pos, const Point &bgOffset, const std::string &bgName, const CFunctionList<void(const std::string &)> &CB);
+	CTextInput(const Rect &Pos, SDL_Surface *srf);
+	void showAll(SDL_Surface * to);
+	void clickLeft(tribool down, bool previousState);
+	void keyPressed(const SDL_KeyboardEvent & key);
+};
+
 class CList : public CIntObject
 {
 public:

+ 1 - 1
hch/CSndHandler.cpp

@@ -27,7 +27,7 @@ CMediaHandler::CMediaHandler(std::string fname)
 	try //c-tor of mapped_file_source throws exception on failure
 	{
 		mfile = new boost::iostreams::mapped_file_source(fname);
-	} HANDLE_EXCEPTION
+	} HANDLE_EXCEPTIONC(tlog1 << "Cannot open " << fname << std::endl)
 	if (!mfile->is_open()) //just in case
 	{
 		tlog1 << "Cannot open " << fname << std::endl;