forked from teamnwah/openmw-tes3coop
Merge branch 'master' into inventoryGUI
Conflicts: apps/openmw/CMakeLists.txt apps/openmw/mwgui/window_manager.cpp apps/openmw/mwgui/window_manager.hpp files/mygui/core.xmlactorid
commit
a1b86acc38
@ -0,0 +1,10 @@
|
||||
Dongle's Oblivion Daedric font set
|
||||
http://www.uesp.net/wiki/Lore:Daedric_Alphabet#Daedric_Font
|
||||
|
||||
---------------------------------------------------
|
||||
|
||||
This was done entirely as a personal project. Bethesda Softworks graciously granted me the permission for it. I am not connected with them in any way.
|
||||
You may freely use these fonts to create anything you'd like. You may re-distribute the fonts freely, over the Internet, or by any other means. Always keep the .zip file intact, and this read me included.
|
||||
Please do not modify and redistribute the fonts without my permission.
|
||||
You may NOT sell any of these fonts under any circumstances. This includes putting them on compilation font CDs for sale, putting them in a "members only" pay-area of a website, or any other means of financial gain connected in ANY way with the redistribution of any of these fonts.
|
||||
You have my permission to create and sell any artwork made with these fonts, however you may need to contact Bethesda Softworks before doing so.
|
@ -0,0 +1,140 @@
|
||||
#include "bookwindow.hpp"
|
||||
|
||||
#include "formatting.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwinput/inputmanager.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
BookWindow::BookWindow (WindowManager& parWindowManager) :
|
||||
WindowBase("openmw_book_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mCloseButton, "CloseButton");
|
||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onCloseButtonClicked);
|
||||
|
||||
getWidget(mTakeButton, "TakeButton");
|
||||
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onTakeButtonClicked);
|
||||
|
||||
getWidget(mNextPageButton, "NextPageBTN");
|
||||
mNextPageButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onNextPageButtonClicked);
|
||||
|
||||
getWidget(mPrevPageButton, "PrevPageBTN");
|
||||
mPrevPageButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onPrevPageButtonClicked);
|
||||
|
||||
getWidget(mLeftPageNumber, "LeftPageNumber");
|
||||
getWidget(mRightPageNumber, "RightPageNumber");
|
||||
|
||||
getWidget(mLeftPage, "LeftPage");
|
||||
getWidget(mRightPage, "RightPage");
|
||||
|
||||
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)
|
||||
{
|
||||
mBook = book;
|
||||
|
||||
clearPages();
|
||||
mCurrentPage = 0;
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (book, "book open", 1.0, 1.0);
|
||||
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
mBook.get<ESM::Book>();
|
||||
|
||||
BookTextParser parser;
|
||||
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)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (mBook, "book close", 1.0, 1.0);
|
||||
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Game);
|
||||
}
|
||||
|
||||
void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (mBook, "Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
|
||||
|
||||
MWWorld::ActionTake take(mBook);
|
||||
take.execute();
|
||||
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
#ifndef MWGUI_BOOKWINDOW_H
|
||||
#define MWGUI_BOOKWINDOW_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class BookWindow : public WindowBase
|
||||
{
|
||||
public:
|
||||
BookWindow(WindowManager& parWindowManager);
|
||||
void open(MWWorld::Ptr book);
|
||||
|
||||
protected:
|
||||
void onNextPageButtonClicked (MyGUI::Widget* _sender);
|
||||
void onPrevPageButtonClicked (MyGUI::Widget* _sender);
|
||||
void onCloseButtonClicked (MyGUI::Widget* _sender);
|
||||
void onTakeButtonClicked (MyGUI::Widget* _sender);
|
||||
|
||||
void updatePages();
|
||||
void clearPages();
|
||||
|
||||
private:
|
||||
MyGUI::Button* mCloseButton;
|
||||
MyGUI::Button* mTakeButton;
|
||||
MyGUI::Button* mNextPageButton;
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,331 @@
|
||||
#include "formatting.hpp"
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
namespace
|
||||
{
|
||||
int convertFromHex(std::string hex)
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
int a = 0;
|
||||
int b = hex.length() - 1;
|
||||
for (; b >= 0; a++, b--)
|
||||
{
|
||||
if (hex[b] >= '0' && hex[b] <= '9')
|
||||
{
|
||||
value += (hex[b] - '0') * (1 << (a * 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (hex[b])
|
||||
{
|
||||
case 'A':
|
||||
case 'a':
|
||||
value += 10 * (1 << (a * 4));
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
case 'b':
|
||||
value += 11 * (1 << (a * 4));
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
case 'c':
|
||||
value += 12 * (1 << (a * 4));
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
case 'd':
|
||||
value += 13 * (1 << (a * 4));
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
case 'e':
|
||||
value += 14 * (1 << (a * 4));
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
case 'f':
|
||||
value += 15 * (1 << (a * 4));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::runtime_error("invalid character in hex number");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
mParent = parent;
|
||||
mWidth = width;
|
||||
mHeight = 0;
|
||||
|
||||
assert(mParent);
|
||||
while (mParent->getChildCount())
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mParent->getChildAt(0));
|
||||
}
|
||||
|
||||
boost::algorithm::replace_all(text, "<BR>", "\n");
|
||||
boost::algorithm::replace_all(text, "<P>", "\n\n");
|
||||
|
||||
// remove leading newlines
|
||||
//while (text[0] == '\n')
|
||||
// text.erase(0);
|
||||
|
||||
// remove trailing "
|
||||
if (text[text.size()-1] == '\"')
|
||||
text.erase(text.size()-1);
|
||||
|
||||
parseSubText(text);
|
||||
return MyGUI::IntSize(mWidth, mHeight);
|
||||
}
|
||||
|
||||
void BookTextParser::parseImage(std::string tag, bool createWidget)
|
||||
{
|
||||
int src_start = tag.find("SRC=")+5;
|
||||
std::string image = tag.substr(src_start, tag.find('"', src_start)-src_start);
|
||||
|
||||
// fix texture extension to .dds
|
||||
if (image.size() > 4)
|
||||
{
|
||||
image[image.size()-3] = 'd';
|
||||
image[image.size()-2] = 'd';
|
||||
image[image.size()-1] = 's';
|
||||
}
|
||||
|
||||
int width_start = tag.find("WIDTH=")+7;
|
||||
int width = boost::lexical_cast<int>(tag.substr(width_start, tag.find('"', width_start)-width_start));
|
||||
|
||||
int height_start = tag.find("HEIGHT=")+8;
|
||||
int height = boost::lexical_cast<int>(tag.substr(height_start, tag.find('"', height_start)-height_start));
|
||||
|
||||
if (createWidget)
|
||||
{
|
||||
MyGUI::ImageBox* box = mParent->createWidget<MyGUI::ImageBox> ("ImageBox",
|
||||
MyGUI::IntCoord(0, mHeight, width, height), MyGUI::Align::Left | MyGUI::Align::Top,
|
||||
mParent->getName() + boost::lexical_cast<std::string>(mParent->getChildCount()));
|
||||
box->setImageTexture("bookart\\" + image);
|
||||
box->setProperty("NeedMouse", "false");
|
||||
}
|
||||
|
||||
mWidth = std::max(mWidth, width);
|
||||
mHeight += height;
|
||||
}
|
||||
|
||||
void BookTextParser::parseDiv(std::string tag)
|
||||
{
|
||||
if (tag.find("ALIGN=") == std::string::npos)
|
||||
return;
|
||||
|
||||
int align_start = tag.find("ALIGN=")+7;
|
||||
std::string align = tag.substr(align_start, tag.find('"', align_start)-align_start);
|
||||
if (align == "CENTER")
|
||||
mTextStyle.mTextAlign = MyGUI::Align::HCenter;
|
||||
else if (align == "LEFT")
|
||||
mTextStyle.mTextAlign = MyGUI::Align::Left;
|
||||
}
|
||||
|
||||
void BookTextParser::parseFont(std::string tag)
|
||||
{
|
||||
if (tag.find("COLOR=") != std::string::npos)
|
||||
{
|
||||
int color_start = tag.find("COLOR=")+7;
|
||||
std::string color = tag.substr(color_start, tag.find('"', color_start)-color_start);
|
||||
|
||||
mTextStyle.mColour = MyGUI::Colour(
|
||||
convertFromHex(color.substr(0, 2))/255.0,
|
||||
convertFromHex(color.substr(2, 2))/255.0,
|
||||
convertFromHex(color.substr(4, 2))/255.0);
|
||||
}
|
||||
if (tag.find("FACE=") != std::string::npos)
|
||||
{
|
||||
int face_start = tag.find("FACE=")+6;
|
||||
std::string face = tag.substr(face_start, tag.find('"', face_start)-face_start);
|
||||
|
||||
if (face != "Magic Cards")
|
||||
mTextStyle.mFont = face;
|
||||
}
|
||||
if (tag.find("SIZE=") != std::string::npos)
|
||||
{
|
||||
/// \todo
|
||||
}
|
||||
}
|
||||
|
||||
void BookTextParser::parseSubText(std::string text)
|
||||
{
|
||||
if (text[0] == '<')
|
||||
{
|
||||
if (text.find('>') == std::string::npos)
|
||||
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
|
||||
|
||||
if (text.size() > 4 && text.substr(0, 4) == "<IMG")
|
||||
parseImage(text.substr(0, text.find('>')));
|
||||
else if (text.size() > 5 && text.substr(0, 5) == "<FONT")
|
||||
parseFont(text.substr(0, text.find('>')));
|
||||
else if (text.size() > 4 && text.substr(0, 4) == "<DIV")
|
||||
parseDiv(text.substr(0, text.find('>')));
|
||||
|
||||
text.erase(0, text.find('>')+1);
|
||||
}
|
||||
|
||||
bool tagFound = false;
|
||||
std::string realText; // real text, without tags
|
||||
unsigned int i=0;
|
||||
for (; i<text.size(); ++i)
|
||||
{
|
||||
char c = text[i];
|
||||
if (c == '<')
|
||||
{
|
||||
if (text[i+1] == '/') // ignore closing tags
|
||||
{
|
||||
while (c != '>')
|
||||
{
|
||||
if (i >= text.size())
|
||||
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
|
||||
++i;
|
||||
c = text[i];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
tagFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
realText += c;
|
||||
}
|
||||
|
||||
MyGUI::EditBox* box = mParent->createWidget<MyGUI::EditBox>("NormalText",
|
||||
MyGUI::IntCoord(0, mHeight, mWidth, 24), MyGUI::Align::Left | MyGUI::Align::Top,
|
||||
mParent->getName() + boost::lexical_cast<std::string>(mParent->getChildCount()));
|
||||
box->setProperty("Static", "true");
|
||||
box->setProperty("MultiLine", "true");
|
||||
box->setProperty("WordWrap", "true");
|
||||
box->setProperty("NeedMouse", "false");
|
||||
box->setMaxTextLength(realText.size());
|
||||
box->setTextAlign(mTextStyle.mTextAlign);
|
||||
box->setTextColour(mTextStyle.mColour);
|
||||
box->setFontName(mTextStyle.mFont);
|
||||
box->setCaption(realText);
|
||||
box->setSize(box->getSize().width, box->getTextSize().height);
|
||||
mHeight += box->getTextSize().height;
|
||||
|
||||
if (tagFound)
|
||||
{
|
||||
parseSubText(text.substr(i, text.size()));
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
#ifndef MWGUI_FORMATTING_H
|
||||
#define MWGUI_FORMATTING_H
|
||||
|
||||
#include <MyGUI.h>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
struct TextStyle
|
||||
{
|
||||
TextStyle() :
|
||||
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;
|
||||
};
|
||||
|
||||
/// \brief utilities for parsing book/scroll text as mygui widgets
|
||||
class BookTextParser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Parse markup as MyGUI widgets
|
||||
* @param markup to parse
|
||||
* @param parent for the created widgets
|
||||
* @param maximum width
|
||||
* @return size of the created widgets
|
||||
*/
|
||||
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:
|
||||
void parseSubText(std::string text);
|
||||
|
||||
void parseImage(std::string tag, bool createWidget=true);
|
||||
void parseDiv(std::string tag);
|
||||
void parseFont(std::string tag);
|
||||
private:
|
||||
MyGUI::Widget* mParent;
|
||||
int mWidth; // maximum width
|
||||
int mHeight; // current height
|
||||
TextStyle mTextStyle;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,121 @@
|
||||
#include "list.hpp"
|
||||
|
||||
#include <MyGUI.h>
|
||||
|
||||
using namespace MWGui;
|
||||
using namespace MWGui::Widgets;
|
||||
|
||||
MWList::MWList() :
|
||||
mClient(0)
|
||||
, mScrollView(0)
|
||||
, mItemHeight(0)
|
||||
{
|
||||
}
|
||||
|
||||
void MWList::initialiseOverride()
|
||||
{
|
||||
Base::initialiseOverride();
|
||||
|
||||
assignWidget(mClient, "Client");
|
||||
if (mClient == 0)
|
||||
mClient = this;
|
||||
|
||||
mScrollView = mClient->createWidgetReal<MyGUI::ScrollView>(
|
||||
"MW_ScrollView", MyGUI::FloatCoord(0.0, 0.0, 1.0, 1.0),
|
||||
MyGUI::Align::Top | MyGUI::Align::Left | MyGUI::Align::Stretch, getName() + "_ScrollView");
|
||||
}
|
||||
|
||||
void MWList::addItem(const std::string& name)
|
||||
{
|
||||
mItems.push_back(name);
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
void MWList::adjustSize()
|
||||
{
|
||||
redraw();
|
||||
}
|
||||
|
||||
void MWList::redraw(bool scrollbarShown)
|
||||
{
|
||||
const int _scrollBarWidth = 24; // fetch this from skin?
|
||||
const int scrollBarWidth = scrollbarShown ? _scrollBarWidth : 0;
|
||||
const int spacing = 3;
|
||||
|
||||
while (mScrollView->getChildCount())
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mScrollView->getChildAt(0));
|
||||
}
|
||||
|
||||
mItemHeight = 0;
|
||||
for (std::vector<std::string>::const_iterator it=mItems.begin();
|
||||
it!=mItems.end(); ++it)
|
||||
{
|
||||
MyGUI::Button* button = mScrollView->createWidget<MyGUI::Button>(
|
||||
"MW_ListLine", MyGUI::IntCoord(0, mItemHeight, mScrollView->getSize().width - scrollBarWidth - 2, 24),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top, getName() + "_item_" + (*it));
|
||||
button->setCaption((*it));
|
||||
button->getSubWidgetText()->setWordWrap(true);
|
||||
button->getSubWidgetText()->setTextAlign(MyGUI::Align::Left);
|
||||
button->eventMouseWheel += MyGUI::newDelegate(this, &MWList::onMouseWheel);
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWList::onItemSelected);
|
||||
|
||||
int height = button->getTextSize().height;
|
||||
button->setSize(MyGUI::IntSize(button->getSize().width, height));
|
||||
|
||||
mItemHeight += height + spacing;
|
||||
}
|
||||
mScrollView->setCanvasSize(mClient->getSize().width + (_scrollBarWidth-scrollBarWidth), std::max(mItemHeight, mClient->getSize().height));
|
||||
mScrollView->setViewOffset(MyGUI::IntPoint(0,0));
|
||||
|
||||
if (!scrollbarShown && mItemHeight > mClient->getSize().height)
|
||||
redraw(true);
|
||||
}
|
||||
|
||||
bool MWList::hasItem(const std::string& name)
|
||||
{
|
||||
return (std::find(mItems.begin(), mItems.end(), name) != mItems.end());
|
||||
}
|
||||
|
||||
unsigned int MWList::getItemCount()
|
||||
{
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
std::string MWList::getItemNameAt(unsigned int at)
|
||||
{
|
||||
assert(at < mItems.size() && "List item out of bounds");
|
||||
return mItems[at];
|
||||
}
|
||||
|
||||
void MWList::removeItem(const std::string& name)
|
||||
{
|
||||
assert( std::find(mItems.begin(), mItems.end(), name) != mItems.end() );
|
||||
mItems.erase( std::find(mItems.begin(), mItems.end(), name) );
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
void MWList::clear()
|
||||
{
|
||||
mItems.clear();
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
void MWList::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
{
|
||||
//NB view offset is negative
|
||||
if (mScrollView->getViewOffset().top + _rel*0.3 > 0)
|
||||
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
|
||||
else
|
||||
mScrollView->setViewOffset(MyGUI::IntPoint(0, mScrollView->getViewOffset().top + _rel*0.3));
|
||||
}
|
||||
|
||||
void MWList::onItemSelected(MyGUI::Widget* _sender)
|
||||
{
|
||||
std::string name = static_cast<MyGUI::Button*>(_sender)->getCaption();
|
||||
|
||||
eventItemSelected(name);
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
#ifndef MWGUI_LIST_HPP
|
||||
#define MWGUI_LIST_HPP
|
||||
|
||||
#include <MyGUI.h>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
namespace Widgets
|
||||
{
|
||||
/**
|
||||
* \brief a very simple list widget that supports word-wrapping entries
|
||||
* \note if the width or height of the list changes, you must call adjustSize() method
|
||||
*/
|
||||
class MWList : public MyGUI::Widget
|
||||
{
|
||||
MYGUI_RTTI_DERIVED(MWList)
|
||||
public:
|
||||
MWList();
|
||||
|
||||
typedef MyGUI::delegates::CMultiDelegate1<std::string> EventHandle_String;
|
||||
|
||||
/**
|
||||
* Event: Item selected with the mouse.
|
||||
* signature: void method(std::string itemName)
|
||||
*/
|
||||
EventHandle_String eventItemSelected;
|
||||
|
||||
/**
|
||||
* Call after the size of the list changed
|
||||
*/
|
||||
void adjustSize();
|
||||
|
||||
void addItem(const std::string& name);
|
||||
void removeItem(const std::string& name);
|
||||
bool hasItem(const std::string& name);
|
||||
unsigned int getItemCount();
|
||||
std::string getItemNameAt(unsigned int at);
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
void initialiseOverride();
|
||||
|
||||
void redraw(bool scrollbarShown = false);
|
||||
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
void onItemSelected(MyGUI::Widget* _sender);
|
||||
|
||||
private:
|
||||
MyGUI::ScrollView* mScrollView;
|
||||
MyGUI::Widget* mClient;
|
||||
|
||||
std::vector<std::string> mItems;
|
||||
|
||||
int mItemHeight; // height of all items
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,61 @@
|
||||
#include "scrollwindow.hpp"
|
||||
|
||||
#include "formatting.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwinput/inputmanager.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
ScrollWindow::ScrollWindow (WindowManager& parWindowManager) :
|
||||
WindowBase("openmw_scroll_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mTextView, "TextView");
|
||||
|
||||
getWidget(mCloseButton, "CloseButton");
|
||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onCloseButtonClicked);
|
||||
|
||||
getWidget(mTakeButton, "TakeButton");
|
||||
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onTakeButtonClicked);
|
||||
|
||||
center();
|
||||
}
|
||||
|
||||
void ScrollWindow::open (MWWorld::Ptr scroll)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (scroll, "scroll", 1.0, 1.0);
|
||||
|
||||
mScroll = scroll;
|
||||
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
mScroll.get<ESM::Book>();
|
||||
|
||||
BookTextParser parser;
|
||||
MyGUI::IntSize size = parser.parse(ref->base->text, mTextView, 390);
|
||||
|
||||
if (size.height > mTextView->getSize().height)
|
||||
mTextView->setCanvasSize(MyGUI::IntSize(410, size.height));
|
||||
else
|
||||
mTextView->setCanvasSize(410, mTextView->getSize().height);
|
||||
|
||||
mTextView->setViewOffset(MyGUI::IntPoint(0,0));
|
||||
}
|
||||
|
||||
void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (mScroll, "scroll", 1.0, 1.0);
|
||||
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
||||
}
|
||||
|
||||
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D (mScroll, "Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
|
||||
|
||||
MWWorld::ActionTake take(mScroll);
|
||||
take.execute();
|
||||
|
||||
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
#ifndef MWGUI_SCROLLWINDOW_H
|
||||
#define MWGUI_SCROLLWINDOW_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class ScrollWindow : public WindowBase
|
||||
{
|
||||
public:
|
||||
ScrollWindow (WindowManager& parWindowManager);
|
||||
void open (MWWorld::Ptr scroll);
|
||||
|
||||
protected:
|
||||
void onCloseButtonClicked (MyGUI::Widget* _sender);
|
||||
void onTakeButtonClicked (MyGUI::Widget* _sender);
|
||||
|
||||
private:
|
||||
MyGUI::Button* mCloseButton;
|
||||
MyGUI::Button* mTakeButton;
|
||||
MyGUI::ScrollView* mTextView;
|
||||
|
||||
MWWorld::Ptr mScroll;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,31 @@
|
||||
#include "actionread.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
#include "../mwgui/bookwindow.hpp"
|
||||
#include "../mwgui/scrollwindow.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
ActionRead::ActionRead (const MWWorld::Ptr& object) : mObject (object)
|
||||
{
|
||||
}
|
||||
|
||||
void ActionRead::execute ()
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||
mObject.get<ESM::Book>();
|
||||
|
||||
if (ref->base->data.isScroll)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->setGuiMode(MWGui::GM_Scroll);
|
||||
MWBase::Environment::get().getWindowManager()->getScrollWindow()->open(mObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->setGuiMode(MWGui::GM_Book);
|
||||
MWBase::Environment::get().getWindowManager()->getBookWindow()->open(mObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
#ifndef GAME_MWWORLD_ACTIONREAD_H
|
||||
#define GAME_MWWORLD_ACTIONREAD_H
|
||||
|
||||
#include "action.hpp"
|
||||
#include "ptr.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class ActionRead : public Action
|
||||
{
|
||||
Ptr mObject; // book or scroll to read
|
||||
|
||||
public:
|
||||
/// @param book or scroll to read
|
||||
ActionRead (const Ptr& object);
|
||||
|
||||
virtual void execute ();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ACTIONOPEN_H
|
Binary file not shown.
@ -0,0 +1,51 @@
|
||||
[settings]
|
||||
size_x = 512
|
||||
size_y = 512
|
||||
|
||||
[tx_menubook_close_idle.dds]
|
||||
x = 0
|
||||
y = 0
|
||||
|
||||
[tx_menubook_close_over.dds]
|
||||
x = 128
|
||||
y = 0
|
||||
|
||||
[tx_menubook_close_pressed.dds]
|
||||
x = 256
|
||||
y = 0
|
||||
|
||||
[tx_menubook_take_idle.dds]
|
||||
x = 384
|
||||
y = 0
|
||||
|
||||
[tx_menubook_take_over.dds]
|
||||
x = 0
|
||||
y = 32
|
||||
|
||||
[tx_menubook_take_pressed.dds]
|
||||
x = 128
|
||||
y = 32
|
||||
|
||||
[tx_menubook_next_idle.dds]
|
||||
x = 256
|
||||
y = 32
|
||||
|
||||
[tx_menubook_next_over.dds]
|
||||
x = 384
|
||||
y = 32
|
||||
|
||||
[tx_menubook_next_pressed.dds]
|
||||
x = 0
|
||||
y = 64
|
||||
|
||||
[tx_menubook_prev_idle.dds]
|
||||
x = 128
|
||||
y = 64
|
||||
|
||||
[tx_menubook_prev_over.dds]
|
||||
x = 256
|
||||
y = 64
|
||||
|
||||
[tx_menubook_prev_pressed.dds]
|
||||
x = 384
|
||||
y = 64
|
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<MyGUI type="Layout">
|
||||
|
||||
<Widget type="Window" skin="" layer="Windows" align="Left|Top" position="0 0 512 256" name="_Main">
|
||||
|
||||
<Widget type="ImageBox" skin="ImageBox" position_real="0 0 1 1" align="Top|Right" name="BookImage">
|
||||
<Property key="ImageTexture" value="textures\tx_menubook.dds"/>
|
||||
|
||||
<Widget type="Button" skin="ButtonImage" position="251 220 96 24" name="NextPageBTN">
|
||||
<Property key="ImageResource" value="MenuBook_Next"/>
|
||||
</Widget>
|
||||
<Widget type="Button" skin="ButtonImage" position="165 220 96 24" name="PrevPageBTN">
|
||||
<Property key="ImageResource" value="MenuBook_Prev"/>
|
||||
</Widget>
|
||||
<Widget type="Button" skin="ButtonImage" position="75 220 96 24" name="TakeButton">
|
||||
<Property key="ImageResource" value="MenuBook_Take"/>
|
||||
</Widget>
|
||||
<Widget type="Button" skin="ButtonImage" position="360 220 96 24" name="CloseButton">
|
||||
<Property key="ImageResource" value="MenuBook_Close"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="TextBox" skin="NormalText" position="155 215 24 24" name="LeftPageNumber">
|
||||
<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>
|
||||
|
||||
</MyGUI>
|
@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<MyGUI type="Resource">
|
||||
<Resource type="ResourceImageSet" name="ArrowPointerImage">
|
||||
<Group name="Pointer" texture="textures\tx_cursor.dds" size="32 32">
|
||||
<Index name="Pointer" >
|
||||
<Frame point="0 0"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
<Resource type="ResourceImageSet" name="HResizePointerImage">
|
||||
<Group name="Pointer" texture="textures\tx_cursormove.dds" size="32 32">
|
||||
<Index name="Pointer" >
|
||||
<Frame point="0 0"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
<Resource type="ResourceImageSet" name="VResizePointerImage">
|
||||
<Group name="Pointer" texture="mwpointer_vresize.png" size="32 32">
|
||||
<Index name="Pointer" >
|
||||
<Frame point="0 0"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
<Resource type="ResourceImageSet" name="DResizePointerImage">
|
||||
<Group name="Pointer" texture="mwpointer_dresize1.png" size="32 32">
|
||||
<Index name="Pointer" >
|
||||
<Frame point="o o"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
<Resource type="ResourceImageSet" name="DResize2PointerImage">
|
||||
<Group name="Pointer" texture="mwpointer_dresize2.png" size="32 32">
|
||||
<Index name="Pointer" >
|
||||
<Frame point="0 0"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
</MyGUI>
|
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<MyGUI type="Resource">
|
||||
<Resource type="ResourceImageSet" name="ArrowPointerImage">
|
||||
<Group name="Pointer" texture="textures\tx_cursor.dds" size="32 32">
|
||||
<Index name="Pointer" >
|
||||
<Frame point="0 0"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
<Resource type="ResourceImageSet" name="HResizePointerImage">
|
||||
<Group name="Pointer" texture="textures\tx_cursormove.dds" size="32 32">
|
||||
<Index name="Pointer" >
|
||||
<Frame point="0 0"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
<Resource type="ResourceImageSet" name="VResizePointerImage">
|
||||
<Group name="Pointer" texture="mwpointer_vresize.png" size="32 32">
|
||||
<Index name="Pointer" >
|
||||
<Frame point="0 0"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
<Resource type="ResourceImageSet" name="DResizePointerImage">
|
||||
<Group name="Pointer" texture="mwpointer_dresize1.png" size="32 32">
|
||||
<Index name="Pointer" >
|
||||
<Frame point="o o"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
<Resource type="ResourceImageSet" name="DResize2PointerImage">
|
||||
<Group name="Pointer" texture="mwpointer_dresize2.png" size="32 32">
|
||||
<Index name="Pointer" >
|
||||
<Frame point="0 0"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
|
||||
<Resource type="ResourceImageSet" name="MenuBook_Close">
|
||||
<Group name="States" texture="mwgui1" size="96 24">
|
||||
<Index name="disabled">
|
||||
<Frame point="0 0"/>
|
||||
</Index>
|
||||
<Index name="normal">
|
||||
<Frame point="0 0"/>
|
||||
</Index>
|
||||
<Index name="highlighted">
|
||||
<Frame point="128 0"/>
|
||||
</Index>
|
||||
<Index name="pushed">
|
||||
<Frame point="256 0"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
|
||||
<Resource type="ResourceImageSet" name="MenuBook_Take">
|
||||
<Group name="States" texture="mwgui1" size="96 24">
|
||||
<Index name="disabled">
|
||||
<Frame point="384 0"/>
|
||||
</Index>
|
||||
<Index name="normal">
|
||||
<Frame point="384 0"/>
|
||||
</Index>
|
||||
<Index name="highlighted">
|
||||
<Frame point="0 32"/>
|
||||
</Index>
|
||||
<Index name="pushed">
|
||||
<Frame point="128 32"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
|
||||
<Resource type="ResourceImageSet" name="MenuBook_Next">
|
||||
<Group name="States" texture="mwgui1" size="96 24">
|
||||
<Index name="disabled">
|
||||
<Frame point="256 32"/>
|
||||
</Index>
|
||||
<Index name="normal">
|
||||
<Frame point="256 32"/>
|
||||
</Index>
|
||||
<Index name="highlighted">
|
||||
<Frame point="384 32"/>
|
||||
</Index>
|
||||
<Index name="pushed">
|
||||
<Frame point="0 64"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
|
||||
<Resource type="ResourceImageSet" name="MenuBook_Prev">
|
||||
<Group name="States" texture="mwgui1" size="96 24">
|
||||
<Index name="disabled">
|
||||
<Frame point="128 64"/>
|
||||
</Index>
|
||||
<Index name="normal">
|
||||
<Frame point="128 64"/>
|
||||
</Index>
|
||||
<Index name="highlighted">
|
||||
<Frame point="256 64"/>
|
||||
</Index>
|
||||
<Index name="pushed">
|
||||
<Frame point="384 64"/>
|
||||
</Index>
|
||||
</Group>
|
||||
</Resource>
|
||||
|
||||
|
||||
<Resource type="ResourceLayout" name="ButtonImage" version="3.2.0">
|
||||
<Widget type="Widget" skin="Default" position="20 20 16 16" name="Root">
|
||||
<Property key="TextAlign" value="Center"/>
|
||||
<Property key="FontName" value="Default"/>
|
||||
<Property key="ModeImage" value="true"/>
|
||||
<Widget type="ImageBox" skin="ImageBox" position="0 0 16 16" align="Stretch" name="Image">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
</Resource>
|
||||
|
||||
</MyGUI>
|
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<MyGUI type="Layout">
|
||||
|
||||
<Widget type="Window" skin="" layer="Windows" position="0 0 512 512" name="_Main">
|
||||
|
||||
<Widget type="ImageBox" skin="ImageBox" position_real="0 0 1 1" name="ScrollImage">
|
||||
<Property key="ImageTexture" value="textures\scroll.dds"/>
|
||||
|
||||
<Widget type="Button" skin="ButtonImage" position="12 18 96 24" name="TakeButton">
|
||||
<Property key="ImageResource" value="MenuBook_Take"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Button" skin="ButtonImage" position="418 24 96 24" name="CloseButton">
|
||||
<Property key="ImageResource" value="MenuBook_Close"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="ScrollView" skin="MW_ScrollView" position="60 130 410 300" name="TextView">
|
||||
<Property key="CanvasSize" value="410 900"/>
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
</MyGUI>
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<MyGUI type="Skin">
|
||||
|
||||
<Skin name="MW_ScrollView" size="516 516" texture="mwgui.png">
|
||||
<Child type="Widget" skin="" offset="0 0 516 516" align="Stretch" name="Client"/>
|
||||
|
||||
<Child type="ScrollBar" skin="MW_VScroll" offset="498 3 14 509" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="VScroll"/>
|
||||
</Skin>
|
||||
|
||||
</MyGUI>
|
@ -0,0 +1,113 @@
|
||||
#include "atlas.hpp"
|
||||
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreImage.h>
|
||||
#include <OgreTexture.h>
|
||||
#include <OgreRenderTarget.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreTextureUnitState.h>
|
||||
#include <OgreHardwarePixelBuffer.h>
|
||||
#include <OgreConfigFile.h>
|
||||
#include <OgreStringConverter.h>
|
||||
|
||||
using namespace Ogre;
|
||||
using namespace OEngine::Render;
|
||||
|
||||
void Atlas::createFromFile (const std::string& filename, const std::string& textureName, const std::string& texturePrefix)
|
||||
{
|
||||
ConfigFile file;
|
||||
file.load(filename, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, "\t:=", true);
|
||||
|
||||
Root* root = Ogre::Root::getSingletonPtr();
|
||||
|
||||
SceneManager* sceneMgr = root->createSceneManager(ST_GENERIC);
|
||||
Camera* camera = sceneMgr->createCamera("AtlasCamera");
|
||||
|
||||
int width = StringConverter::parseInt(file.getSetting("size_x", "settings"));
|
||||
int height = StringConverter::parseInt(file.getSetting("size_y", "settings"));
|
||||
|
||||
std::vector<Rectangle2D*> rectangles;
|
||||
int i = 0;
|
||||
|
||||
ConfigFile::SectionIterator seci = file.getSectionIterator();
|
||||
while (seci.hasMoreElements())
|
||||
{
|
||||
Ogre::String sectionName = seci.peekNextKey();
|
||||
seci.getNext();
|
||||
|
||||
if (sectionName == "settings" || sectionName == "")
|
||||
continue;
|
||||
|
||||
MaterialPtr material = MaterialManager::getSingleton().create("AtlasMaterial" + StringConverter::toString(i), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
material->getTechnique(0)->getPass(0)->setLightingEnabled(false);
|
||||
material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
|
||||
TextureUnitState* tus = material->getTechnique(0)->getPass(0)->createTextureUnitState(texturePrefix + sectionName);
|
||||
tus->setTextureBorderColour(ColourValue(0, 0, 0, 0));
|
||||
|
||||
Rectangle2D* rect = new Rectangle2D(true);
|
||||
rect->setMaterial("AtlasMaterial" + StringConverter::toString(i));
|
||||
rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND);
|
||||
|
||||
int x = StringConverter::parseInt(file.getSetting("x", sectionName));
|
||||
int y = StringConverter::parseInt(file.getSetting("y", sectionName));
|
||||
|
||||
TexturePtr texture = TextureManager::getSingleton().getByName(texturePrefix + sectionName);
|
||||
if (texture.isNull())
|
||||
{
|
||||
std::cerr << "OEngine::Render::Atlas: Can't find texture " << texturePrefix + sectionName << ", skipping..." << std::endl;
|
||||
continue;
|
||||
}
|
||||
int textureWidth = texture->getWidth();
|
||||
int textureHeight = texture->getHeight();
|
||||
|
||||
float left = x/float(width) * 2 - 1;
|
||||
float top = (1-(y/float(height))) * 2 - 1;
|
||||
float right = ((x+textureWidth))/float(width) * 2 - 1;
|
||||
float bottom = (1-((y+textureHeight)/float(height))) * 2 - 1;
|
||||
rect->setCorners(left, top, right, bottom);
|
||||
|
||||
// Use infinite AAB to always stay visible
|
||||
AxisAlignedBox aabInf;
|
||||
aabInf.setInfinite();
|
||||
rect->setBoundingBox(aabInf);
|
||||
|
||||
// Attach background to the scene
|
||||
SceneNode* node = sceneMgr->getRootSceneNode()->createChildSceneNode();
|
||||
node->attachObject(rect);
|
||||
|
||||
rectangles.push_back(rect);
|
||||
++i;
|
||||
}
|
||||
|
||||
TexturePtr destTexture = TextureManager::getSingleton().createManual(
|
||||
textureName,
|
||||
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
TEX_TYPE_2D,
|
||||
width, height,
|
||||
0,
|
||||
PF_FLOAT16_RGBA,
|
||||
TU_RENDERTARGET);
|
||||
|
||||
RenderTarget* rtt = destTexture->getBuffer()->getRenderTarget();
|
||||
rtt->setAutoUpdated(false);
|
||||
Viewport* vp = rtt->addViewport(camera);
|
||||
vp->setOverlaysEnabled(false);
|
||||
vp->setShadowsEnabled(false);
|
||||
vp->setBackgroundColour(ColourValue(0,0,0,0));
|
||||
|
||||
rtt->update();
|
||||
|
||||
// remove all the junk we've created
|
||||
for (std::vector<Rectangle2D*>::iterator it=rectangles.begin();
|
||||
it!=rectangles.end(); ++it)
|
||||
{
|
||||
delete (*it);
|
||||
}
|
||||
while (i > 0)
|
||||
{
|
||||
MaterialManager::getSingleton().remove("AtlasMaterial" + StringConverter::toString(i-1));
|
||||
--i;
|
||||
}
|
||||
root->destroySceneManager(sceneMgr);
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
#ifndef OENGINE_OGRE_ATLAS_HPP
|
||||
#define OENGINE_OGRE_ATLAS_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace OEngine
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
|
||||
/// \brief Creates a texture atlas at runtime
|
||||
class Atlas
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param absolute path to file that specifies layout of the texture (positions of the textures it contains)
|
||||
* @param name of the destination texture to save to (in memory)
|
||||
* @param texture directory prefix
|
||||
*/
|
||||
static void createFromFile (const std::string& filename, const std::string& textureName, const std::string& texturePrefix="textures\\");
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue