From 01ca21ae67ff61188b8515bbd31b85441bd8d1fa Mon Sep 17 00:00:00 2001 From: toneyisnow Date: Tue, 21 Jan 2020 01:09:08 -0800 Subject: [PATCH 1/2] Fix bug: LobbyScreen UI has a bug on the Difficulty toggle group. Scenario: In LoadGame Lobby screen, the difficulty toggle group is showing multiple choices, but actually only one valid is working. The reason is, in the Lobby screen Initialization code will set the difficulty = 0, and each time the player changes a map in the selection, the toggle group control is not resetting the difficulty buttons to disabled state. How fix: Add a new method to ToggleGroup class: setSelectedOnly, which will disable all other buttons and then set the selected button. Note: During the game loading time, the client is loading the map, and send a NetPack to server: LobbySetMap, and send a NetPack to Interface: LobbyUpdateState. In the LobbyUpdateState it sets the map difficulty. --- client/lobby/CLobbyScreen.cpp | 16 +++++++++++++--- client/widgets/Buttons.cpp | 23 +++++++++++++++++++++++ client/widgets/Buttons.h | 8 ++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/client/lobby/CLobbyScreen.cpp b/client/lobby/CLobbyScreen.cpp index ad076088a..4406f2865 100644 --- a/client/lobby/CLobbyScreen.cpp +++ b/client/lobby/CLobbyScreen.cpp @@ -187,9 +187,19 @@ void CLobbyScreen::updateAfterStateChange() tabOpt->recreate(); card->changeSelection(); - if(card->iconDifficulty) - card->iconDifficulty->setSelected(CSH->si->difficulty); - + if (card->iconDifficulty) + { + if (screenType == ESelectionScreen::loadGame) + { + // When loading the game, only one button in the difficulty toggle group should be enabled, so here disable all other buttons first, then make selection + card->iconDifficulty->setSelectedOnly(CSH->si->difficulty); + } + else + { + card->iconDifficulty->setSelected(CSH->si->difficulty); + } + } + if(curTab == tabRand && CSH->si->mapGenOptions) tabRand->setMapGenOptions(CSH->si->mapGenOptions); } diff --git a/client/widgets/Buttons.cpp b/client/widgets/Buttons.cpp index f605866fd..519084347 100644 --- a/client/widgets/Buttons.cpp +++ b/client/widgets/Buttons.cpp @@ -23,6 +23,8 @@ #include "../windows/InfoWindows.h" #include "../../lib/CConfigHandler.h" +using namespace std; + void CButton::update() { if (overlay) @@ -322,6 +324,11 @@ void CToggleBase::doSelect(bool on) // for overrides } +void CToggleBase::setEnabled(bool enabled) +{ + // for overrides +} + void CToggleBase::setSelected(bool on) { bool changed = (on != selected); @@ -363,6 +370,11 @@ void CToggleButton::doSelect(bool on) } } +void CToggleButton::setEnabled(bool enabled) +{ + setState(enabled ? NORMAL : BLOCKED); +} + void CToggleButton::clickLeft(tribool down, bool previousState) { // force refresh @@ -425,6 +437,17 @@ void CToggleGroup::setSelected(int id) selectionChanged(id); } +void CToggleGroup::setSelectedOnly(int id) +{ + for (map >::iterator it = buttons.begin(); it != buttons.end(); it++) + { + int buttonId = it->first; + buttons[buttonId]->setEnabled(buttonId == id); + } + + selectionChanged(id); +} + void CToggleGroup::selectionChanged(int to) { if (to == selectedID) diff --git a/client/widgets/Buttons.h b/client/widgets/Buttons.h index fe875c8e9..9e8ac298b 100644 --- a/client/widgets/Buttons.h +++ b/client/widgets/Buttons.h @@ -139,12 +139,17 @@ public: void setSelected(bool on); void addCallback(std::function callback); + + /// Set whether the toggle is currently enabled for user to use, this is only inplemented in ToggleButton, not for other toggles yet. + virtual void setEnabled(bool enabled); }; /// A button which can be selected/deselected, checkbox class CToggleButton : public CButton, public CToggleBase { void doSelect(bool on) override; + void setEnabled(bool enabled) override; + public: CToggleButton(Point position, const std::string &defName, const std::pair &help, CFunctionList Callback = 0, int key=0, bool playerColoredButton = false ); @@ -173,6 +178,9 @@ public: void addToggle(int index, std::shared_ptr button); /// Changes selection to specific value. Will select toggle with this ID, if present void setSelected(int id); + /// in some cases, e.g. LoadGame difficulty selection, after refreshing the UI, the ToggleGroup should + /// reset all of it's child buttons to BLOCK state, then make selection again + void setSelectedOnly(int id); }; /// A typical slider for volume with an animated indicator From 8341ba3c278d78b63e24c5f633766c4e3d608565 Mon Sep 17 00:00:00 2001 From: toneyisnow Date: Wed, 22 Jan 2020 23:07:20 -0800 Subject: [PATCH 2/2] Update according to comments. --- client/widgets/Buttons.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/widgets/Buttons.cpp b/client/widgets/Buttons.cpp index 519084347..d50e3cf0a 100644 --- a/client/widgets/Buttons.cpp +++ b/client/widgets/Buttons.cpp @@ -23,8 +23,6 @@ #include "../windows/InfoWindows.h" #include "../../lib/CConfigHandler.h" -using namespace std; - void CButton::update() { if (overlay) @@ -439,7 +437,7 @@ void CToggleGroup::setSelected(int id) void CToggleGroup::setSelectedOnly(int id) { - for (map >::iterator it = buttons.begin(); it != buttons.end(); it++) + for(auto it = buttons.begin(); it != buttons.end(); it++) { int buttonId = it->first; buttons[buttonId]->setEnabled(buttonId == id);