diff --git a/CMakeLists.txt b/CMakeLists.txt index d50cbe919..47575e0ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -206,7 +206,12 @@ IF(BOOST_STATIC) endif() find_package(OGRE REQUIRED) + find_package(MyGUI REQUIRED) +if (${MYGUI_VERSION} VERSION_LESS "3.2.1") + message(FATAL_ERROR "OpenMW requires MyGUI 3.2.1 or later, please install the latest version from http://mygui.info") +endif() + find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) find_package(SDL2 REQUIRED) find_package(OpenAL REQUIRED) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index a7e263b11..babde8ff2 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -1,16 +1,13 @@ # local files -if (NOT ANDROID) - set(GAME - main.cpp - engine.cpp - ) -else() - set(GAME - main.cpp - android_main.c - engine.cpp - ) +set(GAME + main.cpp + engine.cpp +) + +if (ANDROID) + set(GAME ${GAME} android_main.c) endif() + if(NOT WIN32 AND NOT ANDROID) set(GAME ${GAME} crashcatcher.cpp) endif() diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index bf64ee44e..02e143286 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -148,8 +148,11 @@ namespace MWBase virtual void getDoorMarkers (MWWorld::CellStore* cell, std::vector& out) = 0; ///< get a list of teleport door markers for a given cell, to be displayed on the local map - virtual void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y) = 0; - ///< see MWRender::LocalMap::getInteriorMapPosition + virtual void worldToInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y) = 0; + ///< see MWRender::LocalMap::worldToInteriorMapPosition + + virtual Ogre::Vector2 interiorMapToWorldPosition (float nX, float nY, int x, int y) = 0; + ///< see MWRender::LocalMap::interiorMapToWorldPosition virtual bool isPositionExplored (float nX, float nY, int x, int y, bool interior) = 0; ///< see MWRender::LocalMap::isPositionExplored diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index a541901ea..2593e6e77 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -61,8 +61,9 @@ namespace MWGui }; - HUD::HUD(int fpsLevel, DragAndDrop* dragAndDrop) + HUD::HUD(CustomMarkerCollection &customMarkers, int fpsLevel, DragAndDrop* dragAndDrop) : Layout("openmw_hud.layout") + , LocalMapBase(customMarkers) , mHealth(NULL) , mMagicka(NULL) , mStamina(NULL) @@ -161,7 +162,7 @@ namespace MWGui getWidget(mTriangleCounter, "TriangleCounter"); getWidget(mBatchCounter, "BatchCounter"); - LocalMapBase::init(mMinimap, mCompass, this); + LocalMapBase::init(mMinimap, mCompass); mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked); mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver); diff --git a/apps/openmw/mwgui/hud.hpp b/apps/openmw/mwgui/hud.hpp index bf0419aae..b41a374b6 100644 --- a/apps/openmw/mwgui/hud.hpp +++ b/apps/openmw/mwgui/hud.hpp @@ -15,7 +15,7 @@ namespace MWGui class HUD : public OEngine::GUI::Layout, public LocalMapBase { public: - HUD(int fpsLevel, DragAndDrop* dragAndDrop); + HUD(CustomMarkerCollection& customMarkers, int fpsLevel, DragAndDrop* dragAndDrop); virtual ~HUD(); void setValue (const std::string& id, const MWMechanics::DynamicStat& value); void setFPS(float fps); diff --git a/apps/openmw/mwgui/itemwidget.cpp b/apps/openmw/mwgui/itemwidget.cpp index 3e109384b..ade8f5731 100644 --- a/apps/openmw/mwgui/itemwidget.cpp +++ b/apps/openmw/mwgui/itemwidget.cpp @@ -35,26 +35,12 @@ namespace MWGui void ItemWidget::setIcon(const std::string &icon) { - // HACK HACK HACK: Don't setImageTexture if it hasn't changed. - // There is a leak in MyGUI for each setImageTexture on the same widget. - // http://www.ogre3d.org/addonforums/viewtopic.php?f=17&t=30251 - if (mCurrentItemTexture == icon) - return; - - mCurrentItemTexture = icon; if (mItem) mItem->setImageTexture(icon); } void ItemWidget::setFrame(const std::string &frame, const MyGUI::IntCoord &coord) { - // HACK HACK HACK: Don't setImageTexture if it hasn't changed. - // There is a leak in MyGUI for each setImageTexture on the same widget. - // http://www.ogre3d.org/addonforums/viewtopic.php?f=17&t=30251 - if (mCurrentFrameTexture == frame) - return; - - mCurrentFrameTexture = frame; if (mFrame) { mFrame->setImageTexture(frame); @@ -77,21 +63,8 @@ namespace MWGui if (ptr.isEmpty()) { if (mFrame) - { - // HACK HACK HACK: Don't setImageTexture if it hasn't changed. - // There is a leak in MyGUI for each setImageTexture on the same widget. - // http://www.ogre3d.org/addonforums/viewtopic.php?f=17&t=30251 - if (!mCurrentFrameTexture.empty()) - { - mFrame->setImageTexture(""); - mCurrentFrameTexture = ""; - } - } - if (!mCurrentItemTexture.empty()) - { - mCurrentItemTexture = ""; - mItem->setImageTexture(""); - } + mFrame->setImageTexture(""); + mItem->setImageTexture(""); return; } diff --git a/apps/openmw/mwgui/itemwidget.hpp b/apps/openmw/mwgui/itemwidget.hpp index 5cdf71212..3de98489d 100644 --- a/apps/openmw/mwgui/itemwidget.hpp +++ b/apps/openmw/mwgui/itemwidget.hpp @@ -42,9 +42,6 @@ namespace MWGui MyGUI::ImageBox* mItem; MyGUI::ImageBox* mFrame; - - std::string mCurrentItemTexture; - std::string mCurrentFrameTexture; }; } diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 1f2794be3..2271fc2e5 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -18,48 +18,131 @@ #include "widgets.hpp" +namespace +{ + + const int widgetSize = 512; + + const int cellSize = 8192; + + enum WidgetDepth + { + CompassLayer = 0, + MarkerAboveFogLayer = 1, + FogLayer = 2, + MarkerLayer = 3, + MapLayer = 4 + }; + +} + namespace MWGui { - LocalMapBase::LocalMapBase() + void CustomMarker::save(ESM::ESMWriter &esm) const + { + esm.writeHNT("POSX", mWorldX); + esm.writeHNT("POSY", mWorldY); + mCell.save(esm); + if (!mNote.empty()) + esm.writeHNString("NOTE", mNote); + } + + void CustomMarker::load(ESM::ESMReader &esm) + { + esm.getHNT(mWorldX, "POSX"); + esm.getHNT(mWorldY, "POSY"); + mCell.load(esm); + mNote = esm.getHNOString("NOTE"); + } + + // ------------------------------------------------------ + + void CustomMarkerCollection::addMarker(const CustomMarker &marker, bool triggerEvent) + { + mMarkers.push_back(marker); + if (triggerEvent) + eventMarkersChanged(); + } + + void CustomMarkerCollection::deleteMarker(const CustomMarker &marker) + { + std::vector::iterator it = std::find(mMarkers.begin(), mMarkers.end(), marker); + if (it != mMarkers.end()) + mMarkers.erase(it); + else + throw std::runtime_error("can't find marker to delete"); + + eventMarkersChanged(); + } + + void CustomMarkerCollection::updateMarker(const CustomMarker &marker, const std::string &newNote) + { + std::vector::iterator it = std::find(mMarkers.begin(), mMarkers.end(), marker); + if (it != mMarkers.end()) + it->mNote = newNote; + else + throw std::runtime_error("can't find marker to update"); + + eventMarkersChanged(); + } + + void CustomMarkerCollection::clear() + { + mMarkers.clear(); + eventMarkersChanged(); + } + + std::vector::const_iterator CustomMarkerCollection::begin() const + { + return mMarkers.begin(); + } + + std::vector::const_iterator CustomMarkerCollection::end() const + { + return mMarkers.end(); + } + + size_t CustomMarkerCollection::size() const + { + return mMarkers.size(); + } + + // ------------------------------------------------------ + + LocalMapBase::LocalMapBase(CustomMarkerCollection &markers) : mCurX(0) , mCurY(0) , mInterior(false) , mFogOfWar(true) , mLocalMap(NULL) - , mMapDragAndDrop(false) , mPrefix() , mChanged(true) - , mLayout(NULL) , mLastPositionX(0.0f) , mLastPositionY(0.0f) , mLastDirectionX(0.0f) , mLastDirectionY(0.0f) , mCompass(NULL) , mMarkerUpdateTimer(0.0f) + , mCustomMarkers(markers) { + mCustomMarkers.eventMarkersChanged += MyGUI::newDelegate(this, &LocalMapBase::updateCustomMarkers); } LocalMapBase::~LocalMapBase() { - // Clear our "lost focus" delegate for marker widgets first, otherwise it will - // fire when the widget is about to be destroyed and the mouse cursor is over it. - // At that point, other widgets may already be destroyed, so applyFogOfWar (which is called by the delegate) would crash. - for (std::vector::iterator it = mDoorMarkerWidgets.begin(); it != mDoorMarkerWidgets.end(); ++it) - (*it)->eventMouseLostFocus.clear(); - for (std::vector::iterator it = mMarkerWidgets.begin(); it != mMarkerWidgets.end(); ++it) - (*it)->eventMouseLostFocus.clear(); + mCustomMarkers.eventMarkersChanged -= MyGUI::newDelegate(this, &LocalMapBase::updateCustomMarkers); } - void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop) + void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass) { mLocalMap = widget; - mLayout = layout; - mMapDragAndDrop = mapDragAndDrop; mCompass = compass; + mCompass->setDepth(CompassLayer); + mCompass->setNeedMouseFocus(false); + // create 3x3 map widgets, 512x512 each, holding a 1024x1024 texture each - const int widgetSize = 512; for (int mx=0; mx<3; ++mx) { for (int my=0; my<3; ++my) @@ -67,16 +150,15 @@ namespace MWGui MyGUI::ImageBox* map = mLocalMap->createWidget("ImageBox", MyGUI::IntCoord(mx*widgetSize, my*widgetSize, widgetSize, widgetSize), MyGUI::Align::Top | MyGUI::Align::Left); + map->setDepth(MapLayer); - MyGUI::ImageBox* fog = map->createWidget("ImageBox", - MyGUI::IntCoord(0, 0, widgetSize, widgetSize), + MyGUI::ImageBox* fog = mLocalMap->createWidget("ImageBox", + MyGUI::IntCoord(mx*widgetSize, my*widgetSize, widgetSize, widgetSize), MyGUI::Align::Top | MyGUI::Align::Left); + fog->setDepth(FogLayer); - if (!mMapDragAndDrop) - { - map->setNeedMouseFocus(false); - fog->setNeedMouseFocus(false); - } + map->setNeedMouseFocus(false); + fog->setNeedMouseFocus(false); mMapWidgets.push_back(map); mFogWidgets.push_back(fog); @@ -112,19 +194,7 @@ namespace MWGui : ""); } } - notifyMapChanged (); - } - - void LocalMapBase::onMarkerFocused (MyGUI::Widget* w1, MyGUI::Widget* w2) - { - // Workaround to not make the marker visible if it's under fog of war - applyFogOfWar (); - } - - void LocalMapBase::onMarkerUnfocused (MyGUI::Widget* w1, MyGUI::Widget* w2) - { - // Workaround to not make the marker visible if it's under fog of war - applyFogOfWar (); + redraw(); } MyGUI::IntPoint LocalMapBase::getMarkerPosition(float worldX, float worldY, MarkerPosition& markerPos) @@ -139,7 +209,6 @@ namespace MWGui { int cellX, cellY; MWBase::Environment::get().getWorld()->positionToIndex(worldX, worldY, cellX, cellY); - const int cellSize = 8192; nX = (worldX - cellSize * cellX) / cellSize; // Image space is -Y up, cells are Y up nY = 1 - (worldY - cellSize * cellY) / cellSize; @@ -150,21 +219,21 @@ namespace MWGui markerPos.cellX = cellX; markerPos.cellY = cellY; - widgetPos = MyGUI::IntPoint(nX * 512 + (1+cellDx) * 512, - nY * 512 - (cellDy-1) * 512); + widgetPos = MyGUI::IntPoint(nX * widgetSize + (1+cellDx) * widgetSize, + nY * widgetSize - (cellDy-1) * widgetSize); } else { int cellX, cellY; Ogre::Vector2 worldPos (worldX, worldY); - MWBase::Environment::get().getWorld ()->getInteriorMapPosition (worldPos, nX, nY, cellX, cellY); + MWBase::Environment::get().getWorld ()->worldToInteriorMapPosition (worldPos, nX, nY, cellX, cellY); markerPos.cellX = cellX; markerPos.cellY = cellY; // Image space is -Y up, cells are Y up - widgetPos = MyGUI::IntPoint(nX * 512 + (1+(cellX-mCurX)) * 512, - nY * 512 + (1-(cellY-mCurY)) * 512); + widgetPos = MyGUI::IntPoint(nX * widgetSize + (1+(cellX-mCurX)) * widgetSize, + nY * widgetSize + (1-(cellY-mCurY)) * widgetSize); } markerPos.nX = nX; @@ -172,6 +241,52 @@ namespace MWGui return widgetPos; } + void LocalMapBase::updateCustomMarkers() + { + for (std::vector::iterator it = mCustomMarkerWidgets.begin(); it != mCustomMarkerWidgets.end(); ++it) + MyGUI::Gui::getInstance().destroyWidget(*it); + mCustomMarkerWidgets.clear(); + + for (std::vector::const_iterator it = mCustomMarkers.begin(); it != mCustomMarkers.end(); ++it) + { + const CustomMarker& marker = *it; + + if (marker.mCell.mPaged != !mInterior) + continue; + if (mInterior) + { + if (marker.mCell.mWorldspace != mPrefix) + continue; + } + else + { + if (std::abs(marker.mCell.mIndex.mX - mCurX) > 1) + continue; + if (std::abs(marker.mCell.mIndex.mY - mCurY) > 1) + continue; + } + + MarkerPosition markerPos; + MyGUI::IntPoint widgetPos = getMarkerPosition(marker.mWorldX, marker.mWorldY, markerPos); + + MyGUI::IntCoord widgetCoord(widgetPos.left - 4, + widgetPos.top - 4, + 8, 8); + MyGUI::Button* markerWidget = mLocalMap->createWidget("ButtonImage", + widgetCoord, MyGUI::Align::Default); + markerWidget->setDepth(MarkerAboveFogLayer); + markerWidget->setImageResource("DoorMarker"); + markerWidget->setUserString("ToolTipType", "Layout"); + markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine"); + markerWidget->setUserString("Caption_TextOneLine", MyGUI::TextIterator::toTagsString(marker.mNote)); + markerWidget->setColour(MyGUI::Colour(1.0,0.3,0.3)); + markerWidget->setUserData(marker); + markerWidget->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &LocalMapBase::onCustomMarkerDoubleClicked); + mCustomMarkerWidgets.push_back(markerWidget); + } + redraw(); + } + void LocalMapBase::setActiveCell(const int x, const int y, bool interior) { if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) @@ -182,6 +297,9 @@ namespace MWGui mInterior = interior; mChanged = false; + applyFogOfWar(); + + // clear all previous door markers for (std::vector::iterator it = mDoorMarkerWidgets.begin(); it != mDoorMarkerWidgets.end(); ++it) MyGUI::Gui::getInstance().destroyWidget(*it); @@ -240,12 +358,11 @@ namespace MWGui ++counter; MyGUI::Button* markerWidget = mLocalMap->createWidget("ButtonImage", widgetCoord, MyGUI::Align::Default); + markerWidget->setDepth(MarkerLayer); markerWidget->setImageResource("DoorMarker"); markerWidget->setUserString("ToolTipType", "Layout"); markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine"); markerWidget->setUserString("Caption_TextOneLine", marker.name); - markerWidget->eventMouseSetFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerFocused); - markerWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerUnfocused); // Used by tooltips to not show the tooltip if marker is hidden by fog of war markerWidget->setUserString("IsMarker", "true"); markerWidget->setUserData(markerPos); @@ -253,21 +370,19 @@ namespace MWGui mDoorMarkerWidgets.push_back(markerWidget); } - updateMarkers(); - - applyFogOfWar(); - - // set the compass texture again, because MyGUI determines sorting of ImageBox widgets - // based on the last setImageTexture call - std::string tex = "textures\\compass.dds"; - mCompass->setImageTexture(""); - mCompass->setImageTexture(tex); + updateMagicMarkers(); + updateCustomMarkers(); } + void LocalMapBase::redraw() + { + // Redraw children in proper order + mLocalMap->getParent()->_updateChilds(); + } void LocalMapBase::setPlayerPos(const float x, const float y) { - updateMarkers(); + updateMagicMarkers(); if (x == mLastPositionX && y == mLastPositionY) return; @@ -280,7 +395,7 @@ namespace MWGui MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); mLocalMap->setViewOffset(pos); - mCompass->setPosition(MyGUI::IntPoint(512+x*512-16, 512+y*512-16)); + mCompass->setPosition(MyGUI::IntPoint(widgetSize+x*widgetSize-16, widgetSize+y*widgetSize-16)); mLastPositionX = x; mLastPositionY = y; } @@ -342,11 +457,12 @@ namespace MWGui ++counter; MyGUI::ImageBox* markerWidget = mLocalMap->createWidget("ImageBox", widgetCoord, MyGUI::Align::Default); + markerWidget->setDepth(MarkerAboveFogLayer); markerWidget->setImageTexture(markerTexture); markerWidget->setUserString("IsMarker", "true"); markerWidget->setUserData(markerPos); markerWidget->setColour(markerColour); - mMarkerWidgets.push_back(markerWidget); + mMagicMarkerWidgets.push_back(markerWidget); } } @@ -357,16 +473,16 @@ namespace MWGui if (mMarkerUpdateTimer >= 0.25) { mMarkerUpdateTimer = 0; - updateMarkers(); + updateMagicMarkers(); } } - void LocalMapBase::updateMarkers() + void LocalMapBase::updateMagicMarkers() { // clear all previous markers - for (std::vector::iterator it = mMarkerWidgets.begin(); it != mMarkerWidgets.end(); ++it) + for (std::vector::iterator it = mMagicMarkerWidgets.begin(); it != mMagicMarkerWidgets.end(); ++it) MyGUI::Gui::getInstance().destroyWidget(*it); - mMarkerWidgets.clear(); + mMagicMarkerWidgets.clear(); addDetectionMarkers(MWBase::World::Detect_Creature); addDetectionMarkers(MWBase::World::Detect_Key); @@ -386,22 +502,31 @@ namespace MWGui 8, 8); MyGUI::ImageBox* markerWidget = mLocalMap->createWidget("ImageBox", widgetCoord, MyGUI::Align::Default); + markerWidget->setDepth(MarkerAboveFogLayer); markerWidget->setImageTexture("textures\\menu_map_smark.dds"); markerWidget->setUserString("IsMarker", "true"); markerWidget->setUserData(markerPos); - mMarkerWidgets.push_back(markerWidget); + mMagicMarkerWidgets.push_back(markerWidget); } + + redraw(); } // ------------------------------------------------------------------------------------------ - MapWindow::MapWindow(DragAndDrop* drag, const std::string& cacheDir) + MapWindow::MapWindow(CustomMarkerCollection &customMarkers, DragAndDrop* drag, const std::string& cacheDir) : WindowPinnableBase("openmw_map_window.layout") , NoDrop(drag, mMainWidget) + , LocalMapBase(customMarkers) , mGlobal(false) , mGlobalMap(0) , mGlobalMapRender(0) + , mEditNoteDialog() { + mEditNoteDialog.setVisible(false); + mEditNoteDialog.eventOkClicked += MyGUI::newDelegate(this, &MapWindow::onNoteEditOk); + mEditNoteDialog.eventDeleteClicked += MyGUI::newDelegate(this, &MapWindow::onNoteEditDelete); + setCoord(500,0,320,300); getWidget(mLocalMap, "LocalMap"); @@ -423,8 +548,78 @@ namespace MWGui getWidget(mEventBoxLocal, "EventBoxLocal"); mEventBoxLocal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); mEventBoxLocal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); + mEventBoxLocal->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &MapWindow::onMapDoubleClicked); + + LocalMapBase::init(mLocalMap, mPlayerArrowLocal); + } + + void MapWindow::onNoteEditOk() + { + if (mEditNoteDialog.getDeleteButtonShown()) + mCustomMarkers.updateMarker(mEditingMarker, mEditNoteDialog.getText()); + else + { + mEditingMarker.mNote = mEditNoteDialog.getText(); + mCustomMarkers.addMarker(mEditingMarker); + } + + mEditNoteDialog.setVisible(false); + } + + void MapWindow::onNoteEditDelete() + { + mCustomMarkers.deleteMarker(mEditingMarker); + + mEditNoteDialog.setVisible(false); + } - LocalMapBase::init(mLocalMap, mPlayerArrowLocal, this); + void MapWindow::onCustomMarkerDoubleClicked(MyGUI::Widget *sender) + { + mEditingMarker = *sender->getUserData(); + mEditNoteDialog.setText(mEditingMarker.mNote); + mEditNoteDialog.showDeleteButton(true); + mEditNoteDialog.setVisible(true); + } + + void MapWindow::onMapDoubleClicked(MyGUI::Widget *sender) + { + MyGUI::IntPoint clickedPos = MyGUI::InputManager::getInstance().getMousePosition(); + + MyGUI::IntPoint widgetPos = clickedPos - mEventBoxLocal->getAbsolutePosition(); + int x = int(widgetPos.left/float(widgetSize))-1; + int y = (int(widgetPos.top/float(widgetSize))-1)*-1; + float nX = widgetPos.left/float(widgetSize) - int(widgetPos.left/float(widgetSize)); + float nY = widgetPos.top/float(widgetSize) - int(widgetPos.top/float(widgetSize)); + x += mCurX; + y += mCurY; + + Ogre::Vector2 worldPos; + if (mInterior) + { + worldPos = MWBase::Environment::get().getWorld()->interiorMapToWorldPosition(nX, nY, x, y); + } + else + { + worldPos.x = (x + nX) * cellSize; + worldPos.y = (y + (1.0-nY)) * cellSize; + } + + mEditingMarker.mWorldX = worldPos.x; + mEditingMarker.mWorldY = worldPos.y; + + mEditingMarker.mCell.mPaged = !mInterior; + if (mInterior) + mEditingMarker.mCell.mWorldspace = LocalMapBase::mPrefix; + else + { + mEditingMarker.mCell.mWorldspace = "sys::default"; + mEditingMarker.mCell.mIndex.mX = x; + mEditingMarker.mCell.mIndex.mY = y; + } + + mEditNoteDialog.setVisible(true); + mEditNoteDialog.showDeleteButton(false); + mEditNoteDialog.setText(""); } void MapWindow::renderGlobalMap(Loading::Listener* loadingListener) @@ -545,9 +740,6 @@ namespace MWGui void MapWindow::open() { globalMapUpdatePlayer(); - - mPlayerArrowGlobal->setImageTexture (""); - mPlayerArrowGlobal->setImageTexture ("textures\\compass.dds"); } void MapWindow::globalMapUpdatePlayer () @@ -584,20 +776,6 @@ namespace MWGui globalMapUpdatePlayer (); } - void MapWindow::notifyMapChanged () - { - // workaround to prevent the map from drawing on top of the button - MyGUI::IntCoord oldCoord = mButton->getCoord (); - MyGUI::Gui::getInstance().destroyWidget (mButton); - mButton = mMainWidget->createWidget("MW_Button", - oldCoord, MyGUI::Align::Bottom | MyGUI::Align::Right); - mButton->setProperty ("ExpandDirection", "Left"); - - mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); - mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" : - "#{sWorld}"); - } - void MapWindow::setGlobalMapPlayerPosition(float worldX, float worldY) { float x, y; @@ -617,6 +795,7 @@ namespace MWGui { mMarkers.clear(); mGlobalMapRender->clear(); + mChanged = true; while (mEventBoxGlobal->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(mEventBoxGlobal->getChildAt(0)); @@ -654,4 +833,67 @@ namespace MWGui } } } + + // ------------------------------------------------------------------- + + EditNoteDialog::EditNoteDialog() + : WindowModal("openmw_edit_note.layout") + { + getWidget(mOkButton, "OkButton"); + getWidget(mCancelButton, "CancelButton"); + getWidget(mDeleteButton, "DeleteButton"); + getWidget(mTextEdit, "TextEdit"); + + mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditNoteDialog::onCancelButtonClicked); + mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditNoteDialog::onOkButtonClicked); + mDeleteButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditNoteDialog::onDeleteButtonClicked); + } + + void EditNoteDialog::showDeleteButton(bool show) + { + mDeleteButton->setVisible(show); + } + + bool EditNoteDialog::getDeleteButtonShown() + { + return mDeleteButton->getVisible(); + } + + void EditNoteDialog::setText(const std::string &text) + { + mTextEdit->setCaption(MyGUI::TextIterator::toTagsString(text)); + } + + std::string EditNoteDialog::getText() + { + return MyGUI::TextIterator::getOnlyText(mTextEdit->getCaption()); + } + + void EditNoteDialog::open() + { + WindowModal::open(); + center(); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit); + } + + void EditNoteDialog::exit() + { + setVisible(false); + } + + void EditNoteDialog::onCancelButtonClicked(MyGUI::Widget *sender) + { + setVisible(false); + } + + void EditNoteDialog::onOkButtonClicked(MyGUI::Widget *sender) + { + eventOkClicked(); + } + + void EditNoteDialog::onDeleteButtonClicked(MyGUI::Widget *sender) + { + eventDeleteClicked(); + } + } diff --git a/apps/openmw/mwgui/mapwindow.hpp b/apps/openmw/mwgui/mapwindow.hpp index 7021a5d62..1c7ba34ed 100644 --- a/apps/openmw/mwgui/mapwindow.hpp +++ b/apps/openmw/mwgui/mapwindow.hpp @@ -5,6 +5,8 @@ #include "windowpinnablebase.hpp" +#include + namespace MWRender { class GlobalMap; @@ -23,12 +25,52 @@ namespace Loading namespace MWGui { + + struct CustomMarker + { + float mWorldX; + float mWorldY; + + ESM::CellId mCell; + + std::string mNote; + + bool operator == (const CustomMarker& other) + { + return mNote == other.mNote && mCell == other.mCell && mWorldX == other.mWorldX && mWorldY == other.mWorldY; + } + + void load (ESM::ESMReader& reader); + void save (ESM::ESMWriter& writer) const; + }; + + class CustomMarkerCollection + { + public: + void addMarker(const CustomMarker& marker, bool triggerEvent=true); + void deleteMarker (const CustomMarker& marker); + void updateMarker(const CustomMarker& marker, const std::string& newNote); + + void clear(); + + size_t size() const; + + std::vector::const_iterator begin() const; + std::vector::const_iterator end() const; + + typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; + EventHandle_Void eventMarkersChanged; + + private: + std::vector mMarkers; + }; + class LocalMapBase { public: - LocalMapBase(); + LocalMapBase(CustomMarkerCollection& markers); virtual ~LocalMapBase(); - void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop=false); + void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass); void setCellPrefix(const std::string& prefix); void setActiveCell(const int x, const int y, bool interior=false); @@ -57,44 +99,74 @@ namespace MWGui bool mChanged; bool mFogOfWar; + // Stores markers that were placed by a player. May be shared between multiple map views. + CustomMarkerCollection& mCustomMarkers; + std::vector mMapWidgets; std::vector mFogWidgets; // Keep track of created marker widgets, just to easily remove them later. - std::vector mDoorMarkerWidgets; // Doors - std::vector mMarkerWidgets; // Other markers + std::vector mDoorMarkerWidgets; + std::vector mMagicMarkerWidgets; + std::vector mCustomMarkerWidgets; - void applyFogOfWar(); + void updateCustomMarkers(); - void onMarkerFocused(MyGUI::Widget* w1, MyGUI::Widget* w2); - void onMarkerUnfocused(MyGUI::Widget* w1, MyGUI::Widget* w2); + void applyFogOfWar(); MyGUI::IntPoint getMarkerPosition (float worldX, float worldY, MarkerPosition& markerPos); virtual void notifyPlayerUpdate() {} virtual void notifyMapChanged() {} - // Update markers (Detect X effects, Mark/Recall effects) - // Note, door markers are handled in setActiveCell - void updateMarkers(); + virtual void onCustomMarkerDoubleClicked(MyGUI::Widget* sender) {} + + void updateMagicMarkers(); void addDetectionMarkers(int type); - OEngine::GUI::Layout* mLayout; + void redraw(); float mMarkerUpdateTimer; - bool mMapDragAndDrop; - float mLastPositionX; float mLastPositionY; float mLastDirectionX; float mLastDirectionY; }; + class EditNoteDialog : public MWGui::WindowModal + { + public: + EditNoteDialog(); + + virtual void open(); + virtual void exit(); + + void showDeleteButton(bool show); + bool getDeleteButtonShown(); + void setText(const std::string& text); + std::string getText(); + + typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; + + EventHandle_Void eventDeleteClicked; + EventHandle_Void eventOkClicked; + + private: + void onCancelButtonClicked(MyGUI::Widget* sender); + void onOkButtonClicked(MyGUI::Widget* sender); + void onDeleteButtonClicked(MyGUI::Widget* sender); + + MyGUI::TextBox* mTextEdit; + MyGUI::Button* mOkButton; + MyGUI::Button* mCancelButton; + MyGUI::Button* mDeleteButton; + }; + class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase, public NoDrop { public: - MapWindow(DragAndDrop* drag, const std::string& cacheDir); + MapWindow(CustomMarkerCollection& customMarkers, DragAndDrop* drag, const std::string& cacheDir); virtual ~MapWindow(); void setCellName(const std::string& cellName); @@ -123,7 +195,10 @@ namespace MWGui void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onWorldButtonClicked(MyGUI::Widget* _sender); - + void onMapDoubleClicked(MyGUI::Widget* sender); + void onNoteEditOk(); + void onNoteEditDelete(); + void onNoteDoubleClicked(MyGUI::Widget* sender); void globalMapUpdatePlayer(); MyGUI::ScrollView* mGlobalMap; @@ -148,12 +223,14 @@ namespace MWGui MWRender::GlobalMap* mGlobalMapRender; - protected: + EditNoteDialog mEditNoteDialog; + CustomMarker mEditingMarker; + virtual void onPinToggled(); virtual void onTitleDoubleClicked(); + virtual void onCustomMarkerDoubleClicked(MyGUI::Widget* sender); virtual void notifyPlayerUpdate(); - virtual void notifyMapChanged(); }; } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 7c0baaffe..780580e2a 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -207,14 +207,12 @@ namespace MWGui mVideoWidget->setNeedMouseFocus(true); mVideoWidget->setNeedKeyFocus(true); -#if MYGUI_VERSION >= MYGUI_DEFINE_VERSION(3,2,1) // Removes default MyGUI system clipboard implementation, which supports windows only MyGUI::ClipboardManager::getInstance().eventClipboardChanged.clear(); MyGUI::ClipboardManager::getInstance().eventClipboardRequested.clear(); MyGUI::ClipboardManager::getInstance().eventClipboardChanged += MyGUI::newDelegate(this, &WindowManager::onClipboardChanged); MyGUI::ClipboardManager::getInstance().eventClipboardRequested += MyGUI::newDelegate(this, &WindowManager::onClipboardRequested); -#endif } void WindowManager::initUI() @@ -227,7 +225,7 @@ namespace MWGui mRecharge = new Recharge(); mMenu = new MainMenu(w,h); - mMap = new MapWindow(mDragAndDrop, ""); + mMap = new MapWindow(mCustomMarkers, mDragAndDrop, ""); trackWindow(mMap, "map"); mStatsWindow = new StatsWindow(mDragAndDrop); trackWindow(mStatsWindow, "stats"); @@ -245,7 +243,7 @@ namespace MWGui trackWindow(mDialogueWindow, "dialogue"); mContainerWindow = new ContainerWindow(mDragAndDrop); trackWindow(mContainerWindow, "container"); - mHud = new HUD(mShowFPSLevel, mDragAndDrop); + mHud = new HUD(mCustomMarkers, mShowFPSLevel, mDragAndDrop); mToolTips = new ToolTips(); mScrollWindow = new ScrollWindow(); mBookWindow = new BookWindow(); @@ -1532,6 +1530,8 @@ namespace MWGui mSelectedSpell.clear(); + mCustomMarkers.clear(); + mGuiModes.clear(); MWBase::Environment::get().getInputManager()->changeInputMode(false); updateVisible(); @@ -1551,6 +1551,14 @@ namespace MWGui writer.endRecord(ESM::REC_ASPL); progress.increaseProgress(); } + + for (std::vector::const_iterator it = mCustomMarkers.begin(); it != mCustomMarkers.end(); ++it) + { + writer.startRecord(ESM::REC_MARK); + (*it).save(writer); + writer.endRecord(ESM::REC_MARK); + progress.increaseProgress(); + } } void WindowManager::readRecord(ESM::ESMReader &reader, int32_t type) @@ -1564,12 +1572,19 @@ namespace MWGui reader.getSubNameIs("ID__"); mSelectedSpell = reader.getHString(); } + else if (type == ESM::REC_MARK) + { + CustomMarker marker; + marker.load(reader); + mCustomMarkers.addMarker(marker, false); + } } int WindowManager::countSavedGameRecords() const { return 1 // Global map + 1 // QuickKeysMenu + + mCustomMarkers.size() + (!mSelectedSpell.empty() ? 1 : 0); } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 76bab8fc8..00a5ce80e 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -12,6 +12,8 @@ #include "../mwbase/windowmanager.hpp" +#include "mapwindow.hpp" + #include #include @@ -345,6 +347,9 @@ namespace MWGui std::stack mCurrentModals; + // Markers placed manually by the player. Must be shared between both map views (the HUD map and the map window). + CustomMarkerCollection mCustomMarkers; + OEngine::GUI::MyGUIManager *mGuiManager; OEngine::Render::OgreRenderer *mRendering; HUD *mHud; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 132ed3326..e1f7c31fc 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -498,48 +498,6 @@ namespace MWInput void InputManager::keyPressed( const SDL_KeyboardEvent &arg ) { -#if MYGUI_VERSION <= MYGUI_DEFINE_VERSION(3,2,0) - // Cut, copy & paste - MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); - if (focus) - { - MyGUI::EditBox* edit = focus->castType(false); - if (edit && !edit->getEditReadOnly()) - { - if (arg.keysym.sym == SDLK_v && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL))) - { - char* text = SDL_GetClipboardText(); - - if (text) - { - edit->insertText(MyGUI::UString(text), edit->getTextCursor()); - SDL_free(text); - } - } - if (arg.keysym.sym == SDLK_x && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL))) - { - // Discard color codes and other escape characters - std::string text = MyGUI::TextIterator::getOnlyText(edit->getTextSelection()); - if (text.length()) - { - SDL_SetClipboardText(text.c_str()); - edit->deleteTextSelection(); - } - } - } - if (edit && !edit->getEditStatic()) - { - if (arg.keysym.sym == SDLK_c && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL))) - { - // Discard color codes and other escape characters - std::string text = MyGUI::TextIterator::getOnlyText(edit->getTextSelection()); - if (text.length()) - SDL_SetClipboardText(text.c_str()); - } - } - } -#endif - OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); bool consumed = false; @@ -552,12 +510,6 @@ namespace MWInput } if (!mControlsDisabled && !consumed) mInputBinder->keyPressed (arg); - - // Clear MyGUI's clipboard, so it doesn't interfere with our own clipboard implementation. - // We do not use MyGUI's clipboard manager because it doesn't support system clipboard integration with SDL. -#if MYGUI_VERSION <= MYGUI_DEFINE_VERSION(3,2,0) - MyGUI::ClipboardManager::getInstance().clearClipboardData("Text"); -#endif } void InputManager::textInput(const SDL_TextInputEvent &arg) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index ace105b2d..85f73ab7e 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -431,7 +431,7 @@ void LocalMap::render(const float x, const float y, mRendering->getScene()->setAmbientLight(oldAmbient); } -void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y) +void LocalMap::worldToInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y) { pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().y), mAngle); @@ -444,6 +444,18 @@ void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, nY = 1.0-(pos.y - min.y - sSize*y)/sSize; } +Ogre::Vector2 LocalMap::interiorMapToWorldPosition (float nX, float nY, int x, int y) +{ + Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y); + Ogre::Vector2 pos; + + pos.x = sSize * (nX + x) + min.x; + pos.y = sSize * (1.0-nY + y) + min.y; + + pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().y), -mAngle); + return pos; +} + bool LocalMap::isPositionExplored (float nX, float nY, int x, int y, bool interior) { std::string texName = (interior ? mInteriorName + "_" : "Cell_") + coordStr(x, y); @@ -502,7 +514,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni Vector2 pos(position.x, position.y); if (mInterior) - getInteriorMapPosition(pos, u,v, x,y); + worldToInteriorMapPosition(pos, u,v, x,y); Vector3 playerdirection = mCameraRotNode->convertWorldToLocalOrientation(orientation).yAxis(); diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index aed7e0637..b531c3e29 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -74,7 +74,9 @@ namespace MWRender * Get the interior map texture index and normalized position * on this texture, given a world position */ - void getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y); + void worldToInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y); + + Ogre::Vector2 interiorMapToWorldPosition (float nX, float nY, int x, int y); /** * Check if a given position is explored by the player (i.e. not obscured by fog of war) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 46ff57cb0..15bac7454 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -945,9 +945,14 @@ void RenderingManager::setCameraDistance(float dist, bool adjust, bool override) } } -void RenderingManager::getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y) +void RenderingManager::worldToInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y) { - return mLocalMap->getInteriorMapPosition (position, nX, nY, x, y); + return mLocalMap->worldToInteriorMapPosition (position, nX, nY, x, y); +} + +Ogre::Vector2 RenderingManager::interiorMapToWorldPosition(float nX, float nY, int x, int y) +{ + return mLocalMap->interiorMapToWorldPosition(nX, nY, x, y); } bool RenderingManager::isPositionExplored (float nX, float nY, int x, int y, bool interior) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index ef436931d..c5a77afc7 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -198,8 +198,11 @@ public: Ogre::Viewport* getViewport() { return mRendering.getViewport(); } - void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y); - ///< see MWRender::LocalMap::getInteriorMapPosition + void worldToInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y); + ///< see MWRender::LocalMap::worldToInteriorMapPosition + + Ogre::Vector2 interiorMapToWorldPosition (float nX, float nY, int x, int y); + ///< see MWRender::LocalMap::interiorMapToWorldPosition bool isPositionExplored (float nX, float nY, int x, int y, bool interior); ///< see MWRender::LocalMap::isPositionExplored diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 96f14d7e9..80851d573 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -363,6 +363,7 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl case ESM::REC_GMAP: case ESM::REC_KEYS: case ESM::REC_ASPL: + case ESM::REC_MARK: MWBase::Environment::get().getWindowManager()->readRecord(reader, n.val); break; @@ -375,7 +376,7 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl default: // ignore invalid records - /// \todo log error + std::cerr << "Ignoring unknown record: " << n.name << std::endl; reader.skipRecord(); } listener.increaseProgress(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 89741dc74..f19a40313 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1627,9 +1627,14 @@ namespace MWWorld } } - void World::getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y) + void World::worldToInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y) { - mRendering->getInteriorMapPosition(position, nX, nY, x, y); + mRendering->worldToInteriorMapPosition(position, nX, nY, x, y); + } + + Ogre::Vector2 World::interiorMapToWorldPosition(float nX, float nY, int x, int y) + { + return mRendering->interiorMapToWorldPosition(nX, nY, x, y); } bool World::isPositionExplored (float nX, float nY, int x, int y, bool interior) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index ad166c91a..4dade0f21 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -210,8 +210,11 @@ namespace MWWorld virtual void getDoorMarkers (MWWorld::CellStore* cell, std::vector& out); ///< get a list of teleport door markers for a given cell, to be displayed on the local map - virtual void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y); - ///< see MWRender::LocalMap::getInteriorMapPosition + virtual void worldToInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y); + ///< see MWRender::LocalMap::worldToInteriorMapPosition + + virtual Ogre::Vector2 interiorMapToWorldPosition (float nX, float nY, int x, int y); + ///< see MWRender::LocalMap::interiorMapToWorldPosition virtual bool isPositionExplored (float nX, float nY, int x, int y, bool interior); ///< see MWRender::LocalMap::isPositionExplored diff --git a/cmake/FindMyGUI.cmake b/cmake/FindMyGUI.cmake index ebf069404..40fa2373f 100644 --- a/cmake/FindMyGUI.cmake +++ b/cmake/FindMyGUI.cmake @@ -12,6 +12,7 @@ # For details see the accompanying COPYING-CMAKE-SCRIPTS file. CMAKE_POLICY(PUSH) include(FindPkgMacros) +include(PreprocessorUtils) # IF (MYGUI_LIBRARIES AND MYGUI_INCLUDE_DIRS) # SET(MYGUI_FIND_QUIETLY TRUE) @@ -131,6 +132,18 @@ IF (MYGUI_FOUND) MESSAGE(STATUS " libraries : ${MYGUI_LIBRARIES} from ${MYGUI_LIB_DIR}") MESSAGE(STATUS " includes : ${MYGUI_INCLUDE_DIRS}") ENDIF (NOT MYGUI_FIND_QUIETLY) + + find_file(MYGUI_PREQUEST_FILE NAMES MyGUI_Prerequest.h PATHS ${MYGUI_INCLUDE_DIRS}) + file(READ ${MYGUI_PREQUEST_FILE} MYGUI_TEMP_VERSION_CONTENT) + get_preprocessor_entry(MYGUI_TEMP_VERSION_CONTENT MYGUI_VERSION_MAJOR MYGUI_VERSION_MAJOR) + get_preprocessor_entry(MYGUI_TEMP_VERSION_CONTENT MYGUI_VERSION_MINOR MYGUI_VERSION_MINOR) + get_preprocessor_entry(MYGUI_TEMP_VERSION_CONTENT MYGUI_VERSION_PATCH MYGUI_VERSION_PATCH) + set(MYGUI_VERSION "${MYGUI_VERSION_MAJOR}.${MYGUI_VERSION_MINOR}.${MYGUI_VERSION_PATCH}") + + IF (NOT MYGUI_FIND_QUIETLY) + MESSAGE(STATUS "MyGUI version: ${MYGUI_VERSION}") + ENDIF (NOT MYGUI_FIND_QUIETLY) + ELSE (MYGUI_FOUND) IF (MYGUI_FIND_REQUIRED) MESSAGE(FATAL_ERROR "Could not find MYGUI") diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index f967af274..6ef0f77fb 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -112,6 +112,7 @@ enum RecNameInts REC_MPRJ = FourCC<'M','P','R','J'>::value, REC_PROJ = FourCC<'P','R','O','J'>::value, REC_DCOU = FourCC<'D','C','O','U'>::value, + REC_MARK = FourCC<'M','A','R','K'>::value, // format 1 REC_FILT = 0x544C4946 diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index 54a4d0b63..a59535090 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -81,6 +81,7 @@ set(MYGUI_FILES openmw_savegame_dialog.layout openmw_recharge_dialog.layout openmw_screen_fader.layout + openmw_edit_note.layout DejaVuLGCSansMono.ttf markers.png ../launcher/images/openmw.png diff --git a/files/mygui/openmw_edit.skin.xml b/files/mygui/openmw_edit.skin.xml index 50f37dbfc..9a872c576 100644 --- a/files/mygui/openmw_edit.skin.xml +++ b/files/mygui/openmw_edit.skin.xml @@ -40,4 +40,21 @@ + + + + + + + + + + + + + + + + + diff --git a/files/mygui/openmw_edit_note.layout b/files/mygui/openmw_edit_note.layout new file mode 100644 index 000000000..4985b5187 --- /dev/null +++ b/files/mygui/openmw_edit_note.layout @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/mygui/openmw_map_window.layout b/files/mygui/openmw_map_window.layout index b842888a1..605c3d6ff 100644 --- a/files/mygui/openmw_map_window.layout +++ b/files/mygui/openmw_map_window.layout @@ -12,7 +12,9 @@ - + + + @@ -28,7 +30,6 @@ -