M changelog.md => changelog.md +1 -0
@@ 21,6 21,7 @@
* `[desktop][messages]` Fixed notifications display and navigation
* `[cellular]` Fixed 32 bit UCS2 codes handling.
* `[call]` Fixed incorrect start of call duration timer
+* `[GUI]` minor refresh race fixed
### Other
M module-apps/Application.cpp => module-apps/Application.cpp +38 -50
@@ 74,6 74,10 @@ namespace app
longPressTimer = std::make_unique<sys::Timer>("LongPress", this, key_timer_ms);
longPressTimer->connect([&](sys::Timer &) { longPressTimerCallback(); });
+
+ connect(typeid(AppRefreshMessage), [this](sys::DataMessage *msg, sys::ResponseMessage *) -> sys::Message_t {
+ return handleAppRefresh(msg);
+ });
}
Application::~Application() = default;
@@ 108,43 112,32 @@ namespace app
void Application::render(gui::RefreshModes mode)
{
- if (getCurrentWindow() == nullptr) {
+ if (windowsStack.isEmpty()) {
LOG_ERROR("Current window is not defined");
return;
}
- LOG_DEBUG("Rendering %s", getCurrentWindow()->getName().c_str());
-
// send drawing commands only when if application is in active and visible.
if (state == State::ACTIVE_FORGROUND) {
- auto currwin = getCurrentWindow();
+ auto window = getCurrentWindow();
if (Store::Battery::get().state == Store::Battery::State::Charging) {
- currwin->batteryCharging(true);
+ window->batteryCharging(true);
}
else {
- currwin->updateBatteryLevel(Store::Battery::get().level);
+ window->updateBatteryLevel(Store::Battery::get().level);
}
- currwin->setSIM();
- currwin->updateSignalStrength();
- currwin->updateNetworkAccessTechnology();
-
- std::list<gui::DrawCommand *> commandsList = currwin->buildDrawList();
+ window->setSIM();
+ window->updateSignalStrength();
+ window->updateNetworkAccessTechnology();
+ auto message = std::make_shared<sgui::DrawMessage>(window->buildDrawList(), mode);
if (shutdownInProgress) {
- auto msg =
- std::make_shared<sgui::DrawMessage>(commandsList, mode, sgui::DrawMessage::DrawCommand::SHUTDOWN);
- sys::Bus::SendUnicast(msg, "ServiceGUI", this);
+ message->setCommandType(sgui::DrawMessage::Type::SHUTDOWN);
}
else if (suspendInProgress) {
- auto msg =
- std::make_shared<sgui::DrawMessage>(commandsList, mode, sgui::DrawMessage::DrawCommand::SUSPEND);
- sys::Bus::SendUnicast(msg, "ServiceGUI", this);
- }
- else {
- auto msg =
- std::make_shared<sgui::DrawMessage>(commandsList, mode, sgui::DrawMessage::DrawCommand::NORMAL);
- sys::Bus::SendUnicast(msg, "ServiceGUI", this);
+ message->setCommandType(sgui::DrawMessage::Type::SUSPEND);
}
+ sys::Bus::SendUnicast(message, "ServiceGUI", this);
}
if (suspendInProgress)
@@ 197,8 190,10 @@ namespace app
void Application::refreshWindow(gui::RefreshModes mode)
{
- auto msg = std::make_shared<AppRefreshMessage>(mode);
- sys::Bus::SendUnicast(msg, this->GetName(), this);
+ if (not windowsStack.isEmpty()) {
+ auto msg = std::make_shared<AppRefreshMessage>(mode, getCurrentWindow()->getName());
+ sys::Bus::SendUnicast(msg, this->GetName(), this);
+ }
}
sys::Message_t Application::DataReceivedHandler(sys::DataMessage *msgl)
@@ 239,9 234,6 @@ namespace app
else if (msgl->messageType == MessageType::AppRebuild) {
return handleAppRebuild(msg);
}
- else if (msgl->messageType == MessageType::AppRefresh) {
- return handleAppRefresh(msgl);
- }
else if (msgl->messageType == MessageType::AppFocusLost) {
return handleAppFocusLost(msgl);
}
@@ 282,7 274,7 @@ namespace app
else if (msg->getEvent().state == gui::InputEvent::State::keyReleasedShort) {
longPressTimer->stop();
}
- if (getCurrentWindow() != nullptr && getCurrentWindow()->onInput(msg->getEvent())) {
+ if (not windowsStack.isEmpty() && getCurrentWindow()->onInput(msg->getEvent())) {
refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
}
return msgHandled();
@@ 397,25 389,23 @@ namespace app
if (switchData && switchData->ignoreCurrentWindowOnStack) {
popToWindow(getPrevWindow());
}
- getCurrentWindow()->onClose();
+ if (not windowsStack.isEmpty()) {
+ getCurrentWindow()->onClose();
+ }
setActiveWindow(msg->getWindowName());
LOG_DEBUG("Current window: %s vs %s", getCurrentWindow()->getName().c_str(), msg->getWindowName().c_str());
getCurrentWindow()->handleSwitchData(switchData.get());
- // check if this is case where application is returning to the last visible window.
- if ((switchData != nullptr) && (msg->LastSeenWindow)) {}
- else {
- auto ret = dynamic_cast<gui::SwitchSpecialChar *>(switchData.get());
- if (ret != nullptr && switchData != nullptr) {
- auto text = dynamic_cast<gui::Text *>(getCurrentWindow()->getFocusItem());
- if (text != nullptr) {
- text->addText(ret->getDescription());
- refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
- return msgHandled();
- }
+ auto ret = dynamic_cast<gui::SwitchSpecialChar *>(switchData.get());
+ if (ret != nullptr && switchData != nullptr) {
+ auto text = dynamic_cast<gui::Text *>(getCurrentWindow()->getFocusItem());
+ if (text != nullptr) {
+ text->addText(ret->getDescription());
+ refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
+ return msgHandled();
}
- getCurrentWindow()->onBeforeShow(msg->getCommand(), switchData.get());
}
+ getCurrentWindow()->onBeforeShow(msg->getCommand(), switchData.get());
refreshWindow(gui::RefreshModes::GUI_REFRESH_DEEP);
}
else {
@@ 449,6 439,13 @@ namespace app
sys::Message_t Application::handleAppRefresh(sys::DataMessage *msgl)
{
auto *msg = static_cast<AppRefreshMessage *>(msgl);
+ assert(msg);
+ if (windowsStack.isEmpty() || (getCurrentWindow()->getName() != msg->getWindowName())) {
+ LOG_DEBUG("Ignore request for window %s we are on window %s",
+ msg->getWindowName().c_str(),
+ windowsStack.isEmpty() ? "none" : getCurrentWindow()->getName().c_str());
+ return msgNotHandled();
+ }
render(msg->getMode());
return msgHandled();
}
@@ 518,15 515,6 @@ namespace app
sys::Bus::SendUnicast(msg, application, sender);
}
- void Application::messageRefreshApplication(sys::Service *sender,
- std::string application,
- std::string window,
- gui::SwitchData *data)
- {
- auto msg = std::make_shared<AppMessage>(MessageType::AppRefresh);
- sys::Bus::SendUnicast(msg, application, sender);
- }
-
void Application::messageCloseApplication(sys::Service *sender, std::string application)
{
M module-apps/Application.hpp => module-apps/Application.hpp +1 -4
@@ 291,10 291,6 @@ namespace app
std::string application,
std::string window,
std::unique_ptr<gui::SwitchData> data);
- static void messageRefreshApplication(sys::Service *sender,
- std::string application,
- std::string window,
- gui::SwitchData *data = nullptr);
static void messageCloseApplication(sys::Service *sender, std::string application);
static void messageRebuildApplication(sys::Service *sender, std::string application);
static void messageApplicationLostFocus(sys::Service *sender, std::string application);
@@ 328,6 324,7 @@ namespace app
/// @ingrup AppWindowStack
void cleanPrevWindw();
/// getter for current wisible window in application
+ /// if there is none - returns default window
/// @ingrup AppWindowStack
gui::AppWindow *getCurrentWindow();
M module-apps/WindowsStack.hpp => module-apps/WindowsStack.hpp +5 -0
@@ 51,5 51,10 @@ namespace app
auto ret = windows.find(name);
return ret == std::end(windows) ? nullptr : ret->second.get();
}
+
+ [[nodiscard]] auto isEmpty() const noexcept
+ {
+ return stack.size() == 0;
+ }
};
} // namespace app
M module-apps/application-desktop/windows/DesktopMainWindow.cpp => module-apps/application-desktop/windows/DesktopMainWindow.cpp +6 -7
@@ 78,6 78,12 @@ namespace gui
DesktopMainWindow::DesktopMainWindow(app::Application *app) : AppWindow(app, app::window::name::desktop_main_window)
{
buildInterface();
+
+ preBuildDrawListHook = [this](std::list<Command> &cmd) {
+ if (time != nullptr) {
+ time->setText(topBar->getTimeString());
+ }
+ };
}
void DesktopMainWindow::setVisibleState()
@@ 146,7 152,6 @@ namespace gui
if (inputEvent.is(KeyCode::KEY_PND) && (!app->lockHandler.lock.isLocked())) {
app->lockHandler.lock.lock();
setVisibleState();
- application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);
application->setSuspendFlag(true);
return true;
}
@@ 249,12 254,6 @@ namespace gui
return ret;
}
- std::list<DrawCommand *> DesktopMainWindow::buildDrawList()
- {
- time->setText(topBar->getTimeString());
- return gui::AppWindow::buildDrawList();
- }
-
auto DesktopMainWindow::buildNotifications(app::ApplicationDesktop *app) -> bool
{
erase(notifications);
M module-apps/application-desktop/windows/DesktopMainWindow.hpp => module-apps/application-desktop/windows/DesktopMainWindow.hpp +0 -1
@@ 83,7 83,6 @@ namespace gui
void destroyInterface() override;
bool updateTime(const UTF8 &timeStr) override;
bool updateTime(const uint32_t ×tamp, bool mode24H) override;
- std::list<DrawCommand *> buildDrawList() override;
private:
void invalidate() noexcept;
M module-apps/messages/AppMessage.hpp => module-apps/messages/AppMessage.hpp +13 -10
@@ 1,9 1,9 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#ifndef MODULE_APPS_MESSAGES_APPMESSAGE_HPP_
-#define MODULE_APPS_MESSAGES_APPMESSAGE_HPP_
+#pragma once
+#include "Common.hpp"
#include "MessageType.hpp"
#include "Service/Message.hpp"
#include "SwitchData.hpp"
@@ 21,7 21,7 @@ namespace app
{
public:
AppMessage(MessageType messageType) : sys::DataMessage(messageType){};
- virtual ~AppMessage(){};
+ AppMessage() : sys::DataMessage(MessageType::AppMessage){};
};
// this message is used to notify application about switching event. Application will gain or lose focus upon
@@ 80,16 80,21 @@ namespace app
{
protected:
gui::RefreshModes mode;
+ std::string window_name;
public:
- // AppRefreshMessage( const std::string& application, gui::RefreshModes mode ) :
- AppRefreshMessage(gui::RefreshModes mode) : AppMessage(MessageType::AppRefresh), mode{mode} {};
- virtual ~AppRefreshMessage(){};
+ AppRefreshMessage(gui::RefreshModes mode, std::string window_name)
+ : mode{mode}, window_name(std::move(window_name)){};
- const gui::RefreshModes &getMode()
+ [[nodiscard]] const gui::RefreshModes &getMode() const
{
return mode;
- };
+ }
+
+ [[nodiscard]] const std::string &getWindowName() const
+ {
+ return window_name;
+ }
};
class AppSwitchWindowMessage : public AppMessage
@@ 101,7 106,6 @@ namespace app
std::unique_ptr<gui::SwitchData> data;
public:
- bool LastSeenWindow = false;
AppSwitchWindowMessage() = delete;
AppSwitchWindowMessage(const std::string &window,
@@ 170,4 174,3 @@ namespace app
{}
};
}; // namespace app
-#endif /* MODULE_APPS_MESSAGES_APPMESSAGE_HPP_ */
M module-apps/windows/AppWindow.cpp => module-apps/windows/AppWindow.cpp +0 -5
@@ 118,11 118,6 @@ namespace gui
}
}
- std::list<DrawCommand *> AppWindow::buildDrawList()
- {
- return Window::buildDrawList();
- }
-
bool AppWindow::onDatabaseMessage(sys::Message *msg)
{
return false;
M module-apps/windows/AppWindow.hpp => module-apps/windows/AppWindow.hpp +0 -1
@@ 77,7 77,6 @@ namespace gui
void buildInterface() override;
void destroyInterface() override;
bool onInput(const InputEvent &inputEvent) override;
- std::list<DrawCommand *> buildDrawList() override;
/// Setting bottom bar temporary text
/// @param text - bottomBar text
/// @param overwriteOthers - set or not other bottomBar texts to "" (default true)
M module-gui/gui/Common.hpp => module-gui/gui/Common.hpp +11 -0
@@ 143,3 143,14 @@ namespace gui
void setTimeFunction(timeSecondsFunctionPtr fptr);
} // namespace gui
+
+inline const char *c_str(gui::RefreshModes refresh)
+{
+ switch (refresh) {
+ case gui::RefreshModes::GUI_REFRESH_FAST:
+ return "GUI_REFRESH_FAST";
+ case gui::RefreshModes::GUI_REFRESH_DEEP:
+ return "GUI_REFRESH_DEEP";
+ }
+ return "";
+}
M module-gui/gui/core/DrawCommand.hpp => module-gui/gui/core/DrawCommand.hpp +0 -9
@@ 15,9 15,6 @@
namespace gui
{
- /**
- * @brief IDs of the drawing commands
- */
enum class DrawCommandID
{
GUI_DRAW_UNDEFINED = 0,
@@ 50,9 47,6 @@ namespace gui
virtual ~DrawCommand(){};
};
- /**
- * @brief Draw command for rendering.
- */
class CommandRender : public DrawCommand
{
public:
@@ 63,9 57,6 @@ namespace gui
};
};
- /**
- * @brief Draw command for line.
- */
class CommandLine : public DrawCommand
{
public:
A module-gui/gui/core/DrawCommandForward.hpp => module-gui/gui/core/DrawCommandForward.hpp +13 -0
@@ 0,0 1,13 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <memory>
+
+namespace gui
+{
+ class DrawCommand;
+
+ using Command = std::unique_ptr<DrawCommand>;
+} // namespace gui
M module-gui/gui/core/RawFont.cpp => module-gui/gui/core/RawFont.cpp +4 -3
@@ 12,7 12,6 @@
#include "utf8/UTF8.hpp" // for UTF8
#include <cstring> // for memcpy
#include <utility> // for pair
-#include <vector> // for vector
namespace gui
{
@@ 307,7 306,8 @@ namespace gui
commandRect->penWidth = unsupported->xoffset;
auto renderCtx = std::make_unique<Context>(unsupported->width, unsupported->height);
- std::vector<gui::DrawCommand *> commands = {commandRect.get()};
+ std::list<Command> commands;
+ commands.emplace_back(std::move(commandRect));
Renderer().render(renderCtx.get(), commands);
auto size = unsupported->width * unsupported->height;
@@ 317,7 317,8 @@ namespace gui
void RawFont::setFallbackFont(RawFont *fallback)
{
- if (fallback != this)
+ if (fallback != this) {
fallback_font = fallback;
+ }
}
} /* namespace gui */
M module-gui/gui/core/Renderer.cpp => module-gui/gui/core/Renderer.cpp +14 -8
@@ 288,30 288,36 @@ namespace gui
delete drawCtx;
}
- void Renderer::render(Context *ctx, std::vector<DrawCommand *> &commands)
+ void Renderer::render(Context *ctx, std::list<Command> &commands)
{
- for (auto cmd : commands) {
+ if (ctx == nullptr) {
+ return;
+ }
+ for (auto &cmd : commands) {
+ if (cmd == nullptr) {
+ continue;
+ }
switch (cmd->id) {
case DrawCommandID::GUI_DRAW_CLEAR:
ctx->fill(15);
break;
case DrawCommandID::GUI_DRAW_LINE:
- drawLine(ctx, static_cast<CommandLine *>(cmd));
+ drawLine(ctx, static_cast<CommandLine *>(cmd.get()));
break;
case DrawCommandID::GUI_DRAW_RECT:
- drawRectangle(ctx, static_cast<CommandRectangle *>(cmd));
+ drawRectangle(ctx, static_cast<CommandRectangle *>(cmd.get()));
break;
case DrawCommandID::GUI_DRAW_ARC:
- drawArc(ctx, static_cast<CommandArc *>(cmd));
+ drawArc(ctx, static_cast<CommandArc *>(cmd.get()));
break;
case DrawCommandID::GUI_DRAW_CIRCLE:
- drawCircle(ctx, static_cast<CommandCircle *>(cmd));
+ drawCircle(ctx, static_cast<CommandCircle *>(cmd.get()));
break;
case DrawCommandID::GUI_DRAW_TEXT:
- drawText(ctx, static_cast<CommandText *>(cmd));
+ drawText(ctx, static_cast<CommandText *>(cmd.get()));
break;
case DrawCommandID::GUI_DRAW_IMAGE:
- drawImage(ctx, static_cast<CommandImage *>(cmd));
+ drawImage(ctx, static_cast<CommandImage *>(cmd.get()));
break;
default:
break;
M module-gui/gui/core/Renderer.hpp => module-gui/gui/core/Renderer.hpp +3 -2
@@ 3,12 3,13 @@
#pragma once
-#include <vector>
+#include <list>
#include <module-utils/math/Math.hpp>
#include "DrawCommand.hpp"
#include "Context.hpp"
+#include "DrawCommandForward.hpp"
namespace gui
{
@@ 49,7 50,7 @@ namespace gui
public:
virtual ~Renderer() = default;
- void render(Context *ctx, std::vector<DrawCommand *> &commands);
+ void render(Context *ctx, std::list<Command> &commands);
};
} /* namespace gui */
M module-gui/gui/widgets/Arc.cpp => module-gui/gui/widgets/Arc.cpp +3 -12
@@ 104,23 104,14 @@ namespace gui
return start;
}
- std::list<DrawCommand *> Arc::buildDrawList()
+ void Arc::buildDrawListImplementation(std::list<Command> &commands)
{
- if (!visible) {
- return {};
- }
-
- auto arc = new CommandArc(center, radius, start, sweep, focus ? focusPenWidth : penWidth, color);
+ auto arc = std::make_unique<CommandArc>(center, radius, start, sweep, focus ? focusPenWidth : penWidth, color);
arc->areaX = widgetArea.x;
arc->areaY = widgetArea.y;
arc->areaW = widgetArea.w;
arc->areaH = widgetArea.h;
- std::list<DrawCommand *> commands;
- commands.push_back(arc);
-
- auto childrenCommands = Item::buildChildrenDrawList();
- commands.splice(commands.end(), childrenCommands);
- return commands;
+ commands.emplace_back(std::move(arc));
}
} // namespace gui
M module-gui/gui/widgets/Arc.hpp => module-gui/gui/widgets/Arc.hpp +1 -1
@@ 47,7 47,7 @@ namespace gui
trigonometry::Degrees getSweepAngle() const noexcept;
trigonometry::Degrees getStartAngle() const noexcept;
- std::list<DrawCommand *> buildDrawList() override;
+ void buildDrawListImplementation(std::list<Command> &commands) override;
protected:
Arc(Item *parent,
M module-gui/gui/widgets/BottomBar.hpp => module-gui/gui/widgets/BottomBar.hpp +1 -2
@@ 83,8 83,7 @@ namespace gui
void setFont(Side side, const UTF8 &fontName);
- // virtual methods from Item
- bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim);
+ bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) override;
};
} /* namespace gui */
M module-gui/gui/widgets/BoxLayout.cpp => module-gui/gui/widgets/BoxLayout.cpp +0 -6
@@ 100,12 100,6 @@ namespace gui
Item::erase();
}
- std::list<DrawCommand *> BoxLayout::buildDrawList()
- {
- auto el = Rect::buildDrawList();
- return el;
- }
-
void BoxLayout::setVisible(bool value, bool previous)
{
visible = value; // maybe use parent setVisible(...)? would be better but which one?
M module-gui/gui/widgets/BoxLayout.hpp => module-gui/gui/widgets/BoxLayout.hpp +0 -1
@@ 97,7 97,6 @@ namespace gui
bool removeWidget(Item *item) override;
bool erase(Item *item) override;
void erase() override;
- std::list<DrawCommand *> buildDrawList() override;
/// add item if it will fit in box, return true on success
/// axis sets direction to define space left in container
template <Axis axis> void addWidget(Item *item);
M module-gui/gui/widgets/CMakeLists.txt => module-gui/gui/widgets/CMakeLists.txt +0 -1
@@ 21,7 21,6 @@ target_sources( ${PROJECT_NAME}
"${CMAKE_CURRENT_LIST_DIR}/BoxLayout.cpp"
"${CMAKE_CURRENT_LIST_DIR}/BoxLayoutSizeStore.cpp"
"${CMAKE_CURRENT_LIST_DIR}/PageLayout.cpp"
- "${CMAKE_CURRENT_LIST_DIR}/Layout.cpp"
"${CMAKE_CURRENT_LIST_DIR}/TopBar.cpp"
"${CMAKE_CURRENT_LIST_DIR}/TopBar/SIM.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Text.cpp"
M module-gui/gui/widgets/CheckBox.hpp => module-gui/gui/widgets/CheckBox.hpp +0 -1
@@ 26,7 26,6 @@ namespace gui
std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr,
std::function<void()> bottomBarRestoreFromTemporaryMode = nullptr,
bool textOnLeft = true);
- virtual ~CheckBox() override = default;
void setImageVisible(bool state);
bool isChecked();
M module-gui/gui/widgets/Circle.cpp => module-gui/gui/widgets/Circle.cpp +3 -12
@@ 75,24 75,15 @@ namespace gui
isFilled{_filled}, fillColor{_fillColor}, focusBorderColor{_focusBorderColor}
{}
- std::list<DrawCommand *> Circle::buildDrawList()
+ void Circle::buildDrawListImplementation(std::list<Command> &commands)
{
- if (!visible) {
- return {};
- }
-
- auto circle = new CommandCircle(
+ auto circle = std::make_unique<CommandCircle>(
center, radius, focus ? focusPenWidth : penWidth, focus ? focusBorderColor : color, isFilled, fillColor);
circle->areaX = widgetArea.x;
circle->areaY = widgetArea.y;
circle->areaW = widgetArea.w;
circle->areaH = widgetArea.h;
- std::list<DrawCommand *> commands;
- commands.push_back(circle);
-
- auto childrenCommands = Item::buildChildrenDrawList();
- commands.splice(commands.end(), childrenCommands);
- return commands;
+ commands.emplace_back(std::move(circle));
}
} // namespace gui
M module-gui/gui/widgets/Circle.hpp => module-gui/gui/widgets/Circle.hpp +1 -2
@@ 5,7 5,6 @@
#include <list>
#include <cstdint>
-
#include "Arc.hpp"
#include "Common.hpp"
#include "Style.hpp"
@@ 41,7 40,7 @@ namespace gui
Circle(Item *parent, const Circle::ShapeParams ¶ms);
- std::list<DrawCommand *> buildDrawList() override;
+ void buildDrawListImplementation(std::list<Command> &commands) override;
private:
Circle(Item *parent,
M module-gui/gui/widgets/GridLayout.hpp => module-gui/gui/widgets/GridLayout.hpp +0 -1
@@ 26,7 26,6 @@ namespace gui
{}
GridLayout() : GridLayout(0, 0, 0, 0, {0, 0})
{}
- ~GridLayout() override = default;
/// when reached top -> start from bottom. When reached left, start from right.
bool navigationRotate = true;
void resizeItems() override;
M module-gui/gui/widgets/Image.cpp => module-gui/gui/widgets/Image.cpp +3 -20
@@ 50,29 50,14 @@ namespace gui
}
}
- std::list<DrawCommand *> Image::buildDrawList()
+ void Image::buildDrawListImplementation(std::list<Command> &commands)
{
-
- std::list<DrawCommand *> commands;
-
- // check if widget is visible
- if (visible == false)
- return commands;
-
- // get children draw commands
- std::list<DrawCommand *> childrenCommands = Item::buildDrawList();
- if (!childrenCommands.empty())
- commands.merge(childrenCommands);
-
- // set local draw commands
- CommandImage *img = new CommandImage{};
-
+ auto img = std::make_unique<CommandImage>();
// image
img->x = drawArea.x;
img->y = drawArea.y;
img->w = drawArea.w;
img->h = drawArea.h;
-
// cmd part
img->areaX = img->x;
img->areaY = img->y;
@@ 81,9 66,7 @@ namespace gui
img->imageID = this->imageMap->getID();
- commands.push_back(img);
-
- return commands;
+ commands.emplace_back(std::move(img));
}
} /* namespace gui */
M module-gui/gui/widgets/Image.hpp => module-gui/gui/widgets/Image.hpp +2 -5
@@ 29,14 29,11 @@ namespace gui
Image(Item *parent, uint32_t x, uint32_t y, const UTF8 imgName = UTF8{""})
: Image(parent, x, y, 0u, 0u, imgName)
{}
- virtual ~Image() = default;
- /// set image with id
+
bool set(int id);
- /// set image with string name
void set(const UTF8 &name);
- // virtual methods from Item
- std::list<DrawCommand *> buildDrawList();
+ void buildDrawListImplementation(std::list<Command> &commands) override;
};
} /* namespace gui */
M module-gui/gui/widgets/Item.cpp => module-gui/gui/widgets/Item.cpp +16 -10
@@ 10,11 10,7 @@
#include <algorithm> // for find
#include <list> // for list<>::iterator, list, operator!=, _List...
#include <memory>
-
-namespace gui
-{
- class DrawCommand;
-}
+#include <DrawCommand.hpp>
namespace gui
{
@@ 107,21 103,31 @@ namespace gui
visible = value;
}
- std::list<DrawCommand *> Item::buildDrawList()
+ std::list<Command> Item::buildDrawList()
{
- return buildChildrenDrawList();
+ if (not visible) {
+ return {};
+ }
+ auto commands = std::list<Command>();
+ if (preBuildDrawListHook != nullptr) {
+ preBuildDrawListHook(commands);
+ }
+ buildDrawListImplementation(commands);
+ buildChildrenDrawList(commands);
+ if (postBuildDrawListHook != nullptr) {
+ postBuildDrawListHook(commands);
+ }
+ return commands;
}
- std::list<DrawCommand *> Item::buildChildrenDrawList()
+ void Item::buildChildrenDrawList(std::list<Command> &commands)
{
- std::list<DrawCommand *> commands;
for (auto widget : children) {
auto drawCommands = widget->buildDrawList();
if (!drawCommands.empty()) {
commands.splice(commands.end(), drawCommands);
}
}
- return commands;
}
void Item::setArea(BoundingBox area)
M module-gui/gui/widgets/Item.hpp => module-gui/gui/widgets/Item.hpp +13 -9
@@ 14,10 14,8 @@
#include <list> // for list
#include <memory> // for unique_ptr
#include <utility> // for move
-namespace gui
-{
- class DrawCommand;
-}
+#include <core/DrawCommandForward.hpp>
+
namespace gui
{
class InputEvent;
@@ 277,11 275,17 @@ namespace gui
/// calls onDimensionChanged & updateDrwArea
/// @attention should be bind to area
virtual void setBoundingBox(const BoundingBox &new_box);
- /// list of commands for renderer to draw elements on screen
- /// all elements consist od lines, arcs, rectangles, text and images
- /// for full list of elements please see renderer code
+ /// entry function to create commands to execute in renderer to draw on screen
/// @note we should consider lazy evaluation prior to drawing on screen, rather than on each resize of elements
- virtual std::list<DrawCommand *> buildDrawList();
+ /// @return list of commands for renderer to draw elements on screen
+ virtual std::list<Command> buildDrawList() final;
+ /// Implementation of DrawList per Item to be drawn on screen
+ /// This is called from buildDrawList before children elements are added
+ /// should be = 0;
+ virtual void buildDrawListImplementation(std::list<Command> &commands)
+ {}
+ std::function<void(std::list<Command> &)> preBuildDrawListHook = nullptr;
+ std::function<void(std::list<Command> &)> postBuildDrawListHook = nullptr;
/// sets radius of Item box
/// @note this should be moved to Rect
virtual void setRadius(int value);
@@ 350,7 354,7 @@ namespace gui
/// On change of position or size this method will recalculate visible part of the widget
/// considering widgets hierarchy and calculate absolute position of drawing primitives.
virtual void updateDrawArea();
- std::list<DrawCommand *> buildChildrenDrawList();
+ virtual void buildChildrenDrawList(std::list<Command> &commands) final;
/// Pointer to navigation object. It is added when object is set for one of the directions
gui::Navigation *navigationDirections = nullptr;
};
D module-gui/gui/widgets/KeyEvent.hpp => module-gui/gui/widgets/KeyEvent.hpp +0 -71
@@ 1,71 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-///*
-// * KeyEvent.hpp
-// *
-// * Created on: 25 kwi 2019
-// * Author: robert
-// */
-//
-//#ifndef GUI_WIDGETS_KEYEVENT_HPP_
-//#define GUI_WIDGETS_KEYEVENT_HPP_
-//
-//#include <cstdint>
-//
-// namespace gui {
-//
-// enum class KeyCode {
-// KEY_LEFT,
-// KEY_UP,
-// KEY_RIGHT,
-// KEY_DOWN,
-// KEY_LF,
-// KEY_RF,
-// KEY_ENTER,
-// KEY_0,
-// KEY_1,
-// KEY_2,
-// KEY_3,
-// KEY_4,
-// KEY_5,
-// KEY_6,
-// KEY_7,
-// KEY_8,
-// KEY_9,
-// KEY_AST,
-// KEY_PND,
-// KEY_GREEN,
-// KEY_RED,
-// KEY_VOLUP,
-// KEY_VOLDN,
-// KEY_TORCH,
-// SWITCH_UP,
-// SWITCH_MID,
-// SWITCH_DN
-//};
-//
-// enum class KeyState {
-// KEY_UNKNOWN = 0x00,
-// KEY_PRESSED = 0x01,
-// KEY_RELEASED_SHORT = 0x02,
-// KEY_RELEASED_LONG = 0x04,
-// KEY_CYCLE = 0x08
-//};
-//
-// class KeyEvent {
-// public:
-// //defines mapped code of the pressed button
-// KeyCode keyCode;
-// //defines state of the button
-// KeyState keyState;
-// //defines how long button was pressed
-// uint32_t duration;
-//
-// KeyEvent();
-// virtual ~KeyEvent();
-//};
-//
-//} /* namespace gui */
-//
-//#endif /* GUI_WIDGETS_KEYEVENT_HPP_ */
M module-gui/gui/widgets/Label.cpp => module-gui/gui/widgets/Label.cpp +23 -44
@@ 215,53 215,32 @@ namespace gui
calculateDisplayText();
}
- std::list<DrawCommand *> Label::buildDrawList()
+ void Label::buildDrawListImplementation(std::list<Command> &commands)
{
-
- std::list<DrawCommand *> commands;
-
- // check if widget is visible
- if (visible == false) {
- return commands;
- }
-
- // get children draw commands
- std::list<DrawCommand *> commandsChildren;
- commandsChildren = Item::buildDrawList();
-
- // base class draw commands
- std::list<DrawCommand *> commandsBase;
- commandsBase = gui::Rect::buildDrawList();
-
- commands.splice(commands.end(), commandsBase);
- // set local draw commands - text command
if (font != nullptr) {
- CommandText *textCmd = new CommandText();
- textCmd->str = textDisplayed;
- textCmd->fontID = font->id;
- textCmd->color = textColor;
-
- textCmd->x = drawArea.x;
- textCmd->y = drawArea.y;
- textCmd->w = drawArea.w;
- textCmd->h = drawArea.h;
- textCmd->tx = textArea.x;
- textCmd->ty = textArea.y;
- textCmd->tw = textArea.w;
- textCmd->th = textArea.h;
- textCmd->charsWidth = stringPixelWidth;
-
- textCmd->areaX = widgetArea.x;
- textCmd->areaY = widgetArea.y;
- textCmd->areaW = widgetArea.w;
- textCmd->areaH = widgetArea.h;
- commands.push_back(textCmd);
+ auto cmd = std::make_unique<CommandText>();
+ cmd->str = textDisplayed;
+ cmd->fontID = font->id;
+ cmd->color = textColor;
+
+ cmd->x = drawArea.x;
+ cmd->y = drawArea.y;
+ cmd->w = drawArea.w;
+ cmd->h = drawArea.h;
+ cmd->tx = textArea.x;
+ cmd->ty = textArea.y;
+ cmd->tw = textArea.w;
+ cmd->th = textArea.h;
+ cmd->charsWidth = stringPixelWidth;
+
+ cmd->areaX = widgetArea.x;
+ cmd->areaY = widgetArea.y;
+ cmd->areaW = widgetArea.w;
+ cmd->areaH = widgetArea.h;
+
+ commands.emplace_back(std::move(cmd));
}
- if (not commandsChildren.empty()) {
- commands.splice(commands.end(), commandsChildren);
- }
-
- return commands;
+ Rect::buildDrawListImplementation(commands);
}
bool Label::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim)
M module-gui/gui/widgets/Label.hpp => module-gui/gui/widgets/Label.hpp +1 -1
@@ 125,7 125,7 @@ namespace gui
void setFont(RawFont *font);
RawFont *getFont() const noexcept;
// virtual methods
- std::list<DrawCommand *> buildDrawList() override;
+ void buildDrawListImplementation(std::list<Command> &commands) override;
uint32_t getTextNeedSpace() const noexcept;
/// line: height
uint32_t getTextHeight() const noexcept;
D module-gui/gui/widgets/Layout.cpp => module-gui/gui/widgets/Layout.cpp +0 -0
M module-gui/gui/widgets/ListView.cpp => module-gui/gui/widgets/ListView.cpp +0 -10
@@ 357,16 357,6 @@ namespace gui
}
};
- std::list<DrawCommand *> ListView::buildDrawList()
- {
- // check if widget is visible
- if (visible == false) {
- return std::list<DrawCommand *>();
- }
-
- return gui::Rect::buildDrawList();
- }
-
bool ListView::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim)
{
Rect::onDimensionChanged(oldDim, newDim);
M module-gui/gui/widgets/ListView.hpp => module-gui/gui/widgets/ListView.hpp +0 -1
@@ 78,7 78,6 @@ namespace gui
void onProviderDataUpdate();
// virtual methods from Item
- std::list<DrawCommand *> buildDrawList() override;
bool onInput(const InputEvent &inputEvent) override;
bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) override;
auto handleRequestResize(const Item *, unsigned short request_w, unsigned short request_h) -> Size override;
M module-gui/gui/widgets/ProgressBar.cpp => module-gui/gui/widgets/ProgressBar.cpp +6 -21
@@ 47,24 47,12 @@ namespace gui
setValue(absoluteValue);
}
- std::list<DrawCommand *> ProgressBar::buildDrawList()
+ void ProgressBar::buildDrawListImplementation(std::list<Command> &commands)
{
- if (!visible) {
- return {};
- }
-
- std::list<DrawCommand *> baseCommands = gui::Rect::buildDrawList();
- auto it = baseCommands.begin();
- it++;
- CommandRectangle *fill = static_cast<CommandRectangle *>(*it);
-
uint32_t progressSize = maxValue == 0U ? 0 : (currentValue * widgetArea.w) / maxValue;
- fill->w = progressSize;
+ drawArea.w = progressSize;
- std::list<DrawCommand *> commands;
- commands.splice(commands.end(), baseCommands, it);
- commands.splice(commands.end(), baseCommands);
- return commands;
+ gui::Rect::buildDrawListImplementation(commands);
}
bool ProgressBar::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim)
@@ 137,17 125,14 @@ namespace gui
return static_cast<float>(currentValue) / maxValue;
}
- std::list<DrawCommand *> CircularProgressBar::buildDrawList()
+ void CircularProgressBar::buildDrawListImplementation(std::list<Command> &commands)
{
using namespace trigonometry;
- if (!visible) {
- return {};
- }
-
progressArc->setSweepAngle(getPercentageValue() * FullAngle);
progressIndicator->setCenter(calculateProgressIndicatorCenter());
- return Circle::buildDrawList();
+
+ Circle::buildDrawListImplementation(commands);
}
bool CircularProgressBar::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim)
M module-gui/gui/widgets/ProgressBar.hpp => module-gui/gui/widgets/ProgressBar.hpp +2 -2
@@ 30,7 30,7 @@ namespace gui
void setValue(unsigned int value) noexcept override;
void setPercentageValue(unsigned int value) noexcept override;
- std::list<DrawCommand *> buildDrawList() override;
+ void buildDrawListImplementation(std::list<Command> &commands) override;
bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) override;
private:
@@ 50,7 50,7 @@ namespace gui
void setValue(unsigned int value) noexcept override;
void setPercentageValue(unsigned int value) noexcept override;
- auto buildDrawList() -> std::list<DrawCommand *> override;
+ void buildDrawListImplementation(std::list<Command> &commands) override;
auto onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) -> bool override;
private:
M module-gui/gui/widgets/Rect.cpp => module-gui/gui/widgets/Rect.cpp +7 -22
@@ 93,21 93,9 @@ namespace gui
yapSize = value;
}
- std::list<DrawCommand *> Rect::buildDrawList()
+ void Rect::buildDrawListImplementation(std::list<Command> &commands)
{
-
- std::list<DrawCommand *> commands;
-
- // check if widget is visible
- if (visible == false) {
- return commands;
- }
-
- // get children draw commands
- std::list<DrawCommand *> childrenCommands = Item::buildDrawList();
-
- // set local draw commands
- CommandRectangle *rect = new CommandRectangle();
+ auto rect = std::make_unique<CommandRectangle>();
rect->x = drawArea.x;
rect->y = drawArea.y;
@@ 123,21 111,18 @@ namespace gui
rect->yaps = yaps;
rect->yapSize = yapSize;
rect->radius = radius;
- if (focus)
+ if (focus) {
rect->penWidth = penFocusWidth;
- else
+ }
+ else {
rect->penWidth = penWidth;
+ }
rect->filled = filled;
rect->borderColor = borderColor;
rect->fillColor = fillColor;
- commands.push_back(rect);
-
- if (!childrenCommands.empty())
- commands.insert(commands.end(), childrenCommands.begin(), childrenCommands.end());
-
- return commands;
+ commands.emplace_back(std::move(rect));
}
} /* namespace gui */
M module-gui/gui/widgets/Rect.hpp => module-gui/gui/widgets/Rect.hpp +1 -1
@@ 50,7 50,7 @@ namespace gui
virtual void setYaps(RectangleYap yaps);
virtual void setYapSize(unsigned short value);
void setFilled(bool val);
- std::list<DrawCommand *> buildDrawList() override;
+ void buildDrawListImplementation(std::list<Command> &commands) override;
};
} /* namespace gui */
M module-gui/gui/widgets/RichTextParser.cpp => module-gui/gui/widgets/RichTextParser.cpp +4 -2
@@ 15,9 15,11 @@
#include <module-utils/pugixml/src/pugixml.hpp>
#include <utility>
-#ifndef DEBUG_RTP
+#ifdef DEBUG_RTP
const std::string node_types[] = {"null", "document", "element", "pcdata ", "cdata", "comment", "pi", "declaration"};
#define log_parser(...) LOG_DEBUG(__VA_ARGS__)
+#else
+#define log_parser(...)
#endif
namespace text
@@ 426,7 428,7 @@ namespace gui::text
auto RichTextParser::parse(const UTF8 &text, TextFormat *base_style) -> std::unique_ptr<TextDocument>
{
- LOG_DEBUG("parsing: %s", text.c_str());
+ log_parser("parsing: %s", text.c_str());
if (text.empty() || base_style == nullptr) {
LOG_ERROR("no: %s", text.empty() ? "text" : "base style");
return std::unique_ptr<TextDocument>();
M module-gui/gui/widgets/Span.hpp => module-gui/gui/widgets/Span.hpp +1 -1
@@ 21,7 21,7 @@ namespace gui
Span(Item *parent, Axis axis, unsigned int size) : Span(axis, size)
{
- if (parent) {
+ if (parent != nullptr) {
parent->addWidget(this);
}
}
M module-gui/gui/widgets/Text.cpp => module-gui/gui/widgets/Text.cpp +4 -2
@@ 24,6 24,7 @@
#include <RawFont.hpp>
#include <RichTextParser.hpp>
#include "Lines.hpp"
+#include <DrawCommand.hpp>
#if DEBUG_GUI_TEXT == 1
#define debug_text(...) LOG_DEBUG(__VA_ARGS__)
@@ 70,6 71,8 @@ namespace gui
setBorderColor(gui::ColorFullBlack);
setEdges(RectangleEdge::All);
+
+ preBuildDrawListHook = [this](std::list<Command> &commands) { preBuildDrawListHookImplementation(commands); };
}
Text::Text() : Text(nullptr, 0, 0, 0, 0)
@@ 434,7 437,7 @@ namespace gui
}
}
- std::list<DrawCommand *> Text::buildDrawList()
+ void Text::preBuildDrawListHookImplementation(std::list<Command> &commands)
{
// we can't build elements to show just before showing.
// why? because we need to know if these elements fit in
@@ 452,7 455,6 @@ namespace gui
return str.c_str();
}()
.c_str());
- return Rect::buildDrawList();
}
void Text::buildDocument(const UTF8 &text)
M module-gui/gui/widgets/Text.hpp => module-gui/gui/widgets/Text.hpp +1 -1
@@ 78,7 78,7 @@ namespace gui
auto handleNavigation(const InputEvent &inputEvent) -> bool;
auto handleEnter() -> bool;
- auto buildDrawList() -> std::list<DrawCommand *> override;
+ void preBuildDrawListHookImplementation(std::list<Command> &commands);
/// redrawing lines
/// it redraws visible lines on screen and if needed requests resize in parent
virtual void drawLines();
M module-gui/gui/widgets/TopBar.cpp => module-gui/gui/widgets/TopBar.cpp +4 -20
@@ 25,16 25,6 @@ namespace gui
gui::TopBar::TimeMode TopBar::timeMode = TimeMode::TIME_24H;
uint32_t TopBar::time = 0;
- TopBar::TopBar()
- {
-
- prepareWidget();
-
- setFillColor(ColorFullWhite);
- setBorderColor(ColorNoColor);
- setFilled(true);
- setSize(480, 50);
- }
TopBar::TopBar(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h) : Rect{parent, x, y, w, h}
{
@@ 45,9 35,11 @@ namespace gui
setFilled(true);
setSize(480, 50);
updateDrawArea();
+
+ preBuildDrawListHook = [this](std::list<Command> &) {
+ setTime(time, (timeMode == TimeMode::TIME_24H) ? true : false);
+ };
}
- TopBar::~TopBar()
- {}
void TopBar::batteryShowBars(uint32_t val)
{
@@ 285,14 277,6 @@ namespace gui
return timeLabel->getText();
}
- std::list<DrawCommand *> TopBar::buildDrawList()
- {
-
- // make sure that time text is updated.
- setTime(time, (timeMode == TimeMode::TIME_24H) ? true : false);
-
- return Rect::buildDrawList();
- }
void TopBar::simSet()
{
M module-gui/gui/widgets/TopBar.hpp => module-gui/gui/widgets/TopBar.hpp +0 -10
@@ 76,14 76,7 @@ namespace gui
} elements = {false, false, false, false, true, true};
public:
- TopBar();
TopBar(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
- virtual ~TopBar();
-
- /**
- * @brief Sets mode of time displaying according to TimeMode enum
- * @note Variable is common for all instances of TopBar
- */
/**
* @brief Hides or shows images.
@@ 115,9 108,6 @@ namespace gui
{
return time;
};
-
- // virtual methods from Item
- std::list<DrawCommand *> buildDrawList() override;
};
} /* namespace gui */
M module-gui/gui/widgets/Window.cpp => module-gui/gui/widgets/Window.cpp +6 -18
@@ 17,7 17,7 @@
namespace gui
{
- Window::Window(std::string name) : Item(), refreshMode{RefreshModes::GUI_REFRESH_FAST}, name{name}
+ Window::Window(std::string name) : Item(), name{name}
{}
void Window::onBeforeShow(ShowMode mode, SwitchData *data)
@@ 26,36 26,24 @@ namespace gui
void Window::onClose()
{}
- void Window::getRefreshArea(RefreshModes &mode, uint16_t &x, uint16_t &y, uint16_t &w, uint16_t &h)
+ void Window::getRefreshArea(uint16_t &x, uint16_t &y, uint16_t &w, uint16_t &h)
{
x = widgetArea.x;
y = widgetArea.y;
w = widgetArea.w;
h = widgetArea.h;
- mode = refreshMode;
}
bool Window::handleSwitchData(SwitchData *data)
{
- return true;
+ return false;
}
- std::list<DrawCommand *> Window::buildDrawList()
+ void Window::buildDrawListImplementation(std::list<Command> &commands)
{
-
- std::list<DrawCommand *> commands;
- std::list<DrawCommand *> childrenCommands = Item::buildDrawList();
-
- DrawCommand *clearCommand = new DrawCommand();
+ auto clearCommand = std::make_unique<DrawCommand>();
clearCommand->id = DrawCommandID::GUI_DRAW_CLEAR;
-
- commands.push_back(clearCommand);
-
- if (!childrenCommands.empty()) {
- commands.splice(commands.end(), childrenCommands);
- }
-
- return commands;
+ commands.emplace_back(std::move(clearCommand));
}
bool Window::onInput(const InputEvent &inputEvent)
M module-gui/gui/widgets/Window.hpp => module-gui/gui/widgets/Window.hpp +4 -3
@@ 30,7 30,6 @@ namespace gui
class Window : public Item
{
protected:
- RefreshModes refreshMode;
/// name of window used for windows switching
std::string name;
@@ 43,7 42,7 @@ namespace gui
/// @note this is most likely being duplicated by handleSwitchData
virtual void onBeforeShow(ShowMode mode, SwitchData *data);
virtual void onClose();
- virtual void getRefreshArea(RefreshModes &mode, uint16_t &x, uint16_t &y, uint16_t &w, uint16_t &h);
+ virtual void getRefreshArea(uint16_t &x, uint16_t &y, uint16_t &w, uint16_t &h);
/// run prior to onBeforeShow
/// @note this is most likely duplicate of onBeforeShow
@@ 58,7 57,9 @@ namespace gui
// virtual methods from Item
bool onInput(const InputEvent &inputEvent) override;
- std::list<DrawCommand *> buildDrawList() override;
+
+ void buildDrawListImplementation(std::list<Command> &commands) override;
+
std::string getName()
{
return name;
M module-gui/test/test-catch/test-gui.cpp => module-gui/test/test-catch/test-gui.cpp +1 -7
@@ 97,15 97,9 @@ TEST_CASE("Draw window with labels")
// vector with draw commands
// context for drawing commands
- std::list<gui::DrawCommand *> commandsList = win->buildDrawList();
- std::vector<gui::DrawCommand *> commands{commandsList.begin(), commandsList.end()};
+ auto commandsList = win->buildDrawList();
delete win;
-
- // cleanup
- for (auto cmd : commands) {
- delete cmd;
- }
}
TEST_CASE("Draw window with box layouts")
M module-services/service-gui/ServiceGUI.cpp => module-services/service-gui/ServiceGUI.cpp +4 -6
@@ 118,13 118,13 @@ namespace sgui
// if suspend flag is set ignore any new message
if (!suspendInProgress) {
- if (dmsg->command == sgui::DrawMessage::DrawCommand::SHUTDOWN) {
+ if (dmsg->type == sgui::DrawMessage::Type::SHUTDOWN) {
LOG_WARN("Shutdown - received shutdown draw commands");
shutdownInProgress = true;
}
// if message carries suspend flag set flag in service and proceed
- if (dmsg->command == sgui::DrawMessage::DrawCommand::SUSPEND) {
+ if (dmsg->type == sgui::DrawMessage::Type::SUSPEND) {
LOG_WARN("Suspended - received suspend draw commands");
suspendInProgress = true;
}
@@ 134,13 134,11 @@ namespace sgui
mode = dmsg->mode;
}
- // LOG_INFO("[ServiceGUI] Received %d draw commands", dmsg->commands.size());
+ // LOG_DEBUG("Received %d draw commands", dmsg->commands.size());
// lock access to commands vector, clear it and then copy commands from message to vector
if (xSemaphoreTake(semCommands, pdMS_TO_TICKS(1000)) == pdTRUE) {
- commands.clear();
- for (auto it = dmsg->commands.begin(); it != dmsg->commands.end(); it++)
- commands.push_back(std::move(*it));
+ commands = std::move(dmsg->commands);
xSemaphoreGive(semCommands);
}
else {
M module-services/service-gui/ServiceGUI.hpp => module-services/service-gui/ServiceGUI.hpp +1 -1
@@ 58,7 58,7 @@ namespace sgui
volatile bool rendering = false;
// set of commands recently received. If this vector is not empty and new set of commands is received
// previous commands are removed.
- std::vector<std::unique_ptr<gui::DrawCommand>> commands;
+ std::list<std::unique_ptr<gui::DrawCommand>> commands;
// uint32_t timer_id= 0;
gui::RefreshModes mode = gui::RefreshModes::GUI_REFRESH_DEEP;
M module-services/service-gui/WorkerGUI.cpp => module-services/service-gui/WorkerGUI.cpp +3 -11
@@ 40,29 40,21 @@ namespace sgui
xQueueReceive(queue, &received, 0);
// take all unique pointers
- std::vector<std::unique_ptr<gui::DrawCommand>> uniqueCommands;
+ std::list<std::unique_ptr<gui::DrawCommand>> uniqueCommands;
if (xSemaphoreTake(serviceGUI->semCommands, pdMS_TO_TICKS(1000)) == pdTRUE) {
- for (auto it = serviceGUI->commands.begin(); it != serviceGUI->commands.end(); it++)
- uniqueCommands.push_back(std::move(*it));
- serviceGUI->commands.clear();
+ uniqueCommands = std::move(serviceGUI->commands);
xSemaphoreGive(serviceGUI->semCommands);
}
else {
LOG_ERROR("Failed to acquire semaphore");
}
- // create temporary vector of pointers to draw commands to avoid polluting renderer with smart pointers.
- std::vector<gui::DrawCommand *> commands;
- for (auto it = uniqueCommands.begin(); it != uniqueCommands.end(); it++)
- commands.push_back((*it).get());
-
// uint32_t start_tick = xTaskGetTickCount();
- serviceGUI->renderer.render(serviceGUI->renderContext, commands);
+ serviceGUI->renderer.render(serviceGUI->renderContext, uniqueCommands);
// uint32_t end_tick = xTaskGetTickCount();
// LOG_INFO("[WorkerGUI] RenderingTime: %d", end_tick - start_tick);
- // delete received;
// notify gui service that rendering is complete
auto message = std::make_shared<sys::DataMessage>(MessageType::GUIRenderingFinished);
M module-services/service-gui/messages/DrawMessage.cpp => module-services/service-gui/messages/DrawMessage.cpp +2 -15
@@ 2,28 2,15 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "DrawMessage.hpp"
-
#include "GUIMessage.hpp"
-
#include <Common.hpp>
#include <DrawCommand.hpp>
-#include <MessageType.hpp>
namespace sgui
{
- DrawMessage::DrawMessage(const std::list<gui::DrawCommand *> &commandsList, gui::RefreshModes mode, DrawCommand cmd)
- : GUIMessage(MessageType::GUICommands), command{cmd}
+ DrawMessage::DrawMessage(std::list<gui::Command> commands, gui::RefreshModes mode)
+ : GUIMessage(MessageType::GUICommands), mode(mode), commands(std::move(commands))
{
-
- this->mode = mode;
- for (auto cmd : commandsList) {
- if (cmd)
- commands.push_back(std::unique_ptr<gui::DrawCommand>(cmd));
- }
}
-
- DrawMessage::~DrawMessage()
- {}
-
} /* namespace sgui */
M module-services/service-gui/messages/DrawMessage.hpp => module-services/service-gui/messages/DrawMessage.hpp +13 -19
@@ 4,7 4,6 @@
#pragma once
#include "GUIMessage.hpp"
-
#include <core/DrawCommand.hpp>
#include <gui/Common.hpp>
#include <Service/Message.hpp>
@@ 12,21 11,18 @@
#include <list>
#include <memory>
-namespace gui
-{
- class DrawCommand;
-} // namespace gui
+#include "Service/Message.hpp"
+#include "core/DrawCommandForward.hpp"
+#include "GUIMessage.hpp"
+#include "gui/Common.hpp"
namespace sgui
{
- /*
- *
- */
class DrawMessage : public GUIMessage
{
public:
- enum class DrawCommand
+ enum class Type
{
NORMAL,
SUSPEND,
@@ 35,17 31,15 @@ namespace sgui
public:
gui::RefreshModes mode;
- std::list<std::unique_ptr<gui::DrawCommand>> commands;
+ std::list<gui::Command> commands;
+ Type type = Type::NORMAL;
- /**
- * flag that informs that this is last rendering before suspending system.
- */
- DrawCommand command = DrawCommand::NORMAL;
+ DrawMessage(std::list<gui::Command> commandsList, gui::RefreshModes mode);
- DrawMessage(const std::list<gui::DrawCommand *> &commandsList,
- gui::RefreshModes mode,
- DrawCommand cmd = DrawCommand::NORMAL);
- virtual ~DrawMessage();
+ void setCommandType(Type type)
+ {
+ this->type = type;
+ }
};
-} /* namespace sgui */
+} // namespace sgui
M source/MessageType.hpp => source/MessageType.hpp +2 -1
@@ 147,7 147,8 @@ enum class MessageType
// keyboard messages
KBDKeyEvent,
- AppSwitch, ///< application receives this message from application manager. It a signal to gain or loose focus.
+ AppMessage, //< generic application message
+ AppSwitch, ///< application receives this message from application manager. It a signal to gain or loose focus.
AppSwitchWindow, ///< This is internal message transmitted within application to change window. Additional command
///< and data are transmitted with it.
AppInputEvent, ///< used after key event translation to send input event to application