Merge remote branch 'zini/master' into sound

This commit is contained in:
Chris Robinson 2012-05-11 01:15:37 -07:00
commit bcd371d37b
56 changed files with 1651 additions and 173 deletions

View file

@ -103,6 +103,7 @@ set(OENGINE_OGRE
${LIBDIR}/openengine/ogre/mouselook.cpp ${LIBDIR}/openengine/ogre/mouselook.cpp
${LIBDIR}/openengine/ogre/fader.cpp ${LIBDIR}/openengine/ogre/fader.cpp
${LIBDIR}/openengine/ogre/imagerotate.cpp ${LIBDIR}/openengine/ogre/imagerotate.cpp
${LIBDIR}/openengine/ogre/atlas.cpp
) )
set(OENGINE_GUI set(OENGINE_GUI
${LIBDIR}/openengine/gui/events.cpp ${LIBDIR}/openengine/gui/events.cpp

10
Daedric Font License.txt Normal file
View file

@ -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.

View file

@ -25,7 +25,8 @@ add_openmw_dir (mwinput
add_openmw_dir (mwgui add_openmw_dir (mwgui
layouts text_input widgets race class birth review window_manager console dialogue layouts text_input widgets race class birth review window_manager console dialogue
dialogue_history window_base stats_window messagebox journalwindow charactercreation dialogue_history window_base stats_window messagebox journalwindow charactercreation
map_window window_pinnable_base cursorreplace tooltips map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list
formatting
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue
@ -46,7 +47,7 @@ add_openmw_dir (mwsound
add_openmw_dir (mwworld add_openmw_dir (mwworld
refdata world physicssystem scene globals class action nullaction actionteleport refdata world physicssystem scene globals class action nullaction actionteleport
containerstore actiontalk actiontake manualref player cellfunctors containerstore actiontalk actiontake manualref player cellfunctors
cells localscripts customdata weather inventorystore ptr cells localscripts customdata weather inventorystore ptr actionread
) )
add_openmw_dir (mwclass add_openmw_dir (mwclass

View file

@ -158,13 +158,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
OMW::Engine::~Engine() OMW::Engine::~Engine()
{ {
delete MWBase::Environment::get().getInputManager(); mEnvironment.cleanup();
delete MWBase::Environment::get().getSoundManager();
delete MWBase::Environment::get().getMechanicsManager();
delete MWBase::Environment::get().getDialogueManager();
delete MWBase::Environment::get().getJournal();
delete MWBase::Environment::get().getScriptManager();
delete MWBase::Environment::get().getWorld();
delete mScriptContext; delete mScriptContext;
delete mOgre; delete mOgre;
} }
@ -200,6 +194,12 @@ void OMW::Engine::addResourcesDirectory (const boost::filesystem::path& path)
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true);
} }
void OMW::Engine::addZipResource (const boost::filesystem::path& path)
{
mOgre->getRoot()->addResourceLocation (path.string(), "Zip",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false);
}
void OMW::Engine::enableFSStrict(bool fsStrict) void OMW::Engine::enableFSStrict(bool fsStrict)
{ {
mFSStrict = fsStrict; mFSStrict = fsStrict;
@ -287,6 +287,8 @@ void OMW::Engine::go()
settings.loadDefault(localdefault); settings.loadDefault(localdefault);
else if (boost::filesystem::exists(globaldefault)) else if (boost::filesystem::exists(globaldefault))
settings.loadDefault(globaldefault); settings.loadDefault(globaldefault);
else
throw std::runtime_error ("No default settings file found! Make sure the file \"settings-default.cfg\" was properly installed.");
// load user settings if they exist, otherwise just load the default settings as user settings // load user settings if they exist, otherwise just load the default settings as user settings
const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg"; const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg";
@ -320,6 +322,7 @@ void OMW::Engine::go()
addResourcesDirectory(mResDir / "water"); addResourcesDirectory(mResDir / "water");
addResourcesDirectory(mResDir / "gbuffer"); addResourcesDirectory(mResDir / "gbuffer");
addResourcesDirectory(mResDir / "shadows"); addResourcesDirectory(mResDir / "shadows");
addZipResource(mResDir / "mygui" / "Obliviontt.zip");
// Create the window // Create the window
mOgre->createWindow("OpenMW"); mOgre->createWindow("OpenMW");

View file

@ -62,6 +62,7 @@ namespace OMW
/// \brief Main engine class, that brings together all the components of OpenMW /// \brief Main engine class, that brings together all the components of OpenMW
class Engine : private Ogre::FrameListener class Engine : private Ogre::FrameListener
{ {
MWBase::Environment mEnvironment;
std::string mEncoding; std::string mEncoding;
Files::PathContainer mDataDirs; Files::PathContainer mDataDirs;
boost::filesystem::path mResDir; boost::filesystem::path mResDir;
@ -77,7 +78,6 @@ namespace OMW
std::string mFocusName; std::string mFocusName;
std::map<std::string,std::string> mFallbackMap; std::map<std::string,std::string> mFallbackMap;
MWBase::Environment mEnvironment;
Compiler::Extensions mExtensions; Compiler::Extensions mExtensions;
Compiler::Context *mScriptContext; Compiler::Context *mScriptContext;
@ -91,9 +91,11 @@ namespace OMW
/// add resources directory /// add resources directory
/// \note This function works recursively. /// \note This function works recursively.
void addResourcesDirectory (const boost::filesystem::path& path); void addResourcesDirectory (const boost::filesystem::path& path);
/// add a .zip resource
void addZipResource (const boost::filesystem::path& path);
/// Load all BSA files in data directory. /// Load all BSA files in data directory.
void loadBSA(); void loadBSA();

View file

@ -3,6 +3,19 @@
#include <cassert> #include <cassert>
#include "../mwinput/inputmanager.hpp"
#include "../mwscript/scriptmanager.hpp"
#include "../mwsound/soundmanager.hpp"
#include "../mwworld/world.hpp"
#include "../mwdialogue/dialoguemanager.hpp"
#include "../mwdialogue/journal.hpp"
#include "../mwmechanics/mechanicsmanager.hpp"
MWBase::Environment *MWBase::Environment::sThis = 0; MWBase::Environment *MWBase::Environment::sThis = 0;
MWBase::Environment::Environment() MWBase::Environment::Environment()
@ -15,6 +28,7 @@ MWBase::Environment::Environment()
MWBase::Environment::~Environment() MWBase::Environment::~Environment()
{ {
cleanup();
sThis = 0; sThis = 0;
} }
@ -116,6 +130,30 @@ float MWBase::Environment::getFrameDuration() const
return mFrameDuration; return mFrameDuration;
} }
void MWBase::Environment::cleanup()
{
delete mInputManager;
mInputManager = 0;
delete mSoundManager;
mSoundManager = 0;
delete mMechanicsManager;
mMechanicsManager = 0;
delete mDialogueManager;
mDialogueManager = 0;
delete mJournal;
mJournal = 0;
delete mScriptManager;
mScriptManager = 0;
delete mWorld;
mWorld = 0;
}
const MWBase::Environment& MWBase::Environment::get() const MWBase::Environment& MWBase::Environment::get()
{ {
assert (sThis); assert (sThis);

View file

@ -43,7 +43,7 @@ namespace MWBase
/// ///
/// This class allows each mw-subsystem to access any others subsystem's top-level manager class. /// This class allows each mw-subsystem to access any others subsystem's top-level manager class.
/// ///
/// \attention Environment does not take ownership of the manager class instances it is handed over in /// \attention Environment takes ownership of the manager class instances it is handed over in
/// the set* functions. /// the set* functions.
class Environment class Environment
{ {
@ -108,6 +108,9 @@ namespace MWBase
float getFrameDuration() const; float getFrameDuration() const;
void cleanup();
///< Delete all mw*-subsystems.
static const Environment& get(); static const Environment& get();
///< Return instance of this class. ///< Return instance of this class.
}; };

View file

@ -8,7 +8,7 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actionread.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
#include "../mwrender/objects.hpp" #include "../mwrender/objects.hpp"
@ -60,12 +60,8 @@ namespace MWClass
boost::shared_ptr<MWWorld::Action> Book::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Book::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor) const const MWWorld::Ptr& actor) const
{ {
// TODO implement reading
MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack);
return boost::shared_ptr<MWWorld::Action> ( return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr)); new MWWorld::ActionRead (ptr));
} }
std::string Book::getScript (const MWWorld::Ptr& ptr) const std::string Book::getScript (const MWWorld::Ptr& ptr) const

View file

@ -883,4 +883,11 @@ namespace MWDialogue
} }
return factionID; return factionID;
} }
void DialogueManager::goodbye()
{
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->goodbye();
}
} }

View file

@ -56,6 +56,8 @@ namespace MWDialogue
void askQuestion(std::string question,int choice); void askQuestion(std::string question,int choice);
void goodbye();
///get the faction of the actor you are talking with ///get the faction of the actor you are talking with
std::string getFaction(); std::string getFaction();

View file

@ -6,6 +6,8 @@
#include "../mwgui/window_manager.hpp" #include "../mwgui/window_manager.hpp"
#include "../mwgui/messagebox.hpp" #include "../mwgui/messagebox.hpp"
#include "../mwworld/world.hpp"
namespace MWDialogue namespace MWDialogue
{ {
Quest& Journal::getQuest (const std::string& id) Quest& Journal::getQuest (const std::string& id)
@ -38,7 +40,7 @@ namespace MWDialogue
quest.addEntry (entry, *MWBase::Environment::get().getWorld()); // we are doing slicing on purpose here quest.addEntry (entry, *MWBase::Environment::get().getWorld()); // we are doing slicing on purpose here
std::vector<std::string> empty; std::vector<std::string> empty;
std::string notification = "Your Journal has been updated."; std::string notification = MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sJournalEntry")->str;
MWBase::Environment::get().getWindowManager()->messageBox (notification, empty); MWBase::Environment::get().getWindowManager()->messageBox (notification, empty);
} }

View file

@ -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;
}
}

View file

@ -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

View file

@ -183,6 +183,7 @@ void CharacterCreation::spawnDialog(const char id)
if (mCreateClassDialog) if (mCreateClassDialog)
mWM->removeDialog(mCreateClassDialog); mWM->removeDialog(mCreateClassDialog);
mCreateClassDialog = new CreateClassDialog(*mWM); mCreateClassDialog = new CreateClassDialog(*mWM);
mCreateClassDialog->setNextButtonShow(mCreationStage >= CSE_ClassChosen);
mCreateClassDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogDone); mCreateClassDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogDone);
mCreateClassDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogBack); mCreateClassDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogBack);
mCreateClassDialog->open(); mCreateClassDialog->open();

View file

@ -111,6 +111,7 @@ PickClassDialog::PickClassDialog(WindowManager& parWindowManager)
MyGUI::ButtonPtr backButton; MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton"); getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onBackClicked); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onBackClicked);
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
MyGUI::ButtonPtr okButton; MyGUI::ButtonPtr okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");
@ -431,6 +432,7 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager)
MyGUI::ButtonPtr backButton; MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton"); getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onBackClicked); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onBackClicked);
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
MyGUI::ButtonPtr okButton; MyGUI::ButtonPtr okButton;
getWidget(okButton, "OKButton"); getWidget(okButton, "OKButton");

View file

@ -2,6 +2,7 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <openengine/ogre/imagerotate.hpp> #include <openengine/ogre/imagerotate.hpp>
#include <openengine/ogre/atlas.hpp>
#include <OgreResourceGroupManager.h> #include <OgreResourceGroupManager.h>
#include <OgreRoot.h> #include <OgreRoot.h>
@ -13,4 +14,6 @@ CursorReplace::CursorReplace()
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_vresize.png", 90); OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_vresize.png", 90);
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize1.png", -45); OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize1.png", -45);
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize2.png", 45); OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize2.png", 45);
OEngine::Render::Atlas::createFromFile("atlas1.cfg", "mwgui1", "textures\\");
} }

View file

@ -2,6 +2,7 @@
#include "dialogue_history.hpp" #include "dialogue_history.hpp"
#include "window_manager.hpp" #include "window_manager.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#include "list.hpp"
#include "components/esm_store/store.hpp" #include "components/esm_store/store.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwdialogue/dialoguemanager.hpp" #include "../mwdialogue/dialoguemanager.hpp"
@ -38,6 +39,7 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su
DialogueWindow::DialogueWindow(WindowManager& parWindowManager) DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
: WindowBase("openmw_dialogue_window_layout.xml", parWindowManager) : WindowBase("openmw_dialogue_window_layout.xml", parWindowManager)
, mEnabled(true)
{ {
// Centre dialog // Centre dialog
center(); center();
@ -56,17 +58,19 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
//Topics list //Topics list
getWidget(topicsList, "TopicsList"); getWidget(topicsList, "TopicsList");
topicsList->setScrollVisible(true);
//topicsList->eventListSelectAccept += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); //topicsList->eventListSelectAccept += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
topicsList->eventListMouseItemActivate += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); topicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
//topicsList->eventListChangePosition += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); //topicsList->eventListChangePosition += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
MyGUI::ButtonPtr byeButton; MyGUI::ButtonPtr byeButton;
getWidget(byeButton, "ByeButton"); getWidget(byeButton, "ByeButton");
byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked); byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
byeButton->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGoodbye")->str);
getWidget(pDispositionBar, "Disposition"); getWidget(pDispositionBar, "Disposition");
getWidget(pDispositionText,"DispositionText"); getWidget(pDispositionText,"DispositionText");
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize);
} }
void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender) void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
@ -79,6 +83,10 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
size_t cursorPosition = t->getCursorPosition(lastPressed); size_t cursorPosition = t->getCursorPosition(lastPressed);
MyGUI::UString color = history->getColorAtPos(cursorPosition); MyGUI::UString color = history->getColorAtPos(cursorPosition);
if (!mEnabled && color == "#572D21")
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
if(color != "#B29154") if(color != "#B29154")
{ {
UString key = history->getColorTextAt(cursorPosition); UString key = history->getColorTextAt(cursorPosition);
@ -88,6 +96,11 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
} }
} }
void DialogueWindow::onWindowResize(MyGUI::Window* _sender)
{
topicsList->adjustSize();
}
void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{ {
if (history->getVScrollPosition() - _rel*0.3 < 0) if (history->getVScrollPosition() - _rel*0.3 < 0)
@ -98,7 +111,7 @@ void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
void DialogueWindow::open() void DialogueWindow::open()
{ {
topicsList->removeAllItems(); topicsList->clear();
pTopicsText.clear(); pTopicsText.clear();
history->eraseText(0,history->getTextLength()); history->eraseText(0,history->getTextLength());
updateOptions(); updateOptions();
@ -110,23 +123,24 @@ void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
} }
void DialogueWindow::onSelectTopic(MyGUI::ListBox* _sender, size_t _index) void DialogueWindow::onSelectTopic(std::string topic)
{ {
if (_index == MyGUI::ITEM_NONE) if (!mEnabled) return;
return;
std::string topic = _sender->getItemNameAt(_index);
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic)); MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
} }
void DialogueWindow::startDialogue(std::string npcName) void DialogueWindow::startDialogue(std::string npcName)
{ {
mEnabled = true;
topicsList->setEnabled(true);
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(npcName); static_cast<MyGUI::Window*>(mMainWidget)->setCaption(npcName);
adjustWindowCaption(); adjustWindowCaption();
} }
void DialogueWindow::setKeywords(std::list<std::string> keyWords) void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{ {
topicsList->removeAllItems(); topicsList->clear();
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); it++) for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); it++)
{ {
topicsList->addItem(*it); topicsList->addItem(*it);
@ -135,9 +149,9 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
void DialogueWindow::removeKeyword(std::string keyWord) void DialogueWindow::removeKeyword(std::string keyWord)
{ {
if(topicsList->findItemIndexWith(keyWord) != MyGUI::ITEM_NONE) if(topicsList->hasItem(keyWord))
{ {
topicsList->removeItemAt(topicsList->findItemIndexWith(keyWord)); topicsList->removeItem(keyWord);
pTopicsText.erase(keyWord); pTopicsText.erase(keyWord);
} }
} }
@ -211,7 +225,7 @@ void DialogueWindow::askQuestion(std::string question)
void DialogueWindow::updateOptions() void DialogueWindow::updateOptions()
{ {
//Clear the list of topics //Clear the list of topics
topicsList->removeAllItems(); topicsList->clear();
pTopicsText.clear(); pTopicsText.clear();
history->eraseText(0,history->getTextLength()); history->eraseText(0,history->getTextLength());
@ -220,3 +234,10 @@ void DialogueWindow::updateOptions()
pDispositionText->eraseText(0,pDispositionText->getTextLength()); pDispositionText->eraseText(0,pDispositionText->getTextLength());
pDispositionText->addText("#B29154"+std::string("40/100")+"#B29154"); pDispositionText->addText("#B29154"+std::string("40/100")+"#B29154");
} }
void DialogueWindow::goodbye()
{
history->addDialogText("\n#572D21" + MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGoodbye")->str);
topicsList->setEnabled(false);
mEnabled = false;
}

View file

@ -7,6 +7,11 @@
namespace MWGui namespace MWGui
{ {
class WindowManager; class WindowManager;
namespace Widgets
{
class MWList;
}
} }
/* /*
@ -40,12 +45,14 @@ namespace MWGui
void addText(std::string text); void addText(std::string text);
void addTitle(std::string text); void addTitle(std::string text);
void askQuestion(std::string question); void askQuestion(std::string question);
void goodbye();
protected: protected:
void onSelectTopic(MyGUI::ListBox* _sender, size_t _index); void onSelectTopic(std::string topic);
void onByeClicked(MyGUI::Widget* _sender); void onByeClicked(MyGUI::Widget* _sender);
void onHistoryClicked(MyGUI::Widget* _sender); void onHistoryClicked(MyGUI::Widget* _sender);
void onMouseWheel(MyGUI::Widget* _sender, int _rel); void onMouseWheel(MyGUI::Widget* _sender, int _rel);
void onWindowResize(MyGUI::Window* _sender);
private: private:
void updateOptions(); void updateOptions();
@ -54,8 +61,10 @@ namespace MWGui
*/ */
std::string parseText(std::string text); std::string parseText(std::string text);
bool mEnabled;
DialogueHistory* history; DialogueHistory* history;
MyGUI::ListBox* topicsList; Widgets::MWList* topicsList;
MyGUI::ProgressPtr pDispositionBar; MyGUI::ProgressPtr pDispositionBar;
MyGUI::EditPtr pDispositionText; MyGUI::EditPtr pDispositionText;
std::map<std::string,std::string> pTopicsText;// this map links keyword and "real" text. std::map<std::string,std::string> pTopicsText;// this map links keyword and "real" text.

View file

@ -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()));
}
}

View file

@ -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

View file

@ -82,6 +82,7 @@ book formatText(std::string text,book mBook,int maxLine, int lineSize)
MWGui::JournalWindow::JournalWindow (WindowManager& parWindowManager) MWGui::JournalWindow::JournalWindow (WindowManager& parWindowManager)
: WindowBase("openmw_journal_layout.xml", parWindowManager) : WindowBase("openmw_journal_layout.xml", parWindowManager)
, lastPos(0) , lastPos(0)
, mVisible(false)
{ {
//setCoord(0,0,498, 342); //setCoord(0,0,498, 342);
center(); center();
@ -109,9 +110,15 @@ MWGui::JournalWindow::JournalWindow (WindowManager& parWindowManager)
//std::list<std::string> list = formatText("OpenMW rgh dsfg sqef srg ZT uzql n ZLIEHRF LQSJH GLOIjf qjfmj hslkdgn jlkdjhg qlr isgli shli uhs fiuh qksf cg ksjnf lkqsnbf ksbf sbfkl zbf kuyzflkj sbgdfkj zlfh ozhjfmo hzmfh lizuf rty qzt ezy tkyEZT RYYJ DG fgh is an open-source implementation of the game engine found in the game Morrowind. This is a dumb test text msodjbg smojg smoig fiiinnn"); //std::list<std::string> list = formatText("OpenMW rgh dsfg sqef srg ZT uzql n ZLIEHRF LQSJH GLOIjf qjfmj hslkdgn jlkdjhg qlr isgli shli uhs fiuh qksf cg ksjnf lkqsnbf ksbf sbfkl zbf kuyzflkj sbgdfkj zlfh ozhjfmo hzmfh lizuf rty qzt ezy tkyEZT RYYJ DG fgh is an open-source implementation of the game engine found in the game Morrowind. This is a dumb test text msodjbg smojg smoig fiiinnn");
//std::list<std::string> list = formatText(); //std::list<std::string> list = formatText();
//displayLeftText(list.front()); //displayLeftText(list.front());
}
MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget); void MWGui::JournalWindow::setVisible(bool visible)
t->eventWindowChangeCoord += MyGUI::newDelegate(this, &JournalWindow::onWindowResize); {
if (mVisible && !visible)
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
mVisible = visible;
mMainWidget->setVisible(visible);
} }
void MWGui::JournalWindow::open() void MWGui::JournalWindow::open()
@ -159,10 +166,6 @@ void MWGui::JournalWindow::open()
} }
} }
void MWGui::JournalWindow::onWindowResize(MyGUI::Window* window)
{
}
void MWGui::JournalWindow::displayLeftText(std::string text) void MWGui::JournalWindow::displayLeftText(std::string text)
{ {
mLeftTextWidget->eraseText(0,mLeftTextWidget->getTextLength()); mLeftTextWidget->eraseText(0,mLeftTextWidget->getTextLength());

View file

@ -18,16 +18,9 @@ namespace MWGui
JournalWindow(WindowManager& parWindowManager); JournalWindow(WindowManager& parWindowManager);
void open(); void open();
virtual void setVisible(bool visible); // only used to play close sound
private: private:
enum ColorStyle
{
CS_Sub,
CS_Normal,
CS_Super
};
void onWindowResize(MyGUI::Window* window);
void displayLeftText(std::string text); void displayLeftText(std::string text);
void displayRightText(std::string text); void displayRightText(std::string text);
@ -50,6 +43,7 @@ namespace MWGui
std::vector<std::string> leftPages; std::vector<std::string> leftPages;
std::vector<std::string> rightPages; std::vector<std::string> rightPages;
int mPageNumber; //store the number of the current left page int mPageNumber; //store the number of the current left page
bool mVisible;
}; };
} }

121
apps/openmw/mwgui/list.cpp Normal file
View file

@ -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);
}

View file

@ -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

View file

@ -12,12 +12,12 @@ namespace MWGui
GM_Console, // Console mode GM_Console, // Console mode
GM_Journal, // Journal mode GM_Journal, // Journal mode
// None of the following are implemented yet GM_Scroll, // Read scroll
GM_Book, // Read book
GM_Dialogue, // NPC interaction GM_Dialogue, // NPC interaction
GM_Barter, GM_Barter,
GM_Rest, GM_Rest,
// .. more here ..
// Startup character creation dialogs // Startup character creation dialogs
GM_Name, GM_Name,

View file

@ -248,7 +248,7 @@ MyGUI::TextBox* ReviewDialog::addValueItem(const std::string text, const std::st
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Default); skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Default);
skillNameWidget->setCaption(text); skillNameWidget->setCaption(text);
skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Default); skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Top | MyGUI::Align::Right);
skillValueWidget->setCaption(value); skillValueWidget->setCaption(value);
skillValueWidget->_setWidgetState(state); skillValueWidget->_setWidgetState(state);

View file

@ -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);
}

View file

@ -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

View file

@ -230,7 +230,9 @@ void StatsWindow::setBirthSign (const std::string& signId)
void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{ {
MyGUI::ImageBox* separator = skillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default); MyGUI::ImageBox* separator = skillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine",
MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18),
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
skillWidgets.push_back(separator); skillWidgets.push_back(separator);
coord1.top += separator->getHeight(); coord1.top += separator->getHeight();
@ -239,7 +241,9 @@ void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{ {
MyGUI::TextBox* groupWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default); MyGUI::TextBox* groupWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandBrightText",
MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height),
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
groupWidget->setCaption(label); groupWidget->setCaption(label);
skillWidgets.push_back(groupWidget); skillWidgets.push_back(groupWidget);
@ -251,12 +255,12 @@ MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::st
{ {
MyGUI::TextBox *skillNameWidget, *skillValueWidget; MyGUI::TextBox *skillNameWidget, *skillValueWidget;
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Default); skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
skillNameWidget->setCaption(text); skillNameWidget->setCaption(text);
skillNameWidget->setUserString("ToolTipType", "Text"); skillNameWidget->setUserString("ToolTipType", "Text");
skillNameWidget->setUserString("ToolTipText", tooltip); skillNameWidget->setUserString("ToolTipText", tooltip);
skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Default); skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Right | MyGUI::Align::Top);
skillValueWidget->setUserString("ToolTipType", "Text"); skillValueWidget->setUserString("ToolTipType", "Text");
skillValueWidget->setUserString("ToolTipText", tooltip); skillValueWidget->setUserString("ToolTipText", tooltip);
skillValueWidget->setCaption(value); skillValueWidget->setCaption(value);

View file

@ -31,13 +31,10 @@ void ToolTips::onFrame(float frameDuration)
{ {
/// \todo Store a MWWorld::Ptr in the widget user data, retrieve it here and construct a tooltip dynamically /// \todo Store a MWWorld::Ptr in the widget user data, retrieve it here and construct a tooltip dynamically
/// \todo we are destroying/creating the tooltip widgets every frame here, MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox);
/// because the tooltip might change (e.g. when trap is activated) mDynamicToolTipBox = mMainWidget->createWidget<Widget>("HUD_Box",
/// is there maybe a better way (listener when the object changes)? IntCoord(0, 0, mMainWidget->getCoord().width, mMainWidget->getCoord().height),
for (size_t i=0; i<mDynamicToolTipBox->getChildCount(); ++i) Align::Stretch, "DynamicToolTipBox");
{
mDynamicToolTipBox->_destroyChildWidget(mDynamicToolTipBox->getChildAt(i));
}
const IntSize &viewSize = RenderManager::getInstance().getViewSize(); const IntSize &viewSize = RenderManager::getInstance().getViewSize();
@ -56,7 +53,6 @@ void ToolTips::onFrame(float frameDuration)
std::string text = focus->getUserString("ToolTipText"); std::string text = focus->getUserString("ToolTipText");
ToolTipInfo info; ToolTipInfo info;
if (type == "") if (type == "")
{ {
mDynamicToolTipBox->setVisible(false); mDynamicToolTipBox->setVisible(false);
@ -64,7 +60,7 @@ void ToolTips::onFrame(float frameDuration)
} }
else if (type == "Text") else if (type == "Text")
{ {
info.caption = text; info.text = text;
} }
else if (type == "CaptionText") else if (type == "CaptionText")
{ {
@ -107,8 +103,8 @@ void ToolTips::onFrame(float frameDuration)
// adjust tooltip size to fit its content, position it above the crosshair // adjust tooltip size to fit its content, position it above the crosshair
/// \todo Slide the tooltip along the bounding box of the focused object (like in Morrowind) /// \todo Slide the tooltip along the bounding box of the focused object (like in Morrowind)
setCoord(viewSize.width/2 - (tooltipSize.width)/2.f, setCoord(std::max(0, viewSize.width/2 - (tooltipSize.width)/2),
viewSize.height/2 - (tooltipSize.height) - 32, std::max(0, viewSize.height/2 - (tooltipSize.height) - 32),
tooltipSize.width, tooltipSize.width,
tooltipSize.height); tooltipSize.height);
} }
@ -200,8 +196,8 @@ IntSize ToolTips::createToolTip(const ToolTipInfo& info)
const IntPoint padding(8, 8); const IntPoint padding(8, 8);
const int imageCaptionHPadding = 8; const int imageCaptionHPadding = (caption != "" ? 8 : 0);
const int imageCaptionVPadding = 4; const int imageCaptionVPadding = (caption != "" ? 4 : 0);
std::string realImage = "icons\\" + image; std::string realImage = "icons\\" + image;
findImageExtension(realImage); findImageExtension(realImage);
@ -211,7 +207,7 @@ IntSize ToolTips::createToolTip(const ToolTipInfo& info)
captionWidget->setCaption(caption); captionWidget->setCaption(caption);
IntSize captionSize = captionWidget->getTextSize(); IntSize captionSize = captionWidget->getTextSize();
int captionHeight = std::max(captionSize.height, imageSize); int captionHeight = std::max(caption != "" ? captionSize.height : 0, imageSize);
EditBox* textWidget = mDynamicToolTipBox->createWidget<EditBox>("SandText", IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), Align::Stretch, "ToolTipText"); EditBox* textWidget = mDynamicToolTipBox->createWidget<EditBox>("SandText", IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), Align::Stretch, "ToolTipText");
textWidget->setProperty("Static", "true"); textWidget->setProperty("Static", "true");

View file

@ -356,18 +356,6 @@ void MWSpellEffect::updateWidgets()
if (!mWindowManager) if (!mWindowManager)
return; return;
// lists effects that have no magnitude (e.g. invisiblity)
/// \todo this list is probably incomplete
std::vector<std::string> effectsWithoutMagnitude;
effectsWithoutMagnitude.push_back("sEffectInvisibility");
effectsWithoutMagnitude.push_back("sEffectStuntedMagicka");
effectsWithoutMagnitude.push_back("sEffectParalyze");
// lists effects that have no duration (e.g. open lock)
/// \todo this list is probably incomplete
std::vector<std::string> effectsWithoutDuration;
effectsWithoutDuration.push_back("sEffectOpen");
const ESMS::ESMStore &store = mWindowManager->getStore(); const ESMS::ESMStore &store = mWindowManager->getStore();
const ESM::MagicEffect *magicEffect = store.magicEffects.search(effect.effectID); const ESM::MagicEffect *magicEffect = store.magicEffects.search(effect.effectID);
if (textWidget) if (textWidget)
@ -401,8 +389,7 @@ void MWSpellEffect::updateWidgets()
spellLine += " " + mWindowManager->getGameSettingString(attributes[effect.attribute], ""); spellLine += " " + mWindowManager->getGameSettingString(attributes[effect.attribute], "");
} }
bool hasMagnitude = (std::find(effectsWithoutMagnitude.begin(), effectsWithoutMagnitude.end(), effectIDStr) == effectsWithoutMagnitude.end()); if ((effect.magnMin >= 0 || effect.magnMax >= 0) && effectHasMagnitude(effectIDStr))
if ((effect.magnMin >= 0 || effect.magnMax >= 0) && hasMagnitude)
{ {
if (effect.magnMin == effect.magnMax) if (effect.magnMin == effect.magnMax)
spellLine += " " + boost::lexical_cast<std::string>(effect.magnMin) + " " + ((effect.magnMin == 1) ? pt : pts); spellLine += " " + boost::lexical_cast<std::string>(effect.magnMin) + " " + ((effect.magnMin == 1) ? pt : pts);
@ -415,8 +402,7 @@ void MWSpellEffect::updateWidgets()
// constant effects have no duration and no target // constant effects have no duration and no target
if (!(mFlags & MWEffectList::EF_Constant)) if (!(mFlags & MWEffectList::EF_Constant))
{ {
bool hasDuration = (std::find(effectsWithoutDuration.begin(), effectsWithoutDuration.end(), effectIDStr) == effectsWithoutDuration.end()); if (effect.duration >= 0 && effectHasDuration(effectIDStr))
if (effect.duration >= 0 && hasDuration)
{ {
spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast<std::string>(effect.duration) + ((effect.duration == 1) ? sec : secs); spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast<std::string>(effect.duration) + ((effect.duration == 1) ? sec : secs);
} }
@ -590,11 +576,107 @@ std::string MWSpellEffect::effectIDToString(const short effectID)
names[35] ="sEffectWeaknesstoPoison"; names[35] ="sEffectWeaknesstoPoison";
names[30] ="sEffectWeaknesstoShock"; names[30] ="sEffectWeaknesstoShock";
// bloodmoon
names[138] ="sEffectSummonCreature01";
names[139] ="sEffectSummonCreature02";
names[140] ="sEffectSummonCreature03";
names[141] ="sEffectSummonCreature04";
names[142] ="sEffectSummonCreature05";
// tribunal
names[137] ="sEffectSummonFabricant";
assert(names.find(effectID) != names.end() && "Unimplemented effect type"); assert(names.find(effectID) != names.end() && "Unimplemented effect type");
return names[effectID]; return names[effectID];
} }
bool MWSpellEffect::effectHasDuration(const std::string& effect)
{
// lists effects that have no duration (e.g. open lock)
std::vector<std::string> effectsWithoutDuration;
effectsWithoutDuration.push_back("sEffectOpen");
effectsWithoutDuration.push_back("sEffectLock");
effectsWithoutDuration.push_back("sEffectDispel");
effectsWithoutDuration.push_back("sEffectSunDamage");
effectsWithoutDuration.push_back("sEffectCorpus");
effectsWithoutDuration.push_back("sEffectVampirism");
effectsWithoutDuration.push_back("sEffectMark");
effectsWithoutDuration.push_back("sEffectRecall");
effectsWithoutDuration.push_back("sEffectDivineIntervention");
effectsWithoutDuration.push_back("sEffectAlmsiviIntervention");
effectsWithoutDuration.push_back("sEffectCureCommonDisease");
effectsWithoutDuration.push_back("sEffectCureBlightDisease");
effectsWithoutDuration.push_back("sEffectCureCorprusDisease");
effectsWithoutDuration.push_back("sEffectCurePoison");
effectsWithoutDuration.push_back("sEffectCureParalyzation");
effectsWithoutDuration.push_back("sEffectRemoveCurse");
effectsWithoutDuration.push_back("sEffectRestoreAttribute");
return (std::find(effectsWithoutDuration.begin(), effectsWithoutDuration.end(), effect) == effectsWithoutDuration.end());
}
bool MWSpellEffect::effectHasMagnitude(const std::string& effect)
{
// lists effects that have no magnitude (e.g. invisiblity)
std::vector<std::string> effectsWithoutMagnitude;
effectsWithoutMagnitude.push_back("sEffectInvisibility");
effectsWithoutMagnitude.push_back("sEffectStuntedMagicka");
effectsWithoutMagnitude.push_back("sEffectParalyze");
effectsWithoutMagnitude.push_back("sEffectSoultrap");
effectsWithoutMagnitude.push_back("sEffectSilence");
effectsWithoutMagnitude.push_back("sEffectParalyze");
effectsWithoutMagnitude.push_back("sEffectInvisibility");
effectsWithoutMagnitude.push_back("sEffectWaterWalking");
effectsWithoutMagnitude.push_back("sEffectWaterBreathing");
effectsWithoutMagnitude.push_back("sEffectSummonScamp");
effectsWithoutMagnitude.push_back("sEffectSummonClannfear");
effectsWithoutMagnitude.push_back("sEffectSummonDaedroth");
effectsWithoutMagnitude.push_back("sEffectSummonDremora");
effectsWithoutMagnitude.push_back("sEffectSummonAncestralGhost");
effectsWithoutMagnitude.push_back("sEffectSummonSkeletalMinion");
effectsWithoutMagnitude.push_back("sEffectSummonBonewalker");
effectsWithoutMagnitude.push_back("sEffectSummonGreaterBonewalker");
effectsWithoutMagnitude.push_back("sEffectSummonBonelord");
effectsWithoutMagnitude.push_back("sEffectSummonWingedTwilight");
effectsWithoutMagnitude.push_back("sEffectSummonHunger");
effectsWithoutMagnitude.push_back("sEffectSummonGoldenSaint");
effectsWithoutMagnitude.push_back("sEffectSummonFlameAtronach");
effectsWithoutMagnitude.push_back("sEffectSummonFrostAtronach");
effectsWithoutMagnitude.push_back("sEffectSummonStormAtronach");
effectsWithoutMagnitude.push_back("sEffectSummonCenturionSphere");
effectsWithoutMagnitude.push_back("sEffectBoundDagger");
effectsWithoutMagnitude.push_back("sEffectBoundLongsword");
effectsWithoutMagnitude.push_back("sEffectBoundMace");
effectsWithoutMagnitude.push_back("sEffectBoundBattleAxe");
effectsWithoutMagnitude.push_back("sEffectBoundSpear");
effectsWithoutMagnitude.push_back("sEffectBoundLongbow");
effectsWithoutMagnitude.push_back("sEffectBoundCuirass");
effectsWithoutMagnitude.push_back("sEffectBoundHelm");
effectsWithoutMagnitude.push_back("sEffectBoundBoots");
effectsWithoutMagnitude.push_back("sEffectBoundShield");
effectsWithoutMagnitude.push_back("sEffectBoundGloves");
effectsWithoutMagnitude.push_back("sEffectStuntedMagicka");
effectsWithoutMagnitude.push_back("sEffectMark");
effectsWithoutMagnitude.push_back("sEffectRecall");
effectsWithoutMagnitude.push_back("sEffectDivineIntervention");
effectsWithoutMagnitude.push_back("sEffectAlmsiviIntervention");
effectsWithoutMagnitude.push_back("sEffectCureCommonDisease");
effectsWithoutMagnitude.push_back("sEffectCureBlightDisease");
effectsWithoutMagnitude.push_back("sEffectCureCorprusDisease");
effectsWithoutMagnitude.push_back("sEffectCurePoison");
effectsWithoutMagnitude.push_back("sEffectCureParalyzation");
effectsWithoutMagnitude.push_back("sEffectRemoveCurse");
effectsWithoutMagnitude.push_back("sEffectSummonCreature01");
effectsWithoutMagnitude.push_back("sEffectSummonCreature02");
effectsWithoutMagnitude.push_back("sEffectSummonCreature03");
effectsWithoutMagnitude.push_back("sEffectSummonCreature04");
effectsWithoutMagnitude.push_back("sEffectSummonCreature05");
effectsWithoutMagnitude.push_back("sEffectSummonFabricant");
return (std::find(effectsWithoutMagnitude.begin(), effectsWithoutMagnitude.end(), effect) == effectsWithoutMagnitude.end());
}
MWSpellEffect::~MWSpellEffect() MWSpellEffect::~MWSpellEffect()
{ {
} }

View file

@ -197,6 +197,8 @@ namespace MWGui
void setFlags(int flags) { mFlags = flags; } void setFlags(int flags) { mFlags = flags; }
std::string effectIDToString(const short effectID); std::string effectIDToString(const short effectID);
bool effectHasMagnitude (const std::string& effect);
bool effectHasDuration (const std::string& effect);
const SpellEffectValue &getSpellEffect() const { return effect; } const SpellEffectValue &getSpellEffect() const { return effect; }

View file

@ -8,6 +8,9 @@
#include "stats_window.hpp" #include "stats_window.hpp"
#include "messagebox.hpp" #include "messagebox.hpp"
#include "tooltips.hpp" #include "tooltips.hpp"
#include "scrollwindow.hpp"
#include "bookwindow.hpp"
#include "list.hpp"
#include "../mwmechanics/mechanicsmanager.hpp" #include "../mwmechanics/mechanicsmanager.hpp"
#include "../mwinput/inputmanager.hpp" #include "../mwinput/inputmanager.hpp"
@ -37,6 +40,8 @@ WindowManager::WindowManager(
, mMessageBoxManager(NULL) , mMessageBoxManager(NULL)
, console(NULL) , console(NULL)
, mJournal(NULL) , mJournal(NULL)
, mBookWindow(NULL)
, mScrollWindow(NULL)
, dialogueWindow(nullptr) , dialogueWindow(nullptr)
, mCharGen(NULL) , mCharGen(NULL)
, playerClass() , playerClass()
@ -69,6 +74,13 @@ WindowManager::WindowManager(
//Register own widgets with MyGUI //Register own widgets with MyGUI
MyGUI::FactoryManager::getInstance().registerFactory<DialogueHistory>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<DialogueHistory>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSkill>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWAttribute>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSpell>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWEffectList>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSpellEffect>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWDynamicStat>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWList>("Widget");
// Get size info from the Gui object // Get size info from the Gui object
assert(gui); assert(gui);
@ -84,6 +96,8 @@ WindowManager::WindowManager(
mMessageBoxManager = new MessageBoxManager(this); mMessageBoxManager = new MessageBoxManager(this);
dialogueWindow = new DialogueWindow(*this); dialogueWindow = new DialogueWindow(*this);
mToolTips = new ToolTips(this); mToolTips = new ToolTips(this);
mScrollWindow = new ScrollWindow(*this);
mBookWindow = new BookWindow(*this);
// The HUD is always on // The HUD is always on
hud->setVisible(true); hud->setVisible(true);
@ -101,13 +115,6 @@ WindowManager::WindowManager(
playerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat<float>())); playerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat<float>()));
} }
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSkill>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWAttribute>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSpell>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWEffectList>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSpellEffect>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWDynamicStat>("Widget");
// Set up visibility // Set up visibility
updateVisible(); updateVisible();
} }
@ -179,6 +186,8 @@ void WindowManager::updateVisible()
stats->setVisible(false); stats->setVisible(false);
console->disable(); console->disable();
mJournal->setVisible(false); mJournal->setVisible(false);
mScrollWindow->setVisible(false);
mBookWindow->setVisible(false);
dialogueWindow->setVisible(false); dialogueWindow->setVisible(false);
// Mouse is visible whenever we're not in game mode // Mouse is visible whenever we're not in game mode
@ -199,6 +208,12 @@ void WindowManager::updateVisible()
case GM_Console: case GM_Console:
console->enable(); console->enable();
break; break;
case GM_Scroll:
mScrollWindow->setVisible(true);
break;
case GM_Book:
mBookWindow->setVisible(true);
break;
case GM_Name: case GM_Name:
case GM_Race: case GM_Race:
case GM_Class: case GM_Class:

View file

@ -62,6 +62,8 @@ namespace MWGui
class JournalWindow; class JournalWindow;
class CharacterCreation; class CharacterCreation;
class ToolTips; class ToolTips;
class ScrollWindow;
class BookWindow;
class TextInputDialog; class TextInputDialog;
class InfoBoxDialog; class InfoBoxDialog;
@ -125,6 +127,9 @@ namespace MWGui
MWGui::DialogueWindow* getDialogueWindow() {return dialogueWindow;} MWGui::DialogueWindow* getDialogueWindow() {return dialogueWindow;}
MWGui::BookWindow* getBookWindow() {return mBookWindow;}
MWGui::ScrollWindow* getScrollWindow() {return mScrollWindow;}
MyGUI::Gui* getGui() const { return gui; } MyGUI::Gui* getGui() const { return gui; }
void wmUpdateFps(float fps, size_t triangleCount, size_t batchCount) void wmUpdateFps(float fps, size_t triangleCount, size_t batchCount)
@ -203,6 +208,8 @@ namespace MWGui
Console *console; Console *console;
JournalWindow* mJournal; JournalWindow* mJournal;
DialogueWindow *dialogueWindow; DialogueWindow *dialogueWindow;
ScrollWindow* mScrollWindow;
BookWindow* mBookWindow;
CharacterCreation* mCharGen; CharacterCreation* mCharGen;

View file

@ -133,6 +133,9 @@ namespace MWInput
void screenshot() void screenshot()
{ {
mEngine.screenshot(); mEngine.screenshot();
std::vector<std::string> empty;
windows.messageBox ("Screenshot saved", empty);
} }
/* toggleInventory() is called when the user presses the button to toggle the inventory screen. */ /* toggleInventory() is called when the user presses the button to toggle the inventory screen. */

View file

@ -115,6 +115,16 @@ namespace MWScript
} }
}; };
class OpGoodbye : public Interpreter::Opcode0
{
public:
virtual void execute(Interpreter::Runtime& runtime)
{
MWBase::Environment::get().getDialogueManager()->goodbye();
}
};
const int opcodeJournal = 0x2000133; const int opcodeJournal = 0x2000133;
const int opcodeSetJournalIndex = 0x2000134; const int opcodeSetJournalIndex = 0x2000134;
const int opcodeGetJournalIndex = 0x2000135; const int opcodeGetJournalIndex = 0x2000135;
@ -122,6 +132,7 @@ namespace MWScript
const int opcodeChoice = 0x2000a; const int opcodeChoice = 0x2000a;
const int opcodeForceGreeting = 0x200014f; const int opcodeForceGreeting = 0x200014f;
const int opcodeForceGreetingExplicit = 0x2000150; const int opcodeForceGreetingExplicit = 0x2000150;
const int opcodeGoodbye = 0x2000152;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
@ -133,6 +144,7 @@ namespace MWScript
extensions.registerInstruction("forcegreeting","",opcodeForceGreeting); extensions.registerInstruction("forcegreeting","",opcodeForceGreeting);
extensions.registerInstruction("forcegreeting","",opcodeForceGreeting, extensions.registerInstruction("forcegreeting","",opcodeForceGreeting,
opcodeForceGreetingExplicit); opcodeForceGreetingExplicit);
extensions.registerInstruction("goodbye", "", opcodeGoodbye);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -144,6 +156,7 @@ namespace MWScript
interpreter.installSegment3 (opcodeChoice,new OpChoice); interpreter.installSegment3 (opcodeChoice,new OpChoice);
interpreter.installSegment5 (opcodeForceGreeting, new OpForceGreeting<ImplicitRef>); interpreter.installSegment5 (opcodeForceGreeting, new OpForceGreeting<ImplicitRef>);
interpreter.installSegment5 (opcodeForceGreetingExplicit, new OpForceGreeting<ExplicitRef>); interpreter.installSegment5 (opcodeForceGreetingExplicit, new OpForceGreeting<ExplicitRef>);
interpreter.installSegment5 (opcodeGoodbye, new OpGoodbye);
} }
} }

View file

@ -145,4 +145,5 @@ op 0x200014e: ModDisposition, explicit reference
op 0x200014f: ForceGreeting op 0x200014f: ForceGreeting
op 0x2000150: ForceGreeting, explicit reference op 0x2000150: ForceGreeting, explicit reference
op 0x2000151: ToggleFullHelp op 0x2000151: ToggleFullHelp
opcodes 0x2000152-0x3ffffff unused op 0x2000152: Goodbye
opcodes 0x2000153-0x3ffffff unused

View file

@ -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);
}
}
}

View file

@ -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

View file

@ -9,7 +9,7 @@ configure_file("${SDIR}/black.png" "${DDIR}/black.png" COPYONLY)
configure_file("${SDIR}/core.skin" "${DDIR}/core.skin" COPYONLY) configure_file("${SDIR}/core.skin" "${DDIR}/core.skin" COPYONLY)
configure_file("${SDIR}/core.xml" "${DDIR}/core.xml" COPYONLY) configure_file("${SDIR}/core.xml" "${DDIR}/core.xml" COPYONLY)
configure_file("${SDIR}/mwgui.png" "${DDIR}/mwgui.png" COPYONLY) configure_file("${SDIR}/mwgui.png" "${DDIR}/mwgui.png" COPYONLY)
configure_file("${SDIR}/openmw_images.xml" "${DDIR}/openmw_images.xml" COPYONLY) configure_file("${SDIR}/openmw_resources.xml" "${DDIR}/openmw_resources.xml" COPYONLY)
configure_file("${SDIR}/openmw_settings.xml" "${DDIR}/openmw_settings.xml" COPYONLY) configure_file("${SDIR}/openmw_settings.xml" "${DDIR}/openmw_settings.xml" COPYONLY)
configure_file("${SDIR}/openmw_box.skin.xml" "${DDIR}/openmw_box.skin.xml" COPYONLY) configure_file("${SDIR}/openmw_box.skin.xml" "${DDIR}/openmw_box.skin.xml" COPYONLY)
configure_file("${SDIR}/openmw_button.skin.xml" "${DDIR}/openmw_button.skin.xml" COPYONLY) configure_file("${SDIR}/openmw_button.skin.xml" "${DDIR}/openmw_button.skin.xml" COPYONLY)
@ -51,7 +51,12 @@ configure_file("${SDIR}/openmw_interactive_messagebox_layout.xml" "${DDIR}/openm
configure_file("${SDIR}/openmw_journal_layout.xml" "${DDIR}/openmw_journal_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_journal_layout.xml" "${DDIR}/openmw_journal_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_journal_skin.xml" "${DDIR}/openmw_journal_skin.xml" COPYONLY) configure_file("${SDIR}/openmw_journal_skin.xml" "${DDIR}/openmw_journal_skin.xml" COPYONLY)
configure_file("${SDIR}/openmw_tooltips.xml" "${DDIR}/openmw_tooltips.xml" COPYONLY) configure_file("${SDIR}/openmw_tooltips.xml" "${DDIR}/openmw_tooltips.xml" COPYONLY)
configure_file("${SDIR}/openmw_scroll_layout.xml" "${DDIR}/openmw_scroll_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_scroll_skin.xml" "${DDIR}/openmw_scroll_skin.xml" COPYONLY)
configure_file("${SDIR}/openmw_book_layout.xml" "${DDIR}/openmw_book_layout.xml" COPYONLY)
configure_file("${SDIR}/atlas1.cfg" "${DDIR}/atlas1.cfg" COPYONLY)
configure_file("${SDIR}/smallbars.png" "${DDIR}/smallbars.png" COPYONLY) configure_file("${SDIR}/smallbars.png" "${DDIR}/smallbars.png" COPYONLY)
configure_file("${SDIR}/transparent.png" "${DDIR}/transparent.png" COPYONLY) configure_file("${SDIR}/transparent.png" "${DDIR}/transparent.png" COPYONLY)
configure_file("${SDIR}/EBGaramond-Regular.ttf" "${DDIR}/EBGaramond-Regular.ttf" COPYONLY) configure_file("${SDIR}/EBGaramond-Regular.ttf" "${DDIR}/EBGaramond-Regular.ttf" COPYONLY)
configure_file("${SDIR}/Obliviontt.zip" "${DDIR}/Obliviontt.zip" COPYONLY)
configure_file("${SDIR}/VeraMono.ttf" "${DDIR}/VeraMono.ttf" COPYONLY) configure_file("${SDIR}/VeraMono.ttf" "${DDIR}/VeraMono.ttf" COPYONLY)

BIN
files/mygui/Obliviontt.zip Normal file

Binary file not shown.

51
files/mygui/atlas1.cfg Normal file
View file

@ -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

View file

@ -2,7 +2,7 @@
<MyGUI> <MyGUI>
<MyGUI type="List"> <MyGUI type="List">
<List file="core.skin" /> <List file="core.skin" />
<List file="openmw_images.xml" /> <List file="openmw_resources.xml" />
<List file="openmw_layers.xml" /> <List file="openmw_layers.xml" />
<List file="openmw.pointer.xml" /> <List file="openmw.pointer.xml" />
<List file="openmw.font.xml" /> <List file="openmw.font.xml" />
@ -20,6 +20,7 @@
<List file="openmw_journal_skin.xml" /> <List file="openmw_journal_skin.xml" />
<List file="openmw_map_window_skin.xml" /> <List file="openmw_map_window_skin.xml" />
<List file="openmw_dialogue_window_skin.xml" /> <List file="openmw_dialogue_window_skin.xml" />
<List file="openmw_scroll_skin.xml" />
<List file="openmw_settings.xml" /> <List file="openmw_settings.xml" />
</MyGUI> </MyGUI>
</MyGUI> </MyGUI>

View file

@ -6,26 +6,38 @@
<Property key="Resolution" value="72"/> <Property key="Resolution" value="72"/>
<Property key="Antialias" value="false"/> <Property key="Antialias" value="false"/>
<Property key="TabWidth" value="8"/> <Property key="TabWidth" value="8"/>
<Property key="CursorWidth" value="2"/>
<Property key="OffsetHeight" value="0"/> <Property key="OffsetHeight" value="0"/>
<Codes> <Codes>
<Code range="33 126"/> <Code range="33 126"/>
<Code range="192 382"/> <!-- Central and Eastern European languages glyphs --> <Code range="192 382"/> <!-- Central and Eastern European languages glyphs -->
<Code range="1025 1105"/> <Code range="1025 1105"/>
<Code range="8470"/> <Code range="8470"/>
<Code range="8216 8217"/> <!-- Single quotes -->
<Code hide="128"/> <Code hide="128"/>
<Code hide="1026 1039"/> <Code hide="1026 1039"/>
<Code hide="1104"/> <Code hide="1104"/>
</Codes> </Codes>
</Resource> </Resource>
<Resource type="ResourceTrueTypeFont" name="Daedric">
<!--<Property key="Source" value="Oblivion/Oblivion Worn.ttf"/>-->
<Property key="Source" value="Oblivion/Oblivion.ttf"/>
<Property key="Size" value="24"/>
<Property key="Resolution" value="72"/>
<Property key="Antialias" value="false"/>
<Property key="TabWidth" value="8"/>
<Property key="OffsetHeight" value="0"/>
<Codes>
<Code range="65 122"/>
</Codes>
</Resource>
<Resource type="ResourceTrueTypeFont" name="MonoFont"> <Resource type="ResourceTrueTypeFont" name="MonoFont">
<Property key="Source" value="VeraMono.ttf"/> <Property key="Source" value="VeraMono.ttf"/>
<Property key="Size" value="18"/> <Property key="Size" value="18"/>
<Property key="Resolution" value="50"/> <Property key="Resolution" value="50"/>
<Property key="Antialias" value="false"/> <Property key="Antialias" value="false"/>
<Property key="TabWidth" value="8"/> <Property key="TabWidth" value="8"/>
<Property key="CursorWidth" value="2"/>
<Property key="OffsetHeight" value="0"/> <Property key="OffsetHeight" value="0"/>
<Codes> <Codes>
<Code range="33 126"/> <Code range="33 126"/>

View file

@ -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>

View file

@ -19,7 +19,7 @@
<Widget type="EditBox" skin="MW_DispositionEdit" position_real = "0 0 1 1" align="Stretch" name = "DispositionText"/> <Widget type="EditBox" skin="MW_DispositionEdit" position_real = "0 0 1 1" align="Stretch" name = "DispositionText"/>
</Widget> </Widget>
<!-- The list of topics --> <!-- The list of topics -->
<Widget type="ListBox" skin="MW_List" position="432 31 132 328" name="TopicsList" align="Right VStretch"> <Widget type="MWList" skin="MW_SimpleList" position="432 31 132 328" name="TopicsList" align="Right VStretch">
</Widget> </Widget>
<!-- The Goodbye button --> <!-- The Goodbye button -->

View file

@ -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>

View file

@ -7,14 +7,14 @@
<Widget type="ImageBox" skin="ImageBox" position_real="0 0 1 1" align="Top|Right" name="JImage"> <Widget type="ImageBox" skin="ImageBox" position_real="0 0 1 1" align="Top|Right" name="JImage">
<Property key="ImageTexture" value="textures\tx_menubook.dds"/> <Property key="ImageTexture" value="textures\tx_menubook.dds"/>
<Widget type="Button" skin="Next_btn" position="370 220 64 32" name="NextPageBTN"> <Widget type="Button" skin="ButtonImage" position="370 220 96 24" name="NextPageBTN">
<Property key="ImageResource" value="MenuBook_Next"/>
</Widget> </Widget>
<Widget type="Button" skin="ButtonImage" position="80 220 96 24" name="PrevPageBTN">
<Widget type="Button" skin="Prev_btn" position="80 220 128 32" name="PrevPageBTN"> <Property key="ImageResource" value="MenuBook_Prev"/>
</Widget> </Widget>
<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.15 0.1 0.3 0.8" name = "LeftText"/> <Widget type="EditBox" skin="MW_BookPage" position_real="0.55 0.1 0.3 0.75" name = "RightText"/>
<Widget type="EditBox" skin="MW_BookPage" position_real="0.55 0.1 0.3 0.8" name = "RightText"/>
</Widget> </Widget>
</Widget> </Widget>

View file

@ -1,18 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Skin"> <MyGUI type="Skin">
<Skin name="Next_btn" size="64 32" texture="textures\tx_menubook_next_idle.dds">
<BasisSkin type="MainSkin" offset="0 0 64 32" align="ALIGN_VSTRETCH">
<State name="normal" offset="0 0 64 32"/>
</BasisSkin>
</Skin>
<Skin name="Prev_btn" size="128 32" texture="textures\tx_menubook_prev_idle.dds">
<BasisSkin type="MainSkin" offset="0 0 128 32" align="ALIGN_VSTRETCH">
<State name="normal" offset="0 0 128 32"/>
</BasisSkin>
</Skin>
<Skin name = "MW_BookClient" size = "10 10"> <Skin name = "MW_BookClient" size = "10 10">
<Property key="FontName" value = "Default" /> <Property key="FontName" value = "Default" />
<Property key="TextAlign" value = "Left Top" /> <Property key="TextAlign" value = "Left Top" />

View file

@ -212,6 +212,20 @@
<Child type="Widget" skin="IB_BR" offset="514 514 2 2" align="ALIGN_BOTTOM ALIGN_RIGHT"/> <Child type="Widget" skin="IB_BR" offset="514 514 2 2" align="ALIGN_BOTTOM ALIGN_RIGHT"/>
</Skin> </Skin>
<Skin name = "MW_SimpleList" size = "516 516" align = "ALIGN_LEFT ALIGN_TOP" texture="mwgui.png">
<Child type="Widget" skin="" offset = "3 3 510 510" align = "ALIGN_STRETCH" name = "Client">
</Child>
<Child type="Widget" skin="IB_T" offset="2 0 512 2" align="ALIGN_TOP ALIGN_HSTRETCH"/>
<Child type="Widget" skin="IB_B" offset="2 514 512 2" align="ALIGN_BOTTOM ALIGN_HSTRETCH"/>
<Child type="Widget" skin="IB_L" offset="0 2 2 512" align="ALIGN_LEFT ALIGN_VSTRETCH"/>
<Child type="Widget" skin="IB_R" offset="514 2 2 512" align="ALIGN_RIGHT ALIGN_VSTRETCH"/>
<Child type="Widget" skin="IB_TL" offset="0 0 2 2" align="ALIGN_TOP ALIGN_LEFT"/>
<Child type="Widget" skin="IB_TR" offset="514 0 2 2" align="ALIGN_TOP ALIGN_RIGHT"/>
<Child type="Widget" skin="IB_BL" offset="0 514 2 2" align="ALIGN_BOTTOM ALIGN_LEFT"/>
<Child type="Widget" skin="IB_BR" offset="514 514 2 2" align="ALIGN_BOTTOM ALIGN_RIGHT"/>
</Skin>
<Skin name = "MW_MultiSubList" size = "516 516" align = "ALIGN_LEFT ALIGN_TOP"> <Skin name = "MW_MultiSubList" size = "516 516" align = "ALIGN_LEFT ALIGN_TOP">
<Property key="NeedKey" value = "true" /> <Property key="NeedKey" value = "true" />
<Property key="SkinLine" value = "MW_ListLine" /> <Property key="SkinLine" value = "MW_ListLine" />

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -26,34 +26,34 @@
<Widget type="TextBox" skin="SandTextRight" position="104 40 104 18" name="ClassText"/> <Widget type="TextBox" skin="SandTextRight" position="104 40 104 18" name="ClassText"/>
</Widget> </Widget>
<Widget type="Widget" skin="MW_Box" position="8 148 212 152"> <Widget type="Widget" skin="MW_Box" position="8 148 212 152" align="ALIGN_LEFT ALIGN_TOP ALIGN_VSTRETCH">
<Widget type="TextBox" skin="SandText" position="4 4 100 18" name="Attrib1"/> <Widget type="TextBox" skin="SandText" position="4 4 160 18" name="Attrib1"/>
<Widget type="TextBox" skin="SandTextRight" position="104 4 104 18" name="AttribVal1"/> <Widget type="TextBox" skin="SandTextRight" position="164 4 44 18" name="AttribVal1"/>
<Widget type="TextBox" skin="SandText" position="4 22 100 18" name="Attrib2"/> <Widget type="TextBox" skin="SandText" position="4 22 160 18" name="Attrib2"/>
<Widget type="TextBox" skin="SandTextRight" position="104 22 104 18" name="AttribVal2"/> <Widget type="TextBox" skin="SandTextRight" position="164 22 44 18" name="AttribVal2"/>
<Widget type="TextBox" skin="SandText" position="4 40 100 18" name="Attrib3"/> <Widget type="TextBox" skin="SandText" position="4 40 160 18" name="Attrib3"/>
<Widget type="TextBox" skin="SandTextRight" position="104 40 104 18" name="AttribVal3"/> <Widget type="TextBox" skin="SandTextRight" position="164 40 44 18" name="AttribVal3"/>
<Widget type="TextBox" skin="SandText" position="4 58 100 18" name="Attrib4"/> <Widget type="TextBox" skin="SandText" position="4 58 160 18" name="Attrib4"/>
<Widget type="TextBox" skin="SandTextRight" position="104 58 104 18" name="AttribVal4"/> <Widget type="TextBox" skin="SandTextRight" position="164 58 44 18" name="AttribVal4"/>
<Widget type="TextBox" skin="SandText" position="4 76 100 18" name="Attrib5"/> <Widget type="TextBox" skin="SandText" position="4 76 160 18" name="Attrib5"/>
<Widget type="TextBox" skin="SandTextRight" position="104 76 104 18" name="AttribVal5"/> <Widget type="TextBox" skin="SandTextRight" position="164 76 44 18" name="AttribVal5"/>
<Widget type="TextBox" skin="SandText" position="4 94 100 18" name="Attrib6"/> <Widget type="TextBox" skin="SandText" position="4 94 160 18" name="Attrib6"/>
<Widget type="TextBox" skin="SandTextRight" position="104 94 104 18" name="AttribVal6"/> <Widget type="TextBox" skin="SandTextRight" position="164 94 44 18" name="AttribVal6"/>
<Widget type="TextBox" skin="SandText" position="4 112 100 18" name="Attrib7"/> <Widget type="TextBox" skin="SandText" position="4 112 160 18" name="Attrib7"/>
<Widget type="TextBox" skin="SandTextRight" position="104 112 104 18" name="AttribVal7"/> <Widget type="TextBox" skin="SandTextRight" position="164 112 44 18" name="AttribVal7"/>
<Widget type="TextBox" skin="SandText" position="4 130 100 18" name="Attrib8"/> <Widget type="TextBox" skin="SandText" position="4 130 160 18" name="Attrib8"/>
<Widget type="TextBox" skin="SandTextRight" position="104 130 104 18" name="AttribVal8"/> <Widget type="TextBox" skin="SandTextRight" position="164 130 44 18" name="AttribVal8"/>
</Widget> </Widget>
<!-- Player skills, factions, birthsign and reputation --> <!-- Player skills, factions, birthsign and reputation -->
<Widget type="Widget" skin="MW_Box" position="228 8 248 292" align="ALIGN_LEFT ALIGN_VSTRETCH" name="Skills"> <Widget type="Widget" skin="MW_Box" position="228 8 248 292" align="ALIGN_LEFT ALIGN_STRETCH" name="Skills">
<Widget type="Widget" skin="" position="4 4 222 284" align="ALIGN_STRETCH" name="SkillClient" /> <Widget type="Widget" skin="" position="4 4 222 284" align="ALIGN_STRETCH" name="SkillClient" />
<Widget type="ScrollBar" skin="MW_VScroll" position="230 4 14 284" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="SkillScroller" /> <Widget type="ScrollBar" skin="MW_VScroll" position="230 4 14 284" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="SkillScroller" />
</Widget> </Widget>

View file

@ -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);
}

View file

@ -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