From c2b7cedb8c58e4cff9be65a14cd70f4eacb4348c Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Tue, 28 May 2013 21:18:45 +0200 Subject: [PATCH] [DEV] add a system for stadard user global config saving --- sources/ewol/UserConfig.cpp | 206 ++++++++++++++++++++++++ sources/ewol/UserConfig.h | 32 ++++ sources/ewol/eObject/EObject.cpp | 3 +- sources/ewol/eObject/EObject.h | 8 + sources/ewol/eObject/EObjectManager.cpp | 17 +- sources/ewol/ewol.cpp | 2 + sources/ewol/widget/Label.cpp | 1 + sources/ewol/widget/Menu.cpp | 41 ++++- sources/ewol/widget/WSlider.cpp | 2 +- sources/ewol/widget/WSlider.h | 19 ++- sources/ewol/widget/meta/Parameter.cpp | 45 ++++-- sources/ewol/widget/meta/Parameter.h | 1 - sources/lutin_ewol.py | 3 +- 13 files changed, 351 insertions(+), 29 deletions(-) create mode 100644 sources/ewol/UserConfig.cpp create mode 100644 sources/ewol/UserConfig.h diff --git a/sources/ewol/UserConfig.cpp b/sources/ewol/UserConfig.cpp new file mode 100644 index 00000000..c1a112a7 --- /dev/null +++ b/sources/ewol/UserConfig.cpp @@ -0,0 +1,206 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + + +#include +#include +#include +#include + +class UserConfig : public ewol::EObject +{ + private: + etk::Vector m_list; + etk::UString m_fileName; + public: + UserConfig(void) : m_fileName("USERDATA:generalConfig.xml") + { + m_static = true; // Note : Set the object static notification( Must be set or assert at the end of process) + }; + ~UserConfig(void) { m_list.Clear(); }; + etk::Vector& List(void) { return m_list; }; + etk::UString& FileName(void) { return m_fileName; }; + + void OnObjectRemove(ewol::EObject * _removeObject) + { + for( int32_t iii=m_list.Size()-1 ; iii>=0 ; iii--) { + if (m_list[iii] == _removeObject) { + m_list.Erase(iii); + } + } + }; +}; + + +static UserConfig& l_obj(void) +{ + static UserConfig s_obj; + return s_obj; +} + + +void ewol::userConfig::Init(void) +{ + +} + +void ewol::userConfig::UnInit(void) +{ + +} + + +const ewol::EObject* ewol::userConfig::GetUserConfig(const etk::UString& _name) +{ + if (_name == "") { + return NULL; + } + for (int32_t iii=0; iiiGetName() == _name) { + return l_obj().List()[iii]; + } + } + } + return NULL; +} + +void ewol::userConfig::AddUserConfig(ewol::EObject* _newConfig) +{ + if (_newConfig == NULL) { + return; + } + for (int32_t iii=0; iiiFirstChild(); + NULL != pNode; + pNode = pNode->NextSibling() ) { + if (pNode->Type()==TiXmlNode::TINYXML_COMMENT) { + // nothing to do, just proceed to next step + } else { + bool elementFound = false; + for (int32_t iii=0; iiiGetName() == pNode->Value()) { + l_obj().List()[iii]->LoadXML(pNode); + elementFound = true; + break; + } + } + } + if (elementFound==false) { + EWOL_ERROR("(l "<Row()<<") node not suported : \""<Value()); + } + } + } + if (NULL != fileBuffer) { + delete[] fileBuffer; + } + return true; +} + +#define MAX_SAVING_FILE_HISTORY (9) + +bool ewol::userConfig::Save(void) +{ + // step 1 : Move the file to prevent writing error + //Get the first oldest save : + for (int32_t iii=MAX_SAVING_FILE_HISTORY-1; iii>0 ; iii--) { + if (true==etk::FSNodeExist(l_obj().FileName()+"-"+iii) ) { + etk::FSNodeMove(l_obj().FileName()+"-"+iii,l_obj().FileName()+"-"+(iii+1)); + } + } + if (true==etk::FSNodeExist(l_obj().FileName()) ) { + etk::FSNodeMove(l_obj().FileName(),l_obj().FileName()+"-1"); + } + // basic create file: + etk::FSNode myNode(l_obj().FileName()); + // create basic folders ... + myNode.Touch(); + etk::UString tmpCompleateName = myNode.GetFileSystemName(); + // step 2 : save the file + TiXmlDocument doc; + TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "UTF-8", ""); + doc.LinkEndChild(decl); + TiXmlElement * ElementBase = new TiXmlElement("config"); + doc.LinkEndChild(ElementBase); + for (int32_t iii=0; iiiGetName().Size() != 0) { + TiXmlElement * element = new TiXmlElement(l_obj().List()[iii]->GetName().c_str()); + if (NULL != element) { + l_obj().List()[iii]->StoreXML(element); + ElementBase->LinkEndChild(element); + } + } + } + } + //Save Document + doc.SaveFile( tmpCompleateName.c_str() ); + EWOL_DEBUG("Save in file : " << tmpCompleateName); + // step 3 : Remove oldest save + return true; +} + + diff --git a/sources/ewol/UserConfig.h b/sources/ewol/UserConfig.h new file mode 100644 index 00000000..ba3aaaf4 --- /dev/null +++ b/sources/ewol/UserConfig.h @@ -0,0 +1,32 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __EWOL_USER_CONFIG_H__ +#define __EWOL_USER_CONFIG_H__ + +#include +#include +#include + +namespace ewol +{ + namespace userConfig + { + void Init(void); + void UnInit(void); + const ewol::EObject* GetUserConfig(const etk::UString& _name); + void AddUserConfig(ewol::EObject* _newConfig); + //void RmUserConfig(ewol::EObject* _newConfig); // note : To remove user config ==> just destroy it ==> simple .. + void SetConfigName(const etk::UString& _fileName="USERDATA:generalConfig.xml"); + bool Load(void); + bool Save(void); + }; +}; + +#endif + diff --git a/sources/ewol/eObject/EObject.cpp b/sources/ewol/eObject/EObject.cpp index 30e5b5c3..2b08655a 100644 --- a/sources/ewol/eObject/EObject.cpp +++ b/sources/ewol/eObject/EObject.cpp @@ -104,7 +104,8 @@ void ewol::EObjectMessageMultiCast::AnonymousSend(const char* const _messageId, const char* const ewol::EObject::configName = "name"; -ewol::EObject::EObject(void) +ewol::EObject::EObject(void) : + m_static(false) { static int32_t ss_globalUniqueId = 0; // note this is nearly atomic ... (but it is enough) diff --git a/sources/ewol/eObject/EObject.h b/sources/ewol/eObject/EObject.h index 02f9a116..94ff0a42 100644 --- a/sources/ewol/eObject/EObject.h +++ b/sources/ewol/eObject/EObject.h @@ -48,6 +48,8 @@ namespace ewol { public: // Config list of properties static const char* const configName; + protected: + bool m_static; //!< set this variable at true if this element must not be auto destroy (exemple : use static object) private: int32_t m_uniqueId; //!< Object UniqueID ==> TODO : Check if it use is needed etk::Vector m_externEvent; //!< Generic list of event generation for output link @@ -63,6 +65,12 @@ namespace ewol { */ virtual ~EObject(void); + /** + * @brief Get the static status of the EObject ==> mark at true if the user set the object mark as static allocated element ==> not auto remove element + * @return true if it might not be removed ==> usefull for conficuration class + */ + bool GetStatic(void){ return m_static; }; + /** * @brief Get the UniqueId of the EObject * @return the requested ID diff --git a/sources/ewol/eObject/EObjectManager.cpp b/sources/ewol/eObject/EObjectManager.cpp index d688ca66..8d08b6b0 100644 --- a/sources/ewol/eObject/EObjectManager.cpp +++ b/sources/ewol/eObject/EObjectManager.cpp @@ -35,13 +35,18 @@ void ewol::EObjectManager::UnInit(void) EWOL_DEBUG("==> Un-Init EObject-Manager"); RemoveAllAutoRemove(); EWOL_INFO(" Remove missing user widget"); - while(0GetObjectType() << "\""); - delete(m_eObjectList[0]); - m_eObjectList[0] = NULL; + int32_t iii=0; + while(iiiGetStatic() == true) { + iii++; + } else { + EWOL_WARNING("Un-INIT : Remove EObject type=\"" << m_eObjectList[iii]->GetObjectType() << "\""); + delete(m_eObjectList[iii]); + m_eObjectList[iii] = NULL; + } } else { - m_eObjectList.Erase(0); + m_eObjectList.Erase(iii); } } diff --git a/sources/ewol/ewol.cpp b/sources/ewol/ewol.cpp index c8c4ef8c..9512583e 100644 --- a/sources/ewol/ewol.cpp +++ b/sources/ewol/ewol.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #undef __class__ #define __class__ "ewol" @@ -31,6 +32,7 @@ int32_t ewol::Run(int32_t argc, const char* argv[]) } // init display convertions: ewol::dimension::Init(); + ewol::userConfig::Init(); EWOL_DEBUG("Store commangLine in the specific system"); ewol::commandLine::Clean(); diff --git a/sources/ewol/widget/Label.cpp b/sources/ewol/widget/Label.cpp index 9b66b98c..c259be59 100644 --- a/sources/ewol/widget/Label.cpp +++ b/sources/ewol/widget/Label.cpp @@ -145,5 +145,6 @@ bool widget::Label::LoadXML(TiXmlNode* _node) // TODO : Unparse data type XML ... EWOL_DEBUG("Load label:" << _node->ToElement()->GetText()); SetLabel(_node->ToElement()->GetText()); + EWOL_ERROR(" parse text : \"" << m_label << "\""); return true; } diff --git a/sources/ewol/widget/Menu.cpp b/sources/ewol/widget/Menu.cpp index 1f825f57..9794f85e 100644 --- a/sources/ewol/widget/Menu.cpp +++ b/sources/ewol/widget/Menu.cpp @@ -181,6 +181,17 @@ void widget::Menu::OnReceiveMessage(const ewol::EMessage& _msg) // set it in the pop-up-system : m_widgetContextMenu->SetSubWidget(mySizer); + bool menuHaveImage = false; + for(int32_t jjj=m_listElement.Size()-1; jjj>=0; jjj--) { + if (m_listElement[iii]!=NULL) { + if (m_listElement[iii]->m_localId == m_listElement[jjj]->m_parentId) { + if (m_listElement[jjj]->m_image.Size()!=0) { + menuHaveImage = true; + break; + } + } + } + } for(int32_t jjj=m_listElement.Size()-1; jjj>=0; jjj--) { if (m_listElement[iii]!=NULL) { if (m_listElement[iii]->m_localId == m_listElement[jjj]->m_parentId) { @@ -188,17 +199,33 @@ void widget::Menu::OnReceiveMessage(const ewol::EMessage& _msg) if (NULL == myButton) { EWOL_ERROR("Allocation Error"); } else { - /*if (m_listElement[jjj]->m_image.Size()!=0) { + if (m_listElement[jjj]->m_image.Size()!=0) { myButton->SetSubWidget( new widget::Composer(widget::Composer::String, - etk::UString("\n") + - " \n" + etk::UString("\n") + + " \n" " m_image + "\" size=\"8,8mm\"/>\n" - " \n" + " \n" " \n" - "SetSubWidget( new widget::Label(etk::UString("") + m_listElement[jjj]->m_label + "") ); + "\n")); + } else { + if (true == menuHaveImage) { + myButton->SetSubWidget( + new widget::Composer(widget::Composer::String, + etk::UString("\n") + + " \n" + " \n" + " \n" + " \n" + "\n")); + } else { + widget::Label* tmpLabel = new widget::Label(etk::UString("") + m_listElement[jjj]->m_label + ""); + if (NULL != tmpLabel) { + tmpLabel->SetExpand(bvec2(true,false)); + tmpLabel->SetFill(bvec2(true,true)); + myButton->SetSubWidget(tmpLabel); + } + } } // set the image if one is present ... myButton->RegisterOnEvent(this, widget::Button::eventPressed, widget::Button::eventPressed); diff --git a/sources/ewol/widget/WSlider.cpp b/sources/ewol/widget/WSlider.cpp index 9bf6ff5a..16625264 100644 --- a/sources/ewol/widget/WSlider.cpp +++ b/sources/ewol/widget/WSlider.cpp @@ -189,7 +189,7 @@ void widget::WSlider::PeriodicCall(int64_t _localTime) } else { if (m_lastPeriodicCall != -1) { float delta = (double)(_localTime - m_lastPeriodicCall)/1000000.0; - m_slidingProgress += m_transitionSpeed*delta; + m_slidingProgress += delta/m_transitionSpeed; m_slidingProgress = etk_avg(0.0f, m_slidingProgress, 1.0f); } m_lastPeriodicCall = _localTime; diff --git a/sources/ewol/widget/WSlider.h b/sources/ewol/widget/WSlider.h index e9d30442..bb3ee482 100644 --- a/sources/ewol/widget/WSlider.h +++ b/sources/ewol/widget/WSlider.h @@ -38,8 +38,6 @@ namespace widget { int32_t m_windowsDestination; //!< widget destinated viewed float m_slidingProgress; //!< ratio progression of a sliding int64_t m_lastPeriodicCall; - float m_transitionSpeed; //!< speed of the transition (default 1 ==> 1s) - sladingMode_te m_transitionSlide; //!< mode to slide the widgets public: /** * @brief Select a new subwidget to display @@ -56,6 +54,22 @@ namespace widget { * @param[in] _widgetName Name of the subwidget name */ void SubWidgetSelectSet(const etk::UString& _widgetName); + private: + float m_transitionSpeed; //!< speed of the transition (default 1 ==> 1s) + public: + /** + * @brief Set transition speed element. + * @param[in] _timeSecond number of second needed to do the transition. + */ + void SetTransitionSpeed(float _timeSecond) { m_transitionSpeed = _timeSecond; }; + /** + * @brief Get transition speed element. + * @return number of second needed to do the transition. + */ + float GetTransitionSpeed(void) { return m_transitionSpeed; }; + private: + sladingMode_te m_transitionSlide; //!< mode to slide the widgets + public: /** * @brief Set a new mode of sliding element * @param[in] _mode new display mode @@ -66,7 +80,6 @@ namespace widget { * @return The current sliding mode */ sladingMode_te GetTransitionMode(void) { return m_transitionSlide; }; - public: // Derived function virtual const char * const GetObjectType(void) { return "Ewol::WSlider"; }; virtual void CalculateSize(const vec2& _availlable); diff --git a/sources/ewol/widget/meta/Parameter.cpp b/sources/ewol/widget/meta/Parameter.cpp index d5fb5be0..fc1ebc3c 100644 --- a/sources/ewol/widget/meta/Parameter.cpp +++ b/sources/ewol/widget/meta/Parameter.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -24,13 +25,13 @@ extern const char * const ewolEventParameterValidate = "ewol-event-parameter-validate"; extern const char * const ewolEventParameterClose = "ewol-event-parameter-close"; +extern const char * const ewolEventParameterSave = "ewol-event-parameter-save"; static const char * const l_eventMenuSelected = "local-event-menu-selected"; widget::Parameter::Parameter(void) : m_currentIdList(0), m_widgetTitle(NULL), - m_widgetCancel(NULL), m_paramList(NULL) { AddEventId(ewolEventParameterClose); @@ -68,11 +69,36 @@ widget::Parameter::Parameter(void) : mySizerHori->SubWidgetAdd(mySpacer); } - m_widgetCancel = new widget::Button(); - if (NULL == m_widgetCancel) { + widget::Button* tmpButton = new widget::Button(); + if (NULL == tmpButton) { EWOL_ERROR("Can not allocate widget ==> display might be in error"); } else { - m_widgetCancel->SetSubWidget( + tmpButton->SetSubWidget( + new widget::Composer(widget::Composer::String, + "\n" + " \n" + " \n" + " \n" + " \n" + "RegisterOnEvent(this, widget::Button::eventPressed, ewolEventParameterSave); + mySizerHori->SubWidgetAdd(tmpButton); + } + + mySpacer = new widget::Spacer(); + if (NULL == mySpacer) { + EWOL_ERROR("Can not allocate widget ==> display might be in error"); + } else { + mySpacer->SetExpand(bvec2(false,false)); + mySpacer->SetMinSize(ewol::Dimension(vec2(10,0))); + mySizerHori->SubWidgetAdd(mySpacer); + } + + tmpButton = new widget::Button(); + if (NULL == tmpButton) { + EWOL_ERROR("Can not allocate widget ==> display might be in error"); + } else { + tmpButton->SetSubWidget( new widget::Composer(widget::Composer::String, "\n" " \n" @@ -80,8 +106,8 @@ widget::Parameter::Parameter(void) : " \n" " \n" "RegisterOnEvent(this, widget::Button::eventPressed, ewolEventParameterClose); - mySizerHori->SubWidgetAdd(m_widgetCancel); + tmpButton->RegisterOnEvent(this, widget::Button::eventPressed, ewolEventParameterClose); + mySizerHori->SubWidgetAdd(tmpButton); } } @@ -131,6 +157,8 @@ widget::Parameter::Parameter(void) : if (NULL == m_wSlider) { EWOL_ERROR("Can not allocate widget ==> display might be in error"); } else { + m_wSlider->SetTransitionSpeed(0.5); + m_wSlider->SetTransitionMode(widget::WSlider::sladingTransitionVert); m_wSlider->SetExpand(bvec2(true,true)); mySizerVert2->SubWidgetAdd(m_wSlider); } @@ -184,6 +212,8 @@ void widget::Parameter::OnReceiveMessage(const ewol::EMessage& _msg) GenerateEventId(ewolEventParameterClose); // Close this widget ... AutoDestroy(); + } else if (_msg.GetMessage() == ewolEventParameterSave) { + ewol::userConfig::Save(); } else if (_msg.GetMessage() == l_eventMenuSelected) { if (NULL != m_wSlider) { int32_t value = 0; @@ -208,9 +238,6 @@ void widget::Parameter::OnObjectRemove(ewol::EObject * removeObject) if(removeObject == m_paramList) { m_paramList = NULL; } - if(removeObject == m_widgetCancel) { - m_widgetCancel = NULL; - } if(removeObject == m_wSlider) { m_wSlider = NULL; } diff --git a/sources/ewol/widget/meta/Parameter.h b/sources/ewol/widget/meta/Parameter.h index 4051d35d..7e7c0934 100644 --- a/sources/ewol/widget/meta/Parameter.h +++ b/sources/ewol/widget/meta/Parameter.h @@ -43,7 +43,6 @@ namespace widget { private: int32_t m_currentIdList; widget::Label* m_widgetTitle; - widget::Button* m_widgetCancel; widget::ParameterList* m_paramList; widget::WSlider* m_wSlider; }; diff --git a/sources/lutin_ewol.py b/sources/lutin_ewol.py index 33692d02..300d3305 100755 --- a/sources/lutin_ewol.py +++ b/sources/lutin_ewol.py @@ -18,7 +18,8 @@ def Create(target): 'ewol/commandLine.cpp', 'ewol/key.cpp', 'ewol/cursor.cpp', - 'ewol/Dimension.cpp']) + 'ewol/Dimension.cpp', + 'ewol/UserConfig.cpp']) # Basic Eobject of EWOL myModule.AddSrcFile([