1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

Basic version of zoomable adventure map

This commit is contained in:
Ivan Savenko 2023-05-16 23:42:51 +03:00
parent ddf22a757d
commit 3e9da333cf
12 changed files with 67 additions and 1 deletions

View File

@ -798,6 +798,11 @@ void AdventureMapInterface::hotkeySwitchMapLevel()
widget->getMapView()->onMapLevelSwitched();
}
void AdventureMapInterface::hotkeyZoom(int delta)
{
widget->getMapView()->onMapZoomLevelChanged( 1.0 + delta / 10.0);
}
void AdventureMapInterface::onScreenResize()
{
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;

View File

@ -109,6 +109,7 @@ public:
void hotkeyEndingTurn();
void hotkeyNextTown();
void hotkeySwitchMapLevel();
void hotkeyZoom(int delta);
/// Called by PlayerInterface when specified player is ready to start his turn
void onHotseatWaitStarted(PlayerColor playerID);

View File

@ -80,6 +80,8 @@ std::vector<AdventureMapShortcutState> AdventureMapShortcuts::getShortcuts()
{ EShortcut::ADVENTURE_VISIT_OBJECT, optionHeroSelected(), [this]() { this->visitObject(); } },
{ EShortcut::ADVENTURE_VIEW_SELECTED, optionInMapView(), [this]() { this->openObject(); } },
{ EShortcut::GAME_OPEN_MARKETPLACE, optionInMapView(), [this]() { this->showMarketplace(); } },
{ EShortcut::ADVENTURE_ZOOM_IN, optionSidePanelActive(),[this]() { this->zoom(+1); } },
{ EShortcut::ADVENTURE_ZOOM_OUT, optionSidePanelActive(),[this]() { this->zoom(-1); } },
{ EShortcut::ADVENTURE_NEXT_TOWN, optionInMapView(), [this]() { this->nextTown(); } },
{ EShortcut::ADVENTURE_NEXT_OBJECT, optionInMapView(), [this]() { this->nextObject(); } },
{ EShortcut::ADVENTURE_MOVE_HERO_SW, optionHeroSelected(), [this]() { this->moveHeroDirectional({-1, +1}); } },
@ -336,6 +338,11 @@ void AdventureMapShortcuts::nextTown()
owner.hotkeyNextTown();
}
void AdventureMapShortcuts::zoom( int distance)
{
owner.hotkeyZoom(distance);
}
void AdventureMapShortcuts::nextObject()
{
const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero();

View File

@ -61,6 +61,7 @@ class AdventureMapShortcuts
void showMarketplace();
void nextTown();
void nextObject();
void zoom( int distance);
void moveHeroDirectional(const Point & direction);
public:

View File

@ -105,6 +105,8 @@ enum class EShortcut
ADVENTURE_CAST_SPELL,
ADVENTURE_THIEVES_GUILD,
ADVENTURE_EXIT_WORLD_VIEW,
ADVENTURE_ZOOM_IN,
ADVENTURE_ZOOM_OUT,
// Move hero one tile in specified direction. Bound to cursors & numpad buttons
ADVENTURE_MOVE_HERO_SW,

View File

@ -116,6 +116,8 @@ std::vector<EShortcut> ShortcutHandler::translateKeycode(SDL_Keycode key) const
{SDLK_q, EShortcut::ADVENTURE_QUEST_LOG },
{SDLK_c, EShortcut::ADVENTURE_CAST_SPELL },
{SDLK_g, EShortcut::ADVENTURE_THIEVES_GUILD },
{SDLK_KP_PLUS, EShortcut::ADVENTURE_ZOOM_IN },
{SDLK_KP_MINUS, EShortcut::ADVENTURE_ZOOM_OUT },
{SDLK_q, EShortcut::BATTLE_TOGGLE_QUEUE },
{SDLK_c, EShortcut::BATTLE_USE_CREATURE_SPELL },
{SDLK_s, EShortcut::BATTLE_SURRENDER },
@ -253,6 +255,8 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const
{"adventureCastSpell", EShortcut::ADVENTURE_CAST_SPELL },
{"adventureThievesGuild", EShortcut::ADVENTURE_THIEVES_GUILD },
{"adventureExitWorldView", EShortcut::ADVENTURE_EXIT_WORLD_VIEW },
{"adventureZoomIn", EShortcut::ADVENTURE_ZOOM_IN },
{"adventureZoomOut", EShortcut::ADVENTURE_ZOOM_OUT },
{"battleToggleQueue", EShortcut::BATTLE_TOGGLE_QUEUE },
{"battleUseCreatureSpell", EShortcut::BATTLE_USE_CREATURE_SPELL },
{"battleSurrender", EShortcut::BATTLE_SURRENDER },

View File

@ -154,6 +154,11 @@ void MapView::onViewWorldActivated(uint32_t tileSize)
controller->setTileSize(Point(tileSize, tileSize));
}
void MapView::onMapZoomLevelChanged(double zoomFactor)
{
controller->modifyTileSize(zoomFactor);
}
void MapView::onViewMapActivated()
{
controller->activateAdventureContext();

View File

@ -79,6 +79,9 @@ public:
/// Switches view to downscaled View World
void onViewWorldActivated(uint32_t tileSize);
/// Changes zoom level / tile size of current view by specified factor
void onMapZoomLevelChanged(double zoomFactor);
/// Switches view from View World mode back to standard view
void onViewMapActivated();
};

View File

@ -75,6 +75,27 @@ void MapViewController::setTileSize(const Point & tileSize)
setViewCenter(model->getMapViewCenter(), model->getLevel());
}
void MapViewController::modifyTileSize(double zoomFactor)
{
Point currentZoom = model->getSingleTileSize();
Point desiredZoom = currentZoom * zoomFactor;
if (desiredZoom == currentZoom && zoomFactor < 1.0)
desiredZoom -= Point(1,1);
if (desiredZoom == currentZoom && zoomFactor > 1.0)
desiredZoom += Point(1,1);
Point minimal = model->getSingleTileSizeLowerLimit();
Point maximal = model->getSingleTileSizeUpperLimit();
Point actualZoom = {
std::clamp(desiredZoom.x, minimal.x, maximal.x),
std::clamp(desiredZoom.y, minimal.y, maximal.y)
};
setTileSize(actualZoom);
}
MapViewController::MapViewController(std::shared_ptr<MapViewModel> model, std::shared_ptr<MapViewCache> view)
: state(new MapRendererContextState())
, model(std::move(model))

View File

@ -83,6 +83,7 @@ public:
void setViewCenter(const int3 & position);
void setViewCenter(const Point & position, int level);
void setTileSize(const Point & tileSize);
void modifyTileSize(double zoomFactor);
void tick(uint32_t timePassed);
void afterRender();

View File

@ -33,6 +33,16 @@ void MapViewModel::setLevel(int newLevel)
mapLevel = newLevel;
}
Point MapViewModel::getSingleTileSizeUpperLimit() const
{
return Point(128, 128); // arbitrary-seleted upscaling limit
}
Point MapViewModel::getSingleTileSizeLowerLimit() const
{
return Point(4, 4); // arbitrary-seleted upscaling limit
}
Point MapViewModel::getSingleTileSize() const
{
return tileSize;
@ -90,7 +100,7 @@ int3 MapViewModel::getTileAtPoint(const Point & position) const
Point MapViewModel::getCacheDimensionsPixels() const
{
return getTilesVisibleDimensions() * getSingleTileSize();
return getTilesVisibleDimensions() * getSingleTileSizeUpperLimit();
}
Rect MapViewModel::getCacheTileArea(const int3 & coordinates) const

View File

@ -25,6 +25,12 @@ public:
void setViewDimensions(const Point & newValue);
void setLevel(int newLevel);
/// returns maximal possible size for a single tile
Point getSingleTileSizeUpperLimit() const;
/// returns minimal possible size for a single tile
Point getSingleTileSizeLowerLimit() const;
/// returns current size of map tile in pixels
Point getSingleTileSize() const;