forked from mirror/openmw-tes3mp
display text on the book window
This commit is contained in:
parent
d69501b061
commit
8a9e05a96b
7 changed files with 223 additions and 27 deletions
|
@ -7,6 +7,8 @@
|
||||||
#include "../mwsound/soundmanager.hpp"
|
#include "../mwsound/soundmanager.hpp"
|
||||||
#include "../mwworld/actiontake.hpp"
|
#include "../mwworld/actiontake.hpp"
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
using namespace MWGui;
|
using namespace MWGui;
|
||||||
|
|
||||||
BookWindow::BookWindow (WindowManager& parWindowManager) :
|
BookWindow::BookWindow (WindowManager& parWindowManager) :
|
||||||
|
@ -24,20 +26,57 @@ BookWindow::BookWindow (WindowManager& parWindowManager) :
|
||||||
getWidget(mPrevPageButton, "PrevPageBTN");
|
getWidget(mPrevPageButton, "PrevPageBTN");
|
||||||
mPrevPageButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onPrevPageButtonClicked);
|
mPrevPageButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onPrevPageButtonClicked);
|
||||||
|
|
||||||
|
getWidget(mLeftPageNumber, "LeftPageNumber");
|
||||||
|
getWidget(mRightPageNumber, "RightPageNumber");
|
||||||
|
|
||||||
|
getWidget(mLeftPage, "LeftPage");
|
||||||
|
getWidget(mRightPage, "RightPage");
|
||||||
|
|
||||||
center();
|
center();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BookWindow::clearPages()
|
||||||
|
{
|
||||||
|
for (std::vector<MyGUI::Widget*>::iterator it=mPages.begin();
|
||||||
|
it!=mPages.end(); ++it)
|
||||||
|
{
|
||||||
|
MyGUI::Gui::getInstance().destroyWidget(*it);
|
||||||
|
}
|
||||||
|
mPages.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void BookWindow::open (MWWorld::Ptr book)
|
void BookWindow::open (MWWorld::Ptr book)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getSoundManager()->playSound3D (book, "book open", 1.0, 1.0);
|
|
||||||
|
|
||||||
mBook = book;
|
mBook = book;
|
||||||
|
|
||||||
|
clearPages();
|
||||||
|
mCurrentPage = 0;
|
||||||
|
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound3D (book, "book open", 1.0, 1.0);
|
||||||
|
|
||||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||||
mBook.get<ESM::Book>();
|
mBook.get<ESM::Book>();
|
||||||
|
|
||||||
//BookTextParser parser;
|
BookTextParser parser;
|
||||||
//parser.parse(ref->base->text, 0, 0);
|
std::vector<std::string> results = parser.split(ref->base->text, mLeftPage->getSize().width, mLeftPage->getSize().height);
|
||||||
|
|
||||||
|
int i=0;
|
||||||
|
for (std::vector<std::string>::iterator it=results.begin();
|
||||||
|
it!=results.end(); ++it)
|
||||||
|
{
|
||||||
|
MyGUI::Widget* parent;
|
||||||
|
if (i%2 == 0)
|
||||||
|
parent = mLeftPage;
|
||||||
|
else
|
||||||
|
parent = mRightPage;
|
||||||
|
|
||||||
|
MyGUI::Widget* pageWidget = parent->createWidgetReal<MyGUI::Widget>("", MyGUI::FloatCoord(0.0,0.0,1.0,1.0), MyGUI::Align::Default, "BookPage" + boost::lexical_cast<std::string>(i));
|
||||||
|
parser.parse(*it, pageWidget, mLeftPage->getSize().width);
|
||||||
|
mPages.push_back(pageWidget);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePages();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BookWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
|
void BookWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
|
||||||
|
@ -54,15 +93,48 @@ void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||||
MWWorld::ActionTake take(mBook);
|
MWWorld::ActionTake take(mBook);
|
||||||
take.execute();
|
take.execute();
|
||||||
|
|
||||||
/// \todo what about scripts?
|
|
||||||
|
|
||||||
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BookWindow::onNextPageButtonClicked (MyGUI::Widget* _sender)
|
void BookWindow::onNextPageButtonClicked (MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
|
if ((mCurrentPage+1)*2 < mPages.size())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound ("book page2", 1.0, 1.0);
|
||||||
|
|
||||||
|
++mCurrentPage;
|
||||||
|
|
||||||
|
updatePages();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* _sender)
|
void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
|
if (mCurrentPage > 0)
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound ("book page", 1.0, 1.0);
|
||||||
|
|
||||||
|
--mCurrentPage;
|
||||||
|
|
||||||
|
updatePages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BookWindow::updatePages()
|
||||||
|
{
|
||||||
|
mLeftPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 1) );
|
||||||
|
mRightPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 2) );
|
||||||
|
|
||||||
|
unsigned int i=0;
|
||||||
|
for (std::vector<MyGUI::Widget*>::iterator it = mPages.begin();
|
||||||
|
it != mPages.end(); ++it)
|
||||||
|
{
|
||||||
|
if (mCurrentPage*2 == i || mCurrentPage*2+1 == i)
|
||||||
|
(*it)->setVisible(true);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*it)->setVisible(false);
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,21 @@ namespace MWGui
|
||||||
void onCloseButtonClicked (MyGUI::Widget* _sender);
|
void onCloseButtonClicked (MyGUI::Widget* _sender);
|
||||||
void onTakeButtonClicked (MyGUI::Widget* _sender);
|
void onTakeButtonClicked (MyGUI::Widget* _sender);
|
||||||
|
|
||||||
|
void updatePages();
|
||||||
|
void clearPages();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MyGUI::Button* mCloseButton;
|
MyGUI::Button* mCloseButton;
|
||||||
MyGUI::Button* mTakeButton;
|
MyGUI::Button* mTakeButton;
|
||||||
MyGUI::Button* mNextPageButton;
|
MyGUI::Button* mNextPageButton;
|
||||||
MyGUI::Button* mPrevPageButton;
|
MyGUI::Button* mPrevPageButton;
|
||||||
|
MyGUI::TextBox* mLeftPageNumber;
|
||||||
|
MyGUI::TextBox* mRightPageNumber;
|
||||||
|
MyGUI::Widget* mLeftPage;
|
||||||
|
MyGUI::Widget* mRightPage;
|
||||||
|
|
||||||
|
unsigned int mCurrentPage; // 0 is first page
|
||||||
|
std::vector<MyGUI::Widget*> mPages;
|
||||||
|
|
||||||
MWWorld::Ptr mBook;
|
MWWorld::Ptr mBook;
|
||||||
};
|
};
|
||||||
|
|
|
@ -65,6 +65,107 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> BookTextParser::split(std::string text, const int width, const int height)
|
||||||
|
{
|
||||||
|
std::vector<std::string> result;
|
||||||
|
|
||||||
|
boost::algorithm::replace_all(text, "<BR>", "\n");
|
||||||
|
boost::algorithm::replace_all(text, "<P>", "\n\n");
|
||||||
|
|
||||||
|
const int spacing = 48;
|
||||||
|
|
||||||
|
while (text.size() > 0)
|
||||||
|
{
|
||||||
|
// read in characters until we have exceeded the size, or run out of text
|
||||||
|
int currentWidth = 0;
|
||||||
|
int currentHeight = 0;
|
||||||
|
std::string currentText;
|
||||||
|
std::string currentWord;
|
||||||
|
|
||||||
|
unsigned int i=0;
|
||||||
|
while (currentHeight <= height-spacing && i<text.size())
|
||||||
|
{
|
||||||
|
if (text[i] == '<')
|
||||||
|
{
|
||||||
|
if (text.find('>', i) == std::string::npos)
|
||||||
|
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
|
||||||
|
|
||||||
|
if (text.size() > i+4 && text.substr(i, 4) == "<IMG")
|
||||||
|
{
|
||||||
|
int h = mHeight;
|
||||||
|
parseImage(text.substr(i, text.find('>', i)-i), false);
|
||||||
|
currentHeight += (mHeight-h);
|
||||||
|
currentWidth = 0;
|
||||||
|
}
|
||||||
|
else if (text.size() > i+5 && text.substr(i, 5) == "<FONT")
|
||||||
|
{
|
||||||
|
parseFont(text.substr(i, text.find('>', i)-i));
|
||||||
|
currentHeight += 18; // keep this in sync with the font size
|
||||||
|
currentWidth = 0;
|
||||||
|
}
|
||||||
|
else if (text.size() > i+4 && text.substr(i, 4) == "<DIV")
|
||||||
|
{
|
||||||
|
parseDiv(text.substr(i, text.find('>', i)-i));
|
||||||
|
currentHeight += 18; // keep this in sync with the font size
|
||||||
|
currentWidth = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentText += text.substr(i, text.find('>', i)-i+1);
|
||||||
|
i = text.find('>', i);
|
||||||
|
}
|
||||||
|
else if (text[i] == '\n')
|
||||||
|
{
|
||||||
|
currentHeight += 18; // keep this in sync with the font size
|
||||||
|
currentWidth = 0;
|
||||||
|
currentWord = "";
|
||||||
|
currentText += text[i];
|
||||||
|
}
|
||||||
|
else if (text[i] == ' ')
|
||||||
|
{
|
||||||
|
currentWidth += 3; // keep this in sync with the font's SpaceWidth property
|
||||||
|
currentWord = "";
|
||||||
|
currentText += text[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentWidth +=
|
||||||
|
MyGUI::FontManager::getInstance().getByName (mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont)
|
||||||
|
->getGlyphInfo(static_cast<unsigned int>(text[i]))->width;
|
||||||
|
currentWord += text[i];
|
||||||
|
currentText += text[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentWidth > width)
|
||||||
|
{
|
||||||
|
currentHeight += 18; // keep this in sync with the font size
|
||||||
|
currentWidth = 0;
|
||||||
|
|
||||||
|
// add size of the current word
|
||||||
|
unsigned int j=0;
|
||||||
|
while (j<currentWord.size())
|
||||||
|
{
|
||||||
|
currentWidth +=
|
||||||
|
MyGUI::FontManager::getInstance().getByName (mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont)
|
||||||
|
->getGlyphInfo(static_cast<unsigned int>(currentWord[j]))->width;
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
if (currentHeight > height-spacing)
|
||||||
|
{
|
||||||
|
// remove the last word
|
||||||
|
currentText.erase(currentText.size()-currentWord.size(), currentText.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push_back(currentText);
|
||||||
|
text.erase(0, currentText.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
MyGUI::IntSize BookTextParser::parse(std::string text, MyGUI::Widget* parent, const int width)
|
MyGUI::IntSize BookTextParser::parse(std::string text, MyGUI::Widget* parent, const int width)
|
||||||
{
|
{
|
||||||
mParent = parent;
|
mParent = parent;
|
||||||
|
@ -92,7 +193,7 @@ MyGUI::IntSize BookTextParser::parse(std::string text, MyGUI::Widget* parent, co
|
||||||
return MyGUI::IntSize(mWidth, mHeight);
|
return MyGUI::IntSize(mWidth, mHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BookTextParser::parseImage(std::string tag)
|
void BookTextParser::parseImage(std::string tag, bool createWidget)
|
||||||
{
|
{
|
||||||
int src_start = tag.find("SRC=")+5;
|
int src_start = tag.find("SRC=")+5;
|
||||||
std::string image = tag.substr(src_start, tag.find('"', src_start)-src_start);
|
std::string image = tag.substr(src_start, tag.find('"', src_start)-src_start);
|
||||||
|
@ -111,11 +212,14 @@ void BookTextParser::parseImage(std::string tag)
|
||||||
int height_start = tag.find("HEIGHT=")+8;
|
int height_start = tag.find("HEIGHT=")+8;
|
||||||
int height = boost::lexical_cast<int>(tag.substr(height_start, tag.find('"', height_start)-height_start));
|
int height = boost::lexical_cast<int>(tag.substr(height_start, tag.find('"', height_start)-height_start));
|
||||||
|
|
||||||
MyGUI::ImageBox* box = mParent->createWidget<MyGUI::ImageBox> ("ImageBox",
|
if (createWidget)
|
||||||
MyGUI::IntCoord(0, mHeight, width, height), MyGUI::Align::Left | MyGUI::Align::Top,
|
{
|
||||||
mParent->getName() + boost::lexical_cast<std::string>(mParent->getChildCount()));
|
MyGUI::ImageBox* box = mParent->createWidget<MyGUI::ImageBox> ("ImageBox",
|
||||||
box->setImageTexture("bookart\\" + image);
|
MyGUI::IntCoord(0, mHeight, width, height), MyGUI::Align::Left | MyGUI::Align::Top,
|
||||||
box->setProperty("NeedMouse", "false");
|
mParent->getName() + boost::lexical_cast<std::string>(mParent->getChildCount()));
|
||||||
|
box->setImageTexture("bookart\\" + image);
|
||||||
|
box->setProperty("NeedMouse", "false");
|
||||||
|
}
|
||||||
|
|
||||||
mWidth = std::max(mWidth, width);
|
mWidth = std::max(mWidth, width);
|
||||||
mHeight += height;
|
mHeight += height;
|
||||||
|
|
|
@ -36,10 +36,15 @@ namespace MWGui
|
||||||
*/
|
*/
|
||||||
MyGUI::IntSize parse(std::string text, MyGUI::Widget* parent, const int width);
|
MyGUI::IntSize parse(std::string text, MyGUI::Widget* parent, const int width);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split the specified text into pieces that fit in the area specified by width and height parameters
|
||||||
|
*/
|
||||||
|
std::vector<std::string> split(std::string text, const int width, const int height);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void parseSubText(std::string text);
|
void parseSubText(std::string text);
|
||||||
|
|
||||||
void parseImage(std::string tag);
|
void parseImage(std::string tag, bool createWidget=true);
|
||||||
void parseDiv(std::string tag);
|
void parseDiv(std::string tag);
|
||||||
void parseFont(std::string tag);
|
void parseFont(std::string tag);
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -57,7 +57,5 @@ void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||||
MWWorld::ActionTake take(mScroll);
|
MWWorld::ActionTake take(mScroll);
|
||||||
take.execute();
|
take.execute();
|
||||||
|
|
||||||
/// \todo what about scripts?
|
|
||||||
|
|
||||||
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,15 @@
|
||||||
<Property key="ImageResource" value="MenuBook_Close"/>
|
<Property key="ImageResource" value="MenuBook_Close"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
<Widget type="EditBox" skin="MW_BookPage" position_real="0.15 0.1 0.3 0.8" name = "LeftText"/>
|
<Widget type="TextBox" skin="NormalText" position="155 215 24 24" name="LeftPageNumber">
|
||||||
<Widget type="EditBox" skin="MW_BookPage" position_real="0.55 0.1 0.3 0.8" name = "RightText"/>
|
<Property key="TextColour" value="0 0 0"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="TextBox" skin="NormalText" position="325 215 24 24" name="RightPageNumber">
|
||||||
|
<Property key="TextColour" value="0 0 0"/>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="Widget" skin="" position_real="0.15 0.1 0.3 0.75" name = "LeftPage"/>
|
||||||
|
<Widget type="Widget" skin="" position_real="0.55 0.1 0.3 0.75" name = "RightPage"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
<Widget type="Button" skin="ButtonImage" position="80 220 96 24" name="PrevPageBTN">
|
<Widget type="Button" skin="ButtonImage" position="80 220 96 24" name="PrevPageBTN">
|
||||||
<Property key="ImageResource" value="MenuBook_Prev"/>
|
<Property key="ImageResource" value="MenuBook_Prev"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="EditBox" skin="MW_BookPage" position_real="0.15 0.1 0.3 0.8" name = "LeftText"/>
|
<Widget type="EditBox" skin="MW_BookPage" position_real="0.15 0.1 0.3 0.75" name = "LeftText"/>
|
||||||
<Widget type="EditBox" skin="MW_BookPage" position_real="0.55 0.1 0.3 0.8" name = "RightText"/>
|
<Widget type="EditBox" skin="MW_BookPage" position_real="0.55 0.1 0.3 0.75" name = "RightText"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue