[DEV] add owner to auto remove an object

This commit is contained in:
Edouard DUPIN 2014-05-23 12:33:49 +02:00
parent 699935e482
commit e6a5c9c85f
21 changed files with 410 additions and 131 deletions

View File

@ -380,13 +380,10 @@ ewol::Context::~Context() {
// TODO : Clean the message list ... // TODO : Clean the message list ...
// set the curent interface : // set the curent interface :
lockContext(); lockContext();
// Remove current windows
m_windowsCurrent.reset();
// call application to uninit // call application to uninit
APP_UnInit(*this); APP_UnInit(*this);
if (m_windowsCurrent != nullptr) {
EWOL_DEBUG("Main windows has not been auto-removed...");
m_windowsCurrent->removeObject();
m_windowsCurrent.reset();
}
// unset all windows // unset all windows
m_msgSystem.clean(); m_msgSystem.clean();

View File

@ -158,7 +158,7 @@ namespace ewol {
*/ */
virtual void stop(); virtual void stop();
private: private:
ewol::object::Shared<ewol::widget::Windows> m_windowsCurrent; //!< curent displayed windows ewol::object::Owner<ewol::widget::Windows> m_windowsCurrent; //!< curent displayed windows
public: public:
/** /**
* @brief set the current windows to display : * @brief set the current windows to display :

View File

@ -35,17 +35,19 @@ ewol::object::Manager::~Manager() {
void ewol::object::Manager::unInit() { void ewol::object::Manager::unInit() {
EWOL_DEBUG(" == > Un-Init Object-Manager"); EWOL_DEBUG(" == > Un-Init Object-Manager");
for (auto &it : m_eObjectList) {
if (it != nullptr) {
//it->removeObject();
}
}
removeAllRemovedObject(); removeAllRemovedObject();
EWOL_INFO(" remove missing user object"); EWOL_INFO(" remove missing user object");
size_t iii=0; size_t iii=0;
if (m_eObjectListActive.size() != 0) { if (m_eObjectListActive.size() != 0) {
EWOL_ERROR("Have " << m_eObjectListActive.size() << " active Object"); EWOL_ERROR("Have " << m_eObjectListActive.size() << " active Object");
} }
while(iii < m_eObjectListActive.size()) { m_eObjectListActive.clear();
if (m_eObjectListActive[iii] != nullptr) { m_eObjectList.clear();
m_eObjectListActive.erase(m_eObjectListActive.begin()+iii);
}
}
removeAllRemovedObject(); removeAllRemovedObject();
} }
@ -68,6 +70,9 @@ void ewol::object::Manager::informOneObjectIsRemoved(const ewol::object::Shared<
it->onObjectRemove(_object); it->onObjectRemove(_object);
} }
} }
for (auto &it : m_removeEventList) {
it->onObjectRemove(_object);
}
// inform the context ... // inform the context ...
ewol::getContext().onObjectRemove(_object); ewol::getContext().onObjectRemove(_object);
} }
@ -136,3 +141,17 @@ ewol::object::Shared<ewol::Object> ewol::object::Manager::get(const std::string&
return nullptr; return nullptr;
} }
void ewol::object::Manager::add(ewol::object::RemoveEvent* _class) {
m_removeEventList.push_back(_class);
}
void ewol::object::Manager::rm(ewol::object::RemoveEvent* _class) {
for (size_t iii=0; iii<m_removeEventList.size(); ++iii) {
if (m_removeEventList[iii] == _class) {
m_removeEventList.erase(m_removeEventList.begin() + iii);
return;
}
}
}

View File

@ -12,11 +12,13 @@
#include <etk/types.h> #include <etk/types.h>
#include <ewol/object/Object.h> #include <ewol/object/Object.h>
#include <ewol/object/MultiCast.h> #include <ewol/object/MultiCast.h>
#include <ewol/object/RemoveEvent.h>
namespace ewol { namespace ewol {
namespace object { namespace object {
class Manager { class Manager {
private: private:
std::vector<ewol::object::RemoveEvent*> m_removeEventList;
std::vector<ewol::object::Shared<ewol::Object>> m_eObjectList; // all widget allocated == > all time increment ... never removed ... std::vector<ewol::object::Shared<ewol::Object>> m_eObjectList; // all widget allocated == > all time increment ... never removed ...
std::vector<ewol::object::Shared<ewol::Object>> m_eObjectListActive; // all active widget std::vector<ewol::object::Shared<ewol::Object>> m_eObjectListActive; // all active widget
public: public:
@ -61,6 +63,9 @@ namespace ewol {
ewol::object::MultiCast& multiCast() { ewol::object::MultiCast& multiCast() {
return m_multiCast; return m_multiCast;
}; };
void add(ewol::object::RemoveEvent* _class);
void rm(ewol::object::RemoveEvent* _class);
}; };
}; };
}; };

View File

@ -49,6 +49,7 @@ void ewol::Object::operator delete[](void* _ptr, std::size_t _sz) {
} }
void ewol::Object::autoDestroy() { void ewol::Object::autoDestroy() {
EWOL_VERBOSE("Destroy object : [" << m_valUID << "] type:" << getTypeDescription());
{ {
std::unique_lock<std::mutex> lock(m_lockRefCount); std::unique_lock<std::mutex> lock(m_lockRefCount);
if (m_isDestroyed == true) { if (m_isDestroyed == true) {
@ -114,7 +115,7 @@ ewol::Object::~Object() {
const char * const ewol::Object::getObjectType() { const char * const ewol::Object::getObjectType() {
if (m_listType.size() == 0) { if (m_listType.size() == 0) {
return "ewol::object::Shared<ewol::Object>"; return "ewol::Object";
} }
return m_listType.back(); return m_listType.back();
} }
@ -127,7 +128,7 @@ void ewol::Object::addObjectType(const char* _type) {
m_listType.push_back(_type); m_listType.push_back(_type);
} }
std::string ewol::Object::getTypeDescription() { std::string ewol::Object::getTypeDescription() {
std::string ret("ewol::object::Shared<ewol::Object>"); std::string ret("ewol::Object");
for(auto element : m_listType) { for(auto element : m_listType) {
ret += "|"; ret += "|";
ret += element; ret += element;
@ -136,7 +137,7 @@ std::string ewol::Object::getTypeDescription() {
} }
bool ewol::Object::isTypeCompatible(const std::string& _type) { bool ewol::Object::isTypeCompatible(const std::string& _type) {
if (_type == "ewol::object::Shared<ewol::Object>") { if (_type == "ewol::Object") {
return true; return true;
} }
for(auto element : m_listType) { for(auto element : m_listType) {

View File

@ -14,6 +14,7 @@
#include <vector> #include <vector>
#include <exml/exml.h> #include <exml/exml.h>
#include <mutex> #include <mutex>
#include <ewol/object/Owner.h>
#include <ewol/object/Shared.h> #include <ewol/object/Shared.h>
namespace ewol { namespace ewol {
@ -50,6 +51,7 @@ namespace ewol {
*/ */
class Object { class Object {
template<typename T> friend class ewol::object::Shared; template<typename T> friend class ewol::object::Shared;
template<typename T> friend class ewol::object::Owner;
private: private:
//! @not-in-doc //! @not-in-doc
std::mutex m_lockRefCount; std::mutex m_lockRefCount;

188
sources/ewol/object/Owner.h Normal file
View File

@ -0,0 +1,188 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD 3 clauses (see license file)
*/
#ifndef __EWOL_OBJECT_OWNER_H__
#define __EWOL_OBJECT_OWNER_H__
#include <ewol/debug.h>
namespace ewol {
namespace object {
template<typename T>
class Owner {
private:
T* m_pointer;
public:
Owner() :
m_pointer(nullptr) {
// nothing to do ...
}
Owner(T* _pointer) :
m_pointer(_pointer) {
if (m_pointer == nullptr) {
return;
}
m_pointer->objRefCountIncrement();
}
~Owner() {
reset();
}
// copy constructor
Owner(const Owner& _obj) :
m_pointer(nullptr) {
EWOL_CRITICAL("You can not user copy operator for Owner reference...");
}
// Move Constructor
Owner(Owner&& _obj) :
m_pointer(nullptr) {
// transfert pointer
m_pointer = _obj.m_pointer;
_obj.m_pointer = nullptr;
}
Owner& operator=(const Owner<T>& _obj) noexcept {
if(this == &_obj) {
return *this;
}
reset();
m_pointer = _obj.get();
if (m_pointer != nullptr) {
m_pointer->objRefCountIncrement();
}
return *this;
}
void reset() {
if (m_pointer == nullptr) {
return;
}
m_pointer->removeObject();
if (m_pointer->m_objRefCount <= 0) {
EWOL_ERROR("Object will be already removed");
} else if (m_pointer->m_objRefCount == 1) {
EWOL_ERROR("Remove object (in Owner)");
delete m_pointer;
} else {
m_pointer->objRefCountDecrement();
}
m_pointer = nullptr;
}
void resetShared() {
if (m_pointer == nullptr) {
return;
}
if (m_pointer->m_objRefCount <= 0) {
EWOL_ERROR("Object will be already removed");
} else if (m_pointer->m_objRefCount == 1) {
EWOL_ERROR("Remove object (in Owner)");
delete m_pointer;
} else {
m_pointer->objRefCountDecrement();
}
m_pointer = nullptr;
}
T* get() noexcept {
return m_pointer;
}
T* get() const noexcept {
return m_pointer;
}
T& operator*() const noexcept {
return *m_pointer;
}
T* operator->() const noexcept {
return m_pointer;
}
};
};
// section to compare Owner pointer of an object with an other
//! @not in doc
template<typename T, typename T2>
inline bool operator==(const object::Owner<T>& _obj, const object::Owner<T2>& _obj2) noexcept {
return _obj.get() == _obj2.get();
}
//! @not in doc
template<typename T2>
inline bool operator==(const object::Owner<T2>& _obj, std::nullptr_t) noexcept {
return _obj.get() == nullptr;
}
//! @not in doc
template<typename T2>
inline bool operator==(std::nullptr_t, const object::Owner<T2>& _obj) noexcept {
return _obj.get() == nullptr;
}
//! @not in doc
template<typename T, typename T2, typename = typename
std::enable_if<std::is_convertible<T*, T2*>::value>::type>
inline bool operator==(const object::Owner<T>& _obj, const T2* _obj2) noexcept {
return _obj.get() == _obj2;
}
//! @not in doc
template<typename T, typename T2, typename = typename
std::enable_if<std::is_convertible<T*, T2*>::value>::type>
inline bool operator==(const T* _obj, const object::Owner<T2>& _obj2) noexcept {
return _obj == _obj2.get();
}
//! @not in doc
template<typename T, typename T2>
inline bool operator!=(const object::Owner<T>& _obj, const object::Owner<T2>& _obj2) noexcept {
return _obj.get() != _obj2.get();
}
//! @not in doc
template<typename T>
inline bool operator!=(const object::Owner<T>& _obj, std::nullptr_t) noexcept {
return _obj.get() != nullptr;
}
//! @not in doc
template<typename T>
inline bool operator!=(std::nullptr_t, const object::Owner<T>& _obj) noexcept {
return _obj.get() != nullptr;
}
//! @not in doc
template<typename T, typename T2, typename = typename
std::enable_if<std::is_convertible<T*, T2*>::value>::type>
inline bool operator!=(const object::Owner<T>& _obj, const T2* _obj2) noexcept {
return _obj.get() != _obj2;
}
//! @not in doc
template<typename T, typename T2, typename = typename
std::enable_if<std::is_convertible<T*, T2*>::value>::type>
inline bool operator!=(const T* _obj, const object::Owner<T2>& _obj2) noexcept {
return _obj != _obj2.get();
}
//! @not in doc
template<typename T>
inline void swap(object::Owner<T>& _obj, object::Owner<T>& _obj2) noexcept {
_obj2.swap(_obj);
}
//! @not in doc
template<typename T2, typename T>
inline object::Owner<T2> static_pointer_cast(const object::Owner<T>& _obj) noexcept {
return object::Owner<T2>(_obj, static_cast<T2*>(_obj.get()));
}
//! @not in doc
template<typename T2, typename T>
inline object::Owner<T2> const_pointer_cast(const object::Owner<T>& _obj) noexcept {
return object::Owner<T2>(_obj, const_cast<T2*>(_obj.get()));
}
//! @not in doc
template<typename T2, typename T>
inline object::Owner<T2> dynamic_pointer_cast(const object::Owner<T>& _obj) noexcept {
if (T2* obj = dynamic_cast<T2*>(_obj.get())) {
return object::Owner<T2>(_obj, obj);
}
return object::Owner<T2>();
}
};
#endif

View File

@ -0,0 +1,17 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD 3 clauses (see license file)
*/
#include <ewol/object/RemoveEvent.h>
ewol::object::RemoveEvent::RemoveEvent() {
}
ewol::object::RemoveEvent::~RemoveEvent() {
}

View File

@ -0,0 +1,27 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD 3 clauses (see license file)
*/
#ifndef __EWOL_OBJECT_REMOVE_EVENT_H__
#define __EWOL_OBJECT_REMOVE_EVENT_H__
#include <etk/types.h>
#include <ewol/object/Object.h>
namespace ewol {
namespace object {
class RemoveEvent {
public:
virtual void onObjectRemove(const ewol::object::Shared<ewol::Object>& _object) = 0;
public:
RemoveEvent();
~RemoveEvent();
};
}
};
#endif

View File

@ -32,6 +32,15 @@ namespace ewol {
~Shared() { ~Shared() {
reset(); reset();
} }
// shared to private constructor
Shared(const Owner<T>& _obj) :
m_pointer(nullptr) {
m_pointer = _obj.get();
if (m_pointer == nullptr) {
return;
}
m_pointer->objRefCountIncrement();
}
// copy constructor // copy constructor
Shared(const Shared& _obj) : Shared(const Shared& _obj) :
m_pointer(nullptr) { m_pointer(nullptr) {
@ -48,6 +57,13 @@ namespace ewol {
m_pointer = _obj.m_pointer; m_pointer = _obj.m_pointer;
_obj.m_pointer = nullptr; _obj.m_pointer = nullptr;
} }
bool hasOwner() {
if (m_pointer == nullptr) {
return false;
}
return m_pointer->getRefOwner();
}
Shared& operator=(const Shared<T>& _obj) noexcept { Shared& operator=(const Shared<T>& _obj) noexcept {
if(this == &_obj) { if(this == &_obj) {
return *this; return *this;
@ -83,6 +99,9 @@ namespace ewol {
T* operator->() const noexcept { T* operator->() const noexcept {
return m_pointer; return m_pointer;
} }
operator ewol::object::Owner<T>() const noexcept {
return m_pointer;
}
template<typename T2> operator ewol::object::Shared<T2>() const noexcept { template<typename T2> operator ewol::object::Shared<T2>() const noexcept {
return m_pointer; return m_pointer;
} }
@ -127,6 +146,16 @@ namespace ewol {
inline bool operator==(const T* _obj, const object::Shared<T2>& _obj2) noexcept { inline bool operator==(const T* _obj, const object::Shared<T2>& _obj2) noexcept {
return _obj == _obj2.get(); return _obj == _obj2.get();
} }
//! @not in doc
template<typename T, typename T2>
inline bool operator==(const object::Owner<T>& _obj, const object::Shared<T2>& _obj2) noexcept {
return _obj.get() == _obj2.get();
}
//! @not in doc
template<typename T, typename T2>
inline bool operator==(const object::Shared<T>& _obj, const object::Owner<T2>& _obj2) noexcept {
return _obj.get() == _obj2.get();
}
//! @not in doc //! @not in doc
template<typename T, typename T2> template<typename T, typename T2>
@ -155,6 +184,16 @@ namespace ewol {
inline bool operator!=(const T* _obj, const object::Shared<T2>& _obj2) noexcept { inline bool operator!=(const T* _obj, const object::Shared<T2>& _obj2) noexcept {
return _obj != _obj2.get(); return _obj != _obj2.get();
} }
//! @not in doc
template<typename T, typename T2>
inline bool operator!=(const object::Owner<T>& _obj, const object::Shared<T2>& _obj2) noexcept {
return _obj.get() != _obj2.get();
}
//! @not in doc
template<typename T, typename T2>
inline bool operator!=(const object::Shared<T>& _obj, const object::Owner<T2>& _obj2) noexcept {
return _obj.get() != _obj2.get();
}
//! @not in doc //! @not in doc
template<typename T> template<typename T>

View File

@ -215,16 +215,26 @@ bool ewol::resource::Manager::release(ewol::object::Shared<ewol::Resource> _obje
*/ */
// in case of error ... // in case of error ...
void ewol::resource::Manager::onObjectRemove(const ewol::object::Shared<ewol::Object>& _removeObject) { void ewol::resource::Manager::onObjectRemove(const ewol::object::Shared<ewol::Object>& _removeObject) {
for (size_t iii=0; iii<m_resourceList.size(); ++iii) { EWOL_INFO("remove object in Manager");
if (m_resourceList[iii] == _removeObject) { for (int64_t iii = (int64_t)m_resourceListToUpdate.size()-1; iii>=0; --iii) {
EWOL_WARNING("Remove Resource that is not removed ... "); if (m_resourceListToUpdate[iii] == nullptr) {
m_resourceList[iii].reset(); continue;
} }
} if (m_resourceListToUpdate[iii]->getRefCount() >= 3) {
for (size_t iii=0; iii<m_resourceListToUpdate.size(); ++iii) { continue;
if (m_resourceListToUpdate[iii] == _removeObject) {
EWOL_WARNING("Remove Resource that is not removed .2. ");
m_resourceListToUpdate[iii].reset();
} }
m_resourceListToUpdate.erase(m_resourceListToUpdate.begin() + iii);
break;
} }
for (int64_t iii = (int64_t)m_resourceList.size()-1; iii>=0; --iii) {
if (m_resourceList[iii] == nullptr) {
continue;
}
if (m_resourceList[iii]->getRefCount() >= 2) {
continue;
}
m_resourceList.erase(m_resourceList.begin() + iii);
break;
}
} }

View File

@ -12,10 +12,11 @@
#include <etk/types.h> #include <etk/types.h>
#include <ewol/debug.h> #include <ewol/debug.h>
#include <ewol/resource/Resource.h> #include <ewol/resource/Resource.h>
#include <ewol/object/RemoveEvent.h>
namespace ewol { namespace ewol {
namespace resource { namespace resource {
class Manager { class Manager : private ewol::object::RemoveEvent {
private: private:
std::vector<ewol::object::Shared<ewol::Resource>> m_resourceList; std::vector<ewol::object::Shared<ewol::Resource>> m_resourceList;
std::vector<ewol::object::Shared<ewol::Resource>> m_resourceListToUpdate; std::vector<ewol::object::Shared<ewol::Resource>> m_resourceListToUpdate;

View File

@ -21,7 +21,7 @@ namespace ewol {
*/ */
class Container : public ewol::Widget { class Container : public ewol::Widget {
protected: protected:
ewol::object::Shared<ewol::Widget> m_subWidget; ewol::object::Owner<ewol::Widget> m_subWidget;
public: public:
/** /**
* @brief Constructor * @brief Constructor

View File

@ -22,7 +22,7 @@ namespace ewol {
*/ */
class Container2 : public ewol::Widget { class Container2 : public ewol::Widget {
protected: protected:
ewol::object::Shared<ewol::Widget> m_subWidget[2]; //!< 2 subwidget possible ewol::object::Owner<ewol::Widget> m_subWidget[2]; //!< 2 subwidget possible
int32_t m_idWidgetDisplayed; //!< current widget displayed int32_t m_idWidgetDisplayed; //!< current widget displayed
public: public:
/** /**

View File

@ -86,16 +86,10 @@ void ewol::widget::ContainerN::subWidgetRemove(ewol::object::Shared<ewol::Widget
return; return;
} }
size_t errorControl = m_subWidget.size(); size_t errorControl = m_subWidget.size();
for (size_t iii=0; iii<m_subWidget.size(); iii++) { for (auto it(m_subWidget.begin()) ; it != m_subWidget.end() ; ++it) {
if (_newWidget == m_subWidget[iii]) { if (_newWidget == *it) {
m_subWidget[iii]->removeUpperWidget(); (*it)->removeUpperWidget();
m_subWidget[iii]->removeObject(); m_subWidget.erase(it);
// no remove, this element is removed with the function onObjectRemove == > it does not exist anymore ...
if (errorControl == m_subWidget.size()) {
EWOL_CRITICAL("[" << getId() << "] {" << getObjectType() << "} The number of element might have been reduced ... == > it is not the case ==> the herited class must call the \"OnObjectRemove\" function...");
m_subWidget[iii] = nullptr;
m_subWidget.erase(m_subWidget.begin()+iii);
}
markToRedraw(); markToRedraw();
requestUpdateSize(); requestUpdateSize();
return; return;
@ -107,11 +101,11 @@ void ewol::widget::ContainerN::subWidgetUnLink(ewol::object::Shared<ewol::Widget
if (nullptr == _newWidget) { if (nullptr == _newWidget) {
return; return;
} }
for (size_t iii=0; iii<m_subWidget.size(); iii++) { for (auto it(m_subWidget.begin()) ; it != m_subWidget.end() ; ++it) {
if (_newWidget == m_subWidget[iii]) { if (_newWidget == *it) {
m_subWidget[iii]->removeUpperWidget(); (*it)->removeUpperWidget();
m_subWidget[iii] = nullptr; (*it).resetShared();
m_subWidget.erase(m_subWidget.begin()+iii); m_subWidget.erase(it);
markToRedraw(); markToRedraw();
requestUpdateSize(); requestUpdateSize();
return; return;
@ -120,38 +114,16 @@ void ewol::widget::ContainerN::subWidgetUnLink(ewol::object::Shared<ewol::Widget
} }
void ewol::widget::ContainerN::subWidgetRemoveAll() { void ewol::widget::ContainerN::subWidgetRemoveAll() {
size_t errorControl = m_subWidget.size(); for (auto it : m_subWidget) {
// the size automaticly decrement with the auto call of the onObjectRemove function if (it != nullptr) {
while (m_subWidget.size() > 0 ) { it->removeUpperWidget();
if (nullptr != m_subWidget[0]) {
m_subWidget[0]->removeUpperWidget();
m_subWidget[0]->removeObject();
// no remove, this element is removed with the function onObjectRemove == > it does not exist anymore ...
if (errorControl == m_subWidget.size()) {
EWOL_CRITICAL("[" << getId() << "] {" << getObjectType() << "} The number of element might have been reduced ... == > it is not the case ==> the herited class must call the \"OnObjectRemove\" function...");
m_subWidget[0] = nullptr;
}
} else {
EWOL_WARNING("[" << getId() << "] {" << getObjectType() << "} Must not have null pointer on the subWidget list ...");
m_subWidget.erase(m_subWidget.begin());
} }
errorControl = m_subWidget.size();
} }
m_subWidget.clear(); m_subWidget.clear();
} }
void ewol::widget::ContainerN::subWidgetRemoveAllDelayed() { void ewol::widget::ContainerN::subWidgetRemoveAllDelayed() {
// the size automaticly decrement with the auto call of the onObjectRemove function subWidgetRemoveAll();
for (size_t iii=0; iii<m_subWidget.size(); iii++) {
if (nullptr != m_subWidget[iii]) {
m_subWidget[iii]->removeUpperWidget();
m_subWidget[iii]->removeObject();
m_subWidget[iii] = nullptr;
} else {
EWOL_WARNING("[" << getId() << "] {" << getObjectType() << "} Must not have null pointer on the subWidget list ...");
}
}
m_subWidget.clear();
} }
ewol::object::Shared<ewol::Widget> ewol::widget::ContainerN::getWidgetNamed(const std::string& _widgetName) { ewol::object::Shared<ewol::Widget> ewol::widget::ContainerN::getWidgetNamed(const std::string& _widgetName) {
@ -159,10 +131,10 @@ ewol::object::Shared<ewol::Widget> ewol::widget::ContainerN::getWidgetNamed(cons
if (nullptr!=tmpUpperWidget) { if (nullptr!=tmpUpperWidget) {
return tmpUpperWidget; return tmpUpperWidget;
} }
for (size_t iii=0; iii<m_subWidget.size(); iii++) { for (auto it : m_subWidget) {
if (nullptr != m_subWidget[iii]) { if (nullptr != it) {
ewol::object::Shared<ewol::Widget> tmpWidget = m_subWidget[iii]->getWidgetNamed(_widgetName); ewol::object::Shared<ewol::Widget> tmpWidget = it->getWidgetNamed(_widgetName);
if (nullptr != tmpWidget) { if (tmpWidget != nullptr) {
return tmpWidget; return tmpWidget;
} }
} }
@ -174,11 +146,9 @@ void ewol::widget::ContainerN::onObjectRemove(const ewol::object::Shared<ewol::O
// First step call parrent : // First step call parrent :
ewol::Widget::onObjectRemove(_removeObject); ewol::Widget::onObjectRemove(_removeObject);
// second step find if in all the elements ... // second step find if in all the elements ...
for (int64_t iii=m_subWidget.size()-1; iii >= 0; iii--) { for (auto it(m_subWidget.begin()) ; it != m_subWidget.end() ; ++it) {
if(m_subWidget[iii] == _removeObject) { if(*it == _removeObject) {
EWOL_VERBOSE("[" << getId() << "] {" << getObjectType() << "} remove sizer sub Element [" << iii << "/" << m_subWidget.size()-1 << "] == > destroyed object"); m_subWidget.erase(it);
m_subWidget[iii] = nullptr;
m_subWidget.erase(m_subWidget.begin()+iii);
} }
} }
} }
@ -193,19 +163,19 @@ void ewol::widget::ContainerN::systemDraw(const ewol::DrawProperty& _displayProp
// subwidget draw // subwidget draw
ewol::DrawProperty prop = _displayProp; ewol::DrawProperty prop = _displayProp;
prop.limit(m_origin, m_size); prop.limit(m_origin, m_size);
for (int64_t iii=m_subWidget.size()-1; iii >= 0; iii--) { for (auto it : m_subWidget) {
if (nullptr != m_subWidget[iii]) { if (it != nullptr) {
m_subWidget[iii]->systemDraw(prop); it->systemDraw(prop);
} }
} }
} }
void ewol::widget::ContainerN::calculateSize(const vec2& _availlable) { void ewol::widget::ContainerN::calculateSize(const vec2& _availlable) {
m_size = _availlable; m_size = _availlable;
for (size_t iii=0; iii<m_subWidget.size(); iii++) { for (auto it : m_subWidget) {
if (nullptr != m_subWidget[iii]) { if (it != nullptr) {
m_subWidget[iii]->setOrigin(m_origin+m_offset); it->setOrigin(m_origin+m_offset);
m_subWidget[iii]->calculateSize(m_size); it->calculateSize(m_size);
} }
} }
markToRedraw(); markToRedraw();
@ -216,17 +186,17 @@ void ewol::widget::ContainerN::calculateMinMaxSize() {
m_minSize.setValue(0,0); m_minSize.setValue(0,0);
m_maxSize.setValue(ULTIMATE_MAX_SIZE,ULTIMATE_MAX_SIZE); m_maxSize.setValue(ULTIMATE_MAX_SIZE,ULTIMATE_MAX_SIZE);
//EWOL_ERROR("[" << getId() << "] {" << getObjectType() << "} set min size : " << m_minSize); //EWOL_ERROR("[" << getId() << "] {" << getObjectType() << "} set min size : " << m_minSize);
for (size_t iii=0; iii<m_subWidget.size(); iii++) { for (auto it : m_subWidget) {
if (nullptr != m_subWidget[iii]) { if (it != nullptr) {
m_subWidget[iii]->calculateMinMaxSize(); it->calculateMinMaxSize();
bvec2 subExpendProp = m_subWidget[iii]->canExpand(); bvec2 subExpendProp = it->canExpand();
if (true == subExpendProp.x()) { if (true == subExpendProp.x()) {
m_subExpend.setX(true); m_subExpend.setX(true);
} }
if (true == subExpendProp.y()) { if (true == subExpendProp.y()) {
m_subExpend.setY(true); m_subExpend.setY(true);
} }
vec2 tmpSize = m_subWidget[iii]->getCalculateMinSize(); vec2 tmpSize = it->getCalculateMinSize();
m_minSize.setValue( etk_max(tmpSize.x(), m_minSize.x()), m_minSize.setValue( etk_max(tmpSize.x(), m_minSize.x()),
etk_max(tmpSize.y(), m_minSize.y()) ); etk_max(tmpSize.y(), m_minSize.y()) );
} }
@ -235,9 +205,9 @@ void ewol::widget::ContainerN::calculateMinMaxSize() {
} }
void ewol::widget::ContainerN::onRegenerateDisplay() { void ewol::widget::ContainerN::onRegenerateDisplay() {
for (size_t iii=0; iii<m_subWidget.size(); iii++) { for (auto it : m_subWidget) {
if (nullptr != m_subWidget[iii]) { if (it != nullptr) {
m_subWidget[iii]->onRegenerateDisplay(); it->onRegenerateDisplay();
} }
} }
} }
@ -247,14 +217,14 @@ ewol::object::Shared<ewol::Widget> ewol::widget::ContainerN::getWidgetAtPos(cons
return nullptr; return nullptr;
} }
// for all element in the sizer ... // for all element in the sizer ...
for (size_t iii=0; iii<m_subWidget.size(); iii++) { for (auto it : m_subWidget) {
if (nullptr != m_subWidget[iii]) { if (it != nullptr) {
vec2 tmpSize = m_subWidget[iii]->getSize(); vec2 tmpSize = it->getSize();
vec2 tmpOrigin = m_subWidget[iii]->getOrigin(); vec2 tmpOrigin = it->getOrigin();
if( (tmpOrigin.x() <= _pos.x() && tmpOrigin.x() + tmpSize.x() >= _pos.x()) if( (tmpOrigin.x() <= _pos.x() && tmpOrigin.x() + tmpSize.x() >= _pos.x())
&& (tmpOrigin.y() <= _pos.y() && tmpOrigin.y() + tmpSize.y() >= _pos.y()) ) && (tmpOrigin.y() <= _pos.y() && tmpOrigin.y() + tmpSize.y() >= _pos.y()) )
{ {
ewol::object::Shared<ewol::Widget> tmpWidget = m_subWidget[iii]->getWidgetAtPos(_pos); ewol::object::Shared<ewol::Widget> tmpWidget = it->getWidgetAtPos(_pos);
if (nullptr != tmpWidget) { if (nullptr != tmpWidget) {
return tmpWidget; return tmpWidget;
} }

View File

@ -12,6 +12,7 @@
#include <etk/types.h> #include <etk/types.h>
#include <ewol/debug.h> #include <ewol/debug.h>
#include <ewol/widget/Widget.h> #include <ewol/widget/Widget.h>
#include <list>
namespace ewol { namespace ewol {
namespace widget { namespace widget {
@ -21,7 +22,7 @@ namespace ewol {
*/ */
class ContainerN : public ewol::Widget { class ContainerN : public ewol::Widget {
protected: protected:
std::vector<ewol::object::Shared<ewol::Widget>> m_subWidget; std::list<ewol::object::Owner<ewol::Widget>> m_subWidget;
public: public:
/** /**
* @brief Constructor * @brief Constructor

View File

@ -34,14 +34,14 @@ ewol::object::Shared<ewol::Widget> ewol::widget::Layer::getWidgetAtPos(const vec
return nullptr; return nullptr;
} }
// for all element in the sizer ... // for all element in the sizer ...
for (size_t iii=0; iii<m_subWidget.size(); iii++) { for (auto it : m_subWidget) {
if (nullptr != m_subWidget[iii]) { if (it != nullptr) {
vec2 tmpSize = m_subWidget[iii]->getSize(); vec2 tmpSize = it->getSize();
vec2 tmpOrigin = m_subWidget[iii]->getOrigin(); vec2 tmpOrigin = it->getOrigin();
if( (tmpOrigin.x() <= _pos.x() && tmpOrigin.x() + tmpSize.x() >= _pos.x()) if( (tmpOrigin.x() <= _pos.x() && tmpOrigin.x() + tmpSize.x() >= _pos.x())
&& (tmpOrigin.y() <= _pos.y() && tmpOrigin.y() + tmpSize.y() >= _pos.y()) ) && (tmpOrigin.y() <= _pos.y() && tmpOrigin.y() + tmpSize.y() >= _pos.y()) )
{ {
ewol::object::Shared<ewol::Widget> tmpWidget = m_subWidget[iii]->getWidgetAtPos(_pos); ewol::object::Shared<ewol::Widget> tmpWidget = it->getWidgetAtPos(_pos);
if (nullptr != tmpWidget) { if (nullptr != tmpWidget) {
return tmpWidget; return tmpWidget;
} }

View File

@ -65,19 +65,19 @@ void ewol::widget::Sizer::calculateSize(const vec2& _availlable) {
float unexpandableSize=0.0; float unexpandableSize=0.0;
int32_t nbWidgetFixedSize=0; int32_t nbWidgetFixedSize=0;
int32_t nbWidgetNotFixedSize=0; int32_t nbWidgetNotFixedSize=0;
for (size_t iii=0; iii<m_subWidget.size(); iii++) { for (auto it : m_subWidget) {
if (nullptr != m_subWidget[iii]) { if (it != nullptr) {
vec2 tmpSize = m_subWidget[iii]->getCalculateMinSize(); vec2 tmpSize = it->getCalculateMinSize();
if (m_mode == ewol::widget::Sizer::modeVert) { if (m_mode == ewol::widget::Sizer::modeVert) {
unexpandableSize += tmpSize.y(); unexpandableSize += tmpSize.y();
if (false == m_subWidget[iii]->canExpand().y()) { if (false == it->canExpand().y()) {
nbWidgetFixedSize++; nbWidgetFixedSize++;
} else { } else {
nbWidgetNotFixedSize++; nbWidgetNotFixedSize++;
} }
} else { } else {
unexpandableSize += tmpSize.x(); unexpandableSize += tmpSize.x();
if (false == m_subWidget[iii]->canExpand().x()) { if (false == it->canExpand().x()) {
nbWidgetFixedSize++; nbWidgetFixedSize++;
} else { } else {
nbWidgetNotFixedSize++; nbWidgetNotFixedSize++;
@ -99,27 +99,27 @@ void ewol::widget::Sizer::calculateSize(const vec2& _availlable) {
} }
} }
vec2 tmpOrigin = m_origin + tmpBorderSize; vec2 tmpOrigin = m_origin + tmpBorderSize;
for (size_t iii=0; iii<m_subWidget.size(); iii++) { for (auto it : m_subWidget) {
if (nullptr != m_subWidget[iii]) { if (it != nullptr) {
vec2 tmpSize = m_subWidget[iii]->getCalculateMinSize(); vec2 tmpSize = it->getCalculateMinSize();
// set the origin : // set the origin :
EWOL_VERBOSE("[" << getId() << "] set iii=" << iii << " ORIGIN : " << tmpOrigin << " & offset=" << m_offset); EWOL_VERBOSE("[" << getId() << "] set ORIGIN : " << tmpOrigin << " & offset=" << m_offset);
m_subWidget[iii]->setOrigin(vec2ClipInt32(tmpOrigin+m_offset)); it->setOrigin(vec2ClipInt32(tmpOrigin+m_offset));
// Now update his size his size in X and the curent sizer size in Y: // Now update his size his size in X and the curent sizer size in Y:
if (m_mode == ewol::widget::Sizer::modeVert) { if (m_mode == ewol::widget::Sizer::modeVert) {
if (true == m_subWidget[iii]->canExpand().y()) { if (it->canExpand().y() == true) {
m_subWidget[iii]->calculateSize(vec2ClipInt32(vec2(m_size.x(), tmpSize.y()+sizeToAddAtEveryOne))); it->calculateSize(vec2ClipInt32(vec2(m_size.x(), tmpSize.y()+sizeToAddAtEveryOne)));
tmpOrigin.setY(tmpOrigin.y() + tmpSize.y()+sizeToAddAtEveryOne); tmpOrigin.setY(tmpOrigin.y() + tmpSize.y()+sizeToAddAtEveryOne);
} else { } else {
m_subWidget[iii]->calculateSize(vec2ClipInt32(vec2(m_size.x(), tmpSize.y()))); it->calculateSize(vec2ClipInt32(vec2(m_size.x(), tmpSize.y())));
tmpOrigin.setY(tmpOrigin.y() + tmpSize.y()); tmpOrigin.setY(tmpOrigin.y() + tmpSize.y());
} }
} else { } else {
if (true == m_subWidget[iii]->canExpand().x()) { if (it->canExpand().x() == true) {
m_subWidget[iii]->calculateSize(vec2ClipInt32(vec2(tmpSize.x()+sizeToAddAtEveryOne, m_size.y()))); it->calculateSize(vec2ClipInt32(vec2(tmpSize.x()+sizeToAddAtEveryOne, m_size.y())));
tmpOrigin.setX(tmpOrigin.x() + tmpSize.x()+sizeToAddAtEveryOne); tmpOrigin.setX(tmpOrigin.x() + tmpSize.x()+sizeToAddAtEveryOne);
} else { } else {
m_subWidget[iii]->calculateSize(vec2ClipInt32(vec2(tmpSize.x(), m_size.y()))); it->calculateSize(vec2ClipInt32(vec2(tmpSize.x(), m_size.y())));
tmpOrigin.setX(tmpOrigin.x() + tmpSize.x()); tmpOrigin.setX(tmpOrigin.x() + tmpSize.x());
} }
} }
@ -136,18 +136,18 @@ void ewol::widget::Sizer::calculateMinMaxSize() {
vec2 tmpBorderSize = m_borderSize.getPixel(); vec2 tmpBorderSize = m_borderSize.getPixel();
EWOL_VERBOSE("[" << getId() << "] {" << getObjectType() << "} set min size : " << m_minSize); EWOL_VERBOSE("[" << getId() << "] {" << getObjectType() << "} set min size : " << m_minSize);
m_minSize += tmpBorderSize*2; m_minSize += tmpBorderSize*2;
for (int32_t iii=0; iii<m_subWidget.size(); iii++) { for (auto it : m_subWidget) {
if (nullptr != m_subWidget[iii]) { if (it != nullptr) {
m_subWidget[iii]->calculateMinMaxSize(); it->calculateMinMaxSize();
if (true == m_subWidget[iii]->canExpand().x()) { if (it->canExpand().x() == true) {
m_subExpend.setX(true); m_subExpend.setX(true);
} }
if (true == m_subWidget[iii]->canExpand().y()) { if (it->canExpand().y() == true) {
m_subExpend.setY(true); m_subExpend.setY(true);
} }
vec2 tmpSize = m_subWidget[iii]->getCalculateMinSize(); vec2 tmpSize = it->getCalculateMinSize();
EWOL_VERBOSE("[" << getId() << "] NewMinSize=" << tmpSize); EWOL_VERBOSE("[" << getId() << "] NewMinSize=" << tmpSize);
EWOL_VERBOSE("[" << getId() << "] {" << getObjectType() << "} Get minSize[" << iii << "] "<< tmpSize); EWOL_VERBOSE("[" << getId() << "] {" << getObjectType() << "} Get minSize="<< tmpSize);
if (m_mode == ewol::widget::Sizer::modeVert) { if (m_mode == ewol::widget::Sizer::modeVert) {
m_minSize.setY(m_minSize.y() + tmpSize.y()); m_minSize.setY(m_minSize.y() + tmpSize.y());
if (tmpSize.x()>m_minSize.x()) { if (tmpSize.x()>m_minSize.x()) {

View File

@ -133,7 +133,7 @@ ewol::Widget::Widget() :
m_annimationType[1] = nullptr; m_annimationType[1] = nullptr;
m_annimationTime[0] = 0.1f; // annimation will be 100ms at the first state m_annimationTime[0] = 0.1f; // annimation will be 100ms at the first state
m_annimationTime[1] = 0.1f; // annimation will be 100ms at the first state m_annimationTime[1] = 0.1f; // annimation will be 100ms at the first state
addObjectType("ewol::object::Shared<ewol::Widget>"); addObjectType("ewol::Widget");
// set all the config in the list : // set all the config in the list :
registerConfig(ewol::Widget::configFill, "bvec2", nullptr, "Fill the widget available size"); registerConfig(ewol::Widget::configFill, "bvec2", nullptr, "Fill the widget available size");
registerConfig(ewol::Widget::configExpand, "bvec2", nullptr, "Request the widget Expand size wile space is available"); registerConfig(ewol::Widget::configExpand, "bvec2", nullptr, "Request the widget Expand size wile space is available");
@ -171,8 +171,9 @@ void ewol::Widget::setUpperWidget(ewol::object::Shared<ewol::Widget> _upper) {
m_up = _upper; m_up = _upper;
} }
void ewol::Widget::onObjectRemove(const ewol::object::Shared<ewol::Object>& _removeObject) { void ewol::Widget::onObjectRemove(const ewol::object::Shared<ewol::Object>& _object) {
if (_removeObject == m_up) { ewol::Object::onObjectRemove(_object);
if (_object == m_up) {
EWOL_WARNING("[" << getId() << "] remove upper widget before removing this widget ..."); EWOL_WARNING("[" << getId() << "] remove upper widget before removing this widget ...");
m_up = nullptr; m_up = nullptr;
} }

View File

@ -56,8 +56,8 @@ namespace ewol {
m_hasDecoration = true; m_hasDecoration = true;
} }
private: private:
ewol::object::Shared<ewol::Widget> m_subWidget; ewol::object::Owner<ewol::Widget> m_subWidget;
std::vector<ewol::object::Shared<ewol::Widget>> m_popUpWidgetList; std::vector<ewol::object::Owner<ewol::Widget>> m_popUpWidgetList;
public: public:
void setSubWidget(ewol::object::Shared<ewol::Widget> _widget); void setSubWidget(ewol::object::Shared<ewol::Widget> _widget);
void popUpWidgetPush(ewol::object::Shared<ewol::Widget> _widget); void popUpWidgetPush(ewol::object::Shared<ewol::Widget> _widget);

View File

@ -93,7 +93,8 @@ def create(target):
'ewol/object/Manager.cpp', 'ewol/object/Manager.cpp',
'ewol/object/Message.cpp', 'ewol/object/Message.cpp',
'ewol/object/MultiCast.cpp', 'ewol/object/MultiCast.cpp',
'ewol/object/Object.cpp' 'ewol/object/Object.cpp',
'ewol/object/RemoveEvent.cpp'
]) ])
# OpenGL interface : # OpenGL interface :