Files
mayhem-firmware/firmware/application/ui_notifications.cpp
T
2026-02-19 14:33:01 +01:00

131 lines
4.0 KiB
C++

#include "ui_notifications.hpp"
#include "ui_navigation.hpp"
extern ui::SystemView* system_view_ptr;
namespace ui {
NotificationEntryView::NotificationEntryView(const NotificationEntry& entry, NotificationView* notifhandler)
: entry_(entry), notifhandler_(notifhandler) {
add_children({&background, &border, &title_text, &message_text, &close_button});
border.set_outline(true);
if (entry_.icon != NOTIF_ICON_NONE) {
add_child(&icon_image);
icon_image.set_parent_rect({UI_POS_X(0) + 2, UI_POS_Y(1), UI_POS_WIDTH(2), UI_POS_HEIGHT(1)});
message_text.set_parent_rect({UI_POS_X(2) + 2, UI_POS_Y(1), UI_POS_WIDTH_REMAINING(6) - 2, UI_POS_HEIGHT(2)});
if (entry_.icon == NOTIF_ICON_MESSAGE) {
icon_image.set_bitmap(&bitmap_icon_pocsag);
}
} else {
message_text.set_parent_rect({UI_POS_X(1), UI_POS_Y(1), UI_POS_WIDTH_REMAINING(5) - 1, UI_POS_HEIGHT(2)});
}
title_text.set_style(Theme::getInstance()->bg_dark);
title_text.set(entry_.title);
message_text.set_style(Theme::getInstance()->bg_darkest);
message_text.set(entry_.message);
close_button.on_select = [this](Button&) {
if (notifhandler_) {
notifhandler_->remove_notification(entry_.id);
}
};
message_text.on_select = [this](Text&) {
if (!entry_.source_app.empty() && notifhandler_) {
notifhandler_->open_notification(entry_.source_app);
// notifhandler_->remove_notification(entry_.id);
}
};
title_text.on_select = message_text.on_select;
}
NotificationView::NotificationView(NavigationView& nav)
: nav_(nav) {
signal_token_tick_second = rtc_time::signal_tick_second += [this]() {
this->on_tick_second();
};
}
NotificationView::~NotificationView() {
rtc_time::signal_tick_second -= signal_token_tick_second;
}
void NotificationView::on_tick_second() {
bool changed = false;
for (size_t i = 0; i < notification_views_.size();) {
if (notification_views_[i]->entry()->increase_time(1000)) {
notification_views_.erase(notification_views_.begin() + i);
changed = true;
} else {
i++;
}
}
if (changed) {
rearrange_notifications();
}
}
void NotificationView::rearrange_notifications() {
size_t count = children().size();
while (children().size() > 0) {
remove_child(children().back());
}
const int entry_height = UI_POS_HEIGHT(3) + 1;
int index = 0;
for (auto& view_ptr : notification_views_) {
view_ptr->set_parent_rect({UI_POS_X(0),
(Coord)(UI_POS_Y(0) + (index * entry_height)),
UI_POS_MAXWIDTH,
entry_height});
add_child(view_ptr.get());
index++;
}
set_parent_rect({UI_POS_X(0), UI_POS_Y(0), UI_POS_MAXWIDTH, (Coord)(notification_views_.size() * entry_height)});
set_dirty();
if (count != children().size()) {
// refresh screen!!!
system_view_ptr->set_dirty();
}
}
void NotificationView::add_notification(NotificationEntry& entry) {
if (notification_views_.size() >= max_notifications) {
notification_views_.erase(notification_views_.begin());
}
entry.id = ++curr_not_id;
notification_views_.push_back(std::make_unique<NotificationEntryView>(entry, this));
rearrange_notifications();
}
void NotificationView::remove_notification(uint16_t id) {
bool found = false;
size_t found_index = 0;
for (size_t i = 0; i < notification_views_.size(); i++) {
if (notification_views_[i]->id() == id) {
found = true;
found_index = i;
break;
}
}
if (found) {
notification_views_.erase(notification_views_.begin() + found_index);
rearrange_notifications();
}
}
void NotificationView::open_notification(std::string app_name) {
if (app_name.empty()) return;
nav_.StartAppByName(app_name.c_str());
}
} // namespace ui