mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-19 19:39:41 +00:00
[Local map] Allow zoom on local map
This commit is contained in:
parent
9fadbd5b7a
commit
ed04ebe9ff
2 changed files with 100 additions and 14 deletions
|
@ -252,8 +252,8 @@ namespace MWGui
|
|||
// normalized cell coordinates
|
||||
auto mapWidgetSize = getWidgetSize();
|
||||
return MyGUI::IntPoint(
|
||||
static_cast<int>(nX * mapWidgetSize + (mCellDistance + (cellX - mCurX)) * mapWidgetSize),
|
||||
static_cast<int>(nY * mapWidgetSize + (mCellDistance - (cellY - mCurY)) * mapWidgetSize)
|
||||
std::round(nX * mapWidgetSize + (mCellDistance + (cellX - mCurX)) * mapWidgetSize),
|
||||
std::round(nY * mapWidgetSize + (mCellDistance - (cellY - mCurY)) * mapWidgetSize)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -313,6 +313,13 @@ namespace MWGui
|
|||
mLocalMap->setViewOffset(viewOffset);
|
||||
}
|
||||
|
||||
MyGUI::IntCoord LocalMapBase::getMarkerCoordinates(MyGUI::Widget* widget, size_t markerSize) const
|
||||
{
|
||||
MarkerUserData& markerPos(*widget->getUserData<MarkerUserData>());
|
||||
auto position = getPosition(markerPos.cellX, markerPos.cellY, markerPos.nX, markerPos.nY);
|
||||
return MyGUI::IntCoord(position.left - markerSize / 2, position.top - markerSize / 2, markerSize, markerSize);
|
||||
}
|
||||
|
||||
void LocalMapBase::updateCustomMarkers()
|
||||
{
|
||||
for (MyGUI::Widget* widget : mCustomMarkerWidgets)
|
||||
|
@ -379,6 +386,9 @@ namespace MWGui
|
|||
}
|
||||
}
|
||||
|
||||
for (MyGUI::Widget* widget : mDoorMarkerWidgets)
|
||||
widget->setCoord(getMarkerCoordinates(widget, 8));
|
||||
|
||||
// Delay the door markers update until scripts have been given a chance to run.
|
||||
// If we don't do this, door markers that should be disabled will still appear on the map.
|
||||
mNeedDoorMarkersUpdate = true;
|
||||
|
@ -400,7 +410,7 @@ namespace MWGui
|
|||
|
||||
float LocalMapBase::getWidgetSize() const
|
||||
{
|
||||
return mMapWidgetSize;
|
||||
return mLocalMapZoom * mMapWidgetSize;
|
||||
}
|
||||
|
||||
void LocalMapBase::setPlayerPos(int cellX, int cellY, const float nx, const float ny)
|
||||
|
@ -412,6 +422,11 @@ namespace MWGui
|
|||
notifyPlayerUpdate ();
|
||||
|
||||
mCompass->setPosition(pos);
|
||||
}
|
||||
osg::Vec2f curPos((cellX + nx) * cellSize, (cellY + 1 - ny) * cellSize);
|
||||
if ((curPos - mCurPos).length2() > 0.001)
|
||||
{
|
||||
mCurPos = curPos;
|
||||
centerView();
|
||||
}
|
||||
}
|
||||
|
@ -469,6 +484,7 @@ namespace MWGui
|
|||
markerWidget->setImageTexture(markerTexture);
|
||||
markerWidget->setImageCoord(MyGUI::IntCoord(0,0,8,8));
|
||||
markerWidget->setNeedMouseFocus(false);
|
||||
markerWidget->setUserData(markerPos);
|
||||
mMagicMarkerWidgets.push_back(markerWidget);
|
||||
}
|
||||
}
|
||||
|
@ -619,12 +635,40 @@ namespace MWGui
|
|||
markerWidget->setDepth(Local_MarkerAboveFogLayer);
|
||||
markerWidget->setImageTexture("textures\\menu_map_smark.dds");
|
||||
markerWidget->setNeedMouseFocus(false);
|
||||
markerWidget->setUserData(markerPos);
|
||||
mMagicMarkerWidgets.push_back(markerWidget);
|
||||
}
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
void LocalMapBase::updateLocalMap()
|
||||
{
|
||||
auto mapWidgetSize = getWidgetSize();
|
||||
mLocalMap->setCanvasSize(mapWidgetSize * mNumCells, mapWidgetSize * mNumCells);
|
||||
|
||||
const auto size = MyGUI::IntSize(std::ceil(mapWidgetSize), std::ceil(mapWidgetSize));
|
||||
for (auto& entry : mMaps)
|
||||
{
|
||||
const auto position = getPosition(entry.mCellX, entry.mCellY, 0, 0);
|
||||
entry.mMapWidget->setCoord({ position, size });
|
||||
entry.mFogWidget->setCoord({ position, size });
|
||||
}
|
||||
|
||||
MarkerUserData markerPos(mLocalMapRender);
|
||||
for (MyGUI::Widget* widget : mDoorMarkerWidgets)
|
||||
widget->setCoord(getMarkerCoordinates(widget, 8));
|
||||
|
||||
for (MyGUI::Widget* widget : mCustomMarkerWidgets)
|
||||
{
|
||||
const auto& marker = *widget->getUserData<ESM::CustomMarker>();
|
||||
widget->setCoord(getMarkerCoordinates(marker.mWorldX, marker.mWorldY, markerPos, 16));
|
||||
}
|
||||
|
||||
for (MyGUI::Widget* widget : mMagicMarkerWidgets)
|
||||
widget->setCoord(getMarkerCoordinates(widget, 8));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
MapWindow::MapWindow(CustomMarkerCollection &customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, SceneUtil::WorkQueue* workQueue)
|
||||
|
@ -684,6 +728,7 @@ namespace MWGui
|
|||
mEventBoxLocal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
||||
mEventBoxLocal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
||||
mEventBoxLocal->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &MapWindow::onMapDoubleClicked);
|
||||
mEventBoxLocal->eventMouseWheel += MyGUI::newDelegate(this, &MapWindow::onMapZoomed);
|
||||
|
||||
LocalMapBase::init(mLocalMap, mPlayerArrowLocal);
|
||||
|
||||
|
@ -772,9 +817,17 @@ namespace MWGui
|
|||
|
||||
void MapWindow::onMapZoomed(MyGUI::Widget* sender, int rel)
|
||||
{
|
||||
const static int localWidgetSize = Settings::Manager::getInt("local map widget size", "Map");
|
||||
|
||||
const bool zoomOut = rel < 0;
|
||||
const bool zoomIn = !zoomOut;
|
||||
const double speedDiff = zoomOut ? 1.0 / speed : speed;
|
||||
const float localMapSizeInUnits = localWidgetSize * mNumCells;
|
||||
|
||||
const float currentMinLocalMapZoom = std::max(
|
||||
float(mLocalMap->getWidth()) / localMapSizeInUnits,
|
||||
float(mLocalMap->getHeight()) / localMapSizeInUnits
|
||||
);
|
||||
|
||||
if (mGlobal)
|
||||
{
|
||||
|
@ -797,16 +850,36 @@ namespace MWGui
|
|||
mGlobalMapZoom = currentGlobalZoom;
|
||||
return; //the zoom out is too big, we have reach the borders of the widget
|
||||
}
|
||||
zoomOnCursor(speedDiff);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const currentLocalZoom = mLocalMapZoom;
|
||||
mLocalMapZoom *= speedDiff;
|
||||
|
||||
if (zoomIn && mLocalMapZoom > 4.0f)
|
||||
{
|
||||
mLocalMapZoom = currentLocalZoom;
|
||||
return; //the zoom in is too big
|
||||
}
|
||||
|
||||
if (zoomOut && mLocalMapZoom < currentMinLocalMapZoom)
|
||||
{
|
||||
mLocalMapZoom = currentLocalZoom;
|
||||
return; //the zoom out is too big
|
||||
}
|
||||
}
|
||||
zoomOnCursor(speedDiff);
|
||||
}
|
||||
|
||||
void MapWindow::zoomOnCursor(float speedDiff)
|
||||
{
|
||||
auto cursor = MyGUI::InputManager::getInstance().getMousePosition() - mGlobalMap->getAbsolutePosition();
|
||||
auto centerView = mGlobalMap->getViewOffset() - cursor;
|
||||
updateGlobalMap();
|
||||
mGlobalMap->setViewOffset(MyGUI::IntPoint(
|
||||
auto map = mGlobal ? mGlobalMap : mLocalMap;
|
||||
auto cursor = MyGUI::InputManager::getInstance().getMousePosition() - map->getAbsolutePosition();
|
||||
auto centerView = map->getViewOffset() - cursor;
|
||||
|
||||
mGlobal? updateGlobalMap() : updateLocalMap();
|
||||
|
||||
map->setViewOffset(MyGUI::IntPoint(
|
||||
std::round(centerView.left * speedDiff) + cursor.left,
|
||||
std::round(centerView.top * speedDiff) + cursor.top
|
||||
));
|
||||
|
@ -815,7 +888,14 @@ namespace MWGui
|
|||
void MapWindow::updateGlobalMap()
|
||||
{
|
||||
resizeGlobalMap();
|
||||
notifyPlayerUpdate();
|
||||
|
||||
float x = mCurPos.x(), y = mCurPos.y();
|
||||
if (mInterior)
|
||||
{
|
||||
auto pos = MWBase::Environment::get().getWorld()->getPlayer().getLastKnownExteriorPosition();
|
||||
x = pos.x(), y = pos.y();
|
||||
}
|
||||
setGlobalMapPlayerPosition(x, y);
|
||||
|
||||
for (auto& marker : mGlobalMapMarkers)
|
||||
marker.second->setCoord(createMarkerCoords(marker.first.first, marker.first.second));
|
||||
|
@ -1043,6 +1123,7 @@ namespace MWGui
|
|||
|
||||
void MapWindow::centerView()
|
||||
{
|
||||
LocalMapBase::centerView();
|
||||
// set the view offset so that player is in the center
|
||||
MyGUI::IntSize viewsize = mGlobalMap->getSize();
|
||||
MyGUI::IntPoint pos = mPlayerArrowGlobal->getPosition() + MyGUI::IntPoint{ 16,16 };
|
||||
|
@ -1055,8 +1136,6 @@ namespace MWGui
|
|||
float x, y;
|
||||
worldPosToGlobalMapImageSpace(worldX, worldY, x, y);
|
||||
mPlayerArrowGlobal->setPosition(MyGUI::IntPoint(static_cast<int>(x - 16), static_cast<int>(y - 16)));
|
||||
|
||||
centerView();
|
||||
}
|
||||
|
||||
void MapWindow::setGlobalMapPlayerDir(const float x, const float y)
|
||||
|
@ -1141,12 +1220,14 @@ namespace MWGui
|
|||
marker->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
||||
marker->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
||||
marker->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &MapWindow::onCustomMarkerDoubleClicked);
|
||||
marker->eventMouseWheel += MyGUI::newDelegate(this, &MapWindow::onMapZoomed);
|
||||
}
|
||||
|
||||
void MapWindow::doorMarkerCreated(MyGUI::Widget *marker)
|
||||
{
|
||||
marker->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
||||
marker->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
||||
marker->eventMouseWheel += MyGUI::newDelegate(this, &MapWindow::onMapZoomed);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
|
|
@ -107,9 +107,13 @@ namespace MWGui
|
|||
};
|
||||
|
||||
protected:
|
||||
void updateLocalMap();
|
||||
|
||||
float mLocalMapZoom = 1.f;
|
||||
MWRender::LocalMap* mLocalMapRender;
|
||||
|
||||
int mCurX, mCurY;
|
||||
int mCurX, mCurY; //the position of the active cell on the global map (in cell coords)
|
||||
osg::Vec2f mCurPos; //the position of the player in the world (in cell coords)
|
||||
bool mInterior;
|
||||
MyGUI::ScrollView* mLocalMap;
|
||||
MyGUI::ImageBox* mCompass;
|
||||
|
@ -153,9 +157,10 @@ namespace MWGui
|
|||
MyGUI::IntPoint getMarkerPosition (float worldX, float worldY, MarkerUserData& markerPos) const;
|
||||
MyGUI::IntCoord getMarkerCoordinates(float worldX, float worldY, MarkerUserData& markerPos, size_t markerSize) const;
|
||||
MyGUI::Widget* createDoorMarker(const std::string& name, const MyGUI::VectorString& notes, float x, float y) const;
|
||||
MyGUI::IntCoord getMarkerCoordinates(MyGUI::Widget* widget, size_t markerSize) const;
|
||||
|
||||
virtual void notifyPlayerUpdate() {}
|
||||
void centerView();
|
||||
virtual void centerView();
|
||||
virtual void notifyMapChanged() {}
|
||||
|
||||
virtual void customMarkerCreated(MyGUI::Widget* marker) {}
|
||||
|
@ -302,7 +307,7 @@ namespace MWGui
|
|||
|
||||
void notifyPlayerUpdate() override;
|
||||
|
||||
void centerView();
|
||||
void centerView() override;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue