diff --git a/client/adventureMap/AdventureMapShortcuts.cpp b/client/adventureMap/AdventureMapShortcuts.cpp index ca89415db..2278166b3 100644 --- a/client/adventureMap/AdventureMapShortcuts.cpp +++ b/client/adventureMap/AdventureMapShortcuts.cpp @@ -11,74 +11,73 @@ #include "StdInc.h" #include "AdventureMapShortcuts.h" +#include "../CGameInfo.h" +#include "../CPlayerInterface.h" +#include "../PlayerLocalState.h" +#include "../gui/CGuiHandler.h" +#include "../gui/Shortcut.h" +#include "../lobby/CSavingScreen.h" +#include "../mapView/mapHandler.h" #include "../windows/CKingdomInterface.h" #include "../windows/CSpellWindow.h" #include "../windows/CTradeWindow.h" -#include "../lobby/CSavingScreen.h" - -#include "../gui/CGuiHandler.h" -#include "../gui/Shortcut.h" -#include "../CPlayerInterface.h" -#include "../PlayerLocalState.h" -#include "../CGameInfo.h" +#include "../windows/settings/SettingsMainWindow.h" #include "CAdventureMapInterface.h" #include "CAdventureOptions.h" -#include "../windows/settings/SettingsMainWindow.h" #include "../../CCallback.h" #include "../../lib/CConfigHandler.h" #include "../../lib/CGeneralTextHandler.h" +#include "../../lib/CPathfinder.h" #include "../../lib/mapObjects/CGHeroInstance.h" #include "../../lib/mapObjects/CGTownInstance.h" -#include "../../lib/CPathfinder.h" +#include "../../lib/mapping/CMap.h" AdventureMapShortcuts::AdventureMapShortcuts(CAdventureMapInterface & owner) :owner(owner) {} -std::map> AdventureMapShortcuts::getFunctors() +std::vector AdventureMapShortcuts::getShortcuts() { - std::map> result = { - { EShortcut::ADVENTURE_KINGDOM_OVERVIEW, [this]() { this->showOverview(); } }, - { EShortcut::NONE, [this]() { this->worldViewBack(); } }, - { EShortcut::NONE, [this]() { this->worldViewScale1x(); } }, - { EShortcut::NONE, [this]() { this->worldViewScale2x(); } }, - { EShortcut::NONE, [this]() { this->worldViewScale4x(); } }, - { EShortcut::ADVENTURE_TOGGLE_MAP_LEVEL, [this]() { this->switchMapLevel(); } }, - { EShortcut::ADVENTURE_QUEST_LOG, [this]() { this->showQuestlog(); } }, - { EShortcut::ADVENTURE_TOGGLE_SLEEP, [this]() { this->toggleSleepWake(); } }, - { EShortcut::ADVENTURE_SET_HERO_ASLEEP, [this]() { this->setHeroSleeping(); } }, - { EShortcut::ADVENTURE_SET_HERO_AWAKE, [this]() { this->setHeroAwake(); } }, - { EShortcut::ADVENTURE_MOVE_HERO, [this]() { this->moveHeroAlongPath(); } }, - { EShortcut::ADVENTURE_CAST_SPELL, [this]() { this->showSpellbook(); } }, - { EShortcut::ADVENTURE_GAME_OPTIONS, [this]() { this->adventureOptions(); } }, - { EShortcut::GLOBAL_OPTIONS, [this]() { this->systemOptions(); } }, - { EShortcut::ADVENTURE_NEXT_HERO, [this]() { this->nextHero(); } }, - { EShortcut::GAME_END_TURN, [this]() { this->endTurn(); } }, - { EShortcut::ADVENTURE_THIEVES_GUILD, [this]() { this->showThievesGuild(); } }, - { EShortcut::ADVENTURE_VIEW_SCENARIO, [this]() { this->showScenarioInfo(); } }, - { EShortcut::GAME_SAVE_GAME, [this]() { this->saveGame(); } }, - { EShortcut::GAME_LOAD_GAME, [this]() { this->loadGame(); } }, - { EShortcut::ADVENTURE_DIG_GRAIL, [this]() { this->digGrail(); } }, - { EShortcut::ADVENTURE_VIEW_PUZZLE, [this]() { this->viewPuzzleMap(); } }, - { EShortcut::ADVENTURE_VIEW_WORLD, [this]() { this->viewWorldMap(); } }, - { EShortcut::GAME_RESTART_GAME, [this]() { this->restartGame(); } }, - { EShortcut::ADVENTURE_VISIT_OBJECT, [this]() { this->visitObject(); } }, - { EShortcut::ADVENTURE_VIEW_SELECTED, [this]() { this->openObject(); } }, - { EShortcut::GLOBAL_CANCEL, [this]() { this->abortSpellcasting(); } }, - { EShortcut::GAME_OPEN_MARKETPLACE, [this]() { this->showMarketplace(); } }, - { EShortcut::ADVENTURE_NEXT_TOWN, [this]() { this->nextTown(); } }, -// { EShortcut::ADVENTURE_NEXT_OBJECT, [this]() { this->nextObject(); } }, - { EShortcut::ADVENTURE_MOVE_HERO_SW, [this]() { this->moveHeroDirectional({-1, +1}); } }, - { EShortcut::ADVENTURE_MOVE_HERO_SS, [this]() { this->moveHeroDirectional({ 0, +1}); } }, - { EShortcut::ADVENTURE_MOVE_HERO_SE, [this]() { this->moveHeroDirectional({+1, +1}); } }, - { EShortcut::ADVENTURE_MOVE_HERO_WW, [this]() { this->moveHeroDirectional({-1, 0}); } }, - { EShortcut::ADVENTURE_MOVE_HERO_EE, [this]() { this->moveHeroDirectional({+1, 0}); } }, - { EShortcut::ADVENTURE_MOVE_HERO_NW, [this]() { this->moveHeroDirectional({-1, -1}); } }, - { EShortcut::ADVENTURE_MOVE_HERO_NN, [this]() { this->moveHeroDirectional({ 0, -1}); } }, - { EShortcut::ADVENTURE_MOVE_HERO_NE, [this]() { this->moveHeroDirectional({+1, -1}); } }, + std::vector result = { + { EShortcut::ADVENTURE_KINGDOM_OVERVIEW, optionDefault(), [this]() { this->showOverview(); } }, + { EShortcut::ADVENTURE_EXIT_WORLD_VIEW, optionDefault(), [this]() { this->worldViewBack(); } }, + { EShortcut::ADVENTURE_VIEW_WORLD_X1, optionDefault(), [this]() { this->worldViewScale1x(); } }, + { EShortcut::ADVENTURE_VIEW_WORLD_X2, optionDefault(), [this]() { this->worldViewScale2x(); } }, + { EShortcut::ADVENTURE_VIEW_WORLD_X4, optionDefault(), [this]() { this->worldViewScale4x(); } }, + { EShortcut::ADVENTURE_TOGGLE_MAP_LEVEL, optionHasUnderground(), [this]() { this->switchMapLevel(); } }, + { EShortcut::ADVENTURE_QUEST_LOG, optionHasQuests(), [this]() { this->showQuestlog(); } }, + { EShortcut::ADVENTURE_TOGGLE_SLEEP, optionHeroSelected(), [this]() { this->toggleSleepWake(); } }, + { EShortcut::ADVENTURE_SET_HERO_ASLEEP, optionHeroSleeping(), [this]() { this->setHeroSleeping(); } }, + { EShortcut::ADVENTURE_SET_HERO_AWAKE, optionHeroSleeping(), [this]() { this->setHeroAwake(); } }, + { EShortcut::ADVENTURE_MOVE_HERO, optionHeroCanMove(), [this]() { this->moveHeroAlongPath(); } }, + { EShortcut::ADVENTURE_CAST_SPELL, optionHeroSelected(), [this]() { this->showSpellbook(); } }, + { EShortcut::ADVENTURE_GAME_OPTIONS, optionDefault(), [this]() { this->adventureOptions(); } }, + { EShortcut::GLOBAL_OPTIONS, optionDefault(), [this]() { this->systemOptions(); } }, + { EShortcut::ADVENTURE_NEXT_HERO, optionHasNextHero(), [this]() { this->nextHero(); } }, + { EShortcut::GAME_END_TURN, optionDefault(), [this]() { this->endTurn(); } }, + { EShortcut::ADVENTURE_THIEVES_GUILD, optionDefault(), [this]() { this->showThievesGuild(); } }, + { EShortcut::ADVENTURE_VIEW_SCENARIO, optionDefault(), [this]() { this->showScenarioInfo(); } }, + { EShortcut::GAME_SAVE_GAME, optionDefault(), [this]() { this->saveGame(); } }, + { EShortcut::GAME_LOAD_GAME, optionDefault(), [this]() { this->loadGame(); } }, + { EShortcut::ADVENTURE_DIG_GRAIL, optionHeroSelected(), [this]() { this->digGrail(); } }, + { EShortcut::ADVENTURE_VIEW_PUZZLE, optionDefault(), [this]() { this->viewPuzzleMap(); } }, + { EShortcut::GAME_RESTART_GAME, optionDefault(), [this]() { this->restartGame(); } }, + { EShortcut::ADVENTURE_VISIT_OBJECT, optionHeroSelected(), [this]() { this->visitObject(); } }, + { EShortcut::ADVENTURE_VIEW_SELECTED, optionDefault(), [this]() { this->openObject(); } }, + { EShortcut::GLOBAL_CANCEL, optionSpellcasting(), [this]() { this->abortSpellcasting(); } }, + { EShortcut::GAME_OPEN_MARKETPLACE, optionDefault(), [this]() { this->showMarketplace(); } }, + { EShortcut::ADVENTURE_NEXT_TOWN, optionDefault(), [this]() { this->nextTown(); } }, + { EShortcut::ADVENTURE_NEXT_OBJECT, optionDefault(), [this]() { this->nextObject(); } }, + { EShortcut::ADVENTURE_MOVE_HERO_SW, optionHeroSelected(), [this]() { this->moveHeroDirectional({-1, +1}); } }, + { EShortcut::ADVENTURE_MOVE_HERO_SS, optionHeroSelected(), [this]() { this->moveHeroDirectional({ 0, +1}); } }, + { EShortcut::ADVENTURE_MOVE_HERO_SE, optionHeroSelected(), [this]() { this->moveHeroDirectional({+1, +1}); } }, + { EShortcut::ADVENTURE_MOVE_HERO_WW, optionHeroSelected(), [this]() { this->moveHeroDirectional({-1, 0}); } }, + { EShortcut::ADVENTURE_MOVE_HERO_EE, optionHeroSelected(), [this]() { this->moveHeroDirectional({+1, 0}); } }, + { EShortcut::ADVENTURE_MOVE_HERO_NW, optionHeroSelected(), [this]() { this->moveHeroDirectional({-1, -1}); } }, + { EShortcut::ADVENTURE_MOVE_HERO_NN, optionHeroSelected(), [this]() { this->moveHeroDirectional({ 0, -1}); } }, + { EShortcut::ADVENTURE_MOVE_HERO_NE, optionHeroSelected(), [this]() { this->moveHeroDirectional({+1, -1}); } } }; - return result; } @@ -284,11 +283,6 @@ void AdventureMapShortcuts::viewPuzzleMap() LOCPLINT->showPuzzleMap(); } -void AdventureMapShortcuts::viewWorldMap() -{ - LOCPLINT->viewWorldMap(); -} - void AdventureMapShortcuts::restartGame() { LOCPLINT->showYesNoDialog(CGI->generaltexth->translate("vcmi.adventureMap.confirmRestartGame"), @@ -342,10 +336,65 @@ void AdventureMapShortcuts::showMarketplace() void AdventureMapShortcuts::nextTown() { - owner.hotkeyEndingTurn(); + //TODO +} + +void AdventureMapShortcuts::nextObject() +{ + //TODO } void AdventureMapShortcuts::moveHeroDirectional(const Point & direction) { owner.hotkeyMoveHeroDirectional(direction); } + +bool AdventureMapShortcuts::optionHasQuests() +{ + return CGI->mh->getMap()->quests.empty(); +} + +bool AdventureMapShortcuts::optionHasUnderground() +{ + return LOCPLINT->cb->getMapSize().z > 0; +} + +bool AdventureMapShortcuts::optionMapLevelSurface() +{ + return false; //TODO +} + +bool AdventureMapShortcuts::optionHeroSleeping() +{ + const CGHeroInstance *hero = LOCPLINT->localState->getCurrentHero(); + return hero && LOCPLINT->localState->isHeroSleeping(hero); +} + +bool AdventureMapShortcuts::optionHeroSelected() +{ + return LOCPLINT->localState->getCurrentHero() != nullptr; +} + +bool AdventureMapShortcuts::optionHeroCanMove() +{ + const auto * hero = LOCPLINT->localState->getCurrentHero(); + return hero && hero->movement != 0 && LOCPLINT->localState->hasPath(hero); +} + +bool AdventureMapShortcuts::optionHasNextHero() +{ + const auto * hero = LOCPLINT->localState->getCurrentHero(); + const auto * nextSuitableHero = LOCPLINT->localState->getNextWanderingHero(hero); + + return nextSuitableHero != nullptr; +} + +bool AdventureMapShortcuts::optionSpellcasting() +{ + return true; //TODO +} + +bool AdventureMapShortcuts::optionDefault() +{ + return true; //TODO +} diff --git a/client/adventureMap/AdventureMapShortcuts.h b/client/adventureMap/AdventureMapShortcuts.h index d2f2761ea..b8fe771ec 100644 --- a/client/adventureMap/AdventureMapShortcuts.h +++ b/client/adventureMap/AdventureMapShortcuts.h @@ -17,6 +17,13 @@ VCMI_LIB_NAMESPACE_END enum class EShortcut; class CAdventureMapInterface; +struct AdventureMapShortcutState +{ + EShortcut shortcut; + bool isEnabled; + std::function callback; +}; + /// Class that contains list of functions for shortcuts available from adventure map class AdventureMapShortcuts { @@ -44,7 +51,6 @@ class AdventureMapShortcuts void loadGame(); void digGrail(); void viewPuzzleMap(); - void viewWorldMap(); void restartGame(); void visitObject(); void openObject(); @@ -57,5 +63,15 @@ class AdventureMapShortcuts public: explicit AdventureMapShortcuts(CAdventureMapInterface & owner); - std::map> getFunctors(); + std::vector getShortcuts(); + + bool optionHasQuests(); + bool optionHasUnderground(); + bool optionMapLevelSurface(); + bool optionHeroSleeping(); + bool optionHeroSelected(); + bool optionHeroCanMove(); + bool optionHasNextHero(); + bool optionSpellcasting(); + bool optionDefault(); }; diff --git a/client/adventureMap/CAdventureMapInterface.cpp b/client/adventureMap/CAdventureMapInterface.cpp index 1384b9e5d..544f4466e 100644 --- a/client/adventureMap/CAdventureMapInterface.cpp +++ b/client/adventureMap/CAdventureMapInterface.cpp @@ -55,15 +55,12 @@ CAdventureMapInterface::CAdventureMapInterface(): widget = std::make_shared(shortcuts); widget->setState(EGameState::MAKING_TURN); widget->getMapView()->onViewMapActivated(); - - widget->setOptionHasQuests(!CGI->mh->getMap()->quests.empty()); - widget->setOptionHasUnderground(CGI->mh->getMap()->twoLevel); } void CAdventureMapInterface::onMapViewMoved(const Rect & visibleArea, int mapLevel) { - widget->setOptionUndergroundLevel(mapLevel > 0); widget->getMinimap()->onMapViewMoved(visibleArea, mapLevel); + widget->updateActiveState(); } void CAdventureMapInterface::onAudioResumed() @@ -76,17 +73,6 @@ void CAdventureMapInterface::onAudioPaused() mapAudio->onAudioPaused(); } -void CAdventureMapInterface::updateButtons() -{ - const auto * hero = LOCPLINT->localState->getCurrentHero(); - const auto * nextSuitableHero = LOCPLINT->localState->getNextWanderingHero(hero); - - widget->setOptionHeroSelected(hero != nullptr); - widget->setOptionHeroCanMove(hero && LOCPLINT->localState->hasPath(hero) && hero->movement != 0); - widget->setOptionHasNextHero(nextSuitableHero != nullptr); - widget->setOptionHeroSleeping(hero && LOCPLINT->localState->isHeroSleeping(hero)); -} - void CAdventureMapInterface::onHeroMovementStarted(const CGHeroInstance * hero) { widget->getInfoBar()->popAll(); @@ -100,7 +86,7 @@ void CAdventureMapInterface::onHeroChanged(const CGHeroInstance *h) if (h && h == LOCPLINT->localState->getCurrentHero() && !widget->getInfoBar()->showingComponents()) widget->getInfoBar()->showSelection(); - updateButtons(); + widget->updateActiveState(); } void CAdventureMapInterface::onTownChanged(const CGTownInstance * town) @@ -297,7 +283,8 @@ void CAdventureMapInterface::onSelectionChanged(const CArmedInstance *sel) LOCPLINT->localState->verifyPath(hero); onHeroChanged(hero); } - updateButtons(); + + widget->updateActiveState(); widget->getHeroList()->redraw(); widget->getTownList()->redraw(); } diff --git a/client/adventureMap/CAdventureMapInterface.h b/client/adventureMap/CAdventureMapInterface.h index 6e92fbc6e..2adc77347 100644 --- a/client/adventureMap/CAdventureMapInterface.h +++ b/client/adventureMap/CAdventureMapInterface.h @@ -66,9 +66,6 @@ private: const IShipyard * ourInaccessibleShipyard(const CGObjectInstance *obj) const; //checks if obj is our ashipyard and cursor is 0,0 -> returns shipyard or nullptr else - // update locked state of buttons - void updateButtons(); - void handleMapScrollingUpdate(); void showMoveDetailsInStatusbar(const CGHeroInstance & hero, const CGPathNode & pathNode); diff --git a/client/adventureMap/CAdventureMapWidget.cpp b/client/adventureMap/CAdventureMapWidget.cpp index fc74c6a32..91d969b55 100644 --- a/client/adventureMap/CAdventureMapWidget.cpp +++ b/client/adventureMap/CAdventureMapWidget.cpp @@ -51,8 +51,8 @@ CAdventureMapWidget::CAdventureMapWidget( std::shared_ptr REGISTER_BUILDER("adventureResourceDateBar", &CAdventureMapWidget::buildResourceDateBar ); REGISTER_BUILDER("adventureStatusBar", &CAdventureMapWidget::buildStatusBar ); - for (const auto & entry : shortcuts->getFunctors()) - addShortcut(entry.first, entry.second); + for (const auto & entry : shortcuts->getShortcuts()) + addShortcut(entry.shortcut, entry.callback); const JsonNode config(ResourceID("config/widgets/adventureMap.json")); @@ -190,12 +190,17 @@ std::shared_ptr CAdventureMapWidget::buildMapContainer(const JsonNod else result = std::make_shared(); + result->disableCondition = input["hideWhen"].String(); + result->moveBy(position.topLeft()); subwidgetSizes.push_back(position); for(const auto & entry : input["items"].Vector()) { - result->ownedChildren.push_back(buildWidget(entry)); - result->addChild(result->ownedChildren.back().get(), false); + auto widget = buildWidget(entry); + + addWidget(entry["name"].String(), widget); + result->ownedChildren.push_back(widget); + result->addChild(widget.get(), false); } subwidgetSizes.pop_back(); @@ -378,41 +383,6 @@ EGameState CAdventureMapWidget::getState() return state; } -void CAdventureMapWidget::setOptionHasQuests(bool on) -{ - -} - -void CAdventureMapWidget::setOptionHasUnderground(bool on) -{ - -} - -void CAdventureMapWidget::setOptionUndergroundLevel(bool on) -{ - -} - -void CAdventureMapWidget::setOptionHeroSleeping(bool on) -{ - -} - -void CAdventureMapWidget::setOptionHeroSelected(bool on) -{ - -} - -void CAdventureMapWidget::setOptionHeroCanMove(bool on) -{ - -} - -void CAdventureMapWidget::setOptionHasNextHero(bool on) -{ - -} - CAdventureMapIcon::CAdventureMapIcon(const Point & position, std::shared_ptr animation, size_t index, size_t iconsPerPlayer) : index(index) , iconsPerPlayer(iconsPerPlayer) @@ -431,3 +401,36 @@ void CAdventureMapOverlayWidget::show(SDL_Surface * to) { CIntObject::showAll(to); } + +void CAdventureMapWidget::updateActiveStateChildden(CIntObject * widget) +{ + for(auto & entry : widget->children) + { + auto container = dynamic_cast(entry); + + if (container) + { + if (container->disableCondition == "heroAwake") + container->setEnabled(!shortcuts->optionHeroSleeping()); + + if (container->disableCondition == "heroSleeping") + container->setEnabled(shortcuts->optionHeroSleeping()); + + if (container->disableCondition == "mapLayerSurface") + container->setEnabled(shortcuts->optionMapLevelSurface()); + + if (container->disableCondition == "mapLayerUnderground") + container->setEnabled(!shortcuts->optionMapLevelSurface()); + + } + + } +} + +void CAdventureMapWidget::updateActiveState() +{ + updateActiveStateChildden(this); + + for (auto entry: shortcuts->getShortcuts()) + setShortcutBlocked(entry.shortcut, !entry.isEnabled); +} diff --git a/client/adventureMap/CAdventureMapWidget.h b/client/adventureMap/CAdventureMapWidget.h index 2ed667dba..316310796 100644 --- a/client/adventureMap/CAdventureMapWidget.h +++ b/client/adventureMap/CAdventureMapWidget.h @@ -72,6 +72,7 @@ class CAdventureMapWidget : public InterfaceObjectConfigurable std::shared_ptr buildStatusBar(const JsonNode & input); void setPlayerChildren(CIntObject * widget, const PlayerColor & player); + void updateActiveStateChildden(CIntObject * widget); public: explicit CAdventureMapWidget( std::shared_ptr shortcuts ); @@ -85,13 +86,8 @@ public: void setState(EGameState newState); EGameState getState(); - void setOptionHasQuests(bool on); - void setOptionHasUnderground(bool on); - void setOptionUndergroundLevel(bool on); - void setOptionHeroSleeping(bool on); - void setOptionHeroSelected(bool on); - void setOptionHeroCanMove(bool on); - void setOptionHasNextHero(bool on); + void updateActiveState(); + }; /// Small helper class that provides ownership for shared_ptr's of child elements @@ -99,6 +95,7 @@ class CAdventureMapContainerWidget : public CIntObject { friend class CAdventureMapWidget; std::vector> ownedChildren; + std::string disableCondition; }; class CAdventureMapOverlayWidget : public CAdventureMapContainerWidget diff --git a/client/adventureMap/CAdventureOptions.cpp b/client/adventureMap/CAdventureOptions.cpp index b606c0307..22c4f2ac5 100644 --- a/client/adventureMap/CAdventureOptions.cpp +++ b/client/adventureMap/CAdventureOptions.cpp @@ -28,7 +28,7 @@ CAdventureOptions::CAdventureOptions() { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - viewWorld = std::make_shared(Point(24, 23), "ADVVIEW.DEF", CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_WORLD); + viewWorld = std::make_shared(Point(24, 23), "ADVVIEW.DEF", CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_WORLD_X2); viewWorld->addCallback( [] { LOCPLINT->viewWorldMap(); }); exit = std::make_shared(Point(204, 313), "IOK6432.DEF", CButton::tooltip(), std::bind(&CAdventureOptions::close, this), EShortcut::GLOBAL_RETURN); diff --git a/client/gui/CIntObject.cpp b/client/gui/CIntObject.cpp index 811dec3f9..abe6422df 100644 --- a/client/gui/CIntObject.cpp +++ b/client/gui/CIntObject.cpp @@ -204,6 +204,14 @@ void CIntObject::enable() recActions = 255; } +void CIntObject::setEnabled(bool on) +{ + if (on) + enable(); + else + disable(); +} + void CIntObject::fitToScreen(int borderWidth, bool propagate) { Point newPos = pos.topLeft(); diff --git a/client/gui/CIntObject.h b/client/gui/CIntObject.h index 23d76807e..2ea4f7c87 100644 --- a/client/gui/CIntObject.h +++ b/client/gui/CIntObject.h @@ -140,8 +140,13 @@ public: ui8 defActions; //which calls will be tried to be redirected to children ui8 recActions; //which calls we allow to receive from parent - void disable(); //deactivates if needed, blocks all automatic activity, allows only disposal - void enable(); //activates if needed, all activity enabled (Warning: may not be symetric with disable if recActions was limited!) + /// deactivates if needed, blocks all automatic activity, allows only disposal + void disable(); + /// activates if needed, all activity enabled (Warning: may not be symetric with disable if recActions was limited!) + void enable(); + /// deactivates or activates UI element based on flag + void setEnabled(bool on); + // activate or deactivate object. Inactive object won't receive any input events (keyboard\mouse) // usually used automatically by parent diff --git a/client/gui/InterfaceObjectConfigurable.cpp b/client/gui/InterfaceObjectConfigurable.cpp index 32c523182..e3d3139fc 100644 --- a/client/gui/InterfaceObjectConfigurable.cpp +++ b/client/gui/InterfaceObjectConfigurable.cpp @@ -82,15 +82,26 @@ void InterfaceObjectConfigurable::build(const JsonNode &config) items = &config["items"]; } - const std::string unnamedObjectPrefix = "__widget_"; for(const auto & item : items->Vector()) - { - std::string name = item["name"].isNull() - ? unnamedObjectPrefix + std::to_string(unnamedObjectId++) - : item["name"].String(); - logGlobal->debug("Building widget with name %s", name); - widgets[name] = buildWidget(item); - } + addWidget(item["name"].String(), buildWidget(item)); +} + +void InterfaceObjectConfigurable::addWidget(const std::string & namePreferred, std::shared_ptr widget) +{ + static const std::string unnamedObjectPrefix = "__widget_"; + + std::string nameActual; + + if (widgets.count(namePreferred) == 0) + nameActual = namePreferred; + else + logGlobal->error("Duplicated widget name: '%s'", namePreferred); + + if (nameActual.empty()) + nameActual = unnamedObjectPrefix + std::to_string(unnamedObjectId++); + + logGlobal->debug("Building widget with name %s", nameActual); + widgets[nameActual] = widget; } std::string InterfaceObjectConfigurable::readText(const JsonNode & config) const @@ -382,7 +393,8 @@ std::shared_ptr InterfaceObjectConfigurable::buildSlider(const JsonNode auto itemsTotal = config["itemsTotal"].Integer(); auto value = config["selected"].Integer(); bool horizontal = config["orientation"].String() == "horizontal"; - auto const & result = std::make_shared(position, length, callbacks.at(config["callback"].String()), itemsVisible, itemsTotal, value, horizontal, style); + const auto & result = + std::make_shared(position, length, callbacks.at(config["callback"].String()), itemsVisible, itemsTotal, value, horizontal, style); if (!config["scrollBounds"].isNull()) { diff --git a/client/gui/InterfaceObjectConfigurable.h b/client/gui/InterfaceObjectConfigurable.h index 7ba3d1100..c140742a5 100644 --- a/client/gui/InterfaceObjectConfigurable.h +++ b/client/gui/InterfaceObjectConfigurable.h @@ -48,6 +48,8 @@ protected: //must be called after adding callbacks void build(const JsonNode & config); + + void addWidget(const std::string & name, std::shared_ptr widget); void addCallback(const std::string & callbackName, std::function callback); JsonNode variables; diff --git a/client/gui/Shortcut.h b/client/gui/Shortcut.h index 927906111..b4411d2f4 100644 --- a/client/gui/Shortcut.h +++ b/client/gui/Shortcut.h @@ -95,12 +95,15 @@ enum class EShortcut ADVENTURE_VIEW_SCENARIO,// View Scenario Information window ADVENTURE_DIG_GRAIL, ADVENTURE_VIEW_PUZZLE, - ADVENTURE_VIEW_WORLD, + ADVENTURE_VIEW_WORLD_X1, + ADVENTURE_VIEW_WORLD_X2, + ADVENTURE_VIEW_WORLD_X4, ADVENTURE_TOGGLE_MAP_LEVEL, ADVENTURE_KINGDOM_OVERVIEW, ADVENTURE_QUEST_LOG, ADVENTURE_CAST_SPELL, ADVENTURE_THIEVES_GUILD, + ADVENTURE_EXIT_WORLD_VIEW, // Move hero one tile in specified direction. Bound to cursors & numpad buttons ADVENTURE_MOVE_HERO_SW, diff --git a/client/gui/ShortcutHandler.cpp b/client/gui/ShortcutHandler.cpp index 80a5b2d72..48907eac8 100644 --- a/client/gui/ShortcutHandler.cpp +++ b/client/gui/ShortcutHandler.cpp @@ -105,7 +105,7 @@ std::vector ShortcutHandler::translateKeycode(SDL_Keycode key) const {SDLK_i, EShortcut::ADVENTURE_VIEW_SCENARIO }, {SDLK_d, EShortcut::ADVENTURE_DIG_GRAIL }, {SDLK_p, EShortcut::ADVENTURE_VIEW_PUZZLE }, - {SDLK_v, EShortcut::ADVENTURE_VIEW_WORLD }, + {SDLK_v, EShortcut::ADVENTURE_VIEW_WORLD_X1 }, {SDLK_u, EShortcut::ADVENTURE_TOGGLE_MAP_LEVEL}, {SDLK_k, EShortcut::ADVENTURE_KINGDOM_OVERVIEW}, {SDLK_q, EShortcut::ADVENTURE_QUEST_LOG }, @@ -238,12 +238,15 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const {"adventureViewScenario", EShortcut::ADVENTURE_VIEW_SCENARIO }, {"adventureDigGrail", EShortcut::ADVENTURE_DIG_GRAIL }, {"adventureViewPuzzle", EShortcut::ADVENTURE_VIEW_PUZZLE }, - {"adventureViewWorld", EShortcut::ADVENTURE_VIEW_WORLD }, + {"adventureViewWorld1", EShortcut::ADVENTURE_VIEW_WORLD_X1 }, + {"adventureViewWorld2", EShortcut::ADVENTURE_VIEW_WORLD_X2 }, + {"adventureViewWorld4", EShortcut::ADVENTURE_VIEW_WORLD_X4 }, {"adventureToggleMapLevel", EShortcut::ADVENTURE_TOGGLE_MAP_LEVEL}, {"adventureKingdomOverview", EShortcut::ADVENTURE_KINGDOM_OVERVIEW}, {"adventureQuestLog", EShortcut::ADVENTURE_QUEST_LOG }, {"adventureCastSpell", EShortcut::ADVENTURE_CAST_SPELL }, {"adventureThievesGuild", EShortcut::ADVENTURE_THIEVES_GUILD }, + {"adventureExitWorldView", EShortcut::ADVENTURE_EXIT_WORLD_VIEW }, {"battleToggleQueue", EShortcut::BATTLE_TOGGLE_QUEUE }, {"battleUseCreatureSpell", EShortcut::BATTLE_USE_CREATURE_SPELL }, {"battleSurrender", EShortcut::BATTLE_SURRENDER }, diff --git a/config/widgets/adventureMap.json b/config/widgets/adventureMap.json index a0ae3ec89..e3cf3983f 100644 --- a/config/widgets/adventureMap.json +++ b/config/widgets/adventureMap.json @@ -113,6 +113,7 @@ { "type": "adventureMapContainer", "name" : "buttonsContainer", + "hideWhen" : "worldViewMode", "area": { "top": 196, "right" : 57, "width" : 64, "height" : 192 }, "items" : [ { @@ -125,22 +126,36 @@ "area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 } }, { - "type": "adventureMapButton", - "name": "buttonUnderground", - "image" : "IAM010.DEF", - "help" : "core.help.294", - "hotkey": "adventureToggleMapLevel", - "playerColored" : true, + "type": "adventureMapContainer", + "hideWhen" : "mapLayerUnderground", "area": { "top" : 0, "left": 32, "width" : 32, "height" : 32 } + "items" : [ + { + "type": "adventureMapButton", + "name": "buttonUnderground", + "image" : "IAM010.DEF", + "help" : "core.help.294", + "hotkey": "adventureToggleMapLevel", + "playerColored" : true, + "area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 } + } + ], }, { - "type": "adventureMapButton", - "name": "buttonSurface", - "image" : "IAM003.DEF", - "help" : "core.help.294", - "hotkey": "adventureToggleMapLevel", - "playerColored" : true, + "type": "adventureMapContainer", + "hideWhen" : "mapLayerSurface", "area": { "top" : 0, "left": 32, "width" : 32, "height" : 32 } + "items" : [ + { + "type": "adventureMapButton", + "name": "buttonSurface", + "image" : "IAM003.DEF", + "help" : "core.help.294", + "hotkey": "adventureToggleMapLevel", + "playerColored" : true, + "area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 } + } + ], }, { "type": "adventureMapButton", @@ -152,22 +167,36 @@ "area": { "top" : 32, "left": 0, "width" : 32, "height" : 32 } }, { - "type": "adventureMapButton", - "name": "buttonSleep", - "image" : "IAM005.DEF", - "help" : "core.help.296", - "hotkey": "adventureSetHeroAsleep", - "playerColored" : true, + "type": "adventureMapContainer", + "hideWhen" : "heroAwake", "area": { "top" : 32, "left": 32, "width" : 32, "height" : 32 } + "items" : [ + { + "type": "adventureMapButton", + "name": "buttonSleep", + "image" : "IAM005.DEF", + "help" : "core.help.296", + "hotkey": "adventureSetHeroAsleep", + "playerColored" : true, + "area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 } + } + ] }, { - "type": "adventureMapButton", - "name": "buttonWake", - "image" : "IAM011.DEF", - "help" : "core.help.296", - "hotkey": "adventureSetHeroAwake", - "playerColored" : true, + "type": "adventureMapContainer", + "hideWhen" : "heroSleeping", "area": { "top" : 32, "left": 32, "width" : 32, "height" : 32 } + "items" : [ + { + "type": "adventureMapButton", + "name": "buttonWake", + "image" : "IAM011.DEF", + "help" : "core.help.296", + "hotkey": "adventureSetHeroAwake", + "playerColored" : true, + "area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 } + } + ] }, { "type": "adventureMapButton", @@ -229,6 +258,7 @@ { "type": "adventureMapContainer", "name" : "listContainerSmall", + "hideWhen" : "worldViewMode", "area": { "top": 196, "right" : 0, "width" : 193, "height" : 196 }, "exists" : { "heightMax" : 664 }, "items" : [ @@ -304,6 +334,7 @@ { "type": "adventureMapContainer", "name" : "emptyAreaFillSmall", + "hideWhen" : "worldViewMode", "area": { "top": 392, "right" : 3, "width" : 190, "bottom" : 211 }, "exists" : { "heightMax" : 664 }, "items" : [ @@ -320,6 +351,7 @@ { "type": "adventureMapContainer", "name" : "listContainerLarge", + "hideWhen" : "worldViewMode", "area": { "top": 196, "right" : 0, "width" : 193, "height" : 260 }, "exists" : { "heightMin" : 664 }, "items" : [ @@ -389,6 +421,7 @@ { "type": "adventureMapContainer", "name" : "emptyAreaFillLarge", + "hideWhen" : "worldViewMode", "area": { "top": 456, "right" : 3, "width" : 190, "bottom" : 211 }, "exists" : { "heightMin" : 664 }, "items" : [ @@ -434,6 +467,7 @@ { "type": "adventureMapContainer", "name" : "worldViewContainer", + "hideWhen" : "mapViewMode", "area": { "top": 195, "right" : 4, "width" : 190, "height" : 381 }, "items" : [ {