// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md #include "WindowsStack.hpp" #include #include "WindowsFactory.hpp" #include "windows/AppWindow.hpp" namespace app { std::map>::const_iterator WindowsStack::begin() const { return std::begin(windows); } std::map>::const_iterator WindowsStack::end() const { return std::end(windows); } void WindowsStack::push(const std::string &name, std::unique_ptr window, const gui::popup::Disposition &disposition) { /// Note: this is the place which will destroy old window if there was one windows[name] = std::move(window); stack.emplace_back(name, disposition); } gui::AppWindow *WindowsStack::get(const std::string &name) const { auto ret = windows.find(name); return ret == std::end(windows) ? nullptr : ret->second.get(); } std::optional WindowsStack::getWindowData(std::uint32_t depth) const { if (depth >= stack.size()) { return std::nullopt; } return {*std::prev(stack.end(), depth + 1)}; } std::optional WindowsStack::get(std::uint32_t depth) const { if (auto windowData = getWindowData(depth)) { return {windowData->name}; } return std::nullopt; } [[nodiscard]] bool WindowsStack::isEmpty() const noexcept { return stack.empty(); } /// return false on pop empty bool WindowsStack::pop() noexcept { if (!stack.empty()) { stack.pop_back(); return true; } return false; } bool WindowsStack::pop(const std::string &window) { auto ret = findInStack(window); if (ret != stack.end()) { stack.erase(std::next(ret), stack.end()); return true; } return false; } bool WindowsStack::popLastWindow() { if (stack.size() == 1) { stack.clear(); return true; } return false; } bool WindowsStack::drop(const std::string &window) { auto popWindow = findInStack(window); if (popWindow != stack.end()) { stack.erase(popWindow); return true; } return false; } bool WindowsStack::rebuildWindows(app::WindowsFactory &windowsFactory, ApplicationCommon *app) { if (windows.empty()) { return false; } for (auto &[name, window] : windows) { windows[name] = windowsFactory.build(app, name); } return true; } void WindowsStack::clear() { stack.clear(); windows.clear(); } decltype(WindowsStack::stack)::iterator WindowsStack::findInStack(const std::string &window) { return std::find_if(stack.begin(), stack.end(), [&](auto &el) { return el.name == window; }); } bool WindowsStack::isWindowOnStack(const std::string &window) { return findInStack(window) != stack.end(); } void WindowsStack::dropPendingPopups() { auto it = stack.rbegin(); while (it != stack.rend()) { LOG_DEBUG("Current window on stack: %s, type: %s", it->name.c_str(), magic_enum::enum_name(it->disposition.windowtype).data()); if (it->disposition.windowtype == gui::popup::Disposition::WindowType::Popup) { LOG_DEBUG("Erasing: %s", it->name.c_str()); stack.erase(std::next(it).base()); } std::advance(it, 1); } } std::size_t WindowsStack::getSize() const noexcept { return stack.size(); } } // namespace app