Notifications (#3002)

This commit is contained in:
Totoo
2026-02-19 14:33:01 +01:00
committed by GitHub
parent 77f747aab2
commit 6498f5a1b2
27 changed files with 424 additions and 70 deletions
+30
View File
@@ -154,6 +154,7 @@ class Message {
MorseTXkey = 96,
StreamTXConfiguration = 97,
RTTYData = 98,
NotificationData = 99,
MAX
};
@@ -1793,4 +1794,33 @@ class RTTYDataMessage : public Message {
static constexpr uint16_t max_len = 490;
};
class NotificationDataMessage : public Message {
public:
constexpr NotificationDataMessage(const char* source_app, const char* title, const char* message, uint8_t icon = 0, uint16_t timeout = 10000)
: Message{ID::NotificationData},
icon(icon),
timeout(timeout) {
if (source_app) {
size_t len = std::min(strlen(source_app), (size_t)19);
memcpy(this->source_app, source_app, len);
this->source_app[len] = '\0';
}
if (title) {
size_t len = std::min(strlen(title), (size_t)49);
memcpy(this->title, title, len);
this->title[len] = '\0';
}
if (message) {
size_t len = std::min(strlen(message), (size_t)299);
memcpy(this->message, message, len);
this->message[len] = '\0';
}
}
char source_app[20]{0}; // source application name, null-terminated, max 19 chars + null
char title[50]{0}; // title, null-terminated, max 49 chars + null
char message[300]{0}; // message, null-terminated, max 299 chars + null
uint8_t icon = 0;
uint16_t timeout = 10000;
};
#endif /*__MESSAGE_H__*/
+27 -10
View File
@@ -397,18 +397,35 @@ void Text::getWidgetName(std::string& result) {
void Text::paint(Painter& painter) {
const auto rect = screen_rect();
auto s = has_focus() ? style().invert() : style();
auto max_len = (unsigned)rect.width() / s.font.char_width();
auto text_view = std::string_view{text};
painter.fill_rectangle(rect, s.background);
const int char_width = s.font.char_width();
const int line_height = s.font.line_height();
if (char_width == 0 || line_height == 0) return;
const size_t chars_per_line = rect.width() / char_width;
if (chars_per_line == 0) return;
size_t lines_capacity = rect.height() / line_height;
if (lines_capacity == 0) lines_capacity = 1; // at least one line, even if it overflows vertically
auto text_view = std::string_view{text};
size_t current_offset = 0;
for (size_t line_idx = 0; line_idx < lines_capacity; ++line_idx) {
if (current_offset >= text_view.length()) break;
size_t chunk_len = std::min(chars_per_line, text_view.length() - current_offset);
painter.draw_string(
rect.location() + Point(0, line_idx * line_height),
s,
text_view.substr(current_offset, chunk_len));
current_offset += chunk_len;
}
}
if (text_view.length() > max_len)
text_view = text_view.substr(0, max_len);
painter.draw_string(
rect.location(),
s,
text_view);
bool Text::on_touch(const TouchEvent event) {
if (event.type == TouchEvent::Type::Start) {
if (on_select) {
on_select(*this);
return true;
}
}
return false;
}
/* Labels ****************************************************************/
+3
View File
@@ -209,6 +209,7 @@ class Rectangle : public Widget {
class Text : public Widget {
public:
std::function<void(Text&)> on_select{};
Text()
: text{""} {
}
@@ -223,6 +224,8 @@ class Text : public Widget {
void getAccessibilityText(std::string& result) override;
void getWidgetName(std::string& result) override;
bool on_touch(const TouchEvent event) override;
protected:
// NB: Don't truncate this string. The UI will only render
// as many characters as will fit in its rectange.