M changelog.md => changelog.md +1 -0
@@ 22,6 22,7 @@
### Fixed
+* Fix menu notification dot
* Fix absent notifications
* Fix newly added contact recognized as a duplicate of temporary contact.
* Fix default borderCallback navigation in GridLayout.
M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +5 -2
@@ 203,7 203,11 @@ namespace app
msg->interface == db::Interface::Name::SMS) &&
msg->type != db::Query::Type::Read) {
requestNotReadNotifications();
- windowsFactory.build(this, app::window::name::desktop_menu);
+ if (auto menuWindow = dynamic_cast<gui::MenuWindow *>(getWindow(app::window::name::desktop_menu));
+ menuWindow != nullptr) {
+ menuWindow->refresh();
+ return true;
+ }
}
return false;
@@ 266,7 270,6 @@ namespace app
{
notifications.notRead.Calls = DBServiceAPI::CalllogGetCount(this, EntryState::UNREAD);
notifications.notRead.SMS = DBServiceAPI::ThreadGetCount(this, EntryState::UNREAD);
-
return true;
}
M => +71 -20
@@ 24,16 24,33 @@ namespace style::design
inline const auto notify_dot_x = 80;
inline const auto notify_dot_y = (64 - 50) / 2;
inline const auto grid_offset = 20;
}; // namespace style::design
} // namespace style::design
namespace
{
static constexpr auto deepRefreshDot = "dot_12px_hard_alpha_W_G";
static constexpr auto fastRefreshDot = "dot_12px_hard_alpha_W_M";
gui::Image *buildThumbnail(gui::RefreshModes mode)
{
gui::Image *thumbnail =
new gui::Image(mode == gui::RefreshModes::GUI_REFRESH_DEEP ? deepRefreshDot : fastRefreshDot);
thumbnail->setPosition(style::design::notify_dot_x, style::design::notify_dot_y);
return thumbnail;
}
} // namespace
namespace gui
{
inline const auto APP_SETTINGS_NEW = "ApplicationSettingsNew";
Tile::Tile(UTF8 icon, std::string title, std::function<bool(Item &)> activatedCallback, unsigned int notifications)
Tile::Tile(UTF8 icon,
std::string title,
std::function<bool(Item &)> activatedCallback,
std::function<bool()> hasNotificationsCallback)
{
setSize(style::design::tile_w, style::design::tile_h);
auto *it = new gui::Item();
auto it = new gui::Item();
it->setSize(style::design::tile_w, style::design::tile_h - 2 * style::design::tile_margin);
it->setPosition(area().x, area().y + style::design::tile_margin);
@@ 48,10 65,21 @@ namespace gui
desc->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Bottom));
desc->setText(utils::localize.get(title));
if (notifications > 0) {
auto thumbnail = new gui::Image("dot_12px_hard_alpha_W_G");
thumbnail->setPosition(style::design::notify_dot_x, style::design::notify_dot_y);
it->addWidget(thumbnail);
if (hasNotificationsCallback != nullptr) {
onNotificationsChangeCallback =
[this, it, hasNotifications = std::move(hasNotificationsCallback)](gui::RefreshModes mode) -> bool {
if (hasNotifications() && notificationThumbnail == nullptr) {
notificationThumbnail = buildThumbnail(mode);
it->addWidget(notificationThumbnail);
return true;
}
else if (!hasNotifications() && notificationThumbnail != nullptr) {
it->erase(notificationThumbnail);
notificationThumbnail = nullptr;
}
return false;
};
onNotificationsChangeCallback(gui::RefreshModes::GUI_REFRESH_DEEP);
}
this->activatedCallback = activatedCallback;
@@ 59,9 87,16 @@ namespace gui
this->setPenFocusWidth(style::window::default_border_focus_w);
this->setEdges(RectangleEdge::Top | RectangleEdge::Bottom);
addWidget(it);
};
}
bool Tile::onNotificationsChange(gui::RefreshModes mode)
{
if (onNotificationsChangeCallback != nullptr) {
return onNotificationsChangeCallback(mode);
}
return false;
}
MenuPage::MenuPage(gui::Item *parent, UTF8 title, std::vector<Tile *> tiles) : title(title)
MenuPage::MenuPage(gui::Item *parent, UTF8 title, std::vector<Tile *> tiles) : title(std::move(title))
{
if (parent) {
parent->addWidget(this);
@@ 83,6 118,17 @@ namespace gui
}
}
bool MenuPage::refresh(gui::RefreshModes mode)
{
bool visibleStateChanged = false;
for (auto child : children) {
if (auto tile = dynamic_cast<Tile *>(child); tile != nullptr) {
visibleStateChanged |= tile->onNotificationsChange(mode);
}
}
return visibleStateChanged;
}
MenuWindow::MenuWindow(app::Application *app) : AppWindow(app, app::window::name::desktop_menu)
{
buildInterface();
@@ 150,7 196,8 @@ namespace gui
app::manager::actions::Launch,
std::make_unique<app::ApplicationLaunchData>("ApplicationCallLog"));
},
app->notifications.notRead.Calls},
[=]() { return app->notifications.notRead.Calls > 0; }},
new gui::Tile("menu_contacts_W_G",
"app_desktop_menu_contacts",
[=](gui::Item &item) {
@@ 168,7 215,7 @@ namespace gui
app::manager::actions::Launch,
std::make_unique<app::ApplicationLaunchData>("ApplicationMessages"));
},
app->notifications.notRead.SMS},
[=]() { return app->notifications.notRead.SMS > 0; }},
new gui::Tile{"menu_music_player_W_G",
"app_desktop_menu_music",
[=](gui::Item &item) {
@@ 185,15 232,12 @@ namespace gui
app::manager::actions::Launch,
std::make_unique<app::ApplicationLaunchData>("ApplicationMeditation"));
}},
new gui::Tile{"menu_settings_W_G",
"app_desktop_menu_settings_new",
[=](gui::Item &item) {
new gui::Tile{"menu_settings_W_G", "app_desktop_menu_settings_new", [=](gui::Item &item) {
return app::manager::Controller::sendAction(
application,
app::manager::actions::Launch,
std::make_unique<app::ApplicationLaunchData>(APP_SETTINGS_NEW));
}},
});
}}});
toolsMenu = new MenuPage(
this,
@@ 254,9 298,6 @@ namespace gui
toolsMenu = nullptr;
}
void MenuWindow::onBeforeShow(ShowMode mode, SwitchData *data)
{}
bool MenuWindow::onInput(const InputEvent &inputEvent)
{
if ((inputEvent.state == InputEvent::State::keyReleasedShort) && (inputEvent.keyCode == KeyCode::KEY_RF) &&
@@ 278,7 319,17 @@ namespace gui
setTitle(page->title);
setFocusItem(page);
application->refreshWindow(gui::RefreshModes::GUI_REFRESH_DEEP);
}
void MenuWindow::refresh()
{
if (application->getCurrentWindow() == this) {
if (mainMenu->refresh(RefreshModes::GUI_REFRESH_FAST)) {
application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);
}
}
else {
mainMenu->refresh(RefreshModes::GUI_REFRESH_DEEP);
}
}
} /* namespace gui */
M => +9 -2
@@ 22,7 22,13 @@ namespace gui
Tile(UTF8 icon,
std::string title,
std::function<bool(Item &)> activatedCallback,
unsigned int notifications = 0);
std::function<bool()> hasNotificationsCallback = nullptr);
bool onNotificationsChange(gui::RefreshModes);
private:
std::function<bool(gui::RefreshModes)> onNotificationsChangeCallback = nullptr;
gui::Image *notificationThumbnail = nullptr;
};
class MenuPage : public gui::GridLayout
@@ 36,6 42,7 @@ namespace gui
MenuPage(gui::Item *parent, UTF8 title, std::vector<Tile *> tiles);
/// set child which should be selected on start of desktop
void setFirstTimeSelection();
bool refresh(gui::RefreshModes mode);
};
class MenuWindow : public AppWindow
@@ 48,7 55,6 @@ namespace gui
public:
MenuWindow(app::Application *app);
void onBeforeShow(ShowMode mode, SwitchData *data) override;
bool onInput(const InputEvent &inputEvent) override;
void rebuild() override;
@@ 56,6 62,7 @@ namespace gui
void destroyInterface() override;
void switchMenu(MenuPage *page);
void refresh();
private:
void invalidate() noexcept;
M module-gui/gui/widgets/Item.cpp => module-gui/gui/widgets/Item.cpp +0 -5
@@ 515,11 515,6 @@ namespace gui
return false;
}
- bool Item::onContent()
- {
- return false;
- }
-
auto Item::onTimer(Timer &timer) -> bool
{
if (timerCallback != nullptr) {
M module-gui/gui/widgets/Item.hpp => module-gui/gui/widgets/Item.hpp +0 -7
@@ 139,9 139,6 @@ namespace gui
/// @param `this` item
/// @param `InputEvent`
std::function<bool(Item &, const InputEvent &inputEvent)> inputCallback;
- /// callback when element insides are changed
- /// @param `this` item
- std::function<bool(Item &)> contentCallback;
/// callback when timer is called on Item and onTimer is executed
/// @param `this` item
/// @param `timer` which triggered this callback
@@ 183,10 180,6 @@ namespace gui
/// calls: none, inconsistent api
/// @note TODO should be fixed so that api would be consistent
virtual bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim);
- /// (should be) called each time content in item was changed, added for gui::Text widget
- /// calls: none, inconsistent behaviour
- /// @note TODO should be fixed so that api would be consistent
- virtual bool onContent();
/// called on Timer event in application, triggeres timerCallback
/// @param timer timer element which triggered this action
virtual bool onTimer(Timer &timer);
M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +3 -0
@@ 1044,6 1044,9 @@ sys::MessagePointer ServiceCellular::DataReceivedHandler(sys::DataMessage *msgl,
if (auto response = dynamic_cast<db::query::SMSSearchByTypeResult *>(result.get())) {
responseHandled = handle(response);
}
+ else if (result->hasListener()) {
+ responseHandled = result->handle();
+ }
}
if (responseHandled) {
return std::make_shared<sys::ResponseMessage>();