mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
Implemented configurable buttons. Replaced 'animateLonelyFrame' logic.
This commit is contained in:
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"basepath" : "lobby/",
|
||||
"images" :
|
||||
[
|
||||
{ "frame" : 0, "file" : "selectionTabSortDate.png"}
|
||||
]
|
||||
}
|
||||
@@ -216,8 +216,9 @@ SelectionTab::SelectionTab(ESelectionScreen Type)
|
||||
|
||||
if(enableUiEnhancements)
|
||||
{
|
||||
buttonsSortBy.push_back(std::make_shared<CButton>(Point(371, 85), AnimationPath::builtin("lobby/selectionTabSortDate"), CButton::tooltip("", CGI->generaltexth->translate("vcmi.lobby.sortDate")), std::bind(&SelectionTab::sortBy, this, ESortBy::_changeDate)));
|
||||
//TODO: buttonsSortBy.back()->setAnimateLonelyFrame(true);
|
||||
auto sortByDate = std::make_shared<CButton>(Point(371, 85), AnimationPath::builtin("selectionTabSortDate"), CButton::tooltip("", CGI->generaltexth->translate("vcmi.lobby.sortDate")), std::bind(&SelectionTab::sortBy, this, ESortBy::_changeDate));
|
||||
sortByDate->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("lobby/selectionTabSortDate")));
|
||||
buttonsSortBy.push_back(sortByDate);
|
||||
}
|
||||
|
||||
iconsMapFormats = GH.renderHandler().loadAnimation(AnimationPath::builtin("SCSELC.DEF"));
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/MouseButton.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../gui/InterfaceObjectConfigurable.h"
|
||||
#include "../windows/InfoWindows.h"
|
||||
#include "../render/CAnimation.h"
|
||||
#include "../render/Canvas.h"
|
||||
@@ -29,6 +30,7 @@
|
||||
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/filesystem/Filesystem.h"
|
||||
|
||||
void ButtonBase::update()
|
||||
{
|
||||
@@ -42,15 +44,14 @@ void ButtonBase::update()
|
||||
overlay->moveTo(targetPos);
|
||||
}
|
||||
|
||||
int newPos = stateToIndex[int(state)];
|
||||
if (newPos < 0)
|
||||
newPos = 0;
|
||||
|
||||
// checkbox - has only have two frames: normal and pressed/highlighted
|
||||
// hero movement speed buttons: only three frames: normal, pressed and blocked/highlighted
|
||||
if (state == EButtonState::HIGHLIGHTED && image->size() < 4)
|
||||
newPos = (int)image->size()-1;
|
||||
image->setFrame(newPos);
|
||||
if (image)
|
||||
{
|
||||
// checkbox - has only have two frames: normal and pressed/highlighted
|
||||
// hero movement speed buttons: only three frames: normal, pressed and blocked/highlighted
|
||||
if (state == EButtonState::HIGHLIGHTED && image->size() < 4)
|
||||
image->setFrame(image->size()-1);
|
||||
image->setFrame(stateToIndex[vstd::to_underlying(state)]);
|
||||
}
|
||||
|
||||
if (isActive())
|
||||
redraw();
|
||||
@@ -89,6 +90,7 @@ void ButtonBase::setImage(const AnimationPath & defName, bool playerColoredButto
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
|
||||
|
||||
configurable.reset();
|
||||
image = std::make_shared<CAnimImage>(defName, vstd::to_underlying(getState()));
|
||||
pos = image->pos;
|
||||
|
||||
@@ -96,6 +98,41 @@ void ButtonBase::setImage(const AnimationPath & defName, bool playerColoredButto
|
||||
image->playerColored(LOCPLINT->playerID);
|
||||
}
|
||||
|
||||
const JsonNode & ButtonBase::getCurrentConfig() const
|
||||
{
|
||||
if (!config)
|
||||
throw std::runtime_error("No config found in button!");
|
||||
|
||||
static constexpr std::array stateToConfig = {
|
||||
"normal",
|
||||
"pressed",
|
||||
"blocked",
|
||||
"highlighted"
|
||||
};
|
||||
|
||||
std::string key = stateToConfig[vstd::to_underlying(getState())];
|
||||
const JsonNode & value = (*config)[key];
|
||||
|
||||
if (value.isNull())
|
||||
throw std::runtime_error("No config found in button for state " + key + "!");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void ButtonBase::setConfigurable(const JsonPath & jsonName, bool playerColoredButton)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
|
||||
|
||||
config = std::make_unique<JsonNode>(jsonName);
|
||||
|
||||
image.reset();
|
||||
configurable = std::make_shared<InterfaceObjectConfigurable>(getCurrentConfig());
|
||||
pos = configurable->pos;
|
||||
|
||||
if (playerColoredButton)
|
||||
image->playerColored(LOCPLINT->playerID);
|
||||
}
|
||||
|
||||
void CButton::addHoverText(EButtonState state, std::string text)
|
||||
{
|
||||
hoverTexts[vstd::to_underlying(state)] = text;
|
||||
@@ -110,15 +147,24 @@ void ButtonBase::setImageOrder(int state1, int state2, int state3, int state4)
|
||||
update();
|
||||
}
|
||||
|
||||
//TODO:
|
||||
//void CButton::setAnimateLonelyFrame(bool agreement)
|
||||
//{
|
||||
// animateLonelyFrame = agreement;
|
||||
//}
|
||||
|
||||
void ButtonBase::setStateImpl(EButtonState newState)
|
||||
{
|
||||
state = newState;
|
||||
|
||||
if (configurable)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
|
||||
configurable = std::make_shared<InterfaceObjectConfigurable>(getCurrentConfig());
|
||||
pos = configurable->pos;
|
||||
|
||||
if (overlay)
|
||||
{
|
||||
// Force overlay on top
|
||||
removeChild(overlay.get());
|
||||
addChild(overlay.get());
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -135,7 +181,7 @@ void CButton::setState(EButtonState newState)
|
||||
setStateImpl(newState);
|
||||
}
|
||||
|
||||
EButtonState ButtonBase::getState()
|
||||
EButtonState ButtonBase::getState() const
|
||||
{
|
||||
return state;
|
||||
}
|
||||
@@ -270,9 +316,21 @@ ButtonBase::ButtonBase(Point position, const AnimationPath & defName, EShortcut
|
||||
pos.x += position.x;
|
||||
pos.y += position.y;
|
||||
|
||||
setImage(defName);
|
||||
JsonPath jsonConfig = defName.toType<EResType::JSON>().addPrefix("CONFIG/WIDGETS/BUTTONS/");
|
||||
if (CResourceHandler::get()->existsResource(jsonConfig))
|
||||
{
|
||||
setConfigurable(jsonConfig, playerColoredButton);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
setImage(defName, playerColoredButton);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ButtonBase::~ButtonBase() = default;
|
||||
|
||||
CButton::CButton(Point position, const AnimationPath &defName, const std::pair<std::string, std::string> &help, CFunctionList<void()> Callback, EShortcut key, bool playerColoredButton):
|
||||
ButtonBase(position, defName, key, playerColoredButton),
|
||||
callback(Callback)
|
||||
|
||||
@@ -19,8 +19,7 @@ class Rect;
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
class CAnimImage;
|
||||
class CLabel;
|
||||
class CAnimation;
|
||||
class InterfaceObjectConfigurable;
|
||||
|
||||
enum class EButtonState
|
||||
{
|
||||
@@ -33,7 +32,9 @@ enum class EButtonState
|
||||
class ButtonBase : public CKeyShortcut
|
||||
{
|
||||
std::shared_ptr<CAnimImage> image; //image for this button
|
||||
std::shared_ptr<InterfaceObjectConfigurable> configurable; //image for this button
|
||||
std::shared_ptr<CIntObject> overlay;//object-overlay, can be null
|
||||
std::unique_ptr<JsonNode> config;
|
||||
|
||||
std::array<int, 4> stateToIndex; // mapping of button state to index of frame in animation
|
||||
|
||||
@@ -41,16 +42,20 @@ class ButtonBase : public CKeyShortcut
|
||||
|
||||
void update();//to refresh button after image or text change
|
||||
|
||||
const JsonNode & getCurrentConfig() const;
|
||||
|
||||
protected:
|
||||
ButtonBase(Point position, const AnimationPath & defName, EShortcut key, bool playerColoredButton);
|
||||
~ButtonBase();
|
||||
|
||||
void setStateImpl(EButtonState state);
|
||||
EButtonState getState();
|
||||
EButtonState getState() const;
|
||||
|
||||
public:
|
||||
/// Appearance modifiers
|
||||
void setPlayerColor(PlayerColor player);
|
||||
void setImage(const AnimationPath & defName, bool playerColoredButton = false);
|
||||
void setConfigurable(const JsonPath & jsonName, bool playerColoredButton = false);
|
||||
void setImageOrder(int state1, int state2, int state3, int state4);
|
||||
|
||||
/// adds overlay on top of button image. Only one overlay can be active at once
|
||||
|
||||
@@ -1332,14 +1332,12 @@ void CCastleInterface::recreateIcons()
|
||||
hall = std::make_shared<CTownInfo>(80, 413, town, true);
|
||||
fort = std::make_shared<CTownInfo>(122, 413, town, false);
|
||||
|
||||
fastTownHall = std::make_shared<CButton>(Point(80, 413), AnimationPath::builtin("ITMTL.def"), CButton::tooltip(), [&](){ builds->enterTownHall(); });
|
||||
fastTownHall->setImageOrder(town->hallLevel(), town->hallLevel(), town->hallLevel(), town->hallLevel());
|
||||
//TODO: fastTownHall->setAnimateLonelyFrame(true);
|
||||
fastTownHall = std::make_shared<CButton>(Point(80, 413), AnimationPath::builtin("castleInterfaceQuickAccess"), CButton::tooltip(), [&](){ builds->enterTownHall(); });
|
||||
fastTownHall->setOverlay(std::make_shared<CAnimImage>(AnimationPath::builtin("ITMTL"), town->hallLevel()));
|
||||
|
||||
int imageIndex = town->fortLevel() == CGTownInstance::EFortLevel::NONE ? 3 : town->fortLevel() - 1;
|
||||
fastArmyPurchase = std::make_shared<CButton>(Point(122, 413), AnimationPath::builtin("itmcl.def"), CButton::tooltip(), [&](){ builds->enterToTheQuickRecruitmentWindow(); });
|
||||
fastArmyPurchase->setImageOrder(imageIndex, imageIndex, imageIndex, imageIndex);
|
||||
//TODO: fastArmyPurchase->setAnimateLonelyFrame(true);
|
||||
fastArmyPurchase = std::make_shared<CButton>(Point(122, 413), AnimationPath::builtin("castleInterfaceQuickAccess"), CButton::tooltip(), [&](){ builds->enterToTheQuickRecruitmentWindow(); });
|
||||
fastArmyPurchase->setOverlay(std::make_shared<CAnimImage>(AnimationPath::builtin("itmcl"), imageIndex));
|
||||
|
||||
fastMarket = std::make_shared<LRClickableArea>(Rect(163, 410, 64, 42), [&]()
|
||||
{
|
||||
|
||||
@@ -821,13 +821,13 @@ CTownItem::CTownItem(const CGTownInstance * Town)
|
||||
available.push_back(std::make_shared<CCreaInfo>(Point(48+37*(int)i, 78), town, (int)i, true, false));
|
||||
}
|
||||
|
||||
fastTownHall = std::make_shared<CButton>(Point(69, 31), AnimationPath::builtin("ITMTL.def"), CButton::tooltip(), [&]() { std::make_shared<CCastleBuildings>(town)->enterTownHall(); });
|
||||
fastTownHall->setImageOrder(town->hallLevel(), town->hallLevel(), town->hallLevel(), town->hallLevel());
|
||||
//TODO: fastTownHall->setAnimateLonelyFrame(true);
|
||||
fastTownHall = std::make_shared<CButton>(Point(69, 31), AnimationPath::builtin("castleInterfaceQuickAccessz"), CButton::tooltip(), [&]() { std::make_shared<CCastleBuildings>(town)->enterTownHall(); });
|
||||
fastTownHall->setOverlay(std::make_shared<CAnimImage>(AnimationPath::builtin("ITMTL"), town->hallLevel()));
|
||||
|
||||
int imageIndex = town->fortLevel() == CGTownInstance::EFortLevel::NONE ? 3 : town->fortLevel() - 1;
|
||||
fastArmyPurchase = std::make_shared<CButton>(Point(111, 31), AnimationPath::builtin("itmcl.def"), CButton::tooltip(), [&]() { std::make_shared<CCastleBuildings>(town)->enterToTheQuickRecruitmentWindow(); });
|
||||
fastArmyPurchase->setImageOrder(imageIndex, imageIndex, imageIndex, imageIndex);
|
||||
//TODO: fastArmyPurchase->setAnimateLonelyFrame(true);
|
||||
fastArmyPurchase = std::make_shared<CButton>(Point(111, 31), AnimationPath::builtin("castleInterfaceQuickAccessz"), CButton::tooltip(), [&]() { std::make_shared<CCastleBuildings>(town)->enterToTheQuickRecruitmentWindow(); });
|
||||
fastArmyPurchase->setOverlay(std::make_shared<CAnimImage>(AnimationPath::builtin("itmcl"), imageIndex));
|
||||
|
||||
fastTavern = std::make_shared<LRClickableArea>(Rect(5, 6, 58, 64), [&]()
|
||||
{
|
||||
if(town->builtBuildings.count(BuildingID::TAVERN))
|
||||
|
||||
22
config/widgets/buttons/castleInterfaceQuickAccess.json
Normal file
22
config/widgets/buttons/castleInterfaceQuickAccess.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"normal" : {
|
||||
"width": 38,
|
||||
"height": 38,
|
||||
"items" : []
|
||||
},
|
||||
"pressed" : {
|
||||
"width": 38,
|
||||
"height": 38,
|
||||
"items" : []
|
||||
},
|
||||
"blocked" : {
|
||||
"width": 38,
|
||||
"height": 38,
|
||||
"items" : []
|
||||
},
|
||||
"highlighted" : {
|
||||
"width": 38,
|
||||
"height": 38,
|
||||
"items" : []
|
||||
},
|
||||
}
|
||||
22
config/widgets/buttons/selectionTabSortDate.json
Normal file
22
config/widgets/buttons/selectionTabSortDate.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"normal" : {
|
||||
"width": 18,
|
||||
"height": 31,
|
||||
"items" : []
|
||||
},
|
||||
"pressed" : {
|
||||
"width": 18,
|
||||
"height": 31,
|
||||
"items" : []
|
||||
},
|
||||
"blocked" : {
|
||||
"width": 18,
|
||||
"height": 31,
|
||||
"items" : []
|
||||
},
|
||||
"highlighted" : {
|
||||
"width": 18,
|
||||
"height": 31,
|
||||
"items" : []
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user