From 74a1a39d8c78294268bfb773bf67dd3dc5ea63d9 Mon Sep 17 00:00:00 2001 From: Edouard Dupin Date: Fri, 17 Feb 2012 18:26:47 +0100 Subject: [PATCH] Menu dev OK and change the thread system. add the safe remove of the widgets --- Sources/libetk/Android.mk | 3 +- Sources/libetk/Linux.mk | 3 +- Sources/libewol/Android.mk | 3 +- Sources/libewol/Linux.mk | 3 +- Sources/libewol/ewol/FontFreeType.cpp | 154 ++++++++++-------- Sources/libewol/ewol/Widget.h | 2 + Sources/libewol/ewol/WidgetManager.cpp | 76 ++++++++- Sources/libewol/ewol/WidgetManager.h | 45 ++--- .../libewol/ewol/WidgetMessageMultiCast.cpp | 2 +- Sources/libewol/ewol/WidgetMessageMultiCast.h | 2 +- Sources/libewol/ewol/Windows.cpp | 83 ++++++---- Sources/libewol/ewol/Windows.h | 8 +- Sources/libewol/ewol/base/MainThread.cpp | 31 +++- Sources/libewol/ewol/base/gui.cpp | 10 +- Sources/libewol/ewol/ewol.h | 3 +- Sources/libewol/ewol/widget/Button.cpp | 22 ++- Sources/libewol/ewol/widget/Button.h | 19 ++- Sources/libewol/ewol/widget/ContextMenu.cpp | 60 ++++++- Sources/libewol/ewol/widget/List.cpp | 25 +-- Sources/libewol/ewol/widget/Menu.cpp | 101 +++++++++++- Sources/libewol/ewol/widget/Menu.h | 4 + Sources/libewol/ewol/widget/PopUp.cpp | 3 +- Sources/libewol/ewol/widget/SizerHori.cpp | 5 +- Sources/libewol/ewol/widget/SizerVert.cpp | 5 +- .../libewol/ewol/widget/WidgetScrolled.cpp | 4 +- .../libewol/ewol/widgetMeta/FileChooser.cpp | 4 +- Sources/libewol/ewol/widgetMeta/Keyboard.cpp | 5 + 27 files changed, 503 insertions(+), 182 deletions(-) diff --git a/Sources/libetk/Android.mk b/Sources/libetk/Android.mk index 22e95565..76d9e2f3 100644 --- a/Sources/libetk/Android.mk +++ b/Sources/libetk/Android.mk @@ -15,8 +15,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) LOCAL_CFLAGS := -D__PLATFORM__Android \ -Wno-write-strings \ -DDATA_IN_APK \ - -DETK_DEBUG_LEVEL=3 \ - -std=c++0x + -DETK_DEBUG_LEVEL=3 diff --git a/Sources/libetk/Linux.mk b/Sources/libetk/Linux.mk index 7caa4dea..08557d32 100644 --- a/Sources/libetk/Linux.mk +++ b/Sources/libetk/Linux.mk @@ -15,8 +15,7 @@ LOCAL_CFLAGS := -D__PLATFORM__Linux \ -DETK_DEBUG_LEVEL=3 \ -DEWOL_DEBUG_LEVEL=3 \ -DEWOL_VERSION_TAG_NAME="\"UNKNOW-debug\"" \ - -DVERSION_BUILD_TIME="\"pasd_heure\"" \ - -std=c++0x + -DVERSION_BUILD_TIME="\"pasd_heure\"" # load the common sources file of the platform include $(LOCAL_PATH)/file.mk diff --git a/Sources/libewol/Android.mk b/Sources/libewol/Android.mk index 3ad4792e..25fa28ad 100644 --- a/Sources/libewol/Android.mk +++ b/Sources/libewol/Android.mk @@ -18,8 +18,7 @@ LOCAL_CFLAGS := -D__PLATFORM__Android \ -DEWOL_VERSION_TAG_NAME="\"UNKNOW-debug\"" \ -DVERSION_BUILD_TIME="\"pasd_heure\"" \ -DEWOL_USE_FREE_TYPE \ - -DDATA_IN_APK \ - -std=c++0x + -DDATA_IN_APK # load the common sources file of the platform include $(LOCAL_PATH)/file.mk diff --git a/Sources/libewol/Linux.mk b/Sources/libewol/Linux.mk index d8a82aae..393842cc 100644 --- a/Sources/libewol/Linux.mk +++ b/Sources/libewol/Linux.mk @@ -16,8 +16,7 @@ LOCAL_CFLAGS := -D__PLATFORM__Linux \ -DEWOL_DEBUG_LEVEL=3 \ -DEWOL_VERSION_TAG_NAME="\"UNKNOW-debug\"" \ -DVERSION_BUILD_TIME="\"pasd_heure\"" \ - -DEWOL_USE_FREE_TYPE \ - -std=c++0x + -DEWOL_USE_FREE_TYPE # `pkg-config --cflags freetype2` diff --git a/Sources/libewol/ewol/FontFreeType.cpp b/Sources/libewol/ewol/FontFreeType.cpp index 258c4b11..eebac918 100644 --- a/Sources/libewol/ewol/FontFreeType.cpp +++ b/Sources/libewol/ewol/FontFreeType.cpp @@ -654,71 +654,95 @@ int32_t ewol::DrawText(int32_t fontID, // update texture start X Pos tuB -= addElement; } - /* Bitmap position - * 0------1 - * | | - * | | - * 3------2 - */ - coord2D_ts bitmapDrawPos[4]; - bitmapDrawPos[0].x = dxA; - bitmapDrawPos[1].x = dxB; - bitmapDrawPos[2].x = dxB; - bitmapDrawPos[3].x = dxA; - - bitmapDrawPos[0].y = dyC; - bitmapDrawPos[1].y = dyC; - bitmapDrawPos[2].y = dyD; - bitmapDrawPos[3].y = dyD; - /* texture Position : - * 0------1 - * | | - * | | - * 3------2 - */ - texCoord_ts texturePos[4]; - texturePos[0].u = tuA; - texturePos[1].u = tuB; - texturePos[2].u = tuB; - texturePos[3].u = tuA; - - texturePos[0].v = tvC; - texturePos[1].v = tvC; - texturePos[2].v = tvD; - texturePos[3].v = tvD; - - // NOTE : Android does not support the Quads elements ... - /* Step 1 : - * ******** - * ****** - * **** - * ** - * - */ - // set texture coordonates : - coordTex.PushBack(texturePos[0]); - coordTex.PushBack(texturePos[1]); - coordTex.PushBack(texturePos[2]); - // set display positions : - coord.PushBack(bitmapDrawPos[0]); - coord.PushBack(bitmapDrawPos[1]); - coord.PushBack(bitmapDrawPos[2]); - - /* Step 2 : - * - * ** - * **** - * ****** - * ******** - */ - // set texture coordonates : - coordTex.PushBack(texturePos[0]); - coordTex.PushBack(texturePos[2]); - coordTex.PushBack(texturePos[3]); - // set display positions : - coord.PushBack(bitmapDrawPos[0]); - coord.PushBack(bitmapDrawPos[2]); - coord.PushBack(bitmapDrawPos[3]); + etkFloat_t TexSizeY = tvD - tvC; + if (dyC < drawClipping.y) { + // clip display + etkFloat_t drawSize = drawClipping.y - dyC; + // Update element start display + dyC = drawClipping.y; + etkFloat_t addElement = TexSizeY * drawSize / listOfElement[charIndex].size.y; + // update texture start X Pos + tvC += addElement; + } + if (dyD > drawClipping.y + drawClipping.h) { + // clip display + etkFloat_t drawSize = dyD - (drawClipping.y + drawClipping.h); + // Update element start display + dyD = drawClipping.y + drawClipping.h; + etkFloat_t addElement = TexSizeX * drawSize / listOfElement[charIndex].size.y; + // update texture start X Pos + tvD -= addElement; + } + if( dxB <= dxA + || dyD <= dyC) { + // nothing to do ... + } else { + /* Bitmap position + * 0------1 + * | | + * | | + * 3------2 + */ + coord2D_ts bitmapDrawPos[4]; + bitmapDrawPos[0].x = dxA; + bitmapDrawPos[1].x = dxB; + bitmapDrawPos[2].x = dxB; + bitmapDrawPos[3].x = dxA; + + bitmapDrawPos[0].y = dyC; + bitmapDrawPos[1].y = dyC; + bitmapDrawPos[2].y = dyD; + bitmapDrawPos[3].y = dyD; + /* texture Position : + * 0------1 + * | | + * | | + * 3------2 + */ + texCoord_ts texturePos[4]; + texturePos[0].u = tuA; + texturePos[1].u = tuB; + texturePos[2].u = tuB; + texturePos[3].u = tuA; + + texturePos[0].v = tvC; + texturePos[1].v = tvC; + texturePos[2].v = tvD; + texturePos[3].v = tvD; + + // NOTE : Android does not support the Quads elements ... + /* Step 1 : + * ******** + * ****** + * **** + * ** + * + */ + // set texture coordonates : + coordTex.PushBack(texturePos[0]); + coordTex.PushBack(texturePos[1]); + coordTex.PushBack(texturePos[2]); + // set display positions : + coord.PushBack(bitmapDrawPos[0]); + coord.PushBack(bitmapDrawPos[1]); + coord.PushBack(bitmapDrawPos[2]); + + /* Step 2 : + * + * ** + * **** + * ****** + * ******** + */ + // set texture coordonates : + coordTex.PushBack(texturePos[0]); + coordTex.PushBack(texturePos[2]); + coordTex.PushBack(texturePos[3]); + // set display positions : + coord.PushBack(bitmapDrawPos[0]); + coord.PushBack(bitmapDrawPos[2]); + coord.PushBack(bitmapDrawPos[3]); + } } } posDrawX += listOfElement[charIndex].advance; diff --git a/Sources/libewol/ewol/Widget.h b/Sources/libewol/ewol/Widget.h index f95094f6..d2228bb7 100644 --- a/Sources/libewol/ewol/Widget.h +++ b/Sources/libewol/ewol/Widget.h @@ -133,6 +133,8 @@ namespace ewol { ewol::Widget * m_parrent; //!< parrent of the current widget (if NULL ==> this is the main node(root)) public: void SetParrent(ewol::Widget * newParrent) { m_parrent = newParrent; }; + void UnlinkParrent(void) { if (NULL != m_parrent) { m_parrent->removedChild(this); m_parrent=NULL; } }; + virtual void removedChild(ewol::Widget * removedChild) { }; // ---------------------------------------------------------------------------------------------------------------- // -- Widget Size: diff --git a/Sources/libewol/ewol/WidgetManager.cpp b/Sources/libewol/ewol/WidgetManager.cpp index 901bc2b2..dc07a890 100644 --- a/Sources/libewol/ewol/WidgetManager.cpp +++ b/Sources/libewol/ewol/WidgetManager.cpp @@ -38,7 +38,8 @@ static pthread_mutex_t localMutex; // internal element of the widget manager : -static etk::VectorType m_widgetList; // all widget allocated ==> all time increment ... never removed ... +static etk::VectorType m_widgetList; // all widget allocated ==> all time increment ... never removed ... +static etk::VectorType m_widgetDeletedList; // all widget allocated // For the focus Management static ewol::Widget * m_focusWidgetDefault = NULL; static ewol::Widget * m_focusWidgetCurrent = NULL; @@ -102,6 +103,17 @@ void ewol::widgetManager::Rm(ewol::Widget * newWidget) FocusRemoveIfRemove(newWidget); // Remove Element m_widgetList.Erase(iii); + EWOL_CRITICAL("Widget direct remove is really DANGEROUS due to the multithreading ..."); + return; + } + } + for (int32_t iii=0; iiiUnlinkParrent(); + // add ... + m_widgetDeletedList.PushBack(tmpWidgetProperty); +} + +void ewol::widgetManager::RemoveAllMarkWidget(void) +{ + etk::VectorType m_widgetDeletedList_tmp = m_widgetDeletedList; + pthread_mutex_lock(&localMutex); + // flip/Flop all the widget registered : + for(int32_t iii=0; iii not all the widget are auto-removed"); + // in every case clean the list ... + m_widgetDeletedList.Clear(); + } +} + diff --git a/Sources/libewol/ewol/WidgetManager.h b/Sources/libewol/ewol/WidgetManager.h index 05436fd2..d75090fd 100644 --- a/Sources/libewol/ewol/WidgetManager.h +++ b/Sources/libewol/ewol/WidgetManager.h @@ -33,26 +33,31 @@ namespace ewol { namespace widgetManager { - void Init( void); - void UnInit(void); - void Add( ewol::Widget * newWidget); - void Rm( ewol::Widget * newWidget); - int32_t Get( ewol::Widget * newWidget); - ewol::Widget * Get( int32_t widgetId); - - void FocusKeep( ewol::Widget * newWidget); // set the focus at the specific widget - void FocusSetDefault(ewol::Widget * newWidget); // select the default focus getter - void FocusRelease( void); // Release focus from the current widget to the default - ewol::Widget * FocusGet( void); - void FocusRemoveIfRemove(ewol::Widget * newWidget); - - - int32_t GetDoubleBufferCreate(void); - int32_t GetDoubleBufferDraw(void); - void GetDoubleBufferFlipFlop(void); - bool GetDoubleBufferNeedDraw(void); - void GetDoubleBufferStartDraw(void); - void GetDoubleBufferStopDraw(void); + void Init( void); + void UnInit(void); + void Add( ewol::Widget * newWidget); + void Rm( ewol::Widget * newWidget); + int32_t Get( ewol::Widget * newWidget); + ewol::Widget * Get( int32_t widgetId); + + void FocusKeep( ewol::Widget * newWidget); // set the focus at the specific widget + void FocusSetDefault(ewol::Widget * newWidget); // select the default focus getter + void FocusRelease( void); // Release focus from the current widget to the default + ewol::Widget * FocusGet( void); + void FocusRemoveIfRemove(ewol::Widget * newWidget); + + + int32_t GetDoubleBufferCreate(void); + int32_t GetDoubleBufferDraw(void); + void GetDoubleBufferFlipFlop(void); + bool GetDoubleBufferNeedDraw(void); + void GetDoubleBufferStartDraw(void); + void GetDoubleBufferStopDraw(void); + + // For the multithreaded context the widget mus not de removed by the user ==> he might mark if to be remove later with a mutex protection... + void MarkWidgetToBeRemoved(int32_t widgetId); + void MarkWidgetToBeRemoved(ewol::Widget * expectedWidget); + void RemoveAllMarkWidget(void); }; }; diff --git a/Sources/libewol/ewol/WidgetMessageMultiCast.cpp b/Sources/libewol/ewol/WidgetMessageMultiCast.cpp index fa442a80..4374ab3a 100644 --- a/Sources/libewol/ewol/WidgetMessageMultiCast.cpp +++ b/Sources/libewol/ewol/WidgetMessageMultiCast.cpp @@ -1,6 +1,6 @@ /** ******************************************************************************* - * @file ewol/WidgetMessageMulticast.cpp + * @file ewol/WidgetMessageMultiCast.cpp * @brief basic ewol Widget Message Multi-cast (Sources) * @author Edouard DUPIN * @date 31/01/2012 diff --git a/Sources/libewol/ewol/WidgetMessageMultiCast.h b/Sources/libewol/ewol/WidgetMessageMultiCast.h index d3414d51..a11c8899 100644 --- a/Sources/libewol/ewol/WidgetMessageMultiCast.h +++ b/Sources/libewol/ewol/WidgetMessageMultiCast.h @@ -1,6 +1,6 @@ /** ******************************************************************************* - * @file ewol/WidgetMessageMulticast.h + * @file ewol/WidgetMessageMultiCast.h * @brief basic ewol Widget Message Multi-cast (Header) * @author Edouard DUPIN * @date 31/01/2012 diff --git a/Sources/libewol/ewol/Windows.cpp b/Sources/libewol/ewol/Windows.cpp index 7a0c7ed5..2eb56bb3 100644 --- a/Sources/libewol/ewol/Windows.cpp +++ b/Sources/libewol/ewol/Windows.cpp @@ -31,6 +31,7 @@ #include #include #include +#include @@ -46,7 +47,6 @@ ewol::Windows::Windows(void) { SetCanHaveFocus(true); m_subWidget = NULL; - m_popUpWidget = NULL; m_keyBoardwidget = NULL; // enable specific drawing system ... SpecificDrawEnable(); @@ -57,15 +57,20 @@ ewol::Windows::Windows(void) ewol::Windows::~Windows(void) { if (NULL != m_subWidget) { - delete(m_subWidget); + ewol::widgetManager::MarkWidgetToBeRemoved(m_subWidget); m_subWidget=NULL; } - if (NULL != m_popUpWidget) { - delete(m_popUpWidget); - m_popUpWidget=NULL; + + for(int32_t iii=0; iiiCalculateSize(m_size.x, m_size.y - keyboardHigh); } - if (NULL != m_popUpWidget) { - m_popUpWidget->CalculateMinSize(); - m_popUpWidget->CalculateSize(m_size.x, m_size.y - keyboardHigh); + for(int32_t iii=0; iiiCalculateMinSize(); + m_popUpWidgetList[iii]->CalculateSize(m_size.x, m_size.y - keyboardHigh); + } } // regenerate all the display ... MarkToReedraw(); @@ -108,8 +115,12 @@ bool ewol::Windows::OnEventInput(int32_t IdInput, eventInputType_te typeEvent, e } } // event go directly on the pop-up - if (NULL != m_popUpWidget) { - m_popUpWidget->GenEventInput(IdInput, typeEvent, x, y); + if (0 < m_popUpWidgetList.Size()) { + if (NULL == m_popUpWidgetList[m_popUpWidgetList.Size()-1]) { + m_popUpWidgetList.PopBack(); + } else { + m_popUpWidgetList[m_popUpWidgetList.Size()-1]->GenEventInput(IdInput, typeEvent, x, y); + } // otherwise in the normal windows } else if (NULL != m_subWidget) { m_subWidget->GenEventInput(IdInput, typeEvent, x, y); @@ -145,13 +156,13 @@ void ewol::Windows::SysDraw(void) #endif //http://www.khronos.org/opengles/documentation/opengles1_0/html/glBlendFunc.html - glEnable(GL_POLYGON_SMOOTH); - glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); + //glEnable(GL_POLYGON_SMOOTH); + //glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glShadeModel(GL_POLYGON_SMOOTH); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + //glShadeModel(GL_POLYGON_SMOOTH); + //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA); @@ -171,8 +182,10 @@ void ewol::Windows::OnRegenerateDisplay(void) if (NULL != m_subWidget) { m_subWidget->OnRegenerateDisplay(); } - if (NULL != m_popUpWidget) { - m_popUpWidget->OnRegenerateDisplay(); + for(int32_t iii=0; iiiOnRegenerateDisplay(); + } } if (NULL != m_keyBoardwidget && false == m_keyBoardwidget->IsHide() ) { m_keyBoardwidget->OnRegenerateDisplay(); @@ -188,9 +201,11 @@ bool ewol::Windows::OnDraw(void) //EWOL_DEBUG("Draw Windows"); } // second display the pop-up - if (NULL != m_popUpWidget) { - m_popUpWidget->GenDraw(); - //EWOL_DEBUG("Draw Pop-up"); + for(int32_t iii=0; iiiGenDraw(); + //EWOL_DEBUG("Draw Pop-up"); + } } if (NULL != m_keyBoardwidget && false == m_keyBoardwidget->IsHide() ) { m_keyBoardwidget->GenDraw(); @@ -205,7 +220,7 @@ void ewol::Windows::SetSubWidget(ewol::Widget * widget) { if (NULL != m_subWidget) { EWOL_INFO("Remove current main windows Widget..."); - delete(m_subWidget); + ewol::widgetManager::MarkWidgetToBeRemoved(m_subWidget); m_subWidget = NULL; } m_subWidget = widget; @@ -216,27 +231,27 @@ void ewol::Windows::SetSubWidget(ewol::Widget * widget) void ewol::Windows::PopUpWidgetPush(ewol::Widget * widget) { - if (NULL != m_popUpWidget) { - EWOL_INFO("Remove current pop-up Widget..."); - delete(m_popUpWidget); - m_popUpWidget = NULL; - } - m_popUpWidget = widget; + m_popUpWidgetList.PushBack(widget); // Regenerate the size calculation : CalculateSize(m_size.x, m_size.y); } - -void ewol::Windows::PopUpWidgetPop(void) +void ewol::Windows::PopUpWidgetPop(int32_t popUpId) { - if (NULL != m_popUpWidget) { - EWOL_INFO("Remove current pop-up Widget..."); - delete(m_popUpWidget); - m_popUpWidget = NULL; + if(popUpId >= 0) { + for(int32_t iii=0; iiiGetWidgetId() == popUpId) { + ewol::widgetManager::MarkWidgetToBeRemoved(m_popUpWidgetList[iii]); + m_popUpWidgetList[iii] = NULL; + m_popUpWidgetList.Erase(iii); + return; + } + } + } } } - bool ewol::Windows::OnEventAreaExternal(int32_t widgetID, const char * generateEventId, const char * eventExternId, etkFloat_t x, etkFloat_t y) { if(ewolEventWindowsHideKeyboard == generateEventId) { diff --git a/Sources/libewol/ewol/Windows.h b/Sources/libewol/ewol/Windows.h index 46c34c07..e756be21 100644 --- a/Sources/libewol/ewol/Windows.h +++ b/Sources/libewol/ewol/Windows.h @@ -68,13 +68,13 @@ namespace ewol { m_hasDecoration = true; } private: - ewol::Widget* m_subWidget; - ewol::Widget* m_popUpWidget; - ewol::Keyboard* m_keyBoardwidget; + ewol::Widget* m_subWidget; + etk::VectorType m_popUpWidgetList; + ewol::Keyboard* m_keyBoardwidget; public: void SetSubWidget(ewol::Widget * widget); void PopUpWidgetPush(ewol::Widget * widget); - void PopUpWidgetPop(void); + void PopUpWidgetPop(int32_t popUpId); protected: virtual bool OnDraw(void); public: diff --git a/Sources/libewol/ewol/base/MainThread.cpp b/Sources/libewol/ewol/base/MainThread.cpp index c178bb12..790ffe77 100644 --- a/Sources/libewol/ewol/base/MainThread.cpp +++ b/Sources/libewol/ewol/base/MainThread.cpp @@ -36,7 +36,7 @@ static ewol::threadMsg::threadMsg_ts androidJniMsg; static pthread_t androidJniThread; -//static pthread_attr_t androidJniThreadAttr; +static pthread_attr_t androidJniThreadAttr; enum { THREAD_INIT, @@ -98,6 +98,22 @@ static void* BaseAppEntry(void* param) EWOL_INFO("v" EWOL_VERSION_TAG_NAME); EWOL_INFO("Build Date: " VERSION_BUILD_TIME); + + + /* + struct sched_param pr; + int ret = 9; + int policy; + pthread_getschedparam(pthread_self(), &policy, &pr); + EWOL_INFO("Child Thread Up PL" << policy << " PRI" << pr.sched_priority); //The result here + policy = SCHED_RR; + pr.sched_priority = 19; + pthread_setschedparam(pthread_self(), policy, &pr); + sleep(1); + pthread_getschedparam(pthread_self(), &policy, &pr); + EWOL_INFO("Child Thread Up PL" << policy << " PRI" << pr.sched_priority); //The result Set + */ + ewol::widgetManager::Init(); ewol::texture::Init(); ewol::theme::Init(); @@ -230,7 +246,18 @@ void EWOL_SystemStart(void) ewol::threadMsg::Init(androidJniMsg); // init the thread : EWOL_DEBUG("Create the thread"); - pthread_create(&androidJniThread, NULL, BaseAppEntry, NULL); + pthread_attr_init(&androidJniThreadAttr); + //pthread_attr_setdetachstate(&androidJniThreadAttr, PTHREAD_CREATE_JOINABLE) + pthread_attr_setdetachstate(&androidJniThreadAttr, PTHREAD_CREATE_DETACHED); + //pthread_attr_setscope( &androidJniThreadAttr, PTHREAD_SCOPE_SYSTEM); + // try to set prio : + struct sched_param pr; + pr.sched_priority = 10; + pthread_attr_setschedpolicy(&androidJniThreadAttr, SCHED_RR); + pthread_attr_setschedparam(&androidJniThreadAttr, &pr); + + pthread_create(&androidJniThread, &androidJniThreadAttr, BaseAppEntry, NULL); + //pthread_create(&androidJniThread, NULL, BaseAppEntry, NULL); isGlobalSystemInit = true; EWOL_DEBUG("Send Init message to the thread"); ewol::threadMsg::SendMessage(androidJniMsg, THREAD_INIT, ewol::threadMsg::MSG_PRIO_REAL_TIME); diff --git a/Sources/libewol/ewol/base/gui.cpp b/Sources/libewol/ewol/base/gui.cpp index 7ee70f17..e0343f35 100644 --- a/Sources/libewol/ewol/base/gui.cpp +++ b/Sources/libewol/ewol/base/gui.cpp @@ -37,13 +37,19 @@ ewol::Windows* gui_uniqueWindows = NULL; etkFloat_t gui_width = 320; etkFloat_t gui_height = 480; -void ewol::RmPopUp(void) +void ewol::RmPopUp(int32_t widgetID) { if (NULL != gui_uniqueWindows) { - gui_uniqueWindows->PopUpWidgetPop(); + gui_uniqueWindows->PopUpWidgetPop(widgetID); } } +void ewol::PopUpWidgetPush(ewol::Widget * tmpWidget) +{ + if (NULL != gui_uniqueWindows && NULL != tmpWidget) { + gui_uniqueWindows->PopUpWidgetPush(tmpWidget); + } +} void EWOL_NativeResize(int w, int h ) { diff --git a/Sources/libewol/ewol/ewol.h b/Sources/libewol/ewol/ewol.h index 825be2de..d2da733e 100644 --- a/Sources/libewol/ewol/ewol.h +++ b/Sources/libewol/ewol/ewol.h @@ -42,7 +42,8 @@ namespace ewol { void KeyboardShow(ewol::keyboardMode_te mode); void KeyboardHide(void); void ForceRedrawAll(void); - void RmPopUp(void); + void PopUpWidgetPush(ewol::Widget * tmpWidget); + void RmPopUp(int32_t widgetID); int32_t CmdLineNb(void); etk::UString CmdLineGet(int32_t id); diff --git a/Sources/libewol/ewol/widget/Button.cpp b/Sources/libewol/ewol/widget/Button.cpp index 523b11da..0bf14136 100644 --- a/Sources/libewol/ewol/widget/Button.cpp +++ b/Sources/libewol/ewol/widget/Button.cpp @@ -44,11 +44,14 @@ void ewol::Button::Init(void) AddEventId(ewolEventButtonEnter); AddEventId(ewolEventButtonLeave); - m_padding.x = 4; + m_alignement = ewol::TEXT_ALIGN_CENTER; + #ifdef __PLATFORM__Android m_padding.y = 12; + m_padding.x = 12; #else m_padding.y = 4; + m_padding.x = 4; #endif m_textColorFg.red = 0.0; @@ -81,6 +84,11 @@ ewol::Button::~Button(void) } +void ewol::Button::SetPadding(coord2D_ts newPadding) +{ + m_padding = newPadding; +} + bool ewol::Button::CalculateMinSize(void) { int32_t fontId = GetDefaultFontId(); @@ -103,6 +111,13 @@ void ewol::Button::SetValue(bool val) } +void ewol::Button::SetAlignement(textAlignement_te typeAlign) +{ + m_alignement = typeAlign; + MarkToReedraw(); +} + + bool ewol::Button::GetValue(void) { return false; @@ -126,6 +141,9 @@ void ewol::Button::OnRegenerateDisplay(void) if (true==m_userFillX) { tmpSizeX = m_size.x; tmpOriginX = 0; + if (m_alignement == ewol::TEXT_ALIGN_LEFT) { + tmpTextOriginX = m_padding.x; + } } if (true==m_userFillY) { tmpSizeY = m_size.y; @@ -183,7 +201,7 @@ bool ewol::Button::OnEventInput(int32_t IdInput, eventInputType_te typeEvent, et } -bool ewol::Button::OnEventKb(eventKbType_te typeEvent, char UTF8_data[UTF8_MAX_SIZE]) +bool ewol::Button::OnEventKb(ewol::eventKbType_te typeEvent, char UTF8_data[UTF8_MAX_SIZE]) { //EWOL_DEBUG("BT PRESSED : \"" << UTF8_data << "\" size=" << strlen(UTF8_data)); if( UTF8_data != NULL diff --git a/Sources/libewol/ewol/widget/Button.h b/Sources/libewol/ewol/widget/Button.h index 157d619d..765787ff 100644 --- a/Sources/libewol/ewol/widget/Button.h +++ b/Sources/libewol/ewol/widget/Button.h @@ -34,6 +34,10 @@ extern const char * const ewolEventButtonEnter; extern const char * const ewolEventButtonLeave; namespace ewol { + typedef enum { + TEXT_ALIGN_LEFT, + TEXT_ALIGN_CENTER, + } textAlignement_te; class Button :public ewol::Widget { public: @@ -43,19 +47,22 @@ namespace ewol { virtual ~Button(void); virtual bool CalculateMinSize(void); void SetLabel(etk::UString newLabel); - etk::UString GetLabel(void) {return m_label;}; + etk::UString GetLabel(void) {return m_label;}; void SetValue(bool val); bool GetValue(void); + void SetAlignement(textAlignement_te typeAlign); + void SetPadding(coord2D_ts newPadding); private: - coord2D_ts m_padding; - etk::UString m_label; - color_ts m_textColorFg; //!< Text color - color_ts m_textColorBg; //!< Background color + textAlignement_te m_alignement; + coord2D_ts m_padding; + etk::UString m_label; + color_ts m_textColorFg; //!< Text color + color_ts m_textColorBg; //!< Background color public: virtual void OnRegenerateDisplay(void); public: virtual bool OnEventInput(int32_t IdInput, eventInputType_te typeEvent, etkFloat_t x, etkFloat_t y); - virtual bool OnEventKb(eventKbType_te typeEvent, char UTF8_data[UTF8_MAX_SIZE]); + virtual bool OnEventKb(ewol::eventKbType_te typeEvent, char UTF8_data[UTF8_MAX_SIZE]); }; }; diff --git a/Sources/libewol/ewol/widget/ContextMenu.cpp b/Sources/libewol/ewol/widget/ContextMenu.cpp index 9ada5983..6e4c647f 100644 --- a/Sources/libewol/ewol/widget/ContextMenu.cpp +++ b/Sources/libewol/ewol/widget/ContextMenu.cpp @@ -24,8 +24,9 @@ -#include #include +#include +#include #undef __class__ #define __class__ "ewol::ContextMenu" @@ -51,7 +52,8 @@ ewol::ContextMenu::ContextMenu(void) m_colorBorder.blue = 0.0; m_colorBorder.alpha = 0.50; - m_arrowPos = {0,0}; + m_arrowPos.x = 0; + m_arrowPos.y = 0; m_arrawBorder = ewol::CONTEXT_MENU_MARK_TOP; } @@ -99,7 +101,32 @@ bool ewol::ContextMenu::CalculateSize(etkFloat_t availlableX, etkFloat_t availla subWidgetOrigin.y = (int32_t)(m_size.y - m_origin.y - subWidgetSize.y)/2 + m_origin.y; break; } + // set the widget position at the border of the screen + subWidgetOrigin.x -= m_padding.x*2; + subWidgetOrigin.x = etk_max(0, subWidgetOrigin.x); + subWidgetOrigin.x += m_padding.x*2; + subWidgetOrigin.x = (int32_t)subWidgetOrigin.x; + subWidgetOrigin.y -= m_padding.y*2; + subWidgetOrigin.y = etk_max(0, subWidgetOrigin.y); + subWidgetOrigin.y += m_padding.y*2; + subWidgetOrigin.y = (int32_t)subWidgetOrigin.y; + switch (m_arrawBorder) + { + default: + case ewol::CONTEXT_MENU_MARK_TOP: + case ewol::CONTEXT_MENU_MARK_BOTTOM: + if (m_arrowPos.x <= m_offset ) { + subWidgetOrigin.x = m_arrowPos.x+m_padding.x; + } + break; + case ewol::CONTEXT_MENU_MARK_RIGHT: + case ewol::CONTEXT_MENU_MARK_LEFT: + if (m_arrowPos.y <= m_offset ) { + subWidgetOrigin.y = m_arrowPos.y+m_padding.y; + } + break; + } m_subWidget->SetOrigin(subWidgetOrigin.x, subWidgetOrigin.y); m_subWidget->CalculateSize(subWidgetSize.x, subWidgetSize.y); } @@ -155,7 +182,7 @@ void ewol::ContextMenu::SubWidgetSet(ewol::Widget* newWidget) void ewol::ContextMenu::SubWidgetRemove(void) { if (NULL != m_subWidget) { - delete(m_subWidget); + ewol::widgetManager::MarkWidgetToBeRemoved(m_subWidget); m_subWidget = NULL; } } @@ -184,10 +211,27 @@ void ewol::ContextMenu::OnRegenerateDisplay(void) // display border ... BGOObjects->SetColor(m_colorBorder); - BGOObjects->SetPoint(m_arrowPos.x, m_arrowPos.y); - int32_t laking = m_offset - m_padding.y; - BGOObjects->SetPoint(m_arrowPos.x+laking, m_arrowPos.y+laking); - BGOObjects->SetPoint(m_arrowPos.x-laking, m_arrowPos.y+laking); + switch (m_arrawBorder) + { + case ewol::CONTEXT_MENU_MARK_TOP: + BGOObjects->SetPoint(m_arrowPos.x, m_arrowPos.y); + if (m_arrowPos.x <= tmpOrigin.x ) { + int32_t laking = m_offset - m_padding.y; + BGOObjects->SetPoint(m_arrowPos.x+laking, m_arrowPos.y+laking); + BGOObjects->SetPoint(m_arrowPos.x, m_arrowPos.y+laking); + } else { + int32_t laking = m_offset - m_padding.y; + BGOObjects->SetPoint(m_arrowPos.x+laking, m_arrowPos.y+laking); + BGOObjects->SetPoint(m_arrowPos.x-laking, m_arrowPos.y+laking); + } + break; + default: + case ewol::CONTEXT_MENU_MARK_BOTTOM: + case ewol::CONTEXT_MENU_MARK_RIGHT: + case ewol::CONTEXT_MENU_MARK_LEFT: + EWOL_TODO("later"); + break; + } BGOObjects->Rectangle(tmpOrigin.x-m_padding.x, tmpOrigin.y - m_padding.y, tmpSize.x + m_padding.x*2, tmpSize.y + m_padding.y*2); // set the area in white ... @@ -220,7 +264,7 @@ bool ewol::ContextMenu::OnEventInput(int32_t IdInput, eventInputType_te typeEven || typeEvent == ewol::EVENT_INPUT_TYPE_UP || typeEvent == ewol::EVENT_INPUT_TYPE_ENTER || typeEvent == ewol::EVENT_INPUT_TYPE_LEAVE ) { - ewol::RmPopUp(); + ewol::RmPopUp(GetWidgetId()); } } } diff --git a/Sources/libewol/ewol/widget/List.cpp b/Sources/libewol/ewol/widget/List.cpp index 3b09bff5..92281a3c 100644 --- a/Sources/libewol/ewol/widget/List.cpp +++ b/Sources/libewol/ewol/widget/List.cpp @@ -77,7 +77,6 @@ void ewol::List::OnRegenerateDisplay(void) int32_t tmpOriginX = 0; int32_t tmpOriginY = 0; - int32_t tmpOriginYBG = 0; /* if (true==m_userFillX) { tmpOriginX = 0; @@ -107,45 +106,47 @@ void ewol::List::OnRegenerateDisplay(void) BGOObjects->SetColor(basicBG); BGOObjects->Rectangle(0, 0, m_size.x, m_size.y); - uint32_t displayableRaw = m_size.y / (minHeight + 2*m_paddingSizeY); + uint32_t displayableRaw = m_size.y / (minHeight + 2*m_paddingSizeY) +2; - int32_t startRaw = m_originScrooled.y / (minHeight + 2*m_paddingSizeY) - 1; + int32_t startRaw = m_originScrooled.y / (minHeight + 2*m_paddingSizeY); + + if (startRaw >= nbRaw-1 ) { + startRaw = nbRaw - 1; + } if (startRaw<0) { startRaw = 0; } + // Calculate the real position ... + tmpOriginY = -m_originScrooled.y + startRaw*(minHeight + 2*m_paddingSizeY); + // We display only compleate lines ... - EWOL_VERBOSE("Request drawing list : " << startRaw << "-->" << (startRaw+displayableRaw) << " in " << nbRaw << "raws"); + //EWOL_DEBUG("Request drawing list : " << startRaw << "-->" << (startRaw+displayableRaw) << " in " << nbRaw << "raws ; start display : " << m_originScrooled.y << " ==> " << tmpOriginY << " line size=" << minHeight + 2*m_paddingSizeY ); clipping_ts drawClipping; drawClipping.x = 0; drawClipping.y = 0; drawClipping.w = m_size.x - (2*m_paddingSizeX); drawClipping.h = m_size.y; - + for(uint32_t iii=startRaw; iiiSetColor(bg); - BGOObjects->Rectangle(0, tmpOriginYBG, m_size.x, minHeight+2*m_paddingSizeY); - tmpOriginYBG += minHeight+2*m_paddingSizeY; + BGOObjects->Rectangle(0, tmpOriginY, m_size.x, minHeight+2*m_paddingSizeY); ewol::OObject2DText * tmpText = new ewol::OObject2DText("", -1, fg); coord2D_ts textPos; textPos.x = tmpOriginX; - textPos.y = tmpOriginY; + textPos.y = tmpOriginY + m_paddingSizeY; tmpText->Text(textPos, drawClipping, myTextToWrite); AddOObject(tmpText); tmpOriginY += minHeight + 2* m_paddingSizeY; } AddOObject(BGOObjects, "ListDeco", 0); - //ewol::OObject2DText * tmpText = new ewol::OObject2DText("", -1, m_textColorFg); - //tmpText->Text(tmpOriginX, tmpOriginY, "jhgjhg"); - - //AddOObject(tmpText, "ListText"); // call the herited class... WidgetScrooled::OnRegenerateDisplay(); diff --git a/Sources/libewol/ewol/widget/Menu.cpp b/Sources/libewol/ewol/widget/Menu.cpp index 2a81298b..08e0bc6c 100644 --- a/Sources/libewol/ewol/widget/Menu.cpp +++ b/Sources/libewol/ewol/widget/Menu.cpp @@ -24,8 +24,13 @@ +#include +#include +#include #include #include +#include +#include #undef __class__ #define __class__ "ewol::Menu" @@ -33,6 +38,7 @@ ewol::Menu::Menu(void) { m_staticId = 0; + m_popUpId = -1; } ewol::Menu::~Menu(void) @@ -85,19 +91,22 @@ int32_t ewol::Menu::Add(int32_t parent, etk::UString label, etk::UString image, } tmpObject->m_localId = m_staticId++; tmpObject->m_parentId = parent; + tmpObject->m_widgetId = -1; tmpObject->m_label = label; tmpObject->m_image = image; tmpObject->m_generateEvent = generateEvent; tmpObject->m_message = message; m_listElement.PushBack(tmpObject); if (-1 == tmpObject->m_parentId) { - ewol::Button * myButton = new ewol::Button(label); - ewol::SizerHori::SubWidgetAdd(myButton); - /* - if (false == myButton->ExternLinkOnEvent(ewolEventButtonPressed, GetWidgetId(), "event ... ") ) { - EDN_CRITICAL("link with an entry event"); + ewol::Button * myButton = NULL; + myButton = new ewol::Button(label); + if (NULL == myButton) { + EWOL_ERROR("Allocation button error"); + return tmpObject->m_localId;; } - */ + ewol::SizerHori::SubWidgetAdd(myButton); + myButton->ExternLinkOnEvent(ewolEventButtonPressed, GetWidgetId(), ewolEventButtonPressed); + tmpObject->m_widgetId = myButton->GetWidgetId(); } return tmpObject->m_localId; } @@ -106,3 +115,83 @@ void ewol::Menu::AddSpacer(void) { EWOL_TODO("NOT now..."); } + + +bool ewol::Menu::OnEventAreaExternal(int32_t widgetID, const char * generateEventId, const char * data, etkFloat_t x, etkFloat_t y) +{ + if (true == ewol::SizerHori::OnEventAreaExternal(widgetID, generateEventId, data, x, y)) { + return true; + } + if (NULL==data && generateEventId==ewolEventButtonPressed) { + for(int32_t iii=0; iiim_widgetId) { + // 2 posible case + if (m_listElement[iii]->m_generateEvent != NULL) { + ewol::widgetMessageMultiCast::Send(GetWidgetId(), m_listElement[iii]->m_generateEvent, m_listElement[iii]->m_message); + ewol::RmPopUp(m_popUpId); + m_popUpId = -1; + return true; + } else { + bool findChild = false; + for(int32_t jjj=0; jjjm_localId == m_listElement[jjj]->m_parentId) { + findChild = true; + break; + } + } + if (false == findChild) { + EWOL_WARNING("Event on menu element with no child an no event... label=" << m_listElement[iii]->m_label); + return false; + } + // create a context menu : + ewol::ContextMenu * tmpWidget = new ewol::ContextMenu(); + if (NULL == tmpWidget) { + EWOL_ERROR("Allocation Error"); + return false; + } + // Get the button widget : + coord2D_ts newPosition; + newPosition.x = x; + newPosition.y = y; + ewol::Widget * eventFromWidget = ewol::widgetManager::Get(widgetID); + if (NULL != eventFromWidget) { + coord tmpOri = eventFromWidget->GetOrigin(); + coord tmpSize = eventFromWidget->GetSize(); + // calculate the correct position + newPosition.x = tmpOri.x + tmpSize.x/2; + newPosition.y = tmpOri.y + tmpSize.y; + } + + tmpWidget->SetPositionMark(ewol::CONTEXT_MENU_MARK_TOP, newPosition ); + + ewol::SizerVert * mySizerVert = NULL; + ewol::Button * myButton = NULL; + + mySizerVert = new ewol::SizerVert(); + mySizerVert->LockExpendContamination(true); + // set it in the pop-up-system : + tmpWidget->SubWidgetSet(mySizerVert); + + for(int32_t jjj=0; jjjm_localId == m_listElement[jjj]->m_parentId) { + myButton = new ewol::Button(m_listElement[jjj]->m_label); + if (NULL == myButton) { + EWOL_ERROR("Allocation Error"); + } + m_listElement[jjj]->m_widgetId = myButton->GetWidgetId(); + myButton->ExternLinkOnEvent(ewolEventButtonPressed, GetWidgetId(), ewolEventButtonPressed); + myButton->SetExpendX(true); + myButton->SetFillX(true); + myButton->SetAlignement(ewol::TEXT_ALIGN_LEFT); + mySizerVert->SubWidgetAdd(myButton); + } + } + m_popUpId = tmpWidget->GetWidgetId(); + ewol::PopUpWidgetPush(tmpWidget); + } + return true; + } + } + } + return false; +} diff --git a/Sources/libewol/ewol/widget/Menu.h b/Sources/libewol/ewol/widget/Menu.h index fe775e65..b9742127 100644 --- a/Sources/libewol/ewol/widget/Menu.h +++ b/Sources/libewol/ewol/widget/Menu.h @@ -37,6 +37,7 @@ namespace ewol { public : int32_t m_localId; int32_t m_parentId; + int32_t m_widgetId; etk::UString m_label; etk::UString m_image; const char * m_generateEvent; @@ -55,11 +56,14 @@ namespace ewol { private: etk::VectorType m_listElement; int32_t m_staticId; + int32_t m_popUpId; public: void Clear(void); int32_t AddTitle(etk::UString label, etk::UString image="", const char * generateEvent = NULL, const etk::UString message = ""); int32_t Add(int32_t parent, etk::UString label, etk::UString image="", const char * generateEvent = NULL, const etk::UString message = ""); void AddSpacer(void); + + virtual bool OnEventAreaExternal(int32_t widgetID, const char * generateEventId, const char * data, etkFloat_t x, etkFloat_t y); }; }; diff --git a/Sources/libewol/ewol/widget/PopUp.cpp b/Sources/libewol/ewol/widget/PopUp.cpp index 1755d8e2..fba50018 100644 --- a/Sources/libewol/ewol/widget/PopUp.cpp +++ b/Sources/libewol/ewol/widget/PopUp.cpp @@ -25,6 +25,7 @@ #include +#include #undef __class__ #define __class__ "ewol::PopUp" @@ -136,7 +137,7 @@ void ewol::PopUp::SubWidgetSet(ewol::Widget* newWidget) void ewol::PopUp::SubWidgetRemove(void) { if (NULL != m_subWidget) { - delete(m_subWidget); + ewol::widgetManager::MarkWidgetToBeRemoved(m_subWidget); m_subWidget = NULL; } } diff --git a/Sources/libewol/ewol/widget/SizerHori.cpp b/Sources/libewol/ewol/widget/SizerHori.cpp index 4bc2c478..7ec71784 100644 --- a/Sources/libewol/ewol/widget/SizerHori.cpp +++ b/Sources/libewol/ewol/widget/SizerHori.cpp @@ -25,6 +25,7 @@ #include +#include #undef __class__ #define __class__ "ewol::SizerHori" @@ -165,7 +166,7 @@ void ewol::SizerHori::SubWidgetRemoveAll(void) { for (int32_t iii=0; iii +#include #undef __class__ @@ -167,7 +168,7 @@ void ewol::SizerVert::LockExpendContamination(bool lockExpend) void ewol::SizerVert::SubWidgetRemoveAll(void) { for (int32_t iii=0; iii Auto remove ... bool tmppp = GenEventInputExternal(generateEventId, x, y); - ewol::RmPopUp(); + ewol::RmPopUp(GetWidgetId()); return tmppp; } else if (ewolEventFileChooserHidenFileChange == generateEventId) { // regenerate the display ... @@ -568,7 +568,7 @@ bool ewol::FileChooser::OnEventAreaExternal(int32_t widgetID, const char * gener } else if (ewolEventFileChooserValidateFile == generateEventId) { // select the File ==> generate a validate bool tmppp = GenEventInputExternal(ewolEventFileChooserValidate, x, y); - ewol::RmPopUp(); + ewol::RmPopUp(GetWidgetId()); return tmppp; } else if (ewolEventFileChooserValidate == generateEventId && false == m_hasSelectedFile) { return false; diff --git a/Sources/libewol/ewol/widgetMeta/Keyboard.cpp b/Sources/libewol/ewol/widgetMeta/Keyboard.cpp index 7817d59d..e75821de 100644 --- a/Sources/libewol/ewol/widgetMeta/Keyboard.cpp +++ b/Sources/libewol/ewol/widgetMeta/Keyboard.cpp @@ -72,6 +72,7 @@ ewol::Keyboard::~Keyboard(void) (widget)->SetExpendX(true); \ (widget)->SetFillX(true); \ (widget)->SetCanHaveFocus(false); \ + (widget)->SetPadding(newPadding); \ (upperWidget)->SubWidgetAdd((widget)); \ } while (0) @@ -84,6 +85,10 @@ void ewol::Keyboard::SetMode(keyboardMode_te mode) ewol::SizerHori * mySizerHori = NULL; ewol::Button * myButton = NULL; + coord2D_ts newPadding; + newPadding.y = 20; + newPadding.x = 12; + mySizerVert = new ewol::SizerVert(); m_subWidget = mySizerVert;