notificacions funcionals

This commit is contained in:
2026-04-04 18:28:39 +02:00
parent fe8e5d661e
commit b707bdd63b

View File

@@ -11,29 +11,38 @@ namespace Overlay {
static std::unique_ptr<Text> font_; static std::unique_ptr<Text> font_;
// --- Notificacions amb animació --- // --- Aspecte de la notificació ---
static constexpr Uint32 NOTIF_BG_COLOR = 0xFF2E1A1A; // Fons blau fosc (ABGR)
static constexpr Uint32 NOTIF_TEXT_COLOR = 0xFFFFFF00; // Text cyan (ABGR)
static constexpr int NOTIF_PADDING_H = 8; // Padding horitzontal (esquerra/dreta dins la caixa)
static constexpr int NOTIF_PADDING_V = 4; // Padding vertical (dalt/baix dins la caixa)
static constexpr int NOTIF_MARGIN_X = 4; // Offset des de la vora esquerra de la pantalla
static constexpr int NOTIF_MARGIN_Y = 4; // Offset des de la vora superior de la pantalla
// --- Animació ---
static constexpr float SLIDE_SPEED = 4.0F; // Velocitat de l'animació (unitats/segon)
// --- Pantalla ---
static constexpr int SCREEN_W = 320;
static constexpr int SCREEN_H = 200;
// --- Estat de les notificacions ---
enum class Status { RISING, STAY, VANISHING, FINISHED }; enum class Status { RISING, STAY, VANISHING, FINISHED };
struct Notification { struct Notification {
std::string message; std::string message;
Status status{Status::RISING}; Status status{Status::RISING};
float y_offset{0.0F}; // 0 = fora de pantalla, 1 = posició final float anim{0.0F}; // 0 = fora de pantalla, 1 = posició final
float timer{0.0F}; float timer{0.0F};
float duration{2.0F}; float duration{2.0F};
int box_w{0}; // Ample de la caixa (calculat al crear)
int box_h{0}; // Alçada de la caixa (calculat al crear)
}; };
static std::vector<Notification> notifications_; static std::vector<Notification> notifications_;
static Uint32 last_ticks_ = 0; static Uint32 last_ticks_ = 0;
static constexpr float SLIDE_SPEED = 4.0F; // velocitat d'animació (unitats/segon)
static constexpr int BAR_HEIGHT = 12; // alçada de la barra
static constexpr int TEXT_Y_OFFSET = 2; // offset del text dins la barra
static constexpr Uint32 BG_COLOR = 0xFF1A1A2E; // fons blau fosc
static constexpr Uint32 TEXT_COLOR = 0xFF00FFFF; // cyan
static constexpr int SCREEN_W = 320;
static constexpr int SCREEN_H = 200;
void init() { void init() {
font_ = std::make_unique<Text>("fonts/8bithud.fnt", "fonts/8bithud.gif"); font_ = std::make_unique<Text>("fonts/8bithud.fnt", "fonts/8bithud.gif");
last_ticks_ = SDL_GetTicks(); last_ticks_ = SDL_GetTicks();
@@ -44,10 +53,12 @@ namespace Overlay {
notifications_.clear(); notifications_.clear();
} }
static void drawBar(Uint32* pixel_data, int y, int h, Uint32 color) { // Pinta un rectangle sòlid dins els límits de la pantalla
for (int row = y; row < y + h; row++) { static void drawRect(Uint32* pixel_data, int rx, int ry, int rw, int rh, Uint32 color) {
for (int row = ry; row < ry + rh; row++) {
if (row < 0 || row >= SCREEN_H) continue; if (row < 0 || row >= SCREEN_H) continue;
for (int col = 0; col < SCREEN_W; col++) { for (int col = rx; col < rx + rw; col++) {
if (col < 0 || col >= SCREEN_W) continue;
pixel_data[col + row * SCREEN_W] = color; pixel_data[col + row * SCREEN_W] = color;
} }
} }
@@ -65,9 +76,9 @@ namespace Overlay {
for (auto& notif : notifications_) { for (auto& notif : notifications_) {
switch (notif.status) { switch (notif.status) {
case Status::RISING: case Status::RISING:
notif.y_offset += SLIDE_SPEED * dt; notif.anim += SLIDE_SPEED * dt;
if (notif.y_offset >= 1.0F) { if (notif.anim >= 1.0F) {
notif.y_offset = 1.0F; notif.anim = 1.0F;
notif.status = Status::STAY; notif.status = Status::STAY;
notif.timer = 0.0F; notif.timer = 0.0F;
} }
@@ -81,8 +92,8 @@ namespace Overlay {
break; break;
case Status::VANISHING: case Status::VANISHING:
notif.y_offset -= SLIDE_SPEED * dt; notif.anim -= SLIDE_SPEED * dt;
if (notif.y_offset <= 0.0F) { if (notif.anim <= 0.0F) {
notif.status = Status::FINISHED; notif.status = Status::FINISHED;
} }
break; break;
@@ -93,14 +104,17 @@ namespace Overlay {
if (notif.status == Status::FINISHED) continue; if (notif.status == Status::FINISHED) continue;
// Posició: puja des de sota la pantalla // Posició: entra des de l'esquerra
int bar_y = SCREEN_H - static_cast<int>(notif.y_offset * BAR_HEIGHT); int target_x = NOTIF_MARGIN_X;
int target_y = NOTIF_MARGIN_Y;
int box_x = target_x - static_cast<int>((1.0F - notif.anim) * (notif.box_w + NOTIF_MARGIN_X));
int box_y = target_y;
// Pinta fons // Pinta fons de la caixa
drawBar(pixel_data, bar_y, BAR_HEIGHT, BG_COLOR); drawRect(pixel_data, box_x, box_y, notif.box_w, notif.box_h, NOTIF_BG_COLOR);
// Pinta text centrat // Pinta text dins la caixa
font_->drawCentered(pixel_data, bar_y + TEXT_Y_OFFSET, notif.message.c_str(), TEXT_COLOR); font_->draw(pixel_data, box_x + NOTIF_PADDING_H, box_y + NOTIF_PADDING_V, notif.message.c_str(), NOTIF_TEXT_COLOR);
} }
// Elimina les acabades // Elimina les acabades
@@ -111,9 +125,16 @@ namespace Overlay {
} }
void showNotification(const char* text, float duration_seconds) { void showNotification(const char* text, float duration_seconds) {
// Si ja hi ha una notificació, la reemplaça (no apilem) // Reemplaça la notificació anterior
notifications_.clear(); notifications_.clear();
notifications_.push_back({text, Status::RISING, 0.0F, 0.0F, duration_seconds});
Notification notif;
notif.message = text;
notif.duration = duration_seconds;
notif.box_w = font_->width(text) + NOTIF_PADDING_H * 2;
notif.box_h = font_->charHeight() + NOTIF_PADDING_V * 2;
notifications_.push_back(notif);
} }
} // namespace Overlay } // namespace Overlay