void activateBy(const void *deactivator);
void deactivateBy(const void *deactivator);
+ void addDeactivatorSource(ucl::Widget &source);
+ void delDeactivatorSource(ucl::Widget &source);
+
+ protected:
+ enum {
+ PF_ADD_DEACTIVATOR_SOURCES = 1,
+ PF_ADD_SELF_EXCEPT = 2,
+
+ PF_PASSIVE = 0,
+ PF_DEACTIVATOR = (PF_ADD_DEACTIVATOR_SOURCES | PF_ADD_SELF_EXCEPT),
+ PF_DEFAULT = PF_DEACTIVATOR
+ };
+
protected:
Presenter(ucl::IRefCountObj &rc);
- virtual ~Presenter() = default;
+ virtual ~Presenter();
- ucl::Result prepare(ucl::ElmWidget &widget);
+ ucl::Result prepare(ucl::ElmWidget &widget, int flags = PF_DEFAULT);
+ ucl::Result prepare(Presenter &parent, int flags = PF_DEFAULT);
ucl::Window &getWindow();
bool isWindowReady() const;
- void addDeactivatorSource(ucl::Widget &source);
void addDeactivatorException(const void *deactivator);
+ void setDeactivatorSink(const ucl::WidgetSRef &sink);
void sendActivate(ucl::Widget &sender);
void sendDeactivate(ucl::Widget &sender);
std::unordered_set<const void *> m_deactivatorExceptions;
std::unordered_set<const void *> m_deactivators;
ucl::WindowSRef m_window;
+ ucl::WidgetSRef m_sink;
+ ucl::WidgetWRef m_parentSink;
+ bool m_hasBuildInSources;
+ bool m_isChild;
bool m_isPrepared;
};
}
Presenter::Presenter(IRefCountObj &rc) :
RefCountAware(&rc),
+ m_hasBuildInSources(false),
+ m_isChild(false),
m_isPrepared(false)
{
}
- Result Presenter::prepare(ElmWidget &widget)
+ Presenter::~Presenter()
+ {
+ if (m_hasBuildInSources) {
+ if (m_isChild) {
+ if (const auto parentSink = m_parentSink.lock()) {
+ delDeactivatorSource(*parentSink);
+ }
+ } else if (m_window) {
+ delDeactivatorSource(*m_window);
+ }
+ }
+ }
+
+ Result Presenter::prepare(ElmWidget &widget, const int flags)
{
m_window = asShared(widget.getWindow());
if (!m_window) {
LOG_RETURN(RES_FAIL, "m_window is NULL!");
}
- addDeactivatorSource(*m_window);
- addDeactivatorException(m_rc->getObjPtr());
+ if (flags & PF_ADD_DEACTIVATOR_SOURCES) {
+ addDeactivatorSource(*m_window);
+ m_hasBuildInSources = true;
+ }
+
+ if (flags & PF_ADD_SELF_EXCEPT) {
+ addDeactivatorException(m_rc->getObjPtr());
+ }
m_isPrepared = true;
return RES_OK;
}
+ Result Presenter::prepare(Presenter &parent, const int flags)
+ {
+ if (!parent.m_sink) {
+ LOG_RETURN(RES_FAIL, "parent.m_sink is NULL!");
+ }
+
+ for (auto deactivator: parent.m_deactivators) {
+ if (m_deactivatorExceptions.find(deactivator) ==
+ m_deactivatorExceptions.end()) {
+ m_deactivators.insert(deactivator);
+ }
+ }
+
+ if (flags & PF_ADD_DEACTIVATOR_SOURCES) {
+ addDeactivatorSource(*parent.m_sink);
+ m_hasBuildInSources = true;
+ }
+
+ if (flags & PF_ADD_SELF_EXCEPT) {
+ addDeactivatorException(m_rc->getObjPtr());
+ }
+
+ m_window = parent.m_window;
+ m_parentSink = parent.m_sink;
+ m_isChild = true;
+ m_isPrepared = true;
+
+ return RES_OK;
+ }
+
Window &Presenter::getWindow()
{
UCL_ASSERT(isWindowReady(), "m_window is NULL!");
return !!m_window;
}
- void Presenter::addDeactivatorSource(Widget &source)
- {
- source.addEventHandler(impl::ACTIVATE_BY,
- WEAK_DELEGATE(Presenter::onActivateBySmart, asWeak(*this)));
- source.addEventHandler(impl::DEACTIVATE_BY,
- WEAK_DELEGATE(Presenter::onDeactivateBySmart, asWeak(*this)));
- }
-
void Presenter::addDeactivatorException(const void *const deactivator)
{
const auto pair = m_deactivatorExceptions.insert(deactivator);
}
}
+ void Presenter::setDeactivatorSink(const WidgetSRef &sink)
+ {
+ m_sink = sink;
+ }
+
void Presenter::sendActivate(Widget &sender)
{
sendDeactivator(sender, impl::ACTIVATE_BY, m_rc->getObjPtr());
deactivateByImpl({deactivator, false});
}
+ void Presenter::addDeactivatorSource(Widget &source)
+ {
+ source.addEventHandler(impl::ACTIVATE_BY,
+ WEAK_DELEGATE(Presenter::onActivateBySmart, asWeak(*this)));
+ source.addEventHandler(impl::DEACTIVATE_BY,
+ WEAK_DELEGATE(Presenter::onDeactivateBySmart, asWeak(*this)));
+ }
+
+ void Presenter::delDeactivatorSource(Widget &source)
+ {
+ source.delEventHandler(impl::ACTIVATE_BY,
+ WEAK_DELEGATE(Presenter::onActivateBySmart, asWeak(*this)));
+ source.delEventHandler(impl::DEACTIVATE_BY,
+ WEAK_DELEGATE(Presenter::onDeactivateBySmart, asWeak(*this)));
+ }
+
void Presenter::activateByImpl(const DeactivatorInfo &info)
{
const auto count = m_deactivators.erase(info.deactivator);
if (m_isPrepared && (count > 0)) {
+ if (m_sink) {
+ sendDeactivatorInfo(*m_sink, impl::ACTIVATE_BY, info);
+ }
onActivateBy(info);
if (m_deactivators.size() == 0) {
onActivate();
}
const auto pair = m_deactivators.insert(info.deactivator);
if (m_isPrepared && pair.second) {
+ if (m_sink) {
+ sendDeactivatorInfo(*m_sink, impl::DEACTIVATE_BY, info);
+ }
onDeactivateBy(info);
if (m_deactivators.size() == 1) {
onDeactivate();