mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-09-04 05:49:01 +00:00
Notifications (#3002)
This commit is contained in:
@@ -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__*/
|
||||
|
||||
@@ -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 ****************************************************************/
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user