Browse Source

* VCAI: can't request actions from action handling thread
* Save game screen and returning to main menu will work if game was started with --start option
* GUI controls can selectively capture keyboard events. CTextInput won't capture Enter. Fixes #654.

Michał W. Urbańczyk 13 years ago
parent
commit
6db3c5bc7e

+ 3 - 1
AI/VCAI/VCAI.cpp

@@ -788,7 +788,9 @@ void VCAI::showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *do
 	NET_EVENT_HANDLER;
 	LOG_ENTRY;
 	status.addQuery();
-	pickBestCreatures (down, up);
+
+	//you can't request action from action-response thread
+	//pickBestCreatures (down, up);
 	onEnd();
 }
 

+ 1 - 0
client/CMT.cpp

@@ -716,6 +716,7 @@ static void listenForEvents()
 				const_cast<CGameInfo*>(CGI)->dobjinfo = new CDefObjInfoHandler;
 				const_cast<CGameInfo*>(CGI)->dobjinfo->load();
 
+				CGPreGame::createIfNotPresent();
 				GH.curInt = CGP;
 				GH.defActionsDef = 63;
 				break;

+ 9 - 1
client/CPreGame.cpp

@@ -401,10 +401,12 @@ CGPreGame::CGPreGame():
 	GH.defActionsDef = 63;
 	CGP = this;
 	menu = new CMenuScreen((*pregameConfig)["window"]);
+	loadGraphics();
 }
 
 CGPreGame::~CGPreGame()
 {
+	disposeGraphics();
 }
 
 void CGPreGame::openSel(CMenuScreen::EState screenType, CMenuScreen::EMultiMode multi /*= CMenuScreen::SINGLE_PLAYER*/)
@@ -475,10 +477,17 @@ void CGPreGame::openCampaignScreen(std::string name)
 	tlog1<<"Unknown campaign set: "<<name<<"\n";
 }
 
+void CGPreGame::createIfNotPresent()
+{
+	if(!CGP)
+		CGP = new CGPreGame();
+}
+
 CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMultiMode MultiPlayer /*= CMenuScreen::SINGLE_PLAYER*/, const std::map<ui32, std::string> *Names /*= NULL*/)
 	: ISelectionScreenInfo(Names), serverHandlingThread(NULL), mx(new boost::recursive_mutex),
 	  serv(NULL), ongoingClosing(false), myNameID(255)
 {
+	CGPreGame::createIfNotPresent(); //we depend on its graphics
 	screenType = Type;
 	multiPlayer = MultiPlayer;
 
@@ -514,7 +523,6 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti
 		bg = new CPicture(BitmapHandler::loadBitmap(rand()%2 ? "ZPIC1000.bmp" : "ZPIC1001.bmp"), -3, -6, true);
 	}
 
-	CGP->loadGraphics();
 	sInfo.difficulty = 1;
 	current = NULL;
 

+ 2 - 0
client/CPreGame.h

@@ -501,6 +501,8 @@ public:
 	void disposeGraphics();
 
 	void openCampaignScreen(std::string name);
+
+	static void createIfNotPresent();
 };
 
 extern ISelectionScreenInfo *SEL;

+ 2 - 2
client/UIFramework/CGuiHandler.cpp

@@ -168,7 +168,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
 		bool keysCaptured = false;
 		for(std::list<CIntObject*>::iterator i=keyinterested.begin(); i != keyinterested.end() && current; i++)
 		{
-			if((*i)->captureAllKeys)
+			if((*i)->captureThisEvent(key))
 			{
 				keysCaptured = true;
 				break;
@@ -177,7 +177,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
 
 		std::list<CIntObject*> miCopy = keyinterested;
 		for(std::list<CIntObject*>::iterator i=miCopy.begin(); i != miCopy.end() && current; i++)
-			if(vstd::contains(keyinterested,*i) && (!keysCaptured || (*i)->captureAllKeys))
+			if(vstd::contains(keyinterested,*i) && (!keysCaptured || (*i)->captureThisEvent(key)))
 				(**i).keyPressed(key);
 	}
 	else if(sEvent->type==SDL_MOUSEMOTION)

+ 5 - 0
client/UIFramework/CIntObject.cpp

@@ -442,6 +442,11 @@ const Rect & CIntObject::center(const Point &p, bool propagate /*= true*/)
 	return pos;
 }
 
+bool CIntObject::captureThisEvent(const SDL_KeyboardEvent & key)
+{
+	return captureAllKeys;
+}
+
 void CKeyShortcut::keyPressed(const SDL_KeyboardEvent & key)
 {
 	if(vstd::contains(assignedKeys,key.keysym.sym))

+ 1 - 0
client/UIFramework/CIntObject.h

@@ -104,6 +104,7 @@ public:
 	void activateKeys();
 	void deactivateKeys();
 	virtual void keyPressed(const SDL_KeyboardEvent & key);
+	virtual bool captureThisEvent(const SDL_KeyboardEvent & key); //allows refining captureAllKeys against specific events (eg. don't capture ENTER)
 
 	//mouse movement handling
 	bool strongInterest; //if true - report all mouse movements, if not - only when hovered

+ 8 - 0
client/UIFramework/CIntObjectClasses.cpp

@@ -1470,6 +1470,14 @@ CTextInput::~CTextInput()
 {
 }
 
+bool CTextInput::captureThisEvent(const SDL_KeyboardEvent & key)
+{
+	if(key.keysym.sym == SDLK_RETURN || key.keysym.sym == SDLK_KP_ENTER)
+		return false;
+
+	return true;
+}
+
 CFocusable::CFocusable()
 {
 	focusables.push_back(this);

+ 5 - 3
client/UIFramework/CIntObjectClasses.h

@@ -405,9 +405,11 @@ public:
 	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 = NULL);
 	~CTextInput();
-	void showAll(SDL_Surface * to);
-	void clickLeft(tribool down, bool previousState);
-	void keyPressed(const SDL_KeyboardEvent & key);
+
+	void showAll(SDL_Surface * to) OVERRIDE;
+	void clickLeft(tribool down, bool previousState) OVERRIDE;
+	void keyPressed(const SDL_KeyboardEvent & key) OVERRIDE;
+	bool captureThisEvent(const SDL_KeyboardEvent & key) OVERRIDE;
 };
 
 /// Listbox UI Element