浏览代码

changes to status bar according to review comments:

- renamed IStatusBar API to more clear names
- removed "locking" of status bar
- added comments for IStatusBar API
- removed dynamic_casts to CGStatusBar, now IStatusBar API is fully
sufficient
Ivan Savenko 2 年之前
父节点
当前提交
d40d5250b7

+ 55 - 24
client/battle/BattleInterfaceClasses.cpp

@@ -47,23 +47,28 @@
 
 void BattleConsole::showAll(SDL_Surface * to)
 {
-	Point textPos(pos.x + pos.w/2, pos.y + 17);
+	Point consolePos(pos.x + 10,      pos.y + 17);
+	Point textPos   (pos.x + pos.w/2, pos.y + 17);
 
-	if(ingcAlter.size())
+	if (!consoleText.empty())
 	{
-		graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(ingcAlter, pos.w, FONT_SMALL), Colors::WHITE, textPos);
+		graphics->fonts[FONT_SMALL]->renderTextLinesLeft(to, CMessage::breakText(consoleText, pos.w, FONT_SMALL), Colors::WHITE, consolePos);
 	}
-	else if(texts.size())
+	else if(!hoverText.empty())
 	{
-		if(texts.size()==1)
+		graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(hoverText, pos.w, FONT_SMALL), Colors::WHITE, textPos);
+	}
+	else if(logEntries.size())
+	{
+		if(logEntries.size()==1)
 		{
-			graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(texts[0], pos.w, FONT_SMALL), Colors::WHITE, textPos);
+			graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(logEntries[0], pos.w, FONT_SMALL), Colors::WHITE, textPos);
 		}
 		else
 		{
-			graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(texts[lastShown - 1], pos.w, FONT_SMALL), Colors::WHITE, textPos);
+			graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(logEntries[scrollPosition - 1], pos.w, FONT_SMALL), Colors::WHITE, textPos);
 			textPos.y += 16;
-			graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(texts[lastShown], pos.w, FONT_SMALL), Colors::WHITE, textPos);
+			graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(logEntries[scrollPosition], pos.w, FONT_SMALL), Colors::WHITE, textPos);
 		}
 	}
 }
@@ -78,53 +83,79 @@ bool BattleConsole::addText(const std::string & text)
 	{
 		if(text[i] == 10)
 		{
-			texts.push_back( text.substr(firstInToken, i-firstInToken) );
+			logEntries.push_back( text.substr(firstInToken, i-firstInToken) );
 			firstInToken = (int)i+1;
 		}
 	}
 
-	texts.push_back( text.substr(firstInToken, text.size()) );
-	lastShown = (int)texts.size()-1;
+	logEntries.push_back( text.substr(firstInToken, text.size()) );
+	scrollPosition = (int)logEntries.size()-1;
 	return true;
 }
 void BattleConsole::scrollUp(ui32 by)
 {
-	if(lastShown > static_cast<int>(by))
-		lastShown -= by;
+	if(scrollPosition > static_cast<int>(by))
+		scrollPosition -= by;
 }
 
 void BattleConsole::scrollDown(ui32 by)
 {
-	if(lastShown + by < texts.size())
-		lastShown += by;
+	if(scrollPosition + by < logEntries.size())
+		scrollPosition += by;
 }
 
-BattleConsole::BattleConsole(const Rect & position) : lastShown(-1)
+BattleConsole::BattleConsole(const Rect & position)
+	: scrollPosition(-1)
+	, enteringText(false)
 {
 	pos += position.topLeft();
 	pos.w = position.w;
 	pos.h = position.h;
 }
 
-void BattleConsole::clearIfMatching(const std::string & Text)
+BattleConsole::~BattleConsole()
 {
-	if (ingcAlter == Text)
-		clear();
+	if (enteringText)
+		setEnteringMode(false);
 }
 
-void BattleConsole::clear()
+void BattleConsole::setEnteringMode(bool on)
 {
-	ingcAlter.clear();
+	consoleText.clear();
+
+	if (on)
+	{
+		assert(enteringText == false);
+		CSDL_Ext::startTextInput(&pos);
+	}
+	else
+	{
+		assert(enteringText == true);
+		CSDL_Ext::stopTextInput();
+	}
+	enteringText = on;
+}
+
+void BattleConsole::setEnteredText(const std::string & text)
+{
+	assert(enteringText == true);
+	consoleText = text;
 }
 
 void BattleConsole::write(const std::string & Text)
 {
-	ingcAlter = Text;
+	hoverText = Text;
+}
+
+void BattleConsole::clearIfMatching(const std::string & Text)
+{
+	if (hoverText == Text)
+		clear();
 }
 
-void BattleConsole::lock(bool shouldLock)
+void BattleConsole::clear()
 {
-	// no-op?
+	write({});
 }
 
 void BattleHero::render(Canvas & canvas)

+ 19 - 7
client/battle/BattleInterfaceClasses.h

@@ -43,23 +43,35 @@ class CPlayerInterface;
 class BattleConsole : public CIntObject, public IStatusBar
 {
 private:
-	std::vector< std::string > texts; //a place where texts are stored
-	int lastShown; //last shown line of text
+	/// List of all texts added during battle, essentially - log of entire battle
+	std::vector< std::string > logEntries;
 
-	std::string ingcAlter; //alternative text set by in-game console - very important!
+	/// Current scrolling position, to allow showing older entries via scroll buttons
+	int scrollPosition;
+
+	/// current hover text set on mouse move, takes priority over log entries
+	std::string hoverText;
+
+	/// current text entered via in-game console, takes priority over both log entries and hover text
+	std::string consoleText;
+
+	/// if true then we are currently entering console text
+	bool enteringText;
 public:
 	BattleConsole(const Rect & position);
-	void showAll(SDL_Surface * to = 0) override;
+	~BattleConsole();
+	void showAll(SDL_Surface * to) override;
 
 	bool addText(const std::string &text); //adds text at the last position; returns false if failed (e.g. text longer than 70 characters)
 	void scrollUp(ui32 by = 1); //scrolls console up by 'by' positions
 	void scrollDown(ui32 by = 1); //scrolls console up by 'by' positions
 
+	// IStatusBar interface
+	void write(const std::string & Text) override;
 	void clearIfMatching(const std::string & Text) override;
 	void clear() override;
-	void write(const std::string & Text) override;
-	void lock(bool shouldLock) override;
-
+	void setEnteringMode(bool on) override;
+	void setEnteredText(const std::string & text) override;
 };
 
 /// Hero battle animation

+ 15 - 3
client/gui/CIntObject.h

@@ -220,8 +220,20 @@ class IStatusBar
 {
 public:
 	virtual ~IStatusBar();
+
+	/// set current text for the status bar
+	virtual void write(const std::string & text) = 0;
+
+	/// remove any current text from the status bar
 	virtual void clear() = 0;
-	virtual void clearIfMatching(const std::string & Text) = 0;
-	virtual void write(const std::string & Text) = 0;
-	virtual void lock(bool shouldLock) = 0;
+
+	/// remove text from status bar if current text matches tested text
+	virtual void clearIfMatching(const std::string & testedText) = 0;
+
+	/// enables mode for entering text instead of showing hover text
+	virtual void setEnteringMode(bool on) = 0;
+
+	/// overrides hover text from controls with text entered into in-game console (for chat/cheats)
+	virtual void setEnteredText(const std::string & text) = 0;
+
 };

+ 7 - 30
client/widgets/AdventureMapClasses.cpp

@@ -1126,54 +1126,31 @@ void CInGameConsole::textEdited(const SDL_TextEditingEvent & event)
 
 void CInGameConsole::startEnteringText()
 {
-	auto statusBar = std::dynamic_pointer_cast<CGStatusBar>(GH.statusbar);
+	assert(GH.statusbar);
+	captureAllKeys = true;
+	enteredText = "_";
 
-	if (statusBar)
-	{
-		captureAllKeys = true;
-
-		CSDL_Ext::startTextInput(&statusBar->pos);
-
-		enteredText = "_";
-
-		statusBar->alignment = ETextAlignment::TOPLEFT;
-		statusBar->write(enteredText);
-		statusBar->lock(true);
-	}
+	GH.statusbar->setEnteringMode(true);
+	GH.statusbar->setEnteredText(enteredText);
 }
 
 void CInGameConsole::endEnteringText(bool printEnteredText)
 {
 	captureAllKeys = false;
-
-	CSDL_Ext::stopTextInput();
-
 	prevEntDisp = -1;
 	if(printEnteredText)
 	{
 		std::string txt = enteredText.substr(0, enteredText.size()-1);
 		LOCPLINT->cb->sendMessage(txt, LOCPLINT->getSelection());
 		previouslyEntered.push_back(txt);
-		//print(txt);
 	}
 	enteredText.clear();
-
-	auto statusBar = std::dynamic_pointer_cast<CGStatusBar>(GH.statusbar);
-
-	if(statusBar)
-	{
-		statusBar->alignment = ETextAlignment::CENTER;
-	}
-	GH.statusbar->lock(false);
-	GH.statusbar->clear();
+	GH.statusbar->setEnteringMode(false);
 }
 
 void CInGameConsole::refreshEnteredText()
 {
-	GH.statusbar->lock(false);
-	GH.statusbar->clear();
-	GH.statusbar->write(enteredText);
-	GH.statusbar->lock(true);
+	GH.statusbar->setEnteredText(enteredText);
 }
 
 CAdvMapPanel::CAdvMapPanel(SDL_Surface * bg, Point position)

+ 36 - 11
client/widgets/TextControls.cpp

@@ -339,36 +339,67 @@ void CTextBox::setText(const std::string & text)
 	}
 }
 
+void CGStatusBar::setEnteringMode(bool on)
+{
+	consoleText.clear();
+
+	if (on)
+	{
+		assert(enteringText == false);
+		alignment = ETextAlignment::TOPLEFT;
+		CSDL_Ext::startTextInput(&pos);
+		setText(consoleText);
+	}
+	else
+	{
+		assert(enteringText == true);
+		alignment = ETextAlignment::CENTER;
+		CSDL_Ext::stopTextInput();
+		setText(hoverText);
+	}
+	enteringText = on;
+}
+
+void CGStatusBar::setEnteredText(const std::string & text)
+{
+	assert(enteringText == true);
+	consoleText = text;
+	setText(text);
+}
+
 void CGStatusBar::write(const std::string & Text)
 {
-	if(!textLock)
-		CLabel::setText(Text);
+	hoverText = Text;
+
+	if (enteringText == false)
+		setText(hoverText);
 }
 
 void CGStatusBar::clearIfMatching(const std::string & Text)
 {
-	if (getText() == Text)
+	if (hoverText == Text)
 		clear();
 }
 
 void CGStatusBar::clear()
 {
-	setText("");
+	write({});
 }
 
 CGStatusBar::CGStatusBar(std::shared_ptr<CPicture> background_, EFonts Font, ETextAlignment Align, const SDL_Color & Color)
 	: CLabel(background_->pos.x, background_->pos.y, Font, Align, Color, "")
+	, enteringText(false)
 {
 	background = background_;
 	addChild(background.get());
 	pos = background->pos;
 	getBorderSize();
-	textLock = false;
 	autoRedraw = false;
 }
 
 CGStatusBar::CGStatusBar(int x, int y, std::string name, int maxw)
 	: CLabel(x, y, FONT_SMALL, ETextAlignment::CENTER)
+	, enteringText(false)
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
 	background = std::make_shared<CPicture>(name);
@@ -380,7 +411,6 @@ CGStatusBar::CGStatusBar(int x, int y, std::string name, int maxw)
 		vstd::amin(pos.w, maxw);
 		background->srcRect = new Rect(0, 0, maxw, pos.h);
 	}
-	textLock = false;
 	autoRedraw = false;
 }
 
@@ -423,11 +453,6 @@ Point CGStatusBar::getBorderSize()
 	return Point();
 }
 
-void CGStatusBar::lock(bool shouldLock)
-{
-	textLock = shouldLock;
-}
-
 CTextInput::CTextInput(const Rect & Pos, EFonts font, const CFunctionList<void(const std::string &)> & CB)
 	: CLabel(Pos.x, Pos.y, font, ETextAlignment::CENTER),
 	cb(CB),

+ 13 - 7
client/widgets/TextControls.h

@@ -116,7 +116,10 @@ public:
 /// Status bar which is shown at the bottom of the in-game screens
 class CGStatusBar : public CLabel, public std::enable_shared_from_this<CGStatusBar>, public IStatusBar
 {
-	bool textLock; //Used for blocking changes to the text
+	std::string hoverText;
+	std::string consoleText;
+	bool enteringText;
+
 	void init();
 
 	CGStatusBar(std::shared_ptr<CPicture> background_, EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::CENTER, const SDL_Color & Color = Colors::WHITE);
@@ -138,14 +141,17 @@ public:
 		return ret;
 	}
 
-	void clearIfMatching(const std::string & Text) override;
-	void clear() override;//clears statusbar and refreshes
-	void write(const std::string & Text) override; //prints text and refreshes statusbar
+	void setOnClick(std::function<void()> handler);
 
-	void show(SDL_Surface * to) override; //shows statusbar (with current text)
+	void show(SDL_Surface * to) override;
+
+	// IStatusBar interface
+	void write(const std::string & Text) override;
+	void clearIfMatching(const std::string & Text) override;
+	void clear() override;
+	void setEnteringMode(bool on) override;
+	void setEnteredText(const std::string & text) override;
 
-	void lock(bool shouldLock) override; //If true, current text cannot be changed until lock(false) is called
-	void setOnClick(std::function<void()> handler);
 };
 
 class CFocusable;