From e899683d3e45ff8ab8d5d717adf3a217810a5c40 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 27 Jul 2013 19:01:36 +0300 Subject: Add support for chat emotes. Current emotes by needcoffee / CC0. Add emote to chat by %%X. where X is 0, 1, 2, etc. --- data/graphics/sprites/CMakeLists.txt | 3 +- data/graphics/sprites/Makefile.am | 1 + data/graphics/sprites/chatemotes.png | Bin 0 -> 5381 bytes src/gui/widgets/browserbox.cpp | 69 ++++++++++++++++++++++++++++++++--- src/gui/widgets/browserbox.h | 2 + 5 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 data/graphics/sprites/chatemotes.png diff --git a/data/graphics/sprites/CMakeLists.txt b/data/graphics/sprites/CMakeLists.txt index b076b3e75..bc5d7d70c 100644 --- a/data/graphics/sprites/CMakeLists.txt +++ b/data/graphics/sprites/CMakeLists.txt @@ -1,8 +1,9 @@ SET(FILES - arrow_up.png arrow_down.png arrow_left.png arrow_right.png + arrow_up.png + chatemotes.png error.png error.xml manaplus_emotions.png diff --git a/data/graphics/sprites/Makefile.am b/data/graphics/sprites/Makefile.am index dc2d29e5e..8001e7016 100644 --- a/data/graphics/sprites/Makefile.am +++ b/data/graphics/sprites/Makefile.am @@ -5,6 +5,7 @@ sprites_DATA = \ arrow_left.png \ arrow_right.png \ arrow_up.png \ + chatemotes.png \ error.png \ error.xml \ manaplus_emotions.png\ diff --git a/data/graphics/sprites/chatemotes.png b/data/graphics/sprites/chatemotes.png new file mode 100644 index 000000000..e248f2261 Binary files /dev/null and b/data/graphics/sprites/chatemotes.png differ diff --git a/src/gui/widgets/browserbox.cpp b/src/gui/widgets/browserbox.cpp index 907a45a33..991190e27 100644 --- a/src/gui/widgets/browserbox.cpp +++ b/src/gui/widgets/browserbox.cpp @@ -32,6 +32,7 @@ #include "gui/widgets/linkhandler.h" #include "resources/image.h" +#include "resources/imageset.h" #include "resources/resourcemanager.h" #include @@ -43,6 +44,7 @@ #include "debug.h" Skin *BrowserBox::mSkin = nullptr; +ImageSet *BrowserBox::mEmotes = nullptr; int BrowserBox::mInstances = 0; BrowserBox::BrowserBox(const Widget2 *const widget, const unsigned int mode, @@ -59,6 +61,7 @@ BrowserBox::BrowserBox(const Widget2 *const widget, const unsigned int mode, mHighMode(UNDERLINE | BACKGROUND), mOpaque(opaque), mUseLinksAndUserColors(true), + mUseEmotes(true), mSelectedLink(-1), mMaxRows(0), mHeight(0), @@ -83,6 +86,8 @@ BrowserBox::BrowserBox(const Widget2 *const widget, const unsigned int mode, { if (Theme::instance()) mSkin = Theme::instance()->load("browserbox.xml", ""); + mEmotes = ResourceManager::getInstance()->getImageSet( + "graphics/sprites/chatemotes.png", 17, 18); } mInstances ++; @@ -124,8 +129,16 @@ BrowserBox::~BrowserBox() gui->removeDragged(this); mInstances --; - if (mInstances == 0 && Theme::instance()) - Theme::instance()->unload(mSkin); + if (mInstances == 0) + { + if (Theme::instance()) + Theme::instance()->unload(mSkin); + if (mEmotes) + { + mEmotes->decRef(); + mEmotes = nullptr; + } + } } void BrowserBox::setLinkHandler(LinkHandler* linkHandler) @@ -518,6 +531,7 @@ int BrowserBox::calcHeight() unsigned int x = mPadding; const std::string row = *(i); bool wrapped = false; + int objects = 0; // Check for separator lines if (row.find("---", 0) == 0) @@ -562,6 +576,8 @@ int BrowserBox::calcHeight() start != std::string::npos; start = end, end = std::string::npos) { + bool processed(false); + // Wrapped line continuation shall be indented if (wrapped) { @@ -570,9 +586,18 @@ int BrowserBox::calcHeight() wrapped = false; } + size_t idx1 = end; + size_t idx2 = end; + // "Tokenize" the string at control sequences if (mUseLinksAndUserColors) - end = row.find("##", start + 1); + idx1 = row.find("##", start + 1); + if (mUseEmotes) + idx2 = row.find("%%", start + 1); + if (idx1 < idx2) + end = idx1; + else + end = idx2; if (mUseLinksAndUserColors || (!mUseLinksAndUserColors && (start == 0))) @@ -675,13 +700,47 @@ int BrowserBox::calcHeight() mLinks[link].y2 = y + fontHeight - 1; link++; } - start += 3; + processed = true; + start += 3; if (start == row.size()) break; } } + if (mUseEmotes) + { + // check for emote icons + if (row.size() > start + 2 && row.substr(start, 2) == "%%") + { + if (objects < 5) + { + const int cid = row.at(start + 2) - '0'; + if (cid >= 0) + { + if (mEmotes) + { + const size_t sz = mEmotes->size(); + if (cid < sz) + { + Image *const img = mEmotes->get(cid); + if (img) + { + mLineParts.push_back(LinePart(x, y, + selColor[0], selColor[1], img)); + x += 18; + } + } + } + } + objects ++; + processed = true; + } + start += 3; + if (start == row.size()) + break; + } + } const size_t len = (end == std::string::npos) ? end : end - start; if (start >= row.length()) @@ -755,7 +814,7 @@ int BrowserBox::calcHeight() else width = font->getWidth(part); - if (mMode == AUTO_WRAP && width == 0) + if (mMode == AUTO_WRAP && (width == 0 && !processed)) break; x += width; diff --git a/src/gui/widgets/browserbox.h b/src/gui/widgets/browserbox.h index 51f8bb3ac..89865d18a 100644 --- a/src/gui/widgets/browserbox.h +++ b/src/gui/widgets/browserbox.h @@ -258,6 +258,7 @@ class BrowserBox final : public gcn::Widget, unsigned int mHighMode; bool mOpaque; bool mUseLinksAndUserColors; + bool mUseEmotes; int mSelectedLink; unsigned int mMaxRows; int mHeight; @@ -278,6 +279,7 @@ class BrowserBox final : public gcn::Widget, gcn::Color mColors[2][COLORS_MAX]; static Skin *mSkin; + static ImageSet *mEmotes; static int mInstances; }; -- cgit v1.2.3-70-g09d2