mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 02:45:32 +00:00
Merge remote-tracking branch 'miroslavr/master'
This commit is contained in:
commit
cd7cc4bec9
2 changed files with 110 additions and 39 deletions
|
@ -21,7 +21,7 @@ namespace MWGui
|
|||
{
|
||||
/* BookTextParser */
|
||||
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
|
||||
mText = Interpreter::fixDefinesBook(mText, interpreterContext);
|
||||
|
@ -40,7 +40,7 @@ namespace MWGui
|
|||
mTagTypes[tag] = type;
|
||||
}
|
||||
|
||||
std::string BookTextParser::getReadyText()
|
||||
std::string BookTextParser::getReadyText() const
|
||||
{
|
||||
return mReadyText;
|
||||
}
|
||||
|
@ -81,7 +81,6 @@ namespace MWGui
|
|||
|
||||
if (type == Event_ImgTag)
|
||||
{
|
||||
mIgnoreLineEndings = false;
|
||||
mIgnoreNewlineTags = false;
|
||||
}
|
||||
|
||||
|
@ -117,12 +116,27 @@ namespace MWGui
|
|||
return mAttributes;
|
||||
}
|
||||
|
||||
bool BookTextParser::isClosingTag() const
|
||||
{
|
||||
return mClosingTag;
|
||||
}
|
||||
|
||||
void BookTextParser::parseTag(std::string tag)
|
||||
{
|
||||
size_t tagNameEndPos = tag.find(' ');
|
||||
mAttributes.clear();
|
||||
mTag = tag.substr(0, tagNameEndPos);
|
||||
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)
|
||||
return;
|
||||
tag.erase(0, tagNameEndPos+1);
|
||||
|
@ -183,6 +197,9 @@ namespace MWGui
|
|||
paper->setNeedMouseFocus(false);
|
||||
|
||||
BookTextParser parser(markup);
|
||||
|
||||
bool brBeforeLastTag = false;
|
||||
bool isPrevImg = false;
|
||||
for (;;)
|
||||
{
|
||||
BookTextParser::Events event = parser.next();
|
||||
|
@ -190,10 +207,20 @@ namespace MWGui
|
|||
continue;
|
||||
|
||||
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
|
||||
if (plainText[plainText.size()-1] == '\n')
|
||||
// Each block of text (between two tags / boundary and tag) will be displayed in a separate editbox widget,
|
||||
// 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);
|
||||
|
||||
#if (MYGUI_VERSION < MYGUI_DEFINE_VERSION(3, 2, 2))
|
||||
|
@ -206,13 +233,21 @@ namespace MWGui
|
|||
}
|
||||
#endif
|
||||
|
||||
TextElement elem(paper, pag, mTextStyle, plainText);
|
||||
elem.paginate();
|
||||
if (!plainText.empty() || brBeforeLastTag || isPrevImg)
|
||||
{
|
||||
TextElement elem(paper, pag, mBlockStyle,
|
||||
mTextStyle, plainText);
|
||||
elem.paginate();
|
||||
}
|
||||
|
||||
brBeforeLastTag = brAtEnd;
|
||||
}
|
||||
|
||||
if (event == BookTextParser::Event_EOF)
|
||||
break;
|
||||
|
||||
isPrevImg = (event == BookTextParser::Event_ImgTag);
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case BookTextParser::Event_ImgTag:
|
||||
|
@ -226,12 +261,16 @@ namespace MWGui
|
|||
int width = boost::lexical_cast<int>(attr.at("width"));
|
||||
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();
|
||||
break;
|
||||
}
|
||||
case BookTextParser::Event_FontTag:
|
||||
handleFont(parser.getAttributes());
|
||||
if (parser.isClosingTag())
|
||||
resetFontProperties();
|
||||
else
|
||||
handleFont(parser.getAttributes());
|
||||
break;
|
||||
case BookTextParser::Event_DivTag:
|
||||
handleDiv(parser.getAttributes());
|
||||
|
@ -255,6 +294,11 @@ namespace MWGui
|
|||
return markupToWidget(parent, markup, parent->getWidth(), parent->getHeight());
|
||||
}
|
||||
|
||||
void BookFormatter::resetFontProperties()
|
||||
{
|
||||
mTextStyle = TextStyle();
|
||||
}
|
||||
|
||||
void BookFormatter::handleDiv(const BookTextParser::Attributes & attr)
|
||||
{
|
||||
if (attr.find("align") == attr.end())
|
||||
|
@ -263,9 +307,11 @@ namespace MWGui
|
|||
std::string align = attr.at("align");
|
||||
|
||||
if (Misc::StringUtils::ciEqual(align, "center"))
|
||||
mTextStyle.mTextAlign = MyGUI::Align::HCenter;
|
||||
mBlockStyle.mAlign = MyGUI::Align::HCenter;
|
||||
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)
|
||||
|
@ -296,8 +342,8 @@ namespace MWGui
|
|||
}
|
||||
|
||||
/* GraphicElement */
|
||||
GraphicElement::GraphicElement(MyGUI::Widget * parent, Paginator & pag)
|
||||
: mParent(parent), mPaginator(pag)
|
||||
GraphicElement::GraphicElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle)
|
||||
: mParent(parent), mPaginator(pag), mBlockStyle(blockStyle)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -320,10 +366,10 @@ namespace MWGui
|
|||
}
|
||||
|
||||
/* TextElement */
|
||||
TextElement::TextElement(MyGUI::Widget * parent, Paginator & pag,
|
||||
const TextStyle & style, const std::string & text)
|
||||
: GraphicElement(parent, pag),
|
||||
mStyle(style)
|
||||
TextElement::TextElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle,
|
||||
const TextStyle & textStyle, const std::string & text)
|
||||
: GraphicElement(parent, pag, blockStyle),
|
||||
mTextStyle(textStyle)
|
||||
{
|
||||
MyGUI::EditBox* box = parent->createWidget<MyGUI::EditBox>("NormalText",
|
||||
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("NeedMouse", "false");
|
||||
box->setMaxTextLength(text.size());
|
||||
box->setTextAlign(mStyle.mTextAlign);
|
||||
box->setTextColour(mStyle.mColour);
|
||||
box->setFontName(mStyle.mFont);
|
||||
box->setTextAlign(mBlockStyle.mAlign);
|
||||
box->setTextColour(mTextStyle.mColour);
|
||||
box->setFontName(mTextStyle.mFont);
|
||||
box->setCaption(MyGUI::TextIterator::toTagsString(text));
|
||||
box->setSize(box->getSize().width, box->getTextSize().height);
|
||||
mEditBox = box;
|
||||
|
@ -343,7 +389,7 @@ namespace MWGui
|
|||
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -375,13 +421,21 @@ namespace MWGui
|
|||
}
|
||||
|
||||
/* 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)
|
||||
: GraphicElement(parent, pag),
|
||||
: GraphicElement(parent, pag, blockStyle),
|
||||
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",
|
||||
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()));
|
||||
|
||||
std::string image = Misc::ResourceHelpers::correctBookartPath(src, width, mImageHeight);
|
||||
|
|
|
@ -14,14 +14,22 @@ namespace MWGui
|
|||
mColour(0,0,0)
|
||||
, mFont("Default")
|
||||
, mTextSize(16)
|
||||
, mTextAlign(MyGUI::Align::Left | MyGUI::Align::Top)
|
||||
{
|
||||
}
|
||||
|
||||
MyGUI::Colour mColour;
|
||||
std::string mFont;
|
||||
int mTextSize;
|
||||
MyGUI::Align mTextAlign;
|
||||
};
|
||||
|
||||
struct BlockStyle
|
||||
{
|
||||
BlockStyle() :
|
||||
mAlign(MyGUI::Align::Left | MyGUI::Align::Top)
|
||||
{
|
||||
}
|
||||
|
||||
MyGUI::Align mAlign;
|
||||
};
|
||||
|
||||
class BookTextParser
|
||||
|
@ -40,15 +48,18 @@ namespace MWGui
|
|||
};
|
||||
|
||||
BookTextParser(const std::string & text);
|
||||
void registerTag(const std::string & tag, Events type);
|
||||
std::string getReadyText();
|
||||
|
||||
Events next();
|
||||
void flushBuffer();
|
||||
|
||||
const Attributes & getAttributes() const;
|
||||
void parseTag(std::string tag);
|
||||
std::string getReadyText() const;
|
||||
bool isClosingTag() const;
|
||||
|
||||
private:
|
||||
void registerTag(const std::string & tag, Events type);
|
||||
void flushBuffer();
|
||||
void parseTag(std::string tag);
|
||||
|
||||
size_t mIndex;
|
||||
std::string mText;
|
||||
std::string mReadyText;
|
||||
|
@ -57,6 +68,7 @@ namespace MWGui
|
|||
bool mIgnoreLineEndings;
|
||||
Attributes mAttributes;
|
||||
std::string mTag;
|
||||
bool mClosingTag;
|
||||
std::map<std::string, Events> mTagTypes;
|
||||
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);
|
||||
|
||||
protected:
|
||||
void handleImg(const BookTextParser::Attributes & attr);
|
||||
private:
|
||||
void resetFontProperties();
|
||||
|
||||
void handleDiv(const BookTextParser::Attributes & attr);
|
||||
void handleFont(const BookTextParser::Attributes & attr);
|
||||
private:
|
||||
|
||||
TextStyle mTextStyle;
|
||||
BlockStyle mBlockStyle;
|
||||
};
|
||||
|
||||
class GraphicElement
|
||||
{
|
||||
public:
|
||||
GraphicElement(MyGUI::Widget * parent, Paginator & pag);
|
||||
GraphicElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle);
|
||||
virtual int getHeight() = 0;
|
||||
virtual void paginate();
|
||||
virtual int pageSplit();
|
||||
|
@ -120,24 +134,27 @@ namespace MWGui
|
|||
protected:
|
||||
MyGUI::Widget * mParent;
|
||||
Paginator & mPaginator;
|
||||
BlockStyle mBlockStyle;
|
||||
};
|
||||
|
||||
class TextElement : public GraphicElement
|
||||
{
|
||||
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 pageSplit();
|
||||
private:
|
||||
int currentFontHeight() const;
|
||||
TextStyle mStyle;
|
||||
TextStyle mTextStyle;
|
||||
MyGUI::EditBox * mEditBox;
|
||||
};
|
||||
|
||||
class ImageElement : public GraphicElement
|
||||
{
|
||||
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 pageSplit();
|
||||
|
||||
|
|
Loading…
Reference in a new issue