1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

vcmi: allows to more than 8 components in infobar

This commit is contained in:
Konstantin 2023-03-10 00:18:35 +03:00
parent a0c644a0e5
commit a6cb7fd192
4 changed files with 68 additions and 26 deletions

View File

@ -1040,12 +1040,11 @@ void CPlayerInterface::showInfoDialog(EInfoWindowMode type, const std::string &t
if(autoTryHover || type == EInfoWindowMode::INFO)
{
if(adventureInt->infoBar->tryShowComponents(components, text, timer))
{
if (makingTurn && GH.listInt.size() && LOCPLINT == this)
CCS->soundh->playSound(static_cast<soundBase::soundID>(soundID));
return;
}
adventureInt->infoBar->pushComponents(components, text, timer);
if (makingTurn && GH.listInt.size() && LOCPLINT == this)
CCS->soundh->playSound(static_cast<soundBase::soundID>(soundID));
return;
}
if (settings["session"]["autoSkip"].Bool() && !GH.isKeyboardShiftDown())

View File

@ -869,6 +869,8 @@ boost::optional<Point> CAdvMapInt::keyToMoveDirection(const SDL_Keycode & key)
void CAdvMapInt::select(const CArmedInstance *sel, bool centerView)
{
assert(sel);
if(selection != sel)
infoBar->popAll();
selection = sel;
mapAudio->onSelectionChanged(sel);
if(centerView)

View File

@ -178,7 +178,10 @@ CInfoBar::VisibleComponentInfo::VisibleComponentInfo(const std::vector<Component
{
auto size = CComponent::large;
if(compsToDisplay.size() > 2)
{
size = CComponent::small;
font = FONT_TINY;
}
if(!message.empty())
{
textRect = Rect(CInfoBar::offset,
@ -192,13 +195,11 @@ CInfoBar::VisibleComponentInfo::VisibleComponentInfo(const std::vector<Component
if(compsToDisplay.size() > 4)
size = CComponent::tiny;
}
else if(compsToDisplay.size() > 4)
size = CComponent::small;
std::vector<std::shared_ptr<CComponent>> vect;
for(const auto & c : compsToDisplay)
vect.emplace_back(std::make_shared<CComponent>(c, size));
vect.emplace_back(std::make_shared<CComponent>(c, size, font));
comps = std::make_shared<CComponentBox>(vect, imageRect, 4, 4, 1);
}
@ -263,7 +264,7 @@ void CInfoBar::tick()
{
removeUsedEvents(TIME);
if(GH.topInt() == adventureInt)
showSelection();
popComponents();
}
void CInfoBar::clickLeft(tribool down, bool previousState)
@ -275,7 +276,7 @@ void CInfoBar::clickLeft(tribool down, bool previousState)
else if(state == GAME)
showDate();
else
showSelection();
popComponents();
}
}
@ -317,7 +318,24 @@ void CInfoBar::showDate()
redraw();
}
bool CInfoBar::tryShowComponents(const std::vector<Component> & components, std::string message, int timer)
void CInfoBar::pushComponents(const std::vector<Component> & components, std::string message, int timer)
{
if(components.empty())
prepareComponents(components, message, timer);
else
{
std::vector<Component> vect = components; //I do not know currently how to avoid copy here
while(!vect.empty())
{
std::vector<Component> sender = {vect.begin(), vect.begin() + std::min(vect.size(), 8ul)};
prepareComponents(sender, message, timer);
vect.erase(vect.begin(), vect.begin() + std::min(vect.size(), 8ul));
}
}
popComponents();
}
void CInfoBar::prepareComponents(const std::vector<Component> & components, std::string message, int timer)
{
auto imageH = getEstimatedComponentHeight(components.size()) + (components.empty() ? 0 : 2 * CInfoBar::offset);
auto textH = CMessage::guessHeight(message,CInfoBar::data_width - 2 * CInfoBar::offset, FONT_SMALL);
@ -327,27 +345,42 @@ bool CInfoBar::tryShowComponents(const std::vector<Component> & components, std:
// Order matters - priority form should be chosen first
if(imageH + textH < CInfoBar::data_height)
showComponents(components, message, textH, false, timer);
pushComponents(components, message, textH, false, timer);
else if(!imageH && tinyH < CInfoBar::data_height)
showComponents(components, message, tinyH, true, timer);
pushComponents(components, message, tinyH, true, timer);
else if(imageH + headerH < CInfoBar::data_height)
showComponents(components, header, headerH, false, timer);
else if(imageH < CInfoBar::data_height)
showComponents(components, "", 0, false, timer);
pushComponents(components, header, headerH, false, timer);
else
return false; //We cannot fit message to infobar, fallback to window
pushComponents(components, "", 0, false, timer);
return true;
return;
}
void CInfoBar::showComponents(const std::vector<Component> & comps, std::string message, int textH, bool tiny, int timer)
void CInfoBar::popAll()
{
componentsQueue = {};
}
void CInfoBar::popComponents()
{
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
state = COMPONENT;
visibleInfo = std::make_shared<VisibleComponentInfo>(comps, message, textH, tiny);
if(!componentsQueue.empty())
{
state = COMPONENT;
const auto & extracted = componentsQueue.front();
visibleInfo = extracted.first;
setTimer(extracted.second);
componentsQueue.pop();
redraw();
return;
}
showSelection();
}
setTimer(timer);
redraw();
void CInfoBar::pushComponents(const std::vector<Component> & comps, std::string message, int textH, bool tiny, int timer)
{
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
componentsQueue.emplace(std::make_shared<VisibleComponentInfo>(comps, message, textH, tiny), timer);
}
bool CInfoBar::showingComponents()

View File

@ -125,8 +125,13 @@ private:
std::shared_ptr<CVisibleInfo> visibleInfo;
EState state;
std::queue<std::pair<std::shared_ptr<VisibleComponentInfo>, int>> componentsQueue;
//private helper for showing components
void showComponents(const std::vector<Component> & comps, std::string message, int textH, bool tiny = false, int timer = 3000);
void showComponents(const std::vector<Component> & comps, std::string message, int textH, bool tiny, int timer);
void pushComponents(const std::vector<Component> & comps, std::string message, int textH, bool tiny, int timer);
void prepareComponents(const std::vector<Component> & comps, std::string message, int timer);
void popComponents();
//removes all information about current state, deactivates timer (if any)
void reset();
@ -146,7 +151,10 @@ public:
void showDate();
/// show components for 3 seconds. Used to display picked up resources. Can display up to 8 components
bool tryShowComponents(const std::vector<Component> & comps, std::string message, int timer = 3000);
void pushComponents(const std::vector<Component> & comps, std::string message, int timer = 3000);
/// Remove all queued components
void popAll();
/// print enemy turn progress
void startEnemyTurn(PlayerColor color);