Files
MuditaOS/module-apps/application-desktop/widgets/NotificationsBox.cpp
Wojtek Rzepecki b24f0bca20 [EGD-2501] Add gsm powerdown due to battery
Gsm model power state maintenance based on battery level.
2021-01-15 11:05:22 +01:00

205 lines
7.1 KiB
C++

// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "NotificationsBox.hpp"
#include "application-desktop/data/Style.hpp"
#include "TextFixedSize.hpp"
#include "RichTextParser.hpp"
#include "FontManager.hpp"
using namespace gui;
using namespace style::desktop;
NotificationsBox::NotificationsBox(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
: VBox(parent, x, y, w, h)
{
this->setAlignment(Alignment(gui::Alignment::Horizontal::Center));
this->setPenWidth(style::window::default_border_no_focus_w);
this->setPenFocusWidth(style::window::default_border_no_focus_w);
auto getNextNotification = [this]() -> Item * {
auto focusedItem = getFocusItem();
if (focusedItem == nullptr) {
return nullptr;
}
auto nextItem = focusedItem->getNavigationItem(NavigationDirection::UP);
if (nextItem == nullptr) {
nextItem = focusedItem->getNavigationItem(NavigationDirection::DOWN);
}
return nextItem;
};
auto setNextFocusedItemAfterErase = [this](Item *item) -> bool {
if (item == nullptr) {
setFocus(false);
}
else {
item->clearNavigationItem(NavigationDirection::DOWN);
item->clearNavigationItem(NavigationDirection::UP);
setNavigation();
setFocusItem(item);
}
return true;
};
inputCallback = [this, setNextFocusedItemAfterErase, getNextNotification](Item &, const InputEvent &event) -> bool {
if (event.isShortPress() && event.is(KeyCode::KEY_RF)) {
LOG_DEBUG("Removing single notification");
auto ptr = getFocusItem();
if (ptr == nullptr || focusItem == this) {
return false;
}
auto nextItem = getNextNotification();
ptr->inputCallback(*this, event);
erase(ptr);
return setNextFocusedItemAfterErase(nextItem);
}
return false;
};
}
namespace
{
auto buildImageInactive(const UTF8 &img) -> gui::Image *
{
auto thumbnail = new gui::Image(img);
thumbnail->activeItem = false;
return thumbnail;
}
auto buildNotificationIcon(UTF8 icon) -> gui::Image *
{
auto thumbnail = buildImageInactive(icon);
thumbnail->setMinimumWidth(notifications::IconWidth);
thumbnail->setAlignment(Alignment(gui::Alignment::Horizontal::Right, gui::Alignment::Vertical::Center));
thumbnail->setMargins(
gui::Margins(style::window::default_left_margin, 0, style::window::default_right_margin, 0));
return thumbnail;
}
auto buildNotificationNameLabel(const UTF8 &name, uint32_t width) -> gui::TextFixedSize *
{
auto text = new gui::TextFixedSize(
nullptr, 0, 0, style::desktop::notifications::TextMaxWidth, style::window::label::default_h);
text->setMaximumSize(width, Axis::X);
TextFormat format(FontManager::getInstance().getFont(style::window::font::medium));
text::RichTextParser rtParser;
auto parsedText = rtParser.parse(name, &format);
text->setText(std::move(parsedText));
text->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
text->setPenWidth(style::window::default_border_no_focus_w);
text->setUnderline(false);
text->activeItem = false;
return text;
}
constexpr auto maxNotificationValue = "99+";
auto buildNotificationCountText(const UTF8 &indicator) -> gui::Text *
{
auto number = new gui::Text();
if (indicator.length() > 2) {
number->setText(maxNotificationValue);
}
else {
number->setText(indicator);
}
number->setMinimumWidth(number->getText().length() * notifications::DigitSize);
number->setFont(style::window::font::mediumbold);
number->setPenWidth(style::window::default_border_no_focus_w);
number->setMargins(gui::Margins(0, 0, style::window::default_right_margin, 0));
number->setAlignment(Alignment(gui::Alignment::Horizontal::Right, gui::Alignment::Vertical::Center));
number->activeItem = false;
return number;
}
void setNotificationHboxLayoutProperties(gui::HBox *hbox)
{
hbox->setAlignment(Alignment(gui::Alignment::Vertical::Center));
hbox->setMargins(gui::Margins(0, 0, 0, 10));
hbox->setPenWidth(style::window::default_border_no_focus_w);
hbox->setPenFocusWidth(style::window::default_border_focus_w);
hbox->setEdges(RectangleEdge::Bottom | RectangleEdge::Top);
}
} // namespace
auto NotificationsBox::addNotification(const UTF8 &icon,
const UTF8 &name,
const UTF8 &indicator,
std::function<bool()> showCallback,
std::function<bool()> clearCallback,
std::function<void(bool)> onFocus) -> bool
{
// 1. create hbox for all elements
auto el = new gui::HBox(nullptr, 0, 0, style::window::default_body_width, style::window::label::default_h);
// 2. Add all elements to hbox layout
el->addWidget(buildNotificationIcon(icon));
el->addWidget(buildNotificationNameLabel(name, el->area().w));
el->addWidget(buildImageInactive("dot_12px_hard_alpha_W_G"));
el->addWidget(buildNotificationCountText(indicator));
// 3. Set hbox layout properties
setNotificationHboxLayoutProperties(el);
el->focusChangedCallback = [el, onFocus](Item &) -> bool {
onFocus(el->focus);
return true;
};
el->activatedCallback = [showCallback](Item &) { return showCallback(); };
el->inputCallback = [showCallback, clearCallback, this](Item &, const InputEvent &event) -> bool {
if (event.isShortPress() && event.is(KeyCode::KEY_RF) && clearCallback) {
return clearCallback();
}
return false;
};
this->addWidget(el);
return el->visible;
}
auto NotificationsBox::addNotification(const UTF8 &icon, const UTF8 &name) -> bool
{
auto el = new gui::HBox(this, 0, 0, style::window::default_body_width, style::window::label::default_h);
el->addWidget(buildNotificationIcon(icon));
el->addWidget(buildNotificationNameLabel(name, el->area().w));
setNotificationHboxLayoutProperties(el);
return el->visible;
}
bool NotificationsBox::onInput(const InputEvent &inputEvent)
{
if (inputEvent.isShortPress() && (inputEvent.is(KeyCode::KEY_UP) || inputEvent.is(KeyCode::KEY_DOWN))) {
auto handled = handleNavigation(inputEvent);
if (!handled) {
setFocus(false);
}
return true;
}
return VBox::onInput(inputEvent);
}
bool NotificationsBox::clearAll(const InputEvent &event)
{
while (!children.empty()) {
inputCallback(*this, event);
}
return true;
}
void NotificationsBox::navigateToBottom()
{
setFocusItem(children.back());
}