1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-10-31 00:07:39 +02:00

make town title editable

This commit is contained in:
Laserlicht
2025-10-05 01:49:00 +02:00
parent da79b27547
commit f5d1657041
7 changed files with 120 additions and 14 deletions

View File

@@ -27,6 +27,80 @@
std::list<CFocusable *> CFocusable::focusables;
CFocusable * CFocusable::inputWithFocus;
CTextInputWithConfirm::CTextInputWithConfirm(const Rect & Pos, EFonts font, ETextAlignment alignment, std::string text, bool limitToRect, std::function<void()> confirmCallback)
: CTextInput(Pos, font, alignment, false), confirmCb(confirmCallback), limitToRect(limitToRect), initialText(text)
{
setText(text);
}
bool CTextInputWithConfirm::captureThisKey(EShortcut key)
{
return hasFocus() && (key == EShortcut::GLOBAL_ACCEPT || key == EShortcut::GLOBAL_CANCEL || key == EShortcut::GLOBAL_BACKSPACE);
}
void CTextInputWithConfirm::keyPressed(EShortcut key)
{
if(!hasFocus())
return;
if(key == EShortcut::GLOBAL_ACCEPT)
confirm();
else if(key == EShortcut::GLOBAL_CANCEL)
{
setText(initialText);
removeFocus();
}
CTextInput::keyPressed(key);
}
bool CTextInputWithConfirm::receiveEvent(const Point & position, int eventType) const
{
return eventType == AEventsReceiver::LCLICK; // capture all left clicks (not only within control)
}
void CTextInputWithConfirm::clickReleased(const Point & cursorPosition)
{
if(!pos.isInside(cursorPosition)) // clicked outside
confirm();
}
void CTextInputWithConfirm::clickPressed(const Point & cursorPosition)
{
if(pos.isInside(cursorPosition)) // clickPressed should respect control area (receiveEvent also affects this)
CTextInput::clickPressed(cursorPosition);
}
void CTextInputWithConfirm::onFocusGot()
{
initialText = getText();
CTextInput::onFocusGot();
}
void CTextInputWithConfirm::textInputted(const std::string & enteredText)
{
if(!hasFocus())
return;
CTextInput::textInputted(enteredText);
std::string visibleText = getVisibleText();
const auto & font = ENGINE->renderHandler().loadFont(label->font);
while(limitToRect && font->getStringWidth(visibleText) > pos.w)
{
TextOperations::trimRightUnicode(currentText);
visibleText = getVisibleText();
}
}
void CTextInputWithConfirm::confirm()
{
if(confirmCb && initialText != getText())
confirmCb();
removeFocus();
}
CTextInput::CTextInput(const Rect & Pos)
:originalAlignment(ETextAlignment::CENTERLEFT)
{

View File

@@ -45,8 +45,9 @@ public:
};
/// Text input box where players can enter text
class CTextInput final : public CFocusable
class CTextInput : public CFocusable
{
protected:
using TextEditedCallback = std::function<void(const std::string &)>;
using TextFilterCallback = std::function<void(std::string &, const std::string &)>;
@@ -71,12 +72,12 @@ class CTextInput final : public CFocusable
void createLabel(bool giveFocusToInput);
void updateLabel();
void clickPressed(const Point & cursorPosition) final;
void textInputted(const std::string & enteredText) final;
void textEdited(const std::string & enteredText) final;
void onFocusGot() final;
void onFocusLost() final;
void showPopupWindow(const Point & cursorPosition) final;
void clickPressed(const Point & cursorPosition) override;
void textInputted(const std::string & enteredText) override;
void textEdited(const std::string & enteredText) override;
void onFocusGot() override;
void onFocusLost() override;
void showPopupWindow(const Point & cursorPosition) override;
CTextInput(const Rect & Pos);
public:
@@ -105,7 +106,26 @@ public:
void setAlignment(ETextAlignment alignment);
// CIntObject interface impl
void keyPressed(EShortcut key) final;
void activate() final;
void deactivate() final;
void keyPressed(EShortcut key) override;
void activate() override;
void deactivate() override;
};
class CTextInputWithConfirm final : public CTextInput
{
std::string initialText;
std::function<void()> confirmCb;
bool limitToRect;
void confirm();
public:
CTextInputWithConfirm(const Rect & Pos, EFonts font, ETextAlignment alignment, std::string text, bool limitToRect, std::function<void()> confirmCallback);
bool captureThisKey(EShortcut key) override;
void keyPressed(EShortcut key) override;
void clickReleased(const Point & cursorPosition) override;
void clickPressed(const Point & cursorPosition) override;
bool receiveEvent(const Point & position, int eventType) const override;
void onFocusGot() override;
void textInputted(const std::string & enteredText) override;
};

View File

@@ -30,6 +30,7 @@
#include "../widgets/MiscWidgets.h"
#include "../widgets/CComponent.h"
#include "../widgets/CGarrisonInt.h"
#include "../widgets/CTextInput.h"
#include "../widgets/Buttons.h"
#include "../widgets/TextControls.h"
#include "../widgets/RadialMenu.h"
@@ -1435,7 +1436,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
garr->setRedrawParent(true);
heroes = std::make_shared<HeroSlots>(town, Point(241, 387), Point(241, 483), garr, true);
title = std::make_shared<CLabel>(85, 387, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE, town->getNameTranslated());
title = std::make_shared<CTextInputWithConfirm>(Rect(83, 386, 140, 20), FONT_MEDIUM, ETextAlignment::TOPLEFT, town->getNameTranslated(), true, [this](){ std::cout << title->getText(); });
income = std::make_shared<CLabel>(195, 443, FONT_SMALL, ETextAlignment::CENTER);
icon = std::make_shared<CAnimImage>(AnimationPath::builtin("ITPT"), 0, 0, 15, 387);

View File

@@ -37,6 +37,7 @@ class CGarrisonInt;
class CComponent;
class CComponentBox;
class LRClickableArea;
class CTextInputWithConfirm;
/// Building "button"
class CBuildingRect : public CShowableAnim
@@ -225,7 +226,7 @@ public:
/// Class which manages the castle window
class CCastleInterface final : public CStatusbarWindow, public IGarrisonHolder, public IArtifactsHolder
{
std::shared_ptr<CLabel> title;
std::shared_ptr<CTextInputWithConfirm> title;
std::shared_ptr<CLabel> income;
std::shared_ptr<CAnimImage> icon;

View File

@@ -852,7 +852,7 @@ CBonusSystemNode & CGTownInstance::whatShouldBeAttached()
std::string CGTownInstance::getNameTranslated() const
{
return LIBRARY->generaltexth->translate(nameTextId);
return customName.empty() ? LIBRARY->generaltexth->translate(nameTextId) : customName;
}
std::string CGTownInstance::getNameTextID() const
@@ -865,6 +865,11 @@ void CGTownInstance::setNameTextId( const std::string & newName )
nameTextId = newName;
}
void CGTownInstance::setCustomName( const std::string & newName )
{
customName = newName;
}
const CArmedInstance * CGTownInstance::getUpperArmy() const
{
if(getGarrisonHero())

View File

@@ -46,6 +46,7 @@ class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public I
{
friend class CTownInstanceConstructor;
std::string nameTextId; // name of town
std::string customName;
std::map<BuildingID, TownRewardableBuildingInstance*> convertOldBuildings(std::vector<TownRewardableBuildingInstance*> oldVector);
std::set<BuildingID> builtBuildings;
@@ -75,6 +76,8 @@ public:
{
h & static_cast<CGDwelling&>(*this);
h & nameTextId;
if (h.version >= Handler::Version::CUSTOM_NAMES)
h & customName;
h & built;
h & destroyed;
h & identifier;
@@ -128,6 +131,7 @@ public:
std::string getNameTranslated() const;
std::string getNameTextID() const;
void setNameTextId(const std::string & newName);
void setCustomName(const std::string & newName);
//////////////////////////////////////////////////////////////////////////

View File

@@ -50,8 +50,9 @@ enum class ESerializationVersion : int32_t
BONUS_HIDDEN, // hidden bonus
MORE_MAP_LAYERS, // more map layers
CONFIGURABLE_RESOURCES, // configurable resources
CUSTOM_NAMES, // custom names
CURRENT = CONFIGURABLE_RESOURCES,
CURRENT = CUSTOM_NAMES,
};
static_assert(ESerializationVersion::MINIMAL <= ESerializationVersion::CURRENT, "Invalid serialization version definition!");