notificacions funcionals
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user