feat(editor): franja HUD amb mode, brush/sel, cursor i recompte de constraints

This commit is contained in:
JailDesigner committed 2026-05-02 11:41:25 +02:00
1 parent 10e16d7905
commit 2a78c78e77
2 files changed
+94

No files matched your search

+81
View File
@@ -9,12 +9,15 @@
#include "core/input/key_config.hpp"
#include "core/locale/locale.hpp"
#include "core/rendering/hud_constants.hpp"
#include "core/rendering/notification_presets.hpp"
#include "core/rendering/screen.hpp"
#include "core/rendering/surface.hpp"
#include "core/rendering/text.hpp"
#include "core/resources/resource_cache.hpp"
#include "core/resources/resource_helper.hpp"
#include "core/system/event_buffer.hpp"
#include "core/ui/ui_config.hpp"
#include "external/fkyaml_node.hpp"
#include "game/editor/editor_config.hpp"
#include "game/entities/entity.hpp"
@@ -185,9 +188,19 @@ void Editor::enter() {
brush_entity_.clear();
hand_selected_idx_ = -1;
ensureEditableEntities();
ensureHudFont();
Notification::notify(Locale::get().text("input.editor_on"));
}
void Editor::ensureHudFont() {
if (hud_font_ != nullptr) { return; }
const auto KEY = UiConfig::get().hudFont().name + ".gif";
auto surface = Resource::Cache::get().getSurface(KEY);
if (surface == nullptr) { return; }
hud_font_ = std::make_shared<Text>(surface, UiConfig::get().hudFont().fnt);
hud_font_->setDefaultKerning(UiConfig::get().hudFont().kerning);
}
void Editor::ensureEditableEntities() {
if (!editable_entities_.empty()) { return; }
// Recorrem tots els noms registrats al factory i ens quedem amb els
@@ -623,6 +636,67 @@ void Editor::deleteSelected(EntityManager& entities) {
if (entities.removeEntity(target)) { hand_selected_idx_ = -1; }
}
void Editor::renderEditorHud(const EntityManager& entities) const {
if (hud_font_ == nullptr || Map::hud_h <= 0) { return; }
auto& screen = Screen::get();
const auto& pal = Resource::Cache::get().getPalette("ui");
screen.fillRect(0, 0, GameCanvas::WIDTH, Map::hud_h, pal[UiConfig::get().hudBg()]);
std::string mode_str;
switch (mode_) {
case Mode::TILE:
mode_str = "TILE";
break;
case Mode::ENTITY:
mode_str = "ENTITY";
break;
case Mode::HAND:
mode_str = "HAND";
break;
}
std::string brush_label;
std::string brush_value;
if (mode_ == Mode::TILE) {
brush_label = "BRUSH:";
brush_value = (brush_tile_ >= 0) ? std::to_string(brush_tile_) : "-";
} else if (mode_ == Mode::ENTITY) {
brush_label = "BRUSH:";
brush_value = brush_entity_.empty() ? "-" : brush_entity_;
} else {
const auto LIST = entities.getEntities();
brush_label = "SEL:";
brush_value = (hand_selected_idx_ >= 0 && hand_selected_idx_ < static_cast<int>(LIST.size()))
? LIST[hand_selected_idx_]->getName()
: "-";
}
const std::string COORD = (cursor_col_ >= 0)
? "(" + std::to_string(cursor_col_) + "," + std::to_string(cursor_row_) + ")"
: "(--,--)";
const auto LBL = UiConfig::get().hudLabel();
const auto VAL = UiConfig::get().hudValue();
const int KERN = UiConfig::get().hudFont().kerning;
const int Y = (Map::hud_h - Rendering::Hud::FONT_SIZE_PX) / 2;
int x = 2;
auto draw = [&](const std::string& s, std::uint8_t color) {
hud_font_->writeColored(x, Y, s, color, KERN);
x += hud_font_->length(s, KERN);
};
draw("MODE:", LBL);
draw(" " + mode_str, VAL);
draw(" " + brush_label, LBL);
draw(" " + brush_value, VAL);
draw(" " + COORD, VAL);
draw(" DOOR:", LBL);
draw(" " + std::to_string(countByName(entities, "door")), VAL);
draw(" SARCS:", LBL);
draw(" " + std::to_string(countByName(entities, "sarcophagus")), VAL);
}
void Editor::renderEntityFrame(const Entity& e, std::uint32_t argb) {
const auto R = e.getPixelRect();
auto& screen = Screen::get();
@@ -793,6 +867,13 @@ void Editor::render(const Tilemap& tilemap, const EntityManager& entities) const
}
}
// HUD d'edició: només quan no hi ha picker obert (no té sentit
// tapar el picker amb la franja). Es pinta abans del border per
// que la línia de vora quedi visible per damunt.
if (picker_ == Picker::NONE) {
renderEditorHud(entities);
}
const auto BORDER = EditorConfig::get().borderArgb();
screen.fillRect(0, 0, W, 1, BORDER);
screen.fillRect(0, H - 1, W, 1, BORDER);
+13
View File
@@ -10,6 +10,7 @@
class Entity;
class EntityManager;
class Surface;
class Text;
class Tilemap;
// Mode editor modal del GameScene. Només disponible en Debug — en Release
@@ -117,6 +118,13 @@ class Editor {
// Render del marc d'una entitat: 1 px sobre el seu pixel_rect.
static void renderEntityFrame(const Entity& e, std::uint32_t argb);
// HUD d'edició: franja superior amb mode, brush, cursor i comptadors
// de constraints. Substitueix el HUD del joc mentre l'editor és actiu.
void renderEditorHud(const EntityManager& entities) const;
// Carrega la font 8bithud del cache. Lazy: al primer enter().
void ensureHudFont();
void renderTilePicker(const Tilemap& tilemap) const;
void renderEntityPicker(const Tilemap& tilemap) const;
@@ -159,6 +167,11 @@ class Editor {
std::vector<EditableEntity> editable_entities_;
// Font compartida amb el Notifier/HUD: el surface el carrega Director
// a l'arrencada, ací només prenem la referència del cache. shared_ptr
// perquè `Text` accepta el surface per shared_ptr i així no copiem.
std::shared_ptr<Text> hud_font_;
// Selecció en Mode::HAND. Treballem amb índexs sobre el snapshot de
// `EntityManager::getEntities()` perquè és el que ens dóna l'API
// pública. Després de cada mutació (move/delete) ho recalculem; com