mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-17 10:21:11 +00:00
[Global map] Regroup markers when the zoom out
This commit is contained in:
parent
18f5853279
commit
9fee9dbc9c
@ -30,6 +30,8 @@
|
|||||||
#include "confirmationdialog.hpp"
|
#include "confirmationdialog.hpp"
|
||||||
#include "tooltips.hpp"
|
#include "tooltips.hpp"
|
||||||
|
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -976,8 +978,11 @@ namespace MWGui
|
|||||||
}
|
}
|
||||||
setGlobalMapPlayerPosition(x, y);
|
setGlobalMapPlayerPosition(x, y);
|
||||||
|
|
||||||
for (auto& marker : mGlobalMapMarkers)
|
for (auto& [marker, col] : mGlobalMapMarkers)
|
||||||
marker.second->setCoord(createMarkerCoords(marker.first.first, marker.first.second));
|
{
|
||||||
|
marker.widget->setCoord(createMarkerCoords(marker.position.x(), marker.position.y(), col.size()));
|
||||||
|
marker.widget->setVisible(marker.widget->getHeight() >= 6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWindow::onChangeScrollWindowCoord(MyGUI::Widget* sender)
|
void MapWindow::onChangeScrollWindowCoord(MyGUI::Widget* sender)
|
||||||
@ -1016,12 +1021,12 @@ namespace MWGui
|
|||||||
setTitle("#{sCell=" + cellName + "}");
|
setTitle("#{sCell=" + cellName + "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
MyGUI::IntCoord MapWindow::createMarkerCoords(float x, float y) const
|
MyGUI::IntCoord MapWindow::createMarkerCoords(float x, float y, float agregatedWeight) const
|
||||||
{
|
{
|
||||||
float worldX, worldY;
|
float worldX, worldY;
|
||||||
worldPosToGlobalMapImageSpace((x + 0.5f) * Constants::CellSizeInUnits, (y + 0.5f)* Constants::CellSizeInUnits, worldX, worldY);
|
worldPosToGlobalMapImageSpace((x + 0.5f) * Constants::CellSizeInUnits, (y + 0.5f)* Constants::CellSizeInUnits, worldX, worldY);
|
||||||
|
|
||||||
const float markerSize = getMarkerSize();
|
const float markerSize = getMarkerSize(agregatedWeight);
|
||||||
const float halfMarkerSize = markerSize / 2.0f;
|
const float halfMarkerSize = markerSize / 2.0f;
|
||||||
return MyGUI::IntCoord(
|
return MyGUI::IntCoord(
|
||||||
static_cast<int>(worldX - halfMarkerSize),
|
static_cast<int>(worldX - halfMarkerSize),
|
||||||
@ -1029,13 +1034,12 @@ namespace MWGui
|
|||||||
markerSize, markerSize);
|
markerSize, markerSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
MyGUI::Widget* MapWindow::createMarker(const std::string& name, float x, float y)
|
MyGUI::Widget* MapWindow::createMarker(const std::string& name, float x, float y, float agregatedWeight)
|
||||||
{
|
{
|
||||||
MyGUI::Widget* markerWidget = mGlobalMap->createWidget<MyGUI::Widget>("MarkerButton",
|
MyGUI::Widget* markerWidget = mGlobalMap->createWidget<MyGUI::Widget>("MarkerButton",
|
||||||
createMarkerCoords(x, y), MyGUI::Align::Default);
|
createMarkerCoords(x, y, agregatedWeight), MyGUI::Align::Default);
|
||||||
|
markerWidget->setVisible(markerWidget->getHeight() >= 6.0);
|
||||||
markerWidget->setUserString("Caption_TextOneLine", "#{sCell=" + name + "}");
|
markerWidget->setUserString("Caption_TextOneLine", "#{sCell=" + name + "}");
|
||||||
|
|
||||||
setGlobalMapMarkerTooltip(markerWidget, x, y);
|
setGlobalMapMarkerTooltip(markerWidget, x, y);
|
||||||
|
|
||||||
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
|
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
|
||||||
@ -1057,7 +1061,33 @@ namespace MWGui
|
|||||||
cell.second = y;
|
cell.second = y;
|
||||||
if (mMarkers.insert(cell).second)
|
if (mMarkers.insert(cell).second)
|
||||||
{
|
{
|
||||||
mGlobalMapMarkers[std::make_pair(x, y)] = createMarker(name, x, y);
|
MapMarkerType mapMarkerWidget = { osg::Vec2f(x, y), createMarker(name, x, y, 0) };
|
||||||
|
mGlobalMapMarkers.emplace(mapMarkerWidget, std::vector<MapMarkerType>());
|
||||||
|
|
||||||
|
std::string name_ = name.substr(0, name.find(','));
|
||||||
|
auto& entry = mGlobalMapMarkersByName[name_];
|
||||||
|
if (!entry.widget)
|
||||||
|
{
|
||||||
|
entry = { osg::Vec2f(x, y), entry.widget }; //update the coords
|
||||||
|
|
||||||
|
entry.widget = createMarker(name_, entry.position.x(), entry.position.y(), 1);
|
||||||
|
mGlobalMapMarkers.emplace(entry, std::vector<MapMarkerType>{ entry });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto it = mGlobalMapMarkers.find(entry);
|
||||||
|
auto& marker = const_cast<MapMarkerType&>(it->first);
|
||||||
|
auto& elements = it->second;
|
||||||
|
elements.emplace_back(mapMarkerWidget);
|
||||||
|
|
||||||
|
//we compute the barycenter of the entry elements => it will be the place on the world map for the agregated widget
|
||||||
|
marker.position = std::accumulate(elements.begin(), elements.end(), osg::Vec2f(0.f, 0.f), [](const auto& left, const auto& right) {
|
||||||
|
return left + right.position;
|
||||||
|
}) / float(elements.size());
|
||||||
|
|
||||||
|
marker.widget->setCoord(createMarkerCoords(marker.position.x(), marker.position.y(), elements.size()));
|
||||||
|
marker.widget->setVisible(marker.widget->getHeight() >= 6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1099,9 +1129,12 @@ namespace MWGui
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float MapWindow::getMarkerSize() const
|
float MapWindow::getMarkerSize(size_t agregatedWeight) const
|
||||||
{
|
{
|
||||||
return 12.0f * mGlobalMapZoom;
|
float markerSize = 12.f * mGlobalMapZoom;
|
||||||
|
if (mGlobalMapZoom < 1)
|
||||||
|
return markerSize * std::sqrt(agregatedWeight); //we want to see agregated object
|
||||||
|
return agregatedWeight ? 0 : markerSize; //we want to see only original markers (i.e. non agregated)
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWindow::resizeGlobalMap()
|
void MapWindow::resizeGlobalMap()
|
||||||
@ -1120,13 +1153,8 @@ namespace MWGui
|
|||||||
{
|
{
|
||||||
LocalMapBase::updateCustomMarkers();
|
LocalMapBase::updateCustomMarkers();
|
||||||
|
|
||||||
for (auto& widgetPair : mGlobalMapMarkers)
|
for (auto& [widgetPair, ignore]: mGlobalMapMarkers)
|
||||||
{
|
setGlobalMapMarkerTooltip(widgetPair.widget, widgetPair.position.x(), widgetPair.position.y());
|
||||||
int x = widgetPair.first.first;
|
|
||||||
int y = widgetPair.first.second;
|
|
||||||
MyGUI::Widget* markerWidget = widgetPair.second;
|
|
||||||
setGlobalMapMarkerTooltip(markerWidget, x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
||||||
@ -1251,8 +1279,9 @@ namespace MWGui
|
|||||||
mChanged = true;
|
mChanged = true;
|
||||||
|
|
||||||
for (auto& widgetPair : mGlobalMapMarkers)
|
for (auto& widgetPair : mGlobalMapMarkers)
|
||||||
MyGUI::Gui::getInstance().destroyWidget(widgetPair.second);
|
MyGUI::Gui::getInstance().destroyWidget(widgetPair.first.widget);
|
||||||
mGlobalMapMarkers.clear();
|
mGlobalMapMarkers.clear();
|
||||||
|
mGlobalMapMarkersByName.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWindow::write(ESM::ESMWriter &writer, Loading::Listener& progress)
|
void MapWindow::write(ESM::ESMWriter &writer, Loading::Listener& progress)
|
||||||
|
@ -272,11 +272,12 @@ namespace MWGui
|
|||||||
void onChangeScrollWindowCoord(MyGUI::Widget* sender);
|
void onChangeScrollWindowCoord(MyGUI::Widget* sender);
|
||||||
void globalMapUpdatePlayer();
|
void globalMapUpdatePlayer();
|
||||||
void setGlobalMapMarkerTooltip(MyGUI::Widget* widget, int x, int y);
|
void setGlobalMapMarkerTooltip(MyGUI::Widget* widget, int x, int y);
|
||||||
float getMarkerSize() const;
|
float getMarkerSize(size_t agregatedWeight) const;
|
||||||
void resizeGlobalMap();
|
void resizeGlobalMap();
|
||||||
void worldPosToGlobalMapImageSpace(float x, float z, float& imageX, float& imageY) const;
|
void worldPosToGlobalMapImageSpace(float x, float z, float& imageX, float& imageY) const;
|
||||||
MyGUI::IntCoord createMarkerCoords(float x, float y) const;
|
MyGUI::IntCoord createMarkerCoords(float x, float y, float agregatedWeight) const;
|
||||||
MyGUI::Widget* createMarker(const std::string& name, float x, float y);
|
MyGUI::Widget* createMarker(const std::string& name, float x, float y, float agregatedWeight);
|
||||||
|
|
||||||
|
|
||||||
MyGUI::ScrollView* mGlobalMap;
|
MyGUI::ScrollView* mGlobalMap;
|
||||||
std::unique_ptr<MyGUI::ITexture> mGlobalMapTexture;
|
std::unique_ptr<MyGUI::ITexture> mGlobalMapTexture;
|
||||||
@ -301,7 +302,18 @@ namespace MWGui
|
|||||||
float mGlobalMapZoom = 1.0f;
|
float mGlobalMapZoom = 1.0f;
|
||||||
MWRender::GlobalMap* mGlobalMapRender;
|
MWRender::GlobalMap* mGlobalMapRender;
|
||||||
|
|
||||||
std::map<std::pair<int, int>, MyGUI::Widget*> mGlobalMapMarkers;
|
struct MapMarkerType
|
||||||
|
{
|
||||||
|
osg::Vec2f position;
|
||||||
|
MyGUI::Widget* widget = nullptr;
|
||||||
|
|
||||||
|
bool operator<(const MapMarkerType& right) const {
|
||||||
|
return widget < right.widget;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<std::string, MapMarkerType> mGlobalMapMarkersByName;
|
||||||
|
std::map<MapMarkerType, std::vector<MapMarkerType>> mGlobalMapMarkers;
|
||||||
|
|
||||||
EditNoteDialog mEditNoteDialog;
|
EditNoteDialog mEditNoteDialog;
|
||||||
ESM::CustomMarker mEditingMarker;
|
ESM::CustomMarker mEditingMarker;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user