diff --git a/Sources/libewol/ewol/widget/Button.cpp b/Sources/libewol/ewol/widget/Button.cpp index 79757590..91390135 100644 --- a/Sources/libewol/ewol/widget/Button.cpp +++ b/Sources/libewol/ewol/widget/Button.cpp @@ -60,6 +60,12 @@ void ewol::Button::Init(void) AddEventId(ewolEventButtonLeave); m_hasAnImage = false; m_alignement = ewol::TEXT_ALIGN_CENTER; + + m_status.m_stateOld = 0; + m_status.m_stateNew = 0; + m_status.m_transition = 1.0; + m_time = -1; + m_nextStatusRequested = -1; /* #ifdef __TARGET_OS__Android m_padding.y = 12; @@ -292,9 +298,6 @@ void ewol::Button::OnRegenerateDisplay(void) //EWOL_DEBUG("draw tex at pos : " < pos) { //EWOL_DEBUG("Event on BT ..."); + if(ewol::EVENT_INPUT_TYPE_ENTER == typeEvent) { + ChangeStatusIn(2); + }else if(ewol::EVENT_INPUT_TYPE_LEAVE == typeEvent) { + ChangeStatusIn(0); + } if (1 == IdInput) { if(ewol::EVENT_INPUT_TYPE_DOWN == typeEvent) { GenerateEventId(ewolEventButtonDown); + ChangeStatusIn(1); + MarkToRedraw(); } if(ewol::EVENT_INPUT_TYPE_UP == typeEvent) { GenerateEventId(ewolEventButtonUp); + ChangeStatusIn(0); + MarkToRedraw(); } if( ewol::EVENT_INPUT_TYPE_SINGLE == typeEvent || ewol::EVENT_INPUT_TYPE_DOUBLE == typeEvent @@ -343,3 +355,49 @@ bool ewol::Button::OnEventKb(ewol::eventKbType_te typeEvent, uniChar_t unicodeDa return false; } + + +void ewol::Button::ChangeStatusIn(int32_t newStatusId) +{ + m_nextStatusRequested = newStatusId; + PeriodicCallSet(true); + MarkToRedraw(); +} +/** + * @brief Periodic call of this widget + * @param localTime curent system time + * @return --- + */ +void ewol::Button::PeriodicCall(int64_t localTime) +{ + // start : + if (m_time == -1) { + m_time = localTime; + m_status.m_stateOld = m_status.m_stateNew; + m_status.m_stateNew = m_nextStatusRequested; + m_nextStatusRequested = -1; + m_status.m_transition = 0.0; + //EWOL_ERROR(" ##### START ##### "); + } + int64_t offset = localTime - m_time; + float timeRelativity = m_config->GetFloat(m_confIdChangeTime)*1000.0; + if (offset > timeRelativity) { + // check if no new state requested: + if (m_nextStatusRequested != -1) { + m_time = localTime; + m_status.m_stateOld = m_status.m_stateNew; + m_status.m_stateNew = m_nextStatusRequested; + m_nextStatusRequested = -1; + m_status.m_transition = 0.0; + } else { + m_status.m_transition = 1.0; + //EWOL_ERROR(" ##### STOP ##### "); + PeriodicCallSet(false); + m_time = -1; + } + } else { + m_status.m_transition = (float)offset / timeRelativity; + //EWOL_DEBUG("time=" << offset << " in " << timeRelativity << " Transition : " << m_status.m_transition); + } + MarkToRedraw(); +} diff --git a/Sources/libewol/ewol/widget/Button.h b/Sources/libewol/ewol/widget/Button.h index 9ae74e61..f8f67240 100644 --- a/Sources/libewol/ewol/widget/Button.h +++ b/Sources/libewol/ewol/widget/Button.h @@ -143,6 +143,16 @@ namespace ewol { */ virtual bool OnEventInput(ewol::inputType_te type, int32_t IdInput, eventInputType_te typeEvent, etk::Vector2D pos); virtual bool OnEventKb(ewol::eventKbType_te typeEvent, uniChar_t unicodeData); + private: + int32_t m_nextStatusRequested; + void ChangeStatusIn(int32_t newStatusId); + int64_t m_time; + /** + * @brief Periodic call of this widget + * @param localTime curent system time + * @return --- + */ + virtual void PeriodicCall(int64_t localTime); }; /** diff --git a/share/theme/default/widgetButton.conf b/share/theme/default/widgetButton.conf index cf2df998..8057eca4 100644 --- a/share/theme/default/widgetButton.conf +++ b/share/theme/default/widgetButton.conf @@ -1,6 +1,6 @@ # padding for the GUI -PaddingX=11 -PaddingY=11 +PaddingX=8 +PaddingY=8 # change status in ms ChangeTime=356 diff --git a/share/theme/default/widgetButton.frag b/share/theme/default/widgetButton.frag index 680c40cc..6243847c 100644 --- a/share/theme/default/widgetButton.frag +++ b/share/theme/default/widgetButton.frag @@ -24,12 +24,16 @@ varying vec2 v_position; // interpolated position ... // internal static define vec4 S_colorBg = vec4(0.0); -vec4 S_colorFg = vec4(0.5,0.5,0.5,0.8); +vec4 S_colorFg[3]; vec4 S_colorBorder = vec4(0.0,0.0,0.0,1.0); -float S_sizePadding = 5.0; +float S_sizePadding = 3.0; float S_sizeBorder = 1.0; void main(void) { + S_colorFg[0] = vec4(0.5,0.5,0.5,0.3); + S_colorFg[1] = vec4(0.7,0.0,0.0,0.4); + S_colorFg[2] = vec4(0.0,0.0,0.7,0.4); + float specialBorder = S_sizeBorder+S_sizePadding; vec2 endStart = EW_widgetProperty.size - vec2(S_sizePadding) - vec2(S_sizeBorder); vec2 endStop = EW_widgetProperty.size - vec2(S_sizePadding); @@ -45,7 +49,8 @@ void main(void) { ) { gl_FragColor = S_colorBorder; } else { - gl_FragColor = S_colorFg; + gl_FragColor = S_colorFg[EW_status.stateOld]*(1.0-EW_status.transition) + + S_colorFg[EW_status.stateNew]*EW_status.transition; } } else { gl_FragColor = S_colorBg; diff --git a/share/theme/rounded/widgetButton.conf b/share/theme/rounded/widgetButton.conf index 3db723d3..915fd602 100644 --- a/share/theme/rounded/widgetButton.conf +++ b/share/theme/rounded/widgetButton.conf @@ -1,6 +1,6 @@ # padding for the GUI -PaddingX=14 -PaddingY=14 +PaddingX=13 +PaddingY=7 # change status in ms ChangeTime=356 diff --git a/share/theme/rounded/widgetButton.frag b/share/theme/rounded/widgetButton.frag index 79d64302..101ce778 100644 --- a/share/theme/rounded/widgetButton.frag +++ b/share/theme/rounded/widgetButton.frag @@ -23,42 +23,41 @@ uniform widgetStateProperty EW_status; varying vec2 v_position; // interpolated position ... // internal static define -float S_roundedRatio = 10.0; vec4 S_colorBg = vec4(0.0); vec4 S_colorFg = vec4(0.5,0.5,0.5,0.3); vec4 S_colorBorder = vec4(0.0,0.0,0.0,1.0); -float S_sizePadding = 3.0; // must not be NULL -float S_sizeBorder = 1.0; +float S_sizePadding = 3.0; // must not be NULL +float S_sizeBorder = 1.0; //==> this id for 1 px border +float S_roundedRatio = 10.0; void main(void) { // position form center : vec2 ratio = EW_widgetProperty.size / 2.0; - vec2 positionCenter = v_position-ratio; - if(positionCenter.x<0.0) { - positionCenter.x = -1.0*positionCenter.x; - } - if(positionCenter.y<0.0) { - positionCenter.y = -1.0*positionCenter.y; - } - vec2 ratioHight = ratio - S_sizePadding; - vec2 ratioLow = ratioHight - (S_sizeBorder+S_roundedRatio); - vec2 circleMode = smoothstep(ratioLow, ratioHight, positionCenter); - float tmpDist = sqrt(circleMode.x*circleMode.x + circleMode.y*circleMode.y); + /* generate a central simetry + ____ _____ + \ / + \ / + \ / + - + */ + vec2 positionCenter = abs(v_position-ratio); + // This is a clip to remove center of the display of the widget + vec2 ratioLow = ratio - (S_roundedRatio+S_sizePadding); + vec2 circleMode = smoothstep(ratioLow, ratio, positionCenter)*(S_roundedRatio+S_sizePadding); + // Calculate the distance of the radius + float tmpDist = sqrt(dot(circleMode,circleMode)); + // Generate the internal rampe for the the imput drawing + float tmpVal = smoothstep(S_roundedRatio - S_sizeBorder*1.5, + S_roundedRatio + S_sizeBorder*1.5, + tmpDist); + // set Background + gl_FragColor = S_colorBg; + // set foreground + gl_FragColor = gl_FragColor*tmpVal + S_colorFg*(1.0-tmpVal); + // set border + float tmpVal2 = abs(tmpVal-0.5)*2.0; + gl_FragColor = gl_FragColor*tmpVal2 + S_colorBorder*(1.0-tmpVal2); - //float distanceInternal = (S_roundedRatio-S_sizeBorder/2.0)/(S_roundedRatio-S_sizeBorder); - //float distanceExternal = (S_roundedRatio+S_sizeBorder/2.0)/(S_roundedRatio-S_sizeBorder);; - if(tmpDist <= 0.6 ) { - gl_FragColor = S_colorFg; - } else if(tmpDist <= 0.9) { - float tmpVal = smoothstep(0.7, 0.9, tmpDist); - if (tmpVal<=0.5) { - gl_FragColor = S_colorBorder*(tmpVal*2.0) + S_colorFg*(1.0-tmpVal*2.0); - } else { - gl_FragColor = S_colorBorder*(1.0-(tmpVal-0.5)*2.0) + S_colorBg*((tmpVal-0.5)*2.0); - } - } else { - gl_FragColor = S_colorBg; - } } diff --git a/share/theme/rounded/widgetEntry.frag b/share/theme/rounded/widgetEntry.frag index 71d352bc..75bd3298 100644 --- a/share/theme/rounded/widgetEntry.frag +++ b/share/theme/rounded/widgetEntry.frag @@ -22,17 +22,11 @@ vec4 S_colorBorder = vec4(0.0,0.0,0.0,1.0); void main(void) { // position form center : vec2 ratio = EW_size / 2.0; - vec2 positionCenter = v_position-ratio; - if(positionCenter.x<0.0) { - positionCenter.x = -1.0*positionCenter.x; - } - if(positionCenter.y<0.0) { - positionCenter.y = -1.0*positionCenter.y; - } + vec2 positionCenter = abs(v_position-ratio); vec2 ratioHight = ratio - EW_sizePadding; vec2 ratioLow = ratioHight - (EW_sizeBorder+S_roundedRatio); vec2 circleMode = smoothstep(ratioLow, ratioHight, positionCenter); - float tmpDist = sqrt(circleMode.x*circleMode.x + circleMode.y*circleMode.y); + float tmpDist = sqrt(dot(circleMode,circleMode)); //float distanceInternal = (S_roundedRatio-EW_sizeBorder/2.0)/(S_roundedRatio-EW_sizeBorder); //float distanceExternal = (S_roundedRatio+EW_sizeBorder/2.0)/(S_roundedRatio-EW_sizeBorder);;