--- /dev/null
+#include "Action.hpp"
+
+Action::Action(std::string actionId, std::string title, std::function<void(Action *item)> onInvoke, bool enabled, bool state)
+ : actionId_(std::move(actionId)),
+ title_(std::move(title)),
+ onInvoke_(std::move(onInvoke)),
+ enabled_(enabled),
+ state_(state)
+{
+ if (actionId_ == "titleRightAction")
+ state_.attach([this](auto val) {
+ onInvoke_(this);
+ });
+}
\ No newline at end of file
--- /dev/null
+#ifndef ACTION_HPP
+#define ACTION_HPP
+
+#include "ObservableProperty.hpp"
+
+#include <functional>
+#include <string>
+
+struct Action
+{
+ Action(std::string actionId, std::string title, std::function<void(Action *item)> onInvoke, bool enabled_ = true, bool state = false);
+
+ const std::string actionId_;
+ ObservableProperty<std::string> title_;
+ const std::function<void(Action *item)> onInvoke_;
+ ObservableProperty<bool> enabled_ = true;
+ ObservableProperty<bool> state_ = false;
+};
+
+#endif
\ No newline at end of file
{
return groups_;
}
+
+Action *ListPresenter::getAction(const std::string &actionId) const
+{
+ auto it = actions_.find(actionId);
+ if (it == actions_.end()) {
+ ERROR("Action with id: %s doesn't exist", actionId.c_str());
+ return nullptr;
+ }
+ return it->second.get();
+}
+
+void ListPresenter::addAction(std::unique_ptr<Action> action)
+{
+ actions_.insert_or_assign(action->actionId_, std::move(action));
+}
#ifndef LIST_PRESENTER_HPP
#define LIST_PRESENTER_HPP
+#include "Action.hpp"
#include "ListGroup.hpp"
#include "Observable.hpp"
#include "Presenter.hpp"
+#include <unordered_map>
+
class ListPresenter : public Presenter, public Observable<>
{
public:
const std::vector<ListGroup> &getListGroups() const;
+ Action *getAction(const std::string &actionId) const;
+ void addAction(std::unique_ptr<Action> action);
protected:
using Presenter::Presenter;
std::vector<ListGroup> groups_;
+ std::unordered_map<std::string, std::unique_ptr<Action>> actions_;
};
#endif
\ No newline at end of file
return title_;
}
+void Presenter::setTitle(const std::string &title)
+{
+ title_ = title;
+}
+
const std::function<void()> Presenter::getOnPopCallback() const
{
return onPopCallback_;
virtual ~Presenter() = default;
const TranslatedString getTitle() const;
+ void setTitle(const std::string &title);
const std::function<void()> getOnPopCallback() const;
virtual void onAppPause();
virtual void onAppResume();
#include "ListView.hpp"
+#include "Button.hpp"
+#include "Check.hpp"
#include "Genlist.hpp"
#include "ListPresenter.hpp"
#include "NavigationContext.hpp"
addItemsToGenlist();
- naviframe->pushBack(listPresenter_->getTitle(), genlist_, listPresenter_->getOnPopCallback(), prevButton_);
+ if (auto action = listPresenter_->getAction("selectAll")) {
+ auto checkbox = Widget::make<Check>(context.getNaviframe());
+ checkbox->setState(action->state_.value());
+ checkbox->setEvasSmartCallback("changed", [this, action, checkbox]() {
+ action->state_ = checkbox->getState();
+ });
+ action->state_.attach([this, checkbox](auto val) {
+ checkbox->setState(val);
+ });
+ action->enabled_.attach([this, checkbox](auto val) {
+ checkbox->disable(!val);
+ });
+ backItem_ = checkbox;
+ } else {
+ if (auto action = listPresenter_->getAction("previousView")) {
+ auto wrappedOnClick = [this, action]() {
+ action->onInvoke_(action);
+ };
+ backItem_ = Widget::make<Button>(context.getNaviframe(),
+ wrappedOnClick,
+ "IDS_ST_BUTTON_BACK",
+ Button::BACK_BUTTON_ARROW_STYLE);
+ action->enabled_.attach([this](auto val) {
+ backItem_->disable(!val);
+ });
+ } else {
+ backItem_ = Widget::make<Button>(context.getNaviframe(),
+ [naviframe = context.getNaviframe()]() { naviframe->popBack(); },
+ "IDS_ST_BUTTON_BACK",
+ Button::BACK_BUTTON_ARROW_STYLE);
+ }
+ }
+
+ naviframe->pushBack(listPresenter_->getTitle(), genlist_, listPresenter_->getOnPopCallback(), backItem_);
+
+ if (auto action = listPresenter_->getAction("titleRightAction")) {
+ titleRightButton_ = Widget::make<Button>(context.getNaviframe(), [this, action]() {
+ action->onInvoke_(action);
+ },
+ "<font_size=30>" + TranslatedString{action->title_.value()}.str() + "</font_size>",
+ "naviframe/title_right");
+ action->title_.attach([this](auto val) {
+ auto formatedText = "<font_size=30>" + TranslatedString{val}.str() + "</font_size>";
+ titleRightButton_->setText(formatedText);
+ });
+ action->enabled_.attach([this](auto val) {
+ titleRightButton_->disable(!val);
+ });
+ naviframe->setPartContent("title_right_btn", titleRightButton_);
+ }
+}
+
+ListView::~ListView()
+{
+ if (titleRightButton_) {
+ auto parent = titleRightButton_->getParent();
+ parent->removeChild(titleRightButton_);
+ }
}
void ListView::addItemsToGenlist()
#ifndef LIST_VIEW_HPP
#define LIST_VIEW_HPP
+#include "Button.hpp"
#include "ListPresenter.hpp"
#include "Presenter.hpp"
#include "View.hpp"
{
public:
ListView(const NavigationContext &context, Presenter *presenter);
+ ~ListView();
private:
void addItemsToGenlist();
ListPresenter *listPresenter_ = nullptr;
Genlist *genlist_ = nullptr;
std::unordered_map<GenlistItem *, ListItem *> itemsMapping_;
+ Widget *backItem_ = nullptr;
+ Button *titleRightButton_ = nullptr;
};
#endif
\ No newline at end of file
* In order to add new Presenter class, one should cast received pointer to derived type
* and push proper View on viewStack_
*/
- auto lp = dynamic_cast<ListPresenter *>(presenter);
- if (lp) {
+
+ if (auto lp = dynamic_cast<ListPresenter *>(presenter)) {
viewsStack_.push_back(std::make_unique<ListView>(*this, lp));
return;
}
View::View(const NavigationContext &context)
{
- prevButton_ = Widget::make<Button>(context.getNaviframe(),
- [naviframe = context.getNaviframe()]() { naviframe->popBack(); },
- "IDS_ST_BUTTON_BACK",
- Button::BACK_BUTTON_ARROW_STYLE);
}
\ No newline at end of file
#ifndef VIEW_HPP
#define VIEW_HPP
-#include "Button.hpp"
#include "Presenter.hpp"
class NavigationContext;
virtual ~View() = default;
protected:
- Button *prevButton_ = nullptr;
};
#endif
\ No newline at end of file