From 9b5d0d336cc02b7878ab1fe7470ba34c860de3d5 Mon Sep 17 00:00:00 2001 From: Edouard Dupin Date: Thu, 27 Oct 2011 13:38:55 +0200 Subject: [PATCH] X11: Generate simple, double and triple ckick event on a specific button --- Makefile | 4 +- Sources/base/guiX11.cpp | 149 +++++++++++++++++++++++++++++++++++---- Sources/etk/etkDebug.cpp | 4 +- Sources/etk/etkTypes.h | 5 +- Sources/ewolWidget.cpp | 18 ++++- Sources/ewolWidget.h | 30 ++++---- Sources/ewolWindows.cpp | 64 ++++++++++------- 7 files changed, 210 insertions(+), 64 deletions(-) diff --git a/Makefile b/Makefile index a8cb98cc..98010f5d 100644 --- a/Makefile +++ b/Makefile @@ -93,8 +93,8 @@ DEFINE+= -DVERSION_BUILD_TIME="\"$(VERSION_BUILD_TIME)\"" X11FLAGS= -lX11 -lGL -lGLU # some X11 mode availlable : -X11FLAGS+= -DEWOL_X11_MODE__XF86V -lXxf86vm -#X11FLAGS+= -DEWOL_X11_MODE__XRENDER -lXrandr +#X11FLAGS+= -DEWOL_X11_MODE__XF86V -lXxf86vm +X11FLAGS+= -DEWOL_X11_MODE__XRENDER -lXrandr ############################################################################### ### Basic C flags ### diff --git a/Sources/base/guiX11.cpp b/Sources/base/guiX11.cpp index e9930d4f..943ff2b1 100644 --- a/Sources/base/guiX11.cpp +++ b/Sources/base/guiX11.cpp @@ -43,6 +43,9 @@ # error you might define an EWOL_X11_MODE in EWOL_X11_XF86V / EWOL_X11_XRENDER #endif +#include + + #if defined(EWOL_X11_MODE__XF86V) // attributes for a single buffered visual in RGBA format with at least 4 bits per color and a 16 bit depth buffer static int attrListSgl[] = { @@ -78,6 +81,9 @@ static int VisualData[] = { }; #endif + +#define SEPARATED_CLICK_TIME (30) + namespace guiAbstraction { extern "C" { typedef struct Hints @@ -91,6 +97,15 @@ namespace guiAbstraction { } class X11systemInterface { + private: + // for double and triple click selection, we need to save the previous click up and down position , and the previous time ... + int32_t m_previousBouttonId; + int32_t m_previousDown_x; + int32_t m_previousDown_y; + int32_t m_previous_x; + int32_t m_previous_y; + int64_t m_previousTime; + bool m_previousDouble; private: Atom m_delAtom; Display * m_display; @@ -351,6 +366,13 @@ namespace guiAbstraction { X11systemInterface(void) { m_visual = NULL; + m_previousBouttonId = 0; + m_previousDown_x = -1; + m_previousDown_y = -1; + m_previous_x = -1; + m_previous_y = -1; + m_previousTime = 0; + m_previousDouble = false; CreateX11Context(); CreateOGlContext(); m_run = true; @@ -411,31 +433,132 @@ namespace guiAbstraction { m_uniqueWindows->SysOnExpose(); break; case ButtonPress: - EWOL_DEBUG("X11 event : " << event.type << " = \"ButtonPress\" (" << (double)event.xbutton.x << "," << (double)event.xbutton.y << ")"); - if ( event.xbutton.button & Button2 ) { - m_uniqueWindows->GenEventInput(2, ewol::EVENT_INPUT_TYPE_DOWN, (double)event.xbutton.x, (double)event.xbutton.y); - } else if (event.xbutton.button & Button1) { - m_uniqueWindows->GenEventInput(1, ewol::EVENT_INPUT_TYPE_DOWN, (double)event.xbutton.x, (double)event.xbutton.y); + { + int32_t btId = 0; + //EWOL_DEBUG("X11 event : " << event.type << " = \"ButtonPress\" (" << (double)event.xbutton.x << "," << (double)event.xbutton.y << ")"); + if ( event.xbutton.button & Button2 ) { + btId = 2; + } else if (event.xbutton.button & Button1) { + btId = 1; + } + // Send Down message + m_uniqueWindows->GenEventInput(btId, ewol::EVENT_INPUT_TYPE_DOWN, (double)event.xbutton.x, (double)event.xbutton.y); + // Check double or triple click event ... + m_previousDown_x = event.xbutton.x; + m_previousDown_y = event.xbutton.y; + if (m_previousBouttonId != btId) { + m_previousBouttonId = btId; + m_previous_x = -1; + m_previous_y = -1; + m_previousTime = 0; + m_previousDouble = false; + } else { + if( abs(m_previous_x - event.xbutton.x) < 5 + && abs(m_previous_y - event.xbutton.y) < 5 ) + { + // nothink to do ... wait up ... + } else { + m_previous_x = -1; + m_previous_y = -1; + m_previousTime = 0; + m_previousDouble = false; + } + } } break; case ButtonRelease: - EWOL_DEBUG("X11 event : " << event.type << " = \"ButtonRelease\" (" << (double)event.xbutton.x << "," << (double)event.xbutton.y << ")"); - if(event.xbutton.button & Button2) { - m_uniqueWindows->GenEventInput(2, ewol::EVENT_INPUT_TYPE_UP, (double)event.xbutton.x, (double)event.xbutton.y); - } else if (event.xbutton.button & Button1) { - m_uniqueWindows->GenEventInput(1, ewol::EVENT_INPUT_TYPE_UP, (double)event.xbutton.x, (double)event.xbutton.y); + { + int32_t btId = 0; + //EWOL_DEBUG("X11 event : " << event.type << " = \"ButtonRelease\" (" << (double)event.xbutton.x << "," << (double)event.xbutton.y << ")"); + if(event.xbutton.button & Button2) { + btId = 2; + } else if (event.xbutton.button & Button1) { + btId = 1; + } + // send Up event ... + m_uniqueWindows->GenEventInput(btId, ewol::EVENT_INPUT_TYPE_UP, (double)event.xbutton.x, (double)event.xbutton.y); + + if (m_previousBouttonId != btId) { + m_previousDown_x = -1; + m_previousDown_y = -1; + m_previousBouttonId = 0; + m_previous_x = -1; + m_previous_y = -1; + m_previousTime = 0; + m_previousDouble = false; + } else { + int64_t currentTime = times(NULL); // return the tic in 10ms + //EWOL_DEBUG("time is : " << currentTime << " "<< currentTime/100 <<"s " << (currentTime%100)*10 << "ms"); + if (currentTime - m_previousTime >= SEPARATED_CLICK_TIME) { + //check if the same area click : + if( abs(m_previousDown_x - event.xbutton.x) < 5 + && abs(m_previousDown_y - event.xbutton.y) < 5 ) + { + // might generate an sigle event : + //EWOL_DEBUG("X11 event : " << event.type << " = \"ButtonClockedSingle\" (" << (double)event.xbutton.x << "," << (double)event.xbutton.y << ")"); + m_uniqueWindows->GenEventInput(btId, ewol::EVENT_INPUT_TYPE_SINGLE, (double)event.xbutton.x, (double)event.xbutton.y); + m_previous_x = m_previousDown_x; + m_previous_y = m_previousDown_y; + m_previousTime = currentTime; + } else { + // reset values ... + m_previousDown_x = -1; + m_previousDown_y = -1; + m_previousBouttonId = 0; + m_previous_x = -1; + m_previous_y = -1; + m_previousTime = 0; + } + m_previousDouble = false; + } else { + //check if the same area click : + if( abs(m_previous_x - event.xbutton.x) < 5 + && abs(m_previous_y - event.xbutton.y) < 5 ) + { + // might generate an sigle event : + if (false == m_previousDouble) { + //EWOL_DEBUG("X11 event : " << event.type << " = \"ButtonClockedDouble\" (" << (double)event.xbutton.x << "," << (double)event.xbutton.y << ")"); + m_uniqueWindows->GenEventInput(btId, ewol::EVENT_INPUT_TYPE_DOUBLE, (double)event.xbutton.x, (double)event.xbutton.y); + m_previousTime = currentTime; + m_previousDouble = true; + } else { + //EWOL_DEBUG("X11 event : " << event.type << " = \"ButtonClockedTriple\" (" << (double)event.xbutton.x << "," << (double)event.xbutton.y << ")"); + m_uniqueWindows->GenEventInput(btId, ewol::EVENT_INPUT_TYPE_TRIPLE, (double)event.xbutton.x, (double)event.xbutton.y); + // reset values ... + m_previousDown_x = -1; + m_previousDown_y = -1; + m_previousBouttonId = 0; + m_previous_x = -1; + m_previous_y = -1; + m_previousTime = 0; + m_previousDouble = false; + } + } else { + // reset values ... + m_previousDown_x = -1; + m_previousDown_y = -1; + m_previousBouttonId = 0; + m_previous_x = -1; + m_previous_y = -1; + m_previousTime = 0; + m_previousDouble = false; + } + } + + //int64_t currentTime = + } } break; case EnterNotify: - EWOL_DEBUG("X11 event : " << event.type << " = \"EnterNotify\" (" << (double)event.xcrossing.x << "," << (double)event.xcrossing.y << ")"); + //EWOL_DEBUG("X11 event : " << event.type << " = \"EnterNotify\" (" << (double)event.xcrossing.x << "," << (double)event.xcrossing.y << ")"); m_uniqueWindows->GenEventInput(0, ewol::EVENT_INPUT_TYPE_ENTER, (double)event.xcrossing.x, (double)event.xcrossing.y); break; case MotionNotify: - EWOL_DEBUG("X11 event : " << event.type << " = \"MotionNotify\" (" << (double)event.xmotion.x << "," << (double)event.xmotion.y << ")"); + //EWOL_DEBUG("X11 event : " << event.type << " = \"MotionNotify\" (" << (double)event.xmotion.x << "," << (double)event.xmotion.y << ")"); m_uniqueWindows->GenEventInput(0, ewol::EVENT_INPUT_TYPE_MOVE, (double)event.xmotion.x, (double)event.xmotion.y); break; case LeaveNotify: - EWOL_DEBUG("X11 event : " << event.type << " = \"LeaveNotify\" (" << (double)event.xcrossing.x << "," << (double)event.xcrossing.y << ")"); + //EWOL_DEBUG("X11 event : " << event.type << " = \"LeaveNotify\" (" << (double)event.xcrossing.x << "," << (double)event.xcrossing.y << ")"); m_uniqueWindows->GenEventInput(0, ewol::EVENT_INPUT_TYPE_LEAVE, (double)event.xcrossing.x, (double)event.xcrossing.y); break; case FocusIn: diff --git a/Sources/etk/etkDebug.cpp b/Sources/etk/etkDebug.cpp index 560f8b34..30f71b7e 100644 --- a/Sources/etk/etkDebug.cpp +++ b/Sources/etk/etkDebug.cpp @@ -63,8 +63,8 @@ void TOOLS_DisplayTime(void) struct tm * timeinfo; char tmpdata[50]; - time ( &rawtime ); - timeinfo = localtime ( &rawtime ); + time(&rawtime); + timeinfo = localtime(&rawtime); sprintf(tmpdata, " %2dh %2dmin %2ds | ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); std::cout << tmpdata ; } diff --git a/Sources/etk/etkTypes.h b/Sources/etk/etkTypes.h index 723dddc3..caede1bc 100644 --- a/Sources/etk/etkTypes.h +++ b/Sources/etk/etkTypes.h @@ -47,9 +47,8 @@ typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; - #ifndef __uint64_t_defined - typedef unsigned long int uint64_t; - #endif + //typedef unsigned long int uint64_t; + typedef unsigned long long int uint64_t; #endif #define etk_min(elemA, elemB) ((elemA)<(elemB)) ? (elemA) : (elemB) diff --git a/Sources/ewolWidget.cpp b/Sources/ewolWidget.cpp index 41b8f1b0..1bea2d0b 100644 --- a/Sources/ewolWidget.cpp +++ b/Sources/ewolWidget.cpp @@ -63,8 +63,22 @@ bool ewol::Widget::GenEventInput(int32_t IdInput, eventInputType_te typeEvent, d && m_inputEvent[iii].area.origin.y + m_inputEvent[iii].area.size.y > y ) { // TODO : What is the flags for ??? how can we use it... - if( FLAG_EVENT_INPUT_1 && m_inputEvent[iii].area.flags - && 1 == IdInput) + if( ( ( (FLAG_EVENT_INPUT_1 & m_inputEvent[iii].area.flags) && 1 == IdInput ) + || ( (FLAG_EVENT_INPUT_2 & m_inputEvent[iii].area.flags) && 2 == IdInput) + || ( (FLAG_EVENT_INPUT_3 & m_inputEvent[iii].area.flags) && 3 == IdInput) + || ( (FLAG_EVENT_INPUT_4 & m_inputEvent[iii].area.flags) && 4 == IdInput) + || ( (FLAG_EVENT_INPUT_5 & m_inputEvent[iii].area.flags) && 5 == IdInput) + ) + && ( ( (FLAG_EVENT_INPUT_MOTION & m_inputEvent[iii].area.flags) && EVENT_INPUT_TYPE_MOVE == typeEvent) + || ( (FLAG_EVENT_INPUT_ENTER & m_inputEvent[iii].area.flags) && EVENT_INPUT_TYPE_ENTER == typeEvent) + || ( (FLAG_EVENT_INPUT_LEAVE & m_inputEvent[iii].area.flags) && EVENT_INPUT_TYPE_LEAVE == typeEvent) + || ( (FLAG_EVENT_INPUT_DOWN & m_inputEvent[iii].area.flags) && EVENT_INPUT_TYPE_DOWN == typeEvent) + || ( (FLAG_EVENT_INPUT_UP & m_inputEvent[iii].area.flags) && EVENT_INPUT_TYPE_UP == typeEvent) + || ( (FLAG_EVENT_INPUT_CLICKED & m_inputEvent[iii].area.flags) && EVENT_INPUT_TYPE_SINGLE == typeEvent) + || ( (FLAG_EVENT_INPUT_CLICKED_DOUBLE & m_inputEvent[iii].area.flags) && EVENT_INPUT_TYPE_DOUBLE == typeEvent) + || ( (FLAG_EVENT_INPUT_CLICKED_TRIPLE & m_inputEvent[iii].area.flags) && EVENT_INPUT_TYPE_TRIPLE == typeEvent) + ) + ) { ended = OnEventArea(m_inputEvent[iii].generateEventId, x, y); if (true == ended) { diff --git a/Sources/ewolWidget.h b/Sources/ewolWidget.h index e3c88cb9..7cc28b33 100644 --- a/Sources/ewolWidget.h +++ b/Sources/ewolWidget.h @@ -38,9 +38,10 @@ namespace ewol { } typedef enum { EVENT_INPUT_TYPE_DOWN, + EVENT_INPUT_TYPE_MOVE, + EVENT_INPUT_TYPE_SINGLE, EVENT_INPUT_TYPE_DOUBLE, EVENT_INPUT_TYPE_TRIPLE, - EVENT_INPUT_TYPE_MOVE, EVENT_INPUT_TYPE_UP, EVENT_INPUT_TYPE_ENTER, EVENT_INPUT_TYPE_LEAVE, @@ -63,20 +64,19 @@ namespace ewol { } eventKbMoveType_te; enum { - FLAG_EVENT_INPUT_1 = 1 << 0, - FLAG_EVENT_INPUT_2 = 1 << 1, - FLAG_EVENT_INPUT_3 = 1 << 2, - FLAG_EVENT_INPUT_4 = 1 << 3, - FLAG_EVENT_INPUT_5 = 1 << 4, - FLAG_EVENT_INPUT_MOTION = 1 << 5, - FLAG_EVENT_ENTER = 1 << 6, - FLAG_EVENT_LEAVE = 1 << 7, - FLAG_EVENT_DOWN = 1 << 8, - FLAG_EVENT_UP = 1 << 9, - FLAG_EVENT_MOVE = 1 << 10, - FLAG_EVENT_CLICKED = 1 << 11, - FLAG_EVENT_CLICKED_DOUBLE = 1 << 12, - FLAG_EVENT_CLICKED_TRIPLE = 1 << 13, + FLAG_EVENT_INPUT_1 = 1 << 0, + FLAG_EVENT_INPUT_2 = 1 << 1, + FLAG_EVENT_INPUT_3 = 1 << 2, + FLAG_EVENT_INPUT_4 = 1 << 3, + FLAG_EVENT_INPUT_5 = 1 << 4, + FLAG_EVENT_INPUT_MOTION = 1 << 5, + FLAG_EVENT_INPUT_ENTER = 1 << 6, + FLAG_EVENT_INPUT_LEAVE = 1 << 7, + FLAG_EVENT_INPUT_DOWN = 1 << 8, + FLAG_EVENT_INPUT_UP = 1 << 9, + FLAG_EVENT_INPUT_CLICKED = 1 << 10, + FLAG_EVENT_INPUT_CLICKED_DOUBLE = 1 << 11, + FLAG_EVENT_INPUT_CLICKED_TRIPLE = 1 << 12, }; #define UTF8_MAX_SIZE (8) diff --git a/Sources/ewolWindows.cpp b/Sources/ewolWindows.cpp index e086d26f..792a452b 100644 --- a/Sources/ewolWindows.cpp +++ b/Sources/ewolWindows.cpp @@ -31,7 +31,9 @@ #include //list of local events : -const char * eventClose = "Close Windows"; +const char * ewolEventWindowsClose = "ewol Windows close"; +const char * ewolEventWindowsMinimize = "ewol Windows minimize"; +const char * ewolEventWindowsExpend = "ewol Windows expend/unExpend"; bool ewol::Windows::CalculateSize(double availlableX, double availlableY) { @@ -40,23 +42,18 @@ bool ewol::Windows::CalculateSize(double availlableX, double availlableY) return true; } -// TODO : Rewrite this with common event ... + bool ewol::Windows::OnEventInput(int32_t IdInput, eventInputType_te typeEvent, double x, double y) { +/* if( EVENT_INPUT_TYPE_UP == typeEvent && 1 == IdInput) { - if (y <= 20.0) { - if (x <= 20.0) { - EWOL_INFO("Request close"); - } else if (x <= 40.0) { - EWOL_INFO("Request Minimize"); - } else if (x <= 60.0) { - EWOL_INFO("Request Expend/unExpend"); - } - } + EWOL_INFO("Request ???"); } return true; +*/ + return false; } @@ -106,26 +103,29 @@ void ewol::Windows::SysDraw(void) */ - ewol::OObject2DColored myOObject; + static ewol::OObject2DColored myOObject; static bool isinit = false; - myOObject.Rectangle( 0, 0, 20, 20, 1.0, 0.0, 0.0, 1.0); // Close + if (false == isinit) { isinit=true; - AddEventArea({0.0,0.0}, {20, 20}, FLAG_EVENT_INPUT_1 | FLAG_EVENT_CLICKED, eventClose); + myOObject.Rectangle( 0, 0, 20, 20, 1.0, 0.0, 0.0, 1.0); // Close + myOObject.Rectangle(20, 0, 20, 20, 0.0, 1.0, 0.0, 1.0); // Reduce + myOObject.Rectangle(40, 0, 20, 20, 0.0, 0.0, 1.0, 1.0); // Expend - Un-expend + + AddEventArea({ 0.0,0.0}, {20, 20}, FLAG_EVENT_INPUT_1 | FLAG_EVENT_INPUT_CLICKED, ewolEventWindowsClose); + AddEventArea({20.0,0.0}, {20, 20}, FLAG_EVENT_INPUT_1 | FLAG_EVENT_INPUT_CLICKED, ewolEventWindowsMinimize); + AddEventArea({40.0,0.0}, {20, 20}, FLAG_EVENT_INPUT_1 | FLAG_EVENT_INPUT_CLICKED, ewolEventWindowsExpend); + + // Other ... + myOObject.Rectangle(20, 30, 100, 50, 1.0, 0.0, 0.0, 1.0); + myOObject.Rectangle(50, 50, 50, 50, 0.0, 1.0, 0.0, 1.0); + myOObject.Rectangle(80, 80, 100, 50, 0.0, 0.0, 1.0, 1.0); + myOObject.Rectangle(50, 00, 300, 300, 0.2, 0.2, 0.2, 0.5); + + //myOObject.Rectangle(-50, -50, 120, 120, 0.0, 1.0, 1.0, 0.5); } - myOObject.Rectangle(20, 0, 20, 20, 0.0, 1.0, 0.0, 1.0); // Reduce - myOObject.Rectangle(40, 0, 20, 20, 0.0, 0.0, 1.0, 1.0); // Expend - Un-expend - - // Other ... - myOObject.Rectangle(20, 30, 100, 50, 1.0, 0.0, 0.0, 1.0); - myOObject.Rectangle(50, 50, 50, 50, 0.0, 1.0, 0.0, 1.0); - myOObject.Rectangle(80, 80, 100, 50, 0.0, 0.0, 1.0, 1.0); - myOObject.Rectangle(50, 00, 300, 300, 0.2, 0.2, 0.2, 0.5); - - - //myOObject.Rectangle(-50, -50, 120, 120, 0.0, 1.0, 1.0, 0.5); myOObject.Draw(); @@ -135,8 +135,18 @@ void ewol::Windows::SysDraw(void) bool ewol::Windows::OnEventArea(const char * generateEventId, double x, double y) { - if(eventClose == generateEventId) { - EWOL_DEBUG("Request close of the windows"); + bool eventIsOK = false; + //EWOL_DEBUG("Receive event : \"" << generateEventId << "\""); + if(ewolEventWindowsClose == generateEventId) { + EWOL_INFO("Request close of the windows"); + eventIsOK = true; + } else if(ewolEventWindowsMinimize == generateEventId) { + EWOL_INFO("Request Minimize of the windows"); + eventIsOK = true; + } else if(ewolEventWindowsExpend == generateEventId) { + EWOL_INFO("Request Expend of the windows"); + eventIsOK = true; } + return eventIsOK; }