4b0bc220e4
Context-specific (like per-world) timescales can also be added later
93 lines
3.4 KiB
C++
93 lines
3.4 KiB
C++
#include "StarStatusPane.hpp"
|
|
#include "StarJsonExtra.hpp"
|
|
#include "StarRoot.hpp"
|
|
#include "StarUniverseClient.hpp"
|
|
#include "StarGuiReader.hpp"
|
|
#include "StarImageWidget.hpp"
|
|
#include "StarPlayer.hpp"
|
|
#include "StarAssets.hpp"
|
|
#include "StarStatusEffectDatabase.hpp"
|
|
#include "StarImageMetadataDatabase.hpp"
|
|
#include "StarImageProcessing.hpp"
|
|
#include "StarSimpleTooltip.hpp"
|
|
|
|
namespace Star {
|
|
|
|
StatusPane::StatusPane(MainInterfacePaneManager* paneManager, UniverseClientPtr client) {
|
|
m_paneManager = paneManager;
|
|
m_client = client;
|
|
m_player = m_client->mainPlayer();
|
|
|
|
m_guiContext = GuiContext::singletonPtr();
|
|
auto assets = Root::singleton().assets();
|
|
|
|
GuiReader reader;
|
|
reader.construct(assets->json("/interface/windowconfig/statuspane.config:paneLayout"), this);
|
|
disableScissoring();
|
|
}
|
|
|
|
PanePtr StatusPane::createTooltip(Vec2I const& screenPosition) {
|
|
auto interfaceScale = m_guiContext->interfaceScale();
|
|
for (auto const& indicator : m_statusIndicators) {
|
|
if (indicator.screenRect.contains(Vec2F(screenPosition * interfaceScale))) {
|
|
if (!indicator.label.empty())
|
|
return SimpleTooltipBuilder::buildTooltip(indicator.label);
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
void StatusPane::renderImpl() {
|
|
Pane::renderImpl();
|
|
|
|
auto assets = Root::singleton().assets();
|
|
auto interfaceScale = m_guiContext->interfaceScale();
|
|
auto imageMetadataDatabase = Root::singleton().imageMetadataDatabase();
|
|
|
|
String statusIconDarkenImage = assets->json("/interface.config:statusIconDarkenImage").toString();
|
|
|
|
for (auto const& entry : m_statusIndicators) {
|
|
String image = entry.icon;
|
|
if (entry.durationPercentage) {
|
|
int imageHeight = imageMetadataDatabase->imageSize(image)[1];
|
|
int yOffset = -(int)(*entry.durationPercentage * imageHeight);
|
|
image += "?" + imageOperationToString(BlendImageOperation{
|
|
BlendImageOperation::Multiply, {statusIconDarkenImage}, Vec2I(0, yOffset)});
|
|
}
|
|
m_guiContext->drawQuad(image, entry.screenRect.min(), interfaceScale);
|
|
}
|
|
}
|
|
|
|
void StatusPane::update(float dt) {
|
|
Pane::update(dt);
|
|
|
|
auto assets = Root::singleton().assets();
|
|
auto interfaceScale = m_guiContext->interfaceScale();
|
|
int roundWindowHeight = ceil(windowHeight() / interfaceScale) * interfaceScale;
|
|
|
|
auto imageMetadataDatabase = Root::singleton().imageMetadataDatabase();
|
|
auto statusEffectDatabase = Root::singleton().statusEffectDatabase();
|
|
|
|
Vec2I statusIconOffset = jsonToVec2I(assets->json("/interface.config:statusIconPos"));
|
|
Vec2I statusIconPos = Vec2I(statusIconOffset[0] * interfaceScale, roundWindowHeight - statusIconOffset[1] * interfaceScale);
|
|
Vec2I statusIconShift = jsonToVec2I(assets->json("/interface.config:statusIconShift")) * interfaceScale;
|
|
|
|
RectF boundRect = RectF::null();
|
|
|
|
m_statusIndicators.clear();
|
|
for (auto const& pair : m_player->activeUniqueStatusEffectSummary()) {
|
|
auto effectConfig = statusEffectDatabase->uniqueEffectConfig(pair.first);
|
|
if (effectConfig.icon) {
|
|
RectF rect = RectF::withSize(Vec2F(statusIconPos), Vec2F(imageMetadataDatabase->imageSize(*effectConfig.icon)) * interfaceScale);
|
|
boundRect.combine(rect);
|
|
m_statusIndicators.append(StatusEffectIndicator{*effectConfig.icon, pair.second, effectConfig.label, rect});
|
|
statusIconPos += statusIconShift;
|
|
}
|
|
}
|
|
|
|
setPosition(Vec2I::round(boundRect.min() / interfaceScale));
|
|
setSize(Vec2I::round(boundRect.size() / interfaceScale));
|
|
}
|
|
|
|
}
|