1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-30 22:45:34 +00:00

Merge remote-tracking branch 'miroslavr/master'

This commit is contained in:
Marc Zinnschlag 2014-10-04 09:46:29 +02:00
commit cd7cc4bec9
2 changed files with 110 additions and 39 deletions

View file

@ -21,7 +21,7 @@ namespace MWGui
{ {
/* BookTextParser */ /* BookTextParser */
BookTextParser::BookTextParser(const std::string & text) BookTextParser::BookTextParser(const std::string & text)
: mIndex(0), mText(text), mIgnoreNewlineTags(true), mIgnoreLineEndings(true) : mIndex(0), mText(text), mIgnoreNewlineTags(true), mIgnoreLineEndings(true), mClosingTag(false)
{ {
MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor
mText = Interpreter::fixDefinesBook(mText, interpreterContext); mText = Interpreter::fixDefinesBook(mText, interpreterContext);
@ -40,7 +40,7 @@ namespace MWGui
mTagTypes[tag] = type; mTagTypes[tag] = type;
} }
std::string BookTextParser::getReadyText() std::string BookTextParser::getReadyText() const
{ {
return mReadyText; return mReadyText;
} }
@ -81,7 +81,6 @@ namespace MWGui
if (type == Event_ImgTag) if (type == Event_ImgTag)
{ {
mIgnoreLineEndings = false;
mIgnoreNewlineTags = false; mIgnoreNewlineTags = false;
} }
@ -117,12 +116,27 @@ namespace MWGui
return mAttributes; return mAttributes;
} }
bool BookTextParser::isClosingTag() const
{
return mClosingTag;
}
void BookTextParser::parseTag(std::string tag) void BookTextParser::parseTag(std::string tag)
{ {
size_t tagNameEndPos = tag.find(' '); size_t tagNameEndPos = tag.find(' ');
mAttributes.clear();
mTag = tag.substr(0, tagNameEndPos); mTag = tag.substr(0, tagNameEndPos);
Misc::StringUtils::toLower(mTag); Misc::StringUtils::toLower(mTag);
mAttributes.clear(); if (mTag.empty())
return;
mClosingTag = (mTag[0] == '/');
if (mClosingTag)
{
mTag.erase(mTag.begin());
return;
}
if (tagNameEndPos == std::string::npos) if (tagNameEndPos == std::string::npos)
return; return;
tag.erase(0, tagNameEndPos+1); tag.erase(0, tagNameEndPos+1);
@ -183,6 +197,9 @@ namespace MWGui
paper->setNeedMouseFocus(false); paper->setNeedMouseFocus(false);
BookTextParser parser(markup); BookTextParser parser(markup);
bool brBeforeLastTag = false;
bool isPrevImg = false;
for (;;) for (;;)
{ {
BookTextParser::Events event = parser.next(); BookTextParser::Events event = parser.next();
@ -190,10 +207,20 @@ namespace MWGui
continue; continue;
std::string plainText = parser.getReadyText(); std::string plainText = parser.getReadyText();
if (!plainText.empty()) if (plainText.empty())
brBeforeLastTag = false;
else
{ {
// if there's a newline at the end of the box caption, remove it // Each block of text (between two tags / boundary and tag) will be displayed in a separate editbox widget,
if (plainText[plainText.size()-1] == '\n') // which means an additional linebreak will be created between them.
// ^ This is not what vanilla MW assumes, so we must deal with line breaks around tags appropriately.
bool brAtStart = (plainText[0] == '\n');
bool brAtEnd = (plainText[plainText.size()-1] == '\n');
if (brAtStart && !brBeforeLastTag && !isPrevImg)
plainText.erase(plainText.begin());
if (plainText.size() && brAtEnd)
plainText.erase(plainText.end()-1); plainText.erase(plainText.end()-1);
#if (MYGUI_VERSION < MYGUI_DEFINE_VERSION(3, 2, 2)) #if (MYGUI_VERSION < MYGUI_DEFINE_VERSION(3, 2, 2))
@ -206,13 +233,21 @@ namespace MWGui
} }
#endif #endif
TextElement elem(paper, pag, mTextStyle, plainText); if (!plainText.empty() || brBeforeLastTag || isPrevImg)
{
TextElement elem(paper, pag, mBlockStyle,
mTextStyle, plainText);
elem.paginate(); elem.paginate();
} }
brBeforeLastTag = brAtEnd;
}
if (event == BookTextParser::Event_EOF) if (event == BookTextParser::Event_EOF)
break; break;
isPrevImg = (event == BookTextParser::Event_ImgTag);
switch (event) switch (event)
{ {
case BookTextParser::Event_ImgTag: case BookTextParser::Event_ImgTag:
@ -226,11 +261,15 @@ namespace MWGui
int width = boost::lexical_cast<int>(attr.at("width")); int width = boost::lexical_cast<int>(attr.at("width"));
int height = boost::lexical_cast<int>(attr.at("height")); int height = boost::lexical_cast<int>(attr.at("height"));
ImageElement elem(paper, pag, src, width, height); ImageElement elem(paper, pag, mBlockStyle,
src, width, height);
elem.paginate(); elem.paginate();
break; break;
} }
case BookTextParser::Event_FontTag: case BookTextParser::Event_FontTag:
if (parser.isClosingTag())
resetFontProperties();
else
handleFont(parser.getAttributes()); handleFont(parser.getAttributes());
break; break;
case BookTextParser::Event_DivTag: case BookTextParser::Event_DivTag:
@ -255,6 +294,11 @@ namespace MWGui
return markupToWidget(parent, markup, parent->getWidth(), parent->getHeight()); return markupToWidget(parent, markup, parent->getWidth(), parent->getHeight());
} }
void BookFormatter::resetFontProperties()
{
mTextStyle = TextStyle();
}
void BookFormatter::handleDiv(const BookTextParser::Attributes & attr) void BookFormatter::handleDiv(const BookTextParser::Attributes & attr)
{ {
if (attr.find("align") == attr.end()) if (attr.find("align") == attr.end())
@ -263,9 +307,11 @@ namespace MWGui
std::string align = attr.at("align"); std::string align = attr.at("align");
if (Misc::StringUtils::ciEqual(align, "center")) if (Misc::StringUtils::ciEqual(align, "center"))
mTextStyle.mTextAlign = MyGUI::Align::HCenter; mBlockStyle.mAlign = MyGUI::Align::HCenter;
else if (Misc::StringUtils::ciEqual(align, "left")) else if (Misc::StringUtils::ciEqual(align, "left"))
mTextStyle.mTextAlign = MyGUI::Align::Left; mBlockStyle.mAlign = MyGUI::Align::Left;
else if (Misc::StringUtils::ciEqual(align, "right"))
mBlockStyle.mAlign = MyGUI::Align::Right;
} }
void BookFormatter::handleFont(const BookTextParser::Attributes & attr) void BookFormatter::handleFont(const BookTextParser::Attributes & attr)
@ -296,8 +342,8 @@ namespace MWGui
} }
/* GraphicElement */ /* GraphicElement */
GraphicElement::GraphicElement(MyGUI::Widget * parent, Paginator & pag) GraphicElement::GraphicElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle)
: mParent(parent), mPaginator(pag) : mParent(parent), mPaginator(pag), mBlockStyle(blockStyle)
{ {
} }
@ -320,10 +366,10 @@ namespace MWGui
} }
/* TextElement */ /* TextElement */
TextElement::TextElement(MyGUI::Widget * parent, Paginator & pag, TextElement::TextElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle,
const TextStyle & style, const std::string & text) const TextStyle & textStyle, const std::string & text)
: GraphicElement(parent, pag), : GraphicElement(parent, pag, blockStyle),
mStyle(style) mTextStyle(textStyle)
{ {
MyGUI::EditBox* box = parent->createWidget<MyGUI::EditBox>("NormalText", MyGUI::EditBox* box = parent->createWidget<MyGUI::EditBox>("NormalText",
MyGUI::IntCoord(0, pag.getCurrentTop(), pag.getPageWidth(), 0), MyGUI::Align::Left | MyGUI::Align::Top, MyGUI::IntCoord(0, pag.getCurrentTop(), pag.getPageWidth(), 0), MyGUI::Align::Left | MyGUI::Align::Top,
@ -333,9 +379,9 @@ namespace MWGui
box->setProperty("WordWrap", "true"); box->setProperty("WordWrap", "true");
box->setProperty("NeedMouse", "false"); box->setProperty("NeedMouse", "false");
box->setMaxTextLength(text.size()); box->setMaxTextLength(text.size());
box->setTextAlign(mStyle.mTextAlign); box->setTextAlign(mBlockStyle.mAlign);
box->setTextColour(mStyle.mColour); box->setTextColour(mTextStyle.mColour);
box->setFontName(mStyle.mFont); box->setFontName(mTextStyle.mFont);
box->setCaption(MyGUI::TextIterator::toTagsString(text)); box->setCaption(MyGUI::TextIterator::toTagsString(text));
box->setSize(box->getSize().width, box->getTextSize().height); box->setSize(box->getSize().width, box->getTextSize().height);
mEditBox = box; mEditBox = box;
@ -343,7 +389,7 @@ namespace MWGui
int TextElement::currentFontHeight() const int TextElement::currentFontHeight() const
{ {
std::string fontName(mStyle.mFont == "Default" ? MyGUI::FontManager::getInstance().getDefaultFont() : mStyle.mFont); std::string fontName(mTextStyle.mFont == "Default" ? MyGUI::FontManager::getInstance().getDefaultFont() : mTextStyle.mFont);
return MyGUI::FontManager::getInstance().getByName(fontName)->getDefaultHeight(); return MyGUI::FontManager::getInstance().getByName(fontName)->getDefaultHeight();
} }
@ -375,13 +421,21 @@ namespace MWGui
} }
/* ImageElement */ /* ImageElement */
ImageElement::ImageElement(MyGUI::Widget * parent, Paginator & pag, ImageElement::ImageElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle,
const std::string & src, int width, int height) const std::string & src, int width, int height)
: GraphicElement(parent, pag), : GraphicElement(parent, pag, blockStyle),
mImageHeight(height) mImageHeight(height)
{ {
int left = 0;
if (mBlockStyle.mAlign.isHCenter())
left += (pag.getPageWidth() - width) / 2;
else if (mBlockStyle.mAlign.isLeft())
left = 0;
else if (mBlockStyle.mAlign.isRight())
left += pag.getPageWidth() - width;
mImageBox = parent->createWidget<MyGUI::ImageBox> ("ImageBox", mImageBox = parent->createWidget<MyGUI::ImageBox> ("ImageBox",
MyGUI::IntCoord(0, pag.getCurrentTop(), width, mImageHeight), MyGUI::Align::Left | MyGUI::Align::Top, MyGUI::IntCoord(left, pag.getCurrentTop(), width, mImageHeight), MyGUI::Align::Left | MyGUI::Align::Top,
parent->getName() + boost::lexical_cast<std::string>(parent->getChildCount())); parent->getName() + boost::lexical_cast<std::string>(parent->getChildCount()));
std::string image = Misc::ResourceHelpers::correctBookartPath(src, width, mImageHeight); std::string image = Misc::ResourceHelpers::correctBookartPath(src, width, mImageHeight);

View file

@ -14,14 +14,22 @@ namespace MWGui
mColour(0,0,0) mColour(0,0,0)
, mFont("Default") , mFont("Default")
, mTextSize(16) , mTextSize(16)
, mTextAlign(MyGUI::Align::Left | MyGUI::Align::Top)
{ {
} }
MyGUI::Colour mColour; MyGUI::Colour mColour;
std::string mFont; std::string mFont;
int mTextSize; int mTextSize;
MyGUI::Align mTextAlign; };
struct BlockStyle
{
BlockStyle() :
mAlign(MyGUI::Align::Left | MyGUI::Align::Top)
{
}
MyGUI::Align mAlign;
}; };
class BookTextParser class BookTextParser
@ -40,15 +48,18 @@ namespace MWGui
}; };
BookTextParser(const std::string & text); BookTextParser(const std::string & text);
void registerTag(const std::string & tag, Events type);
std::string getReadyText();
Events next(); Events next();
void flushBuffer();
const Attributes & getAttributes() const; const Attributes & getAttributes() const;
void parseTag(std::string tag); std::string getReadyText() const;
bool isClosingTag() const;
private: private:
void registerTag(const std::string & tag, Events type);
void flushBuffer();
void parseTag(std::string tag);
size_t mIndex; size_t mIndex;
std::string mText; std::string mText;
std::string mReadyText; std::string mReadyText;
@ -57,6 +68,7 @@ namespace MWGui
bool mIgnoreLineEndings; bool mIgnoreLineEndings;
Attributes mAttributes; Attributes mAttributes;
std::string mTag; std::string mTag;
bool mClosingTag;
std::map<std::string, Events> mTagTypes; std::map<std::string, Events> mTagTypes;
std::string mBuffer; std::string mBuffer;
}; };
@ -101,18 +113,20 @@ namespace MWGui
Paginator::Pages markupToWidget(MyGUI::Widget * parent, const std::string & markup, const int pageWidth, const int pageHeight); Paginator::Pages markupToWidget(MyGUI::Widget * parent, const std::string & markup, const int pageWidth, const int pageHeight);
Paginator::Pages markupToWidget(MyGUI::Widget * parent, const std::string & markup); Paginator::Pages markupToWidget(MyGUI::Widget * parent, const std::string & markup);
protected: private:
void handleImg(const BookTextParser::Attributes & attr); void resetFontProperties();
void handleDiv(const BookTextParser::Attributes & attr); void handleDiv(const BookTextParser::Attributes & attr);
void handleFont(const BookTextParser::Attributes & attr); void handleFont(const BookTextParser::Attributes & attr);
private:
TextStyle mTextStyle; TextStyle mTextStyle;
BlockStyle mBlockStyle;
}; };
class GraphicElement class GraphicElement
{ {
public: public:
GraphicElement(MyGUI::Widget * parent, Paginator & pag); GraphicElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle);
virtual int getHeight() = 0; virtual int getHeight() = 0;
virtual void paginate(); virtual void paginate();
virtual int pageSplit(); virtual int pageSplit();
@ -120,24 +134,27 @@ namespace MWGui
protected: protected:
MyGUI::Widget * mParent; MyGUI::Widget * mParent;
Paginator & mPaginator; Paginator & mPaginator;
BlockStyle mBlockStyle;
}; };
class TextElement : public GraphicElement class TextElement : public GraphicElement
{ {
public: public:
TextElement(MyGUI::Widget * parent, Paginator & pag, const TextStyle & style, const std::string & text); TextElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle,
const TextStyle & textStyle, const std::string & text);
virtual int getHeight(); virtual int getHeight();
virtual int pageSplit(); virtual int pageSplit();
private: private:
int currentFontHeight() const; int currentFontHeight() const;
TextStyle mStyle; TextStyle mTextStyle;
MyGUI::EditBox * mEditBox; MyGUI::EditBox * mEditBox;
}; };
class ImageElement : public GraphicElement class ImageElement : public GraphicElement
{ {
public: public:
ImageElement(MyGUI::Widget * parent, Paginator & pag, const std::string & src, int width, int height); ImageElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle,
const std::string & src, int width, int height);
virtual int getHeight(); virtual int getHeight();
virtual int pageSplit(); virtual int pageSplit();