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_;
// --- 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 };
struct Notification {
std::string message;
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 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 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() {
font_ = std::make_unique<Text>("fonts/8bithud.fnt", "fonts/8bithud.gif");
last_ticks_ = SDL_GetTicks();
@@ -44,10 +53,12 @@ namespace Overlay {
notifications_.clear();
}
static void drawBar(Uint32* pixel_data, int y, int h, Uint32 color) {
for (int row = y; row < y + h; row++) {
// Pinta un rectangle sòlid dins els límits de la pantalla
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;
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;
}
}
@@ -65,9 +76,9 @@ namespace Overlay {
for (auto& notif : notifications_) {
switch (notif.status) {
case Status::RISING:
notif.y_offset += SLIDE_SPEED * dt;
if (notif.y_offset >= 1.0F) {
notif.y_offset = 1.0F;
notif.anim += SLIDE_SPEED * dt;
if (notif.anim >= 1.0F) {
notif.anim = 1.0F;
notif.status = Status::STAY;
notif.timer = 0.0F;
}
@@ -81,8 +92,8 @@ namespace Overlay {
break;
case Status::VANISHING:
notif.y_offset -= SLIDE_SPEED * dt;
if (notif.y_offset <= 0.0F) {
notif.anim -= SLIDE_SPEED * dt;
if (notif.anim <= 0.0F) {
notif.status = Status::FINISHED;
}
break;
@@ -93,14 +104,17 @@ namespace Overlay {
if (notif.status == Status::FINISHED) continue;
// Posició: puja des de sota la pantalla
int bar_y = SCREEN_H - static_cast<int>(notif.y_offset * BAR_HEIGHT);
// Posició: entra des de l'esquerra
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
drawBar(pixel_data, bar_y, BAR_HEIGHT, BG_COLOR);
// Pinta fons de la caixa
drawRect(pixel_data, box_x, box_y, notif.box_w, notif.box_h, NOTIF_BG_COLOR);
// Pinta text centrat
font_->drawCentered(pixel_data, bar_y + TEXT_Y_OFFSET, notif.message.c_str(), TEXT_COLOR);
// Pinta text dins la caixa
font_->draw(pixel_data, box_x + NOTIF_PADDING_H, box_y + NOTIF_PADDING_V, notif.message.c_str(), NOTIF_TEXT_COLOR);
}
// Elimina les acabades
@@ -111,9 +125,16 @@ namespace Overlay {
}
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_.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